······
····
Design SystemsMar 5, 2026

Tokens, not colors

Two-layer token system

Primitive

zinc-950
zinc-900
zinc-800
zinc-500
zinc-100
cyan-400

Semantic

--bg-basezinc-950
--surfacezinc-900
--borderzinc-800
--text-mutedzinc-500
--text-primaryzinc-100
--accentcyan-400

Components reference semantic tokens only. Switching theme remaps values — components unchanged.

Most projects start with a color palette—a Figma file with named swatches. Then the same hex value gets copy-pasted into thirty component files. When the brand updates, a developer spends a day doing find-and-replace, misses three occurrences, and ships a half-updated product. This is the cost of working with colors instead of tokens.

Tokens name intent, not value. --color-surface-primary doesn't tell you it's #0a0a0e; it tells you it's the primary surface. That separation is what makes theming, dark mode, and brand updates mechanical instead of laborious. Change the value in one place, and every component that uses the semantic name updates automatically.

We build in two layers. Primitive tokens define the raw palette—every color, spacing step, and radius the brand uses. Semantic tokens reference primitives and name what they mean in context. Components only reference semantic tokens. This is the same model Figma Variables uses, which means the handoff from design to code is a mapping exercise, not a translation.

The practical outcome is that dark mode is not a second design. It's a second token mapping. The components don't change—only the layer that says what --color-surface-primary resolves to changes. We've shipped complete dark mode implementations in a day on projects where every component was already using semantic tokens.