/* ═══ Движение сайта ════════════════════════════════════════════════════
   Просьба владельца 26.09: «анимации невозможно красивые для всего,
   интерфейс живее» — живые карточки, кнопки с бликом, плавные переходы
   между страницами, появление заголовков.

   Правила (после прохода по скорости 26.09 — не нарушать):
   • двигаются только transform и opacity; без mix-blend-mode и filter;
   • длительности 120–320 мс, выход быстрее входа;
   • prefers-reduced-motion — ничего из этого (JS тоже не включается);
   • кнопки: css/components.css (.btn-primary::after, .btn-glass::after).
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Переход между страницами (router.js, View Transitions API) ─────────
   Снимок старой страницы лежит сверху и быстро гаснет (110 мс). Под ним —
   живая новая: её содержимое (#main) чуть позже (60 мс) проявляется —
   opacity, Web Animation в router.js, — а вся картинка новой страницы
   поднимается на 10 px здесь, на псевдоэлементе перехода. Подъём — не на
   #main: transform на #main сделал бы его рамкой для position: fixed внутри
   страницы (слой перламутра на /terms, развёрнутая игра) — они съезжали бы
   на время перехода. Фон новой страницы виден сразу (opacity 1), поэтому не
   проседает между двумя снимками. Верхняя панель — отдельной группой и без
   анимации: стоит на месте, активная вкладка меняется своим переходом. Имя
   панели задаётся только на время перехода (html.vt-nav), чтобы в обычной
   работе не создавать ей лишний слой. */
html.vt-nav .topbar { view-transition-name: site-topbar; }
::view-transition-group(site-topbar) { animation: none; }
::view-transition-old(site-topbar) { display: none; }
::view-transition-new(site-topbar) { animation: none; }
::view-transition-old(root) {
    z-index: 1;
    mix-blend-mode: normal;
    animation: vt-out 110ms cubic-bezier(0.3, 0, 0.8, 0.15) both;
}
::view-transition-new(root) {
    mix-blend-mode: normal;
    animation: vt-rise 220ms cubic-bezier(0.16, 1, 0.3, 1) 60ms both;
}
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-rise { from { transform: translate3d(0, 10px, 0); } }

/* ── Заголовки по словам (js/components/heading-reveal.js) ─────────────
   Заголовок ждёт окна прозрачным; !important — чтобы общее появление
   .reveal (CSS-анимация) не показало его раньше слов. Слова — inline-block:
   строчному span transform не применяется; пробелы остаются текстом между
   ними, переносы строк те же. Слова склеиваются обратно, когда заголовок
   ушёл из окна (на глазах склейка сдвинула бы слова на доли пикселя).
   Спрятан заголовок с первого кадра: класс ставит MutationObserver ещё до
   отрисовки, а не наблюдатель за окном. */
.hr-on .hr-wait { opacity: 0 !important; }
.hr-w { display: inline-block; }

/* ── Живые карточки: блик под курсором (js/components/tilt.js) ─────────
   Пятно света без свечения и без смешивания: белый радиальный градиент
   малой плотности. Двигается transform (translate3d), гаснет opacity. */
.tilt-glare {
    position: absolute;
    inset: 0;
    z-index: 4;
    overflow: hidden;
    border-radius: inherit;
    pointer-events: none;
    opacity: 0;
    transition: opacity 320ms ease;
}
.tilt-glare > i {
    position: absolute;
    left: 0;
    top: 0;
    width: var(--tilt-g, 480px);
    height: var(--tilt-g, 480px);
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(255, 255, 255, 0.12), rgba(244, 240, 255, 0.05) 46%, transparent 72%);
    will-change: transform;
}

/* ── Окна открываются от кнопки, которая их вызвала ──────────────────────
   app.js ставит --modal-origin (точка последнего нажатия относительно
   окна); без неё — из центра. Шторка на телефоне едет снизу, как была. */
.modal { transform-origin: var(--modal-origin, 50% 50%); }

@media (prefers-reduced-motion: reduce) {
    ::view-transition-old(root), ::view-transition-new(root) { animation: none !important; }
    .hr-on .hr-wait { opacity: 1 !important; }
    .tilt-glare { display: none; }
}
