Fifteen years of frontend and UX, and the same wish kept coming back: less energy on the basics, more on the problem only this product has. So I built the system I kept wishing for.
Context
This year I worked on the TV2 Regionerne design system. Then I needed a new job. I could describe what I'd learned in an interview, or I could build it. I built it.
I truly admire the big design systems, Material Design above all. Decades of web design decisions, written down for anyone to learn from. Why reinvent the wheel? So before every component, I had Claude research how Material 3, shadcn and others solved it, and I took the best ideas.
The goal? Gather 15+ years of know-how in one place, for me and my clients, so more of our brain power goes to the problems that are actually unique.
Challenge
My portfolio's brand file was holding the whole semantic tier, about 150 tokens, and dark mode only knew warm stone and teal. Build a new product on it and you'd get… my portfolio. Nice for my ego, less nice for a client.
The fix: a neutral, accessible base that stands on its own, and every brand as a thin layer of overrides on top. A second full brand was the other option. Twice the upkeep, and still no neutral default, so no. Today five brands share one base, three of them demos, in light and dark.
Approach
Colour, spacing and typography. Get them right and most components almost design themselves. Get them wrong and no component can save you.
Colour. Neutrals first, then role-based colours that say what something is for: an accent, a set of surfaces, four feedback colours.
Spacing. A 4px scale underneath, and names by job on top: the gap between page sections, between blocks in a component, between an icon and its label. Section gaps and page gutters grow with the screen, from 48 to 80px and from 20 to 32px.
Typography. Three families (body, heading and mono) and sizes named by role: body text at 18px, captions at 12px, and a display size that scales from 32 to 80px. Even line heights are tokens.
All three run live, in every brand, on design.amezquita.dk.
Tokens flow one way, in three tiers: primitives, semantic and component. Components only read the last two.
My first attempt made Figma the source of truth. It didn't hold. Now code leads: tokens are pushed from code into Figma, where I test ideas and present them, and a weekly job flags when Figma falls behind.
Structure from BEM. Behaviour from Radix. Everything visible: mine. Change one attribute on the html element and every component re-skins. No JavaScript, no rebuild. Where Radix has a tested primitive, I use it. Where it doesn't, I write the keyboard model and test it.
Where design met code
So before anything ships, these run, and one failure stops it.
Contrast. 29 colour pairs, checked in all ten brand and mode combinations: 290 checks.
Looks. 567 Storybook stories, which Chromatic compares screenshot by screenshot in CI.
Token rules. Ten lint rules keep component CSS on the token system: no raw colours, spacing, timing or breakpoints.
Behaviour. 1,996 tests, including keyboard use and screen-reader names.
A design choice I care about becomes something the build enforces. Nobody has to remember it. Me included, on a Friday afternoon.
How the work was split
The checks held us both to the same rules. One week in October, 35 components became 97. I couldn't have done that alone, and I wouldn't trust it without the checks.
A card should work and look like a card, whether a senior, a junior or an AI built it. That's what the rules are for. They democratize the work.
My first sessions? Whenever a component fell short, Claude would find its own fix outside the system. Fast, and a bit sneaky. I asked for the opposite: make the limitation visible and fix it in the library, so every product gets the fix. The docs site logs each gap until it ships.
What I keep for myself:
Final visual judgement. I click through the selects and their states in Storybook and Chromatic. A checkbox that had quietly rounded itself into a radio button, a drawer hiding under the sticky header: both caught by eye, both tested now.
CI health. Once, checks failed across 18 merged pull requests before anyone noticed. Anyone being me. Now I watch.
Taste. Which ideas from Material or shadcn belong here is my call.
Outcome
@amezquita/design-system, version 1.6.2, installable by any React project. Each release opens an update on the docs site and the portfolio automatically.
design.amezquita.dk shows every component live, with its props and tokens.
An MCP server with seven read-only tools lets an agent look up components and tokens instead of guessing.
Reflection
What surprised me? How close design and code have come this year. Claude Design hands work straight to Claude Code, and every tool I use leans on React.
What would I do differently? Settle names before values, plan the layers on day one, and write far fewer component tokens. Naming is still the hardest part of the job.
Things broke, too: stale generated files after a merge, and a release missing its chart types. Who found the second one? Me, using my own package. Both are fixed.
Now it needs real products. Want to build one together? Write to me, let's talk.
Open the inspector. It's all tokens.