top of page

AI Design System: AI Changed What I Need From a Design System

Sep 17
6 min read

Updated: 5 hours ago

Tweaking tokens with Leva
Tokens & System Rules

I’ve been spending more time designing directly in code with Cursor, and I wanted to get better at something fairly basic: starting properly.


Not starting a product. Starting the thing underneath it.


When I open a new project and begin making things with AI, I can get to an interface incredibly quickly. But speed hides a problem. A few sessions in, decisions start accumulating everywhere. There’s a gray that came from Tailwind, a radius that seemed reasonable at the time, a transition with its own duration, another breakpoint because one screen needed it. None of these decisions are particularly bad on their own.


Together, they slowly become a system nobody actually designed.


I wanted to understand how to prevent that before I had a product to distract me.


So I built a design foundation with no product attached to it.


What does AI need to remember?

I started with the normal design-system questions: colour, typography, spacing, radius, motion, responsiveness, accessibility. The things I already understand from a design perspective.


The unfamiliar part was figuring out how those decisions should exist technically when AI is helping write the code. Where should the source values live? How should Tailwind consume them? What happens when I change something visually? How do I make sure the CSS still represents the same decisions? And perhaps more importantly, what prevents the next Cursor session from ignoring all of that and introducing something new?


That last question changed how I thought about the exercise.


Normally, a design system gives designers and developers a shared language. Here I also had another participant: an agent that can produce a lot of interface very quickly, but doesn't necessarily understand why the existing interface is the way it is.


If that reasoning only exists in yesterday's conversation, it effectively doesn't exist.


So I started treating the foundation as a contract.


Paper isn't a particular hex value scattered through the code. It's paper. Ink is ink. Accent exists for state rather than decoration. Motion comes from a small set of named timings and recipes instead of whatever duration happens to appear in a generated component. There is one responsive jump at 768px, and the other Tailwind breakpoints are deliberately unavailable.


Some of this sounds unnecessarily strict until you start generating interface quickly. Then you realize how useful it is to have fewer decisions available.


Tweaking tokens with Leva in real-time
Tweaking tokens with Leva in real-time

Making the AI design system editable without talking to it

I also didn't want the solution to be “ask Cursor to change the design system.”


I ran into this problem in an earlier experiment. AI was useful for generating the interface, but when I wanted to visually tune something (move it slightly, change a value, see what happened), I didn't want to describe that adjustment in words. I wanted knobs.


So I brought Leva into the foundation.


I can open the Tokens page, adjust typography, colour, radius or motion and immediately see what those decisions do to the system. It gives me the speed of working visually without separating what I'm looking at from the thing being built.


That created another problem: dragging a value is useless if the project forgets it on refresh.


So I built a persistence path. Write values takes what I've adjusted visually and writes it back into the actual token source and generated CSS. An agent can change the same source directly and synchronize it from the command line. A separate check makes sure those two representations haven't quietly drifted apart.


I don't have to copy JSON somewhere or explain to Cursor what I just changed. The decision becomes part of the project.


Making the wrong thing harder

Once that worked, I became more interested in enforcement.


Documentation is useful, but documentation still depends on somebody reading it. With AI producing code, I wanted some of the design rules to behave more like technical rules.


So linting became part of the design foundation.


If something introduces a random colour instead of paper, ink or accent, it complains. If a pasted component brings in rounded-xl, it complains. If somebody uses a one-off pixel value or the saved token values stop matching what the page loads, it complains.


I also connected those checks to Cursor's hooks. When an agent edits the interface, the foundation can check what it left behind instead of relying on me to notice every small inconsistency.


That might be the part of this experiment I find most interesting. The design system isn't only describing what the interface should look like. Some of its judgment is actually participating in how the interface gets made.


Three rooms and no product

The project now has three environments.


  1. Stage is where an actual product can eventually live. Right now it is deliberately almost empty. If the basic page already feels wrong there, adding a product isn't going to fix it.

  2. Tokens is where I can see and manipulate the foundation itself: type, colour, motion, contrast and the other values I want to tune. It is basically a showroom where weak decisions have nowhere to hide.

  3. System explains the rules, including the parts an agent needs to understand before touching the interface.


I spent more time than expected on that last one. The first version was technically accurate but read like documentation written for the documentation. I eventually reorganized it around much simpler questions: what is this, why does it work this way, and what does the agent need to know?


The technical instructions can stay technical. I still want the design system itself to make sense to a designer.


The strangely difficult breakpoint

One of the smallest decisions turned out to be one of the more useful tests.


I wasn't sure what to do about responsiveness. Should breakpoints become another thing I could manipulate in Leva? Should I leave the decision until a real product existed? Should I simply keep Tailwind's defaults?


After going around that for a while, I realized a breakpoint isn't really the same kind of decision as colour or radius. A media query can't follow a pixel I'm dragging around, and I didn't need a responsive layout system yet.


What I needed was a rule.


So the foundation has one jump: phone first, desktop at 768px. The other Tailwind breakpoints are disabled. If a future product genuinely needs more, that decision can be made when there is an actual reason for it.


That became a useful principle for the rest of the project. A foundation doesn't need to anticipate every decision a future product could possibly require. It needs to make the decisions that shouldn't have to be reinvented every time.


What I was actually building

There is still no product in this repository, which was intentional.


What exists is Vite, React, TypeScript and Tailwind underneath a set of design decisions that can be visually manipulated, persisted, checked and explained. There are rules for typography, colour, motion, responsiveness and accessibility. There are conventions for what counts as a primitive, a semantic value, a catalog, an example or a recipe. There are instructions for agents, and automated checks for some of the things I don't want them improvising.


I started this because I wanted to understand how to set up a solid foundation while designing with AI in code. I ended up thinking more about what a design system is for when AI becomes part of the production environment.


AI makes it incredibly cheap to generate another interface. It also makes it incredibly cheap to generate another interpretation of the interface.


That makes the foundation more important, not less.


The interesting part for me isn't creating a giant component library before I know what I'm building. It's getting the underlying decisions right once, expressing them in a way both humans and machines can understand, and making enough of those decisions enforceable that the next thing can inherit them rather than reinterpret them.


If this works, I shouldn't need to rebuild this part next time. I should be able to change a few decisions, give the repository to someone else (or another agent) and start with the foundation already intact.


Then I can spend my time on the part I don't want the AI design system deciding for me:

What should we actually build?

 
 
 

Comments


bottom of page