light/dark are now exact lightness mirrors of one true neutral scale, grey is that same canonical neutral scale, and each named theme (red/green/blue/yellow/pink/orange) derives its surface/border/text greys by desaturating its own Tailwind hue at each scale step (HSL S->0, lightness kept), leaving saturated colour only on --c-accent*. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
281 lines
7.1 KiB
CSS
281 lines
7.1 KiB
CSS
@import "tailwindcss";
|
|
|
|
/*
|
|
* Theme system: every visual role the app uses (surfaces, borders, text,
|
|
* danger banners, accent highlights) is a plain CSS custom property here,
|
|
* bridged into real Tailwind utilities (bg-surface-0, text-text-muted,
|
|
* border-accent, ...) via `@theme inline`. Components use those utilities
|
|
* instead of hardcoded palette classes (bg-neutral-950, text-sky-400, ...),
|
|
* so re-declaring the `--c-*` variables under a `html.<theme>` selector
|
|
* re-skins the whole app with no per-component changes.
|
|
*
|
|
* Derivation: surfaces/borders/text are always neutral (S=0) greys, never
|
|
* hue-tinted. `dark`/`grey` share one true black-based grey scale, `light`
|
|
* is its exact lightness mirror. Each named theme (red/green/blue/yellow/
|
|
* pink/orange) takes its hue's real Tailwind swatch at each scale step,
|
|
* converts it to HSL, zeroes the saturation, and keeps that lightness as
|
|
* its grey — so e.g. red's surface-0 is grey at red-950's lightness, not
|
|
* neutral-950. Colour survives only on --c-accent*. To add a new themed
|
|
* variant: pick its hue's Tailwind swatches at 950/900/800/700/600/500/
|
|
* 400/300/100, desaturate each (HSL S->0), and slot the greys into the
|
|
* same --c-surface-*/--c-border-*/--c-text-* roles used below.
|
|
*/
|
|
:root {
|
|
color-scheme: light dark;
|
|
|
|
--c-surface-0: #0a0a0a;
|
|
--c-surface-1: #171717;
|
|
--c-surface-2: #262626;
|
|
|
|
--c-border: #262626;
|
|
--c-border-soft: #404040;
|
|
--c-border-faint: #171717;
|
|
--c-border-strong: #a3a3a3;
|
|
|
|
--c-text: #f5f5f5;
|
|
--c-text-secondary: #d4d4d4;
|
|
--c-text-muted: #a3a3a3;
|
|
--c-text-subtle: #737373;
|
|
--c-text-faint: #525252;
|
|
--c-text-faintest: #404040;
|
|
|
|
--c-danger-bg: #450a0a;
|
|
--c-danger-border: #7f1d1d;
|
|
--c-danger-text: #f87171;
|
|
--c-danger-text-strong: #fca5a5;
|
|
|
|
--c-accent: #0ea5e9;
|
|
--c-accent-soft: #0369a1;
|
|
--c-accent-text: #7dd3fc;
|
|
}
|
|
|
|
/* Exact lightness mirror of :root's neutral-950..50 scale (Tailwind neutral,
|
|
steps flipped: 950<->50, 900<->100, 800<->200, 700<->300, 600<->400). */
|
|
html.light {
|
|
--c-surface-0: #fafafa;
|
|
--c-surface-1: #f5f5f5;
|
|
--c-surface-2: #e5e5e5;
|
|
|
|
--c-border: #e5e5e5;
|
|
--c-border-soft: #d4d4d4;
|
|
--c-border-faint: #f5f5f5;
|
|
--c-border-strong: #525252;
|
|
|
|
--c-text: #171717;
|
|
--c-text-secondary: #404040;
|
|
--c-text-muted: #525252;
|
|
--c-text-subtle: #737373;
|
|
--c-text-faint: #a3a3a3;
|
|
--c-text-faintest: #d4d4d4;
|
|
|
|
--c-danger-bg: #fee2e2;
|
|
--c-danger-border: #fca5a5;
|
|
--c-danger-text: #b91c1c;
|
|
--c-danger-text-strong: #991b1b;
|
|
|
|
--c-accent: #0284c7;
|
|
--c-accent-soft: #7dd3fc;
|
|
--c-accent-text: #0369a1;
|
|
}
|
|
|
|
/* Canonical greyscale theme: identical neutral scale to :root (dark), so
|
|
every other theme's derivation above is measured against this one. */
|
|
html.grey {
|
|
--c-surface-0: #0a0a0a;
|
|
--c-surface-1: #171717;
|
|
--c-surface-2: #262626;
|
|
|
|
--c-border: #262626;
|
|
--c-border-soft: #404040;
|
|
--c-border-faint: #171717;
|
|
--c-border-strong: #a3a3a3;
|
|
|
|
--c-text: #f5f5f5;
|
|
--c-text-secondary: #d4d4d4;
|
|
--c-text-muted: #a3a3a3;
|
|
--c-text-subtle: #737373;
|
|
--c-text-faint: #525252;
|
|
--c-text-faintest: #404040;
|
|
|
|
--c-accent: #38bdf8;
|
|
--c-accent-soft: #0369a1;
|
|
--c-accent-text: #7dd3fc;
|
|
}
|
|
|
|
/* red-950..300/100 desaturated (S->0), lightness kept */
|
|
html.red {
|
|
--c-surface-0: #282828;
|
|
--c-surface-1: #4e4e4e;
|
|
--c-surface-2: #5a5a5a;
|
|
|
|
--c-border: #5a5a5a;
|
|
--c-border-soft: #6a6a6a;
|
|
--c-border-faint: #4e4e4e;
|
|
--c-border-strong: #b4b4b4;
|
|
|
|
--c-text: #f0f0f0;
|
|
--c-text-secondary: #d0d0d0;
|
|
--c-text-muted: #b4b4b4;
|
|
--c-text-subtle: #9a9a9a;
|
|
--c-text-faint: #818181;
|
|
--c-text-faintest: #6a6a6a;
|
|
|
|
--c-accent: #f87171;
|
|
--c-accent-soft: #b91c1c;
|
|
--c-accent-text: #fca5a5;
|
|
}
|
|
|
|
/* green-950..300/100 desaturated (S->0), lightness kept */
|
|
html.green {
|
|
--c-surface-0: #1a1a1a;
|
|
--c-surface-1: #343434;
|
|
--c-surface-2: #3d3d3d;
|
|
|
|
--c-border: #3d3d3d;
|
|
--c-border-soft: #4a4a4a;
|
|
--c-border-faint: #343434;
|
|
--c-border-strong: #949494;
|
|
|
|
--c-text: #ececec;
|
|
--c-text-secondary: #bbbbbb;
|
|
--c-text-muted: #949494;
|
|
--c-text-subtle: #747474;
|
|
--c-text-faint: #5c5c5c;
|
|
--c-text-faintest: #4a4a4a;
|
|
|
|
--c-accent: #4ade80;
|
|
--c-accent-soft: #15803d;
|
|
--c-accent-text: #86efac;
|
|
}
|
|
|
|
/* blue-950..300/100 desaturated (S->0), lightness kept */
|
|
html.blue {
|
|
--c-surface-0: #363636;
|
|
--c-surface-1: #545454;
|
|
--c-surface-2: #666666;
|
|
|
|
--c-border: #666666;
|
|
--c-border-soft: #7a7a7a;
|
|
--c-border-faint: #545454;
|
|
--c-border-strong: #adadad;
|
|
|
|
--c-text: #ececec;
|
|
--c-text-secondary: #c8c8c8;
|
|
--c-text-muted: #adadad;
|
|
--c-text-subtle: #989898;
|
|
--c-text-faint: #888888;
|
|
--c-text-faintest: #7a7a7a;
|
|
|
|
--c-accent: #60a5fa;
|
|
--c-accent-soft: #1d4ed8;
|
|
--c-accent-text: #93c5fd;
|
|
}
|
|
|
|
/* yellow-950..300/100 desaturated (S->0), lightness kept */
|
|
html.yellow {
|
|
--c-surface-0: #242424;
|
|
--c-surface-1: #424242;
|
|
--c-surface-2: #4a4a4a;
|
|
|
|
--c-border: #4a4a4a;
|
|
--c-border-soft: #545454;
|
|
--c-border-faint: #424242;
|
|
--c-border-strong: #888888;
|
|
|
|
--c-text: #e0e0e0;
|
|
--c-text-secondary: #a2a2a2;
|
|
--c-text-muted: #888888;
|
|
--c-text-subtle: #797979;
|
|
--c-text-faint: #676767;
|
|
--c-text-faintest: #545454;
|
|
|
|
--c-accent: #facc15;
|
|
--c-accent-soft: #a16207;
|
|
--c-accent-text: #fde047;
|
|
}
|
|
|
|
/* pink-950..300/100 desaturated (S->0), lightness kept */
|
|
html.pink {
|
|
--c-surface-0: #2c2c2c;
|
|
--c-surface-1: #4e4e4e;
|
|
--c-surface-2: #5a5a5a;
|
|
|
|
--c-border: #5a5a5a;
|
|
--c-border-soft: #6b6b6b;
|
|
--c-border-faint: #4e4e4e;
|
|
--c-border-strong: #b3b3b3;
|
|
|
|
--c-text: #f2f2f2;
|
|
--c-text-secondary: #d0d0d0;
|
|
--c-text-muted: #b3b3b3;
|
|
--c-text-subtle: #9a9a9a;
|
|
--c-text-faint: #818181;
|
|
--c-text-faintest: #6b6b6b;
|
|
|
|
--c-accent: #f472b6;
|
|
--c-accent-soft: #be185d;
|
|
--c-accent-text: #f9a8d4;
|
|
}
|
|
|
|
/* orange-950..300/100 desaturated (S->0), lightness kept */
|
|
html.orange {
|
|
--c-surface-0: #252525;
|
|
--c-surface-1: #474747;
|
|
--c-surface-2: #565656;
|
|
|
|
--c-border: #565656;
|
|
--c-border-soft: #676767;
|
|
--c-border-faint: #474747;
|
|
--c-border-strong: #9b9b9b;
|
|
|
|
--c-text: #eaeaea;
|
|
--c-text-secondary: #b8b8b8;
|
|
--c-text-muted: #9b9b9b;
|
|
--c-text-subtle: #888888;
|
|
--c-text-faint: #7b7b7b;
|
|
--c-text-faintest: #676767;
|
|
|
|
--c-accent: #fb923c;
|
|
--c-accent-soft: #c2410c;
|
|
--c-accent-text: #fdba74;
|
|
}
|
|
|
|
@theme inline {
|
|
--color-surface-0: var(--c-surface-0);
|
|
--color-surface-1: var(--c-surface-1);
|
|
--color-surface-2: var(--c-surface-2);
|
|
|
|
--color-border: var(--c-border);
|
|
--color-border-soft: var(--c-border-soft);
|
|
--color-border-faint: var(--c-border-faint);
|
|
--color-border-strong: var(--c-border-strong);
|
|
|
|
--color-text: var(--c-text);
|
|
--color-text-secondary: var(--c-text-secondary);
|
|
--color-text-muted: var(--c-text-muted);
|
|
--color-text-subtle: var(--c-text-subtle);
|
|
--color-text-faint: var(--c-text-faint);
|
|
--color-text-faintest: var(--c-text-faintest);
|
|
|
|
--color-danger-bg: var(--c-danger-bg);
|
|
--color-danger-border: var(--c-danger-border);
|
|
--color-danger-text: var(--c-danger-text);
|
|
--color-danger-text-strong: var(--c-danger-text-strong);
|
|
|
|
--color-accent: var(--c-accent);
|
|
--color-accent-soft: var(--c-accent-soft);
|
|
--color-accent-text: var(--c-accent-text);
|
|
}
|
|
|
|
html,
|
|
body,
|
|
#root {
|
|
height: 100%;
|
|
margin: 0;
|
|
}
|
|
|
|
body {
|
|
@apply bg-surface-0 text-text;
|
|
font: 14px/1.5 ui-monospace, Consolas, monospace;
|
|
}
|