Case Study
Pulse
Pulse is an AI marketing platform — strategic signal to published post, with a person at every gate. I joined a team prototyping it in six different tools, a week from a pitch — and built the design production system so that rescue never happens twice.
At a glance
- Token-driven design system — 40 components, one source
- Six prototype tools merged into one runnable app
- AI drafts; a person releases at every gate
824commits · 5 weeks
Project Summary
Pulse takes a brand team from a strategic signal to a published social post — an AI marketing platform that never gives up human judgment. When I picked it up, the team was prototyping that one product in six different tools — pages that looked alike and shared nothing underneath — with about a week to fold them into a flow we could pitch.
Over five intensive weeks I went from owning the homepage to owning how the team ships: the merged mockup itself, then the token-driven design system and component library, the automation that keeps AI-generated UI on-system, and the handoff surfaces that let design, engineering, ML, and product finally work from one base.
01 · The melee
Same product, six tools — and not one shared line.
Prototypes that only looked like one product
When I picked up Pulse, everyone was iterating on the same product in a different tool: canvas frames, an AI page-builder, model-pasted HTML, screens composited from images. An early style pass kept the pages looking related, but nothing underneath matched. With a week left before the pitch we had to fold all of it into one flow, and that is where the lesson landed for me. Visual consistency is not system consistency.
02 · The bet
Boards can’t be pitched. Working code can.
Betting the pitch on code
A pitch needs a flow someone can click through and record, not a deck of stills, so the designer and I decided to prototype in code and let AI do most of the typing. To keep six parallel efforts roughly aligned, we seeded a thin style pass first. It gave us a shared look. It did not give us a system, and that difference shaped everything that followed.
03 · The look
Branding at deadline speed: a studio, not a dashboard.
Neutral first, color with meaning
The identity had to be settled fast, and it had to survive AI reproduction, so I kept the rules few and wrote every one of them down. I also refused to pick the direction by taste alone. The accent candidates ran against the same dashboard side by side, and the winner had to prove itself on a full Home screen before we ratified the palette.
the generation ladder — each hue has one job; they light in order as you arrive



04 · The wake-up
Owning Home meant reading everyone’s code.
The front door forces the map
My page was Home, the product’s entry point, so designing it meant understanding every tab, every module, and everyone’s files. Extraction kept failing: styles were welded to pages, interactions died in transit, and much of the generated code was unreadable. The wake-up call was a single prototype file 10,180 lines long. Nothing that size stays maintainable, for a person or, affordably, for a model.
If it’s all code anyway, hand it off clean
I started with my own file: split it, structured it, cleared the dead code. The realization underneath became the whole project. A prototype that looks right but is chaos in the code is still just a prototype — and since generating clean, structured code costs about the same as generating a mess, and it is all code either way, why not generate it in the shape engineering can actually receive, so the designer owns the real front-end result instead of throwing a picture over the wall?
So I asked the engineers a question nobody had raised yet: if design ships code, what shape would you actually accept? Their stack was React, so I rebuilt on their conventions and the handover went cleanly. To me that was the real milestone — AI quietly closing the old, contentious gap between what design draws and what engineering has to build.
05 · The rescue
One week, every prototype, one app.
Unify, engineer, migrate, merge
A week out, the call came to fold every prototype into one mockup and record the pitch video. I took them all: unify the surface, engineer file by file, migrate toward one stack, merge into a single runnable app. AI carried the bulk of the conversion and kept breaking things in transit, so I reviewed every page against its original and repaired every break by hand — a week of nights with a teammate.
Then the real data didn’t fit
For the pitch I wired in the ML team’s real data — and the shapes didn’t match what the screens had assumed. It was the code lesson again, from the other side: a mockup that looks finished but can’t hold real data is still just a picture. We had built the UI first and treated data as a detail to pour in later, when the honest order is the reverse — start from the data that exists, tag it, and design the chart around what it can actually give. Looking right was never the bar; being real enough for engineering to receive — real code and real data both — was. That is the gap the shared base was built to close.
06 · The base
The look became law: one base the whole team ships from.
One canonical base, checked by machines
The fix was a base everyone shares. The look was ratified into one canonical token sheet — six semantic ramps, a fixed type scale, an 8-based rhythm — beneath the 40 standalone components, and every screen composes from those contracts before inventing anything page-local. The standard became commits rather than advice: Prettier normalized the codebase, I purged 1,905 verified-dead lines, and a dependency-free check now enforces all of it in CI.
Build the link that doesn’t exist, then delete the copies.
Stepping down from React, on purpose
I had proven I could ship the React path, and still made plain HTML and CSS the team’s prototype stack — an interim call, and one I stay honest about. Not everyone on the team can fully own engineering standards yet, and plain files meet everyone where they are: a designer and an engineer can both edit them, they export straight to Figma design boards, they preview from a double-click with no dev server to run, and they still convert cleanly into React or another framework later. A mockup a teammate can’t open might as well not exist. The floor mattered more than the ceiling — the discipline lives in the tokens and the checks, not the framework.
Preserve file:// support because designers may open this export directly.
07 · The skills
Rules the AI loads, so nobody has to repeat them.
Teaching the AI the system
A library only holds if every new prototype follows it, and re-typing the rules into a chat box every time is exactly how that falls apart. So I wrote the rules as skills the AI loads before it generates or edits: maintenance skills keep tokens, components, and previews in sync, and a design skill makes new work start on-system instead of getting repaired into it. Calendar began from that baseline, and the melee never came back.
Loaded before the AI generates or edits a prototype — the system, written as procedure.
- compose from the component library before inventing page-local UI
- tokens only — no raw hex, no off-scale spacing or type
- every state ships: hover, focus, empty, loading, error
- run the consistency check before any handoff
maintenance skills keep tokens, previews, and boards in sync
The skill is a living document
When a review catches a drift, the fix lands in the skill’s markdown, not in someone’s memory. I keep editing those files the way engineers keep tests green: each decision we settle — a token, a component pattern, a rule about states — gets written where the AI reads it before it works. That is what makes the generation quality compound: every edit raises the floor of everything produced after it.
08 · The interface
Four roles, one base: previews, a package, a playground.
A surface for each side of the table
I grew a reading surface for each side of the table: a live component browser that renders every component and state from its standalone source, and a sliced, deliberately non-interactive Figma board built purely to be imported, so code UI flows back into design review. The handoff is not a snapshot either: when the system changes, a sync pass carries the decision back out to the designer surfaces.
Buttons
One control contract — four intents, each with its own busy and landed feedback.

From preview to infrastructure
The HTML library stayed the source of truth. Separately, and later, a teammate re-migrated it into a typed React package on the team’s private registry — a distinct build that copies the canonical CSS in so the package can’t drift from its origin, then a CI job publishes that package and deploys its playground. The playground goes past looks: you feed a component data and watch it hold. That was the thing the melee had been missing — not talent, but an interface between the people who had to work together.
versioned releases · CI rebuilds from the design system

integration stopped being a rescue
09 · The product
What the base carried: a studio with a person inside.
A calm studio, not a dashboard
On top of the system sits the application: a sidebar workspace that runs from Home and its docked assistant through Calendar, Signal, Analytics, Strategy, Campaigns, and the production Studio. Hierarchy comes from tone, spacing, and rhythm before borders, and every screenshot on this page renders from a plain file:// address.



A light brief, drafted by the AI, owned by the human
A post starts inside its campaign. New Post, then Create with AI, and from there it is a conversation rather than a form: the user gives a goal and a few assets, Pulse reads the brand vault and the campaign, and a structured Creative Brief comes back as editable fields inside the chat. Only approval hands off to generation.
Urban runners, 18–29, early-morning crews
City miles before the city wakes
Short-form video · street-level POV
Confident, unhurried
Natural light, muted brand palette
Draft brief is ready — audience and tone come from your brand vault.
assistant · plain text, no bubble
user · ink bubble, right-aligned
rich content · a card; inline controls stay flat
Two gates and a guardrail keep a person in charge
Approval runs through an ordered chain — reviewer, brand admin, org owner — with SLA timers and an escalation that never auto-approves. A plan gate signs off direction and spend before any credits burn; a content gate signs off the finished creative before it goes live.
AI can draft and schedule. A person releases to publish.
The guardrail is independent of the gates, so turning approvals off never lets an agent publish on its own.
Rebuilding a vibe-coded page, step by step
The clearest proof of all this is the Campaign page. It reached me as a teammate’s quick, vibe-coded prototype — one four-thousand-line HTML file, styles inlined, images pasted in as data, no system underneath. It looked like a product and behaved like a draft.
Over about two and a half weeks I rebuilt it on the base, a commit at a time: I pulled the status tabs and badges out as real components, reshaped the flow from a flat Campaign Library into a decision-first Overview — what needs your approval and what’s mid-production, with the assistant proposing directions from the week’s signals — added the plan-diff gate and the approval chain, and finally let it consume the design-system components directly. Same brief; a real product. A picture became something engineering could receive and a designer could keep owning — which is the whole point.


Most memorable moment
From shipping pages to building the system that ships them.
Pulse did not hand me a design-system brief. It handed me a melee: one product, six tools, a deadline, and the discovery that pages which look identical can share nothing at all. The real deliverable was never one more screen. It was the base underneath all of them.
So the work became structure. Tokens instead of taste, components instead of copies, and written rules an AI loads instead of instructions repeated into a chat box. Design reads previews, engineering reads a typed package, ML reads data states, product reads one runnable flow. The melee ended when everyone stopped squeezing into the same files and started shipping from the same base.
One rule survived every iteration untouched: AI can draft and schedule, but a person always releases to publish. Speed where it helps, a deliberate checkpoint where it matters. That balance, not the automation, was the design.