/* ==========================================================================
   SBS SMASH CINEMATIC
   Busta Bear / Don Buzzkill "bat through the screen" knockout sequence.
   Replaces the previously dead classes:
     .busta-smash-lunge  -> .sbs-smash-lunge
     .sbs-violent-shake  -> .sbs-smash-body-shake
   ========================================================================== */

/* --------------------------------------------------------------------------
   Stage + faction theming
   --sbs-smash-accent / --sbs-smash-accent-rgb are set inline by the JS
   so a single stylesheet serves both Busta Bear (red) and Don Buzzkill (yellow).
   -------------------------------------------------------------------------- */
.sbs-smash-stage {
    position: fixed;
    inset: 0;
    z-index: 10010;
    overflow: hidden;
    pointer-events: none;
    opacity: 0;
    contain: strict;
}

.sbs-smash-stage.is-armed {
    opacity: 1;
}

.sbs-smash-stage.is-click-block {
    pointer-events: auto;
    cursor: not-allowed;
}

/* Vignette + hard colour wash that closes in as the boss winds up */
.sbs-smash-vignette {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(circle at 50% 58%, transparent 18%, rgba(0, 0, 0, 0.55) 52%, rgba(0, 0, 0, 0.94) 100%),
        radial-gradient(circle at 50% 58%, rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 0) 10%, rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 0.35) 100%);
    opacity: 0;
    transition: opacity 220ms ease-out;
}

.sbs-smash-stage.is-winding .sbs-smash-vignette {
    opacity: 1;
}

.sbs-smash-stage.is-impacting .sbs-smash-vignette {
    animation: sbsSmashVignetteHit 620ms cubic-bezier(0.2, 0.9, 0.3, 1) forwards;
}

/* --------------------------------------------------------------------------
   3D scene
   A single perspective root drives every Z-axis move so the lunge genuinely
   travels toward the camera rather than just scaling up.
   -------------------------------------------------------------------------- */
.sbs-smash-scene {
    position: absolute;
    inset: 0;
    perspective: 900px;
    perspective-origin: 50% 60%;
    transform-style: preserve-3d;
    display: flex;
    align-items: flex-end;
    justify-content: center;
}

.sbs-smash-scene.is-lunging {
    animation: sbsSmashDollyIn 520ms cubic-bezier(0.55, 0, 0.2, 1) forwards;
}

/* --------------------------------------------------------------------------
   Boss sprite rig
   -------------------------------------------------------------------------- */
.sbs-smash-boss-wrap {
    position: relative;
    transform-style: preserve-3d;
    will-change: transform, opacity;
    transform: translate3d(0, 0, -1400px) scale(0.55);
    opacity: 0;
}

.sbs-smash-stage.is-winding .sbs-smash-boss-wrap {
    animation: sbsSmashBossWindup 760ms cubic-bezier(0.34, 1.4, 0.5, 1) forwards;
}

/* The anticipation pull-back, then the explosive lunge */
.sbs-smash-stage.is-lunging .sbs-smash-boss-wrap {
    animation:
        sbsSmashBossLunge 520ms cubic-bezier(0.1, 0.85, 0.2, 1) forwards,
        sbsSmashBossImpact 900ms cubic-bezier(0.16, 1, 0.3, 1) 520ms forwards;
}

.sbs-smash-boss-img {
    display: block;
    height: min(78vh, 640px);
    width: auto;
    max-width: 92vw;
    object-fit: contain;
    transform-style: preserve-3d;
    will-change: transform, filter;
    transform: translateZ(0);
    filter: drop-shadow(0 0 40px rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 0.75));
}

/* Ghost copies trailing the sprite sell the speed of the lunge */
.sbs-smash-boss-ghost {
    position: absolute;
    inset: 0;
    height: min(78vh, 640px);
    width: 100%;
    object-fit: contain;
    opacity: 0;
    pointer-events: none;
    will-change: transform, opacity, filter;
    filter: blur(6px) brightness(1.6) saturate(1.4);
}

.sbs-smash-stage.is-winding .sbs-smash-boss-ghost {
    animation: sbsSmashGhostWindup 760ms ease-out forwards;
}

.sbs-smash-stage.is-lunging .sbs-smash-boss-ghost {
    animation: sbsSmashGhostLunge 520ms cubic-bezier(0.1, 0.85, 0.2, 1) forwards;
}

.sbs-smash-boss-ghost.is-ghost-2 {
    animation-delay: 0ms;
}
.sbs-smash-boss-ghost.is-ghost-3 {
    animation-delay: 40ms;
    filter: blur(14px) brightness(1.9) saturate(1.7);
}

/* --------------------------------------------------------------------------
   Bat rig
   There is no bat sprite in assets/images, so the bat is built from CSS:
   a tapered handle plus a barrel, parented to the boss so it inherits the lunge.
   transform-origin is the grip; every swing is a pure rotation about that grip.
   -------------------------------------------------------------------------- */
.sbs-smash-bat {
    position: absolute;
    left: 50%;
    bottom: 26%;
    width: 0;
    height: 0;
    transform-style: preserve-3d;
    transform-origin: 0 50%;
    transform: rotate(-150deg);
    will-change: transform;
}

.sbs-smash-bat-part {
    position: absolute;
    left: 0;
    transform-origin: 0 50%;
    border-radius: 2px;
}

.sbs-smash-bat-handle {
    width: 34vmin;
    max-width: 260px;
    height: 12px;
    top: -6px;
    background: linear-gradient(180deg, #8a5a2b 0%, #6b431d 55%, #3d2411 100%);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22);
}

/* Barrel widens away from the grip to give the club its taper */
.sbs-smash-bat-barrel {
    width: 30vmin;
    max-width: 232px;
    height: 30px;
    top: -15px;
    left: 32vmin;
    max-left: 248px;
    background: linear-gradient(180deg, #b4763c 0%, #8a5a2b 48%, #5a3718 100%);
    box-shadow:
        inset 0 2px 0 rgba(255, 255, 255, 0.28),
        inset 0 -2px 0 rgba(0, 0, 0, 0.45),
        0 0 24px rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 0.55);
    border-radius: 3px 40% 40% 3px / 3px 26% 26% 3px;
}

.sbs-smash-bat-tape {
    width: 22px;
    height: 32px;
    top: -16px;
    left: 46vmin;
    max-left: 356px;
    background: repeating-linear-gradient(45deg, #111 0 6px, #2a2a2a 6px 12px);
    border-radius: 2px;
    opacity: 0.9;
}

/* Windup: cock the bat back over the shoulder */
.sbs-smash-stage.is-winding .sbs-smash-bat {
    animation: sbsSmashBatWindup 760ms cubic-bezier(0.34, 1.3, 0.5, 1) forwards;
}

/* Swing: fast rotational arc with a violent overshoot at contact */
.sbs-smash-stage.is-lunging .sbs-smash-bat {
    animation:
        sbsSmashBatSwing 300ms cubic-bezier(0.6, 0, 0.9, 0.4) forwards,
        sbsSmashBatFollow 620ms cubic-bezier(0.2, 1, 0.35, 1) 300ms forwards;
}

/* --------------------------------------------------------------------------
   Impact: flash, cracks, shards
   -------------------------------------------------------------------------- */
.sbs-smash-flash {
    position: absolute;
    inset: 0;
    background: #fff;
    opacity: 0;
    mix-blend-mode: screen;
}

.sbs-smash-stage.is-impacting .sbs-smash-flash {
    animation: sbsSmashFlash 460ms cubic-bezier(0.1, 0.8, 0.2, 1) forwards;
}

/* Radial crack web, drawn with repeating conic gradients so it costs no assets */
.sbs-smash-cracks {
    position: absolute;
    inset: -20%;
    opacity: 0;
    background:
        repeating-conic-gradient(from 0deg at 50% 55%,
            rgba(255, 255, 255, 0.85) 0deg 0.35deg,
            transparent 0.35deg 4.2deg),
        repeating-conic-gradient(from 1.9deg at 50% 55%,
            rgba(0, 0, 0, 0.6) 0deg 0.28deg,
            transparent 0.28deg 7.4deg);
    -webkit-mask-image: radial-gradient(circle at 50% 55%, #000 4%, rgba(0, 0, 0, 0.75) 34%, transparent 74%);
    mask-image: radial-gradient(circle at 50% 55%, #000 4%, rgba(0, 0, 0, 0.75) 34%, transparent 74%);
}

.sbs-smash-stage.is-impacting .sbs-smash-cracks {
    animation: sbsSmashCrackBurst 780ms cubic-bezier(0.1, 0.8, 0.25, 1) forwards;
}

/* Shockwave ring pushing outward from the point of contact */
.sbs-smash-ring {
    position: absolute;
    left: 50%;
    top: 55%;
    width: 40vmax;
    height: 40vmax;
    margin: -20vmax 0 0 -20vmax;
    border-radius: 50%;
    border: 6px solid rgba(255, 255, 255, 0.95);
    box-shadow: 0 0 60px 14px rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 0.9);
    opacity: 0;
    will-change: transform, opacity;
}

.sbs-smash-stage.is-impacting .sbs-smash-ring {
    animation: sbsSmashRingBurst 700ms cubic-bezier(0.1, 0.85, 0.2, 1) forwards;
}

.sbs-smash-stage.is-impacting .sbs-smash-ring.is-ring-2 {
    animation-name: sbsSmashRingBurstSoft;
    animation-delay: 90ms;
}

/* Glass shards flung outward; JS writes --sx/--sy/--rot per shard */
.sbs-smash-shard {
    position: absolute;
    left: 50%;
    top: 55%;
    width: 26px;
    height: 26px;
    margin: -13px 0 0 -13px;
    opacity: 0;
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.15));
    clip-path: polygon(50% 0%, 100% 38%, 78% 100%, 12% 82%);
    will-change: transform, opacity;
}

.sbs-smash-stage.is-impacting .sbs-smash-shard {
    animation: sbsSmashShardFly 900ms cubic-bezier(0.12, 0.7, 0.3, 1) forwards;
    animation-delay: var(--shard-delay, 0ms);
}

/* --------------------------------------------------------------------------
   KO stamp + caption
   -------------------------------------------------------------------------- */
.sbs-smash-ko {
    position: absolute;
    left: 50%;
    top: 46%;
    transform: translate(-50%, -50%) rotate(-14deg) scale(0.2);
    font-family: Impact, "Arial Black", sans-serif;
    font-size: clamp(72px, 20vw, 240px);
    line-height: 0.85;
    letter-spacing: 0.04em;
    color: #fff;
    -webkit-text-stroke: 4px #000;
    text-shadow:
        0 0 26px rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 1),
        0 10px 0 rgba(0, 0, 0, 0.85);
    opacity: 0;
    white-space: nowrap;
}

.sbs-smash-stage.is-impacting .sbs-smash-ko {
    animation: sbsSmashStamp 720ms cubic-bezier(0.2, 1.5, 0.4, 1) 120ms forwards;
}

.sbs-smash-caption {
    position: absolute;
    left: 50%;
    top: 66%;
    transform: translateX(-50%);
    width: min(92vw, 760px);
    text-align: center;
    font-family: "JBMono", ui-monospace, monospace;
    font-size: clamp(12px, 2.1vw, 20px);
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: #fff;
    text-shadow: 0 0 18px rgba(0, 0, 0, 0.95), 0 2px 0 #000;
    padding: 0 16px;
    opacity: 0;
}

.sbs-smash-stage.is-impacting .sbs-smash-caption {
    animation: sbsSmashCaptionIn 900ms cubic-bezier(0.2, 1, 0.3, 1) 460ms forwards;
}

.sbs-smash-stage.is-outro .sbs-smash-caption {
    animation: sbsSmashCaptionOut 400ms ease-in forwards;
}

/* --------------------------------------------------------------------------
   Body-level effects
   Applied to <body> so the whole page reacts, not just the overlay.
   -------------------------------------------------------------------------- */
.sbs-smash-body-shake {
    animation: sbsSmashShakeBody 620ms cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

.sbs-smash-body-chroma {
    animation: sbsSmashChromaSplit 560ms steps(1, end) both;
}

/* Radial smear that suggests the camera being hit */
.sbs-smash-body-zoom {
    animation: sbsSmashZoomPunch 620ms cubic-bezier(0.2, 0.9, 0.25, 1) both;
}

/* --------------------------------------------------------------------------
   Keyframes
   -------------------------------------------------------------------------- */
@keyframes sbsSmashBossWindup {
    0% {
        transform: translate3d(0, 6vh, -1400px) scale(0.55) rotateX(6deg);
        opacity: 0;
    }
    38% {
        opacity: 1;
    }
    62% {
        transform: translate3d(-1.5%, -1vh, -980px) scale(0.74) rotateX(-4deg);
        opacity: 1;
    }
    100% {
        transform: translate3d(-2%, 1vh, -760px) scale(0.8) rotateX(-9deg);
        opacity: 1;
    }
}

@keyframes sbsSmashBossLunge {
    0% {
        transform: translate3d(-2%, 1vh, -760px) scale(0.8) rotateX(-9deg);
    }
    38% {
        transform: translate3d(0.5%, -4vh, 180px) scale(1.85) rotateX(5deg);
    }
    100% {
        transform: translate3d(1.5%, -9vh, 420px) scale(2.45) rotateX(11deg);
    }
}

/* Contact: squash hard on impact, then relax while the boss holds the pose */
@keyframes sbsSmashBossImpact {
    0% {
        transform: translate3d(1.5%, -9vh, 420px) scale(2.45, 2.45) rotateX(11deg);
    }
    18% {
        transform: translate3d(1.2%, -8vh, 380px) scale(2.72, 2.12) rotateX(9deg);
    }
    46% {
        transform: translate3d(1.4%, -8.6vh, 400px) scale(2.5, 2.46) rotateX(10.5deg);
    }
    100% {
        transform: translate3d(1.4%, -8.6vh, 400px) scale(2.5, 2.46) rotateX(10.5deg);
    }
}

@keyframes sbsSmashGhostWindup {
    0% {
        opacity: 0;
        transform: translate3d(0, 0, -1400px) scale(0.55);
    }
    100% {
        opacity: 0.16;
        transform: translate3d(-2.5%, 1.5vh, -700px) scale(0.82);
    }
}

@keyframes sbsSmashGhostLunge {
    0% {
        opacity: 0.16;
        transform: translate3d(-2.5%, 1.5vh, -700px) scale(0.82);
    }
    30% {
        opacity: 0.42;
        transform: translate3d(2.5%, -12vh, 320px) scale(2.2);
    }
    100% {
        opacity: 0;
        transform: translate3d(7%, -26vh, 620px) scale(2.9);
    }
}

@keyframes sbsSmashBatWindup {
    0% {
        transform: rotate(-150deg) translateZ(-120px);
    }
    55% {
        transform: rotate(-196deg) translateZ(-60px);
    }
    100% {
        transform: rotate(-214deg) translateZ(0);
    }
}

/* The swing itself is deliberately short and violent */
@keyframes sbsSmashBatSwing {
    0% {
        transform: rotate(-214deg) translateZ(0);
    }
    55% {
        transform: rotate(-92deg) translateZ(180px);
    }
    100% {
        transform: rotate(-38deg) translateZ(260px);
    }
}

/* Follow-through drifts past the camera and settles */
@keyframes sbsSmashBatFollow {
    0% {
        transform: rotate(-38deg) translateZ(260px);
    }
    30% {
        transform: rotate(-12deg) translateZ(320px);
    }
    100% {
        transform: rotate(6deg) translateZ(300px);
    }
}

@keyframes sbsSmashDollyIn {
    0% {
        transform: scale(1);
        filter: blur(0px);
    }
    100% {
        transform: scale(1.08);
        filter: blur(1.5px);
    }
}

@keyframes sbsSmashFlash {
    0% {
        opacity: 0;
    }
    8% {
        opacity: 1;
    }
    22% {
        opacity: 0.85;
    }
    40% {
        opacity: 0.22;
    }
    62% {
        opacity: 0.5;
    }
    100% {
        opacity: 0;
    }
}

@keyframes sbsSmashCrackBurst {
    0% {
        opacity: 0;
        transform: scale(0.18) rotate(-4deg);
    }
    14% {
        opacity: 1;
        transform: scale(0.72) rotate(0deg);
    }
    55% {
        opacity: 0.5;
        transform: scale(1.06) rotate(1.5deg);
    }
    100% {
        opacity: 0;
        transform: scale(1.3) rotate(3deg);
    }
}

@keyframes sbsSmashRingBurst {
    0% {
        opacity: 0;
        transform: scale(0.06);
        border-width: 14px;
    }
    12% {
        opacity: 1;
        transform: scale(0.24);
    }
    100% {
        opacity: 0;
        transform: scale(2.4);
        border-width: 1px;
    }
}

@keyframes sbsSmashRingBurstSoft {
    0% {
        opacity: 0;
        transform: scale(0.04);
        border-width: 8px;
    }
    20% {
        opacity: 0.7;
        transform: scale(0.2);
    }
    100% {
        opacity: 0;
        transform: scale(1.9);
        border-width: 1px;
    }
}

@keyframes sbsSmashShardFly {
    0% {
        opacity: 0;
        transform: translate3d(0, 0, 0) rotate(0deg) scale(0.3);
    }
    10% {
        opacity: 1;
        transform: translate3d(calc(var(--sx) * 0.12), calc(var(--sy) * 0.12), 120px) rotate(60deg) scale(1);
    }
    100% {
        opacity: 0;
        transform: translate3d(var(--sx), var(--sy), 420px) rotate(var(--rot)) scale(0.7);
    }
}

@keyframes sbsSmashStamp {
    0% {
        opacity: 0;
        transform: translate(-50%, -50%) rotate(-32deg) scale(2.6);
    }
    22% {
        opacity: 1;
        transform: translate(-50%, -50%) rotate(-14deg) scale(0.94);
    }
    38% {
        transform: translate(-50%, -50%) rotate(-14deg) scale(1.06);
    }
    62% {
        transform: translate(-50%, -50%) rotate(-14deg) scale(1);
    }
    80% {
        opacity: 1;
    }
    100% {
        opacity: 0.9;
        transform: translate(-50%, -50%) rotate(-14deg) scale(1.02);
    }
}

@keyframes sbsSmashCaptionIn {
    0% {
        opacity: 0;
        transform: translateX(-50%) translateY(22px);
        letter-spacing: 0.5em;
    }
    100% {
        opacity: 1;
        transform: translateX(-50%) translateY(0);
        letter-spacing: 0.14em;
    }
}

@keyframes sbsSmashCaptionOut {
    0% {
        opacity: 1;
    }
    100% {
        opacity: 0;
        transform: translateX(-50%) translateY(-14px);
    }
}

/* Multi-frequency shake: high-frequency jitter decaying into a low lurch */
@keyframes sbsSmashShakeBody {
    0% {
        transform: translate3d(0, 0, 0) rotate(0deg);
    }
    8% {
        transform: translate3d(-22px, 12px, 0) rotate(-1.1deg);
    }
    16% {
        transform: translate3d(19px, -15px, 0) rotate(0.9deg);
    }
    24% {
        transform: translate3d(-16px, -9px, 0) rotate(-0.7deg);
    }
    33% {
        transform: translate3d(13px, 11px, 0) rotate(0.55deg);
    }
    43% {
        transform: translate3d(-10px, 7px, 0) rotate(-0.4deg);
    }
    54% {
        transform: translate3d(7px, -6px, 0) rotate(0.28deg);
    }
    66% {
        transform: translate3d(-5px, 4px, 0) rotate(-0.18deg);
    }
    78% {
        transform: translate3d(3px, -2px, 0) rotate(0.1deg);
    }
    100% {
        transform: translate3d(0, 0, 0) rotate(0deg);
    }
}

/* Hard-stepped RGB split, like a broken CRT taking the hit */
@keyframes sbsSmashChromaSplit {
    0% {
        filter: none;
        transform: translate3d(0, 0, 0);
    }
    10% {
        filter: drop-shadow(9px 0 0 rgba(255, 0, 48, 0.95)) drop-shadow(-9px 0 0 rgba(0, 210, 255, 0.95));
        transform: translate3d(-6px, 3px, 0);
    }
    24% {
        filter: drop-shadow(-14px 0 0 rgba(255, 0, 48, 0.9)) drop-shadow(14px 0 0 rgba(0, 210, 255, 0.9));
        transform: translate3d(8px, -5px, 0);
    }
    40% {
        filter: drop-shadow(9px 0 0 rgba(255, 0, 48, 0.7)) drop-shadow(-9px 0 0 rgba(0, 210, 255, 0.7));
        transform: translate3d(-5px, 3px, 0);
    }
    58% {
        filter: drop-shadow(5px 0 0 rgba(255, 0, 48, 0.45)) drop-shadow(-5px 0 0 rgba(0, 210, 255, 0.45));
        transform: translate3d(3px, -2px, 0);
    }
    78% {
        filter: drop-shadow(2px 0 0 rgba(255, 0, 48, 0.22)) drop-shadow(-2px 0 0 rgba(0, 210, 255, 0.22));
        transform: translate3d(-1px, 1px, 0);
    }
    100% {
        filter: none;
        transform: translate3d(0, 0, 0);
    }
}

@keyframes sbsSmashZoomPunch {
    0% {
        transform: scale(1);
    }
    10% {
        transform: scale(1.035);
    }
    26% {
        transform: scale(0.985);
    }
    100% {
        transform: scale(1);
    }
}

@keyframes sbsSmashVignetteHit {
    0% {
        opacity: 1;
        background:
            radial-gradient(circle at 50% 58%, transparent 18%, rgba(0, 0, 0, 0.55) 52%, rgba(0, 0, 0, 0.94) 100%),
            radial-gradient(circle at 50% 58%, rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 0.35) 0%, rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 0.75) 100%);
    }
    100% {
        opacity: 1;
        background:
            radial-gradient(circle at 50% 58%, transparent 4%, rgba(0, 0, 0, 0.7) 34%, rgba(0, 0, 0, 0.97) 100%),
            radial-gradient(circle at 50% 58%, rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 0.8) 0%, rgba(var(--sbs-smash-accent-rgb, 239, 68, 68), 0.95) 100%);
    }
}

/* --------------------------------------------------------------------------
   Reduced motion
   Keep the narrative beats (stage in, KO, caption, logout) but drop the
   violent transform work so the sequence stays usable and non-nauseating.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .sbs-smash-scene.is-lunging,
    .sbs-smash-body-shake,
    .sbs-smash-body-chroma,
    .sbs-smash-body-zoom,
    .sbs-smash-stage.is-impacting .sbs-smash-cracks,
    .sbs-smash-stage.is-impacting .sbs-smash-shard,
    .sbs-smash-stage.is-impacting .sbs-smash-ring,
    .sbs-smash-stage.is-lunging .sbs-smash-boss-ghost,
    .sbs-smash-stage.is-winding .sbs-smash-boss-ghost {
        animation: none !important;
    }

    .sbs-smash-body-shake,
    .sbs-smash-body-chroma,
    .sbs-smash-body-zoom {
        transform: none !important;
        filter: none !important;
    }

    .sbs-smash-stage.is-winding .sbs-smash-boss-wrap {
        transform: translate3d(0, 0, 0) scale(0.9) !important;
        opacity: 1 !important;
    }

    .sbs-smash-stage.is-lunging .sbs-smash-boss-wrap {
        transform: translate3d(0, -4vh, 0) scale(1.15) !important;
        opacity: 1 !important;
    }

    .sbs-smash-bat {
        transition: transform 200ms ease-out !important;
    }

    .sbs-smash-boss-ghost {
        display: none !important;
    }

    .sbs-smash-stage.is-impacting .sbs-smash-ko,
    .sbs-smash-stage.is-impacting .sbs-smash-caption {
        animation-duration: 200ms !important;
        animation-delay: 0ms !important;
    }
}