@charset "UTF-8";

/* ============================================================================
   antontarasov.pro — визуальная система (док. 01 v2)

   Сайт набирается и ведёт себя как фотографическое издание.
   Фотография — аргумент, а не украшение. Дороговизна берётся из масштаба,
   воздуха и чёрного, не из эффектов. Ноль декора.

   Mobile-first: если приём не работает на 390px, его здесь нет.
   CSS написан с нуля. Фреймворков не используется (док. 04 §1).
   ========================================================================= */

/* critical:start — всё до парного маркера инлайнится в <head> шаблоном,
   чтобы первый экран рисовался без ожидания внешнего файла (док. 04 §4).
   Извлекает tools/critical-css.mjs, руками копировать не нужно.          */

/* ── Шрифты, self-hosted ─────────────────────────────────────────────────
   Локально, не через CDN Google: лишний домен, лишний RTT
   и вопрос с персональными данными (док. 04 §4).                         */

@font-face {
  font-family: 'Prata';
  src: url('/assets/fonts/prata-cyrillic.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Prata';
  src: url('/assets/fonts/prata-latin.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2191, U+2193, U+2212;
}

@font-face {
  font-family: 'Golos Text';
  src: url('/assets/fonts/golos-text-400-cyrillic.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Golos Text';
  src: url('/assets/fonts/golos-text-400-latin.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2212;
}
@font-face {
  font-family: 'Golos Text';
  src: url('/assets/fonts/golos-text-500-cyrillic.woff2') format('woff2');
  font-weight: 500;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Golos Text';
  src: url('/assets/fonts/golos-text-500-latin.woff2') format('woff2');
  font-weight: 500;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2212;
}

@font-face {
  font-family: 'PT Mono';
  src: url('/assets/fonts/pt-mono-cyrillic.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'PT Mono';
  src: url('/assets/fonts/pt-mono-latin.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+2000-206F, U+2122, U+2212;
}

/* ── Токены ─────────────────────────────────────────────────────────────── */

:root {
  /* Цвет (док. 01 §2). ГОЛУБОЙ КРАСИТ ЛИНИИ, НЕ БУКВЫ: линейка колонтитула
     на бумаге и подчёркивание ссылок, плюс заливка кнопки при наведении —
     событие указателя, а не состояние страницы. Монограмма в колофоне —
     единственное исключение в буквах.                                    */
  --paper:         #F2F0EC;
  --paper-deep:    #E6E3DC;
  --ink:           #1A1815;
  --ink-soft:      #77716A;
  --black:         #0C0B0A;
  --on-black:      #E8E4DC;
  --on-black-soft: rgba(232, 228, 220, .55);
  --aegean:        #2C6E9B;
  --aegean-lit:    #6FB0D9;
  --hairline:      rgba(26, 24, 21, .18);
  /* Эгейская волосяная: линейка колонтитула и подчёркивание ссылок.
     Голубой красит линии, не буквы (док. 01 §2, §6.7).                  */
  --hairline-aegean: rgba(44, 110, 155, .30);
  --hairline-dk:   rgba(232, 228, 220, .16);

  /* Три слоя текста (док. 01 §3, §5).
     Prata — единственное начертание, курсива и жирного у неё нет
     и подделывать их нельзя.                                             */
  --display: 'Prata', Georgia, 'Times New Roman', serif;
  --speech:  'Golos Text', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --doc:     'PT Mono', ui-monospace, 'SFMono-Regular', monospace;

  /* ШКАЛА — ПЯТЬ СТУПЕНЕЙ, РОЛЬ НА КАЖДОЙ (док. 01 §3).
     Было шесть кеглей, из которых три верхних на мобильном стояли в
     пределах 34–38px: такую разницу читатель не видит, а на десктопе
     они расходились до 132/112/86 — лестница меняла форму от ширины.
     Соседние ступени расходятся не меньше чем на треть на любой ширине.

     Д1 — герой и экраны спуска. Одна ступень на оба: это одно событие,
     голос во весь экран, и держать под него два кегля незачем.        */
  --h-hero:    clamp(46px, 8vw,   116px);
  --h-descent: clamp(46px, 8vw,   116px);
  --h-chapter: clamp(34px, 5.5vw,  78px);  /* Д2 — заголовок главы     */
  --h-plate:   clamp(28px, 4.2vw,  56px);  /* Д3 — строка на кадре     */
  --t-lead:    clamp(19px, 1.5vw,  24px);  /* Р1 — лид, расшифровка    */
  --t-body:    clamp(17px, 1.2vw,  20px);  /* Р2 — корпус              */

  /* ТРИ РОЛИ ДОКУМЕНТНОГО СЛОЯ (док. 01 §5). Одно начертание одного
     кегля обслуживало семь ролей, поэтому подпись под фотографией
     весила столько же, сколько название главы.                       */
  /* 13px, а не 12 (Р-38): колонтитул — заголовок и не может быть мельче
     содержимого, которое называет. Проверено рядом с основным текстом,
     а не на фотографии: на кадре кегль метки сравнивать не с чем.
     Открыто — возможен шаг до 14px, решать на живом сайте.            */
  --doc-folio:   13px;  --doc-folio-ls:   .16em;  /* называет и нумерует */
  --doc-caption: 13px;  --doc-caption-ls: .02em;  /* то, что читают     */
  --doc-service: 12px;  --doc-service-ls: .10em;  /* чем пользуются     */

  /* Сетка и ритм (док. 01 §4).
     Мобильные 18px — обязательный минимум, меньше не уходим.             */
  --pad:     clamp(18px, 4vw, 54px);
  --measure: 60ch;
  --section: clamp(72px, 12vh, 160px);

  /* ЦИТАТА — ОДИН ОБЪЕКТ, ДВЕ РОЛИ (Р-45). Воздух сверху и снизу у роли
     «в тексте» держит одну переменную на весь сайт, не набор частных
     отступов.                                                          */
  --quote-space: clamp(40px, 6vh, 72px);

  /* ЕДИНИЦА ЭКРАНА (док. 01 §4). Одна на весь сайт: высота полноэкранных
     блоков, шаг слотов снапа и высота сцен считаются только от неё.
     vh, а не svh: адресная строка уходит в начале прокрутки, значит чаще
     человек видит большой вьюпорт, и цвет должен лежать край-в-край.
     vh к тому же статичен — раскладка под пальцем не пересчитывается.   */
  --screen: 100vh;

  /* ВЫСОТА БРАУЗЕРНОЙ ОБВЯЗКИ — полоса, которую занимает всплывшая
     адресная строка. На десктопе ноль. Цена единицы vh: в эту полосу
     смысловой текст ставить нельзя.                                     */
  --chrome: 0px;

  /* Отступ прижатого к краю текста: подписи, колонцифры, строка героя.
     Резерв берётся ВПОЛОВИНУ: 100vh − 100svh это максимальная высота
     адресной строки, а держится он всегда, даже когда строка уже
     схлопнулась в пиктограмму. Полный резерв отрывал подписи от края.  */
  --safe-edge: calc(var(--chrome) * .5 + clamp(24px, 4vh, 44px));
  --safe-copy: calc(var(--chrome) * .5 + clamp(46px, 8vh, 86px));

  /* НИЗ ПОЛНОЭКРАННОГО КАДРА. Одна раскладка на все кадры сайта: на
     нижней линии стоит подпись, дисплейная строка встаёт НАД ней.
     Не подпись убегает в другой угол, а строка поднимается — тогда
     шаблон один и исключений нет. Середина кадра остаётся кадру.     */
  --frame-copy: calc(var(--safe-edge) + var(--doc-caption) * 1.5 + clamp(20px, 3.5vh, 38px));

  /* ВЕРХНЯЯ ЛИНИЯ ИЗДАНИЯ (док. 01 §4). Одна на все экраны: на ней
     начинается колонтитул главы, колонтитул на полноэкранном кадре и
     стопка пройденных меток в спуске. Снап ставит верх секции в верх
     экрана, поэтому эта линия и есть начало экрана.

     --chrome сюда НЕ входит: адресная строка содержимое сверху не
     накрывает, она его сдвигает. Резервировать наверху нечего.         */
  --top-line: clamp(36px, 5vh, 64px);

  /* ЗАТЕМНЕНИЕ ПОЛОС КАДРА. Гаснут только те две полосы, где лежат
     буквы, — верхняя под колонтитулом и нижняя под строкой и подписью.
     Кадр целиком фильтром яркости больше не приглушается: за читаемость
     платила фактура снимка, а платить должна полоса под текстом.
     Полосы держат плотность там, где стоят строки, и сходят на нет
     раньше середины: середина принадлежит кадру (док. 01 §6.8).       */
  --scrim-top: linear-gradient(
    to bottom,
    rgba(8, 7, 6, .78) 0%,
    rgba(8, 7, 6, .34) 12%,
    rgba(8, 7, 6, 0) 27%
  );
  --scrim-bottom: linear-gradient(
    to top,
    rgba(8, 7, 6, .72) 0%,
    rgba(8, 7, 6, .24) 22%,
    rgba(8, 7, 6, 0) 42%
  );
  /* Осветляющей разновидности маски нет: Р-54 отменён (решение владельца),
     знак у затемнения один на все кадры сайта. Светлому пёстрому кадру
     отвечает не перевёрнутый знак, а более плотное затемнение полосы
     (--coda-top) и ступень громкости у метки (.frame__top--bright). */

  /* ТЕНЬ ПОД ИМЕНЕМ МАРКИ (Р-38). Стоит здесь намеренно, рядом с
     параметрами маски: это НЕ свечение. Свечение добавляет букве
     светимость и на фотографии всегда читается как любительский приём;
     тень не добавляет букве ничего — она локально гасит носитель под
     ней, то есть делает ту же работу, что две полосы выше. Приём не
     новый, а точечное продолжение существующего (док. 01 §8, §9).    */
  --mark-shade: 0 0 18px rgba(0, 0, 0, .55);

  /* ШКАЛА ГРОМКОСТИ НА КАДРЕ (Р-38, док. 01 §2). Всё, что спорит за
     внимание поверх фотографии, размечено одной шкалой. Проценты —
     эффективная яркость относительно чистого белого.

     ЧИСТЫЙ БЕЛЫЙ НА КАДРАХ НЕ ПРИМЕНЯЕТСЯ: он ярче собственной палитры
     издания и ярче белых в самой фотографии — после обработки те доходят
     до 235–248. Буквы чистым белым оказывались светлее всего, что есть
     в кадре: они отрывались от изображения вместо того, чтобы лежать
     в нём. Токен возвращает их в снимок.

     Предмет разговора — расстояние, а не отдельные значения: разброс
     шёл от 34 до 100 и края занимали марка с дисплеем, стало от 44
     до 90. Метка колонтитула ходит за дисплейной строкой и берёт тот
     же токен: метка, темнее строки на том же кадре, — несогласованность.

     Имя марки идёт полным --on-black, отдельного токена ему не нужно:
     дисплей опустился до тона издания, а марка на нём и была, — то есть
     сошлись они на её тоне, а не на среднем.                          */
  --on-frame:      rgba(232, 228, 220, .92);  /* строка, метка     · 82% */
  --on-frame-desc: rgba(232, 228, 220, .80);  /* дескриптор марки  · 72% */
  --on-frame-cap:  rgba(232, 228, 220, .70);  /* подпись кадра     · 63% */

  /* ВОЛОСЯНАЯ НА КАДРЕ СТАЛА ЭГЕЙСКОЙ (Р-38). Прежде она была светлой —
     по запрету §8 на выборочный цвет поверх ч/б фотографии. Запрет
     отменён для линии толщиной в пиксель и проверен на четырёх
     носителях, включая светлый кадр, где линия ложится на белую стену:
     выборочным цветом такая линия не читается, она читается
     принадлежностью. Для плашек, заливок и любых площадей запрет
     остаётся в силе.
     .68 — калибровка на четырёх носителях (Р-38). Подъём до .85 в
     прогоне 6 отвечал на ту же задачу камелии, что теперь решает
     Р-54 (осветляющая маска, чернильная волосяная): приём заменён,
     подъём отменён (Р-54). */
  --hairline-frame: rgba(111, 176, 217, .68); /* штрих марки, линейка */

  /* МАРКЕР МЕНЮ ЭГЕЙСКИМ НЕ КРАСИТСЯ. Волосяная у него та же по толщине
     и громкости, но эгейский помечает кликабельное и принадлежность
     марке, а маркер ни то, ни другое — это вход в оглавление. Тон
     светлый (док. 01 §9).                                             */
  --hairline-marker: rgba(232, 228, 220, .68); /* маркер меню      · 61% */

  /* ПРОЯВЛЕНИЕ ТЕКСТА (док. 01 §6). Единственный источник правды по
     времени: в разметке чисел нет, ступени и задержку подписи считает
     CSS. Один приём на все смысловые дисплейные строки.               */
  --reveal: 1500ms;       /* длительность одной строки                 */
  --reveal-step: 600ms;   /* ступень между строками лесенки             */
  --sub-reveal: 900ms;    /* подпись короче строки, она не довод        */

  /* Отставание подписи не выдумано: ровно такое, чтобы она стартовала
     позже последней строки, а заканчивалась вместе с ней.             */
  --sub-lag: calc(var(--reveal) - var(--sub-reveal));

  /* БЕЗУСЛОВНЫЙ УХОД СТРОКИ (док. 01 §6.0). Строка доиграла, читатель
     остался на кадре — через --dwell она уходит тем же приёмом.
     Медленно: при приходе медленно = довод, при уходе быстро = сбой,
     быстро исчезающий текст читается как ошибка рендера. JS берёт
     выдержку отсюда, своих чисел про время у него нет.

     3200 вместо 4500 (Р-34): буквы должны уходить, «пока глаза ещё
     в кадре».                                                        */
  --dwell: 3200ms;
  --depart: 1350ms;

  /* ПЕРЕЛЁТ МЕТКИ В СТОПКУ — и фон спуска вместе с ней. Одно событие:
     экран уходит, метка летит в угол, фон приходит к точке следующего
     экрана. Длительность и кривая общие, иначе движения расходятся.
     JS берёт их отсюда же, своих чисел про время у него нет.         */
  --flight: 1120ms;
  --flight-ease: cubic-bezier(.22, 1, .36, 1);

  /* Освобождение места в стопке — заметно короче самого перелёта: штрих
     должен успеть погаснуть до того, как метка на него сядет.        */
  --flight-clear: 420ms;

  /* СМЕНА НОСИТЕЛЯ под меткой: бумага уходит, приходит кадр. Метка при
     этом не двигается — меняются только её цвета, и меняться они должны
     успеть, пока кадр подходит к линии, а не после (док. 01 §6.3).  */
  --carrier: 500ms;
}

@supports (height: 1svh) {
  :root { --chrome: calc(100vh - 100svh); }
}

/* ── Сброс ──────────────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: auto; /* прокрутка не перехватывается нигде (док. 04 §5) */

  /* Голубая заливка, которой мобильный Safari накрывает всё нажатое,
     — чужой цвет чужой системы поверх фотографии. Обратной связи она
     здесь не даёт: ссылки и кнопки отвечают собственными состояниями. */
  -webkit-tap-highlight-color: transparent;

  /* ШАГ СТРАНИЦЫ. Снап делает браузер: события прокрутки не гасятся,
     инерция, клавиатура и поиск по странице остаются родными. Перехватом
     прокрутки это не является (док. 01 §8).                             */
  scroll-snap-type: y mandatory;
}

/* ── Сплошное покрытие точками (док. 01 §4) ──────────────────────────────
   Правило, без которого mandatory ломает страницу: точками накрывается
   ВСЁ. Секция без точки становится недостижимой — браузер доводит мимо
   неё до ближайшей точки, и содержимое просто нельзя показать.

   Покрытие двух видов:

   — Секция ВЫШЕ экрана превращается из точки в диапазон: внутри неё
     остановиться можно где угодно, текст читается свободно. Флинг при
     этом встаёт на её верхе — глава всегда начинается с колонтитула.
   — Сцена (динамика) даёт точки не собой, а рельсом слотов ровно по
     экрану: тогда флинг любой силы двигает ровно на один экран и ни
     одно состояние сцены не проскакивается.

   Любой новый блок наследует правило автоматически: он либо текст,
   либо сцена с рельсом.                                                 */

main > *, .colophon {
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

/* Сцены точками не являются: они выше экрана и стали бы диапазоном,
   а диапазон убивает жёсткий шаг. Точки дают слоты рельса.             */
main > .js-scene { scroll-snap-align: none; }

/* СЕКЦИЯ ПЕРЕД КОДОЙ СНАПИТСЯ НАЧАЛОМ, КАК ВСЕ ОСТАЛЬНЫЕ (решение
   владельца, отменяет прежнее исключение).

   Прежде она снапилась КОНЦОМ. Довод был верен наполовину: короткая
   секция, поставленная началом в верх экрана, показывала снизу верхнюю
   половину финального кадра. Но лечение оказалось хуже болезни — сверху
   вставал не «хвост предыдущей главы», а её нижнее поле: у главы,
   которая не продолжается, оно полное (--section), и над заголовком
   «Формат работы» повисало больше двухсот пикселей пустой бумаги, из
   которой ещё и нельзя было выехать — снап возвращал назад.

   Настоящая причина была не в выравнивании, а в высоте: секция короче
   экрана. Она снята правилом min-height ниже, из которого исключение
   `:has(+ .closing)` теперь убрано. Секция ровно в экран встаёт началом
   и концом одинаково, кода приходит целиком следующим флингом, а воздух
   остаётся там, где ему и место, — снизу, после последней строки.

   Начало, а не конец, ещё и потому, что --screen считается в vh: при
   видимой адресной строке выравнивание концом срезало бы верх полосы,
   то есть заголовок, а выравнивание началом — низ, то есть воздух.   */

/* Связка секций: блок заметно ниже экрана (аудиострока) точкой быть не
   может — остановка на нём показывает пустоту. Он прилипает к соседней
   секции, и точкой становится их общая связка (док. 01 §4).            */
.group > * { scroll-snap-align: none; scroll-snap-stop: normal; }

.rail { position: absolute; inset: 0; z-index: 0; }
.rail__slot {
  height: var(--screen);
  scroll-snap-align: start;
  scroll-snap-stop: always;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--speech);
  font-size: var(--t-body);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, p, ol, ul, figure { margin: 0; }
ol, ul { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }

/* Ссылки в тексте: подчёркивание 1px с отступом .2em. БУКВЫ ДЕРЖАТ ЦВЕТ
   ТЕКСТА, ЛИНИЯ — ЭГЕЙСКАЯ (док. 01 §6.7). Голубой красит линии, не буквы:
   закреплённый за кнопкой и монограммой, он физически не существовал на
   мобильном — hover не срабатывает, — то есть был фикцией в основании.
   Заодно снимается перегруз: раньше линия шла полным currentColor под
   текстом --ink-soft, то есть была темнее самой ссылки.                  */
a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--hairline-aegean);
  text-underline-offset: .2em;
}

/* Фокус с клавиатуры виден (док. 04 §5). Обводка берёт currentColor,
   а не акцент: голубой закреплён за двумя ролями и больше нигде
   не появляется (док. 01 §2). currentColor читается и на бумаге,
   и на чёрном.                                                          */
:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

/* Слой «Документ» — колонтитулы, номера глав, подписи, метки.
   Занимает не больше 5% площади, для чтения абзацами не используется.

   Роль задаётся местом, а не вторым классом в разметке: колонтитул —
   это колонтитул, где бы он ни стоял. Поэтому ниже три группы
   селекторов, а не три модификатора .doc--*.                           */
.doc {
  font-family: var(--doc);
  line-height: 1.5;
}

/* Роль «колонтитул» — то, что называет и нумерует. Крупнее прежних
   11px: это заголовок, и он не может быть мельче своего содержимого.   */
.folio__label,
.menu__here,
.descent__label,
.descent__stack i,
.descent__flyer,
.numbered__n,
.numbered__sub-title,
.offer__eyebrow,
.longread__meeting,
.longread__part,
.lr__num,
.lr__stage,
.contents__n,
.resume {
  font-size: var(--doc-folio);
  letter-spacing: var(--doc-folio-ls);
  text-transform: uppercase;
}

/* Внутри роли есть старшинство. Колонтитул главы называет весь экран,
   номер в списке — одну строку. У главы «Кому не подойдёт» дисплейного
   заголовка нет вовсе: её заголовок и есть колонтитул, поэтому он
   берёт полный цвет текста, а номера остаются приглушёнными и мельче. */
.folio__label { color: var(--ink); }
.numbered__n  { font-size: 11px; color: var(--ink-soft); }
/* Номер в оглавлении материалов — тот же номер в списке, что у перечня,
   и старшинство у него то же. «Встреча 1» над конспектом, наоборот,
   называет всю страницу и держит полный цвет, как колонтитул главы. */
.contents__n     { font-size: 11px; color: var(--ink-soft); }
.longread__part  { color: var(--ink-soft); }
.longread__meeting { color: var(--ink); }
/* Заголовок раздела конспекта — тот же колонтитул, что «Встреча 1» над
   заглавием: называет то, что под ним, и берёт полный цвет. Веха курса
   («Выводы», «Новый материал») набирается им целиком — речевого
   заголовка у неё нет, колонтитул и есть заголовок. */
.lr__num, .lr__stage { color: var(--ink); }

/* Роль «подпись» — то, что читают. Строчные: капс с большим трекингом
   на двух словах читать мешает, он орнамент. Единственная роль моно,
   которую действительно читают.                                        */
.frame__caption,
.figure__caption,
.review__author,
.quote__source,
.offer__note,
.reviews__note,
.lr__mark,
.lr__chain,
.note-boundaries {
  font-size: var(--doc-caption);
  letter-spacing: var(--doc-caption-ls);
  text-transform: none;
}

/* Роль «служебное» — то, чем пользуются, а не что читают.              */
.menu__sections a,
.audio__trigger,
.offer__meta,
.offer__links-title,
.colophon__service,
.colophon__sections,
.colophon__shot,
.longread__step {
  font-size: var(--doc-service);
  letter-spacing: var(--doc-service-ls);
  text-transform: uppercase;
}

/* ── Марка ──────────────────────────────────────────────────────────────
   Имя дисплеем, штрих, дескриптор документным слоем — стопкой, выключкой
   вправо (Р-20, Р-28). Постоянной шапки на сайте нет: она принадлежала
   первому экрану и уезжала с ним навсегда, и уйти с любого другого экрана
   было некуда. Марка стоит на титуле каждой страницы — на внутренние
   заходят напрямую, из поиска и по ссылке, и главную не видят никогда.

   ЛИНИИ ПОД МАРКОЙ НЕТ: линия — конструкция колонтитула, а титул
   колонтитула не несёт (док. 01 §6.8). Штрих 30px стоит ВНУТРИ марки,
   между именем и дескриптором: книжная звёздочка, пауза между голосом
   и пояснением. Ширина марки остаётся за именем, а не за служебной
   строкой, поэтому во всю ширину он не тянется.                         */

.mark {
  display: inline-block;
  text-align: right;
  text-decoration: none;
  color: inherit;
}

/* Разрядка — старейший способ показать, что набрано с вниманием, и она
   не добавляет на экран ни одного нового объекта (Р-28).               */
.mark__name {
  display: block;
  font-family: var(--display);
  /* 21px, а не 19 (Р-38): марка занимала нижний край разброса громкости,
     дисплей верхний, и разговор шёл про расстояние между ними.        */
  font-size: 21px;
  line-height: 1.1;
  letter-spacing: .045em;
  white-space: nowrap;
  /* Разрядка добавляет пробел и после последней буквы: без компенсации
     выключка вправо перестаёт быть выключкой.                          */
  margin-right: -.045em;
}

/* ЦВЕТ ШТРИХА ЗАДАЁТ НОСИТЕЛЬ — по тому же закону, по которому его меняет
   линейка колонтитула (док. 01 §2). Эгейский теперь на всех трёх: на
   кадре, на чёрном и на бумаге. Разница только в громкости, которую
   держит носитель (Р-38).                                              */
.mark__rule {
  display: block;
  width: 30px;
  height: 1px;
  margin: 9px 0 9px auto;
  background: var(--hairline-frame);
}
.mark--on-black .mark__rule { background: rgba(111, 176, 217, .42); }
.mark--on-paper .mark__rule { background: var(--hairline-aegean); }

/* Контроль на 390: дескриптор — самая длинная строка марки. Если он
   подходит к правому полю ближе имени, трекинг снижается до .22em.     */
.mark__desc {
  display: block;
  font-size: 11px;
  letter-spacing: .26em;
  text-transform: uppercase;
  /* .80, а не .55 (Р-38): дескриптор стоял на 47% громкости — нижний
     край всего, что есть на кадре. Стало 72%.                         */
  opacity: .80;
  white-space: nowrap;
  margin-right: -.26em;
}

/* ── Маркер меню ────────────────────────────────────────────────────────
   Три штриха той же волосяной линии, что линейка колонтитула: та же
   толщина, тот же цвет, 19px по кеглю моно рядом, шаг 5px (Р-18).

   ЭТО НЕ ИКОНКА, А МАТЕРИАЛ САЙТА, СЛОЖЕННЫЙ ВТРОЕ. §8 запрещает иконки —
   запрет перекрыт этим доводом: под букву три полоски попадают, под
   смысл нет. Ни одного нового объекта на экране не появляется.

   Место одно и то же везде: правый конец линейки — он свободен на каждом
   экране без исключения, место не пришлось искать, оно уже было.
   Хитбокс 44×44 невидимый, штрихи стоят в его середине.                 */

.marker {
  position: absolute;
  right: 0;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}
/* ШИРИНА 24px — СРЕДНИЙ ШАГ (Р-38). Рычагов два, и они тянут в разные
   стороны: маркер стоит рядом с меткой колонтитула (прежние 19px были
   взяты по её кеглю), но сделан из той же волосяной, что штрих марки
   (30px), и разная длина читается как несогласованность. Прежнее
   равенство всё равно нарушено — метка выросла с 12 до 13. Полное
   равенство со штрихом марки отвергнуто: маркер набрал бы вес, которого
   интерфейс такой сдержанности не выдерживает.                        */
/* ШТРИХИ МАРКЕРА — ЧЕРНИЛЬНЫЕ (Р-42): цвет говорит, чернила размечают.
   Эгейский остаётся у штриха марки и линейки колонтитула — оба
   принадлежат марке или называют главу; маркер не делает ни того, ни
   другого, это вход в оглавление.                                     */
.marker i {
  position: absolute;
  right: 0;
  display: block;
  width: 24px;
  height: 1px;
  background: var(--hairline);
}
.marker i:nth-child(1) { top: 16px; }
.marker i:nth-child(2) { top: 21px; }
.marker i:nth-child(3) { top: 26px; }

/* ТРИ МЕСТА, И НИ ОДНОГО БОЛЬШЕ (Р-43): титульный кадр, под маркой
   (.title-service); бумажная глава, под группой заголовка (.entry);
   больше маркер не стоит нигде — ни на кадрах, ни на спуске, ни на
   полосах-продолжениях. Прежней абсолютной привязки к линейке колонтитула
   («у правого конца линейки») с уходом folio-линейки с бумаги тоже нет.  */

/* Страница без единого колонтитула: маркер встаёт на верхнюю линию сам,
   иначе входа в меню на ней нет вовсе. Временно — до титулов этих
   страниц (Р-21), после которых маркер придёт в общую пару с маркой.

   ОПУЩЕН ДО НИЗА СТРОКИ ЗАГЛАВИЯ (решение владельца): на верхней линии он
   стоял выше заглавия и висел сам по себе, ни к чему не относясь. Теперь
   нижний штрих совпадает с низом первой строки — маркер читается парой
   к заглавию, как на титуле он пара к марке.

   Считается, а не подбирается числом: заглавие начинается ровно на
   верхней линии, его строка вместе с выносным элементом занимает 1.19
   кегля (Prata, интерлиньяж 1.04), а нижний штрих маркера стоит на 26px
   ниже верха хитбокса. Кегль Д2 тянется от 34px до 78px, и подобранная
   на 390px константа на десктопе разошлась бы на четыре десятка. */
.marker--loose {
  position: absolute;
  top: calc(var(--top-line) + var(--h-chapter) * 1.19 - 26px);
  right: var(--pad);
  z-index: 6;
}

/* На бумажной главе — под всей группой заголовка, у правого поля полосы,
   В ПОТОКЕ, а не абсолютом от первой строки: у заголовка бывает две и три
   строки, и абсолютная привязка к ней плавает (Р-43). Тот же приём
   переключения `position`, что у маркера на титуле, ниже.              */
.marker--entry {
  position: relative;
  right: auto;
  align-self: flex-end;
  margin-top: 12px;
}

/* На титуле линейки нет вовсе — маркер висит под маркой в той же
   вертикали, через воздух (Р-23). Здесь он не повторяет линию, а стоит
   один, и берёт цвет марки, а не волосяной.                            */
.title-service {
  position: absolute;
  top: var(--top-line);
  right: var(--pad);
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  /* Полный тон издания, без приглушения (Р-38): имя марки идёт на 90%,
     а прежние .94 давали 84% — марка стояла ниже всего, что рядом.   */
  color: var(--on-black);
}

/* Мягкая тень под именем: она гасит носитель под буквой, а не светит
   ей (§8, §9). Стоит только на кадре — в колофоне носитель сплошной
   чёрный, гасить там нечего.                                          */
.title-service .mark__name { text-shadow: var(--mark-shade); }
.title-service .marker {
  position: relative;
  right: auto;
  /* ВОЗДУХА ПОД МАРКОЙ 32px, А НЕ 18 (решение владельца). Прежние 18
     держали марку и маркер одним блоком: снизу читалась третья строка
     марки, а не вход в оглавление, — и палец, целясь в штрихи, попадал
     в марку, то есть уезжал на главную. Расстояние теперь больше
     внутренних интервалов марки, и объектов на титуле снова два.
     Штрихи стоят в середине хитбокса, на 16px ниже его верха, поэтому
     отступ считается от них.                                          */
  margin-top: 16px;
  /* Сдвига вправо здесь нет. Штрихи внутри хитбокса и так прижаты к его
     правому краю (`.marker i { right: 0 }`), поэтому отрицательный отступ
     выносил их ЗА поле страницы. Хитбокс 44×44 расширяется влево и вниз,
     штрихи стоят ровно по правому полю — как линейка колонтитула.      */
}
.title-service .marker i { background: var(--hairline-marker); }

/* ── Оглавление ─────────────────────────────────────────────────────────
   Меню — оглавление страницы, а не навбар (Р-19). Три ссылки отвечают
   «куда ещё», но не «где я на этой странице», а непроходимы были именно
   длинные страницы.

   ПОДЛОЖКА С РАЗМЫТИЕМ, А НЕ ОТДЕЛЬНЫЙ ЧЁРНЫЙ ЭКРАН: кадр за меню виден
   как форма. Размытием на сайте уже всё приходит — текст проступает из
   blur(12px), герой наводится из blur(14px), — это собственная субстанция
   сайта, а не эффект со стороны. Величина 3px: на 5 форма за подложкой
   теряется и размытие начинает читаться как эффект.                     */

.menu {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  padding: var(--top-line) var(--pad) clamp(40px, 7vh, 72px);
  background: rgba(12, 11, 10, .90);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  color: var(--on-black);
  opacity: 0;
  transition: opacity .32s;
}
.menu[hidden] { display: none; }
.menu.is-open { opacity: 1; }

/* Верхняя линия на своём месте и здесь: над ней ничего, под ней — где мы. */
.menu__rule {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  top: var(--top-line);
  height: 1px;
  background: rgba(232, 228, 220, .28);
}

.menu__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: clamp(28px, 5vh, 54px);
}
.menu__here {
  padding-top: 11px;
  color: rgba(232, 228, 220, .55);
}

/* Закрытие — тот же штрих, сложенный крестом: другого материала нет. */
.menu__close {
  position: relative;
  width: 44px;
  height: 44px;
  margin-top: 6px;
  /* Штрихи креста тоже прижаты вправо внутри хитбокса — сдвигать его
     наружу нечем, иначе закрытие уезжает за поле.                      */
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}
.menu__close i {
  position: absolute;
  right: 0;
  top: 21px;
  display: block;
  width: 19px;
  height: 1px;
  background: rgba(232, 228, 220, .75);
}
.menu__close i:nth-child(1) { transform: rotate(45deg); }
.menu__close i:nth-child(2) { transform: rotate(-45deg); }

/* Список забирает свободную высоту: разделы сайта уходят вниз экрана,
   и оглавление стоит между двумя линиями, как полоса издания.          */
.menu__list { list-style: none; flex: 1; }
/* Линейки только между пунктами: сверху и снизу их нет (док. 01 §6.6). */
.menu__list li + li { border-top: 1px solid rgba(232, 228, 220, .14); }
.menu__list a {
  display: flex;
  gap: 16px;
  align-items: baseline;
  padding: 15px 0;
  color: inherit;
  text-decoration: none;
}
.menu__title { font-size: var(--t-lead); line-height: 1.3; }

/* УКАЗАТЕЛЬ «ВЫ ЗДЕСЬ» (Р-51): короткий эгейский штрих перед именем
   текущей главы, номер его не заменяет (Р-40) — это было отдельное
   решение, номер лишь служил ему носителем. Приглушение названия для
   этой роли не годится, тем же приёмом помечено неактивное чуть ниже
   в этом меню — знак прочтётся наоборот.                              */
.menu__list a[aria-current] .menu__title {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.menu__list a[aria-current] .menu__title::before {
  content: '';
  width: 14px;
  height: 1px;
  background: var(--aegean-lit);
}

.menu__sections {
  margin-top: clamp(26px, 4vh, 44px);
  padding-top: clamp(20px, 3vh, 32px);
  border-top: 1px solid rgba(232, 228, 220, .28);
}
.menu__sections--alone { border-top: 0; padding-top: 0; }
/* РЯД РАЗДЕЛОВ УЕХАЛ ВПРАВО (решение владельца): под большой палец, на ту
   же сторону, где марка, маркер меню и крестик закрытия. Оглавление глав
   осталось слева — это полоса текста, а не орган управления.           */
.menu__sections {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}
.menu__sections a {
  display: block;
  padding: 9px 0;
  color: var(--on-black);
  text-decoration: none;
}
/* ТЕКУЩИЙ РАЗДЕЛ — САМЫЙ ЯРКИЙ, СО ШТРИХОМ (решение владельца, отменяет
   Р-35). Приглушение читалось как «недоступно», а не «вы здесь»: гашением
   в интерфейсном языке помечают неработающее. Знак тот же, что у текущей
   главы в оглавлении выше, — эгейский штрих перед именем. Перед, а не
   после: ряд выключен вправо, и штрих, поставленный следом, выбил бы
   текущий пункт из общего правого поля — единственную строку столбца,
   которая обязана стоять ровнее прочих.

   ТЕКСТ НЕ ВЫДЕЛЯЕТСЯ. Прежде это был <span>, и долгое нажатие на
   Android выделяло слово и открывало системную словарную подсказку —
   убрать её оттуда читатель уже не мог. Теперь это ссылка, а выделение
   снято и на ней: строка меню — орган управления, а не текст. */
.menu__sections a,
.colophon__sections a {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.menu__sections .is-here span,
.colophon__sections .is-here span {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
.menu__sections .is-here span::before,
.colophon__sections .is-here span::before {
  content: '';
  width: 14px;
  height: 1px;
  background: var(--aegean-lit);
}
.menu__sections .is-here { color: var(--on-black); }
.menu__svc { color: rgba(232, 228, 220, .5); }
/* Служебная страница осталась у ЛЕВОГО поля — место различает роль
   (решение владельца): в общем ряду справа она обещала раздел издания,
   которым не является.                                                */
.menu__sections .menu__svc { align-self: flex-start; text-align: left; }

/* ── Кнопки ─────────────────────────────────────────────────────────────
   Прямоугольник без скругления, рамка 1px (док. 01 §6.7).               */

.btn {
  display: inline-block;
  margin-top: clamp(24px, 4vh, 40px);
  padding: 14px 34px;
  border: 1px solid var(--ink);
  border-radius: 0;
  font-family: var(--speech);
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  color: var(--ink);
  text-decoration: none;
  transition: background-color .2s, color .2s, border-color .2s;
}

.btn:hover { background: var(--aegean); border-color: var(--aegean); color: #fff; }

.btn--on-dark { border-color: var(--on-black-soft); color: #fff; }
.btn--on-dark:hover { background: var(--aegean-lit); border-color: var(--aegean-lit); color: var(--black); }

/* ДВЕ КНОПКИ ПОДРЯД — СТОПКОЙ (решение владельца, витрина отзывов на
   главной). Свой воздух над группой держит первая кнопка, как везде;
   между кнопками промежуток меньше — это не два обращения через поле,
   а два выхода из одного места.                                        */
.btn-stack { display: flex; flex-direction: column; align-items: flex-start; }
.btn-stack .btn + .btn { margin-top: 14px; }

/* ── Колонтитул издания ─────────────────────────────────────────────────
   Волосяная линейка на всю ширину поля, под ней номер и название главы.
   Между линейкой и заголовком главы воздух не меньше 40px (док. 01 §6.6).
   Стоит почти ничего, работает сильнее всего остального.                 */

/* СНЯТО С БУМАГИ ЦЕЛИКОМ (Р-40): линейка, мелкая метка и номер главы на
   бумаге больше не стоят — вход в главу делает Д2-заголовок (.entry
   ниже). Folio остался только на фотокадре (frame_top(), plate_open__folio) —
   там он по-прежнему рисует линейку и название, без номера.             */
.folio { margin-bottom: clamp(40px, 7vh, 80px); }
.folio__rule { height: 1px; background: var(--hairline-aegean); margin-bottom: 22px; }
.folio__label { color: var(--ink); }

/* ── Общие секции на бумаге ─────────────────────────────────────────────── */

/* Секция начинается верхней линией, а не полосой воздуха: снап ставит её
   верх в верх экрана, и первое, что видит читатель, — номер главы.
   Снизу воздух остаётся прежним, это отбивка, а не начало экрана.      */
.chapter, .numbered, .reviews, .offer, .faq, .audio, .longread, .contents {
  padding: var(--top-line) var(--pad) var(--section);
}
/* ПОЛОСА-ПРОДОЛЖЕНИЕ (Р-50, док. 01 §5). Секция, которая главу не
   объявляет, а продолжает уже объявленную, не несёт ни заголовка, ни
   маркера меню, ни верхнего воздуха главы: объявлять уже объявленное
   нечем. Отбивается от предыдущей ВНУТРЕННЕЙ отбивкой, а не межглавной:
   полный --section снизу главы плюс верхняя линия плюс воздух под
   линейкой дают провал, который читатель принимает за конец главы.
   Отбивку даёт пара — низ предыдущей секции и верх этой, — поэтому
   ужимаются обе.                                                       */
.section--running { padding-top: clamp(20px, 3vh, 32px); }

/* ВОЛОСЯНАЯ НА ПОЛОСЕ-ПРОДОЛЖЕНИИ (решение владельца). Правило общее,
   на все вторые и третьи полосы всех глав сайта.

   Полоса-продолжение не объявляет главу и потому не несёт ни заголовка,
   ни маркера, ни метки, — и верхняя линия издания у неё оставалась
   пустой. На фотокадре в том же месте всегда стоит волосяная, и стоит
   она не ради метки: линия держит верхнее поле и принадлежит раскладке
   экрана, а не главе (Р-55). Здесь она делает ровно ту же работу — и
   тем же материалом, что разделители перечня: чернильная, не эгейская.
   Эгейский на бумаге помечает кликабельное и марку, а эта линия ни то,
   ни другое.

   Заодно снимается моно-метка возврата в главу после фотополосы
   (chapter_resume, Р-47): линия называет продолжение продолжением, не
   повторяя имени главы вторым способом.                              */
.section--running::before {
  content: '';
  display: block;
  height: 1px;
  background: var(--hairline);
  /* Воздуха под линией столько же, сколько над ней: линия стоит в поле
     полосы, а не поверх текста, и равенство читается как поле.
     Меньше, чем под линейкой колонтитула на кадре (22px): там под ней
     ещё стоит метка, здесь сразу текст.                               */
  margin-bottom: clamp(18px, 2.6vh, 26px);
}

/* ПОЛОСА ПОДНЯТА К ВЕРХНЕЙ ЛИНИИ (поле tight_top, см. section_class()).
   Верхнее поле главы ужимается до поля продолжения — вся полоса, вместе
   с заголовком и маркером, уходит вверх ровно настолько, чтобы её
   последняя строка помещалась при видимой адресной строке.            */
.section--tight { padding-top: clamp(16px, 2.4vh, 28px); }
/* Хитбокс маркера 44×44, а штрихи стоят в его середине — под ними
   остаётся 18px пустоты, которую видно как воздух, но которой нет как
   объекта. Полоса, считающая пиксели, забирает её обратно: цель касания
   при этом не уменьшается ни на пиксель, она просто заходит на отступ
   под собой.                                                          */
.section--tight .marker--entry { margin-bottom: -14px; }
.section--tight .entry { margin-bottom: clamp(6px, .9vh, 10px); }

/* ВОЗДУХ МЕЖДУ АБЗАЦАМИ СОБРАН (поле dense). Полоса, обязанная встать в
   экран целиком, отдаёт межабзацный интервал: он единственный запас,
   потеря которого не читается сбоем — абзацы остаются абзацами.       */
.section--dense .chapter__p + .chapter__p { margin-top: .4em; }
/* Межабзацного воздуха на такой полосе мало по устройству, поэтому она
   забирает и своё верхнее поле — там, где это не стоит ничего: линия
   и текст под ней просто стоят выше.                                  */
.section--dense { padding-top: clamp(14px, 2vh, 22px); }
.section--dense::before { margin-bottom: clamp(14px, 2vh, 20px); }
:is(.chapter, .numbered, .reviews, .offer, .faq):has(+ .section--running) {
  padding-bottom: clamp(30px, 5vh, 64px);
}
/* НИ ОДНА ПОЛОСА НЕ КОРОЧЕ ЭКРАНА (Р-53 в редакции владельца). Бокс
   короче экрана снизу открывает следующий — ровно то, что жёсткий шаг
   обязан скрывать.

   ИСКЛЮЧЕНИЕ `:has(+ .section--running)` СНЯТО (решение владельца,
   отменяет часть Р-53). Прежде продолжению своей же главы подглядывать
   снизу разрешалось: чужой главы там нет, значит и вреда нет. Владелец
   увидел на телефоне обратное — и увидел именно в полном экране, без
   адресной строки: --screen считается в vh, то есть по БОЛЬШОМУ
   вьюпорту, а видимая высота при свёрнутой адресной строке ему равна.
   Полоса, которая при видимой строке казалась полной, в полном экране
   оказывается короче него, и следующая полоса налезает сверху вниз тем
   сильнее, чем она короче («Как я это вижу», второй экран; «Откуда это
   взялось», второй и третий). Свой это абзац или чужой — читателю в этот
   момент не видно: он видит наползание.

   ИСКЛЮЧЕНИЕ `:has(+ .audio)` ОСТАЁТСЯ: глава, за которой идёт
   аудиострока, уже несёт свой пол в .group { min-height: var(--screen) }
   ниже, и вторая страховка сложила бы два экрана в один бокс, обрезав
   связку снизу.                                                       */
:is(.chapter, .numbered, .reviews, .offer, .faq, .contents):not(:has(+ .audio)) {
  min-height: var(--screen);
}
/* ПОЛОСА ДЕРЖИТ ЭКРАН ПО РЕШЕНИЮ ВЛАДЕЛЬЦА (Р-53, поле hold_screen).
   Продолжение главы подглядывать снизу может, но на отдельных швах
   решено, что следующий абзац не начинается вовсе. Селектором такие
   полосы не отличить от тех, где подглядывание оставлено намеренно, —
   признак приходит из данных, см. section_class() в src/lib/render.php. */
.section--hold { min-height: var(--screen); }

/* ПЕРЕЧЕНЬ И ОТЗЫВЫ — ИСКЛЮЧЕНИЕ СТРОЖЕ ОБЩЕГО (Р-53, пункт 3:
   «цельный элемент границей экрана не разрывается»).

   Обычной полосе-продолжению достаточно не открывать снизу следующую
   ГЛАВУ. Здесь мало и этого: перечень и отзывы состоят из цельных
   единиц, и приоткрыть снизу даже СВОЙ следующий пункт нельзя —
   начатая и оборванная на полуслове единица читается сбоем, а не
   разворотом книги. Абзац главы разорваться может, перечисляемая
   единица — нет.

   Проверено на кадре: после перевода перечня на корпусный кегль первая
   полоса «Кому не подойдёт» стала короче экрана, и снизу повис обрубок
   пятого пункта в две строки. */
.numbered:has(+ .section--running),
.reviews:has(+ .section--running) { min-height: var(--screen); }
/* Возврат в главу после фотополосы (Р-47): метка стоит сразу над первой
   строкой текста, воздуха под ней меньше, чем под Д2-заголовком.        */
.resume { color: var(--ink-soft); margin-bottom: clamp(16px, 2.5vh, 28px); }

/* Страницы без героя начинаются текстом — им воздух сверху нужен.
   Полноэкранный кадр в этот список не входит: отступ сверху оторвал бы
   кадр от края и сломал бы единицу экрана. Так открывается титул
   страницы (док. 03 §4).                                               */
body:not(.has-hero) main > :first-child { padding-top: clamp(112px, 18vh, 200px); }
body:not(.has-hero) main > .spread:first-child,
body:not(.has-hero) main > .plate-hold:first-child,
body:not(.has-hero) main > .plate-open:first-child,
body:not(.has-hero) main > .plate-swap:first-child,
body:not(.has-hero) main > .closing:first-child { padding-top: 0; }

/* Отступа метки под шапку здесь больше нет: постоянной шапки на сайте
   не существует, а колонтитул на титуле снят — верхнюю линию занимает
   марка (Р-21, Р-23).                                                  */

/* Основной текст никогда не растягивается на всю ширину десктопа */
.chapter__p, .chapter__lead, .numbered__list, .offer__p, .faq__a, .numbered__after {
  max-width: var(--measure);
}

/* ВХОД В БУМАЖНУЮ ГЛАВУ (Р-40, Р-41). .entry оборачивает Д2-заголовок и
   маркер меню: заголовок стоит у левого поля, маркер под ним у правого
   (.marker--entry, align-self: flex-end) — в потоке, не абсолютом от
   первой строки, потому что у заголовка бывает две и три строки.        */
.entry {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  /* ВТОРОЕ УПОЛОВИНИВАНИЕ (Р-57): вдвое от значения после Р-44, вчетверо
     от исходного. После Р-44 глава перестала переполнять экран, но
     воздух под входом остался самым большим интервалом полосы, и
     заголовок читался оторванным от своего текста. Правило общее, без
     страничных исключений (Р-41). */
  margin-bottom: clamp(8px, 1.25vh, 14px);
}

/* МЕРА Д2 НЕ ЗАФИКСИРОВАНА В СИМВОЛАХ НА МОБИЛЬНОМ (Р-41): заголовок
   распределяется по ширине полосы через text-wrap: balance — меньше
   строк там, где это возможно, без правки кегля. На десктопе, где полоса
   куда шире меры чтения, ширина ограничивается ориентировочно 24ch. */
.chapter__heading, .offer__heading, .entry__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: var(--h-chapter);
  line-height: 1.04;
  letter-spacing: -.01em;
  margin-bottom: clamp(15px, 2.5vh, 28px);
  text-wrap: balance;
  hyphens: none; /* переносы в дисплейном слое запрещены */
}
.entry__title { margin-bottom: 0; }
@media (min-width: 900px) {
  .chapter__heading, .offer__heading, .entry__title { max-width: 24ch; }
}

.chapter__lead, .offer__lead {
  font-size: var(--t-lead);
  line-height: 1.55;
  margin-bottom: 1.2em;
}

.chapter__p + .chapter__p, .offer__p + .offer__p { margin-top: 1.1em; }

.chapter--airy .chapter__p:last-child { margin-top: 2.4em; }

/* ЦИТАТА В ТЕКСТЕ — РОЛЬ 1 ИЗ ДВУХ (Р-45). Golos 400 на Р1, не Prata:
   цитата — чужая речь, а Prata — голос издания, отдавать её цитате
   значит говорить чужими словами своим шрифтом. Втяжка слева на ширину
   поля отбивает её от корпуса, без линий, кавычек, курсива и плашек. */
.quote {
  margin: var(--quote-space) 0;
  padding-left: var(--pad);
  max-width: var(--measure);
}
.quote__line {
  font-family: var(--speech);
  font-weight: 400;
  font-size: var(--t-lead);
  line-height: 1.55;
}
/* КОРПУСНЫЙ ИНТЕРЛИНЬЯЖ (Р-58): добавочного интервала между строками
   цитаты нет — разбивка на строки остаётся смысловой разметкой, а не
   разрежением. Роль 1 (Р-45) задумывалась тише корпуса, а разреженные
   строки делали цитату самым просторным объектом полосы. Отбивку даёт
   втяжка и воздух вокруг (--quote-space), не воздух внутри. */
.quote__source { margin-top: 14px; color: var(--ink-soft); }

/* Строка границ работы: слоем «Документ», ролью «подпись» — это фраза,
   которую читают, а не служебная метка (док. 02 §7).                    */
.note-boundaries {
  /* Воздух собран (решение владельца): дисклеймер идёт СТРОКОЙ сразу
     после кнопки, а не отдельной зоной через поле. Он оговаривает то,
     на что нажимают, и стоять должен при кнопке.                      */
  margin-top: clamp(18px, 2.6vh, 32px);
  color: var(--ink-soft);
  max-width: 56ch;
}
/* ПОДЧЁРКИВАНИЕ ЧЕРНИЛЬНОЕ, А НЕ ЭГЕЙСКОЕ (Р-83). Эгейский помечает не
   «здесь ссылка», а «сюда стоит нажать»; дисклеймер набран самым тихим
   кеглем и стоит под кнопкой, и голубая волосяная делала его тише кнопки
   по весу и громче по цвету. Ссылка остаётся ссылкой — меняется материал
   подчёркивания, не его наличие. Тот же случай, что ссылки «Материалов». */
.note-boundaries a { text-decoration-color: var(--hairline); }

/* ── Герой ──────────────────────────────────────────────────────────────
   Полный экран, кадр край-в-край, ч/б.
   Высота — единица экрана (док. 01 §4). Текст держится от края на
   --safe-copy, иначе всплывшая адресная строка срезает нижнюю строку.  */

.hero { position: relative; height: var(--screen); overflow: hidden; background: var(--black); }

.hero__frame, .hero__frame picture { position: absolute; inset: 0; }

.hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Единственная автоматическая анимация на сайте: кадр выходит
     из размытия в резкость (док. 01 §6.1). Это не декор, это тезис.     */
  animation: focus-in 2000ms cubic-bezier(.22, 1, .36, 1) both;
}

@keyframes focus-in {
  from { filter: blur(14px) brightness(.62); transform: scale(1.03); }
  to   { filter: blur(0)    brightness(1);   transform: scale(1); }
}

/* Затемняющая маска. Градиент допустим только здесь: контраст текста
   обеспечивается маской, а не тенью текста (док. 01 §8, док. 04 §5).    */
.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(8, 7, 6, .82) 0%,
    rgba(8, 7, 6, .06) 46%,
    rgba(8, 7, 6, .42) 100%
  );
}

/* КОПИЯ УХОДИТ ПО ПРОКРУТКЕ (Р-16). Прозрачность и подъём ставит JS,
   здесь только заявка браузеру: эти два свойства будут меняться каждый
   кадр. Кадр героя при этом неподвижен — граница с параллаксом в том,
   что копия движется в пределах своего блока, а слои кадра друг
   относительно друга не смещаются.                                     */
.hero__copy {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  bottom: var(--safe-copy);
  z-index: 3;
  will-change: opacity, transform;
}

/* ТЭГЛАЙН — ФРАЗА, А НЕ СЛОВО, И ПОТОЛОК У НЕГО ВЕРТИКАЛЬНЫЙ. Ступень Д1
   рассчитана на голос во весь экран в одну-две строки. «Увидеть
   реальность такой, какая она есть» — шесть слов, на широком экране это
   четыре строки, и при 8vw (115px на 1440) они поднимались от нижнего
   поля до подбородка: буквы шли по лицу, а лицо — сюжет кадра (Р-22).

   Лечится это двумя правками, и обе — про фразу, а не про ступень.

   ПОТОЛОК ПО ВЫСОТЕ: строка не крупнее 8,2% экрана. На телефоне и
   планшете он не срабатывает вовсе (там Д1 и так 46–61px) — работает
   только на широком, где беда и была.

   МЕРА ШИРЕ: 20ch вместо 14ch. Четырнадцать знаков — мера для
   заглавия в одно-два слова; шестисловную фразу они резали на четыре
   строки, а четыре строки высотой не удержать без того, чтобы кегль
   стал мельче заголовка главы. На двадцати знаках фраза встаёт в две
   строки и на широком экране начинается на сотню пикселей ниже
   подбородка. На телефоне мера всё равно упирается в ширину колонки,
   и там ничего не изменилось: четыре строки по 46px, как было.

   То же по смыслу, что формула у .spread__title: она укорачивает кегль
   от длины слова, эта — держит фразу в нижней трети кадра.            */
.hero__tagline {
  font-family: var(--display);
  font-weight: 400;
  font-size: min(var(--h-hero), calc(var(--screen) * .082));
  line-height: .98;
  letter-spacing: -.01em;
  color: var(--on-frame);
  max-width: 20ch;
  text-wrap: balance;
  hyphens: none;
}

/* Дескриптор внизу справа героя снят: он ушёл в марку, к имени (Р-20).
   Разнесённая марка — имя в шапке, дескриптор внизу героя — была двумя
   половинами, которые никогда не встречались.                          */

/* ШАПКА КОНСПЕКТА — В КРИТИЧЕСКОМ, а не со своей секцией ниже: это
   первый экран скрытых страниц, и без этих правил заглавие встречи
   успевает мигнуть корпусным шрифтом, пока грузится site.css.
   Остальной конспект — текст под сгибом, ему хватает обычной загрузки. */
.longread__meeting { margin-bottom: clamp(10px, 1.6vh, 16px); }

/* Заглавие встречи — второй уровень иерархии (док. 01 §3): вход в главу,
   Д2 Prata. Первого уровня здесь нет — титула-кадра у конспекта нет. */
.longread__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: var(--h-chapter);
  line-height: 1.04;
  letter-spacing: -.01em;
  text-wrap: balance;
  hyphens: none;
  max-width: 24ch;
  margin: 0 0 clamp(30px, 4.5vh, 56px);
}

/* ЗАПИСЬ ВСТРЕЧИ. Плеер чужой — это единственное место сайта, где чужая
   система показывает своё лицо. Обрамления ему не даётся: ни рамки, ни
   скругления, ни тени (док. 01 §8) — прямоугольник 16:9 на бумаге.
   Чёрная подложка под ним не украшение: пока ролик не загрузился, в
   этом месте иначе дыра в цвет бумаги.

   В потоке плеера больше нет: он заводится по нажатию и всегда один на
   странице (Р-118). Правило осталось в критическом потому, что открыть
   запись могут раньше, чем догрузится site.css.                       */
.longread__player { position: relative; aspect-ratio: 16 / 9; background: var(--black); margin-top: clamp(12px, 1.8vh, 16px); }
.longread__player iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* Плеер, заведённый в плите, встаёт ровно на её место: плита и есть
   тот самый прямоугольник 16:9, и заводить рядом второй незачем. */
.longread__player--vplitu { position: absolute; inset: 0; margin: 0; }

/* critical:end — ниже идёт всё, что первому экрану не нужно */

/* ── ПОЛНОЭКРАННЫЙ КАДР — ОДИН ШАБЛОН НА ВСЕ КАДРЫ (док. 01 §6.8) ───────
   Три позиции и ни одной больше:

     верхняя линия  — колонтитул главы, в которой стоит кадр;
     нижняя линия   — подпись;
     над подписью   — дисплейная строка.

   Середина остаётся кадру. Блоки различаются механикой — держание,
   раскрытие, смена, разворот, финал, — а не раскладкой: раскладка одна
   и лежит здесь. Исключений нет, поэтому у читателя не возникает
   вопроса, где на этом экране искать главу и что за снимок он видит. */

.frame__top {
  position: absolute;
  inset: var(--top-line) var(--pad) auto;
  z-index: 5;
  margin: 0;
}
/* НОСИТЕЛЬ РЕШАЕТ, КАК МЕТКА ВЫГЛЯДИТ (док. 01 §6.8). Рисунок тот же, что
   на бумаге, — линейка и под ней метка, — но в цветах кадра.

   ЛИНИЯ ЭГЕЙСКАЯ (Р-38). Прежде она была здесь светлой — по запрету §8
   на выборочный цвет поверх ч/б фотографии. Запрет отменён для волосяной
   линии: пиксельная линия выборочным цветом не читается, она читается
   принадлежностью, и эгейский на сайте помечает кликабельное и марку —
   теперь он делает это на любом носителе одинаково.

   Метка идёт по шкале громкости кадра, наравне с дисплейной строкой.
   Приглушённость оправдана на бумаге, где метка спорит с текстом главы
   и уступает ему по праву; на кадре она единственная строка сверху и
   спорит с фотографией — ослабленная, она ей проигрывает.             */
.frame__top .folio__rule  { background: var(--hairline-frame); }

/* МЕТКА ХОДИТ ЗА ДИСПЛЕЙНОЙ СТРОКОЙ (Р-38): один токен на обе. Прежде
   здесь стоял чистый белый — он ярче собственной палитры издания и ярче
   белых в самой фотографии, и буквы отрывались от снимка вместо того,
   чтобы лежать в нём. Метка, которая темнее строки на том же кадре, —
   несогласованность, поэтому значение у них общее.                    */
.frame__top .folio__label { color: var(--on-frame); }

/* КАДР СВЕТЛЫЙ И ПЁСТРЫЙ — МЕНЯЕТСЯ ГРОМКОСТЬ, А НЕ ЗНАК.

   Р-54 ОТМЕНЁН ЦЕЛИКОМ (решение владельца). Он отвечал на камелию тремя
   приёмами сразу: осветляющей маской вместо затемняющей, чернильной
   меткой вместо светлой и размытием подложки под самой меткой. Первые
   два перевернули знак колонтитула на одном кадре из семи, третий
   читался плашкой — тем, чего §8 не допускает. Ни один не сделал метку
   читаемой, а вместе они сделали её чужой.

   Осталась одна ручка, и она работает в ту же сторону, что вся шкала
   громкости кадра: метка и волосяная идут ступенью выше общей. Тон тот
   же, что у подписи внизу этого же кадра и у метки на любом другом
   снимке, — тон издания. Чистый белый на кадрах по-прежнему запрещён
   (док. 01 §6.8), поэтому верх шкалы здесь --paper, а не #fff.

   СТОИТ ПОСЛЕ ОБОИХ ОБЩИХ ПРАВИЛ, И ЭТО НЕ ВКУСОВЩИНА: специфичность
   у модификатора и у общего правила одинаковая — два класса, — решает
   порядок в файле. Любой будущий модификатор кадра дописывается СЮДА. */
.frame__top--bright .folio__rule  { background: rgba(242, 240, 236, .82); }
.frame__top--bright .folio__label { color: var(--paper); }

/* НАБОР ДИСПЛЕЙНОЙ СТРОКИ НА КАДРЕ отделён от её ПОЗИЦИИ и от её
   ПОВЕДЕНИЯ намеренно. Строка бывает одна (пластина А, финал), а бывает
   цитатой из нескольких строк с авторством под ними (пластины Б и В) —
   набор у них общий, а приходит и уходит цитата целым блоком, вместе
   с именем автора, а не построчно.                                    */
.frame__line,
.quote-frame__line {
  font-family: var(--display);
  font-size: var(--h-plate);
  line-height: 1.18;
  color: var(--on-frame);
  max-width: 20ch;
  text-wrap: balance;
  hyphens: none;
}

/* Дисплейная строка встаёт НАД подписью, а не в свободный угол кадра. */
.frame__line {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  bottom: var(--frame-copy);
  z-index: 4;
}

/* Подпись всегда светлая и всегда на нижней линии: тёмная сливалась
   со светлым камнем, а угол «где посвободнее» у каждого кадра свой.   */
.frame__caption {
  position: absolute;
  left: var(--pad);
  bottom: var(--safe-edge);
  z-index: 5;
  color: var(--on-frame-cap);
}

/* ЗАТЕМНЯЮТСЯ ПОЛОСЫ, А НЕ КАДР. Раньше светлый снимок приглушался
   целиком фильтром яркости — текст читался ценой фактуры. Теперь
   гаснут только верхняя и нижняя полосы, где лежат буквы; середина
   остаётся кадру и на светлом снимке тоже. Плашкой это не является:
   границы у затемнения нет, есть градиент (док. 01 §8).               */
.frame__scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: var(--scrim-top), var(--scrim-bottom);
}

/* ── Пластина А · держание (док. 01 §6.2) ───────────────────────────────
   СЛОТОВ СТОЛЬКО, СКОЛЬКО СОСТОЯНИЙ: кадр и кадр со строкой. «Слота
   ухода» не бывает — липкая сцена открепляется сама на последнем слоте,
   и следующая секция уносит кадр вместе со строкой. Лишний слот дал бы
   флинг, после которого на экране ничего не меняется.                   */

/* Один слот — одно состояние: кадр со строкой. Сцена ростом ровно
   в экран (док. 01 §6.2).                                             */
.plate-hold { position: relative; height: var(--screen); background: var(--black); }

/* Колонтитул живёт внутри липкой сцены, а не в секции: в секции он
   уезжал на втором слоте, хотя кадр ещё держится. Раскладку даёт
   общий шаблон кадра, здесь только механика.                          */
.plate-hold__stage { position: sticky; top: 0; height: var(--screen); overflow: hidden; z-index: 1; }

.plate-hold__frame, .plate-hold__frame picture { position: absolute; inset: 0; }

/* Яркость поднята с .62: затемнять весь кадр больше незачем, полосы под
   текстом гасит общая маска, а снимок остаётся снимком.                */
.plate-hold__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(.82);
}

/* ── Пластина Б · раскрытие полосы (док. 01 §6.3) ───────────────────────
   Ставится один раз на весь сайт. Кадр входит узкой лентой и раскрывается
   до полного экрана. ОБРАТНОГО ЗАКРЫТИЯ НЕТ: раскрывшись, кадр остаётся
   полноэкранным, и следующая секция на бумаге наезжает на него сверху.  */

/* Два состояния — два слота: лента и раскрытый кадр (док. 01 §6.3). */
.plate-open { position: relative; height: calc(2 * var(--screen)); background: var(--paper); }
.plate-open__stage { position: sticky; top: 0; height: var(--screen); overflow: hidden; z-index: 1; }

.plate-open__frame {
  position: absolute;
  /* Стартовое состояние: лента в 36% высоты сцены с боковыми полями.
     Проценты, а не единицы вьюпорта: сцена уже равна экрану, и внутри
     неё считать надо от неё же — иначе лента снова живёт по своей
     линейке (док. 01 §4).                                              */
  top: 32%;
  bottom: 32%;
  left: var(--pad);
  right: var(--pad);
  overflow: hidden;
}
.plate-open__frame picture { position: absolute; inset: 0; }

.plate-open__img { width: 100%; height: 100%; object-fit: cover; }

/* МЕТКА НЕ ПЕРЕПРЫГИВАЕТ (док. 01 §6.3). Она стоит на верхней линии
   СЦЕНЫ — одном месте в обоих состояниях — и только переключает цвет,
   когда кадр накрывает эту линию. Раньше она лежала внутри кадра и
   графически не отличалась от подписи к снимку.

   В состоянии ленты вокруг кадра бумага, значит метка стоит на бумаге:
   приглушённая, с эгейской линейкой, как на любой текстовой полосе. */
.plate-open__folio {
  position: absolute;
  inset: var(--top-line) var(--pad) auto;
  z-index: 5;
}
.plate-open__folio .folio { margin-bottom: 0; }
/* НА БУМАГЕ ЛИНИЯ ЧЕРНИЛЬНАЯ, ГОЛУБОЙ ОНА СТАНОВИТСЯ НА КАДРЕ (решение
   владельца, возврат прежнего поведения). Эгейская волосяная на бумаге
   принадлежит ссылке и марке; здесь линия ничего не открывает — она
   держит верхнее поле, и до разворота стоит тем же материалом, что
   разделители перечня и штрихи маркера меню. Голубой приходит вместе
   с кадром, и приход голубого — и есть событие разворота.            */
.plate-open__folio .folio__rule { background: var(--hairline); }
.plate-open__folio .folio__rule,
.plate-open__folio .folio__label {
  transition: background-color var(--carrier) var(--flight-ease),
              color var(--carrier) var(--flight-ease);
}
/* Кадр накрыл линию — носитель сменился, и метка переходит к правилу
   кадра: линия из эгейской становится НЕЙТРАЛЬНОЙ, метка берёт полный
   цвет. Линия не исчезает и не появляется — она меняет цвет, потому
   что сменилось то, на чём она лежит. Голубого на фотографии нет ни в
   каком виде (док. 01 §2, §6.8), и переход должен успеть отыграть
   раньше, чем кадр накроет линию совсем.                             */
.plate-open__folio.is-on-frame .folio__rule { background: var(--hairline-frame); }
.plate-open__folio.is-on-frame .folio__label { color: var(--on-frame); }

/* Строка приходит уже на раскрытый кадр, поэтому стоит на сцене, а не
   внутри ленты: в ленте ей места нет. Маску под ней даёт общий шаблон,
   своей у неё больше нет — тени у текста тоже (док. 04 §5).           */
.plate-open .frame__line { max-width: 18ch; }

/* ПОДПИСЬ ЛЕЖИТ ВНУТРИ КАДРА (Р-60, уточнено владельцем): в его левом
   нижнем углу, невысоко от края, видна уже в ленте. Отдельных правил
   ей не нужно — общий .frame__caption ставит её ровно туда, а движется
   она вместе с кадром, потому что она его часть. Единственная поправка:
   в ленте кадр низкий, и отступ от края берётся от кадра, а не от
   экрана, — иначе подпись вылезала бы за его нижнюю границу.          */
.plate-open__frame .frame__caption { bottom: clamp(14px, 2.2vh, 22px); }

/* ── Пластина В · смена пластин (док. 01 §6.4) ──────────────────────────
   Не карусель: ничего не движется само, назад отматывается прокруткой.
   Ни точек, ни стрелок, ни автоплея.                                    */

/* По слоту на кадр и ни одним больше: сцена сходит сама (док. 01 §6.4).
   Высота считается от числа кадров — его ставит шаблон.               */
.plate-swap { position: relative; height: calc(var(--frames, 3) * var(--screen)); background: var(--black); }
.plate-swap__stage { position: sticky; top: 0; height: var(--screen); overflow: hidden; z-index: 1; }

.plate-swap__frame {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity .9s ease;
}
.plate-swap__frame.is-on { opacity: 1; }
.plate-swap__frame picture { position: absolute; inset: 0; }

/* Яркость поднята с .72 по той же причине, что и на пластине А. */
.plate-swap__img { width: 100%; height: 100%; object-fit: cover; filter: brightness(.86); }

/* Кадров три — подписей три: подпись меняется вместе с кадром, поэтому
   у общей нижней линии здесь появляется механика смены, и только она. */
.plate-swap__captions { height: 1.5em; }
.plate-swap__captions span {
  position: absolute;
  left: 0;
  bottom: 0;
  white-space: nowrap;
  opacity: 0;
  transition: opacity .5s;
}
.plate-swap__captions span.is-on { opacity: 1; }

/* ЦИТАТА НА КАДРЕ (Р-45): та же раскладка низа, что у любой дисплейной
   строки на кадре, но обёртка в потоке — строка и авторство стоят
   стопкой, без знания друг о друге высоты. .frame__line сбрасывает
   собственное позиционирование внутри обёртки, не втяжки — цитата на
   кадре без неё, в отличие от роли «в тексте».                        */
.quote-frame {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  bottom: var(--frame-copy);
  z-index: 4;
}
.quote-frame__line { position: static; margin: 0; }
.quote-frame__source { margin-top: 10px; color: var(--on-frame-cap); }

/* ЦИТАТА СТОПКОЙ (пластина Б): разбивка на строки авторская и смысловая,
   а не результат переноса. Запретить перенос внутри строки нельзя —
   на 390px «Жизнь устроена по незыблемым законам.» дисплейным кеглем
   шире поля, и nowrap вынес бы её за край. Поэтому строки просто стоят
   отдельными абзацами: разбивка держится их порядком, а не запретом. */
/* Мера 20ch считалась для одной длинной фразы, которой перенос идёт на
   пользу. Здесь строк три, каждая своей длины, и та же мера ломала
   первую из них натрое — стопка переставала читаться стопкой. Внутри
   стопки строка берёт всё поле, а держит её собственная длина.       */
.quote-frame--stack .quote-frame__line { max-width: none; }
.quote-frame--stack .quote-frame__line + .quote-frame__line { margin-top: .18em; }

/* ── Титул страницы · инверсия пластины (док. 01 §6.2, док. 03 §4) ───────
   Метка называет СТРАНИЦУ и идёт без номера: нумерация глав начинается
   со следующего экрана.

   ТЕКСТ СТОИТ ГОТОВЫМ, КАДР ПРИХОДИТ ИЗ РАЗМЫТИЯ — по остановке. Роли
   пластины меняются местами; правило «от остановки» сохраняется, потому
   что появление по скроллу §8 запрещает как систему. Приём заодно
   объясняет, зачем титул нужен: он открывает главу тем, что глава ещё
   не видна.                                                            */

.spread { position: relative; height: var(--screen); background: var(--black); }
/* Сцена липкая, как у всех приёмов: точку снапа даёт рельс, и в потоке
   стоит именно он. Была бы сцена обычной, она встала бы ПОСЛЕ рельса и
   уехала на его высоту вниз (док. 01 §4).                             */
.spread__stage { position: sticky; top: 0; height: var(--screen); overflow: hidden; z-index: 1; }
.spread__frame, .spread__frame picture { position: absolute; inset: 0; }
.spread__img { width: 100%; height: 100%; object-fit: cover; }

/* ГЛУБОКАЯ НИЖНЯЯ МАСКА. Общая маска гаснет к 42% высоты и под
   заглавием держит едва пятнадцать сотых — этого хватает на кадре,
   который внизу тёмный. На титуле «Тренингов» внизу солнечные плиты,
   да ещё и движущиеся: «нинги» на них пропадало целиком.

   Ручка одна и включается из данных, как громкость метки на коде: где
   кадр внизу тёмный, ничего не меняется. Низ полосы не трогаем — там
   стоят подпись и кнопка, и чернее .78 им не нужно; растёт плотность
   там, где лежит заглавие, и гашение отодвигается до 54%.            */
.spread--deep {
  --scrim-bottom: linear-gradient(
    to top,
    rgba(8, 7, 6, .78) 0%,
    rgba(8, 7, 6, var(--spread-deep, .46)) 27%,
    rgba(8, 7, 6, 0) 54%
  );
}
/* Ролик ведёт себя как кадр: то же ложе, тот же кроп по месту.
   display: block снимает зазор строчного элемента под видео.          */
video.spread__img { display: block; background-color: var(--black, #000); }

/* КНОПКА ЗВУКА НА ТИТУЛЕ. Плашки нет (док. 01 §8) — служебная строка
   того же набора, что подпись кадра, только у правого поля: слева на
   нижней линии уже стоит подпись, и две строки в одном углу дрались бы.

   Цель касания добирается невидимым хитбоксом, как у ссылок «Открытых
   материалов» и каналов колофона: сама строка ниже 44px.              */
.frame__sound {
  position: absolute;
  right: var(--pad);
  bottom: var(--safe-edge);
  z-index: 5;
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  cursor: pointer;
  color: var(--on-frame-cap);
  font: inherit;
  letter-spacing: var(--doc-service-ls);
  text-transform: uppercase;
  font-size: var(--doc-service);
}
.frame__sound::after {
  content: '';
  position: absolute;
  left: -12px;
  right: -12px;
  top: 50%;
  height: 44px;
  transform: translateY(-50%);
}

/* Токены и кривая те же, что у --reveal: это один приём, только роли
   в нём переставлены.                                                 */
.spread__frame {
  opacity: 0;
  filter: blur(12px);
  transform: scale(1.02);
}
.spread__frame.is-on {
  opacity: 1;
  filter: blur(0);
  transform: none;
  transition: opacity var(--reveal),
              filter var(--reveal),
              transform var(--reveal);
}
/* Кадр приходит один раз и с себя не снимается: is-on остаётся до
   перезагрузки, поэтому повтора у него не бывает по устройству. Памяти
   о показе отдельным классом для этого не нужно (Р-34).              */

/* НИЗ ТИТУЛА: заглавие страницы и лид под ним (Р-21). Стоят над подписью,
   как дисплейная строка на любом другом кадре, — раскладка низа одна на
   весь сайт (§6.8), титул только заполняет её своим содержимым.

   Колонтитула на титуле нет вовсе: его место на верхней линии заняла
   марка. Прежняя метка называла страницу — ту же работу делает заглавие
   внизу, и делает её крупнее.

   Текст СТОИТ ГОТОВЫМ: проявляется здесь кадр, не буквы. Общее правило
   проявления (§6.0) титула не касается — приём инвертирован, и роли в нём
   переставлены, а не удвоены.                                          */
.spread__copy {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  bottom: var(--frame-copy);
  z-index: 4;
}
/* ЗАГЛАВИЕ ИДЁТ Д1 (Р-41): титул — первый уровень иерархии наравне с
   тэглайном героя, и на любой внутренней странице должен звучать так же
   громко, как на главной. Прежняя Д3 приравнивала титул к строке на
   кадре — тише, чем полагается первому уровню.                        */
/* ЗАГЛАВИЕ НЕ ВЫХОДИТ ЗА ПОЛЕ, ДАЖЕ ЕСЛИ СЛОВО ДЛИННОЕ. Дисплей не
   переносится (hyphens: none), поэтому слово шире поля вылезало за край
   страницы: «Психосоматика» — тринадцать знаков, и на 375px оно не
   помещалось. Единственный оставшийся ход — кегль, и он уменьшается
   ровно настолько, насколько не хватает места:

     доступная ширина = 100vw − два поля;
     на знак у Prata приходится около 0,62em, берём 0,645 с запасом,
     то есть кегль ≤ ширина ÷ знаков × 1,55.

   min() с общей шкалой означает, что правило умеет только уменьшать:
   там, где слово короткое, множитель выходит больше Д1, и остаётся Д1
   (Р-41 не тронут). --title-word ставит шаблон — это длина самого
   длинного слова заглавия.

   Мера тоже считается от слова: 14ch — это мера строки, а не слова,
   и на широком экране «Психосоматика» выходила и за неё.              */
.spread__title {
  font-family: var(--display);
  font-weight: 400;
  font-size: min(
    var(--h-hero),
    calc((100vw - var(--pad) * 2) / var(--title-word, 8) * 1.55)
  );
  line-height: .98;
  letter-spacing: -.01em;
  color: var(--on-frame);
  max-width: max(14ch, calc(var(--title-word, 8) * 1.25ch));
  margin-bottom: 16px;
  text-wrap: balance;
  hyphens: none;
}
/* ГРОМКОСТЬ ЗАГЛАВИЯ — ручка кадра, как плотность маски (док. 01 §6.8).
   На титуле «Тренингов» внизу солнечные плиты: маска доведена до .46 и
   дальше её поднимать нельзя — кадр гаснет весь, а плиты в нём и есть
   сюжет. Поэтому поднимается не фон, а буквы — той же тенью, какой на
   кадре стоит марка (--mark-shade), только плотнее: у заглавия кегль
   втрое крупнее, и тень по его росту.

   Это не плашка (док. 01 §8): границы у тени нет, форма — форма букв. */
.spread--loud .spread__title {
  text-shadow: 0 1px 2px rgba(8, 7, 6, .5), 0 0 34px rgba(8, 7, 6, .75);
}
.spread--loud .spread__lead {
  text-shadow: 0 1px 2px rgba(8, 7, 6, .45), 0 0 20px rgba(8, 7, 6, .6);
}
/* Лид — слой «Речь», Р1. Мера уже корпусной: под ним не абзац, а одна
   мысль, и длинная строка на кадре читается хуже, чем на бумаге.      */
.spread__lead {
  font-size: var(--t-lead);
  line-height: 1.5;
  color: rgba(232, 228, 220, .88);
  max-width: 30ch;
}

/* ── Кадр в колонке ─────────────────────────────────────────────────────── */

/* Своей нижней отбивки у кадра нет: воздух дают отступы соседних
   секций сверху и снизу, иначе под кадром его вдвое больше, чем над. */
.figure { padding: 0 var(--pad); }
.figure + .figure { margin-top: var(--section); }
.figure--wide  { max-width: 1200px; }
.figure--column { max-width: calc(var(--measure) + var(--pad) * 2); }
.figure__caption { margin-top: 14px; color: var(--ink-soft); }

.figure__stub, .frame__stub {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 240px;
  background: var(--paper-deep);
  color: var(--ink-soft);
}
.frame__stub { position: absolute; inset: 0; }

/* ── Спуск к причине · сигнатурный приём (док. 01 §6.5) ─────────────────
   Четыре экрана — четыре слота, по слоту на экран. Отдельного экрана
   схода нет: на последнем слоте сцена открепляется, и выход наезжает
   на неё сверху. Фон интерполируется по позиции — значение ставит JS.  */

/* Фон стартует с --paper-deep, а не с общей бумаги: на ней первый шаг
   спуска был нулевым, и спуск начинался не спуском (док. 01 §6.5). */
.descent { position: relative; height: calc(4 * var(--screen)); background: var(--paper-deep); }

.descent__stage {
  position: sticky;
  top: 0;
  height: var(--screen);
  z-index: 1;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 var(--pad);

  /* Фон и цвет текста идут ровно со скоростью метки, летящей в стопку:
     одно событие — одно движение (док. 01 §6.5).                      */
  transition: background-color var(--flight) var(--flight-ease),
              color var(--flight) var(--flight-ease);
}

/* Пройденные метки оседают стопкой в левом верхнем углу, прозрачность 42%.
   Стопка стоит ровно там, где у главы стоит подпись колонтитула:
   верхняя линия плюс линейка (1px) и воздух под ней (22px).            */
.descent__stack {
  position: absolute;
  top: calc(var(--top-line) + 23px);
  left: var(--pad);
  display: flex;
  flex-direction: column;
  gap: 9px;
}
/* Метка в стопке, метка на экране и летящая копия берут метрики роли
   «колонтитул» и обязаны брать их одинаково: иначе на перелёте видно,
   как буквы разъезжаются.                                             */
.descent__stack i {
  font-family: var(--doc);
  font-style: normal;
}
/* СТОПКА ПОКАЗЫВАЕТ ГЛУБИНУ (док. 01 §6.5). Места размечены сразу на все
   четыре: пройденные — метками, будущие — волосяными штрихами. Раньше
   будущее место пустовало (opacity: 0), и глубину приходилось показывать
   отдельным индикатором из четырёх штрихов справа — второй объект ради
   того, что помещается в первый. Теперь пустое место видно, и индикатор
   снят целиком.

   Заодно лечится ощущение пустоты на первом экране спуска: верхняя линия
   перестаёт быть пустой с самого начала.                              */
.descent__stack i { position: relative; opacity: 1; }
.descent__stack i b { font-weight: inherit; opacity: .42; }

/* Будущее место: штрих вместо метки. Высота места при этом не меняется —
   текст остаётся на месте и только гасится, поэтому осевшие метки не
   дёргаются, когда прилетает новая.                                    */
.descent__stack i.is-off b { opacity: 0; }
.descent__stack i.is-off::before {
  content: '';
  position: absolute;
  top: .7em;
  left: 0;
  width: 26px;
  height: 1px;
  background: currentColor;
  opacity: .3;
  transition: opacity var(--flight-clear) var(--flight-ease);
}

/* МЕСТО ОСВОБОЖДАЕТСЯ ДО ПРИЛЁТА. Штрих гаснет в начале полёта, а не
   по прибытии: садясь на живой штрих, метка доли секунды лежит на нём,
   и слово читается перечёркнутым. Гашение короче перелёта — место
   должно опустеть заранее, а не одновременно (док. 01 §6.5).         */
.descent__stack i.is-clearing::before { opacity: 0; }

/* ПЕРЕЛЁТ МЕТКИ. Уходя, экран отдаёт метку в стопку: летит копия,
   потому что сам экран в этот момент гаснет. Пока копия в пути, своя
   метка с экрана снята — иначе на месте был бы второй экземпляр.      */
.descent__screen.is-handed .descent__label { opacity: 0; }

.descent__flyer {
  position: absolute;
  z-index: 6;
  margin: 0;
  font-family: var(--doc);
  white-space: nowrap;
  pointer-events: none;
  will-change: transform;
}

/* Индикатора из четырёх штрихов справа больше нет: глубину показывает
   сама стопка, а один объект лучше двух. На мобильном он и так был скрыт
   (max-width: 767px), то есть на основном устройстве не существовал, а на
   десктопе жил на правом краю, где во время флинга появляется родная
   полоса прокрутки, — был невидим ровно тогда, когда на него смотрели бы
   (док. 01 §6.5).                                                      */

.descent__screen {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  opacity: 0;
  pointer-events: none;
}
.descent__screen.is-on { opacity: 1; }

/* Метка идёт currentColor с приглушением, а не акцентом: голубой
   закреплён за кнопкой и монограммой (док. 01 §2). Заодно метка
   сама переключается со светлого на тёмное вместе со сценой.            */
.descent__label {
  color: currentColor;
  opacity: .62;
  margin-bottom: clamp(14px, 2.2vh, 26px);
}

/* Единый кегль на всех четырёх экранах, задан по самой длинной строке.
   Уменьшать кегль на многострочных экранах запрещено (док. 01 §6.5).    */
/* Меры у экрана спуска нет: строки здесь авторские, разбиты руками, и
   мера их только резала. 14ch давали 280px — «так поступить» при 275px
   стояло впритык и на узком экране ломалось третьей строкой.
   Ширину держит поле страницы (док. 01 §6.5).                         */
.descent__big {
  font-family: var(--display);
  font-weight: 400;
  font-size: var(--h-descent);
  line-height: 1;
  letter-spacing: -.015em;
  text-wrap: balance;
  hyphens: none;
}

.descent__line { display: block; }

/* Расшифровка стоит на Р1, как лид: это пояснение к доводу, а не
   подпись и не служебная строка. Раньше она шла шестым кеглем — мельче
   корпуса — и при этом ещё приглушалась прозрачностью: подчинение было
   сделано дважды. Одного раза достаточно, и это цвет.                  */
.descent__sub {
  margin-top: clamp(18px, 2.6vh, 32px);
  font-size: var(--t-lead);
  line-height: 1.55;
  max-width: 46ch;
}

/* ВЫХОД — ПОЛНОЭКРАННЫЙ КАДР (док. 01 §6.5). Бумажный выход давал вспышку
   белого сразу после спуска, потемневшего до чёрного: три строки посреди
   пустоты. Чёрный выход вспышку не убирал, а переносил на экран дальше —
   следом идёт бумага; градиент «рассвет» рядом с семью кадрами читался
   служебным приёмом. Кадр решает обе задачи разом: тьма расступается
   там, где текст говорит «рискните», а светлый снимок ведёт к бумаге
   через полутон, а не встык.

   Механика — инверсия пластины, та же, что у титула страницы: строки
   стоят готовыми, кадр приходит из размытия по остановке. Поэтому
   внутренние элементы несут классы титула, а раскладка кадра общая. */
.descent-exit { position: relative; height: var(--screen); background: var(--black); }
.descent-exit__stage { z-index: 1; }

/* Строки и кнопка стоят одним блоком НАД подписью, по общей раскладке
   кадра: не подпись убегает в другой угол, а копия поднимается.       */
.descent-exit__copy {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  bottom: var(--frame-copy);
  z-index: 4;
}
.descent-exit__lines { margin-bottom: clamp(26px, 4vh, 44px); }

/* КАЖДАЯ ФРАЗА — ОДНА СТРОКА, ТРИ ФРАЗЫ — ТРИ СТРОКИ. Мера в 20ch
   ломала среднюю фразу надвое, и вместо трёх ступеней получалось
   четыре куска. Меру снимаем, перенос запрещаем.

   Кегль здесь СВОЙ, на ступень ниже Д3: самая длинная фраза
   «Но жалко отдать обиду.» — 22 знака, и на 390px в Д3 она за край
   не помещается. Это единственное исключение из шкалы на сайте, и
   держится оно на измерении, а не на глаз (прогон меряет перенос). */
.descent-exit__line {
  font-family: var(--display);
  font-size: clamp(24px, 4.2vw, 56px);
  line-height: 1.24;
  white-space: nowrap;
  color: var(--on-frame);
}

/* СТРОКИ СТОЯТ ГОТОВЫМИ, приходит кадр: приём инвертирован, и роли в нём
   переставлены, а не удвоены (§6.2). Лесенка, которой строки приходили
   на бумаге, снята вместе с бумагой — двух проявлений на одном экране
   не бывает.                                                          */

/* ПОСЛЕДНЯЯ ФРАЗА — НЕ ВЫВОД, А ЖЕСТ. Две первые рассуждают, третья
   зовёт, и голос у неё тот же, что у экранов спуска: Д1. Спуск говорил
   Д1 — выход отвечает тем же кеглем, а не вполовину тише.            */
.descent-exit__line:last-child { font-size: var(--h-descent); }

/* ── Проявление текста (док. 01 §6) ──────────────────────────────────────
   ОДИН ПРИЁМ НА ВСЕ СМЫСЛОВЫЕ ДИСПЛЕЙНЫЕ СТРОКИ: проступание из
   размытия со сдвигом. Раньше у каждой строки была своя механика — у
   спуска блюр, у выхода только сдвиг, у пластины голая прозрачность, у
   финальной строки не было ничего.

   Включает строки JS и только НА ОСТАНОВКЕ: если включать по видимости,
   проявление отыгрывает, пока экран ещё едет, и читатель приходит на
   готовое.

   --d — задержка строки, --dur — её длительность.                     */

.descent__line,
.descent__sub,
.frame__line,
.quote-frame {
  --d: 0ms;
  --dur: var(--reveal);
  opacity: 0;
  filter: blur(12px);
  transform: translateY(16px);
}

/* Ступени лесенки считаются от токена: в разметке чисел про время нет. */
.descent__line:nth-child(2) { --d: var(--reveal-step); }
.descent__line:nth-child(3) { --d: calc(var(--reveal-step) * 2); }

/* Подпись приходит ПОСЛЕДНЕЙ: стартует позже последней строки экрана и
   заканчивается вместе с ней. Номер последней строки объявляет шаблон —
   это признак структуры, а не времени.                                */
.descent__screen { --last-line: 0; }
.descent__sub {
  --d: calc(var(--last-line) * var(--reveal-step) + var(--sub-lag));
  --dur: var(--sub-reveal);
}

.descent__screen.is-on .descent__line,
.descent__screen.is-on .descent__sub,
.frame__line.is-on,
.quote-frame.is-on {
  opacity: 1;
  filter: blur(0);
  transform: none;
  transition: opacity var(--dur) var(--d),
              filter var(--dur) var(--d),
              transform var(--dur) var(--d);
}

/* Подпись держит свою приглушённость, она не выходит на первый план. */
.descent__screen.is-on .descent__sub { opacity: .72; }

/* ПАМЯТИ О ПОКАЗЕ НЕТ (Р-34). Прежнее правило «повтора нет» — строка при
   возврате стояла готовой, за это отвечал класс is-seen — отменено.
   Довод «материализация есть довод, а не украшение» верен для страницы,
   которую читают один раз линейно, но вместе с уходом строки он давал
   то, чего никто не проектировал: вернувшийся на кадр видел фотографию
   без единого слова и не понимал, к чему она. Из двух правил уступило
   то, которое работает против фотографии.

   УХОД СТРОКИ. Тот же приём наоборот и медленно: фотография — аргумент,
   и ей полагается момент без букв. Колонтитул и подпись остаются, экран
   не пустеет — он очищается до кадра. Уходить строка обязана переходом,
   иначе исчезновение читается как сбой рендера (док. 01 §6.0).

   Это уход ПО ВРЕМЕНИ. Уход под пальцем переходом быть не может — он
   идёт со скоростью руки, и значения ему ставит JS инлайном.         */
.frame__line.is-gone,
.quote-frame.is-gone {
  opacity: 0;
  filter: blur(12px);
  transform: translateY(16px);
  transition: opacity var(--depart),
              filter var(--depart),
              transform var(--depart);
}

/* ── Перечисления ───────────────────────────────────────────────────────
   Маркированные списки буллетами запрещены (док. 01 §8).

   ВОЛОСЯНЫХ ВНУТРИ ПЕРЕЧНЯ БОЛЬШЕ НЕТ — правило владельца от 21 сентября
   2026 года распространено с конспектов на открытый сайт. Если волосяная
   отделяет один блок от другого, то внутри блока волосяных нет: иначе
   одна и та же линия значит на странице две разные вещи, и читателю
   приходится догадываться по окружению, где кончился раздел, а где
   кончился пункт.

   Прежнее правило §8 — «линейки только между, n пунктов → n−1 линеек» —
   этим отменено. Оно было верной поправкой к ещё более раннему (список,
   замкнутый линейкой сверху и снизу, — рамка, а рамки §8 запрещает), но
   лечило следствие: линия не должна была стоять внутри перечня вовсе.

   ЗАМЕНЯЕТ ЛИНЕЙКУ ВТЯЖКА — та же, что в конспекте: перечень отступает
   от левого края ровно на ширину номерного жёлоба, 2.6em плюс 12px, и
   стоит так независимо от того, есть в жёлобе номер или нет. Величина
   взята у конспекта не для экономии, а ради одной левой по всему
   изданию: нумерованный перечень, ненумерованный и цитата в тексте
   начинаются с одного пикселя, и читатель узнаёт «отдельный ход речи»
   по одному признаку, а не по трём похожим.

   ЖЁЛОБ СУЗИЛСЯ С 3.2em ДО 2.6em. Прежняя колонка держала номер в
   потоке сетки и нуждалась в запасе на разрядку моно; теперь номер
   вынут из потока и висит в жёлобе абсолютом — «01» на 11px занимает
   там около 16px из 61px. Запас был на воздух, а воздух у втяжки и так
   есть.

   НУМЕРУЮТСЯ ПОСЛЕДОВАТЕЛЬНОСТИ, НЕ ПЕРЕЧНИ: номер обещает порядок, и
   там, где порядка нет, он обещает несуществующее. Но жёлоб теперь
   держит не номер, а сам перечень, — поэтому ненумерованный список
   втяжку не теряет и встаёт по той же левой, что нумерованный.
   Прежний довод «колонку под номер в таком списке не держим, иначе
   текст стоит с отступом ни от чего» этим отменён.                    */

/* СЕТКИ НА ПУНКТЕ НЕТ — по тому же разбору, что в конспекте. Пункт был
   display:grid в две колонки, и колонки раздавались его детям по
   очереди: появись внутри пункта второй элемент кроме номера и текста —
   абзац рассыпался бы лесенкой. Номер вынут из потока в жёлоб, разметка
   внутри пункта после этого может быть любой.                          */
.numbered__item {
  position: relative;
  padding: 0 0 0 calc(2.6em + 12px);
}

/* ВОЗДУХ МЕЖДУ ПУНКТАМИ — ПОЛТОРА ПРЕЖНИХ ПОЛУИНТЕРВАЛА, а не два.
   Прежде между пунктами стояло 2× padding, разрезанное линейкой
   пополам: два полуинтервала читались порознь. Без линейки они
   сливаются в один, и сумма прежних двух читалась бы провалом —
   перечень рассыпался бы на отдельные абзацы. Полтора полуинтервала
   отделяют пункт от пункта и оставляют его пунктом.                   */
.numbered__item + .numbered__item { margin-top: clamp(30px, 4.5vh, 45px); }

/* ПЕРЕЧЕНЬ СОБРАН ПО ВЫСОТЕ (решение владельца). «Кому не подойдёт»
   должно встать в один экран целиком: список делился на две полосы
   только потому, что не помещался. Один пункт снят автором, осталось
   шесть — и недостающее берётся отсюда, из воздуха вокруг волосяных.
   Сокращение ОДИНАКОВОЕ сверху и снизу от линейки: ритм перечня
   держится их равенством, а не абсолютной величиной.

   Только перечни (--plain). Нумерованная последовательность — программа
   тренинга — своего ритма не отдаёт: она длиннее экрана по устройству,
   и сжимать её не за чем.                                            */
.numbered__list--plain .numbered__item + .numbered__item {
  margin-top: clamp(17px, 2.6vh, 30px);
}

/* Номер висит в жёлобе абсолютом. Строка номера приравнена к строке
   корпуса: моно 11px иначе встал бы выше первой строки пункта на
   разницу интерлиньяжей (у пункта 1.5).                               */
.numbered__n {
  position: absolute;
  left: 0;
  top: 0;
  color: var(--ink-soft);
  line-height: calc(var(--t-body) * 1.5);
}
/* ПУНКТ ПЕРЕЧНЯ НАБИРАЕТСЯ КОРПУСОМ. Прежде здесь стоял Р1 полужирным
   (Р-41, «пункты называют позицию, а не читаются абзацем») — на экране
   это оказалось неверно: пункты «Кому не подойдёт» именно читаются, по
   две-три строки каждый, и укрупнённое полужирное начертание делало из
   перечня семь маленьких заголовков. Крупнее корпуса на полосе только
   вход в главу, и второго дисплейного уровня перечню не нужно.
   Р-41 в этой части отменён владельцем по живому кадру.

   Побочная выгода, ради которой правка и затевалась: на корпусном
   кегле пункты занимают меньше места, и глава делится на два экрана
   без обрыва посреди пункта. */
.numbered__text { display: block; max-width: 52ch; line-height: 1.5; }

.numbered__sub-title { margin-top: clamp(40px, 6vh, 70px); color: var(--ink-soft); }
.numbered__list--sub { margin-top: 14px; }

/* Группы перечня (страница клуба). Подзаголовок группы — та же моно-
   подпись, что «Например»; воздух над ней меньше, чем над «Например»:
   там подпись отделяет второй перечень от первого, здесь группы — части
   одного. На широком экране — две колонки, группы по строкам сетки,
   чтобы месяцы шли слева направо, как читают. */
.numbered__groups .numbered__sub-title { margin-top: clamp(26px, 4vh, 44px); }
.numbered__groups .numbered__group:first-child .numbered__sub-title { margin-top: 0; }
/* Темы встреч — однострочные, и воздух перечня, рассчитанный на пункты
   в две-три строки, растянул бы тридцать две строки на три экрана. */
.numbered__groups .numbered__item + .numbered__item { margin-top: clamp(8px, 1.3vh, 14px); }
@media (min-width: 900px) {
  .numbered__groups {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 clamp(40px, 5vw, 96px);
    max-width: 1100px;
  }
  .numbered__groups .numbered__group:nth-child(2) .numbered__sub-title { margin-top: 0; }
}
.numbered__after { margin-top: clamp(34px, 5vh, 56px); font-size: var(--t-lead); max-width: 44ch; }

/* ── Отзывы ─────────────────────────────────────────────────────────────
   Без карточек, кавычек, рамок и портретов. Узкая колонка, мера 52ch.
   Между отзывами только воздух, без разделителей (док. 02 §6).          */

.review { max-width: 52ch; }
.review + .review { margin-top: clamp(54px, 9vh, 100px); }
.review__author { margin-top: 16px; color: var(--ink-soft); }
.reviews__note { margin-top: clamp(40px, 6vh, 64px); }

/* ── Предложения ────────────────────────────────────────────────────────
   Карточек, рамок и плашек нет: текст и волосяные линейки.              */

/* Идущие подряд предложения (витрина тренингов) отбиваются волосяной
   линейкой — так это читается перечнем, а не набором карточек.         */
.offer + .offer { border-top: 1px solid var(--hairline); }
/* Объявление своим экраном (поле alone) — не пункт перечня: линейки нет
   ни над ним, ни над следующим предложением, которое после отдельной
   полосы начинает перечень заново. */
.offer + .offer--alone,
.offer--alone + .offer { border-top: 0; }

.offer__eyebrow { color: var(--ink-soft); margin-bottom: 16px; }
.offer__option-title { font-weight: 500; margin-bottom: .6em; }
.offer__meta { margin-top: 16px; color: var(--ink-soft); }

/* ФОРМАТЫ БЕЗ ВОЛОСЯНОЙ. Приём пришёл из демо 3, вариант В (решение
   владельца по «Консультациям»): разделителя между вариантами нет,
   работу линейки берут на себя тяжёлая первая строка и удвоенный
   воздух. Тогда он был записан как частный — «на витрину тренингов не
   распространяется, там вариантов четыре и они идут перечнем, здесь их
   два и они противопоставлены». Правилом «внутри блока волосяных нет»
   (21 сентября 2026) эта оговорка снята: варианты живут внутри одного
   предложения, и линия между ними значила бы ровно то же, что линия
   между предложениями, — границу блока.

   Заодно уходит то, чего §8 не допускал и по букве: у последнего
   варианта стояла нижняя линейка, то есть набор был замкнут рамкой.
   На «Психосоматике для самостоятельной работы» вариант один — рамка
   обводила его целиком.

   Разделяет варианты теперь только воздух, тот самый удвоенный
   интервал демо 3. Он больше прежнего (26–42px на сторону от линейки,
   то есть 52–84px между) — и это верно: без линии интервал обязан
   читаться границей сам, а не помогать ей.

   Модификатор --plain после этого управляет только видом меты
   (.offer__meta--flat) и остаётся в разметке ради неё.                 */
.offer__option + .offer__option,
.btn--far { margin-top: clamp(38px, 6vh, 54px); }

/* Мета формата — роль «подпись», а не «служебное»: цену и порядок записи
   читают, а не сканируют. Полный цвет чернил: это последнее, что человек
   читает перед кнопкой.                                                */
.offer__meta--flat {
  font-size: var(--doc-caption);
  letter-spacing: var(--doc-caption-ls);
  text-transform: none;
  color: var(--ink);
}
/* ВОЗДУХ СОБРАН (задание 7 §5.4): третья полоса «Откуда это взялось»
   должна поместить абзац, ссылку на запись и все три «Материала» в
   один экран — воздух между ними был самым большим интервалом полосы. */
.offer__note { margin-top: clamp(13px, 2vh, 20px); }
.offer__links-title { margin-top: clamp(15px, 2.2vh, 28px); color: var(--ink-soft); }

/* «ОТКРЫТЫЕ МАТЕРИАЛЫ» ЧИТАЛИСЬ СИРОТЛИВО (замечание владельца).
   Раздел стоит последним на витрине и состоит из заголовка, подменю и
   трёх ссылок — корпусным кеглем это хвост, а не тело полосы, и под ним
   оставалась половина пустого экрана.

   Лечится не воздухом, а весом: строки берут ступень Р1 и полусветлое
   начертание — ту же пару, что имя формата на «Консультациях». Три
   строки становятся содержанием полосы. Шаг между ними растёт следом,
   иначе тяжёлые строки слипаются; 44px на цель касания он перекрывает
   с запасом, и невидимый хитбокс ниже остаётся на месте — вреда от
   него нет.                                                            */
.offer__links {
  display: flex;
  flex-direction: column;
  margin-top: clamp(16px, 2.2vh, 22px);
  /* Шаг сбавлен обратно (решение владельца, 19 сентября): полосу теперь
     держит содержание — шесть плейлистов и отдельное видео, — а не
     воздух. На прежних 34px семь тяжёлых строк с двумя подменю в экран
     телефона не помещались.

     Нижняя граница не произвольна: строка Р1 в минимуме даёт 19×1,55 ≈
     29px, и шаг 17px складывает шаг строки 46px — на два пикселя больше
     хитбокса 44px, то есть соседние цели касания не налезают друг на
     друга.                                                             */
  gap: clamp(17px, 2.2vh, 22px);
}
/* ПОДЧЁРКИВАНИЕ ЧЕРНИЛЬНОЕ, А НЕ ЭГЕЙСКОЕ (решение владельца, частная
   отмена §6.7). Ссылки внутри текста эгейские потому, что их надо найти
   среди строк; здесь строка и есть ссылка — искать нечего, и голубая
   волосяная на трёх строках подряд превращается в блок цвета.
   Промежуток 7px тесноват для трёх целей касания подряд — строки
   получают свои 44px невидимым хитбоксом, тем же приёмом, что каналы
   в колофоне.                                                          */
.offer__links a {
  position: relative;
  font-size: var(--t-lead);
  font-weight: 500;
  text-decoration-color: var(--hairline);
}
.offer__links a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 44px;
  transform: translateY(-50%);
}

/* ── Вопросы и ответы ───────────────────────────────────────────────────
   Аккордеонов и табов нет (док. 01 §8): обычный текст.                  */

.faq__item { max-width: var(--measure); }
.faq__item + .faq__item { margin-top: clamp(38px, 6vh, 64px); }
.faq__q { font-weight: 500; margin-bottom: .5em; }

/* ── Аудиофрагмент ──────────────────────────────────────────────────────
   Не плеер с обложкой, а строка слоем «Документ» с треугольником.
   Автовоспроизведения нет (док. 02 §4).                                 */

.audio { padding-top: 0; }

/* СВЯЗКА ДЕРЖИТ ОДНУ ОТБИВКУ, А НЕ ДВЕ. Аудиострока продолжает главу,
   а не начинает новую, поэтому нижний воздух главы внутри связки снят:
   отбивка снизу остаётся одна, у самой строки. Иначе связка перерастает
   экран, снап ставит в верх её верх — и строки, ради которой всё
   затевалось, читатель не видит (док. 01 §4). Меряется в прогоне.     */
.group > .chapter { padding-bottom: 0; }

/* Воздух между главой и строкой остаётся — но как отбивка внутри
   связки, а не как конец секции: он вдвое меньше --section. Низ связки
   тоже не берёт полный --section (Р-44): после подъёма шкалы Д2 связка
   «Развилка + строка» перестала помещаться в экран на 390px на 10px. */
.group > .audio {
  padding-top: clamp(30px, 4.5vh, 52px);
  padding-bottom: clamp(40px, 6vh, 80px);
}

/* СВЯЗКА НЕ КОРОЧЕ ЭКРАНА (Р-53). Связка — точка снапа сама по себе
   (main > *), и если её бокс ниже экрана, снап всё равно ставит в её
   верх, а низ следующей главы оказывается виден тем же кадром — вход
   в главу, которую читатель ещё не начал, показанный чужим экраном.
   После второго уполовинивания воздуха (Р-57) связка «Развилка» стала
   короче экрана и течь начала показывать; --screen страхует бокс
   снизу тем же измерением, что и полноэкранные сцены. */
.group { min-height: var(--screen); }

/* Строка длинная и на 390px переносится. Перенос идёт от левого края,
   а не по центру: это строка издания, а не подпись под кнопкой.      */
.audio__trigger { text-align: left; }
.audio__row { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }

.audio__trigger {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  background: none;
  border: 0;
  padding: 0;
  color: var(--ink-soft);
  font: inherit;
  font-family: var(--doc);
  cursor: pointer;
}
.audio__trigger:hover { color: var(--ink); }

.audio__bar { position: relative; flex: 1 1 160px; max-width: 320px; height: 1px; background: var(--hairline); }
.audio__bar[hidden] { display: none; }
.audio__progress { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--ink); }

/* ── Конспект встречи и оглавление материалов ────────────────────────────
   Скрытые страницы после оплаты. Здесь единственный на сайте длинный
   текст: полторы тысячи слов подряд вместо полосы с кадром. Набирается
   теми же тремя гарнитурами и той же лестницей кеглей — иначе это был бы
   другой сайт за той же дверью.

   ЖЁСТКИЙ ШАГ НЕ ЛОМАЕТСЯ. Секция выше экрана по правилу сплошного
   покрытия (док. 01 §4) из точки становится диапазоном: внутри
   останавливаются где угодно, флинг встаёт на её верхе. Поэтому
   .longread — единственная бумажная секция без min-height: экрана она
   не короче никогда.                                                    */

.longread__body { max-width: var(--measure); }

/* ЗАГОЛОВОК РАЗДЕЛА — ЛИНЕЙКА, ПОД НЕЙ ИМЯ (док. 01 §6.6).
   Прежде разделы были отбиты одним воздухом, и владелец увидел то, что
   из этого следует: законченный блок не отделялся от соседнего, а узел
   Golos 500 на Р1 над корпусом Р2 — это 19px над 17px, разница, которой
   читатель не видит. Кегль при этом поднять нельзя: узел — третий
   уровень иерархии, и ступени у него своей нет (§3).

   Поэтому отделяет не кегль, а конструкция: волосяная во всю меру, под
   ней имя раздела. Это колонтитул издания — то самое, что превращает
   страницу в полосу, — и в конспекте он появляется там же, где на
   остальном сайте: в начале каждой смысловой главы.

   ЛИНИЯ ЧЕРНИЛЬНАЯ, НЕ ЭГЕЙСКАЯ. Эгейская линейка стоит на кадре, под
   маркой и под ссылками — там она помечает принадлежность и
   кликабельное. Здесь линия делит текст, и материал у неё тот же, что у
   разделителей перечня и у полосы-продолжения (§5).

   ВОЗДУХ НЕСИММЕТРИЧЕН. Над линией — отбивка раздела, под линией —
   поле колонтитула, под именем — начало текста. Заголовок принадлежит
   тому, что под ним, и стоит к нему ближе, чем к тому, что над.       */
.lr__part + .lr__part { margin-top: clamp(46px, 6.5vh, 84px); }

.lr__node, .lr__stage {
  border-top: 1px solid var(--hairline);
  padding-top: clamp(20px, 2.8vh, 30px);
}

/* Узел — третий уровень (док. 01 §3): Golos 500 на Р1. Prata на третьем
   уровне запрещена без исключений, и это тот самый случай, ради
   которого запрет писался: h2 в конспекте пятнадцать на документ, и
   дисплеем они превратили бы чтение в пролистывание заголовков.       */
.lr__node {
  font-family: var(--speech);
  font-weight: 500;
  font-size: var(--t-lead);
  line-height: 1.35;
  text-wrap: balance;
  margin: 0 0 .85em;
}

/* НОМЕР АВТОРА СТОИТ МОНО И В СВОЮ СТРОКУ. «Шаг 1», «Часть 2», «Ключ 3»,
   «Встреча 4» — авторская нумерация конспекта; в строке заголовка она
   съедала начало имени, а на 390px ещё и уводила его на вторую строку.
   Вынесена в объявление над именем — ровно так же, как «Встреча 1»
   стоит над заглавием страницы. Словами номер не повторяется.

   Своей колонкой слева, как в перечнях, номер не ставится: колонка
   стоит 2.6em, а на 390px мера и без того 339px, и заголовок в три
   строки потерял бы восьмую часть ширины ни за что.                   */
.lr__num {
  display: block;
  margin-bottom: .7em;
}

/* ВЕХА КУРСА — ЗАГОЛОВОК ДОКУМЕНТНЫМ СЛОЕМ ЦЕЛИКОМ.
   «Резюме предыдущих встреч», «Новый материал», «Выводы», «Челлендж»,
   «Техника выполнения», «Вопрос» — пятнадцать штук на одиннадцать
   конспектов. Они называют не тему, а место в занятии, и повторяются
   из встречи во встречу. Набранные речью наравне с «Что такое обида?»,
   они обещали новую тему там, где её нет.

   Речевого заголовка у вехи нет: заголовок и есть колонтитул — так же,
   как у главы «Кому не подойдёт» на открытом сайте (§5).             */
.lr__stage {
  line-height: 1.5;
  text-wrap: balance;
  margin: 0 0 clamp(16px, 2.2vh, 22px);
}

/* Подраздел — четвёртый уровень, метка. Роль «подпись»: её читают.    */
.lr__mark { margin: clamp(26px, 3.6vh, 40px) 0 .6em; color: var(--ink-soft); }

.lr__p { margin: 0; }
.lr__p + .lr__p { margin-top: 1.1em; }

/* ЦЕПОЧКА со стрелками (встреча 5). Документным слоем, с переносом по
   словам: на 390px четыре звена в строку не встают, а горизонтальной
   прокрутки на сайте нет.                                             */
.lr__chain {
  margin: clamp(24px, 3.2vh, 34px) 0;
  color: var(--ink-soft);
  line-height: 1.75;
  white-space: normal;
}

/* АКЦЕНТ НАБИРАЕТСЯ НАЧЕРТАНИЕМ, НЕ НАКЛОНОМ. Курсива у Golos Text в
   проекте нет — браузер синтезировал бы его наклоном прямого, то есть
   подделкой (док. 01 §3, правило писалось про Prata, но подделка
   остаётся подделкой). Поэтому em и strong дают одно и то же: Golos
   500. Полужирного 700 в проекте тоже нет.                            */
.longread__body :is(strong, em) { font-weight: 500; font-style: normal; }

/* Многоабзацная цитата. Сама цитата — общий объект сайта (.quote,
   Р-45), и переопределять её здесь нечего; но в главах она стоит
   двумя-тремя строками, а в конспекте бывает притчей на шесть абзацев,
   и между ними нужен воздух.                                          */
.longread .quote__line + .quote__line { margin-top: .8em; }

/* ПЕРЕЧИСЛЕНИЯ В КОНСПЕКТЕ — ВТЯЖКА, А НЕ ЛИНЕЙКИ (решение владельца,
   21 сентября 2026).

   Правило владельца: если волосяная отделяет один блок от другого, то
   внутри блока волосяных нет. Иначе одна и та же линия значит на
   странице две разные вещи, и читателю приходится догадываться по
   окружению, где кончился раздел, а где кончился пункт.

   В конспекте линия теперь открывает раздел — значит, из перечней она
   уходит вся: и из нумерованных, где номер и так называет пункт, и из
   ненумерованных, где её нечем заменить впрямую.

   Заменяет её втяжка. Перечень отступает от левого края ровно на
   ширину номерного жёлоба — 2.6em плюс 12px, — и стоит так независимо
   от того, есть в жёлобе номер или нет. Втяжка — уже принятый на сайте
   способ сказать «это отдельный ход речи»: ею стоит цитата (§«Цитата в
   тексте»). Два перечня, с номерами и без, встают при этом по одной
   левой, то есть читаются одним объектом.

   Прежний довод — «ненумерованный список колонку под номер не держит,
   текст стоял бы с отступом ни от чего» — отменён: жёлоб держит не
   номер, а сам перечень.

   Открытого сайта это пока не касается: там перечень набран по док. 01
   §8 линейками, и менять его — отдельный разговор с владельцем.     */
.lr__list {
  list-style: none;
  margin: clamp(26px, 3.6vh, 40px) 0;
  padding: 0;
  counter-reset: lr;
}
.lr__item {
  position: relative;
  padding: 0 0 0 calc(2.6em + 12px);
  border-top: 0;
}
.lr__item + .lr__item { margin-top: clamp(14px, 2vh, 20px); }

.lr__list--num > .lr__item { counter-increment: lr; }

/* СЕТКИ НА ПУНКТЕ БОЛЬШЕ НЕТ, И ЭТО ИСПРАВЛЕНИЕ, А НЕ ВКУС.
   Пункт был display:grid в две колонки, и колонки раздавались его
   детям по очереди. Пока пункт был сплошным текстом, детей было двое —
   номер и текст, — и всё сходилось. Но в пункте бывает <strong>: тогда
   выделенное начало уходит во вторую колонку, остаток текста падает в
   первую, следующий кусок — снова во вторую, и абзац рассыпается на
   лесенку шириной в два слова. Ровно это владелец увидел в «Какова цель
   моей жизни» (встреча 1) и на телефоне, и на широком экране.

   Номер вынут из потока в жёлоб втяжки — тогда разметка внутри пункта
   может быть любой.                                                   */
.lr__list--num > .lr__item::before {
  content: counter(lr, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0;
  font-family: var(--doc);
  font-size: 11px;
  letter-spacing: var(--doc-folio-ls);
  color: var(--ink-soft);
  /* Строка номера равна строке корпуса: моно 11px иначе встал бы выше
     первой строки пункта на разницу интерлиньяжей.                    */
  line-height: calc(var(--t-body) * 1.62);
}

/* Вложенный список второй втяжки на всю ширину жёлоба не берёт: он
   часть своего пункта, а не отдельный перечень, и уходит вправо на
   один шаг — ровно столько, чтобы было видно подчинение.              */
.lr__list--sub { margin: .7em 0 0; padding-left: 0; }
.lr__list--sub > .lr__item { padding-left: 1.2em; }
.lr__list--sub > .lr__item + .lr__item { margin-top: .45em; }

/* ── ТАБЛИЦА КОНСПЕКТА ─────────────────────────────────────────────────
   Пришла с тренингом 2019: карта конфликтов опорно-двигательного
   аппарата — шестнадцать строк соответствий, и перечнем её не заменить.

   ЛИНЕЕК ВНУТРИ НЕТ. Правило «внутри блока волосяных нет» (док. 01 §8)
   действует и здесь: строки таблицы разделены воздухом, ровно тем же,
   что отбивает пункты перечня. Линейка значит границу блока, а строки
   таблицы — не блоки.

   Шапка набирается документным слоем: она называет столбцы, а не ведёт
   речь (§3, §5).

   НА ТЕЛЕФОНЕ ТАБЛИЦЫ НЕТ. Две колонки с длинным текстом на 390px дают
   либо поперечную прокрутку, либо столбец шириной в два слова; и то и
   другое запрещено. Поэтому базовая раскладка — строками: ячейки идут
   сверху вниз, первая служит заголовком строки. Там, где столбцов
   больше двух и по первой ячейке остальные не опознать, у каждой
   печатается имя её столбца — импорт кладёт его в data-th.

   Шапка при этом не выбрасывается, а убирается с глаз: экранной
   читалке она нужна, глазу — нет, имя столбца уже стоит у ячейки.   */
.lr__table {
  width: 100%;
  margin: clamp(26px, 3.6vh, 40px) 0;
  border-collapse: collapse;
  text-align: left;
}
.lr__table, .lr__table thead, .lr__table tbody, .lr__tr, .lr__th, .lr__td {
  display: block;
}
.lr__table thead {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}
.lr__tr + .lr__tr { margin-top: clamp(18px, 2.6vh, 26px); }

.lr__td { padding: 0; }

/* Заголовок строки — первая ячейка. Остальные уходят на шаг вправо:
   столько, чтобы было видно подчинение, и не больше (ср. lr__list--sub). */
.lr__tr > .lr__td:first-child { color: var(--ink); }
.lr__tr > .lr__td + .lr__td {
  margin-top: .45em;
  padding-left: 1.2em;
}

.lr__table--wide .lr__td::before {
  content: attr(data-th);
  display: block;
  margin-bottom: .2em;
  font-family: var(--doc);
  font-size: 11px;
  letter-spacing: var(--doc-folio-ls);
  color: var(--ink-soft);
}

@media (min-width: 900px) {
  .lr__table, .lr__table thead, .lr__table tbody { display: table; }
  .lr__table thead { display: table-header-group; position: static; width: auto; height: auto; clip-path: none; }
  .lr__table tbody { display: table-row-group; }
  .lr__tr { display: table-row; }
  .lr__th, .lr__td { display: table-cell; vertical-align: baseline; }

  .lr__tr + .lr__tr { margin-top: 0; }
  .lr__table--wide .lr__td::before { content: none; }

  .lr__th {
    padding: 0 clamp(16px, 2vw, 28px) 1em 0;
    font-family: var(--doc);
    font-size: 11px;
    font-weight: 400;
    letter-spacing: var(--doc-folio-ls);
    color: var(--ink-soft);
  }
  .lr__td {
    padding: 0 clamp(16px, 2vw, 28px) clamp(14px, 2vh, 20px) 0;
  }
  .lr__tr > .lr__td + .lr__td { margin-top: 0; padding-left: 0; }
  .lr__tr > *:last-child { padding-right: 0; }

  /* Столбец соответствия держит свою долю: без этого «Локализация»
     разъезжается под ширину самой длинной формулировки конфликта. */
  .lr__table:not(.lr__table--wide) .lr__tr > *:first-child { width: 32%; }
}

/* ── Подвал конспекта ──────────────────────────────────────────────────
   Три ссылки одного класса, и вид у них один (замечание владельца).
   Прежде «Дальше — встреча 2» была набрана речью с эгейским
   подчёркиванием, а «Все материалы» — моно и без подчёркивания; одна
   работа выглядела двумя разными.

   Работа у всех трёх служебная: ими пользуются, а не читают их (§5), —
   отсюда моно, капс и приглушённый цвет. Подчёркивание эгейской
   волосяной стоит под каждой, потому что на бумаге оно и значит
   «ссылка» (§6.7).

   «Предыдущая» стоит перед «дальше»: порядок — ход чтения, а не
   важность. «Все материалы» ничем не выделена — ни цветом, ни лишним
   воздухом (Р-125). Довод прежнего
   выделения — «она выходит из последовательности» — верен по смыслу, но
   на экране читался как разная важность: три служебные ссылки подряд,
   и одна из них тусклее прочих.                                       */
.longread__nav {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(12px, 1.8vh, 16px);
  margin-top: clamp(52px, 7.5vh, 92px);
  padding-top: clamp(20px, 3vh, 30px);
  border-top: 1px solid var(--hairline);
  max-width: var(--measure);
}
.longread__step {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .35em;
  text-decoration-color: var(--hairline-aegean);
}

/* ── Оглавление конспекта в поле (широкий экран) ───────────────────────
   Широкий экран под конспектом пуст: мера набора остаётся мерой, и
   сбоку стоит поле шириной с полосу. Владелец предлагал положить туда
   кадр. Кадр был бы один и тот же на одиннадцати страницах и повторял
   бы титул, мимо которого читатель только что прошёл; оглавление на две
   тысячи слов работает всё время, пока он читает.

   Это аппарат поля, а не второй столбец текста: моно ролью «подпись»
   (её читают), приглушённо, без линеек между пунктами. Текущий узел
   помечен коротким эгейским штрихом — тем же указателем «вы здесь», что
   в оглавлении сайта (Р-51). Приглушение для этой роли не годится: им
   в оглавлении помечено обратное.

   Имя узла длиннее двух строк обрезается. Оглавление — указатель, а не
   копия текста: в конспектах есть заголовки на сто знаков, и полностью
   набранные, они превратили бы поле во вторую полосу.                 */
.lr__toc { display: none; }

@media (min-width: 1000px) {
  /* Связка «поле + полоса» стоит посреди экрана, а не у левого края.
     На остальных страницах сайта текст прижат влево, и пустое поле
     справа — их обычная раскладка. Здесь слева встал аппарат, и та же
     прижимка увела бы всю страницу в левую треть: полоса кончалась бы
     на 867-м пикселе из 1440. Группа целиком берёт свою ширину —
     аппарат плюс мера — и центрируется; мера набора при этом не
     меняется ни на знак.                                              */
  .longread {
    display: grid;
    grid-template-columns: minmax(180px, 230px) minmax(0, 1fr);
    column-gap: clamp(36px, 4.5vw, 72px);
    align-items: start;
    /* Поля секции входят в ширину: box-sizing у всего сайта border-box,
       и без них мера потеряла бы ровно два поля.                      */
    max-width: calc(230px + clamp(36px, 4.5vw, 72px) + var(--measure) + var(--pad) * 2);
    margin-inline: auto;
  }

  /* Перечень частей на широком раскрыт всегда: свёртка — приём тесноты,
     а здесь места вдоволь. Атрибут open ставит site.js, чтобы экранная
     читалка не звала раскрытым то, что она считает закрытым.          */
  .lr__zapis-head { cursor: default; }
  .lr__zapis-head::after { content: none; }

  .lr__toc {
    display: block;
    position: sticky;
    top: var(--top-line);
    max-height: calc(100vh - var(--top-line) * 2);
    overflow-y: auto;
    /* Полоса прокрутки в поле — деталь чужой системы; аппарат короче
       экрана почти всегда, а страховка нужна на самый длинный конспект. */
    scrollbar-width: none;
  }
  .lr__toc::-webkit-scrollbar { display: none; }

  .lr__toc-head {
    color: var(--ink);
    padding-left: 24px;
    padding-bottom: clamp(10px, 1.4vh, 14px);
    border-bottom: 1px solid var(--hairline);
    margin-bottom: clamp(14px, 2vh, 20px);
  }

  /* Полоска указателя стоит в левом жёлобе списка, а не снаружи него:
     аппарат прокручивается сам (overflow-y), а прокрутка по вертикали
     режет и по горизонтали — штрих за краем был бы срезан.            */
  .lr__toc-list { list-style: none; margin: 0; padding: 0 0 0 24px; }
  .lr__toc-item { position: relative; }
  .lr__toc-item + .lr__toc-item { margin-top: .9em; }

  .lr__toc-item a {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-family: var(--doc);
    font-size: var(--doc-caption);
    letter-spacing: var(--doc-caption-ls);
    line-height: 1.45;
    color: var(--ink-soft);
    text-decoration: none;
  }
  .lr__toc-item a:hover { color: var(--ink); }

  .lr__toc-item a[aria-current] { color: var(--ink); }
  .lr__toc-item a[aria-current]::before {
    content: '';
    position: absolute;
    left: -24px;
    top: .62em;
    width: 14px;
    height: 1px;
    background: var(--aegean);
  }
}

/* ── Запись встречи: перечень частей и пометки по разделам ─────────────
   Р-118. Прежде запись стояла столбиком плееров между заглавием и первой
   строкой текста: на телефоне — стена чужих проигрывателей, за ней стена
   конспекта, и полтора десятка мегабайтов до первого слова.

   Теперь запись — аппарат. В начале документа стоит перечень частей
   (на телефоне свёрнутый), а сами части разложены пометками у тех
   разделов, о которых они. Плеер заводится по нажатию и всегда один.

   ПОМЕТКА ГОВОРИТ «ОБ ЭТОМ — ЧАСТЬ N», А НЕ «ЧАСТЬ N». Конспект выстроен
   логически, а говорилось вразброс: у второго дня части 7, 8, 9 стоят
   у разделов 11, 9 и 10. Это ссылка на место в записи, а не плейлист, и
   называться она должна так, чтобы порядок не обещался.

   Голубой здесь красит только линии — подчёркивание ссылок (док. 01 §2);
   указатель перечня чернильный приглушённый.                          */

.lr__zapis-blok {
  max-width: var(--measure);
  margin-bottom: clamp(30px, 4.5vh, 52px);
}

.lr__zapis {
  border-top: 1px solid var(--hairline);
  padding-top: clamp(12px, 1.8vh, 16px);
}

/* ── Плита первой части ────────────────────────────────────────────────
   Запись видна, а не только названа (Р-123). Перечень частей — строки;
   плита ставит первую часть на вид.

   Это обложка с ютуба, а не живой плеер: разница только в весе, на вид
   она та же. По нажатию на её месте заводится настоящий плеер — потому
   у плиты position: relative, а у плеера внутри неё inset: 0.

   Обрамления нет (док. 01 §8): ни рамки, ни скругления, ни тени —
   прямоугольник 16:9 на бумаге, как и сам плеер. Чёрная подложка не
   украшение: пока кадр не пришёл, в этом месте иначе дыра в цвет
   бумаги.                                                             */
.lr__plita {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  margin-top: clamp(14px, 2vh, 20px);
  background: var(--black);
  overflow: hidden;
}

.lr__plita-kadr {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ЗНАК ПУСКА — треугольник, и только он. Красной пилюли ютуба здесь
   нет: чужая марка на нашей бумаге лишняя, а треугольник читается
   «пуск» сам по себе. Полупрозрачная подложка под ним нужна не для
   красоты — на светлой части обложки белый треугольник пропадает.     */
.lr__plita-pusk {
  position: absolute;
  left: 50%;
  top: 50%;
  width: clamp(54px, 9%, 78px);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: rgba(8, 7, 6, .55);
  transition: background .2s ease;
}
.lr__plita-pusk::after {
  content: '';
  position: absolute;
  left: 54%;
  top: 50%;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: .55em 0 .55em .95em;
  border-color: transparent transparent transparent var(--paper);
  font-size: clamp(16px, 2.6vw, 22px);
}
.lr__plita:hover .lr__plita-pusk { background: rgba(8, 7, 6, .75); }

/* ПОДПИСИ У ПЛИТЫ НЕТ. Она напрашивалась — «Часть 1» в нижнем поле
   кадра, как подпись у всякого кадра сайта, — но на самой обложке уже
   набрано «День 2. Часть 1» жирным гротеском в полкадра. Две подписи
   об одном, одна поверх другой. Номер части остался в aria-label: тем,
   кто слушает страницу голосом, обложка не говорит ничего.            */

@media (prefers-reduced-motion: reduce) {
  .lr__plita-pusk { transition: none; }
}

.lr__zapis-head {
  color: var(--ink);
  cursor: pointer;
  list-style: none;
}
.lr__zapis-head::-webkit-details-marker { display: none; }
.lr__zapis-head::after {
  content: '›';
  display: inline-block;
  margin-left: .6em;
  color: var(--ink-soft);
  transition: transform .2s ease;
}
.lr__zapis[open] .lr__zapis-head::after { transform: rotate(90deg); }

/* Части идут строкой с переносом, а не столбиком: девять строк по два
   слова — это список ради списка, а в строку они занимают две.        */
.lr__zapis-list {
  list-style: none;
  margin: clamp(12px, 1.8vh, 16px) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: .9em 1.5em;
}

.lr__zapis-link,
.lr__rec-link,
.lr__folio-rec {
  color: var(--ink-soft);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .35em;
  text-decoration-color: var(--hairline-aegean);
}
.lr__zapis-link:hover,
.lr__rec-link:hover { color: var(--ink); }

/* Пометка у раздела. На телефоне стоит в потоке сразу под заголовком —
   там, где читатель только что прочёл имя раздела; на широком уезжает
   в правое поле (ниже). Внутри неё — строка и плита этой части.      */
.lr__rec { margin: clamp(8px, 1.2vh, 12px) 0 clamp(16px, 2.4vh, 22px); }
.lr__rec-link { display: inline-block; white-space: nowrap; }

/* Плиты, которые ещё не разнесены по разделам, стоят скрытыми в
   аппарате записи. Скрытую ленивую картинку браузер не грузит, поэтому
   без JS страница не платит за них ничего.                           */
.lr__plita[hidden] { display: none; }

/* ── Фигура конспекта ──────────────────────────────────────────────────
   Инфографика тренинга 2019: перо с акварельной заливкой на кремовой
   бумаге (Р-122). Бумага рисунка теплее нашей на полтона, и фигура
   читается вклейкой — вклеенным листом в книге. Это честно: рисунок
   чужой руки и есть вклейка.

   Обрамления нет (док. 01 §8): ни рамки, ни подложки, ни тени. Края
   рисунка и так видны — они и работают границей, и рамка вокруг них
   была бы рамкой вокруг рамки.

   Ширина — мера набора, ни знаком больше: фигура стоит в полосе, как
   стоит в книге, а не вылезает в поле. Поле занято записью, и второй
   жилец там не помещается.

   Воздух тот же, что у цитаты (--quote-space): оба — вставка в речь,
   и мерить их разными величинами значило бы завести второй ритм.     */
.lr__figure {
  margin: var(--quote-space) 0;
}
.lr__figure picture,
.lr__figure img {
  display: block;
  width: 100%;
  height: auto;
}

/* Заглушка: слот есть, производных нет. Видна нарочно — пропавший кадр
   должен сказать о себе, а не оставить дыру в верстке.                */
.lr__figure .figure__stub {
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  border: 1px dashed var(--hairline);
  color: var(--ink-soft);
}

/* ── Створка: раздел, который надо иметь, а не читать (Р-124) ──────────
   Дисклеймер кончает каждый документ тренинга 2019 — сто тридцать слов
   юридической прозы одним абзацем. По весу на странице он равнялся
   разделу конспекта, по делу не читается вовсе: его держат на случай.

   Свёрнут он тем же приёмом, что перечень частей записи: заголовок
   стоит открыто, указатель «›» говорит, что за ним есть текст, одно
   нажатие — и он здесь. Юридически это не «спрятать»: оговорка обязана
   быть на виду и доступной, а не развёрнутой, и текст остаётся в
   разметке страницы — его берут и поиск, и печать.

   Разворачивается СТВОРКОЙ, а не подсветкой: заголовок внутри summary
   остаётся тем же узлом третьего уровня, с той же волосяной сверху, и
   в оглавлении конспекта он стоит наравне с прочими.                  */
.lr__stvorka-head {
  cursor: pointer;
  list-style: none;
}
.lr__stvorka-head::-webkit-details-marker { display: none; }

/* Указатель стоит в строке заголовка, а не на summary: summary здесь —
   обёртка вокруг блочного h2, и псевдоэлемент на ней ушёл бы под него
   отдельной строкой.                                                  */
.lr__stvorka-head .lr__node { margin-bottom: 0; }
.lr__stvorka-head .lr__node::after {
  content: '›';
  display: inline-block;
  margin-left: .6em;
  color: var(--ink-soft);
  transition: transform .2s ease;
}
.lr__stvorka[open] .lr__stvorka-head .lr__node::after { transform: rotate(90deg); }
.lr__stvorka[open] .lr__stvorka-head { margin-bottom: .85em; }

@media (prefers-reduced-motion: reduce) {
  .lr__zapis-head::after,
  .lr__stvorka-head .lr__node::after { transition: none; }
}

/* ── Поле записи справа (от 1260px) ────────────────────────────────────
   Слева аппарат чтения — «где я», справа аппарат записи — «что здесь
   слушать»; между ними мера набора, и она не меняется ни на знак.

   ПОЧЕМУ НЕ ТРЕТЬЯ КОЛОНКА ГРИДА. Пометка обязана стоять на высоте
   своего раздела, а грид выстроил бы её в общий столбик. Поэтому
   пометка остаётся в своём разделе и абсолютно позиционируется от него:
   top: 0 — это в точности волосяная заголовка, и линия в поле встаёт
   продолжением линии раздела. Места под поле добавляет max-width
   секции: правая колонка не объявлена, она просто не занята текстом.

   ПОЧЕМУ 1260, А НЕ 1000. Аппарат плюс мера плюс поле — это около
   1180px при узкой мере; ниже поле пришлось бы сжимать до ширины, в
   которой чужой плеер уже не показывает своих кнопок.                */
@media (min-width: 1260px) {
  .longread {
    --lr-gap: clamp(32px, 3vw, 56px);
    --lr-rail: clamp(240px, 22vw, 360px);
    max-width: calc(230px + clamp(36px, 4.5vw, 72px) + var(--measure)
                    + clamp(32px, 3vw, 56px) + clamp(240px, 22vw, 360px)
                    + var(--pad) * 2);
  }

  /* ПОЛОСА НАБОРА КОНЧАЕТСЯ ТАМ, ГДЕ НАЧИНАЕТСЯ ПОЛЕ. Колонка держала
     всю ширину грида — меру, промежуток и поле разом, — и заглавие
     встречи (Prata до 78px, max-width 24ch) уходило по ней вправо,
     наезжая на перечень частей: на 1320px оно залезало в поле на 268
     пикселей. Текст под заглавием этого не показывал только потому, что
     у абзацев своя мера.

     Мера набора при этом не меняется ни на знак: колонка и была шириной
     в меру по тексту, здесь это просто сказано вслух.                  */
  .longread__col { position: relative; max-width: var(--measure); }
  .lr__part { position: relative; }

  /* В поле уезжает весь аппарат записи разом — перечень и плита под
     ним, — поэтому позиционируется обёртка, а не перечень: плита
     обязана стоять под своим перечнем, а не искать его вторым
     absolute.                                                         */
  .lr__zapis-blok {
    position: absolute;
    top: 0;
    left: calc(var(--measure) + var(--lr-gap));
    width: var(--lr-rail);
    max-width: none;
    margin: 0;
  }

  .lr__rec {
    position: absolute;
    top: 0;
    left: 100%;
    margin: 0 0 0 var(--lr-gap);
    width: var(--lr-rail);
    border-top: 1px solid var(--hairline);
    padding-top: clamp(20px, 2.8vh, 30px);
  }
}

/* ── Колонтитул чтения (телефон) ───────────────────────────────────────
   Постоянной шапки на сайте нет и не заводится (§9): та шапка была
   навигацией и принадлежала первому экрану. Это другой объект —
   колонтитул издания. Он называет раздел, в котором читатель стоит, и
   отмеряет прочитанное; живёт только внутри конспекта, единственного
   длинного текста сайта, и только там, где оглавления в поле нет.

   Линия под ним одна по материалу и двойная по работе: чернильная
   волосяная держит нижний край, эгейская поверх неё показывает
   прочитанную долю. Голубой красит линию, а не буквы (§2), и работает
   указателем — как номер текущей главы в оглавлении (Р-19).           */
.lr__folio {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  display: flex;
  align-items: baseline;
  gap: 1.2em;
  padding: 9px var(--pad) 9px;
  background: var(--paper);
  transform: translateY(-101%);
  transition: transform .22s ease;
}
.lr__folio.is-on { transform: none; }

.lr__folio::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: var(--hairline);
}

/* Имя узла в одну строку: колонтитул не растёт вслед за длиной
   заголовка, иначе он съел бы четверть экрана на «Но хотим ли мы этого
   на самом деле?..».                                                  */
.lr__folio-node {
  color: var(--ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin: 0;
  flex: 1 1 auto;
  min-width: 0;
}

/* ЗАПИСЬ ИЗ КОЛОНТИТУЛА ВЕДЁТ НА ЮТУБ, А НЕ РАСКРЫВАЕТ ПЛЕЕР НА МЕСТЕ.
   Колонтитул называет раздел, который читатель уже прошёл: пометка
   этого раздела осталась выше экрана, и раскрывать плеер там значило бы
   открыть его вне поля зрения. Поэтому здесь внешний переход — и это
   ровно то, чем владелец объяснял всю перестройку: смотреть удобнее в
   ютубе.                                                              */
.lr__folio-rec {
  flex: 0 0 auto;
  white-space: nowrap;
}
.lr__folio-rec[hidden] { display: none; }

.lr__folio-read {
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1px;
  width: 0;
  background: var(--aegean);
}

/* НА ШИРОКОМ ОТ КОЛОНТИТУЛА ОСТАЁТСЯ ОДНА ЛИНИЯ. Имя раздела там
   говорит оглавление в поле, а вот прочитанной доли не говорит никто:
   это вторая, отдельная величина, и она стоит эгейской нитью по самому
   верху окна. Букв в ней нет, перехвата событий тоже — чистый
   указатель.                                                          */
@media (min-width: 1000px) {
  .lr__folio {
    display: block;
    padding: 0;
    background: none;
    transform: none;
    pointer-events: none;
  }
  .lr__folio::after { content: none; }
  .lr__folio-node, .lr__folio-rec { display: none; }
  .lr__folio-read { height: 2px; }
}

/* Колонтитул выезжает — это движение, и в покое его нет: при
   prefers-reduced-motion он просто стоит на месте (док. 01 §8).       */
@media (prefers-reduced-motion: reduce) {
  .lr__folio { transition: none; }
}

/* ── Полоса чтения: заглавие и плита прилипают (слово владельца 23.09) ───
   Пока читатель идёт вниз, заглавие встречи плавно уменьшается — до всё
   ещё крупного, высотой с плиту видео, — и остаётся наверху; плита
   записи встаёт рядом и, если запущена, играет дальше. Касается всех
   страниц встреч: 2025, 2019 и клуба.

   ЗАПУЩЕННЫЙ IFRAME НЕ ПЕРЕСТАВЛЯЕТСЯ В DOM — перенос перезагружает его,
   и видео встаёт. Поэтому плита прилипает на месте: тот же узел
   получает position: fixed, а на прежнем месте остаётся заглушка той же
   высоты (lr__plita-mesto), и текст под ней не прыгает.

   Уменьшение — transform, который пишет site.js в цикле прокрутки; здесь
   только то, что не меняется от кадра к кадру. Всё под классом
   lr--lipko: его ставит скрипт, без JS страница остаётся прежней.

   ЭТАЖИ. Бумага полосы под заглавием, заглавие под плитой, колонтитул
   чтения (z 20) над всеми тремя: он называет раздел и должен быть виден
   поверх полосы, под которой стоит.                                   */
.lr--lipko .longread__head {
  position: sticky;
  top: var(--lr-head-top, 0px);
  z-index: 16;
}
.lr--lipko .longread__title,
.lr--lipko .longread__meeting {
  transform-origin: 0 0;
  will-change: transform;
}
/* Прилипшее заглавие стоит поверх текста прозрачным боксом прежнего
   размера (transform его не уменьшает) — нажатия должны проходить
   сквозь него к тексту. */
.lr--lipko.is-stuck .longread__head { pointer-events: none; }

/* Бумага полосы. Высокая заранее и сдвигается вверх transform'ом: край
   с волосяной встаёт по низу заглавия, и высота не пересчитывается на
   каждом кадре. Во всю ширину окна — это колонтитул издания, а не
   плашка у текста. */
.lr__polosa {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: 70vh;
  z-index: 15;
  background: var(--paper);
  border-bottom: 1px solid var(--hairline);
  transform: translateY(-100%);
  pointer-events: none;
  visibility: hidden;
}
.lr--lipko.is-stuck .lr__polosa { visibility: visible; }

.lr__plita.is-lipko {
  position: fixed;
  z-index: 17;
  margin: 0;
  transform-origin: 0 0;
}
.lr__plita-mesto { display: block; }

/* Пока полоса стоит, заголовок раздела при переходе по оглавлению
   встаёт под неё, а не за неё; оглавление в поле опускается туда же. */
.lr--lipko :is(.lr__node, .lr__stage) { scroll-margin-top: calc(var(--lr-bar, 0px) + 20px); }
@media (min-width: 1000px) {
  .lr--lipko.is-stuck .lr__toc {
    top: calc(var(--lr-bar, 0px) + 20px);
    max-height: calc(100vh - var(--lr-bar, 0px) - 40px);
  }
}
/* Колонтитул чтения выезжает из-под полосы, а не из-под края окна. */
.lr--lipko.is-stuck .lr__folio { top: var(--lr-bar, 0px); }

/* ── Оглавление материалов ─────────────────────────────────────────────── */

.contents__lead {
  font-size: var(--t-lead);
  line-height: 1.55;
  max-width: var(--measure);
  margin: 0 0 clamp(30px, 4.5vh, 56px);
}
.contents__list { list-style: none; margin: 0; padding: 0; max-width: var(--measure); }

/* ВОЛОСЯНЫХ МЕЖДУ ПУНКТАМИ НЕТ (замечание владельца). Пункт нёс сразу
   две пометы: волосяную сверху, как перечень, и эгейское подчёркивание
   заглавия, как ссылка. Помета осталась одна — подчёркивание, потому
   что здесь каждый пункт и есть ссылка, а волосяная об этом не говорит
   ничего. Правило то же, по которому линейки ушли из нумерованных
   списков конспекта: где пункт уже назван номером в своей колонке,
   линия называет его второй раз.

   Перечней на открытом сайте это не касается: там пункты не ссылки, и
   волосяная у них единственная помета.                                */
.contents__item a {
  display: grid;
  grid-template-columns: 2.6em 1fr;
  gap: 0 12px;
  padding: clamp(11px, 1.8vh, 16px) 0;
  color: var(--ink);
  text-decoration: none;
}
.contents__n { padding-top: .4em; }
/* Длительность записи — служебная помета, моно и приглушённо, как номер.
   На широком — своей колонкой справа, на телефоне — строкой под темой:
   третья колонка на 390px отняла бы у темы треть меры. */
.contents__item a:has(.contents__meta) { grid-template-columns: 2.6em 1fr auto; }
.contents__meta {
  padding-top: .4em;
  font-size: 11px;
  color: var(--ink-soft);
  white-space: nowrap;
}
@media (max-width: 599px) {
  .contents__item a:has(.contents__meta) { grid-template-columns: 2.6em 1fr; }
  .contents__meta { grid-column: 2; padding-top: 6px; }
}
/* ЧЕТЫРЕ СТРОКИ — НЕ ПЕРЕЧЕНЬ, А ОГЛАВЛЕНИЕ ТОМА. У месяца клуба встреч
   четыре, и корпусным кеглем они занимали верхнюю треть экрана, оставляя
   под собой пустую полосу. На широком экране тема встречи берёт ступень
   лида: строк мало, каждая — вечер на два-три часа, и вес строки должен
   это говорить. Номер и длительность встают по базовой линии темы. */
@media (min-width: 900px) {
  .contents__item a:has(.contents__meta) {
    align-items: baseline;
    padding: clamp(16px, 2.6vh, 26px) 0;
  }
  .contents__item a:has(.contents__meta) .contents__title { font-size: var(--t-lead); line-height: 1.35; }
  .contents__item a:has(.contents__meta) :is(.contents__n, .contents__meta) { padding-top: 0; }
}
.contents__title {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .2em;
  text-decoration-color: var(--hairline-aegean);
}
.contents__after {
  margin-top: clamp(32px, 4.5vh, 60px);
  max-width: 46ch;
  color: var(--ink-soft);
}

/* ── Финальный кадр ─────────────────────────────────────────────────────
   На главной это цветовое событие, и секция переходит в колофон
   БЕЗ ШВА: разделителя и смены фона нет (док. 02 §4).                   */

.closing { position: relative; height: var(--screen); overflow: hidden; background: var(--black); }
.closing__frame, .closing__frame picture { position: absolute; inset: 0; }
/* Кадрирование держит небо: в цветовом событии платит именно закат */
.closing__img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 38%; }

/* ЗАТЕМНЕНИЕ КОДЫ — ДВУХПОЛОСНОЕ (док. 01 §6.8). Низ уходит в глухой
   чёрный, чтобы стык с колофоном остался без шва (док. 02 §4). Верх
   усиливается против общей маски: у коды метка стоит на самой светлой
   зоне снимка. Это не исключение из правила «затемняются полосы, а не
   кадр», а его применение — границы у затемнения по-прежнему нет.

   Плотность верхней полосы — ПАРАМЕТР КАДРА, а не общая константа:
   тёплому светлому кадру нужно больше, чем закатному. Значение приходит
   из базы через --coda-top (док. 03 §2).

   Настоящее решение для закатного кадра — кроп: пересобрать
   кадрирование так, чтобы верхняя линия падала на плотную часть неба,
   дешевле и лучше любой маски. Маска — страховка.                     */
.closing .frame__scrim {
  background:
    linear-gradient(
      to bottom,
      rgba(8, 7, 6, var(--coda-top, .44)) 0%,
      rgba(8, 7, 6, calc(var(--coda-top, .44) * .45)) 14%,
      rgba(8, 7, 6, 0) 22%
    ),
    linear-gradient(
      to bottom,
      rgba(8, 7, 6, 0) 46%,
      rgba(8, 7, 6, .52) 76%,
      rgba(8, 7, 6, .94) 100%
    );
}

/* Строка финала стоит на общей линии кадра; обёртка нужна затем, что
   строка здесь приходит проявлением и её ширину держит шаблон.        */
.closing__copy {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  bottom: var(--frame-copy);
  z-index: 4;
}
.closing__copy .frame__line { position: static; }

/* Локального размытия под строкой здесь больше нет (решение владельца):
   границы у backdrop-filter действительно не было, но полоса читалась
   прямоугольником — то есть ровно тем, чем плашка и является. Пёстрый
   светлый кадр держится плотностью верхней полосы (--coda-top) и
   громкостью самих букв, а не подложкой под ними.                     */

/* ── Колофон ────────────────────────────────────────────────────────────
   Страница всегда заканчивается чёрным (док. 01 §4).

   ЭКРАН ЦЕЛИКОМ, А НЕ ХВОСТ ПОД КОДОЙ (Р-24). Колофон высотой по
   содержимому делал последнюю точку снапа недостижимой: доскроллить
   некуда, браузер упирался в конец документа, колофон садился у нижнего
   края, а сверху оставалась случайная доля финального кадра — 47% на
   390×844, 65% на 1280×860. Кода — цветовое событие номер один; показать
   её целиком, а следом обрезком, значит потратить её дважды.

   Воздух сверху не пустота, а поле последней полосы: выходные данные
   в книге стоят внизу, под белым. Стык с кодой остаётся бесшовным —
   чёрный низ кадра переходит в чёрный фон колофона, — просто теперь эта
   граница видна только на протяжке, а не в конечном положении.

   РАСКЛАДКА ПРАВОЙ КОЛОНКОЙ (Р-27): марка на сайте всегда у правого поля
   — на титуле правый верх, здесь правый низ. Переключатель языка встаёт
   туда, где на титуле стоит маркер меню: управление справа, читаемое
   слева, один закон на весь сайт.                                      */

.colophon {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--top-line) var(--pad) var(--safe-edge);
  background: var(--black);
  color: var(--on-black);
}

/* Строка о съёмке даёт верхней линии работу: сведения об иллюстрациях —
   классическое содержимое колофона, а не заполнитель.                  */
.colophon__shot,
.colophon__lang {
  position: absolute;
  top: var(--top-line);
  color: rgba(232, 228, 220, .34);
}
/* На 390 строка о съёмке и язык стоят на одной линии: строка переносится,
   а не наезжает на переключатель.                                       */
.colophon__shot { left: var(--pad); max-width: calc(100% - var(--pad) * 2 - 116px); }
.colophon__lang {
  right: var(--pad);
  display: flex;
  gap: 9px;
  align-items: baseline;
  font-size: var(--doc-folio);
  letter-spacing: var(--doc-folio-ls);
  text-transform: uppercase;
}
.colophon__lang-now { color: rgba(232, 228, 220, .95); }
.colophon__lang-sep { color: rgba(232, 228, 220, .38); }
.colophon__lang-off { color: rgba(232, 228, 220, .38); }

/* НАБОР СЧИТАЕТСЯ ОТ ПОЛНОГО ЭКРАНА (Р-32). Кегли подбирались, когда
   колофон занимал половину экрана; на целом тот же набор читается
   сжавшимся в угол. Шкала поднята на ступень, интервалы между группами
   разведены. Правило на будущее: набор проверяется в том объёме,
   в котором стоит, — это отношение буквы к полю, а не вкусовщина.
   Марка исключение: её кегль общий с титулом и различает место,
   а не размер (Р-28).                                                  */
/* ЦЕЛИ КАСАНИЯ — 44px, И ЭТО НЕВИДИМЫЙ ХИТБОКС, А НЕ ВОЗДУХ. Приём
   не новый: ровно так стоят три штриха маркера меню (док. 01 §9) —
   строка остаётся строкой, палец получает свою площадь. Интервал
   разведён до 20px, чтобы соседние хитбоксы касались, а не налезали
   друг на друга: 24px строки + 20px промежутка и есть шаг в 44.       */
/* Тот же жёсткий шаг 44px, что у разделов напротив: пока обе колонки
   считались каждая своим интервалом, строки не совпадали, и шаг у них
   всё равно выходил ≈44 — теперь он ровно 44 у обеих, и совпадение
   держится само.                                                       */
.colophon__channels { display: grid; grid-auto-rows: 44px; align-items: center; justify-items: start; }
.colophon__channels a {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-size: 19px;
  line-height: 1.25;
  /* Подчёркивание берёт на себя название: метка — не часть ссылки,
     а строка выходных данных при ней.                                  */
  text-decoration: none;
}
.colophon__channels a::after,
.colophon__sections a::after,
.colophon__service a::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 44px;
  transform: translateY(-50%);
}
.colophon__channels a span:first-child {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: .22em;
  text-decoration-color: var(--hairline-dk);
}
/* Метка при названии: «Telegram» и «Чат-бот» — оба телеграм, и по
   названиям личную переписку от доступа к материалам не отличить.      */
.colophon__tag {
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(232, 228, 220, .42);
}

/* ДВЕ ОСИ (решение владельца, макет kolofon-2). Каналы у левого поля,
   разделы у правого — друг напротив друга, а не одной лестницей вниз.
   Разделы выключены вправо: та же сторона, что у марки под ними и у
   маркера меню на всех остальных экранах.                             */
.colophon__pair {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
}

/* РЯД РАЗДЕЛОВ (Р-52), теперь полный: «Главная», «Мой подход»,
   «Тренинги», «Консультации», «Отзывы».

   ОБЕ ОСИ — ОДНА СЕТКА (решение владельца). Пунктов пять, ссылок три, и
   пока строки стояли каждая на своём интервале, столбцы просто съезжали
   друг относительно друга. Теперь шаг задан жёстко — 44px, ровно цель
   касания, — и одинаков у каналов и разделов, а разделы подняты на две
   строки: три средних пункта встают напротив трёх ссылок.             */
.colophon__sections {
  display: grid;
  grid-auto-rows: 44px;
  align-items: center;
  justify-items: end;
  text-align: right;
  margin-top: -88px;
  color: rgba(232, 228, 220, .5);
}
.colophon__sections a { position: relative; }
/* Текущий раздел — самый яркий в столбце (решение владельца): см. довод
   у .menu__sections выше. Хитбокс строки здесь и так 44px по сетке,
   отдельного ему не нужно.                                           */
.colophon__sections .is-here { color: rgba(232, 228, 220, .95); }
/* Подчёркивания у текущего раздела нет: он и так помечен тоном и
   штрихом, а третий знак на одной строке — уже украшение.             */
.colophon__sections .is-here { text-decoration: none; }

/* ЭГЕЙСКОЕ ПОДЧЁРКИВАНИЕ ЖИВЁТ НА БУМАГЕ (Р-33). Общее правило ссылок
   (§6.7) задаёт голубую волосяную, и колофон её наследовал: две
   подчёркнутые голубым строки стояли ближе к марке, чем что-либо ещё
   на сайте, и отбирали у её штриха единственное, на чём держался довод, —
   что он единственное синее пятно на чёрном. На чёрном ссылки берут
   светлую волосяную, как каналы; разницу между каналами и служебными
   и так несут кегль и слой.                                            */
.colophon__sections a,
.colophon__service a { text-decoration-color: var(--hairline-dk); }

/* Марка здесь подписывает, а не представляет: место различает роль,
   а не кегль — размер тот же, что на титуле (Р-28). Воздух над ней
   больше любого промежутка внутри групп: это не отступ, а граница
   между выходными данными и подписью издания.                         */
.colophon__sign { margin-top: clamp(42px, 6.5vh, 66px); text-align: right; }

/* НИЗ КОЛОФОНА (решение владельца). Волосяная и под ней одна тихая
   строка: служебные страницы слева, год справа. Так закрывается
   страница — как выходные данные книги, а не обрывом на марке.
   Волосяная светлая, как все линии на чёрном (Р-33).                  */
.colophon__base {
  margin-top: clamp(26px, 4vh, 40px);
  padding-top: clamp(12px, 1.8vh, 18px);
  border-top: 1px solid rgba(232, 228, 220, .10);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}
/* Служебный ряд идёт СТРОКОЙ, а не колонкой: две короткие ссылки через
   тот же разделитель «·», что в переключателе языка. Громкость ниже
   разделов — юридическое место юридического последнее.                */
.colophon__service {
  display: flex;
  align-items: baseline;
  gap: 8px;
  color: rgba(232, 228, 220, .38);
}
.colophon__service a { position: relative; }
.colophon__service-sep { color: rgba(232, 228, 220, .24); }

/* Год без © и без имени: имя стоит прямо над строкой, а знак © прав
   не создаёт. Подставляется временем сервера — устаревший год читается
   как «заброшено» (Р-26).                                              */
.colophon__year {
  font-size: var(--doc-service);
  letter-spacing: var(--doc-service-ls);
  color: rgba(232, 228, 220, .38);
}

@media (min-width: 900px) {
  /* Оси те же, шире только поле: колонки расходятся к краям полосы,
     а не растягиваются по всей её ширине.                            */
  .colophon__channels { flex: 0 0 auto; }
  .colophon__sections { flex: 0 0 auto; }
}

/* ── Сокращённое движение ───────────────────────────────────────────────
   Обрабатывается для ВСЕХ приёмов (док. 04 §5).
   Спуск разворачивается в статичный вертикальный список из четырёх
   блоков на бумаге, sticky отключается. Пластины — обычные
   полноэкранные кадры. Фокус-ин героя не проигрывается.                 */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }

  .hero__img { animation: none; filter: none; transform: none; }

  /* Шага в один экран тоже нет: страница прокручивается как обычная,
     рельсы сцен убираются вместе с самими сценами.                      */
  html { scroll-snap-type: none; }
  main > *, .colophon, .rail__slot { scroll-snap-align: none; scroll-snap-stop: normal; }
  .rail { display: none; }

  .descent { height: auto; }
  .descent__stage {
    position: static;
    height: auto;
    display: block;
    padding-top: var(--section);
    padding-bottom: var(--section);
    background: var(--paper-deep) !important;
    color: var(--ink) !important;
  }
  .descent__stack, .descent__flyer { display: none; }
  .descent__screen {
    position: static;
    opacity: 1;
    pointer-events: auto;
    padding-bottom: clamp(56px, 9vh, 110px);
  }

  /* Ничего не проявляется: весь текст на месте сразу. */
  .descent__line,
  .descent__sub,
  .frame__line,
  .quote-frame {
    opacity: 1;
    filter: none;
    transform: none;
    transition: none;
  }
  .descent__sub { opacity: .72; }

  /* Уход строки — тоже движение: при reduce он не срабатывает. */
  .frame__line.is-gone,
  .quote-frame.is-gone { opacity: 1; filter: none; transform: none; }

  /* Титул страницы: кадр стоит резким сразу, инверсия не проигрывается. */
  .spread__frame { opacity: 1; filter: none; transform: none; }

  .plate-hold, .plate-open, .plate-swap { height: var(--screen); }
  .plate-hold__stage, .plate-open__stage, .plate-swap__stage { position: static; }
  /* !important: если настройку включили уже после загрузки, JS успел
     проставить инлайновые размеры ленты, а инлайн иначе перебьёт CSS. */
  .plate-open__frame {
    top: 0 !important;
    bottom: 0 !important;
    left: 0 !important;
    right: 0 !important;
  }
  .plate-swap__frame { opacity: 0; }
  .plate-swap__frame:first-child { opacity: 1; }
}
