---
name: frontend-design
description: Create beautiful, accessible user interfaces with shadcn/ui components, Tailwind CSS utility-first styling, and principled design systems. Prevents "AI slop" aesthetic by providing opinionated guidance across typography, color, motion, and layouts. Use when building user interfaces, implementing design systems, creating responsive layouts, or establishing consistent styling patterns that avoid generic convergence.
license: MIT
version: 2.0.0
---

# Frontend Design Skill

Comprehensive skill combining **practical UI implementation** (shadcn/ui, Tailwind CSS) with **principled design systems** (avoiding AI slop, typography, color theory) for creating distinctive, accessible interfaces.

## When to Use This Skill

Use when:

- Building UI with React-based frameworks (Next.js, Vite, Remix, Astro)
- Implementing accessible components (dialogs, forms, tables, navigation)
- Creating responsive, mobile-first layouts
- Styling with utility-first CSS approach
- Implementing dark mode and theme customization
- Avoiding generic "AI slop" aesthetics (Inter fonts, purple gradients)
- Building design systems with consistent tokens
- Rapid prototyping with immediate visual feedback

**Don't use** for purely functional CLIs, backend systems, or when visual design is irrelevant.

---

## Part 1: Implementation (shadcn/ui + Tailwind CSS)

### Core Stack

#### Component Layer: shadcn/ui

- Pre-built accessible components via Radix UI primitives
- Copy-paste distribution model (components live in your codebase)
- TypeScript-first with full type safety
- Composable primitives for complex UIs
- CLI-based installation and management

**Reference:** https://ui.shadcn.com/llms.txt

#### Styling Layer: Tailwind CSS

- Utility-first CSS framework
- Build-time processing with zero runtime overhead
- Mobile-first responsive design
- Consistent design tokens (colors, spacing, typography)
- Automatic dead code elimination

**Reference:** https://tailwindcss.com/docs

### Common Patterns

#### Responsive Layout

```tsx
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
  <Card>Content</Card>
</div>
```

#### Dark Mode

```tsx
<div className="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
  Content adapts to theme
</div>
```

#### Accessible Components

```tsx
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog";

<Dialog>
  <DialogTrigger>Open</DialogTrigger>
  <DialogContent>
    <DialogHeader>Fully accessible</DialogHeader>
  </DialogContent>
</Dialog>;
```

### Installation Quick Start

```bash
# Initialize shadcn/ui
npx shadcn-ui@latest init

# Add components
npx shadcn-ui@latest add button dialog form table

# Tailwind is auto-configured
```

---

## Part 2: Design Principles (Avoiding AI Slop)

### The Problem: Distributional Convergence

LLMs naturally converge to "safe" design choices that appear frequently in training data:

- **Typography**: Inter, Roboto, Arial (predictable, boring)
- **Colors**: Purple gradients on white backgrounds (clichéd)
- **Layouts**: Cookie-cutter patterns (immediately recognizable as AI-generated)
- **Result**: Generic aesthetic that undermines brand identity and quality perception

**Root Cause**: During sampling, models drift toward high-probability choices. Even with instructions, convergence happens without explicit reminders.

---

### Four Design Dimensions

#### 1. Typography

**❌ AVOID** (distributional convergence traps):

- Inter, Roboto, Open Sans, Arial
- System fonts (unless intentional for performance)
- Low-contrast pairings (400 weight with 500 weight)
- Safe, predictable font stacks

**✅ USE** (distinctive, high-impact):

**Monospace:** JetBrains Mono, Fira Code, Courier Prime, Space Mono

```tsx
<p className="font-mono text-sm tracking-tight">Distinctive code aesthetic</p>
```

**Display:** Playfair Display, Bricolage Grotesque, Syne, Cabinet Grotesk

```tsx
<h1 className="font-display text-6xl font-bold">Bold statement</h1>
```

**Serif:** Merriweather, Crimson Text, Lora, EB Garamond

```tsx
<p className="font-serif text-lg leading-relaxed">Elegant body text</p>
```

**Sans-serif (alternative):** DM Sans, Manrope, Plus Jakarta Sans, Satoshi

```tsx
<p className="font-sans text-base">Clean, modern alternative</p>
```

**Weight Contrast:** Pair 300 with 700, or 400 with 800 (not 400 with 500)

#### 2. Color

**❌ AVOID**:

- Purple gradients (`from-purple-500 to-pink-500`)
- Pure white backgrounds (`bg-white`)
- High-saturation rainbow colors
- Gradient overkill

**✅ USE**:

**Muted Backgrounds:**

```tsx
<div className="bg-stone-50 dark:bg-stone-950">
  {/* Subtle warmth, not stark white */}
</div>
```

**Accent Colors (choose one):**

```tsx
// Amber (warm, inviting)
<Button className="bg-amber-600 hover:bg-amber-700">

// Emerald (fresh, trustworthy)
<Badge className="bg-emerald-600">

// Slate (professional, calm)
<Card className="border-slate-300 dark:border-slate-700">
```

**Gradients (subtle, directional):**

```tsx
<div className="bg-gradient-to-br from-stone-100 to-amber-50 dark:from-stone-900 dark:to-amber-950">
  {/* Natural light direction */}
</div>
```

#### 3. Motion

**❌ AVOID**:

- No animation (static, lifeless)
- Over-animated (distracting bounces, spins)
- Instant transitions

**✅ USE**:

**Subtle Hover States:**

```tsx
<Button className="transition-all hover:scale-105 hover:shadow-lg">
  Micro-interaction
</Button>
```

**Smooth Transitions:**

```tsx
<Card className="transition-colors duration-200 hover:bg-stone-100">
  Natural state change
</Card>
```

**Staggered Animations:**

```tsx
{
  items.map((item, i) => (
    <div
      key={item.id}
      className="animate-fade-in"
      style={{ animationDelay: `${i * 100}ms` }}
    >
      {item.content}
    </div>
  ));
}
```

#### 4. Layout & Backgrounds

**❌ AVOID**:

- Centered content on pure white
- Generic hero sections
- Cookie-cutter card grids

**✅ USE**:

**Asymmetric Layouts:**

```tsx
<div className="grid grid-cols-3 gap-8">
  <div className="col-span-2">{/* Main content */}</div>
  <div className="col-span-1">{/* Sidebar */}</div>
</div>
```

**Textured Backgrounds:**

```tsx
<div className="bg-[url('/noise.png')] bg-stone-50">
  {/* Subtle texture adds depth */}
</div>
```

**Visual Hierarchy:**

```tsx
<section className="space-y-12">
  <h1 className="text-7xl font-display font-bold">Hero</h1>
  <p className="text-xl text-stone-600 max-w-2xl">Supporting text</p>
  <Button size="lg">Clear CTA</Button>
</section>
```

---

## Design System Template

### Tailwind Config (Opinionated)

```ts
// tailwind.config.ts
export default {
  theme: {
    extend: {
      fontFamily: {
        sans: ["DM Sans", "sans-serif"],
        display: ["Bricolage Grotesque", "sans-serif"],
        mono: ["JetBrains Mono", "monospace"],
      },
      colors: {
        primary: {
          50: "#fef8ee",
          // ... amber scale
          900: "#451a03",
        },
      },
      animation: {
        "fade-in": "fadeIn 0.5s ease-out forwards",
      },
      keyframes: {
        fadeIn: {
          "0%": { opacity: "0", transform: "translateY(10px)" },
          "100%": { opacity: "1", transform: "translateY(0)" },
        },
      },
    },
  },
};
```

### Component Example (Distinctive Design)

```tsx
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";

export function FeatureCard() {
  return (
    <Card className="border-amber-200 bg-gradient-to-br from-stone-50 to-amber-50 dark:from-stone-900 dark:to-amber-950 transition-all hover:shadow-xl hover:scale-[1.02]">
      <CardHeader>
        <CardTitle className="font-display text-3xl font-bold text-amber-900 dark:text-amber-100">
          Distinctive Feature
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <p className="font-sans text-stone-700 dark:text-stone-300 leading-relaxed">
          Clear, purposeful copy with proper contrast
        </p>
        <Button className="bg-amber-600 hover:bg-amber-700 font-mono text-sm tracking-wide">
          Take Action
        </Button>
      </CardContent>
    </Card>
  );
}
```

---

## Best Practices

### Implementation ✅

- Use shadcn/ui for accessible components (copy-paste, no dependencies)
- Tailwind for utility-first styling (fast, consistent)
- TypeScript for type safety
- Mobile-first responsive design
- Dark mode support via `dark:` prefix

### Design Principles ✅

- **Typography:** Avoid Inter/Roboto, use distinctive fonts
- **Color:** Muted backgrounds (stone-50), single accent color (amber/emerald/slate)
- **Motion:** Subtle hover states, smooth transitions (not over-animated)
- **Layout:** Asymmetric grids, visual hierarchy, textured backgrounds

### Anti-Patterns ❌

- Generic purple gradients
- Pure white backgrounds
- No animation (lifeless)
- Cookie-cutter card grids
- Low-contrast font pairings

---

## Quick Reference

**Install:**

```bash
npx shadcn-ui@latest init
npx shadcn-ui@latest add button card dialog form
```

**Opinionated Starter:**

```tsx
<div className="min-h-screen bg-stone-50 dark:bg-stone-950">
  <header className="border-b border-stone-200 dark:border-stone-800">
    <nav className="container mx-auto px-4 py-4 font-mono">
      {/* Navigation */}
    </nav>
  </header>

  <main className="container mx-auto px-4 py-12">
    <h1 className="font-display text-7xl font-bold text-stone-900 dark:text-stone-100 mb-6">
      Distinctive Headline
    </h1>
    <p className="font-sans text-xl text-stone-600 dark:text-stone-400 max-w-2xl mb-8 leading-relaxed">
      Supporting copy with proper hierarchy
    </p>
    <Button className="bg-amber-600 hover:bg-amber-700 font-mono">
      Clear CTA
    </Button>
  </main>
</div>
```

---

## See Also

- shadcn/ui docs: https://ui.shadcn.com
- Tailwind CSS docs: https://tailwindcss.com/docs
- Radix UI primitives: https://www.radix-ui.com
- Google Fonts (for distinctive typography): https://fonts.google.com
