Dark theme
Activated via [data-theme="dark"] on <html> or any subtree. Light is untouched. Matter's warm-neutral palette inverts cleanly:
Flip the theme — live
Side-by-side
light
Card title
Surface · elevated · hairline · primary ink. Token names resolve through both modes.
dark
Card title
Surface · elevated · hairline · primary ink. Token names resolve through both modes.
Token rebind
| Token | Light | Dark |
|---|---|---|
--surface-page | #FFFFFF | #0D0D0D |
--surface-elevated | #FFFFFF | #1A1815 |
--text-primary | #0D0D0D | #F4F1EC (warm white, never #FFF) |
Bloom palette stays — reads as ambient warmth on dark. Each bloom drops α by ~30%.
The dark contract
The semantic ring (--surface-*, --text-*, --line-*, --shadow-*) rebinds under [data-theme="dark"]. Components author only against the ring. Authoring against primitives (var(--peach-3) from a component) breaks the dark contract.
Imports
@import "@matter/tokens/css"; /* primitives */
@import "@matter/tokens/css/canonical"; /* semantic ring — light defaults */
@import "@matter/tokens/css/dark"; /* dark overrides on [data-theme="dark"] */Consume the semantic ring exclusively. Flipping
data-theme repaints everything correctly.Don't reference
#FFF or primitive tokens directly from a component. Both break the dark theme.