/* =============================================================================
   Дизайн-система издания. Одна тема, тёмная. Светлой нет.

   Тема ровно одна: ни переключателя, ни @media (prefers-color-scheme), ни
   секций, которые инвертируются посреди страницы. Единственное исключение —
   @media print в конце файла: на бумагу издание печатается по-бумажному,
   и это не вторая тема, а вывод в другой носитель.

   Отстройка. Прямые конкуренты (vc.ru, Дзен) тоже тёмные, поэтому отличие
   переезжает с цвета фона на всё остальное. У них холодный серый почти-чёрный,
   Roboto и утилитарная лента без иерархии. У нас тёплый чернильный фон с
   уходом в коричневый (тон 34°, а не 220-240°), издательская типографика с
   резким контрастом кеглей, карминовая рубрика, воздух вместо коробок и
   волосяные линии вместо рамок. Это и вкусовое решение, и защита: Яндекс
   наказывает за мимикрию под известные ресурсы, поэтому похожесть на них
   здесь — не «безопасный дефолт», а риск.

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

/* ------------------------------------------------------------------ шрифт */
/* Golos Text — свободная кириллическая гарнитура (SIL OFL), самобытная,
   в отличие от Roboto и Inter не читается как «шрифт по умолчанию».

   ФАЙЛОВ ШРИФТА В РЕПОЗИТОРИИ НЕТ. Что положить и куда — в assets/fonts/README.md:
       assets/fonts/GolosText-Regular.woff2    (400)
       assets/fonts/GolosText-Medium.woff2     (500)
       assets/fonts/GolosText-DemiBold.woff2   (600)
   Больше ничего править не нужно: объявления ниже ждут именно эти имена,
   сборка копирует подпапки assets/ как есть. Пока файлов нет, работает
   запасной стек из --font-sans, вёрстка не меняется. Сторонний CDN не
   подключаем: чужой домен в критическом пути и утечка адресов читателей. */

/* Заготовка на случай, если после подключения Golos Text подмена шрифта будет
   заметно дёргать вёрстку: подогнать метрики запасного и подставить его
   первым в --font-sans после 'Golos Text'.
*/

/* ------------------------------------------------------------------ токены */

:root {
  color-scheme: dark;

  /* --- палитра ---------------------------------------------------------
     Фон #15120E — тёплый чернильный: hsl(34° 20% 7%). Тон 34° уводит его в
     коричневый, то есть в сторону типографской краски, а не в семейство
     холодных почти-чёрных, где сидят vc.ru и Дзен (у них тон 220-240°,
     насыщенность около нуля). Чистый чёрный не берём: на нём светлый текст
     даёт ореол, а полоса выглядит проваленной. Ступени поверхности
     #1F1B14 и #2A2318 подняты по L* на 4.4 и 8.5 — ровно настолько, чтобы
     врезка читалась подложкой, а не вторым фоном.

     Текст #EFEAE1 — тёплый почти-белый, не #FFF: чистый белый на тёмном
     режет и «звенит». Приглушённый #A69B89 держит ту же разницу светлоты
     к фону, что и на светлой теме (ΔL* 58.8 против 58.1), поэтому мета
     осталась ровно такой же по весу, какой была.

     Линии подобраны отдельно, а не инверсией: простая инверсия даёт на
     тёмном волосок, которого не видно. Перепад L* к фону: волосяная 12.3,
     усиленная 20.9, структурная 36.0 (на светлой теме было 8.7, 17.5 и 89.6 —
     последняя была чернилами, и на тёмном её нельзя оставить чернилами,
     иначе каждая отбивка превращается в светящуюся полосу).

     Акцент #EF5B63 — тот же кармин, поднятый по светлоте: тон 356° (синий
     уклон кармина сохранён, B > G), насыщенность 81%. Исходный #A31621 на
     этом фоне даёт 2.40:1 и не проходит вовсе. Поднятый даёт 5.64:1 — выше
     AA (4.5:1) с запасом. AAA (7:1) для красного здесь недостижим
     геометрически: перебор всего диапазона тонов 344-10° при насыщенности
     от 65% показывает, что 7:1 требует светлоты HSL не ниже 67%, а на тоне
     кармина — не ниже 71%, то есть #ED7E85. Это уже роза, а не кармин, и
     характер рубрики, ради которого всё и делается, пропадает. Выбран
     максимум контраста при сохранённом характере.
     Поднятый акцент #F5787F (7.00:1) — состояние наведения и нажатия: на
     тёмном «нажато» светлее, а не темнее, иначе контраст рушится. */
  --paper: #15120e;
  --paper-sunk: #1f1b14;
  --paper-deep: #2a2318;
  --ink: #efeae1;
  --ink-muted: #a69b89;
  --rule: #322b20;
  --rule-strong: #463e2e;
  --rule-bold: #6b6150;
  --accent: #ef5b63;
  --accent-lift: #f5787f;

  /* --- шрифт ----------------------------------------------------------- */
  --font-sans: 'Golos Text', system-ui, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
  --font-mono: ui-monospace, 'SF Mono', 'Cascadia Mono', Consolas, 'Liberation Mono', monospace;

  /* Ступени веса. Значения не менялись при переходе на тёмное — менялось то,
     кто какую ступень берёт. Светлый текст на тёмном поле выглядит на полступени
     жирнее того же начертания на бумаге, поэтому заголовки съехали с 600 на 500
     (правило h1-h4 ниже и три места, где 600 стоял явно). На 600 остались
     логотип, надзаголовки-метки, шапка таблицы, выделение в тексте и рубрика:
     это мелкий кегль, там лишний вес не мешает, а помогает. Начертание рубрики
     трогать нельзя вовсе — кегль, прописные, разрядка и вес у неё те же. */
  --w-regular: 400;
  --w-medium: 500;
  --w-semi: 600;

  /* --- типографическая шкала -------------------------------------------
     Контраст между уровнями намеренно резкий: заголовок статьи почти втрое
     крупнее текста (56 против 19). Ступени 12-13-15-17-19-22, дальше
     заголовки на clamp — они и задают разницу между экраном и телефоном. */
  --fs-2xs: 0.75rem;    /* 12 — надзаголовки, рубрики, метки */
  --fs-xs: 0.8125rem;   /* 13 — мета, подписи под картинками */
  --fs-sm: 0.9375rem;   /* 15 — служебные списки, подвал */
  --fs-base: 1.0625rem; /* 17 — интерфейсный текст, лиды витрин */
  --fs-md: 1.1875rem;   /* 19 — текст статьи */
  --fs-lg: 1.375rem;    /* 22 — лид статьи, цитата */
  --fs-xl: clamp(1.3125rem, 1.16rem + 0.68vw, 1.5rem);   /* 21 → 24  h3 */
  --fs-2xl: clamp(1.5rem, 1.21rem + 1.25vw, 1.875rem);   /* 24 → 30  h2 */
  --fs-3xl: clamp(1.75rem, 1.36rem + 1.7vw, 2.25rem);    /* 28 → 36  крупная карточка */
  --fs-4xl: clamp(2rem, 1.5rem + 2.2vw, 2.75rem);        /* 32 → 44  h1 витрины */
  --fs-5xl: clamp(2.25rem, 1.29rem + 4.1vw, 3.5rem);     /* 36 → 56  h1 статьи */

  --lh-tight: 1.06;
  --lh-head: 1.16;
  --lh-snug: 1.3;
  --lh-base: 1.5;
  --lh-text: 1.62;

  /* Разрядка заголовков ослаблена: на тёмном поле светлые буквы визуально
     набухают и съедают просвет, поэтому прежние -0.025 и -0.015 читались уже
     как слипание. Теперь -0.016 и -0.006 — заголовок остаётся плотным, но
     буквы не срастаются. Разрядка меток (--ls-label) не менялась: на ней
     стоит рубрика, а её начертание неприкосновенно. */
  --ls-tight: -0.016em;
  --ls-head: -0.006em;
  --ls-label: 0.09em;

  /* --- шкала отступов --------------------------------------------------
     Плотность низкая: воздух — основной инструмент разделения, линейка
     подключается только там, где воздуха не хватает. */
  --space-3xs: 4px;
  --space-2xs: 8px;
  --space-xs: 12px;
  --space-sm: 16px;
  --space-md: 24px;
  --space-lg: 32px;
  --space-xl: 48px;
  --space-2xl: 64px;
  --space-3xl: 96px;

  /* --- ширины ----------------------------------------------------------- */
  --measure: 680px;     /* колонка чтения */
  --width-page: 1180px; /* полоса набора */
  --width-side: 300px;  /* боковая колонка витрин */
  --gutter: 24px;
  --col-gap: 64px;
  --head-h: 64px;       /* шапка: одна строка, меньше 72 по требованию */

  /* Вынос картинки в правое поле полосы материала. Ноль до тех пор, пока
     поле не станет заведомо шире выноса: на 1000 пикселях свободного поля
     136, на 1180 - уже 226. Значения ниже с запасом влезают в оба, поэтому
     горизонтальной прокрутки не появляется. Ступени берутся из шкалы
     отступов, отдельного размера у выноса нет. */
  --bleed: 0px;

  /* --- линии и скругления ----------------------------------------------
     Скругление одно на весь сайт и равно нулю. Острый угол — язык бумаги
     и печати; мягкий — язык приложений. Смешивать нельзя, поэтому
     переменная одна и её значение не переопределяется нигде. */
  --hairline: 1px;
  --radius: 0;

  /* --- моторика ---------------------------------------------------------
     Сдержанная: только смена цвета и подчёркивания. Ничего не выезжает,
     не масштабируется и не пружинит. */
  --dur-fast: 120ms;
  --dur: 200ms;
  --dur-slow: 400ms;
  --ease: cubic-bezier(0.2, 0.6, 0.2, 1);
}

@media (min-width: 1000px) {
  :root {
    --bleed: var(--space-2xl);
  }
}

@media (min-width: 1180px) {
  :root {
    --bleed: calc(var(--space-3xl) * 2);
  }
}

/* --------------------------------------------------------- сброс и основа */

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

html {
  -webkit-text-size-adjust: 100%;
  hanging-punctuation: first allow-end last;
  scroll-padding-top: calc(var(--head-h) + var(--space-md));
}
/* overflow-x: hidden на html не ставим намеренно: он не чинит горизонтальную
   прокрутку, а прячет её вместе с диагностикой (scrollWidth перестаёт её
   показывать) и ломает position: sticky. Ширины держим по-честному. */

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--w-regular);
  line-height: var(--lh-base);
  font-kerning: normal;
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-wrap: break-word;
}

h1,
h2,
h3,
h4 {
  font-weight: var(--w-medium);
  letter-spacing: var(--ls-head);
  line-height: var(--lh-head);
  text-wrap: balance;
  margin: 0;
}

p {
  text-wrap: pretty;
}

img,
svg {
  max-width: 100%;
}

img {
  height: auto;
  display: block;
}

/* Ссылка по умолчанию: цвет чернил, подчёркивание акцентом. Так красного
   на полосе остаётся мало, а ссылка всё равно опознаётся без цвета —
   подчёркивание само по себе достаточный признак. */
a {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color var(--dur-fast) var(--ease),
    text-decoration-color var(--dur-fast) var(--ease);
}

a:hover {
  color: var(--accent);
  text-decoration-color: var(--accent);
}

/* На бумаге нажатая ссылка темнела. На тёмном темнеть некуда — там темнее
   значит хуже видно, поэтому нажатие подсвечивается. */
a:active {
  color: var(--accent-lift);
}

/* Рамка фокуса: акцент 5.64:1 к фону, то есть выше порога 3:1 для
   нефтекстовых элементов вдвое. Отступ в 3 пикселя оставляет между рамкой
   и буквами полосу фона — на тёмном это важнее, чем на светлом, иначе
   красная рамка сливается с текстом в одно пятно. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

/* Выделение мышью: акцент подложкой, текст цветом фона. Контраст той же
   пары, что и рубрика на полосе, — 5.64:1, читается. */
::selection {
  background: var(--accent);
  color: var(--paper);
}

/* Табличные цифры везде, где цифры стоят в столбик или сравниваются:
   мета-строки, счётчики, реквизиты, таблицы. */
time,
.card__meta,
.article__meta,
.sections__count,
.authors__count,
.profile__facts,
.arch__date,
.by,
.foot__legal,
.index__count,
.chron__label,
table {
  font-variant-numeric: tabular-nums;
}

.wrap {
  max-width: var(--width-page);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.skip {
  position: absolute;
  left: -9999px;
}

/* Единственное место, где рамка осталась цвета текста: ссылка появляется
   только по фокусу с клавиатуры, лежит поверх полосы и обязана читаться
   мгновенно. Структурной линейкой (--rule-bold) она бы утонула в фоне. */
.skip:focus {
  left: var(--space-xs);
  top: var(--space-xs);
  z-index: 40;
  background: var(--paper);
  color: var(--ink);
  padding: var(--space-2xs) var(--space-xs);
  border: var(--hairline) solid var(--ink);
  text-decoration: none;
}

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

.head {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--paper);
  border-bottom: var(--hairline) solid var(--rule);
}

.head__row {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  height: var(--head-h);
}

.brand {
  flex: none;
  display: inline-flex;
  align-items: baseline;
  text-decoration: none;
  color: var(--ink);
}

.brand:hover {
  color: var(--ink);
}

.brand__name {
  font-size: 1.25rem;
  font-weight: var(--w-semi);
  letter-spacing: var(--ls-tight);
}

/* Шаг между пунктами — 16, а не 24, как было при семи разделах. Считано:
   на полосе 1180 под меню остаётся 817 пикселей, восемь коротких названий
   с «Все темы» и линейкой занимают при шаге 24 ровно 815, то есть влезают
   впритык и вылезают от любого названия издания длиннее placeholder'а.
   При шаге 16 остаётся запас в две трети сотни, и строка остаётся одной
   строкой. Тот же шаг стоит на телефоне, так что значение теперь одно. */
.nav {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
  /* Прокрутка не должна обрезать буквы с выносами и рамку фокуса:
     полоса выше строки, отступы возвращают текст на место. */
  padding: var(--space-xs) 0;
  margin: calc(-1 * var(--space-xs)) 0;
}

.nav::-webkit-scrollbar {
  display: none;
}

.nav__link {
  flex: none;
  white-space: nowrap;
  font-size: var(--fs-sm);
  font-weight: var(--w-medium);
  color: var(--ink-muted);
  text-decoration: none;
}

.nav__link:hover {
  color: var(--ink);
}

.nav__link.is-current {
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.42em;
}

/* «Все темы» — не рубрика, а вход в полный перечень, и в ряду разделов это
   должно читаться без раздумий. Отбивается той же волосяной линейкой, что
   отделяет служебную группу справа: слева от линейки рубрики, справа нет.
   Разделов пятнадцать, в строке помещается восемь, поэтому пункт постоянный,
   а не «ещё» из выпадающего списка: списка в шапке нет вовсе. */
.nav__all {
  padding-left: var(--space-md);
  border-left: var(--hairline) solid var(--rule);
}

.head__aux {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding-left: var(--space-md);
  border-left: var(--hairline) solid var(--rule);
}

.head__aux .nav__link {
  color: var(--ink-muted);
}

/* Линейка шапки появляется при прокрутке, а не висит поверх пустой бумаги.
   Там, где scroll-timeline не поддерживается, линия просто есть всегда. */
@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: scroll()) {
    .head {
      border-bottom-color: transparent;
      animation: head-rule linear both;
      animation-timeline: scroll(root block);
      animation-range: 0 48px;
    }

    @keyframes head-rule {
      to {
        border-bottom-color: var(--rule);
      }
    }
  }
}

/* ------------------------------------------------------------------ сетка */

.layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--width-side);
  gap: var(--col-gap);
  padding-top: var(--space-xl);
  padding-bottom: var(--space-3xl);
}

.layout__main,
.layout__side {
  min-width: 0;
}

@media (max-width: 940px) {
  .layout {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2xl);
  }
}

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

.home__h1 {
  font-size: var(--fs-2xl);
  font-weight: var(--w-medium);
  letter-spacing: var(--ls-head);
  line-height: var(--lh-snug);
  max-width: 26ch;
  margin: 0 0 var(--space-xl);
}

.feed {
  border-top: var(--hairline) solid var(--rule);
}

.card {
  border-bottom: var(--hairline) solid var(--rule);
  padding: var(--space-lg) 0;
}

.card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  margin-bottom: var(--space-xs);
}

.card__title {
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  max-width: var(--measure);
  margin: 0 0 var(--space-2xs);
}

.card__title a {
  color: var(--ink);
  text-decoration: none;
}

.card__title a:hover {
  color: var(--accent);
}

.card__lead {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  max-width: var(--measure);
}

.card--big {
  padding-bottom: var(--space-xl);
}

.card--big .card__title {
  font-size: var(--fs-3xl);
  letter-spacing: var(--ls-tight);
  line-height: var(--lh-head);
  max-width: 20ch;
}

.card--big .card__lead {
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  color: var(--ink);
}

.card__cover {
  display: block;
  margin-bottom: var(--space-md);
}

.card__cover img {
  width: 100%;
  border-radius: var(--radius);
}

/* Рубрика — единственное цветное пятно в мета-строке. Прописные и разрядка
   отбивают её от даты и подписи без рамки и без подложки.

   ПРИ ПЕРЕХОДЕ НА ТЁМНОЕ ЭТОТ БЛОК НЕ МЕНЯЛСЯ, кроме значения --accent:
   кегль 12, вес 600, прописные, разрядка 0.09em — всё как было. Владелец
   прислал этот элемент отдельно, его начертание неприкосновенно.
   Контраст рубрики к фону 5.64:1. */
.badge {
  color: var(--accent);
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  text-decoration: none;
}

.badge:hover {
  color: var(--accent-lift);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

.card__format {
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.feed__more {
  margin: var(--space-lg) 0 0;
  font-size: var(--fs-sm);
}

.empty {
  color: var(--ink-muted);
}

/* ======================================================== витрины издания */
/* Главная, витрина раздела и лента свежего. Полоса набора делится на полосы
   материалов разного размера; разделяют их воздух и волосяная линия, коробок
   нет ни одной. Ритм задаётся только чередованием размеров, поэтому страница
   читается как разворот, а не как список одинаковых строк.

   Ни одного нового цвета, размера и скругления: всё из :root. */

.showcase {
  padding-top: var(--space-xl);
  padding-bottom: var(--space-3xl);
}

/* Служебная подпись для скринридера: число материалов рядом с разделом
   без неё читается как «Маркетинг шесть» и не значит ничего. */
.vh {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ------------------------------------------------------------ шапка выпуска */
/* Дескриптор издания под жирной линейкой. Он и есть h1 главной: крупнее всех
   на странице стоит заголовок ведущего материала, как в журнале, а не
   рекламный слоган во весь экран. */

.masthead {
  border-bottom: 2px solid var(--rule-bold);
  padding-bottom: var(--space-md);
  margin-bottom: var(--space-xl);
}

.masthead__title {
  font-size: var(--fs-lg);
  font-weight: var(--w-medium);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-head);
  max-width: 40ch;
  margin: 0;
}

/* -------------------------------------------------------- материал в потоке */

.story__title {
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
  margin: 0 0 var(--space-2xs);
}

.story__title a,
.lead-story__title a {
  color: var(--ink);
  text-decoration: none;
}

/* Наведение на материал целиком: меняется только цвет заголовка. */
.story:hover .story__title a,
.lead-story:hover .lead-story__title a,
.story__title a:hover,
.lead-story__title a:hover {
  color: var(--accent);
}

.story__lead {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  max-width: 56ch;
}

/* Картинка приподнимается на четыре пикселя. Это transform: он не участвует
   в потоке, поэтому соседние материалы не сдвигаются и текст не перетекает. */
.story__cover {
  display: block;
  margin-bottom: var(--space-md);
  background: var(--paper-sunk);
  transition: transform var(--dur) var(--ease);
}

.story__cover img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--radius);
}

.story:hover .story__cover,
.lead-story:hover .story__cover {
  transform: translateY(-4px);
}

.story__cover--lead {
  aspect-ratio: 12 / 5;
}

.story__cover--duo {
  aspect-ratio: 16 / 9;
}

.story__cover--side {
  aspect-ratio: 4 / 3;
  margin-bottom: 0;
}

/* --------------------------------------------------------- полосы потока */

.lead-story,
.band {
  padding-bottom: var(--space-xl);
  margin-bottom: var(--space-xl);
  border-bottom: var(--hairline) solid var(--rule);
}

.stream > .band:last-child {
  margin-bottom: 0;
}

/* Ведущий: заголовок и лид в разворот, лид посажен на нижнюю линию заголовка. */
.lead-story__head {
  display: grid;
  grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr);
  gap: var(--col-gap);
  align-items: end;
  margin-bottom: var(--space-lg);
}

.lead-story__title {
  font-size: var(--fs-4xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  margin: 0;
}

.lead-story__lead {
  margin: 0;
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  color: var(--ink);
}

.band--duo {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--col-gap);
}

/* Поперечный материал: картинка сбоку. Стороны чередуются от полосы к полосе,
   иначе три таких подряд выстраиваются в одинаковую лестницу. */
.story--wide {
  display: grid;
  grid-template-columns: minmax(0, 38%) minmax(0, 1fr);
  gap: var(--col-gap);
  align-items: start;
}

.story--flip {
  grid-template-columns: minmax(0, 1fr) minmax(0, 38%);
}

.story--flip .story__cover {
  order: 2;
}

.story__title--wide {
  font-size: var(--fs-2xl);
  line-height: var(--lh-head);
  letter-spacing: var(--ls-head);
  margin-bottom: var(--space-xs);
}

/* Три коротких. Вертикальная линейка ровно посередине промежутка: полоса
   читается как набор колонок журнала, а не как три плитки. */
.band--trio {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-lg);
  border-top: var(--hairline) solid var(--rule-bold);
  padding-top: var(--space-md);
}

.band--trio > .story + .story {
  border-left: var(--hairline) solid var(--rule);
  padding-left: var(--space-lg);
}

.story__title--brief {
  font-size: var(--fs-lg);
  margin-bottom: var(--space-xs);
}

.story--brief .byline {
  font-size: var(--fs-xs);
}

/* ----------------------------------------------------------- блоки витрины */

.block {
  border-top: var(--hairline) solid var(--rule-bold);
  padding-top: var(--space-sm);
  margin-top: var(--space-2xl);
}

.block__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-xs) var(--space-md);
  margin-bottom: var(--space-md);
}

.block__head .block__title {
  margin: 0;
}

.block__more {
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

/* Свежее: дата, заголовок, рубрика. Две колонки, потому что список служебный
   и растягивать его на всю ширину полосы незачем. */
.latest {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: var(--space-3xl);
}

.latest__row {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: var(--space-sm);
  padding: var(--space-2xs) 0 var(--space-xs);
  border-bottom: var(--hairline) solid var(--rule);
  break-inside: avoid;
}

.latest__date {
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  padding-top: 0.15em;
}

.latest__body {
  min-width: 0;
}

.latest__title {
  display: block;
  font-size: var(--fs-base);
  line-height: var(--lh-snug);
  font-weight: var(--w-medium);
  color: var(--ink);
  text-decoration: none;
}

.latest__title:hover {
  color: var(--accent);
}

.latest__section {
  display: block;
  margin-top: var(--space-3xs);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

/* Разделы перечнем. Оглавление номера: название и число, ничего больше. */
.index {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: var(--space-3xl);
}

.index__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-xs) 0;
  border-bottom: var(--hairline) solid var(--rule);
  break-inside: avoid;
}

.index__name {
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-head);
  color: var(--ink);
  text-decoration: none;
}

.index__name:hover {
  color: var(--accent);
}

.index__count {
  flex: none;
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

/* Подборки: тема целиком. Список сверху вниз, а не три колонки. */
.topics {
  list-style: none;
  margin: 0;
  padding: 0;
}

.topic {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 200px);
  gap: var(--col-gap);
  align-items: start;
  padding: var(--space-lg) 0;
  border-bottom: var(--hairline) solid var(--rule);
}

.topic:first-child {
  padding-top: var(--space-2xs);
}

.topic__title {
  font-size: var(--fs-2xl);
  line-height: var(--lh-head);
  margin: 0 0 var(--space-2xs);
}

.topic__title a {
  color: var(--ink);
  text-decoration: none;
}

.topic:hover .topic__title a,
.topic__title a:hover {
  color: var(--accent);
}

.topic__lead {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  max-width: 62ch;
}

.topic__meta {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.topic__count {
  display: block;
  color: var(--ink);
}

.topic__section {
  display: block;
  margin-top: var(--space-3xs);
  color: var(--ink-muted);
  text-decoration: none;
}

.topic__section:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* ------------------------------------------------------ шапка витрины раздела */

.showcase__head {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: var(--col-gap);
  align-items: end;
  border-bottom: 2px solid var(--rule-bold);
  padding-bottom: var(--space-lg);
  margin-bottom: var(--space-xl);
}

.showcase__h1 {
  font-size: var(--fs-4xl);
  line-height: var(--lh-head);
  letter-spacing: var(--ls-tight);
  margin: 0;
}

.showcase__stats {
  margin: var(--space-sm) 0 0;
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.showcase__intro {
  margin: 0;
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--ink-muted);
  max-width: 58ch;
}

/* Надзаголовок витрины: «Метка» над именем метки. Повторяет вид всех прочих
   меток издания (кегль 12, прописные, разрядка), но объявлен здесь, а не в
   общей группе надзаголовков: у него свой отступ снизу — до h1 нужен волосок
   воздуха, а не полная ступень. */
.showcase__label {
  margin: 0 0 var(--space-2xs);
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

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

.themes__group {
  margin-top: var(--space-2xl);
}

.themes__head {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: var(--col-gap);
  align-items: baseline;
  border-top: 2px solid var(--rule-bold);
  padding-top: var(--space-sm);
  margin-bottom: var(--space-xs);
}

.themes__title {
  margin: 0;
  font-size: var(--fs-2xl);
  line-height: var(--lh-head);
}

.themes__note {
  margin: 0;
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  max-width: 62ch;
}

.themes__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.themes__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-2xs) var(--col-gap);
  align-items: start;
  padding: var(--space-md) 0;
  border-bottom: var(--hairline) solid var(--rule);
}

.themes__body {
  min-width: 0;
}

.themes__name {
  margin: 0;
  font-size: var(--fs-xl);
  font-weight: var(--w-medium);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-head);
}

.themes__name a {
  color: var(--ink);
  text-decoration: none;
}

.themes__row:hover .themes__name a,
.themes__name a:hover {
  color: var(--accent);
}

.themes__line {
  margin: var(--space-2xs) 0 0;
  color: var(--ink-muted);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  max-width: 68ch;
}

.themes__by {
  margin: var(--space-2xs) 0 0;
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

.themes__by-label {
  margin-right: var(--space-3xs);
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
}

.themes__by a {
  color: var(--ink-muted);
  text-decoration: none;
}

.themes__by a:hover {
  color: var(--accent);
  text-decoration: underline;
}

.themes__count {
  margin: 0;
  text-align: right;
  color: var(--ink-muted);
  font-size: var(--fs-xs);
  line-height: var(--lh-snug);
  font-variant-numeric: tabular-nums;
}

.themes__n {
  display: block;
  font-size: var(--fs-lg);
  font-weight: var(--w-medium);
  color: var(--ink);
}

/* Строка про черновики. Отбита жирной линейкой от перечня: это не ещё один
   раздел, а объяснение, почему их в перечне не пятнадцать. */
.themes__draft {
  margin: var(--space-2xl) 0 0;
  padding-top: var(--space-md);
  border-top: var(--hairline) solid var(--rule-bold);
  color: var(--ink-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  max-width: 68ch;
}

/* Метки перечнем: тот же ряд, что у разделов на главной, но на ступень мельче
   и в три колонки — меток на витрине раздела втрое больше, чем разделов. */
.index--tags {
  columns: 3;
  column-gap: var(--space-2xl);
}

.index--tags .index__name {
  font-size: var(--fs-base);
}

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

.chron__group {
  margin-bottom: var(--space-2xl);
}

/* Вид метки приходит из общей группы надзаголовков (см. .sections__title):
   она объявлена ниже по файлу, поэтому здесь селектор на класс больше. */
.chron .chron__label {
  border-top: var(--hairline) solid var(--rule-bold);
  padding-top: var(--space-2xs);
  margin: 0 0 var(--space-2xs);
}

.chron__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Строка ленты: дата, заголовок, рубрика с подписью. На широком экране всё
   в одну строку - это и есть плотность, ради которой лента существует.
   Длинный заголовок переносится сам, ничего не обрезается многоточием. */
.chron__row {
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr) minmax(0, 17rem);
  grid-template-areas: 'date title meta';
  gap: var(--space-3xs) var(--space-md);
  align-items: baseline;
  padding: var(--space-xs) 0;
  border-bottom: var(--hairline) solid var(--rule);
}

.chron__row:last-child {
  border-bottom: 0;
}

.chron__date {
  grid-area: date;
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

.chron__title {
  grid-area: title;
  font-size: var(--fs-base);
  font-weight: var(--w-medium);
  line-height: var(--lh-snug);
  letter-spacing: 0;
  margin: 0;
}

.chron__title a {
  color: var(--ink);
  text-decoration: none;
}

.chron__row:hover .chron__title a,
.chron__title a:hover {
  color: var(--accent);
}

.chron__meta {
  grid-area: meta;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-end;
  gap: var(--space-3xs) var(--space-sm);
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

/* ------------------------------------------------------------- пагинация */
/* Текстом и только текстом: кружки с номерами - язык приложения, а не издания. */

.pager {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: baseline;
  gap: var(--space-md);
  border-top: var(--hairline) solid var(--rule-bold);
  padding-top: var(--space-md);
  margin-top: var(--space-2xl);
  font-size: var(--fs-sm);
}

.pager__prev {
  justify-self: start;
}

.pager__next {
  justify-self: end;
  text-align: right;
}

.pager__pos {
  margin: 0;
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* -------------------------------------------------------- пустое состояние */

.empty-state {
  border-top: 2px solid var(--rule-bold);
  padding-top: var(--space-md);
  margin-bottom: var(--space-xl);
  max-width: var(--measure);
}

.empty-state__title {
  margin: 0 0 var(--space-2xs);
  font-size: var(--fs-xl);
  font-weight: var(--w-medium);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-head);
}

.empty-state__text {
  margin: 0 0 var(--space-md);
  color: var(--ink-muted);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
}

.empty-state__links {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: var(--space-2xl);
  font-size: var(--fs-sm);
}

.empty-state__links li {
  margin-bottom: var(--space-2xs);
  break-inside: avoid;
}

/* ------------------------------------------------- витрины на среднем экране */

@media (max-width: 940px) {
  .lead-story__head,
  .showcase__head,
  .themes__head,
  .topic {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-md);
    align-items: start;
  }

  .themes__head {
    gap: var(--space-2xs);
  }

  .index--tags {
    columns: 2;
  }

  .topic {
    gap: var(--space-sm);
  }

  /* Три коротких в три колонки здесь уже не встают: на 768 пикселях колонка
     сжимается до 219, и заголовок в 22 пикселя разваливается на пять строк.
     Полоса становится списком во всю ширину, линейка из вертикальной
     превращается в горизонтальную. */
  .band--trio {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-md);
  }

  .band--trio > .story + .story {
    border-left: 0;
    padding-left: 0;
    border-top: var(--hairline) solid var(--rule);
    padding-top: var(--space-md);
  }

  /* Трёх колонок лента уже не держит: рубрика с подписью уходит под
     заголовок и выравнивается по его левому краю. */
  .chron__row {
    grid-template-columns: 7rem minmax(0, 1fr);
    grid-template-areas:
      'date title'
      '.    meta';
  }

  .chron__meta {
    justify-content: flex-start;
  }
}

/* ------------------------------------------------------- витрины на телефоне */

@media (max-width: 640px) {
  .showcase {
    padding-top: var(--space-lg);
  }

  .masthead {
    margin-bottom: var(--space-lg);
  }

  .lead-story,
  .band {
    padding-bottom: var(--space-lg);
    margin-bottom: var(--space-lg);
  }

  .lead-story__head {
    margin-bottom: var(--space-md);
  }

  .lead-story__lead {
    font-size: var(--fs-base);
  }

  .story__cover--lead {
    aspect-ratio: 3 / 2;
  }

  /* Один столбец. Внутри полосы материалы разделяет линейка: воздуха на
     телефоне меньше, и без неё лид одного материала слипается с мета-строкой
     следующего. */
  .band--duo,
  .band--trio {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-lg);
  }

  .band--duo > .story + .story,
  .band--trio > .story + .story {
    border-top: var(--hairline) solid var(--rule);
    padding-top: var(--space-lg);
  }

  .story--wide,
  .story--flip {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .story--flip .story__cover {
    order: 0;
  }

  .story--wide .story__cover {
    margin-bottom: var(--space-md);
    aspect-ratio: 16 / 9;
  }

  .latest,
  .index,
  .index--tags,
  .empty-state__links {
    columns: 1;
  }

  .index__name {
    font-size: var(--fs-base);
  }

  /* Перечень тем на телефоне: счётчик уходит под название, как в каталоге
     авторов, — правая колонка на 320 пикселях съедает половину строки. */
  .themes__row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2xs);
    padding: var(--space-md) 0;
  }

  .themes__count {
    text-align: left;
  }

  .themes__n {
    display: inline;
    font-size: var(--fs-base);
  }

  /* На телефоне дата и рубрика встают в одну служебную строку над заголовком:
     тот же порядок, что у материала в витрине, и на треть короче строка ленты,
     чем если дать каждой части по собственному ряду. */
  .chron__row {
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      'date  meta'
      'title title';
    gap: var(--space-3xs) var(--space-sm);
    padding: var(--space-xs) 0;
  }

  .pager {
    grid-template-columns: minmax(0, 1fr);
    justify-items: start;
    gap: var(--space-2xs);
  }

  .pager__next {
    justify-self: start;
    text-align: left;
  }

  .pager__pos {
    order: 3;
  }
}

/* Уменьшенная моторика. Общее правило в конце файла глушит длительность, но
   мгновенный скачок картинки на четыре пикселя - всё ещё движение, поэтому
   подъём отменяется целиком, а не ускоряется. */
@media (prefers-reduced-motion: reduce) {
  .story:hover .story__cover,
  .lead-story:hover .story__cover {
    transform: none;
  }
}

/* -------------------------------------------------------- боковая колонка */

.sections,
.passport,
.hub-list,
.profile__hubs {
  border-top: var(--hairline) solid var(--rule-bold);
  padding-top: var(--space-sm);
  margin-bottom: var(--space-xl);
  font-size: var(--fs-sm);
}

.sections__title,
.related__title,
.short__title,
.callout__title,
.block__title,
.chron__label {
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
  margin: 0 0 var(--space-sm);
}

.sections__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.sections__list li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-xs);
  padding: var(--space-2xs) 0;
  border-bottom: var(--hairline) solid var(--rule);
}

.sections__list li:last-child {
  border-bottom: 0;
}

.sections__list a {
  text-decoration: none;
  color: var(--ink);
}

.sections__list a:hover {
  color: var(--accent);
}

.sections__count {
  color: var(--ink-muted);
  font-size: var(--fs-xs);
}

.passport p {
  margin: 0 0 var(--space-xs);
  color: var(--ink-muted);
}

/* Плоский список ссылок. Используется не только в подвале: тем же классом
   размечены блоки «О площадке», «Подборки» в профиле и «Ещё о площадке». */
.foot__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.foot__list li {
  margin-bottom: var(--space-2xs);
}

.foot__list a {
  text-decoration: none;
  color: var(--ink-muted);
}

.foot__list a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* ---------------------------------------------------------------- статья */

.crumbs {
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  margin: 0 0 var(--space-md);
}

.crumbs a {
  color: var(--ink-muted);
  text-decoration: none;
}

.crumbs a:hover {
  color: var(--accent);
}

/* Разделитель крошек — знак, а не линия: на тёмном --rule-strong его
   съедает, поэтому взята структурная ступень. */
.crumbs__sep {
  padding: 0 var(--space-2xs);
  color: var(--rule-bold);
}

.article {
  max-width: calc(var(--measure) + var(--gutter) * 2);
  padding-top: var(--space-xl);
  padding-bottom: var(--space-3xl);
}

.article__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  margin-bottom: var(--space-md);
}

.article__h1 {
  font-size: var(--fs-5xl);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  margin: 0 0 var(--space-md);
}

.article__lead {
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  color: var(--ink);
  margin: 0 0 var(--space-md);
  max-width: 46ch;
}

.article__updated {
  color: var(--ink-muted);
}

.article__cover {
  margin: 0 0 var(--space-xl);
}

.article__cover img {
  width: 100%;
}

/* --------------------------------------------------------- полоса материала */
/*
 * Три колонки: поле, колонка чтения и вынос. Колонка чтения ровно 680
 * пикселей и стоит по центру полосы на любой ширине - ось текста не ездит
 * от страницы к странице. С 1180 пикселей в левом поле встаёт липкое
 * оглавление, а картинки и широкие таблицы уходят в правое поле: в журнале
 * иллюстрация выходит в поле, а текст остаётся на своей оси. Ниже 1180 поля
 * схлопываются, оглавление идёт в потоке, картинка равна колонке.
 *
 * Вынос считается только вправо и только на ту величину, которая на этой
 * ширине точно свободна (--bleed), поэтому горизонтальной прокрутки не
 * появляется ни на одной ширине.
 */

.article--post {
  max-width: var(--width-page);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--measure)) minmax(0, 1fr);
}

.article--post > *,
.article__main > * {
  grid-column: 2;
  min-width: 0;
}

.article__main {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, var(--measure)) minmax(0, 1fr);
}

.article--post > .article__main {
  grid-column: 1 / -1;
}

.article--post > .article__cover,
.article--post .article__body figure,
.article--post .article__body .table-wrap {
  width: calc(100% + var(--bleed));
  max-width: calc(100% + var(--bleed));
}

.article--post > .article__cover {
  margin: 0 0 var(--space-2xl);
}

.article--post .article__body figure {
  margin: var(--space-2xl) 0;
}

/* Подзаголовок в длинном материале отбивается воздухом, а не линейкой:
   линейка перед каждым из восьми H2 превращает полосу в бланк. */
.article--post .article__body h2 {
  margin-top: var(--space-3xl);
}

.article--post .article__body > h2:first-child {
  margin-top: 0;
}

/* Шапка материала: крошки, рубрика, заголовок, лид, подпись. */

.lede {
  padding-bottom: var(--space-lg);
  margin-bottom: var(--space-xl);
  border-bottom: var(--hairline) solid var(--rule);
}

.kicker {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
  margin: 0 0 var(--space-sm);
}

.kicker__format {
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.by {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs) var(--space-sm);
  margin-top: var(--space-lg);
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

.by__prefix {
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
}

/* Оглавление в поле. Липнет под шапкой, длинное прокручивается внутри себя. */

.rail {
  margin-bottom: var(--space-xl);
}

@media (min-width: 1180px) {
  .rail {
    grid-column: 1;
    margin-bottom: 0;
    padding-right: var(--space-2xl);
  }

  .rail .toc {
    position: sticky;
    top: calc(var(--head-h) + var(--space-lg));
    columns: 1;
    border-top: 0;
    padding-top: 0;
    margin: 0;
    max-height: calc(100vh - var(--head-h) - var(--space-2xl));
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .rail .toc__list {
    columns: 1;
    border-left: var(--hairline) solid var(--rule);
  }

  .rail .toc__item {
    border-left: 2px solid transparent;
    margin-left: -1px;
  }

  .rail .toc__link {
    padding: var(--space-2xs) 0 var(--space-2xs) var(--space-xs);
    border-bottom: 0;
    font-size: var(--fs-xs);
    color: var(--ink-muted);
  }

  .rail .toc__item.is-current {
    border-left-color: var(--accent);
  }

  .rail .toc__item.is-current .toc__link {
    color: var(--ink);
  }
}

/* ---------------------------------------------------------- текст статьи */

.article__body {
  font-size: var(--fs-md);
  line-height: var(--lh-text);
  max-width: var(--measure);
}

.article__body p {
  margin: 0 0 var(--space-md);
}

.article__body > :first-child {
  margin-top: 0;
}

.article__body h2 {
  font-size: var(--fs-2xl);
  line-height: var(--lh-head);
  margin: var(--space-2xl) 0 var(--space-sm);
}

.article__body h3 {
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
  margin: var(--space-xl) 0 var(--space-xs);
}

.article__body ul,
.article__body ol {
  margin: 0 0 var(--space-md);
  padding-left: var(--space-md);
}

.article__body li {
  margin-bottom: var(--space-2xs);
}

.article__body li::marker {
  color: var(--ink-muted);
}

.article__body a {
  text-decoration-thickness: 1px;
}

.article__body strong {
  font-weight: var(--w-semi);
}

.article__body hr {
  border: 0;
  border-top: var(--hairline) solid var(--rule);
  margin: var(--space-xl) 0;
}

/* Якорь у заголовка. Появляется по наведению и по фокусу с клавиатуры. */
.anchor {
  opacity: 0;
  margin-left: var(--space-2xs);
  font-weight: var(--w-regular);
  color: var(--rule-bold);
  text-decoration: none;
  transition: opacity var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

h2:hover .anchor,
h3:hover .anchor,
.anchor:focus-visible {
  opacity: 1;
  color: var(--accent);
}

/* ------------------------------------------------- изображения и подписи */

figure {
  margin: var(--space-xl) 0;
}

figure img {
  width: 100%;
}

figcaption {
  font-size: var(--fs-xs);
  line-height: var(--lh-base);
  color: var(--ink-muted);
  margin-top: var(--space-xs);
  padding-top: var(--space-2xs);
  border-top: var(--hairline) solid var(--rule);
  max-width: var(--measure);
}

/* ---------------------------------------------------------------- врезки */

/* «Коротко» — сводка перед текстом. Выделена плотностью бумаги, а не рамкой
   и тем более не тенью: подложка на тон глубже полосы, пункты разделены
   линейками. Метка набрана чернилами, а не акцентом: акцент в системе
   означает рубрику, и раздавать его служебным надписям нельзя. От остальных
   меток эту отличает подложка, на которой она стоит. */
.short {
  background: var(--paper-sunk);
  padding: var(--space-md);
  margin: 0 0 var(--space-2xl);
  max-width: var(--measure);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
}

.short__label {
  margin: 0 0 var(--space-sm);
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink);
}

.short__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.short__list li {
  padding: var(--space-xs) 0;
  border-top: var(--hairline) solid var(--rule-strong);
}

.short__list li:first-child {
  padding-top: 0;
  border-top: 0;
}

.short__list li:last-child {
  padding-bottom: 0;
}

/* Заметка редакции внутри текста — на утопленной бумаге. */
.callout {
  background: var(--paper-sunk);
  padding: var(--space-md);
  margin: 0 0 var(--space-xl);
  max-width: var(--measure);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
}

.callout p:last-child,
.callout ul:last-child {
  margin-bottom: 0;
}

/* Служебные уведомления: закрытие от индексации, статус подборки. */
.notice,
.hub-note {
  padding: var(--space-xs) 0 var(--space-xs) var(--space-sm);
  margin: 0 0 var(--space-lg);
  max-width: var(--measure);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  color: var(--ink-muted);
  border-left: 2px solid var(--rule-strong);
}

.hub-note {
  color: var(--ink);
  border-left-color: var(--accent);
}

blockquote {
  margin: var(--space-xl) 0;
  padding-left: var(--space-md);
  border-left: 2px solid var(--accent);
  max-width: var(--measure);
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  color: var(--ink);
}

blockquote p:last-child {
  margin-bottom: 0;
}

/* --------------------------------------------------------------- таблицы */

.table-wrap {
  overflow-x: auto;
  margin: 0 0 var(--space-lg);
  border-bottom: var(--hairline) solid var(--rule);
}

table {
  border-collapse: collapse;
  width: 100%;
  font-size: var(--fs-base);
  line-height: var(--lh-base);
}

th,
td {
  text-align: left;
  padding: var(--space-xs) var(--space-sm) var(--space-xs) 0;
  border-bottom: var(--hairline) solid var(--rule);
  vertical-align: top;
}

th {
  font-weight: var(--w-semi);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
  border-bottom: var(--hairline) solid var(--rule-bold);
  white-space: nowrap;
}

tbody tr:last-child td {
  border-bottom: 0;
}

/* ------------------------------------------------------------------- код */

/* Строчный код стоит на ступень глубже, чем блочный. Причина в размере пятна:
   у врезки и у <pre> подложка занимает сотни пикселей и читается уже при
   перепаде L* в 4.4, а у чипа из трёх букв посреди строки — нет, он на тёмном
   просто исчезает. Поэтому --paper-deep (перепад 8.5), а не --paper-sunk. */
code,
kbd,
samp {
  font-family: var(--font-mono);
  font-size: 0.88em;
  background: var(--paper-deep);
  padding: 0.1em 0.35em;
}

pre {
  background: var(--paper-sunk);
  border-left: 2px solid var(--rule-strong);
  padding: var(--space-sm);
  margin: 0 0 var(--space-md);
  overflow-x: auto;
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  tab-size: 2;
}

pre code {
  background: none;
  padding: 0;
  font-size: inherit;
}

/* ---------------------------------------------------------- оглавление */

/* Одна разметка на два места. В потоке (телефон, планшет, страница подборки)
   это перечень под линейкой, на широком экране — липкая колонка в поле
   (см. «полоса материала»). Активный пункт отмечает assets/toc.js. */

.toc {
  border-top: var(--hairline) solid var(--rule-bold);
  padding-top: var(--space-sm);
  margin: 0 0 var(--space-xl);
  max-width: var(--measure);
}

.toc__label {
  margin: 0 0 var(--space-2xs);
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.toc__list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
}

.toc__item {
  break-inside: avoid;
}

.toc__link {
  display: block;
  padding: var(--space-2xs) 0;
  border-bottom: var(--hairline) solid var(--rule);
  text-decoration: none;
  color: var(--ink);
  transition: color var(--dur-fast) var(--ease);
}

.toc__link:hover {
  color: var(--accent);
}

@media (min-width: 620px) {
  .toc__list {
    columns: 2;
    column-gap: var(--space-2xl);
  }
}

/* --------------------------------------------------------------- метки */
/* Темы материала — строка набора, а не рамки-таблетки: коробок на полосе нет,
   и метка темы не повод их заводить. Отбивка от текста линейкой. */

.tags {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
  margin: var(--space-2xl) 0 0;
  padding-top: var(--space-sm);
  border-top: var(--hairline) solid var(--rule);
  max-width: var(--measure);
}

.tags__label {
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

/* Метка — ссылка на страницу метки, но выглядит она по-прежнему словом в
   строке: подчёркивать все шесть значит сыпать красным по низу материала.
   Признак ссылки появляется по наведению, как в служебных перечнях. */
.tag {
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  text-decoration: none;
}

.tag:hover {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

/* Разделитель — часть ссылки, и без inline-block он получал бы её
   подчёркивание вместе с ней: декорация не проникает в атомарные строчные
   боксы, а в обычный ::before проникает. */
.tag + .tag::before {
  content: '·';
  display: inline-block;
  padding-right: var(--space-sm);
  color: var(--rule-bold);
}

/* ------------------------------------------------------- врезка автора */

.author-box {
  border-top: var(--hairline) solid var(--rule-bold);
  margin-top: var(--space-3xl);
  padding-top: var(--space-md);
  max-width: var(--measure);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  color: var(--ink-muted);
}

.author-box__label {
  margin: 0 0 var(--space-md);
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.author-box__head {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}

.author-box__id {
  min-width: 0;
}

.author-box__name {
  margin: 0;
  font-size: var(--fs-lg);
  font-weight: var(--w-medium);
  letter-spacing: var(--ls-head);
  line-height: var(--lh-snug);
  color: var(--ink);
}

.author-box__name a {
  color: var(--ink);
  text-decoration: none;
}

.author-box__name a:hover {
  color: var(--accent);
}

.author-box__role {
  margin: var(--space-3xs) 0 0;
  font-size: var(--fs-xs);
}

.author-box__bio {
  margin: 0 0 var(--space-sm);
  font-size: var(--fs-base);
  color: var(--ink);
  max-width: 60ch;
}

.author-box__more {
  margin: 0 0 var(--space-sm);
}

.author-box__note {
  margin: 0;
  font-size: var(--fs-xs);
  padding-top: var(--space-sm);
  border-top: var(--hairline) solid var(--rule);
}

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

.readnext {
  margin-top: var(--space-3xl);
  padding-top: var(--space-md);
  border-top: var(--hairline) solid var(--rule-bold);
  max-width: var(--measure);
}

.readnext__title {
  margin: 0 0 var(--space-2xs);
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.readnext__list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.readnext__item {
  padding: var(--space-md) 0;
  border-bottom: var(--hairline) solid var(--rule);
}

.readnext__item:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.readnext__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
  margin: 0 0 var(--space-3xs);
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

.readnext__head {
  margin: 0;
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  font-weight: var(--w-medium);
}

.readnext__head a {
  color: var(--ink);
  text-decoration: none;
}

.readnext__head a:hover {
  color: var(--accent);
}

/* ------------------------------------------ индикатор чтения (в шапке) */
/* Времени чтения на странице нет намеренно: оценка «12 мин» отпугивает до
   начала чтения. Кольцо показывает фактическое положение и стоит в служебной
   группе липкой шапки — своей полосы у него нет, высоты шапке оно не
   добавляет. Появляется, когда текст пошёл, и гаснет на сотне процентов.
   Без JS не рендерится вовсе: разметку целиком создаёт reading-progress.js,
   он же уважает prefers-reduced-motion и в этом режиме элемент не создаёт. */

.progress {
  flex: none;
  display: flex;
  align-items: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--dur) var(--ease);
}

.progress.is-visible {
  opacity: 1;
}

.progress.is-done {
  opacity: 0;
}

.progress__ring {
  flex: none;
  display: block;
}

/* Дорожка кольца — полуторапиксельный волосок в шапке. На --rule-strong
   она на тёмном не видна вовсе, и заполненная дуга висит в пустоте:
   непонятно, сколько осталось. Взята структурная ступень. */
.progress__track {
  stroke: var(--rule-bold);
}

.progress__value {
  stroke: var(--accent);
  transition: stroke-dashoffset 90ms linear;
}

/* ------------------------------------------------ статические и карта */

.article--static .article__body,
.article--hub .article__body {
  font-size: var(--fs-base);
  line-height: var(--lh-base);
}

.article--static .article__h1,
.page__h1 {
  font-size: var(--fs-4xl);
  line-height: var(--lh-head);
  letter-spacing: var(--ls-tight);
  margin: 0 0 var(--space-sm);
}

.page__intro {
  color: var(--ink-muted);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  max-width: var(--measure);
  margin: 0 0 var(--space-xl);
}

.more-pages {
  margin-top: var(--space-2xl);
  border-top: var(--hairline) solid var(--rule-bold);
  padding-top: var(--space-md);
}

.map__block {
  margin-top: var(--space-xl);
}

.map__title {
  font-size: var(--fs-xl);
  margin: 0 0 var(--space-xs);
  padding-bottom: var(--space-2xs);
  border-bottom: var(--hairline) solid var(--rule);
}

.map__title a {
  text-decoration: none;
  color: var(--ink);
}

.map__title a:hover {
  color: var(--accent);
}

.map__list {
  list-style: none;
  margin: 0;
  padding: 0;
  column-count: 2;
  column-gap: var(--space-xl);
  font-size: var(--fs-sm);
}

.map__list li {
  margin-bottom: var(--space-2xs);
  break-inside: avoid;
}

.map__list a {
  text-decoration: none;
  color: var(--ink);
}

.map__list a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* ----------------------------------------------------------------- авторы */
/* Аватар — только монограмма: инициалы на утопленной поверхности. Ни
   фотографий, ни сгенерированных лиц (правило 1 реестра авторов). Цвета в SVG
   заданы атрибутами, поэтому перекрываются отсюда: на сайте один акцент, а не
   семь авторских, иначе лента превращается в цветной конструктор.

   Пересчёт под тёмное. Диск и инициалы подобраны так, чтобы монограмма весила
   на полосе столько же, сколько весила на бумаге, а не «столько же по коду»:
   инициалы к диску 5.67:1 против прежних 5.23:1, сам диск к фону 1.20:1
   против прежних 1.18:1. Токены остались те же (--paper-deep и --ink-muted) —
   изменились их значения, и лестница светлот выстроена по разнице L*, а не
   зеркальным отражением чисел. */

.ava {
  display: block;
  flex: none;
  user-select: none;
  -webkit-user-select: none;
}

.ava > circle {
  fill: var(--paper-deep);
  fill-opacity: 1;
}

.ava__text {
  font-family: var(--font-sans);
  font-weight: var(--w-semi);
  fill: var(--ink-muted);
  letter-spacing: 0.01em;
}

.byline {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  text-decoration: none;
  color: var(--ink-muted);
}

.byline:hover {
  color: var(--accent);
}

.byline:hover .byline__name {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.byline--lg {
  gap: var(--space-xs);
  color: var(--ink);
  font-weight: var(--w-medium);
  font-size: var(--fs-base);
}

/* --------------------------------------------------------- профиль автора */
/* Страница колумниста, а не строка базы: сверху крупная монограмма и имя,
   под ними биография кеглем лида, дальше выходные данные списком признаков
   и лента материалов перечнем. */

.profile {
  margin: 0 0 var(--space-2xl);
  padding-bottom: var(--space-lg);
  border-bottom: var(--hairline) solid var(--rule-bold);
}

.profile__id {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  min-width: 0;
}

.profile__names {
  min-width: 0;
}

.profile__name {
  font-size: var(--fs-4xl);
  line-height: var(--lh-head);
  letter-spacing: var(--ls-tight);
  margin: 0;
}

.profile__role {
  margin: var(--space-2xs) 0 0;
  color: var(--ink-muted);
  font-size: var(--fs-base);
}

.profile__bio {
  max-width: 52ch;
  margin: var(--space-lg) 0 0;
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
}

.profile__facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-md) var(--col-gap);
  margin: var(--space-xl) 0 0;
  padding-top: var(--space-md);
  border-top: var(--hairline) solid var(--rule);
}

.profile__fact--wide {
  grid-column: 1 / -1;
}

.profile__fact dt {
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.profile__fact dd {
  margin: var(--space-3xs) 0 0;
  font-size: var(--fs-base);
  font-variant-numeric: tabular-nums;
}

.profile__hubs {
  border-top: 0;
  padding-top: 0;
  margin-bottom: var(--space-2xl);
  font-size: var(--fs-base);
}

.profile__hubs-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: var(--hairline) solid var(--rule);
}

.profile__hubs-list li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2xs) var(--space-md);
  padding: var(--space-xs) 0;
  border-bottom: var(--hairline) solid var(--rule);
}

.profile__hubs-list a {
  text-decoration: none;
  color: var(--ink);
}

.profile__hubs-list a:hover {
  color: var(--accent);
}

.profile__hubs-count {
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

.profile__all {
  margin: var(--space-xs) 0 0;
  font-size: var(--fs-xs);
}

/* Лента материалов автора: дата отдельной колонкой, дальше рубрика,
   заголовок и лид. Подписи в строках нет - она стоит в шапке страницы. */

.archive__title {
  margin: 0 0 var(--space-2xs);
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.arch {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: var(--hairline) solid var(--rule-bold);
}

.arch__item {
  display: grid;
  grid-template-columns: 7.5rem minmax(0, 1fr);
  gap: var(--space-md);
  padding: var(--space-lg) 0;
  border-bottom: var(--hairline) solid var(--rule);
}

.arch__date {
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  padding-top: 0.35em;
}

.arch__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
  margin: 0 0 var(--space-3xs);
}

.arch__format {
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.arch__title {
  margin: 0;
  font-size: var(--fs-xl);
  line-height: var(--lh-snug);
}

.arch__title a {
  color: var(--ink);
  text-decoration: none;
}

.arch__title a:hover {
  color: var(--accent);
}

.arch__lead {
  margin: var(--space-2xs) 0 0;
  color: var(--ink-muted);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  max-width: var(--measure);
}

/* ---------------------------------------------------------- каталог авторов */
/* Типографический перечень: монограмма, имя, специализация, счётчик.
   Ни плиток, ни иконок, ни колонок одинаковых карточек. */

.authors {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: var(--hairline) solid var(--rule-bold);
}

.authors__item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--space-md);
  padding: var(--space-lg) 0;
  border-bottom: var(--hairline) solid var(--rule);
}

.authors__ava {
  display: block;
  text-decoration: none;
}

.authors__body {
  min-width: 0;
}

.authors__name {
  margin: 0;
  font-size: var(--fs-xl);
  font-weight: var(--w-medium);
  letter-spacing: var(--ls-head);
  line-height: var(--lh-snug);
}

.authors__name a {
  color: var(--ink);
  text-decoration: none;
}

.authors__name a:hover {
  color: var(--accent);
}

.authors__role {
  margin: var(--space-3xs) 0 0;
  color: var(--ink-muted);
  font-size: var(--fs-sm);
}

.authors__spec {
  margin: var(--space-2xs) 0 0;
  color: var(--ink-muted);
  font-size: var(--fs-xs);
  max-width: 60ch;
}

.authors__spec a {
  color: var(--ink-muted);
}

.authors__count {
  margin: 0;
  text-align: right;
  color: var(--ink-muted);
  font-size: var(--fs-xs);
  line-height: var(--lh-snug);
}

.authors__n {
  display: block;
  font-size: var(--fs-lg);
  font-weight: var(--w-medium);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

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

/* Подборка лежит в колонке витрины, свои поля ей не нужны: иначе к отступу
   сетки прибавляется отступ статьи и шапка уезжает на сто пикселей вниз. */
.article--hub {
  max-width: none;
  padding-top: 0;
  padding-bottom: 0;
}

.article--hub .article__lead {
  font-size: var(--fs-lg);
  max-width: 52ch;
}

.entry {
  padding: var(--space-md) 0;
  border-bottom: var(--hairline) solid var(--rule);
  margin: 0;
  list-style: none;
}

.article__body ul:has(> .entry),
.article__body ol:has(> .entry) {
  list-style: none;
  padding-left: 0;
  margin: 0 0 var(--space-xl);
  border-top: var(--hairline) solid var(--rule);
}

.entry__title {
  display: block;
  font-size: var(--fs-lg);
  font-weight: var(--w-medium);
  line-height: var(--lh-snug);
  letter-spacing: var(--ls-head);
  color: var(--ink);
  text-decoration: none;
}

.entry__title:hover {
  color: var(--accent);
}

.entry__note {
  display: block;
  margin-top: var(--space-2xs);
  color: var(--ink-muted);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  max-width: var(--measure);
}

/* Вопросы и ответы: вопрос отбит линейкой, ответ идёт обычным текстом. */

.qa {
  display: block;
}

.qa .qa__q {
  margin: var(--space-lg) 0 var(--space-2xs);
  padding-top: var(--space-sm);
  border-top: var(--hairline) solid var(--rule);
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
  color: var(--ink);
}

.qa .qa__q strong {
  font-weight: var(--w-medium);
}

/* Список материалов подборки в боковой колонке. */

.hub-list__items {
  margin: 0;
  padding-left: 2.2ch;
}

.hub-list__items li {
  padding: var(--space-2xs) 0;
  border-bottom: var(--hairline) solid var(--rule);
}

.hub-list__items li::marker {
  color: var(--ink-muted);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
}

.hub-list__items li:last-child {
  border-bottom: 0;
}

.hub-list__items a {
  text-decoration: none;
  color: var(--ink);
}

.hub-list__items a:hover {
  color: var(--accent);
}

.hub-list__format {
  display: block;
  margin-top: var(--space-3xs);
  font-size: var(--fs-2xs);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

/* ------------------------------------------------------------------ поиск */
/* Поле появляется только после того, как скрипт его включил (атрибут hidden
   снимает assets/search.js). Ни рамки-коробки, ни подложки: поле — это
   строка набора с волосяной линией снизу, как всё остальное на площадке.
   Результаты рисуются разметкой ленты автора (.arch), поэтому своих правил
   у них нет вовсе. */

.search {
  margin-bottom: var(--space-xl);
}

.search__form {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-sm);
  border-bottom: var(--hairline) solid var(--rule-bold);
  padding-bottom: var(--space-2xs);
}

.search__label {
  flex: none;
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.search__field {
  flex: 1 1 12rem;
  min-width: 0;
  background: none;
  border: 0;
  padding: var(--space-2xs) 0;
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
}

.search__field::placeholder {
  color: var(--ink-muted);
  opacity: 0.7;
}

.search__field:focus {
  outline: none;
}

/* Фокус видно по линии поля, а не по рамке вокруг всей строки: рамка здесь
   нарисовала бы ту самую коробку, которой в языке издания нет. */
.search__form:focus-within {
  border-bottom-color: var(--accent);
}

.search__go {
  flex: none;
  background: none;
  border: 0;
  padding: var(--space-2xs) 0;
  color: var(--ink-muted);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--w-medium);
  cursor: pointer;
}

.search__go:hover {
  color: var(--accent);
}

.search__stat {
  margin: var(--space-xs) 0 var(--space-lg);
  font-size: var(--fs-xs);
  color: var(--ink-muted);
}

/* Подсветка совпадения. Не заливка цветом: на тёмном плашка выжигает строку,
   а найденное слово должно читаться как часть текста. Отсюда подчёркивание
   акцентом и обычный цвет текста. */
mark {
  background: none;
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--accent);
  text-decoration-thickness: 2px;
  text-underline-offset: 0.22em;
}

/* ------------------------------------------------------------------ архив */
/* Навигационная решётка, а не витрина: у месяца нет ни лида, ни картинки,
   только подпись и счётчик. Разделение — воздух и волосяная линия. */

.arcx__block {
  border-top: var(--hairline) solid var(--rule);
  padding: var(--space-md) 0;
}

.arcx__title {
  margin: 0 0 var(--space-2xs);
  font-size: var(--fs-lg);
  line-height: var(--lh-snug);
}

.arcx__title a {
  color: var(--ink);
  text-decoration: none;
}

.arcx__title a:hover {
  color: var(--accent);
}

.arcx__n,
.months__n {
  color: var(--ink-muted);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
}

.months {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
  margin: 0;
  font-size: var(--fs-sm);
}

.months__item {
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.months__item:hover {
  color: var(--accent);
}

/* Строка выходов: «дальше отсюда» на страницах ошибок и переходы между
   месяцами в архиве. Один класс на оба места — это одна и та же строка:
   подпись слева, дальше только ссылки, разделение воздухом. */
.ways {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-md);
  margin: var(--space-lg) 0 0;
  font-size: var(--fs-sm);
}

.ways__label {
  font-size: var(--fs-2xs);
  font-weight: var(--w-semi);
  text-transform: uppercase;
  letter-spacing: var(--ls-label);
  color: var(--ink-muted);
}

.ways a {
  color: var(--ink);
  text-decoration: none;
}

.ways a:hover {
  color: var(--accent);
}

/* ----------------------------------------------------------------- подвал */
/* Только про издание: кто издаёт, по каким правилам, куда писать, на каком
   основании. Рубрикатора колонками здесь больше нет — разделы стоят в шапке
   и целиком разобраны на «Все темы», подборки живут на своих страницах, и
   вторая карта сайта под каждым материалом только спорила с ним за внимание.

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

.foot {
  border-top: var(--hairline) solid var(--rule-bold);
  background: var(--paper);
  padding: var(--space-lg) 0 var(--space-xl);
  margin-top: var(--space-2xl);
  font-size: var(--fs-xs);
  color: var(--ink-muted);
  line-height: var(--lh-base);
}

.foot__id {
  margin-bottom: var(--space-md);
}

.foot__brand-name {
  display: inline-block;
  font-size: var(--fs-base);
  font-weight: var(--w-semi);
  letter-spacing: var(--ls-tight);
  color: var(--ink);
  text-decoration: none;
}

a.foot__brand-name:hover {
  color: var(--accent);
}

.foot__brand-tag {
  margin: var(--space-3xs) 0 0;
  color: var(--ink-muted);
  max-width: 60ch;
}

/* Ряды ссылок. Разделение воздухом: точек и линеек между пунктами нет,
   шаг в 24 пикселя заметно больше межсловного и читается как разрыв. */
.foot__nav {
  margin-bottom: var(--space-md);
}

.foot__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
  margin: 0;
}

.foot__row + .foot__row {
  margin-top: var(--space-2xs);
}

.foot__row a {
  color: var(--ink-muted);
  text-decoration: none;
}

.foot__row a:hover {
  color: var(--accent);
  text-decoration: underline;
}

/* Правовое стоит ступенью ниже: те же ссылки по начертанию, но набранные
   как сноска. Это документы, а не продолжение перечня «о проекте». */
.foot__row--legal a {
  font-size: var(--fs-2xs);
}

.foot__legal {
  border-top: var(--hairline) solid var(--rule);
  padding-top: var(--space-sm);
  color: var(--ink-muted);
}

/* Служебная строка: фид и карта сайта. Ниже реквизитов намеренно — это
   не навигация издания, а два технических адреса. */
.foot__service {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-md);
  margin-top: var(--space-2xs);
}

.foot__legal p {
  margin: 0 0 var(--space-2xs);
  max-width: 90ch;
}

.foot__legal p:last-child {
  margin-bottom: 0;
}

.foot__legal a {
  color: var(--ink-muted);
}

.foot__legal a:hover {
  color: var(--accent);
}

/* Возрастная метка обведена рамкой, и рамка обязана читаться: это правовой
   реквизит, а не украшение. На тёмном --rule-strong для неё слишком тих. */
.age {
  border: var(--hairline) solid var(--rule-bold);
  padding: 0 var(--space-3xs);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------- шапка на узкой полосе */
/* Правило простое: одна строка живёт, пока полоса набора полная. Как только
   окно уже 1180 и полоса начинает сжиматься, шапка раскладывается в два ряда.

   Считано на собранной странице: имя издания 95, восемь пунктов меню с
   «Все темы» 650, служебная группа 224, два отступа по 32 — вместе 1033.
   На полной полосе 1180 запас 147 пикселей, у самого порога (окно 1181, из
   которого полоса прокрутки съедает 15) — 85. Этого хватает либо на название
   издания на сотню пикселей длиннее placeholder'а, либо на ещё один раздел в
   меню, но не на то и другое сразу: прибавится и то и другое — порог надо
   поднимать, иначе у порога вернётся тихая обрезка.

   Тихая — потому что выбор здесь ровно один из двух: либо строка молча
   прокручивается и последний пункт выглядит обрезанным (полоса прокрутки в
   шапке скрыта, читатель не догадается, что там что-то есть), либо шапка
   честно становится двухрядной. Второе. Раскладка та же, что была на
   телефоне, и работает одинаково от 1180 до 320: разделы уезжают вторым
   рядом отдельной прокручиваемой полосой с выносом под края экрана, поэтому
   первый и последний пункт не прилипают к кромке и не читаются как срез. */

@media (max-width: 1180px) {
  .head__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      'brand aux'
      'nav   nav';
    align-items: center;
    height: auto;
    gap: 0 var(--space-sm);
    padding-bottom: var(--space-3xs);
  }

  .brand {
    grid-area: brand;
    padding: var(--space-2xs) 0;
  }

  /* Во втором ряду линейка слева от служебной группы отделять нечего:
     между именем издания и группой пустая половина строки. */
  .head__aux {
    grid-area: aux;
    padding-left: 0;
    border-left: 0;
  }

  .nav {
    grid-area: nav;
    /* Полоса прокрутки уезжает под края экрана, чтобы первый и последний
       пункт не прилипали к кромке и не выглядели обрезанными. */
    padding: var(--space-2xs) var(--gutter);
    margin: 0 calc(-1 * var(--gutter));
    scroll-padding-inline: var(--gutter);
  }
}

/* -------------------------------------------------------------- мобильное */

@media (max-width: 940px) {
  :root {
    --col-gap: var(--space-xl);
  }
}

@media (max-width: 640px) {
  :root {
    --gutter: 20px;
    --fs-md: 1.125rem;  /* 18 — на телефоне колонка уже, 19 даёт мало слов в строке */
    --space-3xl: 64px;
  }

  /* Двухрядная шапка включилась выше, на 1180 (см. блок про узкую полосу).
     Здесь чинится только верхний ряд.

     На телефоне к служебной группе добавляется кольцо прогресса, и на 320
     пикселях группа с ним занимает 221 из 280 доступных: имени издания
     остаётся 43, а само оно шире, и текст лезет на текст. Поэтому колонка
     имени переводится в `auto` — имя занимает столько, сколько ему нужно, и
     не ужимается, — а служебная группа получает право переноситься по
     строкам и уезжает вправо-вниз. Наезда не остаётся ни на одной ширине,
     шаг между пунктами группы при этом сжимается до 16. */
  .head__row {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .head__aux {
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-2xs) var(--space-sm);
  }

  .article,
  .layout {
    padding-top: var(--space-lg);
  }

  .article__lead {
    font-size: var(--fs-base);
    max-width: none;
  }

  /* Оглавление на телефоне идёт в потоке, и его пункты - основная навигация
     по длинному материалу. Шаг строки увеличен до пальца. */
  .toc__link {
    padding: var(--space-xs) 0;
  }

  /* Короткая строка терпит переносы: рваный правый край на 18 пикселях
     мешает больше, чем дефис. На широком экране переносы выключены. */
  .article__body p,
  .article__body li {
    hyphens: auto;
    -webkit-hyphens: auto;
    hyphenate-limit-chars: 7 4 3;
  }

  .card--big .card__lead {
    font-size: var(--fs-base);
  }

  .map__list {
    column-count: 1;
  }

  /* Профиль и каталог на телефоне. Монограмма остаётся рядом с именем,
     а всё остальное разворачивается в одну колонку. */
  .profile__id {
    gap: var(--space-sm);
  }

  .profile__name {
    font-size: var(--fs-3xl);
  }

  .profile__bio {
    font-size: var(--fs-base);
    line-height: var(--lh-base);
  }

  .profile__facts {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-sm);
  }

  .authors__item {
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-sm);
    padding: var(--space-md) 0;
  }

  .authors__count {
    grid-column: 2;
    text-align: left;
  }

  .authors__n {
    display: inline;
    font-size: var(--fs-base);
  }

  /* Лента материалов автора: дата уходит над заголовком. */
  .arch__item {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2xs);
    padding: var(--space-md) 0;
  }

  .arch__date {
    padding-top: 0;
  }

  .arch__title {
    font-size: var(--fs-lg);
  }

  /* Подвал на телефоне. Ряды ссылок переносятся сами, и это ровно то, что
     нужно: перечня разделов в подвале больше нет, переносить нечего, кроме
     семи пунктов об издании. Шаг между строками поднят до пальца. */
  .foot {
    padding: var(--space-md) 0 var(--space-lg);
  }

  .foot__row {
    gap: var(--space-3xs) var(--space-md);
  }

  .foot__row a {
    display: inline-block;
    padding: 3px 0;
  }

  .foot__list li {
    margin-bottom: var(--space-3xs);
  }

  .foot__list a {
    display: inline-block;
    padding: 2px 0;
  }

  th,
  td {
    padding-right: var(--space-xs);
  }
}

/* ------------------------------------------------- уменьшенная моторика */
/* Настройка системы уважается целиком: ни переходов, ни анимаций,
   ни плавной прокрутки. Индикатор чтения в этом режиме не создаётся вовсе. */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

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

/* ------------------------------------------------------------------ печать */
/* Это НЕ вторая тема и не светлый режим: переключателя нет, на экране полоса
   всегда тёмная. Но печатать тёмное нельзя — принтер вывалит полстраницы
   краски, а волосяные линии и подложки врезок при этом всё равно пропадут.
   Поэтому на бумагу палитра переопределяется целиком, а не наполовину: если
   задать только --paper и --ink, останутся тёмные подложки врезок и кода
   и почти чёрные линейки на белом. Значения взяты из прежней бумажной
   палитры издания, включая исходный кармин #A31621 — на белом он проходит
   с запасом (7.4:1), а поднятый экранный #EF5B63 на белом дал бы 2.9:1. */

@media print {
  :root {
    --paper: #fff;
    --paper-sunk: #f2efe9;
    --paper-deep: #eae6dd;
    --ink: #000;
    --ink-muted: #4a453d;
    --rule: #d8d3c8;
    --rule-strong: #b7b0a1;
    --rule-bold: #1a1815;
    --accent: #a31621;
    --accent-lift: #7c111a;
  }

  /* Всё, что на бумаге не работает: навигация, липкие колонки, кольцо
     прогресса, поле поиска и строки переходов. Кольцо живёт внутри .head и
     ушло бы вместе с ней, но названо отдельно — чтобы правило не сломалось,
     если его когда-нибудь вынесут из шапки. */
  .head,
  .foot,
  .progress,
  .readnext,
  .layout__side,
  .rail,
  .toc,
  .tags,
  .search,
  .ways,
  .more-pages,
  .skip {
    display: none;
  }

  .article,
  .layout {
    max-width: none;
    padding: 0;
  }

  .article--post,
  .article__main {
    display: block;
  }

  .article--post > .article__cover,
  .article--post .article__body figure,
  .article--post .article__body .table-wrap {
    width: 100%;
    max-width: 100%;
  }

  .article__body a {
    text-decoration: none;
  }
}

/* --------------------------------------------- места без снимка и векторное

   Пока настоящей фотографии нет, по адресу /img/<имя>.svg лежит наборная
   заглушка: утопленное поле с колоночной сеткой и тремя строками набора внизу
   (lib/placeholder.mjs). Кадрировать её нельзя — обрезка съедает как раз те
   строки, ради которых она и стоит. Поэтому в местах с заданной пропорцией
   (карточки ленты) заглушка вписывается целиком, а поле добирается тем же
   тоном, что и у неё самой: шва не видно. Тон один и тот же по обе стороны —
   --paper-sunk здесь и C.paper в генераторе; если менять, то оба сразу.

   То же правило верно и для настоящей векторной схемы, если владелец положит
   её руками: диаграмму не кадрируют. Растровых снимков правило не касается —
   как только рядом появится .webp или .jpg, оно перестанет совпадать. */
img[src^="/img/"][src$=".svg"] {
  object-fit: contain;
  object-position: 50% 50%;
  background-color: var(--paper-sunk);
}
