When you ask generative AI to create a screen, these patterns appear every time.
- A hero section centered on the full screen with a large heading, subtext, and a CTA button below
- Three-column cards with equal width and icons
- Backgrounds or headings with gradients from purple to blue
- Headers with a wordmark, five links, and a CTA on the far right
- Footers with four columns of links and social media icons
- Pure black
#000000text on a pure white#ffffffbackground
You can tell immediately. And once you know what to look for, you stop trusting it.
Because readers assume, "The content is probably generic too."
This is not an issue of the model's aesthetic taste. It is an issue of missing input.
Why the Mode Appears
When you ask to "create a profile screen," no colors, fonts, or whitespace are specified.
When asked to make decisions without reference material, the model outputs the most frequent patterns from its training data. The list above represents that mode.
In other words, as long as you leave visual design decisions to the implementation role, this result is unavoidable.
Adding prompts like "make it stylish" or "make it modern" won't change anything.
Those words are also linked to the same modes in the training data.
The Solution: Finalize Specifications Before Implementation
There is only one thing to do. Separate the design decision process from implementation.
[UI Design] Write docs/design/21-profile.md
↓ Only after specifications are finalized
[Implementation] Implement using the spec as the sole input
If the implementation role needs a design element not described in the spec, they must stop implementing and return it for revision rather than deciding on their own. This is the key point. If you allow "I inferred this because it wasn't written," the inference will revert to the mode.
Order of Decisions
Structure → Tokens → States → Motion → Copy.
The meaning lies in not starting with color. If you start with color, the skeleton remains in the mode, and only the color scheme changes, resulting in the same screen structure.
1. Structure
Decide the page skeleton first. Set one rule:
Do not repeat the same skeleton as the previously created screen.
If three consecutive screens all have "Hero + 3 Columns + Footer," you haven't designed them.
Each screen should have a skeleton suited to its purpose.
A list screen might not need a hero section at all.
There is likely no reason to place three-column cards on a settings screen.
2. Tokens
- One anchor color. Decide one primary color and keep others achromatic or derived from it.
- Up to two typefaces. Headings and body text, or body text and monospace.
- Do not use gradient backgrounds or gradient headings.
- Do not use pure black
#000000or pure white#ffffff.
The last item requires explanation. Pure black and pure white do not exist in reality on paper or objects under natural light. They read as unadjusted. Simply shifting slightly to something like #16203D and #FFFEFB changes the impression significantly.
3. Define All 8 States
default / hover / focus-visible / active / disabled / loading / error / success
Missing states will be invented by the implementation role during coding. This causes breakdowns in consistency.
Two are particularly easy to forget and cause real issues if omitted:
-
focus-visible— Appearance during keyboard navigation. If omitted, users navigating solely with a keyboard lose track of their current position. Implementations that only haveoutline: nonewithout alternatives occur because this wasn't designed. -
loading— Appearance during asynchronous processing. If omitted, you get buttons where it's unclear whether they were clicked or not.
4. Motion
Subtract before adding. Remove animations that don't result in information loss when removed.
The only criterion is this. Movements "just to make them look smooth" only increase wait times. Limit to three types per screen.
5. Copy
Write the text in the spec. This means do not let the implementation role come up with the copy.
And do not fabricate numbers, testimonials, or logos. Leave uncertain values as — (TBD). If you write "10,000+ Users" thinking of it as a placeholder, it will be published as is. This actually happens frequently.
Inspection
Even if you write a spec, it's meaningless if you don't verify that implementation follows it.
Reduce inspection items to those that can be mechanically checked during review.
| Inspection Item | Condition for Return |
|---|---|
| Colors & Fonts | Raw color codes or font names other than the spec's tokens exist in the code |
| States | Any of the 8 states is missing |
| Structure | Elements are added or omitted that are not in the spec |
| Motion | Animations exist that are not in the spec |
| Copy | Strings different from the spec are used |
You can check "whether color codes are hardcoded" using grep.
Making it possible to judge without subjective input ensures reviews function properly.
The return destination is the design role, not the implementation role. Because the cause is a deficiency in the spec.
Design One Screen at a Time
Finally, one operational note.
Do not parallelize design. If you let multiple screens be designed simultaneously,
you cannot detect structural duplication with the previous screen. As a result, everything ends up with the same skeleton.
Implementation can be parallelized, but design must be done one screen at a time.
Summary
- AI-like screens are born from missing input, not lack of taste
- Separate the design decision process from implementation and make the spec the sole input
- Decide structure first. Starting with color leaves the skeleton in the mode
- Define all 8 states.
focus-visibleandloadingare particularly easy to miss - Reduce inspection items to forms that exclude subjective judgment
- Do not parallelize design
I have distributed a configuration where this design role is defined as a Claude Code sub-agent, combined with implementation and review roles. The free version (4 personas, no UI design role) is published under MIT.
Related
- Assigning 5 Personas to Claude Code for Parallel Development
- What Works and What Doesn't in CLAUDE.md
- Is Your AI-Generated Code Review Just a Formality?
I publish the configuration for splitting Claude Code into separate personas —
Architect, Coder, Reviewer, Conflict Resolver — under MIT. Copy it, run
./setup.sh, and it works. It does not depend on your tech stack.
https://github.com/quintetkit/quartet
I built one real tool using nothing but this workflow. Every Issue, PR, review
and merge is still there. The parts that went wrong were not deleted.
https://github.com/quintetkit/mdlinkcheck
The version that adds a UI Designer persona, review criteria, a per-Issue
parallel execution script and a 10-chapter guide is on the
product page.
The full kit — five personas, the scripts and the complete guide — is available here.
Top comments (2)
The strongest part is the return rule: implementation stops and sends it back rather than inferring. That one line removes most of it.
Two things I'd add from running something similar.
Your token rules are negative ones. One anchor colour, no gradients, no pure black or white, no repeated skeleton. They work, and what they do is push the output away from the average. They don't say what it moves toward. A screen can clear every one of those checks and still not look like your product, because not-the-mode and yours are different targets.
The second is where the mode comes back. If the design role is also a model, the spec gets written by the same distribution that produced those screens. It reverts in prose instead of pixels, and it reads as reasonable, because prose always does. Your return path catches inference during implementation. It has nothing watching inference during specification.
What closed that for me was a short list of cases the team had already argued about, written before the design role runs. Not principles, decisions. It gives the spec something to be measured against that the model didn't supply itself.
Both of these land, and the second one is the hole.
You're right that the token rules are all exclusions. They define a
complement, not a target — which is why two products following them end up
equally not-the-mode and still not themselves. I'm adding the positive half:
one anchor colour, one type pairing, a density, a motion character, decided
one anchor colour, one type pairing, a density, a motion character, decided
once and binding, so the spec has something to be measured toward and not
only away from.
The specification point is the one I didn't have. The return path fires when
the Coder needs to leave its scope — that is implementation-time inference,
and it is visible because the scope is declared in the Issue. Nothing declares
what the spec may assume, so the design role drifts and the drift reads as
reasonable. Prose always does.
I think your fix works because prior decisions are the one input the model did
not produce. That is also its failure mode: if the list gets generated too, it
is the same distribution wearing a different hat. So it has to be arguments
people actually had, written down with what was rejected and why — the
rejected option is what makes it checkable later.
What I am doing with it: a decisions file the design role must read and may
not contradict, and every choice in the spec has to cite the decision it comes
from. A choice that cites nothing is the one to look at.
Thanks — this changed the design, not the wording.