---
description: "Design system mechanics: tokens, shadcn/ui, Tailwind v4, composition, theming. Load for UI implementation — aesthetics and anti-slop live in the anti-slop-design skill."
globs: ["**/*.css", "**/globals.css", "**/tailwind.config.*", "**/components.json", "**/components/ui/**"]
alwaysApply: false
---

# Design System Mechanics

Token structure, shadcn/ui usage, Tailwind v4 features, and component composition — not aesthetic direction.

For palettes, font pairings, category tone, layout direction, and the slop checklist, load the **`anti-slop-design`** skill (and its `reference.md` for full pages / responsive matrices). For general coding workflow, use core **Code Discipline**.

Inspect the project first: `package.json`, `tailwind.config.*`, `globals.css`, `components.json`, existing fonts and icon library. Extend what exists; do not replace the design system unprompted.

---

## Token Shape (semantic, not hex soup)

Prefer **semantic names** mapped to CSS variables so themes and shadcn primitives stay aligned:

```css
/* globals.css — Tailwind v4 @theme or :root */
@theme {
  --color-background: …;
  --color-foreground: …;
  --color-primary: …;
  --color-muted: …;
  --color-border: …;
  --radius-md: 8px;
  --font-body: …;
  --font-display: …;
}
```

- Derive real values from the project brand or `anti-slop-design` Category Guide — placeholders above are structural only.
- Prefer **OKLCH** for new token values (`oklch(0.65 0.15 250)`) — perceptually uniform lightness makes scales and dark-mode variants predictable. Tint neutrals toward the brand hue (chroma 0.005–0.01); never ship pure-gray scales or pure `#000`/`#FFF`.
- Three token tiers when the system grows: **primitive** (`--blue-600`) → **semantic** (`--color-primary`) → **component** (`--button-bg`). Components consume semantic tokens; only semantic tokens reference primitives. Skip the component tier until a component actually needs an override.
- Do not default to generic blue/indigo scales or `Inter` / `Roboto` unless the project already uses them.
- Status colors: `--destructive`, `--success`, etc. — keep consistent with shadcn semantic tokens when present.

---

## Typography Mechanics

- Fluid display sizes with `clamp()`: `font-size: clamp(2rem, 1.2rem + 3.5vw, 4rem)` — no breakpoint jumps on headings.
- Pair line-height inversely with size: body `1.6–1.8`, headings `1.1–1.2`. A 56px heading at `line-height: 1.6` is broken.
- Tighten tracking as display size grows (`letter-spacing: -0.01em` to `-0.04em` above ~32px); never negative-track body text.
- Body measure: `max-width: 65ch` on prose containers, not pixel guesses.
- Keep ≥1.25 ratio between adjacent type-scale steps; expose the scale as tokens, not ad-hoc `text-[17px]` values.
- Load fonts with `font-display: swap` and preconnect; subset when the toolchain supports it.

---

## Motion Mechanics

- Animate only `transform` and `opacity`; never `width`/`height`/`top`/`margin` (layout thrash).
- Tokenize easing and duration: `--ease-out: cubic-bezier(0.22, 1, 0.36, 1)`, durations 150–250ms for micro-interactions, 400–600ms for entrances.
- Gate all non-essential motion behind `@media (prefers-reduced-motion: no-preference)`.
- Stagger entrances with `animation-delay` increments (60–100ms); one orchestrated page entrance beats scattered micro-animations.

---

## shadcn/ui

```bash
npx shadcn@latest init
npx shadcn@latest add button card input label form dialog
```

- Compose from primitives (`Card`, `Button`, `Form`, `Dialog`) — do not fork components unless layout truly requires it.
- Map theme overrides at **CSS variable** layer (`--primary`, `--radius`, `--background`) before editing component source.
- Forms: use shadcn `Form` + project validation library (e.g. zod + react-hook-form) when already in the stack.

---

## Tailwind v4 Essentials

- Define tokens in `@theme` in CSS; avoid duplicating palettes in JS config when v4 CSS-first setup is used.
- Container queries: `container-type: inline-size` on parent, `@container` for child layout.
- Use semantic utilities (`bg-background`, `text-muted-foreground`) when shadcn tokens exist — not raw `bg-gray-200` / `text-black`.

---

## Composition Rules

- One primary CTA per section; secondary actions visually quieter.
- Consistent `max-width` and horizontal padding across sections (hero → footer).
- Extract repeated class strings into components — do not paste 20-class strings everywhere.
- Never nest cards; separate grouped content with background shifts or whitespace instead.
- Charts and fixed-height embeds (Chart.js, maps): parent container **must** have explicit height (same discipline as 3D canvases).

---

## Dark Mode

- Prefer `class` strategy with CSS variables when shadcn is present.
- Pair `--background` / `--foreground` for contrast; test muted text ≥ 4.5:1 on body copy.

---

## Responsive & Accessibility

- Mobile-first breakpoints; 44px minimum touch targets on primary actions.
- Every input has a label; errors use color + text (and icon when helpful).
- Visible focus rings — never `outline: none` without an alternative.
- Full responsive hide/reorder/transform guidance: `anti-slop-design` → `reference.md`.

---

## Verification (UI changes)

| Change | Minimum proof |
|--------|----------------|
| Token/theme | Styles apply in browser; no unstyled flash on load |
| New component | Renders at 375px and desktop; focus/hover work |
| Form | Label association, error state, keyboard submit |
| shadcn add | Component imports resolve; theme tokens applied |

Browser verification required for layout/interaction claims (see status-verification rule).

---

## When NOT to Load This File

- Backend-only or non-UI tasks.
- Distinctive marketing/landing aesthetic from scratch — start with **`anti-slop-design`** (Step 1: design thinking), then return here for token/shadcn mechanics.
