Design Tokens in Pure CSS
- Date —
- July 1, 2026
- Tags —
- CSS, Design Systems
Most Tailwind projects define colors in tailwind.config.js. This site does it differently — six CSS custom properties on :root define every color, and Tailwind reads from them at runtime via @theme inline.
This means changing the entire color scheme requires editing five hex values. Dark mode swaps those five values by toggling a .dark class on <html>. No build step, no recompilation, no flash.
The tokens
:root { --paper: #f7f6f3; /* page background */ --ink: #15161b; /* primary text */ --ink-soft: #5b5d66; /* secondary text */ --signal: #3d3dff; /* the one accent color */ --line: #e4e2dc; /* borders, rules */ --surface: #efeeea; /* cards, raised panels */}
.dark { --paper: #101114; --ink: #f2f1ed; --ink-soft: #9a9ca6; --signal: #7b7bff; --line: #26272c; --surface: #1a1b20;}Every component uses Tailwind utilities like bg-paper, text-ink, text-signal that resolve to these variables. The typography plugin is also re-themed to use the same tokens instead of its default gray scale.
@theme inline { --color-paper: var(--paper); --color-ink: var(--ink); --color-ink-soft: var(--ink-soft); --color-signal: var(--signal); --color-line: var(--line); --color-surface: var(--surface);}The tradeoff is that you lose some of Tailwind’s color palette granularity. For a site this size, that’s not a real loss — and the consistency is worth it.