/* ============================================================================
   ТВ-вид «Шпионажа» (GM9): сцена Unity на большом экране. Скрипт —
   connection/_Scripts/Game/Sp_Tv.js. Панель ведущего — общая (_Styles/tv-panel.css).

   Откуда числа: GameMode9.unity + GM9_Character_Prefab + GM9 Vote Root, спроецированные
   камерой Unity (FOV 60, покой (0, 0.24, −0.76); заставка — с (0, 2.54, 0), 8 с OutQuint) на
   кадр 1920×1080: на глубине персонажей (z 0) 1 единица = 1230.7 px. Размеры персонажа ниже —
   при масштабе 1 (ряд до 7 игроков); 8–10 игроков — меньше (Layout By Count в Spy Stage).
   Картинки — public/images_web/tv/gm9 (tools/export_gm9_tv_sprites.py). Шрифт — Bebas Neue,
   TMP SmallCaps — строчные заглавными 0.8 кегля (.sptv-sc).
   Приставка sptv- — своя (в style.css такой нет).
   ============================================================================ */
:root {
  --sptv-min-w: 1000;            /* ТВ-вид с ширины окна, px */
  --sptv-min-aspect: 1.2;        /* …и окно не уже (ширина / высота) */
  --sptv-gname-z: 1.36;          /* название «Шпионаж» на заставке: дальше камеры в покое на, единиц (Unity: z 0.6) */
  --sptv-gname-y: 411px;       /* …центр по высоте на кадре в покое */
  --sptv-gname-fs: 407px;      /* …кегль */
  --sptv-gname-c: #FFDAB1;       /* …цвет */
  --sptv-guess-wait: 1500;       /* догадка шпиона: от прилёта камеры до плашки со словом, мс (в Unity — пока диктор договорит) */
  --sptv-story-y: 347px;       /* титры вступления: центр по вертикали (Story Title) */
  --sptv-story-fs: 88.6px;       /* …кегль (Bebas Book) */
  --sptv-card-w: 360px;          /* панель ведущего: карточка слова слева, ширина (16:9) */
  --sptv-round-fs: 700.9px;      /* итоги раунда: огромный номер раунда — размер (Unity 974.7) */
  --sptv-round-x: 960px;         /* …центр по горизонтали (кадр в покое) */
  --sptv-round-y: 744.35px;      /* …центр по высоте */
  --sptv-round-a: 0.329;         /* …непрозрачность (Unity 0.051) */
  --sptv-round-blend: overlay;   /* …наложение на лес и небо за ним (юзер 30.10: оверлей; Unity — обычное) */
  --sptv-dock-right: 40px;       /* облёт фактов: кнопка действия («Я знаю слово» / «Начать голосование») — от правого края */
  --sptv-dock-bottom: 24px;      /* …над нижней панелью сайта на */
  --sptv-score-gap: 60px;         /* итоги раунда: плашка очков выше роли (ШПИОН / МИРНЫЙ) ещё на (0 — как в Unity) */
  --sptv-glow-pulse-ms: 3900;    /* зарево за лесом пульсирует: один вдох-выдох, мс (юзер 30.10; в Unity стоит) */
  --sptv-glow-pulse-scale: 1; /* …раздувается до */
  --sptv-glow-pulse-dim: 1;    /* …яркость на выдохе (1 — не тускнеет) */
  --sptv-dust-rate: 300;         /* огоньки (CFXR3 Ambient Glows): сколько появляется в секунду (не больше 100 разом) */
  --sptv-dust-a: 1.1;              /* …яркость (множитель к альфе Unity 0.2–0.4) */
  --sptv-dust-size: 1;           /* …размер (множитель) */
  --sptv-fglow-a: 1;             /* красное зарево перед лесом, за персонажами (камера у раскрываемого): непрозрачность */
  --sptv-fglow-in: 1000;         /* …проявляется за, мс (InOutQuart; зарево за лесом в это время гаснет) */
  --sptv-fglow-out: 1000;        /* …гаснет за, мс, когда камера улетает */
  --sptv-fglow-scale: 1;         /* …размер (1 — как зарево за лесом: 2105×2407 px) */
  --sptv-fglow-x: -85px;           /* …сдвиг по горизонтали от места зарева за лесом (центр 1107, 866) */
  --sptv-fglow-y: 275px;           /* …сдвиг по вертикали */
}

.sptv {
  position: fixed; inset: 0; z-index: 25;
  overflow: hidden; display: none;
  background: #000;                              /* камера: Solid Color, чёрный */
  -webkit-user-select: none; user-select: none;
}
body.sptv-on .sptv { display: block; }
.sptv img { max-width: none; }

.sptv-stage {
  position: absolute; left: 50%; top: 50%;
  width: 1920px; height: 1080px; margin: -540px 0 0 -960px;
  transform-origin: 50% 50%;
  font-family: 'Bebas Neue', 'Bebas Neue Pro', Impact, sans-serif;
  line-height: 1;
}
.sptv-plane, .sptv-layer {
  position: absolute; left: 0; top: 0; width: 1920px; height: 1080px;
  transform-origin: 960px 540px; pointer-events: none;
}
.sptv-plane.is-behind { display: none; }
.sptv-plane > *, .sptv-layer > * { position: absolute; }
.sptv-spr { background: center / 100% 100% no-repeat; }
.sptv-sc { font-size: 0.8em; }
.sptv-text { display: flex; align-items: center; justify-content: center; text-align: center; white-space: normal; overflow-wrap: anywhere; }
.sptv-in { display: block; }

/* ---------------------------------------------------------------- лес -- */
/* Слой Background: дальние планы — за ближними (z 4 → 1). */
.sptv-sky { left: -24.5px; top: -694.6px; width: 1988.5px; height: 2300.1px; background: rgb(29 36 55); }   /* «Ресурс 21» — ровная заливка × цвет спрайта: картинка не нужна */
/* .sptv-fglow — то же зарево перед лесом, но за персонажами и землёй (юзер 30.10), положение — как у заднего при камере дома. */
.sptv-fglow { opacity: 0; translate: var(--sptv-fglow-x) var(--sptv-fglow-y); scale: var(--sptv-fglow-scale); }
.sptv-mirror { scale: -1 1; }
.sptv-dust { left: 0; top: 0; width: 1920px; height: 1080px; }
/* Пульс зарева за лесом — размером и яркостью (прозрачность занята переходом зарева на первый план). */
.sptv-glow:not(.sptv-fglow) { animation: sptv-glow-pulse calc(var(--sptv-glow-pulse-ms) * 1ms) ease-in-out infinite alternate; }
@keyframes sptv-glow-pulse {
  from { scale: 1; filter: brightness(var(--sptv-glow-pulse-dim)); }
  to { scale: var(--sptv-glow-pulse-scale); filter: brightness(1); }
}
@media (prefers-reduced-motion: reduce) { .sptv-glow:not(.sptv-fglow) { animation: none; } }
.sptv-glow { left: 54.2px; top: -337.7px; width: 2105.3px; height: 2407.1px; background-image: url('/images_web/tv/gm9/glow.webp'); }
.sptv-trees19 { top: 228.2px; width: 1276.8px; height: 842.6px; background-image: url('/images_web/tv/gm9/trees19.webp'); }
.sptv-trees18 { top: 250.5px; width: 1410.3px; height: 924.6px; background-image: url('/images_web/tv/gm9/trees18.webp'); }
.sptv-tree13 { left: -126.2px; top: 351.9px; width: 403.3px; height: 823.6px; background-image: url('/images_web/tv/gm9/tree13.webp'); }
.sptv-tree11 { left: 1214px; top: 465.2px; width: 298.7px; height: 617.2px; background-image: url('/images_web/tv/gm9/tree11.webp'); }
.sptv-pine7 { background-image: url('/images_web/tv/gm9/pine7.webp'); }
.sptv-pine8 { left: 108.9px; top: 371.4px; width: 278.1px; height: 794.2px; background-image: url('/images_web/tv/gm9/pine8.webp'); }
.sptv-pine9 { left: 1576.3px; top: 24.3px; width: 468.1px; height: 967.6px; background-image: url('/images_web/tv/gm9/pine9.webp'); }
.sptv-ground { top: 892px; width: 984.5px; height: 196.9px; background-image: url('/images_web/tv/gm9/ground.webp'); }

/* -------------------------------------------------------- персонажи -- */
/* Ряд — на весь кадр плана; узел персонажа стоит в центре аватарки, всё остальное — от него
   (префаб при масштабе 1). Без position: absolute узлы вставали потоком в левый верхний угол. */
.sptv-line { left: 0; top: 0; width: 1920px; height: 1080px; }
.sptv-ch { position: absolute; width: 0; height: 0; }
.sptv-ch > *, .sptv-votes > * { position: absolute; }
.sptv-av { left: -116.9px; top: -110.75px; width: 233.8px; height: 221.5px; }
.sptv-av img, .sptv-av i { position: absolute; inset: 0; width: 100%; height: 100%; }
/* Цвет SpriteRenderer умножает аватарку: «не в фокусе» — тёмно-серый, выбывший — красный. */
.sptv-av i { opacity: 0; mix-blend-mode: multiply; -webkit-mask: var(--av) center / 100% 100% no-repeat; mask: var(--av) center / 100% 100% no-repeat;
  transition: opacity var(--tint-ms, 400ms) linear; }
.sptv-av .is-dim { background: #303030; }       /* Unfocused Color (0.189) */
.sptv-av .is-out { background: #FF1C1C; }       /* Eliminated Color (1, 0.108, 0.108) */
.sptv-ch.is-dim .sptv-av .is-dim, .sptv-ch.is-out .sptv-av .is-out { opacity: 1; }
.sptv-ch.is-out .sptv-av .is-dim { opacity: 0; }

/* Ник со стрелкой: появляется, пока камера летит к игроку; на голосовании — у всех. */
.sptv-name { left: -99.55px; top: -209.85px; width: 199.1px; height: 60.3px; color: #FFDAB1; font-size: 60.2px; opacity: 0; white-space: nowrap; }
.sptv-arrow { left: -17.45px; top: -136.4px; width: 34.9px; height: 19.1px; background-image: url('/images_web/tv/gm9/arrow.webp'); opacity: 0; }
/* Реплика (факт): белый Bebas Book, печатается 45 знаков/с. */
.sptv-phrase { left: -216.7px; top: -403.6px; width: 433.4px; height: 152.4px; color: #fff; font-size: 52.1px; font-weight: 300; opacity: 0; }
.sptv-phrase .is-rest { visibility: hidden; }
/* Раскрытие над игроком («Лиза — шпион!»), Bebas Bold. */
.sptv-reveal { left: -177.9px; top: -370.6px; width: 355.8px; height: 135.6px; color: #fff; font-size: 69.1px; font-weight: 700; opacity: 0; }
/* Значок роли: ШПИОН / МИРНЫЙ. */
.sptv-badge { left: -110.75px; top: -270.75px; width: 221.5px; height: 51.7px; font-size: 48px; opacity: 0; white-space: nowrap; }
.sptv-badge.is-spy { color: #FF5C5C; }
.sptv-badge.is-civ { color: #99EB99; }

/* Плашки (PlayerNameTab, чёрные) — маска. */
.sptv-tab { background: #000; -webkit-mask: url('/images_web/tv/gm9/tab.webp') center / 100% 100% no-repeat;
  mask: url('/images_web/tv/gm9/tab.webp') center / 100% 100% no-repeat; position: absolute; inset: 0; }
/* Догадка шпиона: плашка со словом падает (scale 0.4 → 0.03 за 0.06 с), слово — в цвете вердикта. */
.sptv-word { left: -154.6px; top: -340.25px; width: 309.2px; height: 97.1px; opacity: 0; transform-origin: 50% 50%; }
.sptv-word b { position: absolute; left: 34.9px; top: 18.4px; width: 239.4px; height: 60.3px; font-weight: 400; font-size: 60.2px;
  display: flex; align-items: center; justify-content: center; white-space: nowrap; }
.sptv-word.is-right b { color: #AAFFB9; }       /* Secret Word Correct Color */
.sptv-word.is-wrong b { color: #FF5858; }       /* Secret Word Wrong Color */

/* Плашки голосов: над игроком стопкой, первая — на 0.07 выше ника, шаг 0.06. */
.sptv-votes { left: 0; top: 0; width: 0; height: 0; }
.sptv-vote { left: -104.8px; width: 209.6px; height: 61.5px; transform-origin: 50% 50%; }
.sptv-vote b { position: absolute; left: 16.25px; top: 11.65px; width: 177.1px; height: 38.2px; color: #fff; font-weight: 400; font-size: 38.1px;
  display: flex; align-items: center; justify-content: center; white-space: nowrap; }

/* Итоги раунда: плашка очков (Title — за что), над ней число (плюс — зелёный, минус — красный). */
.sptv-score { left: -116.4px; top: -353.55px; width: 232.8px; height: 64.7px; transform-origin: 50% 50%; display: none; }
.sptv-score.is-on { display: block; }
.sptv-score .sptv-stitle { position: absolute; left: 22.65px; top: 7.3px; width: 182.5px; height: 47.5px; color: #fff; font-size: 23.8px; }
.sptv-score .sptv-snum { position: absolute; left: 17.5px; top: -89.4px; width: 190.4px; height: 73.5px; font-size: 73.5px; white-space: nowrap; }
.sptv-snum.is-plus { color: #B6FFAC; }
.sptv-snum.is-minus { color: #F25959; }

/* Огромный номер раунда за персонажами — проявляется на итогах раунда до альфы 0.051 («Round Count»).
   По центру сцены (юзер 30.10; в Unity — правее, x 0.071). */
.sptv-round { left: calc(var(--sptv-round-x) - 960px); top: calc(var(--sptv-round-y) - 676.85px); width: 1920px; height: 1353.7px;
  color: #fff; font-size: var(--sptv-round-fs); font-weight: 700; opacity: 0; }
/* Номер раунда — свой план перед лесом, за персонажами; наложение — у плана (сам номер гаснет прозрачностью, а прозрачный
   узел смешивался бы только с пустотой своего плана). */
.sptv-roundbg { mix-blend-mode: var(--sptv-round-blend); }

/* --------------------------------------------------- надписи и титры -- */
/* Stage / Reveal Banner: Title (#FFDAB1) и Subtitle (белый), вылетают по Z (2 с OutExpo). */
.sptv-btitle { left: 406.2px; top: 190.5px; width: 1107.6px; height: 140.2px; color: #FFDAB1; font-size: 124.1px; opacity: 0; transform-origin: 553.8px 349.5px; }
.sptv-bsub { left: 406.2px; top: 339.4px; width: 1107.6px; height: 73.8px; color: #fff; font-size: 86.1px; opacity: 0; transform-origin: 553.8px 200.6px; }
/* Название режима на заставке (Intro Controller → Game Name, z 0.6). */
.sptv-gname { left: 186.3px; top: calc(var(--sptv-gname-y) - 331.45px); width: 1547.4px; height: 662.9px; color: var(--sptv-gname-c);
  font-size: var(--sptv-gname-fs); opacity: 0; }
/* «3», «2», «GO!» (Countdown Text). */
.sptv-count { left: 734.45px; top: 217.65px; width: 428.9px; height: 423.1px; color: #fff; font-size: 407px; opacity: 0; }
/* Титры вступления: слова проявляются, когда диктор их произносит (Spy Subtitles). */
.sptv-story { left: 396.35px; top: calc(var(--sptv-story-y) - 154.35px); width: 1186.3px; height: 308.7px; color: #fff;
  font-size: var(--sptv-story-fs); font-weight: 300; }
.sptv-story span { opacity: 0; }

/* RoundStatsTab (таймер, раунд «2/3», шпионы) — общая плашка ТВ-видов: tv-stats.css (Utils/PBTvStats.js). */
.sptv-timer { font-weight: 700; }

/* ------------------------------------------------- панель ведущего -- */
/* Панель — общая (tv-panel.css): как экран телефона, блоки в ряд. Своё у «Шпионажа» — карточка слова
   слева (p.lead), как шапка телефона: 16:9, открыта; глаз сжимает её до кнопки (.g9-picture.is-veiled
   из style.css — размер возвращаем ей здесь, иначе его перебивала ширина карточки). */
.tvp-lead.g9-picture { width: var(--sptv-card-w); }
.tvp-lead.g9-picture.is-veiled { width: 40px; height: 40px; }
.sptv-card.is-noimg { background: var(--pb-surface-2); }

/* Облёт фактов: кнопка действия справа внизу — открывает панель ведущего (юзер 30.10). Над нижней панелью сайта. */
.sptv-dock { position: absolute; z-index: 3; display: none; width: auto; max-width: none; margin: 0;
  right: var(--sptv-dock-right);
  bottom: calc(var(--pb-bottom-bar-height, 76px) + env(safe-area-inset-bottom, 0px) + var(--sptv-dock-bottom)); }
.sptv-dock.is-on { display: inline-flex; }
