/* ══════════════════════════════════════════════════════
   AN System · анимации при прокрутке
   Общие для index.html и prices.html. Включаются классом .mo на <html>,
   который ставит motion.js: без скрипта страница выглядит как раньше.

   Правила: только transform, opacity и clip-path; один раз при первом
   появлении; кривая сайта --ease. При «уменьшить движение» — без сдвигов.
══════════════════════════════════════════════════════ */

/* Полоса прогресса чтения. Масштаб, а не ширина: не трогает раскладку. */
.mo-progress{
  position:fixed; top:0; left:0; right:0; height:2px; z-index:1000; pointer-events:none;
  background:linear-gradient(90deg, var(--acc), var(--acc-2));
  box-shadow:0 0 10px rgba(91,139,255,.55);
  transform:scaleX(0); transform-origin:0 50%;
}

/* Заголовки разделов: каждое слово выезжает из-под маски. */
.mo .mo-w{ display:inline-block; overflow:hidden; vertical-align:top; padding-bottom:.14em; margin-bottom:-.14em; }
.mo .mo-w > span{
  display:inline-block; transform:translateY(108%);
  transition:transform .85s var(--ease); transition-delay:calc(var(--wi, 0) * 45ms);
}
.mo .mo-in .mo-w > span{ transform:none; }

/* Подпись над заголовком «печатается» шторкой слева направо. */
.mo .kicker.mo-k{ clip-path:inset(0 100% 0 0); transition:clip-path .7s var(--ease) .05s; }
.mo .kicker.mo-k.mo-in{ clip-path:inset(0 0 0 0); }

/* Сетки, которые раньше появлялись одним куском: теперь карточки по очереди.
   Пока идёт появление, родная анимация наведения карточек отключена,
   иначе подъём при наведении получил бы задержку появления. */
.mo .mo-stagger.reveal{ opacity:1; transform:none; }
.mo .mo-stagger:not(.mo-done) > *{
  opacity:0; transform:translateY(22px);
  transition:opacity .6s var(--ease), transform .75s var(--ease);
  transition-delay:calc(var(--i, 0) * 70ms);
}
.mo .mo-stagger.shown:not(.mo-done) > *{ opacity:1; transform:none; }

/* Параллакс и уход первого экрана двигает скрипт, здесь только подсказка браузеру. */
.mo-px{ display:block; will-change:transform; }
.mo-hero-out{ will-change:transform, opacity; }

@media (prefers-reduced-motion:reduce){
  /* Меньше и мягче, а не ноль: без сдвигов, но с коротким проявлением. */
  .mo .mo-w > span{ transform:none; transition:none; }
  .mo .kicker.mo-k{ clip-path:none; transition:none; }
  .mo .mo-stagger:not(.mo-done) > *{ transform:none; transition:opacity .25s ease; transition-delay:0s; }
  .mo-px,.mo-hero-out{ will-change:auto; }
}

/* ══════════════════════════════════════════════════════
   ВАУ-СЛОЙ: 3D-система, раскрытие разделов, слова-призраки,
   наклон карточек, зерно. Приёмы — из бесплатных промтов
   motionsites.ai (vision-reveal, 3d-collectible-hero), переложены
   на палитру и шрифты сайта.
══════════════════════════════════════════════════════ */

/* 3D-система из частиц: под всем контентом, над фоном страницы */
.mo-scene{ position:fixed; inset:0; width:100%; height:100%; z-index:-1; pointer-events:none; }

/* Плёночное зерно — едва заметное, но делает картинку «киношной» */
.mo-grain{
  position:fixed; inset:-50%; z-index:900; pointer-events:none; opacity:.05; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:200px 200px;
}

/* Огромные контурные слова за разделами, плывут вбок при прокрутке */
.mo-ghost{ position:absolute; inset:0; overflow:hidden; pointer-events:none; z-index:0; }
.mo-ghost span{
  position:absolute; top:clamp(24px,6vw,72px); left:0; white-space:nowrap;
  font-family:var(--display); font-weight:700; text-transform:uppercase; letter-spacing:-.03em; line-height:.9;
  font-size:clamp(84px,17vw,260px); color:transparent;
  -webkit-text-stroke:1px rgba(143,173,255,.13); text-stroke:1px rgba(143,173,255,.13);
  will-change:transform;
}
.mo-ghost-host{ position:relative; }
.mo-ghost-host > .c{ position:relative; z-index:1; }

/* Заголовки: слова ещё и проявляются из размытия (на телефоне без размытия — бережём кадры) */
@media (min-width:761px){
  .mo .mo-w > span{ filter:blur(8px); opacity:0; transition:transform .85s var(--ease), filter .7s var(--ease), opacity .6s var(--ease); transition-delay:calc(var(--wi, 0) * 45ms); }
  .mo .mo-in .mo-w > span{ filter:blur(0); opacity:1; }
}

/* Раздел раскрывается в 3D: наклон задаёт скрипт, тут — точка опоры */
.mo-unfold{ transform-origin:50% 0%; will-change:transform; }
/* Страховка от прокрутки вбок во время раскрытия. clip, а не hidden: не ломает липкие панели внутри. */
.mo-unfold-host{ overflow-x:clip; }

/* Наклон карточек за курсором (только мышь) */
@media (hover:hover) and (pointer:fine){
  .mo .mo-tilt:hover{ transform:perspective(900px) rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg)) translateY(-6px); }
}

@media (prefers-reduced-motion:reduce){
  .mo-grain{ display:none; }
  .mo-ghost span{ will-change:auto; }
  .mo .mo-w > span{ filter:none; opacity:1; }
  .mo .mo-tilt:hover{ transform:none; }
}

/* Тёмный ореол под текстом: снаружи не виден, но отделяет буквы от светящихся точек сзади */
.mo-has-scene .section-head h2,.mo-has-scene .section-head p,.mo-has-scene .section-desc,
.mo-has-scene .kicker,.mo-has-scene .panel-head h2,.mo-has-scene .panel-head p,.mo-has-scene .rv-head h2,
.mo-has-scene .how-aside h2,.mo-has-scene .how-what,.mo-has-scene .hero-desc{
  text-shadow:0 0 16px rgba(13,14,18,.95), 0 0 5px rgba(13,14,18,.9);
}

/* ══════════════════════════════════════════════════════
   ПЕРЕХОДЫ МЕЖДУ БЛОКАМИ — на нативной анимации прокрутки браузера.
   Работает вне основного потока, поэтому на телефоне плавнее скрипта.
   Где браузер не умеет (старый Firefox), включается запасной вариант из motion.js.

   1. Цветная полоса-раздел въезжает закруглённой панелью и раскрывается на всю ширину.
   2. По её верхней кромке пробегает синяя световая линия.
   3. Содержимое раздела поднимается из глубины.
   4. Уходящий вверх блок отъезжает назад и гаснет — слои «перелистываются».
══════════════════════════════════════════════════════ */
.mo-seam{ position:absolute; top:0; left:0; right:0; height:2px; z-index:3; pointer-events:none;
  background:linear-gradient(90deg, transparent, rgba(91,139,255,.25) 18%, #8fadff 50%, rgba(91,139,255,.25) 82%, transparent);
  box-shadow:0 0 22px 2px rgba(47,107,255,.55); transform:scaleX(0); opacity:0; }

@supports (animation-timeline: view()){
  @media (prefers-reduced-motion: no-preference){
    .mo-panel{
      animation:moPanel linear both; animation-timeline:view(); animation-range:entry 0% entry 90%;
    }
    .mo-panel .mo-seam{
      animation:moSeam linear both; animation-timeline:view(); animation-range:entry 15% entry 75%;
    }
    .mo-sec{ perspective:1600px; perspective-origin:50% 0%; }
    .mo-sec > .c{
      transform-origin:50% 0%;
      animation:moRise linear both, moSink linear both;
      animation-timeline:view(), view();
      animation-range:entry 0% entry 80%, exit 30% exit 100%;
    }
  }
}
/* В конце рамка уходит за края: иначе навсегда обрезались бы свечения, заходящие на соседние блоки */
@keyframes moPanel{
  0%{ clip-path:inset(0 6% 0 6% round 56px); }
  92%{ clip-path:inset(0 0 0 0 round 0px); }
  100%{ clip-path:inset(-160px -160px -160px -160px round 0px); }
}
@keyframes moSeam{
  0%{ transform:scaleX(0); opacity:0; }
  30%{ opacity:1; }
  100%{ transform:scaleX(1); opacity:.55; }
}
/* translate/rotate и scale — разные свойства: подъём и уход не мешают друг другу */
@keyframes moRise{
  from{ translate:0 90px; rotate:x -9deg; }
  to{ translate:0 0; rotate:x 0deg; }
}
@keyframes moSink{
  from{ scale:1; opacity:1; }
  to{ scale:.9; opacity:.15; }
}
@media (max-width:760px){
  @keyframes moPanel{
    0%{ clip-path:inset(0 3.5% 0 3.5% round 30px); }
    92%{ clip-path:inset(0 0 0 0 round 0px); }
    100%{ clip-path:inset(-160px -160px -160px -160px round 0px); }
  }
  @keyframes moRise{
    from{ translate:0 56px; rotate:x -6deg; }
    to{ translate:0 0; rotate:x 0deg; }
  }
}
