# Bento Grid Design Guidelines

A reference for designing bento grid layouts that look crafted by a real designer — not generated by AI.

---

## What Is a Bento Grid?

A bento grid is a card-based layout where content is divided into asymmetric, compartmentalized cells of varying sizes on a shared CSS grid. Unlike a standard feature grid (all cells equal), a bento grid uses **size to communicate importance** — the hierarchy is built into the structure itself.

Popularized by Apple's WWDC keynotes and Linear's landing pages, it's now a standard pattern for product feature showcases, SaaS landing pages, dashboards, and portfolios.

---

## Grid Architecture

### Base Grid
Use a **4-column grid** for most layouts. Use a 12-column grid for complex compositions that need finer control.

```
grid-template-columns: repeat(4, 1fr);
gap: 16px; /* or 20px — pick one, stay consistent */
```

### Cell Size Vocabulary

| Name | Span | Role |
|------|------|------|
| **Hero** | 2×2 | The most important element — primary feature, bold headline |
| **Wide** | 2×1 or 3×1 | Secondary features, pull quotes, CTAs |
| **Tall** | 1×2 | Stats, metrics, timelines, vertical-reading content |
| **Small** | 1×1 | Supporting facts, icon + label, badges |

### Layout Before Code
Always sketch `grid-template-areas` mentally before writing CSS. A good 4-column layout:

```
"hero  hero  b    c"
"hero  hero  d    e"
"f     g     g    h"
```

**Content priority maps directly to cell size.** If you can't identify the hero cell within one second, the hierarchy is broken — redesign before moving forward.

### Cell Count
- **Sweet spot: 7–9 cells**
- **Maximum: 12 cells** — beyond this, the organizational benefit collapses and nothing wins attention
- Minimum meaningful variety: at least 3 distinct cell sizes in any grid

---

## Color

### The 70/20/10 Rule

| Proportion | Role | Usage |
|------------|------|-------|
| **70%** | Base background | The deepest, most muted surface — the canvas |
| **20%** | Elevated surface | Slightly lighter — used for most cells |
| **10%** | Accent | One or two hero cells, hover borders, or glow effects only |

Never apply the accent color everywhere. Its power comes from restraint.

### Dark Theme Palette (Default)
```css
--bg:            #0a0a0a;
--surface:       #111111;
--surface-high:  #1a1a1a;
--border:        rgba(255, 255, 255, 0.08);
--accent:        #3b82f6;                   /* swap per project */
--accent-subtle: rgba(59, 130, 246, 0.25);
--text-primary:  #f0f0f0;
--text-muted:    #888888;
```

### Light Theme Palette
```css
--bg:            #f5f5f4;
--surface:       #ffffff;
--surface-high:  #fafaf9;
--border:        rgba(0, 0, 0, 0.08);
--accent:        #2563eb;
--accent-subtle: rgba(37, 99, 235, 0.12);
--text-primary:  #111111;
--text-muted:    #6b7280;
```

### Accent Color Direction by Content Type
- **Tech / SaaS**: Electric blue `#3b82f6`, violet `#7c3aed`, or cyan `#06b6d4`
- **Finance / Enterprise**: Slate blue `#3b5bdb`, forest green `#2f9e44`
- **Creative / Portfolio**: Amber `#f59e0b`, coral `#f97316`, or lime `#84cc16`
- **Health / Wellness**: Teal `#0d9488`, sage `#6a994e`
- **Monochrome**: Single color — vary lightness only

---

## Typography

### The Rule
**Never use Inter, Roboto, Arial, or system-ui as the display typeface.** These are defaults — they signal that no design decision was made. Choose something with character.

Inter is acceptable as a *body* typeface only, paired with a distinctive display font.

### Recommended Pairings

| Display | Body | Character |
|---------|------|-----------|
| Syne | DM Sans | Geometric, modern, forward |
| Playfair Display | Nunito | Editorial, warm, refined |
| Space Mono | IBM Plex Sans | Technical, monospaced, precise |
| Fraunces | Karla | Distinctive, humanist, literary |
| Outfit | Lato | Clean, product-forward, friendly |
| Bricolage Grotesque | Inter | Bold editorial, high contrast |
| Cabinet Grotesk | Satoshi | Contemporary, high-end SaaS |

Load via Google Fonts `@import` or `<link>`. **Vary the pairing per project — never reuse the same combination.**

### Type Scale in Cells
- **Hero cell headline**: 40–56px, bold or black weight
- **Feature cell headline**: 20–24px, semibold
- **Body / description**: 14–16px, regular, muted color
- **Stat number**: 56–80px, bold or black, accent color
- **Stat label**: 12–13px, uppercase, letter-spaced, muted

---

## Icons

**No emojis. No unicode arrows. No letter-based fake icons. Use real SVG icons.**

### Lucide (Recommended)
Clean, consistent, 1.5px stroke weight — the standard for modern product UI.

**HTML/CSS via CDN:**
```html
<script src="https://unpkg.com/lucide@latest/dist/umd/lucide.min.js"></script>
<i data-lucide="zap"></i>
<script>lucide.createIcons();</script>
```

**React:**
```jsx
import { Zap, Globe, Shield, Layers, ArrowRight } from 'lucide-react';
```

### Icon Styling
Always give icons explicit size and color — never leave them unstyled:
```css
.cell-icon {
  width: 24px;
  height: 24px;
  color: var(--accent);
  stroke-width: 1.5;
}
```

---

## Cell Anatomy

### Structure
```css
.bento-cell {
  border-radius: var(--radius);  /* 20px — same on ALL cells */
  padding: 28px;
  border: 1px solid var(--border);
  background: var(--surface);
  overflow: hidden;
  position: relative;
}
```

**Border-radius must be identical across every cell.** Pick one value (16–24px) and never deviate.

### Cell Types and Their Content

**Hero Cell** — 2×2
- Large headline (40–56px)
- 1–2 lines of supporting text
- Optional: CTA button, product visual, or abstract graphic
- Use `var(--surface-high)` background to elevate it

**Stat Cell** — 1×1 or 1×2
- Giant number (64–80px, bold, accent color)
- Short label (12px, uppercase, muted)
- Optional: small sparkline, delta indicator, or trend arrow

**Feature Cell** — 1×1 or 2×1
- Icon (24px, accent color)
- Headline (18–20px, semibold)
- One-line description (14px, muted)

**Visual Cell** — 2×2 or 2×1
- Screenshot, illustration, SVG diagram, or abstract graphic
- Let the visual breathe — minimal text overlay

**Quote Cell** — 2×1
- Pull quote in larger type (18–20px)
- Attribution: name + role in muted smaller text
- Optional: subtle quotation mark as decorative element

**CTA Cell** — 1×1 or 2×1
- Short punchy headline
- Single action button
- Works best with accent color background

**Badge Cell** — 1×1
- Centered icon + label
- Good as an accent cell with a slightly different background

---

## Micro-animations

### Entrance Stagger (Required)
Every cell enters with a staggered fade + lift. 60ms delay per cell.

```css
@keyframes cellIn {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

.bento-cell {
  animation: cellIn 0.55s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.bento-cell:nth-child(1) { animation-delay: 0ms; }
.bento-cell:nth-child(2) { animation-delay: 60ms; }
.bento-cell:nth-child(3) { animation-delay: 120ms; }
.bento-cell:nth-child(4) { animation-delay: 180ms; }
.bento-cell:nth-child(5) { animation-delay: 240ms; }
.bento-cell:nth-child(6) { animation-delay: 300ms; }
.bento-cell:nth-child(7) { animation-delay: 360ms; }
.bento-cell:nth-child(8) { animation-delay: 420ms; }
```

### Hover Lift (Required)
Every cell lifts on hover. Use a spring easing for a physical feel.

```css
.bento-cell {
  transition:
    transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
    box-shadow 0.3s ease,
    border-color 0.3s ease;
  will-change: transform;
}

.bento-cell:hover {
  transform: translateY(-5px) scale(1.015);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
  border-color: var(--accent-subtle);
}
```

### Icon Float on Hover (Recommended)
```css
.cell-icon {
  transition: transform 0.3s ease;
}
.bento-cell:hover .cell-icon {
  transform: translateY(-3px);
  transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
```

### Sibling Dimming (Use Sparingly)
Dims non-hovered cells to focus attention. Only use in grids with 6+ cells.
```css
.bento-grid:has(.bento-cell:hover) .bento-cell:not(:hover) {
  opacity: 0.65;
  transition: opacity 0.25s ease;
}
```

### Animation Rules
- Only animate `transform` and `opacity` — never animate layout properties like `width`, `height`, or `grid-column`
- Use `cubic-bezier(0.34, 1.56, 0.64, 1)` for spring-like hover lift
- Use `cubic-bezier(0.16, 1, 0.3, 1)` for entrance animations (fast out, smooth settle)
- Add `will-change: transform` on cells that animate

---

## Responsive Behavior

```css
/* Tablet */
@media (max-width: 900px) {
  .bento-grid {
    grid-template-columns: repeat(2, 1fr);
    grid-template-areas: none; /* let auto-flow handle it */
  }
  .bento-cell {
    grid-column: span 1 !important;
    grid-row: span 1 !important;
  }
}

/* Mobile */
@media (max-width: 520px) {
  .bento-grid {
    grid-template-columns: 1fr;
  }
}
```

On mobile, disable hover animations (no cursor) and rely on `active` states for tap feedback.

---

## Anti-Patterns

These are the fastest ways to make a bento grid look AI-generated:

| Anti-Pattern | Why It Fails |
|---|---|
| All cells the same size | Defeats the purpose — just a rounded feature grid |
| Emojis as icons | Inconsistent sizing, no stroke control, unprofessional |
| Purple gradient on white | Textbook AI default palette |
| Inter/Roboto as display font | Signals no typographic decision was made |
| More than 12 cells | Information hierarchy collapses |
| No dominant hero cell | Everything at equal weight = nothing wins attention |
| Gradient on every cell | Noisy; reserve gradients for 1–2 accent cells at most |
| Placeholder content | "Feature 1", "Lorem ipsum" — always write real copy |
| Inconsistent border-radius | Different radius on different cells breaks visual cohesion |
| Animating layout properties | Causes layout thrash; only animate `transform` and `opacity` |
| Identical padding across all cells | Scale padding with cell size — hero gets more breathing room |
| Overcrowded hero cell | A hero with 4 paragraphs of text is not a hero |

---

## Checklist Before Shipping

- [ ] Hero cell is visually dominant — largest cell holds the most important content
- [ ] 70/20/10 color rule applied — accent used sparingly
- [ ] Non-generic font pairing loaded and applied to display text
- [ ] SVG icons used (Lucide or inline) — no emojis
- [ ] Entrance stagger animation present on all cells
- [ ] Hover lift animation on every cell
- [ ] Responsive breakpoints at 900px and 520px
- [ ] 6–10 cells total
- [ ] Single consistent border-radius value across all cells
- [ ] Real content — no placeholder text
- [ ] At least 3 distinct cell sizes in the grid
- [ ] Accent color appears on no more than 2 cells
