/* ============================================================
   WARDENCASE — дизайн-система
   Пиксельная эстетика Minecraft: сундуки и иконки предметов
   нарисованы прямоугольниками в SVG с shape-rendering: crispEdges.
   ============================================================ */

/*
 * Шрифты лежат на нашем сервере (public/assets/fonts, лицензия OFL-1.1 —
 * файлы *-OFL.txt рядом). Раньше они грузились с Google Fonts, и каждый
 * посетитель отдавал Google свой IP ещё до того, как что-то прочитал.
 * Вариативные файлы: одно начертание на весь диапазон жирности. Наборы
 * символов разбиты по unicode-range — браузер скачивает только нужные.
 *
 * Роли: Unbounded — заголовки, крупные кнопки и ярлыки-«бровки», то есть
 * голос бренда; Onest — весь текст интерфейса и все числа (у него есть
 * табличные цифры, так что суммы выравниваются без моноширинного шрифта);
 * JetBrains Mono остаётся только там, где данные действительно
 * «технические»: сиды, хэши, коды приглашений. Раньше моноширинным были
 * набраны все цены и балансы, и магазин читался как терминал.
 */
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-display: swap;
  font-weight: 200 900;
  src: url('/assets/fonts/unbounded-cyrillic-ext-wght-normal.woff2') format('woff2');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-display: swap;
  font-weight: 200 900;
  src: url('/assets/fonts/unbounded-cyrillic-wght-normal.woff2') format('woff2');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-display: swap;
  font-weight: 200 900;
  src: url('/assets/fonts/unbounded-latin-ext-wght-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: 'Unbounded';
  font-style: normal;
  font-display: swap;
  font-weight: 200 900;
  src: url('/assets/fonts/unbounded-latin-wght-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('/assets/fonts/onest-cyrillic-ext-wght-normal.woff2') format('woff2');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('/assets/fonts/onest-cyrillic-wght-normal.woff2') format('woff2');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('/assets/fonts/onest-latin-ext-wght-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url('/assets/fonts/onest-latin-wght-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 100 800;
  src: url('/assets/fonts/jetbrains-mono-cyrillic-ext-wght-normal.woff2') format('woff2');
  unicode-range: U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 100 800;
  src: url('/assets/fonts/jetbrains-mono-cyrillic-wght-normal.woff2') format('woff2');
  unicode-range: U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 100 800;
  src: url('/assets/fonts/jetbrains-mono-latin-ext-wght-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 100 800;
  src: url('/assets/fonts/jetbrains-mono-latin-wght-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}

:root {
  --bg: #07070d;
  --bg-deep: #04040a;
  --surface: #0f0f1a;
  --surface-2: #16162a;
  --surface-3: #1e1e38;
  --line: #262645;
  --line-soft: #1b1b30;

  --text: #edeef7;
  --text-dim: #9b9cba;
  /* #74769a давал 4,4:1 на панелях — меньше нормы для мелкого текста (4,5:1),
     а на нём подписи цен, ников и сроков. Этот оттенок даёт 5:1. */
  --text-faint: #7e80a4;

  --aqua: #5eead4;
  --violet: #a78bfa;
  --gold: #f7b955;
  --rose: #fb7185;

  /* Один сплошной акцент. Бирюзово-фиолетовый градиент на кнопках, вкладках
     и заголовке читался как шаблонный «сгенерированный» дизайн. */
  --grad: var(--aqua);
  --aqua-hover: #8af2e2;

  --cut: 12px;
  --cut-sm: 8px;
  --radius: 16px;
  --radius-sm: 12px;

  --font-display: 'Unbounded', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'Onest', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', monospace;

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --top-h: 82px;
  --content-w: 1360px;
}

* { box-sizing: border-box; margin: 0; padding: 0; -webkit-tap-highlight-color: transparent; }
[hidden] { display: none !important; }

body {
  background-color: var(--bg);
  /*
   * Слой с буквой W — уже приглушённая по альфе версия (обычный CSS не
   * умеет менять прозрачность отдельного background-слоя), сидит поверх
   * шума и под цветными пятнами. Один слой на всём body, а не отдельный
   * fixed-элемент — раньше отдельные ::before/::after ловили артефакты
   * отрисовки при скролле в этой среде.
   */
  background-image:
    url("/assets/brand/w-mark-faint-600.webp"),
    radial-gradient(70ch 45ch at 20% 0%, rgba(94, 234, 212, 0.08), transparent 60%),
    radial-gradient(60ch 45ch at 88% 6%, rgba(167, 139, 250, 0.1), transparent 60%);
  background-position: 92% 0, 0 0, 0 0;
  background-size: 900px, auto, auto;
  background-attachment: fixed, fixed, fixed;
  background-repeat: no-repeat, no-repeat, no-repeat;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.55;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* На широких экранах фон — иллюстрация Древнего города в Глубинной тьме
   (deep-city.jpg, см. README): верх картинки уходит в цвет фона, так что
   под контентом темно, а город виден в нижней трети экрана. Знак W из
   фона здесь убран: два фоновых сюжета спорили друг с другом, а бренд и
   так в шапке. Ниже 1100px города нет, и W остаётся. Слои: шум, два
   свечения, город. */
@media (min-width: 1101px) {
  body {
    background-image:
      radial-gradient(70ch 45ch at 20% 0%, rgba(94, 234, 212, 0.08), transparent 60%),
      radial-gradient(60ch 45ch at 88% 6%, rgba(167, 139, 250, 0.1), transparent 60%),
      url("/assets/brand/deep-city.jpg");
    background-position: 0 0, 0 0, center bottom;
    background-size: auto, auto, cover;
    background-attachment: fixed, fixed, fixed;
    background-repeat: no-repeat, no-repeat, no-repeat;
  }
}

/* Пиксель-арт не должен сглаживаться при масштабировании */
svg.px { shape-rendering: crispEdges; display: block; }

/*
 * Тонкий тёмный контур ровно по силуэту иконки: срабатывает только на
 * прямоугольниках с градиентной заливкой (fill="url(#...)"), а не на
 * плоских полупрозрачных полосах светотени поверх них. Это то, что
 * отделяет предмет от фона и убирает эффект «плоской наклейки».
 */
svg.px rect[fill^='url(#'] {
  stroke: rgba(0, 0, 0, 0.55);
  stroke-width: 0.4;
  paint-order: stroke fill;
}

/* Видимый фокус с клавиатуры. Несколько инпутов глушат системный outline,
   а на тёмном фоне браузерное кольцо и так почти не читается. Именно
   :focus-visible, а не :focus — чтобы обводка не выскакивала на обычный
   клик мышью, но оставалась при навигации табом. Радиус outline берёт
   от самого элемента, поэтому на пилюлях кольцо тоже круглое. */
:focus-visible {
  outline: 2px solid var(--aqua);
  outline-offset: 3px;
}

::selection { background: rgba(167, 139, 250, 0.35); color: #fff; }
::placeholder { color: var(--text-faint); opacity: 1; }
code { font-family: var(--font-mono); font-size: 0.92em; }

/* Ссылка без своего стиля раньше получала синий браузерный цвет — на тёмном
   интерфейсе он выглядел чужим (подсказки в профиле, примечания). Всё, что
   оформлено отдельно (меню, кнопки, подвал), перекрывает это своим цветом. */
a { color: var(--aqua); text-underline-offset: 3px; }

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: var(--bg-deep); }
::-webkit-scrollbar-thumb { background: var(--surface-3); border: 2px solid var(--bg-deep); }
::-webkit-scrollbar-thumb:hover { background: var(--line); }

/* ::-webkit-scrollbar работает только в Chrome/Edge/Safari — Firefox его
   вообще не поддерживает и без этого показывает свой классический
   системный скроллбар с кнопками-стрелками поверх всего кастомного тёмного
   интерфейса. scrollbar-width/-color — то же самое для Firefox. */
* { scrollbar-width: thin; scrollbar-color: var(--surface-3) var(--bg-deep); }

/* ---------- Гранёная форма ---------- */

.facet {
  clip-path: polygon(
    var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)),
    calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut)
  );
}

.facet-sm {
  clip-path: polygon(
    var(--cut-sm) 0, 100% 0, 100% calc(100% - var(--cut-sm)),
    calc(100% - var(--cut-sm)) 100%, 0 100%, 0 var(--cut-sm)
  );
}

/* ---------- Типографика ---------- */

h1, h2, h3, .display {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.15;
}

/* Мелкие подписи — обычным текстом: капс с разрядкой на каждой подписи
   читался как шаблонный дизайн. */
.eyebrow {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-faint);
}

.num { font-variant-numeric: tabular-nums; }

.grad-text { color: var(--aqua); }

/* ---------- Шапка ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 26px;
  padding: 0 22px;
  height: var(--top-h);
  background: rgba(7, 7, 13, 0.45);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; color: var(--text); flex-shrink: 0; }

.brand-logo { height: 42px; width: auto; display: block; }

.brand-name { font-family: var(--font-display); font-weight: 800; font-size: 17px; letter-spacing: 0.13em; }

/* Пункты меню во всю высоту шапки: черта активного раздела лежит на её
   нижней кромке, как закладка, а не висит посередине под словом. */
.nav { display: flex; gap: 2px; align-self: stretch; }

.nav a {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 16px;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-dim);
  text-decoration: none;
  transition: color 0.18s;
}

.nav a svg { opacity: 0.75; transition: opacity 0.18s; flex-shrink: 0; }

/* «Telegram» — последний пункт меню: кнопка, открывает окошко канала (.tg-pop). */
/* Бирюзовой была вся надпись — и спорила с активным разделом: два
   пункта одного цвета. Теперь бирюзовый только значок. */
.nav-tg {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 16px;
  border: 0;
  background: none;
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-dim);
  cursor: pointer;
  transition: color 0.18s;
}
.nav-tg:hover, .nav-tg[aria-expanded='true'] { color: var(--text); }
.nav-tg svg { flex-shrink: 0; color: var(--aqua); }

/* Окошко канала: картинка владельца и «Подписаться». Место задаёт setTgPop(). */
.tg-pop {
  position: fixed;
  z-index: 80;
  width: min(380px, calc(100vw - 24px));
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.5);
}
.tg-pop-art { display: block; line-height: 0; }
.tg-pop-art img { display: block; width: 100%; height: auto; aspect-ratio: 1600 / 893; }
.tg-pop-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px; font-size: 12.5px; color: var(--text-dim); }
.nav a:hover svg, .nav a.active svg { opacity: 1; }

/* На средних экранах место в шапке уходит по очереди: сначала словесная
   часть логотипа (знак W бренд опознаёт и без неё) и лишние отступы меню,
   и только ниже 1240px — подписи пунктов: без них пять иконок читаются
   с трудом, поэтому держим их, пока влезают. Ниже 820px меню прячется
   совсем: там за навигацию отвечает нижняя таб-бара. */
@media (max-width: 1600px) {
  .nav a, .nav-tg { padding: 0 12px; }
  .brand-name { display: none; }
  .topbar { gap: 16px; padding: 0 16px; }
}

@media (max-width: 1240px) {
  .nav a span, .nav-tg span { display: none; }
}

/* Правый кластер шапки: длинный ник (до 16 символов) и крупный баланс
   выталкивали край за экран. Место отдаёт ник — он сжимается многоточием
   ровно настолько, насколько не хватает, а подписи меню и «Пополнить»
   остаются. До 1300px меню плотнее, а у плашки спуска остаются знак и
   глубина без полоски — иначе обычный ник обрезался уже на ноутбуке. */
.profile-link { min-width: 0; flex-shrink: 1; }
.profile-link-name { min-width: 0; max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (min-width: 821px) and (max-width: 1300px) {
  .nav a, .nav-tg { padding: 0 9px; }
  .xp-bar { display: none; }
}

.nav a:hover, .nav a.active { color: var(--text); }

/* Черта на кромке шапки (перекрывает её нижнюю линию). При наведении —
   бледная, у активного раздела — полная. */
.nav a::after {
  content: '';
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: -1px;
  height: 2px;
  border-radius: 2px 2px 0 0;
  background: var(--grad);
  opacity: 0;
  transform: scaleX(0.4);
  transition: opacity 0.2s, transform 0.25s var(--ease-out);
}
.nav a:hover::after { opacity: 0.35; transform: scaleX(1); }
.nav a.active::after { opacity: 1; transform: scaleX(1); }

.bottom-tabbar { display: none; }

.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 10px; min-width: 0; }

/* Все элементы правой части шапки — одной высоты (40px) и с одним
   скруглением: раньше круг, плашки 36–40px и разные радиусы читались как
   случайный набор. */
.telegram-btn, .sound-btn {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--text-dim);
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.telegram-btn:hover, .sound-btn:hover { border-color: var(--aqua); color: #fff; }
.telegram-btn, .sound-btn { cursor: pointer; }
/* Круглая кнопка Telegram в шапке нужна только на телефоне, где меню спрятано. */
@media (min-width: 821px) {
  .telegram-btn { display: none; }
}
.sound-btn[aria-pressed="false"] { color: var(--text-faint); }

.balance {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-family: var(--font-body);
  font-variant-numeric: tabular-nums;
  font-size: 14px;
  font-weight: 700;
}

.xp-badge {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 12px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  /* Это ссылка на страницу уровней, поэтому браузер по умолчанию рисует
     подчёркивание — на чипе оно смотрится как артефакт вёрстки. */
  text-decoration: none;
  color: inherit;
  transition: border-color 0.16s, box-shadow 0.16s;
}

.xp-badge:hover { border-color: var(--aqua); box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.1); }

/* Значок уровня в плашке спуска — блок слоя, на котором игрок (пиксели 1:1). */
.xp-layer { display: grid; flex-shrink: 0; width: 16px; height: 16px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.55); }

/* Глубина — светлым текстом: фиолетовый был вторым акцентом в шапке рядом
   с бирюзовым балансом. Дорожка полоски видна целиком, чтобы заполнение
   читалось как доля пути, а не как случайная чёрточка. */
.xp-lv { font-family: var(--font-body); font-variant-numeric: tabular-nums; font-size: 12px; font-weight: 800; letter-spacing: 0.02em; color: var(--text); white-space: nowrap; }

.xp-bar { width: 44px; height: 4px; border-radius: 999px; background: rgba(255, 255, 255, 0.09); overflow: hidden; flex-shrink: 0; }
.xp-fill { display: block; height: 100%; background: var(--grad); border-radius: inherit; }

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 22px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--line);
  cursor: pointer;
  transition: background 0.18s var(--ease-out), border-color 0.18s, color 0.18s, transform 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out), filter 0.18s;
  white-space: nowrap;
  text-decoration: none;
}

.btn:hover:not(:disabled) {
  background: var(--surface-3);
  border-color: var(--aqua);
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(94, 234, 212, 0.16);
}

/* Нажатие: кнопка проседает обратно и чуть сжимается. Без этого клик
   никак не отзывается, и интерфейс кажется подтормаживающим. */
.btn:active:not(:disabled) {
  transform: translateY(0) scale(0.985);
  box-shadow: none;
  transition-duration: 0.06s;
}

.btn:disabled { opacity: 0.4; cursor: not-allowed; }
/* У выключенной кнопки блик выглядит так, будто она живая и просто не
   реагирует на клик. */
.btn:disabled::after { animation: none; opacity: 0; }

/* Тень — box-shadow, а не filter: drop-shadow. Фильтр растрирует кнопку
   вместе с текстом и перерисовывает её на каждом ховере; на пилюле
   обычной тени достаточно, а текст остаётся чётким. */
.btn-primary {
  position: relative;
  overflow: hidden;
  background: var(--grad);
  border: none;
  color: #06060c;
}

/* background обязателен: .btn:hover красит фон в тёмный surface-3, и без
   переопределения градиент главной кнопки на ховере подменялся тёмной
   заливкой — самая заметная кнопка сайта «гасла» под курсором. */
.btn-primary:hover:not(:disabled) {
  background: var(--aqua-hover);
  transform: translateY(-1px);
  color: #06060c;
}

.btn-primary:active:not(:disabled) {
  background: var(--grad);
  filter: brightness(0.95);
  transform: translateY(0);
}

.btn-lg { padding: 15px 36px; font-size: 15px; }

/* Не хватает осколков: та же кнопка, но говорит, чего не хватает, и ведёт
   к пополнению. Обычная подпись прячется, #cost остаётся в разметке. */
.btn .btn-main, .btn .btn-alt { display: inline-flex; align-items: center; gap: 8px; }
.btn .btn-alt { display: none; flex-direction: column; gap: 3px; line-height: 1.15; }
.btn .btn-alt small { display: inline-flex; align-items: center; gap: 5px; font-family: var(--font-body); font-size: 11.5px; font-weight: 600; opacity: 0.85; }
.btn.is-short .btn-main { display: none; }
.btn.is-short .btn-alt { display: inline-flex; }
.btn-primary.is-short { background: var(--surface-2); color: var(--text); box-shadow: inset 0 0 0 1px rgba(251, 113, 133, 0.5); }
.btn-primary.is-short::after { display: none; }
.btn-primary.is-short:hover:not(:disabled) { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--aqua); color: var(--aqua); transform: none; }
/* Мелкие кнопки (частые пары «Продать/В игру» на плотных карточках) —
   на Unbounded в этом размере слова перестают влезать и переносятся
   криво; здесь читаемость важнее фирменного шрифта. */
.btn-sm { padding: 7px 13px; font-family: var(--font-body); font-size: 12px; font-weight: 600; }
.btn-ghost { background: transparent; }

/* Кнопки с гранёным facet-классом — прямоугольники со скруглением, не
   пилюли: пилюля с градиентом — самый узнаваемый шаблон. Сам facet-класс
   не трогаем, панели/модалки/карточки с ним остаются гранёными. */
.btn.facet, .btn.facet-sm, .social-btn.facet-sm, .balance {
  clip-path: none;
  border-radius: 10px;
}
.xp-badge, .topbar .profile-link { clip-path: none; border-radius: 12px; }
.topbar .profile-link { height: 40px; padding: 0 14px 0 10px; }
/* «Войти» у гостя — той же высоты, что соседняя кнопка звука. */
.topbar-right > .btn-primary { height: 40px; padding: 0 20px; border-radius: 12px; }

/* Баланс и «Пополнить» — одна капсула-кошелёк, а не две соседние пилюли:
   правый угол шапки перестаёт быть рядом из четырёх одинаковых чипов, и
   связь «вот сколько есть → вот где добавить» видна без чтения. */
.wallet {
  display: flex;
  align-items: stretch;
  height: 40px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-2);
  overflow: hidden;
  flex-shrink: 0;
}

.wallet .balance {
  border: 0;
  border-radius: 0;
  background: transparent;
  padding: 0 12px 0 15px;
}

/* «Пополнить» — главное действие шапки, поэтому залито акцентом, как
   «Открыть» на кейсе. Прозрачная половина капсулы терялась рядом с числом. */
.wallet .topup-btn {
  border: 0;
  border-radius: 0;
  background: var(--aqua);
  padding: 0 15px 0 12px;
  color: #06060c;
}

.wallet .topup-btn:hover:not(:disabled) {
  background: var(--aqua-hover);
  color: #06060c;
  transform: none;
  box-shadow: none;
}

.wallet .topup-btn:active:not(:disabled) { transform: none; }

.user-avatar {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--grad);
  color: #06110f;
  font-size: 11px;
  font-weight: 800;
}

/* ---------- Каркас: лента дропов над контентом ---------- */

/* Лента «только что выпало» — полоса под шапкой на всю ширину, а не боковая
   колонка: колонка сдвигала весь контент вправо, и барабан на странице
   кейса стоял не по центру экрана. Контент ограничен по ширине и стоит
   по центру, лента выровнена по его краям. */
.layout { display: block; }

.drop-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  max-width: var(--content-w);
  margin: 0 auto;
  padding: 10px 26px 0;
}

.rail-head {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-shrink: 0;
  width: 78px;
  font-size: 11px;
  line-height: 1.25;
  font-weight: 700;
  color: var(--text-faint);
}

/* Строки ленты лежат в ряд; сколько влезло — столько и видно, край
   растворяется. Прокрутки нет: это витрина активности, а не список. */
.drop-strip {
  display: flex;
  gap: 8px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, #000 88%, transparent);
  mask-image: linear-gradient(90deg, #000 88%, transparent);
}

.drop-strip .drop-empty { padding: 10px 4px; text-align: left; }

.live-dot {
  width: 6px;
  height: 6px;
  background: #34d399;
  border-radius: 50%;
  box-shadow: 0 0 8px #34d399;
  animation: pulse 2s ease-in-out infinite;
}

@keyframes pulse { 50% { opacity: 0.35; } }

.main { max-width: var(--content-w); min-width: 0; margin: 0 auto; padding: 26px 26px 80px; }

.section-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin: 40px 0 18px;
}

.section-head:first-child { margin-top: 0; }
.section-head h2 { font-size: 21px; text-transform: uppercase; letter-spacing: 0.04em; }

/* Капс на Unbounded в 19px на 375px переносил «Задания на сегодня» на две
   строки и ломал строку заголовка. */
@media (max-width: 560px) {
  .section-head { gap: 12px; margin: 32px 0 14px; }
  .section-head h2 { font-size: 16px; }
}
.rule { flex: 1; }

/* ---------- Баннер ---------- */

/* Обёртка нужна только затем, чтобы варден мог вылезать за границы
   баннера (у самого .banner overflow:hidden ради внутренних радиальных
   подсветок) и лежать поверх шапки следующей секции — как маскот на
   dashcase, а не запертым внутри панели. */
.banner-wrap { position: relative; margin-bottom: 22px; }

.banner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 30px;
  padding: 26px 34px;
  margin-bottom: 0;
  background: linear-gradient(180deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line);
  --cut: 20px;
  overflow: hidden;
}

.banner h1 { font-size: clamp(24px, 3vw, 36px); margin-bottom: 12px; }

/* Капс на Unbounded заметно шире строчных, поэтому для заголовка героя
   отдельные размеры и чуть поджатый трекинг — иначе вторая строка
   выпадает за колонку на средних экранах. */
.hero-title {
  text-transform: uppercase;
  font-size: clamp(24px, 2.6vw, 38px);
  letter-spacing: -0.02em;
  line-height: 1.08;
  text-wrap: balance;
}
.banner p { font-size: 14px; color: var(--text-dim); max-width: 48ch; margin-bottom: 18px; }
/* Текстовая колонка не заходит под вардена справа. */
.banner > div { max-width: min(70%, 780px); }
/* Кнопки и логотипы серверов — одной строкой: баннер стал ниже на ряд, и
   витрина поднялась на первый экран. На узкой колонке строка переносится. */
.banner-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 20px; }
.banner-actions { display: flex; gap: 10px; flex-wrap: wrap; }

/* Логотипы серверов под подводкой: то, что в абзаце названо словами,
   узнаётся с одного взгляда — и это единственное в герое, что относится
   к конкретному продукту, а не к жанру. */
.hero-servers { display: flex; gap: 8px; flex-wrap: wrap; }
.hero-server {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px 5px 6px;
  border-radius: 8px;
  background: rgba(7, 7, 13, 0.45);
  border: 1px solid rgba(255, 255, 255, 0.08);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--text-dim);
}
.hero-server img { width: 18px; height: 18px; object-fit: contain; }
/* Логотипы серверов в баннере — кнопки: ведут к полке сервера. */
button.hero-server { font-family: inherit; cursor: pointer; transition: border-color 0.16s, color 0.16s; }
button.hero-server:hover { border-color: var(--aqua); color: #fff; }

.social-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 18px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  transition: border-color 0.16s, color 0.16s;
}

.social-btn:hover { border-color: var(--aqua); color: #fff; }
.social-btn.soon { color: var(--text-faint); cursor: default; }
.social-btn.soon:hover { border-color: var(--line); color: var(--text-faint); }

/* Варден — главный визуал правой половины баннера: на широких экранах
   между текстом и краем панели остаётся много пустого места, поэтому
   держим его крупным и по центру этой зоны, а не мелкой деталью в углу.
   Нависает над стыком баннера и следующей секции — поверх всего
   (z-index выше подложек обеих соседних секций). */
.banner-warden {
  position: absolute;
  left: 80%;
  bottom: -16px;
  /* Баннер стал ниже: крупнее варден вылезал бы над ним под шапку, а
     свисать вниз на ряд плиток с текстом ему нельзя. */
  width: clamp(210px, 19vw, 290px);
  transform: translateX(-50%);
  z-index: 5;
  pointer-events: none;
  filter: drop-shadow(0 24px 30px rgba(0, 0, 0, 0.6)) drop-shadow(0 0 42px rgba(94, 234, 212, 0.32));
}

/* ---------- Живая лента дропов (главная) ---------- */

.ticker-wrap { margin-bottom: 30px; overflow: hidden; background: var(--surface); border: 1px solid var(--line-soft); }

/* Пока слева видна боковая лента, бегущая строка показывает те же самые
   дропы второй раз на том же экране — и отодвигает витрину ещё на сотню
   пикселей. Оставляем её только там, где боковой ленты нет. */
@media (min-width: 1101px) {
  .ticker-wrap { display: none; }
}

.ticker-label {
  padding: 10px 16px 0;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-faint);
}

.ticker-track-outer { overflow: hidden; padding: 10px 0; mask-image: linear-gradient(90deg, transparent, #000 4%, #000 96%, transparent); }

.ticker-track {
  display: flex;
  gap: 10px;
  width: max-content;
  animation: tickerScroll 38s linear infinite;
}

.ticker-wrap:hover .ticker-track { animation-play-state: paused; }

@keyframes tickerScroll { to { transform: translateX(-50%); } }

.ticker-item {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 12px 7px 7px;
  background: linear-gradient(90deg, var(--r-dark), var(--surface-2) 80%);
  border: 1px solid var(--line-soft);
  border-left: 3px solid var(--r);
  border-radius: 10px;
}

.ticker-body { min-width: 0; }
.ticker-name { font-size: 12px; font-weight: 600; white-space: nowrap; max-width: 140px; overflow: hidden; text-overflow: ellipsis; }
.ticker-who { display: flex; align-items: center; max-width: 140px; min-width: 0; font-size: 10px; color: var(--text-faint); }

/* ---------- Ряд «сегодня»: бесплатный кейс и прогресс ---------- */

/* Одна строка над вкладками: бесплатный кейс шире, плитки прогресса — поровну,
   сколько бы их ни было (без коллекции или заданий их меньше). */
.today-strip {
  display: grid;
  grid-auto-flow: column;
  grid-template-columns: minmax(0, 1.5fr);
  grid-auto-columns: minmax(0, 1fr);
  gap: 10px;
  margin-bottom: 24px;
}
.today-strip.is-solo { grid-template-columns: minmax(0, 1fr); }

.daily-block {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 10px 14px 10px 8px;
  background: linear-gradient(120deg, rgba(255, 182, 72, 0.12), rgba(94, 234, 212, 0.05)), var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
}

.daily-block.ready { border-color: rgba(94, 234, 212, 0.55); box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.08); }
.daily-block .btn { flex-shrink: 0; }

/* Сундук чуть выходит за границы плитки (отрицательные отступы): так он
   крупнее, а сама строка не становится выше ради картинки. */
.daily-art {
  height: 62px;
  width: auto;
  flex-shrink: 0;
  margin: -12px 0 -10px;
  filter: drop-shadow(0 8px 14px rgba(0, 0, 0, 0.45));
  pointer-events: none;
}

/* Готовый кейс слегка покачивается и светится золотом — взгляд цепляется
   за движение раньше, чем за текст. */
.daily-block.ready .daily-art {
  filter: drop-shadow(0 10px 20px rgba(247, 185, 85, 0.35));
  animation: dailyFloat 3.6s ease-in-out infinite;
}

/* Пока кейс не готов — тот же сундук, но приглушённый: награда видна,
   но ясно, что сейчас её не взять. */
.daily-block.waiting .daily-art { opacity: 0.45; filter: grayscale(0.5) drop-shadow(0 8px 14px rgba(0, 0, 0, 0.4)); }

@keyframes dailyFloat {
  0%, 100% { transform: translateY(0) rotate(-1.5deg); }
  50% { transform: translateY(-6px) rotate(1.5deg); }
}

.daily-copy { flex: 1; min-width: 0; }
.daily-copy b {
  display: block;
  margin-bottom: 2px;
  font-family: var(--font-display);
  font-size: 13.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.daily-copy > span { display: block; font-size: 11.5px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.daily-copy .mono { color: var(--gold); font-weight: 700; }
.daily-copy .daily-streak { margin-top: 6px; }

.daily-progress { width: 100%; height: 4px; margin-top: 7px; border-radius: 999px; background: rgba(255, 255, 255, 0.08); overflow: hidden; }
.daily-progress span { display: block; height: 100%; background: linear-gradient(90deg, var(--gold), var(--aqua)); transition: width 1s linear; }

.daily-streak { display: flex; gap: 5px; flex-shrink: 0; }
.daily-streak span { width: 9px; height: 9px; border-radius: 50%; background: var(--bg-deep); border: 1px solid var(--line); }
.daily-streak span.on { background: var(--gold); border-color: transparent; box-shadow: 0 0 6px rgba(255, 182, 72, 0.6); }

/* ---------- Вкладки группировки кейсов ---------- */

.case-tabs { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 22px; scroll-margin-top: calc(var(--top-h) + 16px); }

.case-tab {
  padding: 9px 18px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--text-dim);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 0.16s, background 0.16s, color 0.16s;
}

.case-tab:hover:not(.on) { border-color: var(--aqua); color: #fff; }
.case-tab { display: inline-flex; align-items: center; gap: 7px; }
.case-tab img { width: 16px; height: 16px; object-fit: contain; margin-left: -4px; }
.case-section-logo { width: 30px; height: 30px; object-fit: contain; flex-shrink: 0; }

/* Эксклюзивная полка «Древний город»: одна широкая карточка — ящик слева,
   справа название, что это за кейс, цена и замок. Без панели, как .ocase:
   ящик парит на фоне, под ним пятно света в цвете кейса. */
/* Отступ сверху — под выступ рендера: сундук Вардена выше квадрата коробки
   и иначе задевал заголовок «Древний город». */
.excl-row { display: flex; justify-content: center; padding-top: 30px; }

/* Варден — самый ценный кейс витрины, поэтому его сундук крупнее обычных
   карточек полки (300 против ~250px), кадр — тот же квадрат, что у .ocase-art. */
.excl-case {
  display: grid;
  grid-template-columns: 300px 1fr;
  align-items: center;
  gap: 32px;
  width: 100%;
  max-width: 860px;
  padding: 6px 12px;
  text-decoration: none;
  color: inherit;
}

.excl-art { position: relative; aspect-ratio: 1 / 1; }
.excl-case:hover .ocase-crate { transform: scale(1.04) translateY(-3px); }
.excl-case:hover .ocase-glow { opacity: 0.55; }

.excl-body { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.excl-name { font-size: 26px; text-transform: none; letter-spacing: -0.01em; }
.excl-text { font-size: 13.5px; line-height: 1.5; color: var(--text-dim); }
.excl-text b { color: var(--text); font-family: var(--font-body); font-weight: 800; }
.excl-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 10px 16px; margin-top: 4px; }
.excl-case:hover .ocase-price { background: var(--grad); color: #06060c; transform: translateY(-1px); }

/* Строка замка: «до Древнего города ещё N опыта» и полоска пути. */
.excl-lock { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; font-size: 12.5px; color: var(--text-dim); }
.excl-lock svg { flex-shrink: 0; color: var(--aqua); }
.excl-lock b { color: var(--text); font-family: var(--font-body); font-weight: 800; }
.excl-lock .mission-bar { flex-basis: 100%; max-width: 260px; }
.excl-lock.is-compact { font-size: 12px; }

/* Страница эксклюзива без знака: вместо кнопки — замок и цена. */
.case-locked { flex-direction: column; gap: 10px; }
.case-lock {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid rgba(94, 234, 212, 0.22);
  border-radius: var(--radius-sm);
}
.case-lock-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.case-lock-body b { font-size: 13.5px; }
.case-lock-price { font-size: 12.5px; color: var(--text-faint); }
.case-lock-price .num { color: var(--text); font-weight: 800; }

/* Значок сервера у названия — в объединённой секции «Кейсы серверов». */
.ocase-server { width: 18px; height: 18px; object-fit: contain; vertical-align: -3px; margin-right: 6px; }
.case-tab.on { background: var(--grad); color: #06060c; border-color: transparent; }

/* ---------- Топ выигрышей ---------- */

/* По левому краю, как заголовок «Топ недели» над рядом: две карточки
   по центру под левым заголовком висели в пустоте. */
.hof-row { display: flex; gap: 14px; flex-wrap: wrap; justify-content: flex-start; margin-bottom: 44px; }

.hof-card {
  width: 168px;
  text-align: center;
  padding: 20px 14px 16px;
  background: var(--surface);
  border: 1px solid var(--r-line);
  border-radius: var(--radius-sm);
}

.hof-icon { display: flex; justify-content: center; margin-bottom: 8px; }
.hof-name { font-size: 13px; font-weight: 700; margin-bottom: 2px; }
.hof-who { display: flex; justify-content: center; align-items: center; min-width: 0; font-size: 11px; color: var(--text-faint); margin-bottom: 10px; }

/* ---------- Карточка кейса ---------- */

/*
 * Витрина кейсов — как у dashcase: НИКАКИХ панелей и рамок. Категория —
 * это просто центрированный заголовок и ряд карточек, которые сами по
 * себе тоже без фона/рамки — только картинка, название и цена-пилюля
 * прямо на фоне страницы. flex-wrap вместо grid — ключевой момент: он
 * центрирует КАЖДУЮ строку по отдельности (в т.ч. неполную последнюю),
 * тогда как grid держит все строки на одной и той же сетке колонок и
 * центрирует их только как единый блок.
 */
.case-section { margin-bottom: 34px; }
.case-section:last-child { margin-bottom: 0; }

/* Заголовок полки на ступень крупнее названий кейсов: при 19px против
   15,5px полка и карточка почти не различались по весу. Отступ снизу —
   место для метки «Лоу-риск»/«Рисковый», которая стоит над сундуком. */
.case-section-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
  font-size: 21px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: 20px;
}

/* Полка на всю ширину контента, пять кейсов в ряду: раньше ряд был
   ограничен 1100px из 1308, карточки по 196px стояли с промежутками по
   22px, и сундуки читались как разрозненные значки. Ширина карточки
   считается от ряда, поэтому неполный ряд (9 = 5 + 4) остаётся по центру
   с теми же размерами. */
.case-row {
  --case-cols: 5;
  --case-gap: 16px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 26px var(--case-gap);
  margin: 0 auto;
}

.ocase {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: calc((100% - (var(--case-cols) - 1) * var(--case-gap)) / var(--case-cols));
  padding: 0 0 4px;
  text-align: center;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
}

/* Коробка квадратная, а рендер 3:4 стоит на её дне и выходит вверх:
   верхняя четверть рендера — прозрачное поле, сундук занимает нижние
   две трети кадра. Так сундук крупнее при той же ширине, а карточка ниже
   на треть. Выступ картинки не ловит курсор (pointer-events), иначе
   прозрачное поле перекрывало бы цену карточки рядом выше. */
.ocase-art {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 1;
}

.ocase-crate {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  pointer-events: none;
  transform-origin: 50% 80%;
  transition: transform 0.25s var(--ease-out);
}

/* Размытое пятно под ящиком — «лужица» света на полу, а не заливка карточки */
.ocase-glow {
  position: absolute;
  left: 15%;
  bottom: 4px;
  width: 70%;
  height: 40%;
  border-radius: 50%;
  background: var(--glow);
  filter: blur(24px);
  opacity: 0.32;
  transition: opacity 0.25s;
}

.ocase:hover .ocase-glow { opacity: 0.55; }

.ocase:hover .ocase-crate { transform: scale(1.05) translateY(-3px); }

.ocase-name {
  font-family: var(--font-display);
  font-size: 16.5px;
  font-weight: 700;
  line-height: 1.25;
}

/* Цена — маленькая версия кнопки «Открыть»: та же огранка, кромка в
   градиенте бренда, число шрифтом заголовков. Кромка — фон самого
   элемента, тёмная заливка лежит поверх на псевдоэлементе с полигоном
   на пиксель меньше: обычный border не умеет срезанные углы. При
   наведении заливка гаснет и остаётся сплошной градиент, как у главной
   кнопки. */
.ocase-price {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin-top: 4px;
  padding: 10px 22px 10px 17px;
  --pc: 8px;
  clip-path: polygon(var(--pc) 0, 100% 0, 100% calc(100% - var(--pc)), calc(100% - var(--pc)) 100%, 0 100%, 0 var(--pc));
  background: linear-gradient(120deg, rgba(94, 234, 212, 0.8), rgba(167, 139, 250, 0.6));
  font-family: var(--font-display);
  font-variant-numeric: tabular-nums;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--text);
  transition: transform 0.2s var(--ease-out), color 0.2s;
}
.ocase-price::before {
  content: '';
  position: absolute;
  inset: 1px;
  z-index: -1;
  clip-path: polygon(calc(var(--pc) - 1px) 0, 100% 0, 100% calc(100% - var(--pc) + 1px), calc(100% - var(--pc) + 1px) 100%, 0 100%, 0 calc(var(--pc) - 1px));
  background: linear-gradient(180deg, #1f1f3a 0%, #10101f 100%);
  transition: opacity 0.2s;
}
.ocase-price .num { font: inherit; }
.ocase-price img { width: 15px; height: 17px; filter: drop-shadow(0 0 5px rgba(94, 234, 212, 0.75)); transition: filter 0.2s; }

.ocase:hover .ocase-price { background: var(--grad); color: #06060c; transform: translateY(-1px); }
.ocase:hover .ocase-price::before { opacity: 0; }
.ocase:hover .ocase-price img { filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35)); }

/* Характер кейса: лоу-риск — спокойный бирюзовый, рисковый — горячий. */
.kind-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px 3px 7px;
  border-radius: 999px;
  font-family: var(--font-body);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  border: 1px solid transparent;
}
.kind-badge.is-steady { color: #5eead4; background: rgba(94, 234, 212, 0.1); border-color: rgba(94, 234, 212, 0.28); }
.kind-badge.is-risky { color: #ff8f5a; background: rgba(255, 110, 60, 0.12); border-color: rgba(255, 120, 70, 0.34); }
/* На карточке метка лежит на полу под сундуком: у рендера снизу пустая
   полоса ~10 % высоты, где только пятно света. Над названием метка делала
   карточку выше и сдвигала цены в ряду, а в верхнем углу наезжала на
   искры и крышку крупного сундука. */
.ocase .kind-badge {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  z-index: 2;
  background-color: rgba(10, 9, 16, 0.88);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
}
.case-kind { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-top: 6px; font-size: 13px; color: var(--text-dim); }

/* Самый дорогой предмет кейса — то, ради чего его открывают; раньше это
   было видно только внутри. Строка тише названия и цены, но даёт повод
   зайти. */
.ocase-top {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: -2px;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-faint);
}
.ocase-top b { font-family: var(--font-body); font-size: 12px; letter-spacing: 0; color: var(--aqua); font-weight: 800; }
.ocase-top img { width: 11px; height: 13px; }

/* На телефоне карточка 176px с отступом 34px не влезала в ряд по две —
   витрина превращалась в колонку из шестнадцати экранов. Две в ряд
   с картинкой, ужатой по ширине колонки. */
/* Экран 1101–1300: колонка у́же из-за ленты дропов слева, чуть меньшие
   карточки ставят пять кейсов полки в один ряд, без одинокого пятого. */
/* 821–1300: четыре плитки в строку сжимались до нечитаемого — бесплатный
   кейс занимает свою строку, плитки прогресса делят следующую. */
@media (min-width: 821px) and (max-width: 1300px) {
  .today-strip { display: flex; flex-wrap: wrap; }
  .today-strip > * { flex: 1 1 200px; }
  .today-strip > .daily-block { flex-basis: 100%; }
  /* Кнопки и логотипы в одну строку тут не помещаются, а те же логотипы
     стоят во вкладках чуть ниже — баннер не растёт на лишний ряд. */
  .banner .hero-servers { display: none; }
}

/* Колонок меньше по мере сужения: пять до 1000px (полки по пять кейсов
   остаются целыми), дальше четыре, на планшете три, на телефоне две —
   сундук не становится мельче ~150px. */
@media (max-width: 1300px) {
  .case-row { --case-gap: 14px; }
}
@media (max-width: 1000px) {
  .case-row { --case-cols: 4; }
}
@media (max-width: 820px) {
  .case-row { --case-cols: 3; --case-gap: 12px; row-gap: 22px; }
  .ocase-name { font-size: 15px; }
}

@media (max-width: 560px) {
  .case-row { --case-cols: 2; --case-gap: 10px; row-gap: 20px; }
  .ocase-name { font-size: 14px; }
  .ocase-price { font-size: 14px; padding: 9px 18px 9px 14px; }
  .case-section-title { font-size: 16px; margin-bottom: 18px; }
  /* Переключатель периода и подпись «осталось N» вместе в строку заголовка
     не влезают; подпись менее важна — счётчик виден и в самих заданиях. */
  .section-head .tabs-inline + .eyebrow { display: none; }
  /* Счётчик предметов уже есть в плашке над барабаном, а в строку с
     заголовком «Содержимое кейса» на телефоне не влезает. */
  .section-head .item-count { display: none; }
}

/* ---------- Карточка предмета ---------- */

.item-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(152px, 1fr)); gap: 12px; }

.item-card {
  padding: 10px 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  transition: transform 0.18s var(--ease-out), border-color 0.18s, box-shadow 0.18s;
}

.item-card:hover {
  transform: translateY(-3px);
  border-color: var(--r);
  box-shadow: 0 12px 28px -14px var(--r-soft);
}

/* Монограмма сервера в углу плитки: сразу видно, куда придёт привилегия */
.srv {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 5px;
  border-radius: 7px;
  font-family: var(--font-body);
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: #07070d;
  background: var(--sc);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
}

/*
 * Настоящий логотип сервера: без цветной подложки и без собственной тени
 * бейджа — только мягкая тень от самого изображения, чтобы оно читалось
 * на любом фоне плитки, но не выглядело квадратной наклейкой.
 */
.srv-logo {
  background: none;
  box-shadow: none;
  padding: 0;
  min-width: 0;
  width: 26px;
  height: 26px;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.65));
}

.srv-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

/*
 * Плитка-арт. Свечение поднимается СНИЗУ, а не залито сверху-слева —
 * так предмет читается будто подсвечен изнутри карточки, а не просто
 * закрашен цветом редкости. Один и тот же приём мы уже используем
 * в crateArt() для ящиков, здесь — его плоский аналог для предметов.
 */
.item-art {
  position: relative;
  display: grid;
  place-items: center;
  height: 104px;
  margin-bottom: 10px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background:
    radial-gradient(85% 65% at 50% 116%, var(--r-soft), transparent 68%),
    radial-gradient(60% 40% at 50% 18%, rgba(255, 255, 255, 0.07), transparent 70%),
    linear-gradient(180deg, var(--r-dark), #0a0a12 88%);
  border: 1px solid var(--r-line);
}

.item-art .glow { filter: drop-shadow(0 0 14px var(--r-soft)); position: relative; z-index: 1; }

/* Пара мелких искр в углу — недорогой способ оживить плитку, если под
   рукой ещё нет настоящей художественной отрисовки предмета. */
.item-spark {
  position: absolute;
  top: 14px;
  right: 16px;
  width: 5px;
  height: 5px;
  background: var(--r);
  border-radius: 1px;
  transform: rotate(45deg);
  opacity: 0.75;
  box-shadow: -14px 20px 0 -1px var(--r), 6px 30px 0 -2px var(--r);
}

/* Название предмета — Onest, а не Unbounded: широкий дисплейный шрифт в
   11px на плитке 150px ломал слова и утомлял; здесь важнее читаемость. */
.item-name {
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: -0.005em;
  line-height: 1.35;
  min-height: 34px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Итоговая строка карточки: цена — пилюлей со своей монеткой, а не
   текстовым тегом, вырез под неё в плитке больше не нужен */
.item-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: 8px;
  min-width: 0;
}

/* Срок привилегии («30 дней», «Навсегда») — то, за что платят, поэтому
   не 10px, а 11px: мельче он терялся рядом с ценой. */
.item-sub {
  font-size: 11px;
  color: var(--text-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex-shrink: 1;
}

.price-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px 4px 6px;
  border-radius: 999px;
  background: var(--surface-3);
  border: 1px solid var(--line);
  font-family: var(--font-body);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
  color: var(--text);
  white-space: nowrap;
}

.price-pill-sm { padding: 2px 8px 2px 5px; font-size: 10px; }
.price-pill-sm svg { width: 10px; height: 10px; }

/* Действия внутри карточки (инвентарь: продать / в игру), а не строкой
   пилюль под ней — раньше кнопки висели в воздухе между плитками и
   визуально не принадлежали ни одной. */
/* Кнопки друг под другом во всю ширину: в один ряд «Продать 9 999» и
   «Получить» не влезали в карточку шириной ~150px, цена вылезала за край. */
.item-actions {
  display: grid;
  gap: 5px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--line-soft);
}
.item-actions .btn { width: 100%; padding: 7px 8px; font-size: 11.5px; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.item-actions .status-pill { margin: 0 auto; }
.item-grid > .state-block { grid-column: 1 / -1; }

/* ---------- Горизонтальная рулетка ---------- */

/* Окно барабана: скруглённое, с тем же Древним городом внутри, что и фон
   страницы, только темнее и ближе — как будто лента едет по улице города.
   Ячейки непрозрачные, фон виден в зазорах и по краям. Углы без среза. */
.reel-box {
  position: relative;
  isolation: isolate;
  padding: 24px 0;
  /* Древний город внутри окна виднее, чем на странице, поверх него —
     свечение в цвете кейса (--tint приходит от .case-stage) и споры скалка
     (::before), медленно всплывающие вверх. Цвет кейса делает каждое окно
     своим: у Flint бирюзовое, у Dragon Egg фиолетовое. */
  background:
    radial-gradient(70% 150% at 50% 50%, color-mix(in srgb, var(--tint, var(--aqua)) 24%, transparent), transparent 70%),
    linear-gradient(180deg, rgba(7, 7, 13, 0.5), rgba(7, 7, 13, 0.18) 50%, rgba(7, 7, 13, 0.55)),
    url("/assets/brand/deep-city.jpg") center 58% / cover no-repeat,
    var(--bg-deep);
  border: 1px solid color-mix(in srgb, var(--tint, var(--aqua)) 28%, transparent);
  border-radius: 22px;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.04),
    inset 0 0 70px rgba(0, 0, 0, 0.5),
    0 0 40px -12px color-mix(in srgb, var(--tint, var(--aqua)) 45%, transparent),
    0 20px 50px -30px rgba(0, 0, 0, 0.8);
  overflow: hidden;
}

.reel-box::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(circle, rgba(94, 234, 212, 0.95) 0 1px, transparent 1.8px),
    radial-gradient(circle, rgba(94, 234, 212, 0.55) 0 1.4px, transparent 2.4px),
    radial-gradient(circle, rgba(255, 255, 255, 0.5) 0 0.8px, transparent 1.4px);
  background-size: 150px 150px, 260px 260px, 190px 190px;
  background-position: 20px 30px, 90px 110px, 140px 60px;
  opacity: 0.45;
  -webkit-mask-image: linear-gradient(180deg, transparent, #000 25%, #000 75%, transparent);
  mask-image: linear-gradient(180deg, transparent, #000 25%, #000 75%, transparent);
  animation: sporesDrift 48s linear infinite;
}
@keyframes sporesDrift {
  to { background-position: 20px -120px, 90px -150px, 140px -130px; }
}
@media (prefers-reduced-motion: reduce) {
  .reel-box::before { animation: none; }
}


/* ---------- Полноэкранный результат для крупного выигрыша ---------- */

.reel-rows { display: grid; gap: 10px; }

/* ×2…×5 — ряд отдельных барабанов (см. buildRows). У каждого своё окно:
   виден один ряд целиком и края соседних ячеек сверху и снизу, как в
   игровом автомате. Черты через всё окно нет — у каждого барабана своя
   рамка выигрыша, а по бокам ряда две короткие метки на её высоте. Барабаны
   встают по очереди слева направо, соседние ячейки вставшего гаснут. Рамка
   красится цветом редкости, только если предмет окупил свой кейс, иначе
   тоже гаснет: после остановки цветом горит то, что принесло прибыль. */
.reel-box.is-multi { padding: 20px 16px; }
.reel-box.is-multi .reel-rows {
  position: relative;
  z-index: 1;
  grid-template-columns: repeat(var(--cols, 2), var(--col-w, 184px));
  gap: 14px;
  width: fit-content;
  margin: 0 auto;
}
/* Метки ряда: коротко, в языке маркера ленты ×1 — черта с точкой на конце. */
.reel-box.is-multi .reel-rows::before,
.reel-box.is-multi .reel-rows::after {
  content: '';
  position: absolute;
  top: 50%;
  width: 18px;
  height: 9px;
  margin-top: -4.5px;
  background:
    radial-gradient(circle at 4.5px 50%, var(--aqua) 4px, transparent 4.6px),
    linear-gradient(var(--aqua), var(--aqua)) 4px 50% / 14px 3px no-repeat;
  transition: filter 0.15s;
}
.reel-box.is-multi .reel-rows::before { left: -28px; }
.reel-box.is-multi .reel-rows::after { right: -28px; transform: scaleX(-1); }
.reel-box.is-multi .reel-rows.is-hit::before,
.reel-box.is-multi .reel-rows.is-hit::after { filter: brightness(1.5) drop-shadow(0 0 6px var(--aqua)); }
.reel-box.is-multi .reel-marker { display: none; }
.reel-box.is-multi::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(4, 4, 10, 0.45), transparent 22%, transparent 78%, rgba(4, 4, 10, 0.45));
}

.reel-col {
  position: relative;
  padding: 0 6px;
  border-radius: 16px;
  background: rgba(6, 7, 14, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.06);
}
/* Рамка выигрыша — на высоте центральной ячейки. */
.reel-col::after {
  content: '';
  position: absolute;
  z-index: 2;
  left: 2px;
  right: 2px;
  top: 50%;
  height: 148px;
  margin-top: -74px;
  border: 2px solid color-mix(in srgb, var(--aqua) 38%, transparent);
  border-radius: 17px;
  pointer-events: none;
  transition: border-color 0.3s var(--ease-out), box-shadow 0.35s var(--ease-out);
}
.reel-box.is-spinning .reel-col:not(.is-landed)::after { border-color: color-mix(in srgb, var(--aqua) 70%, transparent); }
.reel-col.is-miss::after { border-color: rgba(255, 255, 255, 0.1); }
.reel-col.is-win::after { border-color: var(--r); box-shadow: 0 0 26px -6px var(--r); }
.reel-box.is-multi.is-spinning .reel-col:not(.is-landed) .reel-cell { filter: saturate(0.85) brightness(0.9); }
.reel-col.is-landed .reel-cell { transition: opacity 0.35s var(--ease-out), filter 0.35s var(--ease-out); }
.reel-col.is-landed .reel-cell:not(.is-landed) { opacity: 0.32; filter: saturate(0.5); }
.reel-box.is-multi { transition: box-shadow 0.9s ease-out; }
.reel-box.is-multi.is-flash {
  transition-duration: 0.12s;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.04),
    inset 0 0 70px rgba(0, 0, 0, 0.5),
    0 0 80px -8px var(--flash, var(--aqua)),
    0 20px 50px -30px rgba(0, 0, 0, 0.8);
}
/* Окно барабана: центральная ячейка целиком, соседние — краем и приглушённо. */
.reel-v {
  position: relative;
  height: 250px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.5) 26px, #000 58px, #000 calc(100% - 58px), rgba(0, 0, 0, 0.5) calc(100% - 26px), transparent);
  mask-image: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.5) 26px, #000 58px, #000 calc(100% - 58px), rgba(0, 0, 0, 0.5) calc(100% - 26px), transparent);
}
.reel-v .reel-track { flex-direction: column; align-items: stretch; gap: 6px; left: 0; right: 0; }
.reel-v .reel-cell { width: 100%; }
.reel-col.is-landed { animation: colLand 0.45s var(--ease-out); }
.reel-cell.is-landed { animation: cellLand 0.6s var(--ease-out); }
.reel-col.is-win .reel-cell.is-landed { box-shadow: 0 0 24px var(--r-soft); }
/* В широких окнах (×2, ×3) предмет крупнее — ячейка не пустеет. */
.reel-rows[data-cols="2"] .reel-cell :is(.item-img, .px) { width: 64px; height: 64px; }
.reel-rows[data-cols="3"] .reel-cell :is(.item-img, .px) { width: 54px; height: 54px; }
@keyframes colLand {
  0% { transform: translateY(0); }
  35% { transform: translateY(6px); }
  100% { transform: translateY(0); }
}
@keyframes cellLand {
  0% { transform: scale(1); }
  40% { transform: scale(1.05); }
  100% { transform: scale(1); }
}


.reel-h {
  position: relative;
  height: 138px;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 14%, #000 86%, transparent);
}

.reel-track { display: flex; gap: 8px; position: absolute; left: 0; top: 0; will-change: transform; }

.reel-cell {
  position: relative;
  width: 132px;
  height: 138px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 0 8px;
  text-align: center;
  border-radius: 14px;
  background:
    radial-gradient(90% 70% at 50% 120%, var(--r-soft), transparent 70%),
    linear-gradient(165deg, var(--r-dark), #0a0a12 80%);
  border: 1px solid var(--r-line);
  border-bottom: 3px solid var(--r);
  box-shadow: 0 8px 20px -12px rgba(0, 0, 0, 0.9);
}

.reel-cell .cn {
  font-size: 10px;
  font-weight: 600;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Лента ×1: рамка выигрыша по центру вместо черты поверх предмета, над ней
   указатель — черта с точкой, тот же язык, что метки у барабанов ×2…×5.
   Лента встаёт чуть мимо и доезжает в рамку (SETTLE_MS в app.js); после
   остановки соседние ячейки гаснут, рамка красится цветом редкости, если
   предмет окупил кейс, иначе тоже гаснет. */
.reel-box:not(.is-multi) { padding: 26px 0; }
.reel-marker {
  position: absolute;
  z-index: 5;
  top: 21px;
  left: 50%;
  width: 142px;
  height: 148px;
  margin-left: -71px;
  border: 2px solid color-mix(in srgb, var(--aqua) 38%, transparent);
  border-radius: 17px;
  pointer-events: none;
  transition: border-color 0.3s var(--ease-out), box-shadow 0.35s var(--ease-out);
}
.reel-marker::before {
  content: '';
  position: absolute;
  top: -19px;
  left: 50%;
  width: 9px;
  height: 17px;
  margin-left: -4.5px;
  background:
    radial-gradient(circle at 50% 4.5px, var(--aqua) 4px, transparent 4.6px),
    linear-gradient(var(--aqua), var(--aqua)) 50% 4px / 3px 13px no-repeat;
}
.reel-box.is-spinning .reel-marker { border-color: color-mix(in srgb, var(--aqua) 70%, transparent); }
.reel-marker.is-miss { border-color: rgba(255, 255, 255, 0.1); }
.reel-marker.is-win { border-color: var(--r); box-shadow: 0 0 26px -6px var(--r); }
.reel-box.is-landed .reel-h .reel-cell { transition: opacity 0.35s var(--ease-out), filter 0.35s var(--ease-out); }
.reel-box.is-landed .reel-h .reel-cell:not(.is-landed) { opacity: 0.32; filter: saturate(0.5); }
.reel-h .reel-cell.is-landed { animation: cellLand 0.6s var(--ease-out); }
.reel-box.is-landed:has(.reel-marker.is-win) .reel-h .reel-cell.is-landed { box-shadow: 0 0 24px var(--r-soft); }

.mult-row { display: flex; gap: 6px; margin-bottom: 14px; }

.mult {
  padding: 8px 15px;
  border-radius: 8px;
  font-family: var(--font-body);
  font-variant-numeric: tabular-nums;
  font-size: 12px;
  font-weight: 700;
  background: var(--surface-2);
  border: 1px solid var(--line);
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.16s, background 0.16s, color 0.16s;
}

.mult:hover:not(:disabled) { border-color: var(--aqua); }
.mult.on { background: var(--grad); color: #06060c; border-color: transparent; }
.mult:disabled { opacity: 0.45; cursor: not-allowed; }

/* ---------- Результат ---------- */

.result-wrap { display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; animation: rise 0.45s var(--ease-out) both; }

@keyframes rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }

.result-card {
  position: relative;
  width: 196px;
  padding: 12px 12px 16px;
  text-align: center;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--r);
  box-shadow: 0 0 36px -8px var(--r-soft);
}


/* ---------- Лента дропов ---------- */

.drop-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  width: 196px;
  padding: 8px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--r-dark), var(--surface) 70%);
  border: 1px solid var(--line-soft);
  border-left: 3px solid var(--r);
}

/* Въезжает только свежая строка (см. renderFeed в app.js). Раньше
   анимация висела на каждой строке, и при любой смене страницы вся лента
   заново «прилетала» слева — двадцать строк дёргались на ровном месте. */
.drop-row.is-new { animation: slidein 0.4s var(--ease-out) both; }

@keyframes slidein { from { opacity: 0; transform: translateX(-12px); } to { opacity: 1; transform: none; } }

.drop-row .di { flex-shrink: 0; }
.drop-body { flex: 1; min-width: 0; }
.drop-name { font-size: 11.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Ник обрезается многоточием сам, знак после него — никогда: раньше
   многоточие всей строки съедало знак у длинных ников. */
.drop-who { display: flex; align-items: center; min-width: 0; font-size: 10px; color: var(--text-faint); }
.drop-nick { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- Панели ---------- */

.panel { background: var(--surface); border: 1px solid var(--line-soft); padding: 22px; }

.panel-title {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  margin-bottom: 14px;
  display: flex;
  align-items: center;
  gap: 8px;
}


/* ---------- Профиль ---------- */

.profile-top { display: grid; grid-template-columns: 1.1fr 1fr 1fr; gap: 12px; margin-bottom: 12px; }
.profile-card { display: flex; flex-direction: column; gap: 10px; }
.profile-card .eyebrow { margin: 0; }
.profile-card b { font-size: 16px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Любимый кейс и лучший предмет: крупная картинка на мягком свечении в цвет
   кейса или редкости, фон карточки чуть подкрашен тем же цветом. */
.profile-card.has-glow {
  background:
    radial-gradient(90% 110% at 18% 55%, color-mix(in srgb, var(--glow) 14%, transparent), transparent 65%),
    var(--surface);
  border-color: color-mix(in srgb, var(--glow) 32%, var(--line-soft));
}
.profile-feature.is-glow { flex: 1; align-items: center; gap: 20px; }
.profile-feature-art.is-glow {
  position: relative;
  display: grid;
  place-items: center;
  width: 136px;
  height: 136px;
  flex-shrink: 0;
}
.profile-feature-art.is-glow::before {
  content: '';
  position: absolute;
  inset: -6%;
  border-radius: 50%;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--glow) 45%, transparent), transparent 78%);
  filter: blur(4px);
}
.profile-feature-art.is-glow > * { position: relative; filter: drop-shadow(0 8px 22px color-mix(in srgb, var(--glow) 55%, transparent)); }
.profile-card.has-glow .profile-feature-body b { font-size: 19px; }
@media (max-width: 560px) {
  .profile-feature-art.is-glow { width: 104px; height: 104px; }
}

.profile-identity { display: flex; align-items: center; gap: 12px; }
.profile-avatar-lg { width: 44px; height: 44px; font-size: 17px; }
.profile-sub { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-faint); margin-top: 2px; }
.profile-hint { font-size: 11.5px; color: var(--text-faint); }

.profile-feature { display: flex; align-items: center; gap: 14px; }
.profile-feature-art { flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.profile-feature-body { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; }
.profile-feature-body b { max-width: 100%; }

.profile-stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 10px; margin-bottom: 26px; }

.profile-stat {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
}

.profile-stat .profile-stat-icon { display: none; }
.profile-stat-icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(94, 234, 212, 0.12);
  color: var(--aqua);
}

.profile-stat b { display: block; font-family: var(--font-body); font-variant-numeric: tabular-nums; font-size: 18px; font-weight: 800; }
.profile-stat span { font-size: 11px; color: var(--text-faint); }

/* ---------- Коллекция ---------- */

.coll-panel { display: flex; flex-direction: column; gap: 14px; margin-bottom: 26px; }
.coll-row-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.coll-row-head b { font-size: 12.5px; letter-spacing: 0.04em; }
.coll-row-head span { font-variant-numeric: tabular-nums; font-size: 12px; font-weight: 600; color: var(--text-dim); }
.coll-bar { display: block; height: 6px; border-radius: 999px; background: var(--bg-deep); overflow: hidden; }
.coll-bar i { display: block; height: 100%; background: var(--grad); transition: width 0.5s var(--ease-out); }
.coll-hint { font-size: 11.5px; color: var(--text-faint); margin-top: 2px; }

/* Действия после открытия: главная — «открыть ещё», остальные рядом,
   но визуально тише, чтобы не спорить с ней за клик. */
.result-actions { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 18px; }

/* Кнопки под выигрышем: одного размера, с иконкой, без «мелкого» вида. */
.result-btn { min-width: 172px; padding: 12px 20px; font-size: 12.5px; gap: 9px; background: var(--surface-2); border-color: var(--line); }
.result-btn img { width: 14px; height: 16px; }
.result-btn svg { flex-shrink: 0; }
.result-btn b { font-family: var(--font-body); font-weight: 800; }
.result-btn:hover:not(:disabled) { border-color: var(--aqua); color: var(--aqua); background: var(--surface-2); }
.result-btn.is-ghost { background: transparent; }

/* Инвентарь: сетка предметов в панели — на ней живёт декор вардена. */
.inv-panel { padding: 16px; background: var(--surface); border: 1px solid var(--line-soft); }
.inv-panel .item-grid > .state-block { margin: 0; }

/* ---------- Задания на сегодня ---------- */

.mission-list { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 30px; }

.mission-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  transition: border-color 0.18s, box-shadow 0.18s;
}

/* Выполненное, но не забранное задание светится: награда, до которой
   остался один клик, должна находиться взглядом без чтения. */
.mission-row.is-ready { border-color: var(--aqua); box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.1); }
.mission-row.is-claimed { opacity: 0.5; }

.mission-body { flex: 1; min-width: 0; }
.mission-body b { display: block; font-size: 13px; margin-bottom: 2px; }
.mission-body > span { display: block; font-size: 12px; color: var(--text-faint); }

/* Дорожка светлее фона плитки: на почти чёрной дорожке не было видно,
   сколько пути всего, и 10 % заполнения выглядели как точка. */
.mission-bar { display: block; height: 4px; margin-top: 8px; border-radius: 999px; background: rgba(255, 255, 255, 0.08); overflow: hidden; }
.mission-bar i { display: block; height: 100%; border-radius: inherit; background: var(--grad); transition: width 0.4s var(--ease-out); }

.mission-action { flex-shrink: 0; }
.mission-count { font-variant-numeric: tabular-nums; font-size: 12px; font-weight: 600; color: var(--text-dim); }
.mission-done { font-size: 11.5px; font-weight: 600; color: var(--aqua); }

/* ---------- Полоса прогресса: уровень, коллекция, серия ---------- */

.prog-tile {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  text-decoration: none;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: border-color 0.18s, transform 0.18s var(--ease-out);
}
.prog-tile:hover { border-color: var(--line); transform: translateY(-1px); }
.prog-tile:focus-visible { outline: 2px solid var(--aqua); outline-offset: 2px; }
/* Есть что забрать — плитка подсвечена, как готовое задание. */
.prog-tile.is-ready { border-color: rgba(94, 234, 212, 0.55); }
.prog-tile .profile-stat-icon { width: 34px; height: 34px; }
/* Пиксельные значки плиток — на тёмной ячейке, как предмет в слоте. */
.prog-tile .profile-stat-icon:has(.px-art, .ore-icon) { width: 44px; height: 44px; border-radius: 8px; background: #0a0b14; box-shadow: inset 0 0 0 1px var(--line-soft); }
.prog-tile .profile-stat-icon .ore-icon { width: 32px; height: 32px; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6); }
.prog-body { flex: 1; min-width: 0; }
.prog-body b { display: block; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prog-body > span { display: block; font-size: 12px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prog-body .mission-bar { margin-top: 7px; }
.prog-body .daily-streak { margin-top: 8px; }

/* ---------- Состояния: пусто / ошибка / 404 ---------- */

.state-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 64px 20px;
}

.state-icon {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(94, 234, 212, 0.1);
  color: var(--aqua);
}

.state-icon svg { width: 26px; height: 26px; }
.state-block h2 { font-size: 19px; }
.state-block p { font-size: 13.5px; color: var(--text-dim); max-width: 42ch; }
.state-block .btn { margin-top: 6px; }

/* ---------- Спуск ----------
 *
 * Разрез шахты: полосы слоёв одинаковой высоты, жилы на стенах, ствол,
 * прокопанный до текущей глубины, и туман ниже. Цвета слоёв — материалы
 * Minecraft, приглушённые до тёмной палитры сайта; чем глубже, тем больше
 * в разрезе собственного аква-фиолетового цвета сайта: Глубокая тьма —
 * это и есть бренд.
 */

/* Справа от разреза — «где я» и «что сегодня»: они по высоте как раз
   равны разрезу. Лестница перков — ниже на всю ширину, иначе пять
   карточек в правой колонке сжимались до нечитаемых. */
.descent {
  display: grid;
  grid-template-columns: 300px minmax(0, 1fr);
  grid-template-areas: 'shaft card' 'shaft today' 'more more';
  grid-template-rows: auto 1fr auto;
  gap: 18px 20px;
  align-items: start;
}
.descent > .depth-card { grid-area: card; }
.descent > .shaft { grid-area: shaft; }
.descent > .today-block { grid-area: today; }
.descent > .descent-more { grid-area: more; display: flex; flex-direction: column; gap: 12px; }

/* ----- разрез ----- */

.shaft {
  --band-h: 88px;
  --cut: 14px;
  /* Колонка справа под подписи слоёв: линия и находки её не занимают. */
  --label-w: 86px;
  position: relative;
  border: 1px solid var(--line-soft);
  background: var(--bg-deep);
  overflow: hidden;
}

.shaft-strata { display: flex; flex-direction: column; }

.stratum {
  position: relative;
  height: var(--band-h);
  background-color: var(--st, #26272f);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' shape-rendering='crispEdges'%3E%3Crect x='2' y='3' width='1' height='1' fill='%23fff' fill-opacity='.05'/%3E%3Crect x='11' y='1' width='1' height='1' fill='%23000' fill-opacity='.25'/%3E%3Crect x='6' y='9' width='2' height='1' fill='%23fff' fill-opacity='.04'/%3E%3Crect x='13' y='12' width='1' height='1' fill='%23000' fill-opacity='.3'/%3E%3Crect x='3' y='13' width='1' height='1' fill='%23000' fill-opacity='.22'/%3E%3Crect x='9' y='6' width='1' height='1' fill='%23fff' fill-opacity='.06'/%3E%3C/svg%3E"), linear-gradient(180deg, rgba(255, 255, 255, 0.035), transparent 60%);
  background-size: 24px 24px, auto;
  image-rendering: pixelated;
  box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.45);
}
.stratum-surface { --st: #3a2f25; }
.stratum-surface::before { content: ''; position: absolute; inset: 0 0 auto; height: 5px; background: #4d7a36; box-shadow: 0 2px 0 #3b5d2a; }
.stratum-caves { --st: #33353c; }
.stratum-deepslate { --st: #24252c; }
.stratum-deepdark { --st: #0c2226; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' shape-rendering='crispEdges'%3E%3Crect x='6' y='9' width='2' height='2' fill='%235eead4' fill-opacity='.55'/%3E%3Crect x='27' y='4' width='1' height='1' fill='%235eead4' fill-opacity='.7'/%3E%3Crect x='19' y='24' width='2' height='1' fill='%235eead4' fill-opacity='.45'/%3E%3Crect x='33' y='31' width='1' height='2' fill='%235eead4' fill-opacity='.6'/%3E%3Crect x='10' y='33' width='1' height='1' fill='%235eead4' fill-opacity='.5'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' shape-rendering='crispEdges'%3E%3Crect x='2' y='3' width='1' height='1' fill='%23fff' fill-opacity='.05'/%3E%3Crect x='11' y='1' width='1' height='1' fill='%23000' fill-opacity='.25'/%3E%3Crect x='6' y='9' width='2' height='1' fill='%23fff' fill-opacity='.04'/%3E%3Crect x='13' y='12' width='1' height='1' fill='%23000' fill-opacity='.3'/%3E%3Crect x='3' y='13' width='1' height='1' fill='%23000' fill-opacity='.22'/%3E%3Crect x='9' y='6' width='1' height='1' fill='%23fff' fill-opacity='.06'/%3E%3C/svg%3E"); background-size: 40px 40px, 24px 24px; }
.stratum-city { --st: #121628; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' shape-rendering='crispEdges'%3E%3Crect x='6' y='9' width='2' height='2' fill='%237dd3fc' fill-opacity='.55'/%3E%3Crect x='27' y='4' width='1' height='1' fill='%237dd3fc' fill-opacity='.7'/%3E%3Crect x='19' y='24' width='2' height='1' fill='%237dd3fc' fill-opacity='.45'/%3E%3Crect x='33' y='31' width='1' height='2' fill='%237dd3fc' fill-opacity='.6'/%3E%3Crect x='10' y='33' width='1' height='1' fill='%237dd3fc' fill-opacity='.5'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' shape-rendering='crispEdges'%3E%3Crect x='2' y='3' width='1' height='1' fill='%23fff' fill-opacity='.05'/%3E%3Crect x='11' y='1' width='1' height='1' fill='%23000' fill-opacity='.25'/%3E%3Crect x='6' y='9' width='2' height='1' fill='%23fff' fill-opacity='.04'/%3E%3Crect x='13' y='12' width='1' height='1' fill='%23000' fill-opacity='.3'/%3E%3Crect x='3' y='13' width='1' height='1' fill='%23000' fill-opacity='.22'/%3E%3Crect x='9' y='6' width='1' height='1' fill='%23fff' fill-opacity='.06'/%3E%3C/svg%3E"); background-size: 40px 40px, 24px 24px; }
.stratum-void { --st: #07060e; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' shape-rendering='crispEdges'%3E%3Crect x='6' y='9' width='2' height='2' fill='%23a78bfa' fill-opacity='.55'/%3E%3Crect x='27' y='4' width='1' height='1' fill='%23a78bfa' fill-opacity='.7'/%3E%3Crect x='19' y='24' width='2' height='1' fill='%23a78bfa' fill-opacity='.45'/%3E%3Crect x='33' y='31' width='1' height='2' fill='%23a78bfa' fill-opacity='.6'/%3E%3Crect x='10' y='33' width='1' height='1' fill='%23a78bfa' fill-opacity='.5'/%3E%3C/svg%3E"); background-size: 40px 40px; }

/* Подпись слоя — в своей колонке справа, по центру полосы: раньше она
   лежала в углу и перекрывалась находками и маркером игрока. */
.stratum-name {
  position: absolute;
  top: 50%;
  right: 8px;
  width: calc(var(--label-w) - 12px);
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  text-align: right;
  font-size: 10px;
  font-weight: 800;
  line-height: 1.25;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgba(237, 238, 247, 0.62);
  text-shadow: 0 1px 0 #000;
  pointer-events: none;
}
.stratum-name small { font-size: 10px; font-weight: 600; letter-spacing: 0; text-transform: none; color: rgba(237, 238, 247, 0.4); font-variant-numeric: tabular-nums; }
.stratum.is-current .stratum-name { color: var(--text); }

/* Всё, что зависит от позиции игрока, считается от одной пары переменных
   на .shaft-map: номер полосы и доля внутри неё. */
.shaft-map { position: absolute; inset: 0 var(--label-w) 0 0; --y: calc((var(--band) + var(--t)) * var(--band-h)); }

.shaft-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  margin-left: -1px;
  background: repeating-linear-gradient(180deg, rgba(255, 255, 255, 0.16) 0 4px, transparent 4px 9px);
}

.shaft-dug {
  position: absolute;
  top: 0;
  left: 50%;
  width: 4px;
  margin-left: -2px;
  height: var(--y);
  border-radius: 0 0 2px 2px;
  background: linear-gradient(180deg, rgba(94, 234, 212, 0.55), var(--aqua) 60%, var(--violet));
  box-shadow: 0 0 10px rgba(94, 234, 212, 0.35);
}

.shaft-fog {
  position: absolute;
  left: 0;
  /* Туман накрывает и колонку подписей — иначе справа оставался светлый столбик. */
  right: calc(-1 * var(--label-w));
  bottom: 0;
  top: var(--y);
  background: linear-gradient(180deg, rgba(4, 4, 10, 0.15), rgba(4, 4, 10, 0.58) 56px);
  pointer-events: none;
}

.shaft-veins { list-style: none; }

.vein {
  --vy: calc((var(--band) + var(--t)) * var(--band-h));
  position: absolute;
  top: var(--vy);
  display: flex;
  align-items: center;
  gap: 6px;
  transform: translateY(-50%);
  z-index: 2;
}
.vein-l { right: calc(50% + 12px); flex-direction: row-reverse; }
.vein-r { left: calc(50% + 12px); }
.vein-mid { left: 50%; transform: translate(-50%, -50%); z-index: 3; }

.vein-icon {
  position: relative;
  display: grid;
  place-items: center;
  line-height: 0;
  border: 1px solid rgba(0, 0, 0, 0.7);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5), inset 0 0 0 1px rgba(255, 255, 255, 0.06);
  transition: box-shadow 0.25s, opacity 0.25s, filter 0.25s;
}
.ore-icon { display: block; }

.vein-tag {
  font-size: 11px;
  font-weight: 700;
  color: var(--text-dim);
  white-space: nowrap;
  text-shadow: 0 1px 0 #000;
}

.vein.is-claimed .vein-icon { opacity: 0.5; filter: saturate(0.6); }
.vein.is-claimed .vein-tag { color: var(--text-faint); text-decoration: line-through; text-decoration-color: rgba(116, 118, 154, 0.6); }
.vein.is-claimed .vein-icon::after {
  content: '';
  position: absolute;
  right: -5px;
  bottom: -5px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--aqua) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 6.2 5 8l4-4.2' fill='none' stroke='%2306060c' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/9px no-repeat;
}

.vein.is-ready .vein-icon { box-shadow: 0 0 0 2px var(--aqua), 0 0 16px rgba(94, 234, 212, 0.5); animation: veinReady 2.6s ease-in-out infinite; }
.vein.is-ready .vein-tag { color: var(--aqua); }
.vein.is-next .vein-icon { outline: 1px dashed rgba(237, 238, 247, 0.55); outline-offset: 3px; }
.vein.is-next .vein-tag { color: var(--text); }
.vein.is-future .vein-icon { filter: saturate(0.5) brightness(0.8); }
.vein.is-future .vein-tag { color: rgba(155, 156, 186, 0.65); }

@keyframes veinReady {
  0%, 100% { box-shadow: 0 0 0 2px var(--aqua), 0 0 10px rgba(94, 234, 212, 0.35); }
  50% { box-shadow: 0 0 0 2px var(--aqua), 0 0 20px rgba(94, 234, 212, 0.65); }
}

/* Только что забранная находка: блок «откалывается» и встаёт на место. */
.vein.is-just .vein-icon { animation: veinPop 0.62s var(--ease-out) both; animation-delay: calc(var(--k) * 70ms); }
@keyframes veinPop {
  0% { transform: scale(1); filter: brightness(1.8); }
  35% { transform: scale(1.35) rotate(-6deg); filter: brightness(1.6); }
  100% { transform: scale(1); }
}

.shaft-marker {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--y);
  height: 0;
  border-top: 1px solid rgba(94, 234, 212, 0.75);
  box-shadow: 0 0 10px rgba(94, 234, 212, 0.45);
  z-index: 4;
  pointer-events: none;
}
/* Плашка с глубиной — над головой на линии: слева она перекрывала теги находок. */
.shaft-you {
  position: absolute;
  left: 50%;
  top: -36px;
  transform: translateX(-50%);
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(7, 7, 13, 0.92);
  border: 1px solid rgba(94, 234, 212, 0.55);
  font-size: 11px;
  font-weight: 800;
  color: var(--aqua);
}
.shaft-head {
  position: absolute;
  left: 50%;
  top: -11px;
  width: 22px;
  height: 22px;
  margin-left: -11px;
  font-size: 11px;
  box-shadow: 0 0 0 2px var(--bg-deep), 0 0 14px rgba(94, 234, 212, 0.6);
}

/* Вход на страницу: ствол прокапывается сверху до текущей глубины. */
.shaft.is-intro .shaft-dug { animation: shaftDig 1.1s var(--ease-out) both; }
.shaft.is-intro .shaft-fog { animation: shaftFog 1.1s var(--ease-out) both; }
.shaft.is-intro .shaft-marker { animation: shaftMarker 1.1s var(--ease-out) both; }
@keyframes shaftDig { from { height: 0; } }
@keyframes shaftFog { from { top: 0; } }
@keyframes shaftMarker { from { top: 0; opacity: 0; } 20% { opacity: 1; } }

/* ----- карточка глубины ----- */

.depth-card {
  --cut: 18px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 22px 24px;
  border: 1px solid var(--line-soft);
  background:
    radial-gradient(70% 120% at 100% 0%, var(--tint, rgba(94, 234, 212, 0.12)), transparent 60%),
    var(--surface);
}
.stratum-tint-surface, .stratum-tint-caves { --tint: rgba(155, 156, 186, 0.1); }
.stratum-tint-deepslate { --tint: rgba(125, 211, 252, 0.09); }
.stratum-tint-deepdark { --tint: rgba(94, 234, 212, 0.16); }
.stratum-tint-city { --tint: rgba(125, 211, 252, 0.16); }
.stratum-tint-void { --tint: rgba(167, 139, 250, 0.2); }

.depth-now { display: flex; align-items: baseline; gap: 14px; flex-wrap: wrap; }
.depth-y { font-family: var(--font-display); font-size: 40px; font-weight: 800; line-height: 1; letter-spacing: -0.02em; }
.depth-layer { font-size: 16px; font-weight: 700; color: var(--text-dim); }

.depth-next { display: flex; align-items: center; gap: 14px; }
.depth-next-icon { flex-shrink: 0; line-height: 0; border: 1px solid rgba(0, 0, 0, 0.7); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5); }
.depth-next-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.depth-next-body b { font-size: 14px; }
.depth-next-body > span:not(.depth-bar-row) { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; color: var(--text-dim); }
/* Главная полоска сайта — путь к следующей находке. Толще остальных,
   с видимой дорожкой и долей в процентах справа; при заходе на страницу
   заполняется слева направо — видно, сколько уже пройдено. */
.depth-bar-row { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.depth-bar { display: block; flex: 1; height: 8px; border-radius: 999px; background: rgba(255, 255, 255, 0.08); overflow: hidden; }
.depth-bar i {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--grad);
  transform-origin: left center;
  transition: width 0.6s var(--ease-out);
  animation: barFill 0.9s var(--ease-out) 0.15s both;
}
.depth-next-body .depth-pct { flex-shrink: 0; min-width: 3ch; font-size: 13px; font-weight: 800; color: var(--aqua); text-align: right; }
@keyframes barFill { from { transform: scaleX(0); } }

.depth-claim {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, rgba(94, 234, 212, 0.1), rgba(167, 139, 250, 0.06));
  border: 1px solid rgba(94, 234, 212, 0.35);
}
.depth-claim b { display: block; font-size: 14px; }
.depth-claim span { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; color: var(--text-dim); }

.depth-got {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: rgba(94, 234, 212, 0.07);
  border: 1px solid rgba(94, 234, 212, 0.25);
  animation: rise 0.4s var(--ease-out) both;
}
.depth-got > b { display: inline-flex; align-items: center; gap: 5px; font-size: 15px; color: var(--aqua); }
.depth-got-items { display: flex; flex-direction: column; gap: 6px; }
.depth-got-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 10px 6px 6px;
  border-radius: 10px;
  background: linear-gradient(90deg, var(--r-dark), var(--surface) 80%);
  border-left: 3px solid var(--r);
}
.depth-got-item b { display: block; font-size: 13px; }
.depth-got-item small { font-size: 11.5px; color: var(--text-faint); }

.depth-note { font-size: 12.5px; line-height: 1.5; color: var(--text-dim); padding: 10px 12px; border-radius: var(--radius-sm); background: var(--bg-deep); border-left: 2px solid var(--gold); }
.depth-total { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; font-size: 12px; color: var(--text-faint); }

/* ----- перки и «каждый день» ----- */

/* Подзаголовки страницы спуска («Каждый день», «Бонусы по пути») — тем же
   шрифтом, но светлее и на ступень крупнее: бледные 14px читались как подпись. */
.descent-h { font-size: 15px; color: var(--text); margin-bottom: 12px; }

.perk-track { list-style: none; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.perk {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 12px 12px 11px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  min-width: 0;
}
.perk-block { line-height: 0; margin-bottom: 4px; }
.perk-block .ore-icon { border: 1px solid rgba(0, 0, 0, 0.7); }
.perk b { font-size: 12.5px; line-height: 1.3; }
.perk span { font-size: 12px; line-height: 1.35; color: var(--text-dim); }
.perk em { margin-top: auto; padding-top: 6px; font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.perk.is-open { border-color: rgba(94, 234, 212, 0.3); }
.perk.is-open em { color: var(--aqua); }
.perk.is-next { border-color: rgba(167, 139, 250, 0.45); background: linear-gradient(180deg, rgba(167, 139, 250, 0.08), var(--surface) 70%); }
.perk.is-next em { color: var(--violet); }
.perk.is-locked { opacity: 0.62; }

.today-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.today-tile {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 14px;
  border-radius: var(--radius-sm);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  min-width: 0;
}
.today-tile.is-locked { opacity: 0.7; }
.today-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.today-head b { font-size: 13px; }
.today-head > span { font-size: 12px; font-weight: 700; color: var(--text-dim); white-space: nowrap; }
.today-sub { font-size: 12px; line-height: 1.45; color: var(--text-dim); }
.today-tile .btn { align-self: flex-start; margin-top: auto; }
.today-tile .mission-bar { margin-top: 0; }

/* Три шага наверху: что такое спуск и чем по нему двигаться. */

.depth-cta { align-self: flex-start; }
.today-sub img, .perk span img, .prog-body > span img { vertical-align: -3px; }
.perk-mark { filter: grayscale(1) brightness(0.8); }
.perk.is-open .perk-mark, .perk.is-next .perk-mark { filter: drop-shadow(0 0 6px rgba(94, 234, 212, 0.7)); }

/* ----- знаки и подписи в других местах ----- */

/* ----- знак Вардена ----- */

.warden-mark { display: inline-flex; flex-shrink: 0; margin-left: 4px; line-height: 0; vertical-align: -2px; }
.warden-mark img { display: block; filter: drop-shadow(0 0 4px rgba(94, 234, 212, 0.65)); transition: transform 0.2s var(--ease-out), filter 0.2s; }
a.warden-mark:hover img, a.warden-mark:focus-visible img { transform: scale(1.25); filter: drop-shadow(0 0 7px rgba(94, 234, 212, 0.95)) brightness(1.15); }

/* Строка игрока со знаком чуть заметнее остальных: тонкая аква-кромка и
   светлее ник. Ровно настолько, чтобы глаз цеплялся, но строка не спорила
   с редкостью предмета. */
.drop-row.has-mark { box-shadow: inset 0 0 0 1px rgba(94, 234, 212, 0.16); background: linear-gradient(90deg, var(--r-dark), var(--surface) 62%, rgba(94, 234, 212, 0.07)); }
.drop-row.has-mark .drop-nick, .ticker-item.has-mark .drop-nick { color: #a9eee5; }
.drop-row.is-new.has-mark .warden-mark img { animation: markFlash 1.4s var(--ease-out) both; }
@keyframes markFlash {
  0% { transform: scale(0.4); filter: drop-shadow(0 0 0 rgba(94, 234, 212, 0)) brightness(2); }
  40% { transform: scale(1.5); filter: drop-shadow(0 0 10px rgba(94, 234, 212, 1)) brightness(1.4); }
  100% { transform: scale(1); }
}

/* Карточка знака — в правом конце ленты дропов. */
/* Строка «До Древнего города ещё N опыта» в одну строку: переносом на
   третью строку карточка становилась выше строк ленты рядом. */
.rail-mark-slot { flex-shrink: 0; max-width: 280px; }
.rail-mark-slot:empty { display: none; }
.rail-mark {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, rgba(94, 234, 212, 0.09), rgba(167, 139, 250, 0.06)), var(--surface);
  border: 1px solid rgba(94, 234, 212, 0.22);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.2s, transform 0.2s var(--ease-out);
}
.rail-mark:hover { border-color: rgba(94, 234, 212, 0.55); transform: translateY(-1px); }
.rail-mark-icon { flex-shrink: 0; line-height: 0; }
.rail-mark-icon img { filter: grayscale(0.55) brightness(0.85) drop-shadow(0 0 6px rgba(94, 234, 212, 0.35)); transition: filter 0.25s; }
.rail-mark:hover .rail-mark-icon img { filter: drop-shadow(0 0 9px rgba(94, 234, 212, 0.85)); }
.rail-mark-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.rail-mark-body b { font-size: 12px; }
.rail-mark-body small { font-size: 10.5px; line-height: 1.35; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rail-mark-body .mission-bar { margin-top: 3px; }

/* Профиль: знак у ника и строка статуса знака. */
.profile-name { min-width: 0; }
.profile-name b { display: flex; align-items: center; }
.mark-status {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--bg-deep);
  border: 1px solid var(--line-soft);
  color: inherit;
  text-decoration: none;
  transition: border-color 0.2s;
}
.mark-status:hover { border-color: var(--line); }
.mark-status-icon { flex-shrink: 0; line-height: 0; }
.mark-status-icon img { filter: grayscale(1) brightness(0.55); opacity: 0.75; }
.mark-status.is-earned { border-color: rgba(94, 234, 212, 0.35); background: linear-gradient(135deg, rgba(94, 234, 212, 0.1), rgba(167, 139, 250, 0.06)); }
.mark-status.is-earned .mark-status-icon img { filter: drop-shadow(0 0 8px rgba(94, 234, 212, 0.75)); opacity: 1; }
.mark-status-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.profile-card .mark-status-body b { font-size: 13px; white-space: normal; }
.mark-status-body > span:not(.mission-bar) { font-size: 11.5px; line-height: 1.4; color: var(--text-dim); }
.mark-status-body .mission-bar { margin-top: 4px; }

/* В шапке знак сидит в углу аватара: места не занимает, и длинный ник
   не выталкивает его за край экрана. */
.profile-link .user-avatar { position: relative; }
.avatar-mark {
  /* На широком экране знак уже горит в плашке спуска рядом; в углу аватара
     он нужен только на телефоне, где плашка скрыта. */
  display: none;
  position: absolute;
  right: -6px;
  bottom: -5px;
  width: 12px;
  height: 12px;
  filter: drop-shadow(0 0 1px #000) drop-shadow(0 0 4px rgba(94, 234, 212, 0.8));
}
.xp-badge { position: relative; }
.depth-dot {
  position: absolute;
  top: 3px;
  right: 3px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--aqua);
  box-shadow: 0 0 0 2px var(--bg), 0 0 8px rgba(94, 234, 212, 0.8);
}

.result-xp { color: var(--violet); }

@media (max-width: 820px) {
  .descent { grid-template-columns: 1fr; grid-template-areas: 'card' 'shaft' 'today' 'more'; grid-template-rows: none; }
  .shaft { --band-h: 80px; }
  .depth-card { padding: 18px; }
  .depth-y { font-size: 34px; }
  .perk-track { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .perk-track .perk:last-child { grid-column: 1 / -1; }
  .today-grid { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .shaft.is-intro .shaft-dug, .shaft.is-intro .shaft-fog, .shaft.is-intro .shaft-marker,
  .vein.is-ready .vein-icon, .vein.is-just .vein-icon, .depth-got, .depth-bar i,
  .drop-row.is-new.has-mark .warden-mark img { animation: none; }
}

/* ---------- Апгрейд ---------- */

/* ---------- Апгрейд: доска ---------- */

/* Слева ставка, в центре колесо с кнопкой, справа цель — три слота одним
   рядом, как на привычных апгрейдерах. Списки, из которых выбирают, лежат
   ниже и всегда открыты (.upg-panels). */
.upg-board { display: grid; grid-template-columns: minmax(0, 1fr) minmax(320px, 400px) minmax(0, 1fr); gap: 14px; align-items: stretch; }

.upg-slot {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  padding: 16px 18px 18px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
}
.upg-slot-head { display: flex; align-items: center; gap: 10px; min-height: 32px; }
.upg-slot-head b { font-family: var(--font-display); font-size: 14px; }
.upg-slot-head .btn { margin-left: auto; }
.side-sum { display: inline-flex; align-items: center; gap: 5px; font-size: 14px; font-weight: 800; color: var(--aqua); }

/* Само «окно» слота: выбранное лежит на тёмном поле, как в ячейке сундука. */
.upg-slot-body {
  flex: 1;
  min-height: 232px;
  max-height: 420px;
  padding: 10px;
  overflow-y: auto;
  border-radius: var(--radius-sm);
  background: radial-gradient(120% 140% at 50% -10%, rgba(94, 234, 212, 0.05), transparent 60%), var(--bg-deep);
  border: 1px solid var(--line-soft);
}
.upg-slot-body.is-stake { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 8px; align-content: start; }
.upg-slot-body.is-target { display: grid; place-items: center; }
.upg-slot-body.is-empty { display: grid; grid-template-columns: 1fr; place-content: center; place-items: center; }
.upg-slot-body.locked { pointer-events: none; opacity: 0.55; }

.upg-empty { display: flex; flex-direction: column; align-items: center; gap: 12px; max-width: 250px; padding: 12px; text-align: center; text-wrap: balance; }
.upg-empty span { font-family: var(--font-display); font-size: 15px; font-weight: 700; line-height: 1.4; color: var(--text); }

/* Предмет в ставке: плитка с крестиком — по клику уходит обратно в инвентарь. */
.upg-pick {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px 8px;
  border-radius: 10px;
  background: linear-gradient(180deg, var(--r-dark), #0a0a12 88%);
  border: 1px solid var(--r-line);
  color: var(--text);
  font-family: var(--font-body);
  cursor: pointer;
  animation: rise 0.25s var(--ease-out) both;
  transition: border-color 0.15s, transform 0.15s var(--ease-out);
}
.upg-pick:hover { border-color: var(--rose); transform: translateY(-2px); }
.upg-pick-art { display: grid; place-items: center; }
.upg-pick-name { font-size: 11.5px; font-weight: 700; line-height: 1.25; text-align: center; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.upg-pick i { position: absolute; top: 3px; right: 6px; font-style: normal; font-size: 14px; line-height: 1; color: var(--text-faint); }
.upg-pick:hover i { color: var(--rose); }

/* Цель — крупно по центру слота: это то, ради чего всё затевается. */
.upg-target { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 6px; text-align: center; animation: rise 0.25s var(--ease-out) both; }
.upg-target-art {
  position: relative;
  display: grid;
  place-items: center;
  width: 96px;
  height: 96px;
  border-radius: 12px;
  background: linear-gradient(180deg, var(--r-dark), #0a0a12 88%);
  border: 1px solid var(--r-line);
  box-shadow: 0 16px 34px -18px var(--r-soft);
}
.upg-target-art .srv { top: -6px; left: -6px; }
.upg-target b { font-size: 14px; line-height: 1.3; }
.target-sub { font-size: 11px; font-weight: 500; color: var(--text-faint); }

/* Центр доски: сцена с колесом. */
.upg-core {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 18px 20px 20px;
  background:
    radial-gradient(70% 55% at 50% 42%, rgba(94, 234, 212, 0.08), transparent 70%),
    radial-gradient(60% 40% at 50% 100%, rgba(167, 139, 250, 0.1), transparent 70%),
    var(--surface);
  border: 1px solid var(--line-soft);
  --cut: 16px;
}
.upg-core > :not(.stage-sculk) { position: relative; z-index: 1; }

/* Сколк вардена ползёт по сцене от краёв: плитка текстуры из игры без
   сглаживания и радиальная маска — в центре, под кольцом, чисто. */
.stage-sculk {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: url(/assets/warden/vein.png) 0 0 / 48px 48px repeat;
  image-rendering: pixelated;
  opacity: 0.32;
  -webkit-mask-image: radial-gradient(ellipse 62% 58% at 50% 46%, transparent 55%, #000 100%);
  mask-image: radial-gradient(ellipse 62% 58% at 50% 46%, transparent 55%, #000 100%);
  pointer-events: none;
}

@media (max-width: 1180px) {
  /* Колесо шире всего — уводим его в отдельную строку над слотами. */
  .upg-board { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .upg-core { grid-column: 1 / -1; order: -1; }
  /* Сцена во всю ширину — но содержимое остаётся колонкой по центру,
     иначе кнопка растягивается на метр, а колесо тонет в пустоте. */
  .upg-core > :not(.stage-sculk) { width: 100%; max-width: 420px; }
}
@media (max-width: 620px) {
  .upg-board { grid-template-columns: 1fr; }
  .upg-slot-body { min-height: 180px; }
}

/* ---------- Колесо апгрейда ---------- */

.echo {
  position: relative;
  width: min(100%, 340px);
  aspect-ratio: 1;
  margin: 2px auto 0;
  --chance: 0;
}
.echo-svg { width: 100%; height: 100%; display: block; overflow: visible; }

.echo-bed { fill: #0a0b16; stroke: #1b1c33; stroke-width: 1; }

/* Зона шанса: поверх граней — цветной слой, который сводит светящуюся
   полосу вардена к цвету бренда; под гранями — размытое свечение,
   выглядывающее за края кольца. */
.echo-win { fill: url(#echoWin); opacity: 0.42; mix-blend-mode: screen; transition: opacity 0.3s; pointer-events: none; }
.echo-win-glow { fill: #5eead4; opacity: 0.32; transition: opacity 0.3s; }
.echo.is-empty .echo-win, .echo.is-empty .echo-win-glow { opacity: 0; }

/* Грани: тёмный сколк; внутри зоны шанса — светящаяся полоса вардена
   (узор со своим поворотом на каждую грань, см. echoMarkup). Вспышка на
   грани — указатель прошёл мимо. */
.echo-facet {
  fill: url(#sculkP);
  stroke: rgba(0, 0, 0, 0.7);
  stroke-width: 1;
}
.echo-facet.lit { fill: var(--band); stroke: rgba(9, 40, 38, 0.9); }
.echo-facet.hit { animation: facetHit 0.55s ease-out; }
@keyframes facetHit {
  0% { filter: brightness(3.2) saturate(0.6); }
  100% { filter: brightness(1); }
}

.echo-inner { stroke: rgba(94, 234, 212, 0.12); stroke-width: 1; }
.echo-inner-sculk { opacity: 0.5; }

/* Сонар из центра в покое: кольцо «дышит», даже когда ставки ещё нет. */
.echo-pulse { fill: none; stroke: rgba(94, 234, 212, 0.35); stroke-width: 1.5; opacity: 0; transform-origin: 50% 50%; }
.echo.idle .echo-pulse { animation: echoPulse 3.4s ease-out infinite; }
@keyframes echoPulse {
  0% { transform: scale(0.35); opacity: 0.55; }
  70% { opacity: 0; }
  100% { transform: scale(1.32); opacity: 0; }
}

.echo-notch { fill: #fff; opacity: 0.9; filter: drop-shadow(0 0 5px rgba(94, 234, 212, 0.9)); }

/* Указатель и его хвост. */
.echo-spark-glow { fill: #5eead4; opacity: 0.7; }
.echo-spark-shard { stroke: rgba(255, 255, 255, 0.8); stroke-width: 0.8; }
.echo-spark-core { fill: #fff; }
.echo-trail circle { fill: #5eead4; opacity: 0; }
.echo.is-empty .echo-spark { opacity: 0.35; }
.echo.spinning .echo-spark-glow { opacity: 0.95; }

/* Напряжение: осколок замедляется у самого края дуги — дуга пульсирует. */
.echo.is-edge .echo-win-glow { animation: edgePulse 0.5s ease-in-out infinite; }
@keyframes edgePulse { 50% { opacity: 0.75; } }

/* Итог. Победа — дуга вспыхивает целиком, осколок раскалывается на
   кристаллы (burstConfetti) и ударная волна. Мимо — осколок гаснет, кольцо
   вздрагивает. */
.echo.is-win .echo-win { opacity: 0.9; animation: winFlare 1.1s ease-out; }
.echo.is-win .echo-win-glow { opacity: 0.85; }
.echo.is-win .echo-facet.lit { animation: facetHit 1.1s ease-out; }
.echo.is-win .echo-spark-glow { animation: sparkFlare 0.9s ease-out; }
@keyframes winFlare {
  0% { filter: brightness(2.2); }
  100% { filter: brightness(1); }
}
@keyframes sparkFlare {
  0% { r: 16; opacity: 1; }
  100% { r: 40; opacity: 0; }
}
.echo.is-lose { animation: wheelShake 0.5s ease; }
.echo.is-lose .echo-spark-glow { fill: #fb7185; opacity: 0.35; }
.echo.is-lose .echo-spark-shard { fill: #6b5c72; }
.echo.is-lose .echo-win { opacity: 0.15; }

@keyframes wheelShake {
  10%, 90% { transform: translate3d(-2px, 0, 0); }
  20%, 80% { transform: translate3d(4px, 0, 0); }
  30%, 50%, 70% { transform: translate3d(-6px, 0, 0); }
  40%, 60% { transform: translate3d(6px, 0, 0); }
}

/* Число в центре — крупно; в покое без ставки прочерк. */
.echo-hub {
  position: absolute;
  inset: 19%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border-radius: 50%;
  text-align: center;
  pointer-events: none;
}
.echo-hub-body { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 0; }

/* Рёбра вардена по бокам от числа — пиксельная текстура из игры, правое
   зеркально. Бьются как сердце: в покое медленно, в спине — по команде из
   doUpgrade, всё чаще к остановке. */
.echo-rib {
  display: block;
  flex-shrink: 0;
  width: 31px;
  height: 48px;
  background: url(/assets/warden/ribs.png) center / 100% 100% no-repeat;
  image-rendering: pixelated;
  opacity: 0.66;
  filter: drop-shadow(0 0 5px rgba(94, 234, 212, 0.35));
}
.echo-rib.is-right { transform: scaleX(-1); }
.echo.idle .echo-rib { animation: ribBeat 2.6s ease-out infinite; }
.echo-rib.beat { animation: ribBeat 0.5s ease-out; }
@keyframes ribBeat {
  0% { opacity: 0.66; filter: drop-shadow(0 0 5px rgba(94, 234, 212, 0.35)); }
  10% { opacity: 1; filter: brightness(1.5) drop-shadow(0 0 10px rgba(94, 234, 212, 0.9)); }
  28% { opacity: 0.7; filter: drop-shadow(0 0 5px rgba(94, 234, 212, 0.35)); }
  40% { opacity: 0.95; filter: brightness(1.3) drop-shadow(0 0 8px rgba(94, 234, 212, 0.7)); }
  100% { opacity: 0.66; filter: drop-shadow(0 0 5px rgba(94, 234, 212, 0.35)); }
}
.echo.is-empty .echo-rib { opacity: 0.22; filter: none; animation: none; }
.echo.is-win .echo-rib { opacity: 1; filter: brightness(1.6) drop-shadow(0 0 12px rgba(94, 234, 212, 0.95)); animation: none; }
.echo.is-lose .echo-rib { opacity: 0.12; filter: none; animation: none; }
.echo-hub b { display: block; font-family: var(--font-display); font-size: clamp(24px, 9.5cqw, 34px); font-weight: 800; line-height: 1; letter-spacing: -0.02em; color: var(--text); }
.echo.is-empty .echo-hub b { color: var(--text-faint); }
.echo-hub span { font-size: 11px; font-weight: 600; color: var(--text-faint); max-width: 90%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.echo.is-win .echo-hub b { color: var(--aqua); text-shadow: 0 0 22px rgba(94, 234, 212, 0.7); }
.echo.is-win .echo-hub span { color: var(--text); text-transform: none; letter-spacing: 0; font-size: 11px; }
.echo.is-lose .echo-hub b { color: var(--rose); }

.echo .sound-toggle { top: 2px; right: 2px; }
/* Ротация: выигрышная дуга в начале или в конце круга. Кнопка — в ряду с
   «Апгрейд», бирюзовой рамкой: её должно быть видно сразу. Стрелка
   зеркалится вместе со стороной дуги. */
.stage-actions .side-btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 14px;
  font-size: 12px;
  color: var(--aqua);
  background: rgba(94, 234, 212, 0.08);
  border: 1px solid rgba(94, 234, 212, 0.5);
}
.stage-actions .side-btn:hover:not(:disabled) { background: rgba(94, 234, 212, 0.16); border-color: var(--aqua); }
.side-btn svg { transition: transform 0.25s var(--ease-out); }
.side-btn.is-over svg { transform: scaleX(-1); }
.side-btn:disabled { opacity: 0.45; cursor: not-allowed; }


.echo-hint { min-height: 1.5em; font-size: 12.5px; color: var(--text-dim); text-align: center; text-wrap: balance; }
.echo-hint.warn { color: var(--gold); }

/* «Апгрейд» — во всю ширину, под ним «Сторона» и скорость. */
.stage-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; width: 100%; }
.stage-actions .btn-lg { flex: 1 1 100%; }

/* Скорость прокрутки словами, а не одинокой иконкой-молнией. */
.speed-seg { display: flex; padding: 3px; border-radius: 999px; background: var(--bg-deep); border: 1px solid var(--line-soft); flex-shrink: 0; }
.speed-seg button {
  padding: 8px 12px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-family: var(--font-body);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--text-faint);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.speed-seg button.on { background: var(--surface-2); color: var(--text); }
.speed-seg button:disabled { cursor: not-allowed; opacity: 0.6; }

/* Звуковая волна вардена в момент победы: 8 кадров расходящихся колец
   из текстуры сколк-катализатора, покадрово и без сглаживания. */
.sonic-boom {
  position: absolute;
  inset: 12%;
  background: url(/assets/warden/boom.png) 0 0 / 100% 800% no-repeat;
  image-rendering: pixelated;
  mix-blend-mode: screen;
  opacity: 0.85;
  pointer-events: none;
  z-index: 5;
  animation: boomFrames 0.85s steps(8, jump-none) forwards, boomFade 0.85s ease-out forwards;
}
@keyframes boomFrames { to { background-position: 0 100%; } }
@keyframes boomFade {
  0% { transform: scale(0.7); opacity: 0.9; }
  60% { opacity: 0.8; }
  100% { transform: scale(1.45); opacity: 0; }
}

/* Окуп: свечение карточки в цвет редкости вспыхивает и оседает. */
.result-card.is-okup { animation: okupGlow 1.4s var(--ease-out) both; }
.result-card.is-big { animation: okupGlow 2s var(--ease-out) both; }
@keyframes okupGlow {
  0% { box-shadow: 0 0 0 0 var(--r-soft); }
  35% { box-shadow: 0 0 80px 10px var(--r-soft); }
  100% { box-shadow: 0 0 44px -4px var(--r-soft); }
}

/* Дорогой предмет проезжает под стрелкой — короткая вспышка в цвет
   редкости (смена свечения, не движение). */
.reel-cell.is-passing { animation: topPass 0.5s ease-out; }
@keyframes topPass {
  0% { box-shadow: inset 0 0 0 1px var(--r); }
  30% { box-shadow: inset 0 0 0 2px var(--r), inset 0 0 28px var(--r-soft); }
  100% { box-shadow: inset 0 0 0 1px transparent; }
}

/* Легендарка на ленте: остальные ячейки гаснут, выпавшая светится в цвет
   редкости изнутри и дважды мягко пульсирует. Всё внутри ячейки: лента
   обрезает то, что выходит за её край, — увеличенная ячейка и волна
   наружу срезались сверху и снизу и наезжали на соседний ряд. */
/* Затемнение и подсветка появляются за 0,5 с, а гаснут медленнее, за 1,4 с:
   эффект плавно уходит, а не пропадает. Это смена прозрачности и свечения,
   не движение, поэтому работает и при «меньше движения». */
.reel-box .reel-cell { transition: opacity 1.4s ease-in-out, filter 1.4s ease-in-out, box-shadow 1.4s ease-in-out; }
.reel-box.is-legend .reel-cell { transition-duration: 0.5s; }
.reel-box.is-legend .reel-cell:not(.is-legend-cell) { opacity: 0.35; filter: saturate(0.5); }
.reel-cell.is-legend-cell { z-index: 2; box-shadow: inset 0 0 0 2px var(--r), inset 0 0 30px color-mix(in srgb, var(--r) 30%, transparent); }
.reel-cell.is-legend-cell::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 2px var(--r), inset 0 0 44px var(--r-soft);
  opacity: 0;
  pointer-events: none;
  animation: legendPulse 1.1s ease-out 0.05s 2;
}
@keyframes legendPulse {
  0% { opacity: 0; }
  35% { opacity: 1; }
  100% { opacity: 0; }
}

/* Легендарка на карточке результата: свечение и один блик по картинке. */
.result-card.is-legend { animation: okupGlow 2.2s var(--ease-out) both; }
.result-card.is-legend .item-art::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(110deg, transparent 35%, rgba(255, 255, 255, 0.28) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: legendShine 1.1s ease-out 0.35s forwards;
  pointer-events: none;
}
@keyframes legendShine { to { transform: translateX(120%); } }

/* Искры окупа: светящиеся точки поднимаются от карточки и гаснут. */
.spark {
  position: absolute;
  left: var(--x);
  bottom: 35%;
  width: var(--s);
  height: var(--s);
  border-radius: 50%;
  background: var(--r, var(--aqua));
  box-shadow: 0 0 8px 2px var(--r, var(--aqua));
  opacity: 0;
  pointer-events: none;
  z-index: 6;
  animation: sparkRise var(--d) ease-out var(--delay) forwards;
}
@keyframes sparkRise {
  0% { opacity: 0; transform: translate(0, 0) scale(0.6); }
  15% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .result-card.is-okup, .result-card.is-big, .result-card.is-legend { animation: none; box-shadow: 0 0 44px -4px var(--r-soft); }
  .spark, .reel-cell.is-legend-cell::after, .result-card.is-legend .item-art::after { display: none; }
  .reel-col.is-landed, .reel-cell.is-landed { animation: none; }
}

.sound-toggle {
  position: absolute;
  top: 0;
  right: 0;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
  color: var(--text-dim);
  cursor: pointer;
  z-index: 5;
  transition: border-color 0.16s, color 0.16s;
}
.sound-toggle:hover { border-color: var(--aqua); color: #fff; }

.upgrade-history { display: flex; align-items: center; justify-content: center; gap: 5px; flex-wrap: wrap; min-height: 8px; }
.hist-pip { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; animation: rise 0.3s var(--ease-out) both; }
.hist-pip.win { background: var(--aqua); box-shadow: 0 0 6px rgba(94, 234, 212, 0.7); }
.hist-pip.lose { background: #c23a5a; opacity: 0.75; }

/* ---------- Апгрейд: списки под доской ---------- */

/* Слева свой инвентарь, справа каталог целей — оба открыты всегда, чтобы
   обе половины сделки были на одном экране. */
.upg-panels { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; margin-top: 16px; }
.upg-panel { min-width: 0; padding: 16px 18px 18px; background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius); }
.upg-panel-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.upg-panel-head b { font-family: var(--font-display); font-size: 14px; }
.upg-panel-head .toolbar-row { flex: 1; min-width: 200px; margin: 0 0 0 auto; }
.upg-panel-head .tabs { flex: 1 1 100%; min-width: 0; margin-bottom: 0; overflow-x: auto; flex-wrap: nowrap; }
.upg-panel-head .tabs button { flex: none; white-space: nowrap; }

@media (max-width: 900px) {
  .upg-panels { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  /* На телефоне поиск не влезает в строку с заголовком — уходит под него на всю ширину. */
  .upg-panel-head .toolbar-row { flex-basis: 100%; min-width: 0; margin-left: 0; }
}

.slot-icon {
  width: 26px;
  height: 26px;
  padding: 6px;
  border-radius: 50%;
  color: var(--violet);
  background: var(--surface-2);
  border: 1px solid var(--line);
  box-shadow: 0 0 0 4px rgba(167, 139, 250, 0.06);
  flex-shrink: 0;
}


.cat-item.is-cheap { opacity: 0.4; filter: grayscale(0.6); }
.cat-item.is-picked .item-card { border-color: var(--aqua); box-shadow: 0 0 0 2px rgba(94, 234, 212, 0.25); }

/* Плавающий док: кнопка под рукой, пока колесо не на экране — предметы
   выбирают в списках внизу, а «Апгрейд» остался наверху. */
.upgrade-dock { display: none; }
.upgrade-dock.is-away:not([hidden]) {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: 12px;
  z-index: 55;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  max-width: 560px;
  margin: 0 auto;
  padding: 10px 12px 10px 16px;
  background: rgba(15, 15, 26, 0.96);
  backdrop-filter: blur(10px);
  border: 1px solid var(--line);
  border-radius: 999px;
  box-shadow: 0 12px 30px -10px rgba(0, 0, 0, 0.7);
  animation: rise 0.3s var(--ease-out) both;
}
.upgrade-dock .dock-info { display: flex; flex-direction: column; min-width: 0; }
.upgrade-dock .dock-info b { display: inline-flex; align-items: center; gap: 4px; font-size: 13px; }
.upgrade-dock .dock-info span { font-size: 11px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.main:has(.upgrade-dock.is-away:not([hidden])) { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }

@media (max-width: 820px) {
  .upgrade-dock.is-away:not([hidden]) { bottom: calc(66px + env(safe-area-inset-bottom)); }
  .main:has(.upgrade-dock.is-away:not([hidden])) { padding-bottom: calc(150px + env(safe-area-inset-bottom)); }
  .upg-core { padding: 16px 14px 18px; }

  .echo { width: min(100%, 280px); }
  .upg-slot, .upg-panel { padding: 14px; }
  .stage-actions { flex-wrap: wrap; }
  .stage-actions .btn-lg { flex-basis: 100%; }
  .speed-seg { margin: 0 auto; }
}

@media (prefers-reduced-motion: reduce) {
  .echo.idle .echo-pulse, .echo-facet.hit, .echo.is-edge .echo-win-glow, .echo.is-lose, .echo-rib, .echo.idle .echo-rib { animation: none; }
  .echo-trail, .sonic-boom { display: none; }
}

.toggle-hint { cursor: pointer; transition: color 0.15s; }
.toggle-hint:hover { color: var(--aqua); }

.cat-toolbar input {
  padding: 10px 14px;
  background: linear-gradient(160deg, var(--surface-2), var(--bg-deep));
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13px;
  outline: none;
  transition: border-color 0.18s, box-shadow 0.18s;
}
.cat-toolbar input::placeholder { color: var(--text-faint); }
.cat-toolbar input:focus { border-color: var(--aqua); box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.12); }

.cat-grid.locked { pointer-events: none; opacity: 0.5; }

/* ---------- Поля поиска и сортировки в списках ---------- */

.toolbar-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.toolbar-row input[type="text"], .toolbar-row input[type="search"] {
  flex: 1;
  min-width: 150px;
  padding: 10px 14px;
  background: linear-gradient(160deg, var(--surface-2), var(--bg-deep));
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 13.5px;
  outline: none;
  transition: border-color 0.18s, box-shadow 0.18s;
}
.toolbar-row input[type="text"]::placeholder, .toolbar-row input[type="search"]::placeholder { color: var(--text-faint); }
.toolbar-row input[type="text"]:focus, .toolbar-row input[type="search"]:focus {
  border-color: var(--aqua);
  box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.12);
}
.toolbar-row select, .cat-toolbar select {
  padding: 10px 30px 10px 13px;
  background: linear-gradient(160deg, var(--surface-2), var(--bg-deep));
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 12.5px;
  font-weight: 500;
  outline: none;
  cursor: pointer;
  transition: border-color 0.18s, box-shadow 0.18s;
  /* Нативная стрелка селекта — из другого визуального языка, чем весь
     сайт; меняем на свой шеврон в акцентном цвете. */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%235eead4' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"),
    linear-gradient(160deg, var(--surface-2), var(--bg-deep));
  background-repeat: no-repeat;
  background-position: right 12px center, 0 0;
  /* Без явного размера SVG без width/height рендерится в дефолтном
     intrinsic-размере браузера (сотни пикселей) — отсюда гигантский шеврон. */
  background-size: 10px 7px, 100% 100%;
}

.toolbar-row select:hover, .toolbar-row select:focus,
.cat-toolbar select:hover, .cat-toolbar select:focus {
  border-color: var(--aqua);
  box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.12);
}

/* Полноценная сетка вместо горизонтальной ленты — теперь у пикера есть
 * своя колонка на всю высоту правой панели, а не узкая полоса снизу. */
.stake-strip {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  gap: 10px;
  max-height: 460px;
  overflow-y: auto;
  padding: 4px 4px 4px 0;
}

.stake-strip-item { cursor: pointer; }

/* Пустое состояние — единственный ребёнок grid-а иначе занимает всего
   одну колонку auto-fill (128px) и текст ломается по слову на строку. */
.item-grid > .empty,
.stake-strip > .empty {
  grid-column: 1 / -1;
}

.stake-strip.locked { pointer-events: none; opacity: 0.5; }

/* ---------- Каталог целей апгрейда ---------- */

.modal.wide { max-width: 760px; }

.cat-toolbar { display: flex; gap: 8px; margin-bottom: 14px; flex-wrap: wrap; }
.cat-toolbar-row { display: flex; gap: 8px; }
.cat-toolbar input { flex: 1; min-width: 160px; }
.cat-toolbar select { flex: none; }
/* min-width:0 вместо старых 260px — с длинным именем сервера (REALLYWORLD,
   без пробелов, не переносится) фиксированный минимум раздувал полосу
   вкладок шире узкой колонки апгрейдера и вылезал за край. Вкладки не
   сжимаются (flex:none на кнопках) — вместо этого сама полоса скроллится
   по горизонтали, если не помещается целиком. */
/* flex-basis:100% — вкладки всегда занимают отдельную строку целиком
   (после поиска+сортировки), а не делят строку с ними: иначе на узкой
   колонке апгрейдера им доставалось 40-50px и скроллилась почти каждая
   буква. */
.cat-toolbar .tabs { flex: 1 1 100%; min-width: 0; margin-bottom: 0; overflow-x: auto; flex-wrap: nowrap; }
.cat-toolbar .tabs button { flex: none; white-space: nowrap; }

.cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(128px, 1fr));
  gap: 10px;
  max-height: 460px;
  overflow-y: auto;
  padding-right: 4px;
  margin-right: -4px;
}

.cat-item { cursor: pointer; transition: transform 0.15s var(--ease-out); }
.cat-item:hover { transform: translateY(-3px); }
.cat-empty { grid-column: 1 / -1; }

/* ---------- Модалка ---------- */

.overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(4, 4, 10, 0.85);
  animation: fade 0.2s;
}

@keyframes fade { from { opacity: 0; } }

.modal {
  width: 100%;
  max-width: 410px;
  padding: 30px;
  background: var(--surface);
  border: 1px solid var(--line);
  --cut: 16px;
  animation: rise 0.3s var(--ease-out) both;
}

/* Вордмарк выходит за паддинг модалки вплотную к краям — clip-path
   родителя сам обрежет его по той же гранёной форме, что и всю модалку. */
.modal-wordmark {
  display: block;
  width: calc(100% + 60px);
  height: 150px;
  margin: -30px -30px 18px;
  object-fit: cover;
  object-position: center 40%;
}

.modal-title { margin: 0 0 14px; font-family: var(--font-display); font-size: 17px; text-wrap: balance; }

/* Пополнение: сумма, быстрые варианты и сколько придёт на баланс. */
.topup-presets { margin: -4px 0 14px; }
.topup-sum {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--bg-deep);
  border: 1px solid var(--line-soft);
  font-size: 12px;
  color: var(--text-dim);
}
.topup-sum b { display: inline-flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; font-size: 20px; font-weight: 800; color: var(--aqua); }
.topup-note { margin: 0 0 14px; font-size: 12px; line-height: 1.55; color: var(--text-dim); }
.topup-note a { color: var(--aqua); }
/* Демо-начисление под настоящей оплатой — только в разработке, пунктиром: видно, что это не часть оплаты. */
.topup-demo { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; padding: 10px 12px; border: 1px dashed var(--line); border-radius: 10px; font-size: 12px; color: var(--text-faint); }

/* Необратимое действие выглядит иначе, чем остальные кнопки. */
.btn-danger { color: var(--rose); border-color: rgba(251, 113, 133, 0.45); background: rgba(251, 113, 133, 0.08); }
.btn-danger:hover:not(:disabled) { background: rgba(251, 113, 133, 0.16); }

.field { margin-bottom: 13px; }
.field label { display: block; font-size: 12.5px; font-weight: 600; color: var(--text-dim); margin-bottom: 6px; }
.field input {
  width: 100%;
  padding: 11px 13px;
  background: var(--bg-deep);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  outline: none;
  transition: border-color 0.18s;
}
/* Тот же мягкий ореол, что у поиска в тулбаре — раньше здесь менялась
   только рамка, и поля в модалках отзывались на фокус слабее остальных. */
.field input:focus { border-color: var(--aqua); box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.12); }

/* Нативные стрелки number-инпута — из другого визуального языка, чем
   весь остальной сайт; спиннер убираем везде, шаг всё ещё доступен со
   стрелок клавиатуры. */
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

input[type="number"] {
  appearance: textfield;
  -moz-appearance: textfield;
}

.toolbar-row select:disabled, .toolbar-row input:disabled,
.cat-toolbar select:disabled, .cat-toolbar input:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.tabs { display: flex; gap: 4px; margin-bottom: 20px; padding: 4px; background: var(--bg-deep); border: 1px solid var(--line-soft); }
.tabs button {
  flex: 1;
  padding: 9px;
  background: transparent;
  border: none;
  color: var(--text-dim);
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
}
.tabs button.on { background: var(--surface-2); color: var(--text); }

/* Компактный переключатель в строке заголовка (задания: сегодня / неделя). */
.tabs-inline { margin: 0; padding: 3px; border-radius: 999px; flex-shrink: 0; }
.tabs-inline button { flex: none; padding: 6px 14px; font-size: 11px; border-radius: 999px; }

.alert {
  padding: 10px 13px;
  margin-bottom: 13px;
  font-size: 12px;
  background: rgba(251, 113, 133, 0.1);
  border-left: 2px solid var(--rose);
  color: #fecdd3;
}

/* ---------- Уведомления ---------- */

.toasts { position: fixed; bottom: 20px; right: 20px; z-index: 300; display: flex; flex-direction: column; gap: 8px; }

.toast {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 13px 16px;
  border-radius: 13px;
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line-soft);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(6px);
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--text);
  max-width: 330px;
  animation: rise 0.3s var(--ease-out) both;
}

.toast::before {
  content: '';
  flex: none;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--aqua);
  box-shadow: 0 0 16px rgba(94, 234, 212, 0.55);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.55 17.05 4.7 12.2l1.4-1.4 3.45 3.44 8.35-8.34 1.4 1.41z'/%3E%3C/svg%3E") center/14px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9.55 17.05 4.7 12.2l1.4-1.4 3.45 3.44 8.35-8.34 1.4 1.41z'/%3E%3C/svg%3E") center/14px no-repeat;
}

.toast.err::before {
  background: var(--rose);
  box-shadow: 0 0 16px rgba(251, 113, 133, 0.55);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='10.5' y='4' width='3' height='9' rx='1.5'/%3E%3Crect x='10.5' y='15' width='3' height='3' rx='1.5'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='10.5' y='4' width='3' height='9' rx='1.5'/%3E%3Crect x='10.5' y='15' width='3' height='3' rx='1.5'/%3E%3C/svg%3E");
}

/* ---------- Мелочи ---------- */

.empty { padding: 50px 20px; text-align: center; color: var(--text-faint); font-size: 13px; }

/* Спиннер появляется только если ответ задержался: на быстрой сети
   страницы сменяются за десятки миллисекунд, и мелькание кольца между
   ними выглядело как дёрганье, а не как загрузка. */
.spinner {
  width: 24px;
  height: 24px;
  margin: 40px auto;
  border: 2px solid var(--line);
  border-top-color: var(--aqua);
  border-radius: 50%;
  animation: spin 0.7s linear infinite, spinnerIn 0s 0.25s both;
}

@keyframes spin { to { transform: rotate(360deg); } }
@keyframes spinnerIn { from { opacity: 0; } to { opacity: 1; } }

/* Готовая страница мягко проявляется (см. renderLoading в app.js —
   на время загрузки класс is-loading анимацию выключает). */
#app:not(.is-loading) .main { animation: pageIn 0.28s var(--ease-out) both; }
@keyframes pageIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

.fair-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
.fair-verify-grid { display: grid; grid-template-columns: 2fr 2fr 1.2fr 0.6fr 1fr auto; gap: 10px; align-items: end; }

/* Объяснение — обычный список, без капса и плашек: это текст, который читают. */
.fair-how .panel-title { margin-bottom: 10px; }
.fair-list { padding-left: 20px; font-size: 13.5px; line-height: 1.7; color: var(--text-dim); display: flex; flex-direction: column; gap: 6px; }
.fair-list b { color: var(--text); font-weight: 600; }
.fair-terms { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 6px 18px; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-soft); font-size: 12.5px; color: var(--text-dim); }
.fair-terms div { display: flex; gap: 8px; align-items: baseline; }
.fair-terms b { color: var(--text); font-weight: 600; white-space: nowrap; }
.fair-note { margin: -6px 0 12px; font-size: 13px; color: var(--text-dim); }
.fair-hint { display: block; margin-top: 8px; font-size: 12px; color: var(--text-faint); }
.fair-login { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; font-size: 13.5px; color: var(--text-dim); }

/* Строки «Мои открытия»: предмет, номер, ролл, кнопка; результат под строкой. */
.fair-rows { display: flex; flex-direction: column; gap: 8px; }
.fair-row { padding: 10px 12px; background: var(--surface); border: 1px solid var(--line-soft); border-left: 3px solid var(--r); border-radius: var(--radius-sm); }
.fair-row.is-focus { border-color: rgba(94, 234, 212, 0.45); }
.fair-row-main { display: flex; align-items: center; gap: 12px; }
.fair-row-icon { flex-shrink: 0; }
.fair-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; font-size: 12.5px; color: var(--text-dim); }
.fair-row-text b { color: var(--text); font-size: 13px; }
.fair-row-text code { font-family: var(--font-mono); color: var(--text); }
.fair-chip { font-size: 11.5px; color: var(--text-faint); }
.fair-row-out:empty { display: none; }
.fair-row-out { margin-top: 10px; }

/* Разбор пересчёта: вердикт и три строки — что с чем сравнили. */
.fair-out { padding: 10px 12px; background: var(--bg-deep); border: 1px solid var(--line-soft); border-radius: 8px; font-size: 12.5px; color: var(--text-dim); }
.fair-out.is-ok { border-color: rgba(52, 211, 153, 0.35); }
.fair-out.is-bad { border-color: rgba(251, 113, 133, 0.45); }
.fair-verdict b.ok { color: #34d399; }
.fair-verdict b.bad { color: #fb7185; }
.fair-steps { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.fair-steps > div { display: grid; grid-template-columns: 130px 1fr; gap: 2px 12px; align-items: baseline; }
.fair-steps span { color: var(--text-faint); }
.fair-steps code { font-family: var(--font-mono); font-size: 11px; word-break: break-all; color: var(--text); }
.fair-steps i { grid-column: 2; font-style: normal; font-size: 11.5px; color: var(--text-faint); }
.fair-out.is-ok .fair-steps i { color: #34d399; }

/* Пример на странице честности: отрезок 0…1, поделённый шансами, и метка ролла. */
.fair-example { margin-top: 14px; padding: 12px 14px 10px; background: var(--bg-deep); border: 1px solid var(--line-soft); border-radius: 8px; }
.fair-example-title { font-size: 12.5px; font-weight: 700; margin-bottom: 12px; }
.fair-bar { position: relative; display: flex; height: 26px; margin: 0 8px 30px; }
.fair-bar i { display: flex; align-items: center; justify-content: center; height: 100%; font-style: normal; font-size: 11px; font-weight: 700; color: #06060c; background: var(--c); }
.fair-bar i:first-child { border-radius: 6px 0 0 6px; }
.fair-bar i:last-child { border-radius: 0 6px 6px 0; }
.fair-bar-mark { position: absolute; top: -6px; bottom: -6px; width: 2px; margin-left: -1px; background: #fff; box-shadow: 0 0 8px rgba(255, 255, 255, 0.8); }
.fair-bar-mark em { position: absolute; top: 100%; left: 50%; transform: translateX(-50%); margin-top: 4px; font-style: normal; font-size: 11.5px; font-weight: 700; color: var(--text); white-space: nowrap; }
.fair-example p { font-size: 13px; line-height: 1.6; color: var(--text-dim); }


.fair-box {
  font-family: var(--font-mono);
  font-size: 11px;
  padding: 11px 13px;
  background: var(--bg-deep);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  word-break: break-all;
  color: var(--text-dim);
  line-height: 1.7;
}

.fair-box b { color: var(--aqua); font-weight: 600; }

.chip {
  display: inline-flex;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  background: var(--surface-3);
  color: var(--text-dim);
}

.chip.ok { background: rgba(52, 211, 153, 0.14); color: #34d399; }
.chip.wait { background: rgba(247, 185, 85, 0.14); color: var(--gold); }

/* Подсказка про контракты в инвентаре — та же плитка, что и полоса
   прогресса на главной: иконка, заголовок, пояснение, кнопка. */
.inv-promo {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  margin-bottom: 14px;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, rgba(94, 234, 212, 0.08), rgba(167, 139, 250, 0.05)), var(--surface);
  border: 1px solid var(--line-soft);
  text-decoration: none;
  color: inherit;
  transition: border-color 0.18s;
}
.inv-promo:hover { border-color: var(--line); }
.inv-promo > div:not(.profile-stat-icon) { flex: 1; min-width: 0; }
.inv-promo b { display: block; font-size: 13px; }
.inv-promo span:not(.btn) { font-size: 11.5px; color: var(--text-faint); }
.inv-promo .btn { flex-shrink: 0; }

.sel { outline: 2px solid var(--aqua); outline-offset: -2px; }

/* ---------- Подвал ---------- */

.foot {
  margin-top: 70px;
  padding-top: 30px;
  border-top: 1px solid var(--line-soft);
  font-size: 12px;
  color: var(--text-faint);
}

.foot-grid {
  display: grid;
  grid-template-columns: 1.3fr 0.8fr 1fr 1.5fr;
  gap: 30px;
}

.foot p { line-height: 1.7; }
.foot-links { display: flex; flex-direction: column; gap: 7px; }
.foot-links a { color: var(--text-dim); text-decoration: none; font-weight: 600; }
.foot-links a:hover { color: var(--aqua); }
.foot-note { line-height: 1.8; }

@media (max-width: 1100px) {
  .foot-grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 820px) {
  .foot-grid { grid-template-columns: 1fr; gap: 18px; }
}

/*
 * Сцена открытия. Сундук и название стоят над барабаном, кнопка — под
 * ним: взгляд идёт сундук → барабан → кнопка, и результат появляется
 * там, куда игрок и так смотрит. Панели вокруг нет — как у карточек на
 * главной, ящик «парит» на фоне страницы, под ним размытое пятно света.
 * Раньше это была карточка товара (ящик слева, текст и кнопка справа),
 * а барабан стоял под ней второстепенной коробкой; на телефоне он вообще
 * не попадал в первый экран.
 */
.case-back { margin-bottom: 10px; }

.case-stage { display: flex; flex-direction: column; align-items: center; gap: 16px; margin-bottom: 26px; }

.case-stage-head { display: flex; flex-direction: column; align-items: center; gap: 2px; text-align: center; }

/* Коробка ровно под рендер 3:4, как .ocase-art на главной. */
.case-stage-art {
  position: relative;
  display: grid;
  place-items: center;
  width: 270px;
  max-width: 100%;
  aspect-ratio: 3 / 4;
  margin-bottom: 2px;
}

.case-stage-art > img, .case-stage-art > svg { position: relative; }

/* Пятно света под ящиком в цвете кейса — «лужица» на полу, не заливка. */
.case-stage-glow {
  position: absolute;
  bottom: 4px;
  width: 70%;
  height: 40%;
  border-radius: 50%;
  background: var(--tint);
  filter: blur(26px);
  opacity: 0.3;
}

/* На 1440×900 название приходится на портал Древнего города в фоновой
   картинке (тёмный проём между колоннами). Мягкая тень отделяет буквы от
   краёв рисунка на любой ширине экрана. */
.case-stage-title { font-size: 28px; margin-top: 2px; text-transform: none; letter-spacing: -0.01em; text-wrap: balance; text-shadow: 0 2px 14px rgba(0, 0, 0, 0.6); }

.case-stage .case-kind { justify-content: center; }

/* Одна строка фактов вместо трёх плашек: они спорили с кнопкой за внимание. */
.case-facts {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-top: 8px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--text-dim);
}

.case-facts b { font-family: var(--font-body); font-variant-numeric: tabular-nums; font-size: 13.5px; letter-spacing: 0; color: var(--text); font-weight: 800; }
.case-facts-dot { width: 3px; height: 3px; border-radius: 50%; background: var(--text-faint); }

.case-stage .reel-box { width: 100%; }

/* Выигрыш встаёт между барабаном и кнопкой; пустой слот не занимает места
   (иначе flex-gap давал бы лишний зазор). */
.case-stage #resultSlot { width: 100%; }
.case-stage #resultSlot:empty { display: none; }
.result-block { margin-top: 22px; }
.case-stage .result-block { margin-top: 0; }

.case-buy { display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap; scroll-margin-bottom: 24px; }
.case-buy .btn-primary { flex-shrink: 0; }
.case-buy .mult-row { margin-bottom: 0; }
.case-buy .speed-seg { margin-left: 6px; }

@media (prefers-reduced-motion: reduce) {
  .live-dot, .daily-block.ready .daily-art { animation: none; }
  .result-wrap, .drop-row.is-new, .modal, .toast { animation: none; }
  #app:not(.is-loading) .main { animation: none; }
  .btn-primary::after { display: none; }
  .ticker-track { animation: none; }
  .ticker-track-outer { overflow-x: auto; }
}

@media (max-width: 1100px) {
  /* Ниже — бегущая строка на главной (.ticker-wrap), полоса не нужна. */
  .drop-bar { display: none; }
}

@media (max-width: 820px) {
  .main { padding: 18px 14px calc(76px + env(safe-area-inset-bottom)); }

  .bottom-tabbar {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    background: rgba(7, 7, 13, 0.94);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--line-soft);
    padding-bottom: env(safe-area-inset-bottom);
  }

  .bottom-tabbar a {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    padding: 9px 2px 8px;
    color: var(--text-faint);
    text-decoration: none;
    /* Unbounded здесь слишком широкий: пять подписей в него уже не влезают
       на 375px, а читаемость на 9px важнее фирменного шрифта. */
    font-family: var(--font-body);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: -0.01em;
    min-height: 44px;
  }

  .bottom-tabbar a span {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .bottom-tabbar a.active { color: var(--aqua); }
  .topbar { padding: 0 12px; gap: 8px; }
  .brand-name { display: none; }
  /* Нижняя таб-бар (см. ниже) берёт на себя навигацию на телефоне —
     верхний гамбургер-дропдаун больше не нужен, палец и так дотягивается
     до низа экрана быстрее, чем до шапки. */
  .nav { display: none; }

  .topbar-right { gap: 6px; }
  .xp-bar { display: none; }
  /* Круглая Telegram-кнопка добавила ~46px в и без того тесный кластер —
     на узких экранах бейдж уровня менее важен, чем баланс/пополнение/логин,
     и первым уступает место, чтобы юзернейм не схлопывался до 1 символа. */
  .xp-badge { display: none; }
  .avatar-mark { display: block; }
  /* Кластер справа на 375px тесный: длинный ник режем многоточием, а
     «Пополнить» ужимаем до круглой кнопки с плюсом — действие остаётся
     доступным, но перестаёт выталкивать остальное за экран. */
  .profile-link-name { max-width: 66px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .topup-btn span { display: none; }
  .wallet .topup-btn { width: 40px; padding: 0; justify-content: center; }
  /* На телефоне шапке тесно: звук выключается на странице апгрейда и в профиле. */
  .sound-btn { display: none; }

  /* Пальцем в 30px кнопку попадать неудобно — на телефоне поднимаем
     минимальную высоту, не трогая десктопные пропорции. */
  .btn-sm { min-height: 40px; }
  .topup-btn { min-height: 38px; }
  .sound-toggle { width: 36px; height: 36px; }
  .case-tab, .mult { min-height: 38px; }
  /* Шесть вкладок (три сервера) в три ряда съедали полэкрана: на телефоне
     они в одну строку с горизонтальной прокруткой, край страницы — поля. */
  .case-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin-inline: -14px; padding-inline: 14px; }
  .case-tabs::-webkit-scrollbar { display: none; }
  .case-tab { flex-shrink: 0; white-space: nowrap; }


  .banner { flex-direction: column; align-items: flex-start; padding: 20px 18px; }
  .banner > div { max-width: none; }
  .banner p { margin-bottom: 14px; }
  /* Логотипы серверов на телефоне не дублируем: те же три вкладки стоят
     прямо под баннером. Кнопки — в одну строку, поровну. */
  .banner .hero-servers { display: none; }
  .banner > div { width: 100%; min-width: 0; }
  .banner-foot, .banner-actions { width: 100%; }
  .banner-actions { flex-wrap: nowrap; }
  /* min-width: 0 — иначе ширина текста кнопок распирала колонку, и
     подзаголовок уезжал за край баннера. */
  .banner-actions .btn { flex: 1 1 0; min-width: 0; padding-inline: 10px; justify-content: center; }

  .banner-warden { display: none; }
  .excl-case { grid-template-columns: 1fr; text-align: center; max-width: 340px; padding: 0; }
  .excl-art { width: 200px; margin: 0 auto; }
  .excl-body { align-items: center; }
  .excl-foot, .excl-lock { justify-content: center; }
  .case-lock { flex-direction: column; text-align: center; }
  .reel-box.is-multi { padding: 14px 8px; }
  .reel-box.is-multi .reel-rows { grid-template-columns: repeat(var(--cols, 2), minmax(0, 1fr)); gap: 5px; width: auto; }
  .reel-box.is-multi .reel-rows::before, .reel-box.is-multi .reel-rows::after { display: none; }
  .reel-col { padding: 0 3px; border-radius: 12px; }
  .reel-col::after { left: 1px; right: 1px; border-radius: 13px; }
  .reel-v .reel-cell { padding: 0 4px; }
  .reel-v .reel-cell .cn { font-size: 9px; }
  /* Сундук, название, барабан и кнопка помещаются в первый экран телефона. */
  .case-stage { gap: 14px; margin-bottom: 22px; }
  .case-stage-art { width: 180px; }
  .case-stage-title { font-size: 23px; }
  .case-buy { flex-direction: column; gap: 10px; scroll-margin-bottom: calc(84px + env(safe-area-inset-bottom)); }

  .fair-grid { grid-template-columns: 1fr; }
  .fair-verify-grid { grid-template-columns: 1fr 1fr; }
  .fair-verify-grid .btn { grid-column: 1 / -1; }
  .fair-row-main { flex-wrap: wrap; }
  .fair-steps > div { grid-template-columns: 1fr; }
  .fair-steps i { grid-column: 1; }
  .profile-top { grid-template-columns: 1fr; }
  .profile-stats { grid-template-columns: repeat(2, 1fr); }
  .mission-list { grid-template-columns: 1fr; }
  /* «Содержимое кейса» и счётчик не переносятся по словам в две строки. */
  .section-head h2, .section-head .eyebrow { white-space: nowrap; }
  .rule { min-width: 8px; }
  .fair-verify-grid { grid-template-columns: 1fr; align-items: stretch; }

  /* Ряд «сегодня» на телефоне — горизонтальная лента, как вкладки: одна
     строка высотой в плитку вместо стопки из четырёх блоков на экран. */
  .today-strip {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    margin-inline: -14px;
    padding: 12px 14px 4px;
    margin-top: -12px;
    margin-bottom: 18px;
  }
  .today-strip::-webkit-scrollbar { display: none; }
  .today-strip > * { flex: 0 0 auto; width: 64%; scroll-snap-align: start; scroll-margin-left: 14px; }
  .today-strip > .daily-block { width: 90%; }
  .today-strip .daily-art { height: 54px; }
  .today-strip .daily-copy b { font-size: 12.5px; }
  .today-strip.is-solo > .daily-block { width: 100%; }
  .hof-card { width: 130px; }
}

/* ---------- История баланса и открытий ---------- */
.hist-list { display: flex; flex-direction: column; gap: 6px; }
.hist-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
}
.hist-row:hover { border-color: var(--line); }
.hist-icon { display: flex; width: 30px; }
/* Без иконки колонка схлопывается, и строки баланса выравниваются по левому краю. */
.hist-row > .hist-main:first-child { grid-column: 1 / 3; }
.hist-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.hist-main b { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-main span { font-size: 11px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-when { font-size: 11px; color: var(--text-faint); white-space: nowrap; }
.hist-amount { font-size: 13px; font-weight: 700; white-space: nowrap; color: var(--text-dim); }
.hist-amount.plus { color: var(--aqua); }
.hist-amount.minus { color: var(--text-faint); }

@media (max-width: 560px) {
  .hist-row { gap: 10px; padding: 9px 11px; }
  .hist-when { display: none; }
}

/* Ранг в топе недели: сама позиция и есть смысл таблицы, без неё
   карточки читались как четыре равнозначных дропа. */
.hof-card { position: relative; }
.hof-rank {
  position: absolute;
  top: 8px;
  left: 10px;
  font-size: 11px;
  font-weight: 800;
  color: var(--r);
  opacity: 0.85;
}

/* Условие выдачи наград — над списком, до первого нажатия. */
.mission-note {
  margin: -6px 0 12px;
  padding: 9px 13px;
  font-size: 12px;
  color: var(--text-dim);
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--gold);
}

/* Переключатель истории — по содержимому: на всю ширину страницы две
   вкладки растягивались в две гигантские полосы. */
#histTabs { width: fit-content; }
#histTabs button { flex: 0 0 auto; padding: 9px 24px; }

/* =====================================================================
   Общие мелочи для новых экранов
   ===================================================================== */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.eyebrow-link { color: var(--aqua); text-decoration: none; white-space: nowrap; }
.eyebrow-link:hover { color: var(--text); }

.notice-bar {
  margin: 0 0 16px;
  padding: 10px 14px;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--text-dim);
  background: linear-gradient(90deg, rgba(94, 234, 212, 0.08), rgba(167, 139, 250, 0.05));
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--aqua);
}
.notice-bar a { color: var(--aqua); }
.notice-terms { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.notice-terms .btn { flex-shrink: 0; }

.select-sm {
  appearance: none;
  padding: 7px 30px 7px 12px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface-2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%239b9cba' fill='none' stroke-width='1.5'/%3E%3C/svg%3E") no-repeat right 12px center;
  color: var(--text);
  font: 600 12px var(--font-body);
  cursor: pointer;
}
.select-sm:focus-visible { outline: 2px solid var(--aqua); outline-offset: 2px; }

.check-row { display: flex; gap: 9px; align-items: flex-start; font-size: 12px; color: var(--text-dim); cursor: pointer; line-height: 1.45; }
.check-row input { margin-top: 2px; accent-color: var(--aqua); width: 15px; height: 15px; flex-shrink: 0; }
.check-row a { color: var(--aqua); }

.field-opt { text-transform: none; letter-spacing: 0; font-weight: 500; color: var(--text-faint); margin-left: 4px; }
.consent-row { margin: 4px 0 12px; }

.link-btn { background: none; border: none; padding: 0; color: var(--aqua); font: inherit; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.link-btn:disabled { color: var(--text-faint); cursor: default; }

.chip-row { display: flex; flex-wrap: wrap; gap: 6px; }
.chip-row .chip {
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--text-dim);
  padding: 6px 12px;
  font-size: 12.5px;
  font-weight: 600;
  border-radius: 8px;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.chip-row .chip:hover { color: var(--text); border-color: var(--text-faint); }
.chip-row .chip.on { color: #07070d; background: var(--aqua); border-color: var(--aqua); }

.status-pill {
  display: inline-flex;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  background: var(--surface-3);
  color: var(--text-dim);
}
.status-pill.tone-ok { background: rgba(94, 234, 212, 0.13); color: var(--aqua); }
.status-pill.tone-warn { background: rgba(247, 185, 85, 0.14); color: var(--gold); }
.status-pill.tone-bad { background: rgba(251, 113, 133, 0.13); color: var(--rose); }
.status-pill.tone-muted { background: var(--surface-3); color: var(--text-faint); }

.state-block-sm { padding: 34px 16px; }
.state-block-sm h2 { font-size: 16px; }

.up { color: var(--aqua); }
.down { color: var(--text-faint); }

/* =====================================================================
   Контракты: верстак
   ---------------------------------------------------------------------
   Верстак Minecraft в гамме Deep Dark. Ячейки — как в инвентаре игры:
   вдавленные, тёмный край сверху-слева, светлый снизу-справа; цена стоит
   в углу ячейки, как число предметов. Между сеткой и результатом —
   пиксельная стрелка печки: наполняется по мере выбора, при крафте
   прогорает слева направо, а предметы по очереди втягиваются в неё.
   ===================================================================== */

.forge { display: grid; grid-template-columns: minmax(380px, 520px) 1fr; gap: 20px; align-items: start; }

.forge-stage,
.forge-picker {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  padding: 22px;
}
.forge-stage { position: sticky; top: calc(var(--top-h) + 14px); }

.forge-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.forge-head > div { flex: 1; min-width: 0; }
.forge-title { font-size: 18px; margin: 0 0 4px; text-transform: none; }
.forge-lead { font-size: 12.5px; color: var(--text-faint); }
.forge-count { font-size: 12px; color: var(--text-faint); white-space: nowrap; }
.forge-count b { font-size: 15px; color: var(--text); }

/* Ячейка инвентаря — одна на сетку, результат, «может выпасть» и список. */
.bench-slot,
.bench-result,
.hl,
.pick-cell {
  position: relative;
  display: grid;
  place-items: center;
  background: #0a0b14;
  border: 2px solid;
  border-color: #05060b #1e2135 #1e2135 #05060b;
}
/* Число в углу — цена, с жёсткой тенью, как счётчик стака в игре. */
.slot-count {
  position: absolute;
  right: 4px;
  bottom: 2px;
  font-size: 11px;
  font-weight: 800;
  line-height: 1;
  color: #f1f1f5;
  text-shadow: 1px 1px 0 #2b2b36;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
}

.bench {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 18px;
  margin-bottom: 16px;
  background: linear-gradient(rgba(6, 7, 13, 0.88), rgba(6, 7, 13, 0.88)), url(/assets/warden/sculk.png) 0 0 / 48px 48px;
  image-rendering: pixelated;
  border: 1px solid var(--line-soft);
}

.bench-grid { display: grid; grid-template-columns: repeat(3, var(--slot, 68px)); gap: 4px; }
.bench-slot { width: var(--slot, 68px); height: var(--slot, 68px); padding: 0; color: var(--text); font: inherit; image-rendering: auto; }
/* Обязательные слоты — пунктиром: видно, сколько минимум. */
.bench-slot.is-required:not(.is-filled)::before {
  content: '';
  position: absolute;
  inset: 7px;
  border: 1px dashed rgba(94, 234, 212, 0.2);
}
.bench-slot.is-locked { opacity: 0.35; }
.bench-slot.is-filled {
  cursor: pointer;
  background: radial-gradient(circle at 50% 55%, var(--r-soft), transparent 70%), #0a0b14;
  box-shadow: inset 0 -3px 0 var(--r);
  animation: slotIn 0.24s var(--ease-out) both;
}
.bench-slot.is-filled:hover { outline: 1px solid var(--r); outline-offset: -5px; }
.bench-slot.is-filled:disabled { cursor: default; outline: none; }
.bench-slot .srv { top: 3px; left: 3px; transform: scale(0.72); transform-origin: top left; }
.bench-slot-art { display: grid; place-items: center; }
.bench-slot-x {
  position: absolute;
  top: 2px;
  right: 4px;
  font-size: 13px;
  line-height: 1;
  color: var(--rose);
  opacity: 0;
  transition: opacity 0.15s;
}
.bench-slot.is-filled:hover .bench-slot-x,
.bench-slot.is-filled:focus-visible .bench-slot-x { opacity: 1; }

@keyframes slotIn {
  from { transform: scale(0.7); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* Стрелка печки: серая основа и бирюзовая заливка поверх, открытая на --fill. */
.bench-arrow { position: relative; width: 76px; height: 64px; justify-self: center; }
.bench-arrow-svg { position: absolute; inset: 0; width: 100%; height: 100%; }
.bench-arrow-svg path { fill: #262a40; }
.bench-arrow-svg.is-fill { clip-path: inset(0 calc((1 - var(--fill, 0)) * 100%) 0 0); transition: clip-path 0.35s var(--ease-out); }
.bench-arrow-svg.is-fill path { fill: var(--aqua); }
.bench-arrow.is-ready .bench-arrow-svg.is-fill { animation: arrowReady 1.6s ease-in-out infinite; }
.forge-stage.is-crafting .bench-arrow-svg.is-fill { animation: arrowBurn var(--craft-ms, 1s) linear both; }
@keyframes arrowReady { 50% { filter: brightness(1.35); } }
@keyframes arrowBurn {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

/* Слот результата: крупнее, пока пуст — вопрос; во время крафта набирает свет. */
.bench-result { width: 112px; height: 112px; }
.bench-result-q { font-family: var(--font-display); font-size: 38px; font-weight: 800; color: #1f2236; line-height: 1; }
.bench-result.is-ready .bench-result-q { color: rgba(94, 234, 212, 0.45); }
.bench-result.is-crafting { animation: resultCharge var(--craft-ms, 1s) ease-in both; }
.bench-result.is-crafting .bench-result-q { color: var(--aqua); }
@keyframes resultCharge { to { box-shadow: inset 0 0 32px rgba(94, 234, 212, 0.35); } }
.bench-result.is-revealed {
  background: radial-gradient(circle at 50% 50%, var(--r-soft), transparent 72%), #0a0b14;
  box-shadow: inset 0 -3px 0 var(--r), 0 0 28px -8px var(--r);
  animation: resultPop 0.45s var(--ease-out) both;
}
.bench-result.is-revealed .srv { top: 5px; left: 5px; }
.bench-result-art { display: grid; place-items: center; filter: drop-shadow(0 0 14px var(--r-soft)); }
.bench-result .slot-count { right: 6px; bottom: 5px; font-size: 13px; }
@keyframes resultPop {
  0% { transform: scale(0.8); }
  60% { transform: scale(1.06); }
  100% { transform: scale(1); }
}

/* Подъём по редкости перед показом: рамка перекрашивается ступенями. */
.bench-result.is-climbing {
  border-color: var(--r);
  box-shadow: inset 0 0 24px -6px var(--r), 0 0 18px -8px var(--r);
}
.bench-result.is-climbing .bench-result-q { color: var(--r); }
.bench-result.is-step { animation: rankStep 0.16s var(--ease-out); }
@keyframes rankStep { from { transform: scale(1.07); } }

/* Шесть делений под слотом — ступени редкости, горят до выпавшей. */
.rank-pips {
  position: absolute;
  top: calc(100% + 9px);
  left: 50%;
  display: flex;
  gap: 3px;
  transform: translateX(-50%);
}
.rank-pips i { width: 10px; height: 6px; background: #1a1d2e; box-shadow: inset 0 -2px 0 rgba(0, 0, 0, 0.35); }
.rank-pips i.on { background: var(--c); }

/* Окупился — отблеск зачарования: сиреневый силуэт предмета под полосой-маской. */
.bench-result-art { position: relative; }
.glint {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
  filter: url(#wcGlintTint);
  mix-blend-mode: screen;
  opacity: 0.7;
  -webkit-mask-image: linear-gradient(118deg, transparent 38%, #000 38% 47%, transparent 47% 53%, #000 53% 56%, transparent 56%);
  mask-image: linear-gradient(118deg, transparent 38%, #000 38% 47%, transparent 47% 53%, #000 53% 56%, transparent 56%);
  -webkit-mask-size: 300% 100%;
  mask-size: 300% 100%;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  animation: glint 3s linear 0.4s infinite both;
}
@keyframes glint {
  0% { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
  55%, 100% { -webkit-mask-position: 0 0; mask-position: 0 0; }
}

/* Крупный выигрыш — слот-катализатор бьёт квадратной волной, по верстаку идёт скалк. */
.bench-result.is-bloom { animation: resultPop 0.45s var(--ease-out) both, catalystPulse 1.4s ease-out 0.1s 2; }
@keyframes catalystPulse {
  from { box-shadow: inset 0 -3px 0 var(--r), 0 0 0 0 rgba(95, 240, 245, 0.5); }
  to { box-shadow: inset 0 -3px 0 var(--r), 0 0 0 22px rgba(95, 240, 245, 0); }
}
.bench { position: relative; overflow: hidden; }
.bench > * { position: relative; z-index: 1; }
.bench > .sculk-bloom {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  image-rendering: pixelated;
  pointer-events: none;
}
.sculk-bloom.is-settled { opacity: 0.55; transition: opacity 1.4s ease; }

/* Множитель — пиксельный счётчик в строке итога, после разницы с вложенным. */
.ctr-xp { display: inline-flex; align-self: center; margin-left: auto; }
.ctr-xp-num { display: block; line-height: 0; }
.xp-digits .xp-face { fill: #8b93ad; }
.xp-digits .xp-shade { fill: #1d2034; }
.ctr-xp.is-up .xp-digits .xp-face { fill: #8cf53a; }
.ctr-xp.is-up .xp-digits .xp-shade { fill: #28450c; }
.ctr-xp-num.is-level { animation: xpLevel 0.3s var(--ease-out); }
.ctr-xp-num.is-hit .xp-face { animation: xpHit 0.2s ease-out; }
@keyframes xpLevel { 40% { transform: translateY(-3px) scale(1.15); } }
@keyframes xpHit { 50% { fill: #eaffa6; } }

.xp-orb {
  position: fixed;
  top: -4px;
  left: -4px;
  z-index: 90;
  width: 8px;
  height: 8px;
  pointer-events: none;
  background: hsl(calc(80 + var(--hue, 0) * 9) 92% 58%);
  box-shadow: inset -2px -2px 0 rgba(40, 80, 8, 0.55), inset 2px 2px 0 rgba(255, 255, 210, 0.6), 0 0 9px rgba(170, 240, 60, 0.55);
  animation: orbPulse 0.36s steps(2) infinite;
}
@keyframes orbPulse { 50% { filter: brightness(1.3) hue-rotate(-12deg); } }

/* Крафт: содержимое ячеек по очереди уезжает в стрелку и гаснет. */
.forge-stage.is-crafting .bench-slot.is-filled > * {
  animation: slotAbsorb calc(var(--craft-ms, 1s) * 0.45) ease-in both;
  animation-delay: calc(var(--i) * var(--craft-ms, 1s) * 0.05);
}
.forge-stage.is-crafting .bench-slot.is-filled { box-shadow: none; transition: box-shadow 0.3s; }
@keyframes slotAbsorb { to { transform: translateX(46px) scale(0.2); opacity: 0; } }

/* Под верстаком — одна строка «вложено → выпадет за», без плашек. */
.forge-summary { min-height: 58px; margin-bottom: 16px; }
/* Итог — одна строка, запас высоты под расчёт ему не нужен. */
.forge-summary:has(> .forge-got) { min-height: 0; }
.forge-line { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; font-size: 13px; color: var(--text-dim); }
.forge-line b { color: var(--text); font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; }
.forge-line svg { width: 12px; height: 12px; }
.forge-line i { font-style: normal; color: var(--text-faint); margin: 0 4px; }
.forge-line.is-loading { animation: pulse 1.1s ease-in-out infinite; }
.forge-note {
  margin-top: 10px;
  padding: 9px 12px;
  font-size: 12px;
  line-height: 1.5;
  color: #fde7c0;
  background: rgba(247, 185, 85, 0.08);
  border-left: 2px solid var(--gold);
}

/* «Может выпасть» — ряд малых ячеек: картинка и цена, без шансов. */
.forge-highlights { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 12px; }
.forge-highlights .hl { width: 52px; height: 52px; box-shadow: inset 0 -2px 0 var(--r); }
.forge-highlights .hl .slot-count { right: 3px; bottom: 2px; font-size: 10px; }

/* Итог: название цветом редкости, цена и разница с вложенным. */
.forge-got { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 10px; }
.forge-got b { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 16px; color: var(--r); }
.forge-got-price { display: inline-flex; align-items: center; gap: 4px; font-weight: 800; font-variant-numeric: tabular-nums; }
.forge-got-price svg { width: 12px; height: 12px; }
.forge-got-delta { font-size: 13px; font-weight: 800; }

.ch-check { font-size: 11px; color: var(--text-faint); text-decoration: none; }
.ch-check:hover { color: var(--aqua); }
.ch-nums { align-items: flex-end; }

.forge-actions .btn-craft { width: 100%; padding: 13px 18px; font-size: 13px; }
.btn-spin {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-right: 6px;
  border: 2px solid rgba(7, 7, 13, 0.35);
  border-top-color: #07070d;
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
  vertical-align: -1px;
}

.forge-confirm {
  padding: 14px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-left: 2px solid var(--gold);
  animation: rise 0.25s var(--ease-out) both;
}
.forge-confirm b { display: block; font-size: 14px; margin-bottom: 4px; }
.forge-confirm .check-row { margin-bottom: 2px; }
.forge-confirm p { font-size: 12px; line-height: 1.5; color: var(--text-dim); margin-bottom: 9px; }
.confirm-list { list-style: none; max-height: 132px; overflow: auto; margin-bottom: 10px; border-top: 1px solid var(--line-soft); }
.confirm-list li { display: flex; justify-content: space-between; gap: 10px; padding: 5px 0; font-size: 12px; border-bottom: 1px solid var(--line-soft); }
.confirm-list .num { color: var(--text-dim); }
.forge-confirm-actions, .forge-result-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.forge-result-actions .btn { flex: 1 1 auto; }

.picker-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.picker-count { display: block; margin-top: 5px; font-size: 13px; }
.picker-tools { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* Инвентарь для контракта — плотная сетка ячеек, как в игре: картинка,
   цена в углу, название под ячейкой. Выбранные — с номером слота. */
.picker-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 12px 6px; }

.pick {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 5px;
  min-width: 0;
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  font: inherit;
  text-align: center;
  cursor: pointer;
}
.pick-cell { aspect-ratio: 1; box-shadow: inset 0 -3px 0 var(--r); transition: background 0.15s, opacity 0.15s; }
.pick-cell .srv { top: 3px; left: 3px; transform: scale(0.72); transform-origin: top left; }
.pick:hover:not(:disabled) .pick-cell { background: radial-gradient(circle at 50% 55%, var(--r-soft), transparent 70%), #0a0b14; }
.pick.is-picked .pick-cell { outline: 2px solid var(--aqua); outline-offset: -2px; }
.pick-name { font-size: 11px; line-height: 1.25; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick.is-picked .pick-name { color: var(--text); }
.pick:disabled { cursor: not-allowed; }
.pick:disabled .pick-cell, .pick:disabled .pick-name { opacity: 0.38; }
.pick:focus-visible { outline: 2px solid var(--aqua); outline-offset: 3px; }
.pick-slot {
  position: absolute;
  top: 3px;
  right: 3px;
  z-index: 3;
  min-width: 18px;
  height: 18px;
  display: grid;
  place-items: center;
  padding: 0 4px;
  background: var(--aqua);
  color: #07070d;
  font-size: 10.5px;
  font-weight: 800;
}

.contract-history { margin-bottom: 20px; }
.ch-list { display: flex; flex-direction: column; gap: 6px; }
.ch-row {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: center;
  gap: 14px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-left: 2px solid var(--r);
  border-radius: var(--radius-sm);
}
.ch-inputs { display: flex; align-items: center; }
.ch-in { display: grid; place-items: center; width: 30px; height: 30px; margin-left: -6px; background: #0b0b14; border: 1px solid var(--line); }
.ch-in:first-child { margin-left: 0; }
.ch-more { margin-left: 6px; font-size: 11px; color: var(--text-faint); }
.ch-arrow { color: var(--text-faint); }
.ch-result { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ch-result b { display: block; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ch-result span { font-size: 11px; color: var(--text-faint); }
.ch-result > div { min-width: 0; }
.ch-nums { text-align: right; font-size: 11px; color: var(--text-faint); display: flex; flex-direction: column; gap: 2px; }
.ch-nums b { font-size: 13px; }
.ch-more-btn { display: block; margin: 10px auto 0; }

.forge-dock { display: none; }

@media (max-width: 1100px) {
  .forge { grid-template-columns: 1fr; }
  .forge-stage { position: static; }

  .forge-dock:not([hidden]) {
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: 12px;
    z-index: 55;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px 10px 16px;
    background: rgba(15, 15, 26, 0.96);
    backdrop-filter: blur(10px);
    border: 1px solid var(--line);
    border-radius: 999px;
    box-shadow: 0 12px 30px -10px rgba(0, 0, 0, 0.7);
  }
  .dock-info { display: flex; flex-direction: column; min-width: 0; }
  .dock-info b { font-size: 13px; }
  .dock-info span { font-size: 11px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

@media (max-width: 1100px) {
  /* Плашка висит поверх страницы — без запаса она закрывала бы низ подвала. */
  .main:has(.forge-dock:not([hidden])) { padding-bottom: calc(96px + env(safe-area-inset-bottom)); }
}

@media (max-width: 820px) {
  .forge-dock:not([hidden]) { bottom: calc(66px + env(safe-area-inset-bottom)); }
  .main:has(.forge-dock:not([hidden])) { padding-bottom: calc(150px + env(safe-area-inset-bottom)); }
}

@media (max-width: 560px) {
  .forge-stage, .forge-picker { padding: 16px; }
  /* Телефон: сетка, стрелка и результат в один ряд, но мельче. */
  .bench { --slot: 52px; gap: 8px; padding: 12px 10px; }
  .bench-arrow { width: 38px; height: 32px; }
  .bench-result { width: 84px; height: 84px; }
  .forge-stage.is-crafting .bench-slot.is-filled > * { animation-name: slotAbsorbSm; }
  .forge-highlights .hl { width: 44px; height: 44px; }
  .picker-grid { grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); }
  .picker-tools { width: 100%; justify-content: space-between; }
  .ch-row { grid-template-columns: auto 1fr; gap: 8px 12px; }
  .ch-arrow { display: none; }
  .ch-nums { grid-column: 1 / -1; flex-direction: row; justify-content: space-between; text-align: left; }
}

@keyframes slotAbsorbSm {
  to { transform: translateX(28px) scale(0.2); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .bench-slot.is-filled,
  .forge-stage.is-crafting .bench-slot.is-filled > *,
  .bench-result.is-crafting,
  .bench-result.is-revealed,
  .bench-result.is-step,
  .ctr-xp-num.is-level,
  .ctr-xp-num.is-hit .xp-face,
  .bench-arrow.is-ready .bench-arrow-svg.is-fill,
  .forge-stage.is-crafting .bench-arrow-svg.is-fill,
  .forge-confirm { animation: none; }
  .forge-stage.is-crafting .bench-slot.is-filled > * { opacity: 0.3; }
}

/* =====================================================================
   Приглашения
   ===================================================================== */

.ref-hero {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  gap: 28px;
  align-items: center;
  padding: 28px;
  margin-bottom: 14px;
  border: 1px solid var(--line-soft);
  background:
    radial-gradient(80% 120% at 0% 0%, rgba(94, 234, 212, 0.1), transparent 55%),
    radial-gradient(70% 120% at 100% 100%, rgba(167, 139, 250, 0.12), transparent 60%),
    var(--surface);
}
.ref-hero h3 { font-size: 21px; line-height: 1.25; margin: 8px 0 10px; text-transform: none; text-wrap: balance; }
.ref-hero p { font-size: 13px; line-height: 1.6; color: var(--text-dim); max-width: 50ch; }

.field-label { display: block; font-size: 12.5px; font-weight: 600; color: var(--text-dim); margin-bottom: 7px; }
.copy-row { display: flex; gap: 8px; }
.copy-row input {
  flex: 1;
  min-width: 0;
  padding: 10px 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-deep);
  color: var(--text);
  font: 500 12.5px var(--font-mono);
}
.ref-code { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 12px; font-size: 12px; color: var(--text-faint); }
.ref-code b { font-size: 16px; letter-spacing: 0.12em; color: var(--aqua); }

.ref-steps { list-style: none; counter-reset: step; display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 14px; }
.ref-steps li {
  counter-increment: step;
  position: relative;
  padding: 16px 16px 16px 50px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
}
.ref-steps li::before {
  content: counter(step);
  position: absolute;
  left: 14px;
  top: 14px;
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  background: var(--surface-3);
  color: var(--aqua);
  font: 800 12px var(--font-body);
}
.ref-steps b { display: block; font-size: 13px; margin-bottom: 4px; }
.ref-steps span { font-size: 12px; line-height: 1.55; color: var(--text-dim); }

.ref-stats { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; margin-bottom: 14px; }
.ref-stat { padding: 14px; background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); }
.ref-stat b { display: flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; font-size: 20px; font-weight: 800; }
.ref-stat b img { width: 15px; height: 17px; }
.ref-stat > span { font-size: 11px; color: var(--text-faint); }
.ref-stat-earned { border-color: rgba(94, 234, 212, 0.3); }
.ref-stat-earned b { color: var(--aqua); }

.ref-bind { display: flex; justify-content: space-between; align-items: center; gap: 20px; flex-wrap: wrap; margin-bottom: 8px; }
.ref-bind b { font-size: 14px; }
.ref-bind p { font-size: 12px; color: var(--text-dim); margin-top: 4px; max-width: 58ch; line-height: 1.5; }
.ref-bind-form { display: flex; gap: 8px; }
.ref-bind-form input {
  width: 160px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-deep);
  color: var(--text);
  font: 600 13px var(--font-mono);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.ref-list { display: flex; flex-direction: column; gap: 6px; }
.ref-row {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
}
.ref-row .user-avatar { width: 28px; height: 28px; font-size: 12px; }
.ref-row-main { min-width: 0; }
.ref-row-main b { display: block; font-size: 13px; }
.ref-row-main span { font-size: 11px; color: var(--text-faint); }
.ref-row-extra { font-size: 12px; color: var(--text-dim); min-width: 56px; text-align: right; }
.ref-row-extra.plus { color: var(--aqua); font-weight: 700; }
.ref-reward-icon { display: grid; place-items: center; width: 28px; height: 28px; border-radius: 999px; background: var(--surface-3); }

.ref-foot { margin-top: 18px; font-size: 12px; line-height: 1.6; color: var(--text-faint); max-width: 80ch; }
.ref-foot a { color: var(--aqua); }

@media (max-width: 1100px) {
  .ref-hero { grid-template-columns: 1fr; }
  .ref-stats { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 720px) {
  .ref-steps { grid-template-columns: 1fr; }
  .ref-stats { grid-template-columns: repeat(2, 1fr); }
  .ref-stat-earned { grid-column: 1 / -1; }
  .ref-hero { padding: 20px; }
  .ref-row { grid-template-columns: auto 1fr; }
  .ref-row .status-pill, .ref-row-extra { grid-column: 2; justify-self: start; text-align: left; }
  .copy-row { flex-direction: column; }
  .ref-bind-form { width: 100%; }
  .ref-bind-form input { flex: 1; width: auto; }
}

/* =====================================================================
   Правовые документы и F.A.Q.
   ---------------------------------------------------------------------
   Это часть продукта, а не страница «для галочки»: колонка текста
   ограничена по ширине для чтения, оглавление закреплено сбоку на
   широком экране и сворачивается в «Содержание» на телефоне, у каждого
   раздела есть якорь.
   ===================================================================== */

.doc { max-width: 1120px; }

.doc-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 22px; padding: 4px; background: var(--bg-deep); border: 1px solid var(--line-soft); width: fit-content; max-width: 100%; }
.doc-tabs a { padding: 8px 14px; font-size: 12px; font-weight: 600; color: var(--text-dim); text-decoration: none; border-radius: 999px; }
.doc-tabs a:hover { color: var(--text); }
.doc-tabs a.on { background: var(--surface-3); color: var(--text); }

.doc-head { margin-bottom: 26px; max-width: 760px; }
.doc-title { font-size: clamp(24px, 3.4vw, 34px); margin: 8px 0 12px; text-wrap: balance; }
.doc-meta { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 12px; color: var(--text-faint); margin-bottom: 14px; }
.doc-meta b { color: var(--text); }
.doc-lead { font-size: 15px; line-height: 1.65; color: var(--text-dim); max-width: 68ch; }

.doc-body { display: grid; grid-template-columns: 260px minmax(0, 1fr); gap: 40px; align-items: start; }

.doc-toc-desktop { position: sticky; top: calc(var(--top-h) + 16px); max-height: calc(100vh - var(--top-h) - 40px); overflow: auto; padding-right: 6px; }
.doc-toc ol { list-style: none; margin-top: 10px; }
.doc-toc a {
  display: flex;
  gap: 10px;
  padding: 6px 10px;
  font-size: 12.5px;
  line-height: 1.35;
  color: var(--text-dim);
  text-decoration: none;
  border-left: 2px solid transparent;
}
.doc-toc a .num { color: var(--text-faint); min-width: 16px; font-size: 11px; padding-top: 1px; }
.doc-toc a:hover { color: var(--text); }
.doc-toc a.on { color: var(--text); border-left-color: var(--aqua); background: rgba(94, 234, 212, 0.05); }
.doc-toc-mobile { display: none; }

.doc-article { max-width: 72ch; }
.doc-section { padding: 6px 0 22px; scroll-margin-top: calc(var(--top-h) + 20px); }
.doc-section + .doc-section { border-top: 1px solid var(--line-soft); padding-top: 22px; }
.doc-section h2 { font-size: 17px; line-height: 1.35; margin-bottom: 12px; text-transform: none; letter-spacing: 0; }
.doc-num { color: var(--aqua); margin-right: 4px; font-size: 14px; }
.doc-anchor { margin-left: 6px; color: var(--text-faint); text-decoration: none; opacity: 0; transition: opacity 0.15s; font-size: 14px; }
.doc-section h2:hover .doc-anchor, .doc-anchor:focus-visible { opacity: 1; }
.doc-article p { font-size: 14.5px; line-height: 1.75; color: #cfd0e2; margin-bottom: 12px; }
.doc-article ul { margin: 0 0 12px; padding-left: 20px; }
.doc-article li { font-size: 14.5px; line-height: 1.7; color: #cfd0e2; margin-bottom: 6px; }
.doc-article li::marker { color: var(--aqua); }
.doc-article b { color: var(--text); font-weight: 700; }
.doc-article a { color: var(--aqua); text-underline-offset: 3px; }
.doc-note {
  margin: 4px 0 14px;
  padding: 11px 14px;
  font-size: 13px;
  line-height: 1.6;
  color: #fde7c0;
  background: rgba(247, 185, 85, 0.07);
  border-left: 2px solid var(--gold);
}

.doc-operator { margin-top: 10px; padding: 20px; background: var(--surface); border: 1px solid var(--line-soft); scroll-margin-top: calc(var(--top-h) + 20px); }
.doc-operator h2 { font-size: 15px; margin-bottom: 12px; text-transform: none; }
.doc-operator dl { display: grid; grid-template-columns: max-content 1fr; gap: 6px 18px; margin-bottom: 12px; font-size: 13px; }
.doc-operator dt { color: var(--text-faint); }
.doc-cross { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 22px; }

.faq-search { margin: 18px 0 14px; max-width: 520px; }
.faq-search input {
  width: 100%;
  padding: 12px 18px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--bg-deep);
  color: var(--text);
  font: 500 14px var(--font-body);
}
.faq-search input:focus { outline: none; border-color: var(--aqua); box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.12); }

.faq { max-width: 820px; }
.faq-cat { margin-bottom: 26px; scroll-margin-top: calc(var(--top-h) + 20px); }
.faq-cat h2 { font-size: 15px; color: var(--text-dim); margin-bottom: 10px; }
.faq-item { background: var(--surface); border: 1px solid var(--line-soft); margin-bottom: 6px; scroll-margin-top: calc(var(--top-h) + 20px); }
.faq-item[open] { border-color: var(--line); }
.faq-item summary {
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: '+'; font: 400 20px var(--font-mono); color: var(--aqua); line-height: 1; transition: transform 0.2s; }
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item summary:focus-visible { outline: 2px solid var(--aqua); outline-offset: -2px; }
.faq-answer { padding: 0 16px 14px; }
.faq-answer p { font-size: 13.5px; line-height: 1.7; color: #cfd0e2; margin-bottom: 8px; max-width: 70ch; }
.faq-answer a { color: var(--aqua); }

.faq-support { display: flex; justify-content: space-between; align-items: center; gap: 16px; flex-wrap: wrap; max-width: 820px; margin-top: 10px; }
.faq-support b { font-size: 14px; }
.faq-support p { font-size: 12.5px; color: var(--text-dim); margin-top: 4px; }

@media (max-width: 1100px) {
  .doc-body { grid-template-columns: 1fr; gap: 0; }
  .doc-toc-desktop { display: none; }
  .doc-toc-mobile { display: block; margin-bottom: 18px; background: var(--surface); border: 1px solid var(--line-soft); }
  .doc-toc-mobile summary { padding: 12px 16px; font-weight: 700; font-size: 13px; cursor: pointer; }
  .doc-toc-mobile ol { padding: 0 6px 10px; margin-top: 0; }
}

@media (max-width: 560px) {
  .doc-article p, .doc-article li { font-size: 14px; }
  .doc-operator dl { grid-template-columns: 1fr; gap: 2px; }
  .doc-operator dd { margin-bottom: 8px; }
}

/* =====================================================================
   Профиль: безопасность; подвал: документы
   ===================================================================== */

/* text-transform на поле нужен коду, а не подсказке в нём. */
#promoInput::placeholder { text-transform: none; }
.promo-tg { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; margin-top: 12px; font-size: 12.5px; color: var(--text-dim); }
.promo-tg svg { color: var(--aqua); flex-shrink: 0; }
.promo-tg a { color: var(--aqua); font-weight: 700; text-decoration: none; }
.promo-tg a:hover { text-decoration: underline; }

.security-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.security-grid .panel-title { margin-bottom: 6px; }
.security-grid .profile-hint { display: block; margin-bottom: 14px; font-size: 12px; line-height: 1.5; }
@media (max-width: 720px) {
  .security-grid { grid-template-columns: 1fr; }
}

.foot-legal a { color: var(--text-faint); }

/* «Продать всё» на взводе: второе нажатие продаёт, первое только спрашивает. */
.btn.is-armed { border-color: var(--rose); color: var(--rose); background: rgba(251, 113, 133, 0.1); }
.btn.is-armed:hover:not(:disabled) { border-color: var(--rose); color: #fff; background: rgba(251, 113, 133, 0.22); box-shadow: 0 6px 18px rgba(251, 113, 133, 0.2); }

/* Разделы аккаунта в профиле — ссылки со значками, отдельно от настроек
   («звук», «выйти»): раньше пять одинаковых кнопок стояли одним рядом. */
.profile-links { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
.profile-links a {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 10px 6px;
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  color: var(--text);
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
  transition: border-color 0.15s, transform 0.15s var(--ease-out);
}
.profile-links a svg { width: 18px; height: 18px; color: var(--aqua); }
.profile-links a:hover { border-color: var(--aqua); transform: translateY(-1px); }
.profile-tools { display: flex; gap: 8px; flex-wrap: wrap; }

/* Капча регистрации (Cloudflare Turnstile). Виджет сам рисует рамку 65px
 * высотой; блок только держит отступы и место под подсказку об ошибке. */
.captcha-field { margin: 10px 0 2px; min-height: 65px; }
.captcha-note { margin-top: 6px; font-size: 12px; color: #fecdd3; line-height: 1.4; }

/* ---------- Выдача: окно «Получить», шаг с QR, блок заявок, чек ---------- */

/* Шаг с QR на телефоне выше экрана: подложка прокручивается, а модалка
   стоит по центру, пока влезает (auto-поля во flex не уходят в минус,
   в отличие от place-items: center у обычной .overlay). */
.wd-overlay { display: flex; flex-direction: column; overflow-y: auto; overscroll-behavior: contain; }
.wd-overlay > .modal { margin: auto; }

.wd-modal { max-width: 460px; }
.wd-modal .modal-title { font-size: 16px; }
.wd-wide { width: 100%; margin-top: 8px; }

.wd-item {
  display: flex; gap: 12px; align-items: center;
  padding: 10px 12px; margin-bottom: 14px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.wd-item-art { flex-shrink: 0; width: 44px; height: 44px; display: grid; place-items: center; background: var(--bg-deep); border-radius: 10px; }
.wd-item > div:last-child { display: grid; gap: 2px; min-width: 0; }
.wd-item b { font-size: 13.5px; }
.wd-item span { font-size: 12px; color: var(--text-faint); }
.wd-hint { margin-top: 6px; font-size: 11.5px; line-height: 1.4; color: var(--text-faint); }
.wd-note { font-size: 12px; color: var(--text-faint); line-height: 1.45; margin: 10px 0 0; }

/* Два способа: текст слева, действие справа; недоступный — пунктиром, с причиной. */
.wd-methods { display: grid; gap: 8px; }
.wd-method {
  display: flex; align-items: center; gap: 12px;
  padding: 12px 14px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.wd-method-text { flex: 1; min-width: 0; display: grid; gap: 3px; }
.wd-method-text b { font-size: 13.5px; }
.wd-method-text span { font-size: 12px; line-height: 1.4; color: var(--text-dim); }
.wd-method .btn { flex-shrink: 0; max-width: 58%; }
.wd-method .btn.is-busy { opacity: 0.5; pointer-events: none; }
.wd-btn-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.wd-method.is-off { background: transparent; border-style: dashed; }
.wd-method.is-off b, .wd-method.is-off span { color: var(--text-faint); }

.wd-steps { margin: 0 0 12px; padding-left: 18px; display: grid; gap: 6px; font-size: 12.5px; color: var(--text-dim); line-height: 1.5; }
.wd-steps b { color: var(--text); }
.wd-steps a { color: var(--aqua); white-space: nowrap; }

/* Зона вставки: пунктир как у выреза под скриншот; при наведении файла — аква. */
.wd-drop {
  position: relative; display: grid; place-items: center; width: 100%; min-height: 96px;
  padding: 10px; border: 1.5px dashed var(--line); border-radius: var(--radius-sm);
  background: var(--bg-deep); color: var(--text-dim); font: inherit; font-size: 12.5px;
  cursor: pointer; transition: border-color .15s, background .15s;
}
.wd-drop:hover, .wd-drop:focus-visible, .wd-drop.is-over { border-color: var(--aqua); background: rgba(94, 234, 212, 0.05); outline: none; }
.wd-drop.is-busy, .wd-pick.is-busy { cursor: progress; opacity: .7; }
.wd-drop.has-shot { min-height: 0; padding: 6px; }
.wd-drop img { display: block; max-width: 100%; max-height: 200px; border-radius: 8px; object-fit: contain; }
.wd-drop.has-shot .wd-drop-text {
  position: absolute; right: 10px; bottom: 10px; padding: 3px 9px; border-radius: 999px;
  background: rgba(4, 4, 10, 0.8); color: var(--text); font-size: 11.5px;
}
/* Телефон: вместо Ctrl+V — крупная кнопка выбора файла. */
.wd-pick { width: 100%; padding: 15px 20px; font-size: 14px; }
.wd-preview img { display: block; max-width: 100%; max-height: 200px; margin: 0 auto 10px; border-radius: 8px; object-fit: contain; }

.wd-check { margin-top: 10px; font-size: 12.5px; line-height: 1.45; color: var(--text-dim); padding-left: 20px; position: relative; }
.wd-check::before { content: ''; position: absolute; left: 4px; top: 6px; width: 8px; height: 8px; border-radius: 50%; background: var(--text-faint); }
.wd-check.tone-busy::before { background: var(--aqua); animation: pulse 1s infinite; }
.wd-check.tone-warn { color: var(--gold); }
.wd-check.tone-warn::before { background: var(--gold); }
.wd-confirm { margin: 8px 0 0 20px; }

.wd-link { margin: 14px 0 0; }
.wd-link label { text-transform: none; letter-spacing: 0; font-size: 12px; font-weight: 600; color: var(--text-dim); }
.wd-link-row { display: flex; gap: 6px; }
.wd-link-row input { flex: 1; min-width: 0; padding: 9px 12px; font-size: 13px; }
.wd-link-row .btn { flex-shrink: 0; }
.wd-to-nick { display: block; margin: 12px 0 2px; font-size: 12.5px; }

@media (max-width: 480px) {
  .wd-overlay { padding: 16px; }
  .wd-modal { padding: 22px 18px; }
  .wd-method { flex-direction: column; align-items: stretch; gap: 10px; }
  .wd-method .btn { max-width: none; }
}

/* Блок «Выдача» наверху инвентаря: строка на заявку, действия справа. */
.wd-box { margin-bottom: 20px; background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); }
.wd-box-head { display: flex; align-items: center; gap: 12px; padding: 14px 16px 10px; }
.wd-box-head .panel-title { margin: 0; }
.wd-row {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: 6px 14px; align-items: center;
  padding: 12px 16px; border-top: 1px solid var(--line-soft);
}
.wd-art { width: 44px; height: 44px; display: grid; place-items: center; background: var(--surface-2); border: 1px solid var(--line-soft); border-radius: 10px; }
.wd-row.is-closed .wd-art { opacity: 0.55; }
.wd-main { min-width: 0; display: grid; gap: 3px; }
.wd-title { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.wd-title b { font-size: 13.5px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wd-title span { font-size: 12px; color: var(--text-dim); white-space: nowrap; }
.wd-meta { font-size: 11px; color: var(--text-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wd-state { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 8px; margin-top: 2px; }
.wd-when { font-size: 11.5px; color: var(--text-dim); }
.wd-op-note { font-size: 12px; line-height: 1.45; color: var(--text-dim); }
.wd-op-note.is-warn { color: var(--gold); }
.wd-actions { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 6px; max-width: 360px; }
.wd-actions:empty { display: none; }
.wd-nick-input {
  width: 150px; padding: 7px 12px;
  background: var(--bg-deep); border: 1px solid var(--line); border-radius: 999px;
  color: var(--text); font: 13px var(--font-body); outline: none;
}
.wd-nick-input:focus { border-color: var(--aqua); box-shadow: 0 0 0 3px rgba(94, 234, 212, 0.12); }
.wd-box-tools { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.wd-all { font-size: 12px; text-decoration: none; }
/* «Убрать из списка» у завершённой заявки: крестик, в «Все выводы» она останется. */
.wd-hide {
  position: relative;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: none;
  color: var(--text-faint);
  cursor: pointer;
}
.wd-hide::before, .wd-hide::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 12px;
  height: 1.5px;
  background: currentColor;
  transform: translate(-50%, -50%) rotate(45deg);
}
.wd-hide::after { transform: translate(-50%, -50%) rotate(-45deg); }
.wd-hide:hover { color: var(--text); border-color: var(--line); }
.wd-hide:disabled { opacity: 0.5; cursor: default; }

@media (max-width: 640px) {
  .wd-row { grid-template-columns: 40px minmax(0, 1fr); padding: 12px; }
  .wd-art { width: 40px; height: 40px; }
  .wd-actions { grid-column: 1 / -1; justify-content: flex-start; max-width: none; }
  .wd-actions .btn { flex: 1 1 auto; }
  .wd-nick-input { flex: 1 1 100%; width: auto; }
}

/* Число на «Инвентаре»: заявки, где ход за игроком. */
.nav-ico { position: relative; display: inline-flex; flex-shrink: 0; font-style: normal; }
/* Пиксельные значки меню: 10 клеток в 20px, без сглаживания. */
.px-ico, .px-art { display: block; image-rendering: pixelated; }
.nav-badge {
  position: absolute; top: -8px; right: -8px;
  min-width: 15px; height: 15px; padding: 0 4px; border-radius: 999px;
  display: grid; place-items: center;
  background: var(--gold); color: #07070d;
  font: 800 10px/1 var(--font-body); font-style: normal; font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 2px var(--bg);
}

.receipt-modal { max-width: 460px; }
.receipt-head { display: grid; gap: 3px; margin-bottom: 12px; }
.receipt-head b { font-family: var(--font-display); font-size: 15px; }
.receipt-head span { font-size: 12.5px; color: var(--text-dim); }
.receipt-kicker { font-size: 10.5px !important; letter-spacing: .12em; text-transform: uppercase; color: var(--aqua) !important; }
.receipt-shot { display: block; border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; background: var(--bg-deep); }
.receipt-shot img { display: block; width: 100%; max-height: 60vh; object-fit: contain; }
.receipt-modal .wd-note { margin: 8px 0 0; }

/* Правило «Спуска» — одна строка вместо трёх плиток со значками. */
.descent-rule { margin: 0 0 16px; font-size: 13px; color: var(--text-dim); }
.descent-rule img { width: 12px; height: 14px; vertical-align: -2px; }

/* ---------- Декор пустых панелей: скалк вардена ----------
   Пиксельная текстура скалка из игры «прорастает» из нижних углов и мягко
   растворяется к центру; под ней едва заметное бирюзовое свечение, которое
   медленно «дышит», как катализатор. У верстака и инвентаря — всегда (по
   просьбе владельца: с предметами декор пропадал), у остальных панелей —
   пока они пустые. */
.forge-picker,
.inv-panel,
.upg-panel:has(.stake-strip > .empty),
.upg-slot:has(.upg-empty),
.state-block:not(.forge-picker .state-block):not(.profile-card .state-block):not(.inv-panel .state-block),
.profile-card:has(.profile-feature:not(.is-glow)) {
  position: relative;
  isolation: isolate;
}
.forge-picker::before,
.inv-panel::before,
.upg-panel:has(.stake-strip > .empty)::before,
.upg-slot:has(.upg-empty)::before,
.state-block:not(.forge-picker .state-block):not(.profile-card .state-block):not(.inv-panel .state-block)::before,
.profile-card:has(.profile-feature:not(.is-glow))::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: url(/assets/warden/sculk.png) 0 100% / 48px 48px repeat;
  image-rendering: pixelated;
  opacity: 0.42;
  -webkit-mask-image: radial-gradient(70% 85% at 0% 100%, #000 10%, transparent 70%), radial-gradient(45% 60% at 100% 100%, rgba(0, 0, 0, 0.7), transparent 70%);
  mask-image: radial-gradient(70% 85% at 0% 100%, #000 10%, transparent 70%), radial-gradient(45% 60% at 100% 100%, rgba(0, 0, 0, 0.7), transparent 70%);
  pointer-events: none;
}
.forge-picker::after,
.inv-panel::after,
.upg-panel:has(.stake-strip > .empty)::after,
.upg-slot:has(.upg-empty)::after,
.state-block:not(.forge-picker .state-block):not(.profile-card .state-block):not(.inv-panel .state-block)::after,
.profile-card:has(.profile-feature:not(.is-glow))::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background:
    radial-gradient(40% 55% at 6% 100%, rgba(41, 223, 235, 0.22), transparent 70%),
    radial-gradient(30% 40% at 100% 100%, rgba(41, 223, 235, 0.08), transparent 70%);
  animation: sculkBreath 6s ease-in-out infinite alternate;
  pointer-events: none;
}
@keyframes sculkBreath {
  from { opacity: 0.55; }
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .forge-picker::after,
.inv-panel::after,
  .upg-panel:has(.stake-strip > .empty)::after,
  .upg-slot:has(.upg-empty)::after,
  .state-block:not(.forge-picker .state-block):not(.profile-card .state-block):not(.inv-panel .state-block)::after,
  .profile-card:has(.profile-feature:not(.is-glow))::after { animation: none; opacity: 0.8; }
}
/* Блоки-заглушки без рамки (пустой инвентарь, «Войди, чтобы…»): у них нет
   края, в который упирается скалк, поэтому пятно — под значком и мягко
   растворяется во все стороны, без резкой линии снизу. */
.state-block:not(.forge-picker .state-block):not(.profile-card .state-block):not(.inv-panel .state-block)::before {
  -webkit-mask-image: radial-gradient(38% 48% at 50% 42%, #000 0%, transparent 100%);
  mask-image: radial-gradient(38% 48% at 50% 42%, #000 0%, transparent 100%);
  opacity: 0.38;
}
.state-block:not(.forge-picker .state-block):not(.profile-card .state-block):not(.inv-panel .state-block)::after {
  background: radial-gradient(28% 40% at 50% 38%, rgba(41, 223, 235, 0.16), transparent 75%);
}

/* ---------- Слой доработок: значок валюты, плитки-иллюстрации, ваучер ---------- */
.coin-glyph { display: inline-block; width: 13px; height: 15px; flex-shrink: 0; object-fit: contain; vertical-align: -0.16em; }
.balance .coin-glyph { vertical-align: 0; }
/* Иллюстрации без прозрачности — плиткой: скругление, тонкая рамка, тень; без ореола. */
.item-img.is-photo { border-radius: 8px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.1), 0 6px 14px rgba(0, 0, 0, 0.35); }
.item-art .glow:has(.is-photo) { filter: none; }
.voucher-note { font-size: 12px; color: var(--text-dim); }


/* ---------- Меню звука ---------- */
.sound-pop { position: fixed; z-index: 320; width: 264px; padding: var(--sp-3) var(--sp-4); background: var(--surface-2); border: 1px solid var(--line-strong); border-radius: var(--r-lg); box-shadow: var(--shadow-pop), var(--inset-hi); display: grid; gap: 2px; animation: rise var(--t-base) var(--ease) both; }
.sound-pop.is-sheet { left: 16px; right: 16px; width: auto; bottom: calc(64px + 12px + env(safe-area-inset-bottom)); }
.switch { position: relative; display: flex; align-items: center; gap: 10px; min-height: 36px; cursor: pointer; font-size: var(--fs-14); font-weight: 600; color: var(--text); }
.switch input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; }
.switch-track { position: relative; flex-shrink: 0; width: 34px; height: 20px; border-radius: 10px; background: var(--surface-3); border: 1px solid var(--line-strong); transition: background var(--t-fast), border-color var(--t-fast); }
.switch-track::after { content: ''; position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--text-dim); transition: transform var(--t-fast) var(--ease), background var(--t-fast); }
.switch input:checked + .switch-track { background: var(--accent); border-color: var(--accent); }
.switch input:checked + .switch-track::after { transform: translateX(14px); background: var(--accent-ink); }
.switch input:focus-visible + .switch-track { box-shadow: 0 0 0 3px var(--accent-soft); }
.switch-text { flex: 1; }
.switch kbd { font: 600 11px/1 var(--font-body); padding: 3px 6px; border: 1px solid var(--line-strong); border-radius: 4px; color: var(--text-faint); }
.switch-main { padding-bottom: 6px; margin-bottom: 4px; border-bottom: 1px solid var(--line-soft); }
.sound-slider { display: grid; gap: 6px; padding: 6px 0 10px; font-size: var(--fs-12); font-weight: 600; color: var(--text-dim); }
.sound-slider input[type="range"] { width: 100%; accent-color: var(--accent); }
.sound-btn[aria-pressed="false"], .sound-toggle[aria-pressed="false"] { color: var(--text-faint); }

/* ---------- Результат одного предмета — компактно: карточка слева, итог и действия справа ---------- */
.result-block.is-single { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--sp-5); padding: var(--sp-4) var(--sp-5); text-align: left; }
.result-block.is-single .result-card { width: 150px; padding: var(--sp-2); }
.result-block.is-single .result-body { display: grid; gap: var(--sp-3); min-width: 0; }
.result-block.is-single .result-head { align-items: flex-start; }
.result-block.is-single .result-actions { justify-content: flex-start; margin-top: 0; }
.result-block.is-single .result-actions .btn-cta { min-width: 0; }
/* Выигрыш ×2…×5 на телефоне — сеткой по три, а не столбиком карточек по
   полэкрана: пять предметов видны сразу, без длинной прокрутки. */
@media (max-width: 820px) {
  .result-wrap.is-multi { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .result-wrap.is-multi .result-card { width: auto; padding: 8px 8px 10px; }
  .result-wrap.is-multi .item-art { height: 76px !important; }
  .result-wrap.is-multi .item-art :is(.item-img, .px) { width: 44px; height: 44px; }
  .result-wrap.is-multi .item-name { font-size: 11px; }
  .result-wrap.is-multi .item-foot { justify-content: center; margin-top: 6px; }
  .result-wrap.is-multi .item-sub { display: none; }
}
@media (max-width: 820px) {
  .result-block.is-single { grid-template-columns: 112px minmax(0, 1fr); gap: var(--sp-3); padding: var(--sp-3); }
  .result-block.is-single .result-card { width: 112px; }
  .result-block.is-single .result-actions { grid-column: 1 / -1; }
}
/* Динамик виден и на телефоне: меню звука должно быть под рукой всегда. */
@media (max-width: 820px) {
  .sound-btn { display: inline-flex; }
}
/* Уже 375px от ника остаётся обрывок буквы: хватает аватара. */
@media (max-width: 374px) {
  .profile-link-name { display: none; }
  .topbar .profile-link { padding: 0 9px; }
}
.sound-note { margin: 4px 0 0; font-size: 12px; color: var(--text-faint); line-height: 1.4; }

/* ---------- Кейс блогера: страница #/b/:slug и пометка «бесплатно по коду» ---------- */
.ocase-price.is-free { font-size: var(--fs-12); font-weight: 600; color: var(--accent); }
.case-buy.is-voucher { max-width: 520px; }
.creator-head { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: var(--sp-8); align-items: start; margin: var(--sp-4) 0 var(--sp-8); }
.creator-head .ocase { width: 100%; }
.creator-copy h1 { font-size: var(--fs-40); font-weight: 800; letter-spacing: -0.03em; line-height: 1; margin: 6px 0 var(--sp-3); }
.creator-lead { max-width: 56ch; color: var(--text-dim); margin: 0 0 var(--sp-4); }
.creator-code { display: inline-flex; align-items: center; gap: 12px; padding: 6px 6px 6px 14px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); color: var(--text-dim); font-size: var(--fs-12); font-weight: 600; }
.creator-code b { font-family: var(--font-mono, ui-monospace, monospace); font-size: var(--fs-20); font-weight: 700; letter-spacing: 0.08em; color: var(--text); }
.creator-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); margin: var(--sp-4) 0; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.creator-stat { display: grid; align-content: start; gap: 2px; padding: 14px; border-right: 1px solid var(--line-soft); min-width: 0; }
.creator-stat:last-child { border-right: 0; }
.creator-stat > b { font-family: var(--font-display); font-size: var(--fs-28); font-weight: 800; line-height: 1.1; }
.creator-stat > span, .creator-stat-label { font-size: var(--fs-12); color: var(--text-dim); }
.creator-best { display: flex; align-items: center; gap: 10px; margin-top: 4px; min-width: 0; }
.creator-best b { display: block; font-size: var(--fs-14); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.creator-best span { font-size: var(--fs-12); color: var(--text-dim); }
.creator-best .coin-glyph { width: 0.8em; height: 0.8em; vertical-align: -0.1em; }
.creator-none { font-size: var(--fs-14); color: var(--text-faint); margin-top: 4px; }
.creator-actions { display: flex; gap: var(--sp-3); flex-wrap: wrap; }
.creator-note { margin: var(--sp-3) 0 0; font-size: var(--fs-12); color: var(--text-faint); }
@media (max-width: 820px) {
  .creator-head { grid-template-columns: 1fr; gap: var(--sp-4); }
  .creator-head > div:first-child { max-width: 260px; }
  .creator-copy h1 { font-size: var(--fs-28); }
  .creator-stats { grid-template-columns: 1fr; }
  .creator-stat { border-right: 0; border-bottom: 1px solid var(--line-soft); }
  .creator-stat:last-child { border-bottom: 0; }
  .creator-actions .btn { flex: 1; }
}

/* Псевдонимы токенов: меню звука и страница блогера написаны на именах новой шкалы. */
:root {
  --accent: var(--aqua);
  --accent-ink: #06060c;
  --accent-soft: rgba(94, 234, 212, 0.14);
  --line-strong: rgba(255, 255, 255, 0.16);
  --r-md: var(--radius-sm);
  --r-lg: var(--radius);
  --fs-12: 12px; --fs-14: 14px; --fs-20: 20px; --fs-28: 28px; --fs-40: 40px;
  --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 20px; --sp-8: 32px;
  --t-fast: 120ms; --t-base: 220ms; --ease: var(--ease-out);
  --shadow-pop: 0 24px 60px rgba(0, 0, 0, 0.55);
  --inset-hi: inset 0 1px 0 rgba(255, 255, 255, 0.05);
}
.crumb { display: inline-block; margin-bottom: 16px; color: var(--text-dim); font-size: 13px; text-decoration: none; }
.crumb:hover { color: var(--text); }
/* Варден в баннере: ширину задаёт CSS, высота — по пропорции картинки. */
.banner-warden { height: auto; }
/* Первый экран страницы кейса: сундук компактнее, чтобы кнопка «Открыть» была видна без прокрутки на 1440×900. */
@media (min-width: 821px) {
  .case-stage { gap: 12px; }
  .case-stage-art { width: 210px; }
}

/* ---------- Бесплатный кейс: первый блок главной, по центру ---------- */
.daily-hero { max-width: 760px; margin: 0 auto 18px; }
.daily-hero .daily-block { padding: 16px 18px; gap: 16px; }
.daily-hero .daily-art { height: 84px; }
.daily-hero .daily-copy b { font-size: 17px; }
.daily-hero .daily-copy > span { white-space: normal; }
.daily-actions { display: flex; gap: 8px; flex-shrink: 0; }
.daily-block.locked { border-color: rgba(233, 180, 76, 0.4); }
.daily-block.locked .daily-art { opacity: 0.75; }
.daily-tasks { list-style: none; display: grid; gap: 4px; margin: 8px 0 0; padding: 0; }
.daily-tasks li { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-dim); }
.daily-tasks li i { font-style: normal; color: var(--text-faint); }
.daily-tasks li.is-done { color: var(--text); }
.daily-task-mark { width: 14px; height: 14px; flex-shrink: 0; border-radius: 4px; border: 1px solid var(--line); background: var(--bg-deep); }
.daily-tasks li.is-done .daily-task-mark { border-color: var(--aqua); background: var(--aqua); box-shadow: inset 0 0 0 2px var(--bg-deep); }
@media (max-width: 720px) {
  .daily-hero { margin-bottom: 14px; }
  .daily-hero .daily-block { flex-wrap: wrap; }
  .daily-actions { width: 100%; }
  .daily-actions .btn { flex: 1; }
}
/* На телефоне заголовок бесплатного кейса переносится, а не обрезается. */
.daily-hero .daily-copy b { white-space: normal; overflow: visible; text-overflow: clip; }
@media (max-width: 560px) {
  .daily-hero .daily-art { height: 64px; }
  .daily-hero .daily-block { gap: 12px; padding: 14px; }
}

/* ---------- Бесплатный кейс: карточка в витрине и панель на странице ---------- */
/* Пилюля «Бесплатно» — та же огранка, что у цены. Пока кейс можно забрать,
   она сразу залита градиентом, а свет под сундуком дышит. */
.ocase.is-free-case .ocase-top { color: var(--text-dim); }
.ocase.is-free-case.is-ready .ocase-top { color: var(--aqua); font-weight: 700; }
.ocase.is-free-case.is-ready .ocase-price { background: var(--grad); color: #06060c; }
.ocase.is-free-case.is-ready .ocase-price::before { opacity: 0; }
.ocase.is-free-case.is-ready .ocase-glow { animation: freeGlow 2.8s ease-in-out infinite alternate; }
@keyframes freeGlow {
  from { opacity: 0.3; }
  to { opacity: 0.7; }
}
@media (prefers-reduced-motion: reduce) {
  .ocase.is-free-case.is-ready .ocase-glow { animation: none; opacity: 0.5; }
}

.free-panel { display: flex; flex-direction: column; align-items: center; gap: 12px; max-width: 520px; margin: 0 auto; padding: 18px 20px; text-align: center; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.free-note { margin: 0; font-size: 13.5px; color: var(--text-dim); line-height: 1.5; }
.free-note .mono { color: var(--gold); font-weight: 700; }
.free-panel .daily-tasks { justify-items: start; text-align: left; }
.free-actions { display: flex; gap: 10px; flex-wrap: wrap; justify-content: center; }
/* Когда можно забрать — просто кнопка, как «Открыть» у обычного кейса: рамка вокруг одной кнопки выглядела как коробка. */
.free-panel.is-ready { padding: 0; background: none; border: 0; }
.free-panel.is-ready .btn-lg { min-width: 260px; }
@media (max-width: 560px) {
  .free-panel { width: 100%; padding: 16px; }
  .free-actions { width: 100%; }
  .free-actions .btn { flex: 1; }
}

/* ---------- Счёт Crypto Bot в окне пополнения ---------- */
/* Белое поле обязательно: QR на тёмном фоне камеры не читаются. */
.pay-qr { width: min(100%, 220px); margin: 0 auto 14px; padding: 10px; background: #fff; border-radius: 10px; }
.pay-qr-svg { display: block; width: 100%; height: auto; }

/* ---------- Привязка Telegram: профиль и страница бесплатного кейса ---------- */
.tg-panel { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.tg-panel .profile-hint { margin: 0; }
.tg-linked { display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--text); }
.tg-linked svg { color: var(--aqua); }
.tg-code { display: grid; gap: 8px; width: min(100%, 420px); }
.tg-code-row { display: flex; align-items: center; gap: 8px; }
/* Команда — моноширинным и крупно: её набирают или копируют в бота. */
.tg-code-cmd { flex: 1; min-width: 0; padding: 9px 12px; border-radius: 10px; background: var(--bg-deep); border: 1px solid var(--line); font-family: var(--font-mono); font-size: 15px; font-weight: 700; letter-spacing: 0.06em; color: var(--text); user-select: all; overflow-wrap: anywhere; }
.tg-code-note { margin: 0; font-size: 12px; color: var(--text-faint); }
.tg-code-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.free-panel .tg-code-slot { display: flex; justify-content: center; width: 100%; }
.free-panel .tg-code { text-align: left; }
.free-note.is-warn { color: var(--gold); }

/* Окно пополнения: согласие перед оплатой. */
.topup-consent { margin: 2px 0 12px; }

/* Подвал: реквизиты оператора и контакты. */
.foot-operator { grid-column: 1 / -1; font-size: 11.5px; line-height: 1.6; color: var(--text-faint); }
.foot-operator a { color: var(--text-dim); }

/* Текст документа, который сервер отдаёт сразу (lib/legal-html.ts), — пока
   не загрузился скрипт, и для роботов без JavaScript. */
.ssr-doc { max-width: 760px; margin: 0 auto; padding: 32px 16px 48px; color: var(--text-dim); line-height: 1.6; font-size: 14px; }
.ssr-doc h1 { color: var(--text); font-size: 26px; margin-bottom: 8px; }
.ssr-doc h2 { color: var(--text); font-size: 17px; margin: 26px 0 8px; text-transform: none; }
.ssr-doc h3 { color: var(--text); font-size: 14px; margin: 16px 0 4px; }
.ssr-doc p, .ssr-doc ul { margin-bottom: 10px; }
.ssr-doc ul { padding-left: 20px; }
.ssr-doc a { color: var(--aqua); }
.ssr-doc dt { color: var(--text-faint); font-size: 12px; }
.ssr-doc dd { margin: 0 0 8px; color: var(--text); }
