/*
 * Qualims Animations
 * Entrance animations, micro-interactions, stagger utilities.
 * Depends on tokens.css.
 */

/* ── Keyframes ───────────────────────────────────────────── */

@keyframes fadeInUp {
    from { opacity: 0; transform: translateY(20px); }
    to   { opacity: 1; transform: translateY(0); }
}

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

@keyframes scaleIn {
    from { opacity: 0; transform: scale(0.95); }
    to   { opacity: 1; transform: scale(1); }
}

@keyframes slideDown {
    from { opacity: 0; transform: translateY(-10px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes shimmer {
    0%   { background-position: -200% center; }
    100% { background-position:  200% center; }
}

/* ── Easing ──────────────────────────────────────────────── */
/* expo ease-out: snappy start, smooth settle — feels physical */
:root {
    --ease-expo:   cubic-bezier(0.22, 1, 0.36, 1);
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* ── Page enter ──────────────────────────────────────────── */
/* Applied to .main-container in base.html */

.page-enter {
    animation: fadeInUp 340ms var(--ease-expo) both;
}

/* ── Stagger grid children ───────────────────────────────── */
/* Add .stagger-grid to a flex/grid wrapper.                  */
/* Children animate in sequentially (CSS only, no JS).        */

.stagger-grid > * {
    opacity: 0;
    animation: fadeInUp 320ms var(--ease-expo) both;
}

.stagger-grid > *:nth-child(1)  { animation-delay:   0ms; }
.stagger-grid > *:nth-child(2)  { animation-delay:  55ms; }
.stagger-grid > *:nth-child(3)  { animation-delay: 110ms; }
.stagger-grid > *:nth-child(4)  { animation-delay: 165ms; }
.stagger-grid > *:nth-child(5)  { animation-delay: 220ms; }
.stagger-grid > *:nth-child(6)  { animation-delay: 275ms; }
.stagger-grid > *:nth-child(7)  { animation-delay: 330ms; }
.stagger-grid > *:nth-child(8)  { animation-delay: 385ms; }
.stagger-grid > *:nth-child(9)  { animation-delay: 440ms; }
.stagger-grid > *:nth-child(10) { animation-delay: 495ms; }
.stagger-grid > *:nth-child(11) { animation-delay: 550ms; }
.stagger-grid > *:nth-child(12) { animation-delay: 605ms; }

/* ── Table row stagger ───────────────────────────────────── */

.stagger-rows tbody tr {
    opacity: 0;
    animation: fadeInUp 240ms var(--ease-expo) both;
}

.stagger-rows tbody tr:nth-child(1)  { animation-delay:  30ms; }
.stagger-rows tbody tr:nth-child(2)  { animation-delay:  60ms; }
.stagger-rows tbody tr:nth-child(3)  { animation-delay:  90ms; }
.stagger-rows tbody tr:nth-child(4)  { animation-delay: 120ms; }
.stagger-rows tbody tr:nth-child(5)  { animation-delay: 150ms; }
.stagger-rows tbody tr:nth-child(6)  { animation-delay: 180ms; }
.stagger-rows tbody tr:nth-child(7)  { animation-delay: 210ms; }
.stagger-rows tbody tr:nth-child(8)  { animation-delay: 240ms; }
.stagger-rows tbody tr:nth-child(9)  { animation-delay: 270ms; }
.stagger-rows tbody tr:nth-child(10) { animation-delay: 300ms; }
/* Rows after 10th appear instantly to avoid perception of slowness */

/* ── Dashboard widget stagger (JS-driven) ────────────────── */
/* JS sets --widget-i on each widget after GridStack init      */

.widget-animate-in {
    animation: scaleIn 380ms var(--ease-expo) both;
    animation-delay: calc(var(--widget-i, 0) * 70ms);
}

/* ── Card hover lift ─────────────────────────────────────── */

.card-lift {
    transition: transform var(--motion-base) var(--ease-expo),
                box-shadow var(--motion-base) var(--ease-expo);
}

.card-lift:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
}

/* ── Pulse dot (status indicators) ──────────────────────── */

@keyframes pulse-dot {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%       { opacity: 0.6; transform: scale(0.85); }
}

.pulse-dot {
    display: inline-block;
    width: 8px; height: 8px;
    border-radius: var(--radius-full);
    animation: pulse-dot 2s ease-in-out infinite;
}

.pulse-dot-danger  { background: var(--color-danger); }
.pulse-dot-success { background: var(--color-success); }
.pulse-dot-warning { background: var(--color-warning); }

/* ── Skeleton loading ────────────────────────────────────── */

.skeleton {
    background: linear-gradient(
        90deg,
        var(--sl-100) 25%,
        var(--sl-200) 50%,
        var(--sl-100) 75%
    );
    background-size: 200% auto;
    animation: shimmer 1.4s linear infinite;
    border-radius: var(--radius-sm);
}

[data-theme="dark"] .skeleton {
    background: linear-gradient(
        90deg,
        var(--sl-800) 25%,
        var(--sl-700) 50%,
        var(--sl-800) 75%
    );
    background-size: 200% auto;
}

/* ── Modal enter ─────────────────────────────────────────── */

.app-modal-animate .modal-content {
    animation: scaleIn 240ms var(--ease-expo) both;
}

/* ── Toast enter ─────────────────────────────────────────── */

.toast.showing {
    animation: slideDown 200ms var(--ease-expo) both;
}

/* ── Pulse loader (сонар) ────────────────────────────────── */
/*
 * Концентрические расходящиеся круги вокруг ядра — индикатор загрузки.
 * Использование:  <div class="loader-pulse" role="status" aria-label="Загрузка"></div>
 * Настройка через переменные:
 *   --loader-pulse-size  — диаметр (по умолчанию 64px)
 *   --loader-pulse-speed — период волны (по умолчанию 1.8s)
 *   .loader-pulse.is-sm / .is-lg — готовые размеры.
 */
@keyframes loader-pulse-ripple {
    0%        { transform: scale(0.25); opacity: 0.5; }
    80%, 100% { transform: scale(1);    opacity: 0;   }
}

.loader-pulse {
    --loader-pulse-size:  64px;
    --loader-pulse-speed: 1.8s;
    position: relative;
    display: inline-block;
    width:  var(--loader-pulse-size);
    height: var(--loader-pulse-size);
    /* статичное ядро в центре */
    background: radial-gradient(circle,
        var(--accent) 0,
        var(--accent) calc(var(--loader-pulse-size) * 0.13),
        transparent  calc(var(--loader-pulse-size) * 0.13 + 1px));
}

.loader-pulse::before,
.loader-pulse::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: var(--radius-full);
    background: var(--accent);
    transform: scale(0.25);
    opacity: 0;
    animation: loader-pulse-ripple var(--loader-pulse-speed) var(--ease-expo) infinite;
}
/* вторая волна стартует на полпериода раньше → непрерывный пульс */
.loader-pulse::after { animation-delay: calc(var(--loader-pulse-speed) / -2); }

.loader-pulse.is-sm { --loader-pulse-size: 36px; }
.loader-pulse.is-lg { --loader-pulse-size: 96px; }

/* ── Aurora background animation ─────────────────────────── */
/* Применение в ПРИЛОЖЕНИИ убрано (base.css → washed-подложка, ТЗ §03/§05).
   Keyframes оставлен: его использует ЛЕНДИНГ qualims.ru (site-*.css), где
   фоновые эффекты сохраняются по решению заказчика. */
@keyframes aurora-float {
    0%   { transform: translate( 0%,    0%)   scale(1);    }
    30%  { transform: translate( 4%,    3%)   scale(1.04); }
    60%  { transform: translate(-3%,    4.5%) scale(0.97); }
    100% { transform: translate( 3.5%, -3%)   scale(1.03); }
}

/* ── Reduced motion: disable everything ─────────────────── */

@media (prefers-reduced-motion: reduce) {
    .page-enter,
    .stagger-grid > *,
    .stagger-rows tbody tr,
    .widget-animate-in,
    .card-lift,
    .pulse-dot,
    .skeleton,
    .app-modal-animate .modal-content,
    .toast.showing,
    body::after {
        animation: none !important;
        transition: none !important;
        opacity: 1 !important;
        transform: none !important;
    }
}

/* Лоадер при reduced-motion: без пульсации, но остаётся видимый индикатор
   (ядро + одно статичное кольцо). Отдельно от блока выше, чтобы не залить
   всё сплошным кругом. */
@media (prefers-reduced-motion: reduce) {
    .loader-pulse::before {
        animation: none !important;
        transform: scale(0.6);
        opacity: 0.25;
    }
    .loader-pulse::after { display: none; }
}
