---
title: "website skill: the void workflow"
description: "Entry workflow for building or redesigning any website with void so it looks distinctive and premium (not AI-generated), feels smooth and loads fast on the…"
canonical: https://void-design.vercel.app/docs/website
lastModified: 2026-09-16
---

# website — the void workflow

Follow the phases in order. Each has exit criteria; don't start the next phase until they hold. The skills you'll pull in:

| Skill | Owns |
|---|---|
| `inspire` | building from an inspiration URL ("make it look like linear.app") |
| `craft` | direction, color, type, layout, depth, anti-slop checklist |
| `motion` | what moves, timing, effect tiers |
| `components` | sourcing effects/components from libraries (React Bits, Magic UI, skiper-ui…) as lean void code |
| `speed` | Server Components, budgets, images, fonts, LCP/INP/CLS |
| `seo` | metadata, JSON-LD, sitemap, robots, llms.txt, content that gets cited |
| `a11y` | landmarks, keyboard, focus, contrast, forms |
| `audit` | the `void` CLI fix loop |

**Tooling:** `void` is the void CLI. If it isn't on PATH: `bun "${CLAUDE_PLUGIN_ROOT}/packages/cli/src/index.ts" <command>` (run `bun install` in that folder once; `void doctor` checks Chromium).

## The 10 rules

1. **Write the brief before any markup.** No brief, no page.
2. **One direction, one accent, one signature moment.** Decide them in writing in phase 1.
3. **Real content first.** Sections come from what the page must prove, not from a template. No lorem ipsum, no invented logos, quotes, stats or ratings. Ever.
4. **Don't default to hero → 3 icon cards → testimonials → CTA.** Pick archetypes by the job of each section.
5. **Tokens only.** Semantic utilities from `@void/tokens`; zero hex, zero default palette, zero arbitrary spacing.
6. **Server Components by default.** Client islands only for real interactivity. The hero H1 and LCP image are in the HTML and visible at first paint.
7. **Left-aligned, varied rhythm, small type texture.** Measured top sites center ≤ 25% of headings and run on 13–14px UI text.
8. **Motion is budgeted:** 1 signature + ≤ 1 secondary effect, CSS first, reduced motion honored.
9. **Verify with tools and eyes:** `void lint` → `next build` → `void audit` → screenshots at 1440 and 390 against the anti-slop checklist.
10. **Only publish what exists.** Every claim, number, logo and schema entry is real or removed.

## Phase 0 — Brief

Write this block into the conversation (or `BRIEF.md`) before anything else. Ask the user only for what you can't infer; don't stall on optional fields.

```md
## Brief
- Product / person: <what it is in one sentence, no adjectives>
- Audience: <who, how technical, what they already use>
- The one job of this page: <the single action or belief after reading, e.g. "install the CLI">
- Primary CTA: <label + destination>   Secondary: <text link or none>
- Proof we actually have: <screenshots, demo, real numbers with dates, customer names with permission, quotes with attribution, GitHub stars, awards> (or "none yet")
- Tone: <3 words, e.g. "precise, calm, dry">
- Constraints: <existing brand color/font/logo, dark or light, pages needed, deadline>
- Inspiration: <URLs or "none">
```

- **Inspiration URL given** ("like linear.app", "inspired by <url>") → run the `inspire` skill now; it produces the direction and overrides for phase 1.
- **Existing site to redesign** → first run `void audit <url> --screenshots .void/before --format md` and look at the screenshots; list what to keep (content, brand assets, URLs for SEO) and what fails.

**Exit:** one job, one CTA, audience and the real proof inventory are written down.

## Phase 1 — Direction and design statement

Map the brief to exactly one direction (specs in `craft` §1 and `craft/references/directions.md`):

| Brief signals | Direction | Fonts (fixed) | Accent (default) | Radius |
|---|---|---|---|---|
| developer tool, AI/infra, API, B2B SaaS for technical teams, "Linear/Vercel-like" | `precision` (dark) | Geist + Geist Mono | indigo | 6px |
| CLI, open-source infra, hackathon, audience lives in a terminal | `terminal` (dark) | Geist Mono only | amber (dark text on solids) | 0 |
| writing, research, publication, studio with a point of view, premium/editorial brand, long docs | `editorial` (light) | Newsreader + IBM Plex Mono | oxblood | 2px |
| agency, architecture, design/type tool, event, portfolio about craft, data journalism | `swiss` (light) | Schibsted Grotesk + JetBrains Mono | signal red | 0 |
| consumer app, notes/productivity, education, health, community, friendly SMB | `warm` (light) | Bricolage Grotesque + Figtree | clay | 10px |
| analytics, admin, finance, internal tools, docs for a data product | `instrument` | IBM Plex Sans + Plex Mono | blue | 6px |
| personal dev portfolio (owner's taste default) | `precision` or `terminal`, dark, mono label voice | as above | as above | as above |

**Take fonts, accent, radius and durations from the direction file** (`src/styles/void/directions/<name>.css` header). Don't invent a font or accent. Change the accent only when the user has a brand color (then follow `craft/references/color.md` §5) or when `inspire` requires a departure.

Then write the **design statement** (5 lines + signature) into the brief:

```md
## Design statement
1. Direction: precision (dark-first; light theme kept honest)
2. Fonts: Geist 500 display via `text-display-lg` (42→80px, tracking baked in), Geist `text-sm`/`text-md` UI/body, Geist Mono `label-mono` labels
3. Accent: indigo `--brand` oklch(54.5% .19 272) copied from the direction file, only on the primary CTA, links, focus and active nav (≤ 2% of the fold)
4. Radius & depth: 6px knob (buttons 6, cards 9, frames 12); hairlines + lighter surfaces, shadow-3 only on the product frame
5. Motion personality: quick and exact, 100–150ms UI, one 450ms hero settle, 2 scroll reveals
Signature detail: the real deploy log streaming in a framed terminal beside the H1 (T1 CSS, no JS)
```

The signature detail is one specific, ownable thing (a live-looking product surface, a typographic poster hero, a numbered editorial list, a boot-log, a split serif hero). Not "animations" or "gradient".

**Exit:** direction chosen, statement written, custom brand hex (if any) converted per `craft/references/color.md` §5.

## Phase 2 — Scaffold

**New project** (Next 16.3.5, React 19, Tailwind 4.3.3, tokens and SEO wired):

```bash
cp -R "${CLAUDE_PLUGIN_ROOT}/templates/next" ./my-site    # or from a void checkout: cp -R <void>/templates/next ./my-site
cd my-site && bun install
cp .env.example .env.local                                  # set NEXT_PUBLIC_SITE_URL
bun dev
```

Then set the direction (three places must agree): `src/app/globals.css` import, `next/font` loaders in `src/app/layout.tsx` (variable names from the direction file header), `direction` + `theme.default` in `src/site.config.ts`. Replace every fact in `src/site.config.ts` and all copy in `src/content/*`. Template primitives: `components/ui/{button,card,container,section,eyebrow,badge,link,kbd}.tsx`.

**Existing Next/Tailwind v4 project (retrofit):**

1. Copy `${CLAUDE_PLUGIN_ROOT}/packages/tokens/css/base.css`, one `directions/<name>.css` (and `shadcn.css` if the project uses shadcn/ui) into `src/styles/void/`.
2. `globals.css`: `@import "tailwindcss";` → `@import "../styles/void/base.css";` → `@import "../styles/void/directions/<name>.css";` → (optional) `shadcn.css`.
3. Delete `tailwind.config.*` after moving any real theme values into `@theme`.
4. Add the direction's `next/font` loaders with the exact `variable` names; put `.variable` classes on `<html>`.
5. Add the blocking theme script from `templates/next/src/lib/theme.ts` to `<head>`.
6. Run `void lint`: every `lint/tw-unknown-class` and `lint/hardcoded-colors` finding is a class to migrate to semantic tokens (`bg-zinc-900` → `bg-surface`, `shadow-lg` → `shadow-2`, `text-6xl` → `text-display-lg`).

Tailwind v3 project: migrate to v4 first (`npx @tailwindcss/upgrade`), then retrofit.

**Exit:** `bun dev` renders the template (or existing site) with the chosen direction's fonts and colors in both themes; `void lint` has no `lint/tw-*` errors.

## Phase 3 — Content and structure (before styling)

1. **Section plan.** Write a numbered list: section → its job → archetype → the real content it uses. Each section answers one question a skeptical visitor has, in the order they'd ask it (What is it? → Does it work? → For me? → Proof? → Cost? → How do I start?).
2. **Pick archetypes** from `references/section-archetypes.md`. Default page for a product: typographic or product-shot hero → proof strip (only if real) → product showcase → 2–3 feature deep-dive rows → metrics or quote (only if real) → how it works / install → pricing or FAQ → CTA band → footer. Vary adjacent sections: never two card grids in a row; at most one bento; at most one centered section besides the hero.

   | Archetype | Use when |
   |---|---|
   | Hero: editorial left | clear one-line value prop, no strong visual |
   | Hero: product shot | UI is the proof (dev tools, SaaS) |
   | Hero: typographic poster | brand/voice-led, agency, launch, portfolio |
   | Hero: split | H1 needs a paragraph of nuance beside it (Anthropic, Supabase) |
   | Proof strip / logo wall | ≥ 4 real, permitted customer logos |
   | Product showcase | one real screen explains the product |
   | Feature deep-dive rows | 2–4 capabilities, each with a real visual |
   | Editorial capability list | services or many features without visuals |
   | Bento | 4–6 peers of different weight, each tile shows something real |
   | Metrics strip | 3–4 measured numbers with units, dates and sources |
   | Quote | one long, specific, attributed quote |
   | How it works / install | developer products; steps or a copyable command |
   | Pricing / comparison table | real plans or a vs-table |
   | FAQ | real objections from sales/support, 4–8 questions |
   | CTA band | closing ask repeating the primary CTA |

3. **Write real copy** (`references/copy-and-content.md`): specific headline ≤ 10 words, sub ≤ 2 lines, numbers with units, answer-first paragraphs (GEO, see `seo`). CTAs are verb + object ("Install the CLI", not "Get started"/"Learn more"). No buzzwords (unlock, seamless, lightning-fast, supercharge, next-generation). Put copy in `src/content/*.ts`, not inline JSX.
4. **Placeholders are loud, never fake.** Missing proof → the section is omitted, or during development a visible dashed box that says exactly what's needed:

   ```tsx
   <div data-placeholder className="grid min-h-40 place-items-center rounded-xl border border-dashed border-line-strong bg-bg-subtle p-6 label-mono text-fg-subtle">
     TODO(content): customer quote with name, role, company, permission
   </div>
   ```
   Content fields: `quote: null, // TODO(content): …`. Every `TODO(content)` is listed in your final report and removed or resolved before done.
5. Page-type specifics (portfolio, docs home, blog/article, pricing, changelog): `references/page-types.md`.

**Exit:** section plan with job + archetype + real content for every section; copy in content files; no invented proof.

## Phase 4 — Build

Order: layout shell → hero → sections top to bottom → responsive pass → dark/light pass.

- **Craft:** tokens only; direction type tokens (`text-display-lg`, `text-sm`, `label-mono`); `container-page`, `section-y` with deliberate variation; `surface-card`, `shadow-1..3`, `press`, `hit-area`, `grain`. Check `craft` §8 as you go, not only at the end.
- **Speed:** every section is a Server Component; `'use client'` only on leaves (menu, toggle, tabs); `next/image` with `sizes`, one `fetchPriority="high"` LCP image; fonts only via the direction loaders; no client data fetching of public APIs.
- **SEO:** `pageMetadata()` per page (template `src/lib/seo.ts`), exactly one `<h1>`, landmarks, JSON-LD for what's visible, sitemap/robots/llms.txt already wired. Update `src/content/pages.ts` with real `lastModified`.
- **A11y:** real `<button>`/`<a>`, labels on icon buttons, visible focus (base layer), contrast from tokens (don't lower it), `lang`, skip link (template has it), headings in order.
- **Components:** before hand-building an interactive widget or effect, check `components` for the lean version (marquee, number ticker, spotlight…) and its tier.

**Exit:** page complete at 1440 and 390, both themes, `void lint` clean of errors, `bun run build` passes.

## Phase 5 — One signature moment

- Pick exactly one signature (from the design statement) and at most one secondary effect per page. Budget and tiers: `motion` §3. Default to T0–T1 (CSS).
- Candidates: hero lockup settle + staggered sub/CTA (T1), a scroll-revealed product showcase (`reveal`, T1), a masked statement reveal (T1), a live-looking terminal/log (T1), one pointer spotlight on a feature grid (T2), one canvas/shader backdrop (T3/T4, only with all `motion/references/webgl-canvas.md` rules).
- Everything else is still: color/border hover steps, `press`, instant keyboard UI.
- Sourcing from a library: `components` (licence, audit, rewrite on tokens).

**Exit:** ≤ 1 signature + ≤ 1 secondary; reduced-motion screenshot shows every piece of content.

## Phase 6 — Verify and fix

```bash
void lint                                                     # seconds; fix all errors
bun run build                                                 # must pass; check route sizes
void audit --start "bun run start -p 3100" --port 3100 --screenshots .void/shots --format md
```

1. Fix in order: errors → budget failures → warnings. Look up any id with `void rules <id>`. Loop details: `audit`.
2. **Look at the screenshots** (open the PNGs in `.void/shots`): desktop fold, desktop full page, mobile fold. If a screenshot is missing, capture it with `void design --start "bun run start -p 3100" --port 3100 --screenshots .void/shots`.
3. Review each screenshot against `craft` §8 (30 tells). Write down every tell you find and fix it. Then ask: *would this page be mistaken for a template?* If yes, strengthen the signature detail or the typography, not the effects.
4. Toggle OS reduced motion and dark/light once; check the hero and one reveal.
5. Re-run `void audit` until no errors remain.

## Definition of done

- [ ] Brief + design statement written; one direction, one accent, one signature.
- [ ] Every section has a job and a non-template archetype; no two identical grids in a row.
- [ ] No lorem, no invented logos/quotes/stats/ratings; `grep -r "TODO(content)" src` is empty or each item is reported to the user.
- [ ] Tokens only: `void lint` shows no `lint/hardcoded-colors`, `lint/tw-unknown-class`, `lint/tw-v3-arbitrary-var`.
- [ ] Headings: one `<h1>`; display tokens; ≤ 25% of headings centered; balanced wrapping.
- [ ] Accent visible on ≤ ~5 spots in the desktop fold; `design/multiple-accents` clean.
- [ ] Hero H1 and LCP image visible at first paint; `perf/*` budgets pass (marketing ≤ 170 KB first-load JS).
- [ ] Motion: ≤ 1 signature + ≤ 1 secondary; reduced motion shows all content; no `transition-all`, no `hover:scale-*`.
- [ ] Mobile 390: no horizontal scroll, tap targets ≥ 24px (44px primary), text ≥ 13px, H1 ≤ 3 lines.
- [ ] Both themes (or the single declared scheme) look intentional; `theme-color` and `color-scheme` set.
- [ ] `void audit` has 0 errors; screenshots at 1440 and 390 pass the 30-tell checklist.
- [ ] Final report lists: direction + statement, signature, open TODO(content) items, audit summary.

## References

- `references/section-archetypes.md` — markup skeletons for every archetype (4 hero variants → footer)
- `references/copy-and-content.md` — headlines, specificity, numbers, CTAs, answer-first, banned phrases
- `references/page-types.md` — landing, portfolio, docs home, blog/article, pricing, changelog
