/*==================================================================
  ANIMATIONS — слой анимаций появления
  ------------------------------------------------------------------
  Правила безопасности, заложенные в этот файл:

  1. Всё скрытое состояние живёт ТОЛЬКО под `html.has-reveal` и только
     на классе `.anim`, который проставляет animations.js. Без JS класса
     `.anim` не появится — контент виден по умолчанию. Если не отработал
     даже инлайн-скрипт в <head>, не будет и `has-reveal`, и файл не
     скроет вообще ничего.
  2. Анимируем только transform и opacity — работа композитора,
     без пересчёта раскладки и без CLS.
  3. Ни одного transform/filter/perspective на html, body и любом
     предке #header: у шапки position: sticky (main.css:353),
     transform на предке сделал бы её обычным блоком.
  4. Никакого overflow-x на html: сейчас overflow-x: hidden стоит на
     body (main.css:35) и пробрасывается на viewport — именно поэтому
     sticky и работает. Трогать нельзя.
  5. Слайдеры Swiper (.swiper-wrapper/.swiper-slide), Яндекс-карта и
     панели вкладок здесь не упоминаются вовсе — анимируются только
     заголовки таких секций.
==================================================================*/


/*---------------------------------------------------------------
  1. ПЕРВЫЙ ЭКРАН
  ---------------------------------------------------------------
  Баннер появляется сразу, без IntersectionObserver: keyframes
  стартуют самостоятельно, поэтому даже если animations.js не
  загрузился, первый экран отработает и останется видимым
  (animation-fill-mode: both + конечный кадр = обычное состояние).

  .main-title — это LCP-элемент страницы. Ему намеренно НЕ даём
  opacity: 0: элемент рисуется сразу на полной непрозрачности и
  только смещается. Так метрика LCP не сдвигается ни на кадр.
  .main-background (тяжёлое фото баннера) не анимируется вообще.
----------------------------------------------------------------*/
@keyframes anim-hero-shift {
  from { transform: translate3d(0, 14px, 0); }
  to   { transform: none; }
}

@keyframes anim-hero-rise {
  from { opacity: 0; transform: translate3d(0, 18px, 0); }
  to   { opacity: 1; transform: none; }
}

/* Заголовок: только смещение, без прозрачности — бережём LCP */
html.has-reveal #main-block .main-title {
  animation: anim-hero-shift 520ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

html.has-reveal #main-block .main-desc,
html.has-reveal #main-block .main-btn-wrapper,
html.has-reveal #main-block .main-card {
  animation: anim-hero-rise 520ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

html.has-reveal #main-block .main-desc        { animation-delay: 90ms; }
html.has-reveal #main-block .main-btn-wrapper { animation-delay: 170ms; }
html.has-reveal #main-block .main-card        { animation-delay: 240ms; }

/* Карточки-преимущества под баннером — короткой лесенкой */
html.has-reveal #main-block .main-list-item {
  animation: anim-hero-rise 520ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

html.has-reveal #main-block .main-list-item:nth-child(1) { animation-delay: 300ms; }
html.has-reveal #main-block .main-list-item:nth-child(2) { animation-delay: 370ms; }
html.has-reveal #main-block .main-list-item:nth-child(3) { animation-delay: 440ms; }
html.has-reveal #main-block .main-list-item:nth-child(4) { animation-delay: 510ms; }
html.has-reveal #main-block .main-list-item:nth-child(n + 5) { animation-delay: 580ms; }


/*---------------------------------------------------------------
  2. ПОЯВЛЕНИЕ ПРИ СКРОЛЛЕ
  ---------------------------------------------------------------
  Классы `.anim` и `.anim--*` навешивает animations.js и только на
  те элементы, которые в момент загрузки находятся НИЖЕ экрана и
  реально отрисованы. После окончания перехода скрипт снимает все
  свои классы — элемент возвращается к «родному» состоянию, поэтому
  will-change не залипает и собственные hover-переходы блоков
  (например `transition: all .3s` у .fault-item) не перебиваются.
----------------------------------------------------------------*/
html.has-reveal .anim {
  opacity: 0;
  transition:
    opacity 520ms cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 520ms cubic-bezier(0.22, 0.61, 0.36, 1);
  transition-delay: var(--anim-delay, 0ms);
  will-change: opacity, transform;
}

/* Направления смещения. Держим в пределах 16-24px — сдержанно. */
html.has-reveal .anim--up    { transform: translate3d(0, 24px, 0); }
html.has-reveal .anim--left  { transform: translate3d(-24px, 0, 0); }
html.has-reveal .anim--right { transform: translate3d(24px, 0, 0); }
html.has-reveal .anim--fade  { transform: none; }

/* Конечное состояние: два класса в селекторе — перебивает .anim--* */
html.has-reveal .anim.is-visible {
  opacity: 1;
  transform: none;
}


/*---------------------------------------------------------------
  3. УВАЖЕНИЕ К НАСТРОЙКЕ «УМЕНЬШИТЬ ДВИЖЕНИЕ»
  ---------------------------------------------------------------
  Основную защиту даёт инлайн-скрипт в <head>: при включённой
  настройке он вообще не ставит `has-reveal`, и ни одно правило выше
  не применяется. Этот блок — вторая линия обороны на случай, когда
  настройку меняют уже после загрузки страницы.
----------------------------------------------------------------*/
@media (prefers-reduced-motion: reduce) {
  html.has-reveal .anim,
  html.has-reveal .anim--up,
  html.has-reveal .anim--left,
  html.has-reveal .anim--right,
  html.has-reveal .anim--fade,
  html.has-reveal .anim.is-visible {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    will-change: auto !important;
  }

  html.has-reveal #main-block .main-title,
  html.has-reveal #main-block .main-desc,
  html.has-reveal #main-block .main-btn-wrapper,
  html.has-reveal #main-block .main-card,
  html.has-reveal #main-block .main-list-item {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
  }

  html {
    scroll-behavior: auto !important;
  }
}
