Qore: Building an AI-Native Design System From Scratch
How I used Claude Code to fold 150+ inconsistent web pages into one design system AI could read and build with — before that was a documented practice anywhere.
Picture 150+ web pages. Now imagine almost none of them share a single component.
Every page was its own island: unique design, unique spacing, unique everything. Nothing talked to anything else. That's what I inherited.
And it wasn't just messy. It was expensive: every new page meant rebuilding decisions that should've already been made.
What we designed wasn't what shipped
Every page went from Figma to Webflow through an external vendor. Small drifts crept in constantly (spacing, states, responsive behavior) until the live site quietly stopped matching its own source of truth. Nothing was standardized, so the vendor rebuilt every fold from scratch each time — close enough visually, never pixel-perfect.
The vendor was expensive and slipping
Big name, big price tag. But deadlines kept slipping — the vendor routinely ran one to two weeks over — and our roadmap stalled with them.
Our SEO was under threat
Search and AI crawlers were changing how they read websites. Our blog had already moved to Sanity to adapt. The marketing site hadn't, because every update took weeks.
Designed — Figma
Shipped — live site
One fix could solve all three: migrate off Webflow, onto Sanity, powered by a design system precise enough for AI to read and rebuild pages automatically.
That system didn't exist yet. So I built it.
No tutorial on converting an existing UI into a robust design system through Claude Code and Figma MCP. No case study. No blog post. Nothing.
Every design system resource out there assumes a blank canvas. Mine wasn't blank: 150 pages of accumulated decisions, most one-offs, none documented. I was writing the playbook as I built the plane.
This also ran right at the edge of what was possible at the time. Figma's own AI-readability tooling was in early access. MCP was new. "AI-native design system" wasn't a phrase anyone used yet, because almost nobody had tried to build one end to end. There was nothing to copy — every decision below was a first attempt, not a best practice.
Constraints stacked on top:
- 🎯 Zero downtime allowed. The vendor causing the problem was also the only team shipping pages.
- 💸 Budget-capped model. Most of the build ran on a lighter AI model, meaning more errors to catch by hand.
- 🌱 Mentoring in parallel. Teaching a junior designer AI-assisted workflows while building the system itself.
- 🃏 300+ card versions. One component alone consumed enormous time and judgment: 300+ variations across 150+ pages, narrowed first to 36, then collapsed to 4 final layouts. It took this long because the cards shared almost no common logic — each one had to be rethought, not just relabeled.
- 🔧 No token pipeline Claude could read. Most design systems manage this through the Figma Tokens Studio plugin. Claude couldn't read that format directly, so every change meant exporting a JSON, editing it, and reimporting it — a cumbersome loop I wanted to avoid entirely.
None of this was helped by how every page got made in the old world: custom, from scratch, every time. That meant a fresh round of design review and feedback on every single page, not once per component.
Step 1 → I audited before I built anything
I didn't start from zero. I started from what already worked.
I pulled the 20 best-performing pages out of 150, reverse-engineered their components, and used that as my seed library. Then I turned Claude into an auditor: "compare this seed library against all 150 pages, tell me what's missing."
Build on what's proven. Then fill the gaps.
Step 2 → Foundations first. Always.
No jumping straight to the fun stuff. I locked the boring layer first, because everything else depends on it being right:
Skip this order and you rebuild everything twice.
Step 3 → I chose variables over tokens, on purpose
My first instinct, like most design systems, was to reach for the Figma Tokens Studio plugin. It lasted about a day.
Two reasons I switched, both practical:
- Variables are native to Figma. No extra layer to maintain.
- Claude could edit variables directly. It couldn't touch a separate token system.
Speed won. Every component still got a full variant set, a Light/Dark/Glass Light/Glass Dark usage panel, and written documentation. Even so, everything needed multiple passes of checking, since Claude would sometimes edit the wrong component by mistake. As the project progressed, newer models — Opus 4.7 and Fable 5 — got noticeably better at handling this reliably.
It wasn't just cards — everything got standardized
A few other systemization wins happened alongside the card work:
- Buttons. The old file only ever built two hand-made states: Solid and Outlined. Qore's Button component supports those two plus Underline and Ghost as full structural hierarchies (each with a Glass-material counterpart), plus a Pill shape on top of all of them — 2 → 8 structural combinations, not 2 → 2.
- Themes. The old system only had a light theme. Qore adds a dark theme, a glassmorphic light theme, and a glassmorphic dark theme, so branding stays correct everywhere and the system is future-ready.
- Media. Standardized from unlimited, inconsistent image sizes down to 4 fixed ratios, making AI-driven image creation easier and more consistent.
- Typography. Defined a full type scale — H1, H2, Display XL, Body, Disclaimer, and more.
- Iconography. Defined through the Atlas icon set, backed up with Unicon, a Claude-based icon generation project, for the rare case where none of Atlas's existing icons fit.
Step 4 → The card problem: my biggest call on this project
300+ versions, down to 36, down to 4 layout versions of one component. No pattern connected any of them.
I could have "systematized" at least 100 of them. I didn't. I collapsed them into 4 core variants.
Most of the original 300+ fit perfectly into the new system. The other few? I redesigned them to fit, instead of keeping them as permanent exceptions.
Fewer options. Less room for error. Easier for AI to reproduce with a standardized system. That was the entire point.
Step 5 → I built for where we were going, not where we were
Every decision, especially the card consolidation, was made with Sanity as the destination, not Webflow as the present. The real target was a system clean enough for Figma Code Connect to translate straight into code: no drift, no translation errors, no vendor guesswork.
Step 6 → I matched the AI model to the job
I didn't use one model for everything. I routed:
| Task | Model | Why |
|---|---|---|
| Routine components | Sonnet 4.6 | Manage cost across a month-long build |
| High-complexity, high-stakes work | Opus 4.7 | Buttons, full-system audits, anything where a mistake was expensive |
| The hardest component in the system | Claude Fable 5 | Built the entire card component in a 2-day early-access window |
Step 7 → I discovered Figma + AI's biggest blind spot myself
Early on, Claude couldn't reliably read a Figma file's structure at all. Nobody on the design team knew how to fix this yet — we were still adopting AI as a team. My first workaround was describing frames to Claude by hand, in text, one at a time. It technically worked. It also didn't scale past about three components. Figma's own skill library eventually closed most of that gap.
Without it, an estimated 80% of this project doesn't happen at this speed and scale.
Step 8 → I built a memory system so context never got lost
AI forgets. Long sessions blow past context windows constantly, and starting a fresh chat doesn't just lose all context — it burns extra tokens re-explaining things and invites more mistakes.
So I built a consistent memory system: a handover.md file that Claude updated itself before every context window ended, logging what changed, what worked, what didn't, and what's next. The next session would read it and pick up exactly where the last one stopped.
It also let the junior designer and me collaborate on shared groundwork, like the system's base values — we'd share our handover files and merge them so we both worked from the same context. It made prompting easier, too: we didn't have to re-explain every detail each time, since the AI already knew how things worked.
One unexpected benefit: whenever we needed a day-by-day project update, we could just have Claude read the handover file and generate it — project management and status comms, for free, without eating into actual production time.
This later split into two layers: one master file holding the full project history, and lightweight per-session files for narrow, active work.
Zero context lost. Zero re-explaining. Every single time.
Step 9 → I audited every instance, not just the system
Building the system was half the job. Trusting it was the other half.
I checked every card against its original, one at a time, and logged each as matched, redesigned, or a documented outlier where the new system genuinely couldn't replicate something unique.
This rigor caught things a lighter QA pass never would have:
- A hidden bug in the Ghost button style (unbound padding on 10 variants) that I traced to its actual root cause instead of patching the symptom
- A layout regression in a tab component, caused by fixing that same bug, that I diagnosed and resolved without undoing the original fix
- A full icon audit across 10+ components, deciding case by case what should flex and what should stay fixed
I fixed root causes. Not symptoms. That's the difference between a system and a pile of patches.
Step 10 → I ran the same audit across every component, not just cards
The card collapse wasn't a one-off flex. I ran the same "how many layouts does this actually need" audit against all 34 components in the system, not just the one that made headlines. AI assisted with this for some components.
| Component | Old file | Qore |
|---|---|---|
| Card | 36 layout templates | 4 core variants |
| Accordion | 7 | 2 |
| LogoBar | 4 | 2 |
| FlipTiles | 3 | 2 |
| IconBand | 3 | 2 |
| Fold | 6 fixed column layouts | 1 flexible spacing system |
Some components didn't need collapsing at all. BadgeBar, BragBar, SocialProof, Carousel, InlineBanner, and Banner matched the old file's variant count exactly. Where the old system already had it right, I kept it right instead of "improving" it for the sake of touching everything.
6 components consolidated by 50% or more. 6 matched exactly, untouched. 6 are entirely new (IconButton, Line, Stars, Avatar, List, Fold/Hero) doing things the old system never could.
One gap, stated plainly: Special had 9 layouts in the old file and isn't rebuilt yet. These sections never used auto-layout, so they can't be cleanly standardized for AI to work with yet. Still evolving — how to handle them is an open decision.
There was no playbook when I started, so here's the one I'd have wanted:
- Variables over tokens, when your collaborator is an LLM. If your AI can't read your source of truth directly, you don't have a source of truth — you have an export step waiting to go stale.
- Foundations before components, always. Color, type, and effects first. Skip this order and you rebuild everything twice.
- Route models by risk, not by task type. Cheap models for routine work, your best model for anything expensive to get wrong.
- Treat context loss as an engineering problem, not an annoyance. Build the memory system in from day one — don't wait until you're re-explaining the same thing for the fifth time.
- Audit at the instance level, not just the system level. A system that looks right and a system that's been checked against ground truth are not the same claim.
- Don't "improve" what already works. If a component already matches your target, leave it alone. Consistency is worth more than touching everything for the sake of touching everything.
This wasn't a Figma cleanup project. It was three things at once:
A business call
I connected a design system to AI, a vendor exit, and an SEO fix, then built the thing precise enough to make all three possible.
A leadership call
I mentored someone through the exact uncertainty I was navigating myself, in real time, so the system didn't depend on just me.
An engineering discipline call
Every bug got root-caused. Every card got checked against ground truth. Nothing shipped on "looks about right."
The hard part was never the prompting. It was the checking.
AI could generate a component in seconds. But that same AI could silently break something it built correctly yesterday. So every hour of speed had to be matched with an hour of verification, or the system would fill up with exactly the kind of invisible mess it was built to kill.
And mentoring someone through that same uncertainty, at the same time I was living it myself, changed what "finished" meant for me. A system only I can run isn't actually done.
If I started this today, with Figma's skill library and MCP already mature, I'd probably skip most of the manual troubleshooting from Step 7 entirely — a lot of what I had to invent by hand is now documented practice. But I wouldn't skip the audit discipline. That part was never a tooling gap. It was just the job.
I really hated approving every permission prompt — it broke my flow constantly. Why? Because Claude Code worked every time. Once I trusted that, I set it to bypass permissions, and that alone sped things up a lot.