Bolt.new's 7 Signature Patterns (And How to Fix Each One)
Bolt.new builds full-stack apps impressively fast. Its visual defaults are less impressive: purple gradient hero, Inter font, 3-column cards, and fade-up animations. Here's how to fix all seven.
Bolt.new is one of the most capable AI coding tools available. You describe an app, it scaffolds a complete full-stack project: frontend, backend, database schema, auth. The speed is remarkable.
The visual output is a different story. Bolt uses a consistent template for landing pages and feature sections. After working through enough Bolt-generated projects, seven visual patterns appear in almost every output. This article documents all seven and gives the exact fix for each.
Pattern 1: The purple gradient hero
What Bolt generates:
.hero {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
/* hue ~248-280 — deep in the AI color band */
}This gradient is recognizable. It appears in thousands of Bolt-generated apps and in much of the broader AI-generated web. Users have associated it with "AI-made product" without necessarily being able to articulate why.
The fix:
/* Replace with a gradient outside the AI band */
.hero {
background: linear-gradient(135deg, hsl(347, 72%, 48%) 0%, hsl(347, 60%, 35%) 100%);
/* or: solid color + subtle texture */
background: hsl(347, 72%, 48%);
background-image: url("data:image/svg+xml,..."); /* SVG noise texture */
}Alternatively, remove the gradient entirely. A solid-color hero or a near-white hero with typographic focus is more contemporary in 2026 than a gradient.
Pattern 2: Inter font with no display variant
What Bolt generates:
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
/* headings use the same font — no separation */The fix:
@import url('https://fonts.bunny.net/css?family=fraunces:300,400,700ital&family=work-sans:400,500,600');
:root {
--font-display: 'Fraunces', Georgia, serif;
--font-body: 'Work Sans', system-ui, sans-serif;
}
h1, h2, h3, h4 { font-family: var(--font-display); }
body, p, li, button { font-family: var(--font-body); }The Fraunces + Work Sans pairing reads as intentional. The contrast between the optically variable serif display font and the clean geometric sans makes the typography feel designed rather than defaulted.
Pattern 3: Equal-column feature grid
What Bolt generates:
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
{features.map(feature => (
<div className="bg-white rounded-xl p-6 shadow-lg">
<feature.icon className="h-8 w-8 text-purple-600 mb-4" />
<h3 className="font-semibold mb-2">{feature.title}</h3>
<p className="text-gray-600">{feature.description}</p>
</div>
))}
</div>Three identical cards. Same icon size. Same structure. Same visual weight.
The fix:
{/* Asymmetric layout: primary feature gets more space */}
<div style={{ display: 'grid', gridTemplateColumns: '3fr 5fr', gap: '2rem' }}>
<dl style={{ display: 'flex', flexDirection: 'column', gap: '2.5rem' }}>
{primaryFeatures.map(f => (
<div key={f.title}>
<dt style={{ fontWeight: 600, marginBottom: '0.4rem' }}>{f.title}</dt>
<dd style={{ color: 'var(--fg-muted)', lineHeight: 1.65 }}>{f.desc}</dd>
</div>
))}
</dl>
<aside>
{/* Visual demo, code block, or screenshot */}
</aside>
</div>The definition list layout is more semantic and does not read as a card template.
Pattern 4: Fade-up scroll animation on every section
What Bolt generates (usually via a custom hook or library):
// useScrollReveal.ts — appears in most Bolt projects
const useScrollReveal = () => {
// IntersectionObserver adds 'visible' class
// CSS: .reveal { opacity: 0; transform: translateY(20px); transition: 0.3s ease; }
// CSS: .reveal.visible { opacity: 1; transform: translateY(0); }
}Every section gets this treatment. Same values, same easing, same distance.
The fix: Vary the animation by component type. Bolt's hook structure makes this straightforward:
/* Hero headline: clip from left */
.hero-title { clip-path: inset(0 100% 0 0); transition: clip-path 0.7s cubic-bezier(0.16, 1, 0.3, 1); }
.hero-title.visible { clip-path: inset(0 0 0 0); }
/* Features list: slide from left with stagger */
.feature { opacity: 0; transform: translateX(-20px); transition: opacity 0.5s, transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); }
.feature.visible { opacity: 1; transform: translateX(0); }
.feature:nth-child(2) { transition-delay: 0.1s; }
.feature:nth-child(3) { transition-delay: 0.2s; }
/* CTA: scale up */
.cta-section { opacity: 0; transform: scale(0.96); transition: 0.6s ease-out; }
.cta-section.visible { opacity: 1; transform: scale(1); }Pattern 5: Full-width centered CTA section
What Bolt generates:
<section className="bg-gradient-to-r from-purple-600 to-indigo-600 py-20">
<div className="max-w-4xl mx-auto text-center">
<h2 className="text-4xl font-bold text-white mb-4">Ready to get started?</h2>
<p className="text-xl text-purple-100 mb-8">Join thousands of users...</p>
<button className="bg-white text-purple-600 px-8 py-4 rounded-full font-bold">
Get Started Free
</button>
</div>
</section>Full-width accent gradient. Centered everything. "Ready to get started?" The most templated closing section on the web.
The fix: Structural asymmetry and specific language.
<section style={{ borderTop: '1px solid var(--border)', paddingBlock: '80px 100px' }}>
<div style={{ maxWidth: '700px' }}>
<h2 style={{ fontFamily: 'var(--font-display)', fontSize: 'clamp(2rem, 5vw, 3rem)', lineHeight: 1.1, textWrap: 'balance' }}>
Your code scores D on design originality.
</h2>
<p style={{ marginTop: '1.5rem', fontSize: '17px', lineHeight: 1.7, color: 'var(--fg-muted)' }}>
Scan it. See exactly what's flagged. Fix it in one command.
</p>
<a href="/install" style={{ marginTop: '2.5rem', display: 'inline-block', fontFamily: 'var(--font-mono)', fontSize: '15px', borderBottom: '1px solid currentColor', paddingBottom: '2px' }}>
npx sailop install →
</a>
</div>
</section>Left-aligned. Specific. No gradient. No "thousands of users."
Pattern 6: Identical testimonial cards
What Bolt generates:
<div className="grid grid-cols-3 gap-6">
{testimonials.map(t => (
<div className="bg-white rounded-xl shadow-md p-6">
<div className="flex items-center mb-4">
<img className="w-10 h-10 rounded-full" src={t.avatar} />
<div className="ml-3">
<p className="font-semibold">{t.name}</p>
<p className="text-gray-500 text-sm">{t.role}</p>
</div>
</div>
<p className="text-gray-600">{t.quote}</p>
<div className="flex mt-4">
{'★★★★★'}
</div>
</div>
))}
</div>Three cards. Same shadow. Same structure. Five stars on all of them.
The fix: Remove the grid. Use a single featured quote with attribution, or a pull-quote style with blockquote semantics. Three five-star identical cards read as generated. One specific, attributed quote reads as evidence.
<figure style={{ maxWidth: '600px', borderLeft: '3px solid var(--brand)', paddingLeft: '2rem' }}>
<blockquote style={{ fontFamily: 'var(--font-display)', fontSize: '1.4rem', lineHeight: 1.4, fontStyle: 'italic' }}>
"{testimonial.quote}"
</blockquote>
<figcaption style={{ marginTop: '1rem', fontSize: '14px', color: 'var(--fg-muted)' }}>
— {testimonial.name}, {testimonial.role} at {testimonial.company}
</figcaption>
</figure>Pattern 7: "Get Started Free" and "Learn More" CTAs
What Bolt generates:
- Primary: "Get Started Free"
- Secondary: "Learn More"
These are the two most common CTA strings on the web. Combined with the purple gradient, they tell users this site was generated before they read a word.
The fix: Specific language tied to what actually happens.
| Replace | With | |---------|------| | "Get Started Free" | "Scan your code free" | | "Learn More" | "See a 3-minute walkthrough" | | "Start Building" | "Run your first scan" | | "Try for Free" | "npx sailop install" |
The rule: the CTA should describe the action, not the permission to take the action.
Scanning Bolt projects
Bolt exports standard React + Vite or Next.js projects. Sailop works directly on the output:
# Export from Bolt → unzip → scan
sailop scan ./src
# Common Bolt output scores:
# Color: D (gradient hue 248-270)
# Typography: F (Inter only)
# Layout: C (grid-cols-3 × 2-3)
# Animation: D (fade-up uniform)
# Slop score: 72/100 → Grade DThe transform command rewrites all seven patterns automatically. For Bolt projects specifically, the color and typography transforms have the most visible impact.
SHIP CODE THAT LOOKS INTENTIONAL
Scan your frontend for AI patterns. Generate a unique design system. Stop shipping the same blue gradient as everyone else.