:root {
    /* Duration scale — micro / UI / panel / page */
    --anim-duration-instant: 150ms;
    --anim-duration-quick: 200ms;
    --anim-duration-ui: 240ms;
    --anim-duration-moderate: 280ms;
    --anim-duration-fast: 320ms;
    --anim-duration-panel: var(--anim-duration-fast);
    --anim-duration-overlay: var(--anim-duration-moderate);
    --anim-duration-emphasis: 380ms;
    --anim-duration-base: 480ms;
    --anim-duration-slow: 640ms;

    /* Easing — UI hovers vs spatial motion */
    --anim-ease-ui: ease;
    --anim-ease-standard: cubic-bezier(0.22, 1, 0.36, 1);

    --anim-stagger-step: 55ms;
    --anim-stagger-cap: 320ms;
    --anim-offset-y: 28px;
    --anim-offset-x: 28px;
}

.anim-run {
    animation-duration: var(--anim-duration-base);
    animation-timing-function: var(--anim-ease-standard);
    animation-fill-mode: both;
}

.anim-run--fast {
    animation-duration: var(--anim-duration-fast);
}

@keyframes anim-rise {
    from {
        opacity: 0;
        transform: translateY(var(--anim-offset-y));
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes anim-fade-in-down {
    from {
        opacity: 0;
        transform: translateY(calc(-1 * var(--anim-offset-y)));
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes anim-fade-in-left {
    from {
        opacity: 0;
        transform: translateX(calc(-1 * var(--anim-offset-x)));
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes anim-fade-in-right {
    from {
        opacity: 0;
        transform: translateX(var(--anim-offset-x));
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes anim-fade-in {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@keyframes anim-fade-out {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}

@keyframes anim-pulse {
    0% {
        transform: scale3d(1, 1, 1);
    }
    50% {
        transform: scale3d(1.04, 1.04, 1.04);
    }
    100% {
        transform: scale3d(1, 1, 1);
    }
}

@keyframes anim-head-shake {
    0% {
        transform: translateX(0);
    }
    6.5% {
        transform: translateX(-6px) rotateY(-9deg);
    }
    18.5% {
        transform: translateX(5px) rotateY(7deg);
    }
    31.5% {
        transform: translateX(-3px) rotateY(-5deg);
    }
    43.5% {
        transform: translateX(2px) rotateY(3deg);
    }
    50% {
        transform: translateX(0);
    }
}

.anim-rise {
    animation-name: anim-rise;
}

.anim-fade-in-down {
    animation-name: anim-fade-in-down;
}

.anim-fade-in-left {
    animation-name: anim-fade-in-left;
}

.anim-fade-in-right {
    animation-name: anim-fade-in-right;
}

.anim-fade-in {
    animation-name: anim-fade-in;
}

.anim-fade-out {
    animation-name: anim-fade-out;
}

.anim-pulse {
    animation-name: anim-pulse;
}

.anim-head-shake {
    animation-name: anim-head-shake;
}

.anim-enter {
    animation-name: anim-rise;
    animation-duration: var(--anim-duration-base);
    animation-timing-function: var(--anim-ease-standard);
    animation-fill-mode: both;
    animation-delay: var(--anim-delay, 0ms);
}

@media (prefers-reduced-motion: reduce) {
    .anim-run,
    .anim-enter {
        animation: none;
    }
}
