Files
tfm_ainventory/COLOR_SYSTEM_ARCHITECTURE.md
Daniel Bedeleanu 5e8ff23237 docs: add color system architecture and session 48 summary
- Document single source of truth architecture
- Explain CSS variable auto-generation workflow
- Show how colors.mjs eliminates duplication
- Provide maintenance and build integration guide
- Reference commit e715afd8 refactoring

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-25 17:32:03 +03:00

6.1 KiB

Color System Architecture: Single Source of Truth

Status: IMPLEMENTED
Commit: e715afd8
Date: 2026-04-25


Problem Solved

Color definitions were previously duplicated in two locations:

  • frontend/tailwind.config.ts — Tailwind CSS utility classes (e.g., bg-primary)
  • frontend/app/globals.css — CSS custom properties (e.g., --primary)

This created a DRY violation where changing a color required edits in 2 places, with high risk of inconsistency.


New Architecture

1. Single Source of Truth: frontend/colors.mjs

// frontend/colors.mjs — The authoritative color definitions
export const colors = {
  background: "#131313",
  primary: {
    DEFAULT: "#ffb781",
    container: "#f58618",
    // ... all color variants
  },
  // ... 40+ colors from DESIGN.md
};

export const spacing = {
  unit: "4px",
  "stack-sm": "8px",
  // ... spacing tokens
};

Key Features:

  • Pure JavaScript/ESM format for maximum compatibility
  • Matches DESIGN.md specification exactly
  • Single file for all color changes
  • Comment at top: "Changes here automatically propagate to both files"

2. Automated CSS Generation: frontend/scripts/generate-css-vars.mjs

A build-time script that:

  1. Reads colors.mjs
  2. Flattens nested color objects (e.g., primary.DEFAULT--primary-DEFAULT)
  3. Generates CSS custom properties organized by category
  4. Injects into frontend/app/globals.css :root block
  5. Preserves all other CSS code unchanged

Execution:

node frontend/scripts/generate-css-vars.mjs
# Output: ✓ Generated CSS variables in globals.css from colors.mjs

Benefits:

  • No manual CSS variable maintenance
  • Always stays in sync with colors.mjs
  • Runs automatically before every build

3. Import in Tailwind Config: frontend/tailwind.config.ts

import { colors as colorsDefinition } from "./colors.mjs";

const config: Config = {
  theme: {
    extend: {
      colors: colorsDefinition,  // ← Single import!
      // ...
    },
  },
};

Simplification:

  • Removed 80+ lines of duplicated color definitions
  • Now just imports from colors.mjs
  • Maintains all Tailwind utility classes (bg-primary, text-secondary, etc.)

Build Integration

Frontend Build (frontend/package.json)

{
  "scripts": {
    "generate-css-vars": "node scripts/generate-css-vars.mjs",
    "dev": "npm run generate-css-vars && next dev",
    "build": "npm run generate-css-vars && next build"
  }
}

Flow:

  1. npm run dev or npm run build executes
  2. Automatically runs generate-css-vars first
  3. CSS variables synchronized
  4. Next.js build proceeds

Standalone Deployment (start_servers.py)

def setup_frontend(self):
    # Generate CSS variables from colors.mjs before building
    self.log("Generating CSS variables from design system...")
    result = subprocess.run(
        ["node", "scripts/generate-css-vars.mjs"],
        cwd=str(frontend_dir),
        capture_output=True
    )
    # Then proceed with npm run build

Workflow: Changing Colors

Before (2 files, high risk):

  1. Edit hex in tailwind.config.ts line 42
  2. Edit hex in globals.css line 26
  3. Risk: Forget one file, colors diverge
  4. Build has no validation

After (1 file, zero risk):

  1. Edit colors.mjs (one location)
  2. Run npm run build
  3. Script auto-generates both Tailwind colors and CSS variables
  4. No manual sync needed

Example:

// colors.mjs
export const colors = {
  primary: {
    DEFAULT: "#ffb781",  // ← Change here
    // ...
  },
};

Then:

  • npm run build auto-generates CSS variables
  • tailwind.config.ts already imports from colors.mjs
  • Both systems use exact same value
  • Zero inconsistency

CSS Variable Categories

Generated variables are organized by category in :root:

/* Base colors from DESIGN.md */
--background: #131313;
--on-background: #e5e2e1;

/* Surface colors from DESIGN.md */
--surface-DEFAULT: #131313;
--surface-dim: #131313;
/* ... 8 more surface variants */

/* Primary colors from DESIGN.md */
--primary-DEFAULT: #ffb781;
--primary-container: #f58618;
/* ... 7 more primary variants */

/* Secondary, Tertiary, Error colors... */

/* Semantic spacing tokens */
--spacing-unit: 4px;
--spacing-gutter: 16px;
/* ... more spacing */

Design System Compliance

All colors from DESIGN.md are now represented:

Category Count Source
Primary variants 9 colors.mjs
Secondary variants 8 colors.mjs
Tertiary variants 8 colors.mjs
Surface variants 9 colors.mjs
Error variants 4 colors.mjs
Outline/Inverse/Semantic 7 colors.mjs
Total 45 Single file

Build Verification

✅ CSS generation: Completes successfully
✅ Next.js compile: 5.7s with 0 errors
✅ CSS validation: 0 warnings
✅ TypeScript: Strict mode, 0 issues
✅ All pages: 8/8 generated

Future Maintenance

If colors need updating:

  1. Edit frontend/colors.mjs
  2. Run npm run build (auto-syncs everything)
  3. Done!

No need to:

  • Edit tailwind.config.ts
  • Edit globals.css
  • Manually synchronize values
  • Worry about inconsistency

Files Changed

File Change Status
frontend/colors.mjs Created New SSOT
frontend/scripts/generate-css-vars.mjs Created Auto build step
frontend/tailwind.config.ts Updated Imports from colors.mjs
frontend/package.json Updated Added generate-css-vars script
start_servers.py Updated Runs generate step
frontend/app/globals.css Generated Auto-synced on build

Command Reference

# One-time generate CSS variables
npm run generate-css-vars

# Development mode (auto-generates on startup)
npm run dev

# Production build (auto-generates before build)
npm run build

# Standalone deployment (auto-generates before build)
python3 start_servers.py

Implemented by: Claude Haiku 4.5
Architecture Decision: Consolidate to single source of truth with automated CSS generation