The class that did not win
A design-system button could not be changed with a class. Two Panda classes for the same property both stayed on the element, and the wrong one won. Nothing in the toolchain can see it.
Date: 2026-11-09. Context: building the chat page (feat/chat).
What happened
The chat has three starter questions, shown as outline Buttons. On a phone the longest one ran past
the edge of its card. The cause was clear: the design system's Button is white-space: nowrap.
The fix looked trivial. Button takes a className, so I passed one:
<Button className={css({ whiteSpace: "normal", h: "auto", py: "2" })}>…</Button>It type-checked, the linter and the benchmark's graders found nothing (the values are tokens), and
the page did not change. In the browser the button's class list held both white-space_nowrap
(from the component) and white-space_normal (from my css()), and the computed style was
nowrap.
The component joins its classes with cx(buttonRecipe(...), className). Panda's cx concatenates
class names; it does not merge them. Panda's styles are atomic, one class per property and value,
and when two classes set the same property the one that comes later in the stylesheet wins, which has
nothing to do with which one was passed last. Only css() merges, and only inside one call.
What we learned
- An override can fail without an error, anywhere. The compiler sees a valid
className. The linter sees a valid token. The graders see a valid style value. The page is the only place where the override is visibly not applied, and only to someone who looks. - This is how an agent will hit it. "Make this button wrap" is exactly what an agent given a
design system will try, with exactly this line. It will write a clean, token-correct override that
does nothing, and may then pile on more (
!important, a wrapper, an inlinestyle) to make it work. Those are the mistakes the graders do count, caused by one the toolchain cannot see. - The design system could have prevented it. A component that merges its recipe and the caller's
classNamewithcss(recipe, className)-style merging (Panda'scxwithcssobjects, or acssprop) lets a caller override. Or it can refuse: say plainly that it does not take overrides. Silently ignoring one is the worst of the three. - I did not fight it. The starter buttons now have short labels that fit, and send the full question when clicked. Working with the component, not against it, is what the system asks of an agent too.
What it means for Vektos
It belongs with anecdote 09: the second time a class that looked right had no effect on the page. Both are invisible to every static check and visible in a browser. The page checks of the benchmark (render, accessibility in two themes) catch a page that breaks, not one whose override was ignored; a visual diff against a reference page would, and it is on the list of things that need a pinned browser (guide 11).
Follow-ups
Decide what the design system's components do with aDone in chapter 35: they refuse it. The components are governed, take noclassNamethat sets a property their recipe already sets.className, and say so in the MCP's component help (guide 06).A grader forDone in chapter 35:className={css({…})}on a design-system component.outside-stylingcounts it as a design-system violation (guide 03).- Try it on the benchmark: give a task that needs a button to wrap, and see what each model does.
A citation that pointed at the neighbour
A chunker tuned on our own guides merged 19 short WCAG criteria into the criterion before them. The evals still passed, because they checked the words and not the citation.
The words were the same
We feared the AI SDK was rewriting what the agent reads. A diff of its requests against the official SDKs' showed the same words, a different format and a few defaults that nobody had chosen.