App colors as named tokens
Put priority and status colors in the theme, then use them as utilities.
From shadcn (Vercel plugin), “Custom Colors”.
Change a color once
Drag the hue, then count the edits each list needs.
Raw values in each rowBad
text-[oklch(0.637_0.237_15.163)]
Named theme tokenGood
text-priority-urgent
/* app/globals.css */
@theme inline {
--color-priority-urgent: oklch(0.637 0.237 15.163);
--color-priority-high: oklch(0.705 0.213 47.604);
--color-status-done: oklch(0.723 0.219 149.579);
}
<span className="text-priority-urgent">Urgent</span>
Redefine per mode
Switch modes and read each badge’s contrast.
One palette classBad
text-red-700 bg-red-700/10Token, value per modeGood
text-priority-urgent:root {
--priority-urgent: oklch(0.505 0.213 27.518);
--priority-high: oklch(0.47 0.157 37.304);
--status-done: oklch(0.448 0.119 151.328);
}
.dark {
--priority-urgent: oklch(0.704 0.191 22.216);
--priority-high: oklch(0.75 0.183 55.934);
--status-done: oklch(0.792 0.209 151.711);
}
@theme inline {
--color-priority-urgent: var(--priority-urgent);
--color-priority-high: var(--priority-high);
--color-status-done: var(--status-done);
}
Name the meaning, not the hue
Move urgent to a new hue. Which name still holds?
Named by hueBad
Urgent
className="text-red"
--color-redNamed by meaningGood
Urgent
className="text-priority-urgent"
--color-priority-urgent@theme inline {
--color-priority-urgent: oklch(0.637 0.237 15.163);
}
Why it matters, pros and cons
Why it matters
Priority and status are design language, so they belong in the theme.
Pros
- One edit recolors every badge.
- Light and dark values sit beside shadcn’s.
- Names read as intent, not hue.
Cons
- Every token is a name to maintain.
- Near-duplicates like urgent, critical, blocker become sprawl.
@theme inlineutilities need Tailwind v4.