# Bento Modern

애플 키노트 시대의 벤토 그리드 — 중립 캔버스 위에 크기가 뒤섞인 라운드 타일들이 스케일 대비로 이야기하는 스타일.

- taxonomy: bento-modern · bento-grid, feature-tiles, stat-callouts, rounded-surfaces, apple-keynote, tonal-separation · complexity=medium
- page types: landing, marketing, portfolio, dashboard
- best for: 여러 기능을 한 화면에 스캔시키는 제품 랜딩, 스펙·수치가 셀링 포인트인 하드웨어/SaaS 마케팅, 지표 타일 중심의 요약 대시보드, 작업물을 카드 모자이크로 보여주는 포트폴리오
- avoid for: 긴 글 중심의 에디토리얼/문서 사이트, 단일 내러티브로 스크롤시키는 스토리텔링 랜딩, 표 밀도가 극단적으로 높은 어드민 화면
- provenance: authored (2020s Apple-keynote-era bento grid / feature-tile marketing genre (authored reference)) — confidence: colors=manual, typography=manual, spacing=manual, radius=manual, shadows=manual, motion=manual, layout=manual

## Design rules

# Bento Modern

## Overview
Apple-keynote-era bento grid aesthetic: a dense 4-column grid of rounded feature tiles in mixed spans (2x2 hero, 1x2 verticals, 1x1 fillers), each tile a soft-contrast solid surface one tonal step off a neutral canvas. Oversized stat numerals are the heroes; scale contrast — not color, not decoration — carries the hierarchy. Dense between tiles, calm inside them.

## Colors & Roles
Neutral canvas: light `background` is a soft cool gray (oklch ~0.965), dark is true dark (~0.19). Tiles (`card`) sit one tonal step off the canvas — near-white in light mode, charcoal (~0.25) in dark. One confident blue-violet `primary`/`accent` (oklch 0.55/0.22/262 light, 0.64/0.20/262 dark). Rule: **at most one vivid accent per tile**, applied to the stat numeral, an icon, or a badge — never several. `chart-1..5` (blue-violet, violet, green, amber, red-orange) double as per-tile accent hues so adjacent tiles can differ without any tile going rainbow.

## Typography Rules
Single system-sans stack (SF Pro Display → Inter Google fallback). Scale ratio 1.25 for text, but the signature move is the `stat` step: `clamp(3.5rem, 7vw, 6rem)`, weight 700, letter-spacing −0.04em, line-height 1 — up to 6x body size inside a tile. Captions stay lowercase, 0.8125rem/500, in `muted-foreground`. No uppercase tracked labels — that is editorial territory, not bento.

## Layout Principles
Max width 1200px. Sections are bento blocks: 4-column grid, 16–20px gaps, mixed spans (2x2 + 1x2 + several 1x1). Vary the span rhythm per row to avoid monotony. Whitespace lives *inside* tiles (28–40px padding); gaps between tiles stay tight. Section gap `clamp(4rem, 8vw, 7rem)` with a short display headline above each grid.

## Depth & Elevation
One barely-there soft shadow shared by all tiles (0 8px 24px −4px at ~5% foreground opacity), or fully flat with tonal separation only — both are valid; never mix heavy shadows in. Hover elevation is expressed by `scale(1.02)`, not by growing the shadow. No frosted glass, no backdrop blur, no gradients as identity.

## Shapes
Tiles/boxes: 22px radius. Fields and small selectors: 12px. Buttons: full pill (999px). Borders are a fallback only — add a 1px hairline in dark mode if tile edges wash out.

## Component Stylings
- **Button**: pill, `primary` fill, weight 600, padding 10px 22px. Hover: slight brighten or scale(1.02), 200ms ease-out. Secondary variant uses `secondary` fill inside tiles.
- **Card (tile)**: `card` background, radius 22px, padding 28–40px, vertical contrast layout — caption top, big stat/visual bottom. Hover scale(1.02).
- **Input**: borderless `secondary` fill, radius 12px, focus ring 2px.
- **Nav**: thin bar on `background`, centered links, one pill CTA right.
- **Stat callout**: the tile's protagonist — huge numeral + caption below; `foreground` by default, accent at most once per tile.

## Motion
Gentle only: tile hover `scale(1.02)` over 200–300ms ease-out; optional staggered `tile-in` fade (opacity + 12px rise + 0.98 scale). No bounce, spring, parallax, or rotation.

## Do's and Don'ts
**Do:** compose sections as mixed-span bento grids; lead key tiles with one oversized numeral; separate surfaces tonally; cap each tile at one accent hue; pad generously inside, gap tightly outside.
**Don't:** frosted glass or translucency; gradients as identity; heavy shadows or borders for separation; uppercase tracked labels or hairline editorial rules; multiple accent hues in one tile.

## Responsive Behavior
4 columns → 2 on tablet → 1 on mobile; a 2x2 tile becomes full-width and keeps its height presence; 1x2 verticals become standard cards. Stat numerals scale via `clamp()`. Tile padding may drop to 24px on mobile; gaps stay 16px.

## Distinction from Glass Soft Futurism
No transparency, blur, or gradient identity anywhere. Bento Modern is about *composition* (tile spans, scale contrast, tonal steps on solid surfaces); glass styles are about *material*. If a surface needs backdrop-filter, it belongs in the other style.

## Agent Prompt Guide
> Build this in the 'Bento Modern' style: an Apple-keynote-era bento grid — a dense 4-column grid of rounded (22px) feature tiles in mixed spans (2x2 hero stat tile, 1x2 verticals, 1x1 fillers) with 16-20px gaps. Tiles are solid soft-contrast surfaces one tonal step off a neutral canvas; shadows barely visible or absent. System-ui sans (Inter fallback), oversized clamp()-based stat numerals with tight negative tracking, 28-40px tile padding, at most one vivid blue-violet accent per tile. Pill buttons. Gentle scale(1.02) hover, 200-300ms ease-out. No glass, no gradients, no heavy borders.

## Known Gaps / Confidence
Authored reference (manual curation, 2026-07-11) — not extracted from a live site, so all token values are `manual` confidence. Chart hues are chosen for tile-accent duty rather than data-viz optimality; adjust for dense dashboards.


## Tokens (theme.css — use these values verbatim, do not re-derive)

```css
/* Bento Modern — theme.css (generated, do not edit) */
:root {
  --radius: 22px;
  --radius-selector: 12px;
  --radius-field: 12px;
  --font-sans: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Inter', 'Segoe UI', system-ui, sans-serif;
  --font-mono: 'SF Mono', 'JetBrains Mono', ui-monospace, monospace;
  --font-display: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Inter', system-ui, sans-serif;
  --spacing: 8px;
  --shadow: 0px 8px 24px -4px color-mix(in oklab, oklch(0.21 0.015 260) 5%, transparent);
  --ks-display-weight: 700;
  --ks-display-tracking: -0.03em;
  --background: oklch(0.965 0.003 250);
  --foreground: oklch(0.21 0.015 260);
  --card: oklch(0.995 0.001 250);
  --card-foreground: oklch(0.21 0.015 260);
  --popover: oklch(0.995 0.001 250);
  --popover-foreground: oklch(0.21 0.015 260);
  --primary: oklch(0.55 0.22 262);
  --primary-foreground: oklch(0.985 0.005 262);
  --secondary: oklch(0.93 0.005 250);
  --secondary-foreground: oklch(0.28 0.015 260);
  --muted: oklch(0.935 0.004 250);
  --muted-foreground: oklch(0.50 0.015 258);
  --accent: oklch(0.55 0.22 262);
  --accent-foreground: oklch(0.985 0.005 262);
  --destructive: oklch(0.58 0.22 27);
  --destructive-foreground: oklch(0.985 0.005 27);
  --border: oklch(0.905 0.004 250);
  --input: oklch(0.905 0.004 250);
  --ring: oklch(0.55 0.22 262);
  --chart-1: oklch(0.55 0.22 262);
  --chart-2: oklch(0.62 0.19 300);
  --chart-3: oklch(0.68 0.15 165);
  --chart-4: oklch(0.75 0.15 75);
  --chart-5: oklch(0.65 0.18 20);
}

.dark {
  --background: oklch(0.19 0.01 260);
  --foreground: oklch(0.94 0.005 250);
  --card: oklch(0.25 0.012 260);
  --card-foreground: oklch(0.94 0.005 250);
  --popover: oklch(0.25 0.012 260);
  --popover-foreground: oklch(0.94 0.005 250);
  --primary: oklch(0.64 0.20 262);
  --primary-foreground: oklch(0.985 0.005 262);
  --secondary: oklch(0.30 0.012 260);
  --secondary-foreground: oklch(0.88 0.006 250);
  --muted: oklch(0.29 0.012 260);
  --muted-foreground: oklch(0.68 0.01 255);
  --accent: oklch(0.64 0.20 262);
  --accent-foreground: oklch(0.985 0.005 262);
  --destructive: oklch(0.64 0.20 27);
  --destructive-foreground: oklch(0.985 0.005 27);
  --border: oklch(0.32 0.012 260);
  --input: oklch(0.32 0.012 260);
  --ring: oklch(0.64 0.20 262);
  --chart-1: oklch(0.64 0.20 262);
  --chart-2: oklch(0.68 0.17 300);
  --chart-3: oklch(0.72 0.14 165);
  --chart-4: oklch(0.78 0.14 75);
  --chart-5: oklch(0.68 0.17 20);
}
```

## Golden example (exemplar.html — match this structure and token usage)

```html
<!-- Golden snippet for "Bento Modern". Fragment — assumes the style's CSS variables
     (--background, --foreground, --card, --accent, --chart-*, --font-sans, ...) are in scope.
     Tokens only; no literal colors. -->
<section style="background:var(--background); color:var(--foreground); font-family:var(--font-sans); padding:clamp(2rem,5vw,4rem); max-width:1200px; margin:0 auto;">
  <h1 style="margin:0 0 2rem; font-size:clamp(2.5rem,5vw,4rem); font-weight:700; line-height:1.05; letter-spacing:-0.03em;">
    Everything, at a glance.
  </h1>

  <div style="display:grid; grid-template-columns:repeat(4,1fr); grid-auto-rows:minmax(150px,auto); gap:18px;">

    <!-- 2x2 hero stat tile -->
    <article style="grid-column:span 2; grid-row:span 2; background:var(--card); color:var(--card-foreground); border-radius:22px; padding:40px; display:flex; flex-direction:column; justify-content:space-between; box-shadow:0 8px 24px -4px color-mix(in oklch, var(--foreground) 5%, transparent); transition:transform 250ms cubic-bezier(0.25,0.1,0.25,1);">
      <p style="margin:0; font-size:0.8125rem; font-weight:500; color:var(--muted-foreground);">Requests served, daily</p>
      <div>
        <p style="margin:0; font-size:clamp(3.5rem,7vw,6rem); font-weight:700; line-height:1; letter-spacing:-0.04em; color:var(--accent);">2.4B</p>
        <p style="margin:0.75rem 0 0; font-size:0.9375rem; line-height:1.5; color:var(--muted-foreground); max-width:32ch;">One tonal step off the canvas, one accent per tile, and a numeral doing all the talking.</p>
      </div>
      <a href="#" style="align-self:flex-start; background:var(--primary); color:var(--primary-foreground); border-radius:999px; padding:10px 22px; font-size:0.9375rem; font-weight:600; text-decoration:none;">See the numbers</a>
    </article>

    <!-- 1x1 tile -->
    <article style="grid-column:span 1; grid-row:span 1; background:var(--card); color:var(--card-foreground); border-radius:22px; padding:28px; display:flex; flex-direction:column; justify-content:space-between; box-shadow:0 8px 24px -4px color-mix(in oklch, var(--foreground) 5%, transparent);">
      <p style="margin:0; font-size:0.8125rem; font-weight:500; color:var(--muted-foreground);">Uptime</p>
      <p style="margin:0; font-size:2rem; font-weight:650; letter-spacing:-0.02em; color:var(--chart-3);">99.99%</p>
    </article>

    <!-- 1x2 vertical tile -->
    <article style="grid-column:span 1; grid-row:span 2; background:var(--card); color:var(--card-foreground); border-radius:22px; padding:28px; display:flex; flex-direction:column; justify-content:space-between; box-shadow:0 8px 24px -4px color-mix(in oklch, var(--foreground) 5%, transparent);">
      <div>
        <p style="margin:0 0 0.5rem; font-size:0.8125rem; font-weight:500; color:var(--muted-foreground);">Regions</p>
        <h3 style="margin:0; font-size:1.375rem; font-weight:600; line-height:1.2; letter-spacing:-0.015em;">Live in 34 regions worldwide</h3>
      </div>
      <p style="margin:0; font-size:clamp(3rem,5vw,4.5rem); font-weight:700; line-height:1; letter-spacing:-0.04em; color:var(--chart-2);">34</p>
    </article>

    <!-- 1x1 tile -->
    <article style="grid-column:span 1; grid-row:span 1; background:var(--secondary); color:var(--secondary-foreground); border-radius:22px; padding:28px; display:flex; flex-direction:column; justify-content:space-between;">
      <p style="margin:0; font-size:0.8125rem; font-weight:500; color:var(--muted-foreground);">Median latency</p>
      <p style="margin:0; font-size:2rem; font-weight:650; letter-spacing:-0.02em;">18<span style="font-size:1.0625rem; color:var(--muted-foreground);">ms</span></p>
    </article>

  </div>
</section>
```

## Apply

- shadcn project: `npx shadcn@latest add https://web.ggum.uk/styles/r/bento-modern.json` — installs the tokens above into globals.css, then use semantic classes (bg-background, text-primary, …) only.
- other stack: paste the theme.css block above into your global stylesheet and style everything via `var(--…)` references.
- single HTML/artifact: embed the theme.css block in a `<style>` tag and follow the exemplar's markup pattern.
- dark mode: toggle the `.dark` class (both variants are in the tokens above).
- before finishing: re-check every Don't in the Design rules section above against your output.
