/* ============================================================
   O3 Analytics — ТОКЕНЫ. Единственный источник значений.
   ============================================================
   Заведён 03.08.2026. До него шкалу объявляли 35 файлов, каждый у себя
   в `:root`, и 21 токен из 48 имел РАЗНЫЕ значения под одним именем:
   --green был #00a86b в 22 файлах и #1fbf6c в 3, --amber имел 4 значения,
   --bg — три. Выглядело как дизайн-система, ею не являлось.

   Правило: значения живут ТОЛЬКО здесь. Страница подключает файл
   `<link rel="stylesheet" href="{{ sv('app/tokens.css') }}">` и красится
   через var(--…). Свой `:root` с цветом в шаблоне — регресс, не правка.

   Контраст: всё, чем красится ТЕКСТ, даёт ≥4.5:1 на c0/c50/c100/bg —
   в обеих темах. Подробности и таблица — в DESIGN.md, раздел Themes.
   ============================================================ */
:root{
    /* ── Нейтраль (светлая тема; в тёмной инвертируется ниже) ──────────── */
    --c0:#ffffff; --c50:#f7f8fa; --c100:#f1f2f5; --c200:#e7e9ee; --c300:#d3d7e0;
    --c400:#666c7b; --c500:#5a6071; --c600:#4d5463; --c700:#333947; --c800:#1c1f29; --c900:#0c0e14;

    /* ── Акценты: ЗАЛИВКА ──────────────────────────────────────────────────
       Иконки, точки, полосы, фон бейджа, линии графиков. Яркие и заметные.
       Для ТЕКСТА на светлом фоне они не годятся (#1fbf6c даёт 2.4:1) —
       для текста берите пару -700 ниже. */
    --blue:#005bff; --blue-600:#004ad6; --indigo:#3d5afe;
    --green:#1fbf6c; --red:#f5334f; --amber:#ff8a00;
    --purple:#7c3aed; --teal:#0d9488; --pink:#f91155;

    /* ── Акценты: ТЕКСТ ────────────────────────────────────────────────────
       Затемнённые пары для надписей и цифр. Проходят AA и на белом, и на
       СВОЁМ тинте (зелёная цифра на зелёной плашке — частый случай). */
    /* Порог считается по ВСЕМ светлым подложкам, включая ЧУЖИЕ тинты: зелёная
       цифра нередко лежит на голубой строке-ховере. По одним нейтральным фонам
       получались провалы «на волосок» (4.41 на blue-50) — замер их не прощает. */
    --green-700:#157c47;   /* худший 4.54:1 из всех подложек */
    --red-700:#d90b28;     /* 4.52:1 */
    --amber-700:#a55900;   /* 4.52:1 */
    --blue-700:#005bff;    /* синий проходит как есть (5.33:1) — пара заведена для симметрии имён */
    --amber-600:#c76a00;

    /* ЦВЕТ ИМЕНИ В ЗНАКЕ (10.08.2026, решение владельца). Знак двухтоновый в
       одном тоне: кольцо и капсулы — заливка --blue, «3» и ANALYTICS — глубокий
       синий. Это тот же принцип «заливка ≠ текст», что и у пар -700, только
       для брендового слоя, поэтому имя своё, а не blue-800.
       Контраст: 9.53:1 на белом, 8.51:1 на c100 — с запасом.
       ⚠️ На СИНЕЙ подложке (--blue, полоса лендинга) этот цвет даёт 1.79:1 —
       там весь знак перекрашивается в белый, см. `.band .o3` в landing.html. */
    --brand-deep:#1338ae;

    /* ── Тинты (подложки под акцентным текстом) ────────────────────────── */
    --blue-50:#e8f0ff; --green-50:#e6f8ef; --red-50:#feeaed; --amber-50:#fff3e3;

    /* ── Система ───────────────────────────────────────────────────────── */
    --bg:#f4f5f7; --card:#ffffff; --ink:#1c1f29;
    --r:16px; --r-sm:11px; --r-pill:999px;
    --sh:0 1px 2px rgba(20,23,38,.05), 0 2px 8px rgba(20,23,38,.04);
    --sh-lg:0 6px 20px rgba(20,23,38,.10), 0 2px 6px rgba(20,23,38,.05);
    /* Ступень «hero» из DESIGN.md — ТОЛЬКО витрина: мокап висит на пустом поле
       без сетки вокруг, и глубокая тень там работает. В кабинете она ломает ритм
       соседних карточек, поэтому имя отдельное, а не --sh-xl. Значение жило в
       landing.html без имени (DESIGN.md это и отмечал) — теперь оно здесь и
       переворачивается в тёмной теме вместе со всей шкалой. */
    --sh-hero:0 26px 64px rgba(20,23,38,.15);
    --t:.16s cubic-bezier(.4,0,.2,1);

    /* ── Совместимость ─────────────────────────────────────────────────────
       Имена, которые успели разойтись по страницам. Оставлены АЛИАСАМИ, чтобы
       перевод не требовал переписывать CSS каждой страницы разом. Набор
       --gray-* — остаток tailwind-палитры из economics/finance; он больше не
       живёт своей жизнью, а смотрит в нашу нейтраль. Новый код их не использует;
       по мере правки страниц алиасы вычищаются. */
    --gray-50:var(--c50); --gray-100:var(--c100); --gray-200:var(--c200);
    --gray-400:var(--c400); --gray-600:var(--c600); --gray-800:var(--c800);
    --blue-lt:var(--blue-50); --green-lt:var(--green-50);
    --red-lt:var(--red-50); --amber-lt:var(--amber-50);
    --purple-lt:#f0edff; --teal-lt:#e0f5f5;
    --radius:var(--r-sm); --shadow:var(--sh);

    /* ЗНАЧОК СОРТИРОВКИ В ШАПКЕ ТАБЛИЦ (09.08.2026). Сортировка переехала с
       названия колонки на шеврон — значит шеврон стал КНОПКОЙ, и вести себя должен
       как кнопка: подсвечиваться и чуть подрастать под курсором, иначе в него не
       целятся. Одни значения на все таблицы: у нас их полтора десятка, и «немного
       увеличится» в каждой по-своему — это уже не система. */
    --sort-ico:var(--c400);              /* покой: значок приглушён */
    --sort-ico-on:var(--blue-700);       /* колонка отсортирована */
    --sort-ico-hover:var(--blue-700);    /* под курсором */
    --sort-ico-bg-hover:var(--blue-50);  /* подложка-подсветка */
    --sort-ico-grow:1.18;                /* насколько подрастает */
    --sort-ico-hit:20px;                 /* мишень: меньше — не попасть мышью */

    /* РИТМ ТАБЛИЦЫ (09.08.2026). Высоту строки задаёт фото товара 26×26 в первой
       колонке (канон «фото перед SKU»), а не текст. Строки БЕЗ фото — прежде всего
       «Итого» — оказывались на три пикселя ниже: глаз ловит это как сбитую сетку
       раньше, чем успевает прочитать цифру. Поэтому ритм назван явно и задаётся
       обеим частям таблицы, а не выводится из содержимого ячейки. */
    --thumb-sz:26px;                     /* фото товара — оно и держит строку */
    --tbl-row-h:33px;                    /* строка таблицы, включая «Итого» */

    /* ── ПЛИТКА-МЕТРИКА (14.08.2026). Один каркас на «Показатели», «Фин. показатели»,
       «План», «Локализацию» и будущие KPI-карточки. До этого рамки плиток были зашиты
       тремя rgba() прямо в styles.css, и одна из них (янтарная rgba(245,158,11)) вообще
       не совпадала с токеном --amber #ff8a00: заливка одного янтаря, рамка другого.
       Литеральные rgba ещё и не переворачивались в тёмной теме — там они оставались
       настроенными под светлый фон. Теперь цвет плитки живёт ЗДЕСЬ и флипается сам.

       ЯЗЫК ЦВЕТА (один на все плитки): цвет говорит «как дела», а не «что это».
         neutral — оценки нет: справка, прошлое, ожидание;
         up      — стало лучше;   down — стало хуже;
         warn    — цифра неполная, ей нельзя верить целиком;
         пара loc/non — ЕДИНСТВЕННОЕ исключение: там цвет кодирует категорию
                        (локально/нелокально), и это объявлено явно. */
    --tile-r:12px;                       /* радиус плитки (карточка 16, плитка внутри — 12) */
    --tile-pad-y:8px;
    --tile-pad-x:12px;
    --tile-gap:8px;                      /* и между плитками, и между слотами внутри */
    --tile-bd:var(--c100);               /* рамка в покое */
    --tile-bg:var(--c50);                /* поверхность в покое */
    --tile-ink:var(--ink);               /* значение без оценки */
    --tile-lbl:var(--c500);              /* подпись */
    /* Оценочные состояния: тинт + рамка того же тона. Рамка = тот же акцент с альфой,
       поэтому в тёмной теме её достаточно переопределить один раз (ниже). */
    --tile-up-bg:var(--green-50);   --tile-up-bd:rgba(31,191,108,.28);   --tile-up-ink:var(--green-700);
    --tile-down-bg:var(--red-50);   --tile-down-bd:rgba(245,51,79,.25);  --tile-down-ink:var(--red-700);
    --tile-warn-bg:var(--amber-50); --tile-warn-bd:rgba(255,138,0,.28);  --tile-warn-ink:var(--amber-700);
    /* Ступени значения по ширине СЕТКИ (не окна): полное «1 006 692 ₽» влезает при ≥360,
       дальше компакт «1,01 млн ₽» и шрифт вниз. Замерено на боевых числах. */
    --tile-val:26px; --tile-val-md:20px; --tile-val-sm:17px; --tile-val-xs:13.5px;
    /* KPI-карточка («одна цифра покрупнее») — ступень НАД плиткой: она занимает целый
       виджет, а не четверть его. Ниже по ширине падает на те же --tile-val-*, чтобы
       на одном экране числа не спорили размерами. */
    --kpi-val:32px;
    /* ...и ступени ВВЕРХ по ВЫСОТЕ виджета (30.08.2026). Владелец: «одиночные плитки
       выглядят ущербно, воздуха много, всё сгруппировано в одной куче, хотя место
       позволяет увеличить шрифты». Так и было: 32 px держались и в карточке 210 px,
       и в карточке 350 px — во второй число занимало седьмую часть высоты, остальное
       пустота. Ступени ставит сам виджет (ResizeObserver), потому что @container
       меряет ШИРИНУ, а размер здесь должен идти от высоты. */
    --kpi-val-lg:44px; --kpi-val-xl:58px;

    /* ЧЕКБОКСЫ (09.08.2026, владелец: «сделай серыми и поменьше — режет глаз»).
       Синие квадраты кричали в таблицах громче цифр, ради которых туда смотрят.
       Галочка — служебный элемент: она НЕ данные и не должна спорить с ними за
       внимание (канон «минимум цвета»). Одни значения на все виджеты. */
    /* Отмечено — состояние ПО УМОЛЧАНИЮ, значит оно должно молчать. Говорящее
       состояние здесь обратное: снятая галочка = пустая рамка, её и видно.
       09.08, вторая правка владельца: «убери фон, галку в корп. цвет». Заливки
       нет вовсе — только тонкая рамка и сама птичка фирменным синим. Так галочка
       перестаёт быть цветным пятном в строке, но остаётся узнаваемо нашей. */
    --check-size:12px;                   /* было 14–16 по месту */
    --check-border:var(--c300);          /* рамка в покое */
    --check-border-hover:var(--blue);    /* под курсором рамка «оживает» */
    --check-tick:var(--blue);            /* птичка — корпоративный синий */

    /* ВЫПАДАЮЩИЕ МЕНЮ И ОКНА НАСТРОЕК (.oz-pop + core/popkit.js), 09.08.2026.
       Владелец: «есть же готовые окна в виджетах сравнения — посади на токены, пусть
       будут одинаковыми». Геометрия была зашита по месту, и меню выбора колонок в
       реестре (двадцать пунктов) растянулось на весь экран, а у соседних виджетов
       такое же меню выглядело иначе. Теперь размеры — отсюда, для всех сразу.
       Меню остаётся МЕНЮ: не во весь экран, дальше — прокрутка внутри. */
    --pop-w-max:300px;                   /* потолок ширины */
    --pop-h-max:460px;                   /* потолок высоты */
    --pop-h-share:0.6;                   /* и не больше этой доли экрана */

    /* «ЗАТОВАРЕНО» — верхний порог шкалы «на сколько хватит» (09.08). Раньше 21 день
       и 300 дней красились одинаково зелёным, хотя год запаса на складе — это
       замороженные деньги, а не благополучие. Сигнал нужен с обеих сторон шкалы.
       ЗАЛИВКА ОСТАЁТСЯ ЗЕЛЁНОЙ, янтарными становятся только ЦИФРЫ (владелец 09.08).
       В этом и смысловое разделение: фон говорит «товар есть, продавать можно», цифра —
       «но его слишком много, деньги стоят». Товар распродаётся — число падает ниже
       порога и само возвращается в зелёный, без отдельного состояния «починилось». */
    --over-bg:var(--green-50);
    --over-ink:var(--amber-700);   /* 4,73:1 на зелёном тинте — AA проходит */
}

/* ============================================================
   Тёмная тема — та же шкала, нейтраль инвертирована.
   Акценты сохраняются, тинты приглушаются, тени углубляются.
   Компонент красится только токенами → флипается сам.
   ============================================================ */
/* Второй селектор — ОПТ-ИН НА ОДИН БЛОК. Светлая страница может включить
   тёмную половину шкалы на своём куске (первый экран лендинга), не заводя
   вторую палитру в шаблоне: значения остаются здесь, в единственном месте.
   Компоненты внутри блока красятся токенами и флипаются сами. */
html[data-theme="dark"], .oz-dark{
    --c0:#171a21; --c50:#1c2029; --c100:#222732; --c200:#2c313d; --c300:#3a4150;
    --c400:#9097a8; --c500:#a4aab7; --c600:#b8beca; --c700:#c8cdd8; --c800:#e7e9ee; --c900:#f4f5f7;
    --bg:#0e1016; --card:#171a21; --ink:#f1f2f5;
    --blue-50:#16233f; --green-50:#10271c; --red-50:#2b1418; --amber-50:#2a1f0c;
    /* на тёмном фоне текст-акценты, наоборот, светлее заливки */
    --green-700:#4ad991; --red-700:#ff7b8e; --amber-700:#ffb154; --blue-700:#71a5ff;
    --brand-deep:#8fb2ff;  /* имя в знаке: 8.27:1 на c0, 7.11:1 на c100 */
    /* Второстепенные акценты пары -700 не имеют — их поднимаем прямо здесь:
       на тёмной поверхности исходные давали 2.6–4.0:1. Графики этим не задеты,
       они читают литералы (см. PULSE_METRICS.color). */
    --purple:#a477f3; --teal:#0ea093; --indigo:#7085fe; --pink:#fb4d80;
    --sh:0 1px 2px rgba(0,0,0,.45),0 2px 8px rgba(0,0,0,.35);
    --sh-lg:0 6px 22px rgba(0,0,0,.55),0 2px 6px rgba(0,0,0,.4);
    --sh-hero:0 40px 90px rgba(0,0,0,.62);
    /* Рамки плиток: на тёмном фоне светлая альфа акцента выглядит грязным ореолом —
       берём тот же акцент, но в его тёмной редакции и слабее. Заливки (--*-50) уже
       переопределены выше, значение красится парой -700 и тоже уже поднято. */
    --tile-up-bd:rgba(74,217,145,.30);
    --tile-down-bd:rgba(255,123,142,.28);
    --tile-warn-bd:rgba(255,177,84,.28);
}

/* ── МАРКА O3 В ТЕКСТЕ ────────────────────────────────────────────────────────
   Не логотип, а знак «O», дописанный к шрифту (tools/build_o3_font.py собирает
   o3mark.woff2, один глиф ~500 байт). unicode-range U+004F — из этого файла
   берётся ТОЛЬКО буква O, «3» и всё остальное остаётся Golos Text: правило
   «одна гарнитура в продукте» не нарушено, это знак к первой, а не вторая.
   Марка ОСТАЁТСЯ ТЕКСТОМ — копируется, ищется поиском по странице, читается
   читалками как «O3». Логотип для шапок — другое, он в _brandmark.html.
   Живёт здесь, потому что tokens.css подключён и на серверных страницах, и в
   кабинете: до 10.08 объявление сидело только в landing.html, и в подвале
   кабинета марка была набрана обычной латинской O. */
@font-face{font-family:'O3 Mark';font-style:normal;font-weight:400 900;font-display:swap;
  src:url(/static/vendor/fonts/o3mark.woff2) format('woff2');unicode-range:U+004F;}
.o3{font-family:'O3 Mark','Golos Text',-apple-system,sans-serif;font-weight:700;
  color:var(--ink);}
.o3 i{font-style:normal;color:var(--blue);}
