/* Дизайн-система AyanBI — ЕДИНСТВЕННЫЙ дом токенов и компонентов.
   Наряд: Платформа/Spec_Web_Design_2026-09-08.md §5 (этап Д-0), правило Р-08.09-6.

   ПОЧЕМУ ФАЙЛ, А НЕ <style> В ДВУХ СКЕЛЕТАХ. До 08.09.2026 палитра жила копией в
   templates/base.html и templates/vitrina/base.html, а ещё четыре страницы
   (login, invite, error, partner) несли свои копии тех же шести цветов
   ЛИТЕРАЛАМИ, без переменных вовсе. Шесть домов у одной нормы — это шесть мест,
   где следующая правка цвета применится в пяти. Здесь дом один; скелеты его
   подключают и своих стилей не имеют. Судит гейт selfcheck.py --screens.

   ПЕЧАТЬ РАВНА ЭКРАНУ. Тема одна, светлая: у клиента документ дня уходит
   бухгалтеру и печатается, а автор у экрана и PDF ОДИН (Р-14.08-5, Р-07.09-7).
   Тёмного режима нет намеренно (ТЗ §7 п.13), prefers-color-scheme не слушаем.

   ЦВЕТ НЕ БЫВАЕТ ЕДИНСТВЕННЫМ НОСИТЕЛЕМ. У природы суммы и у состояния данных
   рядом с цветом всегда стоит СЛОВО: ч/б печать и дальтонизм не должны отнимать
   у клиента смысл (ТЗ §7 п.3).

   ЗАЧЕМ КИРИЛЛИЧЕСКИЕ ИМЕНА КЛАССОВ. Это разметка клиентского экрана, а не
   исполнительный синтаксис (Р-30.08-2 и Р-01.09-6 говорят о модулях, каталогах,
   ключах CLI и именах юнитов). Имена файлов и токенов путей — латиницей. */

/* ── 1. Шрифт ───────────────────────────────────────────────────────────────
   IBM Plex Sans, self-hosted (SIL OFL-1.1, static/fonts/LICENSE-IBM-Plex.txt).
   Google Fonts не подключаем: витрина не отдаёт посетителя третьей стороне и
   не ждёт чужой сети (ТЗ §7 п.10, CSP font-src 'self').

   Подрезано под наш алфавит: латиница, кириллица, пунктуация, ₸ (U+20B8),
   стрелки и галочки. Два начертания — 17,1 и 18,0 КБ, вместе 35,2 КБ при
   потолке 120 КБ (ТЗ §5.2). Полный Plex дал бы 127 КБ на те же два веса.
   Курсива нет: в продукте он не используется ни разу.

   ЗАМЕР ТАБЛИЧНЫХ ЦИФР: у Plex все десять цифр уже 600 единиц ширины, фичи
   `tnum` в шрифте нет вовсе — она ему не нужна. Объявление ниже работает на
   ЗАПАСНОЙ стек (системные шрифты), где цифры пропорциональные и колонка сумм
   без него едет. */
@font-face {
  font-family: "IBM Plex Sans AyanBI";
  src: url("/static/fonts/IBMPlexSans-Regular-subset.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Sans AyanBI";
  src: url("/static/fonts/IBMPlexSans-SemiBold-subset.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}

/* ── 2. Токены ──────────────────────────────────────────────────────────── */
:root {
  /* Палитра «бумага» — ТЗ §5.1. Здесь ЕЁ ДОМ: значения живут тут, ТЗ на них
     ссылается. Контраст каждого текстового токена к --фон и к --бумага судит
     `selfcheck.py --screens`, порог 4.5:1.

     ЗАМЕР 08.09.2026, из-за которого два значения ТЗ отличаются от напечатанных
     в нём: --вопрос #b7791f давал 3,46:1 на фоне, --неизвестно #9a9a9a — 2,67:1
     при пороге 4,5, объявленном тем же §5.1. Ярлык «под вопросом» — это текст,
     который клиент обязан прочесть, и на телефоне при солнце он не читался.
     Взяты ближайшие тона, проходящие порог: 4,65 и 4,77. Остальные девять токенов
     ТЗ прошли как есть. */
  --фон:        #faf9f7;   /* страница */
  --бумага:     #ffffff;   /* карточка, документ */
  --чернила:    #1a1a1a;   /* текст */
  --серый:      #6b6b6b;   /* подписи, вторичный текст */
  --линия:      #d8d6d1;   /* границы, разделители */
  --акцент:     #8a6d3b;   /* бренд, кнопки, ссылки, активные чипы */

  /* Четыре природы суммы + два состояния пустоты. Природа НИКОГДА не
     передаётся одним цветом: рядом стоит ярлык словом (см. .природа). */
  --потеря:     #8c2f2f;   /* подтверждённая потеря, «срочно» */
  --вопрос:     #9c6519;   /* под вопросом (ТЗ #b7791f — 3,46:1, замер 08.09) */
  --оценка:     #5b6b8c;   /* оценка, плашка демо */
  --оборот:     #4f6b5c;   /* оборот к проверке, «чисто» */
  --неизвестно: #6f6f6f;   /* не считалось, данных нет (ТЗ #9a9a9a — 2,67:1) */

  /* Прежнее имя --тревога оставлено АДРЕСОМ на --потеря: на него смотрят
     шаблоны, написанные до Д-0. Второго значения у него нет. */
  --тревога:    var(--потеря);

  /* Типографика — ТЗ §5.2. Шкала закрыта: 12·14·16·20·28·36. */
  --шрифт: "IBM Plex Sans AyanBI", -apple-system, "Segoe UI", Roboto, system-ui, sans-serif;
  --кегль-подпись: .75rem;   /* 12 */
  --кегль-мелкий:  .875rem;  /* 14 — основной на телефоне */
  --кегль-текст:   1rem;     /* 16 — основной на десктопе, текст находки */
  --кегль-вердикт: 1.25rem;  /* 20 — вердикт, заголовок карточки */
  --кегль-экран:   1.75rem;  /* 28 — заголовок экрана */
  --кегль-число:   2.25rem;  /* 36 — ОДНО число на экране, не больше одного */
  --межстрочный: 1.45;
  --ширина-текста: 70ch;

  /* Ритм и форма */
  --шаг: .5rem;
  --поле: 1rem;
  --скругление: 10px;
  --скругление-мелкое: 6px;
  --полоса: 52rem;         /* колонка кабинета */
  --полоса-широкая: 54rem; /* колонка витрины */
  --колонка-меню: 12rem;   /* левая колонка разделов на десктопе, ТЗ §4.1 */
  --каркас: 66rem;         /* 12 + 2 (зазор) + 52: ширина, с которой колонка встаёт */
  --палец: 44px;           /* минимум для касания, ТЗ §5.5 */
}

/* ── 3. Основа ──────────────────────────────────────────────────────────── */
* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--шрифт);
  font-size: var(--кегль-мелкий);
  line-height: var(--межстрочный);
  font-variant-numeric: tabular-nums;
  color: var(--чернила);
  background: var(--фон);
}
@media (min-width: 48rem) {
 body { font-size: var(--кегль-текст); }}

/* Полоса витрины: ширину задавали, а ЦЕНТРОВКУ и боковые поля — нет. Внутри tailnet
   это было незаметно (смотрели с широкого экрана и не придирались), а первый же выход
   наружу 12.09 показал текст, прилипший к левому краю без единого пикселя отступа.
   `margin-inline: auto` центрует полосу, `padding-inline` держит поле на узком экране,
   где max-width уже не работает. Найдено словом Игоря при открытии ayanbi.kz. */
body.витрина header, body.витрина main, body.витрина footer {
  max-width: var(--полоса-широкая);
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2rem);
}

header { border-bottom: 1px solid var(--линия); padding-top: .75rem; padding-bottom: .5rem; }
main   { padding-bottom: 3rem; }
footer { border-top: 1px solid var(--линия); padding-top: .75rem;
         color: var(--серый); font-size: var(--кегль-подпись); }
footer a { color: var(--серый); }

a { color: var(--акцент); }
p { margin: .4rem 0; max-width: var(--ширина-текста); }
p.лид { font-size: var(--кегль-текст); }

h1 { font-size: var(--кегль-вердикт); font-weight: 600; margin: 1rem 0 .25rem; line-height: 1.3; }
h2 { font-size: var(--кегль-текст);   font-weight: 600; margin: 1.5rem 0 .5rem; }
h3 { font-size: var(--кегль-мелкий);  font-weight: 600; margin: 1.1rem 0 .3rem; }
@media (min-width: 48rem) {

  h1 { font-size: var(--кегль-экран); }
  h2 { font-size: var(--кегль-вердикт); }
  h3 { font-size: var(--кегль-текст); }}

main > h1:first-child { margin-top: 1.2rem; }

/* ── 4. Шапка, меню, крошки ─────────────────────────────────────────────── */
.шапка { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; min-height: 56px; }
.лого { font-weight: 600; color: var(--чернила); text-decoration: none;
        font-size: var(--кегль-текст); display: flex; align-items: center; gap: .4rem; }
.лого svg { width: 1.3rem; height: 1.3rem; }

nav.меню { display: flex; gap: .9rem; flex-wrap: wrap; flex: 1; }
nav.меню a { color: var(--серый); text-decoration: none; font-size: var(--кегль-мелкий); }
nav.меню a.активен, nav.меню a.активна {
  color: var(--чернила); border-bottom: 2px solid var(--акцент);
}

.человек { margin-left: auto; color: var(--серый); font-size: var(--кегль-подпись);
           white-space: nowrap; display: flex; align-items: center; gap: .6rem; }
.колокол .значок { width: 1.35rem; height: 1.35rem; color: var(--чернила); }
.человек a, header a { color: var(--серый); text-decoration: none; }
.крошки .назад { margin-right: .5rem; }
/* Нижняя панель перекрывает низ содержимого — отдаём ей высоту пальца. */
body:not(.витрина) main { padding-bottom: calc(3rem + var(--палец)); }

@media (min-width: 66rem) {

  aside.боковое nav.меню { flex-direction: column; gap: .55rem; }
  aside.боковое nav.меню a.активен, aside.боковое nav.меню a.активна {
    border-bottom: 0; border-left: 2px solid var(--акцент); padding-left: .5rem;
    margin-left: -.7rem;
  }
  body:not(.витрина) main { padding-bottom: 3rem; }}


/* У витрины своя шапка: пунктов четыре, они в одну строку помещаются на любой
   ширине, и ни колонки, ни нижней панели ей не нужно. Замер 08.09: общее правило
   кабинета оставило её телефонную шапку вообще без навигации и без «Входа».

   ПРАВКА Д-4 (09.09.2026, по снимку 360 px): пунктов на витрине СЕМЬ, а не четыре, и
   на телефоне они переносились в три строки ВОКРУГ логотипа — знак сервиса оказывался
   в середине меню. Разводим на две строки: имя сверху, разделы под ним одной лентой с
   горизонтальной прокруткой. Бургера здесь по-прежнему нет: у незнакомого человека,
   пришедшего с телефона, разделы должны быть видны, а не спрятаны за значок. */
@media (max-width: 40rem) {

  body.витрина .шапка { flex-direction: column; align-items: flex-start; gap: .35rem; }
  body.витрина nav.меню { gap: .6rem; font-size: var(--кегль-подпись);
                          flex-wrap: nowrap; overflow-x: auto; max-width: 100%;
                          padding-bottom: .2rem; }
  body.витрина nav.меню a { white-space: nowrap; }}


/* ── 5. Карточка и текстовые классы ─────────────────────────────────────── */
.строка, .карточка {
  border: 1px solid var(--линия); border-radius: var(--скругление);
  background: var(--бумага); padding: .75rem .9rem; margin: .6rem 0;
}
.строка a { color: var(--чернила); }
.строка.главный, .строка.акцент { border-color: var(--акцент); }
.строка.срочно { border-color: var(--потеря); border-left-width: 4px; }
.строка.прокрутка { overflow-x: auto; }

.тихо     { color: var(--серый); font-size: var(--кегль-мелкий); }
.подпись  { color: var(--серый); font-size: var(--кегль-подпись);
            text-transform: uppercase; letter-spacing: .04em; }
/* Подпись стоит НАД своим значением, а не впритык к нему. 09.09 на боевом экране
   профиля читалось «входigor.nam.plh@gmail.com»: два инлайновых span подряд, между
   ними ни пробела, ни переноса. Блочной делается ЗНАЧЕНИЕ после подписи, а не сама
   подпись: в сводках она законно стоит в строку с числом («сюжетов показано 3»), и
   блок там разорвал бы фразу. */
.подпись + .значение { display: block; margin-top: .15rem; }
/* НЕ `nowrap`. Снимок 360 px от 08.09 поймал обрезанную строку находки: класс
   пришёл из base.html, где им мерили короткие величины, а сегодня им же печатается
   «что нашли» — предложение в 60 знаков. Неразрывность нужна ЧИСЛУ, и у числа для
   этого есть `.деньги`. */
.значение { font-size: var(--кегль-текст); overflow-wrap: anywhere; }
.значение.как-есть { white-space: pre-wrap; }
.значение.одной-строкой { white-space: nowrap; }
.деньги   { white-space: nowrap; font-variant-numeric: tabular-nums; }
.тревога  { color: var(--потеря); }
.цена     { font-size: var(--кегль-вердикт); white-space: nowrap; }
.было     { color: var(--серый); text-decoration: line-through; font-size: var(--кегль-мелкий); }

.метка { display: inline-block; font-size: var(--кегль-подпись); padding: .1rem .45rem;
         border-radius: var(--скругление-мелкое); border: 1px solid var(--линия);
         color: var(--серый); }
.метка.высокий { color: var(--потеря); border-color: var(--потеря); }
.метка.акцент  { color: var(--акцент); border-color: var(--акцент); }

/* ── 6. Ярлык природы суммы — ТЗ §5.3 ───────────────────────────────────────
   Компонент стоит СЛЕВА от суммы и всегда несёт текст. Суммы разных природ
   не складываются и не стоят в одной колонке (Р-04.09-2, README_фронт п.2). */
.природа {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: var(--кегль-подпись); line-height: 1.3; white-space: nowrap;
  padding: .1rem .45rem; border-radius: var(--скругление-мелкое);
  border: 1px solid currentColor; color: var(--неизвестно);
}
.природа::before { content: ""; width: .45rem; height: .45rem; border-radius: 50%;
                   background: currentColor; flex: none; }
.природа--потеря { color: var(--потеря); }
.природа--вопрос { color: var(--вопрос); }
.природа--оценка { color: var(--оценка); }
.природа--оборот { color: var(--оборот); }
/* «Назвать нельзя» — не природа суммы, а её отсутствие с причиной (Р-01.08-137). */
.природа--нет    { color: var(--неизвестно); font-style: normal; }
/* СЛУЖЕБНЫЕ КВАЛИФИКАТОРЫ (Д-5): «начислено», «к выплате», «выплачено», «сторно» —
   это не природа НАХОДКИ, а вид платежа, и своего цвета у них нет намеренно: правило
   выше уже красит `.природа` нейтральным, а четыре новых цвета в палитре означали бы,
   что деньги партнёра стоят в одном ряду с ущербом клиента. Классы перечислены, чтобы
   следующий читатель видел закрытый список, а не гадал, опечатка это или замысел. */
.природа--начислено, .природа--к-выплате,
.природа--выплачено, .природа--сторно { color: var(--неизвестно); }

/* ── 7. Состояние данных — ТЗ §5.4, шесть значений ────────────────────────── */
.состояние {
  display: inline-flex; align-items: center; gap: .35rem;
  font-size: var(--кегль-подпись); white-space: nowrap; color: var(--серый);
}
.состояние::before { content: ""; width: .55rem; height: .55rem; border-radius: 2px;
                     background: currentColor; flex: none; }
.состояние--закрыт-чисто   { color: var(--оборот); }
.состояние--закрыт-находки { color: var(--акцент); }
.состояние--не-окончательный { color: var(--вопрос); }
.состояние--не-считался    { color: var(--неизвестно); }
.состояние--данных-нет     { color: var(--неизвестно); }
.состояние--контроль-не-пройден { color: var(--потеря); }
.пусто.чисто { border-style: solid; border-color: var(--оборот); }
/* Результат действия виден там, где действие сделано. */
.строка.чисто-принято { border-color: var(--оборот); border-left-width: 4px; }

/* ── 9. Кнопки, чипы, формы ─────────────────────────────────────────────── */
/* 44 px — требование ПАЛЬЦА (ТЗ §5.5), и оно про телефон. На десктопе такая кнопка
   выглядит грузной и наползает на соседний текст — названо в бою 09.09. Мышь целится
   точнее пальца, поэтому там высота меньше, а отступ сверху обязателен: кнопка внутри
   карточки шла впритык к строке над собой. */
a.кнопка, button, input[type="submit"] {
  font: inherit; padding: .45rem .9rem; min-height: 38px; margin-top: .6rem;
  border: 1px solid var(--линия); border-radius: 8px;
  background: var(--бумага); color: var(--чернила);
  text-decoration: none; cursor: pointer; display: inline-flex;
  align-items: center; justify-content: center;
}
a.кнопка.главная, button.главная, button.основная, input[type="submit"] {
  background: var(--акцент); border-color: var(--акцент); color: var(--бумага);
}
button.тихо    { border-color: transparent; background: none; color: var(--серый);
                 min-height: auto; padding: .2rem .3rem; }
button.исход   { margin: .2rem .3rem .2rem 0; }
@media (max-width: 48rem) {

  a.кнопка, button, input[type="submit"] { min-height: var(--палец); }}

.кнопки { display: flex; gap: .6rem; flex-wrap: wrap; margin: 1rem 0; }

/* Галочка согласия: квадрат слева, текст рядом и в нормальном регистре. Без этого
   `label` был блочным, чекбокс уезжал на свою строку, а строки липли друг к другу. */
label.галочка { display: flex; align-items: flex-start; gap: .5rem; margin-top: .5rem;
                font-size: var(--кегль-мелкий); color: var(--чернила);
                text-transform: none; letter-spacing: 0; }
label.галочка input { margin: .15rem 0 0; flex: none; }
.строка form, .карточка form { margin-top: .8rem; }
.кнопки--разметка { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; }
@media (min-width: 48rem) {
 .кнопки--разметка { grid-template-columns: repeat(3, max-content); }}


label { display: block; font-size: var(--кегль-подпись); color: var(--серый); margin-top: .9rem; }
input, select, textarea {
  font: inherit; padding: .5rem .6rem; border: 1px solid var(--линия);
  border-radius: 8px; background: var(--бумага); color: var(--чернила);
}
/* ПОЛЕ ВСТАЁТ ПОД СВОЕЙ ПОДПИСЬЮ, А НЕ РЯДОМ С НЕЙ. Формы кабинета написаны как
   `<label>Имя <input></label>`: подпись и поле лежат в одном элементе, и пока поле
   было `inline`, они делили строку — на боевом это читалось «Имя[igor.nam...]», а
   кнопка под ними казалась наползающей. Ширина ограничена: поле во всю колонку на
   десктопе обещает длинный ввод там, где ждут двадцать знаков. */
label > input:not([type="checkbox"]):not([type="radio"]),
label > select, label > textarea {
  display: block; width: 100%; max-width: 24rem; margin-top: .25rem;
}
label.галочка > input { display: inline-block; width: auto; max-width: none; }
input[type="checkbox"], input[type="radio"] { width: auto; min-height: auto; margin-top: 0; }

.отказ { border: 1px solid var(--потеря); color: var(--потеря); border-radius: 8px;
         padding: .6rem .8rem; margin: .8rem 0; font-size: var(--кегль-мелкий); }

/* ── 10. Таблица и её мобильная форма ───────────────────────────────────── */
table { width: 100%; border-collapse: collapse; }
td, th { text-align: left; padding: .45rem .4rem; border-bottom: 1px solid var(--линия);
         font-size: var(--кегль-мелкий); vertical-align: top; }
th { font-weight: 600; color: var(--серый); font-size: var(--кегль-подпись);
     text-transform: uppercase; letter-spacing: .04em; }

dl.величины { margin: 0; }
dl.величины dt { margin-top: .8rem; color: var(--серый); font-size: var(--кегль-подпись); }
dl.величины dd { margin: .1rem 0 0; }

ul.области { list-style: none; padding: 0; margin: .5rem 0; }
ul.области li { border-bottom: 1px solid var(--линия); padding: .4rem 0; }

/* ── 13а. Витрина: значки областей, живой фрагмент листа, пакеты (ТЗ §3.1, Д-4) ──
   Значок берёт цвет у текста и стоит РЯДОМ с именем области, а не вместо него:
   носитель смысла — слово, значок только помогает найти строку глазами. */
.область-строка { display: flex; align-items: center; gap: .6rem; }
.область-строка .значок { width: 1.25rem; height: 1.25rem; flex: none; color: var(--акцент); }

/* Живой фрагмент листа дня из демо. Рамка та же, что у карточки кабинета: посетитель
   видит продукт, а не его пересказ версткой витрины. */
.фрагмент { margin: 1rem 0; }
.фрагмент > .строка:last-of-type { border-style: dashed; }

ul.пакеты { list-style: none; padding: 0; margin: .6rem 0; display: grid; gap: var(--шаг); }
ul.пакеты li { border: 1px solid var(--линия); border-radius: var(--скругление);
               background: var(--бумага); padding: .6rem .8rem; }
ul.пакеты li.рекомендован { border-color: var(--акцент); }
ul.пакеты .значение { float: right; }

ul.перечень-услуг { list-style: none; padding: 0; margin: .6rem 0; }
ul.перечень-услуг li { border-bottom: 1px solid var(--линия); padding: .5rem 0; }
.пузырь.ответ { margin-right: auto; }
.пузырь .подпись { display: block; }
.пузырь .метка { margin-top: .4rem; }
.человек-шапка .значок { width: 1.1rem; height: 1.1rem; flex: none;
                         color: var(--серый); align-self: center; }
.ось { display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap; }
.ось > .подпись { flex: 0 0 5.5rem; }
.ось > .чипы { margin: 0; flex: 1 1 12rem; }
.ось .чип { font-size: var(--кегль-подпись); }
details.доступ { margin: .6rem 0 0; }
details.доступ > summary { cursor: pointer; color: var(--акцент);
                           font-size: var(--кегль-мелкий); }
details.доступ fieldset { border: 1px solid var(--линия);
                          border-radius: var(--скругление); margin: .6rem 0; }
@media (max-width: 30rem) {

  .ось { display: block; }
  .ось > .подпись { display: block; }}


/* ── 10д. Тариф: карточка пакета и счета списком — §4.6, Д-5; довод — `tarif.html`. */
.карточка.пакет { border-color: var(--акцент); }
ul.счета { list-style: none; padding: 0; margin: .6rem 0; display: grid; gap: .5rem; }
ul.счета > li { border-bottom: 1px solid var(--линия); padding: .4rem 0; }
ul.счета > li.карточка { border: 1px solid var(--линия);
                         border-radius: var(--скругление); padding: .6rem .8rem; }

/* ── 11. Аккордеон «Происхождение числа» ────────────────────────────────── */
details.происхождение { margin: .8rem 0 0; }
/* НЕ `display: flex`. Снимок 360 px от 09.09 (Д-1) поймал: у свёрнутого блока пропал
   треугольник раскрытия — `flex` снимает маркер `summary`, и «Происхождение числа»
   выглядело подписью, а «Висит давно» — пустой карточкой. Аккордеон, не показывающий,
   что он аккордеон, прячет содержимое ровно так же, как его отсутствие. `list-item`
   маркер возвращает; высота пальца держится `min-height` и отступами. */
details.происхождение summary { cursor: pointer; color: var(--акцент);
                                font-size: var(--кегль-мелкий); min-height: var(--палец);
                                display: list-item; padding: .5rem 0; }
details.происхождение[open] summary { margin-bottom: .4rem; }
.зона > h2 .час { font-weight: 400; font-size: var(--кегль-подпись); color: var(--серый); }
.плитка .подпись { display: block; }
.плитка .значение { font-size: var(--кегль-вердикт); font-weight: 600; }

/* Лист дня на десктопе: якоря слева липко, содержимое справа (ТЗ §4.3). */
@media (min-width: 64rem) {

  .лист { display: grid; grid-template-columns: 14rem 1fr; gap: 2rem; align-items: start; }
  .лист > .якоря { position: sticky; top: 1rem; }
  .лист > .якоря .чипы { flex-direction: column; align-items: flex-start; }}


/* ── 15. Графики — серверный SVG, Р-07.09-7 ────────────────────────────────
   JS-библиотек нет. Значения печатаются текстом рядом с картинкой, поэтому
   ни hover, ни подсказок здесь нет и быть не должно: то, что видно мышью,
   не видно на бумаге и не читается скринридером (ТЗ §5.6 и §7 п.7). */
svg.график { display: block; width: 100%; height: auto; max-width: 100%; }
svg.график text { font-family: var(--шрифт); font-size: 11px; fill: var(--серый); }
.график--потеря { color: var(--потеря); }
.график--вопрос { color: var(--вопрос); }
.график--оценка { color: var(--оценка); }
.график--оборот { color: var(--оборот); }
.график--неизвестно { color: var(--неизвестно); }
.график--акцент { color: var(--акцент); }
/* Ось и разлиновка картинки — та же линия, что у границ карточек: у графика
   нет своей палитры, он берёт роли общей (Д-3, 09.09.2026). */
.график--линия { color: var(--линия); }
.заливка { fill: currentColor; }
.обводка { fill: none; stroke: currentColor; stroke-width: 1.5; }

/* ── 15а. Знак и линейные иконки ──────────────────────────────────────────
   Ни одного #-цвета в шаблонах: цвет знака и иконок приходит из токенов через
   CSS, а не литералом в атрибуте `fill`. Литерал в разметке — второй дом цвета,
   и первая же смена акцента применилась бы везде, кроме логотипа. */
.знак { color: var(--акцент); }
.знак .круг { fill: currentColor; }
.знак .галка { fill: none; stroke: var(--бумага); stroke-width: 3;
               stroke-linecap: round; stroke-linejoin: round; }
.значок { fill: none; stroke: currentColor; stroke-width: 2;
          stroke-linecap: round; stroke-linejoin: round; }
.pwa-баннер .шаг { flex: 1 1 12rem; max-width: 16rem; }
.pwa-баннер .шаг .подпись { display: block; margin-top: .25rem; }
svg.рисунок .линия { fill: none; stroke: var(--линия); stroke-width: 2;
                     stroke-linecap: round; }

/* ── 17. Движение — ТЗ §5.8 ─────────────────────────────────────────────── */
.плашка, details.происхождение, .pwa-баннер { transition: opacity 150ms, transform 150ms; }
@media (prefers-reduced-motion: reduce) {

  * { transition: none !important; animation: none !important; }}


/* ── 18. Печать: экран и PDF — один автор ───────────────────────────────── */
@media print {
  body { background: var(--бумага); font-size: 11pt; }
  header nav, details.бургер, .панель-низ, .кнопки, .чипы, .pwa-баннер { display: none !important; }
  .строка, .карточка, .плитка { break-inside: avoid; page-break-inside: avoid; }
  details, details.свёртка { display: block; }
  details > *:not(summary) { display: block !important; }
  a { color: var(--чернила); text-decoration: none; }
}