@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.` 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; }