/* ============================================
   Animations - Shot & Scoring
   ============================================ */

.animation-overlay {
    position: fixed;
    inset: 0;
    background: rgba(45, 27, 14, 0.95);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 900;
}

.animation-court {
    position: relative;
    width: 320px;
    height: 200px;
    background: linear-gradient(180deg, var(--court-wood) 0%, var(--court-wood-dark) 100%);
    border: 4px solid var(--dark-brown);
    border-radius: var(--radius-md);
    overflow: hidden;
}

/* Court markings */
.animation-court::before {
    content: '';
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 120px;
    height: 80px;
    border: 4px solid rgba(255, 255, 255, 0.5);
    border-bottom: none;
    border-radius: 60px 60px 0 0;
}

.animation-hoop {
    position: absolute;
    top: 20px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 2.5rem;
}

.animation-ball {
    position: absolute;
    font-size: 2rem;
    transition: all 0.5s ease-out;
}

.animation-player {
    position: absolute;
    bottom: 30px;
    font-size: 2.5rem;
}

.animation-message {
    font-family: var(--font-display);
    font-size: 2rem;
    color: white;
    margin-top: 1.5rem;
    text-shadow: 3px 3px 0 var(--primary-orange);
}

.animation-message.success {
    color: var(--pop-lime);
}

.animation-message.miss {
    color: var(--danger-red);
}

/* ============================================
   Animation Wrapper - header, court, and result
   ============================================ */

.animation-wrapper {
    position: absolute;
    top: 85px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 200;
    width: 355px;
    display: flex;
    flex-direction: column;
    align-items: stretch;
}

.animation-wrapper.hidden {
    display: none;
}

/* Animation Header Bar */
.animation-header {
    padding: 0.5rem 0.75rem;
    background: rgba(13, 17, 23, 0.92);
    font-family: var(--font-condensed);
    font-weight: 600;
    font-size: 1.1rem;
    color: rgba(230, 237, 243, 0.95);
    text-align: center;
    border-radius: 12px 12px 0 0;
    border: 1px solid rgba(196, 149, 106, 0.2);
    border-bottom: none;
    min-height: 1.5em;
    line-height: 1.3;
    letter-spacing: 0.02em;
    opacity: 0;
    transform: translateY(-8px);
    transition: opacity 0.25s ease, transform 0.25s ease;
}

.animation-header.visible {
    opacity: 1;
    transform: translateY(0);
}

/* Animation Result Bar */
.animation-result {
    padding: 0;
    font-family: var(--font-display);
    font-size: 1.3rem;
    color: white;
    text-align: center;
    border-radius: 0 0 12px 12px;
    border: 1px solid rgba(196, 149, 106, 0.2);
    border-top: none;
    min-height: 0;
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    transition: opacity 0.3s ease, max-height 0.3s ease, padding 0.3s ease;
}

.animation-result.visible {
    min-height: 1.5em;
    max-height: 3em;
    opacity: 1;
    padding: 0.5rem 0.75rem;
}

.animation-result.success {
    background: linear-gradient(180deg, rgba(56, 142, 60, 0.92) 0%, rgba(46, 125, 50, 0.95) 100%);
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}

.animation-result.miss {
    background: linear-gradient(180deg, rgba(183, 28, 28, 0.92) 0%, rgba(153, 20, 20, 0.95) 100%);
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}

.animation-result.neutral {
    background: rgba(13, 17, 23, 0.92);
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.4);
}

/* ============================================
   Shot Animation Container
   ============================================ */

.shot-animation {
    width: 100%;
    height: 200px;
    overflow: hidden;
    z-index: 200;
    background:
        linear-gradient(180deg, transparent 70%, rgba(196, 149, 106, 0.15) 100%),
        linear-gradient(180deg, #0d1117 0%, #161b22 100%);
    box-shadow: inset 0 -1px 0 rgba(196, 149, 106, 0.3);
}

.shot-court {
    position: relative;
    width: 100%;
    height: 100%;
}

/* Flip court horizontally when AI is on offense (attack right-to-left) */
.shot-animation.reversed .shot-court {
    transform: scaleX(-1);
}

/* Meeple - Rounded & Characterful */
.meeple {
    position: absolute;
    bottom: 20px;
    left: 50px;
    display: flex;
    flex-direction: column;
    align-items: center;
    transition: transform 0.3s ease;
}

.meeple-head {
    width: 18px;
    height: 18px;
    background: #3498db;
    border-radius: 50%;
    margin-bottom: 1px;
    z-index: 2;
}

.meeple-body {
    width: 24px;
    height: 30px;
    background: #3498db;
    border-radius: 8px 8px 6px 6px;
    clip-path: polygon(5% 0%, 95% 0%, 85% 100%, 15% 100%);
    position: relative;
}

.meeple-arms {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    pointer-events: none;
    display: none;
}

.meeple-arms .arm {
    position: absolute;
    width: 7px;
    height: 16px;
    background: inherit;
    border-radius: 4px;
    top: 2px;
}

.meeple-arms .arm:first-child {
    left: -8px;
    transform: rotate(15deg);
    transform-origin: top right;
}

.meeple-arms .arm:last-child {
    right: -8px;
    transform: rotate(-15deg);
    transform-origin: top left;
}

.meeple-legs {
    display: flex;
    gap: 7px;
    margin-top: 1px;
}

.meeple-legs .leg {
    width: 8px;
    height: 18px;
    background: #3498db;
    border-radius: 5px;
}

/* Ground shadow */
.meeple::after {
    content: '';
    position: absolute;
    bottom: -4px;
    left: 50%;
    transform: translateX(-50%);
    width: 28px;
    height: 6px;
    background: radial-gradient(ellipse, rgba(0,0,0,0.25) 0%, transparent 70%);
    border-radius: 50%;
}

/* Player colors */
.meeple.player1 .meeple-head,
.meeple.player1 .meeple-body,
.meeple.player1 .meeple-legs .leg,
.meeple.player1 .meeple-arms .arm {
    background: var(--primary-orange);
    box-shadow: 0 2px 8px rgba(255, 107, 53, 0.4);
}

.meeple.player2 .meeple-head,
.meeple.player2 .meeple-body,
.meeple.player2 .meeple-legs .leg,
.meeple.player2 .meeple-arms .arm {
    background: var(--primary-blue);
    box-shadow: 0 2px 8px rgba(30, 136, 229, 0.4);
}

/* Basketball */
.ball {
    position: absolute;
    width: 18px;
    height: 18px;
    background: linear-gradient(145deg, #ff9800 0%, #f57c00 100%);
    border-radius: 50%;
    bottom: 80px;
    left: 60px;
    box-shadow: 0 3px 10px rgba(0,0,0,0.4), inset -2px -2px 4px rgba(0,0,0,0.2);
    z-index: 10;
}

.ball::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 2px;
    right: 2px;
    height: 2px;
    background: #bf360c;
    transform: translateY(-50%);
}

/* Basket */
.basket {
    position: absolute;
    right: 50px;
    top: 30px;
}

.backboard {
    width: 7px;
    height: 44px;
    background: linear-gradient(90deg, #ecf0f1 0%, #bdc3c7 100%);
    border: 2px solid #95a5a6;
    position: absolute;
    right: 0;
    top: 0;
    border-radius: 2px;
}

.rim {
    width: 32px;
    height: 6px;
    background: linear-gradient(180deg, #e74c3c 0%, #c0392b 100%);
    border-radius: 3px;
    position: absolute;
    right: 7px;
    top: 30px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.3);
}

.net {
    position: absolute;
    right: 12px;
    top: 36px;
    width: 24px;
    height: 20px;
    border-left: 2px dashed rgba(255,255,255,0.8);
    border-right: 2px dashed rgba(255,255,255,0.8);
    border-bottom: 2px dashed rgba(255,255,255,0.8);
    border-radius: 0 0 8px 8px;
}

/* ============================================
   Basic Shot Animation
   ============================================ */

.shot-animation.shooting .ball {
    animation: ball-arc 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

@keyframes ball-arc {
    0% { bottom: 80px; left: 60px; }
    20% { bottom: 130px; left: 100px; }
    40% { bottom: 165px; left: 150px; }
    60% { bottom: 170px; left: 200px; }
    80% { bottom: 155px; left: 240px; }
    100% { bottom: 128px; left: 273px; }
}

/* Made shot - ball drops through */
.shot-animation.made .ball {
    animation: ball-arc 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               ball-drop 0.5s ease-in 1s forwards;
}

@keyframes ball-drop {
    0% { bottom: 128px; left: 273px; }
    30% { bottom: 95px; left: 273px; }
    60% { bottom: 80px; left: 273px; }
    100% { bottom: 20px; left: 273px; }
}

.shot-animation.made .net {
    animation: net-swoosh 0.3s ease-out 1s;
}

@keyframes net-swoosh {
    0%, 100% { transform: scaleY(1); }
    50% { transform: scaleY(1.4); }
}

/* Missed shot - ball bounces off rim */
.shot-animation.missed .ball {
    animation: ball-arc 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               ball-miss 0.6s ease-out 1s forwards;
}

@keyframes ball-miss {
    0% { bottom: 128px; left: 273px; }
    10% { bottom: 133px; left: 265px; }
    25% { bottom: 115px; left: 255px; }
    45% { bottom: 85px; left: 245px; }
    70% { bottom: 45px; left: 235px; }
    100% { bottom: 20px; left: 225px; }
}

/* Swoosh/Clank text */
.shot-animation.made::after {
    content: 'SWOOSH!';
    position: absolute;
    top: 45%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: var(--font-display);
    font-size: 2rem;
    color: var(--success-bright);
    text-shadow: 0 0 20px rgba(63, 185, 80, 0.6), 0 4px 8px rgba(0,0,0,0.5);
    animation: swoosh-text 0.5s ease-out 1.2s forwards;
    letter-spacing: 0.1em;
}

@keyframes swoosh-text {
    0% { transform: translate(-50%, -50%) scale(0); opacity: 0; }
    50% { transform: translate(-50%, -50%) scale(1.2); opacity: 1; }
    100% { transform: translate(-50%, -50%) scale(1); opacity: 1; }
}

.shot-animation.missed::after {
    content: 'CLANK!';
    position: absolute;
    top: 45%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: var(--font-display);
    font-size: 2rem;
    color: var(--danger-red);
    text-shadow: 0 0 20px rgba(218, 54, 51, 0.6), 0 4px 8px rgba(0,0,0,0.5);
    animation: swoosh-text 0.5s ease-out 1.2s forwards;
    letter-spacing: 0.1em;
}

/* ============================================
   Slam Dunk Animation
   ============================================ */

.shot-animation.slam-dunk.shooting .meeple {
    animation: dunk-jump 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

.shot-animation.slam-dunk.shooting .ball {
    animation: dunk-ball 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

@keyframes dunk-jump {
    0% { transform: translateX(0) translateY(0); }
    30% { transform: translateX(80px) translateY(-60px); }
    50% { transform: translateX(140px) translateY(-80px); }
    70% { transform: translateX(180px) translateY(-70px); }
    100% { transform: translateX(200px) translateY(-50px); }
}

@keyframes dunk-ball {
    0% { bottom: 80px; left: 60px; }
    25% { bottom: 130px; left: 120px; }
    50% { bottom: 155px; left: 195px; }
    75% { bottom: 140px; left: 245px; }
    100% { bottom: 128px; left: 273px; }
}

.shot-animation.slam-dunk.made .ball {
    animation: dunk-ball 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               dunk-slam 0.3s ease-in 1s forwards;
}

@keyframes dunk-slam {
    0% { bottom: 128px; left: 273px; }
    40% { bottom: 80px; left: 273px; }
    100% { bottom: 20px; left: 273px; }
}

.shot-animation.slam-dunk.made::after {
    content: 'SLAM!';
}

/* ============================================
   Layup Animation
   ============================================ */

.shot-animation.layup.shooting .meeple {
    animation: layup-run 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

.shot-animation.layup.shooting .ball {
    animation: layup-ball 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

@keyframes layup-run {
    0% { transform: translateX(0); }
    40% { transform: translateX(80px); }
    70% { transform: translateX(140px); }
    100% { transform: translateX(180px); }
}

@keyframes layup-ball {
    0% { bottom: 80px; left: 60px; }
    30% { bottom: 110px; left: 125px; }
    60% { bottom: 140px; left: 200px; }
    80% { bottom: 138px; left: 250px; }
    100% { bottom: 128px; left: 273px; }
}

.shot-animation.layup.made .ball {
    animation: layup-ball 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               ball-drop 0.5s ease-in 1s forwards;
}

.shot-animation.layup.made::after {
    content: 'NICE!';
}

.shot-animation.layup.missed .ball {
    animation: layup-ball 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               ball-miss 0.6s ease-out 1s forwards;
}

.shot-animation.slam-dunk.missed .ball {
    animation: dunk-ball 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               ball-miss 0.6s ease-out 1s forwards;
}

/* ============================================
   Defender Positioning
   ============================================ */

.meeple.offensive {
    left: 50px;
}

.meeple.defender {
    left: 145px;
    bottom: 20px;
}

.meeple.receiver {
    left: 200px;
    bottom: 20px;
    display: none;
}

.shot-animation.passing .meeple.receiver {
    display: block;
}

/* ============================================
   Foul Shot Animation
   ============================================ */

.shot-animation.foul-shot .meeple.defender {
    display: none !important;
}

.shot-animation.foul-shot .meeple.offensive {
    left: 150px;
    bottom: 30px;
}

.shot-animation.foul-shot .ball {
    left: 165px;
    bottom: 70px;
}

.shot-animation.foul-shot.shooting .ball {
    animation: foul-shot-arc 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

@keyframes foul-shot-arc {
    0% { bottom: 70px; left: 165px; }
    30% { bottom: 140px; left: 200px; }
    60% { bottom: 160px; left: 245px; }
    100% { bottom: 128px; left: 273px; }
}

.shot-animation.foul-shot.made .ball {
    animation: foul-shot-arc 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               ball-drop 0.5s ease-in 1s forwards;
}

.shot-animation.foul-shot.missed .ball {
    animation: foul-shot-arc 1s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               ball-miss 0.6s ease-out 1s forwards;
}

/* ============================================
   Defender Challenge Animation
   ============================================ */

.shot-animation.shooting .meeple.defender {
    animation: defender-challenge 1s ease-out forwards;
}

@keyframes defender-challenge {
    0% { transform: translateX(0) translateY(0); }
    30% { transform: translateX(10px) translateY(-40px); }
    60% { transform: translateX(15px) translateY(-50px); }
    100% { transform: translateX(5px) translateY(0); }
}

/* ============================================
   Blocked Shot Animation
   ============================================ */

.shot-animation.blocked .meeple.defender {
    animation: defender-block 1s ease-out forwards;
}

@keyframes defender-block {
    0% { transform: translateY(0) translateX(0); }
    30% { transform: translateY(-75px) translateX(25px); }
    50% { transform: translateY(-90px) translateX(30px); }
    100% { transform: translateY(0) translateX(20px); }
}

.shot-animation.blocked .ball {
    animation: ball-blocked 1.2s ease-out forwards;
}

@keyframes ball-blocked {
    0% { bottom: 80px; left: 60px; }
    25% { bottom: 120px; left: 120px; }
    40% { bottom: 140px; left: 165px; }
    50% { bottom: 130px; left: 175px; }
    100% { bottom: 20px; left: 100px; }
}

.shot-animation.blocked::after {
    content: 'BLOCKED!';
    position: absolute;
    top: 45%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: var(--font-display);
    font-size: 1.8rem;
    color: #ab47bc;
    text-shadow: 0 0 20px rgba(171, 71, 188, 0.6), 0 4px 8px rgba(0,0,0,0.5);
    animation: swoosh-text 0.5s ease-out 0.6s forwards;
}

/* ============================================
   Inside Pass Animation
   ============================================ */

.shot-animation.passing .meeple.offensive {
    animation: none;
}

.shot-animation.passing .meeple.defender {
    animation: defender-reach 1s ease-out forwards;
}

@keyframes defender-reach {
    0% { transform: translateX(0) rotate(0deg); }
    40% { transform: translateX(-50px) rotate(-15deg); }
    60% { transform: translateX(-40px) rotate(-10deg); }
    100% { transform: translateX(-25px) rotate(0deg); }
}

.shot-animation.passing .ball {
    animation: ball-pass 1s ease-out forwards;
}

@keyframes ball-pass {
    0% { bottom: 80px; left: 60px; }
    25% { bottom: 15px; left: 105px; }
    35% { bottom: 15px; left: 125px; }
    50% { bottom: 55px; left: 155px; }
    100% { bottom: 80px; left: 200px; }
}

.shot-animation.passed::after {
    content: 'PASS!';
    position: absolute;
    top: 45%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: var(--font-display);
    font-size: 1.8rem;
    color: #29b6f6;
    text-shadow: 0 0 20px rgba(41, 182, 246, 0.6), 0 4px 8px rgba(0,0,0,0.5);
    animation: swoosh-text 0.5s ease-out 0.8s forwards;
}

/* ============================================
   Interception Animation
   ============================================ */

.shot-animation.intercepted .meeple.defender {
    animation: defender-intercept 1s ease-out forwards;
}

@keyframes defender-intercept {
    0% { transform: translateX(0); }
    40% { transform: translateX(-50px); }
    100% { transform: translateX(-50px); }
}

.shot-animation.intercepted .ball {
    animation: ball-intercepted 1s ease-out forwards;
}

@keyframes ball-intercepted {
    0% { bottom: 80px; left: 60px; }
    40% { bottom: 72px; left: 75px; }
    100% { bottom: 80px; left: 105px; }
}

.shot-animation.intercepted::after {
    content: 'INTERCEPTED!';
    position: absolute;
    top: 45%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: var(--font-display);
    font-size: 1.5rem;
    color: #ff9800;
    text-shadow: 0 0 20px rgba(255, 152, 0, 0.6), 0 4px 8px rgba(0,0,0,0.5);
    animation: swoosh-text 0.5s ease-out 0.6s forwards;
}

/* ============================================
   Steal Animation
   ============================================ */

.shot-animation.stolen .meeple.defender {
    animation: defender-steal 1s ease-out forwards;
}

@keyframes defender-steal {
    0% { transform: translateX(0) rotate(0deg); }
    30% { transform: translateX(-80px) rotate(-15deg); }
    50% { transform: translateX(-90px) rotate(-5deg); }
    100% { transform: translateX(-90px) rotate(0deg); }
}

.shot-animation.stolen .ball {
    animation: ball-stolen 1s ease-out forwards;
}

@keyframes ball-stolen {
    0% { bottom: 80px; left: 60px; }
    30% { bottom: 76px; left: 60px; }
    60% { bottom: 80px; left: 70px; }
    100% { bottom: 80px; left: 70px; }
}

.shot-animation.stolen::after {
    content: 'STOLEN!';
    position: absolute;
    top: 45%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: var(--font-display);
    font-size: 1.8rem;
    color: var(--danger-red);
    text-shadow: 0 0 20px rgba(218, 54, 51, 0.6), 0 4px 8px rgba(0,0,0,0.5);
    animation: swoosh-text 0.5s ease-out 0.6s forwards;
}

/* ============================================
   Defensive Foul Animation
   ============================================ */

.shot-animation.fouled .meeple.defender {
    animation: defender-foul-collision 1.2s ease-out forwards;
}

@keyframes defender-foul-collision {
    0% { transform: translateX(0) translateY(0); }
    20% { transform: translateX(-50px) translateY(-25px); }
    40% { transform: translateX(-65px) translateY(-35px); }
    60% { transform: translateX(-55px) translateY(-25px); }
    80% { transform: translateX(-45px) translateY(0); }
    100% { transform: translateX(-40px) translateY(0); }
}

.shot-animation.fouled::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(255, 235, 59, 0.25);
    animation: foul-flash 0.4s ease-out 0.3s;
    pointer-events: none;
    z-index: 5;
}

@keyframes foul-flash {
    0%, 100% { opacity: 0; }
    50% { opacity: 1; }
}

.shot-animation.fouled.made::after {
    content: 'AND ONE!';
    color: #ffc107;
    text-shadow: 0 0 20px rgba(255, 193, 7, 0.6), 0 4px 8px rgba(0,0,0,0.5);
}

.shot-animation.fouled.missed::after {
    content: 'FOUL! MISS!';
    color: #ffc107;
    text-shadow: 0 0 20px rgba(255, 193, 7, 0.6), 0 4px 8px rgba(0,0,0,0.5);
}

/* ============================================
   Offensive Foul Animation
   ============================================ */

.shot-animation.offensive-foul .meeple.offensive {
    animation: charger-collision 1.2s ease-out forwards;
}

@keyframes charger-collision {
    0% { transform: translateX(0); }
    30% { transform: translateX(85px); }
    50% { transform: translateX(75px) rotate(-15deg); }
    100% { transform: translateX(65px) rotate(0deg); }
}

.shot-animation.offensive-foul .meeple.defender {
    animation: defender-stands-ground 1.2s ease-out forwards;
}

@keyframes defender-stands-ground {
    0% { transform: translateX(0); }
    30% { transform: translateX(0); }
    50% { transform: translateX(12px); }
    100% { transform: translateX(8px); }
}

.shot-animation.offensive-foul .ball {
    animation: ball-loose 1.2s ease-out forwards;
}

@keyframes ball-loose {
    0% { bottom: 80px; left: 60px; }
    30% { bottom: 85px; left: 175px; }
    100% { bottom: 20px; left: 215px; }
}

.shot-animation.offensive-foul::after {
    content: 'CHARGE!';
    position: absolute;
    top: 45%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: var(--font-display);
    font-size: 1.8rem;
    color: var(--danger-red);
    text-shadow: 0 0 20px rgba(218, 54, 51, 0.6), 0 4px 8px rgba(0,0,0,0.5);
    animation: swoosh-text 0.5s ease-out 0.6s forwards;
}

.shot-animation.offensive-foul::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(231, 76, 60, 0.25);
    animation: foul-flash 0.4s ease-out 0.4s;
    pointer-events: none;
    z-index: 5;
}

/* ============================================
   Override animations for slam dunk with defender
   ============================================ */

.shot-animation.slam-dunk.shooting .meeple.defender {
    animation: defender-dunk-challenge 1s ease-out forwards;
}

@keyframes defender-dunk-challenge {
    0% { transform: translateY(0) translateX(0); }
    40% { transform: translateY(-65px) translateX(40px); }
    70% { transform: translateY(-80px) translateX(55px); }
    100% { transform: translateY(0) translateX(40px); }
}

.shot-animation.slam-dunk.blocked .meeple.offensive {
    animation: dunk-jump-blocked 1s ease-out forwards;
}

@keyframes dunk-jump-blocked {
    0% { transform: translateX(0) translateY(0); }
    30% { transform: translateX(70px) translateY(-75px); }
    50% { transform: translateX(95px) translateY(-90px); }
    70% { transform: translateX(95px) translateY(-50px); }
    100% { transform: translateX(85px) translateY(0); }
}

.shot-animation.slam-dunk.blocked .meeple.defender {
    animation: defender-dunk-block 1s ease-out forwards;
}

@keyframes defender-dunk-block {
    0% { transform: translateY(0) translateX(0); }
    30% { transform: translateY(-100px) translateX(35px); }
    50% { transform: translateY(-115px) translateX(45px); }
    100% { transform: translateY(0) translateX(30px); }
}

.shot-animation.slam-dunk.blocked .ball {
    animation: dunk-ball-blocked 1.2s ease-out forwards;
}

@keyframes dunk-ball-blocked {
    0% { bottom: 80px; left: 60px; }
    25% { bottom: 120px; left: 115px; }
    40% { bottom: 140px; left: 170px; }
    50% { bottom: 130px; left: 180px; }
    100% { bottom: 20px; left: 110px; }
}

/* ============================================
   Override animations for layup with defender
   ============================================ */

.shot-animation.layup.shooting .meeple.defender {
    animation: defender-layup-challenge 1s ease-out forwards;
}

@keyframes defender-layup-challenge {
    0% { transform: translateY(0) translateX(0); }
    50% { transform: translateY(-25px) translateX(25px); }
    100% { transform: translateY(0) translateX(15px); }
}

.shot-animation.layup.blocked .meeple.offensive {
    animation: layup-run-blocked 1s ease-out forwards;
}

@keyframes layup-run-blocked {
    0% { transform: translateX(0); }
    40% { transform: translateX(90px); }
    60% { transform: translateX(105px); }
    100% { transform: translateX(105px); }
}

.shot-animation.layup.blocked .meeple.defender {
    animation: defender-layup-block 1s ease-out forwards;
}

@keyframes defender-layup-block {
    0% { transform: translateY(0) translateX(0); }
    30% { transform: translateY(-50px) translateX(20px); }
    50% { transform: translateY(-65px) translateX(30px); }
    100% { transform: translateY(0) translateX(20px); }
}

.shot-animation.layup.blocked .ball {
    animation: layup-ball-blocked 1.2s ease-out forwards;
}

@keyframes layup-ball-blocked {
    0% { bottom: 80px; left: 60px; }
    30% { bottom: 100px; left: 130px; }
    45% { bottom: 120px; left: 170px; }
    55% { bottom: 110px; left: 175px; }
    100% { bottom: 20px; left: 110px; }
}

/* ============================================
   Offensive Rebound Animation
   ============================================ */

.shot-animation.rebounding .meeple.offensive {
    animation: offensive-rebound-jump 1.4s ease-out forwards;
}

@keyframes offensive-rebound-jump {
    0% { transform: translateX(0) translateY(0); }
    25% { transform: translateX(100px) translateY(0); }
    45% { transform: translateX(140px) translateY(-70px); }
    60% { transform: translateX(150px) translateY(-50px); }
    80% { transform: translateX(150px) translateY(-20px); }
    100% { transform: translateX(150px) translateY(0); }
}

.shot-animation.rebounding .meeple.defender {
    animation: defender-rebound-watch 1.4s ease-out forwards;
}

@keyframes defender-rebound-watch {
    0% { transform: translateX(0) translateY(0); }
    30% { transform: translateX(15px) translateY(0); }
    50% { transform: translateX(25px) translateY(-35px); }
    65% { transform: translateX(30px) translateY(-20px); }
    80% { transform: translateX(25px) translateY(-8px); }
    100% { transform: translateX(20px) translateY(0); }
}

.shot-animation.rebounding .ball {
    animation: ball-rebound 1.4s ease-out forwards;
}

@keyframes ball-rebound {
    0% { bottom: 128px; left: 273px; }
    10% { bottom: 133px; left: 265px; }
    25% { bottom: 115px; left: 255px; }
    45% { bottom: 85px; left: 245px; }
    60% { bottom: 90px; left: 230px; }
    75% { bottom: 95px; left: 220px; }
    100% { bottom: 90px; left: 210px; }
}

.shot-animation.rebounding::after {
    content: 'REBOUND!';
    position: absolute;
    top: 45%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: var(--font-display);
    font-size: 1.8rem;
    color: var(--primary-orange);
    text-shadow: 0 0 20px rgba(249, 115, 22, 0.6), 0 4px 8px rgba(0,0,0,0.5);
    animation: swoosh-text 0.5s ease-out 0.8s forwards;
    letter-spacing: 0.1em;
}

/* ============================================
   Combined Pass + Shot Animation
   ============================================ */

.shot-animation.with-pass .meeple.receiver {
    display: block;
}

.shot-animation.with-pass.shooting .ball {
    animation: ball-pass-to-shot 2s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
}

@keyframes ball-pass-to-shot {
    0% { bottom: 80px; left: 60px; }
    10% { bottom: 15px; left: 105px; }
    15% { bottom: 15px; left: 125px; }
    22% { bottom: 55px; left: 165px; }
    30% { bottom: 80px; left: 200px; }
    35% { bottom: 80px; left: 200px; }
    50% { bottom: 130px; left: 220px; }
    65% { bottom: 160px; left: 245px; }
    80% { bottom: 145px; left: 262px; }
    100% { bottom: 128px; left: 273px; }
}

.shot-animation.with-pass.made .ball {
    animation: ball-pass-to-shot 2s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               ball-drop 0.5s ease-in 2s forwards;
}

.shot-animation.with-pass.missed .ball {
    animation: ball-pass-to-shot 2s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards,
               ball-miss 0.6s ease-out 2s forwards;
}

.shot-animation.with-pass.made .net {
    animation: net-swoosh 0.3s ease-out 2s;
}

.shot-animation.with-pass.shooting .meeple.offensive {
    animation: passer-stay 2s ease-out forwards;
}

.shot-animation.with-pass.shooting .meeple.defender {
    animation: defender-stay 2s ease-out forwards;
}

.shot-animation.with-pass.layup.shooting .meeple.defender {
    animation: defender-stay 2s ease-out forwards;
}

@keyframes passer-stay {
    0%, 100% { transform: translateX(0) translateY(0); }
}

@keyframes defender-stay {
    0%, 100% { transform: translateX(0) translateY(0); }
}

.shot-animation.with-pass.fouled .meeple.defender {
    animation: defender-foul-after-pass 2s ease-out forwards;
}

@keyframes defender-foul-after-pass {
    0%, 35% { transform: translateX(0) translateY(0); }
    45% { transform: translateX(15px) translateY(-5px); }
    55% { transform: translateX(30px) translateY(-20px); }
    70% { transform: translateX(25px) translateY(-15px); }
    85% { transform: translateX(15px) translateY(-5px); }
    100% { transform: translateX(0) translateY(0); }
}

.shot-animation.with-pass.fouled::before {
    animation: foul-flash 0.4s ease-out 1.3s;
}

.shot-animation.with-pass .meeple.receiver {
    animation: receiver-catch-and-shoot 2s ease-out forwards;
}

@keyframes receiver-catch-and-shoot {
    0%, 25% { transform: translateY(0); }
    30% { transform: translateY(5px); }
    40% { transform: translateY(0); }
    55% { transform: translateY(-15px); }
    70% { transform: translateY(-20px); }
    85% { transform: translateY(-5px); }
    100% { transform: translateY(0); }
}

/* ============================================
   Alley-Oop (Pass to Slam Dunk)
   ============================================ */

.shot-animation.with-pass.slam-dunk .meeple.defender {
    animation: defender-alley-oop 2s ease-out forwards;
}

@keyframes defender-alley-oop {
    0%, 40% { transform: translateX(0) translateY(0); }
    60% { transform: translateX(0) translateY(-5px); }
    80% { transform: translateX(0) translateY(0); }
    100% { transform: translateX(0) translateY(0); }
}

.shot-animation.with-pass.slam-dunk .meeple.offensive {
    animation: passer-lob 2s ease-out forwards;
}

@keyframes passer-lob {
    0%, 10% { transform: translateY(0); }
    20% { transform: translateY(-8px); }
    35% { transform: translateY(0); }
    100% { transform: translateY(0); }
}

.shot-animation.with-pass.slam-dunk .meeple.receiver {
    animation: alley-oop-receiver 2s ease-out forwards;
}

@keyframes alley-oop-receiver {
    0% { transform: translateY(0) translateX(0); }
    20% { transform: translateY(0) translateX(10px); }
    32% { transform: translateY(-40px) translateX(25px); }
    42% { transform: translateY(-80px) translateX(40px); }
    52% { transform: translateY(-85px) translateX(50px); }
    62% { transform: translateY(-70px) translateX(58px); }
    75% { transform: translateY(-35px) translateX(60px); }
    90% { transform: translateY(-10px) translateX(60px); }
    100% { transform: translateY(0) translateX(60px); }
}

.shot-animation.with-pass.slam-dunk.shooting .ball {
    animation: ball-alley-oop 2s ease-out forwards;
}

@keyframes ball-alley-oop {
    0% { bottom: 80px; left: 60px; }
    15% { bottom: 130px; left: 115px; }
    28% { bottom: 170px; left: 180px; }
    38% { bottom: 175px; left: 230px; }
    48% { bottom: 170px; left: 250px; }
    55% { bottom: 168px; left: 255px; }
    62% { bottom: 145px; left: 268px; }
    68% { bottom: 128px; left: 273px; }
    100% { bottom: 128px; left: 273px; }
}

.shot-animation.with-pass.slam-dunk.made .ball {
    animation: ball-alley-oop 2s ease-out forwards,
               alley-oop-slam 0.25s ease-in 1.35s forwards;
}

@keyframes alley-oop-slam {
    0% { bottom: 128px; left: 273px; }
    50% { bottom: 70px; left: 273px; }
    100% { bottom: 20px; left: 273px; }
}

.shot-animation.with-pass.slam-dunk.missed .ball {
    animation: ball-alley-oop 2s ease-out forwards,
               ball-miss 0.5s ease-out 2s forwards;
}

/* ============================================
   Pass to Layup
   ============================================ */

.shot-animation.with-pass.layup .meeple.receiver {
    animation: receiver-catch-layup 2s ease-out forwards;
}

@keyframes receiver-catch-layup {
    0%, 25% { transform: translateY(0) translateX(0); }
    30% { transform: translateY(3px) translateX(0); }
    45% { transform: translateY(0) translateX(15px); }
    60% { transform: translateY(-20px) translateX(35px); }
    70% { transform: translateY(-25px) translateX(45px); }
    85% { transform: translateY(-10px) translateX(50px); }
    100% { transform: translateY(0) translateX(50px); }
}

.shot-animation.with-pass.layup.shooting .ball {
    animation: ball-pass-to-layup 2s ease-out forwards;
}

@keyframes ball-pass-to-layup {
    0% { bottom: 80px; left: 60px; }
    10% { bottom: 15px; left: 105px; }
    15% { bottom: 15px; left: 125px; }
    22% { bottom: 55px; left: 165px; }
    30% { bottom: 80px; left: 200px; }
    40% { bottom: 80px; left: 210px; }
    55% { bottom: 120px; left: 235px; }
    70% { bottom: 140px; left: 258px; }
    85% { bottom: 135px; left: 268px; }
    100% { bottom: 128px; left: 273px; }
}

.shot-animation.with-pass.layup.made .ball {
    animation: ball-pass-to-layup 2s ease-out forwards,
               ball-drop 0.5s ease-in 2s forwards;
}

.shot-animation.with-pass.layup.missed .ball {
    animation: ball-pass-to-layup 2s ease-out forwards,
               ball-miss 0.6s ease-out 2s forwards;
}

/* ============================================
   Screen Shake on Big Plays
   (ported from V2)
   ============================================ */

@keyframes screen-shake {
    0%, 100% { transform: translate(0, 0); }
    10% { transform: translate(-3px, -2px); }
    20% { transform: translate(3px, 2px); }
    30% { transform: translate(-2px, 3px); }
    40% { transform: translate(2px, -3px); }
    50% { transform: translate(-3px, 1px); }
    60% { transform: translate(3px, -1px); }
    70% { transform: translate(-1px, 3px); }
    80% { transform: translate(1px, -2px); }
    90% { transform: translate(-2px, 1px); }
}

.shot-animation.slam-dunk.made .shot-court,
.shot-animation.blocked .shot-court {
    animation: screen-shake 0.4s ease-out 1.1s;
}

/* Reversed shake - preserve scaleX(-1) so court doesn't flip back during shake */
.shot-animation.reversed.slam-dunk.made .shot-court,
.shot-animation.reversed.blocked .shot-court {
    animation: screen-shake-reversed 0.4s ease-out 1.1s;
}

@keyframes screen-shake-reversed {
    0%, 100% { transform: scaleX(-1) translate(0, 0); }
    10% { transform: scaleX(-1) translate(-3px, -2px); }
    20% { transform: scaleX(-1) translate(3px, 2px); }
    30% { transform: scaleX(-1) translate(-2px, 3px); }
    40% { transform: scaleX(-1) translate(2px, -3px); }
    50% { transform: scaleX(-1) translate(-3px, 1px); }
    60% { transform: scaleX(-1) translate(3px, -1px); }
    70% { transform: scaleX(-1) translate(-1px, 3px); }
    80% { transform: scaleX(-1) translate(1px, -2px); }
    90% { transform: scaleX(-1) translate(-2px, 1px); }
}

/* ============================================
   Impact Burst on Dunks (ported from V2)
   ============================================ */

.shot-animation.slam-dunk.made .basket::before {
    content: '';
    position: absolute;
    top: 20px;
    left: -20px;
    width: 60px;
    height: 60px;
    background: radial-gradient(circle, rgba(255,255,255,0.8) 0%, rgba(255,107,53,0.4) 30%, transparent 70%);
    border-radius: 50%;
    animation: impact-burst 0.4s ease-out 1.1s forwards;
    opacity: 0;
}

@keyframes impact-burst {
    0% { transform: scale(0.3); opacity: 0; }
    30% { transform: scale(1.2); opacity: 1; }
    100% { transform: scale(1.5); opacity: 0; }
}

/* ============================================
   Block Burst Effect (ported from V2)
   ============================================ */

.shot-animation.blocked .shot-court::before {
    content: '';
    position: absolute;
    top: 40%;
    left: 50%;
    width: 80px;
    height: 80px;
    background: radial-gradient(circle, rgba(171, 71, 188, 0.6) 0%, transparent 60%);
    border-radius: 50%;
    transform: translate(-50%, -50%) scale(0);
    animation: block-burst 0.5s ease-out 0.5s forwards;
    z-index: 15;
    pointer-events: none;
}

@keyframes block-burst {
    0% { transform: translate(-50%, -50%) scale(0); opacity: 1; }
    50% { transform: translate(-50%, -50%) scale(1.5); opacity: 0.8; }
    100% { transform: translate(-50%, -50%) scale(2); opacity: 0; }
}

/* ============================================
   Swish Glow Effect (ported from V2)
   ============================================ */

.shot-animation.made .basket {
    animation: swish-glow 0.6s ease-out 1s;
}

@keyframes swish-glow {
    0% { filter: drop-shadow(0 0 0 transparent); }
    50% { filter: drop-shadow(0 0 20px rgba(63, 185, 80, 0.8)); }
    100% { filter: drop-shadow(0 0 0 transparent); }
}

/* ============================================
   Ball Trail Effect (ported from V2)
   ============================================ */

.shot-animation.shooting .ball::after {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: inherit;
    opacity: 0.3;
    animation: ball-trail 0.15s ease-out infinite;
}

/* Hide trail once ball stops (made/missed/passed states) */
.shot-animation.made .ball::after,
.shot-animation.missed .ball::after,
.shot-animation.passed .ball::after,
.shot-animation.blocked .ball::after,
.shot-animation.intercepted .ball::after,
.shot-animation.stolen .ball::after,
.shot-animation.rebounding .ball::after {
    animation: none;
    opacity: 0;
}

@keyframes ball-trail {
    0% { transform: scale(0.9); opacity: 0.3; }
    100% { transform: scale(0.4); opacity: 0; }
}

/* ============================================
   Enhanced Net Animation (ported from V2)
   ============================================ */

.shot-animation.made .net {
    animation: net-swoosh-enhanced 0.5s ease-out 1s;
    transform-origin: top center;
}

@keyframes net-swoosh-enhanced {
    0% { transform: scaleY(1) rotate(0deg); }
    25% { transform: scaleY(1.5) rotate(5deg); }
    50% { transform: scaleY(1.3) rotate(-3deg); }
    75% { transform: scaleY(1.2) rotate(2deg); }
    100% { transform: scaleY(1) rotate(0deg); }
}

/* ============================================
   Dust Cloud on Landing
   ============================================ */

@keyframes dust-puff {
    0% { transform: translateX(-50%) scale(0.3); opacity: 0.6; }
    100% { transform: translateX(-50%) scale(1.5); opacity: 0; }
}

.shot-animation.slam-dunk.made .meeple.offensive::before,
.shot-animation.rebounding .meeple.offensive::before {
    content: '';
    position: absolute;
    bottom: -6px;
    left: 50%;
    width: 30px;
    height: 10px;
    background: radial-gradient(ellipse, rgba(180,160,130,0.5) 0%, transparent 70%);
    border-radius: 50%;
    animation: dust-puff 0.5s ease-out 1.1s forwards;
    opacity: 0;
}

/* ============================================
   Motion Lines (speed lines behind driving meeples)
   ============================================ */

@keyframes speed-lines {
    0% { opacity: 0; width: 0; }
    30% { opacity: 0.5; width: 20px; }
    100% { opacity: 0; width: 35px; }
}

.shot-animation.layup.shooting .meeple.offensive::after,
.shot-animation.slam-dunk.shooting .meeple.offensive::after {
    content: '';
    position: absolute;
    left: -30px;
    top: 50%;
    height: 3px;
    background: repeating-linear-gradient(
        90deg,
        rgba(255,255,255,0.4) 0px,
        rgba(255,255,255,0.4) 6px,
        transparent 6px,
        transparent 10px
    );
    border-radius: 2px;
    animation: speed-lines 0.6s ease-out 0.2s forwards;
    opacity: 0;
    pointer-events: none;
}

/* ============================================
   Score Flash (golden pulse on scoreboard)
   ============================================ */

@keyframes score-flash {
    0% { box-shadow: 0 0 0 rgba(255, 193, 7, 0); }
    50% { box-shadow: 0 0 20px rgba(255, 193, 7, 0.6); }
    100% { box-shadow: 0 0 0 rgba(255, 193, 7, 0); }
}

.score-box.score-flash-active {
    animation: score-flash 0.6s ease-out;
}

/* ============================================
   Spark Burst (JS-driven particles)
   ============================================ */

.spark-particle {
    position: absolute;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    pointer-events: none;
    z-index: 20;
}

/* ============================================
   Mini Confetti (JS-driven particles)
   ============================================ */

.mini-confetti-piece {
    position: absolute;
    width: 6px;
    height: 10px;
    pointer-events: none;
    z-index: 20;
}

/* ============================================
   Fouled Defense Animations
   (When Def Foul counter is used against Block/Steal/Intercept)
   ============================================ */

/* Fouled Block - block attempt that draws a foul */
.shot-animation.fouled-block .meeple.defender {
    animation: defender-fouled-block 1.8s ease-out forwards;
}

@keyframes defender-fouled-block {
    0% { transform: translateX(0) translateY(0); }
    30% { transform: translateX(-25px) translateY(-75px); }
    50% { transform: translateX(-25px) translateY(-90px); }
    70% { transform: translateX(-40px) translateY(-50px); }
    100% { transform: translateX(-45px) translateY(0); }
}

/* Ball bounces back to shooter on fouled block */
.shot-animation.fouled-block .ball {
    animation: ball-fouled-block 1.8s ease-out forwards;
}

@keyframes ball-fouled-block {
    0% { transform: translate(0, 0); }
    40% { transform: translate(-60px, -80px); }
    60% { transform: translate(-40px, -60px); }
    100% { transform: translate(-20px, -20px); }
}

/* Fouled Steal - steal attempt that draws a foul */
.shot-animation.fouled-steal .meeple.defender {
    animation: defender-fouled-steal 1.8s ease-out forwards;
}

@keyframes defender-fouled-steal {
    0% { transform: translateX(0) translateY(0) rotate(0deg); }
    30% { transform: translateX(-70px) translateY(-10px) rotate(-15deg); }
    50% { transform: translateX(-80px) translateY(-5px) rotate(-20deg); }
    70% { transform: translateX(-60px) translateY(5px) rotate(-10deg); }
    100% { transform: translateX(-50px) translateY(0) rotate(0deg); }
}

/* Fouled Intercept - similar to steal but during pass */
.shot-animation.fouled-intercept .meeple.defender {
    animation: defender-fouled-intercept 1.8s ease-out forwards;
}

@keyframes defender-fouled-intercept {
    0% { transform: translateX(0) translateY(0); }
    40% { transform: translateX(-45px) translateY(-10px); }
    60% { transform: translateX(-55px) translateY(0); }
    100% { transform: translateX(-40px) translateY(0); }
}

/* Yellow flash for all fouled defense types */
.shot-animation.fouled-block::before,
.shot-animation.fouled-steal::before,
.shot-animation.fouled-intercept::before {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(255, 235, 59, 0.25);
    animation: foul-flash 0.4s ease-out 0.8s;
    pointer-events: none;
    z-index: 100;
}

/* Result text for fouled defense - "FOULED!" */
.shot-animation.fouled-block::after,
.shot-animation.fouled-steal::after,
.shot-animation.fouled-intercept::after {
    content: 'FOULED!';
    position: absolute;
    top: 45%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0);
    font-family: var(--font-display);
    font-size: 1.8rem;
    color: #ffc107;
    text-shadow: 0 0 20px rgba(255, 193, 7, 0.6), 0 4px 8px rgba(0,0,0,0.5);
    animation: swoosh-text 0.5s ease-out 1.0s forwards;
    letter-spacing: 0.1em;
}
