refactor: consolidate color definitions into single source of truth

- Create frontend/colors.mjs as SSOT for all design colors
- Create scripts/generate-css-vars.mjs to auto-generate CSS variables
- Update tailwind.config.ts to import colors from colors.mjs
- Update frontend/package.json: add 'generate-css-vars' script to build pipeline
- Update start_servers.py: include CSS variable generation before npm build
- All color changes now require only one edit in colors.mjs
- Build process auto-syncs CSS variables and Tailwind colors

Eliminates DRY violation where colors were duplicated in:
  - tailwind.config.ts (Tailwind utility classes)
  - globals.css (CSS custom properties)

Single source of truth approach ensures:
  ✓ No inconsistency between Tailwind and CSS variables
  ✓ One place to update colors for all contexts
  ✓ Automated CSS variable generation on every build

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-04-25 17:31:25 +03:00
parent de1708a754
commit e715afd814
11 changed files with 281 additions and 264 deletions

View File

@@ -5,14 +5,16 @@
@tailwind utilities;
@layer base {
:root {
:root {
/* Base colors from DESIGN.md - AUTO-GENERATED from colors.mjs */
/* Base colors from DESIGN.md */
--background: #131313;
--on-background: #e5e2e1;
--foreground: #e5e2e1;
/* Surface tones from DESIGN.md */
--surface: #131313;
/* Surface colors from DESIGN.md */
--surface-DEFAULT: #131313;
--surface-dim: #131313;
--surface-bright: #3a3939;
--surface-container-lowest: #0e0e0e;
@@ -23,41 +25,41 @@
--surface-variant: #353534;
/* Primary colors from DESIGN.md */
--primary: #ffb781;
--on-primary: #4e2600;
--primary-DEFAULT: #ffb781;
--primary-foreground: #4e2600;
--primary-container: #f58618;
--on-primary-container: #5b2d00;
--primary-on-container: #5b2d00;
--primary-fixed: #ffdcc4;
--primary-fixed-dim: #ffb781;
--on-primary-fixed: #2f1400;
--on-primary-fixed-variant: #6f3800;
--inverse-primary: #924c00;
--primary-on-fixed: #2f1400;
--primary-on-fixed-variant: #6f3800;
--primary-inverse: #924c00;
/* Secondary colors from DESIGN.md */
--secondary: #c8c6c5;
--on-secondary: #303030;
--secondary-DEFAULT: #c8c6c5;
--secondary-foreground: #303030;
--secondary-container: #474746;
--on-secondary-container: #b7b5b4;
--secondary-on-container: #b7b5b4;
--secondary-fixed: #e5e2e1;
--secondary-fixed-dim: #c8c6c5;
--on-secondary-fixed: #1b1c1c;
--on-secondary-fixed-variant: #474746;
--secondary-on-fixed: #1b1c1c;
--secondary-on-fixed-variant: #474746;
/* Tertiary colors from DESIGN.md */
--tertiary: #00e639;
--on-tertiary: #003907;
--tertiary-DEFAULT: #00e639;
--tertiary-foreground: #003907;
--tertiary-container: #00bd2d;
--on-tertiary-container: #00440a;
--tertiary-on-container: #00440a;
--tertiary-fixed: #72ff70;
--tertiary-fixed-dim: #00e639;
--on-tertiary-fixed: #002203;
--on-tertiary-fixed-variant: #00530e;
--tertiary-on-fixed: #002203;
--tertiary-on-fixed-variant: #00530e;
/* Error colors from DESIGN.md */
--error: #ffb4ab;
--on-error: #690005;
--error-DEFAULT: #ffb4ab;
--error-foreground: #690005;
--error-container: #93000a;
--on-error-container: #ffdad6;
--error-on-container: #ffdad6;
/* Outline colors from DESIGN.md */
--outline: #a48c7c;
@@ -67,15 +69,25 @@
--inverse-surface: #e5e2e1;
--inverse-on-surface: #313030;
/* Semantic colors from DESIGN.md */
--border: #353534;
--muted: #9f9e9d;
--info: #64b5f6;
--success: #00e639;
--warning: #ffb781;
--alert: #ffb4ab;
/* Semantic spacing tokens */
--spacing-unit: 4px;
--spacing-stack-sm: 8px;
--spacing-stack-md: 16px;
--spacing-gutter: 16px;
--spacing-margin: 32px;
--spacing-container-gap: 24px;
--spacing-stack-sm: 8px;
--spacing-stack-md: 16px;
}
* {
@apply border-border;
border-radius: 0 !important;