/* ============================================================
   PLUNDER — night-raid aesthetic
   ink sea · lantern gold · crimson vs teal
   ============================================================ */

:root {
  --ink: #070b18;
  --sea-1: #0a1124;
  --sea-2: #13224a;
  --panel: rgba(13, 20, 44, 0.78);
  --panel-solid: #0e1531;
  --line: rgba(245, 197, 66, 0.16);
  /* antique brass, not the bright #f5c542 "AI yellow" */
  --gold: #d3a24b;
  --gold-dim: #8d6a2d;
  --text: #ece3cd;
  --muted: #8b93ad;
  --port: #e2493b;
  --port-soft: rgba(226, 73, 59, 0.16);
  --star: #6ea8e0;
  --star-soft: rgba(110, 168, 224, 0.16);
  --danger: #ff6b5e;
  --radius: 14px;
  /* readable geometric sans (free stand-in for Nexa Heavy — see note in the PR) */
  --display: 'Outfit', 'Segoe UI', sans-serif;
  --mono: 'IBM Plex Mono', Consolas, monospace;
  --sans: 'IBM Plex Sans', 'Segoe UI', sans-serif;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html { height: 100%; }
body {
  min-height: 100%;
  background:
    radial-gradient(1200px 600px at 70% -10%, #1b2a55 0%, transparent 60%),
    radial-gradient(900px 500px at 10% 110%, #101c3d 0%, transparent 55%),
    var(--ink);
  color: var(--text);
  font-family: var(--sans);
  font-size: 15px;
  overflow-x: hidden;
}
.mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
a { color: var(--gold); }
button { font-family: inherit; cursor: pointer; }

/* film grain */
#grain {
  position: fixed; inset: 0; z-index: 90; pointer-events: none; opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.7'/%3E%3C/svg%3E");
}

/* ---------------- topbar ---------------- */
#topbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding: 10px 12px 6px;
  width: 100%; max-width: 1560px; margin: 0 auto;
}
.nav-left, .nav-right { display: flex; align-items: center; gap: 12px; min-width: 0; }
.nav-right { gap: 8px; flex-shrink: 0; }   /* aboard + balance kept tight together */
.brand { display: flex; align-items: baseline; gap: 8px; }
.brand-mark { font-size: 22px; filter: drop-shadow(0 0 6px rgba(245,197,66,.5)); }
.brand h1 {
  font-family: var(--display); font-weight: 800; font-size: 30px; line-height: 1;
  letter-spacing: 2px; color: var(--gold);
  text-shadow: 0 0 18px rgba(211, 162, 75, 0.35);
}
.brand-sub { color: var(--muted); font-size: 11px; letter-spacing: 1.2px; text-transform: uppercase; font-weight: 600; }
@media (max-width: 1100px) { .brand-sub { display: none; } }
.online-pill {
  color: var(--muted); font-size: 12px; padding: 5px 9px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--panel);
}
.you-chip {
  display: flex; align-items: center; gap: 7px;
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
  padding: 6px 11px; border-radius: 999px; font-size: 13px;
}
.music-btn {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--sans); font-size: 12.5px; font-weight: 800;
  letter-spacing: .8px; text-transform: uppercase;
  padding: 7px 14px; border-radius: 999px;
  border: 1px solid var(--gold-dim); color: var(--gold);
  background: rgba(245,197,66,.12); white-space: nowrap;
  transition: background .2s, box-shadow .2s, transform .1s;
}
.music-btn .micon { width: 17px; height: 17px; flex: 0 0 auto; display: block; }
.music-btn.muted .wave { opacity: .2; }        /* muted: speaker only, no sound waves */
.music-btn.on .wave { opacity: 1; }
.music-btn:hover { background: rgba(245,197,66,.2); }
.music-btn:active { transform: scale(.95); }
.music-btn.on { box-shadow: 0 0 0 1px var(--gold-dim), 0 0 16px rgba(245,197,66,.35); }
.music-btn.muted { animation: musicNudge 1.8s ease-in-out infinite; }
@keyframes musicNudge {
  0%, 100% { box-shadow: 0 0 0 0 rgba(245,197,66,.55); transform: scale(1); }
  50% { box-shadow: 0 0 0 7px rgba(245,197,66,0); transform: scale(1.06); }
}
.you-chip .mono { color: var(--gold); font-weight: 600; }
.you-chip .mono::after { content: ""; }

/* ---------------- layout ---------------- */
#layout {
  max-width: 1560px; margin: 0 auto; padding: 6px 10px 0;
  display: grid; grid-template-columns: 1fr; gap: 10px;
}
/* PC: two columns — big scene on the left, chat+betting panel on the right */
@media (min-width: 980px) {
  #layout { grid-template-columns: minmax(0, 2.05fr) minmax(320px, 0.95fr); align-items: start; }
}
@media (min-width: 1500px) {
  #layout { grid-template-columns: minmax(0, 2.4fr) minmax(340px, 0.85fr); }
}

/* ---------------- ship cards ---------------- */
/* DESKTOP: the two ship info cards sit in a row above the stage (the classic
   layout). On phones this becomes an on-ship overlay — see the @media block. */
#cards {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px; align-items: stretch;
  margin-bottom: 6px;
}
.ship-card {
  border-radius: var(--radius); padding: 9px 12px 7px;
  background: var(--panel); border: 1px solid var(--line);
  display: flex; flex-direction: column; gap: 1px; text-align: left;
  color: var(--text); position: relative; overflow: hidden;
  transition: transform .15s ease, box-shadow .2s;
}
.ship-card:active { transform: scale(.98); }
.ship-card.port { border-color: rgba(226,73,59,.4); box-shadow: inset 0 0 30px rgba(226,73,59,.08); }
.ship-card.star { border-color: rgba(110,168,224,.4); box-shadow: inset 0 0 30px rgba(110,168,224,.08); }
.ship-card .card-name {
  font-family: var(--display); font-size: 17px; letter-spacing: 2px; line-height: 1;
  display: flex; align-items: center; gap: 6px;
}
.card-name .cn-ico { font-size: 16px; flex: 0 0 auto; }
.card-name .cn-txt { line-height: 1.02; text-transform: uppercase; font-weight: 800; letter-spacing: .8px; }
/* ship cards are DISPLAY-ONLY now (betting happens on the board buttons) */
.ship-card { cursor: default; }
.ship-card:hover, .ship-card:active { transform: none; }
.ship-card.port .card-name { color: var(--port); }
.ship-card.star .card-name { color: var(--star); }
.ship-card.bump { animation: bump .35s ease; }

/* ---- the live multiplier on each ship card ----
   Both ships ride one clock, so these read alike until a ship sinks; then
   that one FREEZES at its crash point and goes .sunk, which is what makes
   "the Pearl died at x1.20 while the Interceptor made x9" legible at a
   glance. Tabular figures so the number doesn't jitter as it climbs. */
.card-mult {
  display: block; margin-top: 2px;
  font-size: 20px; font-weight: 800; letter-spacing: -.5px;
  font-variant-numeric: tabular-nums;
  color: #e9f3ff; text-shadow: 0 2px 10px rgba(0,0,0,.55);
  transition: color .18s ease, opacity .18s ease;
}
.ship-card.port .card-mult { color: #ffd8d2; }
.ship-card.star .card-mult { color: #d6e9ff; }
.card-mult.sunk { color: var(--muted); opacity: .7; text-decoration: line-through; text-decoration-thickness: 1.5px; }
.ship-card.sunk { filter: grayscale(.7) brightness(.72); }
.ship-card.sunk .card-name { opacity: .5; }
@keyframes bump { 30% { box-shadow: 0 0 24px rgba(245,197,66,.25); } }

/* "lighter — winning" badge: a bottom strip so it never covers the ship name */
.lighter-badge {
  order: 5; margin-top: 5px; align-self: stretch; text-align: center;
  font-size: 9.5px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase;
  color: #0c0b10; background: var(--gold); border-radius: 6px; padding: 3px 6px;
  box-shadow: 0 0 10px rgba(245,197,66,.5); animation: badgePulse 1.6s ease-in-out infinite;
}
@keyframes badgePulse { 50% { box-shadow: 0 0 16px rgba(245,197,66,.85); } }

/* 2X / 5X quick-bet buttons — identical size + weight */
.scale-btn {
  flex: 0 0 auto; width: 56px; background: rgba(255,255,255,.07);
  border: 1px solid rgba(255,255,255,.16); color: var(--text); border-radius: 9px;
  padding: 11px 0; text-align: center;
  font-family: var(--sans); font-weight: 700; font-size: 16px; letter-spacing: .5px;
}
.scale-btn:hover { background: rgba(245,197,66,.18); color: var(--gold); border-color: var(--gold-dim); }
.scale-btn:active { transform: scale(.94); }

/* progressive jackpot bar (overlay on the stage) */
/* jackpot: centered pill at the top of the scene */
#jackpot-bar {
  position: absolute; top: 8px; left: 50%; transform: translateX(-50%); z-index: 7;
  background: rgba(8,12,26,.72); border: 1px solid var(--gold-dim); border-radius: 999px;
  padding: 4px 15px; font-size: 13px; color: var(--gold); font-weight: 600;
  backdrop-filter: blur(3px); white-space: nowrap; pointer-events: none;
  box-shadow: 0 0 14px rgba(245,197,66,.2);
}
#jackpot-bar b { font-family: var(--mono); }
#jackpot-eta { font-family: var(--sans); font-weight: 600; opacity: .82; font-size: 12px; }
#jackpot-bar.hot #jackpot-eta { opacity: 1; color: #fff; }
#jackpot-bar.hot {
  font-size: 15px; background: rgba(66,44,8,.9); border-color: var(--gold);
  animation: jackpotHot 1s ease-in-out infinite;
}
@keyframes jackpotHot {
  0%,100% { box-shadow: 0 0 14px rgba(245,197,66,.4); transform: translateX(-50%) scale(1); }
  50% { box-shadow: 0 0 28px rgba(245,197,66,.75); transform: translateX(-50%) scale(1.06); }
}

/* ---- auto-rebet toggle: full-width button at the bottom ---- */
.autobet-btn {
  width: 100%; padding: 12px; border-radius: 11px;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.14);
  color: var(--muted); font-family: var(--sans); font-weight: 600; font-size: 14px;
  letter-spacing: .8px; text-transform: uppercase;
  transition: background .15s, color .15s, border-color .15s;
}
.autobet-btn:hover { background: rgba(255,255,255,.08); color: var(--text); }
.autobet-btn:active { transform: scale(.99); }
.autobet-btn.on {
  background: rgba(245,197,66,.16); border-color: var(--gold-dim); color: var(--gold);
  box-shadow: inset 0 0 0 1px rgba(245,197,66,.25);
}

/* ---- jackpot ambient glow (whole round) ---- */
body.jackpot-active #stage { animation: jackpotGlow 1.6s ease-in-out infinite; }
@keyframes jackpotGlow {
  0%,100% { box-shadow: inset 0 0 90px rgba(2,5,14,.85), 0 18px 50px rgba(0,0,0,.35); }
  50% { box-shadow: inset 0 0 90px rgba(2,5,14,.85), 0 0 34px rgba(245,197,66,.55), inset 0 0 70px rgba(245,197,66,.16); }
}

/* ---- jackpot DROP full-screen flash ---- */
#jackpot-flash {
  position: fixed; inset: 0; z-index: 120; display: grid; place-items: center;
  pointer-events: none;
  /* no backdrop at all — just the solid box floats over the live scene (no black wash) */
  background: transparent;
}
#jackpot-flash[hidden] { display: none; }
#jackpot-flash.go { animation: jfFade 3.8s ease forwards; }
@keyframes jfFade { 0%, 78% { opacity: 1; } 100% { opacity: 0; } }
/* the ONLY thing shown: one solid box — winner ship + jackpot total */
.jf-inner {
  text-align: center; display: flex; flex-direction: column; gap: 8px;
  padding: 30px 44px; border-radius: 18px;
  background: #0a1526; border: 2px solid var(--gold);
  box-shadow: 0 0 60px rgba(245,197,66,.35), 0 20px 60px rgba(0,0,0,.6);
}
#jackpot-flash.go .jf-inner { animation: jfPop .55s cubic-bezier(.2,1.5,.4,1); }
@keyframes jfPop { from { opacity: 0; transform: scale(.55); } }
.jf-title { font-family: var(--display); font-size: clamp(30px, 8vw, 58px); letter-spacing: 2px; color: var(--gold); text-shadow: 0 0 34px rgba(245,197,66,.75), 0 3px 6px #000; }
.jf-amt { font-size: clamp(30px, 10vw, 72px); font-weight: 700; color: #fff; text-shadow: 0 0 30px rgba(245,197,66,.85); }
.jf-sub { font-size: clamp(12px, 3.6vw, 16px); color: var(--text); text-shadow: 0 1px 3px #000; }

/* phase indicator: a slim centered line above the stage. Fixed height + nowrap so
   it never reflows when the label/eta text changes between phases (no height jump). */
#phase-ribbon {
  display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 10px;
  height: 30px; flex-wrap: nowrap; white-space: nowrap; overflow: hidden;
}
#phase-label {
  font-family: var(--display); font-size: 17px; letter-spacing: 2px; color: var(--gold);
  text-transform: uppercase; line-height: 1;
}
#phase-clock { font-size: 18px; color: var(--text); }

#timerbar { height: 3px; background: rgba(255,255,255,.06); border-radius: 3px; overflow: hidden; }
#timerbar-fill { height: 100%; width: 100%; background: var(--gold); transition: none; border-radius: 3px; }
#timerbar-fill.fog { background: #9db3d8; }
#timerbar-fill.race { background: var(--danger); }

/* ---------------- stage ---------------- */
#stage {
  position: relative; margin-top: 8px;
  height: clamp(320px, 44vh, 460px);
  border-radius: var(--radius);
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.07);
  background: linear-gradient(#0a1c40 0%, #0d2c52 16%, #14507e 22%, #10456f 55%, #0a2b4c 100%);
}
#sea, #fx { position: absolute; inset: 0; width: 100%; height: 100%; }
#fx { z-index: 5; pointer-events: none; }
.lane { position: absolute; left: 0; width: 100%; z-index: 3; }
#lane-port { top: calc(8% + 10px); height: 44%; }
#lane-star { top: calc(50% + 10px); height: 44%; }

.ship {
  position: absolute; left: 0; top: 0;
  width: clamp(190px, 30vw, 300px);
  will-change: transform;
  filter: drop-shadow(0 10px 14px rgba(0,0,0,.45));
}
.ship svg { width: 100%; height: auto; display: block; overflow: visible; }
/* premium ship motion: sails breathe, flags flutter */
.ship .sails { animation: sailBillow 3.4s ease-in-out infinite; }
#lane-star .ship .sails { animation-delay: -1.2s; }
@keyframes sailBillow {
  0%, 100% { transform: scaleX(1) skewX(0deg); }
  50% { transform: scaleX(1.035) skewX(-1.4deg); }
}
.ship .flag { animation: flagWave 1.1s ease-in-out infinite; }
@keyframes flagWave {
  0%, 100% { transform: skewY(0deg) scaleX(1); }
  50% { transform: skewY(4deg) scaleX(.9); }
}
.ship .gold-pile { transition: transform .5s cubic-bezier(.3,1.3,.5,1); }
.ship .skull { transition: opacity .4s ease; }
/* Titanic break-up: hull snaps into a stern + bow that rotate apart and sink */
.ship-half { position: absolute; z-index: 3; pointer-events: none; overflow: hidden; }
.ship-half svg { position: absolute; inset: 0; width: 100%; height: auto; }
.ship-half.stern { clip-path: inset(0 52% 0 0); transform-origin: 62% 55%; animation: sternBreak 2.4s cubic-bezier(.35,.55,.5,1) forwards; }
.ship-half.bow { clip-path: inset(0 0 0 50%); transform-origin: 38% 55%; animation: bowBreak 2.4s cubic-bezier(.35,.55,.5,1) forwards; }
@keyframes sternBreak {
  0% { transform: translate(0,0) rotate(0); opacity: 1; }
  22% { transform: translate(-4px,1px) rotate(-16deg); opacity: 1; }
  100% { transform: translate(-26px,64px) rotate(-40deg); opacity: 0; }
}
@keyframes bowBreak {
  0% { transform: translate(0,0) rotate(0); opacity: 1; }
  22% { transform: translate(4px,1px) rotate(14deg); opacity: 1; }
  100% { transform: translate(30px,76px) rotate(46deg); opacity: 0; }
}
.deck-crew {
  position: absolute; left: 14%; right: 20%; top: 34%;
  display: flex; flex-wrap: nowrap; gap: 2px; justify-content: center; align-items: flex-end;
  pointer-events: none;
}
.av {
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--c, #ccc);
  border: 1.5px solid rgba(0,0,0,.55);
  box-shadow: inset 0 -3px 0 rgba(0,0,0,.35), inset 0 3px 0 rgba(255,255,255,.28);
  flex: 0 0 auto;
}
.av.bot { opacity: .8; border-style: dashed; }
.av.you { outline: 2px solid #fff; outline-offset: 1px; animation: youpulse 1.6s infinite; }
@keyframes youpulse { 50% { outline-color: rgba(255,255,255,.25); } }
.av-more {
  font-size: 9px; color: #fff; background: rgba(0,0,0,.5);
  border-radius: 8px; padding: 0 4px; line-height: 12px; flex: 0 0 auto;
}
.float-stake {
  position: absolute; z-index: 6; font-family: var(--mono); font-weight: 600;
  font-size: 13px; pointer-events: none; text-shadow: 0 1px 3px #000;
  animation: floatup 1.4s ease-out forwards;
}
@keyframes floatup { from { opacity: 0; transform: translateY(8px); } 20% { opacity: 1; } to { opacity: 0; transform: translateY(-34px); } }

/* fog — the tensest beat of the round: a heavy, moody bank that swallows the ships,
   darker at the edges (vignette) with a slow breathing pulse */
/* DEAD — The Fog phase went away with the hidden-headcount game, and
   nothing renders #fog any more. These rules are unreachable and can be
   deleted wholesale along with .fog-blob / #fog-note / @keyframes fogDrift
   and the body.fog-on rules below. */
#fog {
  position: absolute; inset: 0; z-index: 4;
  /* dense, near-opaque steel-blue fog bank — the scene is almost fully hidden.
     No blur: it's the fog itself (thick opacity) doing the work. */
  background:
    radial-gradient(150% 130% at 50% 45%,
      rgba(196,210,232,.88) 0%, rgba(176,193,220,.92) 55%,
      rgba(150,170,202,.95) 100%);
  animation: fogIn 1s ease, fogBreathe 4.5s ease-in-out infinite;
  transition: opacity 1s ease, background 1s ease;
}
@keyframes fogIn { from { opacity: 0; } }
@keyframes fogBreathe { 0%, 100% { filter: brightness(1) contrast(1); } 50% { filter: brightness(1.09) contrast(1.04); } }
/* clearing: slow ~1s fade, banks part to the left and right */
#fog.clearing { opacity: 0; background: transparent; pointer-events: none; }
/* fog swallows the ships entirely — nothing shows through the bank */
body.fog-on #lane-port, body.fog-on #lane-star { opacity: 0 !important; transition: opacity .6s ease; }
#lane-port, #lane-star { transition: opacity .6s ease; }
#fog.clearing .fog-blob { animation: none; transition: transform 1s ease, opacity 1s ease; opacity: 0; }
#fog.clearing .f1, #fog.clearing .f3, #fog.clearing .f4 { transform: translateX(-45%); }
#fog.clearing .f2, #fog.clearing .f5 { transform: translateX(45%); }
#fog .fog-blob {
  position: absolute; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(214,222,238,.72), rgba(214,222,238,.25) 55%, transparent 75%);
  filter: blur(10px);
}
.f1 { width: 90%; height: 85%; top: -6%; left: -16%; animation: drift1 9s ease-in-out infinite alternate; }
.f2 { width: 100%; height: 95%; top: 10%; right: -22%; animation: drift2 11s ease-in-out infinite alternate; }
.f3 { width: 85%; height: 75%; bottom: -12%; left: 10%; animation: drift1 13s ease-in-out infinite alternate-reverse; }
.f4 { width: 80%; height: 70%; top: 24%; left: 24%; animation: drift2 8s ease-in-out infinite alternate; }
.f5 { width: 95%; height: 80%; bottom: 4%; right: -10%; animation: drift1 15s ease-in-out infinite alternate; }
@keyframes drift1 { to { transform: translateX(12%) translateY(-3%); } }
@keyframes drift2 { to { transform: translateX(-12%) translateY(3%); } }
#fog-note {
  position: absolute; left: 50%; top: 44%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: rgba(6, 10, 22, 0.74); border: 1px solid rgba(245,197,66,.32);
  color: #e7edf8; padding: 11px 28px; border-radius: 14px; text-align: center;
  backdrop-filter: blur(4px); white-space: nowrap;
  box-shadow: 0 8px 30px rgba(4,7,16,.6), 0 0 18px rgba(245,197,66,.14);
  animation: fogNotePulse 2s ease-in-out infinite;
}
.fog-head {
  font-family: var(--display); font-size: 23px; letter-spacing: 4px; line-height: 1;
  color: var(--gold); text-transform: uppercase; text-shadow: 0 0 20px rgba(245,197,66,.55);
}
.fog-sub { font-size: 12.5px; color: #cdd7eb; letter-spacing: .8px; text-transform: uppercase; }
.fog-sub b { color: #ff6b5e; text-transform: uppercase; letter-spacing: 1px; }
.fog-sub #fog-timer { color: var(--gold); }
@keyframes fogNotePulse {
  0%, 100% { box-shadow: 0 8px 30px rgba(4,7,16,.6), 0 0 14px rgba(245,197,66,.1); }
  50% { box-shadow: 0 8px 34px rgba(4,7,16,.7), 0 0 30px rgba(245,197,66,.28); }
}

/* race / winner banner — a proper overlay card over the stage */
#banner {
  position: absolute; z-index: 7; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  text-align: center; pointer-events: none;
  padding: 16px 30px; border-radius: 16px;
  background: rgba(6, 10, 22, 0.6); border: 1px solid var(--line);
  backdrop-filter: blur(3px);
  box-shadow: 0 12px 40px rgba(0,0,0,.5), 0 0 40px rgba(245,197,66,.12);
  animation: bannerin .5s cubic-bezier(.2, 1.6, .4, 1);
}
#banner[hidden] { display: none; }
#banner.port { border-color: rgba(226,73,59,.6); box-shadow: 0 12px 40px rgba(0,0,0,.5), 0 0 46px rgba(226,73,59,.3); }
#banner.star { border-color: rgba(110,168,224,.6); box-shadow: 0 12px 40px rgba(0,0,0,.5), 0 0 46px rgba(110,168,224,.28); }
@keyframes bannerin { from { opacity: 0; transform: translate(-50%, -30%) scale(.7); } }
#banner .b-big {
  font-family: var(--display); font-size: clamp(26px, 5vw, 44px); letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--gold); text-shadow: 0 2px 24px rgba(245,197,66,.5), 0 2px 4px #000;
}
#banner .b-sub {
  color: var(--text); font-size: 14px; text-shadow: 0 1px 3px #000; margin-top: 2px;
  text-transform: uppercase; letter-spacing: .5px;
}
#banner.void .b-big { color: #9db3d8; text-shadow: 0 2px 18px rgba(157,179,216,.4); }
/* quick fade-out for "The Race" right before the gold reveal */
#banner.bfade { animation: bannerFadeOut .3s ease forwards; }
@keyframes bannerFadeOut { to { opacity: 0; transform: translate(-50%, -60%) scale(.94); } }




/* ---------------- panel: controls ---------------- */
#panel {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px; display: flex; flex-direction: column; gap: 10px;
  min-height: 320px;
}
/* chat on top, betting controls at the bottom */
#panel > #tabs { order: 1; }
#panel > .tabpane { order: 2; }
#panel > #controls { order: 3; margin-top: 2px; padding-top: 10px; border-top: 1px solid var(--line); }
#chips { display: flex; gap: 6px; }
.chip {
  flex: 1; padding: 8px 0; border-radius: 9px; font-family: var(--mono); font-weight: 600;
  background: rgba(255,255,255,.05); color: var(--muted);
  border: 1px solid rgba(255,255,255,.1); font-size: 13px;
}
.chip.sel { background: rgba(245,197,66,.16); color: var(--gold); border-color: var(--gold-dim); }

#custom-row { display: flex; align-items: center; gap: 10px; }
.custom-field {
  flex: 1; display: flex; align-items: center; gap: 4px;
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.12);
  border-radius: 9px; padding: 0 12px;
}
.custom-field:focus-within { border-color: var(--gold-dim); }
.custom-field span { color: var(--gold); font-family: var(--mono); font-weight: 600; }
#custom-bet {
  flex: 1; width: 100%; background: none; border: none; color: var(--text);
  font-family: var(--mono); font-size: 15px; font-weight: 600; padding: 9px 0;
}
#custom-bet:focus { outline: none; }
#custom-bet::-webkit-outer-spin-button, #custom-bet::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

#board-btns { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.board {
  border-radius: 12px; padding: 12px 8px 10px; border: 1px solid;
  display: flex; flex-direction: column; gap: 3px; align-items: center; justify-content: center;
  min-height: 82px;
  color: #fff; position: relative; overflow: hidden;
  transition: transform .12s, filter .2s;
}
.board:active { transform: scale(.97); }
.board:disabled { filter: grayscale(.7) brightness(.6); cursor: not-allowed; }
.board.port { background: linear-gradient(160deg, #a33227, #6c1f17); border-color: #e2493b; box-shadow: 0 4px 18px rgba(226,73,59,.25); }
.board.star { background: linear-gradient(160deg, #3a6ba3, #22436e); border-color: #6ea8e0; box-shadow: 0 4px 18px rgba(110,168,224,.22); }
.b-title { display: flex; flex-direction: column; align-items: center; gap: 1px; font-family: var(--display); letter-spacing: 1.5px; }
/* BET is the hero of the button; the ship name is the subtitle */
.b-verb { font-size: 21px; font-weight: 800; letter-spacing: 1.2px; line-height: 1.05; opacity: 1; }
.b-ship { font-size: 13px; font-weight: 700; letter-spacing: .8px; line-height: 1.15; white-space: nowrap; opacity: .9; text-transform: uppercase; }
/* reserve two lines so the FULL "bet $X → win $Y" always shows, and the button
   height stays constant whether the text is one line or two */
.b-mult {
  font-size: 12px; opacity: .95; text-align: center; padding: 0 4px;
  font-family: var(--mono); line-height: 1.2; white-space: normal;
  min-height: 29px; display: flex; align-items: center; justify-content: center;
  text-transform: uppercase;   /* BET $0.50 -> WIN $1.04 / MOVE YOUR GOLD */
}

/* ---- the four lives of a ship button ----
   .mine     bet placed, waiting for the ships to sail
   .cashout  LIVE — money on the table, worth more every frame
   .cashed   got out in time, at the multiplier shown
   .lost     went down with the gold still aboard
   The two buttons are independent, so any combination of these can be on
   screen at once — including .cashed on one ship and .cashout on the other,
   which is exactly what a hedged round looks like mid-flight. */
.board.mine { outline: 2px solid var(--gold); outline-offset: -2px; box-shadow: 0 0 0 1px var(--gold), 0 6px 24px rgba(245,197,66,.32); }
.board.mine .b-verb { color: var(--gold); opacity: 1; }
.board.mine .b-mult { color: #ffe9a8; opacity: 1; font-weight: 600; }

/* .cashout / .cashed / .lost live in v2.css, which loads after this file
   and owns the current .board look. */

/* ⓘ info button (navbar, next to How to play) */
/* Info pill — matches the Rules pill. Collapses to a compact "i" on phones so a
   narrow navbar (e.g. 344px folds) can never overflow. */
.info-top {
  align-self: center; flex: 0 0 auto; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center; line-height: 1;
  font-family: var(--sans); font-weight: 800; font-size: 12.5px; padding: 5px 13px;
  letter-spacing: .8px; text-transform: uppercase;
  color: var(--gold); background: rgba(245,197,66,.12); border: 1px solid var(--gold-dim);
  box-shadow: 0 0 0 1px var(--gold-dim), 0 0 16px rgba(211,162,75,.35);   /* glow, like Music */
}
.info-top:hover { background: rgba(245,197,66,.24); }

/* the fine-print list in the info modal */
.fine-list { list-style: none; display: flex; flex-direction: column; gap: 11px; }
.fine-list li { position: relative; padding-left: 18px; font-size: 13.5px; line-height: 1.45; color: var(--text); }
.fine-list li::before { content: '•'; position: absolute; left: 3px; color: var(--gold); }

#position-row { display: flex; gap: 8px; align-items: center; }
#position-pill {
  flex: 1; font-size: 12.5px; color: var(--text);
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1);
  padding: 8px 10px; border-radius: 9px; line-height: 1.35;
}
#position-pill b.port { color: var(--port); } #position-pill b.star { color: var(--star); }
#btn-jump {
  background: linear-gradient(160deg, #f5c542, #d49a1e); color: #2a1e05;
  border: 1px solid #ffe08a; font-weight: 700; letter-spacing: .3px;
  padding: 12px 18px; border-radius: 11px; font-size: 14.5px; white-space: nowrap;
  box-shadow: 0 4px 16px rgba(245,197,66,.35);
  animation: jumpPulse 1.9s ease-in-out infinite;
}
#btn-jump:hover { filter: brightness(1.08); }
#btn-jump:active { transform: scale(.96); }
#btn-jump:disabled { opacity: .3; cursor: not-allowed; animation: none; box-shadow: none; }
#btn-jump small { opacity: .8; font-weight: 600; }
@keyframes jumpPulse {
  0%, 100% { box-shadow: 0 4px 16px rgba(245,197,66,.3); }
  50% { box-shadow: 0 4px 22px rgba(245,197,66,.6); }
}
#btn-salvage {
  background: rgba(110,168,224,.12); color: var(--star); border: 1px dashed var(--star);
  padding: 9px; border-radius: 9px; font-size: 13px;
}

/* ---------------- tabs + feed ---------------- */
#tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--line); }
.tab {
  background: none; border: none; color: var(--muted); padding: 7px 10px 8px;
  font-size: 13px; border-bottom: 2px solid transparent; letter-spacing: .3px;
}
.tab.sel { color: var(--gold); border-bottom-color: var(--gold); }
.help-top {
  align-self: center; font-weight: 800; font-size: 12.5px;
  letter-spacing: .8px; text-transform: uppercase;
  color: var(--gold); border: 1px solid var(--gold-dim); border-radius: 999px;
  padding: 5px 13px; background: rgba(245,197,66,.14); white-space: nowrap;
  animation: helpPulse 2.4s ease-in-out infinite;
}
.help-top:hover { background: rgba(245,197,66,.26); }
@keyframes helpPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(245,197,66,.55); }
  50% { box-shadow: 0 0 0 6px rgba(245,197,66,0); }
}

.tabpane { display: flex; flex-direction: column; gap: 8px; min-height: 180px; }
.tabpane[hidden] { display: none; }   /* the reset broke [hidden]; restore it so only one tab shows */
#tab-log, #tab-book { overflow: hidden; }   /* only the inner list scrolls, never the pane */
#tab-book .pane-note { order: 2; margin-top: auto; padding-top: 8px; border-top: 1px solid var(--line); }
#tab-book #rounds-list { order: 1; }
#feed, #feed-bets {
  height: 240px; overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: 5px;
  padding-right: 6px; overscroll-behavior: contain;
  scroll-behavior: smooth;
}
@media (min-width: 980px) { #feed, #feed-bets { height: 300px; } }
/* one clean scrollbar style across the panel */
#feed, #feed-bets, #leaderboard, #rounds-list {
  scrollbar-width: thin; scrollbar-color: rgba(245,197,66,.35) transparent;
}
#feed::-webkit-scrollbar, #leaderboard::-webkit-scrollbar, #rounds-list::-webkit-scrollbar { width: 7px; }
#feed::-webkit-scrollbar-track, #leaderboard::-webkit-scrollbar-track, #rounds-list::-webkit-scrollbar-track { background: transparent; }
#feed::-webkit-scrollbar-thumb, #leaderboard::-webkit-scrollbar-thumb, #rounds-list::-webkit-scrollbar-thumb {
  background: rgba(245,197,66,.28); border-radius: 6px;
}
#feed::-webkit-scrollbar-thumb:hover, #leaderboard::-webkit-scrollbar-thumb:hover, #rounds-list::-webkit-scrollbar-thumb:hover {
  background: rgba(245,197,66,.5);
}
/* "new messages" nudge when scrolled up */
#tab-chat { position: relative; }
#scroll-bottom {
  position: absolute; right: 12px; bottom: 58px; z-index: 6;
  display: none; align-items: center; gap: 4px;
  background: var(--gold); color: #201a06; font-size: 11px; font-weight: 600;
  border: none; border-radius: 999px; padding: 5px 11px; cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,.4);
}
#scroll-bottom.show { display: inline-flex; }
.msg { font-size: 13px; line-height: 1.4; overflow-wrap: anywhere; }
.msg .who { font-weight: 600; }
.msg .bot-tag { font-size: 9px; color: var(--muted); border: 1px solid var(--muted); border-radius: 4px; padding: 0 3px; margin-left: 3px; vertical-align: 1px; }
.msg.sys { color: var(--muted); font-style: italic; }
.msg.evt { color: var(--gold); }
.msg.evt.treasure { color: #7bdff2; }
#chat-form { display: flex; gap: 6px; }
#chat-input {
  flex: 1; background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.12);
  color: var(--text); padding: 9px 12px; border-radius: 9px; font-size: 14px; font-family: var(--sans);
}
#chat-input:focus { outline: 1px solid var(--gold-dim); }
#chat-form button {
  background: var(--gold); color: #201a06; border: none; border-radius: 9px;
  padding: 0 14px; font-size: 13px; font-weight: 700; font-family: var(--sans);
}

.pane-note { font-size: 11.5px; color: var(--muted); }
#leaderboard, #rounds-list { list-style: none; display: flex; flex-direction: column; gap: 5px; overflow-y: auto; flex: 1 1 auto; min-height: 0; max-height: 46vh; }
#leaderboard li, #rounds-list li {
  display: flex; align-items: center; gap: 8px; font-size: 13px;
  background: rgba(255,255,255,.04); padding: 7px 9px; border-radius: 8px;
}
#leaderboard .pos { font-family: var(--mono); color: var(--muted); width: 16px; }
#leaderboard .lb-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#leaderboard .lb-pct { font-family: var(--mono); color: var(--gold); font-weight: 600; }
#leaderboard .lb-n { font-size: 10.5px; color: var(--muted); }
#rounds-list .r-round { font-family: var(--mono); color: var(--muted); }
#rounds-list .r-winner { font-weight: 600; }
#rounds-list .r-winner.port { color: var(--port); } #rounds-list .r-winner.star { color: var(--star); }
#rounds-list .r-winner.void { color: var(--muted); font-weight: 400; }
#rounds-list .r-mult { margin-left: auto; font-family: var(--mono); color: var(--gold); }

/* ---------------- footer ---------------- */
#foot {
  max-width: 1560px; margin: 4px auto 14px; padding: 0 14px;
  display: flex; flex-wrap: wrap; gap: 4px 14px;
  color: var(--muted); font-size: 10.5px;
}

/* ---------------- toasts / result ---------------- */
/* Toasts sit ABOVE the bet bar, never over it. In a crash round the two
   ship buttons are live controls with a deadline — a sink/cash-out toast
   landing on top of them can cover the exact button the player is reaching
   for, and cost them the round. --betbar-h is kept in sync with the real
   bar height by app.js's syncBars(). */
#toasts {
  position: fixed; z-index: 80; left: 50%; transform: translateX(-50%);
  bottom: calc(var(--betbar-h, 120px) + 14px);
  display: flex; flex-direction: column; gap: 8px; align-items: center; pointer-events: none;
}
.toast {
  background: var(--panel-solid); border: 1px solid var(--line); color: var(--text);
  padding: 10px 18px; border-radius: 12px; font-size: 14px; text-align: center;
  box-shadow: 0 8px 30px rgba(0,0,0,.5);
  animation: toastin .3s ease, toastout .4s ease 3.4s forwards;
}
.toast.win { border-color: var(--gold); color: var(--gold); font-weight: 600; font-size: 16px; text-transform: uppercase; letter-spacing: .5px; }
.toast.loss { border-color: rgba(226,73,59,.5); text-transform: uppercase; letter-spacing: .5px; }
.toast.err { border-color: var(--danger); color: var(--danger); }
@keyframes toastin { from { opacity: 0; transform: translateY(14px); } }
@keyframes toastout { to { opacity: 0; transform: translateY(8px); } }

/* ---------------- dialog ---------------- */
/* ---- custom modal (own z-index + backdrop; no native <dialog> quirks) ---- */
.modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  display: grid; place-items: center; padding: 16px;
  background: rgba(4, 6, 14, 0.82); backdrop-filter: blur(4px);
  animation: overlayIn .2s ease;
}
.modal-overlay[hidden] { display: none; }
@keyframes overlayIn { from { opacity: 0; } }
/* Same glass-panel language as the settings dropdown (.settings-pop) and the
   side panel (#panel, var(--panel)) — translucent + blurred so the scene
   shows through, instead of a flat opaque card that reads as a generic web
   dialog dropped on top of the game. */
.modal-box {
  position: relative; width: min(640px, 100%); max-height: 88vh;
  display: flex; flex-direction: column;
  background: var(--panel); color: var(--text);
  backdrop-filter: blur(20px) saturate(160%);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  border: 1px solid rgba(245,197,66,.28); border-radius: 18px; overflow: hidden;
  box-shadow: 0 24px 70px rgba(0,0,0,.6), inset 0 1px 0 rgba(255,255,255,.06);
  animation: helpIn .28s cubic-bezier(.2,1.2,.4,1);
}
/* a thin gold wash across the top edge — the one "this belongs to Plunder"
   flourish every settings page shares, echoing the horizon line in the scene */
.modal-box::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; z-index: 2;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: .85;
}
.help-body { overflow-y: auto; padding: 26px 26px 10px; flex: 1 1 auto; min-height: 0; overscroll-behavior: contain; }
/* pretty gold scrollbar, not the default */
.help-body { scrollbar-width: thin; scrollbar-color: rgba(245,197,66,.4) transparent; }
.help-body::-webkit-scrollbar { width: 8px; }
.help-body::-webkit-scrollbar-track { background: transparent; margin: 6px 0; }
.help-body::-webkit-scrollbar-thumb { background: rgba(245,197,66,.32); border-radius: 8px; }
.help-body::-webkit-scrollbar-thumb:hover { background: rgba(245,197,66,.55); }
.help-foot { flex: 0 0 auto; padding: 14px 26px 20px; border-top: 1px solid rgba(245,197,66,.16); }
#help-x, #info-x, #limits-x, #credits-x {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 36px; height: 36px; border-radius: 50%; border: 1px solid rgba(255,255,255,.16);
  background: rgba(10,21,38,.6); color: var(--text); font-size: 16px; line-height: 1;
  display: grid; place-items: center; cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .15s;
}
#help-x:hover, #info-x:hover, #limits-x:hover, #credits-x:hover {
  background: rgba(226,73,59,.35); border-color: rgba(226,73,59,.6); color: #fff; transform: scale(1.06);
}
/* lock ONLY the background from scrolling while the modal is open */
html.modal-open, body.modal-open { overflow: hidden !important; touch-action: none; }
@keyframes helpIn { from { opacity: 0; transform: translateY(12px) scale(.96); } }
#help h2, #info h2, #limits h2, #credits h2 {
  font-family: var(--display); color: var(--gold); font-weight: 400; letter-spacing: 1px;
  font-size: 26px; margin-bottom: 16px; padding-bottom: 14px;
  border-bottom: 1px solid rgba(245,197,66,.2);
}
#help h3, #info h3, #limits h3, #credits h3 {
  font-family: var(--display); color: var(--gold); font-weight: 400; letter-spacing: .4px;
  font-size: 16px; margin: 20px 0 8px;
}
#help h3:first-child, #info h3:first-child, #limits h3:first-child, #credits h3:first-child { margin-top: 0; }
#help p, #info p, #limits p, #credits p { font-size: 13.5px; line-height: 1.55; color: var(--text); margin-bottom: 10px; }
/* the gold "Got it" close button — a gentle sheen + lift on hover, matching
   the bet buttons' tactile feel instead of a flat solid rectangle */
#help .close, #info .close, #limits .close, #credits .close {
  width: 100%; padding: 13px; border-radius: 10px;
  border: 1px solid rgba(245,197,66,.5);
  background: linear-gradient(180deg, #e8c26c, var(--gold) 55%, #b9893a);
  color: #201a06; font-weight: 700; font-size: 15px;
  box-shadow: 0 4px 14px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.35);
  transition: transform .12s ease, box-shadow .12s ease;
}
#help .close:hover, #info .close:hover, #limits .close:hover, #credits .close:hover {
  transform: translateY(-1px); box-shadow: 0 7px 18px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.45);
}
#help .close:active, #info .close:active, #limits .close:active, #credits .close:active { transform: translateY(0); }
#help .rule em { color: var(--gold); font-style: normal; }

/* animated demo: lighter ship overtakes and plunders the heavy one, on a loop */
.demo {
  display: flex; flex-direction: column; gap: 6px;
  background: linear-gradient(#0b1630, #0a1226); border: 1px solid var(--line);
  border-radius: 12px; padding: 12px 10px; margin-bottom: 14px; overflow: hidden;
}
.demo-lane { position: relative; height: 34px; }
.demo-ship { position: absolute; left: 0; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.demo-ship .ds-hull { font-size: 24px; }
.demo-ship .ds-tag { font-size: 10.5px; color: var(--muted); }
.demo-ship.light { animation: demoLight 4.2s ease-in-out infinite; }
.demo-ship.heavy { animation: demoHeavy 4.2s ease-in-out infinite; }
.demo-coins { position: absolute; right: 6%; top: 4px; font-size: 12px; animation: demoLoot 4.2s ease-in-out infinite; }
@keyframes demoLight {
  0%, 22% { left: 4%; } 60% { left: 62%; } 72%, 100% { left: 62%; }
}
@keyframes demoHeavy {
  0%, 22% { left: 4%; } 60% { left: 30%; }
  74% { left: 30%; transform: rotate(0); opacity: 1; }
  88% { transform: rotate(16deg) translateY(6px); opacity: .5; }
  100% { transform: rotate(24deg) translateY(14px); opacity: 0; }
}
@keyframes demoLoot {
  0%, 74% { opacity: 0; transform: translateX(0); }
  80% { opacity: 1; } 100% { opacity: 0; transform: translateX(-120px) translateY(-8px); }
}

.steps { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.steps li {
  display: flex; gap: 11px; align-items: flex-start; font-size: 13.5px; line-height: 1.4;
  opacity: 0; transform: translateX(-8px);
  animation: stepIn .45s ease forwards;
}
.steps li:nth-child(1) { animation-delay: .1s; }
.steps li:nth-child(2) { animation-delay: .22s; }
.steps li:nth-child(3) { animation-delay: .34s; }
.steps li:nth-child(4) { animation-delay: .46s; }
.steps li:nth-child(5) { animation-delay: .58s; }
@keyframes stepIn { to { opacity: 1; transform: translateX(0); } }
.step-ico {
  flex: 0 0 auto; width: 30px; height: 30px; display: grid; place-items: center;
  font-size: 16px; border-radius: 8px; background: rgba(245,197,66,.1); border: 1px solid var(--line);
}
.step-ico.ico-weight { animation: tilt 2.6s ease-in-out infinite; }
@keyframes tilt { 0%,100% { transform: rotate(-8deg); } 50% { transform: rotate(8deg); } }
.step-ico.ico-fog { animation: fogPulse 2.4s ease-in-out infinite; }
@keyframes fogPulse { 0%,100% { opacity: .55; } 50% { opacity: 1; } }
#help .fine { font-size: 11px; color: var(--muted); margin-top: 12px; }
#help .close, #info .close, #limits .close, #credits .close {
  width: 100%; padding: 12px; border-radius: 10px; border: none;
  background: var(--gold); color: #201a06; font-weight: 700; font-size: 15px;
}

/* ---------------- How to Play: step screenshot placeholders ---------------- */
/* Clean, consistently-sized boxes even before real screenshots are dropped in —
   the STEP tag + alt text both stay legible if the <img> 404s. To swap in a
   real screenshot, just replace the file at the same path (see index.html):
   /img/help/step-1.jpg … step-4.jpg — same filename, same spot, nothing else
   to change. */
.step-shot {
  position: relative; margin-top: 10px; border-radius: 10px; overflow: hidden;
  aspect-ratio: 16 / 9; background: rgba(255,255,255,.03);
  border: 1px dashed var(--line);
}
.step-shot img { width: 100%; height: 100%; object-fit: cover; display: block; color: var(--muted); font-size: 11px; }
.step-shot-tag {
  position: absolute; top: 8px; left: 8px; z-index: 1;
  background: rgba(0,0,0,.65); color: var(--gold); font-size: 10.5px; font-weight: 700;
  letter-spacing: .08em; padding: 3px 9px; border-radius: 999px; pointer-events: none;
}
/* ---------------- How to Play: two-pane onboarding (steps left / shot right) ----
   Vanilla port of cult-ui's Onboarding component structure/animation
   (https://cult-ui.com/docs/components/onboarding) — that component is
   React + Tailwind + shadcn only, so this reproduces its step-indicator +
   step-list + Back/Next pattern directly in CSS, driven by ui.js. Layout:
   the left column lists every step (click any row to jump straight to it);
   the right column shows ONE screenshot pane that swaps to match whichever
   step is active. Stacks to a single column on narrow screens. --- */
.ob-box { width: min(860px, 96vw); }

/* step indicator — "dots" variant: active dot elongates into a pill and
   turns gold, completed dots stay a dim gold, everything eases smoothly. */
.ob-dots { display: flex; align-items: center; justify-content: center; gap: 7px; margin: 14px 0 4px; }
.ob-dot {
  height: 7px; width: 7px; border-radius: 999px;
  background: rgba(255,255,255,.18);
  transition: width .25s cubic-bezier(.2,1,.3,1), background-color .25s ease;
}
.ob-dot[data-state="active"] { width: 26px; background: var(--gold); }
.ob-dot[data-state="completed"] { background: rgba(245,197,66,.5); }

.ob-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; align-items: start; margin-top: 16px; }

/* left: the full step list. Only the active row expands to show its
   description (a CSS-only accordion via max-height) — inactive rows stay
   compact so all four are always visible at a glance and one tap away. */
.ob-list { display: flex; flex-direction: column; gap: 6px; }
.ob-item {
  display: flex; gap: 12px; align-items: flex-start; width: 100%; text-align: left;
  padding: 12px 14px; border-radius: 12px; border: 1px solid transparent;
  background: transparent; color: inherit; font: inherit; cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}
.ob-item:hover { background: rgba(255,255,255,.035); }
.ob-item[aria-selected="true"] { background: rgba(245,197,66,.07); border-color: rgba(245,197,66,.3); }
.ob-item-ico {
  flex: 0 0 auto; width: 32px; height: 32px; border-radius: 9px; margin-top: 1px;
  display: grid; place-items: center; color: var(--muted);
  background: rgba(255,255,255,.04); border: 1px solid var(--line);
  transition: color .15s ease, background-color .15s ease, border-color .15s ease;
}
.ob-item-ico svg { width: 16px; height: 16px; }
.ob-item[aria-selected="true"] .ob-item-ico { color: var(--gold); background: rgba(245,197,66,.14); border-color: rgba(245,197,66,.4); }
.ob-item-body { flex: 1 1 auto; min-width: 0; }
.ob-item-title { display: block; font-weight: 700; font-size: 14px; color: var(--text); }
.ob-item[aria-selected="true"] .ob-item-title { color: var(--gold); }
.ob-item-text {
  display: block; color: var(--muted); font-size: 12.5px; line-height: 1.55;
  max-height: 0; opacity: 0; overflow: hidden; margin-top: 0;
  transition: max-height .28s ease, opacity .22s ease, margin-top .28s ease;
}
.ob-item[aria-selected="true"] .ob-item-text { max-height: 160px; opacity: 1; margin-top: 6px; }

/* right: one screenshot pane, cross-fades between steps */
.ob-shots { position: relative; }
.ob-shots .step-shot { margin-top: 0; transition: opacity .25s ease; }
.ob-shots .step-shot[hidden] { display: none; }

.ob-reminder { margin-top: 16px; }

/* Back and Next are equal-width (flex:1 1 0 on both, same as Next already
   used) — the row splits evenly, so the gap-to-left-edge on Back mirrors
   the gap-to-right-edge on Next. */
.ob-nav { display: flex; gap: 10px; }
.ob-nav .ob-back {
  flex: 1 1 0; padding: 12px 18px; border-radius: 10px;
  background: transparent; border: 1px solid var(--line); color: var(--text);
  font-weight: 600; font-size: 14px; cursor: pointer; transition: opacity .15s, border-color .15s;
  text-align: center;
}
.ob-nav .ob-back:hover { border-color: var(--gold-dim); }
.ob-nav .ob-back:disabled { opacity: .35; cursor: default; pointer-events: none; }
.ob-nav .ob-next { flex: 1 1 0; }
/* #help .close (higher specificity — it's got an ID) sets width:100%,
   padding:12px and border:none, which otherwise beats the rule above and
   makes Next render a different size than Back. Match #help's specificity
   to actually win the cascade, and give both buttons an identical box
   model (padding + border) so they render exactly the same width. */
#help .ob-nav .ob-next {
  width: auto; padding: 12px 18px; border: 1px solid transparent; box-sizing: border-box;
}

@media (max-width: 700px) {
  .ob-layout { grid-template-columns: 1fr; }
  .ob-shots { order: -1; }   /* screenshot first on narrow screens, step list (with the tap targets) below it */
  .ob-item-text { max-height: 240px; }   /* single column has more vertical room per row */
}

/* ---------------- How to Play: headline + numbered steps ---------------- */
.rule {
  font-family: var(--display); font-size: 18px; text-align: center; line-height: 1.4;
  color: var(--text); background: linear-gradient(135deg, rgba(245,197,66,.1), rgba(255,255,255,.02));
  border: 1px solid rgba(245,197,66,.22); border-radius: 12px;
  padding: 14px 16px; margin-bottom: 18px;
}
/* custom numbering — a gold coin-badge per step instead of the browser's
   flat "1." — so this reads as a designed sequence, not a default <ol>. */
.rules { list-style: none; counter-reset: step; display: flex; flex-direction: column; gap: 14px; margin-bottom: 4px; }
.rules li {
  position: relative; padding-left: 38px; font-size: 13.5px; line-height: 1.55; color: var(--text);
}
.rules li::before {
  counter-increment: step; content: counter(step);
  position: absolute; left: 0; top: 0; width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center; font-family: var(--display); font-size: 13px; font-weight: 700;
  color: #201a06; background: linear-gradient(180deg, #e8c26c, var(--gold) 65%, #b9893a);
  box-shadow: 0 2px 6px rgba(0,0,0,.4);
}
.rules b { color: var(--gold); font-weight: 600; }
.rule-note {
  font-size: 12.5px; line-height: 1.55; color: var(--muted);
  background: rgba(245,197,66,.06); border: 1px solid rgba(245,197,66,.22);
  border-radius: 10px; padding: 11px 14px; margin-top: 14px;
}
.rule-note b { color: var(--gold); }
.rule-note a { color: #6ea8e0; }

/* ---------------- Terms: numbered clauses ---------------- */
.terms-list { list-style: none; display: flex; flex-direction: column; gap: 14px; }
.terms-list li { font-size: 13px; line-height: 1.55; color: var(--text); }
.terms-list b { color: var(--gold); font-weight: 600; }
.terms-note {
  font-size: 12px; color: var(--muted); background: rgba(255,193,7,.08);
  border: 1px solid rgba(255,193,7,.3); border-radius: 10px; padding: 10px 12px; margin-bottom: 14px;
}
.terms-updated { font-size: 11px; color: var(--muted); margin-top: 16px; font-style: italic; }

/* ---------------- Limits: min/max/max-multiplier readout ---------------- */
.limits-list { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 16px; }
.limit-row {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 12px 16px; border-radius: 10px; border-left: 3px solid var(--gold-dim);
  background: linear-gradient(135deg, rgba(245,197,66,.09), rgba(255,255,255,.02));
  border-top: 1px solid rgba(245,197,66,.18); border-right: 1px solid rgba(245,197,66,.18); border-bottom: 1px solid rgba(245,197,66,.18);
}
.limit-row dt { font-size: 13px; color: var(--muted); }
.limit-row dd { margin: 0; font-family: var(--mono); font-size: 15px; font-weight: 700; color: var(--gold); }

/* ---------------- Credits: asset attribution ---------------- */
.credits-list { list-style: none; display: flex; flex-direction: column; gap: 10px; margin: 0 0 14px; padding: 0; }
.credits-list li {
  font-size: 13px; line-height: 1.55; color: var(--text);
  padding: 10px 14px; border-radius: 10px; border-left: 3px solid var(--gold-dim);
  background: linear-gradient(135deg, rgba(245,197,66,.06), rgba(255,255,255,.02));
  border-top: 1px solid var(--line); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.credits-list b { color: var(--gold); font-weight: 600; }
.credits-list a { color: #6ea8e0; margin-left: 4px; white-space: nowrap; }

/* non-blocking: a small pill, never a modal — the game stays fully visible */
/* ============ v6: spacing, full-height desktop, premium polish ============ */

#controls { display: flex; flex-direction: column; gap: 16px; padding: 6px 2px 2px; }
#chips { gap: 8px; }
.chip { padding: 10px 0; }
#board-btns { gap: 10px; }
.board { padding: 15px 10px 13px; border-radius: 14px; }
#position-row { flex-wrap: wrap; gap: 8px; }
#position-pill { min-width: 200px; }
#panel { padding: 16px; gap: 12px; }

.ship-card { backdrop-filter: blur(6px); transition: box-shadow .25s ease, transform .15s ease; }
.ship-card:hover { transform: translateY(-1px); }
.ship-card.port:hover { box-shadow: inset 0 0 30px rgba(226,73,59,.14), 0 6px 24px rgba(226,73,59,.18); }
.ship-card.star:hover { box-shadow: inset 0 0 30px rgba(110,168,224,.14), 0 6px 24px rgba(110,168,224,.16); }
#phase-label { text-shadow: 0 0 20px rgba(245,197,66,.45); }

.board { overflow: hidden; }
.board::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 40%, rgba(255,255,255,.16) 50%, transparent 60%);
  transform: translateX(-130%); transition: transform .55s ease;
}
.board:hover::after { transform: translateX(130%); }

#stage { box-shadow: inset 0 0 90px rgba(2,5,14,.85), 0 18px 50px rgba(0,0,0,.35); }
.msg { animation: msgin .25s ease; }
@keyframes msgin { from { opacity: 0; transform: translateY(5px); } }
.toast.win { box-shadow: 0 0 34px rgba(245,197,66,.28); }
#banner .b-big { font-size: clamp(19px, 3vw, 30px); }

/* PC: fit to the viewport (no scroll). Big scene fills the left column;
   the right panel has chat on top and the betting buttons at the bottom. */
@media (min-width: 980px) {
  html, body { height: 100%; overflow: hidden; }
  body { display: flex; flex-direction: column; }
  #topbar, #foot { flex: 0 0 auto; }
  #layout { flex: 1 1 auto; min-height: 0; width: 100%; padding-bottom: 4px; }
  #stage-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
  #stage { flex: 1 1 auto; height: auto; max-height: none; min-height: 300px; }
  #panel { height: 100%; min-height: 0; overflow: hidden; }
  #tab-chat, #tab-bets { flex: 1 1 auto; min-height: 0; }
  #feed, #feed-bets { flex: 1 1 auto; height: auto; min-height: 0; }
  #tab-log, #tab-book { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
  #leaderboard, #rounds-list { max-height: none; }
  .ship { width: clamp(220px, 24vw, 360px); }
}

/* "back to the game" pill — only on scrolling (mobile/tablet) layouts.
   The chat is its own scroll box, so page-scrolling up is fiddly; this jumps
   straight back to the scene. Hidden on PC (that layout never scrolls). */
#to-top {
  position: fixed; z-index: 86; right: 10px; bottom: calc(7px + env(safe-area-inset-bottom));
  display: none; align-items: center; gap: 5px;
  background: rgba(20, 26, 54, 0.92); color: var(--gold); font-weight: 700; font-size: 12.5px;
  border: 1px solid var(--gold-dim); border-radius: 999px; padding: 8px 16px;
  box-shadow: 0 6px 20px rgba(0,0,0,.55); backdrop-filter: blur(4px);
}
#to-top.show { display: inline-flex; }
@media (min-width: 980px) { #to-top { display: none !important; } }

#reconnect {
  position: fixed; left: 12px; bottom: 12px; z-index: 100;
  pointer-events: none;
  background: rgba(14, 21, 49, 0.92); border: 1px solid var(--line);
  border-radius: 999px; padding: 7px 14px;
  font-size: 12.5px; color: var(--gold);
  box-shadow: 0 6px 20px rgba(0,0,0,.4);
}

/* ============ v7: responsive — tablet & phone ============ */

/* Single column (≤979px): SCENE is the star (big) at the top, chat scrolls,
   BETTING BUTTONS at the very bottom. Natural vertical page-scroll is fine;
   only horizontal scroll is forbidden (body has overflow-x: hidden). */
@media (max-width: 979px) {
  #online { display: none; }                       /* hide "aboard" on tablet + mobile */
  /* pad the scroll container (a footer margin-bottom is ignored at the scroll end) */
  body { padding-bottom: calc(8px + env(safe-area-inset-bottom)); }
  #foot { margin-bottom: 0; }
  #layout { display: block; padding: 6px 10px 14px; }
  #stage-wrap { display: block; }
  #stage { height: 52vh; min-height: 300px; }     /* big scene */
  #cards { margin-bottom: 4px; }
  #panel { min-height: 0; }
  #tab-chat, #tab-bets { min-height: 0; }
  #feed, #feed-bets { height: 50vh; }                          /* generous, scrollable chat */
  /* EVERY device below PC (tablet, fold, phone): betting on TOP, chat at BOTTOM */
  #panel > #controls { order: 0; border-top: none; margin-top: 0; padding-top: 0; }
  #panel > #tabs { order: 1; }
  #panel > .tabpane { order: 2; }
  /* keep Jump ship on the same line as the position bar, never wrapped below */
  #position-row { flex-wrap: nowrap; }
  #position-pill { min-width: 0; }
}

/* Phones */
@media (max-width: 620px) {
  body { font-size: 14px; }
  /* MOBILE: betting on TOP, chat at the BOTTOM */
  #panel > #controls { order: 0; border-top: none; margin-top: 0; padding-top: 0; }
  #panel > #tabs { order: 1; }
  #panel > .tabpane { order: 2; }
  /* topbar: everything icon-sized so nothing overlaps */
  #topbar { padding: 8px 8px 4px; gap: 6px; flex-wrap: nowrap; }
  .brand { gap: 5px; min-width: 0; flex-shrink: 0; align-items: center; }
  .brand h1 { font-size: 21px; letter-spacing: 1px; }
  .brand-sub { display: none; }
  .brand-mark { font-size: 17px; }
  .music-btn .mtext { display: none; }
  /* Info collapses to a compact circular "i" so the narrow navbar never overflows */
  .info-top { width: 30px; height: 30px; padding: 0; font-size: 15px; }
  .help-top, .music-btn { padding: 6px 9px; font-size: 15px; }
  .online-pill .olabel { display: none; }
  .top-right { gap: 6px; min-width: 0; }
  .online-pill { padding: 4px 7px; font-size: 11px; }
  #you-name { display: none; }                 /* hide the name, keep the balance */
  #you-flair { display: none; }
  .you-chip { padding: 5px 9px; font-size: 12.5px; gap: 4px; flex-shrink: 0; }

  /* ON-SHIP READOUTS (phones only): the info cards overlay the stage, positioned
     relative to #stage-wrap, instead of sitting in a desktop top row. */
  #stage-wrap { position: relative; }
  #cards { display: contents; }
  .ship-card {
    position: absolute; left: 12px; z-index: 6;
    width: 152px; box-sizing: border-box; min-height: 48px; justify-content: center;
    padding: 7px 13px; border-radius: 11px; gap: 2px;
    background: rgba(8,15,25,.7); border: 1px solid var(--line);
  }
  /* #card-port/#card-star positioning + tint now live entirely in v2.css
     (loaded after this file, so it already wins) — this block used to also
     set `top`/`bottom` here. Nothing else set `bottom:auto` for #card-star
     at any narrower breakpoint, so that stray `bottom: 12px` combined with
     v2.css's `top: 44%` and stretched the card into a full-height box (an
     absolutely-positioned element with BOTH top and bottom pinned fills the
     gap between them). Removed — v2.css's .ship-card now also explicitly
     pins bottom:auto itself so this class of bug can't come back. */
  #lane-port { top: calc(23% + 10px); }
  #lane-star { top: calc(53% + 10px); }

  #online { display: none; }               /* drop the aboard pill on phones */
  /* tighter everything so the betting + Jump-ship button all fit above the fold */
  #topbar { padding: 6px 8px 2px; }
  #cards { margin-bottom: 2px; }
  /* scene as tall as possible while the betting block + Jump ship still clear the
     fold. We reserve room for topbar+cards+controls+Jump; chat lives below (scroll). */
  /* svh (small viewport height) is FIXED — it does not change when the mobile
     address bar collapses on scroll, so the scene never resizes/reflows mid-scroll */
  /* scene as tall as possible: reserve only topbar + phase + controls + Auto Rebet;
     the chat feed lives entirely below the fold (scroll to reach it) */
  #stage { border-radius: 12px; height: calc(100svh - 403px); max-height: 66svh; min-height: 150px; margin-top: 4px; }
  .ship { width: clamp(160px, 46vw, 220px); }     /* fits two ships + readouts */
  #layout { padding: 3px 8px 10px; gap: 6px; }
  #panel { padding: 9px; gap: 7px; border-radius: 12px; }
  #feed, #feed-bets { height: 46vh; }                   /* scrollable chat, below the betting */
  #controls { gap: 8px; }
  #chips { gap: 5px; } .chip { padding: 8px 0; }
  #board-btns { gap: 8px; }
  .board { min-height: 76px; padding: 9px 8px; }
  #btn-jump { padding: 11px 16px; }
  #custom-row { gap: 6px; }
  /* instructions stay fully readable */
  .modal-overlay { padding: 8px; }
  .modal-box { max-height: 92vh; }
  .help-body { padding: 20px 16px 6px; }
  .help-foot { padding: 10px 16px 16px; }
  .rule { font-size: 16px; padding: 12px 14px; }
  .steps li { font-size: 13px; }
  .demo-ship .ds-tag { font-size: 10px; }
  #help h2, #info h2, #limits h2, #credits h2 { font-size: 21px; }

  #chips { flex-wrap: wrap; gap: 6px; }
  .chip { flex: 1 1 27%; padding: 8px 0; font-size: 13px; }
  .board { padding: 10px 8px; min-height: 76px; }
  .b-title { font-size: 15px; }

  #foot { font-size: 9.5px; gap: 3px 10px; margin-bottom: 0; }
  #toasts { width: calc(100vw - 24px); }
  .toast { font-size: 13px; }
  /* the mid-race "hold your breath" overlay: on phones show just the title, small,
     so it doesn't blanket the ships */
  #banner.racewait { padding: 8px 18px; }
  #banner.racewait .b-sub { display: none; }
  #banner.racewait .b-big { font-size: 22px; }
}

/* Short phones: the stage is cramped, so shrink the ships (they must never
   overlap each other) and the on-ship readouts. */
@media (max-width: 620px) and (max-height: 740px) {
  .ship { width: clamp(92px, 29vw, 130px); }
  #lane-port { top: calc(24% + 8px); }
  #lane-star { top: calc(51% + 8px); }
  .ship-card { max-width: 108px; padding: 4px 8px; gap: 1px; }
  .ship-card .card-name { font-size: 12px; }
  #jackpot-bar { font-size: 11px; padding: 3px 10px; }
}

/* Very small phones */
@media (max-width: 380px) {
  /* Folds (~344px): the wordmark collapses to a P monogram so RULES / I / music
     and the balance all keep their real hit targets on one line. */
  .brand h1 { font-size: 19px; letter-spacing: 0; }
  .brand-rest { display: none; }
  .brand-p {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 8px;
    background: rgba(211,162,75,.16); box-shadow: inset 0 0 0 1px var(--gold-dim);
  }
  .you-chip .mono::after { content: ""; }     /* drop the coin glyph to save space */
  .chip { flex: 1 1 30%; }
  #phase-ribbon { min-width: 58px; }
}

/* Landscape phones: keep the stage from eating the whole viewport */
@media (max-height: 520px) and (orientation: landscape) {
  #stage { height: 46vh; }
  .brand-sub { display: none; }
}
