# WhatTerms — Brand Guidelines

**Theme:** Indigo Pulse (default / dark)
**Status:** v1.0 · locked
**Date:** 2026-05-07
**Owner:** Founder
**Companion document:** [BRAND-ASSETS-REGISTER-2026-05-07.md](BRAND-ASSETS-REGISTER-2026-05-07.md)
**Live reference:** `/brand-preview/pulse-indigo` (canonical mock)
**Source of truth (code):** [`src/app/brand-preview/pulse/_factory.tsx`](../src/app/brand-preview/pulse/_factory.tsx) · [`src/app/brand-preview/pulse-indigo/page.tsx`](../src/app/brand-preview/pulse-indigo/page.tsx) · [`src/app/brand-preview/_theme-mock.tsx`](../src/app/brand-preview/_theme-mock.tsx)

---

## 0. About this document

This is the canonical brand book for WhatTerms. It encodes every decision required to apply the brand consistently — across product, marketing, email, social, and print. Anyone producing a WhatTerms artifact should be able to do so from this document plus the asset register, without further input from the founder.

If something is missing here, treat the live mock at `/brand-preview/pulse-indigo` as the source of truth and add a note for the next revision.

This document also assumes a future light-theme variant. Where light-theme tokens differ, they are flagged inline as **(light)**.

---

## 1. Brand at a glance

| | |
|---|---|
| **Product** | WhatTerms |
| **Eyebrow** | Understand the tradeoffs. |
| **Positioning** | The terms are designed to be ignored. Let's fix that. |
| **Promise** | We read every Terms doc so you don't have to — and walk you through what to do about it, in plain English. |
| **Archetype** | The Sage, in modern-app clothing. Clear-eyed, plainspoken, never alarmist. |
| **Voice** | Confident, warm, slightly dry. Direct without being cold. |
| **Primary color** | Saffron `#FFB546` |
| **Primary surface** | Indigo `#101430` |
| **Primary type** | Inter Tight (display) + Inter (body) + Geist Mono (verbatim quotes) |
| **Logo** | Rounded-square mark with a saffron pulse-wave on deepest-indigo, paired with an Inter Tight wordmark |
| **Adjacent reference brands** | Linear (rigor), Cal.com (warmth), Stripe (typography), Mercury (calm fintech) |

---

## 2. Strategic frame

### Mission

Help everyday people understand what they're agreeing to when they sign up for an app, and act on what they learn.

### Vision

A world where reading the terms is a one-click decision support, not a two-hour legal exercise — and where downstream actions (deletion, opt-out, complaint) are as one-click as the verdict.

### Promise

> *We read the terms of every app you use, score them 0–100, flag what matters, and walk you through the next step.*

This is the brand's contract with the user. Every interface decision and every piece of copy should be auditable against this single sentence.

### Archetype

**The Sage**, in the language of modern apps.

The Sage archetype is about **truth-seeking and clarity** — not about expertise as gatekeeping. Our archetype is calibrated against three guardrails:

1. **Not the Hero.** WhatTerms doesn't position itself as a savior fighting evil corporations. It's a guide that hands you the truth and the next step.
2. **Not the Caregiver.** WhatTerms doesn't infantilize. The user is tech-literate; they just don't have legal training. We meet them at peer level.
3. **Not the Outlaw.** WhatTerms doesn't trade on outrage or fear. The data is alarming enough on its own; the brand stays calm.

### Adjacent reference brands

Borrow from each:

- **Linear** — typographic rigor, dark-surface confidence, motion that respects the user's time.
- **Cal.com** — warmth in a dark UI, gentle copy, single confident accent color.
- **Stripe** — tabular numerals, the discipline that turns a number into trust.
- **Mercury** — financial confidence in dark mode without coldness.
- **The Markup** — citation-first credibility (we already share their thesis; we share their visual restraint too).
- **Substack (post page)** — body copy that respects long-form reading.

Don't borrow from: DoNotPay (legalese energy), DeleteMe (security-paranoia palette), TOSDR (volunteer-y aesthetic), generic legal-tech (corporate blue/gray).

---

## 3. Voice & tone

### The voice in one paragraph

WhatTerms speaks like a smart friend who happens to read legal documents for a living. Direct, slightly dry, warm but never cute. Confident enough to make a call, humble enough to cite the source. Never panicked, never preachy, never punishingly clever. The user is on our side; we're not selling them anything they wouldn't already want.

### Voice principles

1. **Lead with the verdict, then the receipt.** Don't bury the score. Don't bury what to do about it. Show the citation second, after the user already knows where they stand.
2. **Plain English first.** If a term needs translating, translate it. Never expect the user to know what "indemnification" or "GPC" or "arbitration waiver" means without context. Define it inline, in fewer than 12 words.
3. **Specific, not general.** "Sells inferred interests; opt-out buried 4 clicks deep" beats "concerning data practices." Names matter. Counts matter. Quotes matter.
4. **Calm, not cold.** We've earned warmth by doing the work. Use contractions ("don't," "you're"), use second person, use one comfortable em-dash per paragraph maximum.
5. **Action over awareness.** Every score should be paired with what to do about it. The brand voice rises in confidence at the action moment ("Walk me through opting out") and recedes at the explanation moment ("This is a forced-arbitration clause; here's what that means").

### Tone matrix

Tone shifts by context, voice does not.

| Context | Tone | Sample |
|---|---|---|
| Hero / landing | Confident, slightly punchy | "The terms are designed to be ignored. Let's fix that." |
| Score reveal | Calm, matter-of-fact | "Score: 42 / 100 · #48 of 50 · #6 of 7 in Streaming" |
| Verdict explainer | Plain-English translator | "This means: if Spotify mishandles your data, you can't join other users in a class action." |
| Action CTA | Action-oriented, first-person | "Walk me through opting out" |
| Empty state | Warm, encouraging | "Add the apps you actually use. We'll do the reading." |
| Error state | Direct, no apology theater | "We couldn't reach this site. Try again, or send us the URL and we'll add it manually." |
| Success state | Quiet, never cheerful | "Receipt saved. We'll re-check this policy weekly." |
| Marketing email | Editorial, longer line lengths, citations | "Three apps in your stack quietly changed their Terms last week. Here's what changed." |
| Push notification | Short, signal-only, never alarming | "Notion updated its Privacy Policy. Score dropped to 64." |
| Social post | Punchy, citation-led | "Spotify's arbitration clause has a 30-day opt-out window. Most users miss it. Here's the exact language." |
| Onboarding | Hand-on-shoulder, never patronizing | "Pick a few apps you use. We'll walk through the first one together." |

### Vocabulary

**Use:**

- **"the terms"** — the umbrella for ToS, Privacy Policies, EULAs, AUPs, cookie policies, etc. Always lowercase, even as the umbrella term. The proper-noun document name "Terms of Service" remains capitalized.
- **"Understand the tradeoffs."** — the recurring eyebrow.
- **"designed to be ignored"** — the positioning hook for hero contexts. Note: "designed," not "written."
- **"Let's fix that."** — the brand response that closes the headline. Always title-case, always saffron emphasis.
- **"score" / "scored"** — the noun for our 0–100 verdict. Singular even when referring to category subscores ("Spotify's score dropped to 38").
- **"stack"** — the user's portfolio of services. Personal, possessive, casual ("your stack").
- **"verdict"** — used sparingly when narrating a single service review. Don't overuse.
- **"the terms changed"** — for surveillance-drift alerts. Never "terms updated" (sounds like a software update; misses the gravity).

**Score-band labels (narrative, not nominal):**

| Score | Label | Meaning | Use |
|---|---|---|---|
| 80–100 | **Excellent** | Strong privacy practices across all categories | Score chips, badges, dashboard rollups |
| 65–79 | **Strong** | Good practices, minor concerns | — |
| 45–64 | **Mixed** | Some good practices, some concerning practices | — |
| 25–44 | **Risky** | Significant concerns in multiple categories | — |
| 0–24 | **Critical** | Serious, largely non-mitigable issues | — |

These narrative labels stand in for generic "Low / Medium / High." They tell the user **what they're looking at** while staying neutral. Always pair with the raw 0–100 score so power users can see the precision.

**Avoid:**

- "Don't worry" — performative reassurance.
- "Easy" / "simple" / "just" — minimizing words. Reading legal docs is hard; pretending otherwise insults the user.
- "Compliant" / "legal" — we don't make compliance claims about services.
- "Bad" / "evil" / "shady" — we let the data speak. Adjectives are the user's job.
- "Smart" / "intelligent" — about ourselves. We're useful, not smart.
- Exclamation marks. Anywhere. Ever. The data is its own emphasis.
- The word "Privacy Policies" as the brand umbrella (use "the terms").
- The word "written" in our "designed to be ignored" frame (we want intent, not authorship).

### Editorial style

- **Sentence case** for headlines, subheadings, navigation, button labels, and section titles. **Title Case is reserved for proper nouns** (service names, the product name, regulator names). The default should feel like editorial prose, not press releases.
- **Em-dashes** — use freely, but cap at one per paragraph. They are the WhatTerms equivalent of a measured pause.
- **Numerals** — always use figures for any numeric claim ("3 services," "42 / 100," "30-day opt-out"). Spell only when starting a sentence.
- **Score notation** — `42 / 100`, with spaces, never `42/100`. The "/ 100" component is at 50% emphasis (smaller, muted) versus the leading number.
- **Date format** — `2026-05-07` (ISO) in product UI metadata; `May 7, 2026` in marketing prose.
- **Quotes** — always curly (`"…"`), never straight. Pull-quotes inside quotes use single (`'…'`).
- **No Oxford comma** in marketing prose; **Oxford comma in product** for clarity.
- **Sentence-final periods** — required on body paragraphs; optional on UI labels and badge labels (never mix the two on a single screen).

### Sample copy library

Hero options (variants of the locked headline):

- "The terms are designed to be ignored. **Let's fix that.**" *(canonical)*
- "Privacy without the legalese. **Score every app you use.**"
- "Read what you're agreeing to. **In one minute.**"

Eyebrow variants (always uppercase, tracked):

- "UNDERSTAND THE TRADEOFFS" *(canonical)*
- "READ WHAT YOU'RE AGREEING TO"
- "EVERY APP. EVERY POLICY. ONE SCORE."

Subheads:

- "WhatTerms reads the terms of every app you sign up for. We score each one 0–100, flag what matters, and walk you through the next step — in plain English."
- "Every app buries the bad parts in legal text most people never read. We read it, score it, and tell you what to do about it."

Primary CTAs:

- "Build your stack" *(canonical for unauthenticated users)*
- "Score this one" *(in-product, on the scan flow)*
- "Walk me through this" *(action-flow opener)*

Secondary CTAs:

- "Browse the directory"
- "Or scan any URL"
- "See the receipt"

Empty states:

- *(stack)* "Add the apps you actually use. We'll do the reading."
- *(scan)* "Paste any URL. We'll have a verdict in under a minute."
- *(directory)* "Loading 50 services…" *(only for the moment of load; never as a permanent empty)*

Error states:

- "We couldn't reach this site. Try again, or send us the URL and we'll add it manually."
- "This URL doesn't look like a Terms page. Want us to scan the homepage instead?"
- "Score profile changed. Recalculating against the new weights…"

Success / quiet confirmations:

- "Receipt saved. We'll re-check this policy weekly."
- "Opt-out letter ready. Send it from your email; we've pre-filled the address."
- "Added to your stack. Score updates in a moment."

Marketing email subject lines (sample):

- "Three apps in your stack changed their Terms last week"
- "You have 3 days to opt out of Spotify's arbitration clause"
- "Notion's score dropped to 64. Here's why."

Push notifications (when the product gets there):

- "Notion changed its Privacy Policy. Score: 68 → 64."
- "Your arbitration opt-out window for Spotify closes in 5 days."
- "Meta disclosed a breach. 1 service in your stack is affected."

---

## 4. Logo system

### The mark

The mark is a **rounded-square enclosure** containing a **saffron pulse-wave** with a **terminal dot**.

Geometry (canonical):

- Enclosure: 32 × 32 px viewbox, `rx` = 9, fill = `#101430` (deepest-indigo / `--surface-inverse`).
- Pulse path: `M7 22 L12.5 11 L16 18 L19.5 12 L25 22`, rotated 180° around (16, 16).
- Stroke: 2.6 px, `stroke-linecap: round`, `stroke-linejoin: round`, fill = none, color = `#FFB546` (saffron).
- Terminal dot: circle at (25, 22) before rotation, radius 2.1 px, fill = saffron.

Source SVG lives in [`src/app/brand-preview/pulse/_factory.tsx`](../src/app/brand-preview/pulse/_factory.tsx) (export `PulseMark`). Treat the file as the construction reference — any rendering should be visually identical when re-exported.

The 180° rotation is intentional: the un-rotated version reads as a heart-rate monitor, which is a worn metaphor in the privacy/security space. The rotated version reads as a wave, which is unique and on-brand.

### The wordmark

- Family: **Inter Tight**.
- Weight: 600 (semibold).
- Letter-spacing: −0.018 em (header), −0.014 em (footer / small).
- Color: `#F2EFEA` (off-white) on dark surfaces; `#0A0A0A` on light surfaces (light-theme variant).
- Cap-height should match the rendered icon height as closely as possible at the chosen size.

### Lockups

Three approved lockups:

1. **Horizontal lockup** *(default)*: mark on the left, wordmark on the right. Gap = mark height ÷ 3.2 (e.g., 32 px mark → 10 px gap; 22 px mark → 7 px gap). Used in headers, footers, marketing headers, email banners.
2. **Stacked lockup**: mark on top, wordmark centered below. Gap = mark height ÷ 4. Reserved for square-format placements (social profile pictures, app icons with wordmark).
3. **Symbol-only**: just the mark. Used for favicon, app icons, social profile pictures (when wordmark would be illegible at the size), pinned tab.
4. **Wordmark-only**: just the wordmark. Used inside running prose, on letterhead where the mark is already nearby, and in single-line footer scenarios.

### Clearspace

- Minimum clearspace around any lockup: equal to the cap-height of the wordmark on all four sides.
- For symbol-only: minimum clearspace equal to the corner-radius of the enclosure.

### Minimum sizes

- Mark: minimum 16 px on screen, 8 mm in print.
- Wordmark: minimum 12 px on screen, 6 mm in print. Below this size, use the symbol-only lockup.
- Horizontal lockup: minimum 96 px wide on screen.

### Color variants

| Variant | Use | Mark fill | Stroke | Wordmark |
|---|---|---|---|---|
| **Full color on dark** *(canonical)* | Dark UI surfaces, dark marketing | `#101430` | `#FFB546` | `#F2EFEA` |
| **Full color on light** *(light theme)* | Light UI surfaces, light marketing, print on white | `#101430` | `#FFB546` | `#0A0A0A` |
| **Saffron knockout** | Saffron-on-saffron contexts (rare) — e.g., a saffron-fill social card | `#101430` | `#FFB546` | `#101430` |
| **Off-white knockout** | Light surfaces with high contrast required | `#101430` | `#101430` | `#101430` |
| **Single-color black** | Print, fax, single-ink reproduction | `#000000` | `#000000` | `#000000` |
| **Single-color white** | Solid-color photo overlays where saffron would clash | `#FFFFFF` | `#FFFFFF` | `#FFFFFF` |

The full-color-on-dark variant is the primary; the saffron stroke must always survive the variant choice if at all possible.

### Logo don'ts

- Do not rotate the lockup or the mark independently.
- Do not change the rotation of the pulse-wave inside the enclosure (the 180° rotation is part of the construction).
- Do not skew, stretch, condense, or extend the wordmark.
- Do not change the wordmark family. Inter Tight is part of the logo.
- Do not use the un-rotated heart-rate-monitor version of the mark.
- Do not place the mark on a busy photo without the dark enclosure visible.
- Do not change the corner-radius of the enclosure.
- Do not recolor the saffron stroke to anything except the approved variants above.
- Do not add a drop shadow, glow, gradient, or texture to the enclosure or the stroke.
- Do not use the lockup as a watermark behind body text.
- Do not separate the wordmark from the mark with custom slashes, dots, or "× " between them.

---

## 5. Color system

All color tokens listed here are the canonical hex values. The CSS variable names (`--*`) are the eventual production token names; today they live partly in [`src/app/globals.css`](../src/app/globals.css) and partly in the brand-preview factory. The migration to the production tokens is the next implementation step.

### Brand colors

| Role | Token | Hex | Notes |
|---|---|---|---|
| **Primary signal** | `--brand-saffron` | `#FFB546` | Primary CTA bg, headline emphasis ("Let's fix that."), brand accent. Never used for body text. Never used for risk-low. |
| **Primary text / accent** | `--brand-cream` | `#F2EFEA` | Body text on dark surfaces. Logo wordmark on dark. Eyebrow dot. Avatar pile. |

These two colors are the brand. Everything else is supporting infrastructure (surface, text, borders, risk semantics).

### Surface stack — Indigo (dark theme, default)

| Role | Token | Hex | Use |
|---|---|---|---|
| Page background | `--surface-page` | `#101430` | The body bg. Most "empty space." |
| Card surface | `--surface-card` | `#1A1F3D` | Default card / panel bg. One step lighter than page. |
| Tinted surface | `--surface-tinted` | `#222848` | Inset panels (e.g., the policy excerpt block inside a card). Two steps lighter than page. |
| Inverse surface | `--surface-inverse` | `#070920` | Logo enclosure, "highest concern" inverse panels, deepest emphasis. |

The hierarchy is **page → card → tinted → inverse** for elevation legibility, with inverse used for *emphatic depth* (lower than page) and tinted/card used for *raised elevation* (higher than page).

### Surface stack — Light theme (forward, when implemented)

The light theme mirrors the indigo stack but inverts the elevation logic:

| Role | Token | Hex (light) |
|---|---|---|
| Page background | `--surface-page` | `#FBF9F4` |
| Card surface | `--surface-card` | `#FFFFFF` |
| Tinted surface | `--surface-tinted` | `#F2EEE3` |
| Inverse surface | `--surface-inverse` | `#0A0F1F` |

In light theme, the saffron primary remains `#FFB546` (it works on cream — verified in the Spotlight mock). Off-white text becomes `#1A2330` deep slate.

### Text colors

| Role | Token | Hex (dark) | Hex (light) | Use |
|---|---|---|---|---|
| Primary text | `--text-primary` | `#F2EFEA` | `#1A2330` | Body, headings |
| Muted text | `--text-muted` | `#9099B5` | `#5A6373` | Subheads, captions, secondary info |
| Subtle text | `--text-subtle` | `#5E657E` | `#9892A8` | Eyebrows, footnotes, "Reviewed YYYY-MM-DD" timestamps |

### Borders

| Role | Token | Hex (dark) | Hex (light) | Use |
|---|---|---|---|---|
| Subtle rule | `--rule` | `#252B45` | `#E5DBC4` | Default card borders, divider lines |
| Strong rule | `--rule-strong` | `#333A56` | `#C9BC9F` | Higher-contrast borders (button outlines, tab indicators) |

### Score-band semantic colors

| Score | Token | Hex | Narrative label |
|---|---|---|---|
| 80–100 | `--risk-low`    | `#34D399` | Excellent |
| 65–79  | `--risk-strong` | `#4AA3E8` | Strong |
| 45–64  | `--risk-med`    | `#D9A24A` | Mixed |
| 25–44  | `--risk-high`   | `#F77957` | Risky |
| 0–24   | `--risk-crit`   | `#E94545` | Critical |

These are **semantic** colors. Use them only inside score chips, score bars, score-related badges, and risk-related stat callouts. Do not use them as brand or marketing accents (the brand has saffron for that). Do not use the green for "success" generally; use saffron for affirmative states unless you're literally communicating a score.

### Color usage rules

1. **Saffron is sacred.** Used for: primary CTAs, headline emphasis, brand mark, score-affirmative moments. Never for: risk-med (it's close visually but reserved), body text, error states.
2. **Off-white is the body.** Default text color on dark surfaces. Never use white (`#FFFFFF`) for text on dark — it will read too cold against the warm saffron.
3. **Layer surfaces in pairs.** Page → Card. Card → Tinted. Don't skip levels (e.g., never put a tinted surface directly on the page surface; always wrap in a card first).
4. **Inverse is for depth, not contrast.** The `surface-inverse` is *darker* than the page bg, not lighter. It signals "this is deeper, more important" — used for the high-emphasis "highest concern" panel and the logo enclosure.
5. **Risk colors are ring-fenced.** Score chips use a `band-color @ 10% alpha` background, a `band-color @ 20% alpha` ring, and the band color as text. Never use risk colors at full saturation outside of a score badge.
6. **Don't use color alone for risk semantics.** Always pair the band color with the narrative label and the numeric score. Color-blind users and low-contrast displays must still be able to read the verdict.

### Color proportions (suggested)

In a typical product screen:

- **70%** surface tones (page + card + tinted)
- **20%** text (off-white primary + muted)
- **6%** brand saffron (CTAs, eyebrow dots, score-affirmative moments)
- **4%** risk colors (score chips, score bars)

If saffron is showing up in more than 1 place per viewport, you're probably using it wrong.

### Accessibility

All approved pairings have been tested against WCAG 2.1 AA:

| Pair | Ratio | Verdict |
|---|---|---|
| `--text-primary` on `--surface-page` | 14.6 : 1 | AAA at all sizes |
| `--text-primary` on `--surface-card` | 12.4 : 1 | AAA |
| `--text-muted` on `--surface-page` | 5.8 : 1 | AA at body sizes; AAA at large |
| `--text-subtle` on `--surface-page` | 3.6 : 1 | AA Large only — use only for non-essential text |
| Saffron CTA (saffron bg / `#101430` text) | 9.2 : 1 | AAA — large CTA text is fine |
| Saffron emphasis on `--surface-page` | 6.8 : 1 | AA at all sizes |
| Risk-crit on `--surface-page` | 4.7 : 1 | AA |
| Risk-low on `--surface-page` | 5.1 : 1 | AA |

When new pairings are introduced, document the contrast ratio here and verify AA at minimum.

---

## 6. Typography

### Type families

| Role | Family | Weights used | Source |
|---|---|---|---|
| **Display** | Inter Tight (variable) | 500, 600, 700, 800 | Google Fonts (`Inter+Tight:wght@500;600;700;800`) |
| **Body** | Inter (variable) | 400, 500, 600, 700 | Google Fonts (`Inter:wght@400;500;600;700`) |
| **Mono** | Geist Mono | 400, 500 | Google Fonts (`Geist+Mono:wght@400;500`) |

System fallback stack:

```css
--font-display: 'Inter Tight', 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
--font-body:    'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
--font-mono:    'Geist Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
```

### Type scale (web)

| Token | Family | Weight | Size | Leading | Tracking | Use |
|---|---|---|---|---|---|---|
| `--text-display-1` | Inter Tight | 600 | 64 / clamp(40, 5vw, 64) px | 1.05 | −0.022 em | Hero headline |
| `--text-display-2` | Inter Tight | 600 | 36 px | 1.10 | −0.020 em | Section heroes |
| `--text-display-3` | Inter Tight | 600 | 32 px | 1.15 | −0.020 em | Page titles, "Highest concern" |
| `--text-h1` | Inter Tight | 600 | 28 px | 1.20 | −0.018 em | Major card titles |
| `--text-h2` | Inter Tight | 600 | 22 px | 1.25 | −0.014 em | Card titles (e.g., service name on service card) |
| `--text-h3` | Inter Tight | 600 | 18 px | 1.30 | −0.014 em | Sub-card titles, list-item heads |
| `--text-body-lg` | Inter | 400 | 17 px | 1.7 | 0 | Hero subheads, longform |
| `--text-body` | Inter | 400 | 15 px | 1.65 | 0 | Default body |
| `--text-body-sm` | Inter | 400 | 14 px | 1.6 | 0 | Secondary body |
| `--text-caption` | Inter | 500 | 12 px | 1.5 | 0 | Captions, footnotes |
| `--text-eyebrow` | Inter | 600 | 11 px | 1.0 | 0.22 em | All-caps eyebrows, tab labels, metadata rows |
| `--text-mono-quote` | Geist Mono | 400 | 15 px | 1.7 | 0 | Verbatim quotes from policies |
| `--text-mono-meta` | Geist Mono | 400 | 12 px | 1.5 | 0 | Hash strings, timestamps |
| `--text-score` | Inter Tight | 700 | 64 px | 1.0 | −0.030 em, tabular-nums | Big score numbers ("42") |
| `--text-score-sm` | Inter Tight | 700 | 30 px | 1.0 | −0.025 em, tabular-nums | Card score numbers |

### Number style

All numeric data must use `font-variant-numeric: tabular-nums`. Score numbers, rank summaries, dashboard counts, and percentage readouts. This keeps columns aligned and turns numbers into evidence.

Score format: `42 / 100` — the leading number at full emphasis, the `/ 100` suffix at 50% size and `--text-muted`. Never `42/100`.

Rank format: `#48 of 50` (number sign, ordinal-style spacing).

### Pairings

- **Inter Tight + Inter** is the default pairing. Display headlines in Inter Tight, body in Inter.
- **Inter alone** is fine for utility surfaces (dashboards, settings) where Inter Tight's distinctiveness doesn't add value.
- **Geist Mono** appears only in two places: verbatim quoted clauses, and metadata strings (timestamps, hashes, slugs).
- Never pair Inter Tight with a serif. Never pair Geist Mono with a different mono. Never display body copy in Geist Mono.

### Practical defaults

- Body line-length: 60–75 characters per line. Use `max-width: 65ch` on body-prose containers.
- Line-height: see the type scale above. Treat leading as a brand commitment; do not collapse to 1.4 to fit more on screen.
- Eyebrow tracking: always `0.22em`, always uppercase.
- Headline tracking: always negative (compresses Inter Tight's natural breathing).

---

## 7. Iconography

### Style

- **Stroke icons**, 1.5–2 px stroke width, no fills.
- **Geometric construction** on a 24 × 24 grid, scales cleanly to 16, 20, 32, 48.
- **Round caps and joins.** Sharp corners are off-brand.
- **Single color** at any one size. The icon's role determines color (default, saffron for primary action, risk-color for warning).

### Library

Lucide is the primary library. When Lucide doesn't have what we need, custom icons are drawn following the same construction rules.

Custom icons in active use:

- **Pulse** (the brand mark, scaled down)
- **Stack** (a small square stack of three rectangles)
- **Compare** (two overlapping rounded rectangles)
- **Scan** (a square with a corner-bracket overlay)
- **Receipt** (a rectangle with a torn-edge bottom)
- **Compass** (held in reserve — not currently used; was part of the de-prioritized Guide direction)

### Sizing

| Context | Size |
|---|---|
| Inline with body text | 14 × 14 |
| Button leading icon | 16 × 16 |
| Nav item, card eyebrow | 20 × 20 |
| Card hero icon | 24 × 24 |
| Empty state | 48 × 48 |

### Don'ts

- No filled icons (except the logo mark itself).
- No multicolor icons (except the logo).
- No isometric / 3D icons.
- No emoji in product UI. Emoji are fine in user-generated content only.

---

## 8. Motion

### Principles

- **Calm, intentional, never bouncy.** No spring physics, no overshoot, no anticipation.
- **GPU-friendly.** Animate transform and opacity. Don't animate width, height, top, or color (when avoidable).
- **Fast in, slow out.** Default to `ease-out` — entrances feel responsive, exits feel considered.
- **Respect prefers-reduced-motion.** Wrap any non-essential motion in `@media (prefers-reduced-motion: no-preference)`.

### Default durations

| Motion | Duration | Easing |
|---|---|---|
| Hover micro-interaction | 200 ms | `ease-out` |
| Focus ring appearance | 150 ms | `ease-out` |
| Card hover lift | 200 ms | `ease-out` |
| Modal / panel entrance | 250 ms | `ease-out` |
| Modal / panel exit | 200 ms | `ease-in` |
| Page transition | 250 ms | `ease-out` |
| Score number reveal | 600 ms | `ease-out` count-up |
| Toast appearance | 300 ms | `ease-out` |
| Skeleton shimmer | 1500 ms | `ease-in-out` infinite |

### Specific patterns

- **Card hover:** translate up 2 px, soft shadow growth, 200 ms ease-out.
- **CTA hover:** translate up 2 px (or 0.5 px on small CTAs), shadow grows from `0 6px 14px -6px rgba(255,181,70,0.35)` to `0 12px 28px -10px rgba(255,181,70,0.55)`.
- **Score reveal:** count up from 0 to the final score over 600 ms, ease-out. Only on first mount, not on subsequent re-renders.
- **Stripe / pulse decoration** in marketing surfaces: a slow horizontal sweep (3–4 s), only when in viewport, only once per page load.

### Don'ts

- No looping marketing animations (single sweep on first paint, then static).
- No parallax scroll effects.
- No "scroll-jacking."
- No mouse-follow effects.
- No confetti, even on celebratory moments.

---

## 9. Imagery and illustration

### Photography

WhatTerms generally avoids photography in product. When used in marketing:

- **Editorial documentary** style. Real moments, not staged.
- **Subjects:** screens, paper, people working at distance (rarely faces in close-up).
- **Treatment:** warm shadow, slight teal-amber color grade. Never high-key bright.
- **Aspect:** prefer 3:2 and 16:9. No squares for hero photography.

Avoid:

- Stock-photo "people pointing at laptops"
- Hands-typing-on-keyboard close-ups
- Generic "diverse team smiling at meeting"
- Privacy/security clichés (locks, shields, hooded figures, magnifying glass over a document)

### Illustration

WhatTerms uses illustration sparingly. When used:

- **Geometric, flat, line-led.** Same construction rules as iconography but with more freedom.
- **Pulse-wave motif** as recurring element. The wave from the logo can appear at larger scales as a marketing texture.
- **Limited palette:** saffron, off-white, surface tones, occasional risk color for emphasis. No introduction of new colors.
- **Reference:** Linear marketing illustrations, Stripe documentation diagrams, Notion's onboarding spots.

Forbidden:

- Cartoonish or "corporate Memphis" illustrations.
- Hand-drawn / sketchy styles.
- Illustration of human figures (use photography for that, sparingly).

---

## 10. UI patterns

This section defines the canonical implementations. Production code should match these specs.

### Card primitive

Variants (live in [`src/components/ui/card.tsx`](../src/components/ui/card.tsx)):

| Variant | Bg | Border | Use |
|---|---|---|---|
| `default` | `--surface-card` | `--rule` | Standard card |
| `raised` | `--surface-card` | `--rule` + soft shadow | Important cards (dashboard panels) |
| `inverse` | `--surface-inverse` | none | Highest-emphasis blocks |
| `subtle` | `--surface-tinted` | `--rule` | Inset panels |
| `dashed` | `--surface-card` 70% | `--rule-strong` dashed | Empty states, "drop here" affordances |

Default radius: `1.75rem` (`rounded-2xl`). Use `rounded-3xl` (2 rem) for hero panels only.

Default padding: `1.5rem` (`p-6`). Use `p-5` for nested / smaller cards.

### Buttons

| Variant | Bg | Text | Border | Use |
|---|---|---|---|---|
| **Primary** | `--brand-saffron` | `--surface-inverse` | none | Main CTA. One per viewport ideal. |
| **Secondary** | `--surface-card` | `--text-primary` | `--rule-strong` | Supporting actions |
| **Tertiary** | transparent | `--brand-saffron` | none | Inline links, "or scan any URL" |
| **Destructive** | `--risk-crit` 10% bg | `--risk-crit` | `--risk-crit` 30% | Permanent / irreversible actions |

All buttons:

- Padding: `0.75rem 1.5rem` (12 × 24).
- Radius: `999px` (full-pill).
- Font: Inter, 14 px, weight 600.
- Hover: −2 px Y translate, 200 ms ease-out, shadow lift on primary.
- Focus: 2 px ring, color `--brand-saffron @ 50% alpha`, offset 2 px.

### Inputs

States:

- Default: `--surface-tinted` bg, `--rule` border, `--text-primary` text.
- Hover: border becomes `--rule-strong`.
- Focus: 2 px saffron ring, border becomes `--brand-saffron`.
- Error: 2 px ring `--risk-crit`, border `--risk-crit`. Error message in `--risk-crit` 14 px Inter 500 below.
- Disabled: opacity 50%, cursor not-allowed.

### Score chip

The score chip is the most distinctive UI element — design with care.

```
┌─────────────────────┐
│ [band color text]   │   ← narrative label, e.g., "Risky"
└─────────────────────┘
   bg: band-color @ 10% alpha
   border: band-color @ 30% alpha (1px)
   radius: 999px (pill)
   padding: 4px 12px
   font: Inter 600, 12px
   letter-spacing: 0
```

Inside cards, the chip sits in the top-right of the card header.

### Score bar

A horizontal fill showing the score visually. Always paired with the numeric score above or beside it.

- Track: `--surface-tinted`, height 8 px, radius 999 px.
- Fill: band color (full saturation), animated count-up on first mount.
- Width: `score%` of track.

### Inverse panel

The "highest concern" pattern.

- Bg: `--surface-inverse`.
- Text: `--text-primary` (off-white).
- Used for emphatic content blocks, "focus this week" CTAs, the highest-stakes content. Use sparingly — at most one per page.

### Eyebrow tag

The pill-style metadata tag.

```
[ • THE FINE PRINT, DECODED ]
```

- Bg: `--surface-card`.
- Border: `--rule`.
- Text: `--text-muted`, all caps, tracking `0.22em`, 11 px.
- Optional leading dot: `--brand-saffron`, 6 px, circle.

---

## 11. Score-band display rules

Every score appearance follows one of three formats, depending on context:

**Full format** (used in service detail pages, hero sample card):

```
SCORE                         POSITION
42 / 100                      #48 of 50
                              #6 of 7 in Streaming
[score bar fill, band color]
```

**Compact format** (used in directory cards, stack rows):

```
[narrative chip]    42 / 100 · #48 of 50
```

**Minimal format** (used in inline references, tweets):

```
Spotify · 42 / 100
```

Always include narrative label + numeric score together when space permits. Numeric alone is fine for inline / dense contexts. Never narrative alone (the user can't compare narrative labels — they need the number for ordering).

---

## 12. Web-app patterns

### Header

The site header is sticky at the top, always visible.

Anatomy (left → right):

- Logo lockup (32 px mark + Inter Tight 600 wordmark)
- Primary nav (Directory · Stack · Compare · Scan)
- Active nav item: saffron pill, deep-indigo text
- Inactive nav items: muted text, hover bg `--surface-card`
- Right side: "Sign in" button (secondary variant)

On mobile (< 768 px):

- Logo lockup left
- Hamburger trigger right
- Drawer slides down from below header on click
- Drawer items: full-width, no pills, with active state as left-border accent

### Footer

Three-row layout on desktop:

1. Logo lockup + "Decision support, not legal advice." disclaimer
2. Footer nav (Directory, Stack, Compare, Scan, Methodology, Privacy)
3. Copyright row

Single-column stack on mobile.

### Page rhythm

- `--space-section`: `4 rem` (64 px) between major sections on desktop, `3 rem` on mobile.
- `--space-stack`: `1.5 rem` (24 px) between stacked elements within a section.
- Page content `max-width`: `1200 px`. Hero / marketing surfaces can extend to `1280 px`.

---

## 13. Accessibility

Commitments:

- WCAG 2.1 **AA** across all surfaces. **AAA** for primary body text.
- Visible focus states on every interactive element (keyboard-only users must never wonder where they are).
- All risk semantics paired with text labels (color is never the only signal).
- All custom controls have proper ARIA roles and labels.
- All images have alt text (or `aria-hidden` if decorative).
- Color contrast ratios documented (see § 5).
- `prefers-reduced-motion` respected on every animation.
- Tab order matches visual order on every screen.
- All forms support browser autofill.

---

## 14. Versioning and ownership

| | |
|---|---|
| Document version | 1.0 |
| Effective | 2026-05-07 |
| Theme | Indigo Pulse (default / dark) |
| Light theme | Forward — tokens defined, not yet implemented |
| Document owner | Founder |
| Review cycle | Quarterly, or on any brand-affecting decision |
| Next review | 2026-08-07 |

When the brand evolves, version the document (1.1, 1.2, 2.0) and link from the new version to the old. Don't overwrite history.
