/* ============================================================
   Бункер — bunker.chebur-net.ru

   Палитра снята с настоящих карт: жёлтый предупреждающий фон,
   чёрная типографика, у каждой масти своя кайма. Ничего лишнего:
   на экране одновременно шестнадцать видеоплиток, и любой градиент
   там, где можно обойтись плоским цветом, оплачивается кадрами.
   ============================================================ */

:root {
  --yellow:    #f5c518;
  --yellow-dk: #cfa20d;
  --yellow-lt: #ffe066;

  --ink-0: #0c0c0f;
  --ink-1: #131318;
  --ink-2: #1c1c23;
  --ink-3: #2a2932;
  --ink-4: #3a3945;

  --paper:  #f6f2e6;
  --text:   #f3f0e6;
  --dim:    #a5a1b0;
  --danger: #e03b32;
  --ok:     #4fd18b;

  /* Кайма по мастям — как на печатных картах */
  --k-profession: #f2f2f2;
  --k-bio:        #e8801a;
  --k-health:     #d0332e;
  --k-hobby:      #5f8f3a;
  --k-luggage:    #1f3fa8;
  --k-fact:       #3aa8e0;
  --k-special:    #7d43c4;
  --k-bunker:     #f5c518;

  --r-lg: 14px;
  --r-md: 9px;
  --r-sm: 5px;

  --font-head: 'Oswald', 'PT Sans Narrow', 'Arial Narrow', sans-serif;
  --font-ui:   'Inter', 'Segoe UI', system-ui, sans-serif;

  --topbar-h: 54px;
  --dock-h: 178px;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
.hide { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--ink-0);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

button, input, textarea, select {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}
button { cursor: pointer; border: none; background: none; }

/* Косая жёлто-чёрная лента сверху — узнаваемая деталь коробки */
.hazard-top {
  position: fixed; top: 0; left: 0; right: 0; height: 5px; z-index: 60;
  background: repeating-linear-gradient(
    -45deg, #111 0 10px, var(--yellow) 10px 20px);
  opacity: .9;
}

#app {
  position: relative;
  height: 100%;
  padding-top: 5px;
  display: grid;
  grid-template-rows: var(--topbar-h) 1fr auto;
}

/* ============================================================
   Шапка
   ============================================================ */

.topbar {
  display: flex; align-items: center; gap: 10px;
  padding: 0 12px;
  background: var(--ink-1);
  border-bottom: 1px solid var(--ink-3);
  min-width: 0;
}

.brand {
  display: flex; align-items: center; gap: 8px;
  font-family: var(--font-head);
  font-size: 21px; font-weight: 700; letter-spacing: 1.5px;
  color: var(--yellow);
  flex: none;
}
.brand b { color: var(--text); font-weight: 700; }
.brand-mark { width: 26px; height: 22px; }

.beta-chip {
  padding: 2px 7px; border-radius: 999px;
  background: var(--ink-3); border: 1px solid var(--ink-4);
  color: var(--dim);
  font-family: var(--font-ui); font-size: 10px; font-weight: 700;
  letter-spacing: .6px; text-transform: uppercase;
}

.phasebox, .roundbox {
  display: flex; flex-direction: column; justify-content: center;
  padding: 4px 10px;
  background: var(--ink-2);
  border: 1px solid var(--ink-3);
  border-radius: var(--r-md);
  line-height: 1.15;
  flex: none;
}
.phasebox { min-width: 168px; }
.phasebox small, .roundbox small {
  font-size: 9px; letter-spacing: 1.2px; color: var(--dim); text-transform: uppercase;
}
.phasebox b, .roundbox b {
  font-family: var(--font-head); font-size: 17px; letter-spacing: .5px;
}
.phasebox b { color: var(--yellow); }
.phasebox.urgent b { color: var(--danger); animation: blink 1s steps(2) infinite; }
@keyframes blink { 50% { opacity: .35; } }

.acc-badge {
  margin-left: auto;
  display: flex; align-items: center; gap: 7px;
  padding: 3px 9px 3px 3px;
  background: var(--ink-2); border: 1px solid var(--ink-3);
  border-radius: 999px;
  font-size: 12px; font-weight: 600;
  cursor: pointer; flex: none;
}
.acc-badge img, .acc-badge .em {
  width: 24px; height: 24px; border-radius: 50%;
  object-fit: cover; display: grid; place-items: center;
  background: var(--ink-3); font-size: 14px;
}
.acc-badge .lvl { color: var(--dim); font-weight: 400; font-size: 11px; }

.net-status {
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--dim); flex: none;
}
.net-status.online { background: var(--ok); }
.net-status.reconnecting { background: var(--yellow); animation: blink .8s steps(2) infinite; }
.net-status.offline { background: var(--danger); }

.top-actions { display: flex; gap: 5px; flex: none; }

.icon-btn {
  width: 34px; height: 34px; border-radius: var(--r-md);
  background: var(--ink-2); border: 1px solid var(--ink-3);
  display: grid; place-items: center; font-size: 15px;
  transition: background .12s, border-color .12s;
}
.icon-btn:hover { background: var(--ink-3); }
.icon-btn.on { background: var(--yellow); color: #111; border-color: var(--yellow-dk); }
.icon-btn.media.off { position: relative; color: var(--dim); }
.icon-btn.media.off::after {
  content: ''; position: absolute; left: 5px; right: 5px; top: 50%;
  height: 2px; background: var(--danger); transform: rotate(-45deg);
}
.icon-btn.admin { color: var(--yellow); }

/* Посадить бота: робот с плюсиком в углу */
.icon-btn.bots { position: relative; border-color: #6d4aa8; }
.icon-btn.bots i {
  position: absolute; right: -3px; bottom: -3px;
  width: 14px; height: 14px; border-radius: 50%;
  background: #b06bff; color: #fff;
  font: 700 11px/14px var(--font-ui); font-style: normal; text-align: center;
}
.icon-btn:disabled { opacity: .4; cursor: not-allowed; }

/* Новое в закрытом чате — точка на кнопке */
.icon-btn.unread { position: relative; }
.icon-btn.unread::after {
  content: ''; position: absolute; top: 3px; right: 3px;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--danger); box-shadow: 0 0 0 2px var(--ink-1);
}

/* Кнопка на месте, но выключена: в бете медиа нет.
   Курсор и приглушённый вид говорят это раньше, чем подсказка. */
.icon-btn.beta-off {
  opacity: .38;
  cursor: not-allowed;
  position: relative;
}
.icon-btn.beta-off::after {
  content: ''; position: absolute; left: 6px; right: 6px; top: 50%;
  height: 2px; background: var(--dim); transform: rotate(-45deg);
}

/* Без камер плитке не нужна высота под лицо: остаются имя, рожица
   и открытые карты — и шестнадцать таких помещаются на ноутбуке. */
#app.no-media .tile { min-height: 84px; }

/* ============================================================
   Красная плашка

   Отдельно от тостов: «комната заполнена» — это не мелкое
   уведомление, а причина, по которой человек вообще не в игре.
   Она обязана висеть, пока её не закроют.
   ============================================================ */

.alert {
  position: absolute; top: calc(var(--topbar-h) + 5px); left: 0; right: 0; z-index: 55;
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px;
  background: var(--danger);
  color: #fff;
  font-weight: 700; font-size: 14px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, .5);
  animation: slideDown .22s ease-out;
}
@keyframes slideDown { from { transform: translateY(-100%); } }
.alert-x {
  margin-left: auto; font-size: 20px; line-height: 1;
  opacity: .85; color: #fff;
}

/* ============================================================
   Сетка плиток

   Число колонок задаёт скрипт: при двух игроках квадратики
   в четверть экрана выглядят нелепо, а при шестнадцати нужен
   ровно квадрат 4×4.
   ============================================================ */

.stage {
  position: relative;
  overflow: auto;
  padding: 10px;
  display: grid;
}

/* Сетка занимает всю сцену целиком и делит её на строки: при
   шестнадцати участниках все обязаны помещаться сразу, без
   прокрутки, а при четырёх — плитки растут во весь экран, и открытые
   карты на них читаются через комнату. Потолка у плитки нет: пустые
   поля по бокам ничего не показывают. */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr));
  grid-template-rows: repeat(var(--rows, 2), minmax(0, 1fr));
  gap: 8px;
  width: 100%; height: 100%;
}

/* Нижняя граница высоты нужна для низких окон: без неё на ноутбуке
   с короткой матрицей шестнадцать плиток сплющивались бы в полоски,
   где не видно лица. Упёрлись в неё — сцена начинает прокручиваться,
   и это честнее, чем показывать шестнадцать щелей. */
.tile {
  position: relative;
  min-width: 0; min-height: 118px;
  background: var(--ink-1);
  border: 2px solid var(--ink-3);
  border-radius: var(--r-md);
  overflow: hidden;
  min-width: 0;
  transition: border-color .15s, transform .15s;
  cursor: pointer;
  animation: tileIn .25s ease-out;
  /* Всё внутри плитки меряется от её собственного размера (cqw, cqh):
     на четверых полоска карт крупная и в две строки, на шестнадцати —
     узкая, но плитки при этом никуда не уезжают. */
  container-type: size;
}
@keyframes tileIn { from { opacity: 0; transform: scale(.92); } }

.tile video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  background: #000;
  transform: scaleX(-1);        /* себя привычнее видеть зеркально */
}
.tile:not(.me) video { transform: none; }
.tile video.off { display: none; }

.tile-face {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  font-size: clamp(26px, 20cqmin, 120px);
  background: radial-gradient(circle at 50% 40%, var(--ink-2), var(--ink-0));
  transition: padding .4s ease;
}
.tile-face img {
  width: clamp(40px, 34cqmin, 200px); aspect-ratio: 1;
  border-radius: 50%; object-fit: cover;
}
/* Карты розданы — лицо уходит выше, освобождая низ под полоску карт */
.tile.has-cards .tile-face { padding-bottom: 22cqh; }

.tile.speaking { border-color: var(--ok); box-shadow: 0 0 0 2px rgba(79, 209, 139, .35); }
.tile.turn { border-color: var(--yellow); box-shadow: 0 0 0 3px rgba(245, 197, 24, .3); }
.tile.exiled { filter: grayscale(1) brightness(.55); }
.tile.exiled::after {
  content: 'ИЗГНАН';
  position: absolute; top: 50%; left: 0; right: 0;
  transform: translateY(-50%) rotate(-9deg);
  text-align: center;
  font-family: var(--font-head); font-size: clamp(16px, 6cqw, 44px); letter-spacing: 3px;
  color: var(--danger);
  background: rgba(0, 0, 0, .45);
  padding: 3px 0;
}
.tile.offline { opacity: .45; }
.tile.survived { border-color: var(--ok); }

.tile-top {
  position: absolute; top: 0; left: 0; right: 0;
  display: flex; align-items: center; gap: 4px;
  padding: 4px 6px;
  background: linear-gradient(180deg, rgba(0, 0, 0, .72), transparent);
  font-size: 11px;
}
.tile-badge {
  padding: 1px 5px; border-radius: 3px;
  font-family: var(--font-head); font-size: clamp(9px, 1.5cqw, 13px); letter-spacing: .8px;
  background: var(--ink-3);
}
.tile-badge.host { background: var(--yellow); color: #111; }
.tile-badge.you { background: #fff; color: #111; }
.tile-badge.voted { background: var(--ok); color: #06180f; }
.tile-badge.not-ready { background: var(--danger); color: #fff; }
.tile-badge.admin { background: #7b9cff; color: #0b1233; }
.tile-badge.bot { background: #b06bff; color: #fff; }

/* Убрать бота — крестик в правом верхнем углу, только в лобби */
.tile-x {
  position: absolute; top: 4px; right: 4px; z-index: 4;
  width: 24px; height: 24px; border-radius: 50%;
  background: rgba(0, 0, 0, .65); color: #fff;
  border: 1px solid rgba(255, 255, 255, .25);
  font-size: 16px; line-height: 20px; text-align: center; cursor: pointer;
}
.tile-x:hover { background: var(--danger); }

/* Реплика облачком над лицом. Не перехватывает клики: под ним
   плитка, по которой открывают досье. */
.tile-say {
  position: absolute; z-index: 2;
  left: 7%; right: 7%; top: clamp(24px, 9cqh, 46px);
  padding: 6px 10px;
  background: var(--paper); color: #111;
  border-radius: 10px;
  font-size: clamp(11px, 1.9cqw, 15px); line-height: 1.3; font-weight: 600;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden;
  opacity: 0; transform: translateY(-6px);
  transition: opacity .25s, transform .25s;
  pointer-events: none;
}
.tile-say.show { opacity: 1; transform: none; }
.tile-votes { margin-left: auto; font-family: var(--font-head); font-size: 15px; color: var(--danger); }

.tile-bottom {
  position: absolute; bottom: 0; left: 0; right: 0;
  padding: clamp(10px, 5cqh, 26px) clamp(5px, 1.2cqw, 10px) clamp(4px, 1.4cqh, 10px);
  background: linear-gradient(0deg, rgba(0, 0, 0, .85), transparent);
}
.tile-name {
  display: flex; align-items: center; gap: 5px;
  font-weight: 700; font-size: clamp(11px, 2.3cqw, 19px);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tile-name .mute { color: var(--danger); font-size: 11px; }

/* Открытые карты игрока — ряд из семи мини-карт (фактов два).
   На крупной плитке у каждой две строки: масть и сама карта,
   чтобы читать, не открывая досье. На мелкой (шестнадцать человек)
   остаётся одна строка — с одного взгляда видно, кто что открыл. */
.pips {
  display: grid; grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: clamp(2px, .7cqw, 7px);
  margin-top: clamp(3px, .9cqh, 7px);
}
.pip {
  --pip-color: transparent;
  min-width: 0; height: clamp(15px, 17cqh, 78px);
  border-radius: clamp(2px, .8cqw, 7px);
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .08);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; padding: 1px 3px;
  color: rgba(255, 255, 255, .55);
  text-align: center; overflow: hidden;
  font-size: clamp(7px, 2.1cqw, 17px); line-height: 1.12;
  font-weight: 800; text-transform: uppercase; letter-spacing: 0;
  transition: background .3s, box-shadow .3s;
}
.pip b {
  font-family: var(--font-head); font-weight: 600;
  font-size: .76em; letter-spacing: .7px; opacity: .72;
}
.pip span {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; word-break: break-word; max-width: 100%;
}
.pip.open {
  background: var(--pip-color); border-color: transparent;
  color: var(--pip-ink, #111);
  box-shadow: 0 0 12px -2px var(--pip-color);
}
.pip.gone { background: rgba(255, 255, 255, .03); text-decoration: line-through; opacity: .6; }

/* Мелкая плитка: одна строка, масть не подписываем — её видно по цвету */
@container (max-height: 200px) {
  .pip b { display: none; }
  .pip span { display: block; white-space: nowrap; text-overflow: ellipsis; }
}

/* Карта открылась у всех на глазах — вспышка её цвета */
.pip.flash { animation: pipFlash 1.3s ease-out; }
@keyframes pipFlash {
  0%   { transform: scale(1.28); filter: brightness(1.7);
         box-shadow: 0 0 26px 8px var(--pip-color); }
  100% { transform: none; filter: none; box-shadow: 0 0 12px -2px var(--pip-color); }
}
/* Сюда прилетела розданная карта */
.pip.land { animation: pipLand .5s ease-out; }
@keyframes pipLand {
  0%   { transform: scale(1.22); background: rgba(245, 197, 24, .55);
         box-shadow: 0 0 16px 3px rgba(245, 197, 24, .6); }
  100% { transform: none; }
}

/* Рубашка, которая летит из центра стола к игроку при раздаче.
   В покое невидима: между концом полёта и удалением из DOM
   карта не должна мелькнуть в углу экрана. */
.fly-card {
  position: fixed; left: 0; top: 0; z-index: 80;
  width: 30px; height: 42px;
  border: 2px solid #111; border-radius: 4px;
  background: repeating-linear-gradient(-45deg, #111 0 4px, var(--yellow) 4px 8px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, .55), 0 0 12px rgba(245, 197, 24, .4);
  pointer-events: none; opacity: 0;
  will-change: transform, opacity;
}

/* Кнопка голосования — компактная плашка в углу.
   Во всю плитку она закрывала бы лицо, а во всю нижнюю полосу —
   имя и открытые карты. И то и другое закрывается ровно в тот
   момент, когда по ним и принимают решение. */
.tile-vote {
  position: absolute; right: 6px; top: clamp(24px, 7cqh, 40px); z-index: 4;
  padding: 5px 11px;
  background: var(--danger); color: #fff;
  border: 1px solid rgba(255, 255, 255, .35);
  font-family: var(--font-head); font-size: 12px; letter-spacing: 1px;
  text-align: center; border-radius: var(--r-sm);
  opacity: 0; pointer-events: none; transition: opacity .15s, transform .1s;
}
.tile-vote:hover { transform: scale(1.06); }
.tile.votable .tile-vote { opacity: .93; pointer-events: auto; }
.tile.votable:hover .tile-vote { opacity: 1; }
.tile.picked .tile-vote { background: #7a1512; }

.empty-hint {
  position: absolute; inset: 0;
  display: grid; place-content: center; justify-items: center; gap: 8px;
  text-align: center; color: var(--dim); padding: 20px;
}
.empty-hint h2 {
  font-family: var(--font-head); font-size: 26px; letter-spacing: 2px;
  color: var(--yellow); margin: 0;
}
.empty-hint p { max-width: 380px; margin: 0; line-height: 1.5; }

/* Один в комнате: плитка сверху, подсказка под ней, обе по центру.
   Поверх плитки подсказка ложилась прямо на лицо и имя. */
.stage.alone { grid-template-rows: minmax(0, 1fr) auto; align-content: center; }
.stage.alone .grid { max-width: 420px; max-height: min(330px, 100%); margin: auto; }
.stage.alone .empty-hint { position: static; inset: auto; padding: 16px 20px 4px; }

/* ============================================================
   Нижняя палуба: своя рука и действия
   ============================================================ */

.dock {
  display: grid;
  grid-template-columns: 1fr 300px;
  gap: 10px;
  padding: 8px 12px 12px;
  background: var(--ink-1);
  border-top: 1px solid var(--ink-3);
  min-height: var(--dock-h);
}
/* Своя рука занимает внизу ощутимую полосу. На шестнадцати
   участниках эта полоса — те самые полсотни пикселей высоты у
   каждой плитки, поэтому её можно убрать целиком: карты никуда
   не денутся, просто временно уйдут с глаз. */
#app.no-dock .dock { display: none; }

.dock-left { min-width: 0; }
.dock-right { display: flex; flex-direction: column; gap: 8px; min-width: 0; }

/* Сверху и по бокам — запас под подъём карты и её свечение: рука
   прокручивается вбок, а значит, всё, что вылезает за её край,
   обрезается. Отрицательный отступ съедает часть запаса за счёт
   верхнего поля палубы, чтобы она не выросла. */
.hand {
  display: flex; gap: 10px;
  overflow-x: auto; overflow-y: hidden;
  padding: 22px 14px 12px;
  margin: -8px -8px 0;
  /* Непрозрачный фон — не для красоты. Прокручиваемый блок браузер
     выносит в отдельный слой, и на прозрачном слое Windows рисует
     текст без субпиксельного сглаживания: мельче и мыльнее. */
  background: var(--ink-1);
}

/* Два слоя, как в покере: ячейка приподнимается плавным переходом,
   а сама карта внутри покачивается анимацией. Качание на том же
   элементе, что и подъём, перетирало бы его, и при уходе мыши карта
   дёргалась бы вниз рывком вместо того, чтобы спокойно опуститься.

   Только сдвиг — ни масштаба, ни наклона. Увеличенную или повёрнутую
   карту браузер растягивает готовой картинкой, и текст на ней резко
   мылится ровно в тот момент, когда его хотят прочитать. */
.hand-slot {
  flex: none; position: relative;
  transition: transform .28s cubic-bezier(.2, .9, .3, 1.25);
}
.hand-slot:hover { transform: translateY(-14px); z-index: 2; }

/* Свечение масти. У каждой карты свой сдвиг фазы (--gd), иначе вся
   рука мигала бы разом, как гирлянда. */
.hand .card { animation: cardGlow 3.2s ease-in-out infinite; animation-delay: var(--gd, 0s); }
.hand-slot:hover .card {
  animation: cardGlowHi 1.6s ease-in-out infinite, levitate 2.6s ease-in-out infinite;
}
.hand-slot:hover .card.dim { opacity: .85; }

@keyframes cardGlow {
  0%, 100% { box-shadow: 0 0 4px 0 var(--glow, transparent); }
  50%      { box-shadow: 0 0 14px 2px var(--glow, transparent); }
}
@keyframes cardGlowHi {
  0%, 100% { box-shadow: 0 0 10px 1px var(--glow, transparent), 0 12px 20px rgba(0, 0, 0, .5); }
  50%      { box-shadow: 0 0 22px 5px var(--glow, transparent), 0 12px 20px rgba(0, 0, 0, .5); }
}
/* Качается свойством top, а не transform: так карта остаётся частью
   обычной отрисовки и текст рисуется заново в каждом кадре, чётко,
   а не двигается размытой картинкой. Карта и так перерисовывается
   каждый кадр из-за пульсации свечения, лишней работы тут нет. */
@keyframes levitate {
  0%, 100% { top: 0; }
  50%      { top: -5px; }
}

/* Раздача: карта прилетает из центра стола (--dx, --dy считает ui.js
   от настоящего положения ячейки), крутится и садится на место */
.hand-slot.deal-in { animation: handIn .8s cubic-bezier(.2, .85, .3, 1) backwards; }
@keyframes handIn {
  0%   { opacity: 0; transform: translate(var(--dx, 0), var(--dy, -40vh)) rotate(-20deg) scale(.45); }
  18%  { opacity: 1; }
  72%  { transform: translate(0, 7px) rotate(2deg) scale(1.04); }
  100% { opacity: 1; transform: none; }
}

/* Своя карта открылась — переворачивается лицом к столу */
.hand-slot.just-opened { animation: flipReveal .6s cubic-bezier(.2, .9, .3, 1.2); }
@keyframes flipReveal {
  0%   { transform: perspective(700px) rotateY(90deg) scale(1.08); }
  100% { transform: none; }
}

/* ---------- карта ---------- */

.card {
  --edge: #888;
  position: relative; top: 0;
  flex: none;
  width: 112px; height: 154px;
  background: var(--yellow);
  border: 3px solid var(--edge);
  border-radius: 7px;
  display: flex; flex-direction: column;
  overflow: hidden;
  color: #111;
  text-rendering: optimizeLegibility;
}
.card.pickable { cursor: pointer; }
.card.closed { background: #14140f; border-color: var(--ink-4); color: var(--yellow); }
.card.closed .card-art { opacity: .3; }
.card.used { opacity: .4; }
.card.dim { opacity: .55; }

/* Своя карта, которую остальные ещё не видят. Раньше она была
   полупрозрачной целиком — и надпись вместе с ней становилась
   бледной. Теперь приглушена только картинка, а фон в косую
   полоску: видно, что карта «в рукаве», и текст читается чётко. */
.card.unshown {
  background: repeating-linear-gradient(-45deg, #f5c518 0 9px, #e3b312 9px 18px);
}
.card.unshown .card-art { opacity: .45; }

.card-head {
  background: #111; color: var(--yellow);
  font-family: var(--font-head); font-size: 11px; letter-spacing: 1.2px;
  text-align: center; padding: 3px 2px;
  text-transform: uppercase;
}
.card-art {
  flex: 1; display: grid; place-items: center; padding: 5px;
}
.card-art svg { width: 50px; height: 50px; }
.card-name {
  background: #111; color: #fff;
  font-size: calc(10.5px * var(--fit, 1)); font-weight: 800; line-height: 1.2; letter-spacing: .15px;
  text-align: center; padding: 4px 4px; min-height: 34px;
  display: grid; place-items: center;
  text-transform: uppercase;
}
.card.closed .card-name { background: #000; color: var(--dim); }

.card-text {
  flex: 1; padding: 6px 7px;
  font-size: 10px; line-height: 1.28; overflow: hidden;
  color: #111; font-weight: 500;
}

/* Карта особого условия — фиолетовая кайма, текст вместо картинки */
.card.special { --edge: var(--k-special); }
.card.wide { width: 144px; }

/* --glow — цвет свечения. Светлее каймы: тёмно-синий багаж и
   болотное хобби, светясь своим печатным цветом, почти не видны
   на тёмном фоне. */
.card-k-profession { --edge: var(--k-profession); --glow: rgba(255, 255, 255, .55); }
.card-k-bio        { --edge: var(--k-bio);        --glow: rgba(255, 150, 40, .75); }
.card-k-health     { --edge: var(--k-health);     --glow: rgba(255, 60, 50, .8); }
.card-k-hobby      { --edge: var(--k-hobby);      --glow: rgba(110, 225, 80, .75); }
.card-k-luggage    { --edge: var(--k-luggage);    --glow: rgba(90, 130, 255, .85); }
.card-k-fact       { --edge: var(--k-fact);       --glow: rgba(70, 195, 255, .75); }
.card-k-bunker     { --edge: var(--k-bunker);     --glow: rgba(245, 197, 24, .7); }
.card-k-catastrophe{ --edge: #111; }
.card-k-threat     { --edge: #111; }
.card-k-special    { --edge: var(--k-special);    --glow: rgba(175, 105, 255, .85); }

/* ---------- подсказка к карте: что она значит ----------
   Всегда в DOM, но невидима: так её размер можно измерить до показа
   и сразу поставить на место, без прыжка. Клики пропускает сквозь
   себя — под ней может оказаться другая карта. */
.card-tip {
  position: fixed; left: 0; top: 0; z-index: 95;
  max-width: 300px; padding: 10px 12px 11px;
  background: var(--ink-2); color: var(--text);
  border: 1px solid var(--ink-4); border-radius: var(--r-md);
  box-shadow: 0 12px 28px rgba(0, 0, 0, .55);
  font-size: 13px; line-height: 1.45;
  pointer-events: none;
  opacity: 0; visibility: hidden; transform: translateY(4px);
  transition: opacity .15s, transform .15s, visibility 0s .15s;
}
.card-tip.show {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity .15s, transform .15s;
}
.tip-kind {
  font-family: var(--font-head); font-size: 10.5px; letter-spacing: 1.4px;
  text-transform: uppercase; color: var(--kc, var(--yellow));
  margin-bottom: 1px;
}
.tip-title { font-weight: 800; font-size: 14.5px; margin-bottom: 5px; }
.tip-text { color: #dcd8cd; }
.tip-note {
  margin-top: 7px; padding-top: 6px; border-top: 1px solid var(--ink-3);
  color: var(--dim); font-size: 11.5px;
}

/* ---------- подсказка и кнопки ---------- */

.act-hint {
  padding: 8px 10px;
  background: var(--ink-2); border: 1px solid var(--ink-3);
  border-left: 3px solid var(--yellow);
  border-radius: var(--r-md);
  font-size: 12.5px; line-height: 1.4;
  min-height: 44px;
}
.act-hint.warn { border-left-color: var(--danger); }

.act-row { display: flex; flex-wrap: wrap; gap: 6px; }

.btn {
  padding: 9px 14px;
  border-radius: var(--r-md);
  background: var(--ink-3); border: 1px solid var(--ink-4);
  font-family: var(--font-head); font-size: 14px; letter-spacing: .8px;
  text-transform: uppercase;
  transition: transform .1s, filter .1s;
}
.btn:hover:not(:disabled) { filter: brightness(1.18); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .4; cursor: default; }
.btn.gold { background: var(--yellow); border-color: var(--yellow-dk); color: #111; }
.btn.red { background: var(--danger); border-color: #9c2620; color: #fff; }
.btn.wide { flex: 1 1 100%; }
.btn.sm { padding: 6px 10px; font-size: 12px; }

.threat-strip {
  display: flex; gap: 7px; overflow-x: auto; padding-bottom: 6px; margin-bottom: 6px;
}

/* ============================================================
   Боковые панели
   ============================================================ */

.sidepanel, .deckpanel {
  position: fixed; top: 5px; right: 0; bottom: 0; z-index: 50;
  width: min(380px, 92vw);
  background: var(--ink-1);
  border-left: 1px solid var(--ink-3);
  display: flex; flex-direction: column;
  box-shadow: -10px 0 30px rgba(0, 0, 0, .5);
  animation: slideIn .18s ease-out;
}
@keyframes slideIn { from { transform: translateX(100%); } }

.side-head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--ink-3);
  font-family: var(--font-head); letter-spacing: 1px;
}
.side-tabs { display: flex; gap: 4px; }
.side-tab {
  padding: 5px 11px; border-radius: var(--r-sm);
  background: var(--ink-2); font-size: 12px;
  font-family: var(--font-head); letter-spacing: .8px;
}
.side-tab.on { background: var(--yellow); color: #111; }
.side-close { margin-left: auto; font-size: 22px; line-height: 1; color: var(--dim); }

.side-body { flex: 1; overflow-y: auto; padding: 10px; }
#chatPane { display: flex; flex-direction: column; padding: 0; }

.chat-list { flex: 1; overflow-y: auto; padding: 10px; display: flex; flex-direction: column; gap: 7px; }
.chat-item { font-size: 13px; line-height: 1.4; word-break: break-word; }
.chat-item .who { font-weight: 700; color: var(--yellow); }
.chat-item.system { color: var(--dim); font-style: italic; }
.chat-item.bot .who { color: #c9a2ff; }
.chat-item.old { opacity: .6; }

.chat-input { display: flex; gap: 6px; padding: 8px; border-top: 1px solid var(--ink-3); }
.chat-input input {
  flex: 1; min-width: 0; padding: 8px 10px;
  background: var(--ink-2); border: 1px solid var(--ink-3);
  border-radius: var(--r-md); outline: none;
}
.chat-input input:focus { border-color: var(--yellow-dk); }
.chat-send {
  width: 38px; border-radius: var(--r-md);
  background: var(--yellow); color: #111; font-size: 15px;
}

.log-line { font-size: 12.5px; line-height: 1.45; padding: 4px 0; border-bottom: 1px solid var(--ink-2); }
.log-line b { color: var(--yellow); }
.log-line.bad b { color: var(--danger); }

.dossier-head { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }
.dossier-head .av {
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: var(--ink-3); font-size: 22px; object-fit: cover;
}
.dossier-head h3 { margin: 0; font-family: var(--font-head); font-size: 19px; letter-spacing: 1px; }
.dossier-cards { display: flex; flex-wrap: wrap; gap: 7px; }

.deck-body { flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 14px; }
.deck-group h4 {
  margin: 0 0 7px; font-family: var(--font-head); font-size: 13px;
  letter-spacing: 1.6px; color: var(--yellow); text-transform: uppercase;
}
.deck-row { display: flex; flex-wrap: wrap; gap: 7px; }

.bigcard {
  background: var(--yellow); color: #111;
  border: 3px solid #111; border-radius: 8px;
  padding: 0; overflow: hidden; width: 100%;
}
.bigcard .card-head { font-size: 12px; letter-spacing: 2px; }
.bigcard .bc-name {
  background: #111; color: #fff; text-align: center;
  font-family: var(--font-head); font-size: 15px; letter-spacing: 1.2px;
  padding: 5px; text-transform: uppercase;
}
.bigcard .bc-text { padding: 9px 11px; font-size: 12px; line-height: 1.4; }
.bigcard.gone { opacity: .45; }
.bigcard.gone .bc-name { text-decoration: line-through; }

/* ---------- исследование бункера: пара карт посреди экрана ---------- */
.explore {
  position: fixed; inset: 0; z-index: 70;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  background: rgba(8, 8, 10, .72);
  padding: 20px; cursor: pointer;
  animation: exploreIn .35s ease-out;
}
.explore.out { opacity: 0; transition: opacity .3s; }
@keyframes exploreIn { from { opacity: 0; } }
.explore-title {
  font-family: var(--font-head); font-size: 22px; letter-spacing: 2px;
  text-transform: uppercase; color: var(--yellow);
}
.explore-pair { display: flex; gap: 18px; flex-wrap: wrap; justify-content: center; max-width: 760px; }
.explore-slot { width: min(340px, 90vw); animation: exploreCard .5s cubic-bezier(.2, .9, .3, 1.15) backwards; }
.explore-slot.threat { animation-delay: .15s; }
.explore-slot .bigcard { box-shadow: 0 16px 40px rgba(0, 0, 0, .6); }
.explore-slot.threat .bigcard { border-color: var(--danger); }
.explore-cap {
  font-family: var(--font-head); font-size: 12px; letter-spacing: 1.6px;
  text-transform: uppercase; color: var(--dim); margin-bottom: 6px; text-align: center;
}
.explore-slot.threat .explore-cap { color: #ff7a70; }
.explore-note { color: var(--dim); font-size: 12px; }
@keyframes exploreCard {
  from { opacity: 0; transform: translateY(30px) rotate(-3deg) scale(.9); }
}
@media (prefers-reduced-motion: reduce) {
  .explore, .explore-slot { animation: none; }
}

/* ============================================================
   Модальные окна
   ============================================================ */

.modal-bg {
  position: fixed; inset: 0; z-index: 70;
  background: rgba(0, 0, 0, .72);
  display: grid; place-items: center; padding: 16px;
  overflow-y: auto;
}
.modal {
  width: min(520px, 100%);
  background: var(--ink-1);
  border: 1px solid var(--ink-3);
  border-top: 4px solid var(--yellow);
  border-radius: var(--r-lg);
  padding: 18px;
  max-height: 88vh; overflow-y: auto;
}
.modal h2 {
  margin: 0 0 12px;
  font-family: var(--font-head); font-size: 22px; letter-spacing: 1.4px;
  color: var(--yellow); text-transform: uppercase;
}
.modal h3 {
  margin: 16px 0 7px;
  font-family: var(--font-head); font-size: 15px; letter-spacing: 1.1px;
}
.modal p, .modal li { line-height: 1.55; }
.modal label { display: block; margin: 9px 0 4px; font-size: 12px; color: var(--dim); }
.modal input[type=text], .modal input[type=password], .modal input[type=number], .modal select {
  width: 100%; padding: 9px 11px;
  background: var(--ink-2); border: 1px solid var(--ink-3);
  border-radius: var(--r-md); outline: none;
}
.modal input:focus, .modal select:focus { border-color: var(--yellow-dk); }
.modal .row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.modal .err { color: var(--danger); font-size: 13px; margin-top: 9px; min-height: 18px; }
.modal .note { color: var(--dim); font-size: 12px; line-height: 1.5; }
.modal .code {
  font-family: ui-monospace, Consolas, monospace; font-size: 17px; letter-spacing: 2px;
  background: var(--ink-2); padding: 9px; border-radius: var(--r-md);
  text-align: center; color: var(--yellow); user-select: all;
}
.tabs { display: flex; gap: 5px; margin-bottom: 12px; }
.tabs button {
  flex: 1; padding: 8px; border-radius: var(--r-md);
  background: var(--ink-2); font-family: var(--font-head); letter-spacing: .8px;
}
.tabs button.on { background: var(--yellow); color: #111; }

.emoji-grid { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.emoji-grid button {
  width: 34px; height: 34px; border-radius: var(--r-sm);
  background: var(--ink-2); font-size: 17px;
}
.emoji-grid button.on { background: var(--yellow); }

.statbar { height: 7px; background: var(--ink-3); border-radius: 4px; overflow: hidden; margin: 5px 0 3px; }
.statbar i { display: block; height: 100%; background: var(--yellow); }
.stat-row { display: flex; justify-content: space-between; padding: 5px 0; border-bottom: 1px solid var(--ink-2); font-size: 13px; }
.stat-row b { color: var(--yellow); }

.toast {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%) translateY(20px);
  z-index: 80;
  padding: 10px 16px; border-radius: var(--r-md);
  background: var(--ink-3); border: 1px solid var(--ink-4);
  font-size: 13px; font-weight: 600;
  opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s;
  max-width: 90vw; text-align: center;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }
.toast.bad { background: var(--danger); border-color: #9c2620; color: #fff; }

/* ============================================================
   Узкий экран

   Телефон в «Бункере» — не крайний случай, а норма: половина
   компании подключается с дивана. Плитки становятся мельче,
   палуба уезжает вниз, рука прокручивается вбок.
   ============================================================ */

@media (max-width: 900px) {
  .dock { grid-template-columns: 1fr; }
  .phasebox { min-width: 120px; }
  .roundbox { display: none; }
  .brand span { display: none; }
}

@media (max-width: 640px) {
  :root { --topbar-h: 48px; --dock-h: 150px; }
  .topbar { gap: 6px; padding: 0 7px; }
  .icon-btn { width: 30px; height: 30px; font-size: 13px; }
  .card { width: 84px; height: 116px; }
  .card-art svg { width: 34px; height: 34px; }
  .card-name { font-size: calc(8.5px * var(--fit, 1)); min-height: 26px; }
  .stage { padding: 6px; }
  .grid { gap: 5px; }
  .tile-badge { font-size: 9px; }
  .hand { padding: 18px 10px 10px; }
}

/* Кому от движения на экране плохо — тому без качки и полётов.
   Подъём карты оставляем: без него непонятно, на какую наведено. */
@media (prefers-reduced-motion: reduce) {
  .hand .card, .hand-slot:hover .card, .hand-slot.deal-in, .hand-slot.just-opened,
  .pip.flash, .pip.land { animation: none !important; }
  .hand-slot:hover { transform: translateY(-8px); }
}
