# TRUE style guide: content spec

This is the contract between the token file and the style guide site. It says what each
value is, and more importantly when to use it and when not to.

**Status of every claim below.** Values marked with a file path were read out of that file.
Values marked NEW are decisions this spec makes because the code has no answer, and they say
so explicitly. Nothing here was guessed.

**Sources, in priority order.**

1. `TRUE-Website/master/public/assets/.../true-original.webflow.shared.c43aefb38.min.css`
   The compiled Webflow stylesheet. Everything trueoriginal.com renders comes from here.
   Referred to below as **the stylesheet**.
2. `TRUE-Website/master/src/lib/resources-style.ts` The hand written `/resources/` system,
   roughly 70 live pages. Referred to as **resources**.
3. `TRUE-Website/master/src/lib/insights.ts`, `chrome.ts`, `shell.ts` Blog feed styles,
   header and footer markup, the shared `<head>`.
4. `design-references/sign-redesign.html` The product page mockup Victor named. Referred to
   as **the mockup**.
5. `TRUE-Verify/develop/src/frontend/styles/_variables.scss`,
   `TRUE-Sign/master/apps/dash/tailwind.config.ts`,
   `TRUE-Vault/master/apps/dash/tailwind.config.ts` Product token sets.

Where the website and a product disagree, the website wins. Where the website contradicts
itself, this spec picks one and says why.

**Machine readable form:** `tokens/true-tokens.json`.
**Generated artifacts:** `tokens/` (`node generators/build.mjs`).

---

## Contents

1. [The frozen CSS contract](#1-the-frozen-css-contract)
2. [Gradient](#2-gradient)
3. [Colour](#3-colour)
4. [Fonts and sizes](#4-fonts-and-sizes)
5. [Titles and how titles are written](#5-titles-and-how-titles-are-written)
6. [Preambles](#6-preambles)
7. [Paragraphs](#7-paragraphs)
8. [Buttons](#8-buttons)
9. [Links](#9-links)
10. [Icons](#10-icons)
11. [Logo usage and clear space](#11-logo-usage-and-clear-space)
12. [Spacing and the layout grid](#12-spacing-and-the-layout-grid)
13. [Radius](#13-radius)
14. [Shadows and elevation](#14-shadows-and-elevation)
15. [Boxes: cards and panels](#15-boxes-cards-and-panels)
16. [Hero](#16-hero)
17. [Headers and navigation](#17-headers-and-navigation)
18. [Footer](#18-footer)
19. [Forms and inputs](#19-forms-and-inputs)
20. [Badges and pills](#20-badges-and-pills)
21. [Tables](#21-tables)
22. [Lists](#22-lists)
23. [Alerts and toasts](#23-alerts-and-toasts)
24. [Empty states](#24-empty-states)
25. [Loading and skeletons](#25-loading-and-skeletons)
26. [Dark sections](#26-dark-sections)
27. [Imagery and blog header rules](#27-imagery-and-blog-header-rules)
28. [Animations and motion tokens](#28-animations-and-motion-tokens)
29. [Focus and WCAG AA](#29-focus-and-wcag-aa)
30. [PRODUCT PAGE recipe](#30-product-page-recipe)
31. [Do and do not](#31-do-and-do-not)

---

## 1. The frozen CSS contract

Ten custom property names. The style guide site and every TRUE product code against these
exact spellings. **Never rename or remove one.** Adding new names is always fine.

```css
--true-blue:        #7dcade;
--true-pink:        #d82a80;
--true-gradient:    linear-gradient(90deg, #7dcade, #d82a80);
--true-dark:        #1c1c1e;
--true-gray:        #636366;
--true-surface:     #f8f8fb;
--true-border:      #e5e5ea;
--font-display-sc:  'Marcellus SC', Georgia, serif;
--font-display:     'Marcellus', Georgia, serif;
--font-body:        'Helvetica Neue Updated', 'Helvetica Neue', Helvetica, Arial, sans-serif;
```

Everything else in `tokens/true-tokens.css` is named `--true-<group>-<name>`, for
example `--true-radius-lg`, `--true-space-160`, `--true-color-alpha-white-16`. The generator
throws if any of the ten above goes missing, so the contract cannot break silently.

Two of the three font stacks are deliberately **corrected** against production. See
[Fonts and sizes](#4-fonts-and-sizes).

---

## 2. Gradient

There is one TRUE gradient. It has two stops and no midpoint.

```css
linear-gradient(90deg, #7dcade, #d82a80)
```

**Where it comes from.** The stylesheet defines exactly two CSS custom properties in the
entire 208 KB file: `:root{--gradient-blue:#7dcade;--gradient-pink:#d82a80}`. The gradient
string itself appears on twelve selectors: `.ben-6`, `.industries-cta`, `.contact-hero`,
`.hero-thankyou`, `.cta`, `.cta-s` with literal hex, and `.hero.main` plus five
`.hero---*.main` variants through the variables.

**Rules.**

* Always 90deg. Blue on the left, pink on the right. There is no vertical brand gradient
  and no reversed one.
* Use it as a **background**, at full bleed or on a 16px radius panel. Never as a border
  fill except through the two documented tricks below.
* Never put body copy directly on it at 16px. The gradient runs from a very light blue to a
  mid pink, so text contrast changes across the width and there is no single text colour
  that works. Headings in white at 40px and above are fine, which is exactly what `.cta` and
  `.ben-6` do.
* Never introduce a third stop, a midpoint or an opacity ramp on it.

**The four sanctioned variations.**

| Variation | Value | Where it is real |
|---|---|---|
| Gradient text | the gradient plus `background-clip: text; color: transparent` | The mockup, `.grad`. NEW on the website. |
| Top strip | the gradient at `height: 6px`, full bleed | The mockup, `.topstrip`. NEW on the website. |
| Gradient border | 2px padded gradient parent with an ink filled child at the same radius | `insights.ts .feed-load-more-btn` |
| Gradient rule | `height: 2px; width: 64px; border-radius: 2px` | `resources-style.ts .res-rule` |

The mockup also reaches a gradient top rule with `border-top: 6px solid transparent` plus
`border-image: linear-gradient(90deg, ...) 1` on `.ctab`. Both techniques are acceptable.
Prefer the padded parent when the element needs a background of its own.

**Gradient text needs a fallback.** `background-clip: text` with `color: transparent` renders
invisible text if the background fails to paint. Always ship the `-webkit-` prefix, and set a
solid `color` before the clip so the cascade has something to fall back to:

```css
.accent { color: #d82a80; background: var(--true-gradient);
          -webkit-background-clip: text; background-clip: text; color: transparent; }
```

**Not the brand gradient.** These exist in the stylesheet and are not interchangeable with it:
`linear-gradient(180deg, #7dcade, white)` (one rule), the hero scrim
`linear-gradient(#0006, #0006)`, the card scrim `linear-gradient(#0000 50%, #0000007a)`, and
the ticker mask `linear-gradient(90deg, #0000, #000 10% 90%, #0000)`.

**Product page hero wash.** The mockup's hero is not the brand gradient. It is two soft
radial washes over the light surface:

```css
background:
  radial-gradient(1100px 480px at 85% 10%, rgba(125,202,222,.24), transparent 60%),
  radial-gradient(700px 420px at 100% 85%, rgba(216,42,128,.10), transparent 60%),
  #f8f8fb;
```

This is the canonical product page hero background. See [PRODUCT PAGE](#30-product-page-recipe).

---

## 3. Colour

### Core

| Token | Value | Uses in the stylesheet | What it is |
|---|---|---|---|
| `--true-blue` | `#7dcade` | 13 | Gradient stop. Focus ring on dark. Never a fill on the website. |
| `--true-pink` | `#d82a80` | 13 | Gradient stop. Link hover and accent dot on product pages. |
| `--true-dark` | `#1c1c1e` | 156 | Ink. Text on light, dark section background, dark button fill. |
| `--true-gray` | `#636366` | 28 | Secondary body text on light. |
| `--true-surface` | `#f8f8fb` | 16 | The one light surface. Cards, FAQ, footer, light inputs. |
| `--true-border` | `#e5e5ea` | 36 | The one hairline. Always 1px. |
| white | `#ffffff` | 187 | |
| black | `#000000` | 26 | Scrims and rules only. Never text. |

**Body copy is `#636366`, not the ink.** `.body-text` sets `color:#636366`. The ink `#1c1c1e`
is for headings, for RTE body, and for text that has to carry weight. Getting this backwards
is the single most common way a TRUE page looks slightly wrong.

### The white on dark ladder

This is the load bearing part of the palette. Glass fills, borders on dark and placeholder
text are all built from it. Every step is verified in the stylesheet.

| Step | Value | Uses | Job |
|---|---|---|---|
| 0.08, 0.10, 0.15 | | 1 each | Incidental. Do not reach for these. |
| **0.16** | `rgba(255,255,255,0.16)` | 12 | **Glass panel fill. Every dark input fill.** |
| **0.24** | `rgba(255,255,255,0.24)` | 1 | **Glass badge fill.** Paired with `blur(16px)`. |
| 0.45 | | 2 | Incidental. |
| **0.40** | `rgba(255,255,255,0.4)` | 6 | **The default border on dark.** |
| 0.48 | `rgba(255,255,255,0.48)` | 1 | `.button-secondary` only. Not the default. |
| **0.56** | `rgba(255,255,255,0.56)` | 8 | **Placeholder text inside dark inputs.** |
| 0.64, 0.92 | | 1 each | Incidental. |
| **0.80** | `rgba(255,255,255,0.8)` | 13 | **Secondary text on dark.** |

The five bold rows are the ladder. Use those. The current style guide documents 0.48 as the
border on dark, which is one rule; the real answer is 0.40, which is six.

On light, the mirror of the 0.40 border is `rgba(28,28,30,0.4)`, from `.button.light`.

### Black scrims

`rgba(0,0,0,0.4)` over a hero photograph (31 uses, expressed as a flat two stop gradient so
it can layer above the image). `rgba(0,0,0,0.6)` where the photograph is busier.
`rgba(0,0,0,0.48)` for the bottom up fade on a photo card. `rgba(0,0,0,0.2)` is the alpha
inside every real drop shadow.

### Semantic

The website defines exactly one semantic colour: `#1ca800`, as the `.yes` badge outline and
text. **There is no TRUE warning colour and no TRUE error colour.** TRUE Verify invents
`#f59e0b` and `#ef4444`; TRUE Vault invents a yellow ramp and `#DC2626`. None of them trace
to anything. Both are recorded as `TODO` in the token file. Picking them is a design
decision, not an extraction, and it should be made once and centrally.

### Colours that exist but are not brand

`#2d2d2f` is the light navbar text variant (9 rules). `#a1a1a1` is the footer micro link
(3 rules, and it fails contrast, see [WCAG](#29-focus-and-wcag-aa)). `#470505` is the
oxblood that sits behind the hero photograph while it loads and is never visible in a
finished render. `#0050bd` is the focus ring.

`#1a1b1f`, `#32343a`, `#43464d`, `#3898ec`, `#e4ebf3`, `#333` and a run of neutral greys are
Webflow starter theme leftovers. They render on live pages. Do not use them. The token file
marks them `legacy` and the generators do not emit them.

---

## 4. Fonts and sizes

### The three families

```css
--font-display-sc: 'Marcellus SC', Georgia, serif;   /* 10 rules */
--font-display:    'Marcellus', Georgia, serif;      /* 22 rules */
--font-body:       'Helvetica Neue Updated', 'Helvetica Neue', Helvetica, Arial, sans-serif;
                                                     /* 166 rules, the most common in the file */
```

**All three are corrected against what production ships, and the corrections matter.**

* Production writes `Marcellus,Georgia,sans-serif` and `Marcellus SC,Georgia,sans-serif`.
  Georgia is a serif; ending the stack with `sans-serif` means that if Georgia is also
  missing the browser picks the wrong class of face entirely. Corrected to `serif`.
* Production writes `Helvetica Neue Updated,Impact,sans-serif`. Impact is a heavy condensed
  display face with nothing in common with Helvetica Neue. **If the webfont fails to load,
  every paragraph on trueoriginal.com renders in Impact.** This is a website defect, not a
  style guide preference. Corrected to a Helvetica chain. Recorded in DRIFT.md.

TRUE Verify and TRUE Vault already have the serif fallback right where production has it
wrong. They were correct and the website is wrong.

### Font loading

The brand faces are served from `https://www.trueoriginal.com/assets/...`, from the site's
own origin, not from a CDN and not from Google Fonts. `tokens/true-tokens.css` emits
the four `@font-face` rules with absolute URLs so a product on another domain can use them.
Self host if you can: rewrite the `url()` and keep everything else.

| Face | Weight | Format |
|---|---|---|
| Marcellus | 400 | truetype |
| Marcellus SC | 400 | truetype |
| Helvetica Neue Updated | 400 (Roman) | opentype |
| Helvetica Neue Updated | 500 (Medium) | opentype |

**Only 400 and 500 exist in the canonical body family.** Do not write `font-weight: 700`
against it: the browser will synthesise a fake bold. Where a design says bold, use 500.

Two families in production must not be copied. `Helveticaneue` (34 rules) is the older body
face; it is the only family with Light, Thin and Bold, and it should be migrated away.
`Helveticaneue Roman` (16 rules) **has no `@font-face` behind it anywhere and no generic
fallback after it**, so all 16 rules render in the browser default. It must be deleted from
the website, not tokenised.

Every page loads ten weights of **Lato** from Google Fonts (`shell.ts`, `WebFont.load`) and
exactly one CSS rule uses it. That is the largest piece of dead weight in the font loading
path. New TRUE work must not use Lato.

Mono, where you need it: `'SF Mono', ui-monospace, Menlo, Consolas, monospace`
(`resources-style.ts .res-code`).

### The size scale

Every step below is a literal `font-size` in the stylesheet, with its occurrence count. This
is not a ratio scale. It is what the site actually uses.

| px | Uses | Line height | Role |
|---|---|---|---|
| 10 | 1 | | Incidental. |
| **12** | 13 | 18px | Micro copy, footer links, eyebrows. |
| **14** | 27 | 24px | Small copy, nav links, **all blog and RTE body**. |
| 15 | 5 | | Incidental. |
| **16** | 88 | 24px | **The base.** Body copy, buttons, inputs. |
| 17, 18 | 1, 5 | | Incidental. |
| **20** | 11 | 28px | Smallest heading. Blog card titles. |
| 21, 22 | 1 each | | Incidental. |
| **24** | 28 | 32px | Sub headings. |
| **32** | 40 | 40px | Section headings. |
| 36 | 4 | | Incidental on the website. The mockup's `h2`. |
| 38 | 2 | 44px | Webflow reset `h1`. Not a TRUE size. |
| **40** | 25 | 48px | **The step the current guide omits entirely.** RTE `h1`, so it is the top heading of every blog post. |
| **48** | 16 | 56px | **The page heading.** |
| 56 | 3 | | Incidental. |
| **72** | 2 | 72px | Hero, centred variant, set solid. |
| **6vh** | 1 | 6vh | **Hero, left aligned variant.** Viewport relative, not 72px. |

**The hero is not always 72px.** `.heading-hero` is `font-size:6vh;line-height:6vh`. At a
1080px tall viewport that is 64.8px; at 800px it is 48px. Only `.heading` and
`.heading-hero-center` are fixed at 72px.

Line heights are written in pixels, not ratios: 18, 20, 24, 28, 32, 40, 48, 56, 72.

### The real type roles

| Role | Family | Size / line | Weight | Selector |
|---|---|---|---|---|
| Hero, centred | Marcellus SC | 72 / 72 | 400 | `.heading`, `.heading-hero-center` |
| Hero, left | Marcellus SC | 6vh / 6vh | 400 | `.heading-hero` |
| Page heading | Marcellus | 48 / 56 | 400 | `.heading-3`, `.heading-1`, `.heading-8`, `.heading-pains`, `.heading-blog`, `.edu-headline` |
| Stat heading | Marcellus SC | 48 / 48 | 400 | `.heading-2` |
| Article heading | Marcellus | 40 / 48 | 400 | `.rte h1`, `.heading-14` |
| Section heading | Marcellus | 32 / 40 | 400 | `.heading-19`, `.heading-35` |
| Sub heading | Marcellus | 24 / 32 | 400 | `.heading-10`, `.heading-21`, `.heading-37` |
| Card title | body | 20 / 28 | 500 | `.heading-23` |
| Body | body | 16 / 24 | 400 | `.body-text`, colour `#636366` |
| RTE body | body | 14 / 24 | 400 | `.rte`, colour `#1c1c1e`, `margin: 80px 10%` |
| Micro | body | 12 | 400 | `.text-block-12`, `.link-7`, colour `#a1a1a1` |

Note the two body rows. `.body-text` is 16px in `#636366`; `.rte` is 14px in `#1c1c1e`. They
are opposites on both counts, and both are correct in their context.

At 24/32 the body face is the majority: only 3 of the 20 rules at that size are Marcellus.
Choosing Marcellus at 24px is a deliberate act, not the default.

### What an unstyled tag looks like

This is undocumented everywhere and it is why a bare `<h2>` on a TRUE page looks nothing like
a TRUE heading. The Webflow reset gives:

```
body   Arial 14/20, colour #333
h1     38/44 weight 700      h4  18/24 weight 700
h2     32/36 weight 700      h5  14/20 weight 700
h3     24/30 weight 700      h6  12/18 weight 700
```

Bold Arial, not regular Marcellus. **Every heading on a TRUE page must carry a class.** A new
product should ship a reset that maps bare `h1` to `h6` onto the type roles above so this
trap disappears.

---

## 5. Titles and how titles are written

### Which face

* **Marcellus SC** (small caps) is for the hero and for stat numbers. Nothing else. It is
  the loudest thing in the system and it appears once per page at most.
* **Marcellus** is for every other heading: page heading, article heading, section heading,
  sub heading.
* **The body face** is for anything called a heading below 24px, for example a card title at
  20/28 weight 500. A 20px Marcellus heading is not part of the system.

### Case

**Sentence case everywhere.** Capitalise the first word and proper nouns. Nothing else.

Verified against the real copy in `chrome.ts` and the mockup: "How it works", "Case Studies",
"Signed and sealed in three steps", "Made for the documents that matter", "Proof you can hand
to a lawyer." The two exceptions in the nav ("Case Studies", "Product certification" versus
"Media & Awards") are inconsistencies in the live site, not a rule.

Title Case is used in exactly two places and both are labels rather than titles:

* The eyebrow / small caps label, which is `text-transform: uppercase` with `0.08em`
  tracking (`resources-style.ts .res-eyebrow`, mockup `.trust-lbl` and `.f-col h5`).
* The step number, `STEP 1`, uppercase with `0.1em` tracking (mockup `.step-n`).

Never use Title Case for a sentence length heading. Never use ALL CAPS for anything longer
than three words.

### Punctuation

* A full stop at the end of a heading is permitted and is used deliberately in the mockup
  for the strongest statements: "Signatures that prove themselves." and "Proof you can hand
  to a lawyer." Use it when the heading is a complete assertion.
* No full stop on a label style heading: "Signed and sealed in three steps".
* Never a colon in a heading. Never an exclamation mark. Never a question mark unless the
  heading genuinely is a question, which on a TRUE page it usually is not.
* **No hyphens, en dashes or em dashes as punctuation anywhere in TRUE prose.** Rewrite with
  a full stop, a comma, a colon or parentheses. This applies to headings, body copy, button
  labels and microcopy. Hyphens inside a real compound word are fine.

### The gradient accent word

The product page hero puts **one word** of the `h1` in the brand gradient (mockup, `.grad`:
"Signatures that **prove** themselves.").

* **One word. Two at the absolute limit, and only if they are a single idea.** Never three.
* It must be the word carrying the promise: a verb or the noun the product is about. Never
  an article, a preposition or a filler word.
* Only in an `h1`, and only once per page. Never in an `h2`, never in body copy, never in a
  button.
* Never on a dark or gradient background: gradient text on the brand gradient is invisible.
  The accent word belongs on the light hero wash.

### Length

| Element | Target | Hard limit | Why |
|---|---|---|---|
| Hero `h1` | 3 to 6 words | 8 words | `.heading-hero` is `max-width: 800px`; resources caps its hero at `16ch` per line. |
| Page heading | up to 10 words | 12 words | `.heading-3` is `width: 520px`; `.heading-8` is 910px. |
| Section heading | up to 8 words | 10 words | The mockup's `.sect-head` is `max-width: 640px`. Resources caps at `24ch`. |
| Sub heading, card title | 2 to 5 words | 7 words | |
| Eyebrow | 2 to 6 words | 8 words | It is a label, not a sentence. |
| Button label | 2 to 4 words | 5 words | "Start signing free", "See how it works". |

The mockup breaks a two line heading with an explicit `<br>` rather than relying on the
measure ("Everything a signature needs.<br>Nothing it does not."). Do that when the break
point carries meaning. Otherwise let `max-width` do the work.

### Voice

Short declaratives. Say what the thing does, not what it enables. Prefer the concrete noun:
"Certificate of Completion", "document hash", "audit trail". The mockup's headings are the
reference register.

---

## 6. Preambles

A preamble is the paragraph that sits directly under a heading and sets up the section. TRUE
uses three, and they are not interchangeable.

**1. The hero kicker.** A pill above the `h1`, opened by a coloured dot.

```css
.kicker { display: inline-flex; align-items: center; gap: 8px;
          background: #fff; border: 1px solid #e5e5ea; border-radius: 999px;
          padding: 7px 14px; font-size: 12.5px; color: #636366; margin-bottom: 22px; }
.kicker i { width: 7px; height: 7px; border-radius: 50%; background: #d82a80; }
```

Source: the mockup, `.kicker`. Rules: one line, no wrap, 2 to 6 words plus a qualifier. It
states who you are or what category you are in ("By TRUE Original, the document verification
company"). It is never a benefit claim and never a call to action.

**2. The hero sub.** The paragraph under the hero `h1`.

```css
font-size: 18px; line-height: 1.55; color: #636366; max-width: 520px; margin-bottom: 30px;
```

Source: the mockup, `.hero p.sub`. Two sentences maximum. The first says what the product
does end to end; the second says what you get out of it. Both concrete.

**3. The section intro.** The paragraph under a centred section heading.

```css
.sect-head { text-align: center; max-width: 640px; margin: 0 auto 52px; }
.sect-head p { color: #636366; font-size: 16.5px; line-height: 1.55; }
```

Source: the mockup, `.sect-head`. One or two sentences. It answers "why this section" and
then gets out of the way.

**The eyebrow** is a fourth, shorter form used by the resources system rather than the
mockup: Marcellus SC, uppercase, 13px, `letter-spacing: 0.08em`, `opacity: 0.72`,
`margin-bottom: 14px` (`resources-style.ts .res-eyebrow`). Use it where a kicker pill would
be too heavy, for example above an interior section heading.

Never stack a kicker and an eyebrow. Pick one.

---

## 7. Paragraphs

| Context | Size / line | Colour | Source |
|---|---|---|---|
| Marketing body | 16 / 24 | `#636366` | `.body-text` |
| Blog and RTE body | 14 / 24 | `#1c1c1e` | `.rte` |
| Resources prose | 18px / 1.65 | `#1c1c1e` | `resources-style.ts .res-prose` |
| Product page card copy | 13.5 to 14px / 1.55 | `#636366` | mockup `.feat p`, `.step p` |
| Dark section lead | 16px / 1.6 | `rgba(255,255,255,0.8)` | mockup `.sec p.lead` |

**Measure.** RTE body uses `margin: 80px 10%`, which leaves 80% of the parent, not 70%. It
drops to a flat 40px margin below 991px and 16px below 479px. For anything new, cap the
measure at `max-width: 640px` (the mockup's `.sect-head`) or `520px` (the hero sub) rather
than using a percentage.

**Spacing between paragraphs.** The website leaves this to the Webflow reset,
`p { margin-bottom: 10px }`, which is too tight. Resources uses `margin-top: 14px` between
prose blocks. Use 14px for tight copy and 16px for a comfortable article. NEW: neither the
stylesheet nor resources sets a paragraph rhythm larger than that, so anything roomier is a
new decision.

**Do not** centre a paragraph longer than two lines. The centred treatment belongs to the
section intro block, which is capped at 640px for exactly that reason.

**Emphasis inside a paragraph** is weight 500, not 700, because 700 does not exist in the
canonical body family. The mockup uses `b { font-weight: 500 }` throughout, which is the
correct pattern.

---

## 8. Buttons

The stylesheet has nine button classes and they do not agree with each other. Below is what
exists, then what to use.

### What exists on the website

| Class | Fill | Border | Radius | Padding | Type |
|---|---|---|---|---|---|
| `.button` | transparent | `1px rgba(255,255,255,0.4)` | 12px | `8px 16px` | body 16/24 |
| `.button.light` | transparent, text `#000` | `1px rgba(28,28,30,0.4)` | 12px | `8px 16px` | |
| `.button-2` | transparent, text `#fff` | `1px rgba(229,229,234,0.4)` | 12px | `12px 20px` | body 16/24 |
| `.button-2.light` | `#1c1c1e`, text `#fff` | | 12px | `12px 20px` | `width: 328px` |
| `.button-secondary` | transparent | `1px rgba(255,255,255,0.48)` | 12px | `12px 24px` | body 16/24 |
| `.button-4`, `.button-6` | `#1c1c1e` | `1px rgba(28,28,30,0.4)` | **16px** | `16px 0` | `Helveticaneue` 24/32 |
| `.button-3` | | | **80px** | | `64 x 64`, a circle |
| `.button-primary` | `#1a1b1f`, uppercase, `letter-spacing: 2px` | | | `12px 25px` | **Webflow starter. Not TRUE.** |

So: the radius is 12px for most, 16px for two, 80px for the circle. The padding is
`8px 16px`, `12px 20px`, `12px 24px` and `16px 0` depending on which class you land on.
The current style guide documents `12px 24px` as the button padding, which matches exactly
one class.

### What to use

**Two buttons. A pair. Filled leads, ghost follows.** This is the mockup's pattern and it is
the standard TRUE CTA.

```css
.btn      { display: inline-block; border-radius: 12px; padding: 12px 24px;
            font: 400 16px/24px var(--font-body); text-decoration: none;
            border: 1px solid transparent; cursor: pointer;
            transition: background .2s ease, color .2s ease, border-color .2s ease; }

/* primary, on light */
.btn-solid { background: #1c1c1e; color: #fff; border-color: #1c1c1e; }

/* secondary, on light */
.btn-ghost { background: transparent; color: #1c1c1e; border-color: rgba(28,28,30,.4); }
.btn-ghost:hover { border-color: #1c1c1e; }

/* on dark, invert */
.btn-solid-dark { background: #fff; color: #1c1c1e; border-color: rgba(229,229,234,.4); }
.btn-ghost-dark { background: transparent; color: #fff; border-color: rgba(255,255,255,.4); }

/* larger, hero only */
.btn-lg { padding: 16px 32px; }
```

Radius **12px**. Padding **12px 24px**, or **16px 32px** in a hero. Type is the body face at
16/24 weight 400. Border is always 1px.

**The pill button** is the other real shape, from `insights.ts` and `resources-style.ts`:
`border-radius: 999px`, padding `14px 40px` (feed) or `14px 22px` (resources). Use it for a
single standalone action such as Load More, never as one half of a CTA pair.

**Hover.** The stylesheet has no TRUE dark button hover. `#32343a` appears once, on
`.button-primary:hover`, which is a Webflow starter class nothing uses. The mockup copied
that value into `.btn-pink:hover`, so it now exists in two places without ever having been
decided. Until it is, use what the hand written code does:

* Ghost button: darken the border to full ink. `.btn-ghost:hover { border-color: #1c1c1e }`
  (the mockup).
* Filled button: `opacity: .85` (`insights.ts`) or `transform: translateY(-1px)`
  (`resources-style.ts`). Do not use both.
* Card sized targets: `translateY(-3px)` plus `box-shadow: 0 14px 30px rgba(28,28,30,.12)`
  (the mockup, `.case:hover`).

**Never.** Uppercase button labels. Letter spacing on a button. A gradient filled button
(the gradient is a background, and text on it is unreliable). More than two buttons in a
CTA group. A button label longer than five words.

---

## 9. Links

**Inline in prose, light background.** Underlined, pink. `resources-style.ts`:
`color: #d82a80; text-decoration: underline`. Pink on white measures roughly 4.6:1, which
clears AA for normal text with almost nothing to spare, so do not reduce its size or weight.

**Inline in prose, dark section.** Brand blue, still underlined
(`resources-style.ts .res-section--dark .res-prose a { color: #7dcade }`). Blue on ink is
roughly 9.2:1.

**Standalone link with an arrow.** The product page pattern (mockup, `.alink`): ink text,
`border-bottom: 1px solid` in the same colour, and a trailing `→`. Both the text and the
border turn pink on hover. Use `border-bottom` rather than `text-decoration` so the
underline offset stays even.

**Nav link.** 14/20, `letter-spacing: 0.25px`. Hover turns pink on a product page (the
mockup); the website currently fades to `rgba(26,27,31,0.75)`, which is a Webflow leftover.
Use pink.

**Footer micro link.** 12px, `#a1a1a1`. This fails contrast. See [WCAG](#29-focus-and-wcag-aa).

Never use brand blue for a link on white: it measures roughly 1.85:1 and is unreadable.

---

## 10. Icons

**The website has no icon system.** It ships fixed size `<img>` elements. The mockup
introduces the first real pattern and it is the one to adopt: **one inline SVG `<symbol>` in
a hidden `<svg>` at the top of the document, referenced everywhere with `<use href="#id">`.**
That gives one download, `currentColor` or an explicit `fill`, and no icon font.

### Sizes

| Token | Size | Where |
|---|---|---|
| `xs` | 16px | `.icon-2`; the mockup's phone header mark |
| `glyph` | 20px | The glyph inside a 42px feature tile |
| `sm` | 24px | `.image-8`, `.icon-6` |
| `md` | 26px | The mockup's inline icons, `.cert-head` |
| `lockup` | 30px | The TRUE mark in the product header lockup |
| `lg` | 32px | `.image-19`, `.image-20` |
| `xl` | 48px | `.image-10`, `.image-13` |

Small round marks: `tick` 15px and `dot` 7px, both `border-radius: 50%`. The footer link
separator is a 2px dot in `#a1a1a1`.

### The feature icon tile

```css
.ic { width: 42px; height: 42px; border-radius: 12px; background: #eaf6fa;
      display: flex; align-items: center; justify-content: center; margin-bottom: 16px; }
.ic svg { width: 20px; height: 20px; fill: #1c1c1e; }
```

Source: the mockup, `.feat .ic`. A soft blue square with an ink glyph. `#eaf6fa` is the
mockup's `--blue-soft`, a tint of the brand blue. It is not in the website stylesheet, so it
is NEW: it enters the system through the mockup and the token file records it as such.

### Rules

* Icons are **ink** (`#1c1c1e`) or **white** on dark. Never pink, never blue, never a
  gradient. The one exception is a tick inside a coloured circle, where the circle carries
  the colour and the tick stays white.
* Never scale an icon between the sizes above. Pick a step.
* An icon next to text sits on the text baseline box with a `gap`, never with a margin
  hack. The mockup uses `gap: 7px` to `gap: 13px` depending on size.
* Decorative icons get `aria-hidden="true"`. An icon that is the only content of a control
  gets an `aria-label` on the control.

---

## 11. Logo usage and clear space

The wordmark ships as two SVGs, white and black, both `100 x 32` in the navbar
(`chrome.ts`, `.logo-w` and `.logo-b`). The light and dark header variants swap which one is
visible by toggling opacity, so the mark never reflows.

| Placement | Size | Source |
|---|---|---|
| Navbar | 100 x 32 | `.logo-w`, `.logo-b` |
| Footer | 110 x 32 | `.image-23` |
| Partner and accreditation strip | 160 x 40 | `.image-6` |

**Clear space.** The only clear space value expressed anywhere in the code is
`margin-right: 12px` on the navbar mark, the gap before the vertical rule that follows it.
The mockup's lockup uses `gap: 10px`. **Use 12px minimum on all four sides, and scale it with
the mark: 12px at 32px tall means roughly 0.375 times the mark height.** The 12px figure is
extracted; expressing it as a ratio is NEW.

**The product lockup.** Every TRUE product header uses the same construction (the mockup,
`.lockup`):

```html
<a class="lockup" href="/"><svg><use href="#true-mark"/></svg><b>TRUE</b><span>Sign</span></a>
```

```css
.lockup      { display: flex; align-items: center; gap: 10px;
               text-decoration: none; color: #1c1c1e; }
.lockup svg  { width: 30px; height: 30px; }
.lockup b    { font-family: var(--font-display); font-weight: 400;
               font-size: 20px; letter-spacing: .02em; }
.lockup span { font-family: var(--font-display); font-size: 20px; color: #636366; }
```

Mark, then **TRUE** in Marcellus at full ink, then the product word in the same face at
`#636366`. The product word is never bold, never coloured, never in the body face. Swap both
to white on a dark header.

**Never.** Recolour the mark. Put it on the brand gradient (there is no gradient safe
lockup). Stretch it. Add a drop shadow. Set the product word in a different family from
TRUE. Write "TrueSign" or "True Sign": it is **TRUE Sign**, with TRUE in caps and a space.

---

## 12. Spacing and the layout grid

**Production does not use a clean 8px scale.** These are the literal values with occurrence
counts, and 12, 40, 64, 88, 104 and 200 are all in constant use while being absent from
every existing product token set.

| Value | Uses | Job |
|---|---|---|
| 8px | 23 | Navbar padding. Navbar offset from the viewport top. |
| 12px | 14 | Vertical button padding. |
| 16px | 10 | Horizontal button padding. Input horizontal padding. |
| 20px | 5 | `.button-2` horizontal padding. |
| 24px | 25 | Glass panel padding and gap. Wide button padding. |
| 32px | 16 | FAQ padding and gap. |
| 40px | 5 | **The real page side gutter on wide sections.** |
| **48px** | **27** | **THE panel padding.** Every card, CTA, footer and dark panel. |
| 64px | 1 | `.cta-s` top margin. |
| 80px | 8 | RTE top margin. Hero heading bottom margin. |
| 88px | 1 | Hero side padding. |
| 104px | 1 + resources | Agreed independently by the stylesheet and resources. |
| 120px | 12 | The gap above the footer. |
| **160px** | **16** | **THE section rhythm.** |
| 200px | 8 | Hero top padding, which is what clears the fixed navbar. |

**If you take two numbers from this document, take 48px and 160px.** 48px is the padding of
every box. 160px is the space between every section.

The website expresses section rhythm as `margin-top: 160px`, not as padding. The two hand
written systems use symmetric padding instead: resources `padding: 96px 0` (72px below
991px, 56px below 479px), the mockup `padding: 84px 0`. **For new work use symmetric padding
at 84px**, matching the mockup, because a top margin collapses unpredictably against a
neighbouring section and padding does not.

### Containers

There is no single canonical container on trueoriginal.com. Six ship.

| Container | Width | Gutter | Where |
|---|---|---|---|
| **product** | **1180px** | **0 28px** | **The mockup. Use this for a TRUE product page.** |
| resources | 1160px | 0 28px | `resources-style.ts`, roughly 70 live pages |
| Webflow default | 940px | | `.w-container`, `.container`, `.container-2`, `.container-9` (drops to 728px below 991px) |
| 12 column grid | 1440px | 0 4em | `.container-3` to `.container-6`, `gap 1.5em / 4em`, collapses to one column below 991px |
| wide | 1420px | 0 40px | `.section-19` |
| narrow | 1200px | | `.section-14`, `.section-17` |
| navbar | 1000px fixed | 8px | `.div-block` inside `.nav-wrapper` |

`1360px` appears once, on `.ben-1`, a single panel. The current style guide calls it the page
container and TRUE Verify adopts it as `$container-max`. It is neither.

**The only real grid** is the 12 column one on `.container-3` to `.container-6`:
`max-width: 1440px`, `padding: 0 4em`, `grid-column-gap: 1.5em`, `grid-row-gap: 4em`,
collapsing to a single column at 991px with 1.5em gutters. Everything else on the site is
flexbox.

For a product page, use flex and simple `repeat(3, 1fr)` grids with a 22px gap, as the
mockup does. A 12 column grid is not required and the site barely uses one.

### Breakpoints

`991px`, `767px`, `479px`, all `max-width`. Those three are what the site is authored
against. Below 991px the grids collapse and containers drop from 940px to 728px.

The current style guide's own CSS breaks at 768px, which matches nothing. The mockup breaks
at 960px, which also matches nothing. **Use 991px.** A product that breaks at 960px will
disagree with the shared navbar and footer by 31px of viewport.

---

## 13. Radius

The current guide documents four values. Production ships fourteen.

| Token | Value | Uses | Job |
|---|---|---|---|
| `none` | 0 | 6 | |
| `sm` | 4px | 9 | Focus ring rounding on nav links. |
| `yes` | 7px | 3 | The `.yes` success badge. An orphan value. |
| **`input`** | **8px** | **62** | **Every input. Glass badge. Glass panel. Photo cards.** |
| **`md`** | **12px** | **13** | **Buttons. Nav dropdown. Icon tiles.** |
| `image` | 13px | 1 | Orphan. |
| **`lg`** | **16px** | **99** | **Cards, panels, CTAs, navbar, footer. Anything bigger than a button.** |
| `xl`, `xxl` | 24px, 32px | 1 each | Orphans. |
| `circleButton` | 80px | 6 | On a 64 x 64 button this is a circle, not a pill. |
| **`pill`** | **999px** | hand written only | **Chips, pill buttons, the hero kicker.** |
| `circle` | 50% | 3 + | Dots, ticks, avatars, step numbers. |

**Three values do the work: 8px, 12px, 16px.**

* 8px: inputs, glass, small photo cards.
* 12px: buttons, dropdowns, icon tiles.
* 16px: everything larger than a button.

**Inputs are 8px, not 12px.** Every `.text-field` in production is `border-radius: 8px`. The
current style guide says "12px for buttons and inputs" in one place and correctly says 8px
for inputs 150 lines later, contradicting itself.

**The pill is 999px, not 80px.** 999px exists only in hand written TRUE code
(`insights.ts`, `resources-style.ts`, the mockup), which is why the current guide missed it.
80px is what `.button-3` uses to make a 64px square into a circle; on a wide element it does
not produce a pill.

---

## 14. Shadows and elevation

**There are five real box shadows in the entire stylesheet.** Not five categories. Five
declarations.

| Token | Value | Where |
|---|---|---|
| `card` | `0 2px 5px rgba(0,0,0,0.2)` | `.features`, `.connections-grid` |
| `dropdown` | `0 8px 50px rgba(0,0,0,0.05)` | `.nav-dropdown-list.shadow-three` |
| `soft` | `0 4px 24px rgba(150,163,181,0.078)` | `.shadow-two` |
| `video` | `0 4px 12px rgba(0,0,0,0.2)` | `.background-video-2` |
| `linkHover` | `0 3px 8px 3px rgba(0,0,0,0.2)` | `.accreditation-link:hover` |

`soft` is the only tinted one: `#96a3b5` is a cool grey, not black, and the alpha is 0.078
(`0x14` is 20/255), not 0.08.

The current guide documents a dropdown shadow of `0 4px 10px rgba(0,0,0,0.3)`. That shape
exists in the stylesheet as a `backdrop-filter: drop-shadow(...)` at alpha 0.6, not as a
`box-shadow`, and not on a dropdown.

### The product elevation ladder

The mockup's ladder is heavier and more modern than the website's, and it is ink tinted
rather than pure black. **Use this for a product page.**

| Level | Value | Use |
|---|---|---|
| 1 | `0 4px 14px rgba(0,0,0,.06)` | A document or sheet inside an illustration |
| 2 | `0 8px 22px rgba(0,0,0,.08)` | A small floating panel |
| 3 | `0 14px 34px rgba(28,28,30,.12)` | A floating chip. Card hover uses `0 14px 30px` at the same alpha |
| 4 | `0 30px 70px rgba(0,0,0,.4)` | A white card on the ink section, which needs this much to separate |
| device | `0 40px 80px rgba(28,28,30,.28), 0 12px 28px rgba(28,28,30,.16)` | A device mockup |
| accent | `0 8px 20px rgba(216,42,128,.4)` | The one pink badge on a page. Nothing else |

**Most TRUE surfaces have no shadow at all.** A card is `#f8f8fb` at 16px radius, or white
with a 1px `#e5e5ea` border. Elevation is expressed with the border and the surface change,
not with a shadow. Reach for a shadow only when something genuinely floats.

### Glass

Two distinct patterns, both real, and they are not interchangeable.

```css
/* Glass BADGE: small, on a photo */
.glass-badge { backdrop-filter: blur(16px); background: rgba(255,255,255,.24);
               border-radius: 8px; padding: 8px 24px; }   /* .text-block-19, 112 x 40 */

/* Glass PANEL: large, on a hero */
.glass-panel { backdrop-filter: blur(80px); background: rgba(255,255,255,.16);
               border-radius: 8px; padding: 24px; gap: 24px; }   /* .div-block-11 */
```

Small blur with more white; large blur with less. Both at 8px radius. Always ship
`-webkit-backdrop-filter` alongside. Always give the element a solid fallback background for
browsers without support, because 0.16 white over a photograph with no blur is unreadable.

---

## 15. Boxes: cards and panels

Four box types cover almost everything on the site.

**1. Surface card.** `background: #f8f8fb; border-radius: 16px; padding: 48px`
(`.ben-3`, `.ben-4`). No border, no shadow. This is the default TRUE box.

**2. Outlined card.** `background: #fff; border: 1px solid #e5e5ea; border-radius: 16px;
padding: 26px` (`resources-style.ts .res-card`, the mockup `.feat`). Use on a surface
coloured section where a surface card would disappear.

**3. Gradient panel.** `background: var(--true-gradient); border-radius: 16px; padding: 48px`
(`.ben-6`, `.cta`). `.cta` adds `margin-top: 160px`. White headings at 40px and up only.

**4. Dark panel.** `background: #1c1c1e; border-radius: 16px; padding: 48px`
(`.socialproof`, `min-height: 419px`).

Smaller boxes: the FAQ item is `#f8f8fb`, 12px radius, 32px padding, 32px gap
(`.faq-item`). The mockup's step card is white with a 1px border at 16px radius, split into
a 170px tall `#f8f8fb` visual band and a `22px 24px 26px` text block.

**Rules.**

* One radius per box. Never mix 12px and 16px inside the same card.
* Padding is 48px for a full width panel, 26px for a card in a three column grid, 32px for a
  FAQ row. Nothing between those.
* A grid of cards uses a 22px gap (the mockup) or 16px (`.section-9`, `.section-10`).
* A box never carries both a border and a shadow on the website. On a product page, an
  outlined card may gain a shadow on hover, and that is the only combination.

---

## 16. Hero

The website has **three** hero types. They are not variations of one thing.

**1. Gradient hero.** `.hero.main` replaces the background entirely with the brand gradient:
`background-image: linear-gradient(90deg, var(--gradient-blue), var(--gradient-pink));
padding: 17vh 3% 0 6%`. Heading is Marcellus SC in white. This is the home page.

**2. Photo hero.** `.hero` is `background-color: #470505` (a fallback that is never visible),
then `linear-gradient(#0006, #0006)` as a flat 0.4 black scrim, then the photograph, with
`padding: 200px 88px 40px`. The scrim goes to `#0009` where the photograph is busier
(`.hero---product`). The 200px top padding is what clears the fixed navbar.

**3. Light hero.** The mockup, and the pattern for a product page. See
[PRODUCT PAGE](#30-product-page-recipe).

**Heading.** `.heading-hero` is left aligned Marcellus SC at `6vh/6vh`, `max-width: 800px`,
`margin-bottom: 24px`. `.heading-hero-center` is centred at a fixed `72px/72px`. Both are
white. Content inside a hero sits at `z-index: 2` above the background layers
(`.hero-content`, `margin-top: 5vh; margin-bottom: 10vh`).

**Rules.** One hero per page. The heading is 3 to 6 words. A photo hero always carries a
scrim: never place white text on an unscrimmed photograph. Never put the brand gradient
behind a photograph and expect the photograph to show, because in `.hero.main` the gradient
is the topmost background layer and covers everything below it.

---

## 17. Headers and navigation

### The website navbar

A floating pill, fixed to the top.

```css
.nav-wrapper { position: fixed; inset: 0 0 auto; z-index: 10; margin-top: 8px; }
.div-block   { width: 1000px; padding: 8px; border-radius: 16px;
               margin-left: auto; margin-right: auto;
               display: flex; align-items: center; gap: 16px; }
.div-block.light { background: #fff; border-color: #e5e5ea; }
```

Fixed 1000px wide, not a max width. Two variants, dark (transparent over a hero) and light
(white with a 1px `#e5e5ea` border). The dark variant swaps in the white wordmark and
`rgba(255,255,255,0.4)` button borders; the light variant swaps in the black wordmark, text
at `#2d2d2f` and `rgba(28,28,30,0.4)` borders.

Contents, in order (`chrome.ts`): wordmark, a vertical rule SVG, the nav links, one dropdown,
then the buttons. Nav links are 14/20 with `letter-spacing: 0.25px`. The dropdown list is
white at 12px radius with `box-shadow: 0 8px 50px rgba(0,0,0,0.05)` and `10px` vertical
padding.

Because the navbar is fixed, **the first section on every page must clear it**. The website
does this with `padding-top: 200px` on the hero.

### The product page header

Different construction, and the one to use for Sign, Vault and Verify (the mockup, `.hdr`):

```
[ 6px gradient top strip, full bleed                                            ]
[ lockup left | section nav centre | ghost button + solid button right          ]
```

```css
.hdr     { background: #fff; border-bottom: 1px solid #e5e5ea; }
.hdr-in  { display: flex; align-items: center; gap: 36px; min-height: 68px; }
nav      { display: flex; gap: 26px; margin-left: 8px; }
nav a    { color: #1c1c1e; text-decoration: none; font-size: 14.5px; }
nav a:hover { color: #d82a80; }
.hdr-cta { margin-left: auto; display: flex; gap: 10px; align-items: center; }
```

Not fixed, not floating, not a pill. A plain bar with a hairline under it, 68px minimum
height, sitting under the 6px gradient strip. Nav links go to on page anchors, not to other
sites. The right side is always exactly two controls: a ghost or plain text action (Log in)
and the primary solid button.

---

## 18. Footer

The website footer (`chrome.ts`, `.footer-menu`) is substantial and is documented nowhere in
the current guide.

```css
.footer-menu { background: #f8f8fb url(footer-bg.svg); border-radius: 16px;
               margin-top: 120px; padding: 48px; }
```

Structure, in order:

1. A `mailto:` support link, styled as a large heading.
2. A horizontal rule.
3. Four columns: address plus language switcher, Links, Connect with us (social icons),
   Accreditations (logo images with `box-shadow: 0 3px 8px 3px rgba(0,0,0,0.2)` on hover).
4. A separate bar below the panel: copyright on the left; Cookie settings, GDPR and Terms on
   the right, at 12px in `#a1a1a1`, separated by 2px round dots (`.link-7`, `.div-block-38`).

The footer ships in four variants (`en|dark`, `en|base`, `sv|dark`, `sv|base`), so any change
must be made four times.

**The product page footer** (the mockup) is simpler and is the pattern for a product:
white background, `border-top: 1px solid #e5e5ea`, `padding: 56px 0 40px`, a
`1.4fr 1fr 1fr 1fr` grid. The wide first column carries a Marcellus `h4` ("Why TRUE Sign?")
and a 300px paragraph. Each other column has an uppercase 12.5px label with `0.08em`
tracking in `#636366`, then 14px ink links at `margin-bottom: 10px` that turn pink on hover.
A `.f-bot` bar closes it: `border-top`, `margin-top: 44px`, `padding-top: 22px`, 12.5px in
`#636366`, copyright left and location right.

---

## 19. Forms and inputs

### Light input

```css
.text-field { background: #f8f8fb; border: 1px solid #f8f8fb; border-radius: 8px;
              padding: 12px 16px; font: 400 16px/24px var(--font-body); }
```

Note the border is the same colour as the fill, so the field reads as a filled shape with no
visible outline. Below 991px the padding grows to `16px 16px`.

### Dark input

```css
.text-field-2 { background: rgba(255,255,255,.16); border: 1px solid transparent;
                border-radius: 8px; color: #fff;
                font: 400 16px/24px var(--font-body); margin-bottom: 16px; }
.text-field-2::placeholder { color: rgba(255,255,255,.56); }
```

Below 991px: `height: 56px; padding: 16px`. The textarea variant is `height: 160px`.

**Radius is 8px for every input in production, without exception.**

### What does not exist

There is **no focus state for a text input** in the TRUE stylesheet. The only rule is the
Webflow default, `.w-input:focus { border-color: #3898ec; outline: 0 }`, which is a Webflow
blue nothing else uses, and it removes the outline. That is an accessibility regression
shipping on every form on the site.

NEW, and required for any new product form:

```css
.text-field:focus-visible { outline: 2px solid #0050bd; outline-offset: 2px;
                            border-color: #0050bd; }
/* on dark */
.text-field-2:focus-visible { outline: 2px solid #7dcade; outline-offset: 2px; }
```

Those two colours are the real focus colours (see [WCAG](#29-focus-and-wcag-aa)); pairing
them with inputs is the new part.

There are also no error, disabled, required or helper text styles anywhere in the codebase.
Searched: the full stylesheet, `resources-style.ts`, `insights.ts`, `forms.ts`. A product
needing them is defining them for the first time and should bring the result back here.

### Labels and buttons

Label: 14/20 body face in `#1c1c1e`, `margin-bottom: 8px`. NEW; the website has no label
style. Submit button: the solid button from [Buttons](#8-buttons). Field stack gap: 16px,
matching `.text-field-2 { margin-bottom: 16px }`.

---

## 20. Badges and pills

**Success badge**, the only badge in the stylesheet:

```css
.yes { color: #1ca800; border: 1px solid #1ca800; border-radius: 7px;
       padding: 2px 3px; display: inline-block; }
```

Outline plus text, never a fill. Note that `#1ca800` on white is roughly 3.2:1, so this fails
AA for normal text. Use it at 14px or larger and treat the colour as decorative, with the
word carrying the meaning.

**Glass badge**, on a photograph:

```css
.text-block-19 { backdrop-filter: blur(16px); background: rgba(255,255,255,.24);
                 border-radius: 8px; width: 112px; height: 40px; padding: 8px 24px; }
```

**Chip / pill**, hand written only:

```css
.res-chip { display: inline-flex; padding: 10px 18px; background: #fff;
            border: 1px solid #e5e5ea; border-radius: 999px;
            color: #1c1c1e; font-size: 15px; text-decoration: none; }
.res-chip:hover { border-color: #d82a80; }
```

**Hero kicker pill**: see [Preambles](#6-preambles).

**Accent badge**, the one place pink is a fill (the mockup, `.cert-badge`):
`background: #d82a80; color: #fff; border-radius: 10px; font-size: 11px; padding: 7px 13px;
box-shadow: 0 8px 20px rgba(216,42,128,.4)`. **One per page maximum.**

**Step number label**: 12px, `color: #d82a80`, `letter-spacing: 0.1em`, uppercase,
`margin-bottom: 8px` (the mockup, `.step-n`).

---

## 21. Tables

The website stylesheet has no table styling. The only real table system is
`resources-style.ts`, and it is good. Use it.

```css
.res-tableWrap { overflow-x: auto; margin-top: 24px;
                 border: 1px solid #e5e5ea; border-radius: 16px; }
.res-table     { width: 100%; border-collapse: collapse; min-width: 560px; }
.res-table th,
.res-table td  { padding: 15px 16px; text-align: left;
                 border-bottom: 1px solid #e5e5ea; font-size: 16px; }
.res-table th  { font-family: var(--font-display-sc); font-size: 12px;
                 letter-spacing: .06em; text-transform: uppercase; opacity: .75; }
.res-table tr:last-child td { border-bottom: none; }
```

The header row is **Marcellus SC, uppercase, 12px**, which is the one place small caps appear
outside a hero. The wrapper carries the radius and the scroll; the table itself has none, so
the corners stay clean while the content scrolls. On dark, borders become
`rgba(255,255,255,0.14)` and the wrapper border `rgba(255,255,255,0.16)`.

Never zebra stripe. Never add a vertical rule between columns. The bottom border on every row
is the entire structure.

---

## 22. Lists

Bulleted (`resources-style.ts .res-bullets`): `padding-left: 22px`, items at 18px / 1.55 with
`margin: 10px 0`. Default markers.

Numbered steps (`.res-steps`) replace the marker with a counter chip:

```css
.res-steps        { list-style: none; counter-reset: step; padding-left: 0; }
.res-steps li     { counter-increment: step; position: relative;
                    padding-left: 46px; margin-bottom: 18px; }
.res-steps li::before { content: counter(step); position: absolute; left: 0; top: -2px;
                    width: 30px; height: 30px; border-radius: 50%;
                    background: rgba(216,42,128,.10); color: #d82a80;
                    border: 1px solid rgba(216,42,128,.35);
                    display: flex; align-items: center; justify-content: center;
                    font-family: var(--font-display-sc); font-size: 14px; }
```

A pink tinted circle with a Marcellus SC numeral. On dark it becomes
`rgba(255,255,255,.12)` fill, white text, `rgba(255,255,255,.3)` border.

Checklist (the mockup, `.sec-li`): a 15px filled circle tick, `gap: 13px`,
`margin-bottom: 17px`, `align-items: flex-start` with `margin-top: 2px` on the tick so it
lines up with the first line of text. The lead phrase is weight 500 ink or white; the rest is
`#636366` on light, `rgba(255,255,255,0.8)` on dark.

---

## 23. Alerts and toasts

**Nothing in the TRUE codebase is an alert or a toast.** Searched: the full stylesheet,
`resources-style.ts`, `insights.ts`, `forms.ts`, `chrome.ts`, the mockup. The current style
guide documents a toast shadow; that value is `0 4px 12px rgba(0,0,0,0.2)` on
`.background-video-2`, a background video, and the guide also has the alpha wrong.

This is a genuine gap and it cannot be filled by extraction. What a product should do until
it is filled centrally:

* Build the alert as an **outlined card**: white fill, 1px border, 12px radius, `16px 20px`
  padding, an icon at 20px and text at 14/24. That is the nearest real TRUE shape.
* For the border and icon colour use `#1ca800` for success (the only real semantic colour)
  and **stop**. There is no TRUE warning or error colour. Raise it rather than inventing one,
  as TRUE Verify and TRUE Vault each did separately and differently.
* For elevation on a floating toast use the product ladder level 3,
  `0 14px 34px rgba(28,28,30,.12)`.
* Give it `role="status"` for success and information, `role="alert"` for errors.

---

## 24. Empty states

Nothing in the codebase. NEW, built from real parts:

Centre in the container. A 48px icon (the largest real icon step) in `#e5e5ea`, then a sub
heading at Marcellus 24/32, then one line of body at 16/24 in `#636366`, then at most one
button. Vertical padding 80px. No illustration, no shadow, no card around it. An empty state
is an absence, so make it quiet.

---

## 25. Loading and skeletons

**The only animation in the entire compiled stylesheet is a spinner:**
`@keyframes spin`, applied as `animation: .8s linear infinite spin`. That is the whole
loading vocabulary the website has.

For a skeleton, NEW, built from real parts: a `#f8f8fb` block at the radius of the thing it
replaces (8px for an input or small card, 16px for a panel), with `height: 5px` and
`border-radius: 3px` for a text line, which is what the mockup uses for its document lines
(`.p-doc i`, `.mini-body i`). Pulse with the mockup's `@keyframes pulse`, `opacity .75` to
`1` over `2.4s ease infinite`, rather than inventing a shimmer sweep. Both values are real;
using them for skeletons is the new part.

Never animate a skeleton faster than 1s. Never use the brand gradient in a skeleton.

---

## 26. Dark sections

The dark section is `#1c1c1e` full bleed with white text. Real examples: `.socialproof`
(16px radius panel, `min-height: 419px`, `padding: 48px 0`), `resources-style.ts`
`.res-section--dark`, and the mockup's `.sec` (`padding: 84px 0`).

Everything inside changes:

| Element | On light | On dark |
|---|---|---|
| Heading | `#1c1c1e` | `#ffffff` |
| Body | `#636366` | `rgba(255,255,255,0.8)` |
| Border | `#e5e5ea` | `rgba(255,255,255,0.16)` on a surface, `rgba(255,255,255,0.4)` on a control |
| Card fill | `#f8f8fb` | `rgba(255,255,255,0.05)` (resources) |
| Inline link | `#d82a80` | `#7dcade` |
| Solid button | ink fill, white text | white fill, ink text |
| Ghost button border | `rgba(28,28,30,0.4)` | `rgba(255,255,255,0.4)` |
| Input fill | `#f8f8fb` | `rgba(255,255,255,0.16)` |
| Placeholder | (undefined) | `rgba(255,255,255,0.56)` |
| Focus ring | `#0050bd` | `#7dcade` |
| Code block | `#1c1c1e` on `#f2f2f4` | `rgba(0,0,0,0.4)` with a `rgba(255,255,255,0.12)` border |

**Pink does not survive on dark.** `#d82a80` on `#1c1c1e` measures roughly 3.7:1, which
clears AA for large text and UI components but not for body copy. Brand blue on ink is
roughly 9.2:1. That is why every dark section link in `resources-style.ts` switches to blue.

A white card on a dark section needs `box-shadow: 0 30px 70px rgba(0,0,0,.4)` (the mockup,
`.cert`) to separate. Nothing lighter reads.

---

## 27. Imagery and blog header rules

**Format.** The site serves `.avif` throughout with `.jpg` and `.png` fallbacks, and
`loading="lazy"` on everything below the fold. Keep both.

**Every photograph carrying text needs a scrim.** `linear-gradient(#0006, #0006)` at 0.4
black is the standard. Go to `#0009` at 0.6 when the photograph is busy. The scrim is written
as a flat two stop gradient so it sits as its own background layer between the image and
anything above it.

**Photo cards** use a bottom up fade instead: `linear-gradient(#0000 50%, #0000007a)` over
`background-color: #0000007a`, at 8px radius, 560px tall, 48px padding, with the caption at
the bottom (`.div-block-115`). The horizontal variant reads left to right.

**Blog header.** `.heading-blog` is Marcellus 48/56 in white, left aligned, no margins, over
a scrimmed photograph. The card image sits on `.div-block-111` as a `background-image` with
`cover`. The card title is `.heading-23`, body face 20/28 weight 500, with the date above it
in `.text-block-16`.

**Blog body is 14px**, not 16px, at `margin: 80px 10%` (`.rte`), and the article `h1` is
Marcellus 40/48 (`.rte h1`). Blog copy is ink, not `#636366`.

**The logo ticker.** A horizontally scrolling strip masked at both ends:

```css
.ticker.has-horizontal-fade {
  -webkit-mask-image: linear-gradient(90deg, #0000, #000 10% 90%, #0000);
          mask-image: linear-gradient(90deg, #0000, #000 10% 90%, #0000);
  display: flex; gap: 40px; }
```

A vertical variant drops the `90deg`. Logos in the ticker are 100 to 160px wide at 24 to 40px
tall. The mockup's simpler trust band sets partner names in Marcellus at 17px in `#9a9aa0`
with `0.04em` tracking instead of using logo images, which is a reasonable substitute before
you have permission to show real marks.

**Never.** Place text on an unscrimmed photograph. Put the brand gradient over a photograph
and expect the photograph to show. Crop the wordmark into an image.

---

## 28. Animations and motion tokens

**The website is almost motionless.** Four `transition` declarations and one `@keyframes` in
208 KB. The real motion vocabulary is in the hand written code and the mockup.

### Tokens

| Token | Value | Where |
|---|---|---|
| `instant` | 100ms | `transition: background-color .1s, color .1s` |
| **`fast`** | **150ms** | `insights.ts`, `resources-style.ts` and the mockup all agree |
| **`base`** | **200ms** | `transition: all .2s`; the mockup's `.btn` |
| `slow` | 300ms | `transition: all .3s` |

**Easing is the bare `ease` keyword.** Every hand written transition in the TRUE codebase
uses it. There is exactly one custom curve, `cubic-bezier(.5, 0, .7, .2)`, a hard
accelerating fall used for the seal stamp landing on the document (the mockup, `@keyframes
pslam`). Do not invent more curves.

**Use `fast` for hover feedback and `base` for a state change.** Never transition `all`:
name the properties, as the mockup does
(`transition: background .2s ease, color .2s ease, border-color .2s ease`).

### Hover

| Element | Effect |
|---|---|
| Button | `opacity: .85` or `translateY(-1px)`. One, not both. |
| Ghost button | Border darkens to full ink. |
| Card | `translateY(-3px)` plus `0 14px 30px rgba(28,28,30,.12)`. |
| Link | Colour to pink. Border colour follows if there is an underline border. |
| Chip | Border colour to pink. |

### Ambient animation

Reserved for the hero illustration. The mockup's pattern: a float
(`5.5s ease-in-out infinite`, `translateY(0)` to `-9px` at 50%) with **staggered delays**
(0.4s, 1.6s, 2.6s) so elements never move in lockstep, plus a pulse
(`2.4s ease infinite`, opacity `.75` to `1`) and a pop (`3s ease`, scale `.85` to `1` with
opacity).

**Rules.** Ambient motion belongs to the hero and nowhere else. Nothing in the body of a page
animates on a loop. Nothing animates on scroll into view. Loops run 2.4s or slower so they
read as ambient rather than as an alert.

### Reduced motion

**Neither the stylesheet nor any hand written TRUE stylesheet ships a
`prefers-reduced-motion` block.** Searched: the full stylesheet, `resources-style.ts`,
`insights.ts`, the mockup. The only one anywhere is in the current style guide itself, which
is not a source of truth.

This is a required addition, NEW, for every TRUE surface:

```css
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
```

The hero's looping animations are the whole reason this matters: without it they run
indefinitely for a user who has asked them not to.

---

## 29. Focus and WCAG AA

### The real focus ring

```css
:focus-visible { outline: 2px solid #0050bd; outline-offset: 0; border-radius: 4px; }
```

Source: `.nav-link:focus-visible`, `.nav-dropdown-toggle:focus-visible`,
`.nav-dropdown-link:focus-visible`. The rule also sets `color: #0050bd`, and the radius is
4px on a link, 5px on a dropdown.

On dark, the ring is brand blue with an offset:

```css
:focus-visible { outline: 2px solid #7dcade; outline-offset: 2px; }
```

Source: `insights.ts .feed-load-more-btn:focus-visible`.

**There is no pink focus ring anywhere in production.** The current style guide uses one.
`#d82a80` on white is roughly 4.6:1, which is below the 3:1 required of a non text UI
component only in the sense that it passes, but it is far weaker than `#0050bd` at roughly
7.3:1 and it collides with the link colour. Use `#0050bd`.

Webflow removes the outline on eight of its own components (`.w-input:focus`,
`.w-dropdown-toggle:focus`, `.w-nav-button:focus`, `.w-tab-link:focus` and others all set
`outline: 0`). Any product reusing those classes must put the ring back.

### Contrast

Ratios below were computed from the token values against the stated background using the
WCAG 2.1 relative luminance formula. They are calculations, not measurements from a tool.

| Foreground | Background | Ratio | AA normal (4.5) | AA large / UI (3.0) |
|---|---|---|---|---|
| `#1c1c1e` | white | ~17.0 : 1 | pass | pass |
| `#636366` | white | ~6.0 : 1 | pass | pass |
| `#0050bd` | white | ~7.3 : 1 | pass | pass |
| `#d82a80` | white | ~4.6 : 1 | **pass, barely** | pass |
| `#1ca800` | white | ~3.2 : 1 | **FAIL** | pass |
| `#a1a1a1` | white | ~2.6 : 1 | **FAIL** | **FAIL** |
| `#7dcade` | white | ~1.9 : 1 | **FAIL** | **FAIL** |
| white | `#1c1c1e` | ~17.0 : 1 | pass | pass |
| `rgba(255,255,255,.8)` | `#1c1c1e` | ~11.2 : 1 | pass | pass |
| `#7dcade` | `#1c1c1e` | ~9.2 : 1 | pass | pass |
| `#d82a80` | `#1c1c1e` | ~3.7 : 1 | **FAIL** | pass |
| placeholder `.56` white | the `.16` white fill on ink | ~4.5 : 1 | borderline | pass |

**What follows from this.**

* **Brand blue is never a text colour on white.** It is a gradient stop, a focus ring on
  dark, and a tint. Nothing else.
* **Pink is a link and a heading accent on white, and a UI colour only on dark.** Never pink
  body copy on ink.
* **`#a1a1a1` fails everywhere.** It is the footer micro link colour on 3 live rules. Any new
  surface should use `#636366` instead, which passes at 6.0:1 and is already the body colour.
* **`#1ca800` fails for normal text.** The `.yes` badge relies on it. Keep the badge at 14px
  or larger and make sure the word, not the colour, carries the meaning.
* **The gradient is not a text background.** Contrast against white text swings from roughly
  1.9:1 at the blue end to roughly 4.6:1 at the pink end. Only headings at 40px and above
  belong on it, and even then the left edge is weak. This is why every real gradient panel on
  the site carries a large heading and short copy, never a paragraph.

### Other requirements

Every interactive element needs a visible `:focus-visible` state. Never `outline: none`
without a replacement. Icon only controls need an `aria-label`. Decorative SVG needs
`aria-hidden="true"`. Nav links must be real `<a>` elements. The 6px gradient top strip is
decorative and must not be the only indicator of anything.

---

## 30. PRODUCT PAGE recipe

This is the shape every TRUE product page follows: Sign, Vault and Verify. It is the
`sign-redesign.html` mockup reconciled against the real brand values. Follow it top to
bottom.

Where the mockup and the website disagree, this recipe states which one wins and why.

### Reconciliations applied

| The mockup does | The recipe says | Why |
|---|---|---|
| Breaks at `max-width: 960px` | Break at **991px** | 960px matches nothing on the website. A product at 960px disagrees with the shared chrome by 31px. |
| `h1` at 54px, `h2` at 36px | Use **48/56** and **32/40** | Those are the real page and section heading steps, at 16 and 40 uses. 54px and 36px are incidental. |
| Sizes at 14.5px, 16.5px, 13.5px, 12.5px | Round to **14, 16, 14, 12** | Half pixel sizes are mockup artefacts. The real scale has no half steps. |
| `font-family: 'Helvetica Neue Updated','Helvetica Neue',Arial,Helvetica,sans-serif` | Use `--font-body` | Same stack, canonical order. |
| `.btn-pink` is an **ink** filled button | Rename to `.btn-solid` | The class name says pink and the fill is `#1c1c1e`. Nothing in the system has a pink filled button except the one accent badge. |
| `.btn-pink:hover { background: #32343a }` | Darken the border, or `opacity: .85` | `#32343a` is Webflow starter boilerplate, not a TRUE colour. See [Buttons](#8-buttons). |
| `--radius: 16px` as the only radius | Keep 16px for boxes, **12px** for buttons and tiles, **8px** for inputs | The real three step ladder. |
| No `prefers-reduced-motion` | **Required.** See [Motion](#28-animations-and-motion-tokens) | The hero animates on a loop. |
| Marcellus from Google Fonts | Load from the trueoriginal.com origin, or self host | The brand serves its own faces. Google Fonts is a second source of truth for the same file. |

### The page, top to bottom

**0. Gradient top strip.** Full bleed, `height: 6px`, `background: var(--true-gradient)`. The
first element in the body. It is the signature of a TRUE product page.

**1. Header.** White, `border-bottom: 1px solid #e5e5ea`, `min-height: 68px`, container
1180px with 28px gutters.

```
[ lockup ]          [ nav: on page anchors ]          [ ghost | solid ]
```

* Lockup: mark 30px, then **TRUE** in Marcellus 20px `letter-spacing: .02em` at full ink,
  then the product word in Marcellus 20px at `#636366`. `gap: 10px`.
* Nav: 4 to 5 anchors, 14px, `gap: 26px`, hover to pink.
* Right: `margin-left: auto`, `gap: 10px`. A text or ghost action (Log in) then the primary
  solid button.

**2. Hero.** Two columns, `grid-template-columns: 1.02fr .98fr`, `gap: 40px`,
`align-items: center`, `padding: 72px 0 76px`. Background is the two radial washes over
`#f8f8fb` with `border-bottom: 1px solid #e5e5ea` (see [Gradient](#2-gradient)).

Left column, in order:

1. **Kicker.** Pill with a 7px pink dot. 12px, `#636366`, `margin-bottom: 22px`.
   Who you are, not what you do.
2. **`h1`.** Marcellus, **48/56**, with **one word** in the gradient. 3 to 6 words. End with
   a full stop if it is a complete assertion.
3. **Sub.** 18px / 1.55, `#636366`, `max-width: 520px`, `margin-bottom: 30px`. Two sentences.
4. **CTA pair.** `.btn-solid.btn-lg` then `.btn-ghost.btn-lg`, `gap: 14px`,
   `padding: 16px 32px`. The solid one leads.
5. **Trust line.** Three short proofs, `gap: 22px`, 13px `#636366`, each opened by a 15px
   brand blue circle tick. No claim longer than four words.

Right column: the product illustration. A device or document mockup with the level 3
elevation, plus two or three floating proof chips (white, 1px border, 12px radius,
`0 14px 34px rgba(28,28,30,.12)`, `float 5.5s ease-in-out infinite` with staggered delays).
Hidden below 991px.

**3. Trust band.** Full width, `border-bottom: 1px solid #e5e5ea`, `padding: 26px 0`,
centred, `gap: 38px`, wrapping. An uppercase 12px `#636366` label with `0.08em` tracking
("Documents verified for"), then partner names in Marcellus 17px at `#9a9aa0` with `0.04em`
tracking, or real logos in a masked ticker.

**4. How it works.** `.sect { padding: 84px 0 }`. Centred `.sect-head` at `max-width: 640px`,
`margin-bottom: 52px`: Marcellus `h2` at **32/40**, then one 16px `#636366` paragraph.

Three cards, `repeat(3, 1fr)`, `gap: 22px`. Each card is white, 1px border, 16px radius,
`overflow: hidden`, split into:

* A 170px visual band on `#f8f8fb` with `border-bottom: 1px solid #e5e5ea`, holding a small
  animated illustration of that step.
* A text block at `padding: 22px 24px 26px`: the step label (12px, `#d82a80`, uppercase,
  `0.1em` tracking), then an `h3` at 20px weight 500, then 14px / 1.55 `#636366` copy.

**5. Features.** `.sect.sect-mist`: same padding on `#f8f8fb` with a hairline top and bottom.
Same centred `.sect-head`. Six cards, `repeat(3, 1fr)`, `gap: 22px`, each white with a 1px
border, 16px radius, 26px padding: a 42px icon tile, then an `h3` at 16px weight 500, then
14px `#636366` copy.

**6. Security, the dark section.** Full bleed `#1c1c1e`, `padding: 84px 0`, two columns
`1.1fr .9fr`, `gap: 56px`.

Left: Marcellus `h2` in white at 32/40; a lead paragraph at 16px / 1.6 in
`rgba(255,255,255,0.8)`, `max-width: 480px`, `margin-bottom: 26px`; then a checklist of four,
each a 15px brand blue tick plus a weight 500 white lead phrase and
`rgba(255,255,255,0.8)` continuation.

Right: one white card, `max-width: 400px`, `margin-left: auto`, 16px radius, 26px padding,
`box-shadow: 0 30px 70px rgba(0,0,0,.4)`. This is the proof artefact of your product: the
certificate for Sign, the vault record for Vault, the verification result for Verify. A
header row with a 26px mark and a Marcellus 16px title over a hairline, then rows of
`space-between` label and value at 12px, label in `#636366` and value in ink, hashes in the
mono stack at 10.5px. One pink accent badge pinned to the top right corner, and **only** one.

**7. Use cases.** `.sect`. Centred `.sect-head`. Six link cards, `repeat(3, 1fr)`,
`gap: 18px`, each 16px radius, 26px padding, `min-height: 120px`, content aligned to the
bottom with `space-between`, a weight 500 label and a `→` at 18px `opacity: .55`. Rotate
four fills so the grid has rhythm: `#f8f8fb` (with a `#e5e5ea` border), `#eaf6fa`, `#1c1c1e`
(white text), `rgba(216,42,128,.08)`. Hover is `translateY(-3px)` plus
`0 14px 30px rgba(28,28,30,.12)`.

**8. CTA band.** A three way split, 16px radius, `overflow: hidden`, 1px border, with a 6px
gradient top rule (`border-top: 6px solid transparent` plus
`border-image: linear-gradient(90deg, #7dcade, #d82a80) 1`). Columns `1.2fr .9fr .9fr`, each
`padding: 44px 38px`:

* Ink panel, white text: Marcellus `h3` at 24/32, a 14px paragraph at `opacity: .75`, then a
  white filled button.
* `#eaf6fa` panel: 16px weight 500 heading, 14px `#636366` copy, then an arrow link.
* `#f8f8fb` panel: the same, with the second action.

**9. Footer.** See [Footer](#18-footer), product variant.

### Responsive

One breakpoint at **991px**. The hero collapses to one column and the illustration is hidden.
The three column grids become one column. The dark section and the CTA band become one
column. The footer goes to two columns. The `h1` drops from 48px to 36px. Below 479px, page
gutters drop from 28px to 18px and section padding to 56px, matching resources.

---

## 31. Do and do not

### Do

* Use `--true-gradient` at 90deg, blue left, pink right, as a background.
* Use 48px padding for a panel and 160px between website sections, or 84px symmetric padding
  on a product page.
* Use three radii: 8px inputs, 12px buttons, 16px boxes. 999px for a true pill.
* Set body copy at 16/24 in `#636366` on light, `rgba(255,255,255,0.8)` on dark.
* Write every heading in sentence case, in Marcellus, at 400.
* Give every heading a class. A bare `h2` renders as bold Arial.
* Put exactly one word of the hero `h1` in the gradient.
* Ship the ghost plus solid button pair, solid first.
* Use `#0050bd` for focus on light and `#7dcade` on dark, always with a visible outline.
* Break at 991px.
* Ship a `prefers-reduced-motion` block on anything that animates.
* Scrim every photograph that carries text, at 0.4 black.
* Use weight 500 for emphasis, because 700 does not exist in the canonical body family.

### Do not

* Do not put body copy on the brand gradient. Contrast swings from roughly 1.9:1 to 4.6:1
  across its width.
* Do not use brand blue as a text colour on white. It measures roughly 1.9:1.
* Do not use `#a1a1a1` for anything new. It fails contrast at every size.
* Do not use 12px radius on an input. Every input in production is 8px.
* Do not use 80px as a pill radius. It is a circle on a 64px button. The pill is 999px.
* Do not use `#32343a`, `#1a1b1f`, `#3898ec`, `#e4ebf3` or `#333`. They are Webflow starter
  leftovers.
* Do not write `font-weight: 700` against the canonical body family. It will synthesise.
* Do not use the `Helveticaneue Roman` family. It has no `@font-face` behind it and renders
  in the browser default.
* Do not add Lato. Ten weights already load on every website page for one CSS rule.
* Do not use a pink focus ring. It exists nowhere in production.
* Do not invent a warning or error colour locally. Raise it; both Verify and Vault already
  invented different ones.
* Do not use hyphens, en dashes or em dashes as punctuation in TRUE prose.
* Do not use Title Case or ALL CAPS for a heading. Uppercase is for eyebrows and step labels
  only, at 12px with 0.08em tracking.
* Do not stack a kicker and an eyebrow.
* Do not put more than one pink accent badge on a page.
* Do not animate anything below the hero on a loop.
* Do not transition `all`. Name the properties.
* Do not remove an outline without replacing it.
* Do not treat `1360px` as the page container. It is one panel.
* Do not copy the resources `--res-*` names into a new product. They are scoped to
  `/resources/` and they are not a second opinion about what blue is.
