/* Стиль страниц ArtisDomus. Вынесен из index.html, когда появился второй
   шаблон: дублировать семьсот строк во второй файл значит гарантировать,
   что они разойдутся. Значения сюда не попадают — они все в tokens.css. */

/* Раскладка страницы. Все значения приходят из tokens.css.
   Ни одного font-size, отступа, кривой или длительности мимо токена. */

.skip {
	position: absolute;
	inset-inline-start: -9999px;
	top: var(--s2);
	background: var(--ink);
	color: var(--paper);
	padding: var(--s2) var(--s3);
	z-index: var(--z-skip);
}
.skip:focus { inset-inline-start: var(--s3); }

.page {
	max-width: var(--page-max);
	margin-inline: auto;
	padding-inline: var(--page-pad);
}

/* Сетка страницы: колонка аппарата на стороне начала строки и основная
   колонка. На узкой ширине колонка схлопывается, и пометки встают под тем
   утверждением, к которому относятся. Свойства только логические, поэтому
   при арабской версии всё зеркалится само. */
/* Остаток после починки граф — одно длинное слово внутри выделенного
   набора. Перенос внутри слова разрешён на всём теле: документ, который
   при увеличении кегля теряет строку за краем, не читается вовсе. */
body { overflow-wrap: break-word; }

.row {
	display: grid;
	/* `minmax(0, 1fr)`, а не голый `1fr`. Голая доля имеет неявный минимум
	   `auto`, то есть не может стать уже своего содержимого: длинное слово
	   или моноширинная строка распирают графу, и текст уезжает за правый
	   край. На обычном кегле это незаметно, при тексте 200 % — замер на
	   320 px дал 60 элементов за краем на оглавлении и 53 на записи о
	   наследовании, худший вылет 278 px. На широких ширинах идиома уже
	   стояла в двадцати с лишним местах; здесь и ещё в шести базовых
	   объявлениях её просто забыли. */
	grid-template-columns: minmax(0, 1fr);
	gap: var(--s3);
	/* Расстояние от края столбца текста до края окна. Объявлено безусловно,
	   а не внутри медиазапроса: краевая плита читает его на всех ширинах, а
	   значение, объявленное только на широком экране, на узком не
	   существует — и `var()` тихо не применяется, стиль при этом не падает.
	   Поймано гейтом ровно так: «используются без объявления». */
	--bleed-out: calc(max(0px, (100vw - var(--page-max)) / 2) + var(--page-pad));
	/* То же расстояние, но с левой стороны, где между столбцом текста и окном
	   лежит ещё графа аппарата с отбивкой. На узкой полосе графы нет, и оба
	   вылета равны. Краевые плиты считали это выражение у себя, а полосная
	   плита пользовалась общим приёмом `50% - 50vw` — он верен только для
	   колонки, стоящей по центру окна. Наша сдвинута, и плита уезжала за
	   правый край на 136 px при окне 1440. Проверка ширин это печатала на
	   каждой странице корпуса, а гейт такие строки не считал провалом. */
	--bleed-in: var(--bleed-out);
	--row-pad-end: var(--s5);
	/* Верхний отступ раздела на ступень больше нижнего порога шкалы: липкая
	   шапка в сжатом виде занимает 47 px, и на прежних 64 подпись раздела
	   вплотную подходила к её кромке. Величина постоянная и взята со шкалы,
	   а не вычислена из высоты шапки: вычисленная менялась при сжатии, и
	   страница пересчитывала раскладку под пальцем.
	   Посадка по якорю отсчитывается своим отступом, а не суммой с этим:
	   когда складывались оба, подпись уезжала на 279 px от кромки. */
	--row-pad-start: var(--s6);
	padding-block: var(--row-pad-start) var(--row-pad-end);
	scroll-margin-block-start: var(--s3);
	border-top: 1px solid var(--rule);
}
/* На узких ширинах поля встают под текст, и между кнопкой и крупной
   цифрой раздела оставался один шаг сетки — шестнадцать пикселей при
   цифре в тридцать. Читалось как наезд. Шаг тот же, со шкалы, просто
   на две ступени выше. */
@media (max-width: 50.624em) {
	.row > .register { margin-block-start: var(--s4); }
}
.row:first-of-type { border-top: 0; }
.rk + .row { border-top: 0; }

@media (min-width: 50.625em) {
	.row {
		grid-template-columns: var(--register) minmax(0, 1fr);
		gap: var(--gutter);
		--bleed-in: calc(var(--bleed-out) + var(--register) + var(--gutter));
		--row-pad-end: var(--s6);
		--row-pad-start: var(--s6);
		/* Плотная укладка нужна из-за порядка в разметке: колонка аппарата
		   стоит ПОСЛЕ основного текста, чтобы и ассистент, и чтение с экрана
		   получали сначала утверждение, а потом его источник. Визуально она
		   должна остаться слева, а разрежённая укладка назад не возвращается
		   и увела бы её в следующий ряд. */
		grid-auto-flow: row dense;
	}
	.row > .register { grid-column: 1; }
	/* Отступ графы объявлен там же, где графа становится колонкой. Раньше
	   он жил в другом медиаблоке, и у читателя с базовым кеглем 24 px они
	   расходились: колонка уже стояла, а отступа ещё не было — сноска
	   доходила до самого края графы и попадала под засечку указателя. */
	.row > .register { padding-inline-end: var(--s4); }
	/* Место по умолчанию — столбец текста, и оно задано положительно.
	   Стояло `:*not([class])`: основной блок раздела опознавался по
	   ОТСУТСТВИЮ имени. Правило работало и было ловушкой — стоило дописать
	   графе любой класс, и она молча уезжала в столбец аппарата шириной в
	   208 px, потому что селектор переставал совпадать, а замены не было.
	   Теперь по умолчанию столбец текста, а своё место называют те, у кого
	   оно своё: графа аппарата и блоки во всю ширину. Класс на графе больше
	   ничего не отбирает. */
	/* Вес селектора понижен нарочно: `:where()` обнуляет свою часть, и
	   правило весит один элемент. Первая редакция этой правки стояла как
	   `.row > div` — вес `класс + элемент`, — и перебила собственные
	   классы: `.hero-head`, `.titlepage` и стена работ потеряли свои
	   `1 / -1` и уехали в столбец текста на всех страницах корпуса.
	   Поймал снимок раскладки до и после, а не чтение файла: вес селектора
	   в этом проекте подводил уже пятый раз. */
	:where(.row) > div { grid-column: 2; }
	/* Строчная плита, стоящая прямым ребёнком раздела, — тоже в столбце
	   текста: при плотной укладке она падала в графу аппарата (аудит 25.09). */
	:where(.row) > figure.plate--inline { grid-column: 2; }
	/* Крошка → заголовок 32 на всех ширинах: зазор ряда равен межколоннику
	   (32 или 64), и крошка стояла от h1 то в 64, то в 96 (аудит 25.09). */
	.row > .crumb { margin-block-end: calc(var(--s4) - var(--gutter)); }
	.row > .register { grid-column: 1; }
}

/* Вертикальная линейка между колонкой аппарата и основной. Это то самое
   разлиновывание, от которого направление и получило имя: на широком экране
   поля перестают быть пустотой и становятся графой. Ниже 1200 её нет —
   там колонка слишком узкая, и линейка прижимает текст. */
@media (min-width: 75em) {
	/* Линейка перенесена с ячейки на сам раздел, и это не перестановка, а
	   разница между разлиновкой и штрихами. Пока она была границей ячейки
	   аппарата, она шла ровно по высоте содержимого и обрывалась на
	   отступах: между разделами оставалось по девяносто шесть и сто
	   шестьдесят пикселей пустоты, и на прокрутке двенадцать разделов
	   читались как двенадцать отдельных листов.

	   Теперь это одна линия сверху донизу документа. Она нарисована фоном
	   раздела, а не рамкой, поэтому покрывает и отступы; дети раздела
	   рисуются поверх, и линия сама уходит за плиту или за ведомость там,
	   где им отдана вся ширина. Графа аппарата держит своё поле отступом,
	   как держала. */
	.row {
		--row-pad-end: var(--s7);
		--row-pad-start: var(--s6);
		background-image: linear-gradient(var(--rule), var(--rule));
		background-repeat: no-repeat;
		background-size: 1px 100%;
		background-position: var(--register) 0;
	}
	/* Строка титула рисует линейку от колонки текста, а не фоном раздела:
	   h1 и крошка идут на всю ширину, и фоновая линия перечёркивала их на
	   98 страницах (аудит 25.09). `-1000vh` — длина штриха, его обрезает
	   `overflow-y: clip` по низу строки; это не отступ. */
	.row:has(> .hero-head) { background-image: none; overflow-y: clip; }
	.row:has(> .hero-head) > .hero-head + div:not(.register) { position: relative; }
	.row:has(> .hero-head) > .hero-head + div:not(.register)::before {
		content: "";
		position: absolute;
		z-index: var(--z-ground);
		inset-inline-start: calc(-1 * var(--gutter));
		inline-size: 1px;
		inset-block: 0 -1000vh;
		background: var(--rule);
		pointer-events: none;
	}
	/* Указатели без строки титула: крошка на колонке текста, где их метка и h1. */
	.row:not(:has(> .hero-head)) > .crumb { margin-inline-start: calc(var(--register) + var(--gutter)); }
	/* Полка «Read next» — короткий раздел: над меткой и под ссылками было
	   по 260–280 px (аудит 25.09). */
	.row:has(+ section[aria-labelledby="h-shelf"]) { --row-pad-end: var(--s5); }
	section[aria-labelledby="h-shelf"] { --row-pad-end: var(--s6); }
	/* Справа налево линейка отсчитывается от правой кромки. У
	   `background-position` логического варианта нет, и физическое
	   смещение оставляло разлиновку слева, тогда как сама графа уезжала
	   вправо: линия проходила сквозь текст. Арабское издание — второй
	   этап по Приложению 1, и встретить это надо не тогда. */
	[dir="rtl"] .row { background-position: calc(100% - var(--register)) 0; }
}

/* Пометка набирается аппаратом всюду, а не только внутри колонки: две из
   двенадцати стоят вне её — у стены работ и у пустой плиты — и набирались
   основным кеглем 19 px полными чернилами. */
.register,
.note {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	line-height: var(--leading-tight);
	color: var(--muted);
}

/* Номер раздела набирается крупно и дисплейной гарнитурой: колонка аппарата
   иначе стоит полупустой, а страница держится на типографической композиции
   в той же мере, что и на изображениях.

   Он же — единственное место, где фирменный цвет берётся крупно. Замер
   объяснил, почему именно здесь. Акцент против бумаги даёт 6,82, против
   чернил — 1,73: внутри строки чернил крашеное слово отличается почти
   только оттенком и пропадает для дейтеранопа, а стоя на бумаге само по
   себе — держит контраст полностью. Номер стоит в колонке один, кеглем
   h2, порог к нему 3 : 1 как к крупному. Различает его от сноски под ним
   кегль, а не цвет, поэтому правило «не нести смысл одним цветом» не
   нарушено, даже когда оттенок не виден вовсе.

   Двенадцать таких чисел вниз по странице — это и ритм, и единственное
   присутствие марки крупнее пол-буквы. До этого весь фирменный цвет на
   странице из 652 элементов держался на десяти квадратиках. */
.num {
	display: block;
	font-family: var(--font-display);
	font-weight: 500;
	font-size: var(--size-h2);
	line-height: 1;
	letter-spacing: var(--tracking-display);
	color: var(--accent);
	margin-block-end: var(--s3);
}
/* Определение термина помечено `<dfn>`, и пометка ничего не меняет в виде.

   Тег для этого и существует: он говорит, какое предложение определяющее.
   Из пометки живут указатель глоссария, полки направлений и поле описания у
   термина в машинном графе — то есть она работает там, где её не видно.

   Браузер рисует `<dfn>` курсивом по умолчанию. Курсив на сайте несёт свою
   роль — название работы, иностранное слово, — и определение длиной в двести
   знаков, набранное курсивом целиком, отобрало бы эту роль у него. Поэтому
   наследуем начертание абзаца. */
dfn {
	font-style: inherit;
	font-weight: inherit;
}

.num small {
	/* Вес называется явно, потому что он наследуется от счётчика.

	   `.num` набран дисплейной гарнитурой в весе 500, и `small` внутри него
	   переходит на моноширинную, а вес забирает родительский. Начертания
	   моноширинной в весе 500 не объявлено ни одного: браузер подделывает
	   жир сам, растягивая контуры. Замер 16.09.2026: связка «Mono | 500 |
	   normal» набрана на 511 узлах на 86 страницах из 88.

	   Подделанный жир — это не оттенок начертания, а искажение рисунка, и в
	   системе, где начертания названы поимённо и лицензируются поштучно,
	   он не должен появляться вовсе. Держит гейт `.лица.mjs`. */
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-label);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
	margin-inline-start: 0.4em;
	vertical-align: 0.35em;
}

/* Одна полоса на всю ширину экрана, вывернутая по цвету. Пара чернила и
   бумага уже посчитана в обе стороны — 11,76 в светлой теме и 14,12 в
   тёмной, — поэтому выворотка не создаёт новой пары и ничего не нарушает.
   Акцент внутри полосы не применяется: BROWN MADDER на ROYAL NAVY даёт
   1,73 и порога не берёт, поэтому на чернилах работает своя роль,
   объявленная отдельно. */
/* Роли на чернилах вынесены в отдельный селектор и делятся с выворотной
   полосой. Это не аккуратность ради аккуратности: контраст каждой пары на
   этом грунте посчитан и проверен по пикселям один раз, и второй компонент,
   который «тоже инвертируется», обязан брать те же значения, а не свои
   похожие. Иначе через месяц на сайте два разных чёрных и две разные
   приглушённые, и обе надо мерить заново. */
.rk,
.veil,
/* Плита направления вывернута теми же ролями, а не своими: список
   селекторов — единственное место, где эта пара цветов вообще задана.
   Если бы блок здесь переписали, расхождение появилось бы молча и
   первой сломалась бы линейка на 48 %, которая несёт рамку. */
.area:is(:hover, :focus-visible, :active),
.on-ink {
	color: var(--paper);
	--muted: color-mix(in srgb, var(--paper) 72%, transparent);
	--rule: color-mix(in srgb, var(--paper) 22%, transparent);
	/* Средняя и сильная линейки тоже выводятся из бумаги, и это не
	   аккуратность, а два конкретных отказа. Сильная несёт рамку
	   зарезервированной плиты — той самой пустой рамки, которая и есть
	   довод страницы, — и квадрат придержанной пометки. Обе рисуются
	   чернилами по чернилам, то есть не рисуются вовсе: на полосе исчезали
	   и рамка, и различие между «установлено» и «придержано». На 48 %
	   бумаги пара к грунту даёт 3,93 в светлой теме и 3,17 в тёмной, то
	   есть порог 3:1 взят в обеих — та же роль, что и в обычной комнате. */
	--rule-mid: color-mix(in srgb, var(--paper) 28%, transparent);
	--rule-strong: color-mix(in srgb, var(--paper) 48%, transparent);
	/* Печать практики. Плотность взята по худшему случаю: пометка счётчика
	   набрана приглушённой ролью, то есть бумагой в 72 %, и сама
	   полупрозрачна, а на узкой полосе она проходит поверх штриха печати.
	   На 22 % пара «пометка поверх штриха» даёт 4,11 в светлой теме при
	   расчётном пороге 5,0 для мелкого моноширинного; на 12 % — 5,23 в
	   светлой и 5,88 в тёмной. Сам штрих к грунту даёт 1,41 и 1,28: знак
	   читается материалом и не спорит с набором, который держит 11,76 и
	   14,12 на том же грунте. */
	--seal: color-mix(in srgb, var(--paper) 12%, transparent);
	--fg: var(--paper);
}
/* Грунт принадлежит комнате, кегль принадлежит предложению, и делить их
   надо явно. До второй чернильной комнаты один класс `.row--invert` нёс
   и то и другое, и это работало ровно пока комната была одна. Как только
   чернила получает второй раздел, заголовок «Written permission covers
   one engagement» набирается теми же восемьюдесятью пунктами, что и
   «The fee comes from the owner.», — и исключительность самой дорогой
   фразы страницы теряется молча, побочным эффектом смены грунта.

   Теперь `.rk` — это грунт: заливка, роли, снятые пороги, печать.
   `.row--invert` — это только кегль, и стоит он ровно на одном разделе.
   Имя оставлено прежним намеренно: оно уже названо в записях, и
   переименование стоило бы дороже, чем комментарий. */
.rk { position: relative; border-top: 0; }
/* Счётчик вывернутой комнаты берёт свой акцент, а не бумагу. Правило
   акцента на сайте одно — он метит аппарат, — и три комнаты из двенадцати,
   выпадающие из него, превращали систему обратно в украшение. Пара
   замерена: #B49789 на чернилах даёт 4,96 в светлой теме, #7B4330 на
   светлых чернилах тёмной — 5,69.

   Правило стоит здесь, а не рядом с `.num`, потому что там оно проигрывало
   по порядку: `.rk .num` тяжелее `.num` на элемент, и объявление возле
   базового правила молчало. Проверено замером отрисованного цвета — вес
   селектора в этом проекте подводил уже четырежды, и каждый раз его ловил
   замер, а чтение файла — нет. */
/* Второй грунт объявлен рядом, а не отдельным блоком ниже. `.on-ink`
   задаёт те же роли, что и `.rk`, но до 15.09.2026 не получал ни счётчика,
   ни заголовка, ни номера сноски: они были починены только для комнаты.
   Пока `.on-ink` стоял на плите направления, это не проявлялось — плита
   счётчиков не носит. Первая же чернильная плита со счётчиком дала бы
   `--accent` на чернилах, то есть 1,73 при пороге 3. Правило простое: у
   грунта и у его починок должен быть один и тот же список селекторов. */
.rk .num, .on-ink .num { color: var(--accent-on-ink); }
.rk h2, .on-ink h2 { color: var(--fg); }
.row--invert h2 {
	--size-own: var(--size-display);
	--head-floor: var(--head-floor-display);
	line-height: var(--leading-display);
	max-width: 12em;
}
/* Квадрат пометки берёт `--fg`, а не бумагу напрямую. Разница видна
   только на печати: бумага остаётся бумагой и на белом листе, а `--fg`
   печатный блок возвращает к чёрному. Замерено печатью — на чернилах
   установленная сноска печаталась бумагой по белому. */
/* На чернильном грунте акцент свой: тёмный сургуч на чернилах даёт 1,73 и
   в палитру не входит. Роль объявлена отдельно, поэтому подпись практики
   остаётся цветной и в вывернутой комнате, а не гаснет в белый. */
.rk .note::before, .on-ink .note::before { background: var(--accent-on-ink); }

/* Пометка на полях — атом системы. Источник, дата прочтения, характер
   утверждения. Квадрат перед ней тот же, что в знаке: он всегда что-то
   отмечает и никогда не стоит просто так. */
.note {
	margin-block: var(--s3) 0;
	max-width: var(--measure-narrow);
}
/* Метка пометки: три состояния, и различаются они силуэтом, а не цветом.
   Сплошной квадрат — источник назван и датирован. Треугольник — наблюдение
   практики, за которым нет опубликованной величины. Пустой контур —
   придержано: практика применяет к этому притязанию стандарт, которому оно
   ещё не отвечает.

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

   Различие силуэтом, а не цветом, — не педантизм. До этого состояний было
   формально два, а фактически одно: они отличались только тоном квадрата,
   и читателю, который различает цвет хуже, обе пометки выглядели одинаково.
   Класс ставит `.notestate.mjs` по самому реестру, потому что источник
   истины один — статус строки. */
.note::before {
	content: "";
	display: inline-block;
	inline-size: 0.5em;
	block-size: 0.5em;
	margin-inline-end: 0.6em;
	background: var(--accent);
	vertical-align: 0.06em;
}
.note.obs::before {
	clip-path: polygon(0 0, 100% 50%, 0 100%);
}
.note.held::before {
	background: transparent;
	box-shadow: inset 0 0 0 1px var(--rule-strong);
}

/* Тот же силуэт — в самой строке реестра, перед словом состояния.

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

   Состояние ставит `.notestate.mjs` по статусу самой строки, тем же
   проходом, что и пометки. Слово при этом остаётся на месте: силуэт его не
   заменяет, а опережает, иначе смысл нёс бы один значок. */
.reg dd.t > b::before {
	content: "";
	display: inline-block;
	inline-size: 0.5em;
	block-size: 0.5em;
	margin-inline-end: 0.6em;
	background: var(--accent);
	vertical-align: 0.06em;
}
.reg[data-st="obs"] dd.t > b::before { clip-path: polygon(0 0, 100% 50%, 0 100%); }
.reg[data-st="held"] dd.t > b::before {
	background: transparent;
	box-shadow: inset 0 0 0 1px var(--rule-strong);
}
.rk .reg dd.t > b::before, .on-ink .reg dd.t > b::before { background: var(--accent-on-ink); }
.rk .reg[data-st="held"] dd.t > b::before, .on-ink .reg[data-st="held"] dd.t > b::before { background: transparent; }

.body { max-width: var(--measure); }
/* Лид, стоящий сразу за заголовком в той же графе, получает отбивку.
   Почти везде заголовок и лид лежат в разных графах сетки, и зазор даёт
   она; на входе в библиотеку они оказались соседями в одной, и замер дал
   ноль пикселей между восьмидесятипунктовым заголовком и текстом. Строка
   при этом читается не как лид, а как четвёртая строка заголовка. */
:is(h1, h2) + :is(.lead, .body) { margin-block-start: var(--s4); }
/* Лид и следующий за ним блок прозы. Отбивка сверху у лида была, снизу не
   было ни у кого: на странице, где за лидом идёт не абзац-сосед, а целый
   блок `.body`, они смыкались вплотную и читались одним абзацем с разным
   кеглем. Поймано глазом на первой же статье с таким устройством. */
.lead + .body { margin-block-start: var(--s4); }
/* То же на выходе из ведомости, списка шагов, подписи и полосной плиты:
   первый абзац блока обнулён `p:first-child`, и без этой отбивки он ложился
   на нижнюю линейку ведомости (аудит 25.09). Классы голые нарочно: с тегом
   вес поднялся бы и перебил правила узкой полосы. */
:is(.record, .steps, .exh, .counts, .attrib, .plate--full) + .body { margin-block-start: var(--s4); }


h1, h2, h3 {
	font-family: var(--font-display);
	font-weight: 500;
	margin: 0;
	text-wrap: balance;
	/* Переноса по слогам здесь нет, и это решение, а не пропуск. Он стоял
	   тут как подстраховка, пока не появился потолок кегля ниже; потолок
	   решает ту же задачу надёжнее, потому что не зависит от словарей
	   переносов в браузере читателя.

	   А вред от него нашёлся в машинном двойнике. Слой движения режет
	   заголовок на строки по отрисованным прямоугольникам, и с разрешённым
	   переносом разрез попадал внутрь слова: в Markdown уходило «a de
	   scription of the terrain». Страница выглядела верно, а машина —
	   ради которой весь корпус и написан — читала разорванное слово. */
	/* Потолок кегля по ширине собственной графы. Перенос по слогам спасает
	   не всегда: словарей переносов в безголовом Chrome нет, и опираться
	   на них проверка не может, а у читателя они есть или нет — как
	   повезёт. Поэтому заголовок ограничен сверху долей той графы, в
	   которой стоит: пока места хватает, работает шкала Приложения 1 —
	   на полосе 1440 px графа держит 816 px, потолок даёт 98 px, а
	   заголовок остаётся своими 80 px, как и записано;
	   когда графа сжимается, кегль идёт за ней, а не за настройкой
	   браузера. Единица `cqi` меряет ту самую графу — в отличие от `vw`,
	   которая мерила бы окно и ничего не знала о поле аппарата. */
	font-size: max(var(--head-floor, 0px), min(var(--size-own), var(--head-cap)));
}

/* Графа объявлена контейнером запроса, иначе `cqi` считается от окна.
   `inline-size` держит только ширину и на высоту блоков не влияет. */
.row > div,
.row > .archive,
.titlepage > div {
	container-type: inline-size;
}

h1 {
	--size-own: var(--size-display);
	--head-floor: var(--head-floor-display);
	line-height: var(--leading-display);
	letter-spacing: var(--tracking-display);
	max-width: 20em;
}

/* Заголовок первого экрана идёт на всю ширину полосы, поперёк обеих колонок.
   Причина измеримая: в основной колонке при 80 px в строку помещается около
   двадцати пяти знаков, и утверждение разваливается на шесть коротких строк.
   На полной ширине строка держит около сорока знаков и читается как
   утверждение, а не как стихотворение. */
.hero-head { grid-column: 1 / -1; margin-block-end: var(--s4); }

h2 {
	--size-own: var(--size-h2);
	line-height: var(--leading-h2);
	letter-spacing: var(--tracking-display);
	max-width: 18em;
}
/* Метка, размеченная заголовком, остаётся меткой: интерлиньяж, мера и
   перенос h2 делали из «Private capital and collections» две строки в
   графе 198 px (аудит 25.09). */
h2.label { line-height: var(--leading-body); max-width: var(--measure); text-wrap: wrap; }

h3 {
	--size-own: var(--size-h3);
	line-height: var(--leading-tight);
	letter-spacing: var(--tracking-display);
}

/* Отбивка абзаца равна ступени 32, а не 16. Замер, из-за которого это
   изменено: кегль 20, интерлиньяж 30, а между абзацами стояло 16 — то
   есть промежуток был вдвое меньше строки, и абзацы слипались в сплошной
   массив. Именно это читается как «книжная, плотная подача»: не длина
   текста, а отсутствие воздуха между его частями. Ступень одна и та же,
   со шкалы, и она чуть больше строки — ровно столько, чтобы абзац
   читался единицей. */
p { margin-block: var(--s4) 0; }
/* Кроме аппарата: пометка на полях и подпись плиты набраны мелким
   моноширинным и стоят тесно нарочно — там абзац не единица чтения, а
   продолжение той же справки. */
.note + .note, .register p + p, figcaption p + p { margin-block-start: var(--s3); }
p:first-child { margin-block-start: 0; }

/* Первый блок после заголовка отбивается на ступень крупнее, иначе текст
   подпирает заголовок снизу и заголовок теряет вес. */
h2 + p,
h2 + .body,
h2 + .areas,
h2 + ol,
h2 + .record,
h2 + .held-block,
h2 + .held-block { margin-block-start: var(--s4); }
/* Подраздел внутри текста: над h3 пауза больше, чем под ним, иначе
   заголовок прилипает к предыдущему абзацу, а не к своему (аудит 25.09:
   было 0 над и 32 под). */
.body h3 { margin-block-start: var(--s5); }
.body h3:first-child { margin-block-start: 0; }
.body h3 + p { margin-block-start: var(--s3); }

/* Лид набирается лёгким начертанием. Это не украшение: третье начертание
   всё равно занимает лицензионную позицию, поэтому оно должно работать. */
.lead {
	font-size: var(--size-lead);
	font-weight: 300;
	line-height: var(--leading-lead);
	color: var(--ink);
	margin-block-start: 0;
}

.small { font-size: var(--size-small); color: var(--muted); }

/* Шапка. Не липкая: институция не бежит за читателем. */
/* Шапка в газетном смысле: знак, навигация и строка стоящих сведений —
   чем практика занимается, откуда работает и на каких языках. Строка
   стоит один раз и меняется раз в год; она не навигация и вести себя
   как навигация не должна, поэтому набрана аппаратом и приглушена.
   Побочно она же отдаёт машине то, что та ищет в первую очередь: род
   занятий, географию и языки, рядом с именем и в самом начале документа. */
/* Шапка держится при прокрутке. На корпусе в восемьдесят адресов уход
   меню за верх кадра означает, что переход на другую страницу стоит
   прокрутки в начало: читатель платит за навигацию расстоянием. Липнет вся
   шапка, а не одна вкладка: знак и стоячая строка — это адрес документа,
   и терять их при чтении незачем.

   Грунт задан явно. Комната рисует его псевдоэлементом, а у липкого
   элемента этот слой уезжает вместе с ним и под ним просвечивает набор. */
/* Управление и аппарат набраны одним и тем же: 12 px, моноширинный,
   приглушённый цвет. Замер показал полное совпадение — «Contact», «Menu» и
   переключатель темы неотличимы от пометки на полях. Для сайта, весь язык
   которого построен на аппарате, это дорогая ошибка: читатель не видит,
   где можно действовать.

   Различение делается ролью цвета, а не размером и не гарнитурой: чернила
   значат «на это можно нажать», приглушённое — «это примечание о чём-то
   другом». Ни один кегль при этом не трогается, характер шапки прежний. */
.masthead {
	background-color: var(--paper);
	/* Шапка — тоже комната: иначе она стоит на голом фоне тела, без
	   зерна, и в тёмной теме шов виден на первом же экране. */
	/* И она выше содержимого. Порядок отрисовки по умолчанию ставит `main`
	   поверх шапки, потому что он идёт позже, и любой блок, вышедший за
	   свою коробку вверх, накрывает меню. Так и случилось: полосная плита
	   до появления стоит сдвинутой на свою высоту вверх, и на 1920 px этой
	   высоты хватило до шапки. */
	z-index: var(--z-raised);
	display: grid;
	/* Обе колонки сжимаемы, и вторая — не меньше первой по важности.

	   Было `1fr auto`. Колонка `auto` не сжимается ниже своего содержимого,
	   и перенос внутри `.nav`, который там объявлен, не включался никогда:
	   полосе всегда хватало места «на бумаге», она просто выходила за край
	   окна. А выйти за край здесь некуда — `overflow-x: clip` стоит и на
	   корне, и на теле, то есть прокрутки вбок нет по замыслу, и всё, что
	   за краем, для читателя исчезает.

	   Замер 16.09.2026 при увеличении ТОЛЬКО ТЕКСТА: корень 24 px, ширина
	   320 — за краем «Contact», «Menu», «Dark» и сам знак, до 112 px;
	   корень 32 px — до 245 px. Восемьдесят восемь страниц из
	   восьмидесяти восьми. Это отказ по 1.4.4: содержимое обязано
	   оставаться доступным при двукратном увеличении текста.

	   `minmax(0, auto)` снимает нижний предел, и дальше работает перенос,
	   уже объявленный в `.nav`. На 1440 и корне 16 px раскладка не
	   меняется ни на пиксель — проверено сравнением высоты шапки. */
	/* Полоса сама решает, в одну строку ей стоять или в две.

	   Было `1fr auto`. Колонка `auto` не сжимается ниже своего содержимого,
	   поэтому перенос внутри `.nav`, объявленный там же, не включался
	   никогда: полосе всегда хватало места «на бумаге», она просто выходила
	   за край окна. А выйти за край здесь некуда — `overflow-x: clip` стоит
	   и на корне, и на теле, то есть прокрутки вбок нет по замыслу, и всё,
	   что за краем, для читателя исчезает.

	   Замер 16.09.2026 при увеличении ТОЛЬКО ТЕКСТА: корень 24 px, ширина
	   320 — за краем «Contact», «Menu», «Dark» и сам знак, до 112 px;
	   корень 32 px — до 245 px. Восемьдесят восемь страниц из
	   восьмидесяти восьми. Это отказ по 1.4.4: содержимое обязано
	   оставаться доступным при двукратном увеличении текста.

	   Проверены четыре поправки. Простое `minmax(0, auto)` вылет убрало, но
	   знак и полоса налезли друг на друга. Переход на flex убрал и вылет, и
	   налезание, но сломал третий элемент шапки — надстрочную строку, — и
	   поднял знак на тридцать пикселей на всех ширинах. Осталось это:
	   колонка не уже шестнадцати кеглей и не уже самой полосы, а при
	   нехватке места ряд переносится сам. На 1440 и корне 16 px высота
	   шапки и положение знака не меняются ни на пиксель. */
	grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), auto));
	align-items: baseline;
	gap: var(--s3);
	padding-block: var(--s4) var(--s3);
	border-bottom: 1px solid var(--rule);
}
.standing {
	grid-column: 1 / -1;
	grid-row: 1;
	/* Гаснет по мере ухода за кромку. Прозрачность ведёт прокрутка, а не
	   таймер: значение ставит слой движения долей `--head-p`, поэтому
	   строка гаснет ровно настолько, насколько уехала, и обратно — тоже. */
	opacity: calc(1 - var(--head-p, 0));
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
	margin: 0;
}
/* Наезд на 810 px. Стоячая строка и меню стояли в одном ряду, и на этой
   ширине им не хватало места: строка шла до 422, меню начиналось на 416.
   Шесть пикселей перекрытия — не мелочь, это буквы поверх букв.

   Правится не ширина, а порядок. До 1200 px шапка держит два столбца —
   знак и меню, — а стоячая строка уходит в свой ряд под знак. С 1200 она
   возвращается в общий ряд, где место для неё есть по замеру. Так шапка
   не зависит от того, сколько букв в названии направления: перенос строки
   решён раскладкой, а не подгонкой. */
@media (min-width: 50.625em) {
	/* Селекторы ограничены шапкой. Без области действия `.mark` цеплял и
	   знак внутри листа меню: пока строка стояла `grid-row: 1`, это
	   совпадало с его естественным местом и не было видно, а как только
	   ряды поменялись местами, знак в листе уехал во второй ряд, под
	   переключатель языка. Незакреплённый селектор — отложенный дефект:
	   он ждёт правки в соседнем месте. */
	.masthead { grid-template-columns: max-content minmax(0, 1fr); gap: var(--s2) var(--gutter); }
	/* По центру ряда, а не по базовой линии: ряд выравнивался по пустому
	   квадрату переключателя, и меню стояло на 5 px ниже слова (аудит 25.09). */
	.masthead > .mark { grid-column: 1; grid-row: 2; align-self: center; }
	.masthead > .nav { grid-column: 2; grid-row: 2; justify-self: end; align-self: center; }
	.masthead > .standing { grid-column: 1 / -1; grid-row: 1; justify-self: start; }
}
/* Общего ряда со стоячей строкой больше нет ни на какой ширине. Он был на
   1200 и выше, и там по замеру место было — пока в меню не прибавился
   пункт. Прибавится ещё один, и всё повторится: раскладка, которая держится
   на том, что содержимого пока хватает, — это отложенный дефект. Строка
   стоит под знаком, в его же графе, и читается тем, чем она является:
   подписью к знаку, а не соседом меню. */

/* Знак практики: её собственный, а не заменитель.

   До 15.09.2026 в шапке стоял сплошной квадратик и слово гротеском. Её
   марка — другая: тонкий квадрат, сквозь который идёт толстый клин с
   вершиной на левой стороне, и оба его луча выходят за рамку. Плюс
   ARTISDOMUS высокой антиквой вразрядку. Сайт не показывал ни того, ни
   другого, и узнать марку в нём было нельзя.

   Знак взят вектором из её PDF — путь разобран покомандно, не обведён, —
   и подставлен маской: так он берёт цвет ролью и выворачивается на
   чернильном грунте одним правилом. Слово остаётся живым текстом:
   Показатели считаются по тому, назовёт ли машина практику, а картинку
   она не прочтёт. Прописные ставит CSS, в разметке остаётся ArtisDomus,
   поэтому доступное имя не меняется. */
.mark {
	display: inline-flex;
	align-items: center;
	/* Зазор и размер знака взяты из её лого замером, а не на глаз: в её
	   файле высота знака равна 1,611 роста прописной, ширина следует
	   пропорции 1,123 : 1, зазор до слова — 0,828 прописной. Рост прописной
	   у Right Didone Spatial Fine — 0,6836 em, отсюда и числа ниже. */
	gap: 0.566em;
	font-family: var(--font-mark);
	font-weight: 400;
	font-size: var(--size-mark);
	text-transform: uppercase;
	letter-spacing: 0.26em;
	/* Разрядка прибавляет пустоту справа от последней буквы; отрицательный
	   отступ возвращает оптическую границу на место. */
	margin-inline-end: -0.26em;
	color: var(--ink);
	text-decoration: none;
}
.mark .device {
	/* Пропорция знака 1,123 : 1 взята из её файла и здесь не округляется:
	   квадрат в нём не квадратный, потому что клин выходит за правую
	   сторону, и подгонка к единице срезала бы вылет. */
	inline-size: 1.237em;
	block-size: 1.101em;
	background: currentColor;
	-webkit-mask: var(--mark-sign) no-repeat center / contain;
	mask: var(--mark-sign) no-repeat center / contain;
	flex: none;
	transition: transform var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
	a.mark:hover .device { transform: scale(1.22); }
}

/* Цель нажатия не меньше 24×24 CSS-пикселей: это требование WCAG 2.2
   уровня AA, и до правки навигация давала 55×20, кнопка темы 47×15,
   а ссылки подвала 109×16. Высоту добирают отступами, а не кеглем:
   кегль здесь несёт иерархию, а не удобство попадания. */
/* Предел кегля знака: слово обязано помещаться в окно.

   «ARTISDOMUS» — одно слово, и перенести его некуда. При увеличении только
   текста до 200 % оно на узкой полосе становится шире окна: замер дал
   491 px при окне 320. Предел в шесть сотых ширины окна вступает в силу
   только там, где слово иначе не поместилось бы: на 1440 и на 768 при
   обычном корне он не срабатывает вовсе, и кегль остаётся тот же, что был.

   Применяется только в шапке. На странице-образце знак показывается в
   своих кеглях нарочно, и предел там мешал бы. */
.masthead .mark { font-size: var(--size-mark-fit); }
/* Ссылка на главную не шире знака: ниже 810 она растягивалась на весь ряд. */
.masthead > .mark { justify-self: start; }

.nav {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--s3);
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	margin-block: calc(var(--s1) * -1);
}
.nav a,
.nav button {
	display: inline-flex;
	align-items: center;
	min-block-size: 24px;
	padding-block: var(--s1);
}
.nav a {
	/* Чернила, а не приглушённое. Замер показал, что навигация набрана
	   ровно тем же, чем пометка на полях: 12 px, тот же моноширинный, тот
	   же цвет — «Contact» и «Menu» неотличимы от примечания к чужому
	   утверждению. Для сайта, весь язык которого построен на аппарате, это
	   дорого: читатель не видит, где можно действовать.

	   Различение сделано ролью цвета, а не кеглем и не гарнитурой: чернила
	   значат «на это можно нажать», приглушённое — «это примечание». Ни
	   один кегль не тронут, характер шапки прежний. */
	color: var(--ink);
	text-decoration: none;
	position: relative;
}
.nav a::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	inset-block-end: -0.28em;
	block-size: 1px;
	background: currentColor;
	transform: scaleX(0);
	transform-origin: 100% 50%;
	transition: transform var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
	.nav a:hover { color: var(--ink); }
	.nav a:hover::after { transform: scaleX(1); transform-origin: 0 50%; }
}

/* Ссылка, занимающая абзац целиком, — не встроенная в предложение, и
   исключение WCAG 2.2 для встроенных целей на неё не распространяется.
   Замер дал высоту 16–20 px при минимуме 24. Высота добирается отступом,
   кегль не трогается: он несёт иерархию, а не удобство попадания.
   Абзац назван классом: `:only-child` не видит текстовых узлов и цеплял
   186 ссылок внутри предложений — строка росла, подчёркивание уходило
   под коробку, хвост « · Glossary» падал на отдельную строку (аудит 25.09).
   Все 73 абзаца из одной ссылки несут `src-entry` (`.источники.mjs`). */
p.src-entry > .lnk,
.sitemap .lnk {
	display: inline-flex;
	align-items: center;
	min-block-size: var(--target);
	padding-block: var(--s1);
}

/* ── Портрет в записи художника ────────────────────────────────────────
   Квадрат 512 на 512, тот же кадр, что в ведомости на главной. Ставится в
   графу аппарата, а не в основную колонку: портрет — это метка записи, а
   не работа. Работа получает плиту во всю ширину и подпись с источником;
   портрет получает поле и ту же подпись мельче. */
.portrait {
	margin: var(--s4) 0 0;
	max-width: 13rem;
}
.portrait img {
	display: block;
	inline-size: 100%;
	block-size: auto;
	filter: grayscale(1) contrast(1.04);
}
.portrait figcaption {
	margin-block-start: var(--s2);
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	line-height: var(--leading-tight);
	color: var(--muted);
}
.portrait .who { color: var(--ink); }
.rk .portrait .who, .on-ink .portrait .who { color: var(--fg); }
.portrait .src { display: block; margin-block-start: var(--s1); }
@media (min-width: 50.625em) {
	.portrait { max-width: 15rem; }
}

/* ── Кнопка обращения ──────────────────────────────────────────────────
   Единственный элемент сайта, который выглядит нажимаемым и обещает
   действие. До неё на странице не было ни одного места, где читатель,
   решивший написать, мог бы это сделать, не долистав до подвала.

   Рисуется рамкой, а не заливкой: заливка акцентом на бумаге даёт 6,82 и
   проходит, но на чернилах акцент даёт 1,73 и порога не берёт ни при каком
   кегле. Рамка выводится из ролей грунта и работает на обоих. */
.cta {
	/* Кнопка не шире своей колонки. Без этого она держит ширину по
	   содержимому и при крупном кегле выходит за край окна: «Write to the
	   practice» с отбивками давало 447 px при окне 390. */
	max-inline-size: 100%;
	/* Гарнитура своя: в подвале кнопка наследовала моноширинный и была
	   шире и тусклее той же кнопки на странице (аудит 25.09). */
	font-family: var(--font-text);
	display: inline-flex;
	align-items: center;
	gap: var(--s2);
	min-block-size: 44px;
	padding: var(--s2) var(--s4);
	border: 1px solid var(--rule-strong);
	color: var(--ink);
	text-decoration: none;
	font-size: var(--size-small);
	transition: background-color var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.cta::after {
	content: "";
	inline-size: 0.42em;
	block-size: 0.42em;
	background: var(--accent);
	flex: none;
	transition: transform var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
	.cta:hover { background: var(--ink); color: var(--paper); }
	.cta:hover::after { transform: scale(1.4); }
}
.cta:focus-visible { background: var(--ink); color: var(--paper); }
.rk .cta, .on-ink .cta { color: var(--fg); }
.rk .cta::after, .on-ink .cta::after { background: var(--accent-on-ink); }
.rk .cta:hover, .on-ink .cta:hover { background: var(--paper); color: var(--ink); }

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

   Залитая кнопка при этом не громче остального сайта: цвет тот же
   чернильный, что у текста, площадь маленькая, никакого выделения цветом
   нет. Меняется вес, а не характер. */
.cta--solid {
	background: var(--ink);
	color: var(--paper);
	border-color: var(--ink);
}
.cta--solid::after { background: var(--paper); }
@media (hover: hover) {
	/* На наведении заливка снимается, а не усиливается: кнопка «открывается»
	   под курсором. Обратное движение к обычной кнопке, у которой заливка
	   на наведении появляется, даёт паре различимость на ощупь. */
	.cta--solid:hover { background: transparent; color: var(--ink); }
	.cta--solid:hover::after { background: var(--ink); }
}
.rk .cta--solid, .on-ink .cta--solid { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.rk .cta--solid::after, .on-ink .cta--solid::after { background: var(--ink); }
@media (hover: hover) {
	.rk .cta--solid:hover, .on-ink .cta--solid:hover { background: transparent; color: var(--fg); }
	.rk .cta--solid:hover::after, .on-ink .cta--solid:hover::after { background: var(--fg); }
}

/* Мягкий путь стоит рядом с действием, а не под ним: читателю, который не
   готов писать сегодня, нужен второй ход, и он не должен выглядеть отказом
   от первого. */
.actions {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--s3) var(--s4);
}
/* В строке текста кнопка не должна прилипать к абзацу сверху. */
p > .cta { margin-block-start: var(--s2); }

/* ── Указатель сайта ────────────────────────────────────────────────────
   Меню из четырёх ссылок держалось ровно пока страниц было четырнадцать.
   Корпус идёт к восьмидесяти адресам, и полоса в шапке на них не
   раскладывается: либо переносится в три строки, либо начинает выбирать,
   какие разделы читателю показать. Поэтому в шапке стоит одна вкладка, а
   за ней — лист указателя во весь экран.

   Лист собран `05-сборщики/.menu.mjs` из файлов на диске и одинаков на
   всех страницах. В нём только написанное: пункт, который не нажимается,
   обещает страницу, которой нет, поэтому заказанные названия стоят на
   /contents, а не здесь.

   Устройство — `<details>`. Без сценария вкладка всё равно открывает лист
   штатным поведением браузера, и указатель остаётся достижимым; сценарий
   добавляет к этому ход кадра, Esc и возврат фокуса. Выпадающая панель на
   кнопке с `hidden` дала бы обратное: без сценария меню исчезает совсем. */
/* Закрытый лист измеряется как коробка 192×192 при `position: fixed;
   inset: 0`, и это не дефект, хотя выглядит им. Chromium держит закрытое
   содержимое `<details>` под `content-visibility: hidden`, а это свойство
   вводит containment — то есть делает `::details-content` блоком-контейнером
   для потомков с фиксированным положением. Отсюда и размер: лист меряется
   по контейнеру, а не по кадру. `checkVisibility()` в обоих режимах даёт
   false, `elementFromPoint` в центре кадра листа не находит.

   Записано, потому что я на этом ошибся: принял артефакт замера за
   отрендеренное меню и полез чинить работающее. `display` на самом
   `<details>` не задаётся уже по другой причине — ширину и выравнивание
   даёт родительское меню, и лишнее значение здесь только повод для
   расхождения между движками. */
.index { align-items: center; }
/* У вкладки квадрата нет. Он стоял и на ней, и на кнопке темы, и владелец
   промахнулся дважды: два соседних управляющих элемента с одинаковым
   значком читаются как один. Значок остаётся у темы, где он показывает
   состояние; вкладка отличается словом. */
.index-tab {
	display: inline-flex;
	align-items: center;
	min-block-size: 24px;
	padding-block: var(--s1);
	color: var(--ink);
	cursor: pointer;
	list-style: none;
}
/* Треугольник браузера снимается в обеих записях: в Safari он рисуется
   псевдоэлементом WebKit, в остальных — свойством списка. */
.index-tab::-webkit-details-marker { display: none; }
.index-tab::marker { content: ""; }
.index-tab .device {
	inline-size: 0.42em;
	block-size: 0.42em;
	background: var(--accent);
	flex: none;
	transition: transform var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
	.index-tab:hover { color: var(--ink); }
	.index-tab:hover .device { transform: scale(1.22); }
}
.index[open] .index-tab { color: var(--ink); }
.index[open] .index-tab .device { transform: scale(1.22); }

/* Закрытый лист не рисуется и не меряется. Chrome оставляет содержимому
   закрытого `<details>` коробку: она не красится, но прямоугольники у неё
   есть, и лист, лежащий за правым краем, добавлял странице 136 px вбок.
   Проверка ширин это видела и печатала «ЕДЕТ» на всех страницах корпуса.
   Закрывающий ход при этом не ломается: он играет, пока `open` ещё стоит,
   и снимает признак уже по окончании. */
.index:not([open]) .sheet { display: none; }
.sheet {
	position: fixed;
	inset: 0;
	z-index: var(--z-overlay);
	background-color: var(--ink);
	overflow-y: auto;
	overscroll-behavior: contain;
	padding-block: var(--s4) var(--s7);
	padding-inline: var(--page-pad);
	/* Роли фокуса и выделения выводятся из грунта листа, как в чернильной
	   комнате: кольцо, выведенное из чернил, на чернилах невидимо. */
	--focus: var(--paper);
	--select-bg: var(--paper);
	--select-fg: var(--ink);
}
/* Без сценария лист встаёт в поток, а не поверх кадра. Разница не
   косметическая: закрывает лист та же вкладка, которая его открыла, а
   вкладка стоит в шапке — и полноэкранный лист её накрывает. Читатель без
   JavaScript открыл бы указатель и не смог его закрыть, потому что кнопка
   «Close» без сценария ничего не делает. В потоке лист ведёт себя как
   чернильная комната сайта: полоса под шапкой, и вкладка над ней видна. */
html:not(.js) .sheet {
	position: static;
	inset: auto;
	overflow: visible;
}
html:not(.js) /* Переключатель издания стоит в верхней строке листа, рядом с закрытием:
   он относится ко всему сайту, а не к столбцу, под которым оказался
   по остаточному принципу. В столбце «Artists» он читался как девятый
   художник. */
.sheet-lang {
	margin: 0;
	justify-self: end;
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	letter-spacing: var(--tracking-label);
}
/* Переключатель изданий. Текущее издание — состояние, а не ссылка: оно
   набрано полными чернилами и не нажимается, остальные приглушены. Так
   читателю видно и сколько изданий есть, и какое он читает. Разделитель
   рисуется псевдоэлементом, а не ставится в разметку: с приходом
   арабского список меняется в одном месте, и лишняя точка в конце не
   появится сама. */
.lang {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: var(--s1) 0;
	margin: 0;
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
}
.lang > * + *::before {
	content: "\00b7";
	margin-inline: var(--s2);
	color: var(--rule-mid);
}
.lang [aria-current] { color: var(--fg); }
.lang a { color: var(--muted); text-decoration: none; }
@media (hover: hover) {
	.lang a:hover { color: var(--fg); }
}
.sheet-lang a { color: var(--muted); text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
	.sheet-lang a:hover { color: var(--fg); }
}

.index-close { display: none; }

/* Язык и закрытие стояли вплотную, и по «Édition française» промахивались
   в «Close». Между ними теперь целая графа, а не отступ: закрытие уходит к
   краю кадра, язык остаётся при знаке. */
.sheet-top {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
	/* Колонки сжимаемы, и знак не крупнее окна.

	   Было `max-content 1fr max-content`. Крайние колонки по содержимому не
	   сжимаются, и на узкой полосе три колонки вместе давали 350 px в поле
	   288: лист получал 174 px боковой прокрутки ВНУТРИ наложения, а кнопка
	   «Close» — единственный видимый способ его закрыть — стояла целиком за
	   правым краем окна. Замер 16.09.2026 на 320 и 390 px.

	   Наложение с прокруткой в две стороны и органом управления за кадром —
	   это не теснота, а потерянное управление. */
	align-items: baseline;
	gap: var(--s3) var(--s5);
	max-width: var(--page-max);
	margin-inline: auto;
	padding-block-end: var(--s3);
	border-bottom: 1px solid var(--rule);
}
.sheet-top .mark {
	color: var(--fg);
	/* Тот же предел, что и в шапке: слово знака одно и перенести его
	   некуда, а поле листа на узкой полосе уже самого слова. */
	font-size: var(--size-mark-fit);
}
/* Фигура знака в листе меню брала акцент, и это было единственное место
   сайта, где знак набран двумя красками. Правило применения говорит
   обратное — фигура берёт цвет слова, — и правило право: акцент на этом
   сайте метит аппарат и переход, а знак не то и не другое. Вторая краска
   в знаке превращала подпись издания в логотип. Снято 15.09.2026 по
   разбору; фигура берёт `currentColor`, как и везде. */
.index-close {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
	background: none;
	border: 0;
	cursor: pointer;
	min-block-size: 24px;
	padding-block: var(--s1);
}
@media (hover: hover) and (pointer: fine) {
	.index-close:hover { color: var(--fg); }
}
.sheet-in {
	display: grid;
	gap: var(--s5) var(--gutter);
	grid-template-columns: minmax(0, 1fr);
	max-width: var(--page-max);
	margin-inline: auto;
	margin-block-start: var(--s5);
}
@media (min-width: 50.625em) {
	.sheet-in { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	/* Пять групп в четырёх колонках: «Case studies» (две ссылки) стоит под
	   «The practice», остальные три занимают по колонке во всю высоту.
	   Пятая колонка от 80em снята (аудит 25.09): на 1024×768 художники
	   уходили под сгиб (963 при окне 768), на 1280 колонка в 166 px ломала
	   восемь названий. Порядок групп задаёт `.menu.mjs`. */
	.sheet-in { grid-template-rows: auto 1fr; }
	.sheet-col:nth-child(1) { grid-column: 1; grid-row: 1; }
	.sheet-col:nth-child(2) { grid-column: 1; grid-row: 2; }
	.sheet-col:nth-child(3) { grid-column: 2; grid-row: 1 / span 2; }
	.sheet-col:nth-child(4) { grid-column: 3; grid-row: 1 / span 2; }
	.sheet-col:nth-child(5) { grid-column: 4; grid-row: 1 / span 2; }
}
/* Пятая колонка на широком экране, и это замер, а не вкус.

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

   Замерено на 1440×900: низ листа был на 1555, то есть на 655 px за кромкой
   окна; высоты всех четырёх ячеек — 804 при содержании 366, 114, 199 и 804.
   Одна `align-items: start` убирает растяжку, но не переносит художников:
   низ остаётся 1555. Пять колонок дают 954 — за кромку уходит 54 px.

   Порог 80em, а не 75: на 1200 пять колонок дают около 220 px на колонку, и
   «Private capital and collections (23)» ломается на три строки. */
.sheet-in { align-items: start; }
.sheet-col { display: grid; align-content: start; }
.sheet-col .label { margin-block-end: var(--s2); }
.sheet-col a {
	display: block;
	/* Гарнитура текста, а не аппарата. Лист стоит внутри меню, а меню
	   набрано моноширинным, и наследование делало из указателя ведомость
	   машинных строк. Содержание на главной — та же по смыслу вещь — набрано
	   текстовой гарнитурой, и указатель обязан читаться так же. */
	font-family: var(--font-text);
	padding-block: var(--s2);
	padding-inline: var(--s2);
	margin-inline: calc(var(--s2) * -1);
	/* Линейка рисуется внутри поля, а не рамкой: отрицательное поле под
	   заливку наведения выносило рамку на 8 px за колонку (аудит 25.09). */
	border-top: 0;
	position: relative;
	color: var(--fg);
	text-decoration: none;
	font-size: var(--size-small);
}
.sheet-col a::before {
	content: "";
	position: absolute;
	inset-block-start: 0;
	inset-inline: var(--s2);
	border-top: 1px solid var(--rule);
	pointer-events: none;
}
.sheet-col a.more {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
}
/* Метка текущей страницы стоит выше выворотки: вес одинаковый, значит
   решает порядок. Стояла ниже — и выбранный пункт при наведении
   набирался приглушённым по своей же заливке, то есть исчезал. */
.sheet-col a[aria-current="page"] { color: var(--muted); }
.sheet-col a[aria-current="page"]::after {
	content: "";
	display: inline-block;
	inline-size: 0.42em;
	block-size: 0.42em;
	margin-inline-start: 0.55em;
	background: var(--accent);
}

/* Наведение выворачивает пункт целиком и без перехода. Мягкое затухание
   здесь читалось бы подсветкой; резкая замена грунта читается тем, чем
   она является, — выбором строки. Пара считана: бумага на чернилах и
   чернила на бумаге — те же две роли, что несут всю страницу. */
@media (hover: hover) and (pointer: fine) {
	.sheet-col a:hover { background: var(--paper); color: var(--ink); }
	.sheet-col a:hover.more { color: var(--ink); }
}
.sheet-col a:focus-visible { background: var(--paper); color: var(--ink); }

/* ── Содержание ─────────────────────────────────────────────────────────
   Страница ведёт себя как документ, поэтому у неё есть содержание, а не
   меню-гамбургер. Отточие — не украшение: оно связывает название раздела
   с его номером через всю ширину, как в оглавлении отчёта, и заодно даёт
   первому экрану воздух, которого без изображений взять негде. */
/* Метка раздела. Правило потерялось при полной перезаписи файла, и десять
   меток рендерились кеглем 20 px основной гарнитурой вместо 11 px
   моноширинной: раздел открывался не пометкой аппарата, а вторым
   заголовком, который спорил с настоящим. */
.label {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-label);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
	margin-block-end: var(--s2);
}

.toc-label { grid-column: 1 / -1; margin-block: var(--s5) 0; }
.toc {
	grid-column: 1 / -1;
	margin-block-start: var(--s2);
	border-top: 1px solid var(--rule);
}
/* Содержание встаёт в ту же сетку, что и разделы: метка на полях, записи
   в основной колонке. Отдельно висящая метка над таблицей читалась как
   подпись к чужому блоку и оставляла провал в середине первого экрана. */
@media (min-width: 50.625em) {
	.toc-label { grid-column: 1; margin-block-start: var(--s5); }
	.toc {
		grid-column: 2;
		margin-block-start: var(--s5);
		columns: 2;
		column-gap: var(--gutter);
	}
}
.toc a {
	display: flex;
	align-items: baseline;
	gap: var(--s2);
	padding-block: var(--s2);
	border-bottom: 1px solid var(--rule);
	color: var(--ink);
	text-decoration: none;
	break-inside: avoid;
	font-size: var(--size-small);
}
.toc .lead-dots {
	flex: 1 1 auto;
	block-size: 0;
	border-bottom: 1px dotted var(--rule-mid);
	transform: translateY(-0.3em);
}
.toc .n {
	flex: none;
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	color: var(--muted);
}
.toc .t { transition: transform var(--dur-fast) var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
	.toc a:hover .t { transform: translateX(var(--s1)); }
	.toc a:hover .n { color: var(--ink); }
}

/* Вопрос покупателя набирается дисплейной гарнитурой и закавычен: это чужая
   речь, и она отбивается рисунком и кавычками, а не курсивом. Курсива у
   неогротеска в поставке нет, и вводить его значит платить за ещё одно
   начертание ради одного блока. */
/* Четыре направления — ведомость, а не сетка два на два. В сетке ячейки
   расходились по высоте, и раздел читался таблицей с рваными клетками;
   строка во всю ширину делает разницу в длине горизонтальной, а не
   вертикальной. Ведомость здесь та же, что у художников и у библиотеки,
   но набрана крупнее: это четыре утверждения, а не восемь имён. */
/* ── Плита направления ─────────────────────────────────────────────────
   Раньше здесь была ведомость: четыре одинаковых ряда во всю ширину,
   разделённых волосяной линейкой. Ряд работал, но не отвечал: наведение
   двигало вопрос на четыре пикселя и рисовало полоску на поле. По
   собственному правилу практики «отвечает только то, что можно нажать» —
   движение либо что-то показывает, либо его нет.

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

   Проверка, которой не проходит шаблон: замени текст на «рыбу» — и
   композиция сломается, потому что ширины выведены из этих четырёх
   вопросов, а не назначены. Сетка одинаковых карточек с «рыбой»
   выглядит ровно так же, потому что её единственное содержание — что их
   четыре. */
.areas {
	margin-block-start: var(--s5);
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	column-gap: var(--s3);
	row-gap: var(--s4);
}
.area {
	/* Направление хода и задержка входа — свойства плиты, а не системы:
	   их ставит скрипт по тому, откуда пришёл указатель. Значения здесь —
	   то, что видит страница без скрипта: ход сверху вниз, задержка есть. */
	--in-o: 0%;
	--out-o: 100%;
	--lead: calc(var(--sched) * 50ms);
	grid-column: 1 / -1;
	position: relative;
	isolation: isolate;
	color: inherit;
	text-decoration: none;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	row-gap: var(--s3);
	/* Поля не симметричны нарочно: приглашение внизу живёт в том воздухе,
	   который иначе пропал бы. В покое плита выглядит нормально
	   заполненной, а не с карманом под невидимой строкой. */
	padding: var(--s4) var(--s4) var(--s3) var(--s3);
	/* Левый край плиты встаёт ровно туда, где прежде стояла чернильная
	   полоска ряда: `inset-inline-start: calc(var(--s3) * -1)`. Полоска и
	   была левым краем поля, которое не нарисовали. Текст при этом
	   остаётся на хребте страницы — вопрос выровнен с h2 и абзацем над
	   ним. */
	margin-inline-start: calc(var(--s3) * -1);
	border-block-start: 1px solid var(--rule-mid);
}
/* Разные ширины — свойство просторного экрана. Порог поднят до 64em, а
   не оставлен на общем 50.625em: замер показал, что на 810 px размахи
   ещё применяются, узкая плита сжимается до 245 px, и вопрос ложится в
   три строки вместо двух. Ширины выведены для 1024 и выше; ниже все
   четыре берут полную ширину, и неравенство просто исчезает. */
@media (min-width: 64em) {
	.sp-12 { grid-column: 1 / -1; }
	.sp-11 { grid-column: 1 / span 11; }
	.sp-10 { grid-column: 1 / span 10; }
	.sp-9  { grid-column: 1 / span 9; }
	.sp-8  { grid-column: 1 / span 8; }
	.sp-6  { grid-column: 1 / span 6; }
}
/* Голова плиты набрана как голова реестра: номер аппаратом слева, имя
   направления у правого края своей ширины. Никакой новой формы. */
.area .head {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: var(--s3);
}
.area .idx {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	font-variant-numeric: tabular-nums;
	color: var(--muted);
	/* Класс `.idx` занят и контейнером Содержания (поле s5, сетка): без
	   этих двух строк номер карточки получал его поле 64 (аудит 25.09). */
	margin-block-start: 0;
	display: block;
}
.area .q {
	color: var(--fg);
	font-family: var(--font-display);
	font-weight: 500;
	font-size: var(--size-h3);
	line-height: var(--leading-tight);
	letter-spacing: var(--tracking-display);
	margin: 0;
}
.area .name {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-label);
	letter-spacing: var(--tracking-label);
	line-height: 1.7;
	color: var(--fg);
	margin: 0;
}
/* Гнездо держит две строки на одном месте. В базовой раскладке они стоят
   друг под другом и обе видны: там, где нет наведения, спрашивать нечего,
   и терять картотечную строку вместе с наведением нельзя. */
.area .slot {
	display: grid;
	row-gap: var(--s2);
	border-block-start: 1px solid var(--rule);
	padding-block-start: var(--s3);
}
.area .scope { font-size: var(--size-small); color: var(--muted); margin: 0; }
.area .aud {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	font-variant-numeric: tabular-nums;
	color: var(--fg);
	margin: 0;
}
.area .open {
	display: none;
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
	margin: 0;
}
/* Грунт плиты — точная миниатюра грунта комнаты: заливка и зерно двумя
   псевдоэлементами. Зерно не украшение: плоский чернильный прямоугольник
   даёт нулевую дисперсию и читается панелью интерфейса, а не бумагой, —
   это уже измерено в §7. Оба слоя въезжают сверху и уходят вниз: вход и
   выход направлены по-разному, ровно то, ради чего здесь стоит `ease-out`,
   а не парная кривая. Масштаб и начало координат взяты у прежней полоски
   ряда без единого изменения. */
.area::before,
.area::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: var(--z-ground);
	transform: scaleY(0);
	transform-origin: 50% var(--out-o);
	/* Выход: без задержки и короче входа. Уйти всегда должно быть легче,
	   чем прийти. */
	transition: transform var(--dur-invert-out) var(--ease-glide);
}
.area::before { background-color: var(--ink); }
/* Грунт въезжает при наведении, при фокусе и при нажатии — и нажатие
   стоит здесь, снаружи запроса о указателе, нарочно. Палец наведения не
   имеет, но нажатие имеет: читатель, придержавший плиту, видит чернила
   до перехода. Так страница говорит одним языком, есть перед ней курсор
   или палец. */
.area:is(:hover, :focus-visible, :active)::before,
.area:is(:hover, :focus-visible, :active)::after {
	transform: scaleY(1);
	transform-origin: 50% var(--in-o);
	/* Кривая другая, чем у остальных откликов сайта, и §8 на это
	   поправлен. `--ease-out` выходит на 90 % пути за треть времени:
	   для полоски в один пиксель это отклик, для поля в 263 пикселя —
	   вспышка, чёрное не приезжает, а возникает. `--ease-glide` за те
	   же 30 % проходит 53 %, то есть край действительно едет и его
	   видно. Задержка в 50 мс — не украшение: она гасит мигание, когда
	   курсор проходит через четыре плиты подряд, и делает приход
	   намеренным. */
	transition: transform var(--dur-invert) var(--ease-glide) var(--lead);
}

/* ── Выворотка следует за краем ────────────────────────────────────────
   Это то место, где медленный вход мог тихо всё испортить. Цвет ролей
   меняется мгновенно, а грунт едет 280 мс — значит, пока край не дошёл,
   нижняя часть плиты остаётся светлой, а текст на ней уже бумажный, то
   есть невидимый. На 140 мс с прежней кривой окно было около 10 мс и не
   читалось; на 280 мс оно стало бы четвертью секунды.

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

   Расписание не назначено, а посчитано. Замер долей высоты на четырёх
   плитах и двух ширинах: низ головы 0,209, вопроса 0,491, гнезда 0,799,
   приглашения 0,939 — разброс между плитами меньше двух сотых. Через
   обратную `--ease-glide` эти доли дают моменты 16, 53, 107 и 175 мс.
   Ошибка расписания вырождается в короткое «не на своём грунте» на
   половине блока, худший случай 36 мс. */
.area .head { --d: calc(var(--sched) * 16ms);  --dx: calc(var(--sched) * 11ms); }
.area .q    { --d: calc(var(--sched) * 53ms);  --dx: calc(var(--sched) * 38ms); }
.area .slot { --d: calc(var(--sched) * 107ms); --dx: calc(var(--sched) * 77ms); }
.area .open { --d: calc(var(--sched) * 175ms); --dx: calc(var(--sched) * 125ms); }
/* Обратный ход. Когда указатель идёт снизу вверх, край входит снизу — и
   блоки должны выворачиваться в обратном порядке, иначе расписание,
   посчитанное под ход сверху, переключает цвет там, где края ещё нет.
   Доли те же, но отсчитанные от низа: 0,895 / 0,650 / 0,355 / 0,131. */
.area.up .head { --d: calc(var(--sched) * 187ms); --dx: calc(var(--sched) * 134ms); }
.area.up .q    { --d: calc(var(--sched) * 108ms); --dx: calc(var(--sched) * 78ms); }
.area.up .slot { --d: calc(var(--sched) * 54ms);  --dx: calc(var(--sched) * 38ms); }
.area.up .open { --d: calc(var(--sched) * 20ms);  --dx: calc(var(--sched) * 14ms); }
.area :is(.head, .q, .slot, .open, .idx, .name, .scope, .aud) {
	transition: color 1ms linear var(--dx),
	            border-color 1ms linear var(--dx),
	            opacity 1ms linear var(--dx);
}
.area:is(:hover, :focus-visible, :active) :is(.head, .q, .slot, .open, .idx, .name, .scope, .aud) {
	transition: color 1ms linear calc(var(--d) + var(--sched) * 50ms),
	            border-color 1ms linear calc(var(--d) + var(--sched) * 50ms),
	            opacity 1ms linear calc(var(--d) + var(--sched) * 50ms);
}
.area::after {
	background-image: var(--grain);
	background-size: var(--grain-size) var(--grain-size);
	opacity: var(--grain-opacity);
}
/* Всё состояние наведения живёт внутри запроса о точном указателе, и это
   не осторожность, а раскладка. Без указателя обе строки видны сразу,
   приглашения нет, выворотки нет: читатель пальцем не может спросить, и
   потому получает больше, а не меньше. Фокус с клавиатуры на таком
   устройстве рисует кольцо на невывернутой плите — это верно, а не
   пробел.

   Кольцо фокуса не переопределяется намеренно. Оно лежит снаружи плиты,
   на бумаге комнаты, и там видно именно чернила; скопировать сюда
   переопределение из `.rk` значило бы сделать кольцо невидимым. */
@media (hover: hover) and (pointer: fine) {
	.area .slot > * { grid-area: 1 / 1; }
	.area .aud { opacity: 0; }
	.area .open { display: block; opacity: 0; }

	.area:is(:hover, :focus-visible, :active) .scope { opacity: 0; }
	.area:is(:hover, :focus-visible, :active) .aud,
	.area:is(:hover, :focus-visible, :active) .open { opacity: 1; }
}

/* Список закрыт линейкой, как ведомость: без неё последний шаг висел. */
ol.steps { margin: var(--s4) 0 0; padding: 0; list-style: none; counter-reset: step; border-bottom: 1px solid var(--rule); }
ol.steps li {
	counter-increment: step;
	display: grid;
	/* Графа номера на шкале и номер на базовой линии текста: 2.5em давало
	   висячий отступ 61–66 px, а номер стоял на 7 px выше строки (аудит 25.09). */
	grid-template-columns: var(--s4) minmax(0, 1fr);
	align-items: baseline;
	gap: var(--s3);
	padding-block: var(--s3);
	border-top: 1px solid var(--rule);
	max-width: var(--measure);
}
ol.steps li::before {
	content: counter(step, decimal-leading-zero);
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	color: var(--muted);
	line-height: var(--leading-body);
}

blockquote {
	margin: var(--s4) 0 0;
	padding-inline-start: var(--s3);
	border-inline-start: 2px solid var(--accent);
	max-width: var(--measure);
}
blockquote p {
	font-family: var(--font-display);
	font-size: var(--size-lead);
	line-height: var(--leading-tight);
}
blockquote cite {
	display: block;
	margin-block-start: var(--s3);
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	font-style: normal;
	color: var(--muted);
}

/* Ссылка чужой печати вынесена из ведомости и поставлена первой. Довод
   простой: во всём разделе это единственная строка, которую читатель может
   проверить, не поверив практике на слово, — и она стояла последней из
   пяти, тем же кеглем, что «Scope» и «Outcome». Раздел доказательств
   начинался с того, что практика говорит о себе сама.

   Кегль второй ступени, не дисплейный: это чужие слова, а не заявление
   практики, и кричать ими было бы дурным тоном. Многоточие в начале стоит
   не для красоты — цитируется причастный оборот, а не предложение, и
   обрезка обязана быть видна. */
blockquote.credit { margin-block: var(--s5) var(--s6); }
blockquote.credit p {
	/* Вес называется явно. Гарнитура здесь дисплейная — она приходит по
	   наследству вместе с кеглем h2, — а вес наследовался от тела, то есть
	   400. Дисплейной гарнитуры в весе 400 не объявлено: браузер строил её
	   сам. Один узел на одной странице, и его нашёл только поимённый счёт
	   начертаний. */
	font-weight: 500;
	font-size: var(--size-h2);
	line-height: var(--leading-tight);
	letter-spacing: var(--tracking-display);
	text-wrap: balance;
}

/* ─── РЕЕСТР ИСТОЧНИКОВ ─────────────────────────────────────────────────

   Аппарат издания. Каждая пометка на полях получает номер в той же
   счётной семье, что разделы 01–09 и плиты Pl. 01–Pl. 09, и разрешается
   строкой внизу: утверждение, источник, дата прочтения, состояние.

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

   Собственная квалификация в реестр не входит. Придержать имя клиента —
   это дискретность; объявить придержанным собственный диплом — это
   признание, и читатель, который проверяет полномочия за десять минут,
   прочтёт вторую строку именно так. */
/* Номер сноски. Цвет берётся ролью чернил, и внутри вывороточной полосы
   это давало чернила по чернилам: контраст 1,00, то есть номер исчезал.
   Переопределять саму роль внутри полосы нельзя — грунт комнаты берёт
   значение из той же роли на том же элементе и полоса перестала бы быть
   чёрной. Поэтому переопределяется сам номер.

   Размер цели здесь 32×16, то есть ниже минимума 24×24. Это разрешено
   исключением WCAG 2.5.8 для целей внутри строки текста: номер стоит
   в предложении, и его высота задана интерлиньяжем окружающего набора.
   У пунктов навигации такого исключения нет, и там высота добрана. */
/* Строка реестра, на которую увёл номер сноски, отмечается на поле и
   остаётся отмеченной. Это не вспышка: читатель пришёл сюда за конкретной
   строкой, и метка отвечает на вопрос «какая именно», пока он читает.
   Отметка та же, что у строки библиотеки, — один жест на весь сайт. */
/* Отступ посадки по якорю берёт высоту липкой шапки, а не ступень шкалы.
   Прежние 64 px её не покрывали: шапка в полном виде занимает 147 px на
   телефоне, и строка, на которую вела сноска, оказывалась под ней целиком.
   Величину ставит слой движения тем же токеном, которым сдвигает саму
   шапку, поэтому она верна и в сжатом виде, и на другом языке. */
.reg { position: relative; scroll-margin-block-start: calc(var(--head-pinned, 9.5rem) + var(--s4)); scroll-margin-block-end: var(--s5); }
#jurisdictions, .reg-head, .register-ledger .label { scroll-margin-block-start: calc(var(--head-pinned, 9.5rem) + var(--s4)); }
/* Заголовок не уходит под липкую шапку при посадке по якорю.

   Отступ посадки стоял у строк реестра и у рядов указателя, а у заголовков
   его не было вовсе. Замер 16.09.2026: из пятидесяти одного якоря на трёх
   страницах восемнадцать приземлялись так, что первая строка цели
   оказывалась под шапкой — на 59–78 px. Все восемнадцать — `h1` и `h2`.
   Разделы спасал собственный верхний отступ ряда, поэтому в счёт они не
   вошли.

   Это бьёт прямо в продукт: ассистент цитирует
   `/research/…/provenance#h-1970`, читатель открывает и видит не заголовок,
   а пустоту под шапкой.

   Запасное значение взято замером, а не на глаз. Без JavaScript шапка не
   сжимается: её нижняя кромка 148 px на 390, 117 на 768 и 113 на 1280 и
   1440 — против 97, 66, 67 и 67 при включённом слое движения, который и
   ставит `--head-pinned`. Отсюда 9,5rem: она покрывает худший случай без
   сценария, а со сценарием не применяется вовсе. */
:is(h1, h2, h3)[id] { scroll-margin-block-start: calc(var(--head-pinned, 9.5rem) + var(--s4)); }
/* Цель ссылки обхода — тоже якорь, и без сценария она приземлялась под
   шапкой на 17 px. Замер 16.09.2026, тот же прогон, что дал заголовки. */
main[id] { scroll-margin-block-start: calc(var(--head-pinned, 9.5rem) + var(--s4)); }
/* Строку в ведомости отмечают на поле, а не плашкой под ней — правило §8,
   и оно остаётся. Но полоска в один пиксель на поле таблицы, которая сама
   шириной в тысячу двести, разрешение спора не показывает: читатель пришёл
   по ссылке из сноски и должен увидеть, куда попал. Полоска стала в три
   пикселя и берёт `--fg`, то есть сильный цвет своего грунта: прежняя
   брала `--ink` напрямую и на чернильной комнате рисовалась чернилами по
   чернилам. Номер строки при этом набирается сильным цветом — отметка
   ставится дважды, на поле и в самой графе, и обе видны без заливки. */
.reg::before {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-start: calc(var(--s3) * -1);
	inline-size: 3px;
	background: var(--fg);
	transform: scaleY(0);
	transform-origin: 50% 0;
}
@keyframes mark-row { to { transform: scaleY(1); } }
.reg:target::before { animation: mark-row var(--dur) var(--ease-out) forwards; }
.reg:target dt { color: var(--fg); }

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

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

   Отличие одно, и оно продиктовано формой. Тема раскрывается кругом из
   кнопки, потому что у события есть точка касания. У перехода по ссылке
   точки нет — ссылок на странице сотня, и раскрывать круг из каждой
   значило бы делать вид, что положение курсора что-то значит. Поэтому
   страница входит горизонтальной кромкой сверху вниз: тем же движением,
   которым въезжает грунт чернильной комнаты и чернила плиты. Край
   жёсткий, старое полотно под ним не двигается и не гаснет.

   Навигация объявлена `auto`: где браузер переходов между документами не
   знает, страница просто меняется мгновенно — это не запасной вариант,
   а отсутствие украшения. */
@view-transition { navigation: auto; }

::view-transition-old(root) {
	animation: none;
	z-index: var(--z-base);
}
::view-transition-new(root) {
	/* Смена темы правит раскрой скриптом и метит корень классом. Переход
	   между страницами класса не несёт, поэтому кромку получает только он:
	   иначе ключевые кадры и скрипт спорили бы за одно свойство. */
	/* Та же поправка, что на теме. Замена целого полотна — событие с
	   началом и концом, и кривая ему нужна парная: `--ease-glide` не имеет
	   старта вовсе, страница входила с полной скоростью и тормозила,
	   отчего читалась как рывок, а не как ход. */
	animation: var(--dur-invert) var(--ease-pair) both page-wipe;
	z-index: var(--z-raised);
}
:root.theming::view-transition-new(root) { animation: none; }
@keyframes page-wipe {
	from { clip-path: inset(0 0 100% 0); }
	to   { clip-path: inset(0 0 0 0); }
}
@media (prefers-reduced-motion: reduce) {
	@view-transition { navigation: none; }
}
/* Смешивание снимается: при `mix-blend-mode: plus-lighter`, который стоит
   по умолчанию, две темы на границе складываются и дают светящийся ободок.
   Он и есть тот самый мягкий край, которого здесь быть не должно. */
::view-transition-old(root),
::view-transition-new(root) { mix-blend-mode: normal; }

.note-n {
	font-variant-numeric: tabular-nums;
	color: var(--ink);
	text-decoration: none;
	border-bottom: 1px solid var(--rule-strong);
	margin-inline-end: 0.4em;
}
.rk .note-n, .on-ink .note-n {
	color: var(--fg);
	/* Роль, а не пересчёт: значение было выписано тем же выражением, каким
	   объявлена сама роль выше. Две записи одного числа расходятся при
	   первой же правке, и расходятся молча. */
	border-bottom-color: var(--rule-strong);
}
@media (hover: hover) and (pointer: fine) {
	.note-n:hover { border-bottom-color: currentColor; }
}
.register-block .num { font-size: var(--size-h3); }
.wall-note { grid-column: 1 / -1; margin-block: 0 var(--s4); }

.sources { margin-block-start: var(--s4); border-top: 1px solid var(--rule-mid); }
.sources dl { margin: 0; }
.reg-head,
.reg {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--s1);
	padding-block: var(--s3);
	border-bottom: 1px solid var(--rule);
}
.reg-head {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-label);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
	padding-block: var(--s2);
	display: none;
}
.reg dt {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	font-variant-numeric: tabular-nums;
	color: var(--muted);
}
.reg dd { margin: 0; font-size: var(--size-small); }
/* Моноширинный означает «величина, которую сверяют»: источник и дата.
   Состояние — предложение, и набирать его аппаратом значило гнать прозу
   в графу шириной в тридцать знаков: худшая ячейка шла в тринадцать
   строк. Графа расширена долями с 263 до 330 px, а лицо приведено к
   тому, что в этой ячейке на самом деле стоит. Утверждение слева уже
   набрано текстовой гарнитурой — теперь оба предложения строки набраны
   одинаково, а обе величины остаются аппаратом. */
/* Длинное слово в узкой графе не переносится и вытекает в соседнюю —
   буквы ложатся на буквы, а коробка при этом не растёт, поэтому проверка
   по коробкам такого не видит. Перенос разрешён внутри слова. */
.reg .s, .reg .d, .reg .c { overflow-wrap: anywhere; }
.reg .s, .reg .d {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	line-height: var(--leading-tight);
	color: var(--muted);
}
.reg .t {
	font-size: var(--size-small);
	line-height: var(--leading-body);
	color: var(--muted);
}
/* Утверждение и состояние берут `--fg`, а не чернила напрямую. Разница
   видна только тогда, когда реестр попадает на чернильный грунт: чернила
   по чернилам дают 1,00, то есть колонка утверждений исчезает целиком.
   Роль `--fg` переворачивается вместе с комнатой и на бумаге даёт ровно
   те же чернила. Поймано замером отрисованного цвета в тот час, когда
   блок реестра стал чернильной комнатой; чтение файла показывало
   правило, которое выглядело верным. */
.reg .c { color: var(--fg); }
/* Состояние набирается полным цветом: это единственное, ради чего строку
   читают повторно, и приглушённым оно теряется. */
.reg .t > b { color: var(--fg); }
/* Между 640 и 1024 таблица в пять граф не помещается, но и складывать
   номер над строкой незачем: номер уходит в свою графу, остальное
   ложится столбиком рядом. */
/* Контрольных точек ровно пять, как называет Приложение: 640, 810, 1200,
   1280 и 1536. Таблица реестра сначала раскрывалась на 1024 — шестой
   точке, которой в системе нет, — и теперь раскрывается на 1200, а между
   640 и 1200 держит промежуточную раскладку. */
@media (min-width: 40em) and (max-width: 74.999em) {
	.reg {
		grid-template-columns: 2.5em minmax(0, 1fr);
		column-gap: var(--s3);
	}
	.reg dt { grid-row: 1 / span 4; }
}
@media (min-width: 75em) {
	.reg-head { display: grid; }
	.reg-head,
	.reg {
		/* Графы в долях, а не в em и не в rem. Em считался бы от кегля
		   строки, который меняется по ступеням шкалы; rem растёт вместе
		   с пользовательской настройкой базового кегля, и при тексте
		   200 % таблица переставала помещаться. Доли помещаются всегда. */
		/* Доли пересчитаны по замеру. При 4-3-2-5 графа состояния получала
		   263 px и худшая ячейка шла в тринадцать строк моноширинного, а
		   графа утверждения — 210 px. Источник и дата — короткие и всегда
		   одной длины: «Positioning study», «3 Sep 2026». Им хватает
		   меньшего, и отданное идёт туда, где текст. */
		grid-template-columns: auto minmax(0, 4.8fr) minmax(0, 2.6fr) minmax(0, 1.8fr) minmax(0, 6.3fr);
		column-gap: var(--s3);
		align-items: baseline;
	}
	.reg .d { font-variant-numeric: tabular-nums; }
}

/* ─── ДВИЖЕНИЕ ──────────────────────────────────────────────────────────

   Движение объясняет состояние и непрерывность, а не украшает. Отвечает
   только то, что можно нажать: плита каталога состояния наведения не имеет,
   потому что плита в каталоге не интерактивна, и масштабировать при
   наведении чужое произведение значило бы его кадрировать.

   Кривые разведены по смыслу, а не по вкусу. Отклик наведения идёт по
   ease-out: замер показал, что на ease-pair первые 45 мс из 140 дают ход
   0,14, и это читается как задержка, а не как отклик. Парная кривая
   остаётся там, где состояние действительно парное: раскрытие и закрытие.

   Длительностей две, кривых две, свойства только opacity и transform. */

/* Ссылка в тексте. Линия под ней несёт фирменный цвет, а набор остаётся
   чернилами, и это решено замером, а не вкусом.

   Соблазн был обратный: покрасить самоё слово, раз палитра объявляет пару
   «accent на бумаге» и та берёт 6,82. Но ссылка стоит не на бумаге — она
   стоит внутри строки чернил, и мерить надо её против соседей. BROWN
   MADDER против ROYAL NAVY даёт 1,73, против приглушённого — 1,08. То
   есть крашеное слово отличается от соседнего почти только оттенком, а
   для дейтеранопа не отличается ничем: получилась бы ссылка, которую
   видно только тому, кто и так знает, где она.

   Линия же лежит на бумаге, и там акцент берёт свои 6,82 против 3,24 у
   волосяной ступени. Цвет попадает туда, где у него есть
   контраст, и делает работу — отмечает, а не украшает. На чернильном
   грунте берётся своя ступень акцента, иначе линия пропадёт в фоне.

   Движение прежнее: при наведении поверх рисуется линия от начала строки,
   при уходе убирается в конец. Точка отсчёта не анимируется, поэтому вход
   и выход разнонаправлены, и это читается жестом, а не лампочкой. */
.lnk {
	color: inherit;
	text-decoration: none;
	position: relative;
	padding-block-end: 0.06em;
	background-image: linear-gradient(var(--accent), var(--accent));
	background-size: 100% 1px;
	background-repeat: no-repeat;
	background-position: 0 100%;
}
.rk .lnk, .on-ink .lnk { background-image: linear-gradient(var(--accent-on-ink), var(--accent-on-ink)); }
.rk .lnk::after, .on-ink .lnk::after { background: var(--accent-on-ink); }
/* Линия жеста — 2 px поверх постоянной в 1 px. Пока обе были по 1 px одного
   цвета на одном месте, жест шёл, но глазом не читался вовсе: рисовалась
   линия поверх такой же. Найдено 23.09.2026 на странице образцов движения. */
.lnk::after {
	content: "";
	position: absolute;
	inset-inline: 0;
	inset-block-end: 0;
	block-size: 2px;
	background: var(--accent);
	transform: scaleX(0);
	transform-origin: 100% 50%;
	transition: transform var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
	.lnk:hover::after { transform: scaleX(1); transform-origin: 0 50%; }
}

/* Нажатие — основное состояние на касании, а не запасное. Правила наведения
   остаются под защитой (hover: hover): вынести их наружу значит вернуть
   залипающий ховер, при котором строка остаётся отмеченной после того, как
   палец ушёл, и возвращается отмеченной при возврате назад.

   Повторяется тот же жест, что и при наведении, поэтому язык у сайта один
   независимо от того, курсор перед ним или палец. */
.nav a:active { color: var(--ink); }
.nav a:active::after { transform: scaleX(1); transform-origin: 0 50%; }
.lnk:active::after { transform: scaleX(1); transform-origin: 0 50%; }
.toc a:active .t { transform: translateX(var(--s1)); }
.toc a:active .n { color: var(--ink); }
.roster .r:active::before { transform: scaleY(1); transform-origin: 50% 0%; }
.roster .r:active .md { color: var(--ink); }
.note-n:active { border-bottom-color: currentColor; }
a.mark:active .device { transform: scale(1.22); }

/* Одно кольцо фокуса на весь сайт. Чернилами и с отступом: видно и на
   бумаге, и на выворотке, и внутри строки списка. */
:where(a, button, [tabindex]):focus-visible {
	outline: 2px solid var(--focus);
	outline-offset: 3px;
	border-radius: var(--radius-1);
}
.roster a:focus-visible,
.toc a:focus-visible { outline-offset: -2px; }

/* ─── ЗЕРНО ─────────────────────────────────────────────────────────────
   Один неподвижный слой на всю страницу поверх грунта и под содержимым.
   Плитка 180 px, поэтому изображение растрируется один раз и повторяется;
   на прокрутке ничего не пересчитывается. Слой не ловит указатель и от
   чтения с экрана скрыт: это материал бумаги, а не содержание. */
body { background: var(--paper); }

/* ─── КОМНАТЫ ───────────────────────────────────────────────────────────
   Грунт меняется от раздела к разделу. Полоса заливается во всю ширину
   окна, а не по ширине колонки: комната — это стена, а стена не кончается
   там, где кончается текст.

   Все пороги жёсткие. Растушёванный переход пробовался и снят: на
   96 px он читается не как падающий свет, а как виньетка, и в тёмной
   теме особенно — ровно тот приём, от которого направление уходит.
   Тон меняется на линии, и линию держит волосяная линейка: это язык
   документа, где новая тетрадь начинается с новой полосы, а не
   затемнение экрана. */
.room { position: relative; }
/* Липкость шапки объявляется после `.room`, и селектор тяжелее на элемент.
   Первая редакция стояла выше и весила столько же: `position: relative` из
   `.room` побеждал по порядку, и замер показал шапку с `top: -1400` —
   то есть уехавшую вместе со страницей. Правило в файле было, и не
   действовало. */
/* Шапка липнет не кромкой, а упором ниже кромки на высоту стоячей строки.
   Тогда при прокрутке строка уходит вверх сама, ровно с той скоростью, с
   какой едет страница, и на месте остаётся ряд со знаком и меню.

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

   Величина упора ставится слоем движения: она равна высоте первого ряда
   вместе с зазором и верхним отступом, и в разных языках и на разных
   ширинах она разная. */
header.masthead {
	position: sticky;
	top: calc(-1 * var(--head-shift, 0px));
	z-index: var(--z-overlay);
}
/* Сжатие при прокрутке. Липкая шапка забирает 147 px из 844 на телефоне —
   каждый шестой пиксель экрана навсегда. При этом всё, что ей нужно после
   первого экрана, — знак и вход в меню: стоячая строка стоит один раз и
   меняется раз в год, читать её по второму разу незачем.

   Смена высоты происходит мгновенно, и это не недоделка. Первая редакция
   собирала её плавно, по потолку и внутреннему отступу, — и ровно этим
   нарушила Приложение 1: анимировать разрешено прозрачность, цвет и
   трансформацию, а высота и отступ гонят пересчёт раскладки на каждом
   кадре. Гейт движения назвал все три свойства поимённо. Плавную высоту
   без пересчёта раскладки дать нечем, значит остаётся выбор между
   нарушением и щелчком; щелчок выбран сознательно и попадает в характер
   остальной моторики. Дрожания на пороге нет: он с гистерезисом, 120
   на сжатие и 60 на разжатие. */
.room::before,
.room::after {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline: calc(50% - 50vw);
	z-index: var(--z-ground);
	pointer-events: none;
}
.room::before { background-color: var(--room, var(--paper)); }

/* ── Выход чернил: снято ───────────────────────────────────────────────
   Чернильный прямоугольник умел выходить за собственную коробку на
   160 px жёстким краем. Замер был хороший — край поднимался на 155 px и
   тормозил по кривой, — и держалось всё в границах. Владелец снял на
   показе: поле читается не как выход чернил, а как лишний чёрный отступ.

   И он прав ещё по одной причине, которая на замере не видна. Масштаб
   применялся к `::before`, а зерно живёт на `::after` и не растягивалось
   вместе с ним. Значит вышедшее поле было чистыми чернилами, а коробка
   полосы — чернилами с зерном, то есть чуть светлее. На стыке стояла
   ступенька, и именно она делала поле похожим на ошибку вёрстки. Ошибка
   исправимая, решение — нет: отступ и без неё лишний.

   Не возвращать. Резкая смена грунта, ради которой это делалось, теперь
   решается самими комнатами, а не выходом одной. */
/* Зерно лежит на грунте и под текстом. Оба псевдоэлемента на одном
   уровне, ::after рисуется позже, поэтому порядок задан разметкой,
   а не числами. Так текст остаётся чистым: зерно есть у бумаги,
   а не у набора. */
.room::after {
	background-image: var(--grain);
	background-size: var(--grain-size) var(--grain-size);
	opacity: var(--grain-opacity);
}
/* Ступени грунта сняты, и это второй заход. В первый я убрал волосяные
   линейки между разделами и решил, что вопрос закрыт, — а видел владелец
   не линии, а сам перепад тона: разделы стояли на 0, 4, 7 и 11 процентах
   подмеса, и в тёмной теме каждая граница читалась как полоса поперёк
   экрана. Линия лишь объясняла перепад; убрав объяснение и оставив
   перепад, я сделал хуже, а не лучше.

   Теперь все разделы стоят на одной бумаге. Единственная оставшаяся
   смена грунта — `.rk`, вывернутая комната: это не ступень на несколько
   процентов, а полная инверсия, и она читается как решение, а не как
   дефект отрисовки. */
.r0, .r1, .r2, .r3 { --room: var(--paper); }
/* Кольцо фокуса выводится из чернил, а грунт этой комнаты и есть чернила:
   на полосе кольцо совпадало с фоном и было невидимо в обеих темах.
   Переопределение стоит здесь, где решается грунт, а не на классе
   типографической выворотки: иначе при второй чернильной комнате дефект
   вернулся бы молча. По той же причине здесь переопределяется и пара
   выделения: она выводится из тех же ролей и на чернилах тоже совпадала
   бы с фоном. */
/* Перечень тот же, что у ролей на чернилах выше, и это не копия ради
   симметрии — это исправление расхождения.

   Роли на чернилах перечисляют `.rk`, `.veil`, наведённую плиту направления
   и `.on-ink`. Здесь стояли только `.rk` и `.on-ink`, и завеса получала
   бумажный набор из первого списка, а кольцо фокуса — чернильное из общих
   токенов. На завесе, залитой чернилами в 94 %, это давало контраст 1,00 в
   обеих темах: у единственного органа управления модального окна кольца не
   было видно вовсе. Замер 16.09.2026, по пикселям.

   Плита направления в этот список НЕ входит, и это не забывчивость.
   Кольцо фокуса лежит снаружи плиты, на бумаге комнаты, и видно там
   именно чернила. Первая редакция этой правки списки уравняла целиком — и
   кольцо на четырёх плитах главной ушло в бумагу по бумаге, контраст 1,00.
   Поймал гейт `.фокус.mjs` в тот же час, на первом же прогоне. */
.rk,
.veil,
.on-ink { --room: var(--ink); --focus: var(--paper); --select-bg: var(--paper); --select-fg: var(--ink); }

/* Источник в ведомости встаёт своей строкой. Внутри подписи к плите он и
   так блочный, а в графе ведомости оставался строчным и слипался с текстом:
   «Both sources give the same year.Source: Pinakothek…». */
.counts .src {
	display: block;
	margin-block-start: var(--s2);
}
.counts .src + .src { margin-block-start: var(--s1); }

/* ── Архив художников ───────────────────────────────────────────────────
   Ведомость и кадр — один прибор. Читатель ведёт глазом по именам, кадр
   показывает работу той строки, на которой он стоит. Раньше это были два
   разных блока: восемь строк и пять снимков рядом, без всякой связи между
   ними, и какая работа чья — приходилось угадывать.

   На узком экране кадр стоит сверху и липнет, перечень идёт под ним: тогда
   листание имён и есть просмотр собрания. На широком они встают рядом, и
   липнет кадр.

   Высота кадра ограничена, а не форма: соотношения сторон у работ от 0,70
   до 1,91, и кадрировать их нельзя. Плиты сложены в одну ячейку сетки —
   видна только текущая, — поэтому высота блока не скачет при переходе от
   вертикальной работы к горизонтальной. */
.archive {
	/* Одна форма на все ширины и на любой базовый кегль читателя: перечень,
	   и под каждым именем — работа этого художника.

	   Раскол на две графы — ведомость слева, липкий кадр справа — прожил
	   четыре захода и дал четыре разные поломки: на планшете ведомости
	   оставалось 24 px и имя вставало по букве в строку; на телефоне кадр
	   липнул сверху, съедал треть экрана и клал подпись на имена; ячейка
	   кадра держала высоту самой высокой из восьми плит и оставляла пустырь
	   под короткими; а при базовом кегле 24 px порог раскола срабатывал
	   там, где места на две графы уже нет, потому что медиазапрос меряет
	   `em` по начальному кеглю, а колонки — по кеглю читателя.

	   Форма карточки не может starve по построению: у неё одна графа. */
	grid-column: 1 / -1;
	display: grid;
	gap: var(--s5);
	align-items: start;
}
/* Архив занимает всю строку, и первая графа оставлена пустой: там проходит
   указатель разделов, набор в неё не заходит. Отступ ставится там же, где
   объявлена сама графа аппарата, — по её наличию, а не по ширине окна. */
@media (min-width: 50.625em) {
	.row > .archive {
		/* Тот же отступ, что у текста, и с той же ширины, где появляется
		   графа аппарата. Раньше он включался только с 75 em, и между 810 и
		   1200 px архив шёл во всю строку — от самого края, под засечками
		   указателя: имя художника проходило прямо через них. */
		padding-inline-start: calc(var(--register) + var(--gutter));
		/* Архив держится в полях страницы. Он был выпущен к самой кромке
		   окна ради места работе — и владелец сказал на это «слишком к
		   правому краю забито всё»: работа и подпись упирались в стекло,
		   поля справа не оставалось вовсе, и стена читалась обрезанной.
		   Место работе даёт порог ниже, а не отнятое поле. */
		margin-inline-end: 0;
	}
	.row > .arch-note { grid-column: 2 / -1; }
}
.arch-plate {
	margin: 0;
	/* Работа стоит в своей записи и видна всегда. Ни прозрачности, ни
	   перехода: скрывать нечего, менять нечего. Прежние `grid-area: 1 / 1`
	   и нулевая прозрачность держали липкий кадр, где восемь плит лежали в
	   одной ячейке и сменяли друг друга по наведению. */
}
.arch-plate img {
	display: block;
	max-block-size: 46svh;
	/* Ширина от потолка и пропорции, а не от загруженной картинки: при
	   `auto` ленивая картинка до загрузки нулевая, и страница росла под рукой
	   до 6000 px (аудит 25.09, F09). `--ar` пишет `.menu.mjs`; без неё
	   значение недействительно и откатывается к `auto`. Выше натурального
	   размера работа не растёт: раньше её ширину упирает колонка. */
	inline-size: calc(46svh * var(--ar));
	max-inline-size: 100%;
	background: var(--paper-raised);
}
.arch-plate figcaption {
	margin-block-start: var(--s3);
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	line-height: var(--leading-tight);
	color: var(--muted);
	max-inline-size: var(--measure);
}
.arch-plate .who { color: var(--fg); }
.arch-plate .src { display: block; margin-block-start: var(--s2); }
.arch-note { margin-block-start: var(--s4); }

/* Первая редакция раскалывала архив здесь, на 810 px. Правило осталось
   жить после того, как порог был поднят до 1100, и молча перебивало новый:
   на 810 ведомости доставалось 194 px, имя вставало в две строки. Снято.
   Раскол объявлен ровно в одном месте, ниже по файлу. */
/* Ниже порога раскола кадр идёт первым: он и есть вход в раздел, а
   ведомость читается под ним. Так же на телефоне и на планшете. */

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

   Здесь она выходит на полную ширину экрана, а подпись остаётся в полях
   набора. Тогда изображение работает знаком препинания в потоке текста:
   текст — во всю страницу с полями, работа — во всю ширину без полей.
   Ритм прокрутки задают они по очереди. */
/* ── Указатель разделов ─────────────────────────────────────────────────
   Двенадцать засечек на непрерывной вертикали документа. Текущая залита и
   крупнее; на наведении и по клавише рядом появляется имя раздела.

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

   Размер клетки 24 px не декоративен: это нижняя граница цели указания по
   SC 2.5.8. Сама засечка 5 px, остальное — поле, за которое можно попасть
   пальцем и мышью. */
.rail { display: none; }
/* Показывается по наличию графы аппарата, а не по ширине окна: класс
   ставит слой движения, разобрав раскладку строки. Медиазапрос «от 75 em»
   врал у читателя с крупным базовым кеглем — при двадцати четырёх это
   1800 px, и в окне 1578 px прибор пропадал, хотя графа под него стояла. */
:root.has-rail {
	.rail {
		display: grid;
		position: fixed;
		inset-block-start: 50%;
		inset-inline-start: calc(var(--rail-x, -100px) - 12px);
		transform: translateY(-50%);
		z-index: var(--z-raised);
	}
	.rail {
		transition: opacity var(--dur-fade) var(--ease-out);
	}
	.rail.is-off { pointer-events: none; }
	/* Указатель раскрывается из точки и в точку собирается. Прозрачность
	   всей шкалы больше не гасится разом: гасли бы и засечки, и движение
	   читалось бы миганием. Двигается каждая засечка своим сдвигом до
	   середины — величину ставит слой движения, потому что шаг между ними
	   задаёт раскладка. */
	.rail a {
		/* Видимость объявлена здесь и снимается в собранном состоянии.
		   Без неё двенадцать засечек оставались в обходе с клавиатуры при
		   нулевой прозрачности: замер табуляции давал двенадцать остановок
		   подряд, на которых кольцо фокуса уезжало за край экрана и
		   читатель терял место. Собранная шкала — это не просто невидимое,
		   это ещё и недоступное указателю, и обход обязан вести себя так
		   же. Найдено разбором 14.09.2026. */
		visibility: visible;
		transition: transform var(--dur-rail) var(--ease-glide),
		            opacity var(--dur-fade) var(--ease-out),
		            visibility 0s;
		/* Раскрытие идёт от середины к краям: ближняя засечка трогается
		   первой. */
		transition-delay: calc(var(--k, 0) * var(--stagger-rail));
	}
	.rail.is-off a {
		transform: translateY(var(--dy, 0px)) scale(0.35);
		opacity: 0;
		/* Скрывается ПОСЛЕ сбора, а не вместо него: задержка равна полной
		   длительности шкалы вместе с разбежкой, поэтому движение видно
		   целиком, а фокус уходит, когда уходить уже нечему. */
		visibility: hidden;
		/* Сбор идёт наоборот, с краёв к середине: крайняя трогается первой,
		   и стопка складывается, а не осыпается. */
		transition-delay: calc((var(--kmax, 0) - var(--k, 0)) * var(--stagger-rail)),
		                  calc((var(--kmax, 0) - var(--k, 0)) * var(--stagger-rail)),
		                  calc(var(--dur-rail) + var(--kmax, 0) * var(--stagger-rail));
	}
	.rail a {
		position: relative;
		display: block;
		inline-size: 24px;
		block-size: 24px;
	}
	.rail a::before {
		content: "";
		position: absolute;
		inset-block-start: 50%;
		inset-inline-start: 50%;
		inline-size: 5px;
		block-size: 5px;
		margin-block-start: -2.5px;
		margin-inline-start: -2.5px;
		/* Инверсия по грунту, а не обводка. Кольцо контрастным цветом
		   читалось именно обводкой — квадрат выглядел выколотым, с рамкой.
		   Теперь засечка и её поле берут цвет комнаты, над которой стоят:
		   на бумаге чернила в поле бумаги, на чернильной комнате наоборот.
		   Поле совпадает с грунтом и потому невидимо; оно работает маской,
		   разрывая вертикаль ровно под квадратом. Класс ставит слой
		   движения каждой засечке отдельно, поэтому на границе двух комнат
		   половина шкалы уже перевернулась, а половина ещё нет — они стоят
		   на разном. Это же решает случай полосной плиты: над снимком поле
		   остаётся цветом комнаты и отделяет квадрат от фотографии. */
		background: var(--ink);
		/* Непогашенная засечка держит семь десятых, а не четыре. При
		   четырёх квадрат оказывался слабее собственного поля: поле шло в
		   полную силу цветом комнаты, квадрат — вполсилы, и поверх снимка
		   пара читалась кольцом, то есть ровно той обводкой, от которой
		   уходили. Сильнее поля — значит квадрат, слабее — значит рамка. */
		opacity: 0.7;
		box-shadow: 0 0 0 2px var(--paper);
		transition: background-color var(--dur-fast) var(--ease-out),
		            transform var(--dur-fast) var(--ease-out);
	}
	.rail a[aria-current="true"]::before { opacity: 1; transform: scale(1.8); }
	.rail a.is-on-ink::before {
		background: var(--paper);
		box-shadow: 0 0 0 2px var(--ink);
	}
	/* Над работой — третий случай, и он старше двух других. Снимки корпуса
	   светлые в любой теме, поэтому обе роли здесь взяты не из темы:
	   чернила по снимку и бумага по снимку. Приглушение снимается: над
	   фотографией полусила читается не отметкой, а грязью. */
	.rail a.is-on-art::before {
		background: var(--ink-on-art);
		opacity: 1;
		box-shadow: 0 0 0 2px var(--paper-on-art);
	}
	.rail-t {
		position: absolute;
		inset-inline-start: calc(100% + var(--s2));
		inset-block-start: 50%;
		transform: translateY(-50%);
		white-space: nowrap;
		opacity: 0;
		pointer-events: none;
		font-weight: 400;
	font-family: var(--font-mono);
		font-size: var(--size-apparatus);
		color: var(--muted);
		background: var(--paper);
		padding-inline: var(--s2);
		transition: opacity var(--dur-fast) var(--ease-out);
	}
	.rail a:hover .rail-t,
	.rail a:focus-visible .rail-t { opacity: 1; }
}

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

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

   Высота считается от кадра за вычетом припаркованной шапки: иначе первая
   строка ушла бы под панель ровно на её высоту. */
/* Издательский знак в пустоте титула.

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

   Знак взят слепым тиснением, а не краской: на бумаге роль `--rule` даёт
   1,35 в светлой теме. Порога здесь нет и быть не может — знак не несёт
   ни одного сведения, которого нет рядом словом, имя практики стоит в
   шапке и в машинном двойнике. Он даёт материал, а не сообщение, и
   ровно поэтому стоит тише набора на порядок.

   Крупно знак появляется на сайте дважды, и каждый раз делает разную
   работу: здесь — чей это корпус, на реестре — кем выпущен его аппарат.
   Третьего раза нет: знак, поставленный там, где ему нечего удостоверять,
   становится узором. */
.titlepage::before {
	content: "";
	position: absolute;
	z-index: var(--z-ground);
	inset-block-start: var(--row-pad-start);
	inset-inline-end: calc(-1 * var(--bleed-out));
	block-size: 15rem;
	aspect-ratio: 597.56 / 532.08;
	background: var(--rule);
	mask: var(--mark-sign) no-repeat center / contain;
	pointer-events: none;
}
/* На узкой полосе пустота над титулом меньше кегля знака, и он налезал бы
   на первую строку. Там он вдвое мельче и прижат к правой кромке. */
@media (max-width: 50.624em) {
	.titlepage::before { block-size: 7rem; }
}
@media print { .titlepage::before { display: none; } }
.titlepage {
	grid-column: 1 / -1;
	display: grid;
	gap: var(--s5);
	/* Пустота над титулом ограничена сверху, а не привязана к высоте окна.
	   Первая редакция задавала блоку высоту в целый кадр и прижимала набор
	   к низу: на окне в 900 px это читалось паузой перед началом, а на
	   высоком окне заголовок уезжал на три четверти вниз, и первый экран
	   становился пустым. Величина, растущая вместе с экраном, — это не
	   композиция, а случайность.

	   Теперь это отступ с потолком: на невысоком экране он берёт четверть
	   кадра, на высоком упирается в 256 px и дальше не растёт. Потолок
	   сложен из ступеней шкалы, а не задан числом. */
	/* Три ограничителя разом, и третий — главный. Доля кадра держит
	   пропорцию на невысоком экране; потолок в 256 px не даёт пустоте расти
	   вместе с окном; а остаток до запаса блока не даёт ей вытолкнуть
	   действие за сгиб. Правило по высоте окна здесь стояло и было хуже:
	   на границе 896 px величина прыгала, и ровно на 900 кнопка снова
	   уезжала вниз. Непрерывное выражение границы не имеет. */
	padding-block-start: min(
		26svh,
		calc(var(--s7) + var(--s6)),
		max(0px, calc(100svh - var(--title-reserve)))
	);
}
/* Совсем низкий кадр — 667 px, самый маленький из живых телефонов. Воздуха
   над титулом там уже нет вовсе, и единственное, что можно отдать, — зазор
   внутри блока. Он ужимается на ступень; заголовок при этом не мельчает,
   потому что кегль задан Приложением 1 и подгонять его под устройство
   значило бы менять шкалу ради одного экрана. */
@media (max-height: 44em) {
	.titlepage { gap: var(--s4); }
	/* На низком кадре пустоты над титулом нет вовсе — отступ схлопывается
	   в ноль, — и знак ложится прямо на первые строки заголовка. Замер на
	   320×568: знак пересекал две строчные рамки h1. Издательский знак
	   существует ради пустоты; там, где пустоты нет, его нет тоже. */
	.titlepage::before { display: none; }
}
/* Титул получает ту же графу аппарата, что и все остальные разделы.

   Найдено снимком, а не рассуждением. На первом экране страница показывала
   заголовок, абзац, две кнопки и 292 px пустоты над ними — то есть ровно
   то, что показывает любой сайт, — тогда как всё, чем эта страница
   отличается, стояло ниже сгиба. Графа аппарата на ней была прочерчена
   вертикальной линейкой и пуста: линейка есть, графы нет.

   Причина была разметочная: `.titlepage` занимал обе колонки, и реестр
   раздела 01 выталкивался под него следующим рядом. Теперь реестр лежит
   внутри титула и берёт первую колонку, а заголовок по-прежнему идёт на
   всю ширину полосы — замер, по которому он там оказался, в силе: в
   основной колонке на дисплейном кегле строка держит около двадцати пяти
   знаков и утверждение разваливается на шесть строк.

   Титульный лист при этом остаётся титульным: воздух над заголовком,
   полная ширина строки и крупный кегль никуда не делись. Меняется одно —
   счёт раздела и его сноска стоят там же, где стоят на всех остальных
   двенадцати разделах, и читатель видит аппарат прежде, чем доберётся до
   первой плиты. */
@media (min-width: 50.625em) {
	.titlepage {
		grid-template-columns: var(--register) minmax(0, 1fr);
		column-gap: var(--gutter);
	}
	.titlepage > .hero-head { grid-column: 1 / -1; grid-row: 1; max-width: none; }
	.titlepage > .register { grid-column: 1; padding-inline-end: var(--s4); }
	/* Место по умолчанию задано положительно, как и у раздела. Селектор по
	   отрицанию здесь оставался и после того, как у ряда его сняли, а
	   комментарий рядом утверждал обратное — то есть файл говорил о себе
	   неправду. Вес понижен `:where()`, поэтому объявления `.hero-head` и
	   `.register` выше по файлу не перебиваются. */
	:where(.titlepage) > div { grid-column: 2; grid-row: 2; }
	.titlepage > .register { grid-row: 2; }
}

/* ── Разворот ───────────────────────────────────────────────────────────
   Один раздел на всю высоту кадра, и в нём одно утверждение. Это тот самый
   недостающий момент, который остаётся в памяти после закрытия вкладки, и
   он сделан не картинкой и не размером кегля, а изоляцией: фраза стоит на
   экране одна, вокруг неё чернила и ничего больше.

   Кегль взят прежний, дисплейный, 48 → 56 → 80 — тот, что задан
   Приложением 1 для заголовка первого уровня. Увеличивать его ради эффекта
   значило бы завести шестую ступень шкалы и разойтись с Приложением на
   ровном месте. Здесь работает не величина буквы, а количество бумаги
   вокруг неё, и это дешевле, честнее и сильнее.

   Выбрана именно эта фраза: из всего, что практика о себе говорит, она
   единственная одновременно проверяема, отличает её от поля и годится
   как прямая цитата — то есть работает и на читателя, и на ассистента,
   который будет собирать ответ. */
.row--statement { min-block-size: 100svh; align-content: center; }
.row--statement > div { max-width: var(--measure); }
.row--statement h2 {
	--size-own: var(--size-display);
	--head-floor: var(--head-floor-display);
	/* Кегль первого экрана — и интерлиньяж первого экрана (аудит 25.09). */
	line-height: var(--leading-display);
	letter-spacing: var(--tracking-display);
	text-wrap: balance;
}
/* Разовый крупный квадрат на вертикали отсюда снят. Он стоял ровно там,
   где теперь идёт указатель разделов, и два разных знака на одной линии
   спорили: один говорил «вот главное утверждение», другой — «вы здесь».
   Второе полезнее и работает на всей странице, а не в одном месте. */
/* Пауза — после заголовка, а не перед каждым блоком текста: на approach
   второй абзац утверждения стоял через 96 (аудит 25.09). */
.row--statement .body { max-width: var(--measure); }
.row--statement h2 + .body { margin-block-start: var(--s6); }
@media (min-width: 50.625em) {
	.row--statement .body { max-width: calc(var(--measure) * 0.82); }
}

/* Линейки между разделами сняты. Довод, по которому они стояли, был такой:
   смена тона на 2–3 % без линии читается как дефект отрисовки. Довод верен
   для двух комнат подряд, и неверен для страницы из двенадцати: владелец
   увидел на прокрутке ряд полосок и назвал их лишними, и он прав — порог
   уже отмечен сменой грунта, а линия отмечает его во второй раз.

   Не возвращать. Если смена тона окажется незаметной, чинить надо шаг
   тона, а не дорисовывать границу поверх него. */
.row { border-top: 0; }

/* Номер раздела остаётся на полях, пока раздел читается. Это не эффект:
   в длинном документе читателю нужно знать, где он находится, а колонка
   аппарата — единственное место, где это можно сказать, ничего не заслонив. */
@media (min-width: 50.625em) {
	/* Упор липкого номера отсчитывается от нижней кромки шапки, а не от
	   кромки кадра. Стояло 32 px при шапке в 49 — номер парковался на
	   семнадцать пикселей под панелью и наполовину пропадал. Владелец
	   показывал это пять раз, и каждый раз я чинил соседнее: сперва
	   отступ раздела, потом посадку по якорю, потом высоту самой шапки, —
	   а перекрывалась именно эта величина, и она в тех правках не
	   участвовала.

	   Высоту припаркованной шапки ставит слой движения: она равна полной
	   высоте минус то, что шапке позволено уехать вверх, и в разных
	   языках и на разных ширинах она разная. Запасное значение со шкалы
	   держит случай без скрипта. */
	.register-inner { position: sticky; top: calc(var(--head-pinned, var(--s5)) + var(--s5)); }
}

/* ── Плита ──────────────────────────────────────────────────────────────
   Изображение входит на страницу не как иллюстрация, а как плита каталога:
   у неё есть номер, подпись музейного образца и источник с датой прочтения.
   Тот же аппарат, что и у текста, поэтому изображение не выпадает из
   системы и не превращает страницу в галерею. */
figure.plate { margin: 0; }
figure.plate img {
	display: block;
	inline-size: 100%;
	block-size: auto;
	background: var(--paper-raised);
}

/* Единый кадр у плиты в колонке. Соотношения сторон снимков идут от 0,70
   до 1,91 — от вертикального листа до широкой панорамы, — и при одинаковой
   ширине колонки это давало высоту от трети экрана до полутора. Вертикальный
   ритм прокрутки рвался: три строки текста, потом снимок во весь экран,
   потом мелкий кроп.

   Кадрировать нельзя: снимок публикуется так, как его даёт досье художника.
   Поэтому выровнена не форма, а высота кадра — потолок один, ширина следует
   за ним, пропорции целы. Фигура при этом сжимается по содержимому, иначе
   картинка тянулась бы на всю колонку и потолок не работал бы вовсе. */
figure.plate--inline {
	inline-size: fit-content;
	max-inline-size: var(--measure);
}
figure.plate--inline img {
	max-block-size: 62svh;
	/* Ширина от потолка и пропорции (`--ar` пишет `.пропорции.mjs`), чтобы
	   коробка стояла до загрузки картинки (аудит 25.09, F09). */
	inline-size: calc(62svh * var(--ar));
	max-inline-size: 100%;
}

/* Плита с вертикальным снимком уже колонки. Портретный кадр при полной
   ширине колонки уходил на полторы страницы: 1118 × 1600 давало 1523 px
   при окне в 900, и работа переставала быть плитой, становясь стеной.

   Ограничена ширина, а не высота, и это существенно: кадрировать на этом
   сайте нельзя — снимок публикуется так, как его даёт досье художника, —
   а потолок высоты на самом изображении при `inline-size: auto` схлопнул
   плиту до ста пикселей, потому что ширину в сеточной ячейке брать стало
   неоткуда. Узкая колонка даёт то же самое честно: высота следует за
   шириной, пропорции целы. */
/* Вес селектора поднят намеренно: `figure.plate--inline` объявлена ниже по
   файлу и с той же силой перебивала это правило шириной строки, из-за чего
   плита оставалась в 680 px и высота не менялась вовсе. */
figure.plate.plate--tall { max-width: 24em; }
figure.plate figcaption {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--s1);
	margin-block-start: var(--s3);
	padding-block-start: var(--s2);
	border-top: 1px solid var(--rule);
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	line-height: var(--leading-tight);
	color: var(--muted);
}
@media (min-width: 40em) {
	figure.plate figcaption { grid-template-columns: 5em minmax(0, 1fr); gap: var(--s3); }
}
/* Номер плиты — тот же счёт, что и номер раздела, и берёт тот же цвет.
   Правило акцента на сайте одно и его можно назвать словами: фирменный
   цвет метит аппарат и переход — счётчик, номер плиты, квадрат пометки и
   линию под ссылкой. Заголовки, набор и подписи он не трогает. Так цвет
   всегда что-то отмечает, а не украшает, и по нему видно, где у страницы
   доказательство, а где просто текст.

   Кегль этикетки моноширинный и мелкий, поэтому запас считается по
   отрисованному: 6,82 минус примерно 0,58 на сглаживание — около 6,24,
   выше расчётного порога 5,0, который файл токенов держит для мелкого
   моноширинного. */
figure.plate .pl { color: var(--accent); }
.rk figure.plate .pl, .on-ink figure.plate .pl { color: var(--accent-on-ink); }
figure.plate .who { color: var(--fg); }
/* Название работы в этикетке. Курсива у неогротеска в поставке нет, и
   вводить его значит платить за ещё одно начертание ради одной строки.
   Название отбивается тем же приёмом, что и остальной аппарат: цветом
   чернил и разрядкой, а тег i остаётся ради смысла для чтения с экрана. */
figure.plate i { font-style: normal; color: var(--fg); letter-spacing: var(--tracking-title-mono); }
figure.plate .src { display: block; margin-block-start: var(--s1); }

/* Плита во всю полосу, поперёк обеих колонок. Ставится там, где раздел
   должен получить паузу, а не подпись к абзацу. */
figure.plate--bleed { grid-column: 1 / -1; margin-block-start: var(--s6); }

/* Плита во всю ширину окна, без полей страницы. Одна на странице: смысл
   в перемене масштаба, а перемена, повторённая трижды, перестаёт быть
   переменой. Работа не кадрируется — высота берётся из её собственных
   пропорций, поэтому на широком экране она занимает экран целиком, как
   и положено работе в зале. Подпись возвращается в поля страницы:
   этикетка висит рядом с работой, а не под потолком. */
figure.plate--full {
	grid-column: 1 / -1;
	margin-block-start: var(--s6);
	/* Полосная плита стоит в двух разных местах и вылетает по-разному.
	   Прямо в строке раздела она начинается там же, где сама строка, и до
	   окна ей с обеих сторон одно и то же поле. Внутри столбца текста слева
	   от неё лежит ещё графа аппарата с отбивкой, и вылет там больше ровно
	   на неё. Общий приём `50% - 50vw` не годится ни для того, ни для
	   другого случая: он верен только для колонки по центру окна. */
	margin-inline: calc(-1 * var(--bleed-out));
}
.row > div figure.plate--full { margin-inline-start: calc(-1 * var(--bleed-in)); }
figure.plate--full figcaption {
	max-width: var(--page-max);
	margin-inline: auto;
	padding-inline: var(--page-pad);
	border-top: 0;
	/* Линейки нет — нет и поля под неё (аудит 25.09). */
	padding-block-start: 0;
}
/* Подпись строчной плиты не расширяет плиту: её правый край и линейка —
   край изображения (было −204…+145 px, аудит 25.09, F32). Вносится только
   вместе с коробкой изображения до загрузки (F09, `--ar`): без неё плита
   без ширины подписи схлопывалась до 86 px, а подпись вставала столбиком в
   1542 px — гейт чернил поймал это 25.09. Ниже 810 подпись стоит в полях
   нарочно. */
@media (min-width: 50.625em) {
	figure.plate--inline figcaption { contain: inline-size; max-inline-size: none; }
	figure.plate--inline figcaption > span:last-child { max-inline-size: var(--measure); }
}
/* Две строчные плиты подряд в чернильной комнате на широком экране стоят
   парой. Пока ленивые картинки были нулевыми (F09), гейт чернил мерил
   «Recent work» на главной в 1435 px; с картинками она всегда была 2343 —
   2,6 окна при потолке в два. Парой — 1560 px. Цена — работы 376 px вместо
   680. Ниже 1200 колонка для пары узка, и плиты идут столбцом. */
@media (min-width: 75em) {
	.rk > div:has(> figure.plate--inline + figure.plate--inline) { display: flow-root; }
	.rk > div > figure.plate--inline:has(+ figure.plate--inline),
	.rk > div > figure.plate--inline + figure.plate--inline {
		float: inline-start;
		inline-size: calc((100% - var(--gutter)) / 2);
		max-inline-size: none;
	}
	.rk > div > figure.plate--inline + figure.plate--inline { float: inline-end; }
}
@media (min-width: 50.625em) {
	figure.plate--full figcaption { grid-template-columns: var(--register) minmax(0, 1fr); gap: var(--gutter); }
}

/* Плита внутри основной колонки. Ширина ограничена мерой строки, чтобы
   изображение и текст стояли на одном поле, а не спорили. */
figure.plate--inline { margin-block-start: var(--s5); max-width: var(--measure); }

/* Мобильная развеска. Блок стоит НИЖЕ базовых объявлений плиты и это
   не косметика порядка: он жил выше и не действовал вовсе — `max-width:
   var(--measure)` из базового правила перебивал его `max-inline-size:
   none`, и на телефоне все плиты, кроме полосной, стояли в колонке с
   полем в шестнадцать пикселей. Страница читалась уменьшенной настольной
   версией, чем владелец и был недоволен.

   Правило простое: работа выходит на края экрана, подпись остаётся в
   полях. Так набрана и настольная стена, и это же держит первый экран
   телефона: изображение во всю ширину, текст в своей мере. */
@media (max-width: 50.624em) {
	figure.plate--inline {
		inline-size: auto;
		max-inline-size: none;
		margin-inline: calc(-1 * var(--page-pad));
	}
	figure.plate--inline img {
		inline-size: 100%;
		max-inline-size: none;
		max-block-size: none;
	}
	figure.plate.plate--tall { max-width: none; }
	figure.plate.plate--tall img { max-block-size: 62svh; inline-size: calc(62svh * var(--ar)); max-inline-size: 100%; margin-inline: auto; }
	figure.plate--inline figcaption { margin-inline: var(--page-pad); }
	/* Краевая плита и работа в архиве идут тем же правилом. Обрез у края
	   экрана — единственная развеска, которая на телефоне вообще читается:
	   в колонке шириной 358 px любая работа становится эскизом. */
	figure.plate--edge {
		inline-size: auto;
		max-inline-size: none;
		margin-inline: calc(-1 * var(--page-pad));
	}
	figure.plate--edge img { inline-size: 100%; max-inline-size: none; }
	figure.plate--edge figcaption { margin-inline: var(--page-pad); }
	.roster .arch-plate {
		margin-inline: calc(-1 * var(--page-pad));
	}
	/* Потолок высоты, как у высокой плиты: портретная работа была 660 px на
	   440 и 1152 на 768 (аудит 25.09). Коробка есть до загрузки. */
	.roster .arch-plate img { inline-size: 100%; max-inline-size: none; max-block-size: 62svh; object-fit: contain; background: none; }
	.roster .arch-plate figcaption { margin-inline: var(--page-pad); }
}

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

/* ── Последовательность плит ────────────────────────────────────────────
   Двенадцать граф, и каждая плита занимает свою ширину и своё положение.
   Одинаковых рядов нет намеренно: работы разного пропорционального склада,
   и подгонять их под общий кадр значит обрезать чужие произведения.
   Каждая плита в собственном ряду, поэтому раскладка предсказуема на любой
   ширине и не зависит от порядка загрузки изображений. */
/* Последовательность плит висит на своей стене. Внутри раздела это вторая
   комната: ведомость читается в светлом зале, работы висят на тонированном.
   Стена уходит во всю ширину окна и получает поля сверху и снизу, иначе
   верхняя плита прилипает к порогу, а в галерее работу не вешают в угол. */
.plates {
	grid-column: 1 / -1;
	margin-block-start: var(--s5);
	padding-block: var(--s5);
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	row-gap: var(--s5);
}
@media (min-width: 50.625em) {
	.plates {
		grid-template-columns: repeat(12, minmax(0, 1fr));
		column-gap: var(--gutter);
		/* Отбивка между строками развески меньше, чем была: пустоту теперь
		   держит смещение подвеса, а не расстояние. */
		row-gap: var(--s5);
		align-items: start;
	}
	/* Развеска, а не колонка.
	   Раньше каждая работа занимала свою строку: диапазоны граф
	   пересекались, и сетка сама сносила следующую вниз. Получалась
	   вертикаль с большими пустотами — список, поставленный на попа.

	   Теперь строки назначены явно, и в каждой стоит по две работы, кроме
	   последней. Пары собраны по формату, а не по порядку файлов:
	   вертикальный «Pillow» рядом с горизонтальной «No Petal Left to
	   Pluck», горизонтальная Камиль рядом с вертикальным Спирсом,
	   горизонтальный Сент-Джон закрывает стену один.

	   Высота подвеса у соседей разная — это и есть развеска. Ровный верх
	   у двух работ читается таблицей из двух ячеек; смещение на шаг делает
	   из них две работы на одной стене. Смещается всегда одна из пары, и
	   сторона чередуется от строки к строке. */
	.plates > * { grid-column: 1 / -1; }
	/* Селектор с `figure`, а не короче: `figure.plate { margin: 0 }` весит
	   больше, чем один класс, и смещение подвеса молча не применялось —
	   обе работы строки вставали ровным верхом. Тот же капкан, что с
	   краевой плитой; ловится только замером координат. */
	.plates figure.p-a { grid-column: 1 / span 5;  grid-row: 1; }
	.plates figure.p-b { grid-column: 7 / span 6;  grid-row: 1; margin-block-start: var(--s7); }
	.plates figure.p-c { grid-column: 10 / span 3; grid-row: 2; }
	.plates figure.p-d { grid-column: 2 / span 7;  grid-row: 2; margin-block-start: var(--s6); }
	.plates figure.p-e { grid-column: 1 / span 9;  grid-row: 3; }
}
@media (min-width: 75em) {
	.plates { row-gap: var(--s7); padding-block: var(--s6); }
}

/* ── Плита краевая ─────────────────────────────────────────────────────
   Работа уходит за край страницы и обрезается окном. Это не эффект и не
   «полный экран»: так висит работа в зале, где стена длиннее взгляда, и
   так печатается разворот, где изображение уходит в обрез. Кадр остаётся
   кадром — обрезает окно, а не рамка.

   Одна сторона, не обе: обрезанное с двух сторон изображение читается
   баннером. Сторона задаётся классом и меняется от плиты к плите — как
   и ширина, ритм даёт чередование, а не повтор.

   Подпись возвращается в поля страницы: этикетка висит рядом с работой,
   а не под потолком. */
figure.plate--edge { position: relative; }
@media (min-width: 50.625em) {
	/* Селектор повторяет форму `figure.plate img`, а не берёт короче:
	   `.edge-r img` весит меньше и проигрывал, картинка оставалась в
	   графе. Проверяется это только замером — правило есть, а действия
	   у него нет. */
	figure.plate--edge img { max-inline-size: none; }
	/* Расстояние до края окна с двух сторон разное, и это не мелочь.
	   Справа плита стоит у правого края столбца текста, и до окна ей
	   остаётся поле страницы плюс половина того, на что окно шире
	   страницы. Слева между ней и окном лежит ещё графа аппарата с
	   отбивкой — первая редакция про них забыла, и плита уезжала влево,
	   но до края не доходила: 219 px при окне 1600. */

	figure.plate.edge-r img { inline-size: calc(100% + var(--bleed-out)); }
	figure.plate.edge-l {
		margin-inline-start: calc((var(--bleed-out) + var(--register) + var(--gutter)) * -1);
	}
	/* Ширина считается один раз. Отрицательное поле уже расширяет саму
	   фигуру — её правый край держит графа, левый уехал, — и картинке
	   остаётся заполнить фигуру. Первая редакция прибавляла то же
	   расстояние ещё и картинке: она уезжала влево на 75 px и вылезала
	   вправо на 347, то есть за оба края сразу. Обрез с двух сторон
	   читается не развеской, а поломкой, и владелец это так и назвал. */
	figure.plate.edge-l img { inline-size: 100%; }
	/* Подпись возвращается в поля страницы — то же правило, что у плиты во
	   всю ширину: этикетка висит рядом с работой, а не под потолком. Для
	   левого обреза это не «не забыть», а обязанность: фигура утянута
	   отрицательным полем в графу аппарата, и подпись, оставшаяся при ней,
	   ложится прямо на пометку. Возврат равен той же утяжке. */
	figure.plate.edge-l figcaption {
		margin-inline-start: calc(var(--bleed-out) + var(--register) + var(--gutter));
	}
	figure.plate--edge figcaption { max-inline-size: var(--measure); }
}

/* ── Плита парная ──────────────────────────────────────────────────────
   Две работы на одной линии — но не в ряд. Ряд из двух одинаковых
   прямоугольников есть сетка карточек, которую §6 запрещает поимённо.
   Пара держится тем же правилом, что и стена: разные ширины и разная
   высота подвеса. Вторая опущена на треть своей высоты, и глаз читает
   две работы, а не одну строку из двух ячеек.

   Ниже 810 px пара распадается на две плиты друг под другом: сдвиг на
   узком экране крадёт ширину у обеих, а ширина здесь и есть предмет. */
.pair { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: var(--s5); }
@media (min-width: 50.625em) {
	.pair {
		grid-template-columns: repeat(12, minmax(0, 1fr));
		column-gap: var(--gutter);
		align-items: start;
	}
	.pair > :first-child { grid-column: 1 / span 7; }
	.pair > :last-child  { grid-column: 9 / span 4; margin-block-start: var(--s7); }
	.pair--flip > :first-child { grid-column: 1 / span 4; margin-block-start: var(--s7); }
	.pair--flip > :last-child  { grid-column: 6 / span 7; margin-block-start: 0; }
}

/* ── Реестр художников ──────────────────────────────────────────────────
   Ведомость: портрет, имя, год рождения, место, публичная запись. Строка
   на художника, линейка между строками. Это направление в самом буквальном
   виде — список, который ведут, а не витрина, которую оформляют. */
.roster {
	/* Внутри архива ведомость занимает свою графу, а не всю строку: полную
	   ширину она держала, пока была единственным содержимым раздела. */
	margin-block-start: var(--s5);
	border-top: 1px solid var(--rule-mid);
}
/* Портреты из ведомости убраны совсем — вместе с разметкой. Пока работ
   рядом не было, крошечный портрет был единственным изображением строки;
   теперь в записи стоит работа, и портрет размером в ноготь спорит с ней,
   ничего не добавляя. Правило `display: none` держалось полгода, а восемь
   тегов продолжали стоять в разметке: читающему с экрана они доставались,
   валидатору тоже, а на экране их не было ни у кого. */
/* Шапка граф. Без неё смысл крайней колонки только подразумевается, а
   ведомость без названий граф — это список, а не ведомость. На узкой
   ширине строка складывается в столбик, и шапка над ней врала бы. */
.rhead { display: none; }
/* Шапка граф идёт по той же мере, что и записи под ней: контейнерным
   запросом о ширине графы, а не медиазапросом об окне. Пустая первая
   ячейка убрана вместе с графой портрета — из-за неё три подписи стояли
   каждая над чужой колонкой, а четвёртая падала на вторую строку. */
@container (min-inline-size: 34rem) {
	.rhead {
		display: grid;
		grid-template-columns: minmax(0, 1.4fr) minmax(0, 6rem) minmax(0, 1fr);
		column-gap: var(--s3);
		padding-block: var(--s2);
		border-bottom: 1px solid var(--rule);
		font-weight: 400;
	font-family: var(--font-mono);
		font-size: var(--size-label);
		letter-spacing: var(--tracking-label);
		color: var(--muted);
	}
	.rhead > :last-child { text-align: end; }
}
/* Строка ведомости ведёт на запись художника. Восемь внутренних ссылок
   с первой страницы — это архитектура, которую требует Приложение 1, а не
   украшение: перенос восьми записей и есть обязанность по п. 2.2(e).
   Жест наведения тот же, что у строки библиотеки: отметка на поле,
   крайняя графа доходит до чернил. Один жест на весь сайт. */
.roster .r {
	position: relative;
	color: inherit;
	/* Строка под именем — аппарат: кегль и интерлиньяж аппарата. Она
	   наследовала кегль тела, и шаг строк был 29–32 px (аудит 25.09). */
	font-size: var(--size-apparatus);
	line-height: var(--leading-tight);
	text-decoration: none;
	/* Основа — форма записи, а не таблицы: имя строкой, под ним город и
	   институция одной строкой аппаратом через разделитель. Три графы в
	   узкой полосе не помещаются никак, а разложенные по строкам они дают
	   три абзаца с провалами между ними — список вместо записи. Графы
	   включает контейнерный запрос ниже, когда для них есть место. */
	display: block;
	/* Одна графа: портрет из строки убран, и графа под него больше не
	   нужна. Пока она оставалась, имя вставало в колонку шириной 3rem. */
	grid-template-columns: minmax(0, 1fr);
	row-gap: var(--s1);
	padding-block: var(--s3);
	border-bottom: 1px solid var(--rule);
}
/* Запись раскладывается по ширине собственной графы, а не окна. Медиазапрос
   здесь врал дважды: он меряет `em` по начальному кеглю 16 px, ничего не
   знает о поле аппарата слева, и при базовом кегле читателя 24 px включал
   три графы там, где ведомости оставалось 24 px и имя рассыпалось по букве
   в строку. Контейнерный запрос меряет ту самую графу. */
@container (min-inline-size: 34rem) {
	.roster .r {
		display: grid;
		grid-template-columns: minmax(0, 1.4fr) minmax(0, 6rem) minmax(0, 1fr);
		column-gap: var(--s3);
		align-items: baseline;
	}
	.roster .r > .md { display: block; }
	.roster .r > .md + .md::before { content: none; }
	.roster .r > .md:last-child { text-align: end; }
	.roster .nm { margin-block-end: 0; }
}

/* Работа встаёт рядом со своей записью. Под записью она стояла одна в
   пустой полосе: на 1440 px плита занимала 368 px, справа от неё оставалось
   700 px бумаги, а сама запись шла тремя графами поверх этой пустоты.

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

   Порог назначен по месту и по замеру. На полосе 1440 px графа архива
   держит 816 px: при пороге 46 рем работа вставала рядом с записью и
   получала 320 px — эскиз, а не работа, — оставляя записи 432 px на три
   графы. В парном виде запись становится этикеткой: имя строкой, под ним
   город и институция одной строкой аппаратом — теми же тремя графами она
   в оставшиеся шестьдесят процентов не встанет, а работа рядом с
   табличной строкой выходила 256 px и ломала подпись на три строки ради
   «45 × 40 cm». Этикетка рядом с работой — то, как подписана стена. Ниже порога работа стоит под
   записью во всю графу, и это честнее эскиза: на 1440 она выходит 816 px
   шириной. Ширина окна тут ничего не решает — при базовом кегле 24 px те
   же 816 px становятся 34 рем. */
@container (min-inline-size: 48rem) {
	.roster {
		display: grid;
		/* Уступает работа, а не запись. Три графы записи требуют своих
		   тридцати четырёх рем; всё, что сверх них, идёт работе, но не более
		   двадцати рем — дальше она перестаёт быть спутницей строки и спорит
		   с полосными плитами страницы. */
		grid-template-columns: minmax(0, 1fr) var(--plate-col);
		column-gap: var(--gutter);
		/* Растяжкой, а не по верху: линейка записи обязана стоять на дне
		   строки, вровень с низом работы. Пока запись сжималась по тексту,
		   линейка проходила посреди строки и под ней оставалось полполосы
		   пустой бумаги без всякой причины. */
		align-items: stretch;
	}
	/* Запись стоит по середине своей работы, как этикетка на стене. По
	   верху она оставляла под собой до 350 px пустой бумаги: высоту строки
	   держит работа, а имя с двумя строками аппарата занимает девяносто. */
	.roster .r { align-content: center; }
	/* Три графы уступают этикетке. Ширины на них тут нет: графа архива
	   держит около пятидесяти одного рема, из них шестьдесят процентов —
	   запись, и «Skulpturenpark Waldfrieden, Germany» в третьей графе
	   вставало бы в четыре строки по 135 px. */
	.roster .r { display: block; }
	.roster .r > .md { display: inline; }
	.roster .r > .md + .md::before { content: "\00a0\00b7\00a0"; }
	.roster .r > .md:last-child { text-align: start; }
	.roster .nm { margin-block-end: var(--s1); }
	.roster .rhead { display: none; }
	/* Шапка стоит над записями, а не над всей полосой: её графы обязаны
	   совпасть с графами записи, а графа работы своей подписи не имеет. */
	.roster .rhead { grid-column: 1; }
	.roster .r { grid-column: 1; }
	.roster .arch-plate {
		grid-column: 2;
		/* Работа доходит до края окна, подпись — нет. Строка аппарата,
		   упирающаяся в кромку экрана, читается обрезком, а не этикеткой. */
		margin-block: 0;
		align-self: start;
		/* Линейка записи продолжается под работой, иначе строка обрывается
		   на середине полосы. */
		padding-block-end: var(--s3);
		border-bottom: 1px solid var(--rule);
		/* Работа на 16 ниже линейки — как подпись на 16 выше следующей. */
		padding-block-start: var(--s3);
	}
	.roster .arch-plate figcaption { padding-inline-end: var(--gutter); }
}
/* В одну колонку линейка закрывает запись после работы, а не между
   именем и его работой (аудит 25.09). */
@container (max-inline-size: 47.999rem) {
	.roster .r { border-bottom: 0; }
	.roster .arch-plate + .r { border-top: 1px solid var(--rule); margin-block-start: var(--s4); }
}
.roster .nm {
	font-family: var(--font-display);
	font-weight: 500;
	font-size: var(--size-h3);
	line-height: var(--leading-tight);
	letter-spacing: var(--tracking-display);
	color: var(--ink);
}
.roster .nm span {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	letter-spacing: 0;
	color: var(--muted);
	margin-inline-start: 0.5em;
}
/* Графа города на узкой ширине попадает в дорожку шириной ровно 3rem
   и держится только потому, что все восемь городов из шести букв.
   «Amsterdam» вышел бы за неё на 1 px. Дорожка остаётся фиксированной —
   на ней держится выключка имён, — а перенос разрешается самой ячейке. */
.roster .md--place { overflow-wrap: anywhere; hyphens: auto; }
.roster .nm { margin-block-end: var(--s1); }
.roster .md {
	display: inline;
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	text-align: start;
}
.roster .md + .md::before {
	content: "\00a0\00b7\00a0";
	color: var(--rule-mid);
}
.roster .md {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	line-height: var(--leading-tight);
	color: var(--muted);
}
.roster .r::before {
	content: "";
	position: absolute;
	inset-block: 0;
	inset-inline-start: calc(var(--s3) * -1);
	inline-size: 1px;
	background: var(--ink);
	transform: scaleY(0);
	transform-origin: 50% 100%;
	transition: transform var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
	.roster .r:hover::before { transform: scaleY(1); transform-origin: 50% 0%; }
	.roster .r:hover .md { color: var(--ink); }
}

/* Запись о работе оформлена как документ, а не как карточка: линейки вместо
   заливки. Карточка уместна там, где возвышение несёт иерархию; здесь оно
   ничего не несёт, а серая плашка читается как элемент презентации. */
.record { margin-block-start: var(--s4); max-width: var(--measure); border-top: 1px solid var(--rule-mid); }
.record dl { margin: 0; }
.record .line {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--s1);
	padding-block: var(--s3);
	border-bottom: 1px solid var(--rule);
}
@media (min-width: 40em) {
	/* Общая колонка ключа 12em для всех ведомостей (справка, факты, выставки)
	   проверена 25.09 и отвергнута: короткие ключи («Asset», «Scope», год)
	   стояли в пустой графе, а текст справа переносился на строку больше —
	   cites@1024 вырос на 276 px. У каждой ведомости своя графа по её ключам. */
	.record .line { grid-template-columns: 8em minmax(0, 1fr); gap: var(--s3); align-items: baseline; }
}
.record dt {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
}
.record dd { margin: 0; }

/* Перечень источников внизу страницы — те же линейки, что у записи, в одну
   графу. Заменил реестр 24.09.2026: у каждой цифры по п. 13.9 остаются
   документ и дата прочтения, и больше ничего — ни номеров, ни статусов. */
/* Графа уже прозы: в ссылке на документ много узких знаков — цифры, точки,
   скобки, — и на мере прозы строка перечня выходила в 76 знаков при
   границе 75 (`.measure.mjs`, 24.09.2026). */
.sources-list {
	margin: var(--s4) 0 0;
	padding: 0;
	list-style: none;
	max-width: var(--measure-narrow);
	border-top: 1px solid var(--rule-mid);
}
.sources-list li { padding-block: var(--s3); border-bottom: 1px solid var(--rule); }
.sources-list + .body { margin-block-start: var(--s4); color: var(--muted); }
/* Полка «Read next» стояла без правила, на стилях браузера: маркеры,
   отступ 40 и поле 18–20 под списком (аудит 25.09, 73 страницы). */
.shelf { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--s2); justify-items: start; }
/* Заголовок записи на странице источников: пауза перед ним больше, чем
   до его перечня, и цвет один у всех записей. */
.sources-list + .src-entry { margin-block-start: var(--s5); color: inherit; }
.src-entry + .sources-list { margin-block-start: var(--s3); }
/* Метка → линейка ведомости одной ступенью у обеих ведомостей: было 32 у
   одной и 1em у другой (аудит 25.09). */
.label + :is(.sources-list, .record) { margin-block-start: var(--s3); }

.held-block {
	margin-block-start: var(--s4);
	padding: var(--s4);
	border: 1px dashed var(--rule-strong);
	max-width: var(--measure);
}

/* Справочная библиотека. Тринадцать строк перестали быть ссылками: ни одна
   запись ещё не написана, а собственный реестр страницы объявляет их
   придержанными до проверки источников. Живая на вид ссылка в никуда —
   первое, что читатель проверяет, и провалить именно её на странице, весь
   довод которой в проверяемости, значит потерять довод целиком.

   Вместе со ссылкой сняты три обещания навигации: отметка на поле, сдвиг
   заголовка и доведение метки до чернил. Обёртка — тот самый пунктирный
   блок, который правила и отводят придержанному разделу. */
.library {
	margin: 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--rule);
}
.library li {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto;
	gap: var(--s3);
	align-items: baseline;
	padding-block: var(--s3);
	border-bottom: 1px solid var(--rule);
	color: var(--ink);
}
.library li:last-child { border-bottom: 0; }
.library .n {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	color: var(--muted);
}

.contact-mail {
	/* При настройке «только текст 200 %» базовый кегль становится 32 px,
	   и адрес дисплейным кеглем занимает 1509 px против 1248 колонки.
	   Перенос разрешён и подсказан тегом wbr после собачки, чтобы адрес
	   разрывался по смыслу, а не посреди домена. */
	overflow-wrap: anywhere;
	font-family: var(--font-display);
	font-weight: 500;
	font-size: var(--size-display);
	line-height: var(--leading-display);
	letter-spacing: var(--tracking-display);
	display: inline-block;
	margin-block-start: var(--s4);
}
/* На узком экране адрес дисплейным кеглем шире вьюпорта: двадцать знаков при
   48 px дают 453 px против 358 px колонки, и страница начинает ехать вбок.
   Ступень берётся из той же шкалы, а не подгоняется числом. */
@media (max-width: 39.999em) {
	.contact-mail { font-size: var(--size-h2); }
}

.foot {
	border-top: 1px solid var(--rule);
	/* Нижняя панель Safari на iOS стоит поверх страницы и перекрывает
	   последние строки подвала. `env(safe-area-inset-bottom)` за пределами
	   таких устройств равен нулю, поэтому прибавка ничего не меняет там,
	   где её не нужно. */
	padding-block: var(--s5) calc(var(--s6) + env(safe-area-inset-bottom, 0px));
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	color: var(--muted);
	display: grid;
	/* Колонка не уже нуля, а не «не уже своего содержимого».

	   Неявная колонка сетки по умолчанию — `minmax(min-content, max-content)`,
	   и при увеличении только текста её min-content перерастал сам подвал:
	   замер 16.09.2026 дал колонку 432 px в подвале шириной 358 при окне 390.
	   Всё, что в колонке, уезжало за край вместе с ней. */
	grid-template-columns: minmax(0, 1fr);
	gap: var(--s3);
}
@media (min-width: 50.625em) {
	/* Графа карты сайта раньше стояла в 14rem, названия направлений в неё
	   не помещались и переносились, а подчёркивание ссылки рисуется во всю
	   ширину коробки и уходило на 131 px в пустую бумагу. Правится не линия,
	   а графа: max-content подгоняет её под самое длинное название и не
	   зависит от того, какая гарнитура загрузилась. */
	/* Колофон — проза, набранная моноширинным. В три графы он влезает
	   только на широком экране: на 810 px ему оставалось 200 px, то есть
	   двадцать четыре знака в строке, и подвал вырастал до 810 px высотой.
	   Между 810 и 1200 подвал держит две графы, карта сайта и колофон
	   идут друг под другом и оба получают полную ширину столбца. */
	/* Между 810 и 1200 графа аппарата в подвале снимается. На странице она
	   несёт номер раздела и пометку; в подвале — пустоту и знак, то есть
	   176 px, отнятых у единственных двух столбцов, которым ширина нужна.
	   Знак уходит в свой ряд наверх, карта сайта и колофон встают рядом.
	   Замер: колофон получает 472 px вместо 200, подвал 400 px вместо 895. */
	/* Карта сайта сама стала трёхколонной, и графа под неё больше не
	   «самая длинная ссылка». Пока она стояла как `max-content` рядом с
	   колофоном, карта съедала строку целиком: на 834 px колофону
	   доставался 101 px, на 1024 — ноль, а на 1440 три графы в сумме
	   давали 1572 px при 1440 доступных, то есть переполнение. Карта
	   получает полную ширину, колофон встаёт под ней. */
	.foot { grid-template-columns: minmax(0, 1fr); gap: var(--s5) var(--gutter); }
	.foot > :first-child { grid-column: 1; grid-row: 1; }
	.sitemap { grid-column: 1; grid-row: 2; }
	/* Ряд назначен явно, как и остальным: без него блок обращения уходил
	   в автоматическую укладку и вставал поверх первого ряда — кнопка
	   пропадала из подвала совсем. */
	.foot-ask { grid-column: 1; grid-row: 3; }
	.foot .body { grid-column: 1; grid-row: 4; max-width: var(--measure); }
}
/* Широкое правило подвала снято. Знак стоял в одном ряду с картой сайта и
   отнимал у неё графу; на широком экране кегль крупнее, кнопка требует
   около трёхсот пикселей, и трёх граф в остаток не помещалось — подвал на
   1200 складывался в две, хотя на 1024 держал три. Шире окно, меньше
   колонок: это читается поломкой, и ею и было. Знак ушёл в свой ряд
   наверх, карта сайта получила всю строку — то же правило, что и на
   средних ширинах, поэтому отдельного блока больше нет. */
/* Карта сайта в подвале. Приложение 1 требует, чтобы четыре направления
   набирали больше всего внутренних ссылок по построению; в шапке их имена
   не помещаются, поэтому каждое получает по второй ссылке отсюда. */
/* Карта сайта раскладывается в колонки, а не в одну кишку. Одиннадцать
   строк подряд в подвале читались как список задач; в три колонки те же
   строки становятся картой, и подвал перестаёт быть длиннее содержимого.

   Колонки разрываются по заголовкам групп: `break-after` на подписи не
   даёт «Practice areas» оторваться от своих четырёх ссылок. */
.sitemap { display: grid; gap: var(--s2); align-content: start; }
.sitemap-col { display: grid; gap: var(--s5); align-content: start; }
.sitemap-group { display: grid; gap: var(--s2); align-content: start; justify-items: start; }
.sitemap-group .colophon { margin: 0; }
/* Число граф считает раскладка, а не я. Жёсткие «две, потом три» я
   поставил по замеру на двух ширинах и промахнулся посередине: кнопка
   «Write to the practice» ломалась на три строки там, где графа выходила
   уже неё. Минимум графы взят от этой кнопки — самой длинной неразрывной
   единицы подвала.

   Зазор между графами свой, а не общий межколонник страницы: тот на широких
   равен 64, и на два зазора уходило ровно столько, сколько не хватало
   третьей графе. Карта сайта — перечень ссылок, а не колонки текста. */
/* Три графы ссылок. Минимум взят от самой длинной ссылки — «Private
   capital and collections», — а не от кнопки: кнопка ушла в свой ряд и
   больше не диктует ширину тем, кому столько не нужно. */
/* Нижний предел колонки — не больше самой полосы.

   `minmax(14rem, 1fr)` перестаёт помещаться, как только корень растёт:
   при увеличении только текста до 200 % четырнадцать кеглей — это 448 px,
   а окно бывает 390 и 320. Колонка тогда шире окна, и всё, что в ней,
   уезжает за край вместе с ней: замер 16.09.2026 нашёл так три ссылки
   указателя на 15, 72 и 142 пикселя за кромкой.

   `min(100%, 14rem)` оставляет прежнюю раскладку везде, где место есть, и
   снимает предел там, где его нет. */
.sitemap { grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: var(--s5) var(--s4); }
/* Обращение — своя строка под картой сайта, с отбивкой и линией над ней:
   это не четвёртая графа перечня, а действие. */
.foot-ask {
	display: grid;
	justify-items: start;
	/* Поле над обращением складывалось с зазором сетки подвала: 64 + 64 до
	   линейки против 64 после неё (аудит 25.09). Интервал даёт сетка. */
	gap: var(--s2);
	margin-block-start: 0;
	padding-block-start: var(--s5);
	border-top: 1px solid var(--rule);
}
.sitemap a { color: var(--muted); justify-self: start; }

/* Колофон — проза, а не аппарат. Моноширинный в этой системе означает
   «источник, дата, состояние»: величину, которую сверяют. Колофон
   говорит, что это за документ, и читается подряд. Набранный аппаратом,
   он требовал сорока пяти знаков в строке там, где графа давала двадцать
   четыре, и подвал вырастал до 895 px. Гарнитура текста ставит в ту же
   ширину в полтора раза больше знаков — правится не графа, а лицо.
   Ярлыки и карта сайта остаются моноширинными: они и есть аппарат. */
.foot .body p:not(.colophon) {
	font-family: var(--font-text);
	font-size: var(--size-small);
	line-height: var(--leading-body);
}
/* Кнопку не красим: её цвет — свой, с наведением и фокусом. */
.foot a:where(:not(.cta)) { color: var(--muted); }
.foot p a.lnk { display: inline; }
.foot .body { max-width: var(--measure); }
/* Колофон. Издание называет себя в конце: что это за документ, по какому
   стандарту собран и когда напечатан. Это последнее, что видит читатель,
   который дочитал, и первое, что ищет тот, кто проверяет. */
.foot .body > .colophon + p { margin-block-start: 0; }
.colophon {
	font-size: var(--size-label);
	letter-spacing: var(--tracking-label);
	color: var(--ink);
	margin-block-end: var(--s2);
}

.theme {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	/* Тот же довод, что у навигации: это орган управления, а не примечание. */
	color: var(--ink);
	background: none;
	border: 0;
	padding: 0;
	cursor: pointer;
	display: inline-flex;
	align-items: center;
	gap: var(--s2);
	/* Кнопка не наследует интерлиньяж: у неё `normal`, и «Dark» был на 3–6 px
	   ниже соседних ссылок шапки (аудит 25.09). */
	line-height: inherit;
}
.theme .device {
	inline-size: 0.7em;
	block-size: 0.7em;
	background: currentColor;
	flex: none;
	transition: transform var(--dur-fast) var(--ease-out);
}
.theme:active .device { transform: scale(0.86); }
@media (hover: hover) and (pointer: fine) {
	.theme:hover { color: var(--ink); }
	.theme:hover .device { transform: scale(1.18); }
}

@media (prefers-reduced-motion: reduce) {
	/* Движение уменьшается, а не выключается. Сплошное отключение —
	   известная ошибка: оно оставляет висеть содержимое, которое
	   проявлял скрипт, и убивает обратную связь состояния. Сдвиг и
	   масштаб убираем, прозрачность оставляем, длительности схлопываем
	   почти в ноль, чтобы события завершения всё же срабатывали. */
	*, *::before, *::after {
		transition-duration: 1ms !important;
		animation-duration: 1ms !important;
		animation-iteration-count: 1 !important;
		scroll-behavior: auto !important;
	}
	.toc a:hover .t,
	.library a:hover > span:first-child,
	.area:hover .q,
	.theme:hover .device,
	a.mark:hover .device { transform: none !important; }
}

/* Печать. Читатели этой практики печатают документы и пускают их по рукам
   внутри организаций, которые не пересылают ссылки. */
@media print {
	/* Хвостовой отступ подвала на бумаге не нужен: 96 px пустоты за последней
	   строкой выталкивали документ за границу листа, и печатался чистый лист.
	   Поймано 17.09.2026 на `contents.html`, выросшем на две записи: 7914 px
	   при границе седьмого листа 7867 и содержимом до 7818. На экране отступ
	   остаётся. */
	.foot { padding-block-end: 0; }
	/* Витрина архива на бумаге не печатается.

	   На главной у каждой записи художника стоит плита с работой — десять
	   штук. На экране это витрина; на бумаге каждая при `break-inside: avoid`
	   забирает лист и оставляет его недопечатанным. Замер 17.09.2026:
	   лишних листов по корпусу 20 из 96, из них 11 на одной главной.

	   Ни одно изображение при этом не теряется: плиты архива есть ТОЛЬКО на
	   главной, а у каждой записи художника свои собственные плиты, и они
	   печатаются. На бумаге главная остаётся доводом и указателем, работы
	   смотрят на странице записи.

	   После правила: лишних 10 из 86, доля 13,2 % при рубеже 24,0 %. */
	figure.arch-plate { display: none; }

	/* Полка соседних на бумаге не печатается.

	   Она заведена 19.09.2026 на 68 страницах и целиком состоит из ссылок:
	   читателю на экране это следующий ход, читателю на бумаге — три строки
	   адресов, по которым он никуда не пойдёт. Замер сразу после её ввода:
	   лишних листов 19,7 % при рубеже 14,0 %, и главная печаталась на 18
	   листах при 13 листах содержимого.

	   Скрывается вся секция, а не только список: заголовок «Read next» без
	   списка под ним хуже, чем ничего. */
	section[aria-labelledby="h-shelf"] { display: none; }

	/* Плиты кейса на главной на бумаге не печатаются — по тому же доводу,
	   по какому не печатается витрина архива. Замер 19.09.2026: главная
	   печаталась на 18 листах при 13 листах содержимого, и две плиты
	   размером в лист каждая забирали по листу и оставляли его
	   недопечатанным.

	   На экране они и есть доказательство; на бумаге главная остаётся
	   доводом и указателем, а смотреть работу идут на страницу. Это то же
	   правило, что и для витрины, и оно записано здесь, а не выведено из
	   неё: у витрины плиты чужие, а тут свои, и совпадение довода надо
	   сказать вслух. */
	#evidence figure.plate { display: none; }

		/* Палитра сбрасывается в корне, а не по частям. Прежде печатный блок
	   правил отдельные роли внутри чернильной комнаты, а сами токены
	   оставались теми, что были на экране. У читателя с тёмной темой
	   `--fg` оставался почти белым, и на белой бумаге печаталось белым по
	   белому — не в одном блоке, а во всех. Замер: снято `colorScheme:
	   "dark"` плюс `emulateMedia({media:"print"})`, фон тела форсируется в
	   белый, палитра — нет.

	   После этого сброса отдельные правила ниже становятся излишними и
	   оставлены только там, где меняется не цвет, а роль. */
	/* Селекторы повторяют форму тех, которыми объявлена тёмная тема, а не
	   берут силой. Простой `:root` слабее, чем `:root:not([data-theme="light"])`
	   из блока системной темы и `:root[data-theme="dark"]` из блока
	   переключателя, поэтому первый сброс не срабатывал вовсе: замер давал
	   56 почти белых элементов на главной при печати из тёмной схемы. При
	   равной силе побеждает тот, кто ниже, а page.css грузится после
	   tokens.css — этого достаточно, и `!important` не нужен. */
	:root,
	:root:not([data-theme="light"]),
	:root[data-theme="dark"],
	.rk {
		--paper: #fff;
		--ink: #000;
		--fg: #000;
		--accent: #000;
		/* Акцент вывернутой комнаты сбрасывается наравне с обычным. Пока
		   чернильной комнатой была только полоса без пометок, это не
		   проявлялось; блок реестра принёс в неё квадрат пометки, и он
		   печатался краплаком по белому — единственным цветным пятном на
		   всём листе. Найдено отрисовкой в режиме печати, а не чтением. */
		--accent-on-ink: #000;
		--paper-raised: #fff;
		--muted: #444;
		--rule: rgba(0, 0, 0, 0.28);
		--rule-mid: rgba(0, 0, 0, 0.28);
		--rule-strong: rgba(0, 0, 0, 0.48);
		--rule-heavy: rgba(0, 0, 0, 0.72);
		--grain-opacity: 0;
	}
	.nav, .theme, .skip, .index, .sheet { display: none; }
	/* Фоны при печати не печатаются, а вывороточная полоса набрана бумагой
	   по чернилам: на бумаге раздел вышел бы белым по белому, то есть
	   пустым. Роли внутри полосы возвращаются к печатным. */
	.rk,
	.rk h2,
	.rk .num { color: #000; }
	/* Ссылка на сноску внутри полосы набрана бумагой отдельным правилом,
	   и оно старше общего `a` ниже по весу селектора. Без этой строки
	   `n. 05` печатается белым по белому — проверено печатью, не чтением. */
	.rk .note-n {
		color: #000;
		border-bottom-color: rgba(0, 0, 0, 0.48);
	}
	.rk {
		--fg: #000;
		--muted: #444;
		--rule: rgba(0, 0, 0, 0.28);
		--rule-strong: rgba(0, 0, 0, 0.48);
	}
	.room::before,
	.room::after { display: none; }
	.held-block,
	body { background: #fff; color: #000; font-size: 11pt; }
	/* Ряд на бумаге не держится целиком, и это экономия, а не небрежность.

	   `break-inside: avoid` на ряде обещает браузеру, что ряд поместится на
	   лист. Ряд — это раздел, и он бывает в несколько листов высотой:
	   обещание невыполнимо, браузер начинает его с нового листа и всё равно
	   рвёт. Каждый такой ряд стоит недопечатанного листа.

	   Замер 16.09.2026 по десяти страницам: содержимого 79 листов A4,
	   напечатано 123 — лишних 44, то есть 55,7 %. Со снятым правилом
	   напечатано 94: лишних 15 вместо 44. Двадцать девять листов на десяти
	   страницах, при том что корпус — восемьдесят восемь.

	   Целыми держатся единицы, которые в лист помещаются: вклейка, запись
	   художника, строка реестра. Они перечислены ниже и остаются. */
	.row { padding-block: 12pt; }
	h1 { font-size: 28pt; }
	h2 { font-size: 16pt; }
	a { color: #000; text-decoration: none; }
	.note::after { content: ""; }
	figure.plate { break-inside: avoid; }
	.plates { row-gap: 18pt; }
	.roster .r { break-inside: avoid; }
	.roster .arch-plate + .r { margin-block-start: 0; }
	/* Строка реестра не рвётся краем листа. Разбор печати: на 72 страницах
	   из 79 хотя бы одна строка расходилась по двум листам — утверждение на
	   одном, источник и дата прочтения на другом. Это ровно та связка,
	   ради которой реестр и существует: п. 13.9 требует источник и дату
	   рядом с величиной, а на бумаге они оказывались врозь. Ведомость
	   целиком при этом рваться обязана — она длиннее листа. */
	.reg { break-inside: avoid; }
	.register-ledger .sources > dl { break-inside: auto; }


}

/* ─── ЗАПИСЬ ХУДОЖНИКА ───────────────────────────────────────────────────

   Перечень выставок — ведомость по годам, а не абзац через запятую. Год
   стоит в своей графе и повторяется только когда меняется; место и город
   разведены, потому что читатель ищет глазами институцию, а не строку.

   Список назван «selected», и критерий отбора написан рядом. «Selected»
   без критерия означает «мы что-то выкинули и не скажем что», а это ровно
   то, чего практика не делает нигде больше на сайте. */
.crumb {
	grid-column: 1 / -1;
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	color: var(--muted);
	margin: 0 0 var(--s4);
}
.crumb a { color: var(--muted); }

.exh { margin-block-start: var(--s4); border-top: 1px solid var(--rule-mid); }
.exh .y {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--s1);
	padding-block: var(--s3);
	border-bottom: 1px solid var(--rule);
}
@media (min-width: 40em) {
	.exh .y {
		grid-template-columns: 4em minmax(0, 1fr);
		column-gap: var(--s4);
		align-items: baseline;
	}
}
.exh .yn {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	font-variant-numeric: tabular-nums;
	color: var(--muted);
}
.exh ul { margin: 0; padding: 0; list-style: none; display: grid; gap: var(--s2); }
.exh li { font-size: var(--size-small); line-height: var(--leading-tight); }
.exh li i { font-style: normal; color: var(--ink); letter-spacing: var(--tracking-title-text); }
.exh li span { color: var(--muted); }

/* Строки разделяет их собственная отбивка и линейка, как у `.record`:
   зазор сетки поверх неё давал 16 + 16 + 16, а список оставался с полем
   браузера снизу (аудит 25.09). */
.counts { display: grid; gap: 0; margin-block: var(--s4) 0; border-top: 1px solid var(--rule-mid); }
.counts .c1 {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--s1);
	padding-block: var(--s3);
	border-bottom: 1px solid var(--rule);
}
@media (min-width: 40em) {
	.counts .c1 { grid-template-columns: 12em minmax(0, 1fr); gap: var(--s3); align-items: baseline; }
}
.counts dt {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
}
.counts dd { margin: 0; font-size: var(--size-small); }

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

   Строка индекса набрана как строка реестра, и это не экономия, а то же
   утверждение: у каждой записи есть адрес, и адрес показан. Заказанная
   запись стоит без ссылки и с названным стандартом — ровно так, как
   придержанная строка реестра публикует не задачу, а правило. */
.idx { margin-block-start: var(--s5); display: grid; gap: var(--s5); }
/* Строки индекса разделяет их линейка, а не зазор: 4 px сетки поверх
   давали 8 над линейкой и 12 под ней (аудит 25.09). */
.idx-group { display: grid; gap: 0; }
.idx-group .label { margin-block-end: var(--s2); color: var(--fg); }
.idx-sub {
	font-weight: 400;
	font-family: var(--font-mono);
	/* Подгруппа не крупнее группы: кегль метки. */
	font-size: var(--size-label);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
	margin-block: var(--s3) var(--s2);
}
.idx-row {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: 0 var(--s3);
	padding-block: var(--s2);
	border-bottom: 1px solid var(--rule);
	color: inherit;
	text-decoration: none;
}
@media (min-width: 50.625em) {
	.idx-row { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: baseline; }
}
.idx-row .t { font-size: var(--size-small); color: var(--fg); }
.idx-row .u {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	color: var(--muted);
	word-break: break-word;
}
.idx-row.is-held .t { color: var(--muted); }
@media (hover: hover) and (pointer: fine) {
	a.idx-row:hover .u { color: var(--fg); }
}
a.idx-row:active .u { color: var(--fg); }

/* Строка глоссария: имя термина, его определение и то, на чём он стоит.

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

   Раскладка идёт от чтения. На узкой полосе три вещи стоят одна под другой.
   На широкой имя занимает свою графу, а определение и норма — вторую, друг
   под другом: определение читается строкой текста, норма остаётся аппаратом
   под ней и ширину у определения не отбирает. */
/* Строка перехода по алфавиту: все термины страницы в одну строку.

   Группировка идёт по направлениям, и это верно по смыслу, но найти термин
   по имени в такой раскладке нельзя, не зная направления. Полоса решает
   ровно это: ссылки на якоря той же страницы, без сценария.

   Набрана аппаратом, а не текстом: это не проза, а устройство навигации, и
   стоять она должна тише вводки, под которой лежит. */
.alpha {
	font-family: var(--font-mono);
	font-weight: 400;
	font-size: var(--size-apparatus);
	/* 2,4, а не 1,9: при кегле аппарата 1,9 давало шаг строк 21,4 px, 2,2 — 22,8, и две
	   ссылки, вставшие друг над другом, нарушали СК 2.5.8 WCAG 2.2 (24 px).
	   Поймал `.verify.mjs` 24.09.2026 после переписки определений. */
	line-height: 2.4;
	color: var(--muted);
	margin-block: var(--s4) 0;
	max-width: none;
}
/* Цель нажатия (СК 2.5.8 WCAG 2.2). До 25.09 ссылка была блочно-строчной
   высотой 24 px — тот же приём, что у `.nav a`, — когда шаг строк 1,9 и 2,2
   давал 22,8 и 23,7 px между центрами. Блочно-строчная ссылка не пускала
   точку к последнему слову; теперь её держит единица `.alpha-i` ниже. */
.alpha a {
	/* Цель СК 2.5.8: строчная ссылка высотой 22–25 px с полем; где меньше 24,
	   её держит интервал — шаг строк 2,4 (26–34 px между центрами), и
	   соседи по строке отстоят на « · ». Термин, перенесённый внутри единицы,
	   даёт рамку выше 24 сам. */
	padding-block: var(--s1);
	color: var(--muted);
	text-decoration-color: var(--rule);
}
/* Термин и его точка — одна единица `.alpha-i` (её пишет `.indexes.mjs`):
   строка рвётся только между единицами, то есть после точки. Пока точка
   стояла отдельным узлом, она начинала строку (аудит 25.09, F38). Чистым
   CSS это не решалось, три приёма проверены и отвергнуты: точка в `::after`
   ссылки уходила одна на строку или оставляла отступ в начале строки;
   `white-space: nowrap` на разделителе в WebKit выносил точку за край на
   3–7 px; строчная ссылка без единицы давала при переносе рамку во всю
   строку, и гейт 2.5.8 ловил 23,7 px между целями.

   Единица — блочно-строчная: внутри неё строку не разорвать между термином
   и точкой. Ссылка внутри строчная, поэтому неразрывный пробел держит точку
   у последнего слова, и перенесённый длинный термин кончается «…artist ·».
   Единица-flex с блочной ссылкой отвергнута: точка вставала у правого края
   коробки ссылки, далеко от последнего слова. */
.alpha-i { display: inline-block; max-inline-size: 100%; }
@media (hover: hover) and (pointer: fine) {
	.alpha a:hover { color: var(--fg); text-decoration-color: var(--fg); }
}

/* Цель перехода не должна уезжать под липкую шапку. Величина та же, что у
   строк реестра: её ставит слой движения по фактической высоте закреплённой
   шапки, а она меняется и по ширине, и по кеглю корня — 113 px на 1440,
   148 на 390, 195 при двойном увеличении текста. Своё число здесь было бы
   верным ровно для одной из трёх раскладок. */
.idx-row[id] { scroll-margin-block-start: calc(var(--head-pinned, 9.5rem) + var(--s4)); }

.idx-row--def { row-gap: var(--s1); }
.idx-row--def .d {
	font-size: var(--size-small);
	color: var(--muted);
	text-wrap: pretty;
}
@media (min-width: 50.625em) {
	.idx-row--def { grid-template-columns: minmax(0, 15em) minmax(0, 1fr); }
	.idx-row--def .t { grid-column: 1; grid-row: 1; }
	.idx-row--def .d { grid-column: 2; grid-row: 1; }
	.idx-row--def .u { grid-column: 2; grid-row: 2; }
}
@media (hover: hover) and (pointer: fine) {
	a.idx-row--def:hover .d { color: var(--fg); }
}

/* Адреса в пометке — длинные строки без пробелов, и в узкой графе
   аппарата они выходили за её правый край в столбец текста. Перенос
   разрешён внутри слова: адрес читают по частям, а не целиком. */
.note code { font-family: inherit; overflow-wrap: anywhere; }

/* Прочерк «нет даты» был глифом, и на 14 px его штрих при сглаживании
   размазывается на две строки пикселей: замер по отрисовке дал 2,45 при
   пороге 4,5 в светлой теме и 2,99 в тёмной. Номинально `--muted` даёт
   7,39 — арифметика этого не видит, потому что не знает, сколько пикселей
   займёт штрих.

   Отсутствие рисуется линейкой, а не буквой: линейка — не текст, к ней
   применяется порог 3:1, и на несущей ступени — 55 % чернил в светлой
   теме и 40 % в тёмной — пара к грунту даёт 3,24 и 3,08. Слово `none` остаётся в разметке для
   машины и для чтения с экрана.

   Слово при этом нигде не спрятано, и это третья редакция. Первая красила
   его в прозрачный — поймала собственная проверка «текст цветом своего
   грунта», и поймала верно: прозрачный текст от невидимого отличается
   только намерением, а проверка намерений не читает. Вторая вырезала его
   в точку — и попала под проверку обрезанных блоков при тексте 200 %,
   потому что вырезанный в точку блок от обрезанного тоже отличается
   только намерением. Обе проверки правы, а приём был неверный: имя даётся
   картинке, а не прячется текстом. Линейка объявлена изображением с
   именем `none`. */
.reg .none {
	display: inline-block;
	inline-size: 1.1em;
	block-size: 1px;
	background: var(--rule-strong);
	vertical-align: middle;
}

/* Таблица реестра — не часть столбца текста, а собственный ряд раздела.
   Пять граф в мере получали 816 px на всех, и это тот случай, где графа
   аппарата слева стоит дороже, чем стоит: заголовок и лид от неё
   выигрывают, таблица задыхается. Проза остаётся в мере, таблица её
   ломает — обычный приём издания.

   Сделано переносом в разметке, а не отрицательным полем. Отрицательное
   поле пробовалось и снято: таблица уезжала влево под графу аппарата и
   ложилась на пометку, которая там стоит. Элемент сетки, занимающий обе
   графы, такого сделать не может по построению. */
.register-ledger .sources { grid-column: 1 / -1; }
/* Отбивка плиты своя и меньше разделовой. Раздел прозы получает сверху
   ступень `s6`, потому что над ним стоит липкая шапка и подпись раздела
   упиралась бы в её кромку. Плита заявления шапке не подчиняется: она
   сама себе кромка, и лишняя ступень читалась бы на ней пустым полем.
   Величина не подобрана на глаз — она взята под бюджет чернил: на самой
   короткой странице корпуса, `fr-sources.html`, плита при `s6` занимала
   29,9 % документа при потолке 25 %. Гейт `.invert.mjs` печатает долю
   на каждой странице, и величина проверяется им, а не глазом. */
.register-block { --row-pad-start: var(--s5); --row-pad-end: var(--s4); }
/* Ведомость идёт сразу за заявлением и отбивается от него на ступень
   меньше разделовой: между ними не смена темы, а продолжение одной
   мысли. На полной разделовой отбивке под плитой оставалось пустое поле
   в сто пикселей, и заявление читалось оторванным от того, что оно
   объявляет. */
.register-ledger { --row-pad-start: var(--s5); }

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

   Краска не заведена. Печать берёт роль `--seal`, объявленную вместе с
   остальными красками вывернутой комнаты, и потому переворачивается вместе
   с темой сама. Плотность и её основание записаны там же, рядом с
   объявлением роли: здесь их повторять нельзя, две записи одного числа
   расходятся при первой же правке. Так и вышло — в этой шапке тридцать
   строк стояла прежняя плотность в 22 %, уже снятая ниже по файлу.

   Порог контраста к печати не применяется, и это надо сказать прямо:
   она ничего не сообщает. Имя практики стоит в шапке словом, в подвале
   словом и в машинном двойнике словом; печать не несёт ни одного
   сведения, которого нет рядом текстом. Убрать её — не потеряется
   ничего, кроме веса.

   Уходит вправо до кромки окна: `--bleed-out` — это в точности
   расстояние от края столбца текста до края окна, и оно уже посчитано
   строкой раскладки. Луч знака доходит до кромки и обрывается ею, а не
   полем.

   Стоит собственным элементом, а не псевдоэлементом графы счётчика. У
   комнаты оба псевдоэлемента заняты — `::before` красит грунт, `::after`
   несёт зерно, — а графа несёт трансформацию слоя появления, и всякая
   трансформация создаёт систему координат для того, что лежит внутри.
   Печать из-за этого отсчитывалась от графы, ехала вместе с ней и в конце
   перехода прыгала через полполосы. Замер поймал прыжок покадрово; чтение
   файла показывало правило, которое выглядело верным. */
.register-block > .seal {
	position: absolute;
	z-index: var(--z-ground);
	/* Высота ограничена сверху, а не только плитой. `inset-block` привязывал
	   знак к обеим кромкам, и на странице с заявлением в пять строк он
	   разрастался: замер по всем 79 страницам дал ширину от 207 до 665 px,
	   медиана 258. Шестьсот шестьдесят пять — это 61 % ширины ряда, то есть
	   уже не печать, а водяной знак во весь блок. Потолок 14 rem держит
	   медиану и снимает выбросы. */
	inset-block-start: var(--s3);
	inset-inline-end: calc(-1 * var(--bleed-out));
	block-size: min(calc(100% - 2 * var(--s3)), 14rem);
	inline-size: auto;
	/* 597,56 : 532,08 — пропорция самого знака, снятая из его контура. */
	aspect-ratio: 597.56 / 532.08;
	background: var(--seal, var(--rule));
	mask: var(--mark-sign) no-repeat center / contain;
	pointer-events: none;
}
/* На узкой полосе плита выше — заявление идёт в пять строк, — и знак,
   посаженный по её высоте, накрыл бы текст. Там он отвязывается от
   кромок и садится по ширине. */
@media (max-width: 50.624em) {
	.register-block > .seal { inset-block: auto var(--s3); block-size: auto; inline-size: 11rem; }
}
/* Печать не печатается: на бумаге она была бы серым прямоугольником
   поверх заявления. */
@media print {
	.register-block > .seal { display: none; }
}


/* ── Мера ──────────────────────────────────────────────────────────────
   Потолок меры был привязан к одному контейнеру, `.body`, и всё, что вне
   его, шло во всю графу. Замер по числу строк на элемент: графа
   утверждения в реестре — 358 px на 390, 579 на 768, **833 на 1024**,
   312 на 1440. То есть между 640 и 1200 вторая дорожка не ограничена
   ничем, и сплошная проза идёт по 75–101 знаку в строке при верхней
   границе 75.

   Умолчание перевёрнуто: потолок стоит на ролях сплошной прозы, а
   снимается там, где набор табличный по существу. Так новый компонент
   получает меру по построению, а не потому, что о ней вспомнили. */
p, li, dd, blockquote, figcaption { max-width: var(--measure); }
/* Табличное — вне правила: там ширину задаёт графа, а не мера. */
.reg dd, .reg dt, .reg-head > *, .idx-row > *, .foot .sitemap a { max-width: none; }
/* Утверждение и состояние в реестре — предложения, и мера им нужна;
   источник и дата — величины, им нужна графа.

   Поправка. Величина коротка, пока источник — одна ссылка. Как только в
   графе оказывается перечень из пяти инструментов со статьями, это уже
   проза, и на 768 и 1024 px, где реестр складывается в один столбец, она
   пошла по 77 знаков в строке при потолке 75. Потолок ставится и на них:
   короткой дате он ничего не делает, длинную ссылку переносит раньше. */
@media (min-width: 40em) and (max-width: 74.999em) {
	.reg .c, .reg .t, .reg .s, .reg .d { max-width: var(--measure); }
}


/* ── Аппарат поверх работы ─────────────────────────────────────────────
   Краевая плита проходит под графой аппарата, и пометка оказывается
   наполовину на тёмном грунте комнаты, наполовину на светлой стене
   снимка. Читаемость перестаёт быть свойством пары ролей: под буквой не
   грунт, а фотография, и она разная в каждой точке.

   Три редакции, и первые две названы здесь, чтобы к ним не возвращаться.

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

   Вторая ставила `mix-blend-mode: difference`. Не работает здесь по
   устройству, а не по вкусу: предки пометки несут трансформацию слоя
   появления, а трансформация создаёт контекст наложения — буква
   смешивается с прозрачным внутри своей группы и остаётся белой.
   Замером видно сразу: на светлой бумаге пометка исчезала.

   Третья — эта. Цвет режется по краю снимка внутри самой буквы:
   градиент с жёсткой границей заливает текст, `background-clip: text`
   оставляет от заливки только глифы. Один текстовый узел, ни одного
   дубля в разметке, машинная копия не удваивается. Положение границы —
   одно число `--split`, которое ставит скрипт из координат снимка;
   когда пересечения нет, оно равно 100 %, и текст одноцветный.

   Запасной путь обязателен: без `background-clip: text` прозрачный цвет
   оставил бы пустое место. Поэтому весь приём стоит внутри `@supports`,
   а цвет по умолчанию остаётся ролью. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
	/* Номер раздела набран фирменным цветом, пометка — приглушённым:
	   у каждого своя роль над разрезом. Здесь стояла роль чернил, и на
	   пяти страницах с плитами на вылет счётчик терял BROWN MADDER —
	   правило акцента («он метит аппарат») ломалось ровно там, где плита
	   и делает страницу заметной. Роль называется явно, потому что цвет
	   идёт заливкой, а не свойством `color`. */
	.js .row:has(figure.plate--edge, figure.plate--full) .register .note,
	.js .row:has(figure.plate--edge, figure.plate--full) .register .num {
		--art-a: 100%;
		--art-b: 100%;
		--note-role: var(--muted);
		/* Верхний цвет берётся ролью явно. Стоял `currentColor` — и брал
		   его из этого же правила, где цвет уже прозрачный: верхняя
		   половина набора исчезала целиком. Видно только замером на том
		   положении прокрутки, где разрез вообще возникает. */
		/* Маска строго по прямоугольнику работы: две жёсткие кромки, а не
		   одна. Роль — чернила — роль. Одна граница описывала только
		   случай, когда работа стоит ниже набора; когда она стоит выше,
		   чернила уходили на тёмный грунт комнаты и пропадали. Обе кромки
		   ставит скрипт из координат снимка; по умолчанию обе равны ста
		   процентам, то есть маски нет вовсе. */
		background-image: linear-gradient(
			to bottom,
			var(--note-role) 0 var(--art-a),
			var(--ink-on-art) var(--art-a) var(--art-b),
			var(--note-role) var(--art-b) 100%);
		-webkit-background-clip: text;
		background-clip: text;
		color: transparent;
		-webkit-text-fill-color: transparent;
	}
	/* Роль номера объявляется ПОСЛЕ общего правила, а не до него: там
	   `--note-role` ставится приглушённым и для пометки, и для номера, вес
	   селектора тот же, и объявленное выше молчало. Ровно из-за этого
	   счётчик и терял фирменный цвет на страницах с плитами: правило в
	   файле было, а цвет — нет. Проверено замером отрисованной заливки. */
	.js .row:has(figure.plate--edge, figure.plate--full) .register .num { --note-role: var(--accent); }
	.js .rk .row:has(figure.plate--edge, figure.plate--full) .register .num,
	.js .on-ink .row:has(figure.plate--edge, figure.plate--full) .register .num { --note-role: var(--accent-on-ink); }
	/* Ссылка сноски и время внутри пометки заливаются той же заливкой
	   родителя: собственный цвет выбил бы их из разреза и они остались бы
	   единственным местом, где буква не знает, на чём стоит. */
	.js .row:has(figure.plate--edge, figure.plate--full) .register .note :is(.note-n, time, b) {
		color: inherit;
		-webkit-text-fill-color: inherit;
		background: none;
	}
}

/* Печатный сброс приёма с разрезом цвета стоит ПОСЛЕ самого приёма, а не в
   общем печатном блоке выше: тот объявлен раньше, и при равном весе
   селектора побеждало правило приёма. Порядок здесь несущий, и переносить
   этот блок вверх нельзя. Проверено замером отрисованного цвета в режиме
   печати — чтение файла обоих раз показывало «правило есть». */
@media print {
	/* Разрез цвета по краю снимка на печати не работает и отнимает набор.
	   Приём заливает глифы градиентом и делает собственный цвет прозрачным;
	   браузер при печати фоны по умолчанию не выводит, и от ста трёх
	   элементов на восемнадцати страницах на бумаге не остаётся ничего —
	   ни номера раздела, ни пометки с источником и датой. То есть на печать
	   уходил документ без аппарата, ради которого он и сделан.
	   Найдено разбором 14.09.2026. */
	/* Вес селектора взят тот же, что у правила приёма: `.js .row:has(…)
	   .register .num` тяжелее, чем `.register .num`, и лёгкий сброс правило
	   не перебивал. Замер это и показал — чтение файла нет. */
	.js .row:has(figure.plate--edge, figure.plate--full) .register .num,
	.js .row:has(figure.plate--edge, figure.plate--full) .register .note,
	.js .row:has(figure.plate--edge, figure.plate--full) .register .note :is(.note-n, time, b),
	.register .num,
	.register .note,
	.register .note :is(.note-n, time, b) {
		background-image: none;
		-webkit-background-clip: border-box;
		background-clip: border-box;
		-webkit-text-fill-color: currentColor;
	}
	.js .row:has(figure.plate--edge, figure.plate--full) .register .num,
	.register .num { color: #000; }
	.js .row:has(figure.plate--edge, figure.plate--full) .register .note,
	.register .note { color: #444; }
}


/* Почта рвётся по `<wbr>` после «@», а при нехватке места — где придётся.

   Правило стояло обратное: `overflow-wrap: normal`, чтобы адрес не рвался
   посреди домена. Довод был верен по вкусу и неверен по последствию. Замер
   16.09.2026 при увеличении только текста: на 320 px адрес уходил за край
   на 94 px, на 390 — на 24, и даже на 1440 при корне 32 px — на 197.
   Достать уехавшее нечем, прокрутки вбок нет. Это потеря содержимого, и
   контакт — не то место, где её можно себе позволить.

   `break-word` здесь бесполезен: он не уменьшает минимальную ширину, а
   элемент строчно-блочный и берёт её целиком. Уменьшает только `anywhere`.
   Замер после правки: ни одного вылета на девяти сочетаниях корня и
   ширины. При обычном кегле адрес стоит одной строкой на всех ширинах —
   лишние места переноса просто не используются, а `<wbr>` остаётся
   предпочтительным. */
.contact-mail { word-break: normal; }


/* Вложенная комната доходит до низа своего раздела.
   Стена висит внутри раздела и красится своим тоном, а нижнее поле
   раздела оставалось в тоне родителя: между стеной и следующей комнатой
   стояла полоса чужого грунта — 160 px при `--s7`, 96 при `--s6`, 64 при
   `--s5`, то есть ровно нижнее поле ряда. С хода она читается не порогом,
   а висящей полоской. Грунт вложенной комнаты продлевается на эту
   величину, и порог снова один, а не два. */
.plates::before,
.plates::after { inset-block-end: calc(var(--row-pad-end) * -1); }


/* ══ Устройства права ═══════════════════════════════════════════════════
   Собраны по замеру корпуса: юрисдикция названа на 54 страницах из 88, и
   увидеть её можно было только прочитав абзац. Пометка у счётчика отвечает
   на первый вопрос принципала — касается ли раздел права его страны — до
   чтения. Поле в блоке реестра разрешает каждое право в его строки: одна
   ячейка равна одной строке, и каждая ведёт в неё ссылкой. Доля нигде не
   печатается: процент был бы величиной без источника, а ряд ячеек счётен.

   Цвет метки берёт `--fg`, а не `--ink`: графа аппарата попадает внутрь
   вывернутой комнаты, и роль обязана переключаться вместе с грунтом.
   Различение метки от счётчика держится кеглем и рисунком — 13 px
   моноширинного против 40 px дисплейного, — поэтому соперничества с
   краплаковым номером нет даже там, где оттенок не виден вовсе.

   Замерено: метка 31×24 при 390, 34×24 при 1440; код чернилами 11,76 в
   светлой теме и 14,12 в тёмной; рамка на несущей ступени 3,24 и 3,08 при
   пороге 3. Внутри чернильной комнаты набор 11,76 и 14,12. */
/* ── Устройство 3. Пометка юрисдикции в графе аппарата ───────────────── */
.jur {
	display: flex;
	flex-wrap: wrap;
	gap: var(--s1);
	margin-block: calc(var(--s2) * -1) 0;
	max-width: none;
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-label);
	letter-spacing: var(--tracking-label);
}
.jur a {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-block-size: calc(var(--s3) + var(--s2));
	min-inline-size: calc(var(--s3) + var(--s2));
	padding-inline: var(--s2);
	color: var(--fg);
	text-decoration: none;
	box-shadow: inset 0 0 0 1px var(--rule-strong);
}
.jur abbr { text-decoration: none; }
.jur a:hover { box-shadow: inset 0 0 0 1px currentColor; }
/* ── Устройство 4. Поле юрисдикций в блоке реестра ───────────────────── */
.jurs { margin-block-start: var(--s5); }
.jurs { grid-column: 1 / -1; }
.jurs dl { margin: 0; }
.jurs-l {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: var(--s1);
	padding-block: var(--s3);
	border-bottom: 1px solid var(--rule);
}
.jurs-l:first-of-type { border-top: 1px solid var(--rule-mid); }
.jurs dt {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	letter-spacing: var(--tracking-label);
	color: var(--muted);
}
.jurs dt abbr { text-decoration: none; color: var(--fg); margin-inline-end: var(--s2); }
.jurs dd { margin: 0; max-width: none; }
.jurs-r { display: flex; flex-wrap: wrap; gap: var(--s1); }
.jurs-r a {
	flex: none;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-block-size: calc(var(--s3) + var(--s2));
	inline-size: calc(var(--s4) + var(--s2));
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	font-variant-numeric: tabular-nums;
	color: var(--fg);
	text-decoration: none;
	box-shadow: inset 0 0 0 1px var(--rule-strong);
}
.jurs-k {
	font-weight: 400;
	font-family: var(--font-mono);
	font-size: var(--size-apparatus);
	line-height: var(--leading-tight);
	color: var(--muted);
	margin-block: var(--s3) 0;
}
/* Две колонки появляются на том же пороге, что и сама графа аппарата: поле
   живёт внутри `.row`, и переключаться они обязаны вместе. Правило стояло
   без условия — я потерял медиазапрос при переносе из прототипа, — и на
   320 px ячейки уходили на 340: документ ехал вбок на двадцать пикселей.
   Поймала глубокая проверка на восьми ширинах. */
@media (min-width: 50.625em) {
	.jurs-l { grid-template-columns: 14em minmax(0, 1fr); gap: var(--s4); align-items: baseline; }
}

/* Тихое поле юрисдикций — на опорных материалах.

   Заказчица 16.09.2026: пометки FR / GB / IT / JP оставить, но визуально
   очень спокойно, чтобы статья не выглядела как compliance memo. Громким
   поле делают три вещи, и убираются все три: рамка вокруг номера,
   разлиновка строк и графа шириной в четырнадцать кеглей, из-за которой
   две страны читаются таблицей.

   Что НЕ убирается — размер цели нажатия. Ячейка 40 × 24 стоит ровно на
   пороге 24 × 24 из WCAG 2.2; снять с неё высоту вместе с рамкой значило
   бы купить тишину за доступность. Поэтому уходит только рисунок: рамки
   нет, цвет приглушённый, подчёркивание появляется под указателем.

   Полное название страны остаётся в разметке: тишина здесь зрительная, а
   не смысловая, и читателю с экранным чтением поле достаётся целиком.

   Справочные записи под `/glossary/` этого класса не получают: там
   перечень прав — предмет страницы, и таблица на своём месте. */
.jurs--quiet .jurs-l,
.jurs--quiet .jurs-l:first-of-type {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	column-gap: var(--s2);
	row-gap: 0;
	grid-template-columns: none;
	padding-block: var(--s1);
	border: 0;
}
.jurs--quiet .jurs-name { color: var(--muted); }
.jurs--quiet .jurs-r { gap: 0; }
/* Рамка была единственным признаком, по которому номер читался ссылкой:
   без неё остаётся просто число, и первый же снимок это показал. Вместо
   рамки — подчёркивание, которым на этом сайте помечены все ссылки. Так
   тише и вдобавок согласованнее: поле перестаёт быть отдельным устройством
   со своими правилами. */
.jurs--quiet .jurs-r a {
	box-shadow: none;
	color: var(--muted);
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.18em;
	text-decoration-color: var(--rule-strong);
}
@media (hover: hover) and (pointer: fine) {
	.jurs--quiet .jurs-r a:hover { text-decoration-color: var(--fg); }
}

/* ── Узкая полоса: ритм (владелец, 25.09.2026) ─────────────────────────
   «Отступы между текстами, заголовками и т. д. на мобильной вообще ни разу
   не красивые». Замер на iPhone 17 Pro Max (440 × 956, WebKit), главная:
   - номер раздела «02/12» стоял ПОСЛЕ текста раздела: графа реестра на
     узкой полосе складывается под текст, и номер читался началом уже
     следующего раздела;
   - после заголовка раздела шло то 32, то 64, 96 и 149 px; утверждение
     «Независимости» растягивалось на целый экран;
   - абзацы шли через 32 px — на узком кегле это разрыв, а не отбивка;
   - строка «Cultural strategy» в шапке занимала целый ряд, а заголовок
     первого экрана говорит то же самое.
   Здесь всё сведено к одной лестнице со шкалы: номер и метка раздела
   сверху, после заголовка 32, между абзацами 24 (16 + 8), крупные блоки
   через 32–64. Верхнее поле раздела (96) не трогается: оно держит подпись
   ниже липкой шапки при переходе по якорю. */
@media (max-width: 50.624em) {
	.masthead > .standing { display: none; }
	.row > .register { order: -1; margin-block: 0; }
	.titlepage > .register { display: none; }
	.titlepage { gap: calc(var(--s4) + var(--s3)); }
	/* Поле заголовка складывалось с зазором сетки: 32 + 48 = 80 до лида. */
	.titlepage > .hero-head { margin-block-end: 0; }
	.body p + p, p.body + p.body, .body + p.body { margin-block-start: calc(var(--s3) + var(--s2)); }
	.row--statement { min-block-size: auto; }
	.row--statement h2 + .body { margin-block-start: var(--s4); }
	blockquote.credit { margin-block: var(--s4); }
}

/* ── Узкая полоса: правки аудита 25.09 ────────────────────────────────
   Отдельным блоком после блока владельца: при равном весе выигрывает
   позднее правило. Замер и основания — 06-внутреннее/аудит-отступов-25.09. */
@media (max-width: 50.624em) {
	/* Крошка над номером раздела: `order: -1` у номера поднимал его и над
	   крошкой. Строка крошки не ниже цели нажатия. */
	.row > .crumb { order: -2; line-height: var(--target); margin-block-end: var(--s3); }
	/* Лид → подпись 24 на всех страницах, как лид → абзац. */
	.lead + .attrib { margin-block-start: calc(var(--s3) + var(--s2)); }
	/* h1 → текст 48 и на указателях, как у статей и первого экрана. */
	.row > div > h1 + :is(p, .body) { margin-block-start: calc(var(--s4) + var(--s3)); }
	/* Работа на телефоне стоит в 64 от текста; было 112, 96 и 80. У плиты —
	   прямого ребёнка раздела — 16 добавляет зазор сетки. */
	figure.plate--full { margin-block-start: var(--s5); }
	.row > figure.plate { margin-block-start: calc(var(--s4) + var(--s3)); }
	/* Содержание без метки (французская главная) — та же пауза, что у EN. */
	.titlepage + .toc { margin-block-start: var(--s5); }
	/* Поле аппарата с примечанием держит 32 до метки раздела. */
	.row > .register .note:last-child { margin-block-end: var(--s3); }
	/* Подпись под лидом принадлежит шапке: до текста 32, как у блока. */
	p.body.attrib + p { margin-block-start: var(--s4); }
	/* Подраздел на узкой полосе: над h3 48, ступень ниже широкой. */
	.body h3:not(:first-child) { margin-block-start: calc(var(--s4) + var(--s3)); }
	/* Подвал: снаружи групп не меньше, чем внутри, и метка ближе к своему. */
	.foot { gap: var(--s4); }
	.sitemap, .sitemap-col { row-gap: var(--s4); }
	.foot-ask { padding-block-start: var(--s4); }
	/* Страница кончается ведомостью: её линейка закрывает страницу, вторая
	   линейка подвала в 64 px ниже читалась пустой строкой ведомости. */
	main:has(> .row:last-child :is(.sources-list, .record):last-child, > .row:last-child .idx-group:last-child > .idx-row:last-child) + .foot { border-top: 0; }
	/* Шапка в один ряд, где помещается: на 430–440 знак и меню встают
	   строкой (78 px вместо 113). Возражение комментария у сетки шапки —
	   flex ломал надстрочную строку — здесь снято: её ниже 810 нет. */
	.masthead { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--s3); }
	/* Пауза между разделами 128 вместо 160: верх раздела 96 держит подпись
	   под липкой шапкой при переходе по якорю и не трогается, низ — 32.
	   Правится переменная, а не поле: её читают `.plates::before/::after`.
	   Тёмные комнаты держат 64, иначе их плиты стали бы 96/32. */
	.row { --row-pad-end: var(--s4); }
	.rk { --row-pad-end: var(--s5); }
}
/* Карточка направления на узком телефоне симметрична колонке: линейка и
   текст на колонке, заливка нажатия — на 16 шире с обеих сторон. */
@media (max-width: 39.999em) {
	.area { margin-inline-start: 0; padding-inline: 0; }
	.area::before, .area::after { inset-inline: calc(var(--s3) * -1); }
}
