# Exemplars — canonical screens to imitate

> Imitate the **logic** (hierarchy, rhythm, tone), never the pixels. Every card carries
> its captures, its measured analysis, the WHY it's canon, and how to read its Figma
> workarounds as rules. Counter-examples are teaching material too.

## Status: 5 cards, minted from Figma — WHY lines ✅ validated 2026-07-28

Source: the "[WIP] Paradox App" Figma file (`uZfZ4lr4eJeDb4q5KeWDiz`), frames Maxime
declared 100% valid on 2026-07-27. **41 screens extracted and measured**, one analysis
file each in [analysis/](analysis/), one capture each in [captures/](captures/).

Three standing caveats on every card below, from Maxime:
1. **Design truth only.** Content and features have drifted; some blocks are unreleased.
   Never read these as product truth.
2. **Copy and imagery are placeholder** — written quickly to fill the frames. Never
   canon, never a copy reference. (For voice, see the Bible §3.)
3. **The DS wins over Figma.** Where a frame contradicts the validated design system,
   the DS value is right — see [the drift arbitration doc](../../DRIFT-ARBITRAGE-FIGMA.md).
   Build from the analysis files' MAPPED tokens, never by eyedropper.

**Each card's WHY is validated** (Maxime, 2026-07-28). One correction applied: the
responsive doctrine first written under Home was **not** a Home trait — it is a global
layout rule and now lives in the Bible as hard rule 8, applying to every screen.

## What a Figma exemplar teaches — and doesn't

Teaches: layout, hierarchy, spacing rhythm, density, composition, focal-point discipline,
accent discipline, responsive strategy.
Does NOT teach: interactive states, motion, or copy. Those stay governed by the hard
rules and the DS site. Where the frames DO carry state variants, the analysis files hold
a `## State matrix` section.

## Reading a Figma workaround (important)

**A workaround in a frame is an intention, not a mistake.** Maxime builds these to show
what he wants *visually* without breaking a component, inside Figma's constraints
(2026-07-28). So when a frame does something structurally odd — a zeroed-out section with
a pasted overlay, a duplicated hidden block, an off-grid offset — the job is **never** to
copy the mechanism and **never** to dismiss it. It is to read the intent and express it
as a rule coherent with the rest of the corpus.

Each card below therefore carries **"Figma constraint → rule"** instead of a
"do not copy" list. Two consequences:
1. Implement the *rule*, not the frame's mechanism.
2. Per hard rule 7, the rule then applies to **every** screen of that family — not only
   the screen it was read from.

---

## E1 — Home (6 breakpoints)

- **Captures**: `home-{desktop-large,desktop-xl,desktop,desktop-small,tablet,mobile}.png`
- **Analyses**: same slugs in `analysis/`
- **WHY** ✅ (validated 2026-07-28): the reference for the **member dashboard** — mixed
  card families (course, action, tutorial, event, identity) stacked in labelled sections,
  each section a Ground Header over a horizontal card row. Uniform 20px radius across
  ~20 card instances of five different card types. The Paradox Score / streak block is
  the screen's single focal point.
  *(The responsive doctrine originally written here is a global rule, not a Home trait —
  it now lives in the Bible as hard rule 8.)*
- **Richest annotations of the corpus** (19 verbatim, in `home-desktop-large.md`),
  including the scroll-linked course-card animation spec and the streak-chart opacity
  rules — the only place in the corpus where motion intent is written down.
- **Figma constraint → rule**: the tablet frame zeroes the course section (`opacity-0`)
  and pastes an overlay carousel; desktop-small uses hand-placed override frames with
  mask-cropped cards. Both are Figma workarounds for the same intent: **at ≤1024px, card
  rows become peeking horizontal carousels at fixed card size** (Bible hard rule 8).
  Implement one carousel component for the whole compact family — never per-screen
  overlays, and never a reflow that shrinks cards.
- **WIP inside**: the whole Identity/stats block on mobile is annotated
  *"🚧 WIP, do not integrate for now"*; the logo is annotated *"🚧 Wrong logo"*.

## E2 — Catalog (6 breakpoints + multi-topic)

- **Captures**: `catalog-{desktop-large,desktop-xl,desktop,desktop-small,tablet,mobile}.png`,
  `catalog-desktop-large-multitopic.png`, plus hover / search / filters-open variants
- **WHY** ✅ (validated 2026-07-28): the reference for **browsing density and section
  rhythm**. Course cards are a fixed size (244×344 standard, 624×344 featured) — wider
  screens add margin, never columns. Section vertical rhythm is a constant **488px step**
  (440 section + 48 gap), holding even through the 11-section multi-topic frame. Exactly
  one accent badge per visible card, never more, never a fill.
- **Figma constraint → rule**: tablet instances the mobile component at 768px, and every
  instance is internally named "@ Desktop large" whatever its width. Read as: **tablet
  belongs to the compact family and follows the mobile composition** — there is no third
  tablet grid to build (Bible hard rule 8). The naming is Figma hygiene, carrying no
  design meaning.
- **WIP inside**: *"🚧 EMPTY STATE ILLUSTRATION MISSING / SCREENS WIP"* covers all
  empty-state variants — the intent exists, the illustrations don't.

## E3 — Course detail (desktop + mobile)

- **Captures**: `course-detail-desktop-large.png`, `course-detail-mobile.png`
- **WHY** ✅ (validated 2026-07-28): the reference for a **long content page with a
  sidebar**. Desktop runs a genuine two-column split (modules flex-1 ≈848px + fixed 392px
  progress sidebar, 40px gap) that stacks full-width on mobile. Spacing is 100% on the DS
  scale with zero drift anywhere — the cleanest screen of the corpus on that axis. Title
  and description each drop one type-scale tier from desktop to mobile while body copy
  stays 16px.
- **Figma constraint → rule**: on mobile the hero title/meta block exists twice (one live
  over the hero image, one hidden in the block below) — the hidden copy is the component's
  default content, kept rather than detached. Read as: **on mobile the hero title overlays
  the image**, and there is exactly one title in the DOM. Render the overlay, drop the
  duplicate.

## E4 — Loop (16 screens, desktop + mobile)

- **Captures**: `loop-*.png` — main, preview, focus mode, share modal, analysis,
  analysis-exercice, upcoming/past sessions, chat, transcript, filters
- **WHY** ✅ (validated 2026-07-28): the **broadest reference of the corpus** — list
  shells, overlays, modals, chat, and a long report page in one coherent family. It fixes
  the desktop list shell (Ground Header 64, pagination 64, footer 224 over the hard-rule-8
  container) and the overlay vocabulary (528px side panel, 480px modal, both over a
  72%-black + 2px-blur scrim). Accent discipline is at its strictest: burgundy is entirely
  absent from three of four desktop screens and, on chat, marks **only** the member's own
  bubbles.
- **Figma constraint → rule**: the share modal shows off-grid values (7 / 7.5px offsets,
  0.714px borders) — artefacts of scaling a component inside the frame, not intent. Read
  as: **the close button sits at the standard 8px inset and borders are 1px** (DS values).
  The JetBrains Mono Italic quote callout is the real, validated rare exception for
  transcript-style content — not a licence for a third UI font.
- **Hidden system inside**: a "Section compact" variant (82px cards) exists on both
  session lists — an unreleased density system worth knowing about.

## E5 — Loop creation (7 families, desktop + mobile)

- **Captures**: `loop-creation-{dispatch,verbatim,thematique,success,detail-drawer}-desktop-large.png`,
  `loop-creation-{dispatch,preview,frame5075}-mobile.png`, plus section-context captures
- **WHY** ✅ (validated 2026-07-28): the reference for a **multi-step wizard**. The whole
  New Loop flow is ONE master component whose steps are revealed by layer visibility, not
  a component per step — and the type hierarchy is deliberately flat: a single Clash
  headline over an otherwise uniform field of DM Sans 14px. Its `## State matrix` sections
  inventory the empty, filled, error and recap states across the flow — currently the only
  state documentation in the corpus.
- **Figma constraint → rule**: the disabled CTA is a raw 48% opacity class. That value IS
  the DS disabled opacity (`.48`) — so the intent is exactly right, only the binding is
  raw. Read as: **disabled = the DS `.48` opacity state, via its token**. Not a drift in
  design, just in plumbing.
- **⚠️ The Success modal's confetti is dead** — see the resolved section below.

## RESOLVED — the Success modal's confetti is dead, fire replaces it

The Figma Success modal shows a **full-frame confetti raster**. Maxime's ruling
(2026-07-28): **confetti is abandoned** — too gamified, childish and dated. The Paradox
celebration primitive is the **fire-crackle border effect**, already built and shipped in
the codebase.

The code is AHEAD of Figma here. `LoopCreateSuccessModal.tsx` already renders
`<BorderFireEffect cardRef={cardRef} trigger={fireTrigger} />` — this exact screen's
implementation has already dropped the confetti.

Why the fire effect is on-brand by construction, where confetti never was: its
`FIRE_PALETTE` **is PX Heat extended into incandescence** — heat-80 `#6a1f36` →
heat-150 `#8d2146` (the burgundy accent) → heat-250 → heat-400 → heat-600 `#e86a52`, then
on into warm whites. Three particle types (spark / ember / cinder) with gravity, wobble
and trails, emitted from `pointOnBorder()` — the effect traces the card's **border**, so
it frames the artifact rather than covering the screen. That is the difference between
celebrating the residue and burying it.

Consequences, applied:
- Bible stance 7 rewritten and promoted to ✅; stance 4 now bans confetti outright.
- New anti-pattern: the effect is implemented **twice** (`create-loop/BorderFireEffect.tsx`
  and a richer inline copy in `onboarding/steps/FinalConfirmationStep.tsx` with extra
  `ash` / `residual` particles). It belongs in `ds/`; the two copies should converge
  there. Don't write a third.
- The Success modal stays an exemplar for its **layout** (centered 432px card, 40/24
  padding, metric row, dual CTA). Its confetti layer is explicitly **not** canon — read
  the shipped modal for the celebration treatment.

---

## Counter-examples

- **CE1 — MeditationScreen (mobile, shipped code)**: 62 hardcoded hex values, blue/gold
  gradients entirely off PX Heat. What "no referential" drift looks like; every rule it
  breaks is a Bible hard rule.

## How canon gets minted

1. **Through Figma** (the fast path, used above): Maxime hands over frames → export the
   capture, measure the values, map them to `--ds-*` tokens and `ds/` components, flag
   what has no token → draft the annotations and a proposed WHY → **Maxime validates the
   WHY in one line**. No coded implementation required; the frame is the exemplar.
2. **Through the harness**: a screen generated with the Bible, corrected by Maxime,
   shipped — then explicitly promoted by him, with captures, measurable annotations and
   the WHY.

Nobody else mints canon. An agent may *propose* a candidate in a PR; only Maxime's
explicit promotion counts.

**Refresh**: a Figma exemplar goes stale when its frame changes — re-export on change.
A harness exemplar needs the monthly scripted re-capture and diff (running code rots).
An exemplar without a WHY is a screenshot, not an exemplar.
