/* СХРОН — канон-стиль CONTRACT (ContractUiPalette 1:1).
   Скругления запрещены: углы панелей отмечают золотые L-скобки (js ui.brackets).
   Токены — из ContractUiPalette.java, не выдумывать своих цветов. */

@font-face {
  font-family: 'Bender';
  src: url('../../assets/bender.ttf') format('truetype');
  font-display: swap;
}

:root {
  --screen-top: #0A0A0C;
  --screen-bottom: #050506;
  --panel: rgba(18, 18, 20, 0.85);
  --panel-solid: #121214;
  --panel-alt: #1C1C20;
  --edge: #4A4A4C;
  --edge-soft: #1E1E20;
  --gold: #B0894A;
  --gold-strong: #D1A85E;
  /* Приглушённое золото для обводок и рамок. Появилось потому, что его
     использовали в shop.css и map.css, НЕ объявив: `border: 2px solid
     var(--gold-dim)` с несуществующей переменной невалиден целиком и
     схлопывается в `none` — купленная рамка в топах не рисовалась вообще
     нигде, и по виду это читалось как «фича не сделана». */
  --gold-dim: #8A6C3A;
  /* Ярче основного золота — для наведения и активных состояний. Тоже
     использовалась без объявления. */
  --gold-hi: #E6C382;
  /* Шрифт заголовков. Раньше var(--display) молча падал в наследуемый —
     капсовые подписи набирались не тем, чем задумано. */
  --display: 'Bender', 'Chakra Petch', system-ui, sans-serif;
  --red: #A33A32;
  --green: #5C8F5A;
  --purple: #B07AC8;
  --blue: #4A6478;
  --text: #E6E4DE;
  --text-2: #A8A9A6;
  --muted: #7A7B78;
  --disabled: #4E4F4C;
  --btn: #1A1A1C;
  --btn-hover: #232326;

  /* ---------- мобильные токены (единые для всех экранов) ----------
     --tap-min  — минимальная тач-цель, порог ЖЁСТКИЙ (44x44 CSS px).
     --font-min — минимальный кегль на любом экране, включая телефон.
     Точки перелома НЕ переменные (media query не читает var()) — см.
     комментарий "АДАПТИВНАЯ ВЁРСТКА" ниже: 1150 / 700 / 480. Экраны обязаны
     использовать эти токены и готовые классы (.icon-btn — квадратная кнопка
     без подписи; .order-first внутри .layout — поднять блок наверх в
     мобильной колонке; .subtabs/#res-bar/#nav уже получают fade-подсказку
     скролла автоматически, app.js сам вешает .fade-l/.fade-r) вместо своих
     чисел — так все точки перелома правятся в одном месте. */
  --tap-min: 44px;
  --font-min: 13px;
  --mobile-gap: 8px;
  --mobile-pad: 10px;
}

* { margin: 0; padding: 0; box-sizing: border-box; scrollbar-width: thin; scrollbar-color: #2A2A2C #0E0E10; }

/* нативные белые скроллбары ломают канон — красим в тон панелей */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: #0E0E10; }
::-webkit-scrollbar-thumb { background: #2A2A2C; border: 2px solid #0E0E10; }
::-webkit-scrollbar-thumb:hover { background: #3A3A3C; }
::-webkit-scrollbar-corner { background: #0E0E10; }

html { overflow-x: hidden; }

/* Кегль и трекинг. Bender — узкий техно-гротеск с одинаковыми вертикальными
   штрихами: на капсе широкий letter-spacing превращал слово в «заборчик»
   (ГЕНЕРАТОР читался как Г Е Н Е Р А Т О Р). Трекинг режем везде до 0.4-1px,
   базовый кегль поднимаем 14 -> 16px, вторичный 11 -> 13px. */
body {
  background: var(--screen-top);
  color: var(--text);
  font-family: 'Bender', 'Consolas', 'Courier New', monospace;
  font-size: 16px;
  line-height: 1.45;
  min-height: 100vh;
  overscroll-behavior-y: contain;
}

/* Фон-сетка отдельным fixed-слоем с own compositing layer: background-attachment
   fixed на body перерисовывал весь вьюпорт на каждый пиксель скролла — отсюда
   «тугой» скролл. Слой один раз растеризуется и дальше бесплатен. */
body::before {
  content: '';
  position: fixed; inset: 0; z-index: -1;
  background:
    linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px),
    linear-gradient(180deg, var(--screen-top) 0%, var(--screen-bottom) 100%);
  background-size: 28px 28px, 28px 28px, 100% 100%;
  transform: translateZ(0);
  pointer-events: none;
}

#app { max-width: 1500px; margin: 0 auto; padding: 0 16px 40px; }

a { color: var(--gold-strong); text-decoration: none; }
a:hover { color: var(--gold); }
.hidden { display: none !important; }
.muted { color: var(--muted); }
.small { font-size: 13px; }
.gold { color: var(--gold-strong); }
.green { color: var(--green); }
.red { color: var(--red); }
.caps { text-transform: uppercase; letter-spacing: 1px; }

/* ---------- верхняя панель ---------- */
#topbar {
  display: flex; align-items: center; gap: 18px;
  min-height: 60px; padding: 0 4px;
  border-bottom: 1px solid var(--edge);
}
.brand { min-width: 0; }
.brand-name { font-size: 24px; letter-spacing: 2.5px; color: var(--gold-strong); }
/* подзаголовок — декоративный, никогда не переносится (было: на планшетных
   ширинах выше 700px, где мобильный топбар ещё не включается, «CONTRACT ·
   ПОДГОТОВКА К БЕТЕ» разрывался на 3 строки и распирал #topbar) */
.brand-sub { font-size: 13px; letter-spacing: 1px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
#res-bar { display: flex; gap: 8px; margin-left: auto; flex-wrap: wrap; }
/* маска-подсказка «тут ещё контент» для горизонтально скроллящихся строк —
   #res-bar/.subtabs/#nav (app.js сам вешает .fade-l/.fade-r по scrollLeft,
   см. refreshHScrollFades()). --fade-l/--fade-r остаются 0, пока не задан
   класс — мaska тогда не режет края, обычный вид. */
#res-bar, .subtabs, #nav {
  --fade-l: 0px; --fade-r: 0px;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--fade-l), #000 calc(100% - var(--fade-r)), transparent 100%);
}
#res-bar.fade-l, .subtabs.fade-l, #nav.fade-l { --fade-l: 20px; }
#res-bar.fade-r, .subtabs.fade-r, #nav.fade-r { --fade-r: 20px; }
.res-chip {
  display: flex; align-items: center; gap: 7px; height: 38px; padding: 0 12px;
  background: var(--panel); border: 1px solid var(--edge-soft);
  cursor: default; white-space: nowrap;
}
.res-chip img { width: 22px; height: 22px; }
.res-chip .lbl { font-size: 13px; letter-spacing: 0.5px; color: var(--muted); }
.res-chip .val { font-size: 16px; }
#player-chip {
  display: flex; align-items: center; gap: 10px; height: 38px; padding: 0 12px;
  border: 1px solid var(--edge); color: var(--text-2);
  font-size: 13px; letter-spacing: 0.5px; white-space: nowrap;
}
#player-chip > span:first-child {
  max-width: 140px; overflow: hidden; text-overflow: ellipsis;
}

/* на время запроса кнопки заморожены — двойной тап не шлёт действие дважды */
body.acting .btn, body.acting .item-cell, body.acting .row-item, body.acting .fork-choice-card { pointer-events: none; }

/* ---------- навигация ---------- */
#nav { display: flex; gap: 2px; border-bottom: 1px solid var(--edge-soft); overflow-x: auto; }
.nav-tab {
  display: flex; align-items: center; gap: 8px; height: 48px; padding: 0 18px;
  color: var(--text-2); font-size: 14px; letter-spacing: 0.6px; text-transform: uppercase;
  cursor: pointer; border: none; background: none; font-family: inherit;
  border-bottom: 2px solid transparent; white-space: nowrap;
}
.nav-tab:hover { background: var(--btn-hover); color: var(--text); }
.nav-tab.active {
  background: rgba(209, 168, 94, 0.2); color: var(--gold-strong);
  border-bottom-color: var(--gold-strong);
}
.nav-tab .fa-solid { font-size: 15px; }
.nav-tab .badge {
  min-width: 20px; height: 20px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--gold-strong); color: var(--screen-top); font-size: 13px;
}






/* Сырьё в окне добычи — как ресурс в шапке: иконка и количество. Раньше тут
   стояло слово («металлолом», «компоненты»), которое не влезало в ячейку и
   слипалось с соседней в «металлоломкомпоненты». */
.item-cell.loot-res img { width: 28px; height: 28px; object-fit: contain; }
.item-cell.loot-res .qty { color: var(--gold-strong); font-size: 13px; }

/* ---------- что можно отдать без сожалений ----------
   Сдача на витрину необратима. Зелёная рамка — вещь лишняя (запаса хватает
   на всё, на что она ещё нужна), золотая — на неё уже кто-то рассчитывает:
   стройка, рецепт, реставрация или задание. */
.item-cell.give-safe { border-color: var(--green, #4F9A5B); }
.item-cell.give-warn { border-color: var(--gold-strong); }
.btn.btn-safe { border-color: var(--green, #4F9A5B); color: var(--green, #4F9A5B); }
.btn.btn-safe:hover { background: rgba(79, 154, 91, 0.14); }

/* ---------- модалка итога боя ----------
   Шапка и кнопка стоят на месте, прокручивается только середина. Раньше
   скроллилась вся панель, и «Закрыть» уезжала под разбор боя — её было
   видно как подсвеченную полосу где-то за краем. Тот же приём, что уже
   применён к онбордингу (.onboarding-panel выше). */
.fight-modal { display: flex; flex-direction: column; overflow: hidden; }
.fight-modal-body {
  overflow-y: auto; overflow-x: hidden;
  flex: 1; min-height: 0;
  overscroll-behavior: contain;
}
.fight-modal .modal-actions {
  flex: none; padding: 12px 16px;
  border-top: 1px solid var(--edge-soft);
  background: var(--panel);
}
.fight-rounds-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px; padding: 12px 16px 0; flex-wrap: wrap;
}
.fight-rounds-hint { opacity: 0.65; font-size: 12px; }

/* ---------- разбор боя по раундам ---------- */
/* Раунды выезжают по одному (см. roundsBlock в screens/pvp.js): сплошная
   стена одинаковых строк не читалась вообще. Клик по блоку раскрывает всё
   сразу — ожидание не должно быть обязательным. */
.pvp-round {
  padding: 8px 0 10px;
  border-top: 1px solid var(--edge-soft);
}
.pvp-round:first-child { border-top: none; }
.pvp-round-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.pvp-round-n { letter-spacing: 0.14em; }

/* Раунд въезжает в момент добавления в DOM: прятать прозрачностью нельзя —
   скрытый раунд держит своё место, и модалка стоит пустой, пока идёт разбор. */
.pvp-round.appearing {
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 240ms ease-out, transform 240ms ease-out;
}
.pvp-round.appearing.shown { opacity: 1; transform: none; }


.pvp-round-loot {
  display: flex; align-items: center; gap: 8px;
  margin-top: 4px; padding: 3px 6px; font-size: 13px;
  border-left: 2px solid var(--edge);
}
.pvp-round-loot .ri-icon { width: 18px; height: 18px; }
.pvp-round-loot.took { color: var(--green); border-left-color: var(--green); }
.pvp-round-loot.lost { color: var(--red); border-left-color: var(--red); }

.pvp-hp { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.pvp-hp-label {
  flex: 0 0 96px; font-size: 12px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.06em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pvp-hp-track { flex: 1; height: 6px; background: var(--edge-soft); min-width: 60px; }
.pvp-hp-fill {
  display: block; height: 100%; background: var(--gold-strong);
  transition: width 320ms ease-out;
}
.pvp-hp-fill.mid { background: #C9922F; }
.pvp-hp-fill.low { background: var(--red); }
.pvp-hp-val {
  flex: 0 0 40px; text-align: right; font-size: 12px; color: var(--text-2);
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .pvp-round.appearing { transition: none; opacity: 1; transform: none; }
  .pvp-hp-fill { transition: none; }
}

/* ---------- ПК: меню списком слева ----------

   Верхняя лента вкладок росла вместе с числом экранов: четырнадцать штук уже
   не влезали в ряд даже на широком мониторе, и последние прятались за
   горизонтальным скроллом — их не видели вовсе. Список слева не ограничен
   шириной экрана: экранов может стать хоть двадцать, и все они на виду.

   Разметку не трогаем: #app раскладывается сеткой, nav занимает левую
   колонку на всю высоту, остальное уезжает вправо. На узких экранах (≤1100px)
   всё остаётся как было — там меню внизу вкладками, и это верно для телефона.
*/
@media (min-width: 1101px) {
  #app {
    display: grid;
    grid-template-columns: 210px minmax(0, 1fr);
    grid-template-areas:
      "top    top"
      "nav    banner"
      "nav    screen"
      "nav    status";
    /* Строки задаём ЯВНО. Колонка меню высокая (полтора десятка пунктов) и
       растягивает сумму своих трёх строк; без явных размеров лишняя высота
       расходится поровну по строкам, пустая полоса баннера раздувается, и
       содержимое экрана уезжает вниз — на коротких экранах вроде барахолки
       или награды дня это выглядело как провал в пол-экрана. Теперь всё
       лишнее забирает строка экрана, а баннер и статус остаются по содержимому. */
    grid-template-rows: auto auto 1fr auto;
    align-items: start;
    column-gap: 18px;
  }
  #topbar { grid-area: top; }
  #nav { grid-area: nav; }
  #event-banner { grid-area: banner; }
  main#screen { grid-area: screen; }
  #statusbar { grid-area: status; }

  #nav {
    flex-direction: column;
    gap: 1px;
    overflow-x: visible;
    overflow-y: auto;
    border-bottom: none;
    border-right: 1px solid var(--edge-soft);
    padding-right: 6px;
    /* Липкое: при длинной странице меню остаётся на месте, а не уезжает
       вверх вместе с содержимым. */
    position: sticky;
    top: 12px;
    max-height: calc(100vh - 24px);
    /* Затемнение краёв (маска для горизонтального скролла) в колонке
       ни к чему — оно резало бы верхний и нижний пункты. */
    -webkit-mask-image: none;
    mask-image: none;
  }

  #nav .nav-tab {
    width: 100%;
    justify-content: flex-start;
    height: auto;
    min-height: var(--tap-min);
    padding: 10px 12px;
    border-bottom: none;
    border-left: 2px solid transparent;
    text-align: left;
  }
  #nav .nav-tab .fa-solid { width: 18px; text-align: center; flex: none; }
  #nav .nav-tab span:not(.badge) {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  }
  #nav .nav-tab.active {
    border-left-color: var(--gold-strong);
    border-bottom-color: transparent;
  }
  #nav .nav-tab .badge { flex: none; margin-left: auto; }
}

/* ---------- баннер ивента ---------- */
/* контейнер может держать несколько окон разом (общее + личное) — колонка строк */
#event-banner:empty { display: none; }
#event-banner { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; }
.event-row {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 14px;
  background: rgba(176, 137, 74, 0.8); color: var(--screen-top);
  font-size: 13.5px; letter-spacing: 0.4px;
}
/* kind:"bad" — тревожное окно (облава, обрыв связи) вместо золотого доброго */
.event-row.bad { background: rgba(163, 58, 50, 0.85); color: var(--text); }

/* ---------- панели ---------- */
main#screen { padding-top: 16px; }
.panel { position: relative; background: var(--panel); border: 1px solid var(--edge); }
.panel.soft { border-color: var(--edge-soft); }
.panel-hdr {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  min-height: 38px; padding: 0 12px;
  background: var(--panel-alt); border-left: 2px solid var(--gold-strong);
  border-bottom: 1px solid var(--edge-soft);
  font-size: 14px; letter-spacing: 0.8px; text-transform: uppercase;
}
.panel-hdr .sub { font-size: 11px; letter-spacing: 0.4px; color: var(--muted); }
.info-btn {
  background: none; border: none; cursor: pointer; padding: 2px 4px;
  color: var(--muted); font-size: 14px; line-height: 1;
}
.info-btn:hover { color: var(--gold-strong); }
.panel-hdr.dim { border-left-color: var(--edge); color: var(--muted); }

/* Число, которое умеет себя объяснить (ui.js:bindHint). Пунктир под ПОДПИСЬЮ,
   а не под самой цифрой: подчёркнутая цифра читается как ссылка и мешает
   сравнивать столбцы, а подпись всё равно уже служебная. На телефоне подсказка
   открывается шторкой снизу — значок «?» рядом с подписью показывает, что тут
   вообще есть по чему тапнуть. */
.has-hint { cursor: help; }
.has-hint > div:first-child,
.has-hint > .lbl {
  border-bottom: 1px dotted var(--edge);
  display: inline-block; padding-bottom: 1px;
}
.has-hint:hover > div:first-child,
.has-hint:hover > .lbl { border-bottom-color: var(--gold-strong); color: var(--gold-strong); }
.has-hint > div:first-child::after,
.has-hint > .lbl::after {
  content: '?'; margin-left: 4px; font-size: 9px; vertical-align: super;
  color: var(--gold); opacity: .75;
}

.ck { position: absolute; width: 7px; height: 7px; border: 0 solid var(--gold-strong); pointer-events: none; z-index: 2; }
.ck.tl { top: -1px; left: -1px; border-top-width: 1.5px; border-left-width: 1.5px; }
.ck.tr { top: -1px; right: -1px; border-top-width: 1.5px; border-right-width: 1.5px; }
.ck.bl { bottom: -1px; left: -1px; border-bottom-width: 1.5px; border-left-width: 1.5px; }
.ck.br { bottom: -1px; right: -1px; border-bottom-width: 1.5px; border-right-width: 1.5px; }

/* ---------- кнопки ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 36px; padding: 0 16px;
  background: var(--btn); color: var(--text-2);
  border: none; border-top: 1px solid #2A2A2C; border-bottom: 1px solid #101012;
  font-family: inherit; font-size: 13px; letter-spacing: 0.6px; text-transform: uppercase;
  cursor: pointer; white-space: nowrap;
  transition: background 0.12s ease, color 0.12s ease, transform 0.05s ease;
}
.btn:hover { background: var(--btn-hover); color: var(--text); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn-gold { background: rgba(209, 168, 94, 0.2); color: var(--gold-strong); border-top-color: rgba(209, 168, 94, 0.4); }
.btn-gold:hover { background: rgba(209, 168, 94, 0.3); color: var(--gold-strong); }
.btn:disabled { color: var(--disabled); background: var(--btn); cursor: not-allowed; }
.btn.small { min-height: 30px; padding: 0 12px; font-size: 11.5px; }

/* ---------- иконка-кнопка: квадратная, без подписи ----------
   Топбар (звук/уведомления/выйти) — единственная подпись была у "ВЫЙТИ", её
   убрали (title/aria-label остались), теперь все три кнопки одного типа.
   38px на десктопе — компромисс компактности, на телефоне поднимается до
   --tap-min в мобильном медиа-запросе. Экраны могут переиспользовать класс
   для любой другой квадратной кнопки-иконки. */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; padding: 0; flex: none;
  background: var(--btn); color: var(--text-2); border: none;
  border-top: 1px solid #2A2A2C; border-bottom: 1px solid #101012;
  font-family: inherit; font-size: 15px; cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}
.icon-btn:hover { background: var(--btn-hover); color: var(--text); }
.icon-btn.active { background: rgba(209, 168, 94, 0.2); color: var(--gold-strong); }
.icon-btn:disabled { color: var(--disabled); cursor: not-allowed; }

/* ---------- прогресс ---------- */
.bar { height: 4px; background: var(--edge-soft); overflow: hidden; }
.bar > b { display: block; height: 100%; background: var(--gold-strong); transition: width 0.5s linear; }
.bar.green > b { background: var(--green); }
.bar.red > b { background: var(--red); }
.bar.big { height: 6px; }

/* ---------- предупреждение по здоровью (тяжёлое ранение блокирует поле) --- */
/* тот же rgba(163,58,50) что у .event-row.bad/.missing-scav-row — не новый цвет */
.hp-warn {
  padding: 8px 10px; border: 1px solid var(--red);
  background: rgba(163, 58, 50, 0.14); color: var(--red);
  font-size: 12.5px; line-height: 1.45;
}

/* ---------- вылазка: маршрутный лист ---------- */
/* Карта — инлайновый SVG, координаты узлов кладёт JS из mission.map (t/branch),
   ничего тут не завязано на пиксели/анимацию: три состояния (в поле/ждёт
   решения/завершена) должны читаться со статичного кадра. */
.route-card { display: flex; flex-direction: column; gap: 10px; padding: 12px; }
.route-card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.route-card-who { display: flex; align-items: center; }
.route-status-badge {
  font-size: 11px; letter-spacing: 0.6px; text-transform: uppercase;
  padding: 2px 8px; border: 1px solid currentColor; flex: none;
}
.route-status-badge.field { color: var(--gold-strong); }
.route-status-badge.waiting { color: var(--red); }
.route-status-badge.ok { color: var(--green); }
.route-status-badge.wound { color: var(--gold-strong); }
.route-status-badge.dead, .route-status-badge.missing { color: var(--red); }

.route-grid { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(220px, 1fr); gap: 12px; }
.route-map-col { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.route-svg { width: 100%; height: auto; display: block; background: #0C0C0E; border: 1px solid var(--edge-soft); }

/* пины — квадратные, без скруглений; туман — пунктир и «?», кто там был не сказано */
.route-node { cursor: default; }
.route-node.revealed { cursor: pointer; }
.route-pin { fill: #0C0C0E; stroke: var(--muted); stroke-width: 0.6; }
.route-glyph { font-size: 3.1px; fill: var(--muted); text-anchor: middle; font-family: inherit; }
.route-node.revealed .route-pin { stroke: var(--gold-strong); }
.route-node.revealed .route-glyph { fill: var(--gold-strong); }
.route-node.kind-find.revealed .route-pin { stroke: var(--green); }
.route-node.kind-find.revealed .route-glyph { fill: var(--green); }
.route-node.kind-danger.revealed .route-pin { stroke: var(--red); }
.route-node.kind-danger.revealed .route-glyph { fill: var(--red); }
.route-node.outcome-wound .route-pin { stroke: var(--gold); }
.route-node.outcome-dead .route-pin { stroke: var(--red); stroke-dasharray: 1.2 0.9; }
.route-node.outcome-missing .route-pin { stroke: var(--red); stroke-dasharray: 0.6 0.6; }
.route-node.fog .route-pin { stroke-dasharray: 1.1 0.9; }
.route-node.fork-active .route-pin { fill: rgba(209, 168, 94, 0.22); stroke-width: 0.9; }
.route-node.hot .route-pin { fill: rgba(176, 137, 74, 0.3); }

.route-line { fill: none; stroke: var(--edge-soft); stroke-width: 0.5; stroke-dasharray: 1.4 1.1; }
.route-line-done { fill: none; stroke: var(--gold-strong); stroke-width: 0.8; }
.route-marker { fill: var(--gold-strong); }

/* Колонка журнала тянется на высоту карты рядом — раньше список упирался
   в жёсткие 260px, а под ним оставалась пустая дыра до низа панели. */
.route-log-col { display: flex; flex-direction: column; min-width: 0; }
.route-log-hdr { padding: 2px 2px 6px; letter-spacing: 0.6px; text-transform: uppercase; }
.route-log-list {
  display: flex; flex-direction: column;
  flex: 1; min-height: 0;               /* заполняет колонку, а не оставляет дыру */
  max-height: none;
  overflow-y: auto;
  border-top: 1px solid var(--edge-soft);
  /* своя тонкая полоса: общая 10px рядом с мелкими строками смотрелась
     несоразмерно широкой */
  scrollbar-width: thin;
  scrollbar-color: #33333a transparent;
  /* Список «прилипает» к низу (scrollJournalToNewest в expeditions.js) —
     если контент выше max-height, первая строка обрезается ровно по границе
     скролл-окна, а не по своей нижней кромке, и текст тега ("ВХОД" и т.п.)
     резало пополам без всякого намёка, что выше есть ещё записи. Тот же
     mask-fade приём, что у #res-bar/.subtabs/#nav, но вертикальный —
     .fade-t включает JS (scrollJournalToNewest) при scrollTop > 0. */
  --vfade-t: 0px;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 var(--vfade-t), #000 100%);
  mask-image: linear-gradient(180deg, transparent 0, #000 var(--vfade-t), #000 100%);
}
.route-log-list.fade-t { --vfade-t: 16px; }
.route-log-list::-webkit-scrollbar { width: 6px; }
.route-log-list::-webkit-scrollbar-track { background: transparent; }
.route-log-list::-webkit-scrollbar-thumb { background: #33333a; border: 0; }
.route-log-list::-webkit-scrollbar-thumb:hover { background: #45454e; }
.route-log-row { display: flex; gap: 8px; padding: 8px 4px; border-bottom: 1px solid var(--edge-soft); cursor: pointer; transition: background 0.12s ease; }
.route-log-row:hover, .route-log-row.hot { background: rgba(176, 137, 74, 0.15); }
.route-log-num { flex: none; width: 20px; font-size: 13px; color: var(--muted); padding-top: 2px; font-variant-numeric: tabular-nums; }
.route-log-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.route-log-tag { font-size: 13px; letter-spacing: 0.5px; text-transform: uppercase; color: var(--muted); }
.route-log-txt { font-size: 13px; line-height: 1.4; }
.route-log-row.kind-find .route-log-tag { color: var(--green); }
.route-log-row.kind-danger .route-log-tag { color: var(--red); }
.route-log-row.outcome-wound .route-log-tag { color: var(--gold-strong); }
.route-log-row.outcome-dead .route-log-tag, .route-log-row.outcome-missing .route-log-tag { color: var(--red); }
.route-log-row.outcome-ok .route-log-tag { color: var(--green); }
.route-log-loot { display: flex; gap: 6px; margin-top: 2px; flex-wrap: wrap; }
.route-loot-icon {
  position: relative; width: 26px; height: 26px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: #0F0F11; border: 1px solid var(--edge-soft); cursor: pointer;
}
.route-loot-icon img { width: 20px; height: 20px; }
.route-loot-icon .qty { position: absolute; right: 1px; bottom: 0; font-size: 9px; color: var(--text-2); text-shadow: 0 1px 2px #000; }
.route-log-empty { padding: 10px 4px; }

.fork-panel { display: flex; flex-direction: column; gap: 8px; padding-top: 6px; border-top: 1px solid var(--edge-soft); }
.fork-choices { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.fork-choice-card { transition: background 0.12s ease, border-color 0.12s ease; }
.fork-choice-card:hover { border-color: var(--gold-strong); background: rgba(209, 168, 94, 0.08); }

.route-recall-btn { color: var(--red); }
.route-recall-btn:hover { color: var(--red); background: rgba(163, 58, 50, 0.18); }

/* ---------- сетки экранов ---------- */
.grid { display: grid; gap: 12px; }
.cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.layout { display: flex; gap: 14px; align-items: flex-start; }
.layout > .main-col { flex: 1; min-width: 0; }
.layout > .side-col { width: 340px; flex: none; display: flex; flex-direction: column; gap: 14px; }
/* верстак: колонка рецептов — не .side-col (она первая и не по ширине 340px),
   но по узкой ширине должна вести себя так же, как .side-col — см. медиа-запрос */
.wb-recipes { width: 440px; flex: 0 0 440px; }
/* ---------- карточка модуля ---------- */
.module-card { display: flex; flex-direction: column; min-height: 258px; }
/* ненайденный ствол на стене: плитка ровно по содержимому, без пустоты */
.module-card.unfound { min-height: 0; }
.module-card.unfound .mod-icon { flex: none; padding: 10px 0; }
.module-card .mod-icon {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 12px;
  font-size: 40px; color: var(--text-2); padding: 14px 0;
}
.module-card.running .mod-icon { color: var(--gold-strong); }
.module-card.locked .mod-icon { color: var(--disabled); }
.module-card .mod-body { padding: 0 12px 12px; display: flex; flex-direction: column; gap: 8px; font-size: 13px; }
.lvl-pips { display: flex; gap: 3px; }
.lvl-pips i { width: 7px; height: 7px; }
.lvl-pips i.on { background: var(--gold-strong); }
.lvl-pips i.off { border: 1px solid var(--edge); }
.status-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 6px; }

/* ---------- цепочка входа/выхода (Самогонный аппарат) ---------- */
.proc-chain { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.proc-chip {
  position: relative; width: 34px; height: 34px; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: #0F0F11; border: 1px solid var(--edge-soft); color: var(--text-2); font-size: 12px;
}
.proc-chip img { width: 25px; height: 25px; }
.proc-chip.lack { border-color: var(--red); color: var(--red); }
.proc-chip-label {
  position: absolute; right: -2px; bottom: -6px; font-size: 10px;
  background: var(--panel-solid); padding: 0 2px; color: inherit;
}
.proc-plus, .proc-arrow { color: var(--muted); font-size: 13px; flex: none; }

/* ---------- слоты видеокарт с полосой износа (Майнинг-ферма) ---------- */
.farm-slots { display: flex; flex-wrap: wrap; gap: 5px; }
.farm-slot {
  position: relative; width: 36px; height: 36px; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; color: var(--text-2);
  background: #0F0F11; border: 1px solid var(--edge-soft);
}
.farm-slot.empty { border-style: dashed; }
.farm-slot.empty.clickable { cursor: pointer; }
.farm-slot.empty.clickable:hover { border-color: var(--gold-strong); color: var(--gold-strong); }
.farm-slot.filled { border-color: var(--gold); color: var(--gold-strong); }
.farm-slot .wear-bar {
  position: absolute; left: 3px; right: 3px; bottom: 3px; height: 3px;
  background: var(--edge-soft); overflow: hidden;
}
.farm-slot .wear-bar > b { display: block; height: 100%; }
/* полоса — остаток ресурса: полная зелёная -> жёлтая (gold) -> красная у выгорания */
.farm-slot.wear-ok .wear-bar > b { background: var(--green); }
.farm-slot.wear-warn .wear-bar > b { background: var(--gold-strong); }
.farm-slot.wear-crit .wear-bar > b { background: var(--red); }

/* ---------- журнал событий (экран «Прогресс») ---------- */
.event-log-row {
  display: flex; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--edge-soft);
  font-size: 12.5px;
}
.event-log-row:last-child { border-bottom: none; }
.event-log-row .t { color: var(--muted); flex: none; width: 68px; }
.event-log-row.bad .txt { color: var(--red); }
.event-log-row.good .txt { color: var(--green); }
.missing-scav-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 10px; margin-bottom: 8px; background: rgba(163, 58, 50, 0.14);
  border: 1px solid var(--red); font-size: 12.5px; cursor: pointer;
}

/* кнопка лечения: иконка, название с обрезкой, остаток на складе */
.heal-btn { display: flex; align-items: center; gap: 8px; width: 100%; justify-content: flex-start; padding: 0 10px; }
.heal-icon { width: 24px; height: 24px; flex: none; }
.heal-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.heal-qty { flex: none; color: var(--muted); }

.fold-caret { margin-left: auto; color: var(--muted); font-size: 13px; }
.panel-hdr:hover .fold-caret { color: var(--gold-strong); }

/* строка части тела: иконка, короткая подпись, полоса, цифры — всё в один ряд */
.hp-row { display: flex; align-items: center; gap: 7px; }
.hp-name { width: 72px; flex: none; white-space: nowrap; letter-spacing: 0; }
.hp-num { width: 56px; flex: none; text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ---------- слот крафта (Верстак/Стена: иконка + название + кнопка) ---------- */
.craft-slot-card { display: flex; align-items: center; gap: 12px; padding: 10px 12px; }

/* ---------- предметы ---------- */
.item-cell {
  position: relative; width: 62px; height: 62px;
  display: flex; align-items: center; justify-content: center;
  background: #0F0F11; border: 1px solid var(--edge-soft); cursor: pointer;
}
.item-cell img { width: 46px; height: 46px; }
.item-cell .qty {
  position: absolute; right: 3px; bottom: 2px; font-size: 12px;
  color: var(--text-2); text-shadow: 0 1px 2px #000;
}
.item-cell.rare { border-color: var(--gold); }
.item-cell.epic { border-color: var(--purple); }
.item-cell.empty { background: #0C0C0E; cursor: default; }
.item-cell.selected { border-color: var(--gold-strong); background: rgba(209, 168, 94, 0.14); }
.item-inline { display: inline-flex; align-items: center; gap: 6px; }
.item-inline img { width: 24px; height: 24px; }

/* сетка стеллажей: auto-fill вместо жёстких колонок — сама решает, сколько
   ячеек влезет в строку на любой ширине, ячейка тянется до 1fr, но не уже 62px */
.item-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); gap: 6px; }
.item-grid .item-cell { width: auto; height: auto; aspect-ratio: 1 / 1; }

/* Требования (ингредиенты крафта, детали реставрации, цена стройки) — СТРОКОЙ
   с названием, а не чипом с одной иконкой: у порохов «Ястреб»/«Коршун» и у
   двух наборов «частей» картинки почти неотличимы, и «0/2» рядом с похожей
   иконкой читалось как сломанный счётчик, а не как «нужен другой предмет». */
.req-list { display: flex; flex-direction: column; gap: 3px; }
.req-row {
  display: flex; align-items: center; gap: 8px; padding: 5px 8px;
  background: #0F0F11; border: 1px solid var(--edge-soft); font-size: 12.5px;
  cursor: default;
}
.req-icon { width: 24px; height: 24px; flex: none; }
.req-name {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text-2);
}
.req-qty { flex: none; font-variant-numeric: tabular-nums; }
.req-row.lack { border-color: var(--red); }
.req-row.lack .req-qty { color: var(--red); }
.req-row.ok .req-qty { color: var(--green); }

/* ---------- список-строки ---------- */
.row-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  border-bottom: 1px solid var(--edge-soft); cursor: pointer;
}
.row-item { transition: background 0.12s ease; }
.row-item:hover { background: rgba(176, 137, 74, 0.15); }
.item-cell { transition: border-color 0.12s ease, background 0.12s ease; }
.item-cell:hover:not(.empty) { border-color: var(--gold); }

/* пульс на кнопках «готово забрать» */
.btn-gold.pulse { animation: btn-pulse 1.6s ease-in-out infinite; }
@keyframes btn-pulse {
  0%, 100% { background: rgba(209, 168, 94, 0.2); }
  50% { background: rgba(209, 168, 94, 0.38); }
}
.row-item.selected { background: rgba(209, 168, 94, 0.2); }
.row-item.disabled { opacity: 0.55; cursor: default; }
.row-item img.ri-icon { width: 36px; height: 36px; }

/* ---------- оверлеи/модалки ---------- */
.overlay {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(5, 5, 6, 0.82);
  display: flex; align-items: center; justify-content: center;
}
.login-panel { width: 420px; max-width: 92vw; }
.login-body { padding: 18px; display: flex; flex-direction: column; gap: 14px; }
.login-body label { display: flex; flex-direction: column; gap: 6px; font-size: 12px; letter-spacing: 0.5px; color: var(--text-2); }
.login-body input {
  height: 38px; padding: 0 10px; background: #0F0F11; color: var(--text);
  border: 1px solid var(--edge-soft); font-family: inherit; font-size: 15px;
}
.login-body input:focus { outline: none; border-color: var(--gold); }
.login-error { color: var(--red); font-size: 13px; min-height: 18px; }

.modal-panel { width: 520px; max-width: 92vw; max-height: 84vh; overflow-y: auto; overflow-x: hidden; }
.loot-grid { display: flex; flex-wrap: wrap; gap: 8px; padding: 16px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; padding: 0 16px 16px; flex-wrap: wrap; }

/* ---------- модалка онбординга: скроллится ТОЛЬКО тело шагов ----------
   Раньше скроллилась вся .modal-panel целиком (шапка+шаги+кнопка) — на
   вьюпортах ~700px высотой кнопка "ПОНЯТНО" уезжала за clientHeight и была
   не в кадре, а найти её можно было только доскроллив сам модальный блок.
   Теперь шапка и кнопка — фиксированные, скроллится узкая .onboarding-steps
   между ними, кнопка видна всегда независимо от длины текста. */
.onboarding-panel { display: flex; flex-direction: column; overflow: hidden; }
.onboarding-steps { padding: 18px; display: flex; flex-direction: column; gap: 14px; overflow-y: auto; flex: 1; min-height: 0; }
.onboarding-panel .modal-actions { padding: 14px 18px; border-top: 1px solid var(--edge-soft); flex: none; justify-content: stretch; }
.onboarding-panel .modal-actions .btn { flex: 1; }

/* ---------- тултип ---------- */
#tooltip {
  position: fixed; z-index: 200; pointer-events: none;
  min-width: 180px; max-width: 300px; padding: 8px 10px;
  background: rgba(18, 18, 20, 0.94); border: 1px solid var(--edge);
  font-size: 14px;
}
#tooltip .t-name { color: var(--text); }
#tooltip .t-cat { color: var(--muted); font-size: 11px; letter-spacing: 0.5px; text-transform: uppercase; margin-top: 2px; }
#tooltip .t-desc { color: var(--text-2); font-size: 12.5px; margin-top: 5px; }
#tooltip .t-price { color: var(--gold-strong); font-size: 12.5px; margin-top: 5px; }
/* Строка «что предмет даёт». Отделена линией от описания: описание — это
   художественный текст из пака, а стат — правило игры, и путать их нельзя. */
#tooltip .t-stat {
  color: var(--gold); font-size: 12.5px; margin-top: 6px; padding-top: 6px;
  border-top: 1px solid var(--edge); line-height: 1.45;
}
#tooltip .t-stat + .t-stat { margin-top: 3px; padding-top: 0; border-top: none; }

/* Строка «где предмет нужен». Не золотом, как статы: стат — это правило,
   которое предмет ДАЁТ, а это перечень мест, где он ТРЕБУЕТСЯ. Разные вопросы,
   и глаз не должен их склеивать. Отбивка линией — только у первой строки. */
#tooltip .t-use {
  color: var(--text-2); font-size: 12.5px; margin-top: 6px; padding-top: 6px;
  border-top: 1px solid var(--edge); line-height: 1.45;
}
#tooltip .t-use + .t-use { margin-top: 3px; padding-top: 0; border-top: none; }
#tooltip .t-stat + .t-use { border-top: 1px solid var(--edge); }

/* Правило игры в подробной панели предмета: тем же золотом, что и в тултипе,
   чтобы «что даёт» читалось одинаково в обоих местах. */
.stat-line { color: var(--gold); line-height: 1.5; }
/* тач-режим (bindItemTooltip в ui.js переключает класс по ширине экрана):
   тултип не гоняется за пальцем — это шторка снизу по центру, чтобы никогда
   не вылезать за край экрана */
#tooltip.mobile-sheet {
  left: 50% !important; right: auto !important; top: auto !important;
  bottom: calc(72px + env(safe-area-inset-bottom, 0px)) !important;
  transform: translateX(-50%);
  width: 92vw; max-width: 92vw; min-width: 0;
  padding: 12px 14px;
}
/* в шторке (тач) держим порог 13px — на десктопном ховере (без .mobile-sheet)
   мельче ок, там курсор мыши и текст читается вблизи */
#tooltip.mobile-sheet .t-cat { font-size: var(--font-min); }
#tooltip.mobile-sheet .t-desc,
#tooltip.mobile-sheet .t-price,
#tooltip.mobile-sheet .t-stat { font-size: var(--font-min); }

/* ---------- тосты ---------- */
#toast-root { position: fixed; right: 18px; bottom: 18px; z-index: 300; display: flex; flex-direction: column; gap: 8px; }
.toast {
  min-width: 240px; max-width: 360px; padding: 10px 14px;
  background: rgba(18, 18, 20, 0.96); border: 1px solid var(--edge);
  border-left: 2px solid var(--gold-strong);
  font-size: 13.5px; animation: toast-in 0.18s ease-out;
}
.toast.err { border-left-color: var(--red); }
.toast.ok { border-left-color: var(--green); }
.toast.clickable { cursor: pointer; }
.toast.clickable:hover { border-left-color: var(--gold); background: rgba(28, 28, 31, 0.96); }
@keyframes toast-in { from { transform: translateX(30px); opacity: 0; } to { transform: none; opacity: 1; } }

/* ---------- плашка тега в чате (chat_notify.js) ----------
   Отдельная липкая плашка, НЕ тост: обычный тост живёт секунды и теряется
   среди остальных, а личное упоминание — редкое и адресное, ему нельзя
   потеряться. Держится, пока игрок не закроет её крестиком или сам не
   перейдёт в чат — chat_notify.js решает это (клик по плашке, системное
   Notification, либо переход в чат любым другим путём). Несколько тегов
   подряд схлопываются в ОДНУ плашку со счётчиком (.chatnote-plaque-count),
   а не встают стопкой — root у неё один, содержимое просто перерисовывается.
   pointer-events:none на корне + auto на самой плашке — плашка не глотает
   клики по остальному интерфейсу за пределами своего блока. */
#chatnote-root {
  position: fixed; top: 14px; left: 50%; transform: translateX(-50%);
  z-index: 310; width: min(420px, calc(100vw - 24px));
  pointer-events: none;
}
.chatnote-plaque {
  pointer-events: auto; position: relative; display: flex; gap: 10px; align-items: flex-start;
  padding: 12px 34px 12px 14px; cursor: pointer;
  background: rgba(18, 18, 20, 0.97); border: 1px solid var(--gold-strong);
  border-left: 3px solid var(--gold-strong);
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
  animation: chatnote-drop 0.22s ease-out;
}
.chatnote-plaque:hover, .chatnote-plaque:focus-visible {
  background: rgba(28, 28, 31, 0.98); border-color: var(--gold);
  outline: none;
}
.chatnote-plaque-icon { color: var(--gold-strong); font-size: 16px; margin-top: 2px; flex: none; }
.chatnote-plaque-body { min-width: 0; flex: 1; }
.chatnote-plaque-name { font-size: 13px; font-weight: 600; letter-spacing: 0.3px; color: var(--gold-strong); }
.chatnote-plaque-text {
  margin-top: 3px; font-size: 13px; line-height: 1.4; color: var(--text-2);
  overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
}
.chatnote-plaque-count {
  flex: none; align-self: center; min-width: 20px; padding: 1px 6px;
  background: var(--gold-strong); color: var(--screen-top);
  font-size: 11.5px; font-weight: 700; text-align: center;
}
.chatnote-plaque-close {
  position: absolute; top: 0; right: 0; width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: none; color: var(--muted); cursor: pointer;
}
.chatnote-plaque-close:hover { color: var(--text); }
@keyframes chatnote-drop {
  from { transform: translateY(-12px); opacity: 0; }
  to { transform: none; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .chatnote-plaque { animation: none; }
}

/* ---------- статусбар ---------- */
#statusbar {
  display: flex; align-items: center; justify-content: space-between;
  margin-top: 20px; padding: 8px 4px 0; border-top: 1px solid var(--edge-soft);
  font-size: 11.5px; letter-spacing: 0.5px; color: var(--muted); text-transform: uppercase;
}

/* ---------- вкладки внутри экрана ---------- */
/* overflow-x вместо переноса/обрезки: на стеллажах 8 категорий, в узкий экран
   они физически не влезают в строку — тот же приём, что уже есть у #nav */
.subtabs {
  display: flex; gap: 2px; border-bottom: 1px solid var(--edge-soft); margin-bottom: 12px;
  overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
.subtabs::-webkit-scrollbar { display: none; }
.subtab {
  height: 38px; padding: 0 16px; display: flex; align-items: center; flex: none;
  font-size: 13px; letter-spacing: 0.6px; text-transform: uppercase; color: var(--text-2);
  cursor: pointer; background: none; border: none; font-family: inherit;
  border-bottom: 2px solid transparent; white-space: nowrap;
}
.subtab.active { color: var(--gold-strong); background: rgba(209, 168, 94, 0.2); border-bottom-color: var(--gold-strong); }

/* =====================================================================
   АДАПТИВНАЯ ВЁРСТКА
   1150 — планшет/сжатый десктоп: колонка сайдбара падает вниз, сетки 4/3 → 2.
   700  — телефон: нижняя навигация, компактный топбар, hit-target 44px,
          модалки на весь экран, поля ввода 16px (иначе iOS зумит при фокусе).
   480  — совсем узкий телефон: все предметные сетки схлопываются в 1 колонку.
   ===================================================================== */

@media (max-width: 1150px) {
  /* align-items:flex-start в базовом .layout нужен для десктопного РЯДА (чтобы
     колонки не тянулись друг под друга по высоте); в СТОЛБЦЕ та же настройка
     превращается в cross-axis и схлопывает main-col/side-col по ширине до
     fit-content — панели без .grid внутри (прогресс, верстак, вылазки,
     стеллажи) вместо полной ширины экрана становятся узкой колонкой посередине */
  .layout { flex-direction: column; align-items: stretch; }
  .layout > .side-col { width: 100%; }
  /* главный экран: сбор/топливо/скав важнее сетки модулей — сайдбар первым */
  .layout.layout-home > .side-col { order: -1; }
  /* Обобщённый хук для остальных экранов: любой прямой потомок .layout с
     классом order-first встаёт первым в столбце (стек по order, не по DOM).
     ПРАВИЛО для агентов экранов: если важный блок (детали/действие/то, что
     нужно после тапа) в разметке идёт ПОСЛЕ длинного списка — добавьте ему
     этот класс вместо своего CSS-правила. Пример:
     h('div', { class: 'side-col order-first' }) вместо h('div', { class: 'side-col' }). */
  .layout > .order-first { order: -1; }
  .cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cols-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .wb-recipes { width: 100%; flex: none; }
}

@media (max-width: 700px) {
  /* ---------- топбар: бренд слева с жёстким минимумом ширины, действия
     справа, ресурсы прокруткой снизу.
     Было: grid-template-columns:1fr auto отдавал всю ширину auto-колонке
     чипа (5 некомпрессируемых элементов, ~310px) — колонка бренда схлопывалась
     до 0-57px, "СХРОН" и подзаголовок рисовались ПОД чипом игрока (баг с
     подтверждающего скриншота). Теперь у бренда жёсткий пол в 96px
     (minmax), а чип разгружен: подзаголовок и дублирующий "СХРОН УР. N"
     выключены целиком (обрезанный текст всё равно не читается — резать
     дальше некуда), "ВЫЙТИ" стал иконкой как звук/колокольчик. */
  #topbar {
    display: grid; grid-template-columns: minmax(96px, auto) 1fr;
    grid-template-areas: "brand chip" "res res";
    align-items: center; height: auto;
    gap: var(--mobile-gap) var(--mobile-pad); padding: var(--mobile-gap) var(--mobile-pad);
  }
  .brand { grid-area: brand; min-width: 0; }
  .brand-name { font-size: 18px; letter-spacing: 1.5px; }
  .brand-sub { display: none; }
  #player-chip {
    grid-area: chip; height: auto; min-height: var(--tap-min); padding: 0;
    gap: 6px; font-size: var(--font-min); border: none; background: none;
    flex-wrap: wrap; justify-content: flex-end;
  }
  #player-chip > span:first-child { max-width: 72px; }
  /* "СХРОН УР. N" — тот же уровень виден на самом экране "Схрон", десктоп не трогаем */
  .chip-level { display: none; }
  #res-bar {
    grid-area: res; margin-left: 0; flex-wrap: nowrap;
    overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none;
    padding-bottom: 2px;
  }
  #res-bar::-webkit-scrollbar { display: none; }
  .res-chip { height: 32px; padding: 0 8px; gap: 5px; flex: none; }
  .res-chip img { width: 18px; height: 18px; }
  .res-chip .val { font-size: 14px; }
  /* подпись под числом убрана вместо ужатия до 9.5px (нечитаемо): иконка +
     title-подсказка (app.js) уже называют ресурс, а чипы стали уже — раньше
     баланс рублей не влезал в scrollWidth ни на одной телефонной ширине */
  .res-chip .lbl { display: none; }

  /* ---------- иконки-кнопки топбара (звук/уведомления/выйти) — полный
     размер тач-цели, на десктопе .icon-btn остаётся компактным 38px ---------- */
  .icon-btn { width: var(--tap-min); height: var(--tap-min); font-size: 17px; }

  /* ---------- навигация: нижняя панель, 5 приоритетных экранов + «Ещё» ----------
     10 вкладок физически не помещаются по --tap-min в один ряд ни на одной
     телефонной ширине (10 × 44 = 440 > 360 CSS px) — ни сжатие подписи, ни
     иконки-без-текста арифметику не меняют. Решение: app.js на ≤700px рендерит
     5 приоритетных экранов вкладками (Схрон/Верстак/Склад/Рейды/Рынок) + 6-ю
     вкладку «Ещё» (renderNav), открывающую лист с остальными 5 (openMoreSheet,
     .more-sheet-row ниже) — тач-цель гарантированно ≥44px при любом составе
     экранов, без прокрутки самого частого элемента управления в игре. */
  #nav {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 150;
    background: var(--panel-solid); border-top: 1px solid var(--edge); border-bottom: none;
    padding-bottom: env(safe-area-inset-bottom, 0px); overflow-x: visible;
  }
  .nav-tab {
    flex: 1 1 0; min-width: 0; height: 56px; padding: 6px 2px 5px;
    flex-direction: column; gap: 3px; justify-content: center;
    font-size: var(--font-min); letter-spacing: 0.5px; position: relative;
    border-bottom: none; border-top: 2px solid transparent;
  }
  .nav-tab.active { border-top-color: var(--gold-strong); border-bottom-color: transparent; }
  .nav-tab .fa-solid { font-size: 17px; }
  .nav-tab span:not(.badge) { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .nav-tab .badge { position: absolute; top: 4px; right: 8px; min-width: 20px; height: 20px; font-size: var(--font-min); padding: 0 4px; }
  /* нижний бар — поверх контента, поэтому вся страница получает запас снизу */
  #app { padding-bottom: calc(64px + env(safe-area-inset-bottom, 0px)); }

  /* ---------- лист «Ещё»: остальные экраны строками ≥44px (openMoreSheet) ---------- */
  .more-sheet-row {
    display: flex; align-items: center; gap: 12px; width: 100%;
    padding: 12px 14px; min-height: var(--tap-min);
    background: none; border: none; border-bottom: 1px solid var(--edge-soft);
    color: var(--text-2); font-family: inherit; font-size: 14px;
    letter-spacing: 0.6px; text-transform: uppercase; text-align: left;
    cursor: pointer; transition: background 0.12s ease, color 0.12s ease;
  }
  .more-sheet-row:last-child { border-bottom: none; }
  .more-sheet-row:hover { background: rgba(176, 137, 74, 0.15); color: var(--text); }
  .more-sheet-row.active { color: var(--gold-strong); background: rgba(209, 168, 94, 0.12); }
  .more-sheet-row .fa-solid { width: 22px; text-align: center; font-size: 16px; color: var(--gold-strong); flex: none; }
  .more-sheet-row .badge {
    margin-left: auto; flex: none; min-width: 20px; height: 20px; padding: 0 4px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--gold-strong); color: var(--screen-top); font-size: var(--font-min);
  }

  /* ---------- hit-target --tap-min, поля ввода без зума iOS ---------- */
  .btn { min-height: var(--tap-min); padding: 0 14px; white-space: normal; text-align: center; line-height: 1.3; }
  /* .btn.small раньше оставался 38px — на 6px ниже порога на КАЖДОЙ кнопке
     этим классом (СНЯТЬ/ЗАБРАТЬ/УСКОРИТЬ и т.п., не только плотные плашки).
     min-width — отдельно: у степперов количества в магазине (−/+) и похожих
     однознаковых кнопок ширина 30px проваливала И вторую ось; для обычных
     текстовых кнопок min-width ничего не меняет (они и так шире). Группы
     таких кнопок в экранах уже верстают с flex-wrap:wrap (проверено) — рост
     до --tap-min просто переносит лишние на следующую строку, без обрезки. */
  .btn.small { min-height: var(--tap-min); min-width: var(--tap-min); padding: 0 12px; font-size: var(--font-min); }
  .row-item, .subtab { min-height: var(--tap-min); }
  .info-btn { min-width: var(--tap-min); min-height: var(--tap-min); padding: 0; display: inline-flex; align-items: center; justify-content: center; }
  .login-body input { height: var(--tap-min); font-size: 16px; }
  .panel-hdr { min-height: var(--tap-min); }
  .farm-slot { width: var(--tap-min); height: var(--tap-min); }

  /* ---------- текст каркаса — не мельче --font-min ни на одном экране ---------- */
  #statusbar { font-size: var(--font-min); flex-wrap: wrap; gap: 4px 12px; }
  .panel-hdr .sub { font-size: var(--font-min); max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .req-row { font-size: var(--font-min); }
  .event-log-row, .missing-scav-row { font-size: var(--font-min); }
  .hp-warn { font-size: var(--font-min); }
  .route-status-badge { font-size: var(--font-min); }
  .item-cell .qty { font-size: var(--font-min); }
  /* .route-log-tag/.route-log-txt/.route-log-num были мельче 13px и на
     десктопе, и на телефоне (11-12.5px) — подняты прямо в базовых правилах
     выше (route-log-num заодно получил колонку 20px вместо 16px, иначе
     двузначный номер узла обрезался бы), отдельный оверрайд тут не нужен */
  /* НЕ бампим: .proc-chip/.proc-chip-label и .route-loot-icon .qty
     (иконки-глиф в фиксированных чипах 34px/26px, не проза) — тот же
     осознанный компромисс, что у .lvl-pips/.farm-slot */

  /* ---------- модалки почти на весь экран ---------- */
  .modal-panel, .login-panel { width: 96vw; }
  /* Нижний бар навигации накрывает модалку снизу: оставляем ему место,
     иначе кнопка действия жмётся к самому краю и попадает под палец. */
  .modal-panel { max-height: calc(92vh - 64px); }

  /* слот крафта: кнопка с длинной подписью ("НЕТ МЕСТА НА СТЕЛЛАЖАХ",
     "УСКОРИТЬ · 358 782 ₽") в одном ряду с иконкой+названием на узком
     экране отжимала колонку названия до считанных px — текст "Набор
     медикаментов"/"ГОТОВО" вылезал из своей колонки и наезжал на кнопку.
     На телефоне кнопка уходит на отдельную полноширинную строку. */
  .craft-slot-card { flex-wrap: wrap; }
  .craft-slot-card > .btn { flex: 1 1 100%; }

  /* ---------- сетки/карточки ---------- */
  .module-card { min-height: 196px; }
  .module-card .mod-icon { font-size: 28px; padding: 10px 0; }
  /* форма отправки на вылазку: карточки локаций (описание + % выживания)
     в одну колонку раньше общей сетки .cols-2 — иначе текст в кашу */
  .form-grid { grid-template-columns: 1fr; }
  /* стеллажи: ячейки чуть мельче, чтобы в строку влезало больше */
  .item-grid { grid-template-columns: repeat(auto-fill, minmax(58px, 1fr)); }
  .item-grid .item-cell img { width: 42px; height: 42px; }

  /* ---------- тосты не должны прятаться под нижнюю навигацию ---------- */
  #toast-root { left: 10px; right: 10px; bottom: calc(70px + env(safe-area-inset-bottom, 0px)); }
  .toast { width: auto; max-width: none; min-width: 0; }

  /* ---------- плашка тега в чате: под топбар, крестик до --tap-min ---------- */
  #chatnote-root { top: 8px; width: calc(100vw - 16px); }
  .chatnote-plaque { padding-right: var(--tap-min); }
  .chatnote-plaque-close { width: var(--tap-min); height: var(--tap-min); }

  /* ---------- вылазка: журнал уходит под карту (телефон) ---------- */
  .route-grid { grid-template-columns: 1fr; }
  .route-log-list { max-height: 220px; }
}

@media (max-width: 480px) {
  .cols-4, .cols-3, .cols-2 { grid-template-columns: 1fr; }
  .fork-choices { grid-template-columns: 1fr; }
}


/* ---------- живая линия маршрута вылазки ----------
   Выбранная ветка не просто подсвечена: пунктир ползёт вперёд, и сразу видно
   направление движения. Невыбранная гаснет, чтобы не спорить за внимание.
   Анимацию глушим при prefers-reduced-motion — это украшение, не смысл. */
.route-line-active {
  stroke: var(--gold-strong);
  stroke-dasharray: 3 2.2;
  opacity: 0.9;
}
.route-line-dim { opacity: 0.28; }
@media (prefers-reduced-motion: no-preference) {
  .route-line-active { animation: route-crawl 1.4s linear infinite; }
}
@keyframes route-crawl { to { stroke-dashoffset: -5.2; } }

/* маркер скава: мягкий пульс, чтобы глаз находил его на схеме сразу */
@media (prefers-reduced-motion: no-preference) {
  .route-marker { animation: marker-pulse 2s ease-in-out infinite; }
}
@keyframes marker-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}


/* Кнопка закрытия таймера жетонами: отличается от золотого рублёвого
   ускорения синим — две разные валюты не должны выглядеть одинаково. */
.btn-token {
  background: rgba(74, 100, 120, 0.22);
  color: #8FB3CC;
  border-top-color: rgba(74, 100, 120, 0.45);
}
.btn-token:hover { background: rgba(74, 100, 120, 0.34); color: #A9CBE2; }


/* --- карточки стычек (журнал схваток и набегов) -------------------------
   Строка «АТАКА · Ник · победа · +1 240 ₽» не отвечала ни на один реальный
   вопрос: сколько было сил у сторон, куда прилетело, что именно унесли.
   Карточка раскладывает бой на слагаемые, из которых он и состоял. */
.battle-log { display: flex; flex-direction: column; gap: 1px; background: var(--edge-soft); }
.battle-card {
  background: var(--panel); padding: 11px 13px 12px;
  display: flex; flex-direction: column; gap: 7px;
  border-left: 2px solid var(--edge);
}
.battle-card.win { border-left-color: var(--green, #7d9153); }
.battle-card.lose { border-left-color: var(--red, #a33a32); }
.battle-card.scout { border-left-color: var(--edge); }
.bc-head { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.bc-verdict {
  font-family: var(--display); font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase;
}
.battle-card.win .bc-verdict { color: var(--green, #7d9153); }
.battle-card.lose .bc-verdict { color: var(--red, #a33a32); }
.battle-card.scout .bc-verdict { color: var(--text-2); }
.bc-role { font-size: 13px; color: var(--text-2); }
.bc-ago { margin-left: auto; font-size: 13px; color: var(--muted, #6c685e); white-space: nowrap; }
.bc-vs { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 13px; }
.bc-side { color: var(--text); font-variant-numeric: tabular-nums; }
.bc-vs-mark { color: var(--muted, #6c685e); font-size: 13px; }
.bc-gains { display: flex; flex-wrap: wrap; gap: 8px; }
.bc-gain {
  font-size: 13px; padding: 2px 8px; border: 1px solid var(--edge);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.bc-gain.up { color: var(--green, #7d9153); border-color: rgba(125, 145, 83, 0.45); }
.bc-gain.down { color: var(--red, #a33a32); border-color: rgba(163, 58, 50, 0.45); }
.bc-gain.flat { color: var(--muted, #6c685e); }
.bc-items { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; }
.bc-more { font-size: 13px; color: var(--text-2); }
.bc-hits { font-size: 13px; color: var(--text-2); }
.bc-hits.trap { color: var(--gold); }
.bc-note { font-size: 13px; color: var(--muted, #6c685e); }

@media (max-width: 700px) {
  .battle-card { padding: 12px 12px 13px; }
  .bc-ago { margin-left: 0; width: 100%; }
}


/* Метка «лежит в тайнике» на ячейке склада. Тайник — не отдельный склад,
   а флажок поверх стеллажей, поэтому и метка живёт на самой ячейке. */
.item-cell.hidden-item { box-shadow: inset 0 0 0 1px var(--gold); }
.item-cell .hide-mark {
  position: absolute; top: 1px; left: 2px; font-size: 12px; line-height: 1;
  color: var(--gold); pointer-events: none;
}


/* Пометка предметов, делящих одну иконку (шесть карт районов, две коробки):
   в сетке подписей нет, и без метки это визуально один и тот же предмет. */
.item-cell .dup-tag {
  position: absolute; top: 1px; right: 2px;
  font-family: var(--display); font-size: 10.5px; letter-spacing: 0.04em;
  color: var(--gold); background: rgba(10, 10, 12, 0.82); padding: 0 3px;
  pointer-events: none;
}


/* Атрибут hidden обязан скрывать элемент всегда. Без этого правила любой
   класс со своим display (.btn -> inline-flex) молча перебивает его, и
   «скрытый» элемент остаётся на экране пустой полосой. */
[hidden] { display: none !important; }


/* Предмет, выставленный на барахолку: физически на полке, но тронуть нельзя —
   лот может уйти в любой момент. Без метки игрок видит привычное количество,
   жмёт «продать» и получает отказ сервера, который выглядит как враньё. */
.item-cell.listed-item { box-shadow: inset 0 0 0 1px var(--gold-strong, #c9a227); opacity: 0.85; }
.item-cell .listed-mark {
  position: absolute; bottom: 1px; left: 2px; font-size: 10px; line-height: 1;
  color: var(--gold-strong, #c9a227); pointer-events: none;
}


/* Снаряжение, взятое в поле: иконками. Текстом это занимало по три строки на
   предмет и всё равно не читалось — «что на мне» смотрят взглядом. */
.gear-icons { display: flex; flex-wrap: wrap; gap: 6px; }
.gear-icon {
  width: 38px; height: 38px; border: 1px solid var(--edge); background: #0F0F11;
  display: grid; place-items: center; position: relative; cursor: help;
}
.gear-icon img { width: 30px; height: 30px; object-fit: contain; }
.gear-icon.med { box-shadow: inset 0 -2px 0 var(--red, #a33a32); }
.gear-icon.food { box-shadow: inset 0 -2px 0 var(--green, #7d9153); }
.gear-icon.gun { box-shadow: inset 0 -2px 0 var(--gold, #c9a227); }
/* Боекомплект — своя полоска, но родственная стволу: патроны и оружие едут в
   поле одним комплектом, и в отчёте это должно читаться как пара, а не как
   два несвязанных предмета. */
.gear-icon.ammo { box-shadow: inset 0 -2px 0 var(--gold-dim, #8A6C3A); }


/* Контекстная строка в нашем тултипе (что предмет даёт именно здесь).
   Раньше это вешали атрибутом title, и поверх нашего окна вылезал системный. */
#tooltip .t-extra {
  color: var(--gold-hi, #e0c068); font-size: 13px; margin-top: 4px;
  border-top: 1px solid var(--edge-soft); padding-top: 4px;
}

/* =====================================================================
   СХВАТКИ (screens/pvp.js) — боевая система v2: типизированные слоты
   снаряжения + разбор боя по раундам вместо мешка вещей и одного числа.
   Классы только этого экрана, префикс pvp- — общие .row-item/.gear-icons/
   .small/.muted/.gold/.green/.red переиспользуются как есть.
   ===================================================================== */

/* Итог по всем слотам разом (атака/защита/инициатива/уклонение/лечение) —
   что реально понесёшь в бой ПРЯМО СЕЙЧАС, одной строкой над слотами. */
.pvp-gear-summary { display: flex; flex-wrap: wrap; gap: 16px; padding-bottom: 4px; }
.pvp-gear-stat { display: flex; flex-direction: column; gap: 2px; min-width: 64px; }
.pvp-gear-stat > div:last-child { font-size: 16px; font-variant-numeric: tabular-nums; }

/* Один слот снаряжения: закрытый — только объяснение чем открывается;
   открытый — что надето (или почему пусто) и список замены. Разделитель
   между слотами — только начиная со второго (сосед сверху уже даёт край). */
.pvp-slot { display: flex; flex-direction: column; gap: 6px; }
.pvp-slot + .pvp-slot { padding-top: 10px; border-top: 1px solid var(--edge-soft); }

/* Панель снаряжения схватки: четыре карточки разной высоты. Колоночный поток
   вместо grid — карточки перетекают и заполняют колонки целиком, а не
   выстраиваются в ряды по самой высокой. Разделитель между соседями в потоке
   снимаем: в колонках «предыдущий сосед» может оказаться в другой колонке, и
   верхняя карточка получала бы черту ниоткуда. */
.pvp-gear-grid { column-width: 280px; column-gap: 10px; }
.pvp-gear-grid .pvp-slot {
  break-inside: avoid; -webkit-column-break-inside: avoid;
  display: block; margin: 0 0 12px;
  padding: 10px 12px; border: 1px solid var(--edge);
}
.pvp-gear-grid .pvp-slot + .pvp-slot { padding-top: 10px; border-top: 1px solid var(--edge); }
/* display:block вместо flex убирает gap — интервалы задаём сами, иначе
   заголовок слота слипается с первой строкой. */
.pvp-gear-grid .pvp-slot > * + * { margin-top: 6px; }
.pvp-slot-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
/* font-size: var(--font-min) — ниже 13px кегль запрещён каноном везде, не
   только на телефоне (см. корневой комментарий про --font-min в game.css). */
.pvp-slot-label { font-size: var(--font-min); letter-spacing: 0.6px; text-transform: uppercase; color: var(--text-2); }
.pvp-slot-locked { padding: 2px 0 4px; line-height: 1.45; }
.pvp-slot-empty { padding: 2px 0 4px; line-height: 1.45; }
.pvp-slot-alt-label { font-size: var(--font-min); letter-spacing: 0.5px; text-transform: uppercase; margin-top: 2px; }

/* Строки слота переиспользуют .row-item (список-строка канона), только уже
   без внешнего списка-панели — сами по себе внутри блока слота. */
.pvp-slot-row { padding: 7px 8px; }
.pvp-slot-row:last-child { border-bottom: none; }
/* Надетая вещь — не кликабельна сама по себе (снять можно только кнопкой),
   поэтому своя подсветка вместо наведения, которое обещало бы клик по строке. */
.pvp-slot-current {
  cursor: default; border-left: 2px solid var(--gold-strong); background: rgba(176, 137, 74, 0.1);
}
.pvp-slot-current:hover { background: rgba(176, 137, 74, 0.1); }
.pvp-slot-qty { flex: none; font-variant-numeric: tabular-nums; }

/* ---------- журнал боёв: карточка + разбор по раундам ---------- */
.pvp-fight-log { display: flex; flex-direction: column; gap: 1px; background: var(--edge-soft); }
.pvp-fight-card {
  background: var(--panel); padding: 11px 13px 12px;
  display: flex; flex-direction: column; gap: 7px;
  border-left: 2px solid var(--edge);
}
.pvp-fight-card.win { border-left-color: var(--green); }
.pvp-fight-card.lose { border-left-color: var(--red); }
.pvp-fight-head { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
.pvp-fight-verdict { font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase; }
.pvp-fight-ago { margin-left: auto; white-space: nowrap; }
.pvp-fight-vs { color: var(--text-2); font-variant-numeric: tabular-nums; }
.pvp-fight-gains { display: flex; flex-wrap: wrap; gap: 8px; font-variant-numeric: tabular-nums; }
.pvp-loot-row { display: flex; flex-direction: column; gap: 5px; }
.pvp-fight-toggle { align-self: flex-start; }

/* Раунды: раскрываются по кнопке — двадцать боёв по пять раундов каждый
   иначе превращают журнал в стену текста, которую никто не читает целиком. */
.pvp-fight-rounds { padding-top: 4px; border-top: 1px solid var(--edge-soft); }
.pvp-rounds { display: flex; flex-direction: column; gap: 8px; }
.pvp-round { display: flex; flex-direction: column; gap: 2px; }
.pvp-round-n { letter-spacing: 0.5px; text-transform: uppercase; }
.pvp-round-line { line-height: 1.5; }

@media (max-width: 700px) {
  .pvp-fight-ago { margin-left: 0; width: 100%; }
}

/* ---------- чат «Схрона» (screens/chat.js) ----------
   Прямо в game.css, отдельного chat.css нет — тот же приём, что уже есть у
   pvp- классов чуть выше: экран мелкий, заводить лишний link в index.html
   ради десятка правил не стоит. Кегль нигде не мельче --font-min (13px) —
   жёсткий порог канона, держим его даже у меты сообщения и счётчика символов. */

.chat-online {
  display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 12px;
  margin-bottom: 10px; background: var(--panel-alt); border: 1px solid var(--edge-soft);
  font-size: 13px; letter-spacing: 0.4px; color: var(--text-2); width: fit-content;
}
.chat-online-dot {
  width: 8px; height: 8px; flex: none; background: var(--green);
  box-shadow: 0 0 6px rgba(92, 143, 90, 0.7);
}
@media (prefers-reduced-motion: no-preference) { .chat-online-dot { animation: marker-pulse 2s ease-in-out infinite; } }

/* Лента: фикс-высота + свой скролл (тот же приём, что .route-log-list) —
   иначе длинный чат растягивает экран сильнее, чем сама панель ввода под ним. */
.chat-list {
  display: flex; flex-direction: column; gap: 2px;
  height: 46vh; min-height: 260px; max-height: 520px;
  overflow-y: auto; -webkit-overflow-scrolling: touch;
  padding: 4px 2px; margin-bottom: 10px;
  background: #0C0C0E; border: 1px solid var(--edge-soft);
}
.chat-list::-webkit-scrollbar { width: 6px; }
.chat-list::-webkit-scrollbar-track { background: transparent; }
.chat-list::-webkit-scrollbar-thumb { background: #33333a; border: 0; }
.chat-list::-webkit-scrollbar-thumb:hover { background: #45454e; }
.chat-empty { padding: 14px 10px; color: var(--muted); font-size: 13px; }

.chat-row { padding: 6px 10px; border-bottom: 1px solid var(--edge-soft); }
.chat-row:last-child { border-bottom: none; }
/* Своё сообщение — золотая полоса слева, тот же язык, что у .pvp-slot-current
   и врезки-пояснения в tokens.css: "это про тебя" всегда левой полосой. */
.chat-row.own { border-left: 2px solid var(--gold-strong); background: rgba(209, 168, 94, 0.06); }
.chat-meta { display: flex; align-items: baseline; gap: 8px; margin-bottom: 2px; }
.chat-name { font-size: 13px; letter-spacing: 0.3px; color: var(--text); }
.chat-time { font-size: 13px; color: var(--muted); margin-left: auto; white-space: nowrap; }
.chat-text { font-size: 14px; line-height: 1.4; color: var(--text-2); word-break: break-word; white-space: pre-wrap; }
.chat-row.own .chat-text { color: var(--text); }

.chat-compose { display: flex; flex-direction: column; gap: 6px; }
.chat-input {
  width: 100%; min-height: 60px; padding: 9px 10px; resize: vertical;
  background: #0F0F11; color: var(--text); border: 1px solid var(--edge-soft);
  font-family: inherit; font-size: 14px; line-height: 1.4;
}
.chat-input:focus { outline: none; border-color: var(--gold); }
.chat-compose-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.chat-counter { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.chat-counter-warn { color: var(--gold-strong); }
.chat-compose-err { font-size: 13px; color: var(--red); line-height: 1.4; }

/* ---------- соцфичи: раскладка «лента + список в эфире» ----------
   Ростер — узкая колонка справа (только чтобы кликнуть и тегнуть, не витрина
   с деталями игрока — спека владельца), на телефоне уезжает под ленту. */
.chat-layout { display: grid; grid-template-columns: minmax(0, 1fr) 220px; gap: 12px; align-items: start; }
.chat-main { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.chat-main .chat-list { margin-bottom: 0; }

.chat-roster { background: var(--panel-alt); border: 1px solid var(--edge-soft); display: flex; flex-direction: column; min-width: 0; }
.chat-roster-hdr {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 10px; font-size: 13px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); border-bottom: 1px solid var(--edge-soft);
}
.chat-roster-count { color: var(--gold-strong); font-variant-numeric: tabular-nums; }
.chat-roster-list { display: flex; flex-direction: column; overflow-y: auto; max-height: 46vh; min-height: 120px; }
.chat-roster-row {
  display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 1px;
  width: 100%; min-height: var(--tap-min); padding: 6px 10px;
  background: none; border: 0; border-bottom: 1px solid var(--edge-soft);
  color: var(--text); font-family: inherit; text-align: left; cursor: pointer;
}
.chat-roster-row:last-child { border-bottom: none; }
.chat-roster-row:hover { background: rgba(209, 168, 94, 0.08); }
.chat-roster-name { font-size: 13px; color: var(--text); }
.chat-roster-meta { font-size: 13px; color: var(--muted); }
.chat-roster-empty { padding: 14px 10px; color: var(--muted); font-size: 13px; line-height: 1.4; }

/* Подсветка "@ник" внутри чужого текста — см. messageTextNodes(). Своя
   подсветка ярче: "@меня_тегнули" не должно теряться среди обычных тегов. */
.chat-mention { color: var(--gold-strong); background: rgba(209, 168, 94, 0.14); padding: 0 2px; font-weight: 600; }
.chat-mention.mine { color: var(--screen-top); background: var(--gold-strong); }

/* Инструменты компоуза: кнопка «приложить лот» + чип выбранного лота */
.chat-compose-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.chat-offer-chip {
  display: flex; align-items: center; gap: 8px; padding: 4px 8px; min-height: var(--tap-min);
  background: var(--panel-alt); border: 1px solid var(--gold); flex: 1 1 220px; min-width: 0;
}
.chat-offer-chip-ico { width: 26px; height: 26px; object-fit: contain; flex: none; }
.chat-offer-chip-name {
  font-size: 13px; color: var(--text); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; flex: 1 1 auto; min-width: 0;
}
.chat-offer-chip-remove {
  width: 26px; height: 26px; flex: none; display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--edge-soft); color: var(--muted);
  cursor: pointer; font-size: 13px;
}
.chat-offer-chip-remove:hover { color: var(--text); border-color: var(--gold); }

/* Карточка приложенного лота в ленте (см. offerCard() в chat.js) */
.chat-offer-card {
  display: flex; align-items: center; gap: 10px; margin-top: 6px; padding: 8px 10px;
  background: var(--panel-alt); border: 1px solid var(--gold);
}
.chat-offer-card.closed { border-color: var(--edge-soft); opacity: 0.75; }
.chat-offer-ico { width: 34px; height: 34px; object-fit: contain; flex: none; }
.chat-offer-info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.chat-offer-name { font-size: 14px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-offer-total { font-size: 14px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.chat-offer-closed-tag {
  font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
  border: 1px solid var(--edge-soft); padding: 3px 6px; white-space: nowrap; flex: none;
}

/* Модалка выбора своего лота для приложения (openOfferPicker()) */
.chat-offer-pick {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 9px 12px; min-height: var(--tap-min);
  background: none; border: 0; border-bottom: 1px solid var(--edge-soft); color: var(--text);
  font-family: inherit; text-align: left; cursor: pointer;
}
.chat-offer-pick:last-child { border-bottom: none; }
.chat-offer-pick:hover { background: rgba(209, 168, 94, 0.08); }
.chat-offer-pick-ico { width: 32px; height: 32px; object-fit: contain; flex: none; }
.chat-offer-pick-info { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.chat-offer-pick-name { font-size: 14px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- соцфичи ВТОРОЙ волны: ответ, самоудаление, жалоба, системные строки ---------- */

/* Кнопки строки (ответить/удалить/пожаловаться) — всегда видимые мелкие
   иконки, НЕ по hover: половина игроков заходит с телефона, там ховера нет. */
.chat-row-actions { display: flex; gap: 4px; margin-top: 4px; }
.chat-row-action-btn {
  display: flex; align-items: center; justify-content: center; gap: 4px;
  height: 22px; padding: 0 6px; background: transparent; border: 1px solid var(--edge-soft);
  color: var(--muted); font-family: inherit; font-size: 12px; cursor: pointer;
}
.chat-row-action-btn:hover { color: var(--text); border-color: var(--gold); }
.chat-row-action-btn.danger:hover { color: var(--red); border-color: var(--red); }

/* На десктопе эти кнопки узкие намеренно — они не должны отвлекать от текста.
   На телефоне порог тач-цели ЖЁСТКИЙ (44px, см. --tap-min): 22 пикселя высоты
   означают, что «ответить» и «удалить» стоят вплотную и промахнуться по ним
   проще, чем попасть. Растим только высоту зоны, вид кнопки не меняем —
   рамка остаётся тонкой, увеличивается область нажатия. */
@media (max-width: 700px) {
  .chat-row-actions { gap: 8px; margin-top: 6px; }
  .chat-row-action-btn {
    min-height: var(--tap-min);
    min-width: var(--tap-min);
    padding: 0 10px;
    font-size: var(--font-min);
  }
}

/* Цитата над текстом ответа — клик прокручивает к оригиналу в ленте */
.chat-quote {
  display: block; width: 100%; text-align: left; margin-bottom: 3px; padding: 3px 6px;
  background: rgba(209, 168, 94, 0.06); border-left: 2px solid var(--gold);
  font-family: inherit; cursor: pointer;
}
.chat-quote:hover { background: rgba(209, 168, 94, 0.12); }
.chat-quote.deleted { border-left-color: var(--edge-soft); cursor: default; }
.chat-quote-name { font-size: 13px; color: var(--gold-strong); }
.chat-quote-text {
  font-size: 13px; color: var(--muted); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap;
}
/* Подсветка сообщения, к которому только что прокрутили кликом по цитате */
@keyframes chat-row-flash { from { background: rgba(209, 168, 94, 0.22); } to { background: transparent; } }
.chat-row-flash { animation: chat-row-flash 1.1s ease-out; }
@media (prefers-reduced-motion: reduce) { .chat-row-flash { animation: none; } }

/* Чип "отвечаю на..." в компоузе — тот же язык, что .chat-offer-chip */
.chat-reply-chip {
  display: flex; align-items: center; gap: 8px; padding: 4px 8px; min-height: var(--tap-min);
  background: var(--panel-alt); border: 1px solid var(--gold); flex: 1 1 220px; min-width: 0;
}
.chat-reply-chip-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.chat-reply-chip-name { font-size: 13px; color: var(--gold-strong); }
.chat-reply-chip-text {
  font-size: 13px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-reply-chip-remove {
  width: 26px; height: 26px; flex: none; display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--edge-soft); color: var(--muted);
  cursor: pointer; font-size: 13px;
}
.chat-reply-chip-remove:hover { color: var(--text); border-color: var(--gold); }

/* Системная строка детектора (см. докстринг idle_chat.py) — по центру,
   приглушенно, без "своей"/"чужой" окраски и без кнопок строки. */
.chat-row.system {
  display: flex; justify-content: center; text-align: center; border-left: none; background: none;
}
.chat-row.system .chat-text {
  font-size: 13px; color: var(--muted); font-style: italic; white-space: normal;
}

/* Модалка выбора причины жалобы — список кнопок, тот же язык, что .chat-offer-pick */
.chat-report-reason {
  display: block; width: 100%; padding: 10px 12px; min-height: var(--tap-min);
  background: none; border: 0; border-bottom: 1px solid var(--edge-soft); color: var(--text);
  font-family: inherit; font-size: 14px; text-align: left; cursor: pointer;
}
.chat-report-reason:last-child { border-bottom: none; }
.chat-report-reason:hover { background: rgba(209, 168, 94, 0.08); }

/* ---------- заглушка «нет Радиостола» ---------- */
.chat-gate {
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  padding: 20px 4px 6px;
}
.chat-gate .fa-solid { font-size: 30px; color: var(--gold-strong); }
.chat-gate-title { font-size: 15px; letter-spacing: 1px; color: var(--text); }
.chat-gate-text { font-size: 13px; line-height: 1.5; color: var(--text-2); max-width: 480px; }

@media (max-width: 700px) {
  /* телефон: список короче (панель ввода не должна улезать за нижний бар),
     textarea без ручного resize — на тач-экране за уголок никто не тянет */
  .chat-list { height: 42vh; min-height: 200px; }
  .chat-input { resize: none; font-size: 16px; } /* 16px — держит iOS от авто-зума на фокусе поля */
  /* Ростер — в одну колонку под лентой (DOM-порядок уже такой: .chat-main
     идёт первым), своя прокрутка держится компактной, чтобы не съесть экран */
  .chat-layout { grid-template-columns: 1fr; }
  .chat-roster-list { max-height: 160px; min-height: 90px; }
}

/* ---------- «Награда дня» (screens/daily.js) ----------
   Отдельного css/daily.css не заводим (пришлось бы трогать index.html,
   чужая территория этого захода) — всё живёт тут за одним префиксом.

   --font-min (13px) — порог ЖЁСТКИЙ на любом экране, не только на телефоне
   (см. комментарий у :root выше) — ни один текстовый класс здесь не мельче.
   Иконки (fa-solid, картинки) под порог не подпадают — это не проза. */
.daily-hero { display: flex; flex-direction: column; gap: 12px; padding: 14px; }
.daily-hero-main { display: flex; align-items: center; gap: 14px; }
.daily-hero-icon { font-size: 38px; width: 46px; text-align: center; color: var(--gold-strong); flex: none; }
.daily-hero-num { font-size: 36px; line-height: 1; color: var(--gold-strong); font-variant-numeric: tabular-nums; }
.daily-hero-lbl { font-size: var(--font-min); letter-spacing: 1px; color: var(--muted); text-transform: uppercase; margin-top: 2px; }
.daily-cta { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.daily-note { font-size: var(--font-min); line-height: 1.55; color: var(--text-2); }
.daily-body { padding: 12px; display: flex; flex-direction: column; gap: 10px; }

/* сетка календаря: auto-fit сама решает, сколько карточек влезет в строку —
   от 7 в ряд на десктопе до 3-4 на телефоне, без горизонтальной прокрутки.
   min-height, не height: карточка дня 7 несёт больше чипов наград и на
   13px-тексте вырастает выше соседей — сетка это переживает, высота строки
   считается по самой высокой ячейке, ничего не обрезается. */
.daily-calendar { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); gap: 8px; padding: 12px; }
.daily-day {
  position: relative; display: flex; flex-direction: column; gap: 8px;
  padding: 10px 8px; min-height: 118px;
  background: #0F0F11; border: 1px solid var(--edge-soft);
}
.daily-day.today { border-color: var(--gold-strong); background: rgba(209, 168, 94, 0.10); }
.daily-day.passed { opacity: 0.55; }
.daily-day.jackpot { border-color: var(--gold); box-shadow: inset 0 0 0 1px var(--gold); }
.daily-day-num { font-size: var(--font-min); letter-spacing: 0.8px; color: var(--muted); text-transform: uppercase; }
.daily-day.today .daily-day-num { color: var(--gold-strong); }
/* Значок «лучший день» — только иконка (звезда), без подписи: словами
   «ЛУЧШИЙ ДЕНЬ» на 13px не влезли бы в угловую плашку 90px-карточки без
   переноса. Тег сам по себе декоративный поверх золотой рамки .jackpot —
   название читается в тултипе (title). */
.daily-jackpot-tag {
  position: absolute; top: -6px; right: -6px; width: 20px; height: 20px;
  display: flex; align-items: center; justify-content: center;
  background: var(--gold-strong); color: var(--screen-top); font-size: 11px;
}
.daily-day-reward { display: flex; flex-wrap: wrap; gap: 4px; flex: 1; align-content: flex-start; }
.daily-chip {
  display: inline-flex; align-items: center; gap: 4px;
  background: #151517; border: 1px solid var(--edge-soft);
  padding: 2px 6px; font-size: var(--font-min); color: var(--text-2); cursor: default;
}
.daily-chip img { width: 15px; height: 15px; }
.daily-day-state {
  display: flex; align-items: center; gap: 5px; margin-top: auto;
  font-size: var(--font-min); letter-spacing: 0.5px; text-transform: uppercase; color: var(--muted);
}
.daily-day-state .fa-solid { font-size: var(--font-min); }
.daily-day.today .daily-day-state { color: var(--gold-strong); }

/* строка награды крупными значками — итог клейма, превью «если пропустишь» */
.daily-reward-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

@media (max-width: 700px) {
  .daily-calendar { grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); gap: 6px; padding: var(--mobile-pad); }
  .daily-day { min-height: 104px; padding: 8px 6px; }
  .daily-hero { padding: var(--mobile-pad); gap: 10px; }
  .daily-hero-num { font-size: 30px; }
  .daily-hero-icon { font-size: 32px; width: 38px; }
  .daily-cta { align-items: stretch; }
}

/* ---------- карточка игрока (публичный профиль, screens/profile.js) ---------- */
.prof-head { display: flex; align-items: center; gap: 8px; }
.prof-name { font-size: 18px; font-weight: 600; letter-spacing: 0.02em; }
/* Точка "в эфире" — тот же приём и тот же цвет, что у #status-dot в топбаре
   (app.js::renderTopbar), только локальный для карточки: связи между ними
   на уровне CSS нет, это два независимых индикатора одного смысла. */
.prof-online-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--muted); }
.prof-online-dot.on { background: var(--green); box-shadow: 0 0 6px var(--green); }

.prof-stats { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 4px; }
.prof-stat { padding: 10px 8px; text-align: center; background: #0F0F11; border: 1px solid var(--edge-soft); }
.prof-stat-val { font-size: 17px; font-variant-numeric: tabular-nums; margin-bottom: 2px; }

.prof-section-hdr {
  font-size: 11.5px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); margin: 14px 0 6px;
}
/* Раньше тут была .prof-wall-grid — иконки КАЖДОГО ствола стены. Убрана: список
   id восстанавливает точный wall_power (idle_combat.power()) в обход
   бакетирования боевой силы — см. докстринг idle_social.py, пункт 5. Карточка
   показывает только счётчик в заголовке .prof-section-hdr ("СТЕНА · N ИЗ M"). */

.prof-offers { display: flex; flex-direction: column; gap: 6px; }
.prof-offer-row { display: flex; align-items: center; gap: 10px; padding: 8px; background: #0F0F11; border: 1px solid var(--edge-soft); }
.prof-offer-row .item-cell { width: 40px; height: 40px; cursor: default; }
.prof-offer-row .item-cell img { width: 28px; height: 28px; }
.prof-offer-info { flex: 1; min-width: 0; font-size: 12.5px; }

.prof-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--edge-soft);
}

@media (max-width: 700px) {
  .prof-foot { flex-direction: column; align-items: stretch; text-align: center; }
}

/* Галочка «повторять маршрут» в форме отправки. Вся строка — тач-цель:
   попасть пальцем в 13-пиксельный чекбокс на телефоне невозможно. */
.exp-repeat {
  display: flex; align-items: center; gap: 8px;
  min-height: var(--tap-min); cursor: pointer; color: var(--text-2);
}
.exp-repeat input { width: 18px; height: 18px; accent-color: var(--gold-strong); }

/* Ставка боя — ряд кнопок над слотами снаряжения. Тач-цели штатные (.btn уже
   ≥44px на телефоне), тут только раскладка. */
.pvp-stance { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.pvp-stance-row { display: flex; flex-wrap: wrap; gap: 6px; }

/* План боя над разбором по раундам: чья ставка и её вес в итоговых числах. */
.fight-plan {
  display: flex; flex-direction: column; gap: 4px;
  margin: 10px 16px 0; padding: 8px 10px;
  background: var(--panel-solid); border-left: 2px solid var(--gold-dim);
}
.fight-plan-row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.fight-plan-row > *:first-child { min-width: 92px; }


/* Раскрываемый расчёт раунда. Шапка раунда — кнопка: строка события говорит
   ЧТО случилось, раскрытый блок — ПОЧЕМУ. Держать арифметику всегда на виду
   нельзя, четыре строки на каждый удар превращают разбор в простыню. */
.pvp-round-head-btn { cursor: pointer; display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.pvp-round-head-btn:hover .pvp-round-n,
.pvp-round-head-btn:focus-visible .pvp-round-n { color: var(--gold-strong); }
.pvp-round-why-hint { opacity: .55; letter-spacing: .06em; text-transform: uppercase; }
.pvp-round-head-btn:hover .pvp-round-why-hint { opacity: 1; color: var(--gold-strong); }
.pvp-round-head-btn.open .pvp-round-why-hint { opacity: 1; color: var(--gold-strong); }
.pvp-round-head-btn.open .pvp-round-why-hint::after { content: ' ✕'; }
.pvp-round-why {
  margin: 6px 0 2px; padding: 8px 10px;
  border-left: 2px solid var(--gold-dim);
  background: rgba(255, 255, 255, .025);
}
.pvp-why-line { line-height: 1.5; }
.pvp-why-line + .pvp-why-line { margin-top: 3px; }


/* ---------- живой ход схватки ----------
   Модалка боя, который идёт РАУНДАМИ. Три блока сверху (ты — счётчик и
   магазин — соперник), короткий журнал последних раундов, сетка карточек
   действий. Карточка кликабельна целиком: тап сразу отправляет ход, отдельной
   кнопки «подтвердить» нет — тот же паттерн одного тапа, что уже применяет
   замена предмета в слоте. */
.fight-live-top {
  display: grid; grid-template-columns: 1fr auto 1fr; gap: 14px; align-items: center;
  padding: 14px 16px; border-bottom: 1px solid var(--edge);
}
.fight-side-name { font-weight: 600; margin-bottom: 5px; }
.fight-live-top .fight-side:last-child { text-align: right; }
.fight-live-mid { text-align: center; white-space: nowrap; }
.fight-round-counter {
  font-size: var(--font-min); letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-2); margin-bottom: 6px;
}
.fight-mag { display: flex; gap: 3px; justify-content: center; margin-bottom: 5px; }
.fight-mag i { width: 8px; height: 12px; border: 1px solid var(--gold-dim); display: block; }
.fight-mag i.full { background: var(--gold-strong); }
.badge-pos {
  display: inline-block; margin-top: 5px;
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  padding: 2px 7px; border: 1px solid var(--edge); color: var(--muted);
}
.badge-pos.open { border-color: var(--red); color: var(--red); }
.badge-pos.cover { border-color: var(--gold-dim); color: var(--gold-strong); }

.fight-live-log { padding: 10px 16px 0; display: flex; flex-direction: column; gap: 4px; }
.fight-live-round { display: flex; gap: 10px; flex-wrap: wrap; align-items: baseline; }
.fight-live-hint { padding: 10px 16px; line-height: 1.45; }

.fight-acts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(158px, 1fr));
  gap: 8px; padding: 0 16px 16px;
}
.fight-act {
  display: block; text-align: left; cursor: pointer;
  padding: 10px 11px; background: var(--panel-2, #1D1D22);
  border: 1px solid var(--edge); color: var(--text);
  font: inherit; min-height: var(--tap-min);
}
.fight-act:hover:not(:disabled) { border-color: var(--gold-strong); }
.fight-act:disabled { opacity: .45; cursor: default; }
.fight-act-head { display: flex; align-items: baseline; gap: 7px; margin-bottom: 3px; }
.fight-act-head > i { color: var(--gold-strong); font-size: 12px; }
.fight-act-name { font-weight: 600; font-size: 14px; }
.fight-act-cost {
  margin-left: auto; font-size: var(--font-min); color: var(--gold-strong);
  font-variant-numeric: tabular-nums;
}
.fight-act-desc { display: block; font-size: var(--font-min); color: var(--muted); line-height: 1.4; }

.auto-fight-row {
  display: flex; align-items: center; gap: 8px; cursor: pointer;
  margin-top: 10px; min-height: var(--tap-min);
}

@media (max-width: 640px) {
  /* Три блока в ряд на телефоне не помещаются, а счётчик раунда важнее
     симметрии: свои и чужие полоски встают друг под друга. */
  .fight-live-top { grid-template-columns: 1fr; text-align: left; }
  .fight-live-top .fight-side:last-child { text-align: left; }
  .fight-live-mid { text-align: left; }
  .fight-mag { justify-content: flex-start; }
}


/* Опыт наёмника в ростере: подпись с числами над полоской, под ней — что даёт
   уровень. Полоска переиспользует канонный .bar, своей не заводим. */
.scav-xp { display: flex; flex-direction: column; gap: 3px; }
.scav-xp-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }


/* Встреча с чужим постом в журнале маршрута. Метка своя и красная: рядом с
   обычным «ОПАСНО» рассказ про чужого наёмника терялся среди случайностей. */
.route-log-tag.tag-encounter { color: var(--red); border-color: var(--red); }
.route-enc {
  margin-top: 6px; padding: 7px 9px;
  border-left: 2px solid var(--red);
  background: rgba(192, 74, 62, .07);
  display: flex; flex-direction: column; gap: 4px;
}
.route-enc-loot { display: flex; flex-wrap: wrap; gap: 12px; }


/* «Голова — глаза». Самый редкий исход боя обязан выглядеть как событие, а не
   как ещё одна строка урона: своя рамка и капс. */
.pvp-head-eyes {
  border-left: 2px solid var(--red); padding: 5px 9px; margin: 3px 0;
  background: rgba(192, 74, 62, .1); letter-spacing: .02em;
}


/* Общий онлайн в шапке. Не «чип ресурса» — это не ресурс: точка и число,
   без подписи, чтобы не спорить за место с ником и уровнем схрона.
   На узких экранах прячется вместе с уровнем схрона (там борьба за каждый
   пиксель, а онлайн — не то, ради чего открывают игру с телефона). */
.online-chip { display: inline-flex; align-items: center; gap: 5px; }
.online-chip-dot {
  width: 7px; height: 7px; display: block;
  background: var(--green, #7d9153);
  box-shadow: 0 0 6px rgba(125, 145, 83, .8);
}
@media (max-width: 700px) { .online-chip { display: none; } }
