/* ===== движение ============================================
   Правила: анимируем только transform/opacity, длительности из
   токенов, всё гасится по prefers-reduced-motion.
   ============================================================ */

@keyframes rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@keyframes fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes grow-x {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}
@keyframes sheen {
  from { transform: translateX(-100%); }
  to   { transform: translateX(100%); }
}
@keyframes pop {
  0%   { transform: scale(.94); opacity: .4; }
  60%  { transform: scale(1.015); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes float-soft {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-10px); }
}
@keyframes combo-in {
  from { opacity: 0; transform: translateY(-6px) scale(.99); }
  to   { opacity: 1; transform: none; }
}
@keyframes shimmer {
  from { background-position: -420px 0; }
  to   { background-position: 420px 0; }
}

/* --- появление секций при скролле ----------------------------
   Прячем только когда JS точно жив (.js ставится первым же скриптом).
   Иначе без JS — и на самом первом кадре — половина страницы была бы
   пустой, а её должно быть видно сразу. */
.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity var(--dur-5) var(--ease-out), transform var(--dur-5) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  /* НЕ ставим will-change: он навсегда уводит элемент в отдельный слой
     композитора, где текст рисуется без субпиксельного сглаживания —
     вся страница из-за этого выглядела мыльной. Анимация одноразовая,
     браузер справится и без подсказки. */
}
.js .reveal.is-in { opacity: 1; transform: none; }

/* --- стартовая анимация героя (без наблюдателя) -------------- */
.enter { animation: rise var(--dur-5) var(--ease-out) both; }
.enter-1 { animation-delay: 60ms; }
.enter-2 { animation-delay: 140ms; }
.enter-3 { animation-delay: 220ms; }
.enter-4 { animation-delay: 300ms; }
.enter-5 { animation-delay: 380ms; }

.hero__glow { animation: float-soft 14s ease-in-out infinite; }

/* --- смена панели степпера ----------------------------------- */
.panel-swap { animation: rise var(--dur-4) var(--ease-out) both; }

/* --- пересчёт цены ------------------------------------------- */
.price.is-updating { animation: pop var(--dur-4) var(--ease-out); }

/* --- скелет во время «запроса к модели» ---------------------- */
.skeleton {
  border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-2) 50%, var(--surface-3) 75%);
  background-size: 420px 100%;
  animation: shimmer 1.2s linear infinite;
  color: transparent !important;
}

/* при печати и снимках страницы целиком скрывать нечего */
@media print {
  .js .reveal { opacity: 1 !important; transform: none !important; }
}

/* --- уважение к настройкам пользователя ---------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .js .reveal { opacity: 1; transform: none; }
}
