From 5651c6975fb02cd68f7250752ff0b996e652522e Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 16:23:12 +0200 Subject: [PATCH 01/10] feat: add support for custom themes via live, user-provided CSS file --- README.md | 107 +++- patches/16-custom-theme.patch | 79 +++ themes/template.css | 974 ++++++++++++++++++++++++++++++++++ 3 files changed, 1133 insertions(+), 27 deletions(-) create mode 100644 patches/16-custom-theme.patch create mode 100644 themes/template.css diff --git a/README.md b/README.md index e184bf9..b611a90 100644 --- a/README.md +++ b/README.md @@ -75,35 +75,88 @@ You can tweak how the app behaves with the [launch options](#usage) below (start ## Usage -| Option | Description | -| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | -| `--start-in-tray` | Start the app in the tray (see [patch](./patches/01-start-in-tray.patch)) | -| `--disable-systray` | Quit the app when the window is closed (see [patch](./patches/02-start-without-tray.patch)) | -| `--keep-kernel` | Use the exact kernel version (see [patch](./patches/04-remove-os-information.patch))
_This feature impacts privacy._ | -| `--hide-offline-banner` | Hide the "Application is offline" banner that appears when using a VPN or DNS blocker (see [patch](./patches/08-hide-offline-banner.patch)) | -| `--disable-animations` | Disable animations (see [patch](./patches/09-disable-animations.patch)) | -| `--disable-notifications` | Disable notifications (see [patch](./patches/10-disable-notifications.patch)) | -| `--sync-theme` _\*_ | Sync the app's theme (dark/light) to the OS theme (see [patch](./patches/15-sync-theme.systempatch)) | -| `--disable-hardware-acceleration` | Disable hardware acceleration (useful for systems with GPU issues) (see [patch](./patches/13-disable-hardware-acceleration.patch)) | -| `--log-level` | Set the log level (`silly`,`debug`,`verbose`,`info`,`warn`,`error`) (see [patch](./patches/06-control-log-level.patch)) | -| `--enable-wayland-ime` `--ozone-platform-hint=auto` `--wayland-text-input-version=3` | Enable IME keyboard support on Wayland | - -| Environment variable | Options | Description | -| ---------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------- | -| `DZ_START_IN_TRAY` | `yes`,`no` | Start the app in the tray (see [patch](./patches/01-start-in-tray.patch)) | -| `DZ_DISABLE_SYSTRAY` | `yes`,`no` | Quit the app when the window is closed (see [patch](./patches/02-start-without-tray.patch)) | -| `DZ_KEEP_KERNEL` | `yes`,`no` | Use the exact kernel version (see [patch](./patches/04-remove-os-information.patch)) | -| `DZ_LOG_LEVEL` | `silly`,`debug`,`verbose`,`info`,`warn`,`error` | Set the log level (see [patch](./patches/06-control-log-level.patch)) | -| `DZ_HIDE_OFFLINE_BANNER` | `yes`,`no` | Hide the "Application is offline" banner (see [patch](./patches/08-hide-offline-banner.patch)) | -| `DZ_DISABLE_ANIMATIONS` | `yes`,`no` | Disable animations (see [patch](./patches/09-disable-animations.patch)) | -| `DZ_DISABLE_NOTIFICATIONS` | `yes`,`no` | Disable notifications (see [patch](./patches/10-disable-notifications.patch)) | -| `DZ_SYNC_THEME` _\*_ | `yes`,`no` | Sync the app's theme to the OS theme (see [patch](./patches/15-sync-theme.patch)) | -| `DZ_DISABLE_HARDWARE_ACCELERATION` | `yes`,`no` | Disable hardware acceleration (see [patch](./patches/13-disable-hardware-acceleration.patch)) | -| `DZ_RESOURCES_PATH` | _path_ | Override the default resources path (see [patch](./patches/14-override-resources-path.patch)) | -| `DZ_DEVTOOLS` | `yes`,`no` | Enable the developer console (ctrl+shift+i) | +| Option | Description | +| ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--start-in-tray` | Start the app in the tray (see [patch](./patches/01-start-in-tray.patch)) | +| `--disable-systray` | Quit the app when the window is closed (see [patch](./patches/02-start-without-tray.patch)) | +| `--keep-kernel` | Use the exact kernel version (see [patch](./patches/04-remove-os-information.patch))
_This feature impacts privacy._ | +| `--hide-offline-banner` | Hide the "Application is offline" banner that appears when using a VPN or DNS blocker (see [patch](./patches/08-hide-offline-banner.patch)) | +| `--disable-animations` | Disable animations (see [patch](./patches/09-disable-animations.patch)) | +| `--disable-notifications` | Disable notifications (see [patch](./patches/10-disable-notifications.patch)) | +| `--sync-theme` _\*_ | Sync the app's theme (dark/light) to the OS theme (see [patch](./patches/15-sync-theme.systempatch)) | +| `--custom-theme=` | Load a custom CSS theme from ``, applied and hot-reloaded at runtime (see [Custom themes](#custom-themes) and [patch](./patches/16-custom-theme.patch)) | +| `--disable-hardware-acceleration` | Disable hardware acceleration (useful for systems with GPU issues) (see [patch](./patches/13-disable-hardware-acceleration.patch)) | +| `--log-level` | Set the log level (`silly`,`debug`,`verbose`,`info`,`warn`,`error`) (see [patch](./patches/06-control-log-level.patch)) | +| `--enable-wayland-ime` `--ozone-platform-hint=auto` `--wayland-text-input-version=3` | Enable IME keyboard support on Wayland | + +| Environment variable | Options | Description | +| ---------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| `DZ_START_IN_TRAY` | `yes`,`no` | Start the app in the tray (see [patch](./patches/01-start-in-tray.patch)) | +| `DZ_DISABLE_SYSTRAY` | `yes`,`no` | Quit the app when the window is closed (see [patch](./patches/02-start-without-tray.patch)) | +| `DZ_KEEP_KERNEL` | `yes`,`no` | Use the exact kernel version (see [patch](./patches/04-remove-os-information.patch)) | +| `DZ_LOG_LEVEL` | `silly`,`debug`,`verbose`,`info`,`warn`,`error` | Set the log level (see [patch](./patches/06-control-log-level.patch)) | +| `DZ_HIDE_OFFLINE_BANNER` | `yes`,`no` | Hide the "Application is offline" banner (see [patch](./patches/08-hide-offline-banner.patch)) | +| `DZ_DISABLE_ANIMATIONS` | `yes`,`no` | Disable animations (see [patch](./patches/09-disable-animations.patch)) | +| `DZ_DISABLE_NOTIFICATIONS` | `yes`,`no` | Disable notifications (see [patch](./patches/10-disable-notifications.patch)) | +| `DZ_SYNC_THEME` _\*_ | `yes`,`no` | Sync the app's theme to the OS theme (see [patch](./patches/15-sync-theme.patch)) | +| `DZ_DISABLE_HARDWARE_ACCELERATION` | `yes`,`no` | Disable hardware acceleration (see [patch](./patches/13-disable-hardware-acceleration.patch)) | +| `DZ_RESOURCES_PATH` | _path_ | Override the default resources path (see [patch](./patches/14-override-resources-path.patch)) | +| `DZ_CUSTOM_THEME` | _path_ | Load a custom CSS theme from _path_ (see [Custom themes](#custom-themes) and [patch](./patches/16-custom-theme.patch)) | +| `DZ_DEVTOOLS` | `yes`,`no` | Enable the developer console (ctrl+shift+i) | _\*_ This feature does not work on Flatpak because of strict sandboxing. +## Custom themes + +You can restyle the whole app with your own CSS file, for both light and dark modes. The file is read and injected **at runtime** (not at build time), and it is **re-applied automatically every time you save it** — keep the app open, edit your CSS, and watch the changes apply live. + +### Quick start + +1. Copy the template [`themes/template.css`](./themes/template.css) somewhere in your home directory, e.g. `~/.config/deezer/my-theme.css`. +2. Launch the app pointing at it, using either the flag or the environment variable: + + ```sh + deezer-desktop --custom-theme=$HOME/.config/deezer/my-theme.css + # or + DZ_CUSTOM_THEME=$HOME/.config/deezer/my-theme.css deezer-desktop + ``` + + Relative paths are resolved from the current working directory. If the flag and the environment variable are both set, the flag wins. + +3. Edit your CSS file and save — the app reloads the theme on the fly. + +### Writing your theme + +Your rules are injected last into the page, so they take precedence over the app's own styles. + +The current mode is exposed on the root element and on ``, which lets you scope rules to light or dark: + +```css +[data-theme="dark"] body { + /* dark-mode rules */ +} +[data-theme="light"] body { + /* light-mode rules */ +} +``` + +The full list of themeable variables, prefilled with their default values for both modes, is in the template file — uncomment what you want to change. + +Pair this with [`--sync-theme`](#usage) so the mode follows your OS setting automatically. + +### Debugging and inspecting the app + +To discover which selectors to target, launch the app with the developer tools enabled: + +```sh +DZ_DEVTOOLS=yes deezer-desktop +``` + +Then press Ctrl+Shift+I to open the DevTools and use the element picker to inspect elements and read their classes and CSS custom properties (found on the `:root` element). If your theme does not seem to load, check the DevTools **Console** — the app logs a `[custom-theme]` error if the file cannot be read. + +> [!NOTE] +> Deezer's generated class names can change between app versions. Prefer overriding CSS custom properties on `:root` and using stable, structural selectors so your theme keeps working across updates. + ## Building from source ### Available targets @@ -273,7 +326,7 @@ This is usually caused by stale site data from a previous session. Clear the app DZ_DEVTOOLS=yes ./deezer-desktop # or any other way to launch the app ``` -2. Open the devtools (ctrl+shift+i) and go to the Application tab. +2. Open the devtools (Ctrl+Shift+i) and go to the Application tab. 3. In the left sidebar, under Storage, click on Clear storage. diff --git a/patches/16-custom-theme.patch b/patches/16-custom-theme.patch new file mode 100644 index 0000000..361d2d0 --- /dev/null +++ b/patches/16-custom-theme.patch @@ -0,0 +1,79 @@ +From 73f248b3710a2eada877999df5fa9bb9bbb1a28e Mon Sep 17 00:00:00 2001 +From: josselinonduty +Date: Mon, 24 Aug 2026 12:00:00 +0200 +Subject: [PATCH] feat: custom theme via user-provided CSS file + +--- + build/main.js | 11 +++++++++++ + build/preload.js | 35 +++++++++++++++++++++++++++++++++++ + 2 files changed, 46 insertions(+) + +diff --git a/build/main.js b/build/main.js +index d01b1dc..5d3c1c1 100644 +--- a/build/main.js ++++ b/build/main.js +@@ -3127,6 +3127,17 @@ + (process.argv.some((arg) => arg === "--sync-theme") || + "yes" === process.env.DZ_SYNC_THEME) && + "--sync-theme", ++ (() => { ++ const arg = process.argv.find((arg) => ++ arg.startsWith("--custom-theme=") ++ ); ++ const rawPath = arg ++ ? arg.slice("--custom-theme=".length) ++ : process.env.DZ_CUSTOM_THEME; ++ return rawPath ++ ? "--custom-theme=" + external_path_default().resolve(rawPath) ++ : false; ++ })(), + ].filter(Boolean), + }, + windowOptions = { +diff --git a/build/preload.js b/build/preload.js +index 7d834ad..eba8bbb 100644 +--- a/build/preload.js ++++ b/build/preload.js +@@ -571,6 +571,39 @@ + attributeFilter: ["data-theme"], + }); + } ++ const customThemeArg = process.argv.find((arg) => ++ arg.startsWith("--custom-theme=") ++ ); ++ if (customThemeArg) { ++ const fs = require("fs"); ++ const themePath = customThemeArg.slice("--custom-theme=".length); ++ const STYLE_ID = "dz-custom-theme"; ++ const applyCustomTheme = () => { ++ let css; ++ try { ++ css = fs.readFileSync(themePath, "utf8"); ++ } catch (err) { ++ console.error( ++ "[custom-theme] Could not read theme file: " + themePath, ++ err ++ ); ++ return; ++ } ++ let style = document.getElementById(STYLE_ID); ++ if (!style) { ++ style = document.createElement("style"); ++ style.id = STYLE_ID; ++ } ++ style.textContent = css; ++ document.head.appendChild(style); ++ }; ++ applyCustomTheme(); ++ try { ++ fs.watchFile(themePath, { interval: 500 }, applyCustomTheme); ++ } catch (err) { ++ console.error("[custom-theme] Could not watch theme file", err); ++ } ++ } + }), + (module.exports = {}); + })(); +-- +2.53.0 + diff --git a/themes/template.css b/themes/template.css new file mode 100644 index 0000000..bdc2dda --- /dev/null +++ b/themes/template.css @@ -0,0 +1,974 @@ +/* ========================================================================= + * Deezer for Linux — custom theme template + * ========================================================================= + * + * Copy this file, uncomment what you want to change, save. Re-injected + * live on every save — no rebuild, no restart. + * + * deezer-desktop --custom-theme=/path/to/my-theme.css + * # or + * DZ_CUSTOM_THEME=/path/to/my-theme.css deezer-desktop + * + * Sections 1-3 are the palette — edit these, that's usually enough. + * Section 4 wires the app's runtime "tempo" tokens back to sections 1-3 + * and ships pre-wired/ON by default: treat it as source code, not + * something to edit, unless you want to hand-tune one specific state. + * + * ... + * ... + * + * Pair with --sync-theme to follow your OS light/dark setting. + * + * DZ_DEVTOOLS=yes deezer-desktop # inspect elements, Ctrl+Shift+I + * Deezer's generated class names change between versions — prefer the + * variables below and structural selectors over generated classes. + * ========================================================================= */ + +/* ========================================================================= + * 1. GLOBAL BASE PALETTE (shared by both light and dark modes) + * ========================================================================= */ +:root { + /* ---- Accent (Deezer purple) ---- */ + /* --color-accent-main: #a238ff; */ + /* --color-accent-strong: #9333e8; */ + /* --color-accent-weak: #c17aff; */ + /* --color-accent-light: #d09aff; */ + + /* ---- Feedback (error / success / warning) ---- */ + /* --color-feedback-error: #df3c3c; */ + /* --color-feedback-success: #00b23d; */ + /* --color-feedback-warning: #ec7f11; */ + + /* ---- Absolute black / white ---- */ + /* --color-black: #000; */ + /* --color-white: #fff; */ + + /* ---- Neutral grey ramp (50 = lightest ... 900 = darkest) ---- */ + /* --color-grey-50: #f8f8f9; */ + /* --color-grey-100: #f4f4f4; */ + /* --color-grey-200: #eaeaea; */ + /* --color-grey-300: #d1d1d6; */ + /* --color-grey-400: #a2a2ad; */ + /* --color-grey-500: #52525d; */ + /* --color-grey-600: #32323d; */ + /* --color-grey-700: #23232d; */ + /* --color-grey-800: #191922; */ + /* --color-grey-900: #121216; */ + + /* ---- Fixed dark/light grey ramps (do NOT swap with the mode; used by + * always-dark chrome like the player bar even in light mode) ---- */ + /* --color-dark-grey-200: #60606c; */ + /* --color-dark-grey-300: #52525d; */ + /* --color-dark-grey-400: #42424c; */ + /* --color-dark-grey-500: #32323d; */ + /* --color-dark-grey-600: #23232d; */ + /* --color-dark-grey-700: #191922; */ + /* --color-dark-grey-800: #191919; */ + /* --color-dark-grey-900: #121216; */ + /* --color-light-grey-50: #f8f8f9; */ + /* --color-light-grey-100: #f4f4f4; */ + /* --color-light-grey-200: #f2f2f2; */ + /* --color-light-grey-300: #eaeaea; */ + /* --color-light-grey-400: #dfdfe0; */ + /* --color-light-grey-500: #d1d1d6; */ + /* --color-light-grey-600: #bebec7; */ + /* --color-light-grey-700: #a2a2ad; */ + /* --color-light-grey-800: #92929d; */ + /* --color-light-grey-900: #72727d; */ +} + +/* ========================================================================= + * 2. LIGHT MODE (defaults shown) + * ========================================================================= */ +:root, +[data-theme="light"] { + /* ---- Backgrounds ---- */ + /* --color-bg-main: #fdfcfe; */ + /* --color-bg-secondary: #f5f2f8; */ + /* --color-bg-tertiary: #ebe7ee; */ + /* --color-bg-tertiary-hover: #e1dde4; */ + /* --color-bg-tertiary-pressed: var(--color-bg-tertiary-hover); */ + /* --color-bg-contrast: var(--color-grey-200); */ + /* --color-bg-inverse: var(--color-grey-900); */ + /* --transparent-bg: #ffffff80; */ + + /* ---- Text ---- */ + /* --color-text-main: #0f0d13; */ + /* --color-text-secondary: #6f6d71; */ + /* --color-text-disabled: #a9a6aa; */ + /* --color-text-inverse: #fff; */ + + /* ---- Borders & dividers ---- */ + /* --color-border-neutral-primary: #c2c0c4; */ + /* --color-border-neutral-secondary: var(--color-border-neutral-primary); */ + /* --color-divider-main: #c2c0c4; */ + + /* ---- Neutral aliases ---- */ + /* --color-neutral-main: var(--color-grey-300); */ + /* --color-neutral-strong: var(--color-grey-400); */ + /* --color-neutral-weak: var(--color-grey-200); */ +} + +/* ========================================================================= + * 3. DARK MODE (defaults shown) + * ========================================================================= */ +[data-theme="dark"] { + /* ---- Backgrounds ---- */ + /* --color-bg-main: #0f0d13; */ + /* --color-bg-secondary: #1b191f; */ + /* --color-bg-tertiary: #29282d; */ + /* --color-bg-tertiary-hover: #3a393d; */ + /* --color-bg-tertiary-pressed: var(--color-bg-tertiary-hover); */ + /* --color-bg-contrast: var(--color-grey-600); */ + /* --color-bg-inverse: var(--color-grey-50); */ + /* --transparent-bg: #0000004d; */ + + /* ---- Text ---- */ + /* --color-text-main: #fdfcfe; */ + /* --color-text-secondary: #a9a6aa; */ + /* --color-text-disabled: #555257; */ + /* --color-text-inverse: #000; */ + + /* ---- Borders & dividers ---- */ + /* --color-border-neutral-primary: #555257; */ + /* --color-border-neutral-secondary: #fdfcfe; */ + /* --color-divider-main: #555257; */ + + /* ---- Neutral aliases ---- */ + /* --color-neutral-main: var(--color-grey-500); */ + /* --color-neutral-strong: var(--color-grey-400); */ + /* --color-neutral-weak: var(--color-grey-600); */ + + /* ---- Brand accents used only in dark mode ---- */ + /* --color-bg-brand-duo: #96f9f3; */ + /* --color-bg-brand-trio: #96f9f3; */ + /* --color-bg-brand-duo-selected: #2e4d4a; */ + /* --color-bg-brand-family-selected: #461c11; */ + /* --color-bg-brand-premium-selected: #32124e; */ + /* --color-text-brand-duo: var(--color-black); */ + /* --color-text-brand-trio: var(--color-black); */ +} + +/* ========================================================================= + * 4. TEMPO DESIGN TOKENS (pre-wired source — power users only) + * ========================================================================= + * Most of the app's chrome reads this separate "tempo" token layer, not + * sections 1-3 directly — and the app's own JS also writes to it at + * runtime. Every line below is a var() back to sections 1-3 (no literal + * colors) and uses !important to reliably win over that runtime value. + * This block is ON by default: edit sections 1-3 instead, unless you need + * to override one specific state. Some tokens exist in both onDark/on-dark + * casings in the app's CSS (upstream inconsistency) — override both if you + * touch one. + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-disabled: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-hovered: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-pressed: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-disabled: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-hovered: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-pressed: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-disabled: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-hovered: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-pressed: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-disabled: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-focused: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-hovered: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-pressed: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-disabled: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-focused: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-hovered: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-pressed: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-disabled: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-focused: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-hovered: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-pressed: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-disabled: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-hovered: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-pressed: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-disabled: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-hovered: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-pressed: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-disabled: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-hovered: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-pressed: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-disabled: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-hovered: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-pressed: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-disabled: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-hovered: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-pressed: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-disabled: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-hovered: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-pressed: var( + --color-feedback-warning + ) !important; + + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +[data-theme="light"] { + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +[data-theme="dark"] { + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * 5. ARBITRARY CSS + * ========================================================================= */ From 5288dd7645bd49ec17c22213ff4e0e88d8402ace Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 16:23:43 +0200 Subject: [PATCH 02/10] docs(theme): add solarized theme --- README.md | 14 + themes/solarized.css | 830 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 844 insertions(+) create mode 100644 themes/solarized.css diff --git a/README.md b/README.md index b611a90..431dbe8 100644 --- a/README.md +++ b/README.md @@ -144,6 +144,20 @@ The full list of themeable variables, prefilled with their default values for bo Pair this with [`--sync-theme`](#usage) so the mode follows your OS setting automatically. +### Ready-made themes + +The [`themes/`](./themes) folder contains drop-in themes you can use as-is or as a reference: + +| Theme | Modes | +| ----------------------------------- | ------------ | +| [Solarized](./themes/solarized.css) | Light & dark | + +For example: + +```sh +deezer-desktop --sync-theme --custom-theme=/path/to/themes/solarized.css +``` + ### Debugging and inspecting the app To discover which selectors to target, launch the app with the developer tools enabled: diff --git a/themes/solarized.css b/themes/solarized.css new file mode 100644 index 0000000..7badefe --- /dev/null +++ b/themes/solarized.css @@ -0,0 +1,830 @@ +/* ========================================================================= + * Solarized — a custom theme for Deezer for Linux + * ========================================================================= + * + * https://ethanschoonover.com/solarized/ — see themes/template.css for the + * full list of variables. + * + * deezer-desktop --sync-theme --custom-theme=/path/to/themes/solarized.css + * + * ---- Solarized reference ------------------------------------------------ + * base03 #002b36 base02 #073642 base01 #586e75 base00 #657b83 + * base0 #839496 base1 #93a1a1 base2 #eee8d5 base3 #fdf6e3 + * yellow #b58900 orange #cb4b16 red #dc322f magenta #d33682 + * violet #6c71c4 blue #268bd2 cyan #2aa198 green #859900 + * ========================================================================= */ + +/* ========================================================================= + * Shared base palette — Solarized blue accent + a base03..base3 neutral ramp. + * Remapping the grey ramp shifts every neutral surface in both modes. + * ========================================================================= */ +:root { + /* Accent: Solarized blue instead of Deezer purple */ + --color-accent-main: #268bd2; + --color-accent-strong: #1a6ba8; + --color-accent-weak: #6cb0e0; + --color-accent-light: #9cccec; + --color-accent-stronger: #14547f; /* deeper "pressed" tier */ + + /* Feedback (error / success / warning) — one default/disabled/hovered/ + * pressed variable per type, unlike template.css's single flat color */ + --color-feedback-error: #dc322f; + --color-feedback-error-disabled: #e2726f; + --color-feedback-error-hovered: #c22824; + --color-feedback-error-pressed: #a81f1c; + --color-feedback-success: #859900; + --color-feedback-success-disabled: #a8b84d; + --color-feedback-success-hovered: #6b7a00; + --color-feedback-success-pressed: #556100; + --color-feedback-warning: #b58900; + --color-feedback-warning-disabled: #d1ab4d; + --color-feedback-warning-hovered: #8f6d00; + --color-feedback-warning-pressed: #6b5200; + + /* Neutral ramp mapped onto Solarized base tones (light -> dark) */ + --color-grey-50: #fdf6e3; /* base3 */ + --color-grey-100: #f5eeda; /* base3/base2 */ + --color-grey-200: #eee8d5; /* base2 */ + --color-grey-300: #ccc9b6; /* base2/base1 */ + --color-grey-400: #93a1a1; /* base1 */ + --color-grey-500: #586e75; /* base01 */ + --color-grey-600: #113640; /* base02/base03 */ + --color-grey-700: #0b333d; /* base02 */ + --color-grey-800: #073642; /* base02 */ + --color-grey-900: #002b36; /* base03 */ + + /* Fixed dark/light grey ramps — do NOT swap with the mode */ + --color-dark-grey-200: #748b91; + --color-dark-grey-300: #64787e; + --color-dark-grey-400: #5b7278; + --color-dark-grey-500: #586e75; /* base01 */ + --color-dark-grey-600: #113640; + --color-dark-grey-700: #0b333d; + --color-dark-grey-800: #073642; /* base02 */ + --color-dark-grey-900: #002b36; /* base03 */ + --color-light-grey-50: #fdf6e3; /* base3 */ + --color-light-grey-100: #f5eeda; + --color-light-grey-200: #f2ecd9; + --color-light-grey-300: #eee8d5; /* base2 */ + --color-light-grey-400: #d9d3ba; + --color-light-grey-500: #ccc9b6; + --color-light-grey-600: #93a1a1; /* base1 */ + --color-light-grey-700: #839496; /* base0 */ + --color-light-grey-800: #6e838b; + --color-light-grey-900: #586e75; /* base01 */ +} + +/* ========================================================================= + * Tempo design tokens — see themes/template.css section 4 for the full + * rationale. Mode-independent tokens (accent + feedback + onDark/onLight). + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var(--color-accent-stronger) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var(--color-accent-stronger) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var(--color-accent-stronger) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var(--color-accent-stronger) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var(--color-feedback-error) !important; + --tempo-colors-background-feedback-error-disabled: var(--color-feedback-error-disabled) !important; + --tempo-colors-background-feedback-error-hovered: var(--color-feedback-error-hovered) !important; + --tempo-colors-background-feedback-error-pressed: var(--color-feedback-error-pressed) !important; + --tempo-colors-background-feedback-success-default: var(--color-feedback-success) !important; + --tempo-colors-background-feedback-success-disabled: var(--color-feedback-success-disabled) !important; + --tempo-colors-background-feedback-success-hovered: var(--color-feedback-success-hovered) !important; + --tempo-colors-background-feedback-success-pressed: var(--color-feedback-success-pressed) !important; + --tempo-colors-background-feedback-warning-default: var(--color-feedback-warning) !important; + --tempo-colors-background-feedback-warning-disabled: var(--color-feedback-warning-disabled) !important; + --tempo-colors-background-feedback-warning-hovered: var(--color-feedback-warning-hovered) !important; + --tempo-colors-background-feedback-warning-pressed: var(--color-feedback-warning-pressed) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var(--color-accent-stronger) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var(--color-accent-stronger) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var(--color-feedback-error) !important; + --tempo-colors-border-feedback-error-disabled: var(--color-feedback-error-disabled) !important; + --tempo-colors-border-feedback-error-focused: var(--color-feedback-error) !important; + --tempo-colors-border-feedback-error-hovered: var(--color-feedback-error-hovered) !important; + --tempo-colors-border-feedback-error-pressed: var(--color-feedback-error-pressed) !important; + --tempo-colors-border-feedback-success-default: var(--color-feedback-success) !important; + --tempo-colors-border-feedback-success-disabled: var(--color-feedback-success-disabled) !important; + --tempo-colors-border-feedback-success-focused: var(--color-feedback-success) !important; + --tempo-colors-border-feedback-success-hovered: var(--color-feedback-success-hovered) !important; + --tempo-colors-border-feedback-success-pressed: var(--color-feedback-success-pressed) !important; + --tempo-colors-border-feedback-warning-default: var(--color-feedback-warning) !important; + --tempo-colors-border-feedback-warning-disabled: var(--color-feedback-warning-disabled) !important; + --tempo-colors-border-feedback-warning-focused: var(--color-feedback-warning) !important; + --tempo-colors-border-feedback-warning-hovered: var(--color-feedback-warning-hovered) !important; + --tempo-colors-border-feedback-warning-pressed: var(--color-feedback-warning-pressed) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var(--color-accent-stronger) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var(--color-accent-stronger) !important; + --tempo-colors-icon-feedback-error-default: var(--color-feedback-error) !important; + --tempo-colors-icon-feedback-error-disabled: var(--color-feedback-error-disabled) !important; + --tempo-colors-icon-feedback-error-hovered: var(--color-feedback-error-hovered) !important; + --tempo-colors-icon-feedback-error-pressed: var(--color-feedback-error-pressed) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var(--color-feedback-success) !important; + --tempo-colors-icon-feedback-success-disabled: var(--color-feedback-success-disabled) !important; + --tempo-colors-icon-feedback-success-hovered: var(--color-feedback-success-hovered) !important; + --tempo-colors-icon-feedback-success-pressed: var(--color-feedback-success-pressed) !important; + --tempo-colors-icon-feedback-warning-default: var(--color-feedback-warning) !important; + --tempo-colors-icon-feedback-warning-disabled: var(--color-feedback-warning-disabled) !important; + --tempo-colors-icon-feedback-warning-hovered: var(--color-feedback-warning-hovered) !important; + --tempo-colors-icon-feedback-warning-pressed: var(--color-feedback-warning-pressed) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var(--color-accent-stronger) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var(--color-accent-stronger) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var(--color-feedback-error) !important; + --tempo-colors-text-feedback-error-disabled: var(--color-feedback-error-disabled) !important; + --tempo-colors-text-feedback-error-hovered: var(--color-feedback-error-hovered) !important; + --tempo-colors-text-feedback-error-pressed: var(--color-feedback-error-pressed) !important; + --tempo-colors-text-feedback-success-default: var(--color-feedback-success) !important; + --tempo-colors-text-feedback-success-disabled: var(--color-feedback-success-disabled) !important; + --tempo-colors-text-feedback-success-hovered: var(--color-feedback-success-hovered) !important; + --tempo-colors-text-feedback-success-pressed: var(--color-feedback-success-pressed) !important; + --tempo-colors-text-feedback-warning-default: var(--color-feedback-warning) !important; + --tempo-colors-text-feedback-warning-disabled: var(--color-feedback-warning-disabled) !important; + --tempo-colors-text-feedback-warning-hovered: var(--color-feedback-warning-hovered) !important; + --tempo-colors-text-feedback-warning-pressed: var(--color-feedback-warning-pressed) !important; + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +/* ========================================================================= + * Solarized Light (base3 background, base00 text) + * ========================================================================= */ +:root, +[data-theme="light"] { + /* Backgrounds */ + --color-bg-main: #fdf6e3; /* base3 */ + --color-bg-secondary: #eee8d5; /* base2 */ + --color-bg-tertiary: #e6dfc7; /* base2, darker */ + --color-bg-tertiary-hover: #ddd4b8; + --color-bg-tertiary-pressed: #d4c9a8; + --color-bg-contrast: #eee8d5; + --color-bg-inverse: #002b36; /* base03 */ + --transparent-bg: #fdf6e380; + + /* Text */ + --color-text-main: #586e75; /* base01 (strong body) */ + --color-text-secondary: #657b83; /* base00 */ + --color-text-disabled: #93a1a1; /* base1 */ + --color-text-inverse: #fdf6e3; /* base3 */ + + /* Borders & dividers */ + --color-border-neutral-primary: #ddd6c1; + --color-border-neutral-secondary: #93a1a1; + --color-divider-main: #ddd6c1; + + /* Neutral aliases */ + --color-neutral-main: #93a1a1; + --color-neutral-strong: #586e75; + --color-neutral-weak: #eee8d5; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * Solarized Dark (base03 background, base0 text) + * ========================================================================= */ +[data-theme="dark"] { + /* Backgrounds */ + --color-bg-main: #002b36; /* base03 */ + --color-bg-secondary: #073642; /* base02 */ + --color-bg-tertiary: #0d4250; + --color-bg-tertiary-hover: #135263; + --color-bg-tertiary-pressed: #1a5b6e; + --color-bg-contrast: #073642; + --color-bg-inverse: #fdf6e3; /* base3 */ + --transparent-bg: #002b364d; + + /* Text */ + --color-text-main: #93a1a1; /* base1 (bright body) */ + --color-text-secondary: #839496; /* base0 */ + --color-text-disabled: #586e75; /* base01 */ + --color-text-inverse: #002b36; /* base03 */ + + /* Borders & dividers */ + --color-border-neutral-primary: #0d4250; + --color-border-neutral-secondary: #93a1a1; + --color-divider-main: #0d4250; + + /* Neutral aliases */ + --color-neutral-main: #586e75; + --color-neutral-strong: #93a1a1; + --color-neutral-weak: #073642; + + /* Brand accents retinted toward Solarized cyan */ + --color-bg-brand-duo: #2aa198; + --color-bg-brand-trio: #2aa198; + --color-bg-brand-duo-selected: #0d4250; + --color-text-brand-duo: #002b36; + --color-text-brand-trio: #002b36; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} From 5be82b0589e6c96192e56243f5966be8b4b4fda5 Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 16:55:39 +0200 Subject: [PATCH 03/10] docs(theme): add Nord theme --- README.md | 1 + themes/nord.css | 833 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 834 insertions(+) create mode 100644 themes/nord.css diff --git a/README.md b/README.md index 431dbe8..552d0d5 100644 --- a/README.md +++ b/README.md @@ -151,6 +151,7 @@ The [`themes/`](./themes) folder contains drop-in themes you can use as-is or as | Theme | Modes | | ----------------------------------- | ------------ | | [Solarized](./themes/solarized.css) | Light & dark | +| [Nord](./themes/nord.css) | Light & dark | For example: diff --git a/themes/nord.css b/themes/nord.css new file mode 100644 index 0000000..2da5391 --- /dev/null +++ b/themes/nord.css @@ -0,0 +1,833 @@ +/* ========================================================================= + * Nord — a custom theme for Deezer for Linux + * ========================================================================= + * + * https://www.nordtheme.com/ — see themes/template.css for the full list + * of variables. + * + * deezer-desktop --sync-theme --custom-theme=/path/to/themes/nord.css + * + * ---- Nord reference ------------------------------------------------- + * Polar Night: nord0 #2e3440 nord1 #3b4252 nord2 #434c5e nord3 #4c566a + * Snow Storm: nord4 #d8dee9 nord5 #e5e9f0 nord6 #eceff4 + * Frost: nord7 #8fbcbb nord8 #88c0d0 nord9 #81a1c1 nord10 #5e81ac + * Aurora: nord11 #bf616a (red) nord12 #d08770 (orange) + * nord13 #ebcb8b (yellow) nord14 #a3be8c (green) + * nord15 #b48ead (purple) + * ========================================================================= */ + +/* ========================================================================= + * Shared base palette — Nord frost accent + a Polar Night/Snow Storm + * neutral ramp. Remapping the grey ramp shifts every neutral surface in + * both modes. + * ========================================================================= */ +:root { + /* Accent: Nord frost ramp instead of Deezer purple */ + --color-accent-main: #81a1c1; /* nord9 */ + --color-accent-strong: #5e81ac; /* nord10 */ + --color-accent-weak: #88c0d0; /* nord8 */ + --color-accent-light: #a3d0dc; + --color-accent-stronger: #4c6a92; /* deeper "pressed" tier */ + + /* Feedback (error / success / warning) — one default/disabled/hovered/ + * pressed variable per type, unlike template.css's single flat color */ + --color-feedback-error: #bf616a; /* nord11 */ + --color-feedback-error-disabled: #d3939a; + --color-feedback-error-hovered: #a94f58; + --color-feedback-error-pressed: #8f424a; + --color-feedback-success: #a3be8c; /* nord14 */ + --color-feedback-success-disabled: #c1d4b0; + --color-feedback-success-hovered: #8cab72; + --color-feedback-success-pressed: #75935c; + --color-feedback-warning: #ebcb8b; /* nord13 */ + --color-feedback-warning-disabled: #f0d9a8; + --color-feedback-warning-hovered: #d4af5e; + --color-feedback-warning-pressed: #bc9645; + + /* Neutral ramp mapped onto Nord Polar Night/Snow Storm tones (light -> dark) */ + --color-grey-50: #eceff4; /* nord6 */ + --color-grey-100: #e5e9f0; /* nord5 */ + --color-grey-200: #d8dee9; /* nord4 */ + --color-grey-300: #b7c0d1; + --color-grey-400: #949fb2; + --color-grey-500: #6b7890; + --color-grey-600: #4c566a; /* nord3 */ + --color-grey-700: #434c5e; /* nord2 */ + --color-grey-800: #3b4252; /* nord1 */ + --color-grey-900: #2e3440; /* nord0 */ + + /* Fixed dark/light grey ramps — do NOT swap with the mode */ + --color-dark-grey-200: #7b88a1; + --color-dark-grey-300: #6b7890; + --color-dark-grey-400: #5b6b83; + --color-dark-grey-500: #4c566a; /* nord3 */ + --color-dark-grey-600: #434c5e; /* nord2 */ + --color-dark-grey-700: #3b4252; /* nord1 */ + --color-dark-grey-800: #333a48; + --color-dark-grey-900: #2e3440; /* nord0 */ + --color-light-grey-50: #eceff4; /* nord6 */ + --color-light-grey-100: #e5e9f0; /* nord5 */ + --color-light-grey-200: #dee3ec; + --color-light-grey-300: #d8dee9; /* nord4 */ + --color-light-grey-400: #c6cdda; + --color-light-grey-500: #b7c0d1; + --color-light-grey-600: #9aa5b1; + --color-light-grey-700: #838fa1; + --color-light-grey-800: #6b7890; + --color-light-grey-900: #4c566a; /* nord3 */ +} + +/* ========================================================================= + * Tempo design tokens — see themes/template.css section 4 for the full + * rationale. Mode-independent tokens (accent + feedback + onDark/onLight). + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var(--color-accent-stronger) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var(--color-accent-stronger) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var(--color-accent-stronger) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var(--color-accent-stronger) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var(--color-feedback-error) !important; + --tempo-colors-background-feedback-error-disabled: var(--color-feedback-error-disabled) !important; + --tempo-colors-background-feedback-error-hovered: var(--color-feedback-error-hovered) !important; + --tempo-colors-background-feedback-error-pressed: var(--color-feedback-error-pressed) !important; + --tempo-colors-background-feedback-success-default: var(--color-feedback-success) !important; + --tempo-colors-background-feedback-success-disabled: var(--color-feedback-success-disabled) !important; + --tempo-colors-background-feedback-success-hovered: var(--color-feedback-success-hovered) !important; + --tempo-colors-background-feedback-success-pressed: var(--color-feedback-success-pressed) !important; + --tempo-colors-background-feedback-warning-default: var(--color-feedback-warning) !important; + --tempo-colors-background-feedback-warning-disabled: var(--color-feedback-warning-disabled) !important; + --tempo-colors-background-feedback-warning-hovered: var(--color-feedback-warning-hovered) !important; + --tempo-colors-background-feedback-warning-pressed: var(--color-feedback-warning-pressed) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var(--color-accent-stronger) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var(--color-accent-stronger) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var(--color-feedback-error) !important; + --tempo-colors-border-feedback-error-disabled: var(--color-feedback-error-disabled) !important; + --tempo-colors-border-feedback-error-focused: var(--color-feedback-error) !important; + --tempo-colors-border-feedback-error-hovered: var(--color-feedback-error-hovered) !important; + --tempo-colors-border-feedback-error-pressed: var(--color-feedback-error-pressed) !important; + --tempo-colors-border-feedback-success-default: var(--color-feedback-success) !important; + --tempo-colors-border-feedback-success-disabled: var(--color-feedback-success-disabled) !important; + --tempo-colors-border-feedback-success-focused: var(--color-feedback-success) !important; + --tempo-colors-border-feedback-success-hovered: var(--color-feedback-success-hovered) !important; + --tempo-colors-border-feedback-success-pressed: var(--color-feedback-success-pressed) !important; + --tempo-colors-border-feedback-warning-default: var(--color-feedback-warning) !important; + --tempo-colors-border-feedback-warning-disabled: var(--color-feedback-warning-disabled) !important; + --tempo-colors-border-feedback-warning-focused: var(--color-feedback-warning) !important; + --tempo-colors-border-feedback-warning-hovered: var(--color-feedback-warning-hovered) !important; + --tempo-colors-border-feedback-warning-pressed: var(--color-feedback-warning-pressed) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var(--color-accent-stronger) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var(--color-accent-stronger) !important; + --tempo-colors-icon-feedback-error-default: var(--color-feedback-error) !important; + --tempo-colors-icon-feedback-error-disabled: var(--color-feedback-error-disabled) !important; + --tempo-colors-icon-feedback-error-hovered: var(--color-feedback-error-hovered) !important; + --tempo-colors-icon-feedback-error-pressed: var(--color-feedback-error-pressed) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var(--color-feedback-success) !important; + --tempo-colors-icon-feedback-success-disabled: var(--color-feedback-success-disabled) !important; + --tempo-colors-icon-feedback-success-hovered: var(--color-feedback-success-hovered) !important; + --tempo-colors-icon-feedback-success-pressed: var(--color-feedback-success-pressed) !important; + --tempo-colors-icon-feedback-warning-default: var(--color-feedback-warning) !important; + --tempo-colors-icon-feedback-warning-disabled: var(--color-feedback-warning-disabled) !important; + --tempo-colors-icon-feedback-warning-hovered: var(--color-feedback-warning-hovered) !important; + --tempo-colors-icon-feedback-warning-pressed: var(--color-feedback-warning-pressed) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var(--color-accent-stronger) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var(--color-accent-stronger) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var(--color-feedback-error) !important; + --tempo-colors-text-feedback-error-disabled: var(--color-feedback-error-disabled) !important; + --tempo-colors-text-feedback-error-hovered: var(--color-feedback-error-hovered) !important; + --tempo-colors-text-feedback-error-pressed: var(--color-feedback-error-pressed) !important; + --tempo-colors-text-feedback-success-default: var(--color-feedback-success) !important; + --tempo-colors-text-feedback-success-disabled: var(--color-feedback-success-disabled) !important; + --tempo-colors-text-feedback-success-hovered: var(--color-feedback-success-hovered) !important; + --tempo-colors-text-feedback-success-pressed: var(--color-feedback-success-pressed) !important; + --tempo-colors-text-feedback-warning-default: var(--color-feedback-warning) !important; + --tempo-colors-text-feedback-warning-disabled: var(--color-feedback-warning-disabled) !important; + --tempo-colors-text-feedback-warning-hovered: var(--color-feedback-warning-hovered) !important; + --tempo-colors-text-feedback-warning-pressed: var(--color-feedback-warning-pressed) !important; + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +/* ========================================================================= + * Nord Light (Snow Storm background, Polar Night text) + * ========================================================================= */ +:root, +[data-theme="light"] { + /* Backgrounds */ + --color-bg-main: #eceff4; /* nord6 */ + --color-bg-secondary: #e5e9f0; /* nord5 */ + --color-bg-tertiary: #dee3ec; + --color-bg-tertiary-hover: #d3d9e6; + --color-bg-tertiary-pressed: #c6cdda; + --color-bg-contrast: #e5e9f0; + --color-bg-inverse: #2e3440; /* nord0 */ + --transparent-bg: #eceff480; + + /* Text */ + --color-text-main: #2e3440; /* nord0 (strong body) */ + --color-text-secondary: #4c566a; /* nord3 */ + --color-text-disabled: #9aa5b1; + --color-text-inverse: #eceff4; /* nord6 */ + + /* Borders & dividers */ + --color-border-neutral-primary: #ccd3e0; + --color-border-neutral-secondary: #9aa5b1; + --color-divider-main: #ccd3e0; + + /* Neutral aliases */ + --color-neutral-main: #9aa5b1; + --color-neutral-strong: #4c566a; + --color-neutral-weak: #e5e9f0; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * Nord Dark (Polar Night background, Snow Storm text) + * ========================================================================= */ +[data-theme="dark"] { + /* Backgrounds */ + --color-bg-main: #2e3440; /* nord0 */ + --color-bg-secondary: #3b4252; /* nord1 */ + --color-bg-tertiary: #434c5e; /* nord2 */ + --color-bg-tertiary-hover: #4c566a; /* nord3 */ + --color-bg-tertiary-pressed: #566277; + --color-bg-contrast: #3b4252; + --color-bg-inverse: #eceff4; /* nord6 */ + --transparent-bg: #2e34404d; + + /* Text */ + --color-text-main: #e5e9f0; /* nord5 (bright body) */ + --color-text-secondary: #d8dee9; /* nord4 */ + --color-text-disabled: #6b7890; + --color-text-inverse: #2e3440; /* nord0 */ + + /* Borders & dividers */ + --color-border-neutral-primary: #434c5e; + --color-border-neutral-secondary: #6b7890; + --color-divider-main: #434c5e; + + /* Neutral aliases */ + --color-neutral-main: #4c566a; + --color-neutral-strong: #9aa5b1; + --color-neutral-weak: #3b4252; + + /* Brand accents retinted toward Nord frost teal */ + --color-bg-brand-duo: #8fbcbb; /* nord7 */ + --color-bg-brand-trio: #8fbcbb; + --color-bg-brand-duo-selected: #434c5e; + --color-text-brand-duo: #2e3440; + --color-text-brand-trio: #2e3440; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} From 0e00d4b49551da466b1cc96d7d608361d8e36a5a Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 17:04:47 +0200 Subject: [PATCH 04/10] chore: add a build-theme skill --- .claude/skills/build-theme/SKILL.md | 97 +++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 .claude/skills/build-theme/SKILL.md diff --git a/.claude/skills/build-theme/SKILL.md b/.claude/skills/build-theme/SKILL.md new file mode 100644 index 0000000..15da048 --- /dev/null +++ b/.claude/skills/build-theme/SKILL.md @@ -0,0 +1,97 @@ +--- +name: build-theme +description: Build a new Deezer Linux theme (custom CSS) by reading the compiled app source instead of DevTools/screenshots, since neither is available in this environment. +disable-model-invocation: true +--- + +# Build a Deezer Linux theme + +You have no display and no working DevTools attach in this environment (Wayland, no screenshot tool, `--remote-debugging-port` unreliable). Every step below verifies via source, not via eyes. When you report progress, say explicitly that the theme is source-verified, not visually confirmed — never claim a color "looks right." + +## 1. Create the theme file + +``` +cp themes/template.css themes/.css +``` + +`themes/solarized.css` and `themes/nord.css` are filled-in references for the same token set. + +## 2. Extract the compiled app bundle + +This is your substitute for DevTools — the real compiled CSS/JS Deezer ships, not source you'd have to guess at. + +``` +npx --yes asar extract artifacts/x64/linux-unpacked/resources/app.asar /tmp/deezer-app +``` + +Compiled CSS: `/tmp/deezer-app/build/assets/cache/css/sass_c/*.css` +Compiled JS: `/tmp/deezer-app/build/assets/cache/js/*.js` + +## 3. Grep the CSS for a token, when template.css doesn't already cover it + +`themes/template.css` already documents the known token catalog — don't re-derive what's already listed there. Only grep when chasing something new/unlisted, or if a Deezer update may have changed the tokens (full method: `CONTRIBUTING.md` → "Creating a New Theme" → "How the token catalog was discovered"). + +``` +grep -o 'body{background-color:var([^)]*)[^}]*}' \ + /tmp/deezer-app/build/assets/cache/css/sass_c/app-web.*.css +``` + +## 4. Grep the JS for the token behind a specific interactive state (hover/pressed/selected) + +This is the highest-value move — it's how real theming bugs get found without ever seeing the UI. Grep the component's JS bundle for its style props directly: + +``` +grep -o '_active:{[^}]*}' /tmp/deezer-app/build/assets/cache/js/sidebar-logged.*.js +# _active:{backgroundColor:"background.neutral.secondary.pressed",outline:"none"} +``` + +The dot-path (`background.neutral.secondary.pressed`) maps directly to the CSS variable `--tempo-colors-background-neutral-secondary-pressed`. Trust this over guessing from a screenshot — it's the literal source of truth for that state. + +## 5. Fill in the theme file, in this priority order + +1. Section 1 — shared palette +2. Sections 2 & 3 — light/dark mode +3. Section 4 — Tempo tokens. Do not skip this: it paints most of the chrome and every interactive state. Keep `!important` on every uncommented line — the app's JS sets these at runtime and only `!important` beats that. + +## 6. Sanity-check the CSS mechanically + +``` +python3 -c " +s = open('themes/.css').read() +print('braces', s.count('{'), s.count('}')) +print('parens', s.count('('), s.count(')')) +" +``` + +Also scan for duplicate `--var-name:` declarations inside the same rule block — a duplicate silently overrides the earlier one and is easy to introduce when generating a lot of lines at once. + +## 7. Launch the app to catch load errors + +Even with no visual feedback, a launch still surfaces real errors. + +``` +deezer-desktop --custom-theme=/absolute/path/to/themes/.css --no-sandbox > /tmp/deezer.log 2>&1 & +disown +sleep 5 +cat /tmp/deezer.log +``` + +Look for a `[custom-theme] Could not read theme file: ...` line — that means the path is wrong or the CSS failed to load. + +If copying an `Exec` line from a `.desktop` file, drop any `%U` placeholder first — it's meant to be substituted by the launcher, and left literal it crashes Electron's own bootstrap (`Cannot find module '.../%U'`). + +## 8. Report honestly and hand off visual verification + +Tell the human directly: theme built and mapped from source; not visually confirmed in this environment — they should launch it and check light/dark mode plus hover/pressed/selected states on a few elements before merging. Don't say "done" or "looks great." + +If they come back with a specific element that's still wrong, return to step 4 and grep that component's JS directly rather than guessing again. + +## Command reference + +| Purpose | Command | +| ----------------------------- | ----------------------------------------------------------------------------------------------------- | +| Extract the app bundle | `npx --yes asar extract artifacts/x64/linux-unpacked/resources/app.asar /tmp/deezer-app` | +| Find the token behind a state | `grep -o '_active:{[^}]*}' /tmp/deezer-app/build/assets/cache/js/.*.js` | +| Launch with theme | `deezer-desktop --custom-theme=/path/to/theme.css --no-sandbox > /tmp/deezer.log 2>&1 &` | +| Check for load errors | `cat /tmp/deezer.log` (look for `[custom-theme]` lines) | +| Sanity-check generated CSS | `python3 -c "s=open('theme.css').read(); print(s.count('{'),s.count('}'),s.count('('),s.count(')'))"` | From 89112264267cf93438e436ff289e1841b6bcf7b3 Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 17:17:55 +0200 Subject: [PATCH 05/10] chore: improve build-theme skill with real debugging and docs update --- .claude/skills/build-theme/SKILL.md | 138 +++++++++++++++++++++++----- 1 file changed, 116 insertions(+), 22 deletions(-) diff --git a/.claude/skills/build-theme/SKILL.md b/.claude/skills/build-theme/SKILL.md index 15da048..da47493 100644 --- a/.claude/skills/build-theme/SKILL.md +++ b/.claude/skills/build-theme/SKILL.md @@ -1,12 +1,12 @@ --- name: build-theme -description: Build a new Deezer Linux theme (custom CSS) by reading the compiled app source instead of DevTools/screenshots, since neither is available in this environment. +description: Build a new Deezer Linux theme (custom CSS) by reading the compiled app source, then verify it live via a CDP DevTools attach (source-verification + real screenshots, no X/Wayland screenshot tool needed). disable-model-invocation: true --- # Build a Deezer Linux theme -You have no display and no working DevTools attach in this environment (Wayland, no screenshot tool, `--remote-debugging-port` unreliable). Every step below verifies via source, not via eyes. When you report progress, say explicitly that the theme is source-verified, not visually confirmed — never claim a color "looks right." +Every color choice is justified from source first (compiled CSS/JS, not guessing), then verified live by attaching Chrome DevTools Protocol (CDP) to the running app and pulling real screenshots + computed styles over the debug socket. This works even with no X server and no screenshot tool installed, because the screenshot comes from the browser process itself, not from capturing a window on screen. ## 1. Create the theme file @@ -14,11 +14,11 @@ You have no display and no working DevTools attach in this environment (Wayland, cp themes/template.css themes/.css ``` -`themes/solarized.css` and `themes/nord.css` are filled-in references for the same token set. +`themes/solarized.css`, `themes/nord.css` and `themes/everforest.css` are filled-in references for the same token set. ## 2. Extract the compiled app bundle -This is your substitute for DevTools — the real compiled CSS/JS Deezer ships, not source you'd have to guess at. +This is your primary substitute for DevTools when reasoning about _what token to use_ — the real compiled CSS/JS Deezer ships, not source you'd have to guess at. ``` npx --yes asar extract artifacts/x64/linux-unpacked/resources/app.asar /tmp/deezer-app @@ -38,14 +38,14 @@ grep -o 'body{background-color:var([^)]*)[^}]*}' \ ## 4. Grep the JS for the token behind a specific interactive state (hover/pressed/selected) -This is the highest-value move — it's how real theming bugs get found without ever seeing the UI. Grep the component's JS bundle for its style props directly: +This is the highest-value move for finding _which token_ governs a state — it's how real theming bugs get found without ever seeing the UI. Grep the component's JS bundle for its style props directly: ``` grep -o '_active:{[^}]*}' /tmp/deezer-app/build/assets/cache/js/sidebar-logged.*.js # _active:{backgroundColor:"background.neutral.secondary.pressed",outline:"none"} ``` -The dot-path (`background.neutral.secondary.pressed`) maps directly to the CSS variable `--tempo-colors-background-neutral-secondary-pressed`. Trust this over guessing from a screenshot — it's the literal source of truth for that state. +The dot-path (`background.neutral.secondary.pressed`) maps directly to the CSS variable `--tempo-colors-background-neutral-secondary-pressed`. Once you've picked the color for that state (step 5), confirm it rendered correctly in step 7 rather than trusting the mapping blindly. ## 5. Fill in the theme file, in this priority order @@ -65,33 +65,127 @@ print('parens', s.count('('), s.count(')')) Also scan for duplicate `--var-name:` declarations inside the same rule block — a duplicate silently overrides the earlier one and is easy to introduce when generating a lot of lines at once. -## 7. Launch the app to catch load errors - -Even with no visual feedback, a launch still surfaces real errors. +Then run prettier so the file matches the formatting of the other themes: ``` -deezer-desktop --custom-theme=/absolute/path/to/themes/.css --no-sandbox > /tmp/deezer.log 2>&1 & +npm run prettier -- --write themes/.css +``` + +## 7. Launch the app with a CDP DevTools attach + +The unpacked binary is a Node/Electron hybrid — in this dev environment `ELECTRON_RUN_AS_NODE` is set, which makes it launch as plain Node (you'll see a `node --help`-style usage dump) instead of Electron. Unset it. Also quote `--remote-allow-origins=*` — the shell will otherwise glob-expand the bare `*` against files in the cwd and the flag silently vanishes. + +```sh +env -u ELECTRON_RUN_AS_NODE nohup \ + artifacts/x64/linux-unpacked/deezer-desktop \ + --custom-theme=/absolute/path/to/themes/.css \ + --no-sandbox \ + --remote-debugging-port=9222 \ + "--remote-allow-origins=*" \ + > /tmp/deezer.log 2>&1 & disown -sleep 5 +sleep 8 cat /tmp/deezer.log ``` -Look for a `[custom-theme] Could not read theme file: ...` line — that means the path is wrong or the CSS failed to load. +Look for a `[custom-theme] Could not read theme file: ...` line — that means the path is wrong or the CSS failed to load. A clean launch just logs `Init App` and (once the port is up) `DevTools listening on ws://...`. If copying an `Exec` line from a `.desktop` file, drop any `%U` placeholder first — it's meant to be substituted by the launcher, and left literal it crashes Electron's own bootstrap (`Cannot find module '.../%U'`). -## 8. Report honestly and hand off visual verification +### Get the page's debug socket + +```sh +curl -s http://localhost:9222/json | python3 -c \ + "import json,sys; print([x['webSocketDebuggerUrl'] for x in json.load(sys.stdin) if x['type']=='page'])" +``` + +Use the `page` entry (not the `service_worker` or `worker` ones). + +## 8. Verify live over CDP — computed styles, screenshots, and states + +`websocket-client` (Python) is enough to drive the whole protocol — no browser-automation framework needed. Three moves cover everything: + +**a. Read computed CSS values** (`Runtime.evaluate`) — proves the cascade actually resolved to your colors, not just that the file parsed: + +```python +import websocket, json + +def eval_js(ws_url, expr): + ws = websocket.create_connection(ws_url, timeout=10) + ws.send(json.dumps({"id": 1, "method": "Runtime.evaluate", + "params": {"expression": expr, "returnByValue": True}})) + while True: + resp = json.loads(ws.recv()) + if resp.get("id") == 1: + ws.close() + return resp + +eval_js(ws_url, '''JSON.stringify({ + bodyBg: getComputedStyle(document.body).backgroundColor, + accent: getComputedStyle(document.documentElement) + .getPropertyValue("--tempo-colors-background-accent-primary-default") +})''') +``` + +**b. Take a real screenshot** (`Page.captureScreenshot`) — this comes from the renderer itself over the CDP socket, so it works with no X server, no Wayland screenshot tool, and no window manager involvement: + +```python +ws.send(json.dumps({"id": 2, "method": "Page.captureScreenshot", "params": {"format": "png"}})) +# resp["result"]["data"] is base64 PNG — decode and write to a file, then view it +``` + +Do **not** try `import -window ...` / `grim` / `scrot` here — there's no reliable X/Wayland capture path in this environment, and `import` will hang waiting for a window that it can't find. `Page.captureScreenshot` bypasses that entirely. + +**c. Toggle light/dark and simulate hover, without touching the OS theme:** + +```js +// switch mode +document.documentElement.setAttribute("data-theme", "dark"); +document.body.className = document.body.className.replace( + "chakra-ui-light", + "chakra-ui-dark" +); +``` + +```python +# hover a specific point, then screenshot immediately after +ws.send(json.dumps({"id": 3, "method": "Input.dispatchMouseEvent", + "params": {"type": "mouseMoved", "x": x, "y": y}})) +``` + +Read pixel coordinates for `x`/`y` off a screenshot you already took (remember to scale if the image was downsampled for display). + +Check, per theme: light mode, dark mode, and at least one hover/pressed/selected state on a real element (sidebar item, button) — confirm both the screenshot _and_ the computed `--tempo-*` value. + +### Cleanup + +```sh +pkill -f "deezer-desktop.*custom-theme" +``` + +## 9. Update the README's theme table + +If this is a new ready-made theme (not a one-off for a single user), add it to the "Ready-made themes" table in `README.md` next to Solarized/Nord/Everforest, linking to `./themes/.css`. Then run prettier on both files so table alignment and CSS formatting stay consistent with the rest of the repo: + +```sh +npm run prettier -- --write README.md themes/.css +``` + +## 10. Report honestly -Tell the human directly: theme built and mapped from source; not visually confirmed in this environment — they should launch it and check light/dark mode plus hover/pressed/selected states on a few elements before merging. Don't say "done" or "looks great." +Because step 8 gives you real screenshots and real computed values, you can now say the theme is **visually confirmed**, not just source-verified — but say exactly what you checked (which modes, which states, which elements) rather than a blanket "looks great". If you didn't get to a CDP attach for some reason (e.g. the environment truly has no `--remote-debugging-port` support), fall back to the honest source-verified framing instead of claiming visual confirmation you didn't do. -If they come back with a specific element that's still wrong, return to step 4 and grep that component's JS directly rather than guessing again. +If the human comes back with a specific element that's still wrong, return to step 4 to find the right token, fix it, then go straight back to step 8 to re-verify that exact element — don't re-guess from a screenshot alone. ## Command reference -| Purpose | Command | -| ----------------------------- | ----------------------------------------------------------------------------------------------------- | -| Extract the app bundle | `npx --yes asar extract artifacts/x64/linux-unpacked/resources/app.asar /tmp/deezer-app` | -| Find the token behind a state | `grep -o '_active:{[^}]*}' /tmp/deezer-app/build/assets/cache/js/.*.js` | -| Launch with theme | `deezer-desktop --custom-theme=/path/to/theme.css --no-sandbox > /tmp/deezer.log 2>&1 &` | -| Check for load errors | `cat /tmp/deezer.log` (look for `[custom-theme]` lines) | -| Sanity-check generated CSS | `python3 -c "s=open('theme.css').read(); print(s.count('{'),s.count('}'),s.count('('),s.count(')'))"` | +| Purpose | Command | +| ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Extract the app bundle | `npx --yes asar extract artifacts/x64/linux-unpacked/resources/app.asar /tmp/deezer-app` | +| Find the token behind a state | `grep -o '_active:{[^}]*}' /tmp/deezer-app/build/assets/cache/js/.*.js` | +| Sanity-check generated CSS | `python3 -c "s=open('theme.css').read(); print(s.count('{'),s.count('}'),s.count('('),s.count(')'))"` | +| Format the theme/README | `npm run prettier -- --write themes/.css README.md` | +| Launch with theme + CDP attach | `env -u ELECTRON_RUN_AS_NODE nohup artifacts/x64/linux-unpacked/deezer-desktop --custom-theme=/path/to/theme.css --no-sandbox --remote-debugging-port=9222 "--remote-allow-origins=*" > /tmp/deezer.log 2>&1 &` | +| Check for load errors | `cat /tmp/deezer.log` (look for `[custom-theme]` lines) | +| List debuggable pages | `curl -s http://localhost:9222/json` | +| Kill the themed instance | `pkill -f "deezer-desktop.*custom-theme"` | From 85642db5ee39c5d7d5aa8b26532cc42001131c2a Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 17:18:08 +0200 Subject: [PATCH 06/10] docs(theme): add Everforest theme --- README.md | 9 +- themes/everforest.css | 965 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 970 insertions(+), 4 deletions(-) create mode 100644 themes/everforest.css diff --git a/README.md b/README.md index 552d0d5..3470ad6 100644 --- a/README.md +++ b/README.md @@ -148,10 +148,11 @@ Pair this with [`--sync-theme`](#usage) so the mode follows your OS setting auto The [`themes/`](./themes) folder contains drop-in themes you can use as-is or as a reference: -| Theme | Modes | -| ----------------------------------- | ------------ | -| [Solarized](./themes/solarized.css) | Light & dark | -| [Nord](./themes/nord.css) | Light & dark | +| Theme | Modes | +| ------------------------------------- | ------------ | +| [Solarized](./themes/solarized.css) | Light & dark | +| [Nord](./themes/nord.css) | Light & dark | +| [Everforest](./themes/everforest.css) | Light & dark | For example: diff --git a/themes/everforest.css b/themes/everforest.css new file mode 100644 index 0000000..2118e7f --- /dev/null +++ b/themes/everforest.css @@ -0,0 +1,965 @@ +/* ========================================================================= + * Everforest — a custom theme for Deezer for Linux + * ========================================================================= + * + * https://github.com/sainnhe/everforest — see themes/template.css for the + * full list of variables. Values below are the "medium" contrast variant + * (Everforest's default) of both the dark and light palettes. + * + * deezer-desktop --sync-theme --custom-theme=/path/to/themes/everforest.css + * + * ---- Everforest reference (medium contrast) -------------------------- + * Dark bg: bg_dim #232a2e bg0 #2d353b bg1 #343f44 bg2 #3d484d + * bg3 #475258 bg4 #4f585e bg5 #56635f + * Dark fg: fg #d3c6aa grey0 #7a8478 grey1 #859289 grey2 #9da9a0 + * Light bg: bg0 #fdf6e3 bg1 #f4f0d9 bg3 #e6e2cc bg4 #e0dcc7 + * bg5 #bdc3af + * Light fg: fg #5c6a72 grey0 #a6b0a0 grey1 #939f91 grey2 #829181 + * Accents (dark/light): red #e67e80/#f85552 orange #e69875/#f57d26 + * yellow #dbbc7f/#dfa000 green #a7c080/#8da101 + * aqua #83c092/#35a77c blue #7fbbb3/#3a94c5 + * purple #d699b6/#df69ba + * ========================================================================= */ + +/* ========================================================================= + * Shared base palette — Everforest aqua accent (kept distinct from the + * green/yellow/red feedback colors below) + a bg0..bg5/fg neutral ramp. + * Remapping the grey ramp shifts every neutral surface in both modes. + * ========================================================================= */ +:root { + /* Accent: Everforest aqua instead of Deezer purple. The light-palette + * aqua (#35a77c) is used as "main" because, unlike the pastel dark-palette + * aqua, it stays legible on both the cream light background and the dark + * background. */ + --color-accent-main: #35a77c; + --color-accent-strong: #278a65; + --color-accent-weak: #83c092; /* dark-palette aqua */ + --color-accent-light: #a8d4b7; + --color-accent-stronger: #1d6b4d; /* deeper "pressed" tier */ + + /* Feedback (error / success / warning) — one default/disabled/hovered/ + * pressed variable per type, unlike template.css's single flat color. + * Uses the light-palette (more saturated) accents for the same + * both-backgrounds-legible reason as the main accent above. */ + --color-feedback-error: #f85552; + --color-feedback-error-disabled: #f9938f; + --color-feedback-error-hovered: #d93f3c; + --color-feedback-error-pressed: #b93330; + --color-feedback-success: #8da101; + --color-feedback-success-disabled: #b9c766; + --color-feedback-success-hovered: #748501; + --color-feedback-success-pressed: #5c6a01; + --color-feedback-warning: #dfa000; + --color-feedback-warning-disabled: #ecc466; + --color-feedback-warning-hovered: #b98400; + --color-feedback-warning-pressed: #936900; + + /* Neutral ramp mapped onto Everforest bg/grey tones (light -> dark) */ + --color-grey-50: #fdf6e3; /* light bg0 */ + --color-grey-100: #f4f0d9; /* light bg1 */ + --color-grey-200: #e6e2cc; /* light bg3 */ + --color-grey-300: #bdc3af; /* light bg5 */ + --color-grey-400: #939f91; /* light grey1 */ + --color-grey-500: #829181; /* light grey2 */ + --color-grey-600: #475258; /* dark bg3 */ + --color-grey-700: #3d484d; /* dark bg2 */ + --color-grey-800: #343f44; /* dark bg1 */ + --color-grey-900: #2d353b; /* dark bg0 */ + + /* Fixed dark/light grey ramps — do NOT swap with the mode */ + --color-dark-grey-200: #56635f; /* dark bg5 */ + --color-dark-grey-300: #4f585e; /* dark bg4 */ + --color-dark-grey-400: #475258; /* dark bg3 */ + --color-dark-grey-500: #3d484d; /* dark bg2 */ + --color-dark-grey-600: #343f44; /* dark bg1 */ + --color-dark-grey-700: #2d353b; /* dark bg0 */ + --color-dark-grey-800: #262e33; + --color-dark-grey-900: #232a2e; /* dark bg_dim */ + --color-light-grey-50: #fdf6e3; /* light bg0 */ + --color-light-grey-100: #f8f5e4; /* light bg1 (hard) */ + --color-light-grey-200: #f4f0d9; /* light bg1 */ + --color-light-grey-300: #e6e2cc; /* light bg3 */ + --color-light-grey-400: #e0dcc7; /* light bg4 */ + --color-light-grey-500: #bdc3af; /* light bg5 */ + --color-light-grey-600: #a6b0a0; /* light grey0 */ + --color-light-grey-700: #939f91; /* light grey1 */ + --color-light-grey-800: #829181; /* light grey2 */ + --color-light-grey-900: #5c6a72; /* light fg */ +} + +/* ========================================================================= + * Tempo design tokens — see themes/template.css section 4 for the full + * rationale. Mode-independent tokens (accent + feedback + onDark/onLight). + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-background-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-background-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-background-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-background-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-background-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-background-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-background-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-background-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-border-feedback-error-focused: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-border-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-border-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-border-feedback-success-focused: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-border-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-border-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-border-feedback-warning-focused: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-border-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-icon-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-icon-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-icon-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-icon-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-icon-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-icon-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-icon-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-text-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-text-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-text-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-text-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-text-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-text-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-text-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-text-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +/* ========================================================================= + * Everforest Light (cream background, dark fg text) + * ========================================================================= */ +:root, +[data-theme="light"] { + /* Backgrounds */ + --color-bg-main: #fdf6e3; /* light bg0 */ + --color-bg-secondary: #f4f0d9; /* light bg1 */ + --color-bg-tertiary: #e6e2cc; /* light bg3 */ + --color-bg-tertiary-hover: #e0dcc7; /* light bg4 */ + --color-bg-tertiary-pressed: #bdc3af; /* light bg5 */ + --color-bg-contrast: #e6e2cc; + --color-bg-inverse: #2d353b; /* dark bg0 */ + --transparent-bg: #fdf6e380; + + /* Text */ + --color-text-main: #5c6a72; /* light fg (strong body) */ + --color-text-secondary: #829181; /* light grey2 */ + --color-text-disabled: #a6b0a0; /* light grey0 */ + --color-text-inverse: #d3c6aa; /* dark fg */ + + /* Borders & dividers */ + --color-border-neutral-primary: #e0dcc7; + --color-border-neutral-secondary: #bdc3af; + --color-divider-main: #e0dcc7; + + /* Neutral aliases */ + --color-neutral-main: #bdc3af; + --color-neutral-strong: #829181; + --color-neutral-weak: #f4f0d9; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * Everforest Dark (dark bg background, cream/tan fg text) + * ========================================================================= */ +[data-theme="dark"] { + /* Backgrounds */ + --color-bg-main: #2d353b; /* dark bg0 */ + --color-bg-secondary: #343f44; /* dark bg1 */ + --color-bg-tertiary: #3d484d; /* dark bg2 */ + --color-bg-tertiary-hover: #475258; /* dark bg3 */ + --color-bg-tertiary-pressed: #4f585e; /* dark bg4 */ + --color-bg-contrast: #343f44; + --color-bg-inverse: #fdf6e3; /* light bg0 */ + --transparent-bg: #232a2e4d; + + /* Text */ + --color-text-main: #d3c6aa; /* dark fg (bright body) */ + --color-text-secondary: #9da9a0; /* dark grey2 */ + --color-text-disabled: #7a8478; /* dark grey0 */ + --color-text-inverse: #2d353b; /* dark bg0 */ + + /* Borders & dividers */ + --color-border-neutral-primary: #475258; + --color-border-neutral-secondary: #56635f; + --color-divider-main: #475258; + + /* Neutral aliases */ + --color-neutral-main: #475258; + --color-neutral-strong: #9da9a0; + --color-neutral-weak: #343f44; + + /* Brand accents retinted toward Everforest aqua */ + --color-bg-brand-duo: #83c092; /* dark aqua */ + --color-bg-brand-trio: #83c092; + --color-bg-brand-duo-selected: #3d484d; + --color-text-brand-duo: #2d353b; + --color-text-brand-trio: #2d353b; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} From cda1f83a10f6771e67c6a1a7a0059edd689568c3 Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 19:12:07 +0200 Subject: [PATCH 07/10] chore: remove dead reference in build-theme skill --- .claude/skills/build-theme/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.claude/skills/build-theme/SKILL.md b/.claude/skills/build-theme/SKILL.md index da47493..5eb2285 100644 --- a/.claude/skills/build-theme/SKILL.md +++ b/.claude/skills/build-theme/SKILL.md @@ -29,7 +29,7 @@ Compiled JS: `/tmp/deezer-app/build/assets/cache/js/*.js` ## 3. Grep the CSS for a token, when template.css doesn't already cover it -`themes/template.css` already documents the known token catalog — don't re-derive what's already listed there. Only grep when chasing something new/unlisted, or if a Deezer update may have changed the tokens (full method: `CONTRIBUTING.md` → "Creating a New Theme" → "How the token catalog was discovered"). +`themes/template.css` already documents the known token catalog — don't re-derive what's already listed there. Only grep when chasing something new/unlisted, or if a Deezer update may have changed the tokens. ``` grep -o 'body{background-color:var([^)]*)[^}]*}' \ From d5b7f963f4c813aaf6612fa64ddeb7e1d2b033a2 Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 20:09:02 +0200 Subject: [PATCH 08/10] docs(theme): add gruvbox, matrix, monokai, primer, synthwave themes --- README.md | 15 +- themes/gruvbox.css | 960 ++++++++++++++++++++++++++++++++++++ themes/matrix.css | 1039 +++++++++++++++++++++++++++++++++++++++ themes/monokai.css | 953 ++++++++++++++++++++++++++++++++++++ themes/primer.css | 1042 +++++++++++++++++++++++++++++++++++++++ themes/synthwave.css | 1107 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 5111 insertions(+), 5 deletions(-) create mode 100644 themes/gruvbox.css create mode 100644 themes/matrix.css create mode 100644 themes/monokai.css create mode 100644 themes/primer.css create mode 100644 themes/synthwave.css diff --git a/README.md b/README.md index 3470ad6..6f4c10b 100644 --- a/README.md +++ b/README.md @@ -148,11 +148,16 @@ Pair this with [`--sync-theme`](#usage) so the mode follows your OS setting auto The [`themes/`](./themes) folder contains drop-in themes you can use as-is or as a reference: -| Theme | Modes | -| ------------------------------------- | ------------ | -| [Solarized](./themes/solarized.css) | Light & dark | -| [Nord](./themes/nord.css) | Light & dark | -| [Everforest](./themes/everforest.css) | Light & dark | +| Theme | Modes | +| --------------------------------------- | ------------ | +| [Solarized](./themes/solarized.css) | Light & dark | +| [Nord](./themes/nord.css) | Light & dark | +| [Everforest](./themes/everforest.css) | Light & dark | +| [Monokai](./themes/monokai.css) | Light & dark | +| [SynthWave '84](./themes/synthwave.css) | Dark only | +| [Primer](./themes/primer.css) | Light & dark | +| [Gruvbox](./themes/gruvbox.css) | Light & dark | +| [Matrix](./themes/matrix.css) | Dark only | For example: diff --git a/themes/gruvbox.css b/themes/gruvbox.css new file mode 100644 index 0000000..ba7a057 --- /dev/null +++ b/themes/gruvbox.css @@ -0,0 +1,960 @@ +/* ========================================================================= + * Gruvbox — a custom theme for Deezer for Linux + * ========================================================================= + * + * https://github.com/morhetz/gruvbox — see themes/template.css for the + * full list of variables. + * + * deezer-desktop --sync-theme --custom-theme=/path/to/themes/gruvbox.css + * + * ---- Gruvbox reference --------------------------------------------------- + * dark bg: bg0_h #1d2021 bg0 #282828 bg0_s #32302f bg1 #3c3836 + * bg2 #504945 bg3 #665c54 bg4 #7c6f64 + * dark fg: fg4 #a89984 fg3 #bdae93 fg2 #d5c4a1 fg1 #ebdbb2 fg0 #fbf1c7 + * light bg: bg0_h #f9f5d7 bg0 #fbf1c7 bg0_s #f2e5bc bg1 #ebdbb2 + * bg2 #d5c4a1 bg3 #bdae93 bg4 #a89984 + * light fg: fg0 #282828 fg1 #3c3836 fg2 #504945 fg3 #665c54 fg4 #7c6f64 + * neutral: red #cc241d green #98971a yellow #d79921 blue #458588 + * purple #b16286 aqua #689d6a orange #d65d0e gray #928374 + * bright: red #fb4934 green #b8bb26 yellow #fabd2f blue #83a598 + * purple #d3869b aqua #8ec07c orange #fe8019 + * faded: red #9d0006 green #79740e yellow #b57614 blue #076678 + * purple #8f3f71 aqua #427b58 orange #af3a03 + * ========================================================================= */ + +/* ========================================================================= + * Shared base palette — Gruvbox orange accent + a bg0..fg0 neutral ramp. + * Remapping the grey ramp shifts every neutral surface in both modes. + * ========================================================================= */ +:root { + /* Accent: Gruvbox bright orange instead of Deezer purple */ + --color-accent-main: #fe8019; + --color-accent-strong: #d65d0e; + --color-accent-weak: #fe9d54; + --color-accent-light: #ffc38a; + --color-accent-stronger: #af3a03; /* deeper "pressed" tier */ + + /* Feedback (error / success / warning) — one default/disabled/hovered/ + * pressed variable per type, unlike template.css's single flat color */ + --color-feedback-error: #cc241d; + --color-feedback-error-disabled: #e0685f; + --color-feedback-error-hovered: #9d0006; + --color-feedback-error-pressed: #7a0004; + --color-feedback-success: #98971a; + --color-feedback-success-disabled: #c1c161; + --color-feedback-success-hovered: #79740e; + --color-feedback-success-pressed: #5f5a0a; + --color-feedback-warning: #d79921; + --color-feedback-warning-disabled: #eab853; + --color-feedback-warning-hovered: #b57614; + --color-feedback-warning-pressed: #8f5c0f; + + /* Neutral ramp mapped onto Gruvbox bg/fg tones (light -> dark) */ + --color-grey-50: #fbf1c7; /* fg0/bg0 light */ + --color-grey-100: #ebdbb2; /* fg1 */ + --color-grey-200: #d5c4a1; /* fg2 */ + --color-grey-300: #bdae93; /* fg3 */ + --color-grey-400: #a89984; /* fg4/gray */ + --color-grey-500: #7c6f64; /* bg4 */ + --color-grey-600: #665c54; /* bg3 */ + --color-grey-700: #504945; /* bg2 */ + --color-grey-800: #3c3836; /* bg1 */ + --color-grey-900: #282828; /* bg0 */ + + /* Fixed dark/light grey ramps — do NOT swap with the mode */ + --color-dark-grey-200: #7c6f64; /* bg4 */ + --color-dark-grey-300: #665c54; /* bg3 */ + --color-dark-grey-400: #584d43; + --color-dark-grey-500: #504945; /* bg2 */ + --color-dark-grey-600: #3c3836; /* bg1 */ + --color-dark-grey-700: #32302f; /* bg0_s */ + --color-dark-grey-800: #282828; /* bg0 */ + --color-dark-grey-900: #1d2021; /* bg0_h */ + --color-light-grey-50: #fbf1c7; /* bg0 light */ + --color-light-grey-100: #f2e5bc; /* bg0_s light */ + --color-light-grey-200: #ebdbb2; /* bg1 light */ + --color-light-grey-300: #e3d3a4; + --color-light-grey-400: #d5c4a1; /* bg2 light */ + --color-light-grey-500: #c7b592; + --color-light-grey-600: #bdae93; /* bg3 light */ + --color-light-grey-700: #a89984; /* bg4 light / fg4 */ + --color-light-grey-800: #927f68; + --color-light-grey-900: #7c6f64; /* bg4 */ +} + +/* ========================================================================= + * Tempo design tokens — see themes/template.css section 4 for the full + * rationale. Mode-independent tokens (accent + feedback + onDark/onLight). + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-background-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-background-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-background-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-background-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-background-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-background-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-background-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-background-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-border-feedback-error-focused: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-border-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-border-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-border-feedback-success-focused: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-border-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-border-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-border-feedback-warning-focused: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-border-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-icon-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-icon-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-icon-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-icon-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-icon-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-icon-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-icon-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-text-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-text-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-text-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-text-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-text-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-text-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-text-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-text-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +/* ========================================================================= + * Gruvbox Light (bg0 background, fg1 text) + * ========================================================================= */ +:root, +[data-theme="light"] { + /* Backgrounds */ + --color-bg-main: #fbf1c7; /* bg0 light */ + --color-bg-secondary: #f2e5bc; /* bg0_s light */ + --color-bg-tertiary: #ebdbb2; /* bg1 light */ + --color-bg-tertiary-hover: #e3d3a4; + --color-bg-tertiary-pressed: #d5c4a1; /* bg2 light */ + --color-bg-contrast: #f2e5bc; + --color-bg-inverse: #282828; /* bg0 dark */ + --transparent-bg: #fbf1c780; + + /* Text */ + --color-text-main: #3c3836; /* fg1 (strong body) */ + --color-text-secondary: #504945; /* fg2 */ + --color-text-disabled: #a89984; /* fg4/gray */ + --color-text-inverse: #fbf1c7; /* bg0 light */ + + /* Borders & dividers */ + --color-border-neutral-primary: #d5c4a1; + --color-border-neutral-secondary: #a89984; + --color-divider-main: #d5c4a1; + + /* Neutral aliases */ + --color-neutral-main: #bdae93; + --color-neutral-strong: #665c54; + --color-neutral-weak: #ebdbb2; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * Gruvbox Dark (bg0 background, fg1 text) + * ========================================================================= */ +[data-theme="dark"] { + /* Backgrounds */ + --color-bg-main: #282828; /* bg0 */ + --color-bg-secondary: #32302f; /* bg0_s */ + --color-bg-tertiary: #3c3836; /* bg1 */ + --color-bg-tertiary-hover: #504945; /* bg2 */ + --color-bg-tertiary-pressed: #665c54; /* bg3 */ + --color-bg-contrast: #32302f; + --color-bg-inverse: #fbf1c7; /* bg0 light */ + --transparent-bg: #2828284d; + + /* Text */ + --color-text-main: #ebdbb2; /* fg1 (bright body) */ + --color-text-secondary: #d5c4a1; /* fg2 */ + --color-text-disabled: #7c6f64; /* bg4 */ + --color-text-inverse: #282828; /* bg0 */ + + /* Borders & dividers */ + --color-border-neutral-primary: #3c3836; + --color-border-neutral-secondary: #7c6f64; + --color-divider-main: #3c3836; + + /* Neutral aliases */ + --color-neutral-main: #504945; + --color-neutral-strong: #a89984; + --color-neutral-weak: #32302f; + + /* Brand accents retinted toward Gruvbox bright aqua */ + --color-bg-brand-duo: #8ec07c; + --color-bg-brand-trio: #8ec07c; + --color-bg-brand-duo-selected: #3c3836; + --color-text-brand-duo: #282828; + --color-text-brand-trio: #282828; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} diff --git a/themes/matrix.css b/themes/matrix.css new file mode 100644 index 0000000..10f877b --- /dev/null +++ b/themes/matrix.css @@ -0,0 +1,1039 @@ +/* ========================================================================= + * Matrix — a custom theme for Deezer for Linux + * ========================================================================= + * + * Black-and-green, dark-only, terminal-flavored. Squares off the app's + * rounded corners and layers a low-opacity animated "code rain" behind + * the UI (pure CSS: two tiled/animated SVG data-URI backgrounds, no JS). + * + * This theme intentionally renders identically for data-theme="light" and + * "dark" — there is no light variant, matrix runs one way only. + * + * deezer-desktop --custom-theme=/path/to/themes/matrix.css + * + * See themes/template.css for the full list of variables. + * ========================================================================= */ + +/* ========================================================================= + * Shared base palette — matrix green ramp on a near-black neutral ramp. + * ========================================================================= */ +:root { + /* Accent: matrix green instead of Deezer purple */ + --color-accent-main: #00ff41; + --color-accent-strong: #00cc34; + --color-accent-weak: #33ff66; + --color-accent-light: #99ffb3; + --color-accent-stronger: #00991f; /* deeper "pressed" tier */ + + /* Feedback (error / success / warning) — one default/disabled/hovered/ + * pressed variable per type, unlike template.css's single flat color */ + --color-feedback-error: #ff2b2b; + --color-feedback-error-disabled: #b35a5a; + --color-feedback-error-hovered: #d61f1f; + --color-feedback-error-pressed: #a51616; + --color-feedback-success: #39ff14; + --color-feedback-success-disabled: #7fcf6d; + --color-feedback-success-hovered: #2ee00f; + --color-feedback-success-pressed: #1fb00a; + --color-feedback-warning: #d4ff00; + --color-feedback-warning-disabled: #a3c95e; + --color-feedback-warning-hovered: #b8e000; + --color-feedback-warning-pressed: #93b400; + + /* Neutral ramp — near-black to pale green (light -> dark aliasing kept + * for template compatibility, but this theme only ever renders dark) */ + --color-grey-50: #e8ffe8; + --color-grey-100: #c8ffd2; + --color-grey-200: #a0e6ab; + --color-grey-300: #6ecb7c; + --color-grey-400: #3f9450; + --color-grey-500: #276b34; + --color-grey-600: #164a22; + --color-grey-700: #0d3216; + --color-grey-800: #08210f; + --color-grey-900: #030a05; + + /* Fixed dark/light grey ramps — do NOT swap with the mode. This theme is + * dark-only, so both ramps stay on the same near-black/green tones. */ + --color-dark-grey-200: #4c8a57; + --color-dark-grey-300: #3f9450; + --color-dark-grey-400: #2c7a3a; + --color-dark-grey-500: #276b34; + --color-dark-grey-600: #164a22; + --color-dark-grey-700: #0d3216; + --color-dark-grey-800: #08210f; + --color-dark-grey-900: #030a05; + --color-light-grey-50: #e8ffe8; + --color-light-grey-100: #c8ffd2; + --color-light-grey-200: #a0e6ab; + --color-light-grey-300: #6ecb7c; + --color-light-grey-400: #4c8a57; + --color-light-grey-500: #3f9450; + --color-light-grey-600: #2c7a3a; + --color-light-grey-700: #276b34; + --color-light-grey-800: #1a5227; + --color-light-grey-900: #164a22; +} + +/* ========================================================================= + * Tempo design tokens — see themes/template.css for the full rationale. + * Mode-independent tokens (accent + feedback + onDark/onLight). + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-background-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-background-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-background-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-background-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-background-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-background-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-background-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-background-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-border-feedback-error-focused: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-border-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-border-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-border-feedback-success-focused: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-border-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-border-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-border-feedback-warning-focused: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-border-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-icon-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-icon-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-icon-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-icon-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-icon-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-icon-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-icon-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-text-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-text-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-text-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-text-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-text-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-text-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-text-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-text-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +/* ========================================================================= + * "Light" mode — dark-only theme: renders the exact same near-black, + * green-on-black palette as dark mode below. There is no light variant. + * ========================================================================= */ +:root, +[data-theme="light"] { + /* Backgrounds — near-black with a faint green cast */ + --color-bg-main: #010401; + --color-bg-secondary: #030a05; + --color-bg-tertiary: #071206; + --color-bg-tertiary-hover: #0d1f0d; + --color-bg-tertiary-pressed: #123014; + --color-bg-contrast: #0d1f0d; + --color-bg-inverse: #d9ffd9; + --transparent-bg: #00000080; + + /* Text */ + --color-text-main: #c8ffc8; + --color-text-secondary: #5fbf6f; + --color-text-disabled: #2c5230; + --color-text-inverse: #010401; + + /* Borders & dividers */ + --color-border-neutral-primary: #164a22; + --color-border-neutral-secondary: #2f7a3d; + --color-divider-main: #164a22; + + /* Neutral aliases */ + --color-neutral-main: #276b34; + --color-neutral-strong: #3f9450; + --color-neutral-weak: #164a22; + + /* Brand accents — retinted matrix green instead of Deezer's duo/family/premium hues */ + --color-bg-brand-duo: #39ff14; + --color-bg-brand-trio: #39ff14; + --color-bg-brand-duo-selected: #0d3216; + --color-bg-brand-family-selected: #164a22; + --color-bg-brand-premium-selected: #0d3216; + --color-text-brand-duo: #010401; + --color-text-brand-trio: #010401; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * Dark mode — the only mode. Near-black background, matrix-green text. + * ========================================================================= */ +[data-theme="dark"] { + /* Backgrounds — near-black with a faint green cast */ + --color-bg-main: #010401; + --color-bg-secondary: #030a05; + --color-bg-tertiary: #071206; + --color-bg-tertiary-hover: #0d1f0d; + --color-bg-tertiary-pressed: #123014; + --color-bg-contrast: #0d1f0d; + --color-bg-inverse: #d9ffd9; + --transparent-bg: #00000080; + + /* Text */ + --color-text-main: #c8ffc8; + --color-text-secondary: #5fbf6f; + --color-text-disabled: #2c5230; + --color-text-inverse: #010401; + + /* Borders & dividers */ + --color-border-neutral-primary: #164a22; + --color-border-neutral-secondary: #2f7a3d; + --color-divider-main: #164a22; + + /* Neutral aliases */ + --color-neutral-main: #276b34; + --color-neutral-strong: #3f9450; + --color-neutral-weak: #164a22; + + /* Brand accents — retinted matrix green instead of Deezer's duo/family/premium hues */ + --color-bg-brand-duo: #39ff14; + --color-bg-brand-trio: #39ff14; + --color-bg-brand-duo-selected: #0d3216; + --color-bg-brand-family-selected: #164a22; + --color-bg-brand-premium-selected: #0d3216; + --color-text-brand-duo: #010401; + --color-text-brand-trio: #010401; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * 5. ARBITRARY CSS + * ========================================================================= + * - Squares off rounded corners app-wide (terminal/matrix look, not the + * default soft Deezer chrome). + * - Layers two tiled, animated SVG "code rain" backgrounds behind the app + * content at low opacity. Each SVG is a hand-generated tile of random + * half-width katakana + digits with per-glyph opacity so a few "streaks" + * read brighter, like a falling code column; animating background-position + * vertically makes the whole tile scroll down forever, no JS required. + * ========================================================================= */ +* { + border-radius: 2px !important; +} + +html, +body { + background-color: var(--color-bg-main) !important; +} + +body::before, +body::after { + content: ""; + position: fixed; + left: 0; + right: 0; + z-index: 0; + pointer-events: none; + background-repeat: repeat; + will-change: transform; + transform: translate3d(0, 0, 0); +} + +body::before { + top: -680px; + height: calc(100% + 680px); + background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22280%22%20height%3D%22680%22%3E%3Cstyle%3Etext%7Bfont-family%3Amonospace%3Bfont-size%3A16px%3B%7D%3C%2Fstyle%3E%3Ctext%20x%3D%223%22%20y%3D%2255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.49%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%2295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.35%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22115%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.32%22%3E%EF%BE%83%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22175%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.93%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.7%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.64%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.55%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.48%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.23%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BE%92%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22415%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BE%83%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.32%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.29%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.29%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22615%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.99%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22655%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.7%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.67%22%3E%EF%BE%89%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.34%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.27%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%2295%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.94%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.56%22%3E%EF%BE%96%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.44%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22175%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E9%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.15%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.3%22%3E%EF%BE%89%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22395%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.92%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.47%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.4%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22535%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BD%B2%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BE%90%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22615%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E%EF%BE%82%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22655%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.32%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%2255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.18%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%2295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22115%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.9%22%3E%EF%BE%82%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.8%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.82%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22175%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.98%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.79%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.51%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.54%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.47%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.36%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.34%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22455%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.96%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.78%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.82%22%3E%EF%BD%A6%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.58%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.55%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.45%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.44%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22615%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.43%22%3E%EF%BD%BE%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22635%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22655%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.27%22%3E%EF%BE%96%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.29%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.18%22%3E%EF%BE%9C%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22115%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BE%96%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22175%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.18%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BE%96%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.27%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.35%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22335%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.32%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22415%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.93%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.79%22%3E%EF%BE%92%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.7%22%3E%EF%BE%96%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22475%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.98%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22495%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.97%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.6%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22535%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.45%22%3E%EF%BD%B9%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22555%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.99%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.7%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.47%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22635%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22655%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.51%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%2235%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.94%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%2255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.75%22%3E%EF%BE%80%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.66%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%2295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.62%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22115%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.47%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.4%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22175%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22255%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.91%22%3E%EF%BD%B0%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.61%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.5%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.47%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.23%22%3E7%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22415%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BD%B2%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.3%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22535%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.29%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BD%B9%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22615%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.99%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22635%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.79%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22655%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.69%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.53%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%2255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.29%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.34%22%3E%EF%BE%90%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%2295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22115%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.18%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22135%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.96%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.67%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.63%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.53%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.39%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.18%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BE%8D%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22335%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.27%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BD%A6%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BE%83%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22415%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.18%22%3E%EF%BD%B9%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22515%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.91%22%3E9%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22535%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.72%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.58%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.64%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.6%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BE%82%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BE%9C%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2255%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.95%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.76%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2295%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.97%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22115%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.73%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.58%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.36%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.23%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22415%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E7%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22535%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.27%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.34%22%3E%EF%BE%92%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%2295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22115%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BE%90%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.18%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.32%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22175%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BE%83%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E%EF%BE%92%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22255%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.99%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.56%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22335%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.55%22%3E%EF%BD%B2%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.59%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.45%22%3E2%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.46%22%3E%EF%BE%90%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.7%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.54%22%3E2%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.57%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.44%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BE%80%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22615%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BD%BE%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22635%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.32%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.32%22%3E%EF%BE%82%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.23%22%3E%EF%BE%92%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.66%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.54%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22175%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.49%22%3E%EF%BD%AF%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BE%94%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22255%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.93%22%3E%EF%BD%B0%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.82%22%3E%EF%BE%80%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.76%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.54%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.38%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22415%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BE%89%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.3%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22635%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.35%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22655%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.34%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.3%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%2235%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.9%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%2255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.79%22%3E%EF%BD%B9%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.47%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.5%22%3E%EF%BE%94%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BD%B2%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.23%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22295%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.9%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22335%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.78%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.69%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22375%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.95%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.7%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.47%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22475%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.94%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.68%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.66%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22535%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.55%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.59%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22615%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.29%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22635%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22655%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.67%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.53%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%2255%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.99%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.8%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22115%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.89%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.64%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22175%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.55%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.49%22%3E%EF%BD%A6%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.23%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22255%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.92%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.66%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.71%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.6%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.23%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.34%22%3E%EF%BD%AF%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.35%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22615%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BE%93%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22635%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.97%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22655%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.85%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.73%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.36%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%2255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.29%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%2295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.32%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22175%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22195%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.91%22%3E%EF%BE%8F%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.77%22%3E%EF%BE%8F%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.74%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.74%22%3E%EF%BE%92%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.69%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.45%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.49%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22335%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.46%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.31%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22395%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%221.0%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.6%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.57%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.5%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.46%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22535%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.29%22%3E%EF%BE%94%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.27%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22635%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.61%22%3E%EF%BD%A6%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22675%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.48%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%2255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.21%22%3E%EF%BE%82%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BD%A6%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22175%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.27%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.24%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BD%B0%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BE%8F%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22315%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BE%9C%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22355%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.33%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BE%8F%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22415%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.96%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.8%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.6%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.53%22%3E%EF%BE%83%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.54%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22535%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.43%22%3E%EF%BE%93%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.38%22%3E%EF%BE%80%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22575%22%20fill%3D%22%23a6ffc2%22%20opacity%3D%220.96%22%3E%EF%BE%8D%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.68%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22635%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.57%22%3E9%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.2%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BE%82%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.16%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.26%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22115%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BE%80%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22135%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E%EF%BE%83%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22155%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.27%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22175%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.28%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22195%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.17%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22215%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22235%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22255%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.19%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22275%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E7%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22295%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.3%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22335%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.8%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22375%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.61%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22395%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.52%22%3E2%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22435%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.81%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22455%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.73%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22475%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.65%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22495%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.65%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22515%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.48%22%3E%EF%BE%92%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22535%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.39%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22555%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.38%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22575%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.27%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22595%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22615%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22635%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.22%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22655%22%20fill%3D%22%2300ff41%22%20opacity%3D%220.25%22%3E%EF%BD%BB%3C%2Ftext%3E%3C%2Fsvg%3E"); + background-size: 280px 680px; + opacity: 0.34; + animation: matrix-rain-fall-1 9s linear infinite; +} + +body::after { + top: -560px; + height: calc(100% + 560px); + background-image: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22280%22%20height%3D%22680%22%3E%3Cstyle%3Etext%7Bfont-family%3Amonospace%3Bfont-size%3A16px%3B%7D%3C%2Fstyle%3E%3Ctext%20x%3D%223%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.76%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.66%22%3E%EF%BD%B2%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.56%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.51%22%3E2%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.44%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22195%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22255%22%20fill%3D%22%2379ff9e%22%20opacity%3D%221.0%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.78%22%3E%EF%BD%B0%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.61%22%3E%EF%BE%83%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.35%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.16%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.34%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.16%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22535%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22575%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22595%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.94%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%223%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.83%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%2215%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.94%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.69%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.53%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.62%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.55%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.79%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.66%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.46%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.39%22%3E%EF%BE%86%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BE%86%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22315%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.2%22%3E7%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22375%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BD%AF%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E%EF%BE%80%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.16%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.17%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BE%90%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22535%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22575%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.9%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22595%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.64%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22615%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.78%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22655%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.54%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%2223%22%20y%3D%22675%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.42%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BE%86%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.34%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BD%B0%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22155%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BE%8D%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.34%22%3E%EF%BE%83%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.2%22%3E7%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22315%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BE%89%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22455%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.98%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.75%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.53%22%3E2%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.48%22%3E%EF%BE%89%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.63%22%3E%EF%BE%93%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22575%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.54%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22595%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BD%BE%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22615%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.98%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.69%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22655%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.66%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%2243%22%20y%3D%22675%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.47%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.6%22%3E%EF%BE%92%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.54%22%3E9%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%2255%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.98%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.62%22%3E%EF%BE%82%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.53%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.46%22%3E%EF%BD%A6%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.4%22%3E9%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22155%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E%EF%BD%B2%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22195%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.35%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22235%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.93%22%3E%EF%BE%8F%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.64%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.37%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22315%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BE%9C%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22375%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.34%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.32%22%3E%EF%BE%8B%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BE%86%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BE%80%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22535%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22575%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.15%22%3E9%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22595%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22615%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.95%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.9%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22655%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.66%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%2263%22%20y%3D%22675%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.62%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.57%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.39%22%3E%EF%BE%93%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.37%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22155%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.8%22%3E%EF%BE%86%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.53%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22195%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.54%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.43%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BE%92%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22315%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BD%BE%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.2%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.17%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BE%93%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BD%BE%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22535%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.9%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.69%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22615%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.7%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%2283%22%20y%3D%22675%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.91%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.42%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.43%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22375%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.2%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22415%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.95%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.81%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.81%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.49%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.51%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22535%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22575%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BD%B2%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22595%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.95%22%3E%EF%BD%AF%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22615%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.74%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.69%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22103%22%20y%3D%22675%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.53%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.82%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.74%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.51%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.57%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.39%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BE%98%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22155%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BE%9C%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.17%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BE%93%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22375%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.34%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22395%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.95%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.84%22%3E%EF%BE%8D%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.63%22%3E%EF%BE%93%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.62%22%3E%EF%BD%BE%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.59%22%3E%EF%BD%BE%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.48%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.63%22%3E%EF%BE%9C%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22595%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.48%22%3E%EF%BE%89%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.4%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22655%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%22123%22%20y%3D%22675%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.97%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BE%8F%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BD%B2%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BD%B0%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22155%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.93%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.73%22%3E%EF%BD%AF%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22195%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.76%22%3E%EF%BD%B0%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.59%22%3E%EF%BE%8F%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.47%22%3E%EF%BE%8F%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.76%22%3E%EF%BE%89%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22315%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.7%22%3E%EF%BE%8D%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.54%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.54%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22375%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.55%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.47%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BD%B0%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22535%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22575%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.17%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22595%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.2%22%3E%EF%BE%9C%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22615%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BE%91%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22655%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%22143%22%20y%3D%22675%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BD%AF%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2215%22%20fill%3D%22%2379ff9e%22%20opacity%3D%221.0%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.83%22%3E%EF%BE%94%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.8%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.67%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.58%22%3E%EF%BE%96%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.45%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.38%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22155%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22195%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.2%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BE%82%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22315%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BE%8D%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.32%22%3E6%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22375%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BE%89%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.32%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E2%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22535%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.93%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.8%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22575%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.68%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22615%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.42%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.47%22%3E%EF%BD%B9%3C%2Ftext%3E%3Ctext%20x%3D%22163%22%20y%3D%22675%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BD%B2%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.73%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%2235%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.95%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%2255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.86%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.59%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.45%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22195%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.2%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BE%80%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.34%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.2%22%3E%EF%BD%B1%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BE%90%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.17%22%3E%EF%BE%96%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.87%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22575%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.6%22%3E%EF%BD%AF%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22595%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.96%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22615%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.7%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.61%22%3E%EF%BD%A7%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22655%22%20fill%3D%22%2379ff9e%22%20opacity%3D%221.0%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%22183%22%20y%3D%22675%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.69%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BE%80%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E9%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.35%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E%EF%BD%B0%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22195%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.2%22%3E%EF%BE%94%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.34%22%3E2%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BD%AE%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BE%90%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BE%8A%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.32%22%3E%EF%BE%94%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BD%AF%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22435%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.96%22%3E%EF%BE%96%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.66%22%3E%EF%BD%A8%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.58%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.5%22%3E%EF%BE%99%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.43%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22535%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.4%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22575%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.94%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22595%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.7%22%3E%EF%BD%B3%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22615%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.62%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.48%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22203%22%20y%3D%22655%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.32%22%3E%EF%BE%9A%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.72%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%2255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.64%22%3E0%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.58%22%3E%EF%BE%8D%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.37%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.38%22%3E9%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22155%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22195%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.32%22%3E%EF%BE%95%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.15%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22315%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.15%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E2%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22375%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BE%93%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.16%22%3E%EF%BE%8D%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BE%8D%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BE%93%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BD%BF%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22575%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22595%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.34%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22615%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.29%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22223%22%20y%3D%22655%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BE%88%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%2255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BE%8C%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BD%B6%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22175%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.77%22%3E%EF%BD%A6%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22195%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.62%22%3E%EF%BE%86%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.49%22%3E%EF%BD%BB%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.38%22%3E%EF%BE%85%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BD%A9%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22315%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.92%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.73%22%3E%EF%BE%94%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22355%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.95%22%3E%EF%BD%AA%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22375%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.75%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.63%22%3E%EF%BD%B4%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.49%22%3E1%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22495%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.26%22%3E%EF%BD%AC%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.22%22%3E%EF%BD%BD%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22535%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.32%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22635%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.27%22%3E%EF%BE%84%3C%2Ftext%3E%3Ctext%20x%3D%22243%22%20y%3D%22675%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BE%8E%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.81%22%3E8%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2235%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.56%22%3E3%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.61%22%3E%EF%BE%94%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.41%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%2295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.33%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22115%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E%EF%BD%AB%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22135%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.18%22%3E%EF%BD%B8%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22155%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E5%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22215%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BE%83%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22255%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BE%9B%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22275%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.21%22%3E%EF%BE%94%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22295%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.16%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22315%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22335%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.24%22%3E%EF%BD%BC%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22355%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22375%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.23%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22395%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.25%22%3E%EF%BD%BA%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22415%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.3%22%3E4%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22435%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.35%22%3E7%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22455%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.19%22%3E7%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22475%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.16%22%3E%EF%BD%AF%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22495%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.96%22%3E%EF%BE%89%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22515%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.76%22%3E%EF%BE%87%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22535%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.61%22%3E%EF%BE%81%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22555%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.61%22%3E%EF%BD%B9%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22575%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.52%22%3E%EF%BD%B7%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22595%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.31%22%3E%EF%BD%B5%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22615%22%20fill%3D%22%2300c93d%22%20opacity%3D%220.28%22%3E%EF%BE%97%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22635%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.93%22%3E%EF%BE%96%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22655%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.93%22%3E%EF%BD%AD%3C%2Ftext%3E%3Ctext%20x%3D%22263%22%20y%3D%22675%22%20fill%3D%22%2379ff9e%22%20opacity%3D%220.9%22%3E7%3C%2Ftext%3E%3C%2Fsvg%3E"); + background-size: 230px 560px; + opacity: 0.24; + animation: matrix-rain-fall-2 13s linear infinite; +} + +@keyframes matrix-rain-fall-1 { + from { + transform: translate3d(0, 0, 0); + } + to { + transform: translate3d(0, 680px, 0); + } +} + +@keyframes matrix-rain-fall-2 { + from { + transform: translate3d(0, 0, 0); + } + to { + transform: translate3d(0, 560px, 0); + } +} + +#dzr-app { + position: relative; + z-index: 1; +} diff --git a/themes/monokai.css b/themes/monokai.css new file mode 100644 index 0000000..36fc052 --- /dev/null +++ b/themes/monokai.css @@ -0,0 +1,953 @@ +/* ========================================================================= + * Monokai — a custom theme for Deezer for Linux + * ========================================================================= + * + * https://monokai.pro/ — see themes/template.css for the full list + * of variables. + * + * deezer-desktop --sync-theme --custom-theme=/path/to/themes/monokai.css + * + * ---- Monokai reference ------------------------------------------------ + * Background: #272822 Selection: #49483e Line: #3e3d32 Fg: #f8f8f2 + * Comment: #75715e + * Pink/red: #f92672 Orange: #fd971f Yellow: #e6db74 + * Green: #a6e22e Cyan: #66d9ef Purple: #ae81ff + * ========================================================================= */ + +/* ========================================================================= + * Shared base palette — Monokai pink accent + a warm cream/charcoal + * neutral ramp. Remapping the grey ramp shifts every neutral surface in + * both modes. + * ========================================================================= */ +:root { + /* Accent: Monokai pink/magenta instead of Deezer purple */ + --color-accent-main: #f92672; + --color-accent-strong: #d91f5c; + --color-accent-weak: #ff6188; + --color-accent-light: #ff9dbb; + --color-accent-stronger: #b8134a; /* deeper "pressed" tier */ + + /* Feedback (error / success / warning) — one default/disabled/hovered/ + * pressed variable per type, unlike template.css's single flat color */ + --color-feedback-error: #f92672; + --color-feedback-error-disabled: #ff9dbb; + --color-feedback-error-hovered: #d91f5c; + --color-feedback-error-pressed: #b8134a; + --color-feedback-success: #a6e22e; + --color-feedback-success-disabled: #cbeb85; + --color-feedback-success-hovered: #8fc426; + --color-feedback-success-pressed: #79a621; + --color-feedback-warning: #fd971f; + --color-feedback-warning-disabled: #fec97e; + --color-feedback-warning-hovered: #dd7f0f; + --color-feedback-warning-pressed: #bd6a09; + + /* Neutral ramp mapped onto Monokai's warm cream/charcoal tones (light -> dark) */ + --color-grey-50: #f9f8f5; + --color-grey-100: #f0efe9; + --color-grey-200: #e2e0d5; + --color-grey-300: #c4c2b3; + --color-grey-400: #a6a394; + --color-grey-500: #75715e; /* comment grey */ + --color-grey-600: #57544a; + --color-grey-700: #49483e; /* selection */ + --color-grey-800: #3e3d32; /* line highlight */ + --color-grey-900: #272822; /* editor background */ + + /* Fixed dark/light grey ramps — do NOT swap with the mode */ + --color-dark-grey-200: #6e6b5c; + --color-dark-grey-300: #57544a; + --color-dark-grey-400: #49483e; + --color-dark-grey-500: #3e3d32; + --color-dark-grey-600: #34332a; + --color-dark-grey-700: #2d2c25; + --color-dark-grey-800: #272822; + --color-dark-grey-900: #1e1f1a; + --color-light-grey-50: #f9f8f5; + --color-light-grey-100: #f0efe9; + --color-light-grey-200: #e8e6dc; + --color-light-grey-300: #e2e0d5; + --color-light-grey-400: #d1cfc0; + --color-light-grey-500: #c4c2b3; + --color-light-grey-600: #b0ada0; + --color-light-grey-700: #a6a394; + --color-light-grey-800: #928f80; + --color-light-grey-900: #75715e; +} + +/* ========================================================================= + * Tempo design tokens — see themes/template.css section 4 for the full + * rationale. Mode-independent tokens (accent + feedback + onDark/onLight). + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-background-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-background-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-background-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-background-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-background-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-background-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-background-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-background-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-border-feedback-error-focused: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-border-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-border-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-border-feedback-success-focused: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-border-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-border-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-border-feedback-warning-focused: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-border-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-icon-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-icon-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-icon-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-icon-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-icon-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-icon-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-icon-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-text-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-text-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-text-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-text-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-text-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-text-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-text-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-text-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +/* ========================================================================= + * Monokai Light (cream background, charcoal text) + * ========================================================================= */ +:root, +[data-theme="light"] { + /* Backgrounds */ + --color-bg-main: #f9f8f2; + --color-bg-secondary: #f0efe4; + --color-bg-tertiary: #e6e4d5; + --color-bg-tertiary-hover: #dad7c4; + --color-bg-tertiary-pressed: #c9c6b0; + --color-bg-contrast: #e6e4d5; + --color-bg-inverse: #272822; + --transparent-bg: #f9f8f280; + + /* Text */ + --color-text-main: #272822; + --color-text-secondary: #75715e; /* comment grey */ + --color-text-disabled: #a6a394; + --color-text-inverse: #f8f8f2; + + /* Borders & dividers */ + --color-border-neutral-primary: #d1cfc0; + --color-border-neutral-secondary: #a6a394; + --color-divider-main: #d1cfc0; + + /* Neutral aliases */ + --color-neutral-main: #a6a394; + --color-neutral-strong: #75715e; + --color-neutral-weak: #e6e4d5; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * Monokai Dark (classic charcoal background, warm cream text) + * ========================================================================= */ +[data-theme="dark"] { + /* Backgrounds */ + --color-bg-main: #272822; + --color-bg-secondary: #1e1f1a; + --color-bg-tertiary: #3e3d32; + --color-bg-tertiary-hover: #49483e; + --color-bg-tertiary-pressed: #57544a; + --color-bg-contrast: #3e3d32; + --color-bg-inverse: #f8f8f2; + --transparent-bg: #2728224d; + + /* Text */ + --color-text-main: #f8f8f2; + --color-text-secondary: #a6a394; + --color-text-disabled: #57544a; + --color-text-inverse: #272822; + + /* Borders & dividers */ + --color-border-neutral-primary: #49483e; + --color-border-neutral-secondary: #75715e; + --color-divider-main: #49483e; + + /* Neutral aliases */ + --color-neutral-main: #57544a; + --color-neutral-strong: #a6a394; + --color-neutral-weak: #3e3d32; + + /* Brand accents retinted toward Monokai cyan */ + --color-bg-brand-duo: #66d9ef; + --color-bg-brand-trio: #66d9ef; + --color-bg-brand-duo-selected: #234952; + --color-text-brand-duo: #272822; + --color-text-brand-trio: #272822; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} diff --git a/themes/primer.css b/themes/primer.css new file mode 100644 index 0000000..dae1682 --- /dev/null +++ b/themes/primer.css @@ -0,0 +1,1042 @@ +/* ========================================================================= + * Primer — a custom theme for Deezer for Linux + * ========================================================================= + * + * https://primer.style/product/primitives/color/ — GitHub's design system + * primitives (base/color/light and base/color/dark, from the primer/ + * primitives repo). See themes/template.css for the full list of variables. + * + * deezer-desktop --sync-theme --custom-theme=/path/to/themes/primer.css + * + * ---- Primer reference (base color scales, 0 = lightest ... 9 = darkest) -- + * Light neutral: n1 #f6f8fa n2 #eff2f5 n3 #e6eaef n4 #e0e6eb + * n5 #dae0e7 n6 #d1d9e0 n7 #c8d1da n8 #818b98 + * n9 #59636e n10 #454c54 n11 #393f46 n12 #25292e + * Dark neutral: n1 #0d1117 n2 #151b23 n3 #212830 n4 #262c36 + * n5 #2a313c n6 #2f3742 n7 #3d444d n8 #656c76 + * n9 #9198a1 n10 #b7bdc8 n11 #d1d7e0 n12 #f0f6fc + * Blue (accent): 3 #54aeff/#58a6ff 4 #218bff/#388bfd 5 #0969da/#1f6feb + * 6 #0550ae/#1158c7 7 #033d8b/#0d419d + * Red: 4 #fa4549/#f85149 5 #cf222e/#da3633 6 #a40e26/#b62324 + * Green: 4 #2da44e/#2ea043 5 #1a7f37/#238636 6 #116329/#196c2e + * Yellow: 3 #d4a72c/#d29922 4 #bf8700/#bb8009 5 #9a6700/#9e6a03 + * (light/dark values shown where they differ) + * ========================================================================= */ + +/* ========================================================================= + * Shared base palette — Primer's GitHub blue accent + neutral ramps taken + * straight from the light/dark base color scales. Remapping the grey ramp + * shifts every neutral surface in both modes. + * ========================================================================= */ +:root { + /* Accent: Primer blue instead of Deezer purple. The light-scale blue + * (#0969da) is used as "main" so it stays legible as text/icon color on + * a white background as well as a filled button on a dark one. */ + --color-accent-main: #0969da; /* blue.5 (light) */ + --color-accent-strong: #0550ae; /* blue.6 (light) */ + --color-accent-weak: #218bff; /* blue.4 (light) */ + --color-accent-light: #54aeff; /* blue.3 (light) */ + --color-accent-stronger: #033d8b; /* blue.7 (light), deeper "pressed" tier */ + + /* Feedback (error / success / warning) — one default/disabled/hovered/ + * pressed variable per type, unlike template.css's single flat color. + * Uses the light-scale hues for the same both-backgrounds-legible + * reason as the main accent above. */ + --color-feedback-error: #cf222e; /* red.5 */ + --color-feedback-error-disabled: #ff8182; /* red.3 */ + --color-feedback-error-hovered: #a40e26; /* red.6 */ + --color-feedback-error-pressed: #82071e; /* red.7 */ + --color-feedback-success: #1a7f37; /* green.5 */ + --color-feedback-success-disabled: #4ac26b; /* green.3 */ + --color-feedback-success-hovered: #116329; /* green.6 */ + --color-feedback-success-pressed: #044f1e; /* green.7 */ + --color-feedback-warning: #9a6700; /* yellow.5 */ + --color-feedback-warning-disabled: #d4a72c; /* yellow.3 */ + --color-feedback-warning-hovered: #7d4e00; /* yellow.6 */ + --color-feedback-warning-pressed: #633c01; /* yellow.7 */ + + /* Neutral ramp mapped onto Primer's light-mode neutral scale (light -> dark) */ + --color-grey-50: #f6f8fa; /* light n1 */ + --color-grey-100: #eff2f5; /* light n2 */ + --color-grey-200: #e6eaef; /* light n3 */ + --color-grey-300: #dae0e7; /* light n5 */ + --color-grey-400: #c8d1da; /* light n7 */ + --color-grey-500: #818b98; /* light n8 */ + --color-grey-600: #59636e; /* light n9 */ + --color-grey-700: #454c54; /* light n10 */ + --color-grey-800: #393f46; /* light n11 */ + --color-grey-900: #25292e; /* light n12 */ + + /* Fixed dark/light grey ramps — do NOT swap with the mode */ + --color-dark-grey-200: #3d444d; /* dark n7 */ + --color-dark-grey-300: #2f3742; /* dark n6 */ + --color-dark-grey-400: #2a313c; /* dark n5 */ + --color-dark-grey-500: #262c36; /* dark n4 */ + --color-dark-grey-600: #212830; /* dark n3 */ + --color-dark-grey-700: #151b23; /* dark n2 */ + --color-dark-grey-800: #0d1117; /* dark n1 */ + --color-dark-grey-900: #010409; /* dark black */ + --color-light-grey-50: #f6f8fa; /* light n1 */ + --color-light-grey-100: #eff2f5; /* light n2 */ + --color-light-grey-200: #e6eaef; /* light n3 */ + --color-light-grey-300: #e0e6eb; /* light n4 */ + --color-light-grey-400: #dae0e7; /* light n5 */ + --color-light-grey-500: #d1d9e0; /* light n6 */ + --color-light-grey-600: #c8d1da; /* light n7 */ + --color-light-grey-700: #818b98; /* light n8 */ + --color-light-grey-800: #59636e; /* light n9 */ + --color-light-grey-900: #454c54; /* light n10 */ + + /* Typography — Primer/GitHub's system font stack (base/typography/ + * fontStack/normal in primer/primitives), used for both body and + * heading since Primer doesn't split the two the way Deezer does. + * Confirmed consumed by body{font-family:var(--tempo-fonts-body,...)} + * and .modal-header{font-family:var(--tempo-fonts-heading,...)} in the + * compiled app-web CSS. Chakra's theme provider also sets these two + * (and the radii below) as inline custom properties at runtime — same + * as the --tempo-colors-* tokens — so !important is required here too, + * confirmed by testing without it over CDP (computed value stayed + * "Inter" until !important was added). */ + --tempo-fonts-body: + -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, + Arial, sans-serif !important; + --tempo-fonts-heading: + -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Helvetica, + Arial, sans-serif !important; + + /* Corner radius — Primer's flatter 6px default instead of Deezer's 8px, + * with matching smaller tiers. Confirmed consumed by --thumbnail-radius + * (app-web css), popper/account headers (deeztools-popper.css, + * route-naboo.css), and search-result chips (route-artist/album/ + * concerts/naboo css) via var(--tempo-radii-*). */ + --tempo-radii-lg: 6px !important; + --tempo-radii-s: 4px !important; + --tempo-radii-xs: 3px !important; +} + +/* ========================================================================= + * Tempo design tokens — see themes/template.css section 4 for the full + * rationale. Mode-independent tokens (accent + feedback + onDark/onLight). + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-background-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-background-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-background-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-background-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-background-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-background-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-background-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-background-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-border-feedback-error-focused: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-border-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-border-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-border-feedback-success-focused: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-border-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-border-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-border-feedback-warning-focused: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-border-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-icon-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-icon-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-icon-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-icon-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-icon-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-icon-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-icon-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-text-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-text-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-text-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-text-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-text-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-text-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-text-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-text-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +/* ========================================================================= + * Primer Light (GitHub's default light canvas/fg colors) + * ========================================================================= */ +:root, +[data-theme="light"] { + /* Backgrounds */ + --color-bg-main: #ffffff; /* canvas.default */ + --color-bg-secondary: #f6f8fa; /* canvas.subtle, light n1 */ + --color-bg-tertiary: #eff2f5; /* light n2 */ + --color-bg-tertiary-hover: #e6eaef; /* light n3 */ + --color-bg-tertiary-pressed: #e0e6eb; /* light n4 */ + --color-bg-contrast: #dae0e7; /* light n5 */ + --color-bg-inverse: #25292e; /* light n12 */ + --transparent-bg: #ffffff80; + + /* Text */ + --color-text-main: #1f2328; /* fg.default (base black) */ + --color-text-secondary: #59636e; /* fg.muted, light n9 */ + --color-text-disabled: #818b98; /* fg.subtle, light n8 */ + --color-text-inverse: #ffffff; + + /* Borders & dividers */ + --color-border-neutral-primary: #d1d9e0; /* border.default, light n6 */ + --color-border-neutral-secondary: #c8d1da; /* light n7 */ + --color-divider-main: #d1d9e0; + + /* Neutral aliases */ + --color-neutral-main: #e6eaef; /* light n3 */ + --color-neutral-strong: #e0e6eb; /* light n4 */ + --color-neutral-weak: #eff2f5; /* light n2 */ + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * Primer Dark (GitHub's default dark canvas/fg colors) + * ========================================================================= */ +[data-theme="dark"] { + /* Backgrounds */ + --color-bg-main: #0d1117; /* canvas.default, dark n1 */ + --color-bg-secondary: #151b23; /* canvas.subtle, dark n2 */ + --color-bg-tertiary: #212830; /* dark n3 */ + --color-bg-tertiary-hover: #262c36; /* dark n4 */ + --color-bg-tertiary-pressed: #2a313c; /* dark n5 */ + --color-bg-contrast: #2f3742; /* dark n6 */ + --color-bg-inverse: #f6f8fa; /* light n1 */ + --transparent-bg: #0104094d; + + /* Text */ + --color-text-main: #f0f6fc; /* fg.default, dark n12 */ + --color-text-secondary: #9198a1; /* fg.muted, dark n9 */ + --color-text-disabled: #656c76; /* fg.subtle, dark n8 */ + --color-text-inverse: #010409; /* base black (dark) */ + + /* Borders & dividers */ + --color-border-neutral-primary: #3d444d; /* border.default, dark n7 */ + --color-border-neutral-secondary: #f0f6fc; /* dark n12 */ + --color-divider-main: #3d444d; + + /* Neutral aliases */ + --color-neutral-main: #2f3742; /* dark n6 */ + --color-neutral-strong: #3d444d; /* dark n7 */ + --color-neutral-weak: #212830; /* dark n3 */ + + /* Brand accents retinted toward Primer green */ + --color-bg-brand-duo: #56d364; /* green.2 (dark) */ + --color-bg-brand-trio: #56d364; + --color-bg-brand-duo-selected: #212830; + --color-text-brand-duo: #04260f; /* green.9 (dark) */ + --color-text-brand-trio: #04260f; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * 5. ARBITRARY CSS + * ========================================================================= + * Primer's identity isn't only GitHub blue on a grey ramp — it's flat, + * hairline-bordered surfaces with a 6px corner radius instead of Deezer's + * heavier drop shadows and rounder 8-10px curves. This section carries + * that structural language on top of the color/radius/font tokens above. + * Selectors confirmed against the compiled app bundle (app-web css), not + * guessed. !important is used only where overriding an existing hardcoded + * declaration of the same property/selector (border-radius, box-shadow) — + * new properties (border) don't need it. + * ========================================================================= */ + +/* ---- Modals: hairline border + Primer's shallower resting shadow + * instead of Deezer's heavier one, sharper 6px corners to match the + * radii tokens above (.modal-dialog's border-radius:3px is hardcoded, + * not token-driven, so it needs a direct override here) ---- */ +.modal-dialog { + border: 1px solid var(--color-border-neutral-primary); + border-radius: 6px !important; + box-shadow: 0 8px 24px rgba(140, 149, 159, 0.2) !important; +} +.modal-header-partner, +.modal-family-upsale-header { + border-radius: 6px 6px 0 0 !important; +} +.modal-footer { + border-radius: 0 0 6px 6px !important; +} + +/* ---- Cover art / thumbnails: a hairline border reading as a card edge, + * GitHub-repo-card style, in place of the ambient drop shadow ---- */ +.thumbnail { + border: 1px solid var(--color-border-neutral-primary); + box-shadow: none !important; +} + +/* ---- Player bar: hairline top border standing in for Deezer's + * shadow-less flat edge, echoing Primer's bordered toolbars ---- */ +#player { + border-top: 1px solid var(--color-border-neutral-primary); +} + +/* ---- Buttons: Primer's 6px corner instead of Deezer's tighter 3px + * (.navbar-button's border-radius:3px is hardcoded, same as the modal + * above) ---- */ +.navbar-button { + border-radius: 6px !important; +} diff --git a/themes/synthwave.css b/themes/synthwave.css new file mode 100644 index 0000000..6827952 --- /dev/null +++ b/themes/synthwave.css @@ -0,0 +1,1107 @@ +/* ========================================================================= + * SynthWave '84 — a custom theme for Deezer for Linux + * ========================================================================= + * + * https://github.com/robb0wen/synthwave-vscode — see themes/template.css + * for the full list of variables. + * + * Always dark: this theme intentionally paints the same neon palette into + * both the light-mode and dark-mode blocks (sections 2 & 3), so the app + * stays SynthWave regardless of --sync-theme / the OS light-dark setting. + * + * deezer-desktop --custom-theme=/path/to/themes/synthwave.css + * + * ---- SynthWave '84 reference ----------------------------------------- + * Backgrounds: editor #262335 sidebar/status/title #241b2f + * activity bar #171520 dropdown/input #2a2139 + * Neon: pink #ff7edb coral #f97e72 cyan #36f9f6 + * green #72f1b8 yellow #fede5d red #fe4450 + * Text: foreground #ffffff comment/secondary #848bbd + * ========================================================================= */ + +/* ========================================================================= + * 1. GLOBAL BASE PALETTE (shared by both light and dark modes) + * ========================================================================= */ +:root { + /* ---- Accent: SynthWave neon pink instead of Deezer purple ---- */ + --color-accent-main: #ff7edb; + --color-accent-strong: #e455c0; /* darker neon pink — hover/pressed */ + --color-accent-weak: #36f9f6; /* neon cyan — secondary accent, for the pink/cyan retrowave contrast */ + --color-accent-light: #ffc2ef; /* pale pink tint — disabled/onDark */ + --color-accent-stronger: #b83a9c; /* deeper "pressed" tier */ + + /* ---- Feedback (error / success / warning) — SynthWave neon triad ---- */ + --color-feedback-error: #fe4450; + --color-feedback-error-disabled: #ff8890; + --color-feedback-error-hovered: #e3323e; + --color-feedback-error-pressed: #c7222d; + --color-feedback-success: #72f1b8; + --color-feedback-success-disabled: #a8f6d3; + --color-feedback-success-hovered: #4bdb9b; + --color-feedback-success-pressed: #2fbd80; + --color-feedback-warning: #fede5d; + --color-feedback-warning-disabled: #ffedad; + --color-feedback-warning-hovered: #f0c93a; + --color-feedback-warning-pressed: #d6ac1e; + + /* ---- Absolute black / white ---- */ + /* --color-black: #000; */ + /* --color-white: #fff; */ + + /* ---- Neutral grey ramp (50 = lightest ... 900 = darkest), mapped onto + * SynthWave's dark purple chrome (light -> dark) ---- */ + --color-grey-50: #ffffff; /* foreground */ + --color-grey-100: #d3cdee; + --color-grey-200: #a8a1d6; + --color-grey-300: #848bbd; /* comment / secondary text */ + --color-grey-400: #6c6f9a; + --color-grey-500: #614d85; /* button.background */ + --color-grey-600: #463465; /* menu.background */ + --color-grey-700: #37294d; /* list.hoverBackground */ + --color-grey-800: #2a2139; /* dropdown/input.background */ + --color-grey-900: #171520; /* activityBar.background */ + + /* ---- Fixed dark/light grey ramps (do NOT swap with the mode; used by + * always-dark chrome like the player bar even in light mode). This + * theme is always dark, so both ramps stay in the SynthWave palette. */ + --color-dark-grey-200: #6c6f9a; + --color-dark-grey-300: #614d85; + --color-dark-grey-400: #524070; + --color-dark-grey-500: #463465; + --color-dark-grey-600: #37294d; + --color-dark-grey-700: #2a2139; + --color-dark-grey-800: #241b2f; + --color-dark-grey-900: #171520; + --color-light-grey-50: #ffffff; + --color-light-grey-100: #e4e0f5; + --color-light-grey-200: #d3cdee; + --color-light-grey-300: #b6b1e0; + --color-light-grey-400: #a8a1d6; + --color-light-grey-500: #9088c2; + --color-light-grey-600: #848bbd; + --color-light-grey-700: #6c6f9a; + --color-light-grey-800: #5a5580; + --color-light-grey-900: #463465; +} + +/* ========================================================================= + * 2. LIGHT MODE + * ========================================================================= + * Always dark: this theme has no light mode, so the "light" block below + * gets the exact same SynthWave values as the dark block in section 3. + * That way toggling --sync-theme / the OS setting never turns it light. + * ========================================================================= */ +:root, +[data-theme="light"] { + /* ---- Backgrounds ---- */ + --color-bg-main: #262335; /* editor.background */ + --color-bg-secondary: #241b2f; /* sideBar/statusBar/titleBar.background */ + --color-bg-tertiary: #2a2139; /* dropdown/input/badge.background */ + --color-bg-tertiary-hover: #37294d; /* list.hoverBackground */ + --color-bg-tertiary-pressed: #463465; /* menu.background */ + --color-bg-contrast: #171520; /* activityBar.background */ + --color-bg-inverse: #ffffff; + --transparent-bg: #26233580; + + /* ---- Text ---- */ + --color-text-main: #ffffff; + --color-text-secondary: #848bbd; /* comment / lavender-grey */ + --color-text-disabled: #6c6f8f; + --color-text-inverse: #262335; + + /* ---- Borders & dividers ---- */ + --color-border-neutral-primary: #495495; /* editorGroup.border */ + --color-border-neutral-secondary: #6c6f9a; + --color-divider-main: #37294d; + + /* ---- Neutral aliases ---- */ + --color-neutral-main: var(--color-grey-700); + --color-neutral-strong: var(--color-grey-500); + --color-neutral-weak: var(--color-grey-800); +} + +/* ========================================================================= + * 3. DARK MODE + * ========================================================================= */ +[data-theme="dark"] { + /* ---- Backgrounds ---- */ + --color-bg-main: #262335; + --color-bg-secondary: #241b2f; + --color-bg-tertiary: #2a2139; + --color-bg-tertiary-hover: #37294d; + --color-bg-tertiary-pressed: #463465; + --color-bg-contrast: #171520; + --color-bg-inverse: #ffffff; + --transparent-bg: #26233580; + + /* ---- Text ---- */ + --color-text-main: #ffffff; + --color-text-secondary: #848bbd; + --color-text-disabled: #6c6f8f; + --color-text-inverse: #262335; + + /* ---- Borders & dividers ---- */ + --color-border-neutral-primary: #495495; + --color-border-neutral-secondary: #6c6f9a; + --color-divider-main: #37294d; + + /* ---- Neutral aliases ---- */ + --color-neutral-main: var(--color-grey-700); + --color-neutral-strong: var(--color-grey-500); + --color-neutral-weak: var(--color-grey-800); + + /* ---- Brand accents used only in dark mode — retinted to SynthWave cyan ---- */ + --color-bg-brand-duo: #36f9f6; + --color-bg-brand-trio: #36f9f6; + --color-bg-brand-duo-selected: #1b3d3c; + --color-bg-brand-family-selected: #3d1830; + --color-bg-brand-premium-selected: #2a1b45; + --color-text-brand-duo: #08080f; + --color-text-brand-trio: #08080f; +} + +/* ========================================================================= + * 4. TEMPO DESIGN TOKENS (pre-wired source — power users only) + * ========================================================================= + * Most of the app's chrome reads this separate "tempo" token layer, not + * sections 1-3 directly — and the app's own JS also writes to it at + * runtime. Every line below is a var() back to sections 1-3 (no literal + * colors) and uses !important to reliably win over that runtime value. + * This block is ON by default: edit sections 1-3 instead, unless you need + * to override one specific state. Some tokens exist in both onDark/on-dark + * casings in the app's CSS (upstream inconsistency) — override both if you + * touch one. + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-disabled: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-hovered: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-pressed: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-disabled: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-hovered: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-pressed: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-disabled: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-hovered: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-pressed: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-disabled: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-focused: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-hovered: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-pressed: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-disabled: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-focused: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-hovered: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-pressed: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-disabled: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-focused: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-hovered: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-pressed: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-disabled: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-hovered: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-pressed: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-disabled: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-hovered: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-pressed: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-disabled: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-hovered: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-pressed: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-disabled: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-hovered: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-pressed: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-disabled: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-hovered: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-pressed: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-disabled: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-hovered: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-pressed: var( + --color-feedback-warning + ) !important; + + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +[data-theme="light"] { + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +[data-theme="dark"] { + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-primary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * 5. ARBITRARY CSS + * ========================================================================= + * SynthWave '84's identity comes from neon glow + a sunset gradient, not + * just flat accent colors — this section adds both on top of sections 1-4. + * Selectors below are confirmed against the compiled app bundle + * (app-web css + electron/route bundles), not guessed. + * ========================================================================= */ + +/* ---- Ambient horizon wash behind the whole app: a fixed, low-opacity + * sunset spectrum (magenta sky -> coral -> gold) standing in for + * SynthWave's signature glowing sun. Sits behind content (z-index: 0) so + * it never affects legibility. ---- */ +.naboo { + position: relative; +} +.naboo::before { + background: + radial-gradient( + ellipse 90% 55% at 50% -15%, + rgba(255, 126, 219, 0.14), + transparent 55% + ), + radial-gradient( + ellipse 70% 40% at 50% 0%, + rgba(249, 126, 114, 0.1), + transparent 60% + ), + linear-gradient( + 180deg, + transparent 0%, + rgba(254, 222, 93, 0.05) 30%, + transparent 60% + ); + content: ""; + inset: 0; + pointer-events: none; + position: fixed; + z-index: 0; +} + +/* ---- The sun itself: a blurred gold-to-pink disc bleeding down from + * the top of the viewport, mostly off-canvas so it reads as ambient + * sunrise light rather than a hard-edged shape over the UI. ---- */ +.naboo::after { + background: radial-gradient( + circle, + rgba(254, 222, 93, 0.35) 0%, + rgba(249, 126, 114, 0.25) 45%, + rgba(255, 126, 219, 0.15) 70%, + transparent 85% + ); + border-radius: 50%; + content: ""; + filter: blur(40px); + height: 520px; + left: 50%; + pointer-events: none; + position: fixed; + top: -180px; + transform: translateX(-50%); + width: 520px; + z-index: 0; +} + +/* ---- Player bar: vertical gradient instead of a flat fill, plus a + * gold horizon-line glow along the top edge ---- */ +#player { + background: linear-gradient( + 180deg, + var(--color-bg-contrast) 0%, + var(--color-bg-secondary) 100% + ) !important; + box-shadow: + 0 -1px 0 rgba(254, 222, 93, 0.35), + 0 -8px 24px -8px rgba(249, 126, 114, 0.3); +} + +/* ---- Cover art: pink/gold neon halo on hover ---- */ +.playlist-cover-solo, +.playlist-cover, +.cell-thumbnail, +.block_cover, +.tempo-thumbnail-cover-container { + transition: box-shadow 0.25s ease; +} +.playlist-cover-solo:hover, +.playlist-cover:hover, +.cell-thumbnail:hover, +.block_cover:hover, +.tempo-thumbnail-cover-container:hover { + box-shadow: + 0 0 16px 2px rgba(255, 126, 219, 0.45), + 0 0 32px 4px rgba(254, 222, 93, 0.25); +} + +/* ---- Playing-state icon: gold drop-shadow glow — the "now shining" cue ---- */ +.play-active { + filter: drop-shadow(0 0 4px rgba(254, 222, 93, 0.85)); +} + +/* ---- Buttons: full sunset gradient fill (pink -> coral -> gold) + halo ---- */ +.navbar-button { + background: linear-gradient( + 135deg, + var(--color-accent-main) 0%, + #f97e72 50%, + #fede5d 100% + ) !important; + box-shadow: 0 0 10px 1px rgba(249, 126, 114, 0.5); + transition: box-shadow 0.2s ease; +} +.navbar-button:hover { + box-shadow: 0 0 16px 3px rgba(254, 222, 93, 0.7); +} + +/* ---- Progress / volume slider: gold glow track — fills with sunlight ---- */ +.nano-slider { + box-shadow: 0 0 6px 1px rgba(254, 222, 93, 0.4); +} + +/* ---- Scrollbar: faint cyan glow on hover ---- */ +::-webkit-scrollbar-thumb:hover { + box-shadow: 0 0 6px 1px rgba(54, 249, 246, 0.5) !important; +} From 7b3dac87ecb332ed80e556e7f833766fcf46238a Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 23:44:19 +0200 Subject: [PATCH 09/10] docs(theme): add liquid glass theme (experimental) --- README.md | 21 +- themes/liquid-glass.css | 1659 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 1670 insertions(+), 10 deletions(-) create mode 100644 themes/liquid-glass.css diff --git a/README.md b/README.md index 6f4c10b..b2ce722 100644 --- a/README.md +++ b/README.md @@ -148,16 +148,17 @@ Pair this with [`--sync-theme`](#usage) so the mode follows your OS setting auto The [`themes/`](./themes) folder contains drop-in themes you can use as-is or as a reference: -| Theme | Modes | -| --------------------------------------- | ------------ | -| [Solarized](./themes/solarized.css) | Light & dark | -| [Nord](./themes/nord.css) | Light & dark | -| [Everforest](./themes/everforest.css) | Light & dark | -| [Monokai](./themes/monokai.css) | Light & dark | -| [SynthWave '84](./themes/synthwave.css) | Dark only | -| [Primer](./themes/primer.css) | Light & dark | -| [Gruvbox](./themes/gruvbox.css) | Light & dark | -| [Matrix](./themes/matrix.css) | Dark only | +| Theme | Modes | +| ----------------------------------------- | ------------ | +| [Solarized](./themes/solarized.css) | Light & dark | +| [Nord](./themes/nord.css) | Light & dark | +| [Everforest](./themes/everforest.css) | Light & dark | +| [Monokai](./themes/monokai.css) | Light & dark | +| [SynthWave '84](./themes/synthwave.css) | Dark only | +| [Primer](./themes/primer.css) | Light & dark | +| [Gruvbox](./themes/gruvbox.css) | Light & dark | +| [Matrix](./themes/matrix.css) | Dark only | +| [Liquid Glass](./themes/liquid-glass.css) | Light & dark | For example: diff --git a/themes/liquid-glass.css b/themes/liquid-glass.css new file mode 100644 index 0000000..6085b74 --- /dev/null +++ b/themes/liquid-glass.css @@ -0,0 +1,1659 @@ +/* ========================================================================= + * Liquid Glass — a custom theme for Deezer for Linux + * ========================================================================= + * + * Apple's macOS/iOS "Liquid Glass" material language: frosted, translucent + * panels that float as rounded islands over a soft system-grey canvas, an + * iOS-blue accent, and continuous (very round) corners instead of Deezer's + * boxier defaults. See themes/template.css for the full variable list. + * + * deezer-desktop --sync-theme --custom-theme=/path/to/themes/liquid-glass.css + * + * ---- Reference ------------------------------------------------------- + * Accent (iOS blue): #0a84ff / strong #0060df / weak #5ac8fa + * System grey ramp (Apple systemGray6..systemGray, light -> dark): + * #f2f2f7 #e5e5ea #d1d1d6 #c7c7cc #aeaeb2 #8e8e93 #636366 #48484a #2c2c2e #1c1c1e + * Feedback: error #ff3b30 success #34c759 warning #ff9500 + * ========================================================================= */ + +/* ========================================================================= + * Shared base palette + * ========================================================================= */ +:root { + /* Accent: iOS system blue instead of Deezer purple */ + --color-accent-main: #0a84ff; + --color-accent-strong: #0060df; + --color-accent-weak: #5ac8fa; + --color-accent-light: #9dd6ff; + --color-accent-stronger: #0048a8; /* deeper "pressed" tier */ + + /* Feedback (error / success / warning) — iOS system colors, one + * default/disabled/hovered/pressed variable per type */ + --color-feedback-error: #ff3b30; + --color-feedback-error-disabled: #ff9d97; + --color-feedback-error-hovered: #e0332a; + --color-feedback-error-pressed: #c22a22; + --color-feedback-success: #34c759; + --color-feedback-success-disabled: #94e0a8; + --color-feedback-success-hovered: #2aa848; + --color-feedback-success-pressed: #228a3b; + --color-feedback-warning: #ff9500; + --color-feedback-warning-disabled: #ffc477; + --color-feedback-warning-hovered: #e08600; + --color-feedback-warning-pressed: #c27200; + + /* Neutral ramp mapped onto Apple's systemGray6 -> systemGray -> dark + * systemGray tiers (light -> dark) */ + --color-grey-50: #f2f2f7; /* systemGray6 light */ + --color-grey-100: #e5e5ea; /* systemGray5 light */ + --color-grey-200: #d1d1d6; /* systemGray4 light */ + --color-grey-300: #c7c7cc; /* systemGray3 light */ + --color-grey-400: #aeaeb2; /* systemGray2 light */ + --color-grey-500: #8e8e93; /* systemGray light */ + --color-grey-600: #636366; /* systemGray2 dark */ + --color-grey-700: #48484a; /* systemGray4 dark */ + --color-grey-800: #2c2c2e; /* systemGray5 dark */ + --color-grey-900: #1c1c1e; /* systemGray6 dark */ + + /* Fixed dark/light grey ramps — do NOT swap with the mode; always-dark + * chrome (e.g. the player bar even in light mode) reads from these */ + --color-dark-grey-200: #86868b; + --color-dark-grey-300: #757579; + --color-dark-grey-400: #636366; + --color-dark-grey-500: #48484a; + --color-dark-grey-600: #3a3a3c; + --color-dark-grey-700: #2c2c2e; + --color-dark-grey-800: #242426; + --color-dark-grey-900: #1c1c1e; + --color-light-grey-50: #f9f9fb; + --color-light-grey-100: #f2f2f7; + --color-light-grey-200: #e9e9ee; + --color-light-grey-300: #e5e5ea; + --color-light-grey-400: #d8d8dd; + --color-light-grey-500: #d1d1d6; + --color-light-grey-600: #c7c7cc; + --color-light-grey-700: #b6b6bb; + --color-light-grey-800: #aeaeb2; + --color-light-grey-900: #8e8e93; + + /* Continuous, very round "glass island" corners instead of Deezer's + * tighter defaults. Confirmed consumed by --thumbnail-radius (app-web + * css), popper/account headers, and search-result chips via + * var(--tempo-radii-*) — same tokens primer.css uses for the opposite + * (flatter) effect. */ + --tempo-radii-lg: 20px !important; + --tempo-radii-s: 14px !important; + --tempo-radii-xs: 10px !important; + + /* SF Pro stand-in — Apple's system font stack, matching the rest of the + * "liquid glass" identity. Chakra's theme provider sets these two as + * runtime inline custom properties, so !important is required (same + * caveat documented in primer.css). */ + --tempo-fonts-body: + -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", + Helvetica, Arial, sans-serif !important; + --tempo-fonts-heading: + -apple-system, BlinkMacSystemFont, "SF Pro Display", "Helvetica Neue", + Helvetica, Arial, sans-serif !important; +} + +/* ========================================================================= + * Tempo design tokens — see themes/template.css section 4 for the full + * rationale. Mode-independent tokens (accent + feedback + onDark/onLight). + * ========================================================================= */ +:root { + --tempo-colors-background-accent-onColorDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onColorDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onColorLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onColorLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onColorLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-background-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-background-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-background-accent-secondary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-background-accent-secondary-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-background-accent-secondary-pressed: var( + --color-accent-strong + ) !important; + --tempo-colors-background-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-background-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-background-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-background-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-background-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-background-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-background-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-background-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-background-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-background-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-background-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-background-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-background-neutral-onDark-default: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-onDark-disabled: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-onDark-hovered: var( + --color-dark-grey-600 + ) !important; + --tempo-colors-background-neutral-onDark-pressed: var( + --color-dark-grey-500 + ) !important; + --tempo-colors-background-neutral-onLight-default: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-onLight-disabled: var( + --color-light-grey-200 + ) !important; + --tempo-colors-background-neutral-onLight-hovered: var( + --color-light-grey-400 + ) !important; + --tempo-colors-background-neutral-onLight-pressed: var( + --color-light-grey-500 + ) !important; + --tempo-colors-border-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-border-accent-onContent-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-onContent-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-onContent-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-border-accent-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-border-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-border-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-border-cover-neutral-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-border-feedback-error-focused: var( + --color-feedback-error + ) !important; + --tempo-colors-border-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-border-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-border-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-border-feedback-success-focused: var( + --color-feedback-success + ) !important; + --tempo-colors-border-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-border-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-border-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-border-feedback-warning-focused: var( + --color-feedback-warning + ) !important; + --tempo-colors-border-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-border-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-icon-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-icon-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-icon-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-icon-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-icon-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-icon-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-icon-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-icon-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-icon-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-icon-feedback-info-default: var( + --color-accent-main + ) !important; + --tempo-colors-icon-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-icon-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-icon-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-icon-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-icon-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-icon-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-icon-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-icon-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-text-accent-onAccent-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onAccent-selected: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-default: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-disabled: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-hovered: var(--color-grey-50) !important; + --tempo-colors-text-accent-onColor-pressed: var(--color-grey-50) !important; + --tempo-colors-text-accent-onContent-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-default: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-onDark-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-hovered: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onDark-pressed: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onDark-selected: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-default: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-onLight-disabled: var( + --color-accent-weak + ) !important; + --tempo-colors-text-accent-onLight-hovered: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-onLight-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-onLight-selected: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-default: var( + --color-accent-main + ) !important; + --tempo-colors-text-accent-primary-disabled: var( + --color-accent-light + ) !important; + --tempo-colors-text-accent-primary-hovered: var( + --color-accent-strong + ) !important; + --tempo-colors-text-accent-primary-pressed: var( + --color-accent-stronger + ) !important; + --tempo-colors-text-accent-secondary-default: var( + --color-accent-weak + ) !important; + --tempo-colors-text-color-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-feedback-error-default: var( + --color-feedback-error + ) !important; + --tempo-colors-text-feedback-error-disabled: var( + --color-feedback-error-disabled + ) !important; + --tempo-colors-text-feedback-error-hovered: var( + --color-feedback-error-hovered + ) !important; + --tempo-colors-text-feedback-error-pressed: var( + --color-feedback-error-pressed + ) !important; + --tempo-colors-text-feedback-success-default: var( + --color-feedback-success + ) !important; + --tempo-colors-text-feedback-success-disabled: var( + --color-feedback-success-disabled + ) !important; + --tempo-colors-text-feedback-success-hovered: var( + --color-feedback-success-hovered + ) !important; + --tempo-colors-text-feedback-success-pressed: var( + --color-feedback-success-pressed + ) !important; + --tempo-colors-text-feedback-warning-default: var( + --color-feedback-warning + ) !important; + --tempo-colors-text-feedback-warning-disabled: var( + --color-feedback-warning-disabled + ) !important; + --tempo-colors-text-feedback-warning-hovered: var( + --color-feedback-warning-hovered + ) !important; + --tempo-colors-text-feedback-warning-pressed: var( + --color-feedback-warning-pressed + ) !important; + --tempo-colors-gray-200: var(--color-grey-200) !important; +} + +/* ========================================================================= + * Light mode (Apple systemGray6 canvas, white glass panels) + * ========================================================================= */ +:root, +[data-theme="light"] { + /* Backgrounds */ + --color-bg-main: #f2f2f7; + --color-bg-secondary: #ffffff; + --color-bg-tertiary: #e9e9ee; + --color-bg-tertiary-hover: #dedee4; + --color-bg-tertiary-pressed: #d1d1d6; + --color-bg-contrast: #e5e5ea; + --color-bg-inverse: #1c1c1e; + /* The "glass" material itself — white at ~72% opacity, blurred in + * section 5 below. Consumed as a flat fill anywhere blur can't apply. */ + --transparent-bg: rgba(255, 255, 255, 0.72); + + /* Text */ + --color-text-main: #1c1c1e; + --color-text-secondary: #6e6e73; /* Apple secondaryLabel */ + --color-text-disabled: #aeaeb2; + --color-text-inverse: #fff; + + /* Borders & dividers — soft hairlines, not heavy Deezer greys */ + --color-border-neutral-primary: #d8d8dd; + --color-border-neutral-secondary: #c7c7cc; + --color-divider-main: #d8d8dd; + + /* Neutral aliases */ + --color-neutral-main: #c7c7cc; + --color-neutral-strong: #6e6e73; + --color-neutral-weak: #e5e5ea; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-dark-grey-700 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-dark-grey-800 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + /* The "-hovered" tempo tokens (unlike -default/-disabled/-pressed/ + * -selected) drive hover washes across dozens of unrelated surfaces — + * track-list rows, popover/dropdown menu items, the context menu, the + * notification list, sidebar-adjacent poppers (grep-confirmed live in + * the compiled CSS: .jHMC1 track rows, .popper-account/.popper-search/ + * .popper-notifications items, .page-contextmenu .menu-item, + * .dropdown-item). Left pointing at the opaque --color-bg-tertiary + * ramp, every one of those reads as a flat grey slab dropped on top of + * the glass — most visibly the track-row hover, which is otherwise + * unstyled by this theme. Point them at the same translucent wash + * --lg-hover uses for sidebar rows/cards instead, so hovering + * anything gets a soft frosted tint rather than a hard grey box. */ + --tempo-colors-background-neutral-primary-hovered: rgba( + 120, + 130, + 150, + 0.12 + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: rgba( + 120, + 130, + 150, + 0.12 + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: rgba( + 120, + 130, + 150, + 0.12 + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * Dark mode (near-black canvas, dark glass panels) + * ========================================================================= */ +[data-theme="dark"] { + /* Backgrounds */ + --color-bg-main: #1c1c1e; + --color-bg-secondary: #242426; + --color-bg-tertiary: #2c2c2e; + --color-bg-tertiary-hover: #3a3a3c; + --color-bg-tertiary-pressed: #48484a; + --color-bg-contrast: #2c2c2e; + --color-bg-inverse: #f2f2f7; + --transparent-bg: rgba(28, 28, 30, 0.72); + + /* Text */ + --color-text-main: #f5f5f7; + --color-text-secondary: #aeaeb2; /* Apple secondaryLabel, dark */ + --color-text-disabled: #636366; + --color-text-inverse: #1c1c1e; + + /* Borders & dividers */ + --color-border-neutral-primary: #3a3a3c; + --color-border-neutral-secondary: #48484a; + --color-divider-main: #3a3a3c; + + /* Neutral aliases */ + --color-neutral-main: #48484a; + --color-neutral-strong: #aeaeb2; + --color-neutral-weak: #2c2c2e; + + /* Brand accents retinted toward the iOS blue/cyan glass palette */ + --color-bg-brand-duo: #5ac8fa; + --color-bg-brand-trio: #5ac8fa; + --color-bg-brand-duo-selected: #16324a; + --color-bg-brand-family-selected: #3a2416; + --color-bg-brand-premium-selected: #241a3a; + --color-text-brand-duo: #1c1c1e; + --color-text-brand-trio: #1c1c1e; + + --tempo-colors-background-neutral-inverse-default: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-disabled: var( + --color-bg-inverse + ) !important; + --tempo-colors-background-neutral-inverse-hovered: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-pressed: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-inverse-selected: var( + --color-light-grey-300 + ) !important; + --tempo-colors-background-neutral-primary-default: var( + --color-bg-main + ) !important; + --tempo-colors-background-neutral-primary-disabled: var( + --color-bg-secondary + ) !important; + /* Dark-mode counterpart of the light-block override above — same + * reasoning (track-row hover, popovers, context menu, notifications all + * read this token), swapped for the dark-mode --lg-hover wash so hover + * states stay a light frosted lift rather than the app's flat grey. */ + --tempo-colors-background-neutral-primary-hovered: rgba( + 255, + 255, + 255, + 0.08 + ) !important; + --tempo-colors-background-neutral-primary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-primary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-default: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-disabled: var( + --color-bg-secondary + ) !important; + --tempo-colors-background-neutral-secondary-hovered: rgba( + 255, + 255, + 255, + 0.08 + ) !important; + --tempo-colors-background-neutral-secondary-pressed: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-secondary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-background-neutral-tertiary-default: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-disabled: var( + --color-bg-tertiary + ) !important; + --tempo-colors-background-neutral-tertiary-hovered: rgba( + 255, + 255, + 255, + 0.08 + ) !important; + --tempo-colors-background-neutral-tertiary-pressed: var( + --color-bg-tertiary-pressed + ) !important; + --tempo-colors-background-neutral-tertiary-selected: var( + --color-bg-tertiary-hover + ) !important; + --tempo-colors-border-neutral-primary-default: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-border-neutral-primary-focused: var( + --color-accent-main + ) !important; + --tempo-colors-border-neutral-primary-hovered: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-border-neutral-primary-pressed: var( + --color-border-neutral-secondary + ) !important; + --tempo-colors-divider-neutral-primary-default: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-disabled: var( + --color-border-neutral-primary + ) !important; + --tempo-colors-divider-neutral-primary-hovered: var( + --color-divider-main + ) !important; + --tempo-colors-divider-neutral-primary-pressed: var( + --color-divider-main + ) !important; + --tempo-colors-icon-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-icon-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-icon-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-secondary-selected: var( + --color-text-secondary + ) !important; + --tempo-colors-icon-neutral-tertiary-default: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-hovered: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-pressed: var( + --color-text-disabled + ) !important; + --tempo-colors-icon-neutral-tertiary-selected: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-inverse-default: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-disabled: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-hovered: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-pressed: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-inverse-selected: var( + --color-text-inverse + ) !important; + --tempo-colors-text-neutral-primary-default: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-primary-hovered: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-pressed: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-primary-selected: var( + --color-text-main + ) !important; + --tempo-colors-text-neutral-secondary-default: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-disabled: var( + --color-text-disabled + ) !important; + --tempo-colors-text-neutral-secondary-hovered: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-pressed: var( + --color-text-secondary + ) !important; + --tempo-colors-text-neutral-secondary-selected: var( + --color-text-secondary + ) !important; +} + +/* ========================================================================= + * 5. ARBITRARY CSS — the Liquid Glass material + * ========================================================================= + * Sections 1-4 only recolor Deezer. The iOS 26 "Liquid Glass" look is a + * *structural* language, so this section rebuilds the shell as discrete + * floating islands: + * + * - every major surface (sidebar, top bar, player, content sections) + * becomes a rounded card inset from its neighbours by --lg-gap + * - each card gets a layered shadow (tight contact + wide ambient) + * instead of Deezer's single flat edge + * - each card gets a specular rim: a bright 1px inset highlight along + * the top edge, the way light catches the lip of real glass + * - chrome that *overlaps* content (sidebar, top bar, player, popovers, + * modals) gets a real backdrop-filter; content sections deliberately + * do NOT, since only the flat page background sits behind them — + * refracting nothing is both physically wrong and 25x the GPU cost + * + * Layout geometry, all confirmed live over CDP against the running app: + * sidebar position:fixed top:0 left:0 243x100% z-index 2 + * #page_topbar position:fixed top:0 left:243 1189 wide z-index 200 + * #page_player > div position:fixed bottom:0 left:0 100%x80 z-index 300 + * #page_content.page-main margin-left:243px (static flow) + * [data-testid=section-renderer] > * padding:0 40px; margin:24px 0 + * + * CAUTION — the containing-block trap: backdrop-filter (like transform and + * filter) makes an element a containing block for position:fixed + * descendants. #page_player is NOT itself fixed, its child div is, so the + * blur goes on `#page_player > div`. Putting it on #page_player throws the + * player ~8000px down the page. The sidebar and #page_topbar ARE + * themselves the fixed elements, so blurring them directly is safe. + * ========================================================================= */ + +:root { + /* Island geometry */ + --lg-gap: 14px; + --lg-radius: 22px; + --lg-radius-sm: 16px; + /* Fallback only — the live value is redeclared on .naboo below. Custom + * properties resolve var() once, at the element that specifies them, and + * then inherit that already-resolved value downward. Declaring these on + * :root would freeze them at :root's own (unset) --layout-sidebar-width + * forever, so the sidebar-collapse toggle — which sets + * --layout-sidebar-width inline on .naboo, 243px expanded / 80px + * collapsed — would never be reflected here. */ + --lg-sidebar-w: 243px; + --lg-player-h: 80px; /* app's own fixed player height */ + /* Left edge of the content column: clears the sidebar island plus a gap */ + --lg-content-x: calc(var(--lg-sidebar-w) + var(--lg-gap) * 2); + + /* Glass material — light mode */ + --lg-fill: rgba(255, 255, 255, 0.55); + --lg-fill-solid: rgba(255, 255, 255, 0.46); + --lg-blur: blur(30px) saturate(180%); + --lg-rim: rgba(255, 255, 255, 0.75); + --lg-edge: rgba(255, 255, 255, 0.5); + + /* Recessed well (search field): a faint darkening carved into the glass, + * replacing the app's opaque grey input fill. */ + --lg-well: rgba(120, 130, 150, 0.12); + --lg-well-focus: rgba(120, 130, 150, 0.06); + /* Selected/active affordance: a translucent accent wash instead of the + * app's flat grey selection box — the iOS way of showing "current". */ + --lg-selected: rgba(10, 132, 255, 0.16); + --lg-selected-hover: rgba(10, 132, 255, 0.22); + --lg-hover: rgba(120, 130, 150, 0.12); + /* Card frame tint on hover — a light frosted lift, not the app's grey */ + --lg-card-hover: rgba(255, 255, 255, 0.55); + + /* Layered depth: contact shadow + mid lift + wide ambient */ + --lg-shadow: + 0 1px 2px rgba(16, 24, 40, 0.06), 0 8px 20px -6px rgba(16, 24, 40, 0.12), + 0 24px 48px -16px rgba(16, 24, 40, 0.14); + --lg-shadow-lifted: + 0 2px 4px rgba(16, 24, 40, 0.08), 0 16px 32px -8px rgba(16, 24, 40, 0.18), + 0 40px 64px -20px rgba(16, 24, 40, 0.2); +} + +/* Re-resolve --lg-sidebar-w (and --lg-content-x, which depends on it) + * directly on .naboo — the element the app's collapse toggle sets + * --layout-sidebar-width on (243px expanded / 80px collapsed). Declaring + * it here, not at :root, makes the substitution happen using .naboo's own + * live value instead of freezing it at :root's unset fallback. Sidebar, + * top bar and content are all descendants of .naboo (confirmed live over + * CDP), so they inherit the correctly re-resolved value. */ +.naboo { + --lg-sidebar-w: var(--layout-sidebar-width, 243px); + --lg-content-x: calc(var(--lg-sidebar-w) + var(--lg-gap) * 2); +} + +[data-theme="dark"] { + /* Glass material — dark mode. Dark glass reads as a *lighter* film over + * a dark ground, so the fill is a white wash, not a black one. */ + --lg-fill: rgba(40, 40, 44, 0.68); + --lg-fill-solid: rgba(255, 255, 255, 0.055); + --lg-rim: rgba(255, 255, 255, 0.14); + --lg-edge: rgba(255, 255, 255, 0.09); + + --lg-shadow: + 0 1px 2px rgba(0, 0, 0, 0.4), 0 8px 20px -6px rgba(0, 0, 0, 0.5), + 0 24px 48px -16px rgba(0, 0, 0, 0.55); + --lg-shadow-lifted: + 0 2px 4px rgba(0, 0, 0, 0.5), 0 16px 32px -8px rgba(0, 0, 0, 0.6), + 0 40px 64px -20px rgba(0, 0, 0, 0.65); + + --lg-well: rgba(0, 0, 0, 0.28); + --lg-well-focus: rgba(0, 0, 0, 0.18); + --lg-selected: rgba(10, 132, 255, 0.28); + --lg-selected-hover: rgba(10, 132, 255, 0.36); + --lg-hover: rgba(255, 255, 255, 0.08); + --lg-card-hover: rgba(255, 255, 255, 0.1); +} + +/* ------------------------------------------------------------------------- + * Ambient ground + * ------------------------------------------------------------------------- + * Glass needs something behind it or the blur is a no-op. Deezer's page + * background is a flat token fill, so lay a soft wallpaper-ish bloom under + * everything — fixed, pointer-events:none, z-index 0, so it never touches + * layout or hit-testing. + * + * NOTE: only background/pseudo-elements go on .naboo. Never filter, + * transform or backdrop-filter here — .naboo is the ancestor of every + * fixed element in the shell (see the containing-block caution above). + * ---------------------------------------------------------------------- */ +.naboo { + position: relative; +} +/* The ground lives entirely on this fixed, viewport-filling layer — the + * four colour blooms AND the opaque base gradient (last, bottom-most). It + * must NOT sit on .naboo's own box background: during a route change the + * content collapses to a spinner, .naboo shrinks below the viewport, and a + * box background would leave the body colour (a flat dark/near-white) + * showing under it. position:fixed keeps this painting the whole viewport + * regardless of .naboo's height. z-index:0 + pointer-events:none keep it + * behind and inert; the sidebar (z-index 2) and content (later in DOM) + * both paint above it. */ +.naboo::before { + content: ""; + position: fixed; + inset: 0; + z-index: 0; + pointer-events: none; + background: + radial-gradient( + ellipse 70% 55% at 10% 6%, + rgba(10, 132, 255, 0.13), + transparent 62% + ), + radial-gradient( + ellipse 62% 52% at 90% 10%, + rgba(90, 200, 250, 0.12), + transparent 64% + ), + radial-gradient( + ellipse 85% 62% at 72% 94%, + rgba(175, 82, 222, 0.09), + transparent 66% + ), + radial-gradient( + ellipse 58% 48% at 22% 88%, + rgba(48, 209, 176, 0.07), + transparent 62% + ), + linear-gradient(155deg, #dde7f3 0%, #e9eff7 38%, #dfe8f4 100%); +} +[data-theme="dark"] .naboo::before { + background: + radial-gradient( + ellipse 70% 55% at 10% 6%, + rgba(10, 132, 255, 0.28), + transparent 62% + ), + radial-gradient( + ellipse 62% 52% at 90% 10%, + rgba(90, 200, 250, 0.16), + transparent 64% + ), + radial-gradient( + ellipse 85% 62% at 72% 94%, + rgba(175, 82, 222, 0.26), + transparent 66% + ), + radial-gradient( + ellipse 58% 48% at 22% 88%, + rgba(48, 209, 176, 0.14), + transparent 62% + ), + linear-gradient(155deg, #10141c 0%, #161b26 42%, #0e1219 100%); +} + +/* ------------------------------------------------------------------------- + * Sidebar island + * ------------------------------------------------------------------------- + * The app pins it at top:0 left:0, full height, solid white. Inset it on + * all four sides so it floats, stopping clear of the player island. It + * keeps its full 243px width (the nav rows reflow but get cramped if it + * shrinks); the content column is pushed right instead, below. + * + * The app's own box reserves an extra 80px of padding-bottom on top of its + * top:0/bottom:80px inset (so the last nav row clears the docked player in + * the *undecorated* layout). Our island already stops clear of the player + * via the gap math below, so that padding is pure dead air here — visible + * as a blank strip inside the glass card, confirmed live over CDP + * (paddingBottom: 80px on this exact box). Zero it out. */ +.naboo > div:not([id]):has(a) > div { + top: var(--lg-gap) !important; + left: var(--lg-gap) !important; + height: calc(100% - var(--lg-player-h) - var(--lg-gap) * 3) !important; + width: var(--lg-sidebar-w) !important; + padding-bottom: 8px !important; + + background: var(--lg-fill) !important; + -webkit-backdrop-filter: var(--lg-blur); + backdrop-filter: var(--lg-blur); + border-radius: var(--lg-radius) !important; + box-shadow: + inset 0 1px 0 var(--lg-rim), + inset 0 0 0 1px var(--lg-edge), + var(--lg-shadow); + overflow: hidden !important; +} + +/* ------------------------------------------------------------------------- + * Top bar island + * ------------------------------------------------------------------------- + * Pinned at left:243px with an explicit width:1189px — swap to a + * left/right pair so it tracks the window and lines up with the content + * sections. --lg-content-x clears the sidebar island: sidebar occupies + * gap..(gap + 243), so content starts one more gap past that. + * ---------------------------------------------------------------------- */ +#page_topbar, +.page-topbar { + top: var(--lg-gap) !important; + left: var(--lg-content-x) !important; + right: var(--lg-gap) !important; + width: auto !important; + + background: var(--lg-fill) !important; + -webkit-backdrop-filter: var(--lg-blur); + backdrop-filter: var(--lg-blur); + border-radius: var(--lg-radius) !important; + border-bottom: none !important; + box-shadow: + inset 0 1px 0 var(--lg-rim), + inset 0 0 0 1px var(--lg-edge), + var(--lg-shadow) !important; +} + +/* Search field inside the top bar: a recessed glass slot, not a raised one. + * The app ships the input itself as an opaque grey fill (#e9e9ee), which + * reads as a hard grey box sitting ON the glass topbar. Replace it with a + * translucent well — a faint darkening plus an inset shadow so it looks + * carved INTO the glass — and give it an accent focus ring. The outer + * .topbar-search-form keeps the pill radius so the well matches its frame. */ +.topbar-search-form { + border-radius: 999px !important; +} +.topbar-search .chakra-input { + background: var(--lg-well) !important; + border-radius: 999px !important; + box-shadow: + inset 0 1px 2px rgba(16, 24, 40, 0.08), + inset 0 0 0 1px var(--lg-edge) !important; + transition: + box-shadow 0.2s ease, + background-color 0.2s ease; +} +.topbar-search .chakra-input:focus, +.topbar-search .chakra-input:focus-visible { + background: var(--lg-well-focus) !important; + box-shadow: + inset 0 1px 2px rgba(16, 24, 40, 0.06), + 0 0 0 2px rgba(10, 132, 255, 0.55) !important; +} + +/* Same recessed-well treatment for the small per-tab filter search boxes in + * the Library ("Coups de cœur", "Playlists", "Albums", "Artistes", ...) — + * they ship as the same opaque grey #e9e9ee input, just a different Chakra + * size variant, so they weren't caught by the .topbar-search scope above. + * Scoped to #page_content (vs the topbar's own fixed island) and to inputs + * that carry a placeholder, which is how these filter fields are built + * across every tab — confirmed live over CDP: "Rechercher parmi les + * titres" / "une playlist" / "un album" / "un artiste" all match, nothing + * else in #page_content does. */ +#page_content input.chakra-input[placeholder] { + background: var(--lg-well) !important; + border-radius: 999px !important; + box-shadow: + inset 0 1px 2px rgba(16, 24, 40, 0.08), + inset 0 0 0 1px var(--lg-edge) !important; + transition: + box-shadow 0.2s ease, + background-color 0.2s ease; +} +#page_content input.chakra-input[placeholder]:focus, +#page_content input.chakra-input[placeholder]:focus-visible { + background: var(--lg-well-focus) !important; + box-shadow: + inset 0 1px 2px rgba(16, 24, 40, 0.06), + 0 0 0 2px rgba(10, 132, 255, 0.55) !important; +} + +/* ------------------------------------------------------------------------- + * Player island + * ------------------------------------------------------------------------- + * `#page_player > div` is the fixed element (see caution above). Detach it + * from all three window edges so it reads as a floating capsule rather + * than a docked bar, and round every corner instead of just the top two. + * ---------------------------------------------------------------------- */ +#page_player > div { + left: var(--lg-gap) !important; + right: var(--lg-gap) !important; + bottom: var(--lg-gap) !important; + width: auto !important; + + background: var(--lg-fill) !important; + -webkit-backdrop-filter: var(--lg-blur); + backdrop-filter: var(--lg-blur); + border-radius: var(--lg-radius) !important; + border-top: none !important; + box-shadow: + inset 0 1px 0 var(--lg-rim), + inset 0 0 0 1px var(--lg-edge), + var(--lg-shadow-lifted) !important; +} + +/* Transport controls: circular glass keys with a hover bloom */ +#page_player button { + border-radius: 999px !important; + transition: + background-color 0.2s ease, + box-shadow 0.2s ease, + transform 0.15s ease; +} +#page_player button:hover { + background-color: var(--lg-fill-solid) !important; + box-shadow: 0 0 0 1px var(--lg-edge); +} +#page_player button:active { + transform: scale(0.94); +} + +/* ------------------------------------------------------------------------- + * Content section islands + * ------------------------------------------------------------------------- + * Each home/browse section becomes its own card. The inner wrapper already + * ships `padding: 0 40px; margin: 24px 0` — reuse that padding as the + * island's interior and move the vertical rhythm out to the card itself, + * otherwise the margin punches gaps *inside* the glass. + * + * No backdrop-filter here on purpose: only the flat page background sits + * behind these, so a translucent fill is both truer and far cheaper than + * 25 stacked blur layers. + * ---------------------------------------------------------------------- */ +[data-testid="section-renderer"], +.channel-section { + margin: 0 var(--lg-gap) var(--lg-gap) 0 !important; + background: var(--lg-fill-solid); + border-radius: var(--lg-radius) !important; + box-shadow: + inset 0 1px 0 var(--lg-rim), + inset 0 0 0 1px var(--lg-edge), + var(--lg-shadow); +} +[data-testid="section-renderer"] > *, +.channel-section > * { + margin-top: 0 !important; + margin-bottom: 0 !important; + padding-top: 20px !important; + padding-bottom: 20px !important; +} + +/* Re-seat the content column around the floating chrome. The app's own + * layout assumes flush-docked bars: margin-left:243px for a flush-left + * sidebar, and a content top of exactly the 80px topbar height. Both + * assumptions break once those bars are inset, so: + * + * left — clear the sidebar island (--lg-content-x) + * top — the topbar now ends at (gap + 80px) rather than 80px, so add + * gap*2: one for its top inset, one for the gap beneath it. + * Without this the first card sits 14px UNDER the topbar + * (measured live: card top 80, topbar bottom 94). + * bottom — clear the floating player so the last card scrolls fully in + * + * The bars stay position:fixed, so content still slides *under* them as + * you scroll — which is the point of giving them a backdrop-filter. This + * only stops the first card being born clipped. */ +#page_content.page-main { + margin-left: var(--lg-content-x) !important; + padding-top: calc(var(--lg-gap) * 2) !important; + padding-bottom: calc(var(--lg-player-h) + var(--lg-gap) * 2) !important; +} + +/* ------------------------------------------------------------------------- + * Popovers, menus and modals + * ------------------------------------------------------------------------- + * These float above everything and genuinely have content behind them, so + * they get the full blur treatment. .chakra-popover__content backs the + * account menu, search popper and context menus alike (confirmed live: + * account-popover-content / popover-content / context-menu-content all + * resolve to it). + * ---------------------------------------------------------------------- */ +.chakra-popover__content, +.dropdown-menu, +.modal-dialog { + background: var(--lg-fill) !important; + -webkit-backdrop-filter: var(--lg-blur); + backdrop-filter: var(--lg-blur); + border: none !important; + border-radius: var(--lg-radius-sm) !important; + box-shadow: + inset 0 1px 0 var(--lg-rim), + inset 0 0 0 1px var(--lg-edge), + var(--lg-shadow-lifted) !important; +} +.modal-dialog { + border-radius: var(--lg-radius) !important; +} +.modal-header-partner, +.modal-family-upsale-header { + border-radius: var(--lg-radius) var(--lg-radius) 0 0 !important; +} +.modal-footer { + border-radius: 0 0 var(--lg-radius) var(--lg-radius) !important; +} +/* Dim the page behind a modal so the glass has contrast to sit against */ +.modal-backdrop { + -webkit-backdrop-filter: blur(4px); + backdrop-filter: blur(4px); +} + +/* ------------------------------------------------------------------------- + * Cover art + * ------------------------------------------------------------------------- + * Rounded like iOS app icons, with a hairline edge and a lift on hover. + * Three selector families, all confirmed live: the legacy list-row classes + * (still real, just not rendered on every route); the horizontal-row + * covers home/browse use (`*_thumbnail`); and the Library's grid/list + * cells, which use a DIFFERENT testid shape — `thumbnail--li` + * (thumbnail-album-li / -playlist-li / -artist-li). The attribute + * selector `[data-testid^="thumbnail-"][data-testid$="-li"]` catches that + * whole family while excluding thumbnail-title (text) and thumbnail-grid + * (the row container) — confirmed live: 39 real cells, 0 false matches. */ +.thumbnail, +.playlist-cover-solo, +.playlist-cover, +.cell-thumbnail, +.block_cover, +[data-testid="playlist_thumbnail"], +[data-testid="artist_thumbnail"], +[data-testid="album_thumbnail"], +[data-testid="channel_thumbnail"], +[data-testid="channel_cover"], +[data-testid="show_thumbnail"], +[data-testid="smarttracklist_thumbnail"], +[data-testid="livestream_thumbnail"], +[data-testid^="thumbnail-"][data-testid$="-li"], +[data-testid="item_cover"] { + border-radius: var(--lg-radius-sm); + transition: + transform 0.28s cubic-bezier(0.32, 0.72, 0, 1), + box-shadow 0.28s cubic-bezier(0.32, 0.72, 0, 1); +} +.thumbnail:hover, +.playlist-cover-solo:hover, +.playlist-cover:hover, +.cell-thumbnail:hover, +.block_cover:hover, +[data-testid="playlist_thumbnail"]:hover, +[data-testid="artist_thumbnail"]:hover, +[data-testid="album_thumbnail"]:hover, +[data-testid="channel_thumbnail"]:hover, +[data-testid="channel_cover"]:hover, +[data-testid="show_thumbnail"]:hover, +[data-testid="smarttracklist_thumbnail"]:hover, +[data-testid="livestream_thumbnail"]:hover, +[data-testid^="thumbnail-"][data-testid$="-li"]:hover { + /* The app paints the card frame a flat opaque grey on hover (its + * neutral-hover token), which reads as a dull grey slab under the glass + * language. Override it with a light frosted-glass tint so the whole + * card looks like it catches light as it lifts. */ + background: var(--lg-card-hover) !important; + transform: translateY(-4px) scale(1.015); + box-shadow: var(--lg-shadow-lifted); +} + +/* Give horizontal card rows vertical breathing room so the lifted hover + * shadow isn't sheared off. Each row is `overflow-x: scroll`, which per + * spec also clips overflow-Y — so a card's shadow (and its -4px lift) get + * cut at the row's top/bottom edge. Padding opens room for the shadow + * INSIDE the clip region; the equal negative margin cancels the layout + * shift, and overflow-Y stays non-scrolling because the cards still fit. + * + * Selector, deliberately GLOBAL rather than scoped to one page's wrapper: + * every card row across the app (home's "section-renderer" sections, the + * Library's "naboo-catalog" sections, search results, etc.) has the same + * shape — a scroll row > inner wrapper > card cells — so the row is "a div + * whose GRANDCHILD is a card cell". Scoped to #page_content so it can + * never hit the player's own now-playing cover (which is an item_cover, + * excluded here anyway) or the sidebar. Confirmed live on both the home + * and Library layouts: matches every clipping scroll row, zero false + * positives. Two cell-testid shapes are covered: home's `*_thumbnail` + * and the Library grid's `thumbnail--li`. + * + * The padding is ASYMMETRIC because the lifted shadow is. Its widest layer + * is `0 40px 64px -20px`, so it reaches 40 + 64/2 - 20 = 52px BELOW the + * card and nothing above it (the -4px hover lift is all the headroom the + * top needs). 56px of bottom padding clears the full falloff — 20px cut it + * mid-gradient and left a hard horizontal seam under hovered cards. The top + * stays small on purpose: the padding box is a scroll container and sits + * over whatever it overlaps, so a large top inset would swallow clicks on + * the section title/"Voir tout" above it. Hit-tested live at these values — + * every section title, "Voir tout" and carousel arrow still resolves to + * itself under elementFromPoint. */ +#page_content div:has(> div > [data-testid$="_thumbnail"]), +#page_content div:has(> div > [data-testid^="thumbnail-"][data-testid$="-li"]) { + padding-top: 24px !important; + padding-bottom: 56px !important; + margin-top: -24px !important; + margin-bottom: -56px !important; +} + +/* Genre/category cards ("Tes genres favoris", Explorer > Catégories) sit one + * level shallower: the grid cell wrapping each `channel_thumbnail` card is + * `overflow:hidden` with only an 8px margin (the app's own spacing token), + * so the lifted hover shadow gets hard-clipped a few pixels out instead of + * fading — a visible sharp-edged cutoff instead of the soft falloff every + * other card gets. There's nothing this wrapper needs to clip (the card's + * rounded shape comes from the cover image's own SVG mask, not this box), + * so just let it paint outside its box. Confirmed live over CDP: hover + * shadow now falls off softly on all four sides instead of stopping dead + * at the wrapper edge. */ +#page_content div:has(> [data-testid="channel_thumbnail"]) { + overflow: visible !important; +} + +/* ------------------------------------------------------------------------- + * Controls + * ---------------------------------------------------------------------- */ + +/* Sidebar internals. + * The nav block and the two sticky group headers ("Raccourcis", + * "Playlists") ship an opaque white fill, which would tile a solid slab + * over the glass. Blank the block fills entirely; the sticky headers keep + * a fill — they have to mask rows scrolling underneath — but as blurred + * glass rather than a hard white bar, the way iOS section headers read. */ +.naboo > div:not([id]):has(a) > div > div { + background: transparent !important; +} +.naboo > div:not([id]):has(a) > div > div:nth-child(2) > div > div:first-child { + background: var(--lg-fill) !important; + -webkit-backdrop-filter: blur(12px) saturate(180%); + backdrop-filter: blur(12px) saturate(180%); +} + +/* Sidebar nav rows: pill-shaped, with a glass wash on hover. + * All rows get the rounded shape + hover wash. */ +.naboo > div:not([id]):has(a) > div a { + border-radius: var(--lg-radius-sm) !important; + transition: background-color 0.2s ease; +} +.naboo > div:not([id]):has(a) > div a:hover { + background: var(--lg-hover) !important; +} + +/* Selected primary-nav row. + * The app marks the current page by painting that row an opaque grey + * (#e9e9ee) — a hard grey box on the glass. There's no stable class or + * aria-current to hook, but the active row is the only one whose icon is + * the *Filled* variant (HouseFilledIcon vs the Outlined icons on the + * rest), so :has([data-testid$="FilledIcon"]) selects it robustly. + * Scope to the first sidebar block (the primary nav) so it doesn't also + * fire on pinned shortcuts further down, whose heart/pin icons are also + * "Filled". Swap the grey for a translucent accent wash — the iOS way of + * showing "current" — with a matching hover. */ +.naboo + > div:not([id]):has(a) + > div + > div:first-child + a:has([data-testid$="FilledIcon"]) { + background: var(--lg-selected) !important; +} +.naboo + > div:not([id]):has(a) + > div + > div:first-child + a:has([data-testid$="FilledIcon"]):hover { + background: var(--lg-selected-hover) !important; +} + +/* Thinner scrollbars inside the sidebar island — the default 10px thumb + * reads as a hard rule against the rounded glass edge */ +.naboo > div:not([id]):has(a) > div ::-webkit-scrollbar { + width: 6px; +} + +/* Primary buttons keep their accent fill but pick up a capsule shape */ +.navbar-button { + border-radius: 999px !important; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.28), + 0 2px 8px -2px rgba(10, 132, 255, 0.45); + transition: + box-shadow 0.2s ease, + transform 0.15s ease; +} +.navbar-button:hover { + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.28), + 0 4px 16px -2px rgba(10, 132, 255, 0.6); +} +.navbar-button:active { + transform: scale(0.97); +} + +/* Sliders: capsule tracks, lit accent fill */ +.slider-track, +.slider-track-default, +.slider-track-active, +.nano-slider { + border-radius: 999px !important; +} +.slider-track-active { + box-shadow: 0 0 8px 0 rgba(10, 132, 255, 0.5); +} + +/* Scrollbars: floating capsule thumbs, no track furniture */ +::-webkit-scrollbar { + width: 10px; + height: 10px; +} +::-webkit-scrollbar-track { + background: transparent !important; +} +::-webkit-scrollbar-thumb { + background: var(--color-neutral-main) !important; + border: 3px solid transparent !important; + background-clip: padding-box !important; + border-radius: 999px !important; +} +::-webkit-scrollbar-thumb:hover { + background: var(--color-neutral-strong) !important; + background-clip: padding-box !important; +} From a7cd8f4429118ad94d6bf31912a2d026e1034e0b Mon Sep 17 00:00:00 2001 From: josselinonduty Date: Mon, 24 Aug 2026 23:45:13 +0200 Subject: [PATCH 10/10] docs(theme): clean useless or dead comments --- themes/everforest.css | 109 ++++++++++++-------------- themes/gruvbox.css | 97 +++++++++++------------ themes/liquid-glass.css | 33 +++----- themes/matrix.css | 12 +-- themes/monokai.css | 21 ++--- themes/nord.css | 83 +++++++++----------- themes/primer.css | 165 +++++++++++++++++++--------------------- themes/solarized.css | 75 ++++++++---------- themes/synthwave.css | 48 +++++------- 9 files changed, 280 insertions(+), 363 deletions(-) diff --git a/themes/everforest.css b/themes/everforest.css index 2118e7f..b13a01d 100644 --- a/themes/everforest.css +++ b/themes/everforest.css @@ -33,9 +33,9 @@ * background. */ --color-accent-main: #35a77c; --color-accent-strong: #278a65; - --color-accent-weak: #83c092; /* dark-palette aqua */ + --color-accent-weak: #83c092; --color-accent-light: #a8d4b7; - --color-accent-stronger: #1d6b4d; /* deeper "pressed" tier */ + --color-accent-stronger: #1d6b4d; /* Feedback (error / success / warning) — one default/disabled/hovered/ * pressed variable per type, unlike template.css's single flat color. @@ -54,37 +54,36 @@ --color-feedback-warning-hovered: #b98400; --color-feedback-warning-pressed: #936900; - /* Neutral ramp mapped onto Everforest bg/grey tones (light -> dark) */ - --color-grey-50: #fdf6e3; /* light bg0 */ - --color-grey-100: #f4f0d9; /* light bg1 */ - --color-grey-200: #e6e2cc; /* light bg3 */ - --color-grey-300: #bdc3af; /* light bg5 */ - --color-grey-400: #939f91; /* light grey1 */ - --color-grey-500: #829181; /* light grey2 */ - --color-grey-600: #475258; /* dark bg3 */ - --color-grey-700: #3d484d; /* dark bg2 */ - --color-grey-800: #343f44; /* dark bg1 */ - --color-grey-900: #2d353b; /* dark bg0 */ + --color-grey-50: #fdf6e3; + --color-grey-100: #f4f0d9; + --color-grey-200: #e6e2cc; + --color-grey-300: #bdc3af; + --color-grey-400: #939f91; + --color-grey-500: #829181; + --color-grey-600: #475258; + --color-grey-700: #3d484d; + --color-grey-800: #343f44; + --color-grey-900: #2d353b; /* Fixed dark/light grey ramps — do NOT swap with the mode */ - --color-dark-grey-200: #56635f; /* dark bg5 */ - --color-dark-grey-300: #4f585e; /* dark bg4 */ - --color-dark-grey-400: #475258; /* dark bg3 */ - --color-dark-grey-500: #3d484d; /* dark bg2 */ - --color-dark-grey-600: #343f44; /* dark bg1 */ - --color-dark-grey-700: #2d353b; /* dark bg0 */ + --color-dark-grey-200: #56635f; + --color-dark-grey-300: #4f585e; + --color-dark-grey-400: #475258; + --color-dark-grey-500: #3d484d; + --color-dark-grey-600: #343f44; + --color-dark-grey-700: #2d353b; --color-dark-grey-800: #262e33; - --color-dark-grey-900: #232a2e; /* dark bg_dim */ - --color-light-grey-50: #fdf6e3; /* light bg0 */ - --color-light-grey-100: #f8f5e4; /* light bg1 (hard) */ - --color-light-grey-200: #f4f0d9; /* light bg1 */ - --color-light-grey-300: #e6e2cc; /* light bg3 */ - --color-light-grey-400: #e0dcc7; /* light bg4 */ - --color-light-grey-500: #bdc3af; /* light bg5 */ - --color-light-grey-600: #a6b0a0; /* light grey0 */ - --color-light-grey-700: #939f91; /* light grey1 */ - --color-light-grey-800: #829181; /* light grey2 */ - --color-light-grey-900: #5c6a72; /* light fg */ + --color-dark-grey-900: #232a2e; + --color-light-grey-50: #fdf6e3; + --color-light-grey-100: #f8f5e4; /* hard-contrast bg1, not the medium default */ + --color-light-grey-200: #f4f0d9; + --color-light-grey-300: #e6e2cc; + --color-light-grey-400: #e0dcc7; + --color-light-grey-500: #bdc3af; + --color-light-grey-600: #a6b0a0; + --color-light-grey-700: #939f91; + --color-light-grey-800: #829181; + --color-light-grey-900: #5c6a72; } /* ========================================================================= @@ -513,28 +512,24 @@ * ========================================================================= */ :root, [data-theme="light"] { - /* Backgrounds */ - --color-bg-main: #fdf6e3; /* light bg0 */ - --color-bg-secondary: #f4f0d9; /* light bg1 */ - --color-bg-tertiary: #e6e2cc; /* light bg3 */ - --color-bg-tertiary-hover: #e0dcc7; /* light bg4 */ - --color-bg-tertiary-pressed: #bdc3af; /* light bg5 */ + --color-bg-main: #fdf6e3; + --color-bg-secondary: #f4f0d9; + --color-bg-tertiary: #e6e2cc; + --color-bg-tertiary-hover: #e0dcc7; + --color-bg-tertiary-pressed: #bdc3af; --color-bg-contrast: #e6e2cc; - --color-bg-inverse: #2d353b; /* dark bg0 */ + --color-bg-inverse: #2d353b; --transparent-bg: #fdf6e380; - /* Text */ - --color-text-main: #5c6a72; /* light fg (strong body) */ - --color-text-secondary: #829181; /* light grey2 */ - --color-text-disabled: #a6b0a0; /* light grey0 */ - --color-text-inverse: #d3c6aa; /* dark fg */ + --color-text-main: #5c6a72; + --color-text-secondary: #829181; + --color-text-disabled: #a6b0a0; + --color-text-inverse: #d3c6aa; - /* Borders & dividers */ --color-border-neutral-primary: #e0dcc7; --color-border-neutral-secondary: #bdc3af; --color-divider-main: #e0dcc7; - /* Neutral aliases */ --color-neutral-main: #bdc3af; --color-neutral-strong: #829181; --color-neutral-weak: #f4f0d9; @@ -737,34 +732,30 @@ * Everforest Dark (dark bg background, cream/tan fg text) * ========================================================================= */ [data-theme="dark"] { - /* Backgrounds */ - --color-bg-main: #2d353b; /* dark bg0 */ - --color-bg-secondary: #343f44; /* dark bg1 */ - --color-bg-tertiary: #3d484d; /* dark bg2 */ - --color-bg-tertiary-hover: #475258; /* dark bg3 */ - --color-bg-tertiary-pressed: #4f585e; /* dark bg4 */ + --color-bg-main: #2d353b; + --color-bg-secondary: #343f44; + --color-bg-tertiary: #3d484d; + --color-bg-tertiary-hover: #475258; + --color-bg-tertiary-pressed: #4f585e; --color-bg-contrast: #343f44; - --color-bg-inverse: #fdf6e3; /* light bg0 */ + --color-bg-inverse: #fdf6e3; --transparent-bg: #232a2e4d; - /* Text */ - --color-text-main: #d3c6aa; /* dark fg (bright body) */ - --color-text-secondary: #9da9a0; /* dark grey2 */ - --color-text-disabled: #7a8478; /* dark grey0 */ - --color-text-inverse: #2d353b; /* dark bg0 */ + --color-text-main: #d3c6aa; + --color-text-secondary: #9da9a0; + --color-text-disabled: #7a8478; + --color-text-inverse: #2d353b; - /* Borders & dividers */ --color-border-neutral-primary: #475258; --color-border-neutral-secondary: #56635f; --color-divider-main: #475258; - /* Neutral aliases */ --color-neutral-main: #475258; --color-neutral-strong: #9da9a0; --color-neutral-weak: #343f44; /* Brand accents retinted toward Everforest aqua */ - --color-bg-brand-duo: #83c092; /* dark aqua */ + --color-bg-brand-duo: #83c092; --color-bg-brand-trio: #83c092; --color-bg-brand-duo-selected: #3d484d; --color-text-brand-duo: #2d353b; diff --git a/themes/gruvbox.css b/themes/gruvbox.css index ba7a057..b3babd3 100644 --- a/themes/gruvbox.css +++ b/themes/gruvbox.css @@ -32,7 +32,7 @@ --color-accent-strong: #d65d0e; --color-accent-weak: #fe9d54; --color-accent-light: #ffc38a; - --color-accent-stronger: #af3a03; /* deeper "pressed" tier */ + --color-accent-stronger: #af3a03; /* Feedback (error / success / warning) — one default/disabled/hovered/ * pressed variable per type, unlike template.css's single flat color */ @@ -49,37 +49,36 @@ --color-feedback-warning-hovered: #b57614; --color-feedback-warning-pressed: #8f5c0f; - /* Neutral ramp mapped onto Gruvbox bg/fg tones (light -> dark) */ - --color-grey-50: #fbf1c7; /* fg0/bg0 light */ - --color-grey-100: #ebdbb2; /* fg1 */ - --color-grey-200: #d5c4a1; /* fg2 */ - --color-grey-300: #bdae93; /* fg3 */ - --color-grey-400: #a89984; /* fg4/gray */ - --color-grey-500: #7c6f64; /* bg4 */ - --color-grey-600: #665c54; /* bg3 */ - --color-grey-700: #504945; /* bg2 */ - --color-grey-800: #3c3836; /* bg1 */ - --color-grey-900: #282828; /* bg0 */ + --color-grey-50: #fbf1c7; + --color-grey-100: #ebdbb2; + --color-grey-200: #d5c4a1; + --color-grey-300: #bdae93; + --color-grey-400: #a89984; + --color-grey-500: #7c6f64; + --color-grey-600: #665c54; + --color-grey-700: #504945; + --color-grey-800: #3c3836; + --color-grey-900: #282828; /* Fixed dark/light grey ramps — do NOT swap with the mode */ - --color-dark-grey-200: #7c6f64; /* bg4 */ - --color-dark-grey-300: #665c54; /* bg3 */ + --color-dark-grey-200: #7c6f64; + --color-dark-grey-300: #665c54; --color-dark-grey-400: #584d43; - --color-dark-grey-500: #504945; /* bg2 */ - --color-dark-grey-600: #3c3836; /* bg1 */ - --color-dark-grey-700: #32302f; /* bg0_s */ - --color-dark-grey-800: #282828; /* bg0 */ - --color-dark-grey-900: #1d2021; /* bg0_h */ - --color-light-grey-50: #fbf1c7; /* bg0 light */ - --color-light-grey-100: #f2e5bc; /* bg0_s light */ - --color-light-grey-200: #ebdbb2; /* bg1 light */ + --color-dark-grey-500: #504945; + --color-dark-grey-600: #3c3836; + --color-dark-grey-700: #32302f; + --color-dark-grey-800: #282828; + --color-dark-grey-900: #1d2021; + --color-light-grey-50: #fbf1c7; + --color-light-grey-100: #f2e5bc; + --color-light-grey-200: #ebdbb2; --color-light-grey-300: #e3d3a4; - --color-light-grey-400: #d5c4a1; /* bg2 light */ + --color-light-grey-400: #d5c4a1; --color-light-grey-500: #c7b592; - --color-light-grey-600: #bdae93; /* bg3 light */ - --color-light-grey-700: #a89984; /* bg4 light / fg4 */ + --color-light-grey-600: #bdae93; + --color-light-grey-700: #a89984; --color-light-grey-800: #927f68; - --color-light-grey-900: #7c6f64; /* bg4 */ + --color-light-grey-900: #7c6f64; } /* ========================================================================= @@ -508,28 +507,24 @@ * ========================================================================= */ :root, [data-theme="light"] { - /* Backgrounds */ - --color-bg-main: #fbf1c7; /* bg0 light */ - --color-bg-secondary: #f2e5bc; /* bg0_s light */ - --color-bg-tertiary: #ebdbb2; /* bg1 light */ + --color-bg-main: #fbf1c7; + --color-bg-secondary: #f2e5bc; + --color-bg-tertiary: #ebdbb2; --color-bg-tertiary-hover: #e3d3a4; - --color-bg-tertiary-pressed: #d5c4a1; /* bg2 light */ + --color-bg-tertiary-pressed: #d5c4a1; --color-bg-contrast: #f2e5bc; - --color-bg-inverse: #282828; /* bg0 dark */ + --color-bg-inverse: #282828; --transparent-bg: #fbf1c780; - /* Text */ - --color-text-main: #3c3836; /* fg1 (strong body) */ - --color-text-secondary: #504945; /* fg2 */ - --color-text-disabled: #a89984; /* fg4/gray */ - --color-text-inverse: #fbf1c7; /* bg0 light */ + --color-text-main: #3c3836; + --color-text-secondary: #504945; + --color-text-disabled: #a89984; + --color-text-inverse: #fbf1c7; - /* Borders & dividers */ --color-border-neutral-primary: #d5c4a1; --color-border-neutral-secondary: #a89984; --color-divider-main: #d5c4a1; - /* Neutral aliases */ --color-neutral-main: #bdae93; --color-neutral-strong: #665c54; --color-neutral-weak: #ebdbb2; @@ -732,28 +727,24 @@ * Gruvbox Dark (bg0 background, fg1 text) * ========================================================================= */ [data-theme="dark"] { - /* Backgrounds */ - --color-bg-main: #282828; /* bg0 */ - --color-bg-secondary: #32302f; /* bg0_s */ - --color-bg-tertiary: #3c3836; /* bg1 */ - --color-bg-tertiary-hover: #504945; /* bg2 */ - --color-bg-tertiary-pressed: #665c54; /* bg3 */ + --color-bg-main: #282828; + --color-bg-secondary: #32302f; + --color-bg-tertiary: #3c3836; + --color-bg-tertiary-hover: #504945; + --color-bg-tertiary-pressed: #665c54; --color-bg-contrast: #32302f; - --color-bg-inverse: #fbf1c7; /* bg0 light */ + --color-bg-inverse: #fbf1c7; --transparent-bg: #2828284d; - /* Text */ - --color-text-main: #ebdbb2; /* fg1 (bright body) */ - --color-text-secondary: #d5c4a1; /* fg2 */ - --color-text-disabled: #7c6f64; /* bg4 */ - --color-text-inverse: #282828; /* bg0 */ + --color-text-main: #ebdbb2; + --color-text-secondary: #d5c4a1; + --color-text-disabled: #7c6f64; + --color-text-inverse: #282828; - /* Borders & dividers */ --color-border-neutral-primary: #3c3836; --color-border-neutral-secondary: #7c6f64; --color-divider-main: #3c3836; - /* Neutral aliases */ --color-neutral-main: #504945; --color-neutral-strong: #a89984; --color-neutral-weak: #32302f; diff --git a/themes/liquid-glass.css b/themes/liquid-glass.css index 6085b74..d36f61f 100644 --- a/themes/liquid-glass.css +++ b/themes/liquid-glass.css @@ -25,7 +25,7 @@ --color-accent-strong: #0060df; --color-accent-weak: #5ac8fa; --color-accent-light: #9dd6ff; - --color-accent-stronger: #0048a8; /* deeper "pressed" tier */ + --color-accent-stronger: #0048a8; /* Feedback (error / success / warning) — iOS system colors, one * default/disabled/hovered/pressed variable per type */ @@ -42,18 +42,16 @@ --color-feedback-warning-hovered: #e08600; --color-feedback-warning-pressed: #c27200; - /* Neutral ramp mapped onto Apple's systemGray6 -> systemGray -> dark - * systemGray tiers (light -> dark) */ - --color-grey-50: #f2f2f7; /* systemGray6 light */ - --color-grey-100: #e5e5ea; /* systemGray5 light */ - --color-grey-200: #d1d1d6; /* systemGray4 light */ - --color-grey-300: #c7c7cc; /* systemGray3 light */ - --color-grey-400: #aeaeb2; /* systemGray2 light */ - --color-grey-500: #8e8e93; /* systemGray light */ - --color-grey-600: #636366; /* systemGray2 dark */ - --color-grey-700: #48484a; /* systemGray4 dark */ - --color-grey-800: #2c2c2e; /* systemGray5 dark */ - --color-grey-900: #1c1c1e; /* systemGray6 dark */ + --color-grey-50: #f2f2f7; + --color-grey-100: #e5e5ea; + --color-grey-200: #d1d1d6; + --color-grey-300: #c7c7cc; + --color-grey-400: #aeaeb2; + --color-grey-500: #8e8e93; + --color-grey-600: #636366; + --color-grey-700: #48484a; + --color-grey-800: #2c2c2e; + --color-grey-900: #1c1c1e; /* Fixed dark/light grey ramps — do NOT swap with the mode; always-dark * chrome (e.g. the player bar even in light mode) reads from these */ @@ -523,7 +521,6 @@ * ========================================================================= */ :root, [data-theme="light"] { - /* Backgrounds */ --color-bg-main: #f2f2f7; --color-bg-secondary: #ffffff; --color-bg-tertiary: #e9e9ee; @@ -535,18 +532,16 @@ * section 5 below. Consumed as a flat fill anywhere blur can't apply. */ --transparent-bg: rgba(255, 255, 255, 0.72); - /* Text */ --color-text-main: #1c1c1e; --color-text-secondary: #6e6e73; /* Apple secondaryLabel */ --color-text-disabled: #aeaeb2; --color-text-inverse: #fff; - /* Borders & dividers — soft hairlines, not heavy Deezer greys */ + /* Soft hairlines, not heavy Deezer greys */ --color-border-neutral-primary: #d8d8dd; --color-border-neutral-secondary: #c7c7cc; --color-divider-main: #d8d8dd; - /* Neutral aliases */ --color-neutral-main: #c7c7cc; --color-neutral-strong: #6e6e73; --color-neutral-weak: #e5e5ea; @@ -770,7 +765,6 @@ * Dark mode (near-black canvas, dark glass panels) * ========================================================================= */ [data-theme="dark"] { - /* Backgrounds */ --color-bg-main: #1c1c1e; --color-bg-secondary: #242426; --color-bg-tertiary: #2c2c2e; @@ -780,18 +774,15 @@ --color-bg-inverse: #f2f2f7; --transparent-bg: rgba(28, 28, 30, 0.72); - /* Text */ --color-text-main: #f5f5f7; --color-text-secondary: #aeaeb2; /* Apple secondaryLabel, dark */ --color-text-disabled: #636366; --color-text-inverse: #1c1c1e; - /* Borders & dividers */ --color-border-neutral-primary: #3a3a3c; --color-border-neutral-secondary: #48484a; --color-divider-main: #3a3a3c; - /* Neutral aliases */ --color-neutral-main: #48484a; --color-neutral-strong: #aeaeb2; --color-neutral-weak: #2c2c2e; diff --git a/themes/matrix.css b/themes/matrix.css index 10f877b..42ee325 100644 --- a/themes/matrix.css +++ b/themes/matrix.css @@ -23,7 +23,7 @@ --color-accent-strong: #00cc34; --color-accent-weak: #33ff66; --color-accent-light: #99ffb3; - --color-accent-stronger: #00991f; /* deeper "pressed" tier */ + --color-accent-stronger: #00991f; /* Feedback (error / success / warning) — one default/disabled/hovered/ * pressed variable per type, unlike template.css's single flat color */ @@ -40,8 +40,6 @@ --color-feedback-warning-hovered: #b8e000; --color-feedback-warning-pressed: #93b400; - /* Neutral ramp — near-black to pale green (light -> dark aliasing kept - * for template compatibility, but this theme only ever renders dark) */ --color-grey-50: #e8ffe8; --color-grey-100: #c8ffd2; --color-grey-200: #a0e6ab; @@ -502,7 +500,6 @@ * ========================================================================= */ :root, [data-theme="light"] { - /* Backgrounds — near-black with a faint green cast */ --color-bg-main: #010401; --color-bg-secondary: #030a05; --color-bg-tertiary: #071206; @@ -512,18 +509,15 @@ --color-bg-inverse: #d9ffd9; --transparent-bg: #00000080; - /* Text */ --color-text-main: #c8ffc8; --color-text-secondary: #5fbf6f; --color-text-disabled: #2c5230; --color-text-inverse: #010401; - /* Borders & dividers */ --color-border-neutral-primary: #164a22; --color-border-neutral-secondary: #2f7a3d; --color-divider-main: #164a22; - /* Neutral aliases */ --color-neutral-main: #276b34; --color-neutral-strong: #3f9450; --color-neutral-weak: #164a22; @@ -735,7 +729,6 @@ * Dark mode — the only mode. Near-black background, matrix-green text. * ========================================================================= */ [data-theme="dark"] { - /* Backgrounds — near-black with a faint green cast */ --color-bg-main: #010401; --color-bg-secondary: #030a05; --color-bg-tertiary: #071206; @@ -745,18 +738,15 @@ --color-bg-inverse: #d9ffd9; --transparent-bg: #00000080; - /* Text */ --color-text-main: #c8ffc8; --color-text-secondary: #5fbf6f; --color-text-disabled: #2c5230; --color-text-inverse: #010401; - /* Borders & dividers */ --color-border-neutral-primary: #164a22; --color-border-neutral-secondary: #2f7a3d; --color-divider-main: #164a22; - /* Neutral aliases */ --color-neutral-main: #276b34; --color-neutral-strong: #3f9450; --color-neutral-weak: #164a22; diff --git a/themes/monokai.css b/themes/monokai.css index 36fc052..998c3b2 100644 --- a/themes/monokai.css +++ b/themes/monokai.css @@ -25,7 +25,7 @@ --color-accent-strong: #d91f5c; --color-accent-weak: #ff6188; --color-accent-light: #ff9dbb; - --color-accent-stronger: #b8134a; /* deeper "pressed" tier */ + --color-accent-stronger: #b8134a; /* Feedback (error / success / warning) — one default/disabled/hovered/ * pressed variable per type, unlike template.css's single flat color */ @@ -42,17 +42,16 @@ --color-feedback-warning-hovered: #dd7f0f; --color-feedback-warning-pressed: #bd6a09; - /* Neutral ramp mapped onto Monokai's warm cream/charcoal tones (light -> dark) */ --color-grey-50: #f9f8f5; --color-grey-100: #f0efe9; --color-grey-200: #e2e0d5; --color-grey-300: #c4c2b3; --color-grey-400: #a6a394; - --color-grey-500: #75715e; /* comment grey */ + --color-grey-500: #75715e; --color-grey-600: #57544a; - --color-grey-700: #49483e; /* selection */ - --color-grey-800: #3e3d32; /* line highlight */ - --color-grey-900: #272822; /* editor background */ + --color-grey-700: #49483e; + --color-grey-800: #3e3d32; + --color-grey-900: #272822; /* Fixed dark/light grey ramps — do NOT swap with the mode */ --color-dark-grey-200: #6e6b5c; @@ -501,7 +500,6 @@ * ========================================================================= */ :root, [data-theme="light"] { - /* Backgrounds */ --color-bg-main: #f9f8f2; --color-bg-secondary: #f0efe4; --color-bg-tertiary: #e6e4d5; @@ -511,18 +509,15 @@ --color-bg-inverse: #272822; --transparent-bg: #f9f8f280; - /* Text */ --color-text-main: #272822; - --color-text-secondary: #75715e; /* comment grey */ + --color-text-secondary: #75715e; --color-text-disabled: #a6a394; --color-text-inverse: #f8f8f2; - /* Borders & dividers */ --color-border-neutral-primary: #d1cfc0; --color-border-neutral-secondary: #a6a394; --color-divider-main: #d1cfc0; - /* Neutral aliases */ --color-neutral-main: #a6a394; --color-neutral-strong: #75715e; --color-neutral-weak: #e6e4d5; @@ -725,7 +720,6 @@ * Monokai Dark (classic charcoal background, warm cream text) * ========================================================================= */ [data-theme="dark"] { - /* Backgrounds */ --color-bg-main: #272822; --color-bg-secondary: #1e1f1a; --color-bg-tertiary: #3e3d32; @@ -735,18 +729,15 @@ --color-bg-inverse: #f8f8f2; --transparent-bg: #2728224d; - /* Text */ --color-text-main: #f8f8f2; --color-text-secondary: #a6a394; --color-text-disabled: #57544a; --color-text-inverse: #272822; - /* Borders & dividers */ --color-border-neutral-primary: #49483e; --color-border-neutral-secondary: #75715e; --color-divider-main: #49483e; - /* Neutral aliases */ --color-neutral-main: #57544a; --color-neutral-strong: #a6a394; --color-neutral-weak: #3e3d32; diff --git a/themes/nord.css b/themes/nord.css index 2da5391..044242f 100644 --- a/themes/nord.css +++ b/themes/nord.css @@ -23,58 +23,57 @@ * ========================================================================= */ :root { /* Accent: Nord frost ramp instead of Deezer purple */ - --color-accent-main: #81a1c1; /* nord9 */ - --color-accent-strong: #5e81ac; /* nord10 */ - --color-accent-weak: #88c0d0; /* nord8 */ + --color-accent-main: #81a1c1; + --color-accent-strong: #5e81ac; + --color-accent-weak: #88c0d0; --color-accent-light: #a3d0dc; - --color-accent-stronger: #4c6a92; /* deeper "pressed" tier */ + --color-accent-stronger: #4c6a92; /* Feedback (error / success / warning) — one default/disabled/hovered/ * pressed variable per type, unlike template.css's single flat color */ - --color-feedback-error: #bf616a; /* nord11 */ + --color-feedback-error: #bf616a; --color-feedback-error-disabled: #d3939a; --color-feedback-error-hovered: #a94f58; --color-feedback-error-pressed: #8f424a; - --color-feedback-success: #a3be8c; /* nord14 */ + --color-feedback-success: #a3be8c; --color-feedback-success-disabled: #c1d4b0; --color-feedback-success-hovered: #8cab72; --color-feedback-success-pressed: #75935c; - --color-feedback-warning: #ebcb8b; /* nord13 */ + --color-feedback-warning: #ebcb8b; --color-feedback-warning-disabled: #f0d9a8; --color-feedback-warning-hovered: #d4af5e; --color-feedback-warning-pressed: #bc9645; - /* Neutral ramp mapped onto Nord Polar Night/Snow Storm tones (light -> dark) */ - --color-grey-50: #eceff4; /* nord6 */ - --color-grey-100: #e5e9f0; /* nord5 */ - --color-grey-200: #d8dee9; /* nord4 */ + --color-grey-50: #eceff4; + --color-grey-100: #e5e9f0; + --color-grey-200: #d8dee9; --color-grey-300: #b7c0d1; --color-grey-400: #949fb2; --color-grey-500: #6b7890; - --color-grey-600: #4c566a; /* nord3 */ - --color-grey-700: #434c5e; /* nord2 */ - --color-grey-800: #3b4252; /* nord1 */ - --color-grey-900: #2e3440; /* nord0 */ + --color-grey-600: #4c566a; + --color-grey-700: #434c5e; + --color-grey-800: #3b4252; + --color-grey-900: #2e3440; /* Fixed dark/light grey ramps — do NOT swap with the mode */ --color-dark-grey-200: #7b88a1; --color-dark-grey-300: #6b7890; --color-dark-grey-400: #5b6b83; - --color-dark-grey-500: #4c566a; /* nord3 */ - --color-dark-grey-600: #434c5e; /* nord2 */ - --color-dark-grey-700: #3b4252; /* nord1 */ + --color-dark-grey-500: #4c566a; + --color-dark-grey-600: #434c5e; + --color-dark-grey-700: #3b4252; --color-dark-grey-800: #333a48; - --color-dark-grey-900: #2e3440; /* nord0 */ - --color-light-grey-50: #eceff4; /* nord6 */ - --color-light-grey-100: #e5e9f0; /* nord5 */ + --color-dark-grey-900: #2e3440; + --color-light-grey-50: #eceff4; + --color-light-grey-100: #e5e9f0; --color-light-grey-200: #dee3ec; - --color-light-grey-300: #d8dee9; /* nord4 */ + --color-light-grey-300: #d8dee9; --color-light-grey-400: #c6cdda; --color-light-grey-500: #b7c0d1; --color-light-grey-600: #9aa5b1; --color-light-grey-700: #838fa1; --color-light-grey-800: #6b7890; - --color-light-grey-900: #4c566a; /* nord3 */ + --color-light-grey-900: #4c566a; } /* ========================================================================= @@ -381,28 +380,24 @@ * ========================================================================= */ :root, [data-theme="light"] { - /* Backgrounds */ - --color-bg-main: #eceff4; /* nord6 */ - --color-bg-secondary: #e5e9f0; /* nord5 */ + --color-bg-main: #eceff4; + --color-bg-secondary: #e5e9f0; --color-bg-tertiary: #dee3ec; --color-bg-tertiary-hover: #d3d9e6; --color-bg-tertiary-pressed: #c6cdda; --color-bg-contrast: #e5e9f0; - --color-bg-inverse: #2e3440; /* nord0 */ + --color-bg-inverse: #2e3440; --transparent-bg: #eceff480; - /* Text */ - --color-text-main: #2e3440; /* nord0 (strong body) */ - --color-text-secondary: #4c566a; /* nord3 */ + --color-text-main: #2e3440; + --color-text-secondary: #4c566a; --color-text-disabled: #9aa5b1; - --color-text-inverse: #eceff4; /* nord6 */ + --color-text-inverse: #eceff4; - /* Borders & dividers */ --color-border-neutral-primary: #ccd3e0; --color-border-neutral-secondary: #9aa5b1; --color-divider-main: #ccd3e0; - /* Neutral aliases */ --color-neutral-main: #9aa5b1; --color-neutral-strong: #4c566a; --color-neutral-weak: #e5e9f0; @@ -605,34 +600,30 @@ * Nord Dark (Polar Night background, Snow Storm text) * ========================================================================= */ [data-theme="dark"] { - /* Backgrounds */ - --color-bg-main: #2e3440; /* nord0 */ - --color-bg-secondary: #3b4252; /* nord1 */ - --color-bg-tertiary: #434c5e; /* nord2 */ - --color-bg-tertiary-hover: #4c566a; /* nord3 */ + --color-bg-main: #2e3440; + --color-bg-secondary: #3b4252; + --color-bg-tertiary: #434c5e; + --color-bg-tertiary-hover: #4c566a; --color-bg-tertiary-pressed: #566277; --color-bg-contrast: #3b4252; - --color-bg-inverse: #eceff4; /* nord6 */ + --color-bg-inverse: #eceff4; --transparent-bg: #2e34404d; - /* Text */ - --color-text-main: #e5e9f0; /* nord5 (bright body) */ - --color-text-secondary: #d8dee9; /* nord4 */ + --color-text-main: #e5e9f0; + --color-text-secondary: #d8dee9; --color-text-disabled: #6b7890; - --color-text-inverse: #2e3440; /* nord0 */ + --color-text-inverse: #2e3440; - /* Borders & dividers */ --color-border-neutral-primary: #434c5e; --color-border-neutral-secondary: #6b7890; --color-divider-main: #434c5e; - /* Neutral aliases */ --color-neutral-main: #4c566a; --color-neutral-strong: #9aa5b1; --color-neutral-weak: #3b4252; /* Brand accents retinted toward Nord frost teal */ - --color-bg-brand-duo: #8fbcbb; /* nord7 */ + --color-bg-brand-duo: #8fbcbb; --color-bg-brand-trio: #8fbcbb; --color-bg-brand-duo-selected: #434c5e; --color-text-brand-duo: #2e3440; diff --git a/themes/primer.css b/themes/primer.css index dae1682..e7d3faa 100644 --- a/themes/primer.css +++ b/themes/primer.css @@ -32,60 +32,59 @@ /* Accent: Primer blue instead of Deezer purple. The light-scale blue * (#0969da) is used as "main" so it stays legible as text/icon color on * a white background as well as a filled button on a dark one. */ - --color-accent-main: #0969da; /* blue.5 (light) */ - --color-accent-strong: #0550ae; /* blue.6 (light) */ - --color-accent-weak: #218bff; /* blue.4 (light) */ - --color-accent-light: #54aeff; /* blue.3 (light) */ - --color-accent-stronger: #033d8b; /* blue.7 (light), deeper "pressed" tier */ + --color-accent-main: #0969da; + --color-accent-strong: #0550ae; + --color-accent-weak: #218bff; + --color-accent-light: #54aeff; + --color-accent-stronger: #033d8b; /* Feedback (error / success / warning) — one default/disabled/hovered/ * pressed variable per type, unlike template.css's single flat color. * Uses the light-scale hues for the same both-backgrounds-legible * reason as the main accent above. */ - --color-feedback-error: #cf222e; /* red.5 */ - --color-feedback-error-disabled: #ff8182; /* red.3 */ - --color-feedback-error-hovered: #a40e26; /* red.6 */ - --color-feedback-error-pressed: #82071e; /* red.7 */ - --color-feedback-success: #1a7f37; /* green.5 */ - --color-feedback-success-disabled: #4ac26b; /* green.3 */ - --color-feedback-success-hovered: #116329; /* green.6 */ - --color-feedback-success-pressed: #044f1e; /* green.7 */ - --color-feedback-warning: #9a6700; /* yellow.5 */ - --color-feedback-warning-disabled: #d4a72c; /* yellow.3 */ - --color-feedback-warning-hovered: #7d4e00; /* yellow.6 */ - --color-feedback-warning-pressed: #633c01; /* yellow.7 */ + --color-feedback-error: #cf222e; + --color-feedback-error-disabled: #ff8182; + --color-feedback-error-hovered: #a40e26; + --color-feedback-error-pressed: #82071e; + --color-feedback-success: #1a7f37; + --color-feedback-success-disabled: #4ac26b; + --color-feedback-success-hovered: #116329; + --color-feedback-success-pressed: #044f1e; + --color-feedback-warning: #9a6700; + --color-feedback-warning-disabled: #d4a72c; + --color-feedback-warning-hovered: #7d4e00; + --color-feedback-warning-pressed: #633c01; - /* Neutral ramp mapped onto Primer's light-mode neutral scale (light -> dark) */ - --color-grey-50: #f6f8fa; /* light n1 */ - --color-grey-100: #eff2f5; /* light n2 */ - --color-grey-200: #e6eaef; /* light n3 */ - --color-grey-300: #dae0e7; /* light n5 */ - --color-grey-400: #c8d1da; /* light n7 */ - --color-grey-500: #818b98; /* light n8 */ - --color-grey-600: #59636e; /* light n9 */ - --color-grey-700: #454c54; /* light n10 */ - --color-grey-800: #393f46; /* light n11 */ - --color-grey-900: #25292e; /* light n12 */ + --color-grey-50: #f6f8fa; + --color-grey-100: #eff2f5; + --color-grey-200: #e6eaef; + --color-grey-300: #dae0e7; + --color-grey-400: #c8d1da; + --color-grey-500: #818b98; + --color-grey-600: #59636e; + --color-grey-700: #454c54; + --color-grey-800: #393f46; + --color-grey-900: #25292e; /* Fixed dark/light grey ramps — do NOT swap with the mode */ - --color-dark-grey-200: #3d444d; /* dark n7 */ - --color-dark-grey-300: #2f3742; /* dark n6 */ - --color-dark-grey-400: #2a313c; /* dark n5 */ - --color-dark-grey-500: #262c36; /* dark n4 */ - --color-dark-grey-600: #212830; /* dark n3 */ - --color-dark-grey-700: #151b23; /* dark n2 */ - --color-dark-grey-800: #0d1117; /* dark n1 */ - --color-dark-grey-900: #010409; /* dark black */ - --color-light-grey-50: #f6f8fa; /* light n1 */ - --color-light-grey-100: #eff2f5; /* light n2 */ - --color-light-grey-200: #e6eaef; /* light n3 */ - --color-light-grey-300: #e0e6eb; /* light n4 */ - --color-light-grey-400: #dae0e7; /* light n5 */ - --color-light-grey-500: #d1d9e0; /* light n6 */ - --color-light-grey-600: #c8d1da; /* light n7 */ - --color-light-grey-700: #818b98; /* light n8 */ - --color-light-grey-800: #59636e; /* light n9 */ - --color-light-grey-900: #454c54; /* light n10 */ + --color-dark-grey-200: #3d444d; + --color-dark-grey-300: #2f3742; + --color-dark-grey-400: #2a313c; + --color-dark-grey-500: #262c36; + --color-dark-grey-600: #212830; + --color-dark-grey-700: #151b23; + --color-dark-grey-800: #0d1117; + --color-dark-grey-900: #010409; + --color-light-grey-50: #f6f8fa; + --color-light-grey-100: #eff2f5; + --color-light-grey-200: #e6eaef; + --color-light-grey-300: #e0e6eb; + --color-light-grey-400: #dae0e7; + --color-light-grey-500: #d1d9e0; + --color-light-grey-600: #c8d1da; + --color-light-grey-700: #818b98; + --color-light-grey-800: #59636e; + --color-light-grey-900: #454c54; /* Typography — Primer/GitHub's system font stack (base/typography/ * fontStack/normal in primer/primitives), used for both body and @@ -540,31 +539,27 @@ * ========================================================================= */ :root, [data-theme="light"] { - /* Backgrounds */ - --color-bg-main: #ffffff; /* canvas.default */ - --color-bg-secondary: #f6f8fa; /* canvas.subtle, light n1 */ - --color-bg-tertiary: #eff2f5; /* light n2 */ - --color-bg-tertiary-hover: #e6eaef; /* light n3 */ - --color-bg-tertiary-pressed: #e0e6eb; /* light n4 */ - --color-bg-contrast: #dae0e7; /* light n5 */ - --color-bg-inverse: #25292e; /* light n12 */ + --color-bg-main: #ffffff; + --color-bg-secondary: #f6f8fa; + --color-bg-tertiary: #eff2f5; + --color-bg-tertiary-hover: #e6eaef; + --color-bg-tertiary-pressed: #e0e6eb; + --color-bg-contrast: #dae0e7; + --color-bg-inverse: #25292e; --transparent-bg: #ffffff80; - /* Text */ - --color-text-main: #1f2328; /* fg.default (base black) */ - --color-text-secondary: #59636e; /* fg.muted, light n9 */ - --color-text-disabled: #818b98; /* fg.subtle, light n8 */ + --color-text-main: #1f2328; + --color-text-secondary: #59636e; + --color-text-disabled: #818b98; --color-text-inverse: #ffffff; - /* Borders & dividers */ - --color-border-neutral-primary: #d1d9e0; /* border.default, light n6 */ - --color-border-neutral-secondary: #c8d1da; /* light n7 */ + --color-border-neutral-primary: #d1d9e0; + --color-border-neutral-secondary: #c8d1da; --color-divider-main: #d1d9e0; - /* Neutral aliases */ - --color-neutral-main: #e6eaef; /* light n3 */ - --color-neutral-strong: #e0e6eb; /* light n4 */ - --color-neutral-weak: #eff2f5; /* light n2 */ + --color-neutral-main: #e6eaef; + --color-neutral-strong: #e0e6eb; + --color-neutral-weak: #eff2f5; --tempo-colors-background-neutral-inverse-default: var( --color-bg-inverse @@ -764,37 +759,33 @@ * Primer Dark (GitHub's default dark canvas/fg colors) * ========================================================================= */ [data-theme="dark"] { - /* Backgrounds */ - --color-bg-main: #0d1117; /* canvas.default, dark n1 */ - --color-bg-secondary: #151b23; /* canvas.subtle, dark n2 */ - --color-bg-tertiary: #212830; /* dark n3 */ - --color-bg-tertiary-hover: #262c36; /* dark n4 */ - --color-bg-tertiary-pressed: #2a313c; /* dark n5 */ - --color-bg-contrast: #2f3742; /* dark n6 */ - --color-bg-inverse: #f6f8fa; /* light n1 */ + --color-bg-main: #0d1117; + --color-bg-secondary: #151b23; + --color-bg-tertiary: #212830; + --color-bg-tertiary-hover: #262c36; + --color-bg-tertiary-pressed: #2a313c; + --color-bg-contrast: #2f3742; + --color-bg-inverse: #f6f8fa; --transparent-bg: #0104094d; - /* Text */ - --color-text-main: #f0f6fc; /* fg.default, dark n12 */ - --color-text-secondary: #9198a1; /* fg.muted, dark n9 */ - --color-text-disabled: #656c76; /* fg.subtle, dark n8 */ - --color-text-inverse: #010409; /* base black (dark) */ + --color-text-main: #f0f6fc; + --color-text-secondary: #9198a1; + --color-text-disabled: #656c76; + --color-text-inverse: #010409; - /* Borders & dividers */ - --color-border-neutral-primary: #3d444d; /* border.default, dark n7 */ - --color-border-neutral-secondary: #f0f6fc; /* dark n12 */ + --color-border-neutral-primary: #3d444d; + --color-border-neutral-secondary: #f0f6fc; --color-divider-main: #3d444d; - /* Neutral aliases */ - --color-neutral-main: #2f3742; /* dark n6 */ - --color-neutral-strong: #3d444d; /* dark n7 */ - --color-neutral-weak: #212830; /* dark n3 */ + --color-neutral-main: #2f3742; + --color-neutral-strong: #3d444d; + --color-neutral-weak: #212830; /* Brand accents retinted toward Primer green */ - --color-bg-brand-duo: #56d364; /* green.2 (dark) */ + --color-bg-brand-duo: #56d364; --color-bg-brand-trio: #56d364; --color-bg-brand-duo-selected: #212830; - --color-text-brand-duo: #04260f; /* green.9 (dark) */ + --color-text-brand-duo: #04260f; --color-text-brand-trio: #04260f; --tempo-colors-background-neutral-inverse-default: var( diff --git a/themes/solarized.css b/themes/solarized.css index 7badefe..a23db0e 100644 --- a/themes/solarized.css +++ b/themes/solarized.css @@ -24,7 +24,7 @@ --color-accent-strong: #1a6ba8; --color-accent-weak: #6cb0e0; --color-accent-light: #9cccec; - --color-accent-stronger: #14547f; /* deeper "pressed" tier */ + --color-accent-stronger: #14547f; /* Feedback (error / success / warning) — one default/disabled/hovered/ * pressed variable per type, unlike template.css's single flat color */ @@ -41,37 +41,36 @@ --color-feedback-warning-hovered: #8f6d00; --color-feedback-warning-pressed: #6b5200; - /* Neutral ramp mapped onto Solarized base tones (light -> dark) */ - --color-grey-50: #fdf6e3; /* base3 */ - --color-grey-100: #f5eeda; /* base3/base2 */ - --color-grey-200: #eee8d5; /* base2 */ - --color-grey-300: #ccc9b6; /* base2/base1 */ - --color-grey-400: #93a1a1; /* base1 */ - --color-grey-500: #586e75; /* base01 */ - --color-grey-600: #113640; /* base02/base03 */ - --color-grey-700: #0b333d; /* base02 */ - --color-grey-800: #073642; /* base02 */ - --color-grey-900: #002b36; /* base03 */ + --color-grey-50: #fdf6e3; + --color-grey-100: #f5eeda; + --color-grey-200: #eee8d5; + --color-grey-300: #ccc9b6; + --color-grey-400: #93a1a1; + --color-grey-500: #586e75; + --color-grey-600: #113640; + --color-grey-700: #0b333d; + --color-grey-800: #073642; + --color-grey-900: #002b36; /* Fixed dark/light grey ramps — do NOT swap with the mode */ --color-dark-grey-200: #748b91; --color-dark-grey-300: #64787e; --color-dark-grey-400: #5b7278; - --color-dark-grey-500: #586e75; /* base01 */ + --color-dark-grey-500: #586e75; --color-dark-grey-600: #113640; --color-dark-grey-700: #0b333d; - --color-dark-grey-800: #073642; /* base02 */ - --color-dark-grey-900: #002b36; /* base03 */ - --color-light-grey-50: #fdf6e3; /* base3 */ + --color-dark-grey-800: #073642; + --color-dark-grey-900: #002b36; + --color-light-grey-50: #fdf6e3; --color-light-grey-100: #f5eeda; --color-light-grey-200: #f2ecd9; - --color-light-grey-300: #eee8d5; /* base2 */ + --color-light-grey-300: #eee8d5; --color-light-grey-400: #d9d3ba; --color-light-grey-500: #ccc9b6; - --color-light-grey-600: #93a1a1; /* base1 */ - --color-light-grey-700: #839496; /* base0 */ + --color-light-grey-600: #93a1a1; + --color-light-grey-700: #839496; --color-light-grey-800: #6e838b; - --color-light-grey-900: #586e75; /* base01 */ + --color-light-grey-900: #586e75; } /* ========================================================================= @@ -378,28 +377,24 @@ * ========================================================================= */ :root, [data-theme="light"] { - /* Backgrounds */ - --color-bg-main: #fdf6e3; /* base3 */ - --color-bg-secondary: #eee8d5; /* base2 */ + --color-bg-main: #fdf6e3; + --color-bg-secondary: #eee8d5; --color-bg-tertiary: #e6dfc7; /* base2, darker */ --color-bg-tertiary-hover: #ddd4b8; --color-bg-tertiary-pressed: #d4c9a8; --color-bg-contrast: #eee8d5; - --color-bg-inverse: #002b36; /* base03 */ + --color-bg-inverse: #002b36; --transparent-bg: #fdf6e380; - /* Text */ - --color-text-main: #586e75; /* base01 (strong body) */ - --color-text-secondary: #657b83; /* base00 */ - --color-text-disabled: #93a1a1; /* base1 */ - --color-text-inverse: #fdf6e3; /* base3 */ + --color-text-main: #586e75; + --color-text-secondary: #657b83; + --color-text-disabled: #93a1a1; + --color-text-inverse: #fdf6e3; - /* Borders & dividers */ --color-border-neutral-primary: #ddd6c1; --color-border-neutral-secondary: #93a1a1; --color-divider-main: #ddd6c1; - /* Neutral aliases */ --color-neutral-main: #93a1a1; --color-neutral-strong: #586e75; --color-neutral-weak: #eee8d5; @@ -602,28 +597,24 @@ * Solarized Dark (base03 background, base0 text) * ========================================================================= */ [data-theme="dark"] { - /* Backgrounds */ - --color-bg-main: #002b36; /* base03 */ - --color-bg-secondary: #073642; /* base02 */ + --color-bg-main: #002b36; + --color-bg-secondary: #073642; --color-bg-tertiary: #0d4250; --color-bg-tertiary-hover: #135263; --color-bg-tertiary-pressed: #1a5b6e; --color-bg-contrast: #073642; - --color-bg-inverse: #fdf6e3; /* base3 */ + --color-bg-inverse: #fdf6e3; --transparent-bg: #002b364d; - /* Text */ - --color-text-main: #93a1a1; /* base1 (bright body) */ - --color-text-secondary: #839496; /* base0 */ - --color-text-disabled: #586e75; /* base01 */ - --color-text-inverse: #002b36; /* base03 */ + --color-text-main: #93a1a1; + --color-text-secondary: #839496; + --color-text-disabled: #586e75; + --color-text-inverse: #002b36; - /* Borders & dividers */ --color-border-neutral-primary: #0d4250; --color-border-neutral-secondary: #93a1a1; --color-divider-main: #0d4250; - /* Neutral aliases */ --color-neutral-main: #586e75; --color-neutral-strong: #93a1a1; --color-neutral-weak: #073642; diff --git a/themes/synthwave.css b/themes/synthwave.css index 6827952..32cb675 100644 --- a/themes/synthwave.css +++ b/themes/synthwave.css @@ -25,10 +25,10 @@ :root { /* ---- Accent: SynthWave neon pink instead of Deezer purple ---- */ --color-accent-main: #ff7edb; - --color-accent-strong: #e455c0; /* darker neon pink — hover/pressed */ - --color-accent-weak: #36f9f6; /* neon cyan — secondary accent, for the pink/cyan retrowave contrast */ - --color-accent-light: #ffc2ef; /* pale pink tint — disabled/onDark */ - --color-accent-stronger: #b83a9c; /* deeper "pressed" tier */ + --color-accent-strong: #e455c0; + --color-accent-weak: #36f9f6; + --color-accent-light: #ffc2ef; + --color-accent-stronger: #b83a9c; /* ---- Feedback (error / success / warning) — SynthWave neon triad ---- */ --color-feedback-error: #fe4450; @@ -48,18 +48,16 @@ /* --color-black: #000; */ /* --color-white: #fff; */ - /* ---- Neutral grey ramp (50 = lightest ... 900 = darkest), mapped onto - * SynthWave's dark purple chrome (light -> dark) ---- */ - --color-grey-50: #ffffff; /* foreground */ + --color-grey-50: #ffffff; --color-grey-100: #d3cdee; --color-grey-200: #a8a1d6; - --color-grey-300: #848bbd; /* comment / secondary text */ + --color-grey-300: #848bbd; --color-grey-400: #6c6f9a; - --color-grey-500: #614d85; /* button.background */ - --color-grey-600: #463465; /* menu.background */ - --color-grey-700: #37294d; /* list.hoverBackground */ - --color-grey-800: #2a2139; /* dropdown/input.background */ - --color-grey-900: #171520; /* activityBar.background */ + --color-grey-500: #614d85; + --color-grey-600: #463465; + --color-grey-700: #37294d; + --color-grey-800: #2a2139; + --color-grey-900: #171520; /* ---- Fixed dark/light grey ramps (do NOT swap with the mode; used by * always-dark chrome like the player bar even in light mode). This @@ -93,28 +91,24 @@ * ========================================================================= */ :root, [data-theme="light"] { - /* ---- Backgrounds ---- */ - --color-bg-main: #262335; /* editor.background */ - --color-bg-secondary: #241b2f; /* sideBar/statusBar/titleBar.background */ - --color-bg-tertiary: #2a2139; /* dropdown/input/badge.background */ - --color-bg-tertiary-hover: #37294d; /* list.hoverBackground */ - --color-bg-tertiary-pressed: #463465; /* menu.background */ - --color-bg-contrast: #171520; /* activityBar.background */ + --color-bg-main: #262335; + --color-bg-secondary: #241b2f; + --color-bg-tertiary: #2a2139; + --color-bg-tertiary-hover: #37294d; + --color-bg-tertiary-pressed: #463465; + --color-bg-contrast: #171520; --color-bg-inverse: #ffffff; --transparent-bg: #26233580; - /* ---- Text ---- */ --color-text-main: #ffffff; - --color-text-secondary: #848bbd; /* comment / lavender-grey */ + --color-text-secondary: #848bbd; --color-text-disabled: #6c6f8f; --color-text-inverse: #262335; - /* ---- Borders & dividers ---- */ - --color-border-neutral-primary: #495495; /* editorGroup.border */ + --color-border-neutral-primary: #495495; --color-border-neutral-secondary: #6c6f9a; --color-divider-main: #37294d; - /* ---- Neutral aliases ---- */ --color-neutral-main: var(--color-grey-700); --color-neutral-strong: var(--color-grey-500); --color-neutral-weak: var(--color-grey-800); @@ -124,7 +118,6 @@ * 3. DARK MODE * ========================================================================= */ [data-theme="dark"] { - /* ---- Backgrounds ---- */ --color-bg-main: #262335; --color-bg-secondary: #241b2f; --color-bg-tertiary: #2a2139; @@ -134,18 +127,15 @@ --color-bg-inverse: #ffffff; --transparent-bg: #26233580; - /* ---- Text ---- */ --color-text-main: #ffffff; --color-text-secondary: #848bbd; --color-text-disabled: #6c6f8f; --color-text-inverse: #262335; - /* ---- Borders & dividers ---- */ --color-border-neutral-primary: #495495; --color-border-neutral-secondary: #6c6f9a; --color-divider-main: #37294d; - /* ---- Neutral aliases ---- */ --color-neutral-main: var(--color-grey-700); --color-neutral-strong: var(--color-grey-500); --color-neutral-weak: var(--color-grey-800);