/*
 * Lumina Shell: the shared player interface (client/shell/shell.js). One frame, one set of
 * controls, the same positions in every game. Spec: reports/Slot provider UI and motion.md,
 * Part 3. The system chrome looks the same in every game (docs/lumina-overhaul/layers.md,
 * Layer 1): the --lsh-* values below are the shell's own and no game may set them or style a
 * .lsh element (tools/probes/theme-lint.mjs). A game dresses only the themed slots (Layer 2)
 * through its skin: --skin-* properties passed to LuminaShell.mount({ skin }).
 *
 * Zero layout thrash: every track is sized from tokens, never from content; the only
 * flexible track is the stage. State changes swap looks (opacity, colour, icons), never
 * geometry. Controls a market switches off keep their cell (.is-off = visibility hidden).
 *
 * Three layouts, chosen by the viewport (not by the game):
 *   portrait   phones and tablets held upright: stage on top, then the feature rail, the
 *              ticker with Menu / Info at its ends, the readouts, the control row.
 *   landscape  short landscape (phones): stage between a left rail (Menu, Info, readouts,
 *              bet −/+) and a right rail (autoplay, Spin, speed). Left-hand mode swaps them.
 *   desktop    wide and tall enough: stage, ticker, one control bar with Spin centred.
 */

:root {
  /* System values (Layer 1: identical in every game; games may not set them). */
  --lsh-bg: #0b0f14;                       /* page background behind the stage */
  --lsh-deck: rgba(12, 16, 22, 0.78);      /* deck / rail surface where glass cannot blur */
  --lsh-deck-line: rgba(255, 255, 255, 0.12);
  --lsh-face: rgba(255, 255, 255, 0.10);   /* button face (flat) */
  --lsh-face-hover: rgba(255, 255, 255, 0.16);
  /* Liquid glass (owner's direction A, 2026-10-26): clear glass that lets the game's light
     through, a bright rim along the top edge, a soft drop. The blur sits only behind the
     deck, rails and sheets, never over the moving board. */
  --lsh-glass: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0.04) 42%, rgba(255, 255, 255, 0.07)), rgba(12, 16, 22, 0.6);
  --lsh-glass-blur: blur(22px) saturate(185%);
  --lsh-glass-rim: inset 0 1.5px 0 rgba(255, 255, 255, 0.5), inset 0 -1px 0 rgba(255, 255, 255, 0.1), inset 0 0 0 1px rgba(255, 255, 255, 0.12);
  --lsh-glass-drop: 0 24px 48px -18px rgba(0, 0, 0, 0.6);
  --lsh-disc: radial-gradient(120% 100% at 30% 12%, rgba(255, 255, 255, 0.32), rgba(255, 255, 255, 0.07) 54%, rgba(255, 255, 255, 0.12));
  --lsh-disc-rim: inset 0 1px 0 rgba(255, 255, 255, 0.7), inset 0 -3px 8px rgba(0, 0, 0, 0.22), inset 0 0 0 1px rgba(255, 255, 255, 0.2), 0 8px 18px -8px rgba(0, 0, 0, 0.7);
  --lsh-ink: #eef1f4;                      /* text and icons */
  --lsh-muted: #d3dae0;                    /* labels (on glass: kept light enough for 4.5:1) */
  --lsh-accent: #f2c14e;                   /* spin face, pressed toggles, focus */
  --lsh-accent-ink: #1d1300;               /* icon on the spin face */
  --lsh-accent-2: #d9a334;                 /* spin face lower stop */
  --lsh-win: #ffe7a3;                      /* celebrated win text */
  --lsh-sheet: #10161d;                    /* sheet panel */
  --lsh-radius: 26px;
  --lsh-font-ui: "Lumina UI", system-ui, -apple-system, "Segoe UI", sans-serif;
  --lsh-font-num: var(--lsh-font-ui);
  --lsh-texture: none;                     /* optional deck texture (url or gradient) */
  --lsh-spin-glyph: var(--lsh-accent-ink);
  --lsh-face-ink: var(--lsh-ink);          /* icon colour on a button face */
  --lsh-read-bg: transparent;              /* readout surface */
  --lsh-read-ink: var(--lsh-ink);          /* readout value */
  --lsh-read-k: var(--lsh-muted);          /* readout label */
  --lsh-feature-ink: var(--lsh-accent);    /* readout values during a feature (spins left, feature win) */
  /* The one bold thing: Spin is liquid gold inside a clear glass ring, a highlight on its cap. */
  --lsh-spin-ring: 0 0 0 5px rgba(255, 255, 255, 0.10), 0 0 0 6px rgba(255, 255, 255, 0.42), 0 14px 34px -8px rgba(255, 170, 40, 0.55), 0 4px 10px rgba(0, 0, 0, 0.45);
  --lsh-spin-face: radial-gradient(60% 34% at 50% 18%, rgba(255, 255, 255, 0.85), rgba(255, 255, 255, 0) 70%), radial-gradient(circle at 50% 60%, #ffe39a 0, #f6b93b 45%, #c27a12 82%, #8a4f05 100%);

  /* Fixed geometry (not themable: identical in every game). */
  --lsh-gutter: 16px;
  --lsh-gap: 8px;
  --lsh-hit: 44px;                         /* secondary controls: hit area */
  --lsh-spin: 72px;
  --lsh-strip: 18px;                       /* session strip: reserved in EVERY market (empty when unused) */
}

/* One face for words and numbers in every game (Inter, SIL OFL, shipped with the client:
   /play/assets/fonts, the demo's /vault/assets/fonts). */
@font-face { font-family: "Lumina UI"; src: url("../assets/fonts/inter-sub-wght-400-900.woff2") format("woff2"); font-weight: 400 900; font-style: normal; font-display: swap; }

/* The host page's own button styles never reach the shell (the shell's classes win). */
:where(.lsh, .lsh-sheet, .lsh-panel) button { min-height: 0; padding: 0; margin: 0; border-radius: 0; font-weight: inherit; text-shadow: none; box-shadow: none; transition: none; text-transform: none; letter-spacing: normal; }
:where(.lsh, .lsh-sheet, .lsh-panel) button:hover:not(:disabled) { transform: none; filter: none; }
:where(.lsh, .lsh-sheet, .lsh-panel) button:disabled { opacity: 1; }

/* No page zoom from tapping, in every game: a double tap or a burst of taps never zooms the
   page (touch-action has no specificity here, so a rule that needs none / pan-y still wins).
   shell.js adds the event guards iOS Safari needs on top (it ignores user-scalable=no). */
:where(html, body, body *) { touch-action: manipulation; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* ── frame ─────────────────────────────────────────────────────────────── */
.lsh {
  position: fixed;
  inset: 0;
  z-index: 2; /* above the game's page, below every overlay and sheet */
  display: grid;
  gap: var(--lsh-gap);
  padding:
    max(4px, env(safe-area-inset-top))
    max(var(--lsh-gutter), env(safe-area-inset-right))
    max(8px, env(safe-area-inset-bottom))
    max(var(--lsh-gutter), env(safe-area-inset-left));
  color: var(--lsh-ink);
  font: 500 14px/1.2 var(--lsh-font-ui);
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  overflow: hidden;
}
.lsh [hidden] { display: none !important; }
body:not(.app-ready):not(.ui-prerender) .lsh { visibility: hidden; } /* never half-drawn before the game is playable (Vault 20K pre-renders it under the loader) */
/* Every control sits in its NAMED area (never auto-placed: order and hiding can never move it). */
.lsh > [data-area="menu"] { grid-area: menu; } .lsh > [data-area="info"] { grid-area: info; }
.lsh > [data-area="bal"] { grid-area: bal; } .lsh > [data-area="bet"] { grid-area: bet; } .lsh > [data-area="win"] { grid-area: win; }
.lsh > [data-area="autop"] { grid-area: autop; } .lsh > [data-area="minus"] { grid-area: minus; } .lsh > [data-area="spin"] { grid-area: spin; }
.lsh > [data-area="plus"] { grid-area: plus; } .lsh > [data-area="turbo"] { grid-area: turbo; }
.lsh .is-off { visibility: hidden; pointer-events: none; }

.lsh-strip { grid-area: strip; height: var(--lsh-strip); display: flex; align-items: center; gap: 14px; overflow: hidden; font: 600 12px/1 var(--lsh-font-num); letter-spacing: 0.04em; color: var(--lsh-muted); font-variant-numeric: tabular-nums; }
.lsh-host { margin-left: auto; width: var(--lsh-strip); height: var(--lsh-strip); }
.lsh-stage { grid-area: stage; position: relative; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.lsh-rail { grid-area: rail; display: flex; gap: var(--lsh-gap); align-items: stretch; justify-content: center; min-height: 0; }
.lsh-ticker {
  grid-area: tick; min-width: 0; display: flex; align-items: center; justify-content: center;
  font: 600 13px/1 var(--lsh-font-ui); letter-spacing: 0.02em; color: var(--lsh-muted);
  overflow: hidden; white-space: nowrap;
}
.lsh-ticker__text { overflow: hidden; text-overflow: ellipsis; }
.lsh-ticker[data-state="spin"], .lsh-ticker[data-state="say"], .lsh-ticker[data-state="neutral"], .lsh-ticker[data-state="flash-info"] { color: var(--lsh-ink); }
.lsh-ticker[data-state="win"], .lsh-ticker[data-state="flash-win"] { color: var(--lsh-win); font-weight: 800; }
.lsh-ticker[data-state="flash-bonus"] { color: var(--lsh-accent); font-weight: 800; }

/* ── buttons ───────────────────────────────────────────────────────────── */
.lsh-btn, .lsh-spin, .lsh-chip, .lsh-read--bet, .lsh-pill {
  font: inherit; color: inherit; cursor: pointer; border: 0; padding: 0; background: none;
  touch-action: manipulation;
}
.lsh-btn {
  position: relative; display: grid; place-items: center;
  width: var(--lsh-hit); height: var(--lsh-hit); align-self: center; justify-self: center;
  border-radius: 50%;
  color: var(--lsh-face-ink);
  background: var(--lsh-disc);
  box-shadow: var(--lsh-disc-rim);
  transition: filter 120ms, transform 80ms;
}
.lsh-btn svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.lsh-btn:hover:not(:disabled) { filter: brightness(1.15); }
.lsh-btn:active:not(:disabled) { transform: scale(0.94); }
.lsh-btn:disabled { opacity: 0.38; cursor: default; }
.lsh-btn[aria-pressed="true"] { color: var(--lsh-accent); box-shadow: inset 0 0 0 2px var(--lsh-accent), 0 0 16px -2px color-mix(in srgb, var(--lsh-accent) 60%, transparent); }
.lsh-btn[data-speed="turbo"] svg { fill: currentColor; }
.lsh-btn__count { position: absolute; right: -2px; bottom: -2px; min-width: 18px; height: 18px; padding: 0 4px; border-radius: 9px; background: var(--lsh-accent); color: var(--lsh-accent-ink); font: 800 12px/18px var(--lsh-font-num); text-align: center; }
.lsh-btn__count:empty { display: none; }
.lsh :focus-visible { outline: 2px solid var(--lsh-accent); outline-offset: 3px; }

/* Spin: a round face; the icon swaps by data-mode, the size never changes. */
.lsh-spin {
  position: relative; display: grid; place-items: center;
  width: var(--lsh-spin); height: var(--lsh-spin); align-self: center; justify-self: center;
  border-radius: 50%;
  color: var(--lsh-spin-glyph);
  background: var(--lsh-spin-face);
  box-shadow: var(--lsh-spin-ring), inset 0 -8px 14px rgba(110, 55, 0, 0.45);
  transition: transform 80ms, filter 120ms;
}
.lsh-spin:active { transform: scale(0.95); }
.lsh-spin > svg { grid-area: 1 / 1; width: 62%; height: 62%; fill: none; stroke: currentColor; stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; opacity: 0; transition: opacity 120ms; }
.lsh-spin .lsh-head { fill: currentColor; stroke: none; }
.lsh-spin__stop rect { fill: currentColor; stroke: none; }
.lsh-spin[data-mode="spin"] .lsh-spin__go,
.lsh-spin[data-mode="wait"] .lsh-spin__go { opacity: 1; }
.lsh-spin[data-mode="stop"] .lsh-spin__stop { opacity: 1; }
.lsh-spin[data-mode="skip"] .lsh-spin__skip { opacity: 1; }
.lsh-spin__label { grid-area: 1 / 1; font: 800 14px/1 var(--lsh-font-ui); letter-spacing: 0.08em; }
.lsh-spin__label:not(:empty) ~ svg { opacity: 0 !important; }
.lsh-spin[data-mode="pick"] .lsh-spin__label:empty::before { content: "✓"; font-size: 26px; }
.lsh-spin.is-broke, .lsh-spin:disabled { filter: grayscale(0.7) brightness(0.75); }
.lsh-spin__ring { grid-area: 1 / 1; position: absolute; inset: -6px; width: calc(100% + 12px) !important; height: calc(100% + 12px) !important; opacity: 0 !important; stroke: var(--lsh-accent) !important; stroke-width: 3 !important; stroke-dasharray: 48 140; transform-origin: 50% 50%; }
.lsh-spin.is-waiting .lsh-spin__ring { opacity: 1 !important; animation: lsh-ring 1s linear infinite; }
@keyframes lsh-ring { to { transform: rotate(360deg); } }

/* Feature chips (Buy, Ante). */
.lsh-chip {
  display: grid; align-content: center; justify-items: center; gap: 2px;
  min-width: 120px; min-height: 48px; padding: 6px 16px;
  border-radius: 999px;
  /* Glass over the game, dark enough that its label reads over any art (A7: contrast ≥ 4.5:1). */
  background: var(--lsh-glass); box-shadow: var(--lsh-glass-rim), 0 10px 24px -12px rgba(0, 0, 0, 0.7);
  -webkit-backdrop-filter: var(--lsh-glass-blur); backdrop-filter: var(--lsh-glass-blur);
}
.lsh-chip__k { font: 600 12px/1 var(--lsh-font-ui); letter-spacing: 0.02em; color: var(--lsh-muted); }
.lsh-chip__v { font: 800 15px/1 var(--lsh-font-ui); letter-spacing: 0.01em; }
/* Rail cards are a themed slot (layers.md, Layer 2): place, size, labels and states are the
   shell's; the surface, edge, ink and title face are the game's skin (--skin-*). */
.lsh-chip { background: var(--skin-slot-bg, var(--lsh-glass)); color: var(--skin-slot-ink, var(--lsh-ink)); box-shadow: var(--skin-slot-edge, var(--lsh-glass-rim)), 0 10px 24px -12px rgba(0, 0, 0, 0.7); }
.lsh-chip .lsh-chip__k { color: inherit; opacity: 0.8; }
.lsh-chip .lsh-chip__v { font-family: var(--skin-title-font, var(--lsh-font-ui)); }
.lsh-chip--buy { background: var(--skin-buy-bg, radial-gradient(70% 60% at 50% 8%, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0) 70%), linear-gradient(180deg, #ffd37a, #d68c1e)); color: var(--skin-buy-ink, var(--lsh-accent-ink)); box-shadow: var(--skin-buy-edge, inset 0 1px 0 rgba(255, 255, 255, 0.7), inset 0 0 0 1px rgba(255, 255, 255, 0.25), 0 10px 24px -10px rgba(214, 140, 30, 0.7)); }
.lsh-chip[aria-checked="true"] { box-shadow: inset 0 0 0 2px var(--skin-accent, var(--lsh-accent)), var(--skin-slot-edge, 0 0 0 0 transparent); color: var(--skin-accent, var(--lsh-accent)); }
.lsh-chip:disabled { opacity: 0.4; cursor: default; }

/* Readouts: one line each, tabular, clipped: a value can never resize the deck. */
.lsh-read { min-width: 0; display: grid; align-content: center; justify-items: center; gap: 3px; text-align: center; padding: 2px 4px; border-radius: 8px; background: var(--lsh-read-bg); }
.lsh-read__k { font: 600 12px/1 var(--lsh-font-ui); letter-spacing: 0.02em; color: var(--lsh-read-k); white-space: nowrap; }
.lsh-read__v { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 700 17px/1.1 var(--lsh-font-num); font-variant-numeric: tabular-nums lining-nums; color: var(--lsh-read-ink); text-shadow: 0 1px 10px rgba(0, 0, 0, 0.35); }
.lsh-read--bet { border-radius: 10px; min-height: var(--lsh-hit); }
/* Its value may run past the narrow centre column into the empty space beside it (centred;
   Balance and Win keep their values in the middle of their wider cells). */
.lsh-read--bet .lsh-read__v { max-width: none; overflow: visible; }
.lsh-read--bet:hover:not(:disabled) { filter: brightness(1.08); }
.lsh-read--bet:disabled { cursor: default; }
.lsh.is-feature .lsh-read--bet .lsh-read__v, .lsh.is-feature .lsh-read--win .lsh-read__v { color: var(--lsh-feature-ink); }

/* ── portrait (default) ───────────────────────────────────────────────── */
.lsh {
  grid-template-columns: var(--lsh-hit) var(--lsh-hit) minmax(0, 1fr) var(--lsh-spin) minmax(0, 1fr) var(--lsh-hit) var(--lsh-hit);
  grid-template-rows: var(--lsh-strip) minmax(0, 1fr) auto var(--lsh-hit) 42px var(--lsh-spin);
  grid-template-areas:
    "strip strip strip strip strip strip strip"
    "stage stage stage stage stage stage stage"
    "rail  rail  rail  rail  rail  rail  rail"
    "menu  tick  tick  tick  tick  tick  info"
    "bal   bal   bal   bet   win   win   win"
    "autop  minus .     spin  .     plus  turbo";
  column-gap: 6px;
}
.lsh[data-hand="left"] {
  grid-template-areas:
    "strip strip strip strip strip strip strip"
    "stage stage stage stage stage stage stage"
    "rail  rail  rail  rail  rail  rail  rail"
    "info  tick  tick  tick  tick  tick  menu"
    "bal   bal   bal   bet   win   win   win"
    "turbo minus .     spin  .     plus  autop";
}
.lsh::before {
  /* The deck surface behind the bottom three rows (decoration: no layout role). */
  content: ""; grid-row: 4 / 7; grid-column: 1 / -1; margin: -6px calc(-1 * var(--lsh-gutter) + 6px) -6px;
  border-radius: var(--lsh-radius); background: var(--lsh-texture), var(--lsh-glass); box-shadow: var(--lsh-glass-rim), var(--lsh-glass-drop); z-index: -1;
  -webkit-backdrop-filter: var(--lsh-glass-blur); backdrop-filter: var(--lsh-glass-blur);
}
.lsh-rail:not([hidden]) { height: 48px; }
.lsh-read__v { font-size: 16px; }
/* Long numbers (shell.js: data-len by character count) step down to fit their cell. */
.lsh-read__v[data-len="l"] { font-size: 14px; }
.lsh-read__v[data-len="xl"] { font-size: 12px; letter-spacing: -0.02em; }

@media (max-width: 359px) {
  .lsh { --lsh-gutter: 10px; --lsh-spin: 64px; column-gap: 4px; }
  .lsh-read__v { font-size: 15px; }
  .lsh-read__v[data-len="l"] { font-size: 13px; }
}

/* Tablets upright: same layout, a little more air. */
@media (orientation: portrait) and (min-width: 700px) {
  .lsh { --lsh-gutter: 28px; --lsh-spin: 80px; column-gap: 14px; }
  .lsh-read__v, .lsh-read__v[data-len] { font-size: 19px; }
}

/* ── landscape phones (short) ─────────────────────────────────────────── */
@media (orientation: landscape) and (max-height: 520px) {
  .lsh {
    --lsh-spin: 64px;
    grid-template-columns: 68px 68px minmax(0, 1fr) 96px;
    grid-template-rows: var(--lsh-strip) var(--lsh-hit) 40px 40px 40px var(--lsh-hit) minmax(0, 1fr) 22px;
    grid-template-areas:
      "strip strip strip strip"
      "menu  info  stage autop"
      "bal   bal   stage spin"
      "bet   bet   stage spin"
      "win   win   stage turbo"
      "minus plus  stage ."
      "rail  rail  stage ."
      ".     .     tick  .";
    column-gap: 10px; row-gap: 6px;
    padding-top: max(4px, env(safe-area-inset-top));
    padding-bottom: max(4px, env(safe-area-inset-bottom));
  }
  .lsh[data-hand="left"] {
    grid-template-columns: 96px minmax(0, 1fr) 68px 68px;
    grid-template-areas:
      "strip strip strip strip"
      "autop  stage menu  info"
      "spin  stage bal   bal"
      "spin  stage bet   bet"
      "turbo stage win   win"
      ".     stage minus plus"
      ".     stage rail  rail"
      ".     tick  .     .";
  }
  /* Both rails sit on the deck surface, so they read over any game's art. */
  .lsh::before { grid-row: 2 / 8; grid-column: 1 / 3; margin: -6px -5px -6px calc(-1 * var(--lsh-gutter) + 6px); }
  .lsh::after {
    content: ""; grid-row: 2 / 6; grid-column: 4; margin: -6px calc(-1 * var(--lsh-gutter) + 6px) -6px -5px;
    border-radius: var(--lsh-radius); background: var(--lsh-texture), var(--lsh-glass); box-shadow: var(--lsh-glass-rim), var(--lsh-glass-drop); z-index: -1;
    -webkit-backdrop-filter: var(--lsh-glass-blur); backdrop-filter: var(--lsh-glass-blur);
  }
  .lsh[data-hand="left"]::before { grid-column: 3 / 5; margin: -6px calc(-1 * var(--lsh-gutter) + 6px) -6px -5px; }
  .lsh[data-hand="left"]::after { grid-column: 1; margin: -6px -5px -6px calc(-1 * var(--lsh-gutter) + 6px); }
  .lsh-rail:not([hidden]) { height: 44px; align-self: end; flex-direction: row; }
  .lsh-chip { flex: 1 1 0; min-width: 0; min-height: 44px; padding: 4px 6px; }
  .lsh-chip__v { font-size: 12px; }
  .lsh-chip__k { font-size: 12px; letter-spacing: 0.08em; }
  .lsh-read--bet { min-height: 40px; }
  .lsh-read { justify-items: start; text-align: left; }
  .lsh-read__v, .lsh-read__v[data-len] { font-size: 15px; }
  .lsh-ticker { font-size: 12px; }
}

/* ── desktop ──────────────────────────────────────────────────────────── */
@media (min-width: 1000px) and (min-height: 600px) and (orientation: landscape) {
  .lsh {
    --lsh-gutter: 24px; --lsh-spin: 80px;
    grid-template-columns: 48px 48px minmax(0, 1fr) minmax(0, 1fr) 48px 96px 48px minmax(0, 1fr) minmax(0, 1fr) 48px 48px;
    grid-template-rows: var(--lsh-strip) minmax(0, 1fr) 30px 96px;
    grid-template-areas:
      "strip strip strip strip strip strip strip strip strip strip strip"
      "stage stage stage stage stage stage stage stage stage rail  rail"
      "tick  tick  tick  tick  tick  tick  tick  tick  tick  tick  tick"
      "menu  info  bal   bet   minus spin  plus  win   win   autop  turbo";
    column-gap: 12px;
  }
  .lsh[data-hand="left"] {
    grid-template-areas:
      "strip strip strip strip strip strip strip strip strip strip strip"
      "rail  rail  stage stage stage stage stage stage stage stage stage"
      "tick  tick  tick  tick  tick  tick  tick  tick  tick  tick  tick"
      "autop  turbo bal   bet   minus spin  plus  win   win   menu  info";
  }
  .lsh::before { grid-row: 4; margin: 0 -12px; }
  .lsh-rail:not([hidden]) { height: auto; flex-direction: column; justify-content: center; }
  .lsh-read__v, .lsh-read__v[data-len] { font-size: 20px; }
  .lsh-read { justify-self: center; width: min(100%, 240px); }
  .lsh-ticker { font-size: 14px; }
}

/* ── sheets (VxNotify modals) ─────────────────────────────────────────── */
.lsh-sheet { position: fixed; inset: 0; z-index: 60; display: grid; place-items: end center; background: rgba(4, 6, 10, 0.5); padding: 0 max(8px, env(safe-area-inset-right)) max(8px, env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left)); }
.lsh-sheet.hidden { display: none; }
.lsh-sheet__panel {
  width: min(560px, 100%); max-height: min(86vh, 720px); overflow: auto; overscroll-behavior: contain;
  border-radius: 28px 28px 22px 22px; color: var(--lsh-ink);
  background: var(--lsh-texture), linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.03) 30%), rgba(16, 20, 28, 0.8);
  -webkit-backdrop-filter: blur(28px) saturate(170%); backdrop-filter: blur(28px) saturate(170%);
  box-shadow: var(--lsh-glass-rim), 0 -12px 48px rgba(0, 0, 0, 0.55);
  font: 500 15px/1.45 var(--lsh-font-ui);
}
@media (min-width: 700px) { .lsh-sheet { place-items: center; } .lsh-sheet__panel { border-radius: 28px; } }
.lsh-sheet__head { position: sticky; top: 0; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 16px 10px 22px; background: linear-gradient(180deg, rgba(22, 27, 36, 0.96), rgba(22, 27, 36, 0.86) 70%, rgba(22, 27, 36, 0)); }
.lsh-sheet__title { margin: 0; font: 800 19px/1.2 var(--lsh-font-ui); letter-spacing: -0.01em; }
.lsh-sheet__body { padding: 4px 20px 20px; }
.lsh-sheet__body p { margin: 0 0 12px; }
.lsh-sheet__body table { width: 100%; border-collapse: collapse; margin: 6px 0 14px; font-variant-numeric: tabular-nums; }
.lsh-sheet__body th, .lsh-sheet__body td { padding: 6px 4px; border-bottom: 1px solid var(--lsh-deck-line); text-align: right; }
.lsh-sheet__body th:first-child, .lsh-sheet__body td:first-child { text-align: left; }
.lsh-sheet__body h3 { margin: 16px 0 6px; font-size: 15px; letter-spacing: 0.04em; }
.lsh-sheet__body td svg, .lsh-sheet__body td img { width: 26px; height: 26px; vertical-align: middle; margin-right: 6px; }
.lsh-sheet__body { overflow-x: auto; }
.lsh-sheet--wide .lsh-sheet__panel { width: min(760px, 100%); } /* an ask with choice cards (Relic Forge's draft) */
.lsh-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 52px; border-bottom: 1px solid var(--lsh-deck-line); }
.lsh-row__t { display: grid; gap: 2px; }
.lsh-row__t small { color: var(--lsh-muted); font-size: 12px; }
.lsh-row input[type="checkbox"] { appearance: none; width: 50px; height: 30px; border-radius: 15px; background: rgba(255, 255, 255, 0.12); box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.45), inset 0 0 0 1px rgba(255, 255, 255, 0.12); position: relative; cursor: pointer; flex: none; transition: background 160ms; }
.lsh-row input[type="checkbox"]::after { content: ""; position: absolute; top: 3px; left: 3px; width: 24px; height: 24px; border-radius: 50%; background: radial-gradient(circle at 40% 30%, #fff, #dfe5ea); box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45); transition: transform 160ms; }
.lsh-row input[type="checkbox"]:checked { background: linear-gradient(180deg, #ffd37a, #d68c1e); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5), 0 0 14px -2px rgba(246, 185, 59, 0.6); }
.lsh-row input[type="checkbox"]:checked::after { transform: translateX(20px); }
.lsh-row select { min-height: 40px; border-radius: 999px; border: 0; padding: 0 14px; background: var(--lsh-disc); box-shadow: var(--lsh-disc-rim); color: var(--lsh-ink); font: inherit; }
.lsh-seg { display: inline-flex; border-radius: 999px; background: rgba(255, 255, 255, 0.08); box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4), inset 0 0 0 1px rgba(255, 255, 255, 0.1); padding: 3px; gap: 3px; }
.lsh-seg button { min-height: 40px; min-width: 64px; padding: 0 12px; border: 0; border-radius: 999px; background: none; color: var(--lsh-muted); font: 700 13px/1 var(--lsh-font-ui); cursor: pointer; }
.lsh-seg button[aria-checked="true"] { background: var(--lsh-disc); box-shadow: var(--lsh-disc-rim); color: var(--lsh-ink); }
.lsh-pill { display: inline-grid; place-items: center; min-height: 44px; min-width: 64px; padding: 0 18px; border-radius: 999px; background: var(--lsh-disc); box-shadow: var(--lsh-disc-rim); color: var(--lsh-ink); font: 700 15px/1 var(--lsh-font-num); text-decoration: none; }
.lsh-pill[aria-pressed="true"], .lsh-pill--primary { background: radial-gradient(70% 60% at 50% 8%, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0) 70%), linear-gradient(180deg, #ffd37a, #d68c1e); color: var(--lsh-accent-ink); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 10px 22px -10px rgba(214, 140, 30, 0.7); }
.lsh-pill:disabled { opacity: 0.35; cursor: default; }
.lsh-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 10px; margin-top: 16px; }
.lsh-presets, .lsh-ladder { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 12px; }
.lsh-market { color: var(--lsh-muted); font-size: 13px; }
.lsh-controls { color: var(--lsh-muted); font-size: 13px; }
.lsh-build { margin-top: 18px; padding-top: 10px; border-top: 1px solid var(--lsh-deck-line); color: var(--lsh-muted); font: 600 12px/1.4 var(--lsh-font-num); letter-spacing: 0.04em; }

/* No live blur (an old browser, or the OS asks for less transparency): the same glass, denser. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { :root { --lsh-glass: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.03) 42%), rgba(14, 18, 25, 0.86); } }
@media (prefers-reduced-transparency: reduce) { :root { --lsh-glass: linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.02) 42%), rgb(16, 20, 27); } }

/* Reduced motion (OS or menu) and battery saver: the shell's own motion stops. */
.lsh-reduced .lsh *, .lsh-reduced .lsh-sheet * { transition: none !important; }
.lsh-reduced .lsh-spin.is-waiting .lsh-spin__ring { animation: none; stroke-dasharray: none; }

/* Feature panels (intro / outro): over the stage, outside the layout. */
.lsh-panel { position: absolute; inset: 0; z-index: 30; display: grid; place-items: center; padding: 12px; background: rgba(0, 0, 0, 0.45); cursor: pointer; }
.lsh-panel.hidden { display: none; }
/* The feature panel is a themed slot (Layer 2): fixed structure, the game's skin. */
.lsh-panel .lsh-panel__card { width: min(100%, 420px); padding: 22px 22px 18px; border-radius: var(--skin-panel-radius, var(--lsh-radius)); text-align: center;
  background: var(--skin-panel-bg, linear-gradient(180deg, rgba(255, 255, 255, 0.14), rgba(255, 255, 255, 0.03) 40%), rgba(16, 20, 28, 0.82)); color: var(--skin-panel-ink, var(--lsh-ink)); box-shadow: var(--skin-panel-frame, var(--lsh-glass-rim), 0 18px 48px rgba(0, 0, 0, 0.55)); font-family: var(--lsh-font-ui); }
/* The card is a sheet panel, so each game's sheet skin (paper, ink) applies to it too. */
.lsh-panel .lsh-panel__kicker { margin: 0 0 6px; font: 700 12px/1 var(--lsh-font-ui); letter-spacing: 0.18em; text-transform: uppercase; color: var(--skin-panel-muted, var(--lsh-muted)); }
.lsh-panel .lsh-panel__title { margin: 0; font: var(--skin-title-weight, 800) 26px/1.15 var(--skin-title-font, var(--lsh-font-ui)); text-transform: var(--skin-title-case, none); color: var(--skin-panel-title, inherit); }
.lsh-panel .lsh-panel__line { margin: 10px 0 0; font: 500 15px/1.4 var(--lsh-font-ui); color: inherit; }
.lsh-panel .lsh-panel__line:empty { display: none; }
.lsh-panel .lsh-panel__stats { display: flex; justify-content: center; gap: 18px; margin: 14px 0 0; }
.lsh-panel .lsh-panel__stats:empty { display: none; }
.lsh-panel .lsh-panel__stats dt { font: 700 12px/1 var(--lsh-font-ui); letter-spacing: 0.1em; text-transform: uppercase; color: var(--skin-panel-muted, var(--lsh-muted)); }
.lsh-panel .lsh-panel__stats dd { margin: 4px 0 0; font: 800 18px/1 var(--lsh-font-num); font-variant-numeric: tabular-nums; }
.lsh-panel .lsh-panel__total { margin: 16px 0 0; display: grid; gap: 4px; }
.lsh-panel .lsh-panel__tk { font: 700 12px/1 var(--lsh-font-ui); letter-spacing: 0.12em; text-transform: uppercase; color: var(--skin-panel-muted, var(--lsh-muted)); }
.lsh-panel .lsh-panel__tv { font: 800 34px/1 var(--lsh-font-num); font-variant-numeric: tabular-nums; color: var(--skin-panel-total, inherit); }
.lsh-panel .lsh-panel__cta { margin: 14px 0 0; font: 600 13px/1 var(--lsh-font-ui); color: var(--skin-panel-muted, var(--lsh-muted)); }
.lsh-panel .lsh-panel__cta:empty { display: none; }
.lsh-plus { position: fixed; z-index: 70; transform: translate(-50%, -50%); pointer-events: none; font: 900 34px/1 var(--lsh-font-num); color: var(--lsh-win); text-shadow: 0 2px 10px rgba(0, 0, 0, 0.6); }
/* A sheet panel too (each game's sheet skin applies). */
.lsh-stage .lsh-callout { position: absolute; z-index: 25; bottom: 12px; left: 50%; transform: translateX(-50%); width: max-content; max-width: calc(100% - 24px); max-height: none; overflow: visible; margin: 0; padding: 10px 14px; border-radius: var(--lsh-radius);
  font: 600 14px/1.35 var(--lsh-font-ui); text-align: center; pointer-events: none; }
.lsh-stage .lsh-callout[hidden] { display: none; }
/* DE panic button (market session_hud "panic"): in the strip, a 40 px hit area that hangs
   over the top of the stage (never the controls); the visible pill stays strip-sized. */
.lsh-panic { grid-area: strip; justify-self: end; align-self: start; position: relative; z-index: 6; height: 40px; min-width: 40px; margin: 0 calc(var(--lsh-strip) + 6px) 0 0; padding: 0; border: 0; background: none; color: inherit; cursor: pointer; }
.lsh-panic[hidden] { display: none; }
.lsh-panic span { display: block; padding: 3px 10px; border-radius: 999px; font: 700 12px/1 var(--lsh-font-ui); letter-spacing: 0.04em; color: #fff; background: #b3261e; box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.35); }
.lsh-panic:focus-visible span { outline: 2px solid #fff; outline-offset: 2px; }
/* DE return to player at the stake (market rtp_display "stake_area"). Portrait: beside the bet
   buttons, in the autoplay slot the market leaves empty; landscape: on the Bet readout. */
.lsh-rtp { grid-area: bet; justify-self: end; align-self: start; z-index: 2; margin: 8px 10px 0 0; pointer-events: none;
  font: 700 12px/1.2 var(--lsh-font-num); letter-spacing: 0.04em; color: var(--lsh-read-k, var(--lsh-muted)); text-align: right; font-variant-numeric: tabular-nums; }
.lsh-rtp[hidden] { display: none; }
@media (orientation: portrait) {
  .lsh.has-rtp-slot .lsh-rtp { grid-area: autop; justify-self: center; align-self: center; margin: 0; text-align: center; color: var(--lsh-muted); }
  .lsh.has-rtp-slot .lsh-rtp span { display: block; }
}
/* System navigation in the strip (Layer 1): "Games" (when the host gives a lobby URL) on the
   left, full screen on the right. 40 px hit areas hanging over the top of the stage, like the
   panic button; the visible pills stay strip-sized. */
.lsh-nav { grid-area: strip; align-self: start; position: relative; z-index: 6; height: 40px; min-width: 40px; padding: 0; border: 0; background: none; color: var(--lsh-ink); cursor: pointer; text-decoration: none; display: flex; align-items: flex-start; }
.lsh-nav[hidden] { display: none; }
.lsh-nav--back { justify-self: start; }
.lsh-nav--full { justify-self: end; margin-right: calc(var(--lsh-strip) + 6px); }
.lsh[data-session="panic"] .lsh-nav--full { margin-right: calc(var(--lsh-strip) + 136px); }
.lsh-nav > span { display: inline-flex; align-items: center; gap: 6px; height: 18px; padding: 0 10px; border-radius: 999px; font: 700 12px/1 var(--lsh-font-ui); letter-spacing: 0.02em; background: var(--lsh-glass); box-shadow: var(--lsh-glass-rim); -webkit-backdrop-filter: var(--lsh-glass-blur); backdrop-filter: var(--lsh-glass-blur); }
.lsh-nav svg { width: 12px; height: 12px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.lsh-nav:focus-visible > span { outline: 2px solid var(--lsh-accent); outline-offset: 2px; }
/* the session strip's items start after the back link */
.lsh.has-back .lsh-strip { padding-left: 84px; }

/* ── Big win (client/shell/big-win.js): a themed slot (layers.md, Layer 2) ─────────
   One structure and behaviour in every game; colours, title face and lasers from the skin.
   position:fixed + contain:strict: opening it, its per-frame amount text and
   its tier changes cannot reflow or repaint anything in the game underneath.
   Shown by toggling .is-open (opacity/visibility, never display), so the
   particle canvas keeps its backing store between wins.
   z-index: above the buy-confirm modal (9000), below the win chips, soul layer
   and boot loader (9500+). */
.big-win-overlay {
  --bw-color: var(--skin-tier-big, #f2c14e);
  position: fixed;
  inset: 0;
  z-index: 9200;
  contain: strict;
  display: grid;
  place-items: center;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  background:
    radial-gradient(ellipse at 50% 46%, color-mix(in srgb, var(--bw-color) 16%, transparent), transparent 62%),
    var(--skin-bigwin-scrim, rgba(7, 9, 12, 0.82));
  transition: opacity 0.24s ease, visibility 0s linear 0.24s;
  cursor: pointer;
  outline: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
}
.big-win-overlay.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 0.24s ease;
}
.big-win-overlay[data-tier="big"]  { --bw-color: var(--skin-tier-big, #f2c14e); }
.big-win-overlay[data-tier="mega"] { --bw-color: var(--skin-tier-mega, #ff8a3d); }
.big-win-overlay[data-tier="epic"] { --bw-color: var(--skin-tier-epic, #ffe7a3); }
.big-win-overlay[data-tier="legendary"] { --bw-color: var(--skin-tier-legendary, #7ff6e6); }
.big-win-overlay[data-tier="max"]  { --bw-color: var(--skin-tier-max, #ffffff); }

.bw-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* Laser sweeps from the mega tier up, for a skin that asks for them (.has-lasers: Vault
   20K's security lasers). Transform-only, so they run on the compositor; only animated
   while open. */
.bw-lasers {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s ease;
}
.bw-lasers::before,
.bw-lasers::after {
  content: "";
  position: absolute;
  left: -10%;
  right: -10%;
  top: 0;
  height: 2px;
  background: var(--skin-laser-hot, #ffd0cc);
  box-shadow:
    0 0 10px 2px color-mix(in srgb, var(--skin-laser, #ff2a3a) 80%, transparent),
    0 0 34px 6px color-mix(in srgb, var(--skin-laser, #ff2a3a) 35%, transparent);
}
.big-win-overlay.has-lasers.is-open:is([data-tier="mega"], [data-tier="epic"], [data-tier="legendary"], [data-tier="max"]) .bw-lasers {
  opacity: 1;
}
.big-win-overlay.has-lasers.is-open:is([data-tier="mega"], [data-tier="epic"], [data-tier="legendary"], [data-tier="max"]) .bw-lasers::before {
  animation: bwLaserSweepA 2.4s ease-in-out infinite alternate;
}
.big-win-overlay.has-lasers.is-open:is([data-tier="mega"], [data-tier="epic"], [data-tier="legendary"], [data-tier="max"]) .bw-lasers::after {
  animation: bwLaserSweepB 3.1s ease-in-out infinite alternate;
}
@keyframes bwLaserSweepA {
  from { transform: translateY(14vh) rotate(-5deg); }
  to   { transform: translateY(86vh) rotate(4deg); }
}
@keyframes bwLaserSweepB {
  from { transform: translateY(80vh) rotate(6deg); }
  to   { transform: translateY(20vh) rotate(-3deg); }
}

.bw-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(4px, 1.4vmin, 14px);
  padding: 0 16px;
  max-width: 100%;
  text-align: center;
  will-change: transform;
}
/* Static plate behind the figures: a dark core for contrast (gold text over a
   gold coin fountain is otherwise mud at MOTHERLODE) inside a tier-coloured
   halo. Kept off the per-frame text so the count never re-rasterizes a blur. */
.bw-stage::before {
  content: "";
  position: absolute;
  inset: -30% -12%;
  z-index: -1;
  background: radial-gradient(ellipse at center,
    color-mix(in srgb, var(--skin-bigwin-core, #07080a) 72%, transparent) 0%,
    color-mix(in srgb, var(--skin-bigwin-core, #07080a) 45%, transparent) 34%,
    color-mix(in srgb, var(--bw-color) 24%, transparent) 52%,
    transparent 70%);
  transition: background 0.3s ease;
}
.bw-label {
  min-height: 1em; /* reserved, so the amount doesn't jump when the label appears */
  font-family: var(--skin-title-font, var(--lsh-font-ui));
  font-weight: 700;
  font-size: clamp(30px, 10vmin, 96px);
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: var(--skin-title-case, uppercase);
  white-space: nowrap;
  color: var(--bw-color);
  text-shadow:
    0 0 3px rgba(0, 0, 0, 0.9),
    0 3px 0 rgba(0, 0, 0, 0.55),
    0 0 26px color-mix(in srgb, var(--bw-color) 65%, transparent);
}
.bw-amount {
  font-family: var(--skin-amount-font, var(--skin-title-font, var(--lsh-font-num)));
  font-weight: 700;
  font-size: clamp(44px, 16vmin, 168px);
  line-height: 1;
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
  background: linear-gradient(180deg,
    var(--skin-win-hi, #ffffff) 0%, var(--skin-win, #ffe7a3) 38%, var(--skin-accent, #f2c14e) 72%, var(--skin-win-deep, #9c6b12) 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* A dark edge, not a shadow: text-shadow cannot sit under clipped gradient text. */
  -webkit-text-stroke: 2px color-mix(in srgb, var(--skin-bigwin-core, #07080a) 75%, transparent);
  paint-order: stroke fill;
}
.bw-hint {
  margin-top: clamp(6px, 2vmin, 20px);
  font: 600 clamp(12px, 1.8vmin, 14px) / 1 var(--lsh-font-ui);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--lsh-muted);
  opacity: 0;
  transition: opacity 0.3s ease 0.2s;
}
.big-win-overlay.is-done .bw-hint { opacity: 0.85; }

/* Reduced motion: no particles, no lasers, no shake (big-win.js also skips the
   count and the bursts), just a slower fade to the final state. */
@media (prefers-reduced-motion: reduce) {
  .bw-canvas,
  .bw-lasers { display: none; }
  .big-win-overlay { transition: opacity 0.4s ease, visibility 0s linear 0.4s; }
  .big-win-overlay.is-open { transition: opacity 0.4s ease; }
}
.big-win-overlay.is-reduced .bw-canvas,
.big-win-overlay.is-reduced .bw-lasers { display: none; }
.lsh-vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* Intro splash (layers.md, Layer 2): over the stage only (the deck stays usable). The scene,
   logo face and cards are the game's skin; the facts row and Play are system. */
.lsh-splash { position: absolute; inset: 0; z-index: 35; display: grid; grid-template-rows: auto minmax(0, 1fr) auto; gap: 10px; padding: 10px 4px 6px; container-type: size;
  background: var(--skin-scene, radial-gradient(120% 80% at 50% 0%, #1b2430 0%, #0b0f14 70%)); border-radius: var(--lsh-radius); color: var(--lsh-ink); }
.lsh-splash.hidden { display: none; }
.lsh-splash__logo { justify-self: center; text-align: center; font: var(--skin-title-weight, 700) clamp(22px, 9cqi, 52px)/1 var(--skin-title-font, var(--lsh-font-ui)); text-transform: var(--skin-title-case, none); letter-spacing: 0.03em; color: var(--skin-accent, var(--lsh-accent)); text-shadow: 0 2px 0 rgba(0, 0, 0, 0.45); }
.lsh-splash__cards { min-height: 0; align-self: stretch; max-height: 360px; display: grid; grid-template-columns: repeat(auto-fit, minmax(0, 1fr)); gap: 10px; width: min(100%, 720px); justify-self: center; }
.lsh-splash__card { min-height: 0; overflow: hidden; display: grid; grid-template-rows: minmax(0, 1fr) auto; gap: 8px; padding: 10px; border-radius: var(--skin-panel-radius, 12px);
  background: var(--skin-panel-bg, var(--lsh-sheet)); color: var(--skin-panel-ink, var(--lsh-ink)); box-shadow: var(--skin-panel-frame, inset 0 0 0 1px var(--lsh-deck-line)); }
.lsh-splash__art { min-height: 0; display: grid; place-items: center; overflow: hidden; }
.lsh-splash__art > * { max-width: 100%; max-height: min(38cqh, 180px); width: auto; height: auto; }
.lsh-splash__art svg { width: min(38cqh, 150px); height: min(38cqh, 150px); }
.lsh-splash__art b { font: 700 clamp(26px, 9cqi, 56px)/1 var(--skin-title-font, var(--lsh-font-ui)); color: var(--skin-panel-total, var(--skin-accent, var(--lsh-accent))); }
.lsh-splash__card p { margin: 0; font: 600 clamp(12px, 3.6cqi, 15px)/1.35 var(--lsh-font-ui); text-align: center; }
.lsh-splash__facts { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 12px; width: min(100%, 720px); justify-self: center; padding: 8px 12px; border-radius: 20px; background: var(--lsh-glass); box-shadow: var(--lsh-glass-rim); -webkit-backdrop-filter: var(--lsh-glass-blur); backdrop-filter: var(--lsh-glass-blur); }
.lsh-splash__list { display: grid; gap: 4px; }
.lsh-splash__list p { margin: 0; font: 700 12px/1.3 var(--lsh-font-ui); letter-spacing: 0.08em; text-transform: uppercase; color: var(--lsh-muted); }
.lsh-splash__list strong, .lsh-splash__list b { font: 800 16px/1 var(--lsh-font-num); letter-spacing: 0; text-transform: none; color: var(--lsh-ink); }
.lsh-splash__vol { display: inline-flex; align-items: end; gap: 2px; margin: 0 4px; vertical-align: -1px; }
.lsh-splash__vol i { width: 5px; border-radius: 1px; background: rgba(255, 255, 255, 0.22); }
.lsh-splash__vol i:nth-child(1) { height: 6px; } .lsh-splash__vol i:nth-child(2) { height: 9px; } .lsh-splash__vol i:nth-child(3) { height: 12px; }
.lsh-splash__vol i.on { background: var(--lsh-accent); }
.lsh-splash__vol i.half { background: linear-gradient(90deg, var(--lsh-accent) 50%, rgba(255, 255, 255, 0.22) 50%); }
.lsh-splash__dont { display: flex; align-items: center; gap: 8px; min-height: 40px; font: 600 13px/1 var(--lsh-font-ui); color: var(--lsh-ink); cursor: pointer; }
.lsh-splash__dont input { width: 20px; height: 20px; margin: 0; accent-color: var(--lsh-accent); }
.lsh-splash__play { width: 64px; height: 64px; border-radius: 50%; border: 0; cursor: pointer; background: var(--lsh-spin-face); box-shadow: var(--lsh-spin-ring); color: var(--lsh-accent-ink); font: 800 13px/1 var(--lsh-font-ui); letter-spacing: 0.06em; text-transform: uppercase; }
.lsh-splash__play:focus-visible { outline: 3px solid var(--lsh-ink); outline-offset: 3px; }
@container (max-height: 460px) { .lsh-splash { gap: 6px; padding-top: 6px; } .lsh-splash__logo { font-size: 26px; } .lsh-splash__card { padding: 8px; gap: 4px; } .lsh-splash__card p { font-size: 12px; } .lsh-splash__facts { padding: 4px 10px; } .lsh-splash__dont { min-height: 32px; } .lsh-splash__play { width: 56px; height: 56px; } }
@container (max-height: 340px) { .lsh-splash__cards { align-self: center; } .lsh-splash__art > * { max-height: 22cqh; } .lsh-splash__art svg { width: 22cqh; height: 22cqh; } .lsh-splash__logo { font-size: 22px; } }
@container (max-height: 240px) { .lsh-splash__art { display: none; } }

/* The Lumina provider loader (layers.md, Layer 1): the same in every game, in each page's
   markup before any script. Fades out on body.app-ready; Vault 20K drives the bar, the
   others show an indeterminate sweep. */
.lsh-loader { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; background: #0b0f14; color: #eef1f4; transition: opacity 0.45s ease, visibility 0s linear 0.45s; }
body.app-ready .lsh-loader { opacity: 0; visibility: hidden; pointer-events: none; }
.lsh-loader__inner { display: grid; justify-items: center; gap: 16px; }
.lsh-loader__mark { width: 56px; height: 56px; }
.lsh-loader__word { font: 800 22px/1 "Lumina UI", system-ui, sans-serif; letter-spacing: 0.32em; padding-left: 0.32em; text-align: center; }
.lsh-loader__word small { display: block; margin-top: 8px; font: 600 11px/1 "Lumina UI", system-ui, sans-serif; letter-spacing: 0.5em; padding-left: 0.5em; color: #9aa7ad; }
.lsh-loader__track { width: 168px; height: 3px; border-radius: 3px; background: rgba(255, 255, 255, 0.12); overflow: hidden; }
.lsh-loader__bar { width: 0%; height: 100%; background: #f2c14e; transition: width 0.25s ease; }
.lsh-loader.is-indeterminate .lsh-loader__bar { width: 40%; animation: lshLoad 1.1s ease-in-out infinite; }
body.app-ready .lsh-loader.is-indeterminate .lsh-loader__bar { animation: none; } /* idle zero once the game is up */
@keyframes lshLoad { from { transform: translateX(-100%); } to { transform: translateX(260%); } }
.lsh-loader__pct { min-height: 12px; font: 600 12px/1 "Lumina UI", system-ui, sans-serif; letter-spacing: 0.08em; color: #9aa7ad; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { .lsh-loader.is-indeterminate .lsh-loader__bar { animation: none; width: 100%; opacity: 0.6; } }
/* Landscape phones: the rails start right under the strip, so the strip's hanging controls
   (Games, full screen, the DE panic button) sit over the stage column instead. */
@media (orientation: landscape) and (max-height: 520px) {
  .lsh-nav, .lsh-panic { grid-area: auto; grid-row: 1; grid-column: 3; }
  .lsh[data-hand="left"] .lsh-nav, .lsh[data-hand="left"] .lsh-panic { grid-column: 2; }
  .lsh-nav--full { margin-right: 0; }
  .lsh-panic { margin-right: 48px; }
  .lsh[data-session="panic"] .lsh-nav--full { margin-right: 0; }
}
