/* ══ BUILD 401A — THE ONE TOKEN SHEET (FRONT OF HOUSE PLAN §2) ══════════════════════════════
   Declared ONCE, here. `meta.css` no longer carries a `:root` block and no menu rule may invent
   a colour, a text size, a tracking value or a radius: `tokens-test.js` scans meta.css, the
   FRONT-OF-HOUSE regions of this sheet and v3.html's inline <style> and fails the build on any
   literal outside this block. The colour values are copied from Design Book §2, not invented.
   The second group are the Build 400 names the TABLE side still reads; they are kept so the
   table keeps compiling, and are aliased onto the new values wherever the Design Book has one
   (the table's own literals are out of this build's scope and are untouched). */
:root{
 /* ── colour ──────────────────────────────────────────────────────────────────────────── */
 --ink:#05130E;              /* floor black-green, the deepest ground */
 --ink-2:#0A211B;            /* marble emerald base */
 --ink-3:#123528;            /* marble emerald raised */
 --jade:#1E7A50;             /* live emerald: positive, self-employed, online */
 --brass:#C9A24B;            /* champagne brass mid: CTA, numerals, trim */
 --brass-hi:#E8C87A;         /* champagne brass high */
 --brass-deep:#6B4E14;       /* champagne brass deep */
 --ivory:#F5EFDD;            /* ticker ivory: text */
 --muted:#8CA69A;            /* secondary text */
 --slate:#2F5D9E;            /* board slate-blue (salaried) */
 --market:#8E4DC9;           /* market purple — Market Forces only */
 --crash:#E23D3D;            /* crash red — danger, crime, alerts only */
 --hairline:rgba(232,200,122,.22);
 --glass:rgba(5,19,14,.86);
 --shadow:0 24px 70px rgba(0,0,0,.58);
 /* Build 400 names kept for the table-side rules that still read them */
 --exchange:var(--ink-3);
 --jade-bright:#2FC47C;      /* the bright "live/ready" emerald the table and the seat cards use */
 --paper:var(--ivory);
 --danger:var(--crash);
 --opportunity:#4C8DFF;      /* the Opportunity deck's own blue — a table colour with no menu token */
 /* ── type ────────────────────────────────────────────────────────────────────────────── */
 --font-display:'Barlow Semi Condensed',Barlow,sans-serif;
 --font-body:Barlow,'Segoe UI',sans-serif;
 --fs-11:11px;               /* eyebrow / status pill — the floor outside the table */
 --fs-12:12px;               /* captions */
 --fs-14:14px;               /* body */
 --fs-16:16px;               /* controls, list rows */
 --fs-20:20px;               /* section titles */
 --fs-24:24px;               /* page titles */
 --fs-32:32px;               /* hero figures */
 --fs-48:48px;               /* ceremonial only */
 --ls-label:.08em;
 --ls-eyebrow:.14em;
 /* ── space, radius, elevation, motion ────────────────────────────────────────────────── */
 --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:24px; --sp-6:32px; --sp-7:48px;
 --r-chip:4px; --r-card:10px; --r-pill:999px;
 --tap:44px;
 --dur-fast:140ms; --dur:220ms; --dur-slow:420ms; --ease:cubic-bezier(.2,.7,.2,1);
}

/* FRONT-OF-HOUSE START */
html,body{background:var(--ink);color:var(--ivory);font-family:Barlow,'Segoe UI',sans-serif}
button,input{font-family:inherit}
button{-webkit-tap-highlight-color:transparent}
button:focus-visible,input:focus-visible{outline:2px solid var(--brass);outline-offset:3px}

/* Shared engraved surface language */
#v2title,#v3lobby{
 background:
  radial-gradient(circle at 50% 42%,rgba(18,53,40,.18),transparent 42%),
  linear-gradient(rgba(5,19,14,.52),rgba(5,19,14,.8)),
  url('art/theme/exchange-floor-v1.webp') center/cover no-repeat;
}
#v2title::before,#v3lobby::before{
 content:"";position:absolute;inset:18px;pointer-events:none;
 border:1px solid rgba(201,162,75,.25);
 clip-path:polygon(0 28px,28px 0,calc(100% - 28px) 0,100% 28px,100% calc(100% - 28px),calc(100% - 28px) 100%,28px 100%,0 calc(100% - 28px));
 box-shadow:inset 0 0 80px rgba(0,0,0,.38);
}

/* Title: a club invitation rather than a web menu */
#v2title{gap:7px;isolation:isolate;overflow:hidden}
#v2title>*{position:relative;z-index:1}
.ttEyebrow,.ttSeal,.tt1,.tt2,.tttag,.ttmodes,.ttVersion{animation:titleReveal .62s cubic-bezier(.18,.8,.25,1) both}
.ttSeal{animation-delay:.05s}.tt1{animation-delay:.1s}.tt2{animation-delay:.15s}.tttag{animation-delay:.2s}.ttmodes{animation-delay:.25s}.ttVersion{animation-delay:.33s}
@keyframes titleReveal{from{opacity:0;transform:translateY(11px)}to{opacity:1;transform:none}}
.titleArchitecture{display:flex;align-items:center;gap:12px;width:min(620px,72vw);color:var(--brass);opacity:.72}
.titleArchitecture i{height:1px;flex:1;background:linear-gradient(90deg,transparent,var(--brass))}
.titleArchitecture i:last-child{background:linear-gradient(90deg,var(--brass),transparent)}
.titleArchitecture b{font-size:var(--fs-11);font-weight:500}
.ttEyebrow{font:700 11px/1 Barlow;letter-spacing:var(--ls-eyebrow);color:var(--muted);text-align:center}
.ttEyebrow em{font-style:normal;color:var(--brass);padding:0 7px}
.ttSeal{width:48px;height:48px;display:grid;place-items:center;margin-top:3px;color:var(--brass)}
.ttSeal::before,.ttSeal::after{content:"";position:absolute;inset:3px;border:1px solid rgba(201,162,75,.62);transform:rotate(45deg)}
.ttSeal::after{inset:8px;border-color:rgba(201,162,75,.25)}
.ttSeal span{font:700 24px/1 'Bodoni Moda',serif;text-shadow:0 0 16px rgba(201,162,75,.35)}
.ttSeal i{position:absolute;width:3px;height:3px;background:var(--ivory);border-radius:50%;box-shadow:0 0 8px var(--ivory)}
.tt1{font:700 clamp(54px,7vw,92px)/.88 'Bodoni Moda',serif;letter-spacing:var(--ls-label);color:var(--ivory);background:none;filter:none;text-shadow:0 3px 0 #000,0 12px 30px rgba(0,0,0,.72);font-variant-numeric:tabular-nums lining-nums}
.ttCurrency{font-size:.72em;color:var(--brass);padding-right:.08em;vertical-align:.08em}
.tt2{font:400 clamp(16px,2vw,24px)/1 'Bebas Neue';letter-spacing:clamp(8px,1.5vw,17px);color:var(--brass);border:0;padding:8px 0 0;text-indent:clamp(8px,1.5vw,17px)}
.tttag{margin:3px 0 7px;font:700 11px/1.1 Barlow;letter-spacing:var(--ls-eyebrow);color:var(--paper)}
.tttag i{font-style:normal;font-size:var(--fs-11);color:var(--brass);padding:0 10px;vertical-align:2px}
/* Build 355 (David 2026-08-30: "Ugly. Centralize it or something if you cant put 5 buttons in a line.").
   The four-column GRID could only answer a fifth mode with an orphan hanging off one end. This is a CENTRED
   FLEX row instead: every card grows to share the line, the row is centred, and a remainder - now or when a
   sixth mode arrives - centres itself instead of clinging to an edge. The list is widened to 1320px so all
   FIVE fit on one line on a desktop at close to the width four cards had before (256px against 273px). */
.ttmodes{display:flex;flex-direction:row;flex-wrap:wrap;justify-content:center;gap:10px;width:min(1320px,94vw);margin-top:8px}/* flex-direction is DECLARED, not inherited: v3.html's own inline sheet sets .ttmodes to a flex COLUMN for the no-stylesheet case, and the grid this replaced used to mask that by overriding `display`. Dropping the property here stacked all five modes vertically on a desktop - caught in a real browser before it shipped. */
.ttmodes>.ttmode{flex:1 1 170px;max-width:256px}/* 170 is the basis that keeps all FIVE on one line down to ~950px; the 256 cap keeps them from ballooning on an ultrawide. Both are reset where the list stacks. */
/* ══ BUILD 402 — THE CLIMB CARD IS THE PLAY HERO (FRONT OF HOUSE PLAN D5 / §4.1) ═══════════════
   The mode list stays what Build 355 made it - a CENTRED, WRAPPING FLEX ROW of exactly five cards
   in source order, with the campaign last by `order:99`. Nothing above is touched. The hero is
   built out of the row's own rules instead: THE CLIMB takes a full-width basis and comes first, so
   it owns line one on its own; HOST TABLE · JOIN TABLE · TUTORIAL share line two; THE SCHISM takes
   a full-width basis too and `order:99` still puts it last. A phone already stacks this list, so
   the same two declarations simply put the Climb card at the top of the stack and make it tall.
   The hero's CONTENT is written by meta.js paintPlayHero() into one span inside the button - there
   is no sixth element, no nested control, and the pinned inner markup is untouched. */
.ttmodes>.climbMode{order:-1;flex:1 1 100%;max-width:none}
.ttmodes>.campaignRow{flex:1 1 100%;max-width:none}
.ttmodes>.ttmode:not(.climbMode):not(.campaignRow){max-width:330px}/* the three secondary cards share line two; 256 was the five-across cap and made HOST TABLE wrap */
.ttmode.climbMode{grid-template-rows:auto auto;align-content:center;padding:16px 18px}
.ttmode.climbMode>.climbHero{grid-column:1/-1}
.ttmode,.ttmode.gold{
 min-height:90px;display:grid;grid-template-columns:42px 1fr auto;align-items:center;gap:12px;
 padding:13px 15px;text-align:left;border-radius:var(--r-chip);
 border:1px solid rgba(201,162,75,.38);color:var(--ivory);
 background:linear-gradient(145deg,rgba(18,53,40,.96),rgba(5,19,14,.96));
 box-shadow:inset 0 1px rgba(255,255,255,.05),inset 0 -18px 38px rgba(0,0,0,.2),0 9px 22px rgba(0,0,0,.4);
 font:400 20px/1 'Bebas Neue';letter-spacing:var(--ls-label);transition:.18s ease;overflow:hidden;
}
.ttmode.tutorialMode{border-color:rgba(47,196,124,.58);background:linear-gradient(180deg,rgba(18,53,40,.96),rgba(10,33,27,.98));overflow:visible}
.ttmode.tutorialMode em{position:absolute;right:10px;top:-9px;padding:3px 7px;border:1px solid rgba(245,239,221,.45);border-radius:var(--r-pill);background:var(--jade);color:var(--ivory);font:800 11px Barlow;letter-spacing:var(--ls-eyebrow);font-style:normal;box-shadow:0 4px 12px rgba(0,0,0,.45)}
.ttmode.tutorialMode.complete em{background:var(--ink-3);color:var(--muted)}.ttmode.tutorialMode.complete em::before{content:'✓ '}
.ttmode.tutorialMode.firstPrompt{animation:tutorialRecommend 1.1s ease-in-out 2}@keyframes tutorialRecommend{50%{border-color:var(--jade-bright);box-shadow:0 0 0 2px rgba(47,196,124,.4),0 0 28px rgba(47,196,124,.28);transform:translateY(-2px)}}
/* v200 (David): the coloured left edge stripes are retired — a full frame and the medallion carry the state now */
.ttmode.gold{border-color:rgba(201,162,75,.82);background:linear-gradient(145deg,rgba(18,53,40,.98),rgba(10,33,27,.98));color:var(--ivory)}
.ttmode.gold .modeIcon{background:linear-gradient(180deg,var(--brass-hi),var(--brass));color:var(--ink-2);border-color:transparent;box-shadow:0 4px 12px rgba(0,0,0,.35)}
.ttmode.gold{box-shadow:inset 0 1px rgba(245,239,221,.14),inset 0 -18px 38px rgba(0,0,0,.2),0 9px 22px rgba(0,0,0,.4),0 0 22px rgba(201,162,75,.1)}
/* Build 402: :hover used to paint the SAME background as .ttmode.gold, so hovering an ordinary
   card made it look like the recommended one. Hover is a hairline change now - a brighter brass
   edge and a lift - and the gold surface stays the property of the gold state alone. */
.ttmode:hover{transform:translateY(-3px);border-color:var(--brass-hi);box-shadow:inset 0 1px rgba(255,255,255,.07),0 15px 32px rgba(0,0,0,.48),0 0 0 1px rgba(201,162,75,.28)}
.ttmode:active{transform:translateY(1px)}
.ttmode>span:nth-child(2){min-width:0}
.ttmode small{margin-top:6px;color:var(--ivory);font:600 12px/1.3 Barlow;letter-spacing:0;white-space:normal}
.modeIcon{width:34px;height:44px;display:grid;place-items:center;border:1px solid var(--hairline);color:var(--brass);font:700 12px 'Bodoni Moda';clip-path:polygon(50% 0,100% 17%,100% 83%,50% 100%,0 83%,0 17%);background:rgba(0,0,0,.24)}
.ttmode>b{font:800 11px Barlow;letter-spacing:var(--ls-eyebrow);color:var(--brass)}
.ttVersion{margin-top:1px;color:rgba(140,166,154,.64);font:700 11px/1 Barlow;letter-spacing:var(--ls-eyebrow);text-transform:uppercase;font-variant-numeric:tabular-nums}

/* Lobby: private members' room */
#v3lobby{isolation:isolate}
#v3lobby>*{position:relative;z-index:1}
.lbCard{width:min(720px,92vw);max-height:90vh;padding:22px 26px 18px;border-radius:var(--r-chip);border:1px solid rgba(201,162,75,.48);background:linear-gradient(155deg,rgba(18,53,40,.95),rgba(5,19,14,.97));box-shadow:var(--shadow),inset 0 1px rgba(255,255,255,.05);scrollbar-color:var(--brass-deep) transparent}
.lbCard{animation:lobbyReveal .38s cubic-bezier(.2,.8,.25,1) both}
@keyframes lobbyReveal{from{opacity:0;transform:translateY(18px) scale(.985)}to{opacity:1;transform:none}}
.lbCard::before,.lbCard::after{content:"";position:absolute;pointer-events:none}
.lbCard::before{inset:6px;border:1px solid rgba(201,162,75,.12)}
.lbCard::after{left:42px;right:42px;top:0;height:2px;background:linear-gradient(90deg,transparent,var(--brass),transparent)}
.lbHead{align-items:flex-end;padding-bottom:12px;border-color:var(--hairline)}
.lbHead span{display:flex;flex-direction:column;color:var(--ivory);font-size:var(--fs-20);letter-spacing:var(--ls-eyebrow)}
.lbHead span small{margin-bottom:4px;color:var(--muted);font:700 11px Barlow;letter-spacing:var(--ls-eyebrow)}
.lbHead b{font-size:var(--fs-16);color:var(--brass);letter-spacing:var(--ls-eyebrow)}
.lbIntro{display:flex;justify-content:space-between;align-items:baseline;gap:18px;margin:15px 0 8px}
.lbIntro strong{font:400 24px 'Bebas Neue';letter-spacing:var(--ls-label);color:var(--brass)}
.lbIntro span{max-width:390px;color:var(--muted);font:600 11px/1.4 Barlow;text-align:right}
.lbIdent{margin:12px 0 8px;padding:13px;border:1px solid rgba(201,162,75,.17);background:rgba(5,19,14,.38)}
#lbMyAv{width:72px;height:72px;border:2px solid var(--brass);background:var(--exchange);box-shadow:0 0 0 5px rgba(201,162,75,.08),0 9px 22px rgba(0,0,0,.48)}
.lbAvBtn{width:30px;height:30px;border-color:var(--hairline);background:rgba(5,19,14,.92);color:var(--brass)}
#lbName,#lbCode{border-radius:var(--r-chip);border-color:var(--hairline);background:rgba(5,19,14,.7);color:var(--ivory);box-shadow:inset 0 2px 12px rgba(0,0,0,.32)}
#lbName:focus,#lbCode:focus{border-color:var(--brass);box-shadow:0 0 0 3px rgba(201,162,75,.1),inset 0 2px 12px rgba(0,0,0,.3)}
.lbLbl{color:var(--muted);font-size:var(--fs-11);letter-spacing:var(--ls-eyebrow)}
.ttrow.sm button{border-radius:var(--r-chip);background:rgba(5,19,14,.82);border-color:rgba(201,162,75,.24);color:var(--paper)}
.ttrow.sm button.on{background:var(--brass);color:var(--ink-2);border-color:var(--brass);box-shadow:0 0 18px rgba(201,162,75,.22)}
input[type=range]{accent-color:var(--brass)}
#lbSeats{grid-template-columns:repeat(auto-fit,minmax(105px,1fr));gap:8px}
.lbSeat{min-height:98px;border-radius:var(--r-chip);border-color:rgba(201,162,75,.2);background:linear-gradient(160deg,rgba(18,53,40,.78),rgba(5,19,14,.9));box-shadow:inset 0 1px rgba(255,255,255,.035)}
.lbSeat.ready{border-color:rgba(47,196,124,.72);box-shadow:inset 0 -2px rgba(47,196,124,.28),0 0 15px rgba(47,196,124,.08)}
.lbSeat.you{border-color:rgba(201,162,75,.75);box-shadow:inset 0 -2px rgba(201,162,75,.35)}
.lbSeat .st{color:var(--muted)}
.lbSeat .crown{color:var(--brass);text-shadow:0 0 8px rgba(201,162,75,.45)}
/* Build 396: Circle power is material, not a paragraph. Rival cards gain a stronger brass edge and
   deeper halo at each Circle; the avatar itself stays clear and the selected player's frame stays singular. */
.lbSeat.climbRival{--climbPower:.18;overflow:hidden;border-color:rgba(201,162,75,.42);background:linear-gradient(155deg,rgba(18,53,40,.9),rgba(5,19,14,.96));box-shadow:inset 0 -2px rgba(201,162,75,.22),0 0 20px rgba(232,200,122,var(--climbPower))}
.lbSeat.climbRival::after{content:"";position:absolute;z-index:0;left:0;right:0;top:0;height:3px;background:linear-gradient(90deg,transparent,var(--brass-deep) 18%,var(--ivory) 50%,var(--brass-deep) 82%,transparent);opacity:calc(.2 + var(--climbPower));pointer-events:none}.lbSeat.climbRival>*{position:relative;z-index:1}
.lbSeat.climbRival.circle-1{--climbPower:.08}.lbSeat.climbRival.circle-2{--climbPower:.13}.lbSeat.climbRival.circle-3{--climbPower:.18}.lbSeat.climbRival.circle-4{--climbPower:.24}.lbSeat.climbRival.circle-5{--climbPower:.31;border-color:rgba(232,200,122,.58)}.lbSeat.climbRival.circle-6{--climbPower:.4;border-color:rgba(232,200,122,.68)}.lbSeat.climbRival.circle-7{--climbPower:.52;border-color:var(--brass-hi);background:linear-gradient(155deg,rgba(18,53,40,.96),rgba(5,19,14,.99));box-shadow:inset 0 0 0 1px rgba(245,239,221,.18),inset 0 -3px rgba(232,200,122,.42),0 0 28px rgba(232,200,122,.28)}
#lbReady{border-radius:var(--r-chip);border-color:var(--brass-hi);background:linear-gradient(180deg,var(--brass-hi),var(--brass));color:var(--ink-2);font-size:var(--fs-20);box-shadow:inset 0 1px rgba(255,255,255,.55),0 4px 0 var(--brass-deep),0 12px 24px rgba(0,0,0,.38)}
#lbReady.armed{background:linear-gradient(180deg,var(--jade-bright),var(--jade-bright));color:var(--ink)}
#lbHint{color:var(--muted)}
.lbBack{color:var(--muted);text-decoration:none;border-bottom:1px solid rgba(140,166,154,.3)}
/* FRONT-OF-HOUSE END */

/* v130: the legacy desktop Floor Wire is retired. #v2msg remains a hidden compatibility sink
   for diagnostics/tests; all visible play guidance uses the unified #v2toastLane notice below. */
body:not(.playing) #v2command{display:none}
#v2ticker{display:none!important}

/* Bottom command console: all turn-critical information in one safe zone */
#v2command{--console-av:var(--console-av-px,54px);--console-end:88px;--console-arch:0px;--console-lift:var(--console-lift-px,0px);position:fixed;left:16px;right:16px;bottom:12px;height:64px;display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:16px;padding:5px 8px;box-sizing:border-box;pointer-events:none;border:1px solid rgba(210,180,104,.4);border-radius:5px;background:linear-gradient(155deg,rgba(14,48,36,.95),rgba(4,17,13,.97));box-shadow:0 12px 38px rgba(0,0,0,.62),inset 0 1px rgba(255,255,255,.055);backdrop-filter:blur(10px)}
body.playing #v2command{animation:consoleRise .48s cubic-bezier(.18,.8,.25,1) both}
@keyframes consoleRise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
#v2command::before{content:"";position:absolute;inset:4px;border:1px solid rgba(210,180,104,.1);pointer-events:none}
#v2command::after{content:"EXCHANGE CONTROL";position:absolute;left:17px;top:-7px;padding:0 7px;background:var(--ink);color:var(--muted);font:800 6px Barlow;letter-spacing:2px}
/* Build 374 — THE CENTRED CONSOLE (David 2026-09-01). The player's portrait is the console's
   CENTRE, not its left corner, and every other readout is composed around it: the portfolio hugs
   the medallion from the left, turn control from the right, and PASS keeps the right edge it has
   always had. The two side columns are equal 1fr tracks, so the medallion sits on the console's
   true horizontal centre at every width without a single hand-tuned offset. PASS leaves the grid
   (absolute, right edge) precisely so that adding it can never pull the centre off-axis. */
.commandPortfolio,.commandIdentity,.commandWorth,.commandTurn{min-width:0}
/* the plate is DECORATION: every readout stacks above it, or a positioned child would bury them */
.commandPortfolio,.commandIdentity,.commandTurn{position:relative;z-index:1}
#v2end{z-index:2}
.commandPortfolio{display:grid;grid-template-columns:minmax(0,1fr);align-items:center;justify-self:end;width:100%;max-width:100%}
/* The block READS left to right; the block ITSELF hugs the medallion, so a wide desktop does not
   park the fortune 500px away from the face it belongs to (GDKeys: one consolidated identity
   cluster, never a scatter). On a phone the lane is narrower than the block, so this is a no-op. */
/* THE MEDALLION BREAKS THE RAIL. Three of the reference games do not bound the player's portrait
   by a bar at all - MTG Arena's avatar is an oversized medallion crossing a strip of small phase
   glyphs, Hearthstone's hero sits on the board itself. So the diameter is not capped by the plate:
   v3.js sizes it against the plate PLUS the crown and lifts it by exactly what the fan leaves free
   above the console. --console-lift is solved, never guessed. */
.commandIdentity{position:relative;display:grid;place-items:center;justify-self:center;width:var(--console-av);height:var(--console-av);transform:translateY(calc(-1 * var(--console-lift,0px)))}
/* Build 398: the House crest owns a RESERVED side bay. Expanding the middle grid track equally on
   both sides preserves the table axis while keeping the enamel, portrait and turn ring on disjoint
   pixels. The short brass bridge makes the pair read as one identity display, not two loose badges. */
.commandIdentity.houseMarked{width:calc(var(--console-av) + 58px)}
.commandHouse{--command-house-size:22px;position:absolute;z-index:4;left:0;top:50%;display:none;width:var(--command-house-size);height:var(--command-house-size);box-sizing:border-box;transform:translateY(-50%);border:1px solid rgba(232,200,122,.68);border-radius:5px;background-color:#071a14;background-position:center;background-repeat:no-repeat;background-size:contain;box-shadow:0 3px 10px rgba(0,0,0,.5),inset 0 1px rgba(255,255,255,.08);filter:drop-shadow(0 0 4px rgba(232,200,122,.2));pointer-events:none}
.commandHouse::after{content:"";position:absolute;left:100%;top:50%;width:5px;height:1px;background:rgba(232,200,122,.58);box-shadow:0 0 5px rgba(232,200,122,.35)}
.commandHouse.house-gilded{display:block;background-image:url('art/meta/crest-gilded.svg')}.commandHouse.house-vanguard{display:block;background-image:url('art/meta/crest-vanguard.svg')}.commandHouse.house-syndicate{display:block;background-image:url('art/meta/crest-syndicate.svg')}
/* THE READING AXIS RUNS ONE WAY. The goal track fills LEFT to RIGHT, so its label and its number
   start at the left and the target sits at the fill's terminus - the convention every reference
   game keeps (Hearthstone puts the live figure at the ORIGIN of its crystal row; Clash Royale
   reserves the right of the elixir bar for a cumulative total). Right-aligning a number over a
   left-filling bar makes one block read in two directions at once. */
.commandWorth{display:flex;width:min(100%,300px);margin-left:auto;min-width:0;max-width:100%;min-height:0;flex-direction:column;align-items:flex-start;justify-content:center;overflow:hidden;text-align:left}
.commandTurn{justify-self:start;width:100%;box-sizing:border-box;padding-right:calc(var(--console-end) + 16px)}
/* THE STATE RING. Marvel Snap's finding, adopted: whose turn it is is worn by the portrait, not
   spelled out a second time in words. ::before/::after on #v2reactB are already owned (FOUNDER,
   AUTO REPLIES / REPLY), so the ring belongs to the identity cell that frames it. */
.commandIdentity::before{content:"";position:absolute;left:50%;top:50%;width:calc(var(--console-av) + 10px);height:calc(var(--console-av) + 10px);transform:translate(-50%,-50%);border-radius:50%;border:1.5px solid rgba(210,180,104,.4);pointer-events:none;transition:border-color .22s ease,box-shadow .22s ease}
body[data-turn-state="mine-active"] .commandIdentity::before{border-color:rgba(111,227,165,.82);box-shadow:0 0 18px rgba(76,203,138,.3)}
body[data-turn-state="mine-trim"] .commandIdentity::before{border-color:rgba(226,61,61,.82);box-shadow:0 0 18px rgba(226,61,61,.28)}
body[data-turn-state="mine-closing"] .commandIdentity::before{border-color:rgba(210,180,104,.3);box-shadow:none}
body[data-turn-state="rival-active"] .commandIdentity::before{border-color:rgba(210,180,104,.26);box-shadow:none}
/* THE ARCH PLATE. Portrait phones and tablets only: one curved lacquer plate whose crown follows
   the hand fan's own curve, so the two read as one instrument rather than a bar parked under a fan.
   It is an SVG QUADRATIC, not a CSS elliptical corner: the fan's lower boundary is a parabola
   (off^2 x cw x handArc) and an ellipse is much fuller near the edges, which is exactly how the
   first cut of this walked up into the outermost cards of a full hand. v3.js sizes the viewBox and
   writes the path from the solver's own fan numbers. It is painted ABOVE the measured box, so
   #v2command's height - the number hudInsets() hands the solver - is untouched by the curve. */
.commandArch{display:none;position:absolute;z-index:0;left:0;pointer-events:none;overflow:visible}
.commandArch path{fill:rgba(6,26,20,.975);stroke:rgba(210,180,104,.5);stroke-width:1.25;filter:drop-shadow(0 -10px 26px rgba(0,0,0,.55))}
body[data-turn-state="mine-active"] .commandArch path{stroke:rgba(111,227,165,.62)}
body[data-turn-state="mine-trim"] .commandArch path{stroke:rgba(226,61,61,.72)}
.commandLabel{display:flex;align-items:center;justify-content:flex-start;gap:8px;margin-bottom:1px;color:var(--muted);font:800 7px Barlow;letter-spacing:1.7px;white-space:nowrap}
#v2nw{position:static!important;max-width:100%;overflow:hidden;white-space:nowrap;color:var(--ivory);font:700 28px/.95 'Bodoni Moda',serif;letter-spacing:-1px;text-shadow:0 2px 8px #000;font-variant-numeric:tabular-nums}
#v2goal{position:static!important;width:100%!important;margin-top:4px;color:var(--muted);font-size:8px;text-shadow:none}
.goaltrack{position:relative;height:6px;overflow:hidden;border:1px solid rgba(210,180,104,.32);border-radius:4px;background:#020806;box-shadow:inset 0 2px 5px rgba(0,0,0,.85)}
.goalfill{position:absolute;inset:0 auto 0 0;width:0;border-radius:3px;background:linear-gradient(90deg,#806122,var(--brass),#f1dda4);box-shadow:0 0 12px rgba(210,180,104,.42);transition:width .45s cubic-bezier(.2,.8,.2,1)}
.goalmark{position:absolute;right:0;top:-2px;width:2px;height:10px;background:#F5EFDD;opacity:.62;box-shadow:0 0 6px rgba(245,239,221,.5)}
#v2act{position:static!important;display:flex;align-items:center;gap:7px;width:100%;min-width:0;max-width:100%;overflow:hidden;color:var(--brass);font-size:13px;text-shadow:none;white-space:nowrap}
.actlabel{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.actpips{flex:0 0 auto;gap:5px}.apip{width:7px;height:7px;border-color:rgba(210,180,104,.55);background:#020806}.apip.on{background:var(--brass);box-shadow:0 0 8px rgba(210,180,104,.75),inset 0 1px #fff}
/* v235 (Founder feedback 8 Aug: "the number of actions should be very clear at all times"):
   on YOUR turn the actions row brightens to ivory and every live pip glows stronger + ~15%
   larger. Pure emphasis — no layout height change, so the locked phone console rows hold. */
#v2act.mine{color:var(--ivory)}
#v2act.mine .actlabel{font-weight:800;letter-spacing:1.6px}
#v2act.mine .apip{transform:scale(1.15)}
#v2act.mine .apip.on{background:#F2DFA8;box-shadow:0 0 12px rgba(242,223,168,.95),0 0 3px rgba(242,223,168,.9),inset 0 1px #fff}
/* v243 authoritative turn presentation: the canvas owns the table-half wash; this DOM rim makes
   the command/action edge agree without moving a single mobile or desktop control. */
body[data-turn-state="mine-active"] #v2command{border-color:rgba(111,227,165,.72);box-shadow:0 0 24px rgba(76,203,138,.16),0 12px 38px rgba(0,0,0,.62),inset 0 1px rgba(255,255,255,.07)}
body[data-turn-state="mine-active"] #v2act{color:#F5EFDD}
/* v244: the opening glow is intentionally unmistakable until the player's first deliberate
   interaction. The canvas lights the whole owned half; this restrained console breath anchors it
   at the decision controls. The engaged state above remains lit, but stops asking for attention. */
@keyframes turnFreshConsole{0%,100%{box-shadow:0 0 28px rgba(53,213,138,.25),0 0 10px rgba(240,216,148,.13),0 12px 38px rgba(0,0,0,.62),inset 0 1px rgba(255,255,255,.08)}50%{box-shadow:0 0 42px rgba(53,213,138,.38),0 0 18px rgba(240,216,148,.22),0 12px 38px rgba(0,0,0,.62),inset 0 1px rgba(255,255,255,.11)}}
body[data-turn-state="mine-active"][data-turn-attention="fresh"] #v2command{border-color:rgba(240,216,148,.88);animation:turnFreshConsole 1.8s ease-in-out infinite}
body[data-turn-state="mine-trim"] #v2command{border-color:rgba(226,61,61,.76);box-shadow:0 0 25px rgba(226,61,61,.16),0 12px 38px rgba(0,0,0,.62),inset 0 1px rgba(255,255,255,.06)}
#v2act.trimming{color:#ffd0bf}#v2act.trimming .apip.on{background:#E8C87A;box-shadow:0 0 9px rgba(226,61,61,.72)}
body[data-turn-state="mine-closing"] #v2command{border-color:rgba(210,180,104,.32);box-shadow:0 12px 38px rgba(0,0,0,.62),inset 0 1px rgba(255,255,255,.035)}
#v2act.closing{color:#D8E2DD}#v2act.closing .apip{transform:scale(.9);background:#07130F;box-shadow:none}
body[data-turn-state="rival-active"] #v2command{border-color:rgba(210,180,104,.32)}
.apip{transition:transform .22s ease,background .22s ease,box-shadow .22s ease}
.turnclock{flex:0 0 auto;border-radius:3px;border-color:rgba(47,196,124,.42);background:rgba(1,10,7,.72);color:#a6eec7}
.turnclock.warn{border-color:var(--brass);color:var(--ivory)}.turnclock.critical{border-color:var(--danger);background:#351016;color:#ffd1d1}
#v2end{position:absolute!important;right:10px;top:0;bottom:0;margin-top:auto;margin-bottom:auto;min-width:0;width:var(--console-end);height:46px;padding:0 8px;pointer-events:auto;border-radius:3px;border:1px solid #e1ca8c;color:#152018;background:linear-gradient(180deg,#ead598,#c3a156);box-shadow:inset 0 1px rgba(255,255,255,.65),0 3px 0 #6f5420,0 7px 14px rgba(0,0,0,.38);font-size:15px;letter-spacing:1.7px}
#v2end:hover{filter:brightness(1.08);transform:translateY(-1px)}#v2end:active{transform:translateY(2px)}
#v2end:disabled{opacity:.38;transform:none;filter:saturate(.45);pointer-events:none}
/* v247: DISCARD n is a real, warned mode switch. The red control matches the red-lit hand on
   desktop and mobile; geometry and the 44px phone target remain exactly the same. */
body[data-turn-state="mine-trim"] #v2end{border-color:#FF8A8A;color:#FFF4EC;background:linear-gradient(180deg,#C84B4B,#8F252B 58%,#5A161D);box-shadow:inset 0 1px rgba(255,255,255,.34),0 3px 0 #3B0C12,0 0 22px rgba(226,61,61,.38),0 7px 14px rgba(0,0,0,.42)}

/* Activity history is no longer a permanent desktop surface. It opens on demand from the same
   unified table notice, matching the existing mobile interaction. */
#v2feed{display:none;left:124px;top:52px;width:215px;gap:4px}
.feedhead{display:flex;align-items:center;justify-content:space-between;color:var(--brass);font-size:7px;letter-spacing:2.2px}.feedhead span{font:inherit}#v2feedClose{display:none}
#v2feedItems .feeditem:nth-child(n+5){display:none}
.feeditem{padding:6px 8px 6px 11px;border-radius:3px;background:linear-gradient(90deg,rgba(3,16,12,.92),rgba(6,23,17,.6));border-left-color:var(--muted);color:#aec2b8;box-shadow:0 5px 15px rgba(0,0,0,.2)}
.feeditem.money{border-left-color:var(--brass);color:#e3d3a7}.feeditem.danger{border-left-color:var(--danger);color:#efb5b8}.feeditem.market{border-left-color:var(--market);color:#d6c0eb}.feeditem.turn{border-left-color:var(--jade-bright);color:#afe6c8}
@media(min-width:901px){
 /* v254 UI SCALE: the whole Exchange Control console follows --m1-uiscale (100–185%, Settings,
    desktop/tablet landscape
    only). hudInsets() measures the bar's real height, so the board budget shrinks honestly and
    the collision law (§3.11) holds. The board's card sizes follow the same factor in zones(). */
 #v2command{height:calc(64px*var(--m1-uiscale,1))}
 #v2command{--console-end:calc(88px*var(--m1-uiscale,1))}
 #v2nw{font-size:calc(28px*var(--m1-uiscale,1))}
 .commandLabel{font-size:calc(7px*var(--m1-uiscale,1))}
 #v2goal{font-size:calc(8px*var(--m1-uiscale,1))}
 #v2act{font-size:calc(14px*var(--m1-uiscale,1))}
 .apip{width:calc(8px*var(--m1-uiscale,1));height:calc(8px*var(--m1-uiscale,1))}
 .turnclock{font-size:calc(11px*var(--m1-uiscale,1));min-width:calc(27px*var(--m1-uiscale,1))}
 #v2end{height:calc(46px*var(--m1-uiscale,1));font-size:calc(15px*var(--m1-uiscale,1))}
 #v2msg{font-size:calc(14px*var(--m1-uiscale,1))}
 body.feed-open #v2feed{display:flex;left:50%;right:auto;top:auto;bottom:calc(100vh - var(--floor-wire-y,50vh) + 30px);width:min(560px,calc(100vw - 32px));max-height:min(48vh,calc(var(--floor-wire-y,50vh) - 42px),430px);transform:translateX(-50%);overflow:hidden;gap:8px;padding:12px;box-sizing:border-box;pointer-events:auto;z-index:27;border:1px solid rgba(210,180,104,.55);border-radius:5px;background:linear-gradient(155deg,rgba(10,39,29,.985),rgba(3,15,11,.99));box-shadow:0 22px 55px rgba(0,0,0,.72),inset 0 1px rgba(255,255,255,.06);backdrop-filter:blur(12px);transform-origin:bottom center;animation:wireRollOutCentre .34s cubic-bezier(.16,1,.3,1) both}
 body.feed-closing #v2feed{animation:wireRollInCentre .28s cubic-bezier(.4,0,.8,.4) both;pointer-events:none}
 body.feed-open #v2feedItems{display:flex;flex-direction:column;gap:5px;overflow-y:auto;overscroll-behavior:contain}
 body.feed-open #v2feedItems .feeditem{display:block;font-size:13px;line-height:1.32;padding:9px 10px 9px 13px}
 body.feed-open #v2feedItems .feeditem:nth-child(n+5){display:block}
 body.feed-open .feedhead{font-size:9px;padding-bottom:7px;border-bottom:1px solid rgba(210,180,104,.22)}
 body.feed-open #v2feedClose{display:block;padding:5px 8px;border:1px solid rgba(210,180,104,.35);border-radius:3px;background:rgba(0,0,0,.24);color:var(--paper);font:800 8px Barlow;letter-spacing:1.2px;cursor:pointer}
}
@media(min-width:1180px){
 /* v245 wide-table restraint: one console shell, no inset duplicate or floating frame caption. */
 #v2command::before,#v2command::after{display:none}
 #v2command{border-color:rgba(210,180,104,.3);border-top-color:rgba(210,180,104,.48)}
 /* Build 380 THE ONE TABLE AXIS (David 2026-09-01). A wide table reserves the Rival Ledger on the
    left and the deck rail on the right, so the felt the cards are dealt on is centred +68px to
    +138px right of the WINDOW centre. The console is fixed DOM chrome and had no way to know that,
    so the player's own portrait medallion - the thing every other centred element should be
    mirrored about - was the one element off the axis. It now spans the felt exactly: its left edge
    meets the ledger's gutter and its right edge meets the deck rail, which puts its middle grid
    column (the medallion) on `--m1-table-cx` by construction rather than by a tuned offset, and
    makes the console read as the base of the table instead of a bar bolted to the window. The two
    values are published by zones() on every solve (they carry a readable minimum half-width, so in
    the narrow sliver just above 1180 the console is a little wider than the felt - still centred on
    the same axis); the fallbacks reproduce the pre-380 geometry if the solver has not run yet.
    Height, rows, columns and the PASS control are untouched, so hudInsets() measures exactly what it
    measured before. Below 1180px there is no ledger, and desktopFrame() centres the felt's CONTENT
    on the window instead, so the console is already on the axis and needs no help - never add a
    second copy of this rule to a narrower breakpoint. */
 #v2command{left:var(--m1-console-left,16px);right:var(--m1-console-right-inset,16px)}
 /* The LIVE FLOOR panel rolls out of the Floor Wire, which is already lane-aligned to the felt
    (toastLaneEl publishes tableLeft/tableWidth on wide-ledger). It must leave from the same axis or
    the roll-out visibly starts off-centre from the wire that spawned it. */
 body.feed-open #v2feed{left:var(--m1-table-cx,50%);max-width:calc(100vw - 32px)}
}
#v2lead{position:static!important;display:none;min-width:0;max-width:100%;align-items:center;gap:4px;padding:2px 6px;border:1px solid rgba(107,78,20,.72);border-radius:999px;background:linear-gradient(180deg,#F2DFA8,#C9A24B);color:#172019;font:900 7px/1 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;box-shadow:inset 0 1px rgba(255,255,255,.55),0 2px 5px rgba(0,0,0,.28)}
#v2lead .leadCrown{font-size:9px;line-height:1}#v2lead .leadShort{display:none}
#v2badge{top:12px;right:14px;z-index:28}
/* Build 284 SETTINGS DOCK (David): on phone-portrait tables the full-width rival portrait row owns
   the entire top edge, so the compact Settings gear steps down out of that band. zones() computes
   the dock's solver-owned offset (below the pod block, clear of the rival fan) and publishes it as
   --setdock-top; when a compressed tier leaves no clear air, the class is removed and the gear
   returns to its corner. While the LIVE FLOOR history panel is open it would cover the docked gear,
   so the dock yields to the panel's CLOSE control. */
body.playing #v2badge.setDockBelow{top:var(--setdock-top,52px)}
body.feed-open #v2badge.setDockBelow{visibility:hidden}
#v2setB{width:auto;min-width:34px;height:36px;display:flex;align-items:center;justify-content:center;gap:8px;padding:7px 11px;border:1px solid rgba(210,180,104,.42);border-radius:3px;background:rgba(4,17,13,.9);color:var(--brass);cursor:pointer;box-shadow:0 5px 16px rgba(0,0,0,.3)}
#v2setB svg{width:16px;height:16px;fill:currentColor}
#v2setB span{font:800 9px Barlow;letter-spacing:1.5px;color:var(--paper)}
body.playing #v2setB{width:34px;padding:7px}body.playing #v2setB span{display:none}
#v2tray{bottom:86px;right:16px}
.v2mf{border-radius:3px;background:linear-gradient(180deg,#173b66,#0c2340);border-color:#4c8dff;box-shadow:0 3px 0 #071a30,0 8px 18px rgba(0,0,0,.42)}

/* Modals and results: engraved paper / lacquer */
/* FRONT-OF-HOUSE START */
#v2modal{background:rgba(5,19,14,.7);backdrop-filter:blur(7px)}
#v2mbox{border-radius:var(--r-chip);border-color:rgba(201,162,75,.48);background:linear-gradient(155deg,var(--ink-3),var(--ink));box-shadow:0 30px 80px rgba(0,0,0,.78),inset 0 1px rgba(255,255,255,.05)}
#v2mbox h3{color:var(--brass);font-size:var(--fs-24);letter-spacing:var(--ls-label)}
.v2opt{border-radius:var(--r-chip);border-color:rgba(201,162,75,.25);background:rgba(5,19,14,.82);color:var(--ivory)}
.v2opt:hover{border-color:var(--brass)}
.v2opt.gold{background:linear-gradient(180deg,var(--brass-hi),var(--brass));color:var(--ink-2)}
.v2opt.red{border-color:var(--danger);color:var(--crash)}
/* FRONT-OF-HOUSE END */
.resultbox{border-radius:6px!important;background:linear-gradient(165deg,#163e30,#061913)!important;border-color:rgba(210,180,104,.7)!important}
.resultHero{background:radial-gradient(100% 140% at 50% 0,rgba(210,180,104,.2),transparent 62%);border-color:var(--hairline)}
.resultKicker{color:var(--muted)}.resultTitle{font-family:'Bodoni Moda',serif;color:var(--ivory);letter-spacing:-1px}.resultCash{color:var(--brass);font-family:'Bodoni Moda',serif}

/* Show-don't-tell rules primer */
#v2mbox.rulesbox{width:min(920px,94vw);padding:18px 20px 20px;box-sizing:border-box;overflow:hidden}
.rulesPrimer h3{margin-bottom:10px!important}.rulesObjective{position:relative;padding:12px 18px 13px;text-align:center;border:1px solid rgba(210,180,104,.46);border-radius:4px;background:radial-gradient(80% 150% at 50% 0,rgba(210,180,104,.2),transparent 64%),#071a14;overflow:hidden}
.rulesObjective::before,.rulesObjective::after{content:"";position:absolute;top:0;bottom:0;width:1px;background:linear-gradient(transparent,var(--brass),transparent);opacity:.5}.rulesObjective::before{left:12px}.rulesObjective::after{right:12px}
.rulesObjective>span{display:block;font:800 8px Barlow;letter-spacing:3px;color:var(--muted)}
.rulesObjective>strong{display:block;margin-top:2px;font:400 clamp(25px,3.1vw,42px) 'Bebas Neue',sans-serif;letter-spacing:2px;color:var(--ivory);line-height:1}.rulesObjective>strong b{color:var(--brass);font-weight:400}
.millionRace{display:grid;grid-template-columns:28px 1fr 34px;align-items:center;gap:8px;width:min(560px,88%);margin:11px auto 0;color:var(--muted);font:800 9px Barlow;letter-spacing:.6px}
.millionRace i{font-style:normal}.raceFinish{color:var(--brass);font-size:11px}.raceRail{position:relative;height:5px;border-radius:5px;background:#020b08;border:1px solid rgba(210,180,104,.48);box-shadow:inset 0 1px 4px #000}
.raceRail::after{content:"";position:absolute;right:-2px;top:-6px;width:2px;height:15px;background:var(--ivory);box-shadow:4px 0 var(--brass)}
.raceWake{position:absolute;inset:0 auto 0 0;width:10%;border-radius:5px;background:linear-gradient(90deg,#2f8760,var(--brass));animation:raceWake 4.4s cubic-bezier(.22,.8,.22,1) infinite}
.raceRunner{position:absolute;z-index:2;left:0;top:50%;width:15px;height:15px;border-radius:50%;transform:translate(-50%,-50%);background:radial-gradient(circle at 35% 30%,#fff4c2,var(--brass) 42%,#6d4e0e 75%);box-shadow:0 0 0 3px rgba(210,180,104,.18),0 0 14px rgba(232,200,122,.65);animation:raceRunner 4.4s cubic-bezier(.22,.8,.22,1) infinite}
.rulesDemos{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:10px 0}
.ruleDemo{display:grid;grid-template-rows:105px auto;min-width:0;padding:8px 9px 10px;border:1px solid rgba(210,180,104,.23);border-radius:4px;background:linear-gradient(160deg,rgba(14,50,38,.94),rgba(3,16,12,.97));box-shadow:inset 0 1px rgba(255,255,255,.035)}
.ruleDemo>div:last-child{text-align:center}.ruleDemo b{display:block;font:400 17px 'Bebas Neue';letter-spacing:1.5px;color:var(--brass)}.ruleDemo span{display:block;margin-top:2px;font:600 10px Barlow;color:#afc0b8}
.demoStage{position:relative;height:105px;overflow:hidden;background:radial-gradient(circle at 50% 45%,rgba(91,164,124,.15),transparent 62%)}
.demoStage i{position:absolute;display:block;box-sizing:border-box;font-style:normal}
.miniDeck,.movingCard,.miniSlot,.miniCareer,.hiddenCard{width:42px;height:60px;border-radius:5px}
.miniDeck{left:16%;top:22px;background:#11294a;border:2px solid #4d63ad;box-shadow:4px 4px 0 #071528,8px 8px 0 rgba(77,99,173,.25)}
.miniDeck::after{content:"C";position:absolute;inset:0;display:grid;place-items:center;font:400 23px 'Bebas Neue';color:#9db8e8}
.miniSlot{right:13%;top:20px;border:2px dashed rgba(232,200,122,.5);background:rgba(232,200,122,.05);box-shadow:0 0 14px rgba(232,200,122,.12)}
.movingCard{left:18%;top:22px;z-index:3;background:linear-gradient(#2a6ba8 0 55%,#122c52 55%);border:2px solid #76aeed;box-shadow:0 8px 16px rgba(0,0,0,.55);animation:demoDraw 3.8s cubic-bezier(.2,.8,.2,1) infinite}
.miniCareer{left:15%;top:18px;background:linear-gradient(#368a61 0 55%,#123f2e 55%);border:2px solid #6fe3a5;box-shadow:0 8px 16px rgba(0,0,0,.5)}
.movingGem{right:18%;top:40px;z-index:3;width:25px;height:25px;display:grid!important;place-items:center;border-radius:6px;background:#f3d27a;border:2px solid #fff1bd;color:#251a04;font:900 12px Barlow;animation:demoAttach 3.8s cubic-bezier(.2,.8,.2,1) infinite}
.coin{left:29%;top:20px;width:21px;height:21px;display:grid!important;place-items:center;border-radius:50%;background:linear-gradient(#f7e4a6,#b78925);border:1px solid #fff0bb;color:#3b2906;font:900 11px Barlow;opacity:0;animation:demoCoin 3.8s ease-out infinite}.coin.c2{left:43%;animation-delay:.12s}.coin.c3{left:57%;animation-delay:.24s}
.rivalCoin{top:36px;width:35px;height:35px;border-radius:50%;background:radial-gradient(circle at 50% 40%,#c79a71 0 24%,#1b4e3d 25% 61%,#d2b468 63% 69%,#071a14 70%);border:1px solid rgba(245,239,221,.5)}.rivalCoin.r1{left:8%}.rivalCoin.r2{right:8%}
.hiddenCard{left:50%;top:20px;transform:translateX(-50%);display:grid!important;place-items:center;background:#11294a;border:2px solid #4d63ad;color:#9db8e8;font:400 24px 'Bebas Neue';box-shadow:0 8px 16px rgba(0,0,0,.55)}
.scanBeam{left:13%;top:6px;width:2px;height:91px;background:linear-gradient(transparent,#8fc5f2,transparent);box-shadow:0 0 11px 3px rgba(143,197,242,.36);animation:demoScan 3.8s ease-in-out infinite}
.reportStamp{left:50%;top:48px;z-index:4;transform:translate(-50%,-50%) rotate(-8deg) scale(1.7);padding:3px 6px;border:2px solid #e85c5c;color:#ff9999;font:900 9px Barlow;letter-spacing:1px;opacity:0;animation:demoStamp 3.8s ease infinite}
.rulesMicro{display:flex;align-items:center;justify-content:center;gap:10px;min-height:30px;padding:5px 10px;border-top:1px solid rgba(210,180,104,.28);border-bottom:1px solid rgba(210,180,104,.18);text-align:center;font:700 9px Barlow;color:#aabbb3;letter-spacing:.3px}.rulesMicro b{color:var(--ivory);letter-spacing:1px}.rulesMicro i{width:4px;height:4px;border-radius:50%;background:var(--brass)}
.rulesTip{text-align:center;margin:8px 0 6px;font:600 10px Barlow;color:var(--muted)}
/* v170: the CARD GUIDE entry. Build 169 used a bare .v2opt here and it rendered as a thin
   left-aligned strip that read as a caption, not a control — David could not find the feature at
   all. It is now unmistakably a button: full width, gold rule, two lines and a chevron. */
.rulesGuide{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"title chevron" "sub chevron";align-items:center;column-gap:12px;width:100%;min-height:56px;margin:0 0 8px;padding:10px 14px;cursor:pointer;text-align:left;border:1px solid #C9A24B;border-radius:10px;background:linear-gradient(180deg,rgba(232,200,122,.16),rgba(201,162,75,.07))}
.rulesGuide:hover{background:linear-gradient(180deg,rgba(232,200,122,.26),rgba(201,162,75,.12))}
.rulesGuide:active{transform:translateY(1px)}
.rulesGuide b{grid-area:title;align-self:end;font:900 16px/1.15 'Bebas Neue',Barlow,sans-serif;letter-spacing:.09em;color:#E8C87A}
.rulesGuide span{grid-area:sub;align-self:start;margin-top:2px;font:600 11.5px/1.35 Barlow,sans-serif;color:#cfe2d6}
.rulesGuide i{grid-area:chevron;align-self:center;font-style:normal;font-size:26px;line-height:1;color:#E8C87A}
.rulesGo{margin-top:0!important;text-align:center!important;font-size:17px!important;letter-spacing:1.5px!important}.rulesMore{text-align:center!important}
@keyframes raceRunner{0%,12%{left:0}72%,88%{left:100%}100%{left:0}}@keyframes raceWake{0%,12%{width:0}72%,88%{width:100%}100%{width:0}}
@keyframes demoDraw{0%,12%{left:18%;transform:rotate(-5deg) scale(.9);opacity:0}22%{opacity:1}65%,88%{left:72%;transform:rotate(0) scale(1);opacity:1}100%{left:72%;opacity:0}}
@keyframes demoAttach{0%,16%{right:18%;transform:scale(1)}58%,88%{right:66%;transform:scale(.72)}94%,100%{right:66%;transform:scale(.72);opacity:0}}
@keyframes demoCoin{0%,55%{transform:translateY(20px) scale(.5);opacity:0}67%{opacity:1}90%{transform:translateY(-26px) scale(1);opacity:0}100%{opacity:0}}
@keyframes demoScan{0%,12%{left:13%;opacity:0}22%{opacity:1}68%{left:86%;opacity:1}78%,100%{left:86%;opacity:0}}
@keyframes demoStamp{0%,62%{opacity:0;transform:translate(-50%,-50%) rotate(-8deg) scale(1.7)}69%,88%{opacity:1;transform:translate(-50%,-50%) rotate(-8deg) scale(1)}100%{opacity:0}}

body.previewing #v2command,body.inspecting #v2command,body.planning #v2command{visibility:hidden!important}
/* 2026-08-09 net-worth flicker fix: the HUD hide above also took the net worth with it, so the number blinked off every time a card was previewed/planned (measured ~6 flips in 8s, desktop and mobile alike). visibility is inheritable and a child may re-show itself, so the readout stays put while the rest of the bar still clears. */
body.previewing .commandWorth,body.inspecting .commandWorth,body.planning .commandWorth{visibility:visible!important}
body.previewing #v2ticker,body.inspecting #v2ticker{opacity:.28}

@media(max-width:900px){
 #v2ticker{left:8px;right:52px;top:7px;width:auto;min-height:46px;transform:none;padding:6px 8px 6px 13px;grid-template-columns:auto 6px minmax(0,1fr) auto}
 body.playing #v2ticker{animation:wireDropCompact .35s ease-out both}
 @keyframes wireDropCompact{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}
 .wireLabel{font-size:9px}#v2msg{font-size:13.5px}
 #v2command{--console-end:96px;height:88px;bottom:10px;gap:14px;padding:6px 10px;left:calc(16px + env(safe-area-inset-left,0px));right:calc(16px + env(safe-area-inset-right,0px))}/* Build 376: curved-screen guard — the whole console steps in past the rounded corners and any landscape notch */
 .commandLabel{font-size:10.5px;letter-spacing:1.9px}.goalrow{font-size:11px;margin-bottom:7px}.goaltrack{height:8px}
 #v2nw{font-size:36px}#v2act{font-size:17px;gap:9px}.actpips{gap:6px}.apip{width:9px;height:9px}.turnclock{font-size:14px;min-width:34px;padding:3px 6px}#v2end{height:60px;font-size:18px}
 #v2feed{display:none}#v2feedToggle{display:flex}
 body.feed-open #v2feed{display:flex;left:10px;right:10px;top:auto;bottom:calc(100vh - var(--floor-wire-y,50vh) + 28px);width:auto;max-height:min(46vh,calc(var(--floor-wire-y,50vh) - 36px),330px);overflow:hidden;gap:8px;padding:12px;box-sizing:border-box;pointer-events:auto;z-index:24;border:1px solid rgba(210,180,104,.55);border-radius:5px;background:linear-gradient(155deg,rgba(10,39,29,.985),rgba(3,15,11,.99));box-shadow:0 22px 55px rgba(0,0,0,.72),inset 0 1px rgba(255,255,255,.06);backdrop-filter:blur(12px);transform-origin:bottom center;animation:wireRollOut .34s cubic-bezier(.16,1,.3,1) both}
 body.feed-closing #v2feed{animation:wireRollIn .28s cubic-bezier(.4,0,.8,.4) both;pointer-events:none}
 body.feed-open #v2feedItems{display:flex;flex-direction:column;gap:5px;overflow-y:auto;overscroll-behavior:contain}body.feed-open #v2feedItems .feeditem{display:block;font-size:13px;line-height:1.32;padding:9px 10px 9px 13px}body.feed-open #v2feedItems .feeditem:nth-child(n+5){display:block}
 /* Build 331: v3.js sizes this scrollport to the newest three complete actions. Older actions stay
    directly below them and become visible by scrolling; none are hidden or cut from history. */
 body.feed-open .feedhead{font-size:9px;padding-bottom:7px;border-bottom:1px solid rgba(210,180,104,.22);align-items:center}body.feed-open #v2feedClose{display:block;min-width:74px;min-height:44px;padding:0 14px;border:1px solid rgba(210,180,104,.55);border-radius:7px;background:rgba(0,0,0,.32);color:var(--paper);font:800 12px Barlow;letter-spacing:1.6px;cursor:pointer}
}

@media(max-width:900px) and (orientation:portrait){
 /* Build 374 — THE ARCH TIER. Every PORTRAIT phone and tablet gets the same silhouette; the
    plate's height, crown and medallion are one proportional family published by zones() as
    --console-h / --console-arch-px / --console-av-px, so a 390x844 iPhone, a 360x640 Android and
    a 768x1024 tablet differ in pixels and never in ratio (David 2026-09-01: "scale it
    appropriately for all mobile phone sizes such that the ratios are the same"). */
 #v2command{--console-end:96px;--console-arch:var(--console-arch-px,30px);height:var(--console-h,92px);left:0;right:0;bottom:0;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);grid-template-rows:1fr;gap:0 10px;padding:0 12px env(safe-area-inset-bottom,0px);border:none;border-radius:0;background:none;box-shadow:none;backdrop-filter:none}
 .commandArch{display:block}
 #v2command::before,#v2command::after{display:none}/* the arch IS the frame and the caption; the rectangular inset rule and EXCHANGE CONTROL plate belong to the desktop bar */
 .commandTurn>.commandLabel{display:none}
 .commandTurn{padding-right:calc(var(--console-end) + 10px + env(safe-area-inset-right,0px))}#v2command #v2act{font-size:14px}
 /* Build 376 (David): phone screens are rounded, so the two corner readouts step inward — PASS off the right curve, NET WORTH off the left — without eating the turn lane or the medallion. */
 #v2command #v2end{right:calc(14px + env(safe-area-inset-right,0px))}
 .commandWorth{box-sizing:border-box;padding-left:calc(6px + env(safe-area-inset-left,0px))}
 /* ONE FACT, ONE LINE. A live sentence broken across two lines mid-phrase reads as a bug, so this
    lane never wraps: the state word owns row one, the pips and the clock own row two, and the copy
    is short enough at every supported width that the ellipsis is a last resort, not the norm. */
 #v2act{flex-wrap:wrap;row-gap:3px;overflow:visible}
 #v2act .actlabel{flex:1 0 100%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;line-height:1.1}
 #v2nw{font-size:clamp(28px,4.6vw,36px)}
/* FRONT-OF-HOUSE START */
 #v2title{gap:7px}
 .ttmodes{display:flex;flex-direction:column;width:min(520px,86vw);gap:10px;margin-top:12px}
 .ttmodes>.ttmode{flex:0 0 auto;max-width:none;width:100%}/* the stacked list is full width again - the row's basis and cap belong to the row */
 .ttmode,.ttmode.gold{min-height:82px;grid-template-columns:42px 1fr auto;padding:11px 16px;font-size:var(--fs-20)}
 .ttmode small{font-size:var(--fs-14);line-height:1.25;margin-top:4px}.ttmode>b{font-size:var(--fs-11)}.modeIcon{width:34px;height:42px}
 .tttag{font-size:var(--fs-12)}
/* FRONT-OF-HOUSE END */
}
@media(max-width:700px){
 #v2mbox.rulesbox{width:94vw;max-height:94vh;padding:13px 12px 14px;overflow-y:auto}.rulesPrimer h3{font-size:20px!important;margin-bottom:7px!important}.rulesObjective{padding:9px 10px 10px}.rulesObjective>strong{font-size:27px}.millionRace{margin-top:8px}.rulesDemos{grid-template-columns:1fr;gap:6px;margin:7px 0}.ruleDemo{grid-template-columns:91px 1fr;grid-template-rows:72px;align-items:center;padding:4px 7px}.demoStage{height:70px;transform:scale(.68);transform-origin:center}.ruleDemo>div:last-child{text-align:left}.ruleDemo b{font-size:15px}.ruleDemo span{font-size:9.5px}.rulesMicro{flex-wrap:wrap;gap:5px 7px;padding:6px;font-size:8.5px}.rulesMicro i{display:none}.rulesTip{font-size:9px;margin:6px}.rulesGo{min-height:42px!important}.rulesGuide{min-height:52px;padding:8px 11px}.rulesGuide b{font-size:15px}.rulesGuide span{font-size:10.5px}
/* FRONT-OF-HOUSE START */
 #v2title{justify-content:center;gap:5px;padding:15px 0;box-sizing:border-box}
 #v2title::before,#v3lobby::before{inset:8px}
 .titleArchitecture{width:76vw}.titleArchitecture b{font-size:var(--fs-11)}.ttEyebrow{font-size:var(--fs-11);letter-spacing:var(--ls-eyebrow)}.ttSeal{width:40px;height:40px}.ttSeal span{font-size:var(--fs-20)}
 .tt1{font-size:clamp(42px,13vw,60px);letter-spacing:var(--ls-eyebrow)}.tt2{font-size:var(--fs-16);letter-spacing:var(--ls-eyebrow);text-indent:8px;padding-top:5px}.tttag{font-size:var(--fs-11);line-height:1.25;letter-spacing:var(--ls-eyebrow)}.tttag i{padding:0 5px}
 .ttmodes{display:flex;flex-direction:column;gap:8px;width:min(380px,90vw);margin-top:6px}.ttmodes>.ttmode{flex:0 0 auto;max-width:none;width:100%}.ttmode,.ttmode.gold{min-height:72px;grid-template-columns:36px 1fr auto;padding:10px 12px;font-size:var(--fs-20)}.modeIcon{width:30px;height:38px}.ttmode small{margin-top:4px;font-size:var(--fs-12)}.ttmode>b{font-size:var(--fs-11)}.ttVersion{margin-top:0;font-size:var(--fs-11);letter-spacing:var(--ls-eyebrow)}
 .lbCard{width:94vw;max-height:94vh;padding:16px 14px 12px;box-sizing:border-box}.lbHead span{font-size:var(--fs-16)}.lbHead b{font-size:var(--fs-14)}.lbIntro{margin:12px 0 4px;align-items:flex-start}.lbIntro strong{font-size:var(--fs-20)}.lbIntro span{max-width:58%;font-size:var(--fs-11)}.lbIdent{gap:8px;padding:9px}#lbMyAv{width:58px;height:58px}.lbAvBtn{width:27px;height:27px}#lbName{font-size:var(--fs-14);padding:11px}
 #lbSeats{grid-template-columns:repeat(auto-fit,minmax(88px,1fr))}.lbSeat{--seatBadgeLane:17px;min-height:99px;padding:var(--seatBadgeLane) 4px 7px}.lbSeat img{width:44px;height:44px}.lbCred{gap:5px;margin-top:6px;padding-top:5px}.lbCred .mRing{min-width:17px;height:17px;font-size:var(--fs-11)}.lbCred .crTrophy,.lbCred .crHouse{width:17px;height:17px}.lbSeat.founder::before{left:3px;top:3px;width:37px;height:12px;font-size:var(--fs-11)}/* Build 347: the badge lane travels with every seat-card override, or the phone breakpoint - the one David photographed - silently takes it away again. */#lbReady{font-size:var(--fs-20);padding:12px}
/* FRONT-OF-HOUSE END */
 #v2ticker{left:7px;right:48px;top:6px;width:auto;min-height:44px;transform:none;grid-template-columns:auto 6px minmax(0,1fr) auto;padding:5px 6px 5px 9px;gap:7px}.wireLabel{font-size:8px;letter-spacing:1.4px}#v2msg{font-size:12px;line-height:1.2;text-align:left;padding:0}.wirePulse{width:5px;height:5px}#v2feedToggle{min-width:36px;height:28px;padding:0 5px}#v2feedToggle span{font-size:7px}
 body.playing #v2ticker{animation:wireDropMobile .35s ease-out both}
 @keyframes wireDropMobile{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:none}}
 #v2command{--console-end:78px;left:0;right:0;bottom:0;height:var(--console-h,78px);gap:0 9px;padding:0 8px env(safe-area-inset-bottom,0px);border-radius:0} /* v107: trimmed — every saved px goes to the board */
 #v2command::after{display:none}.commandWorth .commandLabel{font-size:8px}.commandTurn>.commandLabel{display:none}
 #v2nw{font-size:clamp(22px,6vw,30px)}.goalrow{display:flex!important;font-size:11px;margin-bottom:4px}#v2goal{align-self:end}.goaltrack{height:6px}
 #v2act{font-size:12px;gap:4px}.actlabel{flex:1 0 100%;white-space:nowrap}.actpips{gap:3px}.apip{width:7px;height:7px}.turnclock{min-width:25px;padding:2px 4px;font-size:11px}
 #v2end{height:50px;font-size:15px;padding:0 5px;right:calc(14px + env(safe-area-inset-right,0px))}/* Build 376: clears the rounded corner */
 .commandWorth{box-sizing:border-box;padding-left:calc(6px + env(safe-area-inset-left,0px))}
 #v2feed{display:none}#v2tray{bottom:91px;right:8px}#v2badge{top:6px;right:6px}#v2setB{width:34px;height:30px;padding:7px}
}
/* ===== v104 COMPACT PHONE MODE (David: the board must FIT a real phone browser viewport —
   iPhone-Pro-with-Safari-chrome is the PRIMARY design target, no scrolling). Slimmer console +
   wire; zones() reclaims the rest (thumbs/deck/gaps). Buttons stay ≥44px touch targets. ===== */
@media (max-width:480px) and (orientation:portrait){
 /* v110 SNAP CONSOLE (chromeless, David's ruling): no bar, no border, no blur — net worth,
    action pips and PASS float directly on the felt. v108's LAW still stands: phone #v2command
    height/rows are declared HERE and NOWHERE ELSE (this bar was silently re-fattened twice by
    later blocks). hudInsets() measures whatever wins the cascade — the board pays every px. */
 #v2command{--console-end:52px;--console-arch:var(--console-arch-px,26px);height:var(--console-h,70px);bottom:0;left:0;right:0;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);grid-template-rows:1fr;gap:0 5px;padding:0 4px env(safe-area-inset-bottom,0px) 11px;border:none;border-radius:0;background:none;box-shadow:none;backdrop-filter:none}
 .commandIdentity.houseMarked{width:calc(var(--console-av) + 46px)}.commandHouse{--command-house-size:16px}.commandHouse::after{width:4px}
 #v2command::before,#v2command::after{display:none}
 body.playing #v2command{animation:none}
 .commandTurn{padding-right:calc(var(--console-end) + 12px + env(safe-area-inset-right,0px))}/* Build 376: grows with PASS's new curve clearance so the lanes still never touch */
 /* the MOBILE READABILITY block further down this sheet re-sizes #v2act and .turnclock for every
    <=700px screen; the phone's centred console needs the compact pair, so it asks by id. */
 #v2command #v2act{font-size:10.5px;gap:0 4px}#v2act .actlabel{font-size:8.5px;letter-spacing:.4px}
 #v2act .actpips{gap:2px}#v2act .turnclock{min-width:18px;padding:1px 2px;font-size:10.5px}
 /* the <=700 readability block below raises every button to 18px; the phone's corner control
    carries DISCARD n as well as PASS, so it asks for its own size by id rather than being clipped. */
 #v2command #v2end{right:calc(11px + env(safe-area-inset-right,0px));height:48px;width:var(--console-end);font-size:12.5px;line-height:1.06;white-space:normal;padding:0 3px}
 #v2command.waitState{--console-end:36px}#v2command.waitState .commandTurn{padding-right:calc(var(--console-end) + 10px + env(safe-area-inset-right,0px))}
 /* Build 284: the "?" entrance is retired, so the badge holds only the compact Settings gear.
    Its in-match position is solver-owned (see the Settings dock rules beside #v2badge above). */
 .commandWorth .commandLabel{font-size:7px}
 /* Build 376: NET WORTH sits in the bottom-left rounded corner on a phone; this steps the whole readout (label, number and goal bar) inward off the curve. */
 .commandWorth{box-sizing:border-box;padding-left:calc(7px + env(safe-area-inset-left,0px))}
 #v2lead{padding:1px 4px;gap:3px;font-size:6.5px;letter-spacing:.7px}#v2lead .leadLong{display:none}#v2lead .leadShort{display:inline}#v2lead .leadCrown{font-size:8px}
 /* v235 (Founder feedback 8 Aug, small iPhone: "$40,000 read as $10,000 — the cross lines on the
    4 were too small to see"): Bodoni's hairline strokes vanish at this size. Small phones swap
    the readout to heavy Barlow Semi Condensed and gain 2px — digits first, calligraphy on
    bigger screens (§3.11: readable beats pretty). */
 #v2nw{font:800 clamp(18px,5.2vw,23px)/.95 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:0;text-shadow:0 2px 6px #000;font-variant-numeric:tabular-nums}
 #v2act{font-size:10.5px;gap:3px}
 /* Build 285 asked that the phone's rival-turn copy be READABLE and keep its explicit LEFT word.
    13.5px served that in a lane about 140px wide. Beside Build 374's centred portrait the lane is
    ~83px, and 13.5px no longer FITS - it clips, which fails the very law it was written for. 11px is
    the project's own floor for control text, keeps every word, and clears the lane with room. */
 #v2act .actlabel.rival{font-size:11px;letter-spacing:.2px}.apip{width:6px;height:6px}.turnclock{min-width:23px;padding:1px 3px;font-size:10.5px}
 /* v130: mobile keeps the exact v119 unified notice; the hidden legacy sink never enters layout */
 #v2tray{bottom:60px}
}
/* v130 unified table notice; phone size, styling and live solver placement are unchanged from v119 */
#v2toastLane{position:fixed;left:12px;right:12px;z-index:26;display:flex;align-items:center;justify-content:center;transform:translateY(-50%);pointer-events:none;transition:opacity .14s ease-out}
.floor-wire-yield #v2toastLane{opacity:0;pointer-events:none}
.floor-wire-yield #v2toastLane .v2toast{pointer-events:none}
.v2toast{display:block;max-width:95vw;min-height:42px;padding:10px 20px;box-sizing:border-box;appearance:none;overflow:hidden;border:1px solid rgba(210,180,104,.58);border-radius:22px;background:rgba(4,17,13,.96);color:#F5EFDD;font:700 15px/1.3 Barlow;text-align:center;text-overflow:ellipsis;white-space:nowrap;box-shadow:0 9px 24px rgba(0,0,0,.44),inset 0 1px rgba(255,255,255,.045);pointer-events:auto;cursor:pointer;animation:v2toastIn .2s ease-out both}
.toastMark{display:none}.toastCopy{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.v2toast.turn{border-color:rgba(111,227,165,.65);color:#c8f4db}
.v2toast.explain{border-color:rgba(226,61,61,.8);background:rgba(38,9,12,.96);color:#f2b8bd}
.v2toast.audio{border-color:rgba(232,200,122,.92);background:rgba(28,21,7,.97);color:#fff0bd;box-shadow:0 9px 26px rgba(0,0,0,.5),0 0 0 1px rgba(232,200,122,.16),inset 0 1px rgba(255,255,255,.08)}
.v2toast.out{animation:v2toastOut .24s ease-in both}
.v2toast:focus-visible{outline:2px solid #E8C87A;outline-offset:2px}
#v2toastLane[data-persistent="true"] .v2toast{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:10px;width:min(560px,100%);min-height:44px;max-height:56px;padding:7px 13px;border-radius:6px;text-align:left;animation:none;transition:background .18s ease,border-color .18s ease,opacity .18s ease}
#v2toastLane[data-persistent="true"] .toastMark{display:flex;align-items:center;gap:6px;padding-right:10px;border-right:1px solid rgba(210,180,104,.24);color:#C9A24B;font:800 7px/1 Barlow;letter-spacing:1.25px;white-space:nowrap}
#v2toastLane[data-persistent="true"] .toastMark::before{content:"";width:5px;height:5px;border-radius:50%;background:#C9A24B;box-shadow:0 0 7px rgba(210,180,104,.45)}
#v2toastLane[data-persistent="true"] .toastCopy{font:700 13px/1.2 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:.1px}
#v2toastLane[data-persistent="true"] .v2toast.idle{opacity:.82;border-color:rgba(210,180,104,.3)}
#v2toastLane[data-persistent="true"] .v2toast.idle .toastCopy{color:#9db4a9;font-weight:600}
@media(max-width:700px){
 #v2toastLane[data-persistent="true"] .v2toast{width:100%;height:44px;min-height:44px;max-height:44px;padding:6px 10px;gap:8px}
 #v2toastLane[data-persistent="true"] .toastMark{padding-right:8px;font-size:6.5px;letter-spacing:1px}
 #v2toastLane[data-persistent="true"] .toastCopy{font-size:12.5px;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}
}
@keyframes v2toastIn{from{opacity:0;transform:translateY(7px) scale(.94)}to{opacity:1;transform:none}}
@keyframes v2toastOut{to{opacity:0;transform:translateY(-7px)}}
@media(min-width:1180px){
 #v2toastLane[data-placement="reserved-ownership-band"]{box-sizing:border-box;padding:0 8px}
  #v2toastLane[data-placement="reserved-ownership-band"] .v2toast{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:center;gap:13px;width:min(900px,72%);max-width:none;min-height:48px;max-height:56px;padding:8px 15px;border-color:rgba(210,180,104,.5);border-radius:6px;background:linear-gradient(180deg,rgba(8,31,23,.985),rgba(3,16,12,.985));text-align:left;box-shadow:0 10px 26px rgba(0,0,0,.46),inset 0 1px rgba(255,255,255,.045)}
 #v2toastLane[data-placement="reserved-ownership-band"] .toastMark{display:flex;align-items:center;gap:7px;padding-right:13px;border-right:1px solid rgba(210,180,104,.24);color:#C9A24B;font:800 8px/1 Barlow;letter-spacing:1.7px;white-space:nowrap}
 #v2toastLane[data-placement="reserved-ownership-band"] .toastMark::before{content:"";width:6px;height:6px;border-radius:50%;background:#C9A24B;box-shadow:0 0 8px rgba(210,180,104,.45)}
  #v2toastLane[data-placement="reserved-ownership-band"] .toastCopy{font:700 clamp(14px,calc(11px + .35vw),20px)/1.22 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:.15px}
 #v2toastLane[data-placement="reserved-ownership-band"] .v2toast.explain{background:linear-gradient(180deg,rgba(42,14,17,.985),rgba(22,8,10,.985));border-color:rgba(226,61,61,.68)}
 #v2toastLane[data-placement="reserved-ownership-band"] .v2toast.explain .toastMark{color:#E5A0A4;border-right-color:rgba(226,61,61,.28)}
 #v2toastLane[data-placement="reserved-ownership-band"] .v2toast.explain .toastMark::before{background:#E23D3D;box-shadow:0 0 8px rgba(226,61,61,.48)}
 #v2toastLane[data-placement="reserved-ownership-band"] .v2toast.explain .toastCopy{display:-webkit-box;white-space:normal;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
}

@media(max-height:650px) and (min-width:701px){
/* FRONT-OF-HOUSE START */
 #v2title{gap:4px}.ttSeal{width:37px;height:37px}.tt1{font-size:var(--fs-48)}.ttmodes{margin-top:3px}.ttmode,.ttmode.gold{min-height:72px}
 .lbCard{max-height:96vh;padding-top:15px}.lbIntro{display:none}.lbJoinIntro{margin:6px 0 0}.lbJoinIntro span{display:none}.lbJoinIntro::after{margin-top:8px}.lbJoinIdent{margin-top:10px}.lbJoinCode{margin-top:10px}
/* FRONT-OF-HOUSE END */
 #v2command{--console-end:80px;height:58px;bottom:8px}.commandLabel{font-size:6px}#v2nw{font-size:23px}#v2tray{bottom:76px}
 #v2toastLane[data-placement="reserved-ownership-band"] .v2toast{min-height:42px;max-height:42px;padding:6px 12px;gap:9px}
 #v2toastLane[data-placement="reserved-ownership-band"] .toastMark{padding-right:9px;font-size:7px}
 #v2toastLane[data-placement="reserved-ownership-band"] .v2toast.explain .toastCopy{display:block;white-space:nowrap;text-overflow:ellipsis}
}

@media(prefers-reduced-motion:reduce){
 .wirePulse,.ttEyebrow,.ttSeal,.tt1,.tt2,.tttag,.ttmodes,.ttVersion,.lbCard,body.playing #v2ticker,body.playing #v2command,.raceWake,.raceRunner,.movingCard,.movingGem,.coin,.scanBeam,.reportStamp{animation:none}.ttmode,.goalfill,.apip{transition:none}.raceRunner{left:100%}.raceWake{width:100%}.movingCard{left:72%;opacity:1}.movingGem{right:66%}.reportStamp{opacity:1;transform:translate(-50%,-50%) rotate(-8deg) scale(1)}
}

/* ==================================================================
   MOBILE READABILITY + TACTILE SYSTEM
   Hard rules: no control text below 11px; no interactive target below
   44px; panels fit the viewport before content is allowed to scroll.
   ================================================================== */
button,.v2opt,.ttmode,#lbReady,.lbContinue,.lbAvatarChoice,.lbStepper button{
 touch-action:manipulation;transform-origin:center;transition:transform 90ms ease-out,filter 120ms ease,border-color 120ms ease,box-shadow 120ms ease
}
button.tactile-down,.v2opt.tactile-down{transform:translateY(2px) scale(.96)!important;filter:brightness(.96)}
button.tactile-release,.v2opt.tactile-release{animation:tactileRelease 140ms cubic-bezier(.34,1.56,.64,1)}
@keyframes tactileRelease{0%{transform:translateY(2px) scale(.96)}65%{transform:translateY(-1px) scale(1.025)}100%{transform:none}}

/* Two short lobby steps use the available area instead of shrinking copy. */
/* FRONT-OF-HOUSE START */
.lbCard{width:min(760px,96vw);box-sizing:border-box;overflow-x:hidden;overscroll-behavior:contain}
.lbSteps{display:grid;grid-template-columns:minmax(0,1fr) 42px minmax(0,1fr);align-items:center;gap:8px;margin:14px 0 8px}
.lbSteps>i{height:1px;background:linear-gradient(90deg,rgba(201,162,75,.15),rgba(201,162,75,.65),rgba(201,162,75,.15))}
.lbSteps button{min-height:44px;border:0;background:none;color:var(--muted);display:flex;align-items:center;justify-content:center;gap:8px;font:800 12px Barlow;letter-spacing:var(--ls-eyebrow);cursor:pointer}
.lbSteps button b{display:grid;place-items:center;width:26px;height:26px;border:1px solid rgba(201,162,75,.32);border-radius:50%;font-size:var(--fs-12);color:var(--muted)}
.lbSteps button.on{color:var(--paper)}.lbSteps button.on b{background:var(--brass);border-color:var(--brass);color:var(--ink-2);box-shadow:0 0 18px rgba(201,162,75,.2)}
/* Build 396 — The Climb is a mode, not a two-step table wizard. Identity remains editable in the
   profile; this screen only confirms the equipped seat before the player enters the current Circle. */
body.climbFlow .lbCard{width:min(1040px,96vw)}
body.climbFlow .lbSteps,body.climbFlow .lbSetupIntro{display:none}
.lbSoloIdentity{display:grid;grid-template-columns:40px minmax(0,1fr);align-items:center;gap:10px;margin:-4px 0 7px;padding:6px 10px;border-left:2px solid rgba(232,200,122,.46);background:linear-gradient(90deg,rgba(232,200,122,.07),transparent 55%)}
.lbSoloIdentity[hidden]{display:none}.lbSoloIdentity .seatAv{margin:0}.lbSoloIdentity img{display:block;width:38px;height:38px;border:1px solid rgba(232,200,122,.64);border-radius:50%;object-fit:cover}.lbSoloIdentity .mRing{min-width:17px;height:17px;font-size:var(--fs-11)}
.lbSoloWho{display:grid;gap:2px;min-width:0}.lbSoloWho small{color:var(--muted);font:800 11px Barlow;letter-spacing:var(--ls-eyebrow)}.lbSoloWho b{overflow:hidden;color:var(--paper);font:800 11px Barlow;letter-spacing:var(--ls-label);text-overflow:ellipsis;white-space:nowrap}
.lbStep{display:none;min-width:0}.lbStep.on{display:block;animation:lbStepIn 260ms cubic-bezier(.2,.8,.25,1) both}
@keyframes lbStepIn{from{opacity:0;transform:translateX(12px)}to{opacity:1;transform:none}}
.lbIdent{display:grid;grid-template-columns:86px minmax(120px,.72fr) minmax(220px,1fr);align-items:center;gap:14px;min-width:0}
#lbMyAv{width:82px;height:82px;object-fit:cover;border-radius:50%;grid-row:1/2}
.lbIdentityCopy{display:flex;flex-direction:column;min-width:0}.lbIdentityCopy strong{font:400 24px 'Bebas Neue';letter-spacing:var(--ls-label);color:var(--paper);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.lbIdentityCopy span{font:600 12px/1.3 Barlow;color:var(--muted)}
#lbName{width:100%;min-width:0;min-height:48px;box-sizing:border-box}
/* ══ BUILD 402 — SETTINGS IS BUILT FROM THE TOKEN COMPONENTS (PLAN §2.4 / §4.7) ══════════════
   The v200 ledger shape David approved is unchanged - label left, state right, hairline rules, no
   boxed rows, no explainer captions - but it is no longer a bespoke .set* family. The rows are the
   shared .row / .pill / .slider components declared once in meta.css, so Settings, the friends
   list and every later page draw the same row. The VOICE PACK chooser and the VOICE COLLECTION
   row are GONE from this sheet: the Collection owns every cosmetic (PLAN D4). Behaviour is
   untouched - Build 378's one-switch-per-channel rules and every handler are exactly as they were. */
.voiceTierTitle{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:14px 0 6px;padding-bottom:5px;border-bottom:1px solid rgba(201,162,75,.2)}.voiceTierTitle b{color:var(--brass);font:800 11px Barlow;letter-spacing:var(--ls-eyebrow)}.voiceTierTitle span{color:var(--muted);font:800 11px Barlow;letter-spacing:var(--ls-label)}
.lbAvatarGrid{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:8px;margin:10px 0}
.lbAvatarChoice{position:relative;min-width:0;min-height:92px;padding:6px 4px 5px;border:1px solid rgba(201,162,75,.2);border-radius:var(--r-chip);background:rgba(5,19,14,.62);color:var(--paper);cursor:pointer;overflow:hidden}
.lbAvatarChoice img{display:block;width:60px;height:60px;max-width:100%;margin:0 auto 4px;border-radius:50%;object-fit:cover;border:2px solid rgba(201,162,75,.25);box-sizing:border-box}
.lbAvatarChoice span{display:block;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font:800 11px Barlow;letter-spacing:0}
.lbAvatarChoice.on{border-color:var(--brass);background:rgba(18,53,40,.82);box-shadow:inset 0 -3px var(--brass),0 0 18px rgba(201,162,75,.13)}.lbAvatarChoice.on img{border-color:var(--brass)}
.lbAvatarChoice.locked{border-color:rgba(201,162,75,.48);background:linear-gradient(155deg,rgba(18,53,40,.62),rgba(5,19,14,.78))}.lbAvatarChoice.locked img{filter:saturate(.68) brightness(.78);border-color:rgba(232,200,122,.62)}.lbAvatarChoice.locked::after{content:"🔒";position:absolute;top:6px;right:6px;display:grid;place-items:center;width:23px;height:23px;border:1px solid rgba(232,200,122,.65);border-radius:50%;background:rgba(5,19,14,.9);font-size:var(--fs-11)}/* v194 (David): mastery is a NUMBER COIN docked on the lower-right of the portrait ring — the
   way avatar level badges ride portraits in most games. The v191 ribbon lane and the locked-price
   ribbon are GONE: names are never covered. A locked card keeps its top-corner lock coin and
   quotes its price on the preview screen's UNLOCK button. .seatAv is the portrait wrapper the
   coin anchors to (identity grid, identity card and every lobby seat). */
.seatAv{position:relative;display:block;width:fit-content;margin:0 auto}
.seatAv img{display:block}
/* the wrapper is a <span>: out-specify `.lbAvatarChoice span` (name styling) so the coin is never clipped */
.lbAvatarChoice .seatAv{overflow:visible;white-space:normal;font:inherit}
.mRing{position:absolute;right:-3px;bottom:1px;min-width:20px;height:20px;padding:0 3px;box-sizing:border-box;display:grid;place-items:center;border:1.5px solid var(--brass);border-radius:50%;background:linear-gradient(180deg,var(--ink-3),var(--ink));color:var(--brass-hi);font:400 12px/1 'Bebas Neue';font-style:normal;letter-spacing:0;pointer-events:none;box-shadow:0 2px 6px rgba(0,0,0,.5);z-index:1}
.mRing:empty{display:none}
.lbIdent .seatAv{grid-row:1/2;margin:0}.lbIdent .mRing{min-width:23px;height:23px;font-size:var(--fs-14)}
/* FRONT-OF-HOUSE END */
/* v197 THE ASSIST WHISPER — Smart Assist's own little guide card, docked beside the glowing
   move. Never the Floor Wire lane. Gentle in; removed INSTANTLY by any tap or spent action. */
#assistTip{position:fixed;z-index:36;max-width:286px;padding:10px 13px;box-sizing:border-box;border:1px solid rgba(232,200,122,.65);border-left:4px solid var(--brass);border-radius:10px;background:linear-gradient(160deg,rgba(8,32,24,.97),rgba(4,17,13,.97));box-shadow:0 10px 28px rgba(0,0,0,.6),0 0 0 1px rgba(232,200,122,.14);cursor:pointer;animation:assistTipIn 320ms ease-out both}
#assistTip span{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;font:650 13px/1.3 Barlow;color:#d7e2da}
/* Build 328: on phones Smart Assist is a 44px whisper, not a desktop explanation card over the
   table. The full move-specific reason remains in its aria label and opens on tap. */
@media(max-width:599px){
 #assistTip[data-mode="phone-compact"]{width:auto;max-width:210px;min-height:44px;max-height:54px;padding:7px 10px;border-left-width:3px;border-radius:8px;box-shadow:0 6px 16px rgba(0,0,0,.52),0 0 0 1px rgba(232,200,122,.12)}
 #assistTip[data-mode="phone-compact"] span{font-size:10.5px;line-height:1.18;color:#d7e2da}
}
@keyframes assistTipIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){#assistTip{animation:none}}
/* FRONT-OF-HOUSE START */
.voiceRosterBox{width:min(560px,94vw);max-height:min(86vh,760px);overflow-y:auto}
.lbContinue{display:block;width:100%;min-height:48px;margin-top:10px;border:1px solid var(--brass-hi);border-radius:var(--r-chip);background:linear-gradient(180deg,var(--brass-hi),var(--brass));box-shadow:inset 0 1px rgba(255,255,255,.55),0 4px 0 var(--brass-deep),0 10px 20px rgba(0,0,0,.28);color:var(--ink-2);font:400 20px 'Bebas Neue';letter-spacing:var(--ls-label);cursor:pointer}
.lbSetupGrid{display:grid;grid-template-columns:minmax(180px,.62fr) minmax(0,1.38fr);gap:12px;align-items:start}
.lbRow{min-width:0}.lbSetupGrid .lbRow{margin:4px 0;padding:10px;border:1px solid rgba(201,162,75,.15);background:rgba(5,19,14,.3);box-sizing:border-box}
.lbMixRow{grid-column:1/-1}.lbStepper{display:grid;grid-template-columns:48px minmax(58px,1fr) 48px;gap:6px;align-items:center}
.lbStepper button{min-width:44px;min-height:44px;border:1px solid rgba(201,162,75,.38);border-radius:var(--r-chip);background:var(--ink-2);color:var(--paper);font:800 24px Barlow;cursor:pointer}.lbStepper b{font:400 32px 'Bebas Neue';color:var(--brass);text-align:center}
#lbCode{width:100%;min-height:48px;box-sizing:border-box;border:1px solid rgba(201,162,75,.4);border-radius:var(--r-chip);background:rgba(5,19,14,.7);color:var(--brass);font:800 20px 'Bebas Neue',Barlow;letter-spacing:var(--ls-eyebrow);text-align:center;padding:9px}

/* ============ v239 THE CLEAN JOIN PANEL ============================================
   David's ruling: tapping JOIN TABLE must land on the code, not on a two-step wizard.
   One screen, the house language only — brass hairlines, Bebas display, emerald felt.
   The numbered step tabs are hidden for the whole time a joiner is outside the table. */
body.joinFlow .lbSteps{display:none}
.lbJoinStep{padding-top:4px}
.lbJoinIntro{margin:16px 0 4px;text-align:center}
.lbJoinIntro strong{display:block;font:400 32px/1 'Bebas Neue';letter-spacing:var(--ls-label);color:var(--brass)}
.lbJoinIntro span{display:block;margin-top:7px;color:var(--muted);font:600 12px/1.4 Barlow;letter-spacing:0}
.lbJoinIntro::after{content:"";display:block;width:74px;height:1px;margin:13px auto 0;background:linear-gradient(90deg,transparent,rgba(201,162,75,.75),transparent)}
.lbJoinIdent{position:relative;display:grid;grid-template-columns:64px minmax(0,1fr);align-items:center;gap:13px;margin:16px auto 0;max-width:430px;padding:11px 13px;border:1px solid rgba(201,162,75,.17);background:rgba(5,19,14,.38)}
.lbJoinIdent .seatAv{margin:0;width:64px;height:64px;overflow:hidden}
.lbJoinIdent #lbJoinAv{width:64px;height:64px;object-fit:cover}
.lbJoinIdent .mRing{min-width:22px;height:22px;font-size:var(--fs-14)}
.lbJoinWho{min-width:0;display:grid;gap:6px}
.lbJoinWho strong{font:400 20px/1 'Bebas Neue';letter-spacing:var(--ls-label);color:var(--paper)}
#lbJoinName{width:100%;min-height:44px;box-sizing:border-box;padding:9px 11px;border:1px solid var(--hairline);border-radius:var(--r-chip);background:rgba(5,19,14,.7);color:var(--ivory);font:700 14px Barlow;letter-spacing:0;box-shadow:inset 0 2px 12px rgba(0,0,0,.32)}
#lbJoinName:focus{outline:none;border-color:var(--brass);box-shadow:0 0 0 3px rgba(201,162,75,.1),inset 0 2px 12px rgba(0,0,0,.3)}
/* v241 (David): .lbJoinChange (CHANGE CHARACTER) is retired — do not reintroduce a button on this
   card. An empty caption span must take no space, so a line that has nothing to say leaves no gap. */
.lbIntro span:empty,.lbJoinIntro span:empty{display:none}
.lbJoinCode{max-width:430px;margin:14px auto 0;text-align:center}
.lbJoinCode label{display:block;margin-bottom:8px;color:var(--muted);font:800 11px Barlow;letter-spacing:var(--ls-eyebrow)}
.lbJoinCode #lbCode{min-height:74px;font-size:40px;letter-spacing:var(--ls-eyebrow);text-indent:18px;border-color:rgba(201,162,75,.5);box-shadow:inset 0 3px 18px rgba(0,0,0,.45)}
.lbJoinCode #lbCode::placeholder{color:rgba(201,162,75,.24)}
.lbJoinGo{max-width:430px;margin:16px auto 0}
.lbJoinHint{max-width:430px;margin:11px auto 0;min-height:18px;text-align:center;color:var(--muted);font:600 12px/1.4 Barlow}
/* v182: the opening mix is one always-visible slider (.lbCustomMix below) — the preset buttons are retired */
.lbCustomMix{display:grid;grid-template-columns:145px minmax(0,1fr);align-items:center;gap:10px;margin-top:9px}.lbCustomMix[hidden]{display:none}.lbCustomMix span{font:700 12px Barlow;color:var(--paper)}.lbCustomMix input{width:100%;min-width:0}
.lbReadyDock{position:sticky;bottom:-18px;z-index:4;padding:9px 0 3px;background:linear-gradient(180deg,transparent 0,var(--ink-2) 28%,var(--ink-2) 100%)}
#lbHint{min-height:18px;font-size:var(--fs-12);line-height:1.35}.lbBack{min-height:44px;padding:8px 14px;font-size:var(--fs-12)}
/* FRONT-OF-HOUSE END */

/* Character reactions: your portrait is the control; the six live choices stay inside one safe panel. */
#v2badge{display:flex;flex-direction:column;align-items:flex-end;gap:6px}
#v2reactB{position:relative;width:var(--console-av,48px);height:var(--console-av,48px);min-width:0;padding:0;pointer-events:auto;border:2px solid rgba(232,200,122,.82);border-radius:50%;background:#071a14;color:var(--brass);box-shadow:0 5px 14px rgba(0,0,0,.42),0 0 0 3px rgba(210,180,104,.08);cursor:pointer;transition:transform .14s ease,border-color .14s ease,box-shadow .14s ease}
#v2reactB:hover{transform:translateY(-1px);border-color:#f1dda4}#v2reactB:active{transform:scale(.95)}#v2reactB:focus-visible{outline:2px solid #fff3d6;outline-offset:3px}#v2reactB[aria-expanded="true"]{border-color:#fff3d6;box-shadow:0 0 0 4px rgba(210,180,104,.18),0 7px 20px rgba(0,0,0,.55)}
#v2reactAv{display:block;width:100%;height:100%;box-sizing:border-box;border-radius:50%;object-fit:cover;background:#071a14}
.reactionBadge{position:absolute;left:50%;right:auto;bottom:-4px;transform:translateX(-50%);display:grid;place-items:center;width:24px;height:16px;border:1px solid #f1dda4;border-radius:8px;background:#123b2d;color:#fff3d6;font:900 14px/.6 Barlow;letter-spacing:0;box-shadow:0 3px 7px rgba(0,0,0,.5)}
#v2reactB.founder::before,.lbIdent.founder::before,.lbSeat.founder::before{content:"FOUNDER";position:absolute;z-index:5;display:grid;place-items:center;border:1px solid #fff3d6;border-radius:999px;background:#6b4e14;color:#fff3d6;font:900 7px/1 Barlow;letter-spacing:.65px;box-shadow:0 3px 9px rgba(0,0,0,.55)}
#v2reactB.founder::before{left:50%;top:-10px;width:40px;height:12px;transform:translateX(-50%)}.lbIdent.founder{position:relative}.lbIdent.founder::before{left:8px;top:-7px;width:48px;height:14px}.lbSeat.founder::before{left:4px;top:4px;width:42px;height:13px;font-size:6px}
/* Build 374 — THE REACTION WHEEL. One short header, then big marks. Every tile is far past the
   44px floor on the smallest supported phone (three to a row inside a 374px panel is ~110x74),
   which is the whole point: the old list asked players to READ six sentences to send one line. */
#reactionMenu{display:none;position:fixed;z-index:32;width:min(420px,calc(100vw - 16px));padding:9px;box-sizing:border-box;border:1px solid rgba(210,180,104,.68);border-radius:14px;background:linear-gradient(155deg,rgba(13,48,36,.995),rgba(3,16,12,.995));box-shadow:0 20px 52px rgba(0,0,0,.72),inset 0 1px rgba(255,255,255,.05);backdrop-filter:blur(12px);transform-origin:50% 100%;overscroll-behavior:contain}
#reactionMenu.open{display:block;animation:reactionMenuIn 180ms ease-out both}
.rxHead{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:1px 3px 8px;margin-bottom:9px;border-bottom:1px solid rgba(210,180,104,.24)}
.rxHead b{min-width:0;overflow:hidden;color:var(--brass);font:800 10.5px Barlow;letter-spacing:1.7px;text-overflow:ellipsis;white-space:nowrap}
.rxHead i{flex:0 0 auto;padding:3px 8px;border:1px solid rgba(210,180,104,.38);border-radius:999px;color:#b8c9c1;font:800 8px Barlow;font-style:normal;letter-spacing:1.2px}
.rxGrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px}
.rxTile{position:relative;display:flex;min-width:0;min-height:74px;flex-direction:column;align-items:center;justify-content:center;gap:6px;padding:8px 4px;border:1px solid rgba(210,180,104,.3);border-radius:11px;background:linear-gradient(155deg,rgba(11,42,31,.96),rgba(2,14,10,.9));color:var(--paper);cursor:pointer;transition:transform .12s ease,border-color .12s ease,background .12s ease}
.rxTile em{display:grid;place-items:center;width:30px;height:30px;border-radius:50%;border:1px solid rgba(210,180,104,.42);background:rgba(232,200,122,.09);color:#F2DFA8;font:800 15px/1 Barlow;font-style:normal}
.rxTile b{display:block;max-width:100%;overflow:hidden;color:#F5EFDD;font:800 9.5px/1.12 Barlow;letter-spacing:.45px;text-align:center}
.rxTile i{position:absolute;top:5px;right:6px;padding:1px 5px;border-radius:999px;background:rgba(232,200,122,.16);color:#E8C87A;font:800 8px Barlow;font-style:normal}
.rxTile:hover,.rxTile:focus-visible{border-color:var(--brass);background:#174735;outline:none}
.rxTile:active{transform:scale(.96)}
.rxTile.locked{opacity:.56;border-style:dashed}
.rxTile.rxMore em,.rxTile.rxBack em{color:#9DB4A9;background:rgba(157,180,169,.09)}
@media(min-width:520px){.rxGrid{grid-template-columns:repeat(4,minmax(0,1fr))}}@keyframes reactionMenuIn{from{opacity:0;transform:translateY(8px) scale(.97)}to{opacity:1;transform:none}}
#reactionLayer{position:fixed;inset:0;z-index:29;pointer-events:none;overflow:hidden}
.reactionBubble{position:absolute;max-width:min(250px,64vw);min-width:120px;padding:10px 13px;box-sizing:border-box;border:1px solid rgba(210,180,104,.75);border-radius:12px;background:linear-gradient(155deg,rgba(255,249,231,.98),rgba(226,208,161,.98));box-shadow:0 10px 25px rgba(0,0,0,.48);color:#14251d;font:800 14px/1.25 Barlow;text-align:center;overflow-wrap:anywhere;animation:reactionBubbleIn 230ms cubic-bezier(.2,.9,.3,1.2) both}
.reactionBubble>b,.reactionBubble>span{display:block}.reactionBubble>b{margin-bottom:2px;font:800 10px Barlow;letter-spacing:1.2px;color:#705522}.reactionBubble.mine>b{color:var(--brass)}
.reactionBubble::after{content:"";position:absolute;left:var(--tail-x,50%);bottom:-7px;width:12px;height:12px;background:#e2d0a1;border-right:1px solid rgba(103,75,24,.55);border-bottom:1px solid rgba(103,75,24,.55);transform:translateX(-50%) rotate(45deg)}.reactionBubble.tailTop::after{top:-7px;bottom:auto;transform:translateX(-50%) rotate(225deg)}
.reactionBubble.mine{background:linear-gradient(155deg,#1f654b,#0c3426);color:var(--paper);border-color:var(--brass)}.reactionBubble.mine::after{background:#0c3426}
.reactionBubble.out{animation:reactionBubbleOut 180ms ease-in both}@keyframes reactionBubbleIn{from{opacity:0;transform:translateY(8px) scale(.82)}to{opacity:1;transform:none}}@keyframes reactionBubbleOut{to{opacity:0;transform:translateY(-8px) scale(.94)}}
.voiceCollectionIntro{margin:0 0 10px;color:#b8c9c1;font:650 12px/1.4 Barlow;text-align:center}.voiceCollectionGrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}.voiceCollectionCard{position:relative;min-width:0;min-height:100px;padding:8px 5px 7px;border:1px solid rgba(210,180,104,.26);border-radius:5px;background:rgba(3,17,13,.72);color:var(--paper);cursor:pointer;text-align:center}.voiceCollectionCard:hover,.voiceCollectionCard:focus-visible{border-color:var(--brass);outline:none}.voiceCollectionCard img{display:block;width:50px;height:50px;margin:0 auto 5px;border:2px solid rgba(210,180,104,.5);border-radius:50%;object-fit:cover}.voiceCollectionCard b{display:block;overflow:hidden;color:var(--ivory);font:800 11px Barlow;letter-spacing:.6px;text-overflow:ellipsis;white-space:nowrap}.voiceCollectionCard small{display:block;margin-top:3px;color:var(--muted);font:750 8px Barlow;letter-spacing:.7px}.voiceCollectionCard.premium{border-color:rgba(210,180,104,.48);background:linear-gradient(155deg,rgba(55,43,19,.5),rgba(2,14,10,.78))}.voiceCollectionCard.premium small{color:var(--brass)}
.voiceLineRow{display:grid;grid-template-columns:minmax(0,1fr) 112px;gap:6px;align-items:stretch}.voiceLineRow>.v2opt{min-width:0}.voiceLineRow>.voiceLineBuy{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center}.voiceLineRow>.voiceLineBuy small{margin-top:3px}

@media(max-width:700px){
/* FRONT-OF-HOUSE START */
 .lbCard{width:calc(100vw - 16px);max-height:calc(100dvh - 16px);padding:14px 12px 10px}.lbHead{padding-bottom:9px}.lbHead span{font-size:var(--fs-16);letter-spacing:var(--ls-eyebrow)}.lbHead b{font-size:var(--fs-12)}.lbSteps{margin:8px 0 4px}.lbSteps button{font-size:var(--fs-11);letter-spacing:var(--ls-label)}.lbIntro{margin:7px 0 5px;gap:10px}.lbIntro strong{font-size:var(--fs-20)}.lbIntro span{max-width:52%;font-size:var(--fs-11);line-height:1.25;text-align:right}
 .lbIdent{grid-template-columns:74px minmax(0,1fr);gap:8px;padding:8px;margin:7px 0}.lbIdent .seatAv{grid-row:1/3}.lbIdent #lbMyAv{width:68px;height:68px}.lbIdentityCopy strong{font-size:var(--fs-20)}.lbIdentityCopy span{font-size:var(--fs-11)}.lbIdent #lbName{grid-column:2;min-height:44px;font-size:var(--fs-16);padding:9px}
 
 .lbAvatarGrid{grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin:7px 0}.lbAvatarChoice{min-height:72px;padding:4px 2px}.lbAvatarChoice img{width:49px;height:49px;margin-bottom:2px}.lbAvatarChoice span{font-size:var(--fs-11);letter-spacing:0}.lbContinue{min-height:46px;margin-top:8px;font-size:var(--fs-20)}
 .lbJoinIntro{margin:10px 0 2px}.lbJoinIntro strong{font-size:var(--fs-24)}.lbJoinIntro span{font-size:var(--fs-11)}.lbJoinIntro::after{margin-top:10px}
 .lbJoinIdent{grid-template-columns:56px minmax(0,1fr);gap:9px;padding:9px;margin-top:11px}.lbJoinIdent .seatAv,.lbJoinIdent #lbJoinAv{width:56px;height:56px}.lbJoinWho strong{font-size:var(--fs-16)}
 .lbJoinCode{margin-top:11px}.lbJoinCode #lbCode{min-height:64px;font-size:var(--fs-32);letter-spacing:var(--ls-eyebrow);text-indent:14px}.lbJoinGo{margin-top:12px;min-height:48px}
 .lbSetupGrid{grid-template-columns:1fr;gap:7px}.lbMixRow{grid-column:auto;grid-row:auto}.lbSetupGrid .lbRow{padding:8px;margin:0}.lbLbl{font-size:var(--fs-11);letter-spacing:var(--ls-eyebrow);margin-bottom:6px}.lbStepper{grid-template-columns:46px minmax(58px,1fr) 46px}.lbCustomMix{grid-template-columns:128px minmax(0,1fr)}
 #lbSeats{grid-template-columns:repeat(4,minmax(0,1fr));gap:5px;margin:8px 0 2px}.lbSeat{--seatBadgeLane:16px;min-width:0;min-height:88px;padding:var(--seatBadgeLane) 3px 7px}/* Build 376: with the face cleared the phone portrait grows 36->44px and every credential moves to the rail. */.lbSeat img{width:44px;height:44px}.lbCred{gap:5px;margin-top:6px;padding-top:5px}.lbCred .mRing{min-width:17px;height:17px;font-size:var(--fs-11)}.lbCred .crTrophy,.lbCred .crHouse{width:17px;height:17px}.lbSeat.founder::before{left:3px;top:3px;width:37px;height:12px;font-size:var(--fs-11)}.lbSeat .nm{font-size:var(--fs-11)}.lbSeat .st{font-size:var(--fs-11);letter-spacing:0}.lbReadyDock{bottom:-12px;padding-top:7px}#lbReady{min-height:48px;padding:10px;font-size:var(--fs-20)}#lbHint{font-size:var(--fs-11);margin-top:6px}.lbBack{margin-top:1px}
/* FRONT-OF-HOUSE END */
 #v2ticker{right:48px}#v2badge{top:6px;right:6px}body:not(.playing) #v2setB{height:34px;padding:6px 9px}body:not(.playing) #v2reactB{width:46px;height:46px}#reactionMenu{width:calc(100vw - 16px);padding:8px}.rxGrid{gap:6px}.rxTile{min-height:70px}.reactionBubble{max-width:min(240px,70vw);font-size:13px}.voiceCollectionGrid{grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}.voiceCollectionCard{min-height:91px}.voiceCollectionCard img{width:44px;height:44px}
}
@media(max-width:370px){
 .lbCard{padding-left:9px;padding-right:9px}.lbHead span{font-size:15px}.lbSteps button span{font-size:10px}.lbAvatarChoice span{font-size:10px}.lbAvatarChoice img{width:45px;height:45px}#lbSeats{grid-template-columns:repeat(4,minmax(0,1fr))}.lbSeat img{width:40px;height:40px}.lbCred{gap:4px}.lbCred .mRing{min-width:16px;height:16px;font-size:10px}.lbCred .crTrophy,.lbCred .crHouse{width:16px;height:16px}.rxTile{min-height:66px}.rxTile b{font-size:9px}.voiceCollectionCard b{font-size:10px}
}
@media(prefers-reduced-motion:reduce){.lbStep.on,.reactionBubble,#reactionMenu.open,button.tactile-release,.v2opt.tactile-release,.v2toast{animation:none}}

/* Build 268 — portrait Market Forces chooser uses real Career miniatures, never a word-only list. */
.mfChooser{width:min(94vw,620px);max-height:min(86vh,720px);overflow:auto}.mfStep{margin:0 0 10px;color:#c9a2f0;font:900 11px/1.2 Barlow Semi Condensed,Barlow;letter-spacing:1.5px;text-align:center}.mfSeatGrid,.mfMiniGrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:8px 0 12px}.mfSeat,.mfMiniCard{min-height:64px;border:1px solid rgba(201,162,240,.55);background:linear-gradient(145deg,rgba(42,14,58,.96),rgba(10,33,27,.98));color:#f5efdd;border-radius:10px;padding:7px;display:flex;align-items:center;gap:9px;text-align:left;overflow:hidden}.mfSeat{min-height:88px;flex-direction:column;justify-content:center;text-align:center;gap:3px}.mfSeat img{display:block;width:46px;height:46px;object-fit:cover;object-position:center top;border:2px solid #e8c87a;border-radius:50%;background:#2a0e3a;box-shadow:0 0 0 3px rgba(142,77,201,.36),0 4px 10px rgba(0,0,0,.45)}.mfSeat b,.mfMiniCard b{font:900 12px/1.12 Barlow Semi Condensed,Barlow;letter-spacing:.35px}.mfSeat span,.mfMiniCard em{font:700 9px/1.25 Barlow;color:#c7bcd0;font-style:normal}.mfMiniCard img{width:44px;height:62px;flex:0 0 44px;object-fit:cover;object-position:top center;border-radius:5px;border:1px solid rgba(232,200,122,.65)}.mfMiniCard>span{min-width:0;display:flex;flex-direction:column;gap:5px}.mfMiniCard .mfDisabledReason{display:block;color:#ef9da7;font:800 10px/1.15 Barlow,sans-serif;margin-top:2px}.mfMiniCard.disabled{opacity:.48;filter:saturate(.55);cursor:not-allowed}.mfMiniCard:not(.disabled):hover,.mfSeat:hover{border-color:#e8c87a;box-shadow:0 0 0 2px rgba(142,77,201,.2)}
@media(max-width:420px){.mfChooser{width:calc(100vw - 16px);padding-left:10px;padding-right:10px}.mfSeatGrid,.mfMiniGrid{gap:6px}.mfMiniCard{min-height:70px;padding:5px;gap:6px}.mfMiniCard img{width:40px;height:58px;flex-basis:40px}.mfMiniCard b{font-size:10.5px}}
.saleChooser{width:min(94vw,680px)}.saleChoiceGrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px;margin:9px 0 12px}.saleChoice{min-height:96px;display:grid;grid-template-columns:86px minmax(0,1fr);align-items:center;gap:10px;padding:8px;border:1px solid rgba(201,162,240,.55);border-radius:11px;background:linear-gradient(145deg,rgba(42,14,58,.96),rgba(10,33,27,.98));color:#f5efdd;text-align:left;overflow:hidden}.saleChoice:hover,.saleChoice:focus-visible{border-color:#e8c87a;box-shadow:0 0 0 2px rgba(232,200,122,.16)}.saleChoice>span:last-child{min-width:0;display:flex;flex-direction:column;gap:4px}.saleChoice b{font:900 11px/1.18 Barlow Semi Condensed,Barlow;letter-spacing:.45px}.saleChoice strong{color:#8fe6b4;font:900 18px/1 Barlow}.saleChoice small{color:#c7bcd0;font:800 9px/1.2 Barlow;letter-spacing:.35px}.saleArtStack{position:relative;display:block;width:82px;height:78px}.saleArtStack img{position:absolute;left:calc(var(--i) * 7px);top:calc(var(--i) * 2px);width:43px;height:62px;border:1px solid rgba(232,200,122,.72);border-radius:5px;object-fit:cover;object-position:top center;box-shadow:0 3px 8px rgba(0,0,0,.48)}.saleArtStack i{position:absolute;right:1px;bottom:0;display:grid;place-items:center;min-width:28px;height:28px;padding:0 4px;border:1px solid #f5efdd;border-radius:50%;background:#6fa8ff;color:#111b24;font:900 11px Barlow;font-style:normal}.saleKeepsEE{display:grid;grid-template-columns:38px minmax(0,1fr);gap:2px 9px;align-items:center;margin:4px 0 12px;padding:9px 11px;border:1px solid rgba(232,200,122,.5);border-radius:10px;background:rgba(232,200,122,.08);text-align:left}.saleKeepsEE span{grid-row:1/3;display:grid;place-items:center;width:34px;height:34px;border:1px solid #fff0b8;border-radius:9px;background:#e8c87a;color:#201707;font:900 11px Barlow}.saleKeepsEE b{color:#f2dfa8;font:900 11px Barlow;letter-spacing:.45px}.saleKeepsEE small{color:#b7c9c0;font:700 10px/1.25 Barlow}@media(max-width:420px){.saleChoiceGrid{grid-template-columns:1fr}.saleChoice{min-height:88px;grid-template-columns:78px minmax(0,1fr)}.saleArtStack{width:74px;height:70px}.saleArtStack img{width:40px;height:58px}.saleChoice strong{font-size:17px}}
.reportTerms{margin:8px 0 12px;padding:9px 10px;border:1px solid rgba(232,200,122,.24);background:rgba(245,239,221,.055);text-align:left;color:#d9d1bf;font:650 11px/1.42 Barlow}.reportTerms p{margin:0 0 7px}.reportTerms p:last-child{margin-bottom:0}.reportTerms b{color:#f5efdd;font-weight:900}

@media(max-width:700px){
 #v2msg{font-size:16px;line-height:1.22}
 .goalrow{font-size:13px}
 #v2act{font-size:16px;line-height:1.15}
 .turnclock{min-width:32px;font-size:14px}
 #v2end{font-size:18px}
 body.feed-open #v2feedItems .feeditem{font-size:16px;line-height:1.4}
}
/* Build 331: on the shortest supported phone, three ordinary two-line actions plus the 44px
   Close control must still unfurl above the Wire. Tighten only the history typography; game cards,
   controls and the persistent Wire keep their normal phone scale. */
@media(max-width:420px) and (max-height:700px){body.feed-open #v2feedItems .feeditem{font-size:12px;line-height:1.22;padding:6px 8px 6px 11px}}
@media(max-width:400px){
 #v2ticker{right:58px;min-height:76px;grid-template-columns:minmax(0,1fr) 44px;padding:5px 6px 5px 10px}
 #v2ticker .wireLabel,#v2ticker .wirePulse{display:none}
 #v2msg{display:-webkit-box;max-height:3.66em;overflow:hidden;-webkit-box-orient:vertical;-webkit-line-clamp:3}
 #v2feedToggle{width:44px;min-width:44px;height:44px;min-height:44px;padding:0 5px}
}

/* v245: the compact goal track replaces the unreadable percentage sentence without changing the
   established console footprint. The portfolio remains one column, including on the locked phone
   console; hudInsets() therefore continues to measure the same honest board budget. */
.commandPortfolio{grid-template-columns:minmax(0,1fr)!important;gap:8px}
#v2goal{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px;margin-top:3px}
#v2goalTag{align-self:center;color:var(--gold,#E8C87A);font-weight:800;line-height:1;letter-spacing:.4px;white-space:nowrap}
/* v108: the phone console height/rows overrides that used to live here are GONE — they were
   silently re-fattening the bar to 88px on ≤480w phones, defeating the v107 single-row console
   (this happened TWICE: also a max-width:400 block, now deleted). LAW: #v2command height/rows
   for phones is declared in EXACTLY ONE place — the ≤480 portrait block above. Never add
   another; hudInsets() measures whatever wins the cascade and the board pays for every px. */
@media(max-width:700px){
 .commandWorth .commandLabel{display:flex;font-size:8px}
}

/* Build 390/391 — THE EXCHANGE CONVENES. One shared 6.5s loading ceremony replaces both the old
   bell curtain and individual welcome poster. Portraits always resolve through the equipped
   attire. Desktop reads as one ceremonial roster; phones become a compact top-to-bottom roll. */
#matchIntro{position:fixed;inset:0;z-index:58;pointer-events:none;overflow:hidden;display:grid;grid-template-rows:auto minmax(0,1fr) auto;gap:clamp(12px,2.4vh,26px);padding:max(20px,env(safe-area-inset-top)) max(18px,env(safe-area-inset-right)) max(16px,env(safe-area-inset-bottom)) max(18px,env(safe-area-inset-left));color:#f7efd9;text-align:center;background:radial-gradient(80% 64% at 50% 23%,rgba(41,104,78,.52),transparent 72%),linear-gradient(180deg,#06120f 0%,#0b241b 42%,#030a08 100%);isolation:isolate}
#matchIntro::before{content:'';position:absolute;inset:0;z-index:-2;background:linear-gradient(90deg,rgba(1,7,5,.94),rgba(2,14,10,.34) 28%,rgba(2,14,10,.34) 72%,rgba(1,7,5,.94)),url('art/theme/exchange-floor-v6-responsive-territories.webp') center/cover;filter:saturate(.7) contrast(1.14);opacity:.3;transform:scale(1.04)}
#matchIntro::after{content:'';position:absolute;inset:0;z-index:-1;background:repeating-linear-gradient(90deg,transparent 0 9.8%,rgba(232,200,122,.055) 10%,transparent 10.2%),linear-gradient(180deg,rgba(232,200,122,.08),transparent 24%,transparent 72%,rgba(0,0,0,.5));box-shadow:inset 0 0 130px #020806}
.conveneHall{position:absolute;inset:0;z-index:-1;display:flex;justify-content:space-around;overflow:hidden;opacity:.7}.conveneHall i{width:13vw;height:45vh;border:1px solid rgba(232,200,122,.16);border-bottom:0;border-radius:50% 50% 0 0;transform:translateY(-12%);box-shadow:inset 0 0 28px rgba(232,200,122,.04)}
.conveneHead{align-self:start;display:grid;justify-items:center;gap:3px;opacity:0;transform:translateY(-12px)}
.conveneHead::after{content:'';width:min(480px,72vw);height:1px;margin-top:5px;background:linear-gradient(90deg,transparent,#e8c87a,transparent)}
.conveneHead b{color:#d7b866;font:800 10px Barlow;letter-spacing:5px}.conveneHead span{color:#fff8e6;font:400 clamp(34px,5.8vw,64px)/.95 'Bebas Neue';letter-spacing:clamp(3px,.7vw,8px);text-shadow:0 0 36px rgba(232,200,122,.32)}.conveneHead em{color:#9db4a9;font:800 10px Barlow;font-style:normal;letter-spacing:2.6px}
.conveneRoster{align-self:center;display:grid;grid-template-columns:repeat(var(--seat-count),minmax(88px,1fr));align-items:end;gap:clamp(8px,1.2vw,18px);width:min(1500px,96vw);margin:auto}
.conveneSeat{position:relative;min-width:0;opacity:0;transform:translateY(28px) scale(.94);filter:brightness(.72)}
.conveneSeat::before{content:'';position:absolute;left:-5px;top:-8px;width:calc(100% + 10px);aspect-ratio:4/5;border:1px solid rgba(232,200,122,.2);border-radius:52% 52% 6px 6px;background:linear-gradient(180deg,rgba(232,200,122,.07),transparent 46%);box-shadow:0 24px 45px rgba(0,0,0,.32)}
.conveneSeat.signature::before{border-color:rgba(232,200,122,.62);box-shadow:0 0 32px rgba(232,200,122,.12),0 24px 45px rgba(0,0,0,.38)}.conveneSeat.prestige::before{border-color:rgba(85,214,160,.7);box-shadow:0 0 34px rgba(85,214,160,.16),0 24px 45px rgba(0,0,0,.38)}
.convenePortrait{position:relative;aspect-ratio:4/5;overflow:hidden;border-radius:50% 50% 8px 8px;background:#0a2018;border:1px solid rgba(232,200,122,.35)}.convenePortrait img{width:100%;height:100%;display:block;object-fit:cover;object-position:center top;transform:scale(1.04)}
.conveneIdentity{position:relative;display:grid;min-width:0;gap:4px;margin-top:12px}.conveneIdentity>b{overflow:hidden;color:#fff8e6;font:400 clamp(20px,2.05vw,34px)/1 'Bebas Neue';letter-spacing:1.4px;text-overflow:ellipsis;white-space:nowrap}.conveneIdentity>span{display:flex;align-items:center;justify-content:center;gap:5px;min-width:0;min-height:23px;overflow:hidden;color:#c6d6ce;font:800 clamp(8px,.72vw,11px)/1.1 Barlow;letter-spacing:.7px;text-overflow:ellipsis;white-space:nowrap}.conveneIdentity>span i{display:grid;place-items:center;width:17px;height:17px;flex:none;border:1px solid rgba(232,200,122,.48);border-radius:50%;color:#e8c87a;font:800 9px Barlow;font-style:normal}.conveneSeat.prestige .conveneIdentity>span i{border-color:#55d6a0;color:#9cf0c1}
.conveneTicker{align-self:end;display:flex;align-items:center;justify-content:center;gap:12px;color:#8aa397;font:800 8px Barlow;letter-spacing:3px;opacity:0}.conveneTicker i{width:min(80px,9vw);height:1px;background:linear-gradient(90deg,transparent,#a88b47,transparent)}
.conveneSweep{position:absolute;inset:-30% auto -30% -30%;width:24%;background:linear-gradient(90deg,transparent,rgba(255,239,190,.16),rgba(255,255,255,.28),rgba(255,239,190,.08),transparent);transform:skewX(-12deg) translateX(-240%);mix-blend-mode:screen}
#matchIntro.armed .conveneHead{animation:conveneHead .5s ease forwards}#matchIntro.armed .conveneSeat{animation:conveneSeat .62s cubic-bezier(.18,.8,.25,1) calc(.48s + var(--seat-index)*.075s) forwards}#matchIntro.armed .conveneTicker{animation:conveneHead .4s ease 1.2s forwards}#matchIntro.armed .conveneSweep{animation:conveneSweep 1s ease 3.45s forwards}#matchIntro.depart{animation:conveneDepart .7s ease forwards}
@keyframes conveneHead{to{opacity:1;transform:none}}@keyframes conveneSeat{70%{filter:brightness(1.08)}to{opacity:1;transform:none;filter:none}}@keyframes conveneSweep{to{transform:skewX(-12deg) translateX(700%)}}@keyframes conveneDepart{to{opacity:0;transform:scale(1.012)}}
@media(max-width:1050px){.conveneRoster{grid-template-columns:repeat(4,minmax(90px,1fr));width:min(780px,92vw);align-items:center;row-gap:22px}.convenePortrait{aspect-ratio:1/1}.conveneSeat{transform:translateY(12px) scale(.96)}.conveneSeat::before{left:-4px;top:-5px;width:calc(100% + 8px);aspect-ratio:1/1}}
@media(max-width:600px){#matchIntro{grid-template-rows:auto minmax(0,1fr) auto;gap:7px;padding-top:max(13px,env(safe-area-inset-top));padding-bottom:max(10px,env(safe-area-inset-bottom))}.conveneHead{gap:1px}.conveneHead b{font-size:8px;letter-spacing:3px}.conveneHead span{font-size:clamp(28px,9vw,38px);letter-spacing:3px}.conveneHead em{font-size:8px;letter-spacing:1.5px}.conveneHead::after{margin-top:2px}.conveneRoster{align-self:stretch;display:flex;flex-direction:column;align-items:stretch;justify-content:center;gap:4px;width:min(420px,100%)}.conveneSeat{box-sizing:border-box;display:grid;grid-template-columns:clamp(44px,10vh,67px) minmax(0,1fr);align-items:center;width:100%;gap:11px;min-height:0;height:min(9vh,72px);padding:3px 10px 3px 5px;border:1px solid rgba(232,200,122,.18);border-radius:36px 10px 10px 36px;background:linear-gradient(90deg,rgba(232,200,122,.08),rgba(3,14,10,.58));transform:translateX(-14px) scale(.98)}.conveneSeat::before{display:none}.convenePortrait{width:100%;height:100%;aspect-ratio:1/1;border-radius:50%}.conveneIdentity{margin:0;text-align:left;gap:2px}.conveneIdentity>b{font-size:clamp(17px,5.2vw,23px)}.conveneIdentity>span{justify-content:flex-start;font-size:clamp(8px,2.5vw,10px);min-height:17px}.conveneIdentity>span i{width:15px;height:15px;font-size:8px}.conveneTicker{gap:6px;font-size:7px;letter-spacing:1.6px}.conveneTicker i{width:24px}}
@media(max-height:500px) and (orientation:landscape){#matchIntro{gap:5px;padding-block:9px}.conveneHead span{font-size:28px}.conveneHead em,.conveneTicker{display:none}.conveneRoster{grid-template-columns:repeat(var(--seat-count),minmax(70px,1fr));width:96vw;gap:7px}.convenePortrait{aspect-ratio:1/1}.conveneIdentity{margin-top:7px}.conveneIdentity>b{font-size:17px}.conveneIdentity>span{font-size:7px}.conveneSeat::before{left:-3px;top:-3px;width:calc(100% + 6px);aspect-ratio:1/1}}
@media(prefers-reduced-motion:reduce){#matchIntro.armed .conveneHead,#matchIntro.armed .conveneSeat,#matchIntro.armed .conveneTicker{animation:none;opacity:1;transform:none;filter:none}#matchIntro.armed .conveneSweep,#matchIntro.depart{animation:none}.conveneSweep{display:none}}

/* v187 (David): the ? TURN GUIDE entrance — 44px target (§3.11), in-match only, never in the
   tutorial (the coach owns guidance there). It lives inside the existing 60px chrome column the
   pod solver already reserves at top-right, so it is NOT a layout input. The portrait voiceCue
   is the §7b.14 "look at this" language: a brief champagne pulse, reduced-motion gated. */
/* Build 284: the in-match "?" Turn Guide button is retired (David: wasted space, blocked the LIVE
   FLOOR close on phones). The Turn Guide remains reachable from Settings. */
@keyframes voicePulse{0%,100%{box-shadow:0 0 0 0 rgba(232,200,122,0)}50%{box-shadow:0 0 0 6px rgba(232,200,122,.35)}}
#v2reactB.voiceCue{outline:1px solid rgba(232,200,122,.85);animation:voicePulse 1.3s ease-in-out 4}
@media (prefers-reduced-motion:reduce){#v2reactB.voiceCue{animation:none}}

/* v206 AUTO-AIM survives Build 374 as the wheel's one-line header: who hears this, and whether
   the table answers rivals for you (AUTO) or waits for you to (MANUAL). */

/* v209 SMART REPLY: when a rival's line targets YOU, the react button pulses with a REPLY tag */
#v2reactB{position:relative}
#v2reactB.replyReady{box-shadow:0 0 0 2px #e8c87a,0 0 18px rgba(232,200,122,.45);animation:replyPulse 1.15s ease-in-out infinite}
/* v215 AUTO REPLIES badge — the spinning green ring means the table answers rivals BY ITSELF
   (Settings → RIVAL REPLIES). Drawn with ::after — never with ::before, which the FOUNDER badge
   owns. In MANUAL mode the class is absent and the v209 gold REPLY pulse takes over; the two
   states are mutually exclusive by design. Static full-colour ring under reduced motion. */
#v2reactB.autoVoice::after{content:'';position:absolute;inset:-5px;border-radius:50%;border:2.5px solid transparent;border-top-color:#57D9A3;border-right-color:#57D9A3;animation:autoVoiceSpin 1.6s linear infinite;pointer-events:none}
@keyframes autoVoiceSpin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){#v2reactB.autoVoice::after{animation:none;border-color:#57D9A3}}
#v2reactB{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none} /* v216: long-press flips AUTO/MANUAL — the OS callout may not steal it */
#v2reactB.replyReady::after{content:'REPLY';position:absolute;top:-9px;right:-7px;background:#e8c87a;color:#14251d;font:800 8px 'Barlow';letter-spacing:1px;padding:2px 5px;border-radius:6px;pointer-events:none}
@keyframes replyPulse{50%{box-shadow:0 0 0 3px #e8c87a,0 0 26px rgba(232,200,122,.6)}}
@media (prefers-reduced-motion:reduce){#v2reactB.replyReady{animation:none}}


/* ══ BUILD 240 — REHOMED FROM THE RETIRED marketing.css ══════════════════════════════════
   marketing.js/.css were the Founders event and went with it. Three things in that
   stylesheet were NOT event chrome and are declared here instead, once, so nothing else
   quietly loses its styling:
   (a) .ttUtilities — the title-menu utility row that holds VIEW THE HOUSE RULES;
   (b) .v2opt.gold small — the sub-label inside every gold button in the game (v3swapGo,
       v3lotOpt, meta.js). It has only ever been declared in one place; keep it that way;
   (c) the FILM STAGE (#trailerStage), the v174 §7b.17 player now driven by v3playFilm in
       v3.js and kept for the single-player campaign. */
/* FRONT-OF-HOUSE START */
.ttUtilities{display:flex;align-items:center;justify-content:center;gap:9px;flex-wrap:wrap;margin-top:2px}
.v2opt.gold small{display:block;margin-top:3px;color:var(--brass-deep);opacity:1;font:900 11px/1.3 Barlow;letter-spacing:var(--ls-label);text-transform:none}
/* FRONT-OF-HOUSE END */

#trailerStage{position:fixed;inset:0;z-index:9000;background:#000;display:flex;align-items:center;justify-content:center;
 opacity:0;transition:opacity .5s ease;overscroll-behavior:none}
#trailerStage.on{opacity:1}
body.trailer-playing{overflow:hidden}
#trailerVid{width:100%;height:100%;object-fit:contain;background:#000;display:block}
#trailerStage button{position:absolute;cursor:pointer;font-family:'Barlow Semi Condensed',Barlow,sans-serif;
 -webkit-tap-highlight-color:transparent;touch-action:manipulation}
#trailerSkip{right:calc(14px + env(safe-area-inset-right));bottom:calc(14px + env(safe-area-inset-bottom));
 min-height:44px;min-width:96px;padding:9px 18px;border:1px solid rgba(232,200,122,.6);border-radius:999px;
 background:rgba(6,13,11,.62);color:#F5EFDD;font-weight:800;font-size:13px;letter-spacing:.14em}
#trailerSkip:hover{background:rgba(6,13,11,.85);border-color:#E8C87A}
#trailerSound{left:50%;transform:translateX(-50%);bottom:calc(72px + env(safe-area-inset-bottom));
 min-height:52px;padding:12px 24px;border:1px solid #C9A24B;border-radius:999px;
 background:linear-gradient(180deg,#E8C87A,#C9A24B);color:#1a1206;font-weight:900;font-size:14px;letter-spacing:.16em;
 box-shadow:0 6px 24px rgba(0,0,0,.55);animation:trailerSoundPulse 1.6s ease-in-out infinite}
@keyframes trailerSoundPulse{50%{filter:brightness(1.14)}}
@media(prefers-reduced-motion:reduce){#trailerSound{animation:none}#trailerStage{transition:none}}
/* Landscape phone: keep the controls tight to the corner so they never sit over the frame. */
@media(max-height:460px){
 #trailerSkip{min-height:44px;padding:7px 14px;font-size:12px}
 #trailerSound{bottom:calc(58px + env(safe-area-inset-bottom));min-height:44px;padding:9px 18px;font-size:12.5px}
}

/* Build 321 THE FLOOR WIRE HISTORY ROLLS (David 2026-08-21: "it should slide out nicely… clicking
   again on the floor wire button SHOULD also minimize it in a roll in and roll out animation").
   The panel is display:none when closed, so the open state runs an ENTRY animation and the close
   runs an EXIT one while `feed-closing` holds the panel on screen for its own length (v3.js owns
   that window and the paired cues). The centred variants keep the wide layout's translateX(-50%)
   inside every keyframe — a transform animation that forgets it would throw the panel sideways. */
@keyframes wireRollOut{from{opacity:.18;transform:translateY(10px) scaleY(.06)}to{opacity:1;transform:none}}
@keyframes wireRollIn{from{opacity:1;transform:none}to{opacity:.08;transform:translateY(10px) scaleY(.04)}}
@keyframes wireRollOutCentre{from{opacity:.18;transform:translateX(-50%) translateY(10px) scaleY(.06)}to{opacity:1;transform:translateX(-50%)}}
@keyframes wireRollInCentre{from{opacity:1;transform:translateX(-50%)}to{opacity:.08;transform:translateX(-50%) translateY(10px) scaleY(.04)}}
@media(prefers-reduced-motion:reduce){body.feed-open #v2feed,body.feed-closing #v2feed{animation:none!important}}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   CAMPAIGN (Build 346) — THE SCHISM
   Mobile first: every surface below is authored for 360x640 and 390x844 and grows from there.
   No horizontal scroll at any width, every interactive control ≥44 CSS px, and no animation
   gates progress — REDUCE MOTION only removes movement, never a step, a word or a button.
   Identity is the Exchange's own: emerald felt, champagne brass, Barlow Semi Condensed for the
   headings, Barlow for everything the player reads.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ── the title-screen entry ─────────────────────────────────────────────────────────────── */
/* Build 354/355 (David 2026-08-30: "i want the lock, i want the gold rim. I want th schism to be
   the main title, then subtext as coming soon"). The Build 346 gold rim and lock glyph are
   RESTORED and THE SCHISM is the headline again. What does NOT come back is the SEALED badge that
   hung off the corner (`em`): the subtext carries the status now, in plainer words, and two
   labels for one fact was the clutter.
   POSITION (Build 355): the mode list is a CENTRED FLEX ROW, so the campaign needs no bespoke
   placement at all - `order:99` keeps it LAST wherever the row happens to break, on any screen,
   and the row centres itself. The Build 353/354 `grid-column:4/-1` is retired with the grid that
   made it necessary; it was that grid, not this button, that produced the orphan David called
   ugly ("Centralize it or something if you cant put 5 buttons in a line"). */
#campaignModeBtn{border-color:rgba(210,180,104,.66);
 background:linear-gradient(145deg,rgba(13,41,33,.98),rgba(6,16,13,.99))}
#campaignModeBtn .modeIcon{background:linear-gradient(180deg,#e6d29a,#a5822f);color:#111a16;border-color:transparent}
#campaignModeBtn>span:nth-child(2)>i.ttLock{font-style:normal;font-size:.62em;margin-left:7px;opacity:.8;vertical-align:middle}
.ttmodes>.campaignRow{order:99}/* LAST wherever the row breaks - order, not a grid column, because the list is a centred flex row now */

/* ── the access-code gate (inside the one modal host) ───────────────────────────────────── */
.campGate{text-align:center}
.campGateSeal{font-size:26px;color:var(--brass);opacity:.85;margin-bottom:2px}
.campGateSub{font:800 10.5px Barlow;letter-spacing:2px;color:var(--muted);margin:0 0 10px}
.campGateAsk{font:600 13px/1.4 Barlow;color:#c7d5ce;margin:0 0 10px}
.campCodeInput{display:block;width:min(240px,80%);margin:0 auto 8px;min-height:52px;
 background:rgba(4,12,9,.92);border:1px solid rgba(210,180,104,.45);border-radius:8px;
 color:var(--ivory);font:800 26px/1 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:9px;
 text-align:center;padding:6px 4px 6px 13px}
.campGateErr{min-height:22px;font:800 11px/1.35 Barlow;letter-spacing:1.1px;color:#e8737b;margin-bottom:8px}
.campGate .v2opt{width:100%;min-height:50px;margin-top:7px;text-align:center}
@keyframes campShake{10%,90%{transform:translateX(-3px)}30%,70%{transform:translateX(5px)}50%{transform:translateX(-6px)}}
.campGate.campShake{animation:campShake .42s ease both}
@media(prefers-reduced-motion:reduce){.campGate.campShake{animation:none}}

/* ── the map ────────────────────────────────────────────────────────────────────────────── */
#campaignMap{display:none;position:fixed;inset:0;z-index:96;overflow-y:auto;overflow-x:hidden;
 -webkit-overflow-scrolling:touch;
 background:radial-gradient(120% 90% at 50% 0,rgba(21,83,63,.5),transparent 62%),var(--ink)}
.campMapCard{width:min(780px,94vw);margin:0 auto;padding:14px 0 30px;
 padding-top:calc(14px + env(safe-area-inset-top));padding-bottom:calc(30px + env(safe-area-inset-bottom))}
.campMapHead{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.campBack{min-width:44px;min-height:44px;border:1px solid rgba(210,180,104,.4);border-radius:8px;
 background:rgba(6,20,15,.9);color:var(--brass);font:800 20px Barlow;cursor:pointer}
.campMapTitles{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.05}
.campMapTitles span{font:900 24px/1 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:1.4px;color:var(--ivory)}
.campMapTitles b{font:800 9.5px Barlow;letter-spacing:1.9px;color:var(--muted);margin-top:3px}
.campStars{font:900 14px 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:1.1px;color:var(--brass);white-space:nowrap}
.campMapProgress{height:4px;border-radius:3px;background:rgba(210,180,104,.16);overflow:hidden;margin-bottom:12px}
.campMapProgress i{display:block;height:100%;background:linear-gradient(90deg,var(--brass-deep),var(--brass))}
.campContinue{width:100%;min-height:56px;margin-bottom:14px}
.campContinue[disabled]{opacity:.55;cursor:default}
.campAct{margin-bottom:14px}
.campAct h4{font:800 10px Barlow;letter-spacing:2.1px;color:var(--brass);margin:0 0 7px;
 padding-bottom:5px;border-bottom:1px solid rgba(210,180,104,.2)}
.campNode{display:flex;align-items:center;gap:9px;min-height:56px;padding:7px 9px;margin-bottom:6px;
 border:1px solid rgba(210,180,104,.2);border-radius:9px;background:rgba(9,21,17,.85)}
.campNode.next{border-color:rgba(47,196,124,.6);background:linear-gradient(180deg,rgba(21,83,63,.55),rgba(9,21,17,.9))}
.campNode.done{opacity:.9}
.campNode.locked{opacity:.45}
.campNodeIcon{flex:0 0 34px;min-width:34px;height:34px;display:flex;align-items:center;justify-content:center;
 border:1px solid rgba(210,180,104,.34);border-radius:7px;color:var(--brass);
 font:800 12px 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:.5px}
.campNode.scene .campNodeIcon{border-radius:50%;font-size:11px}
.campNodeText{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.15}
.campNodeText b{font:800 14.5px 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:.5px;color:var(--ivory);
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.campNodeText small{font:600 11px Barlow;color:var(--muted);margin-top:2px;
 overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.campNodeStar{font-size:15px;color:rgba(210,180,104,.32)}
.campNodeStar.on{color:var(--brass)}
.campLock{font-size:13px;opacity:.7;min-width:34px;text-align:center}
.campNodeGo{min-height:44px;min-width:74px;padding:0 11px;border:1px solid rgba(210,180,104,.5);border-radius:8px;
 background:rgba(13,41,33,.95);color:var(--brass);font:800 10.5px Barlow;letter-spacing:1.3px;cursor:pointer}
.campNodeGo:hover{border-color:var(--brass);color:var(--ivory)}
.campNode.next .campNodeGo{background:linear-gradient(180deg,#ead598,#c4a259);color:#141c17;border-color:transparent}
.campMapExit{width:100%;min-height:48px;margin-top:6px}

/* ── the cutscene interstitial (used only until the film is dropped in) ─────────────────── */
#campaignScene{position:fixed;inset:0;z-index:99;display:flex;align-items:center;justify-content:center;
 padding:16px;overflow-y:auto;background:#04100c}
.campSceneCard{width:min(560px,92vw);text-align:center;border:1px solid rgba(210,180,104,.28);
 border-radius:12px;padding:20px 16px;background:linear-gradient(180deg,rgba(13,41,33,.95),rgba(5,14,11,.98))}
.campSceneKicker{font:800 9.5px Barlow;letter-spacing:2.2px;color:var(--brass);margin-bottom:8px}
.campSceneCard h2{font:900 26px/1.05 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:1px;
 color:var(--ivory);margin:0 0 10px}
.campSceneLog{font:600 13.5px/1.45 Barlow;color:#c7d5ce;margin:0 0 14px}
.campSceneNote{border:1px dashed rgba(210,180,104,.3);border-radius:8px;padding:9px 10px;margin-bottom:14px}
.campSceneNote b{display:block;font:800 9.5px Barlow;letter-spacing:1.8px;color:var(--brass);margin-bottom:4px}
.campSceneNote span{font:600 11.5px/1.4 Barlow;color:var(--muted)}
.campSceneNote code{font-size:11px;color:#c7d5ce;word-break:break-all}
.campSceneGo{width:100%;min-height:52px}

/* ── stage directions and the result panel ─────────────────────────────────────────────── */
#campaignStage{position:fixed;left:50%;top:38%;transform:translate(-50%,-50%);z-index:70;
 max-width:min(520px,88vw);text-align:center;padding:9px 14px;border-radius:8px;
 background:rgba(4,12,9,.82);border:1px solid rgba(210,180,104,.22);
 font:italic 600 14px/1.45 Barlow;color:#d9e4dd;opacity:0;pointer-events:none;transition:opacity .22s ease}
#campaignStage.on{opacity:1}
@media(prefers-reduced-motion:reduce){#campaignStage{transition:none}}
.reactionBubble.campaignLine{border-color:rgba(210,180,104,.5)}
.campNote{font:600 13px/1.45 Barlow;color:#c7d5ce;margin:6px 0 12px}
.campResult{text-align:center}
.campResultKicker{font:800 9.5px Barlow;letter-spacing:2.1px;color:var(--brass);margin-bottom:4px}
.campResultWord{font:900 20px/1.1 'Barlow Semi Condensed',Barlow,sans-serif;letter-spacing:1px;
 color:var(--ivory);margin:6px 0 10px}
.campResultStar{display:block;padding:8px 10px;margin-bottom:12px;border-radius:8px;
 border:1px solid rgba(210,180,104,.22);color:var(--muted);font:800 11.5px Barlow;letter-spacing:1.4px}
.campResultStar.on{color:var(--brass);border-color:rgba(210,180,104,.6);background:rgba(21,83,63,.3)}
.campResultStar small{display:block;margin-top:4px;font:600 11px/1.35 Barlow;letter-spacing:.2px;color:var(--muted)}
.campPrompt h3{margin-bottom:4px}
.campPrompt .v2opt,.campResult .v2opt{width:100%;min-height:50px;margin-top:7px;text-align:center}

/* ── phones: the map is a single readable column and nothing may scroll sideways ───────── */
@media(max-width:520px){
 .campMapCard{width:94vw;padding-left:2px;padding-right:2px}
 .campMapTitles span{font-size:20px}
 .campNode{gap:7px;padding:6px 7px}
 .campNodeIcon{flex-basis:30px;min-width:30px;height:30px;font-size:10.5px}
 .campNodeText b{font-size:13.5px}
 .campNodeText small{font-size:10.5px}
 .campNodeGo{min-width:62px;padding:0 8px;font-size:9.5px}
 .campSceneCard h2{font-size:22px}
 .campCodeInput{width:82%;letter-spacing:7px;font-size:23px}
}
