diff --git a/DESIGN.md b/DESIGN.md
index 858cd5a..3ab10fe 100644
--- a/DESIGN.md
+++ b/DESIGN.md
@@ -355,10 +355,114 @@ When in doubt, apply these in order:
---
+## 15. Tailwind v4 integration
+
+The marketing site (`site/`) uses **Tailwind v4** wired through `@tailwindcss/vite`. There is no `tailwind.config.{js,ts}` — Tailwind v4 is **CSS-first**: tokens declared in `@theme {}` inside [`site/src/styles/tokens.css`](site/src/styles/tokens.css) automatically become utilities (`bg-brand-primary`, `text-ink-700`, `rounded-lg`, …).
+
+### 15.1 Wiring
+
+- `astro.config.mjs` → `vite: { plugins: [tailwindcss()] }`.
+- `site/src/styles/tokens.css` is the single source of truth:
+ 1. **Tailwind imports are split, NOT `@import "tailwindcss"`** :
+ ```css
+ @import 'tailwindcss/theme.css' layer(theme);
+ @import 'tailwindcss/utilities.css' layer(utilities);
+ ```
+ Preflight is **intentionally omitted**. The full `@import "tailwindcss"` pulls a global CSS reset that resets `h1`/`p`/`ul` margins and list markers — that mangles Starlight's docs typography (heading sizes collapse, lists lose bullets, links default-color). Starlight ships its own scoped reset; ours adds nothing. If a marketing component needs a real reset, scope it manually with `.reset { all: revert; }` etc.
+ 2. `@variant dark (&:where([data-theme='dark'], [data-theme='dark'] *))` rebinds Tailwind's built-in `dark:` variant to our `[data-theme]` attribute (instead of `prefers-color-scheme`), so it stays in sync with `ThemeToggle.astro` + Starlight's theme provider.
+ 3. `@theme { … }` declares **every** token Tailwind should expose as utilities.
+ 4. `:root[data-theme='dark']` overrides the same `--color-*` vars for dark mode — utilities and raw `var(--color-…)` references both flip automatically.
+ 5. Legacy aliases (`--brand-primary`, `--space-4`, …) are kept as `var(--color-brand-primary)` etc. so older components written before Tailwind landed keep working without a rewrite.
+
+### 15.2 Token → utility mapping
+
+Tailwind v4 generates utilities from the prefix of each `--*-name` declared in `@theme`. The naming convention is **enforced by Tailwind**, so it's worth memorizing.
+
+| `@theme` prefix | Utilities generated | Example |
+|----------------|---------------------|---------|
+| `--color-*` | `bg-*`, `text-*`, `border-*`, `ring-*`, `from-*`, `to-*`, `via-*`, `outline-*`, `decoration-*`, `accent-*`, `caret-*`, `divide-*`, `placeholder-*` | `bg-brand-primary`, `text-ink-700` |
+| `--font-*` | `font-*` | `font-display`, `font-mono` |
+| `--text-*` | `text-*` (typography scale) | `text-md`, `text-3xl` |
+| `--spacing` (single) | `p-N`, `m-N`, `gap-N`, `w-N`, `h-N`, etc. — `N × spacing` | `p-4` = `4 × 4px` = `16px` |
+| `--radius-*` | `rounded-*` | `rounded-md`, `rounded-full` |
+| `--shadow-*` | `shadow-*` | `shadow-md`, `shadow-lg` |
+| `--container-*` | `max-w-*`, `mx-auto` containers | `max-w-prose`, `max-w-main` |
+| `--breakpoint-*` | responsive variants | `sm:`, `md:`, `lg:`, `xl:` |
+
+### 15.3 When to use utility vs CSS var
+
+- **Tailwind utility** — for layout, spacing, typography, color in JSX-style markup. Reads cleanly inline. Default choice for new components.
+- **Raw `var(--color-…)`** — for SVG fills/strokes, CSS-in-JS dynamic values, gradients with `color-mix()`, anywhere a utility doesn't exist or you need the raw value. The two systems share the same `--color-*` vars, so they stay in sync.
+- **Scoped `
diff --git a/site/src/components/FeatureGrid.astro b/site/src/components/FeatureGrid.astro
index e2d01be..b1fb760 100644
--- a/site/src/components/FeatureGrid.astro
+++ b/site/src/components/FeatureGrid.astro
@@ -27,99 +27,33 @@ const features = [
];
---
-
-
-
-
Why Mailify
-
Built for developers who want ownership without redoing email infra from scratch.
+
+
+
+
Why Mailify
+
+ Built for developers who want ownership without redoing email infra from scratch.
+