html {
  height: 100%;
  overflow: hidden;
}

body.game-page {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  gap: 12px;
  padding: 14px 16px;
}

/* В настоящем полноэкранном режиме убираем внешние поля и ограничение
   ширины: карта занимает всё окно, а не центрированную колонку 1200 px. */
html:fullscreen body.game-page {
  padding: 0;
  gap: 0;
}
html:fullscreen body.game-page .game-wrap {
  max-width: none;
}
html:fullscreen body.game-page .site-head {
  padding: 8px 14px;
}

body.game-page .site-head {
  width: 100%;
  /* Отступ до сцены даёт gap у body.game-page. */
  margin-bottom: 0;
}

body.game-page .brand {
  width: auto;
  max-width: none;
  margin: 0;
  gap: 9px;
  justify-content: flex-start;
  text-decoration: none;
}

/* В подземелье меню сайта убрано — шапка стала одной невысокой строкой,
   и освободившиеся пиксели уходят сцене. Название ведёт на главную. */
body.game-page .brand .logo {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  font-size: 15px;
}

body.game-page .brand h1 {
  font-size: 16px;
}

body.game-page .stage {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
}

body.game-page .game-wrap {
  align-self: stretch;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

body.game-page .game-wrap > .panel {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
}

.stage {
  width: 100%;
  display: flex;
  gap: 16px;
  align-items: stretch;
}

.stage.playing {
  height: 100%;
}

/* Бой показывается настоящим оверлеем (position: fixed), поэтому колонка
   больше не занимает четверть экрана: сама она из раскладки выпадает, а её
   содержимое — модальное окно — позиционируется от вьюпорта. */
.battle-col {
  min-width: 0;
  display: contents;
}

.stage.playing .game-wrap {
  flex: 1 1 auto;
  min-width: 0;
}

.side-panel {
  flex: 0 0 20%;
  max-width: 20%;
}

#screen-game .map-scroll {
  height: auto;
  flex: 1 1 auto;
  min-height: 220px;
}

.map-scroll .game-msg {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  min-height: 0;
  padding: 4px 12px;
  border-radius: 999px;
  background: rgba(4, 7, 15, 0.8);
  border: 1px solid #1d2f4c;
  z-index: 6;
  white-space: nowrap;
}

.side-card {
  background: #101d31;
  border: 1px solid #263a5c;
  border-radius: var(--radius);
  padding: 12px;
}

.side-panel .hud,
.side-panel .equip-bar {
  flex-direction: column;
  gap: 10px;
}

.side-panel .hud-block,
.side-panel .equip-slot {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
}

.side-panel .inventory {
  max-width: none;
}

.map-scroll .log {
  position: absolute;
  left: 10px;
  bottom: 44px;
  width: min(340px, 62%);
  max-height: 30%;
  margin: 0;
  background: rgba(4, 7, 15, 0.85);
  border: 1px solid #1d2f4c;
  border-radius: 10px;
  padding: 8px 10px;
  z-index: 6;
  animation: cardIn 0.18s ease;
}

.map-scroll .log.collapsed {
  display: none;
}

.side-panel {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
  overflow-y: auto;
}

.side-info {
  background: #101d31;
  border: 1px solid #263a5c;
  border-radius: var(--radius);
  padding: 18px;
  color: #9fb3d1;
}

.side-info h3 {
  margin: 0 0 8px;
  color: #f1f5f9;
  font-size: 16px;
}

.side-info p {
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.5;
}

.side-hint {
  color: #7dd3fc;
}

.game-wrap {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  min-width: 0;
}

@media (max-width: 980px) {
  .stage.playing {
    flex-direction: column;
  }
  .side-panel,
  .stage.playing .game-wrap {
    flex: 1 1 auto;
    max-width: none;
    width: 100%;
  }
}

/* ---------- Панель игры (тёмное фэнтези) ---------- */
.panel {
  background: #101d31;
  border: 1px solid #263a5c;
  border-radius: var(--radius);
  box-shadow: 0 24px 60px rgba(2, 6, 23, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  padding: 22px;
  color: #e6edf7;
}

.panel h2 {
  color: #f1f5f9;
}

.panel .lead,
.panel .facts li {
  color: #9fb3d1;
}

.panel .field {
  color: #cbd5e1;
}

.panel input[type="text"] {
  background: #0e1a2f;
  border-color: #2a3b5a;
  color: #e6edf7;
}

.panel input[type="text"]:focus {
  border-color: var(--gold);
  box-shadow: 0 0 0 3px rgba(246, 196, 83, 0.15);
}

.panel .mode {
  background: #0e1a2f;
  border-color: #2a3b5a;
}

.panel .mode b {
  color: #e6edf7;
}

.panel .mode span {
  color: #8ea3c0;
}

.panel .mode:hover {
  border-color: #3b5175;
}

.panel .mode.active {
  border-color: var(--gold);
  background: rgba(246, 196, 83, 0.12);
  box-shadow: 0 0 0 3px rgba(246, 196, 83, 0.12);
}

/* ---------- HUD ---------- */
.hud {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
}

.hud-block {
  min-width: 140px;
  flex: 1 1 160px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid #223451;
  border-radius: 12px;
  padding: 10px 12px;
}

.hud-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: #8296b5;
  font-weight: 800;
  margin-bottom: 6px;
}

.hp-bar {
  height: 15px;
  border-radius: 999px;
  background: #0a1425;
  overflow: hidden;
  box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.6);
}

.hp-bar > i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: #3aa06a;
  box-shadow: 0 0 10px rgba(74, 222, 128, 0.55);
  transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}

.hp-bar.enemy > i {
  background: #c9453f;
  box-shadow: 0 0 10px rgba(248, 113, 113, 0.55);
}

.hp-bar.low > i {
  animation: lowHp 1s ease-in-out infinite;
}

.hp-bar.hurt > i {
  animation: hpFlashHurt 0.5s ease;
}

.hp-bar.heal > i {
  animation: hpFlashHeal 0.5s ease;
}

@keyframes hpFlashHurt {
  0%, 100% { filter: brightness(1); }
  40% { filter: brightness(2.1) saturate(2) hue-rotate(-18deg); }
}

@keyframes hpFlashHeal {
  0%, 100% { filter: brightness(1); }
  40% { filter: brightness(1.7) saturate(1.7); }
}

@keyframes lowHp {
  0%, 100% { filter: brightness(1); }
  50% { filter: brightness(1.6) saturate(1.4); }
}

.xp-bar {
  height: 7px;
  border-radius: 999px;
  background: #0a1425;
  overflow: hidden;
  margin-top: 7px;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.6);
}

.xp-bar > i {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: #8b5cf6;
  box-shadow: 0 0 8px rgba(168, 85, 247, 0.6);
  transition: width 0.35s ease;
}

.hud-num {
  font-size: 13px;
  color: #9fb3d1;
  margin-top: 5px;
  font-weight: 700;
}

.floor-name {
  font-weight: 800;
  font-size: 15px;
  color: #f6c453;
}

/* ---------- Панель экипировки ---------- */
.equip-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-bottom: 14px;
}

.equip-slot {
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid #223451;
  border-radius: 11px;
  padding: 8px 13px;
  min-width: 122px;
  font-size: 13px;
}

.equip-label {
  display: block;
  color: #8296b5;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  font-weight: 800;
  margin-bottom: 3px;
}

.equip-value {
  font-weight: 700;
  color: #e6edf7;
}

/* ---------- Особые эффекты предметов ---------- */
/* Список отвечает на вопрос «что вообще сейчас работает на герое»:
   без него игрок видит только названия предметов и не понимает,
   что вампиризм или шипы уже включены. */
.effect-list:empty {
  display: none;
}

.effect-list {
  margin-top: 12px;
  border-top: 1px solid #223451;
  padding-top: 10px;
}

.effect-title {
  color: #8296b5;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  font-weight: 800;
  margin-bottom: 7px;
}

.effect-row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 12.5px;
  color: #cdd9ea;
  padding: 3px 0;
}

.effect-num {
  margin-left: auto;
  color: #8fa6c4;
  font-variant-numeric: tabular-nums;
  font-size: 11.5px;
  white-space: nowrap;
}

.effect-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: 0 0 auto;
  align-self: center;
  background: #60a5fa;
}

/* У каждого семейства эффектов свой цвет — так строку узнают боковым зрением. */
.effect-dot.lifesteal { background: #f87171; }
.effect-dot.crit { background: #fbbf24; }
.effect-dot.block { background: #38bdf8; }
.effect-dot.thorns { background: #a78bfa; }
.effect-dot.hintFree { background: #34d399; }
.effect-dot.poisonImmune { background: #4ade80; }
.effect-dot.reveal { background: #e879f9; }
.effect-dot.execute { background: #fb923c; }
.effect-dot.goldBonus { background: #facc15; }
.effect-dot.cleanse,
.effect-dot.fullHeal,
.effect-dot.antidote { background: #2dd4bf; }

/* ---------- Всплывающее уведомление об эффекте ---------- */
.effect-flash {
  position: fixed;
  left: 50%;
  bottom: 88px;
  transform: translate(-50%, 10px);
  z-index: 90;
  padding: 9px 18px;
  border-radius: 999px;
  border: 1px solid #2f4a6d;
  background: rgba(9, 16, 30, 0.94);
  color: #e6edf7;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.2px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);
  opacity: 0;
  pointer-events: none;
  white-space: nowrap;
  max-width: min(90vw, 460px);
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Текст пуст — показывать нечего, иначе останется висеть пустая капсула. */
.effect-flash:empty {
  display: none;
}

.effect-flash.show {
  animation: effectFlash 2s ease forwards;
}

@keyframes effectFlash {
  0% { opacity: 0; transform: translate(-50%, 12px) scale(0.96); }
  12% { opacity: 1; transform: translate(-50%, 0) scale(1); }
  75% { opacity: 1; transform: translate(-50%, 0) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -14px) scale(0.98); }
}

/* Уважаем настройку «меньше движения»: показываем без подъёма и масштаба. */
@media (prefers-reduced-motion: reduce) {
  .effect-flash.show {
    animation: effectFlashFade 1.6s ease forwards;
  }
  @keyframes effectFlashFade {
    0% { opacity: 0; }
    15% { opacity: 1; }
    80% { opacity: 1; }
    100% { opacity: 0; }
  }
}

/* ---------- Карта ---------- */
.map-scroll {
  width: 100%;
  height: clamp(300px, 58vh, 640px);
  overflow: hidden;
  position: relative;
  border-radius: 16px;
  margin-bottom: 16px;
  cursor: grab;
  background: #04070f;
}

.map-scroll:active {
  cursor: grabbing;
}

.map {
  --pad: 10px;
  /* Плитки идут встык. Зазор в 2 px и скруглённые «подушки» превращали
     пещеру в кафельный пол — у тайлов DCSS края рассчитаны на стык. */
  --gap: 0px;
  --cell: 32px;
  --floor-a: #1c2c47;
  --floor-b: #101b31;
  --wall-a: #2a3d5c;
  --wall-b: #1b2841;
  --glow: rgba(59, 130, 246, 0.12);
  position: absolute;
  left: 0;
  top: 0;
  margin: 0;
  transform-origin: 0 0;
  will-change: transform;
  transition: transform 0.16s ease;
  background: #060c18;
  border: 1px solid #1d2f4c;
  border-radius: 16px;
  padding: var(--pad);
  width: fit-content;
  box-shadow: inset 0 0 40px rgba(0, 0, 0, 0.7), 0 10px 30px rgba(0, 0, 0, 0.4);
}

/* Темы этажей */
.map[data-theme="0"] { --floor-a:#22345a; --floor-b:#14213c; --wall-a:#131a2e; --wall-b:#0b1220; --glow:rgba(59,130,246,.14); }
.map[data-theme="1"] { --floor-a:#40341f; --floor-b:#251d0d; --wall-a:#1f170c; --wall-b:#120d06; --glow:rgba(212,169,90,.14); }
.map[data-theme="2"] { --floor-a:#37411f; --floor-b:#20260f; --wall-a:#181d0b; --wall-b:#0e1106; --glow:rgba(132,204,22,.14); }
.map[data-theme="3"] { --floor-a:#214536; --floor-b:#122a1f; --wall-a:#0e1c15; --wall-b:#070f0b; --glow:rgba(16,185,129,.16); }
.map[data-theme="4"] { --floor-a:#2a4c6c; --floor-b:#16304a; --wall-a:#101e2c; --wall-b:#080f16; --glow:rgba(56,189,248,.18); }
.map[data-theme="5"] { --floor-a:#46432a; --floor-b:#2b2813; --wall-a:#1c1a0c; --wall-b:#0f0d05; --glow:rgba(234,179,8,.14); }
.map[data-theme="6"] { --floor-a:#4a2323; --floor-b:#2b1212; --wall-a:#1c0c0c; --wall-b:#0f0606; --glow:rgba(239,68,68,.18); }
.map[data-theme="7"] { --floor-a:#36365c; --floor-b:#1d1d34; --wall-a:#141422; --wall-b:#0a0a14; --glow:rgba(148,163,184,.14); }
.map[data-theme="8"] { --floor-a:#422a6e; --floor-b:#261747; --wall-a:#180f28; --wall-b:#0c0714; --glow:rgba(168,85,247,.18); }
.map[data-theme="9"] { --floor-a:#572020; --floor-b:#330e0f; --wall-a:#1e0b0c; --wall-b:#100505; --glow:rgba(220,38,38,.2); }

/* Деревня: светлая трава и каменные дома — мирный уровень, а не этаж.
   Тона заданы отдельной темой, потому что тема этажа считается из номера
   этажа, а у деревни номера нет. */
.map[data-theme="village"] { --floor-a:#5a5340; --floor-b:#3a3527; --wall-a:#4a4436; --wall-b:#2b271e; --glow:rgba(250,204,21,.10); }

/* В деревне нечего пропускать, нечего покупать в лавке подземелья и нечего
   ковать: её собственные действия живут в окнах НПС. Шапка с этими кнопками
   лежит ВНЕ .stage, поэтому цепляемся к ней через :has(.stage.village). */
body.game-page:has(.stage.village) #skip-btn,
body.game-page:has(.stage.village) #shop-btn,
body.game-page:has(.stage.village) #forge-btn,
.stage.village #map-vignette {
  display: none;
}

/* В деревне неоткрытое — не чёрный провал, как в подземелье, а приглушённая
   земля: уровень светлый, и резкий чёрный край читался бы дырой в карте. */
body.game-page:has(.stage.village) .tile.unseen {
  background-color: #101a2e;
}

/* Боковая панель деревни показывает банк и амулеты, а не здоровье похода:
   в деревне герой ещё не в подземелье, и HP/снаряжение тут ни о чём. */#village-info { display: none; }
.stage.village #village-info { display: block; }
.stage.village .side-panel .hud,
.stage.village .side-panel .equip-bar,
.stage.village .side-panel #inventory-card,
.stage.village .side-panel #effect-list { display: none; }
.village-bank .lead { margin: 4px 0; }

/* Памятка наставника — просто список, без карточек. */
.mentor-list { margin: 8px 0 12px; padding-left: 18px; }
.mentor-list li { margin: 6px 0; font-size: 14px; line-height: 1.4; color: #cbd5e1; }

.map.no-cam-anim {
  transition: none;
}

.minimap {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 184px;
  height: 132px;
  background: rgba(4, 7, 15, 0.85);
  border: 1px solid #2a3b5a;
  border-radius: 10px;
  z-index: 6;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
  cursor: pointer;
}

.minimap.off {
  display: none;
}

.cam-hint {
  position: absolute;
  right: 10px;
  bottom: 8px;
  font-size: 11px;
  color: #9fb3d1;
  background: rgba(6, 12, 24, 0.72);
  border: 1px solid #1d2f4c;
  border-radius: 999px;
  padding: 3px 10px;
  pointer-events: none;
  z-index: 5;
}

/* Кнопка действия у объекта на карте: сундук, торговец, лестница.
   Появляется, когда герой стоит на клетке объекта или рядом с ней. */
.action-btn {
  position: absolute;
  left: 50%;
  bottom: 64px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  color: #08131f;
  background: #f6c453;
  border: 1px solid #ffdf9b;
  border-radius: 999px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45);
  cursor: pointer;
  z-index: 30;
  animation: actionBob 1.9s ease-in-out infinite;
}
.action-btn:hover {
  filter: brightness(1.08);
}
.action-btn .action-icon {
  font-size: 16px;
  line-height: 1;
}
.action-btn .action-key {
  font-size: 11px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 5px;
  background: rgba(8, 19, 31, 0.22);
}
.action-btn.locked {
  background: #3f4d63;
  color: #cfe0f5;
  border-color: #556b8c;
  animation: none;
}

/* Пропуск хода. Стоит справа внизу и не перекрывает кнопку действия:
   та появляется по центру только рядом с сундуком, торговцем, лестницей. */
.skip-btn {
  left: auto;
  right: 18px;
  bottom: 64px;
  transform: none;
  color: #cfe0f5;
  /* Ожидание хода — тихая стальная кнопка, а не цветное пятно поверх карты. */
  background: rgba(9, 18, 32, 0.88);
  border-color: rgba(125, 162, 217, 0.32);
  animation: none;
}
.skip-btn:hover {
  color: #f6c453;
  border-color: rgba(246, 196, 83, 0.5);
  background: rgba(14, 26, 45, 0.94);
}
.skip-btn .action-icon {
  font-size: 15px;
}
@keyframes actionBob {
  0%, 100% { transform: translate(-50%, 0); }
  50% { transform: translate(-50%, -4px); }
}
@media (prefers-reduced-motion: reduce) {
  .action-btn { animation: none; }
}

.tiles {
  display: grid;
  gap: var(--gap);
}
.entities {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.entity {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--cell);
  height: var(--cell);
  display: grid;
  place-items: center;
  transition: transform 0.16s ease, opacity 0.25s ease;
  will-change: transform;
}

.entity.no-anim {
  transition: none !important;
}

/* Плитка, в которую герой идёт по клику. */
.tile.walk-target {
  box-shadow: inset 0 0 0 2px rgba(56, 189, 248, 0.9);
  animation: walk-target-pulse 0.9s ease-in-out infinite;
}

@keyframes walk-target-pulse {
  0%, 100% {
    box-shadow: inset 0 0 0 2px rgba(56, 189, 248, 0.9);
  }
  50% {
    box-shadow: inset 0 0 0 2px rgba(56, 189, 248, 0.35);
  }
}

.tile {
  position: relative;
  width: var(--cell);
  height: var(--cell);
  display: grid;
  place-items: center;
  font-weight: 800;
  font-size: 16px;
  user-select: none;
  overflow: hidden;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  /* Тайлы нарисованы в 32 px, а клетка крупнее (48 px при обычном зуме):
     растягиваем без сглаживания, иначе камень превращается в мыло. */
  image-rendering: pixelated;
  /* Раньше здесь были ещё background и transform: на 660 плиток браузер
     держал 1980 переходов и пересчитывал их при каждой смене классов.
     Плавность даёт только opacity — её и оставляем. */
  transition: opacity 0.15s;
}

.tile.unseen {
  background-color: #04070f;
  box-shadow: none;
}

/* Раньше у каждой клетки пола была тень по краю — «подушка». Теперь тень
   только там, где пол упирается в стену: классы edge-n/e/s/w ставит
   renderTiles. Она же держит границу в темах, где пол и стена одного тона. */
.tile.floor {
  background-color: var(--floor-a);
  --ed-n: 0 0 0 0 transparent;
  --ed-e: 0 0 0 0 transparent;
  --ed-s: 0 0 0 0 transparent;
  --ed-w: 0 0 0 0 transparent;
  box-shadow: var(--ed-n), var(--ed-e), var(--ed-s), var(--ed-w);
}

.tile.floor.edge-n { --ed-n: inset 0 calc(var(--cell) * 0.3) calc(var(--cell) * 0.22) calc(var(--cell) * -0.22) rgba(0, 0, 0, 0.62); }
.tile.floor.edge-e { --ed-e: inset calc(var(--cell) * -0.3) 0 calc(var(--cell) * 0.22) calc(var(--cell) * -0.22) rgba(0, 0, 0, 0.62); }
.tile.floor.edge-s { --ed-s: inset 0 calc(var(--cell) * -0.3) calc(var(--cell) * 0.22) calc(var(--cell) * -0.22) rgba(0, 0, 0, 0.62); }
.tile.floor.edge-w { --ed-w: inset calc(var(--cell) * 0.3) 0 calc(var(--cell) * 0.22) calc(var(--cell) * -0.22) rgba(0, 0, 0, 0.62); }

.tile.wall {
  background-color: var(--wall-a);
}

/* Визуал уровней: свет от воды, лавы и фонарей.
   Раньше здесь были цветные пятна поверх процедурных тайлов — теперь тайлы
   готовые (terrain.js), а псевдоэлемент отвечает только за свет. */
.tile.lit-water::after,
.tile.lit-lava::after,
.tile.lit-light::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
}

.tile.lit-water::after {
  background: radial-gradient(60% 60% at 50% 54%, rgba(125, 211, 252, 0.3), transparent 70%);
}

.tile.lit-lava::after {
  background: radial-gradient(62% 62% at 50% 52%, rgba(255, 176, 64, 0.42), transparent 72%);
  animation: lava-glow 2.8s ease-in-out infinite;
}

.tile.lit-light::after {
  background: radial-gradient(58% 58% at 50% 50%, rgba(255, 214, 130, 0.5), transparent 70%);
  animation: torch-flicker 2.3s ease-in-out infinite;
}

@keyframes torch-flicker {
  0%, 100% { opacity: 0.75; }
  38% { opacity: 1; }
  62% { opacity: 0.62; }
}

@keyframes lava-glow {
  0%, 100% { opacity: 0.62; }
  50% { opacity: 0.95; }
}

/* Дымка по краю зрения: центр — герой, радиус считается в клетках, поэтому
   на любом зуме фонарь светит одинаково. */
.map-vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
  background: radial-gradient(circle at var(--fx, 50%) var(--fy, 50%),
    rgba(0, 0, 0, 0) 0,
    rgba(0, 0, 0, 0) calc(var(--cell) * 5.5),
    rgba(0, 0, 0, 0.3) calc(var(--cell) * 9),
    rgba(0, 0, 0, 0.55) calc(var(--cell) * 14));
}

/* Вход на этаж: карта наплывает и на миг светлеет. */
.tiles.floor-in {
  animation: floor-in 0.6s ease-out;
}

@keyframes floor-in {
  0% { opacity: 0.35; filter: brightness(1.5) saturate(1.15); }
  100% { opacity: 1; filter: none; }
}

@media (prefers-reduced-motion: reduce) {
  .tile.lit-lava::after,
  .tile.lit-light::after,
  .tiles.floor-in {
    animation: none;
  }
}

.tile.unseen {
  background-color: #04070f;
  box-shadow: none;
}

.tile.seen {
  /* filter: saturate(.6) снят: на открытом этаже фильтр висел на сотнях
     плиток и стоил ~1.2 мс на кадр. Затемнения достаточно. */
  opacity: 0.46;
}

.ent {
  line-height: 1;
  display: inline-block;
}

/* Герой */
@keyframes firstGoalPulse {
  0%, 100% { filter: drop-shadow(0 0 0 rgba(246, 196, 83, 0)); }
  50% { filter: drop-shadow(0 0 9px rgba(246, 196, 83, 0.95)); }
}
.ent-npc.first-goal {
  animation: firstGoalPulse 1.5s ease-in-out infinite;
}

.ent-player {
  width: calc(var(--cell) * 0.72);
  height: calc(var(--cell) * 0.72);
  filter: drop-shadow(0 0 6px rgba(246, 196, 83, 0.85)) drop-shadow(0 2px 2px rgba(0, 0, 0, 0.5));
  animation: pop 0.2s ease;
}

/* Герой и жители тоже дышат. Анимация на картинке, а не на клетке: у
   клетки бывают свои filter/transform, и они бы спорили. */
.ent-player .sprite-img,
.ent-npc .sprite-img {
  animation: enemyIdle var(--idle-dur, 2.6s) ease-in-out infinite;
  animation-delay: var(--idle-delay, 0s);
  transform-origin: 50% 100%;
}

.ent-svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Герой и враги на карте — готовые спрайты 32×32 вместо SVG-иконок.
   Размер задаёт сам .ent (доля клетки), картинка просто заполняет его. */
.ent .sprite-img {
  width: 100%;
  height: 100%;
  display: block;
  image-rendering: pixelated;
}

@keyframes pop {
  0% { transform: scale(0.7); }
  60% { transform: scale(1.12); }
  100% { transform: scale(1); }
}

/* Враги */
.ent-enemy {
  width: calc(var(--cell) * 0.78);
  height: calc(var(--cell) * 0.78);
  filter: drop-shadow(0 0 5px var(--c, #64748b)) drop-shadow(0 2px 2px rgba(0, 0, 0, 0.5));
  animation: enemyIdle var(--idle-dur, 2.6s) ease-in-out infinite;
  animation-delay: var(--idle-delay, 0s);
}

/* Только сдвиг на целые пиксели: scale() давал дробный масштаб пиксель-арта,
   и спрайт на каждом такте «дышал» неровными пикселями. */
@keyframes enemyIdle {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-2px); }
}

.ent-enemy.boss {
  width: calc(var(--cell) * 0.98);
  height: calc(var(--cell) * 0.98);
  filter: drop-shadow(0 0 11px var(--c, #dc2626)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.55));
}

/* Дракон на карте вдвое крупнее: раньше босс был размером с крысу.
   scale — отдельное свойство, оно складывается с transform анимации покоя;
   ×2 — целый масштаб, пиксели остаются чёткими. */
.ent-enemy.boss.ent-px {
  scale: 2;
}

.ent-enemy.elite {
  width: calc(var(--cell) * 0.9);
  height: calc(var(--cell) * 0.9);
  filter: drop-shadow(0 0 8px rgba(250, 204, 21, 0.95)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.55));
}

/* Страж лестницы: голубое свечение — того же цвета, что лестница на
   мини-карте, чтобы было видно, что он её и держит. Светлый контур плюс
   широкий ореол: одного мягкого ореола на тёмном полу было не видно. */
.ent-enemy.guard {
  filter: drop-shadow(0 0 2px rgba(186, 230, 253, 1)) drop-shadow(0 0 9px rgba(56, 189, 248, 0.95))
    drop-shadow(0 2px 3px rgba(0, 0, 0, 0.55));
}

/* Отряд: группа на одной клетке. Иконка чуть меньше, а по краю —
   красная кайма, чтобы игрок видел: здесь не один монстр. */
.ent-enemy.squad {
  width: calc(var(--cell) * 0.82);
  height: calc(var(--cell) * 0.82);
  filter: drop-shadow(0 0 5px var(--c, #64748b)) drop-shadow(0 0 2px rgba(239, 68, 68, 0.9)) drop-shadow(0 2px 2px rgba(0, 0, 0, 0.5));
}

/* Пиксель-арт — герой, враги, лестницы и ловушки-тайлы — занимает клетку
   целиком. Клетка 32/64/96 px, то есть ×1, ×2, ×3 от нарисованных 32 px:
   пиксели остаются квадратными. Доли клетки выше (0.72, 0.9, 0.98) давали
   дробный масштаб. Элиту, отряд и босса отличает свечение и метка, а не
   размер. SVG-иконки (сундук, торговец) по-прежнему заданы долей клетки. */
.ent.ent-px {
  width: var(--cell);
  height: var(--cell);
}

/* Метка дальнобойного: маленький прицел, сдвинутый в угол клетки. */
.ent-marker {
  width: calc(var(--cell) * 0.4);
  height: calc(var(--cell) * 0.4);
  opacity: 0.92;
  filter: drop-shadow(0 0 4px rgba(244, 114, 182, 0.9));
  animation: none;
}

.ent-marker.ranged {
  margin-left: calc(var(--cell) * 0.52);
  margin-top: calc(var(--cell) * -0.52);
}

/* Метка стража лестницы: щит в нижнем углу (прицел дальнобойного — в верхнем). */
.ent-marker.guard {
  margin-left: calc(var(--cell) * 0.52);
  margin-top: calc(var(--cell) * 0.52);
  filter: drop-shadow(0 0 4px rgba(56, 189, 248, 0.95));
}

/* Сундук */
.ent-treasure {
  width: calc(var(--cell) * 0.66);
  height: calc(var(--cell) * 0.66);
  filter: drop-shadow(0 0 8px rgba(251, 191, 36, 0.9));
  animation: treasurePulse 1.6s ease-in-out infinite;
}

/* Ловушка намеренно тихая: не светится и не пульсирует, чтобы её
   замечали по неровности пола, а не по фонарю. */
.ent-trap {
  width: calc(var(--cell) * 0.46);
  height: calc(var(--cell) * 0.46);
  opacity: 0.3;
  filter: grayscale(0.55) brightness(0.68) drop-shadow(0 1px 1px rgba(0, 0, 0, 0.45));
  animation: none;
}

.ent-trap.spent {
  opacity: 0.12;
  filter: grayscale(0.85);
  animation: none;
}

/* Сундук и ловушки-тайлы мерцают свечением, а не размером: дробный scale
   размывал пиксель-арт на каждом такте. */
.ent-treasure.ent-px {
  animation: treasureGlow 1.6s ease-in-out infinite;
}

.ent-trap.ent-px:not(.spent) {
  animation: none;
}

/* Мешочек с добычей: заметная награда, но не сундук. */
.ent-bag {
  width: calc(var(--cell) * 0.58);
  height: calc(var(--cell) * 0.58);
  filter: drop-shadow(0 0 5px rgba(242, 193, 78, 0.55)) drop-shadow(0 2px 2px rgba(0, 0, 0, 0.5));
  animation: bagBob 2.2s ease-in-out infinite;
}

/* Пиксельный мешочек сохраняет свой размер, а не растягивается на клетку. */
.ent.ent-bag.ent-px {
  width: calc(var(--cell) * 0.58);
  height: calc(var(--cell) * 0.58);
}

@keyframes bagBob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-2px); }
}

@keyframes treasureGlow {
  0%, 100% { filter: drop-shadow(0 0 6px rgba(251, 191, 36, 0.8)); }
  50% { filter: drop-shadow(0 0 12px rgba(251, 191, 36, 1)) brightness(1.2); }
}

@keyframes trapGlow {
  0%, 100% { filter: drop-shadow(0 0 3px var(--c, #f87171)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.5)); }
  50% { filter: drop-shadow(0 0 9px var(--c, #f87171)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.5)); }
}

@keyframes trapPulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.1); }
}

/* Торговец */
.ent-trader {
  width: calc(var(--cell) * 0.8);
  height: calc(var(--cell) * 0.8);
  filter: drop-shadow(0 0 8px rgba(233, 213, 255, 0.8));
  animation: traderBob 2.2s ease-in-out infinite;
}

@keyframes traderBob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-2px); }
}

@keyframes treasurePulse {
  0%, 100% { transform: scale(1); filter: drop-shadow(0 0 6px rgba(251, 191, 36, 0.8)); }
  50% { transform: scale(1.16); filter: drop-shadow(0 0 12px rgba(251, 191, 36, 1)) brightness(1.2); }
}

/* Лестница */
.ent-stairs {
  width: calc(var(--cell) * 0.66);
  height: calc(var(--cell) * 0.66);
  filter: drop-shadow(0 0 8px rgba(56, 189, 248, 0.85));
  animation: stairsPulse 1.4s ease-in-out infinite;
}

.ent-stairs.up {
  filter: drop-shadow(0 0 8px rgba(52, 211, 153, 0.85));
  animation: stairsUpPulse 1.4s ease-in-out infinite;
}

@keyframes stairsUpPulse {
  0%, 100% { transform: translateY(0); opacity: 0.85; }
  50% { transform: translateY(-2px); opacity: 1; }
}

.ent-stairs.locked {
  filter: grayscale(1) brightness(0.55);
  animation: none;
}

@keyframes stairsPulse {
  0%, 100% { transform: translateY(0); opacity: 0.85; }
  50% { transform: translateY(2px); opacity: 1; }
}

/* Всплывающий урон */
.dmg-float {
  position: absolute;
  font-weight: 900;
  font-size: 21px;
  pointer-events: none;
  z-index: 20;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.85);
  animation: floatUp 0.95s ease-out forwards;
}

.dmg-float.hurt { color: #fca5a5; }
.dmg-float.hit { color: #fde68a; }
.dmg-float.heal { color: #86efac; }

@keyframes floatUp {
  0% { opacity: 0; transform: translate(-50%, 6px) scale(0.6); }
  25% { opacity: 1; transform: translate(-50%, -6px) scale(1.1); }
  100% { opacity: 0; transform: translate(-50%, -52px) scale(1); }
}

/* Тряска */
.shake {
  animation: shake 0.4s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}

@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(3px); }
  30%, 50%, 70% { transform: translateX(-5px); }
  40%, 60% { transform: translateX(5px); }
}

/* ---------- Легенда ---------- */
.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  justify-content: center;
  font-size: 13px;
  color: #9fb3d1;
  margin-bottom: 16px;
}

.legend b {
  color: #f6c453;
}

.legend-icon {
  display: inline-block;
  width: 20px;
  height: 20px;
  vertical-align: middle;
  margin-right: 4px;
}

.legend-icon .ent-svg {
  width: 100%;
  height: 100%;
}

.legend-wall {
  display: inline-block;
  width: 18px;
  height: 18px;
  vertical-align: middle;
  margin-right: 4px;
  border-radius: 4px;
  background: #223048;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.game-msg {
  text-align: center;
  min-height: 22px;
  margin-top: 14px;
  font-weight: 700;
  color: #7dd3fc;
  font-size: 14px;
}

#screen-game {
  display: flex;
  flex-direction: column;
}

#screen-game > .hud,
#screen-game > .equip-bar,
#screen-game > .map,
#screen-game > .legend,
#screen-game > .game-msg {
  flex-shrink: 0;
}

.log {
  margin-top: 16px;
  flex: 1 1 auto;
  min-height: 44px;
  overflow-y: auto;
  font-size: 13px;
  color: #9fb3d1;
  border-top: 1px solid #223451;
  padding-top: 10px;
  line-height: 1.6;
}

/* Во время боя окно игры не прокручивается — скролл уходит в лог */
body.game-page.battling .game-wrap > .panel {
  overflow: hidden;
}

.log div {
  padding: 1px 0;
}

/* ---------- Оверлеи и боевая карточка ---------- */
.overlay {
  position: fixed;
  inset: 0;
  /* Вместо прежнего backdrop-filter: blur(4px): браузер размывал всю карту
     (до 2960x2176) на каждом кадре, и любой экран поверх неё шёл ровно
     30 к/с. Тот же «глубокий затемняющий занавес» даётся плотным фоном. */
  background:
    radial-gradient(120% 90% at 50% 40%, rgba(15, 32, 60, 0.74) 0%, rgba(2, 6, 23, 0.9) 72%),
    rgba(2, 6, 23, 0.86);
  display: grid;
  place-items: center;
  padding: 16px;
  z-index: 60;
  overflow-y: auto;
}

.battle {
  position: relative;
  background: #152340;
  border: 1px solid #2f4468;
  border-top: 3px solid #f6c453;
  border-radius: var(--radius);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.7), inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 0 24px rgba(246, 196, 83, 0.08);
  width: 100%;
  max-width: 580px;
  padding: 24px;
  margin: auto;
  color: #e6edf7;
  animation: cardIn 0.28s cubic-bezier(0.2, 0.9, 0.3, 1.2);
  /* Три зоны: шапка с врагом, прокручиваемая середина с заданием и футер
     с кнопками и эффектами. Карточка не выше окна, поэтому кнопка удара
     видна всегда, каким бы длинным ни было задание. */
  display: flex;
  flex-direction: column;
  gap: 0;
  /* В проекте нет глобального box-sizing, а max-height считается по
     content-box: без этой строки карточка вырастала на высоту отступов и
     нижний край с эффектами уезжал за пределы экрана. */
  box-sizing: border-box;
  max-height: min(92vh, 880px);
  overflow: hidden;
}

.battle-foot {
  flex-shrink: 0;
}

/* Шапка коротка (имя врага и здоровье), но при очень длинном имени она
   уступает место середине и прокручивается сама. */
.battle-head {
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.battle-mid {
  flex: 1 1 auto;
  min-height: 96px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: 4px;
}

/* Вопрос в бою: слева задание, справа ответ. Колонки равные, потому что и
   условие задачи, и поле решения бывают длинными. На узком экране они
   складываются друг под друга — так же, как нижние категории кнопок. */
.battle-ask,
.battle-solve {
  min-width: 0;
}

.battle-mid {
  scrollbar-gutter: auto;
}

.battle-mid.split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: 6px 20px;
  align-items: start;
}

.battle-solve .solve-label {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #7d92b4;
  margin-bottom: 6px;
}

.battle-solve .code-editor {
  width: 100%;
}

@media (max-width: 980px) {
  .battle-mid.split {
    grid-template-columns: minmax(0, 1fr);
  }
}

.battle-foot {
  border-top: 1px solid #24365a;
  margin-top: 14px;
  padding-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.battle-foot .battle-actions,
.battle-foot .potion-row {
  margin: 0;
}

/* Полосы прокрутки в окнах игры скрыты. На проекторе и на планшете светлая
   полоса поперёк тёмного окна читается как случайная деталь, а прокрутка
   колесом, пальцем и клавишами работает и без неё. Скрываем только внутри
   окон и панелей: у журнала своя кнопка сворачивания, а страница игры
   пусть остаётся обычной. */
.battle-mid,
.battle-head,
.battle-effects,
.battle,
.panel {
  scrollbar-width: none;             /* Firefox */
  -ms-overflow-style: none;          /* старый Edge */
}

.battle-mid::-webkit-scrollbar,
.battle-head::-webkit-scrollbar,
.battle-effects::-webkit-scrollbar,
.battle::-webkit-scrollbar,
.panel::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* Задание не поместилось: внизу окна вопроса появляется мягкая тень.
   Полосы прокрутки там больше нет, и без этой тени не видно, что ниже есть
   ещё варианты. Тень снимается, как только докурили до конца. */
.battle-mid.can-scroll {
  mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 22px), transparent);
}

.battle-scene {
  padding: 10px 12px;
}

.battle-top .battle-mid {
  margin-top: 8px;
  padding-top: 8px;
}

.battle-mid.split {
  gap: 4px 16px;
}

/* Категории кнопок идут по своему содержимому, а не растягиваются на всю
   карточку: между «Атакой» и «Побегом» больше не пустая полоса. */
.battle-cat-wrap {
  position: relative;
  flex: 1 1 0;
  min-width: 0;
}

/* Крупная кнопка категории: во всю ширину своей доли, текст как у остальных
   кнопок игры. */
.battle-cat {
  width: 100%;
  padding: 10px 12px;
  min-height: 44px;
}

.battle-cat.open {
  box-shadow: 0 0 0 2px rgba(246, 196, 83, 0.55) inset;
}

/* Всплывающий список действий: раскрывается вверх, потому что низ окна —
   последняя строка карточки. */
.battle-cat-list {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + 8px);
  z-index: 6;
  padding: 10px;
  border-radius: 10px;
  background: #101f38;
  border: 1px solid #2a3b5a;
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.55);
}

.battle-cat-list .battle-actions {
  flex-direction: column;
  gap: 6px;
}

.battle-cat-list .btn {
  width: 100%;
}

.battle-cat-wide {
  flex: 1 1 100%;
}

.battle-cat-wide .btn {
  width: 100%;
}

.battle-foot {
  gap: 8px 14px;
}

/* Варианты ответа: строки ниже, чтобы четыре варианта помещались без
   прокрутки даже с заметкой о бое над вопросом. */
.battle .options .option {
  padding: 9px 12px;
}

.battle .options {
  gap: 8px;
}

/* Порядок строк у обоих бойцов один и тот же: имя, подпись, полоса, число.
   Реплика — просто строка под статами, без рамки: коробка с мелкой надписью
   внутри читалась как пустой прямоугольник. */
.battle .scene-quip {
  border: 0;
  background: none;
  padding: 0;
  margin-top: 2px;
  font-size: 11.5px;
  line-height: 1.3;
  max-width: 208px;
  overflow-wrap: anywhere;
}

.battle {
  padding: 16px;
}

.battle-inner {
  gap: 10px;
}

.battle-scene {
  padding: 8px 10px;
}

.battle-mid.split {
  gap: 4px 14px;
}

.battle .options .option {
  padding: 8px 10px;
}

.battle-group {
  min-width: 138px;
  max-width: 200px;
}

/* Эффекты снаряжения внизу боевого окна. */
.battle-effects {
  max-height: 108px;
  overflow-y: auto;
  /* У футера уже есть своя линия и отступ — второй рамки не надо. */
  margin-top: 0;
  border-top: none;
  padding-top: 0;
}

.battle-effects:empty {
  display: none;
}

@keyframes cardIn {
  from { opacity: 0; transform: translateY(16px) scale(0.96); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.battle-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  margin-bottom: 14px;
}

/* Портрет бойца: крупная фигура без круга, без цветной плашки и без ореола.
   Графика — готовые спрайты 32×32 (public domain, набор DCSS rltiles),
   вшиты в sprites.js как data-URI; см. также spriteImg() в game.js. */
.battle-portrait {
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  animation: enemyIdle 2.6s ease-in-out infinite;
  transform-origin: 50% 100%;
}

/* Враги и герой дышат вразнобой, а не как один механизм. */
.fighter-enemy .battle-portrait {
  animation-delay: -1.25s;
}

.fighter.down .battle-portrait {
  animation: fighterDown 0.65s ease forwards;
}

@keyframes fighterDown {
  0% { filter: grayscale(0); opacity: 1; transform: translateY(0) rotate(0deg) scale(1); }
  100% { filter: grayscale(1); opacity: 0.45; transform: translateY(10px) rotate(-8deg) scale(0.92); }
}

.battle-portrait.boss {
  width: 60px;
  height: 60px;
}

.enemy-tag.elite {
  background: #facc15;
  color: #1c1917;
  box-shadow: 0 0 12px rgba(250, 204, 21, 0.6);
  margin-left: 4px;
}

.streak-note {
  margin-top: 8px;
  padding: 5px 10px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 800;
  color: #fde68a;
  background: rgba(250, 204, 21, 0.12);
  border: 1px solid rgba(250, 204, 21, 0.35);
}

/* Плашка ошибок подряд: каждая ошибка в этом бою бьёт сильнее, и об этом
   надо сказать заранее. Темы боя в окне больше нет — она видна в вопросе. */
.battle-topic {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 2px 12px;
  margin-top: 8px;
  padding: 5px 10px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 700;
  color: #bae6fd;
  background: rgba(56, 189, 248, 0.1);
  border: 1px solid rgba(56, 189, 248, 0.35);
}

.battle-topic b {
  color: #f0f9ff;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.battle-topic.review {
  color: #ddd6fe;
  background: rgba(167, 139, 250, 0.12);
  border-color: rgba(167, 139, 250, 0.4);
}

/* Ошибки подряд: предупреждение, что следующий промах ударит сильнее. */
.battle-topic .miss-tag {
  color: #fdba74;
  font-weight: 800;
}

/* Отряд в бою: пока монстры не все повержены, кнопка «Забрать добычу»
   называет следующего противника — игрок видит, что выход из боя не свободен. */
.squad-note {
  margin-top: 8px;
  padding: 5px 10px;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 800;
  color: #fecaca;
  background: rgba(220, 38, 38, 0.14);
  border: 1px solid rgba(239, 68, 68, 0.4);
}

/* Спрайт 32×32 растягивается целым числом пикселей: pixelated держит пиксели
   квадратными, иначе фигура мылится на 96 px. */
.battle-portrait img {
  width: 100%;
  height: 100%;
  display: block;
  image-rendering: pixelated;
}

.enemy-name {
  font-size: 21px;
  font-weight: 900;
  color: #f1f5f9;
  overflow-wrap: anywhere;
}

.enemy-tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: #fff;
  background: #ef4444;
  border-radius: 999px;
  padding: 3px 10px;
  margin-top: 4px;
  box-shadow: 0 0 12px rgba(239, 68, 68, 0.6);
}

.battle .hud-num {
  color: #9fb3d1;
}

.battle .hud-label {
  color: #8296b5;
}

/* Полосы боя чуть толще панельных: в карточке они главный ориентир. */
body.game-page .battle .hp-bar {
  height: 10px;
  border-radius: 4px;
}

/* Полоса врага остаётся красной: правило темы `body.game-page .hp-bar > i`
   перебивало старое `.hp-bar.enemy > i` по весу, и здоровье монстра
   рисовалось тем же зелёным, что и здоровье героя. */
body.game-page .hp-bar.enemy > i {
  background: #c9453f;
  box-shadow: none;
}

/* ---------- Две области боя: слева сцена, справа задание ---------- */
/* Раньше враг, обе полосы и вопрос жили в одной колонке шириной 580 px,
   и на картинку боя места не оставалось. Теперь слева сцена (кто с кем
   бьётся, имена, полосы, фразы), справа — вопрос, свойства и кнопки.
   Ширина задана именно `#battle-box`: лавка и кузница тоже носят класс
   `.battle`, но у них своя ширина. */
#battle-box {
  /* Ширина подобрана под содержимое: окно на 980 пикселей оставляло по бокам
     пустые полосы, а под ним — половину экрана. */
  max-width: min(980px, 94vw);
}

.battle-inner {
  /* Окно боя — две горизонтальные половины: сверху сцена и задание,
     снизу кнопки. Верх растёт, низ держится по содержимому. */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 14px;
  flex: 1 1 auto;
  min-height: 0;
}

.battle-top {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.battle-scene {
  position: relative;
  flex: 0 0 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* Арена стоит посередине полосы: сверху и снизу остаётся воздух, а не
     пустое поле под бойцами. */
  justify-content: center;
  gap: 10px;
  /* По бокам поле чуть меньше, чем сверху и снизу: статы стоят у края блока,
     но не прилипают к нему. */
  padding: 12px 10px;
  border-radius: 12px;
  background: linear-gradient(180deg, rgba(10, 20, 36, 0.75), rgba(12, 24, 44, 0.45));
  border: 1px solid #24365a;
}

.battle-side {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Задание под сценой: во всю ширину, с воздухом от арены. */
.battle-top .battle-mid {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid #24365a;
}

/* Нижняя половина: четыре категории кнопок. На широком экране они стоят
   рядом, на узком — переносятся по две, а не уезжают за край. */
.battle-foot {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 10px 18px;
}

.battle-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 200px;
  min-width: 160px;
}

.battle-group-name {
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #7d92b4;
}

.battle-group .battle-actions {
  flex-wrap: wrap;
  gap: 8px;
}

.battle-group .btn {
  /* Кнопка по своему тексту: уменьшаем отступы и высоту, а размер шрифта
     оставляем как есть — он задан общими правилами кнопок игры. */
  width: auto;
  padding: 7px 12px;
  min-height: 36px;
}

/* Арена: бойцы друг напротив друга. Никакого свечения позади — по просьбе
   «убери ореол» сцена осталась плоской, портреты держит сам фон сцены. */
.scene-arena {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  padding-top: 4px;
  border-radius: 12px;
}

/* Обёртка бойца перестаёт быть коробкой: её содержимое становится клетками
   сетки арены. Так статы и портрет встают в свои колонки без лишней вложенности. */
.fighter {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 14px;
}

/* Содержимое прижато к своему краю, а статы тянутся: у героя первым идёт
   список статов, у врага — портрет. Так портреты стоят у середины арены,
   а статы занимают всё место до внешнего края, и пустых полос по бокам
   не остаётся. */
.fighter {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 14px;
}

/* Портрет смотрит в центр арены, а статы уходят к своему краю: у героя —
   влево, у врага — вправо. Раньше статы лежали под портретом во всю ширину. */
.fighter-hero {
  /* Герой слева, враг справа, но оба чуть сдвинуты к середине арены —
     ровно настолько, чтобы бойцы читались как пара, а не как две крайности. */
  flex-direction: row;
  justify-content: flex-start;
  padding-left: 64px;
}

.fighter-enemy {
  /* Враг справа; тот же сдвиг к середине, что и у героя, — арена остаётся
     зеркальной. */
  flex-direction: row;
  justify-content: flex-end;
  padding-right: 64px;
}

.fighter-stats {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  /* Ширина числом: полосы здоровья у обоих бойцов одной длины, и портрет
     встаёт сразу за списком, а не посреди арены. */
  flex: 0 0 220px;
  width: 220px;
}

.fighter-hero .fighter-stats {
  align-items: flex-start;
  text-align: left;
}

.fighter-enemy .fighter-stats {
  align-items: flex-end;
  text-align: right;
}

.fighter-stats .hp-bar {
  width: 100%;
}

.fighter-name {
  font-size: 14px;
  font-weight: 900;
  line-height: 1.25;
  color: #e6edf7;
  overflow-wrap: anywhere;
  /* Две строки под имя — у врага имена длиннее, и без общей высоты полосы
     бойцов оказывались на разной высоте. */
  min-height: 35px;
  display: flex;
  align-items: center;
}

.fighter-rank {
  font-size: 11px;
  font-weight: 800;
  letter-spacing: 0.4px;
  color: #8296b5;
  min-height: 16px;
}

.fighter-stats .hp-bar {
  width: 100%;
  max-width: 220px;
}

/* Портреты в сцене крупнее, чем были в шапке: тут они главные. */
.battle-scene .battle-portrait {
  width: 96px;
  height: 96px;
}

/* 32 px × 4: целый масштаб держит пиксели квадратными (108 px давал ×3,375). */
.battle-scene .battle-portrait.boss {
  width: 128px;
  height: 128px;
}

/* Итог боя прямо в сцене: когда враг повержен или герой пал, это видно
   там, где идёт бой, а не только строкой в правой части. */
.scene-banner {
  position: absolute;
  left: 50%;
  top: 42%;
  transform: translate(-50%, -50%) rotate(-4deg);
  padding: 6px 16px;
  border-radius: 10px;
  font-size: 22px;
  font-weight: 900;
  letter-spacing: 1px;
  text-transform: uppercase;
  pointer-events: none;
  z-index: 2;
}

.scene-banner.win {
  color: #0b1120;
  background: #f6c453;
  box-shadow: 0 0 26px rgba(246, 196, 83, 0.6);
}

.scene-banner.lose {
  color: #fff;
  background: #b91c1c;
  box-shadow: 0 0 26px rgba(185, 28, 28, 0.6);
}

.fighter .enemy-tag {
  margin-top: 0;
  font-size: 10px;
  padding: 2px 8px;
}

.fighter .hp-bar {
  width: 100%;
}

/* Полоса бойца стоит в колонке .fighter, а не в строке шапки панели. Общее
   правило `body.game-page .hp-bar { flex: 1 1 100% }` в колонке сводило её
   высоту к 0 px, а `order: 3` уводил под реплику: в бою не было видно ни
   здоровья героя, ни здоровья врага. Высоту (10 px) задаёт правило
   `body.game-page .battle .hp-bar` выше по файлу. */
body.game-page .fighter .hp-bar {
  flex: 0 0 auto;
  order: 0;
  margin-top: 0;
}

.fighter-hp {
  font-size: 12px;
  font-weight: 700;
  color: #9fb3d1;
}

.scene-clash {
  align-self: flex-start;
  margin-top: 22px;
  font-size: 22px;
  line-height: 1;
  color: rgba(246, 196, 83, 0.5);
  text-shadow: 0 0 12px rgba(246, 196, 83, 0.4);
}

/* Фраза монстра — прямо под ним, а не подписью под всей сценой. */
.scene-quip {
  align-self: stretch;
  margin-top: 2px;
  padding: 5px 7px;
  border-radius: 8px;
  background: rgba(12, 24, 44, 0.65);
  border: 1px solid rgba(125, 162, 217, 0.16);
  font-style: italic;
  font-size: 12.5px;
  line-height: 1.35;
  color: #a9b6c9;
  text-align: center;
}

/* Павший боец гаснет: видно, кто уже не в игре. */
.fighter.down .battle-portrait {
  filter: grayscale(1);
  opacity: 0.45;
}

.fighter.down .fighter-name {
  opacity: 0.6;
}

/* Живость сцены: бьющий делает выпад, по битому проходит вспышка, число
   урона всплывает рядом с ним (см. strikeScene в game.js). */
@keyframes strikeRight {
  0% { transform: translateX(0); }
  35% { transform: translateX(10px); }
  100% { transform: translateX(0); }
}

@keyframes strikeLeft {
  0% { transform: translateX(0); }
  35% { transform: translateX(-10px); }
  100% { transform: translateX(0); }
}

.battle-scene.strike-enemy .fighter-hero {
  animation: strikeRight 0.42s ease;
}

.battle-scene.strike-hero .fighter-enemy {
  animation: strikeLeft 0.42s ease;
}

@keyframes fighterFlash {
  0% { filter: brightness(2.6); }
  100% { filter: brightness(1); }
}

.fighter.fighter-flash .battle-portrait {
  animation: fighterFlash 0.5s ease;
}

@media (prefers-reduced-motion: reduce) {
  .battle-scene.strike-enemy .fighter-hero,
  .battle-scene.strike-hero .fighter-enemy,
  .fighter.fighter-flash .battle-portrait {
    animation: none;
  }
}

/* Узкий экран: области встают друг под друга — сцена полосой сверху.
   Полоса сжата до предела: её высота отнимается у вопроса, а варианты
   ответа должны оставаться на виду. */
@media (max-width: 980px) {
  .battle-inner {
    flex-direction: column;
    gap: 12px;
  }

  #battle-box {
    padding: 16px;
  }

  .battle-scene {
    flex: 0 0 auto;
    padding: 8px 10px;
    gap: 6px;
  }

  /* 64 и 96 px — ×2 и ×3 от нарисованных 32: целый масштаб, как и на карте. */
  .battle-scene .battle-portrait {
    width: 64px;
    height: 64px;
  }

  .battle-scene .battle-portrait.boss {
    width: 96px;
    height: 96px;
  }

  .fighter-name {
    font-size: 12.5px;
    min-height: 0;
  }

  .fighter-rank {
    font-size: 10px;
    min-height: 0;
  }

  .fighter .enemy-tag {
    font-size: 9px;
    padding: 1px 6px;
  }

  .fighter-hp {
    font-size: 11.5px;
  }

  .scene-clash {
    font-size: 16px;
    margin-top: 14px;
  }

  .scene-quip {
    font-size: 11.5px;
    padding: 4px 6px;
  }
}

.challenge-tag {
  display: inline-block;
  font-size: 11px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: #0b1120;
  background: #38bdf8;
  border-radius: 999px;
  padding: 5px 13px;
  margin: 12px 0 12px;
  box-shadow: 0 0 14px rgba(56, 189, 248, 0.45);
}

.challenge-tag.code {
  background: #a855f7;
  box-shadow: 0 0 14px rgba(168, 85, 247, 0.5);
}

.challenge-tag.copy {
  background: #06b6d4;
  box-shadow: 0 0 14px rgba(6, 182, 212, 0.5);
}

.sample-code {
  user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  -moz-user-select: none;
}

.copy-note {
  font-size: 12px;
  color: #fca5a5;
  margin: -8px 0 12px;
  font-weight: 600;
}

.challenge-q {
  font-size: 18px;
  font-weight: 800;
  line-height: 1.4;
  color: #f1f5f9;
  margin-bottom: 14px;
}

/* Пометка о проклятой плите и других особых условиях боя */
.battle-note {
  font-size: 12px;
  font-weight: 600;
  color: #c4b5fd;
  margin: -6px 0 12px;
  padding: 6px 10px;
  border-left: 3px solid #8b5cf6;
  background: rgba(124, 58, 237, 0.12);
  border-radius: 0 8px 8px 0;
}

.battle .lead {
  color: #9fb3d1;
}

pre.code {
  background: #050a14;
  color: #d1fae5;
  border: 1px solid #1d2f4c;
  border-radius: 12px;
  padding: 16px 18px;
  font-family: "JetBrains Mono", "Consolas", "Courier New", monospace;
  font-size: 15px;
  line-height: 1.6;
  overflow-x: auto;
  margin: 0 0 16px;
  white-space: pre;
  box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.6);
}

.code-editor {
  width: 100%;
  min-height: 140px;
  background: #050a14;
  color: #d1fae5;
  border: 1px solid #2a3b5a;
  border-radius: 12px;
  padding: 14px;
  font-family: "JetBrains Mono", "Consolas", "Courier New", monospace;
  font-size: 14px;
  line-height: 1.6;
  resize: vertical;
  tab-size: 4;
  white-space: pre;
  overflow-wrap: normal;
  overflow-x: auto;
  box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.5);
}

.code-editor:focus {
  outline: none;
  border-color: #a855f7;
  box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.5), 0 0 0 3px rgba(168, 85, 247, 0.2);
}

.test-results {
  margin-top: 12px;
  font-size: 13px;
  font-family: "JetBrains Mono", "Consolas", monospace;
}

.test-line {
  padding: 5px 9px;
  border-radius: 7px;
  margin-bottom: 4px;
}

.test-line.pass {
  background: rgba(22, 163, 74, 0.18);
  color: #86efac;
}

.test-line.fail {
  background: rgba(220, 38, 38, 0.18);
  color: #fca5a5;
}

.battle-feedback {
  margin-top: 14px;
  font-weight: 700;
  font-size: 15px;
}

.battle-feedback.good { color: #4ade80; }
.battle-feedback.bad { color: #fca5a5; }

.battle-explain {
  margin-top: 12px;
  padding: 12px 14px;
  border-radius: 10px;
  background: rgba(56, 189, 248, 0.1);
  border-left: 4px solid #38bdf8;
  color: #cbd5e1;
  font-size: 14px;
  line-height: 1.55;
  animation: cardIn 0.25s ease;
}

.battle-explain b {
  color: #7dd3fc;
}

.battle-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 18px;
}

/* Варианты ответа внутри тёмной карточки */
.battle .option {
  background: #101f38;
  border-color: #2a3b5a;
  color: #e6edf7;
}

.battle .option:hover:not(:disabled) {
  border-color: #7dd3fc;
  background: #16294a;
}

.battle .option .key {
  background: #1e2f4d;
  color: #9fb3d1;
}

.battle .option.correct {
  border-color: #22c55e;
  background: rgba(22, 163, 74, 0.22);
}

.battle .option.wrong {
  border-color: #ef4444;
  background: rgba(220, 38, 38, 0.22);
}

.battle .btn.ghost {
  background: #24344f;
  color: #e6edf7;
}

.battle .btn.ghost:hover {
  background: #2f4468;
}

.potion-row {
  margin-top: 12px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

.potion-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #8296b5;
}

/* Зелье, которое сейчас не нужно: кнопка бледнее, но нажимается — ответит,
   почему не выпито, а не промолчит. */
.battle .btn.idle {
  opacity: 0.55;
}

/* ---------- Инвентарь ---------- */
.inventory {
  max-width: 640px;
}

.inv-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  margin-bottom: 18px;
  font-size: 14px;
  color: #9fb3d1;
}

.inv-stats b {
  color: #7dd3fc;
  font-size: 16px;
}

.inv-section h3 {
  font-size: 13px;
  margin: 0 0 10px;
  color: #8296b5;
  text-transform: uppercase;
  letter-spacing: 0.8px;
}

.inv-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  border: 1px solid #2a3b5a;
  background: rgba(255, 255, 255, 0.03);
  border-left: 5px solid #94a3b8;
  border-radius: 11px;
  padding: 10px 14px;
  margin-bottom: 8px;
  transition: transform 0.12s, box-shadow 0.12s;
}

.inv-item:hover {
  transform: translateX(2px);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}

/* Название — прямой потомок .info. Цена и числа внутри <span> остаются
   строчными: раньше `.info b` растягивал в блок и их, и «цена 90» рвалась
   на три строки. */
.inv-item .info > b {
  display: block;
  font-size: 15px;
  color: #f1f5f9;
}

.inv-item .info span b {
  color: #f1f5f9;
}

.item-ico {
  display: inline-block;
  width: 23px;
  height: 23px;
  vertical-align: -6px;
  margin-right: 7px;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.5));
}

.item-ico .ent-svg {
  width: 100%;
  height: 100%;
}

/* Картинка предмета — пиксель-арт 32×32: ровно ×1, без дробного масштаба. */
.item-ico.item-ico-px {
  width: 32px;
  height: 32px;
  vertical-align: -10px;
  margin-right: 8px;
}

.item-ico .item-px {
  width: 100%;
  height: 100%;
  display: block;
  image-rendering: pixelated;
}

.inv-item .info span {
  font-size: 12px;
  color: #9fb3d1;
}

.inv-item .btn {
  padding: 8px 14px;
  font-size: 14px;
}

.inv-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
}

/* ---------- Наполнение подземелья ---------- */

/* Способность врага — короткая строка под блоком его здоровья. */
.enemy-ability {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  color: #fcd34d;
  background: rgba(120, 53, 15, 0.35);
  border: 1px solid rgba(252, 211, 77, 0.35);
  border-radius: 999px;
  padding: 3px 10px;
  margin-top: 6px;
}

.enemy-ability::before {
  content: "✦";
  color: #f59e0b;
}

.enemy-ability.curse {
  color: #e9d5ff;
  background: rgba(124, 58, 237, 0.3);
  border-color: rgba(192, 132, 252, 0.4);
}

.enemy-ability.curse::before {
  content: "☠";
  color: #c084fc;
}

/* Дальнобойный — розовая плашка с прицелом. */
.enemy-ability.ranged {
  color: #fbcfe8;
  background: rgba(190, 24, 93, 0.28);
  border-color: rgba(244, 114, 182, 0.45);
}

.enemy-ability.ranged::before {
  content: "➶";
  color: #f472b6;
}

.enemy-quip {
  margin: 8px 0 0;
  font-size: 13px;
  font-style: italic;
  color: #94a3b8;
}

.enemy-quip.poison {
  font-style: normal;
  color: #a3e635;
  font-weight: 700;
}

/* Эпиграф этажа при спуске. Панель перекрывает верх карты, поэтому
   исчезает сама через несколько секунд и её можно закрыть крестиком.
   Текст лежит в .floor-arrival-body: контейнер нельзя перезаписывать
   целиком — в нём живёт кнопка закрытия. */
.floor-arrival {
  position: absolute;
  left: 14px;
  right: 200px;
  top: 12px;
  z-index: 6;
  max-width: 520px;
  padding: 12px 40px 12px 16px;
  border: 1px solid rgba(99, 102, 241, 0.45);
  border-left: 4px solid #6366f1;
  border-radius: 12px;
  background: rgba(22, 22, 52, 0.94);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  animation: floor-arrival-in 0.35s ease-out;
}

.floor-arrival-body {
  display: block;
}

.floor-arrival-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid rgba(148, 163, 184, 0.35);
  border-radius: 7px;
  background: rgba(15, 23, 42, 0.8);
  color: #94a3b8;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}

.floor-arrival-close:hover {
  background: rgba(99, 102, 241, 0.35);
  color: #e2e8f0;
}

.floor-arrival h3 {
  margin: 0 0 6px;
  font-size: 16px;
  color: #c7d2fe;
}

.floor-arrival p {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: #cbd5e1;
}

.floor-arrival .floor-epi-topic {
  margin-top: 6px;
  font-size: 12px;
  font-weight: 700;
  color: #a5b4fc;
}

.floor-arrival .floor-hint {
  display: block;
  margin-top: 6px;
  font-size: 13px;
  color: #86efac;
}

@keyframes floor-arrival-in {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.floor-epilogue {
  margin: 12px 0 10px;
  padding: 12px 14px;
  border-left: 3px solid #6366f1;
  background: rgba(99, 102, 241, 0.08);
  border-radius: 0 10px 10px 0;
  color: #cbd5e1;
  font-size: 14px;
  line-height: 1.5;
}

.floor-epilogue b {
  color: #a5b4fc;
}

.floor-epilogue .floor-hint {
  display: block;
  margin-top: 6px;
  font-size: 13px;
  color: #86efac;
}

/* Экран-разбор в конце партии. */
.run-report {
  text-align: left;
  margin: 16px 0;
}

.run-report h3 {
  margin: 14px 0 8px;
  font-size: 15px;
  color: #e2e8f0;
}

.report-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 6px 10px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
  margin-bottom: 5px;
  font-size: 13px;
  color: #cbd5e1;
}

.report-row b {
  color: #f1f5f9;
  white-space: nowrap;
}

.report-bar {
  flex: 1 1 auto;
  height: 6px;
  border-radius: 999px;
  background: #1e293b;
  overflow: hidden;
  min-width: 60px;
}

.report-bar i {
  display: block;
  height: 100%;
  border-radius: 999px;
}

.report-empty {
  font-size: 13px;
  color: #64748b;
}

/* Описание предмета и его особое действие. */
.item-desc {
  display: block;
  font-size: 12px;
  font-style: italic;
  color: #8b9ab5;
  margin-top: 2px;
}

.item-effect {
  display: block;
  font-size: 12px;
  font-weight: 700;
  color: #c4b5fd;
  margin-top: 2px;
}

/* Комплекты-семейства: строка о семье предмета и блок «Комплекты». */
.item-set {
  display: block;
  font-size: 12px;
  font-weight: 700;
  margin-top: 3px;
}

.set-title {
  margin-top: 10px;
}

.effect-row.set-row .effect-num {
  color: #cbd5e1;
  font-weight: 600;
}

.effect-row.set-row.full .effect-num {
  color: #86efac;
}

.set-item .info b {
  letter-spacing: 0.2px;
}

/* Сравнение предмета из сумки с надетым: видно, станет ли лучше. */
.forge-lvl {
  color: #fbbf24;
  font-weight: 700;
}

.item-cmp-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 3px;
  font-size: 12px;
  color: #8296b5;
}

.item-cmp {
  padding: 1px 6px;
  border-radius: 999px;
  border: 1px solid #2b3d5f;
  background: #16233a;
  font-weight: 700;
  white-space: nowrap;
}

.item-cmp.up {
  color: #86efac;
  border-color: #2f6b45;
  background: #14301f;
}

.item-cmp.down {
  color: #fca5a5;
  border-color: #6b2f2f;
  background: #301414;
}

.item-cmp.set {
  color: #fde68a;
  border-color: #6b5a2f;
  background: #302a14;
}

.inv-empty {
  color: #8296b5;
  font-size: 14px;
  padding: 6px 0;
}

/* ---------- Лавка: две колонки и подробные карточки ---------- */
/* Коробка лавки шире инвентаря: слева товар, справа продажа. Потолок высоты
   остаётся общим (.battle), поэтому прокручивается середина — раньше список
   товара упирался в потолок карточки, и до продажи было не добраться. */
#shop-box {
  max-width: 1040px;
}

/* Шапка лавки и кузницы — это название и золото: ужимать её нельзя, иначе
   заголовок срезается. В бою шапка по-прежнему уступает место заданию.
   Тем же правилом живут окна деревни: без него шапка сжимается в нулевую
   высоту, содержимое её перекрывает, и кнопка «Закрыть» пропадает — выйти
   из окна торговца становится нечем. */
#shop-box .battle-head,
#forge-box .battle-head,
#dialog-box .battle-head,
#entrance-box .battle-head {
  flex-shrink: 0;
}

/* Окна жителей и входа — той же ширины, что лавка: в узком окне карточки
   товара вставали в три тесных столбца. */
#dialog-box,
#entrance-box {
  max-width: 1040px;
}

.shop-stats {
  margin: 14px 0 0;
  flex-shrink: 0;
}

/* В панели справа статы живут сеткой 2x2, но в широкой лавке они встают
   одной строкой: так видно всё сразу и нет растянутых промежутков. */
#shop-box .inv-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 22px;
  margin: 14px 0 0;
}

.shop-note {
  margin: 10px 0 14px;
  font-size: 13px;
  color: #9fb3d1;
  flex-shrink: 0;
}

.shop-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 0 22px;
  align-items: start;
}

/* Две кнопки покупки столбиком: в узкой колонке им тесно в строку. */
.shop-buy-actions {
  flex-direction: column;
  align-items: stretch;
}

.shop-buy-actions .btn {
  white-space: nowrap;
}

@media (max-width: 860px) {
  .shop-cols {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---------- Опасная среда этажа ---------- */

/* Лёд: холодная плёнка поверх плитки. Встав на неё, герой скользит. */
.tile.hazard-frost::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(125, 211, 252, 0.28);
  box-shadow: inset 0 0 8px rgba(186, 230, 253, 0.55);
  pointer-events: none;
}

/* Лава: плитка светлее и насыщеннее соседей — в демонической теме стены
   (красный камень) горят ярче самой лавы, и без этого её не отличить. */
.tile.hazard-lava {
  filter: brightness(1.45) saturate(1.3);
}

/* Лава: тёплое дыхание снизу, чуть пульсирует. */
.tile.hazard-lava::after {
  content: "";
  position: absolute;
  inset: 0;
  /* Сама клетка нарисована плиткой лавы (terrainLavaCellBg), поэтому плёнка
     лишь подсвечивает кромку: так опасность читается с первого взгляда. */
  background: rgba(255, 140, 40, 0.16);
  box-shadow: inset 0 0 12px rgba(255, 150, 50, 0.85);
  pointer-events: none;
  animation: lava-breathe 2.4s ease-in-out infinite;
}

@keyframes lava-breathe {
  0%, 100% { opacity: 0.72; }
  50% { opacity: 1; }
}

/* Тьма действует на весь этаж: гасим уже увиденные плитки, но не тех,
   кто в зоне видимости — иначе в темноте не разглядеть даже монстра. */
.map[data-hazard="dark"] .tile.floor.seen {
  filter: brightness(0.42) saturate(0.6);
}

/* Винетка по краям экрана: камера держит героя в центре, поэтому
   затемнение сходится именно там, где он стоит, а не в центре карты. */
.map-scroll.hazard-dark {
  box-shadow: inset 0 0 150px 50px rgba(2, 6, 23, 0.9);
}

.floor-arrival .floor-hazard {
  color: #fca5a5;
  font-weight: 700;
}

.floor-arrival .floor-hazard-hint {
  color: #93c5fd;
}

@media (prefers-reduced-motion: reduce) {
  .tile.hazard-lava::after {
    animation: none;
  }
}

/* ---------- Развилка на входе: сделка ---------- */
/* Развилка на входе — окно уровня карты, а не модальное: в разметке она стоит
   последней среди .overlay, и при общем z-index: 60 перекрывала бой, лавку и
   экран победы. Ученик, не ответивший на развилку, видел её карточки поверх
   всего и не мог ни драться, ни нажать «В деревню» после дракона. Ниже 60 —
   значит выше карты и панели (их z-index максимум 20), но ниже любого окна. */
#blessing-overlay {
  z-index: 55;
}

.bless-box {
  max-width: 640px;
}

.bless-lead {
  color: #cbd5f5;
  margin-bottom: 14px;
}

.bless-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
  margin-top: 6px;
}

.bless-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  text-align: center;
  padding: 18px 14px;
  border-radius: 14px;
  border: 1px solid rgba(148, 163, 184, 0.35);
  background: rgba(24, 33, 51, 0.95);
  color: #e2e8f0;
  cursor: pointer;
  transition: transform 0.12s, box-shadow 0.12s, border-color 0.12s;
}

.bless-card:hover {
  transform: translateY(-2px);
  border-color: rgba(148, 163, 184, 0.7);
}

.bless-card.curse:hover {
  box-shadow: 0 0 22px rgba(248, 113, 113, 0.35);
  border-color: rgba(248, 113, 113, 0.7);
}

.bless-card.blessing:hover {
  box-shadow: 0 0 22px rgba(74, 222, 128, 0.32);
  border-color: rgba(74, 222, 128, 0.7);
}

.bless-icon {
  font-size: 34px;
  line-height: 1;
}

.bless-card.curse .bless-icon {
  color: #f87171;
}

.bless-card.blessing .bless-icon {
  color: #4ade80;
}

.bless-name {
  font-size: 20px;
  font-weight: 800;
}

.bless-good {
  color: #fecaca;
  font-size: 14px;
}

.bless-card.blessing .bless-good {
  color: #bbf7d0;
}

.bless-extra {
  color: #94a3b8;
  font-size: 13px;
}

/* ---------- Калибровка уровня ---------- */
.calibration-box {
  text-align: left;
  max-width: 620px;
}

.calibration-box h2 {
  text-align: center;
  margin: 14px 0 8px;
}

.calibration-box .battle-head {
  margin-bottom: 12px;
}

.calib-question {
  margin: 10px 0 12px;
  color: #f1f5f9;
  font-size: 18px;
  font-weight: 700;
  line-height: 1.4;
}

.calib-code {
  margin: 0 0 14px;
  padding: 10px 12px;
  border: 1px solid #2f4468;
  border-radius: 10px;
  background: #0b1526;
  color: #dbeafe;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-x: auto;
}

.calib-options {
  display: grid;
  gap: 8px;
}

.calib-option {
  display: block;
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #334a6e;
  border-radius: 10px;
  background: #1b2b49;
  color: #e2e8f0;
  font: inherit;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.calib-option b {
  margin-right: 4px;
  color: #93c5fd;
}

.calib-option:hover:not(:disabled) {
  border-color: #3d7ee0;
  background: #22385c;
}

.calib-option:disabled {
  cursor: default;
  opacity: 0.8;
}

.calib-option.correct {
  border-color: #22c55e;
  background: rgba(34, 197, 94, 0.16);
}

.calib-option.wrong {
  border-color: #ef4444;
  background: rgba(239, 68, 68, 0.14);
}

.calib-feedback {
  margin-top: 12px;
  padding: 9px 11px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.04);
  color: #cbd5e1;
  font-size: 13px;
  line-height: 1.45;
}

.calib-feedback.ok {
  color: #86efac;
}

.calib-feedback.bad {
  color: #fca5a5;
}

.calib-foot {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
  margin-top: 16px;
}

.calib-foot .btn {
  min-width: 120px;
}

@media (max-width: 560px) {
  .calibration-box {
    padding: 18px;
  }

  .calib-question {
    font-size: 16px;
  }

  .calib-foot {
    flex-direction: column-reverse;
  }

  .calib-foot .btn {
    width: 100%;
  }
}

/* ---------- Итоговые экраны ---------- */
.center-card {
  text-align: center;
}

/* Заголовок стартового экрана переехал в блок «Главное меню подземелья»
   в конце файла: градиентная заливка текста заменена на обычный цвет. */

.center-card h2 {
  font-size: 28px;
  color: #f1f5f9;
}

.big-emoji-free {
  font-size: 44px;
  font-weight: 900;
  margin: 8px 0;
  letter-spacing: 2px;
}

.game-over {
  color: #f87171;
  text-shadow: 0 0 22px rgba(248, 113, 113, 0.6);
}

.victory {
  color: #4ade80;
  text-shadow: 0 0 22px rgba(74, 222, 128, 0.6);
}

/* Итог похода: компактная сетка, читаемая и на телефоне. */
.run-title {
  margin: 18px 0 4px;
  color: #f4f0e6;
  font-size: 18px;
  letter-spacing: 0.02em;
}

.run-summary {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 12px;
  max-width: 520px;
  margin: 16px auto;
  text-align: left;
}

.run-summary > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 10px;
  border: 1px solid rgba(147, 168, 200, 0.18);
  border-radius: 8px;
  background: rgba(148, 163, 184, 0.06);
}

.run-summary span {
  color: #93a8c8;
  font-size: 13px;
}

.run-summary b {
  color: #f4f0e6;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.run-next {
  max-width: 560px;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 560px) {
  .run-summary {
    grid-template-columns: 1fr;
  }
}

/* Правила .start-grid удалены вместе со старой разметкой кнопок:
   главное меню подземелья больше не собирает кнопки в колонку-карточку. */

a.link-btn {
  display: inline-block;
  text-align: center;
  text-decoration: none;
}

/* ---------- Кнопки (переопределяем на тёмном) ---------- */
.btn {
  background: #2f6fe4;
  box-shadow: 0 6px 18px rgba(37, 99, 235, 0.4);
  transition: transform 0.1s, filter 0.15s, box-shadow 0.15s;
}

.btn:hover {
  filter: brightness(1.1);
  box-shadow: 0 10px 24px rgba(37, 99, 235, 0.5);
}

.btn.ghost {
  background: #24344f;
  color: #cbd5e1;
  box-shadow: none;
}

.btn.ghost:hover {
  background: #2f4468;
}

.btn.purple {
  background: #8b5cf6;
  box-shadow: 0 6px 18px rgba(124, 58, 237, 0.45);
}

.btn.purple:hover {
  filter: brightness(1.1);
  box-shadow: 0 10px 24px rgba(124, 58, 237, 0.55);
}

/* Главное действие окна покупки — «Купить» в лавке и «Улучшить» в кузнице:
   рядом есть второстепенные кнопки, и они не должны выглядеть так же. */
.btn.primary {
  background: linear-gradient(180deg, #3d7ee0, #2f6fe4);
  color: #f4f8ff;
  font-weight: 700;
  box-shadow: 0 6px 18px rgba(37, 99, 235, 0.4);
}

.btn.primary:hover {
  filter: brightness(1.08);
  box-shadow: 0 10px 24px rgba(37, 99, 235, 0.5);
}

/* ============================================================
   ОКНА ДЕРЕВНИ И ВХОДА В ПОДЗЕМЕЛЬЕ
   Раскладка: шапка во всю ширину, ниже две колонки — слева
   настройки похода, справа сводка «что ждёт в подземелье».
   Классы .check/.pick/.modes общие: их используют окна
   страницы проверки и практикума (они делят .modes и .mode).
   ============================================================ */

:root {
  /* Эти переменные уже использовались в game.css (строки с .panel
     input:focus и .panel .mode.active), но нигде не были объявлены:
     var(--gold) не подставлялся, и рамка выбранной карточки красилась
     в currentColor вместо золота. Теперь токены определены. */
  --gold: #f6c453;
  --gold-ink: #2b1e04;
  --steel-1: #101d31;
  --steel-2: #0a1424;
  --steel-line: rgba(125, 162, 217, 0.18);
  --steel-muted: #93a8c8;
  --display: Georgia, "Times New Roman", serif;
}


/* =========================================================
   Экран настройки похода. Язык без карточек.
   Поверхность одна — сама страница. Иерархию держат типографика,
   волосяные линейки и воздух; вложенных прямоугольников с фоном,
   рамкой и скруглением нет. Кнопки, поля и флажки остаются
   контролами: у них есть форма, потому что с ними взаимодействуют.
   ========================================================= */

/* Тёмная поверхность на весь экран: раньше это была панель-карточка. */
body.game-page {
  background-color: #0a1220;
  background-image: var(--tex-dots);
}


.dialog-setup-unused {
  display: grid;
  grid-template-columns: minmax(0, 1.08fr) minmax(300px, 0.92fr);
  grid-template-areas:
    "hero hero"
    "main side";
  gap: 24px 44px;
  align-content: start;
  align-items: start;
  /* Карточки здесь больше нет: секция остаётся областью прокрутки. */
  padding: 2px 0 4px;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  /* Секция — только область прокрутки: карточная анимация появления
     (style.css, .card/.panel) на ней больше не нужна. */
  animation: none;
  text-align: left;
}

/* ---------- шапка ---------- */
.setup-hero {
  grid-area: hero;
  max-width: 76ch;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--steel-line);
}

.setup-kicker {
  margin: 0 0 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #8ea9cf;
}

h2 {
  margin: 0 0 10px;
  font-family: var(--display);
  font-size: clamp(29px, 3vw, 40px);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: #f7ecd2;
  text-wrap: balance;
}

.setup-lead {
  margin: 0;
  max-width: 62ch;
  font-size: 15px;
  line-height: 1.55;
  color: #a9bcd8;
}

/* ---------- левая колонка: настройки ---------- */
.setup-main {
  grid-area: main;
  display: grid;
  gap: 18px;
  align-content: start;
  min-width: 0;
}

/* Кошелёк и медали живут в правой колонке: левая остаётся чистой
   формой, и кнопка спуска видна без прокрутки. Метрики медалей
   перебивают inline-стили badgesHtml() — цвет и рамка остаются его. */
.side-block {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--steel-line);
}

.side-block #wallet-line {
  margin: 8px 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: #a9bcd8;
}

#game-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 6px;
  margin: 10px 0 0;
}

#game-badges span {
  margin: 0 !important;
  padding: 2px 8px !important;
  font-size: 11.5px !important;
}

/* Пока ученик не вошёл, спуск заблокирован. */
#begin-btn[disabled] {
  opacity: 0.45;
  box-shadow: none;
  cursor: not-allowed;
}

/* Лавка деревни — сетка карточек. Ширина карточки ~190px, поэтому на
   планшете влезает две, на телефоне — одна в столбец. */
.hub-shop {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 10px;
}

.hub-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  border: 1px solid rgba(148, 163, 184, 0.28);
  border-radius: 12px;
  background: rgba(15, 23, 42, 0.4);
}

.hub-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  font-size: 14px;
  color: #e2e8f0;
}

.hub-price {
  white-space: nowrap;
  font-size: 12.5px;
  color: #f6c453;
}

.hub-card-note {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.35;
  color: #94a3b8;
}

.hub-stock {
  font-size: 12px;
  color: #7dd3fc;
}

.hub-stock.full {
  color: #94a3b8;
}

.hub-buy {
  margin-top: auto;
  min-height: 38px;
}

/* Развитие деревни и квесты: блок постройки в окне жителя, кнопки роста и
   заголовки разделов в окне старосты. */
.build-block {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  margin: 10px 0;
  border: 1px solid rgba(148, 163, 184, 0.28);
  border-radius: 12px;
  background: rgba(15, 23, 42, 0.4);
}

.build-go,
.upg-buy,
.quest-take,
.quest-claim {
  margin-top: auto;
  min-height: 38px;
}

.quest-head {
  margin: 16px 0 0;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #94a3b8;
}

/* Строка цели в панели подземелья: одна строка, чтобы не раздувать HUD. */
.quest-line {
  color: #f6c453;
  font-size: 12px;
}

/* Прогоревший костёр: тот же спрайт, но видно, что привал здесь уже был. */
.ent-camp.spent {
  filter: grayscale(1) brightness(0.65);
  opacity: 0.75;
}

/* Действия героя в бою: оборона, отступление и умение стоят отдельной
   строкой под подсказкой и пропуском, чтобы их не путали с ответом. */
.battle-actions-hero {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed rgba(148, 163, 184, 0.25);
}

/* Показ первой проверки при «Прозрении» в задании с кодом. */
.code-hint {
  margin: 6px 0 0;
  font-size: 12.5px;
  color: #7dd3fc;
}

/* Флажок «забрать награды»: настоящий чекбокс скрыт, рисуется квадрат
   20×20, а вся строка — цель не меньше 44 px по высоте. */
.check {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  min-height: 44px;
  padding: 2px 0;
  font-size: 14px;
  color: #cbd5e1;
  cursor: pointer;
}

.check input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
}

.check-box {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border: 1px solid #3a5379;
  border-radius: 4px;
  background: none;
  transition: border-color 0.16s ease, background 0.16s ease;
}

.check-box::after {
  content: "";
  width: 10px;
  height: 5px;
  border-left: 2px solid var(--gold-ink);
  border-bottom: 2px solid var(--gold-ink);
  transform: rotate(-45deg) scale(0);
  transition: transform 0.16s ease;
}

.check input:checked + .check-box {
  background: var(--gold);
  border-color: var(--gold);
}

.check input:checked + .check-box::after {
  transform: rotate(-45deg) scale(1);
}

.check input:focus-visible + .check-box {
  outline: 3px solid rgba(246, 196, 83, 0.5);
  outline-offset: 2px;
}

/* ---------- выборы: не карточки, а строки, разделённые линейками ---------- */
.pick-label {
  display: block;
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #8ea9cf;
}

.modes,
#difficulty {
  display: grid;
  gap: 0 34px;
  margin: 0;
}

.modes,
#difficulty {
  grid-template-columns: minmax(0, 1fr);
}

.mode {
  position: relative;
  /* Строка-бланк: маркер, название и пояснение в одну линию.
     На узком экране пояснение уезжает под название (медиазапрос ниже). */
  display: grid;
  grid-template-columns: 16px minmax(140px, 0.44fr) minmax(0, 1fr);
  align-items: baseline;
  gap: 0 12px;
  width: 100%;
  margin: 0;
  padding: 13px 12px 13px 10px;
  border: 0;
  border-top: 1px solid var(--steel-line);
  border-radius: 0;
  background: none;
  box-shadow: none;
  text-align: left;
  cursor: pointer;
  transition: background 0.16s ease, border-color 0.16s ease;
}

.mode:hover {
  background: rgba(125, 162, 217, 0.07);
}

.mode:active {
  background: rgba(125, 162, 217, 0.12);
}

.mode.active {
  border-top-color: var(--gold);
  background: rgba(246, 196, 83, 0.06);
}

.mode:focus-visible {
  outline: 2px solid rgba(246, 196, 83, 0.7);
  outline-offset: -2px;
}

.mode-mark {
  grid-column: 1;
  align-self: start;
  width: 16px;
  height: 16px;
  margin-top: 3px;
  border: 1.5px solid #3a5379;
  border-radius: 50%;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}

.mode.active .mode-mark {
  border-color: var(--gold);
  box-shadow: inset 0 0 0 4px var(--gold);
}

.mode b {
  grid-column: 2;
  display: block;
  font-size: 15.5px;
  font-weight: 700;
  line-height: 1.25;
  color: #e7eefa;
  transition: color 0.16s ease;
}

.mode.active b {
  color: #ffe4a3;
}

.mode .mode-note {
  grid-column: 3;
  display: block;
  margin-top: 0;
  font-size: 12.5px;
  line-height: 1.45;
  color: #9db2d2;
}

/* ---------- действия ---------- */
.setup-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding-top: 2px;
}

#begin-btn,
#resume-btn {
  flex: 0 1 auto;
  min-width: 240px;
  max-width: 320px;
  min-height: 52px;
  padding: 15px 26px;
  border-radius: 12px;
  font-size: 16.5px;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.1s ease, background 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease;
}

#begin-btn {
  border: 0;
  background: #f6c453;
  color: var(--gold-ink);
  box-shadow: 0 6px 18px rgba(223, 168, 56, 0.24);
}

#begin-btn:hover {
  background: #ffd77a;
  transform: translateY(-1px);
  box-shadow: 0 10px 22px rgba(223, 168, 56, 0.3);
}

#begin-btn:active {
  transform: translateY(1px);
}

#resume-btn {
  border: 1px solid #33496e;
  background: none;
  color: #dbe6f7;
}

#resume-btn:hover {
  border-color: #4a6892;
  background: rgba(125, 162, 217, 0.08);
}

.setup-links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 20px;
  margin-top: 2px;
}

.link-quiet {
  padding: 3px 0;
  font-size: 14px;
  color: #9db2d2;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.16s ease, border-color 0.16s ease;
}

.link-quiet:hover {
  color: #ffe4a3;
  border-bottom-color: rgba(246, 196, 83, 0.5);
}

.link-quiet:focus-visible {
  outline: 3px solid rgba(246, 196, 83, 0.5);
  outline-offset: 2px;
}

/* ---------- правая колонка: сводка ---------- */
.setup-side {
  grid-area: side;
  padding-left: 32px;
  border-left: 1px solid var(--steel-line);
}

.side-title {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: #8ea9cf;
}

.brief {
  list-style: none;
  margin: 0;
  padding: 0;
}

.brief li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 12px 0;
}

.brief li + li {
  border-top: 1px solid rgba(125, 162, 217, 0.1);
}

.brief svg {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  margin-top: 3px;
  /* Иконки нарисованы контурами: без этого браузер заливал их чёрным. */
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--gold);
  opacity: 0.9;
}

.brief b {
  display: block;
  font-size: 14px;
  font-weight: 700;
  color: #e7eefa;
}

.brief span {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  line-height: 1.5;
  color: #9db2d2;
}

.keys {
  display: flex;
  flex-wrap: wrap;
  gap: 7px 16px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid rgba(125, 162, 217, 0.1);
  font-size: 12.5px;
  color: #93a8c8;
}

.key-row {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

kbd {
  padding: 1px 6px;
  border: 1px solid #33496e;
  border-radius: 5px;
  background: none;
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 700;
  color: #dbe6f7;
}

/* ---------- адаптив ---------- */
@media (max-width: 1240px) {
  .dialog-setup-unused {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
      "hero"
      "main"
      "side";
  }

  .setup-side {
    padding: 26px 0 0;
    border-left: 0;
    border-top: 1px solid var(--steel-line);
  }
}

@media (max-width: 700px) {
  /* ?? ???????? ????????????? ????? ???????? ?????? ???, ? ? ?????
     ?????? ?????? ???????? ????? ? ????????. */
  #fullscreen-btn {
    display: none;
  }

  /* Узко: пояснение уезжает под название, маркер остаётся слева. */
  .mode {
    grid-template-columns: 16px minmax(0, 1fr);
  }

  .mode b,
  .mode .mode-note {
    grid-column: 2;
  }

  .mode .mode-note {
    margin-top: 3px;
  }

  .setup-actions {
    flex-direction: column;
  }

  #begin-btn,
  #resume-btn {
    flex: 1 1 100%;
    max-width: none;
  }
}

/* Появление экрана: только когда движение не отключено в системе. */
@media (prefers-reduced-motion: no-preference) {
  .setup-hero,
  .setup-main > *,
  .setup-side > * {
    animation: setupIn 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  }

  .setup-main > *:nth-child(2) {
    animation-delay: 0.04s;
  }

  .setup-main > *:nth-child(3) {
    animation-delay: 0.08s;
  }

  .setup-main > *:nth-child(4) {
    animation-delay: 0.12s;
  }

  .setup-side > *:nth-child(2) {
    animation-delay: 0.06s;
  }

  @keyframes setupIn {
    from {
      opacity: 0;
      transform: translateY(6px);
    }
    to {
      opacity: 1;
      transform: none;
    }
  }
}

/* ==========================================================================
   Игровой экран (#screen-game) — тот же безкарточный язык, что и в меню похода
   Одна поверхность вместо карточек, иерархия держится на типографике,
   волосяных линейках и воздухе. Форму сохраняют только те элементы,
   с которыми игрок взаимодействует: поле ввода, кнопки, полосы здоровья.
   ========================================================================== */

/* ---------- Каркас: карта и колонка состояния ---------- */

/* Панель вокруг карты больше не нужна: карта сама себе рамка. */
body.game-page .game-wrap > #screen-game.panel {
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  overflow: hidden;
}

#screen-game .map-scroll {
  border: 1px solid var(--steel-line);
  border-radius: 14px;
}

/* Колонка состояния: ширина по делу, а не процент от экрана.
   На 1024 px подписи и значения перестают наезжать друг на друга. */
body.game-page .side-panel {
  flex: 0 0 clamp(268px, 21vw, 320px);
  max-width: none;
  gap: 0;
}

/* ---------- Колонка состояния: разделы вместо карточек ---------- */
body.game-page .side-card {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
}

body.game-page .side-card + .side-card {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--steel-line);
}

/* Здоровье и опыт: подпись и число в одну строку, полоса под ними. */
body.game-page .hud {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  align-items: stretch;
  justify-content: flex-start;
  gap: 16px;
  margin: 0;
}

body.game-page .hud-block {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 10px;
  flex: none;
  width: 100%;
  min-width: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
}

body.game-page .hud-label {
  flex: 1 1 auto;
  margin: 0;
}

body.game-page .hud-num {
  flex: 0 0 auto;
  margin: 0;
}

body.game-page .hp-bar,
body.game-page .xp-bar {
  flex: 1 1 100%;
  order: 3;
  margin-top: 7px;
  box-shadow: none;
}

body.game-page .hp-bar {
  height: 8px;
  border-radius: 3px;
  background: #0b1526;
}

body.game-page .hp-bar > i {
  border-radius: 3px;
  background: #3f9e6a;
  box-shadow: none;
}

/* Опыт — золотом: единственный акцент подземелья, а не второй цвет. */
body.game-page .xp-bar {
  height: 5px;
  border-radius: 3px;
  background: #0b1526;
}

body.game-page .xp-bar > i {
  border-radius: 3px;
  background: var(--gold);
  box-shadow: none;
}

/* Этаж, монстры и золото — список строками с линейками. */
body.game-page .hud-block:has(.floor-name) {
  display: block;
}

body.game-page .floor-name {
  font-size: 14.5px;
  letter-spacing: 0.2px;
}

body.game-page .hud-block:has(.floor-name) .hud-num {
  margin-top: 8px;
  padding-top: 7px;
  border-top: 1px solid var(--steel-line);
}

/* Экипировка: строки «подпись — значение». */
body.game-page .equip-bar {
  display: block;
  margin: 0;
}

body.game-page .equip-slot {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  min-width: 0;
  padding: 8px 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--steel-line);
  border-radius: 0;
}

body.game-page .equip-slot:first-child {
  border-top: 0;
  padding-top: 0;
}

body.game-page .equip-label {
  margin: 0;
  font-size: 11px;
}

body.game-page .equip-value {
  font-size: 13.5px;
  text-align: right;
}

/* Особые эффекты: точка и название в первой строке, пояснение во второй.
   В узкой колонке пояснение больше не наезжает на название. */
body.game-page .effect-list {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--steel-line);
}

body.game-page .effect-title {
  margin-bottom: 8px;
}

body.game-page .effect-row {
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr);
  gap: 2px 9px;
  align-items: baseline;
  padding: 5px 0;
  font-size: 12.5px;
}

body.game-page .effect-dot {
  align-self: start;
  margin-top: 5px;
}

body.game-page .effect-num {
  grid-column: 2;
  margin: 0;
  white-space: normal;
  font-size: 11.5px;
  color: #7d92b3;
}

body.game-page .effect-row + .effect-row {
  border-top: 1px solid rgba(125, 162, 217, 0.1);
}

/* Сумка: строки с цветной засечкой редкости вместо карточек. Кнопки строк
   остаются плоскими: в панели они не должны спорить с золотыми «Лавкой» и
   «Кузницей» из сводки. */
body.game-page .inv-item .btn {
  font-size: 12px;
  font-weight: 600;
  color: #cfe0f5;
  background: none;
  border: 1px solid var(--steel-line);
  border-radius: 999px;
  padding: 5px 12px;
}

body.game-page .inv-item .btn:hover {
  border-color: rgba(246, 196, 83, 0.5);
  color: var(--gold);
}

#shop-box .inv-item .btn.primary,
#forge-box .inv-item .btn.primary {
  background: linear-gradient(180deg, #3d7ee0, #2f6fe4);
  color: #f4f8ff;
  border-color: rgba(120, 170, 240, 0.55);
  font-weight: 700;
}

#shop-box .inv-item .btn.purple {
  background: linear-gradient(180deg, #9a6cf7, #8b5cf6);
  color: #f7f3ff;
  border-color: rgba(167, 139, 250, 0.55);
  font-weight: 700;
}

#shop-box .inv-item .btn.primary:hover,
#forge-box .inv-item .btn.primary:hover {
  color: #f4f8ff;
  filter: brightness(1.08);
}

#shop-box .inv-item .btn.purple:hover {
  color: #f7f3ff;
  filter: brightness(1.08);
}

/* «Мало золота»: кнопка гаснет и говорит причину — вместо всплывашки после
   нажатия. Продажа остаётся обычной кнопкой, она не отказ. */
#shop-box .inv-item .btn.ghost,
#forge-box .inv-item .btn.ghost {
  color: #8ea3c2;
  border-color: rgba(125, 162, 217, 0.25);
  opacity: 0.75;
}

body.game-page .inv-section h3 {
  font-size: 11px;
  margin: 0 0 4px;
  color: var(--steel-muted);
}

body.game-page .inv-stats {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 7px 12px;
  margin: 0 0 12px;
  font-size: 12px;
}

body.game-page .inv-stats b {
  font-size: 13px;
  color: #e6edf7;
}

body.game-page .inv-item {
  border: 0;
  border-top: 1px solid var(--steel-line);
  border-left: 3px solid #94a3b8;
  border-radius: 0;
  background: none;
  padding: 9px 0 9px 11px;
  margin: 0;
  transition: none;
}

body.game-page .inv-item:hover {
  transform: none;
  box-shadow: none;
}

body.game-page .inv-item .info > b {
  font-size: 13.5px;
}

body.game-page .inv-item .info span {
  font-size: 11.5px;
}

body.game-page .item-desc {
  font-size: 11px;
  color: #7d92b3;
}

body.game-page .inv-empty {
  font-size: 12px;
}

/* ---------- Мебель карты: без наслоений ---------- */

/* Сообщение уходит к левому краю и больше не заезжает на мини-карту. */
#screen-game .game-msg {
  left: 12px;
  right: 208px;
  max-width: 620px;
  transform: none;
  text-align: left;
  white-space: normal;
  border-color: var(--steel-line);
  border-radius: 10px;
  background: rgba(5, 8, 15, 0.86);
}

#screen-game .minimap {
  border: 1px solid var(--steel-line);
  border-radius: 12px;
  background: rgba(5, 8, 15, 0.94);
  box-shadow: none;
}

/* Подсказка про зум: тихая подпись вместо второй пилюли. */
#screen-game .cam-hint {
  right: 12px;
  bottom: 9px;
  color: #6f86a8;
  background: none;
  border: 0;
  padding: 0;
}

/* Журнал: панель над картой в тех же линиях. Кнопка переехала в шапку,
   поэтому раскладку панели задаёт только это правило. */
#screen-game .log {
  left: 12px;
  bottom: 12px;
  width: min(380px, 58%);
  max-height: min(50%, 380px);
  padding: 10px 12px;
  border: 1px solid var(--steel-line);
  border-radius: 12px;
  background: rgba(5, 8, 15, 0.94);
  font-size: 12.5px;
}

/* Род события виден по цвету и значку: находка, бой, урон, новый этаж.
   Одинаковые серые строки приходилось читать подряд, чтобы найти нужную. */
#screen-game .log .log-line {
  padding: 1px 0;
}

#screen-game .log .kind-info {
  color: #9fb3d1;
}

#screen-game .log .kind-loot {
  color: #8fe0a6;
}

#screen-game .log .kind-fight {
  color: #f0a68e;
}

#screen-game .log .kind-hurt {
  color: #f28b7d;
  font-weight: 600;
}

#screen-game .log .kind-floor {
  color: #f6c453;
  font-weight: 600;
}

/* Счётчик новых строк: виден, даже когда журнал свёрнут. */
body.game-page .head-link[data-unread] {
  text-shadow: 0 2px 14px rgba(234, 179, 8, 0.9);
}

body.game-page .head-link[data-unread]::after {
  content: attr(data-unread);
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--gold);
  color: #2a1e02;
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

/* Золота хватает на улучшение: у «Кузницы» тот же значок, что у журнала. */
body.game-page .head-link[data-ready] {
  text-shadow: 0 2px 14px rgba(234, 179, 8, 0.9);
}

body.game-page .head-link[data-ready]::after {
  content: attr(data-ready);
  margin-left: 4px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--gold);
  color: #2a1e02;
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
}

/* Неизведанное — не чёрная пустота, а едва заметная сетка. */
#screen-game .map .tile.unseen {
  background-color: #060c18;
  background-image: var(--tex-grid);
  background-repeat: repeat;
}

/* Список предметов в узкой колонке: действия под описанием, а не сбоку —
   иначе название рвётся на две строки. */
body.game-page .side-panel .inv-item {
  display: block;
  border-left-width: 3px;
}

body.game-page .side-panel .inv-item .inv-actions {
  margin-top: 8px;
  justify-content: flex-start;
}

/* Вкусовое описание предмета в панели лишнее: строка эффекта о нём уже есть. */
body.game-page .side-panel .item-desc {
  display: none;
}

body.game-page .side-panel .item-effect {
  color: #b9c6dd;
  font-weight: 600;
}

/* Колонка прокручивается: покажем, что прокрутка есть. */
body.game-page .side-panel {
  scrollbar-width: thin;
  scrollbar-color: rgba(125, 162, 217, 0.32) transparent;
}

body.game-page .side-panel::-webkit-scrollbar {
  width: 10px;
}

body.game-page .side-panel::-webkit-scrollbar-thumb {
  border: 3px solid transparent;
  border-radius: 999px;
  background-clip: content-box;
  background-color: rgba(125, 162, 217, 0.32);
}

/* Заголовок списка эффектов: без него строки читались как продолжение
   сводки экипировки. Рисуется вместе со списком, пустого не бывает. */
body.game-page .side-panel .effect-title {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--steel-line);
  font-size: 11.5px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: #8296b5;
}

/* ---------- Панель состояния: сводка закреплена ---------- */

/* Здоровье, этаж, золото и кнопки остаются на месте, пока игрок листает
   сумку. Раньше сводка уезжала вверх вместе с прокруткой, и «Лавка» с
   «Выйти» исчезали ровно тогда, когда нужны. */
body.game-page .side-panel > .side-card:first-child {
  margin: 0;
  padding-bottom: 12px;
  background-color: #0b1524;
  background-image: var(--tex-dots);
  border-bottom: 1px solid var(--steel-line);
}

/* Закрепляется сводка только там, где колонка высокая. На узком экране
   колонка стоит под картой и бывает ниже 300px: закреплённые 225px сводки
   оставляли сумке полоску в пару строк, и листать её было некуда. */
@media (min-width: 981px) and (min-height: 560px) {
  body.game-page .side-panel > .side-card:first-child {
    position: sticky;
    top: 0;
    z-index: 4;
  }
}

/* Линейку рисует закреплённая сводка: второй раздел её не дублирует. */
body.game-page .side-panel > .side-card:first-child + .side-card {
  margin-top: 0;
  padding-top: 14px;
  border-top: 0;
}

/* Пункты похода живут в шапке справа. Появляются только в игре: на стартовом
   экране ни лавки, ни кузницы, ни журнала ещё нет, и пунктам там нечего делать. */
body.game-page .head-actions {
  display: none;
  margin-left: auto;
  align-items: baseline;
  gap: 6px 18px;
}

body.game-page:has(.stage.playing) .head-actions {
  display: flex;
}

/* Лавка, кузница, журнал и выход — не кнопки, а золотые ссылки: их ищут глазами,
   но они не должны спорить с кнопками, которые ждут нажатия внутри окон. Тень —
   та же золотая, что была у кнопки, только текстовая. */
body.game-page .head-link {
  padding: 2px 1px;
  background: none;
  border: 0;
  color: #f6c453;
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  text-shadow: 0 2px 10px rgba(234, 179, 8, 0.45);
  cursor: pointer;
  transition: color 0.15s, text-shadow 0.15s;
}

body.game-page .head-link:hover {
  color: #ffe08a;
  text-decoration: underline;
  text-decoration-color: rgba(246, 196, 83, 0.55);
  text-underline-offset: 3px;
  text-shadow: 0 2px 14px rgba(234, 179, 8, 0.8);
}

body.game-page .head-link:focus-visible {
  border-radius: 4px;
  outline: 2px solid rgba(246, 196, 83, 0.7);
  outline-offset: 2px;
}

/* Открытый журнал виден по подчёркиванию: ссылка не должна прыгать по ширине. */
body.game-page .head-link.active {
  text-decoration: underline;
  text-decoration-color: rgba(246, 196, 83, 0.75);
  text-underline-offset: 3px;
}

/* Снаряжение — четыре плашки в два ряда вместо четырёх строк списка. */
body.game-page .equip-bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 6px 8px;
}

body.game-page .equip-slot {
  display: block;
  min-width: 0;
  padding: 5px 10px;
  background: #0d1a2c;
  border: 1px solid var(--steel-line);
  border-radius: 10px;
  color: inherit;
  font: inherit;
  text-align: left;
}

/* Подпись сверху, значение снизу: название вещи помещается целиком. */
body.game-page .equip-slot .equip-label {
  display: block;
  margin: 0 0 1px;
}

body.game-page .equip-slot .equip-value {
  text-align: left;
  overflow-wrap: anywhere;
}

/* Плашка с вещью — кнопка «снять»: подсказка говорит об этом словами,
   а рамка отзывается на наведение. Пустая плашка не нажимается. */
body.game-page button.equip-slot {
  cursor: pointer;
}

body.game-page button.equip-slot:hover:not(:disabled) {
  border-color: rgba(246, 196, 83, 0.55);
  background: #12213a;
}

body.game-page button.equip-slot:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

body.game-page button.equip-slot:disabled {
  cursor: default;
  border-style: dashed;
  opacity: 0.75;
}

/* Строка сумки: название и статы слева, кнопки справа. До этого каждая
   вещь занимала почти треть высоты колонки. */
body.game-page .side-panel #inventory-box .inv-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  padding: 8px 0 8px 10px;
}

body.game-page .side-panel #inventory-box .inv-item .info {
  min-width: 0;
}

body.game-page .side-panel #inventory-box .inv-item .inv-actions {
  margin: 0;
  flex-direction: column;
  align-items: stretch;
  gap: 5px;
}

body.game-page .side-panel #inventory-box .inv-item .btn {
  padding: 4px 10px;
  font-size: 11.5px;
  white-space: nowrap;
}

/* Подробности строки в колонке не нужны: они ждут наведения. Сравнение с
   надетым остаётся — это то, по чему игрок выбирает вещь. */
body.game-page .side-panel #inventory-box .item-effect,
body.game-page .side-panel #inventory-box .item-set,
body.game-page .side-panel #inventory-box .item-desc {
  display: none;
}

body.game-page .side-panel #inventory-box .item-cmp-row {
  display: flex;
  flex-wrap: wrap;
  gap: 3px 8px;
  margin-top: 3px;
  font-size: 11.5px;
  line-height: 1.35;
}

body.game-page .inv-note {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  font-style: normal;
  color: #8296b5;
}

/* Мелкий текст колонки читался как сноска: 11 px на тёмном фоне сливались. */
body.game-page .hud-label,
body.game-page .equip-label,
body.game-page .inv-section h3,
body.game-page .inv-item .info span,
body.game-page .effect-num {
  font-size: 12px;
}

body.game-page .equip-value {
  font-size: 12.5px;
}

/* Тот же мелкий текст в бою, в лавке и в подсказке сумки: 10–11 px
   на тёмном фоне читались как сноска. */
body.game-page .enemy-tag,
body.game-page .challenge-tag,
body.game-page .effect-title,
body.game-page .item-desc,
body.game-page .action-btn .action-key,
body.game-page .inv-note,
body.game-page .side-panel .effect-title {
  font-size: 12px;
}

#screen-game .cam-hint {
  font-size: 12px;
  color: #8296b5;
}

/* ---------- Подсказки при наведении ---------- */

/* Одна карточка на всю игру: подробности предмета и пояснения кнопок.
   Встаёт рядом с тем, о чём рассказывает, и мышь не перехватывает. */
.tip {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 70;
  max-width: 300px;
  padding: 9px 12px;
  border: 1px solid #2c4569;
  border-radius: 10px;
  background: rgba(8, 14, 26, 0.98);
  box-shadow: 0 18px 40px rgba(2, 6, 23, 0.62);
  color: #bdccdf;
  font-size: 12.5px;
  line-height: 1.45;
  pointer-events: none;
}

.tip.hidden {
  display: none;
}

.tip b {
  display: block;
  margin-bottom: 4px;
  color: #f1f5f9;
  font-size: 13px;
}

/* В подсказке строки идут подряд: каждая подробность — своя строка. */
.tip .item-set,
.tip .item-effect {
  display: inline;
  font-weight: 600;
}

/* ---------- Узкое окно ---------- */
@media (max-width: 980px) {
  /* В колонке карта не должна сжиматься до щели: у неё своя высота,
     а колонка панели забирает остаток и прокручивается сама. */
  .stage.playing .game-wrap {
    flex: 0 0 auto;
    height: min(56vh, 440px);
    min-height: 300px;
  }

  #screen-game .map-scroll {
    height: 100%;
    min-height: 0;
  }

  body.game-page .side-panel {
    flex: 1 1 auto;
    min-height: 0;
    max-width: none;
    width: 100%;
  }

  /* Кнопка «Пропустить ход» живёт внизу справа, а карта на узком экране
     низкая: снизу журнал всегда наезжал на неё или на подсказку. Ставим его
     сверху, под строку-подсказку, во всю ширину карты. */
  #screen-game .log {
    left: 10px;
    right: 10px;
    width: auto;
    top: 56px;
    bottom: auto;
    max-height: min(38%, 240px);
  }
}

/* Предметы декора (колонна, фонтан, обломки, кол) — отдельный слой поверх пола.
   Они стоят в клетке как вещь и рядом с героем и монстрами спорили за взгляд:
   белую колонну принимали за препятствие. Вполсилы они
   читаются как обстановка, а герой, враги и сундуки остаются главными. */
.tile.has-obj::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--obj) center / 100% 100% no-repeat;
  image-rendering: pixelated;
  opacity: 0.5;
  filter: saturate(0.6);
  pointer-events: none;
}

/* ==========================================================================
   Телефон (до 700 px): бой и карта
   Карточка боя прятала варианты ответа под сгибом: сцена, кнопки футера и
   список эффектов съедали больше половины высоты. Здесь они ужаты так, чтобы
   вопрос и четыре варианта помещались без прокрутки. На карте кнопки
   «Подняться» и «Пропустить ход» стоят друг над другом и не накладываются,
   мини-карта меньше, а подсказки про колесо и клавиши (их на телефоне нет)
   убраны.
   ========================================================================== */
@media (max-width: 700px) {
  #battle-box {
    padding: 12px;
    max-height: min(94vh, 880px);
  }

  .battle-inner {
    gap: 8px;
  }

  /* Реплика монстра — украшение, а не информация: на телефоне она стоит
     полтора варианта ответа. */
  .scene-quip {
    display: none;
  }

  .challenge-tag {
    margin: 4px 0 8px;
  }

  .challenge-q {
    font-size: 16px;
    margin-bottom: 8px;
  }

  .battle pre.code {
    padding: 8px 10px;
    font-size: 13px;
    margin-bottom: 8px;
  }

  .battle .options {
    gap: 8px;
  }

  .battle .option {
    padding: 8px 10px;
    gap: 10px;
    font-size: 15px;
  }

  .battle .option .key {
    width: 24px;
    height: 24px;
    flex: 0 0 24px;
  }

  /* Футер: подсказка и зелье рядом, эффекты — тонкой строкой без заголовка. */
  .battle-foot {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: stretch;
    gap: 8px;
    margin-top: 8px;
    padding-top: 8px;
  }

  .battle-foot .battle-actions,
  .battle-foot .potion-row {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    gap: 6px;
  }

  .battle-foot .btn {
    flex: 1 1 auto;
    padding: 9px 8px;
    font-size: 13.5px;
  }

  .potion-label {
    display: none;
  }

  .battle-effects {
    flex: 1 1 100%;
    max-height: 52px;
  }

  .battle-effects .effect-title,
  .battle-effects .effect-num {
    display: none;
  }

  /* Карта */
  #screen-game .minimap {
    width: 112px;
    height: 80px;
    top: 6px;
    right: 6px;
  }

  #screen-game .game-msg {
    right: 126px;
    font-size: 13px;
  }

  #screen-game .cam-hint {
    display: none;
  }

  .action-btn {
    left: auto;
    right: 10px;
    bottom: 56px;
    transform: none;
    animation: none;
    padding: 8px 12px;
    font-size: 13.5px;
  }

  .skip-btn {
    right: 10px;
    bottom: 10px;
    padding: 7px 12px;
    font-size: 13px;
  }

  .action-btn .action-key {
    display: none;
  }
}

/* Число предметов в стеке: три зелья — одна строка «Малое зелье ×3». */
.inv-count {
  color: #f6c453;
  font-weight: 700;
}

/* ---------- Загрузка этажа ----------
   Оверлей висит, пока на компьютере игрока генерируется карта и проверяется
   проходимость. Генерация занимает миллисекунды, поэтому минимум времени
   показа держит play-код (LEVEL_MIN_LOAD_MS), иначе экран мигал бы кадром. */
.loading-box {
  width: min(440px, 92vw);
  padding: 26px 26px 22px;
  border-radius: 18px;
  border: 1px solid rgba(246, 196, 83, 0.28);
  background: linear-gradient(180deg, #101f3a 0%, #0b1428 100%);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.05);
  text-align: center;
  color: #e2e8f0;
}

.loading-box h2 {
  margin: 0 0 6px;
  font-size: 20px;
  color: #f6c453;
  letter-spacing: 0.01em;
}

.loading-text {
  margin: 0 0 14px;
  min-height: 20px;
  color: #93a3ba;
  font-size: 14px;
}

.loading-bar {
  height: 8px;
  border-radius: 999px;
  background: rgba(148, 163, 184, 0.18);
  overflow: hidden;
}

.loading-fill {
  width: 12%;
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, #b07a2c, #f6c453);
  box-shadow: 0 0 12px rgba(246, 196, 83, 0.5);
  transition: width 0.22s ease;
}

.loading-note {
  margin: 14px 0 0;
  color: #64748b;
  font-size: 12px;
  line-height: 1.45;
}

.loading-spinner {
  width: 34px;
  height: 34px;
  margin: 0 auto 14px;
  border-radius: 50%;
  border: 3px solid rgba(246, 196, 83, 0.22);
  border-top-color: #f6c453;
  animation: loading-spin 0.9s linear infinite;
}

@keyframes loading-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .loading-spinner {
    animation: none;
    border-top-color: rgba(246, 196, 83, 0.22);
  }
  .loading-fill {
    transition: none;
  }
}

/* ---------- Инструменты разработчика ----------
   Появляются только при запуске сервера с --dev. Панель выше оверлеев,
   чтобы можно было пропустить бой, не закрывая его вручную. */
.dev-toggle {
  position: fixed;
  left: 14px;
  bottom: 14px;
  z-index: 90;
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid rgba(246, 196, 83, 0.5);
  background: rgba(11, 20, 40, 0.92);
  color: #f6c453;
  font: inherit;
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.08em;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
}

.dev-toggle:hover {
  background: rgba(20, 34, 62, 0.96);
}

.dev-panel {
  position: fixed;
  right: 14px;
  bottom: 14px;
  z-index: 95;
  width: min(360px, calc(100vw - 28px));
  max-height: min(70vh, 560px);
  overflow-y: auto;
  padding: 12px 14px 14px;
  border-radius: 14px;
  border: 1px solid rgba(246, 196, 83, 0.35);
  background: linear-gradient(180deg, #101f3a 0%, #0a1226 100%);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.6);
  color: #e2e8f0;
  font-size: 13px;
}

.dev-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  color: #f6c453;
  font-size: 13px;
  margin-bottom: 8px;
}

.dev-close {
  border: 0;
  background: none;
  color: #93a3ba;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}

.dev-close:hover {
  color: #fff;
}

.dev-state {
  margin-bottom: 10px;
  padding: 7px 9px;
  border-radius: 8px;
  background: rgba(148, 163, 184, 0.1);
  color: #9fb0c8;
  font-size: 12px;
  line-height: 1.5;
}

.dev-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(148, 163, 184, 0.12);
}

.dev-group:last-child {
  margin-bottom: 0;
  padding-bottom: 0;
  border-bottom: 0;
}

.dev-group > span {
  color: #93a3ba;
  font-size: 12px;
}

.dev-panel input[type="number"] {
  width: 62px;
  padding: 4px 6px;
  border-radius: 7px;
  border: 1px solid #334155;
  background: #0b1428;
  color: #e2e8f0;
  font: inherit;
  font-size: 12px;
}

.dev-btn {
  padding: 5px 10px;
  border-radius: 8px;
  border: 1px solid rgba(148, 163, 184, 0.3);
  background: rgba(148, 163, 184, 0.08);
  color: #dbe6f5;
  font: inherit;
  font-size: 12px;
  cursor: pointer;
}

.dev-btn:hover {
  border-color: rgba(246, 196, 83, 0.55);
  background: rgba(246, 196, 83, 0.1);
}

.dev-btn.dev-on {
  border-color: #f6c453;
  background: rgba(246, 196, 83, 0.2);
  color: #ffe08a;
}

.dev-btn.dev-danger {
  border-color: rgba(248, 113, 113, 0.5);
  color: #fca5a5;
}

.dev-btn.dev-danger:hover {
  background: rgba(248, 113, 113, 0.14);
}

/* ==========================================================================
   ????????????? ??????? ????: ????? ????? ?????, ????????? ? ??????.
   ========================================================================== */
body.game-page {
  position: relative;
  padding: 0;
  gap: 0;
}

body.game-page .site-head {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  padding: 8px 14px;
  background: linear-gradient(180deg, rgba(6, 12, 24, 0.94) 0%,
    rgba(6, 12, 24, 0.58) 68%, transparent 100%);
  pointer-events: none;
}

body.game-page .site-head .brand,
body.game-page .site-head .head-actions {
  pointer-events: auto;
}

body.game-page .site-head .head-actions {
  flex-wrap: wrap;
  justify-content: flex-end;
}

body.game-page .stage {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

body.game-page .game-wrap,
body.game-page .stage .game-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100%;
  min-height: 0;
  margin: 0;
  z-index: 1;
}

body.game-page .game-wrap > #screen-game.panel {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
  margin: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  overflow: hidden;
}

body.game-page #screen-game .map-scroll {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 0;
  margin: 0;
  border: 0;
  border-radius: 0;
}

body.game-page #screen-game .map-scroll .map {
  border-radius: 0;
}

body.game-page #screen-game .game-msg {
  top: 64px;
}

body.game-page #screen-game .minimap {
  top: 68px;
  left: 12px;
  right: auto;
}

body.game-page .side-panel {
  position: absolute;
  top: 64px;
  right: 12px;
  bottom: 92px;
  width: clamp(264px, 20vw, 330px);
  max-width: none;
  z-index: 30;
  padding: 10px 12px;
  border: 1px solid rgba(125, 162, 217, 0.26);
  border-radius: 14px;
  background: rgba(7, 13, 24, 0.84);
  backdrop-filter: blur(9px);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.4);
  overflow-y: auto;
}

body.game-page .side-panel.hud-collapsed {
  display: none;
}

/* ---------- Постоянная сводка героя поверх карты ---------- */

/* HP, опыт, сила и текущая глава видны всегда: и в деревне, и в подземелье.
   Подробная панель «Статы» остаётся отдельно, но базовые цифры больше не
   приходится искать по меню. */
body.game-page .hero-hud {
  position: absolute;
  top: 70px;
  right: 12px;
  z-index: 32;
  transition: opacity 0.14s ease, visibility 0.14s ease;
  width: clamp(264px, 23vw, 334px);
  padding: 9px 10px 10px;
  border: 1px solid rgba(214, 168, 75, 0.34);
  border-left: 3px solid var(--gold, #d6a84b);
  border-radius: 2px;
  background:
    linear-gradient(180deg, rgba(25, 35, 49, 0.93), rgba(9, 15, 24, 0.94));
  box-shadow:
    5px 5px 0 rgba(0, 0, 0, 0.38),
    inset 0 1px 0 rgba(255, 255, 255, 0.035);
  backdrop-filter: blur(7px);
  color: var(--parchment, #eee4cf);
  font-family: var(--font-data, Consolas, monospace);
  pointer-events: none;
}

body.game-page .hero-hud-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}

body.game-page .hero-hud-rank {
  color: var(--parchment-dim, #b9b3a5);
  font-size: 9px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

body.game-page .hero-hud-rank b {
  color: var(--gold-bright, #f0c66a);
  font-size: 15px;
  letter-spacing: 0;
}

body.game-page .hero-hud-name {
  min-width: 0;
  overflow: hidden;
  color: var(--parchment, #eee4cf);
  font: 700 12px/1.1 var(--font-display, Georgia, serif);
  text-overflow: ellipsis;
  white-space: nowrap;
}

body.game-page .hero-hud-gold {
  margin-left: auto;
  color: var(--gold-bright, #f0c66a);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}

body.game-page .hero-hud-coin {
  margin-right: 3px;
  color: var(--gold, #d6a84b);
  font-size: 9px;
}

body.game-page .hero-hud-bar {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) auto;
  gap: 7px;
  align-items: center;
  margin-top: 7px;
}

body.game-page .hero-hud-key {
  color: var(--parchment-dim, #b9b3a5);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.12em;
}

body.game-page .hero-hud-track {
  height: 7px;
  overflow: hidden;
  border: 1px solid rgba(214, 168, 75, 0.25);
  background: #140d0e;
}

body.game-page .hero-hud-track > i {
  display: block;
  width: 0;
  height: 100%;
  transition: width 0.2s ease;
}

body.game-page .hero-hud-bar.hp .hero-hud-track > i {
  background: linear-gradient(90deg, #7f2f2f, #c96b3b);
}

body.game-page .hero-hud-bar.xp .hero-hud-track {
  height: 5px;
  background: #101a18;
}

body.game-page .hero-hud-bar.xp .hero-hud-track > i {
  background: linear-gradient(90deg, #6f8f5a, #d6a84b);
}

body.game-page .hero-hud-val {
  min-width: 54px;
  color: var(--parchment, #eee4cf);
  font-size: 9px;
  text-align: right;
  white-space: nowrap;
}

body.game-page .hero-hud.is-low .hero-hud-bar.hp .hero-hud-track {
  border-color: rgba(220, 80, 70, 0.72);
  animation: heroHudLow 1.1s ease-in-out infinite;
}

body.game-page .hero-hud-foot {
  display: flex;
  gap: 9px;
  align-items: baseline;
  margin-top: 7px;
  padding-top: 6px;
  border-top: 1px solid rgba(214, 168, 75, 0.14);
  color: var(--parchment-dim, #b9b3a5);
  font-size: 8px;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

body.game-page .hero-hud-foot b {
  color: var(--parchment, #eee4cf);
  font-size: 9px;
}

body.game-page .hero-hud-place {
  min-width: 0;
  margin-left: auto;
  overflow: hidden;
  color: var(--gold-bright, #f0c66a);
  text-overflow: ellipsis;
}

body.game-page .hero-hud-story {
  display: flex;
  align-items: baseline;
  gap: 7px;
  width: 100%;
  min-height: 26px;
  margin-top: 7px;
  padding: 5px 7px;
  border: 1px solid rgba(214, 168, 75, 0.2);
  border-radius: 2px;
  background: rgba(7, 11, 18, 0.34);
  color: var(--parchment-dim, #b9b3a5);
  font: inherit;
  text-align: left;
  cursor: pointer;
  pointer-events: auto;
}

body.game-page .hero-hud-story-kicker {
  flex: 0 0 auto;
  color: var(--gold, #d6a84b);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

body.game-page .hero-hud-story-title {
  min-width: 0;
  overflow: hidden;
  color: var(--parchment, #eee4cf);
  font-size: 10px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

body.game-page .hero-hud-story::after {
  content: "›";
  margin-left: auto;
  color: var(--gold, #d6a84b);
  font-size: 15px;
  line-height: 0.7;
}

body.game-page .hero-hud-story:hover,
body.game-page .hero-hud-story:focus-visible {
  border-color: var(--gold, #d6a84b);
  color: var(--gold-bright, #f0c66a);
  outline: none;
}

body.game-page .hero-hud-story.is-ready {
  border-color: rgba(145, 201, 139, 0.52);
  background: rgba(63, 94, 56, 0.22);
}

body.game-page .hero-hud-story.is-ready .hero-hud-story-kicker {
  color: #a9c79d;
}

body.game-page .hero-hud-story.is-done {
  border-color: rgba(145, 201, 139, 0.4);
}

body.game-page .hero-hud-story.is-done .hero-hud-story-kicker {
  color: #a9c79d;
}

/* В открытом окне HUD не спорит с содержимым: журнал, бой и диалоги
   занимают экран целиком. После закрытия сводка возвращается. */
body.game-page:has(.overlay:not(.hidden)) .hero-hud,
body.game-page.menu-open .hero-hud {
  visibility: hidden;
  opacity: 0;
}

@keyframes heroHudLow {
  0%, 100% { box-shadow: 0 0 0 rgba(220, 80, 70, 0); }
  50% { box-shadow: 0 0 8px rgba(220, 80, 70, 0.42); }
}

@media (max-width: 980px) {
  body.game-page .hero-hud {
    top: 60px;
    width: min(300px, calc(100vw - 16px));
  }
}

/* На узком экране шапка становится выше (навигация в две строки),
   поэтому сводка начинается под ней, а не поверх меню. */
@media (max-width: 900px) {
  body.game-page .hero-hud {
    top: 82px;
  }
}

@media (max-width: 760px) {
  body.game-page .hero-hud {
    top: 82px;
    right: 8px;
    left: 8px;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    width: auto;
    padding: 7px 9px 8px;
  }

  body.game-page .hero-hud-head {
    grid-column: 1;
  }

  body.game-page .hero-hud-gold {
    grid-column: 2;
    grid-row: 1;
  }

  body.game-page .hero-hud-bar,
  body.game-page .hero-hud-foot,
  body.game-page .hero-hud-story {
    grid-column: 1 / -1;
  }

  body.game-page .hero-hud-bar.hp {
    margin-top: 5px;
  }

  body.game-page .hero-hud-foot {
    margin-top: 4px;
    padding-top: 4px;
  }

  body.game-page .hero-hud-place {
    display: none;
  }

  body.game-page .hero-hud-story {
    margin-top: 5px;
    min-height: 24px;
  }
}

@media (prefers-reduced-motion: reduce) {
  body.game-page .hero-hud.is-low .hero-hud-bar.hp .hero-hud-track {
    animation: none;
  }
}

body.game-page .side-panel .side-card {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
}

body.game-page .side-panel .side-card + .side-card {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid rgba(125, 162, 217, 0.16);
}

body.game-page #hud-btn.active {
  color: #f6c453;
  border-color: rgba(246, 196, 83, 0.45);
}

@media (max-width: 980px) {
  body.game-page .site-head {
    padding: 6px 10px;
  }

  body.game-page .side-panel {
    top: 58px;
    left: auto;
    right: 8px;
    bottom: auto;
    width: min(320px, calc(100vw - 16px));
    max-height: 46vh;
  }

  body.game-page #screen-game .minimap {
    display: none;
  }

  body.game-page #screen-game .game-msg {
    top: 58px;
    max-width: calc(100vw - 24px);
    white-space: normal;
    text-align: center;
  }

  body.game-page #screen-game .log {
    left: 8px;
    right: 8px;
    top: auto;
    bottom: 70px;
    width: auto;
    max-height: 30%;
  }
}

/* Первый спуск: небольшая памятка поверх карты, не перекрывает управление. */
.tutorial-panel {
  position: fixed;
  z-index: 45;
  left: clamp(12px, 2vw, 28px);
  top: clamp(78px, 9vh, 110px);
  width: min(360px, calc(100vw - 32px));
  max-height: calc(100vh - 120px);
  overflow: auto;
  padding: 12px 14px 11px;
  pointer-events: none;
  color: #dfe7f1;
  background: rgba(8, 18, 34, 0.94);
  border: 1px solid rgba(246, 196, 83, 0.28);
  border-left: 3px solid #f6c453;
  border-radius: 10px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(5px);
}

.tutorial-panel.hidden {
  display: none;
}

.tutorial-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}

.tutorial-kicker {
  color: #f6c453;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.tutorial-progress {
  margin-left: 6px;
  color: #7f8b9d;
  font-size: 11px;
}

.tutorial-skip {
  pointer-events: auto;
  padding: 4px 7px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 6px;
  background: transparent;
  color: #9da9ba;
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}

.tutorial-skip:hover,
.tutorial-skip:focus-visible {
  border-color: rgba(246, 196, 83, 0.6);
  color: #f6c453;
  outline: none;
}

.tutorial-steps {
  display: grid;
  gap: 5px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.tutorial-steps li {
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr);
  gap: 7px;
  align-items: start;
  color: #8fa3bf;
  font-size: 12px;
  line-height: 1.25;
  opacity: 0.65;
}

.tutorial-steps li::before {
  content: "○";
  color: #66758b;
  line-height: 1.15;
}

.tutorial-steps li b {
  grid-column: 2;
  color: #dfe7f1;
  font-weight: 600;
}

.tutorial-steps li span {
  grid-column: 2;
  grid-row: 2;
  display: block;
  margin-top: 1px;
  color: #7f8b9d;
  font-size: 10px;
}

.tutorial-steps li.is-current {
  color: #f4f0e6;
  opacity: 1;
}

.tutorial-steps li.is-current::before {
  content: "▶";
  color: #f6c453;
}

.tutorial-steps li.is-current b {
  color: #f6c453;
}

.tutorial-steps li.is-done {
  opacity: 0.85;
}

.tutorial-steps li.is-done::before {
  content: "✓";
  color: #91c98b;
}

.tutorial-steps li.is-done b {
  color: #b9d6b0;
}

.tutorial-hint {
  margin: 9px 0 0;
  padding-top: 8px;
  border-top: 1px solid rgba(125, 162, 217, 0.16);
  color: #b9c9dc;
  font-size: 11px;
  line-height: 1.4;
}

@media (max-width: 760px) {
  .tutorial-panel {
    top: auto;
    right: 12px;
    bottom: 72px;
    left: 12px;
    width: auto;
    max-height: 42vh;
    overflow: auto;
  }
}

/* ---------- Визуальный проход A: HUD как каменный журнал ---------- */

body.game-page .side-panel {
  gap: 0;
  padding: 0;
  overflow-y: auto;
  background:
    linear-gradient(180deg, rgba(32, 44, 58, 0.98), rgba(11, 17, 26, 0.99));
  border: 2px solid var(--gold-dim, rgba(214, 168, 75, 0.32));
  border-radius: 2px;
  box-shadow:
    6px 6px 0 rgba(0, 0, 0, 0.42),
    inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

body.game-page .side-panel > .side-card {
  order: 4;
  padding: 12px 13px 14px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(214, 168, 75, 0.16);
  border-radius: 0;
  box-shadow: none;
}

body.game-page .side-panel > .side-card:last-child {
  border-bottom: 0;
}

body.game-page .side-panel > .side-card:nth-child(3) {
  order: 1;
}

/* В деревне карточка героя пустая: HP и снаряжение там не показываются. */
.stage.village .side-panel > .side-card:nth-child(3) {
  display: none;
}

body.game-page #village-info {
  order: 2;
}

body.game-page #wallet-block {
  order: 3;
}

body.game-page #inventory-card {
  order: 5;
}

body.game-page .side-panel > .side-card:nth-child(3)::before,
body.game-page .side-panel > .side-card:nth-child(4)::before,
body.game-page .side-panel > .side-card:nth-child(5)::before {
  display: block;
  margin-bottom: 7px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(214, 168, 75, 0.2);
  color: var(--gold, #d6a84b);
  font-family: var(--font-data, Consolas, monospace);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

body.game-page .side-panel > .side-card:nth-child(3)::before {
  content: "Герой";
}

body.game-page .side-panel > .side-card:nth-child(4)::before {
  content: "Снаряжение";
}

body.game-page .side-panel > .side-card:nth-child(5)::before {
  content: "Сумка";
}

body.game-page .side-title {
  margin-bottom: 7px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(214, 168, 75, 0.2);
  color: var(--gold, #d6a84b);
  font-family: var(--font-data, Consolas, monospace);
  font-size: 10px;
  letter-spacing: 0.14em;
}

body.game-page .side-panel .hud {
  gap: 8px;
  margin-bottom: 0;
}

body.game-page .side-panel .hud-block {
  padding: 0 0 8px;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(214, 168, 75, 0.1);
  border-radius: 0;
}

body.game-page .side-panel .hud-block:last-child {
  padding-bottom: 0;
  border-bottom: 0;
}

body.game-page .side-panel .hud-label {
  color: var(--parchment-dim, #b9b3a5);
  font-family: var(--font-data, Consolas, monospace);
  font-size: 10px;
  letter-spacing: 0.1em;
}

body.game-page .side-panel .hud-num {
  margin-top: 3px;
  color: var(--parchment, #eee4cf);
  font-family: var(--font-data, Consolas, monospace);
  font-size: 12px;
}

body.game-page .side-panel .floor-name {
  color: var(--gold-bright, #f0c66a);
  font-family: var(--font-data, Consolas, monospace);
  letter-spacing: 0.06em;
}

body.game-page .side-panel .lead {
  color: var(--parchment-dim, #b9b3a5);
  font-size: 12px;
  line-height: 1.45;
}

body.game-page .side-panel .hp-bar,
body.game-page .side-panel .xp-bar {
  height: 9px;
  border: 1px solid rgba(214, 168, 75, 0.24);
  border-radius: 0;
  background: #140d0e;
}

body.game-page .side-panel .hp-bar i {
  background: linear-gradient(90deg, #7f2f2f, #c96b3b);
}

body.game-page .side-panel .xp-bar i {
  background: linear-gradient(90deg, #6f8f5a, #d6a84b);
}

body.game-page .side-panel .equip-slot {
  padding: 7px;
  background: rgba(7, 11, 18, 0.4);
  border: 1px solid rgba(214, 168, 75, 0.16);
  border-radius: 0;
}

body.game-page .side-panel .equip-label {
  color: var(--parchment-dim, #b9b3a5);
  font-family: var(--font-data, Consolas, monospace);
  font-size: 9px;
}

body.game-page .side-panel .equip-value {
  color: var(--parchment, #eee4cf);
  font-family: var(--font-data, Consolas, monospace);
  font-size: 11px;
}

/* Памятка первого спуска в той же каменной рамке, что и журнал. */
.tutorial-panel {
  border-width: 2px;
  border-left-width: 4px;
  border-radius: 2px;
  background:
    linear-gradient(180deg, rgba(32, 44, 58, 0.97), rgba(11, 17, 26, 0.98));
  box-shadow:
    6px 6px 0 rgba(0, 0, 0, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.tutorial-kicker,
.tutorial-progress,
.tutorial-steps li b,
.tutorial-hint {
  font-family: var(--font-data, Consolas, monospace);
}

.tutorial-steps li b {
  font-size: 11px;
  letter-spacing: 0.04em;
}

.tutorial-skip {
  border-radius: 2px;
}

/* Верхняя плашка сообщений убрана из вида: она перекрывала мини-карту и
   дублировала журнал/обучение. Текст остаётся в DOM для aria-live и проверок. */
#game-msg {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  clip-path: inset(50%) !important;
  white-space: nowrap !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: none !important;
  color: transparent !important;
  font-size: 0 !important;
  pointer-events: none !important;
}

/* Верхние ярлыки убраны: лавка доступна у торговца, кузница — по F,
   панель героя всегда видна. Журнал и пауза остаются в шапке. */
#shop-btn,
#forge-btn,
#hud-btn,
#village-btn {
  display: none !important;
}

/* ---------- Фон боя: туман и угли под затемнением ---------- */

#battle-overlay {
  isolation: isolate;
  background:
    radial-gradient(120% 90% at 50% 40%,
      rgba(15, 32, 60, 0.48) 0%,
      rgba(2, 6, 23, 0.82) 72%),
    rgba(2, 6, 23, 0.66);
}

#battle-overlay::before,
#battle-overlay::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 0;
}

/* Два медленных слоя тумана: двигаются только transform, без перерисовки
   градиентов на каждом кадре. */
#battle-overlay::before {
  inset: -12%;
  background:
    radial-gradient(42% 36% at 18% 42%, rgba(87, 120, 154, 0.16), transparent 72%),
    radial-gradient(38% 32% at 78% 58%, rgba(57, 91, 128, 0.14), transparent 72%),
    radial-gradient(34% 28% at 48% 18%, rgba(214, 168, 75, 0.055), transparent 72%);
  animation: battle-fog-drift 26s ease-in-out infinite alternate;
  will-change: transform;
}

/* Угли поднимаются снизу вверх; слой повторяется, поэтому шва не видно. */
#battle-overlay::after {
  background-image:
    radial-gradient(circle at 9% 88%, rgba(246, 196, 83, 0.85) 0 1px, transparent 1.7px),
    radial-gradient(circle at 23% 62%, rgba(201, 107, 59, 0.65) 0 1.2px, transparent 2px),
    radial-gradient(circle at 41% 94%, rgba(246, 196, 83, 0.65) 0 1px, transparent 1.6px),
    radial-gradient(circle at 57% 74%, rgba(201, 107, 59, 0.55) 0 1px, transparent 1.8px),
    radial-gradient(circle at 72% 90%, rgba(246, 196, 83, 0.7) 0 1.2px, transparent 2px),
    radial-gradient(circle at 86% 66%, rgba(201, 107, 59, 0.6) 0 1px, transparent 1.7px);
  background-size: 340px 300px;
  opacity: 0.5;
  animation: battle-embers-rise 16s linear infinite;
  will-change: background-position;
}

#battle-box {
  position: relative;
  z-index: 1;
}

@keyframes battle-fog-drift {
  from {
    transform: translate3d(-2.5%, 1.5%, 0) scale(1.02);
  }
  to {
    transform: translate3d(2.5%, -1.5%, 0) scale(1.07);
  }
}

@keyframes battle-embers-rise {
  from {
    background-position: 0 0;
  }
  to {
    background-position: -34px -300px;
  }
}

@media (prefers-reduced-motion: reduce) {
  #battle-overlay::before,
  #battle-overlay::after {
    animation: none;
  }
}

/* Окно боя статично: декоративный туман выходит за края и раньше создавал
   внешнюю прокрутку. Прокрутка остаётся только внутри карточки боя. */
#battle-overlay {
  overflow: hidden !important;
  overscroll-behavior: none;
}

/* ============================================================
   Единая система игровых окон.
   Каркас: шапка -> тело -> подвал; размер зависит от задачи.
   ============================================================ */

.overlay {
  overflow: hidden;
}

.overlay > .battle {
  width: min(760px, 94vw);
  max-height: min(88vh, 900px);
  padding: 0 20px 16px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 2px solid var(--gold-dim);
  border-left: 4px solid var(--gold);
  border-radius: 2px;
  background:
    linear-gradient(180deg, rgba(32, 44, 58, 0.98), rgba(11, 17, 26, 0.99));
  box-shadow:
    10px 10px 0 rgba(0, 0, 0, 0.48),
    inset 0 1px 0 rgba(255, 255, 255, 0.045);
}

#battle-box {
  width: min(980px, 94vw);
  max-height: min(92vh, 900px);
}

#end-box,
#blessing-box {
  width: min(520px, 94vw);
  max-height: min(88vh, 760px);
  overflow-y: auto;
}

/* Шапка — единственное место для закрытия. */
.overlay > .battle > .battle-head {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  gap: 14px;
  margin: 0 -20px;
  padding: 14px 20px 12px;
  border-bottom: 1px solid var(--gold-dim);
  background: rgba(7, 11, 18, 0.3);
}

.overlay > .battle > .battle-head .enemy-name {
  margin: 0;
  color: var(--parchment);
  font: 700 24px/1.08 var(--font-display);
}

.overlay > .battle > .battle-head .hud-num {
  margin-top: 5px;
  color: var(--parchment-dim);
  font: 10px/1.35 var(--font-data);
}

.overlay > .battle > .battle-head .win-chip {
  margin-left: auto;
  padding: 5px 8px;
  border: 1px solid var(--line);
  color: var(--gold-bright);
  font: 10px/1 var(--font-data);
  letter-spacing: 0.05em;
  white-space: nowrap;
}

.overlay > .battle > .battle-foot .foot-note {
  margin-right: auto;
  color: var(--parchment-dim);
  font: 9px/1.2 var(--font-data);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.overlay > .battle > .battle-foot .win-chip {
  margin-left: auto;
  padding: 5px 8px;
  border: 1px solid var(--line);
  color: var(--gold-bright);
  font: 10px/1 var(--font-data);
  letter-spacing: 0.05em;
  white-space: nowrap;
}

.overlay > .battle > .battle-head .exit-btn {
  width: 34px;
  height: 34px;
  min-width: 34px;
  margin-left: auto;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--gold-dim);
  border-radius: 2px;
  background: transparent;
  color: var(--parchment-dim);
  font-size: 0;
  line-height: 1;
  cursor: pointer;
}

.overlay > .battle > .battle-head .exit-btn::before {
  content: "×";
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  font: 22px/1 Georgia, serif;
}

.overlay > .battle > .battle-head .exit-btn:hover,
.overlay > .battle > .battle-head .exit-btn:focus-visible {
  border-color: var(--gold);
  color: var(--gold-bright);
  outline: none;
}

/* Тело — единственная прокручиваемая зона. */
.overlay > .battle > .battle-mid {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 0;
  scrollbar-width: none;
}

.overlay > .battle > .battle-mid::-webkit-scrollbar {
  width: 0;
  height: 0;
}

/* Подвал — действия всегда на месте. */
.overlay > .battle > .battle-foot {
  flex: 0 0 auto;
  margin: 0 -20px;
  padding: 11px 20px 0;
  border-top: 1px solid var(--gold-dim);
  background: rgba(7, 11, 18, 0.3);
}

/* Диалоги и страж не имеют отдельного battle-mid: прокручиваем тело
   карточки, оставляя шапку закреплённой. */
#dialog-box,
#entrance-box,
#calibration-box {
  overflow-y: auto;
  scrollbar-width: none;
}

#dialog-box::-webkit-scrollbar,
#entrance-box::-webkit-scrollbar,
#calibration-box::-webkit-scrollbar {
  width: 0;
  height: 0;
}

#dialog-box > .battle-head,
#entrance-box > .battle-head,
#calibration-box > .battle-head {
  position: sticky;
  top: 0;
  z-index: 2;
}

/* Кнопки внутри окон — один язык. */
.overlay > .battle .btn {
  min-height: 40px;
  border-radius: 2px;
  border-color: var(--gold-dim);
  background: rgba(24, 34, 46, 0.82);
  box-shadow: none;
  color: var(--parchment);
  font: 700 11px/1 var(--font-data);
  letter-spacing: 0.06em;
}

.overlay > .battle .btn:hover,
.overlay > .battle .btn:focus-visible {
  border-color: var(--gold);
  box-shadow: none;
  color: var(--gold-bright);
  outline: none;
}

.overlay > .battle .btn.primary {
  border-color: var(--gold);
  background: var(--gold);
  color: #111821;
}

.overlay > .battle .btn.primary:hover,
.overlay > .battle .btn.primary:focus-visible {
  background: var(--gold-bright);
  color: #111821;
}

/* Финальные окна без шапки: тот же каменный каркас, но своя типографика. */
#end-box > .game-over,
#blessing-box > .battle-head {
  margin-bottom: 10px;
}

#end-box h2,
#blessing-box h2 {
  color: var(--parchment);
  font-family: var(--font-display);
}

#end-box .lead,
#blessing-box .lead {
  color: var(--parchment-dim);
}

@media (max-width: 700px) {
  .overlay > .battle {
    width: 100%;
    max-height: 92vh;
    padding-left: 14px;
    padding-right: 14px;
  }

  .overlay > .battle > .battle-head,
  .overlay > .battle > .battle-foot {
    margin-left: -14px;
    margin-right: -14px;
    padding-left: 14px;
    padding-right: 14px;
  }

  .overlay > .battle > .battle-head .enemy-name {
    font-size: 21px;
  }

  #end-box,
  #blessing-box {
    width: 100%;
  }
}

/* На телефоне сцена боя вертикальная: иначе две колонки статистики
   наезжают друг на друга, а портреты выдавливают полосы здоровья. */
@media (max-width: 700px) {
  #battle-box .scene-arena {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
    padding-top: 0;
  }

  #battle-box .fighter {
    flex: 0 0 auto;
    width: 100%;
    gap: 8px;
    padding: 0;
  }

  #battle-box .fighter-hero {
    flex-direction: row;
  }

  #battle-box .fighter-enemy {
    flex-direction: row-reverse;
  }

  #battle-box .fighter-stats {
    flex: 1 1 auto;
  }

  #battle-box .battle-scene .battle-portrait {
    width: 48px;
    height: 48px;
  }

  #battle-box .scene-clash {
    display: none;
  }
}

/* Лавка: компактные товарные строки вместо длинных описаний.
   Цена и бонус остаются в первой строке; описание, сеты и сравнение
   доступны в сумке, а не отнимают высоту у витрины. */
#shop-box .shop-cols {
  gap: 18px;
}

#shop-box .inv-item {
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
}

#shop-box .inv-item .info {
  min-width: 0;
}

#shop-box .inv-item .info > b {
  font-size: 12.5px;
}

#shop-box .inv-item .info > span:first-of-type {
  margin-top: 3px;
  color: var(--parchment-dim);
  font-size: 9.5px;
}

#shop-box .shop-buy .inv-item .info > span:not(:first-of-type),
#shop-box .shop-sell .inv-item .info > span:not(:first-of-type) {
  display: none;
}

#shop-box .inv-actions .btn {
  min-height: 31px;
  padding: 0 9px;
  font-size: 9.5px;
}

#shop-box .shop-note,
#shop-box .inv-stats {
  font-size: 10px;
}

/* Диалог: та же схема, но содержимое — слоты жителей, а не текстовая стена. */
#dialog-box {
  overflow: hidden;
}

#dialog-box > .battle-head {
  position: static;
}

#dialog-box .dialog-body {
  padding-top: 12px;
}

#dialog-box .hub-shop {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

#dialog-box .hub-card {
  gap: 5px;
  padding: 10px;
  border: 1px solid rgba(214, 168, 75, 0.2);
  border-left: 2px solid rgba(214, 168, 75, 0.45);
  border-radius: 2px;
  background: rgba(7, 11, 18, 0.36);
}

#dialog-box .hub-card-head {
  font-size: 12.5px;
}

#dialog-box .hub-card-head b {
  color: var(--parchment);
  font-family: var(--font-ui);
}

#dialog-box .hub-price {
  color: var(--gold-bright);
  font: 10px/1 var(--font-data);
}

#dialog-box .hub-card-note {
  margin: 0;
  color: var(--parchment-dim);
  font-size: 10.5px;
  line-height: 1.35;
}

#dialog-box .hub-stock {
  color: var(--moss);
  font: 9px/1.2 var(--font-data);
}

#dialog-box .hub-buy {
  width: 100%;
  min-height: 32px;
  margin-top: 2px;
  padding: 0 8px;
  border-radius: 2px;
  font-size: 9.5px;
}

#dialog-box .quest-head,
#dialog-box h3 {
  margin-top: 12px;
  padding-bottom: 6px;
  border-bottom: 1px solid rgba(214, 168, 75, 0.16);
  color: var(--gold);
  font: 10px/1.2 var(--font-data);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

#dialog-box .lead {
  color: var(--parchment-dim);
  font-size: 11px;
  line-height: 1.45;
}

#dialog-box .build-block {
  border: 1px solid rgba(214, 168, 75, 0.16);
  border-radius: 2px;
  background: rgba(7, 11, 18, 0.28);
}

@media (max-width: 640px) {
  #dialog-box .hub-shop {
    grid-template-columns: 1fr;
  }
}

/* Событийный лог больше не часть интерфейса: он остаётся скрытым для
   проверок, а кнопка «Журнал» открывает задания. */
#log {
  display: none !important;
}

#journal-box {
  width: min(860px, 94vw);
}

.journal-body {
  display: flex;
  flex-direction: column;
  min-height: 0;
  scrollbar-width: thin;
  scrollbar-color: rgba(214, 168, 75, 0.3) transparent;
}

/* В журнале полоса прокрутки видна: сюжет длиннее окна, и без неё
   последняя глава выглядела бы отсутствующей. */
#journal-box .journal-body::-webkit-scrollbar {
  width: 8px;
}

#journal-box .journal-body::-webkit-scrollbar-thumb {
  border: 2px solid transparent;
  border-radius: 8px;
  background-clip: content-box;
  background-color: rgba(214, 168, 75, 0.3);
}

.journal-tabs {
  display: flex;
  gap: 4px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(214, 168, 75, 0.18);
}

.journal-tab {
  min-height: 34px;
  padding: 0 11px;
  border: 1px solid transparent;
  border-radius: 2px;
  background: transparent;
  color: var(--parchment-dim);
  font: 700 10px/1 var(--font-data);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
}

.journal-tab b {
  margin-left: 5px;
  color: var(--gold);
}

.journal-tab:hover,
.journal-tab:focus-visible {
  border-color: var(--gold-dim);
  color: var(--parchment);
  outline: none;
}

.journal-tab.is-active {
  border-color: var(--gold);
  background: rgba(214, 168, 75, 0.12);
  color: var(--gold-bright);
}

.journal-list {
  display: grid;
  gap: 8px;
  padding-top: 10px;
}

.journal-card {
  padding: 11px 12px;
  border: 1px solid rgba(214, 168, 75, 0.18);
  border-left: 2px solid var(--gold);
  border-radius: 2px;
  background: rgba(7, 11, 18, 0.36);
}

.journal-card.is-done {
  border-left-color: var(--moss);
}

.journal-card.is-failed {
  border-left-color: var(--ember);
}

.journal-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.journal-kind {
  color: var(--parchment-dim);
  font: 9px/1 var(--font-data);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.journal-status {
  color: var(--gold-bright);
  font: 9px/1 var(--font-data);
  white-space: nowrap;
}

.journal-card.is-done .journal-status {
  color: #a9c79d;
}

.journal-card.is-failed .journal-status {
  color: #d79076;
}

.journal-card h3 {
  margin: 6px 0 4px;
  color: var(--parchment);
  font: 700 16px/1.2 var(--font-display);
}

.journal-card p {
  margin: 0;
  color: var(--parchment-dim);
  font-size: 11px;
  line-height: 1.45;
}

.journal-meta {
  margin-top: 7px;
  padding-top: 6px;
  border-top: 1px solid rgba(214, 168, 75, 0.1);
  color: var(--gold);
  font: 9px/1.3 var(--font-data);
}

.journal-empty {
  padding: 22px 12px;
  border: 1px dashed rgba(214, 168, 75, 0.18);
  color: var(--parchment-dim);
  font: 11px/1.4 var(--font-data);
  text-align: center;
}

/* ---------- Сюжетная вкладка журнала ---------- */

.story-campaign {
  display: grid;
  gap: 12px;
  padding-top: 10px;
}

.story-prologue {
  padding: 10px 12px;
  border: 1px solid rgba(214, 168, 75, 0.16);
  border-left: 2px solid rgba(214, 168, 75, 0.45);
  background: rgba(7, 11, 18, 0.28);
}

.story-kicker {
  color: var(--gold);
  font: 9px/1.2 var(--font-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.story-prologue p {
  margin: 6px 0 0;
  color: var(--parchment-dim);
  font-size: 11.5px;
  line-height: 1.5;
}

.story-current {
  padding: 14px 14px 13px;
  border: 1px solid rgba(214, 168, 75, 0.28);
  border-left: 3px solid var(--gold);
  background:
    linear-gradient(180deg, rgba(31, 42, 55, 0.62), rgba(9, 14, 22, 0.66));
}

.story-current.is-ready {
  border-left-color: #91c98b;
  background:
    linear-gradient(180deg, rgba(35, 52, 39, 0.52), rgba(9, 16, 24, 0.66));
}

.story-current.is-done {
  border-left-color: #91c98b;
}

.story-current h3 {
  margin: 7px 0 6px;
  color: var(--parchment);
  font: 700 24px/1.12 var(--font-display);
}

.story-lead {
  margin: 0;
  color: var(--parchment-dim);
  font-size: 12.5px;
  line-height: 1.55;
}

.story-objective {
  display: flex;
  gap: 10px;
  align-items: baseline;
  margin-top: 11px;
  padding-top: 9px;
  border-top: 1px solid rgba(214, 168, 75, 0.16);
}

.story-objective > span {
  flex: 0 0 auto;
  color: var(--gold);
  font: 8px/1 var(--font-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.story-objective p {
  margin: 0;
  color: var(--parchment);
  font-size: 11.5px;
  line-height: 1.4;
}

.story-progress {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  justify-content: space-between;
  margin-top: 9px;
  padding-top: 8px;
  border-top: 1px solid rgba(214, 168, 75, 0.12);
  color: var(--parchment-dim);
  font: 10px/1.4 var(--font-data);
}

.story-progress span:last-child {
  color: var(--gold);
}

.story-progress.is-ready {
  color: #a9c79d;
}

.story-progress.is-ready span:last-child {
  color: #a9c79d;
}

.story-path-head {
  margin-top: 2px;
  color: var(--parchment-dim);
  font: 9px/1 var(--font-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.story-path {
  list-style: none;
  margin: 0;
  padding: 0;
}

.story-path-step {
  position: relative;
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  gap: 10px;
  align-items: start;
  padding: 7px 0;
}

.story-path-step::before {
  content: "";
  position: absolute;
  top: 32px;
  bottom: -5px;
  left: 13px;
  width: 1px;
  background: rgba(214, 168, 75, 0.18);
}

.story-path-step:last-child::before {
  display: none;
}

.story-path-num {
  display: grid;
  place-items: center;
  width: 27px;
  height: 27px;
  border: 1px solid rgba(214, 168, 75, 0.25);
  border-radius: 50%;
  background: rgba(7, 11, 18, 0.62);
  color: var(--parchment-dim);
  font: 9px/1 var(--font-data);
}

.story-path-text {
  min-width: 0;
  padding-top: 1px;
}

.story-path-text b {
  display: block;
  overflow: hidden;
  color: var(--parchment-dim);
  font-size: 12px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.story-path-text span {
  display: block;
  margin-top: 2px;
  color: #71829c;
  font-size: 10px;
  line-height: 1.35;
}

.story-path-state {
  padding-top: 2px;
  color: #71829c;
  font: 8px/1 var(--font-data);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.story-path-step.is-done .story-path-num {
  border-color: rgba(145, 201, 139, 0.55);
  color: #a9c79d;
}

.story-path-step.is-done .story-path-text b {
  color: #b9d6b0;
}

.story-path-step.is-current .story-path-num {
  border-color: var(--gold);
  background: rgba(214, 168, 75, 0.14);
  color: var(--gold-bright);
  box-shadow: 0 0 0 3px rgba(214, 168, 75, 0.08);
}

.story-path-step.is-current .story-path-text b {
  color: var(--gold-bright);
}

.story-path-step.is-current .story-path-state {
  color: var(--gold);
}

.story-path-step.is-current.is-ready .story-path-num {
  border-color: #91c98b;
  color: #a9c79d;
  box-shadow: 0 0 0 3px rgba(145, 201, 139, 0.1);
}

.story-path-step.is-current.is-ready .story-path-state {
  color: #a9c79d;
}

.story-path-step.is-locked {
  opacity: 0.55;
}

@media (max-width: 640px) {
  .story-current {
    padding: 12px;
  }

  .story-current h3 {
    font-size: 20px;
  }

  .story-path-step {
    grid-template-columns: 26px minmax(0, 1fr);
    gap: 8px;
  }

  .story-path-num {
    width: 25px;
    height: 25px;
  }

  .story-path-step::before {
    left: 12px;
  }

  .story-path-state {
    grid-column: 2;
    padding-top: 0;
  }
}

@media (max-width: 640px) {
  .journal-tabs {
    gap: 2px;
  }

  .journal-tab {
    flex: 1 1 0;
    padding: 0 6px;
    font-size: 9px;
  }

  .journal-tab b {
    display: block;
    margin: 3px 0 0;
  }
}

/* ============================================================
   Верхнее меню и выезжающие панели.
   Логотипа и названия в шапке больше нет; игровые разделы — по центру.
   ============================================================ */

body.game-page .site-head {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 8px 16px;
}

body.game-page .game-nav {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

body.game-page:has(.stage.playing) .game-nav {
  display: flex;
}

body.game-page .nav-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 34px;
  padding: 0 9px;
  border: 1px solid transparent;
  border-radius: 2px;
  background: transparent;
  color: var(--parchment-dim);
  font: 600 10px/1 var(--font-data);
  letter-spacing: 0.04em;
  cursor: pointer;
}

body.game-page .nav-btn svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: square;
  stroke-linejoin: miter;
}

body.game-page .nav-btn:hover,
body.game-page .nav-btn:focus-visible {
  border-color: var(--gold-dim);
  color: var(--parchment);
  outline: none;
}

body.game-page .nav-btn.active {
  border-color: var(--gold);
  background: rgba(214, 168, 75, 0.12);
  color: var(--gold-bright);
}

body.game-page .head-actions {
  position: absolute;
  top: 50%;
  right: 16px;
  display: none;
  transform: translateY(-50%);
  align-items: center;
  gap: 12px;
}

body.game-page:has(.stage.playing) .head-actions {
  display: flex;
}

body.game-page .head-actions .app-version {
  color: var(--parchment-dim);
  opacity: 0.65;
}

/* Панели: одна открыта, остальные скрыты. */
.game-dock {
  position: absolute;
  top: 58px;
  left: 50%;
  z-index: 55;
  width: max-content;
  max-width: calc(100vw - 20px);
  transform: translateX(-50%);
  pointer-events: none;
}

.game-dock.hidden {
  display: none;
}

.game-panel {
  display: none;
  width: 420px;
  max-width: calc(100vw - 20px);
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  pointer-events: auto;
  border: 2px solid var(--gold-dim);
  border-left: 4px solid var(--gold);
  border-radius: 2px;
  background:
    linear-gradient(180deg, rgba(32, 44, 58, 0.99), rgba(11, 17, 26, 0.995));
  box-shadow:
    8px 8px 0 rgba(0, 0, 0, 0.5),
    inset 0 1px 0 rgba(255, 255, 255, 0.04);
  scrollbar-width: none;
}

.game-panel::-webkit-scrollbar {
  width: 0;
  height: 0;
}

.game-panel.is-open {
  display: block;
  animation: game-panel-in 0.16s ease-out;
}

#panel-stats { width: 380px; }
#panel-place { width: 440px; }
#panel-inventory { width: 620px; }
#panel-achievements { width: 520px; }

@keyframes game-panel-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}

.panel-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--gold-dim);
  background: rgba(7, 11, 18, 0.3);
}

.panel-kicker {
  display: block;
  margin-bottom: 4px;
  color: var(--gold);
  font: 9px/1 var(--font-data);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.panel-head h2 {
  margin: 0;
  color: var(--parchment);
  font: 700 22px/1.05 var(--font-display);
}

.panel-close {
  width: 30px;
  height: 30px;
  margin-left: auto;
  padding: 0;
  border: 1px solid var(--gold-dim);
  border-radius: 2px;
  background: transparent;
  color: var(--parchment-dim);
  font: 20px/1 Georgia, serif;
  cursor: pointer;
}

.panel-close:hover,
.panel-close:focus-visible {
  border-color: var(--gold);
  color: var(--gold-bright);
  outline: none;
}

.panel-body {
  padding: 12px 14px 14px;
}

.panel-section-title {
  margin-bottom: 7px;
  padding-bottom: 5px;
  border-bottom: 1px solid rgba(214, 168, 75, 0.18);
  color: var(--gold);
  font: 9px/1 var(--font-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Статы */
#stats-slot {
  display: grid;
  grid-template-columns: 1fr;
  gap: 8px;
}

#stats-slot .hud-block {
  min-width: 0;
  padding: 8px;
  border: 1px solid rgba(214, 168, 75, 0.16);
  background: rgba(7, 11, 18, 0.32);
}

#stats-slot .hud-block:last-child {
  grid-column: 1 / -1;
  border: 0;
  padding: 2px 0 0;
  background: none;
}

#stats-slot .hud-label {
  color: var(--parchment-dim);
  font: 9px/1.2 var(--font-data);
  letter-spacing: 0.08em;
}

#stats-slot .hud-num {
  margin-top: 4px;
  color: var(--parchment);
  font: 11px/1.3 var(--font-data);
}

#stats-slot .hp-bar,
#stats-slot .xp-bar {
  width: 100%;
  max-width: 100%;
  height: 9px;
  margin-top: 6px;
  border: 1px solid rgba(214, 168, 75, 0.22);
  border-radius: 0;
  background: #140d0e;
}

#stats-slot .hp-bar i {
  background: linear-gradient(90deg, #7f2f2f, #c96b3b);
}

#stats-slot .xp-bar i {
  background: linear-gradient(90deg, #6f8f5a, #d6a84b);
}

.stats-combat {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin-top: 10px;
}

.stats-combat span {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 8px;
  border: 1px solid rgba(214, 168, 75, 0.14);
  color: var(--parchment-dim);
  font: 9px/1 var(--font-data);
  text-transform: uppercase;
}

.stats-combat b {
  color: var(--gold-bright);
  font-size: 12px;
}

.stats-effects {
  margin-top: 10px;
}

.stats-effects #effect-list {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

/* Место */
.place-lines {
  display: grid;
  gap: 6px;
}

.place-lines .hud-num,
.place-lines #floor-name {
  padding: 7px 8px;
  border: 1px solid rgba(214, 168, 75, 0.14);
  background: rgba(7, 11, 18, 0.28);
  color: var(--parchment-dim);
  font: 10px/1.3 var(--font-data);
}

.place-lines #floor-name {
  color: var(--gold-bright);
  font: 700 16px/1.2 var(--font-display);
}

#place-village-slot #village-info {
  display: none;
}

body:has(.stage.village) #place-village-slot #village-info {
  display: block;
  margin-top: 10px;
  padding: 9px 10px;
  border: 1px solid rgba(214, 168, 75, 0.16);
  background: rgba(7, 11, 18, 0.25);
}

body:has(.stage.village) #place-dungeon {
  display: none;
}

/* Инвентарь */
#inventory-wallet,
#inventory-equip,
#inventory-bag {
  margin-bottom: 10px;
}

#inventory-wallet::before,
#inventory-equip::before,
#inventory-bag::before {
  display: block;
  margin-bottom: 6px;
  padding-bottom: 5px;
  border-bottom: 1px solid rgba(214, 168, 75, 0.18);
  color: var(--gold);
  font: 9px/1 var(--font-data);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

#inventory-wallet::before { content: "Кошелёк"; }
#inventory-equip::before { content: "Снаряжение"; }
#inventory-bag::before { content: "Сумка"; }

#inventory-wallet .hud-num,
#inventory-wallet .lead {
  margin: 3px 0;
  color: var(--parchment-dim);
  font: 10px/1.35 var(--font-data);
}

#inventory-equip .equip-bar {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 5px;
}

#inventory-bag #inventory-card {
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
}

#inventory-bag #inventory-box > .inv-section:first-child {
  display: none;
}

/* Достижения */
#achievements-slot #game-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin: 0;
}

#achievements-slot .lead {
  color: var(--parchment-dim);
  font-size: 10px;
}

/* Постоянная колонка больше не нужна. */
body.game-page .side-panel {
  display: none !important;
}

@media (max-width: 900px) {
  body.game-page .site-head {
    min-height: 48px;
    padding: 6px 8px;
  }

  body.game-page .nav-btn {
    gap: 3px;
    min-height: 30px;
    padding: 0 5px;
    font-size: 8.5px;
  }

  body.game-page .nav-btn svg {
    width: 12px;
    height: 12px;
  }

  body.game-page .head-actions {
    right: 6px;
    gap: 6px;
  }

  body.game-page .head-actions .app-version,
  body.game-page .head-actions #fullscreen-btn {
    display: none;
  }

  .game-dock {
    top: 52px;
    width: calc(100vw - 12px);
  }

  .game-panel,
  #panel-stats,
  #panel-place,
  #panel-inventory,
  #panel-achievements {
    width: 100%;
    max-width: none;
  }
}

/* Шапка выше сцены: иначе плитки карты перехватывают клики по меню. */
body.game-page .site-head {
  z-index: 70;
  pointer-events: none;
}

body.game-page .site-head .game-nav,
body.game-page .site-head .head-actions {
  pointer-events: auto;
}

/* В сумке уже есть заголовок «Сумка»; внутренний h3 его дублирует. */
#inventory-bag #inventory-box > .inv-section h3 {
  display: none;
}

/* Журнал тоже выглядит как верхняя выезжающая панель, а не как
   полноэкранная модалка. */
#journal-overlay {
  place-items: start center;
  padding: 58px 16px 16px;
  background: rgba(2, 6, 23, 0.28);
  overflow: hidden;
}

#journal-box {
  margin: 0;
  animation: game-panel-in 0.16s ease-out;
}

@media (max-width: 900px) {
  #journal-overlay {
    padding: 52px 8px 8px;
  }
}

/* На телефоне меню переносится на две строки, а «Пауза» остаётся справа. */
@media (max-width: 900px) {
  body.game-page .site-head {
    min-height: 78px;
    align-items: flex-start;
    padding-top: 6px;
  }

  body.game-page .game-nav {
    flex-wrap: wrap;
    max-width: calc(100vw - 78px);
    row-gap: 2px;
  }

  body.game-page .head-actions {
    top: 10px;
    transform: none;
  }

  .game-dock {
    top: 82px;
  }

  #journal-overlay {
    padding-top: 82px;
  }

  body.game-page .game-nav {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    width: min(220px, calc(100vw - 88px));
    max-width: none;
    gap: 2px;
  }

  body.game-page .nav-btn[data-panel="place"] { grid-column: 1 / span 1; }
  body.game-page .nav-btn[data-panel="inventory"] { grid-column: 2 / span 1; }
  body.game-page .nav-btn[data-panel="journal"] { grid-column: 3 / span 1; }

  body.game-page .head-actions #menu-btn {
    display: grid;
    place-items: center;
    width: 34px;
    height: 32px;
    padding: 0;
    border: 1px solid var(--gold-dim);
    border-radius: 2px;
    font-size: 0;
  }

  body.game-page .head-actions #menu-btn::before {
    content: "Ⅱ";
    font: 700 14px/1 var(--font-data);
    letter-spacing: -0.08em;
  }
}

/* Название этажа на весь экран: пара секунд при спуске. */
#floor-arrival {
  position: fixed;
  inset: 0;
  z-index: 120;
  display: grid;
  place-items: center;
  max-width: none;
  padding: 0;
  border: 0;
  border-radius: 0;
  background:
    radial-gradient(circle at 50% 44%, rgba(30, 46, 66, 0.4), transparent 46%),
    rgba(2, 6, 14, 0.62);
  box-shadow: none;
  animation: floor-intro-in 0.22s ease-out;
  transition: opacity 0.38s ease;
}

/* Плавное исчезновение: .hidden оставляет элемент в кадре, но гасит его
   по прозрачности. Автопроверки по-прежнему видят класс hidden сразу. */
#floor-arrival.hidden {
  display: grid !important;
  opacity: 0;
  pointer-events: none;
}

#floor-arrival .floor-arrival-body {
  display: grid;
  place-items: center;
  width: 100%;
}

.floor-intro-card {
  width: min(680px, calc(100vw - 32px));
  padding: 24px 28px;
  border-top: 1px solid var(--gold-dim);
  border-bottom: 1px solid var(--gold-dim);
  background: rgba(7, 11, 18, 0.5);
  text-align: center;
}

.floor-intro-kicker {
  margin-bottom: 8px;
  color: var(--gold);
  font: 10px/1 var(--font-data);
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.floor-intro-title {
  margin: 0;
  color: var(--parchment);
  font: 700 clamp(32px, 5vw, 64px)/1.05 var(--font-display);
  letter-spacing: -0.02em;
}

/* Текст эпиграфа остаётся в разметке для проверок, но игроку не показывается:
   на спуске нужен только название этажа. */
.floor-intro-desc,
#floor-arrival-close {
  display: none !important;
}

@keyframes floor-intro-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (max-width: 640px) {
  .floor-intro-card {
    padding: 18px 16px;
  }

  .floor-intro-title {
    font-size: clamp(28px, 9vw, 42px);
  }
}

/* Пропуск хода — на месте бывшей подсказки, в стиле остальных панелей. */
.skip-btn {
  right: 10px;
  bottom: 10px;
  padding: 6px 8px;
  border: 1px solid var(--gold-dim);
  border-radius: 2px;
  background: rgba(7, 11, 18, 0.88);
  color: var(--parchment-dim);
  gap: 7px;
  font: 700 9px/1 var(--font-data);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.skip-btn:hover {
  border-color: var(--gold);
  background: rgba(14, 24, 38, 0.94);
  color: var(--gold-bright);
}

.skip-btn .action-label {
  font-size: 9px;
}

.skip-btn .action-key {
  padding: 2px 5px;
  border: 1px solid rgba(214, 168, 75, 0.22);
  border-radius: 2px;
  background: rgba(214, 168, 75, 0.1);
  color: var(--gold);
  font-size: 8px;
}

/* Справочник */
#codex-overlay {
  z-index: 100;
}

#codex-box {
  width: min(760px, 94vw);
}

.codex-body {
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.codex-tabs {
  display: flex;
  gap: 4px;
  padding-bottom: 10px;
  border-bottom: 1px solid rgba(214, 168, 75, 0.18);
}

.codex-tab {
  min-height: 32px;
  padding: 0 10px;
  border: 1px solid transparent;
  border-radius: 2px;
  background: transparent;
  color: var(--parchment-dim);
  font: 700 9px/1 var(--font-data);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
}

.codex-tab:hover,
.codex-tab:focus-visible {
  border-color: var(--gold-dim);
  color: var(--parchment);
  outline: none;
}

.codex-tab.is-active {
  border-color: var(--gold);
  background: rgba(214, 168, 75, 0.12);
  color: var(--gold-bright);
}

.codex-list {
  display: grid;
  gap: 7px;
  padding-top: 10px;
}

.codex-key,
.codex-card {
  padding: 8px 10px;
  border: 1px solid rgba(214, 168, 75, 0.16);
  border-left: 2px solid var(--gold-dim);
  border-radius: 2px;
  background: rgba(7, 11, 18, 0.3);
}

.codex-key {
  display: grid;
  grid-template-columns: 120px 1fr;
  gap: 10px;
  align-items: baseline;
}

.codex-key b {
  color: var(--gold-bright);
  font: 700 10px/1.3 var(--font-data);
}

.codex-key span {
  color: var(--parchment-dim);
  font-size: 10px;
  line-height: 1.4;
}

.codex-card-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.codex-card-head h3 {
  margin: 0;
  color: var(--parchment);
  font: 700 15px/1.2 var(--font-display);
}

.codex-card-head span {
  color: var(--gold);
  font: 9px/1.2 var(--font-data);
  white-space: nowrap;
}

.codex-card p {
  margin: 5px 0 0;
  color: var(--parchment-dim);
  font-size: 10px;
  line-height: 1.45;
}

.codex-empty {
  padding: 20px 10px;
  border: 1px dashed rgba(214, 168, 75, 0.18);
  color: var(--parchment-dim);
  font: 10px/1.45 var(--font-data);
  text-align: center;
}

@media (max-width: 640px) {
  .codex-tabs {
    flex-wrap: wrap;
    gap: 2px;
  }

  .codex-tab {
    flex: 1 1 40%;
    padding: 0 5px;
    font-size: 8px;
  }

  .codex-key {
    grid-template-columns: 1fr;
    gap: 3px;
  }

  .skip-btn {
    right: 8px;
    bottom: 8px;
    padding: 5px 7px;
  }
}

/* На телефоне карта шире экрана: кнопка хода должна стоять у края
   видимой области, а не у края прокручиваемой карты. */
@media (max-width: 700px) {
  .skip-btn {
    position: fixed;
    right: 10px;
    bottom: 10px;
    z-index: 25;
  }
}

/* Спрайты и иконки в справочнике: моб, НПС или предмет стоят слева. */
.codex-card {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}

.codex-card-icon {
  flex: 0 0 40px;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(214, 168, 75, 0.18);
  border-radius: 2px;
  background: rgba(4, 8, 14, 0.6);
}

.codex-card-icon svg,
.codex-card-icon img,
.codex-card-icon .item-ico {
  display: block;
  width: 32px;
  height: 32px;
  image-rendering: pixelated;
}

.codex-card-main {
  flex: 1 1 auto;
  min-width: 0;
}

@media (max-width: 640px) {
  .codex-card-icon {
    flex-basis: 34px;
    width: 34px;
    height: 34px;
  }

  .codex-card-icon svg,
  .codex-card-icon img,
  .codex-card-icon .item-ico {
    width: 26px;
    height: 26px;
  }
}

/* Портал в деревню на пятом этаже: заметный фиолетово-голубой проход. */
.ent-portal {
  width: calc(var(--cell) * 0.8);
  height: calc(var(--cell) * 0.8);
  filter: drop-shadow(0 0 8px rgba(124, 58, 237, 0.95))
    drop-shadow(0 0 4px rgba(56, 189, 248, 0.8));
  animation: portalPulse 1.8s ease-in-out infinite;
}

@keyframes portalPulse {
  0%, 100% { transform: scale(1); opacity: 0.9; }
  50% { transform: scale(1.06); opacity: 1; }
}

/* Панель разработчика: вкладки и категории. */
.dev-panel {
  width: min(420px, calc(100vw - 24px));
  max-height: min(82vh, 640px);
  overflow-y: auto;
  border: 2px solid var(--gold-dim);
  border-left: 4px solid var(--gold);
  border-radius: 2px;
  background: linear-gradient(180deg, rgba(32, 44, 58, 0.99), rgba(8, 14, 22, 0.995));
  box-shadow: 8px 8px 0 rgba(0, 0, 0, 0.5);
  scrollbar-width: thin;
}

.dev-head {
  color: var(--parchment);
}

.dev-key {
  margin-left: auto;
  margin-right: 8px;
  padding: 2px 5px;
  border: 1px solid var(--gold-dim);
  color: var(--gold);
  font: 8px/1 var(--font-data);
}

.dev-tabs {
  display: flex;
  gap: 2px;
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(214, 168, 75, 0.2);
  overflow-x: auto;
  scrollbar-width: none;
}

.dev-tab {
  flex: 0 0 auto;
  padding: 5px 7px;
  border: 1px solid transparent;
  border-radius: 2px;
  background: transparent;
  color: var(--parchment-dim);
  font: 700 8px/1 var(--font-data);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  cursor: pointer;
}

.dev-tab:hover,
.dev-tab:focus-visible {
  border-color: var(--gold-dim);
  color: var(--parchment);
  outline: none;
}

.dev-tab.is-active {
  border-color: var(--gold);
  background: rgba(214, 168, 75, 0.12);
  color: var(--gold-bright);
}

.dev-pane {
  display: none;
}

.dev-pane.is-active {
  display: block;
}

.dev-primary {
  border-color: var(--gold);
  background: rgba(214, 168, 75, 0.14);
  color: var(--gold-bright);
}

.dev-quest {
  margin-bottom: 8px;
  padding: 8px;
  border: 1px solid rgba(214, 168, 75, 0.16);
  color: var(--parchment-dim);
  font: 10px/1.5 var(--font-data);
}

.dev-quest b {
  color: var(--gold);
}

@media (max-width: 640px) {
  .dev-panel {
    right: 8px;
    bottom: 8px;
    width: calc(100vw - 16px);
    max-height: 78vh;
  }

  .dev-tab {
    flex: 1 1 0;
    font-size: 7px;
  }
}

/* Обновления: короткая лента новостей в главном меню. */
#updates-overlay {
  z-index: 101;
}

#updates-box {
  width: min(720px, 94vw);
}

.updates-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
}

.updates-body::-webkit-scrollbar {
  display: none;
}

.update-entry {
  padding: 10px 12px;
  border: 1px solid rgba(214, 168, 75, 0.16);
  border-left: 2px solid var(--gold-dim);
  background: rgba(7, 11, 18, 0.3);
}

.update-entry-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.update-entry h3 {
  margin: 0;
  color: var(--parchment);
  font: 700 15px/1.2 var(--font-serif);
  letter-spacing: 0.02em;
}

.update-version {
  flex: 0 0 auto;
  color: var(--gold);
  font: 700 10px/1 var(--font-data);
  letter-spacing: 0.06em;
}

.update-date {
  margin-top: 3px;
  color: var(--parchment-dim);
  font: 9px/1.3 var(--font-data);
  letter-spacing: 0.04em;
}

.update-entry ul {
  margin: 8px 0 0;
  padding-left: 16px;
  color: var(--parchment-dim);
  font: 11px/1.55 var(--font-serif);
}

.update-entry li + li {
  margin-top: 4px;
}

.update-entry li::marker {
  color: var(--gold-dim);
}

@media (max-width: 640px) {
  #updates-box {
    width: calc(100vw - 16px);
  }

  .updates-body {
    max-height: 62vh;
  }

  .update-entry h3 {
    font-size: 14px;
  }

  .update-entry ul {
    font-size: 10px;
  }
}

/* Победа в бою: окно само гаснет через пару секунд. */
#battle-overlay {
  transition: opacity 0.38s ease;
}

#battle-overlay.battle-closing {
  opacity: 0;
  pointer-events: none;
}

#battle-overlay.battle-closing .battle {
  transform: translateY(10px) scale(0.985);
  transition: transform 0.38s ease;
}

.battle-auto-note {
  min-height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--parchment-dim);
  font: 10px/1.4 var(--font-data);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* Анимации покоя и падения отключаются вместе с остальной анимацией. */
@media (prefers-reduced-motion: reduce) {
  .ent-player .sprite-img,
  .ent-npc .sprite-img,
  .battle-portrait,
  .fighter.down .battle-portrait {
    animation: none;
  }
}

/* ============================================================
   Читаемость интерфейса.
   После добавления кампании HUD и журнал стали главными рабочими
   поверхностями, поэтому вся игровая типографика и органы управления
   подросли примерно на 10–15%. Карта и пиксель-арт не масштабируются.
   ============================================================ */

@media (min-width: 901px) {
  body.game-page .nav-btn {
    min-height: 38px;
    padding: 0 11px;
    gap: 7px;
    font-size: 11.5px;
  }

  body.game-page .nav-btn svg {
    width: 16px;
    height: 16px;
  }

  body.game-page .head-actions {
    gap: 14px;
  }

  body.game-page .head-link {
    font-size: 13.5px;
  }
}

body.game-page .hero-hud {
  top: 72px;
  width: clamp(288px, 25vw, 360px);
  padding: 10px 12px 11px;
}

body.game-page .hero-hud-rank {
  font-size: 10px;
}

body.game-page .hero-hud-rank b {
  font-size: 17px;
}

body.game-page .hero-hud-name,
body.game-page .hero-hud-gold {
  font-size: 13.5px;
}

body.game-page .hero-hud-coin {
  font-size: 10px;
}

body.game-page .hero-hud-bar {
  grid-template-columns: 24px minmax(0, 1fr) auto;
  gap: 8px;
  margin-top: 8px;
}

body.game-page .hero-hud-key {
  font-size: 9px;
}

body.game-page .hero-hud-track {
  height: 8px;
}

body.game-page .hero-hud-bar.xp .hero-hud-track {
  height: 6px;
}

body.game-page .hero-hud-val {
  min-width: 62px;
  font-size: 10.5px;
}

body.game-page .hero-hud-foot {
  gap: 10px;
  margin-top: 8px;
  padding-top: 7px;
  font-size: 9px;
}

body.game-page .hero-hud-foot b {
  font-size: 10px;
}

body.game-page .hero-hud-story {
  min-height: 30px;
  margin-top: 8px;
  padding: 7px 8px;
}

body.game-page .hero-hud-story-kicker {
  font-size: 9px;
}

body.game-page .hero-hud-story-title {
  font-size: 12px;
}

body.game-page .hero-hud-story::after {
  font-size: 17px;
}

#journal-box {
  width: min(860px, 94vw);
  max-width: min(860px, 94vw);
}

.overlay > .battle > .battle-head .enemy-name {
  font: 700 27px/1.08 var(--font-display);
}

.overlay > .battle > .battle-head .hud-num {
  font: 11px/1.4 var(--font-data);
}

.overlay > .battle .btn {
  min-height: 42px;
  font-size: 12px;
}

.overlay > .battle > .battle-head .exit-btn {
  width: 38px;
  height: 38px;
  min-width: 38px;
}

.journal-tab {
  min-height: 38px;
  padding: 0 13px;
  font-size: 11px;
}

.journal-card {
  padding: 13px 14px;
}

.journal-kind,
.journal-status {
  font-size: 10px;
}

.journal-card h3 {
  font-size: 18px;
}

.journal-card p {
  font-size: 12.5px;
}

.journal-meta {
  font-size: 10px;
}

.journal-empty {
  font-size: 12px;
}

.story-prologue {
  padding: 12px 14px;
}

.story-kicker {
  font-size: 10px;
}

.story-prologue p {
  font-size: 13px;
}

.story-current {
  padding: 16px 16px 15px;
}

.story-current h3 {
  font-size: 27px;
}

.story-lead {
  font-size: 14px;
}

.story-objective > span {
  font-size: 9px;
}

.story-objective p {
  font-size: 13px;
}

.story-progress {
  font-size: 11.5px;
}

.story-path-head {
  font-size: 10px;
}

.story-path-step {
  grid-template-columns: 31px minmax(0, 1fr) auto;
  gap: 11px;
  padding: 8px 0;
}

.story-path-num {
  width: 30px;
  height: 30px;
  font-size: 10px;
}

.story-path-step::before {
  left: 15px;
  top: 35px;
}

.story-path-text b {
  font-size: 13.5px;
}

.story-path-text span {
  font-size: 11.5px;
}

.story-path-state {
  font-size: 9px;
}

#dialog-box .hub-card-note,
#dialog-box .lead {
  font-size: 12px;
}

#dialog-box .quest-head,
#dialog-box h3 {
  font-size: 11px;
}

#dialog-box .hub-card-head {
  font-size: 13.5px;
}

#dialog-box .hub-price {
  font-size: 11px;
}

.game-panel {
  width: 450px;
}

#panel-stats { width: 410px; }
#panel-place { width: 470px; }
#panel-inventory { width: 660px; }
#panel-achievements { width: 560px; }

.panel-kicker {
  font-size: 10px;
}

.panel-head h2 {
  font-size: 24px;
}

#stats-slot .hud-num,
#inventory-wallet .lead,
#achievements-slot .lead {
  font-size: 11.5px;
}

.tutorial-kicker,
.tutorial-skip {
  font-size: 12px;
}

.tutorial-hint {
  font-size: 12.5px;
}

.action-btn {
  font-size: 15px;
}

.skip-btn,
.skip-btn .action-label {
  font-size: 10.5px;
}

@media (max-width: 980px) {
  body.game-page .hero-hud {
    top: 64px;
    width: min(330px, calc(100vw - 16px));
  }
}

@media (max-width: 900px) {
  body.game-page .hero-hud {
    top: 84px;
  }
}

@media (max-width: 760px) {
  body.game-page .hero-hud {
    top: 84px;
    right: 8px;
    left: 8px;
    width: auto;
    padding: 8px 10px 9px;
  }

  .story-current h3 {
    font-size: 22px;
  }

  .story-lead,
  .story-objective p {
    font-size: 13px;
  }

  .story-prologue p,
  .story-progress {
    font-size: 12px;
  }

  .story-path-step {
    grid-template-columns: 28px minmax(0, 1fr);
    gap: 9px;
  }

  .story-path-num {
    width: 27px;
    height: 27px;
  }

  .story-path-step::before {
    left: 13px;
  }

  .journal-card p {
    font-size: 12px;
  }

  .overlay > .battle .btn {
    font-size: 11.5px;
  }
}

/* =========================================================
   ���������� ���������: ������, ������ � �����.
   ������ ������� � Aseprite (art/ui/make_ui.lua), 9-slice.
   ========================================================= */

@font-face {
  font-family: "Handjet";
  src: url("fonts/Handjet-Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "Handjet";
  src: url("fonts/Handjet-Black.ttf") format("truetype");
  font-weight: 900;
  font-display: swap;
}

@font-face {
  font-family: "Golos Text";
  src: url("fonts/GolosText-Regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Golos Text";
  src: url("fonts/GolosText-Medium.ttf") format("truetype");
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "Golos Text";
  src: url("fonts/GolosText-Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}

:root {
  --font-display: "Golos Text", "Segoe UI", system-ui, sans-serif;
  --font-ui: "Golos Text", "Segoe UI", system-ui, sans-serif;
  --font-data: "Golos Text", "Segoe UI", system-ui, sans-serif;
  --font-pixel: "Handjet", "Golos Text", sans-serif;
}

/* Кириллица Golos — основной голос интерфейса; Handjet — только крупные
   акценты: этаж, уровень и название игры. */
body.game-page .hero-hud,
body.game-page .nav-btn,
body.game-page .head-link,
body.game-page .action-btn,
body.game-page .skip-btn,
.overlay > .battle,
.overlay > .battle .btn {
  font-family: var(--font-ui);
}

body.game-page .hero-hud-val,
body.game-page .hero-hud-gold,
body.game-page .hero-hud-foot {
  font-variant-numeric: tabular-nums;
}

body.game-page .hero-hud-rank b {
  font-family: var(--font-pixel);
  font-size: 21px;
  font-weight: 900;
  letter-spacing: 0.02em;
}

.floor-intro-title {
  font-family: var(--font-pixel);
  font-weight: 900;
  letter-spacing: 0.01em;
}

#menu-title {
  font-family: var(--font-pixel);
  font-weight: 900;
}

.overlay > .battle > .battle-head .enemy-name {
  font-family: var(--font-pixel);
  font-weight: 700;
  letter-spacing: 0.01em;
}

/* --- HUD: ������ �������� �������� --- */
body.game-page .hero-hud {
  width: clamp(300px, 26vw, 384px);
  padding: 8px 12px 10px;
  border: 12px solid transparent;
  border-image: url("ui/panel-dark.png") 16 / 12px stretch;
  border-radius: 0;
  background:
    linear-gradient(180deg, rgba(22, 33, 47, 0.96), rgba(7, 12, 20, 0.97)) padding-box;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);
  image-rendering: pixelated;
}

body.game-page .hero-hud-story {
  border: 8px solid transparent;
  border-image: url("ui/panel-small.png") 12 / 8px stretch;
  border-radius: 0;
  background: rgba(7, 11, 18, 0.55) padding-box;
  image-rendering: pixelated;
}

/* --- ������: ���������� ���� � ������� --- */
body.game-page .hero-hud-track {
  height: 11px;
  border: 0;
  background: url("ui/bar-track.png") left center / 24px 100% repeat-x;
  image-rendering: pixelated;
}

body.game-page .hero-hud-bar.hp .hero-hud-track > i {
  background: url("ui/bar-hp.png") left center / 24px 100% repeat-x;
}

body.game-page .hero-hud-bar.xp .hero-hud-track {
  height: 9px;
}

body.game-page .hero-hud-bar.xp .hero-hud-track > i {
  background: url("ui/bar-xp.png") left center / 24px 100% repeat-x;
}

/* --- ��������� � ������ ���� --- */
body.game-page #screen-game .minimap {
  width: 206px;
  height: 154px;
  border: 11px solid transparent;
  border-image: url("ui/minimap-frame.png") 12 / 11px stretch;
  border-radius: 0;
  background: rgba(5, 8, 15, 0.94);
  box-shadow: none;
  image-rendering: pixelated;
}

/* --- ������ ��������: �������� �������� --- */
body.game-page .action-btn {
  padding: 8px 20px;
  border: 10px solid transparent;
  border-image: url("ui/button-primary.png") 12 / 10px stretch;
  border-radius: 0;
  background: linear-gradient(180deg, #d06d42, #a6472b) padding-box;
  color: #f8eedb;
  text-shadow: 0 1px 0 #5e2416;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.5);
  image-rendering: pixelated;
}

body.game-page .action-btn:hover {
  border-image-source: url("ui/button-primary-hover.png");
  background: linear-gradient(180deg, #e08255, #b85130) padding-box;
  filter: none;
}

body.game-page .action-btn:active {
  border-image-source: url("ui/button-primary-active.png");
  background: linear-gradient(180deg, #9c4027, #7e3220) padding-box;
}

body.game-page .action-btn.locked {
  border-image-source: url("ui/button-ghost.png");
  background: linear-gradient(180deg, #3f4d63, #263243) padding-box;
  color: #dce7f6;
  text-shadow: none;
}

body.game-page .action-btn .action-key {
  border-radius: 0;
  background: rgba(8, 19, 31, 0.45);
}

/* --- ������ ���������: ����������, ����� ������� ����� --- */
body.game-page .nav-btn {
  padding-left: 30px;
  background-repeat: no-repeat;
  background-position: 8px 50%;
  background-size: 18px 18px;
  image-rendering: pixelated;
}

body.game-page .nav-btn svg {
  display: none;
}

body.game-page .nav-btn[data-panel="stats"] { background-image: url("ui/icon-stats.png"); }
body.game-page .nav-btn[data-panel="place"] { background-image: url("ui/icon-map.png"); }
body.game-page .nav-btn[data-panel="inventory"] { background-image: url("ui/icon-inventory.png"); }
body.game-page .nav-btn[data-panel="achievements"] { background-image: url("ui/icon-achievements.png"); }
body.game-page .nav-btn[data-panel="journal"] { background-image: url("ui/icon-journal.png"); }

/* --- ��������: ���������� �� ����� � ������ ������� --- */
#screen-game::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 5;
  pointer-events: none;
  box-shadow: inset 0 0 160px rgba(0, 0, 0, 0.62);
}

@media (max-width: 980px) {
  body.game-page #screen-game .minimap {
    width: 134px;
    height: 102px;
    border-width: 11px;
  }
}

@media (max-width: 760px) {
  body.game-page .hero-hud {
    width: auto;
    border-width: 10px;
  }

  body.game-page .nav-btn {
    padding-left: 26px;
    background-size: 16px 16px;
    background-position: 7px 50%;
  }

  body.game-page .action-btn {
    padding: 7px 14px;
    border-width: 8px;
  }
}

/* ������ ����������� ��� � �� �� ������ ��������, �� �����. */
body.game-page .skip-btn {
  padding: 5px 12px;
  border: 7px solid transparent;
  border-image: url("ui/button-ghost.png") 12 / 7px stretch;
  border-radius: 0;
  background: rgba(9, 18, 32, 0.9) padding-box;
  color: var(--parchment-dim);
  box-shadow: none;
}

body.game-page .skip-btn:hover {
  border-image-source: url("ui/button-ghost-hover.png");
  background: rgba(14, 26, 45, 0.95) padding-box;
  color: var(--gold-bright);
}

/* ������� �������� ���, ������� � �������� � ��� �� ������. */
.overlay > .battle {
  border: 12px solid transparent;
  border-image: url("ui/panel-dark.png") 16 / 12px stretch;
  border-radius: 0;
  background:
    linear-gradient(180deg, rgba(28, 40, 54, 0.98), rgba(7, 11, 18, 0.99)) padding-box;
  image-rendering: pixelated;
}

.overlay > .battle > .battle-head,
.overlay > .battle > .battle-foot {
  margin-left: -12px;
  margin-right: -12px;
  padding-left: 12px;
  padding-right: 12px;
}

@media (max-width: 760px) {
  body.game-page .head-actions #menu-btn {
    background-image: url("ui/icon-menu.png");
    background-repeat: no-repeat;
    background-position: center;
    background-size: 16px 16px;
    image-rendering: pixelated;
  }

  body.game-page .head-actions #menu-btn::before {
    content: "";
  }
}

body.game-page .hero-hud-foot {
  border-top: 0;
  padding-top: 9px;
  background: url("ui/divider.png") center top / 100% 5px no-repeat;
  image-rendering: pixelated;
}

/* ������ ������ ���������: � ���������� �� ������� Segoe UI, Georgia
   � ������ ������������ ������. Golos Text � ���� �����, Handjet � ������
   ������� ������� (��������, ����, �������, ��� �����). */
:root {
  --display: "Golos Text", "Segoe UI", system-ui, sans-serif;
  --font-display: "Golos Text", "Segoe UI", system-ui, sans-serif;
  --font-ui: "Golos Text", "Segoe UI", system-ui, sans-serif;
  --font-serif: "Golos Text", "Segoe UI", system-ui, sans-serif;
  --font-data: "Golos Text", "Segoe UI", system-ui, sans-serif;
  /* Только для кода: HUD и подписи остаются Golos. */
  --font-mono: ui-monospace, SFMono-Regular, "Cascadia Mono",
    Consolas, "Liberation Mono", monospace;
}

body,
body.game-page,
button,
input,
textarea,
select,
option,
.menu-tagline,
.saves-head h2 {
  font-family: var(--font-ui);
}

/* ��� ������� �������� �� ��������, �� ��� �� ����������. */
pre,
code,
kbd,
samp,
.q-code,
.code-editor,
#code-input,
#copy-input,
#copy-sample,
.test-results,
.challenge-code {
  font-family: var(--font-mono, Consolas, "Courier New", monospace) !important;
  font-variant-ligatures: none;
}

.overlay > .battle > .battle-head .exit-btn::before,
#dialog-close::before,
#shop-close::before,
#forge-close::before {
  font-family: var(--font-ui);
}

/* � ��� ������� ������ ���� � ���� � ���� ��������� �����: ��� �����,
   ������ � ������� ��� ���� ����. ������� � ������ � ���� ���. */
#battle-box > .battle-head {
  display: none !important;
}

#battle-box {
  padding-top: 10px;
}

#battle-box > .battle-inner {
  padding-top: 2px;
}

/* ---------- Бой: сцена на карте и нижняя панель ---------- */
/* Камера подъезжает к бойцам, карта занимает весь экран, а вопрос живёт
   в панели снизу. Карточка по центру больше не закрывает подземелье. */

body.game-page.battling .game-wrap > #screen-game.panel {
  position: fixed !important;
  inset: 0 !important;
  z-index: 10;
  width: 100% !important;
  height: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: #04070f !important;
  overflow: hidden;
  box-shadow: none;
  display: block;
}

body.battling #screen-game .map-scroll {
  width: 100%;
  height: 100%;
  margin: 0;
  border-radius: 0;
}

body.battling #map {
  transform-origin: 0 0;
}

#map.battle-cam {
  transition: transform 0.95s cubic-bezier(0.18, 0.82, 0.24, 1);
}

/* Мир на время боя уходит: остаются только плитки и крупные бойцы. */
body.battling #hero-hud,
body.battling #minimap,
body.battling #log,
body.battling #action-btn,
body.battling #skip-btn,
body.battling .game-msg,
body.battling #tutorial-panel,
body.battling .floor-arrival,
body.battling .game-nav,
body.battling .head-actions {
  opacity: 0;
  pointer-events: none;
}

body.battling #entities {
  opacity: 0;
  transition: opacity 0.35s ease;
}

/* Пока окно боя гаснет, фигурки на карте уже проступают: герой не должен
   исчезнуть вместе с окном и появиться заново. */
body.battling.battle-outro #entities {
  opacity: 1;
}

body.battling #battle-overlay {
  display: block;
  padding: 0;
  overflow: hidden;
  background: none;
}

body.battling #battle-overlay::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 34%, transparent 28%, rgba(2, 5, 10, 0.64) 100%),
    linear-gradient(180deg, rgba(2, 5, 10, 0.5), transparent 20%, transparent 56%, rgba(2, 5, 10, 0.88));
}

body.battling #battle-overlay > #battle-box {
  position: static;
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  overflow: visible;
  animation: none;
  display: block;
}

/* Сцена: бойцы стоят над своими клетками. */
body.battling .battle-stage {
  position: fixed;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

body.battling .battle-stage .battle-scene {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  gap: 0;
}

body.battling .battle-stage .scene-arena {
  position: absolute;
  inset: 0;
  display: block;
  padding: 0;
  border-radius: 0;
}

body.battling .battle-stage .fighter {
  position: absolute;
  left: 40%;
  top: 32%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  width: auto;
  min-width: 0;
  flex: none;
  padding: 0;
  transform: translate(-50%, -50%);
  transition: left 0.95s cubic-bezier(0.18, 0.82, 0.24, 1),
              top 0.95s cubic-bezier(0.18, 0.82, 0.24, 1);
  will-change: left, top;
}

body.battling .battle-stage .fighter-hero,
body.battling .battle-stage .fighter-enemy {
  padding-left: 0;
  padding-right: 0;
  justify-content: center;
}

body.battling .battle-stage .fighter-hero {
  left: 40%;
}

body.battling .battle-stage .fighter-enemy {
  left: 60%;
}

body.battling .battle-stage .battle-portrait {
  position: relative;
  width: clamp(96px, 11.5vw, 142px);
  height: clamp(96px, 11.5vw, 142px);
  filter: drop-shadow(0 16px 10px rgba(0, 0, 0, 0.62));
}

body.battling .battle-stage .battle-portrait.boss {
  width: clamp(120px, 14vw, 176px);
  height: clamp(120px, 14vw, 176px);
}

body.battling .battle-stage .fighter-hpbar {
  width: clamp(112px, 11.5vw, 142px);
  height: 9px;
  background: url("ui/bar-track.png") left center / 24px 100% repeat-x;
  image-rendering: pixelated;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
}

body.battling .battle-stage .fighter-hpbar > i {
  display: block;
  height: 100%;
  background: url("ui/bar-hp.png") left center / 24px 100% repeat-x;
  transition: width 0.35s ease;
}

body.battling .battle-stage .fighter-hero .fighter-hpbar > i {
  background-image: url("ui/bar-xp.png");
}

body.battling .battle-stage .fighter-tag {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 3px 8px;
  background: rgba(4, 8, 14, 0.72);
  border: 1px solid rgba(214, 168, 75, 0.22);
  text-align: center;
}

body.battling .battle-stage .fighter-tag b {
  font: 700 14px/1.1 var(--font-ui);
  color: var(--parchment, #eee4cf);
  text-shadow: 0 2px 4px #000;
  white-space: nowrap;
}

body.battling .battle-stage .fighter-tag span {
  font: 500 9px/1 var(--font-ui);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: #a7b2c2;
  white-space: nowrap;
}

/* Выпад в сторону врага: направление задаёт positionBattleFighters. */
@keyframes battleHeroLunge {
  0%, 100% { transform: translate(-50%, -50%); }
  38% { transform: translate(calc(-50% + var(--lunge-x, 54px)), calc(-50% + var(--lunge-y, 0px))) rotate(2deg); }
}

@keyframes battleEnemyLunge {
  0%, 100% { transform: translate(-50%, -50%); }
  38% { transform: translate(calc(-50% + var(--lunge-x, -54px)), calc(-50% + var(--lunge-y, 0px))) rotate(-2deg); }
}

body.battling .battle-scene.strike-enemy .fighter-hero {
  animation: battleHeroLunge 0.42s cubic-bezier(0.2, 0.8, 0.3, 1);
}

body.battling .battle-scene.strike-hero .fighter-enemy {
  animation: battleEnemyLunge 0.42s cubic-bezier(0.2, 0.8, 0.3, 1);
}

/* Вспышка и косой слэш по тому, кто получил удар. */
@keyframes battleSlash {
  0% { opacity: 0; transform: translate(-50%, -50%) rotate(-34deg) scaleX(0.1); }
  22% { opacity: 1; }
  58% { opacity: 1; transform: translate(-50%, -50%) rotate(-34deg) scaleX(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) rotate(-34deg) scaleX(1.12); }
}

body.battling .battle-scene.strike-enemy .fighter-enemy .battle-portrait::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 122%;
  height: 8px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, #fff6db 18%, #fff 50%, #f6d684 82%, transparent);
  box-shadow: 0 0 16px rgba(255, 226, 166, 0.85);
  animation: battleSlash 0.38s ease-out;
}

body.battling .battle-stage .fighter .dmg-float {
  top: 0;
  z-index: 8;
  font: 900 clamp(26px, 3vw, 40px)/1 var(--font-pixel);
  color: #ffe1a0;
  text-shadow: 0 0 10px rgba(255, 170, 90, 0.65), 0 3px 0 #3b1b0c;
}

body.battling .battle-stage .fighter .dmg-float.hurt {
  color: #ff8e78;
  text-shadow: 0 0 10px rgba(255, 70, 50, 0.5), 0 3px 0 #2b0808;
}

body.battling .battle-stage .scene-banner {
  top: 15%;
  left: 50%;
  z-index: 4;
  transform: translate(-50%, -50%) rotate(-4deg);
}

/* Вспышка эффекта в бою не должна садиться на текст панели: уводим её
   в верхнюю полосу, где уже погасла заставка. */
body.battling .effect-flash {
  top: 20px;
  bottom: auto;
}

/* Заставка входа в бой. */
body.battling .battle-intro {
  position: fixed;
  inset: 0;
  z-index: 3;
  display: grid;
  align-content: start;
  justify-items: center;
  padding-top: 4vh;
  text-align: center;
  pointer-events: none;
  background: radial-gradient(circle at 50% 28%, rgba(10, 18, 28, 0.12), rgba(2, 5, 10, 0.66));
  transition: opacity 0.55s ease, visibility 0.55s ease;
}

body.battling .battle-intro.gone {
  opacity: 0;
  visibility: hidden;
}

body.battling .battle-intro-kicker {
  color: #d6a84b;
  font: 700 10px/1 var(--font-ui);
  letter-spacing: 0.24em;
  text-transform: uppercase;
}

body.battling .battle-intro b {
  display: block;
  margin-top: 8px;
  font: 700 clamp(26px, 3.6vw, 46px)/1 var(--font-pixel);
  color: var(--parchment, #eee4cf);
  text-shadow: 0 8px 24px rgba(0, 0, 0, 0.8);
}

body.battling .battle-intro i {
  display: block;
  width: 150px;
  height: 1px;
  margin: 12px auto 0;
  background: linear-gradient(90deg, transparent, #d6a84b, transparent);
}

body.battling .battle-intro p {
  margin: 8px 0 0;
  max-width: 480px;
  padding: 0 16px;
  color: #a7b2c2;
  font: 500 12.5px/1.35 var(--font-ui);
}

/* Нижняя панель: здоровье, вопрос, варианты и действия. */
body.battling .battle-panel {
  position: fixed;
  left: 50%;
  bottom: 16px;
  z-index: 5;
  width: min(1160px, calc(100vw - 24px));
  max-height: min(60vh, 620px);
  display: flex;
  flex-direction: column;
  padding: 12px 16px 13px;
  border: 14px solid transparent;
  border-image: url("ui/panel-dark.png") 16 / 14px stretch;
  background: linear-gradient(180deg, rgba(22, 33, 47, 0.98), rgba(6, 10, 17, 0.99)) padding-box;
  image-rendering: pixelated;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.65);
  pointer-events: auto;
  transform: translate(-50%, calc(100% + 40px));
  transition: transform 0.75s cubic-bezier(0.18, 0.82, 0.24, 1);
}

body.battling #battle-box.panel-open .battle-panel {
  transform: translate(-50%, 0);
}

body.battling .battle-panel .battle-panel-top {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 16px;
  padding-bottom: 9px;
  border-bottom: 1px solid rgba(214, 168, 75, 0.18);
}

body.battling .battle-panel .combatant {
  display: flex;
  align-items: center;
  gap: 9px;
  min-width: 0;
}

body.battling .battle-panel .combatant.hero {
  margin-right: auto;
}

body.battling .battle-panel .combatant.enemy {
  margin-left: auto;
  flex-direction: row-reverse;
}

body.battling .battle-panel .combatant .name {
  font: 700 14px/1 var(--font-ui);
  color: var(--parchment, #eee4cf);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 26vw;
}

body.battling .battle-panel .combatant .num {
  font: 700 11px/1 var(--font-ui);
  color: #a7b2c2;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

body.game-page .battle-panel .combatant .hp-bar {
  flex: 0 0 auto;
  order: 0;
  margin: 0;
  width: clamp(130px, 18vw, 240px);
  height: 10px;
  border-radius: 0;
  box-shadow: none;
  background: url("ui/bar-track.png") left center / 24px 100% repeat-x;
  image-rendering: pixelated;
}

body.game-page .battle-panel .combatant .hp-bar > i {
  border-radius: 0;
  box-shadow: none;
  background: url("ui/bar-hp.png") left center / 24px 100% repeat-x;
}

body.game-page .battle-panel .combatant.hero .hp-bar > i {
  background-image: url("ui/bar-xp.png");
}

body.battling .battle-panel .round-note {
  flex: 0 0 auto;
  padding: 5px 9px;
  border: 1px solid rgba(214, 168, 75, 0.28);
  color: #d6a84b;
  font: 700 9px/1 var(--font-ui);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
}

body.battling .battle-panel .battle-mid {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  padding: 11px 0 8px;
  overflow-y: auto;
  overscroll-behavior: contain;
}

body.battling .battle-panel .battle-foot {
  flex: 0 0 auto;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 8px;
  margin: 0;
  padding-top: 9px;
  border-top: 1px solid rgba(214, 168, 75, 0.18);
}

body.battling .battle-panel .battle-cat-wrap {
  flex: 1 1 0;
  min-width: 118px;
}

body.battling .battle-panel .battle-cat {
  width: 100%;
  min-height: 40px;
  padding: 7px 10px;
  border: 8px solid transparent;
  border-image: url("ui/button-ghost.png") 12 / 8px stretch;
  background: rgba(9, 18, 32, 0.8) padding-box;
  color: var(--parchment, #eee4cf);
  font: 700 11px/1 var(--font-ui);
  letter-spacing: 0.05em;
  image-rendering: pixelated;
}

body.battling .battle-panel .battle-cat:hover,
body.battling .battle-panel .battle-cat:focus-visible {
  border-image-source: url("ui/button-ghost-hover.png");
  color: #f6d684;
  outline: none;
}

body.battling .battle-panel .battle-cat.open {
  border-image-source: url("ui/button-primary.png");
  box-shadow: none;
}

body.battling .battle-panel .battle-cat-list {
  padding: 8px;
  border: 10px solid transparent;
  border-image: url("ui/panel-dark.png") 16 / 10px stretch;
  background: #0b121b padding-box;
  box-shadow: 0 14px 32px rgba(0, 0, 0, 0.55);
}

body.battling .battle-panel .battle-effects {
  flex: 0 0 auto;
  max-height: 64px;
  margin: 0;
  padding-top: 4px;
}

body.battling .battle-panel .battle-explain,
body.battling .battle-panel .battle-feedback,
body.battling .battle-panel .battle-note,
body.battling .battle-panel .battle-topic,
body.battling .battle-panel .squad-note {
  margin-top: 6px;
}

@media (max-width: 760px) {
  body.battling .battle-panel {
    width: calc(100vw - 10px);
    bottom: 6px;
    max-height: 64vh;
    padding: 8px 10px 9px;
    border-width: 10px;
  }

  /* Старые мобильные правила боя адресованы `#battle-box .fighter` и
     перебивают сцену по весу id: возвращаем вертикальную стопку явно. */
  body.game-page.battling #battle-box .battle-stage .fighter {
    flex: none !important;
    width: auto !important;
    flex-direction: column !important;
    padding: 0 !important;
    gap: 5px !important;
  }

  body.game-page.battling #battle-box .battle-stage .fighter-hero,
  body.game-page.battling #battle-box .battle-stage .fighter-enemy {
    flex-direction: column !important;
  }

  body.game-page.battling #battle-box .battle-stage .battle-portrait {
    width: 84px !important;
    height: 84px !important;
  }

  body.game-page.battling #battle-box .battle-stage .battle-portrait.boss {
    width: 108px !important;
    height: 108px !important;
  }

  body.battling .battle-panel .battle-panel-top {
    gap: 8px;
  }

  body.battling .battle-panel .combatant {
    gap: 5px;
  }

  body.battling .battle-panel .combatant .name {
    display: none;
  }

  body.game-page .battle-panel .combatant .hp-bar {
    width: clamp(74px, 22vw, 130px);
  }

  body.battling .battle-panel .round-note {
    font-size: 8px;
    padding: 4px 6px;
  }

  body.battling .battle-stage .fighter {
    top: 28%;
  }

  body.battling .battle-stage .fighter-hero {
    left: 38%;
  }

  body.battling .battle-stage .fighter-enemy {
    left: 62%;
  }

  body.battling .battle-stage .battle-portrait {
    width: 84px;
    height: 84px;
  }

  body.battling .battle-stage .battle-portrait.boss {
    width: 108px;
    height: 108px;
  }

  body.battling .battle-stage .fighter-hpbar {
    width: 84px;
  }

  body.battling .battle-stage .fighter-tag b {
    font-size: 11px;
  }

  body.battling .battle-stage .fighter-tag span {
    display: none;
  }

  body.battling .battle-intro b {
    font-size: 30px;
  }

  body.battling .battle-panel .battle-cat-wrap {
    min-width: 0;
    flex: 1 1 0;
  }

  body.battling .battle-panel .battle-cat {
    min-height: 38px;
    padding: 6px 4px;
    font-size: 10px;
    letter-spacing: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  #map.battle-cam,
  body.battling .battle-stage .fighter,
  body.battling .battle-panel,
  body.battling .battle-intro {
    transition: none;
  }

  body.battling .battle-scene.strike-enemy .fighter-hero,
  body.battling .battle-scene.strike-hero .fighter-enemy,
  body.battling .battle-scene.strike-enemy .fighter-enemy .battle-portrait::after {
    animation: none;
  }
}

/* Телефон и узкий экран: убираем всё, что дороже всего рисуется.
   Камера не масштабирует карту, у портретов нет фильтров и бесконечных
   анимаций, туман и угли не двигаются, тень панели не пересчитывается. */
@media (pointer: coarse), (max-width: 820px) {
  #map.battle-cam {
    transition: none;
  }

  body.battling .battle-stage .fighter {
    transition: none;
    will-change: auto;
  }

  body.battling .battle-stage .battle-portrait {
    filter: none;
    animation: none;
  }

  body.battling #battle-overlay::before,
  body.battling #battle-overlay::after {
    animation: none;
  }

  body.battling .battle-panel {
    box-shadow: none;
    transition: transform 0.35s ease;
  }

  body.battling #screen-game::after {
    display: none;
  }
}

/* Телефон в горизонтальной ориентации: вопрос уходит в правую колонку,
   слева остаётся карта с бойцами. Так на низком экране не приходится
   делить высоту между сценой и панелью. */
@media (orientation: landscape) and (max-height: 560px) and (max-width: 1000px) {
  body.battling .battle-panel {
    left: auto;
    right: 0;
    top: 0;
    bottom: 0;
    width: min(56vw, 580px);
    height: 100%;
    max-height: none;
    padding: 10px 14px;
    border-width: 12px;
    transform: translateX(calc(100% + 24px));
  }

  body.battling #battle-box.panel-open .battle-panel {
    transform: translateX(0);
  }

  body.battling .battle-panel .battle-panel-top {
    gap: 8px;
    padding-bottom: 6px;
  }

  body.battling .battle-panel .combatant .name {
    display: none;
  }

  body.game-page .battle-panel .combatant .hp-bar {
    width: clamp(70px, 12vw, 130px);
  }

  body.battling .battle-panel .round-note {
    font-size: 8px;
    padding: 4px 6px;
  }

  body.battling .battle-panel .battle-mid {
    padding: 8px 0 6px;
  }

  body.battling .battle-panel .battle-foot {
    gap: 6px;
    padding-top: 7px;
  }

  body.battling .battle-panel .battle-cat-wrap {
    min-width: 0;
    flex: 1 1 0;
  }

  body.battling .battle-panel .battle-cat {
    min-height: 34px;
    padding: 4px 3px;
    font-size: 9px;
    letter-spacing: 0;
  }

  body.battling .battle-panel .options {
    grid-template-columns: 1fr 1fr;
    gap: 6px;
  }

  body.battling .battle-panel .option {
    min-height: 42px;
    padding: 6px 9px;
    font-size: 13px;
    line-height: 1.2;
  }

  body.battling .battle-panel .option .key {
    width: 20px;
    height: 20px;
    flex: 0 0 20px;
    font-size: 10px;
  }

  body.battling .battle-panel .challenge-q {
    font-size: 17px;
    line-height: 1.25;
  }

  body.battling .battle-stage .fighter {
    top: 46%;
  }

  body.battling .battle-intro {
    width: calc(100% - min(56vw, 580px));
    right: auto;
    padding-top: 3vh;
  }

  body.battling .battle-intro b {
    font-size: clamp(20px, 4vw, 34px);
  }

  body.battling .battle-intro p {
    font-size: 11.5px;
  }
}

@media (orientation: landscape) and (max-height: 560px) and (max-width: 760px) {
  body.battling .battle-panel .round-note {
    display: none;
  }
}

/* Большие мониторы: панель и бойцы не должны выглядеть игрушечными
   на 1920–2560 px. */
@media (min-width: 1600px) {
  body.battling .battle-panel {
    width: min(1360px, 84vw);
    max-height: min(66vh, 760px);
    padding: 15px 22px;
  }

  body.battling .battle-panel .battle-panel-top {
    gap: 20px;
  }

  body.battling .battle-panel .combatant .name {
    font-size: 16px;
  }

  body.battling .battle-panel .combatant .num {
    font-size: 13px;
  }

  body.game-page .battle-panel .combatant .hp-bar {
    height: 12px;
    width: clamp(180px, 18vw, 280px);
  }

  body.battling .battle-panel .round-note {
    font-size: 10px;
  }

  body.battling .battle-panel .challenge-q {
    font-size: 21px;
  }

  body.battling .battle-panel .option {
    font-size: 14px;
    min-height: 48px;
  }

  body.battling .battle-panel .battle-cat {
    font-size: 12px;
    min-height: 44px;
  }

  body.battling .battle-stage .battle-portrait {
    width: 168px;
    height: 168px;
  }

  body.battling .battle-stage .battle-portrait.boss {
    width: 200px;
    height: 200px;
  }

  body.battling .battle-stage .fighter-hpbar {
    width: 168px;
    height: 11px;
  }

  body.battling .battle-stage .fighter-tag b {
    font-size: 16px;
  }

  body.battling .battle-stage .fighter-tag span {
    font-size: 10px;
  }
}

@media (min-width: 2200px) {
  body.battling .battle-panel {
    width: min(1660px, 82vw);
  }

  body.battling .battle-panel .challenge-q {
    font-size: 26px;
  }

  body.battling .battle-panel .option {
    font-size: 16px;
    min-height: 54px;
  }

  body.battling .battle-panel .battle-cat {
    font-size: 13px;
    min-height: 46px;
  }

  body.battling .battle-panel .combatant .name {
    font-size: 18px;
  }

  body.battling .battle-panel .combatant .num {
    font-size: 15px;
  }

  body.game-page .battle-panel .combatant .hp-bar {
    height: 14px;
    width: clamp(200px, 19vw, 340px);
  }

  body.battling .battle-panel .round-note {
    font-size: 11px;
  }

  body.battling .battle-stage .battle-portrait {
    width: 200px;
    height: 200px;
  }

  body.battling .battle-stage .battle-portrait.boss {
    width: 236px;
    height: 236px;
  }

  body.battling .battle-stage .fighter-hpbar {
    width: 200px;
  }

  body.battling .battle-stage .fighter-tag b {
    font-size: 19px;
  }

  body.battling .battle-stage .fighter-tag span {
    font-size: 11px;
  }
}

/* ---------- Внутреннее подтверждение ---------- */
.confirm-overlay {
  position: fixed;
  inset: 0;
  z-index: 130;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(3, 7, 13, 0.78);
  backdrop-filter: blur(5px);
}

.confirm-overlay.hidden {
  display: none;
}

.confirm-box {
  width: min(540px, 100%);
  padding: 22px 24px 20px;
  border: 1px solid rgba(246, 196, 83, 0.55);
  border-radius: 14px;
  background:
    linear-gradient(180deg, rgba(24, 36, 54, 0.98), rgba(10, 18, 31, 0.99));
  box-shadow:
    0 24px 70px rgba(0, 0, 0, 0.65),
    inset 0 1px 0 rgba(255, 255, 255, 0.06);
  font-family: var(--font-ui);
}

.confirm-kicker {
  margin-bottom: 6px;
  color: var(--gold, #f6c453);
  font: 700 10px/1 var(--font-data);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.confirm-title {
  margin: 0 0 10px;
  color: var(--parchment, #eee4cf);
  font: 700 22px/1.2 var(--font-display);
}

.confirm-text {
  margin: 0;
  color: #cbd5e1;
  font-size: 14px;
  line-height: 1.55;
  white-space: pre-line;
}

.confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}

.confirm-actions .btn {
  min-width: 130px;
}

.confirm-actions .btn.danger {
  border-color: rgba(248, 113, 113, 0.7);
  background: linear-gradient(180deg, #7f1d1d, #4c1010);
  color: #fee2e2;
}

.confirm-actions .btn.danger:hover,
.confirm-actions .btn.danger:focus-visible {
  border-color: #fca5a5;
  background: linear-gradient(180deg, #991b1b, #5f1414);
}

body.confirm-open {
  overflow: hidden;
}

@media (max-width: 700px) {
  .confirm-overlay {
    padding: 16px;
  }

  .confirm-box {
    padding: 18px 18px 16px;
  }

  .confirm-title {
    font-size: 19px;
  }

  .confirm-actions {
    flex-direction: column-reverse;
  }

  .confirm-actions .btn {
    width: 100%;
  }
}

/* ---------- Плоский интерфейс: без золотых рамок ---------- */
/* Золото остаётся акцентом текста, но окна и кнопки больше не обведены
   золотой линией: рамки нейтральные, угловые засечки убраны. */
:root {
  --ui-line: rgba(125, 162, 217, 0.24);
}

/* Иконки верхнего меню больше не рисуются: убираем и старые фоновые PNG,
   иначе после удаления SVG они проявляются спрайт-листом на всю кнопку. */
body.game-page .nav-btn[data-panel] {
  background-image: none !important;
}

body.game-page .nav-btn {
  justify-content: center !important;
  align-items: center;
  gap: 0;
  text-align: center !important;
}

body.game-page .nav-btn > span {
  display: block;
  width: 100%;
  text-align: center;
}

body.game-page .nav-btn.active {
  border-color: var(--ui-line) !important;
  background: rgba(125, 162, 217, 0.12) !important;
}

/* Золотые рамки HUD, боя и внутренних панелей нарисованы border-image
   из panel-dark/panel-small/minimap-frame. Цвет border их не отменяет:
   убираем сам border-image и оставляем тонкий нейтральный контур. */
body.game-page .hero-hud,
body.game-page .hero-hud-story,
body.game-page #screen-game .minimap,
.overlay > .battle,
body.battling .battle-panel,
body.battling .battle-panel .battle-cat,
body.battling .battle-panel .battle-cat-list {
  border: 1px solid var(--ui-line) !important;
  border-image: none !important;
}

/* У кнопок действий рамка была декоративной: убираем её совсем. */
body.game-page .action-btn,
body.game-page .skip-btn {
  border: 0 !important;
  border-image: none !important;
}

body.game-page .action-btn:hover,
body.game-page .action-btn:active,
body.game-page .skip-btn:hover {
  border-image-source: none !important;
}

/* ---------- Мини-карта: размер и масштаб ---------- */
body.game-page .minimap-dock {
  position: absolute;
  top: 68px;
  left: 12px;
  z-index: 6;
  width: var(--minimap-w, 280px);
  box-sizing: content-box;
  padding: 6px;
  border: 1px solid rgba(125, 162, 217, 0.22);
  border-radius: 12px;
  background: rgba(4, 8, 16, 0.58);
  backdrop-filter: blur(6px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  pointer-events: auto;
}

body.game-page .minimap-dock.off {
  display: none;
}

body.game-page .minimap-dock .minimap {
  position: static !important;
  top: auto !important;
  left: auto !important;
  right: auto !important;
  width: 100% !important;
  height: var(--minimap-h, 210px) !important;
  display: block;
  z-index: auto;
  cursor: default;
}

body.game-page .minimap-controls {
  display: flex;
  justify-content: space-between;
  gap: 6px;
  margin-top: 6px;
}

body.game-page .minimap-zoom-btn {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  height: 26px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--ui-line);
  border-radius: 7px;
  background: rgba(9, 18, 32, 0.72);
  color: #cbd5e1;
  font: 700 16px/1 var(--font-ui);
  cursor: pointer;
}

body.game-page .minimap-zoom-btn:hover,
body.game-page .minimap-zoom-btn:focus-visible {
  border-color: rgba(143, 179, 232, 0.7);
  background: rgba(125, 162, 217, 0.16);
  color: #eef5ff;
  outline: none;
}

body.game-page .minimap-zoom-btn:disabled {
  opacity: 0.38;
  cursor: default;
}

body.game-page .minimap-zoom-btn:disabled:hover {
  border-color: var(--ui-line);
  background: rgba(9, 18, 32, 0.72);
  color: #cbd5e1;
}

body.battling .minimap-dock {
  opacity: 0;
  pointer-events: none;
}

@media (max-width: 700px) {
  body.game-page .minimap-dock {
    display: none;
  }
}

/* ---------- Инвентарь: фильтры сумки ---------- */
body.game-page #journal-box,
body.game-page .journal-tabs,
body.game-page .journal-tab,
body.game-page .journal-card {
  border-color: var(--ui-line) !important;
  border-image: none !important;
}

body.game-page #journal-box {
  border-width: 1px !important;
}

body.game-page .journal-tab.is-active {
  border-color: rgba(143, 179, 232, 0.8) !important;
  background: rgba(125, 162, 217, 0.16) !important;
  color: #eef5ff !important;
}

body.game-page .journal-card {
  border-left-color: rgba(143, 179, 232, 0.75) !important;
}

body.game-page .journal-card.is-done {
  border-left-color: var(--moss) !important;
}

body.game-page .journal-card.is-failed {
  border-left-color: var(--ember) !important;
}

body.game-page .inv-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}

body.game-page .inv-head h3 {
  margin: 0;
}

body.game-page .inv-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

body.game-page .inv-tab {
  padding: 4px 8px;
  border: 1px solid var(--ui-line);
  border-radius: 6px;
  background: rgba(9, 18, 32, 0.72);
  color: #9fb3d1;
  font: 600 10px/1 var(--font-ui);
  cursor: pointer;
}

body.game-page .inv-tab:hover,
body.game-page .inv-tab:focus-visible {
  border-color: rgba(143, 179, 232, 0.7);
  color: #e6edf7;
  outline: none;
}

body.game-page .inv-tab.is-active {
  border-color: rgba(143, 179, 232, 0.8);
  background: rgba(125, 162, 217, 0.18);
  color: #eef5ff;
}

#menu-screen[data-mode="main"] .menu-view-main,
#menu-screen[data-mode="main"] .menu-title,
.menu-view-main,
.menu-view-pause,
.menu-view-sub,
.menu-item,
.menu-btn,
.menu-btn.primary,
.menu-gear,
.saves-screen,
.saves-head,
.saves-btn,
.saves-close,
.saves-detail,
.save-slot,
.saves-list,
.battle,
.overlay > .battle,
.battle .btn,
.battle-cat,
.battle-cat-list,
.battle-panel-top,
.battle-foot,
.fighter-tag,
.round-note,
.floor-intro-card,
.nav-btn,
.confirm-box,
.panel,
.panel-head,
.panel-close,
.game-panel,
.side-panel,
.hero-hud,
.hero-hud-story,
.hero-hud-track,
.hero-hud-foot,
.tutorial-panel,
.journal-box,
.dialog-box,
.shop-box,
.forge-box {
  border-color: var(--ui-line) !important;
}

#menu-screen[data-mode="main"] .menu-view-main,
.saves-screen,
.battle,
.menu-view-sub,
.confirm-box {
  border-width: 1px !important;
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55) !important;
}

#menu-screen[data-mode="main"] .menu-view-main::before,
#menu-screen[data-mode="main"] .menu-view-main::after {
  display: none !important;
}

.menu-item.is-active,
.menu-item:hover {
  border-left-color: rgba(143, 179, 232, 0.9) !important;
}

#menu-screen[data-mode="main"] .menu-item.is-active,
#menu-screen[data-mode="pause"] .menu-item.is-active {
  background: linear-gradient(
    90deg,
    rgba(125, 162, 217, 0.18) 0%,
    rgba(125, 162, 217, 0.04) 68%,
    rgba(0, 0, 0, 0) 100%
  ) !important;
}

.save-slot:hover,
.save-slot:focus-visible,
.save-slot.is-selected,
.saves-close:hover,
.saves-close:focus-visible,
.panel-close:hover,
.panel-close:focus-visible {
  border-color: rgba(143, 179, 232, 0.7) !important;
  background: rgba(125, 162, 217, 0.1) !important;
  box-shadow: none !important;
}

.panel .mode.active,
.mode.active {
  border-color: rgba(143, 179, 232, 0.7) !important;
  background: rgba(125, 162, 217, 0.12) !important;
  box-shadow: none !important;
}

.btn:focus-visible,
.menu-item:focus-visible,
.menu-gear:focus-visible,
.menu-btn:focus-visible,
.head-link:focus-visible,
.nav-btn:focus-visible,
.saves-btn:focus-visible {
  outline-color: rgba(160, 196, 245, 0.9) !important;
}
