3-tier tokens, W3C compliant
The model used by leading design systems — Primitives, Semantics, Components. Full compliance with the W3C DTCG Design Tokens Format Module 2025.10.
Modern design system architecture — W3C DTCG compliance, 3-tier token discipline, AI-augmented tooling. Built with Claude and Figma MCP; structured so AI agents can read, reason about, and generate against it.
getLocalVariablesAsync(), matched semantic intent, logged which slots resolved vs. gaps.setBoundVariableForPaint throws on post-combined ComponentNodes.clipsContent = false. WCAG 2.4.11 baked in.label, showIcon, placeholder, helpText, isRequired.I wanted to show how I use AI in real design system work. This is the documented process — building a modern SaaS design system from scratch, using Claude and Figma MCP to move faster without losing rigor.
The system covers what an enterprise DS actually needs: a 3-tier token architecture following the W3C DTCG spec, a set of core components, a scaffolded Figma file structure, naming conventions that map to code, and an integration path from Figma to developer handoff.
The model used by leading design systems — Primitives, Semantics, Components. Full compliance with the W3C DTCG Design Tokens Format Module 2025.10.
Eleven pages, published Text Styles, hidden variable collections. The mechanics that keep designer workflows fast and consistency non-negotiable.
The token format follows W3C DTCG spec — ready for any compliant build tool. AI agents parse the graph without translation. Naming conventions align with engineering practices.
Every tool in the stack solves a specific problem — either in the token architecture itself, or in the workflow that produces it. Nothing here exists to signal fluency.
The AI workflow does the mechanical work: writing scripts, generating variants, scaffolding files. The architectural decisions — naming conventions, tier boundaries, the Tier-3 discipline rule, the state matrix — still had to be made by a human who understood the tradeoffs. Automation is leverage, not replacement.
Variables & Dev Mode. The token source of truth.
Lead Agent orchestrator plus sub-agents. Custom Project with specific instructions and connected skills.
Two execution paths — MCP for interactive builds, Code Runner for JS execution directly in Figma.
Machine-readable token format following the W3C spec. Storybook via Node.js for developer handoff.
I created a Lead Agent orchestrator with sub-agents in Claude, plus a dedicated Project with specific instructions and connected skills. From there, I work through two execution paths depending on the task.
The MCP path is precise but token-heavy. I use it for interactive builds where I need to see the file update as I reason through the change. The Code Runner path is faster and cheaper — Claude writes the JS, I run it directly in Figma using the Code Runner plugin. That path requires understanding the underlying JS logic, which is exactly the point.
Combined, this automation saved roughly a week of manual work.
Claude wrote the JS for text style creation, page scaffolding, variable structure, and component variant generation. It executed the mechanical work at a speed I couldn't match by hand.
Claude did not decide the naming conventions, the tier boundaries, the Tier-3 discipline rule, or the state matrix. Those decisions required judgment about how the system would be used — and by whom — over time. That work is still mine.
Tokens exist for one reason: to be the single source of truth. Change the token, everything updates. Themes become possible. Design and code stay in sync.
I built this system on a 3-tier token architecture in Figma — the model that leading design systems converge on — with every token strictly following the W3C DTCG spec. Any compliant build tool can consume it. AI agents parse it without translation.
The foundational atoms of the system — exact hex codes, absolute pixel values, raw numbers. Named by family and scale. Every change here cascades through the whole system.
Primitives get a specific job. color-background-default references white in light mode, black in dark mode — swap the reference, the whole system follows. For most products, this layer is enough. That's my strong opinion.
The most specific layer, meant for the inner workings of highly customised components. Every component token aliases a semantic token. Roughly 15–20% of total tokens live here — enough to serve real needs, contained enough to stay reviewable.
Forcing component tokens onto every trivial element — badges, list items, toggles, tooltips — creates two problems at once. Designers stop using the system because the overhead of finding the right token is higher than hardcoding the value. Engineers inherit thousands of tokens nobody can explain and that drift out of sync.
My rule: add a component token only when a semantic token genuinely can't solve the problem. In practice, I cover Form Elements, Buttons, and Navigation first — everything else references semantics directly.
The naming discipline is button / {variant} / {slot} / {state} — anatomy first, state last. The state suffix is omitted for the default value; only added when the value actually changes from rest. This keeps the token set minimal and unambiguous, and maps cleanly to CSS custom properties like --button-primary-container-bg-hover.
Every token in this system follows the Design Tokens Format Module 2025.10, always with a category prefix (color/, spacing/, radius/). This is the W3C standard, which means the graph is ready for any DTCG-compliant build tool and parseable by AI agents without translation.
I used Claude + Figma MCP to create the primitive and semantic variables. That connection alone saved about 6 hours of manual work.
Both modes are fully populated. Color tokens carry different semantic aliases per mode. Dimension and typography tokens mirror Light into Dark — they are mode-invariant by design. Scaling to multi-brand themes takes minutes, not weeks.
Once variables are defined, the next layer is what designers actually touch. I built public-facing Text Styles bound to typography variables underneath — designers apply the style, they don't need to know what's running beneath.
The file structure carries the same principle. Eleven pages, scaffolded in advance, so every component category has a predictable home. New contributors don't ask where a component lives.
Inside each Text Style (like Heading/H1 or Body/Regular), properties bind directly to the typography variables. I used Claude to write the JS for the Code Runner plugin — five minutes of prompting, styles created in two milliseconds.
When I published the library, I hid the variable collection and only published the Text Styles. Other designers select text, apply a style, move on. They don't need to know what's running underneath. This keeps designer workflows fast and makes inconsistency impossible.
Claude wrote the scaffolding JS. Code Runner executed it in Figma in two milliseconds. Eleven pages created in order, ready for content.
📁 Design System (Figma File) ├── 📄 01 - Getting Started ├── 📄 02 - Tokens ├── 📄 03 - Icons ├── 📄 04 - Foundation Components ├── 📄 05 - Layout Components ├── 📄 06 - Feedback Components ├── 📄 07 - Navigation Components ├── 📄 08 - Data Components ├── 📄 09 - Patterns ├── 📄 10 - Templates └── 📄 99 - Changelog / Roadmap
Each component page includes: a default-state example, all variants in a grid, all states documented, and usage guidelines for when to use and when to avoid.
Most components in popular design systems ship with two or three states: default, hover, maybe disabled. Then the developer asks: what about loading? What about error? What about empty?
I built every interactive component in this system with a complete state matrix — ten states, each with a defined visual behaviour and interaction principle. Nothing ships without every state accounted for.
Clear legibility. Soft, low-strain colours.
Desktop feedback. Secondary priority on mobile.
Keyboard entry. High-contrast rings, thick outlines.
Physical tap feel. Paired with haptics on mobile.
Data retention. Floating labels so context isn't lost.
High-contrast backgrounds plus checkmarks.
Calm tones, not blazing red. Recovery over blame.
Definitive visual closure.
Prevents accidental double-submits in low-signal environments.
Always explain why something is locked.
Every focus-ring token aliases color/border/focus — 5.9:1 on white. Status text tokens use the /700 step (not /500) on tinted backgrounds — all pass 4.5:1 AA. Warning text is explicitly documented against orange/500.
Accessibility isn't a review pass at the end. It's a token-level requirement encoded into the semantic layer.
The measure of an AI-augmented workflow isn't whether it produced something. It's whether what it produced holds up under scrutiny — whether the tokens are consistent, whether the components are complete, whether the file is navigable by someone who didn't build it.
Below are the outcomes I can name with confidence.
Across Light + Dark modes, fully populated.
Every one aliasing a semantic — never a primitive directly.
Consistent file structure. Predictable location for every component category.
AI acceleration across variable creation, text styles, page scaffolding, component variants.
Every token follows the Design Tokens Format Module 2025.10. Ready for any compliant build tool. Parseable by AI agents without translation.
Focus-ring at 5.9:1 on white. Status text on /700 step for 4.5:1 AA. Not reviewed at the end — encoded from the start.
Variable creation, text style generation, page scaffolding, component variants — all automated. About six hours saved on variable creation alone.
Component tokens reserved for cases where a semantic can't solve the problem. Keeps the system reviewable, keeps designers reaching for it.
The most elegant token graph in the world doesn't matter if designers don't reach for it. Every decision I made about Tier-3 was really an adoption decision — reduce friction, remove the overhead of finding the right token, give designers a clear path from problem to shipped solution.
The consumer of a token isn't the person who created it. It's the person reading button/primary/bg/hover at 4pm on a Friday trying to ship a fix. Optimise the naming for that person, not for the author.
Designers infer intent from context — they read button-primary correctly even when the underlying structure is inconsistent. AI agents read the graph literally. Every ambiguity that a human tolerates breaks an agent. Designing for both audiences requires stricter naming, stricter aliasing, stricter format compliance than either alone.
Claude accelerated the mechanical work — script writing, variable generation, file scaffolding. The architectural decisions still had to be made by a human who understood the tradeoffs. The value of AI in DS work isn't that it decides. It's that it executes decisions at a speed you can't match by hand.
"A design system succeeds when the cost of using it is lower than the cost of ignoring it."