/* =============================================================================
   Движение и живые элементы

   Отдельным файлом, потому что всё здесь необязательное: если стили
   не загрузятся, страница останется полностью читаемой и рабочей.

   Правила, которых держимся:
   1. Анимация несёт смысл, а не украшает. Появление подсказывает, что блок
      новый; сдвиг карточки вверх говорит, что по ней можно нажать.
   2. Длительность 180–450 мс. Дольше выглядит медленно, короче незаметно.
   3. Двигаем только transform и opacity. Анимация ширины и высоты заставляет
      браузер пересчитывать раскладку и даёт дёрганье на слабых телефонах.
   4. prefers-reduced-motion выключает всё. Часть посетителей от анимаций
      испытывает физический дискомфорт, и это не мелочь.
============================================================================= */

/* --------------------------------------------------- Появление при скролле */

/* Элемент скрыт только когда скрипт подтвердил, что умеет его показать.
   Иначе при выключенном JS половина страницы осталась бы невидимой. */
.js-motion [data-reveal] {
    opacity: 0;
    transform: translateY(22px);
    transition:
        opacity 520ms cubic-bezier(.22, .61, .36, 1),
        transform 520ms cubic-bezier(.22, .61, .36, 1);
    will-change: opacity, transform;
}
.js-motion [data-reveal].is-visible {
    opacity: 1;
    transform: none;
    will-change: auto;
}

/* Боковое появление разрешено только там, где по краям экрана есть запас.

   Блок, сдвинутый вправо на 28 пикселей, ровно на столько же расширяет
   страницу — и так до тех пор, пока не попадёт в поле зрения и сдвиг
   не снимется. Отсюда и странность, которую было трудно поймать: сайт
   не помещался в экран телефона, а после прокрутки до середины вдруг
   начинал помещаться. Ширина контейнера 1240, поэтому запас появляется
   примерно с 1300 пикселей. Всё, что уже, появляется снизу вверх. */
.js-motion [data-reveal="left"],
.js-motion [data-reveal="right"] { transform: translateY(22px); }

@media (min-width: 1300px) {
    .js-motion [data-reveal="left"]  { transform: translateX(-28px); }
    .js-motion [data-reveal="right"] { transform: translateX(28px); }
}

.js-motion [data-reveal="scale"] { transform: scale(.955); }
.js-motion [data-reveal="blur"]  { filter: blur(6px); transition-property: opacity, transform, filter; }
.js-motion [data-reveal="blur"].is-visible { filter: none; }

/* Каскад для сеток: элементы появляются по очереди, а не разом */
.js-motion [data-reveal-stagger] > * {
    opacity: 0;
    transform: translateY(18px);
    transition:
        opacity 460ms cubic-bezier(.22, .61, .36, 1),
        transform 460ms cubic-bezier(.22, .61, .36, 1);
}
.js-motion [data-reveal-stagger].is-visible > * { opacity: 1; transform: none; }
.js-motion [data-reveal-stagger].is-visible > *:nth-child(1) { transition-delay: 0ms; }
.js-motion [data-reveal-stagger].is-visible > *:nth-child(2) { transition-delay: 70ms; }
.js-motion [data-reveal-stagger].is-visible > *:nth-child(3) { transition-delay: 140ms; }
.js-motion [data-reveal-stagger].is-visible > *:nth-child(4) { transition-delay: 210ms; }
.js-motion [data-reveal-stagger].is-visible > *:nth-child(5) { transition-delay: 260ms; }
.js-motion [data-reveal-stagger].is-visible > *:nth-child(6) { transition-delay: 310ms; }
.js-motion [data-reveal-stagger].is-visible > *:nth-child(n+7) { transition-delay: 350ms; }

/* ------------------------------------------------------------- Заголовки */

/* Подчёркивание, которое дорисовывается при появлении заголовка */
/* Линия под словами.
   Фразу держим на одной строке: при переносе фон рисуется под обоими
   фрагментами, и вместо одной черты получаются две разной длины.
   Но только начиная с планшета: на узком экране запрет переноса выталкивал
   заголовок за край, и всю страницу можно было утащить вбок пальцем. */
.underline-draw {
    position: relative;
    display: inline;
    background-image: linear-gradient(var(--accent), var(--accent));
    background-repeat: no-repeat;
    background-position: 0 88%;
    background-size: 0 3px;
    transition: background-size 700ms cubic-bezier(.22, .61, .36, 1) 180ms;
    padding-bottom: 2px;
}
@media (min-width: 768px) { .underline-draw { white-space: nowrap; } }
.is-visible .underline-draw,
.underline-draw.is-visible { background-size: 100% 3px; }

/* ------------------------------------------------------------ Счётчики */

.counter { font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------- Живые элементы */

/* Мягкое «дыхание» у кнопки мессенджеров: замечается боковым зрением,
   но не отвлекает от чтения */
@keyframes pulse-ring {
    0%   { transform: scale(.92); opacity: .55; }
    70%  { transform: scale(1.5);  opacity: 0; }
    100% { transform: scale(1.5);  opacity: 0; }
}

/* Медленный дрейф декоративного пятна в героя */
@keyframes drift {
    0%,100% { transform: translate3d(0, 0, 0) scale(1); }
    50%     { transform: translate3d(18px, -22px, 0) scale(1.06); }
}

/* Бегущая полоса в блоке с фактами */
@keyframes marquee {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
}

/* Мерцание для скелетона изображений */
@keyframes shimmer {
    from { background-position: -140% 0; }
    to   { background-position: 240% 0; }
}

/* ------------------------------------------------------------- Наведение */

.hover-lift {
    transition: transform 250ms cubic-bezier(.22,.61,.36,1),
                box-shadow 250ms cubic-bezier(.22,.61,.36,1);
}
.hover-lift:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }

/* Стрелка, выезжающая при наведении на ссылку */
.link-arrow svg,
.card__arrow svg { transition: transform 220ms cubic-bezier(.22,.61,.36,1); }
.link-arrow:hover svg,
a:hover .card__arrow svg { transform: translateX(5px); }

/* -------------------------------------------------- Прогресс чтения */

.read-progress {
    position: fixed;
    top: 0; left: 0;
    height: 3px;
    width: 100%;
    transform: scaleX(0);
    transform-origin: 0 50%;
    background: linear-gradient(90deg, var(--primary), var(--accent));
    z-index: 101;
    pointer-events: none;
}

/* ----------------------------------------------------------- Отключение */

@media (prefers-reduced-motion: reduce) {
    .js-motion [data-reveal],
    .js-motion [data-reveal-stagger] > * {
        opacity: 1 !important;
        transform: none !important;
        filter: none !important;
        transition: none !important;
    }
    .underline-draw { background-size: 100% 3px; transition: none; }
    .messengers__pulse,
    .hero__blob { animation: none !important; }
    .read-progress { display: none; }
}
