/*
 * Signature animations. Same visual identity as the brand doc's reference CSS,
 * re-implemented to honor the standing perf/a11y constraints:
 *   - the looping hot-streak glow animates OPACITY + TRANSFORM only (no per-frame
 *     text-shadow churn) via a blurred glow layer;
 *   - reward/error animations are ONE-SHOT (never looped) and confined to small
 *     elements;
 *   - all flashing stays well under 3/sec;
 *   - prefers-reduced-motion swaps every animation for a STATIC variant that still
 *     conveys the same state (no dropped feedback).
 *
 * Class lifecycle is owned by ui/animations.ts, which clears state classes before
 * a recycled button node is reused (no stale success color).
 */

/* ============================================================
 * Logo "x" state machine — idle spin / correct flash / error shatter
 * ============================================================ */

@keyframes logo-idle-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* Idle: slow continuous rotation (transform only). Phase 4 will speed this up as
   the per-question timer drains. */
.logo-operator.state-idle {
    animation: logo-idle-spin 10s linear infinite;
}

@keyframes logo-correct {
    0%   { transform: scale(1);    color: var(--text-streak); }
    25%  { transform: scale(1.45); color: var(--color-success); }
    100% { transform: scale(1);    color: var(--text-streak); }
}

/* Correct: rapid scale-up + success flash; rotation pauses (idle class removed). */
.logo-operator.state-correct {
    animation: logo-correct var(--dur-flash) var(--ease-pop);
}

@keyframes visceral-shatter {
    0%   { transform: translateX(0)    skewX(0deg);   color: var(--text-primary); }
    20%  { transform: translateX(-4px) skewX(-12deg); color: var(--color-error);
           text-shadow: 2px 0 var(--text-streak), -2px 0 var(--color-error); }
    40%  { transform: translateX(4px)  skewX(12deg);  color: var(--color-error); }
    60%  { transform: translateX(-3px) skewX(-6deg);  color: var(--color-error); }
    80%  { transform: translateX(2px)  skewX(4deg);   color: var(--color-error); opacity: 0.7; }
    100% { transform: translateX(0)    skewX(0deg);   color: var(--color-error); opacity: 1; }
}

/* Error: one-shot horizontal glitch-shake, confined to the small operator + streak. */
.logo-operator.state-error,
#streak.streak-shatter {
    animation: visceral-shatter var(--dur-shatter) steps(6) both;
}

/* ============================================================
 * Flow Pulse — hot-streak heartbeat (glow layer opacity + scale only)
 * ============================================================ */

#streak {
    position:   relative;
    display:    inline-block;
    transition: color 0.2s ease;
}

@keyframes flow-pulse-scale {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.08); }
}

@keyframes flow-pulse-glow {
    0%, 100% { opacity: 0.3; }
    50%      { opacity: 0.75; }
}

#streak.streak-hot {
    color:     var(--text-streak);
    animation: flow-pulse-scale var(--dur-pulse) ease-in-out infinite;
}

/* The neon glow is a separate blurred layer — only its opacity animates. */
#streak.streak-hot::after {
    content:        "";
    position:       absolute;
    inset:          -45% -30%;
    z-index:        -1;
    border-radius:  50%;
    background:      radial-gradient(circle, var(--text-streak) 0%, transparent 70%);
    filter:         blur(6px);
    pointer-events: none;
    animation:      flow-pulse-glow var(--dur-pulse) ease-in-out infinite;
}

/* ============================================================
 * Dopamine Flash — one-shot reward on the correct answer button
 * ============================================================ */

@keyframes dopamine-flash {
    0%   { transform: scale(1);   background-color: var(--surface);
           color: var(--text-primary); box-shadow: none;
           border-color: var(--surface-border); }
    18%  { transform: scale(1.1); background-color: var(--color-success);
           color: var(--bg-canvas);    box-shadow: 0 0 40px var(--color-success);
           border-color: var(--color-success); }
    100% { transform: scale(1);   background-color: var(--surface);
           color: var(--text-primary); box-shadow: none;
           border-color: var(--surface-border); }
}

/* The success color lives ONLY inside the keyframes, so the green border fades
   back to neutral as the animation ends — it never persists on a recycled button. */
.answer.answer-correct {
    animation: dopamine-flash var(--dur-flash) var(--ease-pop);
}

/* ============================================================
 * Reduced motion — static variants; feedback is preserved, motion is not.
 * (OS-level prefers-reduced-motion; a manual override toggle lands in Phase 5.)
 * ============================================================ */

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

    /* Hot streak → static neon glow, no scale/heartbeat. */
    #streak.streak-hot {
        color:       var(--text-streak);
        text-shadow: 0 0 6px var(--text-streak);
        animation:   none !important;
    }
    #streak.streak-hot::after {
        display: none;
    }

    /* Correct → instant success color, no scale/glow sweep. */
    .answer.answer-correct {
        background-color: var(--color-success);
        color:            var(--bg-canvas);
        animation:        none !important;
    }
    .logo-operator.state-correct {
        color:     var(--color-success);
        animation: none !important;
    }

    /* Idle spin off; error → desaturate + error color, no translate/skew/chromatic. */
    .logo-operator.state-idle {
        animation: none !important;
    }
    .logo-operator.state-error,
    #streak.streak-shatter {
        color:       var(--color-error);
        filter:      grayscale(0.35);
        transform:   none !important;
        text-shadow: none !important;
        animation:   none !important;
    }

    /* No tactile press depth under reduced motion. */
    .answer:active:not(:disabled) {
        transform: none;
    }
}
