The generic look is a constraint problem, not a taste problem
Ask an agent for "a clean, modern landing page" and you will get something close to the statistical centre of every landing page it has ever seen: a centred hero, a gradient somewhere, three feature cards, a testimonial strip, a footer. It is competent. It is also indistinguishable from the last one.
This is the correct output for the prompt. "Clean" and "modern" are not constraints — they exclude almost nothing. A design brief only becomes generative when it rules things out. The four levers that actually move output away from the centre:
- A reference with extracted values — not "like Stripe", but the actual type scale, spacing rhythm and palette, pulled as numbers.
- An explicit exclusion list — the shapes you have already seen too often and will not accept.
- A structural constraint — something about the layout that cannot be satisfied by the default arrangement.
- A stopping condition — what "done" means, so the agent stops polishing the wrong layer.
Give an agent all four and the output stops averaging. Give it none and no amount of re-prompting will help, because each re-roll samples from the same unconstrained space.
Extract the reference, do not describe it
The single highest-leverage change: stop describing what a reference looks like and start handing over its real values. An agent with shell access can read them directly.
If the reference is a live page, computed styles are the ground truth — headless-browser tooling can return the resolved font stack, the actual pixel type scale, the spacing values in use, and the palette as it renders rather than as it was authored. If the reference is a file, the tokens are usually already sitting in a stylesheet or a variables block.
What to pull, in rough order of how much it changes the feel:
- Type scale — the actual sizes and line heights at each level, and the ratio between them. Most generic output uses a 1.25 ratio on a system font stack; most distinctive design does not.
- Spacing rhythm — the base unit and which multiples appear. A page built on 8px multiples reads differently from one built on 6, and neither reads like one with arbitrary values.
- The full palette, including the accent — this is the one most often dropped. An agent handed only the primary and neutral colours will produce something that reads monochrome and flat, and the fix is not "add more contrast", it is that a colour was never passed.
- Border, radius and shadow treatment — cheap to copy, and a large share of what makes a surface feel like it belongs to a family.
One caution worth stating plainly: extracting values to understand a design is not the same as reproducing someone else's brand. Learning a spacing rhythm is ordinary practice; cloning a competitor's visual identity is a rights question, and it belongs with the rights holder before it belongs in a build.
The exclusion list does more work than the description
A description tells the agent where to aim. An exclusion list tells it where the crowded ground is. In practice the second one changes output more, because the crowded ground is exactly where an unconstrained sample lands.
A workable starting list, worth editing rather than copying — the point is that it ends up yours:
- No centred hero with a subtitle and two buttons side by side.
- No three-column feature grid with an icon above each heading.
- No purple-to-blue gradient, and no gradient as the primary brand device.
- No card with a 12px radius and a soft drop shadow as the default container.
- No system font stack unless the reference uses one deliberately.
Pair each exclusion with the structural constraint that replaces it — an asymmetric layout, a rule-and-whitespace divider instead of a card, a single strong accent used sparingly rather than a gradient. An exclusion with no replacement just moves the output to the second-most-average option.
Make the agent look at what it built
The most common failure in agent-driven UI work is not a bad layout — it is an agent reporting success on markup it never rendered. Text describing a page and the page itself diverge constantly: an overflow, a broken wrap at a narrow width, an accent colour that never made it into the stylesheet, contrast that fails on the muted text.
The fix is to make rendering part of the loop rather than a thing you do afterwards. A workable cycle:
- Build the page.
- Render and capture it at a wide width, a tablet width, and a narrow width.
- Have the agent read its own captures back and list what is wrong before you look.
- Fix, re-render, repeat until the list is empty.
- Only then bring in taste.
Steps 2 and 3 are what separate an agent that iterates from one that guesses. They also make the stopping condition concrete: done is "three widths render, contrast passes, no overflow, accent present", not "looks good".
Package it as a skill so you stop retyping it
Everything above is a procedure, which means it belongs in a skill rather than in a prompt you rewrite each time. The structure that survives contact with real work:
- A trigger description specific enough that it fires on the right requests and not on every mention of the word "design".
- An inputs block — reference (URL or file), exclusion list, structural constraint, target widths.
- An ordered procedure — extract, draft, render, self-review, fix, gate. Order is load-bearing; a self-review before a render is theatre.
- A stopping condition, written as a checklist the agent can evaluate against its own output.
- An escape hatch — what to do when there is no extractable reference, so the skill degrades to "measured approximation, flagged as approximate" instead of quietly guessing.
The escape hatch matters more than it sounds. Most real briefs arrive with a screenshot rather than a live URL, and a skill that only works on the ideal input gets abandoned the second time you use it.
Or start from a design stack that already carries the constraints The Forge Design Skill Stack packages this as skills that fire on request — token extraction from a reference, a layout pass with an explicit constraint set, a contrast and spacing audit, and a rendered-output check so the agent verifies what it built instead of describing it. Built for people who would rather edit a strong first draft than argue a weak one into shape. $49 · instant download →Common questions
- Why does Claude Code keep producing the same layout?
- Because "clean and modern" excludes almost nothing, so each generation samples from the same broad space and lands near its centre. Output diverges when the brief rules things out — an exclusion list, a structural constraint and extracted reference values change results far more than a longer description does.
- Is a design skill better than just a good prompt?
- For a one-off, a good prompt is fine. A skill earns its keep on the third repeat, because it carries the ordered procedure and the stopping condition rather than relying on you remembering both. The content is the same; what changes is that it fires the same way every time.
- Can an agent extract design tokens from any site?
- From a live page it can usually read computed styles directly, which gives real values rather than estimates. From an image it cannot — that is measured approximation, and it is worth having the agent say so rather than present a guess as an extraction.
- How do I stop an agent claiming a page works when it does not?
- Put rendering inside the loop and make the agent read its own captures back before reporting. A claim based on markup it never rendered is the failure mode; a screenshot it had to look at is the cheapest available correction.