/* Экраны игры. Общий для показа и превью: всё под .stage, кадр 1280×720, в интерфейсе масштабируется целиком.
   Дизайн-система слайдов — токены на .stage, ниже. Правила мастеров и компонентов берут значения только из токенов:
   ни одного размера, шага, цвета или ширины «руками». Новый размер = новый токен, а не число в правиле.
   Сетка: поля --pad-x/--pad-y (тема задаёт свои), 12 колонок --col считаются от полей, межколонник --gut; три горизонтали META (--meta-h), CONTENT, STATUS (--status-h);
   контент центрируется в области между хедером и подвалом. Типографика — пять токенов (xl, l, t, b, m) и таймер; у длинного текста запасные версии.
   Цвет = состояние: --accent — цвет состояния экрана (подпись в хедере, полоса таймера); крупное — часы, таймер, суммы, буквы вариантов, лидер — всегда основным цветом темы --main. Код и ответы — --c-code, ставки и финал — --c-bets, служебные и перерыв — --c-service.
   Тема меняет только цвета и шрифты (TVQS.applyTheme). */
.stage {
  /* цвета: тема переопределяет через applyTheme */
  --bg:#0e0e0e; --fg:#ececec; --muted:#8f8f8f; --line:#2c2c2c; --accent:#e8e8e8; --main:var(--accent); --warn:#e3b341; --twarn:#f85149;   /* --accent — цвет состояния экрана, --main — основной цвет темы для крупного */
  --ph-ratio:5 / 4; --c-code:#ff5c5c; --c-bets:#9b7bff; --c-service:#ffb54d; --c-bubble:#232323;
  /* статусы: те же значения, что отдаёт TVQ.palette — тема их не пересчитывает, только может переопределить */
  --c-ok:#3fb950; --c-bad:#f85149;
  --c-ui:#262626; --c-ui-hover:#3a3a3a; --c-ui-line:#444; --c-ui-line-hover:#5c5c5c; --c-ui-input:#1c1c1c; --c-ui-ink:#111; --c-ph:#3a3a3a; --c-ph-text:#6a6a6a;
  /* шрифты: тема подставляет свои */
  --font-body:system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; --font-head:var(--font-body);
  /* сетка кадра 1280×720 */
  --pad-x:56px; --pad-y:56px; --gut:24px; --col:calc((1280px - 2 * var(--pad-x) - 11 * var(--gut)) / 12);   /* тема меняет поля, колонки пересчитываются */ --meta-h:48px; --status-h:64px; --band-gap:16px;
  --w9:calc(9 * var(--col) + 8 * var(--gut)); --w7:calc(7 * var(--col) + 6 * var(--gut)); --w6:calc(6 * var(--col) + 5 * var(--gut)); --w5:calc(5 * var(--col) + 4 * var(--gut)); --w4:calc(4 * var(--col) + 3 * var(--gut)); --w3:calc(3 * var(--col) + 2 * var(--gut)); --gap-col:calc(var(--col) + 2 * var(--gut));
  /* шаг */
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:20px; --s6:24px; --s7:32px; --s8:40px;
  /* типографика: пять ролей и ни одного размера сверх них. XL 120 — название, команда, ответ, часы перерыва; L 52 — вопрос, фраза бита, таймер, сумма в табло;
     T 40 — заголовок блока, команда в табло, данные соответствия; B 32 — текст; M 22 — хедер, подписи, служебные числа.
     Длинный текст меняет роль на следующую (XL → L, L → T), а не размер. Новый размер в правиле — ошибка. */
  --fs-xl:120px; --lh-xl:1; --ls-xl:-.02em; --fs-l:52px; --lh-l:1.15; --ls-l:-.01em; --fs-t:40px; --lh-t:1.2; --fs-b:32px; --lh-b:1.4; --fs-m:22px; --lh-m:1.3; --ls-m:.01em; --fs-ui:15px;
  --w-xl:800; --w-l:600; --w-t:600; --w-m:500; --w-num:800; --head-scale:1;   /* выравнивание заголовочного шрифта по высоте прописных, ставит applyTheme */
  /* компоненты */
  --radius:8px; --radius-bubble:18px; --hair:1px; --tbar-h:10px; --logo-h:96px; --sting-logo-h:280px; --bug-h:56px; --bug-w:280px; --art-h:440px; --beat-art-h:300px; --bg-dim:.4;
  --timer-w:120px; --rank-w:56px; --total-w:150px; --delta-w:100px; --num-w:36px; --radius-ui:6px; --focus:2px; --btn-min:70px; --adj-w:28px; --indent:1.15em; --dim:.45;
  /* движение: длительность и кривая только отсюда, число в правиле — ошибка */
  --dur-1:.16s; --dur-2:.24s; --dur-3:.32s; --dur-bar:1s; --ease:cubic-bezier(.22,.61,.36,1); --press:.96; --dur-press:.06s; --hover-dim:.9; --rise:10px; --rise-sm:4px; --pop:.98;
  background:var(--bg); color:var(--fg); font-family:var(--font-body); font-size:var(--fs-b); line-height:var(--lh-b); box-sizing:border-box; -webkit-font-smoothing:antialiased; }   /* не сокращением font: одна невалидная переменная роняла бы всё правило */
.stage *, .stage *::before, .stage *::after { box-sizing:border-box; }
.stage main { flex:1; min-height:0; width:100%; padding:var(--pad-y) var(--pad-x); display:grid; grid-template-rows:var(--meta-h) minmax(0,1fr) var(--status-h); grid-template-columns:minmax(0,1fr); row-gap:var(--band-gap); position:relative; }
.stage main > * { position:relative; z-index:1; min-width:0; }
.stage .art.bg { position:absolute; inset:0; width:100%; height:100%; max-height:none; object-fit:cover; border-radius:0; margin:0; opacity:var(--bg-dim); z-index:0; }
/* META: хедер из трёх зон — контекст, состояние, прогресс; у всех мастеров одинаковый */
.stage .meta { grid-row:1; display:grid; grid-template-columns:1fr auto 1fr; gap:var(--s6); align-items:start; padding-top:var(--s2); font-size:var(--fs-m); line-height:var(--lh-m); letter-spacing:var(--ls-m); color:var(--muted); }
.stage .meta .state { text-align:center; color:var(--accent); font-weight:var(--w-t); font-family:var(--font-head); font-size:calc(var(--fs-m) * var(--head-scale)); }
.stage .meta .prog { text-align:right; font-variant-numeric:tabular-nums; }
/* CONTENT: всё центрируется в области между хедером и подвалом; никаких сдвигов «выше центра» (Роман) */
.stage .slide { grid-row:2; min-height:0; display:flex; flex-direction:column; justify-content:safe center; }
.stage .slide.cover { grid-row:1 / 3; }
.stage .slide.full { grid-row:1 / -1; }   /* стингер без хедера и подвала: весь кадр, знак ровно по центру */   /* обложка без хедера: занимает и его полосу, центр выше */
.stage .slide > :nth-child(n+2) { margin-top:var(--s6); }
/* STATUS: таймер и брендовый знак всегда на одном месте */
.stage .foot { grid-row:3; display:flex; align-items:flex-end; gap:var(--s6); }   /* прижат к нижнему полю, чтобы отступ снизу читался как поле */
.stage .foot .tbar { flex:1; margin-bottom:var(--s2); }
/* ширины по колонкам */
.stage .w9 { max-width:var(--w9); }
.stage .w7 { max-width:var(--w7); }
/* типографика: пять токенов. Заголовочный шрифт темы — акциденция: названия, имена команд, ответы, подпись состояния; вопрос и всё, что читают, — текстовым */
.stage .d-xl { font-family:var(--font-head); font-size:calc(var(--fs-xl) * var(--head-scale)); line-height:var(--lh-xl); font-weight:var(--w-xl); letter-spacing:var(--ls-xl); margin:0; overflow-wrap:anywhere; }
.stage .d-xl.long, .stage .d-xl.xlong { font-size:calc(var(--fs-l) * var(--head-scale)); line-height:var(--lh-l); letter-spacing:var(--ls-l); }
.stage .d-l { font-family:var(--font-body); font-size:var(--fs-l); line-height:var(--lh-l); font-weight:var(--w-l); letter-spacing:var(--ls-l); margin:0; }
.stage .d-l.long, .stage .d-l.xlong { font-size:var(--fs-t); line-height:var(--lh-t); }
.stage .t { font-family:var(--font-head); font-size:calc(var(--fs-t) * var(--head-scale)); line-height:var(--lh-t); font-weight:var(--w-t); margin:0; }
.stage .b { font-family:var(--font-body); font-size:var(--fs-b); line-height:var(--lh-b); margin:0; }
.stage .m { font-family:var(--font-body); font-size:var(--fs-m); line-height:var(--lh-m); letter-spacing:var(--ls-m); color:var(--muted); margin:0; font-weight:var(--w-m); }
.stage .quiet { color:var(--muted); }
.stage .warn { color:var(--warn); }
.stage .center { text-align:center; }
.stage .ph { border:var(--hair) dashed var(--c-ph); color:var(--c-ph-text); padding:var(--s4) var(--s5); border-radius:var(--radius); font-size:var(--fs-m); }
.stage .ph.frame { aspect-ratio:var(--ph-ratio); display:flex; align-items:center; justify-content:center; text-align:center; }   /* зона медиа держит композицию, пока файла нет */
.stage .art { width:100%; max-height:var(--art-h); object-fit:cover; border-radius:var(--radius); display:block; margin:0; }
/* логотип: два состояния — большой на обложке, брендовый знак справа в подвале на всех остальных слайдах */
.stage .art.logo { width:auto; max-width:50%; max-height:var(--logo-h); object-fit:contain; border-radius:0; margin:0 auto; }
.stage .art.logo.bug { max-height:var(--bug-h); max-width:var(--bug-w); margin:0 0 0 auto; }
.stage .art.logo.sting { max-height:var(--sting-logo-h); max-width:var(--w9); }   /* стингер: знак серии главный на кадре */
.stage .hero .logo.sting { margin-bottom:0; }   /* знак один в кадре: отступ под подпись не нужен, иначе он уезжает выше центра */
/* мастер «Обложка» */
.stage .hero { text-align:center; }
.stage .hero > :nth-child(n+2) { margin-top:var(--s5); }
.stage .hero .logo { margin-bottom:var(--s7); }
/* «Команда» */
.stage .teamname { text-align:center; }
/* «История»: текст до 9 колонок, не больше трёх абзацев на слайд; с картинкой — 7 текста и 5 картинки */
.stage .story { display:grid; grid-template-columns:minmax(0,1fr); }
.stage .story.with-art { grid-template-columns:var(--w7) var(--w5); column-gap:var(--gut); align-items:start; }
.stage .story .copy { max-width:var(--w9); }
.stage .story .copy > :nth-child(n+2), .stage .story .aside > :nth-child(n+2) { margin-top:var(--s4); }
.stage .list { padding-left:var(--indent); margin:0; }
.stage .list li + li { margin-top:var(--s2); }
.stage ul.list li::marker { color:var(--main); }
.stage ol.list li::marker { color:var(--main); font-weight:var(--w-num); }
.stage ol.list.m { color:var(--fg); }   /* сет-лист длиннее шести раундов: роль M, цвет основной */
/* «Бит»: картинка и одна-две строки крупно */
.stage .beat .art { max-height:var(--beat-art-h); margin-bottom:var(--s7); }
.stage .beat .d-l { max-width:var(--w9); }
/* «Вопрос»: prompt до 9 колонок; с картинкой — 5 текста и 6 медиа справа; соответствие и порядок — инструкция и колонки данных */
.stage .qm { display:grid; grid-template-columns:minmax(0,1fr); }
.stage .qm.with-media { grid-template-columns:var(--w5) var(--w6); column-gap:var(--gap-col); align-items:start; }
.stage .qm.matching .pairs ol, .stage .qm.matching .pairs ul, .stage .opts.data li { font-size:var(--fs-t); }
.stage .qm .prompt { max-width:var(--w9); }
.stage .qm .prompt > :nth-child(n+2) { margin-top:var(--s5); }
.stage .qm .media .art { object-fit:contain; object-position:top; }
.stage .qm .media .m { margin-top:var(--s2); }
.stage .opts { list-style:none; padding:0; margin:0; display:grid; grid-template-columns:1fr 1fr; gap:0 var(--s8); }
.stage .opts.one { grid-template-columns:1fr; }
.stage .opts li { font-size:var(--fs-b); line-height:var(--lh-m); padding:var(--s3) 0; border-top:var(--hair) solid var(--line); }
.stage .opts.dense li { padding:var(--s2) 0; }
.stage .opts b, .stage .pairs b { font-family:var(--font-head); color:var(--main); margin-right:var(--s4); font-weight:var(--w-num); }
.stage .pairs { display:grid; grid-template-columns:1fr 1fr; gap:0 var(--s8); }
.stage .pairs ol, .stage .pairs ul { margin:0; padding:var(--s3) 0 0 var(--indent); border-top:var(--hair) solid var(--line); font-size:var(--fs-b); line-height:var(--lh-m); }
.stage .pairs ul { list-style:none; padding-left:0; }
.stage .pairs li + li { margin-top:var(--s2); }
.stage .pairs ol li::marker { color:var(--main); font-weight:var(--w-num); }
/* «Ответ»: ответ главным, вопрос мелко над ним, разбор абзацем */
.stage .answer.with-media { display:grid; grid-template-columns:var(--w7) var(--w5); column-gap:var(--gut); align-items:start; }
.stage .answer .copy > :nth-child(n+2) { margin-top:var(--s5); }
.stage .answer .recap { font-size:var(--fs-m); }
.stage .answer .list { max-width:var(--w9); }
/* движение очков при ставке: команда → ставка → дельта → всего */
.stage .txn .row { display:grid; grid-template-columns:minmax(0,1fr) auto var(--delta-w) var(--delta-w); column-gap:var(--s7); align-items:baseline; padding:var(--s2) 0; border-top:var(--hair) solid var(--line); font-size:var(--fs-b); line-height:var(--lh-t); }
.stage .txn .team { font-family:var(--font-head); font-weight:var(--w-t); font-size:calc(var(--fs-b) * var(--head-scale)); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.stage .txn .bet { font-size:var(--fs-m); letter-spacing:var(--ls-m); color:var(--muted); }
.stage .txn .delta, .stage .txn .total { font-weight:var(--w-num); text-align:right; font-variant-numeric:tabular-nums; }
.stage .txn .total { color:var(--main); }
.stage .txn.dense .row { padding:var(--s1) 0; }
/* «Служебный»: залу заголовок и строка */
.stage .service > :nth-child(n+2) { margin-top:var(--s4); }
.stage .service .b { max-width:var(--w9); }
/* «Табло»: место → команда → всего; раунды второстепенно */
.stage .board .row { display:grid; grid-template-columns:var(--rank-w) minmax(0,1fr) auto var(--total-w); column-gap:var(--s6); align-items:center; padding:var(--s3) 0; border-bottom:var(--hair) solid var(--line); }
.stage .board .row.head { padding:0 0 var(--s2); }
.stage .board .row.head .rounds span, .stage .board .row.head .total { font-family:var(--font-body); font-size:var(--fs-m); letter-spacing:var(--ls-m); color:var(--muted); font-weight:var(--w-m); line-height:var(--lh-m); }
.stage .board .rank { font-family:var(--font-head); font-size:calc(var(--fs-t) * var(--head-scale)); color:var(--muted); font-variant-numeric:tabular-nums; }
.stage .board .team { font-family:var(--font-head); font-size:calc(var(--fs-t) * var(--head-scale)); font-weight:var(--w-t); line-height:var(--lh-l); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.stage .board .rounds { display:flex; gap:var(--s3); font-size:var(--fs-m); color:var(--muted); font-variant-numeric:tabular-nums; }
.stage .board .rounds span { min-width:var(--num-w); text-align:right; }
.stage .board .total { font-size:var(--fs-l); font-weight:var(--w-num); text-align:right; color:var(--main); font-variant-numeric:tabular-nums; line-height:var(--lh-xl); }
.stage .board .row.lead .team { color:var(--main); }
.stage .board.dense .team { font-size:calc(var(--fs-b) * var(--head-scale)); }
.stage .board.dense .total { font-size:var(--fs-t); }
.stage .board.dense .row { padding:var(--s1) 0; }
.stage .board.dense .rank { font-size:var(--fs-m); }
/* «Карта уровней»: положение команд, а не числа */
.stage .map .band { display:grid; grid-template-columns:var(--w3) minmax(0,1fr); column-gap:var(--gut); padding:var(--s4) 0; border-top:var(--hair) solid var(--line); align-items:baseline; }
.stage .map .lvl .t { color:var(--main); }
.stage .map .names { display:flex; flex-wrap:wrap; gap:var(--s2) var(--s7); align-items:baseline; }
.stage .map .names .t { overflow-wrap:anywhere; }
.stage .map.dense .names .t { font-size:var(--fs-b); }
.stage .map .names .m { margin-left:var(--s3); }
.stage .map .line { margin-top:var(--s2); }
/* таймер: полоса во всю ширину подвала, цифра справа */
.stage .timer { font-size:var(--fs-l); font-weight:var(--w-num); font-variant-numeric:tabular-nums; line-height:var(--lh-xl); color:var(--main); min-width:var(--timer-w); text-align:right; transition:color var(--dur-2) var(--ease); }
.stage .timer.warn { color:var(--twarn); }
.stage .clockbox { text-align:center; }
.stage .clockbox > :nth-child(n+2) { margin-top:var(--s4); }
.stage .timer.clock { display:block; font-family:var(--font-head); font-size:calc(var(--fs-xl) * var(--head-scale)); min-width:0; text-align:center; letter-spacing:var(--ls-xl); }   /* часы перерыва — акциденция, подпись над ними — наборным */
.stage .clockbox .t { font-family:var(--font-body); font-size:var(--fs-t); }
.stage .tbar { height:var(--tbar-h); background:var(--line); border-radius:calc(var(--tbar-h) / 2); overflow:hidden; }
.stage .tfill { height:100%; width:100%; background:var(--accent); transition:width var(--dur-bar) linear, background var(--dur-2) var(--ease); }
.stage .tfill.warn { background:var(--twarn); }
.stage .bubble { display:inline-block; background:var(--c-bubble); border-radius:var(--radius-bubble); padding:var(--s4) var(--s6); font-size:var(--fs-b); line-height:var(--lh-m); }
.stage .ok { color:var(--c-ok); } .stage .bad { color:var(--c-bad); }
/* у ведущего: кнопки, таблицы, поля — только в окне ведущего */
.stage h1 { font-family:var(--font-head); font-size:var(--fs-l); line-height:var(--lh-l); margin:0 0 var(--s4); font-weight:var(--w-l); }
.stage h2 { font-family:var(--font-head); font-size:var(--fs-b); line-height:var(--lh-t); margin:0 0 var(--s3); color:var(--muted); font-weight:var(--w-m); }
.stage button { font:inherit; background:var(--c-ui); color:var(--fg); border:var(--hair) solid var(--c-ui-line); padding:var(--s2) var(--s4); border-radius:var(--radius-ui); cursor:pointer; transition:background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease), filter var(--dur-1) var(--ease); }
/* отклик: наведение светлее фон и рамка, у цветных кнопок чуть темнее; нажатие продавливает быстро, отпускание плавное */
.stage button:not(:disabled):hover { background:var(--c-ui-hover); border-color:var(--c-ui-line-hover); }
.stage button:not(:disabled):active { transform:scale(var(--press)); transition-duration:var(--dur-press); }
.stage button:disabled { opacity:var(--dim); cursor:default; }
.stage button.primary { background:var(--fg); color:var(--c-ui-ink); border-color:var(--fg); }
.stage button.small { padding:var(--s1) var(--s3); font-size:var(--fs-ui); }
.stage button.on { background:var(--c-ui-hover); color:var(--fg); border-color:var(--fg); }   /* выбранное — нейтрально, как нажатый Toggle в shadcn: цвет состояния в крупном не используем (Роман: «че за странный стиль?») */
.stage button.primary:not(:disabled):hover { background:var(--fg); border-color:var(--fg); filter:brightness(var(--hover-dim)); }
.stage button.on:not(:disabled):hover { background:var(--c-ui-hover); border-color:var(--fg); }
.stage button.miss { opacity:var(--dim); }   /* файла нет: кнопка приглушена, подсказка в title */
.stage :focus-visible { outline:var(--focus) solid var(--accent); outline-offset:var(--focus); }
.stage table { border-collapse:collapse; width:100%; margin:var(--s3) 0; }
.stage th, .stage td { border-bottom:var(--hair) solid var(--line); padding:var(--s2); text-align:left; vertical-align:middle; }
.stage th { color:var(--muted); font-weight:var(--w-m); font-size:var(--fs-ui); }
.stage td.num { text-align:right; font-variant-numeric:tabular-nums; }
.stage input[type=text], .stage select { font:inherit; background:var(--c-ui-input); color:var(--fg); border:var(--hair) solid var(--c-ui-line); padding:var(--s2) var(--s3); border-radius:var(--s1); }
.stage input[type=text] { width:100%; }
.stage .audiobar { display:flex; gap:var(--s2); flex-wrap:wrap; align-items:center; margin:var(--s3) 0; }
.stage .audiobar .lbl { color:var(--muted); font-size:var(--fs-m); margin-right:var(--s2); }
.stage .marks button { min-width:var(--btn-min); }
.stage .sub { font-size:var(--fs-ui); } .stage .nowrap { white-space:nowrap; } .stage .adj { display:inline-block; min-width:var(--adj-w); text-align:center; }
.stage.hall .host { display:none !important; }
.stage:not(.hall):not(.host-window) .hall-only { display:none !important; }   /* host-window: окно ведущего, внутри него слайд зала */
.stage.hall .ph { display:none; }
.stage.preview .ph.frame { display:flex; }   /* в превью студии зона медиа видна рамкой, в зале — нет */
/* смена экрана: новый слайд проявляется снизу; при правке текста класс не ставится и перерисовка тихая */
.stage main.swap { animation:screen-in var(--dur-3) var(--ease); }
@keyframes screen-in { from { opacity:0; transform:translateY(var(--rise-sm)); } }
/* автоподгонка: если экран всё же не влезает в кадр, main ужимается через zoom (см. TVQS.fitStage) */
.stage main.fit { overflow:hidden; }
/* меньше движения — системная настройка сильнее оформления */
@media (prefers-reduced-motion: reduce) { .stage *, .stage *::before, .stage *::after { transition-duration:.01ms !important; animation-duration:.01ms !important; animation-iteration-count:1 !important; } }
