/* ═══════════════════════════════════════════════════════
   Shot Animation Stage — Quest
   Outside Jump Shot prototype
   ═══════════════════════════════════════════════════════ */

/* ── Hidden state ──────────────────────────────────────── */
.shot-stage.hidden {
  display: none;
}

/* ── Stage container ───────────────────────────────────── */
.shot-stage {
  width: 400px;
  height: 280px;
  margin: 8px auto;
  background: #0d0d1a;
  border-radius: 8px;
  overflow: hidden;
  position: relative;
}

/* ── Court container ───────────────────────────────────── */
.court {
  width: 400px;
  height: 280px;
  position: relative;
  perspective: 800px;
}

/* ── Court surface (broadcast angle) ───────────────────── */
.court-surface {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 400px;
  height: 200px;
  background: #1a1a2e;
  border: 1px solid #f0a500;
  transform: rotateX(55deg);
  transform-origin: bottom center;
  transform-style: preserve-3d;
}

/*
 * Court markings — NBA proportions
 * Scale: 400px = 50ft → 8px/ft
 * Half-court depth: 200px ≈ 47ft → ~4.26px/ft
 *
 * Key measurements (in our px):
 *   Paint: 16ft wide = 128px, 19ft deep = 81px
 *   FT circle: 6ft radius = 48px diameter on width axis
 *   3pt straight: 14ft from baseline = 60px
 *   3pt corner width: 22ft from center = 176px each side
 *   Basket: ~5ft from baseline = ~21px from top
 */

/* Paint/key — 16' wide × 19' deep */
.court-surface .paint {
  position: absolute;
  top: 0;
  left: 136px;   /* (400 - 128) / 2 */
  width: 128px;
  height: 81px;
  border: 1px solid rgba(240, 165, 0, 0.35);
  background: rgba(240, 165, 0, 0.06);
}

/* Three-point line — straight sides + arc bottom.
   Corner 3 is 22' from basket center → 176px from center = starts at x=24.
   Straight sections run 14' from baseline = 60px.
   Arc section below the straight parts. We use a wrapper with
   straight border-left/right + rounded bottom to approximate. */
.court-surface .three-point-arc {
  position: absolute;
  top: 0;
  left: 24px;
  width: 352px;
  height: 150px;
  border-left: 1px solid rgba(240, 165, 0, 0.25);
  border-right: 1px solid rgba(240, 165, 0, 0.25);
  border-bottom: 1px solid rgba(240, 165, 0, 0.25);
  border-top: none;
  border-radius: 0 0 176px 176px;
}

/* Free throw line — bottom edge of paint, 19' from baseline */
.court-surface .free-throw-line {
  position: absolute;
  top: 81px;
  left: 136px;
  width: 128px;
  height: 0;
  border-top: 1px solid rgba(240, 165, 0, 0.35);
}

/* Free throw circle — 6' radius = 48px/ft... but circle is
   6' radius = same width as paint (12' diameter = 96px at scale,
   but NBA FT circle = 6' radius = 12' diameter and paint = 16' wide,
   so circle is NARROWER than paint: 12/16 = 75% of paint width).
   Actually: 6' radius = 48px wide (diameter 96px).
   Centered on FT line, only bottom half visible (top half is in paint). */
.court-surface .free-throw-circle {
  position: absolute;
  top: 81px;        /* starts at free-throw line */
  left: 152px;      /* (400 - 96) / 2 */
  width: 96px;
  height: 48px;
  border: 1px solid rgba(240, 165, 0, 0.25);
  border-top: none;
  border-radius: 0 0 48px 48px;
}

/* Baseline — at top of surface, nearest to basket */
.court-surface .baseline {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 0;
  border-top: 1px solid rgba(240, 165, 0, 0.4);
}

/* ── Basket ────────────────────────────────────────────── */
.basket {
  position: absolute;
  top: 30px;
  left: 50%;
  transform: translateX(-50%);
  width: 40px;
  height: 40px;
}

/* Backboard */
.basket .backboard {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 36px;
  height: 6px;
  background: #888;
  border-radius: 1px;
}

/* Rim */
.basket .rim {
  position: absolute;
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
  width: 20px;
  height: 8px;
  border: 2px solid #e85d26;
  border-radius: 50%;
  background: transparent;
}

/* Net */
.basket .net {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  width: 16px;
  height: 18px;
  border-left: 1px solid rgba(255, 255, 255, 0.5);
  border-right: 1px solid rgba(255, 255, 255, 0.5);
  border-bottom: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 0 0 4px 4px;
  background: repeating-linear-gradient(
    180deg,
    transparent 0px,
    transparent 3px,
    rgba(255, 255, 255, 0.15) 3px,
    rgba(255, 255, 255, 0.15) 4px
  );
}

/* ── Meeples (stick figures) ───────────────────────────── */
.meeple {
  position: absolute;
  width: 16px;
  height: 32px;
}

/* Head */
.meeple::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 10px;
  height: 10px;
  border-radius: 50%;
}

/* Body */
.meeple::after {
  content: '';
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  width: 3px;
  height: 14px;
  border-radius: 1px;
}

/* Offense (teal) */
.meeple.offense::before {
  background: #00d4aa;
}
.meeple.offense::after {
  background: #00d4aa;
}

/* Defense (coral) */
.meeple.defense::before {
  background: #e85d5d;
}
.meeple.defense::after {
  background: #e85d5d;
}

/* Positioned for Outside Jump Shot scene */
.meeple.shooter {
  left: 260px;
  top: 150px;
}

.meeple.primary {
  left: 244px;
  top: 158px;
}

.meeple.teammate {
  left: 160px;
  top: 175px;
}

.meeple.help {
  left: 145px;
  top: 185px;
}

/* ── Foul shot scene — overrides meeple positions ─────── */
/* Shooter at FT line (center, behind the free-throw circle) */
.scene-foul-shot .meeple.shooter {
  left: 192px;
  top: 180px;
}

/* Lane players — two on each side of the key */
.scene-foul-shot .meeple.teammate {
  left: 128px;
  top: 145px;
}

.scene-foul-shot .meeple.primary {
  left: 256px;
  top: 145px;
}

.scene-foul-shot .meeple.help {
  left: 128px;
  top: 125px;
}

/* ── Ball ──────────────────────────────────────────────── */
.ball {
  position: absolute;
  width: 14px;
  height: 14px;
  background: #e8822b;
  border-radius: 50%;
  opacity: 0;
  z-index: 10;
  box-shadow: 0 0 6px rgba(232, 130, 43, 0.6);
}

/* ── Result text ───────────────────────────────────────── */
.result-text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: 'Anton', sans-serif;
  font-size: 28px;
  text-transform: uppercase;
  letter-spacing: 2px;
  opacity: 0;
  z-index: 20;
  pointer-events: none;
}


/* ═══════════════════════════════════════════════════════
   Keyframe Animations
   ═══════════════════════════════════════════════════════ */

/* ── Shooter jump ──────────────────────────────────────── */
@keyframes shooter-jump {
  0%   { transform: translateY(0); }
  40%  { transform: translateY(-12px); }
  100% { transform: translateY(0); }
}

.meeple.shooter.shooting {
  animation: shooter-jump 500ms ease-out;
}

/* ── Ball arc: Outside Jump Shot — MADE ────────────────── */
@keyframes ball-arc-ojs-made {
  0%   { left: 266px; top: 148px; opacity: 1; }
  15%  { left: 250px; top: 115px; opacity: 1; }
  30%  { left: 235px; top: 85px;  opacity: 1; }
  50%  { left: 218px; top: 58px;  opacity: 1; }
  70%  { left: 206px; top: 42px;  opacity: 1; }
  85%  { left: 198px; top: 36px;  opacity: 1; }
  100% { left: 194px; top: 38px;  opacity: 1; }
}

.ball.arc-ojs-made {
  animation: ball-arc-ojs-made 700ms ease-out forwards;
}

/* ── Ball arc: Outside Jump Shot — MISSED ──────────────── */
@keyframes ball-arc-ojs-missed {
  0%   { left: 266px; top: 148px; opacity: 1; }
  15%  { left: 250px; top: 115px; opacity: 1; }
  30%  { left: 235px; top: 85px;  opacity: 1; }
  50%  { left: 218px; top: 58px;  opacity: 1; }
  70%  { left: 208px; top: 40px;  opacity: 1; }
  82%  { left: 202px; top: 35px;  opacity: 1; }
  90%  { left: 210px; top: 50px;  opacity: 1; }
  100% { left: 222px; top: 72px;  opacity: 1; }
}

.ball.arc-ojs-missed {
  animation: ball-arc-ojs-missed 700ms ease-out forwards;
}

/* ── Ball arc: Free Throw — MADE ─────────────────────── */
/* Shorter, straighter arc from FT line (center) to basket */
@keyframes ball-arc-ft-made {
  0%   { left: 198px; top: 178px; opacity: 1; }
  20%  { left: 197px; top: 140px; opacity: 1; }
  40%  { left: 196px; top: 100px; opacity: 1; }
  60%  { left: 195px; top: 68px;  opacity: 1; }
  80%  { left: 194px; top: 44px;  opacity: 1; }
  100% { left: 194px; top: 38px;  opacity: 1; }
}

.ball.arc-ft-made {
  animation: ball-arc-ft-made 550ms ease-out forwards;
}

/* ── Ball arc: Free Throw — MISSED ───────────────────── */
@keyframes ball-arc-ft-missed {
  0%   { left: 198px; top: 178px; opacity: 1; }
  20%  { left: 197px; top: 140px; opacity: 1; }
  40%  { left: 196px; top: 100px; opacity: 1; }
  60%  { left: 195px; top: 68px;  opacity: 1; }
  78%  { left: 194px; top: 42px;  opacity: 1; }
  88%  { left: 186px; top: 36px;  opacity: 1; }
  100% { left: 178px; top: 55px;  opacity: 1; }
}

.ball.arc-ft-missed {
  animation: ball-arc-ft-missed 550ms ease-out forwards;
}

/* ── Ball arc: Layup — MADE ──────────────────────────── */
/* Short, soft arc from paint. Gentle finger-roll, floats near rim */
@keyframes ball-arc-lay-made {
  0%   { left: 210px; top: 105px; opacity: 1; }
  20%  { left: 206px; top: 85px;  opacity: 1; }
  40%  { left: 202px; top: 65px;  opacity: 1; }
  60%  { left: 198px; top: 48px;  opacity: 1; }
  75%  { left: 196px; top: 40px;  opacity: 1; }
  88%  { left: 195px; top: 36px;  opacity: 1; }  /* floats near rim */
  100% { left: 194px; top: 38px;  opacity: 1; }
}

.ball.arc-lay-made {
  animation: ball-arc-lay-made 500ms ease-out forwards;
}

/* ── Ball arc: Layup — MISSED ───────────────────────── */
/* Same approach, catches front rim and kicks right */
@keyframes ball-arc-lay-missed {
  0%   { left: 210px; top: 105px; opacity: 1; }
  20%  { left: 206px; top: 85px;  opacity: 1; }
  40%  { left: 202px; top: 65px;  opacity: 1; }
  60%  { left: 198px; top: 48px;  opacity: 1; }
  75%  { left: 196px; top: 38px;  opacity: 1; }
  85%  { left: 198px; top: 35px;  opacity: 1; }  /* hits front rim */
  92%  { left: 208px; top: 42px;  opacity: 1; }  /* kicks right */
  100% { left: 224px; top: 62px;  opacity: 1; }
}

.ball.arc-lay-missed {
  animation: ball-arc-lay-missed 500ms ease-out forwards;
}

/* ── Ball arc: Slam Dunk — MADE ─────────────────────── */
/* Aggressive attack from paint. Ball rises high, then SLAMS down through */
@keyframes ball-arc-sd-made {
  0%   { left: 215px; top: 108px; opacity: 1; }
  25%  { left: 208px; top: 72px;  opacity: 1; }
  45%  { left: 202px; top: 30px;  opacity: 1; }  /* above the rim */
  60%  { left: 198px; top: 22px;  opacity: 1; }  /* peak — above backboard */
  75%  { left: 195px; top: 28px;  opacity: 1; }  /* coming down */
  90%  { left: 194px; top: 36px;  opacity: 1; }  /* slams through */
  100% { left: 194px; top: 52px;  opacity: 1; }  /* drops below rim */
}

.ball.arc-sd-made {
  animation: ball-arc-sd-made 550ms cubic-bezier(0.3, 0, 0.7, 1) forwards;
}

/* ── Ball arc: Slam Dunk — MISSED ───────────────────── */
/* Hard attack, ball clangs off front rim and bounces high */
@keyframes ball-arc-sd-missed {
  0%   { left: 215px; top: 108px; opacity: 1; }
  25%  { left: 208px; top: 72px;  opacity: 1; }
  45%  { left: 202px; top: 30px;  opacity: 1; }
  60%  { left: 198px; top: 22px;  opacity: 1; }
  72%  { left: 195px; top: 32px;  opacity: 1; }  /* hits rim hard */
  82%  { left: 210px; top: 18px;  opacity: 1; }  /* bounces UP off rim */
  92%  { left: 228px; top: 30px;  opacity: 1; }
  100% { left: 240px; top: 58px;  opacity: 1; }
}

.ball.arc-sd-missed {
  animation: ball-arc-sd-missed 550ms cubic-bezier(0.3, 0, 0.7, 1) forwards;
}

/* ── Ball arc: Hook Shot — MADE ─────────────────────── */
/* Sweeping sideways hook from inside-left, arcs across and drops in */
@keyframes ball-arc-hs-made {
  0%   { left: 170px; top: 110px; opacity: 1; }
  15%  { left: 174px; top: 90px;  opacity: 1; }
  30%  { left: 180px; top: 68px;  opacity: 1; }
  50%  { left: 188px; top: 48px;  opacity: 1; }
  70%  { left: 193px; top: 38px;  opacity: 1; }
  85%  { left: 194px; top: 36px;  opacity: 1; }
  100% { left: 194px; top: 38px;  opacity: 1; }
}

.ball.arc-hs-made {
  animation: ball-arc-hs-made 600ms ease-out forwards;
}

/* ── Ball arc: Hook Shot — MISSED ───────────────────── */
/* Same hook sweep, catches far side of rim and rolls off left */
@keyframes ball-arc-hs-missed {
  0%   { left: 170px; top: 110px; opacity: 1; }
  15%  { left: 174px; top: 90px;  opacity: 1; }
  30%  { left: 180px; top: 68px;  opacity: 1; }
  50%  { left: 188px; top: 48px;  opacity: 1; }
  68%  { left: 194px; top: 37px;  opacity: 1; }  /* hits far rim */
  80%  { left: 200px; top: 34px;  opacity: 1; }  /* rolls across */
  90%  { left: 206px; top: 44px;  opacity: 1; }
  100% { left: 214px; top: 68px;  opacity: 1; }
}

.ball.arc-hs-missed {
  animation: ball-arc-hs-missed 600ms ease-out forwards;
}

/* ── Ball arc: Long Shot — MADE ─────────────────────── */
/* High rainbow arc from deep. Longer, higher trajectory */
@keyframes ball-arc-ls-made {
  0%   { left: 290px; top: 168px; opacity: 1; }
  12%  { left: 274px; top: 132px; opacity: 1; }
  25%  { left: 256px; top: 92px;  opacity: 1; }
  38%  { left: 240px; top: 56px;  opacity: 1; }
  50%  { left: 226px; top: 30px;  opacity: 1; }  /* peak — very high */
  62%  { left: 214px; top: 22px;  opacity: 1; }
  75%  { left: 204px; top: 28px;  opacity: 1; }
  88%  { left: 198px; top: 34px;  opacity: 1; }
  100% { left: 194px; top: 38px;  opacity: 1; }
}

.ball.arc-ls-made {
  animation: ball-arc-ls-made 800ms ease-out forwards;
}

/* ── Ball arc: Long Shot — MISSED ───────────────────── */
/* Same rainbow, comes up short — front rim and bounces left */
@keyframes ball-arc-ls-missed {
  0%   { left: 290px; top: 168px; opacity: 1; }
  12%  { left: 274px; top: 132px; opacity: 1; }
  25%  { left: 256px; top: 92px;  opacity: 1; }
  38%  { left: 240px; top: 56px;  opacity: 1; }
  50%  { left: 226px; top: 30px;  opacity: 1; }
  62%  { left: 214px; top: 22px;  opacity: 1; }
  74%  { left: 204px; top: 30px;  opacity: 1; }
  83%  { left: 198px; top: 35px;  opacity: 1; }  /* front rim */
  91%  { left: 186px; top: 48px;  opacity: 1; }
  100% { left: 172px; top: 72px;  opacity: 1; }
}

.ball.arc-ls-missed {
  animation: ball-arc-ls-missed 800ms ease-out forwards;
}

/* ── Ball arc: Fadeaway — MADE ──────────────────────── */
/* Shooter drifts backward. Ball launches from slightly further out, high soft arc */
@keyframes ball-arc-fa-made {
  0%   { left: 272px; top: 152px; opacity: 1; }
  15%  { left: 260px; top: 118px; opacity: 1; }
  30%  { left: 246px; top: 82px;  opacity: 1; }
  45%  { left: 232px; top: 52px;  opacity: 1; }
  60%  { left: 218px; top: 34px;  opacity: 1; }
  75%  { left: 206px; top: 30px;  opacity: 1; }  /* floats at peak */
  88%  { left: 198px; top: 34px;  opacity: 1; }
  100% { left: 194px; top: 38px;  opacity: 1; }
}

.ball.arc-fa-made {
  animation: ball-arc-fa-made 700ms ease-out forwards;
}

/* ── Ball arc: Fadeaway — MISSED ─────────────────────── */
/* Same fade, ball comes up short — doesn't quite reach */
@keyframes ball-arc-fa-missed {
  0%   { left: 272px; top: 152px; opacity: 1; }
  15%  { left: 260px; top: 118px; opacity: 1; }
  30%  { left: 246px; top: 82px;  opacity: 1; }
  45%  { left: 232px; top: 52px;  opacity: 1; }
  60%  { left: 218px; top: 34px;  opacity: 1; }
  74%  { left: 208px; top: 30px;  opacity: 1; }
  84%  { left: 202px; top: 34px;  opacity: 1; }  /* front rim */
  92%  { left: 210px; top: 50px;  opacity: 1; }
  100% { left: 220px; top: 74px;  opacity: 1; }
}

.ball.arc-fa-missed {
  animation: ball-arc-fa-missed 700ms ease-out forwards;
}

/* ── Ball arc: Quick Shot — MADE ────────────────────── */
/* Flat, fast. Barely any arc — line drive that drops in */
@keyframes ball-arc-qs-made {
  0%   { left: 258px; top: 146px; opacity: 1; }
  20%  { left: 242px; top: 118px; opacity: 1; }
  40%  { left: 226px; top: 88px;  opacity: 1; }
  60%  { left: 212px; top: 60px;  opacity: 1; }
  80%  { left: 200px; top: 42px;  opacity: 1; }
  100% { left: 194px; top: 38px;  opacity: 1; }
}

.ball.arc-qs-made {
  animation: ball-arc-qs-made 420ms linear forwards;
}

/* ── Ball arc: Quick Shot — MISSED ──────────────────── */
/* Same flat trajectory, glances off rim */
@keyframes ball-arc-qs-missed {
  0%   { left: 258px; top: 146px; opacity: 1; }
  20%  { left: 242px; top: 118px; opacity: 1; }
  40%  { left: 226px; top: 88px;  opacity: 1; }
  60%  { left: 212px; top: 60px;  opacity: 1; }
  78%  { left: 200px; top: 40px;  opacity: 1; }
  88%  { left: 192px; top: 38px;  opacity: 1; }  /* glances rim */
  100% { left: 176px; top: 58px;  opacity: 1; }
}

.ball.arc-qs-missed {
  animation: ball-arc-qs-missed 420ms linear forwards;
}

/* ── Ball arc: Set Shot — MADE ──────────────────────── */
/* High, clean parabola — deliberate release, nothing but net */
@keyframes ball-arc-ss-made {
  0%   { left: 264px; top: 150px; opacity: 1; }
  15%  { left: 248px; top: 118px; opacity: 1; }
  30%  { left: 232px; top: 86px;  opacity: 1; }
  45%  { left: 220px; top: 58px;  opacity: 1; }
  60%  { left: 210px; top: 38px;  opacity: 1; }
  75%  { left: 202px; top: 28px;  opacity: 1; }  /* peak — high arc */
  88%  { left: 197px; top: 32px;  opacity: 1; }
  100% { left: 194px; top: 38px;  opacity: 1; }
}

.ball.arc-ss-made {
  animation: ball-arc-ss-made 700ms ease-out forwards;
}

/* ── Ball arc: Set Shot — MISSED ────────────────────── */
/* High arc, rattles out off the front rim */
@keyframes ball-arc-ss-missed {
  0%   { left: 264px; top: 150px; opacity: 1; }
  15%  { left: 248px; top: 118px; opacity: 1; }
  30%  { left: 232px; top: 86px;  opacity: 1; }
  45%  { left: 220px; top: 58px;  opacity: 1; }
  60%  { left: 210px; top: 38px;  opacity: 1; }
  75%  { left: 202px; top: 28px;  opacity: 1; }  /* peak */
  85%  { left: 197px; top: 34px;  opacity: 1; }  /* hits front rim */
  92%  { left: 188px; top: 44px;  opacity: 1; }  /* bounces out */
  100% { left: 176px; top: 62px;  opacity: 1; }
}

.ball.arc-ss-missed {
  animation: ball-arc-ss-missed 700ms ease-out forwards;
}

/* ── Scene: Inside shot — meeple positions ───────────── */
/* Shooter in the paint, close to basket */
.scene-inside-shot .meeple.shooter {
  left: 210px;
  top: 120px;
}

.scene-inside-shot .meeple.primary {
  left: 218px;
  top: 128px;
}

.scene-inside-shot .meeple.teammate {
  left: 150px;
  top: 165px;
}

.scene-inside-shot .meeple.help {
  left: 260px;
  top: 170px;
}

/* Hook shot shooter — offset to left side of paint */
.scene-hook-shot .meeple.shooter {
  left: 170px;
  top: 125px;
}

.scene-hook-shot .meeple.primary {
  left: 180px;
  top: 132px;
}

.scene-hook-shot .meeple.teammate {
  left: 240px;
  top: 160px;
}

.scene-hook-shot .meeple.help {
  left: 260px;
  top: 175px;
}

/* ── Net ripple ────────────────────────────────────────── */
@keyframes net-ripple {
  0%   { transform: translateX(-50%) scaleY(1); }
  30%  { transform: translateX(-50%) scaleY(1.3); }
  60%  { transform: translateX(-50%) scaleY(0.85); }
  100% { transform: translateX(-50%) scaleY(1); }
}

.basket .net.ripple {
  animation: net-ripple 300ms ease-in-out;
}

/* ── Rim shake ─────────────────────────────────────────── */
@keyframes rim-shake {
  0%   { transform: translateX(-50%); }
  20%  { transform: translateX(calc(-50% + 3px)); }
  40%  { transform: translateX(calc(-50% - 3px)); }
  60%  { transform: translateX(calc(-50% + 2px)); }
  80%  { transform: translateX(calc(-50% - 1px)); }
  100% { transform: translateX(-50%); }
}

.basket .rim.shake {
  animation: rim-shake 200ms ease-in-out;
}

/* ── Result text pop ───────────────────────────────────── */
@keyframes result-text-pop {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(1.8); }
  30%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  75%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1); }
}

.result-text.show {
  animation: result-text-pop 500ms ease-out forwards;
}

.result-text.show.made {
  color: #00d4aa;
}

.result-text.show.missed {
  color: #e85d5d;
}


/* ═══════════════════════════════════════════════════════
   Slam Dunk — Full Choreographed Animation
   CSS-delay driven (JS just adds classes, CSS handles timing)
   ═══════════════════════════════════════════════════════ */

/* ── Shooter drive + jump ────────────────────────────── */
@keyframes sd-shooter-drive-made {
  0%   { transform: translate(0, 0); }
  75%  { transform: translate(-16px, -50px); }
  100% { transform: translate(-16px, -110px); }
}
@keyframes sd-shooter-drive-missed {
  0%   { transform: translate(0, 0); }
  75%  { transform: translate(-16px, -50px); }
  100% { transform: translate(-16px, -80px); }
}

.scene-inside-shot .meeple.shooter.sd-drive {
  animation: sd-shooter-drive-made 800ms cubic-bezier(0.25, 1, 0.5, 1) forwards;
}
.scene-inside-shot .meeple.shooter.sd-drive-miss {
  animation: sd-shooter-drive-missed 800ms cubic-bezier(0.25, 1, 0.5, 1) forwards;
}

/* ── Speed lines trailing behind shooter ─────────────── */
@keyframes sd-speed-lines {
  0%, 100% { opacity: 0; width: 0; }
  30%      { opacity: 0.5; width: 25px; }
}

.meeple.shooter.sd-drive::after,
.meeple.shooter.sd-drive-miss::after {
  content: '';
  position: absolute;
  left: -25px;
  top: 50%;
  height: 3px;
  background: repeating-linear-gradient(
    90deg,
    rgba(255,255,255,0.4) 0px,
    rgba(255,255,255,0.4) 5px,
    transparent 5px,
    transparent 9px
  );
  border-radius: 2px;
  animation: sd-speed-lines 600ms ease-out forwards;
  opacity: 0;
  pointer-events: none;
}

/* ── Ball approach (rises above rim) ─────────────────── */
@keyframes sd-ball-approach-made {
  0%   { left: 210px; top: 118px; opacity: 1; }
  40%  { left: 204px; top: 80px;  opacity: 1; }
  70%  { left: 198px; top: 45px;  opacity: 1; }
  100% { left: 194px; top: 20px;  opacity: 1; }
}

/* ── Ball SLAM down through basket ───────────────────── */
@keyframes sd-ball-slam {
  0%   { left: 194px; top: 20px;  opacity: 1; }
  60%  { left: 194px; top: 42px;  opacity: 1; }
  100% { left: 194px; top: 55px;  opacity: 1; }
}

.ball.arc-sd-made {
  animation: sd-ball-approach-made 600ms ease-in forwards,
             sd-ball-slam 200ms cubic-bezier(0.4, 0, 1, 1) 600ms forwards;
}

/* ── Ball approach for miss ──────────────────────────── */
@keyframes sd-ball-approach-missed {
  0%   { left: 210px; top: 118px; opacity: 1; }
  40%  { left: 204px; top: 80px;  opacity: 1; }
  70%  { left: 198px; top: 50px;  opacity: 1; }
  100% { left: 195px; top: 36px;  opacity: 1; }
}

/* ── Ball clangs off rim violently ───────────────────── */
@keyframes sd-ball-clang {
  0%   { left: 195px; top: 36px;  opacity: 1; }
  25%  { left: 212px; top: 18px;  opacity: 1; }
  50%  { left: 232px; top: 10px;  opacity: 1; }
  100% { left: 260px; top: 40px;  opacity: 0.6; }
}

.ball.arc-sd-missed {
  animation: sd-ball-approach-missed 600ms ease-in forwards,
             sd-ball-clang 450ms cubic-bezier(0.1, 1.2, 0.4, 0.8) 600ms forwards;
}

/* ── Ball trail while in flight ──────────────────────── */
@keyframes sd-ball-trail {
  0%   { transform: translate(-50%, -50%) scale(0.9); opacity: 0.3; }
  100% { transform: translate(-50%, -50%) scale(0.4); opacity: 0; }
}

.ball.arc-sd-made::after,
.ball.arc-sd-missed::after {
  content: '';
  position: absolute;
  left: 50%; top: 50%;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: rgba(232, 130, 43, 0.5);
  animation: sd-ball-trail 150ms ease-out infinite;
  pointer-events: none;
}

/* Stop trail after ball lands */
.ball.sd-landed::after {
  animation: none;
  opacity: 0;
}

/* ── Defender reactions ──────────────────────────────── */
@keyframes sd-defender-stumble {
  0%   { transform: translate(0, 0); }
  100% { transform: translate(12px, 18px); }
}
@keyframes sd-defender-contest {
  0%   { transform: translate(0, 0); }
  45%  { transform: translate(0, -25px); }
  100% { transform: translate(0, 0); }
}

.scene-inside-shot.sd-made .meeple.primary {
  animation: sd-defender-stumble 300ms cubic-bezier(0.1, 0.9, 0.3, 1) 750ms forwards;
}
.scene-inside-shot.sd-missed .meeple.primary {
  animation: sd-defender-contest 400ms cubic-bezier(0.1, 0.9, 0.3, 1) 450ms;
}

/* ── Screen shake (made only) ────────────────────────── */
@keyframes sd-screen-shake {
  0%, 100% { transform: translate(0, 0); }
  12%  { transform: translate(-3px, 2px); }
  25%  { transform: translate(4px, -3px); }
  37%  { transform: translate(-4px, -2px); }
  50%  { transform: translate(3px, 3px); }
  62%  { transform: translate(-2px, -3px); }
  75%  { transform: translate(3px, 1px); }
  87%  { transform: translate(-1px, 2px); }
}

.sd-made .court {
  animation: sd-screen-shake 400ms ease-out 780ms;
}

/* ── Impact burst (made only, on basket) ─────────────── */
@keyframes sd-impact-burst {
  0%   { transform: translate(-50%, -50%) scale(0); opacity: 0; }
  25%  { opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1.6); opacity: 0; }
}

.sd-made .basket::before {
  content: '';
  position: absolute;
  top: 20px;
  left: 50%;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,0.9) 0%, rgba(255,140,50,0.5) 35%, transparent 70%);
  opacity: 0;
  pointer-events: none;
  animation: sd-impact-burst 400ms ease-out 780ms forwards;
}

/* ── Net swoosh (made only) ──────────────────────────── */
@keyframes sd-net-swoosh {
  0%   { transform: translateX(-50%) scaleY(1) rotate(0deg); }
  20%  { transform: translateX(-50%) scaleY(1.5) rotate(-5deg); }
  45%  { transform: translateX(-50%) scaleY(1.25) rotate(3deg); }
  70%  { transform: translateX(-50%) scaleY(1.1) rotate(-1deg); }
  100% { transform: translateX(-50%) scaleY(1) rotate(0deg); }
}

.sd-made .basket .net {
  animation: sd-net-swoosh 500ms cubic-bezier(0.2, 1, 0.4, 1.2) 780ms;
}

/* ── Rim shake (missed only) ─────────────────────────── */
@keyframes sd-rim-shake {
  0%, 100% { transform: translateX(-50%); }
  20%  { transform: translateX(calc(-50% + 4px)); }
  40%  { transform: translateX(calc(-50% - 4px)); }
  60%  { transform: translateX(calc(-50% + 3px)); }
  80%  { transform: translateX(calc(-50% - 2px)); }
}

.sd-missed .basket .rim {
  animation: sd-rim-shake 250ms ease-in-out 600ms;
}

/* ── Result text for slam dunk ───────────────────────── */
@keyframes sd-result-pop {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
  12%  { opacity: 1; transform: translate(-50%, -50%) scale(1.8); }
  28%  { transform: translate(-50%, -50%) scale(1); }
  75%  { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.05); }
}

.result-text.sd-show {
  animation: sd-result-pop 800ms ease-out forwards;
}

/* ═══════════════════════════════════════════════════════
   Mobile scaling
   ═══════════════════════════════════════════════════════ */
@media (max-width: 420px) {
  .shot-stage {
    transform: scale(0.9);
    transform-origin: top center;
    margin: 4px auto;
  }
}
