15
1 min read
Theming without duplication
Dark mode built by copying every component and editing colors by hand is how you get two systems that drift apart by Friday.
The payoff of the whole model: components stay fixed. Only token values change per theme. Light, dark, and brand are alternate value sets over the same structure.
Same names. Same hops. button-bg still points at primary. primary still points at blue-600. The hex behind blue-600 is what moves.
A copied dark mode on the left — leftover light hexes. Same hops on the right, new primitive values.
Card
Learn morebutton#2563eb
border#e2e8f0
background#0f172a
Card
Learn moreprimary#60a5fa
border#1e293b
background#0f172a
The card, the input, and the button did not get rewritten. They resolved a different value set. That is a theme.
:root,
[data-theme="light"] {
--blue-600: #2563eb;
--slate-50: #f8fafc;
--slate-900: #0f172a;
}
[data-theme="dark"] {
--blue-600: #3b82f6;
--slate-50: #0f172a;
--slate-900: #f8fafc;
}
:root {
--color-primary: var(--blue-600);
--button-bg: var(--color-primary);
}
.button {
background: var(--button-bg); /* → primary → blue-600 */
}:root,
[data-theme="light"] {
--blue-600: #2563eb;
--slate-50: #f8fafc;
--slate-900: #0f172a;
}
[data-theme="dark"] {
--blue-600: #3b82f6;
--slate-50: #0f172a;
--slate-900: #f8fafc;
}
:root {
--color-primary: var(--blue-600);
--button-bg: var(--color-primary);
}
.button {
background: var(--button-bg); /* → primary → blue-600 */
}