/* ============================================================
   BATTER UP BASEBALL — arcade stylesheet
   ------------------------------------------------------------
   Everything is drawn with CSS gradients and shapes so the game
   works with zero image files. Each drawn piece is labelled with
   an "IMAGE SWAP" comment showing which file can replace it:

     images/stadium-bg.png       -> .stadium-backdrop
     images/batter.png           -> .cartoon-batter
     images/baseball-button.png  -> .hit-button
     images/logo.png             -> .prongo-logo
     images/bat-swing-*.png      -> .animation-batter (sprite frames)

   Layout is a 16:9 stage. The shell is a CSS size container, so
   all children are sized in cqw/cqh (1cqw = 1% of stage width)
   and the whole game scales as one unit on any screen.
   ============================================================ */

:root {
  --sky-top: #6fc3f7;
  --sky-bottom: #c9ecff;
  --crowd-dark: #23355c;
  --crowd-mid: #31497c;
  --wall-green: #1d6b40;
  --wall-dark: #14522f;
  --grass-light: #46b054;
  --grass-dark: #379446;
  --dirt: #d29053;
  --dirt-dark: #b8763c;
  --navy: #14213f;
  --navy-panel: rgba(13, 25, 48, 0.88);
  --red: #e0342b;
  --red-dark: #a91f18;
  --gold: #ffd23f;
  --white: #ffffff;
  --skin: #ffcf9e;
  --font-arcade: "Arial Rounded MT Bold", "Trebuchet MS", "Segoe UI", Verdana, sans-serif;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100dvh;
  background: radial-gradient(circle at 50% 20%, #1d3358 0%, #0b1526 70%);
  font-family: var(--font-arcade);
  overflow: hidden;
}

button {
  font-family: inherit;
  cursor: pointer;
  border: none;
  background: none;
}

button:focus-visible {
  outline: 0.35cqw solid var(--gold);
  outline-offset: 0.2cqw;
}

/* ============================================================
   GAME SHELL — 16:9 stage, scales to fit the window
   ============================================================ */

.game-shell {
  position: relative;
  width: min(100vw, calc(100dvh * 16 / 9));
  aspect-ratio: 16 / 9;
  container-type: size;
  overflow: hidden;
  border-radius: clamp(0px, 1vw, 14px);
  box-shadow: 0 18px 60px rgba(0, 0, 0, 0.55);
}

.screen {
  position: absolute;
  inset: 0;
  display: none;
}

.screen.is-active {
  display: block;
}

/* ============================================================
   STADIUM BACKDROP (shared by start / play / question / game over)
   ------------------------------------------------------------
   Real art: baseball-background.webp fills the whole stage.
   The CSS-drawn fallback layers (.bg-sky/.bg-crowd/.bg-wall/
   .bg-grass/.bg-dirt) are kept in the HTML but hidden — delete
   those spans anytime, or swap the image path below to change art.
   ============================================================ */

.stadium-backdrop {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  background: url("baseball-background.webp") center / cover no-repeat;
}

/* Old CSS-drawn background layers, now replaced by the photo */
.stadium-backdrop span {
  display: none;
}

/* ============================================================
   SHARED CHROME — corner buttons, logos, labels
   ============================================================ */

.back-button {
  position: absolute;
  top: 3cqh;
  left: 1.6cqw;
  z-index: 30;
  width: 8cqh;
  height: 8cqh;
  font-size: 0;
  background: url("images/back-button.png") center / contain no-repeat;
  filter: drop-shadow(0 0.8cqh 0.7cqh rgba(9, 18, 38, 0.58));
  transition: transform 0.12s ease, filter 0.12s ease;
}

.back-button span {
  display: none;
}

.back-button:hover {
  transform: translateY(-0.3cqh);
}

.back-button:active {
  transform: translateY(0.3cqh);
  filter: drop-shadow(0 0.25cqh 0.25cqh rgba(9, 18, 38, 0.5));
}

/* Sound on/off artwork */
.sound-button {
  position: absolute;
  top: 3cqh;
  right: 1.6cqw;
  z-index: 30;
  width: 7cqh;
  height: 7cqh;
  background: url("images/sound-on.png") center / contain no-repeat;
  filter: drop-shadow(0 0.8cqh 0.7cqh rgba(9, 18, 38, 0.58));
  transition: transform 0.12s ease, filter 0.12s ease;
}

.sound-button::before {
  content: none;
}

.sound-button.is-muted {
  background-image: url("images/sound-off.png");
}

.sound-button:hover {
  transform: translateY(-0.3cqh);
}

/* Prongo.com artwork beside the sound control */
.prongo-logo {
  position: absolute;
  top: 3cqh;
  right: calc(1.6cqw + 8.5cqh);
  z-index: 30;
  width: 18cqw;
  height: 7cqh;
  font-size: 0;
  background: url("images/prongo-com-logo.png") right center / contain no-repeat;
  filter: drop-shadow(0 0.7cqh 0.65cqh rgba(9, 18, 38, 0.52));
}

.prongo-logo span {
  display: none;
}

/* "Addition" category badge */
.category-label {
  position: absolute;
  bottom: 3cqh;
  left: 50%;
  transform: translateX(-50%) rotate(-1deg);
  z-index: 30;
  padding: 1cqh 2.2cqw;
  border-radius: 3cqh;
  background: linear-gradient(var(--gold), #f5b21b);
  color: var(--navy);
  font-size: 2.8cqh;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border: 0.28cqw solid var(--navy);
  box-shadow: 0 0.5cqh 0 rgba(9, 18, 38, 0.5);
}

.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-weight: 900;
}

.is-hidden {
  display: none !important;
}

/* ============================================================
   BASEBALL (shared ball art used by title ball + result ball)
   Sprite: images/baseball.png (cut from the UI sheet)
   ============================================================ */

.big-title-ball,
.baseball,
.end-ball {
  border-radius: 50%;
  position: relative;
  background: url("images/baseball.png") center / contain no-repeat;
}

/* ============================================================
   START SCREEN
   ============================================================ */

.screen-start {
  overflow: hidden;
}

/* Giant ball glowing behind the title */
.big-title-ball {
  position: absolute;
  top: 6cqh;
  left: 50%;
  width: 52cqh;
  height: 52cqh;
  transform: translateX(-50%);
  box-shadow:
    0 0 8cqh rgba(255, 255, 255, 0.75),
    0 2.5cqh 6cqh rgba(0, 0, 0, 0.3);
  animation: title-ball-bob 4s ease-in-out infinite;
}

@keyframes title-ball-bob {
  0%, 100% { transform: translateX(-50%) translateY(0) rotate(-4deg); }
  50% { transform: translateX(-50%) translateY(-2.4cqh) rotate(4deg); }
}

/* Official Batter Up Baseball logo */
.arcade-title {
  position: absolute;
  top: 3cqh;
  left: 0;
  right: 0;
  z-index: 10;
  margin: 0;
  text-align: center;
  animation: title-pop 0.7s cubic-bezier(0.2, 1.6, 0.4, 1) both;
}

.arcade-title img {
  display: block;
  width: min(58cqw, 84cqh);
  height: auto;
  margin: 0 auto;
  filter: drop-shadow(0 1.6cqh 2.4cqh rgba(0, 0, 0, 0.45));
}

@keyframes title-pop {
  from { transform: scale(0.6); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* Home plate the Start button sits on.
   Sprite: images/home-plate.png */
.start-plate {
  position: absolute;
  left: 50%;
  bottom: 6cqh;
  width: 26cqw;
  height: 19cqh;
  transform: translateX(-50%);
  background: url("images/home-plate.png") center / 100% 100% no-repeat;
  filter: drop-shadow(0 1.4cqh 1.6cqh rgba(0, 0, 0, 0.35));
}

.primary-button {
  display: inline-block;
  padding: 2.4cqh 4cqw;
  border-radius: 4cqh;
  background: linear-gradient(#ff6b4a, var(--red) 55%, var(--red-dark));
  color: var(--white);
  font-size: 4.6cqh;
  font-weight: 900;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 0.4cqw solid var(--white);
  box-shadow:
    0 1cqh 0 var(--red-dark),
    0 1.9cqh 3cqh rgba(0, 0, 0, 0.45);
  text-shadow: 0 0.4cqh 0 rgba(0, 0, 0, 0.35);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

/* :where() keeps specificity identical to a bare :hover so the
   per-button overrides below (start, choose player, play ball)
   still win the cascade — while disabled buttons stay still. */
.primary-button:hover:where(:not(:disabled)) {
  transform: translateY(-0.4cqh) scale(1.03);
}

.primary-button:active:where(:not(:disabled)) {
  transform: translateY(0.6cqh);
  box-shadow:
    0 0.3cqh 0 var(--red-dark),
    0 0.8cqh 1.6cqh rgba(0, 0, 0, 0.45);
}

.start-button {
  position: absolute;
  left: 50%;
  bottom: 13.5cqh;
  transform: translateX(-50%);
  z-index: 10;
  width: 38cqw;
  aspect-ratio: 819 / 345;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: url("images/start-button.png") center / contain no-repeat;
  box-shadow: none;
  font-size: 0;
  filter: drop-shadow(0 1.2cqh 1.4cqh rgba(9, 18, 38, 0.5));
  animation: start-pulse 1.6s ease-in-out infinite;
}

.start-button:disabled {
  cursor: wait;
  opacity: 0.78;
  animation: none;
}

body:not(.assets-ready) .player-sprite {
  animation: none;
}

.start-button:hover {
  transform: translateX(-50%) translateY(-0.4cqh) scale(1.04);
  animation-play-state: paused;
}

.start-button:active {
  transform: translateX(-50%) translateY(0.6cqh);
  box-shadow: none;
}

@keyframes start-pulse {
  0%, 100% { scale: 1; }
  50% { scale: 1.05; }
}

/* ============================================================
   SCOREBOARDS
   ============================================================ */

/* Play-screen scoreboard strip.
   Sprite: images/board.png (wood-framed chalkboard) */
.scoreboard {
  position: absolute;
  top: 2.4cqh;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  display: flex;
  gap: 0.5cqw;
  padding: 2.2cqh 1.4cqw;
  background: url("images/board.png") center / 100% 100% no-repeat;
  filter: drop-shadow(0 1.2cqh 1.6cqh rgba(0, 0, 0, 0.45));
}

.scoreboard > div {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 10cqw;
  padding: 0.6cqh 1.4cqw;
  border-radius: 1.2cqh;
  background: rgba(0, 0, 0, 0.35);
}

.score-label {
  font-size: 1.9cqh;
  font-weight: 900;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--gold);
}

.scoreboard strong {
  font-size: 5.2cqh;
  line-height: 1.05;
  color: var(--white);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0.4cqh 0 rgba(0, 0, 0, 0.5);
}

/* Question-screen scoreboard panel.
   Sprite: images/board.png (wood-framed chalkboard) */
.question-card {
  position: absolute;
  top: 2.4cqh;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  width: 56cqw;
  padding: 2.8cqh 3cqw 3cqh;
  text-align: center;
  background: url("images/board.png") center / 100% 100% no-repeat;
  filter: drop-shadow(0 1.2cqh 1.6cqh rgba(0, 0, 0, 0.45));
}

.board-meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.8cqh;
  font-size: 2.4cqh;
  color: #bcd0f0;
  font-weight: 700;
}

.board-meta b {
  color: var(--white);
  font-size: 2.8cqh;
}

.board-meta .eyebrow {
  color: var(--gold);
  font-size: 2.2cqh;
}

/* The math problem — big scoreboard digits */
#questionText {
  font-size: 9.5cqh;
  line-height: 1.1;
  color: var(--white);
  letter-spacing: 0.06em;
  font-variant-numeric: tabular-nums;
  text-shadow:
    0 0 2.4cqh rgba(120, 190, 255, 0.6),
    0 0.6cqh 0 rgba(0, 0, 0, 0.6);
}

/* Field message under the play-screen scoreboard */
.field-message {
  position: absolute;
  top: 19cqh;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  font-size: 4.4cqh;
  font-weight: 900;
  letter-spacing: 0.06em;
  color: var(--white);
  -webkit-text-stroke: 0.22cqw var(--navy);
  paint-order: stroke fill;
  text-shadow: 0 0.6cqh 0 rgba(9, 18, 38, 0.55);
  white-space: nowrap;
}

/* ============================================================
   PLAYER SPRITE
   ------------------------------------------------------------
   One reusable batter component. The <img> inside comes from
   the PLAYERS config in script.js. Characters anchor from the
   bottom center so every mascot's feet line up, and each player
   can be nudged with --sprite-scale / --sprite-x / --sprite-y
   without touching the others.
   ============================================================ */

.player-sprite {
  position: absolute;
  z-index: 15;
  pointer-events: none;
  filter: drop-shadow(0 1.6cqh 1cqh rgba(0, 0, 0, 0.3));
  animation: batter-idle 1.9s ease-in-out infinite;
}

.player-sprite .sprite-scale {
  width: 100%;
  height: 100%;
  transform-origin: bottom center;
  transform: translate(var(--sprite-x, 0), var(--sprite-y, 0)) scale(var(--sprite-scale, 1));
}

.player-sprite .player-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
  transform-origin: bottom center;
}

.play-screen .batter {
  left: 13cqw;
  bottom: 10cqh;
  width: 18cqw;
  height: 38cqh;
}

.question-batter {
  left: 8cqw;
  bottom: 6.2cqh;
  width: 19cqw;
  height: 40cqh;
}

@keyframes batter-idle {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-0.8cqh); }
}

/* ============================================================
   HOME PLATE (large, sits under the batter / answer grid)
   ============================================================ */

/* Sprite: images/home-plate.png */
.home-plate-large {
  position: absolute;
  left: 50%;
  bottom: 4cqh;
  width: 15cqw;
  height: 13cqh;
  transform: translateX(-50%);
  background: url("images/home-plate.png") center / 100% 100% no-repeat;
  filter: drop-shadow(0 1cqh 1.4cqh rgba(0, 0, 0, 0.3));
  z-index: 5;
}

/* ============================================================
   HIT SELECTION — Single / Double / Home Run baseballs
   ------------------------------------------------------------
   IMAGE SWAP: to use ball art, replace the gradient + stitch
   pseudo-elements with
     background: url("images/baseball-button.png") center / contain no-repeat;
   ============================================================ */

.batting-controls {
  position: absolute;
  top: 30cqh;
  left: 58%;
  transform: translateX(-50%);
  z-index: 20;
  display: flex;
  gap: 4cqw;
  align-items: center;
}

.hit-button {
  position: relative;
  width: 15cqw;
  aspect-ratio: 1;
  border-radius: 50%;
  /* Sprite art: labelled baseballs from the UI sheet */
  background: url("images/ball-single.png") center / contain no-repeat;
  filter: drop-shadow(0 1.8cqh 1.4cqh rgba(0, 0, 0, 0.4));
  transition: transform 0.15s ease, filter 0.15s ease;
  animation: ball-float 3s ease-in-out infinite;
}

.hit-button.double {
  background-image: url("images/ball-double.png");
  animation-delay: 0.4s;
}

.hit-button.homerun {
  background-image: url("images/ball-homerun.png");
  animation-delay: 0.8s;
}

@keyframes ball-float {
  0%, 100% { translate: 0 0; }
  50% { translate: 0 -1.6cqh; }
}

/* The label is painted on the ball art — keep the text for screen
   readers but hide it visually */
.hit-button span {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Difficulty pill hangs under the ball */
.hit-button small {
  position: absolute;
  left: 50%;
  bottom: -1.6cqh;
  transform: translateX(-50%);
  padding: 0.25cqh 1cqw;
  border-radius: 2cqh;
  background: var(--navy);
  color: var(--gold);
  font-size: 1.7cqh;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}

.hit-button:hover {
  transform: scale(1.09) rotate(-3deg);
  animation-play-state: paused;
}

.hit-button:active {
  transform: scale(0.96);
  filter: drop-shadow(0 0.6cqh 0.8cqh rgba(0, 0, 0, 0.4));
}

/* ============================================================
   BASES PANEL (mini diamond, right side of play screen)
   ============================================================ */

.base-panel {
  position: absolute;
  right: 1.6cqw;
  bottom: 3cqh;
  z-index: 20;
  width: 17cqw;
  padding: 1.4cqh 1cqw 1.6cqh;
  border-radius: 2cqh;
  text-align: center;
  background: var(--navy-panel);
  border: 0.28cqw solid var(--gold);
  box-shadow: 0 1cqh 2cqh rgba(0, 0, 0, 0.4);
}

.base-panel h2 {
  font-size: 2.2cqh;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 1cqh;
}

.mini-diamond {
  position: relative;
  width: 12cqh;
  height: 12cqh;
  margin: 0 auto 1cqh;
}

.mini-diamond .base {
  position: absolute;
  width: 3cqh;
  height: 3cqh;
  background: #f2f4f8;
  border: 0.2cqw solid #9aa6bb;
  transform: rotate(45deg);
  transition: background 0.2s ease, box-shadow 0.2s ease;
}

.mini-diamond .second { top: 0; left: 50%; margin-left: -1.5cqh; }
.mini-diamond .third  { top: 50%; left: 0; margin-top: -1.5cqh; }
.mini-diamond .first  { top: 50%; right: 0; margin-top: -1.5cqh; }
.mini-diamond .home   { bottom: 0; left: 50%; margin-left: -1.5cqh; background: var(--gold); border-color: #c79a12; }

/* Runner dot lights up when a base is occupied */
.mini-diamond .runner-icon {
  position: absolute;
  inset: 18%;
  border-radius: 50%;
  background: var(--red);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.mini-diamond .base.has-runner {
  background: #fff3c2;
  box-shadow: 0 0 1.6cqh rgba(255, 210, 63, 0.9);
}

.mini-diamond .base.has-runner .runner-icon {
  opacity: 1;
  transform: scale(1);
}

#runnerSummary {
  font-size: 2cqh;
  color: #cfe0f7;
  font-weight: 700;
}

/* Small logotype on the play screen */
.small-title-logo {
  position: absolute;
  top: 10cqh;
  left: 1.6cqw;
  z-index: 20;
  width: 13cqw;
  transform: rotate(-4deg);
}

.small-title-logo img {
  display: block;
  width: 100%;
  height: auto;
  filter: drop-shadow(0 0.5cqh 0.7cqh rgba(0, 0, 0, 0.45));
}

/* ============================================================
   QUESTION SCREEN — 3 x 3 strike-zone answer grid
   ============================================================ */

.answer-zone {
  position: absolute;
  top: 26cqh;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.answer-zone .home-plate-large {
  position: static;
  transform: none;
  margin-top: 1.6cqh;
  width: 17cqw;
}

.answer-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1cqh;
  padding: 1.2cqh;
  border-radius: 1.6cqh;
  background: rgba(9, 18, 38, 0.35);
  border: 0.3cqw solid rgba(255, 255, 255, 0.55);
  box-shadow: 0 1.6cqh 3.2cqh rgba(0, 0, 0, 0.35);
}

/* Strike-zone squares — sprite tiles from the UI sheet:
   tile-dark (rest) / tile-gold (hover) / tile-check / tile-x */
.answer-box {
  width: 16cqh;
  height: 16cqh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: url("images/tile-dark.png") center / 100% 100% no-repeat;
  color: var(--white);
  font-size: 6cqh;
  font-weight: 900;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0.5cqh 0 rgba(0, 0, 0, 0.55);
  transition: transform 0.12s ease;
}

.answer-box:hover:not(:disabled) {
  transform: scale(1.06);
  background-image: url("images/tile-gold.png");
}

.answer-box:disabled {
  cursor: default;
}

/* The check / X art replaces the number on reveal */
.answer-box.is-correct {
  background-image: url("images/tile-check.png");
  color: transparent;
  text-shadow: none;
  animation: answer-pop 0.45s cubic-bezier(0.2, 1.6, 0.4, 1);
}

.answer-box.is-wrong {
  background-image: url("images/tile-x.png");
  color: transparent;
  text-shadow: none;
  animation: answer-shake 0.4s ease;
}

@keyframes answer-pop {
  0% { transform: scale(0.85); }
  60% { transform: scale(1.12); }
  100% { transform: scale(1); }
}

@keyframes answer-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-1cqw); }
  50% { transform: translateX(0.8cqw); }
  75% { transform: translateX(-0.5cqw); }
}

/* ============================================================
   RESULT SCREEN — the pitch / swing / ball-flight scene
   ------------------------------------------------------------
   script.js drives this with classes on .animation-stage:
     .is-pitching             ball flies pitcher -> batter (900ms)
     .is-hit.single-hit       swing + short flight
     .is-hit.double-hit       swing + flight to the wall
     .is-hit.homerun-hit      swing + ball leaves the park
     .is-miss                 pitch sails by, STRIKE stamp
   IMAGE SWAP: .animation-batter can be replaced with bat-swing
   sprite frames (images/bat-swing-1.png ... -4.png) by swapping
   background-image at the same keyframe times as swing-bat.
   ============================================================ */

.result-screen .result-layout {
  position: absolute;
  inset: 0;
}

.animation-stage {
  /* Successful pitches meet the future swing art just beyond the bat head.
     Keep this shared offset on the entire hit path so the incoming pitch,
     contact flash, and outgoing ball never jump apart. */
  --hit-contact-shift-x: 13.6cqw;
  --hit-contact-shift-y: 1cqh;
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: url("baseball-background.webp") center / cover no-repeat;
}

/* The stadium artwork replaces the old CSS-drawn crowd, lights,
   outfield wall, grass, and batter's dirt circle. */
.animation-crowd,
.stadium-lights,
.animation-fence,
.animation-grass,
.animation-mound {
  display: none;
}

.animation-stage::before {
  content: none;
}

/* ---------- Pitcher ----------
   Sprite frames from the pitcher sheet (mound baked in):
     pitcher-idle.png  set position
     pitcher-1..5.png  wind-up through follow-through           */

.animation-pitcher {
  position: absolute;
  left: 60.5cqw;
  bottom: 29.5cqh;
  width: 16cqw;
  height: 31.5cqh;
  aspect-ratio: auto;
  z-index: 6;
  filter: drop-shadow(0 1cqh 0.8cqh rgba(0, 0, 0, 0.25));
  background: url("images/pitcher-idle.png") center bottom / auto 100% no-repeat;
}

/* The spans used to draw the pitcher in CSS; sprites replace them */
.animation-pitcher span {
  display: none;
}

/* Wind-up and delivery while the pitch is coming */
.is-pitching .animation-pitcher,
.is-miss .animation-pitcher {
  animation: pitcher-frames 0.9s steps(1) both;
}

@keyframes pitcher-frames {
  0% { background-image: url("images/pitcher-1.png"); }
  22% { background-image: url("images/pitcher-2.png"); }
  42% { background-image: url("images/pitcher-3.png"); }
  62% { background-image: url("images/pitcher-4.png"); }
  82%, 100% { background-image: url("images/pitcher-5.png"); }
}

/* ---------- Batter in the scene (bigger, lower-left) ----------
   The selected player's sprite. Players with real swingFrames
   step through them in script.js; everyone else gets the CSS
   fallback swing below — always anchored at the feet so nobody
   slides out of the batter's box. */

.animation-batter {
  position: absolute;
  left: 15cqw;
  bottom: 10cqh;
  width: 22cqw;
  height: 45cqh;
  z-index: 7;
  animation: none; /* the idle bob is off during the cinematic */
}

/* Slight ready-lean while the pitch is on its way */
.is-pitching .animation-batter .player-img {
  animation: fallback-ready 0.9s ease both;
}

@keyframes fallback-ready {
  0% { transform: rotate(0deg); }
  60%, 100% { transform: rotate(-7deg) translateX(-0.6cqw); }
}

/* Fallback swing: wind back, whip through, small follow-through.
   Used whenever a player has no (or broken) swing frames. */
.animation-batter .player-img.fallback-swing {
  animation: fallback-swing 0.68s cubic-bezier(0.3, 0, 0.4, 1) both;
}

@keyframes fallback-swing {
  0% { transform: rotate(-9deg) translateX(-0.8cqw); }
  30% { transform: rotate(-13deg) translateX(-1.2cqw); }
  52% { transform: rotate(14deg) translateX(2cqw); }
  70% { transform: rotate(19deg) translateX(2.5cqw); }
  100% { transform: rotate(0deg) translateX(0); }
}

/* Fallback whiff: big cut, then a little slump */
.animation-batter .player-img.fallback-miss {
  animation: fallback-miss 1.3s ease both;
}

@keyframes fallback-miss {
  0%, 50% { transform: rotate(-9deg) translateX(-0.8cqw); }
  62% { transform: rotate(16deg) translateX(2.2cqw); }
  78% { transform: rotate(10deg) translateX(1.6cqw); }
  100% { transform: rotate(0deg) translateX(0); }
}

/* ---------- The ball ---------- */

.animation-ball {
  position: absolute;
  left: 70.5cqw;
  top: 38.5cqh;
  width: 3.6cqh;
  height: 3.6cqh;
  z-index: 8;
  box-shadow: none;
  filter: drop-shadow(0 0.5cqh 0.7cqh rgba(0, 0, 0, 0.35));
}


/* Pitch: pitcher's hand to the batter's contact point */
.is-pitching .animation-ball {
  animation: pitch-fly 0.88s cubic-bezier(0.4, 0, 0.9, 1) both;
}

@keyframes pitch-fly {
  0%   { transform: translate(0, 0) scale(0.9); }
  100% { transform: translate(calc(-48.5cqw + var(--hit-contact-shift-x)), calc(22.5cqh + var(--hit-contact-shift-y))) scale(1.15); }
}

/* Hit flights — all start from the contact point.
   Single lands mid-field, double reaches the wall,
   home run leaves the park. */
.is-hit .animation-ball {
  animation-fill-mode: both;
  animation-timing-function: linear;
}

.is-hit.single-hit .animation-ball {
  animation-name: fly-single;
  animation-duration: 1.5s;
}

@keyframes fly-single {
  0%   { transform: translate(calc(-48.5cqw + var(--hit-contact-shift-x)), calc(22.5cqh + var(--hit-contact-shift-y))); }
  22%  { transform: translate(calc(-45cqw + var(--hit-contact-shift-x)), calc(10.5cqh + var(--hit-contact-shift-y))) rotate(90deg); }
  48%  { transform: translate(calc(-32cqw + var(--hit-contact-shift-x)), calc(-6.5cqh + var(--hit-contact-shift-y))) rotate(190deg); }
  85%  { transform: translate(calc(-19cqw + var(--hit-contact-shift-x)), calc(27.5cqh + var(--hit-contact-shift-y))) rotate(340deg); }
  92%  { transform: translate(calc(-17cqw + var(--hit-contact-shift-x)), calc(23.5cqh + var(--hit-contact-shift-y))) rotate(360deg); }
  100% { transform: translate(calc(-15cqw + var(--hit-contact-shift-x)), calc(27.5cqh + var(--hit-contact-shift-y))) rotate(380deg); }
}

.is-hit.double-hit .animation-ball {
  /* Sprite: ball with a grey speed trail */
  width: 12cqh;
  height: 5cqh;
  border-radius: 0;
  background-image: url("images/ball-fly.png");
  animation-name: fly-double;
  animation-duration: 1.7s;
}

@keyframes fly-double {
  0%   { transform: translate(calc(-48.5cqw + var(--hit-contact-shift-x)), calc(22.5cqh + var(--hit-contact-shift-y))) rotate(-18deg); }
  45%  { transform: translate(calc(-23cqw + var(--hit-contact-shift-x)), calc(-10.5cqh + var(--hit-contact-shift-y))) rotate(-10deg); }
  85%  { transform: translate(calc(-2cqw + var(--hit-contact-shift-x)), calc(17.5cqh + var(--hit-contact-shift-y))) rotate(6deg); }
  100% { transform: translate(calc(1cqw + var(--hit-contact-shift-x)), calc(22.5cqh + var(--hit-contact-shift-y))) rotate(14deg); }
}

.is-hit.homerun-hit .animation-ball {
  /* Sprite: flaming fastball for the big one */
  width: 15cqh;
  height: 5.8cqh;
  border-radius: 0;
  background-image: url("images/ball-fire.png");
  animation-name: fly-homerun;
  animation-duration: 1.6s;
  /* Linear between keyframes — the arc's speed-up/slow-down comes from
     the keyframe spacing itself, so there is no mid-air re-acceleration. */
  animation-timing-function: linear;
}

@keyframes fly-homerun {
  0%   { transform: translate(calc(-48.5cqw + var(--hit-contact-shift-x)), calc(22.5cqh + var(--hit-contact-shift-y))) rotate(-32deg) scale(1); }
  25%  { transform: translate(calc(-30cqw + var(--hit-contact-shift-x)), calc(-10.5cqh + var(--hit-contact-shift-y))) rotate(-28deg) scale(0.85); }
  50%  { transform: translate(calc(-12cqw + var(--hit-contact-shift-x)), calc(-28.5cqh + var(--hit-contact-shift-y))) rotate(-24deg) scale(0.7); }
  75%  { transform: translate(calc(7cqw + var(--hit-contact-shift-x)), calc(-40.5cqh + var(--hit-contact-shift-y))) rotate(-21deg) scale(0.55); }
  100% { transform: translate(calc(27cqw + var(--hit-contact-shift-x)), calc(-46.5cqh + var(--hit-contact-shift-y))) rotate(-18deg) scale(0.4); }
}

/* Miss: the pitch sails past the batter into the corner */
.is-miss .animation-ball {
  animation: pitch-miss 1.3s cubic-bezier(0.4, 0, 0.9, 1) both;
}

@keyframes pitch-miss {
  0%   { transform: translate(0, 0) scale(0.9); opacity: 1; }
  60%  { transform: translate(-48.5cqw, 22.5cqh) scale(1.15); opacity: 1; }
  95%  { transform: translate(-60.5cqw, 36.5cqh) scale(1.2); opacity: 1; }
  100% { transform: translate(-61.5cqw, 38.5cqh) scale(1.2); opacity: 0; }
}

/* Star burst at the moment of contact.
   Sprite: images/star-hit.png */
.ball-trail {
  position: absolute;
  left: 66cqw;
  top: 30cqh;
  width: 9cqh;
  height: 9cqh;
  background: url("images/star-hit.png") center / contain no-repeat;
  opacity: 0;
  z-index: 9;
}

.is-hit .ball-trail {
  animation: star-pop 0.5s ease-out both;
}

@keyframes star-pop {
  0% { opacity: 1; transform: translate(calc(-44cqw + var(--hit-contact-shift-x)), calc(28.2cqh + var(--hit-contact-shift-y))) scale(0.3); }
  70% { opacity: 1; transform: translate(calc(-44cqw + var(--hit-contact-shift-x)), calc(28.2cqh + var(--hit-contact-shift-y))) scale(1.25); }
  100% { opacity: 0; transform: translate(calc(-44cqw + var(--hit-contact-shift-x)), calc(28.2cqh + var(--hit-contact-shift-y))) scale(1.45); }
}

/* Landing puff where a single / double touches down */
.landing-marker {
  position: absolute;
  left: 70.5cqw;
  top: 38.5cqh;
  width: 6cqh;
  height: 3cqh;
  border-radius: 50%;
  background: radial-gradient(ellipse, rgba(255, 255, 255, 0.85), transparent 70%);
  opacity: 0;
  z-index: 6;
}

.is-hit.single-hit .landing-marker {
  transform: translate(calc(-15cqw + var(--hit-contact-shift-x)), calc(27.5cqh + var(--hit-contact-shift-y)));
  animation: landing-puff 0.5s ease-out 1.35s both;
}

.is-hit.double-hit .landing-marker {
  transform: translate(calc(1cqw + var(--hit-contact-shift-x)), calc(22.5cqh + var(--hit-contact-shift-y)));
  animation: landing-puff 0.5s ease-out 1.55s both;
}

@keyframes landing-puff {
  0% { opacity: 0.9; scale: 0.4; }
  100% { opacity: 0; scale: 1.8; }
}

/* STRIKE! stamp on a miss.
   Sprite: images/badge-strike.png */
.animation-stage.is-miss::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 22cqh;
  width: 34cqh;
  height: 36cqh;
  z-index: 12;
  background: url("images/badge-strike.png") center / contain no-repeat;
  filter: drop-shadow(0 1.5cqh 2cqh rgba(0, 0, 0, 0.45));
  animation: strike-stamp 0.5s cubic-bezier(0.2, 1.6, 0.4, 1) 0.85s both;
}

@keyframes strike-stamp {
  0% { transform: translateX(-50%) scale(3); opacity: 0; }
  100% { transform: translateX(-50%) rotate(-8deg) scale(1); opacity: 1; }
}

/* Result caption panel over the scene */
.result-copy {
  position: absolute;
  left: 50%;
  bottom: 4cqh;
  transform: translateX(-50%);
  z-index: 20;
  min-width: 44cqw;
  max-width: 70cqw;
  padding: 2cqh 3cqw;
  border-radius: 2cqh;
  text-align: center;
  background: var(--navy-panel);
  border: 0.32cqw solid var(--gold);
  box-shadow: 0 1.2cqh 2.4cqh rgba(0, 0, 0, 0.45);
}

.result-copy .eyebrow {
  color: var(--gold);
  font-size: 2.4cqh;
}

#resultTitle {
  font-size: 6cqh;
  color: var(--white);
  text-shadow: 0 0.5cqh 0 rgba(0, 0, 0, 0.5);
  margin: 0.4cqh 0;
}

#resultText {
  font-size: 2.8cqh;
  color: #cfe0f7;
  font-weight: 700;
  margin-bottom: 0.6cqh;
}

.result-copy .primary-button {
  font-size: 3.2cqh;
  padding: 1.4cqh 3cqw;
  margin-top: 0.8cqh;
}

/* ============================================================
   GAME OVER SCREEN
   ============================================================ */

.game-over-card {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  z-index: 20;
  width: 56cqw;
  padding: 4cqh 3cqw;
  border-radius: 2.4cqh;
  text-align: center;
  background: var(--navy-panel);
  border: 0.4cqw solid var(--gold);
  box-shadow: 0 2cqh 4cqh rgba(0, 0, 0, 0.5);
  animation: card-drop 0.5s cubic-bezier(0.2, 1.4, 0.4, 1) both;
}

@keyframes card-drop {
  from { transform: translate(-50%, -70%); opacity: 0; }
  to { transform: translate(-50%, -50%); opacity: 1; }
}

.game-over-card .eyebrow {
  color: var(--gold);
  font-size: 2.6cqh;
}

#gameOverTitle {
  font-size: 9cqh;
  margin: 1cqh 0;
  color: var(--white);
  -webkit-text-stroke: 0.3cqw var(--navy);
  paint-order: stroke fill;
  text-shadow: 0 0.8cqh 0 rgba(0, 0, 0, 0.45);
}

.screen-game-over.win #gameOverTitle {
  color: var(--gold);
}

.screen-game-over.lose #gameOverTitle {
  color: #ff8d84;
}

#gameOverText {
  font-size: 3cqh;
  color: #cfe0f7;
  font-weight: 700;
  margin-bottom: 2cqh;
}

/* Little celebration scene above the text */
.end-scene {
  position: relative;
  height: 14cqh;
  margin-bottom: 1cqh;
}

.end-scene span {
  position: absolute;
}

.end-burst {
  left: 50%;
  top: 50%;
  width: 13cqh;
  height: 13cqh;
  transform: translate(-50%, -50%);
  background:
    conic-gradient(var(--gold) 0 10deg, transparent 10deg 30deg,
      var(--gold) 30deg 40deg, transparent 40deg 60deg,
      var(--gold) 60deg 70deg, transparent 70deg 90deg,
      var(--gold) 90deg 100deg, transparent 100deg 120deg,
      var(--gold) 120deg 130deg, transparent 130deg 150deg,
      var(--gold) 150deg 160deg, transparent 160deg 180deg,
      var(--gold) 180deg 190deg, transparent 190deg 210deg,
      var(--gold) 210deg 220deg, transparent 220deg 240deg,
      var(--gold) 240deg 250deg, transparent 250deg 270deg,
      var(--gold) 270deg 280deg, transparent 280deg 300deg,
      var(--gold) 300deg 310deg, transparent 310deg 330deg,
      var(--gold) 330deg 340deg, transparent 340deg 360deg);
  border-radius: 50%;
  opacity: 0.85;
  animation: burst-spin 6s linear infinite;
}

@keyframes burst-spin {
  to { transform: translate(-50%, -50%) rotate(360deg); }
}

.end-ball {
  left: 50%;
  top: 50%;
  width: 8cqh;
  height: 8cqh;
  transform: translate(-50%, -50%);
  z-index: 2;
}

.end-ball::before,
.end-ball::after {
  border-width: 0.3cqw;
}

.end-base {
  width: 2.6cqh;
  height: 2.6cqh;
  background: #f2f4f8;
  transform: rotate(45deg);
  top: 65%;
}

.end-base.one { left: 22%; }
.end-base.two { left: 50%; top: 8%; }
.end-base.three { right: 22%; }

/* Confetti strip — only rains on a win */
.end-confetti {
  display: none;
  left: 0;
  right: 0;
  top: -6cqh;
  height: 4cqh;
  background:
    radial-gradient(circle 0.7cqh at 10% 50%, var(--red) 0 60%, transparent 65%),
    radial-gradient(circle 0.7cqh at 30% 30%, var(--gold) 0 60%, transparent 65%),
    radial-gradient(circle 0.7cqh at 50% 60%, #3fca5f 0 60%, transparent 65%),
    radial-gradient(circle 0.7cqh at 70% 25%, #52a7ff 0 60%, transparent 65%),
    radial-gradient(circle 0.7cqh at 90% 55%, var(--red) 0 60%, transparent 65%);
  background-size: 24cqw 4cqh;
}

.screen-game-over.win .end-confetti {
  display: block;
  animation: confetti-fall 1.6s linear infinite;
}

@keyframes confetti-fall {
  from { transform: translateY(0); opacity: 1; }
  to { transform: translateY(18cqh); opacity: 0; }
}

.screen-game-over.lose .end-burst {
  opacity: 0.25;
  animation: none;
}

/* Winning shows the celebrating batter; losing shows the OUT! badge */
.screen-game-over.win .end-ball {
  width: 15cqh;
  height: 15cqh;
  border-radius: 0;
  background-image: url("images/batter-cheer.png");
}

.screen-game-over.lose .end-ball {
  width: 12cqh;
  height: 12cqh;
  border-radius: 0;
  background-image: url("images/badge-out.png");
}

/* ============================================================
   CHOOSE YOUR PLAYER — staging-room carousel
   ------------------------------------------------------------
   Background: team/baseball-stage-background.png
   Slots use pos-* classes; script.js swaps them to animate one
   smooth slide, then snaps back and rotates the images.
   ============================================================ */

.player-screen .stage-room {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: url("team/baseball-stage-background.png") center / cover no-repeat;
}

.setup-heading {
  position: absolute;
  top: 3.4cqh;
  left: 50%;
  transform: translateX(-50%);
  z-index: 20;
  margin: 0;
  font-size: 6cqh;
  font-weight: 900;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--white);
  -webkit-text-stroke: 0.3cqw var(--navy);
  paint-order: stroke fill;
  text-shadow: 0 0.7cqh 0 rgba(9, 18, 38, 0.55);
  white-space: nowrap;
}

.player-carousel {
  position: absolute;
  inset: 0;
  z-index: 10;
}

.carousel-stage {
  position: absolute;
  inset: 0;
}

.player-slot {
  position: absolute;
  transform: translateX(-50%);
  transition:
    left 0.36s ease,
    bottom 0.36s ease,
    width 0.36s ease,
    height 0.36s ease,
    opacity 0.36s ease,
    filter 0.36s ease;
}

.player-slot .sprite-scale {
  width: 100%;
  height: 100%;
  transform-origin: bottom center;
  transform: translate(var(--sprite-x, 0), var(--sprite-y, 0)) scale(var(--sprite-scale, 1));
}

.player-slot .player-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center bottom;
  transform-origin: bottom center;
}

/* The selected player: front and center on the stage floor */
.pos-center {
  left: 50%;
  bottom: 15cqh;
  width: 34cqw;
  height: 57cqh;
  opacity: 1;
  filter: brightness(1) saturate(1) drop-shadow(0 2cqh 2cqh rgba(0, 0, 0, 0.35));
  z-index: 12;
}

/* Side players: smaller, dimmer, a step up-stage — still recognizable */
.pos-left,
.pos-right {
  bottom: 24cqh;
  width: 18cqw;
  height: 34cqh;
  opacity: 0.78;
  filter: brightness(0.55) saturate(0.55);
  z-index: 8;
}

.pos-left { left: 24%; }
.pos-right { left: 76%; }

/* Off-stage targets for the slide-out animation */
.pos-out-left,
.pos-out-right {
  bottom: 30cqh;
  width: 9cqw;
  height: 18cqh;
  opacity: 0;
  filter: brightness(0.4) saturate(0.4);
  z-index: 6;
}

.pos-out-left { left: 8%; }
.pos-out-right { left: 92%; }

.carousel-stage.no-anim .player-slot {
  transition: none;
}

/* The incoming side player fades in after a slide */
.player-slot.pop-in {
  animation: slot-pop-in 0.24s ease both;
}

@keyframes slot-pop-in {
  from { opacity: 0; }
  to { opacity: 0.78; }
}

.carousel-arrow {
  position: absolute;
  top: 42cqh;
  z-index: 30;
  width: 13cqh;
  height: 13cqh;
  border-radius: 50%;
  background: var(--navy-panel);
  border: 0.4cqw solid var(--gold);
  color: var(--gold);
  font-size: 5.4cqh;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1cqh 2cqh rgba(0, 0, 0, 0.45);
  transition: transform 0.12s ease, background 0.12s ease;
}

.carousel-arrow.arrow-left { left: 3cqw; }
.carousel-arrow.arrow-right { right: 3cqw; }

.carousel-arrow:hover {
  transform: scale(1.1);
  background: rgba(30, 48, 88, 0.95);
}

.carousel-arrow:active {
  transform: scale(0.94);
}

.player-name-plate {
  position: absolute;
  left: 50%;
  bottom: 11cqh;
  transform: translateX(-50%);
  z-index: 25;
  padding: 0.7cqh 3cqw;
  border-radius: 3cqh;
  background: linear-gradient(var(--gold), #f5b21b);
  color: var(--navy);
  font-size: 3.4cqh;
  font-weight: 900;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 0.28cqw solid var(--navy);
  box-shadow: 0 0.6cqh 0 rgba(9, 18, 38, 0.5);
  white-space: nowrap;
}

.choose-player-button {
  position: absolute;
  left: 50%;
  bottom: 2.2cqh;
  transform: translateX(-50%);
  z-index: 30;
  font-size: 3.2cqh;
  padding: 1.4cqh 3.4cqw;
}

.choose-player-button:hover {
  transform: translateX(-50%) translateY(-0.4cqh) scale(1.03);
}

.choose-player-button:active {
  transform: translateX(-50%) translateY(0.6cqh);
}

/* ============================================================
   CHOOSE YOUR GRADE
   ------------------------------------------------------------
   The five finished grade buttons from assets/ are shown as-is
   (transparent PNGs, object-fit: contain). Selection adds a
   glow + scale + "Selected" tag — never a recolor of the art.
   ============================================================ */

.grade-player-preview {
  position: absolute;
  left: 4cqw;
  bottom: 6cqh;
  width: 14cqw;
  height: 34cqh;
  z-index: 15;
  text-align: center;
  pointer-events: none;
}

.grade-player-preview img {
  display: block;
  width: 100%;
  height: 28cqh;
  object-fit: contain;
  object-position: center bottom;
  filter: drop-shadow(0 1.4cqh 1cqh rgba(0, 0, 0, 0.35));
}

.grade-player-preview .preview-name {
  display: inline-block;
  margin-top: 1cqh;
  padding: 0.4cqh 1.6cqw;
  border-radius: 2.4cqh;
  background: linear-gradient(var(--gold), #f5b21b);
  color: var(--navy);
  font-size: 2.2cqh;
  font-weight: 900;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 0.22cqw solid var(--navy);
}

.grade-grid {
  position: absolute;
  top: 26cqh;
  left: 53%;
  transform: translateX(-50%);
  width: 66cqw;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4cqh 2.4cqw;
}

.grade-button {
  position: relative;
  width: 19cqw;
  aspect-ratio: 429 / 190;
  padding: 0;
  filter: drop-shadow(0 1.2cqh 1.2cqh rgba(0, 0, 0, 0.4));
  transition: transform 0.15s ease, filter 0.15s ease;
}

.grade-button img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.grade-button:hover {
  transform: scale(1.05);
}

.grade-button.is-selected {
  transform: scale(1.08);
  filter:
    drop-shadow(0 0 1.2cqh rgba(255, 210, 63, 0.95))
    drop-shadow(0 0 2.6cqh rgba(255, 210, 63, 0.65));
}

.grade-button .selected-tag {
  display: none;
  position: absolute;
  left: 50%;
  bottom: -2.4cqh;
  transform: translateX(-50%);
  padding: 0.25cqh 1.4cqw;
  border-radius: 2cqh;
  background: linear-gradient(var(--gold), #f5b21b);
  color: var(--navy);
  font-size: 1.9cqh;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border: 0.22cqw solid var(--navy);
  white-space: nowrap;
}

.grade-button.is-selected .selected-tag {
  display: block;
}

.play-ball-button {
  position: absolute;
  left: 53%;
  bottom: 14cqh;
  transform: translateX(-50%);
  z-index: 20;
  font-size: 4cqh;
}

.play-ball-button:hover:not(:disabled) {
  transform: translateX(-50%) translateY(-0.4cqh) scale(1.03);
}

.play-ball-button:active:not(:disabled) {
  transform: translateX(-50%) translateY(0.6cqh);
}

.play-ball-button:disabled {
  opacity: 0.45;
  filter: grayscale(0.6);
  cursor: not-allowed;
}

/* Longer answers (decimals, comma numbers) shrink to fit the tiles */
.answer-box.small-text {
  font-size: 4.4cqh;
}

/* Longer questions (multi-step, comma numbers) shrink on the board */
#questionText.question-long {
  font-size: 7.2cqh;
}

/* ============================================================
   COACH MODE
   ------------------------------------------------------------
   CoachSprite: one sheet (coach-sprite-sheet.png), 4 x 3 grid
   of square cells. background-size 400% 300% + a JS pose map
   is the single source of crop logic. If the sheet fails to
   load, body.coach-image-missing hides the character and the
   text hints keep working.
   ============================================================ */

.coach-sprite {
  aspect-ratio: 1 / 1;
  background-image: url("coach-sprite-sheet.png");
  background-size: 400% 300%;
  background-repeat: no-repeat;
  background-position: 0% 0%;
}

.coach-image-missing .coach-sprite {
  display: none;
}

/* ---------- Coach panel ---------- */

.coach-panel {
  position: absolute;
  right: 2cqw;
  bottom: 2.5cqh;
  z-index: 60;
  display: flex;
  align-items: flex-end;
  gap: 0.6cqw;
  max-width: 34cqw;
  animation: coach-in 0.28s ease both;
}

@keyframes coach-in {
  from { transform: translateY(3cqh); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

.coach-panel .coach-sprite {
  width: 11cqw;
  flex: 0 0 auto;
  filter: drop-shadow(0 1cqh 0.8cqh rgba(0, 0, 0, 0.35));
}

/* Keep clear of the Bases panel on the play screen */
.coach-panel[data-screen="game"] {
  right: 20cqw;
}

/* Sit above the result caption card */
.coach-panel[data-screen="result"] {
  bottom: 24cqh;
  right: 1cqw;
}

.coach-bubble {
  position: relative;
  background: var(--white);
  border: 0.32cqw solid var(--navy);
  border-radius: 2.2cqh;
  padding: 1.4cqh 1.6cqw 1.6cqh;
  box-shadow: 0 1cqh 2cqh rgba(0, 0, 0, 0.35);
  color: var(--navy);
  min-width: 16cqw;
}

/* Bubble tail pointing at the coach */
.coach-bubble::after {
  content: "";
  position: absolute;
  left: -1.4cqw;
  bottom: 3cqh;
  border: 1cqh solid transparent;
  border-right-color: var(--navy);
}

.coach-heading {
  color: var(--red);
  font-size: 1.9cqh;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin-bottom: 0.3cqh;
}

.coach-message {
  font-size: 2.4cqh;
  font-weight: 700;
  line-height: 1.25;
}

.coach-dismiss {
  position: absolute;
  top: -1.4cqh;
  right: -0.8cqw;
  width: 4.4cqh;
  height: 4.4cqh;
  border-radius: 50%;
  background: var(--red);
  color: var(--white);
  font-size: 2.8cqh;
  font-weight: 900;
  line-height: 1;
  border: 0.25cqw solid var(--white);
  box-shadow: 0 0.4cqh 0.8cqh rgba(0, 0, 0, 0.35);
}

.coach-tip-button {
  margin-top: 1cqh;
  padding: 0.9cqh 1.8cqw;
  border-radius: 2.4cqh;
  background: linear-gradient(var(--gold), #f5b21b);
  color: var(--navy);
  font-size: 2.2cqh;
  font-weight: 900;
  letter-spacing: 0.06em;
  border: 0.25cqw solid var(--navy);
  box-shadow: 0 0.5cqh 0 rgba(9, 18, 38, 0.4);
}

.coach-tip-button:hover {
  transform: translateY(-0.3cqh);
}

/* ---------- Hint visuals (number line / break apart / decimals) ---------- */

.coach-visual {
  margin-top: 1cqh;
  padding: 1cqh 1cqw;
  border-radius: 1.4cqh;
  background: #eef3fb;
  border: 0.22cqw solid #b9c8e4;
}

.hint-number-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4cqw;
}

.hint-chip {
  min-width: 4cqh;
  padding: 0.4cqh 0.6cqw;
  border-radius: 1cqh;
  background: linear-gradient(var(--gold), #f5b21b);
  border: 0.2cqw solid var(--navy);
  color: var(--navy);
  font-size: 2.4cqh;
  font-weight: 900;
  text-align: center;
}

.hint-arrow {
  color: var(--navy);
  font-size: 2.2cqh;
  font-weight: 900;
}

.hint-line {
  font-size: 2.6cqh;
  font-weight: 900;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
}

.hint-decimal {
  display: inline-block;
  text-align: right;
  font-size: 2.8cqh;
  font-weight: 900;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

.hint-decimal-bottom {
  border-bottom: 0.3cqw solid var(--navy);
  padding-bottom: 0.3cqh;
}

/* ---------- Inactivity pulse (never on a single answer) ---------- */

.pulse-guide {
  animation: guide-pulse 1.6s ease-in-out infinite;
}

@keyframes guide-pulse {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(255, 210, 63, 0)); }
  50% { filter: drop-shadow(0 0 2.2cqh rgba(255, 210, 63, 0.95)); }
}

/* ---------- Coach settings toggles (grade screen) ---------- */

.coach-settings {
  position: absolute;
  top: 14cqh;
  left: 1.6cqw;
  z-index: 25;
  display: flex;
  flex-direction: column;
  gap: 1cqh;
}

.setting-toggle {
  padding: 0.8cqh 1.4cqw;
  border-radius: 2.2cqh;
  background: var(--navy-panel);
  color: #cfe0f7;
  border: 0.25cqw solid var(--gold);
  font-size: 2cqh;
  font-weight: 800;
  text-align: left;
}

.setting-toggle[aria-pressed="true"] {
  color: var(--gold);
}

.setting-toggle:hover {
  transform: translateY(-0.2cqh);
}

/* ---------- First-game tutorial ---------- */

.tutorial-overlay {
  position: absolute;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(9, 18, 38, 0.6);
}

.tutorial-card {
  display: flex;
  align-items: center;
  gap: 1.6cqw;
  width: 62cqw;
  padding: 3cqh 2.4cqw;
  border-radius: 2.4cqh;
  background: var(--navy-panel);
  border: 0.4cqw solid var(--gold);
  box-shadow: 0 2cqh 4cqh rgba(0, 0, 0, 0.5);
}

.tutorial-coach {
  width: 14cqw;
  flex: 0 0 auto;
  filter: drop-shadow(0 1cqh 0.8cqh rgba(0, 0, 0, 0.4));
}

.tutorial-copy h2 {
  color: var(--gold);
  font-size: 4cqh;
  margin-bottom: 1cqh;
}

.tutorial-copy ol {
  margin: 0 0 1.6cqh 2.2cqw;
  color: #e6eefb;
  font-size: 2.5cqh;
  font-weight: 700;
  line-height: 1.5;
}

.tutorial-buttons {
  display: flex;
  align-items: center;
  gap: 1.6cqw;
}

.tutorial-buttons .primary-button {
  font-size: 3cqh;
  padding: 1.2cqh 3cqw;
}

/* ---------- Results card additions ---------- */

.game-over-explain {
  font-size: 2.5cqh;
  font-weight: 800;
  color: var(--gold);
  margin-bottom: 1.2cqh;
}

.results-stats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.8cqh 1.6cqw;
  margin-bottom: 1.8cqh;
}

.results-stats .stat-item {
  min-width: 9cqw;
  padding: 0.7cqh 1.2cqw;
  border-radius: 1.4cqh;
  background: rgba(255, 255, 255, 0.08);
  border: 0.2cqw solid rgba(255, 210, 63, 0.5);
}

.results-stats dt {
  font-size: 1.7cqh;
  font-weight: 900;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gold);
}

.results-stats dd {
  font-size: 2.6cqh;
  font-weight: 900;
  color: var(--white);
  margin: 0;
}

.game-over-buttons {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 1cqh 1.2cqw;
}

.game-over-buttons .primary-button {
  font-size: 3cqh;
  padding: 1.2cqh 2.6cqw;
}

.ghost-button {
  padding: 1cqh 1.8cqw;
  border-radius: 2.6cqh;
  background: rgba(255, 255, 255, 0.06);
  color: #cfe0f7;
  border: 0.28cqw solid var(--gold);
  font-size: 2.2cqh;
  font-weight: 900;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: transform 0.12s ease, background 0.12s ease;
}

.ghost-button:hover {
  transform: translateY(-0.3cqh);
  background: rgba(255, 255, 255, 0.14);
}

/* The coach joins the results card: celebrating on a win,
   supportive on a loss (replaces the old boy-cheer artwork). */
.screen-game-over.win .end-ball,
.screen-game-over.lose .end-ball {
  width: 15cqh;
  height: 15cqh;
  border-radius: 0;
  background: url("coach-sprite-sheet.png") no-repeat;
  background-size: 400% 300%;
}

.screen-game-over.win .end-ball {
  background-position: 100% 50%; /* celebrate */
}

.screen-game-over.lose .end-ball {
  background-position: 0% 0%; /* supportive neutral */
}

/* ---------- Reduced motion ---------- */

body.reduce-motion .pulse-guide {
  animation: none;
  filter: drop-shadow(0 0 1.6cqh rgba(255, 210, 63, 0.85));
}

body.reduce-motion .coach-panel {
  animation: coach-fade 0.2s ease both;
}

@keyframes coach-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

body.reduce-motion .hit-button,
body.reduce-motion .start-button,
body.reduce-motion .player-sprite,
body.reduce-motion .big-title-ball {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .pulse-guide {
    filter: drop-shadow(0 0 1.6cqh rgba(255, 210, 63, 0.85));
  }
}

/* ============================================================
   RESPONSIVE + MOTION PREFERENCES
   ------------------------------------------------------------
   The cqw/cqh sizing already scales the whole stage, so only the
   frame around it needs adjusting on small screens.
   ============================================================ */

@media (max-width: 700px) {
  .game-shell {
    border-radius: 0;
  }
}

/* On phones in portrait the 16:9 stage is a letterboxed strip;
   nudge it toward the top so it reads like a game cabinet. */
@media (orientation: portrait) {
  body {
    align-items: flex-start;
    padding-top: 6dvh;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001s !important;
  }
}
