/* ══════════════════════════════════════════════
   ПЕРЕХОДЫ МЕЖДУ СТРАНИЦАМИ И МИКРОАНИМАЦИИ
   ══════════════════════════════════════════════
   Слои, каждый работает независимо:
     1) View Transitions API — нативный кросс-документный переход
        (Chrome/Edge/Safari 18.2+). Сам обрабатывает «назад/вперёд».
     2) CSS-анимация появления контента — для остальных браузеров.
        Какой из двух слоёв сыграет, решает pagereveal (скрипт в <head>).
     3) Дозагрузка: картинки проявляются, карточки выходят лесенкой.
     4) Микровзаимодействия — единые ховеры/нажатия по всему сайту.
   Всё отключается при prefers-reduced-motion (см. конец файла).
*/

/* ── 1. Кросс-документные переходы ── */
@view-transition {
    navigation: auto;
}

/* Шапка одинакова на всех страницах. Без отдельного имени она уезжает
   вместе с контентом, и переход читается как рывок всей страницы. */
.navbar { view-transition-name: site-nav; }
::view-transition-group(site-nav) {
    animation-duration: .01s; /* позицию не анимируем — шапка просто стоит */
}

/* По умолчанию браузер смешивает старый и новый снимок через plus-lighter.
   Для чистого затухания это идеально, но мы ещё и сдвигаем новую страницу —
   при сдвиге аддитивное смешивание рисует светящегося двойника текста.
   Возвращаем обычное наложение: новый кадр просто лежит поверх старого. */
::view-transition-image-pair(root) { isolation: auto; }
::view-transition-old(root),
::view-transition-new(root) { mix-blend-mode: normal; }

/* Старый кадр держится непрозрачным, пока новый не проявится почти
   полностью, — так между страницами не мелькает фон body. */
::view-transition-old(root) {
    animation: vtOut .32s linear both;
}
::view-transition-new(root) {
    animation: vtIn .32s cubic-bezier(.16, 1, .3, 1) both;
}
@keyframes vtOut {
    0%, 62% { opacity: 1; }
    100%    { opacity: 0; }
}
@keyframes vtIn {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

/* ── 2. Фолбэк: появление контента при загрузке ── */
/* Класс vt-run ставит обработчик pagereveal, когда переход уже отрисовал
   сам браузер. Тогда эту анимацию не играем — иначе контент дёрнется дважды.
   Проверять поддержку через @supports нельзя: Firefox знает
   view-transition-name, но не умеет кросс-документные переходы,
   и по @supports-условию остался бы вообще без анимации. */
html:not(.vt-run) main,
html:not(.vt-run) .auth-page,
html:not(.vt-run) .cert-page {
    animation: pageEnter .34s cubic-bezier(.16, 1, .3, 1) both;
}
@keyframes pageEnter {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}

/* Редактор урока намеренно открывается мгновенно, без анимаций
   (страница-документ, любой сдвиг читается как рывок). */
main:has(.editor-standalone) { animation: none !important; }
html:has(.editor-standalone)::view-transition-old(root),
html:has(.editor-standalone)::view-transition-new(root) { animation: none; }

/* ── 3. Дозагрузка контента ── */

/* Картинки приходят позже разметки и «щёлкают» на месте — проявляем их.
   Класс js-anim ставит скрипт в <head>: если он не отработал, прятать
   картинки нельзя — показать их будет уже некому. */
.js-anim main img { opacity: 0; }
.js-anim main img.img-ready {
    opacity: 1;
    transition: opacity .35s ease;
}

/* Карточки в сетках выходят лесенкой — контент собирается, а не вспыхивает
   разом. Задержка только у первых шести: в длинном списке ожидание своей
   очереди было бы заметнее самой загрузки. */
.course-grid > *,
.hero-stats .stat,
.stats-grid > *,
.admin-stats-grid > * {
    animation: cardEnter .4s cubic-bezier(.16, 1, .3, 1) both;
}
.course-grid > :nth-child(2),
.hero-stats .stat:nth-child(2),
.stats-grid > :nth-child(2),
.admin-stats-grid > :nth-child(2) { animation-delay: .05s; }

.course-grid > :nth-child(3),
.hero-stats .stat:nth-child(3),
.stats-grid > :nth-child(3),
.admin-stats-grid > :nth-child(3) { animation-delay: .10s; }

.course-grid > :nth-child(4),
.hero-stats .stat:nth-child(4),
.stats-grid > :nth-child(4),
.admin-stats-grid > :nth-child(4) { animation-delay: .15s; }

.course-grid > :nth-child(5),
.stats-grid > :nth-child(5),
.admin-stats-grid > :nth-child(5) { animation-delay: .20s; }

.course-grid > :nth-child(n+6),
.stats-grid > :nth-child(n+6),
.admin-stats-grid > :nth-child(n+6) { animation-delay: .25s; }

@keyframes cardEnter {
    from { opacity: 0; transform: translateY(12px); }
    to   { opacity: 1; transform: none; }
}

/* ── 4. Полоса загрузки при переходе ── */
/* Нужна на тяжёлых страницах (детали курса — сотни КБ): показывает,
   что клик сработал, пока браузер ждёт ответ сервера.
   Цвета с запасными значениями — страница сертификата не подключает style.css. */
.nav-progress {
    position: fixed;
    top: 0;
    left: 0;
    height: 3px;
    width: 0;
    z-index: 99999;
    background: linear-gradient(90deg, var(--primary, #4f46e5), var(--accent, #06b6d4));
    box-shadow: 0 0 8px rgba(79, 70, 229, .5);
    opacity: 0;
    pointer-events: none;
    transition: width .2s ease, opacity .2s ease;
}
.nav-progress.active { opacity: 1; }

/* ── 5. Микровзаимодействия ── */

/* Ссылки */
a { transition: color .15s ease; }

/* Кнопки: заметное, но короткое нажатие */
.btn {
    transition: background-color .15s ease, border-color .15s ease,
                color .15s ease, box-shadow .15s ease, transform .12s ease;
}
.btn:active { transform: translateY(1px); }

/* Карточки: подъём при наведении задаёт style.css — здесь только тайминг,
   иначе два файла спорят за одно и то же значение transform. */
.course-card,
.admin-card,
.compact-card,
.au-course,
.au-cert,
.admin-stat-card {
    transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.au-course:hover,
.au-cert:hover,
.admin-stat-card:hover {
    transform: translateY(-2px);
}

/* Строки таблиц и списков */
.data-table tbody tr,
.au-table tbody tr,
.admin-list-item,
.au-feed-item,
.syllabus-lesson,
.lesson-row {
    transition: background-color .13s ease;
}

/* Поля ввода */
input, select, textarea {
    transition: border-color .15s ease, box-shadow .15s ease, background-color .15s ease;
}

/* Иконки-кнопки */
.btn-icon, .btn-icon-xs, .icon-swatch, .icon-reset {
    transition: color .15s ease, background-color .15s ease, transform .12s ease;
}

/* Прогресс-бары: плавный рост вместо мгновенного скачка */
.progress-fill,
.au-progress > div,
.ucd-tab-bar > div {
    transition: width .45s cubic-bezier(.4, 0, .2, 1);
}

/* Видимый фокус с клавиатуры — доступность без ущерба мыши */
a:focus-visible,
.btn:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
    outline: 2px solid var(--primary, #4f46e5);
    outline-offset: 2px;
}

/* ── 6. Уважение к настройкам системы ── */
/* Пользователи с укачиванием/вестибулярными нарушениями включают
   «уменьшить движение» — глушим ВСЕ анимации сайта, не только эти. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        animation-delay: 0s !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    ::view-transition-group(*),
    ::view-transition-old(*),
    ::view-transition-new(*) {
        animation: none !important;
    }
    .js-anim main img { opacity: 1; }
    .btn:active,
    .course-card:hover,
    .au-course:hover,
    .au-cert:hover,
    .admin-stat-card:hover {
        transform: none;
    }
}
