feat(theme): four themes with an actual hue — Indigo, Ocean, Plum, Nordic
The seven existing themes are warm beige, cool grey, sage grey, slate, warm dark, graphite and black — every one neutral, six of the seven accented orange. Picking a theme changed the shade of grey and little else. These colour the SURFACES, not just the accent, and each takes a different primary so the picker tells them apart at a glance: violet on deep indigo, cyan on deep teal, magenta on aubergine, indigo on a crisp cool white. The semantic colours stay recognisable as themselves. A logger is read for hours and "red means a problem" cannot become a decorative choice, so the hue budget went on the surfaces and the primary. Where a theme's primary would have collided with a meaning, the MEANING kept its identity and the ornament moved: Ocean's info is blue rather than cyan, Plum's danger is red rather than rose, and the matrix entity ramp shifts to cyan under Indigo and teal under Nordic so a "confirmed" cell never reads as a button. Everything else follows for free: the grids resolve var(--…) at runtime, so they re-skin with no re-render. The three shared registrations that do NOT follow automatically are done — the chart palette (light vs dark ramp) and the date-picker icon inversion, which is keyed on an explicit list of dark themes.
This commit is contained in:
+288
-3
@@ -495,6 +495,286 @@
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* ---- Theme 5: Indigo — deep blue-violet, electric accent ----------------
|
||||
The first seven themes are all neutral (beige, slate, graphite, black) with an
|
||||
orange accent, so "another dark theme" only ever meant another grey. These
|
||||
four carry a real hue in the SURFACES, not just in the accent, and each takes
|
||||
a different primary — violet, cyan, pink, indigo — so they are told apart at a
|
||||
glance in the picker.
|
||||
|
||||
Every one keeps the same contract: the semantic colours (success / warning /
|
||||
caution / danger / info) must stay recognisable as themselves. A logger is
|
||||
read for hours and "red = a problem" cannot become a decorative choice, so the
|
||||
hue budget is spent on the surfaces and the primary, never on the meanings. */
|
||||
[data-theme="dark-indigo"] {
|
||||
--background: #0e0f1f;
|
||||
--foreground: #e4e5f2;
|
||||
--card: #181a30;
|
||||
--card-foreground: #e4e5f2;
|
||||
--popover: #181a30;
|
||||
--popover-foreground: #e4e5f2;
|
||||
--primary: #7c6cff; /* electric violet */
|
||||
--primary-foreground: #0b0a1a;
|
||||
--secondary: #222542;
|
||||
--secondary-foreground: #e4e5f2;
|
||||
--muted: #1e2038;
|
||||
--muted-foreground: #9d9fbe;
|
||||
--accent: #2a2d51;
|
||||
--accent-foreground: #c7c9ee;
|
||||
--destructive: #f2555a;
|
||||
--destructive-foreground: #12030a;
|
||||
--destructive-muted: #34131c;
|
||||
--destructive-muted-foreground: #fca5a5;
|
||||
--border: #2a2d4c;
|
||||
--input: #2a2d4c;
|
||||
--ring: #9b8dff;
|
||||
|
||||
--success: #34d399;
|
||||
--success-foreground: #052018;
|
||||
--success-muted: #0e2f27;
|
||||
--success-muted-foreground: #6ee7b7;
|
||||
--success-border: #165241;
|
||||
|
||||
--warning: #fbbf24;
|
||||
--warning-foreground: #221803;
|
||||
--warning-muted: #33280f;
|
||||
--warning-muted-foreground: #fcd34d;
|
||||
--warning-border: #4f3e15;
|
||||
|
||||
--caution: #facc15;
|
||||
--caution-foreground: #221e04;
|
||||
--caution-muted: #322d0e;
|
||||
--caution-muted-foreground: #fde047;
|
||||
--caution-border: #4b4315;
|
||||
|
||||
--danger: #fb7185;
|
||||
--danger-foreground: #250912;
|
||||
--danger-muted: #37151f;
|
||||
--danger-muted-foreground: #fda4af;
|
||||
--danger-border: #562533;
|
||||
|
||||
--info: #38bdf8;
|
||||
--info-foreground: #051d29;
|
||||
--info-muted: #0b2a3a;
|
||||
--info-muted-foreground: #7dd3fc;
|
||||
--info-border: #12475c;
|
||||
|
||||
/* The entity ramp moves to CYAN here: violet is the primary, and a violet
|
||||
"entity confirmed" cell would read as a button. */
|
||||
--mx-call-conf: #22c55e;
|
||||
--mx-call-work: #2c7a52;
|
||||
--mx-dx-conf: #22d3ee;
|
||||
--mx-dx-work: #1b6b7c;
|
||||
--mx-none: #2c2f4d;
|
||||
|
||||
--scrollbar-thumb: #383c63;
|
||||
--scrollbar-thumb-hover: #4c5182;
|
||||
--card-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(228, 229, 242, 0.05);
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* ---- Theme 6: Ocean — deep teal, cyan accent --------------------------- */
|
||||
[data-theme="dark-teal"] {
|
||||
--background: #061c21;
|
||||
--foreground: #dcecee;
|
||||
--card: #0d2c33;
|
||||
--card-foreground: #dcecee;
|
||||
--popover: #0d2c33;
|
||||
--popover-foreground: #dcecee;
|
||||
--primary: #22d3ee; /* cyan */
|
||||
--primary-foreground: #041d24;
|
||||
--secondary: #143b44;
|
||||
--secondary-foreground: #dcecee;
|
||||
--muted: #10333b;
|
||||
--muted-foreground: #92b4ba;
|
||||
--accent: #15424c;
|
||||
--accent-foreground: #a5d8e0;
|
||||
--destructive: #f2555a;
|
||||
--destructive-foreground: #12030a;
|
||||
--destructive-muted: #35161a;
|
||||
--destructive-muted-foreground: #fca5a5;
|
||||
--border: #1a4652;
|
||||
--input: #1a4652;
|
||||
--ring: #5fe3f5;
|
||||
|
||||
--success: #4ade80;
|
||||
--success-foreground: #04220f;
|
||||
--success-muted: #0e3020;
|
||||
--success-muted-foreground: #86efac;
|
||||
--success-border: #17593a;
|
||||
|
||||
--warning: #fbbf24;
|
||||
--warning-foreground: #221803;
|
||||
--warning-muted: #33280f;
|
||||
--warning-muted-foreground: #fcd34d;
|
||||
--warning-border: #4f3e15;
|
||||
|
||||
--caution: #facc15;
|
||||
--caution-foreground: #221e04;
|
||||
--caution-muted: #312d0e;
|
||||
--caution-muted-foreground: #fde047;
|
||||
--caution-border: #4a4315;
|
||||
|
||||
--danger: #fb7185;
|
||||
--danger-foreground: #250912;
|
||||
--danger-muted: #38161f;
|
||||
--danger-muted-foreground: #fda4af;
|
||||
--danger-border: #572634;
|
||||
|
||||
/* Info moves to a BLUE: a cyan "info" would be the primary colour again. */
|
||||
--info: #7aa2f7;
|
||||
--info-foreground: #04122e;
|
||||
--info-muted: #16233f;
|
||||
--info-muted-foreground: #a9c2fb;
|
||||
--info-border: #2b3d66;
|
||||
|
||||
--mx-call-conf: #4ade80;
|
||||
--mx-call-work: #2b7a4d;
|
||||
--mx-dx-conf: #a78bfa;
|
||||
--mx-dx-work: #5b4a9c;
|
||||
--mx-none: #1c4550;
|
||||
|
||||
--scrollbar-thumb: #235a68;
|
||||
--scrollbar-thumb-hover: #31788a;
|
||||
--card-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(220, 236, 238, 0.05);
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* ---- Theme 7: Plum — aubergine, magenta accent ------------------------- */
|
||||
[data-theme="dark-plum"] {
|
||||
--background: #180f1e;
|
||||
--foreground: #eee0f0;
|
||||
--card: #251830;
|
||||
--card-foreground: #eee0f0;
|
||||
--popover: #251830;
|
||||
--popover-foreground: #eee0f0;
|
||||
--primary: #f472b6; /* magenta-pink */
|
||||
--primary-foreground: #250518;
|
||||
--secondary: #33203f;
|
||||
--secondary-foreground: #eee0f0;
|
||||
--muted: #2b1b36;
|
||||
--muted-foreground: #b39dbd;
|
||||
--accent: #3b2648;
|
||||
--accent-foreground: #dcc2e6;
|
||||
--destructive: #f2555a;
|
||||
--destructive-foreground: #12030a;
|
||||
--destructive-muted: #3a1620;
|
||||
--destructive-muted-foreground: #fca5a5;
|
||||
--border: #3a2547;
|
||||
--input: #3a2547;
|
||||
--ring: #f9a8d4;
|
||||
|
||||
--success: #34d399;
|
||||
--success-foreground: #052018;
|
||||
--success-muted: #10302a;
|
||||
--success-muted-foreground: #6ee7b7;
|
||||
--success-border: #1a5745;
|
||||
|
||||
--warning: #fbbf24;
|
||||
--warning-foreground: #221803;
|
||||
--warning-muted: #352a12;
|
||||
--warning-muted-foreground: #fcd34d;
|
||||
--warning-border: #524019;
|
||||
|
||||
--caution: #facc15;
|
||||
--caution-foreground: #221e04;
|
||||
--caution-muted: #342e12;
|
||||
--caution-muted-foreground: #fde047;
|
||||
--caution-border: #4e4519;
|
||||
|
||||
/* Danger goes RED here, not rose: a rose "danger" beside a pink primary is
|
||||
indistinguishable, and this is the one colour that must never be missed. */
|
||||
--danger: #f43f3f;
|
||||
--danger-foreground: #2a0606;
|
||||
--danger-muted: #3d1418;
|
||||
--danger-muted-foreground: #fca5a5;
|
||||
--danger-border: #5c2128;
|
||||
|
||||
--info: #38bdf8;
|
||||
--info-foreground: #051d29;
|
||||
--info-muted: #0f2b3a;
|
||||
--info-muted-foreground: #7dd3fc;
|
||||
--info-border: #16485d;
|
||||
|
||||
--mx-call-conf: #22c55e;
|
||||
--mx-call-work: #2f7d55;
|
||||
--mx-dx-conf: #60a5fa;
|
||||
--mx-dx-work: #35538c;
|
||||
--mx-none: #3a2647;
|
||||
|
||||
--scrollbar-thumb: #4a3159;
|
||||
--scrollbar-thumb-hover: #644176;
|
||||
--card-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(238, 224, 240, 0.05);
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* ---- Theme 8: Nordic light — crisp cool white, indigo accent ----------- */
|
||||
[data-theme="light-nordic"] {
|
||||
--background: #eef1f7;
|
||||
--foreground: #1b2130;
|
||||
--card: #ffffff;
|
||||
--card-foreground: #1b2130;
|
||||
--popover: #ffffff;
|
||||
--popover-foreground: #1b2130;
|
||||
--primary: #4f46e5; /* indigo */
|
||||
--primary-foreground: #ffffff;
|
||||
--secondary: #dfe4ee;
|
||||
--secondary-foreground: #1b2130;
|
||||
--muted: #e2e7f0;
|
||||
--muted-foreground: #4a5468;
|
||||
--accent: #dcdcfb;
|
||||
--accent-foreground: #312a91;
|
||||
--destructive: #b91c1c;
|
||||
--destructive-foreground: #ffffff;
|
||||
--destructive-muted: #fef2f2;
|
||||
--destructive-muted-foreground: #b91c1c;
|
||||
--border: #c9d1e0;
|
||||
--input: #c9d1e0;
|
||||
--ring: #6366f1;
|
||||
|
||||
--success: #15803d;
|
||||
--success-foreground: #ffffff;
|
||||
--success-muted: #dcfce7;
|
||||
--success-muted-foreground: #14532d;
|
||||
--success-border: #86efac;
|
||||
|
||||
--warning: #b45309;
|
||||
--warning-foreground: #ffffff;
|
||||
--warning-muted: #fef3c7;
|
||||
--warning-muted-foreground: #92400e;
|
||||
--warning-border: #fcd34d;
|
||||
|
||||
--caution: #a16207;
|
||||
--caution-foreground: #ffffff;
|
||||
--caution-muted: #fef9c3;
|
||||
--caution-muted-foreground: #854d0e;
|
||||
--caution-border: #fde047;
|
||||
|
||||
--danger: #dc2626;
|
||||
--danger-foreground: #ffffff;
|
||||
--danger-muted: #fee2e2;
|
||||
--danger-muted-foreground: #991b1b;
|
||||
--danger-border: #fca5a5;
|
||||
|
||||
--info: #0369a1;
|
||||
--info-foreground: #ffffff;
|
||||
--info-muted: #e0f2fe;
|
||||
--info-muted-foreground: #075985;
|
||||
--info-border: #7dd3fc;
|
||||
|
||||
/* Entity ramp shifts to TEAL: indigo is the primary here. */
|
||||
--mx-call-conf: #15803d;
|
||||
--mx-call-work: #86efac;
|
||||
--mx-dx-conf: #0f766e;
|
||||
--mx-dx-work: #99f6e4;
|
||||
--mx-none: #dde3ec;
|
||||
|
||||
--scrollbar-thumb: #b6c0d2;
|
||||
--scrollbar-thumb-hover: #93a0b8;
|
||||
--card-shadow: 0 1px 2px rgba(27, 33, 48, 0.06), 0 0 0 1px rgba(27, 33, 48, 0.03);
|
||||
color-scheme: light;
|
||||
}
|
||||
|
||||
/* ── Data-viz palette (Statistics dashboard) ────────────────────────────────
|
||||
A VALIDATED categorical palette, not hand-picked: the slot ORDER is what makes
|
||||
it colour-blind-safe (worst adjacent ΔE 24.2 light / 10.3 dark), so never
|
||||
@@ -512,7 +792,8 @@
|
||||
:root,
|
||||
[data-theme="light-warm"],
|
||||
[data-theme="light-cool"],
|
||||
[data-theme="light-sage"] {
|
||||
[data-theme="light-sage"],
|
||||
[data-theme="light-nordic"] {
|
||||
--chart-1: #2a78d6; /* blue — default single-series hue */
|
||||
--chart-2: #1baf7a; /* aqua */
|
||||
--chart-3: #eda100; /* yellow */
|
||||
@@ -533,7 +814,10 @@
|
||||
[data-theme="dim-slate"],
|
||||
[data-theme="dark-warm"],
|
||||
[data-theme="dark-graphite"],
|
||||
[data-theme="high-contrast"] {
|
||||
[data-theme="high-contrast"],
|
||||
[data-theme="dark-indigo"],
|
||||
[data-theme="dark-teal"],
|
||||
[data-theme="dark-plum"] {
|
||||
--chart-1: #3987e5;
|
||||
--chart-2: #199e70;
|
||||
--chart-3: #c98500;
|
||||
@@ -681,7 +965,8 @@
|
||||
help. */
|
||||
Every temporal input carries the same glyph, so the rule names them all:
|
||||
datetime-local was left out at first and its icon stayed invisible. */
|
||||
:is([data-theme='dim-slate'], [data-theme='dark-warm'], [data-theme='dark-graphite'], [data-theme='high-contrast'])
|
||||
:is([data-theme='dim-slate'], [data-theme='dark-warm'], [data-theme='dark-graphite'], [data-theme='high-contrast'],
|
||||
[data-theme='dark-indigo'], [data-theme='dark-teal'], [data-theme='dark-plum'])
|
||||
:is(input[type='date'], input[type='datetime-local'], input[type='time'], input[type='month'], input[type='week'])::-webkit-calendar-picker-indicator {
|
||||
filter: invert(1) brightness(1.8);
|
||||
opacity: 0.9;
|
||||
|
||||
Reference in New Issue
Block a user