The cheap part is the hex code
People reach for the words "design system" when they mean "shared CSS file." A shared CSS file is necessary, but it is the cheap part. The expensive part — the part the system is actually for — is the agreement on what a radius is called. The hex code is trivia. The name is the contract.
When two engineers, separated by months and a JIRA ticket, both reach for
--radius-md, that is the system working. They have to agree on
very little: that there exists a thing called md, that it sits
between sm and lg, and that it is the right pick
for cards. Whether that resolves to 8px or 10px is, in the long run, less
important than whether they reach for the same name.
The disaster is when the name resolves to different values depending on which CSS file loaded last.
What the audit actually found
Week 1 of this sprint started with an inventory. We did not begin by writing tokens; we began by counting. The results:
- 1,016 unique CSS custom properties across six token files.
- 2,181 total lines of token declarations. About a third were duplicates with subtly different values.
- 14% of
box-shadowuses referenced a token; 86% were ad-hoc. - 8.5% of
z-indexuses referenced a token. 91.5% were integer literals. - ~10% of
border-radiusvalues were tokenized. The rest were pixel literals.
None of that is unusual — every codebase that has shipped for a year looks
like this. What was unusual was the cascade-order chaos. We found a 3-way
collision on --radius-md:
enterprise-tokens.cssset it to 8px.premium-b2b-tokens.cssset it to 8px.ypai-variables.cssset it to 16px.- The component using it ended up with 12px, because a fourth file shadowed both.
Same name. Four possible values. The actual resolved value depended entirely
on which file was last imported in global.css — a property no
engineer working on a single component could realistically check. That is
not a typing mistake. That is the system having no opinion about what
md means.
The z-index arms race
The other tell that the system has stopped meaning anything is the
integer-literal arms race. Counting unique z-index values across
src, we found:
-1, 0, 1, 2, 3, 10, 50, 100, 999, 1000, 9999, 10000, 10001, 99998, 99999, 100000, 100001
Seventeen distinct values. The 99998 → 100001 cluster is a fossil record of
two components losing a stacking fight: each one bumped its number by one,
then by ten, then by a thousand, hoping to win the cascade. None of them
fixed the actual problem (a parent position: relative creating
a new stacking context). All of them made it worse for the next engineer.
Renaming the seventeen values into eight semantic layers
(--ds-z-base through --ds-z-toast) does not magically
fix the underlying stacking-context bugs. What it does is make those bugs
nameable. "Toast is below modal" is a sentence you can argue about.
"9999 is below 99999" is a sentence that has already lost.
A design system is a vocabulary
The deeper claim is this: a design system's job is not to make your site look consistent. Consistency is a byproduct. The job is to give a team a shared vocabulary for visual decisions, so that "this card looks wrong" can resolve to a specific token, and "we should add a tighter radius" can resolve to a specific argument with a specific outcome.
Vocabularies have rules. They do not include every word; they include the words worth having. Our radius scale has eight steps because eight is enough — adding a ninth would mean every PR review has to debate which step a new component lands on. Our spacing scale is on a 4-point grid because the grid is the rule that lets us add a 17th value without re-litigating the rest.
A paint kit, by contrast, has no rules. It has paint. Anyone can mix new colors. The result is what we found in the audit: a thousand colors, no agreement on which is which, and a cascade-order roulette every time the page loads.
What this commits us to
The implication is operational, not aesthetic. From this point forward in the system:
- No literal
pxvalues in component styles. Every spacing, radius, shadow, and z-index must reference a--ds-*token. - No new tokens without a written reason. Adding
--ds-radius-xsrequired a one-paragraph defense of why we needed something smaller thansm. - Old tokens get migrated, not aliased. The
--radius-mdcollision is being resolved by a codemod (Week 3, 499 files, 8,814 replacements), not by a compatibility shim. - Lint rules guard the boundary. Magic z-index integers fail CI. Hex colors outside the token files fail CI.
The result is not that the site looks dramatically different. The site looked fine before. The result is that the next engineer who reaches for "the medium radius" gets the same value every time, and that argument nobody was having — about what 9999 means — can finally stop.