Vibe coding gets you a working page in fifteen minutes. It just looks like every other one: a purple to blue gradient, a centered headline, three equal cards with icons, sentences like Unlock the power of. People now recognise this look at a glance, and with it they take the offer behind it for interchangeable. That is not the tool's fault; a language model without constraints builds the average. This guide shows the typical tells, explains where they come from and gives four remedies: rules in AGENTS.md, finished components, your own design tokens and a checklist before going live.
- The AI look is a sum of default decisions: indigo to purple as a gradient, a centered hero with two buttons, three equal cards, glass and glow, icons that say nothing, stock phrases and invented numbers.
- It happens because a model without constraints builds the most likely result. Style words like modern, clean or premium change nothing; they describe exactly that average.
- What helps are constraints with values: colors as hex codes, two fonts, one radius, explicit bans. They belong in the file the tool reads with every request, not in a single prompt.
- In Tailwind 4, --color-*: initial removes the whole default palette. Then bg-indigo-500 simply no longer exists, and the agent has to use your own colors.
How do you spot a website that looks AI-generated?
By a handful of default decisions that show up together. None of them is wrong on its own, but in this combination they sit on so many generated pages that people read them as a pattern rather than as design.
- Color: a gradient from indigo through violet to purple, often as a gradient inside the headline too.
- Layout: a centered hero, a small badge with a sparkle icon above it, two buttons side by side below.
- Cards: three or six equal cards with an icon in a colored square, a shadow and a lift on hover.
- Material: glass cards with blur and glowing edges on a dark background, with nothing behind them to see through to.
- Icons: a sparkle for anything AI, a bolt for speed, a shield for security, or emoji straight away.
- Copy: Unlock the power of, seamless, supercharge your workflow, built for the future.
- Proof: round numbers without a source such as 10,000+ happy customers and quotes from people who do not exist.
The last two are more than a style problem. Invented numbers and quotes on a real page are misleading, and they show the moment someone asks.
Why do vibe-coded websites all look the same?
Because a language model without constraints builds the most likely result, and the most likely result is the average of everything it has seen. Every decision you do not make, the model makes, and it makes it the same way every time.
The tools add to it. Lovable and v0 set up their projects with React, Tailwind and the base components of shadcn/ui. Tailwind 4.2 ships a palette of 26 hues in 11 steps each, among them indigo-500, violet-500 and purple-500, whose hues sit at 277, 293 and 304 degrees. A gradient across just under 27 degrees always looks coherent, so it is the safe choice. Icons work the same way: lucide-react ships exactly 1688 icons in version 0.575, and the model picks the ones whose names match the words in the prompt.
Style words do not help. Modern, clean, sleek or premium are not constraints but descriptions of the average. A prompt with these words confirms to the model that the default is what you want.
- Build a modern, clean, professional landing page for my booking app.
- Landing page for a booking app for physiotherapy practices. Background #f6f4ef, text #1c1917, one accent #c2410c. Headings in Fraunces, body in Albert Sans. Hero left aligned with a photo of a treatment room on the right. No gradients, no emoji, no invented numbers.
Which rules belong in AGENTS.md to avoid the AI look?
Bans and values instead of style words: which colors exist, which fonts, which radius, and which patterns must not appear. A model sticks to a list of hex codes far better than to a feeling, because it can take them literally.
The rules belong in the file the tool reads with every request, not in a single prompt. AGENTS.md is the open format for this and is read by Codex and Cursor, among others. Claude Code reads CLAUDE.md; a line @AGENTS.md in it pulls in the same rules. The app builders have places of their own: Lovable its Instructions in the project settings plus an AGENTS.md in the repository, Bolt the Knowledge field, v0 its Instructions, Replit the replit.md file.
## Design rules - Colors: background #f6f4ef, text #1c1917, one accent #c2410c. No other hues. - No gradients. Never purple, violet or indigo. - Fonts: Fraunces 600 for headings, Albert Sans 400 for body. Nothing else. - Radius: 8px on controls, 12px on cards. - No glass, no glow, no shadows on cards. - Icons only where they carry meaning, never emoji. - Never three equal feature cards in a row. - Copy: short, concrete sentences. Never unlock, seamless, supercharge, elevate, the power of. - No invented numbers, logos or quotes. Use a TODO.
Does a component library via MCP help against the AI look?
Partly. It replaces what the model invents worst, namely layout, spacing and motion, but it solves neither copy nor images nor a missing brand.
When the agent fetches a section from an MCP server, it gets finished code that someone designed and tested, and it has nothing to assemble from the average. That is the biggest lever against the three equal cards and the centered default hero. Some servers also return components already in a brand's colors and fonts, Systra Tools for example through get_component_styled.
Three limits remain. First, when many people use the same library unchanged, their pages look alike again, just at a different level. Second, app builders like to rewrite code they take over and often remove exactly the details it was picked for. Third, copy and images still come from the agent, and the AI impression arises there just as much.
How does a generated page get your own brand?
Through design tokens that are settled before the first prompt: a handful of colors, two fonts, one or two radii as CSS variables that every component reads. The agent then no longer inserts a color but a name like bg-accent.
In Tailwind 4 the tokens live in the @theme block. The first line matters most: --color-*: initial removes the whole default palette. After that, bg-indigo-500 and from-indigo-500 produce no CSS, and the agent cannot accidentally use a color that does not exist. White and black go with it and have to be added back.
If you have no brand yet, take one from a site whose feel fits: colors, fonts and spacing can be read from an existing website and taken over as tokens. Add one to three reference images to the chat that show what you mean; Lovable, Bolt and v0 accept images in the prompt.
@theme { --color-*: initial; --color-white: #ffffff; --color-paper: #f6f4ef; --color-ink: #1c1917; --color-accent: #c2410c; --font-display: "Fraunces", serif; --font-sans: "Albert Sans", sans-serif; --radius-control: 8px; --radius-card: 12px;}
How do you check a generated page before it goes live?
With a short list that asks about each tell from the first section on its own, ideally with fresh eyes or in a new chat without the previous history. Whoever just built the page no longer sees the average.
- Color: Does the code still contain indigo, violet, purple or a gradient? The commands below find it in seconds.
- Layout: Do two neighboring sections share the same layout? Then solve one of them differently.
- Icons: Does every icon say something the text next to it does not? Otherwise remove it.
- Copy: Does one of the banned phrases appear, and can every claim be backed up?
- Proof: Is every number, logo and quote real? Whatever is not real comes out, placeholders included.
- Logo test: Could you swap the logo for another without anyone noticing? Then the page still lacks something of its own.
# default palette hues and gradient utilitiesgrep -rnE "(indigo|violet|purple)-[0-9]+" src/grep -rnE "bg-(linear|gradient)-to-" src/ # stock phrases in the copygrep -rniE "unlock the power|seamless|supercharge" src/
If you can swap the logo without anyone noticing, the page is not done yet.






