/* ============================================================
   Whack-a-Mole 3D — fantasy storybook look.
   Deliberately NOT the Mersen slate contract tokens: the user ruled
   that kid games on this hub are bright/cartoon, and the contract doc
   is flagged for cleanup. This page keeps its OWN dark-purple/gold
   identity and does NOT take body.gk-theme — it uses the shared
   GameKit header (re-skinned below), big tap targets, t(), ?v= bumps
   and the shared mute switch, per _GAMES_CONTRACT.md.
   ============================================================ */

:root {
  --sky-top: #3fa9e8;
  --sky-mid: #9fdcff;
  --sky-bot: #ffe0a8;

  --purple: #4a2f7a;
  --purple-2: #6b3fa0;
  --purple-deep: #2a1745;
  --gold: #ffc93c;
  --gold-deep: #d8930a;
  --grass: #5fc63c;
  --grass-deep: #3c8f27;
  --danger: #ff5a5a;
  --ink: #241a33;
  --cream: #fff6e3;
  --radius: 20px;
  --font: "Baloo 2", "Trebuchet MS", "Segoe UI", system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

body.wam-body {
  font-family: var(--font);
  color: var(--ink);
  background: linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 46%, var(--sky-bot) 100%);
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
}

.app { position: relative; height: 100%; }

/* ---------------------------------------------------------------- header */
/* The ONE shared header (GameKit.header: ← back · title · 44px icon sound
   toggle), re-skinned to this page's dark-purple/gold identity. This page does
   NOT take gk-theme — the gamekit component classes are self-contained, so the
   header is styled here instead of recolouring the whole page.
   It is fixed, exactly like the old .topbar was, so the stage/HUD geometry (and
   safeArea()'s top inset) is unchanged. */
.gk-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 20;
  min-height: 58px;
  padding: 7px 12px;
  border-radius: 0;
  background: linear-gradient(180deg, rgba(42, 23, 69, .96), rgba(42, 23, 69, .82));
  border-bottom: 3px solid var(--gold);
  box-shadow: 0 4px 14px rgba(30, 14, 55, .3);
  backdrop-filter: blur(3px);
}
.gk-header .gk-back {
  min-height: 44px;
  padding: 0 13px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .14);
  border: 2px solid rgba(255, 201, 60, .55);
  color: var(--cream);
  font-size: 15px;
}
.gk-header .gk-back:active { transform: translateY(1px); }
.gk-header .gk-title {
  color: #fff;
  letter-spacing: .4px;
  text-shadow: 0 2px 0 rgba(0, 0, 0, .35);
}
.gk-header .gk-sound {
  width: 44px; height: 44px;
  background: rgba(255, 255, 255, .14);
  border: 2px solid rgba(255, 201, 60, .55);
  color: #fff;
  box-shadow: none;
}
.gk-header .gk-sound[aria-pressed="false"] {
  background: rgba(0, 0, 0, .4);
  color: #ffd9d9;
  box-shadow: inset 0 0 0 2px rgba(255, 201, 60, .35);
}

/* ---------------------------------------------------------------- stage */
.stage {
  position: fixed;
  inset: 0;
  z-index: 1;
  overflow: hidden;
}
.wam-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* soft vignette + a warm-top / cool-bottom grade on top of the 3D, storybook feel.
   No CSS filter on the canvas on purpose: a full-screen filter steals the compositing
   fast path on mid-range Android and this game has to hold 60fps there. */
.vignette {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    radial-gradient(120% 80% at 50% 42%, rgba(255, 255, 255, .10) 0%, rgba(60, 20, 90, .10) 62%, rgba(40, 12, 70, .36) 100%),
    linear-gradient(180deg, rgba(255, 196, 116, .13) 0%, rgba(255, 196, 116, 0) 24%, rgba(30, 70, 150, .12) 100%);
}

/* red pulse when a bomb is struck */
.flash {
  position: fixed;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  background: radial-gradient(120% 90% at 50% 50%, rgba(255, 70, 70, 0) 35%, rgba(255, 60, 60, .55) 100%);
  transition: opacity .09s ease-out;
}
.flash.on { opacity: 1; transition: none; }

/* ---------------------------------------------------------------- hud */
.hud {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  /* 70px = the gamekit header (61px) + clearance, so the clock never sits under it. */
  padding: 70px 10px 12px;
}

.hud-time { display: flex; justify-content: center; }

.stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  min-width: 76px;
  padding: 6px 12px;
  border-radius: 16px;
  background: linear-gradient(180deg, rgba(42, 23, 69, .84), rgba(30, 14, 55, .76));
  border: 2px solid rgba(255, 201, 60, .6);
  box-shadow: 0 4px 12px rgba(24, 10, 46, .3);
  color: #fff;
}
.stat .k {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 1.1px;
  color: var(--gold);
  text-transform: uppercase;
}
.stat .v {
  font-size: 22px;
  font-weight: 900;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.stat.time .v { font-size: 26px; }
.stat.time.low .v { color: #ffd2d2; }
.stat.time.low { border-color: rgba(255, 90, 90, .9); animation: pulse .5s ease-in-out infinite alternate; }
@keyframes pulse { from { transform: scale(1); } to { transform: scale(1.07); } }

.hud-bottom {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
}
.hud-bottom .stat { min-width: 66px; }

#hudStreak.on {
  border-color: var(--gold);
  background: linear-gradient(180deg, rgba(214, 122, 8, .92), rgba(150, 74, 4, .86));
}
#hudStreak.on .v { color: #fff6cf; }

/* ---------------------------------------------------------------- final frenzy
   The last 18 seconds have to be obvious without reading anything: the clock turns gold
   and urgent, a x2 badge locks on, and the vignette warms. */
.frenzy-badge {
  display: none;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
  padding: 6px 13px;
  border-radius: 999px;
  font-size: 17px;
  font-weight: 900;
  color: #4a2f05;
  background: linear-gradient(180deg, #ffe07a, #f5a81b);
  border: 2px solid #fff3c4;
  box-shadow: 0 0 18px rgba(255, 190, 60, .85), 0 4px 10px rgba(24, 10, 46, .35);
  animation: badgePop .5s cubic-bezier(.2, 1.4, .4, 1), glowPulse 1s ease-in-out infinite alternate;
}
body.frenzy .frenzy-badge { display: inline-flex; }
@keyframes badgePop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes glowPulse {
  from { box-shadow: 0 0 12px rgba(255, 190, 60, .6), 0 4px 10px rgba(24, 10, 46, .35); }
  to { box-shadow: 0 0 28px rgba(255, 214, 80, 1), 0 4px 10px rgba(24, 10, 46, .35); }
}

body.frenzy .stat.time {
  border-color: #fff3c4;
  background: linear-gradient(180deg, rgba(214, 122, 8, .95), rgba(150, 74, 4, .9));
  box-shadow: 0 0 22px rgba(255, 190, 60, .7);
}
body.frenzy .stat.time .k { color: #fff6cf; }
body.frenzy .stat.time .v { color: #fff; }
body.frenzy .stat.time.low { border-color: #ffe0a0; animation: pulse .42s ease-in-out infinite alternate; }
body.frenzy .vignette {
  background: radial-gradient(120% 80% at 50% 42%, rgba(255, 214, 120, .14) 0%, rgba(120, 40, 90, .10) 62%, rgba(60, 14, 60, .36) 100%);
}

.frenzy-banner {
  position: fixed;
  z-index: 14;
  left: 50%;
  top: 21%;                     /* in the sky band, clear of the far row of holes: a banner
                                   that covers a creature during the frenzy costs a hit */
  transform: translate(-50%, -50%) scale(.7);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 16px 26px;
  border-radius: 22px;
  text-align: center;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(180deg, rgba(255, 224, 122, .98), rgba(245, 168, 27, .98));
  border: 4px solid #fff6cf;
  box-shadow: 0 0 34px rgba(255, 190, 60, .9), 0 12px 26px rgba(20, 8, 40, .45);
  transition: opacity .18s ease, transform .34s cubic-bezier(.2, 1.5, .4, 1);
}
.frenzy-banner.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.frenzy-banner strong {
  font-size: 27px;
  font-weight: 900;
  letter-spacing: .5px;
  color: #4a2f05;
  text-shadow: 0 2px 0 rgba(255, 255, 255, .5);
}
.frenzy-banner span { font-size: 15px; font-weight: 800; color: #6a4506; }

/* ---------------------------------------------------------------- score pops */
.pop {
  position: fixed;
  z-index: 8;
  pointer-events: none;
  font-weight: 900;
  font-size: 27px;
  color: #fff8d6;
  text-shadow: 0 2px 0 #8a4a06, 0 0 12px rgba(255, 201, 60, .8);
  animation: popUp .85s cubic-bezier(.2, .9, .3, 1) forwards;
  transform: translate(-50%, -50%);
}
.pop.bad { color: #ffe0e0; text-shadow: 0 2px 0 #8a1414, 0 0 12px rgba(255, 90, 90, .8); }
.pop.gem { color: #fff6cf; text-shadow: 0 2px 0 #8a5f00, 0 0 14px rgba(255, 214, 60, .95); }
.pop.royal { color: #fffdf2; font-size: 32px; text-shadow: 0 2px 0 #8a5f00, 0 0 22px rgba(255, 236, 140, 1), 0 0 8px #fffdf2; }
@keyframes popUp {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.5); }
  22%  { opacity: 1; transform: translate(-50%, -78%) scale(1.18); }
  100% { opacity: 0; transform: translate(-50%, -190%) scale(.94); }
}

/* ---------------------------------------------------------------- overlay cards */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 12;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 22px 16px;
  background: radial-gradient(120% 90% at 50% 40%, rgba(40, 12, 70, .38), rgba(24, 8, 46, .74));
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity .22s ease;
}
.overlay.show { opacity: 1; pointer-events: auto; }

.card {
  width: min(520px, 100%);
  max-height: 100%;
  overflow-y: auto;
  padding: 22px 20px 20px;
  border-radius: 26px;
  text-align: center;
  background:
    linear-gradient(180deg, rgba(255, 246, 227, .98), rgba(250, 232, 198, .98));
  border: 4px solid var(--purple-2);
  box-shadow: 0 12px 0 rgba(42, 23, 69, .55), 0 22px 40px rgba(20, 8, 40, .38);
  animation: cardIn .3s cubic-bezier(.2, 1.1, .4, 1);
}
@keyframes cardIn { from { transform: translateY(16px) scale(.96); opacity: 0; } to { transform: none; opacity: 1; } }

.card h1 {
  margin: 2px 0 2px;
  font-size: 32px;
  font-weight: 900;
  letter-spacing: .5px;
  color: var(--purple);
  text-shadow: 0 2px 0 rgba(255, 255, 255, .9);
}
.card h2 { margin: 4px 0 10px; font-size: 25px; font-weight: 900; color: var(--purple); }
.card .sub { margin: 0 0 14px; font-size: 15px; font-weight: 700; color: #6b5470; }

.card .hero { font-size: 54px; line-height: 1; margin: 4px 0 6px; }

.rules {
  text-align: left;
  margin: 0 auto 16px;
  display: inline-block;
}
.rule {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 700;
  color: #4a3550;
  padding: 5px 0;
}
.rule .ico { font-size: 22px; width: 28px; text-align: center; }

.best-line {
  margin: 0 0 14px;
  font-size: 17px;
  font-weight: 900;
  color: var(--gold-deep);
}

.btn {
  display: block;
  width: 100%;
  min-height: 58px;
  margin-top: 10px;
  padding: 14px 18px;
  border: 0;
  border-radius: 18px;
  font-family: inherit;
  font-size: 20px;
  font-weight: 900;
  letter-spacing: .5px;
  color: #fff;
  cursor: pointer;
  background: linear-gradient(180deg, var(--purple-2), var(--purple));
  box-shadow: 0 6px 0 #2a1745;
  text-decoration: none;
  text-align: center;
}
.btn:active { transform: translateY(4px); box-shadow: 0 2px 0 #2a1745; }
/* PLAY / Play again — the primary action: gold, biggest, full width. */
.btn.primary {
  background: linear-gradient(180deg, #ffd75e, #f0a81b);
  color: #4a2f05;
  box-shadow: 0 6px 0 #a86c04;
  font-size: 23px;
}
.btn.primary:active { box-shadow: 0 2px 0 #a86c04; }
/* The secondary way out (← Play Hub): smaller, quieter, and NOT full width, so
   it can never compete with PLAY. Still a >=48px tap target. */
.btn.ghost {
  background: rgba(74, 47, 122, .1);
  color: var(--purple);
  box-shadow: 0 5px 0 rgba(42, 23, 69, .35);
  font-size: 18px;
}
.btn.ghost:active { box-shadow: 0 2px 0 rgba(42, 23, 69, .35); }
.btn-sm {
  width: auto;
  min-height: 48px;
  margin: 6px auto 0;
  padding: 8px 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 15px;
  letter-spacing: .3px;
  box-shadow: none;
}
.btn-sm:active { box-shadow: none; }

.score-big {
  font-size: 60px;
  font-weight: 900;
  line-height: 1;
  color: var(--purple);
  margin: 6px 0 2px;
  font-variant-numeric: tabular-nums;
}
.newbest {
  display: block;
  margin: 2px 0 8px;
  font-size: 18px;
  font-weight: 900;
  color: #e0690a;
  animation: pulse .6s ease-in-out infinite alternate;
}
.tally {
  display: flex;
  justify-content: center;
  gap: 8px;
  margin: 12px 0 6px;
  flex-wrap: wrap;
}
.tally div {
  min-width: 84px;
  padding: 8px 6px;
  border-radius: 14px;
  background: rgba(74, 47, 122, .09);
  border: 2px solid rgba(74, 47, 122, .16);
}
.tally b { display: block; font-size: 21px; color: var(--purple); }
.tally span { font-size: 11px; font-weight: 800; letter-spacing: .6px; color: #6b5470; text-transform: uppercase; }

/* ---------------------------------------------------------------- 2D fallback board */
.stage2d {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 76px 12px 92px;
  background: linear-gradient(180deg, var(--sky-top) 0%, var(--sky-mid) 48%, #7cc94f 78%, #55a834 100%);
}
.board2d {
  width: 100%;
  max-width: 430px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  transform: perspective(760px) rotateX(24deg);
  transform-style: preserve-3d;
}
.hole2d {
  position: relative;
  aspect-ratio: 1 / 1;
  border: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
}
.hole2d::after {
  content: "";
  position: absolute;
  left: 6%; right: 6%; bottom: 10%; height: 26%;
  border-radius: 50%;
  background: radial-gradient(60% 100% at 50% 40%, #1b1226 0%, #2c1a3f 70%, #3d8f2c 72%, #4fae35 100%);
  box-shadow: inset 0 4px 8px rgba(0, 0, 0, .55);
}
.mole2d {
  position: absolute;
  left: 8%; right: 8%;
  bottom: 14%;
  height: 82%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  font-size: clamp(46px, 16vw, 84px);
  line-height: 1;
  transform: translateY(112%) scale(.8);
  transform-origin: bottom center;
  transition: transform .16s cubic-bezier(.2, 1.5, .5, 1), opacity .12s;
  opacity: 0;
  filter: drop-shadow(0 5px 4px rgba(0, 0, 0, .4));
}
.mole2d.up { transform: translateY(0) scale(1); opacity: 1; }
.mole2d.hit { transform: translateY(0) scale(1.35, .45); opacity: 0; transition: transform .11s ease-out, opacity .16s ease-in; }
/* the targets must each read as different at a glance — the colours match the 3D objects:
   white ball = 10, gold-tinted ball = 20 (double), gold cup = 30 (triple), red = bomb.
   The golden ball is deliberately the SAME ⚽ glyph, tinted: "the ball, but gold" is the
   whole idea, so it must not look like a different object. */
.mole2d[data-kind="gold"] { filter: sepia(1) saturate(5.5) hue-rotate(-12deg) brightness(1.32) drop-shadow(0 0 16px rgba(255, 214, 60, .98)) drop-shadow(0 5px 4px rgba(0, 0, 0, .4)); }
.mole2d[data-kind="bomb"] { filter: drop-shadow(0 0 16px rgba(255, 80, 80, .95)) drop-shadow(0 5px 4px rgba(0, 0, 0, .4)); }
.mole2d[data-kind="royal"] { filter: drop-shadow(0 0 22px rgba(255, 246, 200, 1)) drop-shadow(0 0 8px rgba(255, 214, 60, .9)) drop-shadow(0 5px 4px rgba(0, 0, 0, .4)); }

/* ---------------------------------------------------------------- tiny screens */
@media (max-width: 380px) {
  .card h1 { font-size: 27px; }
  .stat { min-width: 66px; padding: 5px 9px; }
  .stat .v { font-size: 19px; }
  .gk-header .gk-title { font-size: 16px; }
  .rule { font-size: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .card { animation: none; }
  .pop { animation-duration: .4s; }
}

/* ================================================================
   PASS 2 — FIFA / EA-FC-style TV broadcast presentation.
   The score bug, the LIVE tag, combo pop-ups and the lower-third.
   Everything here is pointer-events:none and lives OUTSIDE the play
   band (top strip = header/sky; bottom strip = below the front row of
   holes) so it can never cover a hole or steal a tap.
   ================================================================ */

/* --- the score bug: broadcast chip styling for every stat --- */
.hud-time { gap: 8px; }

.stat {
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(12, 16, 38, .88), rgba(8, 10, 26, .82));
  border: 2px solid rgba(255, 201, 60, .55);
  box-shadow: 0 3px 10px rgba(6, 5, 20, .45), inset 0 1px 0 rgba(255, 255, 255, .12);
  position: relative;
  overflow: hidden;
}
.stat::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 3px;
  background: linear-gradient(90deg, #ffc93c, #ff7a3c, #59c8f0);
  opacity: .9;
}
.stat .k { color: #ffd76b; letter-spacing: 1.4px; }

/* LIVE chip, injected into the top clock strip by the 3D view */
.wam-live {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: 8px;
  background: linear-gradient(180deg, #e22b2b, #a20f0f);
  border: 2px solid rgba(255, 255, 255, .35);
  box-shadow: 0 3px 10px rgba(120, 0, 0, .5);
  color: #fff;
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  white-space: nowrap;
}
.wam-live .dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 8px #fff;
  animation: liveDot 1s ease-in-out infinite alternate;
}
@keyframes liveDot { from { opacity: .35; } to { opacity: 1; } }

/* --- combo pop-up (broadcast band, above the board) --- */
.wam-combo {
  position: fixed;
  z-index: 9;
  left: 50%;
  top: 132px;
  transform: translate(-50%, -50%) scale(.4) rotate(-8deg);
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 18px;
  border-radius: 14px;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(180deg, rgba(255, 201, 60, .96), rgba(233, 138, 12, .96));
  border: 3px solid #fff6cf;
  box-shadow: 0 0 22px rgba(255, 190, 60, .85), 0 8px 18px rgba(20, 8, 40, .4);
}
.wam-combo.show { animation: comboPop .9s cubic-bezier(.2, 1.5, .4, 1) forwards; }
.wam-combo b { font-size: 20px; font-weight: 900; color: #4a2f05; letter-spacing: 1px; }
.wam-combo i { font-size: 26px; font-weight: 900; font-style: normal; color: #7a1c0c; }
@keyframes comboPop {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.4) rotate(-8deg); }
  22%  { opacity: 1; transform: translate(-50%, -50%) scale(1.16) rotate(2deg); }
  55%  { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(-1deg); }
  100% { opacity: 0; transform: translate(-50%, -120%) scale(.9) rotate(0deg); }
}

/* --- the lower-third banner --- */
.wam-lower-third {
  position: fixed;
  z-index: 9;
  left: 10px;
  right: 10px;
  bottom: 92px;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  border-radius: 12px;
  pointer-events: none;
  opacity: 0;
  transform: translateY(26px);
  background: linear-gradient(90deg, rgba(12, 16, 38, .94) 0%, rgba(12, 16, 38, .80) 72%, rgba(12, 16, 38, 0) 100%);
  border-left: 6px solid #ffc93c;
  box-shadow: 0 8px 20px rgba(6, 5, 20, .45);
  transition: opacity .22s ease, transform .28s cubic-bezier(.2, 1.3, .4, 1);
}
.wam-lower-third.show { opacity: 1; transform: translateY(0); }
.wam-lower-third strong {
  font-size: 20px;
  font-weight: 900;
  letter-spacing: 1px;
  color: #fff;
  text-transform: uppercase;
  text-shadow: 0 2px 0 rgba(0, 0, 0, .4);
}
.wam-lower-third span {
  font-size: 22px;
  font-weight: 900;
  color: #ffd76b;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 380px) {
  .wam-combo { top: 122px; }
  .wam-lower-third { bottom: 88px; }
}

@media (prefers-reduced-motion: reduce) {
  .wam-live .dot { animation: none; }
  .wam-combo.show { animation-duration: .3s; }
  .wam-lower-third { transition: opacity .12s; transform: none; }
  .wam-lower-third.show { transform: none; }
}
