/* OnlyChats v2 — модуль анимаций, общая CSS-часть (этап 1).
   Подключается сразу после base.css (_v2_assets): стили экранов идут позже
   и перекрывают общее. JS-часть — v2/js/motion.js (window.v2Motion).
   Двигаем только transform и opacity: их исполняет композитор, без layout
   и перерисовки на каждом кадре. */

/* ============ 1. Ключевые кадры ============ */

/* Шиммер скелетона: блик-псевдоэлемент едет transform'ом (а не background-position,
   которая перерисовывает плашку на каждом кадре) */
@keyframes v2Sweep { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
/* Кольцо-пульс: растёт и тает (вместо анимации box-shadow) */
@keyframes v2Ring { 0% { opacity: .7; transform: scale(1); } 100% { opacity: 0; transform: scale(1.45); } }
/* Блик по тосту достижения */
@keyframes v2MoShine { from { transform: translateX(-120%); } to { transform: translateX(260%); } }

/* ============ 2. Нажатие ============ */

/* Сжатие .97 там, где своё не задано: :where() даёт нулевую специфичность,
   любое правило экрана с transform/transition сильнее. Кнопки, .btn и карточки
   персонажей уже жмутся (base.css, catalog.css) */
:where(html.v2) :where([role="button"], [role="link"], .v2-hero, .shop__card, .notification-item,
    .daily-bonus-btn, .notification-bell-container, .v2-meta-balance) {
    transition: transform var(--v2-dur-fast) var(--v2-ease);
}

:where(html.v2) :where([role="button"], [role="link"], .v2-hero, .shop__card, .notification-item,
    .daily-bonus-btn, .notification-bell-container, .v2-meta-balance):active:not(:disabled):not([aria-disabled="true"]) {
    transform: scale(.97);
}

/* ============ 3. Общий шиммер ============ */

/* Класс для новых скелетонов: <div class="v2-shim">. Скелетоны общего слоя
   (.v2-skel) и экранов устроены так же, у себя в файлах */
html.v2 .v2-shim {
    position: relative;
    overflow: hidden;
    background: var(--v2-bg-2);
}

html.v2 .v2-shim::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(44, 33, 57, 0) 0%, var(--v2-skel-hi) 50%, rgba(44, 33, 57, 0) 100%);
    transform: translateX(-100%);
    animation: v2Sweep 1.4s linear infinite;
    pointer-events: none;
}

/* ============ 4. Кольцо-пульс ============ */

/* <x class="v2-ring"> — кольцо вокруг элемента (radius наследуется) */
html.v2 .v2-ring {
    position: relative;
}

html.v2 .v2-ring::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow: 0 0 0 2px var(--v2-accent);
    opacity: 0;
    animation: v2Ring 1.6s ease-out infinite;
    pointer-events: none;
}

/* ============ 5. Слой эффектов motion.js ============ */

html.v2 .v2-mo-layer {
    position: fixed;
    inset: 0;
    z-index: 2147483000;
    overflow: hidden;
    pointer-events: none;
    contain: strict;
}

html.v2 .v2-mo-layer > i {
    position: absolute;
    left: 0;
    top: 0;
    display: block;
    font-style: normal;
    pointer-events: none;
    will-change: transform, opacity;
}

html.v2 .v2-mo-spark {
    width: 3px;
    height: 14px;
    border-radius: 2px;
    background: var(--v2-crystal);
    box-shadow: 0 0 8px var(--v2-crystal);
}

/* Свечение кристалла нарисовано фоном (радиальный градиент), а не filter:
   drop-shadow — фильтр на 16 летящих слоях дорог для слабого GPU */
html.v2 .v2-mo-gem {
    width: 30px;
    height: 30px;
    margin: -15px 0 0 -15px;
    background:
        var(--v2-gem) center / 18px 18px no-repeat,
        radial-gradient(closest-side, rgba(240, 147, 251, .55), rgba(240, 147, 251, 0));
}

html.v2 .v2-mo-heart {
    width: 16px;
    height: 16px;
    color: var(--v2-accent);
}

html.v2 .v2-mo-heart svg {
    display: block;
    width: 100%;
    height: 100%;
}

html.v2 .v2-mo-plus {
    font: 800 28px/1 var(--v2-font-display);
    color: var(--v2-crystal);
    text-shadow: 0 0 14px rgba(240, 147, 251, .7);
    white-space: nowrap;
}

/* Одометр: накладка поверх числа, колонки цифр едут transform'ом */
html.v2 .v2-odo {
    position: absolute;
    z-index: 1;
    display: flex;
    overflow: hidden;
    pointer-events: none;
    font-style: normal;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

html.v2 .v2-odo-col {
    display: flex;
    flex-direction: column;
    font-style: normal;
    will-change: transform;
}

html.v2 .v2-odo-col > i {
    display: block;
    flex: none;
    font-style: normal;
    text-align: center;
}

/* Тост достижения: блик проходит после въезда (motion.js ставит класс) */
html.v2 .ach-toast.v2-mo-ach {
    overflow: hidden;
}

html.v2 .ach-toast.v2-mo-ach::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 60%;
    background: linear-gradient(100deg, rgba(255, 220, 160, 0), rgba(255, 220, 160, .24), rgba(255, 220, 160, 0));
    transform: translateX(-120%);
    pointer-events: none;
}

html.v2 .ach-toast.v2-mo-ach.ach-toast-show::after {
    animation: v2MoShine 900ms var(--v2-ease) 380ms both;
}

/* ============ 6. Пауза бесконечных анимаций ============ */

/* Наезд hero и фона чата, перелив ника: вне экрана (класс от IntersectionObserver),
   при скрытой вкладке и пока идёт прокрутка — стоят */
html.v2 .v2-mo-off,
html.v2.v2-mo-hidden :is(.v2-hero-art, .v2-chat-bg-img, .nick-anim),
html.v2.v2-mo-scrolling :is(.v2-hero-art, .v2-chat-bg-img, .nick-anim) {
    animation-play-state: paused !important;
}

/* ============ 6a. Перелёт обложки (этап 2) ============ */

/* Слой клона: под шторками (1200) и лоадером, над шапкой, кнопкой и таббаром */
html.v2 .v2-mo-fly-layer {
    position: fixed;
    inset: 0;
    z-index: 1100;
    overflow: hidden;
    pointer-events: none;
    contain: strict;
}

/* Клон размером цели; едут только transform и clip-path */
html.v2 .v2-mo-clone {
    position: absolute;
    left: 0;
    top: 0;
    overflow: hidden;
    transform-origin: 0 0;
    background: var(--v2-bg-2);
    will-change: transform, clip-path;
    pointer-events: none;
}

html.v2 .v2-mo-clone > i {
    position: absolute;
    inset: 0;
    display: block;
    font-style: normal;
}

/* Кадр как у арта экрана персонажа (object-fit: cover, object-position center 18%) */
html.v2 .v2-mo-clone-img {
    background: center 18% / cover no-repeat;
}

/* То же растворение в фон, что у .v2-dt-art-shade */
html.v2 .v2-mo-clone-shade {
    background: linear-gradient(180deg, rgba(11, 7, 16, .45) 0%, rgba(11, 7, 16, 0) 20%, rgba(11, 7, 16, 0) 58%, var(--v2-bg-1) 100%);
}

/* Экран персонажа, пока клон держится и летит: арт под клоном спрятан,
   панель, верхняя строка и кнопка ждут начала полёта */
html.v2 .v2-dt.v2-mo-artoff .v2-dt-art-inner {
    opacity: 0;
}

html.v2 .v2-dt.v2-mo-hold .v2-dt-panel,
html.v2 .v2-dt.v2-mo-hold .v2-dt-top,
html.v2 .v2-dt.v2-mo-hold .v2-dt-cta {
    opacity: 0;
    animation: none;
}

/* Полёт: подложка панели проявляется, содержимое поднимается каскадом
   (120 + i·40 мс), верхняя строка проявляется под конец */
html.v2 .v2-dt.v2-mo-in .v2-dt-panel,
html.v2 .v2-dt.v2-mo-flown .v2-dt-panel {
    animation: v2Fade var(--v2-dur-base) var(--v2-ease) 60ms both;
}

html.v2 .v2-dt.v2-mo-in .v2-dt-panel > * {
    animation: v2MoRise var(--v2-dur-screen) var(--v2-ease) both;
    animation-delay: calc(120ms + var(--v2-mo-i, 8) * 40ms);
}

html.v2 .v2-dt.v2-mo-in .v2-dt-top {
    animation: v2Fade var(--v2-dur-base) var(--v2-ease) 220ms both;
}

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

/* Карточка, в которую летит клон обратно */
html.v2 .v2-mo-ghost {
    opacity: 0 !important;
}

/* ============ 6b. Таббар и сайдбар (этап 2) ============ */

/* Пока app.js держит лоадер вкладки, панель над ним (видно, куда едет
   пилюля) и без кликов — двойной тап не запустит второй переход.
   Сайдбар — ребёнок #app, его поднимаем классом на <html>. Таббар заперт в
   слое page-container (проявление страницы в base.css с fill both), поэтому
   motion.js переносит уходящий таббар в body (класс v2-mo-navghost) до
   конца лоадера */
html.v2.v2-mo-navload #app > .v2-side,
html.v2 body > .bottom-nav.v2-mo-navghost {
    z-index: 10000 !important;
    pointer-events: none;
}

/* Пилюля едет отдельным слоем под пунктами; подложка пункта на это время
   прозрачная */
html.v2 .v2-mo-pilling > .nav-item {
    z-index: 1;
}

html.v2 .bottom-nav.v2-mo-pilling > .nav-item.active {
    background: transparent !important;
    box-shadow: none !important;
}

html.v2 .v2-mo-pill {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    display: block;
    font-style: normal;
    pointer-events: none;
    background: var(--v2-accent-fill);
    will-change: transform;
}

html.v2 .v2-side-nav.v2-mo-pilling {
    position: relative;
}

html.v2 .v2-side-nav.v2-mo-pilling > .nav-item.active {
    background: transparent !important;
}

html.v2 .v2-side-nav.v2-mo-pilling > .nav-item.active::after {
    opacity: 0;
}

html.v2 .v2-mo-pill.v2-mo-pill-side {
    height: 48px;
    border-radius: 14px;
    background: var(--v2-accent-tint);
    will-change: transform;
}

html.v2 .v2-mo-pill.v2-mo-pill-side::after {
    content: "";
    position: absolute;
    left: 0;
    top: 12px;
    bottom: 12px;
    width: 3px;
    border-radius: 3px;
    background: var(--v2-accent);
    box-shadow: var(--v2-neon);
}

/* Новая панель после renderApp: пружина иконки уже сыграла при тапе */
html.v2 .nav-item.active.v2-mo-quiet::before,
html.v2 .nav-item.active.v2-mo-quiet span {
    animation: none !important;
}

/* ============ 7. Меньше движения ============ */

/* Полёты, искры и одометр motion.js не запускает вовсе (reduced()); здесь —
   страховка и бесконечные декоративные циклы */
@media (prefers-reduced-motion: reduce) {
    html.v2 .v2-mo-layer,
    html.v2 .v2-odo,
    html.v2 .v2-mo-fly-layer,
    html.v2 .v2-mo-pill {
        display: none !important;
    }
    html.v2 .v2-dt.v2-mo-artoff .v2-dt-art-inner,
    html.v2 .v2-dt.v2-mo-hold .v2-dt-panel,
    html.v2 .v2-dt.v2-mo-hold .v2-dt-top,
    html.v2 .v2-dt.v2-mo-hold .v2-dt-cta,
    html.v2 .v2-mo-ghost {
        opacity: 1 !important;
    }
    html.v2 .v2-shim::after,
    html.v2 .v2-ring::after,
    html.v2 .ach-toast.v2-mo-ach::after {
        animation: none !important;
        display: none;
    }
    :where(html.v2) :where([role="button"], [role="link"], .v2-hero, .shop__card, .notification-item,
        .daily-bonus-btn, .notification-bell-container, .v2-meta-balance) {
        transition: none;
    }
}
