Design token systems for color typically have three layers: primitive tokens (the raw color values), semantic tokens (meaning assignments), and component tokens (specific component bindings). The semantic layer is where most systems go wrong — it is the hardest to get right and the most consequential to get wrong.
**What semantic tokens are**
A semantic token maps a color primitive to an intended use: --color-text-primary maps to the brand's near-black; --color-surface-default maps to the page background. The semantic name expresses meaning (what is this for?) rather than appearance (what does it look like?). The central constraint: a semantic token must be rebindable to a different primitive without breaking any component that uses it. If --color-text-primary can be changed from near-black to a warm dark brown without breaking 300 components, the semantic layer is working. If changing it requires auditing every component, the semantic layer is broken or missing.
**The standard semantic categories**
Surface tokens define backgrounds: --surface-default, --surface-subtle, --surface-raised, --surface-overlay. Each maps to a lightness step in the scale; in dark mode, the same token maps to a different (usually dark) primitive. Text tokens define type colors: --text-primary, --text-secondary, --text-tertiary, --text-placeholder, --text-disabled, --text-inverse. Interactive tokens define UI control states: --interactive-default, --interactive-hover, --interactive-active, --interactive-disabled, --interactive-selected. Feedback tokens define status: --feedback-positive, --feedback-warning, --feedback-error, --feedback-info. Border tokens: --border-default, --border-strong, --border-focus. These categories cover 85-90% of token needs in most products.
**Common naming mistakes**
The most common semantic token error is including appearance information in the name. '--color-blue-500-text' is a broken semantic token — it reveals the primitive it's currently bound to, which means renaming the primitive (or rebranding to green) requires changing every consumer of the token. '--color-text-primary' is correct — it expresses meaning only. The second most common error is too much specificity: '--color-navbar-background' is a component token, not a semantic token. If you rename the navbar to 'topbar,' the token name is wrong. Semantic tokens should be abstract enough to apply to multiple components.
**Theming and dark mode as a correctness test**
The best test of a semantic token system is theming: can you implement dark mode, a high-contrast mode, or a brand variant by rebinding only the semantic-to-primitive mapping, without touching any component? If yes, the semantic layer is working correctly. If dark mode requires editing component files, the semantic layer has gaps — some components are consuming primitives directly instead of semantics. Most practical systems have some impurity here; the goal is minimizing it. Systems built as a clean semantic layer from the start handle dark mode, theming, and rebrand work an order of magnitude faster than those that bolt on theming later.
ColorArchive Notes
2029-08-18
Semantic Color Tokens: The Naming Layer Between Raw Color and Component
How to name the meaning layer of a color token system — the semantic tokens that map raw hue values to design intent and make theming, dark mode, and rebrand work correctly.
Newer issue
Conversion Color: How E-Commerce Brands Use Color Psychologically
2029-08-11
Older issue
Gradients in UI Design: When Decoration Becomes Function
2029-08-25
