<!--
  DESIGN.md — the locked visual system for the FirmClerk marketing site.
  Approved 2026-06-22 (function-led IA + keep-and-refine visual system).
  Source of truth for tokens, type, components, motion, and accessibility.
  PRODUCT.md owns the concept and voice; this file owns the expression.
  The reference implementation is /prototype/index.html.
-->
# Design System

The visual language for the FirmClerk site. It exists to make one feeling legible: **a tailored suit, not off-the-rack automation** — measured, exacting, and quietly confident. Editorial ink on near-white paper, a single bespoke accent, and craft details (a tailor's chalk stitch, optical-size serif display) carry the metaphor. This is also how we do "AI without the hype": restraint, specificity, and outcomes — never glow, robots, or neon.

It descends from the earlier "Direction A" exploration; the *visual system* carried over, the accounting-era tokens (navy/blue, Cormorant) did not.

## Principles → expression

The five [PRODUCT.md](PRODUCT.md) design principles, made concrete here:

1. **Tailored, not off-the-rack** → bespoke layouts over a card grid; the tailoring metaphor names sections (Measure / Cut & build / Fit & run); a single accent reads as "the suit lining."
2. **Outcomes over machinery** → lead with completed work (the hero panel shows agents *done*, one item flagged for approval); architecture shown in plain language, never as a diagram of nodes.
3. **AI without hype** → no gradients-as-decoration, no robots/circuitry, no "AI-powered" badges. Intelligence is shown through concrete workflows.
4. **Managed, accountable, human-in-control** → the "you" state is always visually distinct (accent-tinted row, "you" tag); approvals and guardrails are first-class content.
5. **Specific over sweeping** → real departments, real systems, real example industries. If a block could appear on any SaaS site, it gets rewritten, not restyled.

## Color

Defined in **oklch** for perceptual consistency. All values are locked; do not introduce new hues. The palette is a near-neutral cool-grey ink ladder plus exactly one chromatic accent.

```css
:root {
  --bg:        oklch(0.992 0 0);       /* page — near-white paper            */
  --surface:   oklch(0.974 0.002 265); /* raised panels, alt sections        */
  --ink:       oklch(0.23 0.016 265);  /* primary text, dark "drenched" band */
  --ink-soft:  oklch(0.43 0.016 265);  /* secondary text                     */
  --ink-faint: oklch(0.52 0.012 265);  /* tertiary text, mono labels (AA)    */
  --rule:      oklch(0.9 0.006 265);   /* borders, dividers                  */
  --rule-soft: oklch(0.95 0.004 265);  /* hairlines inside components        */
  --paper-inv: oklch(0.985 0.003 60);  /* text on the dark band (warm white) */

  /* single bespoke accent — "the suit lining". Oxblood, used sparingly. */
  --accent:    oklch(0.46 0.137 24);
  --accent-dk: oklch(0.38 0.12 24);
}
```

**Accent discipline.** The oxblood is a lining, not a coat. Use it for: italic emphasis words in display headings, the human/"you" state, one primary indicator per component, focus rings, and the drenched-band glow. Never for body text, large fills, or more than one attention point in a single viewport.

**Contrast (WCAG 2.1 AA floor).** `--ink`/`--ink-soft` on `--bg`/`--surface` clear 4.5:1 for body. `--ink-faint` at `L 0.52` clears 4.5:1 on both `--bg` (~5.4:1) and `--surface` (~5.1:1), so it is safe even for the small (10.5–12px) mono labels, kickers, and meta it carries. Do not lighten it past `L 0.52`. `--accent` on `--bg` is for ≥18px / bold or non-text indicators; on the dark band it is lightened (`color-mix(... white)`). Placeholders meet the same floor as body text. **Color is never the sole carrier of meaning** — the "you" state also carries a "you" label and an icon.

## Typography

Three families, each with one job. Load only the weights below.

| Family | Role | Weights | Notes |
|---|---|---|---|
| **Fraunces** | Display, headings, pull-quotes | 300–600 + italic | `font-optical-sizing: auto`; display weight ~360; italic = accent emphasis |
| **DM Sans** | Body, UI, buttons | 300 / 400 / 500 | Body 400; sub-copy 300 |
| **DM Mono** | Kickers, labels, meta, step numbers | 400 | uppercase, letter-spacing 0.06–0.16em |

**Display.** `font-family: Fraunces; font-weight: 360; letter-spacing: -0.018em; line-height: 1.05; text-wrap: balance.` Italic emphasis (`<em>`) is set in `--accent` — this is the primary place the lining shows in headings.

**Fluid scale** (`clamp(min, vw, max)`):
- h1 hero — `clamp(46px, 6.6vw, 84px)`
- h2 section — `clamp(31px, 4.3vw, 48px)`
- h2 dark-band / CTA — `clamp(30px, 4vw, 46px)` / `clamp(36px, 5vw, 58px)`
- pull-quote — `clamp(24px, 3.2vw, 33px)`, italic
- body — 16–17px, line-height 1.6–1.75
- kicker/label — 10.5–11.5px mono, uppercase

## Layout & spacing

- **Container:** `--maxw: 1140px`, side padding 32px (22px ≤720px).
- **Section rhythm:** 104px block padding desktop → 78px ≤720px. Dark band and alt-surface bands break the white to pace the page.
- **Grids:** hero 1.12fr / 0.88fr; compare & modes 1fr/1fr; steps & example grid 3-up. All collapse to 1-up ≤980px (example grid → 2-up → 1-up ≤720px).
- **Radii:** cards 11–12px, controls 4–6px. **Borders:** 1px `--rule`. Shadows are rare, soft, and tinted with `--ink` at low alpha (never pure black).

## Signature elements

These are the details that make it FirmClerk and not a template. Keep them.

- **Tailor's chalk stitch** (`.stitch`): a 1px dashed `repeating-linear-gradient` rule, ~0.5 opacity. Section seams.
- **Single-accent indicators:** the pulsing `.live` dot, the `suit` column's top border, the `on` chips in H2A/A2A flows.
- **Hero "agents at work" panel:** rows of completed work + one accent-tinted `human` row ("flagged for your approval", tag = "you"). This is the product story in one glance — keep the human row visually distinct and last.
- **Off-the-rack vs Tailored compare:** two columns, `rack` on `--surface` (flat, minus-icons, faint), `suit` bordered in accent with an accent top-rule and check-icons. The wedge, made visual.
- **Drenched-ink "promise" band:** full-bleed `--ink` background, warm `--paper-inv` text, a single radial accent glow. Used once, for the managed-service promise.

## Components

Buttons — **primary** (`--ink` fill, `--bg` text, 4px radius, lift + soft shadow on hover) and **text** (underline-rule that shifts to accent on hover). Nav CTA = compact primary. Cards — 1px `--rule`, 11–12px radius, optional `translateY(-3px)` hover. Mono "dept/tag" eyebrow in accent. Forms — see below; inputs get an accent focus ring (`box-shadow: 0 0 0 3px oklch(0.46 0.137 24 / 0.1)`).

**Focus.** Every interactive element shows a visible keyboard focus state: links, buttons, the function cards, the menu toggle, and the consent checkbox get a 2px `--accent` `:focus-visible` outline at 3px offset; text inputs keep their accent focus ring instead. Never suppress focus without a replacement.

**Reveal robustness.** Scroll-reveal elements start hidden and are shown by JS, so every indexed page carries a `<noscript>` fallback that forces `.reveal` / `.stagger > *` to their final visible state. Content must never depend on JS to become visible (no-JS clients and headless link-preview scrapers).

## Information architecture (locked: function-led)

The site's spine is **business function**, not industry. Industries are illustrative examples only.

- **Homepage** sections: Hero → The difference (off-the-rack vs tailored) → How it works (Measure/Cut & build/Fit & run) → Two modes (H2A/A2A) → The promise (managed service) → What we automate (by function) → Proof → Book a fitting.
- **Example branches** organize by function — **Finance, Sales, Support, Operations, Admin** — each shown through concrete workflows with an "Example: a \_\_\_ firm" tag. Never lead a page with an industry as the category.
- **Voice rule for every block:** if a line could appear on any automation or consulting site, rewrite it (PRODUCT.md §Design Principles 5).

## Motion

- **Reveal/stagger on scroll** via `IntersectionObserver` (threshold ~0.14): elements rise 20–22px and fade in; staggered children step by ~0.07s. Easing token: `--e-out: cubic-bezier(0.22, 1, 0.36, 1)`.
- **Micro-interactions:** button lift, link underline wipe, card hover, the `.live` pulse. All subtle, all short (≤0.4s).
- **Reduced motion (required):** under `@media (prefers-reduced-motion: reduce)`, all animation/transition durations collapse to ~0, `scroll-behavior: auto`, and every `.reveal`/`.stagger` element renders at its final state (opacity 1, no transform). **Every animation must have this alternative — no exceptions.**

## Accessibility floor (WCAG 2.1 AA)

Non-negotiable, inherited from PRODUCT.md:
- Contrast as specified above; color never the sole signal.
- Full keyboard navigation; visible focus states (accent ring) on every interactive element.
- Forms keep explicit `<label>`s and accessible, text-based error states (not color-only).
- `prefers-reduced-motion` honored everywhere.
- Semantic landmarks (`nav`/`main`/`footer`), one `<h1>` per page, logical heading order, `aria-expanded` on the mobile menu toggle, meaningful `alt`/`aria-label`s.

## Waitlist / "Book a fitting" form (production contract)

Carried over verbatim from the proven live implementation — do not redesign the mechanics, only the skin:

- **Cloudflare Turnstile** — sitekey `0x4AAAAAACoxs1paqeNUfi4O`, `data-theme="light"`, `data-size="flexible"`, with `verified` / `expired` / `error` callbacks. Preconnect to `challenges.cloudflare.com`; load the API script `async defer`.
- **Consent checkbox** — explicit opt-in to email; its label is a real `<label>`. Submit stays **disabled until Turnstile is verified AND consent is checked**.
- **Submit** — `POST /api/waitlist`, JSON body `{ email, token, context, consent }`; success = `{ ok: true }`. Mailchimp runs server-side; the client only talks to `/api/waitlist`. On success, swap the button to a confirmed state and disable the email input; on failure, re-enable and flash the Turnstile widget.
- Two instances per page (hero + CTA) use distinct `context` values ("hero" / "cta") and distinct element IDs.

## Production hardening (live pages only)

When porting to live `index.html` (and any indexed page), carry these forward from the current live site:
- **GTM** container `GTM-P3879ZKR` (head snippet; GTM-only — no direct GA4).
- **SEO:** `robots: index, follow`, canonical URL, descriptive `<title>` + meta description on the *automation* concept.
- **Open Graph** + **Twitter Card** (`summary_large_image`) with `og-image.png` (1200×630), `og:locale en_CA`, updated titles/descriptions.
- **JSON-LD** structured data (Organization / WebSite) reflecting FirmClerk as a managed automation service.
- Font + Turnstile `preconnect`s in `<head>`.

## Do / Don't

**Do:** lead with outcomes and the tailoring metaphor; keep one accent; use real workflows; honor reduced motion; keep the human-in-control state visible.

**Don't:** add a second accent or a gradient hero; use robot/circuit/AI-glow imagery; show a node canvas (that's the foil, n8n/Zapier/Make); use Big-4 stock photography or transformation buzzwords; let industries become the structure; ship an animation without a reduced-motion fallback.
