/* Интерфейс «Подпольной печатни».
   Правила системы, которые здесь соблюдаются буквально:
   квадратное по умолчанию, размытых теней нет (объём — смещённая копия),
   зерно поверх всего, билет — единственный яркий предмет в кадре. */

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

/* Страница прибита к экрану. Любая прокрутка body в MiniApp читается
   Telegram как жест «смахнуть приложение вниз». */
html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  overscroll-behavior: none;
}

body {
  position: fixed;
  inset: 0;
}

body {
  background: var(--room-900);
  color: var(--paper-100);
  font: 400 14px/20px var(--font-body);
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

/* ===== Мастерская: свет одной лампы над столом ===== */

.room {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  background:
    radial-gradient(105% 52% at 50% 2%, rgba(255, 224, 150, .10) 0%, rgba(255, 224, 150, 0) 60%),
    radial-gradient(85% 50% at 92% 82%, rgba(255, 61, 151, .15) 0%, rgba(255, 61, 151, 0) 62%),
    radial-gradient(75% 46% at 4% 58%, rgba(47, 91, 255, .14) 0%, rgba(47, 91, 255, 0) 62%),
    var(--room-800);
}

/* Свет сквозь жалюзи. */
.room::before {
  content: "";
  position: absolute;
  inset: -20% -40%;
  background: repeating-linear-gradient(101deg,
    rgba(255, 233, 180, .05) 0 3px, rgba(255, 233, 180, 0) 3px 26px);
  mask-image: radial-gradient(70% 45% at 50% 0%, #000 0%, transparent 72%);
  -webkit-mask-image: radial-gradient(70% 45% at 50% 0%, #000 0%, transparent 72%);
}

/* Зерно: регулярная растровая точка, а не шум. 7% на тёмном. */
.room::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, .07) 1px, transparent 1px);
  background-size: 3px 3px;
}

/* ===== Каркас ===== */

.app {
  position: relative;
  z-index: 1;
  height: 100%;
  max-width: 452px;
  margin: 0 auto;
  padding: 12px var(--space-4) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.screen { display: none; flex: 1 1 auto; min-height: 0; flex-direction: column; gap: var(--space-3); }
.screen[data-active] { display: flex; }

.scroll { overflow-y: auto; -webkit-overflow-scrolling: touch; }

/* ===== Верхняя строка ===== */

.top { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }
.top .coins { margin-right: auto; }

/* Монеты — единственное место, где работает золотой. */
.coins {
  display: flex;
  align-items: baseline;
  gap: 6px;
  padding: 6px 11px;
  border: var(--stroke-hair) solid rgba(255, 198, 26, .34);
  background: rgba(255, 198, 26, .07);
}
.coins b { color: var(--riso-gold); }
.coins span { color: rgba(255, 198, 26, .72); }

.chip-nominal {
  padding: 5px 9px;
  border: var(--stroke-hair) solid var(--room-line);
  background: var(--room-700);
  color: var(--paper-100);
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.chip-nominal:disabled { cursor: default; opacity: .55; }

.iconbtn {
  width: 38px;
  height: 36px;
  display: grid;
  place-items: center;
  padding: 0;
  border: var(--stroke-hair) solid rgba(232, 227, 212, .26);
  background: rgba(232, 227, 212, .05);
  color: var(--paper-100);
  cursor: pointer;
}
.iconbtn[aria-pressed="true"] {
  border-color: var(--riso-gold);
  color: var(--riso-gold);
  background: rgba(255, 198, 26, .1);
}
.iconbtn svg { width: 18px; height: 18px; }

/* ===== Полосы ===== */

.meters { display: grid; gap: 6px; flex-shrink: 0; }
.meter { display: flex; align-items: center; gap: 9px; }
.meter .lbl { color: var(--dim-400); width: 70px; flex-shrink: 0; }
.meter .num { width: 26px; text-align: right; }
.meter .cap { color: var(--dim-400); width: 22px; }

.bar {
  flex-grow: 1;
  height: 4px;
  background: rgba(232, 227, 212, .12);
  border-radius: var(--radius-pill);
  position: relative;
  overflow: hidden;
}
.bar i {
  position: absolute;
  inset: 0 auto 0 0;
  display: block;
  border-radius: var(--radius-pill);
  transition: width .3s cubic-bezier(.2, .8, .2, 1);
}

/* ===== Билет ===== */

.stage { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; padding: 2px 0; }
.stage > .ticket { width: 100%; }

/* Билет целиком не прокручивается и не тянется: стирание идёт вертикально,
   и Telegram иначе принимает его за жест закрытия. */
.ticket {
  touch-action: none;
  position: relative;
  transform: rotate(-.5deg);
  background: var(--paper-100);
  color: var(--ink-900);
  padding: 13px 13px 12px;
  display: flex;
  flex-direction: column;
  gap: 9px;
  /* Объём даёт смещённая копия краски, а не размытие. */
  box-shadow: var(--misreg-3) var(--misreg-3) 0 rgba(13, 11, 16, .55);
}

/* Зерно на бумаге плотнее: 16%, multiply. */
.ticket::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: multiply;
  background-image: radial-gradient(rgba(23, 20, 15, .16) 1px, transparent 1px);
  background-size: 3px 3px;
}

.tkhead { display: flex; align-items: baseline; gap: var(--space-2); position: relative; z-index: 1; }

/* Название партии печатается в две краски со смещением приводки. */
.series { position: relative; display: inline-block; white-space: nowrap; }
.series::after {
  content: attr(data-series);
  position: absolute;
  left: var(--misreg-1);
  top: var(--misreg-1);
  white-space: nowrap;
  color: var(--riso-pink);
  mix-blend-mode: multiply;
  z-index: -1;
}

.nominal { padding: 3px 7px; background: var(--riso-pink); color: #fff; border-radius: var(--radius-sm); }
.serial { margin-left: auto; color: var(--ink-500); }
.perf { border-top: var(--stroke-rule) dashed rgba(23, 20, 15, .38); position: relative; z-index: 1; }

.cells { display: flex; gap: var(--space-2); position: relative; z-index: 1; touch-action: none; cursor: grab; }

.cell {
  flex: 1 1 0;
  position: relative;
  aspect-ratio: 1 / 1.08;
  max-height: 132px;
  background: var(--paper-200);
  overflow: hidden;
  box-shadow: inset 0 0 0 var(--stroke-rule) rgba(23, 20, 15, .55);
}

/* Знак напечатан под краской с самого начала: любой процарапанный след
   уже что-то показывает. */
.glyph { position: absolute; inset: 0; display: grid; place-items: center; }
.glyph svg { width: 60%; height: 60%; overflow: visible; }
.glyph .misreg { transform: translate(var(--misreg-2), 2.5px); mix-blend-mode: multiply; transition: transform .3s ease .14s; }

.cell[data-state="open"] .glyph { animation: print-in .3s cubic-bezier(.2, .9, .25, 1); }
.cell[data-state="open"] .glyph .misreg { transform: translate(0, 0); }

@keyframes print-in {
  0% { transform: scale(.92); }
  55% { transform: scale(1.05); }
  100% { transform: scale(1); }
}

/* Пауза перед решающей ячейкой — механика, а не оформление. */
.cell[data-state="tense"] { animation: tense .62s ease-in-out 1; }
@keyframes tense {
  0%, 100% { box-shadow: inset 0 0 0 var(--stroke-rule) rgba(23, 20, 15, .55), 0 0 0 0 rgba(255, 61, 151, 0); }
  50% { box-shadow: inset 0 0 0 var(--stroke-rule) var(--riso-pink), 0 0 0 5px rgba(255, 61, 151, .45); }
}

.cell canvas.coat { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; transition: opacity .2s linear; }
canvas.chips { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 3; }

/* Штамп садится в угол и не закрывает знаки.
   Он лежит в обычном потоке, в собственной строке: так он не может вылезти
   за край бумаги при повороте, и не надо вычислять, насколько поднимется
   его левый конец. А вылезти нельзя — multiply работает только по бумаге,
   на тёмной мастерской краска уходит в черноту. */
.tkfoot {
  position: relative;
  z-index: 4;
  min-height: 46px;
  margin-top: -4px;
  padding-right: 4px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.stamp {
  transform: rotate(-9deg) scale(.6);
  transform-origin: 50% 50%;
  opacity: 0;
  font: 400 15px/1 var(--font-display);
  letter-spacing: .05em;
  color: var(--riso-blue);
  border: var(--stroke-heavy) solid var(--riso-blue);
  padding: 3px 9px;
  mix-blend-mode: multiply;
  pointer-events: none;
  white-space: nowrap;
}
.stamp.on { animation: slam .45s cubic-bezier(.2, 1.5, .4, 1) forwards; }
@keyframes slam {
  0% { opacity: 0; transform: rotate(-9deg) scale(1.9); }
  60% { opacity: 1; transform: rotate(-9deg) scale(.94); }
  100% { opacity: 1; transform: rotate(-9deg) scale(1); }
}

/* ===== Вердикт и кнопка ===== */

.verdict {
  min-height: 34px;
  display: flex;
  /* Пробел между текстом и числом: флекс выбрасывает пробелы между
     элементами, поэтому зазор задаётся явно. */
  gap: 6px;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--dim-400);
  padding: 2px var(--space-2);
  flex-shrink: 0;
  transition: color .2s;
}
.verdict.near { color: var(--riso-pink); }
.verdict.win { color: var(--riso-gold); }
.verdict b { font: 800 15px/18px var(--font-mono); font-variant-numeric: tabular-nums; }

.print {
  width: 100%;
  min-height: 56px;
  border: 0;
  flex-shrink: 0;
  background: var(--riso-pink);
  color: var(--on-pink);
  font: 400 17px/1 var(--font-display);
  letter-spacing: .05em;
  cursor: pointer;
  /* Смещённая копия вместо тени. */
  box-shadow: 0 5px 0 #b3175f;
}
.print:not(:disabled):active { transform: translateY(4px); box-shadow: 0 1px 0 #b3175f; }
.print:disabled { background: rgba(232, 227, 212, .1); color: rgba(232, 227, 212, .34); box-shadow: none; cursor: default; }

.print.leftovers { background: var(--riso-blue); color: var(--on-blue); box-shadow: 0 5px 0 #1a3bb8; }

:focus-visible { outline: var(--stroke-heavy) solid var(--riso-gold); outline-offset: 3px; }

/* ===== Панели тёмной части ===== */

.panel {
  background: var(--room-700);
  border: var(--stroke-hair) solid var(--room-line);
  padding: var(--space-3);
  display: grid;
  gap: var(--space-2);
}

.panel h2 { margin: 0; color: var(--paper-100); }
.panel .sub { color: var(--dim-400); margin: 0; }

.rowline { display: flex; align-items: baseline; gap: var(--space-2); }
.rowline .grow { flex-grow: 1; }
.num-gold { color: var(--riso-gold); }
.num-blue { color: var(--riso-blue); }

/* Список построек */
.build {
  width: 100%;
  text-align: left;
  display: grid;
  gap: 5px;
  padding: var(--space-3);
  background: var(--room-800);
  border: var(--stroke-hair) solid var(--room-line);
  color: var(--paper-100);
  cursor: pointer;
}
.build[aria-current="true"] { border-color: var(--riso-pink); background: rgba(255, 61, 151, .08); }
.build:disabled { cursor: default; color: var(--dim-400); }
.build .why { color: var(--dim-400); }

/* ===== Нижняя навигация ===== */

.tabs {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-top: var(--stroke-hair) solid var(--room-line);
  margin: 0 calc(var(--space-4) * -1);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.tab {
  padding: 11px 4px;
  background: none;
  border: 0;
  border-top: var(--stroke-key) solid transparent;
  margin-top: -1px;
  color: var(--dim-400);
  font: 400 12px/14px var(--font-display);
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
}
.tab[aria-current="true"] { color: var(--paper-100); border-top-color: var(--riso-pink); }

/* ===== Сообщения ===== */

.notice {
  padding: var(--space-2) var(--space-3);
  border-left: var(--stroke-heavy) solid var(--riso-blue);
  background: var(--room-700);
  color: var(--paper-100);
}
.notice.warn { border-left-color: var(--signal-warn); }
.notice.offline { border-left-color: var(--dim-400); color: var(--dim-400); }

.stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: var(--stroke-hair) solid var(--room-line); flex-shrink: 0; }
.stat { padding: var(--space-2) var(--space-1); text-align: center; }
.stat + .stat { border-left: var(--stroke-hair) solid var(--room-line); }
.stat dt { color: var(--dim-400); }
.stat dd { margin: 3px 0 0; color: var(--paper-100); }

/* Отсчёт до тиража — единственная крупная цифра на своём экране. */
.countdown { text-align: center; padding: var(--space-6) 0 var(--space-4); }
.countdown .val { color: var(--paper-100); display: block; }
.countdown .lbl { color: var(--dim-400); display: block; margin-top: var(--space-2); }

@media (prefers-reduced-motion: reduce) {
  .stamp.on, .cell[data-state="open"] .glyph { animation: none; }
  .cell[data-state="open"] .glyph { transform: none; }
  .stamp.on { opacity: 1; transform: rotate(-9deg); }
  .bar i, .glyph .misreg { transition: none; }
  /* Пауза перед решающей ячейкой не отключается: это правило игры. */
}
