/* ==========================================================================
   Анимации карточек и реакции на указатель — стили слоя 1 из 2.

   Заполняется тем же агентом, что и js/anim-cards.js. Правила те же:
   transform и opacity, уважение к prefers-reduced-motion, никаких скрытых
   без JavaScript элементов.

   Все правила этого файла висят на классах с префиксом ac-. Классы ставит
   только скрипт, поэтому без JavaScript здесь не применяется ни одна строка,
   и страница выглядит ровно так, как выглядела до этого слоя.

   Транзишены переопределяются целиком (shorthand), а не по одному свойству:
   так видно, что ничего из базовых переходов компонента не потеряно —
   например, смена цвета границы у карточки спикера остаётся на месте.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Магнитные главные кнопки.

   Смещение задаёт скрипт в inline-transform, а здесь живёт только скорость:
   за курсором кнопка идёт коротким линейным шагом (её движение и так
   пересчитывается каждый кадр — длинный транзишен читался бы как запоздание),
   а на место возвращается пружиной.
   -------------------------------------------------------------------------- */

/* Свойства перечислены вместе с базовыми из components.css: правило не должно
   переписывать список переходов целиком, иначе у кнопки отваливается переход
   фона и рамки при наведении. */
.btn.ac-magnet {
    transition:
        transform 0.42s cubic-bezier(0.22, 1.35, 0.36, 1),
        background-color var(--dur) var(--ease),
        border-color var(--dur) var(--ease),
        color var(--dur) var(--ease);
}

/* Кнопка бронирования — единственная, кто ещё и появляется по каскаду .reveal.
   Пока появление не закончилось, подменять ей transform нельзя: слайд на 50px
   превращался в рывок со сдвигом магнита. Класс ac-magnet--ready ставит скрипт
   после того, как элемент показался. */
.btn.ac-magnet.reveal:not(.ac-magnet--ready) {
    transition:
        opacity var(--dur-slow) var(--ease) calc(var(--i, 0) * 90ms),
        transform var(--dur-slow) var(--ease) calc(var(--i, 0) * 90ms),
        background-color var(--dur) var(--ease),
        border-color var(--dur) var(--ease),
        color var(--dur) var(--ease);
}

.btn.ac-magnet.ac-magnet--on {
    transition:
        transform 0.13s linear,
        background-color var(--dur) var(--ease),
        border-color var(--dur) var(--ease),
        color var(--dur) var(--ease);
    /* Слой композитора — только пока курсор на кнопке: постоянный
       will-change держал бы в памяти слой для каждой кнопки на странице */
    will-change: transform;
}

/* --------------------------------------------------------------------------
   Рябь от нажатия.

   Узел создаёт скрипт, здесь только оформление и анимация. Двигаются
   transform и opacity — кадры уходят на композитор, перерисовки нет.
   -------------------------------------------------------------------------- */

/* Класс ставится в момент первого нажатия, а не при загрузке: без него
   у кнопок не появляется ни position, ни overflow — то есть до нажатия
   вёрстка не меняется вообще. */
.ac-ripple-host {
    position: relative;
    /* Рябь не должна вылезать за кнопку: у .btn--secondary и .tab своего
       overflow нет */
    overflow: hidden;
    /* Свой контекст наложения нужен, чтобы рябь с z-index: -1 легла над
       фоном кнопки, но под её текстом */
    z-index: 0;
}

.ac-ripple {
    position: absolute;
    z-index: -1;
    border-radius: 50%;
    pointer-events: none;
    background: radial-gradient(circle,
        rgba(250, 245, 239, 0.38) 0%,
        rgba(250, 245, 239, 0.16) 52%,
        rgba(250, 245, 239, 0) 72%);
    animation: ac-ripple 620ms var(--ease-out) forwards;
}

@keyframes ac-ripple {
    from {
        transform: translate(-50%, -50%) scale(0.16);
        opacity: 1;
    }
    to {
        transform: translate(-50%, -50%) scale(1);
        opacity: 0;
    }
}

/* --------------------------------------------------------------------------
   Наклон карточек спикеров.

   Углы считает скрипт и пишет в inline-transform: браузеру не нужно
   пересчитывать стили от кадров анимации. Здесь — только перспектива
   возврата, глубина портрета и подсветка внутри рамки.
   -------------------------------------------------------------------------- */

.speaker-card.ac-tilt {
    /* Наклон карточки чуть поворачивает её вокруг центра; соседи по сетке
       остаются на своих местах, но приподнятая карточка должна рисоваться
       поверх них */
    transform-origin: 50% 50%;
}

/* Возврат и поведение по умолчанию. Список переходов повторяет базовый из
   sections.css и добавляет к нему свои свойства: переписать список целиком
   нельзя, иначе у карточек пропадают переход opacity и каскадная задержка
   --i, и сетка спикеров перестаёт появляться ступенями — все двенадцать
   карточек выезжают разом и без затухания. */
.speaker-card.ac-tilt.is-visible {
    transition:
        opacity var(--dur-slow) var(--ease) calc(var(--i, 0) * 90ms),
        transform 0.42s cubic-bezier(0.22, 1.35, 0.36, 1),
        border-color var(--dur) var(--ease);
}

.speaker-card.ac-tilt.ac-tilt--on {
    z-index: 1;
    transition:
        transform 0.14s cubic-bezier(0.2, 0.9, 0.3, 1),
        border-color var(--dur) var(--ease);
    will-change: transform;
}

/* Портрет идёт за курсором глубже карточки. Позицию пишет скрипт в
   переменные --ac-ix/--ac-iy, а масштаб наведения (.speaker-card:hover)
   собран в ту же строку transform: inline-значение из JS перебило бы
   правило :hover из sections.css, и портрет перестал бы приближаться.

   Сдвиг ограничен 6 px не случайно: портрет вписан в рамку object-fit:
   cover и собственного запаса по краям почти не имеет, при большем сдвиге
   у края показался бы фон карточки. */
.speaker-card.ac-tilt .speaker-card__img {
    transform: translate3d(var(--ac-ix, 0px), var(--ac-iy, 0px), 0) scale(var(--ac-is, 1));
    transition:
        transform 0.5s var(--ease-out),
        filter var(--dur-slow) var(--ease),
        opacity var(--dur-slow) var(--ease);
}

.speaker-card.ac-tilt:hover .speaker-card__img {
    --ac-is: 1.05;
}

/* Пока курсор на карточке, портрет следует за ним коротким шагом —
   тем же, что и сама карточка, иначе они разъезжались бы по времени */
.speaker-card.ac-tilt.ac-tilt--on .speaker-card__img {
    transition-duration: 0.14s, var(--dur-slow), var(--dur-slow);
}

/* Подсветка внутри портрета: мягкое пятно идёт за курсором и проявляется
   на наведении. Живёт в рамке портрета, поэтому не может наехать на
   подписи и текст. */
.speaker-card.ac-tilt .speaker-card__media {
    /* Свой контекст наложения: пятно должно лечь над портретом,
       но под подписями */
    z-index: 0;
}

.speaker-card.ac-tilt .speaker-card__media::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1;
    width: 78%;
    aspect-ratio: 1;
    border-radius: 50%;
    /* Положение — только через transform: left/top остаются нулевыми,
       иначе каждый кадр вызывал бы пересчёт вёрстки */
    transform: translate3d(var(--ac-gx, 0px), var(--ac-gy, 0px), 0) translate(-50%, -50%);
    background: radial-gradient(circle,
        rgba(236, 214, 202, 0.3) 0%,
        rgba(236, 214, 202, 0.1) 46%,
        rgba(236, 214, 202, 0) 68%);
    opacity: 0;
    transition: opacity 0.45s var(--ease);
    pointer-events: none;
}

.speaker-card.ac-tilt:hover .speaker-card__media::after {
    opacity: 0.45;
}

/* Подписи остаются поверх пятна: текст не должен уходить под подсветку */
.speaker-card.ac-tilt .speaker-card__info {
    z-index: 2;
}

/* --------------------------------------------------------------------------
   Настройка «меньше движения».

   Скрипт при ней не запускается вовсе, и классов ac- здесь не появляется.
   Блок нужен на случай, если настройку включат уже после загрузки: рябь
   тогда не мигнёт, а застывшие сдвиги снимутся.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .ac-ripple {
        display: none;
    }

    .btn.ac-magnet,
    .speaker-card.ac-tilt.is-visible,
    .speaker-card.ac-tilt .speaker-card__img,
    .speaker-card.ac-tilt .speaker-card__media::after {
        transition: none;
    }

    .btn.ac-magnet.ac-magnet--on,
    .speaker-card.ac-tilt.ac-tilt--on {
        will-change: auto;
    }
}
