/* =====================================================================
   base.css — ЕКРАН БАЗИ: ізометрична карта міста та її панелі.

   Окремий файл, бо це окрема підсистема: карта, панель локації і склад
   приїхали разом і разом же читаються. style.css лишається власником
   сцени 440x900, warmatch.css — власником загального «металу»; тут
   тільки те, чого раніше в грі не було.

   Екран складається з чотирьох поверхів:
     · base-hud-*  HUD, що плаває просто на карті (рівень, валюти, ⚙)
     · base-res   стрічка складу: увесь інвентар одним рядком
     · base-view  саме полотно карти — забирає ВСЮ решту висоти
     · панелі     locPanel / stockPanel лягають поверх як шухляди знизу

   Ресурси свідомо живуть НАГОРІ, а не в панелі локації: панель мусить
   відповідати на «що це і що тут робити», а не бути другим складом.

   Полотно рендериться в арт-роздільності (240 px завширшки) і
   розтягується засобами CSS із image-rendering: pixelated — та сама
   схема, за якою в грі малюються всі інші фони. Тому карта сідає в
   загальний стиль, а не виглядає вставкою з іншої гри.
===================================================================== */

.base-wrap {
  position: absolute; inset: 0;
  display: flex; flex-direction: column;
  background: var(--void, #070a08);
}

/* =====================================================================
   HUD
===================================================================== */
/* HUD ПЛАВАЄ НА КАРТІ.

   Суцільної смуги .base-top більше немає: вона забирала висоту назавжди
   і читалась як службовий рядок програми, а не як частина світу. Тепер
   три групи стоять просто поверх карти, як у вертикальній версії
   (E:/pp): профіль ліворуч, лічильники праворуч, шестерня в кутку.

   Прив'язка до .base-view, а не до .base-wrap: саме .base-view — це
   карта, і саме її країв тримається HUD. Заодно все, що плаває, лежить
   в одному контейнері з бічною колонкою чипів, тобто шари вирішуються
   один раз.

   z-index 4 — ПІД затемненням навчання (5) і під колонкою чипів (5).
   Тобто під час навчання HUD темніє разом з усім іншим, і це навмисно:
   поки доступна одна річ, усе решта мусить виглядати недоступним. Крізь
   74% затемнення числа однаково лишаються читними, коли панда про них
   говорить. */
.base-hud-tl,
.base-hud-tr {
  position: absolute; top: 8px; z-index: 4;
  display: flex; align-items: center; gap: 6px;
  pointer-events: none;                 /* лічильники — це табло, не кнопки */
}
/* ---- РОЗКЛАДКА В ПІКСЕЛЯХ СЦЕНИ, А НЕ У ВІДСОТКАХ ----

   Сцена ЗАПЕЧЕНА: 440x900, масштабується цілком, залишок екрана —
   полоси (js/scale.js). Тобто ширина тут стала, і рахувати місце у
   відсотках чи vw нема від чого: 42% від 440 — це просто 185, тільки
   написане так, ніби воно колись поїде.

   Тому весь ряд розкладено числами, які сходяться:

     8   ліворуч
     146 профіль
     8   проміжок
     212 лічильники
     8   проміжок
     42  шестерня (розмір заданий у css/casual.css з !important —
         міняти її тут марно, тому число просто враховане)
     8   праворуч
     ----
     432 + 8 запасу = 440

   Якщо додаватиметься четвертий лічильник — правити треба саме ці
   числа, а не сподіватись, що відсотки якось розсунуться. */
.base-hud-tl { left: 8px; right: auto; max-width: 146px; }

/* Лічильники НЕ ПЕРЕНОСЯТЬСЯ на другий рядок: з wrap третій з'їжджав
   униз, просто на шестерню. Ряд лишається один, а тісно стає самим
   числам — вони й так читаються, бо кожен лічильник має свій колір, а
   точна цифра потрібна лише в магазині. */
.base-hud-tr {
  right: 58px; left: auto;              /* 8 край + 42 шестерня + 8 проміжок */
  flex-wrap: nowrap; justify-content: flex-end;
  max-width: 212px;
  min-width: 0;
}
.base-hud-tl > *, .base-hud-tr > * { pointer-events: auto; }
/* Число всередині лічильника може стиснутись — рамка не роз'їжджається. */
.base-hud-tr .coins { min-width: 0; }
.base-hud-tr .coins b { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Шестерня — у самому кутку, В ОДИН РЯД із лічильниками, а не під ними:
   вона єдина тут кнопка, і рядок від неї не росте. Розмір лишаємо той,
   який дає скін (42px, css/casual.css) — тут тільки позиція. */
#lobby .gear-btn {
  position: absolute; z-index: 4;
  right: 8px; top: 8px;
}

/* Профіль без власної підкладки на всю ширину: тепер це компактна
   пігулка, що займає рівно стільки, скільки треба тексту. */
.base-hud-tl .profile-hud {
  flex: 0 1 auto; min-width: 0; max-width: 146px;
  height: auto; padding: 3px 8px;
  background: rgba(10,16,11,.62);
  border-color: rgba(255,176,32,.34);
  backdrop-filter: blur(2px);
}
.base-hud-tl .ph-xp { min-width: 64px; height: 12px; }

.coins {
  display: flex; align-items: center; gap: 3px;
  padding: 3px 7px;
  background: var(--ink);
  border: 2px solid var(--amber);
  box-shadow: inset 0 0 0 1px rgba(255,224,122,.25);
  color: var(--amber-l);
  font-size: 11px; letter-spacing: .5px;
  flex: 0 0 auto;
}
.coins b { color: var(--sand-l); }
.coins .coin-ic { color: var(--amber); }

/* Лічильник локацій, готових до апгрейду. Це головний «клич» екрана:
   поки він горить, гравцеві є куди тиснути прямо зараз. */
.ready-badge {
  position: absolute; top: -5px; right: -5px;
  min-width: 15px; height: 15px; padding: 0 3px;
  background: var(--olive-l); color: var(--ink);
  border: 2px solid var(--ink);
  font-size: 9px; line-height: 11px; text-align: center;
  animation: wm-ready-pip 1.6s steps(2, end) infinite;
}
@keyframes wm-ready-pip {
  0%, 100% { box-shadow: 0 0 0 0 rgba(111,143,52,.9); }
  50%      { box-shadow: 0 0 0 4px rgba(111,143,52,0); }
}
#btnStock { position: relative; overflow: visible; }

/* ---------------------------------------------------------------------
   СТРІЧКИ СКЛАДУ ПІД HUD БІЛЬШЕ НЕМАЄ (.base-res / .brs-chip)
   Вона тримала ВСІ ресурси гри одним рядком, що гортався вбік. На
   десятку позицій це були лічильники «на очах»; на сорока — стрічка, у
   якій потрібну іконку шукаєш гортанням, тобто рівно та робота, заради
   якої існує склад. Тепер склад відкривається чипом «СКЛАД» у бічній
   колонці, а верх екрана віддано карті.
--------------------------------------------------------------------- */

/* =====================================================================
   ПОЛОТНО КАРТИ
===================================================================== */
.base-view { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; }
#baseCanvas {
  display: block; width: 100%; height: 100%;
  image-rendering: pixelated; image-rendering: crisp-edges;
  touch-action: none;                 /* панорамування й пінч робимо самі */
  cursor: grab;
  background: #05070a;
}
#baseCanvas:active { cursor: grabbing; }

.base-hint {
  position: absolute; left: 50%; bottom: 14px; transform: translateX(-50%);
  padding: 5px 10px;
  background: rgba(5,7,10,.88);
  border: 2px solid var(--amber);
  color: var(--sand-l);
  font-size: 9px; letter-spacing: 1px; white-space: nowrap;
  opacity: 0; transition: opacity .4s;
  pointer-events: none;
}
.base-hint.show { opacity: 1; }

/* --------- АСИСТЕНТ НА БАЗІ: СЕРЖАНТ БУЛОЧКА ---------
   Не портрет у рамці, а персонаж, який ВИХОДИТЬ сказати своє й іде.
   Рамки немає свідомо: ролик — VP9 з альфа-каналом, тож будь-яке тло
   за пандою малювало б прямокутник там, де його не має бути.

   Три стани:
     (без класу) — панда в повний зріст + хмарка над головою;
     .leaving    — програється анімація виходу за лівий край;
     .idle       — асистента на екрані немає взагалі.

   Саме .idle, а не «згорнутий портрет у кутку»: карта — головний
   об'єкт цього екрана, і персонаж поверх неї не має права займати
   нижній лівий кут увесь час заради двох рядків раз на візит.

   Док не ловить події сам (pointer-events: none) — карту під ним видно
   й можна тягти; клікабельні лише панда та хмарка. */
#lobby .zoras-dock, #btPandaHost .zoras-dock{
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 5;
  display: block; height: 0;
  padding: 0;
  pointer-events: none;
}
#lobby .zoras-dock > *, #btPandaHost .zoras-dock > *{ pointer-events: auto; }

#lobby .zoras-frame, #btPandaHost .zoras-frame{
  position: absolute; left: 4px; bottom: -6px;
  width: 132px; height: 238px;
  background: none; box-shadow: none;
  cursor: pointer;
  transform-origin: 15% 100%;
  transition: width .34s cubic-bezier(.2,.82,.25,1.12),
              height .34s cubic-bezier(.2,.82,.25,1.12),
              left .34s cubic-bezier(.2,.82,.25,1.12),
              opacity .2s linear;
}
#lobby .zoras-frame video, #btPandaHost .zoras-frame video{
  display: block; width: 100%; height: 100%;
  max-width: none; max-height: none;
  object-fit: contain; object-position: bottom center;
  background: none;
  filter: drop-shadow(0 5px 9px rgba(0,0,0,.6));
}

/* ---- хмарка ----
   Стоїть над пандою і трохи правіше, хвостик дивиться їй у голову.
   Ширина рахується від правого краю екрана, а не від тексту: інакше
   коротка репліка «стрибала» б хмаркою при кожній зміні рядка. */
#lobby .zoras-box, #btPandaHost .zoras-box{
  position: absolute; left: 96px; right: 8px; bottom: 214px;
  max-width: none; min-height: 0; max-height: calc(38 * var(--vh));
  align-self: auto; margin: 0;
  /* хвостик стирчить ЗА межі хмарки, тому обрізати вміст тут не можна */
  overflow: visible;
  /* Було 12px — на телефоні це читалось важко, підняли в півтора рази.
     Разом із кеглем підняли й стелю висоти: та сама репліка більшим
     шрифтом займає більше рядків, і на старому ліміті довгі репліки
     навчання почали б вилазити за хмарку. */
  font-size: 18px; line-height: 1.4;
  padding: 11px 22px 13px 14px;
}
/* Хвостик: квадрат, повернутий на 45°, із тим самим тлом і тією ж
   обводкою, що й хмарка. Не трикутник з border-color — тому що хмарці
   потрібні ДВІ лінії (амбер + чорна), а їх дає лише box-shadow.
   clip-path лишає тільки зовнішню половину, інакше кільце малювало б
   риску впоперек самої хмарки. */
#lobby .zoras-box::before, #btPandaHost .zoras-box::before{
  content: "";
  position: absolute; left: 20px; bottom: -9px;
  width: 15px; height: 15px;
  background: rgba(7,10,8,.94);
  box-shadow: 0 0 0 2px var(--amber), 0 0 0 4px var(--ink);
  transform: rotate(45deg);
  clip-path: polygon(140% -40%, 140% 140%, -40% 140%);
}
#lobby .zoras-box::after, #btPandaHost .zoras-box::after{ bottom: 3px; }

/* ---- поява: панда «вистрибує» з-за краю разом із хмаркою ---- */
#lobby .zoras-dock.pop .zoras-frame, #btPandaHost .zoras-dock.pop .zoras-frame{ animation: wm-panda-pop .46s cubic-bezier(.2,.82,.25,1.12) both; }
#lobby .zoras-dock.pop .zoras-box, #btPandaHost .zoras-dock.pop .zoras-box{ animation: wm-bubble-pop .26s .16s ease-out both; }
@keyframes wm-panda-pop {
  0%   { transform: translate(-46%, 16%) rotate(-10deg) scale(.72); opacity: 0; }
  60%  { transform: translate(2%, -3%) rotate(3deg) scale(1.06); opacity: 1; }
  100% { transform: translate(0, 0) rotate(0) scale(1); opacity: 1; }
}
@keyframes wm-bubble-pop {
  from { transform: translate(-10px, 8px) scale(.9); opacity: 0; }
  to   { transform: translate(0, 0) scale(1); opacity: 1; }
}

/* ---- вихід: той самий шлях, що й поява, тільки навпаки ----
   Тривалість збігається з LEAVE_MS у js/lobby.js: там за нею ховається
   док. Змінюєте тут — міняйте і там, інакше персонаж або зникне ривком
   посеред анімації, або «зависне» на кадр після неї. */
#lobby .zoras-dock.leaving, #btPandaHost .zoras-dock.leaving{ pointer-events: none; }
#lobby .zoras-dock.leaving .zoras-frame, #btPandaHost .zoras-dock.leaving .zoras-frame{ animation: wm-panda-leave .38s cubic-bezier(.55,0,.85,.35) both; }
#lobby .zoras-dock.leaving .zoras-box, #btPandaHost .zoras-dock.leaving .zoras-box{ animation: wm-bubble-leave .18s ease-in both; }
@keyframes wm-panda-leave {
  0%   { transform: translate(0, 0) rotate(0) scale(1); opacity: 1; }
  35%  { transform: translate(6%, -6%) rotate(6deg) scale(1.05); opacity: 1; }
  100% { transform: translate(-46%, 16%) rotate(-10deg) scale(.72); opacity: 0; }
}
@keyframes wm-bubble-leave {
  to { transform: translate(-10px, 8px) scale(.9); opacity: 0; }
}

/* ---- сказав своє і пішов: на карті асистента немає ---- */
#lobby .zoras-dock.idle, #btPandaHost .zoras-dock.idle{ display: none; }



/* Низька сцена (альбомний телефон): персонаж на пів екрана лише заважає. */
@media (max-height: 640px) {
  #lobby .zoras-frame, #btPandaHost .zoras-frame{ width: 96px; height: 172px; }
  #lobby .zoras-box, #btPandaHost .zoras-box{ left: 74px; bottom: 156px; }
}

/* =====================================================================
   ПАНДА НАД ЕКРАНОМ ГРИ (#puzzle .puz-zoras)

   Той самий асистент, що й на карті, тільки поверх поля: навчання гри
   тепер веде він (games/reforge/js/tutorial.js -> App.shell.say()).

   Правила ті самі, що в лоббі, але СЕЛЕКТОРИ ОКРЕМІ, а не через кому:
   #puzzle живе ЗА межами #app, тобто поза масштабованою сценою, і
   розміри тут — у реальних пікселях в'юпорта, а не в її системі
   координат. Спроба ділити правила з лоббі означала б, що будь-яка
   правка сцени тихо з'їжджає над грою.

   Панда стоїть НИЖЧЕ, ніж на карті: під грою є нижня смуга з
   інструментами, і персонаж не має її накривати.
===================================================================== */
#puzzle .puz-zoras {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 40;
  display: block; height: 0; padding: 0;
  pointer-events: none;
}
#puzzle .puz-zoras > * { pointer-events: auto; }

#puzzle .puz-zoras .zoras-frame {
  position: absolute; left: 2px; bottom: -4px;
  width: clamp(96px, 26vw, 136px); height: clamp(172px, 47vw, 245px);
  background: none; box-shadow: none; cursor: pointer;
  transform-origin: 15% 100%;
}
#puzzle .puz-zoras .zoras-frame video {
  display: block; width: 100%; height: 100%;
  max-width: none; max-height: none;
  object-fit: contain; object-position: bottom center;
  background: none;
  filter: drop-shadow(0 5px 9px rgba(0,0,0,.6));
}
#puzzle .puz-zoras .zoras-box {
  position: absolute; left: clamp(88px, 25vw, 128px); right: 8px;
  bottom: clamp(150px, 41vw, 214px);
  max-width: none; min-height: 0; max-height: 34vh;
  align-self: auto; margin: 0; overflow: visible;
  font-size: clamp(12px, 3.4vw, 15px); line-height: 1.45;
  padding: 9px 20px 11px 12px;
}
#puzzle .puz-zoras .zoras-box::before {
  content: "";
  position: absolute; left: 20px; bottom: -9px;
  width: 15px; height: 15px;
  background: rgba(7,10,8,.94);
  box-shadow: 0 0 0 2px var(--amber), 0 0 0 4px var(--ink);
  transform: rotate(45deg);
  clip-path: polygon(140% -40%, 140% 140%, -40% 140%);
}
#puzzle .puz-zoras .zoras-box::after { bottom: 3px; }

#puzzle .puz-zoras.pop .zoras-frame { animation: wm-panda-pop .46s cubic-bezier(.2,.82,.25,1.12) both; }
#puzzle .puz-zoras.pop .zoras-box { animation: wm-bubble-pop .26s .16s ease-out both; }
#puzzle .puz-zoras.leaving { pointer-events: none; }
#puzzle .puz-zoras.leaving .zoras-frame { animation: wm-panda-leave .38s cubic-bezier(.55,0,.85,.35) both; }
#puzzle .puz-zoras.leaving .zoras-box { animation: wm-bubble-leave .18s ease-in both; }
#puzzle .puz-zoras.idle { display: none; }

/* =====================================================================
   ПАНЕЛЬ ЛОКАЦІЇ
   Шухляда знизу: картка займає нижні дві третини, решта — притемнена
   карта, щоб не втрачався контекст, куди саме гравець тапнув.
===================================================================== */
#locPanel, #stockPanel {
  position: absolute; inset: 0; z-index: 40;
  display: none; align-items: flex-end; justify-content: center;
  background: rgba(5,7,10,.66);
}
#locPanel.show, #stockPanel.show { display: flex; }

.loc-card, .stock-card {
  width: 100%; max-height: 80%;
  display: flex; flex-direction: column;
  background: linear-gradient(180deg, #16201a, #0c110e);
  border-top: 3px solid var(--amber);
  box-shadow: 0 -4px 0 var(--ink), 0 -12px 34px rgba(0,0,0,.7);
  animation: wm-drawer .22s steps(4, end);
}
@keyframes wm-drawer { from { transform: translateY(100%); } to { transform: translateY(0); } }

.loc-bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 10px;
  border-bottom: 2px solid var(--ink);
  background: rgba(0,0,0,.3);
  flex: 0 0 auto;
}
.loc-title { color: var(--amber); font-size: 14px; letter-spacing: 2px; text-shadow: 1px 1px 0 var(--ink); }
.loc-close {
  width: 26px; height: 26px; padding: 0;
  background: var(--ink); color: var(--sand-l);
  border: 2px solid var(--steel); font-size: 13px; cursor: pointer;
}
.loc-close:active { background: var(--alert); }

.loc-body, .stock-list { flex: 1 1 auto; overflow-y: auto; padding: 8px 10px 4px; }

/* ---------- АРТ ЛОКАЦІЇ ----------
   Головний носій змісту в панелі: сама будівля на своєму рівні. Вона
   каже і що це за точка, і в якому вона стані — швидше за будь-який
   абзац. Поділки рівня лежать у кутку рамки, без окремого рядка. */
.loc-art {
  position: relative;
  height: 118px; margin-bottom: 8px;
  display: flex; align-items: flex-end; justify-content: center;
  background:
    radial-gradient(120% 90% at 50% 100%, rgba(255,176,32,.10), rgba(0,0,0,0) 70%),
    linear-gradient(180deg, #0b120e 0%, #131c15 78%, #0a0f0c 100%);
  border: 2px solid var(--ink);
  box-shadow: inset 0 0 0 1px rgba(255,176,32,.16);
  overflow: hidden;
}
.loc-art.ruin { filter: saturate(.55) brightness(.86); }
/* Арт — намальований png, а не піксель-арт: тому вписуємо його
   `contain` і НЕ вмикаємо pixelated, інакше згладжування зникає і
   будівля розсипається на сходинки. */
.loc-art-im {
  display: block; width: 100%; height: 100%;
  background-repeat: no-repeat; background-position: center bottom;
  background-size: contain;
}
.loc-art .lv-pips { position: absolute; left: 6px; top: 6px; }
.lv-pips { display: flex; gap: 3px; }
.lv-pips .pip { width: 16px; height: 7px; background: #22282c; border: 2px solid var(--ink); }
.lv-pips .pip.on { background: var(--amber); }
.lv-pips .pip.on.max { background: #39ff6e; }

/* Єдиний текстовий рядок панелі — і лише коли будівлі ще немає або вже
   максимум. Усе інше показують іконки й цифри. */
.loc-gate {
  margin-bottom: 8px; padding: 5px 8px;
  background: rgba(224,58,28,.12);
  border-left: 3px solid var(--alert);
  font-size: 9px; letter-spacing: 1px; color: var(--flame-l);
}
.loc-gate.max { background: rgba(57,255,110,.08); border-left-color: #39ff6e; color: #8ed24f; }

/* ---------- ПОКАЗНИКИ ТОЧКИ ----------
   Схема ліворуч, три шкали праворуч. Свідомо БЕЗ заголовка-рубрики:
   рядок і так читається як «ось як тут летить», а зайвий підпис у
   попапі, який дивляться пів секунди, коштує дорожче, ніж пояснює. */
.loc-mech-wrap { margin-bottom: 9px; }
.loc-mech {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 9px; padding: 6px 8px;
  background: rgba(74,99,35,.14);
  border: 1px solid var(--ink);
  border-left: 3px solid var(--amber);
}
.loc-mech-wrap .loc-mech { margin-bottom: 0; }
.loc-mech .lm-art {
  display: block; width: 104px; height: 58px; flex: 0 0 auto;
  background-repeat: no-repeat; background-position: center;
  background-size: 104px 58px;
}
.loc-mech .lm-txt { display: flex; flex-direction: column; gap: 3px; flex: 1 1 auto; min-width: 0; }
.lm-row { display: flex; align-items: center; gap: 6px; }
.lm-k { font-size: 8px; letter-spacing: .6px; color: var(--sand-l); opacity: .8; flex: 0 0 62px; }
.lm-bar { display: flex; gap: 2px; flex: 0 0 auto; }
.lm-bar .lm-p { display: block; width: 9px; height: 6px; background: #22282c; border: 1px solid var(--ink); }
.lm-bar .lm-p.on { background: var(--amber); }
.lm-v { font-size: 9px; letter-spacing: .5px; color: var(--amber-l); }
.lm-v.wide { margin-left: 2px; }
.lm-quirk {
  padding: 5px 8px;
  background: rgba(255,176,32,.12);
  border: 1px solid var(--ink); border-top: 0;
  border-left: 3px solid var(--amber);
  font-size: 9px; letter-spacing: .6px; color: var(--amber-l);
}

/* ---------- заголовки ---------- */
.loc-block { margin-bottom: 9px; }
.lb-title {
  font-size: 9px; letter-spacing: 1.4px; color: var(--amber);
  padding-bottom: 3px; margin-bottom: 5px;
  border-bottom: 2px solid rgba(255,176,32,.22);
}
.lb-title.ok { color: #8ed24f; border-bottom-color: rgba(142,210,79,.3); }
.lb-title.miss { color: var(--flame-l); border-bottom-color: rgba(224,58,28,.3); }

/* Чіп «що падає» — сама іконка. Підпис тут зайвий: рядок читають як
   «скільки різного дає точка», а не як список назв. */
.res-row { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 9px; }
.res-chip {
  display: flex; align-items: center; gap: 4px;
  padding: 3px;
  background: rgba(74,99,35,.18);
  border: 1px solid var(--ink);
  border-left: 3px solid var(--olive-l);
  font-size: 9px; color: var(--sand-l);
}
.res-chip.new { border-left-color: var(--amber); background: rgba(255,176,32,.14); }
.res-chip.coin { border-left-color: var(--amber); background: rgba(255,176,32,.12); padding: 3px 7px; }
.res-chip.coin b { color: var(--amber-l); }
.res-ic {
  display: block; width: 24px; height: 24px; flex: 0 0 auto;
  background-repeat: no-repeat; background-position: center;
  background-size: 24px 24px;
  image-rendering: pixelated;
}

/* ---------- сітка вимог ----------
   Плитки, а не рядки: без назви ресурсу рядок на всю ширину — це 90%
   порожнечі. Червона рамка = бракує. */
.req-grid { display: flex; flex-wrap: wrap; gap: 4px; }
.req {
  display: flex; align-items: center; gap: 4px;
  padding: 3px 6px 3px 4px;
  background: rgba(0,0,0,.30);
  border: 1px solid var(--ink);
  border-left: 3px solid var(--olive-l);
  font-size: 9px;
}
.req.wide { flex: 1 1 100%; }
.req.miss { border-left-color: var(--alert); background: rgba(224,58,28,.10); }
.req-name { flex: 1 1 auto; color: #9aa694; font-size: 8px; letter-spacing: .8px; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.req-num { color: #8ed24f; flex: 0 0 auto; }
.req.miss .req-num { color: var(--flame-l); }
.req-coin { width: 12px; text-align: center; color: var(--amber); flex: 0 0 auto; }

/* ---------- рапорти штабу ---------- */
.hq-reports .rep-bar {
  position: relative; height: 14px;
  background: var(--ink); border: 2px solid var(--steel);
  margin-bottom: 6px;
}
.hq-reports .rep-fill { display: block; height: 100%; background: var(--amber); transition: width .3s steps(6, end); }
.hq-reports .rep-num {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 8px; color: var(--sand-l); text-shadow: 1px 1px 0 var(--ink);
}
.claim-btn { width: 100%; font-size: 10px; }

/* ---------- дії ---------- */
.loc-acts {
  display: flex; gap: 6px; padding: 8px 10px;
  border-top: 2px solid var(--ink);
  background: rgba(0,0,0,.34);
  flex: 0 0 auto;
}
.loc-acts .px-btn { flex: 1 1 0; font-size: 10px; padding: 9px 4px; }
#locBack { flex: 0 0 auto; min-width: 78px; }
.loc-acts .px-btn:disabled { opacity: .38; filter: grayscale(1); }
.loc-acts .px-btn.dim { filter: grayscale(.6) brightness(.78); }
.loc-acts .px-btn.ready { animation: wm-can-build 1.4s steps(2, end) infinite; }
@keyframes wm-can-build {
  0%, 100% { box-shadow: 0 0 0 2px var(--ink), 0 0 0 3px rgba(142,210,79,.5); }
  50%      { box-shadow: 0 0 0 2px var(--ink), 0 0 0 5px rgba(142,210,79,0); }
}

/* =====================================================================
   СКЛАД
   Ресурси згруповані ЗА ЛОКАЦІЄЮ-ВИРОБНИКОМ, а не одним довгим списком:
   так одразу видно, куди йти по те, чого бракує.
===================================================================== */
.stock-grp { margin-bottom: 9px; }
.sg-title {
  font-size: 9px; letter-spacing: 1.4px; color: var(--amber);
  border-bottom: 2px solid rgba(255,176,32,.2);
  padding-bottom: 3px; margin-bottom: 4px;
}
/* Підсумок угорі: скільки всього одиниць і скільки видів уже бачив.
   Одна цифра відповідає на «чи є в мене взагалі що обмінювати» без
   перегляду всіх плиток. */
.stk-sum {
  padding: 5px 8px; margin-bottom: 8px;
  background: rgba(0,0,0,.3);
  border-left: 3px solid var(--amber);
  font-size: 9px; letter-spacing: .06em; color: #9aa793;
}
.stk-sum b { color: var(--amber-l); }

/* Плитки, а не рядки: сорок рядків «іконка · назва · число» — це чотири
   екрани гортання, а квадратна плитка тримає групу локації в один-два
   ряди. Назва лишається в підписі й у підказці. */
.stk-grid {
  display: grid; gap: 4px;
  grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
}
.stk-tile {
  display: grid; justify-items: center; align-content: center; gap: 1px;
  padding: 5px 2px 4px;
  background: rgba(0,0,0,.24);
  border: 1px solid var(--ink);
  border-top: 3px solid var(--steel-l);
}
.stk-tile .res-ic { width: 22px; height: 22px; background-size: contain; }
.stk-n { font-size: 11px; color: var(--amber-l); line-height: 1.1; }
.stk-lab {
  font-size: 6.5px; letter-spacing: .04em; color: var(--sand-l);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* нуль не ховаємо: гравець має бачити, ЩО взагалі буває в грі й чого в
   нього ще немає — це підказка, куди йти */
.stk-tile.zero { opacity: .34; border-top-color: var(--steel); }

.stock-empty { padding: 22px 12px; text-align: center; font-size: 9px; line-height: 1.7; color: #7d867c; }

/* =====================================================================
   БІЧНА КОЛОНКА ФІЧ  (за референсом E:\pp)

   Верхня стрічка тримає тільки те, що читають ОЧИМА — рівень, монети,
   енергію — і шестерню. Усе, що ТИСКАЮТЬ, поїхало у вертикальну колонку
   збоку: інакше кожна нова фіча додавала б кнопку в один ряд із
   лічильниками, поки той не з'їв би пів екрана на телефоні.

   Чип — круглий диск з іконкою і підписом під ним, як у рефі: на
   вертикальному екрані кругла ціль пальцем ловиться краще за
   прямокутну, а підпис знімає питання «що це за значок».
===================================================================== */
.base-rail {
  position: absolute; z-index: 5;
  top: 50%; transform: translateY(-50%);
  display: flex; flex-direction: column; gap: 12px;
  pointer-events: none;                 /* колонка прозора для тапів... */
}
.base-rail-r { right: 8px; }
.base-rail-l { left: 8px; }
.base-rail .rail-chip { pointer-events: auto; }   /* ...а самі чипи — ні */

.rail-chip {
  position: relative; overflow: visible;
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: none; border: 0; padding: 0; cursor: pointer;
  filter: drop-shadow(0 3px 6px rgba(0,0,0,.55));
  transition: transform .12s ease;
}
.rail-chip:active { transform: scale(.93); }

.rc-ico {
  width: 46px; height: 46px; border-radius: 50%;
  display: grid; place-items: center;
  border: 2px solid var(--ink);
  box-shadow: inset 0 2px 0 rgba(255,255,255,.22), inset 0 -3px 0 rgba(0,0,0,.28);
  color: #f4f7ec; font-size: 19px; line-height: 1;
}
.rc-ico svg { width: 27px; height: 27px; display: block; }
.rc-cond  { background: radial-gradient(circle at 34% 28%, #8ccf5a, #3f7a24 72%); }
.rc-stock { background: radial-gradient(circle at 34% 28%, #d9b463, #8a6520 72%); }
.rc-swap  { background: radial-gradient(circle at 34% 28%, #7fd4ff, #1a6ea8 72%); }
.rc-shop  { background: radial-gradient(circle at 34% 28%, #9fb8d6, #3f5b7a 72%); }
.rc-rooms { background: radial-gradient(circle at 34% 28%, #cfa4ff, #6b3fa8 72%); }

/* ангар складу: двосхилий дах і ворота */
.rc-box     { fill: #f4e7c8; stroke: #3a2a10; stroke-width: 1.8; stroke-linejoin: round; }
.rc-boxline { fill: none; stroke: #3a2a10; stroke-width: 1.6; stroke-linejoin: round; }
/* обмін: дві стрілки назустріч одна одній */
.rc-arrow {
  fill: none; stroke: #f2fbff; stroke-width: 2.6;
  stroke-linecap: round; stroke-linejoin: round;
}

/* кімнати: будиночок із дверима й зіркою в фронтоні — та сама зірка,
   що є ціною розбудови, тому іконка одразу каже, чим тут платять */
.rc-room     { fill: #f0e6ff; stroke: #2b1a45; stroke-width: 1.8; stroke-linejoin: round; }
.rc-roomline { fill: none; stroke: #2b1a45; stroke-width: 1.6; stroke-linejoin: round; }

/* мапа в іконці території: складений аркуш + зірка-апгрейд */
.rc-map  { fill: #eef3e2; stroke: #24331a; stroke-width: 1.6; stroke-linejoin: round; }
.rc-fold { fill: none; stroke: #24331a; stroke-width: 1.4; }
.rc-star { fill: #ffd35c; stroke: #6b4a00; stroke-width: 1.1; stroke-linejoin: round; }

.rc-lab {
  font-size: 7.5px; letter-spacing: .06em; color: var(--sand-l);
  text-shadow: 0 1px 0 var(--ink), 0 0 3px rgba(0,0,0,.8);
}

.rc-badge {
  position: absolute; top: -3px; right: -1px;
  min-width: 16px; height: 16px; padding: 0 3px;
  display: none; place-items: center;
  background: var(--olive-l); color: var(--ink);
  border: 2px solid var(--ink); border-radius: 9px;
  font-size: 9px; line-height: 1;
}
/* значок «є що зробити» — тільки коли справді є */
.rail-chip.has .rc-badge { display: grid; animation: wm-ready-pip 1.6s steps(2, end) infinite; }
#condBadge { background: #9dff6e; }
#roomsBadge { background: #d3a6ff; }

/* енергія поруч із монетами, але власним кольором — щоб не зливались */
.coins.energy { border-color: #3fa7d6; color: #bfe8ff; }
.coins.energy .coin-ic { color: #3fa7d6; }

/* понад стелею — енергія світиться теплим, а не синім: це запас, який
   сам не поповнюється, і виглядати він мусить інакше за звичайний */
.coins.energy.over { border-color: #ffd35c; color: #fff0c2; }
.coins.energy.over .coin-ic { color: #ffd35c; }

/* зірки — третя валюта, і третій колір: монета бурштинова, енергія
   синя, зірка бузкова. Три лічильники в один рядок читаються лише
   доти, доки жоден не схожий на сусіда. */
.coins.stars { border-color: #b98cf0; color: #e8d8ff; }
.coins.stars .coin-ic { color: #d3a6ff; }


