04
1 min read
Component tokens
Semantic tokens get you close. A component still needs its own vocabulary. A button has a background, a foreground, a border, a radius.
Component tokens are the last hop. button-bg points to primary. button-radius points to radius-md. The button stays ignorant of raw values and still ends up fully specified.
This is also where variants attach. A destructive button doesn't restyle itself with a hex. It points button-bg at destructive.
Delete on the left owns a hex. On the right it points button-bg at destructive. Same paint. A different hop.
Save#2563eb
Delete#dc2626
Savebutton-bg → primary
Deletebutton-bg → destructive
You never opened the button. A variant is a retarget, not a restyle.
:root {
--blue-600: #2563eb;
--red-600: #dc2626;
--color-primary: var(--blue-600);
--color-primary-foreground: #f8fafc;
--color-destructive: var(--red-600);
--color-border: #e2e8f0;
--radius-md: 8px;
--button-bg: var(--color-primary);
--button-fg: var(--color-primary-foreground);
--button-border: var(--color-border);
--button-radius: var(--radius-md);
}
.button--destructive {
--button-bg: var(--color-destructive);
}:root {
--blue-600: #2563eb;
--red-600: #dc2626;
--color-primary: var(--blue-600);
--color-primary-foreground: #f8fafc;
--color-destructive: var(--red-600);
--color-border: #e2e8f0;
--radius-md: 8px;
--button-bg: var(--color-primary);
--button-fg: var(--color-primary-foreground);
--button-border: var(--color-border);
--button-radius: var(--radius-md);
}
.button--destructive {
--button-bg: var(--color-destructive);
}