Chris Learey/Selected work/Case study

Design Systems

A design system that makes wrong UI impossible

A code-first, AI-native design system that collapsed the design → engineering → design-QA loop for a global B2B marketplace.

A design system used to exist to keep designers consistent. I don't think that's the job anymore. More and more of what ships never crosses a designer's desk; agents write it. So I built this one to do the harder thing: take the judgment that used to live in designers' heads and put it in the system, in a form an agent can read, so whoever's building, the taste comes baked in.
Exhibit 01, Live system

ClarityAI

A code-first, AI-native design system that makes wrong UI impossible, built, documented, and running in production.

Home page of the Clarity design system, headline reads ‘Clarity is an AI-native design system’
clarityai.design Open the live system
My role
Team lead, with one senior designer, I owned the strategy and drove the architecture, split delivery while holding direction, token architecture, component API design, build tooling, governance, and docs
Context
Nivoda, a global B2B jewellery marketplace
Duration
~3 months, foundations to ~63 components
Stack
W3C DTCG tokens (OKLCH) · shadcn/ui + Radix · Tailwind v4 · Nx monorepo · Fumadocs · Storybook
What shipped
Token pipeline · component library · live validation app · agent-readable docs · governance model · 4 ADRs
The bet behind it: encode the judgment, not just the components, so the quality bar travels with the system, not whichever designer happened to be in the room.

A system that suggested, but didn't enforce

Nivoda had a working design system: Material UI, a hand-rolled token pipeline, 60+ components. Fine on paper; in practice it leaked design intent at every seam:

81
per-component override files fighting Material's defaults
723
sx={} escapes, each a place a token could be ignored
32
component-specific token files to govern by hand

The team paid, continuously, to make Material not look like Material, and responsiveness was bolted on per component, not in the contract. The cost showed up as a loop that dominates UI delivery everywhere:

Design specs Eng builds Design QA Catch drift Revise
The loop exists because "correctly implemented" was never the same thing as "design-correct."
Industry context: 66% of teams lose 25–50% of their time to design-delivery friction, about $298k/year per product pod. (Builder.io, not a client-measured result.)

The components are the design

Not "follow the design," encode it. Tokens, spacing, type, a11y, responsiveness, and the legal range of variants live inside the API. The guard-rails are in the prop signatures, not a Figma file or a reviewer's eye.

The consequence is the point: nothing builds "correctly" and "design-incorrect" at once. Design has nothing left to catch; the QA loop doesn't get faster, it gets deleted.

Build with components Ship no QA gate
Same work, with the review loop removed, because correctness is structural, not reviewed.

But correctness is only half of it. A component library tells you what the button looks like. It can't tell you why it's that way, when to break the rule, or what "good" feels like for a flow nobody designed by hand. That judgment used to live in designers' heads. I wanted it to live in the system.

Which only matters if the system can be read. If components are the source of truth, that source should be legible to machines, not just people, because engineers, designers, and PMs all build through AI agents now, and they should inherit the same taste and the same guarantee. So it's AI-native from the foundation: the repo is the API, the docs are the interface an agent reads.

Four phases, foundations to library

1 · Diagnose before building

Not components first, a forensic audit. The fastest way to lose a rebuild is to recreate the old system with nicer syntax. The audit produced the numbers above and a token-by-token comparison against what was actually shipping.

That de-risked everything: 15 token-alignment decisions matched the new values to production, so migration could happen incrementally with zero visual drift.

What I believe: evidence first. A one-page diagnostic with real counts wins the room and tells you what to delete.

2 · Tokens as the contract

  • Source of truth: W3C DTCG JSON in Git, vendor-neutral and spec-backed.
  • Two tiers, deliberately: primitives (color.azure.500) and semantic roles (action.primary). Component values live in variants, not a third tier; small governance surface.
  • OKLCH colour, perceptually-even ramps, predictable dark mode.
  • One source, every platform: web CSS, shadcn theme, JS/TS, email, backend JSON. Semantic tokens emit var(--…) chains, so a primitive retargets without recompiling consumers.
DTCG tokens · OKLCH primitive + semantic · in Git build.mjs ~230 lines · 20 tests Web CSS :root / .dark shadcn theme Tailwind JS / TS React Native Email inline values JSON backend
One token source compiles to every platform. I replaced Style Dictionary with a ~230-line bespoke build once the vendor cost more than it saved (ADR-001).
What I believe: semantic tokens with intent in the name (color-feedback-error, never blue-5) are the highest-leverage move, for human clarity and AI output.

3 · Components on headless primitives

Built the way the best teams build in 2026: Radix primitives + Tailwind + code-ownership (shadcn), the foundation OpenAI, Vercel, Linear, and Supabase run. No vendor design language to override back out.

~63 components across four tiers: 38 atoms, 16 molecules, organisms (FilterToolbar, Megamenu, Sidebar), templates. One reference component (Button) was hardened to define "finished" and set the bar. All validated against a live app on real data: done means it survives a real product surface, not that it renders in isolation.

4 · Documentation that is the interface

This is where the why lives, the part a component library can't carry. Not just what a component is, but when to reach for it, when not to, and what good looks like:

  • Library map, a for/not-for index of every component, encoding the judgment of when to use each; the first thing an agent reads.
  • 63 colocated docs, props, usage, do/don't, next to the code so they never drift.
  • TypeScript contracts as spec, Storybook as executable examples, the Nx graph as machine-readable structure.

The docs are the repo, so an agent always reads current truth, and inherits the same taste a senior designer would have applied by hand. No sync step, no stale mirror.

Decisions, recorded as ADRs

A design system is mostly "do we adopt this tool?" calls. I recorded four; the reasoning is the artifact:

  • Bespoke token build over Style Dictionary: use the vendor until it costs more than it saves, then own a small tested script. Reversible; the DTCG source never changed.
  • Removed visual-regression testing: right tool, wrong time. One component, no CI, pure overhead (and a secret-exposure risk). Revisit at 10+ components.
  • Rejected Figma↔code token sync: solves a problem this team didn't have. Designers explore in Figma; they don't author tokens there.
  • Markdown docs over a hosted hub: when the source is already agent-readable, read it directly instead of maintaining a polished copy.
The throughline: adopt the minimum tooling the stage justifies, document why, keep it reversible. That's most of what keeps a young system from collapsing under its own process.

What a system like this lives or dies on

Beyond the code, what decides whether a system survives:

  • Led the team. Lead of a two-person team with a senior designer, I split delivery and drove the architecture, strategy, and quality bar, the direction stayed mine.
  • End-to-end ownership. Strategy, tokens, component APIs, build pipeline, governance, docs: the whole spine, not a slice.
  • Designed for the handover. Two token tiers, a readable ~230-line build, ADRs, in-repo docs: a system the team owns after I step out, not a black box.
  • De-risked the politics. Pre-aligned tokens made migration invisible to users and uncontroversial to leadership: no flag day, no re-skin to argue about.
  • Set the bar by example. One finished reference component defined "done" for everyone, and every agent, after it.
  • Worked with how designers work. Code is the source of truth, but no one's forced to author tokens in Figma.

What changed

  • Anyone building gets the taste by default, designer or not, human or agent, you build against the same library and inherit the same judgment. The quality bar travels with the system, not the person.
  • The QA loop is structurally gone, not optimized; components are the design, so there's nothing to catch.
  • Design hours redirected from reviewing implementations to building components, docs, governance.
  • Zero-drift migration, values pre-aligned to production; adoption is incremental and invisible.
  • Clean, reviewable Git history, phased, conventional commits, decisions recorded. Auditable.
  • Small governance surface, two token tiers and component-encoded variants, not 32 token files and 81 override sheets.

Good design, in work no designer ever touched.

W3C DTCG tokens OKLCH shadcn/ui Radix UI Tailwind v4 Nx monorepo Fumadocs Storybook Vitest TypeScript Claude Code / Cursor native