/*
 * Reusable animation utilities.
 *
 * Add an entrance class to any element (`anim-slide-in-left`, `anim-fade-in`, …).
 * Tune per element with inline custom properties:
 *   style="--anim-duration: 1.2s; --anim-delay: 0.3s;"
 *
 * Continuous helpers: `anim-spin`, `anim-pulse`, `anim-float`.
 */

:root {
    --anim-duration: 1.3s;
    --anim-delay: 0s;
    --anim-distance: 40px;
    --anim-easing: cubic-bezier(0.22, 1, 0.36, 1);
}

[class*="anim-"] {
    animation-duration: var(--anim-duration);
    animation-delay: var(--anim-delay);
    animation-timing-function: var(--anim-easing);
    animation-fill-mode: both;
}

/* --- Slide in (entrance) --- */
.anim-slide-in-left  { animation-name: slideInLeft; }
.anim-slide-in-right { animation-name: slideInRight; }
.anim-slide-in-up    { animation-name: slideInUp; }
.anim-slide-in-down  { animation-name: slideInDown; }

@keyframes slideInLeft {
    from { opacity: 0; transform: translateX(calc(-1 * var(--anim-distance))); }
    to   { opacity: 1; transform: translateX(0); }
}

@keyframes slideInRight {
    from { opacity: 0; transform: translateX(var(--anim-distance)); }
    to   { opacity: 1; transform: translateX(0); }
}

@keyframes slideInUp {
    from { opacity: 0; transform: translateY(var(--anim-distance)); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes slideInDown {
    from { opacity: 0; transform: translateY(calc(-1 * var(--anim-distance))); }
    to   { opacity: 1; transform: translateY(0); }
}

/* --- Slide out (exit) --- */
.anim-slide-out-left  { animation-name: slideOutLeft; }
.anim-slide-out-right { animation-name: slideOutRight; }
.anim-slide-out-up    { animation-name: slideOutUp; }
.anim-slide-out-down  { animation-name: slideOutDown; }

@keyframes slideOutLeft {
    from { opacity: 1; transform: translateX(0); }
    to   { opacity: 0; transform: translateX(calc(-1 * var(--anim-distance))); }
}

@keyframes slideOutRight {
    from { opacity: 1; transform: translateX(0); }
    to   { opacity: 0; transform: translateX(var(--anim-distance)); }
}

@keyframes slideOutUp {
    from { opacity: 1; transform: translateY(0); }
    to   { opacity: 0; transform: translateY(calc(-1 * var(--anim-distance))); }
}

@keyframes slideOutDown {
    from { opacity: 1; transform: translateY(0); }
    to   { opacity: 0; transform: translateY(var(--anim-distance)); }
}

/* --- Fade --- */
.anim-fade-in  { animation-name: fadeIn; }
.anim-fade-out { animation-name: fadeOut; }

@keyframes fadeIn  { from { opacity: 0; } to { opacity: 1; } }
@keyframes fadeOut { from { opacity: 1; } to { opacity: 0; } }

/* --- Zoom --- */
.anim-zoom-in  { animation-name: zoomIn; }
.anim-zoom-out { animation-name: zoomOut; }

@keyframes zoomIn {
    from { opacity: 0; transform: scale(0.85); }
    to   { opacity: 1; transform: scale(1); }
}

@keyframes zoomOut {
    from { opacity: 1; transform: scale(1); }
    to   { opacity: 0; transform: scale(0.85); }
}

/* --- Rotate / spin --- */
.anim-rotate-in {
    animation-name: rotateIn;
}

.anim-spin {
    animation-name: spin;
    animation-duration: 1s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

@keyframes rotateIn {
    from { opacity: 0; transform: rotate(-200deg) scale(0.8); }
    to   { opacity: 1; transform: rotate(0) scale(1); }
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* --- Continuous / looping --- */
.anim-pulse {
    animation-name: pulse;
    animation-duration: 2s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}

.anim-float {
    animation-name: floatY;
    animation-duration: 3s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}

.anim-bounce-in {
    animation-name: bounceIn;
    animation-timing-function: cubic-bezier(0.68, -0.55, 0.27, 1.55);
}

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

@keyframes floatY {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-12px); }
}

@keyframes bounceIn {
    0%   { opacity: 0; transform: scale(0.6); }
    60%  { opacity: 1; transform: scale(1.08); }
    100% { transform: scale(1); }
}

/* Respect users who prefer reduced motion: show the final state, no movement. */
@media (prefers-reduced-motion: reduce) {
    [class*="anim-"] {
        animation: none !important;
    }
}
