/* =====================================================================
   ВАРИАНТ A — ПЕЧАТНЫЙ СТАНОК

   Загрузка — это печать листа, а не ожидание данных. Сначала чистая
   бумага с приводочными крестами по углам. На неё в два прогона вала
   ложится краска: сначала красная форма (M), потом чёрная (K), и
   приводка сходится с еле заметным щелчком. Тот же станок печатает
   и сам первый экран: чёрный прогон приносит кадры, набор и рукопись,
   красный — плашки, точки и фамилию, и все красные слои приходят
   со сдвигом, который сводится в ноль одним движением.

   Ни одного нового цвета, скругления, тени и градиента: та же бумага
   #eeeeee, те же чернила, тот же красный, тот же моноширинный
   прописными. Всё движение — только transform и opacity.

   ФАЗЫ. Ими управляет атрибут на <html>:
     data-boot="run"    — заставка (лист печатается)
     data-boot="print"  — сборка первого экрана
     атрибута нет       — обычный сайт (в том числе когда JS не работает)

   ПРОВЕРКА. Все задержки написаны как calc(var(--d) - var(--seek)).
   Служебный --seek сдвигает весь сценарий назад, поэтому ?step=1500
   показывает статичный кадр «полторы секунды» — без него в headless
   время анимаций не идёт и виден только первый кадр.
   ===================================================================== */

/* =====================================================================
   1. ПЕЧАТНЫЙ СЛОЙ
   ===================================================================== */

.press {
  position: fixed;
  inset: 0;
  z-index: 100;
  overflow: hidden;
  pointer-events: none;
}

/* Чистый лист. Под ним лежит точно такая же бумага первого экрана,
   поэтому в начале сборки его можно просто снять — подмены не видно. */
.press__sheet {
  position: absolute;
  inset: 0;
  background: var(--bg);
}

.press__paper {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: var(--paper-opacity);
  mix-blend-mode: var(--paper-blend);
}

/* --- служебное поле листа: кресты приводки и метки формы ------------- */
.press__marks { position: absolute; inset: 0; }

.press__cross {
  position: absolute;
  width: 34px;
  height: 34px;
  color: var(--ink);
}

.press__cross svg { width: 100%; height: 100%; display: block; }
.press__cross svg circle,
.press__cross svg path { stroke: currentColor; stroke-width: 1; }

/* Кресты красной формы стоят со сдвигом — это и есть та неточность
   приводки, которую станок потом сводит. */
.press__cross--m { color: var(--red); }

.press__cross--tl { left: 26px;  top: 26px; }
.press__cross--tr { right: 26px; top: 26px; }
.press__cross--bl { left: 26px;  bottom: 26px; }
.press__cross--br { right: 26px; bottom: 26px; }

.press__slug {
  position: absolute;
  left: 76px;
  bottom: 32px;
  font-size: 11px;
  line-height: 14px;
  color: var(--ink);
  opacity: 0.55;
}

.press__slug--right { left: auto; right: 76px; }

/* --- центр листа ----------------------------------------------------- */
.press__plate {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
}

.press__word {
  position: relative;
  display: block;
  margin: 0;
  white-space: nowrap;
}

.press__ink {
  display: block;
  font-family: var(--font-mono);
  font-size: clamp(26px, 4.4vw, 60px);
  line-height: 1.1;
  letter-spacing: var(--mono-ls);
  text-transform: uppercase;
}

/* Красная краска ложится первой и со сдвигом, чёрная накрывает её
   сверху — тот же приём, что у оттиска с плохой приводкой. */
.press__ink--m { position: absolute; left: 0; top: 0; color: var(--red); }
.press__ink--k { position: relative; color: var(--ink); }

.press__count {
  margin: 26px 0 0;
  font-size: 13px;
  line-height: 16px;
  color: var(--ink);
}

/* Шкала плотности краски — четыре чёрных поля и четыре красных, как на
   поле типографского листа. Заполняется по числу отпечатанного. */
.press__scale {
  display: flex;
  justify-content: center;
  gap: 6px;
  margin-top: 14px;
}

.press__patch {
  width: 14px;
  height: 14px;
  border: 1px solid rgba(0, 0, 0, 0.28);
}

.press__patch[data-on] { opacity: var(--a); }
.press__patch--k[data-on] { background: var(--ink); border-color: var(--ink); }
.press__patch--m[data-on] { background: var(--red); border-color: var(--red); }

/* --- вал -------------------------------------------------------------
   Полоса с жёсткой нижней кромкой идёт сверху вниз: за кромкой краска
   уже легла, перед ней лист ещё чистый. Плоская заливка, без градиента. */
.press__roller {
  position: absolute;
  left: 0;
  width: 100%;
  height: 24vh;
  transform: translateY(-130%);
  will-change: transform;
}

.press__roller--k {
  top: 0;
  background: rgba(0, 0, 0, 0.06);
  border-bottom: 2px solid var(--ink);
}

.press__roller--m {
  top: 0;
  background: rgba(224, 51, 66, 0.07);
  border-bottom: 2px solid var(--red);
}

/* =====================================================================
   2. ЗАСТАВКА — data-boot="run"

   Печатается имя: сначала красный слой, потом чёрный, потом приводка
   сходится. Заставка держится ровно столько, сколько грузятся кадры и
   шрифты, но не дольше 1,15 с (см. a.js).
   ===================================================================== */

/* До печати ничего нет: ни на листе, ни в композиции под ним. */
html[data-boot] .press__ink,
html[data-boot] .press__count,
html[data-boot] .press__scale,
html[data-boot] .press__slug { opacity: 0; }

html[data-boot] .stage > :not(.paper) { opacity: 0; }
html[data-boot] .stage .tag::before { opacity: 0; }

@keyframes press-in  { from { opacity: 0 } to { opacity: 1 } }
@keyframes press-out { from { opacity: 1 } to { opacity: 0 } }

/* Красный слой имени: приходит со сдвигом и держит его до приводки. */
html[data-boot="run"] .press__ink--m {
  --d: 100ms;
  --d2: 600ms;
  animation:
    press-in 240ms linear calc(var(--d) - var(--seek, 0ms)) both,
    press-reg 280ms cubic-bezier(0.2, 0.85, 0.25, 1) calc(var(--d2) - var(--seek, 0ms)) both;
}

/* Чёрный слой — вторым прогоном, точно на месте. */
html[data-boot="run"] .press__ink--k {
  --d: 300ms;
  animation: press-in 220ms linear calc(var(--d) - var(--seek, 0ms)) both;
}

html[data-boot="run"] .press__count,
html[data-boot="run"] .press__scale,
html[data-boot="run"] .press__slug {
  --d: 160ms;
  animation: press-in 300ms linear calc(var(--d) - var(--seek, 0ms)) both;
}

/* =====================================================================
   3. СБОРКА — data-boot="print". ЧЁРНАЯ ФОРМА (K)

   Лист снимается (под ним та же бумага), заставочный набор уходит,
   и по композиции идёт первый прогон вала. Каждый элемент впечатывается
   в тот момент, когда до него дошла кромка: задержка пропорциональна
   его высоте в макете. Оттиск — это короткая посадка на 4px и набор
   плотности, а не выезд откуда-то сбоку.
   ===================================================================== */

@keyframes ink-k {
  from { opacity: 0; transform: translateY(-4px) var(--base, ); }
  to   { opacity: 1; transform: translateY(0)    var(--base, ); }
}

@keyframes roll-k {
  from { transform: translateY(-130%); }
  to   { transform: translateY(400%); }
}

@keyframes roll-m {
  from { transform: translateY(-130%); }
  to   { transform: translateY(480%); }
}

html[data-boot="print"] .press__sheet {
  animation: press-out 160ms linear calc(0ms - var(--seek, 0ms)) both;
}

html[data-boot="print"] .press__plate {
  animation: plate-out 220ms ease-in calc(0ms - var(--seek, 0ms)) both;
}

@keyframes plate-out {
  from { opacity: 1; transform: translate(-50%, -50%); }
  to   { opacity: 0; transform: translate(-50%, calc(-50% - 10px)); }
}

html[data-boot="print"] .press__roller--k {
  --d: 100ms;
  animation: roll-k 720ms linear calc(var(--d) - var(--seek, 0ms)) both;
}

html[data-boot="print"] .press__roller--m {
  --d: 760ms;
  animation: roll-m 640ms linear calc(var(--d) - var(--seek, 0ms)) both;
}

/* Общее правило чёрной формы: всё, что печатается чёрным. */
html[data-boot="print"] .stage .logo,
html[data-boot="print"] .stage .nav-row,
html[data-boot="print"] .stage .pic--portrait,
html[data-boot="print"] .stage .pic--collage-top,
html[data-boot="print"] .stage .pic--collage-bottom,
html[data-boot="print"] .stage .hand--name,
html[data-boot="print"] .stage .tag,
html[data-boot="print"] .stage .geo,
html[data-boot="print"] .stage .soc--tg,
html[data-boot="print"] .stage .soc--vk,
html[data-boot="print"] .stage .soc--inst,
html[data-boot="print"] .stage .disclaimer,
html[data-boot="print"] .stage .grain {
  animation: ink-k 240ms ease-out calc(var(--d) - var(--seek, 0ms)) both;
}

/* Задержки = высота элемента в макете, приведённая к длине прогона.
   Шапка и портрет — сразу за кромкой, сноска внизу — последней. */
html[data-boot="print"] .stage .logo            { --d: 200ms; }
/* Меню печатается одной строкой: пункты больше не стоят по отдельным
   координатам, и разводить их по времени незачем. --base убран вместе
   с выключкой по середине — строка выключена по левому краю. */
html[data-boot="print"] .stage .nav-row        { --d: 205ms; --base: translateX(-50%); }
html[data-boot="print"] .stage .pic--portrait   { --d: 200ms; }
html[data-boot="print"] .stage .pic--collage-top    { --d: 255ms; }
html[data-boot="print"] .stage .pic--collage-bottom { --d: 445ms; }
html[data-boot="print"] .stage .hand--name      { --d: 410ms; --base: rotate(var(--hand-name-rot)); }
html[data-boot="print"] .stage .tag--vedushiy   { --d: 510ms; --d2: 1016ms; }
html[data-boot="print"] .stage .tag--sobytiy    { --d: 533ms; --d2: 1032ms; }
html[data-boot="print"] .stage .tag--tantsuyu   { --d: 577ms; --d2: 1063ms; }
html[data-boot="print"] .stage .tag--poyu       { --d: 599ms; --d2: 1079ms; }
html[data-boot="print"] .stage .tag--raduyus    { --d: 625ms; --d2: 1098ms; }
html[data-boot="print"] .stage .tag--zhivu      { --d: 657ms; --d2: 1121ms; }
html[data-boot="print"] .stage .geo             { --d: 626ms; }
html[data-boot="print"] .stage .soc--tg         { --d: 698ms; }
html[data-boot="print"] .stage .soc--vk         { --d: 706ms; }
html[data-boot="print"] .stage .soc--inst       { --d: 714ms; }
html[data-boot="print"] .stage .disclaimer      { --d: 726ms; }

/* Зерно — последним слоем, как лак: лист уже допечатан. */
html[data-boot="print"] .stage .grain { --d: 1500ms; }

/* =====================================================================
   4. КРАСНАЯ ФОРМА (M) И ПРИВОДКА

   Красное приходит вторым прогоном и садится НЕ на место: у каждого
   слоя свой сдвиг в несколько пикселей. В 1420 мс все красные слои
   одним движением сходятся в ноль — это и есть приводка. Ради этого
   у элементов две анимации: первая проявляет краску, вторая (с общей
   для всех задержкой) сводит сдвиг.
   ===================================================================== */

@keyframes press-reg {
  from { transform: translate(var(--ox, 9px), var(--oy, -6px)) var(--base, ); }
  to   { transform: translate(0, 0) var(--base, ); }
}

html[data-boot="print"] .stage .bar--corner,
html[data-boot="print"] .stage .cta,
html[data-boot="print"] .stage .hand--surname,
html[data-boot="print"] .stage .bar--bottom,
html[data-boot="print"] .stage .bar--gradient,
html[data-boot="print"] .stage .bar--bottom2,
html[data-boot="print"] .stage .tag::before {
  --d2: 1420ms;
  animation:
    press-in 200ms linear calc(var(--d) - var(--seek, 0ms)) both,
    press-reg 260ms cubic-bezier(0.2, 0.85, 0.25, 1) calc(var(--d2) - var(--seek, 0ms)) both;
}

html[data-boot="print"] .stage .bar--corner   { --d: 780ms;  --ox: 8px;  --oy: -5px; }
/* Кнопка печатается одной вещью и в тот же момент, когда раньше
   печаталась её плашка: 786ms. Прежняя --base: translateX(-50%) убрана
   вместе с самим сдвигом — текст больше не выключен по середине
   плашки, он и есть плашка. */
html[data-boot="print"] .stage .cta           { --d: 786ms;  --ox: 10px; --oy: -6px; }
html[data-boot="print"] .stage .hand--surname { --d: 943ms;  --ox: 11px; --oy: -7px;
                                                --base: rotate(var(--hand-surname-rot)); }
html[data-boot="print"] .stage .bar--bottom   { --d: 1171ms; --ox: -7px; --oy: 6px; }
html[data-boot="print"] .stage .bar--gradient { --d: 1176ms; --ox: -7px; --oy: 6px; }
html[data-boot="print"] .stage .bar--bottom2  { --d: 1181ms; --ox: -7px; --oy: 6px; }

/* Точки списка — красные, поэтому они отдельная форма, а не часть слова.
   Свою задержку берут из --d2 своего слова (см. блок выше). */
html[data-boot="print"] .stage .tag::before {
  --d: var(--d2, 1016ms);
  --d2: 1420ms;
  --ox: 6px;
  --oy: -4px;
}

/* Щелчок станка в момент приводки: композиция садится на 2px.
   Ровно один кадр движения, чтобы сведение слоёв было слышно глазом. */
html[data-boot="print"] .scene--hero {
  animation: press-knock 240ms ease-out calc(1420ms - var(--seek, 0ms)) both;
}

@keyframes press-knock {
  0%   { transform: translateY(2px); }
  55%  { transform: translateY(-1px); }
  100% { transform: translateY(0); }
}

/* Служебное поле уходит последним: сначала лист допечатан, потом с него
   снимают кресты и метки. */
html[data-boot="print"] .press__marks {
  animation: press-out 320ms linear calc(1560ms - var(--seek, 0ms)) both;
}

/* =====================================================================
   5. СТРАХОВКА

   Три отказа, которые нельзя оставлять человеку на экране:
     — JS выключен вовсе: атрибута нет, композиция видна сразу, лист
       снимается через 1,2 с;
     — a.js не загрузился или упал после раннего скрипта: остаётся
       фаза run, поэтому в 3,2 с композиция проявляется сама, а лист
       уходит в 3,4 с;
     — прогресс не досчитался: это уже забота a.js, там жёсткий предел.
   ===================================================================== */

html:not([data-boot]) .press {
  animation: press-out 300ms linear 1200ms both;
}

html[data-boot] .press {
  animation: press-out 300ms linear 3400ms both;
}

html[data-boot="run"] .stage > :not(.paper),
html[data-boot="run"] .stage .tag::before {
  animation: press-in 400ms linear 3200ms both;
}

/* =====================================================================
   6. СПОКОЙНЫЙ РЕЖИМ

   Убираем то, ради чего эту настройку включают: ход вала, сдвиги
   приводки, щелчок. Остаётся честная последовательность — лист, имя,
   композиция, — но всё проявляется, а не движется. Ничего не пропадает
   и не выглядит сломанным.
   ===================================================================== */

@media (prefers-reduced-motion: reduce) {
  .press__roller { display: none; }

  html[data-boot="run"] .press__ink--m,
  html[data-boot="run"] .press__ink--k {
    animation: press-in 300ms linear 80ms both !important;
  }

  html[data-boot="print"] .stage > :not(.paper),
  html[data-boot="print"] .stage .tag::before {
    animation: press-in 380ms linear 80ms both !important;
  }

  html[data-boot="print"] .stage .grain {
    animation: press-in 380ms linear 260ms both !important;
  }

  html[data-boot="print"] .scene--hero { animation: none !important; }

  html[data-boot="print"] .press__plate,
  html[data-boot="print"] .press__marks {
    animation: press-out 260ms linear both !important;
  }
}
