/* ══════════════════════════════════════════════════════════════════════════════════════════════
   PN-TEARSHEET-POPUPS — "B everywhere for pop ups" (CEO decision, 2026-09-27, verbatim)
   ══════════════════════════════════════════════════════════════════════════════════════════════
   CEO picked Direction B ("TEAR-SHEET") off the decision board (scratchpad/directions/DIRECTIONS.md)
   for EVERY pop-up / modal / dialog in the game: full-saturation flat colour blocks per module
   type, no card chrome (the colour block IS the card), a halftone-dot corner as the only texture,
   a bordered mono "tab" eyebrow, giant Inter 900 numerals printed directly on the field.

   HEADLINE FACE — CORRECTED 2026-09-27, same day, mid-build: the CEO's first ruling approved
   Bodoni Moda 900 italic (B's stated "risk" type call). A later message overruled it verbatim:
   "Option B but never use those Serif fonts" — remove Bodoni Moda (and any other serif) from the
   pop-up system entirely, and use B's own DOCUMENTED FALLBACK instead: "Bodoni swaps back to
   Inter 900 italic caps (the existing PROMO treatment) with zero other changes." That fallback is
   what ships here. No serif @font-face, no serif font file, is referenced anywhere in this file.
   Every headline in this system is INTER 900 ITALIC, UPPERCASE, tight tracking — already
   self-hosted by pn-type-cabinet-20260912.css (inter-900-i.woff2), so this file needs zero new
   font files and adds zero @font-face rules of its own.

   COLOUR → TYPE MAPPING (the one rule every module in this file obeys):
     ORANGE  #f97316 / near-black ink #140a04  → celebration · progress · welcome
             (showIntro WELCOME, showWelcomeBack WELCOME BACK, promotions/SUPER-AGENCY/
              SUPER-CLIENT, the Pilot Season welcome, the Vault's PAID receipt)
     COBALT  #1e3a8a / paper ink #f8f9ff       → information · reports · guide
             (the week summary, "The report", the Guide window, the Vault shop sheets, the
              Desk's neutral/informational cards, the tour tip, the rung tips, the feedback
              panel header — all "here's what's true" surfaces)
     YELLOW  #fbbf24 / near-black ink #140a04  → warning · a decision needed · money-short
             (every pnConfirm two-button decision incl. the CFO's offer, the Vault's "you're
              short on WahCoins" banner, the Desk's caution/hazard cards)
   Every text colour below was chosen to clear WCAG AA (4.5:1 body, 3:1 large) against the block
   it sits on — see the contrast table in the hand-back report, measured from the rendered pages,
   not guessed from the hex values.

   SUPERSEDES: the bigmodal/welcome portions of pn-popup-legibility-20260927.css and
   pn-blockcolour-20260927.css. This file is loaded AFTER both (last stylesheet link in play.html,
   just before </body>) and every selector below carries the `html:not(#pn-tsb-x) body …` ID-level
   bump those two files use for their own sweeps, so it wins on specificity as well as source
   order wherever `pn-ds.css`'s own `:not(#pn-ds-never)` sweeps, or those two files, try to repaint
   the same element.

   SCOPE — every pop-up in the game, one system:
     1 · #toast.bigmodal.bigmodal (.bigmodal-card) — showIntro, showWelcomeBack, promotions, "the report",
         the week summary (rendered inline, not via #toast, but same .bigmodal-card component),
         every pnConfirm (incl. the CFO's desk offer).
     2 · #pnps-welcome — the Pilot Season welcome. Neon hero image + live countdown clock left
         exactly as pn-pilot-season.js and its CSS built them; only the card's colour field, ink,
         border and headline face are restyled around them.
     3 · #vv-ov — the Vault (Top up, Basket, item detail, receipt).
     4 · .pno-card.pno-card — the tour coachmark (pn-onboarding.js).
     5 · #pnGd-root — the Guide window.
     6 · .pnfc-scrim / .pnfc-win.pnfc-win — the Desk / urgency pop-over.
     7 · .pnsp-tip — the rung tips.
     8 · #pnfb-panel .pnfb-head — the feedback chat panel's header only (its body is untouched,
         owned elsewhere).
   NOT touched (explicitly out of scope, per brief): pn-pitch2.js's beat windows (in-scene, not
   pop-ups), #pn-pub (Duff's, just redesigned).
   ══════════════════════════════════════════════════════════════════════════════════════════════ */

:root{
  --tsb-line:      #0b1c30;             /* the one ink border colour every block shares */
  /* SOLID tokens — for border-color / box-shadow / currentColor contexts, where a gradient value
     is invalid CSS. Orange is now reserved for buttons/CTAs only (CEO ruling, 2026-09-27 round 3)
     — it never fills a pop-up body any more, but the solid stays because buttons still use it. */
  --tsb-orange:    #f97316; --tsb-orange-ink:#140a04; --tsb-orange-dim:rgba(20,10,4,.74);
  --tsb-cobalt:    #1e3a8a; --tsb-cobalt-ink:#f8f9ff; --tsb-cobalt-dim:rgba(248,249,255,.80);
  --tsb-yellow:    #fbbf24; --tsb-yellow-ink:#140a04; --tsb-yellow-dim:rgba(20,10,4,.74);
  /* MEASURED: the CEO's lighter gradient stop (#1fa37a) only clears 3.2:1 against white text —
     below AA (4.5:1) for body copy. The SOLID/fallback token (background-color, read whenever the
     gradient image can't paint — forced-colors, print, or any tool that only reads backgroundColor)
     uses the darker stop instead, which clears 7.5:1; the lighter stop stays in the gradient IMAGE
     as the top highlight only, kept tight so running text never sits inside it. */
  --tsb-emerald:   #0b5e45; --tsb-emerald-ink:#f0fdf6; --tsb-emerald-dim:rgba(240,253,246,.82);
  /* GRADIENT fills — a rich two-stop linear ramp + a soft radial highlight top-left, per the CEO's
     "flat is AI-weak, give it depth" ruling. These are what every block BACKGROUND uses now; the
     solid tokens above are untouched so shadows/borders/currentColor stay a clean flat colour. */
  --tsb-orange-fill: radial-gradient(120% 140% at 14% -14%, rgba(255,255,255,.38) 0%, transparent 42%),
                     linear-gradient(160deg, #ff8a1f 0%, #e4560b 100%);
  --tsb-cobalt-fill: radial-gradient(120% 140% at 14% -14%, rgba(255,255,255,.16) 0%, transparent 42%),
                     linear-gradient(160deg, #2a4fc4 0%, #12245e 100%);
  --tsb-yellow-fill: radial-gradient(120% 140% at 14% -14%, rgba(255,255,255,.5) 0%, transparent 42%),
                     linear-gradient(160deg, #ffd24a 0%, #f0a500 100%);
  --tsb-emerald-fill:radial-gradient(120% 140% at 14% -14%, rgba(255,255,255,.16) 0%, transparent 38%),
                     linear-gradient(160deg, #158564 0%, #0b5e45 100%);
  /* a repeating SVG feTurbulence grain, tiny + cheap, 8% opacity per the depth ruling */
  --tsb-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --tsb-face-display: 'Inter', system-ui, sans-serif;   /* NEVER a serif — CEO ruling, verbatim */
  --tsb-face-mono:    'JetBrains Mono', ui-monospace, monospace;
  --tsb-face-sans:    'Instrument Sans', 'Inter', system-ui, sans-serif;
}

/* shared building blocks, reused by every popup family below */
.tsb-halftone{ position:absolute; top:0; right:0; width:150px; height:150px; pointer-events:none;
  background-image:radial-gradient(currentColor 1.6px, transparent 1.6px); background-size:9px 9px; opacity:.14; z-index:0; }
.tsb-tab{ display:inline-block; font:700 10.5px/1 var(--tsb-face-mono); letter-spacing:.16em; text-transform:uppercase;
  padding:5px 9px; border:2px solid currentColor; border-radius:2px; }
.tsb-headline{ font-family:var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important;
  text-transform:uppercase !important; letter-spacing:-.01em !important; text-wrap:balance; }

/* the shared TEXTURE + DEPTH mixin — grain overlay, an inner top highlight (a light surface catching
   a lamp from above, not a flat sticker) and a layered shadow (contact + ambient), applied to every
   saturated block via one class so the recipe never drifts between popup families. */
.tsb-textured{ position:relative; isolation:isolate; }
.tsb-textured::before{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:0;
  background-image: var(--tsb-grain); background-size:120px 120px; opacity:.08; mix-blend-mode:overlay;
}
.tsb-textured::after{
  content:""; position:absolute; inset:0 0 auto 0; height:46%; pointer-events:none; z-index:0;
  background:linear-gradient(180deg, rgba(255,255,255,.16) 0%, transparent 100%);
}
.tsb-textured > *{ position:relative; z-index:1; }
.tsb-shadow-deep{ box-shadow: 0 2px 0 rgba(255,255,255,.14) inset, 8px 8px 0 rgba(11,28,48,.28), 0 30px 70px rgba(0,0,0,.5), 0 4px 16px rgba(0,0,0,.35); }

/* ══ 1 · THE BIGMODAL FAMILY (#toast.bigmodal.bigmodal .bigmodal-card + the week-summary's own
        .bigmodal-card, rendered inline into #app but the same component) ═══════════════════════
   No card chrome: 3px ink frame, flat colour fill, halftone corner. Colour + ink are carried on
   CSS custom properties set once per bucket (--tsb-bg/--tsb-ink/--tsb-dim) so every descendant
   rule below reads the SAME two variables regardless of which bucket matched — one paint system,
   four buckets. Default bucket (no :has() match) is COBALT — the safe "information" default for
   any toastBig() call this file's authors didn't enumerate by name. */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card,
html:not(#pn-tsb-x) body .week-summary-screen .bigmodal-card{
  --tsb-bg: var(--tsb-cobalt); --tsb-fill: var(--tsb-cobalt-fill); --tsb-ink: var(--tsb-cobalt-ink); --tsb-dim: var(--tsb-cobalt-dim);
}
/* COBALT — welcome · welcome back (CEO round 3: "black text on blue is illegible" + "orange is
   ONLY for actions/buttons" — welcome/welcomeback move off orange entirely; white ink on cobalt). */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card:is(:has(.pn-welcome-pt.pn-welcome-pt), :has(.wb-feed)){
  --tsb-bg: var(--tsb-cobalt); --tsb-fill: var(--tsb-cobalt-fill); --tsb-ink: var(--tsb-cobalt-ink); --tsb-dim: var(--tsb-cobalt-dim);
}
/* EMERALD — celebration/progress only (promotions, SUPER-AGENCY, SUPER-CLIENT WON). Orange is
   reserved for buttons now, so "you levelled up" gets its own colour instead of inheriting orange. */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card:is(:has(.pill.good), :has(.pill[style*="accent"])){
  --tsb-bg: var(--tsb-emerald); --tsb-fill: var(--tsb-emerald-fill); --tsb-ink: var(--tsb-emerald-ink); --tsb-dim: var(--tsb-emerald-dim);
}
/* YELLOW — every pnConfirm two-button decision, incl. the CFO's offer (a warning: stays yellow).
   pnConfirm's own markup is the only bigmodal family that ever prints a .pn-cf-yes button. */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card:has(.pn-cf-yes){
  --tsb-bg: var(--tsb-yellow); --tsb-fill: var(--tsb-yellow-fill); --tsb-ink: var(--tsb-yellow-ink); --tsb-dim: var(--tsb-yellow-dim);
}
/* COBALT, explicit — the week summary + "the report" (both information, not decisions) */
html:not(#pn-tsb-x) body .week-summary-screen .bigmodal-card.week-summary-inner,
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card:has(.aar-money){
  --tsb-bg: var(--tsb-cobalt); --tsb-fill: var(--tsb-cobalt-fill); --tsb-ink: var(--tsb-cobalt-ink); --tsb-dim: var(--tsb-cobalt-dim);
}

/* the paint, keyed off the variables above — one rule set for every bucket. Background is now the
   gradient FILL token (depth ruling), never the flat solid — the solid token still backs
   border/shadow/currentColor contexts elsewhere so those stay a clean flat colour. */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card,
html:not(#pn-tsb-x) body .week-summary-screen .bigmodal-card{
  background-color: var(--tsb-bg) !important; background-image: var(--tsb-fill) !important;
  color: var(--tsb-ink) !important;
  border: 3px solid var(--tsb-line) !important; border-radius: 2px !important;
  box-shadow: 0 2px 0 rgba(255,255,255,.14) inset, 8px 8px 0 rgba(11,28,48,.24), 0 30px 80px rgba(0,0,0,.55) !important;
  position: relative; overflow: hidden;
}
/* grain (feTurbulence, ~8%, overlay blend) — the depth ruling's texture pass, one shared recipe */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card::before,
html:not(#pn-tsb-x) body .week-summary-screen .bigmodal-card::before{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:0;
  background-image: var(--tsb-grain); background-size:120px 120px; opacity:.08; mix-blend-mode:overlay;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card::after,
html:not(#pn-tsb-x) body .week-summary-screen .bigmodal-card::after{
  content:""; position:absolute; top:0; right:0; width:150px; height:150px; pointer-events:none;
  background-image:radial-gradient(currentColor 1.6px, transparent 1.6px); background-size:9px 9px; opacity:.16; z-index:0;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card > *,
html:not(#pn-tsb-x) body .week-summary-screen .bigmodal-card > *{ position:relative; z-index:1; }
/* the mac-titlebar becomes the "tab" strip — bordered, not filled, sitting on the colour field */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .mac-titlebar,
html:not(#pn-tsb-x) body .week-summary-screen .mac-titlebar{
  background: transparent !important; border-bottom: 2px solid var(--tsb-ink) !important; opacity:.9;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .mac-tb-title,
html:not(#pn-tsb-x) body .week-summary-screen .mac-tb-title{
  color: var(--tsb-ink) !important; -webkit-text-fill-color: var(--tsb-ink) !important;
  font: 700 11px var(--tsb-face-mono) !important; letter-spacing:.14em !important; text-transform:uppercase !important;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .mac-tb-dot{ opacity:.55; }
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .mac-tb-dot.red{ background:var(--tsb-ink); border-color:var(--tsb-ink); }

/* every text leaf inside the card body inherits the bucket ink — nothing light-on-light, nothing
   dark-on-dark, regardless of which of the four colour fields it landed on */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body,
html:not(#pn-tsb-x) body .week-summary-screen .bigmodal-card-body.bigmodal-card-body,
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body :is(p,li,span,div,dd,dt,td,th,small,em,i,label,b,strong,h1,h2,h3,h4,.wb-title,.ws-title,.aar-rows,.aar-row){
  color: var(--tsb-ink) !important; -webkit-text-fill-color: var(--tsb-ink) !important; background-image:none !important;
}
/* MEASURED (contrast probe, see hand-back report): pn-popup-legibility-20260927.css pins
   `.wb-title` inside its own `:is(b,strong,h1,h2,h3,h4,.wb-title,.wb-stats b)` list to a fixed
   #1c130b — because that list names `.wb-title` as a CLASS token, its selector out-specifies the
   element-only list above even though both are !important and this file loads later. Naming the
   same two classes explicitly here (matching that specificity) is what makes this file actually
   win, not just come after it. */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body.bigmodal-card-body.bigmodal-card-body .wb-title,
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body.bigmodal-card-body.bigmodal-card-body .ws-title,
html:not(#pn-tsb-x) body .week-summary-screen .bigmodal-card-body.bigmodal-card-body.bigmodal-card-body.bigmodal-card-body .ws-title{
  color: var(--tsb-ink) !important; -webkit-text-fill-color: var(--tsb-ink) !important;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body :is(.muted,.small.muted,.wb-sub,.sub,.note,.ws-eyebrow,.aar-k,p.muted){
  color: var(--tsb-dim) !important; -webkit-text-fill-color: var(--tsb-dim) !important;
}
/* the real headline in each family — the same treatment wherever a headline lives */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body :is(.wb-title,.ws-title,.row > b:first-of-type),
html:not(#pn-tsb-x) body .week-summary-screen .ws-title{
  font-family: var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important;
  text-transform:uppercase !important; letter-spacing:-.01em !important; text-wrap:balance;
}
/* the eyebrow tag (WELCOME / PROMOTED / SUPER-AGENCY / TICK IT OFF / …) becomes the bordered tab */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body :is(.pill, .tac-eyebrow, .ws-eyebrow){
  font: 700 10.5px/1 var(--tsb-face-mono) !important; letter-spacing:.16em !important; text-transform:uppercase !important;
  padding:5px 9px !important; border:2px solid var(--tsb-ink) !important; border-radius:2px !important;
  background:transparent !important; color:var(--tsb-ink) !important; -webkit-text-fill-color:var(--tsb-ink) !important;
  display:inline-block;
}
/* good/bad pills keep their own semantic chip so a win/loss never reads as neutral, but repainted
   as solid ink chips so they read on any of the four fields */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body .pill.good{
  background:#14532d !important; border-color:#14532d !important; color:#dcfce7 !important; -webkit-text-fill-color:#dcfce7 !important;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body .pill.bad{
  background:#7f1d1d !important; border-color:#7f1d1d !important; color:#fee2e2 !important; -webkit-text-fill-color:#fee2e2 !important;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body .pill.warn,
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body .pill[style*="accent"]{
  background:var(--tsb-ink) !important; border-color:var(--tsb-ink) !important; color:var(--tsb-bg) !important; -webkit-text-fill-color:var(--tsb-bg) !important;
}
/* the welcome's numbered points — ink discs on the colour field, no separate chrome.
   MEASURED: `<i>` is also a member of the broad ink-colour :is() list two rules up, and that
   rule's own doubled-class specificity out-ranked a single-doubled `.pn-welcome-pt` chain here
   (5 classes vs 4) — the disc's number rendered white-on-white. `:is(.pn-welcome-pt,
   .pn-welcome-pt)` repeated as its own compound pushes this rule's class count to 6, so it wins
   outright rather than by a coin-flip of tie-breaking. */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card-body.bigmodal-card-body :is(.pn-welcome-pt.pn-welcome-pt) > i{
  background: var(--tsb-ink) !important; color: var(--tsb-bg) !important; -webkit-text-fill-color: var(--tsb-bg) !important;
  border-radius:2px !important;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .wb-feed li{
  background: color-mix(in srgb, var(--tsb-ink) 8%, var(--tsb-bg)) !important; border-color: var(--tsb-ink) !important;
  color: var(--tsb-ink) !important; -webkit-text-fill-color: var(--tsb-ink) !important;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .wb-feed li::before{ color: var(--tsb-ink) !important; }
/* CEO review (contact sheet round 1): body copy on the orange (welcome/welcomeback/promoted
   bucket) read tiny against the block. Floor every text leaf in that bucket at 15px minimum —
   the field is loud, the words carry it, they were never meant to whisper. */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card:is(:has(.pn-welcome-pt.pn-welcome-pt), :has(.wb-feed), :has(.pill.good), :has(.pill[style*="accent"]))
  .bigmodal-card-body.bigmodal-card-body :is(p, li, .small, .wb-sub){
  font-size: 15px !important; line-height: 1.5 !important;
}
/* the ledger rows / meters inside the week summary get ink-on-field rules, not the old dark card */
html:not(#pn-tsb-x) body .week-summary-screen :is(.wsl-k,.wsl-fig,.wsl-cap,.wsl-v,.wsl-d,.wsl-nm,.wsl-attr,.wsl-word,.wsl-word.wsl-word p){
  color: var(--tsb-ink) !important; -webkit-text-fill-color: var(--tsb-ink) !important;
}
html:not(#pn-tsb-x) body .week-summary-screen .wsl-word::before{ background: var(--tsb-ink) !important; }
html:not(#pn-tsb-x) body .week-summary-screen .wsl-trk{ background: color-mix(in srgb, var(--tsb-ink) 16%, transparent) !important; }
html:not(#pn-tsb-x) body .week-summary-screen .wsl-trk i{
  background: linear-gradient(90deg, color-mix(in srgb, var(--tsb-ink) 68%, transparent), var(--tsb-ink)) !important;
  box-shadow: 0 0 10px color-mix(in srgb, var(--tsb-ink) 55%, transparent);
}
html:not(#pn-tsb-x) body .week-summary-screen .wsl-sec{ border-color: color-mix(in srgb, var(--tsb-ink) 24%, transparent) !important; color: var(--tsb-ink) !important; }

/* the foot — a flush ink-bordered strip, buttons in ink-on-field / outline-on-field */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-foot.bigmodal-foot,
html:not(#pn-tsb-x) body .week-summary-screen .bigmodal-foot.bigmodal-foot{
  border-top: 2px solid var(--tsb-ink) !important; background:transparent !important;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-foot.bigmodal-foot :is(button.primary,.pn-btn--primary,.pn-cf-yes,.ws-cta){
  background: var(--tsb-ink) !important; background-image:none !important; color: var(--tsb-bg) !important; -webkit-text-fill-color: var(--tsb-bg) !important;
  border: 2px solid var(--tsb-ink) !important; border-radius:2px !important;
}
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-foot.bigmodal-foot :is(.pn-btn--ghost,.pn-cf-no,.pn-btn--secondary){
  background: transparent !important; color: var(--tsb-ink) !important; -webkit-text-fill-color: var(--tsb-ink) !important;
  border: 2px solid var(--tsb-ink) !important; border-radius:2px !important;
}

/* ══ 2 · THE PILOT SEASON WELCOME (#pnps-welcome) ═══════════════════════════════════════════════
   Neon hero image + live clock kept exactly as pn-pilot-season.js / pn-pilot-season-20260927.css
   built them — only the card field/ink/border/headline change, via the same custom properties the
   existing file already reads (--pw-bg/--pw-ink/--pw-muted/--pw-accent/--pw-accent-ink/--pw-line).
   CEO round 3: welcome surfaces move OFF orange entirely (orange is buttons/CTAs only now) — this
   is COBALT with white ink; the "Start playing" CTA stays orange because it IS a button. */
html:not(#pn-tsb-x) body #pnps-welcome{
  --pw-bg: var(--tsb-cobalt-fill) !important;   /* consumed as background-image below, not the shorthand */
  /* --pw-ink deliberately NOT overridden: the base file's own default (#0b1c30, navy) is what the
     clock-unit chip background AND the CTA's border/shadow read — those want to stay a dark navy
     chip regardless of the card's own field colour, matching --tsb-line exactly. Text colour on
     the cobalt field is handled by the explicit rules below instead of riding this variable. */
  --pw-muted: var(--tsb-cobalt-dim) !important;
  --pw-line: var(--tsb-line) !important;
  --pw-accent: var(--tsb-orange) !important;       /* the CTA button only — the one orange left */
  --pw-accent-ink: var(--tsb-orange-ink) !important;
}
html:not(#pn-tsb-x) body #pnps-welcome .pnps-pts b{
  color: var(--tsb-cobalt-ink) !important;
}
html:not(#pn-tsb-x) body #pnps-welcome .pnps-welcome-card.pnps-welcome-card{
  background-color: var(--tsb-cobalt) !important; background-image: var(--pw-bg) !important;
  border-width:3px !important; border-radius:2px !important; position:relative; overflow:hidden;
  box-shadow: 0 2px 0 rgba(255,255,255,.14) inset, 10px 10px 0 var(--tsb-line), 24px 24px 60px rgba(0,0,0,.4) !important;
}
html:not(#pn-tsb-x) body #pnps-welcome .pnps-welcome-card.pnps-welcome-card::before{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:0;
  background-image: var(--tsb-grain); background-size:120px 120px; opacity:.07; mix-blend-mode:overlay;
}
/* MEASURED: this rule's own `position:relative` — meant only to lift real content above the grain
   ::before layer — was ALSO landing on `.pnps-welcome-x` (a direct child too), overwriting its own
   `position:absolute` and turning its top/right offsets into a RELATIVE nudge instead of a
   top-right dock, so Close rendered adrift mid-card. Excluded explicitly. */
html:not(#pn-tsb-x) body #pnps-welcome .pnps-welcome-card.pnps-welcome-card > :not(.pnps-welcome-x){ position:relative; z-index:1; }
/* the tab eyebrow — white-on-cobalt (was navy-on-orange; navy-on-navy would vanish here) */
html:not(#pn-tsb-x) body #pnps-welcome .pnps-hdr-eyebrow{
  background: transparent !important; border-color: var(--tsb-cobalt-ink) !important;
  color: var(--tsb-cobalt-ink) !important; -webkit-text-fill-color: var(--tsb-cobalt-ink) !important;
}
html:not(#pn-tsb-x) body #pnps-welcome-h{
  font-family: var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important;
  text-transform:uppercase !important; color: var(--tsb-cobalt-ink) !important;
}
/* primary CTA: the one orange surface left, dark ink label (via --pw-accent/--pw-accent-ink above) */
html:not(#pn-tsb-x) body #pnps-welcome .pnps-welcome-actions .pn-btn--primary{
  color: var(--pw-accent-ink) !important; -webkit-text-fill-color: var(--pw-accent-ink) !important;
}
html:not(#pn-tsb-x) body #pnps-welcome .pnps-welcome-actions .pn-btn--secondary{
  border-color: var(--tsb-cobalt-ink) !important; color: var(--tsb-cobalt-ink) !important; -webkit-text-fill-color: var(--tsb-cobalt-ink) !important;
}
/* the CSS fallback face (only paints if the hero image 404s) — was Archivo Black italic; the
   fallback headline face is Inter, same house rule as everywhere else in this file */
html:not(#pn-tsb-x) body .pnps-welcome-hero--fallback::before{
  font-family: var(--tsb-face-display) !important; font-style:italic !important; color: var(--tsb-line) !important;
  text-shadow:none !important;
}
html:not(#pn-tsb-x) body .pnps-welcome-hero--fallback::after{ transform:none !important; }

/* ══ 3 · THE VAULT (#vv-ov) — Top up, Basket, item detail, receipt ══════════════════════════════
   Shop sheets are INFORMATION (cobalt); the receipt is PAPER (CEO round 3: orange is buttons
   only now, so the till slip is paper, not a colour block); a "short on WahCoins" banner is the
   one WARNING moment (yellow). Scoped tightly to `#vv-ov .vv-win.vv-win` so the shared `.lg-panel`
   family used by dozens of OTHER windows this brief does not touch is never repainted. */
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win{
  background-color: var(--tsb-cobalt) !important; background-image: var(--tsb-cobalt-fill) !important;
  color: var(--tsb-cobalt-ink) !important;
  border: 3px solid var(--tsb-line) !important; border-radius:2px !important;
  box-shadow: 0 2px 0 rgba(255,255,255,.14) inset, 8px 8px 0 rgba(11,28,48,.24), 0 30px 80px rgba(0,0,0,.55) !important;
  position:relative; overflow:hidden;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win::before{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:0;
  background-image: var(--tsb-grain); background-size:120px 120px; opacity:.08; mix-blend-mode:overlay;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win > :not(.vv-paid){ position:relative; z-index:1; }
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .lg-titlebar{ background:transparent !important; border-bottom:2px solid var(--tsb-cobalt-ink) !important; }
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .lg-tb-title{ color: var(--tsb-cobalt-ink) !important; font:700 11px var(--tsb-face-mono) !important; letter-spacing:.14em !important; text-transform:uppercase !important; }
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win :is(.vv-mast, .vv-eye, .vv-line, .vv-line-body, .vv-line-name, .vv-line-tag, .vv-line-where,
  .vv-empty, .vv-pack, .vv-pack-coins, .vv-pack-tier, .pn-pro-k, .pn-pro-v, .pn-pro-prize, .pn-pro-honest, dd, dt){
  color: var(--tsb-cobalt-ink) !important; -webkit-text-fill-color: var(--tsb-cobalt-ink) !important;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-eye{
  font: 700 10.5px/1 var(--tsb-face-mono) !important; letter-spacing:.16em !important; text-transform:uppercase !important;
  border:2px solid var(--tsb-cobalt-ink) !important; padding:5px 9px !important; border-radius:2px !important; display:inline-block;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-mast h2{
  font-family: var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important;
  text-transform:uppercase !important; color: var(--tsb-cobalt-ink) !important;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-line{ border-color: color-mix(in srgb, var(--tsb-cobalt-ink) 26%, transparent) !important; }
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-line-price{ color: var(--tsb-cobalt-ink) !important; }
/* MEASURED: pn-ds.css's button reset pairs `color` with a separate `-webkit-text-fill-color`
   (a gradient-text trick elsewhere in the shell) — overriding only `color` left the label
   painted in the OLD fill colour (white), invisible on the new white button face. Both channels,
   every time, or the label vanishes even though `color` itself is correct. */
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .lg-btn--primary{
  background: var(--tsb-orange) !important; background-image:none !important;
  color: #140a04 !important; -webkit-text-fill-color: #140a04 !important;
  border-color: var(--tsb-line) !important; border-radius:2px !important;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .lg-btn--secondary, html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .lg-btn--ghost{
  background:transparent !important; color: var(--tsb-cobalt-ink) !important; -webkit-text-fill-color: var(--tsb-cobalt-ink) !important;
  border:2px solid var(--tsb-cobalt-ink) !important; border-radius:2px !important;
}
/* the short-on-WahCoins banner — the one warning moment inside the shop */
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-short{
  background-color: var(--tsb-yellow) !important; background-image: var(--tsb-yellow-fill) !important; color: var(--tsb-yellow-ink) !important; -webkit-text-fill-color: var(--tsb-yellow-ink) !important;
  border: 2px solid var(--tsb-line) !important; border-radius:2px !important; padding:12px 14px !important; display:block !important;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-short button{ background: var(--tsb-line) !important; color:#f8f9ff !important; border-color: var(--tsb-line) !important; }
/* the receipt — PAPER (CEO round 3: receipt moves off orange too; a till slip reads as paper,
   not a celebration block). Dark ink on a warm cream stock; the "Wear it now" CTA stays orange
   because it is the one button on the slip. */
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-receipt{
  background: #f6f2e8 !important; color: #201408 !important;
  border: 3px solid var(--tsb-line) !important; border-radius:2px !important; padding:22px !important;
  position:relative; overflow:hidden;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-receipt::before{
  content:""; position:absolute; inset:0; pointer-events:none; z-index:0;
  background-image: var(--tsb-grain); background-size:120px 120px; opacity:.09; mix-blend-mode:multiply;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-receipt > :not(.vv-paid){ position:relative; z-index:1; }
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-receipt :is(.vv-mast, .vv-mast h2, .vv-mast p, .vv-eye, .vv-totals span, .vv-totals i,
  .vv-thanks, .vv-line, .vv-line-name, .vv-line-tag, .vv-line-price, .vv-simbadge){
  color: #201408 !important; -webkit-text-fill-color: #201408 !important;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-receipt .vv-mast h2{
  font-family: var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important; text-transform:uppercase !important;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-receipt .vv-paid{
  background: var(--tsb-line) !important; color:#f8f9ff !important; border-color: var(--tsb-line) !important;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-receipt .vv-rule{ background: rgba(32,20,8,.22) !important; }
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-receipt .lg-btn--primary{
  background: var(--tsb-orange) !important; background-image:none !important;
  color:#140a04 !important; -webkit-text-fill-color:#140a04 !important; border-color: var(--tsb-line) !important;
}
html:not(#pn-tsb-x) body #vv-ov .vv-win.vv-win .vv-receipt .lg-btn--ghost{
  background:transparent !important; color: #201408 !important; -webkit-text-fill-color: #201408 !important;
  border:2px solid #201408 !important;
}

/* ══ 4 · THE TOUR TIP (.pno-card.pno-card) — a compact coachmark ══════════════════════════════════════════
   CEO review (contact sheet round 1): a cobalt tip pinned itself on top of a cobalt week-summary
   card and vanished into it — blue-on-blue, no separating edge. The tour walks a player over EVERY
   screen in the game, including every one of B's own saturated blocks, so its card cannot commit
   to any of the three module colours without eventually landing on itself. It gets B's fourth,
   neutral surface instead — the PAPER ground the direction's own spec calls out ("Ground #edeff6
   — neutral, so the blocks read as pinned objects, not wallpaper") — with the orange tab as its
   one accent. Paper-on-anything always separates. */
html:not(#pn-tsb-x) body .pno-card.pno-card{
  background: #f6f2e8 !important; background-image:none !important;
  color: #201408 !important;
  border: 3px solid var(--tsb-line) !important; border-radius: 2px !important;
  box-shadow: 6px 6px 0 var(--tsb-orange), 0 24px 60px rgba(0,0,0,.55) !important;
  -webkit-backdrop-filter:none !important; backdrop-filter:none !important;
}
html:not(#pn-tsb-x) body .pno-card.pno-card :is(.pno-body p, .pno-body, .pno-count){
  color: #4a3b2c !important; -webkit-text-fill-color: #4a3b2c !important; font-size:15px !important; line-height:1.5 !important;
}
html:not(#pn-tsb-x) body .pno-card.pno-card :is(.pno-title, h3){
  font-family: var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important;
  text-transform:uppercase !important; color: #201408 !important; -webkit-text-fill-color: #201408 !important;
  background-image:none !important;
}
html:not(#pn-tsb-x) body .pno-card.pno-card .pno-eyebrow{
  font: 700 10.5px/1 var(--tsb-face-mono) !important; letter-spacing:.16em !important; text-transform:uppercase !important;
  border:2px solid var(--tsb-orange) !important; padding:4px 8px !important; border-radius:2px !important; display:inline-block;
  color: #9a3412 !important; -webkit-text-fill-color: #9a3412 !important;
}
html:not(#pn-tsb-x) body .pno-card.pno-card :is(.pno-skip, .pno-x){ color: #201408 !important; }
html:not(#pn-tsb-x) body .pno-card.pno-card .pno-x{ border-color: #201408 !important; background:transparent !important; }
html:not(#pn-tsb-x) body .pno-card.pno-card .pno-foot{ border-top-color: rgba(32,20,8,.18) !important; }
html:not(#pn-tsb-x) body .pno-card.pno-card .pno-dots i{ background: rgba(32,20,8,.24) !important; }
html:not(#pn-tsb-x) body .pno-card.pno-card .pno-dots i.on{ background: var(--tsb-line) !important; }
html:not(#pn-tsb-x) body .pno-card.pno-card .lg-btn--primary{
  background: var(--tsb-orange) !important; background-image:none !important;
  color:#140a04 !important; -webkit-text-fill-color:#140a04 !important; border-radius:2px !important;
}
html:not(#pn-tsb-x) body .pno-card.pno-card .lg-btn--secondary{
  background: transparent !important; color: #201408 !important; -webkit-text-fill-color: #201408 !important;
  border: 2px solid #201408 !important; border-radius:2px !important;
}

/* ══ 5 · THE GUIDE (#pnGd-root) — information bucket (cobalt) ═══════════════════════════════════
   A long-form reading window keeps a legible ground (B's own "ground vs block" distinction — the
   block is the identity device, not a forced full-page fill on running text): the title bar and
   the chapter rail become the solid cobalt "spine" (the tab/identity), the reading pane is a pale
   cobalt-tinted paper so body copy stays AA-legible at length, with the chapter headline in the
   house italic-caps face and the eyebrow as the bordered mono tab. */
html:not(#pn-tsb-x) body #pnGd-root .pnGd-win{
  border: 3px solid var(--tsb-line) !important; border-radius: 2px !important;
  box-shadow: 8px 8px 0 rgba(11,28,48,.24), 0 30px 90px rgba(0,0,0,.45) !important;
}
html:not(#pn-tsb-x) body #pnGd-root .pnGd-bar{
  background-color: var(--tsb-cobalt) !important; background-image: var(--tsb-cobalt-fill) !important; border-bottom: 2px solid var(--tsb-line) !important;
}
html:not(#pn-tsb-x) body #pnGd-root .pnGd-title{ color: var(--tsb-cobalt-ink) !important; font:700 11px var(--tsb-face-mono) !important; letter-spacing:.1em !important; text-transform:uppercase !important; }
html:not(#pn-tsb-x) body #pnGd-root .pnGd-x{ color: var(--tsb-cobalt-ink) !important; border-color: var(--tsb-cobalt-ink) !important; }
html:not(#pn-tsb-x) body #pnGd-root .pnGd-rail{
  background-color: var(--tsb-cobalt) !important; background-image: var(--tsb-cobalt-fill) !important; border-right: 2px solid var(--tsb-line) !important;
}
html:not(#pn-tsb-x) body #pnGd-root .pnGd-idxItem{ color: var(--tsb-cobalt-dim) !important; }
html:not(#pn-tsb-x) body #pnGd-root .pnGd-idxItem.is-on, html:not(#pn-tsb-x) body #pnGd-root .pnGd-idxItem[aria-selected="true"]{
  color: var(--tsb-cobalt-ink) !important; background: color-mix(in srgb, var(--tsb-cobalt-ink) 14%, transparent) !important;
}
html:not(#pn-tsb-x) body #pnGd-root .pnGd-idxH{ color: var(--tsb-cobalt-ink) !important; font-weight:800 !important; }
html:not(#pn-tsb-x) body #pnGd-root .pnGd-idxK{ color: var(--tsb-cobalt-dim) !important; }
html:not(#pn-tsb-x) body #pnGd-root .pnGd-search{ background: color-mix(in srgb, var(--tsb-cobalt-ink) 10%, transparent) !important; border-color: var(--tsb-cobalt-ink) !important; color: var(--tsb-cobalt-ink) !important; }
html:not(#pn-tsb-x) body #pnGd-root .pnGd-search::placeholder{ color: var(--tsb-cobalt-dim) !important; }
html:not(#pn-tsb-x) body #pnGd-root .pnGd-picker{ background-color: var(--tsb-cobalt) !important; background-image: var(--tsb-cobalt-fill) !important; border-bottom: 2px solid var(--tsb-line) !important; }
html:not(#pn-tsb-x) body #pnGd-root .pnGd-pickLbl, html:not(#pn-tsb-x) body #pnGd-root .pnGd-pick{ color: var(--tsb-cobalt-ink) !important; }
/* the phone chapter picker: the line above paints its text white, but its fill still came from the
   Guide's THEME token (--gd-bg) — near-white #fbfaf7 on the light theme, so the chosen chapter
   was white on white (1.01:1). Solid ink fill in both themes, and the same pair on the native
   option list so the open dropdown reads too. */
html:not(#pn-tsb-x) body #pnGd-root .pnGd-pick, html:not(#pn-tsb-x) body #pnGd-root .pnGd-pick option{
  background-color: var(--tsb-line) !important; color: var(--tsb-cobalt-ink) !important; -webkit-text-fill-color: var(--tsb-cobalt-ink) !important;
}
/* the reading pane — pale cobalt-tinted paper so long chapters stay legible. Re-declaring the
   window's own --gd-ink/--gd-muted/--gd-accent tokens HERE (not at #pnGd-root, which the bar and
   rail also read) means every existing rule in pn-guide-20260927.css that already reads those
   tokens (chapter body copy, tips, glossary, the Pilot Season header block it borrows) repaints
   correctly for a light ground with zero extra selectors — only descendants of .pnGd-read see
   these values; the cobalt bar/rail siblings keep the dark-theme pair untouched. */
html:not(#pn-tsb-x) body #pnGd-root .pnGd-read{
  background: #eef1f9 !important;
  --gd-bg: #eef1f9; --gd-bg2: #e4e9f4;
  --gd-ink: #12213a; --gd-muted: #45536e;
  --gd-line: rgba(11,28,48,.16); --gd-line-2: rgba(11,28,48,.26);
  --gd-accent: var(--tsb-line); --gd-on-accent: #f8f9ff; --gd-tab-on: rgba(11,28,48,.08); --gd-focus: #0b4fa8;
}
/* the Guide borrows pn-pilot-season.js's headerHTML() verbatim for its own Pilot Season chapter —
   that markup's `.pnps-hdr-eyebrow` reads `--pw-accent`/`--pw-accent-ink` (a different namespace
   from `.pnGd-read`'s own `--gd-*` tokens), so the `.pnGd-read` override above never reaches it.
   Direct override, same navy-on-transparent tab as every other eyebrow in this file. */
html:not(#pn-tsb-x) body #pnGd-root .pnGd-read .pnps-hdr-eyebrow{
  background: transparent !important; border-color: var(--tsb-line) !important;
  color: var(--tsb-line) !important; -webkit-text-fill-color: var(--tsb-line) !important;
}
html:not(#pn-tsb-x) body #pnGd-root .pnGd-eyebrow{
  font: 700 10.5px/1 var(--tsb-face-mono) !important; letter-spacing:.16em !important; text-transform:uppercase !important;
  border:2px solid var(--tsb-line) !important; padding:4px 8px !important; border-radius:2px !important; display:inline-block;
  color: var(--tsb-line) !important; background:transparent !important;
}
html:not(#pn-tsb-x) body #pnGd-root .pnGd-h{
  font-family: var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important;
  text-transform:uppercase !important; color: var(--tsb-line) !important;
}
html:not(#pn-tsb-x) body #pnGd-root .pnGd-body, html:not(#pn-tsb-x) body #pnGd-root .pnGd-tips li, html:not(#pn-tsb-x) body #pnGd-root .pnGd-gloss dd{
  color: #1c2b45 !important;
}
html:not(#pn-tsb-x) body #pnGd-root .pnGd-gloss dt, html:not(#pn-tsb-x) body #pnGd-root .pnGd-tipsHead{ color: var(--tsb-line) !important; }
html:not(#pn-tsb-x) body #pnGd-root .pnGd-take{
  background: var(--tsb-line) !important; color:#f8f9ff !important; -webkit-text-fill-color:#f8f9ff !important;
  border-color: var(--tsb-line) !important; border-radius:2px !important;
}

/* ══ 6 · THE DESK / URGENCY POP-OVER (.pnfc-scrim .pnfc-win.pnfc-win) ════════════════════════════════════
   Scoped to `.pnfc-scrim .pnfc-win.pnfc-win` (never bare `.lg-panel`, which dozens of other windows share).
   Title bar → the cobalt tab (this window is information — "what's on your desk"); each card's
   own urgency tone is remapped onto B's two live tones so severity still reads: caution/hazard →
   yellow, everything else (neutral/good/brand/league/gold) → cobalt ink, via the tone custom
   properties the file already reads (`--pnfc-tone-*`), so no selector work is needed per card. */
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win{
  /* re-declaring the window's own --lg-ink/--lg-ink-dim/--lg-hair/--lg-card-fill/--lg-avatar
     tokens HERE means every existing rule in pn-floor-chrome.js's injected stylesheet that reads
     them (the briefing lede, brief rows, card kind/headline, the mono icon tile) repaints for the
     light paper ground with zero extra per-selector work — scoped to this window only, never the
     dozens of OTHER .lg-panel surfaces the game shares this token family with. */
  --lg-ink: #1c2b45; --lg-ink-dim: rgba(28,43,69,.72);
  --lg-hair: rgba(11,28,48,.16); --lg-card-fill: rgba(11,28,48,.035); --lg-avatar: rgba(11,28,48,.07);
  border: 3px solid var(--tsb-line) !important; border-radius: 2px !important;
  box-shadow: 8px 8px 0 rgba(11,28,48,.24), 0 30px 80px rgba(0,0,0,.55) !important;
  background: #eef1f9 !important; color: #1c2b45 !important;
  --pnfc-tone-neutral: var(--tsb-line); --pnfc-tone-brand: var(--tsb-line); --pnfc-tone-good: #14532d;
  --pnfc-tone-league: #14532d; --pnfc-tone-gold: var(--tsb-line);
  --pnfc-tone-caution: #7a5306; --pnfc-tone-hazard: #7a5306;
}
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .lg-titlebar{
  background-color: var(--tsb-cobalt) !important; background-image: var(--tsb-cobalt-fill) !important; border-bottom: 2px solid var(--tsb-line) !important;
}
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .lg-tb-title{
  color: var(--tsb-cobalt-ink) !important; font:700 11px var(--tsb-face-mono) !important; letter-spacing:.1em !important; text-transform:uppercase !important;
}
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-x{ color: var(--tsb-cobalt-ink) !important; border-color: var(--tsb-cobalt-ink) !important; }
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-weekband{
  background-color: var(--tsb-yellow) !important; background-image: var(--tsb-yellow-fill) !important; border-color: var(--tsb-line) !important; border-radius:2px !important;
}
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-weekband b, html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-weekband .pnfc-headline{
  color: var(--tsb-yellow-ink) !important;
}
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-weekband .pnfc-headline{
  font-family: var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important; text-transform:uppercase !important;
}
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-weekband span{ color: var(--tsb-yellow-ink) !important; opacity:.82; }
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-card{
  background:#fff !important; border-color: color-mix(in srgb, var(--tsb-line) 22%, transparent) !important; border-radius:2px !important;
}
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-card-h{ color:#1c2b45 !important; font-family: var(--pn-type-face,'Inter',sans-serif) !important; }
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-copy, html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-voice{ color:#1c2b45 !important; }
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-opt.lg-btn--primary{
  background: var(--tsb-line) !important; color:#f8f9ff !important; -webkit-text-fill-color:#f8f9ff !important; border-color: var(--tsb-line) !important;
}
/* MEASURED: the Desk's move-rows print their "→" affordance in `--pnd-primary` (the house orange,
   #f97316) — 2.8:1 on the new light paper body, below AA. Not a background fill (so the orange-
   audit didn't flag it) but still a real legibility miss; navy ink, same family as every other
   icon/chevron on this paper ground. */
html:not(#pn-tsb-x) body .pnfc-scrim .pnfc-win.pnfc-win .pnfc-move-go{ color: var(--tsb-line) !important; }

/* ══ 7 · RUNG TIPS (.pnsp-tip) — a compact information chip (cobalt) ════════════════════════════ */
html:not(#pn-tsb-x) body .pnsp .pnsp-tip{
  background-color: var(--tsb-cobalt) !important; background-image: var(--tsb-cobalt-fill) !important; border: 2px solid var(--tsb-line) !important; border-radius: 2px !important;
  box-shadow: 4px 4px 0 rgba(11,28,48,.24) !important;
}
html:not(#pn-tsb-x) body .pnsp .pnsp-tip-h{
  font-family: var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important; text-transform:uppercase !important;
  color: var(--tsb-cobalt-ink) !important;
}
html:not(#pn-tsb-x) body .pnsp .pnsp-tip-row{ color: var(--tsb-cobalt-dim) !important; }
html:not(#pn-tsb-x) body .pnsp .pnsp-tip-row i{ color: var(--tsb-cobalt-dim) !important; }
html:not(#pn-tsb-x) body .pnsp .pnsp-tip-row em{ color:#fde68a !important; }
html:not(#pn-tsb-x) body .pnsp .pnsp-tip-row.is-ok em{ color:#86efac !important; }
html:not(#pn-tsb-x) body .pnsp .pnsp-tip-note{ color: var(--tsb-cobalt-dim) !important; }

/* ══ 8 · THE FEEDBACK PANEL HEADER ONLY (#pnfb-panel .pnfb-head) ════════════════════════════════
   Body/thread of the panel is owned elsewhere and untouched — only the header bar becomes the
   cobalt tab, matching the Guide/Desk title-bar treatment.
   MEASURED: unlike every other popup in this file, `#pnfb-panel` is NOT inside `<body>` — it
   mounts under `#pnfb-root`, a sibling of `<body>` appended directly to `<html>` (checked via
   the live parent chain, not assumed). Every `html:not(#id) body …` selector used everywhere
   else in this file silently fails to match here because `body` is never an ancestor. This
   section drops `body` from the chain for that reason — it is the one deliberate exception. */
html:not(#pn-tsb-x) #pnfb-panel .pnfb-head{
  background-color: var(--tsb-cobalt) !important; background-image: var(--tsb-cobalt-fill) !important; border-bottom: 2px solid var(--tsb-line) !important;
}
html:not(#pn-tsb-x) #pnfb-panel .pnfb-head-title{
  color: var(--tsb-cobalt-ink) !important; -webkit-text-fill-color: var(--tsb-cobalt-ink) !important;
  font-family: var(--tsb-face-display) !important; font-weight:900 !important; font-style:italic !important; text-transform:uppercase !important;
}
html:not(#pn-tsb-x) #pnfb-panel .pnfb-head-sub{ color: var(--tsb-cobalt-dim) !important; }
html:not(#pn-tsb-x) #pnfb-panel .pnfb-headbtn{ color: var(--tsb-cobalt-ink) !important; }
html:not(#pn-tsb-x) #pnfb-panel .pnfb-headbtn:hover, html:not(#pn-tsb-x) #pnfb-panel .pnfb-headbtn:focus-visible{
  background: color-mix(in srgb, var(--tsb-cobalt-ink) 16%, transparent) !important; color:#fff !important;
}

/* focus visibility, everywhere this file paints (apple-design a11y / UX_RULES) */
html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal :focus-visible,
html:not(#pn-tsb-x) body #pnps-welcome :focus-visible,
html:not(#pn-tsb-x) body #vv-ov :focus-visible,
html:not(#pn-tsb-x) body .pno-card.pno-card :focus-visible,
html:not(#pn-tsb-x) body #pnGd-root :focus-visible,
html:not(#pn-tsb-x) body .pnfc-win.pnfc-win :focus-visible{
  outline: 2px solid var(--tsb-line) !important; outline-offset: 2px !important;
}

@media (prefers-reduced-motion: reduce){
  html:not(#pn-tsb-x) body #toast.bigmodal.bigmodal .bigmodal-card{ animation:none !important; }
}

/* ══ 9 · TSB CHART KIT — animated numbers on the block (CEO, 2026-09-27: "more charts and
   graphing — all of which MUST animate") ═══════════════════════════════════════════════════════
   WEEKSUMMARY already draws its money-in/out bars and the runway track for real (script-01.js
   showWeekSummary(), anime.animate on `.wsl-trk i`, 640ms, eased, staggered by row, guarded by
   `matchMedia('(prefers-reduced-motion: reduce)')` — untouched by this brief, and now correctly
   ink-on-field via section 1 above instead of the old dark-card grey). This kit is the SHARED,
   ready-to-consume CSS for the four charts that do not exist in the DOM yet and need real data
   wired from script-01.js before they can draw anything true — REPORT (verdict vs target + a
   delta chart), PROMOTED (a stage-progress meter), VAULT_TOPUP (balance vs pack), CFOCONFIRM
   (a before/after runway bar). Per the brief's own JS rule, those four are NOT wired in this file
   (script-01.js is edit-by-snippet only) — the exact before/after snippets are in the hand-back
   report. This block is what those snippets attach `data-tsb-*` attributes to.

   Contract: every bar/meter starts at 0 via `width:0` (or `stroke-dashoffset` at full length for
   a line) and grows to its real, JS-supplied value through a `!important`-free CSS transition
   fired by the `.is-in` class the snippet adds one animation frame after mount (the same
   two-step "set the 0 state, then flip a class" pattern pn-fin-charts.js already uses for the
   Financials room, so a reviewer finds one convention, not two). Numbers count up via the game's
   own `[data-pn-count]` attribute (pn-motion.js autoCount) — nothing new to teach that engine. */
.tsb-bar{ position:relative; height:14px; border-radius:2px; overflow:hidden; background: color-mix(in srgb, currentColor 16%, transparent); }
.tsb-bar > i{
  position:absolute; inset:0 auto 0 0; display:block; width:0; background:currentColor;
  transition: width .78s cubic-bezier(.16,1,.3,1);
}
.tsb-bar.is-in > i{ width: var(--tsb-w, 0%); }
.tsb-bar .tsb-bar-tick{ position:absolute; top:-3px; bottom:-3px; width:3px; background:currentColor; opacity:.55; }

.tsb-meter{ display:flex; flex-direction:column; gap:6px; }
.tsb-meter-track{ height:16px; border-radius:2px; background: color-mix(in srgb, currentColor 14%, transparent); overflow:hidden; position:relative; }
.tsb-meter-track > i{ position:absolute; inset:0 auto 0 0; width:0; background:currentColor; transition: width .85s cubic-bezier(.16,1,.3,1); }
.tsb-meter-track.is-in > i{ width: var(--tsb-w, 0%); }
.tsb-meter-stages{ display:flex; justify-content:space-between; font:700 10px/1 var(--tsb-face-mono); letter-spacing:.08em; text-transform:uppercase; opacity:.75; }

/* a single-point state — used whenever fewer than 2 real data points exist (CEO rule: never
   invent a line). One dot, one caption, no fabricated trend. */
.tsb-spark-single{ display:inline-flex; align-items:center; gap:8px; font:700 13px var(--tsb-face-mono); }
.tsb-spark-single i{ width:8px; height:8px; border-radius:50%; background:currentColor; flex:none; }

/* a real multi-point line, drawn via stroke-dashoffset (same technique as pn-fin-charts.js's
   trajectory line) — the snippet supplies the real `d` path off the game's own week-close cash
   figures and sets `--tsb-len` to the path's own getTotalLength(). */
.tsb-spark{ overflow:visible; }
.tsb-spark path{
  fill:none; stroke:currentColor; stroke-width:2.5; stroke-linecap:round; stroke-linejoin:round;
  stroke-dasharray: var(--tsb-len, 1000); stroke-dashoffset: var(--tsb-len, 1000);
  transition: stroke-dashoffset .9s cubic-bezier(.16,1,.3,1);
}
.tsb-spark.is-in path{ stroke-dashoffset:0; }
.tsb-spark circle{ fill:currentColor; opacity:0; transition: opacity .3s ease .6s; }
.tsb-spark.is-in circle{ opacity:1; }

/* a compact delta chip — verdict-vs-target, before/after runway. Two bars, one baseline. */
.tsb-delta{ display:flex; flex-direction:column; gap:8px; }
.tsb-delta-row{ display:flex; align-items:center; gap:10px; }
.tsb-delta-row .tsb-delta-k{ flex:0 0 92px; font:700 11px var(--tsb-face-mono); letter-spacing:.06em; text-transform:uppercase; opacity:.75; }
.tsb-delta-row .tsb-bar{ flex:1 1 auto; }
.tsb-delta-row .tsb-delta-v{ flex:0 0 auto; font:900 15px var(--tsb-face-display); font-style:italic; min-width:4.5ch; text-align:right; }

@media (prefers-reduced-motion: reduce){
  .tsb-bar > i, .tsb-meter-track > i, .tsb-spark path, .tsb-spark circle{ transition:none !important; }
  .tsb-bar > i, .tsb-meter-track > i{ width: var(--tsb-w, 0%) !important; }
  .tsb-spark path{ stroke-dashoffset:0 !important; }
  .tsb-spark circle{ opacity:1 !important; }
}
