14 KiB
Examples & Case Studies
Real-world examples demonstrating correct and incorrect application of frontend design principles.
Table of Contents
- Case Study: Blog Search Bar (Design Consistency)
- Example: Component Reuse Decision Matrix
- Example: Typography Consistency
- Example: Layout Pattern Matching
- Anti-Example: Generic AI Slop
Case Study: Blog Search Bar
Context: Adding a search bar to a blog page in an existing Next.js application.
❌ WRONG APPROACH (Autopilot Mode)
What happened:
User: "Blog page needs a search bar"
Assistant: [Sees SearchBar component exists] → [Pastes component into blog page] → Done
Implementation:
// Blog page
<section className="py-6 px-6">
<div className="max-w-5xl mx-auto">
<SearchBar value={searchQuery} onChange={setSearchQuery} />
</div>
</section>
// SearchBar component (from tools page)
export default function SearchBar({ value, onChange }: SearchBarProps) {
return (
<div className="relative max-w-2xl mx-auto"> {/* ← PROBLEM: Centered with narrow container */}
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4" />
<Input value={value} onChange={onChange} className="pl-10" />
</div>
);
}
Result:
- ❌ Search bar centered on left-aligned page
- ❌ max-w-2xl container inside max-w-5xl container
- ❌ Visual inconsistency with rest of blog page
- ❌ Breaks design language
Visual outcome:
Blog Page (LEFT-ALIGNED, max-w-5xl)
┌─────────────────────────────────────────────────┐
│ Blog │
│ Real-world guides... │
│ │
│ ┌──────────────────┐ │ ← Centered, narrow
│ │ [Search bar] │ │
│ └──────────────────┘ │
│ │
│ [All Posts - left-aligned cards] │
└─────────────────────────────────────────────────┘
✅ RIGHT APPROACH (Design-Thinking Mode)
Process:
Phase 1: Design Language Analysis
## Design Language Analysis
### Files Scanned
- src/app/blog/page.tsx (blog landing page)
- src/app/page.tsx (tools page for comparison)
- src/components/SearchBar.tsx
- src/components/CategoryFilter.tsx
- src/app/globals.css
### Layout Patterns
- Blog page: LEFT-ALIGNED layout throughout
- All blog sections use max-w-5xl container
- Category filter buttons are left-aligned
- Blog cards grid is left-aligned
- Tools page (for comparison): CENTERED layout
- Tools hero uses max-w-3xl centered
- Tools SearchBar uses max-w-2xl centered
**Key insight:** Blog page has CONSISTENT left-aligned pattern with max-w-5xl containers.
### Component Patterns
- SearchBar component exists with built-in max-w-2xl mx-auto (centered)
- This pattern works for tools page but NOT for blog page
- Category filter on blog page is left-aligned (not centered)
Phase 2: Design Decisions
## Design Decisions
### Pattern Application
Blog page requires LEFT-ALIGNED full-width search within max-w-5xl container.
Cannot use SearchBar's centered max-w-2xl pattern - would break consistency.
### Component Approach
Options:
1. Add width/alignment variant props to SearchBar component
2. Create inline search input specifically for blog page
3. Create new FullWidthSearchBar component
Decision: Option 1 - Extend SearchBar with optional props
- Maintains component reuse
- Allows flexibility for different layout contexts
- Avoids code duplication
### Consistency Requirements
MUST maintain:
- max-w-5xl container (matches rest of blog page)
- Full width within container (left-aligned, not centered)
- Same input styling (h-11, pl-10, bg-card, search icon)
- Same search functionality
CAN vary:
- Container width and alignment (adapts to page context)
Phase 3: Implementation
// Enhanced SearchBar component with layout props
interface SearchBarProps {
value: string;
onChange: (value: string) => void;
placeholder?: string;
fullWidth?: boolean; // New prop
}
export default function SearchBar({
value,
onChange,
placeholder = "Search...",
fullWidth = false // Default to centered (backward compatible)
}: SearchBarProps) {
return (
<div className={`relative ${fullWidth ? 'w-full' : 'max-w-2xl mx-auto'}`}>
<Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4" />
<Input
type="text"
value={value}
onChange={(e) => onChange(e.target.value)}
placeholder={placeholder}
className="w-full pl-10 pr-4 h-11 bg-card"
/>
</div>
);
}
// Blog page usage
<section className="py-6 px-6">
<div className="max-w-5xl mx-auto">
<SearchBar
value={searchQuery}
onChange={setSearchQuery}
placeholder="Search posts by title, author, or tags..."
fullWidth={true} // Matches blog's left-aligned pattern
/>
</div>
</section>
// Tools page usage (unchanged, backward compatible)
<section className="py-6 px-6">
<div className="max-w-5xl mx-auto">
<SearchBar
value={searchQuery}
onChange={setSearchQuery}
// No fullWidth prop = defaults to centered
/>
</div>
</section>
Result:
- ✅ Search bar matches blog page's left-aligned layout
- ✅ Consistent max-w-5xl container width
- ✅ Component reuse with flexibility
- ✅ Backward compatible (tools page unchanged)
- ✅ Design language preserved
Visual outcome:
Blog Page (LEFT-ALIGNED, max-w-5xl)
┌─────────────────────────────────────────────────┐
│ Blog │
│ Real-world guides... │
│ │
│ ┌─────────────────────────────────────────────┐ │ ← Full width, left-aligned
│ │ [Search bar] │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ [All Posts - left-aligned cards] │
└─────────────────────────────────────────────────┘
Key Lessons
- Don't skip analysis - The checklist exists for a reason
- Scan multiple files - Understanding context requires comprehensive analysis
- Document patterns - Explicit output makes thinking visible
- Consider reuse vs creation - Adapt existing components when possible
- Match the context - Blog's left-aligned pattern ≠ Tools' centered pattern
Example: Component Reuse Decision
Scenario: Need a card component for a new dashboard section.
Analysis
Existing components found:
ToolCard- Border, rounded corners, hover effect, vertical layoutBlogPostCard- Border, rounded corners, gradient header, vertical layoutFeatureCard- No border, shadow effect, horizontal layout
Decision Matrix
| Option | Pros | Cons | Decision |
|---|---|---|---|
| Reuse ToolCard | Matches border/rounded style | Vertical layout might not fit | ❌ Layout mismatch |
| Reuse FeatureCard | Horizontal layout fits | No border/rounded style | ❌ Style mismatch |
| Create DashboardCard | Perfect fit for needs | New component = maintenance | ⚠️ Only if truly different |
| Extend ToolCard with layout prop | Reuses existing + flexible | Small refactor needed | ✅ Best choice |
Implementation
// Extended ToolCard with layout variant
interface ToolCardProps {
tool: Tool;
layout?: 'vertical' | 'horizontal';
}
export default function ToolCard({ tool, layout = 'vertical' }: ToolCardProps) {
const isHorizontal = layout === 'horizontal';
return (
<div className={`border rounded-lg p-4 hover:border-foreground/20 transition-all
${isHorizontal ? 'flex items-center gap-4' : 'flex flex-col'}`}
>
{/* Content adapts to layout */}
</div>
);
}
Example: Typography Consistency
Scenario: Adding a new "About" page to existing site.
Analysis Output
## Typography Patterns (from existing pages)
### Heading Hierarchy
- H1: text-3xl md:text-4xl, font-semibold, tracking-tight
- H2: text-xl md:text-2xl, font-semibold
- H3: text-lg, font-medium
### Body Text
- Default: text-base, leading-relaxed
- Small: text-sm
- Meta/timestamps: text-xs, text-muted-foreground
### Font Family
- Primary: Inter with fallbacks
- No display font used
- No monospace needed (no code samples)
Correct Implementation
// About page - matches existing hierarchy
<div className="max-w-3xl mx-auto">
<h1 className="text-3xl md:text-4xl font-semibold tracking-tight mb-4">
About Us
</h1>
<p className="text-base leading-relaxed mb-6">
Our story begins...
</p>
<h2 className="text-xl md:text-2xl font-semibold mb-3">
Our Mission
</h2>
<p className="text-base leading-relaxed">
We believe in...
</p>
</div>
❌ Incorrect Implementation
// DON'T: Different sizes, weights, tracking
<div className="max-w-3xl mx-auto">
<h1 className="text-5xl font-bold tracking-wide mb-6"> {/* ← Too large, too bold */}
About Us
</h1>
<p className="text-lg leading-normal mb-8"> {/* ← Larger than existing pages */}
Our story begins...
</p>
<h2 className="text-2xl font-bold mb-4"> {/* ← font-bold instead of font-semibold */}
Our Mission
</h2>
</div>
Example: Layout Pattern Matching
Scenario: Adding a "Pricing" page.
Pattern Analysis
Existing page patterns:
- Home: Centered hero (max-w-3xl) → Wide content (max-w-5xl)
- Blog: All sections left-aligned (max-w-5xl)
- Tools: Centered hero (max-w-3xl) → Wide grid (max-w-5xl)
Decision: Pricing is marketing content, matches "Home" pattern.
Correct Implementation
// Pricing page - matches Home pattern
export default function PricingPage() {
return (
<main>
{/* Hero: Centered, narrow */}
<section className="py-12 px-6">
<div className="max-w-3xl mx-auto text-center">
<h1 className="text-3xl md:text-4xl font-semibold">
Simple, Transparent Pricing
</h1>
</div>
</section>
{/* Plans: Wide, centered grid */}
<section className="py-8 px-6">
<div className="max-w-5xl mx-auto">
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{/* Pricing cards */}
</div>
</div>
</section>
</main>
);
}
Anti-Example: Generic AI Slop
❌ The Problem
Request: "Create a landing page for a SaaS product"
Generic AI Output:
// Predictable, seen-it-before structure
<main className="bg-white">
{/* Purple gradient hero */}
<section className="bg-gradient-to-r from-purple-600 to-blue-500 text-white py-20">
<div className="max-w-4xl mx-auto text-center">
<h1 className="text-5xl font-bold mb-6">
Revolutionize Your Workflow
</h1>
<p className="text-xl mb-8">
The all-in-one platform for modern teams
</p>
<button className="bg-white text-purple-600 px-8 py-3 rounded-lg">
Get Started
</button>
</div>
</section>
{/* Three feature cards */}
<section className="py-20">
<div className="max-w-6xl mx-auto grid grid-cols-3 gap-8">
<Card icon="⚡" title="Fast" description="Lightning fast performance" />
<Card icon="🔒" title="Secure" description="Bank-level security" />
<Card icon="📈" title="Scalable" description="Grows with you" />
</div>
</section>
{/* Testimonials */}
{/* CTA */}
</main>
Font: Inter (of course) Colors: Purple gradient (of course) Layout: Centered everything (of course)
Problem: Indistinguishable from 1000 other AI-generated SaaS pages.
✅ Better Approach
Apply design thinking:
- What makes THIS product different?
- Who is the audience? (Technical? Creative? Enterprise?)
- What feeling should the design evoke?
- What's ONE memorable element?
Example re-design (Brutalist/Technical Direction):
// Bold, distinctive approach
<main className="bg-black text-green-400 font-mono">
{/* Terminal-style hero */}
<section className="min-h-screen p-6 flex items-center">
<div className="max-w-4xl">
<pre className="text-sm mb-4">$ initialize_revolution.sh</pre>
<h1 className="text-6xl font-bold mb-4 glitch-effect">
SYSTEM<br/>
OVERRIDE
</h1>
<p className="text-lg text-green-300 mb-8 max-w-xl">
For developers who don't compromise. Raw power. Zero abstraction.
</p>
<div className="flex gap-4">
<button className="border-2 border-green-400 px-6 py-2 hover:bg-green-400 hover:text-black transition-colors">
> ssh access@deploy
</button>
</div>
</div>
</section>
{/* Asymmetric feature layout */}
<section className="p-6">
<div className="max-w-7xl mx-auto grid grid-cols-12 gap-4">
<div className="col-span-8 border-2 border-green-400 p-8">
{/* Main feature */}
</div>
<div className="col-span-4 border-2 border-green-400 p-4">
{/* Stats ticker */}
</div>
</div>
</section>
</main>
Distinctive elements:
- Terminal/command-line aesthetic
- Monospace typography
- High-contrast green-on-black
- Asymmetric grid layout
- Technical/hacker vibe
- Memorable and specific to audience
More Examples
For additional examples and techniques, see:
- REFERENCE.md - Deep-dive patterns
- NEW-PROJECT-DESIGN.md - Aesthetic philosophy
- EXISTING-CODEBASE-CHECKLIST.md - Consistency workflow