/* Подземелье: крупные кнопки под большой палец. Палитра ниже — запасная, на случай,
   если css/book.css (заход 13: облик «иллюстрированная книга», см. .impeccable.md)
   не подключился; сам style.css её больше не выбирает. */

:root {
  --bg: #14121b;
  --panel: #1e1a29;
  --line: #2c2740;
  --text: #d8d3e8;
  --dim: #8a84a3;
  --accent: #e8b34b;
  --good: #93c47d;
  --bad: #e07a68;
  --cream: #201807;
  --track: #33202a;
  --hp-fill: #b8433a;
  --enemy-fill: #7a5c1e;
  --chip-hit-border: #3c5233;
  --chip-miss-border: #5a3129;
  --overlay-bg: rgba(10, 8, 16, .82);
  --stone: #1e1a29;
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 17px;
  line-height: 1.45;
  touch-action: manipulation;
}

.hidden { display: none !important; }
.dim { color: var(--dim); }
.small { font-size: 13px; }
.good { color: var(--good); }
.bad { color: var(--bad); }

#app {
  position: relative;
  max-width: 520px;
  margin: 0 auto;
  height: 100vh;
  height: 100dvh;
}

#ver {
  position: fixed;
  top: 8px; right: 12px;
  z-index: 6;
  font-size: 11px;
  color: var(--dim);
  opacity: .7;
}

.screen {
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: calc(12px + env(safe-area-inset-top)) 14px calc(10px + env(safe-area-inset-bottom));
  overflow-y: auto;
}

h1 {
  font-size: 44px;
  letter-spacing: .04em;
  margin: 0 0 4px;
  color: var(--accent);
}
h2 { font-size: 22px; margin: 6px 0 14px; }
h3 { margin: 0 0 10px; font-size: 20px; color: var(--accent); }

/* ---------- кнопки ---------- */

.act {
  display: block;
  width: 100%;
  min-height: 56px;
  margin-top: 10px;
  padding: 10px 16px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
  font-size: 18px;
  text-align: center;
  cursor: pointer;
}
.act:active { transform: scale(.98); }
.act:disabled, .card:disabled {
  opacity: .5;
  cursor: not-allowed;
}
.act:disabled:active, .card:disabled:active { transform: none; }
.act.primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--cream);
  font-weight: 700;
}
.act.ghost { background: transparent; }
.act .lbl { display: block; }
.act .sub {
  display: block;
  font-size: 13px;
  color: var(--dim);
  font-weight: 400;
}
.act.primary .sub { color: var(--cream); opacity: .8; }
.big { min-height: 64px; font-size: 21px; }

/* ---------- титул ---------- */

.title-wrap {
  margin: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
  max-width: 340px;
  text-align: center;
}

/* ---------- сбор героя ---------- */

.card {
  display: block;
  width: 100%;
  margin-bottom: 10px;
  padding: 14px 16px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
  font-size: 17px;
  text-align: left;
  cursor: pointer;
}
.card b { display: block; font-size: 19px; color: var(--accent); }
.card .sub { display: block; color: var(--dim); font-size: 14px; margin-top: 2px; }
.card.static { cursor: default; }

.theme-input {
  display: block;
  width: 100%;
  min-height: 84px;
  margin-bottom: 10px;
  padding: 12px 14px;
  border-radius: 14px;
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
  font-size: 16px;
  font-family: inherit;
  resize: vertical;
}
.theme-input:focus { outline: 1px solid var(--accent); }

/* ---------- лор партии ---------- */

#scr-lore { justify-content: space-between; overflow: hidden; }
.lore-wrap { flex: 1; min-height: 0; overflow-y: auto; padding-bottom: 6px; }
.lore-wrap h2 { color: var(--accent); font-size: 26px; margin: 8px 0 12px; }
.lore-wrap p { margin: 0 0 10px; }

/* Пролог спуска (заход 15, спека раздел 5): заменил честное мигание точек захода 7.
   Пока собирается мир, идут заготовленные строки (js/prologue.js) — мягкое затухание
   при смене строки читается как страница книги, а не как таймер загрузки. */
.prologue-line { min-height: 46px; opacity: 1; transition: opacity .25s ease; }
.prologue-line.prologue-fade { opacity: 0; }

/* Обложка мира (заход 9): фиксированное соотношение сторон держит место с первого
   кадра — заглушка и итоговая картинка занимают ОДНУ и ту же коробку, object-fit
   гарантирует отсутствие прыжка вёрстки независимо от реальных пропорций картинки.
   Не сложилось (нет ключа, таймаут, отказ модели) — .lore-cover-collapsing гасит
   прозрачность, узел убирается из DOM следом (см. ui.js beginCoverFetch): экран
   лора возвращается ровно к виду без этой фичи, без видимой ошибки. */
.lore-cover {
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  margin: 4px 0 14px;
  border-radius: 14px;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--line);
  opacity: 1;
  transition: opacity .25s ease;
}
.lore-cover-collapsing { opacity: 0; }
.lore-cover-ph {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, var(--panel), var(--bg));
}
.lore-cover-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity .5s ease;
}
.lore-cover.lore-cover-ready .lore-cover-img { opacity: 1; }

/* ---------- игровой экран ---------- */

#scr-game { padding: 0; overflow: hidden; }

#hud {
  border-bottom: 1px solid var(--line);
  padding-bottom: 8px;
}
.hrow { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }

.hpwrap { display: flex; align-items: center; gap: 8px; margin: 6px 0 2px; }
.hpbar {
  flex: 1;
  height: 10px;
  border-radius: 6px;
  background: var(--track);
  overflow: hidden;
}
.hpbar i {
  display: block;
  height: 100%;
  background: var(--hp-fill);
  transition: width .25s ease;
}

.quals { color: var(--text); opacity: .85; }
.inv { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.subrow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

#floor-strip { padding: 6px 2px; min-height: 30px; flex: 1; }
.cell {
  display: inline-block;
  width: 26px; height: 26px;
  line-height: 26px;
  text-align: center;
  margin-right: 4px;
  border-radius: 7px;
  border: 1px dashed transparent;
  color: var(--dim);
}
.cell.rev { border-color: var(--line); color: var(--text); }
.cell.cur { border-color: var(--accent); color: var(--accent); }

/* Общая прокручиваемая лента — сцена, боевой лог и журнал все ею пользуются. */
.feed {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 8px 2px;
  scrollbar-width: thin;
}

/* Текущая сцена (заход 8): комната или итог — крупно и целиком, а не бесконечная
   лента. Всё прежнее уезжает в журнал (см. #journal), см. js/logview.js consume(). */
#scene { font-size: 19px; }

/* Боевой вид: пока бой идёт — виден только он (обмены ударами текущей схватки +
   состояние сторон), комната скрыта. Кончился бой — весь боевой лог уезжает в
   журнал, экран возвращается к #scene. */
#combat-view { flex: 1; min-height: 0; display: flex; flex-direction: column; }
#combat-status {
  flex: none;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
.erow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 6px;
  font-size: 14px;
}
.ename { color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.estate { color: var(--dim); flex: none; }
.ebar { flex: 1; height: 8px; border-radius: 5px; background: var(--track); overflow: hidden; }
.ebar i { display: block; height: 100%; background: var(--enemy-fill); transition: width .25s ease; }

.line { margin-bottom: 9px; }
.line.pre { white-space: pre-line; font-size: 15px; }
/* Строка ждёт гонки заготовка/живой текст (заход 8): решение ещё не принято —
   не читается как окончательный текст. См. logview.js renderNarrated. */
.line.pending { opacity: .5; }

.chips { margin-bottom: 9px; }
.chip {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 9px;
  background: var(--panel);
  border: 1px solid var(--line);
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 14px;
}
.chip.hit { color: var(--good); border-color: var(--chip-hit-border); }
.chip.miss { color: var(--bad); border-color: var(--chip-miss-border); }
.chip.tumble { animation: tumble .45s ease; }
@keyframes tumble {
  0%   { transform: rotate(-14deg) scale(.7); opacity: 0; }
  60%  { transform: rotate(7deg) scale(1.08); opacity: 1; }
  100% { transform: rotate(0) scale(1); }
}

#actions {
  border-top: 1px solid var(--line);
  padding-top: 4px;
  max-height: 46vh;
  overflow-y: auto;
}

/* Кнопка подробности бросков — мелкая, в ряд с полосой этажей */
.mini {
  flex: none;
  padding: 5px 9px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--dim);
  font-size: 12px;
  cursor: pointer;
}
.mini:active { transform: scale(.97); }

/* Кнопка журнала обязана оставаться нажимаемой, ПОКА журнал открыт — она же его
   закрывает («открывается кнопкой и закрывается ею же»). Оверлей журнала — на весь
   экран (.overlay, z-index 10) и без поднятия z-index сам накрыл бы собой кнопку,
   на которой сидит: закрыть было бы нечем. Непрозрачный фон — иначе сквозь
   .mini{background:transparent} снизу просвечивал бы текст журнала, наложенный на
   подпись кнопки. */
#btn-journal { position: relative; z-index: 11; background: var(--panel); }

/* Строка, которую живой рассказчик заменил поверх заготовки */
.line.live {
  border-left: 2px solid var(--accent);
  padding-left: 8px;
}

/* ---------- крупная плашка броска ---------- */

.roll-flash {
  position: fixed;
  left: 50%; top: 36%;
  transform: translate(-50%, -50%);
  z-index: 8;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  opacity: 0;
}
.roll-flash .num {
  font-size: 56px;
  font-weight: 800;
  line-height: 1;
  padding: 12px 20px;
  border-radius: 18px;
  background: var(--text);
  color: var(--cream);
  border: 2px solid var(--line);
  box-shadow: 0 8px 30px rgba(0, 0, 0, .45);
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
}
.roll-flash .num.hit { color: var(--good); border-color: var(--chip-hit-border); }
.roll-flash .num.miss { color: var(--bad); border-color: var(--chip-miss-border); }
.roll-flash .need { margin-top: 6px; font-size: 13px; color: var(--dim); }
.roll-flash.show { animation: rollFlash .62s ease; }
@keyframes rollFlash {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.6); }
  15%  { opacity: 1; transform: translate(-50%, -50%) scale(1.08); }
  30%  { transform: translate(-50%, -50%) scale(1); }
  78%  { opacity: 1; }
  100% { opacity: 0; }
}

/* ---------- летопись ---------- */

.chron-row {
  padding: 9px 12px;
  margin-bottom: 8px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--panel);
  font-size: 15px;
}

/* ---------- плашки поверх ---------- */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 10;
  background: var(--overlay-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 18px;
}
.panel {
  width: 100%;
  max-width: 380px;
  max-height: 86vh;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 18px;
}
.rep {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 13px;
  line-height: 1.5;
  white-space: pre;
  overflow-x: auto;
}

/* ---------- журнал: вся прошедшая история партии ---------- */

/* Плавающая #btn-journal (см. .mini выше) сидит поверх верхнего края оверлея —
   без отступа она наложилась бы на первую строку журнала. Прижимаем панель к верху
   вместо центрирования; точный отступ под кнопку (её высота от HUD не постоянна)
   считает ui.js в момент открытия и пишет inline-стилем поверх этого запасного значения. */
#journal { align-items: flex-start; padding-top: 60px; }
.journal-panel {
  max-width: 480px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
}
.journal-panel h3 { flex: none; }
#journal-list:empty::after { content: 'Пока пусто — история появится по ходу спуска.'; color: var(--dim); }
