How I design. Then how I ship it.

17 pages shipped to production as reviewed PRs at a YC company, plus two self-initiated AI products. I write the decision first, then build and merge it, never unreviewed.

Tokens carry the decision. The page is derived.

Product design starts below the screen. The call is written down first: who it is for, the job, what recedes. Tokens encode it, and everything above them inherits, so nothing on the page is a default nobody chose.

  1. Tokens 180+ WCAG-tested tokens at LexisNexis, named for usage.
  2. Variants & states Closed sets. No CSS rule, no variant.
  3. Components Five primitives, 808 lines, 29 demos on this engine.
  4. Composed page Typed content in, on-brand page out. No raw hex.
  5. Shipped 17 pages, each merged as a PR someone else cleared.

Below is the Marker primitive's real variant set. It stays closed because a variant with no CSS rule renders invisible, which I found out the hard way.

KNOWN_VARIANTS
Component
.demo-marker--default
Page slice

variant: default → 1 component, 1 page slice

THE REGISTERS is the same ladder at page scale: one component set, re-derived under whole token systems. Bold flat motion, liquid glass, Y2K, spatial. Where a register stops being a recolor I rebuild the switcher in that register's own language, and knowing where tokens stop is the rest of the job.

The rest of this page is that method on someone else's production repo.

Claude design in, merged PR out.

At Surface Labs (YC) I was the contract design engineer on the marketing surface. Every page was mine from the first decision to the merge, with no handoff and no unreviewed merge.

The decision is written first.

Nothing gets built until the call is on paper: who it is for, what it claims, one named direction, and what recedes. The direction is locked by hand before the machine proposes anything.

A real preflight for a data-licensing client's valuation page, written before a pixel existed. Client details redacted. The reasoning is mine.

Design preflight Written before build

A data-licensing client · 2026-08-21 · client details redacted

Audience
Owner-level buyers at small, established US firms. Time-poor, and judging whether this is legitimate before they answer anything.
Job
Classification: process. The claim the page makes is that your answers become a valuation. The verb is assembles.
Direction
Category reflex, first order: a friendly cream intake form with a progress bar. Refused. Second order: a dark AI page with neon gradients and glass. Also refused. What survives both is deal-document grammar.
Hierarchy
Leads: one question per view, then the answer, then the continue action. Recedes: the trust strip stays small but always visible, because its absence is itself the defect.

Every decision is a fork. I lock one.

For anything that matters the AI lays out a fork: real options, a recommendation, and the tradeoff between them. I lock one, sometimes against the recommendation, and it builds what I lock.

One rule sits above it: no production code until the mockup is approved.

One engine, every page on-brand.

Velocity without a system produces drift, so the engine comes before the pages. The template owns the brand; my judgment goes into direction, not into re-deciding a margin per page.

A check in CI refuses raw hex, so off-kit style cannot merge. The build is documented in the Surface Labs case study.

Green tests are not a working product.

Pulse held 116 tests green and a clean typecheck while a compare panel contradicted the heatmap beside it. Ghost rendered headings white on white, invisible, with every test still passing. Tests assert that things exist. They cannot see that the pixels are wrong.

So the AI reviews its own work adversarially: reviewers raise findings, then separate refuters attack each one before it counts. On Pulse that loop confirmed 16 real bugs with 0 false positives. A green suite proves the code ran. Only a watched render proves the design works.

Five dimensions, separate hands.

A self-grade cannot see its own taste, so finished work goes out to independent judges, one per dimension, scoring the render and nothing else.

A real board on my own work. Two dimensions came back at 1, each with an exact falsifier. I fixed both on the judges' terms and remeasured instead of arguing the score.

The grade I do not give myself Judged

A data-licensing client · 2026-08-21 · client details redacted

  • Distinctiveness2
  • Signature presence2
  • Restraint1
  • Memorability2
  • Craft1
Total 8 / 10

No dimension at zero, which clears the bar. A cleared bar is a floor, never a verdict.

The restraint judge's falsifier

Typing restarted the memo line's entrance per keystroke. 21 measured restarts, row at opacity 0 while typing.

Fixed the same hour: animate only on blank to filled, quiet amendments after. Remeasured at 1 restart per field.

Five of five self-grades that were later rechecked moved down. None moved up or held. Standing count as of 2026-08-28.

Six early merges out. Three reviewed PRs in.

Nothing of mine merges until another set of eyes clears it. That rule has a source: six of my commits once went in early on a live company repo. I pulled all six, then re-landed the work as three consolidated PRs, each cleared by a reviewer.

On someone else's production repo, the discipline is the deliverable. I would rather be the designer who takes six merges back out than the one who leaves them in and hopes.

Memory is infrastructure, not notes.

A method only compounds if the AI remembers. Early on that meant one file read every session, around forty thousand tokens, mostly irrelevant to the task. I re-architected it: a small always-loaded core, topical rule files pulled when the matching work starts, a failure checklist read only at review time.

Session-start cost dropped by more than an order of magnitude. Each bug a review catches becomes one line, so the next session never re-debugs it. Same instinct as a design token: solve a thing once, encode it, then stop solving it.

Figures measured at the 2026-06-10 restructure, when the rule files were split.

Picture and sound run off one timing function.

At Surface Labs I built a Remotion video system, not a one-off render. Change the data and the motion and the audio re-time together, because both read the same clock (the films play silent on this page).

I composed it on Surface tokens and synthesized the sound kit in code, so a film cannot drift off-brand or out of sync. No stock assets.

Seven tools. One job each.

Speed comes from knowing which tool owns which job, and holding that line under pressure. I do not generate imagery in code and I do not draw a flagship visual in code. That rule is written down.

Figma

Where a surface starts when it has to be drawn before it can be argued.

Claude Design

The design surface for a flagship visual. It produces the approved artifact. Code only lands it.

Claude Code

Production build and merge, in the real repo, never a prototype branch.

ChatGPT

Image generation, at my hand, anchored to approved references. Never free-handed in code.

Higgsfield

AI video and motion footage, under the same rule as imagery.

Remotion

Code-rendered film. One data file per film, one timing function driving picture and sound.

Playwright

Verification. A frame series across a full loop, watched, before anything is surfaced.

Four things you can open.

Surface Labs runs in production. Pulse and Ghost are self-initiated, built in code, and open as live demos. The fourth is the site you are reading. All four were built this way.

Surface Labs

Marketing pages designed in Claude and shipped to production. Live on withsurface.com.

Pulse

A living UX observatory. Scrub time, watch friction heat up, ship the fix.

Ghost

A design system reality scanner. Pick the canon, measure the drift.

This portfolio

Vanilla HTML, CSS, and JS. Every animation on it built and verified the same way.

The operating model, end to end.

That is the whole loop: write the decision, fork, build, verify, revert, remember. This year it built Pulse and Ghost in code, and shipped core pages to production at Surface Labs.

If that is the designer you are hiring, I would love to talk.

Get in touch →