Most "design systems" are a Figma file with named colours and a component library that ignores them. The gap shows up six months in, when a rebrand means grepping for #7E0F13 across two hundred files.
Measure, do not estimate
Start by making the tokens true. The brand colours on this site were sampled pixel-exact from the logo rather than eyeballed: the maroon is #7E0F13, taken from a clean 216×216 block of the mark; the wordmark ink is #201E1D.
That precision has a consequence people miss. Both of those are warm-shifted, so the neutral ramp has to be warm too. A cold grey scale beside a warm logo reads as a mismatch even to someone who cannot say why.
One source, generated utilities
Tailwind v4 takes tokens in a CSS @theme block and generates utilities from them, so --color-brand-700 becomes bg-brand-700 automatically. There is no second JavaScript config to drift out of sync, and a component that wants the brand colour has a named way to ask for it that is shorter than writing the hex.
Make the correct path the easy path and the rule enforces itself.
Contrast is part of the token
Record the measured contrast ratio next to each neutral: body copy at 8.7:1, muted copy at 5.4:1. Then "is this accessible" stops being a judgement call at review time and becomes a property of the token you already chose.
Some tokens have to change per language
This is the part a single-language design system never has to think about. Letter-spacing is the clearest example: a small positive tracking value on an uppercase Latin eyebrow looks deliberate, and the same value applied to Arabic breaks the cursive joins between letters. It is not a stylistic preference, it is a rendering defect.
So tracking is a token whose value is zeroed under the Arabic locale, and the utility that applies it resolves the token rather than hardcoding a value. Line height is the same story: Arabic needs more of it at the same size to stay comfortable, and the type scale carries that rather than leaving each component to discover it.
Logical properties, or the system only works one way
padding-left is a bug in a bilingual product. Every spacing, border and position token has to be expressed logically — inline-start and inline-end rather than left and right — so direction becomes an attribute on the document rather than a second stylesheet.
The same applies to anything with direction baked into it: a chevron in a "next" button mirrors, a play button does not, and a logo never does. Those are decisions that belong in the component, recorded once, rather than made again per screen by whoever is building it.
A token nobody can find is not a token
Adoption is the whole point, and it is a documentation problem as much as an engineering one. If a developer has to read the theme file to discover that a muted text colour exists, they will reach for a near-miss they already know instead.
Which is why the naming matters more than the palette: tokens named for their role — ink-500 for secondary text, paper for a raised surface — get used correctly, and tokens named for their appearance get used wherever the appearance happens to fit.
Say what a token is not for
The most useful line in our token file is a restriction: the brand maroon is an accent on white, never a large flood behind body text and never a gradient. A token system that only says what things are will still let someone build something off-brand out of entirely on-brand colours.
