/* ---------- Бойова арена (screens/battle.js) ---------- */

/* Жодної смуги інтерфейсу: стан обох бійців і такт ходу — у кутах, уся середина й низ
   віддані сцені. Кути на бойовому екрані й так були порожні, а смуга під сценою з'їдала
   висоту в найдефіцитнішому місці. */

/* Підпал під низом сцени. Кубики й кнопки лежать не на малюнку стіни, а на темному —
   інакше число на грані губиться в текстурі підлоги. */
.stage-foot {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 42%;
  background: linear-gradient(180deg, transparent, rgba(6, 4, 3, 0.86) 46%, rgba(6, 4, 3, 0.96));
  pointer-events: none;
  z-index: 1;
}

/* ---------- HUD у кутах ---------- */

.hud {
  position: absolute;
  top: calc(var(--pad) * 0.8);
  display: flex; flex-direction: column; gap: 5px;
  z-index: 2;
  pointer-events: none;
}
.hud > * { pointer-events: auto; }
.hud-hero { left: var(--pad); width: clamp(150px, 26%, 268px); }
.hud-foe { right: var(--pad); width: clamp(150px, 28%, 300px); align-items: flex-end; }
.hud-center {
  left: 50%; transform: translateX(-50%);
  align-items: center; gap: 7px;
}

.hud-name { display: flex; align-items: center; gap: 7px; font-size: 1.05em; white-space: nowrap; }
.hud-name .serif { color: var(--ink); text-shadow: 0 2px 8px #000; }
.hud-name .foe-name { color: var(--blood-lit); }
.hud-name .muted { font-size: 0.74em; }
.hud-tier {
  font-size: 0.66em; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--brass-lit);
}

/* Смужка HUD — прямокутна, з підписом усередині: у кутах екрана іконка збоку з'їдала ширину,
   якої смужці якраз і бракує, щоб прогноз ходу був помітним з іншого боку сцени. */
.hud-bar {
  position: relative;
  width: 100%;
  height: clamp(15px, 3.6dvh, 22px);
  border-radius: 4px;
  overflow: hidden;
  background: rgba(6, 4, 3, 0.75);
  border: 1px solid rgba(242, 203, 132, 0.35);
  box-shadow: 0 6px 18px -8px #000;
}
.hud-bar.foe { border-color: rgba(165, 52, 42, 0.6); }
.hud-bar .fill { height: 100%; background: linear-gradient(180deg, #8fbf4a, #55801f); transition: width 0.35s ease-out; }
.hud-bar .fill.foe { background: linear-gradient(180deg, #d4523c, #8c2318); }
.hud-bar .seg { position: absolute; top: 0; bottom: 0; }
.hud-bar .seg.loss {
  background: linear-gradient(180deg, #ffb199, #c9432e);
  animation: seg-blink 0.9s ease-in-out infinite;
}
.hud-bar .seg.gain {
  background: linear-gradient(180deg, #d9f3ac, #86a341);
  animation: seg-blink 1.3s ease-in-out infinite;
}
.hud-bar .hb-text {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 7px;
  font-size: 0.74em; font-weight: 700; letter-spacing: 0.04em;
  text-shadow: 0 1px 3px #000;
}

.hud-mana { display: flex; align-items: center; gap: 6px; }
.hud-mana-label { font-size: 0.7em; color: var(--ink-muted); letter-spacing: 0.1em; }

/* Рядок «де ми в рані»: акт, локація, хід. Розріджений і тьмяний — це довідка, а не дія. */
.run-line {
  display: flex; align-items: center; gap: 8px;
  font-size: 0.76em; color: var(--ink-muted); letter-spacing: 0.08em;
  white-space: nowrap;
}
.run-line .sep { color: var(--edge); }
.run-line b { color: var(--ink); }
.run-line b.late { color: #ffb08a; }

/* Ромб прогнозу. Стоїть між двома смужками HP, бо він саме про обмін між ними: скільки
   полетить туди й скільки прилетить назад. Ромб, а не прямокутник, — щоб не читався як
   ще одна плашка стану: це не стан, а ціна ходу. */
.forecast {
  --fc: clamp(56px, 13.5dvh, 96px);
  position: relative;
  width: var(--fc);
  height: var(--fc);
  /* Повернутий на 45° квадрат вилазить за свою рамку розкладки на (√2−1)/2 сторони — і
     накривав рядок «АКТ / ЛОКАЦІЯ / ХІД» над собою. Відступ рівно на цю величину. */
  margin-top: calc(var(--fc) * 0.22);
  display: flex; align-items: center; justify-content: center;
  transform: rotate(45deg);
  border: 1px solid rgba(242, 203, 132, 0.4);
  border-radius: 14px;
  background: linear-gradient(180deg, rgba(20, 13, 8, 0.82), rgba(6, 4, 3, 0.9));
  box-shadow: 0 0 30px -10px rgba(242, 203, 132, 0.5);
  cursor: help;
}
.fc-inner {
  transform: rotate(-45deg);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
}
.fc-out { font-size: calc(var(--fc) * 0.3); color: #ff9c85; line-height: 1; }
.fc-rule { width: 2.2em; height: 1px; background: var(--edge); }
.fc-in { font-size: calc(var(--fc) * 0.22); color: var(--blood-lit); line-height: 1; }
.fc-out.zero, .fc-in.zero { color: var(--ink-dim); }

/* ---------- Лівий нижній кут: меню й здібності ---------- */

.stage-left {
  position: absolute;
  left: var(--pad); bottom: calc(var(--pad) * 1.2);
  display: flex; align-items: flex-end; gap: var(--pad);
  z-index: 6;
}
.stage-menu { align-self: flex-end; }

/* Амулети здібностей. Кругла форма тут не косметика: ці кнопки стосуються магії, а не столу,
   і мусять відрізнятися від кубика навпомацки — палець намацує їх, не дивлячись. */
.ability-orbs { display: flex; gap: 8px; }
.orb {
  position: relative;
  width: clamp(34px, 9.5dvh, 60px);
  height: clamp(34px, 9.5dvh, 60px);
  flex: none; padding: 0;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--edge-lit);
  background: radial-gradient(circle at 50% 30%, #2a1c12, #100b07);
  box-shadow: 0 4px 10px -4px #000;
}
.orb .orb-art { --art-size: 56%; }
.ability:not(.off) {
  border-color: var(--arcane);
  background: radial-gradient(circle at 50% 30%, #5b3990, #241636);
  box-shadow: 0 0 16px -2px var(--arcane), 0 1px 0 rgba(255, 210, 150, 0.14) inset;
}
/* Недоступна здібність гасне, але лишається натисною — тап пояснює, чого бракує. */
.ability.off { opacity: 0.55; }
/* Ціна — бейджиком на ріжку: емблема здібності займає середину амулета. */
.orb-cost {
  position: absolute; right: -2px; bottom: -2px;
  font-size: 0.58em; font-weight: 800; line-height: 1;
  color: #1a1108; background: var(--brass);
  border-radius: 999px; padding: 1px 5px;
}
.ability:not(.off) .orb-cost { background: var(--brass-lit); }
/* Максимум один каст на здібність за хід — позначка нагадує, що вона своє відпрацювала. */
.orb-used {
  position: absolute; top: -3px; right: -3px;
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--brass); color: #1a1108;
  font-size: 0.56em; font-weight: 800;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 4px #000;
}
/* Порожній слот — заглиблення без вмісту: рамка пунктиром і темніше дно, щоб читався як
   місце, куди щось кладуть, а не як вимкнена кнопка. Закритий глухий. */
.orb-empty { border-style: dashed; border-color: var(--edge); background: rgba(0, 0, 0, 0.42); }
.orb-locked { border-color: #2e2118; background: linear-gradient(180deg, #1a120c, #0d0906); opacity: 0.7; }
.orb-locked .orb-art { --art-size: 40%; opacity: 0.7; }

/* ---------- Дуга кубиків ---------- */

/* Кубики обох сторін однією дугою: свої ліворуч від риски, ворожі праворуч і тьмяніші.
   Риска — межа відповідальності: усе ліворуч можна перекинути, усе праворуч — лише прочитати. */
.dice-arc {
  position: absolute;
  left: 50%; bottom: calc(var(--pad) * 1.4);
  transform: translateX(-50%);
  display: flex; align-items: flex-end; justify-content: center;
  gap: clamp(4px, 1.2vw, 14px);
  z-index: 4;
  max-width: 62%;
}
/* Дуга: середні кубики вище за крайні. У рівній шеренезі всі однаково далеко від погляду,
   а на дузі центр читається першим — саме там і стоїть щойно перекинутий кубик. */
.arc-slot { transform: translateY(calc(-1 * var(--lift, 0px))); }
.arc-slot.foe { opacity: 0.86; }
.arc-split {
  width: 1px;
  height: clamp(30px, 9dvh, 70px);
  margin: 0 clamp(3px, 0.6vw, 7px);
  background: linear-gradient(180deg, transparent, rgba(165, 52, 42, 0.7), transparent);
  align-self: center;
}

/* Кубик у дузі — без рамки-картки: сам кубик і овал тіні під ним. */
.arc-slot .die { border: none; background: none; padding: 1px; }
.arc-slot .die::before {
  content: "";
  position: absolute;
  left: 12%; right: 12%; bottom: 0;
  height: 7px; border-radius: 50%;
  background: radial-gradient(50% 50% at 50% 50%, #000d, transparent 72%);
  z-index: -1;
}
/* Позначки ↻/✓ — по центру над кубиком: сусід у дузі стоїть просто збоку, і кутова позначка
   читалася б як позначка не того кубика. */
.arc-slot .die.clickable.hot::after { top: -7px; right: auto; left: 50%; transform: translateX(-50%); }
/* Позначений на перекид: земля під кубиком світиться латунню + галочка. */
.arc-slot .die.clickable.picked { border: none; background: none; box-shadow: none; }
.arc-slot .die.clickable.picked::before {
  background: radial-gradient(50% 50% at 50% 50%, #f2cb84e0, transparent 74%);
  height: 9px;
  filter: blur(0.5px);
}
.arc-slot .die.clickable.picked::after { content: "✓"; color: #ffe3ae; }
/* Розкритий кубик — той єдиний, чиї грані зараз у панелі. Земля під ним світиться ширше:
   позначених може бути кілька, розкритий завжди один. */
.arc-slot .die.open::before { height: 12px; filter: blur(0.5px) brightness(1.4); }
/* Ворожий світиться кров'ю, а не латунню: його не вибрано, його просто читають. */
.arc-slot .die.foe.open::before {
  background: radial-gradient(50% 50% at 50% 50%, #d2503ce0, transparent 74%);
}
/* Розкритий кубик світиться понад скримом розгортки, а не з-під нього: у діалозі деталей
   (екран 3a) видно рівно два кубики — той, чиї грані зараз читають, і решту столу тьмяно.
   Піднімати доводиться всю дугу: z-index її дітей замкнений у ній самій, і поодинці за
   скрим (z-index 5) вони не вилізли б. */
.dice-arc.focused { z-index: 6; }
.dice-arc.focused .die:not(.open) { opacity: 0.45; }
/* Оправа розкритого: латунна рамка з тонким світлом усередині. Та сама мова, що й у позначки
   на перекид, лише голосніша — на неї й показує панель із гранями.
   Селектор мусить бути не слабшим за `.die.clickable.picked` вище: розкритий свій кубик
   завжди й позначений, інакше та рамка (точніше, її `border: none`) перебивала б цю. */
.arc-slot .die.open,
.arc-slot .die.picked.open {
  padding: calc(var(--pad) * 0.6);
  border: 1px solid var(--brass-lit);
  background: #f2cb841a;
  box-shadow: 0 0 30px -6px rgba(242, 203, 132, 0.8);
}
.arc-slot .die.foe.open {
  border-color: var(--blood-lit);
  background: #f0a4931a;
  box-shadow: 0 0 30px -6px rgba(240, 164, 147, 0.7);
}

/* ---------- Правий нижній кут: керування ходом ---------- */

.turn-ctl {
  position: absolute;
  right: var(--pad); bottom: calc(var(--pad) * 1.2);
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  /* Понад скримом розгортки (z-index 5): головна дія — і кнопка виходу з неї — мусить
     лишатись яскравою й натисною, поки все інше притемнене. */
  z-index: 6;
}
.reroll-pips {
  display: flex; align-items: center; gap: 4px;
  font-size: 0.8em; color: var(--brass-lit);
  cursor: help;
}
.pips { display: flex; gap: 2px; align-items: center; }
.pip { width: 9px; height: 9px; border-radius: 2px; background: #3a2b1e; border: 1px solid #000; }
.pip.reroll.on { background: var(--brass); box-shadow: 0 0 6px var(--brass); }
.pip.reroll.free { background: var(--brass-lit); box-shadow: 0 0 7px var(--brass-lit); }
.pips-more { font-size: 0.76em; color: var(--ink-muted); }

/* Головна дія такту. Розмір приходить інлайном (--ma), бо ту саму ширину arcDieSize()
   вираховує з дуги — інакше кубики й кнопка не влізли б поруч. */
.main-act {
  width: var(--ma, 56px); height: var(--ma, 56px);
  flex: none;
  padding: 0;
  border-radius: 50%;
  font-size: calc(var(--ma, 56px) * 0.4);
  line-height: 1;
}
.main-act .art { --art-size: 52%; }
/* Зелена — «хід зроблено, бий». Колір несе рішення, тож підпис їй не потрібен. */
.main-act.done {
  background: radial-gradient(circle at 50% 28%, #58ab41, #20491a);
  border-color: #9ada84;
  color: #f4ffec;
  font-weight: 800;
  box-shadow: 0 0 30px -6px #6fbb54, 0 2px 0 rgba(255, 255, 255, 0.22) inset;
  text-shadow: 0 1px 2px #0009;
}
.main-act.done:disabled { box-shadow: none; }
.main-act.go { border-color: var(--brass-lit); box-shadow: 0 0 22px -8px var(--brass-lit); }

/* Підказка під 3D-стіл: у 3D кубиків у дузі немає, тож словами кажемо, що з ними робити. */
.table-hint {
  position: absolute;
  left: 50%; bottom: calc(var(--pad) * 1.4);
  transform: translateX(-50%);
  font-size: 0.8em; text-shadow: 0 1px 2px #000;
  z-index: 4;
}

/* ---------- Шар розгортки ---------- */

/* Чотири яруси, бо шар мусить одночасно гасити стіл, лишати кубики натисними — і не
   накривати ними ж панель:
     • .pick-catch (z-index 3) — прозорий ловець кліків ПІД кубиками: усе, що не кубик і не
       кнопка, це «поза», і клік туди закриває розгортку;
     • .pick-scrim (z-index 5) — притемнення сцени. Кліків не ловить зовсім, інакше з'їдав би
       тапи по кубиках;
     • дуга з розкритим кубиком (z-index 6, .dice-arc.focused) — понад скримом: світиться
       той кубик, чиї грані читають, а решта дуги гасне власною прозорістю;
     • .pick-layer (z-index 7) — сама панель. Над кубиками, бо на низькому екрані дуга
       дістає до середини сцени, а перекривати мусить не панель, а те, про що вона. */
.pick-catch { position: absolute; inset: 0; z-index: 3; }
.pick-scrim {
  position: absolute; inset: 0;
  background: #060302c4;
  z-index: 5;
  pointer-events: none;
}
.pick-layer {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: var(--pad);
  z-index: 7;
  pointer-events: none;
}
.pick-layer .die-card, .pick-layer .dd-aside { pointer-events: auto; }
/* Стелю плитки ділимо на кількість рядів: у d20 їх сім, і без цього картка вилізла б за
   екран. У d4-d12 рядів мало, тож дільник ні на що не впливає — працює верхня межа. */
.pick-layer .die-grid { --dg: min(clamp(30px, 9dvh, 50px), calc(44dvh / var(--rows, 2))); }
/* Картка деталей дихає вільніше за решту місць, де показують кубик: у неї дивляться впритул
   і по ній вирішують, а не пробігають оком у ряду інших. */
.pick-layer .die-card {
  gap: calc(var(--pad) * 1.1);
  padding: calc(var(--pad) * 1.8) calc(var(--pad) * 2);
  border-radius: 14px;
}

/* Рішення — збоку від картки й абсолютом, тож картка лишається по центру екрана: ширина
   кнопки не зсуває розкладку, на яку дивляться. */
.die-detail { position: relative; display: flex; }
.dd-aside {
  position: absolute;
  left: 100%; top: 50%;
  transform: translateY(-50%);
  margin-left: calc(var(--pad) * 2);
  display: flex; flex-direction: column; align-items: center; gap: calc(var(--pad) * 1.2);
}

/* Перекид — кругла латунна кнопка. Підпис під емблемою потрібен саме тут: кнопка стоїть
   окремо від картки, і сама лише ↻ на ній не сказала б, що перекидається й чому вона тут. */
.pick-confirm {
  width: clamp(48px, 15dvh, 74px); height: clamp(48px, 15dvh, 74px);
  min-width: 0; padding: 0;
  border-radius: 50%;
  flex: none; flex-direction: column; gap: 1px;
}
.pick-confirm .art { --art-size: 38%; }
.pc-label {
  font-size: 0.52em; font-weight: 800; line-height: 1;
  letter-spacing: 0.06em; text-transform: uppercase;
}
.rerolls {
  display: flex; align-items: center; gap: 5px;
  padding: 3px 8px; border-radius: 999px;
  border: 1px solid var(--edge-lit); background: #0000005c;
  font-size: 0.82em; color: var(--brass-lit);
  cursor: help;
}

/* ---------- Картка знайомства з вузлом ---------- */

.card.intro { gap: 6px; }
.card.intro .h-big { font-size: 1.45em; }
.intro-dice { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--pad); }
.intro-die {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 5px 9px; border-radius: 10px;
  border: 1px solid var(--edge); background: #0000004d;
  font-size: 0.8em; color: var(--blood-lit);
}

/* ---------- Онбординг ---------- */

/* Не окремий туторіал, а та сама сцена: усе притемнене, світиться лише те, про що йдеться.
   Так підказка вчить на живому екрані, а не на його малюнку. */
.onboard-scrim {
  position: absolute; inset: 0;
  background: rgba(4, 3, 2, 0.68);
  z-index: 8;
}
/* Піднята ціль кроку: над скримом, тож її і видно, і можна натиснути. Клас знімається сам —
   render() перебудовує сцену цілком, і наступний positionOnboarding() ставить його заново. */
.onboard-lift { z-index: 9; }
.onboard-ring {
  position: absolute;
  border-radius: 16px;
  box-shadow: 0 0 0 2px rgba(242, 203, 132, 0.7), 0 0 40px -6px rgba(242, 203, 132, 0.65);
  background: rgba(242, 203, 132, 0.08);
  z-index: 9;
  pointer-events: none;
  transition: all 0.22s ease-out;
}
.onboard-card {
  position: absolute;
  left: 50%; transform: translateX(-50%);
  width: min(430px, 88%);
  display: flex; flex-direction: column; gap: 8px;
  padding: calc(var(--pad) * 1.4);
  border-radius: 14px;
  border: 1px solid var(--brass);
  background: var(--grad-panel-solid);
  box-shadow: 0 22px 50px -18px #000;
  z-index: 10;
}
.onboard-head { display: flex; align-items: center; justify-content: space-between; }
.onboard-step {
  font-size: 0.72em; letter-spacing: 0.18em; text-transform: uppercase; color: var(--brass);
}
.onboard-dots { display: flex; gap: 4px; }
.onboard-dots i { width: 16px; height: 3px; border-radius: 999px; background: #3a2b1e; }
.onboard-dots i.done { background: var(--brass); }
.onboard-dots i.now { background: var(--brass-lit); }
.onboard-card .ob-title { font-family: var(--font-display); font-size: 1.2em; color: var(--ink); }
.onboard-card .ob-text { font-size: 0.9em; line-height: 1.5; color: var(--ink-muted); }
.onboard-card .ob-text b { color: var(--ink); }
.onboard-foot { display: flex; align-items: center; gap: 10px; }
.onboard-foot .ob-skip { flex: 1; font-size: 0.8em; color: var(--ink-dim); cursor: pointer; }
/* Носик картки: він і робить її підказкою про конкретне місце, а не плашкою посеред екрана. */
/* Носика немає, доки не відомо, з якого боку картка стала (це вирішує positionOnboarding):
   без сторони він лежав би просто квадратиком у шапці картки. */
.ob-arrow {
  display: none;
  position: absolute; left: 50%;
  width: 15px; height: 15px;
  background: #1b120d;
  transform: translateX(-50%) rotate(45deg);
}
.ob-arrow.down, .ob-arrow.up { display: block; }
.ob-arrow.down { bottom: -8px; border-right: 1px solid var(--brass); border-bottom: 1px solid var(--brass); }
.ob-arrow.up { top: -8px; border-left: 1px solid var(--brass); border-top: 1px solid var(--brass); }
