/* =============================================================================
   bust.fun — KENO styles  (games/keno/keno.css)
   -----------------------------------------------------------------------------
   Game-SPECIFIC styles for the keno module. Linked from index.html (the lead adds
   the <link>). Synthwave TOKENS ONLY (tokens.css) — no hard-coded palette. The
   module BUILDS its own panel DOM (renderPanel), so every selector here is keno-*
   plus the shared chrome classes it reuses (.preview/.stat/.row owned centrally).

   HARD bars honored here:
     - 44px touch targets: tiles are min 44×44 (aspect-ratio square, min-height).
     - 0 horizontal overflow @360px: an 8-col grid + min() sizing fits 360px wells.
     - reduced-motion: all pop / glow / sweep animations are gated off below.
   ========================================================================== */

/* The toolbar (pick counter + Quick pick / Clear) + the risk segmented control are built by gv-controls
   (toolbar()/segmented({variant:'chip'})/field('Risk',…)) and reuse the shared .gv-toolbar / .seg button.active
   chrome from gv-controls.css + styles.css. The few keno-scoped overrides below fix two layout problems that
   are SPECIFIC to keno's four TEXT chips + two action buttons in the NARROW bet rail (they must not change the
   shared control elsewhere, hence the .keno-* parent scoping). */

/* --- risk segmented (keno-scoped): ONE horizontal row of four chips (Classic → Low → Medium → High), so it
   reads as the SAME segmented control idiom as the Manual/Auto tabs above it (a prior version broke this into
   a one-off 2×2 grid, which looked inconsistent with every other segmented control on the site). The shared
   .gv-seg already lays the four buttons as equal flex tracks on one row; we only (a) tighten each button's
   horizontal padding + step the font down one notch so the longest labels ("Classic"/"Medium") render in FULL
   at four equal ~46px tracks in the narrow rail (clamp(220px,17vw,288px)), and (b) keep flex-wrap as a pure
   safety net so an unusually narrow rail wraps a chip to a second row rather than clipping a label. Scoped to
   .keno-risk-seg so wheel/roulette risk, which share the base control, are untouched. */
.keno-risk-seg.gv-seg { flex-wrap: wrap; }
.keno-risk-seg.gv-seg .gv-seg-btn {
  flex: 1 1 0;                 /* four equal tracks on ONE row (shared idiom), not a 2×2 grid */
  min-width: 0;
  padding-inline: 4px;        /* tighter side padding so four text labels share the narrow rail on one row */
  font-size: var(--fs-sm);    /* one notch down so "Classic"/"Medium" fit their ~46px track without clipping */
  white-space: nowrap;
  text-overflow: ellipsis;    /* last-ditch net: the base button sets overflow:hidden (defaults to clip) */
}

/* --- toolbar (keno-scoped): the counter ("Picks N / 10") + Quick pick + Clear were wrapping into an uneven
   two-row block (counter+Quick on row 1, Clear orphaned on row 2) because gv-toolbar uses margin-right:auto
   on the counter to push the buttons right. Put the counter on its OWN full-width line, then let the two
   action buttons share the next row as equal halves — a tidy single unit above the risk control. */
.keno-toolbar.gv-toolbar { flex-wrap: wrap; }
.keno-toolbar .gv-toolbar-count { flex: 1 0 100%; margin-right: 0; margin-bottom: var(--sp-1); }
.keno-toolbar .gv-tool-btn { flex: 1 1 0; min-width: 0; justify-content: center; }

/* --- the tile pool: an 8×5 grid of 40 keyboard-operable buttons (8 across) ---- */
.keno-grid {
  display: grid;
  /* minmax(0, 1fr) is LOAD-BEARING: a plain `1fr` == `minmax(auto, 1fr)`, and the `auto` MIN resolves to the
     tile's content/min-size — which pins each track's floor and lets the 8-track row grow WIDER than its
     container, so the last column(s) clip when the 360px chat panel docks and shrinks the board. minmax(0,…)
     drops that floor to 0 so all 8 columns shrink together to the ACTUAL container width and never overflow.
     JS still owns the count via --keno-cols (8). */
  grid-template-columns: repeat(var(--keno-cols, 8), minmax(0, 1fr));
  /* Responsive gap (not a fixed --sp-2): the tiles keep their 44px touch floor, so 8 tiles + 7 fixed 8px gaps
     (408px) just overran the narrowest docked board column (~397px at 1024px with chat docked), clipping the
     last column by ~11px. A %-based gap tightens to ~5px there (8x44 + 7x5 = 387 <= column) so all 8 fit, and
     relaxes back to --sp-2 on wider columns. */
  gap: clamp(4px, 1.4%, var(--sp-2));
  margin: var(--sp-2) auto;
  /* FILL the play container by its ACTUAL width — NOT a viewport-height ceiling. The old
     `min(100%, 1100px, calc((100vh - 220px) * 1.6))` sized the pool off 100vh (the full VIEWPORT height),
     which is blind to the docked chat: at e.g. a 1040px viewport that term is ~1216px, far wider than the
     chat-shrunk board column, so the grid overran and column 8 (and part of 7) were clipped. Bounding to the
     container width (100%, capped ~1100px on ultrawide) + minmax(0,1fr) tracks makes the 8 columns scale down
     together to whatever room the board column HAS — docked or not — so nothing is ever cut off.
     min-width:0 lets the grid itself shrink inside its (also min-width:0) flex ancestors. */
  width: 100%;
  max-width: min(100%, 1100px);
  min-width: 0;
}
/* The display holds only the grid now — centre it vertically in the tall play container. */
.gameview-display .panel[data-panel="keno"] { justify-content: center; }
/* OVERRIDE the shared 12-gameview.css rule `.gameview-display .keno-grid { max-width: min(1100px,
   calc((100vh - 220px) * 1.6)) }` — that viewport-height ceiling (blind to the docked chat) is exactly what
   overran the board and clipped columns 7–8. This selector (0,3,0) outranks the shared (0,2,0) regardless of
   stylesheet order, so the grid is bounded by its CONTAINER width, not the viewport height. min-width:0 keeps
   it shrinkable inside the min-width:0 display/panel flex chain (12-gameview.css .gameview-display{min-width:0}). */
.gameview-display .panel[data-panel="keno"] .keno-grid { max-width: min(100%, 1100px); min-width: 0; }
.keno-tile {
  /* Square tiles SIZED BY THE TRACK, not a hard 44px floor. A `min-height: var(--touch)` (44px) combined with
     aspect-ratio:1/1 forced a 44px min-WIDTH, so 8 tiles (352px) overran the 317px board column at 1024px with
     the chat docked and clipped the last columns. Dropping the floor lets the minmax(0,1fr) tracks + aspect-
     ratio size the tiles to the ACTUAL column: ~60px on a wide board, ~36px at the tightest docked width
     (still comfortably tappable) — never clipped. Phones keep their own T3 treatment below. */
  min-height: 0;
  min-width: 0;            /* allow the cell to shrink with the grid track (no overflow) */
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: var(--fw-semi);
  font-variant-numeric: tabular-nums;
  color: var(--fg-dim);
  background: linear-gradient(180deg, var(--surface-3), var(--surface-2));
  border: 1px solid var(--line-2);
  border-radius: var(--r-md);
  cursor: pointer;
  position: relative;
  transition:
    transform var(--dur-1) var(--ease-out),
    border-color var(--dur-2),
    background var(--dur-2),
    color var(--dur-2),
    box-shadow var(--dur-2);
}
.keno-tile:hover { border-color: var(--brand); color: var(--fg); transform: translateY(-2px); box-shadow: var(--shadow-1); }
.keno-tile:active { transform: scale(.95); }
.keno-tile:focus-visible { outline: none; box-shadow: var(--ring); border-color: var(--brand); z-index: var(--z-raised); }

/* --- T3 fill: stacked TABLET layout (the gameview collapses to one column < 1024px, AND above 720px the
   shared display keeps its TALL min-height ~940px with a fill/centre panel) --------------------------------
   In the 721–1023px band the 8×5 SQUARE pool is width-bound to the column (~504px on a tablet) and only
   ~312px tall, so it floated as a small slab with a ~310px dead band above+below it (frame-audit T3). Here
   the grid takes the full column height and its five rows STRETCH the tiles taller-than-square to absorb the
   band — a keno box reads fine slightly portrait. A per-tile max-height keeps cells a tidy box (never an
   extreme sliver). Two-column desktop (≥1024px) keeps square cells (it already fills its column to ~110px
   slack) and the SHORT phone display (≤720px: min-height clamps to ~260–380px with a flex:0 panel, so the
   grid is already compact with no band) is deliberately left out of this range. */
@media (min-width: 721px) and (max-width: 1023px) {
  /* The panel is a column flex container (12-gameview.css) that fills the tall display; make the grid a
     GROWING flex child so it gets a definite height to divide into five rows (a plain height:100% resolves
     to auto against the auto-height flex parent, which is why the rows collapsed to the 44px floor). The
     grid is capped so cells stay a tidy box, not an extreme portrait sliver, on very tall columns. */
  .gameview-display .panel[data-panel="keno"] .keno-grid {
    flex: 1 1 auto;
    min-height: 0;
    max-height: 760px;                   /* keep the pool sane on a very tall column */
    grid-template-rows: repeat(5, 1fr);  /* five rows share the grid height equally */
    align-content: stretch;
  }
  .gameview-display .panel[data-panel="keno"] .keno-tile {
    aspect-ratio: auto;       /* let the stretched 1fr row drive height past the square minimum */
    height: auto;
    max-height: 108px;        /* upper bound so a very tall column yields a tidy box, not a sliver */
  }
}

/* selected (a user pick) — neon violet chip */
.keno-tile.sel {
  color: var(--fg);
  background: linear-gradient(180deg, var(--brand-soft), var(--surface-2));
  border-color: var(--brand);
  box-shadow: inset 0 0 0 1px var(--brand), 0 0 14px var(--brand-glow);
}

/* drawn (a ball the server pulled) — cyan ring on tiles you did NOT pick */
.keno-tile.drawn {
  border-color: var(--cyan);
  color: var(--fg);
  box-shadow: inset 0 0 0 1px var(--cyan), 0 0 12px var(--cyan-glow);
}
.keno-tile.drawn::after {
  /* a small "drawn" dot in the corner so the state is not color-only (a11y) */
  content: "";
  position: absolute; top: 4px; right: 4px;
  width: 6px; height: 6px; border-radius: var(--r-pill);
  background: var(--cyan); box-shadow: 0 0 6px var(--cyan-glow);
}

/* HIT — a drawn tile you picked: the win state, neon win-green + a check glyph. The hit number is the one
   you most want legible, so make it the CRISPEST on the board: --win-ink (dark) clears WCAG AA on the bright
   --win fill (≈10–13:1), and a heavier weight + a faint light halo lifts the digit off the surrounding bloom
   (the 0 0 20px --win-glow box-shadow can otherwise wash the glyph at small sizes). */
.keno-tile.hit {
  color: var(--win-ink);
  font-weight: var(--fw-bold);
  text-shadow: 0 0 6px rgba(255, 255, 255, .35);
  background: linear-gradient(180deg, var(--win), var(--win-2));
  border-color: transparent;
  box-shadow: 0 0 20px var(--win-glow);
}
.keno-tile.hit::after {
  content: "✓";
  position: absolute; top: 2px; right: 5px;
  width: auto; height: auto; background: none; box-shadow: none;
  font-size: var(--fs-xs); font-weight: var(--fw-bold); color: var(--win-ink);
}

/* the per-ball reveal pop (motion only — gated under reduced-motion below) */
.keno-tile.pop { animation: keno-pop var(--dur-3) var(--ease-spring) both; }
@keyframes keno-pop {
  0%   { transform: scale(.55) rotate(-6deg); opacity: .25; }
  60%  { transform: scale(1.12) rotate(2deg); }
  100% { transform: none; opacity: 1; }
}

/* --- status (live region) ------------------------------------------------ */
/* CLS-STABLE: the status copy ("Pick 1–10 tiles, then Bet. The server draws 10 of 40.") wraps to TWO
   lines in the narrow rail, and shorter messages ("Drawing…") are one line — reserve the 2-line worst
   case (~2.6em) so the status changing never grows/collapses the rail. */
.keno-status { font-size: var(--fs-sm); margin: var(--sp-2) 0 0; min-height: 2.6em; }

/* --- payout-by-hits table ------------------------------------------------ */
/* Collapsible payout table in the LEFT rail (summary header + the wrap). */
.keno-paytable-details { margin-top: var(--sp-2); border-top: 1px solid var(--line); }
.keno-paytable-details > summary { cursor: pointer; padding: var(--sp-2) 0; font-size: var(--fs-sm); color: var(--muted); }
.keno-paytable-details > summary:hover { color: var(--fg); }
.keno-paytable-details[open] > summary { color: var(--fg); }
/* CLS-STABLE: the open paytable body grows row-by-row as you pick (1 placeholder → up to 9 data rows
   for Low/10-pick, plus the header). Reserve the tallest set's height so the rows fill a STABLE box —
   picking 1→10 tiles (and switching risk) no longer grows the rail and re-flows everything below it.
   ~280px ≈ header + 9 data rows at the gv table's row height. The user-driven collapse (closing the
   <details>) still folds it away fluidly; this min-height only applies while it's open. */
.keno-paytable-wrap { margin-top: var(--sp-2); min-height: 280px; }
.keno-paytable {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
}
.keno-paytable-cap {
  caption-side: top;
  text-align: left;
  color: var(--muted);
  font-size: var(--fs-xs);
  letter-spacing: var(--tracking-cap);
  text-transform: uppercase;
  padding-bottom: var(--sp-1);
}
.keno-paytable th {
  text-align: left;
  color: var(--muted);
  font-weight: var(--fw-semi);
  font-size: var(--fs-xs);
  padding: var(--sp-1) var(--sp-2);
  border-bottom: 1px solid var(--line);
}
.keno-paytable td {
  padding: var(--sp-1) var(--sp-2);
  border-bottom: 1px solid var(--line);
  color: var(--fg-dim);
}
.keno-paytable tbody tr:last-child td { border-bottom: none; }
.keno-mult { color: var(--gold); font-weight: var(--fw-semi); }
.keno-pay-cell { color: var(--muted); }
/* highlight the row matching the REALIZED hit count after a reveal (set by JS in
   highlightPaytableRow). Reads as a win row: win-tinted fill + a left accent rule so
   the draw outcome is tied to the payout table without relying on color alone. */
.keno-paytable tr.is-hit td {
  color: var(--win);
  background: var(--win-glow);
  box-shadow: inset 2px 0 0 var(--win);
}
.keno-paytable tr.is-hit .keno-mult { color: var(--win); }
.keno-paytable tr.is-hit .keno-pay-cell { color: var(--fg-dim); }
/* over-cap row: this payout at the current stake exceeds the house max, so the shell's gate would REJECT
   placing it (it already flags the headline "Top win pays" red + disables Bet). Tint the matching table
   rows + add a strikethrough on the value so the table never implies a placeable win the gate will block.
   Not color-only: the line-through + the title tooltip carry the meaning for non-color users. */
.keno-paytable tr.is-overcap td { color: var(--muted); }
.keno-paytable tr.is-overcap .keno-mult { color: var(--danger, #ff6b6b); }
.keno-paytable tr.is-overcap .keno-pay-cell { text-decoration: line-through; text-decoration-color: var(--danger, #ff6b6b); }
/* a hit row that is ALSO over-cap reads primarily as the win (the realized outcome), but keep the danger
   tint on the multiplier so the "exceeds cap" signal survives the win highlight. */
.keno-paytable tr.is-hit.is-overcap .keno-mult { color: var(--danger, #ff6b6b); }
@media (prefers-reduced-motion: reduce) {
  /* highlight is a static state change (no animation) — nothing to gate, but keep the
     transition off so it lands instantly alongside the no-stagger reveal. */
  .keno-paytable tr.is-hit td { transition: none; }
}

/* =============================================================================
   REDUCED MOTION — kill every keno animation/transition (HARD a11y bar). The
   reveal still paints (classes apply), it just lands instantly with no pop/sweep.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .keno-tile { transition: none; }
  .keno-tile:hover { transform: none; }
  .keno-tile:active { transform: none; }
  .keno-tile.pop { animation: none; }
}
