I Vibe-Coded My Site on Lovable, v0 or Bolt and It Looks Like Everyone Else's: 35 Fixes for 2026
Your Lovable site got 12 likes and one DM that said "looks AI." Here are 35 prioritized fixes (with real hex codes, shadcn class strings, and paste-ready code) to break the AI visual signature in 30 minutes, 4 hours, or one weekend.
On this page
You opened Lovable on a Sunday afternoon. You wrote a four-line prompt. You watched a complete site render in your browser, with a header, a hero, three feature cards, a pricing block with a "Pro" tier highlighted, two testimonials, a FAQ accordion, and a four-column footer. You shipped. You posted on X. You got 12 likes and one DM that said "looks AI."
That DM is the reason you're here.
This guide is not a takedown of Lovable, v0, Bolt, Replit Agent, or Claude Artifacts. They are real engineering achievements. They compress a job that used to take a freelancer five days into about ninety seconds. The problem is not that they exist. The problem is that, left on their defaults, a large share of the sites that come out of them look like they were stamped from the same press, and your site, today, is one of them.
Below is the long version of the fix. Thirty-five concrete changes, prioritized. Time budgets ranging from a single thirty-minute pass to a full day. Twelve color palettes that don't start with #3b82f6. Code snippets you can paste straight into your repo. A printable checklist. A 15-question diagnosis. We are going to walk through it like we are sitting next to each other looking at your repo on a second monitor.
This article assumes you already shipped something. It also assumes you didn't enjoy the moment your friend told you it looked like every other Lovable site on Twitter. We are not going to relitigate whether you should have used Webflow instead. You are here. Let's fix what you have.
TL;DR: 35 fixes prioritized
Here is the master table. Read it once, pick a row, and skip down to the H3 that matches if you only have time for one. Effort assumes a developer who can copy-paste, not a designer with twelve years of grid mastery. Effort and visual gain are our ratings, not measurements; visual gain runs from 1 to 5, where 5 means "your friends will ask you who redesigned it."
| # | Fix | Effort | Tech level | Visual gain |
|---|---|---|---|---|
| 1 | Drop Inter, pick a typographic duo | Low | Beginner | 5 |
| 2 | Kill Tailwind blue (#3b82f6) | Low | Beginner | 5 |
| 3 | Replace 3-card grid with dl/dt/dd, table, or prose | Medium | Beginner | 4 |
| 4 | Asymmetrize sections (60/40, 70/30, 33/67) | Medium | Intermediate | 4 |
| 5 | Ban rounded-2xl + shadow-md + gradient-to-br | Medium | Beginner | 4 |
| 6 | Replace emojis with custom SVG, ASCII, or corner brackets | Medium | Intermediate | 3 |
| 7 | Custom hero (not h1 + p + 2 buttons) | High | Intermediate | 5 |
| 8 | Kill the 3-card pricing: table or tier slider | Medium | Intermediate | 4 |
| 9 | Replace testimonial slider with one long typographic quote | Medium | Beginner | 3 |
| 10 | Footer not 4-col default | Medium | Beginner | 3 |
| 11 | Kill terminal mockup with three colored dots | Low | Beginner | 4 |
| 12 | Kill the "✨ New: ..." pill above H1 | 5 min | Beginner | 3 |
| 13 | One signature animation, not fade-in-up everywhere | Medium | Intermediate | 3 |
| 14 | Custom cursor | Medium | Intermediate | 2 |
| 15 | Unique 404 page | Medium | Beginner | 2 |
| 16 | Non-spinner loading state | Medium | Intermediate | 2 |
| 17 | Editorial voice, not "We help X do Y" | High | Beginner | 5 |
| 18 | No Unsplash blue gradient with smiling people | Medium | Beginner | 4 |
| 19 | Logo without purple gradient circle | Medium | Intermediate | 3 |
| 20 | Microcopy that isn't "Get started" / "Learn more" | Medium | Beginner | 3 |
| 21 | Form fields not default rounded gray | Medium | Intermediate | 3 |
| 22 | Custom OG image | Medium | Intermediate | 3 |
| 23 | Metadata + sitemap + robots out of Next.js defaults | Medium | Intermediate | 2 |
| 24 | Stop importing <Card> from shadcn | Medium | Intermediate | 4 |
| 25 | Replace Lucide icons with custom SVG set | High | Intermediate | 3 |
| 26 | Switch from text-gray-500 to your own neutral scale | Medium | Intermediate | 3 |
| 27 | Use named CSS variables, not bg-blue-600 everywhere | High | Intermediate | 3 |
| 28 | Real spacing scale, not Tailwind 2/4/6/8 default | Medium | Intermediate | 3 |
| 29 | Use real photography, not stock | High | Beginner | 5 |
| 30 | Custom navbar, not flex justify-between | Medium | Intermediate | 3 |
| 31 | Personality in error messages | Medium | Beginner | 2 |
| 32 | Skip FAQ accordion default: write a magazine Q&A | Medium | Beginner | 3 |
| 33 | Don't put a CTA in every section | Low | Beginner | 3 |
| 34 | Stop using text-balance and text-pretty everywhere | Low | Beginner | 2 |
| 35 | Add at least one weird typographic moment | Medium | Intermediate | 5 |
Total time if you do every single one: several days of focused work, realistically two weekends if you also drink coffee and answer Slack. The 30-minute path lower in this article tells you exactly which 4 to pick first.
The problem: why your site looks like everyone else's
Vibe coding tools share four invisible biases that compound into the same visual signature.
1. The base model has read a million Tailwind sites
Lovable, v0, Bolt, Replit Agent, and Claude Artifacts all sit on top of large language models that were pretrained on, among other things, the public web. The public web of the last four years is heavily Tailwind. Tailwind has documented defaults. Documented defaults appear more often than custom ones in training data. The model, asked to "build a SaaS landing page," reaches for the modal answer of its training distribution.
The usual result of an unsteered first generation looks like this:
bg-whiteorbg-slate-950for the pagetext-slate-900for headings,text-slate-600for bodybg-blue-600for the primary CTArounded-2xl shadow-mdfor every elevated element- A three-card grid for "features"
Interas the typeface, sometimesGeist, sometimesIBM Plex Sansif it gets adventurous
The model makers document the same tendency. Anthropic's own guide says that without guidance Claude "tends toward generic, conservative designs" and "often defaults to simplistic designs with white and purple backgrounds" (Claude Cookbook, 21 October 2025). OpenAI's GPT-5 prompting guide recommends Tailwind CSS, shadcn/ui, Lucide and fonts including Inter and Geist for new frontends (OpenAI cookbook). This is not a bug. This is the model doing what it was trained, and in some cases told, to do. The only way out is to give it constraints it has not seen countless times.
2. shadcn/ui is the lingua franca
shadcn/ui is genuinely good. It is also the default component system of v0, whose docs say "v0 uses Shadcn/ui as its default component system," and a library Lovable's own example rules tell it to prefer. The components are styled in a recognizable way: cards at rounded-xl border bg-card shadow-sm, a theme radius of 0.625rem, a neutral border token at oklch(0.922 0 0), text-muted-foreground for secondary text (shadcn/ui source and theming docs). Once you spot it twice, you spot it everywhere.
A site built on unmodified shadcn primitives has a fingerprint another developer reads in under five seconds. That fingerprint reads "AI-generated" because the modal AI-generated site is unmodified shadcn. The history of how we got here (Bootstrap, then Material, now shadcn) is its own story in the design monoculture timeline.
3. Tailwind defaults compound
Tailwind's spacing scale, color palette, and typographic ramp are all opinionated. They also ship unchanged in the vast majority of generated projects. So you end up with:
p-6andp-8everywhere because those are the visually pleasing defaultstext-3xlthentext-5xlthentext-7xlbecause those are the headline jumps in the docsgap-4for grids because that's what the documentation example usesmax-w-7xl mx-autobecause that's the canonical container width
Each individual default is fine. Stacked together, unmodified, they produce the same visual rhythm on every page that ever applies them.
4. Prompt structure rhymes
The user prompt rhymes too: "build a landing page for a SaaS that does X." Most people describe the same page in the same words, and the words leave every visual decision open. Bolt's own blog puts it plainly: "if you keep things vague and surface-level, you'll end up with a workable but cookie-cutter app" (Bolt blog, 25 September 2025). Same prompt structure, same model, same defaults, same output.
The combined effect is what we have been calling the AI visual signature in our 2026 state-of-the-AI-generated-web report. It is not one tell, it is twenty tells stacked. Each tool has its own dialect of the signature.
Tool-by-tool starting points
What each tool documents about where it starts, read on 17 October 2026. Fonts, colors and section patterns are not documented by any of them; they come from the model and the prompt.
| Trait | Lovable | v0 (Vercel) | Bolt (StackBlitz) | Replit Agent |
|---|---|---|---|---|
| Default stack | TanStack Start (React, Tailwind) for new apps; fixed | Next.js, React, Tailwind CSS, shadcn/ui | Any JavaScript framework; Node.js backend | Depends on the project |
| Where your design rules go | Design questions, knowledge, design systems | Design Systems 2.0, instructions | Project knowledge, agents.md, design systems on Teams | First message, agent customization |
| Free-plan branding | Edit with Lovable badge | Not documented | Made in Bolt badge | Made with Replit badge |
Sources: Lovable docs, v0 docs, Bolt help center, Replit docs.
Same bones, slightly different skin. If you have used two of these tools, the third feels like home immediately. That's the whole problem.
Why this happens (and why it's rational for them, but bad for you)
These tools optimize for one metric: the time-to-first-render that doesn't make the user say "this looks broken." A predictable design is a safe design. A safe design ships, gets shared, drives signups for the tool. The tool wins.
You are downstream of that. The tool got its conversion. You got a landing page that looks like the thousands of other landing pages launched the same week. The tool's interest and your interest diverge at exactly the moment the page is good enough to ship.
That divergence is the gap this article is trying to close.
Five-minute self-diagnosis
Score yourself honestly. One point per "yes." Maximum 75. Lower is better.
| # | Question | Points |
|---|---|---|
| 1 | Do you use Inter, Geist, or system-ui as your only typeface? | 5 |
| 2 | Is your primary brand color a Tailwind blue, indigo, violet, or purple? | 5 |
| 3 | Does your hero have h1 + paragraph + two buttons and nothing else above the fold? | 5 |
| 4 | Do you have a section with exactly three feature cards in a grid? | 5 |
| 5 | Do you use shadcn <Card> unmodified anywhere visible? | 5 |
| 6 | Is rounded-2xl your most common border-radius? | 5 |
| 7 | Does your pricing have exactly three tiers, with the middle one highlighted? | 5 |
| 8 | Do you have a fake terminal mockup with red/yellow/green dots in your hero? | 5 |
| 9 | Do you have a "✨ New: ..." pill or "Backed by YC" badge above your h1? | 5 |
| 10 | Are your icons all from Lucide, unmodified? | 5 |
| 11 | Is your footer four columns: Product / Company / Resources / Legal? | 5 |
| 12 | Do you use bg-gradient-to-br from-blue-500 to-purple-600 anywhere? | 5 |
| 13 | Are your stock images smiling people on a blue/purple gradient? | 5 |
| 14 | Does your CTA say "Get started" or "Start free trial" or "Book a demo"? | 5 |
| 15 | Does your headline contain the word "platform," "powerful," or "seamless"? | 5 |
Severity bands
- 0 to 15: You are doing fine. Maybe spot-check the H3s on typography and color and call it a day.
- 20 to 35: Mild slop. The 30-minute path will get you out.
- 40 to 55: Moderate slop. You need the 2-hour path. Don't ship more features until you do.
- 60 to 75: Severe slop. The 4-hour path is the floor. You probably want the 1-day path. The site, as it is, is hurting your brand.
If you scored in the middle bands, you are in good company: every "yes" above is a default that ships unless someone changes it. Normal is, unfortunately, the problem.
The 35 prioritized fixes
Each H3 below has a "before" you can match against your own code, an "after" you can adapt, and a brief explanation of why the fix moves the needle. Code is React + Tailwind because that is what the generators emit; translate to Vue, Svelte, or Astro as needed.
Fix 1: Drop Inter, pick a typographic duo
Inter is a beautiful, technically excellent typeface. It is also the visual equivalent of "navy blue suit." The moment a site loads in Inter, a part of the visitor's brain says "this is a generic SaaS." Anthropic's own frontend prompt lists Inter among the "overused font families" to avoid. Switching the typeface is the single highest-leverage change in this entire article. Low effort. Five out of five visual gain. We make the full case against Inter in the typography problem.
The trick is to pick a duo, not a single typeface. One typeface for headlines, one for body. The contrast between the two is what creates a memorable feel. Avoid using the same typeface for both, even at different weights, because that is also the LLM default.
Before:
<head>
<link rel="preconnect" href="https://rsms.me/" />
<link rel="stylesheet" href="https://rsms.me/inter/inter.css" />
</head>
<body class="font-sans antialiased">...</body>// tailwind.config.js
fontFamily: {
sans: ['Inter', 'ui-sans-serif', 'system-ui'],
}After (Space Grotesk + Space Mono):
<head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;700&family=Space+Mono:wght@400;700&display=swap" rel="stylesheet" />
</head>// tailwind.config.js
fontFamily: {
sans: ['Space Grotesk', 'ui-sans-serif', 'system-ui'],
mono: ['Space Mono', 'ui-monospace', 'monospace'],
display: ['Space Grotesk', 'ui-sans-serif'],
}Five duos worth pasting in directly:
- Space Grotesk + Space Mono: technical, slightly weird, used in the Sailop brand itself
- Fraunces + Inter Tight: editorial body, Fraunces for "magazine" h1s
- IBM Plex Serif + IBM Plex Mono: corporate but human, reads as "thoughtful"
- Migra + Authentic Sans: high-contrast display + clean body, pairs feel premium
- Söhne + JetBrains Mono: if you can afford Söhne; otherwise Inter Display + JetBrains Mono is close
If you only do one fix, do this one.
Fix 2: Kill Tailwind blue (#3b82f6)
Tailwind's blue-500 (#3b82f6) and blue-600 (#2563eb), with indigo-500 (#6366f1), violet-500 (#8b5cf6) and purple-600 (#9333ea), are the framework's stock accents, and they travel with it. The HTTP Archive's 2025 Web Almanac found indigo-500 in the CSS of 0.54% of all pages in Q4 2025, up from 0.03% in Q3 2022, and ties the rise to Tailwind's own growth (Web Almanac 2025). They are unrelated to your brand. Picking an accent that isn't one of these is its own short discipline: see how to pick an accent color that isn't Tailwind blue.
The fix is to remove every reference to Tailwind's named blues and replace with one of the twelve palettes below. Each palette is a six-color set: --bg, --surface, --ink, --ink-muted, --accent, --accent-ink. Use them as CSS variables, then map your Tailwind config to them.
Twelve anti-slop palettes:
| Name | --bg | --surface | --ink | --ink-muted | --accent | --accent-ink | Use case |
|---|---|---|---|---|---|---|---|
| Newsprint | #f6f3ec | #ffffff | #18181b | #5b5b5b | #c8362d | #ffffff | Editorial, blog, news |
| Terminal Black | #0a0a0a | #141414 | #ededed | #8a8a8a | #d6ff37 | #0a0a0a | Dev tools, infra, security |
| Bauhaus | #f4eedf | #ffffff | #1a1a1a | #555555 | #1d4ed8 | #f4eedf | Design agencies, portfolios |
| Forest Letter | #f0eee2 | #ffffff | #1f2a1f | #4a5a4a | #2f6f3d | #f0eee2 | Sustainability, wellness, food |
| Risograph | #fdf6e3 | #ffffff | #2c2c2c | #6e6e6e | #ff4f5e | #fdf6e3 | Creative tools, indie products |
| Cobalt Print | #ebe8e0 | #ffffff | #111111 | #5a5a5a | #1e3a8a | #ebe8e0 | Finance that doesn't want gradients |
| Marigold | #fffaf0 | #ffffff | #2b1d0e | #6a584a | #e6a132 | #2b1d0e | Warm consumer, hospitality |
| Slate Cathedral | #1c1f24 | #262a31 | #f1f1ee | #a3a3a3 | #c4836a | #1c1f24 | Premium B2B, brutalist |
| Lab White | #ffffff | #f6f6f6 | #0a0a0a | #6b6b6b | #00b894 | #0a0a0a | Health, lab, scientific |
| Postcard | #f5e6d3 | #ffffff | #2d1810 | #6b4f3b | #d63031 | #f5e6d3 | Travel, restaurants |
| Carbon Lime | #0e0e0e | #1a1a1a | #f5f5f5 | #888888 | #b8ff00 | #0e0e0e | Crypto, dev tools, energy |
| Plum Office | #f4ecf2 | #ffffff | #2a1a2a | #6a5a6a | #6b21a8 | #f4ecf2 | Productivity, calm B2B |
Implementation:
/* globals.css */
:root {
--bg: #0a0a0a;
--surface: #141414;
--ink: #ededed;
--ink-muted: #8a8a8a;
--accent: #d6ff37;
--accent-ink: #0a0a0a;
}// tailwind.config.js
theme: {
colors: {
bg: 'var(--bg)',
surface: 'var(--surface)',
ink: 'var(--ink)',
'ink-muted': 'var(--ink-muted)',
accent: 'var(--accent)',
'accent-ink': 'var(--accent-ink)',
transparent: 'transparent',
current: 'currentColor',
},
}This kills bg-blue-600 text-white everywhere. It also breaks the visual fingerprint immediately. Read more about why Tailwind blue and the purple gradient became the AI signature in our deep dive on the topic.
Fix 3: Replace the 3-card grid with dl/dt/dd, table, or flowing prose
The three-card "features" grid is the single most recognizable AI-generated layout pattern: grid grid-cols-3 gap-6, icon on top, bold heading, two sentences of body. Lovable does it. v0 does it. Bolt does it. Your visitors have seen it countless times this year, and three identical cards tell them nothing about which feature matters; the argument is in the card-grid problem.
There are at least four better ways to present feature lists.
Pattern A: Description list
<section class="max-w-3xl mx-auto px-6 py-24">
<h2 class="font-display text-4xl mb-12">What this thing does</h2>
<dl class="space-y-10">
<div class="grid grid-cols-[140px_1fr] gap-8 items-baseline">
<dt class="font-mono text-sm uppercase tracking-wider text-ink-muted">01 / Routing</dt>
<dd class="text-ink text-lg leading-relaxed">
Inbound calls are matched to the right team in under 200ms, with a fallback chain you control from a single YAML file.
</dd>
</div>
<div class="grid grid-cols-[140px_1fr] gap-8 items-baseline">
<dt class="font-mono text-sm uppercase tracking-wider text-ink-muted">02 / Memory</dt>
<dd class="text-ink text-lg leading-relaxed">
Caller context persists across sessions for ninety days. No PII leaves your region.
</dd>
</div>
</dl>
</section>Pattern B: Comparison table
<table class="w-full text-left border-collapse">
<thead>
<tr class="border-b border-ink/20">
<th class="py-4 font-mono text-sm uppercase">Feature</th>
<th class="py-4 font-mono text-sm uppercase">Free</th>
<th class="py-4 font-mono text-sm uppercase">Team</th>
</tr>
</thead>
<tbody>
<tr class="border-b border-ink/10">
<td class="py-4">Realtime collaboration</td>
<td class="py-4 text-ink-muted">3 users</td>
<td class="py-4">Unlimited</td>
</tr>
</tbody>
</table>Pattern C: Flowing prose with marginalia
<article class="max-w-prose mx-auto prose prose-lg">
<p>
The product does three things and refuses to do anything else. It routes,
it remembers, and it reports. <span class="text-accent font-mono text-sm">- that's the whole pitch</span>
</p>
</article>Pattern D: Asymmetric two-up
A wide left column with a long primary feature description, and a narrow right column with two short ones. Breaks the three-equal-columns reflex completely.
Pick one of the four. Whichever you pick, your features section will look like nobody else's.
Fix 4: Asymmetrize sections (60/40, 70/30, 33/67)
Generated sites stack symmetric blocks. Hero centered. Three equal cards. Two equal columns. Footer four equal columns. The eye reads symmetry as "default template."
Asymmetry is the cheapest signal of intentional design. Pick a non-50/50 ratio for at least three sections.
Before:
<section class="grid grid-cols-2 gap-12">
<div>...left...</div>
<div>...right...</div>
</section>After:
<section class="grid grid-cols-12 gap-8">
<div class="col-span-7">
<!-- main content, larger -->
</div>
<div class="col-span-4 col-start-9">
<!-- secondary content, smaller, offset -->
</div>
</section>The gap between col-span-7 ending at column 7 and col-span-4 starting at column 9 leaves an empty column in the middle. That empty column is the design choice. It looks deliberate because it is.
Use col-span-8 / col-span-4, col-span-7 / col-span-5, or col-span-9 / col-span-3 depending on the content. Avoid col-span-6 / col-span-6 for any section that isn't strictly comparing two equal things.
Fix 5: Ban rounded-2xl + shadow-md + gradient-to-br
These three classes appear together so often that they have effectively become a brand mark of generated UI. They appear on cards, buttons, hero containers, badges, and modals. Together they communicate "soft, friendly, web-app." Apart, they are useful. Together, on every component, they are a signature.
The fix is to ban the trio outright at the linter level if you can, or by manual audit otherwise.
Replacement combinations:
/* Choice 1 - sharp and printed */
.card { border-radius: 0; border: 1px solid var(--ink); }
/* Choice 2 - barely rounded */
.card { border-radius: 2px; box-shadow: 4px 4px 0 var(--ink); }
/* Choice 3 - uneven */
.card { border-radius: 24px 4px 24px 4px; }
/* Choice 4 - outline only, no shadow */
.card { border-radius: 8px; border: 1.5px solid var(--ink-muted); box-shadow: none; }For gradients, ban bg-gradient-to-br from-X-500 to-Y-600 entirely. If you must have a gradient, use a single-channel one (from-accent/0 to-accent/40) or a noise gradient generated from CSS conic-gradients. Avoid the blue-to-purple diagonal at all costs.
Fix 6: Replace emojis with custom SVG, ASCII, or corner brackets
Emojis in feature cards (✨ 🚀 ⚡ 🔒 🎯 💡) are the textual analog of bg-blue-600. They communicate "default LLM output." They date your site to the AI generation era.
Three replacement strategies:
Strategy A: Numbered annotations
<span class="font-mono text-xs text-accent">01 /</span>
<h3 class="font-display text-2xl">Routing</h3>Strategy B: Custom inline SVG icon
<svg viewBox="0 0 24 24" class="w-5 h-5 stroke-ink fill-none" stroke-width="1.5">
<path d="M3 12h12l-4-4M15 12l-4 4" />
</svg>A custom 16-icon set takes about an hour to draw if you can use Figma. If you can't, hire a designer for $300 to draw 16 icons in a single style. It is the highest dollar-per-uniqueness ratio you can spend.
Strategy C: Corner brackets / ASCII
<div class="relative p-6">
<span class="absolute top-0 left-0 font-mono text-accent">┌</span>
<span class="absolute top-0 right-0 font-mono text-accent">┐</span>
<span class="absolute bottom-0 left-0 font-mono text-accent">└</span>
<span class="absolute bottom-0 right-0 font-mono text-accent">┘</span>
<h3>Section title</h3>
</div>Corner brackets are part of the Sailop brand on purpose. They communicate "scanner / reticle / engineering UI" without being heavy.
Fix 7: Custom hero (not h1 + p + 2 buttons)
The default generated hero is:
<section class="text-center py-32">
<span class="badge">✨ New: ...</span>
<h1 class="text-6xl font-bold">The platform for X</h1>
<p class="text-xl text-gray-600 max-w-2xl mx-auto">We help Y do Z faster than ever.</p>
<div class="flex gap-4 justify-center">
<button class="bg-blue-600 text-white">Get started</button>
<button class="border">Watch demo</button>
</div>
</section>That exact hero (badge, h1, subhead, two buttons, centered, py-32) appears in some variation on a large share of generated landing pages. It is so familiar that visitors stop reading after the first few words.
Custom hero patterns to try:
Pattern A: Quote-led
<section class="grid grid-cols-12 py-32">
<blockquote class="col-span-7 col-start-2 font-display text-5xl leading-tight">
"The job we hired this product for is the one nobody's talking about: stopping the meeting before it gets booked."
</blockquote>
<p class="col-span-3 col-start-9 self-end font-mono text-sm text-ink-muted">
[Customer name], Head of Ops at <a href="#" class="underline">[Company]</a>
</p>
</section>Pattern B: Demo-as-headline
A working interactive demo of the product is the headline. No h1. The user types in the demo and the demo responds. The product itself is the pitch.
Pattern C: Manifesto
A single 80-word paragraph in large display type. No CTA above the fold. The first CTA appears after the user has scrolled past the manifesto. Bold but very effective for products with a strong point of view.
Pattern D: Dataset hero
A live counter, a chart, a table of real data your product produced. Communicates capability without saying "powerful platform."
The hero is the most-viewed component of your site. Spending 45 minutes to make it not generic is the highest leverage 45 minutes you have.
Fix 8: Kill the 3-card pricing for a comparison table or tier slider
Three pricing tiers, middle one highlighted with a "Most popular" ribbon. We have all seen it. The pattern is fine when it is true to your product. It is rarely true to your product.
Alternative A: Comparison table
<table class="w-full">
<thead>
<tr>
<th class="text-left py-4 font-mono">Tier</th>
<th class="text-left py-4 font-mono">Solo</th>
<th class="text-left py-4 font-mono">Team</th>
<th class="text-left py-4 font-mono">Custom</th>
</tr>
</thead>
<tbody>
<tr class="border-t border-ink/10">
<td class="py-4">Price / month</td>
<td class="py-4">$19</td>
<td class="py-4">$79</td>
<td class="py-4">Talk to us</td>
</tr>
<tr class="border-t border-ink/10">
<td class="py-4">Seats</td>
<td class="py-4">1</td>
<td class="py-4">10</td>
<td class="py-4">Unlimited</td>
</tr>
</tbody>
</table>Alternative B: Usage slider
A slider where the user moves a thumb to indicate their expected usage and the price updates live. Honest, interactive, and impossible to mistake for a generated three-card.
Alternative C: One price, one button
If your product has one price, say so in one sentence. "$29/month, no tiers, no seats, no asterisks." The simplicity itself is the design.
Fix 9: Replace testimonial slider with one long typographic quote
Testimonial sliders with three logos and three two-sentence quotes are the third-most-recognizable AI-generated section. Visitors have learned to skip them entirely.
Replace with a single, long, well-set quote from a real customer. 100 to 250 words. Real photo of the human. Real attribution with role and company.
<section class="max-w-3xl mx-auto py-32 px-6">
<p class="font-display text-3xl leading-snug">
"We were paying for a meeting-scheduling tool, a CRM, a help-desk, and a calendar plugin
and they didn't talk to each other. We replaced four tools with this one and our ops
week got simpler. The thing I keep going back to is that nothing in their pricing
page tried to oversell what we got. It just worked."
</p>
<div class="mt-12 grid grid-cols-[64px_1fr] gap-4 items-center">
<img src="/customer.jpg" class="w-16 h-16 rounded-full object-cover" alt="" />
<div class="font-mono text-sm">
<div>[Customer name]</div>
<div class="text-ink-muted">Head of Operations, [Company]</div>
</div>
</div>
</section>One real quote beats five fake ones. Five real quotes will not fit, so pick the strongest.
Fix 10: Footer not 4-col default
The four-column footer with "Product / Company / Resources / Legal" is so universal that it has become invisible to users. Try one of the following.
Pattern A: Single line + sitemap drawer
<footer class="border-t border-ink/10 py-8 px-6">
<div class="flex justify-between items-center font-mono text-sm">
<span>Sailop © 2026</span>
<button class="underline">Sitemap</button>
</div>
</footer>Pattern B: Manifesto footer
A single paragraph of three sentences explaining what the company stands for, signed by the founder, with a link to email them directly.
Pattern C: Status page integration
The footer is mostly empty, except for a live indicator pulled from your status page: "All systems operational. Last incident: 47 days ago."
Pattern D: Horizontal-rule footer
<footer class="py-16 px-6">
<div class="font-display text-7xl leading-none">Sailop</div>
<div class="mt-8 grid grid-cols-12">
<div class="col-span-4 font-mono text-sm text-ink-muted">
Anti-slop frontend toolkit. Built in Paris.
</div>
<div class="col-span-3 col-start-7 font-mono text-sm">
<a href="/" class="block">Home</a>
<a href="/blog" class="block">Blog</a>
</div>
<div class="col-span-2 col-start-11 font-mono text-sm">
<a href="/legal" class="block">Legal</a>
</div>
</div>
</footer>Fix 11: Kill the terminal mockup with three colored dots
You know the one. A fake terminal window with red, yellow, and green dots in the top left, "code" in monospace inside, often syntax-highlighted, often showing a sample install command. v0 in particular loves this pattern. So does Bolt. So does every other landing page launched on Product Hunt this year.
If you must show code, show it without the chrome.
<div class="bg-surface border border-ink/20 p-6 font-mono text-sm">
<span class="text-ink-muted">$</span> npm install acme-cli
<br />
<span class="text-ink-muted">$</span> npx acme-cli check ./src
</div>If your product is a CLI, render real output, not staged output. If your product is not a CLI, do not show a terminal at all. Your users probably don't use one.
Fix 12: Kill the "✨ New: ..." pill above H1
The little pill that says "✨ New: We just shipped X →" above the headline (usually rounded-full border bg-muted px-3 py-1 text-sm) is on most generated landing pages. It is one of the fastest "AI-generated" signals for any visitor who reads tech Twitter.
Three options:
- Remove it entirely. Most pages don't need it.
- Replace with a single line in monospace below the headline: "v2.4, released April 2026."
- Move the announcement to a thin top bar above the navbar, with no emoji, no sparkle, and no gradient.
<div class="bg-surface border-b border-ink/10 py-2 px-6 text-center font-mono text-xs text-ink-muted">
Sailop v2.4 is out. <a href="/changelog" class="underline">Changelog</a>
</div>Fix 13: One signature animation, not fade-in-up everywhere
Every section fading in from the bottom on scroll has become the visual marker of a Framer-Motion-defaults site. The cumulative effect is that the page feels like it is loading forever, when in fact it is loaded. This specific tic (initial={{ opacity: 0, y: 20 }} plus whileInView on every block) has its own teardown in the motion-slop piece.
Delete this, which is on every generated section:
// the tell - repeated on every block
<motion.div initial={{ opacity: 0, y: 20 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }}>Pick one signature animation that means something on your site, and remove all the others. Examples:
- A horizontal ticker of customer logos that moves slowly only on hover
- A counter that increments once when the hero comes into view
- A cursor-following element only on the hero
- A typewriter effect on a single word in the headline
Everything else: instant. No fade. No slide.
// framer-motion stripped down
import { motion } from 'framer-motion';
export function Counter({ end }) {
return (
<motion.span
initial={{ opacity: 0 }}
whileInView={{ opacity: 1 }}
transition={{ duration: 0.4 }}
>
{end}
</motion.span>
);
}That is the only motion import on the page. Everything else is static. The page feels faster and more confident.
Fix 14: Custom cursor
A custom cursor is a small flex but a real one. It signals "the people who built this site cared about details that don't matter to anyone but them," which is exactly the brand signal generic sites can't fake.
* { cursor: none; }
.cursor {
position: fixed;
top: 0; left: 0;
width: 12px; height: 12px;
border: 1.5px solid var(--accent);
border-radius: 50%;
pointer-events: none;
transform: translate(-50%, -50%);
transition: transform 0.08s linear;
z-index: 9999;
}
.cursor.hovering { transform: translate(-50%, -50%) scale(2.5); }// minimal cursor follower
useEffect(() => {
const c = document.querySelector('.cursor');
const m = (e) => {
c.style.left = e.clientX + 'px';
c.style.top = e.clientY + 'px';
};
window.addEventListener('mousemove', m);
return () => window.removeEventListener('mousemove', m);
}, []);Disable on touch devices. Make it skip animations on prefers-reduced-motion. Keep it subtle.
Fix 15: Unique 404 page
Default Next.js 404. "404 | This page could not be found." That is what visitors who mistype a URL see. It is also a missed branding opportunity that every generated site missed.
Spend 25 minutes writing a 404 that:
- Uses your own typography
- Has a moment of humor or honesty
- Links back to the most useful pages on your site
- Includes a search box if you have one
<main class="min-h-screen grid place-items-center px-6 text-center">
<div>
<div class="font-display text-9xl tracking-tighter">404</div>
<p class="mt-6 font-mono text-sm text-ink-muted max-w-sm mx-auto">
We looked. The URL doesn't exist on this server. The most likely cause
is that we moved a page and forgot to redirect. Please tell us at
<a href="mailto:[email protected]" class="underline text-ink">[email protected]</a>
and we will fix it.
</p>
<div class="mt-12 flex gap-6 justify-center font-mono text-sm">
<a href="/" class="underline">Home</a>
<a href="/blog" class="underline">Blog</a>
<a href="/docs" class="underline">Docs</a>
</div>
</div>
</main>Fix 16: Non-spinner loading state
The default React loading state is a spinner. Spinners are fine. They are also default. A loading state can be a brand moment.
Options:
- A skeleton that matches your actual layout, with shimmer disabled
- A progress bar with copy that says what is loading: "Loading 247 customer rows..."
- A counter that ticks up: "Resolving... 0.4s"
- A monospaced log: "GET /api/customers... 247 rows... rendering..."
<div class="font-mono text-sm text-ink-muted space-y-1">
<div>→ GET /api/customers</div>
<div>→ 247 rows</div>
<div>→ rendering...</div>
</div>Loading is a moment when the user is looking at your interface and not at content. Don't waste it on a spinning circle.
Fix 17: Editorial voice, not "We help X do Y"
This is the largest single uniqueness gain you can buy. It is also the hardest, because it requires writing.
The default LLM voice for a SaaS landing page is:
"We help [audience] do [outcome] without [pain]. Powerful, seamless, and beautifully simple. Trusted by 10,000+ teams."
That sentence has been written countless times. Visitors skip it.
The fix is to write like a person, not a brand. Pick one of the following voices and commit to it.
Voice A: The technical operator
"Sailop is a scan. You paste a URL, you get the list of defaults on the page and a kit to fix them. There is no account to create. There is no dashboard. There is no marketing webinar."
Voice B: The first-person founder
"I built this because [the problem you lived, in one sentence]. So I [what you made, in one sentence]. [The one constraint you chose on purpose.]" ([Your name])
Fill it with what actually happened. A first-person story only works if it is true.
Voice C: The editorial
"Lovable says 100,000 new projects are started on its platform every day. Most of them begin from the same defaults, so consistently that experienced developers can often name the tool at a glance. This catches the defaults so you can break them."
(The figure is Lovable's own, as quoted in the HTTP Archive's 2025 Web Almanac. An editorial voice cites its numbers.)
Pick one. Use it for the hero, the about page, the docs intro, and the email replies. Do not switch voices between sections.
Fix 18: No Unsplash blue gradient with smiling people
The "stock photo of a smiling diverse team in a sunlit coworking space" is the visual analog of "We help X do Y." It is in most generated SaaS landing pages, and it is the same handful of Unsplash photos every time.
Replacements:
- Real photos of your real team, taken on your real phone, lightly graded
- Screenshots of the actual product, cropped tight
- Diagrams or technical illustrations
- No image at all: heavy typography instead
If you absolutely must use stock, choose Unsplash photos that are:
- Black and white only
- Of objects, not people
- Heavily cropped or rotated
- Layered with a duotone in your accent color
.duotone {
filter: grayscale(100%) contrast(1.2);
mix-blend-mode: multiply;
}Fix 19: Logo without purple gradient circle
A circle, sometimes a hexagon, with a from-blue-500 to-purple-600 gradient and a white or black wordmark inside. That is the logo of most generated landing pages. They are indistinguishable at favicon size.
Spend 30 minutes drawing a wordmark instead. A wordmark is just your product name set in your display typeface, possibly with one custom letter. You can do it in Figma in 20 minutes. Export as SVG.
<a href="/" class="font-display text-2xl tracking-tight">
Sail<span class="text-accent">op</span>
</a>That is a wordmark. It is unique to you. It scales. It costs zero.
Fix 20: Microcopy that isn't "Get started" / "Learn more"
Default LLM CTAs:
- Get started
- Start free trial
- Book a demo
- Learn more
- Watch demo
- Sign up for free
Each appears on most generated sites. They communicate "AI default."
Better CTAs are specific to your product and tell the user what will literally happen.
| Generic | Specific |
|---|---|
| Get started | Install via npm |
| Start free trial | Free for the first 30 days, no card |
| Book a demo | 20 minutes with the founder, this week |
| Learn more | Read the docs |
| Watch demo | See the 90-second walkthrough |
| Sign up | Create an account in 12 seconds |
Fix 21: Form fields not default rounded gray
The default shadcn input (flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm) is on nearly every generated form. It is the form analog of bg-blue-600.
.field {
background: transparent;
border: none;
border-bottom: 1.5px solid var(--ink);
padding: 0.75rem 0;
border-radius: 0;
font-family: var(--font-mono);
font-size: 0.95rem;
}
.field:focus {
outline: none;
border-bottom-color: var(--accent);
}
.field-label {
display: block;
font-family: var(--font-mono);
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--ink-muted);
margin-bottom: 0.5rem;
}<label>
<span class="field-label">Email</span>
<input class="field w-full" type="email" placeholder="[email protected]" />
</label>Underlined fields with monospaced labels feel editorial. They are the opposite of the soft-rounded default.
Fix 22: Custom OG image
The default OG image generated by Next.js or by these tools is your logo on a black or white background. Half of Product Hunt has the same one.
A custom OG image takes 35 minutes if you can use Figma or Photoshop. Make it 1200×630, include:
- Your product name in your display typeface, large
- A one-line tagline below
- A subtle pattern or graphic from your brand
- Your accent color in at least one place
// app/opengraph-image.tsx (Next.js 15 default)
import { ImageResponse } from 'next/og';
export const size = { width: 1200, height: 630 };
export default async function OG() {
return new ImageResponse(
(
<div style={{
background: '#0a0a0a',
color: '#ededed',
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
padding: 80,
fontFamily: 'Space Grotesk, sans-serif',
}}>
<div style={{ fontSize: 32, color: '#d6ff37' }}>SAILOP</div>
<div style={{ fontSize: 88, lineHeight: 1, fontWeight: 700 }}>
Anti-slop frontend toolkit
</div>
<div style={{ fontSize: 24, color: '#8a8a8a' }}>
sailop.com/scan
</div>
</div>
),
{ ...size }
);
}Fix 23: Metadata + sitemap + robots out of Next.js defaults
The defaults in app/layout.tsx:
export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
};These are in the world more than you think. Real OG fetchers have crawled them. Replace with intentional metadata that reflects your real positioning.
export const metadata = {
title: { default: 'Sailop - Anti-slop frontend toolkit', template: '%s - Sailop' },
description: 'Sailop checks any live page for the defaults that make AI-built sites look identical, and returns a kit to fix them.',
metadataBase: new URL('https://sailop.com'),
openGraph: {
type: 'website',
locale: 'en_US',
url: 'https://sailop.com',
siteName: 'Sailop',
},
twitter: { card: 'summary_large_image' },
};Write a real robots.txt that does not block answer-engine bots.
User-agent: *
Allow: /
User-agent: GPTBot
Allow: /
User-agent: ClaudeBot
Allow: /
User-agent: PerplexityBot
Allow: /
Sitemap: https://sailop.com/sitemap.xmlGenerate a real sitemap. Submit to Google Search Console. Do not skip these steps because they are boring; they are the difference between a site that ranks and a site that doesn't.
Fix 24: Stop using `<Card>` from shadcn. Write your own primitives
shadcn's Card, CardHeader, CardContent, CardFooter produce a recognizable rhythm: 24px padding, 16px gap between header and content, rounded-2xl border bg-card text-card-foreground shadow-sm. Once you spot it, you spot it on a hundred sites.
Write your own primitives. They can be twelve lines of code.
// components/Block.tsx
type BlockProps = { children: React.ReactNode; tone?: 'default' | 'accent' };
export function Block({ children, tone = 'default' }: BlockProps) {
const styles = tone === 'accent'
? 'bg-accent text-accent-ink'
: 'bg-surface text-ink border border-ink/10';
return (
<div className={`${styles} p-8 relative`}>
<span className="absolute top-2 left-2 font-mono text-xs text-accent">+</span>
<span className="absolute top-2 right-2 font-mono text-xs text-accent">+</span>
<span className="absolute bottom-2 left-2 font-mono text-xs text-accent">+</span>
<span className="absolute bottom-2 right-2 font-mono text-xs text-accent">+</span>
{children}
</div>
);
}That Block component has corner brackets. It does not have rounded-2xl. It does not have shadow-sm. It looks like nobody else's. Use it everywhere you would have used <Card>.
Fix 25: Replace Lucide icons with custom SVG set
Lucide is genuinely good. Lucide is also installed everywhere. A 16-icon custom set takes one focused hour to draw.
The cheap version: take Lucide icons and modify them. Change the stroke width to 1.25, change the line caps to butt instead of round, rotate certain icons by 45°, replace certain icons with text glyphs.
// Before
import { ArrowRight } from 'lucide-react';
<ArrowRight className="w-4 h-4" />
// After (custom)
function ArrowRight() {
return (
<svg viewBox="0 0 24 24" className="w-4 h-4 stroke-current fill-none" strokeWidth={1.25} strokeLinecap="square">
<path d="M5 12h14M13 6l6 6-6 6" />
</svg>
);
}Square line caps and 1.25 stroke is a one-line change that shifts the whole feel of the icon set.
Fix 26: Switch from `text-gray-500` defaults to your own neutral scale
Tailwind's gray, slate, zinc, neutral, and stone scales carry every generated site. zinc-950 in particular has become the default dark hero: more on that in the zinc-950 tell. Pick none of them and write your own.
// tailwind.config.js
extend: {
colors: {
ink: {
DEFAULT: 'var(--ink)',
muted: 'var(--ink-muted)',
faint: 'var(--ink-faint)',
},
},
}Use text-ink for primary, text-ink-muted for secondary, text-ink-faint for tertiary. That is three colors. Three is enough. The Tailwind defaults give you eleven and tempt you to use all of them.
Fix 27: Use named CSS variables, not `bg-blue-600` everywhere
Tailwind classes like bg-blue-600 are a code smell once you commit to your own palette. Use named variables and Tailwind classes that reference them.
:root {
--bg: #0a0a0a;
--surface: #141414;
--ink: #ededed;
--accent: #d6ff37;
}// tailwind.config.js
theme: {
extend: {
colors: {
bg: 'var(--bg)',
surface: 'var(--surface)',
ink: 'var(--ink)',
accent: 'var(--accent)',
},
},
}Now your buttons say bg-accent text-accent-ink, not bg-blue-600 text-white. The semantic shift is the design shift.
Fix 28: Build a real spacing scale, not Tailwind 2/4/6/8 default
Tailwind's spacing scale is geometric and pleasing. It is also the rhythm of nearly every generated site: p-4, p-6, p-8, gap-4, gap-8. Visitors recognize the rhythm before they read the page.
Pick a base unit other than 4px. Use 6px or 7px. Multiply: 6, 12, 18, 30, 48, 78. The numbers feel slightly off, and that's the point.
// tailwind.config.js
theme: {
spacing: {
0: '0',
1: '6px',
2: '12px',
3: '18px',
4: '30px',
5: '48px',
6: '78px',
7: '126px',
},
}The default spacing scale tells your visitors "I used the defaults." Your own scale tells them "I thought about this."
Fix 29: Use real photography, not stock
If you have a physical product, photograph it. If you have a team, photograph them. If you have an office, photograph it. A real photograph, even slightly out of focus, beats the most polished stock photo for brand uniqueness.
For a software product without a physical referent: photograph the things adjacent to your product. The screen. The keyboard. The monitor. The notebook. These photographs root your brand in a real place and a real workflow.
The cost is one hour and a phone. Light is free if you wait until the right time of day. If you must compromise, license one or two original photographs from a Cherrydeck-listed photographer for a few hundred dollars and use them as your hero images.
Fix 30: Custom navbar, not `flex justify-between` with logo + nav + button
The default navbar pattern:
<nav class="flex justify-between items-center px-6 py-4">
<a href="/" class="font-bold">Logo</a>
<ul class="flex gap-6">
<li><a href="/features">Features</a></li>
<li><a href="/pricing">Pricing</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
<button class="bg-blue-600 text-white">Get started</button>
</nav>Visitors stop seeing it after page two.
Alternative A: Wordmark dominant
<nav class="grid grid-cols-12 items-baseline px-6 py-8">
<a href="/" class="col-span-3 font-display text-3xl">Sailop</a>
<ul class="col-span-6 col-start-5 flex gap-8 font-mono text-sm">
<li><a href="/install">Install</a></li>
<li><a href="/docs">Docs</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
<a href="/scan" class="col-span-2 col-start-11 font-mono text-sm underline justify-self-end">
Scan now →
</a>
</nav>Alternative B: Sidebar nav
A vertical navbar pinned to the left of the page on desktop, collapsing to horizontal on mobile. Common on documentation sites; rare on marketing sites; unique either way.
Alternative C: No navbar at all
For a single-page marketing site, navigation is a luxury that costs uniqueness. Replace it with anchor links rendered inline in the hero text.
Fix 31: Personality in error messages
Default error messages:
- "Something went wrong"
- "An error occurred"
- "Please try again later"
Each communicates "we ran out of words." The visitor disengages.
Better:
- "We tried to reach our pricing API and it didn't answer. We've alerted ourselves. If this keeps happening, email [email protected] and we'll dig in."
- "The form didn't go through. Probably our fault. Click again, and if it fails twice, the issue is on our side."
Do not be cute. Be clear and honest. Honesty is rare in error messages, and rare reads as bespoke.
Fix 32: Skip the FAQ accordion default. Write a magazine Q&A
The default FAQ is a stack of accordions, each with a one-sentence answer. Visitors expand the first, read four words, collapse it, leave.
A magazine-style Q&A reads like a real interview:
<section class="max-w-2xl mx-auto py-24 px-6">
<h2 class="font-display text-4xl mb-12">Asked frequently, answered honestly</h2>
<div class="space-y-12">
<div>
<h3 class="font-mono text-sm uppercase text-ink-muted mb-3">
Will it work with my Lovable / v0 / Bolt project?
</h3>
<p class="text-lg leading-relaxed">
Yes. Sailop's scan is built for the patterns those tools produce.
It reads the page's markup and stylesheets, checks eight common
signatures, and returns a kit to fix them.
</p>
</div>
</div>
</section>No accordion. No "+/-" icon. The answers are visible, full, real. People read them.
Fix 33: Don't put a CTA in every section
A CTA after every section ("Try it free →" repeated five times) communicates "I want you to convert and I don't care about the read." Visitors notice.
Pick three places to put a CTA:
- In the hero, but not above the fold
- After the case study or testimonial
- At the very end, after the FAQ
That is it. The other sections are content. They communicate confidence by not asking.
Fix 34: Stop using `text-balance` and `text-pretty` everywhere
text-wrap: balance and text-wrap: pretty are good CSS features. They are also the fingerprint of "developer who recently learned about CSS text-wrap and applied it everywhere," which is what generated sites do.
Use text-balance exclusively on h1 and h2. Nowhere else. Use text-pretty only on the longest paragraph in your hero. Nowhere else. Default text-wrap: normal is fine for body copy, and slightly less fashionable, which is the point.
Fix 35: Add at least one weird typographic moment
This is the fix that makes your site memorable. One typographic moment per site is enough.
Options:
- A drop cap on the first paragraph of your about page
- A vertical-orientation section title pinned to the left margin
- An oversized number used as a section index ("01" at 240px font-size)
- Marginalia: small annotations in the right margin of a long paragraph
- A pull quote that breaks out of the column with negative margins
- A single word in your hero rendered in your secondary typeface for emphasis
<article class="max-w-prose mx-auto prose-lg relative">
<p class="first-letter:font-display first-letter:text-7xl first-letter:float-left first-letter:mr-3 first-letter:leading-none">
Most landing pages are read for a few seconds before the visitor decides
whether anyone made a choice on this one.
</p>
</article>That drop cap, on its own, will make the page memorable. Pair it with one other moment from the list and your typography is doing more work than the typography of nearly every site that shipped this month.
Choose your time budget
Here is the explicit prioritization for four time budgets. Pick one and commit. Do not pick two. The budgets are rough guides, not measurements.
| Path | Budget | Fixes to do |
|---|---|---|
| Quickwin | 30 min | 1, 2, 12, 34 |
| Standard | 2 hours | 1, 2, 3, 5, 7, 17, 33 |
| Solid | 4 hours | 1, 2, 3, 5, 7, 8, 17, 24, 27, 35 |
| Total | 1 day+ | All 35 fixes, in order |
30 minutes: the quick win
You have one coffee, one focused half hour. Do these four fixes:
- Drop Inter, pick a typographic duo (Space Grotesk + Space Mono is a quick start, but Anthropic's own prompt warns that models converge on Space Grotesk too, so prefer a less common pair if you can)
- Replace
bg-blue-600with one of the 12 palettes - Remove the "✨ New: ..." pill above your h1
- Stop using
text-balanceeverywhere: keep it for h1 and h2 only
That is it. The page stops reading as a stock default at first glance.
2 hours: the standard path
Add to the 30-min path:
- Replace the 3-card features grid with a description list or comparison table
- Ban rounded-2xl + shadow-md + gradient-to-br: audit first, then replace
- Rebuild the hero: pick from the four hero patterns
- Rewrite the voice: the most important hour you'll spend
- Remove CTAs from sections that don't need them
You can ship the new version with confidence.
4 hours: the solid path
Add to the 2-hour path:
- Kill the 3-card pricing, replace with comparison table
- Stop using shadcn
<Card>, write your own primitives - Use named CSS variables instead of Tailwind blue references
- Add at least one weird typographic moment: drop cap, oversized number, or marginalia
The site now carries decisions someone made, which is the whole point.
1 day: the total path
Do all 35 fixes in the priority order in the master table. Spread them over a weekend. Take photos for fix 29 on Saturday, do the rest of the work on Sunday.
Run the self-diagnosis again at the end: most of the fifteen questions should now be a "no."
Mermaid flowchart: which path to choose
flowchart TD
A[Score yourself 0 to 75] --> B{Score >= 60?}
B -->|Yes| C[1-day path]
B -->|No| D{Score >= 40?}
D -->|Yes| E[4-hour path]
D -->|No| F{Score >= 20?}
F -->|Yes| G[2-hour path]
F -->|No| H[30-min quick win]
C --> I[Ship and audit again]
E --> I
G --> I
H --> I
I --> J{Score < 20?}
J -->|Yes| K[Done]
J -->|No| L[Step up one path]Tools to validate
Once you have applied the fixes, validate the result. Three categories of tools, in order of usefulness:
Sailop scan
The free web scan checks a live page (your preview URL or the deployed site) for eight of the most common signatures covered here: blue-family utilities, the blue-to-purple gradient, Inter or Geist as the page font, a three-equal-column grid, fade-up motion, frosted glass on several surfaces, stock button copy and soft-shadow cards. It returns what it found and a fix kit, including a brief you can paste into Claude Code or Cursor. A repository scanner (CLI) and an MCP server are planned but not published yet; the install page tracks their status.
Manual review
Open the page in an incognito window. Scroll through it once at full speed without reading anything. Ask yourself, in the first three seconds: "does this feel like the last ten landing pages I saw?" If the answer is yes, your fixes did not go far enough. If the answer is "I don't know, it's different," you are done.
Bring in one developer friend who has not seen the site before. Ask them to score it on the 15-question diagnosis. Their score will be more honest than yours.
Lighthouse for SEO, not slop
Lighthouse measures performance, accessibility, SEO, and best practices. Run it on the new version. The score should not drop. If it dropped because you switched to a custom font with too many weights, fix that. If it dropped because you removed the alt text on your custom photos, add the alt text back.
Lighthouse does not look for defaults. The scan does. Use both. Read the deeper analysis on detection signals in our guide to spotting AI-generated sites in under 30 seconds.
What Lovable / v0 / Bolt won't tell you
This section is going to read as critical of those tools. To be precise: they are good tools. But there are a few things that don't appear on their landing pages.
1. Their incentive is your conversion, not your differentiation
Each of these tools makes money when you sign up, ship, and stay. A site that ships in five minutes is a successful conversion. A site that ships in five hours is a failed conversion. Every tradeoff in the system is biased toward the five-minute case.
That is rational for the tool. It is also why your output looks like everyone else's. The tool is doing exactly what its incentives told it to do.
2. The defaults are not neutral
Inter is not a neutral typeface. bg-blue-600 is not a neutral color. The three-card grid is not a neutral layout. Each is a choice the tool made on your behalf, often without surfacing that it was a choice.
When you ship without changing the defaults, you ship the tool's brand, not yours.
3. The "ship in 5 minutes" promise has a real cost
The promise is real. Sites do ship in five minutes. The cost is paid in the long tail: every site shipping in five minutes from the same generator looks like every other site that did the same.
The cost compounds. The longer the tool is popular, the more saturated its signature becomes, the higher the slop floor, the more your unmodified output reads as generic. Two years from now, the unmodified output of today's Lovable will be embarrassing the way a 2005 default WordPress theme is embarrassing today.
4. The premium plans don't fix this
A higher plan does not give you a unique starting point. It gives you more generations, larger projects, team features. It does not change the underlying defaults, because the defaults are the model's and the prompt's, not the plan's. (Lovable's design questions, for instance, are on every plan.)
You can ship a beautiful, unique site on the free tier. You can ship a generic site on the most expensive tier. The plan is unrelated.
5. Compare their marketing pages with their blank-prompt output
Open the marketing site of the tool you use next to what a blank prompt gives you. A company's own brand page is designed to be recognizable; the default output is designed to be acceptable to everyone. The difference between the two is the work this guide is about.
6. There is a real talent in vibe coding well
We are not anti-vibe-coding. We are pro-vibe-coding plus polish. The talent is in knowing what the tool is good at (rendering layout, scaffolding components, wiring auth) and what the tool is bad at (your unique brand voice, your typographic identity, your color choices). Use the tool for the first set. Do the second set yourself.
That is the entire posture of this article. Sailop's product is a scanner that catches the things in the second set.
When vibe coding is OK and when it's not
Vibe coding is a tool. Tools have appropriate uses.
When it's OK
- Internal tools: admin dashboards, ops dashboards, CRUD pages your team uses. Nobody outside the company will see them. Defaults are fine. Ship the slop.
- MVPs and prototypes: a one-week test of an idea. The point is to learn whether the idea works, not whether the design is unique. Defaults are fine.
- Hackathon submissions: judges will look at the demo, not the design.
- Personal experiments and learning projects: defaults teach you what good is. Once you see the patterns repeat, you are ready for fix 1.
- Documentation sites and changelog pages: content is the value, design is service. Defaults are fine.
- Backend services with a thin demo UI: if your real product is the API, the dashboard is just enough scaffolding. Defaults are fine.
When it's not
- Public marketing site for a real product you charge for: your design is your brand. Defaults are not fine. Apply the 35 fixes.
- Portfolio for a creative service: designers, agencies, photographers, video producers. Your portfolio is your work. Default = "I don't take my own brand seriously." Apply the fixes.
- Brand site for any product where positioning matters: premium positioning especially cannot be reached with defaults.
- Anything you'll show to investors as a brand artifact: investors have seen a great many generated landing pages this year. Yours has to differ.
- E-commerce stores: every default Lovable e-com page looks like a Shopify Dawn theme. Apply the fixes.
- Content publications: typography is the substance. Defaults sabotage the read.
If you are in the "OK" column, do the 30-minute path anyway. If you are in the "not OK" column, do at least the 4-hour path. The 1-day path is rarely overkill in the not-OK column.
FAQ
1. I paid for Lovable Pro. Did I waste money?
No. You paid for fast scaffolding, working auth, deploy pipeline, database wiring. You got those. The fact that the default visuals are generic is a separate fact. Use Lovable to build, use this guide to differentiate.
2. Is this just typography snobbery?
Partly. Mostly it is pattern recognition. Visitors who have seen enough generated sites recognize Inter + blue-600 + three-card grid as "AI default" at a glance. That recognition costs trust regardless of whether the visitor is a typography snob.
3. Can I run Sailop on a deployed site, not a repo?
Yes, and today that is the only way: the free web scan runs against a live page's HTML and CSS. A repository scanner, which would also see config files and component code, is not published yet.
4. My site uses Tailwind v4. Do these fixes still apply?
Yes. Tailwind v4 uses CSS variables natively, so fix 27 is even easier. Otherwise the patterns and signatures are unchanged.
5. What if my client really wants a 3-card features grid?
Show them examples of both, then propose the description-list pattern as an A/B test and let the numbers decide. Bring data, not taste.
6. Should I use a CSS-in-JS library or stick with Tailwind?
Stick with Tailwind. The fixes in this article are independent of your styling library. If you change your color tokens and your spacing scale, Tailwind disappears as a uniqueness penalty.
7. Is shadcn/ui bad?
No. Unmodified shadcn/ui in your visible UI is bad. The library itself is excellent for primitives. Take what shadcn gives you, restyle the visible bits, keep the headless logic.
8. Will Google penalize me for being unique?
No. Google rewards quality content, page speed, and good crawlability. None of the 35 fixes harm those. Several improve them (custom typography subset, real metadata, real sitemap).
9. Will answer engines (ChatGPT search, Perplexity, Claude search) crawl my site after these fixes?
Yes, if your robots.txt allows their crawlers. Fix 23 covers this explicitly. Do not block GPTBot, ClaudeBot or PerplexityBot unless you have a reason to; the HTTP Archive's 2025 Web Almanac found GPTBot named in about 4.5% of robots.txt files, nearly always to disallow it, so allowing them is a choice worth making on purpose.
10. How often should I re-scan?
Every time you ship a new section or page. Run the free web scan on the preview or the live page after each release. Drift is real: you will accidentally re-add rounded-2xl six months from now, and a scan will catch it.
11. What if my designer disagrees with these fixes?
Your designer is probably right. The 35 fixes are heuristics for sites without designers. A designer who tells you "the three-card grid works for your specific audience" is making a contextual judgment that the heuristics cannot make. Trust them, but ask for the rationale.
12. Can I use AI to apply the fixes?
Yes, and you should. Run the web scan, then paste the agent brief from its fix kit into Claude Code or Cursor, and the LLM has a concrete list of what to change. The trick is giving the LLM a constraint to work against. Without the constraint, the LLM regenerates the same defaults. With the constraint, it works around them. Read our anti-slop prompt template for the prompt structure.
13. Does any of this matter on mobile?
Yes. The mobile-rendered version of a default generated site looks even more uniform than the desktop version, because mobile collapses everything into a single column and the only signals left are typography and color. That makes Fix 1 and Fix 2 the most important fixes on mobile.
14. I run an enterprise marketing site, can I still ship in a day?
The 1-day path is for one-page sites and small marketing sites of three to six pages. For an enterprise site of 30+ pages, you need a system: commit to the typography, color, spacing, and components scale once, then apply across pages over two to three weeks. Sailop scans page-by-page, so you can prioritize.
15. What's the single most important fix?
Fix 1, in our judgment. Drop Inter. Pick a typographic duo. Low effort, five out of five visual gain. If you do nothing else from this article, do that.
Annexes
A. Printable 35-fix checklist
[ ] 01 Drop Inter, pick a typographic duo
[ ] 02 Kill Tailwind blue (#3b82f6)
[ ] 03 Replace 3-card grid with dl/dt/dd or table
[ ] 04 Asymmetrize sections (60/40, 70/30, 33/67)
[ ] 05 Ban rounded-2xl + shadow-md + gradient-to-br
[ ] 06 Replace emojis with custom SVG / corner brackets
[ ] 07 Custom hero (not h1 + p + 2 buttons)
[ ] 08 Kill 3-card pricing - comparison table or slider
[ ] 09 Replace testimonial slider with one long quote
[ ] 10 Footer not 4-col default
[ ] 11 Kill terminal mockup with three colored dots
[ ] 12 Kill the "✨ New: ..." pill above H1
[ ] 13 One signature animation, not fade-in-up everywhere
[ ] 14 Custom cursor
[ ] 15 Unique 404 page
[ ] 16 Non-spinner loading state
[ ] 17 Editorial voice, not "We help X do Y"
[ ] 18 No Unsplash blue gradient with smiling people
[ ] 19 Logo without purple gradient circle
[ ] 20 Specific microcopy, not "Get started" / "Learn more"
[ ] 21 Form fields not default rounded gray
[ ] 22 Custom OG image
[ ] 23 Real metadata + sitemap + robots.txt
[ ] 24 Stop using shadcn <Card> - write own primitives
[ ] 25 Replace Lucide icons with custom SVG set
[ ] 26 Switch from text-gray-500 to own neutral scale
[ ] 27 Use named CSS variables, not bg-blue-600 everywhere
[ ] 28 Real spacing scale, not Tailwind 2/4/6/8 default
[ ] 29 Real photography, not stock
[ ] 30 Custom navbar - not flex justify-between with logo + nav + button
[ ] 31 Personality in error messages
[ ] 32 Skip FAQ accordion default - write a magazine Q&A
[ ] 33 Don't put a CTA in every section
[ ] 34 Stop using text-balance / text-pretty everywhere
[ ] 35 Add at least one weird typographic momentPrint this. Tape it next to your monitor. Tick rows as you ship.
B. Glossary
- Generator: Lovable, v0, Bolt, Replit Agent, Claude Artifacts, and similar AI tools that produce a working site from a prompt.
- Slop: content or design produced at scale with no human-level intentionality. The visual analog of repetitive, generic prose.
- Signature: the recognizable visual fingerprint of a generator's defaults, visible in 5 to 30 seconds to a trained eye.
- Tell: a single visual element that hints at AI generation. The 35 fixes correspond to the tells this guide covers.
- Anti-slop: the practice of breaking the signature; the noun version of "make it not look generated."
- Default: a setting the tool chose for you that you did not change. Where most slop comes from.
- Asymmetric layout: a section with non-50/50 column ratios; one of the cheapest signals of intentional design.
- Wordmark: your company name set in your display typeface, used as a logo. Cheaper, more unique, and more legible than a circle-with-gradient.
- Magazine Q&A: an FAQ pattern where answers are visible by default, like an editorial interview, instead of collapsed into accordions.
- Marginalia: small annotations placed in the margin next to the main text, common in print, rare on the web, distinctive when used.
- Drop cap: an oversized first letter at the start of a paragraph, classic typographic move, instantly memorable.
- Description list:
<dl>,<dt>,<dd>HTML pattern, semantically rich, visually distinct from grids.
C. Further reading
- The state of AI web design in 2026: what the HTTP Archive's public data shows
- Anti-slop prompt template: how to constrain the generator before you write the prompt
- Tailwind blue and the purple gradient as the AI signature: why these colors specifically, and what to use instead
- Detect an AI-generated site in 30 seconds: 21 signs: the inverse of this article, how visitors spot what we are trying to fix
That is the guide. If you got this far, you have the diagnosis, the prioritization, the code, the time budgets, the FAQ, the checklist, and the glossary. Pick a path. Set a timer. Ship the new version this weekend.
If you want a second pair of eyes, run the free web scan on your live page. It lists the common defaults still on it and gives you a fix kit. Apply the fix, re-scan, ship.
Your site does not have to look like everyone else's. It mostly does because nobody made the changes we just walked through. Now somebody (you) has the list. The rest is a couple of hours of work and one good cup of coffee.
Appendix D: Extended notes per fix
A handful of fixes deserve a longer treatment than fit in the H3s above. If you have the time, read these. If you don't, skip back up to the master table and pick a path.
D.1: More on typography pairing
The reason a typographic duo works is that the eye reads the contrast between the two faces as intentionality. A single typeface, even a beautiful one, used at multiple weights, reads as "designer used the defaults." A duo reads as "someone made a choice."
A good duo pairs faces with different temperaments:
- Sans + serif: modern + classic, the most common pairing, hard to get wrong
- Display + mono: expressive + technical, good for dev and infra products
- High-contrast + low-contrast: Migra (high) + Authentic Sans (low) is one example
- Two sans of different feel: Söhne (warm) + Inter Display (neutral) works because the warmth contrasts the neutrality
Avoid pairing two serifs or two sans of similar feel. The contrast collapses and the page reads "I picked two random fonts," which is worse than "I picked one default font."
For licensing: Google Fonts covers everything you need. Pay for Söhne, Migra, or Authentic Sans only if you are a serious brand and the cost is meaningful relative to your budget. The free pairings are good enough for almost everyone.
D.2: More on color palettes
The twelve palettes above are starting points. Customize them. Move the accent +/- 15° in hue. Lighten or darken the surface by 5%. Make sure your accent has enough contrast against your --ink color to clear WCAG AA on the largest button.
Run your final palette through a contrast checker before shipping: a custom palette is only as accessible as the ratios you checked.
If you must pick a palette quickly, the safest bet for a B2B product is Slate Cathedral or Cobalt Print. The safest bet for a consumer product is Postcard or Marigold. The safest bet for a developer-tool brand is Terminal Black or Carbon Lime.
D.3: More on the editorial voice
Voice is harder than typography because there is no shortcut. Three working techniques:
- Read the last six emails you sent your top customer. Use that voice on the site. Whatever made the customer respond well to your email will work on visitors.
- Record yourself describing the product to a friend. Transcribe. Edit lightly. Use that as the hero copy.
- Pick a writer you admire and read three of their pieces before writing your own. Not to copy, but to set your internal pacing and rhythm. The borrowed cadence fades, the unique voice remains.
Avoid all of these:
- "We help X do Y"
- "powerful," "seamless," "robust," "tapestry," "delve," "leverage," "navigate the landscape," "harness," "revolutionize," "empower," "unleash"
- "trusted by 10,000+ teams" without a citation
- "the future of X" anywhere
These phrases are LLM-default and reader-deaf. Visitors skim past them.
D.4: More on the four hero patterns
A breakdown of when each hero pattern works:
Quote-led hero works when:
- You have at least one customer who can articulate the value better than you can
- Your product solves a non-obvious problem (where the customer's framing is more persuasive than yours)
- Your audience is enterprise or considered-purchase
Demo-as-headline works when:
- The product is interactive and the demo can run in-browser
- The product's value is immediate and visible in 10 seconds
- Your audience is technical and prefers proof to claims
Manifesto hero works when:
- You have a strong point of view that differentiates you
- Your audience is values-driven (creative, ethical, founder-led)
- You are willing to lose visitors who don't share the view (you should be)
Dataset hero works when:
- You have real data your product produced
- The data tells a story without explanation
- Your audience is analytical (operators, finance, data teams)
Pick the pattern that matches your audience. If you can't decide, start with quote-led: it borrows the customer's words, which are usually more convincing than yours.
D.5: More on photography
Real photography is the single most effective non-typographic uniqueness move. The reason is that AI image generators produce a recognizable visual signature too: soft lighting, idealized faces, slightly waxy skin, blue-purple background bokeh. Real photographs do not have this signature, even bad ones.
A practical photography session for a software product:
- Spend 90 minutes on a Sunday morning with natural light from a north-facing window
- Photograph: your laptop, your keyboard, your monitor, your hand on the keyboard, your notebook with the product sketched, the coffee next to the laptop
- Take 200 shots. Keep 8.
- Convert to black-and-white if your brand is dark; keep color if your brand is warm
- Crop tight; show texture, not composition
The output is photographs that look like nothing else on the AI-generated web. Cost: 90 minutes and a phone. Visual gain: 5/5.
D.6: More on case study writing
Case studies are content marketing's most underrated asset. Most generated sites have either zero case studies or three thin testimonials. A long-form case study is a uniqueness signal because the work to produce it cannot be defaulted by a generator.
A working case study format:
- Problem: what the customer was trying to do, in their own words, before they found you. 200 to 300 words.
- Process: how they evaluated, what they tried, why they picked you. 200 words.
- Result: concrete metric improvement, with caveats and dates. 100 words.
- Quote: one long quote, set typographically, with a real photograph of the human.
- Footnote: what the customer would do differently, what didn't work, what is still hard. 100 words.
The footnote is what separates case studies from sales pages. Honesty in the footnote is the signal of editorial quality.
D.7: More on internal linking
Internal links signal site depth to both visitors and search engines. Generated sites rarely link internally beyond the navbar. Real sites have dozens.
Each H3 in this article links back to one of the related Sailop pieces. That is intentional. It tells search engines and answer engines that this article is part of a deeper content cluster, not a one-off post.
Apply the same to your own site:
- Every blog post should link to at least 3 other posts
- Every product page should link to at least 2 case studies
- Every case study should link back to the product feature it demonstrates
- Use descriptive anchor text, not "click here"
D.8: More on shipping the redesign
Shipping a redesign without breaking conversions is its own discipline.
The plan:
- Build the new version in a feature branch, not on main.
- Deploy to a preview URL. Send to 3 to 5 friendly users. Get reactions.
- Run Lighthouse on both versions. The new version should score within 5 points of the old.
- Run the self-diagnosis and the free web scan on both versions. The new version should answer "no" to most of the fifteen questions.
- Deploy behind a feature flag if your stack supports it; otherwise deploy at a low-traffic hour and monitor.
- Watch your analytics for the first 48 hours. The bounce rate should not jump. If it does, something specific is broken; isolate the section that broke.
- Keep the old version's source tree archived for 30 days in case you need to roll back.
When a redesign hurts, it is usually in one of two places: (a) form conversion, because the new form is too unfamiliar, or (b) the hero, because it is too clever to understand at a glance. Watch those two things.
D.9: More on the relationship between scanners and LLMs
Isn't it strange to use an LLM to undo what an LLM produced? It is not. The model is not the problem. The defaults are. A model with no constraints regenerates the most common output of its training data. A model with concrete constraints, such as a scan report saying "your page has these signatures, fix them," works around those defaults toward something of your own.
The same model can write generic copy or distinctive copy depending on what you put in front of it. That is why the web scan's fix kit includes an agent brief: it turns the findings into instructions your coding agent can act on. Check the result yourself; constraints steer the model, they do not guarantee the outcome.
D.10: Closing notes
This article will probably read as exhausting. Thirty-five fixes is a lot. The diagnosis, the time budgets, the appendix: also a lot.
The reason it is long is that the problem is real and the answer is not one fix. There is no single thing that, applied to a Lovable default site, makes it look unique. There are many small things, applied together, that compound. This article is the catalog of those things, in the order that compounds fastest.
Pick a path. The 30-minute path is a start for most people on most weekends. The 4-hour path is the minimum for any site you want to take seriously. The full path is for the site you want people to remember.
Whichever path you pick, the goal is the same: when the next visitor opens your site, the first three seconds do not register as "AI default." That is the entire bar. Three seconds. After three seconds, the content takes over and the design fades into the background. But the first three seconds are everything, and the first three seconds are exactly what generators get wrong by default.
Print the checklist. Tape it next to your monitor. Re-scan after every section ships.
Revision note
Updated on 18 October 2026. Removed: a figure of "approximately 90%" of generated sites, a stack said to recur in "8 out of 10 first generations" across "roughly 200 customer audits," a median score from "two hundred landing pages submitted by Sailop users," a chart of per-fix uniqueness gains, four "anonymized before/after case studies" with scores, signups and bounce rates, expected score drops per time budget, and a first-person quote attributed to Robin about shipping Lovable sites. None of it was documented. The defaults are now described from v0's, Lovable's, Bolt's, Anthropic's and OpenAI's own documentation, time estimates are labeled as rough, and the validation section describes the free web scan that exists today instead of a CLI and MCP server that are not published.
Scan a live page
Eight AI defaults, the evidence for each, and a fix kit. Free, no account.