/* КриптоСреда — вёрстка темы поверх токенов.
   Все значения берутся из tokens.css. Собственных цветов, скруглений,
   теней и градиентов здесь нет и быть не может — правило дизайн-системы. */

/* ---------- Шрифты: self-host, cyrillic + latin, swap ---------- */
/* Обе гарнитуры вариативные, поэтому один файл на подмножество покрывает
   все веса: у Google Fonts запросы 400/500/600 отдают один и тот же woff2.
   Держать три копии одного файла было бы 3× трафика на ровном месте.

   ОБЪЯВЛЕНИЯ ЖИЛИ В tokens.css ОДИН ВЕЧЕР, 26.08.2026, и вернулись сюда.
   Замысел был такой: theme.css весит 37 КБ, латинские подмножества
   начинали грузиться только после того, как он докачан, — значит, перенос
   в трёхкилобайтный tokens.css даст им фору.

   Не дал. Запросы шрифтов запускает РАСКЛАДКА, а она ждёт ВСЕ
   блокирующие стили — и tokens.css, и theme.css, оба с
   renderBlockingStatus «blocking» (замер 26.08.2026). Пока theme.css не
   доскачан, раскладки нет, шрифт не нужен, запроса не будет — где бы ни
   лежало объявление. Холодные прогоны это подтвердили: старт латиницы не
   сдвинулся за пределы разброса сети.

   Правка была чистой перекладкой без выигрыша, и держать её ради
   красивого объяснения незачем. Правило про unicode-range и swap осталось
   в tools/check_shrifty.py — оно про другое и стоит своего. */
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/oswald-var-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Oswald';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/oswald-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2122;
}
/* GOLOS — 400 900, ПО ОСИ САМОГО ФАЙЛА (25.09.2026, п. 4 задания). До этого
   стояло «400 600», а ось wght в обоих файлах Golos — 400…900 (таблица fvar,
   разбор woff2 25.09.2026; у Oswald — 400…700, как и объявлено). По CSS
   Fonts 4 вес вне объявленного диапазона прижимается к краю: Golos 700
   рисовался как 600 (замер CDP 23.09.2026 — ширина строки при 600, 700 и
   900 одинакова). Решение владельца 25.09: заголовки карточек — Golos 700,
   и 700 берётся из того же файла; новых файлов шрифтов нет.
   Следствие на весь сайт: полужирный текст Golos (<strong>, первая ячейка
   карточной таблицы) теперь честные 700, а не прижатые 600. */
@font-face {
  font-family: 'Golos Text';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('../fonts/golos-text-var-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Golos Text';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('../fonts/golos-text-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2122;
}


/* ---------- База ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; }
img, svg { max-width: 100%; height: auto; display: block; }
figure { margin: 0; }

h1, h2, h3, h4 { margin: 0 0 var(--space-4); }
h1 { font: var(--text-h1); text-transform: uppercase; letter-spacing: var(--tracking-display); }
h2 { font: var(--text-h2); }
h3 { font: var(--text-h3); }
/* Отступ между абзацами — свой токен, а не шаг шкалы: он равен строке
   основного текста. Было --space-5 (24 px) — меньше строки, и абзацы
   читались слитно; 20.09.2026 поднято до 29 по решению редакции, на всём
   сайте сразу. Подробности — у токена в tokens.css. */
p  { margin: 0 0 var(--space-abzac); }
/* СПИСОК В ПОТОКЕ ТЕКСТА ВЕДЁТ СЕБЯ КАК АБЗАЦ — тот же токен, что у p.
   20.09.2026 отступ между абзацами подняли с 24 до 29 (строка основного
   текста), а списки оставили на 24: «они не абзацы». В итоге вокруг
   списка отступы стали разной величины — 29 сверху (от абзаца перед ним)
   и 24 снизу. Замер на живом разборе, 1400 и 390 px, дал ровно это.
   Разнобой виден не как «24 против 29», а как сбитый ритм колонки:
   список слегка прилипает к следующему абзацу.
   Внутренний шаг списка (li) при этом НЕ ТРОГАЕТСЯ: 8 px — это шаг
   внутри одного блока, как межстрочный интервал внутри абзаца, и к
   ритму ВОКРУГ списка отношения не имеет. */
ul, ol { margin: 0 0 var(--space-abzac); padding-left: var(--space-5); }
li { margin-bottom: var(--space-2); }
/* ВЛОЖЕННЫЙ СПИСОК — ЧАСТЬ ПУНКТА, А НЕ БЛОК В ПОТОКЕ ТЕКСТА. Без этого
   правила он наследует отступ строкой выше, и внутри одного списка
   получаются два разных шага: 8 px между обычными пунктами и 29 после
   пункта с вложением. Замер до правки: 8 и 24 — тот же разнобой, только
   меньше; подняв внешний отступ, мы сделали бы его заметнее. */
li > ul, li > ol { margin-block: var(--space-2); }

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--container-pad);
}
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--color-coal); color: var(--color-paper); padding: var(--space-3);
}
.skip-link:focus { left: 0; }

/* Фокус виден всегда: клавиатурная навигация — не опция */
:focus-visible { outline: 3px solid var(--brand-red-text); outline-offset: 2px; }

.meta {
  font: var(--text-meta);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--color-muted);
}

/* ---------- Шапка ---------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--color-paper);
  border-bottom: var(--border);
}
.site-header__inner {
  /* min-height, а не height: знак 40px при высоте 72 давал по 16px сверху
     и снизу, но визуально прижимался к нижней линейке — у самого знака
     фон до края, и «воздух» читался только сверху. Явные поля решают
     это надёжнее любого выравнивания. */
  min-height: var(--header-h);
  /* padding-block, а НЕ шорткат. Шорткат `padding: 16px 0` обнулял
     горизонтальные поля, которые задаёт .container, и шапка оставалась
     единственным контейнером сайта без бокового отступа: замер
     23.08.2026 на 390px — логотип на 0px, тогда как h1, абзац и обложка
     на 20px, а подвал и сетка статьи тоже на 20px. Логотип упирался в
     край экрана. Теперь горизонтальные поля приходят из .container и
     сами меняются с шириной: 20px на мобильной, 48px на десктопной. */
  padding-block: var(--space-4);
  display: flex; align-items: center; gap: var(--space-6);
  transition: min-height var(--motion-base) var(--ease-out),
              padding var(--motion-base) var(--ease-out);
}
.site-header.is-compact .site-header__inner {
  min-height: var(--header-h-m);
  padding-block: var(--space-2);
}
.site-logo { display: flex; align-items: center; gap: var(--space-3); text-decoration: none; }
.site-logo__mark { width: 40px; height: 40px; flex: none; }
.site-logo__text {
  font: var(--text-h3); text-transform: uppercase;
  letter-spacing: var(--tracking-meta); color: var(--color-coal);
}
.site-nav { margin-left: auto; display: flex; align-items: center; gap: var(--space-5); }
.site-nav ul { display: flex; gap: var(--space-5); list-style: none; margin: 0; padding: 0; }
.site-nav a {
  font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase; color: var(--color-coal);
}
/* Красный ховер оставлен ТОЛЬКО десктопной шапке (фон — бумага).
   В бургер-меню на ≤900px фон — уголь, и красный там не проходит AA;
   правило для узких экранов — ниже, в мобильном блоке.

   Ховер целиком закрыт условием (hover: hover) and (pointer: fine).
   На тачскрине состояния «навёл» не существует: браузер выдаёт :hover
   по тапу и держит его, пока не тронут другое место. Из-за этого
   «Регуляторика» оставалась подчёркнутой после нажатия и выглядела
   выбранной, хотя ничего выбрано не было. Условие оставляет ховер там,
   где он есть на самом деле, — мыши и трекпаду. */
@media (hover: hover) and (pointer: fine) {
  .site-nav a:hover { color: var(--brand-red-text); }
  .submenu-toggle:hover { color: var(--brand-red-text); }
  .site-search summary:hover { color: var(--brand-red-text); }
  .month-nav__item:hover { background: var(--color-coal); color: var(--color-paper); }
}

/* --- Подменю -------------------------------------------------------------
   Раскрытие держится на CSS, а не на JS: :hover для мыши, :focus-within для
   клавиатуры. Поэтому меню работает и при отключённом JavaScript, а скрипт
   добавляет только нажатие и Escape. Правило с [aria-expanded="true"] —
   это как раз состояние, которым управляет скрипт.

   Кнопка раскрытия всегда стоит НЕПОСРЕДСТВЕННО перед своим <ul>, поэтому
   хватает соседнего комбинатора и не нужен ни один id. */
.site-nav .menu > li { position: relative; }
.submenu-toggle {
  background: none; border: none; padding: 0 var(--space-2); cursor: pointer;
  font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase; color: var(--color-coal);
  display: inline-flex; align-items: center; gap: var(--space-2);
}
/* Ховер этой кнопки — в блоке (hover: hover) выше, рядом с ховером меню. */
.submenu-toggle__chevron {
  width: 0; height: 0; display: inline-block;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  transition: transform var(--motion-fast) var(--ease-out);
}
.submenu-toggle[aria-expanded="true"] .submenu-toggle__chevron { transform: rotate(180deg); }

/* Десктопное выпадающее подменю. 1131, а НЕ 769: до 1130px работает
   бургер, и два набора правил перекрывались бы. Перекрытие было не
   безобидным — .site-nav .menu > li:hover > .sub-menu имеет специфичность
   выше, чем .site-nav .sub-menu { display: none } в блоке бургера, и
   побеждало независимо от порядка в файле. То есть в открытой панели
   бургера подменю раскрывалось по наведению — ровно то, что комментарий
   ниже называет недопустимым на тачскрине. Дефект существовал и на
   769–900px; вынос бургера до 1130 сделал бы его заметным на каждом
   десктопном окне этой полосы. */
@media (min-width: 1131px) {
  .site-nav .sub-menu {
    display: none; position: absolute; top: 100%; left: 0; z-index: 20;
    flex-direction: column; gap: var(--space-3);
    min-width: 190px; padding: var(--space-4);
    background: var(--color-paper); border: var(--border);
  }
  .site-nav .menu > li:hover > .sub-menu,
  .site-nav .menu > li:focus-within > .sub-menu,
  .site-nav .submenu-toggle[aria-expanded="true"] + .sub-menu { display: flex; }
  /* Мышь идёт к подменю по диагонали и на пути пересекает край пункта —
     без этого зазора оно закрывалось бы под курсором. */
  .site-nav .sub-menu::before {
    content: ""; position: absolute; top: -6px; left: 0; right: 0; height: 6px;
  }
  /* Свёрнуто по Escape. Правило стоит ПОСЛЕ открывающих и имеет ту же
     специфичность — значит побеждает оно, без !important. Нужно потому,
     что Escape возвращает фокус на кнопку, а кнопка лежит внутри того же
     пункта: :focus-within открыл бы подменю обратно в тот же миг. */
  .site-nav .menu > li[data-collapsed="true"] > .sub-menu { display: none; }
}

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap-target-min);
  padding: var(--space-3) var(--space-5);
  font: var(--text-meta); letter-spacing: var(--tracking-meta); text-transform: uppercase;
  background: var(--brand-red-text); color: var(--color-paper);
  border: none; cursor: pointer;
  transition: background var(--motion-fast) var(--ease-out);
}
.btn:hover { background: var(--brand-red-text-hover); color: var(--color-paper); }
/* 80ms linear — точное значение из спеки для состояния active.
   Оно короче любого токена движения и при reduced-motion обнуляется
   отдельным правилом в конце файла. */
.btn:active { transform: translateY(1px); transition: transform 80ms linear; }
.btn--ghost { background: transparent; color: var(--color-coal); border: var(--border); }
.btn--ghost:hover { background: var(--color-coal); color: var(--color-paper); }

/* Коробка кнопки складывается из значка и полей: 24 + 8×2 + рамка 2×2 = 44,
   то есть общепринятый минимум пальцевой цели получается сам, без задания
   размера числом. До 23.08.2026 внутри стоял символ ☰ размером 12×15, и та
   же формула давала 32×36 — кнопка была мала не по замыслу, а потому что
   размер задавала системная гарнитура. */
.nav-toggle {
  display: none; background: none; border: var(--border);
  padding: var(--space-2); line-height: 0;
}
.nav-toggle__znak { display: block; }

/* ---------- Hero ---------- */
/* ГЕРО — ПЛАКАТ. Иллюстрация занимает весь первый экран, текст лежит
   поверх неё на сплошной угольной подложке (решение владельца 19.08.2026,
   вариант B из трёх промеренных).

   Почему не текст прямо на картинке: тёмный текст на фирменном красном
   даёт контраст 3,74 при пороге 4,5 — лид на такой подложке нечитаем,
   это замерено, а не на глаз. С подложкой — 12,2–14,6.

   Почему подложка СПЛОШНАЯ, а не часть картинки: контраст не должен
   зависеть от загрузки. Не приехал файл — текст остаётся на угле, а не
   оказывается на красном фоне секции, то есть не проваливается в те же
   3,74. По той же причине у секции задан background-color.

   Картинка остаётся тегом <img> (.hero__bg), а не background-image:
   background теряет alt, fetchpriority и srcset, а это LCP-элемент
   главной. */
.hero {
  position: relative;
  overflow: hidden;
  border-bottom: var(--border);
  padding: var(--space-9) 0;
  background: var(--brand-red);
}
/* ПЯТЬ СЛОЁВ ИЛЛЮСТРАЦИИ (задание АУ, 03.09.2026). Коробки слоёв равны кадру, масштаб и кадрирование как у прежней
   одной картинки — кадр при нулевой прокрутке пиксель в пиксель прежний. Движение по прокрутке первого экрана
   разнонаправленное (значения и знаки пишет theme.js в переменные; без скрипта они равны нулю). Слои в потоке идут
   снизу вверх и при одном z-index накладываются в этом порядке. Запаса у слоёв нет: растр кончается на краю кадра,
   поэтому фон и капюшон, касающиеся правого края, уходят вправо (за кадр), а не влево — иначе у края открылась бы
   полоса ровно на ход. */
.hero { --hero-fon: 0px; --hero-hood: 0px; --hero-helmet: 0px; --hero-cap: 0px; --hero-glasses: 0px; }
.hero__sloj { position: absolute; inset: 0; z-index: 0; display: block; pointer-events: none; will-change: transform; }
.hero__sloj .hero__bg { inset: 0; }
.hero__sloj--fon { transform: translate3d(var(--hero-fon), 0, 0); }
.hero__sloj--hood { transform: translate3d(var(--hero-hood), 0, 0); }
.hero__sloj--helmet { transform: translate3d(var(--hero-helmet), 0, 0); }
.hero__sloj--cap { transform: translate3d(var(--hero-cap), 0, 0); }
.hero__sloj--glasses { transform: translate3d(var(--hero-glasses), 0, 0); }
@media (prefers-reduced-motion: reduce) {
  .hero__sloj { transform: none; }
}
.hero__bg {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  /* COVER И КАДР ПО ТОЧКЕ 72% — значения редакции, выверенные
     скриншотами на живом 19.09.2026 (1400 px и 390 px). Приехали из
     «Дополнительных стилей» настройщика, где лежали с пометкой
     ks-vremenno-hero-i-mobilnyj-fon.

     ОНИ ОТМЕНЯЮТ ПРАВКУ 20.08.2026, КОТОРАЯ СТАВИЛА ЗДЕСЬ contain.
     Та правка решала задачу ДРУГОЙ иллюстрации: полотно 1376×768 с
     пропорцией 1,79 в коробке 2,34 при cover наезжало, и крайний левый
     профиль уходил под непрозрачную часть подложки. На нынешней
     картинке contain даёт обратное — в кадр попадает пустой фон вместо
     лиц. Прежнее обоснование не стало неверным: оно описывало снимок,
     которого больше нет.

     72% по горизонтали, а не right center: лица сдвинуты от правого
     края, и упор вправо срезал бы крайнюю фигуру. */
  object-fit: cover;
  object-position: 72% 50%;
}
/* Подложка. Слева плотный уголь, справа прозрачность — там лица, и
   закрывать их незачем.

   ГРАДИЕНТ ОСЛАБЛЕН редакцией 19.09.2026, значения выверены скриншотами
   на 1400 px. Прежний был СПЛОШНЫМ до 42% ширины и полупрозрачным до
   82% — на новой картинке он гасил фигуры. Новый не имеет сплошного
   участка вовсе (начинается с 0,94) и уходит в прозрачность уже к 72%.

   Заголовок остаётся читаемым не за счёт подложки, а за счёт самой
   иллюстрации: её левая часть почти чёрная. Это и есть причина, по
   которой плотность можно было снять. Значения не подбирать заново. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(
    90deg,
    rgba(20, 18, 16, 0.94) 0%,
    rgba(20, 18, 16, 0.80) 30%,
    rgba(20, 18, 16, 0.32) 54%,
    rgba(20, 18, 16, 0) 72%
  );
}
.hero__grid {
  position: relative; z-index: 2;
  display: grid; grid-template-columns: 1fr; gap: var(--grid-gutter);
  align-items: center;
}
.hero__grid > div { max-width: 58%; }
.hero__title {
  font: var(--text-display); text-transform: uppercase;
  letter-spacing: var(--tracking-display); margin: 0 0 var(--space-5);
  color: var(--color-paper);
}
/* Лид и часы на угле — кремовые. --color-muted (#5B5751) здесь дал бы
   2,4:1 и не читался бы вовсе. */
.hero__lead { max-width: var(--measure-article); color: var(--color-paper); }
/* Часы над заголовком. Базовые правила ниже по файлу написаны под светлое
   геро (--color-muted на бумаге); на угле #5B5751 даёт 2,4 и не читается
   вовсе. Селектор с .hero перебивает их специфичностью, а не порядком. */
.hero .site-clock--hero { color: var(--color-paper); opacity: 0.75; }
.hero .site-clock--hero .site-clock__time,
.hero .site-clock--hero .site-clock__sep { color: var(--color-paper); }
/* Призрачная кнопка на тёмном: обводка и текст кремовые, иначе угольная
   рамка на угле исчезает. */
.hero .btn--ghost { color: var(--color-paper); border-color: var(--color-paper); }
.hero .btn--ghost:hover { background: var(--color-paper); color: var(--color-coal); }
.hero__actions { display: flex; gap: var(--space-4); flex-wrap: wrap; }

/* ---------- Плашка-хаб со счётчиком ---------- */
.hub-banner {
  background: var(--color-coal); color: var(--color-paper);
  padding: var(--space-7) var(--space-6);
  display: grid; grid-template-columns: auto 1fr auto;
  gap: var(--space-6); align-items: center;
}
.hub-banner h2 { color: var(--color-paper); margin: 0 0 var(--space-2); }
.hub-banner p { margin: 0; color: var(--color-line-soft); }

/* Счётчик закона. Состояния — строго по спеке листа 3. */
.law-counter { text-align: center; min-width: 140px; }
.law-counter__num { font: var(--text-display); line-height: 0.9; display: block; }
.law-counter__word { font: var(--text-meta); letter-spacing: var(--tracking-meta); text-transform: uppercase; }
/* Красная остаётся только ЦИФРА: 72px — крупный текст, порог 3:1 взят
   (3,45 на угле). Слово под ней — 13px, для него красный на угле не
   проходит AA, поэтому оно кремовое — тем же токеном, что сосед
   .hub-banner p (решение 14.08.2026). */
.law-counter--before { color: var(--brand-red-text); }
.law-counter--before .law-counter__word { color: var(--color-line-soft); }
.law-counter--after {
  background: var(--color-paper-2); color: var(--color-coal);
  border: var(--border); border-left: var(--border-accent);
  padding: var(--space-4) var(--space-5);
}
.law-counter__label { font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase; color: var(--color-line-soft); display: block; }

/* ---------- Лента новостей ---------- */
/* padding-block, а НЕ шорткат: `padding: 64px 0` обнулял горизонтальное
   поле, которое задаёт .container, и секция «Новости» на главной стояла
   вплотную к краям — h2 на 0 px при «Ликбезе» на 20. Та же ошибка, что
   была в .site-header__inner; проверка tools/test_kontejnery.php теперь
   ловит её у всех классов, которые ставятся рядом с container. */
.layout { display: grid; grid-template-columns: minmax(0, 8fr) minmax(0, 4fr); gap: var(--space-8); padding-block: var(--space-8); }
/* Шапка блока: заголовок с меткой слева, выход в рубрику справа.

   align-items: flex-end, а не baseline. В шапке три разных шрифта и три
   разные высоты строки — Oswald 32/35.2 у заголовка, Oswald 13/16.9 у
   метки, Golos 18/29.7 у ссылки, — и базовая линия при таком наборе
   даёт лесенку: ссылка садилась на 5 px ниже остальных (замер живого
   сайта 16.08.2026). Нижняя кромка — единственная линия, которая от
   высоты строки не зависит.

   Подпирать лесенку отступами нельзя: это чинит один набор кеглей,
   а следующая правка типографики вернёт её обратно. */
.section-head {
  display: flex; align-items: flex-end;
  gap: var(--space-4); margin-bottom: var(--space-5);
}
/* Заголовок и метка — один блок, чтобы ссылке было по чему равняться. */
.section-head__title { display: flex; align-items: baseline; gap: var(--space-4); }
/* Выход в рубрику: у правого края и одной строкой. Перенос его подписи
   и был вторым дефектом — «Все / новости / →» в три строки. */
.section-head__link { margin-left: auto; white-space: nowrap; }
/* И h1 тоже: в архивах заголовок первого уровня стоит в той же строке,
   а нижний отступ по умолчанию ломал выравнивание по базовой линии. */
.section-head h2, .section-head h1 { margin: 0; }

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

   Втроём в один ряд они не помещаются: на 390 px ссылке «Все новости →»
   оставалось 82 px, и она вставала в ТРИ строки высотой 89 px — выше
   собственного заголовка блока. Замер на живом сайте 16.08.2026.

   Порядок задаётся order, а не перестановкой разметки: в разметке метка
   стоит между заголовком и ссылкой, и менять её место значило бы трогать
   три шаблона ради одного экрана. */
@media (max-width: 600px) {
  .section-head { flex-wrap: wrap; gap: var(--space-2) var(--space-4); }
  /* На телефоне метка встаёт ПОД заголовок, а не рядом: втроём в ряд они
     не помещаются, и ссылке доставалось 82 px на три строки. */
  .section-head__title { flex-direction: column; align-items: flex-start; gap: 2px; }
  .section-head__title .meta { font-size: 12px; }
  .section-head__link { flex: 0 0 auto; }
}

/* Компактная строка ленты: без обложки, плотнее по вертикали.

   Пункт 3 задания по мобильной вёрстке. Замер 16.08.2026: одна карточка
   на 390 px занимала 560 px — две трети экрана, и половину этой высоты
   забирала обложка. За экран читатель видел один материал.

   Обложка убрана только из показа. Она по-прежнему генерируется и нужна:
   это og:image в превью Telegram и в поисковой выдаче.

   Первая карточка остаётся крупной — у ленты должен быть вход, а не
   ровный список одинаковых строк. */
.card--compact {
  padding: var(--space-4) var(--space-5);
  /* Сетка на две колонки: кадр обложки 120 px слева (до 25.09.2026 —
     сцена-значок 68×68), текст справа. Кадр вынесен в сетку, а не пущен во
     float: заголовок в две строки при float обтекал бы картинку снизу, и
     левый край текста гулял бы от строки к строке. */
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  grid-column-gap: var(--space-4);
  align-items: start;
}
/* Раскладка задаётся ЯВНО для обеих колонок, а не полагается на
   автоматическое размещение.

   Живой дефект 16.08.2026: у сцены стояло только `grid-row: 1 / -1`, и
   `-1` указывало на последнюю линию ЯВНОЙ сетки, то есть на вторую. Сцена
   занимала одну строку, а подзаголовок и метаданные автоматически падали
   в первую колонку шириной 68 px — и текст выводился по одному слову в
   строку. На превью это выглядит как рассыпавшаяся вёрстка, потому что
   она и рассыпалась.

   Отсюда правило: в сетке из двух колонок каждому элементу колонка
   назначается прямо. Автоподстановка экономит три строки CSS и стоит
   поломанной главной. */
.card--compact > * {
  grid-column: 2;
}
.card--compact .card__kadr {
  grid-column: 1;
  grid-row: 1 / span 3;
  display: block;
}
/* Карточка без кадра (записи без обложки) не должна оставлять пустую
   колонку. */
.card--compact:not(:has(.card__kadr)) {
  display: block;
}
/* Крупная карточка: кадр 4:3 слева (5/12), текст справа — как «Главное»
   на главной. До 900 px — колонкой, кадр над заголовком. */
.card:not(.card--compact):has(.card__kadr) {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  grid-column-gap: var(--space-5);
  align-items: start;
}
.card:not(.card--compact):has(.card__kadr) > * { grid-column: 2; }
.card:not(.card--compact) > .card__kadr { grid-column: 1; grid-row: 1 / span 3; display: block; }
.card:not(.card--compact):has(.card__kadr) .card__title { margin-top: 0; }
/* До 900 px крупная карточка — колонкой: правила в общем мобильном блоке ниже. */
@media (max-width: 600px) {
  .card--compact { grid-template-columns: 96px minmax(0, 1fr); }
}
.card--compact .card__title {
  /* Заголовок компактной строки — тот же кегль, что у основного текста,
     но плотнее: h3 по умолчанию крупнее и с большими полями, а в списке
     из восьми строк каждый лишний пиксель множится на восемь. */
  font: var(--text-body);
  font-weight: 700;
  line-height: 1.3;
  margin: 0 0 var(--space-2);
}
.card--compact .card__lead {
  font: var(--text-small);
  margin: 0 0 var(--space-2);
}
.card--compact .card__meta { margin: 0; }

.card {
  border: var(--border); padding: var(--space-5);
  margin-bottom: var(--space-5); background: var(--color-paper);
  transition: border-color var(--motion-base) var(--ease-out);
}
.card:hover { border-color: var(--brand-red-text); }
.card:hover .card__title a { color: var(--brand-red-text); }
/* Заголовки карточек — Golos Text 700 по всему сайту (решение владельца
   25.09.2026): Oswald остаётся заголовкам секций и hero. */
.card__title { font: 700 22px/1.3 var(--font-text); margin: var(--space-3) 0; }
.card__title a { color: var(--color-coal); }
.card__lead { color: var(--color-muted); margin: 0; }
.card__meta { display: flex; gap: var(--space-3); align-items: center; flex-wrap: wrap; }

/* Шапка записи: сцена рядом с рубрикой. До 16.08.2026 внутри материала не
   было ни одного изображения вообще — читатель видел сплошной текст.
   Обложку сюда ставить нельзя: на ней тот же заголовок крупным кеглем. */
.article__head {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.article__head > p { margin: 0; }
.article__scene {
  flex: 0 0 auto;
  width: 96px;
  height: 96px;
  overflow: hidden;
  border: var(--border);
  background: var(--color-paper);
}
.article__scene .scene { display: block; width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 640px) {
  .article__scene { width: 64px; height: 64px; }
}

/* --- Поиск в шапке --------------------------------------------------------
   <details>, а не скрипт: разворачивается без JS, закрывается Escape
   средствами браузера, и состояние не надо держать вторым способом. */
.site-search { position: relative; }
/* Кнопка поиска набрана как пункт меню (--text-meta, капс, тот же
   трекинг): она стоит в одном ряду с рубриками и не должна выглядеть
   инородно. Цвет — уголь на бумаге (~14:1), иконка идёт currentColor
   и наследует контраст текста. Поле нажатия остаётся 44×44 (Z10). */
.site-search summary {
  list-style: none; cursor: pointer;
  font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase; color: var(--color-coal);
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  min-width: var(--tap-target-min); min-height: var(--tap-target-min);
}
.site-search summary svg { flex: none; display: block; }
.site-search summary::-webkit-details-marker { display: none; }
/* Ховер — в блоке (hover: hover) выше. */
.site-search__panel {
  position: absolute; right: 0; top: 100%; z-index: 30;
  padding: var(--space-4); min-width: 320px;
  background: var(--color-paper); border: var(--border);
}

/* Форма поиска. Раньше жила в атрибутах style внутри searchform.php, и
   переопределить её медиазапросом было нечем — инлайновый стиль сильнее
   любого правила таблицы.

   min-width: 0 на поле — не украшение, а весь смысл правки. Флекс-элемент
   по умолчанию не сжимается уже своей внутренней ширины (min-width: auto),
   а у input[type=search] она берётся из атрибута size и составляет около
   двадцати знаков. Поэтому в узкой панели бургера поле держало ширину, а
   кнопка «Найти» выдавливалась за правый край экрана. */
.search-form { display: flex; gap: var(--space-3); max-width: 520px; }
/* Кнопка поиска — иконкой. Область нажатия НЕ МЕНЬШЕ 44×44: это нижняя
   граница, ниже которой промахиваются пальцем, и она же причина, по
   которой размер задан здесь, а не оставлен на усмотрение содержимого —
   один символ лупы дал бы кнопку в 20 px. */
.search-form__knopka {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 .6em;
  line-height: 1;
}

.search-form__input {
  flex: 1 1 auto; min-width: 0;
  border: var(--border); padding: var(--space-3);
  background: var(--color-paper); font: var(--text-body);
}
/* Кнопка не сжимается: «Найти» в две строки читается как две кнопки. */
.search-form .btn { flex: 0 0 auto; }

/* --- Навигация по месяцам -------------------------------------------------
   Ряд ссылок, а не выпадающий список: месяцев у рубрики единицы, и
   спрятать их под клик значит спрятать сам факт, что архив есть. */
.month-nav { margin: 0 0 var(--space-6); }
.month-nav ul {
  display: flex; flex-wrap: wrap; gap: var(--space-2);
  list-style: none; margin: 0; padding: 0;
}
.month-nav li { margin: 0; }
.month-nav__item {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: var(--border); color: var(--color-coal);
  font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
}
/* Ховер — в блоке (hover: hover) выше. */
.month-nav__item.is-current { background: var(--brand-red-text); color: var(--color-paper); border-color: var(--brand-red-text); }
.month-nav__count { opacity: .7; }


/* Описание рубрики под заголовком архива. Абзац, а не врезка: это
   вводный текст страницы, а не выноска. */
/* ПОЯВЛЕНИЕ КАРТОЧЕК В СПИСКАХ (архивы рубрик и витрина «Истории»). Класс .poyavlenie ставит скрипт (theme.js) — без
   скрипта карточки видны сразу и целиком. Меняются только opacity и transform: высота и поля не трогаются, вёрстка при
   прокрутке не сдвигается. Задержка по порядку — переменная от скрипта, шаг 60 мс. */
.poyavlenie { --poyavlenie-delay: 0ms; opacity: 0; transform: translateY(24px) scale(0.985); }
/* border-color в списке — чтобы переход рамки карточки при наведении (.card) не перебивался переходом появления. */
.poyavlenie.is-vidno { opacity: 1; transform: none; transition: opacity 400ms ease-out, transform 400ms ease-out, border-color var(--motion-base) var(--ease-out); transition-delay: var(--poyavlenie-delay), var(--poyavlenie-delay), 0ms; }
@media (prefers-reduced-motion: reduce) {
  .poyavlenie, .poyavlenie.is-vidno { opacity: 1; transform: none; transition: none; }
}

.archive-intro {
  font: var(--text-small);
  color: var(--color-muted);
  max-width: var(--measure-article);
  /* Отрицательного отступа больше нет: он компенсировал поля заголовка,
     пока абзац лежал внутри .section-head. Компенсировать чужую геометрию
     минусом — способ получить ещё одну поломку при следующей правке. */
  margin: 0 0 var(--space-6);
}
/* Описание рубрики стало телом хаба: внутри бывают абзацы, списки,
   подзаголовки и ссылки. Отступы задаются здесь, а не в вёрстке
   описания, — редакция пишет текст, а не разметку страницы. */
.archive-intro > *:first-child { margin-top: 0; }
.archive-intro > *:last-child { margin-bottom: 0; }
.archive-intro p { margin: 0 0 var(--space-4); }
.archive-intro h2 { font: var(--text-h3); margin: var(--space-6) 0 var(--space-3); }
.archive-intro ul,
.archive-intro ol { margin: 0 0 var(--space-4); padding-left: var(--space-5); }
.archive-intro li { margin-bottom: var(--space-2); }

/* Медиа-блок карточки: одинаковая геометрия у изображения и у заглушки.
   Это предохранитель, а не украшение. Запись без обложки — штатная
   ситуация: так выходит любая автопубликация пайплайна. Пока размер
   медиа-блока зависел от того, ЧТО в него попало, каждая такая запись
   могла увести раскладку. Теперь коробка одна и та же: ширина карточки
   и фиксированное соотношение — картинка другого формата не меняет
   высоту ряда.

   Соотношение 1200/630, а не 16/9. Обложки рисуются ровно 1200×630
   (канон og:image), и коробка 16/9 обрезала их повторно: object-fit:
   cover срезает то, что не влезло, а не влезает низ — там подпись
   «КРИПТОСРЕДА · CRYPTOSREDA.RU». Первая обрезка происходила ещё раньше,
   при загрузке (см. set_post_thumbnail_size в inc/setup.php), и вместе
   они срезали подпись дважды.

   object-fit оставлен cover: заглушка и чужая картинка нестандартного
   формата всё равно обязаны заполнить коробку целиком, иначе вернётся
   прыгающая высота ряда. Для наших обложек он теперь ничего не режет —
   соотношение коробки совпадает с их собственным. */
.card > a > img,
.card .cover {
  display: block;
  width: 100%;
  aspect-ratio: 1200 / 630;
}
.card > a > img { object-fit: cover; }


.tag {
  display: inline-block; padding: var(--space-1) var(--space-3);
  font: var(--text-meta); letter-spacing: var(--tracking-meta); text-transform: uppercase;
  border: var(--border); color: var(--color-coal);
  transition: background var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out);
}
.tag:hover { background: var(--color-coal); color: var(--color-paper); }

/* ---------- Авто-обложка (карточка): без файлов, только CSS ---------- */
/* Ручных картинок к автоновостям не будет никогда, поэтому обложка ленты —
   это разметка, а не изображение. og-image генерируется отдельно (PHP GD). */
/* container-type — чтобы кегль считался от ШИРИНЫ ОБЛОЖКИ, а не экрана.
   Пока обложка занимала всю ширину контейнера, разница не проявлялась;
   в сетке карточка стала 327 px, а заголовок остался 30 px по vw — и
   налез на штамп и знак. Кегль обязан зависеть от коробки, в которой
   он живёт, а не от того, какой ширины окно.

   Верхний отступ отдельно от общего: штамп и знак лежат абсолютом в
   верхних углах, и заголовок, растущий снизу вверх, обязан иметь под
   них зарезервированное место, а не «обычно помещаться». */
.cover {
  /* То же соотношение, что у загруженных обложек: CSS-заглушка и картинка
     обязаны занимать одинаковую коробку, иначе высота ряда прыгает между
     записью с обложкой и записью без неё. */
  position: relative; aspect-ratio: 1200 / 630;
  padding: var(--space-5);
  padding-top: calc(var(--space-4) * 2 + 26px);
  container-type: inline-size;
  display: flex; flex-direction: column; justify-content: flex-end;
  overflow: hidden;
}
.cover__stamp {
  position: absolute; top: var(--space-4); left: var(--space-4);
  padding: var(--space-1) var(--space-3);
  font: var(--text-meta); letter-spacing: var(--tracking-meta); text-transform: uppercase;
}
/* Знак и штамп тоже от ширины обложки: 40 px на карточке 327 px —
   это четверть высоты кадра. */
.cover__mark {
  position: absolute; top: var(--space-4); right: var(--space-4);
  width: clamp(24px, 11cqw, 40px); height: auto;
}
.cover__stamp { font-size: clamp(9px, 3.4cqw, 12px); }
.cover__title {
  font-family: var(--font-display); font-weight: 700; line-height: 1.02;
  text-transform: uppercase; letter-spacing: var(--tracking-display);
  margin: 0; overflow: hidden;
  /* Не больше трёх строк: четвёртая уезжает под штамп, и обложка
     превращается в кашу из наложенного текста. Обрезка видимая —
     она честнее, чем наложение. */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
}
.cover__meta { font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase; margin-top: var(--space-3); }
/* Штриховка — единственная декорация, разрешённая спекой обложек */
.cover__hatch {
  position: absolute; inset: auto 0 0 0; height: 8px;
  background: repeating-linear-gradient(
    90deg, currentColor 0 12px, transparent 12px 24px);
  opacity: .35;
}

.cover--news    { background: var(--color-paper); color: var(--color-coal); }
.cover--news    .cover__stamp { background: var(--color-coal); color: var(--color-paper); }
.cover--edu     { background: var(--color-coal); color: var(--color-paper); }
.cover--edu     .cover__stamp { background: var(--brand-red-text); color: var(--color-paper); }
.cover--hub     { background: var(--color-paper); color: var(--color-coal); }
.cover--hub     .cover__stamp { background: var(--brand-red-text); color: var(--color-paper); }
/* Страница (24.09b): без штампа и мета-строки — только заголовок и знак,
   цвета новости. Шаблона flash больше нет (inc/covers.php). */
.cover--stranica { background: var(--color-paper); color: var(--color-coal); }

/* Кегль заголовка обложки — из спеки листа 3 (карточка 800×450) */
.cover--news .cover__title, .cover--edu .cover__title,
.cover--stranica .cover__title { font-size: clamp(15px, 6.4cqw, 30px); }
.cover--hub   .cover__title { font-size: clamp(14px, 5.7cqw, 27px); }

/* ---------- Кадр обложки: правая часть обложки 1200×630 ---------- */
/* Решение владельца 25.09.2026: в карточке — только правая часть обложки,
   иллюстрация без впечатанного заголовка; заголовок — живым текстом рядом
   (задание 25.09, п. 3). Разметку даёт inc/kadr.php (cryptosreda_kadr).

   Канон обложки: текст слева до x ≈ 627 из 1200, чистая зона x ≥ 640 —
   560×630, около 8:9. Кадр — окно с overflow: hidden, картинка в нём
   абсолютом, прижата вправо. Размер картинки — по форме кадра:
   — кадр шире 8:9 (4:3, 1:1): ширина 100% × 1200/560, по вертикали по
     центру — в окно входят ровно правые 560 из 1200;
   — кадр уже 8:9 (4:5): высота 100%, ширина авто — правые 504 из 1200.

   object-fit: cover с object-position: right здесь запрещён: он вписывает
   картинку по высоте кадра и на 1:1 открывает x от 570 — текст.
   max-width: none обязателен: общее img { max-width: 100% } в начале файла
   сжало бы картинку до ширины кадра, и в окно вернулась бы вся обложка.

   СПЕЦИФИЧНОСТЬ ПРАВИЛ КАРТИНКИ — (0,3,0): класс кадра, класс формы,
   класс картинки. Кадр встаёт внутрь чужих обёрток, а у темы есть
   контекстные правила вида .chitajte__oblozhka img { width: 100% } (0,1,1)
   и даже .guide__main figure.wp-block-image img (0,2,2). Простое
   .kadr__img (0,1,0) им проигрывало: в «Читайте также» картинка сжималась
   до ширины кадра, и в окно возвращалась вся обложка с текстом (ревью
   п. 3, 25.09.2026). Телефонный блок и «целиком» той же специфичности
   стоят ниже — при равенстве решает порядок.

   Ширину обёртка задаёт себе сама (width: 100%): картинка в ней абсолютом
   и ширины не даёт, и в flex-ряду или в сетке с выравниванием по началу
   кадр без своей ширины схлопнулся бы в ноль. Колонку ему даёт родитель
   (flex-basis, grid-column).

   Числа держит tools/test_kadr_oblozhki.php: он читает эти правила и
   считает, какая часть оригинала видна — и в чистом кадре, и внутри
   каждого контекстного правила темы. Поменяли правило — пересчитайте
   там, а не подгоняйте тест. */
.kadr {
  position: relative; display: block; overflow: hidden;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--color-paper);
}
.kadr--1x1 { aspect-ratio: 1 / 1; }
.kadr--4x5 { aspect-ratio: 4 / 5; }
.kadr--3x2 { aspect-ratio: 3 / 2; }
.kadr.kadr--4x3 .kadr__img,
.kadr.kadr--1x1 .kadr__img,
.kadr.kadr--3x2 .kadr__img,
.kadr.kadr--4x5 .kadr__img {
  position: absolute; top: 50%; right: 0;
  width: calc(100% * 1200 / 560); max-width: none; height: auto;
  transform: translateY(-50%);
}
.kadr.kadr--4x5 .kadr__img { top: 0; width: auto; height: 100%; transform: none; }
/* Телефон, до 600 px — одна колонка: своя форма кадра, по умолчанию 4:3
   у всех мест (решение 25.09). Граница — CRYPTOSREDA_KADR_TELEFON в
   inc/kadr.php, по ней считается sizes; разойдутся числа — браузер скачает
   картинку под одну форму, а покажет другую. Блок стоит после правил
   широкого экрана: при равной специфичности решает порядок. */
@media (max-width: 600px) {
  .kadr--t-4x3 { aspect-ratio: 4 / 3; }
  .kadr--t-1x1 { aspect-ratio: 1 / 1; }
  .kadr--t-4x5 { aspect-ratio: 4 / 5; }
  .kadr--t-3x2 { aspect-ratio: 3 / 2; }
  .kadr.kadr--t-4x3 .kadr__img,
  .kadr.kadr--t-1x1 .kadr__img,
  .kadr.kadr--t-3x2 .kadr__img { top: 50%; width: calc(100% * 1200 / 560); height: auto; transform: translateY(-50%); }
  .kadr.kadr--t-4x5 .kadr__img { top: 0; width: auto; height: 100%; transform: none; }
}
/* Целиком — обложка не 1,85–1,95 : 1 или вложение из реестра
   inc/data/kadr-isklyucheniya.json. Кадр берёт пропорцию самой обложки
   (aspect-ratio: auto, картинка в потоке): видна вся, без полей.
   До 25.09.2026 здесь был contain в окне формы места — на стенде главной
   обложка 1200×630 в кадре 4:5 занимала меньше половины высоты карточки,
   остальное было пустой бумагой. Специфичность обёртки (0,2,0) выше
   правил формы и телефона, у картинки (0,3,0) — та же, что у телефонных,
   и блок стоит после них: форма кадра на телефоне меняется, способ
   показа — нет. */
.kadr.kadr--celikom { background: var(--color-paper); aspect-ratio: auto; }
.kadr.kadr--celikom .kadr__img {
  position: static; display: block;
  width: 100%; max-width: 100%; height: auto; transform: none;
}
/* Форма 3:2 — рамка фиксирована даже у «целиком» (задание 30.09.2026,
   п. 3). В ряду «Три» у всех карточек область картинки одной пропорции:
   «целиком» не задаёт высоту кадра сама, а лежит в рамке 3:2 — contain по
   центру на бумаге, ничего не режется. Без этого блока обложка 1,905 : 1
   выходила в 2,4 раза ниже кропа рядом, и ряд растягивался по самой
   высокой карточке (замер живой главной 30.09: 197 px против 468).
   Правила стоят после «целиком» и специфичнее его: (0,3,0) у обёртки и
   (0,4,0) у картинки против (0,2,0) и (0,3,0). Широкий экран и телефон —
   своими блоками, как у кропа: форма на телефоне меняется независимо. */
@media (min-width: 601px) {
  .kadr.kadr--celikom.kadr--3x2 { aspect-ratio: 3 / 2; }
  .kadr.kadr--celikom.kadr--3x2 .kadr__img {
    position: absolute; top: 0; left: 0; right: auto;
    width: 100%; max-width: none; height: 100%; transform: none;
    object-fit: contain; object-position: 50% 50%;
  }
}
@media (max-width: 600px) {
  .kadr.kadr--celikom.kadr--t-3x2 { aspect-ratio: 3 / 2; }
  .kadr.kadr--celikom.kadr--t-3x2 .kadr__img {
    position: absolute; top: 0; left: 0; right: auto;
    width: 100%; max-width: none; height: 100%; transform: none;
    object-fit: contain; object-position: 50% 50%;
  }
}

/* ---------- Статья ---------- */

/* Плашка «Что это значит для пользователя в России».
   Разметку даёт публикатор воркера (publish/wordpress.py, build_content_html):
   <div class="ks-rf-block"><h2>…</h2><p>…</p></div>.

   Именно блок, а не картинка plate-rf из дизайн-системы: картинка не тянется
   под длину текста, не переносится на мобильном и не индексируется поиском,
   а этот блок — главное, ради чего материал вообще переписывается.

   Значения цветов заданы числами, а не токенами: правило приехало из ТЗ
   владельца в таком виде, и совпадает с --color-paper-2 / --color-coal /
   --brand-red-text. Разъедутся — править здесь. */
.ks-rf-block {
  background: #E4DCC8;
  border: 2px solid #141210;
  border-left: 6px solid var(--brand-red-text);
  padding: 16px 20px;
  margin: var(--space-6) 0;
}
.ks-rf-block > :first-child { margin-top: 0; }
.ks-rf-block > :last-child { margin-bottom: 0; }

.article { padding: var(--space-8) 0; }
/* minmax(0, …) вместо голых долей, и min-width: 0 у колонок.
   ЗАЧЕМ. Замер 23.08.2026, iframe 390 px: /cfa-i-kriptovalyuta-raznica/
   уезжала за экран на 132 px. У элемента сетки по умолчанию
   min-width: auto — он не сжимается ниже минимальной ширины своего
   содержимого. Широкая сравнительная таблица задирала колонку до
   502 px, и вместе с ней за экран уезжали h1, обложка, мета-строка и
   весь текст: читатель на телефоне видел страницу «зазумленной».
   Дефект вылез на одной записи из пятидесяти, но причина общая — любой
   широкий блок в контенте ломает страницу так же. */
.article__grid {
  display: grid;
  grid-template-columns: minmax(0, 8fr) minmax(0, 4fr);
  gap: var(--space-8);
}
.article__body { max-width: var(--measure-article); min-width: 0; }
.article__grid > * { min-width: 0; }

/* Та же болезнь у ленты: сетка из тех же долей. */
.layout > * { min-width: 0; }

/* ТАБЛИЦЫ ТЕКСТА НЕ ОБРЕЗАЮТСЯ НИКОГДА (задание 24.09.2026b, п. 1.5).

   Разметку даёт inc/tablicy.php: .tablica (фигура блока «Таблица» или
   обёртка голой таблицы) → .tablica__prokrutka → table, под ней подпись
   .tablica__podskazka. Правила висят на классе обёртки, а не на
   .article__body: у документов редакции (/politika-obrabotki-dannyh/,
   /principy/) текст стоит в .dokument__kolonka, и таблицы там обрезались
   при 375 так же.

   До 24.09.2026 здесь стояло `table { min-width: max-content }` (23.08,
   f5a2500): любая таблица растягивалась до строки без переносов, а
   фигура прятала излишек прокруткой, полосы которой на macOS не видно.
   Владелец видел в гайде срезанный третий столбец. Без того правила при
   1280 и 1024 помещались ВСЕ 13 таблиц сайта (замер разведки 24.09b).

   Таблица — во всю колонку, ячейки переносят слова (auto-раскладка:
   ширины столбцов по содержимому). table-layout: fixed из задания не
   взят: он делит колонку поровну, и столбец-подпись «Что это» получил бы
   треть ширины, а длинное слово в узком столбце рвалось бы посередине.
   Не поместилась и с переносом — прокрутка ВНУТРИ .tablica__prokrutka,
   страницу она не двигает. Полоса прокрутки видна всегда (::-webkit-
   scrollbar отключает прозрачную «оверлейную» полосу macOS; Firefox —
   scrollbar-color), а подпись «← листайте таблицу →» открывает theme.js,
   когда таблица шире колонки на самом деле. */
.tablica { margin: var(--space-6) 0; max-width: 100%; }
/* Ядро вешает overflow-x: auto на саму фигуру — прокрутка переезжает на
   внутреннюю обёртку, иначе вместе с таблицей уезжала бы и подпись. */
figure.wp-block-table.tablica { overflow: visible; }
.tablica__prokrutka { overflow-x: auto; max-width: 100%; }
.tablica table { width: 100%; border-collapse: collapse; }
.tablica th,
.tablica td { overflow-wrap: break-word; vertical-align: top; }
/* Переносы по слогам (hyphens: auto) — только на узких экранах, правило в
   общем мобильном блоке ниже: на десктопе места хватает, а «Удоб-ство» в
   столбце подписей при 1280 читается как опечатка. Отдельного блока
   @media (max-width: 900px) здесь нет намеренно — tools/test_brejkpointy.php
   держит первый такой блок за общим мобильным. */
.tablica__prokrutka::-webkit-scrollbar { height: 12px; }
.tablica__prokrutka::-webkit-scrollbar-track { background: var(--color-paper-2); }
.tablica__prokrutka::-webkit-scrollbar-thumb { background: var(--color-coal); }
@supports not selector(::-webkit-scrollbar) {
  .tablica__prokrutka { scrollbar-color: var(--color-coal) var(--color-paper-2); }
}
.tablica__prokrutka:focus-visible { outline: 3px solid var(--brand-red); outline-offset: 2px; }
.tablica__podskazka { display: none; margin: var(--space-2) 0 0; font: var(--text-small); color: var(--color-muted); }
/* Слова подписи — здесь, а не в разметке (inc/tablicy.php): текстом они
   уезжали бы в авто-отрывки и REST. Элемент и так aria-hidden. */
.tablica__podskazka::before { content: "← листайте таблицу →"; }
.tablica--shire .tablica__podskazka { display: block; }

/* До 600 px таблица из 3+ столбцов с шапкой — карточками: строка — блок,
   у каждой ячейки подпись столбца из data-label (ставит inc/tablicy.php
   из thead). Ячейка без подписи — заголовок строки («Что это», «Ключ»):
   она идёт первой строкой карточки полужирным. Шапка скрыта — её слова
   уже стоят у каждой ячейки. */
@media (max-width: 600px) {
  .tablica.tablica--kartochki .tablica__prokrutka { overflow: visible; }
  .tablica.tablica--kartochki table,
  .tablica.tablica--kartochki tbody,
  .tablica.tablica--kartochki tfoot,
  .tablica.tablica--kartochki tr,
  .tablica.tablica--kartochki th,
  .tablica.tablica--kartochki td { display: block; width: auto; }
  .tablica.tablica--kartochki thead { display: none; }
  .tablica.tablica--kartochki tr {
    border: 2px solid var(--color-coal);
    padding: var(--space-3) var(--space-4);
    margin: 0 0 var(--space-4);
  }
  .tablica.tablica--kartochki td,
  .tablica.tablica--kartochki th { border: 0; padding: var(--space-1) 0; text-align: left; }
  .tablica.tablica--kartochki td[data-label]::before,
  .tablica.tablica--kartochki th[data-label]::before {
    content: attr(data-label) ": ";
    font-weight: 600;
  }
  /* Первая ячейка — предмет строки («Что это», «Нет посредника»):
     полужирной всегда, с подписью столбца или без неё. */
  .tablica.tablica--kartochki tr > :first-child {
    font-weight: 700;
    padding-bottom: var(--space-2);
  }
  .tablica.tablica--kartochki .tablica__podskazka { display: none; }
}
.article__stamp {
  display: inline-block; background: var(--brand-red-text); color: var(--color-paper);
  padding: var(--space-1) var(--space-3);
  font: var(--text-meta); letter-spacing: var(--tracking-meta); text-transform: uppercase;
}
.article__dates { margin: var(--space-4) 0; }
.article__lead {
  border-left: var(--border-accent); padding-left: var(--space-5);
  font-size: 20px; color: var(--color-coal);
}
.article__body h2 { margin-top: var(--space-7); }
.article__body a { text-decoration: underline; text-underline-offset: 3px; }

/* ЦИТАТА — комментарий эксперта. Отбивка слева, без курсива и без фона.

   Селектор — .article__body, а не .entry-content: класса .entry-content в
   теме нет вовсе (проверено 01.09.2026: на всех трёх страницах приёмки в
   разметке стоит .article__body, .entry-content не встречается ни разу).
   Правило под .entry-content не применилось бы ни к одной цитате.

   Красный ЗДЕСЬ ДРУГОЙ, и это не оплошность. У лида, плашки РФ и
   «Обновлено» стоит --border-accent: 6px solid var(--brand-red-text) —
   в теме это значит «редакция говорит от себя». Цитата — речь стороннего
   человека, и путать её с голосом редакции нельзя: 3 px вместо 6 и
   --brand-red (#D7262C) вместо служебного --brand-red-text. Цвет канонный,
   похожий не подбирать.

   Курсива нет намеренно. Комментарии приходят по 400–600 знаков — на таком
   объёме наклонное начертание Golos Text читается заметно хуже прямого.
   font-style: normal стоит явно: ядро WP наклоняет цитату у стиля
   is-style-large, и без этой строки один вставленный «крупный» блок
   отменил бы правило.

   Горизонтальных margin НЕТ ВООБЩЕ — только padding слева. Браузерный
   дефолт у blockquote — margin 40px по бокам; на 375 px колонка равна
   335 px (375 − 2×--container-pad-m), и цитата с дефолтом ужалась бы до
   255 px, то есть встала бы уже абзаца. Отступ внутри блока, за полосой,
   ширину не трогает. */
.article__body blockquote {
  border-left: 3px solid var(--brand-red);
  padding: 2px 0 2px var(--space-4);   /* 16px слева, за полосой */
  margin: var(--space-5) 0;            /* 24px сверху и снизу, по бокам ноль */
  background: none;
  font-style: normal;
}
.article__body blockquote p:last-child { margin-bottom: 0; }

/* Подпись. Своего <cite> у нынешних девяти цитат нет — имя и место работы
   стоят внутри абзаца в <strong>. Правило заведено на вперёд: блок цитаты
   в редакторе поле подписи предлагает, и без него cite приехал бы курсивом
   от браузера, в кегле основного текста и без отбивки. */
.article__body blockquote cite {
  display: block;
  margin-top: var(--space-2);          /* 8px */
  font-size: 0.9em;
  font-style: normal;
  opacity: 0.75;
}

/* Плашка «Что это значит для пользователя в РФ» — приходит из пайплайна
   как <h2> + <p>, тема оборачивает её в блок (inc/pipeline.php) */
.rf-note {
  background: var(--color-paper-2);
  border-left: var(--border-accent);
  padding: var(--space-5) var(--space-6);
  margin: var(--space-7) 0;
}
.rf-note > :last-child { margin-bottom: 0; }
.rf-note__title { font: var(--text-h3); text-transform: uppercase; margin: 0 0 var(--space-3); }

/* Плашка «Обновлено {дата}: {что изменилось}» — над текстом записи.

   Отбивка слева акцентом, как у лида и у плашки РФ: в теме это уже значит
   «редакция говорит от себя», и четвёртого способа сказать то же самое
   заводить незачем. Фон бумажный, а не красный: сообщение не тревожное. */
.obnovleno {
  background: var(--color-paper-2);
  border-left: var(--border-accent);
  padding: var(--space-4) var(--space-5);
  margin: 0 0 var(--space-6);
  font: var(--text-small);
  color: var(--color-coal);
}
.obnovleno__data { font-weight: 600; }

/* FAQ-блок редакции. Раскрывашка родная, <details>: ни строки JS, работает
   с клавиатуры и читается диктором. Стороннего аккордеона в теме нет. */
.faq {
  border-top: var(--border);
  margin: var(--space-7) 0 0;
  padding-top: var(--space-5);
}
.faq__zagolovok { font: var(--text-h2); margin: 0 0 var(--space-5); }
.faq__para { border-bottom: 1px solid var(--color-line-soft); }
/* Маркер-треугольник браузера убран в пользу своего знака: у Safari и
   Chrome он рисуется по-разному и в разном месте строки. */
.faq__vopros {
  display: flex; justify-content: space-between; gap: var(--space-4);
  align-items: baseline;
  min-height: var(--tap-target-min);
  padding: var(--space-4) 0;
  cursor: pointer; font-weight: 600;
  list-style: none;
}
.faq__vopros::-webkit-details-marker { display: none; }
.faq__vopros::after { content: "+"; color: var(--brand-red-text); flex: none; }
.faq__para[open] .faq__vopros::after { content: "–"; }
.faq__otvet { padding-bottom: var(--space-4); }
.faq__otvet > p:first-child { margin-top: 0; }
.faq__otvet > p:last-child { margin-bottom: 0; }

/* Мини-квиз «Проверьте себя». Вариант — кнопка, а не radio: radio просит
   «отправить», а отправлять здесь некуда и незачем. */
.quiz {
  border: var(--border);
  border-top: var(--border-accent);
  padding: var(--space-5);
  margin: var(--space-7) 0 0;
}
.quiz__zagolovok { font: var(--text-h3); margin: 0 0 var(--space-5); }
.quiz__voprosy { list-style: none; margin: 0; padding: 0; counter-reset: kviz; }
.quiz__vopros { counter-increment: kviz; margin-bottom: var(--space-6); }
.quiz__vopros:last-child { margin-bottom: 0; }
.quiz__tekst { font-weight: 600; margin: 0 0 var(--space-4); }
.quiz__tekst::before { content: counter(kviz) ". "; color: var(--color-muted); }
.quiz__varianty { list-style: none; margin: 0; padding: 0; }
.quiz__varianty li { margin-bottom: var(--space-3); }
/* Кнопка во всю ширину и с левым выравниванием: вариант ответа — это
   строка текста, а не подпись на кнопке «ОК». */
.quiz__variant {
  display: block; width: 100%; text-align: left;
  min-height: var(--tap-target-min);
  padding: var(--space-3) var(--space-4);
  border: var(--border); background: var(--color-paper);
  font: var(--text-body); color: var(--color-coal);
  cursor: pointer;
}
.quiz__variant:hover:enabled { background: var(--color-paper-2); }
.quiz__variant:disabled { cursor: default; }
.quiz__variant--verno { border-color: var(--brand-red); background: var(--color-paper-2); font-weight: 600; }
.quiz__variant--neverno { opacity: .6; text-decoration: line-through; }
/* Сегментирующий вопрос: выбор виден, оценки нет. Тот же вид, что у
   выбранного варианта диагностики, — там верного ответа тоже не бывает. */
.quiz__variant--vybran {
  border-color: var(--brand-red); background: var(--color-paper-2); font-weight: 600;
}
/* Слово «неверно» само не зачёркивается: у неверного варианта стоит
   line-through, и подпись уезжала под ту же черту — то есть единственное
   место, где ответ назван словом, читалось хуже всего. */
.quiz__znak { color: var(--brand-red-text); font-weight: 600; }
.quiz__variant--neverno .quiz__znak { text-decoration: none; display: inline-block; }
.quiz__razbor {
  margin: var(--space-3) 0 0; padding-left: var(--space-4);
  border-left: var(--border-accent);
  font: var(--text-small); color: var(--color-coal);
}
.quiz__itog { margin: var(--space-5) 0 0; font-weight: 600; }
.quiz__nota { margin: var(--space-4) 0 0; color: var(--color-muted); }

/* Диагностика 115-ФЗ / 161-ФЗ. Кнопки, а не форма: формы на странице нет
   вовсе — ответы про блокировку счёта конкретного человека собирать
   нельзя ни при каких условиях. */
.diag__voprosy { list-style: none; margin: 0 0 var(--space-6); padding: 0; counter-reset: diag; }
.diag__vopros { counter-increment: diag; margin-bottom: var(--space-6); }
.diag__tekst { font-weight: 600; margin: 0 0 var(--space-4); }
.diag__tekst::before { content: counter(diag) ". "; color: var(--color-muted); }
.diag__varianty { list-style: none; margin: 0; padding: 0; }
.diag__varianty li { margin-bottom: var(--space-3); }
.diag__variant {
  display: block; width: 100%; text-align: left;
  min-height: var(--tap-target-min);
  padding: var(--space-3) var(--space-4);
  border: var(--border); background: var(--color-paper);
  font: var(--text-body); color: var(--color-coal);
  cursor: pointer;
}
.diag__variant:hover { background: var(--color-paper-2); }
.diag__variant--vybran {
  border-color: var(--brand-red); background: var(--color-paper-2); font-weight: 600;
}
.diag__itog {
  border: var(--border); border-top: var(--border-accent);
  padding: var(--space-5); margin-bottom: var(--space-5);
}
.diag__itog-zagolovok { font: var(--text-h3); margin: 0 0 var(--space-3); }
.diag__itog p:last-child { margin-bottom: 0; }
.diag__materialy { margin: 0 0 var(--space-5); padding-left: var(--space-5); }
/* Оговорка не мельче основного текста и не серая: она обязательна к
   прочтению, а не сноска. */
.diag__ogovorka {
  border-left: var(--border-accent); padding-left: var(--space-4);
  margin: 0 0 var(--space-5); color: var(--color-coal);
}
.diag__nota { color: var(--color-muted); }

/* Пояснение про шкалу — под результатом, отбито от него, но не сноской:
   на вопрос «почему такая ставка» отвечает именно оно. */
.calc__scale { margin: var(--space-4) 0 0; color: var(--color-muted); }

/* «Читайте также» — три карточки в ряд, на мобильном в колонку. */
.chitajte { border-top: var(--border); margin-top: var(--space-7); padding-top: var(--space-5); }
.chitajte__zagolovok { font: var(--text-h3); margin: 0 0 var(--space-5); }
.chitajte__spisok {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5);
}
.chitajte__ssylka { display: block; text-decoration: none; color: var(--color-coal); }
.chitajte__ssylka:hover .chitajte__nazvanie { text-decoration: underline; }
/* Обложка держит своё соотношение и не тянет ряд: высоту ячейки задаёт
   самый длинный заголовок, а не картинка. */
.chitajte__oblozhka { display: block; margin-bottom: var(--space-3); }
.chitajte__oblozhka img,
.chitajte__oblozhka .cover { display: block; width: 100%; height: auto; }
.chitajte__nazvanie { display: block; font-weight: 700; }

/* «Поделиться» (inc/podelitsya.php, 24.09.2026). Текстовые кнопки, без
   логотипов площадок: знаки чужих брендов в теме запрещены, а подпись
   «Telegram» и так читается сразу.

   Контраст на бумаге #F0EBDD: текст кнопок — уголь, 15,69; подпись
   «Поделиться» — --color-muted, 6,02; при наведении и фокусе —
   --brand-red-text-hover, 6,37. Подчёркивание — красный бренда: это не
   текст, ему достаточно 3:1, у #D7262C на бумаге 4,20.

   Цель не меньше 44×44 при мелком кегле: min-height и min-width от
   --tap-target-min. Поля кнопки по бокам нулевые, расстояние между
   целями задаёт gap — тогда подчёркивание идёт ровно по буквам.
   Селектор с родителем нарочно: .article__body a (0,1,1) иначе
   перебил бы подчёркивание своим смещением. */
.podelitsya {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-line-soft);
}
.podelitsya__zagolovok {
  margin: 0;
  font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase; color: var(--color-muted);
}
.podelitsya__knopki {
  display: flex; flex-wrap: wrap; align-items: center;
  column-gap: var(--space-5);
}
.podelitsya .podelitsya__knopka {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap-target-min); min-width: var(--tap-target-min);
  margin: 0; padding-block: 0; padding-inline: 0;
  font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase; color: var(--color-coal);
  background: none; border: 0; cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--brand-red);
  text-decoration-thickness: 2px;
  text-underline-offset: .35em;
}
.podelitsya .podelitsya__knopka:hover,
.podelitsya .podelitsya__knopka:focus-visible { color: var(--brand-red-text-hover); }
/* hidden обязан побеждать display: inline-flex выше: иначе кнопки,
   которые без скрипта ничего не делают, были бы видны всегда. */
.podelitsya .podelitsya__knopka[hidden],
.podelitsya .podelitsya__adres[hidden] { display: none; }
/* Пустое сообщение высоты не занимает: поля у абзаца сняты. */
.podelitsya__status {
  margin: 0;
  font: var(--text-small); color: var(--color-coal);
}
/* Поле с адресом — только когда буфер обмена отказал, как в календаре
   (.timeline__adres). */
.podelitsya__adres {
  display: block; width: 100%;
  min-height: var(--tap-target-min);
  margin: var(--space-2) 0 0;
  padding: var(--space-2);
  font: var(--text-small);
  border: var(--border); background: var(--color-paper); color: var(--color-coal);
}
/* Страница 404. Отступ сверху и снизу — как у любой посадочной: раньше
   он стоял инлайном в шаблоне, а инлайновый отступ не переживает правку
   токенов. */
/* padding-BLOCK, а не шорткат padding: класс стоит рядом с .container, и
   `padding: X 0` обнулил бы боковое поле контейнера. Эта ошибка в теме
   случалась дважды за один день (логотип у края экрана, секция «Новости»
   вплотную к краям), и на неё есть отдельная проверка. */
.oshibka { padding-block: var(--space-9); }
/* Лид 404 — на бумаге, поэтому приглушённый уголь (6,02 на бумаге), а не
   бумажный цвет лида плаката главной: с ним абзац сливался с фоном. */
.oshibka__lid { max-width: var(--measure-article); color: var(--color-muted); margin: 0 0 var(--space-6); }
.oshibka__puti { margin: 0 0 var(--space-7); padding-left: var(--space-5); }
.oshibka__puti li { margin-bottom: var(--space-3); }
.oshibka__svezhee { margin-top: var(--space-8); }

/* Иллюстрация 404 (02.10.2026; вложение из медиатеки — inc/oshibka.php).
   КАРТИНКА — ОТДЕЛЬНЫМ БЛОКОМ, а не фоном под текстом. У иллюстрации своя бумага
   (средний цвет левой части ≈ #EEDCC1, бежевая), не бумага сайта #F0EBDD, и красная
   ссылка #C2372B на ней даёт контраст 4,04:1 (в тёмном зерне бумаги — 3,67:1) против
   4,55:1 на бумаге сайта — ниже порога 4,5 для обычного текста (замер по файлу
   02.10.2026). Блок рядом с текстом держит контраст там, где он уже проверен, и не
   зависит от того, сколько строк займёт текст на конкретной ширине.
   Телефон: заголовок, лид, ссылки и поиск — как было, картинка под ними (на 375 px
   заголовок и первые две ссылки на первом экране, поиск тоже). От 901 px: слева
   текст, справа картинка; картинка по центру высоты текста.
   Без вложения модификатора --s-kartinkoj нет, и страница та же, что была. */
.oshibka__kartinka { margin: var(--space-7) 0 0; }
.oshibka__img {
  display: block; width: 100%; height: auto;
  /* Левая часть иллюстрации — пустая бумага под заголовок обложки; в этой раскладке
     она не нужна, поэтому кадр 4:3 прижат вправо и срезает только пустоту: фигура,
     дверь и стрела (правые ~55 %) остаются целиком. */
  aspect-ratio: 4 / 3; object-fit: cover; object-position: 100% 50%;
  border: var(--border);
}
@media (min-width: 901px) {
  .oshibka__verh--s-kartinkoj {
    display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: var(--space-7); align-items: center;
  }
  .oshibka__kartinka { margin: 0; }
}

/* Подпись автора под записью. Появится, когда страницу «Об авторе»
   опубликуют, — стиль лежит здесь заранее и ничего не стоит. */
.avtor { margin: var(--space-5) 0 0; }
.avtor__podpis { margin-right: var(--space-2); }
.avtor__imya { font-weight: 600; }

/* Список дат на странице календаря, собранной из файла. Шаблон пока не
   привязан к странице — см. docs/BLOCKERS.md. */
/* Документ редакции: узкая колонка. 68ch — примерно 12 слов в строке,
   ширина, на которой глаз не теряет начало следующей. Правовой текст
   читают по пунктам, и длинная строка здесь дороже, чем в статье. */
.dokument__kolonka { max-width: 68ch; margin: 0 auto; }
.dokument__daty { margin: 0 0 var(--space-6); }
.dokument__kolonka h2 { margin-top: var(--space-7); }

/* ---------- Ось событий ---------- */
/* Линия оси — псевдоэлемент группы, а не отдельный узел: полоса это
   оформление, и в разметке ей делать нечего. */
.timeline { margin: var(--space-7) 0; }
.timeline__filtr { margin-bottom: var(--space-6); }
.timeline__filtr-podpis { margin: 0 0 var(--space-3); }
.timeline__roli { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.timeline__rol {
	border: var(--border);
	background: transparent;
	color: inherit;
	padding: var(--space-2) var(--space-4);
	font: var(--text-small);
	cursor: pointer;
}
.timeline__rol[aria-pressed="true"] { background: var(--color-coal); color: var(--color-paper); }
.timeline__pusto { color: var(--color-muted); }
.timeline__gruppa { position: relative; padding-left: var(--space-6); }
.timeline__gruppa::before {
	content: "";
	position: absolute;
	left: 0;
	top: 0;
	bottom: 0;
	width: 2px;
	background: var(--color-line-soft);
}
.timeline__epoha { font: var(--text-h3); margin: var(--space-6) 0 var(--space-4); }
.timeline__spisok { list-style: none; margin: 0; padding: 0; }
.timeline__sobytie {
	position: relative;
	padding-bottom: var(--space-6);
	border-left: 2px solid transparent;
	margin-left: calc(var(--space-6) * -1);
	padding-left: var(--space-6);
}
/* Текущее событие подсвечивается ЛИНИЕЙ, а не заливкой: заливка на
   светлом фоне читается как выделение мышью. */
.timeline__sobytie.is-tekushchee { border-left-color: var(--brand-red-text); }
.timeline__data { margin: 0; font: var(--text-small); color: var(--color-muted); }
.timeline__status { text-transform: uppercase; letter-spacing: .08em; }
.timeline__zagolovok { font: var(--text-h3); margin: var(--space-2) 0; }
/* Название события — абзац со strong, а не заголовок: одиннадцать дат это
   навигация, а не структура документа. Кегль остаётся заголовочным. */
.timeline__zagolovok strong { font-weight: inherit; }
.timeline__note { margin: 0 0 var(--space-2); }
.timeline__norma { margin: 0; color: var(--color-muted); }

/* ── Календарь: якоря, статусы, прошедшее ────────────────────────────

   ДАТА — ССЫЛКА НА СЕБЯ. Выглядит как дата, а не как ссылка: подчёркивание
   приходит по наведению и по фокусу. Сплошь подчёркнутый столбец дат
   читался бы как список ссылок на другие страницы, а ведёт он сюда же. */
.timeline__yakor-ssylka { color: inherit; text-decoration: none; }
.timeline__yakor-ssylka:hover,
.timeline__yakor-ssylka:focus-visible { text-decoration: underline; }

/* Якорь-зонт для повторяющейся даты: пустой узел, место не занимает.
   scroll-margin на нём — чтобы строка не прилипала к верхнему краю окна
   при переходе по ссылке. */
.timeline__zont { display: block; height: 0; }
.timeline__sobytie { scroll-margin-top: var(--space-7); }

/* ПЕРЕХОД ПО ЯКОРЮ — ПЛАВНЫЙ, А НЕ ПРЫЖКОМ. Страница длинная: мгновенный
   скачок между разделами не даёт понять, куда тебя перенесло, — читатель
   теряет место. Правило reduced-motion ниже по файлу уже возвращает
   auto: кто просил меньше движения, получает прежний прыжок.

   scroll-margin у заголовков — под липкую шапку: без него цель уезжает
   под неё и выглядит «недопрокрученной». */
html { scroll-behavior: smooth; }
.article__body h2,
.article__body h3 { scroll-margin-top: calc(var(--space-7) + 72px); }

/* ПОДСВЕТКА ПРИШЕДШЕГО ПО ССЫЛКЕ — ЛИНИЕЙ, как у текущего события: тот же
   довод, заливка на светлом фоне читается как выделение мышью. Второе
   правило ловит случай трёх событий одной даты: там :target попадает на
   зонт внутри строки, а подсветить надо строку. */
.timeline__sobytie:target,
.timeline__sobytie:has(> .timeline__zont:target) {
  border-left-color: var(--brand-red-text);
}

/* ПРОШЕДШЕЕ ПРИГЛУШАЕТСЯ, НО ЧИТАЕТСЯ. Приглушение сделано полосой и
   меткой статуса, а НЕ opacity на всей строке: opacity 0,7 опускает
   контраст основного текста с 12,6 до 8,3, а приглушённого — с 4,8 до
   3,4, то есть ниже порога AA. Календарь читается как история; история,
   которую нельзя прочесть, — не история. */
.timeline__sobytie.is-proshloe { border-left-color: var(--color-line-soft); }
.timeline__sobytie.is-proshloe .timeline__status { color: var(--color-muted); }

/* Окно, которое закрывается, — единственный статус со срочностью, и он
   единственный красится. «Действует» и «вступает» — просто состояния. */
.timeline__sobytie.is-okno .timeline__status { color: var(--brand-red-text); }
.timeline__sobytie.is-okno { border-left-color: var(--brand-red-text); }

/* ── Шапка оси: ближайшая дата ───────────────────────────────────────
   Рамка как у карточек сайдбара: это карточка того же ряда. Число дней
   приходит с сервера готовым — в разметке лежит слово, а не счётчик. */
.timeline__shapka {
  border: var(--border); border-top: var(--border-accent);
  padding: var(--space-5); margin-bottom: var(--space-6);
}
.timeline__shapka-podpis { margin: 0 0 var(--space-2); }
.timeline__shapka-data { margin: 0; font: var(--text-h3); }
.timeline__shapka-data a { color: inherit; }
.timeline__shapka-ostalos {
  margin: .35em 0 0; color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

/* ── Полоса времени ──────────────────────────────────────────────────

   Прошедшая часть оси плотнее будущей: граница — отметка «сегодня»,
   приходит из разметки переменной --segodnya, посчитанной сервером.
   Метки стоят на своих долях отрезка (--mesto), подписи — только для
   дикторов и для всплывающей подсказки: четырнадцать дат в строку
   превратились бы в кашу. */
/* Подписи лет сверху, линия посередине, «сегодня» снизу — три этажа, и
   ни один не наезжает на другой. Первая версия (19.09.2026) клала всё в
   один: подписи концов стояли в строке под линией, метки лезли на них, а
   «сегодня» рисовалось поверх точек. Замер на живом это и показал. */
.timeline__polosa { position: relative; margin: 0 0 var(--space-7); }
.timeline__polosa-koncy {
  display: flex; justify-content: space-between;
  margin: 0 0 var(--space-3); font: var(--text-meta);
  letter-spacing: var(--tracking-meta); color: var(--color-muted);
}
.timeline__polosa-spisok {
  position: relative; list-style: none; margin: 0; padding: 0;
  height: 3px;
  background: linear-gradient(
    90deg,
    var(--color-coal) 0 var(--segodnya, 0%),
    var(--color-line-soft) var(--segodnya, 0%) 100%
  );
}
/*
 * СБРОС ЧУЖОГО ПРАВИЛА, И ЭТО НЕ ПЕРЕСТРАХОВКА. В теме два разных
 * компонента с приставкой timeline: этот и старый `<ol class="timeline">`,
 * который редакция ставит в текст страницы-хаба. У старого есть правило
 * `.timeline li { border-left: var(--border-accent); padding: … }`, и оно
 * доставалось меткам полосы: замер на живом 19.09.2026 показал у каждой
 * метки красную полосу 6 px и коробку 52×54 вместо точки.
 *
 * СЕЛЕКТОР ИЗ ДВУХ КЛАССОВ, А НЕ ИЗ КЛАССА И ТИПА. `.timeline li` и
 * `.timeline__polosa-spisok li` весят одинаково (0,1,1), а старое
 * правило лежит НИЖЕ в файле — при равном весе побеждает оно. Два
 * класса (0,2,0) снимают зависимость от того, кто где в файле.
 */
.timeline__polosa .timeline__metka { border: 0; padding: 0; margin: 0; }
.timeline__metka { position: absolute; top: 50%; left: var(--mesto, 0%); width: 0; height: 0; }
/* Точка 12 px, площадка нажатия 32×32: меньше — промах пальцем, больше —
   площадки соседних дат наезжают друг на друга (в реестре три события
   одной даты и две пары в пределах недели). */
.timeline__metka a {
  position: absolute; top: -16px; left: -16px;
  display: block; width: 32px; height: 32px; border-radius: 50%;
}
.timeline__metka a::before {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 12px; height: 12px; margin: -6px 0 0 -6px;
  border-radius: 50%;
  /* Будущее — светлая точка в тёмной обводке, прошедшее — залитая.
     Разница видна и в чёрно-белой печати, и при дальтонизме. */
  background: var(--color-paper); border: 2px solid var(--color-coal);
  /* ТОЧКА ВЫШЕ ЗАСЕЧКИ «СЕГОДНЯ». Замер 19.09.2026: засечка стоит в
     разметке после списка и потому рисовалась поверх — ближайшая к ней
     точка (15 августа) пропадала совсем. */
  z-index: 2;
}

/* ПОДСКАЗКА У МЕТКИ — СВОЯ, А НЕ БРАУЗЕРНАЯ. Атрибут title всплывает
   примерно через секунду и не открывается с клавиатуры вовсе: для
   навигации по четырнадцати точкам это слишком долго. Текст лежит в
   разметке всегда — читалке он доступен и без наведения, — а показывается
   мгновенно при наведении и при фокусе. */
.timeline__metka-podpis {
  position: absolute; bottom: 26px; left: 50%;
  transform: translateX(-50%);
  width: max-content; max-width: 15rem;
  padding: var(--space-2) var(--space-3);
  background: var(--color-coal); color: var(--color-paper);
  font: var(--text-small); line-height: 1.25; text-align: left;
  clip-path: inset(50%);          /* скрыто для глаз, доступно диктору */
  pointer-events: none; z-index: 3;
}
.timeline__metka a:hover .timeline__metka-podpis,
.timeline__metka a:focus-visible .timeline__metka-podpis { clip-path: none; }
/* У крайних меток подсказка упиралась бы в край страницы. */
.timeline__metka:first-child .timeline__metka-podpis { left: 0; transform: none; }
.timeline__metka:last-child .timeline__metka-podpis { left: auto; right: 0; transform: none; }
.timeline__metka.is-proshloe a::before { background: var(--color-coal); }
.timeline__metka a:hover::before,
.timeline__metka a:focus-visible::before {
  background: var(--brand-red-text); border-color: var(--brand-red-text);
}
/* «Сегодня» — засечка от линии вниз и подпись под ней. Засечка нужна:
   без неё подпись сама по себе не говорит, к какому месту относится. */
.timeline__polosa-segodnya {
  position: absolute; top: calc(50% + 3px); left: var(--segodnya, 0%);
  margin: 0; padding-top: 14px;
  transform: translateX(-50%);
  font: var(--text-meta); letter-spacing: var(--tracking-meta);
  color: var(--brand-red-text); white-space: nowrap;
}
.timeline__polosa-segodnya::before {
  content: ""; position: absolute; top: 0; left: 50%;
  width: 2px; height: 12px; margin-left: -1px;
  background: var(--brand-red-text);
  z-index: 1;   /* ниже точек: иначе засечка съедает ближайшую */
}

/* ── Действия у строки: файл календаря и копирование ────────────────── */
.timeline__dejstviya {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-3); margin: var(--space-3) 0 0;
}
.timeline__dejstvie {
  font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase; color: var(--color-muted);
  background: none; border: 0; padding: 0; cursor: pointer;
  text-decoration: none; text-underline-offset: .25em;
}
.timeline__dejstvie:hover,
.timeline__dejstvie:focus-visible { color: var(--brand-red-text); text-decoration: underline; }
/* Поле с адресом появляется, только когда буфер обмена недоступен: тогда
   читатель выделяет и копирует руками. Ширину держим по строке. */
.timeline__adres {
  flex: 1 1 100%; min-width: 0; margin-top: var(--space-2);
  font: var(--text-small); padding: var(--space-2);
  border: var(--border); background: var(--color-paper); color: var(--color-coal);
}

/* ── Навигация между разделами страницы ──────────────────────────────

   Три слота сеткой, а не flex со space-between: у первого раздела нет
   «назад», у последнего нет «дальше», и при space-between оставшаяся
   ссылка уезжала бы то влево, то вправо. С сеткой «все разделы» стоит
   посередине всегда. На узком экране — в столбик. */
.razdel-nav {
  display: grid; grid-template-columns: 1fr auto 1fr;
  gap: var(--space-3) var(--space-5); align-items: baseline;
  margin: var(--space-6) 0 var(--space-7);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-line-soft);
  font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
}
.razdel-nav a { color: var(--color-muted); text-decoration: none; }
.razdel-nav a:hover,
.razdel-nav a:focus-visible { color: var(--brand-red-text); text-decoration: underline; }
.razdel-nav__nazad { grid-column: 1; justify-self: start; }
.razdel-nav__naverh { grid-column: 2; justify-self: center; }
.razdel-nav__vpered { grid-column: 3; justify-self: end; text-align: right; }

/* ── Журнал правок ───────────────────────────────────────────────────
   Две колонки на широком экране, одна на узком. Дата не переносится:
   tabular-nums держит столбец ровным. */
.timeline__zhurnal { margin-top: var(--space-7); border-top: var(--border); padding-top: var(--space-5); }
.timeline__zhurnal-zagolovok { font: var(--text-h3); margin: 0 0 var(--space-4); }
/* ВОЗДУХ МЕЖДУ ЗАПИСЯМИ, А НЕ ВНУТРИ НИХ. Замер 19.09.2026 по скриншоту
   владельца: gap в две единицы давал между двумя записями столько же
   места, сколько между строками одной записи, и журнал читался сплошным
   абзацем. Дата и описание одной записи остаются рядом, следующая пара
   отходит на пять. */
.timeline__zhurnal-spisok {
  display: grid; grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--space-5) var(--space-5); margin: 0;
  line-height: 1.5;
}
.timeline__zhurnal-data {
  margin: 0; color: var(--color-muted); font: var(--text-small);
  font-variant-numeric: tabular-nums; line-height: inherit;
}
.timeline__zhurnal-chto { margin: 0; line-height: inherit; }
/* Строка сверки — отдельное утверждение, а не хвост последней записи
   журнала: без отступа она читалась как её продолжение (замер 19.09.2026,
   скриншот владельца). Линия сверху отделяет её и от списка. */
.timeline__svereno {
  margin: var(--space-5) 0 0; padding-top: var(--space-4);
  border-top: 1px solid var(--color-line-soft);
}

/* Разделы хаба темы: «с чего начать», ключевые даты, все материалы. */
.hub-tema { margin-top: var(--space-7); }
.hub-tema__zagolovok { font: var(--text-h2); margin: 0 0 var(--space-4); }
.hub-tema__spisok { margin: 0; padding-left: var(--space-5); }
.hub-tema__punkt { margin-bottom: var(--space-3); }

/* Блок «Что пока неясно» в конце записи. Тише основного текста и явно
   отделён: это не продолжение материала, а признание его границы. */
.neyasno {
	margin-top: var(--space-7);
	padding-top: var(--space-5);
	border-top: 1px solid var(--color-line-soft);
}
.neyasno__zagolovok { font: var(--text-h3); margin: 0 0 var(--space-4); }
.neyasno__spisok { margin: 0; padding-left: var(--space-5); }
.neyasno__punkt { margin-bottom: var(--space-3); color: var(--color-muted); }
.neyasno__punkt:last-child { margin-bottom: 0; }
.neyasno__norma { display: block; margin-top: var(--space-2); font: var(--text-small); }

/* Карточка «Источник нормы». Служебная сноска внутри текста: заметная,
   но не спорящая с абзацем, из которого выросла. */
.norma {
	margin: var(--space-5) 0;
	padding: var(--space-4) var(--space-5);
	border-left: 3px solid var(--color-line-soft);
	background: var(--color-paper-2);
	font: var(--text-small);
}
.norma p { margin: 0; }
.norma p + p { margin-top: var(--space-2); }
.norma__akt { font-weight: 600; }
.norma__daty { color: var(--color-muted); }
.norma__ssylka { margin-top: var(--space-3); }

.daty { margin: 0 0 var(--space-7); }
.daty__data { font-weight: 600; margin-top: var(--space-5); }
.daty__norma { margin: var(--space-2) 0 0 0; color: var(--color-muted); font: var(--text-small); }
.daty__pometka { display: block; margin-top: var(--space-2); }
.daty__status { text-transform: uppercase; letter-spacing: .08em; }

.disclaimer {
  border-top: 1px dashed var(--color-line-soft);
  padding-top: var(--space-4); margin-top: var(--space-7);
  font: var(--text-small); color: var(--color-muted);
}

.toc { border: var(--border); padding: var(--space-5); margin-bottom: var(--space-6); }
.toc h3 { margin-top: 0; }
.toc ol { list-style: none; padding: 0; margin: 0; counter-reset: toc; }
.toc li { counter-increment: toc; margin-bottom: var(--space-3); }
.toc li::before { content: counter(toc, decimal-leading-zero) " · "; color: var(--color-muted); }

.subscribe {
  border: var(--border); border-top: var(--border-accent);
  padding: var(--space-6); margin-bottom: var(--space-6);
}

/* Ближайшая дата вступления норм в силу — сайдбар главной.
   Рамка как у .subscribe: это карточка того же ряда, своего оформления
   она не просит. Ширина контента сайдбара 337 px при padding 32 px
   (замер 23.08.2026), длинные названия переносятся — обрезки нет
   намеренно: усечённое название нормы читается как другая норма. */
.kalendar {
  border: var(--border); border-top: var(--border-accent);
  padding: var(--space-6); margin-bottom: var(--space-6);
}
/* Подпись со значком в одну строку. gap в em, а не в px: значок обязан
   держаться подписи при любом кегле, а кегль тут задаётся токеном. */
.kalendar .meta { display: flex; align-items: center; gap: .5em; margin: 0; }
.kalendar__znak { flex: none; }
.kalendar__data { margin: .35em 0 0; font-weight: 600; }
/* --color-ink-soft НЕ СУЩЕСТВУЕТ в tokens.css, и строка «осталось N дней»
   из-за этого рисовалась основным цветом вместо приглушённого: объявление
   с неизвестной переменной браузер отбрасывает молча. Найдено 23.08.2026
   при разборе карточки. Верный токен — --color-muted, тот же, что у .meta. */
.kalendar__ostalos {
  margin: .35em 0 0; color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}
.kalendar__vse { margin: .75em 0 0; }

/* Обложка страницы календаря — как обложка дайджеста ниже: блоки стоят
   рядом в одной колонке и обязаны читаться как один ряд карточек.
   Картинка внутри ссылки, но из дерева доступности убрана: ссылка «все
   даты →» ведёт туда же, и второе имя на тот же адрес читалке не нужно
   (тот же довод, что у логотипа в шапке). */
.kalendar__oblozhka { display: block; width: 100%; height: auto; margin: 0 0 var(--space-4); }
.kalendar__oblozhka-ssylka { display: block; }
.kalendar__spisok { list-style: none; margin: 0; padding: 0; }
/* Разделитель между датами — линия, а не отступ: три даты подряд без
   границы читаются как один абзац с тремя числами. */
.kalendar__punkt + .kalendar__punkt {
  margin-top: var(--space-3); padding-top: var(--space-3);
  border-top: 1px solid var(--color-line-soft);
}
.kalendar__data a { color: inherit; text-decoration: none; }
.kalendar__data a:hover,
.kalendar__data a:focus-visible { text-decoration: underline; }

/* Картинка и пункты дайджеста из сайдбара главной ушли вместе с сайдбаром
   (24.09.2026, п. 7): блок «Дайджест по средам» теперь текстовый, правила — в
   разделе «Главная» в конце файла. */

/* Обложка материала в теле записи и страницы.

   aspect-ratio ЗАДАН ЯВНО, и это не украшение: без него браузеру нечем
   занять место до загрузки картинки, и текст прыгает вниз в момент, когда
   она приезжает. Атрибуты width/height в разметке настоящие (1024×538), но
   при width:100% они перестают задавать пропорцию — её держит эта строка.
   1200/630 — пропорция исходников обложек, из которой WordPress режет large.

   Ширина по колонке текста: обложка часть материала, а не врезка во всю
   ширину экрана. max-width страхует узкие экраны — картинка не вылезет за
   контейнер, даже если колонка окажется уже её. */
.entry-cover {
  margin: 0 0 var(--space-6);
  max-width: var(--measure-article);
}
.entry-cover__img {
  display: block;
  width: 100%;
  max-width: 100%;
  height: auto;
  aspect-ratio: 1200 / 630;
  object-fit: cover;
  border: var(--border);
}

/* Глоссарий: автоссылка первого вхождения термина */
.glossary-term {
  border-bottom: 1px dotted var(--brand-red-text);
  text-decoration: none;
}

/* Подсказка к термину. Позицию ставит скрипт, здесь только вид и предел
   ширины: без max-width определение на 220 знаков растягивается в одну
   строку во весь экран. */
.glossary-tip {
  position: absolute;
  z-index: 20;
  max-width: min(320px, calc(100vw - 16px));
  background: var(--color-coal);
  color: var(--color-paper);
  padding: var(--space-3) var(--space-4);
  font: var(--text-small);
  box-shadow: var(--shadow);
}
.glossary-tip[hidden] { display: none; }

/* ---------- Хаб ---------- */
.hub-toc ol { list-style: none; padding: 0; counter-reset: hub; }
.hub-toc li { counter-increment: hub; border-bottom: var(--border); padding: var(--space-4) 0; }
.hub-toc li::before { content: counter(hub, decimal-leading-zero) " · "; color: var(--brand-red-text); }

table.compare { width: 100%; border-collapse: collapse; margin-bottom: var(--space-6); }
table.compare th, table.compare td {
  border: var(--border); padding: var(--space-4); text-align: left; vertical-align: top;
}
table.compare thead th { background: var(--color-coal); color: var(--color-paper);
  font: var(--text-meta); letter-spacing: var(--tracking-meta); text-transform: uppercase; }
table.compare tbody tr:nth-child(even) { background: var(--color-paper-2); }

.timeline { list-style: none; padding: 0; }
.timeline li { border-left: var(--border-accent); padding: 0 0 var(--space-6) var(--space-5); }
.timeline__date { font: var(--text-meta); letter-spacing: var(--tracking-meta);
  text-transform: uppercase; color: var(--brand-red-text); }

/* FAQ-аккордеон: grid-template-rows 0fr → 1fr, без opacity (спека листа 3) */
.faq__item { border-bottom: var(--border); }
.faq__q {
  width: 100%; text-align: left; background: none; border: none; cursor: pointer;
  padding: var(--space-5) 0; font: var(--text-h3); color: var(--color-coal);
  display: flex; justify-content: space-between; gap: var(--space-4); align-items: center;
}
.faq__sign { color: var(--brand-red-text); flex: none;
  transition: transform var(--motion-slow) var(--ease-inout); }
.faq__q[aria-expanded="true"] .faq__sign { transform: rotate(90deg); }
.faq__a { display: grid; grid-template-rows: 0fr;
  /* Спека листа 3 называет 220ms, здесь стоит --motion-slow (240ms).
     Разница незаметна, зато длительность идёт через токен: при
     prefers-reduced-motion токены сводятся к 1ms, а зашитое число — нет. */
  transition: grid-template-rows var(--motion-slow) var(--ease-inout); }
.faq__q[aria-expanded="true"] + .faq__a { grid-template-rows: 1fr; }
.faq__a > div { overflow: hidden; }

/* ---------- Подвал ---------- */
.site-footer { background: var(--color-coal); color: var(--color-line-soft); padding: var(--space-8) 0; }
.site-footer a { color: var(--color-paper); }
/* Ховер НЕ красный: на угле красный текст не проходит AA ни одним из двух
   токенов (3,74 и 3,45 против порога 4,5 — решение 14.08.2026, третий,
   осветлённый токен не заводим). Состояние показывает подчёркивание,
   кремовый остаётся кремовым (15,7:1). */
.site-footer a:hover { color: var(--color-paper); text-decoration: underline; }
.site-footer__grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: var(--space-7); }
.site-footer__disclaimer { font: var(--text-small); }


/* ---------- Бургер: до 1130px ----------
   ОТДЕЛЬНЫЙ БЛОК, А НЕ ОБЩИЙ МОБИЛЬНЫЙ. Бургер выключался на 901px, а
   полное меню помещается без переноса только с 1131px. В полосе между
   этими числами шапка росла с 76 до 99px.

   ЧИСЛО 1131 ЗАМЕРЕНО 25.08.2026, А НЕ ВЗЯТО ИЗ ЗАДАНИЯ. В задании стояло
   1050 — из замера 23.08. С тех пор шапку правили (кнопка выросла до 44px,
   поля пересчитаны), и сегодня на 1050 шапка по-прежнему 99. Проверено
   двоичным поиском на живом сайте: 1128 и 1130 — 99px, 1132 и 1140 — 76px.

   МЕХАНИЗМ ПЕРЕНОСА тоже другой, чем в описании задания. Переносится не
   «последний пункт меню на вторую строку»: строка пунктов остаётся одна
   (все пять li имеют одинаковый top). Не помещается СОДЕРЖИМОЕ пункта —
   ul.menu это flex с nowrap, при нехватке места пункты сжимаются ниже
   своей ширины, и кнопка-шеврон уходит под подпись. Замер на 1130:
   у пункта «Ликбез» ссылка на top 22, шеврон на top 62, высота li 59
   вместо 44.

   ЧИСЛО ЗАВИСИТ ОТ ПОДПИСЕЙ ПУНКТОВ. Переименование пункта меню сдвигает
   порог, и тихо: шапка просто станет на 23px выше. Статической проверкой
   это не ловится — тест ниже держит РАЗДЕЛЬНОСТЬ границ, а не само число.

   Границу общего блока @media (max-width: 900px) двигать нельзя: там же
   сетки переходят в одну колонку, и на 1000px страница схлопнулась бы в
   столбец — дефект хуже исходного. Замерено: на 1000px лента в две
   колонки, на 899 — в одну. Поэтому правила бургера вынесены сюда, а всё
   остальное осталось на 900.

   БЛОК СТОИТ ПЕРЕД мобильным намеренно. Специфичность у правил одна, и на
   ширинах до 900px побеждает то, что ниже по файлу, — то есть мобильные
   значения (высота шапки, поля). Перестановка блоков местами тихо сломает
   мобильную шапку.

   JS трогать не пришлось, и это проверено: меню в assets/js/theme.js
   работает на атрибутах data-open и aria-expanded, брейкпоинта в нём нет
   ни одного. */
@media (max-width: 1130px) {
  /* ВЫСОТУ ШАПКИ ЗДЕСЬ НЕ ЗАДАЁМ, И ЭТО РЕШЕНИЕ, А НЕ ПРОПУСК.
     Первая версия правки ставила сюда своё поле, посчитанное из токенов.
     Замер показал, что оно не нужно и вредно: в этой полосе действует
     базовое правило (min-height 72, padding-block 16), самый высокий
     ребёнок строки — кнопка бургера 44px, итого 44 + 32 = 76. На десктопе
     ровно столько же: там самый высокий ребёнок — панель меню, и она тоже
     44px, потому что обе величины идут от одного токена --tap-target-min.
     То есть высота совпадает по построению, а не по подобранному числу, и
     на границе 1131px шапка не дёргается. Любое поле, добавленное сюда,
     этот скачок бы СОЗДАЛО: замер 25.08.2026 — с полем 14px выходило 72
     против 76 на десктопе.

     Ниже 900px действуют мобильные правила (min-height 56, padding 10 →
     64): они стоят дальше по файлу и перекрывают базовое. */
  /* Кнопка меню: цель нажатия и отступ от кромки экрана.
     Была 31.7×36 и прижата к правому краю вплотную (0 px на 320, 390 и 414).
     Промахнуться мимо неё проще, чем попасть, а палец у самой кромки экрана
     вдобавок цепляет системный жест «назад».

     Зона нажатия доводится до 44×44 псевдоэлементом, а не размером кнопки:
     кнопка выше строки логотипа, и рост её коробки тянет за собой высоту
     шапки — замер показал +8 px, а вслед за ними вниз уезжает весь геро-блок,
     где запас до сгиба на коротких экранах уже израсходован. Тот же приём,
     что у монетки-пасхалки, и по той же причине. */
  .nav-toggle {
    display: block; position: relative;
    /* margin-right больше не нужен: боковое поле пришло от .container,
       и кнопка встала по одной вертикали с правым краем h1 и обложки. */
    margin-left: auto;
  }
  .nav-toggle::after {
    content: ""; position: absolute; top: 50%; left: 50%;
    width: var(--tap-target-min); height: var(--tap-target-min);
    transform: translate(-50%, -50%);
  }
  /* Панель мобильного меню.
     Была прибита к числу: position:fixed + inset:var(--header-h-m), то есть
     к токену 56px, а не к реальной нижней кромке шапки. Прятали её через
     translateY(-110%) — минус 110% СВОЕЙ высоты. При высоте 92px это 101.2px,
     а уйти надо было на 56 + 92 = 148. Нижний край панели оставался на
     56 − 0.1×высота пикселей от верха экрана, и в закрытом состоянии из-под
     шапки торчала кнопка Telegram, разрезанная кромкой пополам. Торчала при
     любой высоте меньше 560px, то есть всегда; чем короче меню, тем сильнее.
     Перекрыть шапкой это нельзя: панель — её потомок и рисуется поверх фона
     независимо от z-index.

     Теперь top:100% от .site-header (она sticky, значит позиционирована) —
     привязка к содержимому, а не к токену: панель едет за реальной высотой
     шапки и когда та выросла от переноса, и когда сжалась в компактную.
     Прячется clip-path'ом, а не геометрией: обрезка не зависит ни от высоты
     панели, ни от того, докуда доехал трансформ. */
  .site-nav {
    position: absolute; top: 100%; left: 0; right: 0;
    background: var(--color-coal); flex-direction: column; align-items: stretch;
    padding: var(--space-5) var(--space-5) var(--space-6);
    gap: var(--space-3);
    /* Панель занимает вьюпорт до низа. Было max-height — высоту задавало
       содержимое, и при коротком меню снизу оставалась полоса страницы:
       из-под открытого меню светил геро-блок, а это читается как «меню
       не открылось до конца», а не как «меню короткое». Замер на 390×844:
       панель не доходила до низа на 214 px.
       dvh, а не vh: в мобильном Safari адресная строка меняет высоту
       вьюпорта, и на vh панель то не достаёт до низа, то уезжает под него. */
    height: calc(100dvh - 100%);
    overflow-y: auto;
    clip-path: inset(0 0 100% 0);
    /* visibility снимает закрытую панель с фокуса клавиатурой; задержка
       равна длительности, чтобы не гасить её посреди анимации закрытия */
    visibility: hidden;
    transition: clip-path var(--motion-slow) var(--ease-inout),
                visibility 0s linear var(--motion-slow);
  }
  .site-nav[data-open="true"] {
    clip-path: inset(0);
    visibility: visible;
    transition: clip-path var(--motion-slow) var(--ease-inout), visibility 0s;
  }
  /* Зазор между пунктами: 16 → 8. Сама цель нажатия остаётся 44 px, её
     задаёт min-height ссылки, а зазор к попаданию пальцем не относится —
     он только добавлял высоты. На 390×844 пять пунктов с поиском и
     кнопкой требовали прокрутки, хотя помещаться обязаны целиком. */
  .site-nav ul { flex-direction: column; gap: var(--space-2); }
  .site-nav a { color: var(--color-paper); min-height: var(--tap-target-min); display: flex; align-items: center; }
  /* Ховер в открытом бургере: фон здесь уголь, красный не проходит AA
     (см. tokens.css). Специфичность у правила та же, что у общего
     .site-nav a:hover, — побеждает порядок в файле, поэтому правило
     обязано стоять в мобильном блоке ПОСЛЕ общего; вариант с [data-open] —
     страховка на случай перестановки. */
  @media (hover: hover) and (pointer: fine) {
    .site-nav[data-open] a:hover,
    .site-nav a:hover { color: var(--color-paper); text-decoration: underline; }
  }

  /* Аккордеон внутри бургера. Наведения на тачскрине нет, поэтому здесь
     подменю открывается ТОЛЬКО нажатием — правил с :hover нет намеренно:
     на тач-устройствах :hover залипает после тапа и закрыть подменю
     становится нечем. */
  .site-nav .menu > li { display: flex; flex-wrap: wrap; align-items: center; }
  .site-nav .menu > li > a { flex: 1 1 auto; }
  .submenu-toggle {
    color: var(--color-paper);
    min-height: var(--tap-target-min); min-width: var(--tap-target-min);
    justify-content: center;
  }
  /* «Инструменты» — единственный пункт без своей страницы, поэтому он
     не ссылка, а кнопка-подпись. От соседей он отличался двумя вещами,
     и обе делали его похожим на подпункт неизвестно чего: собственный
     боковой padding сдвигал ТЕКСТ на 8 px вправо (коробка при этом
     стояла ровно — замер показал отступ 0, расходился только текст),
     а justify-content: center от кнопки-шеврона тянул его к середине.
     Здесь он выравнивается по левому краю, как остальные пункты. */
  /* Пункт-без-ссылки обязан быть визуально НЕОТЛИЧИМ от пункта-ссылки.
     Отличался он тремя вещами сразу (замер живого сайта 16.08.2026):
       - собственный боковой padding 8 px сдвигал текст правее соседей;
       - justify-content: center от кнопки-шеврона тянул содержимое к
         середине строки;
       - шеврон стоял вплотную к слову, а у «Ликбеза» и «Регуляторики» —
         у правого края.

     Кнопка растягивается на всю строку и разводит текст и шеврон по краям.
     Правый отступ считается из геометрии соседей, а не подобран на глаз:
     у них шеврон центрован в поле нажатия 44 px, значит его правая кромка
     отстоит от края пункта на (44 − ширина шеврона) / 2. Шеврон — два
     бордюра по 4 px, итого 8. Так правые кромки всех трёх шевронов
     совпадают попиксельно.

     Кегль и трекинг повторены явно: и .site-nav a, и .submenu-toggle берут
     var(--text-meta), но правка одного из двух правил развела бы их молча. */
  .submenu-toggle--label {
    flex: 1 1 100%;
    justify-content: space-between;
    padding-left: 0;
    padding-right: calc((var(--tap-target-min) - 8px) / 2);
    gap: var(--space-3);
    font: var(--text-meta);
    letter-spacing: var(--tracking-meta);
  }
  .site-nav .sub-menu {
    display: none; flex-basis: 100%; margin: var(--space-3) 0 0;
    padding-left: var(--space-5); border-left: 1px solid var(--color-line-soft);
  }
  .site-nav .submenu-toggle[aria-expanded="true"] + .sub-menu { display: flex; }

  /* ── Поиск внутри панели ──────────────────────────────────────────
     ЭТИ ПРАВИЛА ЖИЛИ В @media (max-width: 768px), И ЭТО БЫЛА ОШИБКА.
     Каждое из них — про бургер, о чём говорят и их собственные
     пояснения, — но граница у них стояла своя, на 768. То есть в полосе
     769–900px панель уже открывалась, а поиск в ней оставался в
     десктопном виде: контроль «Поиск» рисовался цветом --color-coal на
     угольном фоне панели, контраст 1:1 — контроль был невидим.

     Замер 25.08.2026 на живом, ширина 1000: summary color rgb(20,18,16),
     фон панели rgb(20,18,16). Дефект существовал до правки З4 на
     769–900, а вынос бургера до 1130 расширил бы полосу втрое.

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

  /* В бургере поиск разворачивается на всю ширину панели: там места
     достаточно, а попасть пальцем в узкое поле у края — нет. */
  .site-search { width: 100%; }
  .site-search summary { justify-content: flex-start; color: var(--color-paper); }
  /* Подпись в бургере остаётся: панель вертикальная, места достаточно,
     а «Поиск» рядом с рубриками читается как ещё один пункт меню. */
  /* Фон и рамку снимаем: панель наследовала кремовую подложку от
     десктопного выпадающего блока, и в бургере на угле она рисовалась
     пустой светлой плашкой над полем ввода — полосой шириной во всю
     панель и высотой в верхний padding. Здесь подложка не нужна вовсе:
     поле ввода и так кремовое, а панель лежит на угле. */
  /* Панель поиска нарисована под СВЕТЛУЮ десктопную шапку: кремовая
     коробка с рамкой. В тёмном бургере она торчала светлой полосой сверху
     и по бокам — 94 px коробки при форме в 58, разница ровно padding 32
     плюс border 4 (замер 16.08.2026). Поле ввода внутри того же цвета
     с ней сливалось.

     Здесь панель не рисует ничего: ни фона, ни рамки, ни отступа. Поле
     встаёт в поток между «Поиск» и кнопкой Telegram, а расстояние до
     соседей задаёт общий gap панели меню. */
  .site-search__panel {
    position: static; min-width: 0; padding: 0;
    background: none; border: 0;
  }
  /* Поле и кнопка встык: зазор между ними на угольном фоне читался как
     ещё одна светлая щель. */
  .search-form { max-width: none; gap: 0; }
  /* Автозаполнение красит фон принудительно, своим цветом и поверх
     background. Единственный способ его перебить — внутренняя тень во всю
     коробку; заодно фиксируется цвет текста, который браузер меняет вместе
     с фоном. Без этого поле в бургере вспыхивало бы светло-жёлтым. */
  .search-form__input:-webkit-autofill,
  .search-form__input:-webkit-autofill:hover,
  .search-form__input:-webkit-autofill:focus {
    -webkit-box-shadow: 0 0 0 1000px var(--color-paper) inset;
    -webkit-text-fill-color: var(--color-coal);
    caret-color: var(--color-coal);
  }
}

/* ---------- Мобильная ---------- */
@media (max-width: 900px) {
  .container { padding: 0 var(--container-pad-m); }
  /* Таблицы текста: переносы по слогам на узких экранах (inc/tablicy.php). */
  .tablica th,
  .tablica td { hyphens: auto; }
  .hero__grid, .layout, .article__grid, .site-footer__grid,
  .chitajte__spisok { grid-template-columns: 1fr; }
  /* Крупная карточка архива (п. 5, 25.09.2026): кадр над заголовком. */
  .card:not(.card--compact):has(.card__kadr) { display: block; }
  .card:not(.card--compact) > .card__kadr { margin-bottom: var(--space-3); }
  .hero { padding: var(--space-7) 0; }
  .hero__title { font-size: 40px; }
  /* Первый экран на телефоне.

     Замер живой главной 16.08.2026, 390×844: геро-блок занимал 791 px, то
     есть 94% вьюпорта, и первая карточка ленты начиналась на 981 px —
     полтора экрана. Материала на первом экране не было ни одного, при том
     что основной трафик проекта мобильный и из поиска.

     Что урезано и что нет. Текст не тронут ни словом: слоган, описание и
     обе кнопки остаются целиком — они и есть смысл первого экрана.
     Урезана ГЕОМЕТРИЯ: воздух блока, кегль заголовка, интерлиньяж
     описания и высота иллюстрации.

     Иллюстрация не спрятана. Четыре профиля — единственная картинка
     первого экрана и половина узнаваемости бренда; вместо этого она
     подрезана до полосы с обрезкой по центру, где профили как раз и
     стоят. object-position: center — не «по умолчанию», а осознанно:
     лица в кадре по центру, и при обрезке сверху и снизу они остаются. */
  .hero { padding: var(--space-5) 0; }
  .hero__title { font-size: 34px; }
  .hero__lead { line-height: 1.45; }
  .hero__grid { gap: var(--space-4); }
  /* Текст занимает всю ширину: колонки на телефоне нет, а подложка ниже
     переведена в вертикальную и кроет весь кадр. */
  .hero__grid > div { max-width: 100%; }
  /* Кадр смещён: на узком экране при обрезке по ширине правый край
     уезжает за пределы, и лица уходили бы из кадра целиком. */
  /* На узком экране кадрируем, а не вписываем: коробка уже полотна, и
     contain дал бы полоску 209 px посреди блока вместо иллюстрации. */
  /* ГЕРО ЗДЕСЬ БОЛЬШЕ НЕ ПРАВИТСЯ. Кадр и подложка первого экрана стоят
     на границе 768 — так их задала редакция, выверив скриншотами. Пока
     правила жили и здесь, в полосе 769–900 действовал мобильный кадр;
     теперь там десктопный, как и на живом сайте с 19.09.2026, где эту
     полосу перекрывал блок из «Дополнительных стилей». Сами правила —
     в @media (max-width: 768px) ниже по файлу. */
  /* Воздух между геро-блоком и лентой. 64 px сверху и снизу — десктопная
     величина, и на телефоне она стоит ровно между читателем и первым
     материалом. Урезано до 24: на узком экране разделяет уже сама смена
     фона, а не расстояние. */
  .layout { padding-block: var(--space-5); gap: var(--space-6); }
  h1 { font-size: 32px; }
  /* padding-block, а не шорткат: шорткат обнулял бы горизонтальное поле
     контейнера — ровно то, что чинилось в основном правиле. Правил у
     .site-header__inner ЧЕТЫРЕ (базовое, компактное и два здесь), и
     достаточно одного с шорткатом, чтобы поле снова исчезло. */
  .site-header__inner { min-height: var(--header-h-m); padding-block: var(--space-3); }
  /* Кнопка выросла с 36 до 44 и стала выше логотипа (40) — строка шапки
     тянется за ней. Чтобы высота шапки осталась прежней (замер: 66px),
     вертикальные поля уменьшены на те же 4px, что прибавила кнопка:
     44 + 10×2 = 64 = прежние 40 + 12×2. Число не выбрано, а посчитано из
     требования «шапка не растёт».

     Стоит ПОСЛЕ правила выше и перекрывает его вертикаль намеренно: то
     задаёт min-height, это — поля. */
  .site-header__inner { padding-block: 10px; }
  .hub-banner { grid-template-columns: 1fr; }
  table.compare, table.compare thead, table.compare tbody,
  table.compare tr, table.compare th, table.compare td { display: block; }
  table.compare thead { display: none; }
  table.compare td::before { content: attr(data-label) " · "; color: var(--color-muted); }
}

/* Низкий экран: iPhone SE/8 (375×667), типовой Android (360×640), любой
   телефон в ландшафте. Здесь геро занимает почти весь первый экран, и
   сигнала «ниже что-то есть» читателю не остаётся.

   16.08.2026 картинку отсюда УБИРАЛИ (display: none) ради цели «геро не
   больше 60% вьюпорта». Замер 19.08.2026 показал, что цель недостижима и
   не была достигнута: 60% от 667 — это 400 px, а геро БЕЗ картинки уже
   занимает 482. То есть узнаваемость бренда с первого экрана убрали, а
   прокрутку не выиграли.

   Цель переформулирована владельцем: картинка видна И под геро виден край
   следующего блока. Так и сделано — ужимаются отступы, а не содержимое:
   геро 474 px, нижняя граница 586 из 667 (88%), под ней остаётся 81 px и
   видна шапка «Новости».

   22 px оставлены числом, а не токеном: ближайший --space-5 равен 24, и
   пара сверху-снизу дала бы +4 px к замеренной высоте. Остальные три
   значения совпали с токенами точно.

   object-position подобран замером под КОНКРЕТНЫЙ файл: у иллюстрации
   лица прижаты к правому краю, а левая половина кадра — пустое полотно.
   При смене файла подбирать заново. */
@media (max-width: 900px) and (max-height: 700px) {
  .hero { padding-top: 22px; padding-bottom: 22px; }
  .hero__grid { gap: var(--space-3); }
  .hero__lead { margin-bottom: var(--space-4); }
}

/* ЛАНДШАФТ — отдельный случай, и полоса его не решает. Замер 19.08.2026 на
   844×390: со стопкой «текст, под ним полоса» геро занимает 116% вьюпорта,
   то есть картинка обрезана нижним краем экрана, а следующего блока не
   видно вовсе. Это ХУЖЕ, чем было со спрятанной картинкой.

   Причина в том, что в ландшафте не хватает высоты, а не ширины: 844 px
   поперёк — это ширина планшета, и колонки в неё помещаются. Возвращаем
   двухколоночную сетку: высота геро становится не суммой блоков, а
   максимумом из них.

   Замер после правки: геро 292 px, нижняя граница 358 из 390 (92%), под
   ней 32 px следующего блока, картинка 325×181 — лица крупные.
   Кегль h1 28 px здесь тоже от замера: с 34 px геро не помещалось
   (398 из 390). */
@media (max-width: 900px) and (max-height: 700px) and (orientation: landscape) {
  /* В ландшафте не хватает высоты, а не ширины: 844 px поперёк — ширина
     планшета. Текст сжимается в колонку слева, картинка работает фоном
     во всю ширину, лица остаются справа от текста. */
  .hero__grid > div { max-width: 62%; }
  .hero__title { font-size: 28px; }
  /* Ландшафт: кадр и подложка не переопределяются. Коробка здесь широкая
     (844×290), и ей подходит десктопный кадр — тот самый, что действует
     на живом с 19.09.2026: блок редакции стоял без медиазапроса и
     перекрывал эти строки. Телефон, у которого в ландшафте ширина всё же
     ≤768, получит мобильные правила из блока ниже. */
}

/* ГЕРО НА ТЕЛЕФОНЕ. Значения редакции, скриншоты на живом 19.09.2026,
   ширина 390 px. Приехали из «Дополнительных стилей» настройщика (блок
   ks-vremenno-hero-i-mobilnyj-fon) и здесь стоят НИЖЕ всех прочих правил
   первого экрана — ровно там же, где стояли в каскаде до переноса.

   Граница 768, а не 900, как у бургера: её выбрала редакция под кадр
   картинки, а не под раскладку меню. Разные границы у разных вещей —
   обычно ошибка (см. историю поиска в бургере выше), но здесь это два
   независимых решения: в полосе 769–900 меню уже свёрнуто, а кадр ещё
   десктопный, и так же было на живом до переноса. */
@media (max-width: 768px) {
  /* Стрелки разделов на телефоне — в столбик по левому краю: три слота
     в строку дают по 110 px на название, и каждое ломается на три
     строки. */
  .razdel-nav { grid-template-columns: 1fr; }
  .razdel-nav__nazad,
  .razdel-nav__naverh,
  .razdel-nav__vpered { grid-column: 1; justify-self: start; text-align: left; }

  /* ПОЛОСА ВРЕМЕНИ НА ТЕЛЕФОНЕ СКРЫТА. Четырнадцать меток на 350 px —
     это 25 px на метку: подписей не разобрать, а площадки нажатия
     наезжают друг на друга. Оставить её «поменьше» значило бы получить
     горизонтальный пролив, которого на странице быть не должно.
     Навигация при этом не теряется: список дат идёт следом, а ссылка на
     конкретную дату по-прежнему живёт на самой дате. */
  .timeline__polosa { display: none; }

  /* Журнал правок: на узком экране дата встаёт над строкой, а не слева.
     Две колонки при ширине экрана 390 оставили бы описанию около 220 px,
     и каждая запись растянулась бы на пять строк. */
  /* Одна колонка: дата встаёт над описанием. Воздух между записями тот
     же, что на широком экране, — иначе список снова слипается. */
  .timeline__zhurnal-spisok { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .timeline__zhurnal-chto { margin-bottom: var(--space-5); }

  /* Лица смещаются чуть левее, чем на десктопе: коробка у́же, и при 72%
     крайняя фигура уходила за край. */
  .hero__bg { object-position: 70% 50%; }
  /* Подложка вертикальная и заметно легче прежней: та гасила картинку
     на телефоне целиком — иллюстрации было не видно совсем.

     ВЕРХНЯЯ ОСТАНОВКА 0,70, А НЕ 0,86, — правка 19.09.2026 по решению
     владельца. Значение 0,86 выверялось до того, как редакция заменила
     картинку на hero-chetvero-chitatelej-v2.jpg; замер на 390 px показал,
     что на новом снимке оно гасит фигуры в верхней трети целиком —
     проверено тем же экраном с ослабленной подложкой, фигуры в кадре
     были. Остальные две остановки не трогаем: заголовок лежит в верхней
     половине, и читаемость держит именно она. */
  .hero::after {
    background: linear-gradient(
      180deg,
      rgba(20, 18, 16, 0.70) 0%,
      rgba(20, 18, 16, 0.52) 42%,
      rgba(20, 18, 16, 0.22) 100%
    );
  }
}

/* Печать: обложки и навигация не нужны */
@media print {
  .site-header, .site-footer, .cover, .subscribe, .toc { display: none; }
  /* Печать калькулятора — своим блоком в конце раздела калькулятора,
     ниже его экранных правил: отсюда её перебивал бы каскад. */
}

/* ---------- prefers-reduced-motion ----------
   Токены движения tokens.css уже сводятся к 1ms — здесь добиваем то,
   что задано литералами, и убираем раскрытие аккордеона переходом
   (правило спеки: «раскрытие показываем без перехода»). */
@media (prefers-reduced-motion: reduce) {
  .btn:active { transition: none; }
  .faq__a { transition: none; }
  .faq__sign { transition: none; }
  html { scroll-behavior: auto; }
}

/* ---------- Гайд и блок помощи (волна 2.8) ----------
   Скруглений, теней и градиентов в системе нет — акцент даёт красная
   линейка слева, как у остальных выделенных блоков. */
.guide__toc { border-left: var(--border-accent); padding: var(--space-4) var(--space-5); background: var(--color-paper-2); margin: var(--space-6) 0; }
.guide__toc ol { margin: var(--space-3) 0 0; padding-left: var(--space-5); }
.guide__toc li { margin-bottom: var(--space-2); }
.guide__toc summary { cursor: pointer; }
.guide__more { border-left: 2px solid var(--color-line-soft); padding-left: var(--space-4); font: var(--text-small); }
/* Текущий раздел гайда (задание 24.09.2026, п. 2): метку ставит theme.js
   атрибутом aria-current="location". Красное подчёркивание, без фона —
   фон у пункта оглавления читался бы как кнопка. Цвет текста не
   меняется: контраст пункта остаётся прежним. */
.guide__toc a[aria-current="location"] {
  text-decoration: underline;
  text-decoration-color: var(--brand-red);
  text-decoration-thickness: 3px;
  text-underline-offset: 5px;
  font-weight: 600;
}
/* Цель ссылки на оглавление: не уезжать под липкую шапку. */
.guide__toc { scroll-margin-top: calc(var(--header-h) + var(--space-4)); }

/* ---------- Гайд как курс (задание 24.09.2026b, п. 1.1) ----------
   Разметку даёт inc/gid-kurs.php, отметки открывает assets/js/gid-kurs.js.
   Всё, что стоит с hidden, получает display ниже — поэтому у каждого
   такого элемента явное [hidden] { display: none }: правило display
   перебивает браузерное скрытие, и галочка была бы видна без скрипта. */

/* Шапка урока: пиктограмма слева, над заголовком «Урок N из M · K мин».
   h2 внутри — тот же, что был, с тем же id. */
.gid-urok__shapka {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin: var(--space-7) 0 var(--space-4);
}
.gid-urok__shapka h2 {
  margin: 0;
  /* строка «Урок N» стоит НАД заголовком: переход по #якорю не должен
     прятать её под липкую шапку */
  scroll-margin-top: calc(var(--space-7) + 72px + 24px);
}
.gid-urok__ikonka { flex: none; width: 48px; height: 48px; }
.gid-urok__zagolovok { min-width: 0; }
/* #C2372B на бумаге #F0EBDD — 4,55: мелкий текст проходит 4,5 впритык
   (5,42 — это против белого; ревью 24.09b поправило число). */
.gid-urok__metka {
  margin: 0 0 var(--space-2);
  font: var(--text-meta);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--brand-red-text);
}

/* Заставка части — угольная полоса. Не заголовок: новых h2 в гайде
   задание не допускает (см. inc/gid-kurs.php). */
.gid-chast {
  margin: var(--space-8) 0 0;
  padding: var(--space-6) var(--space-5);
  background: var(--color-coal);
  color: var(--color-paper);
  border-top: 4px solid var(--brand-red);
  scroll-margin-top: calc(var(--header-h) + var(--space-4));
}
/* #A9A296 на угле — 7,34 */
.gid-chast__nomer,
.gid-chast__uroki {
  margin: 0;
  font: var(--text-meta);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--color-line-soft);
}
.gid-chast__nazvanie {
  margin: var(--space-2) 0;
  font: 700 40px/1.25 var(--font-display);
  text-transform: uppercase;
  color: var(--color-paper);
}

/* Конец урока: строка, галочка, «Далее». */
.gid-konec {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-5);
  margin: var(--space-6) 0 0;
  padding: var(--space-4) 0 0;
  border-top: 2px solid var(--color-coal);
}
.gid-konec__stroka {
  flex: 1 0 100%;
  margin: 0;
  font: var(--text-meta);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
}
.gid-konec__otmetka {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--tap-target-min);
  cursor: pointer;
  font: var(--text-small);
  font-weight: 600;
}
.gid-konec__otmetka[hidden] { display: none; }
/* Галочка — квадрат без скругления, отметка — чертой, не шрифтом. */
.gid-konec__flazhok {
  appearance: none;
  flex: none;
  display: grid;
  place-content: center;
  width: 24px;
  height: 24px;
  margin: 0;
  border: 2px solid var(--color-coal);
  background: var(--color-paper);
  cursor: pointer;
}
.gid-konec__flazhok::before {
  content: "";
  width: 12px;
  height: 6px;
  border-left: 3px solid var(--color-paper);
  border-bottom: 3px solid var(--color-paper);
  transform: translateY(-2px) rotate(-45deg);
  opacity: 0;
}
.gid-konec__flazhok:checked { background: var(--brand-red-text); border-color: var(--brand-red-text); }
.gid-konec__flazhok:checked::before { opacity: 1; }
.gid-konec__flazhok:focus-visible { outline: 3px solid var(--brand-red); outline-offset: 2px; }
/* Строчный блок, а не flex: у flex стрелка — отдельный элемент, и при
   переносе длинного названия она отрывалась к правому краю. Высота цели
   нажатия 44 px — полями сверху и снизу. */
.gid-konec__dalee {
  display: inline-block;
  padding: 10px 0;
  line-height: 1.35;
  font-weight: 600;
}

/* Оглавление курса: части, номера уроков, галочки, счёт, сброс.

   КОМПАКТНО НА ДЕСКТОПЕ. Липкая колонка ограничена высотой экрана, и
   оглавление курса (части, счёт, сброс) при 1280×800 перестало в неё
   помещаться: 823 px при 696 видимых, урок 10 и «Сбросить прогресс»
   уходили под край — а полоса прокрутки колонки на macOS невидима,
   ровно та беда, что с таблицами (ревью 24.09b). Поэтому пункты 16 px
   с плотным межстрочным, галочка — не столбец сетки, а в поле справа.

   КОНТРАСТ. Ссылки на бумаге оглавления (#E4DCC8) общим #C2372B давали
   3,97 < 4,5 — так было и до курса; тёмный красный #A8121A даёт 5,56. */
.guide__toc .gid-toc__spisok,
.guide__toc .gid-toc__chast > ol { list-style: none; padding-left: 0; }
.guide__toc .gid-toc__spisok a { color: var(--brand-red-text-hover); }
.guide__toc .gid-toc__spisok a:hover { color: var(--color-coal); }
.guide__toc .gid-toc__spisok li { margin-bottom: var(--space-1); }
.gid-toc__progress[hidden],
.gid-toc__sbros[hidden] { display: none; }
.gid-toc__progress {
  margin: var(--space-3) 0 0;
  font: var(--text-meta);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
}
.gid-toc__chast { margin-top: var(--space-4); }
.gid-toc__chast-nazvanie {
  margin: 0 0 var(--space-2);
  font: var(--text-meta);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--color-muted);
}
.gid-toc__spisok a { font-size: 16px; line-height: 1.35; }
.gid-toc__punkt--urok > a {
  position: relative;
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: var(--space-1);
  align-items: baseline;
  padding-right: 20px;
}
.gid-toc__nomer { font: 500 14px/1.35 var(--font-display); color: var(--color-muted); }
/* Текущий урок: подчёркнуто только название, а не номер в соседнем
   столбце сетки (подчёркивание расходилось на оба). */
.gid-toc__punkt--urok > a[aria-current="location"] { text-decoration: none; }
.gid-toc__punkt--urok > a[aria-current="location"] .gid-toc__nazvanie {
  text-decoration: underline;
  text-decoration-color: var(--brand-red);
  text-decoration-thickness: 3px;
  text-underline-offset: 5px;
}
/* Галочка скрыта ВИДИМОСТЬЮ, а не прозрачной рамкой: в режиме высокой
   контрастности браузер красит прозрачную рамку системным цветом, и
   галочки стояли у всех десяти уроков (ревью 24.09b). */
.gid-toc__galochka {
  position: absolute;
  top: 0.45em;
  right: 2px;
  width: 12px;
  height: 6px;
  border-left: 3px solid var(--brand-red-text);
  border-bottom: 3px solid var(--brand-red-text);
  transform: rotate(-45deg);
  visibility: hidden;
}
.gid-toc__punkt.is-projden .gid-toc__galochka { visibility: visible; }
.gid-toc__sbros {
  min-height: var(--tap-target-min);
  margin-top: var(--space-4);
  padding: 0 var(--space-4);
  border: 2px solid var(--color-coal);
  background: transparent;
  color: var(--color-coal);
  font: var(--text-meta);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  cursor: pointer;
}
.gid-toc__sbros:focus-visible { outline: 3px solid var(--brand-red); outline-offset: 2px; }

@media (max-width: 600px) {
  .gid-urok__ikonka { width: 40px; height: 40px; }
  .gid-chast__nazvanie { font-size: 32px; }
}
/* Сенсорный экран: цель нажатия у пунктов оглавления и «Содержания» —
   не меньше 44 px (было 22–30 и 17). На десктопе не трогаем — там
   оглавление обязано помещаться в высоту экрана. */
@media (max-width: 900px) {
  .guide__toc .gid-toc__spisok a { display: block; min-height: var(--tap-target-min); padding-block: 10px; box-sizing: border-box; }
  .guide__toc .gid-toc__punkt--urok > a { display: grid; }
  .guide__toc summary { display: block; min-height: var(--tap-target-min); padding-block: 13px; box-sizing: border-box; }
  .guide__toc .gid-toc__spisok li { margin-bottom: 0; }
}

/* ---------- Врезки: Главное, Осторожно, Оговорка редакции (п. 1.2) ----------
   Стили блока «Группа», разметку метки даёт inc/vrezki.php. Цвета — из
   задания числами, как у плашки РФ выше: #E6DFCC (бумага темнее),
   #6E675F (рамка и метка оговорки, 4,68 на бумаге), #4A453F (текст
   оговорки, 7,96). Контраст всех пар держит tools/test_vrezki.php. */
.wp-block-group.is-style-glavnoe,
.wp-block-group.is-style-ostorozhno,
.wp-block-group.is-style-ogovorka {
  margin: var(--space-6) 0;
  padding: var(--space-5);
}
.wp-block-group.is-style-glavnoe > :last-child,
.wp-block-group.is-style-ostorozhno > :last-child,
.wp-block-group.is-style-ogovorka > :last-child { margin-bottom: 0; }
.vrezka__metka {
  margin: 0 0 var(--space-3);
  font-family: var(--font-display);
  text-transform: uppercase;
  letter-spacing: .06em;
}
.wp-block-group.is-style-glavnoe {
  background: #E6DFCC;
  border-left: 4px solid var(--brand-red);
  color: var(--color-coal);
}
.is-style-glavnoe .vrezka__metka { font-size: 20px; font-weight: 600; line-height: 1.25; color: var(--color-coal); }
/* Ссылка на бумаге темнее: общий #C2372B на #E6DFCC даёт 4,08 < 4,5
   (tools/test_vrezki.php), тёмный красный #A8121A — 5,71. */
.wp-block-group.is-style-glavnoe a { color: var(--brand-red-text-hover); }
.wp-block-group.is-style-glavnoe a:hover { color: var(--color-coal); }
/* Метка «Осторожно» красным на угле: #D7262C даёт 3,74 — это меньше 4,5,
   поэтому кегль 20 px полужирный 700: от 18,66 px полужирного порог 3,0
   (правило проекта по WCAG, задание 24.09b, п. 5). */
.wp-block-group.is-style-ostorozhno { background: var(--color-coal); color: var(--color-paper); }
.is-style-ostorozhno :where(h2, h3, h4, p, li, strong, em, b, a) { color: inherit; }
.is-style-ostorozhno .vrezka__metka { font-size: 20px; font-weight: 700; line-height: 1.25; color: var(--brand-red); }
/* Общее a:hover красит ссылку углём — на угольной плашке это 1,00, ссылка
   пропадала бы под курсором. Здесь наведение — без смены цвета, толще черта. */
.wp-block-group.is-style-ostorozhno a:hover,
.wp-block-group.is-style-ostorozhno a:focus-visible { color: var(--color-paper); text-decoration-thickness: 3px; }
.wp-block-group.is-style-ogovorka { border: 1px solid #6E675F; color: #4A453F; }
.is-style-ogovorka :where(h2, h3, h4, p, li, strong, em, b, a) { color: inherit; }
.is-style-ogovorka .vrezka__metka { font: var(--text-meta); letter-spacing: var(--tracking-meta); color: #6E675F; }

/* ---------- «Подробнее» — блок «Подробности» (п. 1.3) ----------
   Текст внутри остаётся в разметке — его видит поиск и находит Ctrl+F.
   Маркер «+ / −» — вместо треугольника браузера; у content задан
   пустой альтернативный текст, чтобы читалка не произносила «плюс». */
.wp-block-details {
  margin: var(--space-6) 0;
  padding: 0 var(--space-5);
  border: 2px solid var(--color-coal);
}
.wp-block-details > summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--tap-target-min);
  padding: var(--space-3) 0;
  list-style: none;
  cursor: pointer;
  font: 500 20px/1.25 var(--font-display);
}
.wp-block-details > summary::-webkit-details-marker { display: none; }
.wp-block-details > summary::before {
  content: "+";
  content: "+" / "";
  flex: none;
  width: 24px;
  font: 700 24px/1 var(--font-display);
  text-align: center;
  color: var(--brand-red-text);
}
.wp-block-details[open] > summary::before { content: "−"; content: "−" / ""; }
.wp-block-details > summary:focus-visible { outline: 3px solid var(--brand-red); outline-offset: 2px; }
.wp-block-details[open] > summary { margin-bottom: var(--space-3); }
.wp-block-details > :last-child:not(summary) { margin-bottom: var(--space-5); }

/* ---------- Схемы и картинки гайда (п. 1.4) ----------
   Схема (стиль «Схема» у блока «Изображение» или класс skhema) — на всю
   колонку, подпись Golos 16 px, нажатие открывает файл (ссылку ставит
   inc/vrezki.php). Обычная картинка в гайде — так же, без ссылки.
   #5B5751 на бумаге — 6,02. */
figure.is-style-skhema,
figure.skhema,
.guide__main figure.wp-block-image { width: 100%; margin: var(--space-6) 0; }
figure.is-style-skhema img,
figure.skhema img,
.guide__main figure.wp-block-image img { display: block; width: 100%; height: auto; }
figure.is-style-skhema figcaption,
figure.skhema figcaption,
.guide__main figure.wp-block-image figcaption {
  margin: var(--space-2) 0 0;
  font: 400 16px/1.5 var(--font-text);
  color: var(--color-muted);
  text-align: left;
}
.skhema__ssylka { display: block; }
.skhema__ssylka:focus-visible { outline: 3px solid var(--brand-red); outline-offset: 2px; }

.help-block { border: var(--border); border-left: var(--border-accent); padding: var(--space-5); margin: var(--space-7) 0; background: var(--color-paper-2); }
.help-block__title { font: var(--text-h3); margin: 0 0 var(--space-3); }
.help-block__note { font: var(--text-small); color: var(--color-muted); }

/* Липкое оглавление — только на десктопе: на мобильном оно съедает экран,
   поэтому там остаётся раскрывающийся <details>.

   Липнет БОКОВАЯ КОЛОНКА, а не само оглавление. Раньше sticky стоял на
   .guide__toc — элементе во всю ширину потока с непрозрачным фоном, и при
   прокрутке он просто закрывал собой текст. Ширину липкому элементу должна
   задавать колонка сетки; за тем, чтобы это правило не отменили обратно,
   следит tools/check_layout.py. */
@media (min-width: 901px) {
  .guide__layout {
    display: grid;
    grid-template-columns: minmax(0, var(--measure-article)) minmax(220px, 1fr);
    gap: var(--space-8);
    align-items: start;
  }
  .guide__main  { grid-column: 1; grid-row: 1; }
  .guide__aside {
    grid-column: 2; grid-row: 1;
    position: sticky; top: calc(var(--header-h) + var(--space-4));
    /* Длинное оглавление не должно уезжать за экран без прокрутки */
    max-height: calc(100vh - var(--header-h) - var(--space-6));
    overflow-y: auto;
  }
  .guide__aside .guide__toc { margin: 0; }
  /* Полоса прокрутки липкой колонки ВИДИМА: оглавление курса при
     невысоком окне длиннее экрана, а оверлейная полоса macOS прячет
     прокрутку — оглавление выглядело бы просто обрезанным снизу. */
  .guide__aside::-webkit-scrollbar { width: 8px; }
  .guide__aside::-webkit-scrollbar-track { background: var(--color-paper-2); }
  .guide__aside::-webkit-scrollbar-thumb { background: var(--color-coal); }
}
/* 901–1180: колонка оглавления шире, зазор уже — при 1024 названия
   уроков шли по одному-два слова в строке в колонке 220 px. */
@media (min-width: 901px) and (max-width: 1180px) {
  .guide__layout {
    grid-template-columns: minmax(0, var(--measure-article)) minmax(260px, 1fr);
    gap: var(--space-6);
  }
}
@media (max-width: 900px) {
  .site-footer__grid { grid-template-columns: 1fr; }
}

/* --- Баннер согласия на cookie ------------------------------------------
   position: fixed — из потока выключен, вёрстку не сдвигает и CLS не даёт.
   Кнопки равнозначны по размеру и весу: «серая кнопка отказа» рядом
   с яркой кнопкой согласия — это интерфейсное давление, а не выбор.
   Контраст обеих к своему фону проходит AA:
     бумага по красному #C2372B — 5,42:1
     уголь #141210 по бумаге    — 14:1                                    */
.ks-consent {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  background: var(--color-paper);
  border-top: 2px solid var(--color-coal);
}
.ks-consent__inner {
  max-width: var(--container, 1200px);
  margin: 0 auto;
  padding: var(--space-4, 16px) var(--space-5, 24px);
  display: flex;
  gap: var(--space-5, 24px);
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
.ks-consent__text { flex: 1 1 320px; font: var(--text-small); color: var(--color-coal); }
.ks-consent__text p { margin: 0; }
.ks-consent__title {
  font: var(--text-meta);
  text-transform: uppercase;
  letter-spacing: var(--tracking-meta);
  margin-bottom: 4px !important;
}
.ks-consent__actions { display: flex; gap: 12px; flex: 0 0 auto; flex-wrap: wrap; }

/* Одинаковые размеры, вес и типографика — различие только в цвете,
   и красный стоит на действии, а не на «правильном» ответе */
.ks-consent__btn {
  font: var(--text-meta);
  text-transform: uppercase;
  letter-spacing: var(--tracking-meta);
  padding: 12px 20px;
  border: 2px solid var(--color-coal);
  cursor: pointer;
  min-height: 44px;          /* палец, а не курсор */
}
.ks-consent__btn--accept {
  background: var(--brand-red-text);
  border-color: var(--brand-red-text);
  color: var(--color-paper);
}
.ks-consent__btn--accept:hover { background: var(--brand-red-text-hover); border-color: var(--brand-red-text-hover); }
.ks-consent__btn--reject { background: transparent; color: var(--color-coal); }
.ks-consent__btn--reject:hover { background: var(--color-paper-2); }

/* Ссылка «Настройки cookie» в подвале — кнопка, но выглядит ссылкой:
   это способ передумать, а не призыв к действию */
.ks-consent-reopen {
  background: none; border: 0; padding: 0;
  font: inherit; color: inherit;
  text-decoration: underline; cursor: pointer;
}

@media (max-width: 640px) {
  /* На узком экране действия уходят вниз и занимают всю ширину:
     баннер не должен закрывать половину первого экрана */
  .ks-consent__inner { padding: var(--space-4, 16px); gap: 12px; }
  .ks-consent__actions { width: 100%; }
  .ks-consent__btn { flex: 1 1 auto; }
  .ks-consent__text { font-size: 15px; }
}

/* Компактный баннер согласия на телефоне.
   Замер 16.08.2026 на живом сайте: баннер занимал 269 px, это 32% экрана
   390×844. Метрика у нас fail-closed — до ответа счётчик не грузится, —
   значит баннер видит КАЖДЫЙ посетитель из поиска, то есть вся целевая
   аудитория SEO. Треть первого экрана под служебным блоком.

   ЧТО ЗДЕСЬ НЕ МЕНЯЕТСЯ. Ни одного слова текста, ни одной кнопки, ни
   одного атрибута data-consent. Обработчики, порядок кнопок и вызов
   window.ksMetrika остаются прежними: согласие — правовая часть, а не
   вёрстка. Здесь только геометрия.

   Цель ≤120 px этой правкой НЕ достигается: при полном тексте выходит
   около 220 px. Сокращать текст самостоятельно нельзя, поэтому здесь
   сделано всё, что можно сделать без него, а решение по тексту — за
   владельцем. */
@media (max-width: 600px) {
  .ks-consent__inner {
    padding: 12px var(--space-4, 16px);
    gap: 10px;
  }
  /* Заголовок в одну строку с текстом: отдельная строка «ФАЙЛЫ COOKIE»
     стоила 24 px и не несла ничего сверх первой фразы. Слово остаётся
     на месте и по-прежнему служит меткой для aria-labelledby. */
  .ks-consent__title {
    display: inline;
    margin-bottom: 0 !important;
  }
  .ks-consent__title::after { content: " · "; }
  .ks-consent__text { font-size: 14px; line-height: 1.35; }
  .ks-consent__text p { display: inline; }
  /* Кнопки остаются в ряд и не ниже 44 px: цель нажатия сокращать нельзя,
     экономить надо на воздухе, а не на пальце.

     nowrap обязателен именно на узких экранах. На 360 px (старые Android
     и встроенный браузер Telegram) «Только необходимые» не помещалось
     рядом с «Принять», кнопки складывались в столбик, и баннер вырастал
     до 264 px — 41% экрана 360×640. С запретом переноса подпись длинной
     кнопки переносится ВНУТРИ неё: обе остаются в ряд, высота 58 px,
     баннер 226 px. Тридцать восемь пикселей, отыгранных без единого
     слова правки в тексте. */
  .ks-consent__actions { gap: 8px; flex-wrap: nowrap; }
  .ks-consent__btn { padding: 10px 12px; min-width: 0; }

  /* Место под баннер в конце страницы, пока он показан.
     Баннер фиксированный, и низ страницы уходил под него безвозвратно:
     доскроллить до последних 212 px было нельзя — их закрывала плашка.
     Здесь страница просто становится длиннее ровно на это время.

     Отступ ПРИВЯЗАН К КЛАССУ, а не выставляется скриптом, и это главное
     требование: `.is-visible` снимает hide() в тот же момент, что и сам
     баннер, поэтому пустой полосы после ответа не остаётся физически —
     её нечему пережить. Скрипт согласия при этом не тронут ни одной
     строкой: он и раньше ставил и снимал этот класс.

     240 px — с запасом над измеренными 212 (390 px) и 226 (360 px).
     Перебор здесь ничего не стоит: лишние пиксели лежат ПОД баннером,
     который их и закрывает, а после ответа отступ исчезает целиком.
     Поэтому число можно не пересчитывать при правке текста баннера.

     :has() не поддержан в старых браузерах — там останется прежнее
     поведение, то есть низ страницы под баннером. Это ровно то, что
     было до правки, и хуже не становится. */
  body:has(.ks-consent.is-visible) { padding-bottom: 240px; }
}

/* Анимация появления — только там, где её не просили выключить */
@media (prefers-reduced-motion: no-preference) {
  .ks-consent { transform: translateY(100%); transition: transform .2s ease-out; }
  .ks-consent.is-visible { transform: translateY(0); }
}

/* --- Непринятая норма: [300 000 ₽](draft:id) ----------------------------
   Пометка попадает В ТЕКСТ, а не в атрибут: читатель должен видеть её
   без наведения, а поиск и копирование — забирать вместе с цифрой.
   Красный здесь уместен: это предупреждение, а не украшение.          */
.ks-draft {
  border-bottom: 2px dotted var(--brand-red-text);
  white-space: nowrap;
}
.ks-draft__label {
  font: var(--text-meta);
  text-transform: uppercase;
  letter-spacing: var(--tracking-meta);
  color: var(--brand-red-text);
  margin-left: 6px;
  white-space: nowrap;
}
/* На узком экране пометка переносится вместе со значением, а не рвётся */
@media (max-width: 480px) {
  /* Если ссылка перестаёт помещаться рядом с заголовком, она уходит на
     свою строку — но целиком, одной строкой и прижатой вправо. Требование
     задания: перенос допустим, разрыв подписи — нет. */
  .section-head__link { flex: 1 0 100%; text-align: right; }
  .ks-draft { white-space: normal; }
  .ks-draft__label { display: inline-block; margin-left: 4px; }
}

/* ---------- Словарь: поиск и группы ----------
   Единственный источник терминов — inc/data/glossary.json. Содержимое
   страницы шаблон не печатает: на проде из-за этого было два словаря. */
.glossary-search { margin: var(--space-6) 0; }
.glossary-search__label { display: block; font: var(--text-meta); text-transform: uppercase; letter-spacing: var(--tracking-meta); margin-bottom: var(--space-2); }
.glossary-search__input {
  width: 100%; max-width: var(--measure-article);
  padding: var(--space-3) var(--space-4);
  border: var(--border); border-left: var(--border-accent);
  background: var(--color-paper); color: inherit; font: inherit;
}
.glossary-search__input:focus-visible { outline: 2px solid var(--brand-red-text); outline-offset: 2px; }
.glossary-search__count { margin: var(--space-2) 0 0; color: var(--color-muted); }
.glossary-group__title { border-top: var(--border); padding-top: var(--space-5); margin-top: var(--space-6); }
.glossary-empty { margin: var(--space-6) 0; }

/* ---------- Врезка с цифрой ----------
   Значение, норма и дата сверки приходят из реестра при выводе страницы
   (inc/figures.php). Врезка без пригодной записи не рендерится вовсе.
   Анимаций нет намеренно: врезка должна читаться как часть газетной
   полосы, а не как виджет. */
.ks-figure {
  margin: var(--space-7) 0;
  padding: var(--space-5) var(--space-5) var(--space-5) var(--space-5);
  border-left: var(--border-accent);
  background: var(--color-paper-2);
  /* При печати врезка не должна разрываться между страницами */
  break-inside: avoid;
  page-break-inside: avoid;
}
.ks-figure__value {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(32px, 6.5vw, 52px);
  line-height: 0.95;
  letter-spacing: var(--tracking-display);
  color: var(--color-coal);
  /* Цифры одной ширины: иначе «13%» и «15%» в соседних врезках пляшут */
  font-variant-numeric: tabular-nums;
  /* Капса на самой цифре быть не должно: читалки произносят его побуквенно */
  text-transform: none;
}
.ks-figure__caption {
  font: var(--text-small);
  color: var(--color-coal);
  margin-top: var(--space-3);
  max-width: 46ch;
}
.ks-figure__source {
  font: var(--text-small);
  color: var(--color-muted);
  margin: var(--space-3) 0 0;
}
.ks-figure__source a { color: inherit; }
/* Проект нормы: цифра красным и видимая пометка в тексте.
   Красный только на крупном кегле — на мелком его контраст 4,55:1
   не оставляет запаса. */
.ks-figure--draft .ks-figure__value { color: var(--brand-red-text); }
.ks-figure__draft {
  font: var(--text-meta);
  letter-spacing: var(--tracking-meta);
  text-transform: uppercase;
  color: var(--brand-red-text);
  margin: var(--space-2) 0 0;
}
/* Врезка внутри плашки «Что это значит для РФ» не должна ломать плашку */
.ks-rf-block .ks-figure { margin: var(--space-5) 0; }

/* ---------- Ликбез: плитки тем и карточки материалов ----------
   Задание 24.09.2026, п. 1 (решение владельца 20.09): плитка темы →
   раздел с карточками → статья. Темы и их порядок — реестр
   inc/data/likbez.json; здесь только вид.

   Плитки и карточки стоят в .likbez-hab на всю ширину контейнера, а не
   в полосе текста 680 px: четыре плитки в ней вышли бы по 150 px.
   Вся плитка и вся карточка — одна ссылка; цель касания больше 44×44.
   Без скруглений, теней и градиентов: рамка var(--border), как у
   остальных блоков темы. */
.likbez-hab { margin-top: var(--space-7); }
.likbez-plitki__zagolovok { font: var(--text-h2); margin: 0 0 var(--space-5); }
.likbez-plitki__spisok {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4);
}
/* Четыре колонки — с 901 px, где тема перестаёт быть «мобильной». С 601
   было рано: на 601–705 px «Безопасность» не влезала в колонку (ревью
   24.09.2026, замер по ширине слов). */
@media (min-width: 901px) {
  .likbez-plitki__spisok { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
.likbez-plitki__punkt { margin: 0; min-width: 0; }
/* Селектор из двух классов, а не один: плитки стоят и внутри
   .article__body (гайд, «Куда дальше»), где .article__body a подчёркивает
   любую ссылку — замер на стенде 24.09.2026 дал подчёркнутые подписи. */
.likbez-plitki .likbez-plitka {
  display: flex; flex-direction: column; gap: var(--space-2);
  height: 100%; min-height: 44px; box-sizing: border-box;
  padding: var(--space-4);
  border: var(--border); background: var(--color-paper); color: var(--color-coal);
  text-decoration: none;
}
.likbez-plitka:hover { border-color: var(--brand-red); color: var(--color-coal); }
.likbez-plitka:hover .likbez-plitka__nazvanie { text-decoration: underline; text-underline-offset: 3px; }
.likbez-plitka:focus-visible { outline: 3px solid var(--brand-red-text); outline-offset: 2px; }
.likbez-plitka__ikonka { display: block; width: 64px; height: 64px; }
.likbez-plitka__ikonka img { width: 100%; height: 100%; }
/* Нет пиктограммы — не пустое место, а крупный номер Oswald на бумаге. */
.likbez-plitka__ikonka--nomer {
  display: flex; align-items: center; justify-content: center;
  background: var(--color-paper-2);
  font: 700 44px/1 var(--font-display); color: var(--color-coal);
}
.likbez-plitka__nomer { font: var(--text-meta); letter-spacing: var(--tracking-meta); color: var(--brand-red-text); }
.likbez-plitka__nazvanie { font: var(--text-h3); overflow-wrap: break-word; hyphens: auto; }
.likbez-plitka__opisanie { font: var(--text-small); color: var(--color-muted); overflow-wrap: break-word; hyphens: auto; }
.likbez-plitka__chislo { margin-top: auto; padding-top: var(--space-2); color: var(--color-muted); }
/* Компактно — «Куда дальше» в гайде: без описаний и чисел. Пиктограмма
   НАД подписью, а не рядом: в колонке гайда плитка шириной ~155 px, и
   рядом с пиктограммой на подпись оставалось ~80 px — «Безопасность»
   рвалась посреди слова (стенд 24.09.2026). */
.likbez-plitki--kompakt .likbez-plitka { gap: var(--space-2); padding: var(--space-3); }
.likbez-plitki--kompakt .likbez-plitka__ikonka { width: 40px; height: 40px; flex: none; }
.likbez-plitki--kompakt .likbez-plitka__ikonka--nomer { font-size: 28px; }
.likbez-plitki--kompakt .likbez-plitka__nomer { display: none; }
.likbez-plitki--kompakt .likbez-plitka__nazvanie { font: var(--text-small); font-weight: 600; }

/* Разделы тем. Отступ под липкую шапку — как у заголовков текста:
   по якорю из плитки, меню или «где вы находитесь» раздел не должен
   уезжать под шапку. Пустой якорь-синоним (#purchase) — в начале раздела. */
.likbez-level { margin-top: var(--space-8); }
.likbez-level,
.likbez-level__yakor { scroll-margin-top: calc(var(--space-7) + var(--header-h)); }
.likbez-level__yakor { display: block; height: 0; }
.likbez-level__title {
  display: flex; align-items: center; gap: var(--space-3);
  border-top: var(--border); padding-top: var(--space-5); margin: 0;
  font: var(--text-h2);
}
.likbez-level__ikonka { width: 40px; height: 40px; flex: none; }
.likbez-level__num { color: var(--brand-red-text); font: var(--text-h2); }
.likbez-level__lead { color: var(--color-muted); max-width: var(--measure-article); }
.likbez-level__empty { margin: 0; }

.likbez-kartochki {
  list-style: none; margin: var(--space-5) 0 0; padding: 0;
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-5);
}
@media (min-width: 601px) {
  .likbez-kartochki { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 901px) {
  .likbez-kartochki { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
.likbez-kartochki__punkt { margin: 0; min-width: 0; }
.likbez-kartochki .likbez-kartochka {
  display: flex; flex-direction: column; height: 100%; box-sizing: border-box;
  border: var(--border); background: var(--color-paper); color: var(--color-coal);
  text-decoration: none;
}
.likbez-kartochka:hover { border-color: var(--brand-red); color: var(--color-coal); }
.likbez-kartochka:hover .likbez-kartochka__zagolovok { text-decoration: underline; text-underline-offset: 3px; }
.likbez-kartochka:focus-visible { outline: 3px solid var(--brand-red-text); outline-offset: 2px; }
.likbez-kartochka__oblozhka { display: block; border-bottom: var(--border); }
.likbez-kartochka__img { width: 100%; height: auto; aspect-ratio: 1200 / 630; object-fit: cover; }
.likbez-kartochka__tekst { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-4); flex: 1; }
.likbez-kartochka__zagolovok { margin: 0; font: var(--text-h3); overflow-wrap: break-word; hyphens: auto; }
/* Одна строка отрывка: остальное — многоточием, текст целиком в HTML. */
.likbez-kartochka__otryvok {
  font: var(--text-small); color: var(--color-muted);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.likbez-kartochka__meta { margin-top: auto; color: var(--color-muted); }

/* «Лестница ликбеза» на главной снята 24.09.2026 (п. 7); 25.09.2026 по
   дефолту редакции вместо её тридцати ссылок — одна ссылка «Все
   материалы обучения →» на /likbez/, где материалы разложены по темам. */

/* Строка «порядок чтения — на хабе» в архиве рубрики «Ликбез». */
.archive-hab { color: var(--color-muted); max-width: var(--measure-article); }

/* Переходы «предыдущий/дальше» по теме «Обучения» в конце записи.
   До 25.09.2026 здесь же жили лестница «Ступень N из 35» и соседи по
   рубрике — оба блока сняты (задание, п. 2), вместе с правилами номера
   ступени и итога лестницы. Две колонки, чтобы «назад» и «вперёд»
   стояли по краям; при одном соседе оставшаяся ссылка прижимается к
   своему краю. */
.perehod {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  border-top: var(--border);
  padding-top: var(--space-5);
  margin-top: var(--space-7);
}
/* Заголовки — углём и полужирным, как карточки «Читайте также» сразу
   ниже: два соседних блока ссылок на материалы не должны выглядеть
   по-разному. Подпись «Дальше в теме» — красным текстовым оттенком
   бренда: это шаг, ради которого блок стоит; «Предыдущий» остаётся
   приглушённой подписью .meta. У последнего материала темы подпись
   «Последний в теме» — тоже приглушённая: это состояние, а не шаг, и
   красным она выглядела бы призывом (ревью 25.09). Цвета — только
   токены палитры. */
.perehod--tema a { color: var(--color-coal); font-weight: 600; }
.perehod--tema a:hover,
.perehod--tema a:focus-visible { color: var(--brand-red-text); }
.perehod--tema .perehod__vpered:not(.perehod__vsya-tema) .meta { color: var(--brand-red-text); }
.perehod__nazad { grid-column: 1; }
.perehod__vpered { grid-column: 2; text-align: right; }
.perehod a { display: block; text-decoration: none; }
.perehod a:hover { text-decoration: underline; }
.perehod .meta { display: block; margin-bottom: var(--space-2); }
@media (max-width: 900px) {
  .perehod { grid-template-columns: 1fr; }
  .perehod__vpered { grid-column: 1; text-align: left; }
}

/* Блок «где вы находитесь» в записи */
.likbez-path {
  border-left: var(--border-accent);
  background: var(--color-paper-2);
  padding: var(--space-4) var(--space-5);
  margin: var(--space-5) 0 var(--space-6);
}
.likbez-path__title { margin: 0 0 var(--space-3); }
.likbez-path__steps {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4);
}
.likbez-path__step { display: flex; align-items: baseline; gap: var(--space-2); margin: 0; font: var(--text-small); }
.likbez-path__num { font: var(--text-meta); letter-spacing: var(--tracking-meta); color: var(--color-muted); }
/* Текущий шаг — не только цветом: цвет единственным носителем смысла быть не может */
.likbez-path__step--current { font-weight: 600; }
.likbez-path__step--current .likbez-path__num { color: var(--brand-red-text); }
.likbez-path__step--current span[aria-current] { border-bottom: 2px solid var(--brand-red-text); }

/* ---------- Калькулятор НДФЛ ----------
   Числа приходят из реестра норм через data-атрибуты; в CSS и JS
   ни одной ставки нет. */
.calc { border: var(--border); border-left: var(--border-accent); padding: var(--space-5); margin: var(--space-6) 0; }
.calc__privacy { margin: 0 0 var(--space-5); }
.calc__field { margin-bottom: var(--space-5); border: 0; padding: 0; }
.calc__field label, .calc__field legend { display: block; font: var(--text-small); margin-bottom: var(--space-2); }
.calc__hint { color: var(--color-muted); }
.calc__field input[type="text"] {
  width: 100%; max-width: 22rem;
  padding: var(--space-3) var(--space-4);
  border: var(--border); background: var(--color-paper);
  font: var(--text-body); color: inherit;
  font-variant-numeric: tabular-nums;
}
.calc__status label { display: inline-flex; align-items: center; gap: var(--space-2); margin-right: var(--space-5); font: var(--text-body); }
.calc__result {
  font: var(--text-h2); margin: var(--space-5) 0 var(--space-4);
  font-variant-numeric: tabular-nums;
}
/* «Как посчитано» (задание 25.09.2026, п. 6а) — шаги под результатом,
   у каждого норма и дата сверки строкой ниже, тише самого шага. До 25.09
   на этом месте стояли строки .calc__row «подпись — сумма»; их заменил
   список шагов, стили строк удалены вместе с разметкой.
   Разряды в числах — неразрывным пробелом: сумма не рвётся на строки и
   при 375 px. У всего, что стоит с hidden и получает display, — явное
   [hidden] { display: none }: иначе правило display перебьёт скрытие. */
.calc__kak { margin: 0 0 var(--space-4); }
.calc__kak[hidden] { display: none; }
.calc__kak-zagolovok { font: var(--text-h3); margin: 0 0 var(--space-3); }
.calc__shagi { margin: 0; padding-left: var(--space-5); font-variant-numeric: tabular-nums; }
.calc__shag { padding: var(--space-2) 0; border-bottom: 1px solid var(--color-line-soft); }
.calc__shag-norma { display: block; font: var(--text-small); color: var(--color-muted); margin-top: var(--space-1); }
.calc__kopiya { margin: var(--space-4) 0 0; }
.calc__kopirovat[hidden] { display: none; }
.calc__kopiya-status { font: var(--text-small); color: var(--color-muted); }
.calc__kopiya-pole {
  display: block; width: 100%; min-height: 8rem; margin-top: var(--space-3);
  padding: var(--space-3); border: var(--border); background: var(--color-paper);
  font: var(--text-small); color: inherit;
}
.calc__kopiya-pole[hidden] { display: none; }

/* Два разобранных примера (п. 6б) — статический текст под формой, в той
   же разметке шагов, что и «Как посчитано». */
.calc__primery { margin-top: var(--space-7); border-top: var(--border); padding-top: var(--space-5); }
.calc__primer { margin-top: var(--space-5); }
.calc__primer h3 { font: var(--text-h3); margin: 0 0 var(--space-2); }
.calc__primer-itog { margin: var(--space-3) 0 0; font-variant-numeric: tabular-nums; }
.calc__warning { margin: var(--space-6) 0; }
/* Строка об актуальности под формой: служебная, тише результата. */
.calc__aktualnost { margin: var(--space-4) 0 0; color: var(--color-muted); }

.calc__norms { margin-top: var(--space-7); border-top: var(--border); padding-top: var(--space-5); }
.calc__norms-list dt { font: var(--text-small); font-weight: 600; margin-top: var(--space-4); }
.calc__norms-list dd { margin: var(--space-1) 0 0; font: var(--text-small); color: var(--color-muted); }
/* ---------- Полоса прогресса чтения ----------
   Появилась вместе с гайдом на 25 минут чтения: в коротком материале
   она бессмысленна, в длинном — единственный способ понять, сколько
   осталось, не листая до конца.

   Поверх шапки (z-index выше 50): шапка липкая, и полоса под ней была бы
   не видна там, где на неё смотрят — у верхнего края экрана. */
.reading-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 60;
  /* Фона у дорожки нет: незаполненная часть должна быть незаметна,
     иначе полоса читается как элемент интерфейса, а не как индикатор */
  background: transparent;
  pointer-events: none;
}
.reading-progress__bar {
  height: 100%;
  width: 0;
  background: var(--brand-red-text);
  /* Ширину двигает скрипт на каждом кадре прокрутки — переход здесь
     дал бы отставание от пальца, а не плавность */
  transition: none;
}

/* Движение отключено — полосы нет вовсе.
   Она сообщает информацию исключительно движением: статичная полоса
   прогресса это просто красная черта под шапкой. */
@media (prefers-reduced-motion: reduce) {
  .reading-progress { display: none; }
}

/* --- Часы МСК/UTC в подвале ---------------------------------------------
   Цифры моноширинные и с табличными пропорциями: без этого строка дёргается
   на каждой смене минуты, потому что «1» уже «8». Секунд нет намеренно. */
.site-clock {
  font: var(--text-meta);
  text-transform: uppercase;
  letter-spacing: var(--tracking-meta);
  /* Цвет задаёт ВАРИАНТ, а не базовый класс: подвал тёмный, геро — на бумаге,
     и один набор цветов на оба не годится. Первая версия часов красила цифры
     в уголь и на тёмном подвале была чёрным по чёрному. */
  color: inherit;
  margin: var(--space-3, 12px) 0 0;
  display: flex;
  align-items: baseline;
  gap: var(--space-2, 8px);
  flex-wrap: wrap;
}
.site-clock__time {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0;
}

/* Подвал: тёмный фон */
.site-clock--footer { color: var(--color-line-soft); }
.site-clock--footer .site-clock__time { color: var(--color-paper); }
.site-clock--footer .site-clock__sep { color: var(--color-muted); }

/* Геро: бумага. Строка-надзаголовок над H1 — мелкая и приглушённая,
   чтобы не спорить ни с заголовком, ни с кнопкой «Читать новости». */
.site-clock--hero {
  color: var(--color-muted);
  margin: 0 0 var(--space-3, 12px);
  font-size: 12px;
}
.site-clock--hero .site-clock__time { color: var(--color-coal); }
.site-clock--hero .site-clock__sep { color: var(--color-line-soft); }

/* Мигающее двоеточие. Мигает ОПАЦИТИ, а не видимостью и не содержимым:
   любой из двух других способов на моноширинных цифрах даёт скачок ширины,
   и строка дёргается раз в секунду.

   Отключение при prefers-reduced-motion обязательно и не является
   украшением: мигание в поле зрения мешает читать, а у части читателей
   вызывает и худшее. Мы медиа для чтения — цена анимации выше её пользы
   ровно там, где читатель об этом попросил. */
@keyframes ks-clock-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: .2; }
}

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

   Поэтому у геро своя амплитуда, а не своя анимация: период, кривая и
   отключение при prefers-reduced-motion остаются общими. */
@keyframes ks-clock-blink-deep {
  0%, 100% { opacity: 1; }
  50%      { opacity: .06; }
}
.site-clock__colon { animation: ks-clock-blink 1s ease-in-out infinite; }
.site-clock--hero .site-clock__colon { animation-name: ks-clock-blink-deep; }

@media (prefers-reduced-motion: reduce) {
  .site-clock__colon { animation: none; opacity: 1; }
}

/* --- Монетка-пасхалка ---------------------------------------------------
   Стоит в строке копирайта и намеренно ничем себя не объявляет: у пасхалки
   не должно быть подписи, иначе это пункт меню. */
.fun-egg {
  text-decoration: none;
  /* В покое монетка приглушена и обесцвечена — она не должна спорить с
     копирайтом. Но и невидимой быть не должна: о пасхалке, которую нельзя
     заметить, никто не узнает. Поэтому наведение красит её в красный
     фирменный круг — жест «здесь что-то есть» без единого слова подписи. */
  opacity: .5;
  filter: grayscale(1);
  margin-left: var(--space-2, 8px);
  /* Цель нажатия на телефоне — не меньше минимальной, но за счёт padding,
     а не размера шрифта: строка копирайта не должна разъезжаться */
  display: inline-block;
  padding: 6px;
  line-height: 1;
  border-radius: 50%;
  /* Зона нажатия доводится до минимальной (--tap-target-min) псевдоэлементом,
     а не размером самой монетки: 44 пикселя в строке копирайта раздвинули бы
     межстрочный интервал. На проверке 320px реальная зона была 27px. */
  position: relative;
  transition:
    opacity var(--motion-fast) ease,
    filter var(--motion-fast) ease,
    background-color var(--motion-fast) ease,
    transform var(--motion-fast) ease;
}
.fun-egg::after {
  content: '';
  position: absolute;
  inset: 50%;
  width: var(--tap-target-min);
  height: var(--tap-target-min);
  transform: translate(-50%, -50%);
}
.fun-egg:hover,
.fun-egg:focus-visible {
  opacity: 1;
  filter: none;
  background: var(--brand-red-text);
  transform: rotate(-12deg) scale(1.15);
}

/* Монетка в строке часов геро. Мельче подвальной и с меньшим внутренним
   отступом — чтобы её высота не превысила высоту строки: строка часов
   стоит над заголовком, и лишние пиксели здесь уезжают вниз ко всему
   блоку, а запас до сгиба на коротких экранах уже израсходован.
   Зона нажатия при этом остаётся полной: её задаёт ::after, который
   на поток не влияет. */
.site-clock--hero .fun-egg {
  font-size: 11px;
  padding: 2px;
  margin-left: var(--space-3, 12px);
}

/* --- Врезка «Калькулятор» ----------------------------------------------- */
.calc-card {
  border: 2px solid var(--color-coal);
  padding: var(--space-5);
  margin: var(--space-6) 0;
  max-width: var(--measure-article);
}
.calc-card__label {
  font: var(--text-meta);
  text-transform: uppercase;
  letter-spacing: var(--tracking-meta);
  color: var(--color-muted);
  margin: 0 0 var(--space-2);
}
.calc-card__title { font: var(--text-h3); text-transform: uppercase; margin: 0 0 var(--space-2); }
.calc-card__text { font: var(--text-small); color: var(--color-muted); margin: 0 0 var(--space-4); }

/* --- «Читать дальше» под калькулятором ---------------------------------- */
.calc-next {
  border-top: 1px solid var(--color-line-soft);
  padding-top: var(--space-4);
  margin: var(--space-6) 0 0;
  max-width: var(--measure-article);
}
.calc-next__label {
  font: var(--text-meta);
  text-transform: uppercase;
  letter-spacing: var(--tracking-meta);
  color: var(--color-muted);
  margin: 0 0 var(--space-2);
}
.calc-next ul { margin: 0; padding-left: var(--space-4); }
.calc-next li { font: var(--text-small); color: var(--color-muted); margin: 0 0 var(--space-2); }
.calc-next li a { color: var(--color-coal); }

/* Печать калькулятора (задание 25.09.2026, п. 6в): на бумагу идут поля с
   введёнными суммами, результат, «Как посчитано» с нормами, примеры и
   нормы. Кнопка, её сообщение, поле копии и «Читать дальше» на бумаге
   ничего не делают. Цвета — углём по белому: приглушённый серый нормы и
   красная линейка на лазерном принтере бледнеют до нечитаемого. Шаг и
   пример не рвутся между страницами.

   БЛОК СТОИТ НИЖЕ ВСЕХ ЭКРАННЫХ ПРАВИЛ КАЛЬКУЛЯТОРА — И ДОЛЖЕН ТАМ
   ОСТАВАТЬСЯ. Селекторы здесь те же, что на экране, а при равной
   специфичности побеждает правило, стоящее в файле ниже. До ревью
   25.09.2026 эти правила жили в общем @media print выше по файлу, и на
   бумаге оставались красная линейка .calc, экранный фон полей и серые
   нормы; срабатывали только display: none. Порядок держит проверка в
   tools/test_calc_kak_poschitano.php. */
@media print {
  .calc__kopiya, .calc__kopiya-pole, .calc-next { display: none; }
  .calc { border: 1px solid var(--color-coal); }
  .calc__field input[type="text"] { border: 1px solid var(--color-coal); background: none; }
  .calc__shag-norma, .calc__aktualnost, .calc__scale, .calc__norms-list dd { color: var(--color-coal); }
  .calc__shag, .calc__primer { break-inside: avoid; }
}

/* ---------- Курс криптовалют ---------- */
.kurs {
  border: var(--border); border-top: var(--border-accent);
  padding: var(--space-6); margin-bottom: var(--space-6);
}
.kurs__shapka {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); margin-bottom: var(--space-4);
}
.kurs__shapka .meta { margin: 0; }
.kurs__tumbler { display: inline-flex; border: var(--border); }
/* Кнопки ₽/$ — цель нажатия не меньше 44×44 (--tap-target-min), как у
   кнопки поиска (Z10). До 24.09.2026 размер задавали кегль и padding:
   около 36×28 px в колонке сайдбара, ниже канона; нашло ревью задания
   БД-4. Зону нажатия здесь не доводят псевдоэлементом, как у пасхалки
   в часах: две кнопки стоят вплотную, и растянутые зоны легли бы одна
   на другую — палец попадал бы не в ту валюту. Поэтому растёт сама
   кнопка. */
.kurs__knopka {
  font: inherit; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: var(--tap-target-min); min-height: var(--tap-target-min);
  padding: 0 .6em; border: 0; background: transparent; color: var(--color-muted);
}
.kurs__knopka + .kurs__knopka { border-left: var(--border); }
.kurs__knopka.is-on { background: var(--color-coal); color: var(--color-paper); }
.kurs__spisok { list-style: none; margin: 0; padding: 0; }
.kurs__stroka {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-3); padding: .35em 0;
}
.kurs__stroka + .kurs__stroka { border-top: 1px solid var(--color-line-soft); }
/* Курс доллара — не цена актива, поэтому отделён, а не в общем ряду */
.kurs__stroka--valuta { margin-top: .35em; border-top: var(--border); }
.kurs__tiker { font-family: var(--font-display); letter-spacing: .02em; }
.kurs__cena { font-variant-numeric: tabular-nums; white-space: nowrap; }
.kurs__podpis {
  margin: var(--space-4) 0 0; font-size: var(--text-small); color: var(--color-muted);
}
.kurs--polnyj { max-width: 34rem; }
/* Пояснение под виджетом курса. Своего оформления не просит: заголовки и
   абзацы наследуют типографику тела статьи, здесь только отступ сверху —
   иначе первый заголовок липнет к последней строке таблицы. */
.kurs-poyasnenie { margin-top: 2rem; }
.kurs-poyasnenie h2:first-child { margin-top: 0; }

/* ========== Главная: сетка из секций разного типа ==========
   Сетка БЕ-7 (задание 24.09.2026, п. 7), переделанная по решениям
   владельца 25.09.2026 (задание 25.09, п. 4); разметка — front-page.php,
   выбор записей и карточки — inc/glavnaya.php. Правила hero (.hero*) —
   выше по файлу и КАК НА main: плакат не трогается.

   ПАЛИТРА НОВЫХ ЭЛЕМЕНТОВ — #D7262C, #141210, #F0EBDD и их прозрачности
   (токены --color-coal-70, --color-coal-25, --color-paper-72), без золота
   и без промежуточных серых. Исключений два, оба — служебный красный
   #C2372B (--brand-red-text), потому что канонный #D7262C на бумаге даёт
   4,20 при пороге 4,5 для мелкого текста (правило tokens.css от
   14.08.2026), а #C2372B — 4,55:
   — рубрика капсом 13 px в «Главном» и карточках — здесь, в разделе;
   — общие компоненты темы, которые раздел не перекрашивает: кнопка .btn
     («Читать», «Открыть календарь», «Подписаться в Telegram»; заливка
     #C2372B, при наведении #A8121A — та же кнопка, что в hero) и ссылки
     «Все новости →», «Все материалы обучения →», «прошлые выпуски →».
   Крупные заголовки (от 18,66 px полужирным) при наведении — канонным
   #D7262C: для крупного текста порог 3,0. Перенесённые виджеты (отсчёт,
   курс) — в своих цветах, как в сайдбаре.

   ШРИФТЫ — решение владельца 25.09: Oswald — только заголовки секций и
   hero. Заголовки карточек — Golos 700 обычным font-weight (@font-face
   объявляет Golos по оси файла, 400 900, раздел «Шрифты» в начале файла);
   служебные строки новых блоков — рубрика и время, метки «Дайджест по средам» —
   тоже Golos, 600 капсом, а не общий --text-meta (он Oswald). Кнопка .btn
   остаётся общим компонентом сайта — той же, что в hero.

   СЕТКА — ДВЕНАДЦАТЬ КОЛОНОК, а не доли 8fr/4fr: доли делят ширину за
   вычетом одного зазора, и край рельса уезжал на 8 px от края третьей
   карточки «Трёх» (ревью 25.09.2026). В двенадцати колонках с зазором
   --grid-gutter края 8/12, 4/12, третей и половин совпадают.
   Без скруглений, теней и градиентов; рамки 2 px, как у карточек сайта. */

/* --- Плашка «Скоро вступает в силу»: тонкая рамочная строка --- */
.skoro { padding-block: var(--space-5) 0; }
.skoro__stroka {
  margin: 0; padding: var(--space-2) var(--space-4);
  border: var(--border); border-left: 6px solid var(--brand-red);
  font: 400 16px/1.5 var(--font-text); color: var(--color-coal);
}
.skoro__ssylka { color: var(--color-coal); }
.skoro__ssylka time { font-weight: 700; }
.skoro__ssylka:hover,
.skoro__ssylka:focus-visible,
.skoro__razbor:hover,
.skoro__razbor:focus-visible { color: var(--color-coal); text-decoration: underline; }
.skoro__razbor { color: var(--color-coal); white-space: nowrap; text-decoration: underline; }

/* Плашка-хаб — только если задана в настройках; поля — блоком, чтобы не
   обнулить боковое поле .container (tools/test_kontejnery.php). */
.glavnaya-hab { padding-block: var(--space-5) 0; }

/* --- Верхний блок: «Главное» на всю ширину (задание 25.09b, п. 2) --- */
.verh { padding-block: var(--space-7); }
.verh__setka {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--grid-gutter); align-items: start;
}
.verh__setka > .glavnoe { grid-column: 1 / -1; }
/* С обложкой — картинка на весь блок, 21:9, кроп по центру (CSS, новых
   файлов нет); текст — на бумажной плашке в левом нижнем углу, до 45 %
   ширины. Плашка #F0EBDD НЕПРОЗРАЧНАЯ (задание: не меньше 0,92): при 0,95
   сквозь неё проступал впечатанный текст старых обложек (стенд 25.09b,
   запись 505), а красная рубрика #C2372B на бумаге, подмешанной к чёрной
   картинке, давала 4,09 при пороге 4,5. Сплошная бумага держит 4,55 и
   15,7 на любой картинке.
   sizes картинки — cryptosreda_glavnaya_oblozhka (inc/glavnaya.php):
   поменяли ширину блока или окно — пересчитайте там. Высота блока — высота
   картинки: 1184 × 9/21 = 507 px при 1280, 928 × 9/21 = 398 px при 1024. */
.glavnoe { position: relative; min-width: 0; }
.glavnoe__kartinka { aspect-ratio: 21 / 9; overflow: hidden; background: var(--color-coal); }
.glavnoe__kartinka .glavnoe__img {
  display: block; width: 100%; height: 100%; max-width: none;
  object-fit: cover; object-position: 50% 50%;
}
.glavnoe--s-kartinkoj .glavnoe__telo {
  position: absolute; left: 0; bottom: 0; max-width: 45%;
  padding: 28px; background: var(--color-paper);
}
/* Без обложки — тот же текст на бумажном фоне в рамке. */
.glavnoe--tekst .glavnoe__telo { border: var(--border); padding: var(--space-6); }
.glavnoe__meta,
.kartochka__meta {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-3);
  margin: 0 0 var(--space-3);
  font: 600 13px/1.4 var(--font-text); letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-coal-70);
}
.glavnoe__rubrika,
.kartochka__rubrika { position: relative; color: var(--brand-red-text); }
/* Цель нажатия рубрики — 44 px в высоту без роста строки: зону задаёт
   ::after, на поток он не влияет (тот же приём, что у монетки в часах). */
.glavnoe__rubrika::after,
.kartochka__rubrika::after { content: ""; position: absolute; inset: -14px -6px; }
.glavnoe__rubrika:hover,
.kartochka__rubrika:hover { color: var(--color-coal); text-decoration: underline; }
/* h2/h3 наследуют font: var(--text-h2|h3) — это Oswald; заголовок
   карточки набран Golos 700. */
.glavnoe__zagolovok,
.kartochka__zagolovok,
.lenta__zagolovok,
.po-sredam__zagolovok { font-family: var(--font-text); font-weight: 700; letter-spacing: normal; text-transform: none; }
.glavnoe__zagolovok { font-size: 36px; line-height: 1.2; margin: 0 0 var(--space-3); }
/* Не больше трёх строк: длиннее — многоточие; весь заголовок — ссылка. */
.glavnoe__zagolovok a {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3;
  overflow: hidden;
}
.glavnoe__zagolovok a,
.kartochka__zagolovok a,
.lenta__zagolovok a,
.po-sredam__zagolovok a { color: var(--color-coal); }
.glavnoe__zagolovok a:hover,
.kartochka__zagolovok a:hover,
.lenta__zagolovok a:hover,
.po-sredam__zagolovok a:hover { color: var(--brand-red); }
.glavnoe__lid {
  font: 400 17px/1.5 var(--font-text); color: var(--color-coal-70);
  margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.glavnoe__telo > :last-child { margin-bottom: 0; }

/* --- Строка курса под «Дайджест по средам» (задание 25.09b, п. 3) ---
   Одна строка при 1280 и 1024: цены через «·», переключатель ₽/$, подпись
   мелко. Высота ≤ 56 px: её задаёт кнопка переключателя (44 px — цель
   нажатия, --tap-target-min) + рамка 2 с двух сторон = 48, плюс воздух
   строки (стенд 25.09b: 56 при поле 2 px — впритык, поле снято). При
   1024 цены 15 px и зазоры уже — иначе подпись уходила второй строкой
   (стенд: 74 px). На телефоне цены сеткой 2 × 2 без «·» (точка в начале
   второй строки читалась как мусор), переключатель справа, подпись —
   отдельной строкой. */
.glavnaya-kurs { padding-block: var(--space-5) 0; }
.kurs.kurs--stroka {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--space-4);
  margin: 0; padding: 0 var(--space-2) 0 var(--space-4);
  border: var(--border);
}
.kurs--stroka .kurs__spisok {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 .5em;
  font: 600 16px/1.5 var(--font-text); color: var(--color-coal);
}
.kurs--stroka .kurs__stroka { display: inline-flex; gap: .35em; padding: 0; border: 0; margin: 0; }
.kurs--stroka .kurs__stroka + .kurs__stroka::before { content: "·"; color: var(--color-coal-70); font-weight: 400; margin-right: .15em; }
.kurs--stroka .kurs__tiker { font-family: var(--font-text); letter-spacing: normal; }
.kurs--stroka .kurs__cena { font-weight: 400; }
.kurs--stroka .kurs__podpis { margin: 0 0 0 auto; font: 400 13px/1.4 var(--font-text); color: var(--color-coal-70); }
@media (max-width: 1130px) {
  .kurs.kurs--stroka { gap: 0 var(--space-3); padding-left: var(--space-3); }
  .kurs--stroka .kurs__spisok { font-size: 15px; gap: 0 .4em; }
}
@media (max-width: 600px) {
  .kurs.kurs--stroka {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
    gap: var(--space-1) var(--space-3); padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
  }
  .kurs--stroka .kurs__spisok { display: grid; grid-template-columns: repeat(2, max-content); gap: 0 var(--space-4); }
  .kurs--stroka .kurs__stroka + .kurs__stroka::before { content: none; }
  .kurs--stroka .kurs__podpis { grid-column: 1 / -1; margin: 0; }
}

/* --- «Новости» лентой 1 : 1: только текст --- */
.lenta { padding-block: 0 var(--space-7); }
.lenta .section-head,
.sreda .section-head,
.obuchenie .section-head { border-top: var(--border); padding-top: var(--space-4); }
.lenta__setka {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--grid-gutter);
}
.lenta__krupno { padding-right: var(--grid-gutter); border-right: var(--border); }
.lenta__spisok {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-5) var(--grid-gutter); align-content: start;
}
.lenta__punkt { margin: 0; padding-top: var(--space-3); border-top: 1px solid var(--color-coal-25); }
.lenta__punkt:nth-child(-n + 2) { padding-top: 0; border-top: 0; }
.lenta__zagolovok { font-size: 19px; line-height: 1.35; margin: 0 0 var(--space-2); }
.lenta__zagolovok--krupno { font-size: 32px; line-height: 1.25; margin-bottom: var(--space-4); }
.lenta__lid { font: 400 18px/1.55 var(--font-text); color: var(--color-coal-70); margin: 0 0 var(--space-3); }
.lenta__vremya { font: 400 14px/1.4 var(--font-text); color: var(--color-coal-70); margin: 0; }

/* --- Ряды «Три» и «Два»: кадр сверху, текст под ним ---
   Кадр — первый ребёнок карточки (inc/kadr.php), форма по месту: у «Трёх»
   3:2 на всех ширинах (одна пропорция у всех карточек ряда — задание
   30.09.2026, п. 3), у «Двух» 4:5, на телефоне 4:3. Ширины для sizes —
   cryptosreda_glavnaya_shiriny. */
.ryad { padding-block: 0 var(--space-7); }
.ryad__setka {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--grid-gutter); align-items: stretch;
}
.ryad--dva .ryad__setka { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kartochka {
  display: flex; flex-direction: column; min-width: 0;
  border: var(--border); background: var(--color-paper);
  transition: border-color var(--motion-base) var(--ease-out);
}
.kartochka:hover { border-color: var(--brand-red); }
.kartochka__telo {
  flex: 1; padding: var(--space-4);
  /* Без hyphens: auto — перенос с дефисом в заголовке («обязатель-ный»)
     читается хуже, чем рваный край. */
  overflow-wrap: break-word;
}
.kartochka__zagolovok { font-size: 20px; line-height: 1.3; margin: 0 0 var(--space-3); }
.ryad--dva .kartochka__zagolovok { font-size: 24px; line-height: 1.25; }
.kartochka__lid { font: 400 16px/1.5 var(--font-text); color: var(--color-coal-70); margin: 0; }
.ryad--dva .kartochka__lid { font-size: 17px; }
/* «Три» (задание 30.09.2026, п. 3): лид — не больше трёх строк с многоточием
   (заголовок с 01.10.2026 — до четырёх, правило ниже). Лид обрезан и на сервере
   (CRYPTOSREDA_GLAVNAYA_LID_TRI знаков), но в узкой карточке при 1024
   эти знаки занимали пять строк и растягивали ряд по самой говорливой
   карточке (замер живой главной 30.09). Текст остаётся в разметке целиком:
   обрезает только показ. Префикс -webkit- нужен Safari и старым Chrome,
   line-clamp без префикса — остальным. */
.ryad--tri .kartochka__zagolovok a,
.ryad--tri .kartochka__lid {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3;
  overflow: hidden;
}
/* Заголовок «Трёх» — до четырёх строк, а не трёх (решение владельца
   01.10.2026): номера законов («282-ФЗ») в конце заголовка не должны
   обрезаться. Лид остаётся в три строки. Правило позже общего — побеждает
   то же по весу. */
.ryad--tri .kartochka__zagolovok a {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; line-clamp: 4;
  overflow: hidden;
}
/* Тёмная карточка — акцент ряда. Красного мелким текстом на угле нет:
   #D7262C даёт 3,74 при пороге 4,5, поэтому рубрика здесь кремовая. */
.kartochka--temnaya { background: var(--color-coal); border-color: var(--color-coal); color: var(--color-paper); }
.kartochka--temnaya .kartochka__zagolovok a,
.kartochka--temnaya .kartochka__rubrika { color: var(--color-paper); }
.kartochka--temnaya .kartochka__lid,
.kartochka--temnaya .kartochka__meta { color: var(--color-paper-72); }
.kartochka--temnaya .kartochka__zagolovok a:hover { color: var(--color-paper); text-decoration: underline; }

/* --- Календарь законов: большой блок на всю ширину ---
   Фон — уголь во всю ширину окна, как у hero; красный — полоса сверху и
   метки у дат (нетекстовые элементы: #D7262C на угле 3,74 при пороге 3).
   Текст — бумага и её 72 %: 15,69 и 8,44. */
.kalendar-promo {
  margin-block: 0 var(--space-7);
  background: var(--color-coal); color: var(--color-paper);
  border-top: 6px solid var(--brand-red);
}
.kalendar-promo__setka {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-6) var(--grid-gutter); align-items: start;
  padding-block: var(--space-8);
}
.kalendar-promo__tekst { grid-column: span 5; }
.kalendar-promo__spisok { grid-column: span 7; }
.kalendar-promo__zagolovok { font: 600 40px/1.25 var(--font-display); color: var(--color-paper); margin: 0 0 var(--space-4); }
.kalendar-promo__opisanie { font: 400 18px/1.55 var(--font-text); color: var(--color-paper-72); margin: 0 0 var(--space-5); }
.kalendar-promo__knopka { margin: 0; }
.kalendar-promo__spisok { list-style: none; margin: 0; padding: 0; }
.kalendar-promo__punkt {
  display: grid; grid-template-columns: minmax(0, 11em) minmax(0, 1fr) auto;
  gap: var(--space-2) var(--space-4); align-items: baseline;
  padding: var(--space-4) 0 var(--space-4) var(--space-4);
  border-left: 4px solid var(--brand-red);
}
.kalendar-promo__punkt + .kalendar-promo__punkt { margin-top: var(--space-3); }
.kalendar-promo__data { font: 700 20px/1.3 var(--font-text); color: var(--color-paper); }
.kalendar-promo__data:hover,
.kalendar-promo__data:focus-visible { color: var(--color-paper); text-decoration: underline; }
.kalendar-promo__nazvanie { font: 400 17px/1.45 var(--font-text); }
.kalendar-promo__ostalos {
  font: 400 15px/1.45 var(--font-text); color: var(--color-paper-72);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

/* --- «Дайджест по средам»: дайджест и отдельно следующий выпуск ---
   Название с 30.09.2026 — решение владельца (было «По средам»); классы
   .sreda и .po-sredam не менялись. Сразу после hero (задание 25.09b,
   п. 1): отступ сверху свой, снизу — у следующего блока (плашка, верхний
   блок). */
.sreda { padding-block: var(--space-7) 0; }
.sreda__setka {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--grid-gutter); align-items: stretch;
}
.sreda__setka > .po-sredam { grid-column: span 8; }
.sreda__setka > .sreda-vypusk { grid-column: span 4; }
/* Рамочный текстовый блок: красная рамка 2 px (#D7262C — нетекстовый
   элемент, 4,20 на бумаге при пороге 3). */
.po-sredam { border: 2px solid var(--brand-red); padding: var(--space-6); }
.po-sredam__metka,
.sreda-vypusk__metka {
  font: 600 13px/1.4 var(--font-text); letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-coal-70); margin: 0 0 var(--space-3);
}
.po-sredam__zagolovok { font-size: 28px; line-height: 1.25; margin: 0 0 var(--space-3); }
.po-sredam__data,
.po-sredam__status { font: 400 16px/1.5 var(--font-text); margin: 0 0 var(--space-2); }
.po-sredam__data { color: var(--color-coal-70); }
.po-sredam__status { font-weight: 700; }
.po-sredam__opisanie { font: var(--text-small); color: var(--color-coal-70); margin: var(--space-4) 0; }
.po-sredam__arhiv { margin: 0; }
.sreda-vypusk {
  display: flex; flex-direction: column;
  border: var(--border); padding: var(--space-6);
}
.sreda-vypusk__data { font: 700 28px/1.25 var(--font-text); margin: 0 0 var(--space-2); }
.sreda-vypusk__data::first-letter { text-transform: uppercase; }
.sreda-vypusk__schetchik { font: 400 16px/1.5 var(--font-text); color: var(--color-coal-70); margin: 0 0 var(--space-5); }
.sreda-vypusk__knopka { margin: auto 0 0; }

/* --- «Обучение»: плитки реестра и одна ссылка на /likbez/ --- */
.obuchenie { padding-block: 0 var(--space-7); }
/* Зазор между плитками — как у сетки главной: четыре плитки встают ровно
   по три колонки из двенадцати, под карточками рядов. */
.obuchenie .likbez-plitki__spisok { column-gap: var(--grid-gutter); }

/* --- Планшет и телефон --- */
@media (max-width: 1130px) {
  .glavnoe__zagolovok { font-size: 28px; }
  .glavnoe--s-kartinkoj .glavnoe__telo { padding: 24px; }
  .lenta__zagolovok--krupno { font-size: 28px; }
  .kartochka__zagolovok { font-size: 19px; }
  .ryad--dva .kartochka__zagolovok { font-size: 22px; }
  .kalendar-promo__punkt { grid-template-columns: minmax(0, 1fr) auto; }
  .kalendar-promo__nazvanie { grid-column: 1 / -1; grid-row: 2; }
}
@media (max-width: 900px) {
  .glavnoe__zagolovok { font-size: 26px; }
  /* «Лента» — список: крупная новость сверху, остальные строками. */
  .lenta__setka { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  .lenta__krupno { padding: 0 0 var(--space-4); border-right: 0; border-bottom: var(--border); }
  .lenta__spisok { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
  .lenta__punkt:nth-child(2) { padding-top: var(--space-3); border-top: 1px solid var(--color-coal-25); }
  .lenta__punkt:first-child { padding-top: 0; border-top: 0; }
  .kalendar-promo__setka { padding-block: var(--space-7); }
  .kalendar-promo__tekst,
  .kalendar-promo__spisok,
  .sreda__setka > .po-sredam,
  .sreda__setka > .sreda-vypusk { grid-column: 1 / -1; }
}
/* 601–760 px (телефон лёжа, маленький планшет): три колонки дают карточку
   171–200 px, и длинное слово заголовка Golos 700 рвётся посреди слова —
   «Налогообложе|ние» (ревью 25.09.2026, замер при 601 и 640). Одна
   колонка с кадром 4:5 во всю ширину — картинка выше экрана, поэтому
   карточка ложится: кадр слева, 40 % её ширины, текст справа. «Два» в две
   колонки здесь помещаются (карточка от 268 px). */
@media (min-width: 601px) and (max-width: 760px) {
  .ryad--tri .ryad__setka { grid-template-columns: minmax(0, 1fr); }
  .ryad--tri .kartochka { flex-direction: row; }
  .ryad--tri .kartochka > .kadr { flex: 0 0 40%; align-self: flex-start; }
}
@media (max-width: 600px) {
  /* 375: картинка 4:3, плашка уходит под неё — текст обычным потоком. */
  .verh { padding-block: var(--space-6); }
  .glavnoe__kartinka { aspect-ratio: 4 / 3; }
  .glavnoe--s-kartinkoj .glavnoe__telo { position: static; max-width: none; padding: var(--space-4) 0 0; background: none; }
  .glavnoe--tekst .glavnoe__telo { padding: var(--space-5); }
  .glavnoe__zagolovok { font-size: 24px; }
  .glavnoe__lid { font-size: 16px; }
  .lenta__zagolovok--krupno { font-size: 24px; }
  .ryad__setka,
  .ryad--dva .ryad__setka { grid-template-columns: minmax(0, 1fr); }
  .kartochka__zagolovok,
  .ryad--dva .kartochka__zagolovok { font-size: 19px; }
  .ryad--dva .kartochka__lid { font-size: 16px; }
  .kalendar-promo__zagolovok { font-size: 30px; }
  .kalendar-promo__punkt { grid-template-columns: minmax(0, 1fr); }
  .kalendar-promo__nazvanie { grid-row: auto; }
  .kalendar-promo__ostalos { white-space: normal; }
  .po-sredam,
  .sreda-vypusk { padding: var(--space-5); }
  .po-sredam__zagolovok,
  .sreda-vypusk__data { font-size: 24px; }
}
