/* Слои страницы: фон → зерно → фигуры → контент (визуальный план v3, разделы 2, 9.3, 11).
   Только токены из tokens.css. Зерно — в base.css. */

/* ===== Обёртка страницы: от неё считаются позиции фигур (в % высоты документа) ===== */
.page {
  position: relative;
  z-index: var(--z-page);                       /* вся страница над зерном */
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow-x: clip;
}
.main,
.footer { position: relative; z-index: var(--z-content); }

/* ===== Слой фигур: никогда не ловит клики и фокус ===== */
.figures {
  position: absolute;
  inset: 0;
  z-index: var(--z-figures);
  overflow: hidden;
  pointer-events: none;
}

/* Внешняя обёртка .fig двигается параллаксом (motion.js пишет transform),
   внутренняя .fig__inner плавает CSS-анимацией — два transform не мешают друг другу.
   Цвет — тип области: <div class="fig fig--mid c--investigative">; без типа — нейтральный.
   На тёмном фоне фигура светлая (--c), на светлом — тёмный вариант того же оттенка (--c-ink). */
.fig {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--fig-size);
  height: var(--fig-size);
  color: var(--c, var(--text-2));
  transition: color var(--dur-base) var(--ease);
  will-change: transform;
}
[data-theme="light"] .fig { color: var(--c-ink, var(--text-2)); }
.fig__inner {
  width: 100%;
  height: 100%;
  animation: fig-float var(--float-dur, var(--float-default)) var(--ease-float) var(--float-delay, 0s) infinite alternate;
}
.fig svg { display: block; width: 100%; height: 100%; }

/* Четыре глубины (9.3): размер, непрозрачность, цикл плавания по умолчанию.
   Сервер обычно передаёт свой --float-dur (уже с замедлением для «тихих» страниц). */
.fig--giant { --fig-size: var(--fig-giant); --float-default: var(--float-giant); opacity: var(--fig-op-giant); }
.fig--near  { --fig-size: var(--fig-near);  --float-default: var(--float-near);  opacity: var(--fig-op-near); }
.fig--mid   { --fig-size: var(--fig-mid);   --float-default: var(--float-mid);   opacity: var(--fig-op-mid); }
.fig--far   { --fig-size: var(--fig-far);   --float-default: var(--float-far);   opacity: var(--fig-op-far); }

/* Гигантская: линия в пикселях, а не в единицах холста (иначе на 640 px была бы ~32 px).
   Плывёт с меньшей амплитудой. Ставится слотом у края экрана, частично срезана. */
.fig--giant svg * { vector-effect: non-scaling-stroke; stroke-width: var(--fig-giant-stroke); }
.fig--giant .fig__inner { animation-name: fig-float-giant; }

/* Прорисовка гигантской фигуры (страница результата, план дизайна теста v2, 6.3): слой .figures--draw.
   До прорисовки фигура скрыта, motion.js рисует её линией и ставит .is-drawing. Если motion.js не сработал,
   фигура через --fig-draw-wait сама проявляется — скрытой не остаётся. Без JS и при «уменьшить движение»
   правило не действует: фигура видна сразу. */
@media (prefers-reduced-motion: no-preference) {
  .js .figures--draw .fig--giant svg { opacity: 0; animation: fig-appear var(--dur-reveal) var(--ease) var(--fig-draw-wait) forwards; }
  .js .figures--draw .fig--giant.is-drawing svg { opacity: 1; animation: none; }
}
@keyframes fig-appear {
  to { opacity: 1; }
}

/* Слоты (9.5): позиции фигур. Сервер раздаёт номера слотов, шаблон ставит класс .fig--slot-N.
   Гигантская (0) — у правого края первого экрана, видна на 70%, остальное срезано краем.
   Обычные (1–8) — в поле слева и справа от контейнера, по очереди слева и справа.
   На каждой стороне две колонки, внешняя и внутренняя, и соседние слоты одной стороны
   стоят в разных колонках и не ближе ~четверти страницы по высоте: при параллаксе глубины
   сдвигаются с разной скоростью, и в одной колонке фигуры наезжали бы друг на друга.
   Верхние слоты не поднимаются выше --fig-first-screen (там заголовок первого экрана), а каждый
   следующий — не выше предыдущего плюс шаг: на короткой странице проценты не сводят их вместе.
   Что ниже конца страницы, срезается слоем (overflow: hidden).
   [допущение: координаты] */
.fig {
  --side: max(0px, (100% - var(--container)) / 2);                 /* ширина поля сбоку от контейнера */
  --col-out: max(var(--sp-2), var(--side) * 0.12);                 /* внешняя колонка, от края */
  --col-in: max(var(--sp-2) + var(--fig-size) * 0.7, var(--side) * 0.6 - var(--fig-size) / 2);
}
.fig--slot-0 { --x: calc(100% - var(--fig-size) * var(--fig-giant-visible)); --y: var(--sp-9); }
.fig--slot-1 { --x: var(--col-out);                                 --y: max(22%, var(--fig-first-screen)); }
.fig--slot-2 { --x: calc(100% - var(--col-in) - var(--fig-size));  --y: max(30%, calc(var(--fig-first-screen) + var(--sp-10))); }
.fig--slot-3 { --x: var(--col-in);                                  --y: max(40%, calc(var(--fig-first-screen) + var(--sp-10) * 2)); }
.fig--slot-4 { --x: calc(100% - var(--col-out) - var(--fig-size)); --y: max(50%, calc(var(--fig-first-screen) + var(--sp-10) * 3)); }
.fig--slot-5 { --x: var(--col-out);                                 --y: max(62%, calc(var(--fig-first-screen) + var(--sp-10) * 4)); }
.fig--slot-6 { --x: calc(100% - var(--col-in) - var(--fig-size));  --y: max(72%, calc(var(--fig-first-screen) + var(--sp-10) * 5)); }
.fig--slot-7 { --x: var(--col-in);                                  --y: max(83%, calc(var(--fig-first-screen) + var(--sp-10) * 6)); }
.fig--slot-8 { --x: calc(100% - var(--col-out) - var(--fig-size)); --y: max(92%, calc(var(--fig-first-screen) + var(--sp-10) * 7)); }

/* На телефоне показываются только фигуры с mobile=True (9.4) */
@media (max-width: 599.98px) {
  .fig--no-phone { display: none; }
}

@keyframes fig-float {
  from { transform: translate(0, 0) rotate(var(--float-rot-from)); }
  to   { transform: translate(var(--float-x), var(--float-y)) rotate(var(--float-rot-to)); }
}
@keyframes fig-float-giant {
  from { transform: translate(0, 0) rotate(var(--float-giant-rot-from)); }
  to   { transform: translate(var(--float-giant-x), var(--float-giant-y)) rotate(var(--float-giant-rot-to)); }
}

/* «Тихие» страницы (вуз, профиль, служебные): без ближней глубины, плавание на 30% медленнее.
   Замедляем только значение по умолчанию: серверный --float-dur уже замедлен. */
.figures--quiet .fig--near { display: none; }
.figures--quiet .fig { --float-default-quiet: calc(var(--float-default) * var(--quiet-slow)); }
.figures--quiet .fig__inner { animation-duration: var(--float-dur, var(--float-default-quiet)); }

/* ===== Всплытие блоков при прокрутке (11.5) =====
   Прячем только когда motion.js реально запустился (класс has-motion на <html>):
   без JS, при ошибке скрипта и при «уменьшить движение» всё видно сразу.
   [допущение: в 14.3 было .js — но тогда при сбое motion.js блоки остались бы скрытыми] */
.has-motion .reveal {
  transition: opacity var(--dur-reveal) var(--ease), transform var(--dur-reveal) var(--ease);
}
.has-motion .reveal:not(.is-visible) { opacity: 0; transform: translateY(var(--reveal-shift)); }

/* ===== Уменьшенное движение (11.6) ===== */
@media (prefers-reduced-motion: reduce) {
  .fig__inner { animation: none; }
  .has-motion .reveal:not(.is-visible) { opacity: 1; transform: none; }
  *, *::before, *::after { transition-duration: 0.01ms !important; transition-delay: 0s !important; }
  /* смены цвета остаются, не дольше --dur-base */
  body { transition-duration: var(--dur-base) !important; }
}


/* ===== Производительность ===== */

/* Слабое устройство (html.lite, см. base.html): размытие стекла — самый дорогой эффект, поэтому плашки получают
   плотный фон вместо него; цвет тот же, что у запасного варианта без blur. Форма, расположение и движение не меняются. */
html.lite *,
html.lite *::before,
html.lite *::after {
  -webkit-backdrop-filter: none !important;
  backdrop-filter: none !important;
}
html.lite[data-theme] {
  --glass-bg: var(--glass-fallback);
  --glass-bg-hover: var(--glass-fallback);
}

/* Слабое устройство, облегчение вида (композиция узнаваема, нагрузка меньше):
   — дальние и средние фигуры скрыты, остаются ближние и гигантские (у каждой фигуры свой слой и анимация);
   — фигуры не плавают (вечный fig-float греет процессор и без прокрутки), параллакс при прокрутке остаётся (motion.js);
   — лента новостей и «reel» статичны: без бесконечной прокрутки и второй копии; лента новостей листается пальцем. */
html.lite .fig--far,
html.lite .fig--mid { display: none; }
html.lite .fig__inner,
html.lite .qfig__float { animation: none; }
html.lite .ticker__track { animation: none; }
html.lite .ticker__track--copy,
html.lite .reel__group[aria-hidden="true"] { display: none; }
html.lite .reel__track { animation: none; will-change: auto; }

/* Блок вне экрана (motion.js ставит .is-idle): его вечные анимации на паузе. Пауза, а не сброс: при возвращении
   в экран движение продолжается с того же места, скачка нет. */
.is-idle,
.is-idle *,
.is-idle *::before,
.is-idle *::after { animation-play-state: paused !important; }
