/* =============================================================================
   bust.fun — HI-LO styles  (games/hilo)  — OWNER A
   -----------------------------------------------------------------------------
   Game-specific styles for the Hi-Lo card game. Linked from index.html (the lead
   adds the <link>). Synthwave tokens only (tokens.css) — no hard-coded palette.
   The card flip is the centerpiece: a crisp 3D rotateY reveal with suit/rank
   styling, win glow / loss dim, and a streak build. a11y bars: 44px touch targets,
   0 horizontal overflow @360px, and ALL motion is no-op'd under reduced-motion.
   ========================================================================== */

/* FILL: the module root claims the full height of the display column so the felt
   stage can grow tall and the card fills it. min-height:0 lets the flex child shrink
   on short screens without overflowing. */
.hilo { display: flex; flex-direction: column; gap: var(--sp-3); margin: 0; flex: 1; min-height: 0; }

/* ---------------------------------------------------------------------------
   Stage — the felt where the card sits, with a faint deck behind it.
   FILL: the stage is the hero — it grows to consume the column's spare height and
   centers the (now large) card inside it.
   --------------------------------------------------------------------------- */
.hilo-stage {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--sp-3);
  flex: 1; min-height: 0;
  padding: var(--sp-5) var(--sp-3);
  border-radius: var(--r-lg); border: 1px solid var(--line-2);
  background:
    radial-gradient(120% 90% at 50% 0%, var(--brand-soft), transparent 60%),
    linear-gradient(180deg, var(--surface-2), var(--bg-1));
  position: relative; overflow: hidden;
}
/* faint synthwave grid wash on the felt (decorative; below the card) */
.hilo-stage::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; opacity: .5;
  background-image:
    linear-gradient(var(--grid-color) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-color) 1px, transparent 1px);
  background-size: var(--grid-size) var(--grid-size);
  mask-image: radial-gradient(80% 80% at 50% 35%, #000, transparent 75%);
}

/* FILL: the card is the centerpiece — size it by HEIGHT off the viewport (capped on
   big screens, floored so it never gets tiny) and derive the width from the 132:188
   playing-card ratio (≈0.702). --hilo-card-h drives every inner glyph so the whole
   card scales as one unit. */
.hilo-card-wrap {
  position: relative;
  --hilo-card-h: min(42vh, 460px);
  --hilo-card-w: calc(var(--hilo-card-h) * 132 / 188);
  width: var(--hilo-card-w); height: var(--hilo-card-h);
}

/* the faint "deck" stack behind the live card */
.hilo-deck {
  position: absolute; inset: 0; border-radius: var(--r-md);
  background: linear-gradient(160deg, var(--surface-4), var(--surface-3));
  border: 1px solid var(--line-2);
  transform: translate(8px, 8px) rotate(3deg); opacity: .55;
  box-shadow: var(--shadow-1);
}

/* ---------------------------------------------------------------------------
   The card — 3D flip via preserve-3d + rotateY on the inner element.
   --------------------------------------------------------------------------- */
.hilo-card {
  position: relative; width: var(--hilo-card-w, 132px); height: var(--hilo-card-h, 188px); z-index: 1;
  perspective: 900px; border-radius: var(--r-md);
}
.hilo-card-inner {
  position: relative; width: 100%; height: 100%;
  transform-style: preserve-3d;
  transition: transform var(--dur-3) var(--ease-in-out);
  will-change: transform;
}
/* flipping: rotate a half-turn; the face swap happens at the midpoint (JS) */
.hilo-card.flipping .hilo-card-inner { transform: rotateY(180deg); }

.hilo-face {
  position: absolute; inset: 0; backface-visibility: hidden; -webkit-backface-visibility: hidden;
  border-radius: var(--r-md); border: 1px solid var(--line-2);
  display: flex; align-items: center; justify-content: center;
  box-shadow: var(--shadow-2);
}
.hilo-face-front {
  background: linear-gradient(165deg, #f6f7fb, #dfe3ee);
  color: #1b2030;
}
.hilo-face-back {
  background:
    repeating-linear-gradient(45deg, var(--brand-soft) 0 8px, transparent 8px 16px),
    linear-gradient(160deg, var(--brand), var(--brand-2));
  color: var(--brand-ink); transform: rotateY(180deg);
  border-color: var(--line-3);
}
/* Back face is a NEUTRAL brand mark ("B"), NOT the word "bust" — the flip rotates THROUGH this back
   face on EVERY guess (wins included), so it must never read as a loss verdict. */
.hilo-back-mark {
  font-family: var(--font-display); font-weight: var(--fw-bold);
  /* scale with the card height (≈22% of card height for a single glyph), floored/capped for legibility */
  font-size: clamp(40px, calc(var(--hilo-card-h, 188px) * 0.22), 110px);
  letter-spacing: var(--tracking-cap); opacity: .9; text-transform: uppercase;
  text-shadow: var(--neon-glow-text);
}

/* ---------------------------------------------------------------------------
   Pre-round face-down cover — a deck back over the (blank) front so a resting card reads as
   "a card to deal", not an empty white rectangle. JS toggles .is-facedown on the .hilo-card:
   ON pre-round / terminal-cleared, OFF on Deal + during a live round. Below the 3D inner so the
   flip never has to fight it; sits flat on top of the front face.
   --------------------------------------------------------------------------- */
.hilo-card-cover {
  position: absolute; inset: 0; z-index: 2; border-radius: var(--r-md);
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line-3);
  background:
    repeating-linear-gradient(45deg, var(--brand-soft) 0 8px, transparent 8px 16px),
    linear-gradient(160deg, var(--brand), var(--brand-2));
  box-shadow: var(--shadow-2);
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity var(--dur-2, .2s) var(--ease-out, ease);
}
.hilo-card.is-facedown .hilo-card-cover { opacity: 1; visibility: visible; }
.hilo-cover-mark {
  font-family: var(--font-display); font-weight: var(--fw-bold);
  font-size: clamp(40px, calc(var(--hilo-card-h, 188px) * 0.26), 120px);
  color: var(--brand-ink); opacity: .8; text-shadow: var(--neon-glow-text);
}

/* red suits (hearts / diamonds) recolor the front face glyphs */
.hilo-card.red .hilo-face-front { color: var(--accent-2); }

/* center pip + corner rank/suit — all sized off the card height so they grow with the
   (now large) card and keep their proportions. */
.hilo-pip { font-size: clamp(54px, calc(var(--hilo-card-h, 188px) * 0.29), 150px); line-height: 1; }
.hilo-corner {
  position: absolute; display: flex; flex-direction: column; align-items: center;
  font-weight: var(--fw-bold); line-height: 1;
}
.hilo-corner .hl-r { font-size: clamp(19px, calc(var(--hilo-card-h, 188px) * 0.10), 52px); font-family: var(--font-display); }
.hilo-corner .hl-s { font-size: clamp(15px, calc(var(--hilo-card-h, 188px) * 0.08), 42px); }
.hilo-corner.tl { top: calc(var(--hilo-card-h, 188px) * 0.043); left: calc(var(--hilo-card-h, 188px) * 0.048); }
.hilo-corner.br { bottom: calc(var(--hilo-card-h, 188px) * 0.043); right: calc(var(--hilo-card-h, 188px) * 0.048); transform: rotate(180deg); }

/* win glow / loss dim on the settled card */
.hilo-card.won .hilo-face-front {
  border-color: var(--win); box-shadow: 0 0 26px var(--win-glow), var(--shadow-2);
}
.hilo-card.lost .hilo-face-front { filter: saturate(.55) brightness(.82); }

/* ---------------------------------------------------------------------------
   Readout under the card
   --------------------------------------------------------------------------- */
.hilo-readout { display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; }
.hilo-current-label { font-size: var(--fs-xs); letter-spacing: var(--tracking-cap); text-transform: uppercase; color: var(--muted); }
.hilo-current-name { font-size: var(--fs-md); font-weight: var(--fw-semi); color: var(--fg); }
/* CLS FIX — the streak line used to toggle display:none→shown at streak>=2, inserting a
   ~18px line that pushed the picks down. It now stays ALWAYS in flow: a reserved min-height
   (one --fs-sm line) holds the space, and .is-empty just makes it invisible (not removed) so
   it fades in on the streak rather than shifting the layout. */
.hilo-streak {
  margin-top: 2px; font-size: var(--fs-sm); font-weight: var(--fw-bold); color: var(--gold);
  text-shadow: 0 0 10px var(--gold-glow);
  min-height: var(--fs-sm); line-height: 1;
  transition: opacity var(--dur-2, .2s) var(--ease-out, ease);
}
.hilo-streak.is-empty { visibility: hidden; opacity: 0; }

/* ---------------------------------------------------------------------------
   Pick buttons — Higher / Lower, each with its multiplier + win chance.
   44px+ touch targets; full-width split that never overflows at 360px.
   --------------------------------------------------------------------------- */
.hilo-picks { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-3); }
.hilo-pick {
  display: flex; flex-direction: column; gap: var(--sp-1);
  min-height: 64px; padding: var(--sp-3); cursor: pointer;
  border-radius: var(--r-md); border: 1px solid var(--line-2);
  background: linear-gradient(180deg, var(--surface-3), var(--surface-2));
  color: var(--fg); text-align: left;
  transition: transform var(--dur-1) var(--ease-out), border-color var(--dur-2), box-shadow var(--dur-2), background var(--dur-2);
}
.hilo-pick:hover { transform: translateY(-2px); border-color: var(--line-3); box-shadow: var(--shadow-1); }
.hilo-pick:active { transform: scale(.98); }
.hilo-pick:focus-visible { outline: none; box-shadow: var(--ring); }

.hilo-pick-top { display: flex; align-items: center; gap: var(--sp-2); }
.hilo-pick-arrow { color: var(--win); font-size: 14px; }
.hilo-pick-arrow.down { color: var(--accent-text); }
.hilo-pick-name { font-family: var(--font-display); font-weight: var(--fw-bold); font-size: var(--fs-md); }
/* sub-label: ALWAYS one line. The text varies by state ("Same or higher" / "Ace lowest - skip free" /
   "odds show on deal"); clamping to a single line with ellipsis guarantees the button height never grows
   from a wrap on a narrow (≤360px) split, so the picks row — and the controls below it — never shift. */
.hilo-pick-sub {
  font-size: var(--fs-xs); color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
/* The live risk/reward line — payout multiplier + win chance read as ONE inline unit
   ("1.07×  ·  92%"). The two figures sit on a shared baseline; a token-only "·" separator
   (pseudo-element, no markup) ties them together. CLS: the row height is governed by the
   larger --fs-lg multiplier, so the chance / separator (both ≤ --fs-sm) never change row
   height across the bet / skip ("always wins") / pre-round ("-") states. */
.hilo-pick-stats { display: flex; align-items: baseline; justify-content: flex-start; gap: var(--sp-2); margin-top: 2px; }
.hilo-pick-mult { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--fg); font-variant-numeric: tabular-nums; }
.hilo-pick-chance {
  font-size: var(--fs-sm); color: var(--fg-dim); font-variant-numeric: tabular-nums;
  display: inline-flex; align-items: baseline; gap: var(--sp-2);
}
/* "·" separator between the multiplier and the chance — decorative, token color only. Suppressed in the
   pre-round empty state (chance textContent ''), so a dealt-yet board never reads "- · -". */
.hilo-pick-chance::before { content: "·"; color: var(--muted); font-weight: var(--fw-bold); }
.hilo-pick-chance:empty::before { content: none; }

/* below-even: this pick pays under 1.00× (guaranteed net loss from the edge). Mute the
   multiplier so it reads as a poor bet — honest, not alarmist. Display only. */
.hilo-pick.below-even .hilo-pick-mult { color: var(--muted); }

/* is-skip: the GUARANTEED side of an extreme card (Ace→higher / King→lower) is a guaranteed win at <= 1.00×
   — no edge to bet, so it's a FREE SKIP (Stake/Roobet parity), not a 0.99× loss bet. Render it as a ghost/
   dashed Skip affordance so it never reads as a real wager. Clicking it routes to /skip. Display only. */
.hilo-pick.is-skip {
  border-style: dashed; border-color: var(--line-2);
  background: linear-gradient(180deg, var(--surface-2), var(--surface-1));
}
.hilo-pick.is-skip:hover { border-color: var(--line-3); box-shadow: none; transform: translateY(-1px); }
.hilo-pick.is-skip .hilo-pick-mult { color: var(--muted); font-size: var(--fs-md); }
.hilo-pick.is-skip .hilo-pick-name::after { content: ' · skip'; color: var(--muted); font-weight: var(--fw-regular); }

/* active (selected) pick — neon-rimmed */
.hilo-pick.active[data-pick="higher"] {
  border-color: var(--win); background: linear-gradient(180deg, var(--win-soft), var(--surface-2));
  box-shadow: inset 0 0 0 1px var(--win), 0 0 18px var(--win-glow);
}
.hilo-pick.active[data-pick="lower"] {
  border-color: var(--accent-text); background: linear-gradient(180deg, var(--accent-soft), var(--surface-2));
  box-shadow: inset 0 0 0 1px var(--accent), 0 0 18px var(--accent-glow);
}

/* a disabled (over-cap or in-flight) call button reads as unavailable */
.hilo-pick:disabled { opacity: .5; cursor: not-allowed; }
.hilo-pick:disabled:hover { transform: none; border-color: var(--line-2); box-shadow: none; }

/* ---------------------------------------------------------------------------
   STREAK controls — the in-panel Cash Out button (module-owned, never shared chrome)
   --------------------------------------------------------------------------- */
.hilo-controls { display: flex; justify-content: center; gap: var(--sp-3); flex-wrap: wrap; }
.hilo-cashout { min-height: 44px; min-width: 60%; }
.hilo-cashout.loading { opacity: .7; pointer-events: none; }

/* Mobile-only Cash Out mirror — co-located with the Higher/Lower picks so a streak player isn't
   scrolling ~1.5 viewports down to the action-rail Cash Out on every call. Hidden on desktop (the
   rail button is in view there); shown only on phones below. Mirrors the rail button's win-green CTA. */
.hilo-cashout-mobile {
  display: none; min-height: 44px; flex: 1; min-width: 60%;
  background: linear-gradient(180deg, var(--win), #169a52); color: #06210f;
  border: 1px solid var(--win); font-weight: var(--fw-bold);
}
.hilo-cashout-mobile:hover { filter: brightness(1.06); }
.hilo-cashout-mobile.loading { opacity: .7; pointer-events: none; }
.hilo-cashout-mobile[hidden] { display: none; }

/* ---------------------------------------------------------------------------
   Visible round-result chip — mirrors the sr-only #hiloVerdict so sighted players SEE the
   outcome (multiplier + payout), not just confetti. win = green, loss = red. Appears under
   the card readout, ABOVE the Higher/Lower pick buttons (.hilo-picks).
   CLS FIX (baccarat/roulette reserve pattern): #hiloResult sits IN FLOW in .hilo-stage, between
   the card readout and .hilo-picks. It used to toggle display:none (.is-hidden) ↔ flex, so every
   round it APPEARED and shoved the Higher/Lower buttons DOWN ~48px (then the next round hid it and
   they jumped back UP) — the pick buttons moved under the player's cursor between rounds. Now we
   PRE-ALLOCATE a fixed slot (min-height = the 2-line head+pay content) and keep the box IN FLOW
   when hidden via `visibility:hidden` (override below) — the pick buttons never move across
   idle → guess → result → idle.
   --------------------------------------------------------------------------- */
.hilo-result {
  box-sizing: border-box; min-height: 48px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; text-align: center;
  padding: var(--sp-2) var(--sp-4); margin-top: var(--sp-1);
  border-radius: var(--r-md); border: 1px solid var(--line-2);
  background: linear-gradient(180deg, var(--surface-3), var(--surface-2));
  animation: hilo-result-in var(--dur-2, .2s) var(--ease-out, ease);
}
/* hidden = reserved-but-invisible: keep the box (and its reserved min-height) IN FLOW so the pick
   buttons below never shift, but make it fully invisible + inert. `visibility:hidden` hides the
   tint/border/text and removes it from the a11y tree (matching the old display:none + aria-hidden). */
.hilo-result.is-hidden { visibility: hidden; pointer-events: none; animation: none; }
.hilo-result-head {
  font-family: var(--font-display); font-weight: var(--fw-bold);
  font-size: var(--fs-sm); letter-spacing: var(--tracking-cap); text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
.hilo-result-pay { font-size: var(--fs-lg); font-weight: var(--fw-bold); color: var(--fg); font-variant-numeric: tabular-nums; }
.hilo-result.is-win {
  border-color: var(--win); background: linear-gradient(180deg, var(--win-soft), var(--surface-2));
}
.hilo-result.is-win .hilo-result-head { color: var(--win); text-shadow: 0 0 12px var(--win-glow); }
.hilo-result.is-loss {
  border-color: var(--lose); background: linear-gradient(180deg, rgba(244, 63, 94, .1), var(--surface-2));
}
.hilo-result.is-loss .hilo-result-head { color: var(--lose); }
.hilo-result.is-loss .hilo-result-pay { color: var(--muted); }
@keyframes hilo-result-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* ---------------------------------------------------------------------------
   Phones — the action rail (with the primary Cash Out) stacks BELOW the board (12-gameview.css
   @760px), so reveal the board-level Cash Out mirror co-located with the picks. Desktop keeps it
   hidden (the rail button is in view there). JS still toggles its [hidden] per round state.
   --------------------------------------------------------------------------- */
@media (max-width: 760px) {
  .hilo-cashout-mobile { display: inline-flex; align-items: center; justify-content: center; }
  .hilo-cashout-mobile[hidden] { display: none; }
}

/* ---------------------------------------------------------------------------
   Narrow screens — keep 0 horizontal overflow at 360px.
   --------------------------------------------------------------------------- */
@media (max-width: 380px) {
  /* on phones the column is shorter and the card competes with the picks/cashbar below —
     cap the card height a touch lower so the whole panel still fits with no page scroll.
     Width + every glyph follow --hilo-card-h automatically. */
  .hilo-card-wrap { --hilo-card-h: min(46vh, 320px); }
  .hilo-stage { padding: var(--sp-4) var(--sp-2); }
}

/* ---------------------------------------------------------------------------
   Reduced motion — no flip, no float; the reveal is instant + legible.
   (JS also branches on reducedMotion; this is the CSS belt-and-braces.)
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .hilo-card-inner { transition: none !important; }
  .hilo-card.flipping .hilo-card-inner { transform: none !important; }
  .hilo-pick { transition: none !important; }
  .hilo-pick:hover, .hilo-pick:active { transform: none !important; }
  .hilo-streak { transition: none !important; }
}
