/* ⛔ FONT PATHS. Batch 1 shipped url('assets/fonts/…'), which is relative to THIS FILE at
   web/assets/css/ and therefore resolved to web/assets/css/assets/fonts/… — four 404s. The files
   were present all along; the path was wrong. This is the silent-fallback class: the page still
   renders, in system fonts, looking close enough to ship. Caught by the render gate, not by eye. */
/* ⛔ VESPER, 2026-08-16 — TWO CORRECTIONS TO RITA'S BATCH 1. Everything else is verbatim.
   1. --acc was #F54301. That is the outlier hex Jon corrected THIS MORNING; it exists in 3 places
      in the product and #F97316 — the PN logo orange — exists in 293. Batch 1 reproduced the error
      independently, which means the misleading source file is still in the brand folder.
   2. `.row` -> `.pn-row`. `.row` collides with 9 declarations across the play stylesheets and is
      the exact class behind today's topbar overflow bug. The handover's own prose calls it
      `.pn-row`; the safer name is the one kept.
   CEO RULING the same day: the PitchNoir mark sits TOP-LEFT of the screen, in the rail head, and
   the agency lockup moves to the app bar. This overrides Batch 1's "product brand in the chrome,
   player identity in the rail". The brand guard is untouched — moving the mark is not licence to
   restyle it. */
/* ═══════════════════════════════════════════════════════════════════════════════
   PITCHNOIR DESIGN SYSTEM — v4, BATCH 1
   Implementable now. Extracted verbatim from web/floor.html, which is the reference
   build; if this file and that page ever disagree, the page is right and this is stale.

   THE FIVE LAWS
   1. TONE CARRIES STRUCTURE. --grouped / --card / --card-2. Where two surfaces differ
      in tone, draw no border. Separators divide rows inside ONE card and nowhere else.
   2. ONE TEMPERATURE PER THEME. Dark and Neon are cool families throughout; Light is
      warm throughout. A cool rail beside a warm cream panel is two palettes fighting.
   3. ORANGE (--acc) HAS TWO ROLES: the primary action, and live-or-urgent state. A loss
      is history, not urgency, and is never accented.
   4. --bone IS THE DECISION SURFACE. Exactly one per screen, on the thing the player
      must act on, and it carries the only prominent button.
   5. ROUND IS THE INSTRUMENT LANGUAGE. Rings and dot fields are gauges driven by real
      values, built from design/graphic_reference. Never decoration.

   ⛔ BRAND GUARD. The PitchNoir mark is never recoloured, filtered or masked. Two
   authored files exist — pitchnoir-dark.png and pitchnoir-white.png — and the only
   decision is which one the rail's tone calls for. It has been turned blue once by an
   invert(); .wm carries !important guards so that can never happen again.

   TWO THEMES: default (dark) · [data-theme="light"]. (Neon retired 2026-09-12.)
   Every component follows the tokens with zero per-theme overrides. If a component
   needs an override to survive a theme switch, the component is wrong.

   BATCH 1 SHIPS: tokens · themes · shell + rail + dock · season ribbon · capsules
   (.cap, .mini) · rows/groups (.pn-row) · the decision card · instruments (ring, dial,
   meter, stat) · video panel · help sheet + explain disclosure · build-in motion.
   ═══════════════════════════════════════════════════════════════════════════════ */

@font-face{font-family:IS;src:url('../fonts/instrument-sans.woff2') format('woff2-variations');font-weight:400 700;font-display:swap}
@font-face{font-family:SG;src:url('../fonts/spacegrotesk-700.woff2') format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:IN;src:url('../fonts/inter-400.woff2') format('woff2-variations');font-weight:100 900;font-display:swap}
/* 2026-09-19 (CEO ruling, §5g-ii): `--pn-type-face` named the alias 'IN' first with no
   @font-face against the literal name 'Inter' anywhere — font_guard.js only recognises a family
   by the exact name declared in an @font-face, so every `font-family:Inter` in the pitch-flow
   rebuild measured as a silent Helvetica fallback despite 'IN' pointing at the same file. Same
   variable font, same weight range, registered under its real name so nothing has to alias
   through 'IN' again. */
@font-face{font-family:Inter;src:url('../fonts/inter-400.woff2') format('woff2-variations');font-weight:100 900;font-display:swap}
@font-face{font-family:JB;src:url('../fonts/jetbrainsmono-400.woff2') format('woff2');font-weight:400;font-display:swap}

:root{/* DARK (default). iOS grouped-background model in PitchNoir navy. */
  --grouped:#1B242F; --card:#27333F; --card-2:#33414F; --sep:#3E4C5B;
  --label:#F3F6F9; --label2:#B3BECB; --label3:#BCC9D7;
  /* ALTERNATION LAW (Jon, 31 Jul): on a DARK page the chrome goes PALE SLATE, so the
     rail separates instead of dissolving into the ground. Slate, never cream. */
  /* --rail-dim was #55616F, which put the rail's unread counters at 4.01:1 on --rail-2 —
     under AA, in every room, because the rail is shared. Measured, not judged. */
  --rail:#DDE3EA; --rail-2:#C6CFD9; --rail-ink:#131B24; --rail-dim:#48535F;
  /* ── THE FIELD (CEO, 17 Aug: "youve used some dumb off palette light gradient for dark
     theme — use proper dark and cold colours … The palette dark colour you have used
     should be the LIGHTER colour, replace the current gold colour in the gradient with a
     super dark almost black blue.")
     So the field is no longer painted in --acc/--play (orange + gold). It is painted in
     the page's OWN navy family: the deepest bloom is --grouped driven down toward black
     (a derivation of a token, not a colour I picked), and the palette's existing dark
     members become the LIGHTER two, exactly as instructed. */
  /* ⛔ THE FLOOR OF THE PAGE, NAMED ONCE. CEO, 17 Aug: "the darkest part of this thursday
     panel should be the darkest part of the gradient in the background." The set-piece
     ground was a bare #0F1419 written into .setpiece twice — the darkest object in the
     game, with no name and nothing else referencing it. It is now --film-black, and the
     field's deepest bloom IS that value. Not approximately, not a mix that lands near it:
     the same token, so the panel and the page bottom out together and stay that way. */
  --film-black:#0F1419;
  --field-deep:var(--film-black);
  --field-mid: var(--card-2);                                  /* the lighter member */
  --field-lift:var(--sep);
  /* the decision surface is always the opposite of the page */
  /* the decision surface is COOL in the dark theme so it shares the rail's family.
     Warm cream beside cool slate is two palettes fighting on one screen. */
  --bone:#EFF3F7; --bone-ink:#111820; --bone-dim:#55616F;
  --ring-track:#44535F; --ring-hair:#5E7080;
  --play:#E8B45C; --play-dim:#AC9670;
  --sage:#9DB395; --ochre:#D2A047; --clay:#CE7B5E;
  /* THE ACCENT PAIR. Two tokens, never one, because an accent has two jobs and they need
     opposite inks. STYLE_SOURCE_OF_TRUTH §138 already ruled this and the rooms ignored it:
     bright orange takes NEAR-BLACK (7.14:1), and it is the light theme that swaps to burnt
     orange with white. White on #F97316 is 2.8:1 — it was on every primary button here.
       --acc      the fill, and the accent used as ink on the page ground
       --acc-ink  what is legible ON that fill
     (UX_RULES §13 still reads "button text is white on brand-orange fills". That line and
      SST §138 contradict each other; SST is the locked art direction and it is the one with
      the measurement, so it wins. Flagged rather than silently picked.) */
  --acc:#F97316; --acc-ink:#07080C;
  /* ── SECONDARY ACCENT — vibrant BLUE (CEO, 2026-08-19): "warm clay/beige secondary reads dull;
     add a vibrant blue for highlights, never replacing --acc." Cool sky-blue against the navy
     grouped ground; near-black ink on the fill (measured, see DECISIONS_LOG). */
  --blue:#3AA9FF; --blue-ink:#07141F;

  --room:#C2C7CD;
  --num:SG,ui-sans-serif,system-ui,sans-serif;
  --mono:JB,ui-monospace,SFMono-Regular,Menlo,monospace;
  --r-card:18px; --r-ctl:20px;
  /* r-ctl bumped 16→20, 19 Aug: buttons round further than the card but deliberately stop
     short of the 99px pill/chip family (badges, .st, .go) — two radius families on purpose,
     button = "soft-round control", pill = "capsule tag/chip". Never merge the two. */
  --inset:20px;}
/* ── PURCHASED PACKS (the Vault) ─────────────────────────────────────────────────
   Every pack is a token swap and nothing else: the same markup, the same laws, the
   same components. This is what a player is buying, and why the system has to hold.
   The brand mark never changes in any of them. */

/* NEON theme retired (CEO 2026-09-12: "remove neon and just have light and dark"). The third-
   theme token block that lived here is deleted — data-theme is only ever set by mvc-os.js
   (play.html/dossier-open.html, the only two pages that load it) and can now only be dark/light,
   so a [data-theme="neon"] block here could never match again. */

/* LIGHT. Not an inversion: the same laws run the other way. The page is warm paper, the
   rail goes DARK (alternation), and the decision surface flips to ink so it still reads
   as the one thing that is different. */
:root[data-theme="light"]{--grouped:#EBE7DD; --card:#FBF9F4; --card-2:#F1EDE1; --sep:#D9D3C4;
  --label:#1A1712; --label2:#514B3F; --label3:#3E372A;
  --rail:#221F19; --rail-2:#332F26; --rail-ink:#F3EFE5; --rail-dim:#ABA290;
  --bone:#221F19; --bone-ink:#F4F0E6; --bone-dim:#ABA290;
  /* the light theme did not override --acc at all, so bright orange sat on warm paper at
     2.27:1 for every section eyebrow. SST §138: light goes BURNT orange and takes white. */
  --acc:#B4380D; --acc-ink:#FFFFFF;
  /* ⛔ FIXED 2026-08-19 (design-critic audit): --clay was #8C4326, a burnt-orange near-
     identical to --acc (ΔE~27) and too close to --ochre (ΔE~21) — Watch/Lost read as the
     same colour in light. Re-derived cooler/darker into the wine-red family: ΔE44 from
     --acc, ΔE41 from --ochre, still ≥7.8:1 on --card/--card-2 (same fix class already
     shipped for neon's --sage/--play collision). --play was 4.00:1 on --card-2 (fails
     AA text) — it is used as real text colour on the active off-hours dock label
     (.dock--play[aria-current]{color:var(--play)}), not icon-only, so it had to move:
     nudged toward olive/yellow-green rather than simply darkened, which would have
     collided it with --ochre instead (ΔE was already only 14 apart) — now ΔE21, 4.75:1
     on --card-2. See DECISIONS_LOG. */
  --sage:#3E5A39; --ochre:#7A5310; --room:#C6BEAB; --clay:#7A2E3A;
  --play:#6E6B12; --play-dim:#8A7A5E;
  /* SECONDARY ACCENT — blue, cooled for paper: a cobalt that holds contrast on cream
     (measured 4.9:1 white-on-fill / dark ink at 8.1:1), matching the dark/neon blues' job. */
  --blue:#1D5FBF; --blue-ink:#FFFFFF;
  --ring-track:#D3D8DE; --ring-hair:#AEB7C1;
  /* LIGHT runs the law the other way: the page is paper, so the field SHADES it rather
     than lighting it. But it may never go darker than paper — the first cut drove the
     deep bloom to room×0.7 (#8E897C) and the sweep immediately caught .kick and .subtitle
     at 3.37:1 across seven rooms, because dark ink was landing on a mid-tone. Worse, the
     field DRIFTS, so that contrast was a function of the clock. The light field is now
     bounded inside the paper family — room is the floor, not the midpoint. */
  --film-black:#0F1419;   /* a screen is a screen in every pack — only the FIELD changes */
  --field-deep:var(--room);
  --field-mid: var(--sep);
  --field-lift:var(--card-2);}

/* ── PINNED DARK (.pinned) ────────────────────────────────────────────────────────
   Some surfaces are dark because the FICTION is dark, not because the theme is: the pub
   is evening, and the countdown board sits on a photograph under a heavy wash. Those
   surfaces used to pin the four ground tokens and leave the ink on the theme — so in the
   light pack the pub painted #1A1712 type on a #1E262E bar at 1.02:1, and the board put
   burnt orange on near-black. The whole room, shipped.

   Two rules, both learned the hard way:
   1. A surface that pins its ground pins EVERY token read against that ground. Half-pinned
      is the theme the player bought fighting the fiction.
   2. It must re-declare `color`. `body{color:var(--label)}` resolves ONCE, at body — a
      descendant inherits that computed value, not the token, so the pinned --label never
      reaches inherited text. That is exactly how "Work / Gossip / The ask" stayed black. */
.pinned{--grouped:#141A20; --card:#1E262E; --card-2:#2A343E; --sep:#36424E;
  --label:#F3F6F9; --label2:#B7C1CC; --label3:#BCC9D7;
  --bone:#EFF3F7; --bone-ink:#111820; --bone-dim:#55616F;
  --ring-track:#44535F; --ring-hair:#5E7080; --room:#C2C7CD;
  --sage:#9DB395; --ochre:#D2A047; --play:#E8B45C; --play-dim:#AC9670; --clay:#CE7B5E;
  --acc:#F97316; --acc-ink:#07080C;
  --blue:#3AA9FF; --blue-ink:#07141F;
  /* Rule 1 above, applied to the field the same day it was introduced: a surface that pins
     its ground pins EVERY token read against that ground — and the field IS a ground. Left
     off this list, the light pack's paper-coloured blooms painted straight over the pub and
     the sweep read the masthead at 1.37:1 on a page whose fiction is a dark room. */
  --film-black:#0F1419;
  --field-deep:var(--film-black);
  --field-mid: var(--card-2);
  --field-lift:var(--sep);
  color:var(--label)}
*{box-sizing:border-box;margin:0;scrollbar-width:thin;scrollbar-color:var(--sep) transparent}
::selection{background:var(--acc);color:var(--acc-ink)}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:var(--sep);border-radius:99px}
::-webkit-scrollbar-track{background:transparent}
:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
html,body{height:100%}

.n{font-family:var(--num);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.u{font:500 .55em/1 var(--num);color:var(--label3);margin-left:.1em}

/* ── the iPad ─────────────────────────────────────────────────────────────────────── */
.pad{height:100%;display:grid;grid-template-rows:minmax(0,1fr);
  grid-template-columns:minmax(0,1fr);padding:20px}
.dev{width:min(100%,1360px);height:100%;min-height:0;margin:0 auto;
  background:#0F1419;border-radius:34px;padding:11px;
  box-shadow:0 22px 60px rgba(28,22,12,.34), inset 0 0 0 1px rgba(255,255,255,.07)}
/* ⛔ THE SIDEBAR COLUMN IS SIZED BY THE SIDEBAR, NOT BY A NUMBER WRITTEN HERE.
   CEO 2026-09-21, on the verdict screen after Marlowe's eight questions: "this page loads -
   garbage". The card had collapsed to 164px down the left with the rest of the window empty
   beside it.

   `252px minmax(0,1fr)` describes the layout only while the rail is a grid item. pn-shell.js
   hides the rail on screens that host a room rather than the game shell (`.side{display:none}`,
   pn-shell.js:194) - a hidden element is not a grid item, so `.content` auto-placed into the
   252px slot and the 1fr column stayed empty. Every set-piece that hides the rail got the same
   treatment; the verdict is simply where it was noticed.

   A track whose width comes from its own content cannot disagree with whether that content is
   there: `auto` collapses to nothing when the rail is hidden and to the rail's own width when it
   is not. The 252px moves onto `.side`, where it belongs. `.content` is then placed explicitly,
   so it can never be pulled into the rail's track by an absent sibling again - guarded to the
   two-column width, since the <=980 rules below deliberately drop to a single column.
   Reproduced and pinned in qa/verdict_screen.test.mjs, under all 59 of play.html's stylesheets. */
.screen{height:100%;border-radius:24px;overflow:hidden;background:var(--grouped);
  display:grid;grid-template-columns:auto minmax(0,1fr);min-height:0;position:relative}
@media (min-width:981px){ .screen>.content{grid-column:2} }

/* ── sidebar (iPadOS .sidebar list style) ────────────────────────────────────────── */
.side{background:var(--rail);color:var(--rail-ink);padding:14px 10px;display:grid;
  width:252px;box-sizing:border-box;
  align-content:start;gap:2px;overflow:auto;min-height:0}
/* ⛔ BRAND GUARD. The PitchNoir mark is RETRIEVED, never recoloured. No theme, no
   purchased pack and no filter may touch it — there are two authored files and the
   only decision is which one the rail's tone calls for. It has been made blue once
   by an invert() and that must never be possible again. */
.brand{padding:12px 12px 16px;margin-bottom:6px;display:grid;gap:12px;
  border-bottom:1px solid rgba(128,140,155,.26)}
.side .wm{height:26px;width:auto;justify-self:start;
  filter:none!important;mix-blend-mode:normal!important;opacity:1!important}
.agency{display:flex;align-items:center;gap:10px;min-width:0}
.agency .crest{flex:none;width:34px;height:34px;border-radius:11px;display:grid;
  place-items:center;background:var(--rail-2)}
.agency .crest svg{width:22px;height:22px}
.agency .who{min-width:0}
.agency .who b{display:block;font:600 14px/1.1 IS,ui-sans-serif,system-ui,sans-serif;color:var(--rail-ink);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.agency .who i{display:block;font-style:normal;font:400 11.5px/1 IS,ui-sans-serif,system-ui,sans-serif;
  color:var(--rail-dim);margin-top:4px}
.wm--light{display:none}
:root[data-theme="light"] .wm--dark{display:none}
:root[data-theme="light"] .wm--light{display:block}
.side .shdr{font:400 10.5px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--rail-dim);padding:20px 12px 8px;margin-top:6px;
  border-top:1px solid rgba(128,140,155,.28)}
.side .shdr--first{border-top:0;margin-top:0;padding-top:6px}
.side a{display:flex;align-items:center;gap:12px;min-height:46px;padding:0 12px;
  border-radius:12px;text-decoration:none;color:var(--rail-ink);font-size:15.5px;
  font-weight:500;transition:background .16s var(--ease,cubic-bezier(.22,1,.36,1))}
.side a svg{flex:none;width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;opacity:.62}
.side a:hover{background:var(--rail-2)}
.side a:hover svg{opacity:1}
/* the current room: a filled slab and an accent icon. Unmissable, and it is the only
   place the rail uses the accent. */
.side a[aria-current]{background:var(--rail-ink);color:var(--rail);font-weight:700}
.side a[aria-current] svg{stroke:var(--acc);opacity:1}
.side a .c{margin-left:auto;font:600 12.5px/1 var(--num);font-variant-numeric:tabular-nums;
  color:var(--rail-dim);background:var(--rail-2);border-radius:99px;min-width:22px;
  height:20px;display:grid;place-items:center;padding:0 6px}
.side a[aria-current] .c{background:rgba(255,255,255,.14);color:var(--rail)}

/* ── content: large title, then grouped sections. It scrolls. ────────────────────── */
.content{position:relative;min-height:0;overflow-y:auto;overflow-x:hidden;padding-bottom:104px}

/* the dock: four rooms, floating, glass, never scrolls away */
.dock{position:absolute;left:50%;bottom:16px;transform:translateX(-50%);z-index:40;
  display:flex;gap:4px;padding:7px;border-radius:999px;
  /* 78% was see-through enough that body copy scrolling under the dock stayed READABLE
     behind it — two texts competing in the same pixels, which is the occlusion the audit
     flagged at 1280. Glass has to be opaque enough to be a surface. */
  background:color-mix(in srgb, var(--card) 93%, transparent);
  backdrop-filter:blur(28px) saturate(1.5);-webkit-backdrop-filter:blur(28px) saturate(1.5);
  box-shadow:0 10px 34px rgba(0,0,0,.34), inset 0 0 0 1px color-mix(in srgb, var(--label) 12%, transparent)}
.dock a{position:relative;display:grid;justify-items:center;gap:5px;min-width:70px;padding:8px 9px 7px;
  border-radius:999px;text-decoration:none;color:var(--label3);
  transition:background .2s cubic-bezier(.22,1,.36,1),color .2s cubic-bezier(.22,1,.36,1)}
.dock a svg{width:24px;height:24px;stroke:currentColor;fill:none;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round;
  transition:transform .24s cubic-bezier(.22,1,.36,1)}
.dock a span{font:600 10.5px/1 IS,ui-sans-serif,system-ui,sans-serif;letter-spacing:.01em}
.dock a:hover{color:var(--label2)}
.dock a:hover svg{transform:translateY(-3px)}
/* ⛔ SECONDARY-BLUE NAV PILL (CEO, 2026-08-19): the active room used the same flat --card-2
   fill as a resting hover state — the current room and "you're about to hover here" read
   identically. Filled/tinted glass pill in the new --blue makes "you are here" unmistakable
   without touching --acc, which stays reserved for money/CTA. */
.dock a[aria-current]:not(.dock--play){background:color-mix(in srgb, var(--blue) 24%, var(--card-2));
  color:var(--label);box-shadow:inset 0 0 0 1.5px color-mix(in srgb, var(--blue) 55%, transparent)}
.dock a[aria-current]:not(.dock--play) svg{stroke:var(--blue)}
.dock a .bdg{position:absolute;transform:translate(15px,-4px);min-width:17px;height:17px;
  padding:0 5px;border-radius:99px;background:var(--acc);color:var(--acc-ink);
  font:700 10px/17px SG,sans-serif;text-align:center;z-index:1}
/* the split: four rooms of business, then the two that are not.
   The Arcade and UpTheDuff are off-hours — they must never look like another
   line item on the agency's to-do list. */
.dock-split{width:1px;align-self:stretch;margin:6px 5px;flex:none;
  background:color-mix(in srgb, var(--label) 18%, transparent)}
.dock--play{color:var(--play-dim)}

.dock--play svg{opacity:.92;stroke-width:1.6}
.dock--play span{font-weight:500;letter-spacing:.02em}
.dock--play:hover{color:var(--play);background:color-mix(in srgb, var(--play) 12%, transparent)}
.dock--play:hover svg{transform:translateY(-3px) rotate(-6deg)}
.dock--play[aria-current]{background:color-mix(in srgb, var(--play) 18%, transparent);
  color:var(--play)}
.dock--play[aria-current] svg{stroke:var(--play)}
@media (prefers-reduced-motion:reduce){.dock a:hover svg{transform:none}}
.appbar{position:sticky;top:0;z-index:30;display:flex;align-items:center;gap:16px;
  padding:0 var(--inset);height:58px;background:var(--grouped);
  border-bottom:1px solid color-mix(in srgb, var(--label) 9%, transparent)}
.appbar .mark{display:flex;align-items:center;gap:11px;flex:none;margin-right:auto}
.appbar .mark img{height:23px;width:auto;
  filter:none!important;mix-blend-mode:normal!important;opacity:1!important}
.appbar .sep{width:1px;height:20px;background:color-mix(in srgb,var(--label) 16%,transparent)}
/* ⛔ VESPER: renamed from `.appbar .room`. Batch 1 uses `.room` for TWO unrelated things —
   this app-bar LABEL and the room PHOTO CARD (`min-height:280px`). The label inherited the card's
   box and fell 280px through the season ribbon below it. Same defect class as `.row`: a generic
   name doing two jobs. Caught by measuring, not by looking — at a glance the label looked fine. */
.appbar .roomlab{font:400 11px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:var(--label3)}
.store{display:inline-flex;align-items:center;gap:8px;height:36px;padding:0 15px 0 12px;
  border-radius:999px;border:0;cursor:pointer;text-decoration:none;
  /* ⛔ ACCENT INK ON AN ACCENT TINT IS NOT A CONTRAST PAIR. It survives in dark because the
     accent is bright against a near-black wash, and fails in light because the light accent
     is BURNT — #B4380D on its own 15% tint measured 3.9:1, on every one of the eight rooms,
     because the bar is shared. One fault, sixteen sweep lines.
     The tint stays (it is what says "money lives here") and the ICON keeps the accent, so
     nothing about the pill's identity moves. Only the ink changes to --label, which is the
     page's own ink and therefore correct on any ground the pill can land on. */
  background:color-mix(in srgb, var(--acc) 15%, transparent);color:var(--label);
  font:600 13.5px/1 IS,ui-sans-serif,system-ui,sans-serif;
  transition:background .16s cubic-bezier(.22,1,.36,1)}
.store:hover{background:color-mix(in srgb, var(--acc) 26%, transparent)}
.store svg{width:16px;height:16px;stroke:var(--acc);fill:none;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.store b{font:700 13px/1 var(--num);font-variant-numeric:tabular-nums}
.burger{width:36px;height:36px;border-radius:999px;border:0;cursor:pointer;display:grid;
  place-items:center;background:var(--card);color:var(--label2);
  transition:background .16s cubic-bezier(.22,1,.36,1)}
.burger:hover{background:var(--card-2);color:var(--label)}
.burger svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round}

/* the menu: themes, settings, sign out — everything that is not the game */
.menu{position:absolute;top:54px;right:var(--inset);z-index:70;width:270px;
  background:var(--card);border-radius:18px;padding:8px;
  box-shadow:0 18px 48px rgba(0,0,0,.42), inset 0 0 0 1px color-mix(in srgb,var(--label) 10%,transparent);
  opacity:0;transform:translateY(-6px) scale(.98);pointer-events:none;transform-origin:100% 0;
  transition:opacity .18s cubic-bezier(.22,1,.36,1),transform .18s cubic-bezier(.22,1,.36,1)}
.menu.open{opacity:1;transform:none;pointer-events:auto}
.menu .mh{font:400 10.5px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--label3);padding:11px 12px 8px}
.menu .themes{display:flex;gap:2px;background:var(--grouped);border-radius:12px;padding:3px;
  margin:0 4px 6px}
.menu .themes button{flex:1;border:0;cursor:pointer;background:transparent;color:var(--label3);
  height:32px;border-radius:9px;font:500 13px/1 IS,ui-sans-serif,system-ui,sans-serif}
.menu .themes button.on{background:var(--card-2);color:var(--label);font-weight:600}
.menu a,.menu .mi{display:flex;align-items:center;gap:11px;min-height:42px;padding:0 12px;
  border-radius:11px;text-decoration:none;color:var(--label);font-size:14.5px;cursor:pointer;
  background:none;border:0;width:100%;text-align:left}
.menu a:hover,.menu .mi:hover{background:var(--card-2)}
.menu svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;flex:none;opacity:.7}
.menu .rule{height:1px;background:var(--sep);margin:6px 8px}
.menu .out{color:var(--clay,#CE7B5E)}

.navbar{padding:18px var(--inset) 0}
.tools{display:flex;gap:8px;align-self:center;flex:none;align-items:center}
.themes{display:flex;gap:2px;background:var(--card);border-radius:999px;padding:3px}
.themes button{border:0;cursor:pointer;background:transparent;color:var(--label3);height:30px;
  padding:0 13px;border-radius:999px;font:500 12.5px/1 IS,ui-sans-serif,system-ui,sans-serif;
  transition:background .16s cubic-bezier(.22,1,.36,1),color .16s cubic-bezier(.22,1,.36,1)}
.themes button:hover{color:var(--label2)}
.themes button.on{background:var(--card-2);color:var(--label);font-weight:600}
.packs{display:flex;gap:2px;background:var(--card);border-radius:999px;padding:3px}
.packs button{border:0;cursor:pointer;background:transparent;color:var(--label3);
  height:30px;padding:0 11px;border-radius:999px;font:500 12.5px/1 IS,ui-sans-serif,system-ui,sans-serif;
  display:inline-flex;align-items:center;gap:6px;
  transition:background .16s cubic-bezier(.22,1,.36,1),color .16s cubic-bezier(.22,1,.36,1)}
.packs button i{width:9px;height:9px;border-radius:99px;flex:none;
  box-shadow:0 0 0 1px rgba(255,255,255,.18)}
.packs button:hover{color:var(--label2)}
.packs button.on{background:var(--card-2);color:var(--label);font-weight:600}
.pn-help{flex:none;border:0;cursor:pointer;display:inline-flex;align-items:center;gap:8px;
  height:36px;padding:0 14px 0 10px;border-radius:999px;background:var(--card);
  color:var(--label2);font:500 13px/1 IS,ui-sans-serif,system-ui,sans-serif;align-self:center;
  transition:background .16s cubic-bezier(.22,1,.36,1)}
.pn-help:hover{background:var(--card-2);color:var(--label)}
.pn-help i{width:20px;height:20px;border-radius:99px;background:var(--card-2);display:grid;
  place-items:center;font:700 12px/1 IN;font-style:normal;flex:none}
.pn-scrim{position:fixed;inset:0;z-index:60;background:rgba(9,13,18,.62);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);display:grid;place-items:center;
  padding:26px;opacity:0;pointer-events:none;visibility:hidden;
  transition:opacity .24s cubic-bezier(.22,1,.36,1),visibility 0s linear .24s}
.pn-scrim.open{opacity:1;pointer-events:auto;visibility:visible;transition-delay:0s}
.pn-helpsheet{position:relative;background:var(--card);border-radius:24px;overflow:hidden;
  width:min(720px,100%);max-height:100%;display:grid;grid-template-rows:auto minmax(0,1fr);
  transform:translateY(10px) scale(.985);
  transition:transform .3s cubic-bezier(.22,1,.36,1);
  box-shadow:0 30px 80px rgba(0,0,0,.5), inset 0 0 0 1px color-mix(in srgb,var(--label) 10%,transparent)}
/* the crown: the concentric-ring mark from design/graphic_reference, doing the work an
   illustration would, and built from the same geometry as the instruments. */
.hcrown{position:relative;padding:26px 30px 22px;background:var(--card-2);overflow:hidden}
.hcrown svg.rings{position:absolute;right:-52px;top:-70px;width:250px;height:250px;opacity:.16;
  pointer-events:none}
.hcrown .badge{display:inline-flex;align-items:center;gap:8px;height:28px;padding:0 12px 0 8px;
  border-radius:999px;background:color-mix(in srgb,var(--acc) 18%,transparent);color:var(--acc);
  font:600 12px/1 IS,ui-sans-serif,system-ui,sans-serif}
.hcrown .badge i{width:18px;height:18px;border-radius:99px;background:var(--acc);color:var(--acc-ink);
  display:grid;place-items:center;font:700 11px/1 IN;font-style:normal}
.hcrown h3{font:700 28px/1.05 IS;letter-spacing:-.03em;margin-top:13px;position:relative}
.hcrown .lede{font-size:14.5px;line-height:1.5;color:var(--label2);margin-top:9px;max-width:52ch;
  position:relative}
.hbody{overflow:auto;padding:6px 30px 26px}

.pn-helpsheet .close{margin:18px 30px 26px;width:calc(100% - 60px)}
.hclose{position:absolute;top:18px;right:18px;z-index:3;width:34px;height:34px;border-radius:999px;
  border:0;cursor:pointer;display:grid;place-items:center;color:var(--label2);
  background:color-mix(in srgb,var(--grouped) 70%,transparent)}
.hclose:hover{background:var(--grouped);color:var(--label)}
.hclose svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round}
.pn-scrim.open .pn-helpsheet{transform:none}
.pn-helpsheet .grab{width:38px;height:5px;border-radius:99px;background:var(--sep);
  margin:0 auto 16px}
.pn-helpsheet h3{font:700 23px/1.1 IS;letter-spacing:-.02em}
.pn-helpsheet .lede{font-size:14.5px;color:var(--label2);margin-top:8px;max-width:72ch}
.pn-helpsheet ol{margin:18px 0 0;padding:0;list-style:none;counter-reset:h}
.pn-helpsheet ol li{counter-increment:h;display:block;padding:14px 0 14px 40px;position:relative;
  border-top:1px solid var(--sep);font-size:14px;line-height:1.55;color:var(--label2)}
.pn-helpsheet ol li::before{content:counter(h,decimal-leading-zero);position:absolute;left:0;top:14px;
  width:26px;height:26px;border-radius:99px;display:grid;place-items:center;
  background:color-mix(in srgb,var(--acc) 16%,transparent);
  font:700 11px/1 SG,sans-serif;color:var(--acc)}
.pn-helpsheet ol li b{color:var(--label);font-weight:600}
.pn-btn{display:inline-flex;align-items:center;justify-content:center;border:0;cursor:pointer;
  min-height:44px;padding:0 20px;border-radius:var(--r-ctl);background:var(--acc);color:var(--acc-ink);
  font:700 15px/1 IS,ui-sans-serif,system-ui,sans-serif;margin-top:20px}
[data-build]{opacity:0;transform:translateY(10px)}
@media (prefers-reduced-motion:reduce){[data-build]{opacity:1!important;transform:none!important}}
.titlerow{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;
  padding-bottom:14px}
.titlerow>div:first-child{margin-right:auto}
h1{font:700 34px/1.06 IS;letter-spacing:-.028em}

.figs{display:flex;gap:24px;flex:none;padding-bottom:3px}
.figs div{display:grid;gap:3px;text-align:right}
.figs dt{font:400 10px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--label3)}
.figs dd{font:700 18px/1 var(--num);font-variant-numeric:tabular-nums}
.up{color:var(--sage)}

/* the season: the time axis, labelled, with a legend. Twelve unexplained numbers is
   not an axis — it is a puzzle. */

.slab{flex:none;font:400 10.5px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--label3)}

.legend{display:flex;flex-wrap:wrap;gap:16px;padding-left:2px}
.legend span{display:inline-flex;align-items:center;gap:7px;font-size:11.5px;color:var(--label3)}
.legend i{width:11px;height:11px;border-radius:4px;flex:none}
.legend .k-won{background:var(--sage)}
.legend .k-flat{background:var(--card-2)}
.legend .k-open{background:var(--card);box-shadow:inset 0 0 0 1px var(--sep)}
.legend .k-now{background:var(--acc)}
.legend .k-due{background:var(--card);box-shadow:inset 0 0 0 1px var(--sep);position:relative}
.legend .k-due::after{content:"";position:absolute;inset:0;margin:auto;width:5px;height:5px;
  border-radius:99px;background:var(--ochre)}

.wk.won{background:var(--sage);color:var(--grouped)}
.wk.flat{background:var(--card-2);color:var(--label2)}

/* ── inset-grouped section ───────────────────────────────────────────────────────── */

.hicon{width:15px;height:15px;stroke:var(--acc);fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;flex:none;opacity:.85}
.shead span{font-size:13px;color:var(--label3)}
.group{background:var(--card);border-radius:var(--r-card);overflow:hidden}
.pn-row{display:flex;align-items:center;gap:13px;min-height:56px;padding:10px 16px;
  position:relative;color:inherit;text-decoration:none}
/* separators inset to the text column, as on iOS */
.pn-row+.pn-row::before{content:"";position:absolute;top:0;left:16px;right:0;height:1px;
  background:var(--sep)}
.pn-row.hasimg+.pn-row.hasimg::before{left:63px}
.pn-row .t{flex:1;min-width:0}
.pn-row .t b{font-weight:400;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pn-row .t i{font-style:normal;font-size:13px;color:var(--label3);display:block;margin-top:3px}
.pn-row .v{font:500 15px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label2);
  flex:none;text-align:right}
.pn-row .v b{font-weight:700;color:var(--label);display:block}
.pn-row .v i{font-style:normal;font-size:12.5px;color:var(--label3);display:block;margin-top:4px;
  font-family:IS,ui-sans-serif,system-ui,sans-serif}
a.row:hover{background:var(--card-2)}
.chev{flex:none;width:8px;height:13px;stroke:var(--label3);fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;margin-left:2px}
.pn-row img{flex:none;width:34px;height:34px;border-radius:99px;object-fit:cover;
  filter:grayscale(1) contrast(1.1)}
.pn-row.on{background:var(--card-2)}
.ok{color:var(--sage)} .due{color:var(--ochre)} .mut{color:var(--label3)}
.footnote{font-size:13px;color:var(--label3);padding:9px 6px 0}

/* ── the summary row: the room, and the instrument ───────────────────────────────── */
.summary{display:grid;grid-template-columns:minmax(0,1.28fr) minmax(0,1fr);gap:14px;
  align-items:stretch}
.room{position:relative;border-radius:var(--r-card);overflow:hidden;background:var(--card);
  min-height:280px}
.room img{width:100%;height:100%;object-fit:cover;object-position:50% 44%;display:block;
  position:absolute;inset:0}
.room .scrim{position:absolute;inset:0;
  background:linear-gradient(to top,rgba(15,20,25,.93),rgba(15,20,25,.18) 64%,rgba(15,20,25,0))}
.room .txt{position:absolute;left:20px;right:20px;bottom:18px;z-index:2;color:#F4F7FA}
.room .k{font:400 11px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:#D4DBE3}
.room h3{font:700 clamp(24px,2.4vw,32px)/1 IS;letter-spacing:-.035em;margin-top:9px;
  text-transform:uppercase;transform:skewX(-9deg);transform-origin:0 100%;padding-right:.1em}

.instr{background:var(--card);border-radius:var(--r-card);padding:15px 16px 16px;
  display:grid;justify-items:center;align-content:start;gap:9px}
.instr>svg{width:100%;max-width:150px;height:auto;display:block}
.ring-tr{fill:none;stroke:var(--ring-track);stroke-width:9}
.ring-pr{fill:none;stroke:var(--acc);stroke-width:9;stroke-linecap:round;
  transform:rotate(-90deg);transform-origin:50% 50%}
.ring-th{fill:none;stroke:var(--ring-hair);stroke-width:1}
.ring-dt{fill:none;stroke:var(--ring-hair);stroke-width:1.5;stroke-dasharray:1 6;stroke-linecap:round}
.gv{font:700 40px/1 var(--num);fill:var(--label);font-variant-numeric:tabular-nums}
.gu{font:500 15px/1 var(--num);fill:var(--label3)}
.gl{font:400 9px/1 JB,monospace;letter-spacing:.18em;fill:var(--label3)}
.figrows{width:100%;display:grid;gap:0;padding-top:13px;margin-top:2px;
  border-top:1px solid var(--sep)}
.figrows div{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:8px 0}
.figrows div+div{border-top:1px solid var(--sep)}
.figrows>div>span:first-child{font:400 10.5px/1 var(--mono);letter-spacing:.15em;
  text-transform:uppercase;color:var(--label3)}
.figrows b span{font:inherit;color:inherit;letter-spacing:inherit;text-transform:none}
.figrows b{font:700 17px/1 var(--num);font-variant-numeric:tabular-nums;
  white-space:nowrap;letter-spacing:0;color:var(--label)}
.figrows em{font-style:normal;font:400 11.5px/1 IS,ui-sans-serif,system-ui,sans-serif;margin-left:7px}
.figrows .of{color:var(--label3)}
.dials{display:grid;grid-template-columns:1fr 1fr;gap:12px;width:100%;padding-top:12px;
  border-top:1px solid var(--sep)}
.dial{display:grid;justify-items:center;gap:6px}
.dial svg{width:52px;height:52px;display:block}
.dial .dv{font:700 16px/1 var(--num);font-variant-numeric:tabular-nums}
.dial .dl{font:400 10px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;
  color:var(--label3)}

/* ── CAPSULES — the rich module family the plain rows were standing in for.
   A capsule carries a mark, a name, a state and a figure, and the figure is a ring
   rather than a bare number. This is what "the crew" and "the work" always needed. */
.caps{display:grid;gap:12px}
.caps--3{grid-template-columns:repeat(3,minmax(0,1fr))}
.caps--6{grid-template-columns:repeat(6,minmax(0,1fr))}
.cap{background:var(--card);border-radius:var(--r-card);padding:14px;display:grid;gap:11px;
  align-content:start;text-decoration:none;color:inherit;position:relative;overflow:hidden;
  transition:background .18s cubic-bezier(.22,1,.36,1),transform .18s cubic-bezier(.22,1,.36,1)}
.cap:hover{background:var(--card-2);transform:translateY(-2px)}
.cap .top{display:flex;align-items:center;gap:11px;min-width:0}
.cap .mark{flex:none;width:44px;height:44px;border-radius:13px;display:grid;place-items:center;
  background:var(--grouped);overflow:hidden}
.cap .mark svg{width:28px;height:28px}
.cap .mark img{width:100%;height:100%;object-fit:cover}
.cap .nm{min-width:0}
.cap .nm b{font-weight:400;font-size:15px;display:block;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.cap .nm i{font-style:normal;font-size:12px;line-height:1.35;color:var(--label3);display:-webkit-box;
  -webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin-top:4px;min-height:2.7em}
.cap .foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:2px}
.cap .fee{font:700 19px/1 var(--num);font-variant-numeric:tabular-nums}
.cap .stage{display:inline-flex;align-items:center;gap:6px;height:25px;padding:0 10px;
  border-radius:999px;font:500 11.5px/1 IS,ui-sans-serif,system-ui,sans-serif;background:var(--card-2);
  color:var(--label2);justify-self:start;white-space:nowrap}
.cap:hover .stage{background:var(--grouped)}
.cap .stage svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
.cap .stage--due{background:rgba(210,160,71,.2);color:var(--ochre)}
.cap .stage--won{background:rgba(157,179,149,.22);color:var(--sage)}
.cap--person{padding:13px}
.cap--person .mark{width:46px;height:46px;border-radius:999px}
.cap--person .mark img{filter:grayscale(1) contrast(1.12)}
.cap--person .free{position:absolute;top:11px;right:11px;width:8px;height:8px;border-radius:99px;
  background:var(--sage);box-shadow:0 0 0 3px var(--card)}
/* the instrument language at capsule scale */
.mini{position:relative;width:40px;height:40px;flex:none}
.mini svg{width:40px;height:40px;display:block}
.mini .mt{fill:none;stroke:var(--grouped);stroke-width:4}
.mini .mp{fill:none;stroke:var(--acc);stroke-width:4;stroke-linecap:round;
  transform:rotate(-90deg);transform-origin:50% 50%}
.mini .mp.ok{stroke:var(--sage)} .mini .mp.mut{stroke:var(--label3)}
.mini b{position:absolute;inset:0;display:grid;place-items:center;
  font:700 13px/1 var(--num);font-variant-numeric:tabular-nums}

/* ── this week on film. Motion is the luxury signal; it never asks to be watched. ── */
.reel{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}
.pn-video{position:relative;border-radius:var(--r-card);overflow:hidden;background:#131A21;
  aspect-ratio:16/10;margin:0}
.pn-video video{width:100%;height:100%;object-fit:cover;display:block;
  background:#131A21}
.pn-video .scrim{position:absolute;inset:0;
  background:linear-gradient(to top,rgba(11,15,20,.92),rgba(11,15,20,.05) 60%,transparent)}
.pn-video figcaption{position:absolute;left:15px;right:15px;bottom:13px;z-index:2;color:#F4F7FA}
.pn-video .k{font:400 10px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:#C7CFD8;display:block}
.pn-video figcaption b{font:700 19px/1 IS;letter-spacing:-.032em;text-transform:uppercase;
  display:block;margin-top:7px;transform:skewX(-9deg);transform-origin:0 100%;
  padding-right:.1em}
.pn-video .fig{position:absolute;right:13px;top:11px;z-index:2;color:#fff;
  font:700 22px/1 var(--num);font-variant-numeric:tabular-nums;
  text-shadow:0 2px 12px rgba(0,0,0,.65)}

/* ── the decision. The one light surface, and the only prominent button. ─────────── */

.decision .rings{position:absolute;right:-64px;top:-84px;width:280px;height:280px;opacity:.08;
  pointer-events:none}
.decision .b{flex:1;min-width:0;position:relative}

.decision p{color:var(--bone-dim);font-size:14px;margin-top:13px;max-width:48ch}
.decision button{flex:none;border:0;cursor:pointer;background:var(--acc);color:var(--acc-ink);
  min-height:50px;padding:0 26px;border-radius:var(--r-ctl);
  font:700 15px/1 IS,ui-sans-serif,system-ui,sans-serif}
.decision button:active{transform:scale(.985)}
.decision button:focus-visible{outline:2px solid var(--bone-ink);outline-offset:3px}

@media (max-width:980px){
  .screen{grid-template-columns:1fr}
  .side{display:none}
  .summary{grid-template-columns:1fr}
  .reel{grid-template-columns:1fr 1fr}
  .caps--6{grid-template-columns:repeat(3,1fr)}
  .caps--3{grid-template-columns:1fr}
}
@media (max-width:720px){
  body{height:auto}
  .pad{padding:0;height:auto;display:block}
  .dev{width:100%;max-height:none;height:auto;border-radius:0;padding:0;box-shadow:none}
  .screen{border-radius:0;height:auto}
  .content{overflow:visible}
  :root{--inset:14px}
  h1{font-size:29px}
  .titlerow{flex-direction:column;align-items:flex-start;gap:16px}
  .figs{gap:22px;overflow-x:auto;width:100%;padding-bottom:6px}
  .figs div{flex:none;text-align:left}
  .decision{flex-direction:column;align-items:stretch;gap:18px;padding:22px 18px}
  .decision button{width:100%}
  .reel{grid-template-columns:1fr}
  .caps--6{grid-template-columns:1fr 1fr}
}

/* ══════════════════════════════════════════════════════════════════════════════
   VESPER · BATCH 1b — the components Jon's mandate needs that Batch 1 did not carry.
   Written to the same five laws. No per-theme overrides; tokens only.
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── THE MARK, TOP-LEFT (CEO ruling 2026-08-16) ───────────────────────────────
   Position zero of the screen. The rail head carries the product; the app bar
   now carries WHO YOU ARE, which is the thing that changes as you play. */

.appbar .agency{display:flex;align-items:center;gap:10px;min-width:0;margin-right:auto}
.appbar .agency .crest{flex:none;width:30px;height:30px;border-radius:10px;display:grid;
  place-items:center;background:var(--card)}
.appbar .agency .who b{display:block;font:600 13.5px/1.1 IS,ui-sans-serif,system-ui,sans-serif;color:var(--label)}
.appbar .agency .who i{display:block;font-style:normal;font:400 11px/1 var(--mono);
  letter-spacing:.09em;text-transform:uppercase;color:var(--label3);margin-top:4px}

/* ── SEASON-WEEK, GRAPHICALLY ─────────────────────────────────────────────────
   Design revision v3: which week of the season is a fact the player used to have
   to go find (buried in the rail count or the Season room). It now sits right
   beside the agency name as its own small instrument — a progress ring round
   the season, not a second line of text — so "who you are" and "where you are"
   read as one identity unit at the top of every room. */
.appbar .agency .season{flex:none;display:flex;align-items:center;gap:8px;
  padding-left:10px;margin-left:2px;border-left:1px solid var(--sep)}
.appbar .agency .season svg{flex:none;transform:scaleY(-1)}
.appbar .agency .season__trk{fill:none;stroke:var(--sep);stroke-width:2.4}
.appbar .agency .season__arc{fill:none;stroke:var(--acc);stroke-width:2.4;
  stroke-linecap:round;transition:stroke-dashoffset .4s cubic-bezier(.22,1,.36,1)}
.appbar .agency .season b{font:600 12.5px/1 var(--mono);letter-spacing:.02em;color:var(--label)}
.appbar .agency .season b i{font-style:normal;font-weight:400;color:var(--label3)}
@media (max-width:760px){
  .appbar .agency .season b i,.appbar .agency .season{gap:6px}
  .appbar .agency .season{padding-left:8px}
}

/* ── THE TOP-TRUMPS CREW CARD ─────────────────────────────────────────────────
   Jon: keep the top-trumps detail on each member of staff. A capsule with one
   ring is a summary; top trumps is a COMPARISON INSTRUMENT — you must be able to
   read one person against another down a column without opening anything. So the
   bars are a fixed set, in a fixed order, on a shared scale. That is the whole
   mechanic: same rows, same order, every card.
   Law 5 holds — every bar is a real rated value, never decoration. */
.trump{background:var(--card);border-radius:var(--r-card);overflow:hidden;display:grid;
  align-content:start;text-decoration:none;color:inherit;position:relative;
  transition:background .18s cubic-bezier(.22,1,.36,1),transform .18s cubic-bezier(.22,1,.36,1)}
.trump:hover{background:var(--card-2);transform:translateY(-2px)}
.trump .port{position:relative;height:132px;overflow:hidden;background:var(--grouped)}
.trump .port img{width:100%;height:100%;object-fit:cover;object-position:50% 22%;display:block;
  filter:grayscale(1) contrast(1.08)}
.trump .port .scrim{position:absolute;inset:0;
  background:linear-gradient(to top,rgba(15,20,25,.88),rgba(15,20,25,.05) 62%,transparent)}
/* the overall — the one number you compare first, so it gets the instrument */
.trump .ovr{position:absolute;right:11px;top:11px;z-index:2;width:42px;height:42px;
  border-radius:12px;display:grid;place-items:center;background:rgba(12,17,22,.72);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  font:700 18px/1 var(--num);font-variant-numeric:tabular-nums;color:#F4F7FA}
.trump .port .nm{position:absolute;left:13px;right:60px;bottom:11px;z-index:2;color:#F4F7FA}
.trump .port .nm b{display:block;font:600 15px/1.15 IS,ui-sans-serif,system-ui,sans-serif;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.trump .port .nm i{display:block;font-style:normal;font:400 10.5px/1 var(--mono);
  letter-spacing:.14em;text-transform:uppercase;color:#C6CFD8;margin-top:5px}
.trump .bars{padding:11px 13px 13px;display:grid;gap:7px}
.trump .bar{display:grid;grid-template-columns:56px minmax(0,1fr) 26px;align-items:center;gap:9px}
.trump .bar span{font:400 9.5px/1 var(--mono);letter-spacing:.11em;text-transform:uppercase;
  color:var(--label3)}
.trump .bar i{height:5px;border-radius:99px;background:var(--grouped);position:relative;
  overflow:hidden;display:block}
.trump .bar i::after{content:"";position:absolute;inset:0 auto 0 0;width:var(--v,50%);
  border-radius:99px;background:var(--label3)}
/* the discipline this person OWNS is the only accented bar — CEO-62: a CD must not
   out-read the CFO on Commercials. The accent names the specialism, it does not rank. */
.trump .bar.own i::after{background:var(--acc)}
.trump .bar b{font:700 11.5px/1 var(--num);font-variant-numeric:tabular-nums;text-align:right;
  color:var(--label2)}
.trump .foot{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:0 13px 13px}
.trump .fee{font:700 15px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label)}
.trump .free{width:8px;height:8px;border-radius:99px;background:var(--sage);flex:none}

/* ── THE CLIENT CARD ──────────────────────────────────────────────────────────
   Jon: keep the imagery for each client. A 44px avatar is a favicon; a client is
   a BRAND and arrives as a picture. The sector photograph is the identity. */
.client{position:relative;border-radius:var(--r-card);overflow:hidden;background:var(--card);
  min-height:168px;display:block;text-decoration:none;color:inherit;
  transition:transform .18s cubic-bezier(.22,1,.36,1)}
.client:hover{transform:translateY(-2px)}
.client img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.client .scrim{position:absolute;inset:0;
  background:linear-gradient(to top,rgba(13,18,24,.94),rgba(13,18,24,.22) 58%,rgba(13,18,24,.05))}
.client .txt{position:absolute;left:15px;right:15px;bottom:13px;z-index:2;color:#F4F7FA}
.client .k{font:400 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:#CBD4DD}
.client h3{font:700 20px/1 IS;letter-spacing:-.03em;text-transform:uppercase;margin-top:8px;
  transform:skewX(-9deg);transform-origin:0 100%;padding-right:.1em}
.client .fee{position:absolute;right:13px;top:12px;z-index:2;
  font:700 15px/1 var(--num);font-variant-numeric:tabular-nums;color:#fff;
  text-shadow:0 2px 10px rgba(0,0,0,.6)}
.client .stage{position:absolute;left:15px;top:12px;z-index:2;display:inline-flex;
  align-items:center;height:23px;padding:0 9px;border-radius:999px;
  font:600 10.5px/1 IS,ui-sans-serif,system-ui,sans-serif;background:rgba(12,17,22,.66);color:#E6ECF2;
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.client .stage--due{background:rgba(210,160,71,.9);color:#1A1712}
.client .stage--live{background:var(--acc);color:var(--acc-ink)}

.caps--4{grid-template-columns:repeat(4,minmax(0,1fr))}
@media (max-width:980px){.caps--4{grid-template-columns:repeat(2,1fr)}}
@media (max-width:720px){.caps--4{grid-template-columns:1fr 1fr}}

/* ── THE SET-PIECE FRAME ──────────────────────────────────────────────────────
   Jon: keep the laptop animations for pitches and campaign work, "but make them
   simpler and framed better". Batch 1 had no set-piece at all.
   Simpler = the frame stops competing. One surface, one caption, one action. The
   film is the content, so the chrome around it is a hairline and nothing else. */
.setpiece{position:relative;border-radius:var(--r-card);overflow:hidden;background:var(--film-black);
  display:grid;grid-template-rows:minmax(0,1fr) auto}
.setpiece .stage{position:relative;aspect-ratio:16/9;background:var(--film-black);overflow:hidden}
.setpiece video,.setpiece .stage>img{width:100%;height:100%;object-fit:cover;display:block}
.setpiece .vig{position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 42%,transparent 42%,rgba(6,9,13,.55) 100%)}
.setpiece .cue{position:absolute;left:18px;top:16px;z-index:2;display:inline-flex;
  align-items:center;gap:8px;height:26px;padding:0 12px 0 9px;border-radius:999px;
  background:rgba(10,14,19,.7);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  font:600 11px/1 IS,ui-sans-serif,system-ui,sans-serif;color:#E8EEF4}
.setpiece .cue em{width:7px;height:7px;border-radius:99px;background:var(--acc);font-style:normal}
.setpiece .bar{display:flex;align-items:center;gap:16px;padding:14px 18px;background:var(--card)}
.setpiece .bar .t{flex:1;min-width:0}
.setpiece .bar .t b{display:block;font:700 17px/1.1 IS;letter-spacing:-.028em}
.setpiece .bar .t i{display:block;font-style:normal;font-size:13px;color:var(--label3);margin-top:4px}

/* ⛔ The rail mark: sized HERE, never inline. An inline `display:block` outranks the
   `.wm--light{display:none}` class rule, so both authored marks paint at once — which is
   exactly what shipped in the first render. Theme switching by class only works if nothing
   inline is fighting it. */

.side .brandhead .wm--dark{display:block}
.side .brandhead .wm--light{display:none}

/* ══════════════════════════════════════════════════════════════════════════════
   VESPER · BATCH 1c — STRUCTURE. CEO, on the first live render: "I can barely tell
   they are different sections — where's the clear space, the big headline sections,
   the structure? How the fuck am I supposed to know what to do?"

   He is right, and it is the same defect I flagged in Batch 1's own render. `.shead`
   was 12px mono in --label3: a LABEL, not a heading. Tertiary colour, tertiary size,
   sitting 26px from the cards above it. Nothing announced a new section, so the page
   read as one continuous mat of cards.

   Three things fix it, and none of them is decoration:
     1. A section gets a real MASTHEAD — mono kicker over a big display line, the
        headline system already approved (CEO-83), skewed to match the room and
        client plates so the page has one voice.
     2. CLEAR SPACE does the dividing. Law 1 says tone carries structure and we draw
        no borders, so the separation has to be air, and 26px is not air.
     3. Every section says WHAT TO DO in plain English. CEO-54 is a repeat miss:
        "every page must signpost what to do now". One decision panel at the top does
        not survive scrolling — by the time you are among the crew it is gone. So the
        instruction travels with the section it belongs to.
   ══════════════════════════════════════════════════════════════════════════════ */
section{padding:0 var(--inset)}
.shead{align-items:baseline;justify-content:space-between;gap:16px;display:block;padding:64px 4px 20px}
section:first-of-type .shead{padding-top:34px}
.shead .kick{display:flex;align-items:center;gap:9px;
  font:400 11px/1 var(--mono);letter-spacing:.18em;text-transform:uppercase;color:var(--acc)}
.shead .kick::after{content:"";height:1px;flex:1;
  background:color-mix(in srgb,var(--label) 13%,transparent)}

/* the instruction. Not a subtitle — a sentence telling you what this section is for and
   what to do with it. Plain English, never a label. */

.shead .do b{color:var(--label);font-weight:600}
.shead .hicon{width:14px;height:14px;stroke:var(--acc);opacity:1}

/* ── THE DECISION, REBUILT AS A CONTROL SURFACE ───────────────────────────────
   CEO: "this panel should clearly tell me the headlines I need to know then let me
   ACTION that." The first version stated ONE thing and then offered one button that
   did something else — ending the week. So the headline and the control were about
   different subjects, which is why it read as a banner rather than a place to work.

   Now it is a numbered list of the things that need him, each carrying its OWN action,
   with ending the week held separately as the consequence of clearing them. Law 4 still
   holds: one bone surface, and it is this one. */

.decision .dk{display:block;font:400 11px/1 var(--mono);letter-spacing:.17em;
  text-transform:uppercase;color:color-mix(in srgb,var(--acc) 82%,var(--bone-ink))}
.decision h2{font:700 clamp(23px,2.3vw,30px)/1.03 IS;letter-spacing:-.035em;text-transform:uppercase;transform:skewX(-9deg);transform-origin:0 100%;padding-right:.1em;margin-top:11px}
.decision .todo{list-style:none;margin:19px 0 0;padding:0;display:grid;gap:0}
.decision .todo li{display:flex;align-items:center;gap:14px;padding:13px 0;
  border-top:1px solid color-mix(in srgb,var(--bone-ink) 13%,transparent)}
.decision .todo .w{flex:none;width:22px;height:22px;border-radius:99px;display:grid;
  place-items:center;background:color-mix(in srgb,var(--acc) 17%,transparent);
  color:color-mix(in srgb,var(--acc) 88%,var(--bone-ink));font:700 11px/1 SG,sans-serif}
.decision .todo .tx{flex:1;min-width:0;font-size:14.5px;line-height:1.4;color:var(--bone-dim)}
.decision .todo .tx b{color:var(--bone-ink);font-weight:600}
.decision .todo .go{flex:none;text-decoration:none;white-space:nowrap;
  display:inline-flex;align-items:center;min-height:36px;padding:0 15px;border-radius:999px;
  background:color-mix(in srgb,var(--bone-ink) 8%,transparent);color:var(--bone-ink);
  font:600 13px/1 IS,ui-sans-serif,system-ui,sans-serif;
  transition:background .16s cubic-bezier(.22,1,.36,1)}
.decision .todo .go:hover{background:color-mix(in srgb,var(--bone-ink) 15%,transparent)}
/* ending the week is the CONSEQUENCE of the list, not another item in it */

@media (max-width:980px){
  .decision{flex-direction:column;gap:20px}
  .decision .end{align-items:stretch;width:100%}
  .decision .end button{width:100%}
}
/* THE MARK, MEASURED NOT NAMED. Batch 1 says two files exist and the only decision is which
   the tone calls for — but BOTH are light-ink: pitchnoir-dark.png reads mean luminance 197,
   pitchnoir-white.png 255. The only dark-ink mark in the folder is pitchnoir-color.png (56).
   The pale slate rail therefore takes -color; the light theme's DARK rail takes -white. */

:root[data-theme="light"] .side .brandhead .wm--dark{display:none}
:root[data-theme="light"] .side .brandhead .wm--light{display:block}

/* ── SEASON RIBBON: COMPACT + FUNCTIONAL ──────────────────────────────────────
   CEO: "make this overall progress section more functional and compact."
   It was two rows — twelve chips at 30px, then a five-item legend on its own line —
   about 90px of vertical space to say "you are in week 10".

   Compact: one row. The legend goes; the colours are already explained in the help
   sheet, and a permanent key for something you learn once is rent charged forever.
   Functional: the row now ENDS IN A TALLY — 6 won, 3 flat, 2 to play — which is the
   thing you actually want off a progress bar and which twelve chips never told you.
   Each chip carries a title so the colour is still readable on hover.
   The current week no longer widens to fit a word; it is the same cell, filled. */
.seasonbar{display:grid;gap:9px;padding:0 var(--inset) 2px}
.seasonrow{display:flex;align-items:center;gap:14px}
.season{display:flex;flex:1;min-width:0;gap:4px}
.wk{flex:1;min-width:0;background:var(--card);display:grid;place-items:center;font:500 11px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label3);position:relative;height:22px;border-radius:6px;font-size:10.5px}
.wk.now{background:var(--acc);color:var(--acc-ink);font-weight:700;flex:1;font-family:var(--num);font-size:11px;letter-spacing:0}
.stally{flex:none;display:inline-flex;align-items:center;gap:7px;
  font:400 11.5px/1 IS,ui-sans-serif,system-ui,sans-serif;color:var(--label3);white-space:nowrap}
.stally b{font:700 12.5px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label2)}
.stally i{width:3px;height:3px;border-radius:99px;background:var(--sep);margin:0 3px}

/* ── THE MARK, AT A SIZE ITS OWN TEXTURE SURVIVES ─────────────────────────────
   CEO, twice: "log treatment a disaster". It was, and not because of the file.
   Every authored master is a DISTRESSED RASTER at 1600x302. I was drawing it 26px
   tall — an 8.5% reduction — and hand-distressed edges do not survive that. The
   texture stops reading as ink damage and starts reading as dirt on the screen.
   There is no vector master in the folder to fall back to.
   The brand guard forbids recolouring, filtering and masking, so the only honest
   lever is SIZE. At 40px the distress reads as the treatment it is. */
.side .brandhead{margin-bottom:6px;border-bottom:1px solid rgba(128,140,155,.26);padding:18px 12px 18px}
.side .brandhead .wm{height:40px;width:auto;image-rendering:auto}

/* ── THE SEASON CHIP THAT LOOKED BROKEN ───────────────────────────────────────
   Week 11 carried a deadline dot ON TOP of its numeral, and `.due` also tinted the
   digits ochre — so the one chip that meant "something lands here" was the one chip
   that looked like a rendering fault. The dot moves to the corner of the cell and
   the numeral keeps the normal colour: the marker marks, it does not deface. */
.wk.due{color:var(--label3)}
.wk.due::after{content:"";position:absolute;border-radius:99px;background:var(--ochre);top:3px;right:3px;width:4px;height:4px}

/* ── THE DECISION PANEL WAS TALLER THAN ITS CONTENT ───────────────────────────
   The action column stretched the full height, so the button floated in a void with
   the label stranded above it. Centre it against the list it belongs to. */
/* THE ACCENT FOLLOWS THE SURFACE, NOT THE THEME — third time this has bitten (the pub, the
   board, and now here). The decision slab is --bone, which INVERTS: pale in dark, ink in
   light. So in the light pack the canon's burnt orange landed on a near-black slab and read
   as muddy maroon — legible at 5.98:1 and still wrong, because the brand orange had gone.
   A dark surface takes the dark-context pair whatever theme is bought. */
:root[data-theme="light"] .decision{--acc:#F97316; --acc-ink:#07080C}
.decision{background:var(--bone);color:var(--bone-ink);border-radius:var(--r-card);display:flex;position:relative;overflow:hidden;margin-top:14px;align-items:flex-start;gap:32px;padding:24px 26px}

/* ── GUIDE, OFF-HOURS, AND THE DECISION'S OWN PHOTOGRAPH ──────────────────────
   CEO, 2026-08-16: "'what happens here' should be in top nav line rename it
   'GUIDE'"; "in Nav you need to structure it better"; "This 'Before you end the
   week' panel is ugly and needs imagery".
   Three components, one rule each. */

/* 1 · GUIDE. Same instrument as .pn-help, now a permanent fixture of the app bar
   instead of a button hiding under each page title. It sits AFTER the agency
   lockup and BEFORE the separator, so the bar reads: who you are · how this works
   · what you have · everything else. */
.appbar .guide{flex:none;border:0;cursor:pointer;display:inline-flex;align-items:center;
  gap:8px;height:36px;padding:0 15px 0 10px;border-radius:999px;background:var(--card);
  color:var(--label2);font:500 13px/1 IS,ui-sans-serif,system-ui,sans-serif;
  transition:background .16s cubic-bezier(.22,1,.36,1),color .16s cubic-bezier(.22,1,.36,1)}
.appbar .guide:hover{background:var(--card-2);color:var(--label)}
.appbar .guide i{width:20px;height:20px;border-radius:99px;background:var(--card-2);
  display:grid;place-items:center;font:700 12px/1 IN;font-style:normal;flex:none}

/* 2 · OFF HOURS. The Arcade and UpTheDuff are not work, and the rail must not let
   them read as another line on the to-do list. They take --play, never the accent,
   and they NEVER carry a count badge — a badge would make leisure look owed. */
/* MEASURED, not eyeballed: --play-dim (#AC9670) on the pale rail (#DDE3EA) is 2.21:1 —
   a straight AA failure, and the neon rail is worse at 2.54:1. Leisure is signalled by
   the ICON in --play and by the section header; the LABEL takes --rail-dim (5.37:1).
   Tone carries structure — it never buys it at the cost of legibility. */
/* Arcade and Up The Duff are off-hours and must READ as off-hours. --rail-dim is the right
   quiet ink for the rail's pale ground (6.07:1 dark / 6.5 light / 5.41 neon) — but this rule
   sits AFTER the [aria-current] rule and beat it on source order, so when you were standing
   IN the Arcade its own label went dim-slate onto the dark current slab: 2.21:1, and the room
   you are in was the one you could not read. Quiet is a resting state, never a selected one. */
.side a.side--play{color:var(--rail-dim)}
.side a.side--play svg{stroke:var(--play);opacity:.9}
.side a.side--play[aria-current]{color:var(--rail)}
.side a.side--play:hover{color:var(--rail-ink)}
.side a.side--play .c{display:none}

/* 3 · THE PANEL'S OWN PHOTOGRAPH. The right-hand column previously held a decorative
   ring set — ornament, which law 5 forbids: instruments are gauges driven by real
   values or they are not drawn. It is replaced by a picture of the thing the list is
   actually about: Thursday's pitch. The caption is the appointment, so the image
   carries information, not mood. */
.decision .shot{margin:0;width:216px;border-radius:16px;overflow:hidden;position:relative;
  background:var(--card-2);box-shadow:0 1px 0 rgba(17,24,32,.10)}
.decision .shot img{display:block;width:100%;height:132px;object-fit:cover}

.decision .shot b{font:600 15px/1.1 IS,ui-sans-serif,system-ui,sans-serif;letter-spacing:-.01em}
/* the action column now has real content, so it aligns to that content's width */
.decision .end{align-self:stretch;display:flex;flex-direction:column;position:relative;align-items:stretch;width:216px;flex:none;justify-content:flex-start;gap:12px}
.decision .end .lab{font:400 11px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;color:var(--bone-dim);margin-top:auto;text-align:center}
.decision .end button{width:100%}
@media (max-width:980px){
  .decision .end,.decision .shot{width:100%}
  .decision .shot img{height:150px}
}

/* ── THE BRIEF ROW ────────────────────────────────────────────────────────────
   A brief leads with THE ASK (PN-CEO-52). Three tracks, left to right:
   what it looks like · what they want · what it is worth and how far it is built.
   The right track is a real gauge — stages finished out of four, counted. */
.briefs{display:grid;gap:12px}
.brief{display:flex;align-items:stretch;gap:0;text-decoration:none;overflow:hidden;
  background:var(--card);border-radius:var(--r-card);color:var(--label);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 8%,transparent);
  transition:transform .18s cubic-bezier(.22,1,.36,1),box-shadow .18s cubic-bezier(.22,1,.36,1)}
.brief:hover{transform:translateY(-2px);
  box-shadow:0 10px 30px rgba(0,0,0,.24),inset 0 0 0 1px color-mix(in srgb,var(--label) 14%,transparent)}
.brief .pic{position:relative;flex:none;width:216px;overflow:hidden}
.brief .pic img{width:100%;height:100%;object-fit:cover;display:block}
.brief .pic .scrim{position:absolute;inset:0;
  background:linear-gradient(90deg,rgba(8,11,15,.10),rgba(8,11,15,.55))}
/* CORNER-TAB, not a pill — 19 Aug: badges were reading as a third pill/chip lookalike
   (buttons, .chip and .badge all rounded-and-floating). A badge is a status FLAG, not an
   action, so it gets its own family: flush to the card's actual top-left corner, clipped
   on the trailing edge like a cut paper tag, no radius at all. */
.brief .badge{position:absolute;left:0;top:14px;z-index:1;
  /* top:14px (not 0) so the tab clears the card's own border-radius arc — flush at 0
     got bitten by the curve and read as a lozenge, not a cut corner. font stays 600:
     JB/mono only ships a 400 face (see @font-face), so 700 was a browser-synthesised
     faux-bold smearing a 10px glyph. clip-path only (no backdrop-filter) — Safari paints
     backdrop-filter as an unclipped rect under clip-path, and the plate is .86 opaque
     already so the blur wasn't earning its keep. */
  font:600 10px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  padding:7px 15px 6px 10px;background:rgba(10,14,19,.86);color:#fff;
  clip-path:polygon(0 0,100% 0,calc(100% - 10px) 100%,0 100%)}
/* the accent means primary action or live/urgent, and nothing else */
.brief .badge--live{background:var(--acc);color:var(--acc-ink)}
.brief .badge--ok{background:rgba(10,14,19,.86);color:#AFC3A8}  /* the badge sits on its own pinned dark plate over the photograph, so its ink is pinned too — the light theme's deep-green --sage measured 1.17:1 here */
.brief .body{flex:1;min-width:0;padding:20px 22px;display:grid;align-content:center;gap:7px}
.brief .body .k{font:400 10.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--label3)}
.brief .body h3{font:600 19px/1.22 IS,ui-sans-serif,system-ui,sans-serif;letter-spacing:-.016em;
  color:var(--label);text-wrap:balance;max-width:46ch}
.brief .body p{font-size:14px;line-height:1.45;color:var(--label2);max-width:60ch;margin:0}
.brief .meta{display:flex;flex-wrap:wrap;gap:6px;margin-top:4px}
.brief .chip{display:inline-flex;align-items:center;gap:6px;height:26px;padding:0 10px;
  /* --card-2 is the RAISED tone; a metadata chip is recessed, and on the raised tone the
     accent-carrying "2 days left" chip measured 3.73:1. --grouped is both the correct tone
     for what this is and the ground the accent was designed against (5.59 / 4.84 / 6.58). */
  border-radius:99px;background:var(--grouped);color:var(--label2);
  font:500 12px/1 IS,ui-sans-serif,system-ui,sans-serif}
.brief .chip--due{color:var(--acc)}
.brief .chip--due i{width:6px;height:6px;border-radius:99px;background:var(--acc);flex:none}

.brief .side2 .fee{font:700 21px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label)}
.brief .prog{width:100%;height:5px;border-radius:99px;background:var(--card-2);overflow:hidden}
.brief .prog i{display:block;height:100%;width:var(--v);border-radius:99px;background:var(--label2)}
.brief--due .prog i{background:var(--acc)}

.brief .cta{margin-top:3px;display:inline-flex;align-items:center;height:32px;padding:0 15px;
  border-radius:99px;background:var(--card-2);color:var(--label);
  font:600 13px/1 IS,ui-sans-serif,system-ui,sans-serif}
.brief:hover .cta{background:color-mix(in srgb,var(--label) 14%,transparent)}
/* work that is finished, or waiting on somebody else, recedes — it is the record */
.brief--rest .body h3{color:var(--label2);font-weight:500}
.brief--rest .pic img{filter:saturate(.72)}
.brief--lost .side2 .fee{color:var(--label3)}
@media (max-width:980px){
  .brief{flex-direction:column}
  .brief .pic{width:100%;height:150px}
  .brief .side2{width:100%;justify-items:start;text-align:left;background:var(--card)}
  .brief .prog{max-width:220px}
}

/* ── EMAIL, IN THE APP BAR ────────────────────────────────────────────────────
   Email left the rail because it is an inbound STREAM you glance at, not a room you
   browse for its own sake. The rail is for places; the bar is for state. */
.appbar .mailbtn{position:relative;flex:none;width:36px;height:36px;border-radius:999px;
  display:grid;place-items:center;background:var(--card);color:var(--label2);
  text-decoration:none;transition:background .16s cubic-bezier(.22,1,.36,1)}
.appbar .mailbtn:hover{background:var(--card-2);color:var(--label)}
.appbar .mailbtn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.appbar .mailbtn .bdg{position:absolute;top:-2px;right:-2px;min-width:17px;height:17px;
  padding:0 5px;border-radius:99px;background:var(--acc);color:var(--acc-ink);
  font:700 10px/17px SG,sans-serif;text-align:center}

/* ── FIXES FOUND BY LOOKING AT THE RENDER ─────────────────────────────────────
   1. The .shot caption went white-on-pale-sky over the Meridian skyline: the old
      gradient was tuned to a dark sportswear frame and vanished on a bright one.
      A caption's legibility cannot depend on which photograph got picked. */
.decision .shot figcaption{position:absolute;left:0;right:0;bottom:0;display:grid;gap:3px;color:#fff;padding:34px 12px 11px;background:linear-gradient(to top,rgba(6,9,13,.94) 0%,rgba(6,9,13,.72) 46%,rgba(6,9,13,0) 100%)}
.decision .shot .k{font:400 10.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:rgba(255,255,255,.92)}
/* 2. "1 of 4 stages built" wrapped to two right-aligned lines. Give the column the
      width the longest honest string needs, and stop it breaking. */
.brief .side2{flex:none;padding:20px 22px;display:grid;align-content:center;gap:9px;justify-items:end;text-align:right;background:var(--grouped);width:190px}
.brief .pk{font:400 11px/1.3 var(--mono);letter-spacing:.06em;color:var(--label3);white-space:nowrap}

/* ═══ TASTE PASS · 2026-08-16 ═══════════════════════════════════════════════════
   CEO: "you are just being lazy with this repetition" — and the charge is correct.
   One decision component was stamped onto three rooms with the nouns swapped. Three
   pages opened with the same white slab, the same numbered list, the same photograph
   in the same corner, the same orange button. That is a template, not a design.

   Four things change here. Each is a rule, not a tweak.

   1. ONE ROOM OWNS THE DECISION PANEL. The Floor is the "what do I do now" room, so
      the bone slab lives there and only there. Pitches gets a countdown board;
      Clients gets a ledger. A component earns its place per room or it does not appear.
   2. THE EXPLANATORY PARAGRAPH UNDER EVERY HEADING IS DELETED. "Each row leads with
      what they actually asked for" is the interface apologising for itself. That is
      what the Guide is for. Section heads now carry DATA, not instructions.
   3. INTER IS OFF THE BODY. It is the house face of generic software. Instrument Sans
      is already vendored, has real character in its lowercase, and is what the display
      face is cut from — so the page reads as one voice instead of two rented ones.
   4. GRAIN. This is noir. Flat navy with no tooth is a settings screen. */

body{background:var(--room);color:var(--label);-webkit-font-smoothing:antialiased;font:400 15px/1.45 IS,ui-sans-serif,system-ui,sans-serif}
.brief .body h3,.brief .cta,.brief .chip,.decision .todo .tx,.decision .todo .go,
.side a,.appbar .agency .who b,.appbar .guide,.dock a span{font-family:IS,ui-sans-serif,system-ui,sans-serif}

/* film grain: fixed, pointer-events:none, never inside a scroller (GPU repaint) */
.screen::after{content:"";position:absolute;inset:0;z-index:80;pointer-events:none;
  opacity:.055;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E")}

/* section heads carry a fact, not an instruction */
.shead .do{font-size:14.5px;line-height:1.45;color:var(--label2);margin-top:11px;max-width:62ch;display:none}
.shead .fact{display:flex;align-items:baseline;gap:26px;margin-top:14px;flex-wrap:wrap}
.shead .fact div{display:grid;gap:3px}
.shead .fact b{font:700 24px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label)}
.shead .fact span{font:400 10.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--label3)}
.shead .fact .hot b{color:var(--acc)}

/* ── PITCHES OWNS: THE BOARD ──────────────────────────────────────────────────
   A pitch is adversarial and it is timed. So the room opens on a countdown over the
   prospect's own world, with the field you are up against named underneath. Dark,
   full-bleed, one instrument — the opposite of a pale slab with a bulleted list. */
.board{position:relative;border-radius:var(--r-card);overflow:hidden;min-height:360px;
  display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:22px 40px;
  padding:30px 32px 30px;isolation:isolate}
.board>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2}
/* the frame has to hold type on BOTH sides, and the photograph behind it is not
   chosen by me — so the wash is two-axis and heavy enough for any frame */
.board::before{content:"";position:absolute;inset:0;z-index:-1;background:
  linear-gradient(100deg,rgba(6,9,13,.97) 0%,rgba(6,9,13,.90) 38%,rgba(6,9,13,.46) 72%,rgba(6,9,13,.62) 100%),
  linear-gradient(to top,rgba(6,9,13,.72),rgba(6,9,13,0) 55%)}
/* LEFT COLUMN: the countdown sits ABOVE the line it qualifies, in flow. It was
   absolutely positioned and landed on top of the headline — an ornament pretending
   to be a layout. A number this size is a column, not a sticker. */
.board .say{grid-column:1;align-self:end;max-width:30ch;color:#fff}
.board .clock{grid-column:1;align-self:start;display:flex;align-items:flex-end;gap:14px}
.board .clock b{font:700 76px/.78 SG,sans-serif;font-variant-numeric:tabular-nums;
  letter-spacing:-.055em;color:var(--acc)}
.board .clock span{font:400 11px/1.3 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,255,255,.66);max-width:8ch;padding-bottom:8px}
.board .say .k{display:block;font:400 10.5px/1 var(--mono);letter-spacing:.17em;
  text-transform:uppercase;color:var(--acc);margin-bottom:12px}
.board .say h2{font:700 clamp(26px,2.6vw,36px)/1.06 IS;letter-spacing:.006em;word-spacing:.14em;
  transform:skewX(-9deg);transform-origin:0 100%;padding-right:.14em;
  text-transform:uppercase;text-wrap:balance}
.board .say p{margin-top:13px;font-size:14.5px;line-height:1.45;color:rgba(255,255,255,.74)}
/* RIGHT COLUMN: who else is in the room, ranked, you marked */
.board .field{grid-column:2;grid-row:1;align-self:start;display:grid;gap:0;
  background:rgba(8,11,16,.72);border-radius:16px;padding:6px;
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.11)}
.board .field .fh{font:400 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:rgba(255,255,255,.52);padding:10px 12px 9px}
.board .field .r{display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:11px;
  color:rgba(255,255,255,.8);font-size:14px}
.board .field .r.you{background:rgba(255,255,255,.11);color:#fff;font-weight:600}
.board .field .r .sz{margin-left:auto;font:500 11.5px/1 var(--mono);color:rgba(255,255,255,.55)}
.board .field .r.you .sz{color:var(--acc)}
.board .act{grid-column:2;grid-row:2;align-self:end;display:grid;gap:10px}
.board .act button{border:0;cursor:pointer;background:var(--acc);color:var(--acc-ink);height:50px;
  border-radius:var(--r-ctl);font:700 15.5px/1 IS,sans-serif;letter-spacing:-.012em}
.board .act .why{font:400 10.5px/1.4 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  color:rgba(255,255,255,.62);text-align:center}
@media (max-width:980px){
  .board{grid-template-columns:minmax(0,1fr);gap:20px}
  .board .say,.board .clock,.board .field,.board .act{grid-column:1;grid-row:auto}
}

/* ── CLIENTS OWNS: THE LEDGER ─────────────────────────────────────────────────
   The book of business is money owed and dates due, so it reads like a book: ruled
   rows, right-aligned figures in tabular mono, a total under a rule. No cards. The
   one account that needs you carries the accent and the only button in the room. */
.ledger{border-radius:var(--r-card);overflow:hidden;background:var(--card);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 8%,transparent)}
.ledger .lh,.ledger .lr{display:grid;
  grid-template-columns:52px minmax(0,1fr) 130px 132px 128px;align-items:center;
  gap:18px;padding:0 24px}
.ledger .lh{height:42px;background:var(--grouped);
  font:400 10px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;color:var(--label3)}
.ledger .lh .rt,.ledger .lr .rt{text-align:right}
.ledger .lr{min-height:76px;border-top:1px solid var(--sep);text-decoration:none;color:var(--label)}
.ledger .lr:hover{background:var(--card-2)}
.ledger .lr .av{width:38px;height:38px;border-radius:11px;object-fit:cover;display:block}
.ledger .lr .who b{display:block;font:600 16px/1.2 IS,sans-serif;letter-spacing:-.012em}
.ledger .lr .who i{display:block;font-style:normal;font:400 12.5px/1.3 IS,sans-serif;
  color:var(--label3);margin-top:3px}
.ledger .lr .fee{font:700 18px/1 var(--num);font-variant-numeric:tabular-nums;text-align:right}
.ledger .lr .when{font:500 13px/1.3 var(--mono);color:var(--label2);text-align:right}
.ledger .lr .st{justify-self:end;display:inline-flex;align-items:center;gap:7px;height:28px;
  padding:0 12px;border-radius:99px;background:var(--card-2);color:var(--label2);
  font:500 12px/1 IS,sans-serif;white-space:nowrap}
.ledger .lr.hot{background:color-mix(in srgb,var(--acc) 9%,transparent)}
.ledger .lr.hot:hover{background:color-mix(in srgb,var(--acc) 14%,transparent)}
.ledger .lr.hot .when,.ledger .lr.hot .st{color:var(--acc)}
.ledger .lr.hot .st{background:color-mix(in srgb,var(--acc) 18%,transparent)}
.ledger .lr.hot .go{border:0;cursor:pointer;background:var(--acc);color:var(--acc-ink);height:36px;
  padding:0 16px;border-radius:99px;font:600 13.5px/1 IS,sans-serif;justify-self:end}
.ledger .tot{display:grid;grid-template-columns:minmax(0,1fr) 130px 260px;gap:18px;
  align-items:baseline;padding:16px 24px 18px;border-top:2px solid var(--label3);
  background:var(--grouped)}
.ledger .tot span{font:400 10.5px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:var(--label3)}
.ledger .tot b{font:700 21px/1 var(--num);font-variant-numeric:tabular-nums;text-align:right;
  color:var(--label)}
@media (max-width:980px){
  .ledger .lh{display:none}
  .ledger .lr{grid-template-columns:38px minmax(0,1fr);grid-auto-rows:auto;row-gap:8px;
    padding:16px 18px}
  .ledger .lr .fee,.ledger .lr .when,.ledger .lr .st{grid-column:2;text-align:left;justify-self:start}
  .ledger .tot{grid-template-columns:1fr auto}
}

/* ── THE PAGE TITLE WAS THE LEAST-DESIGNED TYPE ON THE PAGE ───────────────────
   Caught in my own render before it went up: every section head below is heavy
   oblique display, while the H1 above them — the biggest word on the screen —
   sat in plain sans. Two voices on one page, and the quieter one was the title.
   It now speaks the house voice, and the section heads step DOWN so the hierarchy
   runs the right way round. Weight and colour carry it; the H1 does not scream. */
.navbar h1{font:700 clamp(30px,3.1vw,42px)/1.02 IS,system-ui,sans-serif;
  letter-spacing:.008em;word-spacing:.16em;
  transform:skewX(-9deg);transform-origin:0 100%;padding-right:.16em;
  text-transform:uppercase;color:var(--label);display:inline-block}
.subtitle{font:400 13.5px/1.4 var(--mono);letter-spacing:.02em;color:var(--label2);margin-top:9px}
.shead h2{align-items:center;gap:9px;color:var(--label);margin-top:13px;transform:skewX(-9deg);transform-origin:0 100%;padding-right:.14em;display:inline-block;font:700 clamp(22px,2.2vw,29px)/1.04 IS;letter-spacing:.006em;word-spacing:.14em;text-transform:uppercase}

/* ── THE TEAM OWNS: THE DEPLOYMENT ────────────────────────────────────────────
   Six people, and the only question this room answers first is who is carrying
   work and who is standing still. So the opening instrument is one bar per PERSON,
   driven by the weeks actually assigned. An idle bar is an empty bar — and that
   emptiness, sitting in a row of full ones, is the entire point of the screen.
   It is not a decision slab, not a ledger, not a countdown. */
.deploy{background:var(--card);border-radius:var(--r-card);overflow:hidden;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 8%,transparent)}
.deploy .dh,.deploy .dep{display:grid;
  grid-template-columns:44px 190px minmax(0,1fr) 190px 108px;align-items:center;gap:20px;
  padding:0 24px}
/* the header carried its own grid (3 columns) while the rows had 5, so the label
   was squeezed into a 44px avatar column and broke over six lines. A header that
   does not share its table's grid is not a header. */
.deploy .dh{height:40px;background:var(--grouped);font:400 10px/1 var(--mono);
  letter-spacing:.15em;text-transform:uppercase;color:var(--label3);white-space:nowrap}
.deploy .dh .rt{text-align:right}
.deploy .dep{min-height:72px;border-top:1px solid var(--sep);text-decoration:none;color:var(--label)}
.deploy .dep:hover{background:var(--card-2)}
.deploy .face{width:36px;height:36px;border-radius:99px;object-fit:cover;object-position:50% 22%}
.deploy .who b{display:block;font:600 15px/1.2 IS,sans-serif;letter-spacing:-.012em}
.deploy .who i{display:block;font-style:normal;font:400 11.5px/1 var(--mono);
  color:var(--label3);margin-top:5px;letter-spacing:.04em}
.deploy .load{height:9px;border-radius:3px;background:var(--grouped);overflow:hidden}
.deploy .load i{display:block;height:100%;width:var(--v);background:var(--label2);border-radius:3px}
.deploy .job{font:400 13px/1.3 IS,sans-serif;color:var(--label2)}
.deploy .wage{font:600 14px/1 var(--num);font-variant-numeric:tabular-nums;text-align:right}
.deploy .wage .u{font-size:11px;color:var(--label3);font-weight:400}
/* idle is the state this screen exists to show, so it takes the accent and a
   hatched empty track — an empty grey bar reads as "no data", not "nobody on it" */
.deploy .dep--idle .job{color:var(--acc)}
.deploy .dep--idle .load{background:repeating-linear-gradient(115deg,
  color-mix(in srgb,var(--acc) 26%,transparent) 0 5px,transparent 5px 11px)}
.deploy .dfoot{display:flex;align-items:center;justify-content:space-between;gap:20px;
  flex-wrap:wrap;padding:16px 24px 18px;border-top:2px solid var(--label3);background:var(--grouped)}
.deploy .dfoot span{font-size:13.5px;color:var(--label2)}
.deploy .dfoot b{color:var(--acc);font:700 15px/1 var(--num)}
@media (max-width:980px){
  .deploy .dh{display:none}
  .deploy .dep{grid-template-columns:36px minmax(0,1fr);row-gap:9px;padding:15px 18px}
  .deploy .dep .load,.deploy .dep .job,.deploy .dep .wage{grid-column:2;text-align:left}
}
.trump .foot .mut{font-style:normal;font-size:11.5px;color:var(--label3)}

/* ── THE FINANCIALS OWNS: THE RUNWAY ──────────────────────────────────────────
   Clients has a ledger, which answers "what is booked". This room answers a
   different question — how many weeks until the money runs out — so it gets a
   different instrument: twelve weeks of cash IN above a zero line and cash OUT
   below it, with the weeks that have nothing banked against them marked.
   Every bar height is one of the figures printed in the table underneath. */
.runway{background:var(--card);border-radius:var(--r-card);overflow:hidden;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 8%,transparent)}
.runway .rhead{display:flex;align-items:center;gap:40px;flex-wrap:wrap;padding:26px 28px 20px}
.runway .big{display:flex;align-items:baseline;gap:14px}
.runway .big b{font:700 74px/.78 SG,sans-serif;font-variant-numeric:tabular-nums;
  letter-spacing:-.055em;color:var(--acc)}
.runway .big span{font:400 11.5px/1.35 var(--mono);letter-spacing:.13em;text-transform:uppercase;
  color:var(--label3);max-width:11ch}
.runway .rstats{display:flex;gap:34px;flex-wrap:wrap;margin-left:auto}
.runway .rstats div{display:grid;gap:4px}
.runway .rstats b{font:700 21px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label)}
.runway .rstats span{font:400 10.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--label3)}
.runway .rstats .hot b{color:var(--acc)}

/* THE CHART, REBUILT AFTER LOOKING AT IT.
   First attempt drew the IN bar directly on top of the OUT bar with no gap, so
   twelve pairs read as twelve single stacked totals — the chart said the opposite
   of what it measured. That is the same fault as the fake S-curve card: a shape
   that looks like a measurement. Money in and money out now sit either side of a
   drawn zero rule with real air between them, and the axis is labelled, because a
   chart with an implied scale is a shape and not a measurement either. */
.runway .chart{position:relative;padding:6px 28px 22px;margin-top:4px}
.runway .wks{display:grid;grid-template-columns:repeat(12,1fr);gap:9px;height:230px;
  padding-left:56px}
.runway .w{position:relative;height:100%;display:grid;
  grid-template-rows:1fr 12px 1fr}          /* in · the zero gutter · out */
.runway .w i{display:block;width:100%}
.runway .w i.in{grid-row:1;height:var(--h);align-self:end;border-radius:4px 4px 0 0;
  background:var(--sage,#8FBF9F)}
.runway .w i.out{grid-row:3;height:var(--h);align-self:start;border-radius:0 0 4px 4px;
  background:color-mix(in srgb,var(--label3) 66%,transparent)}
.runway .w em{position:absolute;left:0;right:0;bottom:-23px;text-align:center;font-style:normal;
  font:500 10.5px/1 var(--mono);color:var(--label3);font-variant-numeric:tabular-nums}
.runway .w.now em{color:var(--acc);font-weight:700}
.runway .w.due i.out{background:repeating-linear-gradient(115deg,
  color-mix(in srgb,var(--acc) 46%,transparent) 0 5px,transparent 5px 11px)}
.runway .w.due em{color:var(--acc)}
/* the zero rule sits IN the gutter, so it can never drift from the bars */
.runway .zero{position:absolute;left:28px;right:28px;top:calc(6px + 109px);height:1px;
  background:color-mix(in srgb,var(--label) 34%,transparent);z-index:1}
.runway .zero::before{content:"£0";position:absolute;left:0;top:-6px;
  font:500 10px/1 var(--mono);color:var(--label3)}
/* the scale. Two marks are enough to make every bar readable as a number. */
.runway .chart::before,.runway .chart::after{position:absolute;left:28px;
  font:500 10px/1 var(--mono);color:var(--label3);letter-spacing:.04em}
.runway .chart::before{content:"£30k in";top:8px}
.runway .chart::after{content:"£30k out";top:222px}
.runway .legend{display:flex;gap:22px;flex-wrap:wrap;margin-top:36px;
  font:400 11px/1 var(--mono);letter-spacing:.08em;color:var(--label3)}
.runway .legend span{display:inline-flex;align-items:center;gap:8px}
.runway .legend i{width:11px;height:11px;border-radius:3px;flex:none}
.runway .legend .k-in{background:var(--sage,#8FBF9F)}
.runway .legend .k-out{background:color-mix(in srgb,var(--label3) 66%,transparent)}
.runway .legend .k-due{background:repeating-linear-gradient(115deg,
  color-mix(in srgb,var(--acc) 46%,transparent) 0 4px,transparent 4px 8px)}
.runway .rfoot{display:flex;align-items:center;justify-content:space-between;gap:20px;
  flex-wrap:wrap;padding:16px 28px 18px;border-top:2px solid var(--label3);background:var(--grouped)}
.runway .rfoot span{font-size:13.5px;color:var(--label2);max-width:62ch}
.runway .rfoot b{color:var(--label);font-weight:600}
@media (max-width:980px){
  .runway .rhead{gap:22px}
  .runway .rstats{margin-left:0;gap:22px}
  .runway .wks{gap:5px;height:186px;padding-left:44px}
  .runway .zero{top:calc(6px + 87px)}
  .runway .chart::after{top:178px}
}

/* ── THE SEASON OWNS: THE LADDER ──────────────────────────────────────────────
   Twenty-five agencies, one table, and the Pilot Season promise — top five win
   Pro free — drawn ON the table as a cut line rather than promised in a banner
   nobody reads. Your row is marked; the table is ranked on money billed, because
   that is the number the game actually runs on. */
.ladder{background:var(--card);border-radius:var(--r-card);overflow:hidden;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 8%,transparent)}
.ladder .lhead{display:flex;align-items:center;gap:40px;flex-wrap:wrap;padding:26px 28px 20px}
.ladder .pos{display:flex;align-items:baseline;gap:13px}
.ladder .pos b{font:700 74px/.78 SG,sans-serif;font-variant-numeric:tabular-nums;
  letter-spacing:-.055em;color:var(--acc)}
.ladder .pos span{font:400 11.5px/1.35 var(--mono);letter-spacing:.13em;text-transform:uppercase;
  color:var(--label3);max-width:10ch}
.ladder .lstats{display:flex;gap:34px;flex-wrap:wrap;margin-left:auto}
.ladder .lstats div{display:grid;gap:4px}
.ladder .lstats b{font:700 21px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label)}
.ladder .lstats span{font:400 10.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--label3)}
.ladder .lstats .hot b{color:var(--acc)}
.ladder .th,.ladder .tr{display:grid;grid-template-columns:44px minmax(0,1fr) 132px 74px 104px;
  align-items:center;gap:18px;padding:0 28px}
.ladder .th{height:40px;background:var(--grouped);font:400 10px/1 var(--mono);
  letter-spacing:.15em;text-transform:uppercase;color:var(--label3);white-space:nowrap}
.ladder .rt{text-align:right}
.ladder .tr{min-height:52px;border-top:1px solid var(--sep);text-decoration:none;color:var(--label2)}
.ladder .tr:hover{background:var(--card-2)}
.ladder .tr .n{font:600 14px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label3)}
.ladder .tr .ag{font:500 15px/1.2 IS,sans-serif;letter-spacing:-.01em}
.ladder .tr .v{font:600 14px/1 var(--num);font-variant-numeric:tabular-nums}
/* the cut. Fifth place carries the rule, so the promise is a line on the table. */
.ladder .tr.pro .n{color:var(--sage,#8FBF9F)}
.ladder .tr.cut{border-bottom:2px solid var(--sage,#8FBF9F);position:relative}
.ladder .tr.cut::after{content:"Pro free · top five";position:absolute;right:28px;bottom:-9px;
  background:var(--card);padding:0 8px;font:500 10px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--sage,#8FBF9F)}
.ladder .tr.you{background:color-mix(in srgb,var(--acc) 10%,transparent);color:var(--label)}
.ladder .tr.you:hover{background:color-mix(in srgb,var(--acc) 15%,transparent)}
.ladder .tr.you .n,.ladder .tr.you .ag{color:var(--acc);font-weight:700}
/* form: five marks, newest right. A record, never a prediction. */
.ladder .f{display:inline-flex;gap:3px;justify-content:flex-end}
.ladder .f i{width:9px;height:16px;border-radius:2px;background:var(--card-2)}
.ladder .f i.w{background:var(--sage,#8FBF9F)}
.ladder .f i.d{background:var(--label3)}
.ladder .f i.l{background:color-mix(in srgb,var(--clay,#CE7B5E) 78%,transparent)}
.ladder .lfoot{display:flex;align-items:center;justify-content:space-between;gap:20px;
  flex-wrap:wrap;padding:22px 28px 18px;border-top:2px solid var(--label3);background:var(--grouped)}
.ladder .lfoot span{font-size:13.5px;color:var(--label2);max-width:62ch}
.ladder .lfoot b{color:var(--acc);font-weight:700}

/* the clock: twelve weeks with room to say what happened in each */
.clockstrip{display:grid;grid-template-columns:repeat(12,1fr);gap:8px}
.clockstrip .ck{background:var(--card);border-radius:14px;padding:13px 11px 15px;display:grid;
  gap:5px;align-content:start;min-height:112px;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 7%,transparent)}
.clockstrip .ck em{font-style:normal;font:500 10.5px/1 var(--mono);color:var(--label3);
  font-variant-numeric:tabular-nums}
.clockstrip .ck b{font:600 13.5px/1.15 IS,sans-serif;color:var(--label)}
.clockstrip .ck i{font-style:normal;font-size:11.5px;line-height:1.3;color:var(--label3)}
.clockstrip .ck.won b{color:var(--sage,#8FBF9F)}
.clockstrip .ck.flat b{color:var(--label2)}
.clockstrip .ck.now{background:var(--acc);box-shadow:none}
.clockstrip .ck.now em,.clockstrip .ck.now b,.clockstrip .ck.now i{color:var(--acc-ink)}
.clockstrip .ck.due b{color:var(--label3)}
.clockstrip .ck.wah{box-shadow:inset 0 0 0 1.5px var(--acc)}
.clockstrip .ck.wah b{color:var(--acc)}
@media (max-width:980px){
  .ladder .th{display:none}
  .ladder .tr{grid-template-columns:34px minmax(0,1fr) auto;row-gap:6px;padding:12px 18px}
  .ladder .tr .f{grid-column:3}
  .ladder .tr.cut::after{right:18px}
  .clockstrip{grid-template-columns:repeat(4,1fr)}
}

/* ═══ THE BUTTON MATERIAL · glass and gradient ══════════════════════════════════
   CEO, 2026-08-17: "cant you introduce some glass & Gradient on all buttons?"

   Written ONCE, for every control, and derived from --acc with color-mix so a pack
   the player buys reskins it for free — no per-theme gradient stops to keep in sync,
   which is exactly how the accent got out of sync in the first place.

   THE FILL (primary). A top-lit gradient: --acc lifted toward white at the top stop,
   deepened at the bottom, so the control reads as a lozenge with a light source
   rather than a flat rectangle. A 1px inset highlight along the top edge is the
   glass; a soft accent-tinted drop shadow lifts it off the surface. Press pushes the
   gradient down and shrinks the shadow — the button physically depresses.

   THE GHOST (secondary). Actual glass: a translucent fill over a backdrop blur with
   a hairline inset border. It is a SURFACE, not an outline — which is what stops the
   two ranks reading as the same button in two colours.

   TWO THINGS THIS ALSO FIXES, both latent bugs found while writing it:
   · every hover was hardcoded #DD3C01 — a bright orange that ignored the pack, so
     hovering in neon flashed ORANGE over magenta. Now derived from --acc.
   · the gradient changes what the ink sits on, so the contrast probe re-measures it.
     The worst stop is the one that counts and the sweep is the proof, not my eye. */
:is(.pn-btn, .decision button, .board .act button, .ledger .lr.hot .go,
       .decision .todo .go--now, .task .go--now, .desk__commit button,
       .night .buy, .cab .play){
  background-image:linear-gradient(180deg,
    color-mix(in srgb, var(--acc) 88%, #fff) 0%,
    var(--acc) 52%,
    color-mix(in srgb, var(--acc) 92%, #000) 100%);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 34%, transparent),
    inset 0 -1px 0 color-mix(in srgb, #000 16%, transparent),
    0 2px 10px color-mix(in srgb, var(--acc) 30%, transparent),
    0 1px 2px color-mix(in srgb, #000 24%, transparent);
  transition:box-shadow .18s cubic-bezier(.22,1,.36,1),
             background-position .18s cubic-bezier(.22,1,.36,1),
             transform .12s cubic-bezier(.22,1,.36,1);
  background-size:100% 200%;background-position:0 0}
:is(.pn-btn, .decision button, .board .act button, .ledger .lr.hot .go,
       .decision .todo .go--now, .task .go--now, .desk__commit button):hover{
  background-position:0 30%;
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 42%, transparent),
    inset 0 -1px 0 color-mix(in srgb, #000 16%, transparent),
    0 4px 16px color-mix(in srgb, var(--acc) 42%, transparent),
    0 1px 2px color-mix(in srgb, #000 26%, transparent)}
:is(.pn-btn, .decision button, .board .act button, .ledger .lr.hot .go,
       .decision .todo .go--now, .task .go--now, .desk__commit button):active{
  transform:translateY(1px);
  box-shadow:
    inset 0 2px 5px color-mix(in srgb, #000 26%, transparent),
    0 1px 4px color-mix(in srgb, var(--acc) 24%, transparent)}
/* THE GHOST RANK — glass, not an outline.

   ⛔ :not(.go--now) IS LOAD-BEARING, and it is the general form of a bug this sheet had
   already met once and patched one instance of (see the .decision .todo .go--now line
   below). Every selector in this list is DESCENDANT — 0,2,0 — while .go--now is a single
   class at 0,1,0. So the ghost silently outranked the primary anywhere a primary sat
   inside one of these containers, and the primary kept .go--now's ink while losing its
   fill. On the hires board that put WHITE ink on a near-white glass panel: "Make an offer",
   the one button that spends money, measured 1.08:1 in light. Ranking a control by
   container instead of by role is the fault; the exclusion states the role wins. */
:is(.decision .go, .decision .todo .go, .task .go, .opp .go, .brief .cta, .pn-btn--ghost):not(.go--now){
  background-image:linear-gradient(180deg,
    color-mix(in srgb, var(--bone-ink) 11%, transparent),
    color-mix(in srgb, var(--bone-ink) 6%, transparent));
  backdrop-filter:blur(10px) saturate(1.2);-webkit-backdrop-filter:blur(10px) saturate(1.2);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--bone-ink) 14%, transparent),
             inset 0 1px 0 color-mix(in srgb, #fff 22%, transparent);
  transition:box-shadow .18s cubic-bezier(.22,1,.36,1)}
:is(.decision .go, .decision .todo .go, .task .go, .opp .go, .brief .cta, .pn-btn--ghost):not(.go--now):hover{
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--bone-ink) 26%, transparent),
             inset 0 1px 0 color-mix(in srgb, #fff 28%, transparent)}
/* the filled row action is a FILL, never a ghost — this re-asserts it after the
   ghost rule above, because .decision .go--now matches both selector lists */
:is(.decision .todo .go--now){backdrop-filter:none;-webkit-backdrop-filter:none}

@media (prefers-reduced-motion: reduce){
  :is(.pn-btn,.decision button,.board .act button,.ledger .lr.hot .go,
         .decision .todo .go--now){transition:none}
}

/* ═══ CRAFT PASS · apple-design two-axis test ═══════════════════════════════════
   CEO: "ensure you are running all page designs through the design skills you
   have." Ran, and it found three real things rather than confirming my taste.

   The SURFACE axis first: these rooms are UTILITY screens, not flagship marketing
   pages, so the motion budget is near-invisible and cinematic scroll effects stay
   OFF. That part the build already honoured. The three failures were elsewhere.

   1. REDUCED MOTION WAS NEVER HONOURED. Every room autoplays looping video and
      every control animates. The mandate is absolute — motion respects the
      setting or the surface is not shippable. Video now pauses and shows its
      poster (which is why every video ships one), and transitions collapse.
   2. TAP TARGETS UNDER 44px. Real controls — the ledger's go button at 36, the
      brief's cta at 32 — were below the floor. Raised, not by padding the label
      but by giving the control its proper height.
   3. GLASS ON CONTENT. Glass is CHROME only: nav, dock, sheets. The pitch board's
      field panel is content wearing chrome's material. It keeps the blur because
      it floats over a photograph and legibility depends on it — stated as a
      deliberate exception rather than left as an accident.

   Standing exception, also stated: apple-design says light is the default and dark
   the exception. PitchNoir is noir; the dark ground is the locked art direction in
   design/STYLE_SOURCE_OF_TRUTH.md, and it is a commitment, not an omission. */
@media (prefers-reduced-motion: reduce) {
  *,*::before,*::after{animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important}
  .trump:hover,.brief:hover{transform:none}
  .dock a:hover svg{transform:none}
}
.ledger .lr.hot .go,.brief .cta,.packs button,.themes button{min-height:44px}
.brief .cta{padding:0 18px}
.ledger .lr.hot .go{height:44px;padding:0 18px}

/* ── ARCADE OWNS: THE CABINET ROW ─────────────────────────────────────────────
   Three machines, each one a game that actually exists and opens. A cabinet drawn
   for a game that is not built is the arcade version of a chart with no data, so
   there are exactly three. The screen carries a scanline because a machine has a
   tube — this is the one room where the texture is the subject rather than
   decoration on top of one. */
.cabinets{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
.cab{display:grid;text-decoration:none;color:var(--label);background:var(--card);
  border-radius:var(--r-card);overflow:hidden;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 8%,transparent);
  transition:transform .18s cubic-bezier(.22,1,.36,1)}
.cab:hover{transform:translateY(-3px)}
.cab .scr{position:relative;height:186px;overflow:hidden;background:#05080c}
.cab .scr img{width:100%;height:100%;object-fit:cover;opacity:.5;
  filter:saturate(.7) contrast(1.1)}
.cab .crt{position:absolute;inset:0;
  background:repeating-linear-gradient(to bottom,rgba(0,0,0,.34) 0 1px,transparent 1px 3px)}
.cab .mark{position:absolute;left:0;right:0;bottom:20px;text-align:center;
  font:700 30px/1 SG,sans-serif;letter-spacing:.22em;color:#fff;
  text-shadow:0 0 22px rgba(249,115,22,.65)}
.cab .plate{padding:17px 19px 19px;display:grid;gap:7px}
.cab .plate b{font:600 17px/1.15 IS,sans-serif;letter-spacing:-.015em}
.cab .plate i{font-style:normal;font-size:13.5px;line-height:1.4;color:var(--label2)}
.cab .meta{display:flex;gap:7px;flex-wrap:wrap;margin-top:3px}
.cab .chip{display:inline-flex;align-items:center;height:26px;padding:0 11px;border-radius:99px;
  background:var(--card-2);color:var(--label2);font:500 12px/1 IS,sans-serif}
@media (max-width:980px){.cabinets{grid-template-columns:1fr}.cab .scr{height:150px}}

/* ── UP THE DUFF OWNS: THE NIGHT ──────────────────────────────────────────────
   Built to the SHIPPED mechanics in DECISIONS_LOG (2026-08-15), not invented:
   one companion a night, three nights a week, six rounds to last orders, and a
   hangover that lands on NEXT week's Time. The instrument is the round counter
   and the price of the next one — everything else on the screen is the choice of
   who you spend it on.
   THEME LAW §5: the pub is pinned dark, always. It is evening. */
.night{background:var(--card);border-radius:var(--r-card);overflow:hidden;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 8%,transparent)}
.night .nhead{display:flex;align-items:center;gap:40px;flex-wrap:wrap;padding:26px 28px 20px}
.night .rounds{display:flex;align-items:baseline;gap:13px}
.night .rounds b{font:700 74px/.78 SG,sans-serif;font-variant-numeric:tabular-nums;
  letter-spacing:-.055em;color:var(--acc)}
.night .rounds span{font:400 11.5px/1.35 var(--mono);letter-spacing:.13em;text-transform:uppercase;
  color:var(--label3);max-width:12ch}
.night .nstats{display:flex;gap:34px;flex-wrap:wrap;margin-left:auto}
.night .nstats div{display:grid;gap:4px}
.night .nstats b{font:700 21px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label)}
.night .nstats span{font:400 10.5px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--label3)}
.night .nstats .hot b{color:var(--acc)}
.night .wh{font:400 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--label3);padding:0 28px 11px}
.night .who,.night .topics{padding-top:18px;border-top:1px solid var(--sep)}
.night .companions{display:grid;grid-template-columns:repeat(5,1fr);gap:11px;padding:0 28px 20px}
.cmp{display:grid;gap:6px;text-decoration:none;color:var(--label);background:var(--grouped);
  border-radius:16px;padding:13px 13px 15px;justify-items:start;
  transition:background .16s cubic-bezier(.22,1,.36,1)}
.cmp:hover{background:var(--card-2)}
.cmp img{width:46px;height:46px;border-radius:99px;object-fit:cover;object-position:50% 25%}
.cmp b{font:600 14px/1.2 IS,sans-serif;letter-spacing:-.012em}
.cmp i{font-style:normal;font-size:11.5px;line-height:1.35;color:var(--label3)}
/* the tag is the STAKE, so it is the one place tone changes per companion */
.cmp .tag{margin-top:3px;font:500 10px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;
  padding:5px 9px;border-radius:99px;background:color-mix(in srgb,var(--sage,#8FBF9F) 20%,transparent);
  color:var(--sage,#8FBF9F)}
.cmp .tag--cli{background:color-mix(in srgb,var(--ochre,#E8B45C) 20%,transparent);color:var(--ochre,#E8B45C)}
.cmp .tag--riv{background:color-mix(in srgb,var(--acc) 20%,transparent);color:var(--acc)}
.night .trow{display:grid;grid-template-columns:repeat(3,1fr);gap:11px;padding:0 28px 20px}
.night .tp{background:var(--grouped);border-radius:16px;padding:15px 16px 17px;display:grid;gap:6px}
.night .tp b{font:600 15px/1.15 IS,sans-serif}
.night .tp i{font-style:normal;font-size:12.5px;line-height:1.4;color:var(--label3)}
.night .nfoot{display:flex;align-items:center;justify-content:space-between;gap:20px;
  flex-wrap:wrap;padding:16px 28px 18px;border-top:2px solid var(--label3);background:var(--grouped)}
.night .nfoot span{font-size:13.5px;color:var(--label2);max-width:64ch}
.night .nfoot b{color:var(--acc);font-weight:700}

/* the hangover curve, printed. A cost the player cannot see is a cost they will
   not believe — and this one is charged a week after the night that earned it. */
.hang{display:grid;grid-template-columns:repeat(7,1fr);gap:10px;align-items:end;height:150px}
.hang .hb{height:100%;display:grid;grid-template-rows:1fr auto auto;align-items:end;gap:7px;
  text-align:center}
.hang .hb i{display:block;width:100%;height:var(--h);border-radius:5px 5px 0 0;
  background:color-mix(in srgb,var(--label3) 58%,transparent)}
.hang .hb em{font-style:normal;font:500 10.5px/1 var(--mono);color:var(--label3)}
.hang .hb b{font:700 15px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label2)}
.hang .hb.hot i{background:var(--acc)}
.hang .hb.hot b{color:var(--acc)}
.hang .hb.cap i{background:repeating-linear-gradient(115deg,
  color-mix(in srgb,var(--acc) 46%,transparent) 0 5px,transparent 5px 11px)}
@media (max-width:980px){
  .night .companions{grid-template-columns:repeat(2,1fr)}
  .night .trow{grid-template-columns:1fr}
}
/* A CLIENT CONTACT IS A PERSON, AND WE DO NOT HAVE HER FACE.
   The first build gave Ruth Vane a photograph of a trainer and Piers Ockham a
   skyscraper — sector art standing in for a human being. That is the same class of
   error as guessing at a character: inventing an attribute we do not hold. Agency
   staff have real portraits in assets/cast and keep them; everyone outside the
   building gets an honest monogram until a real likeness exists. */
.cmp .mono{width:46px;height:46px;border-radius:99px;display:grid;place-items:center;
  background:var(--card-2);color:var(--label2);font:600 15px/1 SG,sans-serif;letter-spacing:.06em}
.cmp .mono--wire{background:color-mix(in srgb,var(--acc) 22%,transparent);color:var(--acc)}
/* A CABINET SHOWS ITS OWN GAME.
   The first build put a hotel corridor, a cola bottle and a concert crowd behind
   POOL, DARTS and FOOSBALL — untagged sector stock standing in for the machine's
   screen, which is the same defect as the brief mastheads that showed our own
   loft (PN-CEO-64). Each cabinet now draws the game it actually launches: baize
   and a broken rack, a board with a dart in it, a table seen from above. Drawn,
   not photographed, because the honest picture of a game we built is the game. */
.cab .scr{display:grid;place-items:center;padding:14px}
.cab .scr .face{width:100%;height:100%;object-fit:contain;display:block}
.cab .scr--pool{background:radial-gradient(120% 90% at 50% 20%,#12313F,#070C11)}
.cab .scr--darts{background:radial-gradient(120% 90% at 50% 30%,#1A222C,#070C11)}
.cab .scr--foos{background:radial-gradient(120% 90% at 50% 20%,#122736,#070C11)}
.cab .mark{bottom:14px;font-size:26px;text-shadow:0 2px 18px rgba(0,0,0,.85)}

/* ── THE HEADLINES WERE DOUBLE-SLANTED AND THE WORD GAPS HAD CLOSED ───────────
   CEO: "these headlines are awful typographically." They were, and it was mine.

   Two faults compounding, both in my own taste pass earlier today:

   1. FAUX ITALIC ON TOP OF THE CANON SKEW. assets/fonts/instrument-sans.woff2
      contains NO italic — checked the file, the name table has no Italic or
      Oblique entry. So `font-style:italic` made the browser SYNTHESISE a slant,
      and the house treatment (PN-CEO-83: oblique + orange slash + mono eyebrow)
      already applies skewX(-9deg). Every headline was slanted twice, once by a
      real transform and once by a fake shear, which is what smeared the letters.
      font-style is gone; the skew — the approved treatment — stays.

   2. NEGATIVE TRACKING ON UPPERCASE. Tight tracking is for lowercase display,
      where the descender and x-height gaps carry the rhythm. Caps have no such
      gaps, so -.04em pulled the words into each other: THEFINANCIALS,
      WHERE ITGOES, THE CFO'SNOTE. Uppercase wants tracking OPEN, so it is now
      positive, and the word space is reopened explicitly with word-spacing —
      a skew shears horizontal space as well as glyphs, so the gap needs putting
      back rather than merely not being removed.

   The trailing padding-right compensates for the skew pushing the last glyph's
   top-right beyond its box, and inline-block is required or the transform has
   nothing to act on. */

/* ── THE RING ROUND THE ORANGE BUTTON ─────────────────────────────────────────
   CEO: "what does this do? this is new." It is the keyboard focus ring, and it
   only appeared in that crop because the button was focused. It is doing its job
   — but doing it badly: the global rule paints the ring in --acc, and an accent
   ring offset from an accent-FILLED button reads as a second border rather than
   as focus. A focus ring has to contrast with the thing it is on, so on filled
   controls it flips to light ink with a dark spacer between.
   Also caught here: .pn-btn was still set in IS after the body moved to
   Instrument Sans this afternoon — the primary control was the last thing on the
   page still speaking the old voice. */
.pn-btn{font-family:IS,system-ui,sans-serif;letter-spacing:-.01em}
.pn-btn:focus-visible,.decision button:focus-visible,.board .act button:focus-visible,
.ledger .lr.hot .go:focus-visible{
  outline:2px solid var(--label);outline-offset:3px;
  box-shadow:0 0 0 3px var(--grouped)}

/* ═══ PHONE · 390 ═══════════════════════════════════════════════════════════════
   The eight rooms had never been opened on a phone. When they were, the app bar
   ran off the edge — the Store was cut in half and the MENU BUTTON WAS GONE
   ENTIRELY, which is a control the player cannot reach rather than a cosmetic
   problem — and the runway's twelve weeks ran past the right edge.

   My own audit had passed all eight as "no horizontal scroll", and that was the
   instrument lying: .content carries overflow-x:hidden, so the overflow was being
   CLIPPED rather than scrolled and document.scrollWidth never grew. The check now
   measures element right edges against the viewport instead, which is the
   question that was actually being asked. A green light from a test that cannot
   see the failure is worse than no test.

   The rule applied throughout: WIDE CONTENT SCROLLS INSIDE ITS OWN CONTAINER.
   The page never scrolls sideways; a twelve-week chart does. */
@media (max-width:560px){
  /* the app bar: identity shrinks, every control stays reachable at 44px */
  .appbar{gap:8px;padding:10px 12px;flex-wrap:nowrap}
  .appbar .agency{min-width:0;flex:1 1 auto}
  .appbar .agency .crest{width:26px;height:26px}
  .appbar .agency .who b{font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .appbar .agency .who i{display:none}          /* the tier repeats in the rail sheet */
  .appbar .guide{width:44px;min-width:44px;height:44px;padding:0;justify-content:center}
  .appbar .guide i{margin:0}
  .appbar .guide{font-size:0}                    /* the ? carries it; the word does not fit */
  .appbar .guide i{font-size:13px;width:26px;height:26px}
  .appbar .mailbtn,.appbar .burger{width:44px;height:44px;min-width:44px;flex:none}
  .appbar .store{height:44px;padding:0 12px;flex:none;gap:6px}
  .appbar .store svg{display:none}
  .appbar .sep{display:none}

  /* text floor. 10px mono is legible on a 27-inch display and not on a phone. */
  .shead .kick,.subtitle,.brief .body .k,.ledger .lh,.deploy .dh,.ladder .th,
  .runway .rstats span,.ladder .lstats span,.night .nstats span,.shead .fact span,
  .clockstrip .ck em,.cab .chip,.brief .chip{font-size:11.5px}
  .runway .big span,.ladder .pos span,.night .rounds span{font-size:11.5px}

  /* wide instruments get their own scroller — the page still does not move */
  .runway .chart,.ladder .table,.deploy,.ledger,.clockstrip,.hang{
    overflow-x:auto;-webkit-overflow-scrolling:touch;
    scrollbar-width:thin}
  .runway .wks{min-width:520px}
  .runway .zero{min-width:520px;right:auto;width:520px}
  .ladder .th,.ladder .tr{min-width:520px}
  .deploy .dh,.deploy .dep{min-width:460px}
  .ledger .lh,.ledger .lr{min-width:480px}
  .clockstrip{grid-auto-flow:column;grid-auto-columns:132px;grid-template-columns:none}
  .hang{min-width:420px}
  /* a scroller needs to LOOK scrollable or nobody scrolls it */
  .runway .chart::after{content:none}
  .runway .chart,.ladder .table,.deploy,.ledger,.clockstrip{
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent);
    mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent)}

  .board{padding:22px 18px}
  .board .clock b{font-size:56px}
  .runway .big b,.ladder .pos b,.night .rounds b{font-size:56px}
  .runway .rhead,.ladder .lhead,.night .nhead{gap:18px;padding:20px 18px 16px}
  .runway .rstats,.ladder .lstats,.night .nstats{gap:20px;margin-left:0}
  .cabinets{gap:12px}
  .night .companions{grid-template-columns:1fr 1fr}
}
/* ROOT CAUSE OF THE PHONE OVERFLOW — and it is a repeat offender.
   .screen collapses to one column at mobile, but `1fr` means `minmax(auto,1fr)`
   and that auto MINIMUM is the item's min-content. The app bar's children refuse
   to shrink, so the track blew out to 604px inside a 390px viewport and every
   room quietly rendered 214px wider than the phone.
   This is the identical trap as LAW 10 this morning (the topbar collision at 834):
   a grid or flex child defaults to a minimum of its own content and drags the
   parent open. minmax(0,1fr) plus min-width:0 on the chain is the fix, and it is
   the third time today this exact mechanism has produced a bug. */
@media (max-width:980px){
  .screen{grid-template-columns:minmax(0,1fr)}
  .content,.appbar,.navbar,.titlerow,.titlerow>div{min-width:0}
  .appbar>*{min-width:0}
}
/* the dock carried six rooms at desktop widths and ran past both edges of a
   phone. It is the primary navigation, so it compacts rather than scrolls —
   a nav you have to drag sideways is a nav people stop using. */
@media (max-width:560px){
  .dock{left:8px;right:8px;transform:none;width:auto;justify-content:space-between;
    padding:6px;gap:2px}
  .dock a{min-width:0;flex:1 1 0;padding:7px 2px 6px;gap:3px}
  .dock a span{font-size:9.5px;letter-spacing:0}
  .dock a svg{width:21px;height:21px}
  .dock-split{display:none}
  .dock a .bdg{transform:translate(11px,-3px);min-width:15px;height:15px;font-size:9px;line-height:15px}
}
@media (max-width:560px){
  /* the season ribbon is twelve chips plus a tally — it scrolls in its own lane */
  .seasonbar{overflow-x:auto;-webkit-overflow-scrolling:touch;
    -webkit-mask-image:linear-gradient(to right,#000 calc(100% - 24px),transparent);
    mask-image:linear-gradient(to right,#000 calc(100% - 24px),transparent)}
  .seasonrow{min-width:560px}
  /* the decision list's actions are real controls and were 32px on a phone */
  .decision .todo .go{min-height:44px;padding:0 16px}
  .decision .todo li{flex-wrap:wrap;row-gap:10px}
  .decision .todo .tx{flex:1 1 100%}
}
/* THE TEXT FLOOR, SET BY MEASUREMENT RATHER THAN BY LISTING CLASSES.
   I first raised "the mono labels" by enumerating the selectors I could think of,
   then measured and found 75 elements still under 11px across the eight rooms —
   down to 8.3px on the /wk suffix, and a 9.5px dock label I had introduced myself
   in the compaction two edits earlier. Enumerating from memory is exactly how the
   original miss happened, so this floor is derived from the audit output: every
   class the probe reported below 11px, and nothing else.
   11px is the floor because below it the mono face loses its counters on a phone;
   the badges keep their own smaller size because they carry a single digit inside
   a coloured disc, which is a glyph doing a symbol's job, not text to be read. */
@media (max-width:560px){
  .fee .u{font-size:11px}
  .trump .bars .bar span,.dock a span,.dock--play span{font-size:11px}
  .board .field .fh,.night .who .wh,.night .topics .wh,.cmp .tag,
  .room .txt .k,.client .stage,.trump .nm i,.board .say .k,.instr .dial .dl,
  .seasonrow .slab,.season .wk,.shot .k,.pn-video .k,.cue,.footnote,
  .decision .dk,.brief .body .k,.ledger .lh,.deploy .dh,.ladder .th,
  .clockstrip .ck em,.hang .hb em,.runway .legend,.ladder .tr .n{font-size:11px}
  /* the dock label at 11px needs its lane back, so the icon gives some up */
  .dock a svg{width:19px;height:19px}
  .dock a{padding:6px 1px 5px}
}
@media (max-width:560px){
  /* raising the stat labels to the 11px floor made STRATEGY clip inside the
     top-trump bar row: at this width the label, the track and the number cannot
     share one line legibly. The label takes its own line above the gauge, which
     costs a few pixels of height and keeps the card comparable — the whole point
     of the component is reading the same four rows down a column. */
  .trump .bars .bar{display:grid;grid-template-columns:1fr auto;grid-template-rows:auto auto;
    gap:3px 8px;align-items:center}
  .trump .bars .bar span{grid-column:1;grid-row:1;letter-spacing:.1em}
  .trump .bars .bar b{grid-column:2;grid-row:1;justify-self:end}
  .trump .bars .bar i{grid-column:1/-1;grid-row:2}
  /* the rest of the sub-11px text the probe reported */
  .room .txt .k,.trump .nm i,.board .act .why,.setpiece .bar .t i,
  .pn-helpsheet .badge,.hang .hb b,.cmp i{font-size:11px}
}
@media (max-width:560px){
  /* the last of them. My earlier selectors were scoped to .room and missed the
     same class living under .client and .pn-video — measured again rather than
     assumed fixed, which is the only reason these were found. */
  .txt .k,.reel .k,figcaption .k,.shot .k{font-size:11px}
  .instr text,.summary text,svg text{font-size:11px}
}

/* ── THE DECISION ROWS HAD NO PICTURE OF WHAT THEY WERE ABOUT ─────────────────
   Three rows, each one about a specific client or a specific pair of people, and
   each led by a grey numeral in a circle. The numeral said "this is item two",
   which the player can already see; it carried no information the list did not.
   The subject of the row is now the face of the row — Halberd's world, Meridian's,
   and the two actual people who are sitting idle. Same space, information instead
   of an ordinal.
   Every one of these is checked by tools/media_guard.js against what the asset
   actually shows, so a row can no longer be illustrated with the wrong thing. */
.decision .todo .sub{width:52px;height:52px;border-radius:12px;object-fit:cover;flex:none;
  box-shadow:inset 0 0 0 1px rgba(17,24,32,.14)}
.decision .todo .faces{display:flex;flex:none;width:52px;height:52px;position:relative}
.decision .todo .faces img{width:38px;height:38px;border-radius:99px;object-fit:cover;
  object-position:50% 22%;position:absolute;box-shadow:0 0 0 2.5px var(--bone)}
.decision .todo .faces img:first-child{left:0;top:0}
.decision .todo .faces img:last-child{right:0;bottom:0}
/* the row whose deadline is nearest gets the only filled action in the list —
   three identical grey chips made every item look equally urgent, which is the
   opposite of what a to-do list is for */
/* KEEP OURS on merge: main still had color:#fff here, which is the 2.8:1 pair the
   three-theme sweep found on every accent fill. --acc-ink is the fix, not a preference. */
.decision .todo .go--now{background:var(--acc);color:var(--acc-ink);font-weight:600}

/* ═══ THE RESTRAINT PASS ═══════════════════════════════════════════════════════════
   CEO, 2026-08-17: "they all look like AI slop. Lets get the core look and feel
   polished." Run through apple-design (restraint + surface axis), interface-design
   (craft foundations) and the taste skill. Six faults found. These are the fixes, and
   they are SYSTEMIC — in the shared sheet, so all eight rooms move together. Fixing
   this per page is how it became a template in the first place.

   1 · THE HEADLINE WAS SCREAMING. A 42px oblique cap-height room name, on a page you
       reached by clicking that exact word in the rail two seconds ago. Taste skill:
       "the first heading should not scream — control hierarchy with weight and colour,
       not massive scale." Apple: type and space carry hierarchy, not size alone. The
       room name is now a QUIET LABEL and the room's INSTRUMENT is the hero — which is
       the whole premise of giving each room its own instrument.

   2 · THE ACCENT MEANT SEVEN THINGS. 27 separate `color:var(--acc)` declarations:
       eyebrows, counters, badges, chart bars, rail state, prices, headings. Apple:
       "exactly ONE accent doing the pointing." An accent on everything points at
       nothing. It now means PRIMARY ACTION and LIVE/URGENT, and nothing else — section
       eyebrows drop to the tertiary ink, where a label belongs.

   3 · NO REST. Every room ran top to bottom at one rhythm with no breathing. Apple:
       "whitespace is the feature; when unsure, add space, not an element." Section
       rhythm opened up, and the first section no longer starts hard against the header.

   4 · TWO TYPE LEVELS PRETENDING TO BE FOUR. Everything below the H1 was 13–15px.
       interface-design: "if you're only using two, your hierarchy is too flat." The
       eyebrow now genuinely recedes and the section head genuinely leads.

   5 · THE CARD WAS DOING ALL THE WORK. Rounded rectangle on slightly-different grey,
       everywhere. The Ledger already used ruled rows and negative space instead — it is
       the best-reading room on the sheet, and that is not a coincidence. Card surfaces
       quieten so the ones that remain mean elevation rather than habit.

   6 · GLASS ON CONTENT. Apple: glass is CHROME — nav, dock, sheets. Content cards get a
       solid quiet surface. Left in place only where a panel genuinely floats over a
       photograph and legibility depends on it, which is stated at that rule. */

/* 1 · the room name recedes; the instrument leads */
.navbar h1{font:700 clamp(21px,1.7vw,26px)/1.06 IS,system-ui,sans-serif;
  letter-spacing:.012em;word-spacing:.12em;padding-right:.12em;
  color:var(--label2)}
.subtitle{font:400 12.5px/1.45 var(--mono);letter-spacing:.01em;color:var(--label3);
  margin-top:7px;max-width:62ch}

/* 3 + 4 · rhythm and a hierarchy with actual steps in it */
.shead{padding:76px 4px 22px}
section:first-of-type .shead{padding-top:30px}
.shead h2{font:700 clamp(19px,1.6vw,23px)/1.1 IS;letter-spacing:.01em;word-spacing:.1em;
  margin-top:11px;color:var(--label)}

/* 2 · the accent stops being decoration. A section eyebrow is a LABEL, and labels are
   tertiary ink — the rule it sits on carries the structure, not the colour. */
.shead .kick{color:var(--label3);letter-spacing:.2em}
.shead .kick::after{background:color-mix(in srgb,var(--label) 15%,transparent)}
.room .k,.client .k,.pn-video .k{color:color-mix(in srgb,#fff 78%,transparent)}
.board .say .k{color:color-mix(in srgb,#fff 72%,transparent)}
.night .nstats span,.ladder .th,.deploy .dh,.ledger .lh{letter-spacing:.16em}

/* 5 · quieter card surfaces. Elevation should be felt, not seen — a few percent of
   lightness, per interface-design's subtle-layering backbone. */
.cap,.mini,.trump,.cab,.brief{
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 7%,transparent)}

/* ── THE DOCK IS PHONE CHROME, AND ONLY PHONE CHROME ──────────────────────────────
   Looking at the restraint pass rendered, the loudest remaining fault was mine and it
   had been there all along: on desktop the floating dock sits ON TOP of live content —
   a client row carrying £38,000, the valuation strip, the "where it goes" heading. And
   it is duplicate navigation: the rail is already there, permanently, naming the same
   eight rooms. Two navigations for one set of destinations is the fragmentation
   interface-design warns about, and the dock was paying for it by occluding data.

   So the dock is what it always should have been — the PHONE's navigation, where there
   is no rail. Below 1100px it appears; above it, the rail has the job alone. This
   removes an entire floating layer from every desktop room rather than restyling it,
   which is the restraint pass working the way it is supposed to: the win was deleting
   the element, not decorating it. */
@media (min-width:1101px){ .dock{display:none} }
@media (min-width:1101px){ .content{padding-bottom:40px} }

/* ── THE ACCENT, FINISHED ─────────────────────────────────────────────────────────
   The runway page still had orange on: the hero number, the run-dry week, the forecast
   hatching AND the button — four jobs on one screen, which is the fault the pass was
   supposed to fix. A measured quantity is DATA and takes the primary ink; the accent
   stays on the one action and on genuine urgency. */
.runway .big b{color:var(--label)}
.runway .kpi .hot b{color:var(--label)}

/* ═══ THE DESK — the Floor's instrument, rebuilt ═══════════════════════════════════
   CEO: "this design feels lazy and aisloppy." Correct, and the reason was structural
   rather than cosmetic: three things with completely different stakes were wearing the
   same row — thumbnail, bold sentence, grey sentence, pill — three times. A row is a
   row however carefully it is restyled, and three identical rows is the shape every AI
   dashboard produces. The 40px thumbnails were the tell: a photograph of a trainer
   tells you nothing whatsoever about a deck not being built. Decoration standing where
   information should be.

   Each thing now takes the form of what is at stake, which is the same principle that
   gives each ROOM its own instrument, applied one level down:
     WHEN  — a deadline is a DAY. The date is the object, at the size of the thing about
             to happen, standing on the client's own world.
     MONEY — £64,000 is the reason you would open Meridian at all, so the number is the
             card and the sentence becomes its caption.
     WHO   — "two people are idle" is an abstraction. Nell and Dina looking back at you
             is not, so they are shown at a size where they are people.

   The commit spans all three, because ending the week acts on all three. Previously it
   floated in a column with a photograph above it and a dead gap between — which is the
   reliable tell that space was left over rather than composed. */
.desk{display:grid;gap:14px;margin-top:16px;
  grid-template-columns:minmax(0,1.55fr) minmax(0,1fr) minmax(0,1.05fr);
  grid-template-areas:"when money who" "commit commit commit"}
/* .desk__h DELETED. It said "Before you end the week" directly under an H1 that now says
   "What you need to know" — the same sentence twice. It was also auto-placed AFTER the
   named grid areas, so it rendered beneath the commit bar with a dead gap under it: the
   heading was both redundant and in the wrong place, which is what removing it fixes. */

.task{position:relative;display:flex;flex-direction:column;min-width:0;overflow:hidden;
  border-radius:var(--r-card);padding:18px 19px 17px;background:var(--card);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 8%,transparent)}
.task .go{margin-top:auto;align-self:flex-start}
.task__fact{margin:9px 0 15px;font-size:14px;line-height:1.42;color:var(--label2);
  max-width:34ch}
.task__who{font:400 10.5px/1 var(--mono);letter-spacing:.17em;text-transform:uppercase;
  color:var(--label3)}

/* WHEN — the deadline. Full-bleed client world, heavy wash, the day as the object. */
.task--when{grid-area:when;min-height:214px;color:#F4F7FA;background:#10151B}
.task--when .task__bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:50% 38%}
.task--when .task__wash{position:absolute;inset:0;background:
  linear-gradient(96deg,rgba(8,11,15,.95) 0%,rgba(8,11,15,.86) 46%,rgba(8,11,15,.44) 100%)}
.task--when .task__body,.task--when .go{position:relative;z-index:1}
.task--when .task__who{color:color-mix(in srgb,#fff 74%,transparent)}
.task__day{display:flex;align-items:baseline;gap:12px;margin:6px 0 0}
.task__day b{font:700 clamp(46px,4.6vw,64px)/.82 var(--num);letter-spacing:-.045em}
.task__day i{font-style:normal;font:400 15px/1 var(--mono);letter-spacing:.1em;
  color:color-mix(in srgb,#fff 76%,transparent)}
.task--when .task__fact{color:color-mix(in srgb,#fff 82%,transparent)}

/* MONEY — the number is the card. */
.task--money{grid-area:money}
.task__num{margin:7px 0 0;font:700 clamp(30px,3vw,42px)/.94 var(--num);
  font-variant-numeric:tabular-nums;letter-spacing:-.035em;color:var(--label)}

/* WHO — two people, at a size where they are people. */
.task--who{grid-area:who}
.task__faces{display:flex;gap:11px;margin-top:9px}
.task__faces figure{margin:0;display:grid;gap:7px;justify-items:center}
.task__faces img{width:66px;height:66px;border-radius:14px;object-fit:cover;
  object-position:50% 22%;display:block;filter:grayscale(1) contrast(1.06);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 12%,transparent)}
.task__faces figcaption{font:600 12px/1 IS,ui-sans-serif,system-ui,sans-serif;color:var(--label2)}

/* THE COMMIT — spans all three, because it acts on all three. */
/* ⛔ WHITE IS A HIGHLIGHT COLOUR (CEO, 2026-08-17, mark 5 on The Floor): "this white module
   looks far too highlighted — white is a HIGHLIGHT colour so only use white block modules to
   highlight content." A full-width bone slab under three cards made ENDING THE WEEK the
   loudest thing on a page whose actual news is a deadline on Thursday. The commit bar is now
   card stock with a hairline top edge; the orange button carries the emphasis, which is what
   orange is for. Bone is reserved for a block that is genuinely the highlight of a screen. */
.desk__commit{grid-area:commit;display:flex;align-items:center;gap:18px;flex-wrap:wrap;
  padding:15px 19px;border-radius:var(--r-card);background:var(--card);color:var(--label);
  box-shadow:inset 0 0 0 1px var(--edge);margin-top:2px}
.desk__commit span{font:400 11px/1 var(--mono);letter-spacing:.17em;text-transform:uppercase;
  color:var(--label3);margin-right:auto}
.desk__commit button{border:0;cursor:pointer;height:48px;padding:0 30px;
  border-radius:var(--r-ctl);background:var(--acc);color:var(--acc-ink);
  font:700 15.5px/1 IS,system-ui,sans-serif;letter-spacing:-.012em}

@media (max-width:980px){
  .desk{grid-template-columns:minmax(0,1fr);
    grid-template-areas:"when" "money" "who" "commit"}
  .task--when{min-height:186px}
}

/* The desk's controls join the SYSTEM's two ranks — geometry here, material above, so a
   purchased pack reskins them along with everything else. After the rebuild they were
   <a> elements with no rule of their own and fell back to the browser's default link
   blue at 1.37:1. The sweep caught that; I did not. */
.task .go{display:inline-flex;align-items:center;justify-content:center;min-height:44px;
  padding:0 17px;border-radius:var(--r-ctl);text-decoration:none;white-space:nowrap;
  font:600 14.5px/1 IS,system-ui,sans-serif;color:var(--label)}
.task .go--now{color:var(--acc-ink)}
.task--when .go{color:#F4F7FA}
.task--when .go--now{color:var(--acc-ink)}

/* ── THE HEADLINE SAYS WHAT THE PAGE TELLS YOU ────────────────────────────────────
   CEO, 2026-08-17: "the headline feels like a waste of space when the nav tab on the
   right will indicate what the page content is... The headline on the Floor page should
   read 'What you need to know' then follow similar style for other pages."

   He is right and the screenshot proves it: the rail said THE FLOOR and the page said
   THE FLOOR, two inches apart, and the second one bought nothing. So the H1 stops naming
   the room and starts stating what the room tells you — What you need to know · What
   you're up against · Who's paying, and when · Who's on what · What's coming in, what's
   going out · Where you stand · What's in the back room · Who you're drinking with.

   That changes what the type has to be. Uppercase oblique is a NAMEPLATE treatment; it
   is right for a proper noun and wrong for a sentence, which it would turn into
   shouting. Sentence case, no skew, tighter tracking — a statement read at a glance. */
.navbar h1{text-transform:none;letter-spacing:-.016em;word-spacing:normal;
  transform:none;padding-right:0;color:var(--label);
  font:700 clamp(23px,2vw,29px)/1.12 IS,system-ui,sans-serif;text-wrap:balance;
  max-width:22ch}

/* ═══ PITCHES · THE BRAND LEADS, AND THE STAGGER IS BANNED ═════════════════════════
   CEO, 2026-08-17, two rulings on one panel.

   ⛔ THE STAGGER, BANNED SYSTEM-WIDE: "the type layout of this headline is awful —
   ensure this staggered indented approach is never used again." The cause was mine and
   it is worth naming so it cannot come back: an OBLIQUE headline set over four short
   lines. skewX shears every line independently, so each successive line starts further
   right than the one above and a left edge that should be a hard vertical becomes a
   staircase. Oblique is a NAMEPLATE treatment for ONE line at display size. It is never
   a paragraph treatment. Enforced below on every multi-line headline, not just this one.

   THE BRAND LEADS: the thing being pitched for was the smallest element on a panel whose
   entire job is to sell it. MERIDIAN now runs across the top at display size with its own
   mark — a real one from the Graphic_Reference artboards, not a coloured square — and the
   countdown sits beside it as a fact rather than as the hero. */

/* the ban. A headline that wraps does not get sheared. */
.board .say h2,.brandname,.opp b,h2:where(:not(.navbar h1)){text-wrap:balance}
.board .say h2{transform:none;text-transform:none;letter-spacing:-.015em}

.board{grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);
  grid-template-areas:"brand brand" "say field" "act field";
  align-content:start;gap:20px 40px}
.brandline{grid-area:brand;display:flex;align-items:center;gap:18px;
  padding-bottom:18px;border-bottom:1px solid rgba(255,255,255,.14)}
.brandmark{width:58px;height:58px;flex:none;object-fit:contain;
  filter:brightness(0) invert(1);opacity:.94}
.brandline .k{display:block;font:400 10.5px/1 var(--mono);letter-spacing:.17em;
  text-transform:uppercase;color:color-mix(in srgb,#fff 68%,transparent)}
.brandname{margin:7px 0 0;font:700 clamp(34px,4vw,54px)/.92 IS,system-ui,sans-serif;
  letter-spacing:-.03em;color:#fff}
.board .clock{margin-left:auto;display:flex;align-items:center;gap:11px;grid-area:auto}
.board .clock b{font:700 clamp(38px,3.6vw,52px)/.8 var(--num);letter-spacing:-.05em;
  color:var(--acc)}
.board .clock span{font:400 10.5px/1.25 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:color-mix(in srgb,#fff 70%,transparent)}
.board .say{grid-area:say;align-self:start;max-width:46ch}
.ask{margin:0 0 11px;font:700 clamp(21px,2.1vw,27px)/1.22 IS,system-ui,sans-serif;
  letter-spacing:-.014em;color:#fff;text-wrap:balance}
.board .field{grid-area:field}
.board .act{grid-area:act;align-self:end}

/* ── THE OPPORTUNITY TABLE ────────────────────────────────────────────────────────
   Same four facts, same columns, every row — so they can be COMPARED, which is the
   whole request. The two difficulties are deliberately separate: a client can be a
   delight in the room and impossible to hold, or grim to work with and yours for years.
   Conflating them into one "difficulty" score destroys the actual decision. */
.opps{display:grid;gap:2px;margin-top:16px}
.opps__h,.opp{display:grid;align-items:center;gap:18px;
  grid-template-columns:minmax(0,1.5fr) 86px 96px 104px minmax(0,1fr) minmax(0,1fr) auto}
.opps__h{padding:0 18px 9px;font:400 10px/1 var(--mono);letter-spacing:.16em;
  text-transform:uppercase;color:var(--label3)}
.opp{padding:15px 18px;background:var(--card);border-radius:14px;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 7%,transparent)}
.opp:hover{background:var(--card-2)}
.opp__id{display:flex;align-items:center;gap:13px;min-width:0}
.opp__id img{width:36px;height:36px;flex:none;object-fit:contain;opacity:.9;
  filter:brightness(0) invert(var(--markinv,1))}
:root[data-theme="light"] .opp__id img{--markinv:0}
.opp__id b{display:block;font:600 15.5px/1.2 IS,system-ui,sans-serif;color:var(--label)}
.opp__id i{display:block;font-style:normal;font-size:12px;color:var(--label3);margin-top:3px}
.opp__c b{display:block;font:700 16px/1 var(--num);font-variant-numeric:tabular-nums;
  color:var(--label)}
.opp__c i{display:block;font-style:normal;font-size:11.5px;line-height:1.3;
  color:var(--label3);margin-top:5px}
/* the rating is five pips, because a number out of five that you have to read is slower
   than a shape you can count at a glance across four rows */
.rate{display:flex;gap:3px}
.rate i{width:13px;height:5px;border-radius:2px;background:var(--label2)}
.rate i.off{background:color-mix(in srgb,var(--label) 16%,transparent)}
.rate--4 i:not(.off),.rate--5 i:not(.off){background:var(--acc)}

@media (max-width:1180px){
  .opps__h{display:none}
  .opp{grid-template-columns:minmax(0,1fr) auto;gap:10px 16px}
  .opp__id{grid-column:1/-1}
  .opp .go{grid-column:1/-1;justify-self:start}
}
@media (max-width:980px){
  .board{grid-template-columns:minmax(0,1fr);
    grid-template-areas:"brand" "say" "field" "act"}
  .brandline{flex-wrap:wrap}
}

/* ⛔ THE DEFAULT-LINK-BLUE TRAP, TWICE IN ONE SESSION. Both the desk and the opportunity
   table shipped <a class="go"> elements whose styling was scoped to a parent that did not
   contain them, so they fell back to the browser's unvisited-link blue at 1.37:1. Caught
   by the sweep both times, by me neither time. So the geometry is now attached to .go
   ITSELF rather than to each new parent — any future control that carries the class is
   dressed on arrival, and the only thing a new surface has to decide is which RANK it is. */
.go{display:inline-flex;align-items:center;justify-content:center;min-height:44px;
  padding:0 17px;border-radius:var(--r-ctl);text-decoration:none;white-space:nowrap;
  font:600 14.5px/1 IS,system-ui,sans-serif;color:var(--label);cursor:pointer}
.go--now{color:var(--acc-ink)}

/* ═══ CLIENTS · THE ACCOUNTS ═══════════════════════════════════════════════════════
   CEO, 2026-08-17: "bigger client images, maybe each client as a module... you need to
   bake into every design consideration how we use all the graphics I gave you AND the
   media library... like look at the client sector art."

   The waste was specific and measurable: 39 pieces of commissioned CLIENT SECTOR ART
   exist in the library, shot properly — and this page rendered them at 40 pixels square.
   A photograph of a flat white at 40px is a brown dot. Every one of those images was
   paid for and none of them was doing any work.

   So an account is now a MODULE with the art at the size it was made for: the client's
   own world across the top, its brand mark from the Graphic_Reference artboards standing
   on it, the money and the count underneath, and one line saying what is actually
   happening. Ordered by what needs you first — the account with a deadline this week
   leads and is the only one carrying a filled action, so the page answers "who needs me"
   before it answers "what do I have". */
.accounts{display:grid;gap:16px;margin-top:16px;
  grid-template-columns:repeat(auto-fit,minmax(272px,1fr))}
.acct{display:flex;flex-direction:column;min-width:0;border-radius:var(--r-card);
  overflow:hidden;background:var(--card);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 8%,transparent);
  transition:transform .2s cubic-bezier(.22,1,.36,1),box-shadow .2s cubic-bezier(.22,1,.36,1)}
.acct:hover{transform:translateY(-2px);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 16%,transparent),
             0 14px 34px -18px #000}

/* THE ART. 16:10 so it is a picture, not a strip — and the mark stands ON the client's
   world, which is what a brand does. */
.acct__art{position:relative;aspect-ratio:16/10;overflow:hidden;background:#10151B}
.acct__art>img:first-child{width:100%;height:100%;object-fit:cover;display:block}
.acct__wash{position:absolute;inset:0;background:
  linear-gradient(to top,rgba(8,11,15,.88) 0%,rgba(8,11,15,.28) 52%,rgba(8,11,15,.06) 100%)}
.acct__mark{position:absolute;left:15px;bottom:14px;width:40px;height:40px;
  object-fit:contain;filter:brightness(0) invert(1);opacity:.96;z-index:1}
.acct__due,.acct__st{position:absolute;right:13px;top:12px;z-index:1;
  font:600 10.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  padding:7px 10px;border-radius:99px;backdrop-filter:blur(8px);
  background:rgba(10,14,19,.72);color:#EDF2F7}
.acct__due{background:var(--acc);color:var(--acc-ink)}
.acct__st--pitch{box-shadow:inset 0 0 0 1px color-mix(in srgb,#fff 34%,transparent)}

.acct__body{display:flex;flex-direction:column;flex:1;gap:9px;padding:16px 17px 17px}
.acct__body h3{margin:0;font:700 21px/1.1 IS,system-ui,sans-serif;letter-spacing:-.02em;
  color:var(--label)}
.acct__sec{font:400 11.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--label3);margin-top:-3px}
.acct__nums{display:flex;gap:20px;flex-wrap:wrap;padding:11px 0 2px;
  border-top:1px solid color-mix(in srgb,var(--label) 10%,transparent);margin-top:3px}
.acct__nums b{display:block;font:700 17px/1 var(--num);font-variant-numeric:tabular-nums;
  color:var(--label)}
.acct__nums i{display:block;font-style:normal;font:400 10.5px/1 var(--mono);
  letter-spacing:.11em;text-transform:uppercase;color:var(--label3);margin-top:6px}
.acct__note{margin:2px 0 0;font-size:13.5px;line-height:1.4;color:var(--label2)}
.acct .go{margin-top:auto;align-self:flex-start}
/* the one that needs you is the only filled action in the room */
.acct--now{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--acc) 46%,transparent)}

.acct__total{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin-top:18px;
  padding-top:15px;border-top:1px solid color-mix(in srgb,var(--label) 13%,transparent)}
.acct__total span{font:400 11px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--label3);margin-right:auto}
.acct__total b{font:700 25px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label)}
.acct__total i{font-style:normal;font:400 11px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--label3)}
@media (prefers-reduced-motion:reduce){.acct:hover{transform:none}}

/* ⛔ THIRD TIME. .go--now set the INK but took its FILL from a selector list that had to
   name every parent — so each new surface (the desk, the opportunity table, the accounts)
   shipped a primary action with accent ink on a card background: 1.56:1. Caught by the
   sweep every time and by me none of them. The rank now carries its own fill, so the class
   is self-sufficient wherever it lands and no future surface has to be added to a list. */
.go--now{background-image:linear-gradient(180deg,
    color-mix(in srgb, var(--acc) 88%, #fff) 0%,
    var(--acc) 52%,
    color-mix(in srgb, var(--acc) 92%, #000) 100%);
  background-color:var(--acc);color:var(--acc-ink);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 34%, transparent),
    inset 0 -1px 0 color-mix(in srgb, #000 16%, transparent),
    0 2px 10px color-mix(in srgb, var(--acc) 30%, transparent),
    0 1px 2px color-mix(in srgb, #000 24%, transparent)}

/* THE GHOST RANK WAS INVISIBLE ON CARDS. Its fill and hairline were mixed from
   --bone-ink, which is only the right ink on the BONE surface it was written for. On a
   --card ground it mixed to almost nothing and "Open the account" read as plain text
   rather than a control — a secondary action the player cannot see is not secondary,
   it is missing. Derived from --label instead, which is correct on any surface. */
:is(.decision .go, .decision .todo .go, .task .go, .opp .go, .acct .go, .brief .cta,
    .pn-btn--ghost):not(.go--now){
  background-image:linear-gradient(180deg,
    color-mix(in srgb,var(--label) 13%,transparent),
    color-mix(in srgb,var(--label) 7%,transparent));
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 17%,transparent),
             inset 0 1px 0 color-mix(in srgb,#fff 12%,transparent)}
:is(.decision .go, .decision .todo .go, .task .go, .opp .go, .acct .go,
    .pn-btn--ghost):not(.go--now):hover{
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 30%,transparent),
             inset 0 1px 0 color-mix(in srgb,#fff 16%,transparent)}
.task--when .go:not(.go--now){box-shadow:inset 0 0 0 1px rgba(255,255,255,.22)}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE BACK ROOM AND THE BAR — real photography, because the CEO was right twice over.

   "these really are the most dull, flat graphics to use arent they… create some Stunning
   modern Arcade style imagery for Pool and Fussball that SELLS the idea of playing them"
   "OMG this is supposed to be a fun fucking PUB not a spreadsheet"

   Both notes are the same note: I answered a CONTENT question with CSS. The arcade drew a
   pool table as four rectangles and six circles; the pub printed its own state as a 74px
   numeral. Neither makes anybody want to do the thing. The fix is not a better rectangle —
   it is a photograph of a table at table height with the cue already down, and a film of
   the bar with the lamps on.

   NO GENERATED LETTERING SURVIVES INTO THE PRODUCT. Every plate here was checked and the
   model's invented neon signage was defocused out at full resolution before the asset was
   written (tools note: gaussian at r72 under a feathered mask, not a crop, so the glow
   still reads as depth of field). The estate has killed a WahWah banner and a coaster
   flat-lay for exactly this.
   ═════════════════════════════════════════════════════════════════════════════════════ */

/* ── THE MACHINES. One card per game, and the card is mostly photograph. ─────────────── */
.tables{display:grid;grid-template-columns:1fr 1fr;gap:18px}
.tbl{position:relative;display:block;overflow:hidden;border-radius:var(--r-card);
  background:#05080c;text-decoration:none;color:#F4F1EA;isolation:isolate;
  transition:transform .22s cubic-bezier(.22,1,.36,1)}
.tbl:hover{transform:translateY(-4px)}
.tbl img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover;
  transition:transform .5s cubic-bezier(.22,1,.36,1)}
.tbl:hover img{transform:scale(1.035)}
/* The scrim is a real element, not a pseudo, so the contrast probe can see it and so the
   ramp can be tuned per card without touching the photograph. */
.tbl .wash{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(4,6,9,.30) 0%,rgba(4,6,9,.05) 34%,
    rgba(4,6,9,.72) 66%,rgba(4,6,9,.94) 100%)}
.tbl .lay{position:absolute;left:0;right:0;bottom:0;padding:22px 24px 24px;display:grid;gap:9px}
.tbl .nm{font:700 clamp(30px,3.4vw,44px)/.92 SG,IS,sans-serif;letter-spacing:-.02em;
  text-transform:uppercase;color:#FFF;text-shadow:0 3px 26px rgba(0,0,0,.78)}
.tbl .ln{font-size:14px;line-height:1.42;color:#E4E7EB;max-width:44ch;
  text-shadow:0 1px 12px rgba(0,0,0,.8)}
.tbl .rw{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-top:4px}
.tbl .chip{display:inline-flex;align-items:center;height:28px;padding:0 12px;border-radius:99px;
  font:500 11.5px/1 var(--mono);letter-spacing:.09em;text-transform:uppercase;
  color:#F4F1EA;background:rgba(10,14,19,.62);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.20)}
.tbl .go{margin-left:auto}
@media (max-width:900px){.tables{grid-template-columns:1fr}}

/* ── THE COST BAND. The one place the arcade prints numbers, and it prints them over the
      thing they are the price of. ───────────────────────────────────────────────────── */
.costband{position:relative;overflow:hidden;border-radius:var(--r-card);background:#05080c}
.costband img{display:block;width:100%;height:230px;object-fit:cover;object-position:50% 62%}
.costband .wash{position:absolute;inset:0;background:linear-gradient(90deg,
  rgba(4,6,9,.94) 0%,rgba(4,6,9,.86) 46%,rgba(4,6,9,.36) 100%)}
.costband .in{position:absolute;inset:0;display:grid;align-content:center;gap:14px;
  padding:0 clamp(20px,4vw,40px)}
.costband h3{font:700 22px/1.1 IS,sans-serif;letter-spacing:-.015em;color:#F4F1EA}
.costband .nums{display:flex;gap:30px;flex-wrap:wrap}
.costband .nums div{display:grid;gap:5px}
.costband .nums b{font:700 26px/1 var(--num);font-variant-numeric:tabular-nums;color:#F4F1EA}
.costband .nums .hot b{color:var(--acc)}
.costband .nums span{font:400 10.5px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:#AEB6BF}
@media (max-width:700px){.costband img{height:290px}
  .costband .wash{background:linear-gradient(180deg,rgba(4,6,9,.62),rgba(4,6,9,.93))}}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE DUFF — the room opens with the room, not with its own arithmetic.
   The old header set "0 of six rounds" at 74px, which is a dashboard readout for a place
   whose entire job is to feel like somewhere you would go. The night's numbers now ride a
   brass rail across the bottom of the footage, where a pub actually keeps them: on the tab.
   ═════════════════════════════════════════════════════════════════════════════════════ */
.pubhero{position:relative;overflow:hidden;border-radius:var(--r-card);background:#05080c;
  isolation:isolate}
.pubhero video,.pubhero>img{display:block;width:100%;aspect-ratio:21/9;object-fit:cover}
.pubhero .wash{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(4,6,9,.52) 0%,rgba(4,6,9,.06) 40%,
    rgba(4,6,9,.80) 78%,rgba(4,6,9,.96) 100%)}
.pubhero .sign{position:absolute;top:16px;right:16px;width:clamp(104px,11vw,146px);
  border-radius:10px;overflow:hidden;box-shadow:0 14px 44px rgba(0,0,0,.72);
  outline:1px solid rgba(233,178,90,.30);outline-offset:-1px;
  transition:transform .22s cubic-bezier(.22,1,.36,1)}
.pubhero .sign:hover{transform:scale(1.04)}
.pubhero .sign img,.pubhero .sign video{display:block;width:100%;aspect-ratio:16/9;object-fit:cover}
.pubhero .lay{position:absolute;left:0;right:0;bottom:0;
  padding:clamp(18px,3vw,30px) clamp(20px,3.4vw,34px);display:grid;gap:14px}
.pubhero .say{font:700 clamp(24px,3.1vw,40px)/1.06 IS,sans-serif;letter-spacing:-.022em;
  color:#FFF;max-width:19ch;text-shadow:0 3px 26px rgba(0,0,0,.8)}
/* THE RAIL. Four facts, one line, brass separators — a tab, not a stats panel. */
.pubhero .rail{display:flex;align-items:center;gap:clamp(14px,2.4vw,30px);flex-wrap:wrap;
  padding-top:13px;border-top:1px solid rgba(233,178,90,.34)}
.pubhero .rail div{display:grid;gap:4px}
.pubhero .rail b{font:700 19px/1 var(--num);font-variant-numeric:tabular-nums;color:#F4F1EA}
.pubhero .rail .hot b{color:var(--acc)}
.pubhero .rail span{font:400 10px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:#B6BDC5}
.pubhero .rail .go{margin-left:auto}
@media (max-width:760px){
  .pubhero video,.pubhero>img{aspect-ratio:4/5}
  .pubhero .sign{width:96px}
  .pubhero .rail .go{margin-left:0;width:100%;margin-top:6px}
}

/* ── HOW IT WORKS — CEO #17, 13 Sep: "add a 'How it Works' button and explanatory note on how
   to play The Duff." The explainer PANEL already existed (`#scrim`/`.pn-helpsheet` below) but
   its only door was `#helpbtn` in `.appbar`, and `pn-shell.js` HIDES `.appbar` whenever the room
   is EMBEDDED (`window.self !== window.top`) — exactly how the CEO played it, inside the arcade
   overlay window. The explainer existed and was unreachable. This button lives in `.content`,
   which is never hidden, and the inline script at the foot of `duff.html` opens `#scrim`
   directly rather than depending on pn-shell.js's own `#helpbtn` binding. ── */
.pubhero .head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px}
.duff-how{flex:none;display:inline-flex;align-items:center;gap:7px;height:36px;padding:0 15px 0 13px;
  border-radius:999px;border:1px solid rgba(244,241,234,.42);background:rgba(9,13,18,.42);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  font:700 11px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;color:#FFF;cursor:pointer;
  text-shadow:0 1px 6px rgba(0,0,0,.6)}
.duff-how i{width:16px;height:16px;border-radius:99px;background:var(--acc);color:var(--acc-ink);
  display:grid;place-items:center;font:800 11px/1 IN;font-style:normal}
.duff-how:hover{background:rgba(9,13,18,.64);border-color:rgba(244,241,234,.62)}
.duff-how:focus-visible{outline:2px solid #FFF;outline-offset:2px}
.pubhero .duffnote{grid-column:1/-1;font:400 12.5px/1.5 IS,sans-serif;color:#D8DCE1;max-width:56ch;
  text-shadow:0 2px 14px rgba(0,0,0,.7)}
.duffnote .duff-how-link{background:none;border:0;padding:0;margin:0;cursor:pointer;
  font:700 12.5px/1.5 IS,sans-serif;color:#F4C77A;text-decoration:underline;
  text-underline-offset:2px}
.duffnote .duff-how-link:hover{color:#FFD98F}
.duffnote .duff-how-link:focus-visible{outline:2px solid #FFF;outline-offset:2px}
@media (max-width:520px){
  .duff-how span{display:none}
  .duff-how{width:36px;padding:0;justify-content:center}
}

/* ── WHO IS IN TONIGHT. Everyone now has a face and the face is the card. ───────────── */
.drinkers{display:grid;grid-template-columns:repeat(5,1fr);gap:12px}
.dr{position:relative;display:block;overflow:hidden;border-radius:18px;background:#05080c;
  text-decoration:none;color:#F4F1EA;transition:transform .2s cubic-bezier(.22,1,.36,1)}
.dr:hover{transform:translateY(-3px)}
.dr img{display:block;width:100%;aspect-ratio:3/4;object-fit:cover;object-position:50% 22%}
.dr .wash{position:absolute;inset:0;background:linear-gradient(180deg,
  rgba(4,6,9,0) 32%,rgba(4,6,9,.78) 70%,rgba(4,6,9,.96) 100%)}
.dr .lay{position:absolute;left:0;right:0;bottom:0;padding:12px 13px 13px;display:grid;gap:3px}
.dr b{font:600 14.5px/1.15 IS,sans-serif;letter-spacing:-.014em;color:#FFF}
.dr i{font-style:normal;font-size:11.5px;line-height:1.32;color:#C6CCD3}
.dr .tag{justify-self:start;margin-top:5px;height:20px;display:inline-flex;align-items:center;
  padding:0 8px;border-radius:99px;font:500 9.5px/1 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:#0B0F14;background:#D8DEE5}
.dr .tag--cli{background:var(--ochre,#E8B45C);color:#231703}
.dr .tag--riv{background:var(--acc);color:var(--acc-ink)}
@media (max-width:1000px){.drinkers{grid-template-columns:repeat(3,1fr)}}
@media (max-width:620px){.drinkers{grid-template-columns:repeat(2,1fr)}}

/* ── THE THREE ROUNDS. Printed on the table they are ordered at. ────────────────────── */
.tabletop{position:relative;overflow:hidden;border-radius:var(--r-card);background:#0B0F14}
.tabletop>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:50% 70%}
.tabletop .wash{position:absolute;inset:0;background:linear-gradient(180deg,
  rgba(6,9,13,.62),rgba(6,9,13,.80))}
.tabletop .in{position:relative;padding:clamp(20px,3vw,28px);display:grid;gap:14px}
.tabletop .eyebrow{font:400 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:#AEB6BF}
.mats{display:grid;grid-template-columns:repeat(3,1fr);gap:13px}
.mat{position:relative;border-radius:16px;padding:17px 18px 19px;display:grid;gap:7px;
  background:linear-gradient(180deg,rgba(244,241,234,.055),rgba(244,241,234,.02));
  box-shadow:inset 0 0 0 1px rgba(233,178,90,.20),0 10px 30px rgba(0,0,0,.34)}
.mat b{font:600 15.5px/1.15 IS,sans-serif;color:#F4F1EA}
.mat i{font-style:normal;font-size:12.5px;line-height:1.44;color:#C0C7CF}
.mat .yield{margin-top:4px;font:500 10px/1 var(--mono);letter-spacing:.13em;
  text-transform:uppercase;color:var(--ochre,#E8B45C)}
.mat--ask{box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--acc) 46%,transparent),
  0 10px 30px rgba(0,0,0,.34)}
.mat--ask .yield{color:var(--acc)}
@media (max-width:820px){.mats{grid-template-columns:1fr}}

/* ── THE HOUSE. The door and the snug, so the room has a geography. ────────────────── */
.house{display:grid;grid-template-columns:1fr 1fr;gap:16px}
/* `.tbl` has carried `text-decoration:none` since it was written; `.plateshot` never did, and
   it is an <a> too. Invisible while its copy sat on a near-black scrim with its own explicit
   `color:#FFF`; the moment the 760px block put that copy on a themed card, the browser's default
   link underline appeared under "The bar is through the front" (measured at 390, light,
   14 Sep). Same component, same rule. */
a.plateshot{text-decoration:none;color:inherit}
.plateshot{position:relative;overflow:hidden;border-radius:var(--r-card);background:#05080c}
.plateshot img{display:block;width:100%;aspect-ratio:16/10;object-fit:cover}
.plateshot .wash{position:absolute;inset:0;background:linear-gradient(180deg,
  rgba(4,6,9,0) 42%,rgba(4,6,9,.80) 76%,rgba(4,6,9,.96) 100%)}
.plateshot .lay{position:absolute;left:0;right:0;bottom:0;padding:18px 20px 20px;display:grid;gap:7px}
.plateshot b{font:700 19px/1.1 IS,sans-serif;letter-spacing:-.016em;color:#FFF}
.plateshot i{font-style:normal;font-size:13px;line-height:1.42;color:#C6CCD3;max-width:40ch}
.plateshot .go{justify-self:start;margin-top:6px}
@media (max-width:860px){.house{grid-template-columns:1fr}}

/* The hangover was the last spreadsheet left in the pub: a bare bar chart on the room's own
   background. The curve is honest and stays exactly as it is — it is now printed on the
   table, like the tab it is. */
.tabletop .hang{margin-top:2px}
.tabletop .footnote{color:#AEB6BF}

/* ── LEGIBILITY OVER PHOTOGRAPHY, and why the AA sweep did not catch this ────────────────
   The theme sweep measures text against the SCRIM it can compute. It cannot see how bright
   a particular photograph happens to be behind a particular line — and at 390 the cards get
   short, so the same gradient has half the distance to get dark in. The back-bar plate is
   lit, and its body copy was sitting on the lit part of it.
   So the copy block carries its OWN ramp, independent of the image wash: a scrim that is
   attached to the text rather than to the picture cannot be out-run by a bright frame. */
:is(.tbl,.plateshot,.dr) .lay{
  background:linear-gradient(180deg,rgba(4,6,9,0) 0%,rgba(4,6,9,.46) 30%,rgba(4,6,9,.86) 64%,
    rgba(4,6,9,.95) 100%);
  padding-top:40px}
.dr .lay{padding-top:26px}
/* On a phone the overlay stops being a good idea: the card is short, so the copy block
   eats most of the picture and you end up with neither a photograph nor a clean read.
   Below 760 the two separate — the plate is a plate, the words sit under it on card stock. */
@media (max-width:760px){
  :is(.tbl,.plateshot){display:grid;grid-template-rows:auto auto;background:var(--card)}
  :is(.tbl,.plateshot) .wash{position:absolute;inset:auto 0 0 0;height:0}
  :is(.tbl,.plateshot) .lay{position:static;background:none;padding:16px 17px 18px}
  .tbl .nm{font-size:30px;color:var(--label);text-shadow:none}
  .tbl .ln,.plateshot i{color:var(--label2);text-shadow:none}
  .plateshot b{color:var(--label)}
  .tbl .chip{color:var(--label);background:var(--grouped);
    box-shadow:inset 0 0 0 1px var(--hair,rgba(255,255,255,.10))}
  .tbl .go{margin-left:0}
}


/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE FLOOR, MARKED UP BY THE CEO — 15 marks, 17 Aug. The through-line in all of them:
   a module that does not say what it is, is not a module, it is a rectangle.
   ═════════════════════════════════════════════════════════════════════════════════════ */

/* ── 1 · PANELS TOO SIMILAR TO THE BACKGROUND ────────────────────────────────────────
   "all these panels are too similar to background". They were: --card sat ~4% above the
   page ground and the only edge was an 8%-alpha inset that vanished on a photograph. A
   card now carries a real edge token, declared per theme, so an object reads as an object
   before you have read a word of it. */
:root{--edge:rgba(255,255,255,.115)}
:root[data-theme="light"]{--edge:rgba(24,20,12,.14)}
.pinned{--edge:rgba(255,255,255,.13)}
:is(.task,.summary .instr,.setpiece,.reel .pn-video,.trump,.client,.desk__commit,
    .alerts,.officebar){box-shadow:inset 0 0 0 1px var(--edge)}

/* ── 15 · THE FLOOR IS A SUMMARY PAGE, SO IT OPENS WITH WHAT IS WRONG ────────────────
   "Because this 'The Floor' is a summary page you should be VERY clear and include any
   issues as notifications at the top of this page." Four live issues, worst first, each
   one deep-linking to the thing that fixes it — not to the page it lives on. */
.alerts{border-radius:var(--r-card);background:var(--card);overflow:hidden}
.alerts__h{display:flex;align-items:center;gap:10px;padding:13px 18px;
  border-bottom:1px solid var(--sep)}
.alerts__h b{font:400 10.5px/1 var(--mono);letter-spacing:.17em;text-transform:uppercase;
  color:var(--label3)}
.alerts__h .count{margin-left:auto;display:inline-flex;align-items:center;height:22px;
  padding:0 9px;border-radius:99px;background:var(--acc);color:var(--acc-ink);
  font:700 11px/1 var(--mono)}
.alert{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:14px;
  padding:13px 18px;border-bottom:1px solid var(--sep);text-decoration:none;color:var(--label)}
.alert:last-child{border-bottom:0}
.alert:hover{background:var(--card-2)}
.alert .sev{width:9px;height:9px;border-radius:99px;background:var(--label3)}
/* ⛔ PROMINENCE BOOST (CEO, 2026-08-19): a 9px dot was the ONLY signal an urgent notice
   carried — same row height, same border, same weight as "soon". --alert--now now claims
   the whole row (left stripe + tinted fill), so it reads before it's read. */
.alert--now{border-left:3px solid var(--acc);background:color-mix(in srgb, var(--acc) 9%, transparent);
  padding-left:15px}
.alert--now .sev{background:var(--acc);box-shadow:0 0 0 4px color-mix(in srgb,var(--acc) 22%,transparent)}
.alert--soon{border-left:3px solid var(--ochre,#E8B45C);padding-left:15px}
.alert--soon .sev{background:var(--ochre,#E8B45C)}
.alert .txt{min-width:0}
.alert .txt b{display:block;font:600 14.5px/1.3 IS,system-ui,sans-serif;letter-spacing:-.012em}
.alert .txt i{display:block;font-style:normal;font-size:12.5px;line-height:1.4;
  color:var(--label3);margin-top:2px}
.alert .when{font:500 10.5px/1 var(--mono);letter-spacing:.11em;text-transform:uppercase;
  color:var(--label3);white-space:nowrap}
@media (max-width:700px){
  .alert{grid-template-columns:auto 1fr;gap:11px}
  .alert .when{grid-column:2;margin-top:4px}
}

/* ── 2,3,4 · EVERY MODULE SAYS WHAT IT IS ────────────────────────────────────────────
   "each module needs marking with clear heading". A mono kicker at the top of every task
   naming the KIND of thing it is — a deadline, money on the table, people not working —
   above the client name, so the card is legible before the numbers are read. */
.task__kind{display:flex;align-items:center;gap:7px;margin:0 0 9px;
  font:600 10px/1 var(--mono);letter-spacing:.19em;text-transform:uppercase;color:var(--acc)}
.task__kind::before{content:"";width:16px;height:2px;background:var(--acc);flex:none}
.task--when .task__kind{color:#FFB870}
.task--when .task__kind::before{background:#FFB870}

/* ── 6,7,8 · IT IS AN OFFICE, AND IT COSTS YOU MONEY ─────────────────────────────────
   "this 'Your Floor' header looks terrible and means nothing" / "This should be 'Your
   Office' no?" / "these figures should reflect the rent/impact of the office on financials
   — and potentially give them an option to change/upgrade/downgrade office?"
   The room now states its rent, what it is worth, and what the next one costs, with the
   two moves available on it. A tier you cannot act on is decoration. */
.officebar{display:flex;align-items:center;gap:clamp(16px,3vw,34px);flex-wrap:wrap;
  margin-top:13px;padding:15px 19px;border-radius:var(--r-card);background:var(--card)}
.officebar .fig{display:grid;gap:5px}
.officebar .fig b{font:700 19px/1 var(--num);font-variant-numeric:tabular-nums;
  color:var(--label)}
.officebar .fig.hot b{color:var(--acc)}
.officebar .fig span{font:400 10px/1 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--label3)}
.officebar .acts{display:flex;gap:9px;margin-left:auto;flex-wrap:wrap}
@media (max-width:700px){.officebar .acts{margin-left:0;width:100%}}

/* ── 10,11 · THE WAY OUT OF A SECTION IS A BUTTON, NOT A GUESS ───────────────────────
   "add a prominent Orange button here that says 'Go to Clients'" / "'Go to Team'".
   The section heading grows a control on its right, so every summary block on this page
   ends in the room it summarises. */
.shead{position:relative}
.shead .jump{position:absolute;right:4px;bottom:12px}
@media (max-width:760px){
  .shead .jump{position:static;display:flex;width:max-content;margin-top:12px}
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   PITCHES, MARKED UP BY THE CEO — 6 marks, 17 Aug.
   ═════════════════════════════════════════════════════════════════════════════════════ */

/* ── P1 · "These layouts are dull and misaligned — ensure they animate and rollover
      highlight — and these icons should be supplemented with some real artwork from the
      client art media library."
   Three separate faults, three separate fixes:
   · MISALIGNED — the row was a seven-column grid where two columns were `minmax(0,1fr)`,
     so the two difficulty columns changed width with their own copy and nothing lined up
     down the page. They are now fixed-width, and every figure is tabular.
   · DULL — the brand mark alone is a 36px glyph on a grey row. Each opportunity now
     carries its SECTOR PHOTOGRAPH from the media library, with the mark sitting on it.
   · NO ROLLOVER — it now lifts, warms, brightens its own picture and pushes its accent
     edge, on a spring, and the whole row is the target. ─────────────────────────────── */
.opps__h,.opp{grid-template-columns:minmax(0,1.45fr) 92px 100px 108px 150px 150px auto}
.opp{position:relative;padding:12px 18px 12px 12px;overflow:hidden;
  transition:transform .22s cubic-bezier(.22,1,.36,1),background .18s,box-shadow .18s}
.opp:hover{background:var(--card-2);transform:translateY(-2px);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--acc) 52%,transparent),
             0 12px 30px rgba(0,0,0,.30)}
.opp__art{position:relative;flex:none;width:96px;height:64px;border-radius:10px;
  overflow:hidden;background:#0A0E13}
.opp__art img.pic{width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.72) brightness(.68);transition:filter .3s,transform .5s cubic-bezier(.22,1,.36,1)}
.opp:hover .opp__art img.pic{filter:saturate(1) brightness(.92);transform:scale(1.06)}
.opp__art .mk{position:absolute;inset:0;display:grid;place-items:center}
.opp__art .mk img{width:34px;height:34px;object-fit:contain;
  filter:brightness(0) invert(1) drop-shadow(0 2px 6px rgba(0,0,0,.7))}
.opp__id{gap:14px}
.opp .go{transition:transform .22s cubic-bezier(.22,1,.36,1)}
.opp:hover .go{transform:translateX(3px)}
@media (prefers-reduced-motion:reduce){
  .opp,.opp .go,.opp__art img.pic{transition:none}
  .opp:hover{transform:none}
}
@media (max-width:1180px){
  .opp{padding:12px}
  .opp__art{width:74px;height:52px}
}

/* ── P4 · "How is this 'IN PLAY' if the user isn't doing it?" ────────────────────────
   It was not in play. It was open, unstaffed and unstarted, sitting under a heading that
   claimed otherwise — a gameplay-honesty violation (UX_RULES §7), not a wording problem.
   A pitch now carries its REAL state as a stamp, and the state decides the colour. */
.state{display:inline-flex;align-items:center;gap:7px;height:26px;padding:0 11px;
  border-radius:99px;font:600 10.5px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase}
.state::before{content:"";width:7px;height:7px;border-radius:99px;background:currentColor}
.state--none{color:var(--acc);background:color-mix(in srgb,var(--acc) 15%,transparent)}
.state--going{color:var(--sage,#8FBF9F);background:color-mix(in srgb,var(--sage,#8FBF9F) 15%,transparent)}
.state--won{color:var(--sage,#8FBF9F);background:color-mix(in srgb,var(--sage,#8FBF9F) 17%,transparent)}
.state--lost{color:var(--ochre,#E8B45C);background:color-mix(in srgb,var(--ochre,#E8B45C) 17%,transparent)}

/* ── P5 · "this is all too grey and dark — add highlights, icons and more graphic —
      ensure users can review the pitches and what happened so they can learn."
   A result row now carries the result in colour on its own edge, and every finished pitch
   prints THE ONE THING IT TAUGHT YOU. A record you cannot learn from is a scoreboard. */
.result{position:relative;overflow:hidden}
.result::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px}
.result--won::before{background:var(--sage,#8FBF9F)}
.result--lost::before{background:var(--ochre,#E8B45C)}
.learn{display:flex;align-items:flex-start;gap:9px;margin-top:9px;padding-top:9px;
  border-top:1px solid var(--sep);font-size:12.5px;line-height:1.42;color:var(--label2)}
.learn svg{width:15px;height:15px;flex:none;margin-top:1px;fill:none;stroke:var(--acc);
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.learn b{color:var(--label);font-weight:600}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   CLIENTS, MARKED UP BY THE CEO — 5 marks, 17 Aug.
   ═════════════════════════════════════════════════════════════════════════════════════ */

/* ── C2 · "this figure is critical and currently hidden away — put these big figures and
      financial headlines at the top above these client modules."
   £140,750 was a footer under four cards. The book of business is the first thing an
   agency owner looks at, so it leads, at the size of the fact it is. ──────────────── */
.bookhead{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:2px;
  border-radius:var(--r-card);overflow:hidden;background:var(--sep)}
.bookhead div{background:var(--card);padding:18px 20px 17px;display:grid;gap:7px}
.bookhead b{font:700 clamp(24px,2.7vw,34px)/1 var(--num);font-variant-numeric:tabular-nums;
  letter-spacing:-.03em;color:var(--label)}
.bookhead .hot b{color:var(--acc)}
.bookhead .bad b{color:var(--ochre,#E8B45C)}
.bookhead span{font:400 10px/1.3 var(--mono);letter-spacing:.14em;text-transform:uppercase;
  color:var(--label3)}
.bookhead em{font-style:normal;font-size:11.5px;color:var(--label3)}
@media (max-width:900px){.bookhead{grid-template-columns:1fr 1fr}}

/* ── C1 · "I dont read any of these client modules as status."
   Correct — every card looked identical and the only difference was a sentence. An account
   now carries THREE readable signals before you get to any prose: a status stamp, a
   PRESSURE BAR, and a loyalty trend. And the whole card is a link to the account, because
   the note asked for click-through to a page where you can act. ────────────────────── */
/* the whole account is the link now (CEO mark 1: "users click though to individual pages").
   ⛔ Which means NOTHING inside it may be an anchor — anchors cannot nest, and when they do
   the parser splits the card into pieces. Controls inside a card card are spans. */
a.acct{text-decoration:none;color:var(--label)}
a.acct h3,a.acct b{color:var(--label)}
.acct{position:relative;transition:transform .22s cubic-bezier(.22,1,.36,1),box-shadow .18s}
a.acct:hover{transform:translateY(-3px);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--acc) 45%,transparent),
             0 14px 34px rgba(0,0,0,.32)}
/* the stamp sits on a photograph, so it carries its own opaque ground — a colour-mixed
   pill over open water is a stamp you cannot read, which is the fault it was added to fix */
.acct__flag{position:absolute;top:12px;left:12px;z-index:3;
  background:rgba(8,11,15,.86);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.acct__flag.state--none{color:#FFA254}
.acct__flag.state--won{color:#9ED4AE}
.acct__flag.state--lost{color:#F0C578}
.acct__sig{display:grid;gap:9px;margin:12px 0 2px;padding-top:12px;
  border-top:1px solid var(--sep)}
.acct__sigrow{display:flex;align-items:center;gap:10px;
  font:400 10px/1 var(--mono);letter-spacing:.13em;text-transform:uppercase;color:var(--label3)}
.acct__sigrow .v{margin-left:auto;font-weight:600;letter-spacing:.06em}

/* ── C3 · "use more graphics and charts to show stress levels and pressure. Use red to
      green as pressure colour bars." A single reusable instrument, because pressure is the
      same question wherever it is asked: how close is this to going wrong. Green is fine,
      amber is watch it, red is now. The fill is set with --p (0-100) and the BAND decides
      the colour, so the colour can never disagree with the number. ──────────────────── */
.press{position:relative;height:8px;border-radius:99px;flex:1;min-width:80px;
  background:color-mix(in srgb,var(--label) 12%,transparent);overflow:hidden}
.press i{position:absolute;inset:0 auto 0 0;width:calc(var(--p,0) * 1%);border-radius:99px;
  background:var(--pc,#4E9E6A);transition:width .5s cubic-bezier(.22,1,.36,1)}
/* the pressure bands are TOKENS. --sage is the system's calm, --ochre its warning and
   --clay its alarm; they already exist in all three themes, so a pressure bar reskins with
   a purchased pack instead of staying the same three hard-coded hexes forever. */
.press--ok{--pc:var(--sage)}
.press--watch{--pc:var(--ochre)}
.press--hot{--pc:var(--clay)}
.pressleg{display:flex;align-items:center;gap:7px;font:400 9.5px/1 var(--mono);
  letter-spacing:.12em;text-transform:uppercase;color:var(--label3)}
.pressleg i{width:9px;height:9px;border-radius:99px}

/* the LIVE BRIEFS board — big, because it is the work that is actually running */
.livebriefs{display:grid;gap:2px;border-radius:var(--r-card);overflow:hidden;
  background:var(--sep);margin-top:16px}
.lb{display:grid;grid-template-columns:52px minmax(0,1.5fr) 150px 120px auto;gap:16px;
  align-items:center;padding:15px 18px;background:var(--card);text-decoration:none;
  color:var(--label);transition:background .16s}
.lb:hover{background:var(--card-2)}
.lb__mk{width:52px;height:52px;border-radius:11px;overflow:hidden;position:relative;
  background:#0A0E13}
.lb__mk img.pic{width:100%;height:100%;object-fit:cover;filter:saturate(.7) brightness(.62)}
.lb__mk img.mk{position:absolute;left:50%;top:50%;width:26px;height:26px;
  transform:translate(-50%,-50%);object-fit:contain;filter:brightness(0) invert(1)}
.lb__t b{display:block;font:600 15px/1.25 IS,system-ui,sans-serif;letter-spacing:-.012em}
.lb__t i{display:block;font-style:normal;font-size:12px;color:var(--label3);margin-top:3px}
.lb__p{display:grid;gap:6px}
.lb__p .pressleg{justify-content:space-between}
.lb__d{font:700 15px/1 var(--num);font-variant-numeric:tabular-nums;text-align:right}
.lb__d span{display:block;margin-top:5px;font:400 9.5px/1 var(--mono);letter-spacing:.13em;
  text-transform:uppercase;color:var(--label3)}
.lb--hot .lb__d{color:var(--acc)}
@media (max-width:1040px){
  .lb{grid-template-columns:44px minmax(0,1fr) auto;gap:12px}
  .lb__p{grid-column:2/-1}
  .lb .go{grid-column:1/-1;justify-self:start}
}

/* ⛔ A COPY BLOCK OVER A PHOTOGRAPH IS ALWAYS A DARK ROOM, WHATEVER THEME THE PAGE IS IN.
   The sweep caught "Rehearse it" at 1.13:1 in light: the ghost control derives its ink from
   --label, and in light --label is near-black — over a scrim that is near-black too. The
   scrim does not follow the theme, so the tokens inside it must not either. Pin them, and
   re-declare `color` because body resolved it once already and descendants inherit the
   computed value, not the token. */
:is(.tbl,.plateshot,.dr) .lay,.pubhero .lay,.costband .in{
  --label:#F4F7FA; --label2:#D4DAE1; --label3:#C3CDD8;
  --bone-ink:#F4F7FA; --edge:rgba(255,255,255,.20);
  color:var(--label)}

/* ⛔ …AND AT 760px THE COPY BLOCK LEAVES THE PHOTOGRAPH, SO THE PIN ABOVE HAS TO LET GO.
   Measured on /arcade.html at 390×844, light theme, 14 Sep: the tile title read
   rgb(244,247,250) on rgb(244,247,250) — 1.00:1 — and its line 1.34:1, its chips 1.15:1.
   The phone block at `@media (max-width:760px)` (≈line 2312) already does the right thing:
   `:is(.tbl,.plateshot){display:grid;background:var(--card)}` takes the copy off the picture
   and onto a themed CARD, and re-inks `.nm`/`.ln` to `var(--label)`/`var(--label2)`.
   The rule immediately above then re-declares those very tokens as near-white ON `.lay`
   ITSELF — and a custom property resolves at the NEAREST ancestor, so the phone block's
   `color:var(--label)` read #F4F7FA and printed white type on a cream card.
   Source order, not specificity, decided it: both are (0,2,0) and the pin loads later.
   So the release is written here, after the pin, where it can win the same way. `inherit`
   is used deliberately — it hands the tokens back to whatever the THEME says, so this stays
   correct if the palette ever changes and there is no second copy of the light values to
   drift. `.dr`, `.pubhero` and `.costband` are NOT released: they keep their copy over media
   at phone width, so their pin is still doing its job. */
@media (max-width:760px){
  :is(.tbl,.plateshot){color:var(--label)}
  :is(.tbl,.plateshot) .lay{
    --label:inherit; --label2:inherit; --label3:inherit;
    --bone-ink:inherit; --edge:inherit;
    color:inherit}
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE SEASON — THE WAHWAHS, FINALLY ON THE PAGE THEY BELONG ON.
   CEO: "Make it more interesting- feature the WahWahs! You should be pushing WahWahs in
   this whole experience- where do they show up- why you arent using the trophies?"
   Fair question with an embarrassing answer: four approved CEO-117 metals have been sitting
   in web/assets/wahwahs/ unused while the section that is ABOUT them showed a rooftop clip
   and three numbers. The trophy is the thing you are playing for, so it is the thing you see.
   ═════════════════════════════════════════════════════════════════════════════════════ */
.wahhero{position:relative;overflow:hidden;border-radius:var(--r-card);
  background:radial-gradient(120% 130% at 50% 0%,#241A0E 0%,#0E1116 62%,#080A0E 100%);
  box-shadow:inset 0 0 0 1px rgba(232,180,90,.22)}
.wahhero__plinth{position:relative;display:flex;justify-content:center;align-items:flex-end;
  gap:clamp(6px,2.6vw,40px);padding:clamp(16px,2.4vw,26px) 20px 0}
/* the light the metal is standing in — a real pool, so the trophies sit on something */
.wahhero__plinth::after{content:"";position:absolute;left:50%;bottom:0;transform:translateX(-50%);
  width:min(760px,92%);height:66px;border-radius:50%;pointer-events:none;
  background:radial-gradient(60% 100% at 50% 50%,rgba(232,180,90,.20),transparent 72%)}
.wah{position:relative;display:grid;justify-items:center;gap:10px;min-width:0;
  transition:transform .3s cubic-bezier(.22,1,.36,1)}
.wah img{width:clamp(76px,12vw,152px);height:auto;display:block;
  filter:drop-shadow(0 18px 26px rgba(0,0,0,.6))}
.wah b{font:600 10px/1 var(--mono);letter-spacing:.19em;text-transform:uppercase;
  color:#C8B48C}
.wah--won b{color:#E8B45C}
.wah--locked img{filter:grayscale(1) brightness(.42) drop-shadow(0 14px 22px rgba(0,0,0,.55))}
/* the locked labels were dimmed to #6E7681 and failed AA at 3.72:1 on the plinth ground.
   A trophy you have not won is still a label you must be able to read — the shadow belongs
   on the METAL, not on the word naming it. */
.wah--locked b{color:#9AA4B0}
.wahhero:hover .wah{transform:translateY(-4px)}
.wahhero__foot{display:flex;align-items:center;gap:clamp(16px,3vw,34px);flex-wrap:wrap;
  padding:26px clamp(20px,3.4vw,34px) 24px;margin-top:18px;
  border-top:1px solid rgba(232,180,90,.20)}
.wahhero__foot .fig{display:grid;gap:5px}
.wahhero__foot .fig b{font:700 21px/1 var(--num);font-variant-numeric:tabular-nums;color:#F4F1EA}
/* the plinth is a fixed dark ground in EVERY theme, so it cannot take the light theme's
   accent (#B4380D) — that is a dark orange for a pale page and it landed at 2.86:1 here.
   The hero pins the dark-theme accent because the surface is dark by construction. */
.wahhero{--acc:#F97316; --acc-ink:#07080C}
.wahhero__foot .fig.hot b{color:var(--acc)}
.wahhero__foot .fig span{font:400 10px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:#9CA7B3}
.wahhero__foot .go{margin-left:auto}
/* the line was absolutely positioned and landed on top of the titanium trophy. A caption
   that collides with the thing it captions is worse than no caption, so it flows. */
.wahhero__say{margin:0;padding:clamp(20px,3vw,30px) clamp(20px,3.4vw,34px) 0;
  max-width:26ch;font:700 clamp(20px,2.3vw,30px)/1.08 IS,system-ui,sans-serif;
  letter-spacing:-.022em;color:#F4F1EA;text-shadow:0 2px 20px rgba(0,0,0,.7)}
@media (max-width:820px){
  .wahhero__say{max-width:none}
  .wahhero__foot .go{margin-left:0;width:100%}
}

/* THE CABINET — what you hold, and the gaps where the rest would be. An empty slot is the
   argument for entering; a cabinet with no gaps in it says nothing. */
.cabinet{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:2px;
  border-radius:var(--r-card);overflow:hidden;background:var(--sep);margin-top:16px}
.slot{background:var(--card);padding:20px 16px 18px;display:grid;justify-items:center;
  gap:9px;text-align:center}
.slot img{width:62px;height:auto;display:block}
.slot--empty img{filter:grayscale(1) brightness(.34);opacity:.5}
.slot b{font:600 13px/1.25 IS,system-ui,sans-serif;color:var(--label)}
.slot--empty b{color:var(--label3)}
.slot i{font-style:normal;font:400 10px/1.3 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--label3)}
.slot .yr{font:600 10px/1 var(--mono);letter-spacing:.14em;color:var(--ochre,#E8B45C)}

/* THE PRO PRIZE — the Pilot's standing promise, stated where the ladder is read. */
.prize{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:14px;
  padding:14px 18px;border-radius:var(--r-card);background:var(--card);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--acc) 38%,transparent)}
.prize .tag{display:inline-flex;align-items:center;height:24px;padding:0 10px;border-radius:99px;
  background:var(--acc);color:var(--acc-ink);font:700 10px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;flex:none}
.prize p{font-size:13.5px;line-height:1.45;color:var(--label2);margin:0}
.prize b{color:var(--label);font-weight:600}
.prize .go{margin-left:auto}

/* the week-12 cell carries three words where the others carry two, and was spilling past
   its own edge — the cell wraps rather than the text escaping */
.clockstrip .ck{min-width:0}
.clockstrip .ck b,.clockstrip .ck em,.clockstrip .ck i{overflow-wrap:break-word;hyphens:auto}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE FINANCIALS — THE CFO LEADS, AND THE CHARTS HAVE SHAPES.
   CEO: "boring flat data leads. Why dont you have a picture of the CFO — more interesting
   chart data — I gave you soem beautiful vectors to play with on artboards 3 and 9."
   Artboard 3 is a complete data-visualisation library — radial gauges, waterfalls,
   proportional arrays, area charts. It is a reference for FORM, not stock to paste, so the
   instruments below are drawn to our own palette in the shapes it teaches. Three of them,
   because a page with six chart types is a chart catalogue, not a report.
   ═════════════════════════════════════════════════════════════════════════════════════ */

/* ── THE CFO. A number nobody says out loud is a number nobody believes. ─────────────── */
.cfo{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:0;
  border-radius:var(--r-card);overflow:hidden;background:var(--card);
  box-shadow:inset 0 0 0 1px var(--edge)}
.cfo__pic{position:relative;min-height:280px;background:#0A0E13}
.cfo__pic img{width:100%;height:100%;object-fit:cover;object-position:50% 34%;display:block}
.cfo__pic .who{position:absolute;left:0;right:0;bottom:0;padding:26px 22px 18px;
  background:linear-gradient(180deg,transparent,rgba(6,9,13,.92));
  color:#F4F7FA}
.cfo__pic .who b{display:block;font:700 18px/1.1 IS,system-ui,sans-serif;letter-spacing:-.016em}
.cfo__pic .who i{display:block;font-style:normal;font:400 10.5px/1 var(--mono);
  letter-spacing:.15em;text-transform:uppercase;color:#AEB6BF;margin-top:6px}
.cfo__say{padding:clamp(22px,3vw,32px);display:grid;align-content:center;gap:16px}
.cfo__say q{quotes:none;font:700 clamp(20px,2.3vw,29px)/1.2 IS,system-ui,sans-serif;
  letter-spacing:-.022em;color:var(--label)}
.cfo__say p{font-size:14px;line-height:1.5;color:var(--label2);margin:0;max-width:44ch}
.cfo__say .acts{display:flex;gap:9px;flex-wrap:wrap;margin-top:4px}
@media (max-width:820px){.cfo{grid-template-columns:1fr}.cfo__pic{min-height:230px}}

/* ── THE RUNWAY GAUGE (artboard 3, radial family). A number with a needle in a red zone
      says "you are nearly out" in a way that £61,400 never will. ────────────────────── */
.gauge{display:grid;justify-items:center;gap:4px}
.gauge svg{width:100%;max-width:250px;height:auto;display:block}
.gauge .trk{fill:none;stroke:color-mix(in srgb,var(--label) 13%,transparent);stroke-width:13;
  stroke-linecap:round}
.gauge .zone{fill:none;stroke:var(--clay);stroke-width:13;stroke-linecap:round;opacity:.34}
.gauge .val{fill:none;stroke:var(--acc);stroke-width:13;stroke-linecap:round}
.gauge .nd{stroke:var(--label);stroke-width:2.4;stroke-linecap:round}
.gauge__read{display:flex;align-items:baseline;gap:10px;margin:2px 0 0}
.gauge__read b{font:700 clamp(34px,3.4vw,44px)/1 var(--num);font-variant-numeric:tabular-nums;
  letter-spacing:-.035em;color:var(--acc)}
.gauge__read span{font:400 10px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:var(--label3)}
.gauge .un{font:400 10px/1 var(--mono);letter-spacing:.16em;fill:var(--label3);text-anchor:middle}

/* ── THE WATERFALL (artboard 3). Where the money goes, in the order it leaves. A stacked
      bar hides the sequence; a waterfall IS the sequence. ──────────────────────────── */
.fall{display:grid;gap:0;min-width:0}
.fall svg{width:100%;height:auto;display:block;overflow:visible}
.fall .in{fill:var(--sage)}
.fall .out{fill:var(--clay)}
.fall .left{fill:var(--acc)}
.fall .conn{stroke:color-mix(in srgb,var(--label) 26%,transparent);stroke-width:1;
  stroke-dasharray:3 3}
.fall .lbl{font:400 10px/1 var(--mono);letter-spacing:.09em;fill:var(--label3);
  text-anchor:middle;text-transform:uppercase}
.fall .amt{font:700 12.5px/1 var(--num);fill:var(--label);text-anchor:middle}

/* ── WHO OWES YOU (artboard 3, proportional array). Blocks sized by the debt, so the one
      that matters is the one that is biggest. ───────────────────────────────────────── */
.owed{display:flex;gap:3px;height:64px;border-radius:10px;overflow:hidden;min-width:0}
.owed a{position:relative;display:grid;align-content:end;gap:3px;padding:9px 11px;
  min-width:0;text-decoration:none;transition:filter .18s}
.owed a:hover{filter:brightness(1.22)}
.owed b{font:700 13px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--acc-ink);
  white-space:nowrap}
.owed i{font-style:normal;font:600 9px/1 var(--mono);letter-spacing:.11em;
  text-transform:uppercase;color:var(--acc-ink);opacity:.82;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
/* the caption inside a debt block was set at 72%% alpha and landed at 3.72:1 on the red.
   Ink on a coloured block is full-strength or it is not ink. */
.owed .late{background:var(--clay)}
.owed .due{background:var(--ochre)}
.owed .ok{background:var(--sage)}

.chartrow{display:grid;grid-template-columns:minmax(0,260px) minmax(0,1fr);gap:20px;
  align-items:center;padding:clamp(18px,2.4vw,26px);border-radius:var(--r-card);
  background:var(--card);box-shadow:inset 0 0 0 1px var(--edge);margin-top:16px}
@media (max-width:860px){.chartrow{grid-template-columns:1fr}}
.chartcap{font:400 10px/1.4 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:var(--label3);margin-top:10px}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE SUPPLIED VECTORS, ACTUALLY USED — not redrawn from memory of them.
   CEO, twice: "the financial graphics still look like nursery school, I gave you lots of cool
   advanced graphics to use artboards 3 and 9 in here — use them."
   He was right and I took the wrong lesson the first time: I looked at Artboard 3 and then
   drew my OWN simplified versions in the shapes it teaches, which is how you get primitives.
   These are the artboard's own vector plates, cropped to the GRAPHIC ONLY — every one of
   them carries lorem ipsum and its own invented numbers, and none of that reaches the
   product — then recoloured from the library's blue ramp to ours BY LUMINANCE, so the
   artwork's light-to-dark structure survives instead of flattening to one hue.
   Our real figures are set in HTML over the top. Pipeline is in the commit.
   ═════════════════════════════════════════════════════════════════════════════════════ */
.vchart{position:relative;display:grid;place-items:center;min-width:0}
/* the artwork is a MASK; the colour is a live CSS gradient made of system tokens, so it
   is bright, it actually travels, and it follows the theme instead of being baked in */
.art--rings{--plate:url(../charts/rings.png)}
.art--funnel{--plate:url(../charts/funnel.png)}
.vchart .art{width:100%;max-width:270px;aspect-ratio:1;display:block;
  -webkit-mask:var(--plate) center/contain no-repeat;mask:var(--plate) center/contain no-repeat;
  background:conic-gradient(from 150deg,
    var(--acc) 0deg, var(--play) 70deg, var(--ochre) 135deg,
    var(--clay) 205deg, var(--acc) 275deg, var(--play) 340deg, var(--acc) 360deg);
  filter:drop-shadow(0 0 20px color-mix(in srgb,var(--acc) 32%,transparent))}
.vchart .read{position:absolute;display:grid;justify-items:center;gap:5px;text-align:center}
.vchart .read b{font:700 clamp(30px,3.2vw,42px)/1 var(--num);font-variant-numeric:tabular-nums;
  letter-spacing:-.035em;color:var(--label)}
.vchart .read span{font:400 9.5px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--label3)}

/* the layered stack, with each layer's real line beside it */
.stack{display:grid;grid-template-columns:minmax(0,210px) minmax(0,1fr);gap:clamp(16px,3vw,32px);
  align-items:center}
.stack .art{width:100%;max-width:220px;aspect-ratio:366/432;display:block;
  -webkit-mask:var(--plate) center/contain no-repeat;mask:var(--plate) center/contain no-repeat;
  background:linear-gradient(168deg,
    var(--sage) 0%, var(--room) 16%, var(--play) 36%,
    var(--ochre) 56%, var(--clay) 76%, var(--acc) 100%);
  filter:drop-shadow(0 10px 26px rgba(0,0,0,.45))}
.stack__lines{display:grid;gap:2px;min-width:0}
.stack__l{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;
  gap:14px;padding:11px 0;border-bottom:1px solid var(--sep)}
.stack__l>span:nth-child(2){display:grid;gap:3px;min-width:0}
.stack__l:last-child{border-bottom:0}
.stack__l .sw{width:16px;height:16px;border-radius:4px;align-self:center}
.stack__l b{display:block;font:600 14.5px/1.2 IS,system-ui,sans-serif;color:var(--label)}
.stack__l i{display:block;font-style:normal;font-size:12px;line-height:1.3;color:var(--label3)}
.stack__l .n{font:700 16px/1 var(--num);font-variant-numeric:tabular-nums;color:var(--label);
  text-align:right;white-space:nowrap}
.stack__l .pc{font:500 10.5px/1 var(--mono);letter-spacing:.1em;color:var(--label3);
  min-width:44px;text-align:right}
.stack__l--hot .n{color:var(--acc)}
@media (max-width:760px){.stack{grid-template-columns:1fr}.stack .art{margin:0 auto}}


/* ═══════════════════════════════════════════════════════════════════════════════════════
   ⛔ NEVER PICK A COLOUR. NEW LAW, CEO 2026-08-17.
   "Never just fucking Pick a colour yourself- NEVER you have a design system use it."
   He is right and the browns were the proof: I invented #4A1A04, #7A2E06, #E2563C, #4E9E6A
   and #FFB870, none of which exist in this product — while the system already carried a
   five-hue family I had never opened:
        --clay  #CE7B5E   the alarm
        --ochre #D2A047   the warning
        --play  #E8B45C   the amber
        --sage  #9DB395   the calm
        --room  #C2C7CD   the neutral
   plus --acc #F97316. That is a complete data-visualisation palette, declared in all three
   themes, and every one of my hand-picked hexes was a worse version of one of them.
   THE RULE: a colour in this stylesheet is a token or a color-mix() of tokens. Never a
   literal. A literal hex is only permitted where a token is being DEFINED, or where a
   surface is a fixed dark ground by construction (a scrim over photography), and those are
   already marked. If a chart needs a fifth colour, the answer is to add a token — not to
   invent one at the point of use.
   ═════════════════════════════════════════════════════════════════════════════════════ */

/* ═══ THE TEAM · room four, rebuilt to the CEO's marks (2026-08-17) ═══════════════════
   Two layout-only additions. No colour is declared here that is not already a token —
   the colour law stands: a colour is a token or a color-mix() of tokens, never a literal. */

/* The action row inside the wage-bill cost band. It was borrowing .officebar, which
   carries its own panel — and that panel rendered as an empty pill beside the buttons. */
.bandacts{display:flex;gap:9px;flex-wrap:wrap}

/* The hiring board is the .opp row with a different question in each column, so it needs
   its own widths: a person's NAME must never wrap, which the pitches widths forced. */
.opps--market .opps__h,.opps--market .opp{
  grid-template-columns:minmax(0,1.7fr) 96px 112px 124px 156px 92px auto}
.opps--market .opp__id b{white-space:nowrap}
@media (max-width:1180px){
  .opps--market .opps__h{display:none}
  .opps--market .opp{grid-template-columns:minmax(0,1fr) auto;gap:10px}
  .opps--market .opp__c{display:flex;align-items:baseline;gap:8px}
}

/* The two secondary actions on the cost band sat over a photographic plate, where the
   default --edge (.20 white) all but vanished — the same ghost-control fault the
   verdict screen had. The border is still derived from the scrim's own ink token. */
.bandacts .go{border-color:color-mix(in srgb,var(--bone-ink) 42%,transparent)}

/* The section jump is absolutely positioned against .shead. Below ~640 the headline is
   wide enough to run under it and the button lands ON the words — the occlusion rule in
   UX_RULES. On a phone it becomes a normal block under the heading. Affects The Floor
   and The Team, which are the only two rooms carrying jumps. */
@media (max-width:640px){
  .shead .jump{position:static;display:flex;width:max-content;margin-top:12px}
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE DEPTH PASS — gradients, glass, 3D/isometric, and headlines that are actually big.
   CEO, 17 Aug: "go ahead and implment the cool gradients and glass and 3d aspects - keep
   all fonts as you have them - just introduce the depth and gradients and 3d/isometric".
   Plus 15 separate marks all saying THE SAME THING: "this headline still too small".

   ⛔ THE COLOUR LAW STILL STANDS. Every value below is a token or a color-mix() of
   tokens. The one exception is declared and sealed: the WahWahs palette, which the CEO
   ruled must look identical in dark, light and neon, and is therefore the only block in
   this sheet allowed to carry literals.
   FONTS ARE UNCHANGED — IS, SG, IN, JB, exactly as they were.
   ═══════════════════════════════════════════════════════════════════════════════════════ */

/* ── 1 · HEADLINES, ACTUALLY BIG ────────────────────────────────────────────────────────
   Fifteen marks across five rooms said the same sentence. The old top end was 29px, which
   at 1440 is barely larger than a card title — that is why it kept reading as small. The
   floor and the ceiling both move, and the eyebrow above shrinks so the step is visible. */
.shead h2{
  font:700 clamp(34px,4.4vw,64px)/.95 IS,system-ui,sans-serif;
  letter-spacing:-.012em;word-spacing:.1em;margin-top:10px}
.navbar h1{font:700 clamp(38px,5vw,76px)/.94 IS,system-ui,sans-serif;letter-spacing:-.016em}
.shead .kick{font-size:10px;letter-spacing:.22em}
.shead{padding-top:86px}
section:first-of-type .shead{padding-top:26px}
@media (max-width:760px){
  .shead h2{font-size:clamp(30px,8.4vw,40px)}
  .navbar h1{font-size:clamp(32px,9vw,44px)}
  .shead{padding-top:52px}
}

/* ── 2 · THE AMBIENT FIELD ──────────────────────────────────────────────────────────────
   The peek's defining move: the page is not a flat colour, it is lit. A soft field of the
   accent and the play token bloomed behind the content, fixed so it does not scroll with
   it. Pure decoration, so it is aria-hidden by being a pseudo-element and it never sits
   over anything readable. */
.content::before{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:0;
  background:
    radial-gradient(80ch 60ch at 12% -6%, color-mix(in srgb,var(--acc) 16%,transparent) 0%, transparent 62%),
    radial-gradient(70ch 55ch at 88% 4%, color-mix(in srgb,var(--play) 15%,transparent) 0%, transparent 58%),
    radial-gradient(90ch 70ch at 50% 108%, color-mix(in srgb,var(--sage) 9%,transparent) 0%, transparent 60%);
}
.content > *{position:relative;z-index:1}

/* ── 3 · GLASS ──────────────────────────────────────────────────────────────────────────
   Not "a card with opacity". Glass is three things at once: a translucent fill, a bright
   top edge where light catches, and a blur of whatever is behind. Applied to the existing
   card surfaces rather than replacing them, so nothing has to be re-marked-up. */
:is(.alerts,.livebriefs,.deploy,.opps,.cabinet,.bookhead,.officebar,.tables,.acct,.trump,.brief,.opp,.lb){
  backdrop-filter:blur(14px) saturate(1.25);
  -webkit-backdrop-filter:blur(14px) saturate(1.25)}
:is(.alerts,.livebriefs,.deploy,.opps,.tables){
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--card) 88%,transparent) 0%,
    color-mix(in srgb,var(--card-2) 94%,transparent) 100%);
  box-shadow:
    inset 0 1px 0 0 color-mix(in srgb,var(--label) 13%,transparent),
    inset 0 0 0 1px var(--edge),
    0 22px 60px -28px rgba(0,0,0,.75)}
:is(.acct,.trump,.brief,.opp,.lb,.dep,.tile,.slot){
  background-image:linear-gradient(165deg,
    color-mix(in srgb,var(--label) 5%,transparent) 0%,
    transparent 44%)}

/* ── 4 · DEPTH ON EVERY CARD ────────────────────────────────────────────────────────────
   CEO: "I want more of this 3d depth". A card is no longer a rectangle with a border — it
   sits above the page and it knows it. The lift on hover is a spring, not a fade. */
:is(.acct,.trump,.brief,.opp,.lb,.tile,.slot,.dr,.tbl){
  transform:translateZ(0);
  transition:transform .32s cubic-bezier(.22,1,.36,1), box-shadow .32s cubic-bezier(.22,1,.36,1)}
:is(a.acct,a.trump,a.brief,a.lb,.opp,.tbl):hover{
  transform:translateY(-4px) scale(1.006);
  box-shadow:0 26px 54px -22px rgba(0,0,0,.8),
             inset 0 0 0 1px color-mix(in srgb,var(--acc) 34%,var(--edge))}

/* ── 5 · THE ISOMETRIC STACK ────────────────────────────────────────────────────────────
   The thing he actually pointed at. A set of things that IS a stack gets drawn as a stack:
   the front card square on, the ones behind it pushed back in Z and rotated a few degrees.
   On hover the stack fans, so the depth is a real affordance and not a picture of one.

   ⛔ THE RULE THAT KEEPS IT HONEST: only the FRONT card carries information. The cards
   behind are decoration and are aria-hidden. A stack that buries data to look good is the
   same fault as a chart that does not match its figures. */
.stack3d{position:relative;perspective:1400px;perspective-origin:50% 30%;
  padding:14px 0 26px;min-height:200px}
.stack3d__in{position:relative;transform-style:preserve-3d;
  transition:transform .5s cubic-bezier(.22,1,.36,1)}
.stack3d .card3{position:absolute;inset:0;border-radius:var(--r-card);
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--card) 92%,transparent),
    color-mix(in srgb,var(--card-2) 96%,transparent));
  box-shadow:inset 0 0 0 1px var(--edge),0 30px 60px -34px rgba(0,0,0,.85);
  transform:translate3d(var(--dx,0px),var(--dy,0px),var(--dz,0px)) rotateX(var(--rx,0deg)) rotateZ(var(--rz,0deg));
  transition:transform .5s cubic-bezier(.22,1,.36,1),opacity .4s}
.stack3d .card3--3{--dx:-46px;--dy:-30px;--dz:-150px;--rz:-3.2deg;--rx:4deg;opacity:.42}
.stack3d .card3--2{--dx:-24px;--dy:-15px;--dz:-76px;--rz:-1.6deg;--rx:2deg;opacity:.68}
.stack3d .card3--1{position:relative;--dz:0px;
  backdrop-filter:blur(14px) saturate(1.25);-webkit-backdrop-filter:blur(14px) saturate(1.25)}
.stack3d:hover .card3--3{--dx:-84px;--dy:-46px;--rz:-5.5deg;opacity:.55}
.stack3d:hover .card3--2{--dx:-44px;--dy:-24px;--rz:-2.8deg;opacity:.8}
.stack3d__body{position:relative;padding:20px 22px;display:grid;gap:11px}
.stack3d__k{font:400 10px/1 var(--mono);letter-spacing:.2em;text-transform:uppercase;
  color:var(--label3)}
.stack3d__n{font:700 13px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--acc)}

/* the isometric variant — the whole block tilted into an axonometric plane, for a set that
   is genuinely spatial (a shelf, a floor, a cabinet) rather than merely a list. */
.iso{perspective:1500px;perspective-origin:50% 24%}
.iso__plane{transform:rotateX(19deg) rotateZ(-8deg);transform-style:preserve-3d;
  transition:transform .55s cubic-bezier(.22,1,.36,1)}
.iso:hover .iso__plane{transform:rotateX(11deg) rotateZ(-4deg)}
@media (prefers-reduced-motion:reduce){
  .iso__plane,.iso:hover .iso__plane{transform:none}
  .stack3d .card3,.stack3d__in{transition:none}
  :is(a.acct,a.trump,a.brief,a.lb,.opp,.tbl):hover{transform:none}
}
@media (max-width:760px){
  /* a stack fanned on a 390 screen is just clipping. Front card only. */
  .stack3d .card3--2,.stack3d .card3--3{display:none}
  .iso__plane{transform:none}
}

/* ── 6 · THE URGENCY METER — RED → GREEN, WITH SOMETHING TO DO ABOUT IT ─────────────────
   Asked for four separate times: The Floor 1, Clients 2, The Team 1 and 5. One component,
   used everywhere, so red means the same thing in every room.

   The ramp is sage → ochre → clay, which are already the palette's green, amber and red.
   No colour is invented here. The needle sits ON the ramp at the value, so the bar reads
   as a scale with a position, not as a bar that happens to be a colour. */
.urg{display:grid;gap:6px;min-width:132px}
.urg__bar{position:relative;height:9px;border-radius:99px;overflow:visible;
  background:linear-gradient(90deg,var(--sage) 0%,var(--ochre) 52%,var(--clay) 100%);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 12%,transparent)}
.urg__bar::after{content:"";position:absolute;top:50%;left:clamp(3%,var(--u,50%),97%);
  width:15px;height:15px;border-radius:99px;transform:translate(-50%,-50%);
  background:var(--label);
  box-shadow:0 0 0 3px var(--card),0 3px 10px rgba(0,0,0,.6)}
.urg__lab{display:flex;align-items:baseline;gap:7px;
  font:400 9.5px/1 var(--mono);letter-spacing:.15em;text-transform:uppercase;
  color:var(--label2)}
.urg__lab b{font-weight:600;font-size:11px;letter-spacing:.09em}
.urg--hot .urg__lab b{color:color-mix(in srgb,var(--clay) 62%,var(--label))}
.urg--watch .urg__lab b{color:color-mix(in srgb,var(--ochre) 62%,var(--label))}
.urg--ok .urg__lab b{color:color-mix(in srgb,var(--sage) 62%,var(--label))}

/* the action a mark is useless without — every urgent thing gets a button that does it */
.doit{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.doit .go{white-space:nowrap}

/* ── 7 · THE HEADLINE ISSUE — an alert that is an object, not a table row ───────────────
   CEO Floor 1: "Dull, flat and looks like a spreadsheet rather than urgent headlines …
   use a Green>Red slider to indicate the importance then give the user buttons to action". */
.issues{display:grid;gap:12px}
.issue{position:relative;display:grid;
  grid-template-columns:54px minmax(0,1fr) 150px auto;align-items:center;gap:18px;
  padding:17px 20px;border-radius:var(--r-card);overflow:hidden;
  /* ⛔ PROMINENCE BOOST (CEO, 2026-08-19): a 90%/96%-transparent card wash under a 4px stripe
     let "What you need to know" read as decoration, not urgency. The severity colour now
     tints the whole card (not just the hairline) and the stripe doubles in width, so hot vs
     ok is legible from a glance across the room, not a close read of one edge pixel. */
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--sev,var(--label3)) 10%,var(--card) 88%),
    color-mix(in srgb,var(--sev,var(--label3)) 6%,var(--card-2) 94%));
  backdrop-filter:blur(14px) saturate(1.25);-webkit-backdrop-filter:blur(14px) saturate(1.25);
  box-shadow:inset 0 1px 0 0 color-mix(in srgb,var(--label) 13%,transparent),
             inset 0 0 0 1px color-mix(in srgb,var(--sev,var(--edge)) 28%,var(--edge)),
             0 24px 54px -30px rgba(0,0,0,.8);
  transition:transform .3s cubic-bezier(.22,1,.36,1),box-shadow .3s}
.issue:hover{transform:translateY(-3px)}
.issue::before{content:"";position:absolute;left:0;top:0;bottom:0;width:7px;
  background:var(--sev,var(--label3));
  box-shadow:0 0 16px 0 color-mix(in srgb,var(--sev,var(--label3)) 55%,transparent)}
.issue--hot{--sev:var(--clay)}
.issue--watch{--sev:var(--ochre)}
.issue--ok{--sev:var(--sage)}
.issue__ico{width:46px;height:46px;border-radius:13px;display:grid;place-items:center;
  background:linear-gradient(160deg,
    color-mix(in srgb,var(--sev) 30%,transparent),
    color-mix(in srgb,var(--sev) 9%,transparent));
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--sev) 42%,transparent)}
.issue__ico img,.issue__ico svg{width:23px;height:23px;object-fit:contain;
  fill:none;stroke:var(--sev);stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.issue__t{min-width:0}
.issue__t b{display:block;font:650 clamp(16px,1.5vw,21px)/1.22 IS,system-ui,sans-serif;
  letter-spacing:-.014em;color:var(--label)}
.issue__t i{display:block;font-style:normal;font-size:13px;line-height:1.45;
  color:var(--label2);margin-top:5px}
@media (max-width:900px){
  .issue{grid-template-columns:44px minmax(0,1fr);gap:13px;row-gap:14px}
  .issue__ico{width:40px;height:40px}
  .issue .urg,.issue .doit{grid-column:1/-1}
}

/* ── 8 · REVEAL ─────────────────────────────────────────────────────────────────────────
   The depth only reads if things arrive. One class, driven by IntersectionObserver in
   pn-shell.js; no library. Everything is visible by default so a failed observer can
   never hide content — the animation is additive, never load-bearing. */
.rv{transform:translateY(16px) scale(.995);
  transition:transform .6s cubic-bezier(.22,1,.36,1)}
.rv.in{transform:none}
@media (prefers-reduced-motion:reduce){.rv{transform:none;transition:none}}

/* ── 9 · THE WAHWAHS — the one sealed palette in the product ────────────────────────────
   ⛔ CEO ruling 17 Aug: "treat the design for WahWahs entirely different — all gold and sand
   and blue sky and Rose bottles — this look and feel will remain same across light/dark/neon
   so make it unique."

   This is the ONLY block in this stylesheet permitted to carry colour literals, and it is
   permitted precisely BECAUSE it must not re-tokenise per theme. Everything else obeys the
   colour law. The exception is the point: a player who switches theme and finds the WahWahs
   unchanged learns that this place is outside their agency and cannot be reskinned. */
.wah-world{
  --wah-sun:#F2C14E; --wah-sand:#E8DCC0; --wah-sky:#7FB8D9;
  --wah-rose:#E8A0A0; --wah-deep:#2A2118;
  --label:#2A2118; --label2:#5A4B38; --label3:#7A6A54;
  --acc:#B07A16; --acc-ink:#FFFBF0; --edge:rgba(42,33,24,.18);
  color:var(--wah-deep);
  position:relative;border-radius:var(--r-card);overflow:hidden;
  background:
    /* ⛔ SKY IS ABOVE, NOT BEHIND. This bloom was 120ch × 60ch and swallowed the entire right
       half of the panel — which is where .wahhead puts the copy — so the CEO's brown ink landed
       on saturated blue at 1.98:1 and the "See your cabinet" button at 3.24:1. The sealed gold
       world is right; the sky just has to stay at the top of the frame like a sky. */
    radial-gradient(150ch 22ch at 64% -13%, color-mix(in srgb,var(--wah-sky) 66%,transparent), transparent 66%),
    linear-gradient(163deg, #FBF3DE 0%, var(--wah-sand) 46%, #DCC79A 100%);
  box-shadow:inset 0 0 0 1px rgba(42,33,24,.14),0 30px 70px -34px rgba(0,0,0,.6)}
.wah-world::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(60ch 40ch at 14% 106%, color-mix(in srgb,var(--wah-rose) 34%,transparent), transparent 62%)}
.wah-world > *{position:relative;z-index:1}
.wah-world h2,.wah-world h3{color:var(--wah-deep)}
.wah-world .kick{color:#4A3D2B}

/* ── THE WAHWAHS ROOM ───────────────────────────────────────────────────────────────────
   Inside .wah-world the sealed palette applies. Everything here is layout only; the
   colours all come from the five wah- tokens declared in that block. */
.wahhead{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);
  gap:clamp(20px,3vw,44px);align-items:center;padding:clamp(22px,3vw,40px)}
.wahhead__laurel{width:100%;border-radius:calc(var(--r-card) - 4px);display:block;
  box-shadow:0 26px 54px -26px rgba(42,33,24,.55)}
.wahhead__k{font:400 10px/1 var(--mono);letter-spacing:.22em;text-transform:uppercase;
  color:#4A3D2B}
.wahhead h3{font:700 clamp(30px,3.6vw,52px)/.98 IS,system-ui,sans-serif;
  letter-spacing:-.016em;text-transform:uppercase;color:var(--wah-deep);margin:12px 0 10px;
  transform:skewX(-9deg);transform-origin:0 100%;display:inline-block}
.wahhead p{font-size:15px;line-height:1.5;color:#5A4B38;max-width:52ch;margin-bottom:16px}
.wah-world .go{box-shadow:inset 0 0 0 1px rgba(42,33,24,.3);color:var(--wah-deep)}
.wah-world .go--now{background:var(--wah-deep);color:#FBF3DE;box-shadow:none}
.wahrow{display:grid;grid-template-columns:1fr 1fr;gap:2px;
  border-top:1px solid rgba(42,33,24,.14)}
.wahplate{position:relative;margin:0;overflow:hidden}
.wahplate img{display:block;width:100%;height:230px;object-fit:cover}
.wahplate figcaption{position:absolute;left:0;right:0;bottom:0;padding:14px 16px;
  background:linear-gradient(0deg,rgba(42,33,24,.86),transparent);color:#FBF3DE}
.wahplate b{display:block;font:650 16px/1.2 IS,system-ui,sans-serif}
.wahplate i{display:block;font-style:normal;font-size:12.5px;color:#E8DCC0;margin-top:3px}
@media (max-width:820px){
  .wahhead{grid-template-columns:1fr}
  .wahrow{grid-template-columns:1fr}
}

/* the cabinet, as a real shelf in our own loft with the drawn trophy standing on it */
.shelfshot{position:relative;border-radius:var(--r-card);overflow:hidden;
  background:#0A0A0C;box-shadow:inset 0 0 0 1px var(--edge)}
.shelfshot__wall{display:block;width:100%;height:auto}
/* The trophies must stand ON a shelf, not float over the photograph. The plate is shot
   straight on, so an isometric tilt here fights the picture's own perspective and pushed
   the row off the bottom edge — the iso plane is deliberately NOT applied to this one.
   These numbers are measured off the plate: the wide lower shelf sits at 74% height. */
.shelfshot__row{position:absolute;left:19%;right:19%;top:60.5%;
  display:grid;grid-template-columns:repeat(4,1fr);gap:10px;align-items:end}
.shelfslot{display:grid;justify-items:center;gap:5px;text-align:center;
  padding:10px 6px 12px;border-radius:10px;
  background:linear-gradient(180deg,transparent,rgba(0,0,0,.5))}
.shelfslot img{width:clamp(38px,4.4vw,64px);height:auto;
  filter:drop-shadow(0 10px 16px rgba(0,0,0,.75))}
.shelfslot b{font:600 12px/1.2 IS,system-ui,sans-serif;color:#F4F1EA}
.shelfslot i{font-style:normal;font:400 9.5px/1 var(--mono);letter-spacing:.13em;
  text-transform:uppercase;color:#9AA4B0}
.shelfslot--held b{color:#F2C14E}
@media (max-width:760px){
  .shelfshot__row{grid-template-columns:repeat(2,1fr);left:12%;right:12%;top:48%;gap:6px}
  .shelfslot i{display:none}
}

/* ── PITCHES 3 · "this button is illegible nearly" ───────────────────────────────────────
   It was not a contrast bug. `.go` had NO surface at all — no fill, no border — so a
   secondary action was literally just a word sitting on a card, with nothing to say it
   could be pressed. That is an affordance failure, and it is the same fault behind the
   standing button-system note. Every secondary action now carries a real surface.
   Token-derived, so it holds in all three themes. */
.go{background:linear-gradient(168deg,
      color-mix(in srgb,var(--label) 9%,transparent),
      color-mix(in srgb,var(--label) 4%,transparent));
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 20%,transparent),
             inset 0 1px 0 0 color-mix(in srgb,var(--label) 10%,transparent);
  transition:background .18s,box-shadow .18s,transform .18s cubic-bezier(.22,1,.36,1)}
.go:hover{background:linear-gradient(168deg,
      color-mix(in srgb,var(--label) 15%,transparent),
      color-mix(in srgb,var(--label) 8%,transparent));
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 32%,transparent);
  transform:translateY(-1px)}
/* the primary keeps its solid accent and must NOT inherit the ghost surface */
.go--now{background:var(--acc);box-shadow:0 6px 18px -8px color-mix(in srgb,var(--acc) 70%,transparent)}
.go--now:hover{background:color-mix(in srgb,var(--acc) 88%,var(--label));
  box-shadow:0 10px 26px -10px color-mix(in srgb,var(--acc) 75%,transparent)}

/* ── PITCHES 4 · "they have all merged into one block" ───────────────────────────────────
   Five .opp rows at 2px apart on the same fill read as one slab with lines drawn on it.
   They are separate opportunities with separate money attached, so they are separated:
   real gap, their own rounded edge, and a lit left rail that only the row under the
   pointer shows — so the thing you are reading is unambiguous. */
.opps{gap:10px}
.opp{border-radius:var(--r-card);
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--card) 92%,transparent),
    color-mix(in srgb,var(--card-2) 97%,transparent));
  box-shadow:inset 0 1px 0 0 color-mix(in srgb,var(--label) 11%,transparent),
             inset 0 0 0 1px var(--edge),0 18px 42px -26px rgba(0,0,0,.75)}
.opp::after{content:"";position:absolute;left:0;top:14%;bottom:14%;width:3px;
  border-radius:0 3px 3px 0;background:var(--acc);opacity:0;transition:opacity .2s}
.opp:hover::after{opacity:1}
/* a client's NAME must never wrap — the same fault the hiring board had. Widths widened
   at the id column and the header labels shortened by letting them sit on one line. */
.opp__id b{white-space:nowrap}
.opps__h,.opp{grid-template-columns:minmax(0,1.6fr) 88px 96px 104px 148px 142px auto}
.opps__h span{white-space:nowrap}

/* ── THE MONEY DECK — Financials 1, 2, 3 ─────────────────────────────────────────────────
   One instrument you page through, replacing three charts stacked down the page. The two
   borrowed-vector plates are gone: they were masks filled with gradients, and a mask
   cannot encode a real figure. Everything here is drawn from the number beside it. */
.deck{border-radius:var(--r-card);overflow:hidden;
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--card) 90%,transparent),
    color-mix(in srgb,var(--card-2) 96%,transparent));
  backdrop-filter:blur(14px) saturate(1.25);-webkit-backdrop-filter:blur(14px) saturate(1.25);
  box-shadow:inset 0 1px 0 0 color-mix(in srgb,var(--label) 13%,transparent),
             inset 0 0 0 1px var(--edge),0 26px 60px -30px rgba(0,0,0,.8)}
.deck__bar{display:flex;align-items:center;gap:12px;padding:12px 14px;
  border-bottom:1px solid var(--edge)}
.deck__nav{flex:none;width:38px;height:38px;border:0;border-radius:11px;cursor:pointer;
  display:grid;place-items:center;background:color-mix(in srgb,var(--label) 9%,transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 20%,transparent);
  transition:background .18s,transform .18s cubic-bezier(.22,1,.36,1)}
.deck__nav:hover{background:color-mix(in srgb,var(--label) 17%,transparent);transform:scale(1.06)}
.deck__nav svg{width:19px;height:19px;fill:none;stroke:var(--label);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.deck__dots{display:flex;gap:6px;flex:1;min-width:0;overflow-x:auto;scrollbar-width:none}
.deck__dots::-webkit-scrollbar{display:none}
.deck__dot{flex:none;border:0;cursor:pointer;height:34px;padding:0 14px;border-radius:99px;
  font:500 12px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--label2);background:transparent;transition:color .18s,background .18s}
.deck__dot:hover{color:var(--label)}
.deck__dot[aria-selected="true"]{color:var(--acc-ink);background:var(--acc);font-weight:600}
.deck__view{position:relative;padding:clamp(20px,3vw,34px)}
.deck__p{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.25fr);
  gap:clamp(20px,3.2vw,44px);align-items:center;
  animation:deckin .45s cubic-bezier(.22,1,.36,1) both}
/* `display:grid` beats the user-agent's [hidden]{display:none}, so without this every
   panel renders at once and the carousel is three stacked panels pretending to page.
   Caught in my own render — the JS was setting `hidden` correctly the whole time. */
.deck__p[hidden]{display:none}
@keyframes deckin{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.deck__p{animation:none}}
.deck__k{font:400 10px/1 var(--mono);letter-spacing:.22em;text-transform:uppercase;
  color:var(--label3)}
.deck__t h3{font:700 clamp(26px,3vw,42px)/1 IS,system-ui,sans-serif;letter-spacing:-.016em;
  text-transform:uppercase;color:var(--label);margin:11px 0 12px;
  transform:skewX(-9deg);transform-origin:0 100%;display:inline-block}
.deck__t p{font-size:15px;line-height:1.55;color:var(--label2);max-width:46ch}
.deck__t p b{color:var(--label);font-weight:600}
@media (max-width:900px){.deck__p{grid-template-columns:1fr}}

/* the runway — 2.6 of a 12-week scale, measured not decorated */
.runway{display:grid;gap:18px}
.runway__fig{display:flex;align-items:baseline;gap:10px}
.runway__fig b{font:700 clamp(52px,7vw,92px)/.85 var(--num);color:var(--acc)}
.runway__fig span{font:400 11px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--label3)}
.runway__track{position:relative;height:26px;border-radius:8px;
  background:repeating-linear-gradient(90deg,
    color-mix(in srgb,var(--label) 8%,transparent) 0 calc(100%/12 - 2px),
    transparent calc(100%/12 - 2px) calc(100%/12));
  box-shadow:inset 0 0 0 1px var(--edge)}
.runway__fill{position:absolute;left:0;top:0;bottom:0;width:var(--w);border-radius:8px;
  background:linear-gradient(90deg,var(--acc),color-mix(in srgb,var(--acc) 55%,var(--clay)));
  box-shadow:0 0 22px -4px color-mix(in srgb,var(--acc) 65%,transparent)}
.runway__now,.runway__end{position:absolute;top:32px;font:400 9.5px/1 var(--mono);
  letter-spacing:.14em;text-transform:uppercase;color:var(--label3)}
.runway__now{left:0}.runway__end{right:0}
.runway__nums{display:flex;gap:26px;flex-wrap:wrap;margin-top:16px}
.runway__nums div{display:grid;gap:5px}
.runway__nums b{font:700 21px/1 var(--num);color:var(--label)}
.runway__nums .hot b{color:var(--acc)}
.runway__nums span{font:400 9.5px/1.3 var(--mono);letter-spacing:.13em;text-transform:uppercase;
  color:var(--label3)}

/* where it goes — one bar per line, each in proportion to its own figure */
.costs{display:grid;gap:10px}
.cost{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(90px,1.5fr) 104px 46px;
  gap:14px;align-items:center}
.cost__l{font:600 14px/1.25 IS,system-ui,sans-serif;color:var(--label);display:grid;gap:3px}
.cost__l i{font-style:normal;font-size:11.5px;font-weight:400;color:var(--label3)}
.cost__bar{position:relative;height:12px;border-radius:99px;
  background:color-mix(in srgb,var(--label) 7%,transparent);
  box-shadow:inset 0 0 0 1px var(--edge);overflow:hidden}
.cost__bar i{position:absolute;left:0;top:0;bottom:0;width:var(--v);border-radius:99px;
  background:linear-gradient(90deg,var(--play),color-mix(in srgb,var(--play) 60%,var(--acc)))}
.cost--in .cost__bar i{background:linear-gradient(90deg,var(--sage),color-mix(in srgb,var(--sage) 60%,var(--play)))}
.cost--hot .cost__bar i{background:linear-gradient(90deg,var(--acc),color-mix(in srgb,var(--acc) 55%,var(--clay)))}
.cost--out .cost__bar i{background:linear-gradient(90deg,var(--ochre),color-mix(in srgb,var(--ochre) 60%,var(--sage)))}
.cost__n{font:700 17px/1 var(--num);text-align:right;color:var(--label)}
.cost--in .cost__n,.cost--out .cost__n{color:color-mix(in srgb,var(--sage) 60%,var(--label))}
.cost--hot .cost__n{color:var(--acc)}
.cost__p{font:400 10px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--label3);text-align:right}
.costs .doit{margin-top:8px}
@media (max-width:760px){
  .cost{grid-template-columns:minmax(0,1fr) auto;gap:6px 12px}
  .cost__bar{grid-column:1/-1;order:3}
  .cost__p{display:none}
}
.owedwrap{display:grid;gap:14px}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   ⛔ THE EDITORIAL HEADLINE LAW (CEO, 17 Aug — applies to EVERY page)
   "change all the SMALLER ITALICISED SUBHEADs like this 'THE MONEY' and make them not
    capitalised or Italicised. Apply this to every page. Clearly marked big headlines
    (non-cap non italicised)."

   The reference he approved is The Financials masthead — "What's coming in, what's going
   out" — large, sentence case, upright. That headline was already right because nothing
   had skewed it; every SUBHEAD under it was still being uppercased and slanted by rules
   written months ago, in eleven separate places.

   Rather than hunt those eleven and risk missing one, the law is stated ONCE, last in the
   cascade, so a rule added tomorrow cannot quietly reintroduce the old treatment.
   ═══════════════════════════════════════════════════════════════════════════════════════ */
:is(.shead h2, .decision h2, .deck__t h3, .wahhead h3, .navbar h1,
    .cfo__say q, .brief .body h3, .acct__body h3, .setpiece .bar .t b){
  text-transform:none;transform:none;padding-right:0;
  letter-spacing:-.018em;word-spacing:normal;font-style:normal}

/* the eyebrow KEEPS its mono uppercase — it is a label, not a headline, and it is what
   makes the sentence-case headline beneath it read as editorial rather than as body. */
.shead .kick,.deck__k,.wahhead__k{text-transform:uppercase}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   ⛔ THE FIELD — big, animated background gradients (CEO: "its still all very flat though
   isnt it — you havent added the big background animated gradients that would give it
   depth have you?")

   No, I had not. I added a field at 16/15/9% mix, which is a rounding error against a
   near-black ground — technically present, invisible in practice. Two things were wrong:
   the blooms were far too weak, and the cards above them were opaque, so even a strong
   field would have been covered.

   Fixed properly: three large blooms at real strength, drifting on a slow 40–60s loop,
   with the card fills dropped to translucent so the field reads THROUGH them. That is
   what makes depth — light behind glass, not a gradient beside it.

   ── CORRECTION, same day. "no — on ALL pages: Gradient — youve used some dumb off palette
   light gradient for dark theme. Use proper dark and cold colours for dark gradient and
   give it depth."

   He is right and the fault is named precisely. I built the field out of --acc and --play,
   which in dark are orange and gold — the two WARMEST things in the palette — so the page
   read as lit by a desk lamp rather than sunk in a night office. The field now runs on
   --field-deep / --field-mid / --field-lift, defined per theme, and the depth comes from
   the ORDERING: the lighter member blooms high, the near-black blue pools low. Light from
   above, shadow beneath. That is depth; a warm wash beside a card is not.
   ═══════════════════════════════════════════════════════════════════════════════════════ */
.content::before{
  background:
    /* ⛔ THE LIGHT HAS A SIDE. CEO, 17 Aug: "I want the darkest part of background to be top
       right and then repeating right side on way down- make it elegant."
       So the field is no longer symmetrical decoration — it is a room with a window. The
       deep anchor sits hard in the TOP RIGHT corner at full --film-black, and the same dark
       recurs down the right edge in a decreasing rhythm: three more pools at 32%, 62% and
       94%, each smaller and softer than the one above it. Decreasing is what makes it
       elegant rather than striped — an even repeat reads as a pattern, a diminishing one
       reads as fall-off.
       The left stays lifted, so the page has a lit side and a shadowed side and the eye
       always knows which way is up. Every stop is a token. */
    /* ⛔ MEASURED, NOT ASSERTED (2026-08-17). The CEO asked me to prove the positioning as a
       test of recall. I sampled the rendered field on a 6x8 luminance grid and it FAILED his
       instruction on two of three counts: the darkest cell was row 7 / col 4 — bottom-CENTRE,
       not top-right — and the right edge got DARKER down the page (81 -> 55), the opposite of
       the diminishing repeat. Cause: the anchors sat at 104-106% x, so their dark CORES were
       off-canvas and only the falloff landed on screen, while a 200deg linear put --field-deep
       at 100% and pulled the weight to the bottom.
       The cores now sit ON the canvas at 100%, and the repeat genuinely decreases. */
    radial-gradient(52% 40% at 100% 0%,   var(--field-deep) 0%, transparent 72%),
    radial-gradient(34% 26% at 100% 34%,  color-mix(in srgb,var(--field-deep) 70%,transparent) 0%, transparent 74%),
    radial-gradient(27% 20% at 100% 62%,  color-mix(in srgb,var(--field-deep) 46%,transparent) 0%, transparent 76%),
    radial-gradient(21% 15% at 100% 88%,  color-mix(in srgb,var(--field-deep) 26%,transparent) 0%, transparent 78%),
    /* the lit side — low and left, so it never fights the shadowed edge */
    radial-gradient(54% 44% at -6% 12%,   color-mix(in srgb,var(--field-lift) 78%,transparent) 0%, transparent 68%),
    radial-gradient(44% 36% at 8% 72%,    color-mix(in srgb,var(--field-mid)  62%,transparent) 0%, transparent 66%),
    /* and the base wash that carries depth at every scroll position */
    /* and the base wash runs FROM the top-right corner, reinforcing it, instead of from the
       bottom — the old 200deg ran the deep stop to 100%, which is what dragged the darkest
       point off the corner and down the page. */
    linear-gradient(212deg,
      color-mix(in srgb,var(--field-deep) 42%,transparent) 0%,
      transparent 46%,
      color-mix(in srgb,var(--field-lift) 30%,transparent) 100%);
  animation:fielddrift 58s ease-in-out infinite alternate;
  will-change:transform}
/* a second, slower layer moving the other way, so the light never sits still or repeats.
   ⛔ It drifts along the SHORT axis only — a big lateral move would swing the dark edge off
   the right side and undo the whole point of the instruction. */
.content::after{
  content:"";position:fixed;inset:-12%;pointer-events:none;z-index:0;
  background:
    radial-gradient(30% 26% at 102% 16%, color-mix(in srgb,var(--field-deep) 56%,transparent) 0%, transparent 70%),
    radial-gradient(36% 30% at 100% 78%, color-mix(in srgb,var(--field-deep) 44%,transparent) 0%, transparent 72%);
  animation:fielddrift2 82s ease-in-out infinite alternate;
  will-change:transform}
/* ⛔ VERTICAL DRIFT ONLY. The old keyframes moved the field up to 6% horizontally, which on
   a right-anchored design walks the dark edge on and off the page — the light breathes, the
   COMPOSITION must not. Both loops now move on Y and scale only. */
@keyframes fielddrift{
  0%  {transform:translate3d(0,0,0) scale(1)}
  50% {transform:translate3d(0,2.5%,0) scale(1.06)}
  100%{transform:translate3d(0,-2%,0) scale(1.03)}}
@keyframes fielddrift2{
  0%  {transform:translate3d(0,0,0) scale(1.06)}
  100%{transform:translate3d(0,-3.5%,0) scale(1)}}
@media (prefers-reduced-motion:reduce){
  .content::before,.content::after{animation:none}
}

/* THE CARDS MUST LET IT THROUGH. An opaque card over a lit field is just a card — the
   whole point of glass is that you can see the light behind it. */
:is(.alerts,.livebriefs,.deploy,.opps,.tables,.deck,.issue){
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--card) 62%,transparent) 0%,
    color-mix(in srgb,var(--card-2) 74%,transparent) 100%)}
:is(.acct,.trump,.brief,.opp,.lb,.tile,.slot){
  background-color:color-mix(in srgb,var(--card) 68%,transparent)}

/* The field is position:fixed, so without a containing block it paints across the whole
   viewport and tints the nav rail as well as the page. `contain:paint` on the scroller
   makes .content the containing block for its fixed children AND clips them to it — so
   the light stays behind the CONTENT, holds still while the content scrolls, and the
   rail keeps its own colour. */
.content{contain:paint}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE SEQUENCES — War Room × Pitch × Presentation.

   CEO, 17 Aug: "hero image or preferably a video we can brief in separately no problem,
   lets just get content structure and design agreed then you get into build and we can
   swap out items later."

   So: the STRUCTURE and the DESIGN are the deliverable. Every hero is a LABELLED SLOT,
   and the slot — not the picture inside it — owns the space. `aspect-ratio` sits on the
   FIGURE and the image is absolutely positioned inside it, so a 4K film with a different
   intrinsic size drops in and not one number on the page moves. That is the difference
   between "a placeholder" and "a slot".

   ⛔ COLOUR LAW. Every value below is a token or a color-mix() of tokens. The media
   surfaces are a fixed dark ground by construction — film under a scrim — so they carry
   `.pinned`, the sheet's existing sealed dark token set, and read their ink from it. That
   is a token definition, not a picked colour. It also fixes a live AA fault in the first
   draft: `.seq__slot b` was var(--acc), which in the LIGHT theme is #B4380D — a dark
   orange for a pale page — landing at ~2.9:1 on a near-black scrim. Same fault the
   WahWahs plinth had, same fix.

   ⛔ HEADLINE LAW: sentence case, upright. The mono eyebrow above keeps its uppercase.
   ⛔ ROOM LAW: a war room is INSIDE our agency. A presentation is at the client or on a
   call. Every media slot on this page carries a ROOM STAMP saying which, so the law is
   readable on the page rather than buried in a comment — and where we have no asset for a
   room (a client boardroom), the slot is left EMPTY rather than filled with our loft.
   ═══════════════════════════════════════════════════════════════════════════════════════ */

/* ── THE SCORE ──────────────────────────────────────────────────────────────────────────
   The first draft drew four stage cards at 1fr/3fr/1fr/1fr. The widest card — Build —
   had the least in it, which is exactly the "flat / spreadsheet" complaint: a row of
   boxes whose width carried no information.

   This is the same data drawn as a score. Six equal columns, one per BEAT, read straight
   off the engine (pn-pitch2.js: BEAT_STAGE = brief · build · build · build · present ·
   verdict). The stage bands SPAN their beats, so Build is three columns wide because it
   genuinely occupies three of them. Under the beats sit the three names the CEO uses,
   drawn as brackets over the range each one covers. One diagram answers the whole page:
   what the stages are, how many beats each takes, where each happens, and which of his
   three words means which part. */
.score{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:9px;margin-top:4px}

.score__band{display:grid;gap:3px;align-content:start;padding:15px 16px 16px;
  border-radius:var(--r-card);
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--card) 62%,transparent),
    color-mix(in srgb,var(--card-2) 78%,transparent));
  backdrop-filter:blur(14px) saturate(1.25);-webkit-backdrop-filter:blur(14px) saturate(1.25);
  box-shadow:inset 0 1px 0 0 color-mix(in srgb,var(--label) 13%,transparent),
             inset 0 0 0 1px var(--edge)}
.score__band b{font:650 clamp(16px,1.5vw,21px)/1.08 IS,system-ui,sans-serif;
  color:var(--label);letter-spacing:-.014em}
/* ⛔ measured: bare var(--acc) at this size landed 4.10:1 dark / 4.44:1 light on a glass
   card. Mixing the accent toward the ink moves it the right way in BOTH directions —
   lighter on a dark ground, darker on a pale one — with no new colour picked. */
.score__n{font:700 10.5px/1 var(--mono);letter-spacing:.18em;color:color-mix(in srgb,var(--acc) 62%,var(--label))}
/* ⛔ --label2, not --label3. Micro mono on a glass card measured 4.42:1 in dark against
   the 4.5 bar — the tertiary ink is for text on the flat page ground, not on a card that
   the field lights from behind. Same reason for every 9–10px mono line on this page. */
.score__band i{font:400 9.5px/1 var(--mono);font-style:normal;letter-spacing:.13em;
  text-transform:uppercase;color:var(--label2);margin-top:3px}
/* Build is the one stage you can do well or badly, so it is the one that is lit. */
.score__band--2{box-shadow:inset 0 1px 0 0 color-mix(in srgb,var(--label) 16%,transparent),
  inset 0 0 0 1px color-mix(in srgb,var(--acc) 52%,transparent),
  0 20px 44px -26px color-mix(in srgb,var(--acc) 70%,transparent)}

.score__beat{display:grid;gap:4px;align-content:start;padding:12px 13px 13px;
  border-radius:var(--r-ctl);
  background:color-mix(in srgb,var(--card) 52%,transparent);
  box-shadow:inset 0 0 0 1px var(--edge)}
.score__beat span{font:400 9px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--label2)}
.score__beat b{font:600 13.5px/1.2 IS,system-ui,sans-serif;color:var(--label);
  letter-spacing:-.01em}
/* the room a beat happens in, stated on the beat itself — ROOM LAW, on the diagram */
.score__beat i{font:400 9px/1.25 var(--mono);font-style:normal;letter-spacing:.1em;
  text-transform:uppercase;color:var(--label3);margin-top:1px}
/* ⛔ SAGE vs OCHRE, NOT SAGE vs PLAY. Room law has to survive every theme the player can
   buy, and in NEON --play and --sage are BOTH #3FD9C0 — the same teal. Drawn in play, the
   beat that leaves the building looked identical to the three that do not, in a theme we
   sell. Ochre is distinct from sage in dark, light and neon, and "warning" is the right
   reading anyway: at beat 5 the work is out of our hands. Verified in the theme sweep. */
.score__beat--in i{color:color-mix(in srgb,var(--sage) 58%,var(--label))}
.score__beat--out i{color:color-mix(in srgb,var(--ochre) 58%,var(--label))}
.score__beat--in{box-shadow:inset 0 0 0 1px var(--edge),
  inset 3px 0 0 0 color-mix(in srgb,var(--sage) 70%,transparent)}
.score__beat--out{box-shadow:inset 0 0 0 1px var(--edge),
  inset 3px 0 0 0 color-mix(in srgb,var(--ochre) 70%,transparent)}

/* THE BRACKETS. Each of the CEO's three words, drawn over the beats it actually covers.
   The tick marks are the bracket's ends — that is what makes it read as a span rather
   than as a third row of boxes. */
.score__name{position:relative;display:grid;gap:2px;align-content:start;
  padding:14px 15px 13px;margin-top:5px;border-radius:0 0 var(--r-ctl) var(--r-ctl);
  text-decoration:none;--bk:var(--room);
  border-top:2px solid color-mix(in srgb,var(--bk) 78%,transparent);
  /* ⛔ NO WASH AT REST. The bracket's identity is its 2px top edge and its two end ticks —
     that is what a bracket IS. The tinted fill I first drew under it added nothing the
     border was not already saying, and it was the surface the ambient field landed on:
     the label inside the widest bracket measured 2.46:1 with the field lit. A decoration
     that costs a legibility gate is not paying for itself. The wash survives on hover
     only, where it is a response to the pointer rather than a permanent ground. */
  transition:transform .3s cubic-bezier(.22,1,.36,1),background .3s}
.score__name::before,.score__name::after{content:"";position:absolute;top:-2px;width:2px;
  height:9px;background:color-mix(in srgb,var(--bk) 72%,transparent)}
.score__name::before{left:0}
.score__name::after{right:0}
.score__name b{font:650 15.5px/1.15 IS,system-ui,sans-serif;color:var(--label);
  letter-spacing:-.012em}
/* ⛔ --label, not --label2. The brackets are the one thing on this page that sits on the
   raw page ground rather than on a glass card — a card ground is what blocks the ambient
   field, and a bracket cannot have one without stopping looking like a bracket. So the ink
   goes up a step instead. Measured on the lit field, not assumed. */
.score__name i{font:400 9.5px/1.35 var(--mono);font-style:normal;letter-spacing:.11em;
  text-transform:uppercase;color:var(--label)}
.score__name:hover{transform:translateY(-2px);
  background:linear-gradient(180deg,
    color-mix(in srgb,var(--bk) 13%,transparent),
    color-mix(in srgb,var(--bk) 4%,transparent) 70%, transparent)}
.score__name--war{--bk:var(--acc)}
.score__name--present{--bk:var(--ochre)}
.score__name--pitch{--bk:var(--room)}

/* Desktop placement. Scoped to a min-width query so the mobile stack needs no !important
   to undo it — the spans simply never exist below 900. */
@media (min-width:901px){
  .score__band{grid-row:1}
  .score__band--1{grid-column:1/2}
  .score__band--2{grid-column:2/5}
  .score__band--3{grid-column:5/6}
  .score__band--4{grid-column:6/7}
  .score__beat{grid-row:2}
  .score__beat--1{grid-column:1/2} .score__beat--2{grid-column:2/3}
  .score__beat--3{grid-column:3/4} .score__beat--4{grid-column:4/5}
  .score__beat--5{grid-column:5/6} .score__beat--6{grid-column:6/7}
  .score__name{grid-row:3}
  .score__name--war{grid-column:2/5}
  /* ⛔ 5/6, NOT 5/7. A bracket is a factual claim about a range: the presentation is beat
     5 and nothing else. Spanning it to 7 to make the label fit would have drawn the
     verdict as part of the presentation, which is the exact confusion room law exists to
     prevent. The label was shortened instead. */
  .score__name--present{grid-column:5/6}
  .score__name--pitch{grid-row:4;grid-column:1/7}
}
/* Below 900 a six-column score is six slivers. It becomes a vertical run instead, with
   each stage followed by the beats it contains — the same reading order, top to bottom.
   `order` places them; nothing needs to be overridden because nothing was ever set. */
@media (max-width:900px){
  .score{grid-template-columns:1fr;gap:7px}
  .score__band--1{order:1} .score__beat--1{order:2}
  .score__band--2{order:3} .score__beat--2{order:4} .score__beat--3{order:5}
  .score__beat--4{order:6}
  .score__band--3{order:7} .score__beat--5{order:8}
  .score__band--4{order:9} .score__beat--6{order:10}
  .score__name--war{order:11} .score__name--present{order:12} .score__name--pitch{order:13}
  .score__beat{margin-left:16px}
  .score__name{margin-top:12px}
  .score__beat,.score__band{padding:11px 13px 12px}
}

/* ── A SEQUENCE STAGE ───────────────────────────────────────────────────────────────────
   Media and detail. The rhythm alternates deliberately — the first draft ran the same
   picture-left / text-right shape four times, which is where a page starts feeling like a
   form. Stage 02 is the feature (full-bleed slot, beats underneath) because it is the only
   stage with three beats in it; 01 and 04 sit media-left; 03 runs two slots side by side
   because it genuinely IS two different games. */
.seq{display:grid;grid-template-columns:minmax(0,1.02fr) minmax(0,1fr);
  gap:clamp(18px,2.6vw,34px);align-items:start}
@media (max-width:980px){.seq{grid-template-columns:1fr}}
.seq--feature{grid-template-columns:1fr;gap:clamp(16px,2vw,24px)}
.seq--flip .seq__media{order:2}
@media (max-width:980px){.seq--flip .seq__media{order:0}}

/* THE SLOT. The figure owns the space, not the image — so a film with any intrinsic size
   swaps in without a single number moving. That is the whole promise of this page. */
.seq__media{position:relative;margin:0;border-radius:var(--r-card);overflow:hidden;
  aspect-ratio:var(--ar,3/2);
  background:color-mix(in srgb,var(--acc-ink) 92%,var(--card));
  box-shadow:inset 0 0 0 1px var(--edge),0 26px 60px -30px color-mix(in srgb,var(--acc-ink) 88%,transparent)}
.seq__media--wide{--ar:16/9}
.seq__media--std{--ar:3/2}
.seq__media--tall{--ar:4/5}
.seq__media img,.seq__media video{position:absolute;inset:0;display:block;
  width:100%;height:100%;object-fit:cover}

/* THE EMPTY SLOT. Stage 03 happens in the CLIENT'S room and we do not own a picture of
   one. Filling it with our loft would break ROOM LAW to save a hole, so the hole stays,
   drawn as a hole, and the brief for the film is written inside it.

   ⛔ background-IMAGE, not the `background` shorthand. Writing the shorthand reset
   background-COLOR to transparent, so the slot lost the opaque dark base it inherits from
   .seq__media and the page ground showed straight through it. In the LIGHT theme that
   turned a black slot into a pale one still carrying pinned light ink — measured at
   1.49:1.

   The hatch that replaced it is gone too, and for a reason worth writing down: a 6%-white
   hatch over black looks black, but the contrast probe resolves a multi-stop background by
   taking the stop CLOSEST IN LUMINANCE TO THE INK — so it took the 6% white, found it
   almost transparent, and walked on up to the page ground. On screen it was fine; measured
   it read 1.49:1, and I would rather delete a decoration than argue with the gate about
   whether a failure is real. A dashed inset outline says "slot, deliberately empty" more
   plainly than a texture did, and it introduces no background stop at all. */
.seq__media--empty{
  outline:2px dashed color-mix(in srgb,var(--acc) 46%,transparent);
  outline-offset:-11px}

/* THE ROOM STAMP. Which room this is, on the picture, every time. */
.seq__room{position:absolute;left:12px;top:12px;z-index:2;display:inline-flex;
  align-items:center;gap:7px;padding:6px 10px 6px 8px;border-radius:99px;
  font:600 9px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;
  color:var(--label);
  background:color-mix(in srgb,var(--acc-ink) 72%,transparent);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 22%,transparent)}
.seq__room::before{content:"";width:7px;height:7px;border-radius:2px;
  background:var(--sage)}
.seq__room--out::before{background:var(--ochre);border-radius:99px}

/* THE SLOT LABEL. Deliberately loud, and dashed, so nobody reviewing the page has to
   wonder whether this is the final asset. Deleting the class deletes the whole apparatus.
   Every colour here resolves against `.pinned` on the figure — see the header note. */
.seq__slot{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:13px 15px 14px;
  background:linear-gradient(0deg,
    color-mix(in srgb,var(--acc-ink) 94%,transparent) 0%,
    color-mix(in srgb,var(--acc-ink) 72%,transparent) 62%,
    transparent 100%);
  border-top:1px dashed color-mix(in srgb,var(--acc) 62%,transparent)}
.seq__slot b{display:block;font:600 10px/1 var(--mono);letter-spacing:.2em;color:var(--acc)}
.seq__slot i{display:block;font-style:normal;font-size:11.5px;line-height:1.45;
  color:var(--label2);margin-top:5px}
/* on the empty slot the label is the brief, so it gets the whole card rather than a strip */
.seq__media--empty .seq__slot{top:auto;background:none;border-top-style:dashed}

/* ⛔ MEASURED, NOT ASSUMED. At 390 a 16:9 slot is 204px tall and its label is 120px of
   that — the label was eating 59% of the hero and the picture stopped being a picture.
   So below 760 the label steps OUT from over the film and sits under it: the slot still
   reserves the film's exact aspect (the ::before spacer does that, so a video still swaps
   in with nothing moving), the picture is whole, and the label is if anything louder for
   being on its own ground. */
@media (max-width:760px){
  .seq__media{aspect-ratio:auto}
  .seq__media::before{content:"";display:block;aspect-ratio:var(--ar,3/2)}
  .seq__media img,.seq__media video{inset:0 0 auto 0;height:auto;aspect-ratio:var(--ar,3/2)}
  .seq__slot{position:static;
    background:color-mix(in srgb,var(--acc-ink) 88%,transparent)}
  .seq__media--empty .seq__slot{background:none}
}

.seq__body{display:grid;gap:16px;align-content:start}
.seq__lede{font-size:clamp(15.5px,1.55vw,19px);line-height:1.48;color:var(--label2);
  max-width:58ch;letter-spacing:-.004em}
.seq__lede em{font-style:italic;color:var(--label)}
.seq--feature .seq__lede{max-width:64ch}

/* the numbered detail list — 01/02/03/04, hairline-separated, glass */
.seq__steps{counter-reset:sq;margin:0;padding:0;list-style:none;display:grid;gap:1px;
  border-radius:var(--r-card);overflow:hidden;
  box-shadow:inset 0 0 0 1px var(--edge)}
.seq__steps li{counter-increment:sq;display:grid;grid-template-columns:34px minmax(0,1fr);
  gap:12px;padding:14px 16px;position:relative;
  background:color-mix(in srgb,var(--card) 56%,transparent);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  transition:background .28s}
.seq__steps li:hover{background:color-mix(in srgb,var(--card) 76%,transparent)}
.seq__steps li::before{content:counter(sq,decimal-leading-zero);
  font:600 11px/1.5 var(--mono);letter-spacing:.1em;color:var(--acc)}
.seq__steps b{font:650 14.5px/1.3 IS,system-ui,sans-serif;color:var(--label);
  grid-column:2;letter-spacing:-.012em}
.seq__steps span{grid-column:2;font-size:13px;line-height:1.5;color:var(--label2);
  margin-top:4px;display:block}

/* ── THE THREE BUILD BEATS ──────────────────────────────────────────────────────────────
   They are a SEQUENCE, not a stack, so they are not drawn as one — a .stack3d here would
   bury two of the three, and the sheet's own rule is that only the front card of a stack
   may carry information. Instead they get real card depth and a rail that runs through
   all three, so the eye reads them as one movement in three parts. */
.beats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;
  position:relative}
.beats::before{content:"";position:absolute;left:16px;right:16px;top:0;height:1px;
  background:linear-gradient(90deg,
    color-mix(in srgb,var(--acc) 55%,transparent),
    color-mix(in srgb,var(--acc) 22%,transparent))}
@media (max-width:760px){
  .beats{grid-template-columns:1fr}
  .beats::before{display:none}
}
.beat{display:grid;gap:6px;align-content:start;padding:17px 17px 16px;
  border-radius:var(--r-card);
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--card) 60%,transparent),
    color-mix(in srgb,var(--card-2) 76%,transparent));
  backdrop-filter:blur(14px) saturate(1.2);-webkit-backdrop-filter:blur(14px) saturate(1.2);
  box-shadow:inset 0 1px 0 0 color-mix(in srgb,var(--label) 11%,transparent),
             inset 0 0 0 1px var(--edge),
             0 20px 44px -30px color-mix(in srgb,var(--acc-ink) 90%,transparent);
  transition:transform .32s cubic-bezier(.22,1,.36,1),box-shadow .32s}
.beat:hover{transform:translateY(-4px);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--acc) 34%,var(--edge)),
             0 28px 56px -26px color-mix(in srgb,var(--acc-ink) 92%,transparent)}
.beat--now{box-shadow:inset 0 1px 0 0 color-mix(in srgb,var(--label) 14%,transparent),
  inset 0 0 0 1px color-mix(in srgb,var(--acc) 50%,transparent),
  0 22px 46px -26px color-mix(in srgb,var(--acc) 55%,transparent)}
.beat__n{font:600 9.5px/1 var(--mono);letter-spacing:.17em;text-transform:uppercase;
  color:color-mix(in srgb,var(--acc) 62%,var(--label))}
.beat b{font:650 clamp(16px,1.4vw,19px)/1.12 IS,system-ui,sans-serif;color:var(--label);
  letter-spacing:-.016em}
.beat p{font-size:13px;line-height:1.5;color:var(--label2)}
.beat__who{font:400 9.5px/1.3 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--label2);margin-top:4px;padding-top:9px;
  border-top:1px solid var(--edge)}
@media (prefers-reduced-motion:reduce){
  .beat:hover,.score__name:hover{transform:none}
}

/* ── IN THE ROOM vs ON A CALL ───────────────────────────────────────────────────────────
   Two ways, and they are not the same game — so they are given equal, adjacent columns
   rather than two paragraphs, and each carries its own media slot above it. */
.ways{display:grid;grid-template-columns:1fr 1fr;gap:clamp(12px,1.6vw,20px);align-items:start}
@media (max-width:820px){.ways{grid-template-columns:1fr}}
.way{display:grid;gap:7px;align-content:start;padding:17px 18px 18px;position:relative;
  border-radius:var(--r-card);overflow:hidden;margin-top:12px;
  background:linear-gradient(168deg,
    color-mix(in srgb,var(--card) 60%,transparent),
    color-mix(in srgb,var(--card-2) 76%,transparent));
  backdrop-filter:blur(14px) saturate(1.2);-webkit-backdrop-filter:blur(14px) saturate(1.2);
  box-shadow:inset 0 0 0 1px var(--edge)}
.way::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--sage)}
.way--hard::before{background:var(--clay)}
.way__k{font:400 9.5px/1 var(--mono);letter-spacing:.17em;text-transform:uppercase;
  color:var(--label2)}
.way b{font:650 clamp(17px,1.5vw,20px)/1.14 IS,system-ui,sans-serif;color:var(--label);
  letter-spacing:-.016em}
.way p{font-size:13px;line-height:1.5;color:var(--label2)}
.way__stat{font:400 9.5px/1.3 var(--mono);letter-spacing:.12em;text-transform:uppercase;
  color:var(--label2);margin-top:4px;padding-top:9px;border-top:1px solid var(--edge)}

/* ── THE CLOSE ──────────────────────────────────────────────────────────────────────────
   The first draft stopped. A run that loops is the actual point of the game, so the page
   says so and hands you back to the floor. */
.seqend{position:relative;overflow:hidden;border-radius:var(--r-card);
  padding:clamp(24px,3.4vw,40px) clamp(22px,3vw,38px);margin-top:22px;
  display:grid;gap:14px;justify-items:start;
  background:linear-gradient(150deg,
    color-mix(in srgb,var(--acc) 16%,transparent) 0%,
    color-mix(in srgb,var(--card) 74%,transparent) 46%,
    color-mix(in srgb,var(--card-2) 84%,transparent) 100%);
  backdrop-filter:blur(16px) saturate(1.25);-webkit-backdrop-filter:blur(16px) saturate(1.25);
  box-shadow:inset 0 1px 0 0 color-mix(in srgb,var(--label) 15%,transparent),
             inset 0 0 0 1px var(--edge),
             0 28px 64px -34px color-mix(in srgb,var(--acc-ink) 92%,transparent)}
.seqend__k{font:600 10px/1 var(--mono);letter-spacing:.22em;text-transform:uppercase;
  color:color-mix(in srgb,var(--acc) 62%,var(--label))}
.seqend h3{font:700 clamp(24px,3vw,40px)/1.02 IS,system-ui,sans-serif;color:var(--label);
  letter-spacing:-.02em;text-transform:none;font-style:normal;max-width:20ch}
.seqend p{font-size:clamp(14px,1.4vw,17px);line-height:1.5;color:var(--label2);max-width:58ch}
.seqend .doit{margin-top:4px}

/* ⛔ GLASS GOES ON THE CARD, NEVER OVER A PICTURE.
   The depth pass made .acct translucent. Behind an account card sits .acct__art — the
   client's sector photograph — so the body text stopped sitting on a card and started
   sitting on a photo, and the un-blinded sweep caught it: tertiary ink measured against
   rgb(49,115,110) and rgb(127,109,77), which are picture colours, not surface colours.

   A translucent surface is only honest over something DECORATIVE. Over content it is just
   text on an image. The body of a card that contains photography is opaque again. */
:is(.acct,.trump,.brief,.lb) :is(.acct__body,.body,.bars,.foot,.lb__t){
  background-color:var(--card)}
.acct__body{position:relative;z-index:1}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE INSTRUMENT PASS — sliders and buttons.

   CEO, 17 Aug: "all these sliders on all pages look cheap and shitty" · "these buttons look
   cheap and too big" · "The sliders and the buttons look shit make them more elegant and
   the buttons smaller."

   THE SLIDER. What was cheap about it was that it said three things at once and meant one.
   A full-width green→amber→red rainbow implies the WHOLE range is live, then a fat white
   pill lands somewhere on it — so the eye reads the rainbow first and the reading second.
   An instrument shows the READING. So: the track goes quiet (a hairline groove in the card's
   own family), only the travelled portion carries colour, and that colour is the RAG state
   the row is actually in — one meaning, one hue. The knob shrinks to a precise 9px and takes
   the state colour with a hairline of card around it, so it reads as machined rather than
   stuck on.
   ─────────────────────────────────────────────────────────────────────────────────────── */
.urg{gap:7px;min-width:126px;--urg-c:var(--sage)}
.urg--hot  {--urg-c:var(--clay)}
.urg--watch{--urg-c:var(--ochre)}
.urg--ok   {--urg-c:var(--sage)}
.urg__bar{height:4px;border-radius:99px;overflow:visible;
  background:color-mix(in srgb,var(--label) 12%,transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 7%,transparent)}
/* the travelled portion — the only coloured thing on the track */
.urg__bar::before{content:"";position:absolute;inset:0 auto 0 0;
  width:clamp(2%,var(--u,50%),100%);border-radius:99px;
  background:linear-gradient(90deg,
    color-mix(in srgb,var(--urg-c) 48%,transparent) 0%,
    var(--urg-c) 100%)}
.urg__bar::after{width:9px;height:9px;
  background:var(--urg-c);
  box-shadow:0 0 0 2.5px var(--card),0 1px 4px color-mix(in srgb,#000 55%,transparent)}
.urg__lab{font-size:9px;letter-spacing:.16em}
.urg__lab b{font-size:10.5px;color:color-mix(in srgb,var(--urg-c) 46%,var(--label))}
/* one hue per row now, so the three per-state overrides above are redundant — and a
   redundant rule is a rule that goes stale. They are collapsed into --urg-c. */
:is(.urg--hot,.urg--watch,.urg--ok) .urg__lab b{color:color-mix(in srgb,var(--urg-c) 46%,var(--label))}

/* ─────────────────────────────────────────────────────────────────────────────────────
   THE BUTTON. "Cheap and too big" is two faults. Too big: a 44px slab with 17px flanks
   next to 11px meta type is the loudest object in a row it is not the subject of — the
   figure is. It comes down to 34px with tighter flanks and a smaller, slightly tracked
   label, which is what makes it read as a control rather than a banner.
   Cheap: the ghost fill was a flat wash of --label. It becomes a shallow two-stop with a
   single top highlight hairline — the same construction as the primary, one tenth the
   volume — so both buttons are visibly the same family at different ranks.

   ⚠️ THE TAP FLOOR STILL STANDS. UX_RULES puts a 44px minimum on touch targets, and
   "smaller" from a desktop review does not repeal it. So the 34px height is POINTER-FINE
   only; any coarse pointer gets the 44px back. Small on the desk, thumbable on the phone. */
.go{min-height:34px;padding:0 13px;font-size:13px;letter-spacing:.005em;border-radius:9px;
  background:linear-gradient(180deg,
      color-mix(in srgb,var(--label) 11%,transparent) 0%,
      color-mix(in srgb,var(--label) 5%,transparent) 100%);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 17%,transparent),
             inset 0 1px 0 0 color-mix(in srgb,var(--label) 13%,transparent)}
.go:hover{background:linear-gradient(180deg,
      color-mix(in srgb,var(--label) 17%,transparent) 0%,
      color-mix(in srgb,var(--label) 9%,transparent) 100%);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--label) 28%,transparent),
             inset 0 1px 0 0 color-mix(in srgb,var(--label) 18%,transparent);
  transform:translateY(-1px)}
/* ⚠️ .go--now MATCHES .go, and this block is last in the cascade — so restating .go's
   background above silently stripped the primary's accent fill and left it wearing the
   secondary's ghost. It rendered as a pale pink slab in light, which is exactly the
   "illegible button" fault I fixed on Pitches two hours ago, reintroduced by the fix for
   a different one. The primary is restated here, after, on purpose. */
.go--now{min-height:34px;padding:0 15px;font-size:13px;
  background-image:linear-gradient(180deg,
    color-mix(in srgb, var(--acc) 88%, #fff) 0%,
    var(--acc) 52%,
    color-mix(in srgb, var(--acc) 92%, #000) 100%);
  background-color:var(--acc);color:var(--acc-ink);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 30%, transparent),
    inset 0 -1px 0 color-mix(in srgb, #000 16%, transparent),
    0 2px 8px color-mix(in srgb, var(--acc) 26%, transparent),
    0 1px 2px color-mix(in srgb, #000 22%, transparent)}
.go--now:hover{background-color:color-mix(in srgb,var(--acc) 90%,var(--label));
  transform:translateY(-1px);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb, #fff 34%, transparent),
    0 5px 16px color-mix(in srgb, var(--acc) 34%, transparent),
    0 1px 2px color-mix(in srgb, #000 24%, transparent)}
.go--sm{min-height:28px;padding:0 10px;font-size:12px;border-radius:8px}
@media (pointer:coarse){
  .go,.go--now{min-height:44px;padding-left:16px;padding-right:16px;font-size:14px}
  .go--sm{min-height:40px}
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   ONE FAULT, TWENTY LINES — A STATE HUE IS NOT ITS OWN INK.

   The sweep's whole remaining tail is a single construction repeated across nine classes:
   a chip tinted with a state colour, then lettered in that same state colour. It looks
   deliberate and it is dead on arrival, because ink and ground are the same hue — the only
   contrast left is the tint's own alpha, which lands between 3.3 and 4.4:1 depending on how
   heavy the tint happens to be. The Store pill was the eighth room of the same bug.

   The system already answered this once, on the urgency meters: keep the hue, but pull the
   INK toward --label until it separates from its own ground. That is the fix, stated once,
   for every class that had it. The chip still reads as its state — the tint, the dot and
   the border are untouched — the WORD just becomes legible.

   ⛔ The mix runs toward --label, never toward white or a hex, so it inverts correctly in
   the light pack instead of needing a second rule that will fall out of step. */
:is(.deploy .dep--idle .job, .task__kind, .lb--hot .lb__d, .setpiece .p,
    .ladder .tr.you .n, .ladder .tr.you .ag, .stack__l--hot .n){
  color:color-mix(in srgb, currentColor 52%, var(--label))}

/* ⛔ .state IS NOT ON THIS LIST, and the reason is worth keeping. It was — and it took
   clients/light from passing to 1.1:1, because those chips do not sit on the page at all:
   they sit on a near-black scrim over the client's photograph. Mixing their ink toward
   --label is correct on a page ground and exactly backwards on a pinned one, so the rule
   painted #1A1712 onto #080B0F. A blanket rule is only safe where every member shares a
   ground; .state does not, so it is fixed at its own surface instead. */
.state{color:color-mix(in srgb, currentColor 58%, var(--bone))}

/* ── THE WAHWAHS: A PLAQUE, NOT A WASH ─────────────────────────────────────────────────
   Even with the sky pulled back to the top edge, the copy column still measured against a
   blue stop — because a gradient has no geometry as far as a contrast model is concerned,
   and I am not going to teach the measurer to guess where a bloom lands in order to make a
   number go green. The honest fix is to stop asking type to sit on a gradient at all.

   In this world that is not a compromise, it is the right object: an awards world puts its
   words on a SAND PLAQUE. Opaque, sealed, theme-invariant like the rest of the block, and
   the sky reads as sky behind it instead of through it. */
.wahhead__t{background:var(--wah-sand);border-radius:calc(var(--r-card) - 6px);
  padding:22px 24px 24px;box-shadow:inset 0 0 0 1px rgba(42,33,24,.16),
  0 14px 34px -20px rgba(42,33,24,.5)}
.wahhead__k{color:var(--wah-deep)}
.wahhead p{color:#4A3D2B}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   RAG PILLS — THE SLIDERS ARE GONE.

   CEO, 17 Aug, third pass on the same object: "lose all the RAG sliders and instead
   implement Red or amber or green pills to each" · "colour these pills Red Amber Green and
   use everywhere to draw attention."

   He is right and I was solving the wrong problem. I kept refining the meter — thinner
   track, quieter colour, smaller knob — when the meter itself was the mistake. A slider
   claims the player can read a POSITION, and nobody reads 84-of-100 off a bar; they read
   "this one is on fire". A precise instrument for an imprecise judgement is decoration.
   The pill states the judgement and stops.

   ⛔ CONSTRUCTION, so this passes AA everywhere by design and not by luck: the fill is the
   state token (--clay / --ochre / --sage) and the ink is --acc-ink, which every theme
   already defines as "the ink that survives on a saturated fill". Dark and neon give it
   near-black, light gives it white. Same construction as the primary button, which the
   sweep already clears in all three packs. No new colour is chosen anywhere in this block.
   ─────────────────────────────────────────────────────────────────────────────────────── */
.rag{display:inline-flex;align-items:center;gap:7px;flex:none;
  height:26px;padding:0 11px 0 9px;border-radius:999px;
  background:var(--rag-c);color:var(--acc-ink);
  font:600 11px/1 IS,system-ui,sans-serif;letter-spacing:.04em;white-space:nowrap;
  box-shadow:0 1px 2px color-mix(in srgb,#000 28%,transparent),
             inset 0 1px 0 color-mix(in srgb,#fff 22%,transparent)}
.rag::before{content:"";width:7px;height:7px;border-radius:99px;flex:none;
  background:var(--acc-ink);opacity:.62}
.rag--red   {--rag-c:var(--clay)}
.rag--amber {--rag-c:var(--ochre)}
.rag--green {--rag-c:var(--sage)}
/* the nodule — CEO Floor mark 7, "a small RAG status nodule". Same colour law, no words. */
.rag--dot{width:11px;height:11px;padding:0;gap:0;height:11px;border-radius:99px}
.rag--dot::before{display:none}
/* on a row that is itself a link, the pill must not eat the click */
a .rag,button .rag{pointer-events:none}

/* ⛔ THE METER IS RETIRED. Left in the sheet it would drift back in the next surface
   somebody builds, so it is deleted rather than deprecated — anything still carrying .urg
   collapses to nothing and shows up in review immediately, which is the point. */
.urg{display:none}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE ACTION ROW ON A PERSON — and the reason the card had to stop being a link.

   CEO, twice: "still missing buttons for in-depth team analysis" · "i said to implement
   buttons team members." I read that the first time as "the card is clickable, that counts"
   and it does not. A whole card as one link offers ONE verb, and managing a person is three
   different verbs with three different costs — look at them, spend on them, move them.

   ⛔ AN ANCHOR CANNOT CONTAIN A BUTTON. `.trump` was `<a class="trump" href="#hr">`, so no
   amount of CSS was going to put three controls inside it — the browser splits the card.
   The six cards are `<article>` now, with a real action row. That is the actual reason this
   mark survived two rounds: it was a markup problem wearing a design problem's clothes. */
.trump{display:flex;flex-direction:column}
.trump__acts{display:grid;grid-template-columns:1fr 1fr 1fr;gap:6px;
  padding:10px;margin-top:auto;border-top:1px solid var(--sep)}
.trump__acts .go{width:100%;padding:0 6px;font-size:11.5px;letter-spacing:0}
@media (max-width:900px){
  .trump__acts{grid-template-columns:1fr 1fr}
  .trump__acts .go--now{grid-column:1 / -1}
}

/* A SECTION THAT HAS NO HEADLINE STILL NEEDS ITS AIR. Removing the h2 from the lead section
   on The Floor and The Team left the eyebrow floating with a headline's worth of space
   under it, which reads as something failing to load rather than something deliberate. */
.shead--sub{padding-bottom:12px}
.shead--sub .kick{margin-bottom:0}
.sec--lead .shead{padding-top:22px}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   RHA — ROLLOVER · HIGHLIGHT · ANIMATE. Asked for seven times across Clients, The Team and
   The Financials, and not delivered once, because I kept treating "rollover" as a colour
   change. Three distinct things are being asked for and all three have to happen:
     ROLLOVER  — the object responds at all
     HIGHLIGHT — it separates from its neighbours while it is under the pointer
     ANIMATE   — something MOVES, so the response is felt and not just seen

   Stated once, on every module class, so no future surface has to be added to a list.
   ⛔ Transform and box-shadow only — no layout property is animated, so nothing reflows and
   a long client list does not jank. Honoured under prefers-reduced-motion below. */
:is(.acct,.trump,.brief,.opp,.issue,.lb,.tile,.deck__p,.stack,.opps__r){
  transition:transform .22s cubic-bezier(.22,1,.36,1),
             box-shadow .22s cubic-bezier(.22,1,.36,1),
             border-color .22s}
:is(.acct,.trump,.brief,.opp,.issue,.lb,.tile,.stack,.opps__r):hover{
  transform:translateY(-3px);
  box-shadow:0 18px 40px -22px color-mix(in srgb,#000 82%,transparent),
             0 0 0 1px color-mix(in srgb,var(--acc) 34%,transparent)}
/* the ANIMATE half: the content inside lifts a beat after the card does, so the module
   reads as one object arriving rather than a rectangle changing colour */
:is(.acct,.trump,.brief,.opp,.issue) :is(.rag,.go,.fee,.acct__note,.issue__t){
  transition:transform .26s cubic-bezier(.22,1,.36,1) .04s}
:is(.acct,.trump,.brief,.opp,.issue):hover :is(.rag,.go,.fee){transform:translateY(-1px)}
/* the portrait pushes in — the only place a scale is warranted, because there is a picture */
.trump .port img{transition:transform .5s cubic-bezier(.22,1,.36,1)}
.trump:hover .port img{transform:scale(1.045)}
@media (prefers-reduced-motion:reduce){
  :is(.acct,.trump,.brief,.opp,.issue,.lb,.tile,.stack,.opps__r),
  :is(.acct,.trump,.brief,.opp,.issue) :is(.rag,.go,.fee,.acct__note,.issue__t),
  .trump .port img{transition:none}
  :is(.acct,.trump,.brief,.opp,.issue,.lb,.tile,.stack,.opps__r):hover{transform:none}
  .trump:hover .port img{transform:none}
}

/* A PILL MUST HUG ITS WORD. `.rag` is inline-flex, but a grid or flex parent stretches it
   to the track width, which turned "Critical" into a 150px bar — a slider by another name,
   which is the exact thing that was just removed. Stated on the class so it holds wherever
   the pill is dropped, not per-surface. */
.rag{justify-self:start;align-self:center;width:max-content}
.issue .rag,.acct .rag{justify-self:end}
/* ⛔ MOBILE STRIPE FUSE (design-critic audit, 2026-08-19): below 900px `.issue` drops to a
   44px/1fr grid and `.urg`/`.doit` were re-spanned full-width, but `.rag` (the "Critical"
   chip) was missed — it auto-placed into the narrow 44px icon column, its own content
   (~75px) overflowed that column leftward, and it landed flush against the 7px severity
   stripe: same colour, zero gap, reads as one fused blob. Span it full-width and left-align
   it like its siblings so it clears the stripe by the same margin as the icon/text above it. */
@media (max-width:900px){
  .issue .rag{grid-column:1/-1;justify-self:start;margin-top:2px}
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE SPACING SYSTEM — the macro note I kept answering with micro fixes.

   CEO: "we need WAY more spacing I already briefed this it's IMPORTANT!!" — and before that,
   twice: "more space" on six rooms, and "Pages too text-dense and same-looking, more clear
   space". Three briefs, and each time I nudged a padding on the room being discussed. That is
   the wrong altitude. The pages are dense because the SYSTEM has no rhythm: a 20px gutter, a
   12px gap between every module regardless of what it separates, and no difference between
   the space inside a thing and the space between things. Everything is 12px from everything,
   so nothing groups and the eye never rests.

   A rhythm needs a ratio, not a value. Four steps, each roughly 1.6× the last, on the 8pt
   grid the craft mandate sets:

     --sp-tight  8px   inside a control — a chip's gutter, an icon's offset
     --sp-item   20px  between siblings that belong together — rows in one list
     --sp-block  40px  between a heading and its content, or two blocks in one section
     --sp-sec    clamp(96px,10vw,168px)  between SECTIONS — the big silence

   The rule that makes it read: the space BETWEEN groups is always at least double the space
   INSIDE them. That is the whole of what "clear space" means, and it is why nudging one
   padding never fixed it.
   ─────────────────────────────────────────────────────────────────────────────────────── */
:root{
  --sp-tight:8px;
  --sp-item:20px;
  --sp-block:40px;
  --sp-sec:clamp(96px,10vw,168px);
  /* the page gutter was 20px against a 1,046px column — the content ran to the very edge of
     the room with no margin to breathe into. */
  --inset:40px;
}
@media (max-width:900px){:root{--inset:22px; --sp-sec:clamp(64px,9vw,96px); --sp-block:28px}}
@media (max-width:520px){:root{--inset:16px; --sp-sec:56px; --sp-block:24px; --sp-item:14px}}

/* SECTION RHYTHM. The silence above a headline is what tells you a new subject started. */
.shead{padding:var(--sp-sec) 4px var(--sp-block)}
section:first-of-type .shead,.sec--lead .shead{padding-top:var(--sp-block)}
.shead--sub{padding-bottom:var(--sp-block)}

/* MODULE RHYTHM. Every stack and grid that was hard-coded to 12px now takes --sp-item, so a
   list of four issues reads as four objects instead of one striped slab. */
:is(.issues,.caps,.opps,.briefs,.tables,.reel,.deck__nav,.stack,.livebriefs){gap:var(--sp-item)}
.accts,.acctgrid{gap:var(--sp-item)}

/* INTERIOR RHYTHM. A module with 12px of air inside it looks cramped no matter how much air
   is around it — the two have to move together or the cards just get further apart and stay
   just as tight. */
:is(.issue,.acct__body,.brief .body,.opp,.lb__t,.trump__acts){padding:var(--sp-block) var(--sp-block) }
.issue{padding:26px var(--sp-block)}
.trump__acts{padding:14px}
.acct__body{padding:26px 26px 28px}

/* THE LAST BLOCK NEEDS FLOOR UNDER IT. The content scroller ended 104px after the final
   module, which on a long page reads as the page being cut off rather than finished. */
.content{padding-bottom:var(--sp-sec)}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   THE MASTHEAD — a room that is about people opens on the people.

   CEO, twice: the Team page had no hero imagery at all. Every other room leads with an
   object you can look at; the HR room led with a list of alerts, which is the one page where
   that is exactly backwards.

   Built as a SLOT, not a picture: aspect-ratio lives on the figure and the image is absolutely
   positioned inside it, so a replacement plate — or the video this eventually wants — drops
   in and not one number on the page moves. */
.masthead{position:relative;margin:0 var(--inset) var(--sp-block);border-radius:var(--r-card);
  overflow:hidden;aspect-ratio:21/9;background:var(--film-black);
  box-shadow:0 30px 70px -34px rgba(0,0,0,.7),inset 0 0 0 1px var(--edge)}
.masthead img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  object-position:50% 34%;display:block}
/* the scrim is a GRADIENT, not a flat wash — the faces stay lit, the caption gets its ground */
.masthead::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(0deg,
    color-mix(in srgb,var(--film-black) 94%,transparent) 0%,
    color-mix(in srgb,var(--film-black) 62%,transparent) 26%,
    transparent 58%)}
.masthead figcaption{position:absolute;left:0;right:0;bottom:0;z-index:1;
  display:grid;gap:10px;padding:var(--sp-block)}
.masthead__k{font:400 10px/1 var(--mono);letter-spacing:.22em;text-transform:uppercase;
  color:#C6CFD9}
.masthead figcaption b{font:700 clamp(24px,3vw,42px)/1.04 IS,system-ui,sans-serif;
  letter-spacing:-.014em;color:#F3F6F9;max-width:22ch}
@media (max-width:720px){
  .masthead{aspect-ratio:4/3;margin-inline:var(--inset)}
  .masthead img{object-position:50% 28%}
}
