Theme Token Architecture Playbook
Scope
This guide turns CSS variables into a long-term contract for components, teams, and product surfaces.
Token Layers
Use three layers:
- primitive tokens (raw palette and spacing values)
- semantic tokens (surface, text, border, accent, success)
- component tokens (optional per-component aliases)
Naming Rules
- stable prefixes:
--color-*,--spacing-*,--radius-*,--shadow-*,--transition-* - avoid intent-less names such as
--blue-1in component code - component files consume semantic tokens only
Theme Model
Define light defaults in :root and dark overrides in [data-theme="dark"].
:root {
--color-bg: #ffffff;
--color-surface: #f8f9fa;
--color-text: #1a1a1a;
--color-border: #d1d5db;
--color-primary: #0066cc;
}
[data-theme="dark"] {
--color-bg: #0a0a0a;
--color-surface: #161b22;
--color-text: #f3f4f6;
--color-border: #374151;
--color-primary: #3b82f6;
}Derived Values
Use color-mix() for hover, focus, and subtle gradients. This keeps derivatives linked to core semantic tokens.
Accessibility Contract
- all text combinations must pass WCAG AA
- maintain explicit tokens for text on accent and text on warning
- keep disabled states distinct from muted states
Token Governance
Create a change policy:
- add before rename
- deprecate with comment and migration ticket
- remove only after usage count reaches zero
Migration Strategy
When replacing token names:
- add new token aliases
- update components gradually
- run contrast validation
- remove deprecated aliases in a later release
Testing Strategy
Unit:
- token parser and fallback logic
Integration:
- critical components snapshot in light and dark themes
- contrast checks over core semantic pairs
Regression:
- check that no component style introduces hardcoded colors
Operational Checks
- monitor contrast validator in CI
- monitor token growth to avoid uncontrolled sprawl
- maintain token docs with examples and intended usage
Anti-patterns
- hardcoding color values in component files
- making dark theme a separate stylesheet with duplicated rules
- encoding business meaning into primitive token names