/* Игра в браузере — экраны на токенах сайта (см. site/assets/css/style.css).
   Подключается ПОСЛЕ style.css, тут только то, чего там нет. */

.igra-body { min-height: 100vh; display: flex; flex-direction: column; }

/* Фон игры — было ровное фиолетовое звёздное небо (.sky/.stars из style.css),
   потом (первый заход) его сменили на то же фото-«шапку», что на других
   страницах сайта (hero-desktop.webp). С Раунда 3 (spisok.md п.3, находка
   Егора: «сверху видно старое небо/фонарщика, киберпанк-город начинается
   ниже») фото убрано совсем. Причина не в одной опечатке в CSS — у общего
   hero-фото сайта нет версии «под тему», оно ОДНО на всех 13 тем и не гасло
   мгновенно: пока JS не навесил data-theme (первая краска страницы, медленный
   канал) или пока сама фотография догружается, ровно этот бесхозный кадр и
   торчал сверху — картинка, а не токен, не может смениться раньше, чем
   догрузится. Токены темы (--gold/--surface-2/--bg — applyTheme выставляет
   их на <html> синхронно, до первой краски) такой щели не оставляют: ниже
   (правило `[data-theme=...] .sky`) у восьми сюжетных тем этот градиент всё
   равно гасится в сплошной var(--bg) под их рендером, а для пяти тем без
   сцены (4 цветовые + Терминал) это и есть финальный вид — свой акцентный
   градиент на палитре темы вместо чужого фото каменного замка, которое не
   сочеталось смыслом ни с «Лесным», ни с «Сапфировым». */
.igra-body .sky {
  background:
    radial-gradient(1100px 650px at 15% -10%, color-mix(in srgb, var(--gold) 20%, transparent), transparent 60%),
    radial-gradient(900px 620px at 92% 6%, color-mix(in srgb, var(--gold-2, var(--gold)) 14%, transparent), transparent 60%),
    linear-gradient(180deg, var(--surface-2, var(--surface)) 0%, var(--bg) 70%);
}
.btn-primary { color: var(--on-gold, #1a1206); background: linear-gradient(135deg, var(--btn-a, var(--gold-2)), var(--btn-b, var(--gold))); }
.igra-body .sky::after, .igra-body .stars { display: none; }  /* 29.09: ни шума, ни звёзд под интерфейсом игры */

/* Четыре чисто цветовые темы (Фиолетовый/Сапфировый/Лесной/Янтарный) — без
   сюжетного рендера и без своего --surface-tint, поэтому общий .sky выше
   («20%/14%») читался владельцем 29.09 как «пустой плоский фон»: у них нет
   ни карточки-акцента, ни силуэта, которые обычно отвлекают взгляд от того,
   что фон почти не виден за топбаром/картами. Усиливаем ИМЕННО у этой
   четвёрки — не трогая формулу самого .sky (её всё ещё используют crt и
   восемь сюжетных тем как основу под свой рендер/скрим): три слоя вместо
   двух (третий — тёплое пятно снизу, чтобы фон не выглядел «светильником
   в одном углу»), плюс лёгкая виньетка по краям — тень по контуру экрана,
   собранная тем же radial-gradient, а не картинкой (закон 9 — только код). */
[data-theme="dark_purple"] .igra-body .sky,
[data-theme="dark_blue"] .igra-body .sky,
[data-theme="dark_green"] .igra-body .sky,
[data-theme="dark_amber"] .igra-body .sky {
  background:
    radial-gradient(1000px 640px at 12% -8%, color-mix(in srgb, var(--gold) 32%, transparent), transparent 55%),
    radial-gradient(820px 620px at 100% 4%, color-mix(in srgb, var(--gold-2) 22%, transparent), transparent 58%),
    radial-gradient(1000px 700px at 50% 118%, color-mix(in srgb, var(--gold) 16%, transparent), transparent 65%),
    radial-gradient(140% 120% at 50% 50%, transparent 55%, color-mix(in srgb, var(--bg) 65%, black) 100%),
    linear-gradient(180deg, var(--surface-2) 0%, var(--bg) 70%);
}
[data-theme="dark_purple"] .igra-body .sky::after,
[data-theme="dark_blue"] .igra-body .sky::after,
[data-theme="dark_green"] .igra-body .sky::after,
[data-theme="dark_amber"] .igra-body .sky::after { opacity: .16; }
[data-theme="dark_purple"] .igra-body .stars,
[data-theme="dark_blue"] .igra-body .stars,
[data-theme="dark_green"] .igra-body .stars,
[data-theme="dark_amber"] .igra-body .stars { opacity: .55; }
/* position+z-index обязательны: .theme-scene-render/.theme-scrim —
   position:fixed с z-index:0 (см. igra.css ниже), а без собственного z-index
   у .igra-main эти фоновые слои по правилам стекового контекста CSS красятся
   ПОСЛЕ обычного статичного контента — то есть поверх него, а не под ним.
   Из-за этого «непрозрачные на 92%» панели (js/themes.js) на глаз всё равно
   выглядели полупрозрачными: фон и подложка ложились НА карточки сверху,
   разбавляя их обратно. Нашли на снимках сюжетных тем (28.09,
   F:\Android\otchet\temy\perenos.md) — раньше это маскировалось тем, что и
   карточки, и фон были одинаково полупрозрачными, разницу не было видно. */
/* 30.09: z-index 3, а не 1. С Раунда 4 .theme-scrim стоит на z-index 2 (над рендером
   с z-index 1) — и оказался НАД содержимым с z-index 1: вся лента, пузыри и капсула
   ввода сюжетных тем были под вуалью цвета фона на 14–32% (пергамент Летописи на
   замере 175,165,140 вместо 248,238,214). Отсюда во многом и «плоско, без глубины». */
.igra-main { position: relative; z-index: 3; flex: 1; width: 100%; padding: 24px 16px 40px; }
.igra-shell { width: min(720px, 100%); margin-inline: auto; }
.igra-shell.wide { width: min(960px, 100%); }

/* Экран входа рисуется до setTopbarVisible(true) — топбара (и его логотипа)
   на странице ещё нет вовсе, поэтому свой, отдельный от шапки. */
/* display:flex (а не inline-flex у .brand): блок на всю строку, заголовок «Вход»
   (inline-block-плашка сюжетных тем) всегда уходит строкой ниже и не наезжает
   на надпись «RPG Studio», как бы ни сузилась ширина. */
.igra-auth-brand { display: flex; width: fit-content; max-width: 100%; justify-content: center; margin: 8px 0 20px; }

.igra-topbar {
  display: flex; align-items: center; justify-content: flex-start; gap: 12px;
  padding: 12px 16px; border-bottom: 1px solid var(--border);
  background: rgba(11, 10, 18, 0.72); backdrop-filter: blur(12px);
  position: sticky; top: 0; z-index: 40;
}
.igra-topbar .brand { font-size: 1.15rem; gap: 8px; }
.igra-topbar .brand-mark { width: 30px; height: 30px; }
/* Слева направо: меню, логотип-бренд, а чернила и аватар — у правого края
   (margin-left:auto). Раньше стояло space-between на трёх детях, и логотип
   оказывался посередине шапки (владелец 29.09: «звёздочка посередине»). */
.igra-topbar-actions { display: flex; align-items: center; gap: 10px; margin-left: auto; }
/* Чернила — не рубли (владелец 28.09: «Чернил: 110 ₽» читалось как цена, хотя
   это остаток расходуемого ресурса, курс 1 чернило = 1 ₽ только на пополнении).
   Капля вместо знака ₽, ₽ тут больше нигде не показывается. */
/* Чип чернил: раньше капля+число сидели голыми на шапке — на глаз тонут
   рядом с логотипом и меню. Своя плашка того же тона, что и остальные
   акценты темы (--gold), делает цифру заметной И даёт акцентному цвету
   темы ещё одну точку на экране (владелец 29.09, второй заход: «акцент на
   счётчике чернил» — одна из пяти опор различимости темы наравне с
   карточкой/орнаментом/шапкой/кнопкой). */
.igra-ink {
  display: inline-flex; align-items: center; gap: 5px; font-size: .85rem; color: var(--text-2);
  white-space: nowrap; padding: 5px 10px 5px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--gold) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--gold) 30%, transparent);
}
.igra-ink .ink-drop { flex: none; color: var(--gold-t); }
.igra-ink b { color: var(--gold-t); font-weight: 700; }
/* Чернила в шапке — ссылка в магазин с кружком «+», как у платной валюты в играх (23.10). Кружок залит акцентом
   темы, крест — цветом фона темы: пара та же, что у текста --gold-t на фоне, поэтому читается во всех 13 темах. */
a.igra-ink-buy { text-decoration: none; cursor: pointer; padding-right: 4px; }
a.igra-ink-buy:hover, a.igra-ink-buy:focus-visible { border-color: color-mix(in srgb, var(--gold) 55%, transparent); }
.igra-ink .ink-plus {
  flex: none; display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; margin-left: 1px;
  border-radius: 50%; background: var(--gold-t); color: var(--bg);
}
.igra-ink .ink-plus svg { display: block; }
a.igra-ink-buy:hover .ink-plus, a.igra-ink-buy:focus-visible .ink-plus { filter: brightness(1.12); }
@media (max-width: 360px) {
  .igra-ink .ink-plus { width: 15px; height: 15px; }
  .igra-ink .ink-plus svg { width: 8px; height: 8px; }
}
/* crt: шрифт чипов 1.2rem; с кляксами и пятизначными чернилами «+» переносил верхнюю полосу на вторую строку (59 -> 101-108 px)
   уже на 390. Тот же приём, что в klyaksy.css на 360: чип чернил чуть мельче, пока рядом есть кляксы. */
@media (max-width: 480px) {
  html[data-theme="crt"] .igra-topbar-actions:has(#klyBadge:not([hidden])) .igra-ink { font-size: .95rem; }
  html[data-theme="crt"] .igra-topbar-actions:has(#klyBadge:not([hidden])) .igra-kly { font-size: .95rem; }
  html[data-theme="crt"] .igra-topbar-actions:has(#klyBadge:not([hidden])) .ink-plus { width: 15px; height: 15px; }
}
@media (max-width: 340px) {
  /* body в селекторе: klyaksy.css грузится позже и с той же силой ставит .95rem */
  html[data-theme="crt"] body .igra-topbar-actions:has(#klyBadge:not([hidden])) .igra-ink,
  html[data-theme="crt"] body .igra-topbar-actions:has(#klyBadge:not([hidden])) .igra-kly { font-size: .8rem; padding-left: 5px; gap: 3px; }
}

/* 320-360 px: колокольчик + кляксы + чернила + аватар не влезали в строку, и шапка переезжала на вторую (владелец 24.10,
   замер на стенде: «12 345» чернил и «240» клякс, у владельца «без ограничений»). Сжимаем зазоры и чипы, пока рядом есть
   кляксы; большие числа короче в самом app.js (chipNumber: «12 тыс», владельцу «∞»). Замер: 13 тем x 320, «99 тыс» + «999» -
   одна строка. body в селекторе - klyaksy.css грузится позже. */
@media (max-width: 360px) {
  .igra-topbar { gap: 6px; padding-left: 8px; padding-right: 8px; }
  .igra-topbar-actions { gap: 4px; }
  body .igra-topbar-actions:has(#klyBadge:not([hidden])) .igra-ink { font-size: .74rem; padding: 4px 6px 4px 5px; gap: 3px; }
  body .igra-topbar-actions:has(#klyBadge:not([hidden])) a.igra-ink-buy { padding-right: 3px; }
  body .igra-topbar-actions:has(#klyBadge:not([hidden])) .ink-plus { width: 14px; height: 14px; }
}

[hidden] { display: none !important; }

/* Материал карточки — везде градиент --surface→--surface-tint (перенос
   .spill/#input-area из ui.html: там у каждой темы своя пара тонов
   материала, а не один плоский серый + цветная рамка), плюс
   backdrop-filter: blur — теперь, когда --surface стал прозрачнее (см.
   js/themes.js, второй заход 29.09: «задников не видно» — было почти
   сплошных .92/.96), сквозь карточку виден размытый задник темы вместо
   голой плашки. var(--surface-tint, var(--surface)) — фолбэк для четырёх
   цветовых тем: там своего тона материала нет (в исходнике они тоже без
   формы, см. комментарий у THEMES), фолбэк схлопывает градиент в плоский
   цвет, ничего не ломая. */
.igra-card, .igra-start-card, .igra-turn-assistant, .igra-turn-user,
.igra-chat-item, .igra-pick, .igra-lore-item {
  background: linear-gradient(165deg, var(--surface), var(--surface-tint, var(--surface)));
  backdrop-filter: blur(16px) saturate(1.05);
  -webkit-backdrop-filter: blur(16px) saturate(1.05);
}

.igra-card {
  padding: 24px; border-radius: var(--radius);
  border: 1px solid var(--border); margin-bottom: 16px;
}
.igra-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.igra-field label { font-size: .85rem; color: var(--text-2); }

/* Тёмная тема для всех полей ввода экранов игры — раньше правило цепляло
   только инпуты, обёрнутые в .igra-field, а textarea хода и select модели
   стоят в разметке БЕЗ такой обёртки и рисовались системным белым полем.
   Селектор широкий (по .igra-shell), чтобы больше не зависеть от обёртки. */
.igra-field input, .igra-field textarea, .igra-field select,
.igra-shell input, .igra-shell textarea, .igra-shell select {
  padding: 12px 14px; border-radius: 12px; background: rgba(255,255,255,.05);
  border: 1px solid var(--border-strong); color: var(--text); font: inherit;
  width: 100%; accent-color: var(--gold);
}
.igra-field textarea { min-height: 90px; resize: vertical; }
.igra-field input:focus, .igra-field textarea:focus, .igra-field select:focus,
.igra-shell input:focus, .igra-shell textarea:focus, .igra-shell select:focus {
  outline: none; border-color: var(--gold);
}
.igra-shell select::-webkit-scrollbar { width: 10px; }
.igra-shell option { background: #17131f; color: var(--text); }

/* Обводка фокуса с клавиатуры — везде в игре, поверх обычного :focus выше */
.igra-shell :focus-visible, .igra-topbar :focus-visible {
  outline: 2px solid var(--gold); outline-offset: 2px;
}

/* Выбор модели: системная стрелка select тоже белая на белом — рисуем свою */
.igra-select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  padding-right: 34px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23e8934c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 16px;
}
.igra-row { display: flex; gap: 10px; flex-wrap: wrap; }
.igra-row .btn { flex: none; }
.igra-error {
  padding: 12px 14px; border-radius: 12px; background: rgba(240,143,176,.1);
  border: 1px solid rgba(240,143,176,.35); color: var(--rose); font-size: .92rem;
  margin-bottom: 14px;
}
.igra-error[hidden] { display: none !important; }
.igra-error { scroll-margin: 90px 0; }
/* Находка 065: в «Летописи» и других сюжетных темах полупрозрачная розовая плашка с красным текстом поверх картинки
   задника читалась с контрастом ~1.3:1. Фон теперь сплошной тёмно-красный, текст светлый: читается на любом заднике. */
.igra-error:not([hidden]) {
  background: #2a1219; color: #ffd9de; border-color: rgba(240,143,176,.7);
}
.is-error { color: #ffb3c0; text-shadow: 0 1px 3px rgba(0,0,0,.85); }
input.is-invalid, textarea.is-invalid, select.is-invalid { border-color: rgba(240,143,176,.85) !important; box-shadow: 0 0 0 3px rgba(240,143,176,.18); }
.igra-hint { font-size: .82rem; color: var(--text-3); }

/* Список партий */
.igra-list { display: flex; flex-direction: column; gap: 10px; }
.igra-chat-item {
  display: flex; align-items: center; gap: 14px; padding: 14px 16px;
  border-radius: 14px; border: 1px solid var(--border);
  cursor: pointer; text-align: left; width: 100%;
}
.igra-chat-item:hover { background: var(--surface-2); border-color: var(--border-strong); }
.igra-chat-item .txt { flex: 1; min-width: 0; }
.igra-chat-item b { display: block; font-size: 1rem; }
.igra-chat-item span { display: block; font-size: .85rem; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.igra-chat-item .del { flex: none; }
.igra-empty { padding: 40px 20px; text-align: center; color: var(--text-3); }

/* Карточки миров/героев */
.igra-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 12px; margin-bottom: 8px; }
.igra-pick {
  padding: 16px; border-radius: 14px; border: 1px solid var(--border);
  cursor: pointer; text-align: left;
}
.igra-pick b { display: block; margin-bottom: 6px; }
/* Длинное название без пробелов (находка 027): режется внутри карточки, не вылезает под крестик и за край экрана */
.igra-pick { min-width: 0; }
.igra-pick b { overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; }
.igra-manage-card b { padding-right: 22px; }
.igra-pick span { font-size: .82rem; color: var(--text-2); display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.igra-pick.is-selected { border-color: var(--gold); background: rgba(232,147,76,.1); }
.igra-pick.is-add { display: flex; align-items: center; justify-content: center; color: var(--text-3); border-style: dashed; }
.igra-cards-empty { grid-column: 1 / -1; padding: 4px 2px 10px; font-size: .85rem; color: var(--text-3); }

/* Игровой экран ---------------------------------------------------------- */
.igra-game-head { justify-content: space-between; align-items: center; margin-bottom: 10px; flex-wrap: nowrap; gap: 10px; }
/* ── Экран партии: материал и шрифты (30.09, раунд 2) ─────────────────────
   Владелец 30.09: «окна скучные, шрифты плоские, не чувствуется глубины в
   обрамлениях». Причины были буквальные: у пяти тем дисплейный шрифт вообще
   без кириллицы (Orbitron, VT323, Special Elite, Quicksand — Google отдаёт им
   только латиницу), и русский текст молча падал в Georgia/Inter/Consolas; а
   пузыри были одной плоской плашкой с одной тенью. Теперь у экрана партии свои
   переменные (--pt-*), тема их переопределяет в themes.css, раздел «Экран
   партии»: шрифт заголовка и прозы (все с кириллицей, index.html), стекло
   поверх картины (приём SillyTavern VN), трёхслойная тень + светлая кромка,
   уголки-орнамент, ярлык говорящего (Night Call / Honkai), маркер «дальше» ▼
   (Hades / HSR). Референсы: F:\Android\otchet\igra_dizajn_0930\referensy\.
   --font-display не трогаем: им пользуются остальные экраны. */
:root {
  --pt-title: var(--font-display);
  --pt-title-weight: 700;
  --pt-title-case: none;
  --pt-title-track: .005em;
  --pt-prose: 'Lora', Georgia, serif;
  --pt-prose-size: 1.07rem;
  --pt-prose-lh: 1.74;
  --pt-ui: var(--font-body);
  --pt-glow: color-mix(in srgb, var(--gold) 45%, transparent);
  --pt-bubble: linear-gradient(168deg, var(--surface), var(--surface-tint, var(--surface)));
  --pt-sheen: linear-gradient(180deg, rgba(255,255,255,.075), rgba(255,255,255,0) 42%);
  --pt-frame: color-mix(in srgb, var(--border-strong) 85%, var(--gold));
  --pt-edge: rgba(255,255,255,.13);
  --pt-shade: 0 1px 1px rgba(0,0,0,.3), 0 6px 14px -6px rgba(0,0,0,.5), 0 24px 46px -22px rgba(0,0,0,.72);
  --pt-corner: color-mix(in srgb, var(--gold) 75%, transparent);
  --pt-corners:
    linear-gradient(var(--pt-corner), var(--pt-corner)) left 7px top 7px / 12px 1.5px no-repeat,
    linear-gradient(var(--pt-corner), var(--pt-corner)) left 7px top 7px / 1.5px 12px no-repeat,
    linear-gradient(var(--pt-corner), var(--pt-corner)) right 7px top 7px / 12px 1.5px no-repeat,
    linear-gradient(var(--pt-corner), var(--pt-corner)) right 7px top 7px / 1.5px 12px no-repeat,
    linear-gradient(var(--pt-corner), var(--pt-corner)) left 7px bottom 7px / 12px 1.5px no-repeat,
    linear-gradient(var(--pt-corner), var(--pt-corner)) left 7px bottom 7px / 1.5px 12px no-repeat,
    linear-gradient(var(--pt-corner), var(--pt-corner)) right 7px bottom 7px / 12px 1.5px no-repeat,
    linear-gradient(var(--pt-corner), var(--pt-corner)) right 7px bottom 7px / 1.5px 12px no-repeat;
  --pt-radius: var(--radius);
  --pt-tag-bg: color-mix(in srgb, var(--gold) 16%, transparent);
  --pt-tag-fg: color-mix(in srgb, var(--gold-t) 60%, var(--text));   /* чистый --gold-t на подложке ярлыка давал 4.2–4.4 у dark_green/dark_amber */
  --pt-tag-bd: color-mix(in srgb, var(--gold) 50%, transparent);
  --pt-user-bg: linear-gradient(160deg, color-mix(in srgb, var(--gold) 24%, var(--surface)), color-mix(in srgb, var(--gold) 11%, var(--surface-tint, var(--surface))));
  --pt-user-bd: color-mix(in srgb, var(--gold) 62%, transparent);
  --pt-glass: color-mix(in srgb, var(--bg) 80%, transparent);
}

/* Ореол текста цвета фона темы — читаемость заголовков поверх любого задника. */
.igra-game-head, .igra-begin { --halo: 0 0 2px var(--bg), 0 0 6px var(--bg), 0 0 14px var(--bg), 0 0 28px var(--bg); }
/* Под шапкой партии — мягкое затемнение-виньетка цвета фона (не плашка): у Пустоши
   заголовок лежал на светлом небе и читался слабо (снимок 30.09). */
.igra-game-head { position: relative; isolation: isolate; }
.igra-game-head::before {
  content: ''; position: absolute; inset: -14px 0 -10px 0; z-index: -1; pointer-events: none; /* 20.10: края ленты совпадают с блоком реплик (раньше выступала на 18 px влево) */
  /* полоса-«лента» цвета фона, тает вправо и по краям сверху/снизу: заголовок на светлом
     небе (Пустошь, Летопись) держит контраст без глухой плашки */
  background: linear-gradient(90deg, color-mix(in srgb, var(--bg) 80%, transparent), color-mix(in srgb, var(--bg) 80%, transparent) 55%, transparent 95%);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 22%, #000 78%, transparent); mask-image: linear-gradient(180deg, transparent, #000 22%, #000 78%, transparent);
}
.igra-title-wrap { min-width: 0; flex: 1; position: relative; padding-bottom: 14px; }
/* Заголовок партии — дисплейный шрифт темы, ореол из --bg, под ним разделитель
   «линия — ромб — линия» с угасанием (Genshin / HSR). */
.igra-title {
  margin: 0; cursor: pointer; border-radius: 8px; padding: 2px 4px; margin-left: -4px;
  font-family: var(--pt-title); font-weight: var(--pt-title-weight); text-transform: var(--pt-title-case);
  font-size: clamp(1.5rem, 1.1rem + 1.5vw, 2.2rem); line-height: 1.15; letter-spacing: var(--pt-title-track);
  color: var(--text);
  text-shadow: var(--halo), 0 0 22px var(--pt-glow);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: color .18s ease, text-shadow .18s ease;
}
.igra-title:hover, .igra-title:focus-visible { color: var(--gold-t); outline: none; }
.igra-title-wrap::before {
  content: ''; position: absolute; left: 0; right: 12%; bottom: 5px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold) 6%, color-mix(in srgb, var(--gold) 40%, transparent) 55%, transparent);
  box-shadow: 0 0 10px var(--pt-glow);
}
.igra-title-wrap::after {
  content: ''; position: absolute; left: 22px; bottom: 2px; width: 7px; height: 7px;
  background: linear-gradient(135deg, var(--gold-2), var(--gold)); transform: rotate(45deg);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--bg) 85%, transparent), 0 0 12px var(--pt-glow);
}
.igra-title-input {
  font: inherit; font-family: var(--font-display); font-size: inherit; font-weight: 600;
  color: var(--text); background: rgba(255,255,255,.05); border: 1px solid var(--gold);
  border-radius: 8px; padding: 4px 8px; margin-left: -8px; width: 100%; max-width: 420px;
}
.icon-btn-sm { flex: none; width: 34px; height: 34px; border-radius: 10px; border: 1px solid var(--border); }
.icon-btn-sm svg { width: 17px; height: 17px; }
.icon-btn-sm:disabled { opacity: .4; cursor: default; }
.icon-btn-sm:disabled:hover { background: none; color: var(--text-2); }

/* Карточка «с чего начинаем» — мастер + мир партии. Крупная, пока ход не
   сделан ни один (владелец 28.09: раньше это выглядело «сырой формой» —
   голый select и раскрывашка прямо над лентой), после первого хода
   renderStartCard() (app.js) добавляет .is-collapsed — те же самые
   modelSelect/modelHint/worldPanelBody, но в одну тонкую строку-чип, чтобы
   не отъедать место у ленты партии. */
.igra-start-card {
  padding: 16px 18px; border-radius: var(--radius);
  border: 1px solid var(--border); margin-bottom: 16px;
}
.igra-start-card .igra-field { margin-bottom: 8px; }
#modelHint { margin: 0 0 10px; }
.igra-world-panel { margin: 0; }
.igra-world-panel summary { cursor: pointer; font-size: .9rem; color: var(--text-2); padding: 6px 0; list-style-position: outside; }
.igra-world-panel .body { font-size: .9rem; color: var(--text-2); white-space: pre-wrap; padding: 8px 0 2px; }

.igra-start-card.is-collapsed {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 16px; padding: 8px 14px;
}
.igra-start-card.is-collapsed .igra-field {
  /* Базовый .igra-field — flex-direction: column (подпись НАД полем, форма
     на всю ширину). Тут поле сжато в чип, подпись и select должны стоять
     В РЯД — без переопределения direction здесь оставался column, и label
     улетал самостоятельной строкой над select, а align-items: center по
     column-оси центрировал её по ширине — то есть вправо от узкого select
     (владелец 28.09: «Мастер» висит над и правее своего select). */
  margin-bottom: 0; display: flex; flex-direction: row; align-items: center; gap: 8px; flex: none;
}
.igra-start-card.is-collapsed .igra-field label { font-size: .78rem; white-space: nowrap; }
.igra-start-card.is-collapsed .igra-select {
  padding: 5px 26px 5px 10px; font-size: .82rem; width: auto; min-width: 0;
}
.igra-start-card.is-collapsed #modelHint { display: none; }
.igra-start-card.is-collapsed .igra-world-panel { flex: none; }
.igra-start-card.is-collapsed .igra-world-panel summary { font-size: .82rem; padding: 0; }

.igra-turns { display: flex; flex-direction: column; gap: 20px; margin-bottom: 18px; padding-top: 4px; }
/* Материал реплик. Фон — три слоя: уголки-орнамент (--pt-corners), блик сверху
   (--pt-sheen) и сама поверхность темы (--pt-bubble); тень — контактная +
   средняя + рассеянная; внутри — светлая кромка сверху и тёмная снизу (толщина
   «стекла»). Размытие задника под пузырём умеренное (8px): пузырей в партии
   много, на телефоне каждый — отдельный слой. */
.igra-turn-assistant, .igra-turn-user { position: relative; animation: pt-rise .42s cubic-bezier(.2,.8,.2,1) both; }
.igra-turns.no-rise > .igra-turn-assistant, .igra-turns.no-rise > .igra-turn-user { animation: none; }
.igra-turns-earlier { align-self: center; }
@keyframes pt-rise { from { opacity: 0; transform: translateY(10px) scale(.992); } }
.igra-turn-assistant {
  font-family: var(--pt-prose); font-size: var(--pt-prose-size); line-height: var(--pt-prose-lh);
  letter-spacing: .003em; white-space: pre-wrap; overflow-wrap: break-word;
  font-kerning: normal; font-variant-numeric: oldstyle-nums proportional-nums; text-wrap: pretty;
  background: var(--pt-corners), var(--pt-sheen), var(--pt-bubble);
  box-shadow: var(--pt-shade), inset 0 1px 0 var(--pt-edge), inset 0 -1px 0 rgba(0,0,0,.22);
  backdrop-filter: blur(8px) saturate(1.1); -webkit-backdrop-filter: blur(8px) saturate(1.1);
}
/* Ярлык говорящего над текстом мастера — «Мастер» капсом с разрядкой, как имя
   в диалоговом окне игры. Абсолютный: в потоке он перехватил бы ::first-letter. */
.igra-turn-assistant::before {
  content: 'Мастер'; position: absolute; top: 13px; left: 20px; pointer-events: none;
  font: 700 .66rem/1 var(--pt-ui); letter-spacing: .18em; text-transform: uppercase; white-space: nowrap;
  color: var(--pt-tag-fg); padding: 4px 9px 4px 10px; border-radius: 999px;
  background: var(--pt-tag-bg); border: 1px solid var(--pt-tag-bd);
}
/* Маркер «дальше» у последнего готового ответа — треугольник, мягко дышит (Hades / HSR). */
.igra-turns > .igra-turn-assistant:last-child:not(.igra-turn-pending)::after {
  content: ''; position: absolute; left: 50%; margin-left: -5px; bottom: 10px; width: 10px; height: 7px; pointer-events: none;
  background: var(--gold-t); clip-path: polygon(0 0, 100% 0, 50% 100%);
  filter: drop-shadow(0 0 4px var(--pt-glow)); animation: pt-next 1.6s ease-in-out infinite;
}
@keyframes pt-next { 0%, 100% { transform: translateY(0); opacity: .95; } 50% { transform: translateY(3px); opacity: .55; } }
/* Вступление — буквица на три строки: только у первой реплики мастера в партии
   (если историю начал игрок, первой стоит его реплика — буквица у первого ответа). */
.igra-turns:not(.is-folded) > .igra-turn-assistant:not(.igra-turn-assistant ~ .igra-turn-assistant):not(.igra-turn-pending)::first-letter {
  float: left; font-family: var(--pt-title); font-weight: 700; font-size: 3.35em; line-height: .86;
  margin: .06em .12em -.04em 0; color: var(--gold-t);
  text-shadow: 0 2px 0 rgba(0,0,0,.25), 0 0 18px var(--pt-glow);
}
.igra-turn-user {
  /* Раньше — rgba(232,180,92,.12) и color: var(--gold-t): полупрозрачный
     янтарный вне зависимости от темы, а var(--gold-2) на светлой
     pink_kingdom и на dark_purple даёт контраст 2.6–2.7 к любому фону под
     ним (посчитано в F:\Android\otchet\temy\perenos.md) — и это не только
     из-за задника, так было бы и на плоском фоне. var(--text) вместо
     var(--gold-2) гарантирует ≥4.5:1 на всех восьми темах (та же панель,
     что у текста мастера), акцент остаётся золотой рамкой. */
  align-self: flex-end; max-width: 80%; padding: 12px 17px 13px; border-radius: 20px 20px 5px 20px;
  border: 1px solid var(--pt-user-bd); color: var(--text);
  background: var(--pt-sheen), var(--pt-user-bg);
  box-shadow: 0 1px 1px rgba(0,0,0,.28), 0 12px 26px -14px color-mix(in srgb, var(--gold) 55%, rgba(0,0,0,.6)), inset 0 1px 0 var(--pt-edge);
  backdrop-filter: blur(8px) saturate(1.1); -webkit-backdrop-filter: blur(8px) saturate(1.1);
  white-space: pre-wrap; overflow-wrap: break-word; font-family: var(--pt-ui); font-size: .98rem; line-height: 1.55;
}
.igra-caret { display: inline-block; width: 2px; height: 1em; background: var(--gold); vertical-align: -0.15em; margin-left: 2px; animation: igra-blink 1s steps(2) infinite; }
@keyframes igra-blink { 50% { opacity: 0; } }

/* «Мастер печатает» — раньше вместо этого висел ПУСТОЙ .igra-turn-assistant
   (только моргающий 2-пиксельный курсор) с первого чанка до последнего, а
   если поток обрывался ДО первого чанка (сеть/ошибка), пузырь так и
   оставался пустым навсегда — на светлых темах (pink_kingdom) это читалось
   как голая белая плашка без смысла (владелец прислал снимок 28.09, счёл
   «вёрсткой из 90-х»). Точки — понятная замена; appendStreamingBubble()
   в app.js убирает сам пузырь целиком, если ответ так и не начал приходить. */
.igra-turn-pending { min-height: 22px; display: flex; align-items: center; align-self: flex-start; min-width: 220px;
  animation: pt-rise .42s cubic-bezier(.2,.8,.2,1) both, pt-think 2.2s ease-in-out .42s infinite; }
/* «Мастер печатает»: рамка пузыря дышит светом акцента, точки — волной. Одна анимация
   на один пузырь, не на весь экран. */
@keyframes pt-think { 50% { border-color: var(--gold); } }
/* Подсказка в ожидании долгого ответа (app.js, appendStreamingBubble): отдельной строкой под точками */
.igra-turn-pending:has(.igra-wait-hint) { flex-wrap: wrap; row-gap: 8px; }
.igra-wait-hint { flex: 1 0 100%; font: italic .86rem/1.45 var(--pt-prose); color: color-mix(in srgb, currentColor 84%, transparent); /* цвет самого пузыря (пергамент светлый, у тёмных тем светлый): не токен --text-2 другой темы */ animation: pt-rise .42s cubic-bezier(.2,.8,.2,1) both; }
.igra-typing { display: inline-flex; align-items: center; gap: 6px; }
.igra-typing i {
  width: 7px; height: 7px; border-radius: 50%; background: var(--gold-t); display: block;
  box-shadow: 0 0 8px var(--pt-glow);
  animation: igra-typing-bounce 1.2s ease-in-out infinite;
}
.igra-typing i:nth-child(2) { animation-delay: .16s; }
.igra-typing i:nth-child(3) { animation-delay: .32s; }
.igra-typing::after { content: 'подбирает слова'; margin-left: 8px; font: italic .86rem/1 var(--pt-prose); color: color-mix(in srgb, currentColor 84%, transparent); /* цвет самого пузыря (пергамент светлый, у тёмных тем светлый): не токен --text-2 другой темы */ }
@keyframes igra-typing-bounce { 0%, 60%, 100% { transform: translateY(0); opacity: .4; } 30% { transform: translateY(-5px); opacity: 1; } }

/* #screen-game — единственный экран, где секция должна доставать до низа
   вьюпорта: .igra-main — flex-item на всю высоту .igra-body (flex:1), но сам
   он не flex-контейнер, а секции внутри — обычные блоки высотой по контенту.
   При короткой партии (пара ходов) #screen-game заканчивался сразу под
   последним сообщением, а .igra-input-bar (position: sticky; bottom: 0)
   стикуется только в границах своего родителя — если у родителя нет запаса
   высоты вниз, стикать некуда, и полоса ввода вставала не у низа экрана,
   а сразу после сообщений, с фоном темы голой плашкой под ней до самого низа
   страницы (владелец 28.09: «полоса ввода после сообщений, плашка фона под
   ней»). min-height гарантирует запас, чтобы sticky всегда мог дотянуть
   полосу до низа вьюпорта — на 100dvh (учитывает адресную строку/панели
   браузера), с запасным 100vh для браузеров без dvh. */
#screen-game.igra-shell {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
#screen-game.igra-shell .igra-turns { flex: 1 0 auto; }
/* 30.09: пустая партия прокручивалась на 105 px (телефон) / 123 px (ПК): min-height секции = 100dvh,
   а над ней ещё шапка (57-59 px) и верхний отступ .igra-main, а под ней нижний отступ .igra-main —
   страница выходила выше окна, при прокрутке заголовок уходил под шапку, а под капсулой показывалась
   тёмная плашка градиента .igra-input-bar. Теперь, пока открыта партия, .igra-main сам тянется на
   остаток окна под шапкой, секция заполняет его целиком (без собственных 100dvh) и нижнего отступа нет:
   капсула стоит у низа окна, страница ровно в окно. Длинная партия прокручивается как раньше. */
.igra-body:has(#screen-game:not([hidden])) { min-height: 100vh; min-height: 100dvh; }
.igra-main:has(#screen-game:not([hidden])) { display: flex; flex-direction: column; padding-bottom: 0; }
.igra-main:has(#screen-game:not([hidden])) > #screen-game { flex: 1 0 auto; min-height: 0; }

/* Поле ввода хода: прибито к низу, растёт по высоте само (app.js трогает
   height напрямую), круглая кнопка отправки — вместо прежней текстовой
   «Ход»/«Заново» пары. Подсказка про Enter/Shift+Enter раньше жила прямо в
   placeholder и лезла на телефоне в три строки текста вместо одной короткой
   («что вы делаете?») — теперь это отдельная строка, и показывается только
   там, где есть мышь/трекпад (hover:hover) И точный указатель (pointer:fine):
   у тач-телефона в норме нет ни того, ни другого, клавиши Shift на
   экранной клавиатуре тоже нет — подсказка там была не подсказкой, а шумом.

   env(safe-area-inset-bottom) — отступ снизу на телефонах с домашним
   индикатором (iPhone): без него кнопка отправки утыкается прямо в
   системную полосу жестов. interactive-widget=resizes-content в <meta
   viewport> (index.html) — чтобы при открытии клавиатуры браузер уменьшал
   layout-вьюпорт вместе с visual-вьюпортом: без этого sticky продолжает
   считать «низ» от старой, большей высоты, и полоса ввода утекает под
   клавиатуру вместо того, чтобы всплыть над ней. */
.igra-input-bar {
  position: sticky; bottom: 0; z-index: 2;
  padding: 10px 0 max(14px, env(safe-area-inset-bottom));
}
/* Подложка под капсулой: раньше фон самой полосы — прямоугольник шириной с колонку, и его
   боковые края и углы торчали из-под скруглённой капсулы на фоне задника темы (аудит 03.10, P2-3).
   Теперь подложка шире колонки и гаснет к краям и кверху, своих краёв у неё не видно. */
.igra-input-bar::before {
  content: ''; position: absolute; z-index: -1; pointer-events: none;
  top: 0; bottom: 0; left: -16px; right: -16px;
  background: linear-gradient(0deg, color-mix(in srgb, var(--bg) 92%, transparent) 30%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 40px, #000 calc(100% - 40px), transparent);
  mask-image: linear-gradient(90deg, transparent, #000 40px, #000 calc(100% - 40px), transparent);
}
@media (max-width: 700px) { .igra-input-bar::before { -webkit-mask-image: none; mask-image: none; } }
.igra-turn-user:has(.igra-msg-more) { padding-right: 40px; }

/* Капсула ввода — один скруглённый контур на весь блок (textarea сверху,
   тулбар снизу), а не текстовое поле и круглая кнопка порознь рядом друг с
   другом, как было раньше («уровень школьника», слово владельца 29.09).
   Материал — тот же градиент surface→surface-tint, что у карточек
   (см. правило выше в файле), поэтому капсула не плоская голая рамка, а
   стекло того же тона, что и остальной интерфейс темы. */
.igra-composer {
  position: relative; display: flex; flex-direction: column; gap: 4px;
  border-radius: 26px; border: 1px solid var(--pt-frame);
  /* Капсула сама и есть поле (без «поля в поле»): тёмное стекло поверх картины,
     блик сверху, толщина кромками, подъём трёхслойной тенью. */
  background: var(--pt-sheen), linear-gradient(170deg, color-mix(in srgb, var(--surface) 70%, var(--pt-glass)), var(--pt-glass));
  backdrop-filter: blur(18px) saturate(1.15);
  -webkit-backdrop-filter: blur(18px) saturate(1.15);
  padding: 8px 8px 8px 16px;
  box-shadow: var(--pt-shade), inset 0 1px 0 var(--pt-edge), inset 0 -1px 0 rgba(0,0,0,.25);
  transition: border-color .18s ease, box-shadow .22s ease;
}
.igra-composer:focus-within {
  border-color: var(--gold);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 26%, transparent), 0 0 28px -4px var(--pt-glow),
              var(--pt-shade), inset 0 1px 0 var(--pt-edge);
}
.igra-turn-input {
  display: block; width: 100%; resize: none; overflow-y: auto;
  min-height: 24px; max-height: 160px; line-height: 1.45;
  /* Своя textarea без рамки/фона общего правила `.igra-shell textarea` —
     капсула уже несёт и то, и другое, второй контур внутри выглядел бы
     полем в поле. */
  background: none; border: 0; border-radius: 0; padding: 6px 2px 4px;
}
html .igra-shell .igra-composer #turnInput.igra-turn-input {
  padding: 10px 4px 6px; min-height: 42px; font-size: 1rem; color: var(--text);
  background: transparent; border: 0; border-radius: 0; box-shadow: none;
}
html .igra-shell .igra-composer #turnInput.igra-turn-input:focus { outline: none; box-shadow: none; border: 0; }
.igra-composer-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-top: 6px;
  border-top: 1px solid color-mix(in srgb, var(--border-strong) 45%, transparent); }

/* Таблетка «Мастер · мир» — заменяет отдельную карточку #startCard над
   лентой (владелец 29.09: «сырая форма» — голый select и раскрывашка прямо
   над сообщениями). Открывает #masterPopover, те же modelSelect/modelHint/
   worldPanelBody, что были в карточке — просто в другом месте разметки.
   30.09: чип с рамкой акцента (NovelAI), значок в кружке-медальоне. */
.igra-master-pill {
  display: inline-flex; align-items: center; gap: 7px; max-width: 58%;
  padding: 5px 12px 5px 5px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--gold) 45%, var(--border-strong));
  background: var(--pt-sheen), color-mix(in srgb, var(--gold) 10%, var(--surface-2)); color: var(--text); font-family: var(--pt-ui); font-size: .82rem; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;
  box-shadow: 0 1px 2px rgba(0,0,0,.3), 0 6px 14px -8px rgba(0,0,0,.6), inset 0 1px 0 var(--pt-edge);
  transition: background .15s ease, color .15s ease, border-color .15s ease, transform .15s ease, box-shadow .15s ease;
}
.igra-master-pill::after {
  content: ''; flex: none; width: 6px; height: 6px; margin: -3px 1px 0 2px;
  border-right: 1.6px solid var(--gold-t); border-bottom: 1.6px solid var(--gold-t); transform: rotate(45deg);
  transition: transform .2s ease;
}
.igra-master-pill[aria-expanded="true"]::after { transform: rotate(225deg); margin-top: 3px; }
.igra-master-pill:hover, .igra-master-pill:focus-visible { color: var(--text); border-color: var(--gold); transform: translateY(-1px);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 18%, transparent), 0 8px 18px -8px var(--pt-glow), inset 0 1px 0 var(--pt-edge); outline: none; }
.igra-master-pill:active { transform: translateY(0); }
.igra-master-pill svg {
  flex: none; box-sizing: content-box; padding: 5px; border-radius: 50%; color: var(--on-gold, #1a1206);
  background: linear-gradient(135deg, var(--gold-2), var(--gold)); box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 0 10px -2px var(--pt-glow);
}
.igra-master-pill span { overflow: hidden; text-overflow: ellipsis; }

/* «Ход с картинкой» (21.10): переключатель рядом с плашкой мастера; в подписи — цена ближайшего хода. Включён — золотой
   контур и закрашенный значок, выключен — приглушённый контур (состояние не только цветом: подпись «С картинкой/Без картинки»). */
.igra-turn-image {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  padding: 5px 11px 5px 7px; border-radius: 999px; border: 1px dashed var(--border-strong);
  background: transparent; color: var(--text-2); font-family: var(--pt-ui); font-size: .8rem; font-weight: 600;
  white-space: nowrap; cursor: pointer; transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.igra-turn-image[hidden] { display: none; }
.igra-turn-image svg { flex: none; }
.igra-turn-image span { flex: none; white-space: nowrap; }   /* слова и цена не сжимаются (21.10): сокращается имя мастера */
.igra-turn-image .ti-slash { display: none; }
.igra-turn-image[aria-pressed="false"] { color: var(--text-2); opacity: .85; }
.igra-turn-image[aria-pressed="false"] .ti-slash { display: inline; }
.igra-turn-image .ti-drop { flex: none; opacity: .8; }
.igra-turn-image[aria-pressed="true"] {
  border: 1px solid color-mix(in srgb, var(--gold) 55%, var(--border-strong)); color: var(--text);
  background: color-mix(in srgb, var(--gold) 14%, var(--surface-2));
}
.igra-turn-image[aria-pressed="true"] svg { color: var(--gold-t, var(--gold)); }
.igra-turn-image:hover, .igra-turn-image:focus-visible { color: var(--text); border-color: var(--gold); outline: none; }
.igra-composer-toolbar:has(.igra-turn-image:not([hidden])) .igra-master-pill { flex: 0 1 auto; min-width: 0; max-width: none; }
.igra-turn-image .ti-price { font-variant-numeric: tabular-nums; }
/* узкий экран: рядом ещё плашка мастера, микрофон и «отправить» — слова прячем, остаются значок и цена; состояние видно по рамке
   (золотая сплошная — с картинкой, пунктир — без), в aria-label и подсказке слова есть всегда */
@media (max-width: 520px) {
  .igra-turn-image .ti-words { display: none; }
  .igra-turn-image { padding: 5px 10px 5px 8px; gap: 5px; }
  .igra-composer-toolbar:has(.igra-turn-image:not([hidden])) .igra-master-pill { max-width: none; }
}

.igra-input-hint { display: none; flex: 1; text-align: center; margin: 0; font-size: .74rem; color: var(--text-2); letter-spacing: .01em; }
.igra-input-hint kbd, .igra-input-hint b { font: inherit; }
/* Только мышь и не узкое окно: в окне ПК шириной с телефон подсказка
   сжималась в три строки рядом с «таблеткой» мастера (снимки 29.09) */
@media (hover: hover) and (pointer: fine) and (min-width: 600px) {
  .igra-input-hint { display: block; }
}
/* Кнопка хода: литой кружок акцента — блик сверху, тень внутри снизу, кольцо и
   свечение; нажатие вдавливает. */
.igra-send-btn {
  position: relative; flex: none; margin-left: auto; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  color: var(--on-gold, #1a1206); border: 1px solid color-mix(in srgb, var(--gold-2) 70%, #fff); cursor: pointer;
  background: radial-gradient(120% 90% at 50% 0%, rgba(255,255,255,.38), rgba(255,255,255,0) 55%), linear-gradient(160deg, var(--gold-2), var(--gold));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 16%, transparent), 0 10px 22px -8px var(--pt-glow), 0 2px 3px rgba(0,0,0,.35),
              inset 0 -3px 6px rgba(0,0,0,.22);
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease, opacity .15s ease, filter .15s ease;
}
.igra-send-btn:hover { transform: translateY(-1px); filter: brightness(1.08); box-shadow: 0 0 0 4px color-mix(in srgb, var(--gold) 24%, transparent), 0 12px 26px -8px var(--pt-glow), 0 2px 3px rgba(0,0,0,.35), inset 0 -3px 6px rgba(0,0,0,.22); }
.igra-send-btn:active { transform: translateY(1px) scale(.97); box-shadow: 0 0 0 2px color-mix(in srgb, var(--gold) 20%, transparent), inset 0 3px 6px rgba(0,0,0,.35); }
.igra-send-btn:focus-visible { outline: 2px solid var(--gold-t); outline-offset: 3px; }
/* Пусто в поле — кнопка пригашена и не кликается, как в образце (Claude):
   раньше кружок был всегда ярким, даже когда отправлять нечего. 30.09: не
   прозрачная, а «выключенная» — утопленный кружок с видимой стрелкой. */
.igra-send-btn:disabled {
  cursor: default; transform: none; filter: none; color: var(--text-2);
  background: color-mix(in srgb, var(--surface-2) 80%, transparent); border-color: var(--border-strong);
  box-shadow: inset 0 2px 5px rgba(0,0,0,.3);
}
.igra-send-btn[data-state="stop"] {
  color: var(--text); background: var(--surface-2); border-color: var(--border-strong);
  box-shadow: inset 0 1px 0 var(--pt-edge);
}
.igra-send-btn[data-state="stop"] svg { width: 15px; height: 15px; }

/* Окно «Модель» (+ «Мир партии»). Лежит в <body>, а не в экране игры: слой
   .igra-main (z-index 1) оказывался под шапкой (40), и окно наезжало на
   заголовок «Новая партия» (снимок владельца 29.09). Выше меню (60).
   Телефон — панель снизу на всю ширину, ПК — окно у кнопки (left/bottom
   ставит app.js, placeMasterPopover). Фон непрозрачный: --bg под градиентом,
   иначе текст читался бы поверх ленты. */
.igra-master-popover-backdrop { position: fixed; inset: 0; z-index: 70; background: radial-gradient(120% 90% at 50% 100%, rgba(6,5,10,.66), rgba(6,5,10,.4)); backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }
.igra-master-popover-backdrop[hidden] { display: none; }
.igra-master-popover {
  position: fixed; z-index: 71; left: 12px; bottom: 80px;
  width: 700px; max-width: calc(100vw - 24px); max-height: min(70vh, 600px);
  display: flex; flex-direction: column; overflow: hidden; overflow: clip; /* clip: окно не прокрутить программно (фокус/scrollIntoView), шапка стоит на месте (083) */
  padding: 18px 18px 0; border-radius: calc(var(--radius) + 4px); border: 1px solid var(--pt-frame);
  color: var(--text);
  /* Непрозрачное «стекло»: --bg под поверхностью, блик и уголки сверху — окно
     лежит над лентой, текст под ним просвечивать не должен. */
  background-color: var(--bg);
  background-image: var(--pt-corners), var(--pt-sheen), radial-gradient(90% 60% at 15% 0%, color-mix(in srgb, var(--gold) 12%, transparent), transparent 70%), linear-gradient(165deg, var(--surface), var(--surface-tint, var(--surface)));
  box-shadow: 0 2px 6px rgba(0,0,0,.35), 0 30px 80px -20px rgba(0,0,0,.8), 0 0 40px -12px var(--pt-glow), inset 0 1px 0 var(--pt-edge), inset 0 0 0 1px rgba(255,255,255,.03);
  animation: pt-pop .24s cubic-bezier(.2,.8,.2,1) both;
}
@keyframes pt-pop { from { opacity: 0; transform: translateY(12px) scale(.985); } }
/* Затухание снизу: если под последней строкой окна есть ещё содержимое (класс ставит app.js). */
/* 15.10, владелец: на телефоне после нажатия «Показывать ответ целиком» окно растянулось, а содержимое осталось
   обрезанным по старой высоте и затёртым градиентом. Градиент был отдельным слоем (::after) поверх окна: при
   смене высоты (панель браузера, фокус на переключателе) Chrome на Android рисовал его по старой высоте и не
   перерисовывал тело. Теперь затухание — маска на самом прокручиваемом теле: один слой, высота всегда та же. */
.igra-master-popover.has-more .igra-sheet-body {
  -webkit-mask-image: linear-gradient(180deg, #000 calc(100% - 44px), transparent);
  mask-image: linear-gradient(180deg, #000 calc(100% - 44px), transparent);
}
.igra-master-popover[hidden] { display: none; }
.igra-sheet-body { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; padding: 2px 2px 16px; }
.igra-sheet-head {
  flex: none; display: flex; align-items: center; gap: 10px; margin-bottom: 14px; padding-bottom: 13px; position: relative;
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, var(--gold) 4%, color-mix(in srgb, var(--gold) 30%, transparent) 60%, transparent) 1;
}
/* ромб на разделителе под заголовком окна — тот же знак, что под заголовком партии */
.igra-sheet-head::after {
  content: ''; position: absolute; left: 18px; bottom: -4px; width: 7px; height: 7px; transform: rotate(45deg);
  background: linear-gradient(135deg, var(--gold-2), var(--gold)); box-shadow: 0 0 10px var(--pt-glow);
}
.igra-sheet-title { margin: 0; flex: 1; min-width: 0; font-family: var(--pt-title); font-weight: var(--pt-title-weight); text-transform: var(--pt-title-case); letter-spacing: var(--pt-title-track); font-size: 1.4rem; color: var(--text); line-height: 1.1; text-shadow: 0 0 18px var(--pt-glow); }
.igra-sheet-count {
  flex: none; font-family: var(--pt-ui); font-size: .76rem; font-weight: 700; letter-spacing: .04em; color: var(--text); padding: 4px 11px; border-radius: 999px;
  background: color-mix(in srgb, var(--gold) 18%, var(--surface-2, transparent)); border: 1px solid color-mix(in srgb, var(--gold) 55%, transparent);
  box-shadow: inset 0 1px 0 var(--pt-edge);
}
.igra-sheet-close {
  width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  color: var(--text); background: var(--pt-sheen), var(--surface-2, transparent); border: 1px solid var(--border-strong);
  box-shadow: 0 2px 6px -2px rgba(0,0,0,.5), inset 0 1px 0 var(--pt-edge);
  transition: border-color .15s ease, transform .2s ease, box-shadow .15s ease;
}
.igra-sheet-close:hover, .igra-sheet-close:focus-visible { border-color: var(--gold); transform: rotate(90deg); box-shadow: 0 0 14px -2px var(--pt-glow), inset 0 1px 0 var(--pt-edge); outline: none; }
/* Список моделей: на ПК две колонки, на телефоне одна плотная. Все 7 видны сразу. */
.igra-model-list { list-style: none; margin: 0 0 14px; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.igra-model-list > li { display: flex; }
.igra-model-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; cursor: pointer; position: relative;
  padding: 9px 12px; border-radius: max(8px, calc(var(--pt-radius) - 4px)); border: 1px solid color-mix(in srgb, var(--border-strong) 80%, transparent);
  background: var(--pt-sheen), color-mix(in srgb, var(--surface-2) 70%, var(--bg)); color: var(--text); font: inherit; font-family: var(--pt-ui);
  box-shadow: 0 1px 2px rgba(0,0,0,.3), inset 0 1px 0 var(--pt-edge);
  transition: border-color .15s ease, background .15s ease, transform .15s ease, box-shadow .15s ease;
}
.igra-model-item:hover, .igra-model-item:focus-visible { border-color: var(--gold); transform: translateY(-1px); outline: none;
  box-shadow: 0 10px 20px -12px rgba(0,0,0,.8), 0 0 0 3px color-mix(in srgb, var(--gold) 14%, transparent), inset 0 1px 0 var(--pt-edge); }
.igra-model-item:active { transform: translateY(0) scale(.99); }
/* Поставщик мастера сейчас не отвечает (models.js isModelDown): серым, без наведения */
.igra-model-item.is-down { opacity: .5; filter: grayscale(.8); cursor: not-allowed; }
.igra-model-item.is-down:hover { transform: none; border-color: transparent; }
.igra-model-item.is-down .igra-model-note { color: var(--rose); }
.igra-model-item[aria-checked="true"] {
  border-color: var(--gold);
  background: var(--pt-sheen), linear-gradient(160deg, color-mix(in srgb, var(--gold) 26%, var(--surface-2)), color-mix(in srgb, var(--gold) 9%, var(--bg)));
  box-shadow: 0 0 0 1px var(--gold), 0 12px 26px -12px var(--pt-glow), inset 0 1px 0 var(--pt-edge);
}
.igra-model-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.igra-model-name { font-size: .96rem; font-weight: 700; color: var(--text); overflow-wrap: anywhere; line-height: 1.2; }
.igra-model-note { font-size: .76rem; line-height: 1.3; color: var(--text-2); overflow-wrap: anywhere; }
.igra-model-tags { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 1px; }
.igra-model-tag { font-size: .68rem; line-height: 1.25; padding: 1px 7px; border-radius: 999px; color: var(--text-2); border: 1px solid var(--border-strong); background: transparent; overflow-wrap: anywhere; }
.igra-model-tag.is-warn { color: var(--text); border-color: var(--gold); }
.igra-model-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.igra-model-price { flex: none; font-size: .74rem; color: var(--text-2); white-space: nowrap; }
.igra-model-tick {
  flex: none; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; line-height: 1;
  border: 1.5px solid var(--border-strong); font-weight: 800; font-size: .8rem; color: var(--on-gold, #1a1206);
  box-shadow: inset 0 2px 4px rgba(0,0,0,.3);
}
.igra-model-item[aria-checked="true"] .igra-model-tick { background: radial-gradient(100% 80% at 50% 0%, rgba(255,255,255,.4), transparent 60%), linear-gradient(135deg, var(--btn-a, var(--gold-2)), var(--btn-b, var(--gold))); border-color: var(--gold-t); box-shadow: 0 0 12px var(--pt-glow); } /* концы градиента --btn-a/--btn-b подтянуты под цвет текста --on-gold (themes.js, readableTokens) */
/* «Рекомендуем» (catalog.yaml: recommended): зелёная рамка и подпись; выбранная — та же рамка
   поверх золотой заливки выбора. Память мастера — строка под подписью. */
.igra-model-item.is-recommended {
  border-color: color-mix(in srgb, var(--ok, #4cc985) 80%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--ok, #4cc985) 45%, transparent), 0 1px 2px rgba(0,0,0,.3), inset 0 1px 0 var(--pt-edge);
}
.igra-model-item.is-recommended:hover, .igra-model-item.is-recommended:focus-visible { border-color: var(--ok, #4cc985); }
.igra-model-item.is-recommended[aria-checked="true"] {
  border-color: var(--ok, #4cc985);
  box-shadow: 0 0 0 1px var(--ok, #4cc985), 0 12px 26px -12px var(--pt-glow), inset 0 1px 0 var(--pt-edge);
}
/* Мастер временно скрыт защитой от убытка (сервер, catalog: unavailable): виден, но не выбирается */
.igra-model-item.is-unavailable { opacity: .55; cursor: not-allowed; }
.igra-model-item.is-unavailable:hover { border-color: var(--border, transparent); }
.igra-model-rec {
  align-self: flex-start; font-size: .64rem; font-weight: 800; letter-spacing: .07em; text-transform: uppercase; line-height: 1.3;
  color: var(--ok, #4cc985); padding: 1px 8px; border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--ok, #4cc985) 60%, transparent);
  /* подложка непрозрачная: токен --ok подтянут к --bg, а на полупрозрачной подложке фон ложится картинкой темы (замер 16.10: 3,3:1 в «Летописи») */
  background: color-mix(in srgb, var(--ok, #4cc985) 12%, var(--bg));
}
.igra-model-mem { font-size: .72rem; line-height: 1.3; color: var(--text-2); overflow-wrap: anywhere; }
/* «Премиум» (Qwen3.8 Max): тот же бейдж, золотой вместо зелёного */
.igra-model-rec.is-premium {
  color: var(--gold-t, var(--gold)); border-color: color-mix(in srgb, var(--gold) 60%, transparent);
  background: color-mix(in srgb, var(--gold) 14%, var(--bg));
}
/* «Вашего запаса хватит на 1 ход этого мастера» */
.igra-model-afford { font-size: .72rem; line-height: 1.3; color: var(--text); overflow-wrap: anywhere; }

/* Кольцо «Память и расход» в шапке чата (ring.js): дуга — самое «тесное» значение. */
.igra-ring-btn { position: relative; }
.igra-ring-svg { display: block; }
.icon-btn-sm.igra-ring-btn svg { width: 22px; height: 22px; }
.igra-ring-track { stroke: color-mix(in srgb, var(--text) 20%, transparent); }
.igra-ring-arc { stroke: var(--gold-t, var(--gold)); transition: stroke-dashoffset .4s ease, stroke .2s ease; }
.igra-ring-btn[data-level="warn"] .igra-ring-arc { stroke: var(--warn-fill, var(--warn, #e9b43c)); }
.igra-ring-btn[data-level="danger"] .igra-ring-arc { stroke: var(--rose); }
@media (prefers-reduced-motion: reduce) { .igra-ring-arc { transition: none; } }

.igra-ring-backdrop { position: fixed; inset: 0; z-index: 70; background: rgba(6,5,10,.28); }
.igra-ring-backdrop[hidden] { display: none; }
.igra-ring-sheet {
  position: fixed; z-index: 71; top: 72px; right: 16px; width: 380px; max-width: calc(100vw - 24px); max-height: min(78vh, 640px);
  display: flex; flex-direction: column; overflow: hidden; padding: 14px 16px 6px;
  border-radius: calc(var(--radius) + 2px); border: 1px solid var(--pt-frame, var(--border-strong)); color: var(--text);
  background-color: var(--bg);
  background-image: var(--pt-sheen), radial-gradient(90% 60% at 85% 0%, color-mix(in srgb, var(--gold) 12%, transparent), transparent 70%), linear-gradient(165deg, var(--surface), var(--surface-tint, var(--surface)));
  box-shadow: 0 2px 6px rgba(0,0,0,.35), 0 30px 80px -20px rgba(0,0,0,.8), 0 0 40px -12px var(--pt-glow), inset 0 1px 0 var(--pt-edge);
  font-family: var(--pt-ui); animation: pt-pop .2s cubic-bezier(.2,.8,.2,1) both;
}
.igra-ring-sheet[hidden] { display: none; }
.igra-ring-sheet.is-dragging { transition: none; animation: none; }
.igra-ring-grip { display: none; }
.igra-ring-top { flex: none; display: flex; align-items: center; gap: 10px; padding-bottom: 10px; margin-bottom: 4px; border-bottom: 1px solid var(--border-strong); }
.igra-ring-title { margin: 0; flex: 1; min-width: 0; font-family: var(--pt-title); font-weight: var(--pt-title-weight); text-transform: var(--pt-title-case); letter-spacing: var(--pt-title-track); font-size: 1.15rem; line-height: 1.15; color: var(--text); }
.igra-ring-close { flex: none; }
.igra-ring-body { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 4px 0 10px; }
.igra-ring-row { padding: 10px 0; }
.igra-ring-row + .igra-ring-row { border-top: 1px solid color-mix(in srgb, var(--border-strong) 70%, transparent); }
.igra-ring-row-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.igra-ring-row-title { margin: 0; font-size: .92rem; font-weight: 700; color: var(--text); }
.igra-ring-row-value { font-size: .82rem; color: var(--text-2); font-variant-numeric: tabular-nums; }
.igra-ring-row-note { margin: 6px 0 0; font-size: .8rem; line-height: 1.4; color: var(--text-2); overflow-wrap: anywhere; }
.igra-ring-bar { margin-top: 8px; height: 8px; border-radius: 999px; overflow: hidden; background: color-mix(in srgb, var(--text) 14%, transparent); }
.igra-ring-bar-fill { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, var(--gold), var(--gold-2)); transition: width .4s ease; }
.igra-ring-bar[data-level="warn"] .igra-ring-bar-fill { background: var(--warn-fill, var(--warn, #e9b43c)); }
.igra-ring-bar[data-level="danger"] .igra-ring-bar-fill { background: var(--rose); }
.igra-ring-shop { display: inline-block; margin-top: 8px; font-size: .84rem; font-weight: 700; color: var(--gold-t, var(--gold)); text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 700px) {
  .igra-ring-sheet {
    top: auto !important; right: 0 !important; left: 0; bottom: 0; width: 100%; max-width: 100%;
    max-height: 85vh; max-height: 85dvh; border-radius: 22px 22px 0 0; border-bottom: 0;
    padding: 6px 16px calc(8px + env(safe-area-inset-bottom)); transition: transform .2s ease;
  }
  .igra-ring-grip { display: block; flex: none; width: 40px; height: 4px; border-radius: 999px; margin: 2px auto 8px; background: color-mix(in srgb, var(--text) 35%, transparent); }
  .igra-ring-backdrop { background: rgba(6,5,10,.5); }
}

.igra-world-panel-title { margin: 0 0 6px; font-size: .82rem; color: var(--text-2); font-weight: 700; }
.igra-world-panel { border-top: 1px solid var(--border); padding-top: 12px; }
.igra-world-panel .body { font-size: .88rem; color: var(--text-2); }
.igra-world-rows { margin: 0; display: grid; grid-template-columns: max-content 1fr; gap: 6px 12px; }
.igra-world-rows dt { font-weight: 700; color: var(--text); }
.igra-world-rows dd { margin: 0; color: var(--text-2); overflow-wrap: anywhere; }
@media (max-width: 700px) {
  .igra-master-popover {
    left: 0 !important; right: 0; bottom: 0 !important; width: 100%; max-width: 100%;
    max-height: 88vh; max-height: 88dvh; border-radius: 22px 22px 0 0; border-bottom: 0;
    padding: 12px 12px env(safe-area-inset-bottom);
  }
  .igra-sheet-head { margin-bottom: 8px; padding-bottom: 8px; }
  .igra-model-list { grid-template-columns: 1fr; gap: 6px; margin-bottom: 10px; }
  .igra-model-item { padding: 7px 11px; }
  .igra-model-note { font-size: .72rem; }
}
@media (max-width: 700px) and (max-height: 700px) {
  .igra-model-item { padding: 6px 10px; }
  .igra-model-name { font-size: .9rem; }
}

/* Выбор «кто начинает» — две карточки над пустой лентой новой партии. */
.igra-begin { margin: 8px 0 18px; animation: pt-rise .45s cubic-bezier(.2,.8,.2,1) both; }
/* Заголовок блока — дисплейный шрифт темы с ромбами по бокам (Genshin). */
.igra-begin-title {
  display: flex; align-items: center; gap: 12px; margin: 0 0 14px; position: relative; isolation: isolate;
  font-family: var(--pt-title); font-weight: var(--pt-title-weight); text-transform: var(--pt-title-case); letter-spacing: var(--pt-title-track);
  font-size: 1.28rem; color: var(--text); text-shadow: var(--halo), 0 0 20px var(--pt-glow);
}
.igra-begin-title::before {
  content: ''; position: absolute; inset: -10px -16px; z-index: -1; pointer-events: none;
  background: linear-gradient(90deg, color-mix(in srgb, var(--bg) 80%, transparent), color-mix(in srgb, var(--bg) 80%, transparent) 60%, transparent 96%);
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 25%, #000 75%, transparent); mask-image: linear-gradient(180deg, transparent, #000 25%, #000 75%, transparent);
}
.igra-begin-title::after {
  content: ''; flex: 1; height: 1px; min-width: 24px;
  background: linear-gradient(90deg, var(--gold), transparent); box-shadow: 0 0 8px var(--pt-glow);
}
.igra-begin-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
/* Карточки выбора: стекло поверх картины, свет из верхнего угла (Friends & Fables),
   уголки-орнамент, стрелка «вперёд» выезжает при наведении. */
.igra-begin-card {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px; text-align: left; cursor: pointer; position: relative;
  padding: 18px 18px 20px; border-radius: var(--pt-radius); border: 1px solid var(--pt-frame); color: var(--text); font: inherit; font-family: var(--pt-ui);
  background: var(--pt-corners), radial-gradient(80% 70% at 0% 0%, color-mix(in srgb, var(--gold) 16%, transparent), transparent 70%), var(--pt-sheen), var(--pt-bubble);
  backdrop-filter: blur(14px) saturate(1.1); -webkit-backdrop-filter: blur(14px) saturate(1.1);
  box-shadow: var(--pt-shade), inset 0 1px 0 var(--pt-edge), inset 0 -1px 0 rgba(0,0,0,.22);
  transition: border-color .18s ease, transform .2s cubic-bezier(.2,.8,.2,1), box-shadow .2s ease;
}
.igra-begin-card::after {
  content: '→'; position: absolute; right: 16px; top: 50%; transform: translate(-6px, -50%); opacity: 0;
  font: 700 1.2rem/1 var(--pt-ui); color: var(--gold-t); transition: opacity .2s ease, transform .2s ease;
}
.igra-begin-card:hover, .igra-begin-card:focus-visible {
  border-color: var(--gold); transform: translateY(-3px); outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 16%, transparent), 0 22px 40px -16px var(--pt-glow), var(--pt-shade), inset 0 1px 0 var(--pt-edge);
}
.igra-begin-card:hover::after, .igra-begin-card:focus-visible::after { opacity: 1; transform: translate(0, -50%); }
.igra-begin-card:active { transform: translateY(0) scale(.99); }
.igra-begin-ico {
  width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; color: var(--on-gold, #1a1206); margin-bottom: 6px;
  background: radial-gradient(100% 80% at 50% 0%, rgba(255,255,255,.42), transparent 58%), linear-gradient(145deg, var(--gold-2), var(--gold));
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--gold) 16%, transparent), 0 10px 20px -8px var(--pt-glow), inset 0 -3px 5px rgba(0,0,0,.2);
}
.igra-begin-ico.alt { color: var(--gold-t); background: radial-gradient(100% 80% at 50% 0%, rgba(255,255,255,.12), transparent 60%), color-mix(in srgb, var(--gold) 14%, var(--surface-2)); border: 1px solid color-mix(in srgb, var(--gold) 55%, transparent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--gold) 8%, transparent), inset 0 1px 0 var(--pt-edge); }
/* подпись карточки — столбцом: имя над пояснением (на ПК спаны текли одной строкой) */
.igra-begin-txt { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.igra-begin-name { font-family: var(--pt-title); font-weight: var(--pt-title-weight); font-size: 1.12rem; line-height: 1.25; padding-right: 18px; }
.igra-begin-sub { font-size: .85rem; line-height: 1.45; color: var(--text-2); }
@media (max-width: 600px) {
  .igra-begin-grid { grid-template-columns: 1fr; gap: 10px; }
  .igra-begin-card { flex-direction: row; align-items: center; gap: 14px; padding: 14px 16px; }
  .igra-begin-ico { margin: 0; flex: none; width: 42px; height: 42px; }
  .igra-begin-txt { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
  .igra-begin-card::after { display: none; }
}

/* Навигация игры: бургер + выдвижная панель (истинная боковая — от 1024px) */
.igra-nav-toggle { padding: 8px 10px; }
.igra-nav-backdrop {
  position: fixed; inset: 0; background: rgba(6,5,10,.6); z-index: 55;
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.igra-nav-backdrop.is-open { opacity: 1; pointer-events: auto; }
.igra-nav {
  position: fixed; top: 0; left: 0; height: 100vh; width: 272px; max-width: 84vw;
  /* var(--surface) задумана для панелей поверх фона страницы, а не поверх
     остального содержимого (после 28.09 она уже почти непрозрачная — см.
     js/themes.js, — но выдвижное меню всё равно лежит НАД текстом хода и
     карточками, z-index выше, и должно быть однозначно непрозрачным, а не
     «почти»). Свой непрозрачный градиент, как у бокового меню сайта
     (.drawer в assets/css/style.css), решает то же самое надёжнее. */
  background: linear-gradient(180deg, #14111f, #0e0c18); border-right: 1px solid var(--border-strong);
  z-index: 60; transform: translateX(-100%); transition: transform .2s ease;
  overflow-y: auto; overflow-x: hidden; padding-bottom: 16px; display: flex; flex-direction: column;
}
.igra-nav.is-open { transform: translateX(0); }
/* Сдвиг за край экрана не убирает ссылки из Tab-порядка: на телефоне фокус
   уходил в закрытое меню. visibility скрывает его и от клавиатуры, и от скринридера;
   переход оставляет анимацию закрытия, а постоянное меню на ПК не затрагивается. */
@media (max-width: 1023px) {
  .igra-nav { visibility: hidden; transition: transform .2s ease, visibility .2s; }
  .igra-nav.is-open { visibility: visible; }
}
/* Владелец 24.10 (давняя беда): докрутил меню до конца и продолжаешь — начинала ехать страница под ним. Меню держит прокрутку
   у себя (overscroll-behavior), а страница, пока меню выдвинуто поверх неё, не прокручивается вовсе. От 1024px меню — постоянная
   боковая колонка, страницу там не замораживаем. */
.igra-nav { overscroll-behavior: contain; }
@media (max-width: 1023px) { html.igra-nav-lock, html.igra-nav-lock body { overflow: hidden; overscroll-behavior: none; } }
.igra-nav-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--border); margin-bottom: 8px;
}
.igra-nav-head .brand { font-size: 1.05rem; gap: 8px; }
.igra-nav-close { display: inline-flex; }
/* Пункты бокового меню. Всё на токенах темы (--gold/--gold-2/--text*/--border*/--radius-sm):
   подложка и полоса активного пункта берут акцент темы, форму задают переменные
   --nav-r/--nav-tile-r, которые themes.css переопределяет по темам. position не ставим
   ни на .igra-nav, ни на .igra-topbar (ломало макет, spisok п.25) — полоса делается
   inset-тенью, украшения — псевдоэлементами внутри пункта. */
.igra-nav-group { display: flex; flex-direction: column; gap: 3px; padding: 0 12px; margin-top: 18px; } /* отступы у подписей разделов (находка 052) */
.igra-nav-label {
  display: flex; align-items: center; gap: 8px; margin: 0 4px 9px;
  font-size: .68rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--text-3);
}
.igra-nav-label::after { content: ''; flex: 1; height: 1px; background: var(--border-strong); }
.igra-nav-foot { margin-top: auto; padding-top: 12px; border-top: 1px solid var(--border-strong); }
.igra-nav-item {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 46px;
  text-align: left; padding: 5px 10px 5px 6px; color: var(--text); background: transparent;
  border: 1px solid transparent; border-radius: var(--nav-r, var(--radius-sm));
  font: inherit; font-size: .95rem; font-weight: 500; cursor: pointer; text-decoration: none;
  transition: background .16s ease, color .16s ease, border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.nav-ic {
  flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: var(--nav-tile-r, 10px); color: var(--text-2);
  background: color-mix(in srgb, var(--text) 6%, transparent); border: 1px solid var(--border-strong);
  transition: background .16s ease, color .16s ease, border-color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.igra-nav-item .ic { width: 20px; height: 20px; display: block; }
.nav-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.igra-nav-item:hover {
  background: color-mix(in srgb, var(--gold) 12%, transparent); color: var(--text);
  transform: translateX(2px);
}
.igra-nav-item:hover .nav-ic {
  color: var(--gold-t); border-color: color-mix(in srgb, var(--gold-2) 55%, transparent);
  background: color-mix(in srgb, var(--gold) 16%, transparent);
}
.igra-nav-item:focus-visible, .igra-nav-account:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 1px; }
.igra-nav-item.is-active, .igra-nav-item.is-active:hover {
  color: var(--text); font-weight: 600; transform: none;
  background: linear-gradient(90deg, color-mix(in srgb, var(--gold) 30%, transparent), color-mix(in srgb, var(--gold) 7%, transparent));
  border-color: color-mix(in srgb, var(--gold-2) 50%, transparent);
  box-shadow: inset 3px 0 0 var(--gold-2), 0 0 22px -8px var(--gold-2);
}
.igra-nav-item.is-active .nav-ic {
  color: #fff; border-color: transparent;
  background: linear-gradient(135deg, var(--gold-2), var(--gold));
  box-shadow: 0 0 14px -2px var(--gold-2);
}
.igra-nav-item.is-disabled, .igra-nav-item.is-disabled:hover {
  color: var(--text-3); cursor: default; background: transparent; transform: none; box-shadow: none;
}
.igra-nav-item.is-disabled .nav-ic { color: var(--text-3); background: transparent; border-style: dashed; border-color: var(--border-strong); }
.igra-nav-item .tag {
  flex: none; margin-left: auto; font-size: .6rem; letter-spacing: 0; padding: 1px 7px;
  border: 1px solid var(--border-strong); border-radius: 999px; color: var(--text-3); white-space: nowrap;
}
#navLogout { color: color-mix(in srgb, var(--rose) 30%, var(--text)); }
#navLogout .nav-ic { color: var(--rose); border-color: color-mix(in srgb, var(--rose) 35%, transparent); }
#navLogout:hover { background: color-mix(in srgb, var(--rose) 14%, transparent); }
#navLogout:hover .nav-ic { color: var(--rose); border-color: var(--rose); background: color-mix(in srgb, var(--rose) 16%, transparent); }
@media (prefers-reduced-motion: reduce) { .igra-nav-item, .nav-ic { transition: none; } .igra-nav-item:hover { transform: none; } }

/* Свёртка меню (19.10). Кнопка есть только на ПК; значок-шеврон смотрит влево («свернуть») и поворачивается вправо в узком виде. */
.igra-nav-tab { display: none; }
.igra-nav-tip {
  position: fixed; z-index: 90; transform: translateY(-50%); pointer-events: none; max-width: 260px;
  padding: 6px 11px; border-radius: var(--nav-r, var(--radius-sm)); font-size: .85rem; font-weight: 600; line-height: 1.3; white-space: nowrap;
  color: var(--text); background: color-mix(in srgb, var(--gold) 16%, var(--bg)); border: 1px solid var(--gold-2);
  box-shadow: 0 6px 20px -6px rgba(0,0,0,.6);
}
.igra-nav-tip[hidden] { display: none; }
@media (min-width: 1024px) {
  /* Язычок свёртки (владелец 29.10): скруглённое ушко на правом краю меню, по центру высоты окна. Фон и рамка берутся от меню
     (navcollapse.js копирует фон меню, attachment fixed совмещает градиент с меню), левого ребра нет: язычок продолжает край.
     left едет тем же переходом, что и ширина меню, поэтому язычок не отстаёт при сворачивании. */
  .igra-nav-tab {
    position: fixed; z-index: 61; top: 50%; left: calc(var(--nav-w) - 1px); width: 24px; height: 56px; margin: -28px 0 0; padding: 0 0 0 1px;
    display: grid; place-items: center; cursor: pointer; color: var(--text-2);
    background-color: color-mix(in srgb, var(--bg) 92%, var(--text)); background-attachment: fixed; background-size: 100vw 100vh;
    border: 1px solid var(--border-strong); border-left: 0; border-radius: 0 14px 14px 0;
    box-shadow: 6px 0 14px -8px rgba(0, 0, 0, .55);
    transition: left .22s ease, transform .16s ease, color .16s ease, border-color .16s ease, box-shadow .16s ease;
  }
  .igra-nav[hidden] + .igra-nav-tab { display: none; }
  .igra-nav-tab::before { content: ''; position: absolute; inset: -4px -6px -4px -2px; } /* зона нажатия 46x64 без смены вида */
  .igra-nav-tab .ic { width: 18px; height: 18px; display: block; transform: rotate(180deg); transition: transform .22s ease; }
  body.nav-collapsed .igra-nav-tab .ic { transform: none; }
  .igra-nav-tab:hover, .igra-nav-tab:focus-visible { transform: translateX(3px); color: var(--gold-t, var(--gold)); border-color: var(--gold-2); box-shadow: 8px 0 16px -8px rgba(0, 0, 0, .6), 0 0 14px -6px var(--gold-2); }
  .igra-nav-tab:focus-visible { outline: 2px solid var(--gold-2); outline-offset: 2px; }
  /* Узкий вид: только иконки, аватар кружком, вместо подписей групп - тонкие разделители. */
  body.nav-collapsed .igra-nav-head { justify-content: center; padding: 14px 0; }
  body.nav-collapsed .igra-nav-head .brand { font-size: 0; gap: 0; }
  body.nav-collapsed .igra-nav-group { padding: 0 11px; }
  body.nav-collapsed .igra-nav-label { font-size: 0; letter-spacing: 0; margin: 0 6px 10px; gap: 0; }
  /* 20.10 (проверка 4): тема подставляет свои значки в ::before/::after подписи («//» у crt, «[ ]» у neo_action, «✿», «≈»); в полосе 72 px
     подпись группы не показываем ни в одной теме, остаётся тонкий разделитель. */
  html body.nav-collapsed .igra-nav-label { font-size: 0; letter-spacing: 0; gap: 0; opacity: 1; }
  html body.nav-collapsed .igra-nav-label::before { content: none; display: none; }
  html body.nav-collapsed .igra-nav-label::after { content: ''; display: block; flex: 1; height: 0; width: 100%; background: none; border: 0; border-top: 1px solid var(--border-strong); }
  body.nav-collapsed .igra-nav-item { padding: 5px; gap: 0; justify-content: center; min-height: 48px; }
  body.nav-collapsed .igra-nav-item:hover { transform: none; }
  body.nav-collapsed .igra-nav-item .nav-t, body.nav-collapsed .igra-nav-item .tag { display: none; }
  body.nav-collapsed .igra-nav-item.is-active { box-shadow: inset 3px 0 0 var(--gold-2), 0 0 18px -8px var(--gold-2); }
  body.nav-collapsed .igra-nav-account { margin: 4px 11px 2px; padding: 6px; justify-content: center; gap: 0; }
  body.nav-collapsed .igra-nav-account .nav-who, body.nav-collapsed .igra-nav-account .nav-chev { display: none; }
  body.nav-collapsed .igra-nav-account .avatar-circle { width: 36px; height: 36px; font-size: 16px; }
  body.nav-collapsed .igra-nav-foot { padding-top: 12px; }
  /* Владелец 26.10: свёрнутое меню обрезалось снизу («Выйти» наполовину, «Развернуть» не видно) - пункты по 48 px с отступами групп
     занимали 760+ px у гостя и 900+ у вошедшего. Полосу прокрутки здесь не показываем (19.10, «уродская»), поэтому значки плотнее,
     а если окно всё равно ниже меню - у нижнего края затухание: видно, что ниже есть ещё, и последний пункт не выглядит отрезанным
     (запас снизу больше затухания, так что докрученный до конца пункт стоит целиком). */
  body.nav-collapsed .igra-nav-item { min-height: 40px; padding: 3px; }
  body.nav-collapsed .igra-nav-group { margin-top: 10px; gap: 2px; }
  body.nav-collapsed .igra-nav-label { margin-bottom: 6px; }
  body.nav-collapsed .igra-nav-head { padding: 10px 0; margin-bottom: 4px; }
  body.nav-collapsed .igra-nav-foot { padding-top: 8px; }
  body.nav-collapsed .igra-nav { padding-bottom: 28px; -webkit-mask-image: linear-gradient(#000 calc(100% - 22px), transparent); mask-image: linear-gradient(#000 calc(100% - 22px), transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .igra-nav, #topbar, #topbar ~ .igra-main, .igra-games-panel, .igra-nav-tab, .igra-nav-tab .ic { transition: none !important; }
}

/* Аватарка: картинка на месте, пока не пришла (или у игрока её нет) —
   буква имени в кружке того же размера, тот же вид, что у людей привычен
   по почте/мессенджерам */
.avatar-circle {
  flex: none; border-radius: 50%; overflow: hidden; background: var(--surface-2);
  border: 1px solid var(--border); display: grid; place-items: center;
  color: var(--text-2); font-weight: 700; font-family: var(--font-body, Inter, system-ui, sans-serif);
  line-height: 1; padding: 0; text-indent: 0; text-align: center;
  text-transform: uppercase; user-select: none;
}
.avatar-circle img { width: 100%; height: 100%; object-fit: cover; display: block; }
.igra-topbar-avatar { width: 32px; height: 32px; font-size: 14.4px; cursor: pointer; padding: 0; border: 1px solid var(--border); }
.igra-nav-account {
  display: flex; align-items: center; gap: 12px; align-self: stretch; margin: 4px 12px 2px; padding: 12px;
  border-radius: var(--nav-r, var(--radius-sm)); cursor: pointer; text-align: left; font: inherit; color: var(--text);
  border: 1px solid var(--border-strong);
  background: linear-gradient(135deg, color-mix(in srgb, var(--gold) 22%, transparent), color-mix(in srgb, var(--gold) 4%, transparent));
  transition: border-color .16s ease, box-shadow .16s ease;
}
.igra-nav-account:hover { border-color: var(--gold-2); box-shadow: 0 0 20px -8px var(--gold-2); }
.igra-nav-account:hover .nav-chev { color: var(--gold-t); transform: translateX(2px); }
.igra-nav-account .avatar-circle {
  width: 42px; height: 42px; font-size: 18.9px; border: 2px solid var(--gold-2);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 22%, transparent);
}
.nav-who { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.nav-who small { font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; color: var(--text-3); font-weight: 700; }
.nav-who b { font-size: .9rem; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-chev { flex: none; width: 18px; height: 18px; color: var(--text-3); transition: color .16s ease, transform .16s ease; }
.cabinet-avatar-row { display: flex; align-items: center; gap: 16px; margin-bottom: 14px; }
.cabinet-avatar-row .avatar-circle { width: 72px; height: 72px; font-size: 32.4px; }
.cabinet-avatar-actions { display: flex; flex-direction: column; gap: 8px; flex: 1 1 0; min-width: 0; align-items: flex-start; }
/* 30.09: на 360 в «Экшене» (моноширинный капс) кнопки шире карточки: разрешаем перенос строки и сжатие до колонки */
.cabinet-avatar-actions .btn { max-width: 100%; white-space: normal; text-align: center; overflow-wrap: anywhere; line-height: 1.25; }

@media (min-width: 1024px) {
  /* Ширина бокового меню: 272px развёрнутое, 72px свёрнутое (js/navcollapse.js ставит body.nav-collapsed).
     Всё, что стоит правее меню (шапка, содержимое, колонка партий, сцены вкладок), считает от неё. */
  :root { --nav-w: 272px; }
  body.nav-collapsed { --nav-w: 72px; }
  .igra-nav-toggle, .igra-nav-close, .igra-nav-backdrop { display: none; }
  .igra-nav { transform: none; box-shadow: none; width: var(--nav-w); transition: width .22s ease; }
  #topbar:not([hidden]), #topbar:not([hidden]) ~ .igra-main { transition: margin-left .22s ease, width .22s ease; }
  /* .igra-nav — position:fixed (вне потока), поэтому margin-left сам по себе
     только СДВИГАЕТ topbar/main, а их width:100% по-прежнему считается от
     ширины body — без вычитания ширины бокового меню оба вылезают вправо на
     272px за край экрана (у .igra-shell.wide, 960px, это давало ~112px
     обрезанного правого края — Герои и Миры несли ту же поломку ДО раздела
     Таверна/Магазин, просто на них так широко ничего не смотрели).

     Отступ нужен, только пока меню вообще показано. app.js прячет и топбар,
     и .igra-nav разом атрибутом hidden (setTopbarVisible) — на экране входа
     до setTopbarVisible(true) меню нет вовсе, а этот отступ раньше всё равно
     сдвигал .igra-main, и экран входа оказывался смещён вправо примерно на
     половину отступа (центрирование считало центр от чужой, урезанной
     ширины). Держим #topbar:not([hidden]) как метку «меню сейчас показано»
     — самого топбара это не касается, у него и так display:none, пока он
     hidden. */
  #topbar:not([hidden]) { margin-left: var(--nav-w); width: calc(100% - var(--nav-w)); }
  #topbar:not([hidden]) ~ .igra-main { margin-left: var(--nav-w); width: calc(100% - var(--nav-w)); }
  /* На узком ПК язычок перекрывал карточки: отступ учитывает выступ, сдвиг при наведении и зону нажатия. */
  body:not(.has-games-panel) #topbar:not([hidden]) ~ .igra-main { padding-left: 40px; }
  /* На ПК боковое меню всегда на экране (строка выше) и уже несёт свою
     надпись «Игра» с логотипом (.igra-nav-head .brand) — та же надпись в
     верхней шапке была бы вторая подряд перед глазами. На телефоне меню
     скрыто за бургером, поэтому там марка в шапке остаётся единственной и
     этот блок её не трогает (media начинается с 1024px). */
  .igra-topbar .brand { display: none; }
}

/* Панель партий внутри игры (задание 29.09: «большая пустая область слева»
   на экране хода). Тот же материал и приём, что у .igra-nav (выезжающая
   панель, непрозрачный градиент, задвижка translateX) — но отдельный
   компонент, а не часть .igra-nav: тот общий для всех экранов и уже несёт
   свою мобильную логику (бургер сайта), плести туда ещё и партии значило бы
   путать два независимых выезжающих меню в одном narrow-контейнере. На ПК
   компонент просто встаёт правым соседом .igra-nav (left: var(--nav-w)) — на глаз
   это одна колонка «меню сверху, партии снизу», а по разметке — два места
   с одинаковым покроем. */
/* На телефоне это была ВТОРАЯ кнопка меню рядом с бургером ☰ в шапке
   (владелец 29.09: «два значка списка на одном экране») — обе открывали
   разные списки почти одного и того же (партии). Оставляем один вход:
   бургер шапки → пункт «Партии» (тот же renderChatList, что видит и эта
   панель). На ПК кнопка и так скрыта ниже (панель там — постоянная колонка). */
.igra-games-panel-toggle { display: none; }

.igra-games-panel-backdrop {
  position: fixed; inset: 0; background: rgba(6,5,10,.6); z-index: 55;
  opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
.igra-games-panel-backdrop.is-open { opacity: 1; pointer-events: auto; }

.igra-games-panel {
  position: fixed; top: 0; left: 0; height: 100vh; width: 300px; max-width: 88vw;
  background: linear-gradient(180deg, #14111f, #0e0c18); border-right: 1px solid var(--border-strong);
  z-index: 58; transform: translateX(-100%); transition: transform .2s ease;
  overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 12px;
}
.igra-games-panel.is-open { transform: translateX(0); }
.igra-games-panel-head { display: flex; align-items: center; justify-content: space-between; }
.igra-games-panel-head h2 { margin: 0; }
.igra-games-panel-new { width: 100%; }

.igra-games-panel-list { display: flex; flex-direction: column; gap: 8px; overflow-y: auto; flex: 1; }
.igra-game-item {
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border-radius: 14px;
  border: 1px solid var(--border); cursor: pointer; text-align: left; width: 100%; background: none;
  color: var(--text); font: inherit;
}
.igra-game-item:hover { background: var(--surface-2); border-color: var(--border-strong); }
.igra-game-item.is-current { border-color: var(--gold); background: color-mix(in srgb, var(--gold) 12%, transparent); }
.igra-game-item .txt { flex: 1; min-width: 0; }
.igra-game-item b { display: block; font-size: .95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.igra-game-item span { display: block; font-size: .8rem; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: 2px; }
.igra-game-item time { display: block; font-size: .72rem; color: var(--text-3); margin-top: 4px; }
.igra-game-item .del { flex: none; }

@media (min-width: 1024px) {
  .igra-games-panel-backdrop { display: none; }
  .igra-games-panel-close { display: none; }
  /* body.has-games-panel — выставляет app.js, пока открыт #screen-game.
     Без class-гейта панель сидела бы в разметке (position:fixed, вне потока)
     и была бы видна поверх остальных экранов (Кабинет, Миры…), хотя там ей
     не место — там «партии» уже есть отдельным пунктом меню. */
  body.has-games-panel .igra-games-panel {
    left: var(--nav-w); transform: none; box-shadow: none; transition: left .22s ease;
  }
  body.has-games-panel #topbar:not([hidden]) { margin-left: calc(var(--nav-w) + 300px); width: calc(100% - var(--nav-w) - 300px); }
  body.has-games-panel #topbar:not([hidden]) ~ .igra-main { margin-left: calc(var(--nav-w) + 300px); width: calc(100% - var(--nav-w) - 300px); }
  /* На ПК внутри партии рядом с .igra-nav встаёт вторая колонка — сам список
     партий (см. комментарий у .igra-games-panel выше). Пункт «Партии» в
     .igra-nav ведёт туда же (screen-list, тот же renderChatList) — пока
     колонка на экране, это дубль одного и того же списка (владелец 29.09:
     «Партии» дважды на экране). Вне игры (Герои/Миры/Кабинет) колонки нет,
     и пункт меню остаётся единственным путём к списку партий. */
  body.has-games-panel #navPartii { display: none; }
}

/* Сворачиваемая колонка «Партии» (20.10): 300 px -> полоса 48 px; кнопка и значок только на ПК. */
.igra-games-panel-collapse, .igra-games-panel-head .gp-ico { display: none; }
@media (min-width: 1024px) {
  :root { --gp-w: 300px; }
  body.games-collapsed { --gp-w: 56px; }
  body.has-games-panel .igra-games-panel { left: var(--nav-lane); width: var(--gp-w); transition: width .22s ease-out, left .22s ease-out; }
  /* 20.10 (владелец: «чтобы не было прыжков, всё фиксированно»): в партии лента и поле ввода стоят на одном месте и той же ширины,
     свёрнуты меню и колонка или нет. Дорожка под меню (272) и колонку (300) занята всегда, освободившееся место остаётся пустым. */
  /* верхняя полоса (колокольчик, чернила) во всю ширину справа от бокового меню: уступа над пустым местом нет; ленту это не двигает */
  body.has-games-panel #topbar:not([hidden]) { margin-left: var(--nav-lane); width: calc(100% - var(--nav-lane)); transition: none; }
  body.has-games-panel #topbar:not([hidden]) ~ .igra-main { margin-left: var(--game-lane); width: calc(100% - var(--game-lane)); transition: none; }
  .igra-games-panel-collapse { display: inline-flex; }
  .igra-games-panel-collapse .gp-chev { transition: transform .22s ease; }
  body.games-collapsed .igra-games-panel-collapse .gp-chev { transform: rotate(180deg); }
  body.games-collapsed .igra-games-panel { padding: 12px 0; align-items: center; overflow: hidden; }
  body.games-collapsed .igra-games-panel-head { flex-direction: column; gap: 12px; }
  body.games-collapsed .igra-games-panel-head h2, body.games-collapsed .igra-games-panel-list, body.games-collapsed .gp-new-t { display: none; }
  body.games-collapsed .igra-games-panel-head .gp-ico { display: block; color: var(--text-3); }
  body.games-collapsed .igra-games-panel-new { width: 40px; height: 40px; min-height: 40px; padding: 0; border-radius: 50%; font-size: 1.2rem; }
}

/* Свёрнутая колонка «Партии»: кружки партий по образцу Discord (20.10). Ширина полосы 48 px не меняется, лента на месте. */
.igra-games-rail { display: none; }
@media (min-width: 1024px) {
  body.games-collapsed .igra-games-rail {
    display: flex; flex-direction: column; align-items: center; gap: 8px; flex: 1; min-height: 0; width: 100%;
    overflow-y: auto; overflow-x: hidden; padding: 6px 0 10px; scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent;
  }
  body.games-collapsed .igra-games-rail::-webkit-scrollbar { width: 4px; }
  body.games-collapsed .igra-games-rail::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 4px; }
  .gp-dot {
    position: relative; flex: none; width: 36px; height: 36px; padding: 0; border-radius: 50%; cursor: pointer; overflow: visible;
    display: grid; place-items: center; font: inherit; font-weight: 700; font-size: .95rem; color: var(--text);
    background: color-mix(in srgb, var(--gold) 22%, var(--bg)); border: 1px solid var(--border-strong);
    transition: border-radius .15s ease, box-shadow .15s ease;
  }
  .gp-dot img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
  .gp-dot.has-cover .gp-dot-l { display: none; }
  .gp-dot:hover, .gp-dot:focus-visible { border-radius: 12px; border-color: var(--gold-2, var(--gold)); }
  .gp-dot.is-current { border-color: var(--gold); box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--gold); }
  .gp-dot.is-current::before { content: ''; position: absolute; left: -5px; top: 50%; width: 3px; height: 20px; transform: translateY(-50%); border-radius: 0 3px 3px 0; background: var(--gold); }
  .gp-dot-star {
    position: absolute; right: -3px; bottom: -3px; width: 15px; height: 15px; display: grid; place-items: center; border-radius: 50%;
    font-size: 10px; line-height: 1; color: var(--on-gold, #1a1204); background: var(--gold); box-shadow: 0 0 0 2px var(--bg);
  }
}

/* Рельсы и шторки (20.10). В партии на ПК слева всегда две рельсы: меню 72 px и партии 56 px; лента по центру правее них, сдвиг 0.
   «Развернуть» выдвигает шторку ПОВЕРХ ленты: стекло из токенов темы, тень у края, выезд 220 мс; ленту не двигает. */
.igra-nav-pin, .igra-games-panel-pin { display: none; }
.igra-game-scrim { display: none; }
@media (min-width: 1024px) {
  body { --nav-lane: var(--nav-w); }
  body.has-games-panel { --nav-lane: 72px; --game-lane: 128px; }
  .igra-nav { transition: width .22s ease-out; }
  body.has-games-panel.nav-open .igra-nav-pin, body.has-games-panel:not(.games-collapsed) .igra-games-panel-pin { display: inline-flex; }
  body.has-games-panel.nav-open .igra-nav-head { gap: 8px; justify-content: flex-start; }
  body.has-games-panel.nav-open .igra-nav-head .brand { margin-right: auto; }
  .igra-nav-pin[aria-pressed="true"], .igra-games-panel-pin[aria-pressed="true"] { color: var(--gold); background: color-mix(in srgb, var(--gold) 16%, transparent); }
  .igra-nav-pin[aria-pressed="true"] .gp-pin-ic, .igra-games-panel-pin[aria-pressed="true"] .gp-pin-ic { fill: currentColor; }
  html body.has-games-panel.nav-open .igra-nav,
  html body.has-games-panel:not(.games-collapsed) .igra-games-panel {
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    -webkit-backdrop-filter: blur(18px) saturate(1.15); backdrop-filter: blur(18px) saturate(1.15);
    box-shadow: 16px 0 36px -14px rgba(0, 0, 0, .55); border-right: 1px solid var(--border-strong);
  }
  body.has-games-panel.nav-open .igra-games-panel { left: 272px; } /* рельса партий едет за краем открытой шторки меню, ленты это не касается */
  .igra-game-scrim {
    display: block; position: fixed; inset: 0; z-index: 54; background: rgba(0, 0, 0, .26);
    opacity: 0; pointer-events: none; transition: opacity .22s ease-out;
  }
  .igra-game-scrim.is-on { opacity: 1; pointer-events: auto; }
}

/* Список записей лора (общий список-стиль с «Партиями») */
.igra-lore-item {
  display: flex; align-items: center; gap: 14px; padding: 14px 16px;
  border-radius: 14px; border: 1px solid var(--border);
  cursor: pointer; text-align: left; width: 100%;
}
.igra-lore-item:hover { background: var(--surface-2); border-color: var(--border-strong); }
.igra-lore-item .txt { flex: 1; min-width: 0; }
.igra-lore-item b { display: block; font-size: 1rem; }
.igra-lore-item span { display: block; font-size: .85rem; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.igra-lore-item .del { flex: none; }

/* Карточки-«манагеры» (Герои/Миры) — те же .igra-pick, плюс кнопка удаления сверху */
.igra-manage-card { position: relative; }
.igra-manage-card .del {
  position: absolute; top: 6px; right: 6px; width: 28px; height: 28px; padding: 0;
  display: flex; align-items: center; justify-content: center; border-radius: 8px;
}

@media (max-width: 600px) {
  .igra-main { padding: 16px 16px 32px; }
  .igra-topbar { padding: 10px 12px; flex-wrap: wrap; row-gap: 8px; }
  .igra-topbar .brand span:last-child { display: none; }
  .igra-topbar-actions { gap: 6px; }
  .igra-ink { font-size: .78rem; }
  .igra-topbar-actions .btn-sm { padding: 8px 10px; font-size: .82rem; }
  .igra-title { font-size: 1.5rem; }
  .igra-turn-user { max-width: 90%; }
}

@media (prefers-reduced-motion: reduce) {
  .igra-caret { animation: none; }
  .igra-typing i { animation: none; opacity: .8; }
  .igra-turn-assistant, .igra-turn-user, .igra-turn-pending, .igra-begin, .igra-master-popover { animation: none; }
  .igra-turns > .igra-turn-assistant:last-child::after { animation: none; }
}

/* ── Темы оформления (js/themes.js) ──────────────────────────────────────
   Восемь сюжетных тем кладут растровый рендер (#theme-scene-render,
   <picture> с ПК/мобильным webp) поверх .sky. Раунд 3 (spisok.md п.4,
   находка Егора: «Розовое королевство» — плоский рисунок вместо 3D-замка)
   дал рендеру z-index:1 против z-index:0 у тогдашнего SVG-плейсхолдера —
   починило порядок относительно .sky, но не саму жалобу: SVG (fantasy.svg/
   cyberpunk.svg/pink_kingdom.svg) как был отдельным непрозрачным (opacity
   .5) на весь экран слоем НАД .sky, так и остался — просто теперь НИЖЕ
   рендера, а не выше. На 1280, где рендер уже загружен, его object-fit:cover
   не гарантирует, что каждый пиксель экрана закрашен непрозрачной частью
   картинки (кадр у webp меньше/иначе скадрирован, чем у SVG) — по краям
   сквозь рендер была видна часть SVG-силуэта. На 412 те же два слоя, вместе
   с decoding=async/loading=lazy у рендера, иногда давали окно, где снимок
   стенда успевал случиться ДО onload картинки — виден только SVG, и это и
   есть «плоский замок вместо 3D» из жалобы (a). Раунд 4 убрал SVG совсем
   (см. THEME_SCENES/mountScene в js/themes.js): пока webp не загрузился (js
   добавляет класс .is-loaded только из onload с реальным naturalWidth>0),
   под .theme-scrim/.sky виден сплошной var(--bg) той же темы — ни силуэта,
   ни постороннего рисунка, никогда одновременно с рендером. */
.theme-scene-render {
  position: fixed; inset: 0; width: 100%; height: 100%;
  display: block; pointer-events: none; z-index: 1;
}
.theme-scene-render img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 30%;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) { .theme-scene-render img { transition: opacity .35s ease; } }
.theme-scene-render.is-loaded img { opacity: 1; }
/* Шире 1920 px фон не растягивается сверх 1,5 раза от файла 1280 px (аудит У2, U2-009): картинка стоит по центру шириной 1920,
   края плавно уходят в фон темы. Новых картинок нет: это только CSS. До 1920 включительно всё как было. */
@media (min-width: 1921px) {
  .theme-scene-render img {
    inset: 0 auto 0 50%; width: 1920px; transform: translateX(-50%);
    -webkit-mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
    mask-image: linear-gradient(to right, transparent, #000 10%, #000 90%, transparent);
  }
}
@media (max-width: 600px) {
  .theme-scene-render img { object-position: center 20%; }
}
/* Свой задник Таверны (.taverna-bg) и Кабинета (.kabinet-bg), 13.10. Слой создаёт js/themes.js (setSectionBg)
   только на этих экранах: <picture> с картинками img/<раздел>/<тема>.webp и <тема>_m.webp. Пока файла нет
   или он грузится, слой невидим (opacity 0) и виден обычный задник темы — вёрстка не прыгает, слой fixed.
   Стоит над общим рендером темы (z-index 1, позже в разметке) и под .theme-scrim. У четырёх цветовых тем и
   «Терминала» общей вуали нет — их затемнение даёт ::after слоя. */
.section-bg {
  position: fixed; inset: 0; width: 100%; height: 100%; display: block; pointer-events: none; z-index: 1;
}
.section-bg img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center 30%; opacity: 0;
}
.section-bg.is-loaded img { opacity: 1; }
/* Задник не тянется за адресной строкой (владелец 25.10: «картинка на фоне сжимается/растягивается» при прокрутке).
   Слой был inset: 0 - его высота = видимая область, а она на телефоне меняется, когда браузер прячет и показывает адресную
   строку; object-fit: cover каждый раз перемасштабировал картинку. Высота - большая высота экрана (lvh: как при спрятанной
   строке), она постоянна; при показанной строке низ картинки просто уходит за край. */
.theme-scene-render, .section-bg { bottom: auto; height: 100vh; height: 100lvh; }
.section-bg.is-loaded::after { content: ""; position: absolute; inset: 0; background: var(--bg); opacity: var(--scrim-opacity, .45); }
:root[data-story="1"] .section-bg::after { display: none; }
@media (prefers-reduced-motion: no-preference) { .section-bg img { transition: opacity .35s ease; } }
@media (max-width: 600px) { .section-bg img { object-position: center 20%; } }

/* Затемняющая/высветляющая подложка над задником сюжетной темы, под шапкой
   и содержимым. Красится в var(--bg) самой темы, а не в чёрный, — на тёмных
   темах затемняет, на светлой pink_kingdom (bg почти белый) высветляет, и
   в обоих случаях тянет задник к тому же тону, на который уже рассчитан
   контраст текста и панелей. Без неё сюжетные фоны (особенно webp-рендеры)
   спорили с текстом на экране входа и текстом хода мастера (см. итог
   проверки читаемости, F:\Android\otchet\temy\perenos.md). z-index:2 —
   заведомо выше рендера (см. комментарий выше), а не «следующий элемент в
   разметке». Непрозрачность — var(--scrim-opacity), своя у каждой сюжетной
   темы (js/themes.js): единое число «на глаз» (было .45) держалось на
   тёмных фонах, а на светлом pink_kingdom клало плотную вуаль поверх
   готового рендера — Раунд 4, жалоба владельца на «выцветший» замок. */
.theme-scrim {
  position: fixed; inset: 0; z-index: 2; pointer-events: none;
  background: var(--bg); opacity: var(--scrim-opacity, .45);
}
@media (prefers-reduced-motion: no-preference) { .theme-scrim { transition: background-color .2s ease, opacity .2s ease; } }

/* Источник «наслоения тем», которое поймал владелец на 412px (28.09, вторая
   переделка, и снова Раунд 3, spisok.md п.3): .igra-body .sky — это
   ОБЩЕСАЙТОВЫЙ статичный задник (строка ~11 выше — до Раунда 3 фото
   hero-desktop(.webp), теперь токены темы), вообще не знающий о теме игры.
   У сюжетных тем он не заменялся, а ложился ПОД их SVG/webp-сцену и
   .theme-scrim — сквозь полупрозрачные слои были видны одновременно ДВЕ
   картинки, и это выглядело как «осталась прошлая тема» (или, после Раунда 3
   без фото, — как задник, не закрывающий экран целиком, пока сцена
   догружается). Правка: где у темы есть собственная сцена (`THEME_SCENES` в
   js/themes.js — восемь тем с рендером из тринадцати), `.sky` гасится в
   сплошной var(--bg), дальше решает сама тема; у цветовых тем и у `crt`
   (Терминал — задника нет нарочно, см. THEME_SCENES) `.sky` остаётся
   единственным задником, поведение не меняется. */
[data-theme="fantasy"] .igra-body .sky,
[data-theme="cyberpunk"] .igra-body .sky,
[data-theme="pink_kingdom"] .igra-body .sky,
[data-theme="neo_action"] .igra-body .sky,
[data-theme="wasteland"] .igra-body .sky,
[data-theme="horror"] .igra-body .sky,
[data-theme="noir"] .igra-body .sky,
[data-theme="abyss"] .igra-body .sky {
  /* Не background-image: none — .sky это ОДНО правило `background:` с двумя
     слоями (градиент + фото), image:none снял бы и градиент, обнажив то,
     что за .sky (без объявленного фона). var(--bg) — тот же тон, что кладёт
     .theme-scrim поверх сцены темы, поэтому смена бесшовная. */
  background: var(--bg);
}

/* Текст мастера — самый долгочитаемый экран игры, поэтому у него своя
   непрозрачная подложка (var(--surface), см. js/themes.js — с 28.09 это уже
   ≥92% непрозрачности), а не голый текст поверх задника/подложки: даже с
   .theme-scrim пёстрый webp-рендер даёт локальные яркие/тёмные пятна, на
   которых фиксированный контраст не гарантирован. У пользовательской
   реплики (.igra-turn-user) такая же панель была и раньше. */
.igra-turn-assistant {
  border: 1px solid var(--pt-frame);
  border-radius: var(--pt-radius); padding: 42px 24px 24px; color: var(--text);
}
@media (max-width: 600px) { .igra-turn-assistant { padding: 40px 18px 22px; } }
/* ПК: колонка 720px — строка прозы выходила под 85 знаков; крупнее кегль и шире поля → ~70. */
@media (min-width: 1024px) { .igra-turn-assistant { font-size: calc(var(--pt-prose-size) * 1.07); padding: 44px 34px 28px; } }
[data-theme="pink_kingdom"] .igra-field input, [data-theme="pink_kingdom"] .igra-field textarea,
[data-theme="pink_kingdom"] .igra-field select, [data-theme="pink_kingdom"] .igra-shell input,
[data-theme="pink_kingdom"] .igra-shell textarea, [data-theme="pink_kingdom"] .igra-shell select {
  background: rgba(240,72,154,.06); color: var(--text);
}

/* ── Полный перекрас интерфейса по темам (перенос из F:\rpg_studio_tablet\ui.html) ──
   Раньше тема меняла только фон-задник и палитру CSS-переменных (--bg/--gold/…),
   а карточки мастера, пузыри игрока, кнопка отправки, поле ввода и шапка/меню
   везде рисовались одинаково. Настольная версия красит под тему ещё и форму:
   шрифт заголовков/хода мастера (там --acc/--t0 плюс код на data-theme=X режет
   форму кнопок и рамки — ui.html:785-980), у некоторых тем — обводку карточки
   (fantasy: ::before/::after у #entity-card, ui.html:492-500). Здесь то же самое
   через существующие --font-display/var(--radius) и точечные правила по
   [data-theme] — без WebGL и без переснятых картинок, только CSS. Четыре
   цветовые темы (dark_purple/blue/green/amber) в исходнике тоже без формы —
   только палитра, это не пропуск, а то же самое отличие «сюжетная/цветовая»,
   что в ui.html (родные THEMES там тоже не размечают data-theme для них). */

/* «Летопись» (fantasy) — тёмное дерево, пергамент, золото: сдвоенная рамка
   карточек (ui.html:492-500 рисует ::before/::after у карточки такой же
   парой линий), ход мастера — засечками с воздухом, как разворот книги. */
[data-theme="fantasy"] { --font-display: 'Playfair Display', 'Cormorant Garamond', 'Georgia', serif; }
[data-theme="fantasy"] .igra-card, [data-theme="fantasy"] .igra-start-card {
  border: 2px solid var(--border-strong);
  box-shadow: inset 0 0 0 2px #241a0c, inset 0 0 0 3px rgba(224,173,63,.35), 0 6px 18px rgba(0,0,0,.3);
}
/* пузыри партии этой темы — themes.css, раздел «Экран партии» (30.09) */
[data-theme="fantasy"] .igra-send-btn {
  border-radius: 50%; box-shadow: 0 0 0 3px rgba(201,150,46,.18), 0 8px 22px rgba(0,0,0,.35);
}
/* Шапка/меню — золотая линия-рамка снизу/справа (border-image, перенос
   ui.html:945-948: там та же лента "прозрачный→золото→прозрачный") —
   вместо плоской тёмной плашки, которую легко спутать с нуаром/тишиной. */
[data-theme="fantasy"] .igra-topbar {
  background: linear-gradient(180deg, #221a0e, #1a140c);
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, transparent, #8a621c 20%, #e0ad3f 50%, #8a621c 80%, transparent) 1;
}
[data-theme="fantasy"] .igra-nav, [data-theme="fantasy"] .igra-games-panel { background: linear-gradient(180deg, #191309, #150f08); border-right-color: #4a3c24; }
[data-theme="fantasy"] .igra-nav-item:hover, [data-theme="fantasy"] .igra-game-item:hover { background: #241c10; }

/* «Киберпанк» (cyberpunk) — холодная ночь, циан + всплеск мадженты:
   неоновое свечение на кнопке/рамках (ui.html:851-908 — box-shadow с тем же
   циановым тоном), заголовок/ход мастера — геометрический дисплейный шрифт. */
[data-theme="cyberpunk"] { --font-display: 'Orbitron', 'Inter', sans-serif; }
[data-theme="cyberpunk"] .igra-card, [data-theme="cyberpunk"] .igra-start-card {
  box-shadow: 0 0 0 1px rgba(0,200,240,.22), 0 0 18px rgba(0,200,240,.08);
}
[data-theme="cyberpunk"] .igra-field input, [data-theme="cyberpunk"] .igra-field textarea,
[data-theme="cyberpunk"] .igra-field select, [data-theme="cyberpunk"] .igra-shell input,
[data-theme="cyberpunk"] .igra-shell textarea, [data-theme="cyberpunk"] .igra-shell select,
[data-theme="cyberpunk"] .igra-turn-input {
  background: rgba(0,200,240,.05); border-color: rgba(0,200,240,.35);
}
[data-theme="cyberpunk"] .igra-field input:focus, [data-theme="cyberpunk"] .igra-field textarea:focus,
[data-theme="cyberpunk"] .igra-turn-input:focus {
  border-color: var(--gold); box-shadow: 0 0 0 2px rgba(0,200,240,.25);
}
[data-theme="cyberpunk"] .igra-send-btn { box-shadow: 0 0 18px rgba(0,200,240,.55), inset 0 1px 0 rgba(255,255,255,.35); }
[data-theme="cyberpunk"] .igra-topbar {
  background: rgba(6,10,18,.92);
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, rgba(63,224,255,.7), rgba(63,224,255,.08) 40%, rgba(63,224,255,.08) 60%, rgba(63,224,255,.7)) 1;
}
[data-theme="cyberpunk"] .igra-nav, [data-theme="cyberpunk"] .igra-games-panel { background: #060a12; }
/* Срезанный угол (перенос ui.html:1000+ clip-path у #chat-empty h2) —
   у сюжетной карточки самой, не только у пустого экрана: узнаваемый
   «чип» без круглых углов, которых в теме нет нигде. */
[data-theme="cyberpunk"] .igra-card, [data-theme="cyberpunk"] .igra-start-card {
  clip-path: polygon(14px 0, 100% 0, 100% 100%, 0 100%, 0 14px);
}

/* «Розовое королевство» (pink_kingdom) — светлая, зефирная: мягче скругления
   (уже даёт var(--radius) выше), пастельный градиент карточек, лёгкий
   шрифт-заголовок вместо тяжёлой антиквы (ui.html:796-845 — форма кнопок и
   рамки на розовом фоне мягче обычных, никаких острых углов вовсе). */
[data-theme="pink_kingdom"] { --font-display: 'Quicksand', 'Inter', sans-serif; }
[data-theme="pink_kingdom"] .igra-card, [data-theme="pink_kingdom"] .igra-start-card {
  background: linear-gradient(180deg, #ffffff, #ffeaf3);
}
/* пузыри партии этой темы — themes.css, раздел «Экран партии» (30.09) */
[data-theme="pink_kingdom"] .igra-send-btn { box-shadow: 0 8px 20px rgba(240,72,154,.35), inset 0 1px 0 rgba(255,255,255,.5); }
[data-theme="pink_kingdom"] .igra-topbar { background: rgba(255,245,249,.86); }
[data-theme="pink_kingdom"] .igra-nav, [data-theme="pink_kingdom"] .igra-games-panel { background: linear-gradient(180deg,#fff5f9,#ffeaf3); border-right-color: var(--border); }
[data-theme="pink_kingdom"] .igra-nav-item:hover, [data-theme="pink_kingdom"] .igra-chat-item:hover, [data-theme="pink_kingdom"] .igra-game-item:hover { background: #ffeaf3; }

/* «Экшен» (neo_action) — графит и электрический след: срезанные углы вместо
   скруглений (ui.html держит --r-lg маленьким у этой темы и рубит форму
   кнопок), шрифт заголовков — плотный гротеск в духе консольного HUD. */
[data-theme="neo_action"] { --font-display: 'Oswald', 'Inter', sans-serif; }
[data-theme="neo_action"] .igra-card, [data-theme="neo_action"] .igra-start-card {
  clip-path: polygon(0 0, 100% 0, 100% calc(100% - 10px), calc(100% - 10px) 100%, 0 100%);
}
/* пузыри партии этой темы — themes.css, раздел «Экран партии» (30.09) */
/* Уголки-скобки на кнопке отправки — перенос ui.html:965-984 (::before/
   ::after у #sendbtn, тот же HUD-приём: не рамка целиком, а засечки по
   двум углам, как прицел). */
[data-theme="neo_action"] .igra-send-btn {
  border-radius: 8px; box-shadow: 0 0 14px rgba(0,217,110,.45); position: relative; overflow: visible;
}
[data-theme="neo_action"] .igra-send-btn::before, [data-theme="neo_action"] .igra-send-btn::after {
  content: ''; position: absolute; width: 10px; height: 10px; pointer-events: none;
}
[data-theme="neo_action"] .igra-send-btn::before {
  top: -2px; left: -2px; border-top: 2px solid #3dff9c; border-left: 2px solid #3dff9c;   /* -2, не -4: на телефоне поля капсулы 3 px, засечки при -4 вылезали за её рамку (аудит 29.10, U3-007) */
}
[data-theme="neo_action"] .igra-send-btn::after {
  bottom: -2px; right: -2px; border-bottom: 2px solid #3dff9c; border-right: 2px solid #3dff9c;
}
[data-theme="neo_action"] .igra-topbar {
  background: #080a0c; border-bottom: 1px solid transparent;
  border-image: linear-gradient(90deg, rgba(0,217,110,.7), rgba(0,217,110,.08) 40%, rgba(0,217,110,.08) 60%, rgba(0,217,110,.7)) 1;
}
[data-theme="neo_action"] .igra-nav, [data-theme="neo_action"] .igra-games-panel { background: #070910; border-right-color: rgba(0,217,110,.3); }

/* «Пустошь» (wasteland) — ржавое железо, пыль: рубленые края (radius уже
   мал в палитре), пунктирная «сварная» рамка карточек, машинописный шрифт
   заголовка — как обрывок радиолога, а не книжная антиква. */
[data-theme="wasteland"] { --font-display: 'Special Elite', 'Georgia', serif; }
[data-theme="wasteland"] .igra-card, [data-theme="wasteland"] .igra-start-card {
  border: 2px dashed var(--border-strong);
}
/* пузыри партии этой темы — themes.css, раздел «Экран партии» (30.09) */
[data-theme="wasteland"] .igra-send-btn { border-radius: 4px; box-shadow: 0 0 0 2px rgba(194,112,58,.3); }
/* Ржавые потёки на стыке шапки (перенос ui.html:10541-10567: неровные
   диагональные полосы через repeating-linear-gradient — тема просит
   фактуры, "ровный градиент читался бы просто как цвет", их же слова). */
[data-theme="wasteland"] .igra-topbar {
  background: #1c160c; border-bottom: 3px solid transparent;
}
[data-theme="wasteland"] .igra-topbar::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -3px; height: 3px; pointer-events: none;
  background: rgba(150,72,26,.55);
}
[data-theme="wasteland"] .igra-nav, [data-theme="wasteland"] .igra-games-panel { background: #17130b; border-right-color: #3d3324; }

/* «Тишина» (horror) — холод, обесцвеченность, клинические углы: острые
   прямые края (radius уже 3-4px в палитре), разрядка/капитель у названий —
   клинический протокол, а не тёплая книжная надпись. */
[data-theme="horror"] .igra-title, [data-theme="horror"] .igra-nav-item,
[data-theme="horror"] .igra-topbar .brand span:last-child {
  letter-spacing: .04em;
}
/* Ничего тёплого и ничего скруглённого: ни свечения, ни градиента на
   рамке (в отличие от fantasy/wasteland/abyss) — «клинический протокол»
   держится на голом контрасте, это и есть его отличие от соседей по
   тёмной палитре. filter: grayscale чуть гасит цвет самого текста/рамок,
   не трогая фон/задник — картинка коридора/палаты остаётся цветной. */
[data-theme="horror"] .igra-card, [data-theme="horror"] .igra-start-card {
  border-width: 1px; border-radius: 2px; box-shadow: none; filter: saturate(.7);
}
/* пузыри партии этой темы — themes.css, раздел «Экран партии» (30.09) */
[data-theme="horror"] .igra-send-btn { border-radius: 2px; box-shadow: none; }
[data-theme="horror"] .igra-topbar {
  background: #0c1211; border-bottom: 1px solid var(--border-strong);
}
[data-theme="horror"] .igra-nav, [data-theme="horror"] .igra-games-panel { background: #0a0e0d; border-right: 1px solid var(--border-strong); }
[data-theme="horror"] .igra-nav-item:hover, [data-theme="horror"] .igra-chat-item:hover, [data-theme="horror"] .igra-game-item:hover { background: #10201d; }

/* «Нуар» (noir) — монохром и один тёплый фонарь: узкие жалюзи-полосы в
   подложке шапки/меню (ui.html держит нуар почти без формы — три правила —
   тон и один акцент важнее декора), тёплое свечение только на кнопке
   отправки — «фонарь» в чёрно-белом кадре. */
[data-theme="noir"] .igra-topbar, [data-theme="noir"] .igra-nav, [data-theme="noir"] .igra-games-panel {
  background: #0b0b0c;
}
[data-theme="noir"] .igra-send-btn { box-shadow: 0 0 16px rgba(217,164,65,.5), inset 0 1px 0 rgba(255,255,255,.35); }
/* пузыри партии этой темы — themes.css, раздел «Экран партии» (30.09) */
/* «Один тёплый фонарь»: единственный цветной штрих в монохромной теме —
   тёплая полоска слева на реплике мастера, как край света от лампы под
   абажуром, остальная рамка нейтрально-серая. */
[data-theme="noir"] .igra-card, [data-theme="noir"] .igra-start-card {
  border-width: 1px 1px 1px 3px; border-left-color: var(--gold);
}

/* «Бездна» (abyss) — глубокая вода, свет живых существ: мягкое голубое
   свечение карточек (как биолюминесценция), плавные скругления (radius уже
   выше среднего), спокойная пульсация выключена при prefers-reduced-motion. */
[data-theme="abyss"] .igra-card, [data-theme="abyss"] .igra-start-card {
  border-width: 1px; border-color: rgba(43,179,200,.4);
  box-shadow: 0 0 26px rgba(43,179,200,.22), inset 0 0 0 1px rgba(79,216,232,.18);
  animation: abyss-glow 4.5s ease-in-out infinite;
}
@keyframes abyss-glow {
  0%, 100% { box-shadow: 0 0 26px rgba(43,179,200,.22), inset 0 0 0 1px rgba(79,216,232,.18); }
  50% { box-shadow: 0 0 34px rgba(43,179,200,.36), inset 0 0 0 1px rgba(79,216,232,.3); }
}
@media (prefers-reduced-motion: reduce) {
  [data-theme="abyss"] .igra-card, [data-theme="abyss"] .igra-start-card { animation: none; }
}
[data-theme="abyss"] .igra-send-btn { box-shadow: 0 0 20px rgba(43,179,200,.55); }
[data-theme="abyss"] .igra-topbar { background: rgba(4,8,15,.9); border-bottom-color: rgba(43,179,200,.3); }
[data-theme="abyss"] .igra-nav, [data-theme="abyss"] .igra-games-panel { background: #04080f; border-right-color: rgba(43,179,200,.25); }

/* «Терминал» (crt) — экран ЭЛТ вплотную: единственная тема без задника
   вовсе (js/themes.js THEME_SCENES) — вся тема в фактуре, а не в картинке.
   Развёртка — CSS-повтор поверх .igra-main (не картинка, не WebGL, чистый
   градиент), весь текст на люминофорном моноширинном шрифте, острые края
   (radius уже 2-3px в палитре). Развёртка выключена при
   prefers-reduced-motion — мерцающий узор поверх текста хода мешает читать
   тем, кто просил меньше движения. */
[data-theme="crt"] { --font-display: 'VT323', 'Consolas', monospace; --font-body: 'VT323', 'Consolas', monospace; }
[data-theme="crt"] .igra-nav-item, [data-theme="crt"] .igra-game-item, [data-theme="crt"] button,
[data-theme="crt"] .igra-field input, [data-theme="crt"] .igra-field textarea, [data-theme="crt"] .igra-field select {
  font-family: 'VT323', 'Consolas', monospace; letter-spacing: .02em;
}
[data-theme="crt"] .igra-card, [data-theme="crt"] .igra-start-card {
  border-radius: 2px; box-shadow: inset 0 0 0 1px rgba(34,224,92,.25);
}
[data-theme="crt"] .igra-main {
  position: relative;
}
[data-theme="crt"] .igra-main::before {
  content: ''; position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(0,0,0,0) 0px, rgba(0,0,0,0) 2px, rgba(0,0,0,.12) 3px);
  mix-blend-mode: multiply;
}
@media (prefers-reduced-motion: reduce) {
  [data-theme="crt"] .igra-main::before { display: none; }
}
[data-theme="crt"] .igra-send-btn { border-radius: 2px; box-shadow: 0 0 12px rgba(34,224,92,.6); }
[data-theme="crt"] .igra-topbar, [data-theme="crt"] .igra-nav, [data-theme="crt"] .igra-games-panel { background: #020604; }

/* Переключатель темы (кабинет /igra/): сетка превью-карточек */
.theme-picker { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 10px; }
.theme-swatch {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  padding: 12px; border-radius: 14px; border: 1px solid var(--border);
  background: var(--surface); cursor: pointer; text-align: left; font: inherit; color: var(--text);
}
.theme-swatch:hover { border-color: var(--border-strong); }
.theme-swatch.is-selected { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold); }
.theme-swatch .dot { width: 100%; height: 34px; border-radius: 10px; }
.theme-swatch .name { font-size: .88rem; }
.theme-sound-row { display: flex; align-items: center; gap: 10px; margin-top: 14px; font-size: .9rem; color: var(--text-2); }

@media (prefers-reduced-motion: reduce) {
  .theme-scene-render img { transition: none; }
  .theme-scrim { transition: none; }
}

/* ===================================================================
   ПУСТЫЕ СОСТОЯНИЯ (правки 29.09, пачка 2). Только общие токены темы —
   --bg / --text / --text-2 / --gold / --border-strong. Нет ни одного
   [data-theme=...] правила: цвета сами подстраиваются под все темы.
   Подложка непрозрачная (смесь фона темы и золота), чтобы текст не
   сливался с рисунком экрана (было: розовая тема, замок под текстом).
   =================================================================== */
.igra-empty-card, .igra-shell .tv-notice {
  grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center;
  padding: clamp(28px, 5vw, 48px) 20px; border-radius: var(--radius, 18px);
  border: 2px dashed color-mix(in srgb, var(--gold) 65%, var(--bg));
  background: color-mix(in srgb, var(--bg) 88%, var(--gold) 12%);
  color: var(--text);
}
.igra-empty-ic {
  display: grid; place-items: center; width: 60px; height: 60px; border-radius: 50%;
  color: var(--gold-t); background: color-mix(in srgb, var(--bg) 78%, var(--gold) 22%);
  border: 1px solid color-mix(in srgb, var(--gold) 55%, var(--bg));
}
.igra-empty-title, .igra-shell .tv-notice-title { margin: 0; font-family: var(--font-display); font-size: 1.3rem; font-weight: 700; color: var(--text); }
.igra-empty-text, .igra-shell .tv-notice-text { margin: 0; max-width: 46ch; color: var(--text); font-size: .95rem; line-height: 1.5; }
.igra-empty-card .btn { margin-top: 6px; }
#magazinBalance:empty { display: none; }
/* Вход: «Войти по паролю» — заметная второстепенная кнопка */
.igra-alt-link {
  display: inline-flex; align-items: center; justify-content: center; min-height: 46px; padding: 10px 22px;
  font-size: 1rem; font-weight: 700; color: var(--gold-t); border: 2px solid var(--gold); background: color-mix(in srgb, var(--bg) 92%, var(--gold) 8%);
  border-radius: 12px; text-decoration: none;
}
.igra-linkbtn { appearance: none; background: none; border: 0; padding: 0; font: inherit; color: var(--gold-t); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; text-align: left; }
.igra-alt-link:hover { background: color-mix(in srgb, var(--bg) 82%, var(--gold) 18%); }
/* Вход: «Отправить код ещё раз» с отсчётом (resend.js) */
.igra-resend-note { margin: 0 0 12px; color: var(--text-2); overflow-wrap: anywhere; }
.igra-resend-note b { color: var(--text); font-weight: 700; }
.igra-resend-row { margin: 14px 0 0; }
.igra-resend {
  min-height: 44px; padding: 8px 4px; border: 0; background: transparent; font: inherit; font-size: .95rem; font-weight: 700;
  color: var(--gold-t); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; text-align: left; max-width: 100%;
}
.igra-resend:disabled { color: var(--text-2); text-decoration: none; cursor: default; opacity: 1; }
.igra-resend:not(:disabled):hover { text-decoration-thickness: 2px; }

/* ===================================================================
   ГЕРОИ И NPC (29.09). Экран «Герои» — два параллельных столбца на ПК
   (≥1024), две вкладки на телефоне. Только токены темы, без [data-theme].
   Столбцы делят ширину .igra-shell.wide; справа от неё на ≥1181 лежит
   колонка сцены (padding-right у .igra-main), поэтому сами столбцы
   узкие и карточки в них — по одной в ряд.
   =================================================================== */
.igra-count {
  display: inline-block; min-width: 1.6em; padding: 1px 8px; margin-left: 6px; border-radius: 999px;
  font-size: .78rem; font-weight: 700; line-height: 1.5; text-align: center; vertical-align: middle;
  color: var(--text); background: color-mix(in srgb, var(--bg) 80%, var(--gold) 20%);
  border: 1px solid color-mix(in srgb, var(--gold) 45%, var(--bg));
}
.igra-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px; align-items: start; }
.igra-col { min-width: 0; }
.igra-col-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; min-height: 40px; }
.igra-col-title { margin: 0; font-family: var(--font-display); font-size: 1.2rem; font-weight: 700; color: var(--text); }
.igra-col-cards { grid-template-columns: minmax(0, 1fr); }
.igra-chartabs { display: none; }

.igra-typebadge {
  display: inline-flex; align-items: center; gap: 5px; margin-bottom: 8px; padding: 2px 9px 2px 7px;
  border-radius: 999px; font-style: normal; font-size: .72rem; font-weight: 700; letter-spacing: .3px;
  color: var(--text); border: 1px solid color-mix(in srgb, var(--gold) 50%, var(--bg));
  background: color-mix(in srgb, var(--bg) 82%, var(--gold) 18%);
}
.igra-pick.is-npc .igra-typebadge {
  border-color: color-mix(in srgb, var(--text-2) 55%, var(--bg));
  background: color-mix(in srgb, var(--bg) 84%, var(--text-2) 16%);
}
.igra-pick.is-hero { border-left: 3px solid color-mix(in srgb, var(--gold) 80%, var(--bg)); }
.igra-pick.is-npc { border-left: 3px dashed color-mix(in srgb, var(--text-2) 70%, var(--bg)); }
.igra-manage-card .igra-typebadge { display: inline-flex; }
.igra-pick[aria-pressed="true"]::after { content: "\2713"; float: right; color: var(--gold-t); font-weight: 700; }

@media (max-width: 1023px) {
  .igra-chartabs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 16px; padding: 4px; border-radius: 14px;
    border: 1px solid var(--border-strong); background: color-mix(in srgb, var(--bg) 88%, var(--text) 12%); }
  .igra-chartab { min-height: 44px; padding: 8px 12px; border: 0; border-radius: 10px; cursor: pointer;
    font: inherit; font-weight: 700; color: var(--text-2); background: transparent; }
  .igra-chartab.is-active { color: var(--text); background: color-mix(in srgb, var(--bg) 70%, var(--gold) 30%);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--gold) 60%, var(--bg)); }
  .igra-cols { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .igra-cols[data-active="heroes"] #colNpcs, .igra-cols[data-active="npcs"] #colHeroes { display: none; }
  .igra-col-head { justify-content: flex-end; }
  .igra-col-title { display: none; }
}

/* Форма героя / NPC: обложка-квадрат слева, имя и тип справа (образец — ui.html настольной версии) */
.igra-charform-top { display: flex; gap: 20px; align-items: flex-start; margin-bottom: 4px; }
.igra-charform-main { flex: 1; min-width: 0; }
.igra-charform-cover {
  flex: none; width: 132px; height: 132px; border-radius: 18px; display: grid; place-items: center;
  font-family: var(--font-display); font-size: 3rem; font-weight: 700; line-height: 1; color: var(--gold-t);
  background: color-mix(in srgb, var(--bg) 84%, var(--gold) 16%);
  border: 2px dashed color-mix(in srgb, var(--gold) 55%, var(--bg));
}
.igra-charform-cover[data-type="npcs"] { color: var(--text-2); border-color: color-mix(in srgb, var(--text-2) 55%, var(--bg)); background: color-mix(in srgb, var(--bg) 88%, var(--text-2) 12%); }
.igra-charform-cover[data-type="worlds"] { border-radius: 14px; }
/* Обложка: квадрат стал кнопкой (выбор файла), картинка ложится поверх буквы */
button.igra-charform-cover { position: relative; overflow: hidden; padding: 0; margin: 0; cursor: pointer; appearance: none; -webkit-appearance: none; }
button.igra-charform-cover:hover, button.igra-charform-cover:focus-visible { border-color: var(--gold); }
button.igra-charform-cover:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
button.igra-charform-cover.has-image { border-style: solid; }
.igra-charform-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.igra-charform-cover img[hidden], .igra-charform-cover span[hidden] { display: none; }
.igra-charform-coverbox { flex: none; width: 132px; display: flex; flex-direction: column; gap: 8px; }
.igra-cover-actions { display: flex; flex-direction: column; gap: 6px; }
.igra-cover-actions .btn { width: 100%; justify-content: center; white-space: normal; text-align: center; }
/* ПК (находка 080): обложка и её кнопки стоят рядом, строкой над полями, как на телефоне; раньше две узкие кнопки висели
   под обложкой, а справа от них была пустота */
@media (min-width: 521px) {
  .igra-charform-top { flex-direction: column; align-items: stretch; }
  .igra-charform-main { width: 100%; }
  .igra-charform-coverbox { width: 100%; flex-direction: row; align-items: center; gap: 16px; }
  .igra-cover-actions { flex-direction: row; flex-wrap: wrap; flex: 1; min-width: 0; }
  .igra-cover-actions .btn { width: auto; white-space: nowrap; }
}
}
.igra-backlink { margin: 0 0 12px; }
/* Миниатюра обложки в карточке списка */
.igra-manage-card.has-cover { padding-left: 84px; min-height: 84px; }
.igra-manage-card .igra-cover-thumb {
  position: absolute; left: 14px; top: 14px; width: 56px; height: 56px; border-radius: 12px; object-fit: cover;
  border: 1px solid var(--border-strong);
}
.igra-typeswitch { display: flex; gap: 8px; flex-wrap: wrap; }
.igra-typeopt {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 16px; border-radius: 999px; cursor: pointer;
  font: inherit; font-weight: 600; color: var(--text-2); background: transparent; border: 1px solid var(--border-strong);
}
.igra-typeopt:hover { color: var(--text); border-color: var(--gold); }
.igra-typeopt.is-active { color: var(--text); background: color-mix(in srgb, var(--bg) 70%, var(--gold) 30%); border-color: var(--gold); }
@media (max-width: 520px) {
  .igra-charform-top { flex-direction: column; align-items: stretch; } /* «Имя» не уже остальных полей (находка 024) */
  .igra-charform-main { width: 100%; }
  .igra-charform-cover { width: 96px; height: 96px; font-size: 2.2rem; }
  .igra-charform-coverbox { width: 100%; flex-direction: row; align-items: center; gap: 14px; }
  .igra-cover-actions { flex: 1; min-width: 0; }
}

/* ── Формы: флажки, радиокнопки и тумблеры (29.09) ──────────────────────────
   Общее правило `.igra-shell input` (ширина 100%, поля, фон) годится для текстовых полей и
   ломало флажки: квадратик прижимался влево, подпись съезжала в узкую колонку. */
.igra-shell input[type="checkbox"], .igra-shell input[type="radio"] {
  width: auto; padding: 0; background: transparent; border-radius: 4px; flex: none;
}
.theme-sound-row { display: flex; align-items: center; gap: 4px; margin-top: 16px; }
.igra-switch { display: flex; align-items: center; gap: 12px; cursor: pointer; text-align: left; color: var(--text); font-size: .92rem; line-height: 1.35; }
.igra-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
.igra-switch-track {
  position: relative; flex: none; width: 46px; height: 26px; border-radius: 999px;
  background: color-mix(in srgb, var(--text) 14%, var(--bg)); border: 1px solid var(--border-strong);
  transition: background .16s ease, border-color .16s ease;
}
.igra-switch-track::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%;
  background: var(--text-2); transition: transform .16s ease, background .16s ease;
}
.igra-switch input:checked + .igra-switch-track { background: color-mix(in srgb, var(--gold) 55%, var(--bg)); border-color: var(--gold-2); }
.igra-switch input:checked + .igra-switch-track::after { transform: translateX(20px); background: #fff; }
.igra-switch input:focus-visible + .igra-switch-track { outline: 2px solid var(--gold-2); outline-offset: 2px; }
.igra-switch-text { flex: 1; min-width: 0; }
@media (prefers-reduced-motion: reduce) { .igra-switch-track, .igra-switch-track::after { transition: none; } }

/* Пункты меню «Картинки» (в разработке) и «Выйти» — читаемые, не блёклые */
.igra-nav-item.is-disabled { color: var(--text-2); }
.igra-nav-item.is-disabled .nav-ic { color: var(--text-2); border-color: var(--text-3); }
.igra-nav-item .tag { color: var(--text-2); border-color: var(--text-3); }
#navLogout { color: var(--text); }
#navLogout .nav-ic { color: color-mix(in srgb, var(--rose) 60%, var(--text)); border-color: color-mix(in srgb, var(--rose) 60%, transparent); }
.igra-hint { color: var(--text-2); }

/* 29.09: подсказки в полях — читаемые (браузерный серый давал 3:1 на тёмных подложках) */
.igra-shell input::placeholder, .igra-shell textarea::placeholder { color: var(--text-2); opacity: 1; }
/* Подсказки «Дополнительной настройки» NPC светлее набранного текста, курсивом: не похожи на заполненные поля (находка 026) */
.igra-shell .npcx-input::placeholder { opacity: .62; font-style: italic; }
.igra-shell .tv-subnav { background: color-mix(in srgb, var(--bg) 82%, var(--text) 18%); }
/* 30.09: вкладки Таверны читаются во всех 13 темах (замер по пикселям: было 2,1-4,5, стало не ниже 4,5).
   Подпись — основным цветом темы, активная — не сплошной заливкой (белёсый текст на розовом давал 2,1:1),
   а тонированной таблеткой с рамкой цвета кнопки темы. Только внутри игры: /taverna/ не затронута. */
.igra-shell .tv-subnav a { color: var(--text); font-weight: 600; }
.igra-shell .tv-subnav a.is-active { color: var(--text); font-weight: 700; background: color-mix(in srgb, var(--btn-b, var(--gold)) 24%, var(--bg)); box-shadow: inset 0 0 0 1.5px var(--btn-b, var(--gold)); }

/* ── Список выбора на «Новой партии» (picker.js) ───────────────────────────
   Свёрнутое поле — одна строка высотой с обычный input; открытый список
   лежит в <body> (fixed) и на ≤700px выезжает панелью снизу. */
.igra-pickcard { margin-bottom: 16px; }
.igra-pickcard .igra-pick-h { margin: 0 0 8px; }
.igra-pickcard .igra-pick-h:not(:first-child) { margin-top: 20px; }
.igra-pickcard .igra-pick-hint { margin: 0 0 8px; font-size: .82rem; line-height: 1.4; color: var(--text-2); }
.igra-pick-none { margin: 0 0 8px; color: var(--text-2); }
.igra-pick-none-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.cb { position: relative; }
.cb-field {
  display: flex; align-items: center; gap: 10px; width: 100%; min-height: 48px; text-align: left;
  padding: 8px 12px 8px 14px; border-radius: 12px; cursor: pointer; font: inherit;
  background: color-mix(in srgb, var(--bg) 70%, var(--surface));
  border: 1px solid var(--border-strong); color: var(--text);
}
.cb-field:hover, .cb-field[aria-expanded="true"] { border-color: var(--gold); }
.cb-val { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.cb-val b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-val b.cb-empty { font-weight: 500; color: var(--text-2); }
.cb-val small { font-size: .78rem; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-arrow { flex: none; display: flex; color: var(--text-2); transition: transform .15s; }
.cb-field[aria-expanded="true"] .cb-arrow { transform: rotate(180deg); }
.cb-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.cb-chip {
  display: inline-flex; align-items: center; gap: 2px; max-width: 100%; padding: 2px 2px 2px 10px;
  border-radius: 999px; font-size: .84rem; color: var(--text);
  background: color-mix(in srgb, var(--bg) 70%, var(--surface)); border: 1px solid var(--gold);
}
.cb-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 60vw; }
.cb-chip button {
  flex: none; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: transparent; color: var(--text); font-size: 1.1rem; line-height: 1;
}
.cb-chip button:hover { background: color-mix(in srgb, var(--gold) 30%, transparent); }
.cb-backdrop { position: fixed; inset: 0; z-index: 1190; background: rgba(0,0,0,.5); }
.cb-pop {
  position: fixed; z-index: 1200; display: flex; flex-direction: column; box-sizing: border-box;
  padding: 8px; border-radius: 12px; border: 1px solid var(--border-strong); color: var(--text);
  background-color: var(--bg);
  background-image: linear-gradient(165deg, var(--surface), var(--surface-tint, var(--surface)));
  box-shadow: 0 14px 40px rgba(0,0,0,.45);
}
.cb-grip { display: none; }
.cb-pop .cb-search {
  flex: none; width: 100%; box-sizing: border-box; margin-bottom: 6px; padding: 10px 12px; border-radius: 10px;
  font: inherit; color: var(--text); background: color-mix(in srgb, var(--bg) 70%, var(--surface));
  border: 1px solid var(--border-strong);
}
.cb-pop .cb-search:focus { outline: none; border-color: var(--gold); }
.cb-list { list-style: none; margin: 0; padding: 0; overflow-y: auto; overscroll-behavior: contain; flex: 1; min-height: 0; }
.cb-opt {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 8px; cursor: pointer;
  min-height: 44px; box-sizing: border-box;
}
.cb-opt.is-active { background: color-mix(in srgb, var(--gold) 22%, transparent); }
.cb-opt.is-selected { background: color-mix(in srgb, var(--gold) 14%, transparent); }
.cb-opt.is-selected.is-active { background: color-mix(in srgb, var(--gold) 28%, transparent); }
.cb-mark {
  flex: none; width: 18px; height: 18px; border-radius: 5px; border: 1.5px solid var(--text-2);
  display: flex; align-items: center; justify-content: center; font-size: 13px; font-weight: 700; color: var(--text);
}
.cb-opt.is-selected .cb-mark { border-color: var(--gold); background: color-mix(in srgb, var(--gold) 35%, transparent); }
.cb-opt.is-selected .cb-mark::after { content: ""; width: 5px; height: 9px; border: solid currentColor; border-width: 0 2px 2px 0; transform: rotate(45deg) translate(-1px, -1px); }
/* Потолок выбора (персонажей в партии не больше пяти): строка не гаснет прозрачностью, меняется курсор и рамка отметки */
.cb-opt.is-full { cursor: not-allowed; }
.cb-opt.is-full .cb-mark { border-style: dashed; }
.cb-pop:not(.cb-multi) .cb-mark { border-radius: 50%; }
.cb-txt { min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
.cb-txt b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-txt small { font-size: .78rem; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cb-create .cb-txt b { color: var(--gold-t, var(--text)); }
.cb-none { padding: 10px; font-size: .84rem; color: var(--text-2); }
@media (max-width: 700px) {
  .cb-pop {
    left: 0; right: 0; bottom: 0; top: auto; width: auto; max-height: 72dvh; height: auto;
    border-radius: 16px 16px 0 0; padding: 6px 12px calc(12px + env(safe-area-inset-bottom));
  }
  .cb-grip { display: block; flex: none; width: 40px; height: 4px; margin: 2px auto 10px; border-radius: 2px; background: var(--text-2); opacity: .6; }
}

/* 360–400px: «Модель мастера» и «С чего начнём историю?» дисплейными шрифтами тем
   (капитель Тишины, Pixelify Терминала, Russo One Киберпанка) переносились на две строки. */
@media (max-width: 400px) {
  .igra-sheet-title { font-size: 1.12rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .igra-begin-title { font-size: 1.08rem; }
  html[data-theme="horror"] .igra-sheet-title, html[data-theme="horror"] .igra-begin-title { letter-spacing: .02em; font-size: .98rem; }
}

.igra-resend-turn { display: block; margin: 8px 0 0 auto; }

/* Отказ хода карточкой под репликой игрока (turnfail.js, тестер 02.10): причина и выход из неё. */
.igra-turn-fail {
  margin: 10px 0 0 auto; max-width: 560px; padding: 12px 14px; border-radius: 14px;
  background: linear-gradient(rgba(240,143,176,.1), rgba(240,143,176,.1)), var(--bg); border: 1px solid rgba(240,143,176,.38); color: var(--text);
  font-size: .94rem; line-height: 1.45; animation: pt-rise .3s ease both;
}
.igra-turn-fail-text { margin: 0; }
/* «Ответ остановлен» (U3-001): решение игрока, не сбой - без розовой рамки ошибки */
.igra-turn-fail[data-kind="stopped"] { background: transparent; border: 1px dashed var(--border-strong); color: var(--text-2); font-size: .88rem; }
/* Обрывок ответа мастера (05.10): поток оборвался, повтор кнопкой его заменит. Бледнее и пунктиром, */
/* чтобы не путать с полным ответом */
.igra-turn-partial { opacity: .72; border-style: dashed; }
.igra-turn-fail-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.igra-turn-fail-actions .igra-resend-turn { display: inline-flex; margin: 0; }
@media (max-width: 520px) { .igra-turn-fail-actions .btn { flex: 1 1 auto; } }

/* Кружок «!» и всплывающее пояснение (hint.js) — один компонент на всю игру (владелец 02.10:
   пояснения не лежат абзацами в карточках и шторках, а открываются по кружку). */
.igra-info-btn {
  flex: none; display: inline-grid; place-items: center; width: 26px; height: 26px; margin: -4px 0; padding: 0;
  border: 0; border-radius: 50%; background: transparent; color: var(--text-2); cursor: pointer; vertical-align: middle;
  transition: color .15s ease, background .15s ease;
}
.igra-info-btn:hover, .igra-info-btn[aria-expanded="true"] { color: var(--gold-t, var(--gold)); background: color-mix(in srgb, var(--gold) 14%, transparent); }
.igra-info-btn:focus-visible { outline: 2px solid var(--gold-t, var(--gold)); outline-offset: 1px; }
.igra-info-ico { width: 16px; height: 16px; display: block; }
/* ОДНО правило для кружка «!» (22.10, владелец: на 390 px он стоял то у слова, то у правого края, то на отдельной строке).
   1) Заголовок/подпись: текст течёт как обычно, кружок - сразу после ПОСЛЕДНЕГО слова, по центру его строки, сколько бы строк ни было.
      (Раньше flex: двухстрочный заголовок отправлял кружок на третью строку или к середине блока.)
   2) Строка с переключателем (.theme-sound-row): переключатель с текстом занимает всё свободное место, кружок - в одном столбце у правого края,
      по центру высоты строки при любом числе строк текста; у строки «подпись + список» (голос озвучки) кружок тоже прижат вправо. */
.igra-with-info { display: block; }
.igra-with-info > .igra-info-btn { display: inline-grid; vertical-align: calc(.5em - 9px); margin: -4px 0 -4px 6px; }  /* середина кружка (поле 18px) - на середину строки текста; во flex-заголовках vertical-align не действует, там align-items */
h1.igra-with-info > .igra-info-btn { vertical-align: calc(.36em - 9px); }   /* крупные h1: строка выше, кружок ниже */
.lv-h-title.igra-with-info > .igra-info-btn, .lv-ink.igra-with-info > .igra-info-btn { margin-left: 0; }   /* эти заголовки flex со своим зазором, одна строка */
.igra-with-info > svg { display: inline-block; vertical-align: middle; margin-right: 8px; }
.theme-sound-row > .igra-switch { flex: 1 1 auto; min-width: 0; }
.theme-sound-row > .igra-info-btn { margin-left: auto; }
.igra-pick-opt { font-family: var(--pt-ui); font-size: .74rem; font-weight: 400; color: var(--text-2); letter-spacing: 0; text-transform: none; }
.igra-info-pop {
  position: fixed; z-index: 95; left: 12px; top: 12px; width: max-content; max-width: 340px;
  padding: 10px 12px 12px 14px; border-radius: var(--radius-sm, 12px); color: var(--text);
  border: 1px solid var(--pt-frame, var(--border-strong));
  background-color: var(--bg);
  background-image: var(--pt-sheen), linear-gradient(165deg, var(--surface-2, var(--surface)), var(--surface));
  box-shadow: 0 12px 34px -8px rgba(0,0,0,.7), 0 0 24px -10px var(--pt-glow), inset 0 1px 0 var(--pt-edge);
  font-family: var(--pt-ui); font-size: .86rem; line-height: 1.45; animation: pt-pop .16s cubic-bezier(.2,.8,.2,1) both;
}
.igra-info-pop[hidden] { display: none; }
.igra-info-pop:focus { outline: none; }
.igra-info-pop-head { display: flex; align-items: flex-start; gap: 8px; margin-bottom: 4px; }
.igra-info-pop-title { margin: 3px 0 0; flex: 1; min-width: 0; font-weight: 700; font-size: .88rem; color: var(--text); }
.igra-info-pop-close {
  flex: none; width: 26px; height: 26px; margin: -2px -4px 0 0; display: grid; place-items: center; border: 0; border-radius: 50%;
  background: transparent; color: var(--text-2); cursor: pointer;
}
.igra-info-pop-close:hover, .igra-info-pop-close:focus-visible { color: var(--text); background: color-mix(in srgb, var(--text) 10%, transparent); outline: none; }
.igra-info-pop-body p { margin: 0; color: var(--text-2); }
.igra-info-pop-body p + p { margin-top: 6px; }

/* Карточка мастера после 02.10: бейджи, имя и цена, короткая память; кружок «!» — в углу карточки
   (отдельной кнопкой рядом, не внутри: кнопка в кнопке недопустима). */
.igra-model-li { position: relative; }
.igra-model-li > .igra-info-btn { position: absolute; top: 6px; right: 6px; margin: 0; z-index: 1; }
.igra-model-li .igra-model-item { padding-right: 38px; align-items: stretch; min-height: 76px; }
/* Карточка без плашки низкая: «!» (сверху) и радио (снизу) не должны налезать друг на друга; зазор не меньше 8px */
.igra-model-li .igra-model-tick { position: absolute; right: 10px; bottom: 10px; width: 20px; height: 20px; font-size: .74rem; }
.igra-model-li .igra-model-tags { margin: 0 0 2px; }
.igra-model-note:empty { display: none; }

/* Шторка кольца: название строки с кружком «!», под полосой — короткая приписка (время, срок) */
.igra-ring-row-titlewrap { display: inline-flex; align-items: center; gap: 2px; min-width: 0; }
.igra-ring-row-meta { margin: 6px 0 0; font-size: .8rem; line-height: 1.35; color: var(--text-2); }

/* Шкала сюжета (plot.js): шесть ступеней в ряд, на телефоне переносятся. */
.igra-plot { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 6px; }
.igra-plot-step {
  flex: 1 1 auto; min-width: 72px; padding: 8px 10px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line, rgba(255,255,255,.14)); background: transparent; color: var(--text-2);
  font: inherit; font-size: .88rem; transition: border-color .15s ease, background .15s ease, color .15s ease;
}
.igra-plot-step:hover, .igra-plot-step:focus-visible { border-color: var(--gold); color: var(--text); outline: none; }
.igra-plot-step[aria-checked="true"] { background: linear-gradient(180deg, var(--btn-a, var(--gold)), var(--btn-b, var(--gold))); border-color: var(--gold); color: var(--on-gold, #fff); } /* на ярком золоте («Терминал») белый давал 1,8:1 */
.igra-plot-hint { margin: 0 0 4px; }
/* Подача (podacha.js): две кнопки той же формы, что шкала сюжета, но не во всю ширину экрана ПК. */
.igra-podacha { max-width: 420px; }
/* Шкала сюжета на телефоне (аудит 03.10, P2-4): шесть делений в одну строку вместо двух рядов по три.
   Подписи прячутся, в каждом делении столбики уровня, имя выбранной ступени — в подсказке.
   Подача (две кнопки) остаётся с подписями и встаёт ниже отдельной строкой. */
.igra-plot-bars { display: none; }
.igra-plot-cur { display: none; font-weight: 600; color: var(--text); }
@media (max-width: 520px) {
  .igra-plot:not(.igra-podacha) { flex-wrap: wrap; gap: 6px; } /* 20.10: два ряда по три, подпись 12 px (было один ряд и 9,9 px) */
  /* 08.10 (приёмка): под столбиками — короткая подпись ступени (Выкл … Бурно), чтобы 360 читалось без нажатия */
  .igra-plot:not(.igra-podacha) .igra-plot-step { flex: 1 1 calc(33.333% - 6px); min-width: 0; height: 56px; padding: 4px 1px 3px; display: flex; flex-direction: column-reverse; align-items: center; justify-content: center; gap: 4px; border-radius: 14px; }
  .igra-plot:not(.igra-podacha) .igra-plot-name { font-size: .75rem; line-height: 1; letter-spacing: 0; white-space: nowrap; max-width: 100%; }
  .igra-plot:not(.igra-podacha) .igra-plot-bars { display: inline-flex; align-items: flex-end; gap: 2px; height: 16px; }
  .igra-plot-bars i { display: block; width: 3px; border-radius: 2px; background: currentColor; opacity: .28; }
  .igra-plot-bars i:nth-child(1) { height: 5px; } .igra-plot-bars i:nth-child(2) { height: 8px; } .igra-plot-bars i:nth-child(3) { height: 11px; }
  .igra-plot-bars i:nth-child(4) { height: 14px; } .igra-plot-bars i:nth-child(5) { height: 16px; } .igra-plot-bars i:nth-child(6) { height: 16px; }
  .igra-plot-bars i.on { opacity: 1; }
  .igra-plot-bars:not(:has(i.on)) i { display: none; }
  .igra-plot-step .igra-plot-bars:not(:has(i.on))::before { content: ''; width: 14px; height: 2px; border-radius: 2px; background: currentColor; align-self: center; }
  .igra-plot-step { position: relative; }
  .igra-plot-cur { display: inline; }
}

/* Правка сообщений (app.js MsgEdit): «⋯» в углу реплики, меню и поле правки на месте. */
.igra-msg-more {
  position: absolute; top: -2px; right: -2px; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; /* зона нажатия 44 px, видимый кружок 28 px — ::before */
  display: grid; place-items: center; background: transparent; color: var(--text-3); cursor: pointer;
  opacity: 0; transition: opacity .15s ease, background .15s ease;
}
.igra-turn-user:hover .igra-msg-more, .igra-turn-assistant:hover .igra-msg-more, .igra-msg-more:focus-visible { opacity: 1; }
.igra-msg-more::before { content: ''; position: absolute; inset: 8px; border-radius: 50%; background: transparent; transition: background .15s ease; z-index: -1; }
.igra-msg-more { isolation: isolate; }
.igra-msg-more > * { position: relative; }
.igra-msg-more:hover { color: var(--text); }
.igra-msg-more:hover::before { background: rgba(255,255,255,.08); }
@media (hover: none) { .igra-msg-more { opacity: .55; } }
.igra-msg-menu {
  position: absolute; z-index: 60; min-width: 220px; padding: 6px; border-radius: 12px;
  /* Находка 073: фон был фиксированно тёмным, а текст --text; в светлом «Розовом королевстве» это розовое на чёрном
     (контраст 1,3:1). Фон и рамка теперь от темы: текст и подложка всегда из одной пары. */
  background: var(--bg, #1b1830); border: 1px solid var(--border-strong, rgba(255,255,255,.12)); box-shadow: 0 12px 32px rgba(0,0,0,.35);
}
.igra-msg-menu button {
  display: block; width: 100%; text-align: left; padding: 10px 12px; border: 0; border-radius: 8px;
  background: transparent; color: var(--text); font: inherit; font-size: .95rem; cursor: pointer;
}
.igra-msg-menu button:hover, .igra-msg-menu button:focus-visible { background: color-mix(in srgb, var(--text) 10%, transparent); outline: none; }
.igra-msg-edit { display: flex; flex-direction: column; gap: 8px; animation: none !important; }
.igra-msg-edit-input {
  width: 100%; min-height: 80px; resize: vertical; padding: 10px 12px; border-radius: 10px; box-sizing: border-box;
  border: 1px solid var(--gold); background: rgba(0,0,0,.25); color: var(--text); font: inherit; line-height: 1.5;
}
.igra-msg-edit-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

/* ── Событие недели: карточка сверху «Новой партии» и рамка у участника ─────
   Картинка на всю карточку, текст на тёмной подложке: читается на любой теме. */
.igra-event {
  position: relative; display: flex; align-items: flex-end; min-height: 250px; margin-bottom: 18px;
  border-radius: 14px; overflow: hidden; border: 1px solid var(--gold-2, var(--border)); background: #0b0a12; isolation: isolate;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 14%, transparent);
}
.igra-event[hidden] { display: none; }
.igra-event-art, .igra-event-art img { position: absolute; inset: 0; width: 100%; height: 100%; }
.igra-event-art img { object-fit: cover; filter: brightness(calc(1 / (1 - var(--scrim-opacity, 0)))); }
/* Полоса низкая, а заметна из-за подложки только верхняя её часть: кадр ставим так, чтобы наверху оказались лица и силуэты (картинки 4:3, перерисованы 30.10) */
.igra-event[data-art="card-fantasy"] .igra-event-art img { object-position: 50% 58%; }
.igra-event[data-art="card-blank"] .igra-event-art img { object-position: 50% 38%; }
.igra-event[data-art="card-horror"] .igra-event-art img { object-position: 50% 10%; }
.igra-event-body {
  position: relative; z-index: 1; width: 100%; display: flex; flex-direction: column; align-items: flex-start; box-sizing: border-box;
  padding: 56px 20px 18px; color: #f4efe6;
  background: linear-gradient(180deg, rgba(8,7,14,0) 0, rgba(8,7,14,.88) 52px, rgba(8,7,14,.95) 100%);
}
.igra-event-kicker {
  margin: 0; display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: .74rem; letter-spacing: .08em; text-transform: uppercase;
  font-weight: 700; color: #f2c98a; text-shadow: 0 1px 3px rgba(0,0,0,.9);
}
.igra-event-kicker span + span { color: #e8e0f0; }
.igra-event-name { text-shadow: 0 1px 4px rgba(0,0,0,.9); margin: 4px 0 6px; font-family: var(--font-display); font-size: 1.5rem; line-height: 1.2; font-weight: 700; color: #fff; }
.igra-event-hook { margin: 0 0 14px; max-width: 46em; font-size: .95rem; line-height: 1.45; color: #f1edf6; text-shadow: 0 1px 3px rgba(0,0,0,.9); }
.igra-event .btn-primary { min-width: 150px; }
html[data-theme="crt"] .igra-event .btn-primary { background: linear-gradient(135deg, #4cf27e, #22e05c); }
html[data-theme="pink_kingdom"] .igra-event .btn-primary { background: linear-gradient(180deg, #a3155b, #870f4a); }
html[data-theme="pink_kingdom"] .igra-event .btn-primary::before { opacity: .35; }
html[data-theme="abyss"] .igra-event .btn-primary { background: linear-gradient(135deg, #a8f1f8, #ddd6ff) !important; }
@media (max-width: 720px) {
  .igra-event { min-height: 270px; }
  .igra-event-body { padding: 64px 16px 16px; }
  .igra-event-name { font-size: 1.3rem; }
  .igra-event .btn-primary { width: 100%; }
}
/* «Новая партия»: событие недели стоит под выбором и не главное (кнопка второстепенная), «Начать» на телефоне
   прилипает к низу над нижней панелью — видна без прокрутки (20.10, замечание 2) */
.igra-event .btn-ghost { color: #fff; border-color: rgba(255,255,255,.7); background: rgba(8,7,14,.55); }
.igra-event { margin-top: 18px; margin-bottom: 0; min-height: 180px; }
@media (max-width: 767.98px) {
  /* сама полоса (отступы, подложка) - в partiya.css, одна на все виды партии (чистка 12): здесь осталось только то, что не спорит с ней */
  #screen-new #newStartRow .btn-primary { flex: 1 1 auto; min-height: 48px; }
  .igra-event { min-height: 170px; }
  .igra-event .btn-ghost { width: 100%; }
}
/* Значок участника: двойная золотая рамка у кружка аватара и строка в Кабинете */
.avatar-circle.has-event-frame, .igra-nav-account .avatar-circle.has-event-frame {
  border: 2px solid var(--gold-2, #c9a24a);
  box-shadow: 0 0 0 2px var(--surface, #1a1722), 0 0 0 4px var(--gold-2, #c9a24a);
}
.igra-event-badge {
  display: inline-flex; align-items: center; gap: 8px; margin: 4px 0 12px; padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--gold-2, var(--border)); color: var(--gold-t, var(--text)); font-size: .85rem; font-weight: 600;
  background: color-mix(in srgb, var(--gold) 12%, transparent);
}
.igra-event-badge[hidden] { display: none; }
.igra-event-badge svg { flex: none; }

/* «Расписать за меня» у поля карточки (raspisat.js, 03.10): кнопка с пером под описанием, пояснение за «!» */
.igra-assist-row { display: flex; align-items: center; gap: 6px; margin: -4px 0 14px; flex-wrap: wrap; }
.igra-assist-btn { gap: 8px; }
.igra-assist-btn::before {
  content: ""; width: 16px; height: 16px; flex: none; background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 4C11 4 6 9 5 19'/%3E%3Cpath d='M5 19c3-1 7-3 9-7'/%3E%3Cpath d='M14 12c2 0 4-1 6-8'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 4C11 4 6 9 5 19'/%3E%3Cpath d='M5 19c3-1 7-3 9-7'/%3E%3Cpath d='M14 12c2 0 4-1 6-8'/%3E%3C/svg%3E") center / contain no-repeat;
}
.igra-assist-btn.is-busy { opacity: .75; cursor: progress; }
.igra-assist-btn.is-busy::before { animation: igra-assist-pulse 1s ease-in-out infinite; }
@keyframes igra-assist-pulse { 50% { opacity: .3; } }
.igra-assist-error { margin: -6px 0 14px; }

/* Форма карточки в «Новой партии» (revealForm в app.js, 04.10): при прокрутке к ней начало не прячется под липкой шапкой */
#entityForm { scroll-margin-top: 84px; scroll-margin-bottom: 16px; }

/* Баннер после регистрации: «+20 чернил, это 20 ходов в игре» (welcome.js): по центру, с затемнением */
.igra-welcome {
  position: fixed; inset: 0; z-index: 9000; display: flex; align-items: center; justify-content: center;
  padding: 16px; box-sizing: border-box; background: rgba(8, 7, 16, .72);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  animation: igraWelcomeFade .25s ease-out;
}
.igra-welcome-card {
  width: min(100%, 380px); box-sizing: border-box; padding: 26px 22px 22px; text-align: center;
  border-radius: 20px; color: #f1eefb;
  background: linear-gradient(180deg, #25214a 0%, #17142e 100%);
  border: 1px solid rgba(154, 157, 212, .45);
  box-shadow: 0 20px 60px rgba(0, 0, 0, .55), 0 0 40px rgba(123, 108, 246, .28);
  animation: igraWelcomePop .35s cubic-bezier(.2, .9, .3, 1.15);
}
.igra-welcome-icon {
  display: grid; place-items: center; width: 64px; height: 64px; margin: 0 auto 12px; border-radius: 50%;
  color: #e8b45c; background: rgba(232, 180, 92, .14); border: 1px solid rgba(232, 180, 92, .4);
}
.igra-welcome-head { margin: 0 0 6px; font-size: 2.2rem; font-weight: 800; line-height: 1.1; color: #f4c777; }
.igra-welcome-turns { margin: 0 0 12px; font-size: 1.15rem; font-weight: 600; }
.igra-welcome-note { margin: 0 0 20px; font-size: .95rem; line-height: 1.45; color: #b9b3d6; }
.igra-welcome-close { min-width: 160px; }
@keyframes igraWelcomeFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes igraWelcomePop { from { opacity: 0; transform: translateY(14px) scale(.94); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .igra-welcome, .igra-welcome-card { animation: none; } }

/* Нижние окна на телефоне (sheet.js, 14.10): лента под окном не листается, окно смахивается вниз, затемнение
   не пропускает движение пальца. Замок страницы — только на узком/сенсорном экране: на ПК пропала бы полоса
   прокрутки и страница дёрнулась бы. */
html.igra-sheet-open { overscroll-behavior: none; }
@media (max-width: 700px), (pointer: coarse) {
  html.igra-sheet-open, html.igra-sheet-open body { overflow: hidden; }
}
.igra-master-popover-backdrop, .igra-ring-backdrop, .cb-backdrop, .pt-lb-overlay { touch-action: none; }
.igra-sheet-head, .igra-ring-top, .igra-ring-grip, .igra-sheet-grip, .cb-grip, .pt-lb-head, .pt-lb-grip { touch-action: none; }
.igra-sheet-grip, .pt-lb-grip { display: none; }
.igra-master-popover.is-dragging, .cb-pop.is-dragging, .pt-lb.is-dragging { transition: none; animation: none; }
@media (max-width: 700px) {
  .igra-master-popover, .cb-pop { transition: transform .2s ease; }
  .igra-sheet-grip { display: block; flex: none; width: 40px; height: 4px; border-radius: 999px; margin: 0 auto 8px; background: color-mix(in srgb, var(--text) 35%, transparent); }
}

/* Липкая панель партии (14.10, владелец: «после 150 сообщений кружки, SFW и кольцо памяти не найти»):
   кружки героя/мира/NPC, значок режима и кольцо «Память и расход» остаются под верхней шапкой сайта при
   прокрутке ленты. Высота шапки — переменная --igra-topbar-h (app.js, mountPartyBar). Развёрнутая шапка
   партии большая и текст перекрыла бы — тогда панель обычная (класс is-open), кольцо над ней справа. */
.igra-sticky-sentinel { display: block; height: 0; margin: 0; padding: 0; pointer-events: none; }
.igra-sticky-bar {
  position: sticky; top: var(--igra-topbar-h, 56px); z-index: 30;
  display: flex; align-items: center; gap: 8px; margin: 0 -6px 10px; padding: 4px 6px; border-radius: 16px;
}
.igra-sticky-bar .pt-head { flex: 1 1 auto; min-width: 0; margin: 0 !important; }
.igra-sticky-ring { flex: none; margin-left: auto; display: flex; }
.igra-sticky-bar.is-stuck {
  background: color-mix(in srgb, var(--bg) 95%, transparent); /* 80% просвечивала: строка текста резалась планкой пополам (находка 008) */
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  box-shadow: 0 8px 18px -12px rgba(0, 0, 0, .7);
}
/* 15.10, владелец: «при развёртывании персонажей они улетают на самый верх». Раскрытая шапка была position: static и
   возвращалась на своё место в начале ленты, а страница, прокрученная вниз, оставалась там же: блок оказывался
   тысячей пикселей выше экрана. Теперь она остаётся липкой там, где была нажата, и сама прокручивается, если не
   влезает: страница не двигается, раскрытый блок виден и сворачивается той же стрелкой. */
.igra-sticky-bar.is-open {
  flex-direction: column; align-items: stretch;
  max-height: calc(100vh - var(--igra-topbar-h, 56px) - 24px); max-height: calc(100dvh - var(--igra-topbar-h, 56px) - 24px);
  overflow-y: auto; overscroll-behavior: contain;
}
.igra-sticky-bar.is-open.is-stuck { background: color-mix(in srgb, var(--bg) 94%, transparent); }
.igra-sticky-bar.is-open .igra-sticky-ring { order: -1; align-self: flex-end; margin-bottom: 6px; }
@media (max-width: 700px) { .igra-sticky-bar { margin-left: -4px; margin-right: -4px; padding: 3px 4px; } }

/* «К списку партий» (17.10, владелец): в открытой партии нижнего меню нет, путь к списку был только через бургер.
   Первая кнопка липкой панели; на телефоне — стрелка 44x44, на ПК со словом «Партии». Цвета только из токенов темы. */
.igra-party-back {
  flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  min-width: 44px; height: 44px; padding: 0; border-radius: 14px; cursor: pointer; font: inherit; font-weight: 600;
  color: var(--text); background: color-mix(in srgb, var(--gold) 10%, var(--surface-2)); border: 1px solid color-mix(in srgb, var(--gold) 45%, var(--border-strong));
  box-shadow: inset 0 1px 0 var(--pt-edge, transparent); transition: border-color .15s ease, box-shadow .15s ease;
}
.igra-party-back:hover { border-color: var(--gold); box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 18%, transparent); }
.igra-party-back:focus-visible { outline: 2px solid var(--gold-t, var(--gold)); outline-offset: 2px; }
.igra-party-back-t { display: none; font-size: .9rem; }
@media (min-width: 701px) { .igra-party-back { padding: 0 12px 0 8px; } .igra-party-back-t { display: inline; } }
/* Раскрытая шапка (17.10, владелец прислал снимок): в столбце кнопка «назад» и кольцо вставали каждая на свою строку,
   между ними зияла пустота. Теперь раскрытая панель — строка с переносом: «назад» и кольцо делят первую строку,
   шапка партии ниже на всю ширину. */
.igra-sticky-bar.is-open:has(.igra-party-back) { flex-direction: row; flex-wrap: wrap; align-items: center; align-content: flex-start; }
.igra-sticky-bar.is-open .igra-party-back { order: -2; align-self: center; margin-bottom: 0; }
.igra-sticky-bar.is-open:has(.igra-party-back) .igra-sticky-ring { order: -1; align-self: center; margin: 0 0 0 auto; }
.igra-sticky-bar.is-open:has(.igra-party-back) .pt-head { flex: 1 1 100%; order: 0; }
[data-theme="wasteland"] .igra-party-back { border-radius: 4px; }
[data-theme="horror"] .igra-party-back, [data-theme="crt"] .igra-party-back { border-radius: 2px; }

/* Голосовой ввод хода (14.10, js/golos.js): кружок микрофона слева от «Отправить».
   Цвета только из переменных темы, поэтому одинаково читается во всех 13 темах. */
.igra-mic-btn {
  position: relative; flex: none; margin-left: auto; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  color: var(--gold-t, var(--text)); cursor: pointer;
  background: color-mix(in srgb, var(--gold) 10%, var(--surface-2)); border: 1px solid color-mix(in srgb, var(--gold) 45%, var(--border-strong));
  box-shadow: inset 0 1px 0 var(--pt-edge, transparent);
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease, color .15s ease;
}
.igra-mic-btn + .igra-send-btn { margin-left: 0; }
.igra-mic-btn:hover { transform: translateY(-1px); border-color: var(--gold); box-shadow: 0 0 0 3px color-mix(in srgb, var(--gold) 18%, transparent); }
.igra-mic-btn:focus-visible { outline: 2px solid var(--gold-t, var(--gold)); outline-offset: 3px; }
.igra-mic-btn.is-listening {
  color: #fff; background: #d6334a; border-color: #ff8a98;
  animation: igra-mic-pulse 1.3s ease-out infinite;
}
@keyframes igra-mic-pulse {
  0% { box-shadow: 0 0 0 0 rgba(214,51,74,.6); }
  100% { box-shadow: 0 0 0 14px rgba(214,51,74,0); }
}
@media (prefers-reduced-motion: reduce) {
  .igra-mic-btn.is-listening { animation: none; box-shadow: 0 0 0 4px rgba(214,51,74,.35); }
}
.igra-mic-hint { margin: 0; padding: 6px 4px 2px; font-size: .8rem; line-height: 1.4; color: var(--text-2); }
[data-theme="wasteland"] .igra-mic-btn { border-radius: 4px; }
[data-theme="horror"] .igra-mic-btn, [data-theme="crt"] .igra-mic-btn { border-radius: 2px; }

/* Переключатель «Тратить: лимит подписки / чернила» у премиум-мастера подписчика (15.10, app.js spendToggle) */
.igra-spend { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 4px 4px 0; font-size: .78rem; color: var(--muted, var(--text)); }
.igra-model-li { flex-wrap: wrap; }
.igra-model-li > .igra-model-item { flex: 1 1 100%; }
.igra-spend-btn { min-height: 30px; padding: 0 10px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--text) 25%, transparent); background: transparent; color: var(--text); font: inherit; cursor: pointer; }
.igra-spend-btn.is-on { background: var(--gold-t, var(--gold)); color: var(--on-gold, #1b1830); border-color: transparent; font-weight: 600; }
.igra-spend-btn:focus-visible { outline: 2px solid var(--gold-t, var(--gold)); outline-offset: 2px; }

/* Телефон лёжа (находка 047): липкая шапка сайта и панель партии сверху плюс поле хода снизу съедали больше половины
   высоты, на текст оставалась полоса в 120 px. В низком альбомном экране шапка и панель идут с лентой, липким
   остаётся только поле хода. */
@media (orientation: landscape) and (max-height: 520px) {
  .igra-topbar { position: static; }
  .igra-sticky-bar:not(.is-open) { position: static; } /* раскрытая шапка остаётся липкой (15.10) */
  .igra-sticky-bar:not(.is-open).is-stuck { background: none; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* Строка «Что делаешь?» с крошечным выключателем (19.10, askline.js): вопрос в конце ответа можно отключить */
.igra-ask-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.igra-ask-off {
  flex: none; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0;
  border: 1px solid color-mix(in srgb, currentColor 35%, transparent); border-radius: 50%;
  background: transparent; color: inherit; cursor: pointer; opacity: .6;
}
.igra-ask-off:hover, .igra-ask-off:focus-visible { opacity: 1; background: color-mix(in srgb, currentColor 14%, transparent); }
@media (pointer: coarse) { .igra-ask-off { width: 32px; height: 32px; } }

/* Ряд вкладок, который не помещается: гаснет край, куда можно листать (scrollfade.js, 20.10) */
.sf-r:not(.sf-l) { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 34px), transparent); }
.sf-l:not(.sf-r) { -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 34px), transparent); mask-image: linear-gradient(to left, #000 calc(100% - 34px), transparent); }
.sf-l.sf-r { -webkit-mask-image: linear-gradient(to right, transparent, #000 34px, #000 calc(100% - 34px), transparent); mask-image: linear-gradient(to right, transparent, #000 34px, #000 calc(100% - 34px), transparent); }

/* Зоны нажатия 44x44 (20.10, замечание 5): сам значок не растёт, невидимая область вокруг него шире */
.igra-info-btn { position: relative; }
.igra-info-btn::after { content: ''; position: absolute; inset: -10px; }   /* 26 + 20 = 46: запас на округление, зона не меньше 44 (U2-006) */
.igra-topbar-avatar { position: relative; }
.igra-topbar-avatar::after { content: ""; position: absolute; inset: -7px; border-radius: 50%; }
.igra-topbar .brand { position: relative; }
.igra-topbar .brand::after { content: ''; position: absolute; inset: -8px -14px -8px 0; }   /* слева не заходим на кнопку меню: у неё своя зона 44 px */
.igra-chat-item.igra-pcard .del::after, .igra-manage-card .del::after, .igra-pick.igra-ecard .del::after { content: ""; position: absolute; inset: -9px; }
@media (pointer: coarse), (max-width: 767.98px) {
  html body .lp-tab, html body .igra-chars .igra-chartab, html body .kb-btn, html body .kb .kb-ink-go, html body .lv-buy { min-height: 44px; }
  .igra-topbar-avatar { overflow: visible; }
  .igra-topbar-avatar img { border-radius: 50%; }
  .pc-cover .lp-star::after, .ec-cover .lp-star::after { content: ''; position: absolute; inset: -5px; }
  #navToggle { position: relative; }
  #navToggle::after { content: ''; position: absolute; inset: -5px -3px; }
  .igra-topbar .nav-bell-btn::after { content: ''; position: absolute; inset: -4px -3px; }
  a.igra-hint { min-height: 44px; display: inline-flex; align-items: center; }
}

/* Кольцо «Память и расход»: с подписью-процентом, до первого хода скрыто (20.10, замечание 15) */
.icon-btn-sm.igra-ring-btn { width: auto; min-width: 34px; padding: 0 8px; gap: 5px; display: inline-flex; align-items: center; justify-content: center; }
.igra-ring-btn[hidden] { display: none; }
.igra-ring-pct { font-size: .72rem; font-weight: 700; line-height: 1; color: var(--text); padding: 3px 6px; border-radius: 999px; background: color-mix(in srgb, var(--bg) 94%, var(--text) 6%); }

/* Счётчик длины описания и кнопка «Сократить до лимита» (22.10, sokrat.js). Превышение - сплошная тёмно-красная плашка, как у
   ошибок: читается на любом заднике темы. */
.igra-sokrat { display: flex; flex-direction: column; gap: 8px; margin-top: 6px; }
.igra-sokrat-row { display: flex; align-items: center; gap: 6px; min-height: 36px; }
/* Плашка счётчика одного размера в обоих состояниях (граница и отступы есть всегда, меняется только цвет): ничего не прыгает */
.igra-sokrat-count { box-sizing: border-box; min-width: 9.5em; text-align: center; font-size: .82rem; line-height: 1.3; color: var(--text-2); font-variant-numeric: tabular-nums; background: transparent; border: 1px solid transparent; border-radius: 999px; padding: 1px 10px; font-weight: 600; }
.igra-sokrat.is-over .igra-sokrat-count { background: #2a1219; color: #ffd9de; border-color: rgba(240,143,176,.7); }
/* Подсказка и кнопка стоят в той же строке справа от счётчика; когда лимит не превышен они скрыты (visibility), но место держат:
   высота строки одна и та же, ничего не прыгает и пустоты под полем нет */
.igra-sokrat-over { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex: 1 1 auto; min-width: 0; }
.igra-sokrat-over.is-idle { visibility: hidden; }
.igra-sokrat-over[hidden], .igra-sokrat-prev[hidden] { display: none; }
.igra-sokrat-btn { white-space: nowrap; text-align: center; min-height: 36px; padding-block: 4px; }
@media (min-width: 701px) { .igra-sokrat-btn { min-width: 11.5em; } }
@media (max-width: 700px) { .igra-sokrat-overtext, .igra-sokrat-btn-long { display: none; } }
/* «Терминал»: узкий пиксельный шрифт и строки развёртки размывали мелкие цифры на красной плашке; крупнее, без свечения, светлее */
[data-theme="crt"] .igra-sokrat-count { font-size: 1.12rem; letter-spacing: .06em; text-shadow: none; }
[data-theme="crt"] .igra-sokrat.is-over .igra-sokrat-count { background: #4a0f1b; color: #fff; border-color: #ff7b93; }
.igra-sokrat-overtext { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: .88rem; color: var(--text); }
.igra-sokrat-error { margin: 0; }
.igra-sokrat-prev { display: flex; flex-direction: column; gap: 8px; padding: 12px; border-radius: 12px; border: 1px solid var(--border-strong, var(--border)); background: var(--surface); }
.igra-sokrat-prevhead { margin: 0; font-size: .88rem; color: var(--text); }
.igra-sokrat-prevtext { width: 100%; min-height: 120px; resize: vertical; box-sizing: border-box; padding: 10px 12px; border-radius: 10px; border: 1px solid var(--border-strong, var(--border)); background: var(--bg); color: var(--text); font: inherit; }

/* Зоны нажатия в шапке на телефоне (аудит 29.10, U3-003): кнопки и плашки не меньше 44x44, вид прежний - зона растёт невидимым
   слоем (псевдоэлемент принадлежит своему элементу, нажатие по нему считается нажатием на него). Плашке клякс не хватало ширины - 44 по ширине настоящие. */
@media (max-width: 767.98px) {
  html body #navToggle { min-width: 44px; min-height: 44px; }
  html body .igra-topbar-actions .igra-ink, html body .igra-topbar-actions .igra-kly { position: relative; }
  html body .igra-topbar-actions .igra-ink::after, html body .igra-topbar-actions .igra-kly::after { content: ''; position: absolute; inset: -9px 0; }
  html body .igra-topbar-actions .igra-kly { min-width: 44px; justify-content: center; }
}

/* Сервер недоступен при входе (U2-010): сообщение поверх страницы, сессия цела */
.igra-offline { position: fixed; inset: 0; z-index: 400; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 24px; text-align: center; background: var(--bg); color: var(--text); }
.igra-offline h2 { margin: 0; font-size: 1.4rem; }
.igra-offline p { margin: 0; max-width: 32ch; color: var(--text-2); }

/* Зоны нажатия 44 px невидимым слоем, вид не меняется (аудит У2, U2-006): «⋯» у карточек (их зона 48 px уже есть выше), переключатель «Персонажи/Миры»,
   «Позвать друга», почта в реквизитах */
.kt-kind-btn { position: relative; }
.kt-kind-btn::after { content: ''; position: absolute; inset: -6px 0; }
.kb .kb-invite { min-height: 44px; }
.igra-hint a[href^="mailto:"], .lv-legal a[href^="mailto:"] { position: relative; }
.igra-hint a[href^="mailto:"]::after, .lv-legal a[href^="mailto:"]::after { content: ''; position: absolute; inset: -15px 0; }
/* Создание: поля остаются в документе, поэтому переходы не сбрасывают ввод. */
.cw-progress { color: var(--gold-2); font-weight: 700; font-size: .85rem; letter-spacing: .04em; margin: 8px 0 16px; }
.cw-summary, .cw-theme { margin: 14px 0; padding: 16px; }
.cw-theme { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; background: var(--surface); border: 1px solid var(--border-strong); border-radius: 12px; }
.cw-theme span { font-weight: 700; }
.cw-theme select { max-width: 100%; color: var(--text); background: var(--bg); border: 1px solid var(--border-strong); border-radius: 8px; padding: 8px; }
.cw-entity-controls { display: contents; }
.cw-creating[data-creation-step="0"] [data-creation-part="1"], .cw-creating[data-creation-step="0"] [data-creation-part="2"],
.cw-creating[data-creation-step="1"] [data-creation-part="0"], .cw-creating[data-creation-step="1"] [data-creation-part="2"],
.cw-creating[data-creation-step="2"] [data-creation-part="0"], .cw-creating[data-creation-step="2"] [data-creation-part="1"] { display: none !important; }
#screen-new[data-creation-step]:not(.cw-inline-open) #newTabs { display: none !important; }
#screen-new[data-creation-step="0"] :is(#newContentWrap,#newCharPanel,#newPickCard,#eventCard,#cwPartyTheme,#cwPartySummary),
#screen-new[data-creation-step="1"] :is(#newModes,#newModeDesc,#newContentWrap,#eventCard,#cwPartyTheme,#cwPartySummary,#newPlotWrap,#newPodachaWrap,#newAdv),
#screen-new[data-creation-step="2"] :is(#newModes,#newModeDesc,#cwPartySummary,[data-ntab="people"]),
#screen-new[data-creation-step="3"] :is(#newModes,#newModeDesc,#newContentWrap,#newCharPanel,#newPickCard,#eventCard,#cwPartyTheme) { display:none !important; }
#screen-new[data-creation-step="2"] #newCharPanel .pt-char-who,
#screen-new[data-creation-step="2"] #newCharPanel #charNpcHead,
#screen-new[data-creation-step="2"] #newCharPanel #charNpcCards,
#screen-new[data-creation-step="2"] #newCharPanel .pt-char-links,
#screen-new[data-creation-step="2"] #newCharPanel #charHeroCards,
#screen-new[data-creation-step="1"] #newCharPanel .pt-char-masters { display:none !important; }
#screen-new.cw-inline-open > :not(#entityForm) { display: none !important; }
#screen-entity-form.cw-creating .igra-charform-top { display: block; }
#screen-entity-form.cw-creating .igra-charform-coverbox { max-width: 190px; }
#screen-entity-form.cw-creating .igra-charform-top:has([data-creation-part="0"]) { margin-bottom: 0; }
#screen-entity-form h1, #screen-new h1 { font-size: clamp(1.5rem, 3vw, 2.15rem); }
#cwCurrentTheme { margin: 4px 0; }
#cwCurrentTheme .cw-theme { padding: 6px 10px; margin: 0; font-size: .8rem; }
.cw-theme-preview { display: block; width: 42px; height: 32px; border-radius: 7px; border: 1px solid var(--border-strong); flex: none; }
.cw-story-details, .cw-tags { margin: 14px 0; border: 1px solid var(--border-strong); border-radius: 10px; padding: 12px; }
.cw-story-details summary, .cw-tags summary { cursor: pointer; font-weight: 700; color: var(--text); }
#screen-new[data-creation-step="1"] .cw-story-details { display: none; }
#screen-new[data-creation-step="1"] #newCharPanel h2:nth-of-type(3),
#screen-new[data-creation-step="2"] #newCharPanel h2:nth-of-type(2) { display:none !important; }
/* В выборе мастера лицо помогает узнать вариант, но имя и цена важнее размера портрета. */
#screen-new #newAdv .adv-new-opts { display: flex; flex-direction: column; }
#screen-new #newAdv .adv-new-opts > [data-ntab="master"] { order: -1; }
#screen-new #newAdv .adv-mcards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
#screen-new #newAdv .adv-mcard { flex-direction: row; }
#screen-new #newAdv .adv-mcard-art { width: 56px; min-height: 68px; aspect-ratio: auto; align-self: stretch; }
#screen-new #newAdv .adv-mcard-body { padding: 7px; justify-content: center; }
#screen-new #newAdv .adv-mcard-name, #screen-new #newAdv .adv-mcard-price { font-size: .88rem; }
#screen-new #newAdv .adv-mcard-note { font-size: .72rem; }
@media (max-width: 650px) { #screen-new #newAdv .adv-mcards { grid-template-columns: repeat(2, minmax(0,1fr)); } #screen-new #newAdv .adv-mcard-art { width: 40px; } #screen-new #newAdv .adv-mcard-head { flex-wrap: wrap; gap: 2px 5px; } }
/* Светлая палитра должна освещать и навигацию, иначе её тёмный текст пропадает на старом тёмном фоне. */
html[data-theme="white"] .igra-nav, html[data-theme="white"] .igra-games-panel, html[data-theme="white"] .igra-topbar, html[data-theme="white"] .igra-bottom-nav { background: #f6f5fa; color: #22222d; }
html[data-theme="white"] .igra-nav-item, html[data-theme="white"] .igra-nav-label, html[data-theme="white"] .igra-nav-account, html[data-theme="white"] .igra-nav-head .brand { color: #292735; }
html[data-theme="white"] .igra-nav-item.is-active { color: #34237c; }
.cw-entity-controls[hidden], .cw-progress[hidden] { display: none !important; }
.cw-step-caption { display: block; margin-bottom: 8px; font-size: .76rem; color: var(--text-2); }
.cw-steps { display: flex; gap: 8px; padding: 0; margin: 0; list-style: none; }
.cw-steps li { min-width: 0; flex: 1; display: flex; align-items: center; gap: 7px; color: var(--text-2); font-size: .76rem; line-height: 1.2; }
.cw-step-num { flex: none; display: grid; place-items: center; width: 25px; height: 25px; border: 1px solid var(--border-strong); border-radius: 50%; color: var(--text-2); }
.cw-steps .is-current { color: var(--text); font-weight: 700; }
.cw-steps .is-current .cw-step-num { background: var(--gold); color: white; border-color: var(--gold); }
.cw-steps .is-done .cw-step-num { color: var(--gold-2); border-color: var(--gold-2); }
.cw-theme { display: grid; grid-template-columns: minmax(0, 1fr) minmax(160px, 220px); gap: 10px 18px; }
.cw-theme-label { display: grid; gap: 8px; font-weight: 700; align-content: start; }
.cw-theme-hint { grid-column: 1 / -1; margin: 0; }
.cw-inventory-panel { box-sizing: border-box; border: 12px solid transparent; border-image-repeat: stretch; min-height: 100px; padding: 5px 12px; font-size: .8rem; }
.cw-inventory-cells { display: flex; gap: 5px; margin: 7px 0; }
.cw-inventory-cells i { width: 22px; height: 22px; border: 1px solid currentColor; border-radius: 3px; opacity: .8; }
.cw-inventory-money { display: flex; gap: 6px; align-items: center; }
.cw-inventory-money img { width: 21px; height: 21px; object-fit: contain; }
.cw-current-theme { margin: 5px 0; }
.cw-current-theme > summary { width: fit-content; cursor: pointer; color: var(--text-2); font-size: .85rem; }
#cwCurrentTheme .cw-theme { max-width: 520px; padding: 12px; }
.cw-summary h2 { margin: 0 0 10px; }
.cw-review-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; border-top: 1px solid var(--border); padding: 8px 0; }
.cw-review-row > div { display: grid; gap: 2px; min-width: 0; }
.cw-review-row span { color: var(--text-2); font-size: .78rem; }
.cw-review-row strong { overflow-wrap: anywhere; font-size: .94rem; }
@media (max-width: 650px) {
  .cw-steps { gap: 4px; }
  .cw-steps li { flex-direction: column; align-items: flex-start; gap: 4px; font-size: .66rem; }
  .cw-step-num { width: 22px; height: 22px; }
  .cw-theme { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 650px) {
  #screen-entity-form.cw-creating .igra-charform-coverbox { max-width: none; }
  #screen-entity-form.cw-creating .igra-cover-actions { flex-direction: column; align-items: stretch; }
  #screen-entity-form.cw-creating .igra-cover-actions .btn { width: 100%; white-space: normal; }
}
.cw-normal-master { display: grid; gap: 8px; margin: 14px 0; padding: 16px; background: var(--surface); border: 1px solid var(--border-strong); border-radius: 12px; font-weight: 700; }
.cw-normal-master select { width: 100%; padding: 9px; background: var(--bg); color: var(--text); border: 1px solid var(--border-strong); border-radius: 8px; }
#screen-new[data-creation-step="0"] #cwNormalMaster, #screen-new[data-creation-step="1"] #cwNormalMaster, #screen-new[data-creation-step="3"] #cwNormalMaster { display:none !important; }
.cw-guest-master { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; margin: 14px 0; padding: 16px; background: var(--surface); border: 1px solid var(--border-strong); border-radius: 12px; }
.cw-guest-master p { flex: 1 1 240px; margin: 0; color: var(--text); }
.cb-has-cards { display: grid; gap: 10px; }
.cb-has-cards .cb-field { width: fit-content; min-width: 135px; min-height: 42px; padding: 9px 16px; border-radius: 10px; color: var(--text); background: var(--surface-2); }
.cb-has-cards .cb-arrow { display: none; }
.cb-selected-view.is-people { display: flex; gap: 10px; flex-wrap: wrap; }
.cw-pick-card { position: relative; display: flex; overflow: hidden; border: 1px solid var(--border-strong); border-radius: 14px; background: var(--surface-2); min-width: 0; }
.cw-pick-card.is-world { width: 100%; min-height: 132px; }
.cw-pick-card.is-person { width: min(100%, 300px); min-height: 132px; }
.cw-pick-cover { flex: none; width: 150px; min-height: 132px; background: var(--bg); }
.cw-pick-card.is-person .cw-pick-cover { width: 100px; }
.cw-pick-cover img { display: block; width: 100%; height: 100%; min-height: 132px; object-fit: cover; }
.cw-pick-body { display: flex; flex-direction: column; justify-content: center; gap: 6px; min-width: 0; padding: 15px; }
.cw-pick-body strong { color: var(--text); font-family: var(--font-display, inherit); font-size: 1.05rem; }
.cw-pick-body span { color: var(--text-2); font-size: .83rem; line-height: 1.35; overflow-wrap: anywhere; }
.cb-has-cards .cw-pick-body .cb-field { min-height: 44px; margin-top: 4px; padding: 9px 14px; color: var(--text); background: var(--surface); border: 1px solid var(--gold-2); font-weight: 700; }
.cw-pick-remove { position: absolute; right: 6px; top: 6px; width: 32px; height: 32px; border: 1px solid var(--border-strong); border-radius: 50%; background: var(--surface); color: var(--text); cursor: pointer; }
@media (max-width: 600px) { .cw-pick-card.is-world .cw-pick-cover { width: 105px; } .cw-pick-card.is-person { width: 100%; } .cw-pick-body { padding: 12px; } }
.cw-guest-master { display: block; }
.cw-guest-master h2 { margin: 0 0 6px; }
.cw-guest-master > p { margin: 0 0 14px; color: var(--text-2); }
.cw-guest-masters { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 9px; }
.cw-guest-master-card { display: grid; grid-template-columns: 1fr auto; text-align: left; gap: 5px 10px; padding: 13px; border: 1px solid var(--border-strong); border-radius: 10px; background: var(--surface-2); color: var(--text); }
button.cw-guest-master-card { cursor: pointer; font: inherit; }
.cw-guest-master-card.is-current { border-color: var(--gold); }
.cw-guest-master-card small { grid-column: 1 / -1; color: var(--text-2); line-height: 1.35; }
.cw-guest-master-card > span { font-size: .8rem; }
.cw-guest-master-card .cw-master-status { grid-column: 1 / -1; color: var(--text-2); font-weight: 700; }
.cw-guest-master-card.is-current .cw-master-status { color: var(--text); }
.cw-theme { grid-template-columns: minmax(0,1fr) minmax(200px,240px); }
.cw-inventory-panel { border-width: 18px; min-height: 140px; padding: 8px 12px; }
.cw-inventory-money { flex-wrap: wrap; overflow-wrap: anywhere; }
@media (max-width: 650px) { .cw-guest-masters { grid-template-columns: 1fr; } .cw-theme { grid-template-columns: 1fr; } .cw-inventory-preview { width: 100%; max-width: 260px; } }
@media (max-width: 360px) {
  .cw-pick-card.is-world { flex-direction: column; }
  .cw-pick-card.is-world .cw-pick-cover { width: 100%; height: 120px; min-height: 120px; }
  .cw-pick-card.is-world .cw-pick-cover img { height: 120px; min-height: 0; }
  #screen-new #newStartRow { flex-wrap: nowrap; gap: 6px; }
  #screen-new #newStartRow .btn { min-width: 0; min-height: 44px; padding-left: 10px; padding-right: 10px; }
  #screen-new #newStartRow #cancelNewBtn { background: transparent; border-color: transparent; }
}
