/* ============================================================================
   WaifuHunt — tokens.css
   Единственный источник цветов, кеглей, отступов и движения.
   ПРАВИЛО: в коде интерфейса не должно быть ни одного литерального hex,
   ни одного произвольного font-size, ни одного произвольного отступа.
   Всё только через var(--...). Проверяется автоматически (см. ТЗ).
   ============================================================================ */

:root {
  /* ==========================================================================
     1. ПОВЕРХНОСТИ — лестница глубины тёмной темы
     Чистый #000 не используется: на нём теряются тени и границы, и глаз
     читает интерфейс как «дыру». Самый тёмный уровень — тонированный.
     ========================================================================== */
  --bg-void:        #05050a;   /* фон за оверлеями, самый низ */
  --bg-base:        #0a0810;   /* основной фон страницы и панелей */
  --bg-raised:      #0e0b14;   /* приподнятая поверхность: тулбары, шапки */
  --bg-panel:       #120f18;   /* карточки, поля ввода, вложенные блоки */
  --bg-hover:       #171320;   /* наведение на поверхность */
  --bg-active:      #1d1828;   /* нажатое / выбранное состояние */
  --bg-inset:       #07060c;   /* утопленное: ниши, шкалы, скроллы */

  /* Границы — три уровня, больше не нужно */
  --line-subtle:    rgba(255,255,255,0.07);  /* разделители внутри блока */
  --line:           rgba(255,255,255,0.12);  /* граница блока */
  --line-strong:    rgba(255,255,255,0.22);  /* граница интерактивного элемента */

  /* Текст — четыре уровня. Пятого не заводить. */
  --ink:            #ffffff;                 /* заголовки, ключевые значения */
  --ink-2:          rgba(255,255,255,0.72);  /* основной текст */
  --ink-3:          rgba(255,255,255,0.48);  /* второстепенный, подписи */
  --ink-4:          rgba(255,255,255,0.30);  /* служебный: даты, счётчики */
  /* ⚠️ Ничего светлее --ink-4 на тексте не использовать: на --bg-panel это
     уже ниже порога читаемости. Проверять контраст по APCA, не по WCAG 2 —
     на тёмных фонах WCAG 2 систематически завышает оценку. */

  /* ==========================================================================
     2. АКЦЕНТ ИНТЕРАКЦИИ — одна шкала, одно значение
     Это ЕДИНСТВЕННЫЙ цвет интерфейсных действий: ссылки, фокус, активная
     вкладка, первичная кнопка, выбранный чип.
     ⚠️ Он НЕ обозначает редкость. Редкость выражается металлом (см. 3).

     2026-08-09: акцент переведён с розового на ЛАТУНЬ. Причина не вкусовая:
     сайт говорит языком собственной игры, а в зале гильдии розового нет
     вовсе — действия там латунные (ручки ящиков, окантовка стойки), и
     розовый на этом фоне читался посторонним, «киберпанковым». Значения
     сняты пиксельно с арта: assets/guild/hall/bg.webp и cabinet-open-art.webp.

     ⚠️ РАЗВЕДЕНИЕ С МЕТАЛЛАМИ (см. 3). Латунь намеренно ТЕМНЕЕ и КОРИЧНЕВЕЕ
     светлого золота жетонов (--rank-d #e8c065, --rank-founder #e0b45f):
     латунь = интеракция, светлое золото = печать и ранг. Если сравнять их
     по светлоте, кнопка станет неотличима от жетона — как это и было
     задумано разведено ещё на этапе 2.
     ========================================================================== */
  --accent-1:       #241a0c;   /* тонкий фон акцентного блока */
  --accent-2:       #33260f;   /* фон акцентного блока, наведение */
  --accent-3:       #4a3714;   /* нажатое состояние акцентного блока */
  --accent-line:    #8a5f2c;   /* граница акцентного элемента */
  --accent-focus:   #febb6d;   /* ФОКУС-РИНГ. Только для этого. */
  --accent:         #bd8843;   /* сплошной акцент: кнопка, активная вкладка */
  --accent-hover:   #d5a057;   /* наведение на сплошной акцент */
  --accent-ink:     #241703;   /* текст ПОВЕРХ сплошного акцента */
  --accent-text:    #e7bb7c;   /* акцентный ТЕКСТ на тёмном фоне */

  /* ==========================================================================
     3. РЕДКОСТЬ = МЕТАЛЛ ЖЕТОНА
     Ранг карточки совпадает с рангом гильдии, а у каждого ранга в
     backend/services/guild.js уже задан свой жетон. Поэтому редкость
     выражается материалом оправы, а не цветной полоской — и не конфликтует
     с акцентом интеракции.
     ⚠️ ИСПРАВЛЕНИЕ ОШИБКИ МАКЕТОВ: в макетах металлы были расставлены
     произвольно (алмаз на SS, золото на S). По guild.js порядок другой.
     Ниже — правильный.
     ========================================================================== */
  --rank-g:   #5c6067;   /* Железный жетон   · Кандидат */
  --rank-f:   #a5763d;   /* Бронзовый жетон  · Новичок */
  --rank-e:   #cdd3da;   /* Серебряный жетон · Ученик */
  --rank-d:   #e8c065;   /* Золотой жетон    · Охотник */
  --rank-c:   #e6ecef;   /* Платиновый жетон · Опытный */
  --rank-b:   #f0d8ea;   /* Алмазный жетон   · Старший охотник */
  --rank-a:   #c9a2ef;   /* Мифический жетон · Элитный охотник */
  --rank-s:   #f6dd93;   /* Легендарный жетон · Легенда гильдии */
  --rank-ss:  #ffffff;   /* SS — НЕ металл, см. ниже */
  --rank-founder: #e0b45f; /* Печать основателя — служебный, не в охоте */

  /* Градиенты пластин: металл рисуется не одним цветом, а бликом.
     Это то, что делает жетон похожим на металл без единой картинки. */
  --plate-g:   linear-gradient(138deg,#5c6067,#31343a 34%,#6b7078 52%,#282b30 74%,#4d5157);
  --plate-f:   linear-gradient(138deg,#a5763d,#5c3f1e 34%,#c99356 52%,#4d3418 74%,#8a6132);
  --plate-e:   linear-gradient(138deg,#cdd3da,#7d848d 34%,#eef2f6 52%,#6c737c 74%,#b4bbc3);
  --plate-d:   linear-gradient(138deg,#e8c065,#8f6d22 34%,#f8e2a0 52%,#7d5d1a 74%,#d0a445);
  --plate-c:   linear-gradient(138deg,#e6ecef,#9aa4ad 34%,#fbfdff 52%,#8b959f 74%,#ccd4da);
  --plate-b:   linear-gradient(138deg,#f0d8ea,#a877a0 30%,#ffffff 48%,#c78fbd 62%,#e9c4e0);
  --plate-a:   linear-gradient(138deg,#c9a2ef,#6b4499 32%,#efe0ff 50%,#5c3a86 72%,#a882dc);
  --plate-s:   linear-gradient(138deg,#f6dd93,#9c7318 30%,#fffbe8 48%,#8a6413 70%,#e3c464);
  /* SS не выдаётся Гильдией — это личное касание Заступника. Поэтому у SS
     не металл, а свет: видно, что объект вне ладдера гильдейских жетонов. */
  --plate-ss:  radial-gradient(ellipse at 38% 30%, #ffffff, #ffe9fb 34%, #d8a9ee 62%, #8f6bb5 100%);

  /* ==========================================================================
     4. СЕМАНТИКА — состояние, не редкость и не роль
     ========================================================================== */
  --ok:         #8fd6a8;   --ok-line:   rgba(143,214,168,0.42);   --ok-bg:   rgba(143,214,168,0.07);
  --warn:       #e0b45f;   --warn-line: rgba(224,180,95,0.42);    --warn-bg: rgba(224,180,95,0.06);
  --danger:     #e08b95;   --danger-line: rgba(224,139,149,0.45); --danger-bg: rgba(224,139,149,0.06);
  --info:       #8fb3e8;   --info-line: rgba(143,179,232,0.42);   --info-bg: rgba(143,179,232,0.06);
  /* ⚠️ Дубли из макетов схлопнуты: было два зелёных (#8fd6a8/#7fbf7f),
     два «опасных» (#e08b95/#e08f8f), два сиреневых (#b28fe8/#c9a2ef). */

  /* ==========================================================================
     5. РОЛИ ПЕРСОНАЛА — четвёртая независимая шкала
     ========================================================================== */
  --role-owner:   #e0b45f;
  --role-gm:      #b28fe8;
  --role-editor:  #8fd6a8;
  --role-moder:   #8fb3e8;
  --role-user:    rgba(255,255,255,0.11);

  /* ==========================================================================
     6. ВАЛЮТЫ — у каждой свой цвет, чтобы не путались в ценах
     ========================================================================== */
  --cur-marka:    #cdd3da;   /* Марки — серебряная бумага гильдии */
  --cur-pechat:   #e79bd6;   /* Печати Зова — донат */
  --cur-krupica:  #ffe9fb;   /* Крупицы Благодати — свет */

  /* ==========================================================================
     7. ТИПОГРАФИКА
     Три роли, не больше. Четвёртая (mono) только для цифр и служебных ID.
     ========================================================================== */
  /* Гарнитуры выбраны 2026-08-09 по единственному жёсткому критерию: КИРИЛЛИЦА.
     До этого стояли Fraunces (дисплей) и Cinzel (капитель) — в обеих гарнитурах
     кириллических глифов нет вовсе, поэтому весь русский заголовочный слой
     сайта рендерился системной Georgia (гейт 1 slop-теста — авто-провал).
     Латиница тянулась из waifuhunt-archive.css, где так и подписана:
     «Latin display», «Latin UI».
     ⚠️ Любая новая гарнитура проверяется на покрытие ДО попадания сюда:
     запросить у поставщика css2 с параметром family и убедиться, что в ответе
     есть сабсет `cyrillic`. Нет его — гарнитура не годится, как бы красиво она
     ни выглядела в образце на латинице. */
  --font-display: 'Old Standard TT', Georgia, 'Times New Roman', serif;
  --font-label:   'Forum', Georgia, serif;
  --font-body:    'Manrope', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:    'JetBrains Mono', ui-monospace, monospace;
  /* ⚠️ Arial из стеков убран — он протёк в profile-unified-v9.
     ⚠️ Inter убран из стека тела: он дефолт №1 того же гейта, а Manrope
     самохостится с полной кириллицей и характернее. */

  /* Шкала кеглей — 9 ступеней, fluid. Больше ступеней не заводить.
     В макетах было 19 разных кеглей на одной странице; это и есть
     отсутствие шкалы. */
  --t--2: clamp(0.625rem, 0.61rem + 0.08vw, 0.6875rem);   /* 10–11 · служебное */
  --t--1: clamp(0.6875rem, 0.66rem + 0.13vw, 0.75rem);    /* 11–12 · подписи */
  --t-0:  clamp(0.8125rem, 0.79rem + 0.13vw, 0.875rem);   /* 13–14 · основной текст */
  --t-1:  clamp(0.9375rem, 0.91rem + 0.16vw, 1rem);       /* 15–16 · крупный текст */
  --t-2:  clamp(1.125rem, 1.08rem + 0.25vw, 1.25rem);     /* 18–20 · заголовок блока */
  --t-3:  clamp(1.3125rem, 1.24rem + 0.38vw, 1.5rem);     /* 21–24 · заголовок панели */
  --t-4:  clamp(1.625rem, 1.5rem + 0.63vw, 2rem);         /* 26–32 · заголовок экрана */
  --t-5:  clamp(2rem, 1.75rem + 1.25vw, 2.75rem);         /* 32–44 · герой раздела */
  --t-6:  clamp(2.5rem, 1.9rem + 3vw, 4rem);              /* 40–64 · герой главной */

  /* Начертания — четыре, не восемь */
  --w-normal: 400;
  --w-medium: 500;
  --w-semi:   600;
  --w-bold:   700;

  /* Межстрочное. У заголовков строго меньше, чем у текста. */
  --lh-flat:  1;      /* однострочные подписи: кнопка, жетон, чип */
  --lh-tight: 1.15;   /* заголовки от --t-4 и выше */
  --lh-snug:  1.3;    /* --t-2 … --t-3 */
  --lh-body:  1.6;    /* основной текст */
  --lh-loose: 1.8;    /* длинные документы: legal, лор, работы игроков */

  /* Трекинг. Cinzel-лейблы всегда с разрядкой, иначе капслок читается кашей. */
  --ls-label: 0.12em;
  --ls-kicker: 0.2em;
  --ls-tight: -0.015em;   /* только для --t-5 и --t-6 */

  --measure: 68ch;        /* максимальная длина строки текста */

  /* ⚠️ Fraunces: обязательно задавать font-variation-settings 'opsz' под
     ступень, иначе браузер берёт дефолт и характер шрифта пропадает.
     См. правило в ТЗ. */

  /* ==========================================================================
     8. ОТСТУПЫ — база 4px. Значений всего 10.
     В макетах было 27 разных значений отступов на одной странице.
     ========================================================================== */
  --s-0:  0;      /* «отступа нет» — тоже решение, и оно тоже пишется токеном */
  --s-1:  4px;
  --s-2:  8px;
  --s-3:  12px;
  --s-4:  16px;
  --s-5:  20px;
  --s-6:  24px;
  --s-8:  32px;
  --s-10: 40px;
  --s-14: 56px;
  --s-20: 80px;

  /* ==========================================================================
     9. РАДИУСЫ, ТЕНИ, СЛОИ
     Проект намеренно почти без закруглений — это часть характера.
     ========================================================================== */
  --r-0:  0;
  --r-1:  2px;
  --r-2:  4px;
  /* Кнопка — исключение из «почти без закруглений»: скругление 10px принято
     заказчиком 2026-08-09 (вариант Б парного сравнения). Прежние 2px читались
     заготовкой из генератора лендингов. Только для .button. */
  --r-btn: 10px;
  --r-pill: 999px;   /* только для тумблеров и круглых кнопок */

  --sh-1: 0 4px 12px rgba(0,0,0,0.45);
  --sh-2: 0 10px 26px rgba(0,0,0,0.55);
  --sh-3: 0 20px 46px rgba(0,0,0,0.62);
  --sh-4: 0 34px 84px rgba(0,0,0,0.72);   /* оверлей */
  --sh-inset: inset 0 2px 10px rgba(0,0,0,0.7);
  /* Жетон ранга: тёмный контур + верхний блик. Металл задаёт --plate-*,
     а объём — вот эта тень; иначе кружок читается цветной точкой. */
  --sh-plate: 0 0 0 1px rgba(0,0,0,0.55), inset 0 1px 0 rgba(255,255,255,0.18);
  /* Виньетка полотна во всю ширину: край кадра гасится, взгляд идёт к центру.
     Только для полноэкранного арта, к панелям не применять. */
  --sh-vignette: inset 0 0 200px 60px rgba(5,5,10,0.9);

  /* Затемнения ПОВЕРХ изображения (scrim). Текст никогда не лежит на сыром
     арте (ТЗ §5.1) — под ним всегда одна из этих ступеней. Заводить новые
     значения затемнения в страницах запрещено: их станет девять. */
  --scrim-top:   rgba(5,5,10,0.55);   /* верх кадра: шапка не спорит с артом */
  --scrim-clear: rgba(5,5,10,0.12);   /* середина: арт виден почти как есть */
  --scrim-deep:  rgba(5,5,10,0.82);   /* низ: подложка под текст и кнопки */

  /* ==========================================================================
     9б. МАТЕРИАЛЫ ЗАЛА
     Сайт говорит языком собственной игры: у ZZZ сайт похож на HUD ZZZ, у
     Arknights — на терминал Arknights, и узнаются они поэтому, а не потому,
     что «красиво». Наш игровой экран — зал гильдии, значит материалы берутся
     оттуда. Значения СНЯТЫ ПИКСЕЛЬНО с арта художника: assets/guild/hall/
     bg.webp (стойка, стена, свет лампы) и cabinet-open-art.webp (картотека).

     ⚠️ Живопись НЕ подделывается градиентами: дерево полосками даёт красный
     пластик со штрих-кодом, пурпур светлой заливкой — фиолетовый. Если
     материал нарисован — берём файл (нижняя треть bg.webp и есть столешница),
     а эти токены держат ТОН вокруг него: подложки, кромки, чернила.
     Отменено 2026-08-09: «камень со сколом» (--stone/--niche/--clip-chip) —
     выдуманная эстетика, к нашей игре отношения не имела.
     ========================================================================== */
  --wood:        #4b1d1f;   /* столешница стойки, средняя */
  --wood-lit:    #682b28;   /* столешница под лампой */
  --wood-deep:   #2a1010;   /* тень дерева, подложка полосы */
  --wall:        #231924;   /* стена зала */
  --wall-deep:   #18111f;   /* глубина полок */
  --plum:        #2c032e;   /* картотека, основа */
  --plum-lit:    #4b1142;   /* картотека, ребро под светом */
  --plum-deep:   #1d0121;   /* картотека, тень */
  --brass:       #9b6a46;   /* латунь, основа */
  --brass-hi:    #f4c6ac;   /* блик латуни */
  --brass-lo:    #64470f;   /* латунь в тени */
  --lamp:        #fcf5ea;   /* свет лампы: заголовки в зале */
  --lamp-2:      rgba(252,245,234,0.76);  /* основной текст в зале */
  --lamp-3:      rgba(252,245,234,0.5);   /* подписи в зале */
  --lamp-4:      rgba(252,245,234,0.34);  /* служебное в зале */

  /* Бумага регистра — предмет НА поверхности, а не поле во всю страницу. */
  --leaf:        #ded0ae;
  --leaf-lo:     #bfae86;
  --leaf-hi:     #f6ecd3;
  --leaf-ink:    #2a2015;
  --leaf-ink-2:  rgba(42,32,21,0.72);
  --leaf-ink-3:  rgba(42,32,21,0.5);
  --leaf-line:   rgba(42,32,21,0.18);
  --leaf-edge:   rgba(96,74,40,0.32);     /* потемнение по периметру листа */

  /* Шум генерит браузер, файлов на диске нет; img-src data: разрешён в
     src/data/csp.json. ⚠️ feColorMatrix saturate=0 ОБЯЗАТЕЛЕН: без него
     feTurbulence шумит по всем четырём каналам, и на mix-blend-mode:multiply
     бумага идёт радужным муаром.
     У --fibre частота задана ДВУМЯ числами (.02 по X, .9 по Y) — это и даёт
     горизонтальное волокно бумаги вместо манной крупы. */
  --fibre: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.02 .9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23f)'/%3E%3C/svg%3E");
  --blots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='b'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.008' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23b)'/%3E%3C/svg%3E");
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");

  /* Обрез бумаги: амплитуда 2–3px. Больше — читается рваньём, ровно —
     теряется ощущение листа. Это НЕ скол (тот отменён вместе с камнем). */
  --clip-leaf: polygon(0 2px, 14% 0, 31% 3px, 52% 0, 68% 2px, 86% 0, 100% 3px,
    100% calc(100% - 2px), 84% 100%, 63% calc(100% - 3px), 44% 100%,
    26% calc(100% - 2px), 9% 100%, 0 calc(100% - 3px));

  /* Прогиб листа: тени идут в РАЗНЫЕ стороны, поэтому drop-shadow'ов три,
     а не один box-shadow — лист лежит не идеально плоско. */
  --sh-leaf: drop-shadow(0 2px 2px rgba(0,0,0,0.5))
             drop-shadow(-10px 22px 30px rgba(0,0,0,0.42))
             drop-shadow(12px 26px 40px rgba(0,0,0,0.42));
  --sh-slip: 0 2px 2px rgba(0,0,0,0.5), 0 16px 30px rgba(0,0,0,0.5);
  /* Гнездо картотеки: вырез в дереве — темно внутри, латунная нить по
     периметру, светлая кромка снизу (свет падает сверху). */
  --sh-cell: inset 0 4px 10px rgba(0,0,0,0.75), inset 0 0 0 1px rgba(155,106,70,0.5),
             0 1px 0 rgba(255,240,214,0.14);
  /* Гнездо под курсором: та же ниша плюс латунная нить по внешнему контуру —
     подсветка выбранного ящика, а не подъём карточки. */
  --sh-cell-hot: inset 0 4px 10px rgba(0,0,0,0.75), inset 0 0 0 1px rgba(155,106,70,0.5),
                 0 1px 0 rgba(255,240,214,0.14), 0 0 0 1px #8a5f2c;
  /* Толщина листа: потемнение по периметру + светлая верхняя и тёмная
     нижняя кромки. Без них бумага читается заливкой, а не предметом. */
  --sh-paper: inset 0 0 var(--s-8) var(--leaf-edge),
              inset 0 1px 0 rgba(255,250,236,0.5),
              inset 0 -1px 0 rgba(96,74,40,0.28);
  /* Латунная кромка полосы: та же деталь, что по краю стойки и ящика. */
  --sh-brass-rule: inset 0 3px 0 var(--brass), inset 0 -3px 0 var(--brass-lo);
  /* Латунная пластина: блик по верхней кромке, тень по нижней. */
  --sh-brass: inset 0 1px 0 rgba(255,240,214,0.7), inset 0 -1px 0 rgba(0,0,0,0.4),
              0 6px 14px rgba(0,0,0,0.5);

  /* ── Переплёт: тома на полке ────────────────────────────────────────────
     Работы о героине Гильдия переплетает в её том, и полка — это отдельный
     материал: доска, корешок, блок страниц, золочёная врезка портрета. */
  /* Доска полки: светлая кромка сверху (свет падает сверху) + тень под ней. */
  --sh-plank: 0 -2px 0 rgba(244,198,172,0.22), 0 14px 28px rgba(0,0,0,0.6);
  /* Корешок: затемнение к правому краю даёт объём книги, стоящей в ряду. */
  --sh-spine: inset -3px 0 8px rgba(0,0,0,0.7), 3px 6px 14px rgba(0,0,0,0.5);
  /* Вынутый том: та же тень + золочёный контур и отрыв от соседей. */
  --sh-spine-out: inset -3px 0 8px rgba(0,0,0,0.7), 0 0 0 1px rgba(232,192,101,0.5),
                  6px 12px 26px rgba(0,0,0,0.6);
  /* Том лицом: лежит ближе к зрителю, чем корешки, — тень крупнее. */
  --sh-tome: 8px 14px 30px rgba(0,0,0,0.6), inset 0 1px 0 rgba(255,255,255,0.06);
  /* Обрез страниц сбоку от обложки: тень от блока внутрь переплёта. */
  --sh-pages: inset -2px 0 4px rgba(0,0,0,0.55);
  /* Портрет, врезанный в кожу: золочёная нить, тёмный паспарту, тень внутрь. */
  --sh-gilt: 0 0 0 1px rgba(232,192,101,0.75), 0 0 0 4px rgba(0,0,0,0.5),
             inset 0 0 20px rgba(0,0,0,0.7);

  /* Слой ПОД содержимым: атмосфера страницы, водяные знаки. Отдельная
     ступень нужна потому, что «за всем» — это тоже осознанное место в
     стопке, а не «минус один, чтобы не мешало». */
  --z-behind: -1;
  --z-base: 0;
  --z-sticky: 10;
  --z-dropdown: 20;
  --z-overlay: 50;
  --z-toast: 200;

  /* ==========================================================================
     10. ДВИЖЕНИЕ — три длительности, три кривые
     ========================================================================== */
  --dur-1: 130ms;   /* наведение, мелкие состояния */
  --dur-2: 220ms;   /* появление панели, смена вкладки */
  --dur-3: 420ms;   /* снятие листа с доски, переворот */
  --ease-out: cubic-bezier(0.16, 0.84, 0.24, 1);
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-snap: cubic-bezier(0.2, 0.72, 0.2, 1);

  /* ==========================================================================
     11. РАЗМЕРЫ КОМПОНЕНТОВ — канон вместо разнобоя
     В макетах: кнопка в 8 размерах, оверлей в 7 ширинах, карточка
     в 3 пропорциях, 3 разных крестика. Ниже — по одному варианту на роль.
     ========================================================================== */
  --btn-lg-y: 14px;  --btn-lg-x: 26px;  --btn-lg-t: var(--t-0);
  --btn-md-y: 10px;  --btn-md-x: 16px;  --btn-md-t: var(--t--1);
  --btn-sm-y: 6px;   --btn-sm-x: 11px;  --btn-sm-t: var(--t--2);

  --ov-sm: 620px;    /* подтверждение, одна задача */
  --ov-md: 900px;    /* обычный экран аккаунта */
  --ov-lg: 1240px;   /* админка, доска охоты */
  --ov-h: 88vh;      /* единая модель высоты + внутренняя прокрутка */

  --card-ratio: 5 / 7;   /* единственная пропорция карточки героини */
  --tap-min: 24px;       /* минимальная цель нажатия */

  --focus-ring: 0 0 0 2px var(--accent-focus);
}

/* ============================================================================
   БАЗА
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

/* Forum — одноначертательная гарнитура (только 400). Любой запрос жирного
   заставлял бы браузер синтезировать его наклоном/обводкой — капитель от этого
   мажется и теряет рисунок. Синтез гасим глобально: у Old Standard TT есть
   настоящие 400/700, у Manrope — вариативная ось, подделка не нужна нигде. */
html { font-synthesis-weight: none; }

/* ⚠️ Тёмная схема объявляется ЯВНО. Без неё браузер рисует служебные части
   по своим светлым умолчаниям: полосы прокрутки, выпадающие списки, поля
   выбора даты. Раньше это давала легаси-тема (`:root { color-scheme: dark }`),
   и при её снятии страницы получили белые скроллбары.
   Фон дублируется на html: пока он был только на body, зона «перелёта»
   прокрутки на iOS отсвечивала белым. */
html {
  color-scheme: dark;
  background: var(--bg-base);
}

body {
  background: var(--bg-base);
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: var(--t-0);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* ⚠️ Начертание заголовков — 400, и это не «облегчили для красоты».
   У Old Standard TT самохостятся ровно два начертания: 400 и 700. Пока
   страницы грузили легаси-тему, та прибивала заголовкам 360/420/500
   через !important — браузер округлял к 400, и весь сайт был принят
   заказчиком именно в этом виде. После детокса (2026-08-10) сюда впервые
   дошло объявленное здесь --w-semi (600), браузер округлил ВВЕРХ, к 700,
   и все заголовки на всех страницах внезапно потяжелели: заголовок героя
   главной перестал помещаться в строку. Иерархию держит РАЗМЕР, а не
   насыщенность — у дисплейного серифа это и правильнее. */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: var(--w-normal);
  font-style: normal;          /* заголовки никогда не курсивом */
  line-height: var(--lh-snug);
  color: var(--ink);
}
h1 { font-size: var(--t-5); line-height: var(--lh-tight); letter-spacing: var(--ls-tight);
     font-variation-settings: 'opsz' 96, 'SOFT' 0, 'WONK' 0; }
h2 { font-size: var(--t-4); line-height: var(--lh-tight);
     font-variation-settings: 'opsz' 48, 'SOFT' 0, 'WONK' 0; }
h3 { font-size: var(--t-3); font-variation-settings: 'opsz' 24; }
h4 { font-size: var(--t-2); font-variation-settings: 'opsz' 18; }

/* Кикер / лейбл — Cinzel, всегда капслок с разрядкой */
.kicker, .label {
  font-family: var(--font-label);
  text-transform: uppercase;
  letter-spacing: var(--ls-kicker);
  font-size: var(--t--2);
  font-weight: var(--w-bold);
  color: var(--ink-4);
}

/* Фокус — один стиль на весь проект, никогда не анимируется */
:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
/* ⚠️ outline:none без замены запрещён. Проверяется автоматически. */

/* Уважение к настройке пользователя. Проверяется не наличием этого блока,
   а фактом: при эмуляции reduced-motion все длительности должны быть 0. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
