Semantic Tokens
Role-based token mappings for backgrounds, foregrounds, borders, and interactive states in light and dark modes.
Semantic tokens map functional roles to primitive colour values. Using semantic tokens instead of primitives means a single token change updates every element that uses that role — and dark mode is handled automatically.
Token structure
Semantic tokens are grouped into five categories:
bg — backgrounds
| Token | Role |
|---|---|
bg.base | Default page/panel background |
bg.subtle | Slightly elevated surface (sidebars, cards) |
bg.muted | Receded, secondary content areas |
bg.emphasis | High-contrast background (banners, emphasis panels) |
bg.inverse | Inverted background (dark surface on light theme) |
fg — foregrounds / text
| Token | Role |
|---|---|
fg.base | Primary text |
fg.muted | Secondary, supporting text |
fg.subtle | Tertiary, placeholder text |
fg.onInverse | Text on top of an bg.inverse surface |
fg.brand | Brand-colored text |
fg.accent | Accent/highlight text (indigo by default) |
border — borders
| Token | Role |
|---|---|
border.base | Default border |
border.muted | Lighter border for subtle dividers |
border.emphasis | Stronger border for focus/active states |
border.brand | Brand-colored border |
interactive — interactive states
| Token | Role |
|---|---|
interactive.primary | Primary action background |
interactive.primaryHover | Primary action hover background |
interactive.primaryActive | Primary action active/pressed background |
interactive.accent | Accent action background |
interactive.accentHover | Accent action hover |
interactive.accentActive | Accent action active |
surface — layered surfaces
| Token | Role |
|---|---|
surface.base | Base layer surface |
surface.raised | Elevated surface (modals, dropdowns) |
surface.overlay | Top-level overlay (tooltips, popovers) |
Light / dark themes
The semantic token map is defined twice — once for light and once for dark. The correct values are applied via a [data-theme] CSS attribute or media query, depending on how your app's theme switcher works.
/* simplified example */
[data-theme='light'] {
--bg-base: var(--color-white);
--fg-base: var(--color-black);
}
[data-theme='dark'] {
--bg-base: var(--color-grey-950);
--fg-base: var(--color-grey-50);
}Note: The semantic token values are currently being finalised. The structure above is the intended API; exact primitive mappings will be documented here as they are locked in.