/ references / frontend-design.md
frontend-design.md
1 # Frontend Design 2 3 > **Load when:** Project has no design system, or user says "make it look good" / "design a screen" without specifying visual direction 4 > **Skip when:** Project has existing DESIGN.md, token files, or CSS variable system 5 > **Why it matters:** Without a design system, AI defaults to generic web tropes (Inter, blue gradients, rounded containers). This reference gives concrete aesthetic starting points. 6 > **Typical failure it prevents:** Generic-looking output that violates the "avoid AI slop" guideline; fonts and colors that clash instead of harmonize 7 8 ## Visual Taste Principles 9 10 ### Principle 1: Distinctive Typography Creates Identity 11 12 **Why it works:** Typography is the fastest way to establish visual identity. Generic system fonts (Inter, Roboto, Arial) are invisible because they're everywhere. Distinctive fonts create recognition and personality. 13 14 **How to apply:** Choose fonts that match the project's emotional tone. Pair a distinctive primary font with a complementary secondary font for hierarchy. Use weight variation (400/500/700) within the same family before switching fonts. 15 16 **Positive examples:** 17 - Startup/SaaS: DM Sans (clean geometric) + Source Serif 4 (professional serif) 18 - Creative portfolio: Space Grotesk (distinctive sans) + Playfair Display (classic serif) 19 - Dev tools: JetBrains Mono (monospace identity) + Outfit (modern sans) 20 21 **Negative examples:** 22 - Inter everywhere (no identity, looks like every other SaaS) 23 - Mixing 3+ font families (visual chaos) 24 - Using decorative fonts for body text (readability suffers) 25 26 ### Principle 2: Perceptual Color Harmony Over RGB 27 28 **Why it works:** oklch color space ensures colors feel equally bright and saturated to human eyes. RGB/hex colors can look muddy or clash even when mathematically "correct" because they don't match human perception. 29 30 **How to apply:** Pick one identity color, then generate harmonious variants by rotating hue (±30° for analogous, 180° for complement). Keep lightness and chroma consistent across the palette for visual coherence. 31 32 **Positive examples:** 33 - `oklch(0.55 0.18 240)` for primary, `oklch(0.55 0.18 270)` for accent (30° rotation, same L/C) 34 - Surface at L=0.95, text at L=0.15, accent at L=0.55 (clear contrast hierarchy) 35 36 **Negative examples:** 37 - Random hex colors picked from a gradient generator (no perceptual consistency) 38 - Using pure black (#000) and pure white (#fff) (harsh, no warmth) 39 - Accent colors with wildly different chroma values (some pop, some fade) 40 41 ### Principle 3: Intentional Whitespace Creates Hierarchy 42 43 **Why it works:** Whitespace isn't empty space, it's active design. More space around an element = more importance. Consistent spacing creates rhythm and makes content scannable. 44 45 **How to apply:** Use an 8px base grid. Scale by multiples (4px, 8px, 16px, 24px, 32px, 48px, 64px). Give hero sections 60% whitespace, data-dense sections 40% whitespace. One dominant element per section gets the most breathing room. 46 47 **Positive examples:** 48 - Hero with 64px top/bottom padding, 32px between headline and subhead 49 - Card grid with 24px gap, 16px internal padding 50 - Section breaks using 48-64px vertical spacing 51 52 **Negative examples:** 53 - Equal spacing everywhere (no hierarchy, everything feels the same) 54 - Cramped layouts with 4-8px everywhere (claustrophobic, hard to scan) 55 - Random spacing values (13px, 19px, 27px) that break the grid 56 57 ### Principle 4: One Visual Weight Per Section 58 59 **Why it works:** Human attention is limited. When everything screams for attention (bold text, bright colors, large size), nothing stands out. One dominant element per section creates clear focal points. 60 61 **How to apply:** Pick the most important element in each section. Make it 2-3x larger, bolder, or brighter than everything else. Everything else supports it with smaller size, lighter weight, or muted color. 62 63 **Positive examples:** 64 - Hero: 72px headline, 18px body text (4x size difference) 65 - Feature card: Bold 24px title, regular 16px description 66 - Stats section: 80px number, 18px label 67 68 **Negative examples:** 69 - Everything bold (no hierarchy, visual noise) 70 - Headline and body text the same size (no entry point) 71 - Multiple competing focal points (split attention, confusion) 72 73 ### Principle 5: Consistent Depth Language 74 75 **Why it works:** Shadows and borders create depth. Mixing shadow styles creates visual inconsistency. Pick one depth language and use it everywhere. 76 77 **How to apply:** Choose either subtle shadows (`0 1px 3px rgba(0,0,0,0.1)`) for modern/flat or dramatic shadows (`0 8px 30px rgba(0,0,0,0.12)`) for depth. Use borders (`1px solid var(--border)`) for dense layouts where shadows would clutter. Never mix shadow styles on the same page. 78 79 **Positive examples:** 80 - All cards use `0 1px 3px rgba(0,0,0,0.1)` (consistent subtle depth) 81 - All separators use `1px solid oklch(0.80 0.02 0)` (consistent borders) 82 - Modals use `0 8px 30px rgba(0,0,0,0.12)`, nothing else does (clear hierarchy) 83 84 **Negative examples:** 85 - Some cards with subtle shadows, others with dramatic shadows (inconsistent) 86 - Mixing borders and shadows on similar elements (visual confusion) 87 - Heavy shadows on every element (muddy, claustrophobic) 88 89 ## Font Selection 90 91 **Recommended fonts by project type:** 92 93 | Type | Primary | Secondary | Rationale | 94 |------|---------|-----------|-----------| 95 | Startup / SaaS | `DM Sans` | `Source Serif 4` | Clean geometric, professional serif for emphasis | 96 | Creative / Portfolio | `Space Grotesk` | `Playfair Display` | Distinctive geometric sans, classic serif contrast | 97 | Technical / Dev tool | `JetBrains Mono` | `Outfit` | Monospace identity, modern sans for body | 98 | Presentation / Deck | `Bricolage Grotesque` | `Instrument Serif` | Warm grotesque, elegant serif | 99 | Mobile app UI | `Plus Jakarta Sans` | `Fraunces` (only as accent) | Friendly sans, quirky serif accent | 100 | Minimal / Editorial | `Sora` | `Cormorant Garamond` | Precise sans, refined serif | 101 102 Load from Google Fonts: `<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&family=Source+Serif+4:wght@400;600&display=swap" rel="stylesheet">` 103 104 ## Color System (oklch) 105 106 When no design system exists, build a palette using oklch for perceptual uniformity. 107 108 ### Method 109 110 1. Pick one **identity color** (the brand/accent) — ask the user or pick from context 111 2. Generate 3 harmonious colors using oklch hue rotation: 112 - Complement: rotate hue by 180° 113 - Analogous: rotate by ±30° 114 3. Set lightness range: surface=0.95, text=0.15, muted=0.6, accent=0.55 115 4. Map to CSS custom properties 116 117 ```css 118 :root { 119 --surface: oklch(0.95 0.02 hue); 120 --text: oklch(0.15 0.02 hue); 121 --muted: oklch(0.60 0.04 hue); 122 --accent: oklch(0.55 0.18 hue); 123 --accent-light: oklch(0.85 0.08 hue); 124 --border: oklch(0.80 0.02 hue); 125 } 126 ``` 127 128 Replace `hue` with the actual value (0-360). Example: warm orange = hue 55. 129 130 ### Common starting palettes 131 132 | Mood | Hue | Accent oklch | Use case | 133 |------|-----|-------------|----------| 134 | Warm | 55 | oklch(0.55 0.18 55) | Consumer, lifestyle | 135 | Cool | 240 | oklch(0.55 0.18 240) | Enterprise, data | 136 | Fresh | 150 | oklch(0.55 0.15 150) | Health, sustainability | 137 | Bold | 25 | oklch(0.60 0.22 25) | Entertainment, gaming | 138 | Neutral | 0 (achromatic) | oklch(0.50 0.02 0) | Dev tools, docs | 139 140 ## Spacing System 141 142 Use an 8px base grid. Scale by multiples of 4px for density control. 143 144 | Token | Value | Use | 145 |-------|-------|-----| 146 | `--space-1` | 4px | Icon gaps, tight inline | 147 | `--space-2` | 8px | Button padding, list items | 148 | `--space-3` | 16px | Card padding, section gaps | 149 | `--space-4` | 24px | Section padding, card margins | 150 | `--space-5` | 32px | Page margins, hero spacing | 151 | `--space-6` | 48px | Section breaks | 152 | `--space-7` | 64px | Full-bleed separators | 153 154 ## Composition Rules 155 156 1. **Contrast hierarchy**: Headings 2-3x body size. Body 16-18px for web, 24px+ for 1920x1080 slides. 157 2. **Visual weight**: One element dominant per section. Everything else supports it. 158 3. **Whitespace ratio**: 60% space, 40% content for hero/cover. 40% space, 60% content for data-dense sections. 159 4. **Alignment**: One alignment per section (left, center, or right). Mix across sections, not within. 160 5. **Depth**: Use only 1 shadow level across the entire page. Either `0 1px 3px rgba(0,0,0,0.1)` for subtle or `0 8px 30px rgba(0,0,0,0.12)` for dramatic. Never both. 161 6. **Borders**: Prefer `1px solid var(--border)` over shadows for separation in dense layouts. Shadows for isolation in sparse layouts.