/* ══════════════════════════════════════════════════════════════════════════════════════════════
   pn-final — THE LAST LAYER.  Loaded 37th and last, on purpose.

   WHY THIS FILE EXISTS. The CEO asked three times for one button style, and three passes failed.
   Not because the rules were wrong — because of WHERE they were written. play.html loads 36
   stylesheets. style-01.css, where all three passes landed, is number EIGHT. Twenty-eight sheets
   overrule it, including pn-button-unify-20260819.css at #35, whose entire job is buttons and
   which is scoped to `.content .hub-view` — so it never reaches the war room, the pitch, the
   brief or the agency setup, which is precisely where he kept photographing mismatched buttons.

   A rule that cannot win the cascade is not a fix, it is a comment. Anything that must be true
   EVERYWHERE, regardless of view or component, belongs here and nowhere else. Keep it small:
   this file is for universal invariants, not for styling things.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── 1 · ONE BUTTON, EVERYWHERE ────────────────────────────────────────────────────────────────
   "no corner cuts on ANY buttons and all in new style no shadows" · "all buttons look different
   — everywhere — consolidate".

   Stated as a RULE over anything that IS a button, not as a list of button class names — the
   list approach failed twice because this codebase has button classes I have not read. Colour,
   size and weight still carry ROLE; only the geometry is standardised. */
button,
a.btn, a[class*="-btn"], a[class*="btn-"],
[role="button"],
input[type="submit"], input[type="button"],
[class*="btn"]:not(div):not(section):not(header):not(footer):not(aside),
button[class*="cta"], a[class*="cta"], [class*="-go"]{
  clip-path: none !important;          /* the notch was a flourish on the one element whose whole job is to be pressed */
  box-shadow: none !important;
  text-shadow: none !important;
  /* pn-journey moved the primary's outer glow into drop-shadow() specifically BECAUSE clip-path
     clips box-shadow. The notch is gone; the workaround behind it must go too, or "no shadows"
     keeps being written against a property that no longer draws the glow. */
  filter: none !important;
  -webkit-filter: none !important;
}
button::before, button::after,
[class*="btn"]::before, [class*="btn"]::after,
[class*="cta"]::before, [class*="cta"]::after{
  clip-path: none !important; box-shadow: none !important; filter: none !important;
}
/* ONE radius. Genuinely round controls (dots, icons, avatars, pills, chips) keep theirs — a
   deliberately circular control is a different object, not an inconsistent button. */
button:not([class*="dot"]):not([class*="chip"]):not([class*="ico"]):not([class*="pill"]):not([class*="avatar"]):not(.pn-urg),
a.btn, [role="button"]:not([class*="pill"]):not([class*="chip"]),
input[type="submit"], input[type="button"],
[class*="btn"]:not([class*="dot"]):not([class*="chip"]):not([class*="ico"]):not([class*="pill"]),
button[class*="cta"], a[class*="cta"], [role="button"][class*="cta"]{
  border-radius: 10px !important;   /* controls only — a container is not a button (see §13) */
}
/* pressing is a colour change. It is not a lift, and it does not cast. */
/* ⛔ CONTROLS ONLY. `[class*="cta"]:hover` also matched CONTAINERS (.vc-cta-row,
   .perf-hero-cta), and forcing filter:none on them snapped any dimmed panel to full brightness
   the moment the cursor crossed it — the "massive rollover" on PITCH READY. My button rules must
   never reach a container, on hover least of all, because that is where it looks like a bug
   rather than a style. */
button:hover,
a.btn:hover,
[role="button"]:hover,
input[type="submit"]:hover, input[type="button"]:hover,
[class*="btn"]:hover:not(div):not(section):not(header):not(footer):not(aside),
button[class*="cta"]:hover, a[class*="cta"]:hover{
  transform: none !important; box-shadow: none !important; filter: none !important;
}
/* the corner ticks and slashes several buttons drew with pseudo-elements went with the notch */
.ag-new::before, .ag-new::after, .ag-open::before, .ag-open::after,
.cab-btn::before, .cab-btn::after, .tb-btn::before, .tb-btn::after,
.bop-lvl::before, .bop-lvl::after{ content: none !important; }

/* ── 2 · NOTICES ARE SENTENCES ─────────────────────────────────────────────────────────────────
   A wire reads "you walk out before the work starts — <b>£1,136 returned</b>." A blanket
   `> * { display:block }` put the bold on its own line and the full stop on a third. Only real
   block children stack; phrasing stays inline. */
html body .toast.pn-wire .wire-body > b,
html body .toast.pn-wire .wire-body > strong,
html body .toast.pn-wire .wire-body > em,
html body .toast.pn-wire .wire-body > i,
html body .toast.pn-wire .wire-body > u,
html body .toast.pn-wire .wire-body > s,
html body .toast.pn-wire .wire-body > a,
html body .toast.pn-wire .wire-body > small,
html body .toast.pn-wire .wire-body > span{ display: inline !important; }
/* and the NOTICE chip sits in the flow, never absolutely across the copy */
html body .toast.pn-wire .wire-body::before{
  position: static !important; left: auto !important; right: auto !important;
  top: auto !important; bottom: auto !important; height: auto !important; width: auto !important;
}

/* ── 3 · THE UNMUTE AFFORDANCE ─────────────────────────────────────────────────────────────────
   Only ever appears when the browser REFUSED unmuted autoplay. It is the difference between a
   silent film and a silent film you can turn on — never decoration, and it removes itself the
   moment sound is on. */
.pn-unmute{
  position: absolute !important; right: 10px; bottom: 10px; z-index: 6;
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border: 1px solid rgba(255,255,255,.34) !important;
  background: rgba(8,10,16,.82) !important; color: #F6F3FF !important;
  font: 700 11.5px/1 var(--sans, IS, ui-sans-serif, system-ui, sans-serif); letter-spacing: .02em;
  cursor: pointer; backdrop-filter: blur(6px);
}
.pn-unmute:hover{ border-color: rgba(255,255,255,.6) !important; background: rgba(8,10,16,.94) !important; }
.pn-unmute span{ font-size: 13px; opacity: .85; }

/* ── 4 · PITCH & BRIEF ARE A WINDOW ────────────────────────────────────────────────────────────
   CEO 2026-08-20: "put all Pitch and Brief experiences into a cleaner, tidier Finder window as
   overlay", after two rounds of "the Pitch and Brief work pages are ugly and broken STILL".

   WHAT WAS ACTUALLY WRONG. Not one bug — a missing frame. The war room was a full-bleed page
   pretending to be a screen, so nothing established a measure, and every section invented its
   own: the masthead ran to the browser edge, the brief card stopped at ~865px, the response
   panel spanned a different width again, the team section a third, and the response docket
   floated loose in the right margin with a large void beside it. Four widths and a floater on
   one page reads as broken because it IS broken — there was no edge for anything to line up to.

   A window supplies the edge. One frame, one measure, everything inside aligned to it — the
   same object the notices, the store and the report already are, instead of a fourth kind of
   surface. This lives in the LAST sheet because it has to outrank the war room's own layout,
   which is spread across four earlier stylesheets.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
html body .pitch-wrap.pn-fwin{
  --fwin-gut: 34px;                     /* ONE gutter. Every child lines up to this and nothing else. */
  position: relative;
  max-width: 1240px;
  margin: 18px auto 26px !important;
  background: #0C1017;
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 14px;
  overflow: hidden;                      /* the frame CLIPS — the hero can no longer bleed past the edge */
  /* .card carries its own 41px padding. Measured after the first pass: the frame landed at 100px
     but the masthead at 141 and the content at 175 — i.e. the gutter was being ADDED to an
     inherited pad, so the window's edge was not the real edge. Take it, and let --fwin-gut be
     the only inset in play. */
  padding: 0 !important;
  box-shadow: 0 40px 90px -30px rgba(0,0,0,.8), 0 0 0 1px rgba(0,0,0,.5);
}
/* the titlebar is the window's own chrome, so it spans the full frame and never takes the gutter */
html body .pitch-wrap.pn-fwin > .mac-titlebar{
  position: sticky; top: 0; z-index: 30;
  margin: 0; border-radius: 0;
  background: rgba(14,18,26,.94);
  border-bottom: 1px solid rgba(255,255,255,.12);
  backdrop-filter: blur(10px);
}
/* the page behind reads as a backdrop, not as more page */
html body .warroom.pn-fwin::after{ content: none !important; }

/* ── ONE MEASURE ───────────────────────────────────────────────────────────────────────────────
   The rule that actually fixes the "broken" look: every direct child of the content column takes
   the SAME gutter, and none of them carry their own inherited insets (24 / 16 / 20 / 40 / 44). */
/* MEASURED on the live page before this fix (1440 viewport), which is what made the diagnosis
   certain rather than plausible. Left edges inside ONE column: masthead 41px, dossier 81px,
   response 65px. Widths: 1358 / 705 / 910. Nothing lined up with anything, and the docket sat
   296px wide in the margin with a 50px dead gap beside it. That is the whole "ugly and broken".

   So the padding is taken with !important (an earlier sheet sets 41px here and my first pass
   lost to it), and children are stripped of the private max-widths that produced 705 and 910. */
html body .pn-fwin .pitch-inner{ padding: 0 0 30px !important; }
html body .pn-fwin .pitch-inner > *{
  margin-left: var(--fwin-gut) !important;
  margin-right: var(--fwin-gut) !important;
  max-width: none !important;
}
/* the masthead is the one deliberate full-bleed — it is the window's cover image */
html body .pn-fwin .pitch-inner > .wr-masthead,
html body .pn-fwin .pitch-inner > .pitch-bgstrip{
  margin-left: 0 !important; margin-right: 0 !important;
}
/* the split becomes a real two-column inside the frame — the docket is a COLUMN, not a floater */
html body .pn-fwin .wr-split{
  display: grid !important;
  grid-template-columns: minmax(0,1fr) 320px !important;
  column-gap: 28px !important;
  align-items: start !important;
  padding-right: 0 !important;
  margin-left: var(--fwin-gut) !important; margin-right: var(--fwin-gut) !important;
}
html body .pn-fwin .wr-split > .wr-main{ min-width: 0; }
/* Only the OUTER box is normalised. An earlier version of this rule also forced
   padding-left/right to 0, which would have stripped every card of the inset that holds its own
   content off its own border — the children here are .wr-doss, .wr-resp, .wr-work, .poap and
   .room-mod, all of which are cards, not bare blocks. Alignment is a margin/width problem;
   padding is internal and is none of this rule's business. */
html body .pn-fwin .wr-main > *{
  margin-left: 0 !important; margin-right: 0 !important;
  max-width: none !important; width: auto !important;
}
html body .pn-fwin .wr-rail{
  margin: 0 !important; position: sticky; top: 66px;   /* clears the sticky titlebar */
  display: flex; flex-direction: column; gap: 16px;
}
html body .pn-fwin .wr-rail > *{ margin: 0 !important; }
/* below the split point the docket sits UNDER the work at the same measure, never squeezed */
@media (max-width: 1100px){
  html body .pn-fwin .wr-split{ grid-template-columns: minmax(0,1fr) !important; row-gap: 22px; }
  html body .pn-fwin .wr-rail{ position: static; }
}
@media (max-width: 760px){
  html body .pitch-wrap.pn-fwin{ --fwin-gut: 16px; margin: 0 !important;
    border-radius: 0; border-left: 0; border-right: 0; max-width: none; }
}

/* ── 5 · A PICKED TEAMMATE LOOKS PICKED ────────────────────────────────────────────────────────
   CEO 2026-08-20: "when I'm picking a team they need to be highlighted — they are not."

   The state was being SET correctly (pn-pitch2.js toggles .on), it just could not be seen: the
   selected style was a 1px border-colour swap plus a 12% tint, on a dark row, against a base that
   already has a 1px hairline border. That is a change of about two shades — technically a
   highlight, practically invisible. Selection is the single most important feedback on this
   screen, so it now reads at a glance: accent spine, real tint, accent hairline, and the score
   picked out. */
.pnp2-sq{ position: relative; transition: background .18s ease, border-color .18s ease; }
.pnp2-sq.on{
  border-color: var(--accent,#f97316) !important;
  background: color-mix(in srgb, var(--accent,#f97316) 22%, rgba(9,14,24,.75)) !important;
}
.pnp2-sq.on::before{                       /* the spine — visible from across the room */
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
  background: var(--accent,#f97316);
}
.pnp2-sq.on .nm b{ color: #fff !important; }
.pnp2-sq.on .ovr{ color: var(--accent,#f97316) !important; font-weight: 800; }
.pnp2-sq.on .m{ box-shadow: 0 0 0 2px var(--accent,#f97316) !important; }
.pnp2-sq:hover:not(.on){ border-color: rgba(255,255,255,.34) !important; }

/* ── 6 · THE TOP BAR IS A BAR, NOT A NOTICEBOARD ───────────────────────────────────────────────
   CEO 2026-08-20: "this nav bar is now ugly and cluttered". That one is mine, from this morning:
   I put AGENCY VALUE and CASH IN BANK on the bar as two-word stacked labels, and at the bar's
   real height they wrapped to three lines each and turned the chrome into a wall of text.
   The figures stay — they are the point — but the labels shrink to one word and never wrap. */
.pn-snap-rail{ gap: 18px !important; }
.pn-snap-fig i{
  white-space: nowrap !important;
  font-size: 7.5px !important; letter-spacing: .14em !important;
  opacity: .62;
}
.pn-snap-fig b{ font-size: 14px !important; white-space: nowrap !important; }
/* the urgency block was also carrying two stacked words next to a ring; give it room and stop it
   competing with the figures for the same eye */
.pn-urg-lbl i{ font-size: 7.5px !important; letter-spacing: .14em !important; white-space: nowrap; }
.pn-urg-lbl em{ white-space: nowrap; font-size: 11.5px !important; }
.pn-urg{ padding: 6px 12px 6px 7px !important; gap: 8px !important; }

/* ── 7 · A LIGHT ROOM BEHIND A DARK DEVICE ─────────────────────────────────────────────────────
   CEO 2026-08-20: "on the main logged in page I want a light background to show the dark iPad —
   so light background over the background video."

   The iPad was a dark object floating on a dark plate, so its edge did the work of separating two
   things that were nearly the same value, and the device never read as a device. A light wash
   over the plate gives the dark shell something to sit against. The video stays — it is the room,
   and it still moves behind the wash — it just stops competing with the thing in front of it. */
html body[data-view="office"] #penthouse-bg{ position: relative; }
html body[data-view="office"] #penthouse-bg::after{
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  /* warm off-white, brightest behind the device and falling away at the edges, so it reads as
     light in a room rather than a flat panel laid over the footage */
  background:
    radial-gradient(120% 90% at 50% 38%, rgba(247,245,241,.93) 0%, rgba(240,238,233,.88) 42%, rgba(226,224,219,.80) 72%, rgba(214,212,207,.76) 100%);
}
/* the plate keeps moving under the wash, just quieter and cooler so the warm light sits on top */
html body[data-view="office"] #penthouse-bg #bgplate{
  display: block !important;
  opacity: .5 !important;
  filter: saturate(.55) contrast(1.02) brightness(1.12) !important;
}
/* the grit overlays were tuned for a dark room; at this value they read as dirt on a white wall */
html body[data-view="office"] #penthouse-bg .wash{ opacity: .22 !important; mix-blend-mode: multiply; }
/* and the device now casts, because it is a dark object on a light ground */
html body[data-view="office"] #pn-shell{
  box-shadow: 0 50px 90px -30px rgba(28,26,22,.55), 0 18px 40px -18px rgba(28,26,22,.4) !important;
}

/* ── 8 · THE WIRE SITS ABOVE ITS OWN BACKDROP ──────────────────────────────────────────────────
   CEO 2026-08-20, reported twice: "clicking on the email icon top nav causes this weird panel
   expansion and total page blur" · "email icon at top nav still gives me a blurred screen".

   The panel was never missing. It opens, renders and fills with content — and then gets blurred,
   because .feed-rail is z-index 30 and the .fw-backdrop added to dim the page behind it is
   z-index 55. The scrim was sitting ON TOP of the thing it exists to reveal. Its
   pointer-events:auto also meant the first click anywhere — including on the wire itself —
   closed it, so it read as a panel that flashed and died.

   A backdrop must always rank between the page and the panel. Never above both. */
.screen > .fw-backdrop{ z-index: 40 !important; }
body.feed-open #app > .feed-rail,
body.feed-open .feed-rail{ z-index: 60 !important; }

/* ── 9 · THE RESPONSE SCREENS — TOKENS THAT DO NOT DEPEND ON A FLAG ────────────────────────────
   CEO priority, 2026-08-20: "your priority is the Pitch and Brief response screens, ensure these
   are done."

   TWO faults, and the second explains the screenshots better than any styling argument.

   (1) SCOPE. The whole response design system — every colour token on .wr-resp — is declared
       under `body[data-view="pitch"]` in pn-squad-dossier. render() only sets that view when
       `S.activePitch && !window.__pnAway`. Reach the war room by a route that leaves __pnAway
       set and NONE of those tokens exist, so the panel falls back to raw defaults and renders
       genuinely broken rather than merely ugly. Same root cause as the window frame. Tokens are
       redeclared here against the components themselves, so they are always defined.

   (2) THE PALE LETTERHEAD. In dark mode --rail-bg was a near-white gradient and --bs-head-bg was
       #d3dbe7, by an "alternation" intent: dark page, pale letterhead. That reads as a cream
       card pasted onto a dark page — which is exactly what kept being photographed as "old
       design" — and it no longer holds now the pitch sits inside a dark window. The docket and
       the response rail join the window they live in. Light theme keeps the alternation, where
       it was always correct.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
/* The pale rail is a SYSTEMATIC choice, not a bug: ~10 declarations across the codebase pair a
   dark theme with a pale rail and vice versa ("alternation"). It is right on clients, accounts and
   the command bar. It is wrong here, now the pitch lives inside a dark window — it produced the
   cream "02 · YOUR RESPONSE" bar and the cream "BRIEF DOCUMENT" band that kept being photographed
   as old design. So the override is scoped to the window and inherits to every descendant that
   reads these tokens (.wr-resp, .wr-doss-band, the docket), and nothing outside it changes. */
html body .pn-fwin,
html body .pn-fwin .wr-resp{
  --rsp-face: linear-gradient(178deg, rgba(12,18,28,.6), rgba(8,12,20,.72));
  --rsp-edge: rgba(242,246,252,.34); --rsp-hair: rgba(242,246,252,.14);
  --rsp-well: rgba(4,7,12,.5);  --rsp-ink: #f2f6fc; --rsp-dim: rgba(242,246,252,.66);
  --rail-bg: linear-gradient(180deg, #18202c, #121924);
  --rail-solid: #18202c;
  --rail-ink: #eef3fb; --rail-dim: rgba(238,243,251,.7); --rail-ink-dim: rgba(238,243,251,.62);
  --rail-hair: rgba(238,243,251,.16); --rail-edge: rgba(238,243,251,.14); --rail-on: #f97316;
}
html body .pn-fwin .wr-bs, html body .wr-bs{
  --bs-paper:#12161f; --bs-ink:#eef2f8; --bs-dim:rgba(238,242,248,.8); --bs-hair:rgba(238,242,248,.17);
  --bs-acc:#ff8a4f; --bs-pos:#5fd39b; --bs-neg:#ff8f7a; --bs-track:rgba(238,242,248,.16);
  /* was #d3dbe7 — the cream docket head that dominated the whole panel */
  --bs-head-bg:#1a2230; --bs-head-img:linear-gradient(180deg,#1f2836,#161d29);
  --bs-head-ink:#eef3fb; --bs-head-dim:rgba(238,243,251,.78); --bs-head-hair:rgba(238,243,251,.18);
}
/* LIGHT THEME keeps the alternation — a dark docket on a light page was always right */
html body.mvc-light .pn-fwin, html body.mvc-light .pn-fwin .wr-resp{
  --rsp-face: linear-gradient(178deg,#efe7d9,#e6dccb);
  --rsp-edge: rgba(28,22,17,.5); --rsp-hair: rgba(28,22,17,.16);
  --rsp-well:#fffdf8; --rsp-ink:#1c1611; --rsp-dim:rgba(28,22,17,.68);
  --rail-bg: linear-gradient(180deg,#132743,#0b1c30); --rail-ink:#e9f0fb;
  --rail-dim: rgba(233,240,251,.74); --rail-hair: rgba(233,240,251,.2); --rail-on:#f97316;
}
html body.mvc-light .pn-fwin .wr-bs, html body.mvc-light .wr-bs{
  --bs-paper:#f6f3ec; --bs-ink:#141b26; --bs-dim:rgba(20,27,38,.78); --bs-hair:rgba(20,27,38,.17);
  --bs-acc:#9d4300; --bs-pos:#146b3f; --bs-neg:#a8321d; --bs-track:rgba(20,27,38,.14);
  --bs-head-bg:#0a1a2c; --bs-head-img:linear-gradient(180deg,#0f2138,#0a1a2c);
  --bs-head-ink:#eaf1fb; --bs-head-dim:rgba(234,241,251,.8); --bs-head-hair:rgba(234,241,251,.22);
}
/* the docket is part of the window, so it takes the window's corner and hairline, not its own
   drop-shadowed floating-card treatment */
html body .pn-fwin .wr-bs{
  border-radius: 10px !important;
  border: 1px solid rgba(255,255,255,.13) !important;
  box-shadow: none !important;
}

/* ── 10 · THE NEW-AGENCY SCREENS JOIN THE REST OF THE GAME ─────────────────────────────────────
   CEO 2026-08-20: "I also caught the shitty new agency set up experience screens" · earlier,
   "these designs are disjointed and terrible and need to be in the finder design style window".

   The structure was already right — onbShell() has been rendering a real Finder window with a
   traffic-light titlebar since July. What was wrong was the MATERIAL: .onb-card is porcelain
   glass, a cream gradient with a raking white sheen and a multiply halftone, from a period when
   the setup flow was its own light world. Every other window in the game is now dark, so the
   first thing a new player saw was the one screen that matched nothing after it.

   Same window, same chrome, same copy — the game's material instead of its own. */
html body .onb-card{
  background: #0C1017 !important;
  border: 1px solid rgba(255,255,255,.14) !important;
  border-radius: 14px !important;
  box-shadow: 0 40px 90px -30px rgba(0,0,0,.8), 0 0 0 1px rgba(0,0,0,.5) !important;
  -webkit-backdrop-filter: none !important; backdrop-filter: none !important;
}
/* the glass sheen and the halftone tooth were porcelain-only tells */
html body .onb-card::before, html body .onb-card::after{ content: none !important; }
html body .onb-card .mac-titlebar{
  background: rgba(14,18,26,.94) !important;
  border-bottom: 1px solid rgba(255,255,255,.12) !important;
}
html body .onb-card .mac-tb-title{ color: rgba(246,243,255,.72) !important; }
/* ink: the card was built for dark type on cream, so every default flips */
html body .onb-card,
html body .onb-card .onb-inner,
html body .onb-card h1, html body .onb-card h2, html body .onb-card p,
html body .onb-card label, html body .onb-card li{ color: #EDF1FA; }
html body .onb-card .onb-headline{ color: #F6F3FF !important; }
html body .onb-card .onb-kicker{ color: var(--accent,#f97316) !important; }
html body .onb-card .muted, html body .onb-card .small{ color: rgba(237,241,250,.66) !important; }
/* fields were white-on-cream */
html body .onb-card input, html body .onb-card select, html body .onb-card textarea{
  background: rgba(4,7,12,.5) !important;
  border: 1px solid rgba(255,255,255,.16) !important;
  color: #F2F6FF !important; border-radius: 10px !important;
}
html body .onb-card input::placeholder, html body .onb-card textarea::placeholder{ color: rgba(242,246,255,.4) !important; }
/* the city grid — the real contract is `.city-btn` + `.selected` (script-01.js:117 says so
   explicitly), not the onb-* names a first pass guessed at. Checked rather than assumed. */
html body .onb-card .city-btn, html body .city-btn{
  background: rgba(255,255,255,.04) !important;
  border: 1px solid rgba(255,255,255,.14) !important;
  color: #EDF1FA !important; border-radius: 10px !important;
  box-shadow: none !important;
}
html body .onb-card .city-btn .ct-code, html body .city-btn .ct-code{ color: #F6F3FF !important; }
html body .onb-card .city-btn .ct-meta, html body .city-btn .ct-meta{ color: rgba(237,241,250,.6) !important; }
html body .onb-card .city-btn.selected, html body .city-btn.selected{
  border-color:var(--accent,var(--accent,#FF2E88)) !important;
  background:color-mix(in srgb, var(--accent,var(--accent,#FF2E88)) 22%, rgba(9,14,24,.72)) !important;
}
html body .city-btn.selected .ct-code{ color: #fff !important; }
html body .onb-card .city-btn:hover:not(.selected){ border-color: rgba(255,255,255,.32) !important; }
/* the CTA: one flat accent slab, no ink-stamp bevel, no lift, matching every other primary */
html body .onb-card button.primary{
  background:var(--accent,var(--accent,#FF2E88)) !important;
  color: #16100A !important;
  border: 0 !important; border-radius: 10px !important;
  box-shadow: none !important; filter: none !important; transform: none !important;
}
html body .onb-card button.primary:hover{ filter: brightness(1.06) !important; transform: none !important; }
html body .onb-card button.primary[disabled]{ opacity: .45 !important; }
/* the action bar under it carried a light-world fade */
html body .onb-card .onb-actionbar{ background: transparent !important; }
html body .onb-card .onb-dot{ background: rgba(255,255,255,.22) !important; }
html body .onb-card .onb-dot.active{ background: var(--accent,#f97316) !important; }

/* ── 9b · THE DOCKET HEAD, SETTLED ON THE PAINTED PROPERTY ─────────────────────────────────────
   Overriding --bs-head-bg alone did not hold: measured in the live page, .wr-bs-head still
   computed rgb(211,219,231) with my token declared and parsed correctly. Rather than keep
   arguing specificity with a token that something upstream keeps re-declaring, set the property
   that actually paints. The token stays correct above for anything else reading it. */
html body .pn-fwin .wr-bs-head,
html body .wr-bs .wr-bs-head{
  background-color: #1a2230 !important;
  background-image: linear-gradient(180deg,#1f2836,#161d29) !important;
  color: #eef3fb !important;
  border-bottom: 1px solid rgba(238,243,251,.16) !important;
}
html body.mvc-light .pn-fwin .wr-bs-head,
html body.mvc-light .wr-bs .wr-bs-head{
  background-color: #0a1a2c !important;
  background-image: linear-gradient(180deg,#0f2138,#0a1a2c) !important;
  color: #eaf1fb !important;
}
/* the head's own type was inked for a pale ground */
html body .pn-fwin .wr-bs-head *{ color: inherit !important; }
html body .pn-fwin .wr-bs-head .wr-bs-k{ color: rgba(238,243,251,.66) !important; }

/* ── 11 · SETUP-FLOW FIXES (CEO feedback round 2, 2026-08-20) ──────────────────────────────────

   F1 · THE INVISIBLE QUESTIONS — MY REGRESSION, from flipping .onb-card to dark an hour ago.
        .onb-slider-name and .onb-slider-labels were inked near-black for the cream porcelain
        card. On the new dark ground they went dark-on-dark and the questions disappeared, so
        the player was dragging four unlabelled sliders. Section 10 flipped headings, body, muted
        and fields — and missed the one set of labels that mattered most on that screen. */
html body .onb-card .onb-slider-name{ color: #F6F3FF !important; opacity: 1 !important; }
html body .onb-card .onb-slider-labels{ color: rgba(237,241,250,.66) !important; opacity: 1 !important; }
html body .onb-card .onb-slider-labels *{ color: inherit !important; }
html body .onb-card .onb-slider-row{ color: #EDF1FA !important; }
html body .onb-card .onb-body{ color: rgba(237,241,250,.78) !important; }
html body .onb-card .onb-addl{ color: #EDF1FA !important; }
html body .onb-card .small.muted{ color: rgba(237,241,250,.6) !important; }

/* F3 · "Before you walk in." on ONE line — it was breaking to two and eating vertical space on a
        screen that already scrolls. The headline also comes down a step so it stops dominating. */
html body .onb-card .onb-headline{
  white-space: nowrap !important;
  font-size: clamp(26px, 3.2vw, 40px) !important;
  line-height: 1.06 !important;
  margin-bottom: 10px !important;
}
html body .onb-card .onb-headline br{ display: none !important; }

/* F2 · the titlebar was oversized for what it carries, and carried no mark. Trimmed to a real
        window bar, with the PN monogram set in it. */
html body .onb-card .mac-titlebar{
  padding: 7px 14px !important;
  min-height: 0 !important;
  display: flex !important; align-items: center !important; gap: 10px !important;
}
html body .onb-card .mac-tb-title{
  font-size: 11.5px !important; font-weight: 700 !important;
  letter-spacing: .02em !important;
}
html body .onb-card .mac-titlebar .mac-tb-dots{ gap: 6px !important; }
html body .onb-card .mac-titlebar .mac-tb-dot{ width: 10px !important; height: 10px !important; }
/* the mark, drawn in the bar itself so no markup change is needed */
html body .onb-card .mac-titlebar::before{
  content: "PN";
  font: 900 10.5px/1 var(--mono, ui-monospace, monospace);
  letter-spacing: .1em;
  color: var(--accent,#f97316);
  padding: 3px 5px;
  border: 1px solid color-mix(in srgb, var(--accent,#f97316) 55%, transparent);
  border-radius: 4px;
  margin-left: 6px;
  flex: none;
}

/* F4 · DOUBLE FINDER WINDOW. The interview brings its OWN window (.vc-room.pn-window, with its
        own traffic lights and title) and is rendered inside onbShell, which is also a window.
        Two sets of chrome, one inside the other. The inner window is the one that names the
        scene, so the outer stands down to a plain container wherever it wraps a real window. */
html body .onb-card:has(.pn-window),
html body .onb-card:has(.vc-room){
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  width: auto !important; margin: 0 auto !important;
}
html body .onb-card:has(.pn-window) > .mac-titlebar,
html body .onb-card:has(.vc-room) > .mac-titlebar{ display: none !important; }
html body .onb-card:has(.pn-window) .onb-inner,
html body .onb-card:has(.vc-room) .onb-inner{ padding: 0 !important; }

/* F5 · "not all answers are visible when answering". Checked before writing this: .vc-room-body
        ALREADY scrolls (style-01.css:8669, overflow-y:auto), so nothing is unreachable — the
        real fault is that the hero question is set so large it pushes the third answer past the
        fold with NO indication anything is below it. A scrollable region that looks complete is
        worse than one that looks cut off.

        So: bring the question down to a size that leaves the answers in view, and give the
        scrolling column a bottom fade so a clipped option always reads as "there is more". */
html body .vc-room .vc-q--hero, html body .vc-room .vc-q{
  font-size: clamp(19px, 1.55vw, 26px) !important;
  line-height: 1.16 !important;
  margin-bottom: 14px !important;
}
html body .vc-room .vc-intro{ font-size: 12.5px !important; margin-bottom: 8px !important; }
html body .vc-room .vc-room-body{
  overflow-y: auto !important; min-height: 0 !important;
  /* the fade is a mask so it works over any background without painting a panel */
  -webkit-mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 26px), transparent 100%);
          mask-image: linear-gradient(180deg, #000 0, #000 calc(100% - 26px), transparent 100%);
  scrollbar-width: thin;
}
html body .vc-room .vc-answers{ padding-bottom: 12px !important; }
html body .vc-room .vc-ans{ white-space: normal !important; }

/* ── 12 · ONE COMMIT BUTTON ON THE PITCH ───────────────────────────────────────────────────────
   CEO 2026-08-20: "bad layout, multiple buttons, all sitting full frame."

   The pitch really does render TWO identical primary CTAs, both reading "Build the pitch":
     · #get-to-work  — in the docket rail, carrying the Time cost, sticky, always in view
     · #wr-deliver   — a full-width block inside the response panel
   Two commit buttons for one action is not a styling problem: the player has to work out whether
   they do the same thing. The docket is the sign-off rail and states the price, so it keeps the
   action. The response panel keeps its explanatory note, which is the part that was doing work.

   Hidden rather than deleted: both ids carry their own handlers and the flow is being demoed in
   hours. Removing markup is the tidy-up, not the fix. */
html body .pn-fwin #wr-deliver{ display: none !important; }
html body .pn-fwin .wr-deliver-note{
  margin-top: 0 !important;
  font-size: 12.5px !important;
  color: rgba(237,241,250,.62) !important;
}
/* the remaining CTA is the one that matters, so it reads as the commit and not as one more slab */
html body .pn-fwin #get-to-work{
  background: var(--accent,#FF2E88) !important;
  color: #14060D !important;
  border: 0 !important;
  font-weight: 800 !important;
}
/* stop every panel being a full-bleed slab — the work column gets a reading measure */
html body .pn-fwin .wr-resp, html body .pn-fwin .wr-doss{ border-radius: 12px !important; }
html body .pn-fwin .wr-doss-lead, html body .pn-fwin .wr-deliver-note,
html body .pn-fwin .wr-resp p{ max-width: 68ch !important; }

/* ── 13 · A PRIMARY BUTTON IS ONE COLOUR, EVERYWHERE ───────────────────────────────────────────
   CEO: "button colours should either all be pink (preferred) or orange — not both."

   The orange sweep repointed every rule whose fill NAMED an orange. It could not catch the mint
   ones, because they were never orange: "Back to the floor" on the verdict and "I know my people"
   on the team screen are teal, "Pitch it" is orange, "Go to the rooms" is pink. Four colours for
   one job across four screens of a single flow.

   Stated on ROLE, not on colour: the primary action takes the accent, whatever the accent is.
   Status colour is untouched — WINNING, SUPER-IMPRESSED, room temperature and the ledger's
   green/red report a state, and a chip that reports a state is not a button. */
html body button.primary,
html body .pn-btn--primary,
html body .lg-btn--primary,
html body .pnv4-go,
/* ⛔ MUST be an actual control. An earlier version of this selector was
   `[class*="cta"]`, which matches CONTAINERS too — .vc-cta-row, .perf-hero-cta — so it painted
   whole panels accent-orange and broke PITCH READY into a solid block. A colour rule for buttons
   must require the element to BE a button. */
html body button[class*="cta"]:not([class*="secondary"]):not([class*="ghost"]),
html body a[class*="cta"]:not([class*="secondary"]):not([class*="ghost"]),
html body [role="button"][class*="cta"]:not([class*="secondary"]):not([class*="ghost"]),
html body button.hub-advance,
html body button.sea-promo-cta{
  background: var(--accent,#FF2E88) !important;
  background-image: none !important;
  color: #14060D !important;
  border-color: transparent !important;
}
/* ⛔ CEO 2026-09-19 ("why do we still have dark text on dark buttons"): the two blocks above pin
   near-black ink (#14060D) on every primary — correct for the DARK theme's bright orange
   (#f97316, 7.9:1) and WRONG for the LIGHT theme, where the fill is the deep burnt orange
   (#b4380d) and the same ink measured as dark-on-dark. STYLE_SOURCE_OF_TRUTH §5f corollary:
   light-theme burnt orange takes WHITE ink (4.66:1). Stated once here, for every primary. */
html body.mvc-light button.primary,
html body.mvc-light .pn-btn--primary,
html body.mvc-light .lg-btn--primary,
html body.mvc-light .pnv4-go,
html body.mvc-light button[class*="cta"]:not([class*="secondary"]):not([class*="ghost"]),
html body.mvc-light a[class*="cta"]:not([class*="secondary"]):not([class*="ghost"]),
html body.mvc-light [role="button"][class*="cta"]:not([class*="secondary"]):not([class*="ghost"]),
html body.mvc-light button.hub-advance,
html body.mvc-light button.sea-promo-cta,
html body.mvc-light .pn-fwin #get-to-work{
  color: #fff !important;
}
html body button.primary:hover,
html body .pn-btn--primary:hover,
html body .lg-btn--primary:hover{ filter: brightness(1.07) !important; }
html body .pn-btn--secondary, html body .lg-btn--secondary, html body .pn-btn--ghost{
  background: transparent !important; color: #EDF1FA !important;
  border: 1px solid rgba(255,255,255,.22) !important;
}

/* ── 14 · THE REVIEW (CLIENT WORK) — THE THIRD SCREEN WITH THE PALE CONSOLE ────────────────────
   CEO 2026-08-20: "same bad design experience confirmed on Brief work — it's all bad full screen
   experiences", PRIORITY.

   Identical root cause to the pitch, in a third place. pn-review declares --rvc-bg as a
   near-white gradient under the dark theme, by the same "alternation" intent, so the sign-off
   console renders as a full-width WHITE slab across the bottom of an otherwise dark screen —
   with the REJECTED chip, the REWORK/AMENDS/APPROVED track and "Skip to sign-off" all sitting on
   white. That is the bar in the screenshot.

   The console is the most important object on the screen: it carries the verdict. It should read
   as an instrument in the same room as the work, not as a printout stapled underneath it. */
html body .pn-review{
  --rvc-bg: linear-gradient(180deg,#18202c,#121924);
  --rvc-ink: #eef3fb;
  --rvc-dim: rgba(238,243,251,.7);
  --rvc-hair: rgba(238,243,251,.16);
  --rvc-on: var(--accent,#FF2E88);
  --rvc-on-ink: #14060D;
}
/* light theme keeps the alternation, where a dark console on a light page is right */
html body.mvc-light .pn-review{
  --rvc-bg: linear-gradient(180deg,#14263f,#0b1c30);
  --rvc-ink: #eaf0fa; --rvc-dim: rgba(234,240,250,.68);
}
/* the review is a WINDOW, like the pitch — one edge, one measure, not a full-bleed page */
html body .pn-review{
  max-width: 1240px !important;
  margin: 18px auto 26px !important;
  border: 1px solid rgba(255,255,255,.14) !important;
  border-radius: 14px !important;
  overflow: hidden !important;
  box-shadow: 0 40px 90px -30px rgba(0,0,0,.8) !important;
}
/* the accent inside the review was orange while the rest of the game moved to the accent */
html body .pn-review{ --rv-accent: var(--accent,#FF2E88); --rv-accent-ink: #14060D; }
@media (max-width: 760px){
  html body .pn-review{ max-width: none !important; margin: 0 !important;
    border-radius: 0 !important; border-left: 0 !important; border-right: 0 !important; }
}

/* ── 15 · THE FLOOR, AFTER THE FAKE PANEL CAME OUT ─────────────────────────────────────────────
   CEO 2026-08-20: "the lower half of The Floor is a mess… not useful or real, remove it. Fix
   what is."

   LIVE CAMS is gone from the dashboard (see script-01.js). What remains is the part that was
   always real — live opportunities, active clients, and the HR queue — so this closes the gap it
   left and gives those three equal standing instead of leaving them as the leftovers under a
   hero that no longer exists. */
html body .hub-view[data-view="v-perf"] .perf-grid{
  display: grid !important;
  grid-template-columns: minmax(0,1.15fr) minmax(0,1fr) !important;
  gap: 16px !important;
  align-items: start !important;
}
@media (max-width: 1000px){
  html body .hub-view[data-view="v-perf"] .perf-grid{ grid-template-columns: minmax(0,1fr) !important; }
}
/* the panels that survived carry real state, so they get a real head rather than an eyebrow
   floating over a slab */
html body .hub-view[data-view="v-perf"] .perf-grid .card h2,
html body .hub-view[data-view="v-perf"] .pv-mod h2{
  font-size: 19px !important; letter-spacing: -.01em !important; margin: 2px 0 0 !important;
}
/* an empty panel should say so plainly, not sit blank — the Floor's whole job is "what needs you" */
html body .hub-view[data-view="v-perf"] .muted.small{ color: rgba(237,241,250,.55) !important; }

/* ── 16 · MEET THE TEAM — a window, not a page with a light bar over it ────────────────────────
   CEO 2026-08-20: "format this screen as a proper finder without the shitty top nav and better
   content design."

   THE LIGHT BAR was the NEXT MOVE strip (#pn-nextmove / #pn-desk) — a sign-posting rail that is
   correct on the hub and wrong here. This screen has exactly one thing to do, and its button
   says so; a second bar telling you to end the week, over a screen about meeting your team, is
   two instructions competing on a screen that needs one.

   The stage now carries real window chrome (titlebar added in script-01.js, red dot wired to the
   continue button) and the content gets a reading measure instead of running centred across the
   full width. */
html body[data-view="meetteam"] #pn-nextmove,
html body[data-view="meetteam"] #pn-desk,
html body[data-view="meetteam"] .topbar,
html body[data-view="meetteam"] .pnos-dock,
html body[data-view="meetteam"] .dock{ display: none !important; }

html body .meetteam-stage{
  max-width: 900px !important;
  margin: 4vh auto !important;
  padding: 0 0 30px !important;
  background: #0C1017 !important;
  border: 1px solid rgba(255,255,255,.14) !important;
  border-radius: 14px !important;
  overflow: hidden !important;
  box-shadow: 0 40px 90px -30px rgba(0,0,0,.8) !important;
  text-align: left !important;
}
html body .meetteam-stage > .mac-titlebar{
  background: rgba(14,18,26,.94) !important;
  border-bottom: 1px solid rgba(255,255,255,.12) !important;
  padding: 7px 14px !important; margin: 0 !important;
}
/* the copy was centred across the full width, which is why it read as a poster rather than a
   screen you act on */
html body .meetteam-stage > .tac-eyebrow{ display: block; margin: 22px 34px 0 !important; }
html body .meetteam-stage .mt-title{ margin: 6px 34px 0 !important; text-align: left !important; }
html body .meetteam-stage .mt-sub{
  margin: 10px 34px 0 !important; text-align: left !important; max-width: 62ch !important;
  color: rgba(237,241,250,.7) !important;
}
html body .meetteam-stage > *:not(.mac-titlebar){ margin-left: 34px !important; margin-right: 34px !important; }
html body .meetteam-stage .mt-go{ margin: 22px 34px 0 !important; width: auto !important; }

/* ── 17 · THE BOARDROOM CAN BE SEEN ───────────────────────────────────────────────────────────
   CEO 2026-08-20: the deck-playing screen was near-black — the laptop, the deck and the room all
   sat within a few values of each other, so there was nothing to look at on the screen whose
   whole job is watching your work play.

   The radial ground is lifted and the deck itself brought forward, so the thing being presented
   is the brightest object in the room. */
html body .pitch-wrap.boardroom-mode.deliver-mode{
  background: radial-gradient(130% 100% at 78% -12%, #24344f 0%, #16223a 44%, #0e1524 100%) !important;
}
html body .boardroom-mode.deliver-mode .deckwrap,
html body .boardroom-mode.deliver-mode .pn-deck,
html body .boardroom-mode.deliver-mode .laptop,
html body .boardroom-mode.deliver-mode .deck-stage{
  filter: brightness(1.35) contrast(1.06) !important;
}
html body .boardroom-mode.deliver-mode .pitch-bgstrip,
html body .boardroom-mode.deliver-mode .pitch-bgstrip-bleed{ opacity: .12 !important; }

/* ── 18 · THE PRESENT DECK STOPS BEING CLIPPED ─────────────────────────────────────────────────
   CEO 2026-08-20: on PRESENT, the deck panel's content was cut off at its left edge — "BIG IDEA"
   started mid-letter. The deck is rendered at a fixed composition and then dropped into a column
   narrower than it, with the overflow simply hidden, so the slide lost its left margin rather
   than scaling to fit. Contain it and let it scale. */
html body .vc-room-inner > *:last-child,
html body .pn-deck-col, html body .deck-col{ min-width: 0 !important; }
html body .pn-deck, html body .deck-stage, html body .deckwrap{
  max-width: 100% !important;
  margin-left: 0 !important; margin-right: 0 !important;
}
html body .pn-deck img, html body .deck-stage img,
html body .pn-deck video, html body .deck-stage video{
  max-width: 100% !important; height: auto !important; object-fit: contain !important;
}

/* ── 19 · THE TEAM PAGE — MINE, THEN THEIRS ────────────────────────────────────────────────────
   CEO 2026-08-20, verbatim brief: see WHO I HAVE first and manage them; then clearly below and
   separate, Available and Poaching Opportunities in GREYSCALE; then The 100 as headlines with
   examples, locked until earned. "That's it — simple."

   The colour split is the load-bearing idea, not decoration: full colour means yours, greyscale
   means not yours yet. It makes the page readable at a glance and makes it impossible to mistake
   a target for a signing — which is the confusion behind "I can form a team but then I can't see
   where they are".
   ══════════════════════════════════════════════════════════════════════════════════════════ */
html body .tm-band{ margin: 0 0 20px; }
html body .tm-head{ margin: 0 0 12px; }
html body .tm-h{
  margin: 2px 0 0; font-size: clamp(22px, 2.4vw, 30px); font-weight: 900;
  letter-spacing: -.02em; line-height: 1.02; display: flex; align-items: baseline; gap: 10px;
}
html body .tm-n{
  font: 800 11px/1 var(--mono, ui-monospace, monospace); letter-spacing: .1em;
  padding: 4px 7px; border-radius: 5px;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14);
  color: rgba(246,243,255,.72);
}
html body .tm-sub{
  margin: 8px 0 0; max-width: 64ch;
  font-size: 13.5px; line-height: 1.5; color: rgba(237,241,250,.66);
}

/* THE DIVIDER — the page's one structural statement: everything under it is not yours */
html body .tm-rule{
  display: flex; align-items: center; gap: 14px;
  margin: 30px 0 22px; color: rgba(237,241,250,.42);
  font: 800 9.5px/1 var(--mono, ui-monospace, monospace); letter-spacing: .24em;
}
html body .tm-rule::before, html body .tm-rule::after{
  content: ""; flex: 1; height: 1px; background: rgba(255,255,255,.14);
}

/* ── FULL COLOUR: yours ──────────────────────────────────────────────────────────────────── */
html body .tm-band--mine{ filter: none; }

/* ── GREYSCALE: not yours yet ────────────────────────────────────────────────────────────── */
html body .tm-band--market{ filter: grayscale(1) brightness(.92); opacity: .9; }
/* …but the ACTION must stay legible and clickable — a greyed-out page you can still act on has
   to keep its buttons readable, or the treatment reads as "disabled" instead of "not yours". */
html body .tm-band--market button,
html body .tm-band--market [role="button"],
html body .tm-band--market a.btn,
html body .tm-band--market [class*="cta"]{
  filter: grayscale(0) !important;
}
html body .tm-band--market:hover{ filter: grayscale(.55) brightness(.97); opacity: 1; }
html body .tm-band--market .tm-h,
html body .tm-band--market .tac-eyebrow{ filter: grayscale(0); }

/* THE 100 — a headline and a taste. Locked rows read as locked, not as broken. */
html body .tm-band--the100{ filter: grayscale(1) brightness(.9); opacity: .85; }
html body .tm-band--the100:hover{ filter: grayscale(.6) brightness(.96); opacity: 1; }
html body .tm-band--the100 .tm-h{ filter: grayscale(0); }
html body .tm-band--the100 .tm-h span[style]{ color: var(--accent,#FF2E88) !important; }

/* the old sub-tabs are gone from the markup; hide any that a cached render still paints */
html body .hub-view[data-view="v-hires"] .s2-htabs{ display: none !important; }
html body .hub-view[data-view="v-hires"] .s2-hpanel{ display: block !important; }

@media (prefers-reduced-motion: no-preference){
  html body .tm-band--market, html body .tm-band--the100{ transition: filter .25s ease, opacity .25s ease; }
}

/* ── 20 · PITCH & BRIEF PREP — ONE COLUMN, COMMIT AT THE BOTTOM ────────────────────────────────
   CEO 2026-08-20: "clean this all up into one column, with the actual Pitch it button at the
   bottom — apply same for brief prep as this is the same."

   The two-column split was the last thing keeping this page busy: the work ran down the left
   while the docket floated in the right rail carrying a SECOND commit button, so the eye had two
   places to finish and the reading measure was needlessly narrow. One column reads top to bottom
   — brief, response, team, then the decision — which is the order the job is actually done in.

   The docket already follows .wr-main in source order, so a single-column grid puts it last with
   no markup change: the commit button lands at the bottom by construction rather than by
   position juggling.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
html body .pn-fwin .wr-split{
  display: block !important;
  grid-template-columns: none !important;
  column-gap: 0 !important;
}
html body .pn-fwin .wr-main{ width: auto !important; max-width: none !important; }
html body .pn-fwin .wr-rail{
  position: static !important;
  width: auto !important; max-width: none !important;
  margin: 22px 0 0 !important;
  display: block !important;
}
/* the docket becomes the closing act: full width, and its CTA is the biggest thing on it */
html body .pn-fwin .wr-rail .wr-bs{ width: auto !important; max-width: none !important; }
html body .pn-fwin #get-to-work,
html body .pn-fwin #pitch-it{
  width: 100% !important;
  min-height: 56px !important;
  font-size: 16px !important;
  justify-content: center !important;
}
/* a reading measure for prose, so one column does not become one very wide column */
html body .pn-fwin .wr-doss-lead,
html body .pn-fwin .wr-deliver-note,
html body .pn-fwin .wr-more-body p,
html body .pn-fwin .bop p{ max-width: 72ch !important; }

/* ── ROLL THE DICE — the control row stops overflowing its panel ───────────────────────────────
   The button itself was correct; the ROW carrying it was not. Label and controls sat in a row
   with no wrapping and no min-width:0, so on a narrower column the controls were pushed past the
   panel edge — which is why "Roll the Dice" appeared half outside the box and overlapping the
   header above it. A control that leaves its container is not a styling nit; it is unclickable. */
html body .pn-dice-wrap{
  display: inline-flex !important; align-items: center; gap: 8px;
  flex: 0 0 auto; margin-left: auto;
}
html body .wr-more-body > .row,
html body .wr-angle > .row,
html body .pn-fwin .row:has(> .pn-dice-wrap){
  display: flex !important; flex-wrap: wrap !important;
  align-items: center !important; gap: 10px !important;
  min-width: 0 !important; width: 100% !important;
  padding-right: 0 !important;
}
html body .wr-more-body > .row > *:first-child,
html body .pn-fwin .row:has(> .pn-dice-wrap) > *:first-child{ min-width: 0; flex: 1 1 180px; }
/* the "open the file" action was running past the edge on the same row */
html body .pn-fwin [class*="openfile"], html body .pn-fwin .wr-openfile,
html body .pn-fwin .wr-more-body button{ max-width: 100% !important; white-space: normal !important; }
/* the docket CTA was clipping its own label at (0 Time) */
html body .pn-fwin #get-to-work small{ white-space: nowrap; margin-left: 6px; opacity: .85; }

/* ── 21 · THE WIRE — KILL THE STAMP, LIFT THE PANEL ────────────────────────────────────────────
   CEO 2026-08-20: "these popups use ugly stamp marks and are too dark on dark backgrounds — they
   need to be bigger and clearer."

   THE STAMP. A rotated "NOT RANKED / WK 1" rubber stamp sat in the corner of every notice. It was
   already supposed to be dead — style-01 sets display:none on .wire-stamp — but style-01 is sheet
   #8 and pn-squad-dossier at #22 re-floats it, so the kill never took. Killed here, where it
   cannot be overruled. It was decoration competing with the sentence, and it repeated a fact the
   TESTER chip already states permanently in the corner of the screen.

   THE CONTRAST. The wire is a dark panel on dark screens, separated only by a hairline, so a
   notice could appear and be missed. It now sits on a lifted surface with a real border and a
   cast shadow, at a size you cannot miss — this is the game talking to you.                    */
html body .toast.pn-wire .pn-stamp,
html body .toast.pn-wire .wire-stamp,
html body .toast.pn-wire [class*="stamp"]{
  display: none !important; content: none !important;
}
html body .toast.pn-wire{
  width: min(720px, calc(100vw - 40px)) !important;
  max-width: none !important;
}
html body .toast.pn-wire .wire-body{
  background: linear-gradient(180deg, #1b2331, #141b27) !important;
  color: #F4F7FE !important;
  font-size: 17px !important;
  line-height: 1.5 !important;
  padding: 20px 24px 22px !important;
}
html body .toast.pn-wire{
  border: 1px solid rgba(255,255,255,.2) !important;
  border-radius: 14px !important;
  overflow: hidden !important;
  box-shadow: 0 34px 80px -22px rgba(0,0,0,.9), 0 0 0 1px rgba(0,0,0,.6) !important;
}
html body .toast.pn-wire .wire-band{
  background: rgba(28,22,44,.96) !important;
  border-bottom: 1px solid rgba(255,255,255,.14) !important;
  padding: 10px 16px !important;
}
/* the NOTICE chip earns its place — it names the kind of message. Bigger, and it stays inline. */
html body .toast.pn-wire .wire-body::before{
  font-size: 10px !important;
  padding: 5px 10px !important;
  margin-right: 10px !important;
  vertical-align: 2px !important;
  margin-bottom: 0 !important;
}
html body .toast.pn-wire .wire-body b{ color: #fff !important; }

/* ── 22 · THE PITCH LIVES IN THE DEVICE NOW ────────────────────────────────────────────────────
   CEO 2026-08-20, having asked several times: "why can you NOT put all this Pitch and Brief PREP
   content in iPad? So everything is in the iPad, NOT full screen. Financials are also full screen
   for some reason."

   pn-shell-adopt.css excluded data-view="pitch" from shell adoption for a real reason — the war
   room was two columns and the shell's 1180 well crushed the build-sheet rail. That reason died
   this morning when the CEO asked for one column. The exclusions are removed there; this makes
   the window fit the well instead of fighting it.

   The frame stays: a window inside the device is the right object — it is what the notices, the
   store and the report already are. It simply stops trying to be 1240 wide inside an 1180 well. */
html body .pn-fwin{
  max-width: 100% !important;
  margin: 12px 0 20px !important;
}
/* inside the device the gutter can come in a little — the device already provides an edge */
html body .content .pn-fwin{ --fwin-gut: 26px; }
/* the well scrolls; the window must not also try to own a viewport height */
html body .content .pn-fwin{ height: auto !important; max-height: none !important; }
/* the war room's own full-bleed background strip was sized to the viewport, not the well */
html body .content .pitch-wrap .pitch-bgstrip{ position: absolute !important; inset: 0 !important; }

/* ── 23 · FINANCIALS COMES INSIDE TOO ──────────────────────────────────────────────────────────
   The CFO Pressure Room is position:fixed against the VIEWPORT, so it covered the whole browser
   and broke out of the device — the same complaint, different screen. Pinned to the device's
   screen instead, so it reads as a window on the iPad rather than a takeover of the page. */
html body #__cfoOverlay,
html body #__cooOverlay{
  position: fixed !important;
  inset: 0 !important;
  display: grid !important;
  place-items: center !important;
  padding: 3vh 3vw !important;
  background: rgba(4,7,12,.72) !important;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
html body .screen #__cfoOverlay, html body .screen #__cooOverlay{ position: absolute !important; }
html body #__cfoOverlay > *, html body #__cooOverlay > *{
  max-width: min(1080px, 100%) !important;
  max-height: 92% !important;
  overflow: auto !important;
  border-radius: 14px !important;
  border: 1px solid rgba(255,255,255,.14) !important;
  box-shadow: 0 40px 90px -30px rgba(0,0,0,.85) !important;
}

/* ── 24 · THE PITCH SCROLLS IN THE WELL (P0) ───────────────────────────────────────────────────
   Belt and braces on the fix in pn-shell-adopt: the war room must have a working scroller no
   matter which way the wrappers resolve. If .content is a real box it scrolls; if anything
   dissolves it again, the device screen takes over. A player must never be unable to finish a
   pitch because of a layout rule. */
html body[data-view="pitch"] .content{
  display: block !important;
  overflow-y: auto !important;
  overflow-x: hidden !important;
  max-height: 100% !important;
  -webkit-overflow-scrolling: touch;
}
html body[data-view="pitch"] .screen{ display: block !important; overflow: hidden !important; }
html body[data-view="pitch"] .pad, html body[data-view="pitch"] .dev{ display: block !important; }
html body[data-view="pitch"] .content > #app.wrap{ overflow: visible !important; height: auto !important; }

/* ── 25 · THE ANSWER TO TWENTY ROUNDS OF "UGLY TYPE" ───────────────────────────────────────────
   CEO, ~20 times: the type on the pitch and brief prep pages is ugly. He was right every time and
   every sweep I ran missed it, because I kept checking the wrong property.

   THE ACTUAL FAULT. pn-design-0817 sets the brief's headline as:
       .pitch-wrap .bop-ask{ font:700 clamp(26px,3.4vw,46px)/1.06 IS,system-ui,sans-serif }
   IS is Instrument Sans — the BODY face — set at 46px and asked to behave like a headline. The
   money and the clock do the same. Six pixels above them, the masthead correctly uses Space
   Grotesk, the display face. So one sans is doing every job on the page: body copy, headline and
   figure, with a real display face sitting right beside it for contrast.

   That is the flat, generic look, and it is the open-design anti-pattern by name: "one
   sans-serif at every size with no display/mono contrast".

   WHY EVERY FIX MISSED IT. Each sweep asked "is this family LOADED, and is it ON-BRAND?" IS is
   both — it is a house face. font_guard passes it and always will. The fault was never a wrong
   font; it was the right font in the wrong ROLE, and no amount of checking font-family could
   find that. Twenty rounds of the same complaint because I audited the property that was fine.

   THE RULE. Display roles take the display face. Body copy stays Instrument Sans. Data stays JB.
   Three faces, three jobs — which is the system this product already had, applied to the two
   screens that never got it.
   ══════════════════════════════════════════════════════════════════════════════════════════ */
html body .pitch-wrap .bop-ask,
html body .pn-fwin .bop-ask{
  font-family: 'Space Grotesk', IS, system-ui, sans-serif !important;
  font-weight: 700 !important;
  letter-spacing: -.028em !important;
  line-height: 1.02 !important;
}
/* the figures are DATA at display size — they take the display face and tabular figures so the
   money does not wobble as it counts */
html body .pitch-wrap .bop-hero-v,
html body .pn-fwin .bop-hero-v{
  font-family: 'Space Grotesk', IS, system-ui, sans-serif !important;
  font-weight: 700 !important;
  letter-spacing: -.032em !important;
  font-variant-numeric: tabular-nums !important;
}
/* the section heads on the response and the build sheet were body-face-as-headline too */
html body .pn-fwin .wr-bs-brand,
html body .pn-fwin .wr-doss h2,
html body .pn-fwin .wr-resp h2,
html body .pn-fwin .bop h2,
html body .pn-fwin .bop h3,
html body .pn-fwin .wr-mh-title{
  font-family: 'Space Grotesk', IS, system-ui, sans-serif !important;
  letter-spacing: -.02em !important;
}
/* and the depth cards — "Tick it off / Review it / Oversee it" — which are headings, not copy */
html body .pn-fwin .bop-lvl b,
html body .pn-fwin .bop-lvl strong,
html body .pn-fwin .bop-lvl-k{
  font-family: 'Space Grotesk', IS, system-ui, sans-serif !important;
  letter-spacing: -.012em !important;
}
/* BODY COPY STAYS BODY COPY. Stated so the next sweep does not "helpfully" push prose into the
   display face and undo the contrast this rule exists to create. */
html body .pn-fwin p,
html body .pn-fwin .bop-body,
html body .pn-fwin .wr-deliver-note,
html body .pn-fwin .muted{
  font-family: IS, ui-sans-serif, system-ui, sans-serif !important;
}

/* ── 26 · HEADINGS TAKE THE DISPLAY FACE, GAME-WIDE ────────────────────────────────────────────
   The role check added to font_guard found THIRTY rules setting the body face at display size —
   .bop-ask (the one the CEO kept circling), h1, .fl-mast h1, .navbar h1, .rv-brand, .shead h2,
   .sqd-read b, .t100-ovr b and more. So it was never a pitch/brief problem; those two screens
   were simply where he looked hardest.

   Stated once, as a rule, rather than screen by screen: a heading is a heading everywhere.
   Space Grotesk for display, Instrument Sans for copy, JB for data. Copy elements are excluded
   explicitly so prose cannot drift into the display face and flatten the contrast from the
   other direction. */
html body h1, html body h2, html body h3,
html body .fl-mast h1, html body .navbar h1, html body .shead h2,
html body .hcrown h3, html body .board .say h2,
html body .rv-brand, html body .pn-review .rv-brand,
html body .sqd-read > b, html body .t100-ovr b, html body .pn-stgseal-n,
html body .mt-title, html body .onb-headline, html body .tm-h,
html body [class*="-title"]:not(p):not(span[class*="sub"]),
html body [class*="headline"]:not(p){
  font-family: 'Space Grotesk', IS, system-ui, sans-serif !important;
  letter-spacing: -.02em;
}
/* mono-set headings are DATA and keep their face — a case ref is not a headline */
html body h1[class*="mono"], html body h2[class*="mono"], html body h3[class*="mono"],
html body .tac-eyebrow, html body [class*="-k"], html body [class*="eyebrow"]{
  font-family: var(--mono, JB, ui-monospace, monospace) !important;
  letter-spacing: .16em;
}
/* and prose stays prose */
html body p, html body li, html body .muted, html body .small,
html body [class*="-sub"], html body [class*="-body"], html body [class*="-note"]{
  font-family: IS, ui-sans-serif, system-ui, sans-serif !important;
  letter-spacing: 0;
}

/* ── 27 · THE TEAM PAGE — THREE PARTS, AND THE INVENTED HEADLINE IS GONE ───────────────────────
   CEO 2026-08-20: "look at this type — do you think this works? Double space, white and orange?
   That's a totally NEW treatment you should not be creating. I already gave you proper titles for
   each page." And: "I said to have 3 clear parts."

   Two separate faults, both mine.

   THE HEADLINE. The shell already prints his own page title — VIEW_TITLES maps v-hires to "The
   Team" and has since 08-19. I stacked an invented "WHO I HAVE" underneath it in a white/orange
   split with a hard space, a treatment nobody asked for. Two headlines for one page. Removed in
   the markup; the band keeps one orientation line.

   THREE PARTS. I built the bands and then left five stacked components inside the first — a
   second dossier view of the same team among them. Part one is now the people and nothing else.

   What is left here is the SEPARATION: each part has to read as a part from across the room. */
html body .tm-band{ margin: 0 0 26px; }
html body .tm-band--mine{ margin-bottom: 8px; }

/* section labels are labels — one weight, one colour, sentence case. Not headlines competing
   with the page title above them. */
html body .tm-h{
  font-family: 'Space Grotesk', IS, system-ui, sans-serif !important;
  font-size: 19px !important;
  font-weight: 700 !important;
  letter-spacing: -.01em !important;
  color: #F6F3FF !important;
  text-transform: none !important;
  display: flex; align-items: baseline; gap: 10px;
}
html body .tm-h span[style]{ color: inherit !important; }   /* kill any inherited split colour */
html body .tm-sub--lead{
  margin: 0 0 16px !important;
  font-size: 14px !important;
  color: rgba(237,241,250,.72) !important;
}
/* the divider between "yours" and "not yours" is the page's one structural statement, so it
   carries real weight rather than a hairline */
html body .tm-rule{ margin: 34px 0 24px !important; }
html body .tm-rule::before, html body .tm-rule::after{ height: 1px; background: rgba(255,255,255,.18); }

/* THE 100 is the third part and is locked, so it reads as a preview, not as a live board */
html body .tm-band--the100{ margin-top: 30px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.12); }

/* ── 28 · PREP LIVES IN THE DEVICE. THE PITCH ITSELF DOES NOT. (P1) ────────────────────────────
   CEO: "cut off page content or nearly zero visible page content — a mess."

   My error, and it is a distinction I collapsed. data-view="pitch" covers TWO different kinds of
   screen:

     PREP   — the war room, build the pitch, build the brief. A document you work on.
              The CEO asked for this in the device, and it belongs there.
     THE RUN — PRESENT, the boardroom, the deck playing, PITCH READY. Cinematic set-pieces that
              were always full-bleed and were never the complaint.

   I put both in the well. The run's rooms size themselves against the VIEWPORT —
   .pn-call is height:min(884px,96vh), .vc-room is min(92vh,860px) — and 96vh inside a well that
   is shorter than the viewport overflows and clips, which is the cut-off content and the large
   empty area beneath it.

   A viewport unit inside a container that is not the viewport is always going to lie. So the run
   goes back to being full-bleed, and prep stays in the device. */
html body.pn-call-live .pad,
html body.pn-call-live .dev,
html body.pn-call-live .screen,
html body.pn-call-live .content,
html body:has(.pn-review) .pad, html body:has(.pn-review) .dev,
html body:has(.pn-review) .screen, html body:has(.pn-review) .content,
html body:has(.result-screen) .pad, html body:has(.result-screen) .dev,
html body:has(.result-screen) .screen, html body:has(.result-screen) .content,
html body:has(#vc-shell) .pad, html body:has(#vc-shell) .dev,
html body:has(#vc-shell) .screen, html body:has(#vc-shell) .content,
html body:has(.pn-preroom) .pad, html body:has(.pn-preroom) .dev,
html body:has(.pn-preroom) .screen, html body:has(.pn-preroom) .content,
html body:has(.boardroom-mode) .pad, html body:has(.boardroom-mode) .dev,
html body:has(.boardroom-mode) .screen, html body:has(.boardroom-mode) .content{
  display: contents !important;
}
/* and those set-pieces get the page scroll back, since they are no longer in a well */
html:has(body.pn-call-live), html:has(body:has(#vc-shell)),
html:has(body:has(.pn-preroom)), html:has(body:has(.boardroom-mode)),
html:has(body:has(.pn-review)), html:has(body:has(.result-screen)),
body.pn-call-live, body:has(#vc-shell), body:has(.pn-preroom), body:has(.boardroom-mode),
body:has(.pn-review), body:has(.result-screen){
  overflow: auto !important; height: auto !important;
}
/* belt and braces: nothing in the pitch flow may size itself off the viewport while it is inside
   the well, because the well is not the viewport.

   ⛔ FIXED 26 AUG — THIS WAS THE LETTERBOX. CEO: "everything has been compressed into this thin
   section - its a disaster."

   The intent above is right; the guard was firing when it should not. `display:contents` removes
   an element's BOX, not its place in the tree — so `.content .pn-call` still matches once the
   wrappers above have been dissolved and the room has gone full-bleed. The room was therefore
   being held at `height:auto` in exactly the state the auto was meant to protect it from, and
   `height:auto` on a flex column shrink-wraps: measured 67px with stub content, and the ~325px
   band in the CEO's screenshot with the real thing. It beat `html body .pn-call{height:min(920px,
   94vh)}` on specificity, so the room never got its 94vh.

   So the guard now asks whether the room is ACTUALLY in a well, rather than inferring it from an
   ancestor selector that survives the collapse. The state list is the same one that collapses the
   wrappers twenty lines above — if a state is added there it must be added here, and the two are
   deliberately adjacent so that is hard to miss. */
html body[data-view="pitch"]:not(.pn-call-live):not(:has(#vc-shell)):not(:has(.pn-preroom)):not(:has(.boardroom-mode)):not(:has(.pn-review)):not(:has(.result-screen)) .content .pn-call,
html body[data-view="pitch"]:not(.pn-call-live):not(:has(#vc-shell)):not(:has(.pn-preroom)):not(:has(.boardroom-mode)):not(:has(.pn-review)):not(:has(.result-screen)) .content .vc-room{
  height: auto !important; max-height: none !important;
}

/* ── 29 · THE COMMIT BUTTON IS A BUTTON, NOT A HOARDING ────────────────────────────────────────
   CEO: "the pitch it button also was buggy." I had made it width:100% at 56px, which turned the
   page's last object into a full-bleed orange slab with a focus ring baked on. Full width was
   right for a single-column page; slab height and a permanent ring were not. */
html body .pn-fwin #get-to-work,
html body .pn-fwin #pitch-it{
  min-height: 48px !important;
  max-width: 520px !important;
  margin: 4px 0 0 !important;
  font-size: 15px !important;
  box-shadow: none !important;
  outline: none !important;
}
html body .pn-fwin #get-to-work:focus-visible,
html body .pn-fwin #pitch-it:focus-visible{ outline: 2px solid #fff !important; outline-offset: 2px !important; }

/* ── 30 · THE PITCH ITSELF — DIALOGUE AND PROGRESS ARE THE EVENT ───────────────────────────────
   CEO 2026-08-20, PRIORITY: "AGENCY films in squares cutting off the dialogue below — headlines
   top right crash the placeholder video — so reduce main placeholder video, remove the square
   videos, hero the dialogue and the progress."

   The screen had its priorities inverted. A large placeholder film held the left, a five-up grid
   of agency stills held the right, and the two things the player is actually here for — what the
   room SAYS and whether the room is WARMING — were squeezed to the bottom edge and clipped. The
   deck grid also collided with its own slide headline, because both were absolutely placed in
   the same corner.

   So the stills go, the film gets smaller, and the dialogue and the temperature take the space
   they earn. This is a pitch, not a moodboard. */
html body .pn-rail-share{ display: none !important; }

/* ⛔ CORRECTED 2026-08-21. My first pass at "reduce the main placeholder video" capped the feed
   at 38vh and made the stage flex:0 0 auto. Combined with height:auto on the room, that collapsed
   the whole call to a thin band floating in an otherwise empty page — the film cropped to a strip
   with the client's face behind the caption, and the transcript clipped again at the bottom. I
   was asked to make the film smaller RELATIVE to the dialogue, and instead made the entire room
   smaller than the screen.
   The room fills the screen again. The film is reduced by taking the SMALLER COLUMN — which is
   what "reduce the placeholder video" actually meant — not by shrinking the room around it. */
html body .pn-call-stage{
  flex: 1 1 0 !important;
  min-width: 0 !important; min-height: 0 !important;
  display: flex !important; flex-direction: column !important;
}
html body .pn-call-feed{
  flex: 1 1 auto !important;
  min-height: 0 !important; max-height: none !important;
  border-radius: 12px !important; overflow: hidden !important;
}
html body .pn-call-feed video, html body .pn-call-feed img{
  width: 100% !important; height: 100% !important; object-fit: cover !important;
}

/* THE DIALOGUE — the reason the screen exists */
html body .pn-call-rail{
  display: flex !important; flex-direction: column !important;
  min-height: 0 !important; gap: 12px !important;
}
html body .pn-rail-transcript{
  flex: 1 1 auto !important;
  min-height: 0 !important;
  overflow-y: auto !important;
  font-size: 15.5px !important;
  line-height: 1.5 !important;
  padding-right: 4px;
}
html body .pn-rail-transcript > *{ margin-bottom: 10px !important; }
/* the caption sits UNDER the film, not across the client's face — it was covering the very
   performance it is captioning */
html body .pn-call-caption{
  position: static !important;
  flex: 0 0 auto !important;
  margin-top: 10px !important;
  font-size: 16px !important; line-height: 1.4 !important;
  padding: 12px 16px !important;
  border-radius: 10px !important;
  background: rgba(10,14,22,.78) !important;
}
html body .pn-call-cliname{ z-index: 3 !important; }
/* participants stay, but as a strip rather than a column of cards */
html body .pn-rail-parts{
  display: flex !important; flex-wrap: wrap !important; gap: 8px !important;
  flex: 0 0 auto !important;
}

/* THE PROGRESS — the temperature is the score. It reads at a glance or it is not doing its job. */
html body .pn-tempstrip{
  flex: 0 0 auto !important;
  padding: 14px 16px !important;
  border-radius: 12px !important;
  background: rgba(10,14,22,.72) !important;
  border: 1px solid rgba(255,255,255,.14) !important;
}
html body .pn-temp-track{ height: 12px !important; border-radius: 99px !important; }
html body .pn-temp-eyebrow{ font-size: 10px !important; letter-spacing: .18em !important; }

/* THE ROOM FILLS THE SCREEN. It is the main event, not a widget in the middle of a page. */
html body .pn-callroom{
  position: fixed !important; inset: 0 !important;
  display: grid !important; place-items: center !important;
  padding: 2vh 2vw !important;
}
html body .pn-call{
  width: min(1440px, 96vw) !important;
  height: min(920px, 94vh) !important;
  max-height: 94vh !important;
  display: flex !important; flex-direction: column !important;
}
html body .pn-call-body{
  flex: 1 1 auto !important;
  min-height: 0 !important;
  overflow: hidden !important;
  align-items: stretch !important;
  display: flex !important;
}
/* the dialogue column is the larger of the two — that is the whole point of this screen */
html body .pn-call-rail{ flex: 1 1 0 !important; min-width: 0 !important; }
@media (min-width: 1100px){
  html body .pn-call-stage{ flex: 0 0 46% !important; }
  html body .pn-call-rail{ flex: 1 1 54% !important; }
}
html body .pn-call-dock{ flex: 0 0 auto !important; }
@media (max-width: 1100px){
  html body .pn-call-body{ flex-direction: column !important; overflow-y: auto !important; }
  html body .pn-call-stage{ flex: 0 0 auto !important; }
  /* GP-16 (2026-09-14, coordinator-eye finding) — SUPER-IMPRESSED / WINNING collision. This rule
     gave .pn-call-feed a real height:30vh + flex:0 0 auto, but never touched its BASE
     `position:absolute;inset:0` (style-01.css:845) — an absolutely-positioned box takes zero
     space in a flex parent regardless of its flex-basis, so `.pn-tempstrip` (the next real
     flow child of `.pn-call-stage`) rose to the very top of the stage and sat directly under
     `.pn-call-cliread` ("SUPER-IMPRESSED", position:absolute;top:13px;right:15px relative to
     THE STAGE, not the feed) — the WINNING pill inside `.pn-tempstrip`'s header row landed on
     top of it. Putting the feed back into flow at this breakpoint is the fix: it becomes a real
     30vh flex sibling, `.pn-tempstrip` renders below it as the "BROADCAST STACK" comment above
     already intended, and the absolutely-positioned name/read chips (anchored to the stage, which
     still starts above the feed) stay exactly where they've always been — over the video, not
     over the temperature strip. */
  html body .pn-call-feed{ height: 30vh !important; flex: 0 0 auto !important; position: relative !important; inset: auto !important; }
}

/* the held state that covers the pitch film's load — see pnWalkingIn() */
#pn-walkin{
  position: fixed; inset: 0; z-index: 21000;
  display: grid; place-items: center;
  background: radial-gradient(120% 90% at 50% 40%, #121a28 0%, #080c14 60%, #05070c 100%);
  opacity: 1; transition: opacity .26s ease;
}
#pn-walkin.is-out{ opacity: 0; pointer-events: none; }
#pn-walkin .wi-in{ text-align: center; max-width: 460px; padding: 0 24px; }
#pn-walkin .wi-k{
  display: block; font: 800 10px/1 var(--mono, JB, monospace);
  letter-spacing: .28em; color: var(--accent,#f97316); margin-bottom: 14px;
}
#pn-walkin .wi-h{
  display: block; font-family: 'Space Grotesk', IS, system-ui, sans-serif;
  font-size: 34px; font-weight: 700; letter-spacing: -.02em; color: #F6F3FF;
}
#pn-walkin .wi-s{
  display: block; margin-top: 8px; font-size: 14px;
  color: rgba(237,241,250,.62); font-family: IS, ui-sans-serif, system-ui, sans-serif;
}
#pn-walkin .wi-bar{
  display: block; margin: 22px auto 0; width: 200px; height: 3px;
  background: rgba(255,255,255,.14); border-radius: 99px; overflow: hidden;
}
#pn-walkin .wi-bar i{
  display: block; width: 40%; height: 100%; border-radius: 99px;
  background: var(--accent,#f97316); animation: wiSlide 1.05s ease-in-out infinite;
}
@keyframes wiSlide{ 0%{transform:translateX(-110%)} 100%{transform:translateX(360%)} }
@media (prefers-reduced-motion: reduce){ #pn-walkin .wi-bar i{ animation: none; width: 100%; } }

/* ── 31 · THE WON PAGE — THE FILM PLAYS, AND THE TYPE BEHAVES ──────────────────────────────────
   CEO 2026-08-20: "the Won page looks awful — fonts are weird — we need the win video on here
   for pitches, not Briefs."

   THE FILM. assets/video/result/win.mp4 has always been rendered here, but as `.result-vid`
   inside `.result-bg`, under a gradient, a grain layer and a vignette. Three scrims on top of a
   celebration means you cannot see it. Winning a new-business pitch is the biggest moment in the
   game and it was being used as wallpaper. On a won PITCH it now actually plays; client sign-offs
   keep the quiet treatment, which is the distinction he asked for.

   THE TYPE. "WON" was inheriting a light weight at display size — the same body-face-as-display
   fault as the brief headline, which is why it reads thin and wrong against a heavy masthead
   elsewhere in the game. It takes the display face at full weight, and the rest of the screen
   follows the same three-role system: Space Grotesk display, IS copy, JB data. */
html body .result-screen.is-pitchwin .result-vid{
  opacity: 1 !important;
  filter: saturate(1.05) contrast(1.04) !important;
}
html body .result-screen.is-pitchwin .result-bg-grad{
  background: linear-gradient(180deg, rgba(5,8,14,.35) 0%, rgba(5,8,14,.62) 46%, rgba(5,8,14,.88) 100%) !important;
}
html body .result-screen.is-pitchwin .result-bg-grain{ opacity: .05 !important; }
html body .result-screen.is-pitchwin .result-bg-vig{ opacity: .45 !important; }
/* the copy still has to be readable over a moving image — it earns its contrast from a surface */
html body .result-screen.is-pitchwin .result-inner{ position: relative; z-index: 2; }
html body .result-screen.is-pitchwin .pn-rz-quote,
html body .result-screen.is-pitchwin .pn-rz-ledger,
html body .result-screen.is-pitchwin .pn-rz-notes{
  background: rgba(8,11,18,.82) !important;
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}

/* THE VERDICT WORD — display face, full weight. It is the loudest word on the screen. */
html body .pn-rz-word{
  font-family: 'Space Grotesk', IS, system-ui, sans-serif !important;
  font-weight: 700 !important;
  letter-spacing: -.03em !important;
  line-height: .92 !important;
}
html body .pn-rz-brandrow .bn{
  font-family: 'Space Grotesk', IS, system-ui, sans-serif !important;
  font-weight: 700 !important; letter-spacing: -.01em !important;
}
html body .pn-rz-brandrow .bn span{
  font-family: IS, ui-sans-serif, system-ui, sans-serif !important;
  font-weight: 400 !important; letter-spacing: 0 !important;
}
/* the client's line is a QUOTE — it is dialogue, so it stays in the reading face, not display */
html body .pn-rz-quote, html body .pn-rz-quote *{
  font-family: IS, ui-sans-serif, system-ui, sans-serif !important;
}
/* the ledger is DATA */
html body .pn-rz-ledger .lg-v, html body .pn-rz-ledger .lg-k,
html body .result-screen [class*="score"], html body .result-screen [class*="bar-to"]{
  font-family: var(--mono, JB, ui-monospace, monospace) !important;
}

/* ── 32 · THE CLIENT REVIEW STOPS BEING CUT ────────────────────────────────────────────────────
   CEO: "several disasters on the build the brief — cut pages… look at the actual Presentation
   experience — disaster."

   Same fault as the pitch run, one screen along. The review is a SET-PIECE — it carries its own
   window, its own chrome and its own scroll — and I put it in the device's well along with prep,
   because both answer to data-view="pitch". Its panels size against the viewport, so inside a
   shorter well the content ran out of room and left the large dead area underneath the options.
   It is now full-bleed with page scroll, like the call room and the verdict. */
html body .pn-review{
  max-width: min(1240px, 96vw) !important;
  margin: 18px auto 26px !important;
  height: auto !important;
  max-height: none !important;
}
html body .pn-review .rv-body, html body .pn-review .rv-scroll{
  max-height: none !important; overflow: visible !important;
}

/* ── 33 · THE LIGHT ROOM, ON EVERY SCREEN THAT SHOWS THE DEVICE ────────────────────────────────
   CEO: "you still haven't implemented the light page background here to emphasise the dark iPad."

   I had — but scoped to body[data-view="office"], so it only ever appeared on the Floor. The
   agency picker, sign-in and every other device screen kept the dark plate, which is exactly
   where he was looking. The device is the device on every screen that shows it, so the wash
   follows the device, not one view. */
html body:has(#pn-shell) #penthouse-bg,
html body:has(.pad) #penthouse-bg{ position: relative; }
html body:has(#pn-shell) #penthouse-bg::after,
html body:has(.pad) #penthouse-bg::after{
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 2;
  background:
    radial-gradient(120% 90% at 50% 38%, rgba(247,245,241,.93) 0%, rgba(240,238,233,.88) 42%, rgba(226,224,219,.80) 72%, rgba(214,212,207,.76) 100%);
}
html body:has(#pn-shell) #penthouse-bg #bgplate,
html body:has(.pad) #penthouse-bg #bgplate{
  display: block !important; opacity: .5 !important;
  filter: saturate(.55) contrast(1.02) brightness(1.12) !important;
}
html body:has(#pn-shell) #penthouse-bg .wash,
html body:has(.pad) #penthouse-bg .wash{ opacity: .22 !important; mix-blend-mode: multiply; }
html body:has(#pn-shell) #pn-shell, html body:has(.pad) .pad{
  box-shadow: 0 50px 90px -30px rgba(28,26,22,.55), 0 18px 40px -18px rgba(28,26,22,.4) !important;
}
/* the set-pieces are cinematic and keep their dark room */
html body.pn-call-live #penthouse-bg::after,
html body:has(#vc-shell) #penthouse-bg::after,
html body:has(.pn-preroom) #penthouse-bg::after,
html body:has(.result-screen) #penthouse-bg::after,
html body:has(.pn-review) #penthouse-bg::after{ content: none !important; }

/* ── 34 · THE DECISION IS A WINDOW, NOT A BAND ─────────────────────────────────────────────────
   CEO 2026-08-20: "these full width pages with pauses and decision for user to make are terribly
   designed — have this as finder window pop up."

   .rv-fork was position:fixed; left:0; right:0; bottom:0 — a full-bleed band welded across the
   foot of the screen, with the two options stranded at opposite ends of a very wide row and the
   scene above it merely blurred. It reads as a page that has broken in half rather than as a
   moment that has stopped for you.

   A decision that pauses the game is a modal by nature: it wants focus, a centre, an edge, and
   the scene visibly held behind it. So it becomes the same Finder window every other interruption
   in this game already is — titlebar, traffic lights, one measure — with the two calls side by
   side at a size you can actually compare. */
html body .pn-review.has-fork::before,
html body .pn-review:has(.rv-fork)::before{
  content: ""; position: fixed; inset: 0; z-index: 8;
  background: rgba(4,7,12,.62);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
html body .pn-review .rv-fork{
  position: fixed !important;
  left: 50% !important; right: auto !important;
  top: 50% !important; bottom: auto !important;
  transform: translate(-50%, -50%) !important;
  width: min(720px, calc(100vw - 40px)) !important;
  max-height: min(84vh, 640px) !important;
  overflow-y: auto !important;
  z-index: 30 !important;
  background: #0C1017 !important;
  border: 1px solid rgba(255,255,255,.16) !important;
  border-radius: 14px !important;
  padding: 0 0 22px !important;
  box-shadow: 0 44px 100px -28px rgba(0,0,0,.88), 0 0 0 1px rgba(0,0,0,.6) !important;
  animation: none !important;
}
/* YOUR CALL becomes the window's titlebar, with the traffic lights drawn in it */
html body .pn-review .rv-fork-k{
  display: flex !important; align-items: center !important; gap: 10px !important;
  margin: 0 0 18px !important; padding: 10px 16px !important;
  background: rgba(14,18,26,.94) !important;
  border-bottom: 1px solid rgba(255,255,255,.12) !important;
  border-radius: 14px 14px 0 0 !important;
  font: 800 10px/1 var(--mono, JB, monospace) !important;
  letter-spacing: .2em !important; color: rgba(246,243,255,.7) !important;
  position: sticky; top: 0; z-index: 2;
}
html body .pn-review .rv-fork-k::before{
  content: ""; flex: none; width: 42px; height: 10px; border-radius: 99px;
  background:
    radial-gradient(circle 5px at 5px 5px,  #FF5F57 98%, transparent) 0 0/16px 10px no-repeat,
    radial-gradient(circle 5px at 5px 5px,  #FEBC2E 98%, transparent) 16px 0/16px 10px no-repeat,
    radial-gradient(circle 5px at 5px 5px,  #28C840 98%, transparent) 32px 0/16px 10px no-repeat;
}
html body .pn-review .rv-fork-h{
  margin: 0 20px 8px !important;
  font-family: 'Space Grotesk', IS, system-ui, sans-serif !important;
  font-size: 24px !important; font-weight: 700 !important; letter-spacing: -.02em !important;
}
html body .pn-review .rv-fork-sub{
  margin: 0 20px 18px !important; max-width: none !important;
  font-size: 14.5px !important; color: rgba(237,241,250,.7) !important;
}
/* the two calls sit side by side and are comparable, which is the whole job of this moment */
html body .pn-review .rv-fork-opts{
  display: grid !important;
  grid-template-columns: 1fr 1fr !important;
  gap: 14px !important;
  margin: 0 20px !important;
  align-items: start !important;
}
html body .pn-review .rv-optwrap{ min-width: 0 !important; }
html body .pn-review .rv-opt{
  width: 100% !important; text-align: left !important;
  padding: 14px 16px !important; border-radius: 10px !important;
  clip-path: none !important;
}
html body .pn-review .rv-why{ margin-top: 8px !important; }
html body .pn-review .rv-optdetail{
  margin: 8px 0 0 !important; font-size: 13px !important;
  color: rgba(237,241,250,.66) !important;
}
@media (max-width: 620px){
  html body .pn-review .rv-fork-opts{ grid-template-columns: 1fr !important; }
}

/* the client's reaction on the verdict — fills the column that was empty, and lands the result
   on a face rather than on a table of numbers.
   CEO 2026-09-06: this box shipped as a plain black void when the reaction clip was absent or
   stalled — the composed .rv-react-bed plate (brand mark + graded halftone) is now ALWAYS present
   underneath, so there is no state in which this reads as an empty box (UX_RULES §3). */
html body .rv-react{
  position: relative; margin: 0 0 18px; border-radius: 12px; overflow: hidden;
  border: 1px solid rgba(255,255,255,.14);
  background: #05080e; aspect-ratio: 16 / 10;
}
html body .rv-react-bed{
  position: absolute; inset: 0; z-index: 0; display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(120% 90% at 20% 0%, rgba(var(--glow,249,115,22),.22), transparent 60%),
    repeating-linear-gradient(115deg, rgba(255,255,255,.035) 0 2px, transparent 2px 26px),
    linear-gradient(150deg,#141c2c 0%,#0a1120 62%,#05080e 100%);
}
html body .rv-react-init{
  font: 900 clamp(30px,4vw,42px)/1 IS,sans-serif; font-style: italic; letter-spacing: -.02em;
  color: rgba(255,255,255,.22); text-transform: uppercase;
}
html body .rv-react-v{
  position: relative; z-index: 1; width: 100%; height: 100%; object-fit: cover; display: block;
  opacity: 0; transition: opacity .5s cubic-bezier(.4,0,.2,1);
}
html body .rv-react-v.is-live{ opacity: 1; }
@media (prefers-reduced-motion: reduce){ html body .rv-react-v{ transition: none; } }
html body .rv-react.is-win .rv-react-v{ filter: saturate(1.06) contrast(1.03); }
html body .rv-react-cap{
  position: absolute; left: 12px; bottom: 10px; z-index: 2;
  font: 700 9.5px/1 var(--mono, JB, monospace); letter-spacing: .2em; text-transform: uppercase;
  color: rgba(246,243,255,.82); text-shadow: 0 1px 6px rgba(0,0,0,.9);
}
html body .rv-react::after{
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(180deg, transparent 55%, rgba(4,7,12,.72) 100%);
}

/* ── 35 · THE READY SCREEN STOPS CLIPPING ITS OWN EYEBROW ──────────────────────────────────────
   CEO 2026-08-20, last blocker before he leaves: the WORK READY / PITCH READY card cuts its
   header off — "◤ THE REVIEW · FIELD & FORK" is sliced in half by the card's own top edge.

   The stage seal sits at the very top of .pn-ready-inner while the card clips its overflow, so
   the one line that tells you WHICH case you are about to walk into is the one line you cannot
   read. Give the card room for its own header and stop it clipping. */
html body .pn-ready-inner{
  overflow: visible !important;
  padding-top: 34px !important;
}
html body .pn-ready-inner > *:first-child{ margin-top: 0 !important; }
/* the seal/eyebrow row sits INSIDE the card, in the flow, not straddling its border */
html body .pn-ready .result-eyebrow,
html body .pn-ready .pnr-kick,
html body .pn-ready [class*="eyebrow"],
html body .pn-ready [class*="seal"]{
  position: static !important;
  transform: none !important;
  margin: 0 auto 14px !important;
  display: flex !important; align-items: center !important; justify-content: center !important;
  gap: 8px !important;
  white-space: nowrap !important;
  overflow: visible !important;
}
/* the whole set-piece scrolls if the viewport is short, rather than cropping the card */
html body .pn-ready{
  overflow-y: auto !important;
  align-items: flex-start !important;
  padding: max(24px, 4vh) 24px !important;
}
html body .pn-ready .pn-ready-inner{ margin: auto !important; }

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   36 · NEON — RETIRED (CEO 2026-09-12: "remove neon and just have light and dark")
   The contained [data-theme="neon"] skin that used to live in this section (built 2026-08-20) is
   deleted. data-theme can now only ever be "dark" or "light" (mvc-os.js) so it was dead weight.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── 37 · THE VERDICT'S LEFT COLUMN STOPS FLOATING ─────────────────────────────────────────────
   The result grid is named areas: "brand squad" / "quote squad" / "ledger squad". The right-hand
   column SPANS those three rows, so its height is distributed across them — which means the
   taller the right column gets, the bigger the gaps between brand, quote and ledger on the left.

   A previous fix pinned each left item to the top of its own row with align-self:start. That
   stops the items floating WITHIN a row, but does nothing about the rows themselves growing. Add
   the reaction film to the right column, as the CEO asked, and the right column gets taller — so
   the left column opens up a void, exactly as he has just photographed.

   The fix is to stop the slack being shared: the left rows take their content height, and the
   LAST row absorbs whatever is left over. The right column can then be any height it likes and
   the left column stays as one block. */
html body .pn-rz .result-inner{
  grid-template-rows: auto auto min-content min-content 1fr auto !important;
  align-content: start !important;
}
html body .pn-rz .pn-rz-brandrow{ margin-bottom: 0 !important; }
html body .pn-rz .result-quote,
html body .pn-rz .pn-rz-quote{ margin-top: 18px !important; align-self: start !important; }
html body .pn-rz .pn-rz-ledger{ margin-top: 18px !important; align-self: start !important; }
/* on a straight approval the quote row can be empty — an empty row must not hold space open */
html body .pn-rz .result-quote:empty,
html body .pn-rz .pn-rz-quote:empty{ display: none !important; }

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   26 AUG · THE VERDICT SCREEN — TWO STACKS, NOT ONE SHARED GRID
   ══════════════════════════════════════════════════════════════════════════════════════════════
   CEO: "this WON page is also a disaster."

   ⛔ FIRST, WHAT IT IS NOT. I assumed the shell wrappers being dissolved to `display:contents` had
   cost this screen its well. That collapse is DELIBERATE and argued above: these rooms size in
   `vh`, and a viewport unit inside a container that is not the viewport always lies. I changed it,
   measured no improvement, and reverted. Do not re-parent the set-pieces into the well.

   THE CAUSE, measured at 1440x900 on a forced verdict render. The children sat FLAT in one grid
   driven by template areas:

       "eyebrow eyebrow" / "word word" / "brand squad" / "quote squad" / "ledger squad" / "ledger actions"

   So the two columns shared row tracks, and every row was as tall as its tallest member. The left
   column's three rows (brand 52 + quote 72 + ledger 296) sized rows 3-5, while the right column
   held one 154px notes card — leaving a 208px hole between the notes and the action, and the
   "Back to the floor" button stranded at the bottom of it with "You are up to date. Nothing is
   late." adrift beside it. Parts that had drifted apart with nothing for the eye to follow.

   ⛔ AND ALIGNMENT CANNOT FIX IT. `align-content:start` and `align-self:start` pull an item to the
   TOP of its row; the leftover space stays in the row. Tried, measured (the button moved 708 ->
   708), reverted rather than left in the tree pretending to be a fix. A shared row track is a
   structural fact, not an alignment preference — so the rows had to stop being shared.

   THE FIX. showResult() now wraps each column's children in its own stack (.rz-col--l / --r), so
   the grid has exactly two cells under the headline and each column packs its own content from the
   top with one rhythm. Nothing is resized, nothing changes column: the composition the screen was
   designed with is intact, the drift is not.

   The template areas are replaced rather than overridden — leaving the old six-row map in place to
   be beaten by later rules is how this kind of layout rots. */
html body .pn-rz .result-inner{
  grid-template-areas:"eyebrow eyebrow" "word word" "coll colr" !important;
  grid-template-rows:auto auto 1fr !important;
  align-content:start !important;
}
html body .pn-rz .rz-col{
  display:flex !important; flex-direction:column !important; align-items:stretch !important;
  gap:clamp(14px,2.2vh,24px) !important; min-width:0 !important;
}
html body .pn-rz .rz-col--l{grid-area:coll !important}
html body .pn-rz .rz-col--r{grid-area:colr !important}
/* the stack owns the rhythm now, so the members stop carrying their own row-era margins */
html body .pn-rz .rz-col > *{margin-block:0 !important; align-self:stretch !important}
/* the action sits under the thing it acts on, at the end of its own column — never at the bottom
   of a window it does not fill */
html body .pn-rz .rz-col--r .result-actions{margin-top:auto !important; padding-top:clamp(8px,1.4vh,18px) !important}

/* one column at the narrow end: two 444px columns do not fit a phone, and a stack that reads
   top-to-bottom is the honest shape there anyway. */
@media (max-width:860px){
  html body .pn-rz .result-inner{
    grid-template-areas:"eyebrow" "word" "coll" "colr" !important;
    grid-template-columns:minmax(0,1fr) !important;
    grid-template-rows:auto auto auto auto !important;
    row-gap:clamp(16px,3vh,26px) !important;
  }
  html body .pn-rz .rz-col--r .result-actions{margin-top:0 !important}
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   26 AUG · THE BOARDROOM PRE-ROLL — the seconds before you present
   ══════════════════════════════════════════════════════════════════════════════════════════════
   CEO: "this page looks ugly too redress it."

   This is the beat where the client is already in the room and the deck is up. Its whole job is
   anticipation, and it was reading as a form: a headline, a picture, and a small pale button.

   What was actually wrong, measured on the markup at 1440x900:
     · #bail (Back) rendered 58x36 — UNDER the 44px tap floor this project sets for itself, and
       it was the only control on screen.
     · Centred and alone under the laptop, Back read as the PRIMARY action. It is the escape
       hatch. The thing actually happening — the room connecting — was set smaller than it.
     · The rhythm was loose and even: headline, gap, laptop, gap, button. Nothing was the subject,
       so the eye had nowhere to rest and the moment carried no tension.

   The redress, and none of it moves an element or changes a word:
     · The laptop is the subject, so it gets the room to be one.
     · The status line is promoted — it is the sentence that says the room is live.
     · Back is demoted to what it is, and given a real 44px target while being demoted. Quiet and
       small are different things; only one of them is a usability decision.
     · The rhythm goes tight-loose-tight so the laptop sits in held air rather than in a gap. */
/* ⛔ THE COLUMN IS .pitch-inner, NOT .pn-preroom — CORRECTED 26 Aug, same day I shipped it wrong.
   I designed this against a harness I built by hand, and my harness put the head / laptop / cta
   directly inside .pn-preroom. The real markup does not:

       .pn-preroom > .pitch-bgstrip (the giant BOARDROOM bleed)  +  .pitch-inner > (head, lap, cta)

   So the flex column was being applied one level too high: it was laying out the bleed text and
   the content block as a two-item centred column, which is not the rhythm I verified and which
   also drags the bleed off its own anchoring. The descendant rules below (headline size, the
   status line, the 44px Back) hit the right elements either way — those were and are correct.
   Only the container was wrong, and it is the container that carries the rhythm.

   This is the second time today a hand-built harness showed me my own placeholder rather than the
   component. The rule stands, in the file where it was broken: design against the real component
   or do not design. */
html body .pn-preroom .pitch-inner{
  display:flex !important; flex-direction:column !important;
  align-items:center !important; justify-content:center !important;
  gap:clamp(18px,3.2vh,34px) !important;
  min-height:min(760px,86vh) !important;
}
html body .pn-preroom .pn-preroom-head{display:grid !important; gap:10px !important; text-align:center !important}
/* the headline dominates — this is a set-piece, not a panel heading */
html body .pn-preroom .pn-preroom-h{
  font-size:clamp(30px,4.6vw,60px) !important; line-height:1.02 !important;
  letter-spacing:-.02em !important; text-wrap:balance !important; margin:0 !important;
}
html body .pn-preroom .pn-preroom-sub{
  max-width:46ch !important; margin-inline:auto !important; opacity:.82 !important;
}
/* ⛔ THE LAPTOP IS DELIBERATELY NOT TOUCHED. It looks under-sized for the subject of the beat —
   452px inside a 1105px stage — and widening it was the obvious next move. I could not VERIFY it:
   the harness I designed against stubs boardroomStage(), so the laptop collapsed to a 113px sliver
   there and I would have been judging my own placeholder. Changing the proportions of a component
   I have only seen in a screenshot is how the last three of these got broken. It needs one look at
   a real pre-roll, which needs a real pitch in flight. Left alone until then, on purpose. */

/* THE FOOTER ROW — what is happening, and the way out, in that order of weight. */
html body .pn-preroom .pn-preroom-cta{
  display:flex !important; flex-direction:column !important; align-items:center !important;
  gap:clamp(12px,1.8vh,20px) !important; margin-top:0 !important;
}
html body .pn-preroom .pn-preroom-connect{
  font-size:12.5px !important; letter-spacing:.18em !important; opacity:1 !important;
}
/* ⛔ 44px, AND STILL SECONDARY. The escape hatch does not get to be the loudest thing on a screen
   whose subject is a room you are walking into — but a control under the tap floor is a defect,
   not a design choice, and this project set that floor itself. */
html body .pn-preroom #bail{
  min-height:44px !important; min-width:96px !important; padding-inline:22px !important;
  opacity:.72 !important; font-size:13px !important;
}
html body .pn-preroom #bail:hover{opacity:1 !important}

@media (max-width:640px){
  html body .pn-preroom .pitch-inner{gap:clamp(14px,2.6vh,22px) !important; min-height:auto !important}
  html body .pn-preroom .pn-lap-stage{width:100% !important}
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   26 AUG · THE CLIENT NAME-PLATE STOPS SITTING ON THE ROOM'S CAPTION
   ══════════════════════════════════════════════════════════════════════════════════════════════
   Two text layers were occupying one band, measured on a real match at 1440x900:

       .pn-call-caption   635x46 @30,82     "The client settles in. Read the room."
       .pn-call-cliname   135x42 @44,84     "Peltwyn Collective / THE CLIENT"

   The name-plate sits INSIDE the caption's box, so the client's name renders as a ghost behind the
   room's read-out line. Nobody introduced a bug: `.pn-call-cliname` is `position:absolute; top:13px`
   anchored to the STAGE (style-01 ~845), written when the caption was an overlay too. The 20 Aug
   pass above turned `.pn-call-caption` into a `position:static` flex item at the top of that same
   stage — so the caption moved into the band the name-plate had always occupied, and the collision
   arrived without either rule changing again.

   ⛔ ANCHORED TO THE BOTTOM, NOT NUDGED DOWN BY THE CAPTION'S HEIGHT. Offsetting `top` by the
   caption's height would work today and break the first time the caption runs to two lines, which
   it will — its text is generated per beat. Bottom-left is also where a name-plate belongs on a
   video feed, so the fix is the idiom rather than an arithmetic patch on a moving number. */
html body .pn-call-stage .pn-call-cliname{
  top: auto !important;
  bottom: 14px !important;
  left: 14px !important;
}

/* ══ PN-M20 · THE WAY OUT OF THE VERDICT IS NOT A WIDTH ═══════════════════════════════════════
   CEO, 2026-09-20: the verdict page needs a scroll to reach its button.

   An anchored foot already existed — style-01.css:740 makes .result-actions sticky with an opaque
   plate and a hard top rule, and pn-touch §PN-M18 spent a block getting it flush. Both live inside
   `@media (max-width:900px)`, and the CEO plays on an iPad at 1194–1338px: the screen every pitch
   ends on had no anchored exit on the only device it is tested on. Same shape as the casing rule,
   the client catch, the log reader, the button gate and the card wildcard — a RANGE written where
   the real condition is a FACT.

   MEASURED on the booted game, one resolved pitch, "Back to the floor →" the only control, BEFORE
   this block:
     1338×1000   18px over    visible (the one size it nearly fit)
     1194× 834  174px over    107px below the fold
     1180× 820  187px over    120px below
     1024× 768  758px over    691px below
      390× 844  771px over    162px below
   AFTER it: 1338 fits outright, 1194 and 1180 reach the exit without scrolling.

   ⛔ WHAT IS STILL BROKEN, AND WHY IT IS NOT FIXED HERE. 1024×768 and 390×844 still put the exit
   below the fold, and this block cannot reach them. `position:sticky` is bounded by the element's
   PARENT, and at those two widths the layout stacks: .result-actions becomes the FIRST child of
   .rz-col--r, and that column itself starts 727px (1024) and 891px (390) down the scroll — so the
   bar is already below the fold before stickiness has anything to act on. It pins correctly once
   you have scrolled to it, which is the thing being complained about.

   The obvious answer, position:fixed, was TRIED AND MEASURED AND DOES NOT WORK HERE: pn-ipad-shell
   sets transform:translateZ(0) on body.pn-folio, and a transformed ancestor becomes the containing
   block for fixed descendants, so the bar resolves against the internally-scrolled body box rather
   than the viewport. Measured it land at y=1300 in a 768px viewport. (The same trap is documented
   in pn-wahwahs.js, which portals its room to <html> to escape it.)

   The real fix is to move .result-actions out of .rz-col--r in resultPageHTML so the bar belongs
   to the scene rather than to a column — a markup change that re-cuts the grid areas at
   style-01.css:1181, which is not something to do unattended at two in the morning on the screen
   every pitch ends on. Logged open on the board with these numbers. */
@media (min-width:901px){
  html body[data-view="result"] .pn-rz .rz-col--r .result-actions{
    position:sticky !important; bottom:0; z-index:6;
    margin-top:auto !important;
    padding:12px 0 calc(12px + env(safe-area-inset-bottom,0px)) !important;
    background:#070c15;
    border-top:1px solid rgba(255,255,255,.14);
    box-shadow:0 -14px 28px rgba(4,7,12,.55);
  }
  /* The scroller's bottom padding sits INSIDE the sticky constraint rectangle, so bottom:0 means
     "that padding up" and the bar floats with a strip of ledger visible beneath it. pn-touch
     §PN-M18 measured that as 41px on a phone and deleted it; the same 40px is here at every other
     width, so it goes the same way. */
  html body[data-view="result"] .result-screen{ padding-bottom:0 !important; }
}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   THE FOUNDING FLOW, 2026-09-22 — CEO: "Bad typ on this screen, more typos, text too small,
   sliders are weak design- input text bok invisible".

   All of this is one fault wearing four hats. These screens were designed for the CREAM porcelain
   card and later re-themed dark by overriding COLOURS only — so every value that was chosen
   against a pale ground (a 13%-opacity navy track, a white input, a 10px label at 74% ink) was
   left exactly as it was and simply stopped working. Re-inking is not re-designing.
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── THE SLIDERS. A 6px groove whose unfilled half is rgba(11,28,48,.13) — dark navy at thirteen
      per cent, on a dark card. It is not a weak design so much as an absent one: on this ground
      there is nothing to see but the thumb, so there is no sense of a RANGE, which is the entire
      job of a slider. Give it a real groove, a fill that reads as a level, and a thumb big enough
      to look draggable. */
html body .onb-card .onb-slider-row input[type=range]{
  height: 10px !important;
  background: linear-gradient(to right,
    #FF8A3D var(--pct,50%), rgba(233,240,251,.34) var(--pct,50%)) !important;
  box-shadow: inset 0 0 0 1px rgba(233,240,251,.42) !important;
}
html body .onb-card .onb-slider-row input[type=range]::-webkit-slider-thumb{
  width: 24px !important; height: 24px !important;
  background: radial-gradient(circle at center,#0b1c30 0 3.5px,#fff 4.6px) !important;
  border: 3px solid #FF8A3D !important;
  box-shadow: 0 2px 8px rgba(0,0,0,.55) !important;
  margin-top: -7px !important;
}
html body .onb-card .onb-slider-row input[type=range]::-moz-range-thumb{
  width: 24px !important; height: 24px !important;
  background: radial-gradient(circle at center,#0b1c30 0 3.5px,#fff 4.6px) !important;
  border: 3px solid #FF8A3D !important;
  box-shadow: 0 2px 8px rgba(0,0,0,.55) !important;
}
/* room to breathe: four of these stacked with 6px gaps read as one grey mass */
html body .onb-card .onb-slider-row{ margin: 0 0 26px !important; }
html body .onb-card .onb-slider-row:last-child{ margin-bottom: 0 !important; }

/* ── THE TYPE. 10px and 10.5px labels set in italic at 66–72% ink. That is a caption size doing a
      label's job, and the CEO reads this on a laptop, not through a loupe. */
html body .onb-card .onb-slider-name{
  font-size: 12.5px !important; letter-spacing: .12em !important;
  margin-bottom: 10px !important; color: #FFFFFF !important;
}
html body .onb-card .onb-slider-labels{
  font-size: 13px !important; font-style: normal !important;
  margin-top: 10px !important; color: rgba(237,241,250,.80) !important;
}
html body .onb-card .onb-body{
  font-size: 16.5px !important; line-height: 1.62 !important;
  max-width: 62ch !important; color: rgba(237,241,250,.86) !important;
}

/* ── THE INPUT BOX. ⛔ MY FIRST EXPLANATION OF THIS WAS WRONG AND IS CORRECTED HERE. I wrote that
      it was `background:#fff` from the porcelain design under near-white text — white ink in a
      white box. Then I measured it. The ground had already been re-themed by another sheet to
      rgba(4,7,12,.5), and the typed text on it clears comfortably. What is actually invisible is
      the BOX: its border computes to rgba(255,255,255,.16), which is 1.57:1 against the card, and
      its placeholder sits at 40% opacity. So "input text bok invisible" is exactly right and
      exactly literal — you cannot see where to type, and the prompt telling you what to type is
      barely there. The typing itself was never the problem. */
html body .onb-card .onb-addl{
  background: rgba(233,240,251,.07) !important;
  border: 1px solid rgba(233,240,251,.34) !important;
  border-radius: 8px !important;
  color: #FFFFFF !important;
  font-size: 15.5px !important;
  padding: 14px 16px !important;
  min-height: 84px !important;
}
html body .onb-card .onb-addl::placeholder{ color: rgba(237,241,250,.62) !important; opacity: 1 !important; }
html body .onb-card .onb-addl:focus{
  border-color: #FF8A3D !important;
  background: rgba(233,240,251,.11) !important;
  box-shadow: 0 0 0 3px rgba(255,138,61,.24) !important;
}

/* ── "YOU'RE IN." — the backing note and the founding form, 2026-09-22.
      CEO: "a) page is ugly b) why cant I progress?"

      The note was a .glass-panel (a LIGHT-theme surface) carrying color:var(--ink,#0b1c30) on a
      screen where --ink is not defined — so the fallback applied and printed near-black navy on a
      pale grey slab in the middle of a dark page. It is the payoff of the whole interview and it
      looked like a system message that had wandered in from another product.

      Her verdict now sits on the page's own ground, the cheque is the loud number it has earned,
      and the accent is spent once. */
html body .onb-card .onb-backed{
  margin: 18px 0 28px; padding: 20px 22px;
  border: 1px solid rgba(255,138,61,.34); border-radius: 12px;
  background: linear-gradient(168deg, rgba(255,138,61,.10), rgba(255,138,61,.03) 62%, transparent);
}
html body .onb-card .onb-backed-line{
  margin: 0; font-size: 17px; line-height: 1.5; color: rgba(237,241,250,.88);
}
html body .onb-card .onb-backed-line b{ color: #FFFFFF; font-weight: 700; }
html body .onb-card .onb-backed-prob{
  display: inline-block; margin-left: 8px; padding: 2px 9px; border-radius: 999px;
  border: 1px solid rgba(255,186,120,.5); background: rgba(255,186,120,.12);
  font: 700 10.5px/1.6 ui-monospace,"JetBrains Mono",monospace; letter-spacing: .12em;
  text-transform: uppercase; color: #FFCFA0; vertical-align: 2px;
}
/* the number is the moment — it is the one thing on this screen she actually gave you */
html body .onb-card .onb-backed-cheque{
  display: flex; align-items: baseline; gap: 12px; margin: 14px 0 12px;
}
html body .onb-card .onb-backed-cheque span{
  font: 700 10.5px/1 ui-monospace,"JetBrains Mono",monospace; letter-spacing: .18em;
  text-transform: uppercase; color: #FF8A3D;
}
html body .onb-card .onb-backed-cheque b{
  font-size: clamp(30px,3.4vw,42px); line-height: 1; letter-spacing: -.02em; color: #FFFFFF;
  font-variant-numeric: tabular-nums;
}
html body .onb-card .onb-backed-note{
  margin: 0; font-size: 14.5px; line-height: 1.6; color: rgba(237,241,250,.72);
}

/* ── the form. Four stacked full-width boxes with no rhythm is a queue, not a layout. */
html body .onb-card .grid > div{ margin-bottom: 20px; }
html body .onb-card .grid > div:last-child{ margin-bottom: 0; }
html body .onb-card .grid label.muted{
  display: block; margin-bottom: 8px;
  font-size: 12.5px !important; letter-spacing: .04em; color: rgba(237,241,250,.82) !important;
}
html body .onb-card .grid input{
  width: 100%; box-sizing: border-box; padding: 13px 15px !important;
  font-size: 16px !important;
  background: rgba(233,240,251,.06) !important;
  border: 1px solid rgba(233,240,251,.30) !important;
  border-radius: 9px !important; color: #FFFFFF !important;
}
html body .onb-card .grid input::placeholder{ color: rgba(237,241,250,.46) !important; opacity: 1; }
html body .onb-card .grid input:focus{
  outline: none; border-color: #FF8A3D !important;
  box-shadow: 0 0 0 3px rgba(255,138,61,.22) !important;
  background: rgba(233,240,251,.10) !important;
}
html body .onb-card .onb-hint{
  display: block; margin-top: 7px; font-size: 12.5px; line-height: 1.5;
  color: rgba(237,241,250,.60);
}
html body .onb-card .onb-confirm-city{
  padding: 13px 15px; border-radius: 9px;
  border: 1px solid rgba(233,240,251,.22); background: rgba(233,240,251,.04);
  font-size: 16px; color: #FFFFFF;
}
/* ⛔ A DISABLED BUTTON MUST LOOK DISABLED. The CEO's screenshot shows a full-strength orange pill
   that simply does not respond — because it was disabled and nothing said so. That reads as a
   broken button, not a locked one, and it is half of why he asked why he could not progress. */
html body .onb-card .onb-actionbar .primary[disabled]{
  opacity: .42 !important; cursor: not-allowed !important; filter: saturate(.55) !important;
  box-shadow: none !important;
}

/* ── A PILLAR NOBODY BUILT LOOKS UNBUILT (2026-09-22). CEO on Pitch ready: it "always loads with
      these same low figures". Every untouched slot printed 6, the same number a pillar that WAS
      worked on and went badly prints — so the deck could not tell you which of the two had
      happened, and that is the one thing it exists to tell you. It shows an em-dash now, and it
      is drawn as absent rather than as weak: an empty track, no tier colour, nothing claiming a
      score it never earned. */
html body .pnr-pill.is-untouched{
  opacity: .72;
  border-style: dashed !important;
  border-color: rgba(233,240,251,.26) !important;
  background: transparent !important;
}
html body .pnr-pill.is-untouched .pnr-q{
  color: rgba(237,241,250,.52) !important; font-variant-numeric: normal;
}
html body .pnr-pill.is-untouched i > u{ background: rgba(233,240,251,.14) !important; }
html body .pnr-seam-ticks i.is-untouched{ opacity: .3; }
