An LLM-Safe Design System
Bibel TV
Tokens have always been a guideline. This is what changed when the build started enforcing them, and when the people prototyping were not designers.
- 32
- Off-system values found in a library believed clean
- 6
- Checks, identical locally and in CI
- 8
- Token gaps the system reported on itself
The problem
Bibel TV has no in-house design team. That single fact determines the shape of everything else.
There is no designer to ask when something is ambiguous. There is no team maintaining a Figma library as the canonical reference. And most consequentially, there is nobody whose job it is to catch drift in review.
Every design system I have worked on has the same soft spot. The tokens exist, the naming is thought through, the documentation is written, and then enforcement is a person noticing. Tokens are a convention held up by attention. When nobody is paid to pay that attention, the convention is decorative.
So the direction was set before any of this tooling existed. Storybook would become the source of truth rather than a Figma file: one place where the components are real, runnable and inspectable, with a prototyping layer on top. A new design language and thirty new components were landing, and the people who needed to build with them were product managers and engineers.
What I had not accounted for
How fast that gets away from you once an AI assistant is in the loop.
Prototyping the Android redesign myself, I watched it confidently reference tokens that did not exist, and quietly hardcode values where a token did.
Both mistakes compile. Both render.
A hallucinated token name falls back silently and looks approximately right. A hardcoded value looks exactly right, and stays invisible until someone changes the palette and one card does not move. I know that system as well as anyone does, and I still could not catch either of them by reading.
That is what turned a documentation problem into an enforcement problem. The docs were already good. What was missing was a mechanism that does not depend on anyone reading them. In an organisation without a design team, the build is the only reviewer that always shows up.
Three layers, doing three different jobs
The build refuses off-system work. Six checks, one command, identical locally and in CI. Two are new and cover exactly the mistakes I had made myself. One rejects a reference to a token that does not exist. The other rejects a colour, size or duration written straight into a component. The rest guard the palette against acquiring a second grey, and protect the token names our implementation partner builds against.
The vocabulary is handed over, not remembered. An assistant asked to recall a token name will produce something plausible. Asked to choose from an enumerated list of the valid ones, it cannot invent. The same closed vocabulary, the system's conventions, and the checks themselves are exposed as tools it can call, so the compliant path is also the fastest one.
Storybook is where the system becomes visible. You cannot prototype with components you have never seen. Storybook is the shared surface: every component, every state, in light and dark, at phone through TV size, so a product person can find the right thing before writing anything.
The three layers compound. Storybook makes the system legible, the vocabulary makes the right answer reachable, and the build makes the wrong answer visible before it ships. Any one of them alone would have been a partial fix.
Twelve pixels is not twelve pixels
A check that only says no is useless to a product manager. So failures name the token to use instead. The first version of that was quietly dangerous.
It was looking at a font size of 12px. It found a token holding exactly 12px and offered it as the fix. That token was a spacing value. Taking the suggestion would have compiled, rendered pixel-identical, passed review, and welded the size of our body text to the gap between two cards. Months later, tightening a layout would have changed the typography. I had written that suggestion engine an hour earlier, and I had written it to be helpful.
Two numbers matching is a coincidence, not a relationship. Suggestions are now constrained to the property's own family, and a component's token is only ever offered to that component. Where nothing qualifies, the check says nothing at all.
That silence is the part I would defend hardest. It means the system genuinely has no name for this decision yet, which is a finding worth surfacing rather than a hole worth filling with the nearest number that fits. For someone who does not know the catalogue, a confidently wrong suggestion is worse than no suggestion.
Catching what reading cannot
The same audit compared every web component against the native app it mirrors. One of the things it surfaced: a card's fallback gradient was aliased one layer too deep in light mode, so where the app rendered a soft ramp, the web rendered flat white. Nobody had spotted it, because there was nothing visibly broken to spot. Just a gradient quietly not being a gradient.
That is the class of defect this work exists for. It is not a crash and it is not ugly. It is the system slowly ceasing to mean what it says.
The escape hatch became the roadmap
Some values genuinely are not design decisions. A black stop inside a mask gradient is alpha arithmetic. An icon font's optical size is not a brand token. A rule with no exit gets worked around, so there is a documented one: annotate the line with a reason. Every annotation is recorded, and adding one fails the build until that record is updated, so an exception can never be taken quietly.
Then the register started telling me something I had not designed it to say. Of the sixteen exceptions in the system, eight say some version of "a token should exist here and does not." Written by whoever hit the friction, at the moment they hit it, with the reason attached.
That is a better backlog than I would have written from a workshop. It is in priority order by definition: the gaps people actually walk into, ranked by how often they walk into them.
Trusting the tooling, carefully
All thirty components were audited against the native source. Then every substantive finding was handed to an independent reviewer whose instruction was to refute it.
Eleven of forty-six did not survive. Roughly a quarter would have become confident, well-argued, wrong changes to a client's design system. The same scepticism that motivated the checks had to be applied to the tooling that found the problems. Otherwise I would have automated the production of plausible mistakes instead of the prevention of them.
The findings worth the whole exercise were the ones that changed the question. More than once, something that looked like a missing token name turned out to be a genuine difference in how two platforms behaved. That needs a design decision, not a rename.
What changed
Enforcement moved from a written convention checked by whoever noticed in review, to six checks that fail the build before off-system work lands. Prototyping moved from something only people who already knew the token catalogue could do, to something anyone can attempt: describe a change and get an on-system result, or a named and actionable refusal.
Hidden drift moved from invisible to counted. A library believed clean after two cleanup passes gave up thirty-two off-system values, including a category nobody had thought to look at. And token gaps moved from being discovered in review, or never, to the system reporting its own.
Someone who has never opened the token file can now describe what they want, make the cards rounder, and get either a change that uses the real system or a refusal that names what is missing. Never a silent off-system change that looks fine in a screenshot and fails six months later when the palette moves.
Because the enforcement sits on the token source rather than on one platform's components, the same guarantee reaches Android, iOS, web and Figma. That includes the implementation partner building against those names, who now gets a breaking change announced instead of discovered.
What I took from it
I used to think design authority lived in the Figma library and the review. It lives in whatever the build refuses. Everything else is advice.
The strongest version of this makes off-system code impossible to express at all: a constrained set of primitives where the wrong thing simply will not compile. I scoped it and declined it, for now. It is a large migration whose cost is certain and whose benefit is still unmeasured, checks that fail the build may prove sufficient, and every constraint has a cost at the edges while this system is still gaining tokens weekly. The exception register is the instrument that decides it. If it grows, the stricter version earns its migration. If it stays small and every entry stays honest, it does not.