body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  background: #0f3d1e;
  font-family: system-ui, sans-serif;
  color: #f5f5f5;
}

/* Applied while a delivery is bowling/in-flight so a swipe aimed at the ground can't scroll the
   page instead. `position: fixed` (not just overflow: hidden) is needed to stop iOS Safari's
   rubber-band scroll; scrollY is saved/restored across the lock in JS via the --scroll-lock-y var. */
body.scroll-locked {
  position: fixed;
  top: calc(-1 * var(--scroll-lock-y, 0px));
  left: 0;
  right: 0;
  overflow: hidden;
}

.app {
  text-align: center;
  width: 600px;
  max-width: 94vw;
  padding-bottom: 9.5rem; /* clearance so content isn't hidden behind the fixed D-pad swing bar (taller than the old single-row bar) */
}

h1 {
  margin: 0 0 0.15rem;
  font-size: 1.5rem;
}

.best-score {
  margin: 0 0 0.2rem;
  font-size: 0.85rem;
  color: #ffd54f;
  font-weight: bold;
}

.difficulty-screen {
  background: #124a26;
  border-radius: 10px;
  padding: 1.5rem 1.25rem;
  margin-top: 1rem;
}

.difficulty-screen-subtitle {
  margin: 0 0 0.75rem;
  font-size: 1rem;
  color: #9fd8ac;
}

.begin-btn {
  margin-top: 0.75rem;
  padding: 0.7rem 1.75rem;
  font-size: 1.05rem;
  border: none;
  border-radius: 6px;
  background: #4caf50;
  color: white;
  cursor: pointer;
}

.begin-btn:hover {
  background: #43a047;
}

.difficulty-selector,
.mode-selector {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0.5rem 0 0.75rem;
}

.difficulty-btn,
.mode-btn {
  padding: 0.35rem 0.75rem;
  font-size: 0.8rem;
  border: 1px solid #3a3a52;
  border-radius: 6px;
  background: #2c2c3e;
  color: #ccc;
  cursor: pointer;
}

.difficulty-btn:hover:not(:disabled),
.mode-btn:hover:not(:disabled) {
  background: #3a3a52;
}

.difficulty-btn.active,
.mode-btn.active {
  background: #3d6fd8;
  border-color: #3d6fd8;
  color: white;
}

.stats {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  row-gap: 0.3rem;
  background: #124a26;
  border-radius: 8px;
  padding: 0.4rem 1.25rem;
  margin-bottom: 0.3rem;
  position: sticky;
  top: 0;
  z-index: 15;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.35);
}

.stats > div {
  display: flex;
  flex-direction: column;
}

.label {
  font-size: 0.7rem;
  color: #9fd8ac;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.stats span:last-child {
  font-size: 1.3rem;
  font-weight: bold;
}

.directions {
  display: flex;
  flex-direction: column;
  align-items: center;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 20;
  padding: 0.3rem 0.5rem;
  padding-bottom: calc(0.3rem + env(safe-area-inset-bottom));
  background: #0f3d1e;
  box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.35);
}

/* Ball-flow actions (Start/Next Ball, and the contextual Replay/Skip buttons) live in the fixed
   bottom bar alongside the D-pad, not in the scrollable .controls block below the ground — this is
   the one area guaranteed to stay on screen without scrolling, and it's exactly what you need to
   reach every single ball. */
.ball-actions {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 5px;
  width: min(360px, 94vw);
  margin-bottom: 5px;
}

.ball-actions button {
  padding: 0.35rem 0.7rem;
  font-size: 0.85rem;
}

/* D-pad: 3x3 plus/cross. DOM order is row-major, so buttons read:
   On Drive | Straight Drive | Cover Drive  /  Pull Shot | Any | Square Drive  /
   Leg Glance | Third Man | Square Cut — mirroring the arrow-key layout (↑ top, ↓ bottom, corners = combos). */
.dpad {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 5px;
  width: min(360px, 94vw);
}

.dir-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 2.3rem;
  padding: 0.2rem 0.2rem;
  font-size: 0.72rem;
  line-height: 1.05;
  text-align: center;
  border: 1px solid #3a3a52;
  border-radius: 6px;
  background: #2c2c3e;
  color: #ccc;
  cursor: pointer;
}

.dir-btn:not(:disabled) {
  background: #d84545;
  border-color: #d84545;
  color: white;
}

.dir-btn:not(:disabled):hover {
  background: #c93a3a;
}

/* Diagonal (combo) buttons: a slightly deeper red so they read as a distinct tier from the cardinals. */
.dir-diag:not(:disabled) {
  background: #b23c3c;
  border-color: #b23c3c;
}

.dir-diag:not(:disabled):hover {
  background: #a03434;
}

/* 'Defend' is not an attacking shot — colour it distinctly (blue) so it never reads as a direction. */
.dir-defend:not(:disabled) {
  background: #3d6fd8;
  border-color: #3d6fd8;
}

.dir-defend:not(:disabled):hover {
  background: #345fc0;
}

/* Highlighted while a combo window is open, on the two diagonals the first press could still become. */
.dir-btn.combo-candidate {
  box-shadow: 0 0 0 2px #ffd54f inset;
  border-color: #ffd54f;
}

.key-hint {
  font-size: 0.6rem;
  opacity: 0.75;
  margin-top: 1px;
}

.bowler-type {
  min-height: 1.1rem;
  font-size: 0.85rem;
  color: #ffcc80;
  margin: 0 0 0.15rem;
}

.powerplay-tag {
  display: inline-block;
  margin: 0 0 0.15rem;
  padding: 0.15rem 0.6rem;
  font-size: 0.75rem;
  font-weight: bold;
  letter-spacing: 0.05em;
  color: #1a1a1a;
  background: #ffb300;
  border-radius: 12px;
}

.powerplay-tag.hidden {
  display: none;
}

.replay-tag {
  display: inline-block;
  margin: 0 0 0.15rem;
  padding: 0.15rem 0.6rem;
  font-size: 0.75rem;
  font-weight: bold;
  letter-spacing: 0.05em;
  color: #fff;
  background: #ab47bc;
  border-radius: 12px;
}

.replay-tag.hidden {
  display: none;
}

.ground {
  position: relative;
  width: min(680px, 94vw, calc(100vh - 412px));
  aspect-ratio: 1 / 1;
  margin: 0 auto 0.5rem;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, #2f8f42 0%, #1f6e30 70%, #185a27 100%);
  border: 4px solid #e8e8e8;
  overflow: hidden;
  transition: filter 0.3s ease;
  touch-action: none; /* swipe-to-play controls need to own touch gestures, not the page scroller */
}

/* Slow-motion replay: a desaturated, dimmed "instant replay" tint over the whole scene so it can
   never be mistaken for a live in-progress delivery. */
.ground.replaying {
  filter: grayscale(0.55) brightness(0.8) sepia(0.15);
}

/* 30-yard fielding circle: radius comes from --fielding-circle-radius (script.js), derived from
   real Law 20 distances rather than a hardcoded percentage. Drawn first so the pitch strip below
   layers on top of it where the two intentionally-different-scale elements cross. Purely visual
   for now — no fielder-count enforcement relative to this circle yet. */
.fielding-circle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--fielding-circle-radius) * 2);
  height: calc(var(--fielding-circle-radius) * 2);
  transform: translate(-50%, -50%);
  border-radius: 50%;
  border: 2px dashed rgba(255, 255, 255, 0.4);
  pointer-events: none;
}

/* Pitch geometry comes entirely from CSS custom properties set by script.js
   (the single source of truth), so the strip can never drift out of sync
   with the ball's travel range again. */
.pitch-strip {
  position: absolute;
  left: var(--pitch-strip-left);
  width: var(--pitch-strip-width);
  top: var(--pitch-strip-top);
  height: var(--pitch-strip-height);
  background: repeating-linear-gradient(
    90deg,
    #d2b48c,
    #d2b48c 14px,
    #c9a876 14px,
    #c9a876 28px
  );
  border: 2px solid #7a5c3e;
  border-radius: 3px;
}

.pitch-marker {
  position: absolute;
  width: 16px;
  height: 16px;
  margin-left: -8px;
  margin-top: -8px;
  border-radius: 50%;
  border: 2px solid rgba(255, 235, 59, 0.9);
  background: rgba(255, 235, 59, 0.25);
  transition: opacity 0.3s ease, left 0.15s ease, top 0.15s ease;
  animation: pitch-marker-pulse 0.9s ease-in-out infinite;
  pointer-events: none;
}

@keyframes pitch-marker-pulse {
  0%, 100% { transform: scale(0.85); }
  50% { transform: scale(1.25); }
}

.hit-zone {
  position: absolute;
  left: 86%;
  width: 14%;
  top: -2px;
  bottom: -2px;
  background: rgba(255, 255, 255, 0.2);
  border-left: 2px dashed rgba(255, 255, 255, 0.5);
  border-right: 2px dashed rgba(255, 255, 255, 0.5);
}

.bowler-end,
.umpire,
.batter,
.fielder {
  position: absolute;
  transform: translate(-50%, -50%);
  font-size: 1.4rem;
}

.bowler-end {
  left: var(--bowler-x);
  top: var(--pitch-y);
}

.stumps {
  position: absolute;
  top: var(--pitch-y);
  width: 16px;
  height: 36px;
  transform: translate(-50%, -50%);
}

#stumps-batting {
  left: var(--stumps-x);
}

.stumps-far {
  left: var(--bowler-x);
}

.umpire {
  left: var(--umpire-x);
  top: var(--pitch-y);
  font-size: 1.2rem;
}

.batter {
  left: var(--batter-x);
  top: var(--pitch-y);
}

.fielder {
  font-size: 1.1rem;
  opacity: 0.9;
  transition: left 1.1s ease, top 1.1s ease;
}

.ball {
  position: absolute;
  left: 24%;
  top: 50%;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
  transform: translate(-50%, -50%);
}

.ball.flying {
  transition: left 0.45s ease, top 0.45s ease;
}

@keyframes ball-bounce {
  0% { transform: translate(-50%, -50%) scale(1, 1); }
  40% { transform: translate(-50%, -50%) scale(1.7, 0.5); }
  100% { transform: translate(-50%, -50%) scale(1, 1); }
}

.ball.bouncing {
  animation: ball-bounce 0.18s ease-out;
}

@keyframes stumps-hit {
  0% { transform: translate(-50%, -50%) rotate(0deg) scale(1); }
  20% { transform: translate(-50%, -50%) rotate(-18deg) scale(1.3); }
  40% { transform: translate(-50%, -50%) rotate(16deg) scale(1.3); }
  60% { transform: translate(-50%, -50%) rotate(-10deg) scale(1.15); }
  80% { transform: translate(-50%, -50%) rotate(6deg) scale(1.05); }
  100% { transform: translate(-50%, -50%) rotate(0deg) scale(1); }
}

.stumps.hit {
  animation: stumps-hit 0.6s ease;
}

@keyframes fielder-celebrate {
  0%, 100% { transform: translate(-50%, -50%) scale(1) translateY(0); }
  25% { transform: translate(-50%, -50%) scale(1.6) translateY(-6px); }
  50% { transform: translate(-50%, -50%) scale(1.3) translateY(0); }
  75% { transform: translate(-50%, -50%) scale(1.45) translateY(-3px); }
}

.fielder.celebrating {
  animation: fielder-celebrate 0.6s ease;
}

#message {
  min-height: 1.4rem;
  font-size: 1rem;
  font-weight: bold;
  margin-bottom: 0.3rem;
}

/* Live ball-by-ball commentary feed: compact, scrollable, newest entry on top. Deliberately kept
   small (max-height + tight padding) since the ground's size is the priority — this panel is a
   secondary, "nice to check" feed, not something that should compete with it for vertical space. */
.commentary-panel {
  background: #124a26;
  border-radius: 8px;
  padding: 0.3rem 0.5rem;
  margin-bottom: 0.3rem;
  text-align: left;
}

.commentary-panel-label {
  font-size: 0.65rem;
  color: #9fd8ac;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.15rem;
}

.commentary-log {
  max-height: 3rem;
  overflow-y: auto;
  font-size: 0.75rem;
  line-height: 1.35;
}

.commentary-entry {
  padding: 0.1rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.commentary-entry:last-child {
  border-bottom: none;
}

.commentary-wicket {
  color: #ff6e6e;
  font-weight: bold;
}

.feedback-tag {
  font-weight: bold;
}

.feedback-good {
  color: #69db7c;
}

.feedback-bad {
  color: #ff8a65;
}

.controls {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

/* Secondary controls (Restart/Scorecard/Mute) live behind a single toggle so they don't add a
   permanent row next to the ball-by-ball Start/Replay buttons. Positioned absolutely so opening it
   never reflows the page (and so never affects the ground's vh-based size). */
.more-controls-wrap {
  position: relative;
  display: inline-flex;
}

#more-controls-toggle {
  background: #2c2c3e;
  font-size: 1.1rem;
  padding: 0.5rem 0.75rem;
}

#more-controls-toggle:hover {
  background: #3a3a52;
}

.more-controls {
  position: absolute;
  bottom: calc(100% + 8px);
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 170px;
  background: #14401f;
  border: 1px solid #2c2c3e;
  border-radius: 8px;
  padding: 0.5rem;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
  z-index: 25;
}

.more-controls.hidden {
  display: none;
}

.more-controls button {
  width: 100%;
}

button {
  padding: 0.5rem 1rem;
  font-size: 0.95rem;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  background: #2c2c3e;
  color: #fff;
}

#start {
  background: #4caf50;
}

#start:hover:not(:disabled) {
  background: #43a047;
}

#restart {
  background: #3d6fd8;
}

#restart:hover {
  background: #345fc0;
}

#view-scorecard {
  background: #8a6d3b;
}

#view-scorecard:hover {
  background: #a17f45;
}

#replay-dismissal {
  background: #ab47bc;
}

#replay-dismissal:hover:not(:disabled) {
  background: #9539a5;
}

#skip-replay {
  background: #6b6b7a;
}

#skip-replay:hover:not(:disabled) {
  background: #575764;
}

/* Fixed corner FAB: mute needs to be reachable in one tap at any scroll position, any point in
   the game, without opening the ⚙ menu first -- unlike Restart/Scorecard it's the one control
   you'd realistically want mid-delivery. */
.mute-fab {
  position: fixed;
  top: 12px;
  right: 12px;
  z-index: 30;
  background: #2c2c3e;
  font-size: 1.1rem;
  line-height: 1;
  padding: 0.6rem 0.7rem;
  border-radius: 50%;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
}

.mute-fab:hover {
  background: #3a3a52;
}

button:disabled {
  opacity: 0.4;
  cursor: default;
}

.hidden {
  display: none;
}

.wagon-wheel-modal {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 1rem;
}

.wagon-wheel-modal.hidden {
  display: none;
}

.wagon-wheel-modal-content {
  position: relative;
  background: #14401f;
  border: 1px solid #2c2c3e;
  border-radius: 10px;
  padding: 1.5rem;
  max-width: 92vw;
  max-height: 90vh;
  overflow-y: auto;
}

.wagon-wheel-modal-content h2 {
  font-size: 1.1rem;
  margin: 0 0 0.75rem;
}

.wagon-wheel-modal-content svg {
  display: block;
  margin: 0 auto 0.75rem;
}

.scorecard-result {
  font-size: 0.95rem;
  font-weight: bold;
  color: #ffd54f;
  margin: 0 0 0.75rem;
  text-align: left;
}

.scorecard-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.4rem 1rem;
  margin: 0 0 1rem;
  font-size: 0.85rem;
  min-width: 260px;
}

.scorecard-stats > div {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  padding-bottom: 0.2rem;
}

.scorecard-stats .stat-label {
  color: #9fd8ac;
}

.scorecard-stats .stat-value {
  font-weight: bold;
  white-space: nowrap;
}

.scorecard-fow-section {
  text-align: left;
  margin: 0 0 1rem;
}

.scorecard-fow-section.hidden {
  display: none;
}

.scorecard-section-label {
  font-size: 0.7rem;
  color: #9fd8ac;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.35rem;
}

.scorecard-fow {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.82rem;
}

.fow-entry {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  padding-bottom: 0.15rem;
}

.fow-wicket {
  color: #ff8a65;
  font-weight: bold;
  min-width: 1.6rem;
}

/* The winning moment isn't a dismissal, so it gets its own green entry instead of the red used
   for actual fallen wickets. */
.fow-win {
  color: #69db7c;
  font-weight: bold;
  min-width: 1.6rem;
}

.fow-partnership {
  font-weight: bold;
  min-width: 4rem;
}

.fow-score {
  color: #9fd8ac;
  font-size: 0.78rem;
  margin-left: auto;
}

.wagon-wheel-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 50%;
  background: #2c2c3e;
  font-size: 1rem;
  line-height: 1;
}

.wagon-wheel-close:hover {
  background: #d84545;
}

.wagon-wheel-legend {
  font-size: 0.8rem;
  color: #ccc;
  margin: 0 0 0.5rem;
}

.wagon-wheel-legend span {
  font-size: 1rem;
}

.wagon-wheel-breakdown {
  font-size: 0.85rem;
  color: #9fd8ac;
  margin: 0;
}

/* Compact layout for narrow/short viewports (typical phones), so the stats bar, ground,
   and swing controls all fit together without needing to scroll mid-ball. */
@media (max-width: 430px), (max-height: 480px) {
  .app {
    padding-bottom: 8.5rem;
  }

  .mute-fab {
    top: 8px;
    right: 8px;
    font-size: 1rem;
    padding: 0.5rem 0.6rem;
  }

  h1 {
    font-size: 1.25rem;
    margin-bottom: 0.15rem;
  }

  .best-score {
    font-size: 0.75rem;
    margin-bottom: 0.4rem;
  }

  .difficulty-screen {
    padding: 1rem 0.9rem;
  }

  .stats {
    padding: 0.45rem 0.6rem;
    margin-bottom: 0.5rem;
  }

  .label {
    font-size: 0.6rem;
  }

  .stats span:last-child {
    font-size: 1rem;
  }

  .bowler-type {
    font-size: 0.75rem;
    margin: -0.2rem 0 0.4rem;
    min-height: 1rem;
  }

  .ground {
    width: min(300px, 80vw, calc(100vh - 360px));
    margin-bottom: 0.5rem;
  }

  #message {
    font-size: 0.85rem;
    min-height: 1.3rem;
    margin-bottom: 0.5rem;
  }

  .controls {
    gap: 0.4rem;
  }

  .controls button {
    padding: 0.45rem 0.75rem;
    font-size: 0.8rem;
  }

  .directions {
    padding: 0.35rem 0.35rem;
    padding-bottom: calc(0.35rem + env(safe-area-inset-bottom));
  }

  .dpad {
    gap: 4px;
    width: min(330px, 96vw);
  }

  .dir-btn {
    min-height: 2.1rem;
    padding: 0.2rem 0.15rem;
    font-size: 0.64rem;
  }

  .key-hint {
    font-size: 0.55rem;
  }
}

/* Win celebration: shown for a couple of seconds after a successful chase, before the scorecard
   takes over. Sits above the scorecard modal (z-index 1000) so it's seen first, not alongside it. */
.celebration-overlay {
  position: fixed;
  inset: 0;
  z-index: 1500;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.55);
  overflow: hidden;
  pointer-events: none;
}

.celebration-overlay.hidden {
  display: none;
}

.celebration-text {
  position: relative;
  z-index: 2;
  font-size: 2.2rem;
  font-weight: bold;
  color: #ffd54f;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.6);
  animation: celebration-pop 0.5s ease;
}

@keyframes celebration-pop {
  0% { transform: scale(0.5); opacity: 0; }
  60% { transform: scale(1.15); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}

.confetti-container {
  position: absolute;
  inset: 0;
}

.confetti-piece {
  position: absolute;
  top: -5%;
  width: 8px;
  height: 14px;
  opacity: 0.9;
  animation-name: confetti-fall;
  animation-timing-function: ease-in;
  animation-fill-mode: forwards;
}

@keyframes confetti-fall {
  0% { transform: translateY(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(115vh) rotate(360deg); opacity: 0.85; }
}
