feat(themes): consolidate UI CSS properties into theme registry

- Add darkUI and lightUI objects with all 25 CSS custom properties
- Add applyThemeUI() function to apply CSS vars via JavaScript
- Update useTheme.js to call applyThemeUI() instead of setAttribute
- Remove [data-theme="dark"] and [data-theme="light"] from index.css
- Custom themes can now override individual UI properties with cascade
- Update README.md to document the ui key and cascade behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Matt 2026-05-01 16:17:26 +00:00
commit f0acea33a0
4 changed files with 191 additions and 93 deletions

View file

@ -4,6 +4,10 @@
NAVI DESIGN TOKENS
Warm grays, sage greens, khaki tans, deep blacks.
No blue in UI chrome.
NOTE: Color tokens (--bg-*, --text-*, --border, etc.)
are now applied via applyThemeUI() in src/themes/registry.js.
Each theme defines its own ui object with CSS custom properties.
*/
:root {
@ -19,80 +23,6 @@
--text-lg: 1.125rem; /* 18px */
}
/* ═══ DARK MODE (default) ═══ */
[data-theme="dark"] {
--bg-base: #1c1917; /* warm off-black (was #0f1210) */
--bg-raised: #252220; /* raised surface (was #181d1a) */
--bg-overlay: #2e2a27; /* overlay/dropdown (was #1e2522) */
--bg-input: #201d1a; /* input fields (was #141a16) */
--text-primary: #dde3dc;
--text-secondary: #8f9a8e;
--text-tertiary: #5e6b5d;
--text-inverse: #1c1917;
--border: #3a3530; /* warm brown-gray (was #2a3329) */
--border-subtle: #2a2624; /* (was #1f261e) */
--accent: #7a9a6b; /* sage green — interactive states */
--accent-hover: #8fad7f;
--accent-muted: #3d4d36;
--tan: #b8a88a; /* khaki — secondary highlights */
--tan-muted: #4a4235;
--pin-origin: #6b8f5e; /* sage */
--pin-destination: #a67c52; /* rust/tan */
--pin-intermediate: #6b7268; /* warm gray */
--pin-stroke: #1c1917;
--status-success: #6b8f5e;
--status-warning: #b89a4a;
--status-danger: #a65c52;
--route-line: #7a9a6b;
--shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
--shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.5);
}
/* ═══ LIGHT MODE ═══ */
[data-theme="light"] {
--bg-base: #ddd2b9; /* warm khaki-tan (was #ece8e1) */
--bg-raised: #e8dec8; /* raised surface (was #f5f2ec) */
--bg-overlay: #e3d9c1; /* overlay/dropdown (was #f0ece5) */
--bg-input: #e8dec8; /* input fields (was #f5f2ec) */
--text-primary: #1a1d1a;
--text-secondary: #4f5a49; /* darkened for WCAG AA on new base (was #5c6558) */
--text-tertiary: #7a8674; /* darkened proportionally (was #8a9486) */
--text-inverse: #f5f2ed;
--border: #c4b89e; /* warmer border (was #d4cfc5) */
--border-subtle: #d5cab2; /* warmer subtle border (was #e8e3db) */
--accent: #4a7040;
--accent-hover: #3d5e35;
--accent-muted: #dce8d6;
--tan: #8a7556;
--tan-muted: #f0e8d8;
--pin-origin: #4a7040;
--pin-destination: #8a5c35;
--pin-intermediate: #6b6960;
--pin-stroke: #1a1d1a;
--status-success: #4a7040;
--status-warning: #8a7040;
--status-danger: #8a4040;
--route-line: #4a7040;
--shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
--shadow-lg: 0 4px 16px rgba(0, 0, 0, 0.12);
}
/* ═══ BASE STYLES ═══ */
html, body, #root {
margin: 0;