/* ==========================================================================
   Игра «Магнит» — вёрстка четырёх экранов.

   Макет 1080×1920, но фиксированных размеров в разметке нет: вся геометрия
   считается от одной переменной --d («один пиксель макета»). Сцена вписывается
   в экран по короткой стороне и держит пропорцию 9:16 — поэтому одинаково
   выглядит и на телефоне, и на 55" стойке, и не разваливается в ландшафте
   (там просто остаются красные поля по бокам).
   ========================================================================== */

:root {
  /* Ширина сцены: сколько влезло по ширине, но не больше, чем позволяет высота */
  --stage-w: min(100vw, calc(100vh * 9 / 16));
  /* Один «пиксель макета»: 1080 таких пикселей = вся ширина сцены */
  --d: calc(var(--stage-w) / 1080);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", Roboto,
          "Helvetica Neue", Arial, "Liberation Sans", sans-serif;

  --red: #e30a15;          /* фирменный красный Магнита (взят из bg-game.png) */
  --red-dark: #a80812;     /* тени и обводки */
  --yellow: #ffd21e;       /* акцент кнопок, как в референсе */
  --panel: #f2f1ec;        /* светлая плашка: поле, блоки результата */
  --panel-soft: rgba(255, 255, 255, .78); /* полупрозрачная плашка правил */
  --ink: #2b2b2b;          /* основной тёмный текст на светлом */
  --ink-soft: #8a8a8a;     /* второстепенный текст (номера мест) */

  /* Заполняются из JS (GAME_CONFIG), значения ниже — запасные */
  --rows: 7;
  --cols: 5;
  --glow-scale: 1.7;
  --glow-strength: 1;       /* картинка glow крупнее обычной — свечение нарисовано с запасом */
  --fade: 220ms;
  --board-rows: 4;         /* leaderboard.size из конфига */
  --board-k: 1;            /* во сколько ужать строку топа, чтобы влезли все места */
}

/* dvh точнее на мобильных: убирает скачок при появлении адресной строки */
@supports (height: 100dvh) {
  :root { --stage-w: min(100vw, calc(100dvh * 9 / 16)); }
}

* , *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  overflow: hidden;
  background: #6d0309;   /* поля вокруг сцены — тёмно-красные, не чёрные */
}

body {
  position: fixed;       /* вместе с overscroll-behavior убирает «оттяжку» страницы */
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font);
  font-weight: 800;
  color: #fff;
  overscroll-behavior: none;
  touch-action: none;              /* без зума, без двойного тапа, без скролла */
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;     /* без «сохранить картинку» по долгому тапу */
  -webkit-tap-highlight-color: transparent;
  text-rendering: optimizeLegibility;
}

body.kiosk-nocursor, body.kiosk-nocursor * { cursor: none; }

img { -webkit-user-drag: none; user-select: none; pointer-events: none; }

/* ─── Сцена и экраны ─────────────────────────────────────────────────── */

.stage {
  position: relative;
  width: var(--stage-w);
  height: calc(var(--stage-w) * 16 / 9);
  overflow: hidden;
  background: var(--red);
}

/* Все экраны лежат стопкой; активный — тот, чей класс стоит на body.
   Прячем прозрачностью, а не display:none, чтобы работало перелистывание. */
.screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  background-repeat: no-repeat;
  background-position: center top;
  background-size: 100% 100%;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  /* visibility гасим только ПОСЛЕ затухания, а включаем мгновенно: если её
     анимировать, первые кадры нового экрана не ловят касание и быстрый
     повторный тап по стойке пропадает впустую. */
  transition: opacity var(--fade) ease, visibility 0s linear var(--fade);
}
body.screen-attract #screen-attract,
body.screen-rules   #screen-rules,
body.screen-game    #screen-game,
body.screen-result  #screen-result {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity var(--fade) ease, visibility 0s linear 0s;
}

/* фоны подставляет JS из GAME_CONFIG.backgrounds */
/* запасные пути — если JS не успел подставить свои из конфига */
.screen--attract { background-image: var(--bg-attract, url("../assets/bg-attract.png")); }
.screen--rules,
.screen--game,
.screen--result  { background-image: var(--bg-game, url("../assets/bg-game.png")); }

/* Пустые надписи из конфига не занимают места */
[data-text]:empty { display: none; }

/* ─── Общая кнопка ───────────────────────────────────────────────────── */

.btn {
  display: block;
  width: 100%;
  border: calc(6 * var(--d)) solid var(--yellow);
  border-radius: calc(90 * var(--d));
  background: var(--red);
  color: var(--yellow);
  font-family: inherit;
  font-weight: 900;
  font-size: calc(58 * var(--d));
  line-height: 1;
  padding: calc(40 * var(--d)) calc(30 * var(--d));
  box-shadow: 0 calc(10 * var(--d)) calc(30 * var(--d)) rgba(0, 0, 0, .28);
  touch-action: manipulation;
  transition: transform 90ms ease, filter 90ms ease;
}
.btn:active { transform: scale(.97); filter: brightness(1.15); }

/* ─── 1. Аттрактор ───────────────────────────────────────────────────── */

.screen--attract {
  justify-content: space-between;
  padding: calc(120 * var(--d)) calc(70 * var(--d)) calc(110 * var(--d));
  text-align: center;
}
.attract__title {
  font-size: calc(96 * var(--d));
  line-height: 1.05;
  text-transform: uppercase;
  text-shadow: 0 calc(6 * var(--d)) calc(24 * var(--d)) rgba(0, 0, 0, .35);
}
.attract__subtitle {
  margin-top: calc(24 * var(--d));
  font-size: calc(48 * var(--d));
  font-weight: 700;
}
.attract__foot { margin-top: auto; }
.btn--cta {
  background: rgba(255, 255, 255, .96);
  color: var(--red);
  border-color: rgba(255, 255, 255, .96);
  animation: ctaPulse 1.8s ease-in-out infinite;
}
/* Никакого масштабирования: на стойке пляшущая кнопка читается как дребезг.
   Дышим только тенью и яркостью — заметно, но глаз не дёргает. */
@keyframes ctaPulse {
  0%, 100% { box-shadow: 0 calc(10 * var(--d)) calc(30 * var(--d)) rgba(0, 0, 0, .3); filter: brightness(1); }
  50%      { box-shadow: 0 calc(14 * var(--d)) calc(52 * var(--d)) rgba(0, 0, 0, .5); filter: brightness(1.06); }
}

/* ─── 2. Правила ─────────────────────────────────────────────────────── */

.screen--rules {
  padding: calc(250 * var(--d)) calc(70 * var(--d)) calc(90 * var(--d));
}
.rules__title {
  font-size: calc(120 * var(--d));
  font-weight: 900;
  letter-spacing: calc(2 * var(--d));
  text-align: center;
  margin-bottom: calc(46 * var(--d));
  text-shadow: 0 calc(6 * var(--d)) calc(20 * var(--d)) rgba(0, 0, 0, .25);
}
.rules__list {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: calc(30 * var(--d));
  margin-bottom: calc(50 * var(--d));
  min-height: 0;
}
.rule {
  flex: 1 1 0;
  display: flex;
  align-items: center;
  gap: calc(24 * var(--d));
  background: var(--panel-soft);
  border-radius: calc(60 * var(--d));
  padding: calc(30 * var(--d)) calc(44 * var(--d));
  min-height: 0;
}
.rule__text {
  flex: 1 1 auto;
  color: var(--red-dark);
  font-size: calc(44 * var(--d));
  font-weight: 800;
  line-height: 1.22;
}
.rule__img {
  flex: 0 0 auto;
  width: calc(190 * var(--d));
  max-height: 100%;
  object-fit: contain;
}
.rule__badge {
  flex: 0 0 auto;
  background: #fff;
  border: calc(4 * var(--d)) solid rgba(227, 10, 21, .35);
  border-radius: calc(40 * var(--d));
  color: var(--ink);
  font-size: calc(56 * var(--d));
  font-weight: 900;
  padding: calc(14 * var(--d)) calc(38 * var(--d));
  letter-spacing: calc(3 * var(--d));
}

/* ─── 3. Игра ────────────────────────────────────────────────────────── */

.screen--game {
  padding: calc(230 * var(--d)) calc(46 * var(--d)) calc(80 * var(--d));
}
.hud {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: calc(24 * var(--d));
  margin-bottom: calc(30 * var(--d));
}
.hud__cell { display: flex; flex-direction: column; gap: calc(10 * var(--d)); }
.hud__cell--right { align-items: flex-end; }
.hud__label {
  font-size: calc(30 * var(--d));
  font-weight: 700;
  opacity: .85;
  padding: 0 calc(20 * var(--d));
  text-transform: uppercase;
  letter-spacing: calc(2 * var(--d));
}
.plate {
  background: var(--panel);
  border-radius: calc(60 * var(--d));
  box-shadow: 0 calc(8 * var(--d)) calc(24 * var(--d)) rgba(0, 0, 0, .22);
}
.hud__box {
  color: var(--ink);
  font-size: calc(72 * var(--d));
  font-weight: 900;
  line-height: 1;
  padding: calc(28 * var(--d)) calc(48 * var(--d));
  font-variant-numeric: tabular-nums;
  letter-spacing: calc(2 * var(--d));
  min-width: calc(320 * var(--d));
  text-align: center;
}
.hud__box.is-bump { animation: bump 220ms ease; }
@keyframes bump { 50% { transform: scale(1.08); } }

/* Поле: обычная CSS-сетка rows × cols, размеры берёт из --rows/--cols (их ставит JS) */
.field {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  grid-template-rows: repeat(var(--rows), 1fr);
  gap: calc(10 * var(--d));
  padding: calc(26 * var(--d));
  background: var(--panel);
  border-radius: calc(56 * var(--d));
  box-shadow: 0 calc(10 * var(--d)) calc(34 * var(--d)) rgba(0, 0, 0, .25);
  min-height: 0;
}
.cell {
  position: relative;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
}
.cell__normal,
.cell__glow {
  position: absolute;
  left: 50%;
  top: 50%;
  object-fit: contain;
  /* Подсветка обязана появляться мгновенно: любая плавность здесь читается
     как тормоз игры. Гаснет чуть мягче, чтобы не мигало. */
  transition: opacity 60ms linear;
}
.cell__normal {
  width: 100%;
  height: 100%;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 calc(3 * var(--d)) calc(6 * var(--d)) rgba(0, 0, 0, .16));
}
/* Свечение крупнее плашки и вылезает за пределы ячейки — поэтому масштаб и z-index */
.cell__glow {
  width: calc(100% * var(--glow-scale));
  height: calc(100% * var(--glow-scale));
  transform: translate(-50%, -50%);
  opacity: 0;
}
.cell.is-glow { z-index: 2; }
.cell.is-glow .cell__normal { opacity: 0; }
.cell.is-glow .cell__glow {
  opacity: 1;
  /* Ассетное свечение бледнеет на большом экране, поэтому усиливаем его
     двойной красной тенью. Плотность крутится через --glow-strength. */
  filter:
    drop-shadow(0 0 calc(10 * var(--d) * var(--glow-strength)) rgba(225, 0, 25, .95))
    drop-shadow(0 0 calc(26 * var(--d) * var(--glow-strength)) rgba(225, 0, 25, .75));
}
/* Пульсация тоже без transform: раньше картинка ездила туда-сюда и выглядела
   как тряска. Меняем только плотность красного ореола. */
body.pulse-on .cell.is-glow .cell__glow { animation: cellPulse 1100ms ease-in-out infinite; }
@keyframes cellPulse {
  0%, 100% {
    filter:
      drop-shadow(0 0 calc(10 * var(--d) * var(--glow-strength)) rgba(225, 0, 25, .95))
      drop-shadow(0 0 calc(26 * var(--d) * var(--glow-strength)) rgba(225, 0, 25, .75));
  }
  50% {
    filter:
      drop-shadow(0 0 calc(14 * var(--d) * var(--glow-strength)) rgba(225, 0, 25, 1))
      drop-shadow(0 0 calc(38 * var(--d) * var(--glow-strength)) rgba(225, 0, 25, .9));
  }
}
/* Попадание — короткий «щелчок» плашки, промах — лёгкое подрагивание */
.cell.is-hit .cell__normal { animation: hitPop 260ms ease; }
@keyframes hitPop {
  0%   { transform: translate(-50%, -50%) scale(1.18); }
  100% { transform: translate(-50%, -50%) scale(1); }
}
.cell.is-miss .cell__normal { animation: missShake 240ms ease; }
@keyframes missShake {
  25% { transform: translate(-54%, -50%) scale(.94); }
  75% { transform: translate(-46%, -50%) scale(.94); }
}
.game__hint {
  margin-top: calc(20 * var(--d));
  text-align: center;
  font-size: calc(34 * var(--d));
  font-weight: 700;
  opacity: .9;
}

/* ─── 4. Результат ───────────────────────────────────────────────────── */

.screen--result {
  padding: calc(215 * var(--d)) calc(70 * var(--d)) calc(70 * var(--d));
  gap: calc(28 * var(--d));
}
.result__title {
  font-size: calc(78 * var(--d));
  font-weight: 900;
  line-height: 1.1;
  text-align: center;
  text-transform: uppercase;
  white-space: pre-line;          /* \n из конфига = перенос строки */
  text-shadow: 0 calc(6 * var(--d)) calc(20 * var(--d)) rgba(0, 0, 0, .25);
}
.panel {
  background: var(--panel);
  border-radius: calc(56 * var(--d));
  color: var(--ink);
  padding: calc(34 * var(--d)) calc(44 * var(--d)) calc(40 * var(--d));
  box-shadow: 0 calc(10 * var(--d)) calc(30 * var(--d)) rgba(0, 0, 0, .25);
  min-height: 0;
}
/* Таблица лидеров занимает столько, сколько нужно строкам (как в референсе),
   а не растягивается на весь экран: пустая плашка на первом игроке выглядела дырой.
   Длинный топ не обрезаем, а ужимаем строки — см. --board-k из game.js. */
.panel--board { flex: 0 1 auto; overflow: hidden; }
.panel__title {
  text-align: center;
  font-size: calc(52 * var(--d));
  font-weight: 800;
  margin-bottom: calc(22 * var(--d));
}
.result__line {
  text-align: center;
  font-size: calc(42 * var(--d));
  font-weight: 700;
  margin-top: calc(12 * var(--d));
}
.num {
  color: var(--red);
  font-weight: 900;
  font-size: calc(52 * var(--d));
  font-variant-numeric: tabular-nums;
  letter-spacing: calc(2 * var(--d));
}
.board { list-style: none; }
.board__row {
  display: flex;
  align-items: baseline;
  gap: calc(24 * var(--d) * var(--board-k));
  padding: calc(10 * var(--d) * var(--board-k)) calc(20 * var(--d));
  border-radius: calc(28 * var(--d));
}
.board__row + .board__row { margin-top: calc(6 * var(--d) * var(--board-k)); }
.board__row.is-self { background: rgba(227, 10, 21, .10); }
.board__rank {
  flex: 0 0 calc(60 * var(--d) * var(--board-k));
  color: var(--ink-soft);
  font-size: calc(46 * var(--d) * var(--board-k));
  font-weight: 900;
}
.board__score {
  color: var(--red);
  font-size: calc(48 * var(--d) * var(--board-k));
  font-weight: 900;
  font-variant-numeric: tabular-nums;
}
.board__id {
  color: var(--ink);
  font-size: calc(36 * var(--d) * var(--board-k));
  font-weight: 700;
  opacity: .8;
}
.board__empty {
  text-align: center;
  font-size: calc(36 * var(--d));
  font-weight: 700;
  color: var(--ink-soft);
  padding: calc(16 * var(--d)) 0;
}
.prize {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(28 * var(--d));
}
.prize__img {
  width: calc(190 * var(--d));
  object-fit: contain;
}
.prize__title {
  font-size: calc(44 * var(--d));
  font-weight: 900;
  color: var(--red);
  text-align: left;
}
.btn--finish { margin-top: auto; }

/* ─── Мелкие экраны и ландшафт ───────────────────────────────────────── */
/* Сцена держит пропорцию сама, но в ландшафте она узкая: убираем лишний
   «воздух», чтобы поле оставалось крупным. */
@media (orientation: landscape) {
  .screen--rules  { padding-top: calc(230 * var(--d)); }
  .screen--game   { padding-top: calc(215 * var(--d)); }
  .screen--result { padding-top: calc(200 * var(--d)); }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
