How Vercel uses design.md to keep agent output on-brand in any context
Starting from the gap between in-repo and out-of-repo context, this piece breaks down how design.md, shared brand CSS, and an evaluation loop work together—and how a typical team can build its own design feedback system in six steps.
- Inside the repo, skills rely on real components and examples; outside it, agents lose that context and drift toward generic SaaS pages. Subjective style prompts don't provide stable constraints.
- Vercel uses design.md to govern design decisions, shared CSS to handle mechanical primitives, and an evaluation loop to combine human judgment with deterministic checks.
- Across six internal test pages, known mechanical failures dropped from 91 to 39—about 57% fewer—though these numbers don't reflect overall design quality, and all six pages still had release-blocking issues.
- A typical team can start with one high-frequency scenario, a bare-baseline run, and the last ten human corrections, then build a similar loop in six steps.
Vercel's design team regularly has coding agents produce reports, renewal proposals, benchmark pages, and one-off websites. Even when these artifacts don't enter Vercel's product codebase, they still have to be recognized as carrying the same brand judgment: information order has a rationale, evidence can be compared, copy makes a clear claim, and layout doesn't overshadow content.
Inside the company's codebase, an agent can read real components, design tokens, product specs, and shipped pages. Away from the repo, all that context vanishes. Vercel initially merged the reference files from its internal product-design Skill into a public prompt, but different models still interpreted words like "clean," "restrained," and "layered" as completely different pages.
In this article, Vercel details how the team rebuilt that missing context using a public design.md, shared brand CSS, and a continuous evaluation system. The whole process spans seven fixed scenarios, more than 200 runs, and a small but telling set of before-and-after comparisons.
Two core problems to solve
- Internal vs. external context gap: Inside the repo, the
product-designSkill is surrounded by real components, class names, design systems, product guidelines, and shipped examples, so abstract specs can be grounded in concrete objects. Out-of-repo tasks like proposals, reports, and standalone pages can't access any of that context, and models often fall back to generic SaaS dashboards that lack focus. - Subjective descriptions don't transfer: Telling a model the page should be "clean, simple, and layered" without executable boundaries leaves too much open. The model still has to invent typography, whitespace, components, information order, and evidence relationships. Different models turn the same sentence into very different layouts, and some even invent extra design rules that have no basis in the context.
Instead of continuing to expand that merged prompt, Vercel rewrote a design file from scratch that could work outside the repo. The team also froze seven real tasks with simulated inputs: usage and performance reports, renewal proposals, benchmark reports, interactive planning pages, build-vs-buy briefs, security governance briefs, and slide decks. With prompts, data, and rendering settings held constant, any output differences can be traced back to the design context alone.
In the first round of renewal proposal comparisons, the same environment, model, data, and viewport were used for both variants. Each side generated exactly once, with no cherry-picking of a better version. Without design.md, the page looked like a generic SaaS dashboard. With it, the page led with the renewal recommendation, arranged business evidence in a shared grid, put similar numbers on the same scale, and let supporting details sit below the summary.

This comparison shows that what out-of-repo agents lack isn't just brand color — it's the judgment about what readers should see first, how evidence gets assembled, and how details recede into supporting roles.
The three pillars of the system
To help agents produce pages that feel like Vercel across different tools and runtime environments, the team split the solution into three layers:
design.md: handles subjective judgment and strategic guidance.- Public
vercel-brand.css: handles mechanical visual constraints. - Evaluation loop: verifies whether rules take effect and routes new issues back to the right layer.
1. design.md: turning design judgment into a public spec
design.md starts by asking what a reader needs to understand and decide when they land on a page, then requires the page to present the strongest evidence-backed answer, along with any limitations that could change the conclusion. It guides agents in organizing information, building visual hierarchy, and writing restrained but specific copy, and it gives names to recurring generative-design bad habits.
The same page has to serve two reading depths: executives can quickly grasp the conclusion and next steps, while reviewers can keep tracing evidence, comparisons, and caveats. In that framing, "simple" no longer means stripping out detail — it means giving each level of information its own place.

The file describes judgments that transfer across pages: where key conclusions should sit, how evidence and copy reinforce each other, and which content should be demoted to supporting detail. Individual pages still organize around their own reader tasks — the spec doesn't compress every page into the same template.
2. Public CSS: turning repeated mechanisms into primitives
Agents used to reinvent typography, spacing, tables, stat bars, and chart styles every time. Vercel turned those decisions into bounded classes and tokens, and design.md only tells the agent which names to use in HTML. The stylesheet loads at render time in the browser, so the model doesn't have to read complex CSS into context.
That reduces two kinds of waste: the model no longer spends context describing basic styles for each page, and it's much harder for it to invent a random set of spacing, typography, and layout parameters that have nothing to do with the brand. The model's context can stay focused on the reader's task, the evidence, and composition decisions.
3. Evaluation loop: human judgment plus deterministic checks
Each fixed prompt with its simulated input forms a scenario. Regenerating all scenarios with the current files forms a round. A full round runs all seven scenarios on both Claude Opus 4.8 and Codex with GPT-5.5. If a rule only affects tables, the team can re-test just the relevant scenarios or a single model to shorten the iteration cycle.

Code checks catch mechanical failures like tables not using available width or content overflowing. Humans judge hierarchy, composition, copy, and whether the page answers the reader's question. Vercel also built a local review app that stores prompts, inputs, model configuration, design.md version, full-page screenshots, and feedback for every run, with blind A/B support.
Rules in design.md can't be added just because someone prefers them. Each guideline comes from a concrete problem exposed in a fixed scenario: the team accepts the correction, encodes it in the appropriate rule layer, re-runs the affected scenarios, and confirms the fix holds without degrading other artifacts. A rule that hasn't gone through that evaluation chain doesn't enter the file.
design.md
Reader tasks, evidence tiers, copy boundaries, composition principles, and anti-pattern names.
Shared CSS
Fonts, spacing, tables, stat bars, chart classes, and tokens; loaded at render time.
Evaluation loop
Fixed scenarios, blind A/B tests, human review, and mechanical checks; re-test other scenarios after changes.
Together, the three layers shrink the space where models can freely invent, while still leaving room for judgment about the specific material at hand. Judgment changes go into design.md, cross-page reusable mechanisms go into CSS, reliably detectable issues become code checks, and problems with the evaluation framework itself stay in the harness.
Measured results and data
- Structural changes: With
design.mdloaded, models didn't just swap colors and fonts — they started reorganizing pages around the reader's task. The renewal proposal led with the decision recommendation and then placed business evidence in comparable structures. The interactive planning page put controls front and center so readers could change numbers and see outcomes. - Known mechanical failures dropped by about 57%: Vercel picked three desktop scenarios and had Codex with GPT-5.5 generate each once with and without
design.md. Both sets kept their first results with no regeneration. The deterministic checker found 91 known failures in the group without the file, and 39 in the group with it.
Building design.md involved more than 200 runs in total, including full rounds, targeted checks, dry runs, and failed attempts. The 91-to-39 split suggests that when the team has explicitly named and encoded a mechanical problem, it recurs much less often.
That number only covers known mechanical failures. The checker can't judge overall composition, information value, or aesthetic quality, and three scenarios with six pages aren't enough to estimate long-term reliability. A more immediate limitation: all six pages, with or without design.md, still had at least one issue serious enough to block publishing.

The deterministic checker holds the line on known mechanical issues, while blind evaluation and human review keep handling hierarchy, composition, and reader value. Vercel keeps model judges in the loop to generate criticism, but also requires final sign-off from a human.
How to keep maintaining and iterating
Daily feedback collection
Vercel uses an eve-based @design-agent in Slack. When colleagues post design critiques, copy alternatives, icon suggestions, or website requests in a thread, the agent reads the current design.md, builds the page with the public stylesheet, and posts the full screenshot and a deploy link back to the thread.
Each week, the team aggregates Slack threads, GitHub reviews, and Figma comments. Automation groups repeated complaints first, then people check whether the existing system already covers them. When users start requesting new page types that haven't been tested, those tasks become new fixed scenarios.
Precision triage of fixes
- Subjective judgment, information hierarchy, and copy problems → go into
design.md. - Typography mechanisms that reuse across pages → become public CSS classes or tokens.
- Clear, measurable formatting defects → become deterministic code checks.
- Bugs in the evaluation framework itself (saving, rendering, comparison) → fix the harness.
- Issues that only appear occasionally on a single model and don't reproduce elsewhere → observe for now, and avoid adding global constraints for a single anomaly.
The "table is too cramped" case shows how this triage works. Early renewal proposals squeezed the business terms table into the same narrow width as body text. The team rewrote the complaint as an observable behavior: "Evidence tables must use the full available width." Then design.md told the agent to actively give tables more space during composition, and a code check measured whether the table was still ignoring available width.

The team also tracks how often each complaint type appears across similar work. After a fix ships, related complaints should drop. If they don't, the cause could be an unclear rule, the file not loading correctly, the CSS missing a workable primitive, or the problem needing a code check instead of more prose.
How any team can build its own design loop (6 steps)
- Pick one high-frequency scenario. Start with a report, proposal, benchmark page, or microsite that keeps coming up and has a real audience with real inputs. Write a short acceptance checklist: whether facts are preserved, whether the reader's decision is clear, and whether the most common manual corrections are addressed.
- Keep the initial baseline. Before adding design context, let the model run bare and save the prompt, input, configuration, and screenshot. If the harness has no faults, keep the first result — don't hunt for the prettiest version.
- Turn everyday complaints into observable rules. Collect ten recent pieces of design feedback and rewrite "the table is too cramped" as "data tables must use the full available width." Organize the first
design.mdaround scope, reader task, observable decisions, and available primitives. - Consolidate style decisions. Turn repeated typography, spacing, and layout mechanisms into CSS classes and tokens, and make the available names explicit to the agent. Judgment stays in the prose spec; mechanical repetition belongs in CSS or a checker.
- Run a matched blind comparison. Regenerate with the same input, model, and viewport, shuffle the baseline and the new result, and review against the same acceptance criteria. A single comparison can expose big errors; reliability requires many independent first runs.
- Iterate on real edits. Watch what users keep adjusting, and decide whether it's a missing rule, something CSS can't express, or a candidate for a mechanical check. Before writing anything in, ask: would this fix generalize beyond the current output? If not, don't elevate a one-off adjustment into a global rule. Send generalizable fixes to the narrowest rule layer, then run the next matched comparison.
Once the manual loop shows value, add hidden holdouts, model and rule version tracking, automated checks, and multiple blind reviewers. Every update returns to the same testable question: did complaints of this type actually drop in real work?
Use the first asset to draft your team's own design.md and the second to verify whether a new rule actually improves output. Copy them into a project, then adapt them with real scenarios.
- design.md starter template
- Design evaluation loop checklist
Members can copy or download the full Markdown, and let their AI subscribe and ask.
Found this useful? Leave your email — every new explainer, the moment it's out. Unsubscribe anytime.
