Tokens · Layer 2
Semantic tokens
What a value means, independent of which component uses it. This is the layer to reach for by default — it is stable across redesigns, and it is the only layer a second theme has to reassign.
Start here
When you are unsure which token to use, the answer is almost always a semantic one. Component tokens are for retheming a single component; primitives are not for components at all.
BrowsePermalink to this section
Each row shows the primitive it resolves to, so the full chain is visible without opening another page.
Choosing between similar tokensPermalink to this section
A few pairs come up repeatedly in review. These are the distinctions worth memorising.
| Use | Not | Because |
|---|---|---|
--muted-foreground | --faint-foreground | Faint is for placeholders and disabled labels only. At 13px it is borderline for body text. |
--border-default | --border-subtle | Subtle is for dividers inside a single component. Card and input outlines use default. |
--surface | --surface-raised | Raised is white on white — it only reads as raised when a shadow or border accompanies it. |
--brand-primary | --interactive-accent | Brand is for actions and active state. The interactive accent is for inline links. |
--danger | --warning | Danger means something failed or will be destroyed. Warning means it still works, but needs attention. |
NamingPermalink to this section
Semantic names describe a role in the interface. If a name mentions a colour or a component, it belongs in a different layer.
foreground / backgroundThe default pair. Everything else is a deviation from these.-muted, -faintDescending emphasis. Never invent a fourth step.-hover, -softState and tint modifiers, applied consistently across every family.surface-, border-, action-, status-Role prefixes. The prefix says where the token is allowed to appear.