/* 002-ui-v4-palette-roles.css — v4 role tokens per palette (stage 1)
 * All roles use --v4-* to avoid collision with 242 legacy variables in 001-design-tokens.css.
 *
 * --v4-warn-1/2/3 — три градации одной роли «внимание»: сдержанная, средняя,
 * плотная. Оттенок один, различаются насыщенность и светлота (решение владельца
 * 2026-08-10). Нужны там, где значение различает больше состояний, чем даёт
 * контракт ступеней: шкала вреда несёт вредный / очень вредный / супервредный
 * внутри одной ступени warn-strong. Второй цветовой системы это не заводит —
 * роль та же, меняется только глубина.
 *
 * --v4-btn-on-act — цвет текста на заливке --v4-act.
 * Песочная: #2b1608 / #1a0f04. Светло-синяя: #ffffff (4.77:1 на #1d5e96).
 * Сине-тёмная: #0b1621 (5.26:1 на #3f8fd0) — решение дизайнера 3 сентября
 * «правится палитра, канвас верен»; белый там давал 3.47:1, ниже порога.
 *
 * Устаревшие запасные значения рядом с ролями — известно и решено не трогать
 * (владелец, 2026-08-31). Замер по всем модулям: записей
 * `var(--v4-роль, запасное)` 4017, из них у 2356 запасное не совпадает со
 * значением роли ни в одном наборе — там остались литералы прежнего синего
 * набора (#2563eb, #111827, #16a34a). На экране это не видно: роль объявлена и
 * рисуется она, запасное — мёртвый код, и врёт оно только читающему.
 * Опасно оно ровно в одном случае: когда роль в каком-то наборе НЕ объявлена —
 * тогда рисуется запасное. Таких мест на момент замера одно
 * (734-ui-v4-insights.css, --v4-border объявлена только в тёмных наборах),
 * и этот случай ловит BASELINE в scripts/ui-v4-check-undefined-roles.mjs.
 * Массовую замену 2356 мест решено не делать: тридцать файлов, каждый под
 * параллельной сессией, цена — конфликты, польза — только читаемость.
 * Мерка «запасное ≠ роль» сама по себе находит эти 2356 и уводит в мёртвый
 * код; рабочая мерка — «роль не объявлена хоть в одном наборе».
 */

@font-face {
  font-family: Manrope;
  src: url('/fonts/manrope/Manrope-Variable.ttf') format('truetype');
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
}

/* ── Лестница слоёв ────────────────────────────────────────────────────────
 * Источник правды — home-widgets.v4.dc.html, строка «порядок слоёв · правило
 * продукта»: снизу вверх экран → липкая капсула даты → нижняя навигация и
 * плавающая кнопка → бар отмены → шторки и листы с их затемнением → модалка
 * обновления и офлайн-баннер. Слой, который человек открыл сам, встаёт над
 * тем, что было; служебный слой обновления — над всем.
 *
 * Ступени именованные, потому что раньше числа жили по всему продукту и
 * частью инлайном в JS (бар отмены — 1010 прямо в heys_undo_v1.js), и «что
 * выше чего» нельзя было прочитать нигде. Слои ссылаются на ступень, а не на
 * число; запасное значение у var() равно самой ступени — файл ролей грузится
 * до main.css, но критический CSS может встать раньше него.
 *
 * Ступени идут с зазором: сосед, которому нужно встать чуть выше своего
 * рунга, берёт `calc(var(--ступень) + 1)`, а не новое число из воздуха.
 * ─────────────────────────────────────────────────────────────────────── */
:root {
  /* Семантическая лестница чернил из актуального контракта home-widgets.
     Производные роли считаются от чернил текущего набора, поэтому одинаковые
     проценты работают во всех четырёх палитрах без отдельного dark-boost. */
  /* 7 сентября: `--v4-ink-data/label/secondary/mark` сняты — продукт переведён
     на равные ступени лестницы (`--v4-ink-2/3/4/30`), объявленные в каждом
     наборе ниже по файлу. Доли совпадали один в один (56/45/38/30), поэтому в
     песочном цвет не изменился; изменился он там, где и была беда, — в синем и
     тёмных, где эти четыре роли жили одной долей на все наборы и палитре не
     следовали. Здесь их объявлять нельзя: `:root` перебил бы наборы. */

  /* Липкая капсула даты. Не общий fixed-слой: она внутри прокрутки экрана
     (.tab-active-viewport), и над навигацией её держит не число, а то, что
     навигация fixed и стоит на своём рунге. */
  --v4-z-date-capsule: 11;

  /* Нижняя навигация и плавающая кнопка — один рунг контракта, но кнопка
     рисуется поверх ряда вкладок, а полоса CRS — поверх обеих. */
  --v4-z-nav: 1000;
  --v4-z-fab: 1001;
  --v4-z-nav-progress: 1002;

  /* Бар отмены: выше навигации и кнопки, ниже шторок и листов. Строка
     undo-bar.v4.dc.html «порядок слоёв»: открытие листа бар не закрывает —
     он остаётся под ним и доживает своё окно. */
  --v4-z-undo: 1010;

  /* Обычный тост приложения — роли success / error / warning / tip. Лестница
     шестнадцатой сборки ставит его выше бара отмены и НИЖЕ шторок: тост,
     пришедший при открытом листе, человек не видит, и это решение, а не
     недосмотр. Раньше стоял голым числом 10002 — выше всех листов.

     Вестника версии среди ролей нет: мягкие уведомления обновления сняты
     как мёртвый код (pwa-update.v4.dc.html, «мягкие уведомления»). */
  --v4-z-toast: 1100;

  /* Шторки и листы. Затемнение — отдельным элементом под своим листом;
     если элемент несёт и затемнение, и лист (подложка с flex-контентом),
     он берёт --v4-z-sheet-scrim, а лист внутри едет без числа.
     Блокировщик касаний живёт под затемнением: он показывается только в
     кадре закрытия, когда самого листа уже нет. */
  --v4-z-sheet-blocker: 1199;
  --v4-z-sheet-scrim: 1200;
  --v4-z-sheet: 1205;

  /* Второй лист над шторкой. Контракт settings-system: «шторка настроек и
     лист „на домашний экран“ — два слоя, лист встаёт над шторкой». Общее
     правило «двух затемнений одновременно не бывает» этой парой и
     ограничено — третьего уровня в продукте нет. Ступень одна: у обоих
     вторых листов затемнение и лист — один элемент. */
  --v4-z-sheet-2: 1210;

  /* Соседи выше листов. Кураторский лист — рунг контракта; остальные три
     контрактом не ранжированы и стоят между ним и баннером. */
  --v4-z-curator-sheet: 10001;
  --v4-z-sync-lock: 10030;
  --v4-z-level-up: 10060;
  --v4-z-install: 13000;
  /* Лист баланса над нижним окном стопки (Итоги недели → Дни недели). */
  --v4-z-modal-stack-top: 10000;

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

     Поднят выше подложки установки и слоя уровня, а не только над листом
     куратора: лестница называет баннер вторым сверху, а эти трое в ней не
     перечислены вовсе. Тот же довод — состояние связи важнее празднования и
     предложения установить. */
  --v4-z-offline-banner: 14000;

  /* Ландшафтная заглушка на телефоне — перекрывает интерфейс, но ниже
     служебного слоя обновления (heys_platform_apis_v1.js). */
  --v4-z-landscape-gate: 900000;

  /* Служебный слой обновления — над всем (pwa-update.v4.dc.html, строка
     «порядок слоёв и два устройства»). */
  --v4-z-update: 999999;
  /* Глобальный ConfirmModal — выше training fullscreen (.fingers-fs 2147483000) */
  --v4-z-confirm-global: 2147483600;

  /* Боковое поле экрана вкладки — контракт «поля 16px 18px 0» (home-widgets,
     reports-insights): полоса геймификации, заголовок вкладки, капсула даты
     и карточки контента отступают от края экрана на одно и то же значение.
     Решение владельца 20.09 после того, как это поле три раза чинили по
     отдельности в .wrap и в паре .hdr-правил на разных вкладках и разъезд
     возвращался — теперь оно живёт в одном токене, а не в пяти литералах. */
  --v4-tab-gutter: 18px;

  /* Вертикальный ритм шапки вкладки — та же история, что у --v4-tab-gutter:
     владелец увидел «дрожание» между вкладками при перелистывании. Разбор
     20.09: полоса → заголовок/капсула даты была 16px (Актив/Питание, .hdr-
     bottom), 18px (Отчёты/Инсайты, .reports-v4-meta/.insights-v4-meta) и
     14px (Главная, своя капсула без заголовка) — три числа на одну роль.
     Взято 16 — уже кратно 4, как соседние токены шкалы, и это значение уже
     было у большинства практических случаев (Актив и Питание вместе — тот
     же код, что и у будущей «Главной»-заглушки, если у неё когда-то
     появится заголовок). */
  /* 23.09 владелец: 16 читался великоватым (под «Эксперт» 33px видимого
     зазора — 17 поля полосы + 16), стало 10 → 27px. Кадры рисуют 15 — это
     названное отступление, см. UI_V4_OWNER_DECISIONS.md. */
  --v4-tab-header-gap: 10px;

  /* Заголовок вкладки → первый блок под ним (капсула для Актива/Питания,
     первая карточка для Отчётов/Инсайтов). Разбор 20.09: у карточек Отчётов
     и Инсайтов число уже названо контрактом дважды независимо — «Отчёты ·
     мало данных», элементы 06/10, и «Инсайты», элемент 17, — оба «отступ
     сверху 14». У Актива/Питания тот же зазор (между заголовком и капсулой
     даты) держался на 12px и не совпадал ни с одной цитатой контракта.
     Взято 14 — то, что контракт называет дважды, а не число капсулы. */
  --v4-tab-block-gap: 14px;
}

[data-theme-id="sand"],
[data-theme="sand"][data-palette="sand"] {
  --v4-bg: #fffaf1;
  /* Подложка полноэкранного сканера штрихкода — камера всегда на тёмном,
     вне зависимости от темы (кадр «Штрихкод · наведение» рисует один и тот
     же #141210 без палитровых копий). Раньше сканер брал var(--v4-bg,
     #141210): фолбэк не срабатывал, потому что --v4-bg ОБЪЯВЛЕНА (просто
     светлым значением) — подставлялась она, а не тёмный фолбэк. */
  --v4-scanner-bg: #141210;
  --v4-scanner-ink: #f2ede6;
  --v4-hero: #efe3cf;
  --v4-surface: #f7efe2;
  /* Роль канваса --c1: первая поверхность карточек (советы, чипы, поля). */
  --v4-c1: #f7efe2;
  /* Роль канваса --md: поверхность модального слоя, намеренно не равна --c1
     (пакет 81, ответ на записку № 15 — четыре набора палитры канваса). */
  --v4-md: #fffaf1;
  --v4-ok-bg: #eaefe0;
  --v4-wk-gr: #eaefe0;
  --v4-mid-bg: #f5e8c2;
  --v4-wk-weak: var(--v4-tint);
  --v4-act: #c67139;
  /* Плавающая кнопка: своя пара, знак на ней 4,77 — песочный. */
  --v4-fab: #c67139;
  --v4-on-fab: #2b1608;
  --v4-act-text: #8a4a20;
  --v4-ok-text: #5c6a45;
  /* Тинт свайпа «Копировать» — канвасный --sage (контракт «цвет
     свайп-действий»). С --v4-ok-bg (канвасный --gr-bg) он совпадает ТОЛЬКО в
     песочной: дальше #2b3122 против #232a1b, #e3f0e8 против #e6f3ec,
     #1d3328 против #16302a. Сливать нельзя. */
  --v4-ok-tint: #eaefe0;
  /* Отмеченный чип добавки — средний шалфей между --v4-ok-tint и --v4-ok-fill
     (канвас --gr-mid / --on-gr-mid, пакет «новое 2», решение владельца 27.09). */
  --v4-ok-mid: #c8d1b9;
  --v4-on-ok-mid: #171d0d;
  /* Чернила на шалфейном ТИНТЕ --v4-ok-tint — канвасный --sageTx: 10,5 px на
     тинте живут по порогу 4,5:1, и тон подобран под этот тинт, а не под
     сплошную заливку (контракт «цвет свайп-действий»). */
  --v4-on-ok: #3f4a2e;
  /* Чернила на СПЛОШНОЙ шалфейной заливке --v4-ok-fill — канвасный --on-gr
     (контракт «цвета» блока добавок: #171d0d / #12180a / #04231a / #052019).
     Развязано с --v4-on-ok 2026-08-24: одна роль не могла нести оба тона —
     --on-gr на тинте выглядит грязным, а --sageTx на заливке недобирает
     контраст. */
  --v4-on-ok-fill: #171d0d;
  /* Шкала зон итогов дня — константы дизайна из v4-canvas.css: --gr2 (шалфей),
     --warn (предупреждение), --red (красный). Контракт nutrition-tab,
     «цвета зон»: значения одни на все четыре набора, продукт их не подбирает. */
  --v4-ok-fill: #7a8a5e;
  /* Метка «факт есть» — роль канваса --val-good: точка записи под числом в
     сетке календаря и её пара в легенде. Роль не была задана ни в одной
     палитре, и `var(--v4-good, #7a8a5e)` подставлял песочный шалфей во всех
     четырёх наборах, включая синие. С --v4-ok-fill (--gr2) не сливается:
     совпадают только в песочной, дальше #8faa6d против #8a9a6a, #3e9a6b
     против #4f9a78, #4caf7d против #6fbf9a. */
  --v4-good: #7a8a5e;
  --v4-warn-soft: #c9922e;
  /* Анаэробная зона пульса: самостоятельная сливовая роль activity canvas. */
  --v4-z4: #7a5a8c;
  --v4-ink: #201e1d;
  --v4-ink-rgb: 0, 0, 0;
  --v4-water: #7d98a6;
  /* 56 %, а не 55 %: решение дизайнера 7 сентября. По самой тёмной
     поверхности набора --v4-hero #efe3cf при 55 % выходило 4,48 — ниже
     порога 4,5; при 56 % — 4,64. Тёмные наборы остаются на 63 %: там
     хватило бы 53 и 56, запас есть. */
  --v4-ink-2: rgba(0, 0, 0, 0.56);
  --v4-ink-3: rgba(0, 0, 0, 0.45);
  --v4-ink-4: rgba(0, 0, 0, 0.38);
  /* 30 % чернил: покой облака синхронизации в шапке (контракт tips «третий бокс»). Ступень ниже ink-4 — фоновая примета, а не действие. */
  --v4-ink-30: rgba(0, 0, 0, 0.3);
  /* Три роли линии (home-widgets.v4.dc.html, строка «роли линий · правило
     продукта»): --v4-line — разделитель, чернила 8 %; линия списка приёмов
     приведена к ней, прежние 7 % отдельной ролью не заводятся. --v4-track —
     пустой сегмент мини-карточек и дорожка полосы, чернила 12 %. --v4-edge —
     обводка пилюли группы, чернила 18 %: это край контейнера, а не
     разделитель. Больше ролей на линию не заводится, и процент живёт только
     здесь — в продуктовом коде линия задаётся именем токена. */
  --v4-line: rgba(0, 0, 0, 0.08);
  --v4-track: rgba(0, 0, 0, 0.12);
  --v4-edge: rgba(0, 0, 0, 0.18);
  --v4-plan: rgba(0, 0, 0, 0.22);
  /* Поверхность «ещё не состоялось» (tab-activity, «вид · карточка «Впереди»», 26.09): холодный тон и пунктирная кромка.
     Имя не --v4-plan: оно занято чернилами 22 %. Канвас: --plan / --plan-edge.
     Ж5-Б (пакет 102, 27.09): отдельное действие плана --plan-acs / --on-plan-acs,
     чтобы «Добавить активность» оставалось на общем акценте набора. Пакет «новое 2»
     (27.09): заливка смягчена до 40 % синего на --plan, текст — чернила набора. */
  --v4-plan-surface: #e8eef0;
  --v4-plan-edge: rgba(84, 116, 130, 0.4);
  --v4-plan-act: #97b4cc;
  --v4-btn-on-plan-act: #201e1d;
  --v4-tint-warm: #c67139;
  --v4-tint-cool: #7a8a5e;
  --v4-float: #fffaf1;
  --v4-accent-bg: #f0dcc6;
  --v4-warn-1: #d99a63;
  --v4-warn-2: #c67139;
  --v4-warn-3: #a1471c;
  /* Продуктовая копия канвасного --red. 03.09 углублена с #b4442a до #a83c22 по
     решению дизайнера: на --v4-hero (#efe3cf) прежний тон давал 4,36 при
     11 px/600, стало 4,97. Меняется только песочный — тёмный (#e0704f, 4,57),
     синий (#b03a24, 5,05) и сине-тёмный проходили порог сами.
     Заменой по файлу это не делается: в синем наборе литерал #b03a24 носят ещё
     --v4-warn-text, --v4-overlay-fill и --v4-wave-overlap, и они отвечают
     канвасным --ac2/--ovl/--val-bad, а не --red. */
  --v4-bad-text: #a83c22;
  --v4-val-bad: #a8382b;
  /* Текстовый шаг предупреждения: между акцентом действия и «вниманием».
     Тон кнопки крупному числу не годится — на подложке героя он даёт 2,84:1,
     а крупный текст живёт по порогу 3:1 (контракт nutrition-tab, «цвет числа»). */
  --v4-warn-text: #a1471c;
  /* Тонированная подложка-подсказка: плашка куратора и родственные ей. */
  --v4-tint: #f6e6dd;
  /* Капсула даты в прошлом дне. */
  /* Решение владельца 31 августа уточняет прежнее (12 августа, «painted modules
     keep warm look on every theme»): тёплое у героя остаётся во всех наборах,
     но выражается ролью героя --v4-hero-act, а не именем набора. Роль вида
     --v4-<набор>-* в модуле — ошибка по определению: модуль не должен знать,
     что палитра песочная, и синий обязан быть синим целиком. Семейство ниже
     остаётся для самих наборов и для мест, размеченных владельцем как
     геройские; новые вхождения в модулях ловит ui:v4:check, опись нынешних —
     docs/ui/UI_V4_SAND_ROLES_INVENTORY.md. */
  /* Тёплый акцент героя: контракт виджетов прямо называет терракоту героем
     у «Калорий» и «Оценки дня» — она держится во всех четырёх наборах.
     Это роль героя, а не роль набора: модули красят ею и не знают, какая
     палитра выбрана. */
  --v4-hero-act: #c67139;
  /* Жиры в БЖУ — янтарь кадра «ярус Питание» (#d9b96a). Контракт зоны
     reports-insights называет его «цветом не из палитры»: тон один во всех
     четырёх наборах, поэтому значение повторяется, но цвет всё равно идёт
     ролью, а не литералом в модуле. */
  --v4-macro-fat: #d9b96a;
  --v4-sand-act: #c67139;
  --v4-sand-act-deep: #8a4a20;
  --v4-sand-act-text: #8a4a20;
  --v4-sand-act-mid: #a75c2b;
  --v4-add: #a75c2b; --v4-add-line: rgba(167,92,43,.32);
  /* Мягкий тёплый акцент: один и тот же #e2a468 во всех четырёх наборах —
     единственная роль с полным совпадением hex (ui-v4-audit-same-value-roles).
     На тёмных наборах это читаемый акцентный тон текста (≡ --v4-act-text там);
     на светлых — рамки/заливки в hero-language и в [data-theme$="dark"]-ветках.
     Имя «sand» — историческое семейство, не привязка к песочному набору. */
  --v4-sand-act-soft: #e2a468;
  --v4-sand-hero: #efe3cf;
  --v4-sand-hero-cool: #e8ecf1;
  --v4-sand-hero-dark: #211e19;
  --v4-sand-hero-night: #0f172a;
  --v4-sand-accent-bg: #f0dcc6;
  --v4-sand-surface: #f7efe2;
  --v4-sand-surface-soft: #fffaf1;
  --v4-sand-wave-fill: #e6cfa8;
  --v4-sand-ink: #201e1d;
  --v4-sand-ink-deep: #2b1608;
  --v4-sand-ink-slate: #1f2937;
  --v4-sand-ok-text: #5c6a45;
  --v4-sand-ok-fill: #7a8a5e;
  --v4-sand-ok-fill-soft: #dfe6d1;
  --v4-sand-tint: #f3e0d2;
  --v4-sand-warn-bg: #fef3c7;
  --v4-wgt-emerald: #7a8a5e;
  --v4-wgt-ok-deep: #5c6a45;
  --v4-wgt-link: #c67139;
  --v4-wgt-slate: #8a8578;
  --v4-wgt-violet: #a68b7a;
  --v4-wgt-danger-text: #a1471c;
  --v4-wgt-mint: #eaefe0;
  --v4-wgt-sky: #f0dcc6;
  --v4-wgt-magenta: #d99a63;
  --v4-wgt-lilac: #f7efe2;
  --v4-wgt-amber: #d99a63;
  --v4-wgt-orange: #c67139;
  --v4-wgt-rose: #f7efe2;
  --v4-wgt-danger-bg: #f0dcc6;
  --v4-wgt-cream: #efe3cf;
  --v4-wgt-peach: #efe3cf;
  --v4-wgt-teal: #5c6a45;
  --v4-wgt-apple-green: #7a8a5e;
  --v4-wgt-indigo: #a68b7a;
  --v4-wgt-cyan: #7d98a6;
  --v4-wgt-brown: #8a4a20;
  --v4-wgt-purple: #a68b7a;
  --v4-wgt-rust: #c67139;
  --v4-wgt-gold: #d99a63;
  --v4-wgt-salmon: #d99a63;
  --v4-wgt-yellow: #d99a63;
  --v4-wgt-apricot: #efe3cf;
  --v4-wgt-coral: #c67139;
  --v4-wgt-lemon: #d99a63;
  --v4-btn-on-act: #2b1608; /* текст на терракотовой кнопке, 4.77:1 на #c67139 */
  /* Канвасный --ovl: заливка состояния, а не текст. Старое имя волны остаётся
     алиасом, потому что эта роль также красит нахлёст инсулиновых волн. */
  /* Первая поверхность (роль канваса --c1): карточки правок куратора, чипы и
     поля потока добавок, строки-ответы развилки. В тёмных наборах роль была
     задана, в светлых — нет, и туда подставлялся песочный литерал из
     var(--v4-card, #f3ece2): синий набор показывал кремовую поверхность. */
  --v4-card: #f7efe2;
  /* Вторая поверхность (роль канваса --c2): дорожки ползунков, тихие пилюли,
     карточка «записано», выбранная строка принудительной оценки, кнопка
     «Позже» в листе куратора. Роль не была задана ни в одной палитре — семь
     мест использования подставляли литерал #efe3cf, то есть песочную вторую
     поверхность во всех наборах. Значения взяты из канваса; --v4-hero
     приведён к ним же 24.08 — в синих наборах он расходился с контрактом
     на волос. */
  --v4-chip: #efe3cf;
  /* Тень листов и нажатых капсул (роль канваса --shadow, тройка RGB). */
  --v4-shadow-rgb: 80, 50, 20;
  --v4-chip-2: #efe3cf;
  --v4-overlay-fill: #d99a63;
  --v4-wave-overlap: #d99a63;
  /* Затемнение под листами — роль канваса --scrim (home-widgets, строка
     «затемнение под слоем · правило продукта», 4 сентября).
     Решение владельца 22.09: тон — тёплый серый вместо коричневого
     rgba(42, 26, 12) канваса. Коричневый поверх оранжевых элементов уходил в
     рыжий и читался тревожно. Плотность прежняя; кадры ждут перерисовки
     (tmp/sverka/designer-after-release.md). */
  --scrim: rgba(36, 33, 30, 0.5);
}

[data-theme-id="sand-dark"],
[data-theme="sand-dark"][data-palette="sand"] {
  --v4-bg: #141210;
  /* Подложка сканера — тот же константный тёмный, что и в остальных трёх
     наборах (см. комментарий в песочном блоке). */
  --v4-scanner-bg: #141210;
  --v4-scanner-ink: #f2ede6;
  --v4-hero: #2f2820;
  --v4-surface: #23201b;
  --v4-c1: #23201b;
  --v4-md: #191613;
  --v4-ok-bg: #232a1b;
  --v4-wk-gr: #2f3d22;
  --v4-mid-bg: #3d3420;
  --v4-wk-weak: #4a2d20;
  --v4-act: #cf8144;
  /* Плавающая кнопка: своя пара, знак на ней 6,17 — песочно-тёмный. */
  --v4-fab: #cf8144;
  --v4-on-fab: #1a0f04;
  --v4-act-text: #e2a468;
  --v4-ok-text: #9fb37a;
  /* Тинт свайпа «Копировать» — канвасный --sage; не равен --v4-ok-bg
     (канвасный --gr-bg) — контракт «цвет свайп-действий». */
  --v4-ok-tint: #2b3122;
  --v4-ok-mid: #424c33;
  --v4-on-ok-mid: #f2ede6;
  /* Чернила на шалфейном ТИНТЕ --v4-ok-tint — канвасный --sageTx. */
  --v4-on-ok: #cfe0b8;
  /* Чернила на СПЛОШНОЙ заливке --v4-ok-fill — канвасный --on-gr
     (контракт «цвета» блока добавок). */
  --v4-on-ok-fill: #12180a;
  --v4-ok-fill: #8a9a6a;
  --v4-good: #8faa6d;
  --v4-warn-soft: #e2b264;
  --v4-z4: #b89ad0;
  --v4-ink: #f2ede6;
  --v4-ink-rgb: 242, 237, 230;
  --v4-water: #8fb2c2;
  --v4-ink-2: rgba(242, 237, 230, 0.63);
  --v4-ink-3: rgba(242, 237, 230, 0.5);
  --v4-ink-4: rgba(242, 237, 230, 0.46);
  --v4-ink-30: rgba(242, 237, 230, 0.3);
  /* Три роли линии — см. комментарий в песочном наборе. Проценты одни на все
     четыре набора (v4-canvas.css, строка 5: роли объявлены один раз через
     rgba(var(--ink), …), а меняются только чернила). Разделитель тут был 12 %
     до 25.08 — приведён к контрактным 8 %. */
  --v4-line: rgba(242, 237, 230, 0.08);
  --v4-track: rgba(242, 237, 230, 0.12);
  --v4-edge: rgba(242, 237, 230, 0.18);
  --v4-plan: rgba(242, 237, 230, 0.22);
  --v4-plan-surface: #1a2327;
  --v4-plan-edge: rgba(143, 179, 194, 0.38);
  --v4-plan-act: #294e6b;
  --v4-btn-on-plan-act: #f2ede6;
  --v4-card: #23201b;
  /* Вторая поверхность (роль канваса --c2): дорожки ползунков, тихие пилюли,
     карточка «записано», выбранная строка принудительной оценки, кнопка
     «Позже» в листе куратора. Роль не была задана ни в одной палитре — семь
     мест использования подставляли литерал #efe3cf, то есть песочную вторую
     поверхность во всех наборах. Значения взяты из канваса; --v4-hero
     приведён к ним же 24.08 — в синих наборах он расходился с контрактом
     на волос. */
  --v4-chip: #2f2820;
  /* Тень листов и нажатых капсул (роль канваса --shadow, тройка RGB). */
  --v4-shadow-rgb: 0, 0, 0;
  --v4-chip-2: #2f2820;
  --v4-text: #f2ede6;
  --v4-muted: rgba(242, 237, 230, 0.58);
  --v4-border: rgba(242, 237, 230, 0.12);
  --v4-bg-secondary: #2f2820;
  /* Тёмные градации выведены из светлых: тот же оттенок, светлота подобрана
     под фон палитры (контраст к фону 3.4–7.5). Предварительные — тёмных
     версий градаций внимания дизайнер не присылал. */
  --v4-tint-warm: #cf8144;
  --v4-tint-cool: #8faa6d;
  --v4-float: #23201b;
  --v4-accent-bg: #3a2620;
  --v4-warn-1: #d39673;
  --v4-warn-2: #d07d4e;
  --v4-warn-3: #c9662c;
  --v4-bad-text: #e0704f;
  --v4-val-bad: #e08a72;
  /* Текстовый шаг предупреждения: между акцентом действия и «вниманием».
     Тон кнопки крупному числу не годится — на подложке героя он даёт 2,84:1,
     а крупный текст живёт по порогу 3:1 (контракт nutrition-tab, «цвет числа»). */
  --v4-warn-text: #d07d4e;
  /* Тонированная подложка-подсказка: плашка куратора и родственные ей. */
  --v4-tint: #3a241a;
  /* Капсула даты в прошлом дне. */
  /* Решение владельца 31 августа уточняет прежнее (12 августа, «painted modules
     keep warm look on every theme»): тёплое у героя остаётся во всех наборах,
     но выражается ролью героя --v4-hero-act, а не именем набора. Роль вида
     --v4-<набор>-* в модуле — ошибка по определению: модуль не должен знать,
     что палитра песочная, и синий обязан быть синим целиком. Семейство ниже
     остаётся для самих наборов и для мест, размеченных владельцем как
     геройские; новые вхождения в модулях ловит ui:v4:check, опись нынешних —
     docs/ui/UI_V4_SAND_ROLES_INVENTORY.md. */
  --v4-hero-act: #cf8144;
  --v4-macro-fat: #d9b96a;
  --v4-sand-act: #cf8144;
  --v4-sand-act-deep: #e2a468;
  --v4-sand-act-text: #e2a468;
  --v4-sand-act-mid: #e2a468;
  --v4-add: #d68d55; --v4-add-line: rgba(214,141,85,.34);
  --v4-sand-act-soft: #e2a468;
  --v4-sand-hero: #2f2820;
  --v4-sand-hero-cool: #2f2820;
  --v4-sand-hero-dark: #141210;
  --v4-sand-hero-night: #141210;
  --v4-sand-accent-bg: #3a2620;
  --v4-sand-surface: #23201b;
  --v4-sand-surface-soft: #141210;
  --v4-sand-wave-fill: #5c4a32;
  --v4-sand-ink: #f2ede6;
  --v4-sand-ink-deep: #1a0f04;
  --v4-sand-ink-slate: #f2ede6;
  --v4-sand-ok-text: #9fb981;
  --v4-sand-ok-fill: #8faa6d;
  --v4-sand-ok-fill-soft: #242c20;
  --v4-sand-tint: #3a2c20;
  --v4-sand-warn-bg: #3a2c20;
  --v4-wgt-emerald: #8faa6d;
  --v4-wgt-ok-deep: #9fb981;
  --v4-wgt-link: #cf8144;
  --v4-wgt-slate: #b5afa3;
  --v4-wgt-violet: #c49a78;
  --v4-wgt-danger-text: #c9662c;
  --v4-wgt-mint: #242c20;
  --v4-wgt-sky: #3a2c20;
  --v4-wgt-magenta: #cf9257;
  --v4-wgt-lilac: #23201b;
  --v4-wgt-amber: #cf9257;
  --v4-wgt-orange: #cf8144;
  --v4-wgt-rose: #2f2820;
  --v4-wgt-danger-bg: #3a2c20;
  --v4-wgt-cream: #2f2820;
  --v4-wgt-peach: #2f2820;
  --v4-wgt-teal: #9fb981;
  --v4-wgt-apple-green: #8faa6d;
  --v4-wgt-indigo: #c49a78;
  --v4-wgt-cyan: #8fb2c2;
  --v4-wgt-brown: #e2a468;
  --v4-wgt-purple: #c49a78;
  --v4-wgt-rust: #cf8144;
  --v4-wgt-gold: #cf9257;
  --v4-wgt-salmon: #d39673;
  --v4-wgt-yellow: #cf9257;
  --v4-wgt-apricot: #2f2820;
  --v4-wgt-coral: #d07d4e;
  --v4-wgt-lemon: #cf9257;
  --v4-btn-on-act: #201509; /* текст на терракотовой кнопке, канвас .pal.dk --on-acs (решение дизайнера 19.09) */
  /* Тёплый акцент нахлёста волн — строка контракта «волна · пересечение».
     Красным нахлёст не красится: это не ошибка, а факт про день. */
  --v4-overlay-fill: #c98a55;
  --v4-wave-overlap: #c98a55;
  --scrim: rgba(0, 0, 0, 0.62);
}

[data-theme-id="blue"],
[data-theme="blue"][data-palette="blue"] {
  /* История ступени данных в синем наборе. Пока роль звалась `--v4-ink-data` и
     выводилась из чернил набора (#101826), доля .56 давала 4,01 на --v4-bg,
     3,95 на --v4-c1 и 3,89 на --v4-chip — мелкий текст не проходил 4,5 ни на
     одной поверхности, а не только на чипе, как было сообщено; долю подняли до
     .64 (5,19 / 5,10 / 4,98). 7 сентября роль сняли: продукт перешёл на
     `--v4-ink-2`, которая в светлых наборах литерально чёрная. Доля этого
     набора — .61 ниже по файлу; замер даёт 6,01 / 5,75 / 5,64, то есть порог
     держится с бо́льшим запасом, чем прежние .64. Тёмно-синий набор не
     трогали: там 5,68 и 5,16, он проходит. */
  --v4-bg: #ffffff;
  /* Подложка сканера — тот же константный тёмный, что и в остальных трёх
     наборах (см. комментарий в песочном блоке). */
  --v4-scanner-bg: #141210;
  --v4-scanner-ink: #f2ede6;
  --v4-hero: #e2ecf6;
  --v4-surface: #eef3f9;
  --v4-c1: #eef3f9;
  --v4-md: #ffffff;
  --v4-ok-bg: #e6f3ec;
  --v4-wk-gr: #e6f3ec;
  --v4-mid-bg: #f7efd3;
  --v4-wk-weak: var(--v4-tint);
  --v4-act: #1d5e96;
  /* Плавающая кнопка затемнена относительно акцента: белый знак на
     #1d5e96 даёт 4,77, на #286da9 — 5,45. Пара обязательна, порознь не берётся. */
  --v4-fab: #286da9;
  --v4-on-fab: #ffffff;
  --v4-act-text: #1d5e96;
  --v4-ok-text: #1f6e4d;
  /* Тинт свайпа «Копировать» — канвасный --sage; не равен --v4-ok-bg
     (канвасный --gr-bg) — контракт «цвет свайп-действий». */
  --v4-ok-tint: #e3f0e8;
  --v4-ok-mid: #b9d8c9;
  --v4-on-ok-mid: #04231a;
  /* Чернила на шалфейном ТИНТЕ --v4-ok-tint — канвасный --sageTx. */
  --v4-on-ok: #1f4a34;
  /* Чернила на СПЛОШНОЙ заливке --v4-ok-fill — канвасный --on-gr
     (контракт «цвета» блока добавок). */
  --v4-on-ok-fill: #04231a;
  --v4-ok-fill: #4f9a78;
  --v4-good: #3e9a6b;
  --v4-warn-soft: #c0871c;
  --v4-z4: #6a4c9c;
  --v4-ink: #101826;
  --v4-ink-rgb: 16, 24, 38;
  --v4-water: #4c8fb8;
  /* 61 %, а не 55 %: решение дизайнера 7 сентября после независимого
     пересчёта по WCAG. Доля считается по САМОЙ ТЁМНОЙ поверхности набора, а
     не по фону: на --v4-hero #e2ecf6 при 55 % контраст был 3,77, при 61 % —
     4,53. Считая по --v4-bg (белому), порог формально проходил, а на
     карточке текст был нечитаем. */
  /* Ступени чернил и линии — на тройке набора --v4-ink-rgb (16, 24, 38), как
     в v4-canvas.css: на нейтральной 0,0,0 синий текст выходил серым (ответ
     дизайнера 19.09, UI_V4_FINDINGS_HISTORY#palette-product-vs-canvas-values). */
  --v4-ink-2: rgba(16, 24, 38, 0.61);
  --v4-ink-3: rgba(16, 24, 38, 0.45);
  --v4-ink-4: rgba(16, 24, 38, 0.38);
  --v4-ink-30: rgba(16, 24, 38, 0.3);
  /* Три роли линии — см. комментарий в песочном наборе. */
  --v4-line: rgba(16, 24, 38, 0.08);
  --v4-track: rgba(16, 24, 38, 0.12);
  --v4-edge: rgba(16, 24, 38, 0.18);
  --v4-plan: rgba(16, 24, 38, 0.22);
  --v4-plan-surface: #e6f2f4;
  --v4-plan-edge: rgba(55, 113, 139, 0.42);
  --v4-plan-act: #96b7ce;
  --v4-btn-on-plan-act: #101826;
  /* Сдержанная была янтарной (#e0a93e) — заменена 2026-08-10. Янтарный в этой
     палитре уже занят ролью мягкого внимания (шаги, профицит), поэтому первая
     градация вреда читалась не как слабая степень того же сигнала, а как
     другой сигнал. Три градации обязаны читаться как одно усиливающееся. */
  --v4-tint-warm: #2e7cc0;
  --v4-tint-cool: #3e9a6b;
  --v4-float: #ffffff;
  --v4-accent-bg: #d7e8f7;
  --v4-warn-1: #e59ea8;
  --v4-warn-2: #d9707e;
  --v4-warn-3: #a83246;
  --v4-bad-text: #b03a24;
  --v4-val-bad: #a8382b;
  /* Текстовый шаг предупреждения: между акцентом действия и «вниманием».
     Тон кнопки крупному числу не годится — на подложке героя он даёт 2,84:1,
     а крупный текст живёт по порогу 3:1 (контракт nutrition-tab, «цвет числа»). */
  --v4-warn-text: #b03a24;
  /* Тонированная подложка-подсказка: плашка куратора и родственные ей. */
  --v4-tint: #fbe6e2;
  /* Капсула даты в прошлом дне. */
  /* Решение владельца 31 августа уточняет прежнее (12 августа, «painted modules
     keep warm look on every theme»): тёплое у героя остаётся во всех наборах,
     но выражается ролью героя --v4-hero-act, а не именем набора. Роль вида
     --v4-<набор>-* в модуле — ошибка по определению: модуль не должен знать,
     что палитра песочная, и синий обязан быть синим целиком. Семейство ниже
     остаётся для самих наборов и для мест, размеченных владельцем как
     геройские; новые вхождения в модулях ловит ui:v4:check, опись нынешних —
     docs/ui/UI_V4_SAND_ROLES_INVENTORY.md. */
  --v4-hero-act: #c67139;
  --v4-macro-fat: #d9b96a;
  --v4-sand-act: #c67139;
  --v4-sand-act-deep: #8a4a20;
  --v4-sand-act-text: #8a4a20;
  --v4-sand-act-mid: #a75c2b;
  --v4-add: #1d5e96; --v4-add-line: rgba(29,94,150,.32);
  --v4-sand-act-soft: #e2a468;
  --v4-sand-hero: #efe3cf;
  --v4-sand-hero-cool: #e8ecf1;
  --v4-sand-hero-dark: #211e19;
  --v4-sand-hero-night: #0f172a;
  --v4-sand-accent-bg: #f0dcc6;
  --v4-sand-surface: #f7efe2;
  --v4-sand-surface-soft: #fffaf1;
  --v4-sand-ink: #201e1d;
  --v4-sand-ink-deep: #2b1608;
  --v4-sand-ink-slate: #1f2937;
  --v4-sand-ok-text: #5c6a45;
  --v4-sand-ok-fill: #7a8a5e;
  --v4-sand-ok-fill-soft: #dfe6d1;
  --v4-sand-tint: #f3e0d2;
  --v4-sand-warn-bg: #fef3c7;
  --v4-wgt-emerald: #3e9a6b;
  --v4-wgt-ok-deep: #1f6e4d;
  --v4-wgt-link: #2e7cc0;
  --v4-wgt-slate: #6b7c93;
  --v4-wgt-violet: #6a8fc4;
  --v4-wgt-danger-text: #a83246;
  --v4-wgt-mint: #e4efe7;
  --v4-wgt-sky: #d7e8f7;
  --v4-wgt-magenta: #e59ea8;
  --v4-wgt-lilac: #eef3f9;
  --v4-wgt-amber: #e0a93e;
  --v4-wgt-orange: #2e7cc0;
  --v4-wgt-rose: #eef3f9;
  --v4-wgt-danger-bg: #d7e8f7;
  --v4-wgt-cream: #e2edf7;
  --v4-wgt-peach: #e2edf7;
  --v4-wgt-teal: #1f6e4d;
  --v4-wgt-apple-green: #3e9a6b;
  --v4-wgt-indigo: #6a8fc4;
  --v4-wgt-cyan: #4c8fb8;
  --v4-wgt-brown: #1d5e96;
  --v4-wgt-purple: #6a8fc4;
  --v4-wgt-rust: #2e7cc0;
  --v4-wgt-gold: #e0a93e;
  --v4-wgt-salmon: #e59ea8;
  --v4-wgt-yellow: #e0a93e;
  --v4-wgt-apricot: #e2edf7;
  --v4-wgt-coral: #d9707e;
  --v4-wgt-lemon: #e0a93e;
  --v4-btn-on-act: #ffffff; /* на #1d5e96 — 4.77:1; решение food-meal 4 сентября */
  /* Тёплый акцент нахлёста волн — строка контракта «волна · пересечение».
     Красным нахлёст не красится: это не ошибка, а факт про день. */
  /* Первая поверхность (роль канваса --c1): карточки правок куратора, чипы и
     поля потока добавок, строки-ответы развилки. В тёмных наборах роль была
     задана, в светлых — нет, и туда подставлялся песочный литерал из
     var(--v4-card, #f3ece2): синий набор показывал кремовую поверхность. */
  --v4-card: #eef3f9;
  /* Вторая поверхность (роль канваса --c2): дорожки ползунков, тихие пилюли,
     карточка «записано», выбранная строка принудительной оценки, кнопка
     «Позже» в листе куратора. Роль не была задана ни в одной палитре — семь
     мест использования подставляли литерал #efe3cf, то есть песочную вторую
     поверхность во всех наборах. Значения взяты из канваса; --v4-hero
     приведён к ним же 24.08 — в синих наборах он расходился с контрактом
     на волос. */
  --v4-chip: #e2ecf6;
  /* Тень листов и нажатых капсул (роль канваса --shadow, тройка RGB). */
  --v4-shadow-rgb: 16, 24, 38;
  --v4-chip-2: #e2ecf6;
  --v4-overlay-fill: #b03a24;
  --v4-wave-overlap: #b03a24;
  --scrim: rgba(16, 24, 38, 0.45);
}

[data-theme-id="blue-dark"],
[data-theme="blue-dark"][data-palette="blue"] {
  --v4-bg: #0d1a26;
  /* Подложка сканера — тот же константный тёмный, что и в остальных трёх
     наборах (см. комментарий в песочном блоке). */
  --v4-scanner-bg: #141210;
  --v4-scanner-ink: #f2ede6;
  --v4-hero: #1e3448;
  --v4-surface: #182a3a;
  --v4-c1: #182a3a;
  --v4-md: #12222f;
  --v4-ok-bg: #16302a;
  --v4-wk-gr: #1c3d33;
  --v4-mid-bg: #38331f;
  --v4-wk-weak: #4a2c36;
  --v4-act: #3f8fd0;
  /* Плавающая кнопка затемнена относительно акцента: белый знак на
     #3f8fd0 даёт контраст выше порога, на #286da9 — 5,45. Пара обязательна. */
  --v4-fab: #286da9;
  --v4-on-fab: #ffffff;
  --v4-act-text: #7fbceb;
  --v4-ok-text: #7fd0a8;
  /* Тинт свайпа «Копировать» — канвасный --sage; не равен --v4-ok-bg
     (канвасный --gr-bg) — контракт «цвет свайп-действий». */
  --v4-ok-tint: #1d3328;
  --v4-ok-mid: #315b4c;
  --v4-on-ok-mid: #e8eef6;
  /* Чернила на шалфейном ТИНТЕ --v4-ok-tint — канвасный --sageTx. */
  --v4-on-ok: #a8dcc0;
  /* Чернила на СПЛОШНОЙ заливке --v4-ok-fill — канвасный --on-gr
     (контракт «цвета» блока добавок). */
  --v4-on-ok-fill: #052019;
  --v4-ok-fill: #6fbf9a;
  --v4-good: #4caf7d;
  --v4-warn-soft: #e6b567;
  --v4-z4: #b39ddb;
  --v4-ink: #e8eef6;
  --v4-ink-rgb: 232, 238, 246;
  --v4-water: #6fa8c8;
  --v4-ink-2: rgba(232, 238, 246, 0.63);
  --v4-ink-3: rgba(232, 238, 246, 0.5);
  --v4-ink-4: rgba(232, 238, 246, 0.46);
  --v4-ink-30: rgba(232, 238, 246, 0.3);
  /* Три роли линии — см. комментарий в песочном наборе. Разделитель тут был
     12 % до 25.08 — приведён к контрактным 8 %. */
  --v4-line: rgba(232, 238, 246, 0.08);
  --v4-track: rgba(232, 238, 246, 0.12);
  --v4-edge: rgba(232, 238, 246, 0.18);
  --v4-plan: rgba(232, 238, 246, 0.22);
  --v4-plan-surface: #112a33;
  --v4-plan-edge: rgba(127, 182, 208, 0.38);
  --v4-plan-act: #235272;
  --v4-btn-on-plan-act: #e8eef6;
  --v4-card: #182a3a;
  /* Вторая поверхность (роль канваса --c2): дорожки ползунков, тихие пилюли,
     карточка «записано», выбранная строка принудительной оценки, кнопка
     «Позже» в листе куратора. Роль не была задана ни в одной палитре — семь
     мест использования подставляли литерал #efe3cf, то есть песочную вторую
     поверхность во всех наборах. Значения взяты из канваса; --v4-hero
     приведён к ним же 24.08 — в синих наборах он расходился с контрактом
     на волос. */
  --v4-chip: #1e3448;
  /* Тень листов и нажатых капсул (роль канваса --shadow, тройка RGB). */
  --v4-shadow-rgb: 0, 0, 0;
  --v4-chip-2: #1e3448;
  --v4-text: #e8eef6;
  --v4-muted: rgba(232, 238, 246, 0.58);
  --v4-border: rgba(232, 238, 246, 0.12);
  --v4-bg-secondary: #1d3348;
  /* Тёмные градации выведены из светлых: тот же оттенок, светлота подобрана
     под фон палитры (контраст к фону 3.4–7.5). Предварительные — тёмных
     версий градаций внимания дизайнер не присылал. */
  --v4-tint-warm: #52a8e0;
  --v4-tint-cool: #4caf7d;
  --v4-float: #13222f;
  --v4-accent-bg: #1b3a54;
  --v4-warn-1: #d8838e;
  --v4-warn-2: #d05868;
  --v4-warn-3: #cc3347;
  --v4-bad-text: #f08a6a;
  --v4-val-bad: #e08a72;
  /* Текстовый шаг предупреждения: между акцентом действия и «вниманием».
     Тон кнопки крупному числу не годится — на подложке героя он даёт 2,84:1,
     а крупный текст живёт по порогу 3:1 (контракт nutrition-tab, «цвет числа»). */
  --v4-warn-text: #f0a08a;
  /* Тонированная подложка-подсказка: плашка куратора и родственные ей. */
  --v4-tint: #33242a;
  /* Капсула даты в прошлом дне. */
  /* Sand UI language: painted modules keep warm look on every theme
     (owner 2026-08-12: not shared --v4-act with warm fallback). Тёплый вид в
     тёмном наборе — это ТЁМНЫЕ тёплые значения, те же, что в sand-dark. Весь
     блок был копией светлого: --v4-sand-hero держал #efe3cf, --v4-sand-surface
     #f7efe2, --v4-sand-ink #201e1d — светлые плашки со светлыми чернилами
     поверх на тёмном экране (карточка подписки в профиле давала контраст 1,1).
     Сине-тёмная — единственный набор, где семейство не потемнело; 19 ролей
     приведены к sand-dark 31.08. --v4-sand-act-soft уже совпадал. */
  --v4-hero-act: #cf8144;
  --v4-macro-fat: #d9b96a;
  --v4-sand-act: #cf8144;
  --v4-sand-act-deep: #e2a468;
  --v4-sand-act-text: #e2a468;
  --v4-sand-act-mid: #e2a468;
  --v4-add: #7fbceb; --v4-add-line: rgba(127,188,235,.34);
  --v4-sand-act-soft: #e2a468;
  --v4-sand-hero: #2f2820;
  --v4-sand-hero-cool: #2f2820;
  --v4-sand-hero-dark: #141210;
  --v4-sand-hero-night: #141210;
  --v4-sand-accent-bg: #3a2620;
  --v4-sand-surface: #23201b;
  --v4-sand-surface-soft: #141210;
  --v4-sand-ink: #f2ede6;
  --v4-sand-ink-deep: #1a0f04;
  --v4-sand-ink-slate: #f2ede6;
  --v4-sand-ok-text: #9fb981;
  --v4-sand-ok-fill: #8faa6d;
  --v4-sand-ok-fill-soft: #242c20;
  --v4-sand-tint: #3a2c20;
  --v4-sand-warn-bg: #3a2c20;
  --v4-wgt-emerald: #4caf7d;
  --v4-wgt-ok-deep: #7fd1a0;
  --v4-wgt-link: #2e7cc0;
  --v4-wgt-slate: #94a8bc;
  --v4-wgt-violet: #6a8fc4;
  --v4-wgt-danger-text: #cc3347;
  --v4-wgt-mint: #17302a;
  --v4-wgt-sky: #1b3a54;
  --v4-wgt-magenta: #d8838e;
  --v4-wgt-lilac: #182a3a;
  --v4-wgt-amber: #e0a93e;
  --v4-wgt-orange: #2e7cc0;
  --v4-wgt-rose: #182a3a;
  --v4-wgt-danger-bg: #1b3a54;
  --v4-wgt-cream: #1d3348;
  --v4-wgt-peach: #1d3348;
  --v4-wgt-teal: #7fd1a0;
  --v4-wgt-apple-green: #4caf7d;
  --v4-wgt-indigo: #6a8fc4;
  --v4-wgt-cyan: #6fa8c8;
  --v4-wgt-brown: #8fc1e8;
  --v4-wgt-purple: #6a8fc4;
  --v4-wgt-rust: #2e7cc0;
  --v4-wgt-gold: #e0a93e;
  --v4-wgt-salmon: #d8838e;
  --v4-wgt-yellow: #e0a93e;
  --v4-wgt-apricot: #1d3348;
  --v4-wgt-coral: #d05868;
  --v4-wgt-lemon: #e0a93e;
  --v4-btn-on-act: #0b1621; /* на #3f8fd0 — 5.26:1; решение дизайнера 3 сентября (канвас .pal.bldk) */
  /* Тёплый акцент нахлёста волн — строка контракта «волна · пересечение».
     Красным нахлёст не красится: это не ошибка, а факт про день. */
  --v4-overlay-fill: #f0a08a;
  --v4-wave-overlap: #f0a08a;
  --scrim: rgba(0, 0, 0, 0.62);
}

/* Метки Б/Ж/У и подобные ряды «это другая штука» — не палитра по типу данных,
 * а три ступени чернил набора. Значения производные от --v4-ink, поэтому
 * следуют за палитрой сами и не требуют шести новых хексов
 * (решение владельца 2026-08-10, расформирование категорийных палитр).
 * Порядок ступеней — по величине нормы; различие несёт буква и подпись.
 */
:root {
  --v4-mark-1: color-mix(in srgb, var(--v4-ink, #111827) 62%, transparent);
  --v4-mark-2: color-mix(in srgb, var(--v4-ink, #111827) 45%, transparent);
  --v4-mark-3: color-mix(in srgb, var(--v4-ink, #111827) 28%, transparent);
  /* Product modal scrim (2026-08-16): один blur для чек-ина, настроек, куратора.
     Не плодить blur(4/7/8/12/18) на подложках product UI. Glass шапок/виджетов —
     вне этого инварианта.

     Затемнение — роль --scrim набора, объявленная в четырёх наборах выше
     (песочный 50 %, тёмный 62 %, синий 45 %, сине-тёмный 62 %). Алиасы
     --v4-modal-backdrop-dim и --v4-modal-backdrop-dim-dark сняты решением
     дизайнера 5 сентября: два имени одной роли расходились запасными
     значениями — по коду встречались .42, .55 и .62 у одного и того же
     затемнения, и какое из них увидит человек, зависело от того, какой файл
     писали последним. Отдельное «тёмное» имя роли теперь тоже лишнее: --scrim
     различается по набору сам, и переопределять его под [data-theme] не нужно.
     Перешедшие на роль правила оставлены как есть — они дают тот же цвет. */
  --v4-modal-backdrop-blur: 2.5px;
}

/* --v4-tint-warm / --v4-tint-cool — декоративные пятна фона экрана: радиальные
 * градиенты страницы дня и вкладки виджетов. Самая большая поверхность в
 * приложении, и до 2026-08-10 она была единственной, одинаковой во всех
 * наборах: оранжевый #ff9500 и синий #0a84ff зашиты литералами, поэтому в
 * песочной холодные пятна читались как чужие.
 *
 * Песочная и синяя берут собственную пару «тёплый акцент / холодный шалфей».
 * Геометрия и прозрачность градиентов не тронуты, меняется только оттенок.
 */

/* --v4-float — самая приподнятая поверхность, лежащая поверх контента:
 * плавающие кнопки, модалки, шторки. Роль настоящая, а не переиспользование:
 * маппинг переворачивается между светлыми и тёмными наборами. На светлом
 * «выше» значит светлее, и это грунт (--v4-bg); на тёмном «выше» значит
 * светлее фона, то есть карточка. Поэтому свести к одной существующей роли
 * нельзя — в blue-dark #13222f не совпадает вообще ни с чем.
 * Решение владельца 2026-08-10.
 */

/* HEYS.Toast — v4 sand surfaces (heys_toast_v1.js) */
#heys-toast-container {
  position: fixed;
  top: calc(72px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--v4-z-toast, 1100);
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
  pointer-events: none;
  width: min(360px, calc(100vw - 32px));
  max-width: calc(100vw - 32px);
}

.heys-toast {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  padding: 12px 14px;
  border-radius: 14px;
  pointer-events: auto;
  cursor: pointer;
  background: var(--v4-sand-surface-soft, #fffaf1);
  color: var(--v4-sand-ink, #201e1d);
  border: 1px solid color-mix(in srgb, var(--v4-sand-ink, #201e1d) 10%, transparent);
  box-shadow: 0 10px 28px rgba(33, 30, 25, 0.12);
  opacity: 0;
  transform: translateY(-12px);
  transition: opacity 300ms ease, transform 300ms cubic-bezier(0.22, 1, 0.36, 1);
}

.heys-toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.heys-toast.is-hiding {
  opacity: 0;
  transform: translateY(-8px);
}

.heys-toast__icon {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 700;
  line-height: 1;
  border-radius: 999px;
}

.heys-toast__content {
  flex: 1;
  min-width: 0;
}

.heys-toast__title {
  font-size: 14px;
  font-weight: 700;
  line-height: 1.35;
  margin-bottom: 2px;
}

.heys-toast__message {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.4;
  white-space: pre-line;
}

.heys-toast__action {
  flex-shrink: 0;
  padding: 6px 10px;
  border: 1px solid color-mix(in srgb, var(--v4-sand-ink, #201e1d) 12%, transparent);
  border-radius: 10px;
  background: var(--v4-sand-surface, #f7efe2);
  color: var(--v4-sand-ink-deep, #2b1608);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

/* Полоса времени у тоста с действием: окно отмены равно видимой полосе. */
.heys-toast__timer {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  border-radius: 0;
  background: color-mix(in srgb, var(--v4-sand-ink, #201e1d) 8%, transparent);
  overflow: hidden;
}

.heys-toast__timer i {
  display: block;
  height: 100%;
  width: 100%;
  transform-origin: left center;
  background: var(--v4-sand-act, #c67139);
  animation: heysToastTimer linear forwards;
}

@keyframes heysToastTimer {
  from { transform: scaleX(1); }
  to { transform: scaleX(0); }
}

.heys-toast--success {
  border-color: var(--v4-sand-ok-fill-soft, #dfe6d1);
}

.heys-toast--success .heys-toast__icon {
  color: var(--v4-sand-ok-fill, #7a8a5e);
  background: var(--v4-sand-ok-fill-soft, #dfe6d1);
}

.heys-toast--error {
  border-color: var(--v4-wgt-danger-bg, #fee2e2);
  background: var(--v4-sand-surface-soft, #fffaf1);
}

.heys-toast--error .heys-toast__icon {
  color: var(--v4-wgt-danger-text, #b91c1c);
  background: var(--v4-wgt-danger-bg, #fee2e2);
}

.heys-toast--warning {
  border-color: var(--v4-sand-warn-bg, #fef3c7);
}

.heys-toast--warning .heys-toast__icon {
  color: var(--v4-sand-act-deep, #8a4a20);
  background: var(--v4-sand-warn-bg, #fef3c7);
}

.heys-toast--info .heys-toast__icon,
.heys-toast--tip .heys-toast__icon {
  color: var(--v4-sand-act-mid, #a75c2b);
  background: var(--v4-sand-accent-bg, #f0dcc6);
}

body:has(.confirm-modal-backdrop) #heys-toast-container {
  display: none;
}

/* ── Крупный системный шрифт (home-widgets.v4.dc.html) ─────────────────────
 * tailwind base ставит -webkit-text-size-adjust:100% и гасит Android «Масштаб
 * текста». Файл грузится в index.html сразу после tailwind и снова из main.css. */
html {
  -webkit-text-size-adjust: auto;
  text-size-adjust: auto;
}

/* ── v4 держатель места (home-widgets «держатель места · правило продукта») ──
 * Ровная заливка --c1 без пульсации, скелетон-полос и спиннера внутри.
 * Появление данных — .v4-place-reveal (200 ms на месте, без сдвига). */
/* Табличные цифры. Строка «формат чисел · правило продукта»: цифры
   выравниваются в столбце «и включаются классом .n — это общий приём
   продукта, класс объявляется один раз для всех зон, а не в стилях
   экрана». Разметка его уже носила (heys_steps_v1.js:2633, :5016), а
   правила не было нигде — класс не делал ничего.

   Значение то же, что в v4-canvas.css:43. Двести тридцать одно место в
   продукте задаёт tabular-nums напрямую: строка их не запрещает, она
   требует, чтобы общий приём существовал и жил в одном месте. */
.n {
  font-variant-numeric: tabular-nums;
}

.v4-place-holder {
  background: var(--v4-c1, #f7efe2);
  animation: none;
  box-shadow: none;
}

.v4-place-reveal {
  animation: v4-place-reveal-in 200ms ease-out both;
}

@keyframes v4-place-reveal-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .v4-place-reveal {
    animation: none;
    opacity: 1;
  }
}
