/* ══════════════════════════════════════════
   ANIMATIONS — Все анимации
   ══════════════════════════════════════════ */

:root {
    --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
    --transition-smooth: 0.25s var(--ease-out-expo);
    --transition-bouncy: 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
    --transition-hover: 0.2s var(--ease-out-expo);
}

/* Применяем плавность ко всем интерактивным элементам */
a, button, .card, .sidebar__nav-item, .table tr {
    transition:
        color var(--transition-hover),
        background-color var(--transition-hover),
        border-color var(--transition-hover),
        box-shadow var(--transition-hover),
        transform var(--transition-hover),
        opacity var(--transition-hover);
}

/* === Появление элементов === */
@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes fadeInUp {
    from { opacity: 0; transform: translateY(24px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes fadeInDown {
    from { opacity: 0; transform: translateY(-16px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes fadeInLeft {
    from { opacity: 0; transform: translateX(-24px); }
    to { opacity: 1; transform: translateX(0); }
}

@keyframes fadeInRight {
    from { opacity: 0; transform: translateX(24px); }
    to { opacity: 1; transform: translateX(0); }
}

@keyframes fadeInScale {
    from { opacity: 0; transform: scale(0.95) translateY(10px); }
    to { opacity: 1; transform: scale(1) translateY(0); }
}

.page-entrance {
    animation: fadeInScale 0.3s var(--ease-out) forwards;
    will-change: opacity, transform;
}

/* Utilities */
.animate-fade-in { 
    opacity: 0; 
    animation: fadeIn 0.4s var(--ease-out) forwards; 
    will-change: opacity;
}
.animate-fade-in-up { 
    opacity: 0; 
    animation: fadeInUp 0.3s var(--ease-out) forwards; 
    will-change: opacity, transform;
}
.animate-scale-in { 
    opacity: 0; 
    animation: fadeInScale 0.3s var(--ease-out) forwards; 
    will-change: opacity, transform;
}

/* Каскадное появление */
.stagger-item {
    opacity: 0;
    transform: translateY(10px);
    animation: fadeInUp 300ms var(--ease-out) forwards;
    animation-delay: calc(min(12, var(--stagger-index, 0)) * 25ms);
    will-change: opacity, transform;
}

/* Scroll reveal */
.reveal {
    opacity: 0;
    transform: translateY(20px);
    transition: opacity var(--duration-slower) var(--ease-out),
        transform var(--duration-slower) var(--ease-out);
}

.reveal.visible {
    opacity: 1;
    transform: translateY(0);
}

/* === Score animations === */
@keyframes scoreFlipIn {
    0% {
        transform: perspective(400px) rotateX(90deg);
        opacity: 0;
    }

    40% {
        transform: perspective(400px) rotateX(-15deg);
    }

    70% {
        transform: perspective(400px) rotateX(10deg);
    }

    100% {
        transform: perspective(400px) rotateX(0deg);
        opacity: 1;
    }
}

@keyframes scoreFlipOut {
    from {
        transform: perspective(400px) rotateX(0deg);
        opacity: 1;
    }

    to {
        transform: perspective(400px) rotateX(-90deg);
        opacity: 0;
    }
}

@keyframes scorePop {
    0% {
        transform: scale(1);
    }

    30% {
        transform: scale(1.4);
        color: var(--accent);
    }

    60% {
        transform: scale(0.95);
    }

    100% {
        transform: scale(1);
    }
}

/* === Live пульс === */
@keyframes livePulse {

    0%,
    100% {
        opacity: 1;
        box-shadow: 0 0 0 0 var(--live-glow);
    }

    50% {
        opacity: 0.6;
        box-shadow: 0 0 0 8px transparent;
    }
}

/* === Ripple === */
@keyframes ripple {
    to {
        transform: scale(4);
        opacity: 0;
    }
}

/* === Modal === */
@keyframes modalOverlayIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes modalIn {
    from {
        opacity: 0;
        transform: scale(0.92) translateY(10px);
    }

    to {
        opacity: 1;
        transform: scale(1) translateY(0);
    }
}

@keyframes modalOut {
    from {
        opacity: 1;
        transform: scale(1);
    }

    to {
        opacity: 0;
        transform: scale(0.95);
    }
}

/* === Toast === */
@keyframes toastSlideIn {
    from {
        transform: translateX(120%);
        opacity: 0;
    }

    to {
        transform: translateX(0);
        opacity: 1;
    }
}

@keyframes toastSlideOut {
    from {
        transform: translateX(0);
        opacity: 1;
    }

    to {
        transform: translateX(120%);
        opacity: 0;
    }
}

@keyframes toastProgress {
    from {
        width: 100%;
    }

    to {
        width: 0%;
    }
}

/* === Sidebar === */
@keyframes sidebarItemFadeIn {
    from {
        opacity: 0;
        transform: translateX(-8px);
    }

    to {
        opacity: 1;
        transform: translateX(0);
    }
}

/* === Skeleton loading === */
@keyframes skeletonShimmer {
    0% {
        background-position: -200% 0;
    }

    100% {
        background-position: 200% 0;
    }
}

/* === Bracket === */
@keyframes bracketLineGrow {
    from {
        stroke-dashoffset: 100;
    }

    to {
        stroke-dashoffset: 0;
    }
}

@keyframes bracketMatchFadeIn {
    from {
        opacity: 0;
        transform: scale(0.8);
    }

    to {
        opacity: 1;
        transform: scale(1);
    }
}

@keyframes pathGlow {

    0%,
    100% {
        filter: drop-shadow(0 0 4px var(--accent-glow));
    }

    50% {
        filter: drop-shadow(0 0 12px var(--accent-glow));
    }
}

/* === Map Veto === */
@keyframes mapBan {
    0% {
        filter: brightness(1);
        transform: scale(1);
    }

    50% {
        filter: brightness(0.3);
        transform: scale(0.95);
    }

    100% {
        filter: brightness(0.3) grayscale(1);
        transform: scale(0.95);
    }
}

@keyframes mapPick {
    0% {
        transform: scale(1);
        box-shadow: none;
    }

    50% {
        transform: scale(1.05);
    }

    100% {
        transform: scale(1.02);
        box-shadow: var(--shadow-glow-success);
    }
}

@keyframes banStamp {
    0% {
        transform: scale(3) rotate(-30deg);
        opacity: 0;
    }

    60% {
        transform: scale(1.1) rotate(-15deg);
        opacity: 0.9;
    }

    100% {
        transform: scale(1) rotate(-12deg);
        opacity: 0.8;
    }
}

@keyframes pickCheckmark {
    0% {
        stroke-dashoffset: 30;
        opacity: 0;
    }

    100% {
        stroke-dashoffset: 0;
        opacity: 1;
    }
}

/* === Confetti === */
@keyframes confettiFall {
    0% {
        transform: translateY(-100vh) rotate(0deg);
        opacity: 1;
    }

    100% {
        transform: translateY(100vh) rotate(720deg);
        opacity: 0;
    }
}

@keyframes confettiSway {

    0%,
    100% {
        transform: translateX(0);
    }

    25% {
        transform: translateX(50px);
    }

    75% {
        transform: translateX(-50px);
    }
}

/* === Progress bar === */
@keyframes progressFill {
    from {
        width: 0%;
    }

    to {
        width: var(--progress-value, 0%);
    }
}

/* === Card shine === */
@keyframes cardShine {
    0% {
        background-position: -200% 0;
    }

    100% {
        background-position: 200% 0;
    }
}

/* === Count up (numbers) === */
@keyframes countUp {
    from {
        opacity: 0;
        transform: translateY(10px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* === Graph line draw === */
@keyframes drawLine {
    to {
        stroke-dashoffset: 0;
    }
}

/* === Spin === */
@keyframes spin {
    to {
        transform: rotate(360deg);
    }
}

.spinner {
    width: 32px;
    height: 32px;
    border: 3px solid var(--border-subtle);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: spin 600ms linear infinite;
}

/* === Shake (error) === */
@keyframes shake {

    0%,
    100% {
        transform: translateX(0);
    }

    10%,
    30%,
    50%,
    70%,
    90% {
        transform: translateX(-4px);
    }

    20%,
    40%,
    60%,
    80% {
        transform: translateX(4px);
    }
}

.shake {
    animation: shake 500ms var(--ease-out);
}

/* === Bounce in === */
@keyframes bounceIn {
    0% {
        transform: scale(0);
        opacity: 0;
    }

    50% {
        transform: scale(1.15);
    }

    100% {
        transform: scale(1);
        opacity: 1;
    }
}

/* === Reduced motion === */
@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}
