/* ============================================================
   Оформление игры «Сопоставь человека и факт» — фирменный стиль BetBoom.
   Палитра и типографика из брендбука BetBoom:
   • Yellow #F8F700 — основной, всегда в макете, в паре с чёрным.
   • Black Grey #222524 / Grey #F1F4F3 — фоновая пара (тёмная/светлая).
   • Акценты (мелкие элементы): Fuchsia #F61875, Lime #91FF55.
     Жёлтый сочетается со всеми, кроме Lime.
   • Заголовки — узкий тяжёлый шрифт (ONY Track → веб-замена Oswald Bold, капс).

   Task 1 редизайна: фикс-стейдж 1920×1080 (см. stage.js — скейлер) +
   токены дизайн-системы. Остальные экраны (#menu, #game, оверлеи) пока
   визуально НЕ переверстаны — это Задачи 3-6; здесь только каркас и
   легаси-алиасы токенов, чтобы текущая вёрстка не сломалась.
   ============================================================ */

/* ---- Фирменные шрифты BetBoom (ONY) ----
   ONY Track (Black, узкий) — заголовки/дисплей; ONY One — кнопки/текст. */
@font-face { font-family: "ONY Track"; src: url("assets/fonts/ony/ONYTrack-CompressedBlack.woff2") format("woff2"); font-weight: 900; font-style: normal; font-display: swap; }
@font-face { font-family: "ONY Track Condensed"; src: url("assets/fonts/ony/ONYTrack-CondensedBlack.woff2") format("woff2"); font-weight: 900; font-style: normal; font-display: swap; }
@font-face { font-family: "ONY Track UC"; src: url("assets/fonts/ony/ONYTrack-UltraCondensedBlack.ttf") format("truetype"); font-weight: 900; font-style: normal; font-display: swap; }
@font-face { font-family: "ONY One"; src: url("assets/fonts/ony/ONYOne-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "ONY One"; src: url("assets/fonts/ony/ONYOne-Medium.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "ONY One"; src: url("assets/fonts/ony/ONYOne-Bold.ttf") format("truetype"); font-weight: 700; font-style: normal; font-display: swap; }

:root {
  /* ---- Токены редизайна ---- */
  --yellow: #F8F700;
  --ink: #0A0A0A;
  --panel: #1A1C1B;
  --panel-2: #222524;
  --grey-bg: #F1F4F3;
  --fuchsia: #F61875;
  --lime: #91FF55;
  --text: #F1F4F3;
  --muted: #9AA19D;
  --line: rgba(255, 255, 255, .10);
  --disp: "ONY Track", "Oswald", "PT Sans Narrow", sans-serif;
  --body: "ONY One", "Manrope", system-ui, sans-serif;
  --r-lg: 20px;
  --r-md: 14px;

  /* ---- Легаси-алиасы: используются текущей вёрсткой экранов игры,
     которая будет переверстана в Задачах 3-6. Значения — ТОЧНО как в старом
     style.css (до Task 1), чтобы непереверстанные экраны выглядели без
     изменений. Не удалять раньше времени и не путать с новыми токенами
     выше (--panel, --r-lg и т.д.), которые предназначены для будущей
     переверстки, а не для текущей вёрстки. ---- */
  --font-body: var(--body);
  --font-display: var(--disp);
  --bg: #1b1d1c;
  --bg-2: #222524;
  --panel-solid: #2a2d2b;   /* = старое значение --panel; см. .game-card/.person/.fact */
  --radius: 18px;            /* старое значение (было 18px, НЕ путать с --r-lg:20px) */
  --shadow: 0 14px 34px rgba(0, 0, 0, 0.5);
  --glow-y: 0 0 0 1px rgba(248, 247, 0, 0.55), 0 10px 28px rgba(248, 247, 0, 0.28);
  --ok: var(--lime);
  --ok-bg: rgba(145, 255, 85, 0.14);
  --no: var(--fuchsia);
  --no-bg: rgba(246, 24, 117, 0.14);
}

* { box-sizing: border-box; margin: 0; -webkit-tap-highlight-color: transparent; }

html, body {
  height: 100%;
  background: #000;
  overflow: hidden;
  font-family: var(--body);
  color: var(--text);
  -webkit-user-select: none;
  user-select: none;
}

/* ---------- Резиновый (fluid) стейдж ----------
   Раньше здесь был фикс-стейдж 1920×1080 (position:absolute + transform:scale
   + отрицательные margin для центрирования, см. git-историю) — заменён на
   заполнение окна без масштабирования: #stage растягивается на весь
   #stage-wrap (100vw/100dvh), letterbox/чёрные поля больше не нужны.
   Экраны внутри (.auth-screen/.menu-screen/.game-screen) сами становятся
   flex/grid-контейнерами 100%×100% — см. соответствующие секции ниже. */
#stage-wrap {
  position: fixed;
  inset: 0;
  overflow: hidden;
}
#stage {
  position: relative;
  width: 100vw;
  height: 100dvh;
  overflow: hidden;
}

/* Брендовый градиент непереверстанных экранов — раньше жил на html,body,
   но html,body теперь #000 (нужен для letterbox фикс-стейджа), поэтому
   градиент переехал на #app: под ним нет letterbox-полей, и он совпадает
   1:1 с прежним (значения — точная копия из style.css до Task 1). */
#app {
  position: relative;
  width: 100%;
  height: 100%;
  background:
    radial-gradient(1000px 560px at 88% -10%, rgba(248, 247, 0, 0.10), transparent 60%),
    radial-gradient(900px 520px at 6% 108%, rgba(38, 92, 255, 0.10), transparent 60%),
    linear-gradient(180deg, var(--bg-2), var(--bg));
  background-attachment: fixed;
}

/* ---------- Экраны ---------- */
.screen { display: none; }
.screen.active { display: block; animation: fade-in .35s ease both; }

@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes rise-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@keyframes pop-in { 0% { opacity: 0; transform: scale(.9) translateY(10px); } 100% { opacity: 1; transform: none; } }
@keyframes placed-pop { 0% { transform: scale(.85); } 60% { transform: scale(1.05); } 100% { transform: scale(1); } }
@keyframes pulse-ok { 0% { box-shadow: 0 0 0 0 rgba(145,255,85,.5); } 100% { box-shadow: 0 0 0 10px rgba(145,255,85,0); } }
@keyframes pulse-no { 0% { box-shadow: 0 0 0 0 rgba(246,24,117,.5); } 100% { box-shadow: 0 0 0 10px rgba(246,24,117,0); } }

/* ---------- Кнопки ---------- */
.btn {
  border: none;
  border-radius: 12px;
  padding: 11px 22px;
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .6px;
  cursor: pointer;
  transition: transform .12s ease, box-shadow .2s ease, background .2s ease, opacity .2s ease;
  color: var(--text);
}
.btn:active { transform: scale(0.96); }
.btn-primary {
  background: var(--yellow);
  color: var(--ink);
  box-shadow: 0 6px 18px rgba(248, 247, 0, 0.28);
}
.btn-primary:hover { box-shadow: 0 10px 26px rgba(248, 247, 0, 0.45); transform: translateY(-1px); }
.btn-primary:disabled {
  background: rgba(255,255,255,0.09);
  color: var(--muted);
  box-shadow: none;
  opacity: .7;
  cursor: not-allowed;
  transform: none;
}
.btn-ghost { background: rgba(255,255,255,0.07); border: 1px solid var(--line); color: var(--text); }
.btn-ghost:hover { background: rgba(255,255,255,0.14); }
.btn-block { display: block; width: 100%; margin-top: 10px; padding: 15px; font-size: 17px; }

/* ---------- Меню: старые классы (.menu-inner/.menu-title/.menu-sub/
   .game-card-num) заменены редизайном Task 4 — см. секцию
   «Task 4: Экран меню (`.menu-*`)» ниже, рядом с Task 3 (`.auth-*`/
   `.deco-*`), откуда menu забирает общий декор-шелл. ---------- */

/* ============================================================
   Резиновая (fluid) вёрстка игровой доски (`.game-*`, `.person`, `.slot`,
   `.fact*`). Раньше был фикс-канвас 1920×1080 с абсолютным позиционированием
   1:1 из Figma (см. git-историю / docs/superpowers/design/game-start-spec.md
   для исходных координат) — переведено на flex/grid, заполняющий 100%
   ширины/высоты окна: .game-screen — flex-колонка (шапка/подзаголовок/тело),
   .game-body — grid из 3 колонок (люди 41fr | факты 31fr | сайдбар 23fr —
   пропорции взяты из исходных Figma-ширин 783/602/431). Шрифты — clamp().
   Пиксель-в-пиксель с макетом больше не сохраняется (осознанное решение
   заказчика ради резиновости) — см. docs/superpowers/design/
   fluid-conversion-spec.md.
   ID-хуки для app.js (#peopleCol/#factPool/#gameTitle/#gameRound/
   #gameProgress/#checkBtn/#scoreChip/#pairValueChip/#hintsChip/#backToMenu)
   и классы (.person/.avatar/.person-name/.slot/.fact/.fact-body/.fact-text/
   .fact-hint/.fact-info) не менялись — переверстан только их CSS.
   ============================================================ */
.game-screen {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--ink);
  color: var(--text);
  font-family: var(--body);
  display: flex;
  flex-direction: column;
}
.screen.active.game-screen { display: flex; }

/* ---------- Жёлтая шапка ---------- */
/* Шапка по Figma: три группы — слева menu+заголовок, ПО ЦЕНТРУ кадра
   round+пилюля (в макете 734..1186, центр 960 = центр 1920), справа лого.
   grid 1fr auto 1fr держит центр-группу точно посередине независимо от
   ширины боковых групп. */
.game-header {
  flex: 0 0 auto;
  width: 100%;
  height: clamp(64px, 8vh, 92px);
  box-sizing: border-box;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(10px, 1.5vw, 24px);
  padding: 0 clamp(16px, 2vw, 34px);
  background: var(--yellow);
}
.game-header-left {
  justify-self: start;
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.55vw, 30px);   /* Figma: menu→заголовок ~30px */
  min-width: 0;
}
.game-header-center {
  justify-self: center;
  display: flex;
  align-items: center;
  gap: clamp(12px, 1.65vw, 31px);   /* Figma: round→пилюля ~31px */
  min-width: 0;
}

/* «‹ Меню» (#backToMenu) */
.game-back {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, .75vw, 14px);             /* Figma: зазор иконка↔текст ~14px */
  box-sizing: border-box;
  height: clamp(34px, 5.2vh, 56px);
  min-width: clamp(92px, 7vw, 133px);      /* Figma 133×56 — не даём кнопке ужаться */
  padding: 0 clamp(11px, 1.05vw, 18px);    /* Figma: боковые отступы ~17–18px (итог 133) */
  border: none;
  border-radius: 7px;                       /* Copy game_start decode: menu Rectangle r=7 (было 15) */
  background: #1D1E1F;
  color: #EFEFEF;                           /* Figma: текст «Меню» #EFEFEF (не чистый белый) */
  font-family: var(--body);
  font-weight: 700;                         /* ONY One Bold */
  font-size: clamp(15px, 1.25vw, 24px);     /* Figma 24px @1920 */
  line-height: 1.2;                         /* Figma line height 120% */
  letter-spacing: 0;                        /* Figma letter spacing 0% */
  white-space: nowrap;
  cursor: pointer;
  transition: opacity .15s ease, transform .12s ease;
}
/* menu_icon — векторный шеврon «‹» из Figma (не символ): белый, stroke 1.788,
   round cap/join; ширина берётся из viewBox (9.14/15.89). */
.game-back-ic {
  flex: 0 0 auto;
  height: clamp(11px, .83vw, 16px);
  width: auto;
  color: #fff;
}
.game-back:hover { opacity: .82; }
.game-back:active { transform: scale(.96); }

/* #gameTitle («Интуиция | Выпуск 1») — ONY Track 900, uppercase, #040404.
   Самый "тянущийся" элемент шапки: flex:1 1 auto + ellipsis, чтобы не
   ломать раскладку на узких окнах вместо того, чтобы вытеснять соседей. */
.game-title-text {
  flex: 0 1 auto;                 /* не растягиваем — стоит сразу за menu (Figma x193) */
  min-width: 0;
  display: flex;
  align-items: center;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: var(--disp);
  font-weight: 900;
  font-size: clamp(22px, 3.2vw, 62px);   /* Figma 62px @1920 (ONY Track Compressed Black) */
  line-height: .75;               /* Figma line height 75% */
  text-transform: uppercase;
  color: #000000;                 /* Figma fill #000000 */
  white-space: nowrap;
}

/* #gameRound («РАУНД N») — обновляется в app.js/updateProgress(). */
.game-round {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: visible;
  font-family: var(--disp);
  font-weight: 900;
  font-size: clamp(22px, 3.2vw, 62px);   /* Figma: тот же размер, что заголовок — 62px */
  line-height: .75;                       /* Figma line height 75% */
  text-transform: uppercase;
  color: #040404;                         /* Figma fill #040404 */
  white-space: nowrap;
}

/* #gameProgress (пилюля «Сопоставлено X/10») */
/* #gameProgress (пилюля «Сопоставлено X/10») — Figma 299×56, radius 15,
   fill #222524; текст ONY One Regular 24px #FFFFFF (ширина текста 223 в
   299 → гориз. паддинг ~38px). */
.game-progress {
  flex: 0 0 auto;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 clamp(18px, 2vw, 38px);
  height: clamp(34px, 5.2vh, 56px);
  border-radius: 8px;                     /* Copy game_start decode: counter pill Rectangle r≈8.44 (было 15) */
  background: #222524;
  color: #FFFFFF;
  font-family: var(--body);
  font-weight: 400;                       /* Figma: ONY One Regular */
  font-size: clamp(13px, 1.25vw, 24px);   /* Figma 24px @1920 */
  line-height: 1.2;
  white-space: nowrap;
}

/* Лого BETBOOM — assets/ui/logo-betboom.png уже чёрный на прозрачном
   фоне, подходит для жёлтой шапки без фильтра. */
.game-header-logo {
  position: relative;
  justify-self: end;
  flex: 0 0 auto;
  width: clamp(108px, 10.6vw, 227px);
  height: clamp(26px, 4.6vh, 54px);
}
.game-logo-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  z-index: 2;
}
/* Текстовый фолбэк на случай 404 картинки (см. onerror в разметке) —
   спрятан за .game-logo-img, пока файл доступен. */
.game-logo-mark {
  width: 34px; height: 34px;
  border-radius: 8px;
  background: var(--ink);
  color: var(--yellow);
  display: grid; place-items: center;
  font-family: var(--disp);
  font-weight: 900;
  font-size: 17px;
}
.game-header-logo.no-asset .game-logo-mark,
.game-header-logo.no-asset .game-logo-text { display: flex; }
.game-logo-text {
  font-family: var(--disp);
  font-weight: 900;
  font-size: 26px;
  letter-spacing: .3px;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
}

/* ---------- Подзаголовок ---------- */
/* #hint («Перетащи каждый факт к нужному стримеру») — ONY One 400, center. */
.hint {
  flex: 0 0 auto;
  width: 100%;
  box-sizing: border-box;
  padding: clamp(6px, 1vh, 12px) clamp(16px, 2vw, 30px) 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: visible;
  text-align: center;
  color: #6A6A6A;
  font-family: var(--body);
  font-weight: 400;
  font-size: clamp(14px, 1.2vw, 23px);
  line-height: 1.2;
}

/* ---------- Тело: grid из 3 колонок (люди | факты | сайдбар) ----------
   Пропорции 41/31/23 fr — взяты из исходных Figma-ширин 783/602/431.
   min-height:0 обязателен — иначе grid-строка растягивается по контенту
   и 10 карточек/сайдбар перестают ужиматься под высоту окна (обрезка). */
.game-body {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(0, 627fr) minmax(0, 756fr) minmax(0, 431fr);  /* новая Copy: люди 627 / факты 756 / сайдбар 431 (было 783/602/431) */
  gap: clamp(10px, 1vw, 22px);
  padding: clamp(10px, 1.4vh, 26px) clamp(14px, 2vw, 40px);
}
/* .game-main — чистая обёртка в разметке вокруг #peopleCol/#factPool;
   display:contents делает оба её прямых потомка грид-item'ами наравне
   с .game-side, т.е. реальными колонками 1 и 2 трёхколоночного грида. */
.game-main { display: contents; }

/* ---------- Левая колонка: люди (#peopleCol) ----------
   Флекс-колонка на всю высоту грид-строки; 10 строк — flex:1 1 0,
   поровну заполняют доступную высоту (min-height:0 на каждой — иначе
   контент не даёт строке ужаться и колонка обрезается снизу). */
#peopleCol {
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  /* Figma: gap 10 / row 80 → gap ≈ 10/(80+10) = 11.1% высоты строки;
     clamp с vh держит ту же пропорцию на разных высотах окна, максимум
     ограничен фактическим значением макета (10px). */
  gap: clamp(4px, .9vh, 10px);
}
/* Строка человека: bg #1D1E1F, radius 15, border 1.43px.
   Аватар слева + ИМЯ (ONY Track капс белый) + слот справа — flex-строка
   вместо абсолютных left/top, порядок в разметке = порядок во flex. */
.person {
  position: relative;
  width: 100%;
  flex: 1 1 0;
  min-height: 0;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: 0;   /* новая Copy 627: между avatar/slot нет flex-gap — слот ВСЕГДА
               прижат к правому краю контента (доля от 627 фиксирована), а
               зазор avatar→имя задан padding-left на .person-name (не gap,
               иначе он же раздвигал бы имя←→слот, чего в декоде нет: слот
               у правого края всегда, независимо от длины имени). */
  /* Figma game_start (627×80): avatar x9 w64 (аватар слева), SLOT фикс-ширины
     373/627 = 59.5% у правого края (слот всегда завершается у content-края —
     без доп. отступа), имя — flex-зона МЕЖДУ ними, ВЫРАВНЕНА ПО ЛЕВОМУ краю
     (не по центру — левый край текста имени одинаков во всех 10 строках
     независимо от длины ника). Боковые инсеты ≈9px (9/627). Вертикальный
     паддинг мал и не раздувает высоту (min-height:0 + flex:1 1 0). */
  /* Fix round 1 (ревью Task 3): ГОРИЗОНТАЛЬНОГО padding на .person больше НЕТ —
     `.slot { flex-basis: 59.5% }` резолвится в % от CONTENT-BOX флекс-контейнера
     (.person), а не от его border-box; при паддинге 9px с каждой стороны это
     давало 59.5% от (627−18)=609, т.е. слот ≈362px вместо целевых 373px (недобор
     ~11px/3%, живой замер на staging давал ещё больше из-за border). Боковые
     инсеты 9px перенесены на margin у крайних детей (.avatar/.slot) — тогда
     59.5% считается от почти полной ширины строки (минус только 1.43px рамки
     ×2, что уже, а не 18px паддинга). Вертикальный паддинг (не влияет на
     flex-basis по главной оси row) остаётся на .person. */
  padding: 0;   /* было clamp(4px,.7vh,8px) 0 — вертикальный padding делал СЛОТ
                   короче строки, из-за чего карточки-факты не совпадали по высоте
                   со слотами. Убран → слот заполняет всю высоту строки, и слот ≈
                   строка ≈ карточка-факт (1/N). Горизонтальный инсет и так был 0
                   (перенесён на margin у .avatar/.slot). */
  /* Task 4: градиентная рамка (fig: GRADIENT_LINEAR сверху-вниз rgba(255,255,255,.10)→0,
     strokeWeight 1.43) — border:solid transparent + два background-слоя:
     padding-box (сплошной fill #1D1E1F) поверх border-box (сам градиент-«штрих»). */
  border: 1.43px solid transparent;
  background:
    linear-gradient(#1D1E1F, #1D1E1F) padding-box,
    linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,0)) border-box;
  border-radius: 11px;                        /* новая Copy: радиус карточек 11 (был 15) */
  overflow: hidden;
  transition: border-color .2s ease, background .25s ease, box-shadow .25s ease;
}
.person.correct {
  background: var(--ok-bg);
  border-color: var(--ok);
  animation: pulse-ok .6s ease;
}
.person.wrong {
  background: var(--no-bg);
  border-color: var(--no);
  animation: pulse-no .6s ease;
}

/* Аватар: фото (cover) или серый плейсхолдер — см. styleAvatar() в app.js.
   Квадрат по высоте строки (aspect-ratio:1 держит форму на любой высоте). */
.avatar {
  position: relative;
  flex: 0 0 auto;
  height: 100%;
  /* Кап высоты: в раундах с малым числом пар строка .person (flex:1 1 0)
     вытягивается по высоте, а квадратный аватар (height:100% + aspect-ratio)
     раздувался по ширине и съедал колонку имени (ник падал до нечитаемых
     ~10px). Замер 10-строчной доски: аватар ≈6.0–6.2vh (66.6px@1080 /
     43.1px@720) — кап 6.6vh НЕ трогает полную доску, но в раундах <10 пар
     держит аватар того же размера (центрируется по вертикали), освобождая
     имя. Ширина следует из aspect-ratio → тоже ограничена. */
  max-height: clamp(40px, 6.6vh, 120px);
  margin-left: clamp(4px, .47vw, 9px);  /* Fix round 1: левый инсет строки — теперь margin, не padding у .person (см. коммент там) */
  aspect-ratio: 64 / 65;   /* Figma photo_streamer 64×65 */
  border-radius: 7px;      /* Copy game_start decode: photo Rectangle r=7 (было 10) */
  background-color: #3a3f3c;
  background-size: cover;
  background-position: center;
  cursor: zoom-in;
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.14);
  /* Центрирование инициалов-фолбэка (когда нет фото) */
  display: grid;
  place-items: center;
  font-family: var(--disp);
  font-weight: 900;
  font-size: clamp(12px, 1.6vw, 22px);
  color: #fff;
  text-transform: uppercase;
}
/* Имя name_streamer: ONY Track 900, по центру по вертикали. Ник занимает
   flex-зону между аватаром и слотом; fitPersonNames() в app.js дожимает
   font-size, если длинный ник всё равно не влезает. */
/* Имя name_streamer (Figma game_start 627-строка): ONY Track Compressed Black
   42, lineHeight .75. По ГОРИЗОНТАЛИ — ВЫРАВНЕНО ПО ЛЕВОМУ КРАЮ, не центр:
   во всех 10 строках левый край текста имени идентичен (87/627 от начала
   строки = 14px после аватара) независимо от длины ника — слот же сидит на
   фиксированной доле у правого края и от длины имени не зависит. */
.person-name {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  z-index: 2;
  display: block;               /* блок — чтобы работали ellipsis/обрезка */
  text-align: left;             /* Figma: левый край текста фиксирован во всех строках */
  padding-left: clamp(3px, .73vw, 14px);  /* Figma: зазор avatar→имя = 14/627 строки */
  margin-right: clamp(8px, 1vw, 18px);  /* зазор имя→слот: без него длинный ник (NOTINMYHOUSE) упирается в пунктир слота. margin (а не padding) — сжимает сам бокс, clientWidth уменьшается корректно, fitPersonNames подгоняет шрифт без обрезки многоточием; геометрия слота (flex 0 0 59.5%) не меняется */
  font-family: var(--disp);
  font-weight: 900;
  font-size: clamp(15px, 2.19vw, 42px);   /* Figma 42px @1920 (42/1920 ≈ 2.19vw) */
  line-height: .75;             /* Figma line-height 75% */
  letter-spacing: 0;
  text-transform: uppercase;
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}

/* Слот «Перетащи факт сюда» — ФИКС-ширина 373/627 = 59.5% у правого края
   строки (Figma game_start; было 504/783=64.4% в старой Copy — ширины
   строки/слота изменились). Левый край одинаков во всех строках → слоты
   выровнены; имя занимает всю среднюю зону, не влияя на позицию слота. */
.slot {
  position: relative;
  flex: 0 0 59.5%;
  margin-right: clamp(4px, .47vw, 9px);  /* Fix round 1: правый инсет строки — margin, не .person padding (см. коммент у .person) */
  min-width: 0;
  height: 100%;
  box-sizing: border-box;
  background: #1D1E1F;              /* Figma frame_sm fill #1D1E1F */
  border: 1px dashed #3F3F3F;
  border-radius: 5px;               /* Copy game_start decode: слот-frame r≈5.3 (было 10) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4px clamp(8px, 1vw, 10px);
  overflow: hidden;
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.slot:not(.filled)::after {
  content: "Перетащи факт сюда";
  font-family: var(--body);
  font-size: clamp(10px, .99vw, 19px);   /* Task 5: приведено к тому же размеру, что и .fact
                                             (см. правку выше) — плейсхолдер не крупнее самих
                                             фактов; реальный line-box глифа ONY One ≈23px @1920 */
  font-weight: 400;
  color: #3F3F3F;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.slot.drop-hover {
  border-color: var(--yellow);
  border-style: solid;
  background: rgba(248,247,0,0.12);
  box-shadow: var(--glow-y);
}
/* Возврат факта в пул — app.js добавляет .drop-hover на #factPool как
   валидную зону сброса; подсветка была потеряна при переверстке. */
.fact-pool.drop-hover {
  background: rgba(248,247,0,0.06);
  box-shadow: inset 0 0 0 2px rgba(248,247,0,0.3);
  border-radius: 15px;
}
/* margin-right НЕ сбрасываем — это инсет строки (правый край слота = правый
   край строки минус 9px и в пустом, и в заполненном состоянии, Fix round 1). */
.slot.filled { border-style: solid; border-color: transparent; padding: 0; }

/* ---------- Центральная колонка: карточки фактов (#factPool) ----------
   Флекс-колонка на всю высоту грид-строки, 10 карточек — flex:1 1 0,
   поровну заполняют доступную высоту (тот же паттерн, что #peopleCol). */
#factPool {
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  /* та же пропорция gap/row, что и #peopleCol — см. коммент там. */
  gap: clamp(4px, .9vh, 10px);
}

/* Карточка факта: bg #323232 + linear-gradient белый 10%→0%
   + backdrop-filter blur(28.5px), radius 15, border 1.43px.
   Ширина/высота НЕ в базовом классе .fact — та же карточка переиспользуется
   и в #factPool (колонка, тянется на flex:1 1 0), и внутри .slot (после
   матча, там нужно 100%/100% от слота) — см. два разных правила ниже
   (.fact-pool > .fact и .slot .fact), которые не пересекаются (карточка
   не может быть одновременно прямым ребёнком #factPool и потомком .slot). */
.fact-pool > .fact {
  width: 100%;
  /* Фикс-высота = 1/N колонки, где N = число пар в раунде (--rows задаётся
     в renderBoard на #peopleCol и #factPool). Строки людей слева — flex:1 1 0,
     т.е. тоже 1/N; тот же gap → высота карточки-факта ТОЧНО совпадает с
     высотой строки/слота при любом числе пар (8, 2 и т.д.). Раньше знаменатель
     был захардкожен 10 → при N≠10 карточки были ниже слотов (визуальный
     рассинхрон). flex:0 0 (фикс) — при переносе факта в слот оставшиеся
     карточки НЕ растягиваются, сохраняют размер и стекаются к верху. */
  flex: 0 0 calc((100% - (var(--rows, 10) - 1) * clamp(4px, .9vh, 10px)) / var(--rows, 10));
  min-height: 0;
}
/* Высота карточки-факта = 1/N высоты колонки (N=--rows), т.е. РОВНО шаг строки
   слева (.person, flex:1 1 0). Тот же gap → карточки выстраиваются строка-в-строку
   со слотами и заполняют колонку до низа (без «стекания» вверх). Чтобы высота
   ещё и совпала со слотом, у .person убран вертикальный padding — слот заполняет
   строку (см. .person). flex:0 0 (фикс) — оставшиеся карточки не растягиваются
   при переносе факта в слот. */
.fact {
  position: relative;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(8px, 1vw, 12px);
  text-align: center;    /* Task 3: текст факта — center, не left */
  /* Task 4: та же техника градиентной рамки, что у .person, — базовый
     fill #323232 (padding-box) + градиент-«штрих» (border-box). */
  border: 1.43px solid transparent;
  background:
    linear-gradient(#323232, #323232) padding-box,
    linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,0)) border-box;
  backdrop-filter: blur(28.5px);
  -webkit-backdrop-filter: blur(28.5px);
  border-radius: 11px;                    /* новая Copy: радиус карточек 11 (был 15) */
  /* Figma game_start (карточка 756): молния-круг у правого края (правый
     инсет 22/756), текст факта центрирован в оставшейся зоне (левый инсет
     ≈20/756) — асимметрично, было ошибочно симметрично 27/27. */
  padding-left: clamp(9px, 1.05vw, 20px);
  padding-right: clamp(9px, 1.15vw, 22px);
  font-family: var(--body);
  /* Task 5 фикс-заход: предыдущая правка (fs 22px, .fact-text line-height
     1.05 → computed line-height 23.1px) НЕ дала нужный результат — замерено
     на staging через Range.getClientRects() (реальный line-box глифа ONY
     One, а не CSS line-height, который на line-box текста не влияет —
     проверено: варьирование line-height не меняло итоговую высоту, только
     font-size даёт линейный эффект): fs 22px → line-box глифа ≈26px (заметно
     крупнее фигмы), fs 19px → line-box глифа ровно 23.0px — точное попадание
     в целевые h≈23 из декода game_start. Новый clamp пропорционально уменьшен
     от старого (22→19, т.е. ×19/22) с тем же min/max соотношением. */
  font-size: clamp(10px, .99vw, 19px);   /* Figma: строка факта ~23px @1920 (замерено на реальном рендере) */
  font-weight: 400;
  line-height: 1.24;
  color: #fff;
  cursor: grab;
  touch-action: none;
  box-shadow: 0 3px 12px rgba(0,0,0,0.32);
  transition: transform .12s ease, box-shadow .2s ease, border-color .2s ease;
}
.fact:hover {
  transform: translateY(-1px);
  border-color: rgba(248,247,0,0.5);
  box-shadow: 0 8px 22px rgba(0,0,0,0.45);
}
.fact-body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
}
.fact-text {
  display: -webkit-box;
  -webkit-line-clamp: 3;   /* до 3 строк (по просьбе заказчика — длинные факты влезают целиком) */
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-align: center;   /* Figma: text CENTER, vAlign top */
  line-height: 1.05;    /* Figma line-height 1.05 */
}

/* Текст взятой подсказки под фактом (Figma game_help_3): жёлтый clue
   ONY One Regular 15px #F8F700, center. */
.fact-hint {
  display: none;
  text-align: center;
  font-family: var(--body);
  font-size: clamp(10px, .78vw, 15px);   /* Figma 15px @1920 */
  font-weight: 400;                      /* Figma Regular (был 700) */
  line-height: 1.2;
  color: var(--yellow);                  /* #F8F700 */
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Подсказка теперь показывается в модалке (#hintReveal), НЕ инлайн — карточка
   факта не меняет высоту и доска не «едет». Инлайн .fact-hint не рендерится. */

/* Молния — взять подсказку. Figma: ELLIPSE 33×33 (доля высоты карточки
   ≈41%, 33/80) fill #F61875 + белая молния-VECTOR ~10.4×19 внутри
   (тот же path, что .side-hints-bolt в сайдбаре, но один экземпляр) —
   реальный CSS-круг (border-radius:50%, background:#F61875), а не
   растровая/векторная картинка, чтобы фон читался как настоящий фон. */
.fact-info {
  position: relative;
  flex: 0 0 auto;
  height: 41%;
  aspect-ratio: 1;
  min-width: 18px;
  min-height: 18px;
  max-width: clamp(34px, 5.2vh, 64px);
  max-height: clamp(34px, 5.2vh, 64px);
  padding: 0;
  border: none;
  border-radius: 50%;
  background: #F61875;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform .12s ease;
}
.fact-info-bolt {
  width: 31.5%;    /* 10.4/33 */
  height: 57.6%;   /* 19/33 */
  fill: #FFFFFF;
  display: block;
}
.fact-info:hover { transform: scale(1.1); }
/* Надпись «Взять подсказку» при наведении на молнию */
.fact-info::after {
  content: "Взять подсказку";
  position: absolute;
  right: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  background: #0f110f;
  border: 1px solid rgba(248,247,0,0.55);
  border-radius: 8px;
  padding: 6px 12px;
  font-family: var(--body);
  font-weight: 700;
  font-size: 12.5px;
  color: var(--text);
  white-space: nowrap;
  box-shadow: 0 6px 18px rgba(0,0,0,0.5);
  opacity: 0;
  pointer-events: none;
  transition: opacity .15s ease;
  z-index: 20;
}
.fact-info:hover::after { opacity: 1; }
.no-hints .fact:not(.hint-used) .fact-info { display: none; }

/* Подсказка взята — молния на карточке остаётся БЕЛОЙ (фуксия-кружок),
   чтобы было видно, что по ней можно кликнуть и снова открыть подсказку.
   «Погасание» происходит в сайдбаре (см. .side-hints-bolt.spent). */
.fact.hint-used .fact-info { cursor: pointer; }
.fact.hint-used .fact-info::after { content: "Показать подсказку"; }

.fact:active { cursor: grabbing; }
.fact.dragging { opacity: 0; pointer-events: none; }

/* факт, лежащий в слоте — жёлтый (matched state, бренд-цвет всегда в макете).
   width/height/flex тут ОБЯЗАТЕЛЬНЫ (100%/100%/none) — см. коммент у
   .fact-pool > .fact выше про баг с "flex: 0 0 80px" в базовом классе. */
.slot .fact {
  width: 100%;
  height: 100%;
  flex: none;
  background: var(--yellow);
  border-color: transparent;
  color: var(--ink);
  font-weight: 700;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: 0 4px 14px rgba(248, 247, 0, 0.32);
}
.slot .fact .fact-hint { color: #4a4a00; }
/* Размещённый факт: слот ниже пуловой карточки (64 vs 80). Текст переносится
   свободно (без line-clamp), а fitPlacedFact() в app.js ужимает размер шрифта,
   пока текст не поместится по высоте слота — длинные факты не обрезаются. */
.slot .fact .fact-text {
  display: block;
  -webkit-line-clamp: unset;
  white-space: normal;
  overflow-wrap: anywhere;
}
/* Молния ОСТАЁТСЯ доступной и у размещённого факта (по решению заказчика) —
   подсказку можно взять и после перетаскивания в слот. Клик по .fact-info
   не стартует drag (см. onPointerDown в app.js), обработчик askHint — на той
   же карточке. Кружок фуксия на жёлтом факте виден и кликабелен. */
.slot .fact.placed { animation: placed-pop .25s ease; }

/* ---------- Правый сайдбар ----------
   Флекс-колонка на всю высоту грид-строки: счёт → цена пары →
   подсказки → «Проверить ответы» → камера. Верхние блоки — flex:0 0 auto
   (высота ограничена сверху clamp'ом), камера — flex:0 0 auto с
   margin-top:auto, чтобы забрать весь оставшийся низ колонки (без
   flex-grow — иначе aspect-ratio перестал бы держать форму 16:9).
   Task 5: зазоры между блоками НЕ равномерные (см. game-start-fig-spec.md →
   «Вертикальные отступы сайдбара»: score→10→price→27→(баннер удалён,
   Task 4)→41→hints→10→check→28→camera). Единый `gap` заменён на явные
   margin-top у каждого
   блока (кроме первого — score), пропорциональные исходным Figma-долям
   от высоты сайдбара 890 (10/27/41/10/28 ≈ 2.45vh/4.08vh/6.82vh/2.45vh на
   базе кадра 1080 = viewport 1080). Камера по-прежнему margin-top:auto —
   забирает весь остаток и держит низ вровень с низом последней строки. */
/* Сайдбар — абсолютные ПРОЦЕНТЫ высоты столбца (доли из Figma game_start,
   база 890px = board 147..1037). Так пропорции и зазоры совпадают с макетом
   при ЛЮБОМ соотношении окна (раньше flex + margin-top:auto сбрасывал весь
   остаток высоты в одну дыру перед камерой). Верхние края (доля от 890):
   score 0 · price 90/890 · hints 450/890 · check 540/890 ·
   camera 648/890. Высоты: чипы 80/890, camera — до низа. */
.game-side {
  position: relative;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  box-sizing: border-box;
}

/* «СЧЁТ» + жёлтый бокс с числом (#scoreChip = сам жёлтый бокс) —
   единая двухцветная пилюля. */
/* score_counter (Figma 281×80 в сайдбаре 431) — уже, чем остальные блоки
   (~65% ширины) и прижат к правому краю: правая кромка выравнивается с
   ценой/подсказками/камерой, слева остаётся зазор. */
/* score_counter (Figma game_start: 281×80) — тёмный box (162×80, левые
   углы r≈12, правые квадратные, #222524) + жёлтый box (119×80, ВСЕ углы
   r11, #F8F700), НАЧИНАЕТСЯ РОВНО ТАМ, ГДЕ ЗАКАНЧИВАЕТСЯ тёмный (162+119=281,
   БЕЗ нахлёста — было ошибочно 200/119 с нахлёстом 38px по старой Copy).
   СЧЁТ центрируется во всём тёмном боксе; «0» — в жёлтом. */
.side-score {
  position: absolute;
  top: 0;
  right: 0;                     /* прижат к правому краю сайдбара */
  width: 65.2%;                 /* 281 / 431 */
  height: 8.99%;                /* 80 / 890 */
  box-sizing: border-box;
}
.side-score-label {
  position: absolute; left: 0; top: 0; height: 100%;
  width: 57.65%;                /* 162 / 281 (было 71.17%=200/281, устаревший нахлёст) */
  box-sizing: border-box;
  border-radius: 12px 0 0 12px; /* Copy decode: r≈12.05 (было 15), скруглены только левые углы */
  background: #222524;
  display: flex;
  align-items: center;
  justify-content: center;      /* без нахлёста — центр во всём тёмном боксе */
  font-family: var(--disp);
  font-weight: 900;
  font-size: clamp(22px, 3.23vw, 62px);   /* Figma 62px @1920 */
  line-height: .75;             /* Figma line-height 75% */
  text-transform: uppercase;
  color: #FFFFFF;
}
.side-score-value {
  position: absolute; right: 0; top: 0; height: 100%;
  width: 42.35%;                /* 119 / 281 */
  z-index: 1;
  box-sizing: border-box;
  border-radius: 0 11px 11px 0; /* Copy decode: r=11, но левые углы прямые — вертикальный шов с тёмным лейблом */
  background: var(--yellow);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--disp);
  font-weight: 900;
  font-size: clamp(22px, 3.23vw, 62px);   /* Figma 62px @1920 */
  line-height: .75;
  color: #0D0D0D;               /* Figma #0D0D0D */
}

/* «Цена пары – N баллов» (#pairValueChip) */
.side-pill {
  position: absolute;
  top: 10.11%;                  /* 90 / 890 */
  left: 0;
  width: 100%;
  height: 8.99%;                /* 80 / 890 */
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 3px solid #fff;
  border-radius: 11px;          /* Copy game_start decode: price Rectangle r=11 (было 15) */
  padding: clamp(6px, 1vh, 12px) clamp(14px, 1.4vw, 18px);
  text-align: center;
  font-family: var(--body);
  font-weight: 400;                        /* Figma: ONY One Regular (был Bold) */
  font-size: clamp(13px, 1.45vw, 28px);    /* Figma 28px @1920 (был 18) */
  line-height: 1.2;
  color: #EFEFEF;
}

/* counter_hints (Figma game_start: 431×80) — контейнер БЕЗ фона: две
   скруглённые коробки БЕЗ нахлёста, встык. Тёмная «number of hints»
   (236×80, #222524, r11) слева; розовая (194×80, #F61875, r11) справа,
   начинается ровно там, где заканчивается тёмная (236+194=430 — было
   ошибочно 268/194 с нахлёстом 32px по старой Copy). Внутри розовой:
   2 залитых белых молнии + белый круг с числом. Пропорции — доли от 431×80. */
.side-hints {
  position: absolute;
  top: 50.56%;                  /* 450 / 890 */
  left: 0;
  width: 100%;
  height: 8.99%;                /* 80 / 890 */
  box-sizing: border-box;
}
.side-hints-label-box {
  position: absolute; left: 0; top: 0; height: 100%;
  width: 54.76%;                     /* 236/431 (было 62.33%=268/430, устаревший нахлёст) */
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;  /* без нахлёста — центр во всём боксе */
  background: #222524;
  border-radius: 12px 0 0 12px;      /* Copy decode: r=11, скруглены только левые углы (шов с розовым боксом) */
}
.side-hints-label {
  max-width: 70%;                    /* Figma TEXT 166×52 внутри лейбла ~236 ⇒ ≈70% ⇒ перенос в 2 строки */
  white-space: normal;
  text-align: center;
  font-family: var(--body);
  font-weight: 700;                  /* ONY One Bold */
  font-size: clamp(13px, 2.15vh, 29px);   /* Figma 29px */
  line-height: 1.05;                 /* Figma h=52 на 2 строки 29px */
  letter-spacing: -.01em;            /* Figma -1% */
  color: #FFFFFF;
}
.side-hints-box {
  position: absolute; right: 0; top: 0; height: 100%;
  width: 45.24%;                     /* 194/431 (было 45.01% — сумма с label-box 54.76%
                                         давала 99.77%, ~1px тёмная щель в шве; дотянуто
                                         до 100%, как у блока СЧЁТ) */
  z-index: 1;
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  gap: clamp(8px, .95vw, 18px);      /* Figma: ~17–18px между молниями/кругом */
  padding: 0 clamp(12px, 1.3vw, 24px);
  background: var(--fuchsia);        /* #F61875 */
  border-radius: 0 11px 11px 0;      /* Copy decode: r=11, но левые углы прямые — вертикальный шов с тёмным лейблом */
}
.side-hints-bolt {
  flex: 0 0 auto;
  height: 56%;                       /* 45/80 */
  width: auto;
  fill: #FFFFFF;
  display: block;
  transition: fill .2s ease;
}
/* Использованная подсказка — молния «гаснет» на розовом блоке. */
.side-hints-bolt.spent { fill: rgba(255,255,255,.28); }
.side-hints-num {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  height: 60.6%;                     /* круг 48.5/80 */
  aspect-ratio: 47 / 48.52;
  border-radius: 50%;
  background: #FFFFFF;
  font-family: var(--body);
  font-weight: 700;                  /* ONY One Bold */
  font-size: clamp(13px, 2.15vh, 28px);   /* Figma 28px */
  line-height: 1;
  color: #0D0D0D;                    /* Figma #0D0D0D */
}

/* «Проверить ответы» (#checkBtn) — Figma start_of_check 430×80 r15.
   Disabled (по умолчанию): фон #323232, текст #545454, ONY One Bold 28px.
   Активная (10/10, :not(:disabled)): жёлтая (.btn-primary). */
.game-check {
  position: absolute;
  top: 60.67%;                  /* 540 / 890 */
  left: 0;
  width: 100%;
  height: 8.99%;                /* 80 / 890 */
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 11px;          /* Copy game_start decode: check Rectangle r=11 (было 15) */
  font-family: var(--body);
  font-weight: 700;                          /* ONY One Bold */
  font-size: clamp(15px, 1.45vw, 28px);      /* Figma 28px @1920 */
  line-height: 1.2;
  text-transform: none;
  letter-spacing: 0;
}
/* точное disabled-состояние из Figma (перебивает .btn-primary:disabled) */
.game-check:disabled {
  background: #323232;
  color: #545454;
  opacity: 1;
  box-shadow: none;
  border: 1px solid #000000;        /* Copy game_half decode: Rectangle15 stroke #000 sw=1 */
}
/* Активная (10/10 заполнено) — Copy game_full decode: Rectangle15 fill #F8F700
   stroke #E4E304 sw=4 (тот же приём, что .result-card .btn-primary). */
.game-check:not(:disabled) {
  border: 4px solid #E4E304;
}

/* Зона камеры (web, пустая, заполняется оператором в OBS поверх). ВАЖНО: рамка
   должна стоять в ОДНОМ месте/размере на ВСЕХ экранах (auth/меню/игра), иначе
   вебкамера в OBS не совпадает при переключении экранов («едет»). Поэтому
   привязываем её к ВЬЮПОРТУ теми же процентами, что .auth-cam-zone/.deco-cam-zone
   (Figma 1445/798, 430.49×242.21 @ 1920×1080), а не к высоте сайдбара — так
   координаты идентичны меню/авторизации. position:fixed = относительно вьюпорта;
   элемент внутри #game (display:none когда экран неактивен), поэтому рамка видна
   только на игровом экране, но в тех же координатах, что и на остальных. */
.game-cam-zone {
  position: fixed;
  left: 75.2604%;               /* 1445 / 1920 — как .deco-cam-zone/.auth-cam-zone */
  top: 73.8889%;                /* 798 / 1080 */
  width: 22.4213%;              /* 430.49 / 1920 */
  height: 22.4269%;             /* 242.21 / 1080 */
  box-sizing: border-box;
  border: 3px solid var(--yellow);
  border-radius: 20px;          /* Copy game_start decode: camera mask Rectangle r=20 (было 15) */
  background: rgba(10,10,10,.22);
  box-shadow: 0 0 0 2px rgba(10,10,10,.3), 0 10px 26px rgba(10,10,10,.18);
  z-index: 3;
}

/* ---------- Оверлеи ---------- */
.overlay {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(6, 8, 7, 0.78);
  backdrop-filter: blur(6px);
}
.overlay.active { display: flex; animation: fade-in .25s ease both; }

/* ---------- Проверка результата (Copy result_1/result_2/result_3/result_10) ----------
   Затемнённая доска сзади (#overlay уже тёмный) + центр-карточка 'Name' 740×H
   (decode: x=590,y=312..281,w=740,h=456/519/585 — H растёт с длиной инфо-текста,
   карточка вертикально/горизонтально ЦЕНТРИРОВАНА в кадре 1920×1080 при любом H):
   fill #323232, r11 (не 22), градиент-рамка 1.43 — тот же приём, что у .person/
   .confirm-card. Внутри сверху вниз (offsets от верха карточки, decode result_1):
   заголовок «Пара N из 10» (y+32, ONY Track UC жёлтый) → фото 64×64 r7 + бокс-имя
   253×64 r11 (y+93, ONY Track) → факт (y+180..182, ONY One, центр, max-width 420/740)
   → баннер-вердикт 666×81 r11 (y+235..239: wrong=#FF4492@.7/border #F61875,
   correct=#384B31/border #91FF55, decode result_2/3/10) → инфо/разбор серый
   #6A6A6A 16px (y+333, «Пара перейдёт в следующий раунд.» / разбор факта) →
   кнопки «Назад» 198×58 серая #4E4E4E + «Далее» 454×58 жёлтая, r11, gap≈14
   (198+14+454=666 — «Далее» = flex:1 1 auto добирает остаток). Боковой паддинг
   карточки ≈35/740 → баннер/инфо/кнопки естественно тянутся на всю content-box
   шириной (без отдельных width). */
.reveal-card, .result-card {
  box-shadow: var(--shadow), inset 0 1px 0 rgba(255,255,255,0.05);
  text-align: center;
  animation: pop-in .3s cubic-bezier(.2,.8,.25,1) both;
}
/* .result-card (Task 6, Copy result_score/final_score → #result — промежуточный
   счёт раунда и финальный счёт делят один и тот же DOM/CSS, app.js переключает
   контент по `finished`). decode: карточка "Name" fill #323232, r11 (не 22),
   градиент-рамка 1.43 — тот же приём, что у .reveal-card/.confirm-card.
   result_score: x=590,y=243,w=740,h=623. final_score: x=626,y=237,w=667,h=606
   (обе карточки центрированы в кадре 1920×1080). Ширина между экранами
   расходится (740 vs 667) — общий DOM берёт 740 (совпадает с .reveal-card,
   ширина авто по контенту всё равно резиновая). Внутри сверху вниз (offset от
   верха карточки, среднее по обоим экранам): иконка (Emoji_Biceps 153×153 /
   Trophy_BB 179×179) y+~23 → крупный счёт (INSTANCE box 164×145/163×145,
   центр) y+~16 gap → инфо-текст (реальный TEXT, ONY One/Regular/19,
   #6A6A6A, «Раунд N: верно X из Y…» / «Все пары сопоставлены!…») y+~28 gap
   → кнопка-1 (Rectangle 554×58 r11 fill #F8F700 border #E4E304 sw4) y+~28 gap
   → кнопка-2 (Name 554×58 r11 fill #4E4E4E) y+~12 gap. Боковой паддинг
   ≈93/740 (кнопки 554 внутри карточки 740). */
.result-card {
  width: min(740px, 92vw);
  box-sizing: border-box;
  border: 1.43px solid transparent;
  border-radius: 11px;
  background:
    linear-gradient(#323232, #323232) padding-box,
    linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,0)) border-box;
  padding: clamp(20px, 2.9vw, 55px) clamp(20px, 4.85vw, 93px);
  max-height: 92dvh;
  overflow-y: auto;
}
.reveal-card {
  width: min(740px, 92vw);
  box-sizing: border-box;
  border: 1.43px solid transparent;
  border-radius: 11px;
  background:
    linear-gradient(#323232, #323232) padding-box,
    linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,0)) border-box;
  padding: clamp(18px, 1.7vw, 32px) clamp(18px, 1.85vw, 35px);
  /* Защита от переполнения на маленьких экранах — карточка скроллится, не страница */
  max-height: 92dvh;
  overflow-y: auto;
}

/* Навигация в разборе: «Назад» (серая, фикс) + «Далее» (жёлтая, добирает остаток) */
.reveal-nav { display: flex; gap: clamp(8px, .75vw, 14px); margin-top: clamp(12px, 1.05vw, 20px); }
.reveal-nav .btn {
  height: clamp(38px, 3vw, 58px);
  padding: 0 clamp(10px, 1.2vw, 22px);
  border-radius: 11px;
  font-family: var(--body);
  font-weight: 400;
  font-size: clamp(14px, 1.2vw, 23px);
  text-transform: none;
  letter-spacing: 0;
}
.reveal-nav #revealNext { flex: 1 1 auto; }
.reveal-nav #revealPrev {
  flex: 0 0 clamp(120px, 10.3vw, 198px);
  background: #4E4E4E;
  color: #FFFFFF;
  border: none;
}
.reveal-nav .btn[hidden] { display: none; }

.reveal-step {
  font-family: "ONY Track UC", var(--disp);
  color: var(--yellow);
  font-size: clamp(24px, 2.9vw, 55px);
  font-weight: 900;
  line-height: 1;
  letter-spacing: 0;
  text-transform: uppercase;
  margin: 0 0 clamp(14px, 1.3vw, 25px);
}
.reveal-person {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(6px, .6vw, 11px);
  margin-bottom: clamp(12px, 1.2vw, 23px);
}
.reveal-avatar {
  flex: 0 0 auto;
  width: clamp(38px, 3.35vw, 64px);
  height: clamp(38px, 3.35vw, 64px);
  border-radius: clamp(4px, .4vw, 7px);
  background-size: cover; background-position: center;
  background-color: #3a3f3c;
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-weight: 700; font-size: 30px; color: var(--ink);
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,.18);
}
/* Бокс-имя: fill #323232, border 1.43 #3F3F3F, r11 (decode: Name 253×64) —
   ширина плавающая (min-width из декода), не фикс, чтобы длинные ники не резались. */
.reveal-person-name {
  flex: 0 1 auto;
  min-width: clamp(90px, 13.2vw, 253px);
  height: clamp(38px, 3.35vw, 64px);
  box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  padding: 0 clamp(10px, 1.2vw, 24px);
  background: #323232;
  border: 1.43px solid #3F3F3F;
  border-radius: 11px;
  font-family: var(--font-display);
  font-size: clamp(16px, 1.7vw, 32px); font-weight: 900;
  text-transform: uppercase; letter-spacing: -0.2px;
  color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.reveal-fact {
  margin: 0 auto clamp(12px, 1.2vw, 23px);
  max-width: clamp(240px, 22vw, 420px);
  font-family: var(--body);
  font-size: clamp(14px, 1.3vw, 24px);
  color: #fff;
  line-height: 1.35;
}
.reveal-verdict {
  display: flex; align-items: center; justify-content: center;
  min-height: clamp(46px, 4.25vw, 81px);
  box-sizing: border-box;
  font-family: var(--body);
  font-size: clamp(14px, 1.2vw, 23px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .3px;
  padding: clamp(8px, .8vw, 14px) clamp(12px, 1.5vw, 28px);
  border-radius: 11px;
  border: 3px solid transparent;
  color: #fff;
  margin-bottom: clamp(10px, 1.05vw, 20px);
}
/* Copy result_2/3/10: correct = fill #384B31, border #91FF55 (var(--lime)) */
.reveal-verdict.ok { background: #384B31; border-color: var(--lime); }
/* Copy result_1: wrong = fill #FF4492@0.7, border #F61875 (var(--fuchsia)) */
.reveal-verdict.no { background: rgba(255,68,146,0.7); border-color: var(--fuchsia); }
.reveal-answer {
  font-family: var(--body);
  font-size: clamp(12px, .9vw, 16px);
  color: #6A6A6A;
  line-height: 1.4;
  margin-bottom: clamp(4px, .4vw, 8px);
}
.reveal-answer .owner { color: var(--yellow); font-weight: 700; }
.reveal-answer .answer-skip { font-size: 1em; opacity: 1; }

/* Фото-разбор — адаптивное, скруглённое */
.answer-photo { margin-bottom: 12px; }
.answer-photo img {
  width: 100%;
  max-height: 260px;
  object-fit: cover;
  border-radius: 14px;
  border: 1px solid var(--line);
}

/* Видео-подтверждение — круглый «кружочек» в стиле BetBoom */
/* 16:9-видео в разборе (интервью со склейками): прямоугольник умеренного
   размера (не на весь экран), жёлтая рамка, клик — пауза/плей. */
.wide-video {
  position: relative;
  width: min(520px, 68vw);
  aspect-ratio: 16 / 9;
  margin: 4px auto 14px;
  border-radius: 11px;
  overflow: hidden;
  cursor: pointer;
  outline: none;
  border: 2px solid var(--yellow);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  background: #000;
}
.wide-video video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.wide-video-play {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 54px; height: 54px;
  display: grid;
  place-items: center;
  background: rgba(217, 217, 217, 0.30);
  color: #fff;
  border-radius: 50%;
  font-size: 20px;
  pointer-events: none;
}

.round-video {
  position: relative;
  width: min(285px, 62vw);   /* 1.5× от прежних 190px; описание под видео убрано,
                                освободившееся место занимает крупный кружок */
  height: min(285px, 62vw);
  margin: 4px auto 14px;
  border-radius: 50%;
  cursor: pointer;
  outline: none;
}
/* Клип-контейнер обрезает видео по кругу; кольцо остаётся снаружи */
.round-video-clip {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  overflow: hidden;
  background: #000;
}
.round-video-clip video {
  position: absolute;
  left: 50%;
  top: 50%;
  background: #000;
}
/* Жёлтое кольцо-обводка бренда */
.round-video-ring {
  position: absolute;
  inset: -6px;
  border-radius: 50%;
  padding: 6px;
  background: conic-gradient(from 0deg, var(--yellow), #fff28a, var(--yellow), #d9d800, var(--yellow));
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 6px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 6px), #000 calc(100% - 6px));
  animation: ring-spin 6s linear infinite;
  pointer-events: none;
}
@keyframes ring-spin { to { transform: rotate(360deg); } }
.round-video-mute {
  position: absolute;
  right: 8px; bottom: 8px;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  background: rgba(0,0,0,0.6);
  border: 1px solid rgba(255,255,255,0.25);
  border-radius: 50%;
  font-size: 16px;
  pointer-events: none;
}

/* Голосовое подтверждение — динамический эквалайзер (синусоида).
   Copy result_2 «Group 14»: Rectangle 665×60 r11 fill #14150F border #F8F700 sw3
   (полоска-«прогресс» + play — decode: Vector 9×12 треугольник + Vector 33×33
   круг), border 3px и r11 (не 16) — тот же приём, что у .reveal-verdict/.person. */
.eq-audio {
  display: flex;
  align-items: center;
  gap: clamp(8px, .73vw, 14px);
  margin-bottom: 14px;
  padding: clamp(8px, .73vw, 14px);
  min-height: clamp(40px, 3.1vw, 60px);
  box-sizing: border-box;
  background: #14150f;
  border: 3px solid var(--yellow);
  border-radius: 11px;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.03);
  overflow: hidden;   /* синусоида не вылезает за рамку */
}
.eq-play {
  flex: 0 0 auto;
  width: 46px; height: 46px;
  border-radius: 50%;
  border: none;
  background: var(--yellow);
  color: var(--ink);
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  display: grid; place-items: center;
  transition: transform .12s ease, box-shadow .2s ease;
  box-shadow: 0 4px 14px rgba(248,247,0,0.32);
}
.eq-play:hover { transform: scale(1.06); }
.eq-play:active { transform: scale(0.94); }
.eq-canvas {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 100%;
  height: 52px;
  width: 100%;
  display: block;
}
.eq-audio.playing { border-color: rgba(248,247,0,0.7); box-shadow: 0 0 0 1px rgba(248,247,0,0.4), 0 8px 24px rgba(248,247,0,0.15); }

/* Аудио с портретом: синусоида «прорисовывает» лицо на большом холсте */
.eq-audio.has-portrait {
  flex-direction: column;
  gap: 10px;
  padding: 14px;
}
.eq-audio.has-portrait .eq-canvas {
  width: min(300px, 74vw);
  height: min(300px, 74vw);
  aspect-ratio: 1 / 1;
}
.eq-audio.has-portrait .eq-play { order: 2; }

/* ---------- Модалка подтверждения подсказки (Copy game_help_2, попап 'Name' 743,406,434×269) ----------
   Карточка 434×269 по центру: #323232 r11 (decode_copy.py game_help_2: r=11.0, НЕ 15/20),
   градиент-рамка 1.43 (GRADIENT_LINEAR sw=1.43), backdrop-blur.
   Оверлей — #000 @50% (decode: "Виджет" fill #000000@0.5), см. #hintConfirm.overlay ниже. */
#hintConfirm.overlay {
  background: rgba(0,0,0,.5);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.confirm-card {
  width: min(434px, 92vw);           /* Figma 434 */
  box-sizing: border-box;
  /* градиент-рамка как у карточек: fill #323232 + штрих rgba(255,255,255,.10)→0 */
  border: 1.43px solid transparent;
  border-radius: 11px;               /* Copy game_help_2: r=11.0 (не 15/20) */
  background:
    linear-gradient(#323232, #323232) padding-box,
    linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,0)) border-box;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  padding: clamp(28px, 3vw, 56px) clamp(24px, 2.8vw, 54px);
  text-align: center;
  box-shadow: 0 24px 60px rgba(0,0,0,.5);
  animation: pop-in .3s cubic-bezier(.2,.8,.25,1) both;
}
.confirm-title {
  font-family: "ONY Track UC", var(--disp);   /* Figma: ONY Track UltraCondensed Black */
  font-size: clamp(30px, 2.74vw, 52.6px);   /* Figma 52.57 @1920 */
  font-weight: 900;
  line-height: .9;
  text-transform: uppercase;
  letter-spacing: 0;
  white-space: nowrap;               /* Figma: заголовок в одну строку */
  color: #FFFFFF;
  margin: 0 0 clamp(10px, .9vw, 16px);
}
.confirm-sub {
  font-family: var(--body);
  font-weight: 400;
  font-size: clamp(14px, 1.2vw, 23px);   /* Figma 23 */
  line-height: 1.2;
  color: #6A6A6A;                        /* Figma #6A6A6A */
  margin: 0 0 clamp(16px, 1.6vw, 28px);
}
/* Кнопки «Да»/«Нет» — фикс 158×49, r11, рядом (Copy game_help_2: обе кнопки-Frame r=11.0). */
.confirm-actions { display: flex; gap: clamp(6px, .5vw, 9px); justify-content: center; }
.confirm-actions .btn {
  flex: 0 0 auto;
  width: clamp(112px, 8.2vw, 158px);     /* Copy 158 */
  height: clamp(40px, 2.55vw, 49px);     /* Copy 49 */
  padding: 0;
  border-radius: 11px;                   /* Copy game_help_2: r=11.0 (не 10) */
  font-family: var(--body);
  font-weight: 400;
  font-size: clamp(18px, 1.5vw, 29px);   /* Copy 29 */
  text-transform: none;
  letter-spacing: 0;
}
/* Copy game_help_2: кнопка «Да» — fill #F61875 (розовый), текст #FFFFFF (не жёлтый/чёрный). */
.confirm-actions #hintYes { background: #F61875; color: #FFFFFF; box-shadow: none; }
.confirm-actions #hintNo  { background: #4E4E4E; color: #FFFFFF; border: none; }

/* Модалка показа подсказки (#hintReveal) — тот же стиль карточки .confirm-card
   (r11 уже унаследован сверху). В Copy game_help_3 отдельного попапа-карточки
   с текстом подсказки не обнаружено (decode: карточка 743,406,434×269 из
   game_help_2 в game_help_3 отсутствует; экран показывает лишь притушенный
   счётчик подсказок и подсвеченные строки) — переиспользуем стиль
   confirm-card по аналогии, жёлтый текст подсказки (#F8F700) оставлен как
   единственный доступный сигнал акцента для «показа» состояния. */
#hintReveal.overlay { background: rgba(0,0,0,.5); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }

/* Модалка подтверждения перезагрузки (#reloadConfirm) — тот же confirm-card,
   что и #hintConfirm. Reload-guard может сработать, пока уже открыт другой
   оверлей того же базового z-index:50 (пошаговая проверка #reveal или
   промежуточный/финальный результат #result) — оба стоят ПОЗЖЕ #reloadConfirm
   в DOM (index.php/index.html/redesign/preview.html), поэтому при равном
   z-index визуально перекрыли бы модалку, хоть класс .active и выставлен
   (клики программно проходили бы, но пользователь предупреждение не видел
   бы). Явный z-index выше базового гарантирует, что #reloadConfirm всегда
   поверх любого другого оверлея, независимо от DOM-порядка. */
#reloadConfirm.overlay {
  z-index: 60;
  background: rgba(0,0,0,.5);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.hint-reveal-text {
  font-family: var(--body);
  font-weight: 400;
  font-size: clamp(16px, 1.5vw, 26px);
  line-height: 1.25;
  color: #F8F700;                    /* жёлтая подсказка (как clue в game_help_3) */
  margin: 0 0 clamp(16px, 1.6vw, 28px);
}
.confirm-actions #hintRevealClose {
  width: auto;
  min-width: clamp(112px, 8.2vw, 158px);
  padding: 0 clamp(16px, 1.6vw, 28px);
  background: #4E4E4E;
  color: #FFFFFF;
  border: none;
}

[hidden] { display: none !important; }

/* ---------- Результат (Task 6: Copy result_score/final_score) ----------
   Иконка 153×153(round)/179×179(final) в кадре 1920×1080 → clamp по vw,
   центр карточки. */
.result-emoji {
  font-size: clamp(48px, 7.8vw, 150px);
  line-height: 1;
  margin-bottom: clamp(8px, 1vw, 20px);
  filter: drop-shadow(0 8px 18px rgba(0,0,0,0.45));
}
/* Крупный счёт — INSTANCE-бокс ~164×145 (decode), ONY Track Black, центр. */
.result-score {
  font-family: var(--font-display);
  font-size: clamp(40px, 5.4vw, 104px);
  font-weight: 900;
  letter-spacing: -1px;
  line-height: 1;
  margin: 0 0 clamp(10px, 1.5vw, 28px);
  color: var(--yellow);
  text-shadow: 0 4px 30px rgba(248, 196, 0, 0.3);
}
/* Инфо-текст — реальный TEXT-узел decode: ONY One/Regular/19, #6A6A6A. */
.result-text {
  font-family: var(--body);
  font-weight: 400;
  font-size: clamp(13px, 1.1vw, 19px);
  color: #6A6A6A;
  margin: 0 0 clamp(16px, 1.55vw, 28px);
  letter-spacing: .3px;
  white-space: pre-line;
  line-height: 1.5;
}
/* Кнопки: primary (decode Rectangle 554×58 r11 fill #F8F700 border 4px
   #E4E304) и secondary (decode Name 554×58 r11 fill #4E4E4E, не .btn-ghost
   транслюсент — тот же приём, что у #revealPrev в .reveal-nav). */
.result-card .btn-block {
  display: flex;
  align-items: center;
  justify-content: center;
  height: clamp(40px, 3vw, 58px);
  border-radius: 11px;
  padding: 0 clamp(14px, 1.6vw, 28px);
  font-size: clamp(14px, 1.2vw, 19px);
  margin-top: clamp(8px, .75vw, 14px);
  box-sizing: border-box;
}
.result-card .btn-primary {
  border: 4px solid #E4E304;
}
.result-card #resultToMenu {
  background: #4E4E4E;
  color: #FFFFFF;
  border: none;
}
.result-card #resultToMenu:hover { background: #5a5a5a; }

/* Резиновая вёрстка: старый @media(max-width:720px) для .board/.chip/
   .game-footer не нужен — .game-screen/.auth-screen/.menu-screen сами
   flex/grid и реагируют на ширину/высоту окна через clamp()/fr, без
   отдельных брейкпоинтов (см. секции выше и docs/superpowers/design/
   fluid-conversion-spec.md). */

/* ---------- Лайтбокс аватара (клик по фото на доске, Copy click_photo) ----------
   Copy: полноэкранный "Виджет" fill #000000@0.5 (перебивает базовый .overlay
   0.78 — тут ровно decode-значение); фото — ROUNDED_RECTANGLE ~550×559 (почти
   квадрат), r=37 (37/1920=1.93vw), stroke #F8F700 sw=2 (сплошной, не 0.5-alpha,
   как было раньше); крестик-закрытие — Ellipse 58×58 fill #D9D9D9@0.3 + X
   VECTOR #949494, у правого верхнего угла фото (не угол экрана). */
.avatar-zoom.overlay {
  background: rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.avatar-zoom { flex-direction: column; gap: 14px; cursor: zoom-out; }
/* .avatar-zoom-frame — обёртка фото+крестика (см. app.js openAvatarZoom):
   position:relative тут, а не на .avatar-zoom-inner, потому что innerHTML
   .avatar-zoom-inner целиком перезаписывается на img/большие инициалы при
   каждом открытии — крестик внутри него не пережил бы перезапись. */
.avatar-zoom-frame { position: relative; display: flex; }
.avatar-zoom-inner { display: flex; }
.avatar-zoom-inner img {
  display: block;
  width: auto; height: auto;
  max-width: min(90vw, 560px);      /* Copy: фото ≈550/1920 @1920 */
  max-height: 78vh;
  border-radius: clamp(16px, 1.93vw, 37px);  /* Copy: r=37 @1920 */
  border: 2px solid var(--yellow);           /* Copy: stroke #F8F700 sw=2, сплошной */
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.65);
}
.avatar-zoom-inner .big-initials {
  width: min(72vw, 300px); height: min(72vw, 300px);
  border-radius: 28px;
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-weight: 700; color: var(--ink);
  font-size: clamp(64px, 22vw, 150px);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.6);
}
.avatar-zoom-name {
  font-family: var(--font-display);
  font-weight: 700; font-size: 22px;
  text-transform: uppercase; letter-spacing: .3px;
  color: var(--text);
}
/* Copy: кружок 58×58 у правого верхнего угла фото, не угла экрана.
   Инсет ПОЛОЖИТЕЛЬНЫЙ (внутрь фото), не отрицательный — иначе на низких
   viewport (photo близко к верхнему краю окна) кружок обрезается за пределами
   экрана (см. .overlay padding:20px, фото центрируется по высоте). */
.avatar-zoom-close {
  position: absolute;
  top: clamp(6px, .8vw, 16px);
  right: clamp(6px, .8vw, 16px);
  width: clamp(34px, 3vw, 58px); height: clamp(34px, 3vw, 58px);
  border-radius: 50%;
  display: grid; place-items: center;
  background: rgba(217, 217, 217, 0.3);   /* Copy: #D9D9D9 @0.3 */
  border: none;
  font-size: clamp(14px, 1.2vw, 20px);
  color: #949494;                          /* Copy: X vector #949494 */
}

/* Клон, который тащим пальцем/мышью */
.drag-ghost {
  position: fixed;
  z-index: 1000;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--yellow);
  border: 1px solid rgba(0,0,0,0.15);
  border-radius: 12px;
  padding: 10px 14px;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--ink);
  text-align: center;
  box-shadow: 0 22px 44px rgba(0,0,0,0.6), var(--glow-y);
  opacity: .98;
  transform: rotate(-1.5deg);
}

/* ============================================================
   Task 3: Экран авторизации (`.auth-*`) + общий декор-шелл (`.deco-*`),
   переиспользуемый в Task 4 (`.menu-*`, см. секцию «Task 4: Экран меню»
   ниже — блок/бейдж/камера/тикет/BETBOOM у auth и menu идентичны, поэтому
   каждое правило декора объявлено как `.auth-X, .deco-X { ... }`: auth
   продолжает работать через `.auth-*` без изменений разметки, а menu
   подключает те же стили через параллельный класс `.deco-*`).
   Разметка: includes/pin_page.php (боевая, через PHP-гейт) +
   redesign/preview-auth.html (статическое зеркало для само-проверки
   без PHP). Обе используют один и тот же `.auth-*` CSS ниже.

   Раскладка снята попиксельно с docs/superpowers/snapshots/figma/01-password.png
   (1920×1080): тикет-лого NIX GAMES по центру сверху → тёмная PIN-панель
   (620×261, 6 ячеек 72×104, активная — жёлтая рамка) → «Введи 6-значный
   ПИН» → лого BETBOOM. Фон — светло-серый + жёлтый органический блоб.

   АССЕТЫ (assets/ui/*): часть уже экспортирована заказчиком
   (blob-yellow.svg, badge-banner.svg, icon-bolt.svg — последний для
   игрового экрана, здесь не используется), часть ещё нет
   (obj-explosion.png, obj-keyboard.png, cursor-hand.png,
   logo-nix-ticket.svg, logo-betboom.svg). Единый паттерн для ВСЕГО
   декора: `<img src="/assets/ui/...">` c `onerror`, который либо просто
   прячет картинку (для 3D-рендеров — под ними декор-стаб-фон), либо
   открывает CSS/текстовый стаб-фолбэк того же элемента (для бейджа/
   логотипов — стаб лежит "под" img и просто выглядывает при 404).
   Маркеры точек подмены — "ЗАМЕНИТЬ:". 404 на ещё не отданные
   assets/ui/* в консоли — ожидаемо и не является ошибкой вёрстки.
   ============================================================ */

.auth-screen, .menu-screen {
  position: relative;
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--grey-bg);
  font-family: var(--body);
  color: var(--ink);
}

/* Фон: жёлтый органический блоб — assets/ui/blob-yellow.svg (уже отдан
   заказчиком, ЗАМЕНЫ не требует). SVG на всю область стейджа (viewBox
   1920×1080, органический контур с прозрачным "вырезом" — сквозь него
   должен быть виден светло-серый .auth-screen (--grey-bg) слева/сверху-
   слева, поэтому .auth-blob-wrap НЕ должен иметь свой сплошной фон —
   иначе прозрачные области SVG будут "затыкаться" жёлтым, а не серым.
   Сплошная жёлтая подложка навешивается ТОЛЬКО как onerror-фолбэк,
   если файл вдруг недоступен (см. .auth-blob-wrap.no-asset). */
.auth-blob-wrap, .deco-blob-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: 1;
}
.auth-blob-wrap.no-asset, .deco-blob-wrap.no-asset { background: var(--yellow); }
.deco-blob {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Блоб (ye_element): в Figma 1470×1613 @ left 244 / top −267 (кадр 1920×1080),
   экспорт 1470×1080 — видимая часть начинается с left 244 / top 0.
   Резиновая версия: позиция/размер в % от вьюпорта (244/1920, 1470/1920 —
   тот же кадр 1920×1080, что и раньше, просто в относительных единицах),
   object-fit:fill сохраняет заливку без пустот при любых пропорциях окна. */
.auth-blob {
  display: block;
  position: absolute;
  left: 12.7083%;
  top: 0;
  width: 76.5625%;
  height: 100%;
  object-fit: fill;
}

/* Реальные лого (nix_games.png / logo_bb.png) со своими скобками уже отданы —
   прячем прежние CSS/текст-стабы, чтобы не задваивались поверх картинок. */
.auth-ticket-text, .deco-ticket-text,
.auth-ticket-notch, .deco-ticket-notch,
.auth-betboom-mark, .deco-betboom-mark,
.auth-betboom-text, .deco-betboom-text { display: none !important; }
.auth-ticket::before, .auth-ticket::after,
.deco-ticket::before, .deco-ticket::after { display: none !important; }
/* Контейнеры лого — чисто под натуральный размер реального PNG (сам PNG
   содержит тикет/скобки/BB-монограмму), без прежнего чёрного фона/паддинга. */
.auth-ticket, .deco-ticket {
  background: none !important;
  padding: 0 !important;
  width: 488px;
  height: 138px;
}
.auth-betboom, .deco-betboom { width: 380px; height: 90px; display: block; }
.auth-ticket-img, .deco-ticket-img,
.auth-betboom-img, .deco-betboom-img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: contain; display: block; opacity: 1 !important;
}

/* ---------- Декор-слоты (рендеры, ассетов пока нет) ----------
   Общие для auth (.auth-*) и menu (.deco-*, Task 4) — оба экрана
   используют один и тот же декор-шелл (см. redesign-spec.md «Menu»:
   «Тот же фон/декор/зоны, что auth»). */
.auth-decor-slot, .deco-decor-slot {
  position: absolute;
  z-index: 2;
  pointer-events: none;
}
.auth-decor-slot img, .deco-decor-slot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
/* Фолбэк, если PNG ещё не завезли: полупрозрачный цветной блок вместо
   пустоты, чтобы раскладка не "разваливалась" на пустое место. */
.auth-decor-slot.no-asset, .deco-decor-slot.no-asset { border-radius: 24px; opacity: .5; }

/* Клинок/взрыв (blink) — .auth-explosion (auth) и .deco-explosion (menu)
   используют один и тот же кадр (подтверждено заказчиком, декор menu
   идентичен auth) — объединены в общий селектор. Позиция/размер в %
   от вьюпорта (px/1920, px/1080 из исходного Figma-кадра 1920×1080).
   Сверено с новой Copy (decode_copy.py password/menu): emoji_boom
   895×895 @ left −266 / top 169 (кадр 1920×1080), без поворота —
   идентично на обоих экранах (подтверждено decode). Значения ниже
   исправлены под этот decode (были смещены/меньше в пред. версии). */
.auth-explosion, .deco-explosion {
  left: -13.8542%; top: 15.6481%;
  width: 46.6146%; height: 82.8704%;
}
.auth-explosion.no-asset, .deco-explosion.no-asset {
  background:
    radial-gradient(circle at 38% 40%, var(--fuchsia), transparent 58%),
    radial-gradient(circle at 62% 58%, #ffb020, transparent 55%);
}

/* Клавиатура (keyboard): Figma 890.14×890.14 @ left 1009 / top −751, rotation 30°
   (кадр 1920×1080) — Figma поворачивает вокруг центра; знак угла в CSS
   обратный (Figma +30 = CSS −30). .auth-keyboard/.deco-keyboard идентичны. */
.auth-keyboard, .deco-keyboard {
  /* Figma X/Y для повёрнутого слоя = top-left его AABB (1009,−751).
     Центр = AABB-центр (1617,−143) → неповёрнутый top-left (1172,−588),
     переведён в % от вьюпорта 1920×1080. */
  left: 61.0417%; top: -54.4444%;
  width: 46.3615%; height: 82.4204%;
  transform: rotate(-30deg);
  transform-origin: center;
}
.auth-keyboard.no-asset, .deco-keyboard.no-asset {
  background: repeating-linear-gradient(45deg, #fff, #fff 14px, var(--yellow) 14px, var(--yellow) 28px);
  opacity: .3;
  border: 2px dashed rgba(10,10,10,.2);
}

/* Рука-курсор (emoji_finger): Figma 464.26² @ (1338,309) rot 17.42°
   (кадр 1920×1080). AABB→центр (1629,600), неповёрнутый top-left
   (1397,368) → % от вьюпорта; CSS rotate(-17.42deg). */
.auth-cursor, .deco-cursor {
  left: 72.7604%; top: 34.0741%;
  width: 24.1802%; height: 42.9870%;
  transform: rotate(-17.42deg);
  transform-origin: center;
}
.auth-cursor.no-asset, .deco-cursor.no-asset {
  background: var(--fuchsia);
  opacity: .8;
  clip-path: polygon(70% 0%, 100% 55%, 62% 62%, 40% 100%, 22% 88%, 42% 58%, 0% 46%);
}

/* Бейдж «БАННЕР В ОПИСАНИИ» удалён отовсюду (меню/авторизация/сайдбар) по
   просьбе заказчика — Никс знает всех стримеров лично, плейсхолдер не нужен. */

/* ---------- Зона камеры (ПУСТАЯ — заполняется оператором в OBS
   поверх этого места; никакого текста/иконки внутри быть не должно) ---------- */
.auth-cam-zone, .deco-cam-zone {
  position: absolute;
  z-index: 3;
  border: 2px solid var(--yellow);
  border-radius: 18px;
  background: rgba(10, 10, 10, .22);
  box-shadow: 0 0 0 2px rgba(10, 10, 10, .3), 0 10px 26px rgba(10, 10, 10, .18);
}
/* Окно камеры (web) под OBS: Figma 430.49×242.21 @ left 1445 / top 798
   (кадр 1920×1080), пропорция ≈16:9 — позиция/размер в % от вьюпорта.
   .auth-cam-zone (auth) и .deco-cam-zone (камера на экране меню)
   идентичны (подтверждено заказчиком). */
.auth-cam-zone, .deco-cam-zone {
  left: 75.2604%;
  top: 73.8889%;
  width: 22.4213%;
  height: 22.4269%;
  border: 3px solid var(--yellow);
  border-radius: 20px;
}

/* ---------- Тикет-лого NIX GAMES ----------
   ЗАМЕНИТЬ: assets/ui/logo-nix-ticket.svg заказчик ещё не отдал.
   Паттерн подмены: <img> лежит абсолютным слоем ПОВЕРХ CSS-стаба
   (чёрный тикет + жёлтый текст + скобки-орнаменты + перфорация-нотчи);
   пока файла нет — onerror прячет <img>, и стаб виден как есть. Когда
   заказчик отдаст SVG — он просто ляжет в assets/ui/, <img> перестанет
   404-ить и перекроет стаб без правки разметки/CSS. */
/* Тикет-лого NIX GAMES: Figma 487.65×137.65 @ left 716 / top 100
   (кадр 1920×1080) — позиция/размер в % от вьюпорта. Реальный PNG уже
   содержит тикет+скобки+перфорацию, поэтому фон/паддинг стаба сброшены
   (background:none/padding:0) — контейнер только под натуральный размер
   картинки. .auth-ticket/.deco-ticket идентичны. */
.auth-ticket, .deco-ticket {
  position: absolute;
  left: 37.2917%;
  top: 9.2593%;
  width: 25.3984%;
  height: 12.7454%;
  z-index: 4;
  background: none;
  border-radius: 18px;
  padding: 0;
}
.auth-ticket-img, .deco-ticket-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  z-index: 5;
}
/* Скобки-орнаменты (стилизованные "⧙ ⧘" по бокам тикета, как в эталоне).
   ВАЖНО: заливка чёрная (var(--ink)), а не жёлтая обводка — тикет сидит
   на жёлтом блобе, и жёлтый-на-жёлтом был бы невидим. В эталоне скобки —
   это чёрные скруглённые "уши" тикета того же цвета, что и его тело. */
.auth-ticket::before, .deco-ticket::before,
.auth-ticket::after, .deco-ticket::after {
  content: '';
  position: absolute;
  top: 8%;
  width: 20px;
  height: 84%;
  background: var(--ink);
  border-radius: 999px;
}
.auth-ticket::before, .deco-ticket::before { left: -16px; }
.auth-ticket::after, .deco-ticket::after { right: -16px; }
/* Перфорация-нотчи (маленькие "укусы" сверху/снизу тикета у скобок) */
.auth-ticket-notch, .deco-ticket-notch {
  position: absolute;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--yellow);
  z-index: 2;
}
.auth-ticket-notch--tl, .deco-ticket-notch--tl { left: 30px; top: -9px; }
.auth-ticket-notch--tr, .deco-ticket-notch--tr { right: 30px; top: -9px; }
.auth-ticket-notch--bl, .deco-ticket-notch--bl { left: 30px; bottom: -9px; }
.auth-ticket-notch--br, .deco-ticket-notch--br { right: 30px; bottom: -9px; }
.auth-ticket-text, .deco-ticket-text {
  position: relative;
  z-index: 0;
  display: block;
  font-family: var(--disp);
  font-weight: 700;
  font-size: clamp(24px, 2.7vw, 52px);
  line-height: 1;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--yellow);
  white-space: nowrap;
}

/* ---------- Подзаголовок (эхо $pin_title) ----------
   В эталоне 01-password.png такого текста нет — визуально скрыт через
   .sr-only (см. ниже), но echo $title в разметке сохранён (не убирать
   из PHP/preview — это требование брифа, только визуальное скрытие). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------- PIN-панель ----------
   Figma 619×262.83 @ left 650 / top 433 (кадр 1920×1080) — позиция/размер
   в % от вьюпорта; внутренние отступы и PIN-ячейки — vw/vh-clamp (та же
   система координат 1920×1080, просто в относительных единицах, чтобы
   панель и её содержимое масштабировались синхронно). */
.auth-panel {
  position: absolute;
  left: 33.8542%;
  top: 40.0926%;
  width: 32.2396%;
  height: 24.3361%;
  z-index: 4;
  /* Rectangle 3 (Group 1, фон панели) fill #222524 — сверено с
     decode_copy.py password (Fix round 1). --panel (#1A1C1B) чуть темнее
     эталона, используем готовый токен --panel-2 (#222524), под этот
     оттенок и заведённый ранее, но нигде не подключённый. */
  background: var(--panel-2);
  /* Rectangle 3 (Group 1) r≈14.4626 @ панель 619×262.8 (кадр 1920×1080) —
     сверено с decode_copy.py password: 14.4626/1920*100 = 0.7532vw
     (раньше был захардкожен 28px — вдвое больше эталона). Не путать с
     радиусом 11 у строк людей/фактов игрового экрана — тот из другого
     декода. */
  border-radius: clamp(10px, .7532vw, 16px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .35);
  padding: clamp(22px, 4.44vh, 48px) clamp(24px, 2.97vw, 57px) 0;
  box-sizing: border-box;
  text-align: center;
}
.auth-pin {
  display: flex;
  /* Шаг между PIN-ячейками в decode ≈86.9px @1920 (x: 706.9→793.8→880.6…),
     ширина ячейки 73px → зазор ≈13.9px = 0.7240vw (был .9vw/12px). */
  gap: clamp(6px, .7240vw, 14px);
  justify-content: center;
}
.auth-pin input {
  /* Rectangle 4/5/7/8/9 (Group 1): 73.0×104.1 @1920×1080 —
     3.8021vw × 9.6389vh (был 3.75vw/72px чуть уже эталона). */
  width: clamp(38px, 3.8021vw, 73px);
  height: clamp(52px, 9.6389vh, 104px);
  text-align: center;
  font-family: var(--disp);
  font-size: clamp(18px, 1.77vw, 34px);
  font-weight: 700;
  color: var(--text);
  /* Rectangle 4/5/7/8/9 (неактивные PIN-ячейки) fill #040404 — сверено с
     decode_copy.py password (Fix round 1); был #0A0A0A (--ink), чуть
     светлее эталона. */
  background: #040404;
  border: 3px solid transparent;
  /* r≈10.8470 @1920 (эта же ячейка "12" в decode) = 0.5649vw
     (раньше был захардкожен 16px — заметно крупнее эталона). */
  border-radius: clamp(7px, .5649vw, 11px);
  outline: none;
  caret-color: var(--yellow);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.auth-pin input:focus {
  border-color: var(--yellow);
  box-shadow: 0 0 0 4px rgba(248, 247, 0, .18);
}
.auth-pin.err input {
  border-color: var(--fuchsia);
  animation: auth-shake .32s;
}
@keyframes auth-shake { 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }

.auth-msg {
  min-height: 18px;
  font-size: clamp(11px, .68vw, 13px);
  font-weight: 600;
  color: var(--fuchsia);
  margin: 10px 0 0;
}
.auth-hint {
  margin-top: 14px;
  font-size: clamp(12px, .83vw, 16px);
  color: var(--muted);
}

/* ---------- Лого BETBOOM ----------
   ЗАМЕНИТЬ: assets/ui/logo-betboom.svg заказчик ещё не отдал. Тот же
   паттерн, что у тикета: <img> абсолютным слоем поверх CSS-стаба
   (монограмма "B" + текст), onerror прячет <img>, стаб виден под ним;
   когда SVG появится — просто перекроет стаб. */
/* Лого BETBOOM: Figma 379.71×89.81 @ left 769 / top 891 (кадр 1920×1080) —
   позиция/размер в % от вьюпорта. .auth-betboom/.deco-betboom идентичны. */
.auth-betboom, .deco-betboom {
  position: absolute;
  left: 40.0521%;
  top: 82.5%;
  width: 19.7766%;
  height: 8.3157%;
  z-index: 4;
  display: flex;
  align-items: center;
  gap: 14px;
}
.auth-betboom-img, .deco-betboom-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  z-index: 5;
}
.auth-betboom-mark, .deco-betboom-mark {
  width: clamp(26px, 2.29vw, 44px);
  height: clamp(26px, 2.29vw, 44px);
  border-radius: 10px;
  background: var(--ink);
  display: grid;
  place-items: center;
  font-family: var(--disp);
  font-weight: 700;
  font-size: clamp(14px, 1.15vw, 22px);
  color: var(--yellow);
}
.auth-betboom-text, .deco-betboom-text {
  font-family: var(--disp);
  font-weight: 700;
  font-size: clamp(22px, 2.08vw, 40px);
  letter-spacing: .5px;
  text-transform: uppercase;
  color: var(--ink);
  white-space: nowrap;
}

/* ============================================================
   Task 4: Экран меню (`.menu-*`).
   Разметка: index.php / index.html / redesign/preview.html — все три
   держат идентичный #menu (см. комментарий в каждом файле), генерация
   кнопок — app.js buildMenu() → .game-card внутри #gameList.
   Декор (блоб/взрыв/клавиатура/курсор/бейдж/камера/тикет/BETBOOM) —
   переиспользован из Task 3 через общие классы `.deco-*` (см. блок выше),
   разметка #menu просто использует .deco-* вместо .auth-* — сам CSS
   декора при этом объявлен ровно один раз.

   Раскладка снята с docs/superpowers/snapshots/figma/n9-3744.png
   (1920×1080, hover-состояние первой кнопки). Тикет (top:95) и лого
   BETBOOM (top:891) сидят на тех же координатах, что и на auth —
   оба экрана используют одну сетку.

   Сверено с новой Copy (decode_copy.py menu_select, DEPTH=8, полное
   дерево узлов): .game-list/тикет/BETBOOM-лого уже совпадают 1:1
   (позиции/размеры), правки Fix round 2 — .game-card (фон/радиус/
   толщина обводки ховера) и .menu-title (см. ниже).
   ============================================================ */
/* Заголовок «Выбери игру»: в декоде menu_select (и menu) НЕТ такого
   текстового узла — полное дерево (DEPTH=8) и поиск по всему файлу
   ("Выбери"/"выбери") ничего не находят на этом экране. Новая Copy
   убрала заголовок из макета меню (эталон — только тикет-лого + 3
   кнопки + BETBOOM-лого). Разметку (h1, a11y-заголовок) не убираем —
   только визуально скрываем (тот же приём, что .auth-hint/.sr-only на
   экране авторизации: echo-текст остаётся в DOM для скринридеров/SEO,
   но не должен быть виден и не должен занимать место в раскладке). */
.menu-title {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  margin: 0;
}

/* Контейнер кнопок игр (id="gameList" из app.js/PHP-разметки).
   selection_button: Figma 528.7×114.44 @ top 430, gap ≈12.5 (кадр
   1920×1080) — ширина списка и вертикальный зазор в vw/vh-clamp. */
.game-list {
  position: absolute;
  left: 50%;
  top: 39.8148%;
  transform: translateX(-50%);
  z-index: 4;
  width: clamp(320px, 27.54vw, 620px);
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.16vh, 18px);
}

/* Кнопка игры — тёмная «пилюля»: название по центру, шеврон "›" справа.
   Рендерится в app.js buildMenu(); onclick → startGame(game) не трогали.
   Сверено с decode_copy.py menu_select ("Name" FRAME, Group 2/3/4):
   528.7×114.4 @ top 430/557/683.2, gap≈12 (кадр 1920×1080) — уже верно
   в .game-list выше. Фикс round 2: fill #1D1E1F (был #000000), radius
   22.8 (было захардкожено 25px — НЕ радиус 11, тот только у строк
   людей/фактов игрового экрана), ховер-обводка 3px (было 2px, decode:
   Group 2 stroke #FFFFFF sw:3.0 — единственная кнопка со stroke в
   декоде — это иллюстрация hover/focus-состояния, не отдельная кнопка). */
.game-card {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  width: 100%;
  height: clamp(64px, 10.6vh, 114px);
  padding: 0 clamp(18px, 1.78vw, 34px);
  box-sizing: border-box;
  background: #1D1E1F;
  border: 3px solid transparent;
  border-radius: clamp(13px, 2.1111vh, 23px);
  cursor: pointer;
  color: #fff;
  font-family: inherit;
  text-align: left;
  box-shadow: 0 16px 34px rgba(0, 0, 0, .35);
  transition: border-color .15s ease, color .15s ease, transform .15s ease, box-shadow .15s ease;
  animation: rise-in .45s ease both;
}
.game-card:nth-child(2) { animation-delay: .06s; }
.game-card:nth-child(3) { animation-delay: .12s; }

.game-card-text {
  position: relative;
  min-width: 0;
  flex: 0 1 auto;
  font-family: var(--body);   /* ONY One (кнопки набраны ONY One Regular) */
  font-weight: 400;
  font-size: clamp(16px, 1.77vw, 34px);
  letter-spacing: .3px;
  color: inherit;
  overflow: visible;
  text-align: center;
  white-space: nowrap;
}

.game-card-chevron {
  position: absolute;
  right: clamp(14px, 1.77vw, 34px);
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--disp);
  font-size: clamp(20px, 2.19vw, 42px);
  font-weight: 700;
  color: #fff;
  transition: color .15s ease, transform .15s ease;
}

/* Ховер (эталон n9-3744.png, первая кнопка): жёлтый текст + белая
   обводка + cursor:pointer (курсор-рука — статичный декор рядом со
   списком, см. .deco-cursor, а не системный курсор). */
.game-card:hover,
.game-card:focus-visible {
  border-color: #fff;
  color: var(--yellow);
  transform: translateY(-2px);
  box-shadow: 0 20px 44px rgba(0, 0, 0, .45);
  outline: none;
}
.game-card:hover .game-card-chevron,
.game-card:focus-visible .game-card-chevron {
  transform: translateY(-50%) translateX(4px);
  color: var(--yellow);
}

/* taskblock-04: залоченная карточка (Игра 2/3 до прохождения Игры 1 —
   progress.unlocked из api/progress.php, см. app.js buildMenu()). Приглушаем
   и убираем hover-эффекты, шеврон заменён на 🔒 (.game-card-lock). */
.game-card.locked {
  opacity: .55;
  cursor: not-allowed;
}
.game-card.locked:hover,
.game-card.locked:focus-visible {
  border-color: transparent;
  color: #fff;
  transform: none;
  box-shadow: 0 16px 34px rgba(0, 0, 0, .35);
}
.game-card-lock {
  font-size: clamp(16px, 1.5vw, 30px);
}
.game-card.locked:hover .game-card-lock,
.game-card.locked:focus-visible .game-card-lock {
  transform: translateY(-50%);
  color: #fff;
}

/* «Coming Soon» — игра ещё не готова (game.comingSoon в данных): карточка
   приглушена, некликабельна, вместо шеврона — жёлтый бейдж «Coming Soon». */
.game-card.coming-soon {
  opacity: .6;
  cursor: not-allowed;
  justify-content: space-between;   /* заголовок слева, бейдж справа — без наложения */
}
.game-card.coming-soon:hover,
.game-card.coming-soon:focus-visible {
  border-color: transparent;
  color: #fff;
  transform: none;
  box-shadow: 0 16px 34px rgba(0, 0, 0, .35);
}
/* На coming-soon заголовок прижат влево и чуть уменьшен, чтобы «Выпуск N»
   помещался целиком рядом с бейджем (без многоточия). Ellipsis — страховка. */
.game-card.coming-soon .game-card-text {
  text-align: left;
  font-size: clamp(13px, 1.45vw, 27px);
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Бейдж «Coming Soon» — компактный жёлтый пилл В ПОТОКЕ (flex-ребёнок), справа. */
.game-card-badge {
  flex: 0 0 auto;
  font-family: var(--body);
  font-weight: 700;
  font-size: clamp(10px, .9vw, 15px);
  letter-spacing: .3px;
  color: #0d0d0d;
  background: var(--yellow);
  padding: clamp(3px, .4vh, 6px) clamp(8px, .8vw, 14px);
  border-radius: 999px;
  white-space: nowrap;
  line-height: 1;
}

/* game header: реальный logo-betboom.png содержит BB+вордмарк — прячем текст-стаб. */
.game-logo-text, .game-logo-mark { display: none !important; }

/* ============================================================
   Экран правил (#rules) — интерстишл после PIN, до меню (Task 3,
   taskblock-03-rules-interstitial). Тёмная тема BetBoom: фон — общий
   градиент #app (см. выше), карточка — тёмная (стиль как у
   .confirm-card/.reveal-card), заголовок жёлтый, чекбокс крупный,
   предупреждение фуксия. Показывается один раз за сессию — логика
   в app.js (sessionStorage "bb_rules_ok"). ============================================================ */
#rules.active {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 24px;
  box-sizing: border-box;
}

.rules-card {
  width: 100%;
  max-width: min(680px, 88vw);
  margin: auto;
  box-sizing: border-box;
  border: 1.43px solid transparent;
  border-radius: var(--r-lg);
  background:
    linear-gradient(180deg, #262927, #1c1e1d) padding-box,
    linear-gradient(180deg, rgba(255, 255, 255, .10), rgba(255, 255, 255, 0)) border-box;
  padding: clamp(28px, 4vw, 48px) clamp(24px, 4vw, 44px);
  box-shadow: 0 24px 60px rgba(0, 0, 0, .5);
  color: var(--text);
  animation: pop-in .35s cubic-bezier(.2, .8, .25, 1) both;
}

.rules-title {
  font-family: var(--disp);
  color: var(--yellow);
  font-size: clamp(28px, 3.2vw, 46px);
  font-weight: 900;
  text-transform: uppercase;
  line-height: 1;
  margin: 0 0 10px;
}

.rules-sub {
  font-family: var(--body);
  color: var(--muted);
  font-size: clamp(14px, 1.3vw, 18px);
  margin: 0 0 22px;
}

.rules-list {
  margin: 0 0 26px;
  padding-left: 1.25em;
  font-family: var(--body);
  font-size: clamp(15px, 1.3vw, 18px);
  line-height: 1.45;
  color: var(--text);
}
.rules-list li { margin: .5em 0; }
.rules-list b { color: var(--yellow); }

.rules-check {
  display: flex;
  gap: 10px;
  align-items: center;
  cursor: pointer;
  margin: 0 0 14px;
  font-family: var(--body);
  font-size: clamp(14px, 1.2vw, 17px);
  color: var(--text);
}
.rules-check input[type="checkbox"] {
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  accent-color: var(--yellow);
  cursor: pointer;
}

.rules-warn {
  color: #F61875;
  font-family: var(--body);
  font-weight: 600;
  font-size: 14px;
  margin: 0 0 14px;
}

/* .rulesNext не несёт базовый класс .btn (см. разметку в index.php) —
   собственные border/padding/typography добавлены здесь, поверх фоновых
   стилей из .btn-primary. */
.rules-next {
  display: block;
  width: 100%;
  margin-top: 4px;
  border: none;
  border-radius: 12px;
  padding: 14px 22px;
  font-family: var(--disp);
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .6px;
  cursor: pointer;
  transition: transform .12s ease, box-shadow .2s ease, background .2s ease, opacity .2s ease;
}
.rules-next:active { transform: scale(.97); }
