Browse all prompts
Extract a design token system
Replace the scattered hex codes and one-off spacing values in an existing project with a small, named token system in Tailwind 4's @theme — a value-preserving refactor first, with any consolidation proposed separately.
This project has accumulated colour and spacing values one commit at a time. Turn them into a token system. The visible design should not change — this is a refactor, and a screenshot before and after should be nearly identical. ## 1. Inventory first, decide later Go through the stylesheets and components and collect every hard-coded value: colours in any notation, font sizes, spacing, radii, shadows, transition durations. Group them by what they were trying to be, not by their value — `#1a1a1a`, `#181818` and `rgb(26,26,26)` are three attempts at one colour. Show me the inventory before you change anything, with a count per group. That count is the argument: seven near-identical greys is the finding. ## 2. Name them for their job A token is named for what it does, not what it looks like. `--color-surface`, not `--color-white`; `--color-ink-muted`, not `--color-gray-500`. The site will get a dark mode one day and `--color-white: black` is where that goes wrong. Keep the palette small — but extraction and consolidation are two steps, and this is the first one. Give every distinct value its own token even when two are nearly identical, then hand me a separate list of the merges you would make, with the callers each one touches. Two values being close is not proof they mean the same thing: a body colour and a border colour that happen to match today may need to diverge in dark mode, and merging two text colours can cross a contrast threshold. I decide the merges; you do not apply them in this pass. ## 3. Declare them in `@theme` Tailwind 4 has no config file. Tokens live in the CSS entry: ```css @import 'tailwindcss'; @theme { --color-surface: oklch(0.99 0.003 265); --color-ink: oklch(0.21 0.02 265); --color-ink-muted: oklch(0.52 0.02 265); --color-accent: oklch(0.62 0.18 265); --radius-control: 0.5rem; } ``` Use `oklch()` for colour. It makes "the same hue, a bit lighter" a change to one number, which is the whole reason to have tokens. Anything a consumer is meant to override goes through a public custom property with a private fallback, so overriding it does not require editing the component: ```css .thing { background: var(--component-thing-bg, var(--_thing-bg)); } ``` ## 4. Migrate the callers Replace the hard-coded values with the tokens, one group at a time. Every class name must appear complete somewhere Tailwind scans: `bg-surface` is fine, and so is picking between two complete class names with a conditional or a lookup map. What does not work is assembling one from fragments — `` `bg-${tone}` `` — because the finished name never appears in the source for the scanner to find. ## 5. Prove nothing moved Screenshot the main pages before and after and diff them. This pass preserves values, so the diff should be empty. Any pixel that moved is a mistake, not a consolidation — the merges are still a proposal at this point. Finish by telling me: how many distinct values you found, how many tokens you ended up with, the merges you are proposing and what each would change, and anything you left hard-coded on purpose.