/* Spry design system — slice 9 token pass (shared/polish-spec.md).
   "An heirloom puzzle book that came alive": warm paper, print craft,
   Fraunces display + Inter body, calm motion. */

/* --- fonts (self-hosted, latin subsets) ----------------------------------- */
@font-face {
  font-family: 'Fraunces'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/fraunces-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Fraunces'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/fonts/fraunces-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/fonts/inter-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('/fonts/inter-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('/fonts/inter-600.woff2') format('woff2');
}

/* --- tokens ---------------------------------------------------------------- */
:root {
  /* palette (polish spec §1 — use only these) */
  --paper: #F6F4EF; --card: #FFFFFF; --ink: #23221F; --muted: #6B6660; --line: #E7E2D8;
  --spring: #1F8A6D; --spring-d: #16694F; --spring-bg: #DDF1EA;
  --sun: #E0913A; --sun-bg: #FBEEDA;
  --berry: #C0506B;

  /* legacy aliases — pre-polish views/games reference these names */
  --teal: var(--spring); --teal-dk: var(--spring-d); --teal-bg: var(--spring-bg);
  --amber: var(--sun); --amber-bg: var(--sun-bg);
  --mut: var(--muted); --white: var(--card);

  /* type */
  --display: 'Fraunces', Georgia, serif;
  --body: 'Inter', 'Segoe UI', system-ui, sans-serif;

  /* spacing scale 8/16/24/40/64 · shape · depth */
  --s1: 8px; --s2: 16px; --s3: 24px; --s4: 40px; --s5: 64px;
  --r-card: 16px; --r-btn: 12px;
  --shadow: 0 2px 8px rgba(40, 34, 20, .05), 0 8px 24px rgba(40, 34, 20, .06);
  --shadow-lift: 0 4px 12px rgba(40, 34, 20, .07), 0 12px 32px rgba(40, 34, 20, .08);
  --shadow-press: 0 1px 3px rgba(40, 34, 20, .06);
}

/* living light (§0B): four fixed paper tints by local hour, ≥60s crossfade.
   Default skin only — a value set on body outranks a pack theme's :root
   override by inheritance, which turned dark-paper shows invisible (cream
   ink on daypart paper). Packs with a theme opt out via .pack-themed. */
body[data-daypart='dawn']:not(.pack-themed) { --paper: #F8F3EC; }
body[data-daypart='day']:not(.pack-themed) { --paper: #F6F4EF; }
body[data-daypart='golden']:not(.pack-themed) { --paper: #F7F2E7; }
body[data-daypart='evening']:not(.pack-themed) { --paper: #F2EFEA; }
/* entering a themed show snaps to its paper — the 75s crossfade is daypart
   drift, not a curtain */
body.pack-themed { transition: background-color .4s ease; }

* { box-sizing: border-box; margin: 0; }
html, body { height: 100%; }
body {
  font-family: var(--body);
  background: var(--paper); color: var(--ink);
  font-size: 19px; line-height: 1.55;
  transition: background-color 75s linear;
}
:focus-visible { outline: 3px solid var(--spring); outline-offset: 2px; border-radius: 6px; }

/* paper grain (§0): inline SVG turbulence via #grain overlay, set up in JS */
#grain {
  position: fixed; inset: 0; z-index: 1; pointer-events: none; opacity: .025;
}
.view, #nav, #toast, #spry-corner, #spry-center { position: relative; z-index: 2; }

.view { min-height: 100vh; padding: var(--s4) var(--s3) 80px; }
.frame { max-width: 760px; margin: 0 auto; position: relative; }

.card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-card);
  padding: 44px 36px; box-shadow: var(--shadow);
  animation: view-in 260ms ease-out;
}
@keyframes view-in {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}

.center { text-align: center; }
h1 { font-family: var(--display); font-size: 33px; font-weight: 600; letter-spacing: -0.015em; margin-bottom: 12px; }
h2 { font-family: var(--display); font-size: 25px; font-weight: 600; letter-spacing: -0.01em; margin-bottom: 10px; }
p.lead { font-size: 20px; color: var(--muted); max-width: 520px; margin: 0 auto 26px; }

/* masthead (§0A): printed-matter dateline with hairline rule */
.masthead {
  font-family: var(--display); font-weight: 500; font-size: 15px;
  letter-spacing: .14em; text-transform: uppercase; font-variant-caps: all-small-caps;
  color: var(--muted); text-align: center;
  padding-bottom: 10px; margin-bottom: var(--s3);
  border-bottom: 1px solid var(--line);
}

/* --- buttons (§2: press compress, hover lift) -------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  background: var(--spring); color: #fff; text-decoration: none; border: 0; cursor: pointer;
  font-size: 21px; font-weight: 600; font-family: var(--body);
  padding: 18px 40px; border-radius: var(--r-btn); min-height: 60px;
  box-shadow: var(--shadow);
  transition: transform 90ms ease-out, box-shadow 120ms ease-out, background 120ms;
}
.btn:hover { background: var(--spring-d); transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.btn:active { transform: scale(.97); box-shadow: var(--shadow-press); }
.btn2 {
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--card); color: var(--muted); text-decoration: none; cursor: pointer;
  font-size: 18px; font-family: var(--body); padding: 16px 28px; border-radius: var(--r-btn);
  border: 1px solid var(--line); min-height: 56px;
  transition: transform 90ms ease-out, box-shadow 120ms ease-out, border-color 120ms;
}
.btn2:hover { border-color: var(--muted); transform: translateY(-2px); box-shadow: var(--shadow); }
.btn2:active { transform: scale(.97); }
.quiet { color: var(--muted); font-size: 17px; text-decoration: underline; background: none; border: 0; cursor: pointer; font-family: var(--body); min-height: 48px; }
.row { display: flex; gap: 14px; justify-content: center; flex-wrap: wrap; margin-top: 26px; }

/* --- Spry ---------------------------------------------------------------------- */
.spry { width: 110px; height: 110px; border-radius: 50%; background: var(--spring-bg); display: flex; align-items: center; justify-content: center; margin: 0 auto 20px; }
.spry.small { width: 56px; height: 56px; margin: 0; flex: none; }
.spry svg { width: 62%; height: 62%; }
.bubble { display: flex; align-items: flex-end; gap: 12px; margin-top: 34px; }
.bubble .txt { background: var(--card); border: 1px solid var(--line); border-radius: 16px; border-bottom-left-radius: 4px; padding: 14px 18px; font-size: 18px; font-family: var(--display); font-weight: 500; }

/* Spry behavior states (§5) — CSS-animated on the flat SVG; Rive swaps in later */
.spry svg, #spry-corner svg { transform-origin: 50% 60%; }
[data-spry='idle'] svg { animation: spry-breathe 3s ease-in-out infinite; }
[data-spry='idle'] svg .eye { animation: spry-blink 5.5s infinite; }
[data-spry='happy'] svg { animation: spry-wag 700ms ease-in-out; }
[data-spry='celebrate'] svg { animation: spry-bounce 900ms ease-out; }
[data-spry='think'] svg { transform: rotate(6deg); transition: transform 400ms ease-out; }
[data-spry='encourage'] svg { transform: translateY(2px) scale(1.03); transition: transform 400ms ease-out; }
@keyframes spry-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.015); } }
@keyframes spry-blink { 0%, 92%, 100% { transform: scaleY(1); } 95% { transform: scaleY(.1); } }
@keyframes spry-wag { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-5deg); } 60% { transform: rotate(4deg); } }
@keyframes spry-bounce { 0%, 100% { transform: none; } 30% { transform: translateY(-8px); } 55% { transform: translateY(0); } 72% { transform: translateY(-3px) rotate(-3deg); } }
.spry svg .eye { transform-origin: center; transform-box: fill-box; }

/* --- meters / tracks / score ------------------------------------------------------ */
.meter { height: 12px; background: #EDEAE2; border-radius: 999px; overflow: hidden; margin: 10px 0 4px; }
.meter i { display: block; height: 100%; background: var(--spring); border-radius: 999px; transition: width 500ms ease-out; }
.meter.amb i { background: var(--sun); }
.tracks { max-width: 460px; margin: 26px auto; text-align: left; display: flex; flex-direction: column; gap: var(--s2); }
.trk .lab { display: flex; justify-content: space-between; font-size: 17px; margin-bottom: 4px; }
.trk .lab b { font-weight: 600; }
.good { color: var(--spring); } .grow { color: var(--sun); } .mutd { color: var(--muted); }
.score {
  font-family: var(--display); font-size: 76px; font-weight: 600; line-height: 1;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.pill {
  display: inline-flex; align-items: center; gap: 8px; background: var(--spring-bg); color: var(--spring-d);
  border-radius: 999px; padding: 8px 18px; font-size: 17px; font-weight: 600;
  animation: pill-in 200ms ease-out;
}
.pill.amb { background: var(--sun-bg); color: var(--sun); }
.pill.berry { background: #F7E4EA; color: var(--berry); }
@keyframes pill-in { from { opacity: 0; transform: scale(.8); } to { opacity: 1; transform: none; } }

/* --- belts (M2, ported from show wireframe) ---------------------------------- */
:root {
  --b-white: #EDE9E1; --b-yellow: #E8C34A; --b-orange: #D98736; --b-green: #1F8A6D;
  --b-blue: #3B7EA1; --b-purple: #7A5CA8; --b-brown: #7B5B3F; --b-black: #2C2A26;
}
.wbelt {
  position: relative; width: 250px; height: 30px; border-radius: 7px; margin: 16px auto 2px;
  box-shadow: inset 0 -5px 0 rgba(0, 0, 0, .14), 0 6px 16px rgba(40, 34, 20, .12);
}
.wbelt::before {
  content: ""; position: absolute; inset: 0; border-radius: 7px;
  background: repeating-linear-gradient(115deg, rgba(255, 255, 255, .10) 0 9px, rgba(0, 0, 0, .05) 9px 18px);
}
.wbelt .knot {
  position: absolute; left: 50%; top: -4px; bottom: -4px; transform: translateX(-50%);
  width: 40px; border-radius: 6px; background: inherit; filter: brightness(.82);
}
.beltpill { font-size: 12px; font-weight: 700; padding: 3px 10px; border-radius: 99px; }

/* --- game elements ------------------------------------------------------------------ */
.tiles { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; margin: 26px 0; }
.tile {
  width: 62px; height: 62px; border-radius: var(--r-btn); border: 0; cursor: pointer;
  background: var(--spring-bg); color: var(--spring-d);
  font-size: 30px; font-weight: 650; font-family: var(--body);
  display: flex; align-items: center; justify-content: center;
  transition: transform 90ms ease-out, background 120ms, color 120ms;
}
.tile:hover { background: var(--spring); color: #fff; }
.tile:active { transform: scale(.94); }
.tile.q { background: var(--card); border: 2px dashed var(--line); color: var(--muted); }

.grid4 { display: grid; grid-template-columns: repeat(4, 72px); gap: 12px; justify-content: center; margin: 26px 0; }
.cell { aspect-ratio: 1; min-width: 48px; border-radius: var(--r-btn); background: var(--card); border: 1px solid var(--line); cursor: pointer; padding: 0; transition: transform 90ms ease-out; }
.cell:active { transform: scale(.94); }
.cell.a { background: var(--spring-bg); border-color: var(--spring); }
.cell.ok { outline: 3px solid var(--spring); outline-offset: -3px; }

.checks { max-width: 430px; margin: 22px auto; text-align: left; display: flex; flex-direction: column; gap: 12px; font-size: 18px; }
.checks div::before { content: "✓"; color: var(--spring); font-weight: 700; margin-right: 12px; }

.chips { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; margin-top: 10px; min-height: 44px; }
.chip { background: var(--card); border: 1px solid var(--line); border-radius: 999px; padding: 8px 16px; font-size: 17px; animation: pill-in 200ms ease-out; }

input[type=text], input[type=email] {
  width: 100%; max-width: 420px; font-size: 20px; padding: 16px 18px;
  border-radius: var(--r-btn); border: 1px solid var(--line); background: var(--card);
  margin: 8px 0 4px; font-family: var(--body);
}
.fine { font-size: 15px; color: var(--muted); margin-top: 14px; }
.topbar { display: flex; justify-content: space-between; align-items: center; font-size: 17px; color: var(--muted); margin-bottom: 26px; }
.streak { color: var(--sun); font-weight: 600; font-variant-numeric: tabular-nums; }
.lockrow { display: flex; align-items: center; gap: 10px; justify-content: center; background: var(--sun-bg); color: var(--sun); border-radius: var(--r-btn); padding: 12px 18px; font-size: 17px; font-weight: 600; max-width: 520px; margin: 0 auto 22px; }

/* focus dimming (§0C): during play, everything but the puzzle goes quiet */
body.playing .topbar, body.playing .masthead, body.playing #spry-corner, body.playing #nav {
  opacity: .55; filter: saturate(.85);
  transition: opacity 600ms ease-out, filter 600ms ease-out;
}
body:not(.playing) .topbar, body:not(.playing) .masthead {
  transition: opacity 600ms ease-out, filter 600ms ease-out;
}

/* --- hover-reveal nav ------------------------------------------------------------------ */
#nav { position: fixed; left: 0; top: 0; bottom: 0; width: 26px; background: var(--card); border-right: 1px solid var(--line); z-index: 50; transition: width .18s ease; overflow: hidden; display: none; }
#nav.app { display: block; }
#nav .hint { position: absolute; top: 50%; left: 7px; transform: translateY(-50%); width: 5px; height: 76px; border-radius: 999px; background: var(--spring); }
#nav:hover, #nav:focus-within { width: 230px; }
#nav ul { list-style: none; padding: 26px 0 0 0; opacity: 0; transition: opacity .15s; }
#nav:hover ul, #nav:focus-within ul { opacity: 1; }
#nav a { display: block; padding: 15px 26px; font-size: 19px; color: var(--ink); text-decoration: none; white-space: nowrap; }
#nav a:hover { background: var(--spring-bg); color: var(--spring-d); }
#nav .navlab { padding: 0 26px 8px; font-size: 12px; letter-spacing: .1em; color: var(--muted); }
.haspad { padding-left: 40px; }

/* --- Spry host (contracts §7) ------------------------------------------------------------- */
#spry-corner {
  position: fixed; left: 18px; bottom: 18px; z-index: 60;
  display: flex; align-items: flex-end; gap: 12px; max-width: 340px;
  opacity: 0; transform: translateY(8px); pointer-events: none;
  transition: opacity .3s, transform .3s;
}
#spry-corner.on { opacity: 1; transform: none; }
#spry-corner .spry { width: 56px; height: 56px; margin: 0; flex: none; }
#spry-corner .txt { background: var(--card); border: 1px solid var(--line); border-radius: 16px; border-bottom-left-radius: 4px; padding: 12px 16px; font-size: 17px; font-family: var(--display); font-weight: 500; box-shadow: var(--shadow); }
#spry-center {
  position: fixed; inset: 0; z-index: 70; background: rgba(35, 34, 31, .45);
  display: flex; align-items: center; justify-content: center; padding: 24px;
}

/* --- juice (§2) ------------------------------------------------------------------------------ */
.j-pop { animation: j-pop 220ms cubic-bezier(.34, 1.56, .64, 1); }
@keyframes j-pop { 0% { transform: scale(1); } 45% { transform: scale(var(--pop-scale, 1.12)); } 100% { transform: scale(1); } }
.j-glow { animation: j-glow 500ms ease-out; }
@keyframes j-glow { 0% { box-shadow: 0 0 0 0 rgba(31, 138, 109, .45); } 100% { box-shadow: 0 0 18px 10px rgba(31, 138, 109, 0); } }
.j-shake { animation: j-shake 180ms ease-in-out; }
@keyframes j-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-4px); } 65% { transform: translateX(4px); } }
.j-settle { animation: j-settle 240ms ease-out; }
@keyframes j-settle { 0% { transform: translateY(-4px); } 70% { transform: translateY(1px); } 100% { transform: none; } }
.j-dim { filter: saturate(.6); opacity: .75; transition: filter .3s, opacity .3s; }

.confetti-bit { position: fixed; width: 9px; height: 9px; border-radius: 2px; pointer-events: none; z-index: 80; }

/* sunrise reveal (§4A): radial dawn glow behind the card */
.sunrise { position: relative; overflow: hidden; }
.sunrise::before {
  content: ''; position: absolute; inset: -40%; pointer-events: none;
  background: radial-gradient(circle at 50% 72%, rgba(224, 145, 58, .22), rgba(251, 238, 218, .1) 45%, transparent 70%);
  animation: sunrise-rise 2200ms ease-out forwards;
}
@keyframes sunrise-rise {
  from { opacity: 0; transform: translateY(24%); }
  60% { opacity: 1; }
  to { opacity: .6; transform: none; }
}

/* --- show stage (M3 ScenePlayer, ported from show wireframe) ---------------------- */
/* STAGE MARGINS (Seth 2026-07-24): a show's theme.css may author the stage's
   top/left/right margins per mode (--stage-*; the write-through releases the
   720px cap with --stage-max:none). The nav keeps the stage's own top frame
   and the host/controls keep a floor below the scenes — authored margins can
   narrow the stage, never push the chrome off. */
/* definite viewport-bound height (review #6): the frame must SHRINK to the
   window, never inflate the stage past it — dvh tracks mobile chrome */
.stage { max-width: var(--stage-max, 720px); width: 100%; margin: 0 auto; height: 100vh; height: 100dvh; display: flex; flex-direction: column; padding: 14px max(var(--stage-right, 22px), 10px) 16px max(var(--stage-left, 22px), 10px); position: relative; }
.chipsrow { display: flex; align-items: center; gap: 12px; }
.chips { display: flex; gap: 4px; flex: 1; }
.chips .c { height: 5px; flex: 1; background: var(--line); border-radius: 99px; overflow: hidden; cursor: pointer; }
.chips .c i { display: block; height: 100%; width: 0; background: var(--spring); border-radius: 99px; transition: width .4s ease; }
.chap { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin-top: 7px; text-align: center; min-height: 15px; }
.mutebtn { background: var(--card); border: 1px solid var(--line); border-radius: 99px; width: 38px; height: 38px; font-size: 15px; cursor: pointer; color: var(--muted); flex-shrink: 0; }
/* authored top margin = air between the nav and the scene; the bottom floor
   is platform-owned — the host dock and ♡/Skip always keep their landing */
/* THE 16:9 LAW (Seth 2026-07-25): the stage holds 16:9 — video plays full
   screen at its native ratio, stage stills land uncropped, bridges land on
   node frames pixel-true, and every node designs against ONE canvas. The
   scene frame letterboxes inside whatever window it gets (the paper around
   it is where chrome lives); PORTRAIT is the exemption — the stage fills
   the phone and the 16:9 video letterboxes within it, television-style. */
.scenes { flex: 1; min-height: 0; position: relative; display: grid; grid-template-columns: 100%; grid-template-rows: 100%; place-items: center; padding-top: var(--stage-top, 0px); padding-bottom: max(var(--stage-bottom, 0px), 52px); }
/* wide stages need a reading measure — headlines never run the full bleed */
.scene h1, .scene h2 { max-width: 28ch; margin-left: auto; margin-right: auto; }
.scene { grid-area: 1 / 1; position: relative; width: min(100%, calc(var(--scenes-h, 480px) * 16 / 9)); aspect-ratio: 16 / 9; overflow: hidden; display: none; flex-direction: column; align-items: center; justify-content: center; text-align: center; padding: 8px 0; }
.scene.on { display: flex; }
/* PORTRAIT = the same 16:9 stage, letterboxed (Seth 2026-07-25: "letterbox
   everything, suggest rotating") — no portrait variant of any node exists.
   The hint lives in the paper below the frame; games compress their chrome
   so the strip stays playable until the phone turns. */
.scenes::after { content: '⟳ rotate for the full picture'; grid-area: 1 / 1; align-self: center; justify-self: center; transform: translateY(calc(var(--frame-h, 240px) / 2 + 30px)); font-size: 12.5px; letter-spacing: .06em; color: var(--muted); display: none; pointer-events: none; }
@media (orientation: portrait) {
  .scenes::after { display: block; }
  /* .scene prefix: outranks the base .gamebox.staged rules regardless of
     file order (the base cell-size rule sits later in this sheet) */
  /* the floor yields on tiny phones — a clipped board is worse than small cells (Sol review) */
  .scene .gamebox.staged { padding: 10px 14px; --c4-cell-size: clamp(11px, calc((var(--frame-h, 240px) - 92px) / 6 - 6px), 72px); }
  .scene .gamebox.staged .gk { display: none; }
  .scene .gamebox.staged h2 { font-size: 14px; margin-bottom: 4px; }
  .scene .gamebox.staged .fine { display: none; }
  .scene .gamebox.staged .c4-board { margin: 6px 0 !important; padding: 8px !important; gap: 4px !important; }
}
.kick { font-size: 13px; letter-spacing: .14em; text-transform: uppercase; color: var(--muted); margin-bottom: 10px; }
.sub { color: var(--muted); font-size: 19px; max-width: 480px; margin-top: 12px; }
.sub b { color: var(--ink); }
.cta {
  display: inline-flex; align-items: center; gap: 9px; background: var(--spring); color: #fff;
  border: none; text-decoration: none; font-size: 20px; font-weight: 600; font-family: var(--body);
  padding: 15px 38px; border-radius: 14px; margin-top: 22px; cursor: pointer;
  box-shadow: 0 8px 22px rgba(31, 138, 109, .22); transition: transform .09s, background .15s;
}
.cta:hover { background: var(--spring-d); } .cta:active { transform: scale(.97); }
.cta2 { background: var(--card); color: var(--muted); border: 1px solid var(--line); box-shadow: none; font-size: 17px; padding: 12px 24px; }
.grid { display: grid; grid-template-columns: repeat(2, minmax(0, 230px)); gap: 11px; margin-top: 20px; justify-content: center; }
@media (min-width: 560px) { .grid.g3 { grid-template-columns: repeat(3, minmax(0, 170px)); } }
.gcardb { background: var(--card); border: 1.5px solid var(--line); border-radius: 14px; padding: 15px 13px; font-size: 16.5px; cursor: pointer; transition: all .15s; user-select: none; }
.gcardb .em { font-size: 22px; display: block; margin-bottom: 5px; }
.gcardb.sel { border-color: var(--spring); background: var(--spring-bg); color: var(--spring-d); font-weight: 600; }
.gcardb:hover { border-color: var(--spring); }
.cele { background: var(--spring-bg); border-radius: 20px; padding: 30px 36px; max-width: 490px; }
.cele.amber { background: var(--sun-bg); }
.sp-dock { position: absolute; left: 10px; bottom: 4px; width: 62px; height: 62px; z-index: 30; pointer-events: none; }
.sp-dock svg { width: 100%; filter: drop-shadow(0 4px 10px rgba(31, 138, 109, .25)); }
.dockbubble { position: absolute; left: 78px; bottom: 12px; max-width: 52%; background: var(--card); border: 1px solid var(--line); border-radius: 14px; border-bottom-left-radius: 4px; padding: 8px 13px; font-size: 14.5px; opacity: 0; z-index: 30; text-align: left; box-shadow: 0 4px 14px rgba(40, 34, 20, .08); transition: opacity .3s; font-family: var(--display); }
/* the ctrl row must WIN clicks — tall scenes overflow over it and were
   swallowing like/back/skip (Seth 2026-07-22) */
.ctrl { display: flex; align-items: center; justify-content: center; gap: 14px; padding-top: 10px; position: relative; z-index: 70; }
.ctrl button { background: var(--card); border: 1px solid var(--line); border-radius: 99px; width: 42px; height: 42px; font-size: 16px; color: var(--muted); cursor: pointer; box-shadow: 0 1px 6px rgba(0,0,0,.08); }
#sp-like.on { animation: likepop .25s ease; }
@keyframes likepop { 40% { transform: scale(1.35); } }
.ctrl .skip { width: auto; border-radius: 99px; padding: 0 16px; font-size: 13.5px; }
.rig #spry-body { transform-origin: 32px 40px; }
.rig #spry-head { transform-origin: 32px 32px; }
.rig #spry-tail { transform-origin: 52px 46px; }
.rig .eye { transform-box: fill-box; transform-origin: center; }
body.playing .chipsrow, body.playing .chap, body.playing .ctrl, body.playing .sp-dock { opacity: .55; transition: opacity .4s; }

/* --- M5 premiere scenes (ported from show wireframe) ------------------------------ */
.plantrow { display: flex; gap: 14px; justify-content: center; margin: 20px 0 4px; flex-wrap: wrap; }
.word { background: var(--card); border: 1px solid var(--spring); border-radius: 14px; padding: 16px 22px; font-family: var(--display); font-size: 24px; font-weight: 600; box-shadow: 0 4px 14px rgba(40, 34, 20, .06); background: var(--spring-bg); color: var(--spring-d); }
.bigscore { font-family: var(--display); font-size: 80px; font-weight: 600; line-height: 1; font-variant-numeric: tabular-nums; }
.dawn { position: absolute; inset: 0; background: radial-gradient(circle at 50% 62%, rgba(224, 145, 58, .16), transparent 55%); opacity: 0; transition: opacity 1.6s ease; pointer-events: none; }
.scene.on .dawn { opacity: 1; }
.mapgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; width: 100%; max-width: 540px; margin-top: 16px; }
@media (max-width: 560px) { .mapgrid { grid-template-columns: repeat(2, 1fr); } }
.mapcard { background: var(--card); border: 1px solid var(--line); border-radius: 13px; padding: 11px 12px; text-align: left; opacity: 0; transform: translateY(10px); transition: all .4s; }
.mapcard.in { opacity: 1; transform: none; }
.mapcard.focus { border-color: var(--sun); box-shadow: 0 0 0 1px var(--sun); }
.mapcard .mh { display: flex; justify-content: space-between; align-items: center; font-size: 14.5px; font-weight: 600; margin-bottom: 5px; }
.mapcard .bp { font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 99px; }
.mapcard .mo { font-size: 12.5px; color: var(--muted); line-height: 1.35; }
.plan { background: var(--card); border: 1px solid var(--line); border-radius: 18px; padding: 22px 24px; max-width: 480px; text-align: left; box-shadow: 0 6px 22px rgba(40, 34, 20, .07); }
.plan h2 { font-family: var(--display); font-size: 24px; text-align: center; margin-bottom: 14px; }
.plan .li { display: flex; gap: 11px; padding: 10px 0; border-top: 1px solid var(--line); font-size: 16px; }
.plan .li:first-of-type { border-top: none; }
.plan .li .em { font-size: 20px; flex-shrink: 0; }
.plan .li b { display: block; font-size: 16.5px; }
.plan .li span { color: var(--muted); font-size: 14.5px; }
.plan .li span i { color: var(--spring-d); font-style: normal; font-weight: 600; }
.proj { background: var(--card); border: 1px solid var(--line); border-radius: 18px; padding: 20px 22px 14px; max-width: 460px; }
.proj svg { width: 100%; }
.projdate { font-family: var(--display); font-size: 19px; color: var(--sun); font-weight: 600; }
.gamebox { background: var(--card); border: 2px solid var(--spring); border-radius: 16px; padding: 22px 24px; max-width: 480px; width: 100%; box-shadow: 0 6px 22px rgba(31, 138, 109, .10); }
/* THE DRESSED STAGE (2026-07-24): stage.backdrop paints the show's world
   behind the play; a soft scrim keeps the words readable on any art */
/* THE STAGE MODEL (Seth 2026-07-25): the stage is the whole area where
   interaction and display occur — the backdrop is its SURFACE, not a card
   floating on paper. The staged box fills the scene area top to bottom;
   the play centers on it. */
.gamebox.staged { background-size: cover; background-position: center; border: none; max-width: none; width: 100%; min-height: 100%; align-self: stretch; display: grid; align-content: center; justify-items: center; padding: 26px 34px; position: relative; overflow: hidden; border-radius: 14px; }
.scene:has(.gamebox.staged), .scene:has([data-vs]) { padding: 0; }
/* the backdrop's own clear zone IS the scrim (the mint leaves the center
   empty) — only a whisper of lift so type never fights a stray petal */
.gamebox.staged::before { content: ''; position: absolute; inset: 0; background: rgba(255, 253, 248, .10); pointer-events: none; }
.gamebox.staged > * { position: relative; }
.gamebox.staged h2, .gamebox.staged .gk { text-shadow: 0 1px 6px rgba(255, 253, 248, .9); }
/* tabletop illusion, flat: the board sits ON the stage via contact shadow —
   no perspective tilt (watercolor storybook stays a flat medium) */
.gamebox.staged .c4-board { box-shadow: 0 12px 28px rgba(50, 45, 38, .25), 0 2px 8px rgba(50, 45, 38, .18); width: fit-content; margin-inline: auto !important; }
/* the play scales to the FRAME (16:9 law): cell size derives from the frame
   height minus the chrome budget (title + legend + message + paddings), so
   the board always fits the stage — bigger frame, bigger board */
.gamebox.staged { --c4-cell-size: clamp(28px, calc((var(--frame-h, 480px) - 255px) / 6 - 6px), 72px); }
.gamebox.staged .c4-board { grid-template-columns: repeat(7, var(--c4-cell-size)) !important; }
.gamebox.staged .c4-board .c4 { width: var(--c4-cell-size) !important; height: var(--c4-cell-size) !important; }
/* (the old fluid-board mobile rule died with the 16:9 law — the frame-derived
   cell size covers every screen, portrait included) */
.gamebox .gk { font-size: 12px; letter-spacing: .12em; text-transform: uppercase; color: var(--spring-d); font-weight: 700; margin-bottom: 6px; }
.gamebox h2 { font-family: var(--display); font-size: 22px; font-weight: 600; margin-bottom: 12px; }
.bmeter { height: 11px; background: #EFEAE0; border-radius: 99px; overflow: hidden; width: 100%; max-width: 430px; margin: 16px auto 4px; }
.bmeter i { display: block; height: 100%; width: 0; background: var(--spring); border-radius: 99px; transition: width .5s ease; }
.blist { max-width: 430px; text-align: left; font-size: 16.5px; display: flex; flex-direction: column; gap: 8px; min-height: 170px; margin-top: 12px; }
.blist div { opacity: 0; transition: opacity .3s; }
.blist div.in { opacity: 1; }
.blist div::before { content: "✓"; color: var(--spring); font-weight: 700; margin-right: 9px; }
.cele .pill { background: var(--card); }
.rounds { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* --- M7 guide (home between episodes) ----------------------------------------------- */
.gwrap { max-width: 600px; margin: 0 auto; padding: 26px 22px 80px; }
.mast { text-align: center; margin-bottom: 18px; }
.mast small { letter-spacing: .14em; text-transform: uppercase; font-size: 12.5px; color: var(--muted); }
.mast .rule { height: 1px; background: var(--line); margin: 10px 0; }
.mast .dl { font-family: var(--display); font-size: 15px; color: var(--muted); }
.gcard { background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 20px; margin-bottom: 14px; box-shadow: var(--shadow); }
.gcard h2 { font-size: 13px; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); font-weight: 600; margin-bottom: 12px; font-family: var(--body); }
.beltrow { display: flex; gap: 16px; justify-content: center; margin-top: 18px; flex-wrap: wrap; }
.beltcard { background: var(--card); border: 1px solid var(--line); border-radius: 14px; padding: 14px 18px; min-width: 130px; }
.beltcard .a { font-size: 15px; font-weight: 600; }
.beltcard .mini { height: 10px; border-radius: 4px; margin: 8px 4px 5px; box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .14); }
.beltcard .b { font-size: 13px; color: var(--muted); }
.arow { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 16.5px; }
.arow:last-child { border-bottom: none; }
.arow .nm { flex: 1; font-weight: 600; }
.arow .next { font-size: 13px; color: var(--muted); } .arow .next b { color: var(--sun); }
.gcta { display: block; text-align: center; background: var(--spring); color: #fff; text-decoration: none; font-size: 19px; font-weight: 600; padding: 15px; border-radius: 13px; cursor: pointer; }
.gmenu { display: flex; justify-content: center; gap: 16px; font-size: 15px; margin-top: 16px; flex-wrap: wrap; }
.gmenu a { color: var(--spring-d); cursor: pointer; text-decoration: underline; }

/* --- storyboard placeholder (shown whenever a video asset is missing) --------------- */
.sb { border: 2px dashed var(--sun); border-radius: 18px; background: var(--sun-bg); padding: 16px 18px; max-width: 640px; width: 100%; text-align: left; }
.sb .sbhead { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.sb .sbtitle { font-family: var(--display); font-size: 19px; font-weight: 600; }
.sb .sbmeta { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: var(--sun); font-weight: 700; white-space: nowrap; }
.sb .sbnote { font-size: 12.5px; color: var(--muted); margin-bottom: 12px; }
.sb .sbposter { width: 100%; max-height: 200px; object-fit: cover; border-radius: 12px; margin-bottom: 10px; }
.sb .shots { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 6px; }
.sb .shot { flex: 0 0 172px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; }
.sb .shot .sn { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--sun); font-weight: 700; margin-bottom: 5px; }
.sb .shot .sd { font-size: 13.5px; line-height: 1.4; }
.sb .vo { margin-top: 12px; background: var(--card); border-left: 3px solid var(--sun); border-radius: 0 10px 10px 0; padding: 9px 13px; font-size: 14.5px; font-style: italic; }
.sb .vo b { font-style: normal; font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--sun); display: block; margin-bottom: 2px; }

/* --- M4 video seam --------------------------------------------------------------- */
.vscene { padding: 0; }
.vfull { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: 18px; background: #111; }
.vskip {
  position: absolute; right: 14px; bottom: 14px; z-index: 5;
  background: rgba(255, 255, 255, .92); border: 1px solid var(--line); border-radius: 99px;
  padding: 10px 20px; font-size: 15px; font-family: var(--body); color: var(--ink); cursor: pointer;
}
.vwatch {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); z-index: 5;
  background: rgba(255, 255, 255, .95); border: 1px solid var(--line); border-radius: 99px;
  padding: 18px 40px; font-size: 21px; font-weight: 600; font-family: var(--body);
  color: var(--ink); cursor: pointer; box-shadow: var(--shadow-lift);
}
/* ONE SURFACE (Seth 2026-07-25): film, bridge, and game all play in the SAME
   16:9 stage frame — identical rectangle, identical corners, chrome constant
   around it. The transition mounts as a scene-shaped layer over the frame
   (not a window-filling overlay), so every cut is pixel-true. */
.scenes .transvid { z-index: 5; }

/* --- transitions (Seth 2026-07-22): free tier wipes + video interstitials --- */
.sp-wipe { position: absolute; inset: 0; z-index: 60; pointer-events: none; }
.sp-wipe.sweep { background: var(--spring); opacity: .97; transform: translateX(-101%); transition: transform .3s ease-in; }
.sp-wipe.sweep.in { transform: translateX(0); }
.sp-wipe.sweep.out { transform: translateX(101%); transition: transform .34s ease-out; }
.sp-wipe.fade { background: var(--paper); opacity: 0; transition: opacity .26s; }
.sp-wipe.fade.in { opacity: 1; }
.sp-wipe.fade.out { opacity: 0; }
/* the host dock's avatar media (video mood clip or still) fills its circle */
.dockv { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; box-shadow: 0 4px 10px rgba(31, 138, 109, .25); }

/* --- text size XL (settings) -------------------------------------------------------------------- */
body.xl { font-size: 23px; }
body.xl .btn { font-size: 24px; }
body.xl h1 { font-size: 38px; }
body.xl h2 { font-size: 29px; }

/* --- toast ----------------------------------------------------------------------------------------- */
#toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%);
  background: var(--ink); color: var(--paper); font-size: 18px;
  padding: 14px 22px; border-radius: var(--r-btn); max-width: 90vw;
  opacity: 0; pointer-events: none; transition: opacity .25s; z-index: 99;
}
#toast.on { opacity: 1; }

/* --- reduced motion (global rule): instant states, no decorative motion ----------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  #grain { display: none; }
}

/* nav honesty (2026-07-22): back is disabled until there's history */
.ctrl button:disabled { opacity: .3; cursor: default; }
#sp-like.on { color: #B5533C; border-color: #B5533C; }

/* THE EXPERIENCE BASE's shared vocabulary (Seth 2026-07-27): every leaf
   built on engine/experience.js renders through these, so theme.css tokens
   skin every experience per show — leaves never inline their look. */
.xp-grid { display: grid; gap: 10px; justify-content: center; padding: 10px; }
.xp-cell { aspect-ratio: 1; font-size: 30px; cursor: pointer;
  border-radius: var(--r-btn, 9px); border: 2px solid var(--c4-line, #8883);
  background: var(--c4-board, #9992); transition: background .15s, opacity .3s; }
.xp-cell.xp-up { background: var(--c4-cell, #fff); }
.xp-cell.xp-matched { background: var(--c4-cell, #fff); opacity: .45; }
.xp-cell:disabled { cursor: default; }
.xp-hud { text-align: center; font-size: 12px; color: var(--mut, #8b857a); padding: 4px 0 8px; }
.xp-prompt { text-align: center; font-size: 17px; font-weight: 600; padding: 14px 18px 6px; }
.xp-choices { display: flex; flex-direction: column; gap: 8px; max-width: 420px; margin: 8px auto; padding: 0 14px; }
.xp-choice { padding: 10px 14px; font-size: 14px; text-align: left; cursor: pointer;
  border-radius: var(--r-btn, 9px); border: 2px solid var(--c4-line, #8883);
  background: var(--c4-cell, #fff); transition: background .2s, border-color .2s; }
.xp-choice.xp-good { border-color: var(--c4-you, #4a7c59); background: color-mix(in srgb, var(--c4-you, #4a7c59) 18%, var(--c4-cell, #fff)); }
.xp-choice.xp-bad { border-color: var(--c4-host, #a05a2c); opacity: .6; }
.xp-choice:disabled { cursor: default; }
.xp-explain { text-align: center; font-size: 13px; color: var(--mut, #8b857a); max-width: 420px; margin: 0 auto; padding: 2px 14px 8px; }
/* host-beat: the length bar the viewer owns. It measures the BEAT — never the
   viewer — so nothing here ever renders a number about the person. */
.hb-bar { position: relative; height: 6px; max-width: 420px; margin: 18px auto 0; cursor: pointer;
  border-radius: 999px; background: var(--c4-line, #8883); }
.hb-bar:focus-visible { outline: 2px solid var(--spring, #a0522d); outline-offset: 4px; }
.hb-fill { height: 100%; border-radius: 999px; background: var(--spring, #a0522d); transition: width .2s linear; }
.hb-controls { display: flex; gap: 8px; justify-content: center; padding: 10px 0 2px; }
.hb-btn { padding: 6px 14px; font-size: 13px; cursor: pointer;
  border-radius: var(--r-btn, 9px); border: 1px solid var(--c4-line, #8883);
  background: transparent; color: var(--mut, #8b857a); }

/* card-placement experiences: the card in hand, the push-back, and the wall of
   cards already got. The wall is a row of cards, never a count — no counter is
   rendered here and none should be added. */
.xp-hand { text-align: center; font-size: 26px; font-weight: 600; letter-spacing: .01em;
  max-width: 420px; margin: 10px auto 4px; padding: 18px 16px;
  border-radius: var(--r-btn, 9px); border: 2px solid var(--c4-line, #8883);
  background: var(--c4-cell, #fff); }
.xp-hand-empty { opacity: 0; min-height: 68px; }
.xp-park { display: block; margin: 8px auto; padding: 8px 16px; font-size: 13px; cursor: pointer;
  border-radius: var(--r-btn, 9px); border: 1px solid var(--c4-line, #8883);
  background: transparent; color: var(--mut, #8b857a); }
.xp-wall { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center;
  max-width: 460px; margin: 14px auto 6px; padding: 0 14px; }
/* a card under the finger. No colour change and no shadow shift on drop —
   a misplaced card must look exactly like one put back on purpose. */
.xp-dragging { cursor: grabbing; opacity: .92; z-index: 3; position: relative; touch-action: none; }
.xp-hand[data-drag] { cursor: grab; touch-action: none; user-select: none; }
.xp-card { font-size: 13px; padding: 5px 9px;
  border-radius: var(--r-btn, 9px); border: 1px solid var(--c4-line, #8883);
  background: var(--c4-cell, #fff); }

/* card-wall: the viewer's wall. NOTHING here renders a count — not a number, not
   a meter, not an "x of y". Empty space is room. */
.cw-wall { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center;
  max-width: 460px; margin: 16px auto 4px; padding: 0 14px; }
.cw-empty { min-height: 90px; }
.cw-room { flex: 1; min-height: 90px; border-radius: var(--r-card, 9px);
  border: 1px dashed var(--c4-line, #8883); opacity: .5; }
.cw-card { cursor: pointer; padding: 8px 11px; text-align: left;
  border-radius: var(--r-card, 9px); border: 1px solid var(--c4-line, #8883);
  background: var(--c4-cell, #fff); }
.cw-es { font-size: 15px; font-weight: 600; }
.cw-en { font-size: 12px; color: var(--mut, #8b857a); margin-top: 2px; }
.cw-also { display: none; font-size: 12px; color: var(--mut, #8b857a);
  margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--c4-line, #8883); }
.cw-card.cw-open .cw-also { display: block; }

/* the drill's scrim: every card screen sits on its own dark panel, because the
   stage plate behind it is a lit room and ink-on-light was unreadable there. */
.xp-scrim { max-width: 480px; margin: 8px auto; padding: 14px 12px 18px;
  border-radius: var(--r-card, 12px);
  background: color-mix(in srgb, var(--paper, #13100E) 88%, transparent);
  box-shadow: 0 8px 30px rgba(0,0,0,.35); }
/* targets are MOMENTS from the scene — faces, objects, instants. Never English strips. */
.xp-moments { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px;
  max-width: 440px; margin: 10px auto; padding: 0 6px; }
.xp-moment { aspect-ratio: 16/9; cursor: pointer; padding: 0; border-radius: var(--r-btn, 9px);
  border: 2px solid var(--c4-line, #8883); background-size: cover; background-position: center;
  transition: border-color .12s; }
.xp-moment:hover { border-color: var(--spring, #F2542D); }

/* ---- THE MINDGARDEN: boards, asks and the pattern path ---------------------
   The board's own chrome lives with the board (experiences/lib/board.js); this
   is the copy around it and the Pattern Path's overlaid tiles. Sizes are set
   for 55-85 on a tablet: nothing here is smaller than 18px, and every tap
   target clears 56px. */
.mg-ask{font-size:20px;line-height:1.35;text-align:center;margin:0 0 14px;color:var(--ink)}
.mg-count{text-align:center;color:#fff;font-size:17px;margin:0;text-shadow:0 1px 5px rgba(0,0,0,.6)}
.mg-enough{font-size:18px;font-weight:700;padding:12px 22px;border-radius:var(--r-btn,9px);
  border:2px solid rgba(255,255,255,.8);background:rgba(255,253,248,.92);color:var(--ink);
  cursor:pointer;box-shadow:0 3px 14px rgba(0,0,0,.3)}
.pp-run{display:flex;justify-content:center;align-items:center;gap:10px;margin:0;flex-wrap:wrap}
/* 2x (Seth 2026-08-24, user test: sequence icons + tiles too small) */
.pp-s,.pp-q{font-size:90px;line-height:1;filter:drop-shadow(0 1px 3px rgba(0,0,0,.45))}
.pp-q{color:#fff;font-weight:800}
.pp-choices{display:flex;justify-content:center;gap:14px;margin:0;flex-wrap:wrap}
.pp-c{font-size:48px;line-height:1;min-width:104px;min-height:104px;border-radius:var(--r-btn,9px);
  /* legible over a photograph, not over paper */
  border:2px solid rgba(255,255,255,.75);background:rgba(255,253,248,.90);
  cursor:pointer;transition:transform .12s,box-shadow .18s;box-shadow:0 3px 12px rgba(0,0,0,.28)}
.pp-c:hover,.pp-c:focus-visible{box-shadow:0 4px 16px rgba(0,0,0,.14);outline:none}
.pp-c:active{transform:scale(.95)}
.pp-c.right{box-shadow:0 0 0 4px var(--spring),0 0 22px 6px rgba(255,246,214,.7)}
/* a miss dims the tile for a moment — never red, never a shake */
.pp-c.wrong{opacity:.45}
.pp-stones{text-align:center;letter-spacing:.35em;font-size:18px;color:#fff;margin:0;text-shadow:0 1px 4px rgba(0,0,0,.5)}
@media (max-width:560px){.pp-s,.pp-q{font-size:64px}.pp-c{font-size:36px;min-width:76px;min-height:76px}}
@media (prefers-reduced-motion:reduce){.pp-c{transition:none}}

/* FULL-BLEED BOARDS (Seth 2026-08-17: "we are always in this garden and not in
   an app"; 16:9 is the plate, native on laptops and phones, letterboxed on
   iPads). The board fills the stage edge to edge, the letterbox is filled with
   a blurred copy of the same picture, and every piece of furniture — the
   question, the counter, the buttons — rides ON the picture. Nothing here is a
   card, so none of the card's chrome applies. */
/* SAMENESS BEATS FULL BLEED (Seth, play-test 2026-08-19: "the game board is
   being rendered at a different size than the videos"). The board used to break
   out of the stage entirely — max-width:none, padding:0 — while a video scene
   stayed inside the 720px stage box. Measured on one viewport: board 581x324 at
   left 8, film 436x245 at left 81. Both 16:9, so the CUT between them was a jump
   in scale and position, which is exactly what a seam must not be.
   The board now sits in the same stage box as the film. This supersedes the
   full-bleed half of the 2026-08-17 ruling and restores the video-scene law
   ("the same 16:9 stage frame as everything else... sameness across film/bridge/
   game is what makes the cuts read smooth"). The garden still reaches every edge
   INSIDE that frame via the blurred wrap, so the game is still not a card. */
.stage:has(.mg-board) { padding: 14px max(var(--stage-right, 22px), 10px) 16px max(var(--stage-left, 22px), 10px); }
.scene:has(.mg-board) { padding: 0; }
/* NOT .scenes — its padding is what --scenes-h is measured from (a
   ResizeObserver on #sp-scenes reads contentRect, which excludes padding), and
   CSS derives every scene's 16:9 frame from that variable. Zeroing it only on
   game scenes made the board's frame measure taller than a film's, so the two
   scene types drew different-sized pictures: 528x295 against 436x245. The
   padding stays, so board and film are handed the same frame. */
.gamebox:has(.mg-board) { max-width: none; border: none; background: transparent;
  box-shadow: none; padding: 0; height: 100%; width: 100%; position: relative; }
/* the card's own heading and kicker are replaced by .mg-title on the plate */
.gamebox:has(.mg-board) > h2, .gamebox:has(.mg-board) > .gk { display: none; }
.gamebox:has(.mg-board) > [data-xp] { position: static; }
/* the wrap is no longer full-screen, so the scene frame clips it again — the
   blurred garden fills the FRAME, not the window (2026-08-19) */
.scene:has(.mg-board) { overflow: hidden; }
.gamebox:has(.mg-board) > [data-xp] { position: absolute; inset: 0; }
/* THE PRE-BOARD FLASH (Seth 2026-08-19: "still the white flash... from video
   to game board"). Between the game scene mounting and the leaf's code+images
   arriving, the bare gamebox card paints — pale bg, 2px border, its title — for
   one frame warm, visibly longer on a cold import. Video->video has no such gap,
   which was exactly the symptom. While the experience mount point is still
   empty, the whole card stays invisible: the stage paper holds (the same ground
   every video sits on), and the board appears in one piece when it is ready. */
.gamebox:has(> [data-xp]:empty) { visibility: hidden; }
/* ...and stays invisible until the plate can paint (board.js decode gate) —
   the board appears in one piece, never frame-then-picture */
.gamebox:has(.mg-board.mg-wait) { visibility: hidden; }

/* chrome floats above the garden */
.hostbar, .sctls, .scenes::after { z-index: 40; }
/* the pattern path stacks a run + choices under its plate, so its plate yields */
