/* --opposition — ДОБАВЛЕН ПО РЕШЕНИЮ АВТОРА МАКЕТА 2026-08-05.
 * Причина: на карте связей шесть категорий редакционной позиции, а смысловых
 * цветов в макете было пять — «Нейтральные» и «Оппозиционные» сливались.
 *
 * #7C3AED задан автором. Остальные три значения ВЫВЕДЕНЫ по правилу, которое уже
 * действует в макете: средняя светлота канала подгоняется под семейство.
 *   светлый wash  -> средняя 235.0 (как у bad/warn/ok/accent/none)
 *   тёмная база   -> средняя 155.2
 *   тёмный wash   -> средняя  35.5
 * Производные помечены как таковые: их можно менять, не спрашивая заново про #7C3AED.
 */

/* Дизайн-система отчёта — перенесена ДОСЛОВНО из утверждённого макета.
 * Источник: report-mockup.html (артефакт, утверждён пользователем 2026-08-05).
 *
 * Правило: значения здесь не меняются без отдельного одобрения. Если нужного
 * компонента нет — его не выдумывают, а запрашивают у автора макета.
 *
 * Загружается в base.html ПОСЛЕ Tailwind, чтобы перебивать его утилиты там,
 * где они конфликтуют (фон, цвет текста, радиусы, шрифты заголовков).
 */
:root {
    --paper:#F7F8FA; --paper-2:#FFFFFF; --paper-3:#EDEFF4;
    --ink:#1A1F2B; --ink-soft:#3D4557; --neutral:#5B6474; --neutral-2:#8B94A4;
    --rule:#D9DDE6; --accent:#1F5F6B; --accent-2:#2C7E8D; --accent-wash:#E4EEF0;
    --ok:#2E7D5B; --ok-wash:#E3F0EA; --warn:#B07A1E; --warn-wash:#F6EEDC;
    --bad:#A6392F; --bad-wash:#F6E4E1; --none:#6B7280; --none-wash:#ECEEF1;
    --opposition:#7C3AED; --opposition-wash:#E8DDFC;
    --display: Georgia, "Times New Roman", "PT Serif", serif;
    --body: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
    --mono: ui-monospace, "SF Mono", Consolas, "Liberation Mono", monospace;
    --measure: 66ch; --radius: 3px;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --paper:#131720; --paper-2:#1A202C; --paper-3:#232B39;
      --ink:#E8EBF1; --ink-soft:#C2C9D6; --neutral:#949DAE; --neutral-2:#6D7688;
      --rule:#2E3644; --accent:#6FB6C4; --accent-2:#8FCEDA; --accent-wash:#1C2E33;
      --ok:#6BBF95; --ok-wash:#172A22; --warn:#D9AB55; --warn-wash:#2C2417;
      --bad:#E0796C; --bad-wash:#2E1C19; --none:#98A1AF; --none-wash:#232935;
    --opposition:#9A66F2; --opposition-wash:#200F3C;
    }
  }
  :root[data-theme="dark"] {
    --paper:#131720; --paper-2:#1A202C; --paper-3:#232B39;
    --ink:#E8EBF1; --ink-soft:#C2C9D6; --neutral:#949DAE; --neutral-2:#6D7688;
    --rule:#2E3644; --accent:#6FB6C4; --accent-2:#8FCEDA; --accent-wash:#1C2E33;
    --ok:#6BBF95; --ok-wash:#172A22; --warn:#D9AB55; --warn-wash:#2C2417;
    --bad:#E0796C; --bad-wash:#2E1C19; --none:#98A1AF; --none-wash:#232935;
    /* Производные от --opposition: тот же тёмный вариант, что в блоке
       @media (prefers-color-scheme: dark). Здесь их не было, поэтому при ручном
       переключении темы фиолетовый оставался светлым.
       Замер scripts/theme_check.py 2026-09-04: прежний #8E54EF на своём фоне
       давал контраст 3,90 — ниже порога WCAG 4,5 для текста. #9A66F2 даёт 4,65
       при наименьшем сдвиге по светлоте. Значение ПРОИЗВОДНОЕ (см. шапку файла),
       авторский #7C3AED светлой темы не тронут. */
    --opposition:#9A66F2; --opposition-wash:#200F3C;
  }
  :root[data-theme="light"] {
    --paper:#F7F8FA; --paper-2:#FFFFFF; --paper-3:#EDEFF4;
    --ink:#1A1F2B; --ink-soft:#3D4557; --neutral:#5B6474; --neutral-2:#8B94A4;
    --rule:#D9DDE6; --accent:#1F5F6B; --accent-2:#2C7E8D; --accent-wash:#E4EEF0;
    --ok:#2E7D5B; --ok-wash:#E3F0EA; --warn:#B07A1E; --warn-wash:#F6EEDC;
    --bad:#A6392F; --bad-wash:#F6E4E1; --none:#6B7280; --none-wash:#ECEEF1;
    /* Симметрично тёмному блоку: без этих строк переключение в светлую тему
       на системно-тёмной машине оставляло фиолетовый тёмным. */
    --opposition:#7C3AED; --opposition-wash:#E8DDFC;
  }

  * { box-sizing: border-box; }
  body {
    background: var(--paper); color: var(--ink); font-family: var(--body);
    font-size: 16px; line-height: 1.6; margin: 0; -webkit-font-smoothing: antialiased;
  }
  .wrap {
    max-width: 1180px; margin: 0 auto; padding: 2.5rem 1.25rem 5rem;
    display: grid; grid-template-columns: minmax(0,1fr) 340px; gap: 2.5rem; align-items: start;
  }
  @media (max-width: 940px) { .wrap { grid-template-columns: minmax(0,1fr); } }
  main { min-width: 0; display: flex; flex-direction: column; gap: 2.75rem; }

  .eyebrow { font-family: var(--mono); font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--neutral); }
  .masthead { display: flex; flex-direction: column; gap: .85rem; }
  h1 {
    font-family: var(--display); font-weight: 600; font-size: clamp(1.5rem,3.4vw,2.1rem);
    line-height: 1.22; letter-spacing: -.01em; margin: 0; text-wrap: balance; max-width: 30ch;
  }
  .meta {
    display: flex; flex-wrap: wrap; gap: .4rem 1.15rem; font-family: var(--mono);
    font-size: .74rem; color: var(--neutral); font-variant-numeric: tabular-nums;
    border-top: 1px solid var(--rule); padding-top: .8rem;
  }
  .meta b { color: var(--ink-soft); font-weight: 600; }

  h2 { font-family: var(--display); font-size: 1.22rem; font-weight: 600; margin: 0 0 .2rem; display: flex; align-items: baseline; gap: .6rem; }
  h2 .n { font-family: var(--mono); font-size: .7rem; color: var(--accent); letter-spacing: .1em; border: 1px solid var(--rule); padding: .1rem .38rem; border-radius: var(--radius); flex: none; }
  .lede { color: var(--ink-soft); max-width: var(--measure); margin: .35rem 0 1.1rem; }
  /* Рубрика уточнений без тезисов. Не прочерк и не ошибка: материал собран, а
     проверяемых утверждений из него не вышло. Цвет предупреждения, а не
     «плохо» — это ограничение разбора, и читатель должен увидеть его сразу. */
  .aspect-empty { color: var(--warn); font-family: var(--mono); font-size: .78rem; }

  .ledger { border: 1px solid var(--rule); border-radius: var(--radius); overflow: hidden; background: var(--paper-2); }
  .ledger-scroll { overflow-x: auto; }
  table { border-collapse: collapse; width: 100%; font-size: .875rem; }
  thead th {
    text-align: left; font-family: var(--mono); font-weight: 500; font-size: .66rem;
    letter-spacing: .12em; text-transform: uppercase; color: var(--neutral);
    padding: .7rem .85rem; background: var(--paper-3); border-bottom: 1px solid var(--rule); white-space: nowrap;
  }
  tbody td { padding: .8rem .85rem; border-bottom: 1px solid var(--rule); vertical-align: top; }
  tbody tr:last-child td { border-bottom: 0; }
  tbody tr:hover { background: var(--paper-3); }
  td.idx { font-family: var(--mono); color: var(--neutral); width: 2.4rem; font-variant-numeric: tabular-nums; }
  td.claim { min-width: 22rem; }
  td.claim a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--rule); }
  td.claim a:hover, td.claim a:focus-visible { border-bottom-color: var(--accent); color: var(--accent); }
  td.ev { font-family: var(--mono); font-size: .78rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
  td.ev .s { color: var(--ok); } td.ev .c { color: var(--bad); } td.ev .sep { color: var(--neutral-2); }
  .jump { font-family: var(--mono); font-size: .72rem; color: var(--accent); text-decoration: none; white-space: nowrap; border: 1px solid transparent; padding: .12rem .3rem; border-radius: var(--radius); }
  .jump:hover, .jump:focus-visible { background: var(--accent-wash); border-color: var(--accent); }

  .verdict {
    display: inline-flex; align-items: center; gap: .34rem; font-family: var(--mono);
    font-size: .7rem; letter-spacing: .04em; padding: .16rem .44rem; border-radius: var(--radius);
    white-space: nowrap; border: 1px solid transparent;
  }
  .verdict::before { content: ""; width: .42rem; height: .42rem; border-radius: 50%; background: currentColor; flex: none; }
  .v-ok { color: var(--ok); background: var(--ok-wash); border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
  .v-bad { color: var(--bad); background: var(--bad-wash); border-color: color-mix(in srgb, var(--bad) 30%, transparent); }
  .v-warn { color: var(--warn); background: var(--warn-wash); border-color: color-mix(in srgb, var(--warn) 30%, transparent); }
  .v-none { color: var(--none); background: var(--none-wash); border-color: color-mix(in srgb, var(--none) 30%, transparent); }

  .scale {
    font-family: var(--mono); font-size: .72rem; font-weight: 600; padding: .1rem .34rem;
    border-radius: var(--radius); background: var(--accent-wash); color: var(--accent);
    border: 1px solid color-mix(in srgb, var(--accent) 28%, transparent);
    cursor: help; position: relative; text-decoration: none;
  }
  .scale:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  /* Подсказка живёт не внутри триггера, а одним фиксированным элементом на body:
     любой контейнер с overflow (досье, скролл графа, таблицы) обрезал бы absolute-всплывашку.
     Здесь .tip — только хранилище текста, наружу его показывает #tt. */
  .scale .tip { display: none; }
  #tt {
    position: fixed; z-index: 9999; max-width: 20rem;
    background: var(--ink); color: var(--paper);
    font-family: var(--body); font-size: .78rem; line-height: 1.45; text-align: left;
    padding: .55rem .7rem; border-radius: var(--radius);
    box-shadow: 0 8px 28px rgba(0,0,0,.3); pointer-events: none;
    opacity: 0; visibility: hidden; transition: opacity .12s ease;
  }
  #tt.on { opacity: 1; visibility: visible; }
  #tt b { display: block; font-family: var(--mono); font-size: .7rem; letter-spacing: .06em; margin-bottom: .22rem; opacity: .75; }
  @media (prefers-reduced-motion: reduce) { #tt { transition: none; } }

  .conclusion { border-left: 2px solid var(--accent); padding-left: 1.15rem; max-width: var(--measure); }
  .conclusion p { margin: 0 0 .9rem; } .conclusion p:last-child { margin-bottom: 0; }
  .ref {
    font-family: var(--mono); font-size: .72rem; color: var(--accent); text-decoration: none;
    background: var(--accent-wash); padding: .05rem .3rem; border-radius: var(--radius);
    border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  }
  .ref:hover, .ref:focus-visible { background: var(--accent); color: var(--paper-2); }
  /* Номер факта после тезиса без подписи читался как случайная цифра в конце
     предложения. Подпись «см. факт» превращает его в ссылку на разбор. */
  .ref-note { white-space: nowrap; margin-left: .4rem; }
  .ref-label { font-family: var(--mono); font-size: .68rem; color: var(--neutral); margin-right: .28rem; }
  .ref + .ref { margin-left: .22rem; }

  .thesis { border: 1px solid var(--rule); border-radius: var(--radius); background: var(--paper-2); scroll-margin-top: 1rem; }
  .thesis > header {
    display: flex; flex-wrap: wrap; gap: .55rem .9rem; align-items: center;
    padding: .75rem .95rem; border-bottom: 1px solid var(--rule); background: var(--paper-3);
  }
  .thesis > header .tag { font-family: var(--mono); font-size: .7rem; color: var(--neutral); letter-spacing: .1em; }
  .thesis-body { padding: 1rem .95rem 1.1rem; display: flex; flex-direction: column; gap: 1.1rem; }
  .claim-text { font-size: 1rem; line-height: 1.55; margin: 0; max-width: var(--measure); }

  /* ── Доказательства с цитатами ── */
  .side { display: flex; flex-direction: column; gap: .5rem; }
  .side-head {
    font-family: var(--mono); font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
    display: flex; align-items: center; gap: .45rem;
  }
  .side-head.sup { color: var(--ok); } .side-head.con { color: var(--bad); }
  /* alpha8: «контекст» — цитаты, которые не подтверждают и не оспаривают.
     Приглушены намеренно: они не участвуют в счётчиках, и выделять их наравне
     со сторонами значило бы снова показывать спор там, где его нет. */
  .side-head.ctx { color: var(--neutral); }
  .side-head::after { content: ""; flex: 1; height: 1px; background: var(--rule); }

  .quote {
    display: grid; grid-template-columns: 3px minmax(0,1fr); gap: .7rem;
    background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius);
    overflow: hidden;
  }
  .quote .bar { background: var(--neutral-2); }
  .quote.sup .bar { background: var(--ok); }
  .quote.con .bar { background: var(--bad); }
  .quote.empty .bar { background: var(--warn); }
  .quote.ctx .bar { background: var(--neutral-2); }

  /* alpha8: отброшенные доказательства — свёрнутым блоком.
     Раньше на каждой неподтверждённой цитате стояло ⚠ с текстом «источник
     засчитан не был»; в сохранённом DOM таких плашек было видно 39 при 8
     настоящих. Повтор предупреждения даёт баннерную слепоту, поэтому здесь одна
     строка-итог, а подробности — по раскрытию. */
  .dropped { margin-top: .35rem; }
  .dropped > summary {
    cursor: pointer; font-family: var(--mono); font-size: .66rem;
    letter-spacing: .1em; text-transform: uppercase; color: var(--neutral);
  }
  .dropped > summary:hover { color: var(--ink); }
  .dropped .quote { margin-top: .5rem; }
  .trust-note.warn { color: var(--warn); }
  /* Пометка о старом формате — приглушённее аварийной плашки: это оговорка о
     происхождении данных, а не сбой расследования. */
  /* Пробел доказательной базы — оговорка о материале, не сбой сервиса:
     тоньше аварийной плашки, но заметнее обычной подписи. */
  .gap-note {
    display: flex; gap: .45rem; align-items: baseline;
    font-size: .82rem; line-height: 1.45; color: var(--warn);
    border-left: 2px solid var(--warn); padding: .1rem 0 .1rem .55rem;
    max-width: var(--measure);
  }

  .alarm.soft { border-color: var(--rule); color: var(--neutral); background: var(--paper); }
  .quote-in { padding: .6rem .75rem .65rem 0; display: flex; flex-direction: column; gap: .45rem; }
  .quote blockquote {
    margin: 0; font-size: .875rem; line-height: 1.55; color: var(--ink);
    font-family: var(--display); max-width: 62ch;
  }
  .quote .attrib { display: flex; flex-wrap: wrap; gap: .45rem; align-items: center; font-size: .78rem; }
  .src-btn {
    display: inline-flex; align-items: center; gap: .38rem; font-size: .78rem;
    padding: .16rem .45rem; border: 1px solid var(--rule); border-radius: var(--radius);
    background: var(--paper-2); color: var(--ink-soft); cursor: pointer; font-family: var(--body);
  }
  .src-btn:hover, .src-btn[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); background: var(--accent-wash); }
  .src-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
  .src-btn .dom { font-family: var(--mono); font-size: .72rem; }
  .src-btn .sc { font-family: var(--mono); font-size: .64rem; opacity: .75; }
  .orig { font-family: var(--mono); font-size: .72rem; color: var(--neutral); text-decoration: none; border-bottom: 1px solid var(--rule); }
  .orig:hover, .orig:focus-visible { color: var(--accent); border-bottom-color: var(--accent); }
  .trust-note { font-family: var(--mono); font-size: .68rem; color: var(--neutral); }
  .empty-note { font-size: .84rem; color: var(--warn); display: flex; gap: .45rem; align-items: baseline; }
  .empty-note b { color: var(--ink); font-weight: 600; }

  .debate { border-top: 1px dashed var(--rule); padding-top: .95rem; display: flex; flex-direction: column; gap: .85rem; }
  .turn { display: grid; grid-template-columns: 7.2rem minmax(0,1fr); gap: .6rem; }
  @media (max-width: 620px) { .turn { grid-template-columns: 1fr; } }
  .turn .who { font-family: var(--mono); font-size: .66rem; letter-spacing: .1em; text-transform: uppercase; color: var(--neutral); padding-top: .15rem; }
  .turn .said { margin: 0 0 .4rem; font-size: .9rem; color: var(--ink-soft); max-width: var(--measure); }
  .turn.judge .who { color: var(--accent); }
  .turn.judge .said { color: var(--ink); }
  .cite {
    font-size: .8rem; color: var(--neutral); display: flex; flex-wrap: wrap; gap: .4rem; align-items: baseline;
    border-left: 2px solid var(--rule); padding-left: .6rem; max-width: var(--measure);
  }
  .cite em { font-family: var(--display); font-style: italic; color: var(--ink-soft); }

  /* ── Карта связей ── */
  .matrix-scroll { overflow-x: auto; border: 1px solid var(--rule); border-radius: var(--radius); background: var(--paper-2); }
  table.matrix { font-size: .8rem; }
  table.matrix th.rot { padding: .55rem .35rem; text-align: center; vertical-align: bottom; }
  table.matrix th.rot span { writing-mode: vertical-rl; transform: rotate(180deg); font-family: var(--mono); font-size: .68rem; letter-spacing: .04em; text-transform: none; white-space: nowrap; }
  table.matrix td { text-align: center; padding: .4rem .35rem; }
  table.matrix td.rowhead { text-align: left; font-family: var(--mono); font-size: .72rem; white-space: nowrap; color: var(--ink-soft); }
  table.matrix td.rowhead a { color: inherit; text-decoration: none; border-bottom: 1px solid var(--rule); }
  table.matrix td.rowhead a:hover { color: var(--accent); border-bottom-color: var(--accent); }
  .dot { display: inline-block; width: .72rem; height: .72rem; border-radius: 50%; }
  .dot.sup { background: var(--ok); }
  .dot.con { background: var(--bad); }
  .dot.hollow { background: transparent; border: 1.5px solid var(--warn); }
  .mx-legend { display: flex; flex-wrap: wrap; gap: .5rem 1.1rem; font-size: .8rem; color: var(--neutral); margin-top: .7rem; align-items: center; }
  .mx-legend span { display: inline-flex; align-items: center; gap: .35rem; }

  /* ── Граф связей ── */
  .graph-shell { border: 1px solid var(--rule); border-radius: var(--radius); background: var(--paper-2); overflow-x: auto; }
  .graph-shell svg { display: block; min-width: 760px; width: 100%; height: auto; }
  .g-lane { font-family: var(--mono); font-size: 9px; letter-spacing: .14em; text-transform: uppercase; fill: var(--neutral-2); }
  .g-node { cursor: pointer; }
  .g-node rect, .g-node circle { transition: opacity .12s ease; }
  .g-label { font-family: var(--body); font-size: 11px; fill: var(--ink); pointer-events: none; }
  .g-sub { font-family: var(--mono); font-size: 9px; fill: var(--neutral); pointer-events: none; }
  .g-edge { fill: none; transition: opacity .12s ease, stroke-width .12s ease; }
  .dim { opacity: .12; }
  @media (prefers-reduced-motion: reduce) { .g-node rect, .g-node circle, .g-edge { transition: none; } }
  .g-legend { display: flex; flex-wrap: wrap; gap: .5rem 1.15rem; font-size: .8rem; color: var(--neutral); margin-top: .75rem; align-items: center; }
  .g-legend span { display: inline-flex; align-items: center; gap: .38rem; }
  .swatch { width: 1.1rem; height: 0; border-top-width: 2px; border-top-style: solid; display: inline-block; }
  .alarm {
    border: 1px solid color-mix(in srgb, var(--bad) 45%, var(--rule)); background: var(--bad-wash);
    border-radius: var(--radius); padding: .8rem .9rem; margin-top: .9rem;
    font-size: .87rem; color: var(--ink-soft); max-width: var(--measure);
  }
  .alarm b { color: var(--bad); }

  /* ── Рельса ── */
  aside { position: sticky; top: 1.5rem; }
  @media (max-width: 940px) { aside { position: static; } }
  .card { border: 1px solid var(--rule); border-radius: var(--radius); background: var(--paper-2); overflow: hidden; }
  .card > header {
    padding: .7rem .85rem; border-bottom: 1px solid var(--rule); background: var(--paper-3);
    font-family: var(--mono); font-size: .66rem; letter-spacing: .12em; text-transform: uppercase;
    color: var(--neutral); display: flex; justify-content: space-between; gap: .5rem; align-items: center;
  }
  .card-body { padding: .9rem .85rem 1rem; display: flex; flex-direction: column; gap: .8rem; font-size: .875rem; }
  .src-name { font-family: var(--display); font-size: 1.05rem; margin: 0; line-height: 1.3; }
  .src-dom { font-family: var(--mono); font-size: .74rem; color: var(--neutral); word-break: break-all; }
  .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: .55rem .8rem; }
  .kv { display: flex; flex-direction: column; gap: .12rem; }
  .kv dt { font-family: var(--mono); font-size: .62rem; letter-spacing: .1em; text-transform: uppercase; color: var(--neutral-2); }
  .kv dd { margin: 0; font-size: .84rem; }
  .why { background: var(--paper); border: 1px solid var(--rule); border-radius: var(--radius); padding: .6rem .7rem; font-size: .84rem; color: var(--ink-soft); }
  .why strong { display: block; font-family: var(--mono); font-size: .62rem; letter-spacing: .1em; text-transform: uppercase; color: var(--neutral-2); margin-bottom: .3rem; font-weight: 500; }
  /* Провенанс утверждения о владельце. Метка обязана быть ВИДНА, а не жить в
     подсказке: без неё «ООО Ромашка» из поиска и «ООО Ромашка» из реестра
     выглядят в отчёте одинаково, хотя это утверждения разной силы. */
  .prov { font-family: var(--mono); font-size: .58rem; letter-spacing: .08em;
          text-transform: uppercase; padding: .08rem .3rem; border-radius: 3px;
          border: 1px solid var(--rule); white-space: nowrap; vertical-align: middle; }
  .prov-heur { color: var(--neutral-2); background: transparent; }
  .prov-reg { color: var(--accent-2); border-color: currentColor; }  /* было var(--good, #2C7E8D): токена --good в системе нет, поэтому
     всегда работал запасной литерал и на тёмной теме оставался светлым. */

  /* Выписка из реестра — отдельный блок, а не строка в «Владелец». */
  .reg { border: 1px solid var(--rule); border-radius: var(--radius);
         padding: .6rem .7rem; font-size: .84rem; }
  .reg-backed { background: var(--paper); }
  .reg-none { color: var(--neutral); font-size: .8rem; background: transparent;
              border-style: dashed; }
  /* «Не сверялось» отличается от «не подтвердил» и на вид: первое — отсутствие
     проверки, второе — её результат. Одинаковый вид склеивал бы их обратно. */
  .reg-unknown { color: var(--neutral-2); font-size: .8rem; background: transparent;
                 border-style: dotted; }
  .reg-h { font-family: var(--mono); font-size: .62rem; letter-spacing: .1em;
           text-transform: uppercase; color: var(--neutral-2); margin-bottom: .4rem;
           display: flex; gap: .4rem; align-items: center; }
  .metric { padding: .35rem 0; border-bottom: 1px solid var(--rule); }
  .metric:last-of-type { border-bottom: none; }
  .metric-t { display: flex; justify-content: space-between; gap: .8rem; font-size: .84rem; }
  .metric-v { font-weight: 500; text-align: right; }
  /* Отсутствие данных отличается на вид от значения: «недостаточно данных» —
     это не измерение, и выглядеть как измерение оно не должно. */
  .metric-absent { color: var(--neutral-2); font-weight: 400; font-style: italic; }
  .metric-h { font-size: .74rem; color: var(--neutral); margin-top: .12rem; }

  .reg-note { margin-top: .45rem; color: var(--ink-soft); font-size: .8rem; }
  .reg-attr { margin-top: .45rem; color: var(--neutral); font-size: .74rem; }

  ul.flags { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
  ul.flags li { font-size: .82rem; display: flex; gap: .45rem; align-items: flex-start; }
  ul.flags li::before { content: "▪"; color: var(--warn); flex: none; }
  ul.flags li.unverified::before { content: "?"; color: var(--neutral-2); font-family: var(--mono); }
  ul.flags li.coi::before { content: "▪"; color: var(--bad); }
  ul.flags li .note { color: var(--neutral); font-size: .78rem; }
  .btn-open {
    display: inline-flex; align-items: center; gap: .4rem; align-self: flex-start;
    font-family: var(--mono); font-size: .74rem; color: var(--paper-2); background: var(--accent);
    padding: .34rem .6rem; border-radius: var(--radius); text-decoration: none; border: 1px solid var(--accent);
  }
  .btn-open:hover, .btn-open:focus-visible { background: var(--accent-2); border-color: var(--accent-2); }
  .backlinks { display: flex; flex-wrap: wrap; gap: .3rem; }

  .note-box {
    border: 1px dashed color-mix(in srgb, var(--warn) 45%, var(--rule)); background: var(--warn-wash);
    border-radius: var(--radius); padding: .85rem .95rem; font-size: .86rem; color: var(--ink-soft); max-width: var(--measure);
  }
  .note-box b { color: var(--ink); }
  footer.foot {
    grid-column: 1 / -1; border-top: 1px solid var(--rule); padding-top: 1rem;
    font-family: var(--mono); font-size: .7rem; color: var(--neutral-2);
    display: flex; flex-wrap: wrap; gap: .4rem 1.2rem;
  }
  a { color: var(--accent); }

  /* ═══════════════════════════════════════════════════════════════════════════
     ВЫВЕДЕННЫЕ КОМПОНЕНТЫ

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

     Правило для этого блока: ни одного нового цвета, радиуса или семейства
     шрифтов. Используются только существующие переменные и уже утверждённые
     приёмы (рамка --rule, фон --paper-2, фокус --accent — как у .src-btn
     и .btn-open). Размеры выведены из соседних компонентов.
     ═══════════════════════════════════════════════════════════════════════════ */

  /* ── Одноколоночная сетка ──
     .wrap задан в две колонки под рельсу досье. У истории, методологии,
     прогресса и уточнения рельсы нет, и правая колонка на 340px оставалась бы
     пустой. Правило дословно совпадает с адаптивом .wrap под 940px. */
  .wrap.solo { grid-template-columns: minmax(0, 1fr); }

  /* ── Подзаголовок третьего уровня ──
     Выведен из h2: то же семейство --display и тот же вес, кегль на ступень
     меньше (1.22rem у h2 → 1.02rem), без рамки-номера .n. */
  h3 {
    font-family: var(--display); font-size: 1.02rem; font-weight: 600;
    margin: 1.4rem 0 .3rem; line-height: 1.3; color: var(--ink);
  }

  /* ── Восстановление типографики заголовков ──
     Значения ниже НЕ новые: они дословно повторяют правила h1/h2 из верхней части
     файла и h3 из этого блока. Повтор нужен только ради специфичности.
     Причина: Tailwind CDN собирает стили в браузере и вставляет их инлайновым
     <style> в конец head, уже после mockup.css. Его preflight объявляет
     `h1,h2,h3,h4,h5,h6 { font-size: inherit; font-weight: inherit }` с той же
     специфичностью (0,0,1), поэтому побеждал по порядку следования — заголовки на
     всех страницах, включая утверждённый отчёт, рисовались размером основного
     текста. Селектор `body h1` даёт (0,0,2) и возвращает значения макета.
     Отключить preflight через corePlugins нельзя: к моменту присваивания
     tailwind.config ресет уже впрыснут (проверено 2026-08-05).
     Если Tailwind уберут из base.html — этот блок можно удалить целиком. */
  body h1 { font-size: clamp(1.5rem, 3.4vw, 2.1rem); font-weight: 600; }
  body h2 { font-size: 1.22rem; font-weight: 600; }
  body h3 { font-size: 1.02rem; font-weight: 600; }

  /* ── Прозаические списки ──
     ul.flags в макете — служебный список флагов КИ со своими маркерами.
     Здесь обычный текстовый список: те же ширина строки --measure и цвет
     --ink-soft, что у .lede и .conclusion p.
     list-style задан явно: preflight от Tailwind объявляет
     `ol, ul, menu { list-style: none; margin: 0; padding: 0 }`, и без своего
     значения маркеры пропадали. */
  .prose-list { margin: .3rem 0 1rem; padding-left: 1.15rem; max-width: var(--measure); color: var(--ink-soft); list-style: disc; }
  ol.prose-list { list-style: decimal; }
  .prose-list li { margin: .22rem 0; }

  /* ── Поля ввода ──
     Рамка, фон, радиус и поведение фокуса — как у .src-btn: 1px var(--rule),
     фон var(--paper-2), радиус var(--radius), при фокусе рамка и обводка
     var(--accent). Кегль 0.9rem — между базовым 1rem и 0.875rem у .card-body. */
  .field { display: flex; flex-direction: column; gap: .35rem; }
  .field > label {
    font-family: var(--mono); font-size: .66rem; letter-spacing: .1em;
    text-transform: uppercase; color: var(--neutral);
  }
  .field .hint { font-size: .78rem; color: var(--neutral); max-width: var(--measure); }
  .input, textarea.input, select.input {
    font-family: var(--body); font-size: .9rem; line-height: 1.5; color: var(--ink);
    background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--radius);
    padding: .55rem .7rem; width: 100%; appearance: none;
    /* Та же мера строки, что у прозы (.lede, .claim-text, .conclusion): поле на всю
       ширину колонки в 1140px выбивалось из ритма страницы — текст вопроса кончался
       на 66 символах, а поле под ним тянулось ещё на пол-экрана. */
    max-width: var(--measure);
  }
  textarea.input { resize: vertical; min-height: 6.5rem; }
  .input::placeholder { color: var(--neutral-2); }
  .input:hover { border-color: color-mix(in srgb, var(--accent) 40%, var(--rule)); }
  .input:focus-visible, .input:focus {
    outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent);
  }
  .input:disabled { background: var(--paper-3); color: var(--neutral-2); cursor: not-allowed; }

  /* ── Кнопки ──
     .btn-open в макете — маленькая ссылка-кнопка на 0.74rem для рельсы досье;
     для главного действия страницы она мелка. Здесь тот же приём (фон --accent,
     текст --paper-2, наведение --accent-2), но кегль основного текста и шрифт
     --body, потому что это подпись действия, а не служебная метка.
     .btn-quiet — вторичное действие: та же геометрия, рамка вместо заливки. */
  .btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
    font-family: var(--body); font-size: .9rem; line-height: 1.2;
    padding: .6rem 1.1rem; border-radius: var(--radius); cursor: pointer;
    text-decoration: none; border: 1px solid var(--accent);
    background: var(--accent); color: var(--paper-2);
  }
  .btn:hover:not(:disabled) { background: var(--accent-2); border-color: var(--accent-2); }
  .btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
  .btn:disabled { background: var(--paper-3); border-color: var(--rule); color: var(--neutral-2); cursor: not-allowed; }
  .btn-quiet {
    background: var(--paper-2); color: var(--ink-soft); border-color: var(--rule);
  }
  .btn-quiet:hover:not(:disabled) { background: var(--accent-wash); border-color: var(--accent); color: var(--accent); }

  /* ── Группа взаимоисключающих вариантов (глубина расследования) ──
     Выведена из .src-btn с его же состоянием aria-pressed/[aria-expanded]:
     выбранный вариант получает акцентную рамку и подложку --accent-wash. */
  /* По умолчанию — поток: варианты ответа на странице уточнения бывают короткими
     («2024», «оба»), и растягивать их до равной ширины незачем. */
  .choices { display: flex; flex-wrap: wrap; gap: .5rem; }
  /* .even — равные колонки. Нужно там, где варианты сопоставляют между собой и
     разная ширина читается как небрежность: карточки глубины на главной
     расходились на 300/306/406px, потому что flex мерил их по содержимому. */
  .choices.even { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
  .choice {
    display: flex; flex-direction: column; gap: .15rem; text-align: left;
    font-family: var(--body); font-size: .875rem; color: var(--ink-soft);
    background: var(--paper-2); border: 1px solid var(--rule); border-radius: var(--radius);
    padding: .5rem .7rem; cursor: pointer; min-width: 9.5rem;
  }
  .choice .sub { font-family: var(--mono); font-size: .68rem; color: var(--neutral); }
  .choice:hover { border-color: var(--accent); }
  .choice:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
  .choice[aria-pressed="true"] { border-color: var(--accent); background: var(--accent-wash); color: var(--accent); }
  .choice[aria-pressed="true"] .sub { color: var(--accent); }

  /* ── Отступ у врезки ──
     В макете вертикальные отступы внутри раздела несут сами компоненты
     (.alarm — .9rem, .mx-legend — .7rem, .g-legend — .75rem), а не утилиты.
     .note-box своего отступа не имел и прижимался к предыдущему блоку вплотную —
     это и был «странный отступ» на странице прогресса. Задаём то же значение,
     что у .alarm. В отчёте .note-box не используется, так что утверждённая
     страница не меняется. */
  .note-box { margin-top: .9rem; }

  /* ── Строка этапа (страница прогресса) ──
     Полосы прогресса в макете нет, и по решению владельца она не вводится:
     ход показывается строками этапов. Геометрия взята у .turn (сетка «кто/что»),
     цвета состояний — у .verdict. */
  .steps { display: flex; flex-direction: column; gap: .5rem; max-width: var(--measure); }
  .step { display: grid; grid-template-columns: 1.2rem minmax(0, 1fr); gap: .6rem; align-items: baseline; }
  .step .mark { font-family: var(--mono); font-size: .8rem; color: var(--neutral-2); }
  .step .what { font-size: .9rem; color: var(--neutral); }
  .step.done .mark { color: var(--ok); }
  .step.done .what { color: var(--ink-soft); }
  .step.now .mark { color: var(--accent); }
  .step.now .what { color: var(--ink); }
  .step.fail .mark { color: var(--bad); }
  .step.fail .what { color: var(--bad); }
