Files
ottyl/webapp/src/index.css
T
Hugh KaznowskiandClaude Sonnet 5 758feca780 Rework colour themes as greyscale + accent-only colour (ticket 032)
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
2026-09-05 16:21:50 +01:00

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;
}