Where we started
Selzy is an email marketing platform with more than 50,000 customers and more than a billion emails delivered every month. I lead a team of four designers: three product designers and a content designer. We work with six PMs, all remote.
When we started, it was the usual cycle: Figma files, handoff, fixes after release. Design and iterations were slow, and so was development.
The design system was old. Parts of the product live in separate repos and release on their own schedule.
In May I moved the team from Figma to prototypes in code, on the product's real UI kit. An AI tool can build a page from a prompt, but on generic components, and that shows little about our product. A prototype on the real kit shows real states, real text and every language before engineering starts.
The tool changed, not the job. We still decide how a screen should work. The difference is depth: instead of a set of screens, we build a working model of the product, with its logic, scenarios and every state.
How the team moved
At first it was scary for everyone. It felt like we would stop being product designers. I tried not to push. I showed how I work on my own tasks, said when I didn't know something either, and we figured things out together. I helped along the way and steered gently. I also set up calls with designers from other products who had already brought AI into their teams.
Teaching happens on real tasks and at our weekly syncs. One designer came from email template design and had never opened a code project. By the end of June, the whole team was committing prototypes to one repo, each in their own way.
The setup
Every task gets its own project in TypeScript, React and Vite. The real UI kit and icon library come from the frontend repos, locked to versions we've checked.
Any designer has to be able to start a project with one command, so I wrote one script that sets it all up: it clones five repos, switches them to those versions, generates 1,068 icon components from SVG and rebuilds the index. It's safe to run twice and never overwrites local changes. The test: someone else runs git clone, setup, npm install and npm run dev, and it works with no manual fixes.
Designers don't need the terminal for any of it. The agent runs the setup and prepares the commits. Every session starts by pulling the team's latest changes, so everyone works on the current template, skills and projects.
Before the template, I had the team audit the prototypes repo. They found:
- 25 project folders
- 19 separate Vite apps
- 11 different sidebars
- 5 ways to wire the UI kit
- 5 ways to build a standalone
So I built one layout template, with the sidebar, top bar and account menu rebuilt from the product's own components. The kickoff skill copies it for every new task. Copied, not generated, so every designer starts from the same file. The template has versions and a changelog, like a product, and every copy records the version it started from.
Rebuilding it from the code wasn't enough. About 30 small differences from prod slipped through. I wrote a script that measures the live product, and it caught all of them.
The template holds what rarely changes. Screens that change often go into a separate library of ready-made pieces, sorted by product area, each with the date it was last checked against prod. A designer takes a piece, checks it against prod and finishes it for the task.
I wrote the rules every agent follows, in one file, AGENTS.md. Nobody makes up interface text. It comes from the product's real translations in Crowdin, not from screenshots. Claude would rather read a screenshot than a repo, so the rules send it to the repos first. The agents are also connected to Jira, Figma and Mobbin.
Two skills are mandatory, and I wrote both. Kickoff finds the project by its Jira key, or starts a new one from the template. Wrap-up ends every session with a commit and a Jira comment. Both live in one folder any AI tool can read. We use Claude Code by default. Codex and Cursor have worked from the same files too.
What an iteration looks like
An iteration used to mean everything done before the first review with the PM. Two of them took three and a half weeks. Now an iteration is one session of two or three hours.
Every iteration ends the same way: a single HTML file anyone can open, a commit, and a Jira comment on what changed and why, like in the thread above. So every step of a task is visible, the flow is the same for every task, and any designer can pick a task up at any step, without a long handoff. A designer can do three iterations in a day. We've made 107 so far, across more than 35 tasks.
Before a call, everyone downloads the latest iteration and clicks through it on their own machine, so on the call we discuss a working thing, not a picture. Feedback comes back through Jira and chat. The next session starts from the Jira task: the agent finds the project and reads its notes and history before it changes anything.
Before handoff
Prototypes go to support and marketing first. Support clicks through them with the customer's questions in mind, and their notes come back as fixes before engineering sees the task.
Handoff
Engineering gets the whole project, with links to the discussion, the UI kit and the repos. Before that, wrap-up strips out anything the task didn't ask for. The designer walks the developer through it with prod open in the next tab: this comes from here, that comes from there.
One PM brought a task with Figma mockups. We fixed them in Figma, and he still asked for a prototype at the end. It's easier to write the spec from it, and easier for engineers to read.
Portuguese and German text runs long, and layouts used to break after release and get fixed in prod. Now the team sees every language in every part of the interface before handoff, like the topbar states above. The content designer and the localization manager were the first to say so.
The design system
A prototype on the real UI kit inherits all its problems. Moving to code gave us a strong reason to clean it up. It isn't simple. The product lives in 12 frontend repos that release separately, so a token can look unused in the kit and still be used by a live page somewhere else.
I split the cleanup between three designers and mentor them through it. One takes colors, one takes shadows, overlays and layers, one takes sizes. Each writes up what they find as an HTML page built with Claude, not a slide deck, and defends it on a weekly call with the frontend lead. I run those calls. The audit runs on scripts that collect every color, shadow and size from the kit and the product repos, so anyone can rerun it and get the same numbers.
We work in a fork of the UI kit, so the product doesn't change while we clean up.
I set the stages of the cleanup. First the names, then the duplicates. Old names stay as aliases until a script replaces them across all repos. Then the token layers: primitive, semantic, component, with new scales for shadows, layers, spacing and borders. Visual changes get a separate review, with before and after side by side. My rule is backwards compatibility first, cleanup second.
The last stage is moving the components to the new tokens. We try the new kit on one page of the product first, then roll it out next to the old one, piece by piece. That's where we are now.
What changed
In Figma, half of the time went into building mockups by hand, and the other half into feedback and adjusting them after team syncs. It's hard to think through every state of a screen when half the time goes into drawing it. Now building takes about a fifth of the time. The rest goes to research, hypotheses, scenarios and states, and to product decisions with the team. We see flows, states and every language much sooner, catch mistakes earlier and ship fixes faster.
What stays with the designer
Claude took over the building. The designers on the team now work more like design engineers: they give agents tasks, build and test hypotheses fast, and take the one that wins all the way.
What stays with the designer is what Claude can't pick for us: what the user actually needs, which pattern fits, how deep to go at this stage of the task, and whether the same problem is solved the same way across the product. That comes from knowing the audience and from years of looking at good and bad interfaces.
My part as the lead is the decisions. I build the process and the design system, set the direction and make the final call on the interface. That keeps the product consistent, however many hypotheses we run.
What broke
Commenting got worse. In Figma, PMs and marketing could leave a comment on a pixel. Now they screenshot a prototype and paste it back into Figma to mark it up. We haven't solved this yet.
Prototypes drifted from prod. Changes in prod don't always reach design, so the latest prototype stopped matching the product. Under a deadline, a PM and I made quick fixes in Figma, and the developer ended up with three versions: Figma, the prototype and prod. After that, I made it a rule: a prototype has to match prod. A designer checks it against prod before starting a task, and Figma is only for text edits.
The agent made things up. In one prototype it found leftover JavaScript, decided it was a feature and built states nobody asked for. Engineering caught it in code review. Now, before handoff, wrap-up removes anything the task didn't ask for.
The first version of the kickoff skill built the setup from the repos for every task. It worked, but each designer's setup came out a little different. That's why the skill copies the template now.
What's next
More ready-made pieces, starting with the rest of Contacts. Token rules written down so agents can follow them, and a lint check that flags raw values in code.
After the cleanup, prototypes will match the product more closely, and engineering will spend less time on each task. New ideas and changes will be easier too, because a working system is easier to change than legacy code.
