Skip to content
ColorArchive
Design Systems
Search intent: design tokens color token architecture CSS variables semantic tokens primitive tokens dark mode Tailwind Style Dictionary DTCG design system

Color Token Architecture: Building Maintainable Design Token Systems

A poorly designed token architecture makes dark mode a two-week rebuild. A well-designed one makes it a two-hour configuration change. This guide covers the structural principles — primitive, semantic, and component tier design — that determine how maintainable your color system is over time.

Design TokensDesign SystemsCSS VariablesTailwind
Key points
The two-tier primitive/semantic split is the minimum viable token architecture. Primitive tokens are raw values (--color-blue-500: #3b82f6). Semantic tokens are intent references (--color-interactive-primary: var(--color-blue-500)). Components use the semantic tier only — this means changing blue-500's hex updates everything that references interactive-primary automatically.
Semantic token naming should describe function, not appearance. --color-text-default is correct. --color-text-dark-gray is wrong — it describes the current value, not the purpose. When dark mode makes text light, --color-text-dark-gray becomes actively misleading. Test: can this token name remain accurate in dark mode and high-contrast mode? If not, it describes appearance, not function.
CSS custom properties are the broadest-compatible output format and integrate directly with Tailwind 4. JSON is most portable for cross-platform systems. DTCG (Design Tokens Community Group) format, now supported by Tokens Studio, adds type and description metadata. For web-only systems, CSS custom properties from a simple JSON source is sufficient; for multi-platform systems, DTCG + Style Dictionary is current best practice.

Structuring the primitive layer

The primitive layer contains every color value the system will ever use, organized by hue. A full-scale primitive palette typically contains 6-12 hues × 8-12 lightness steps = 48-144 raw values. For dark mode, a linear lightness scale (100, 200... 900) makes it easy to find semantic equivalents by inverting steps: what was step 200 in light mode becomes step 800 in dark mode. HSL-based steps work better for this inversion than OKLCH steps because HSL inversion is predictable. OKLCH produces more perceptually consistent steps — systems built for multiple brand themes benefit from OKLCH primitives despite the inversion complexity.

When to add the component tier

Component tokens are the third tier many systems add: --color-button-primary-background: var(--color-interactive-primary). This allows consumers to override button styles without modifying the global semantic layer. Add the component tier only when the system has confirmed use cases for component-level overrides. A three-tier token system is significantly more complex to document and maintain — adding it speculatively creates documentation debt before the use case arrives. For most in-house design systems serving a single product team, two tiers are sufficient and easier to keep current.

Practical next step

Move from the guide into a concrete palette lane

Guides explain the use case. Collections prove the taste. Packs handle the export and implementation layer.

Related guides