/* ============================================================
   ДИЗАЙН-СИСТЕМА — ПРОСЛОЙКА (единый источник стиля)
   ============================================================
   Это ГЛАВНЫЙ файл стиля. Здесь живут все цвета, шрифты и отступы.
   Его подключают И образец (ОБРАЗЕЦ-СТИЛЯ.html), И все страницы игры
   (index/lobby/novella). Поэтому: меняешь значение ЗДЕСЬ — оно
   меняется и в образце, и во всей игре одновременно.

   Шаг 1 (сейчас): здесь только токены (цвета/шрифты/отступы).
   Дальше сюда же постепенно переедет единый вид элементов.
   ============================================================ */
/* Шрифт Oswald — встроен в проект (файлы в public/fonts), БЕЗ запроса к Google.
   Это убирает «местами шрифт есть, местами нет»: раньше шрифт тянулся с серверов
   Google при каждой загрузке и у части игроков не догружался. Теперь едет вместе с игрой.
   Файлы вариативные: один файл на алфавит покрывает все толщины 300–700. */
@font-face {
  font-family:'Oswald'; font-style:normal; font-weight:300 700; font-display:swap;
  src:url('fonts/oswald-cyrillic.woff2') format('woff2');
  unicode-range:U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family:'Oswald'; font-style:normal; font-weight:300 700; font-display:swap;
  src:url('fonts/oswald-cyrillic-ext.woff2') format('woff2');
  unicode-range:U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family:'Oswald'; font-style:normal; font-weight:300 700; font-display:swap;
  src:url('fonts/oswald-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family:'Oswald'; font-style:normal; font-weight:300 700; font-display:swap;
  src:url('fonts/oswald-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* — Тёмные фоны — */
  --c-charcoal:#21201C; --c-midnight-umber:#1E1C1A; --c-espresso:#513D34;
  --c-pitch:#0F0F0F;

  /* — Поверхности (фоны окон, карточек, полей) — */
  --surface-app:#21201C; --surface-panel:#1A1916; --surface-card:#26241F;
  --surface-card-head:#513D34; --surface-slot:#513D34; --surface-inset:#161412;
  --surface-tooltip:#0F0F0F;

  /* — Пергамент / кость / тексты — */
  --c-parchment:#C5A87E; --c-pale-cream:#F8EAB9; --c-concrete:#A6A6A6;
  --c-warm-mud:#7D7260; --c-ancient-bone:#C8B89F;
  --text-strong:#F8EAB9; --text-body:#C5A87E; --text-muted:#A6A6A6;
  --text-faint:#7D7260; --text-on-gold:#0F0F0F;

  /* — Золото (главный акцент) — */
  --c-harvest-gold:#C1913C; --c-deep-gold:#9D6E20; --c-gold-stroke:#674919;
  --c-leather:#635045;
  --accent:#C5A87E; --accent-strong:#C1913C; --accent-deep:#9D6E20;

  /* — Панели поверх сцены (чат, полоса записи, кнопки у края экрана) —
     Они лежат не на фоне страницы, а поверх картинки сцены, поэтому у них
     свой, более плотный серый. Раньше он был вписан числом в десяток мест —
     и в любой новой теме вылезал бы серым пятном на синем. */
  --surface-float:#302F2B; --surface-float-btn:#57574F;

  /* — Семейства нод конструктора: данные · вид · экземпляр · расчёт · действие —
     Цвет тут = смысл, по нему нода узнаётся с одного взгляда. В темах эти
     пять оттенков не подбираются заново, а подмешиваются к фону темы
     (color-mix ниже): семейства остаются различимыми, но перестают быть
     чужеродными пятнами. */
  --fam-data-bg:#16242E; --fam-data-head:#3F6E8C;
  --fam-view-bg:#241A12; --fam-view-head:#8A6A34;
  --fam-inst-bg:#1E1830; --fam-inst-head:#6A54A0;
  --fam-calc-bg:#2A1608; --fam-calc-head:#B0701E;
  --fam-act-bg:#2A100C;  --fam-act-head:#A6483A;

  /* — Семейства нод конструктора 2.0 (шапки нод на холсте) —
     Мастер узнаёт ноду по цвету шапки быстрее, чем по надписи. */
  --b2-fam-base:#2F4A5C; --b2-fam-math:#3E5238; --b2-fam-logic:#4A3A55;
  --b2-fam-port:#5C4630; --b2-fam-event:#6B5A2E; --b2-fam-act:#2F5C4A;
  --b2-fam-dice:#6B3A34; --b2-fam-script:#3A4A5C; --b2-fam-text:#5C3A4E;
  --b2-fam-list:#4A5A2E;   /* списки и свои правила — оливковые */
  --b2-fam-pole:#2E4A5A;   /* поле, цель и расстояния — стальные */
  --b2-wire-card:#7FA5B8;   /* провод к карточке и к цели */

  /* — Гнёзда нод: подключено / пусто —
     Гнездо горит акцентом, когда в него заведён провод, и гаснет, когда пусто.
     Белое гнездо — «провод порядка» (что за чем выполняется), зелёное —
     флаг: видимость детали, выход на лист. */
  --sock-on:#C1913C;   --sock-off:#5A5347;
  --sock-exec:#E8E2D4; --sock-exec-off:#5B564C;
  --sock-flag:#7FB07F; --sock-flag-off:#3F5540;

  /* — Провода между нодами. Цвет провода = семейство того, что по нему течёт.
     Ярче шапок нод: провод тонкий, ему нужно пробиваться сквозь холст. */
  --wire-data:#4E86A8; --wire-view:#A8842E; --wire-inst:#8168C4;
  --wire-calc:#C8811F; --wire-act:#A6483A;  --wire-temp:#F0C067;  /* тянется за курсором */

  /* — Подсветка языка (скрипт как вторая проекция нод) —
     Это раскраска текста, а не фонов: каждый вид слова светится своим. */
  --scr-event:#F0C05A; --scr-act:#7FBFA3; --scr-math:#C9A96E; --scr-ctrl:#C08CD6;
  --scr-dice:#D98878;  --scr-decl:#6FA8D0; --scr-bag:#C79A5B; --scr-text:#C9A0B8;
  --scr-tgt:#9BD4B0;   --scr-port:#79C4C9; --scr-num:#B5CEA8; --scr-str:#A3B57C;
  --field-bad-bg:#3A1F1C; --field-bad-tx:#E8A99C;   /* поле с ошибкой */

  /* — Плашки-статусы и «доброе» действие —
     Статус новеллы на карточке («набор открыт», «добор»), зелёная кнопка
     согласия, светлый текст на красной кнопке удаления. */
  --status-ok-bg:#2C3823; --status-ok-tx:#7E9E6B; --status-warn-bg:#3A2C10;
  --btn-ok:#334431; --text-on-danger:#F3E7D2;

  /* — Подсветки поверх содержимого: «влезает» / «не влезает» / «заперто» /
     «сюда попадёт». Полупрозрачные, ложатся на картинки и сетки. */
  --hl-ok:#78AF5A; --hl-bad:#C8463C; --hl-lock:#5A96D2; --hl-pulse:#5ABE5A;

  /* — Роли — */
  --role-master:#C1913C; --role-podmaster:#526C7F; --role-player:#466340;

  /* — Опасность / удаление — */
  --danger:#78362D; --danger-deep:#662219;

  /* — Доступность по датам (календарь): свободен / занят / не определился — */
  --avail-free:#4E7140; --avail-busy:#8A3A2C; --avail-unknown:#6E4C93;

  /* — Линии и рамки — */
  --border-strong:#635045; --border-soft:#322C26; --border-hair:#161412;

  /* — Геометрия: скруглений нет, резаные углы — */
  --r-sm:0; --r-md:0; --r-lg:0; --bw-hair:1px; --bw:2px;

  /* — Отступы — */
  --sp-2:4px; --sp-3:6px; --sp-4:8px; --sp-5:12px; --sp-6:16px; --sp-7:20px;
  --sp-8:12px; --sp-9:32px; --sp-10:48px;

  /* — Тени / фокус — */
  --shadow-card:0 1px 0 rgba(0,0,0,0.35);
  --shadow-popover:0 6px 20px rgba(0,0,0,0.55);
  --inset-well:none; /* обводок-рамок 1px больше нет нигде — убрано по всему проекту */
  --ring:0 0 0 2px var(--c-charcoal),0 0 0 3px var(--c-harvest-gold);

  /* — Шрифты / анимация — */
  --font-display:"Oswald",Impact,"Arial Narrow",sans-serif;
  --font-ui:"Oswald","Arial Narrow",sans-serif;
  --ease:cubic-bezier(0.2,0,0.2,1); --dur-fast:90ms; --dur:140ms; --dur-press:80ms;
  --press-y:2px; /* на сколько кнопка проваливается при нажатии */

  /* — ФОРМА ТЕМЫ —
     Тема — это ЦВЕТ и ФОРМА, больше ничего. Цвет живёт в значениях выше,
     форма — в этих четырёх переменных. У эталона формы нет: углы прямые,
     срезов нет, поэтому здесь везде «none» и нулевые надбавки к отступам.
     Тема подменяет их у себя, и все экраны переодеваются разом. */
  --shape-panel:none;   /* окна, панели, карточки, всплывашки */
  --shape-btn:none;     /* кнопки, плашки, гнёзда, значки */
  --shape-head:none;    /* шапки окон и панелей */
  --shape-head-pad-r:0px; --shape-head-pad-l:0px; --shape-head-pad-t:0px;
  --shape-btn-pad-r:0px;
  /* Тёмная вуаль поверх акцента (наведение на крестик в золотой шапке).
     В светлых-на-тёмном темах перекрывается на светлую — иначе не видно. */
  --on-accent-veil:rgba(0,0,0,0.18); --on-accent-veil-2:rgba(0,0,0,0.28);
}

/* ============================================================
   ПЯТЬ ТЕМ ОФОРМЛЕНИЯ — ТОЛЬКО ЦВЕТ (форма ниже, отдельным блоком)
   ============================================================
   Согласовано пользователем 19 августа 2026, собрано в ТЕМЫ-ВИЗУАЛА.html.
   Тема = второй набор значений тех же переменных. Экраны, отступы,
   размеры и разметка НЕ меняются — переодевается только вид.

   ⚠ ПРАВИЛО: цвет в проекте нигде не пишется числом, только переменной.
   Написал «#C1913C» руками — сломал все пять тем разом: в неоне это
   вылезет коричневым пятном на синем.

   ⚠ И ВТОРОЕ: заводишь НОВУЮ переменную цвета в :root — заведи её
   во всех пяти темах ниже. Переменная, которой в теме нет, останется
   тёплой из эталона и будет выглядеть как грязь.
   ============================================================ */

/* ——— 1 · ДРЕВНЯЯ САГА — тёмное фэнтези: чёрное с золотом ——— */
:root[data-theme="saga"] {
  --c-charcoal:#0C0B09; --c-midnight-umber:#0A0907; --c-espresso:#262015; --c-pitch:#000000;
  --surface-app:#0C0B09; --surface-panel:#070605; --surface-card:#151310;
  --surface-card-head:#262015; --surface-slot:#262015; --surface-inset:#030302;
  --surface-tooltip:#000000;
  --c-parchment:#A2967A; --c-pale-cream:#F0E3BE; --c-concrete:#7E7565;
  --c-warm-mud:#57503F; --c-ancient-bone:#C9BC9C;
  --text-strong:#F0E3BE; --text-body:#A2967A; --text-muted:#7E7565;
  --text-faint:#57503F; --text-on-gold:#0A0906;
  --c-harvest-gold:#C9A227; --c-deep-gold:#8E6F14; --c-gold-stroke:#5E4A0E;
  --c-leather:#443A2C;
  --accent:#A2967A; --accent-strong:#C9A227; --accent-deep:#8E6F14;
  --role-master:#C9A227; --role-podmaster:#3F4A63; --role-player:#3A5A3C;
  --danger:#7A211C; --danger-deep:#5A1613;
  --avail-free:#3A5A3C; --avail-busy:#7A211C; --avail-unknown:#4A3A63;
  --border-strong:#443A2C; --border-soft:#201C16; --border-hair:#030302;
}

/* ——— 2 · ВИКТОРИАНСКАЯ ГОСТИНАЯ — бутылочное стекло и латунь ——— */
:root[data-theme="parlour"] {
  --c-charcoal:#101613; --c-midnight-umber:#0D120F; --c-espresso:#26392E; --c-pitch:#040705;
  --surface-app:#101613; --surface-panel:#0A0F0C; --surface-card:#18211A;
  --surface-card-head:#26392E; --surface-slot:#26392E; --surface-inset:#060A08;
  --surface-tooltip:#040705;
  --c-parchment:#B4B29C; --c-pale-cream:#EFE6D2; --c-concrete:#8F958A;
  --c-warm-mud:#666C62; --c-ancient-bone:#CFC8B4;
  --text-strong:#EFE6D2; --text-body:#B4B29C; --text-muted:#8F958A;
  --text-faint:#666C62; --text-on-gold:#0D0B05;
  --c-harvest-gold:#C2A05A; --c-deep-gold:#96793C; --c-gold-stroke:#6B5528;
  --c-leather:#3A4A3E;
  --accent:#B4B29C; --accent-strong:#C2A05A; --accent-deep:#96793C;
  --role-master:#C2A05A; --role-podmaster:#4E5A78; --role-player:#4A6B4E;
  --danger:#7C2A32; --danger-deep:#5E1F25;
  --avail-free:#4A6B4E; --avail-busy:#7C2A32; --avail-unknown:#574A78;
  --border-strong:#3A4A3E; --border-soft:#1C2820; --border-hair:#060A08;
}

/* ——— 3 · НЕОН — киберпанк: холодная глубина и электрический циан ——— */
:root[data-theme="neon"] {
  --c-charcoal:#0D131C; --c-midnight-umber:#0A1018; --c-espresso:#1E3348; --c-pitch:#03070C;
  --surface-app:#0D131C; --surface-panel:#080D15; --surface-card:#141C28;
  --surface-card-head:#1E3348; --surface-slot:#1E3348; --surface-inset:#05090F;
  --surface-tooltip:#03070C;
  --c-parchment:#93B7CC; --c-pale-cream:#DFF7FF; --c-concrete:#7C93A3;
  --c-warm-mud:#55697A; --c-ancient-bone:#B6D6E4;
  --text-strong:#DFF7FF; --text-body:#93B7CC; --text-muted:#7C93A3;
  --text-faint:#55697A; --text-on-gold:#02141A;
  --c-harvest-gold:#2FD9E8; --c-deep-gold:#17A2B5; --c-gold-stroke:#0E6C7A;
  --c-leather:#2A4258;
  --accent:#93B7CC; --accent-strong:#2FD9E8; --accent-deep:#17A2B5;
  --role-master:#2FD9E8; --role-podmaster:#5D6FD6; --role-player:#18A97E;
  --danger:#B02551; --danger-deep:#8A1A3E;
  --avail-free:#18A97E; --avail-busy:#B02551; --avail-unknown:#5D6FD6;
  --border-strong:#2A4258; --border-soft:#16202C; --border-hair:#05090F;
  --neon:47,217,232; /* цвет свечения цифрами — им управляется прозрачность ореола */
}

/* ——— 4 · ПЫЛЬ И РЖАВЧИНА — постапокалипсис: бетон и ржавый металл ——— */
:root[data-theme="rust"] {
  --c-charcoal:#1B1B18; --c-midnight-umber:#171714; --c-espresso:#3A362C; --c-pitch:#070706;
  --surface-app:#1B1B18; --surface-panel:#131311; --surface-card:#24241F;
  --surface-card-head:#3A362C; --surface-slot:#3A362C; --surface-inset:#0C0C0A;
  --surface-tooltip:#070706;
  --c-parchment:#A39C8B; --c-pale-cream:#DCD6C6; --c-concrete:#8A8375;
  --c-warm-mud:#635E53; --c-ancient-bone:#C4BDAB;
  --text-strong:#DCD6C6; --text-body:#A39C8B; --text-muted:#8A8375;
  --text-faint:#635E53; --text-on-gold:#140A05;
  --c-harvest-gold:#B5643A; --c-deep-gold:#8C4526; --c-gold-stroke:#63301A;
  --c-leather:#4A453A;
  --accent:#A39C8B; --accent-strong:#B5643A; --accent-deep:#8C4526;
  --role-master:#B5643A; --role-podmaster:#566A72; --role-player:#5C7047;
  --danger:#8E3A2A; --danger-deep:#6B2A1C;
  --avail-free:#5C7047; --avail-busy:#8E3A2A; --avail-unknown:#6A5A78;
  --border-strong:#4A453A; --border-soft:#2A2924; --border-hair:#0C0C0A;
}

/* ——— 5 · КРОВЬ И БАРХАТ — готический ужас: сливовая тьма и кровь ——— */
:root[data-theme="blood"] {
  --c-charcoal:#141017; --c-midnight-umber:#110D14; --c-espresso:#3A2440; --c-pitch:#050308;
  --surface-app:#141017; --surface-panel:#0D0A11; --surface-card:#1D1724;
  --surface-card-head:#3A2440; --surface-slot:#3A2440; --surface-inset:#08060B;
  --surface-tooltip:#050308;
  --c-parchment:#A897A2; --c-pale-cream:#EDE3E6; --c-concrete:#8B7C86;
  --c-warm-mud:#63565E; --c-ancient-bone:#C9BBC1;
  --text-strong:#EDE3E6; --text-body:#A897A2; --text-muted:#8B7C86;
  --text-faint:#63565E;
  /* ⚠ Единственная тема, где текст на акценте СВЕТЛЫЙ. Акцент здесь тёмно-красный,
     чёрным по нему не прочитать. Правило проекта звучит как «текст на акценте
     всегда контрастный» — тут контраст даёт светлый. */
  --text-on-gold:#F3E2E2;
  --c-harvest-gold:#A32530; --c-deep-gold:#7E1C22; --c-gold-stroke:#5A1418;
  --c-leather:#4A3A50;
  --accent:#A897A2; --accent-strong:#A32530; --accent-deep:#7E1C22;
  --role-master:#A32530; --role-podmaster:#5B5079; --role-player:#4E6B4A;
  --danger:#8A2E4A; --danger-deep:#661F36;
  --avail-free:#4E6B4A; --avail-busy:#8A2E4A; --avail-unknown:#5B5079;
  --border-strong:#4A3A50; --border-soft:#241C2A; --border-hair:#08060B;
  /* текст на акценте светлый — значит и вуаль наведения должна быть светлой */
  --on-accent-veil:rgba(255,255,255,0.14); --on-accent-veil-2:rgba(255,255,255,0.22);
}

/* ——— ОБЩЕЕ ДЛЯ ВСЕХ ПЯТИ ТЕМ ———
   Здесь то, что во всех темах считается одинаково и не требует ручного
   подбора. Эталона это не касается: у него атрибута data-theme нет вовсе. */
:root[data-theme] {
  /* панели поверх сцены живут в тех же слоях, что карточки и гнёзда */
  --surface-float:var(--surface-card);
  --surface-float-btn:var(--surface-slot);
  /* Семейства нод: свой оттенок подмешан к фону темы. Так синее остаётся
     синим, а красное красным — но в неоне они холодные, а в ржавчине пыльные,
     и ни одно не выглядит заплаткой из чужой палитры. */
  --fam-data-bg:  color-mix(in srgb, #3F6E8C 22%, var(--surface-card));
  --fam-data-head:color-mix(in srgb, #3F6E8C 70%, var(--surface-slot));
  --fam-view-bg:  color-mix(in srgb, #8A6A34 22%, var(--surface-card));
  --fam-view-head:color-mix(in srgb, #8A6A34 70%, var(--surface-slot));
  --fam-inst-bg:  color-mix(in srgb, #6A54A0 22%, var(--surface-card));
  --fam-inst-head:color-mix(in srgb, #6A54A0 70%, var(--surface-slot));
  --fam-calc-bg:  color-mix(in srgb, #B0701E 22%, var(--surface-card));
  --fam-calc-head:color-mix(in srgb, #B0701E 70%, var(--surface-slot));
  --fam-act-bg:   color-mix(in srgb, #A6483A 22%, var(--surface-card));
  --fam-act-head: color-mix(in srgb, #A6483A 70%, var(--surface-slot));
  /* Шапки нод конструктора 2.0 — тем же приёмом: оттенок семейства остаётся
     узнаваемым, но садится на плиту темы. */
  --b2-fam-base:  color-mix(in srgb, #2F4A5C 62%, var(--surface-slot));
  --b2-fam-math:  color-mix(in srgb, #3E5238 62%, var(--surface-slot));
  --b2-fam-logic: color-mix(in srgb, #4A3A55 62%, var(--surface-slot));
  --b2-fam-port:  color-mix(in srgb, #5C4630 62%, var(--surface-slot));
  --b2-fam-event: color-mix(in srgb, #6B5A2E 62%, var(--surface-slot));
  --b2-fam-act:   color-mix(in srgb, #2F5C4A 62%, var(--surface-slot));
  --b2-fam-dice:  color-mix(in srgb, #6B3A34 62%, var(--surface-slot));
  --b2-fam-script:color-mix(in srgb, #3A4A5C 62%, var(--surface-slot));
  --b2-fam-text:  color-mix(in srgb, #5C3A4E 62%, var(--surface-slot));
  --b2-fam-list:  color-mix(in srgb, #4A5A2E 62%, var(--surface-slot));
  --b2-fam-pole:  color-mix(in srgb, #2E4A5A 62%, var(--surface-slot));
  --b2-wire-card: color-mix(in srgb, #7FA5B8 60%, var(--text-body));
  /* Подсветка языка — это ТЕКСТ, его нельзя топить в фоне, иначе слова
     перестанут читаться. Оттенок подмешиваем к сильному тексту темы:
     виды слов остаются различимыми и не спорят с окружением. */
  --scr-event: color-mix(in srgb, #F0C05A 70%, var(--text-strong));
  --scr-act:   color-mix(in srgb, #7FBFA3 70%, var(--text-strong));
  --scr-math:  color-mix(in srgb, #C9A96E 70%, var(--text-strong));
  --scr-ctrl:  color-mix(in srgb, #C08CD6 70%, var(--text-strong));
  --scr-dice:  color-mix(in srgb, #D98878 70%, var(--text-strong));
  --scr-decl:  color-mix(in srgb, #6FA8D0 70%, var(--text-strong));
  --scr-bag:   color-mix(in srgb, #C79A5B 70%, var(--text-strong));
  --scr-text:  color-mix(in srgb, #C9A0B8 70%, var(--text-strong));
  --scr-tgt:   color-mix(in srgb, #9BD4B0 70%, var(--text-strong));
  --scr-port:  color-mix(in srgb, #79C4C9 70%, var(--text-strong));
  --scr-num:   color-mix(in srgb, #B5CEA8 70%, var(--text-strong));
  --scr-str:   color-mix(in srgb, #A3B57C 70%, var(--text-strong));
  --field-bad-bg: color-mix(in srgb, var(--danger) 45%, var(--surface-inset));
  --field-bad-tx: color-mix(in srgb, var(--danger) 30%, var(--text-strong));
  /* Гнёзда: горящее — акцент темы, погасшее — её же тихий тон. */
  --sock-on:var(--c-harvest-gold);
  --sock-off:color-mix(in srgb, var(--text-faint) 70%, var(--surface-slot));
  --sock-exec:var(--text-strong);
  --sock-exec-off:color-mix(in srgb, var(--text-faint) 55%, var(--surface-slot));
  --sock-flag:var(--role-player);
  --sock-flag-off:color-mix(in srgb, var(--role-player) 45%, var(--surface-inset));
  /* Провода: оттенок семейства, подтянутый к светлому тону темы — иначе
     тёплые провода висели бы поперёк холодного холста. */
  --wire-data:color-mix(in srgb, #4E86A8 68%, var(--text-body));
  --wire-view:color-mix(in srgb, #A8842E 68%, var(--text-body));
  --wire-inst:color-mix(in srgb, #8168C4 68%, var(--text-body));
  --wire-calc:color-mix(in srgb, #C8811F 68%, var(--text-body));
  --wire-act: color-mix(in srgb, #A6483A 68%, var(--text-body));
  --wire-temp:var(--c-harvest-gold);
  /* Статусы: «хорошо» — от цвета игрока темы, «внимание» — от её акцента. */
  --status-ok-bg:color-mix(in srgb, var(--role-player) 45%, var(--surface-inset));
  --status-ok-tx:color-mix(in srgb, var(--role-player) 55%, var(--text-strong));
  --status-warn-bg:color-mix(in srgb, var(--c-harvest-gold) 28%, var(--surface-inset));
  --btn-ok:var(--role-player);
  --text-on-danger:var(--c-pale-cream);
  /* Подсветки — светлее ролевых цветов темы: они лежат поверх картинок,
     и тёмного оттенка на них было бы не видно. */
  --hl-ok:color-mix(in srgb, var(--role-player) 60%, var(--text-strong));
  --hl-bad:color-mix(in srgb, var(--danger) 60%, var(--text-strong));
  --hl-lock:color-mix(in srgb, var(--role-podmaster) 60%, var(--text-strong));
  --hl-pulse:color-mix(in srgb, var(--role-player) 45%, var(--text-strong));
}

/* ============================================================
   ЭЛЕМЕНТЫ — единый вид (источник для образца и для игры)
   ============================================================ */

/* — Кнопки —
   Правило цвета: оранжевый (золото) — только при наведении/нажатии; в покое без оранжевого.
   Высота 32px: padding 6px + font-size 13px, без рамок. */
button { background:var(--surface-card); color:var(--text-body); border:none; border-radius:0;
  padding:6px; font-family:var(--font-display); font-size:15px; font-weight:700; text-transform:uppercase;
   cursor:pointer; transition:background var(--dur) var(--ease),color var(--dur) var(--ease),
   translate var(--dur-press) var(--ease), box-shadow var(--dur-press) var(--ease); }
button:not(:disabled):hover { background:var(--c-harvest-gold); color:var(--text-on-gold); filter:none; }
button:not(:disabled):active { background:var(--c-deep-gold); color:var(--text-on-gold); filter:none; }
button:disabled { opacity:0.5; cursor:default; }
button:focus-visible { outline:none; box-shadow:var(--ring); }

/* ============================================================
   НАЖАТИЕ — КНОПКА ПРОВАЛИВАЕТСЯ ВНУТРЬ
   ============================================================
   Утверждено пользователем 19 августа 2026. Приём выведен в
   ЭТАЛОН-ВИЗУАЛА.html (раздел 12) и живёт здесь как общее правило.
   Нажатая кнопка съезжает на 2 пикселя вниз и получает тень внутрь —
   как настоящая клавиша, которую продавили пальцем.

   ⚠ ПОЧЕМУ ЗДЕСЬ ЕСТЬ ::after — И ЕГО НЕЛЬЗЯ УБИРАТЬ.
   Сдвиг делается через transform, а transform двигает и область
   попадания мыши. Если нажать в самые верхние 2 пикселя кнопки,
   она уезжает ВНИЗ из-под курсора, отпускание приходится уже мимо
   неё — и браузер отдаёт click общему предку, то есть клик ПРОПАДАЕТ.
   Это ровно та мина «срабатывает через раз», что записана в CLAUDE.md.
   Лечится тем, что на время нажатия у кнопки появляется невидимая
   надставка сверху ровно в 2 пикселя: она едет вместе с кнопкой и
   закрывает то место, где кнопка была до сдвига. Область попадания
   не меняется ни на пиксель, клик не теряется.
   События на псевдоэлементе целятся в саму кнопку, поэтому
   обработчики ничего не замечают.
   ============================================================ */
/* ⚠ СДВИГ ДЕЛАЕТСЯ СВОЙСТВОМ «translate», А НЕ «transform», И ЭТО НЕ ПРИДИРКА.
   «transform» ЗАМЕЩАЕТ тот transform, что у кнопки уже есть. У крестика
   в шапке окна стоит «top:50%; transform:translateY(-50%)» — так он
   центрирован по высоте. На нажатие центровка терялась, и кнопка
   26 пикселей высотой прыгала вниз на ПЯТНАДЦАТЬ (половина высоты плюс
   сам сдвиг). Надставка ::after прикрывает два пикселя и помочь тут
   не могла: нажал в верхнюю половину крестика — он уехал из-под курсора,
   отпускание пришлось мимо, и клик достался шапке. Окно не закрывалось.
   Свойство «translate» СКЛАДЫВАЕТСЯ с «transform», а не затирает его.
   Поэтому свой transform кнопки цел, а сдвиг ровно два пикселя — те, что
   закрывает надставка. И это чинит НЕ ОДНУ кнопку, а все будущие тоже. */
/* ⚠ ЯКОРЬ ДЛЯ НАДСТАВКИ СТОИТ ЗАРАНЕЕ И БЕЗ СИЛЫ — А НЕ ВНУТРИ «:active».
   Это та же самая мина, что абзацем выше, только не про сдвиг, а про МЕСТО
   на экране. «position:relative» жило в правиле нажатия, а правило нажатия
   («button:not(:disabled):active») сильнее простого класса. Значит кнопка,
   у которой есть своё «position:absolute», на время нажатия ТЕРЯЛА его и
   падала обратно в поток. Крестик в шапке окна прижат вправо
   («position:absolute; right:2px; top:50%») — на нажатие он прыгал из
   правого края к самому заголовку, то есть уезжал из-под курсора,
   отпускание приходилось мимо, и браузер отдавал click шапке: ОКНО НЕ
   ЗАКРЫВАЛОСЬ. Так ломались десять кнопок проекта (крестик окна листа,
   закрытие просмотра картинки, кнопки на сцене, «+» на листе и другие).
   «:where(...)» не имеет силы вовсе, поэтому своё «position» у кнопки
   главнее и остаётся целым, а кнопке без своего места достаётся нужный
   якорь. Обратно в «:active» это переносить НЕЛЬЗЯ. */
:where(button, .sp-dd-trigger, .sp-dd-opt, .sp-ctx-item,
       .skill-card, .skill-pick, .sp-check, .die.rp-pick, .sp-press) { position:relative; }
button:not(:disabled):active,
.sp-dd-trigger:active, .sp-dd-opt:active, .sp-ctx-item:active,
.skill-card:active, .skill-pick:active, .sp-check:active,
.die.rp-pick:active, .sp-press:active {
  translate:0 var(--press-y);
  box-shadow:inset 0 3px 7px rgba(0,0,0,0.45);
}
button:not(:disabled):active::after,
.sp-dd-trigger:active::after, .sp-dd-opt:active::after, .sp-ctx-item:active::after,
.skill-card:active::after, .skill-pick:active::after, .sp-check:active::after,
.die.rp-pick:active::after, .sp-press:active::after {
  content:''; position:absolute; left:0; right:0; top:calc(-1 * var(--press-y)); height:var(--press-y);
}
/* Иконка-кнопка прозрачная — тень внутрь нарисовала бы тёмный квадрат на пустом месте.
   Ей оставляем только сам сдвиг. */
.ic-btn:not(:disabled):active { box-shadow:none; }
/* Выключенная кнопка не проваливается: она и не нажимается. */
button:disabled:active { translate:none; box-shadow:none; }
/* Кому анимация мешает — уважаем настройку системы. */
@media (prefers-reduced-motion:reduce){
  button:not(:disabled):active, .sp-dd-trigger:active, .sp-dd-opt:active, .sp-ctx-item:active,
  .skill-card:active, .skill-pick:active, .sp-check:active, .die.rp-pick:active, .sp-press:active {
    translate:none; }
}
/* filter здесь обязателен: у .skill-card своя подсветка яркостью, и без него
   это правило затёрло бы её переход. */
.sp-dd-trigger, .sp-dd-opt, .sp-ctx-item, .skill-card, .skill-pick, .sp-check, .die.rp-pick, .sp-press {
  transition:translate var(--dur-press) var(--ease), box-shadow var(--dur-press) var(--ease),
             filter var(--dur) var(--ease), background var(--dur) var(--ease); }
/* второстепенная (ghost) */
.ghost { background:transparent; border:none; color:var(--text-muted); }
.ghost:hover { background:var(--c-harvest-gold); color:var(--text-on-gold); filter:none; }
/* добавить */
.btn-add { background:var(--surface-panel); color:var(--text-body); align-self:flex-start; padding:9px 16px; }
.btn-add:hover { background:var(--c-harvest-gold); color:var(--text-on-gold); filter:none; }

/* — Поля ввода — однострочные высотой 32px; многострочное растягиваемое — */
input[type=text], input[type=password], input[type=number], input[type=url], input[type=email], input[type=search] {
  height:32px; padding:0 10px; background:var(--surface-inset); border:none; border-radius:0;
  color:var(--text-strong); font-family:var(--font-ui); font-size:16px; }
input::placeholder { color:var(--text-faint); }
input:focus, textarea:focus { outline:none; box-shadow:var(--ring); }
textarea { background:var(--surface-app); border:none; border-radius:0; padding:8px 10px;
  color:var(--text-strong); font-family:var(--font-ui); font-size:16px; resize:vertical; min-height:56px; }
.num-input { width:64px; flex:none; text-align:center; }
/* отключённое числовое поле (напр. «Сколько» при «на выбор игрока») — серое */
.num-input:disabled { opacity:.4; cursor:not-allowed; }
/* Убираем «стрелочки» у числовых полей (свой степпер плюс/минус) */
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }
input[type=number] { -moz-appearance:textfield; appearance:textfield; }

/* Степпер числа: [−] [поле] [+]. Кнопки — иконки плюс/минус (.ic-btn), фон прозрачный, символ = цвет текста. */
.num-stepper { display:inline-flex; align-items:center; gap:var(--sp-2); }
.num-stepper .num-input { width:48px; }
/* Высота кнопок = высоте строки (32px), а сам значок плюс/минус мельче — чтобы не был больше строки */
.num-stepper .ic-btn { height:32px; width:32px; }
.num-stepper .ic-btn svg { width:16px; height:16px; }

/* — Чекбокс (галочка): квадрат слева, текст справа, в одну строку. Вместо системной галочки — иконки. —
   off = пустой квадрат, on = галочка; цвет — currentColor (= цвет текста). */
.sp-check { display:inline-flex; flex-direction:row; align-items:center; gap:var(--sp-4); cursor:pointer; color:var(--text-body); }
.sp-check > input { position:absolute; width:1px; height:1px; opacity:0; pointer-events:none; }
.sp-check .cb-off, .sp-check .cb-on { width:20px; height:20px; flex:none; display:block; }
.sp-check .cb-on { display:none; }
.sp-check > input:checked ~ .cb-off { display:none; }
.sp-check > input:checked ~ .cb-on { display:block; }
.sp-check > input:focus-visible ~ .cb-off,
.sp-check > input:focus-visible ~ .cb-on { box-shadow:var(--ring); }
.sp-check .cb-label { font-family:var(--font-ui); font-size:16px; text-transform:uppercase;  color:var(--text-body); }

/* — Попап результата броска (вид; без верхней полоски). Позиционирование/анимация — на стороне игры. — */
.roll-popup { min-width:280px; max-width:520px; background:var(--surface-card); box-shadow:var(--shadow-popover);
  padding:var(--sp-7) var(--sp-8); text-align:center; }
.rp-who { font-family:var(--font-display); text-transform:uppercase;  color:var(--text-muted); font-size:13px; }
.rp-big { font-family:var(--font-display); font-weight:700; color:var(--text-strong); font-size:34px; line-height:1.1; margin-top:4px; }
.roll-popup.fail .rp-big { color:var(--text-faint); }
.rp-crit { font-family:var(--font-display); font-weight:700; color:var(--c-harvest-gold);  margin-top:4px; }
/* ВЫВОД БРОСКА в новом конструкторе: «ПОПАЛ» / «ПРОМАХ» под числом.
   Ради него плашку и смотрят: число само по себе ничего не говорит, пока
   не знаешь класс доспеха цели.
   ⚠ Цвет берём из ТОНА плашки, а не пишем числом: у площадки шесть тем,
   и зелёный «на глаз» в неоне вылезет ядовитым пятном. */
.rp-verdict { font-family:var(--font-display); font-weight:700; text-transform:uppercase;
  letter-spacing:.06em; font-size:17px; margin-top:6px; color:var(--text-body); }
.roll-popup.ok .rp-verdict { color:var(--hl-ok); }
.roll-popup.fail .rp-verdict { color:var(--hl-bad); }
.roll-popup.crit .rp-verdict { color:var(--c-harvest-gold); }
.rp-sub { color:var(--text-muted); font-size:12px; margin-top:6px; }
.rp-dice { display:flex; flex-wrap:wrap; gap:5px; justify-content:center; margin-top:8px; }
.die { min-width:24px; height:24px; padding:0 4px; display:flex; align-items:center; justify-content:center; background:var(--surface-inset); color:var(--text-faint); font-variant-numeric:tabular-nums; font-size:13px; box-shadow:var(--inset-well); }
.die.s { background:var(--c-deep-gold); color:var(--text-on-gold); }
.die.c { background:var(--c-pale-cream); color:var(--text-on-gold); font-weight:700; }
.rp-crittext { color:var(--c-parchment); font-size:13px; margin-top:8px; }
.rp-insp { color:var(--c-harvest-gold); font-size:13px; margin-top:8px; }
/* Пуш-броски: интерактивная плашка результата (кнопки видит только тот, кто бросил). */
.roll-popup.rp-live { pointer-events:auto; }
.die.rp-pick { cursor:pointer; }
.die.rp-pick:hover { background:var(--c-warm-mud); color:var(--c-pale-cream); }
.die.rp-pick.sel { background:var(--danger); color:var(--c-pale-cream); } /* отмечен на переброс */
.rp-pushhint { color:var(--text-muted); font-size:12px; margin-top:10px; }
.rp-pushrow { display:flex; gap:var(--sp-4); justify-content:center; margin-top:10px; }
.rp-pushrow button { min-width:120px; }

/* — Выпадающий список (свой, вместо системного <select>) —
   В покое без оранжевого; оранжевый — при наведении/открытии. Высота 32px. */
.sp-dd { position:relative; display:inline-flex; }
.sp-dd-trigger { display:inline-flex; align-items:center; justify-content:space-between; gap:var(--sp-4);
  width:100%; min-width:160px; height:32px; padding:0 10px; background:var(--surface-card); color:var(--text-body);
  font-family:var(--font-display); font-weight:600; text-transform:uppercase; 
  font-size:15px; cursor:pointer; }
.sp-dd-trigger:hover,
.sp-dd[data-open="true"] .sp-dd-trigger { background:var(--c-harvest-gold); color:var(--text-on-gold); }
.sp-dd-label { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.sp-dd-arr { flex:none; width:0; height:0; border-left:5px solid transparent; border-right:5px solid transparent;
  border-top:6px solid currentColor; }
.sp-dd[data-open="true"] .sp-dd-arr { transform:rotate(180deg); }
.sp-dd-menu { position:absolute; top:100%; left:0; min-width:100%; max-height:260px; overflow-y:auto;
  background:var(--surface-card); box-shadow:var(--shadow-popover); z-index:200; display:flex; flex-direction:column; }
.sp-dd-menu[hidden] { display:none; }
.sp-dd-opt { padding:8px 10px; font-family:var(--font-display); font-weight:600; text-transform:uppercase;
   font-size:15px; color:var(--text-body); cursor:pointer; white-space:nowrap; }
.sp-dd-opt:hover { background:var(--c-harvest-gold); color:var(--text-on-gold); }
.sp-dd-opt[data-selected="true"] { background:var(--c-harvest-gold); color:var(--text-on-gold); }

/* — Иконка-кнопка (удалить/закрыть/кубик): сама иконка, 32×32, без рамок —
   Символ наследует currentColor; фон прозрачный (совпадает с фоном блока). */
.ic-btn { width:32px; height:32px; flex:none; padding:0; border:none; background:transparent;
  color:var(--text-body); cursor:pointer; line-height:0; display:inline-flex; align-items:center; justify-content:center; }
.ic-btn svg { display:block; width:32px; height:32px; }
/* В шапке окна (золотой фон) крестик — чёрный */
.win-head .ic-btn { color:var(--text-on-gold); }
.ic-btn:not(:disabled):hover { filter:brightness(1.12); background:transparent; }
.ic-btn:not(:disabled):active { filter:brightness(1.25); }
.ic-btn:focus-visible { outline:none; box-shadow:var(--ring); }
/* В шапке окна крестик чёрный, при наведении — лёгкая тёмная подложка */
.win-head .ic-btn:hover, .nc-head .ic-btn:hover { background:var(--on-accent-veil); }
.win-head .ic-btn:active, .nc-head .ic-btn:active { background:var(--on-accent-veil-2); }
.nc-head .ic-btn { color:var(--text-on-gold); }

/* Линии-разделители сегментов у иконок (кубики и т.п.): красятся в цвет фона позади иконки —
   тогда между гранями «просвечивает» фон, а внешний контур на том же фоне невидим. Получаются
   сегменты без обводки и без пятна. По умолчанию — цвет тёмной панели; в нужных местах фон зазора
   переопределяется через --ic-seg (например, у кнопок кубиков чата — цвет кнопки). Всегда два цвета. */
.ic svg path[stroke] { stroke:var(--ic-seg, var(--surface-panel)); }

/* Иконка-деталь вписывается в свою «рамку»: размер задаёт SPBox (attr-util.js) переменной
   --sp-icon-fit + классом .sp-icon-fit на узле-рамке. Через CSS, а не только инлайном на svg,
   чтобы вписалась и АСИНХРОННО загруженная иконка (у игрока svg вставляется позже) — одна истина. */
.sp-icon-fit svg { width:var(--sp-icon-fit); height:var(--sp-icon-fit); max-width:100%; max-height:100%; flex:none; }

/* — Ползунок (слайдер): тёмная дорожка, квадратный золотой бегунок по центру.
   Закраску слева от бегунка задаёт скрипт (icons.js → paintSlider). — */
.slider { -webkit-appearance:none; appearance:none; width:220px; height:8px;
  background:var(--surface-inset); border:none; cursor:pointer; }
.slider::-webkit-slider-runnable-track { -webkit-appearance:none; height:8px; background:transparent; border:none; }
.slider::-webkit-slider-thumb { -webkit-appearance:none; appearance:none; width:14px; height:14px; margin-top:-3px;
  background:var(--c-harvest-gold); border:none; border-radius:0; box-shadow:0 1px 4px rgba(0,0,0,0.7); }
.slider::-moz-range-track { height:8px; background:var(--surface-inset); border:none; }
.slider::-moz-range-progress { height:8px; background:var(--c-harvest-gold); }
.slider::-moz-range-thumb { width:14px; height:14px; background:var(--c-harvest-gold); border:none; border-radius:0; box-shadow:0 1px 4px rgba(0,0,0,0.7); }
.slider.small { width:90px; }

/* — Шапка окна (золотая полоса с названием) — */
/* Отступы шапки заданы с надбавками темы: у эталона они нулевые, а тема
   добавляет ровно столько, сколько съедает её знак формы — хвост справа
   (Сага), полоса опасности слева (Ржавчина), остриё арки сверху (Кровь).
   Без надбавки надпись налезала бы на срез. */
.win-head { display:flex; align-items:center; justify-content:space-between; gap:var(--sp-5);
  margin:calc(-1 * var(--sp-8)) calc(-1 * var(--sp-8)) 0; background:var(--c-harvest-gold);
  padding:calc(10px + var(--shape-head-pad-t)) calc(var(--sp-6) + var(--shape-head-pad-r))
          10px calc(var(--sp-6) + var(--shape-head-pad-l)); }
.win-title { font-family:var(--font-display); font-weight:700; text-transform:uppercase; 
  color:var(--text-on-gold); font-size:16px; margin:0; flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* — Текст ошибки / валидации — */
.error { color:var(--danger); font-size:13px; min-height:1rem; margin:0; text-align:center; }

/* — Пикер навыков: сетка карточек —
   Список всегда ровно 3 колонки, равные по ширине.
   ВАЖНО: JS переносит .skill-card-tip прямо в <body>, иначе filter:brightness
   на .skill-card:hover создаёт новый containing block и сдвигает fixed-позиционированный тултип. */
.skill-pick-list { display:grid; grid-template-columns:repeat(3,1fr); gap:var(--sp-3); }
.skill-card { display:flex; align-items:flex-start; gap:var(--sp-4); background:var(--surface-panel);
  padding:var(--sp-4) var(--sp-5); cursor:pointer; position:relative;
  box-shadow:var(--inset-well); transition:filter var(--dur) var(--ease); }
.skill-card:hover { filter:brightness(1.3); }
.skill-card-icon { width:40px; height:40px; flex:none; background:var(--surface-slot) center/cover no-repeat;
  box-shadow:var(--inset-well); }
.skill-card-body { flex:1; min-width:0; display:flex; flex-direction:column; gap:2px; }
.skill-card-name { font-family:var(--font-display); font-weight:700; text-transform:uppercase;
   color:var(--text-strong); font-size:13px; }
.skill-card-desc { font-size:11px; color:var(--text-muted); line-height:1.3; }
.skill-card-tip { display:none; position:fixed; z-index:1000; width:220px; pointer-events:none; }

/* — Подсказка / тултип (по образцу ОБРАЗЕЦ-СТИЛЯ.html, раздел 9). Без рамок — только фон + тень. —
   Блоки внутри разделяются РАЗНЫМ ФОНОМ и отступом (никаких линий — правило проекта). */
.tooltip { display:flex; flex-direction:column; gap:var(--sp-3); background:var(--surface-tooltip); color:var(--text-body);
  font-size:12px; line-height:1.4; padding:var(--sp-5); max-width:260px; box-shadow:var(--shadow-popover); }
.tooltip strong { color:var(--text-strong); font-family:var(--font-display); text-transform:uppercase;
   display:block; }
/* блок-секция: своя заливка, чтобы блоки визуально отделялись */
.tooltip .tip-sec { padding:var(--sp-3) var(--sp-4); background:var(--surface-panel); }
.tooltip .tip-sec.tip-fx { background:var(--surface-card); color:var(--c-parchment); }
.tooltip .tip-line { margin:0; }
.tooltip .tip-line + .tip-line { margin-top:2px; }
/* описание — простым текстом, приглушённое, отделено отступом */
.tooltip .tip-desc { margin:0; color:var(--text-muted); }
.tooltip p { margin:0; }

/* — Крупный тултип предмета инвентаря: большая картинка сверху (по форме предмета) +
   подписи нормальным шрифтом, блоки разделены разным фоном (без линий — правило проекта). — */
.inv-item-tip { width:auto; }
.inv-item-tip .tooltip { max-width:340px; gap:var(--sp-4); padding:var(--sp-6); font-size:14px; line-height:1.5; }
.inv-item-tip .tooltip strong { font-size:20px; margin-bottom:2px; }
.inv-item-tip .tip-img { align-self:center; background:center/cover no-repeat; }
.inv-item-tip .tooltip .tip-sec { padding:var(--sp-4) var(--sp-5); font-size:14px; }
.inv-item-tip .tooltip .tip-desc { font-size:14px; line-height:1.5; }
.inv-item-tip .tooltip .rp-sub { font-size:13px; }
/* Подсказка плашки-элемента: шире короткого, с метками секций (что это · собрать · на листе · пример) */
.inv-item-tip .tooltip.sp-el-tip { max-width:400px; }
.tooltip .tip-k { font-family:var(--font-display); text-transform:uppercase; font-size:10px; letter-spacing:.05em;
   color:var(--text-strong); margin-bottom:2px; opacity:.85; }
.inv-item-tip .tooltip.sp-el-tip .tip-k { font-size:11px; }

/* ── ВСПЛЫВАЮЩЕЕ ОКОШКО ПО ЦЕНТРУ (window.spFlash) ─────────────────────────
   Короткое сообщение, которое само уходит через пару секунд. Не полоса во всю
   ширину и не модалка: оно ничего не перекрывает и не требует нажатий. ── */
.sp-flash { position:fixed; left:50%; top:50%; transform:translate(-50%,-50%) scale(.96);
  z-index:4000; max-width:420px; padding:var(--sp-6) var(--sp-7);
  background:var(--surface-card); color:var(--text-strong); box-shadow:var(--shadow-popover);
  font-size:14px; line-height:1.45; text-align:center; pointer-events:none;
  opacity:0; transition:opacity var(--dur) var(--ease), transform var(--dur) var(--ease); }
.sp-flash.show { opacity:1; transform:translate(-50%,-50%) scale(1); }

/* ── ВИТРИНА ТЕМ (window.SPTheme.picker) ───────────────────────────────
   Одна на все места: кабинет, настройки новеллы, меню игрока. «Неон» и
   «Пыль и ржавчина» — слова, а выбирают глазами: три полоски показывают
   фон, шапку и акцент темы, и этого хватает, чтобы узнать её не открывая.
   Строки разделены отступом и фоном — линий в проекте нет. ── */
.sp-thlist { display:flex; flex-direction:column; gap:var(--sp-3); }
.sp-thline { display:flex; align-items:center; gap:var(--sp-5); padding:var(--sp-4) var(--sp-5);
  background:var(--surface-inset); cursor:pointer; user-select:none;
  transition:background var(--dur) var(--ease); }
.sp-thline:hover { background:var(--surface-slot); }
.sp-thline.on { background:var(--c-espresso); }
.sp-thsw { display:flex; width:42px; height:26px; flex:none; }
.sp-thsw i { display:block; flex:1; height:100%; }
.sp-thtxt { display:flex; flex-direction:column; gap:2px; min-width:0; }
.sp-thname { font-family:var(--font-display); font-weight:700; text-transform:uppercase;
  letter-spacing:.04em; font-size:13px; color:var(--text-body); }
.sp-thline.on .sp-thname { color:var(--c-pale-cream); }
.sp-thsub { font-size:11px; color:var(--text-faint); }

/* ============================================================
   ФОРМА ТЕМЫ — ГДЕ ОНА ПРИМЕНЯЕТСЯ (один список на всю игру)
   ============================================================
   Ниже — ЕДИНСТВЕННОЕ место, где сказано, какие элементы игры носят
   форму темы. Сами формы задаются переменными в блоке темы выше,
   у эталона они «none» — поэтому в эталоне этот блок не делает ничего.

   Четыре роли, и больше никаких:
     --shape-panel  окна, панели, всплывашки  (крупный срез)
     --shape-head   шапки окон и панелей      (знак темы: хвост, арка, полоса)
     --shape-btn    всё НАЖИМАЕМОЕ            (мелкий срез + шляпка, см. ниже)
     --shape-tile   плитки, гнёзда, поля      (мелкий срез, без шляпки)

   ⚠ ПОЧЕМУ У НАЖИМАЕМОГО ОТДЕЛЬНАЯ ФОРМА СО «ШЛЯПКОЙ».
   Нажатая кнопка съезжает на --press-y вниз (см. раздел «НАЖАТИЕ»),
   и её спасает невидимая надставка ::after сверху. Но clip-path режет
   и псевдоэлементы: обычная форма отрезала бы надставку, и вернулась
   бы старая мина «клик срабатывает через раз». Поэтому у --shape-btn
   контур начинается не с 0, а с calc(-1 * var(--press-y)) — полоса над
   кнопкой входит в форму. Краски там нет, видно ничего не будет,
   а надставка уцелеет. Заводишь новую форму кнопки — шляпку не забудь.

   ⚠ И ВТОРОЕ: тень у обрезанного блока не видна — clip-path срезает
   её вместе с углами. Мелким всплывашкам тень возвращаем рисованной
   (filter:drop-shadow), КРУПНЫМ окнам — нет: filter делает элемент
   точкой отсчёта для position:fixed внутри, и выпадающие меню,
   палитры и подсказки внутри окна уехали бы не туда.
   ============================================================ */

/* — Окна, панели, всплывашки — */
.modal-box, .ed-box, .cropper-box, .crop2-box, .prof-box,
.nv-dropdown, .nv-side, .novella-chat, .nov-cal, .sp-fly,
.ctx-menu, .sp-ctx, .spc-ctx, .sp-dd-menu, .col-pop, .ic-pop,
.roll-popup, .sp-flash, .sp-tip, .tooltip, .sp-undo-toast,
.music-bar, .foot-v2, .skill-card { clip-path:var(--shape-panel); }

/* — Мелким всплывашкам тень возвращаем рисованной: внутри них нет
     ничего с position:fixed, поэтому filter им безопасен.
     У эталона атрибута data-theme нет вовсе — его тени не трогаем. — */
:root[data-theme] .roll-popup, :root[data-theme] .sp-flash,
:root[data-theme] .sp-tip, :root[data-theme] .tooltip,
:root[data-theme] .sp-dd-menu, :root[data-theme] .ctx-menu,
:root[data-theme] .sp-ctx, :root[data-theme] .spc-ctx,
:root[data-theme] .sp-undo-toast {
  box-shadow:none; filter:var(--shape-shadow, none); }

/* — Шапки —
   Только .win-head: это и есть «плита с названием окна», на которой
   читается знак темы. Полоса кнопок чата (.nc-head) шапкой не считается —
   там кнопки, и каждая уже носит свою форму. */
.win-head { clip-path:var(--shape-head); }

/* — Всё нажимаемое (форма со шляпкой). .ic-btn исключён: он прозрачный,
     это сам значок, резать у него нечего. — */
button:not(.ic-btn), .sp-dd-trigger, .sp-dd-opt, .ctx-item, .sp-ctx-item,
.menu-btn, .btn-add, .econ-btn { clip-path:var(--shape-btn); }

/* — Плитки, гнёзда, поля ввода, кубики — */
input[type=text], input[type=password], input[type=number], input[type=url],
input[type=email], input[type=search], textarea,
.skill-card-icon, .char-thumb, .ed-portrait, .chat-badge, .die,
.ic-swatch, .cover-preview { clip-path:var(--shape-tile); }

/* ============================================================
   1 · ДРЕВНЯЯ САГА — мелкая огранка + хоругвь с одним хвостом
   ============================================================ */
:root[data-theme="saga"] {
  --shape-panel: polygon(4px 0, calc(100% - 4px) 0, 100% 4px, 100% calc(100% - 4px),
                         calc(100% - 4px) 100%, 4px 100%, 0 calc(100% - 4px), 0 4px);
  --shape-tile:  polygon(3px 0, calc(100% - 3px) 0, 100% 3px, 100% calc(100% - 3px),
                         calc(100% - 3px) 100%, 3px 100%, 0 calc(100% - 3px), 0 3px);
  /* кнопка: тот же камень, но со шляпкой над верхней гранью */
  --shape-btn:   polygon(3px calc(-1 * var(--press-y)), calc(100% - 3px) calc(-1 * var(--press-y)),
                         calc(100% - 3px) 0, 100% 3px, 100% calc(100% - 3px),
                         calc(100% - 3px) 100%, 3px 100%, 0 calc(100% - 3px), 0 3px, 3px 0);
  /* шапка: в правый конец врезан треугольник — плита раздваивается хвостом вымпела */
  --shape-head:  polygon(0 0, 100% 0, calc(100% - 13px) 50%, 100% 100%, 0 100%);
  --shape-head-pad-r:13px;
  --shape-shadow: drop-shadow(0 8px 20px rgba(0,0,0,.85));
}

/* ============================================================
   2 · ВИКТОРИАНСКАЯ ГОСТИНАЯ — уголки-косынки и надпись по центру
   ============================================================
   Единственная тема без срезов: форму держат косынки в углах панелей
   и центрованный заголовок вразрядку, как табличка на двери кабинета. */
:root[data-theme="parlour"] { --shape-shadow: drop-shadow(0 8px 20px rgba(0,0,0,.7)); }
:root[data-theme="parlour"] .modal-box,
:root[data-theme="parlour"] .ed-box,
:root[data-theme="parlour"] .prof-box,
:root[data-theme="parlour"] .nv-dropdown,
:root[data-theme="parlour"] .nv-side,
:root[data-theme="parlour"] .novella-chat,
:root[data-theme="parlour"] .roll-popup,
:root[data-theme="parlour"] .tooltip,
:root[data-theme="parlour"] .sp-tip,
:root[data-theme="parlour"] .ctx-menu { position:relative; }
:root[data-theme="parlour"] .modal-box::before, :root[data-theme="parlour"] .modal-box::after,
:root[data-theme="parlour"] .ed-box::before, :root[data-theme="parlour"] .ed-box::after,
:root[data-theme="parlour"] .prof-box::before, :root[data-theme="parlour"] .prof-box::after,
:root[data-theme="parlour"] .nv-dropdown::before, :root[data-theme="parlour"] .nv-dropdown::after,
:root[data-theme="parlour"] .nv-side::before, :root[data-theme="parlour"] .nv-side::after,
:root[data-theme="parlour"] .novella-chat::before, :root[data-theme="parlour"] .novella-chat::after,
:root[data-theme="parlour"] .roll-popup::before, :root[data-theme="parlour"] .roll-popup::after,
:root[data-theme="parlour"] .tooltip::before, :root[data-theme="parlour"] .tooltip::after,
:root[data-theme="parlour"] .sp-tip::before, :root[data-theme="parlour"] .sp-tip::after,
:root[data-theme="parlour"] .ctx-menu::before, :root[data-theme="parlour"] .ctx-menu::after {
  content:''; position:absolute; width:10px; height:10px; z-index:1;
  background:var(--c-espresso); pointer-events:none; }
:root[data-theme="parlour"] .modal-box::before, :root[data-theme="parlour"] .ed-box::before,
:root[data-theme="parlour"] .prof-box::before, :root[data-theme="parlour"] .nv-dropdown::before,
:root[data-theme="parlour"] .nv-side::before, :root[data-theme="parlour"] .novella-chat::before,
:root[data-theme="parlour"] .roll-popup::before, :root[data-theme="parlour"] .tooltip::before,
:root[data-theme="parlour"] .sp-tip::before, :root[data-theme="parlour"] .ctx-menu::before {
  left:0; top:0; clip-path:polygon(0 0, 100% 0, 0 100%); }
:root[data-theme="parlour"] .modal-box::after, :root[data-theme="parlour"] .ed-box::after,
:root[data-theme="parlour"] .prof-box::after, :root[data-theme="parlour"] .nv-dropdown::after,
:root[data-theme="parlour"] .nv-side::after, :root[data-theme="parlour"] .novella-chat::after,
:root[data-theme="parlour"] .roll-popup::after, :root[data-theme="parlour"] .tooltip::after,
:root[data-theme="parlour"] .sp-tip::after, :root[data-theme="parlour"] .ctx-menu::after {
  right:0; bottom:0; clip-path:polygon(100% 0, 100% 100%, 0 100%); }
/* всплывашке косынки красим акцентом — она главная на экране */
:root[data-theme="parlour"] .roll-popup::before, :root[data-theme="parlour"] .roll-popup::after {
  background:var(--c-harvest-gold); }
/* заголовок по центру вразрядку, крестик прижат вправо */
:root[data-theme="parlour"] .win-head { position:relative; justify-content:center; letter-spacing:.16em; }
:root[data-theme="parlour"] .win-head .win-title { flex:0 1 auto; text-align:center; }
:root[data-theme="parlour"] .win-head .ic-btn { position:absolute; right:var(--sp-4); }
:root[data-theme="parlour"] button, :root[data-theme="parlour"] .sp-dd-trigger,
:root[data-theme="parlour"] .sp-dd-opt { letter-spacing:.12em; }

/* ============================================================
   3 · НЕОН — скос двух углов и свечение акцента
   ============================================================ */
:root[data-theme="neon"] {
  --shape-panel: polygon(8px 0, 100% 0, 100% calc(100% - 8px), calc(100% - 8px) 100%, 0 100%, 0 8px);
  --shape-tile:  polygon(5px 0, 100% 0, 100% calc(100% - 5px), calc(100% - 5px) 100%, 0 100%, 0 5px);
  --shape-btn:   polygon(5px calc(-1 * var(--press-y)), 100% calc(-1 * var(--press-y)),
                         100% calc(100% - 5px), calc(100% - 5px) 100%, 0 100%, 0 5px, 5px 0);
  --shape-head:  polygon(5px 0, 100% 0, 100% calc(100% - 5px), calc(100% - 5px) 100%, 0 100%, 0 5px);
  --shape-shadow: drop-shadow(0 8px 18px rgba(0,0,0,.75)) drop-shadow(0 0 16px rgba(var(--neon),.38));
}
/* свечение — только на том, что светится: акцентные кнопки и шапки.
   На окна filter вешать нельзя (ломает position:fixed внутри). */
:root[data-theme="neon"] button:not(.ic-btn):not(:disabled):hover,
:root[data-theme="neon"] .sp-dd-trigger:hover,
:root[data-theme="neon"] .sp-dd-opt:hover {
  filter:drop-shadow(0 0 4px rgba(var(--neon),.55)) drop-shadow(0 0 11px rgba(var(--neon),.24)); }
:root[data-theme="neon"] .win-head { filter:drop-shadow(0 0 4px rgba(var(--neon),.35)); }
:root[data-theme="neon"] button:not(.ic-btn), :root[data-theme="neon"] .sp-dd-trigger,
:root[data-theme="neon"] .sp-dd-opt { transition:filter 150ms var(--ease), background var(--dur) var(--ease); }
:root[data-theme="neon"] .rp-big { text-shadow:0 0 20px rgba(var(--neon),.70), 0 0 6px rgba(var(--neon),.55); }

/* ============================================================
   4 · ПЫЛЬ И РЖАВЧИНА — четыре скоса и полоса опасности в шапке
   ============================================================ */
:root[data-theme="rust"] {
  --shape-panel: polygon(9px 0, calc(100% - 9px) 0, 100% 9px, 100% calc(100% - 9px),
                         calc(100% - 9px) 100%, 9px 100%, 0 calc(100% - 9px), 0 9px);
  --shape-tile:  polygon(5px 0, calc(100% - 5px) 0, 100% 5px, 100% calc(100% - 5px),
                         calc(100% - 5px) 100%, 5px 100%, 0 calc(100% - 5px), 0 5px);
  --shape-btn:   polygon(5px calc(-1 * var(--press-y)), calc(100% - 5px) calc(-1 * var(--press-y)),
                         calc(100% - 5px) 0, 100% 5px, 100% calc(100% - 5px),
                         calc(100% - 5px) 100%, 5px 100%, 0 calc(100% - 5px), 0 5px, 5px 0);
  --shape-head-pad-l:14px;
  --hazard:14px;
  --shape-shadow: drop-shadow(0 8px 18px rgba(0,0,0,.72));
}
:root[data-theme="rust"] .win-head { position:relative; }
:root[data-theme="rust"] .win-head::before {
  content:''; position:absolute; left:0; top:0; bottom:0; width:var(--hazard); pointer-events:none;
  background:repeating-linear-gradient(-45deg,
    var(--c-harvest-gold) 0 4px, var(--surface-slot) 4px 8px); }
:root[data-theme="rust"] .win-head, :root[data-theme="rust"] button:not(.ic-btn),
:root[data-theme="rust"] .sp-dd-trigger { letter-spacing:.13em; }

/* ============================================================
   5 · КРОВЬ И БАРХАТ — стрельчатая арка у шапок
   ============================================================ */
:root[data-theme="blood"] {
  --shape-panel: polygon(7px 0, calc(100% - 7px) 0, 100% 7px, 100% 100%, 0 100%);
  --shape-tile:  polygon(4px 0, calc(100% - 4px) 0, 100% 4px, 100% 100%, 0 100%);
  --shape-btn:   polygon(4px calc(-1 * var(--press-y)), calc(100% - 4px) calc(-1 * var(--press-y)),
                         calc(100% - 4px) 0, 100% 4px, 100% 100%, 0 100%, 0 4px, 4px 0);
  /* остриё 8, а не 12 как в макете: в игре есть узкие шапки высотой 32 —
     на них арка в 12 съедала бы строку целиком */
  --shape-head:  polygon(0 8px, 50% 0, 100% 8px, 100% 100%, 0 100%);
  --shape-head-pad-t:8px;
  --shape-shadow: drop-shadow(0 10px 22px rgba(0,0,0,.8));
}
:root[data-theme="blood"] .rp-big { text-shadow:0 0 22px rgba(163,37,48,.45); }
