/* ─────────────────────────────────────────────────────────────────────────────
   Раскладка приложения: боевой слой, оболочка вкладок, слой экранов.

   Атомы живут в kit.css. Здесь только то, где они стоят. Позиции боевого HUD
   перенесены из src/viewer/index.html один в один — это утверждённый вручную
   экран (§10.6), и «подвинуть на два пикселя, пока переносил» — самый частый
   способ его потерять.
   ────────────────────────────────────────────────────────────────────────── */

html, body { height: 100%; overflow: hidden; background: var(--bg-scene); }
body.doc { overflow: auto; }

/* ── боевой слой ─────────────────────────────────────────────────────────── */
#arena { position: fixed; inset: 0; }
#arena canvas { display: block; }

#vignette {
  position: fixed; inset: 0; pointer-events: none; z-index: 5;
  background:
    radial-gradient(120% 90% at 50% 42%, transparent 52%, rgba(3, 7, 13, .42) 100%),
    linear-gradient(to bottom, rgba(6, 12, 20, .32) 0%, transparent 13%),
    linear-gradient(to top, rgba(4, 9, 16, .45) 0%, transparent 14%);
}

#hud { position: fixed; inset: 0; pointer-events: none; z-index: 10; }
#hud > * { pointer-events: auto; }
/* Экран поверх арены гасит HUD: две колонки чисел друг на друге не читаются. */
body.overlay #hud { opacity: .12; transition: opacity .25s ease; }
body.overlay #hud > * { pointer-events: none; }

/* карточки бойцов [эталон] */
.bar-wrap { position: absolute; top: 62px; display: flex; gap: 16px; align-items: flex-start; }
#bar-oct { left: 22px; color: var(--oct); }
#bar-gor { right: 22px; color: var(--gor); flex-direction: row-reverse; }
.bar-wrap .col { display: flex; flex-direction: column; }
#bar-gor .col { align-items: flex-end; }
.emblem { width: 100px; height: 100px; flex: 0 0 100px; margin-top: 2px; }

.namerow { display: flex; align-items: baseline; gap: 10px; margin-top: 3px; }
#bar-gor .namerow { flex-direction: row-reverse; }
.name {
  font-size: 21px; font-weight: 500; letter-spacing: .1em; text-transform: uppercase;
  line-height: 1.1; color: var(--name-cy);
  text-shadow: 0 0 16px rgba(95, 180, 200, .35), 0 0 5px rgba(95, 180, 200, .2);
}
#bar-gor .name { color: var(--name-or); text-shadow: 0 0 16px rgba(210, 140, 75, .32), 0 0 5px rgba(210, 140, 75, .2); }
.sub { font-size: 11px; font-weight: 500; letter-spacing: .06em; color: var(--dim); }

.hprow { position: relative; margin-top: 8px; height: 16px; width: 330px; }
#bar-gor .hp::before { clip-path: polygon(0 0, calc(100% - 5px) 0, 100% 100%, 5px 100%); }
#bar-gor .hp > i {
  left: auto; right: 0;
  clip-path: polygon(0 0, calc(100% - 5px) 0, 100% 100%, 5px 100%);
  background-image: linear-gradient(90deg,
    #e28642 0, #e28642 66px, #d47b3d 66px, #d47b3d 132px,
    #c26f38 132px, #c26f38 198px, #ac6231 198px, #ac6231 264px,
    #965429 264px, #965429 330px);
  background-position: right center;
  filter: drop-shadow(0 0 5px rgba(226, 140, 70, .45));
}
.hp > b {
  position: absolute; top: 50%; transform: translateY(-50%);
  left: calc(100% + 14px); font-size: 15px; font-weight: 600;
  font-variant-numeric: tabular-nums; letter-spacing: .02em; color: var(--oct);
  white-space: nowrap; text-shadow: 0 0 12px rgba(95, 180, 200, .3);
}
#bar-gor .hp > b { left: auto; right: calc(100% + 14px); color: var(--name-or); text-shadow: 0 0 12px rgba(210, 140, 75, .25); }

.cds { display: flex; gap: 7px; margin-top: 10px; }
#bar-gor .cds { flex-direction: row-reverse; }
.cd.ready { color: currentColor; }
.cd.cool { color: var(--dim); opacity: .75; }
/* Мёртвый боец: запись, не пульт. Существительное, не глагол — род имени
   существа задаёт игрок, и «выиграл/выиграла» рядом с ним всегда лотерея. */
.bar-wrap.dead { filter: grayscale(1); opacity: .45; }
.bar-wrap.dead .name::after { content: ' · ПОРАЖЕНИЕ'; opacity: .75; font-size: 12px; letter-spacing: .06em; }
.bar-wrap.won .name::after { content: ' · ПОБЕДА'; opacity: .8; font-size: 12px; letter-spacing: .06em; }

/*
 * Метка принадлежности боя (D162). Живёт под часами, в единственном месте,
 * куда смотрят все: между таймером и подписью про авторство мозгов.
 */
/*
 * Ширина ограничена ЗДЕСЬ, а не только в узких переломах.
 *
 * Замер по прямоугольникам при 1366×768: строка «твой бой» пересекалась с
 * чипами набора обеих сторон (59×16 и 27×16), а первый перелом стоял на 1300 —
 * то есть на самой массовой ноутбучной ширине дефект был, а правило до него
 * не доставало. Часы и так по центру; ограничение по ширине им ничего не
 * стоит и держится на всех размерах сразу.
 */
#clock .whose {
  margin-top: 7px; font-size: 11px; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; min-height: 13px;
  max-width: 26ch; margin-left: auto; margin-right: auto;
}
/* Цвет строки — нейтральный: сторона игрока бывает и оранжевой, и циановой,
   и красить «ТВОЙ БОЙ» всегда в циан значит спорить с точкой рядом, которая
   как раз показывает настоящую сторону. */
#clock .whose.mine { color: var(--ink); }
#clock .whose.other { color: var(--dim); }
#clock .whose .dot {
  display: inline-block; width: 7px; height: 7px; margin-right: 7px;
  border-radius: 50%; vertical-align: baseline;
}

/* «ТВОЁ» и «СЛЕДИШЬ» на плите — цвет берётся у СТОРОНЫ, а не у слова.
   Базовый `.badge` в kit.css циановый; на ОРАНЖЕВОЙ плите это чужой цвет
   ровно на том экране, весь смысл которого в том, что цвет = сторона. */
.sidetag .badge { border-color: currentColor; color: var(--oct); }
#bar-gor .sidetag .badge { color: var(--gor); }

.sidetag { margin-top: 9px; display: flex; gap: 7px; align-items: center; }
#bar-gor .sidetag { flex-direction: row-reverse; }
.sidetag .note { font-size: 10.5px; letter-spacing: .04em; color: var(--dim); max-width: 210px; }

/* часы [эталон] */
#clock { position: absolute; top: 56px; left: 50%; transform: translateX(-50%); text-align: center; }
#clock .t { font-size: 44px; font-weight: 600; letter-spacing: .04em; line-height: 1; font-variant-numeric: tabular-nums; color: var(--ink); }
#clock .s { margin-top: 6px; font-size: 12px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--dim); }
#clock .s.burning {
  font-size: 15px; font-weight: 700; color: var(--bad);
  text-shadow: 0 0 14px rgba(255, 106, 82, .75);
  animation: sd-pulse 1.1s ease-in-out infinite;
}
@keyframes sd-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .62; } }
/* Единственная строка объяснения, которую §10.3 разрешает на арене — и та,
   что закрывает крупнейшую утечку воронки клипа. */
#clock .byline {
  margin-top: 9px; font-family: var(--font-body); font-size: 11.5px;
  line-height: 1.35; letter-spacing: .02em; color: var(--dim);
  width: 34ch; margin-left: auto; margin-right: auto;
}
/*
 * ── УЗКИЙ ЭКРАН: ТРИ АБСОЛЮТНЫХ БЛОКА ПЕРЕСТАЮТ ПОМЕЩАТЬСЯ ────────────────
 *
 * Карточки бойцов прижаты к краям, часы и подпись — по центру, и ни один из
 * трёх не знает про остальные. При 1440 ширины зазор есть; при 1280 его нет:
 * замерено попарным пересечением прямоугольников — `.byline` лежит на плитке
 * кулдауна (70×24 px), id модели — на часах (112×16). Текст поверх текста.
 *
 * Считать зазор в CSS нечем, поэтому он назначается: карточка это эмблема
 * (100) плюс полоса здоровья, значит при сужении сужается полоса, а подпись
 * перестаёт быть шире того, что осталось посередине.
 *
 * Пороги стоят ВЫШЕ замеренных разрешений, а не на них. Сначала я поставил
 * ровно 1279 — и при 1280 не применилось ничего: точное совпадение с
 * замеренным числом означает, что на этом числе правило уже не действует.
 * Границе нужен запас с той стороны, откуда приходит беда.
 *
 * ВЕРХНЯЯ ГРАНИЦА — 1380, и это решение основателя. Первый порог стоял на
 * 1500 и срабатывал на его собственном экране (1440–1512): сжимался ровно тот
 * боевой экран, который уже утверждён вручную (§10.6) и на 1440 помещается
 * целиком. 1440 — это и есть то разрешение, на котором вёрстку принимали,
 * поэтому граница проходит НИЖЕ него: 1440 и шире не задевается вовсе.
 */
@media (max-width: 1380px) {
  .hprow, .hp { width: 250px; }
  #clock .byline { width: 26ch; }
  .emblem { width: 76px; height: 76px; flex: 0 0 76px; }
}
@media (max-width: 1300px) {
  .hprow, .hp { width: 178px; }
  /*
   * КАРТОЧКЕ НАЗНАЧАЕТСЯ ПРЕДЕЛ, иначе её ширину задаёт содержимое.
   *
   * Полоса здоровья ужалась, а карточка всё равно доставала до центра: её
   * ширину держала строка чипов набора. Замерено при 1280: `#bar-oct` 22→604
   * при часах, начинающихся на 353. Половина минус запас на центр — это и есть
   * «до центра не доставать»; чипы переносятся, а не вылезают.
   */
  .bar-wrap { max-width: calc(50% - 150px); }
  .bar-wrap .col { min-width: 0; }
  .cds { flex-wrap: wrap; }
  /*
   * И ЦЕНТР тоже ограничен. Строка внезапной смерти — самая длинная в игре
   * («арена жжёт обоих, −0.2% в секунду»), и без предела она растягивалась на
   * 574 px, то есть под обе карточки разом. Замерено: `#clock .s` 353→927 при
   * окне 1280. Пусть переносится.
   */
  #clock { max-width: 280px; }
  #clock .s { white-space: normal; }
  /*
   * Строка «чей это бой» переносится вместе с остальными.
   *
   * Замерено при 1280×720: `#whose` пересекался с чипами набора левого бойца
   * на 12×32 px, при 1024×768 — с чипами обеих сторон. Это ровно та строка,
   * которую основатель просил проверить, и печаталась она поверх другого
   * текста на двух самых массовых размерах окна. Внутри iframe GENEX
   * доступная ширина заведомо меньше ширины монитора, то есть попадание в
   * этот случай — норма, а не край.
   */
  #clock .whose { white-space: normal; font-size: 10px; letter-spacing: .12em; }
  #clock .byline { width: 19ch; font-size: 11px; }
  .name { font-size: 18px; }
  .emblem { width: 64px; height: 64px; flex: 0 0 64px; }
}
/*
 * И НИЖЕ 1280 — потому что двумя переломами класс дефекта СДВИГАЕТСЯ, а не
 * закрывается. Замерено той же пробой: 1200 — «.byline × .cd 19×21», 1120 —
 * «59×21», 1024 — два наложения плюс горизонтальная прокрутка (`scrollWidth`
 * 1280 при окне 1024).
 *
 * Ниже 1100 подпись авторства убирается совсем. Она объясняет игре её же
 * правило и стоит места; на узком экране место дороже объяснения, а сам HUD
 * — нет.
 */
@media (max-width: 1180px) {
  .hprow, .hp { width: 150px; }
  /* Ниже 1180 карточки подходят к центру вплотную: строку «чей бой» убираем
     в габарит часов и укорачиваем, иначе она снова ложится на чипы. */
  #clock .whose { font-size: 9.5px; letter-spacing: .08em; }
  #clock .byline { width: 17ch; }
  .bar-wrap { top: 52px; }
  #bar-oct { left: 12px; }
  #bar-gor { right: 12px; }
  /*
   * КАРТОЧКЕ НАЗНАЧАЕТСЯ ПРЕДЕЛ, иначе её ширину задаёт содержимое.
   *
   * Полоса здоровья ужалась до 150, а карточка всё равно доставала до центра:
   * её ширину держала строка чипов набора. Замерено: `#bar-oct` 12→578 при
   * часах, начинающихся на 535.
   *
   * Половина минус запас на часы — это и есть «до центра не доставать».
   * Чипы переносятся, а не вылезают.
   */
}
@media (max-width: 1040px) {
  .hprow, .hp { width: 118px; }
  #clock .byline { display: none; }
  .name { font-size: 15px; }
  .emblem { width: 48px; height: 48px; flex: 0 0 48px; }
}

/* Пока идёт бой, подпись авторства уходит: она нужна тому, кто ещё не понял,
   что смотрит, а не тому, кто уже смотрит. */
/*
 * Подпись про авторство ГАСНЕТ НЕ ДО НУЛЯ.
 *
 * Было `opacity: 0` во время боя. А гость с клипа попадает в СЕРЕДИНУ боя
 * (§10.5: «0–2 с уже идёт бой») — то есть единственное объяснение того, что
 * он видит, показывалось ему только между боями, когда он уже ушёл.
 * Приглушить, чтобы не спорить с ареной, — да; спрятать — нет.
 */
body.fighting #clock .byline { opacity: .38; transition: opacity .6s ease; }

/* лента [эталон] */
#feedwrap { position: absolute; left: 26px; bottom: 20%; width: 400px; }
#feedwrap::before {
  content: ""; position: absolute; left: -20px; top: -14px; width: 330px; bottom: -16px;
  z-index: -1; background: rgba(8, 15, 24, .36); border-radius: 22px; filter: blur(26px);
}
#feed { margin-top: 14px; max-height: 30vh; display: flex; flex-direction: column-reverse; gap: 8px; overflow: hidden; font-size: 14px; font-weight: 500; }
/*
 * Строка ленты — ФЛЕКС, а не поток.
 *
 * Отметка времени была `inline-block` с отступом, и длинный текст переносился
 * ПОД неё: замер по прямоугольникам при 1280 дал наложения «0.0 × прошло под
 * прыжком: 44×19» на каждой такой строке. Метка промаха «прошло под прыжком»
 * — новая (D160), и она первая, которой хватило длины, чтобы это проявилось.
 *
 * Флекс с `min-width: 0` у текста переносит внутри своей колонки и под
 * отметку не залезает.
 */
#feed div { color: var(--ink); letter-spacing: .04em; display: flex; gap: 14px; align-items: baseline; }
#feed div > :not(.ft) { min-width: 0; }
#feed .ft { flex: 0 0 44px; color: var(--dim); font-variant-numeric: tabular-nums; }
#feed b { color: var(--ink); font-weight: 700; }
/* Дайджест закреплён ВНЕ ленты: внутри неё он вытесняется за четыре секунды
   плотного боя, а он — единственный ответ на «что было, пока меня не было». */
#digest { margin-top: 12px; }
#digest .box { padding: 9px 12px; background: rgba(10, 18, 28, .55); border-left: 2px solid var(--oct); }
#digest .hd { font-size: 11px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--oct); }
#digest .ln { font-size: 13px; color: var(--dim); margin-top: 3px; }

#banner {
  position: absolute; inset: 0; display: none; place-items: center; pointer-events: none;
  background: radial-gradient(ellipse at center, #0000 30%, #000a 100%);
}
/* Ниже карточек бойцов: в эталоне они начинались на 20 px, здесь — на 54,
   потому что сверху стоит оболочка вкладок. */
#banner.on { display: grid; align-items: start; padding-top: 19vh; }
#banner .box { text-align: center; background: rgba(8, 14, 22, .85); border: 1px solid rgba(120, 180, 205, .25); padding: 22px 46px; }
#banner .who { font-size: 40px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }
#banner .why { font-size: 12px; font-weight: 500; color: var(--dim); letter-spacing: .22em; text-transform: uppercase; margin-top: 8px; }

#netstate {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: none; padding: 10px 20px; background: rgba(8, 14, 22, .9);
  border: 1px solid rgba(224, 76, 60, .4); color: var(--bad);
  font-size: 13px; letter-spacing: .08em;
}
#netstate.on { display: block; }

/* реплики, цифры урона, неймплейты [эталон]
   Класс НЕ `.say`: пузырь над телом и абзац в карточке — разные вещи, и
   общее имя между ними стоило часа отладки. Пузырь позиционирован в мире и
   несёт translate(-50%,-100%); абзац, унаследовавший этот transform, уезжает
   за левый край панели, оставаясь при этом position:static. */
.saybubble {
  position: absolute; transform: translate(-50%, -100%);
  background: rgba(10, 17, 26, .88); border: 1px solid currentColor;
  padding: 3px 10px; font-size: 12.5px; font-weight: 600; letter-spacing: .04em;
  white-space: nowrap; pointer-events: none;
}
.dmg { position: absolute; transform: translate(-50%, -50%); font-size: 15px; font-weight: 700; pointer-events: none; text-shadow: 0 1px 4px #000c; }
.plate { position: absolute; transform: translate(-50%, -100%); width: 84px; pointer-events: none; }
.plate .t { height: 5px; background: rgba(6, 12, 20, .75); border: 1px solid rgba(0, 0, 0, .5); overflow: hidden; }
.plate .t > i { display: block; height: 100%; background: currentColor; }
.plate .cast { margin-top: 2px; height: 4px; display: none; }
.plate .cast > i { background: #ff4d3d; }
.plate .lab { font-size: 10px; font-weight: 600; line-height: 1.2; letter-spacing: .1em; text-transform: uppercase; text-align: center; color: var(--bad); text-shadow: 0 1px 3px #000; display: none; }
.plate.casting .cast, .plate.casting .lab { display: block; }

#boot {
  position: absolute; inset: 0; display: grid; place-items: center; z-index: 12;
  background: var(--bg-scene); font-size: 12px; letter-spacing: .3em;
  text-transform: lowercase; color: var(--dim);
}
#boot.off { display: none; }
#devsockets { display: none; }

/* ── оболочка вкладок ────────────────────────────────────────────────────── */
#shell {
  position: fixed; top: 0; left: 0; right: 0; height: 42px; z-index: 30;
  display: flex; align-items: center; gap: 26px; padding: 0 22px;
  /* Оболочка лежит НА сцене, а не поверх неё прямоугольником: сверху почти
     непрозрачная, книзу растворяется. */
  background: linear-gradient(180deg, rgba(9, 14, 22, .92), rgba(9, 14, 22, .55) 70%, transparent);
}
#shell .brand {
  font-size: 15px; font-weight: 700; letter-spacing: .3em; text-transform: uppercase;
  color: var(--oct); text-shadow: 0 0 14px rgba(95, 180, 200, .3);
}
#shell .tabs { display: flex; gap: 4px; }
#shell .tab {
  position: relative; padding: 5px 14px; font-size: 12.5px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--dim);
  text-decoration: none; border-bottom: 2px solid transparent;
}
#shell .tab:hover { color: var(--oct); }
#shell .tab.on { color: var(--oct); border-bottom-color: var(--oct); }
#shell .tab .pip {
  display: none; margin-left: 7px; padding: 0 5px; font-size: 10.5px;
  background: rgba(79, 200, 220, .18); color: var(--oct); border: 1px solid rgba(79, 200, 220, .4);
}
#shell .tab .pip.on { display: inline-block; }
#shell .status { margin-left: auto; font-size: 11px; letter-spacing: .1em; color: var(--dim); text-transform: uppercase; }
#shell.hidden { display: none; }

/* ── слой экранов ────────────────────────────────────────────────────────── */
#screen { position: fixed; inset: 42px 0 0; z-index: 20; overflow-y: auto; display: none; }
#screen.on { display: block; }
/* Документ (существо, лестница) закрывает арену; слой (создание, стена) —
   нет: §10.3 требует, чтобы ожидание занимал идущий бой. */
#screen.doc { background: var(--bg-page); }
#screen.veil { background: linear-gradient(180deg, rgba(8, 12, 19, .55), rgba(8, 12, 19, .86)); }

.overlay-card { max-width: 640px; margin: 6vh auto 40px; }

/* ── арена-простой: кольцо ожидания ─────────────────────────────────────── */
#idle {
  position: absolute; left: 50%; bottom: 12%; transform: translateX(-50%);
  text-align: center; z-index: 11;
}
#idle .cd-t { margin-top: 12px; font-size: 12.5px; letter-spacing: .08em; color: var(--dim); font-variant-numeric: tabular-nums; }
#idle .prog { width: 240px; margin: 10px auto 0; }

/* ── таблицы и списки на страницах ──────────────────────────────────────── */
.section { margin: 34px 0 0; }
.section > .hcut { margin-bottom: 12px; }
.cards { display: flex; gap: 14px; flex-wrap: wrap; }
.card {
  position: relative; flex: 1 1 240px; min-width: 240px; padding: 15px 17px;
  background: var(--bg-cell); border: 1px solid var(--line); cursor: pointer;
}
.card.on { border-color: rgba(79, 200, 220, .55); background: #17202e; }
.card .hd { font-size: 14px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--oct); }
.card .why { font-family: var(--font-body); font-size: 13px; color: var(--dim); margin-top: 5px; }
.card .atoms { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 11px; }
/* Описание умения внутри карточки — абзац, а не реплика бойца. `.say` из
   кита несёт `white-space: nowrap` (пузырь над телом не переносится), и
   унаследовать его здесь значит вытолкнуть текст за экран. */
.card .say, .cards .say {
  position: static; transform: none; display: block; white-space: normal; background: none;
  border: none; padding: 0; margin-top: 8px; font-family: var(--font-body);
  font-size: 12.5px; font-weight: 400; letter-spacing: 0; color: var(--dim);
}

.skills { display: flex; flex-direction: column; gap: 12px; }
.skillrow { display: flex; align-items: flex-start; gap: 14px; padding: 11px 14px; background: rgba(21, 27, 40, .55); border-left: 2px solid rgba(79, 200, 220, .35); }
.skillrow .n { font-size: 13px; font-weight: 600; letter-spacing: .1em; color: var(--dim); min-width: 22px; }
.skillrow .body { flex: 1; }
.skillrow .atoms { display: flex; flex-wrap: wrap; gap: 5px; }
.skillrow .say {
  display: block; white-space: normal; background: none; border: none;
  padding: 0; margin-top: 6px; color: var(--dim);
  font-family: var(--font-body); font-size: 13px; font-weight: 400; letter-spacing: 0;
}
.skillrow .cost { font-size: 11px; letter-spacing: .1em; color: var(--dim); text-transform: uppercase; }

.unfit { border-left: 2px solid rgba(224, 179, 76, .5); padding: 12px 16px; background: rgba(30, 26, 14, .35); }
.unfit .ln { font-family: var(--font-body); font-size: 14px; color: var(--gor); margin: 5px 0; }
.unfit .ln b { color: var(--gor); font-weight: 600; }

.jrow { display: grid; grid-template-columns: 96px 1fr 96px; gap: 14px; align-items: baseline; padding: 9px 0; border-top: 1px solid var(--line); }
.jrow .when { font-size: 12px; color: var(--dim); font-variant-numeric: tabular-nums; }
.jrow .what { font-family: var(--font-body); font-size: 13.5px; color: var(--dim); }
.jrow .score { text-align: right; font-size: 13px; font-variant-numeric: tabular-nums; color: var(--oct); }
.jrow.no .score { color: var(--dim); }
/* Строка истории кликабельна — значит обязана выглядеть кликабельной.
   Ряд, который ведёт на повтор боя и ничем этого не показывает, читается
   как таблица, и по нему не жмут. */
.jrow.tap { cursor: pointer; transition: background 120ms; margin: 0 -10px; padding-left: 10px; padding-right: 10px; }
.jrow.tap:hover { background: var(--hover, rgba(127, 127, 127, 0.09)); }
.jrow.tap:hover .what { color: var(--fg); }

.spark { display: block; width: 100%; height: 46px; }

.stages { display: flex; flex-direction: column; gap: 7px; margin-top: 16px; }
.stage { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--dim); letter-spacing: .04em; }
.stage .dot { width: 7px; height: 7px; background: #33414f; flex: 0 0 7px; }
.stage.on { color: var(--ink); }
.stage.on .dot { background: var(--oct); box-shadow: 0 0 8px rgba(79, 200, 220, .7); }
.stage.done { color: var(--dim); }
.stage.done .dot { background: #4a6d78; }

.beats { display: flex; flex-direction: column; gap: 9px; }
.beat { display: grid; grid-template-columns: 52px 1fr; gap: 12px; align-items: baseline; }
.beat .t { font-size: 12.5px; color: var(--dim); font-variant-numeric: tabular-nums; }
.beat .x { font-family: var(--font-body); font-size: 14px; color: var(--ink); }
.beat .x q { color: var(--oct); font-style: normal; }
.beat.or .x q { color: var(--gor); }

/*
 * Предупреждение внутри карточки — не ошибка и не успех, а «читай внимательно».
 * Янтарный, не красный: красным на этом экране отмечены отказы, и смешивать
 * «не получилось» с «получилось не то, что ты думаешь» нельзя.
 */
.note.warn {
  border-left: 2px solid var(--warn, #e0a340);
  background: rgba(224, 163, 64, .07);
  padding: 10px 12px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--gor);
}
.note.warn b { color: var(--gor); font-weight: 600; }


/*
 * Подсказка «как читать бой» — один раз и навсегда убирается.
 *
 * Не панель: панель живёт всегда и отнимает место у арены. Это строчки поверх
 * пола, в углу, которые человек прочитает за пять секунд и закроет.
 */
/* Вспышка кадра (VFX-IR, ось `screen`). Внутри арены и под HUD: это часть
   боя, а не оверлей над интерфейсом. Прозрачность ставит `paintFlash`. */
#vfxflash {
  position: absolute; inset: 0; background: #fff; opacity: 0;
  pointer-events: none; z-index: 4; transition: none;
}

#howto {
  position: fixed; right: 22px; bottom: 92px; z-index: 18;
  display: flex; flex-direction: column; gap: 5px;
  padding: 12px 14px; max-width: 320px;
  background: rgba(12, 19, 29, .92);
  border-left: 2px solid var(--oct);
  font-family: var(--font-body); font-size: 12.5px; color: var(--dim);
}
#howto[hidden] { display: none; }
/*
 * Пока на экране итог боя — легенды нет.
 *
 * Она объясняет, как ЧИТАТЬ бой, и после его конца объясняет нечего; а на
 * узком экране она вдобавок ложилась прямо на числа итога. Замерено при
 * 1024×768: панель итога и легенда перекрывались телами, а не только рамками.
 *
 * Дешевле убрать её на время итога, чем искать ей место: у неё уже есть
 * кнопка «понятно», и человек, дочитавший бой до конца, в ней не нуждается.
 */
body.decided #howto { display: none; }
/*
 * Пока на экране баннер исхода — строки под часами не показываются.
 *
 * `#banner` центрирован по горизонтали и начинается на той же высоте, что
 * подпись под часами: замер по прямоугольникам в состоянии `body.decided`
 * дал «#whose × #banner .box 169×25» при 1280 и «161×28» при 1024, то есть
 * на 1024 строка «чей это бой» накрывалась целиком. Прежний замер этого не
 * нашёл, потому что снимался только во время боя.
 *
 * Прятать правильно именно их: баннер говорит то же самое крупнее и
 * однозначнее, а вернутся они на следующем бое.
 */
body.decided #clock .whose,
body.decided #clock .byline { visibility: hidden; }
/* `flex-start`, а не `center`: строка легенды бывает в две строки, и квадрат
   цвета, повисший посередине абзаца, читается как отдельный элемент, а не как
   его метка. */
#howto .row { display: flex; align-items: flex-start; gap: 8px; line-height: 1.35; }
#howto .row > i { width: 10px; height: 10px; flex: 0 0 10px; display: inline-block; margin-top: 3px; }
#howto .btn { margin-top: 8px; align-self: flex-start; }
