41 rules for the visual tells of AI-generated design. Each one has a made-up page in two versions, the same except for the tell, so you can see exactly what to change.
Run the detector
The detector renders a page in headless Chromium and reports which rules fire, with a score from 0 to 100. It needs a local Chrome or Chromium (setCHROME_PATH to choose one).
Terminal
pnpm add -D ../brandcloud/packs/brandcloud-antipatterns-0.9.0.tgz # packed from the repository, see Getting started
pnpm exec brand-detect https://your-site.co.uk # desktop, 1440 by 900
pnpm exec brand-detect dist/index.html --mobile # 390 by 844
pnpm exec brand-detect dist/index.html --json # machine-readable
pnpm exec brand-detect dist/index.html --max-score 9 --fail-on high # CI gate: exit 1 on failure
Scoring: high 12, medium 7, low 4, capped at 100.0 to 9: clean; 10 to 29: some tells; 30 to 59: reads as AI; 60 to 100: obviously AI. Aim for 0 to 9 and no high-severity rule.
Pages that use absolute asset paths (most built sites) need to be served, not opened as files, so the detector sees their CSS. Rules can be extended with addRules()or a JSON pack named by AP_EXTRA_RULES, in the same shape as rules.json.
The example pages with the tell are shown here as screenshots on purpose, so this page itself stays clean. Each pair also opens as a live page.
Colour and gradient
Hue-shifting 'AI' gradient
AP-GRAD-01, high severity
Gradients that travel across hues (indigo to violet, purple to pink, blue to cyan to pink) on buttons, backgrounds or badges.
Why it reads as generated: Indigo and violet gradients are the default accent of Tailwind demos and the training data behind most generators, so they became the signature colour of generated sites. There is no light source that produces them, so they read as decoration.
Fix: Use a single-hue tonal gradient that models light: lighter top, deeper bottom, thin sheen, same-hue shadow (e.g. #3b82f6 to #1d4ed8). Take it from tokens (action-depth-*, level-*), never hard-coded hex.
With the tell
Fixed
AP-GRAD-01: the same page with the tell (left) and fixed (right).
Headline words filled with a gradient via background-clip: text.
Why it reads as generated: The single most repeated hero treatment in generated landing pages: one or two words of the H1 clipped to an indigo or purple gradient.
Fix: Solid ink headline. Let the wording and the size carry the emphasis. If a word must stand out, change the sentence, not the paint.
With the tell
Fixed
AP-GRAD-02: the same page with the tell (left) and fixed (right).
Large absolutely positioned circles with heavy blur or soft radial gradients floating behind content.
Why it reads as generated: Generators add 'depth' by dropping two or three blurred coloured orbs behind the hero. They carry no information and are the same on every page.
Fix: Remove the blobs. Create depth with real content: a photograph of the work, a tonal brand section, or a clear contrast step between paper and ink.
With the tell
Fixed
AP-GRAD-03: the same page with the tell (left) and fixed (right).
Section backgrounds built from several layered radial gradients or a conic gradient in different hues.
Why it reads as generated: Mesh and aurora backgrounds are a stock generator move to make an empty section feel designed.
Fix: One brand colour section with a single-hue tonal gradient (e.g. deep navy top to slightly deeper bottom), or a flat colour. Never more than one hue family.
With the tell
Fixed
AP-GRAD-04: the same page with the tell (left) and fixed (right).
Centred, saturated box-shadow or text-shadow glows on buttons, cards, icons and headings.
Why it reads as generated: Neon glow shadows are the generator's way of signalling 'premium' or 'AI'. On real objects light casts a shadow below, not a halo all round.
Fix: Neutral or same-hue shadows with a vertical offset (light from above). At most one soft halo, on the primary action.
With the tell
Fixed
AP-GRAD-05: the same page with the tell (left) and fixed (right).
Semi-transparent panels with backdrop-filter: blur() holding body text.
Why it reads as generated: Frosted glass cards over gradient blobs are a 2021 Dribbble trend that generators still reach for. Text over a blurred, moving background loses contrast.
Fix: Solid surfaces for anything with text. Contrast checked against the actual background (WCAG 2.2 AA).
With the tell
Fixed
AP-GRAD-07: the same page with the tell (left) and fixed (right).
Every heading, paragraph and list centre-aligned down the whole page.
Why it reads as generated: Centring is the safest default for a model that does not know the content. Long centred text is harder to read and makes every section look the same.
Fix: Left-align text on a grid. Use asymmetry (wide headline column, narrower body column) and centre only short, standalone moments.
With the tell
Fixed
AP-LAY-01: the same page with the tell (left) and fixed (right).
Three, six or nine cards of identical size, each icon + short heading + one-line blurb.
Why it reads as generated: The 3-up feature row is the most common generated section. Equal weight for every item says the author did not decide what matters.
Fix: Rank the points. Lead with the one that matters most, give it room and a specific example; list the rest as plain rows. Drop the decorative icons.
With the tell
Fixed
AP-LAY-02: the same page with the tell (left) and fixed (right).
A grid of rounded tiles of mixed spans, each holding a feature blurb or a fake widget.
Why it reads as generated: Bento grids became the default 'features' layout after Apple keynotes and component libraries. Generators fill them with filler tiles because the format demands a tile count, not content. Counter-evidence: a Reddit-mined ranking puts bento grids near the bottom of complaints, so this is a weak tell on its own.
Fix: Lay out what you actually have. Real content of different kinds deserves different treatments, not equal tiles.
With the tell
Fixed
AP-LAY-03: the same page with the tell (left) and fixed (right).
Hero, logo strip, features, testimonials, pricing, FAQ, closing CTA, in that order.
Why it reads as generated: Every generated SaaS page uses the same skeleton, so a visitor can predict the next section before scrolling.
Fix: Order sections by the visitor's questions for this business (what is it, is it for me, proof, price, how to start). Merge or drop sections that have nothing specific to say.
With the tell
Fixed
AP-LAY-04: the same page with the tell (left) and fixed (right).
Every card, image, input and panel uses the same big rounded corner (rounded-2xl / rounded-3xl).
Why it reads as generated: One radius everywhere is a utility-class default, not a design decision. It flattens hierarchy and gives the soft 'template' look.
Fix: A small radius scale with roles (e.g. 4px controls, 8px cards, 0 for full-bleed media). Fewer boxes overall.
With the tell
Fixed
AP-LAY-05: the same page with the tell (left) and fixed (right).
A small monospace or wide-tracked uppercase label sitting on top of each section heading ('FEATURES', '// HOW IT WORKS').
Why it reads as generated: Kickers on every section are a generator habit borrowed from developer-tool sites. They repeat the heading and add a third type style for no reason.
Fix: Delete the kicker and make the heading say the specific thing. If navigation context is needed, use a breadcrumb or the section's own wording.
With the tell
Fixed
AP-TYPE-02: the same page with the tell (left) and fixed (right).
Accent words in headlines (colour or italic serif)
AP-TYPE-03, medium severity
Headlines with one phrase in the brand colour, a muted grey second half ('Ship faster. Without the chaos.') or one italic serif word in a sans headline.
Why it reads as generated: Two-tone headlines are the non-gradient version of gradient text. The 2026 variant is a single Fraunces or Instrument Serif italic word inside an Inter headline.
Fix: One colour and one typeface per headline. Emphasis comes from the words, the size and the line break.
With the tell
Fixed
AP-TYPE-03: the same page with the tell (left) and fixed (right).
Small absolutely positioned cards ('+38% conversions', 'Payment received') stuck over the corners of a hero image.
Why it reads as generated: Fake notifications floating over a mockup are a stock hero composition. The numbers are invented and the cards hide the image.
Fix: Show the image unobstructed. Put one real, sourced fact in the caption.
With the tell
Fixed
AP-COMP-03: the same page with the tell (left) and fixed (right).
Lists and headings that start with emoji (rocket, lightning, check, fire) as icons.
Why it reads as generated: Chat models use emoji as visual bullets and generated pages inherit the habit. On a business site it reads as unedited model output.
Fix: Plain bullets or numbered rows. Use real icons only with a purpose and a text label.
With the tell
Fixed
AP-COMP-05: the same page with the tell (left) and fixed (right).
shadcn/ui default theme variables, slate-900 6px-radius buttons and grey-bordered cards exactly as installed.
Why it reads as generated: A component kit is a starting point. Shipping its default theme means the site looks like thousands of others built from it.
Fix: Theme the kit with brand tokens: colour, type, radius scale, shadows, button family (depth / solid / ink).
With the tell
Fixed
AP-COMP-06: the same page with the tell (left) and fixed (right).
A pretend app window (traffic-light dots, skeleton bars, fake chart columns) drawn in HTML as the hero visual.
Why it reads as generated: Generators cannot show the real product so they draw a plausible one. Visitors learn nothing and it signals there is no product to show.
Fix: A real screenshot or photo of the real thing, with a caption saying what it is. If nothing exists yet, show the outcome in words or a real example.
With the tell
Fixed
AP-IMG-01: the same page with the tell (left) and fixed (right).
Every block starts invisible and slides up as it enters the viewport (AOS, framer-motion whileInView, .reveal classes).
Why it reads as generated: Generators wrap every section in the same entrance animation. Content hides from people who scroll fast, print or use reduced motion.
Fix: Content visible by default. Motion only where it explains a change (a state, an order, a reveal the user asked for), and none under prefers-reduced-motion.
With the tell
Fixed
AP-MOT-01: the same page with the tell (left) and fixed (right).
Cards that jump up or grow on hover even though they are not links.
Why it reads as generated: hover:-translate-y-1 hover:scale-105 is pasted onto every card. Motion on non-interactive things signals a click that does nothing.
Fix: Hover feedback only on interactive elements, and keep it calm (colour, underline, a 1px press).
With the tell
Fixed
AP-MOT-03: the same page with the tell (left) and fixed (right).
Infinite float, bob, pulse or shimmer animations on badges, blobs, icons and buttons.
Why it reads as generated: Looping motion is added to make static generated pages feel alive. It pulls the eye away from the content and ignores reduced motion.
Fix: No looping decoration. Loops only for real progress (a spinner while something loads) and stopped under prefers-reduced-motion.
With the tell
Fixed
AP-MOT-04: the same page with the tell (left) and fixed (right).
AP-MOT-06, medium severity, checked by the CLI only
A radial glow that follows the pointer across the page or across cards.
Why it reads as generated: Spotlight cards and cursor glows are copied from a handful of developer sites. They add work for the GPU and nothing for the reader.
Fix: Remove it. Use standard hover and focus-visible states.
With the tell
Fixed
AP-MOT-06: the same page with the tell (left) and fixed (right).
A 'Trusted by teams at' row of company names typed out as text wordmarks, often Acme, Globex, Initech or invented brands, usually greyed out.
Why it reads as generated: Generators always add a logo strip and fill it with placeholders. Visitors recognise the names, and fake proof costs more trust than none.
Fix: Only real clients you may name. One named client with what you did beats twelve grey logos.
With the tell
Fixed
AP-TRUST-01: the same page with the tell (left) and fixed (right).