Sebastián Balderas — Home

Every design system knows how to ship a Button. None of them knows how to ship an interface that says “this might be wrong.”

Taking a component library and dressing it in a brandbook is the general job. The layer above it is different: no component library ships it on its own. It has to define the states, permissions, provenance, and behavior that let humans and agents work from the same contract.

When I reviewed them in August 2026, IBM Carbon, AWS Cloudscape, Atlassian Rovo and GitLab Pajamas all documented AI patterns. All four were missing the same thing: uncertainty, hallucination risk, the limits of confidence.

  • IBM Carbon
  • AWS Cloudscape
  • Atlassian Rovo
  • GitLab Pajamas

The defects are the proof

You only get this class of defect building a layer that did not exist. They are proof it was built, not installed — and neither surfaced from using the site.

  1. Finding 01

    A visual token with two meanings

    The voice bars keep animating while the assistant speaks — with the microphone closed. Animated bars mean live audio input, so the interface asserted one that did not exist. No model involved: the UI hallucinated on its own.

  2. Finding 02

    Rigorous provenance, and no surface at all

    The backend already wraps every source with its author, and the instruction already forbids inventing. The interface shows none of it — the gap the four systems above are missing, found where the data already exists.

Touch the components

The real components from this site, running here. The judgement is in the states — switch them.

Voice status pill

The only place voice mode is visible while the chat is collapsed. Live in production.

components/chat/voice-launcher-status.tsx
Your turn — I'm listening

Try it

It is not the model hallucinating; it is the interface asserting a capability the system does not have at that moment.

Audio quota notice

The spoken-reply quota ran out — and this is deliberately NOT the error banner. Live in production.

components/chat/chat-ui.tsx → VoiceNoticeBanner
Audio is paused for now — you’ve reached the spoken-reply limit. The conversation keeps going in text, and you can keep asking questions.

Try it

Separating notice from error is what allowed the anonymous quota to drop to 8/h. It changed what the system can afford.

The three, side by side — only one is an error

Something went wrong — try sending that again.
Voice mode stopped — the reply couldn't be played. You can keep reading, or tap the voice button to try again.
Audio is paused for now — you’ve reached the spoken-reply limit. The conversation keeps going in text, and you can keep asking questions.

Generation states

The turn's whole lifecycle in one control: ready, submitted, streaming, error — and the same button changes job in each. Live in production.

components/chat/chat-ui.tsx → ChatComposer

Enter arrow — nothing in flight, and something to send.

Try it

Text outranks everything. Ranking the voice session above the typed text is what produced a second button mid-session — there is now no state with two controls.

Reading measure

The 48ch reading cap, and what happens when a component does not carry it. Toggle it and watch the line length — the figure below is measured live, in your window.

app/globals.css:623 · components/ai/provenance-disclosure.tsx

These sources describe the original text, not what you are reading now. A person changed it after it was generated. What changed, and who changed it, is not recorded — this conversation has no account and no history.

measuring…

Try it

The rule lived in globals.css scoped to main — and the chat widget mounts in the root layout, outside main. Same rule, two behaviours depending on where the component is mounted. It is the second instance of the class the voice bars exposed, and it was found because the first one was already written down — which is the difference between a fix and a system.

Who said what

The chat's core row. Assistant bubbles are terracotta, user bubbles the raised surface — swapped in July to match Figma, and not to be “fixed” back.

components/chat/chat-ui.tsx → MessageRow

What did he actually do on Strata?

Sole designer. Information architecture, role-based permissions and the design system, presented daily to the CEO, the project managers and the engineers.

Try it

Fixed p-5 padding stacked 40px on top of the card's 64 and the shell's 48: 152px of padding on a 390px screen, and the greeting fit in 25.7 characters per line against a 35–45 target — the email and both phone numbers broke mid-string, on the site's only conversion path.

Metrics with attribution

Scroll-triggered metrics. Every figure on this site is tied to the project it came from.

components/motion/count-up.tsx
  • +40%SLA complianceStrata
  • +40%throughputStrata
  • ~85%of surfaced functionality removedRepfabric
  • 20 → 1roles reduced to one primary personaRepfabric

Try it

Played 1×

The final value belongs in the server HTML, and the animation is decoration on top of it — never the source of the number.

Back to the latest message

Return to the latest message after scrolling up. Live in production, in both chat surfaces.

components/ai-elements/conversation.tsx → ConversationScrollButton

What did he actually do on Strata?

Sole designer. Information architecture, role-based permissions and the design system, presented daily to the CEO, the PMs and the engineers.

Did he build it, or just design it?

Designed. The delivery was Figma primitives and tokens mapped to code, plus the Storybook the engineers consumed.

Has he designed agent behaviour, or only used AI tools?

Both, and the distinction matters to him. On this site's assistant he designed the retrieval routing, the guardrails, the persona boundary and the voice mode.

What would he not take on?

Model training and fine-tuning. He designs behaviour; he does not claim the other thing.

Try it

A warning can only be checked if you can go back and read what caused it. Without that, every answer is something you saw once.

Provenance disclosure

New — a design proposal, not shipped. The backend already emits every source with its author; the interface shows none of it.

components/ai/provenance-disclosure.tsx

He was the sole designer on Strata, presenting daily to the CEO, the project managers and the engineers. The scope was design: information architecture, role-based permissions and the design system.

Try it

It does not stop the model from being wrong: it makes being wrong locatable.

None of this is a component library to adopt. It is the set of decisions a team otherwise re-makes by hand, one ticket at a time, and usually differently each time.

This system isn't just documentation — it's the constraint that keeps AI-generated output on-brand and on-system. The same rules a developer follows are the rules an agent has to follow: without them, speed produces divergence, not consistency.

MEDIUM · CONTRA

The states no component library ships:Read the full article on Medium

I write about these decisions in more depth.

Design system as code, fixed scope:Check the price on Contra