/* qa-tools — дизайн-токены
   Источник правды по цвету, типографике, ритму и движению.
   Ни одного значения не вписывайте в компоненты напрямую: всё берётся отсюда.

   Тема переключается атрибутом на <html>:
     <html data-theme="dark">  или  <html data-theme="light"> */

/* ==========================================================================
   1. СЫРАЯ ПАЛИТРА — не зависит от темы
   ========================================================================== */
:root{
  --ink-1000:#07090b;--ink-950:#0b0e11;--ink-900:#101317;--ink-850:#16191e;--ink-800:#1b2026;
  --ink-750:#22272e;--ink-700:#2b3138;--ink-600:#363d45;--ink-500:#4a525c;--ink-400:#6b7480;
  --ink-300:#8f98a3;--ink-200:#b9c0c8;--ink-100:#dfe3e8;--ink-050:#f1f3f6;--ink-000:#ffffff;

  --blue-100:#d6efff;--blue-200:#9ddcff;--blue-300:#5fc6ff;--blue-400:#35b8ff;--blue-500:#1e9df0;
  --blue-600:#0f7fd1;--blue-700:#0a5f9e;--blue-800:#083f68;--blue-900:#06263f;

  --green-400:#3ddc97;--green-600:#17a673;--green-700:#0f7f57;
  --amber-400:#ffc046;--amber-600:#d99320;--amber-700:#a8710f;
  --red-400:#ff5d52;--red-600:#cf2f2a;
  --violet-400:#9d8cff;--violet-600:#6a55d6;

  /* Дисплейная гарнитура заголовков. Geologica: кириллица родная, характер
     технический и слегка узкий — не спорит с округлым Manrope и заметно
     отличается от него, в отличие от Onest, который на пробе оказался
     почти неотличим. Space Grotesk остался ЛОГОТИПУ и только ему:
     кириллицы в нём нет, а в логотипе одна латиница. */
  --font-display:"Geologica","Segoe UI",system-ui,sans-serif;
  --font-brand:"Space Grotesk","Segoe UI",system-ui,sans-serif;
  --font-ui:"Manrope","Segoe UI",system-ui,sans-serif;
  --font-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;

  /* Размер текста. Все кегли идут через --fs-scale, поэтому регулятор в
     шапке — одна переменная, а не набор правил на каждый компонент.
     Множитель, а не переопределение font-size на :root, потому что кегли
     заданы в px: сохраняется точное соотношение между уровнями. */
  --fs-scale:1;
  /* Кегль заголовка страницы. Заведён отдельно от --text-title-1 после
     сверки с эталоном (design/bar.md): заголовок был крупнее основного
     текста всего в 1.5 раза, у Supabase 4.5, у Neon 5, у AuthKit 3.
     48/16 даёт ровно трёхкратную разницу — нижнюю границу планки. */
  /* design-bold (2026-09-06): шкала сжата. 48px на странице инструмента
     отодвигал рабочую область на экран вниз; заголовок здесь — подпись к
     работе, а не афиша. 36/28/20/16 — четыре ступени, каждая заметно
     отличается от соседней, и ни одна не спорит с полем ввода. */
  --text-display:calc(36px * var(--fs-scale));
  --text-title-1:calc(28px * var(--fs-scale));   /* заголовок инструмента */
  --text-title-2:calc(20px * var(--fs-scale));   /* приглашение поиска */
  --text-title-3:calc(16px * var(--fs-scale));
  --text-search:calc(20px * var(--fs-scale));    /* строка поиска в каталоге */
  --text-brand:calc(19px * var(--fs-scale));     /* логотип */
  --text-body-lg:calc(16px * var(--fs-scale));
  --text-body:calc(15px * var(--fs-scale));
  --text-body-sm:calc(14px * var(--fs-scale));
  --text-caption:calc(13px * var(--fs-scale));
  --text-micro:calc(12px * var(--fs-scale));

  --fw-regular:400;--fw-medium:500;--fw-semibold:600;--fw-bold:700;
  --ls-title:-.01em;--ls-label:.02em;--ls-caps:.10em;

  --space-1:2px;--space-2:4px;--space-3:6px;--space-4:8px;--space-5:12px;
  --space-6:16px;--space-7:20px;--space-8:24px;--space-9:32px;--space-10:40px;
  --space-11:56px;--space-12:80px;

  /* Радиусов ровно три значения, а не пять: 6px для мелких элементов,
     14px для карточек и панелей, пилюля для кнопок и меток. Раньше было
     4, 6, 10, 14 — четыре почти неразличимых на глаз ступени, из-за
     которых форма выглядела случайной. Имена токенов оставлены прежними,
     чтобы не переписывать компоненты. */
  --radius-sm:6px;--radius-md:6px;--radius-lg:14px;--radius-card:14px;--radius-pill:999px;

  /* design-bold: два уровня тени. Панель лежит НА холсте, а не рядом с
     ним, и одной границы для этого мало на тёмном: --shadow-1 — едва
     заметный отрыв, --shadow-2 — для того, что висит поверх страницы
     (палитра). Больше двух уровней не заводим. */
  --shadow-1:0 1px 2px rgba(0,0,0,.28),0 10px 28px -14px rgba(0,0,0,.55);
  --shadow-2:0 16px 48px rgba(0,0,0,.30);
  /* Ширина колонки инструментов на странице инструмента (js/palette.js) */
  --rail-w:236px;

  /* Фон плоский. Был радиальный градиент с синевой в верхней точке плюс
     три слоя летящих звёзд — «космос», который читался как заставка, а не
     как рабочий инструмент. Ни у одного из трёх эталонов фонового движения
     нет, а Supabase и Neon вообще держат ровную заливку: глубину дают
     светлые карточки на тёмном холсте и заметные границы, а не градиент.
     Оба цвета живут здесь, а не в темах: слои перекрёстно гаснут (см. .sky). */
  --sky-dark:#0b0e11;
  /* design-bold: светлая тема — тёплая бумага, а не холодный серый.
     Холодный #eef1f5 рядом с белыми карточками читался как «выключенный
     экран»; тёплый оттенок даёт карточкам контраст без тени. */
  --sky-light:#f4f2ed;

  --dur-fast:140ms;--dur-base:200ms;--dur-slow:320ms;--dur-theme:340ms;
  --ease-standard:cubic-bezier(.2,0,.2,1);
  --ease-emphasis:cubic-bezier(.2,.8,.2,1);
  --ease-spring:cubic-bezier(.34,1.56,.64,1);
  --ease-theme:cubic-bezier(.76,.05,.24,.95);

  --sidebar-w:216px;
  --gutter-page:40px;
  /* Рабочее пространство тянется на всю ширину окна: инструменты здесь —
     редакторы и таблицы, им ширина в плюс, в отличие от текста статьи.
     Отдельные текстовые блоки (.toolhead__sub, .foot p) держат свой
     max-width, чтобы строка не растягивалась до нечитаемой длины. */
  --maxw-content:100%;
}

/* Шаги регулятора. По умолчанию выбран КРУПНЫЙ: базовые кегли рассчитаны
   на плотный экран, а на 27" 2K обычного не хватало. Обычный и мелкий
   остались для тех, кому крупный великоват.
   Обычный шаг не пишет атрибут — это значение по умолчанию в CSS, но
   выбран при первом заходе не он, а «l» (см. initFontSize и инлайн-скрипт
   в <head> каждой страницы). */
:root[data-fontsize="s"]{--fs-scale:.92}
:root[data-fontsize="l"]{--fs-scale:1.32}

/* ==========================================================================
   2. СЕМАНТИКА — тёмная тема (родная для дизайн-системы)
   ========================================================================== */
:root,[data-theme="dark"]{
  --surface-app:var(--ink-950);
  --surface-chrome:rgba(11,14,17,.86);
  --surface-card:var(--ink-850);
  --surface-card-hover:var(--ink-800);
  --surface-input:var(--ink-900);
  --surface-hover:rgba(255,255,255,.04);
  --surface-selected:rgba(53,184,255,.10);

  /* Значения заданы явно, а не взяты из ink-шкалы: шкала равномерна по
     светлоте, а нужна равномерность по КОНТРАСТУ к тёмному фону —
     это разные вещи, и внизу шкалы шаги получались слишком тусклыми.
     Основная проза (описание инструмента, пояснялки, подвал, третья
     колонка таблиц) живёт на --text-faint, поэтому его подняли сильнее
     всего: 6:1 на 13px читались тяжело даже на большом мониторе.
     Заголовки не трогали — с ними проблем и не было. */
  --text-heading:var(--ink-000);   /* ~17:1 */
  --text-body:#e8ecf1;             /* ~14:1 */
  --text-muted:#d3dae2;            /* ~11:1 */
  --text-faint:#bcc5cf;            /* ~9:1  — было ~6:1 */
  --text-ghost:#98a1ac;            /* ~6:1  — было ~3.7:1 */

  /* Граница карточки поднята с .06 до .11: при .06 карточки почти сливались
     с холстом. У Supabase это #2e2e2e на #121212 — примерно .12 в наших
     терминах. Там, где нет теней, всю работу по отделению поверхностей
     делает именно граница. */
  --border-hairline:rgba(255,255,255,.11);
  --border-subtle:rgba(255,255,255,.16);
  --border-accent:rgba(53,184,255,.55);

  --accent:var(--blue-400);
  --accent-text:var(--blue-300);
  --accent-quiet:rgba(53,184,255,.14);
  /* Заливка под текстом и текст поверх неё. Отдельно от --accent, потому
     что у акцента задача быть заметным штрихом, а у заливки — держать
     контраст с текстом: в светлой теме для этого нужен ещё более тёмный
     синий, чем сам акцент. */
  --accent-fill:var(--blue-400);
  --on-accent:#04121c;

  /* Свечения погашены. Синий блик в углу карточки и ореол вокруг активного
     фильтра — это ровно «glow ради glow» из каталога слопа: у эталонов
     теней и свечений нет вовсе, поверхности разделяются границей.
     Переменные оставлены, чтобы не переписывать компоненты. */
  --glow-accent-soft:none;
  --glow-marker:none;
  --glow-dot:none;
  --card-sheen:none;
  --marker-fill:linear-gradient(145deg,rgba(255,255,255,.10),rgba(255,255,255,.02));
  --marker-border:rgba(255,255,255,.15);
  --marker-topline:rgba(255,255,255,.8);

  --dot-data:var(--blue-400);--dot-format:var(--green-400);--dot-text:var(--amber-400);
  --dot-web:var(--violet-400);--dot-ui:var(--red-400);--dot-ref:var(--ink-400);
  --dot-all:var(--ink-300);

  --ok-fg:var(--green-400);--ok-bg:rgba(61,220,151,.10);--ok-br:rgba(61,220,151,.30);
  /* Пара к --ok-*: «плохое» состояние — удалённые строки в /diff. Токенов
     не было, и удалённое рисовалось без цвета: css/tools/diff.css ссылался
     на --bad-*, которых никто не завёл. Поймано 2026-09-02. */
  --bad-fg:var(--red-400);--bad-bg:rgba(255,93,82,.12);--bad-br:rgba(255,93,82,.32);

  /* Вторая подсветка — для случая, когда два выделенных куска стоят
     ВПЛОТНУЮ и одним цветом слились бы в одно пятно. Заведена для
     совпадений в /regex: там от этого зависит, видно ли, что шаблон
     захватил больше нужного. Живёт здесь, а не в css/tools/regex.css,
     потому что цвет обязан переключаться вместе с темой — в компоненте
     он был бы одинаковым на обеих и на светлой читался бы плохо. */
  --mark-alt-fill:rgba(157,140,255,.18);--mark-alt-line:rgba(157,140,255,.45);
  --mark-alt-text:var(--violet-400);

  /* фон-небо: сам градиент — в сырой палитре (--sky-dark/--sky-light),
     здесь только частицы */
  color-scheme:dark;
}

/* ==========================================================================
   3. СЕМАНТИКА — светлая тема
   Не инверсия: фон холодно-серый, а не белый, иначе карточки исчезают.
   Акцент уходит на два шага темнее — #35b8ff на белом не читается.
   Свечения гасятся почти полностью: неон на светлом выглядит как дефект.
   ========================================================================== */
[data-theme="light"]{
  --surface-app:#f4f2ed;
  --surface-chrome:rgba(250,249,246,.9);
  --shadow-1:0 1px 2px rgba(7,9,11,.06),0 10px 28px -14px rgba(7,9,11,.18);
  --shadow-2:0 16px 48px rgba(7,9,11,.16);
  --surface-card:var(--ink-000);
  --surface-card-hover:var(--ink-000);
  --surface-input:var(--ink-000);
  --surface-hover:rgba(7,9,11,.04);
  --surface-selected:rgba(15,127,209,.10);

  /* Симметрично тёмной теме: каждый уровень на ступень темнее прежнего.
     На светло-сером фоне #eef1f5 прежние значения тоже сидели ниже
     комфортного порога. */
  --text-heading:#07090b;
  --text-body:#22272e;
  --text-muted:#363d45;
  --text-faint:#4a525c;
  --text-ghost:#6b7480;

  --border-hairline:rgba(7,9,11,.14);
  --border-subtle:rgba(7,9,11,.20);
  --border-accent:rgba(15,127,209,.55);

  --accent:var(--blue-600);
  --accent-text:var(--blue-700);
  --accent-quiet:rgba(15,127,209,.10);
  --accent-fill:var(--blue-700);
  --on-accent:#ffffff;

  --glow-accent-soft:none;
  --glow-marker:none;
  --glow-dot:none;
  --card-sheen:none;
  --marker-fill:linear-gradient(145deg,rgba(15,127,209,.14),rgba(15,127,209,.06));
  --marker-border:rgba(15,127,209,.28);
  --marker-topline:rgba(255,255,255,.9);

  --dot-data:var(--blue-600);--dot-format:var(--green-700);--dot-text:var(--amber-700);
  --dot-web:var(--violet-600);--dot-ui:var(--red-600);--dot-ref:var(--ink-500);
  --dot-all:var(--ink-500);

  --ok-fg:var(--green-700);--ok-bg:rgba(15,127,87,.09);--ok-br:rgba(15,127,87,.28);
  --bad-fg:var(--red-600);--bad-bg:rgba(207,47,42,.09);--bad-br:rgba(207,47,42,.28);

  --mark-alt-fill:rgba(106,85,214,.14);--mark-alt-line:rgba(106,85,214,.38);
  --mark-alt-text:var(--violet-600);

  /* фон-небо: днём только мягкий градиент (--sky-light в сырой палитре).
     Частицы на светлом либо не видны, либо выглядят как грязь на экране —
     середины тут нет, поэтому слой гасится в ноль.
     Разметка и генератор остались: включается одной строкой. */
  color-scheme:light;
}
/* Гасим плавно, а не display:none — иначе частицы пропадали мгновенно,
   пока фон под ними ещё ехал. Прозрачный слой браузер не рисует, а
   пауза снимает нагрузку от трёх анимаций, которых всё равно не видно. */
[data-theme="light"] .stars{animation-play-state:paused}
