/* =============================================================================
   bust.fun — MINES styles  (games/mines/mines.css)
   -----------------------------------------------------------------------------
   Game-SPECIFIC styles for this module. Linked from index.html. SYNTHWAVE TOKENS
   ONLY (tokens.css) — no hard-coded palette. Premium 5×5 grid: neutral tiles until
   the server resolves, then a staggered gem/mine reveal.

   HARD bars honored here:
     • 44px touch targets (tiles + slider thumb).
     • 0 horizontal overflow at 360px (the 5-col grid is fluid; gap shrinks at small w).
     • reduced-motion: ALL keyframe motion is no-op'd (the @media block at the bottom);
       reveals still land via the static end-state classes (the core paints all at once).
     • synthwave tokens only; the win/loss/cashout/bust feel comes from ctx.fx (presentation).
   ========================================================================== */

/* =============================================================================
   Mines grid — 5×5, fluid, never overflows
   ========================================================================== */
.mines-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr)); /* minmax(0,..) lets columns shrink below content @360px */
  grid-auto-rows: 1fr;            /* square cells when the grid is a square */
  gap: var(--sp-2);
  /* FILL: a large 5×5 SQUARE that scales with the viewport height, centred, capped to the panel width. */
  width: min(100%, 600px, 64vh);
  max-width: 100%;
  aspect-ratio: 1 / 1;
  margin: var(--sp-2) auto;
  /* a faint synthwave well behind the board so the tiles read as "set into" the panel */
  padding: var(--sp-2);
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 90% at 50% -10%, var(--brand-soft), transparent 60%),
    var(--surface-2);
  border: 1px solid var(--line);
}
/* MOBILE FILL (report issue #5): on narrow viewports the shared display panel is tall (min-height clamp in
   12-gameview.css) while the grid was capped at min(100%, 600px, 64vh), so the board floated in the middle
   with big empty bands. Raise the height term so the SQUARE grid can grow TALLER and fill more of that panel,
   shrinking the dead bands. We keep `100%` as the binding width cap (relative to the PADDED display, so the
   board never overflows the viewport — HARD bar: 0 horizontal overflow at 360px) and only lift the vh term.
   The panel's own min-height is shared chrome — see sharedFixesNeeded for dropping it to the grid on mobile. */
@media (max-width: 560px) { .mines-grid { width: min(100%, 92vh); } }
@media (max-width: 380px) { .mines-grid { gap: var(--sp-1); } }

.tile {
  aspect-ratio: 1 / 1;
  min-width: 44px;            /* HARD: 44px touch target */
  min-height: 44px;
  /* RESTING CONTRAST (report issue #1): a pre-round tile must read as a raised, tappable cell, not a
     barely-there rectangle on the same-colour well. The fill is brightened to a clearly-above-well
     gradient, the border lifted to --line-2 + a 1px inner highlight, and a soft outer drop so each of the
     25 tiles separates from the --surface-2 well and from its neighbours BEFORE any round starts. The grid
     should look like the game it is on first paint, even while every tile is disabled. */
  background: linear-gradient(180deg, #2b2b52, var(--surface-3));
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .08),   /* top inner highlight — reads as a raised face */
    0 1px 2px rgba(0, 0, 0, .35);             /* soft drop — lifts the tile off the well */
  font-size: clamp(18px, 5vw, 22px);
  line-height: 1;
  color: var(--fg);
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  -webkit-tap-highlight-color: transparent;
  transition:
    transform var(--dur-1) var(--ease-out),
    border-color var(--dur-2),
    background var(--dur-2),
    box-shadow var(--dur-2),
    opacity var(--dur-2);
}
/* a disabled-but-pre-round tile keeps the raised resting look so the board reads as POPULATED, not empty
   (report issue #1). The SHARED global `button:disabled { opacity:.45; box-shadow:none }` (03-layout-forms.css)
   beats the plain `.tile` rule and was halving the pre-round tiles' opacity AND stripping their elevation —
   the root cause of the "nearly invisible" pre-round board. This higher-specificity rule restores full
   opacity + the resting inner-highlight/drop so the 5×5 grid is clearly visible while every tile is disabled.
   (A RESOLVED disabled tile — .gem/.mine/.dim — is handled by the rules below, which override this.) */
.tile:disabled:not(.gem):not(.safe):not(.mine):not(.dim) {
  opacity: 1;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .08),
    0 1px 2px rgba(0, 0, 0, .35);
}
/* sheen sweep on hover (motion-gated below) */
.tile::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, transparent 35%, rgba(255, 255, 255, .06) 50%, transparent 65%);
  transform: translateX(-120%);
  transition: transform var(--dur-3) var(--ease-out);
  pointer-events: none;
}
.tile:hover { border-color: var(--brand); transform: translateY(-2px); box-shadow: var(--glow-brand); }
.tile:hover::before { transform: translateX(120%); }
.tile:active { transform: scale(.95); }
.tile:focus-visible { outline: none; box-shadow: var(--ring); border-color: var(--brand); z-index: 1; }

/* ---- PENDING: the per-reveal SUSPENSE beat — a tile is "about to flip". A held, anticipatory
   state (lift + brand glow + a slow breathing pulse) that reads as tension the instant before the
   server-resolved verdict lands. Purely presentation: it shows NO outcome (no gem/mine), so it can
   never leak which tile is safe — it's just "this tile is resolving next". Motion-gated below. ---- */
.tile.pending {
  background: linear-gradient(180deg, var(--brand-soft), var(--surface-3));
  border-color: var(--brand);
  box-shadow: 0 0 18px var(--brand-glow, var(--cyan-glow)), inset 0 0 0 1px rgba(255, 255, 255, .12);
  transform: translateY(-2px) scale(1.02);
  z-index: 1;
  animation: tile-suspense var(--dur-4) var(--ease-out) infinite alternate;
}
/* No "?" glyph on the pending tile (owner: the lift + glow + pulse already carry the suspense; the
   question mark read as clutter). The state stays outcome-free either way — nothing to leak. */
@keyframes tile-suspense {
  0%   { box-shadow: 0 0 12px var(--cyan-glow), inset 0 0 0 1px rgba(255, 255, 255, .10); }
  100% { box-shadow: 0 0 26px 3px var(--cyan-glow), inset 0 0 0 1px rgba(255, 255, 255, .22); }
}

/* ---- REVEALED: GEM (safe) — the premium payoff look ---- */
.tile.gem,
.tile.safe {                 /* .safe kept for back-compat; .gem is the live class the core adds */
  background:
    radial-gradient(80% 80% at 50% 30%, var(--win), var(--win-2)),
    linear-gradient(180deg, var(--win), var(--win-2));
  color: var(--win-ink);
  border-color: transparent;
  box-shadow: 0 0 22px var(--win-glow), inset 0 0 0 1px rgba(255, 255, 255, .25);
}
/* a faceted gem glyph with a glassy highlight */
.tile.gem::after,
.tile.safe::after {
  content: "◈";
  font-size: 1.05em;
  text-shadow: 0 0 8px rgba(255, 255, 255, .55);
}
.tile.gem::before,
.tile.safe::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(40% 30% at 35% 22%, rgba(255, 255, 255, .5), transparent 70%);
  transform: none;
  opacity: .9;
}

/* ---- REVEALED: MINE — the explosion look ---- */
.tile.mine {
  background:
    radial-gradient(70% 70% at 50% 40%, var(--lose), var(--lose-2)),
    linear-gradient(180deg, var(--lose), var(--lose-2));
  color: var(--brand-ink);
  border-color: transparent;
  box-shadow: 0 0 26px var(--lose-glow), inset 0 0 0 1px rgba(255, 255, 255, .15);
}
.tile.mine::after {
  content: "✸";
  font-size: 1.1em;
  text-shadow: 0 0 10px rgba(0, 0, 0, .5);
}

/* SKIN ART: when the active skin places gem/bomb art (the core adds .mines-skinned + the --mines-*-art vars
   on the grid), paint the art on the revealed SAFE (.gem) / MINE (.mine) tile instead of the built-in glyph.
   Falls back to the glyph automatically when the skin is classic/disabled (no .mines-skinned, higher
   specificity than the glyph rule). */
.mines-skinned .tile.gem::after,
.mines-skinned .tile.safe::after,
.mines-skinned .tile.mine::after {
  content: ""; position: absolute; inset: 10%;
  background-position: center; background-repeat: no-repeat; background-size: contain;
  font-size: 0;  /* collapse the glyph box */
  text-shadow: none;
}
.mines-skinned .tile.gem::after,
.mines-skinned .tile.safe::after { background-image: var(--mines-gem-art); filter: drop-shadow(0 0 8px var(--win-glow)); }
.mines-skinned .tile.mine::after { background-image: var(--mines-bomb-art); filter: drop-shadow(0 0 9px var(--lose-glow)); }

/* ---- DIM: never-revealed tiles fade back so the reveals pop ---- */
.tile.dim { opacity: .42; filter: saturate(.5); }

/* ---- DISABLED: a resolved tile is no longer interactive. Keep its revealed fill at full
   strength (override any UA disabled-opacity), and drop the pointer affordances + sheen so it
   reads as "locked in" rather than clickable. A dimmed unrevealed tile keeps its .dim fade. ---- */
.tile:disabled { cursor: default; }
/* a RESOLVED/DIMMED disabled tile drops the resting elevation on hover (it's locked in, not clickable);
   a PRE-ROUND disabled tile keeps its raised resting look so the idle board still reads as a board. */
.tile.gem:disabled:hover,
.tile.safe:disabled:hover,
.tile.mine:disabled:hover,
.tile.dim:disabled:hover { transform: none; box-shadow: none; border-color: transparent; }
.tile:disabled:not(.gem):not(.safe):not(.mine):not(.dim):hover { transform: none; }
.tile.gem:disabled,
.tile.safe:disabled { box-shadow: 0 0 22px var(--win-glow), inset 0 0 0 1px rgba(255, 255, 255, .25); }
.tile.mine:disabled { box-shadow: 0 0 26px var(--lose-glow), inset 0 0 0 1px rgba(255, 255, 255, .15); }
.tile:disabled::before { display: none; }   /* no hover sheen on a locked tile */

/* the reveal flip + per-state pop (motion-gated below) */
.tile.flip { animation: tile-flip var(--dur-3) var(--ease-spring) both; }
.tile.gem.flip,
.tile.safe.flip { animation: tile-flip var(--dur-3) var(--ease-spring) both, gem-pop var(--dur-4) var(--ease-out) both; }
.tile.mine.flip { animation: tile-flip var(--dur-2) var(--ease-out) both, mine-pop var(--dur-3) var(--ease-out) both; }

@keyframes tile-flip {
  0%   { transform: rotateX(90deg) scale(.85); opacity: .3; }
  100% { transform: none; opacity: 1; }
}
@keyframes gem-pop {
  0%   { box-shadow: 0 0 0 0 var(--win-glow), inset 0 0 0 1px rgba(255, 255, 255, .25); }
  60%  { box-shadow: 0 0 30px 6px var(--win-glow), inset 0 0 0 1px rgba(255, 255, 255, .4); }
  100% { box-shadow: 0 0 22px var(--win-glow), inset 0 0 0 1px rgba(255, 255, 255, .25); }
}
@keyframes mine-pop {
  0%   { transform: scale(1); box-shadow: 0 0 0 0 var(--lose-glow); }
  30%  { transform: scale(1.08); box-shadow: 0 0 34px 8px var(--lose-glow); }
  100% { transform: scale(1); box-shadow: 0 0 26px var(--lose-glow); }
}

/* =============================================================================
   Mine-count slider (the #mineCount range lives in a .seg label)
   ========================================================================== */
.panel[data-panel="mines"] .seg input[type="range"] { accent-color: var(--accent-text); }
/* the mine-count value label is owned by the gv-controls slider (.gv-slider-val) now — no #mineCountLabel. */

/* =============================================================================
   Interactive controls — the in-panel Cash Out button below the board during an
   ACTIVE round. Module-owned (created in mines.js via gv-controls actionButton).
   NOTE: the old #minesNextMult/#minesSelMult/#minesSelected/.mines-allsafe-note/
   .mines-next-clause readout block + the .mines-controls/.mines-hud* HUD block were
   removed — none of those ids/classes are produced by the current mines.js (it uses
   the gv-controls readout/actionButton with ids minesNextPay/minesSafeCount/
   minesCashout). See qa report issue #9 (dead CSS).
   ========================================================================== */
/* the Cash Out button — a green (win) payout CTA, FULL strength only while a round is ACTIVE.
   IMPORTANT: this button is MOUNTED IN THE LEFT RAIL (#gameActionSlot), NOT inside .panel[data-panel="mines"]
   — so these rules are UNSCOPED (target .mines-cashout directly). The old `.panel[data-panel="mines"]
   .mines-cashout` selectors never matched the rail-mounted button (exactly like the .mines-reveal-status note
   below); the disabled de-emphasis below relied on that, so it silently no-op'd. (The button still LOOKED
   green only because the neon-noir base `button` brand IS green — which is precisely the report's issue #2:
   two equally-green CTAs.) */
.mines-cashout {
  background: linear-gradient(180deg, var(--win), var(--win-grad-end));
  color: #00120a;
  font-weight: 800;
  min-height: 44px;
  border: 1px solid transparent;
}
.mines-cashout:hover { box-shadow: 0 0 16px var(--win-glow); }
/* ONE primary CTA at a time (report issue #2): pre-round the Cash Out button is PRESENT-BUT-DISABLED so the
   action rail stays CLS-stable — but a solid-green disabled Cash Out competed with the shared green Bet
   button as a second equally-loud CTA, so a new player couldn't tell which control starts the round. While
   disabled we drop it to a GHOST/OUTLINE (no fill, no glow, muted) so only the Bet button reads as primary
   before a round exists; the moment the round goes ACTIVE it re-enables to the full green payout CTA.
   Specificity (0,2,0) beats the shared global `button:disabled` (0,1,1) that was dimming + flattening it. */
.mines-cashout:disabled {
  background: transparent;
  color: var(--muted);
  border-color: var(--line-2);
  box-shadow: none;
  opacity: 1;            /* override the global button:disabled dimming — the outline already reads "inactive" */
}
.mines-cashout:disabled:hover { box-shadow: none; }
/* the Cash Out button is hidden via the shared .hidden class (gv-controls actionButton.show) now. */
.mines-cashout.loading { pointer-events: none; opacity: .7; }

/* =============================================================================
   Live reveal status — the running cumulative multiplier / cashout readout that
   ticks up per safe reveal during the cascade (aria-live). Module-owned (created in
   mines.js), shown only while/after a reveal. The figure is server-mirrored minesPayout
   (BigInt) — display only, never a money decision. Tabular so the number doesn't jump.
   ========================================================================== */
/* NOTE: the reveal-status element is MOUNTED IN THE LEFT RAIL (#gameActionSlot), NOT inside the mines
   .panel — so the layout-box rules below are UNSCOPED (target .mines-reveal-status directly). The old
   `.panel[data-panel="mines"] .mines-reveal-status { min-height }` reservation never matched the element,
   which is exactly why the rail collapsed when the status appeared/cleared. */
.mines-reveal-status {
  margin: var(--sp-2) 0 0;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  /* CLS-STABLE: reserve the line at its 2-LINE worst case (e.g. "Bust · 0.00× - $1,234.56 (8 safe)."
     wraps to two lines in the narrow rail). ~2.8em = 2 × the gv-status 1.4 line-height. Sized so the
     status appearing/changing/clearing never grows or collapses the action rail. */
  min-height: 2.8em;
  transition: color var(--dur-2), transform var(--dur-1) var(--ease-out);
}
/* CLS-STABLE: when there's no status text the gv-controls statusLine adds .hidden (display:none !important).
   Override it so the line stays IN FLOW (reserved height kept) but invisible — visibility:hidden, not
   display:none — so toggling the status text never collapses the rail. */
.mines-reveal-status.hidden {
  display: block !important;
  visibility: hidden;
}
/* tone colours/emphasis for the reveal status. UNSCOPED for the same reason as .mines-reveal-status above:
   the status is rail-mounted (#gameActionSlot), so the old `.panel[data-panel="mines"] .mines-reveal-status
   .is-*` selectors never matched — the intended cashout text-shadow + tick pop silently never fired (the
   plain tone colour came only from the shared `.gv-status.is-*` fallback). Unscoping restores them. The base
   colours match the shared gv-status tones; mines layers the win-glow + the tick on a cash-out. (issue #9) */
.mines-reveal-status.is-safe { color: var(--win); }
.mines-reveal-status.is-bust { color: var(--lose); }
.mines-reveal-status.is-cashout {
  color: var(--win);
  text-shadow: 0 0 12px var(--win-glow);
  animation: mines-cashout-tick var(--dur-3) var(--ease-spring) both;
}
@keyframes mines-cashout-tick {
  0%   { transform: scale(.96); opacity: .6; }
  60%  { transform: scale(1.06); }
  100% { transform: scale(1); opacity: 1; }
}

/* =============================================================================
   Reduced motion — HARD gate: no-op ALL keyframe/transition motion. The end-state
   color classes (.gem/.mine/.dim) still apply, and the core collapses the
   cascade to a single frame, so every reveal still lands — just without animation.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .tile,
  .tile.flip,
  .tile.gem.flip,
  .tile.safe.flip,
  .tile.mine.flip,
  .tile.pending,
  .mines-reveal-status,
  .mines-reveal-status.is-cashout { animation: none !important; transition: none !important; }
  .tile::before { transition: none !important; }
  .tile:hover { transform: none; }
  .tile:active { transform: none; }
  /* the pending suspense state is reduced to a static highlight (no lift/pulse) — but in reduced
     motion the core never paints a pending state at all (it reveals everything in one frame), so
     this is belt-and-braces. */
  .tile.pending { transform: none; }
}
