├── app
├── package.json
├── vibe.node
├── css_editor
│ ├── favicon.png
│ ├── preload.js
│ └── index.html
├── discord_acrylic
│ ├── package.json
│ ├── utils
│ │ ├── settings.js
│ │ └── idb.js
│ ├── LICENSE
│ └── main.js
├── index.js
└── theme.css
├── .gitattributes
└── README.md
/app/package.json:
--------------------------------------------------------------------------------
1 | {"name":"discord_acrylic_injection","main":"index.js"}
--------------------------------------------------------------------------------
/app/vibe.node:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uwu/Acrylic/HEAD/app/vibe.node
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/app/css_editor/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/uwu/Acrylic/HEAD/app/css_editor/favicon.png
--------------------------------------------------------------------------------
/app/discord_acrylic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "discord_acrylic",
3 | "version": "2.0.0",
4 | "private": "true",
5 | "main": "./main.js"
6 | }
--------------------------------------------------------------------------------
/app/css_editor/preload.js:
--------------------------------------------------------------------------------
1 | const { contextBridge, ipcRenderer } = require('electron');
2 |
3 | console.log('%c[Acrylic]%c %s', 'color: #ceb4ed', 'color: inherit', "Arcylic injected.");
4 |
5 | const utils = {
6 | getCss: () => {
7 | return ipcRenderer.sendSync('get-css');
8 | },
9 |
10 | saveCss: (css) => {
11 | ipcRenderer.send('save-css', css);
12 | },
13 |
14 | reloadCss: () => {
15 | ipcRenderer.send('css-reload');
16 | }
17 | }
18 |
19 | contextBridge.exposeInMainWorld('utils', utils);
--------------------------------------------------------------------------------
/app/discord_acrylic/utils/settings.js:
--------------------------------------------------------------------------------
1 | const { get, set } = require("./idb");
2 |
3 | const defaultSettings = {
4 | acrylic: true,
5 | css: true,
6 | type: 1,
7 | };
8 |
9 | let currentSettings = null;
10 |
11 | const saveSettings = async (settings) => {
12 | await set("settings", settings);
13 | currentSettings = settings;
14 | };
15 |
16 | const getSettings = async () => {
17 | if (!currentSettings) {
18 | currentSettings = await get("settings");
19 | if (
20 | !currentSettings ||
21 | !Object.keys(currentSettings).length ==
22 | Object.keys(defaultSettings).length
23 | ) {
24 | await saveSettings(defaultSettings);
25 | }
26 | }
27 | return currentSettings;
28 | };
29 |
30 | module.exports = { saveSettings, getSettings };
31 |
--------------------------------------------------------------------------------
/app/discord_acrylic/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 alethéia
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/css_editor/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CSS Editor
6 |
17 |
18 |
19 |
20 |
21 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Acrylic
2 |
3 | (Windows Only) Spiritual successor to Glasscord. Does not provide compatibility with Glasscord themes, only translucency effects.
4 |
5 | # Disclaimer
6 |
7 | This Discord mod is still a work in progress. Features and compatibility may change at any time!
8 |
9 | # Installation
10 |
11 | 1. Copy `app` folder into `%userprofile%/AppData/Local/Discord/app-x.y.z/resources`
12 |
13 | - The Discord folder name changes depending on the installed channel
14 |
15 | | Channel | Name |
16 | | ------- | --------------- |
17 | | Stable | `Discord` |
18 | | Canary | `DiscordCanary` |
19 |
20 | 2. Rename app.asar to original.asar
21 | 3. That's it :)
22 |
23 | # Usage
24 |
25 | The recommended way to interact with the settings is to use https://shelter.xirreal.dev/acrylicSettings/, which provides a comfy menu to interact with the API.
26 |
27 | By default, Acrylic will inject it's own included css theme, making it standalone in case you don't want to use it with another mod.
28 | A simple API is exposed on `window.acrylic`, allowing quick toggling of both acrylic features and css.
29 | To open the CSS editor, use `window.acrylic.css.openEditor()`.
30 |
31 | Settings are stored in IDB, under the `acrylic/settings` table.
32 |
33 | # Credits
34 |
35 | - [Impregnate](https://github.com/Cumcord/Impregnate) for injection
36 | - [Vibe](https://github.com/pykeio/vibe) for composition effects in electron apps
37 | - [Monaco Editor](https://microsoft.github.io/monaco-editor/) and [Monaco Loader](https://github.com/suren-atoyan/monaco-loader)
38 |
--------------------------------------------------------------------------------
/app/discord_acrylic/utils/idb.js:
--------------------------------------------------------------------------------
1 | /*
2 | From: https://github.com/jakearchibald/idb-keyval
3 | Copyright 2016, Jake Archibald
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | http://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
16 |
17 | Stripped for use in this project.
18 | */
19 |
20 | function promisifyRequest(request) {
21 | return new Promise((resolve, reject) => {
22 | request.oncomplete = request.onsuccess = () => resolve(request.result);
23 | request.onabort = request.onerror = () => reject(request.error);
24 | });
25 | }
26 |
27 | function createStore(dbName, storeName) {
28 | const request = indexedDB.open(dbName);
29 | request.onupgradeneeded = () => request.result.createObjectStore(storeName);
30 | const dbp = promisifyRequest(request);
31 | return (txMode, callback) =>
32 | dbp.then((db) =>
33 | callback(db.transaction(storeName, txMode).objectStore(storeName))
34 | );
35 | }
36 |
37 | let _store = null;
38 |
39 | function getStore() {
40 | if (!_store) {
41 | _store = createStore("acrylic", "settings");
42 | }
43 | return _store;
44 | }
45 |
46 | function get(key) {
47 | getStore();
48 | return _store("readonly", (store) => promisifyRequest(store.get(key)));
49 | }
50 |
51 | function set(key, value) {
52 | getStore();
53 | return _store("readwrite", (store) => {
54 | store.put(value, key);
55 | return promisifyRequest(store.transaction);
56 | });
57 | }
58 |
59 | module.exports = { get, set };
60 |
--------------------------------------------------------------------------------
/app/discord_acrylic/main.js:
--------------------------------------------------------------------------------
1 | const { contextBridge, ipcRenderer } = require("electron");
2 | const { getSettings, saveSettings } = require("./utils/settings");
3 |
4 | ipcRenderer.invoke("isMainProcessAlive").then(async () => {
5 | console.log(
6 | "%c[Acrylic]%c %s",
7 | "color: #ceb4ed",
8 | "color: inherit",
9 | "Arcylic injected."
10 | );
11 |
12 | const settings = await getSettings();
13 |
14 | const acrylic = {
15 | version: "2.0.0",
16 | internal: {
17 | getSettings: () => {
18 | return settings;
19 | },
20 | },
21 |
22 | enable: () => {
23 | ipcRenderer.send("enable", settings.type);
24 | saveSettings({ ...settings, acrylic: true });
25 | settings.acrylic = true;
26 | },
27 |
28 | disable: () => {
29 | ipcRenderer.send("disable");
30 | saveSettings({ ...settings, acrylic: false });
31 | settings.acrylic = false;
32 | },
33 |
34 | setType: (type) => {
35 | if (type == settings.type || type < 0 || type > 2)
36 | return "Setting was not changed.";
37 | ipcRenderer.send("enable", type);
38 | saveSettings({ ...settings, type: type });
39 | settings.type = type;
40 | },
41 |
42 | css: {
43 | enable: () => {
44 | ipcRenderer.send("css-enable");
45 | saveSettings({ ...settings, css: true });
46 | settings.css = true;
47 | },
48 | disable: () => {
49 | ipcRenderer.send("css-disable");
50 | saveSettings({ ...settings, css: false });
51 | settings.css = false;
52 | },
53 | reload: () => {
54 | if (settings.css) {
55 | ipcRenderer.send("css-reload");
56 | }
57 | },
58 | openEditor: () => {
59 | if (!settings.css) {
60 | ipcRenderer.send("css-enable");
61 | saveSettings({ ...settings, css: true });
62 | settings.css = true;
63 | }
64 | ipcRenderer.send("open-css");
65 | },
66 | },
67 | };
68 |
69 | contextBridge.exposeInMainWorld("acrylic", acrylic);
70 | if (settings.acrylic) {
71 | acrylic.enable();
72 | }
73 | if (settings.css) {
74 | acrylic.css.enable();
75 | }
76 | });
77 |
--------------------------------------------------------------------------------
/app/index.js:
--------------------------------------------------------------------------------
1 | const electron = require("electron");
2 | const path = require("path");
3 | const fs = require("fs");
4 |
5 | var vibe = null;
6 | var cssEditor = null;
7 | var mainWindow = null;
8 |
9 | if (process.platform === "win32") {
10 | vibe = require("./vibe.node");
11 | vibe.setup(electron.app);
12 | console.log("[Acrylic] Setting up the vibe~");
13 | } else {
14 | console.log("[Acrylic] Not getting the right vibes...");
15 | }
16 |
17 | function copyDir(src, dest) {
18 | fs.mkdirSync(dest, { recursive: true });
19 | const entries = fs.readdirSync(src, { withFileTypes: true });
20 | for (let entry of entries) {
21 | let srcPath = path.join(src, entry.name);
22 | let destPath = path.join(dest, entry.name);
23 |
24 | entry.isDirectory()
25 | ? copyDir(srcPath, destPath)
26 | : fs.copyFileSync(srcPath, destPath);
27 | }
28 | }
29 |
30 | const basePath = path.join(path.dirname(require.main.filename), "..");
31 |
32 | if (process.platform != "darwin") {
33 | const modulesPath = path.join(basePath, "..", "modules");
34 | const corePath = fs
35 | .readdirSync(modulesPath)
36 | .find((folder) => folder.includes("discord_desktop_core-"));
37 | const acrylicPath = path.join(modulesPath, corePath, "discord_acrylic");
38 |
39 | if (fs.existsSync(acrylicPath)) {
40 | fs.rmdirSync(acrylicPath, { recursive: true });
41 | }
42 | copyDir(path.join(basePath, "app", "discord_acrylic"), acrylicPath);
43 | } else {
44 | const os = require("os");
45 |
46 | const homePath = os.homedir();
47 |
48 | const hostBasePath = path.join(
49 | homePath,
50 | "Library/Application Support/discord"
51 | );
52 | const modulesPath = path.join(
53 | hostBasePath,
54 | fs
55 | .readdirSync(hostBasePath)
56 | .find((folder) => folder.split(".").length == 3),
57 | "modules"
58 | );
59 | const acrylicPath = path.join(modulesPath, "discord_acrylic");
60 |
61 | if (fs.existsSync(acrylicPath)) {
62 | fs.rmdirSync(acrylicPath, { recursive: true });
63 | }
64 | copyDir(path.join(basePath, "app", "discord_acrylic"), acrylicPath);
65 | }
66 |
67 | let originalAppPath = path.join(basePath, "original.asar");
68 |
69 | const originalPackage = require(path.resolve(
70 | path.join(originalAppPath, "package.json")
71 | ));
72 |
73 | require.main.filename = path.join(originalAppPath, originalPackage.main);
74 |
75 | electron.app.setAppPath(originalAppPath);
76 | electron.app.name = originalPackage.name;
77 | //#endregion
78 |
79 | const electronCache = require.cache[require.resolve("electron")];
80 |
81 | //#region CSP Removal
82 | electron.app.on("ready", () => {
83 | // Removes CSP
84 | electron.session.defaultSession.webRequest.onHeadersReceived(
85 | ({ responseHeaders }, done) => {
86 | const cspHeaders = Object.keys(responseHeaders).filter((name) =>
87 | name.toLowerCase().startsWith("content-security-policy")
88 | );
89 |
90 | for (const header of cspHeaders) {
91 | delete responseHeaders[header];
92 | }
93 |
94 | done({ responseHeaders });
95 | }
96 | );
97 |
98 | // Prevents other mods from removing CSP
99 | electronCache.exports.session.defaultSession.webRequest.onHeadersReceived =
100 | () => {
101 | console.log("[RawDog] Prevented CSP from being modified...");
102 | };
103 | });
104 | //#endregion
105 |
106 | const { BrowserWindow } = electron;
107 | const propertyNames = Object.getOwnPropertyNames(electronCache.exports);
108 |
109 | delete electronCache.exports;
110 | // Make a new electron that will use the new 'BrowserWindow'
111 | const newElectron = {};
112 | for (const propertyName of propertyNames) {
113 | Object.defineProperty(newElectron, propertyName, {
114 | ...Object.getOwnPropertyDescriptor(electron, propertyName),
115 | get: () =>
116 | propertyName === "BrowserWindow"
117 | ? class extends BrowserWindow {
118 | constructor(opts) {
119 | if (opts.resizable && process.platform == "win32") {
120 | if (vibe.platform.isWin11()) {
121 | opts.frame = true;
122 | }
123 | }
124 |
125 | opts.webPreferences.devTools = true;
126 |
127 | const window = new BrowserWindow(opts);
128 |
129 | if (window.resizable && !mainWindow) {
130 | console.log("[Acrylic] Found Discord window.");
131 |
132 | mainWindow = window;
133 |
134 | window.webContents.on("dom-ready", () => {
135 | if (process.platform == "win32") {
136 | window.setBackgroundColor("#00000000");
137 | vibe.forceTheme(window, "dark");
138 | }
139 |
140 | window.webContents.executeJavaScript(
141 | `DiscordNative.nativeModules.requireModule("discord_acrylic");`
142 | );
143 | });
144 | }
145 |
146 | return window;
147 | }
148 | }
149 | : electron[propertyName],
150 | });
151 | }
152 |
153 | electronCache.exports = newElectron;
154 | //#endregion
155 |
156 | module.exports = require(originalAppPath);
157 |
158 | function loadCss() {
159 | return fs.readFileSync(path.join(basePath, "app", "theme.css"), "utf8");
160 | }
161 |
162 | function saveCss(css) {
163 | return fs.writeFileSync(path.join(basePath, "app", "theme.css"), css);
164 | }
165 |
166 | function removeCss(window) {
167 | window.webContents.executeJavaScript(
168 | `document.getElementById("acrylic")?.remove?.();`
169 | );
170 | }
171 |
172 | function injectCss(window, css, id = "acrylic") {
173 | window.webContents.executeJavaScript(
174 | `document.body.insertAdjacentHTML("beforeend", \`\`);`
175 | );
176 | }
177 |
178 | electron.ipcMain.handle("isMainProcessAlive", () => {
179 | console.log("[Acrylic] Injected into render process.");
180 | if (vibe.platform.isWin11()) {
181 | injectCss(
182 | mainWindow,
183 | ".titleBar-1it3bQ { display: none; }",
184 | "acrylic-titlebar-remove"
185 | );
186 | }
187 | return true;
188 | });
189 |
190 | electron.ipcMain.on("open-css", () => {
191 | if (!cssEditor) {
192 | cssEditor = new BrowserWindow({
193 | width: 1000,
194 | height: 800,
195 | autoHideMenuBar: true,
196 | backgroundColor: "#1e1e1e",
197 | webPreferences: {
198 | preload: path.join(
199 | path.join(basePath, "app", "css_editor", "preload.js")
200 | ),
201 | },
202 | });
203 |
204 | if (process.platform == "win32") {
205 | vibe.forceTheme(cssEditor, "dark");
206 | }
207 |
208 | cssEditor.setIcon(path.join(basePath, "app", "css_editor", "favicon.png"));
209 | cssEditor.loadFile(path.join(basePath, "app", "css_editor", "index.html"));
210 | cssEditor.on("closed", () => {
211 | cssEditor = null;
212 | });
213 | } else {
214 | cssEditor.focus();
215 | }
216 | });
217 |
218 | electron.ipcMain.on("get-css", (event) => {
219 | event.returnValue = loadCss();
220 | });
221 |
222 | electron.ipcMain.on("save-css", (_, css) => {
223 | saveCss(css);
224 | });
225 |
226 | electron.ipcMain.on("css-enable", () => {
227 | console.log("[Acrylic] Injecting CSS.");
228 | injectCss(mainWindow, loadCss());
229 | });
230 |
231 | electron.ipcMain.on("css-disable", () => {
232 | console.log("[Acrylic] Removing CSS.");
233 | removeCss(mainWindow);
234 | });
235 |
236 | electron.ipcMain.on("css-reload", () => {
237 | console.log("[Acrylic] Reloading CSS.");
238 | removeCss(mainWindow);
239 | injectCss(mainWindow, loadCss());
240 | });
241 |
242 | const types = ["mica", "acrylic", "blurbehind"];
243 |
244 | electron.ipcMain.on("enable", (_, type) => {
245 | console.log("[Acrylic] Enabling Acrylic.");
246 | if ((type == 0 && !vibe.platform.isWin11()) || type === undefined) {
247 | type = 1;
248 | }
249 | console.log("[Acrylic] Type: " + types[type]);
250 | vibe?.applyEffect?.(mainWindow, types[type]);
251 | });
252 |
253 | electron.ipcMain.on("disable", () => {
254 | console.log("[Acrylic] Disabling Acrylic.");
255 | vibe?.clearEffects?.(mainWindow);
256 | });
257 |
--------------------------------------------------------------------------------
/app/theme.css:
--------------------------------------------------------------------------------
1 | .theme-dark {
2 | --background-primary: transparent;
3 | --background-primary-alt: #36393ff0;
4 | --background-secondary: #2f313650;
5 | --background-secondary-chat: #2f3136a0;
6 | --background-secondary-alt: #292b2f00;
7 | --background-tertiary: #20222570;
8 | --background-quaternay: #20222570;
9 | --background-logo: #36393fa0;
10 | --deprecated-card-bg: #36393f4c;
11 | --deprecated-store-bg: #36393f00;
12 | --background-attachments: #2f313640;
13 | --background-search-bar: #202225a0;
14 | --background-switcher: #2f3136a0;
15 | --background-chatbox: #20222550;
16 | --background-lights-out: #000;
17 | --text-lights-out: #f0f0f0;
18 | --background-titlebar: #202225af;
19 | --background-floating: #383841ef;
20 | --interactive-muted: #93939750;
21 | --background-mobile-primary: var(--background-secondary);
22 | --channeltextarea-background: #9289891f;
23 | --background-modifier-accent: #fffefe15;
24 | --background-modifier-selected: var(--background-tertiary);
25 | --scrollbar-thin-thumb: var(--background-tertiary);
26 | --scrollbar-thin-track: var(--background-primary);
27 | --scrollbar-auto-thumb: var(--background-tertiary);
28 | --scrollbar-auto-track: var(--background-primary);
29 | }
30 |
31 | html,
32 | body,
33 | .appMount-2yBXZl,
34 | .app-2CXKsg,
35 | .bg-1QIAus,
36 | .members-3WRCEx,
37 | .members-3WRCEx > div,
38 | .scroller-3X7KbA,
39 | .guilds-2JjMmN,
40 | .container-1NXEtd,
41 | .channelName-3w2Y3c,
42 | .bodyInnerWrapper-2bQs1k,
43 | .member-48YF_l,
44 | .container-3wLKDe,
45 | .content-1jQy2l {
46 | background: transparent !important;
47 | }
48 |
49 | .cooldownWrapper-2k1jHK {
50 | padding-right: 10px;
51 | }
52 |
53 | .sidebar-1tnWFu {
54 | border-radius: 8px 0px 0px 8px !important;
55 | }
56 |
57 | .chat-2ZfjoI,
58 | .scroller-1ox3I2,
59 | .peopleColumn-1wMU14,
60 | .background-fkKrXt {
61 | background: var(--background-secondary) !important;
62 | }
63 |
64 | .searchBar-3TnChZ,
65 | .header-11eigE {
66 | box-shadow: none !important;
67 | background: var(--background-secondary);
68 | }
69 |
70 | .container-ZMc96U.themed-Hp1KC_ {
71 | background: var(--background-tertiary);
72 | }
73 |
74 | .container-1zzFcN,
75 | .panel-2ZFCRb {
76 | border: transparent;
77 | background: var(--background-tertiary);
78 | }
79 |
80 | .circleIconButton-1VxDrg,
81 | .childWrapper-1j_1ub {
82 | color: white;
83 | background: var(--background-logo);
84 | }
85 |
86 | .circleIconButton-1VxDrg.selected-2r1Hvo {
87 | background: var(--background-floating);
88 | }
89 |
90 | .userPopout-2j1gM4,
91 | .contentWrapper-3vHNP2,
92 | .tooltip-14MtrL,
93 | .messagesPopoutWrap-3zryHW,
94 | .browser-mnQ1T7,
95 | .recentMentionsPopout-2bI1ZN,
96 | .emojiPicker-6YCk8a,
97 | .wrapper-2vIMkT,
98 | .container-2McqkF,
99 | .userPopoutInner-1hXSeY,
100 | .userProfileInnerThemedNonPremium-1gT-zY,
101 | .popout-1KHNAq {
102 | background-color: var(--background-floating);
103 | }
104 |
105 | .searchOption-3u1gRt::after,
106 | .option-ayUoaq::after,
107 | .tabBody-2dgbAs::before,
108 | .content-1jQy2l::before {
109 | display: none;
110 | }
111 |
112 | .divider-IqmEqJ.isUnread-3Lojb- {
113 | margin-top: 0px !important;
114 | }
115 |
116 | .divider-IqmEqJ,
117 | .divider-IqmEqJ.hasContent-31hcsn {
118 | margin-top: 2rem !important;
119 | }
120 |
121 | .content-3spvdd {
122 | transform: translate(0%, -100%);
123 | }
124 |
125 | .chat-2ZfjoI {
126 | border-radius: 0px 8px 0px 0px;
127 | }
128 |
129 | .scrollerSpacer-3AqkT9 {
130 | height: 30px;
131 | }
132 |
133 | .container-YkUktl {
134 | background: var(--background-tertiary);
135 | margin-bottom: 0px;
136 | height: 61px;
137 | }
138 |
139 | .messagesWrapper-RpOMA3 {
140 | margin-bottom: 8px;
141 | }
142 |
143 | .form-3gdLxP {
144 | background: var(--background-tertiary);
145 | }
146 |
147 | .typing-2J1mQU {
148 | background: var(--background-tertiary);
149 | position: absolute;
150 | top: 0px;
151 | transform: translate(0px, -24px);
152 | border-radius: 8px 8px 0px 0px;
153 | }
154 |
155 | .channelTextArea-1FufC0 {
156 | margin-top: 8px;
157 | margin-bottom: 9px;
158 | }
159 |
160 | .communityInfoVisible-3zc5_s .header-3OsQeK,
161 | .communityInfoVisible-3zc5_s .header-3OsQeK:hover,
162 | .hasBanner-2IrYih .header-3OsQeK,
163 | .hasBanner-2IrYih .header-3OsQeK:hover {
164 | background: var(--background-secondary);
165 | }
166 |
167 | .header-3OsQeK,
168 | .animatedContainer-2laTjx {
169 | background: var(--background-tertiary);
170 | box-shadow: none;
171 | }
172 |
173 | .scroller-305q3I {
174 | background-color: transparent;
175 | }
176 |
177 | .scroller-RmtA4e,
178 | .scroller-1JbKMe {
179 | background-color: var(--background-tertiary);
180 | }
181 |
182 | .platform-win .bg-h5JY_x {
183 | top: 0px;
184 | background-color: transparent;
185 | }
186 |
187 | .iconBadge-3qSJIw.participating-1NvRVd {
188 | background-color: #4d5564;
189 | }
190 |
191 | .theme-dark
192 | .scrollerThemed-2oenus.themedWithTrack-q8E3vB
193 | .scroller-2FKFPG::-webkit-scrollbar-track-piece {
194 | background-color: transparent;
195 | border: 4px solid transparent;
196 | }
197 |
198 | .theme-dark
199 | .scrollerThemed-2oenus.themedWithTrack-q8E3vB
200 | .scroller-2FKFPG::-webkit-scrollbar-thumb {
201 | background-color: #20222550;
202 | }
203 |
204 | .theme-dark .container-1D34oG {
205 | background-color: transparent;
206 | }
207 |
208 | .theme-dark .card-FDVird:before {
209 | background-color: #33363c90;
210 | }
211 |
212 | .theme-dark .codeRedemptionRedirect-1wVR4b {
213 | background-color: #2f313650;
214 | border-color: #20222550;
215 | }
216 |
217 | .theme-dark .pageWrapper-1PgVDX {
218 | background-color: transparent;
219 | }
220 |
221 | .tooltip-2QfLtc,
222 | .container-3XJ8ns {
223 | background-color: rgb(43, 44, 46) !important;
224 | }
225 |
226 | .theme-light {
227 | --background-primary: transparent;
228 | --background-primary-alt: #ffffffff;
229 | --background-secondary: #f2f3f550;
230 | --background-secondary-chat: #f2f3f5a0;
231 | --background-secondary-alt: #ebedef00;
232 | --background-tertiary: #e3e5e860;
233 | --background-logo: #f2f3f5a0;
234 | --deprecated-card-bg: #f8f9f94c;
235 | --deprecated-store-bg: #f8f9f900;
236 | --background-attachments: #f6f6f640;
237 | --background-search-bar: #e3e5e8a0;
238 | --background-switcher: #f2f3f5a0;
239 | --background-chatbox: #e3e5e850;
240 | --background-lights-out: #fff;
241 | --text-lights-out: #202020;
242 | --background-titlebar: #202225af;
243 | --interactive-muted: #95999d;
244 | }
245 |
246 | .theme-light
247 | .scrollerThemed-2oenus.themedWithTrack-q8E3vB
248 | .scroller-2FKFPG::-webkit-scrollbar-track-piece {
249 | background-color: transparent;
250 | border: 4px solid transparent;
251 | }
252 |
253 | .theme-light
254 | .scrollerThemed-2oenus.themedWithTrack-q8E3vB
255 | .scroller-2FKFPG::-webkit-scrollbar-thumb {
256 | border-color: transparent;
257 | background-color: #e3e5e850;
258 | }
259 |
260 | .theme-light .container-1D34oG {
261 | background-color: transparent;
262 | }
263 |
264 | .theme-light .card-FDVird:before {
265 | background-color: #f6f6f790;
266 | }
267 |
268 | .theme-light .codeRedemptionRedirect-1wVR4b {
269 | background-color: #f6f6f750;
270 | border-color: #dcddde50;
271 | }
272 |
273 | .theme-light .pageWrapper-1PgVDX {
274 | background-color: transparent;
275 | }
276 |
277 | .withFrame-haYltI {
278 | height: 18px;
279 | margin-top: 0;
280 | padding-top: 4px;
281 | }
282 |
283 | .platform-win .sidebar-2K8pFh {
284 | border-radius: 0;
285 | background-color: var(--background-primary);
286 | }
287 |
288 | #private-channels-2 {
289 | display: none;
290 | }
291 |
292 | .appMount-3lHmkl {
293 | background-color: transparent;
294 | }
295 |
296 | .app-2rEoOp {
297 | background-color: transparent;
298 | }
299 |
300 | .attachment-33OFj0 {
301 | background-color: var(--background-attachments) !important;
302 | }
303 |
304 | .header-2o-2hj {
305 | -webkit-box-shadow: none;
306 | box-shadow: none;
307 | }
308 |
309 | .privateChannels-1nO12o {
310 | background-color: transparent;
311 | }
312 |
313 | .container-PNkimc {
314 | background-color: transparent;
315 | }
316 |
317 | .container-1r6BKw.themed-ANHk51 {
318 | background-color: var(--background-tertiary);
319 | }
320 |
321 | .members-1998pB .content-3YMskv {
322 | background-color: transparent !important;
323 | }
324 |
325 | .header-2V-4Sw {
326 | background-color: var(--background-tertiary);
327 | -webkit-box-shadow: none;
328 | box-shadow: none;
329 | }
330 |
331 | .container-3w7J-x {
332 | background-color: var(--background-primary);
333 | }
334 |
335 | .wrapper-1Rf91z {
336 | background-color: var(--background-secondary);
337 | }
338 |
339 | .childWrapper-anI2G9 {
340 | background-color: var(--background-logo);
341 | }
342 |
343 | .searchBar-3dMhjb {
344 | background-color: var(--background-search-bar);
345 | }
346 |
347 | .searchBar-6Kv8R2 {
348 | background-color: var(--background-tertiary);
349 | -webkit-box-shadow: none;
350 | box-shadow: none;
351 | }
352 |
353 | .content-yTz4x3:before {
354 | -webkit-box-shadow: none;
355 | box-shadow: none;
356 | }
357 |
358 | .tabBody-3YRQ8W:before {
359 | -webkit-box-shadow: none;
360 | box-shadow: none;
361 | }
362 |
363 | .container-19hC9u:before {
364 | -webkit-box-shadow: none;
365 | box-shadow: none;
366 | }
367 |
368 | .container-xm7Ad0:before {
369 | -webkit-box-shadow: none;
370 | box-shadow: none;
371 | }
372 |
373 | .searchBar-6Kv8R2 .searchBarComponent-32dTOx {
374 | background-color: var(--background-search-bar);
375 | }
376 |
377 | .scroller-2TZvBN {
378 | background-color: transparent;
379 | }
380 |
381 | .scroller-2TZvBN:active,
382 | .scroller-2TZvBN:focus {
383 | outline: 0;
384 | outline-style: none;
385 | outline-width: 0;
386 | }
387 |
388 | .quickswitcher-3JagVE {
389 | background-color: var(--background-switcher);
390 | }
391 |
392 | .wrapper-2aW0bm {
393 | background-color: var(--background-primary-alt);
394 | }
395 |
396 | .searchResultMessage-2VxO12.hit-NLlWXA {
397 | background-color: var(--background-primary-alt);
398 | }
399 |
400 | .scroller-zPkAnE {
401 | background-color: transparent;
402 | }
403 |
404 | .embedFull-2tM8-- {
405 | background-color: var(--background-attachments);
406 | }
407 |
408 | .messagesWrapper-3lZDfY {
409 | margin-bottom: 8px;
410 | }
411 |
412 | .panels-j1Uci_ {
413 | background-color: var(--background-tertiary);
414 | }
415 |
416 | .titleBar-AC4pGV {
417 | background-color: var(--background-titlebar);
418 | }
419 |
420 | .uploadArea-3QgLtW {
421 | background-color: var(--background-lights-out);
422 | }
423 |
424 | .backdropWithLayer-3_uhz4 {
425 | background-color: var(--background-lights-out) !important;
426 | }
427 |
428 | .backdrop-1wrmKB {
429 | background-color: var(--background-lights-out) !important;
430 | }
431 |
432 | .downloadLink-1ywL9o {
433 | color: var(--text-lights-out) !important;
434 | }
435 |
436 | .bg-AYqtMd {
437 | -webkit-mask-image: linear-gradient(#000f, #0000) !important;
438 | mask-image: linear-gradient(#000f, #0000) !important;
439 | }
440 |
441 | .scrollableContainer-2NUZem {
442 | background-color: var(--background-chatbox);
443 | }
444 |
445 | .circleIconButton-1QV--U,
446 | .linkButtonIcon-Mlm5d6 {
447 | /* Server discovery and new server buttons + friends icon*/
448 | color: #e7e7e8 !important;
449 | }
450 |
451 | .circleIconButton-1QV--U {
452 | /* Server discovery and new server buttons */
453 | background-color: var(--background-secondary);
454 | }
455 |
456 | .linkButtonIcon-Mlm5d6.selected-1JjBPm,
457 | .circleIconButton-1QV--U.selected-1JjBPm {
458 | background-color: #4e525a6c;
459 | }
460 |
461 | .theme-dark .recentMentionsPopout-3rCiI6,
462 | .messagesPopoutWrap-1MQ1bW {
463 | background-color: rgb(43, 44, 46) !important;
464 | box-shadow: none !important;
465 | }
466 |
467 | .scroller-3BxosC.thin-1ybCId.scrollerBase-289Jih,
468 | .attachPopout-36hjtN {
469 | background-color: rgb(43, 44, 46);
470 | border: transparent 0px;
471 | border-radius: 5px;
472 | box-shadow: none;
473 | }
474 |
475 | .content-1o0f9g {
476 | background: rgb(43, 44, 46);
477 | padding: 3px 12px 3px 12px;
478 | }
479 |
480 | .messageGroupWrapper-o-Zw7G {
481 | border-color: transparent;
482 | background-color: rgba(0, 0, 0, 0.048);
483 | }
484 |
485 | .header-8ilj5e {
486 | box-shadow: none;
487 | }
488 |
489 | .contentWrapper-SvZHNd,
490 | .wrapper-1-Fsb8.header-ywPcAE,
491 | .unicodeShortcut-15J8Ck {
492 | background-color: rgb(43, 44, 46);
493 | box-shadow: none;
494 | }
495 |
496 | .noiseCancellationPopout-iRK2A0 {
497 | background-color: rgb(43, 44, 46);
498 | }
499 |
500 | .closeButton-1152MI {
501 | margin-right: 19px;
502 | }
503 |
504 | .channelHeader-3Gd2xq {
505 | padding-left: 35px;
506 | margin-left: -15px;
507 | margin-right: -15px;
508 | }
509 |
510 | .markReadButton-qAjML_ {
511 | margin-right: 20px;
512 | }
513 |
514 | .collapseButton-2ZsEjz {
515 | padding-left: 12px;
516 | }
517 |
518 | .menu-Sp6bN1 {
519 | background-color: #1e2024;
520 | }
521 |
522 | .button-1I8KM5 {
523 | background-color: transparent;
524 | }
525 |
526 | .icon-QsFCBC {
527 | transform: scale(1.2);
528 | }
529 |
530 | div.gm-toasts > div {
531 | background-color: rgb(43, 44, 46);
532 | }
533 |
534 | .default-cS_caM {
535 | padding: 0px 0px 10px 10px;
536 | }
537 |
538 | .container-3sNMIc {
539 | margin-left: -8px;
540 | }
541 |
542 | .theme-dark .toasts {
543 | position: fixed;
544 | max-width: max-content;
545 | left: 0px !important;
546 | bottom: 0px !important;
547 | background-color: rgb(43, 44, 46) !important;
548 | color: white;
549 | padding: 12px;
550 | border: 4px solid transparent;
551 | border-radius: 15px;
552 | }
553 |
554 | .folder-1hbNCn,
555 | .expandedFolderIconWrapper-Huv7rA {
556 | background: transparent;
557 | }
558 |
559 | .form-2fGMdU {
560 | padding-top: 7.25px;
561 | }
562 |
563 | .form-2fGMdU::before {
564 | display: none;
565 | }
566 |
567 | .artwork-L5TAwQ {
568 | display: none;
569 | }
570 |
--------------------------------------------------------------------------------