Berlin, DE

15:36

CET

All Rights Reserved.

All Rights Reserved.

Berlin, DE

15:36

CET

All Rights Reserved.

The system we needed

to collaborate with AI

Re-designing

Toaster,
the Keyword

Optimization tool

at Phiture.

Re-designing Toaster,
the Keyword Optimization tool at Phiture.

/specs

COMPANY

Doinstruct

Doinstruct

Adobe

ROLE

Design chapter lead

Design chapter lead

Adobe

OWNED

Design system to Code

Design system to Code

Adobe

PROJECT TEAM

Myself and 1 FE reviewer

Myself and 1 FE reviewer

Adobe

TIMELINE

June 2026

June 2026

Adobe

STAKEHOLDERS

CEO, Head of Engineering

CEO, Head of Engineering

Adobe

/problem

We have adopted building fast with AI. However, designers know this puts a spotlight on the speed <> quality dilema.


Knowing speed wasn't negotiable in an engineering led-company, my goal was to achieve the highest quality AI output possible. With Claude Code in the codebase, Figma through MCP, Claude design and other tools for prototyping on the side, we had good bases to build a good workflow.


However, our design system didn't have enough context for the LLMs to know how to behave around them.

Semantic layer for tokens

Primitive layers were often linked to our components.


Allowing for miss-alignment.

Rules and guardrails

We needed usage rules to be taken as context for whatever AI to understand our opportunities and limitations.

UX pattern library

Similar as with our rules, a UX pattern library prevents hallucinations from the LLMs in regards to surface solutions.

Component library

Our components, still carried some low-quality properties and building styles typical of a start-up.


Not ideal as pillar base for AI to create from.

/component-library

I decided the old component library wasn't worth restyling. Instead, it was worth replacing.


The strategy chosen was usign a headless component library, rolled out one component at a time. Headless, because construction quality, behavior, keyboard handling, accessibility, comes solid from the primitives and we only own the skin.


And deliberate in one more way: clean, predictable component code is exactly the context an LLM needs to build new components correctly, remapping the new semantic token layer to it.


shadcn-svelte was the obvious candidate for Doinstruct. However, this wasn't headless option, so we decided to use bits-ui, which is the underlaying layer of schadcn, but with our own CSS instead of adopting Tailwind as shadcn proposed.

PATH A - REJECTED

Adopt schadn as is

Take the components and take Tailwind with them. Fastest to start, and it puts a CSS framework migration on top of a component migration, and throws away years of working SCSS foundations against the preference of the engineers.

PATH B - CHOSEN

Adopt the model, keep our CSS

Own-your-code, headless bits-ui primitives, CLI distribution, on our SCSS system. Components become skeletons we reskin. More work per component, one migration instead of two.

/token-architecture

Two brand palettes feed one semantic role set through component variants.


Underneath every component sit bits-ui's headless primitives, which is where keyboard behavior, focus management, and ARIA live, so accessibility is inherited.


The idea is to mimic the token usage of shadcn so we can still use whatever documentation from both libraries to AI generate further needs.


Distribution runs through a custom registry: every repo pulls component source and owns its copy, updates are deliberate. Migration follows the strangler pattern, low-risk components first, all new work on the new library from day one.

Primitive

Raw values. Colors, sizes, type scales. No opinions.

Semantic

Roles: surface, border, input, focus ring, destructive. The layer AI and humans reason with.

Component

Per-component decisions, only where a component genuinely differs.

/machine-legible

A design-map bridges Figma component and token IDs to their code counterparts, so what an AI reads in Figma resolves to what exists in the repo.


Markdown files state the rules any AI working in the codebase follows, which patterns, which tokens, and hard git guardrails, added after Claude Code once created a branch on its own initiative.

CONVENTIONS, THE FLAVOR OF THEM

semantic tokens only, never raw hex

never create or switch branches without being asked

variants are page-appended before they're combined

variable bindings get reassigned, never mutated

design-map.json

Figma component and token IDs mapped to their code counterparts. What the agent reads on one side resolves to what exists on the other.

CLAUDE.md

The repo's working rules for any AI: which library components and UX patterns to use, how the token layers apply, SCSS and naming conventions, and hard guardrails.

/proof

The designs for the Video Studio feature slash product (which you can read about on this case study in my portfolio) were built through this system: thirteen production-fidelity screens in one session, using the published component library, with real data driving the states.

/red-checks

Rollout has a price

A staggered migration sounds gentle, and it still costs real capacity: every component rebuilt is sprint time not spent on features, and Path B made each one more expensive by design.


The hard part wasn't the technical work, it was the team accepting that this bill was worth paying at all. That acceptance took longer than any architecture decision.

Selling the invisible

Some teams pushed back on prioritizing foundations over features, and with full roadmaps, and capable tools to prototype in seconds, makes sense.


However, the cost of postponing this, is simple: if we don't, AI output degrades quietly, screen by screen, snowballing inconsistencies in system until it just stops being one.