/* Оценщик артефактов — оформление мини-аппа.
   Палитра тёмная «под игру», но подхватывает цвета темы Telegram там,
   где это не ломает читаемость. */

:root {
  --bg:        #14161f;
  --bg-soft:   #1c1f2b;
  --card:      #232736;
  --card-hi:   #2b3042;
  --line:      #343a4e;
  --text:      #eceef5;
  --muted:     #949bb2;
  --gold:      #d3bc8e;
  --gold-dim:  #a8946c;
  --good:      #5fd39a;
  --warn:      #f0c05a;
  --bad:       #ef7a7a;
  /* голубой — «идеальный» ориентир: не оценка «хорошо/плохо», а отдельная
     сущность, поэтому и цвет вне шкалы good/warn/bad */
  --info:      #6fb6e8;
  --radius:    14px;
  --tabbar-h:  58px;
  /* Отступ под плавающие кнопки Telegram в полноэкранном режиме (закрыть/
     назад, ещё) — их зона не пересекается с OS-овым safe-area-inset, это
     отдельное значение от Telegram WebApp API. JS выставляет реальное число
     через contentSafeAreaInset/safeAreaInset; 0 — безопасный дефолт для
     остальных клиентов. */
  --tg-safe-top: 0px;
  /* Доп. запас под таб-баром сверх env(safe-area-inset-bottom) — на части
     устройств/клиентов один только safe-area-inset слишком плотно подходит
     к домашней полосе (home indicator). */
  --home-strip: 34px;
  /* Иконка очистки поля поиска — data:URI с готовыми цветами темы (не mask:
     через mask сохраняется только альфа-канал, а тут и кружок, и крестик
     одинаково непрозрачны, поэтому крестик пропадал и оставался сплошной
     кружок — см. ::-webkit-search-cancel-button). Цвет крестика — цвет фона
     самого поля (--bg-soft), чтобы он выглядел прорезанным в кружке. */
  --icon-clear: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231c1f2b' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9' fill='%23949bb2' stroke='none'/%3E%3Cpath d='M9 9l6 6M15 9l-6 6'/%3E%3C/svg%3E");
  --icon-clear-hover: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231c1f2b' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9' fill='%23eceef5' stroke='none'/%3E%3Cpath d='M9 9l6 6M15 9l-6 6'/%3E%3C/svg%3E");
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }

/* Сплошная маска на самой верхней полосе экрана — см. комментарий у
   #safe-top-mask в index.html. Ниже sheet'ов (20/21), но выше вкладок,
   поиска и версий, которые сами по себе тоже sticky в этой зоне. */
#safe-top-mask {
  position: fixed; top: 0; left: 0; right: 0;
  height: calc(env(safe-area-inset-top) + var(--tg-safe-top));
  background: var(--bg);
  z-index: 19;
  pointer-events: none;
}

/* Правила вроде `.sheet { display: flex }` перебивают браузерное `[hidden]`,
   и скрытая шторка продолжает перехватывать клики. Закрываем это раз и навсегда. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 15px;
  line-height: 1.45;
  overscroll-behavior-y: none;
}

body { padding-bottom: env(safe-area-inset-bottom); }

#app { max-width: 720px; margin: 0 auto; }

/* В полноэкранном режиме Telegram (requestFullscreen) страница уходит под
   статус-бар устройства и под плавающие кнопки самого Telegram — без этого
   отступа контент экранов оказывался бы под ними. env() — обычный вырез/чёлка
   ОС, --tg-safe-top — отдельно зона кнопок Telegram (см. :root). Вне
   фуллскрина оба резолвятся в 0, для остальных клиентов ничего не меняется. */
.screen { padding: calc(12px + env(safe-area-inset-top) + var(--tg-safe-top)) 14px 28px; }

/* Экраны-вкладки (Герой/Артефакты/Билды) живут над нижним таб-баром и над
   плавающей кнопкой добавления — резервируем место снизу, чтобы контент не
   прятался под ними. Прочие экраны таб-бар не показывают, но небольшой
   лишний отступ снизу им не мешает — проще резервировать всегда. */
/* Плавающей кнопки добавления больше нет (её роль забрала центральная «+»
   таб-бара) — запас снизу нужен только под сам таб-бар. */
.main-screen { padding-bottom: calc(var(--tabbar-h) + 18px + env(safe-area-inset-bottom) + var(--home-strip)); }

/* «Мои артефакты» и «Билды» держат список поверх, а «+» плавает выше
   таб-бара — обычного запаса .main-screen не хватает, и «+» перекрывает
   последнюю карточку. Резервируем место под сам круг кнопки (52px) с
   отступом, как у screen-pick. */
#screen-storage, #screen-builds {
  padding-bottom: calc(var(--tabbar-h) + 82px + env(safe-area-inset-bottom) + var(--home-strip));
}

/* Пока набирают в поиске, таб-бар и «+» только перекрывают низ списка, по
   которому и листают результаты (см. обработчики focus/blur в app.js).
   Заодно отдаём списку освободившееся место снизу. */
body.searching .tabbar,
body.searching .fab-plus,
body.searching .fab-reset { display: none; }
body.searching .main-screen { padding-bottom: 18px; }
.top-search { padding-top: 6px; }

/* ── шапка ─────────────────────────────────────────────────────────────── */

/* Фуллскрин Telegram кладёт свои плавающие кнопки (закрыть/назад, ещё) поверх
   страницы у самых краёв — фиксированная сетка 40px/1fr/40px держит заголовок
   математически по центру независимо от того, есть ли у экрана кнопка назад
   или меню «⋮»: пустая колонка не хуже занятой держит симметрию. */
.topbar {
  display: grid;
  grid-template-columns: 40px 1fr 40px;
  align-items: start;
  gap: 6px;
  padding: 6px 0 14px;
}
.topbar h1 { margin: 0; font-size: 21px; font-weight: 650; letter-spacing: .2px; }
.topbar .sub { margin: 3px 0 0; color: var(--muted); font-size: 13px; }
.topbar > div { grid-column: 2; text-align: center; min-width: 0; }

/* Заголовок без шапки — экраны без кнопки назад (полагаются на системную
   кнопку Telegram) и без подзаголовка: только имя/заголовок, повыше и
   покомпактнее, чем полноценный .topbar. */
.screen-title { margin: 2px 0 14px; font-size: 21px; font-weight: 650; letter-spacing: .2px; text-align: center; }

.topbar .back { grid-column: 1; justify-self: start; }
.topbar .menu-btn { grid-column: 3; justify-self: end; margin-top: 0; }

.back {
  flex: none;
  width: 34px; height: 34px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--card);
  color: var(--text);
  font-size: 22px; line-height: 1;
  cursor: pointer;
}
.back:active { background: var(--card-hi); }

/* ── поиск ─────────────────────────────────────────────────────────────── */

/* Поиск не липнет к верху сам по себе — только пока в нём набирают текст
   (см. .sticky-focused, включается/выключается фокусом инпута в app.js).
   Иначе залипающий блок просто откусывал экран без пользы, пока пользователь
   не искал ничего конкретного. */
.search-wrap { position: static; padding: 4px 0 10px; background: var(--bg); }
/* top не 0, а отступ под плавающие кнопки Telegram (--tg-safe-top, см. :root)
   — иначе залипшее поле оказалось бы у самого верха экрана и пряталось бы
   под системной шапкой в фуллскрине вместо того, чтобы просто оставаться
   под ней видимым. */
.search-wrap.sticky-focused { position: sticky; top: var(--tg-safe-top); z-index: 5; }

/* Строка поиска + кнопка «⋮» рядом — там, где раньше «⋮» сидела в шапке или
   в строке вкладок, теперь она у поля поиска: ближе к остальным действиям
   экрана и не мешает вкладкам скроллиться по всей ширине. */
.search-row { display: flex; align-items: center; gap: 8px; }
.search-row input { flex: 1; min-width: 0; }
.search-row .menu-btn { flex: none; }
.search-row button.primary { flex: none; }

/* ── переключатель типа артефакта («Мои артефакты») ──────────────────────── */
/* Теперь подписи заменены иконками (кроме «Все»), поэтому текст больше не
   давит ширину — вкладки растянуты поровну, тем же размером и той же
   геометрией, что и фильтр стихий (.elements/.el) на «Билдах»: тот же
   паттерн переключателя-чипов, просто другой набор картинок. */
.slot-tabs { display: flex; gap: 6px; padding: 8px 0 2px; }
.slot-tab {
  flex: 1 1 0;
  min-width: 0;
  padding: 7px 2px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--muted);
  font-size: 13px; font-weight: 600;
  text-align: center;
  white-space: nowrap;
  cursor: pointer;
}
.slot-tab.active { background: var(--card-hi); color: var(--text); border-color: var(--gold-dim); }

/* Слоты, кроме «Все», показаны иконкой предмета в геншин-стилистике вместо
   подписи — компактнее и сразу узнаваемо. Раньше красили через mask в
   сплошной цвет (важна была только альфа) — теперь просто картинка как
   есть, своими цветами, без перекраски. Размер — как у .el img в фильтре
   стихий. */
.slot-tab-ic { display: block; width: 26px; height: 26px; margin: 0 auto; object-fit: contain; }

/* Поисковые поля с type="search" без явного сброса едут на нативный вид
   браузера (светлый фон, своя обводка). Правило по типу, а не по списку
   id: раньше здесь перечислялись конкретные поля, и каждое новое приезжало
   с нативным видом, пока про него не вспомнят. */
input[type="search"] {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--bg-soft);
  color: var(--text);
  font-size: 15px;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
}
input[type="search"]:focus { border-color: var(--gold-dim); }

/* Нативный крестик очистки в WebKit — светлый квадратик, чужеродный на
   тёмном фоне. Подменяем на свою иконку в цвет остального интерфейса
   (mask, а не background: так цвет задаётся переменной темы). */
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  width: 18px; height: 18px;
  cursor: pointer;
  background: var(--icon-clear) center/18px no-repeat;
}
input[type="search"]::-webkit-search-cancel-button:hover { background-image: var(--icon-clear-hover); }


/* ── сетка персонажей ──────────────────────────────────────────────────── */

.char-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(88px, 1fr));
  gap: 10px;
}

.char {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: 6px 5px 8px;
  text-align: center;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.char:active { background: var(--card-hi); }
.char.dim { opacity: .45; }

.char .portrait {
  width: 100%;
  aspect-ratio: 1;
  border-radius: 10px;
  background: var(--bg-soft) center/cover no-repeat;
  display: block;
  margin-bottom: 5px;
}

.char .name {
  font-size: 12px;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.char .rarity-bar { position: absolute; left: 0; right: 0; top: 0; height: 3px; }
.char .no-data { font-size: 10px; color: var(--muted); }

/* ── карточки отрядов ──────────────────────────────────────────────────── */

.team {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: 13px 14px;
  margin-bottom: 11px;
  cursor: pointer;
}
.team:active { background: var(--card-hi); }
/* та же карточка топа/билда внутри «С чем сравниваем» — не кликабельна,
   там незачем ни курсор-указатель, ни отклик на нажатие */
.team.no-click { cursor: default; }
.team.no-click:active { background: var(--card); }
/* заглушка вместо карточки эталона, когда эталонов у героя нет вовсе */
.team.no-profile { border-style: dashed; }
.team.no-profile .empty { margin: 0; padding: 4px 0; }

.team h3 { margin: 0; font-size: 16px; font-weight: 600; }
.team-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 3px; }
.akasha-link-btn {
  flex: none; display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  border: 1px solid var(--line); border-radius: 50%;
  background: var(--bg-soft); color: var(--muted); cursor: pointer;
}
.akasha-link-btn:active { background: var(--card-hi); }
/* по умолчанию 2 строки — длинные комментарии akasha раньше обрезались
   троеточием без возможности дочитать; теперь просто сворачиваем и даём
   кнопку «Показать целиком» (см. .details-toggle и делегированный
   обработчик в init()) */
.team .details {
  margin: 0 0 4px; color: var(--muted); font-size: 12.5px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.team .details.expanded { -webkit-line-clamp: unset; overflow: visible; }
.details-toggle {
  display: block; margin: 0 0 10px; padding: 0;
  border: none; background: none;
  color: var(--gold-dim); font-size: 11.5px; font-weight: 600; cursor: pointer;
}

.mates { display: flex; gap: 8px; margin-bottom: 11px; flex-wrap: wrap; }
/* flex: none — иначе ячейки состава сжимаются по ширине, оставаясь 46px в
   высоту, и круглые аватары превращаются в овалы */
.mate { flex: none; width: 46px; text-align: center; }
.mate .av {
  flex: none;
  width: 46px; height: 46px;
  border-radius: 50%;
  background: var(--bg-soft) center/cover no-repeat;
  border: 2px solid var(--line);
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; color: var(--muted);
}
.mate .nm { font-size: 10px; color: var(--muted); margin-top: 3px; line-height: 1.2; }
/* Пустая ячейка состава — «Билды akasha» напарников не задают. Класс именно
   .blank, а не .empty: .empty — это глобальная заглушка «тут ничего нет» со
   своими отступами, из-за которых кружок раздувался в овал. */
.mate .av.blank { border-style: dashed; opacity: .45; }

.team-sets { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 9px; }

.set-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px 4px 4px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--bg-soft);
  font-size: 12.5px;
}
.set-chip img { width: 22px; height: 22px; border-radius: 50%; background: var(--card); }
.set-chip b { color: var(--gold); font-weight: 600; }

.mains-line { font-size: 12.5px; color: var(--muted); }
.mains-line div { margin-bottom: 2px; }
.mains-line div:last-child { margin-bottom: 0; }
.mains-line b { color: var(--text); font-weight: 500; }

/* ── слоты ─────────────────────────────────────────────────────────────── */

.slots { display: flex; flex-direction: column; gap: 9px; }

.slot {
  display: flex; align-items: center; gap: 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: 10px 12px;
  cursor: pointer;
  min-height: 68px;
}
.slot:active { background: var(--card-hi); }
/* не .empty: этот класс уже занят общим пустым состоянием, которое центрирует
   текст и красит его в серый — пустой слот выглядел бы сломанным */
.slot.vacant { border-style: dashed; }

.slot .icon {
  flex: none;
  width: 46px; height: 46px;
  border-radius: 10px;
  background: var(--bg-soft) center/cover no-repeat;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; color: var(--gold-dim);
}

.slot .info { flex: 1; min-width: 0; }
.slot .slot-name { font-size: 12px; color: var(--muted); }
.slot .slot-main { font-size: 14.5px; font-weight: 600; }
.slot .slot-main .val { color: var(--gold); }
.slot .slot-set { font-size: 12px; color: var(--muted); }
.slot .slot-subs { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

.slot .clear {
  flex: none;
  border: none; background: none;
  color: var(--muted); font-size: 18px;
  padding: 4px 2px; cursor: pointer;
}

/* ── кнопки ────────────────────────────────────────────────────────────── */

.actions { margin-top: 18px; display: flex; flex-direction: column; gap: 9px; }

button.primary {
  padding: 13px;
  border: none;
  border-radius: 12px;
  background: linear-gradient(135deg, var(--gold), var(--gold-dim));
  color: #241f14;
  font-size: 15.5px; font-weight: 650;
  cursor: pointer;
}
button.primary:disabled { opacity: .4; cursor: default; }
button.primary:not(:disabled):active { filter: brightness(.92); }

button.ghost {
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: transparent;
  color: var(--text);
  font-size: 14.5px;
  cursor: pointer;
}
button.ghost:active { background: var(--card); }

button.wide { width: 100%; margin-top: 14px; }

/* ── шторки ────────────────────────────────────────────────────────────── */

.sheet-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,.55);
  z-index: 20;
}

.sheet {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 21;
  max-height: 86vh;
  display: flex; flex-direction: column;
  background: var(--bg-soft);
  border-radius: 18px 18px 0 0;
  border-top: 1px solid var(--line);
  animation: rise .18s ease-out;
}
@keyframes rise { from { transform: translateY(18px); opacity: .4; } }

.sheet-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--line);
}
.sheet-head h2 { margin: 0; font-size: 17px; font-weight: 600; }

.close {
  border: none; background: none;
  color: var(--muted); font-size: 19px;
  padding: 4px 6px; cursor: pointer;
}

.sheet-body {
  padding: 14px 16px 20px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
/* Снизу — тот же запас под домашнюю полосу, что и у таб-бара (--home-strip):
   шторка прижата к низу экрана, и без него кнопки диалога (удалить артефакт
   и т.п.) упираются в home indicator. Когда под телом есть .sheet-foot,
   отступ держит он — иначе запас удвоился бы. */
.sheet-body:last-child {
  padding-bottom: calc(20px + env(safe-area-inset-bottom) + var(--home-strip));
}

/* Кнопка вне .sheet-body — не скроллится вместе со списком сетов, всегда
   видна внизу шторки независимо от того, насколько длинный список. */
.sheet-foot {
  flex: none;
  padding: 12px 16px calc(14px + env(safe-area-inset-bottom) + var(--home-strip));
  border-top: 1px solid var(--line);
  background: var(--bg-soft);
}
.sheet-foot .primary { margin-top: 0; }

/* ── карточка артефакта в списке ───────────────────────────────────────── */

.art {
  display: flex; align-items: center; gap: 11px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  padding: 9px 11px;
  margin-bottom: 8px;
  cursor: pointer;
  position: relative;         /* якорь для .art-owner в углу */
}
.art:active { background: var(--card-hi); }
.art.no-click { cursor: default; margin-bottom: 0; }
.art.no-click:active { background: var(--card); }

/* Чей это артефакт — в правом верхнем углу и только при 2+ аккаунтах.
   Вне потока: справа в строке уже стоит бейдж качества, а подпись должна
   быть именно в углу, над ним. */
.art-owner {
  position: absolute; top: 5px; right: 11px;
  max-width: 45%;
  font-size: 10.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  pointer-events: none;
}

/* ── свайп-удаление карточки артефакта ───────────────────────────────────── */
/* Кнопка удаления больше не сидит в самой карточке — она открывается
   смахиванием влево (см. attachSwipeDelete в app.js). .art-swipe — рамка с
   обрезкой, .art-swipe-body — сама карточка, которая едет поверх кнопки. */
.art-swipe { position: relative; overflow: hidden; border-radius: 12px; margin-bottom: 8px; }
.art-swipe .art-swipe-body.art,
.art-swipe .art-swipe-body.saved {
  margin-bottom: 0;
  position: relative;
  z-index: 1;
  touch-action: pan-y;
}
.art-swipe-action {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: 76px;
  border: none;
  background: var(--bad);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.art .icon {
  flex: none; width: 42px; height: 42px;
  border-radius: 9px;
  background: var(--bg-soft) center/cover no-repeat;
}
/* На «Мои артефакты» картинка сета крупнее — это единственная опора для
   узнавания предмета на глаз теперь, когда карточка не занята кнопкой
   удаления (она открывается смахиванием). */
.art-swipe-body .icon { width: 58px; height: 58px; border-radius: 11px; }
.art .info { flex: 1; min-width: 0; }
.art .line1 { font-size: 14px; font-weight: 600; }
.art .line1 .val { color: var(--gold); }
.art .line2 { font-size: 12px; color: var(--muted); }

/* ── единая карточка артефакта (artCardHtml) ──────────────────────────────
   Одна вёрстка на все экраны: список, выбор в слот, надетое на сборке и
   разбор сравнения. Меняются только три места справа — тег, процент и
   «Подробнее», — поэтому колонка всегда из трёх элементов (пустые <span>
   держат позиции, даже когда что-то из этого не показываем). */
.acard { display: block; }
.acard-main { display: flex; align-items: center; gap: 11px; }
/* .art и .slot остаются flex-контейнерами (в них бывает ещё чекбокс
   массового выделения слева) — сама карточка занимает всё остальное */
.art > .acard-main, .slot > .acard-main { flex: 1; min-width: 0; }

.acard-left { flex: none; width: 46px; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.acard-pic {
  width: 46px; height: 46px; border-radius: 10px;
  background: var(--bg-soft) center/cover no-repeat;
}
.acard-rar { font-size: 12px; font-weight: 600; color: var(--gold); line-height: 1.2; }
.acard-slotname { font-size: 12px; color: var(--muted); text-align: center; line-height: 1.1; }

.acard-mid { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.acard-mainstat { display: flex; align-items: center; gap: 4px; font-size: 14.5px; font-weight: 600; }
.acard-mainstat b { color: var(--gold); font-weight: 600; }
.acard-mainstat .si { width: 24px; height: 24px; vertical-align: middle; }
.acard-setline { display: flex; align-items: center; gap: 4px; font-size: 12px; min-width: 0; }
.acard-setline .lvl { flex: none; color: var(--gold); font-weight: 600; }
.acard-setline .nm { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* доп-статы — сетка 2×2 с отступами: значения выровнены друг под другом */
.acard-subs {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2px 8px; margin-top: 2px;
}
.acard-sub {
  display: flex; align-items: center; gap: 2px; min-width: 0;
  font-size: 11.5px; color: var(--muted); white-space: nowrap;
}
.acard-sub span { overflow: hidden; text-overflow: ellipsis; }
.acard-sub .si { flex: none; width: 24px; height: 24px; }
.acard-sub.good { color: var(--good); }
.acard-sub.bad { color: var(--bad); }

.acard-right {
  flex: none; width: 34px; align-self: stretch;
  display: flex; flex-direction: column; align-items: flex-end; justify-content: space-between;
  gap: 4px;
}
.acard-tag, .acard-pct {
  flex: none; white-space: nowrap;
  border: 1px solid var(--line); border-radius: 200px;
  padding: 2px 6px; font-size: 10px; font-weight: 600; text-align: center;
}
.acard-tag { border-color: var(--gold); color: var(--gold); }
.acard-tag.good { border-color: var(--good); color: var(--good); }
.acard-tag.info { border-color: var(--info); color: var(--info); }
.acard-pct { color: var(--good); border-color: var(--good); }
.acard-cv {
  flex: none; white-space: nowrap;
  border: 1px solid var(--line); border-radius: 200px;
  padding: 2px 6px; font-size: 10px; font-weight: 600; text-align: center;
  color: var(--gold-dim); border-color: var(--gold-dim);
}
.acard-toggle {
  flex: none; border: none; background: none; padding: 0;
  font: inherit; font-size: 10px; font-weight: 600; color: var(--gold);
  white-space: nowrap; cursor: pointer;
}
.acard-close {
  flex: none; border: none; background: none; padding: 0 2px;
  color: var(--bad); font-size: 15px; line-height: 1; cursor: pointer;
}
/* корзина в списке выбора артефакта на слот (см. renderPickList) — тег
   «Надет» там ещё нужен сверху, в отличие от close, поэтому это отдельная
   кнопка снизу, а не замена тега. */
.acard-del {
  flex: none; border: none; background: none; padding: 2px;
  color: var(--bad); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.acard-del svg { width: 15px; height: 15px; }

/* Разбор под карточкой: в разметке он есть всегда, но показывается только
   у раскрытой карточки. Так «Подробнее» переключается прямо в DOM, без
   перерисовки экрана — иначе сбрасывалась горизонтальная прокрутка ленты
   версий, и следующий клик приходился уже по другой карточке. */
.acard-detail { display: none; }
.acard.open > .acard-detail {
  border-top: 1px dashed var(--line);
  margin-top: 11px; padding-top: 9px;
  display: flex; flex-direction: column; gap: 8px;
}
.acard-note-head {
  display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
  font-size: 13px; color: var(--text);
}
.acard-note-head .num { color: var(--muted); }
.acard-note-tail { font-size: 10px; opacity: .8; }
.acard-note-sub { padding-left: 20px; margin-top: 1px; font-size: 10px; color: var(--text); opacity: .8; }
.acard-note-sub b { font-weight: 600; }
.acard-note-ok { font-size: 12px; color: var(--good); }
.acard-hint { font-size: 10.5px; color: var(--muted); margin-bottom: 6px; }
.acard-chip { display: inline-flex; align-items: center; gap: 2px; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.acard-chip .si { width: 24px; height: 24px; }
.acard-chip.good { color: var(--good); }
.acard-chip.bad { color: var(--bad); }

/* ── лента из трёх версий предмета (ваш / топ-N / идеал) ─────────────────── */
.grade-block { margin-bottom: 12px; }
.grade-slot { font-size: 12px; color: var(--muted); margin: 0 0 5px 2px; }
.acard-swiper {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  gap: 8px; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  /* без этого соседние карточки растягиваются по высоте раскрытой (flex по
     умолчанию тянет элементы на всю высоту строки) — свёрнутая карточка
     выглядела как раскрытая, только с пустотой вместо разбора */
  align-items: flex-start;
  /* горизонтальный «доскролл» не должен уходить наружу: в Telegram этот жест
     ловит сам клиент (свайп «назад»/закрыть), и лента переставала листаться */
  overscroll-behavior-x: contain;
  cursor: grab;
}
.acard-swiper.dragging { cursor: grabbing; scroll-snap-type: none; user-select: none; }
.acard-swiper::-webkit-scrollbar { display: none; }
.acard-slide { flex: 0 0 100%; scroll-snap-align: start; min-width: 0; }
.acard-slide .acard {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card); padding: 10px 12px;
}
/* точки — кнопки: свайп в Telegram может перехватывать клиент, поэтому по
   ним ленту можно листать и тапом. Сама точка мелкая, но зона нажатия
   крупная за счёт padding */
.acard-dots { display: flex; justify-content: center; gap: 2px; margin-top: 4px; }
.acard-dot {
  border: none; background: none; padding: 6px 4px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.acard-dot::before {
  content: ''; width: 5px; height: 5px; border-radius: 50%;
  background: var(--line); transition: background .15s ease;
}
.acard-dot.on::before { background: var(--gold); }

/* доп-статы карточки — сеткой 2×2: так значения выровнены друг под другом
   и читаются с одного взгляда, а не выискиваются в сплошной строке через « · » */
.subs-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3px 12px;
  margin-top: 4px;
}
.sub-cell {
  display: flex; align-items: center; gap: 2px;
  min-width: 0;
  font-size: 11.5px; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* внутри плотной сетки 24px раздувал бы карточку — берём заметно крупнее
   прежнего (было ~16px), но без потери компактности списка */
.sub-cell .si { width: 18px; height: 18px; vertical-align: -4px; margin-right: 2px; }
.sub-cell b { color: var(--text); font-weight: 600; margin-left: 2px; }
.art .del {
  flex: none; border: none; background: none;
  color: var(--bad); padding: 6px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.art .badge {
  flex: none;
  font-size: 11px; color: var(--good);
  border: 1px solid var(--good); border-radius: 20px;
  padding: 1px 7px;
}

/* ── форма ─────────────────────────────────────────────────────────────── */

.field { display: block; margin-bottom: 12px; }
.field > span { display: block; font-size: 12.5px; color: var(--muted); margin-bottom: 5px; }
.field > span .hint-inline { color: var(--gold); font-weight: 500; margin-left: 4px; }

/* .num — исторически «числовое поле», но по факту это общий вид поля ввода
   в приложении. Поля с текстом (токен HoYoLAB) цепляем по типу, чтобы не
   вешать на них класс, который врёт про содержимое. */
select, input.num, input[type="password"] {
  width: 100%;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card);
  color: var(--text);
  font-size: 15px;
  outline: none;
  appearance: none;
}
select:focus, input.num:focus, input[type="password"]:focus { border-color: var(--gold-dim); }

.main-value { margin: -4px 0 14px; font-size: 12.5px; color: var(--gold); }

.subs-head {
  display: flex; align-items: baseline; justify-content: space-between;
  margin: 4px 0 8px;
  font-size: 12.5px; color: var(--muted);
}

/* Стат теперь выбирается кнопкой-«пикером», а не <select> — без явного flex
   она тянулась под свой контент и отжимала поле ввода до нечитаемой узкой
   полоски. Название стата короче цифр, поэтому ему достаточно меньшей доли
   строки, а полю ввода — оставляем гарантированный минимум под «999.9». */
/* Пока в форме что-то редактируют, держим запас пустоты снизу: последние
   поля саб-статов стоят у самого низа документа, и без этого запаса
   прокрутке просто некуда их поднять из-под клавиатуры (см. обработчик
   focusin в app.js). Без фокуса отступ схлопывается. */
#screen-new-artifact:focus-within { padding-bottom: 50vh; }

/* stretch, а не center: в «выборе стата» лежит иконка 22px, из-за которой
   он выше поля ввода — раньше они стояли разной высоты. Так поле тянется
   по высоте соседа, чем бы та ни задавалась. */
.sub-row { display: flex; gap: 8px; margin-bottom: 8px; align-items: stretch; }
.sub-row .sub-picker { flex: 1.1; min-width: 0; padding: 11px 10px; }
.sub-row .sub-picker .label { font-size: 13.5px; }
.sub-row input { flex: none; width: 76px; min-width: 76px; text-align: center; padding: 11px 6px; }
.sub-row .rolls {
  flex: none; width: 56px; font-size: 11px; text-align: right; white-space: nowrap;
  display: flex; flex-direction: column; align-items: flex-end; justify-content: center;
  line-height: 1.35;
}
/* «N слаб./сред./макс.» столбиком — общие стили для формы добавления и
   таблицы саб-статов в детальном виде артефакта (см. breakdownLinesHtml). */
.rb-line { display: block; }
.rb-weak { color: var(--bad); }
.rb-medium { color: var(--warn); }
.rb-max { color: var(--good); }
table.rolls .rolls-cell { text-align: right; font-size: 11px; line-height: 1.35; }

.form-error {
  margin: 4px 0 0;
  padding: 9px 11px;
  border-radius: 10px;
  background: rgba(239,122,122,.13);
  color: var(--bad);
  font-size: 13px;
}

/* ── результат ─────────────────────────────────────────────────────────── */

.score-hero {
  position: relative;            /* якорь для имени и кнопок по углам */
  border: 1px solid var(--line);
  border-radius: 18px;
  background: var(--card);
  padding: 20px 16px 18px;
  text-align: center;
  margin-bottom: 14px;
}

/* Имя героя — в левом верхнем углу, действия — в правом, оба вне потока:
   иначе строка с ними отжимала круговой прогресс вниз, и он «уезжал» тем
   сильнее, чем больше кнопок справа. Теперь прогресс всегда на одной
   высоте, независимо от того, сколько кнопок показано. */
.score-hero-head {
  position: absolute; left: 16px; right: 16px; top: 14px;
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 8px; text-align: left; pointer-events: none;
}
.score-hero-name {
  font-size: 16.5px; font-weight: 650; min-width: 0;
  max-width: 55%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.score-hero-actions { display: flex; align-items: flex-start; gap: 6px; flex: none; pointer-events: auto; }
/* сам прогресс отодвигаем от наложенной строки с именем */
.score-hero-head + .gauge { margin-top: 30px; }

/* «Удалить», «Экспортировать», «Редактировать» — рамкой, в столбик друг под
   другом (удаление сверху). */
.icon-btn-stack { display: flex; flex-direction: column; gap: 4px; }

.icon-btn {
  flex: none; border: none; background: none;
  color: var(--muted); padding: 6px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.icon-btn.bad { color: var(--bad); }
.icon-btn.framed {
  border: 1px solid var(--line);
  border-radius: 8px;
}
.icon-btn.framed:active { border-color: var(--gold-dim); background: var(--card-hi); }
.icon-btn.bad.framed { border-color: var(--bad); }
.icon-btn.bad.framed:active { background: var(--card-hi); }

.gauge { position: relative; width: 148px; height: 148px; margin: 0 auto 12px; }
.gauge svg { transform: rotate(-90deg); }
.gauge .num {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.gauge .num b { font-size: 34px; font-weight: 700; line-height: 1; }
.gauge .num small { font-size: 11px; color: var(--muted); margin-top: 3px; }

.score-hero h2 { margin: 0 0 4px; font-size: 19px; }
.score-hero p { margin: 0; color: var(--muted); font-size: 13.5px; }

.part {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  padding: 11px 13px;
  margin-bottom: 9px;
}
.part .head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 6px; }
.part .head b { font-size: 14.5px; font-weight: 600; }
.part .head .pct { font-size: 14.5px; font-weight: 650; }
.part .bar { height: 6px; border-radius: 4px; background: var(--bg-soft); overflow: hidden; }
.part .bar i { display: block; height: 100%; border-radius: 4px; }
.part .detail { margin: 7px 0 0; font-size: 12.5px; color: var(--muted); }
.part .weight { font-size: 11px; color: var(--muted); margin-left: 6px; font-weight: 400; }

/* разбивка «что не так» по конкретным статам — раньше одной строкой через
   «; », теперь построчно, чтобы иконка стата не терялась в общем тексте */
.part-items { display: flex; flex-direction: column; gap: 6px; margin-top: 7px; }
.part-item {
  display: flex; align-items: center; gap: 5px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--muted);
}
.pi-slot { color: var(--text); font-weight: 600; flex: none; }
.pi-val { display: inline-flex; align-items: center; }
.pi-want { color: var(--gold); }
.pi-arrow { color: var(--muted); }
.pi-gap { margin-left: auto; color: var(--warn); }

.block-title { margin: 18px 0 9px; font-size: 13px; color: var(--muted); text-transform: uppercase; letter-spacing: .6px; }

/* «С чем сравниваем» — заголовок блока и «Сменить билд» в одну строку */
.compare-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.compare-head .block-title { margin: 18px 0 9px; }

table.stats { width: 100%; border-collapse: collapse; font-size: 13px; }
table.stats th {
  text-align: right; font-weight: 500; color: var(--muted);
  font-size: 11.5px; padding: 0 0 6px;
}
table.stats th:first-child { text-align: left; }
table.stats td { padding: 6px 0; border-top: 1px solid var(--line); text-align: right; }
table.stats td:first-child { text-align: left; }
table.stats .low { color: var(--bad); }
table.stats .ok { color: var(--good); }

/* Разбор по слотам: цвет полосы слева — насколько предмет подходит билду
   (см. grade_artifacts в scoring.py). */
.grade-list { display: flex; flex-direction: column; gap: 7px; }
.grade-row {
  display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  padding: 8px 11px;
}
.grade-row.good { border-left-color: var(--good); }
.grade-row.ok   { border-left-color: var(--warn); }
.grade-row.weak { border-left-color: var(--bad); }
.grade-row .pic {
  flex: none; width: 34px; height: 34px;
  border-radius: 8px;
  background: var(--bg-soft) center/cover no-repeat;
}
.grade-row .txt { flex: 1; min-width: 0; }
.grade-row .l1 { font-size: 13px; font-weight: 600; }
.grade-row .l2 { font-size: 11.5px; color: var(--muted); margin-top: 1px; }
.grade-row .l2 .val { color: var(--gold); }
/* главный стат — своей строкой под названием сета, чтобы длинное имя сета не
   уносило его на перенос вместе с иконкой */
.grade-row .l2-main { display: flex; align-items: center; gap: 3px; }
.grade-row .l3 { font-size: 11px; color: var(--bad); margin-top: 2px; }
.grade-row .l3.ok { color: var(--muted); }
.grade-row .tag {
  font-size: 10px; font-weight: 600;
  border-radius: 20px; padding: 1px 7px; margin-left: 5px;
  border: 1px solid currentColor;
}
.grade-row.good .tag { color: var(--good); }
.grade-row.ok   .tag { color: var(--warn); }
.grade-row.weak .tag { color: var(--bad); }

.grade-row .l3-row { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.grade-row .l3-row .l3 { margin-top: 0; flex: 1; }
.grade-detail-toggle {
  flex: none; padding: 0; border: none; background: none;
  color: var(--gold-dim); font-size: 10.5px; font-weight: 600; cursor: pointer;
}
.grade-detail {
  display: none;
  margin-top: 7px; padding-top: 7px;
  border-top: 1px dashed var(--line);
}
.grade-detail.open { display: block; }

/* «Эталонный предмет» / «Идеальный предмет» — маленькие чипы под разбором
   точного сравнения (см. renderExactResult/showRefArtifactPreview). */
.ref-preview-row { display: flex; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.chip-btn {
  flex: none; padding: 5px 10px;
  border: 1px solid var(--line); border-radius: 20px;
  background: none; color: var(--gold-dim);
  font-size: 11px; font-weight: 600; cursor: pointer;
}
.chip-btn:active { background: var(--card-hi); border-color: var(--gold-dim); }
.gd-row {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 11px; color: var(--muted);
  padding: 3px 0;
}
.gd-row.need { color: var(--bad); }
.gd-row.above { color: var(--good); }
.gd-stat { flex: 1; min-width: 0; display: flex; align-items: center; gap: 4px; }
/* свой стат и стат эталона — в одну колонку справа, строка под строкой:
   так процент оказывается ровно под процентом, а роллы под роллами */
.gd-nums { flex: none; display: flex; flex-direction: column; align-items: flex-end; }
.gd-val { color: var(--text); white-space: nowrap; }
.gd-row.need .gd-val { color: var(--bad); }
.gd-row.above .gd-val { color: var(--good); }
.gd-ref { white-space: nowrap; }

.advice { list-style: none; padding: 0; margin: 0; }
.advice li {
  border: 1px solid var(--line);
  border-left: 3px solid var(--warn);
  border-radius: 10px;
  background: var(--card);
  padding: 9px 12px;
  margin-bottom: 7px;
  font-size: 13px;
}
/* цвет полосы = насколько срочно менять предмет */
.advice li.sev-high { border-left-color: var(--bad); }
.advice li.sev-mid  { border-left-color: var(--warn); }
.advice li.sev-low  { border-left-color: var(--gold-dim); }

.cv-row {
  display: flex; gap: 10px; margin-bottom: 14px;
}
.cv-box {
  flex: 1;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  padding: 10px 12px;
  text-align: center;
}
.cv-box small { display: block; font-size: 11.5px; color: var(--muted); }
.cv-box b { font-size: 19px; }

/* ── фильтр по стихиям ─────────────────────────────────────────────────── */

.elements { display: flex; gap: 6px; padding: 8px 0 2px; }

.el {
  flex: 1 1 0;
  min-width: 0;
  padding: 7px 2px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  cursor: pointer;
  text-align: center;
  /* невыбранные приглушены, но узнаваемы */
  opacity: .38;
  filter: grayscale(.7);
  transition: opacity .12s, filter .12s;
}
.el img { display: block; width: 26px; height: 26px; margin: 0 auto; }
.el.on { opacity: 1; filter: none; background: var(--card-hi); }

/* ── иконки статов ─────────────────────────────────────────────────────── */

.si {
  display: inline-block;
  width: 24px; height: 24px;
  vertical-align: -7px;
  margin-right: 4px;
  object-fit: contain;
  flex: none;
}

/* ── выбор из списка с картинками ──────────────────────────────────────── */

.picker {
  display: flex; align-items: center; gap: 9px;
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card);
  color: var(--text);
  font-size: 15px;
  text-align: left;
  cursor: pointer;
}
.picker:active { background: var(--card-hi); }
.picker .pic {
  flex: none; width: 30px; height: 30px;
  object-fit: contain;
  border-radius: 7px;
  background: var(--bg-soft);
}
.picker .pic:not([src]), .picker .pic[src=""] { visibility: hidden; }
.picker .label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.picker .chev { flex: none; color: var(--muted); font-size: 19px; }

/* шторка выбора лежит поверх шторки создания артефакта */
.sheet.over { z-index: 23; }
.sheet-backdrop.over { z-index: 22; }

.choice {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px;
  border: 1px solid transparent;
  border-radius: 10px;
  cursor: pointer;
}
.choice:active { background: var(--card); }
.choice.on { border-color: var(--gold); background: var(--card); }
.choice img {
  flex: none; width: 34px; height: 34px;
  object-fit: contain;
  border-radius: 8px;
  background: var(--bg-soft);
}
.choice .nm { flex: 1; min-width: 0; font-size: 14px; }
.choice .sub2 { font-size: 11.5px; color: var(--muted); }

.choice-sym {
  flex: none; width: 34px; height: 34px;
  border-radius: 8px;
  background: var(--bg-soft);
  display: flex; align-items: center; justify-content: center;
  font-size: 17px; color: var(--gold);
}

#choose-search { margin-bottom: 10px; }

/* ── детальный вид артефакта ───────────────────────────────────────────── */

.art-head { display: flex; gap: 12px; align-items: center; margin-bottom: 14px; }
.art-head .pic {
  flex: none; width: 62px; height: 62px;
  border-radius: 12px;
  background: var(--bg-soft) center/cover no-repeat;
}
.art-head .who { flex: 1; min-width: 0; }
.art-head .set { font-size: 15px; font-weight: 600; }
/* не .slot: этот класс уже занят слотом на экране сборки — там крупная
   карточка с рамкой, и подпись превращалась в пустой блок */
.art-head .where { font-size: 12.5px; color: var(--muted); }
.art-head .main { font-size: 14px; margin-top: 3px; }
.art-head .main b { color: var(--gold); }

.q-row { display: flex; gap: 10px; margin-bottom: 14px; }
.q-box {
  flex: 1;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  padding: 9px 11px;
  text-align: center;
}
.q-box small { display: flex; align-items: center; justify-content: center; gap: 4px;
  font-size: 11px; color: var(--muted); margin-bottom: 3px; }
.q-box .q-val { display: flex; align-items: baseline; justify-content: center; gap: 5px; }
.q-box b { font-size: 18px; }
.q-box .cap, .q-box .q-sub { font-size: 11.5px; color: var(--muted); font-weight: 400; }

/* число роллов — цветом сразу видно, «9-рольный» артефакт или нет */
.q-box .q-sub.rolls-low  { color: var(--bad); }
.q-box .q-sub.rolls-mid  { color: var(--warn); }
.q-box .q-sub.rolls-high { color: var(--good); }

.info-btn {
  flex: none;
  width: 15px; height: 15px;
  border: 1px solid var(--muted);
  border-radius: 50%;
  background: none;
  color: var(--muted);
  font-size: 10px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  font-style: italic; font-family: Georgia, serif;
}
.info-btn:active { border-color: var(--gold); color: var(--gold); }

table.rolls { width: 100%; border-collapse: collapse; font-size: 13px; margin-bottom: 6px; }
table.rolls th {
  text-align: right; font-weight: 500; color: var(--muted);
  font-size: 11.5px; padding: 0 0 6px;
}
table.rolls th:first-child { text-align: left; }
table.rolls td { padding: 7px 0; border-top: 1px solid var(--line); text-align: right; }
table.rolls td:first-child { text-align: left; }
table.rolls .cap { color: var(--muted); font-size: 11.5px; }

/* ── «кому подходит» в детальном виде артефакта ────────────────────────── */

.fit-list { display: flex; flex-direction: column; gap: 8px; }
.fit-note { font-size: 12.5px; color: var(--muted); }
.fit-row {
  display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--card); padding: 9px 11px;
}
.fit-ava {
  flex: none; width: 38px; height: 38px;
  border-radius: 10px; object-fit: cover;
  background: var(--bg-soft); border: 1px solid var(--line);
}
.fit-main { flex: 1; min-width: 0; }
.fit-name { font-size: 13.5px; font-weight: 600; }
.fit-label { font-weight: 400; font-size: 11.5px; color: var(--muted); margin-left: 6px; }
.fit-bar {
  height: 5px; border-radius: 3px; margin: 5px 0 4px;
  background: var(--bg-soft); overflow: hidden;
}
.fit-bar i { display: block; height: 100%; border-radius: 3px; }
.fit-why { font-size: 11px; color: var(--muted); }
.fit-pct { flex: none; font-size: 15px; font-weight: 700; }

/* ── артефакт внутри рекомендации ──────────────────────────────────────── */

.rec-art {
  display: flex; align-items: center; gap: 9px;
  margin-top: 8px; padding-top: 8px;
  border-top: 1px dashed var(--line);
}
.rec-art .pic {
  flex: none; width: 34px; height: 34px;
  border-radius: 8px;
  background: var(--bg-soft) center/cover no-repeat;
}
.rec-art .txt { flex: 1; min-width: 0; font-size: 11.5px; color: var(--muted); }
.rec-art .txt b { color: var(--text); font-weight: 600; }
.rec-art .hl { color: var(--gold); font-weight: 600; }

/* доп. статы рекомендованного предмета — раньше одной строкой через «·»,
   теперь таблицей 2×2 (артефакт даёт максимум 4 саб-стата) */
.rec-subs-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 3px 10px; margin-top: 4px;
}
.rec-subs-empty { margin-top: 4px; }

/* ── нижняя навигация ──────────────────────────────────────────────────── */

.tabbar.hidden-bar { display: none; }

.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0;
  z-index: 15;
  height: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--home-strip));
  padding-bottom: calc(env(safe-area-inset-bottom) + var(--home-strip));
  display: flex; align-items: stretch; justify-content: space-around;
  background: var(--bg-soft);
  border-top: 1px solid var(--line);
}

.tabbar-btn {
  flex: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px;
  border: none; background: none;
  color: var(--muted);
  font-size: 11px;
  cursor: pointer;
}
.tabbar-btn svg { width: 23px; height: 23px; }
.tabbar-btn.active { color: var(--gold); }

/* Плавающая кнопка «+» — отдельно от таб-бара, в правом нижнем углу поверх
   контента; своя роль (см. handlePlusClick) не зависит от того, где кнопка
   физически нарисована. */
.fab-plus {
  position: fixed;
  right: 16px;
  bottom: calc(var(--tabbar-h) + 14px + env(safe-area-inset-bottom) + var(--home-strip));
  z-index: 16;
  width: 52px; height: 52px;
  border: none; border-radius: 50%;
  background: linear-gradient(135deg, var(--gold), var(--gold-dim));
  color: #241f14;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  box-shadow: 0 3px 10px rgba(211,188,142,.35);
}
/* На экранах без таб-бара (выбор артефакта в слот) под кнопкой нет панели —
   опускаем её к самому низу, оставив только системный отступ. */
#screen-pick .fab-plus { bottom: calc(16px + env(safe-area-inset-bottom) + var(--home-strip)); }
/* …и резервируем под неё место, чтобы последняя карточка не пряталась */
#screen-pick { padding-bottom: calc(84px + env(safe-area-inset-bottom) + var(--home-strip)); }

.fab-plus svg { width: 24px; height: 24px; }
.fab-plus:active { filter: brightness(.94); }
.fab-plus:disabled { opacity: .4; pointer-events: none; }
.fab-plus.hidden-bar { display: none; }

/* Плавающая кнопка сброса фильтра сетов — только когда фильтр реально
   что-то прячет; левый нижний угол, чтобы не спорить с «+» за правый. */
.fab-reset {
  position: fixed;
  left: 16px;
  bottom: calc(var(--tabbar-h) + 14px + env(safe-area-inset-bottom) + var(--home-strip));
  z-index: 16;
  padding: 11px 16px;
  border: none; border-radius: 20px;
  background: var(--card-hi);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 13px; font-weight: 600;
  cursor: pointer;
  box-shadow: 0 3px 10px rgba(0,0,0,.35);
}
.fab-reset:active { background: var(--card); }


/* ── шапка с меню «⋮» ──────────────────────────────────────────────────── */

.menu-btn {
  flex: none;
  width: 36px; height: 36px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--card);
  color: var(--text);
  font-size: 20px; line-height: 1;
  cursor: pointer;
}
.menu-btn:active { background: var(--card-hi); }

/* ── строка вкладок аккаунтов + меню «⋮» рядом с ней ─────────────────────── */

/* На «Мои артефакты»/«Мои билды» заголовка-шапки больше нет вовсе — экран
   начинается сразу со строки вкладок аккаунтов, поднятой к самому верху (под
   плавающими кнопками Telegram). «⋮» сидит в этой же строке, справа. Сами
   вкладки скроллятся по горизонтали, если аккаунтов много, а кнопка
   остаётся на месте — не уезжает вместе с ними. */
.tabs-row {
  display: flex; align-items: center; gap: 8px;
  margin: 0 0 13px;
}
/* .top — эта строка теперь первый элемент экрана: небольшой зазор под
   отступ .screen (там уже учтён --tg-safe-top), а не полноразмерный margin
   шапки, которой здесь больше нет. */
.tabs-row.top { margin-top: 2px; }
.tabs-row .tabs {
  flex: 1; min-width: 0;
  margin-bottom: 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.tabs-row .tabs::-webkit-scrollbar { display: none; }
.tabs-row .tabs .tab { flex: none; white-space: nowrap; }
/* margin-left:auto, а не justify-content на строке: так кнопка уезжает
   вправо и когда вкладки скрыты (один аккаунт), и когда видны — без
   зависимости от :has(), который старые WebView могут не понимать */
.tabs-row .menu-btn { flex: none; margin-left: auto; }

/* ── массовое выделение ────────────────────────────────────────────────── */

.bulk-bar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px;
  margin-bottom: 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-soft);
  font-size: 13.5px;
}
.bulk-bar span { flex: 1; color: var(--muted); }

button.link {
  border: none; background: none;
  color: var(--text); font-size: 13.5px;
  padding: 6px 4px; cursor: pointer;
}
button.bad {
  border: 1px solid var(--bad);
  border-radius: 10px;
  background: transparent;
  color: var(--bad);
  font-size: 13.5px; font-weight: 600;
  padding: 8px 14px;
  cursor: pointer;
}
button.bad:active { background: rgba(239,122,122,.12); }
button.wide-auto { width: auto; margin-top: 0; }

.pick-box {
  flex: none; width: 20px; height: 20px;
  border: 1.5px solid var(--line);
  border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; color: #241f14;
}
.picked .pick-box { background: var(--gold); border-color: var(--gold); }

/* ── сортировка ────────────────────────────────────────────────────────── */

/* ── фильтр по сетам (в шторке сортировки) ────────────────────────────── */

#set-filter-list { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.set-filter-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  cursor: pointer;
}
.set-filter-row.on { border-color: var(--gold); background: var(--card-hi); }
.set-filter-row img {
  flex: none; width: 30px; height: 30px;
  object-fit: contain;
  border-radius: 7px;
  background: var(--bg-soft);
}
.set-filter-row span { flex: 1; min-width: 0; font-size: 13.5px; }

/* ── чипы статов в шторке сортировки «По статам» ──────────────────────────── */
.stat-chip-grid {
  display: flex; flex-wrap: wrap; gap: 7px;
}
.stat-chip {
  display: flex; align-items: center; gap: 5px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--card);
  color: var(--muted);
  font-size: 12.5px;
  cursor: pointer;
}
.stat-chip img { width: 16px; height: 16px; flex: none; }
.stat-chip.on { border-color: var(--gold); background: var(--card-hi); color: var(--text); }

/* ── список синхронизированных аккаунтов (Настройки) ─────────────────────── */

.account-row {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  margin-bottom: 8px;
}
.account-row .info { flex: 1; min-width: 0; }
.account-row .nm { font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
.account-row .uid { font-size: 12px; color: var(--muted); margin-top: 1px; }
.account-row .badge-primary {
  flex: none;
  font-size: 10px; font-weight: 600;
  color: #241f14;
  background: linear-gradient(135deg, var(--gold), var(--gold-dim));
  border-radius: 20px;
  padding: 1px 8px;
}
.account-row .sync {
  flex: none; border: none; background: none;
  color: var(--muted); padding: 6px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.account-row .del {
  flex: none; border: none; background: none;
  color: var(--bad); padding: 6px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}

/* ── подтверждение действия ───────────────────────────────────────────── */

#confirm-buttons { display: flex; flex-direction: column; gap: 9px; margin-top: 4px; }

.sort-dir { display: flex; gap: 8px; margin-top: 12px; }
.dir-btn {
  flex: 1;
  padding: 11px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card);
  color: var(--text);
  font-size: 13.5px;
  cursor: pointer;
}
.dir-btn.active { border-color: var(--gold); background: var(--card-hi); color: var(--gold); }

/* ── вкладки ───────────────────────────────────────────────────────────── */

.tabs {
  display: flex; gap: 6px;
  padding: 4px;
  margin-bottom: 13px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--bg-soft);
}
.tab {
  flex: 1;
  padding: 9px 6px;
  border: none;
  border-radius: 9px;
  background: transparent;
  color: var(--muted);
  font-size: 14px; font-weight: 550;
  cursor: pointer;
}
.tab.active { background: var(--card-hi); color: var(--text); }
.tab small { display: block; font-size: 11px; font-weight: 400; opacity: .75; }

/* ── оружие ────────────────────────────────────────────────────────────── */

.weapons { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 9px; }

.weapon-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px 3px 3px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--bg-soft);
  font-size: 12.5px;
}
.weapon-chip img {
  width: 24px; height: 24px; border-radius: 6px;
  background: var(--card); object-fit: cover;
}
.weapon-chip .cnt { color: var(--muted); font-size: 11px; }

/* ── сохранённые билды ─────────────────────────────────────────────────── */

.saved {
  display: flex; align-items: center; gap: 11px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  padding: 10px 12px;
  margin-bottom: 8px;
  cursor: pointer;
}
.saved:active { background: var(--card-hi); }
.saved.picked { border-color: var(--gold); }

.saved .box {
  flex: none; width: 22px; height: 22px;
  border: 1.5px solid var(--line);
  border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; color: #241f14;
}
.saved.picked .box { background: var(--gold); border-color: var(--gold); }

.saved .av-wrap { position: relative; flex: none; }
.saved .av {
  width: 40px; height: 40px;
  border-radius: 50%;
  background: var(--bg-soft) center/cover no-repeat;
  border: 2px solid var(--line);
}
.saved .set-badge {
  position: absolute; right: -5px; bottom: -3px;
  width: 19px; height: 19px;
  border-radius: 50%;
  background: var(--card) center/cover no-repeat;
  border: 1.5px solid var(--bg-soft);
}
.saved .info { flex: 1; min-width: 0; }
.saved .nm { font-size: 14px; font-weight: 600; }
.saved .lb {
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.saved .dt { font-size: 11px; color: var(--muted); }
.saved .vc {
  font-size: 10.5px; color: var(--gold);
  border: 1px solid var(--gold-dim); border-radius: 20px;
  padding: 0 6px; margin-left: 5px;
}
.saved .sc { flex: none; font-size: 17px; font-weight: 700; }
/* процент и под ним владелец — правая колонка карточки */
.saved .sc-wrap { flex: none; text-align: right; }
/* чей это герой — только при 2+ синхронизированных аккаунтах */
.saved .owner {
  flex: none;
  font-size: 10.5px; color: var(--muted);
  max-width: 84px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  margin-top: 2px;
}

/* синхронизированный герой без единой посчитанной версии — приглушённая
   карточка, чтобы не путать с реальным результатом */
.saved.pending { border-style: dashed; }
.saved .pending-label { color: var(--gold-dim); font-style: italic; }
.saved .del {
  flex: none; border: none; background: none;
  color: var(--bad); font-size: 15px; padding: 6px; cursor: pointer;
}

/* ── версии билда персонажа ────────────────────────────────────────────── */

.history-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
}
.history-toolbar .sub { margin: 0; color: var(--muted); font-size: 13px; }

/* Липнут к верху экрана при скролле, чтобы переключать версии можно было
   без прокрутки назад — и сжимаются, чтобы не отъедать слишком много места
   у контента, пока висят поверх него. top — отступ под плавающие кнопки
   Telegram (--tg-safe-top, см. :root и .search-wrap.sticky-focused) —
   иначе залипшие чипы оказались бы у самого верха и в фуллскрине прятались
   бы под системной шапкой вместо того, чтобы просто оставаться под ней. */
.versions {
  display: flex; gap: 8px; overflow-x: auto;
  padding: 8px 0 8px;
  margin: 0 -14px 14px;
  padding-left: 14px; padding-right: 14px;
  position: sticky; top: var(--tg-safe-top); z-index: 6;
  background: var(--bg);
  transition: padding .15s ease;
}
.versions.shrink { padding-top: 4px; padding-bottom: 4px; }
.version-chip {
  flex: none;
  padding: 8px 12px;
  border: 1px solid var(--line);
  border-radius: 11px;
  background: var(--card);
  text-align: center;
  cursor: pointer;
  min-width: 84px;
  transition: padding .15s ease, transform .15s ease;
}
.versions.shrink .version-chip { padding: 5px 10px; transform: scale(.92); }
.version-chip.active { border-color: var(--gold); background: var(--card-hi); }
.version-chip .vsc { font-size: 15px; font-weight: 700; }
.version-chip .vdt { font-size: 10.5px; color: var(--muted); margin-top: 2px; white-space: nowrap; }
.version-chip .vac { font-size: 10.5px; color: var(--gold-dim); margin-top: 1px; white-space: nowrap; }
.versions.shrink .vdt, .versions.shrink .vac { display: none; }

table.cmp .better { color: var(--good); }
table.cmp .worse  { color: var(--bad); }

/* ── все билды за карточкой топа/билда ────────────────────────────────── */

#all-builds-title { margin: 0 0 12px; color: var(--muted); font-size: 13px; }

.all-builds-btn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; margin-top: 10px; padding: 9px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-soft); color: var(--text);
  font-size: 13px; font-weight: 600; cursor: pointer;
}
.all-builds-btn:active { background: var(--card-hi); }

.pbuild {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--card);
  margin-bottom: 8px;
  overflow: hidden;
}
.pbuild-head {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 11px 13px;
  border: none; background: none; color: var(--text);
  font-size: 13.5px; cursor: pointer;
}
.pbuild-nm { flex: 1; min-width: 0; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pbuild-cv { flex: none; color: var(--gold); font-weight: 600; }
.pbuild-head .chev { flex: none; color: var(--muted); font-size: 19px; transition: transform .15s ease; }
.pbuild.open .pbuild-head .chev { transform: rotate(90deg); }
.pbuild-arts { display: none; padding: 0 11px 11px; }
.pbuild.open .pbuild-arts { display: block; }
.pbuild-arts .art { cursor: default; }
.pbuild-arts .art:active { background: var(--card); }
.pbuild-compare-btn {
  display: block; width: 100%; margin: 0; padding: 10px 13px;
  border: none; border-top: 1px solid var(--line); background: none;
  color: var(--gold-dim); font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.pbuild-compare-btn:active { background: var(--card-hi); color: var(--gold); }

.exact-note { padding: 12px; font-size: 13px; color: var(--muted); line-height: 1.4; }
.exact-note b { color: var(--text); }

/* Место в таблице лидеров рядом с ником — и в списке «Топ-10», и на
   карточке выбранного игрока (см. playerProfileCard/teamCardHtml). */
.pbuild-rank, .player-rank {
  flex: none; font-size: 11px; font-weight: 700; color: var(--gold);
  border: 1px solid var(--gold-dim); border-radius: 20px; padding: 2px 8px;
  white-space: nowrap;
}
.player-line { display: flex; align-items: center; gap: 8px; margin: 2px 0 8px; flex-wrap: wrap; }
.player-nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.player-cv { flex: none; color: var(--gold); font-weight: 600; font-size: 12.5px; }

/* ── результат импорта витрины ─────────────────────────────────────────── */

.imported {
  display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  padding: 7px 11px;
  margin-bottom: 6px;
}
.imported .av {
  flex: none; width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--bg-soft) center/cover no-repeat;
  border: 2px solid var(--line);
}
.imported .nm { flex: 1; min-width: 0; font-size: 13.5px; }
.imported .nm small {
  display: block; font-size: 11px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.imported .cnt { flex: none; font-size: 12px; color: var(--muted); }

/* ── сравнение ─────────────────────────────────────────────────────────── */

.cmp-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; margin-bottom: 16px; }

table.cmp { border-collapse: collapse; font-size: 13px; min-width: 100%; }
table.cmp th, table.cmp td {
  padding: 8px 10px;
  border-top: 1px solid var(--line);
  text-align: center;
  white-space: nowrap;
}
table.cmp th:first-child, table.cmp td:first-child {
  text-align: left;
  position: sticky; left: 0;
  background: var(--bg);
  color: var(--muted);
  font-weight: 400;
}
table.cmp td:first-child .si { width: 16px; height: 16px; vertical-align: -3px; margin-right: 3px; }
table.cmp thead th { border-top: none; vertical-align: bottom; }
table.cmp .hero { display: flex; flex-direction: column; align-items: center; gap: 4px; }
table.cmp .hero img { width: 38px; height: 38px; border-radius: 50%; background: var(--bg-soft); }
table.cmp .hero b { font-size: 12.5px; font-weight: 600; }
table.cmp .hero small { color: var(--muted); font-size: 10.5px; max-width: 110px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
table.cmp .big { font-size: 18px; font-weight: 700; }
table.cmp .best { color: var(--good); }

/* Имя героя — в углу таблицы, слева от колонок версий (отдельной шапки у
   экрана больше нет). */
.cmp-hero { display: flex; align-items: center; gap: 8px; }
.cmp-hero .av {
  flex: none; width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--bg-soft) center/cover no-repeat;
  border: 2px solid var(--line);
}
.cmp-hero .nm { font-size: 14px; font-weight: 650; color: var(--text); }
/* название билда длинное — единственная строка, которой можно переноситься */
table.cmp td.cmp-build {
  white-space: normal;
  max-width: 140px;
  font-size: 11.5px;
  color: var(--muted);
}

/* заголовки-разделители секций («Артефакты», «Саб-статы») внутри той же
   таблицы — не отдельная таблица, чтобы колонки версий не разъезжались */
table.cmp .cmp-section td {
  text-align: left;
  color: var(--gold-dim);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .5px;
  font-weight: 600;
  background: var(--bg);
  position: static;
}

.cmp-art { display: flex; flex-direction: column; align-items: center; gap: 3px; }
.cmp-art-pic {
  width: 26px; height: 26px;
  border-radius: 7px;
  background: var(--bg-soft) center/cover no-repeat;
}
.cmp-art-txt { display: flex; align-items: center; gap: 2px; font-size: 11.5px; white-space: nowrap; }
.cmp-art-txt .si { width: 16px; height: 16px; margin-right: 1px; vertical-align: -3px; }

/* ── прочее ────────────────────────────────────────────────────────────── */

.hint {
  margin: 0 0 12px;
  padding: 9px 11px;
  border-radius: 10px;
  border-left: 3px solid var(--gold-dim);
  background: var(--card);
  color: var(--muted);
  font-size: 12.5px;
}

.actions.tight { margin-top: 0; margin-bottom: 12px; }

.empty { color: var(--muted); text-align: center; padding: 26px 10px; font-size: 14px; }

/* ── подключение HoYoLAB в шторке синхронизации ────────────────────────── */
.hoyo-note { font-size: 12.5px; color: var(--muted); margin: 0 0 10px; line-height: 1.45; }
.hoyo-note b { color: var(--text); }
.hoyo-help {
  margin-bottom: 14px; font-size: 12px; color: var(--muted);
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-soft); padding: 8px 11px;
}
.hoyo-help summary {
  cursor: pointer; color: var(--gold-dim); font-weight: 600;
  font-size: 12.5px; padding: 2px 0;
}
.hoyo-help ol { margin: 8px 0 0; padding-left: 20px; line-height: 1.55; }
.hoyo-help li { margin-bottom: 5px; }
.hoyo-help b { color: var(--text); }
.hoyo-help p { margin: 10px 0 0; line-height: 1.45; }
/* вкладки внутри шторки: у .tabs снизу большой отступ под контент экрана,
   в шторке он лишний */
#import-tabs { margin-bottom: 14px; }
.hoyo-status { font-size: 13px; color: var(--good); margin: 0 0 10px; }
/* разбор не удался по части предметов — таблица кодов статов HoYoLAB могла
   разойтись с реальностью, см. PROPERTY_TYPE в hoyolab.py */
.hoyo-problems {
  font-size: 11.5px; color: var(--warn); margin: 10px 0 0;
  border-left: 3px solid var(--warn); padding-left: 9px; line-height: 1.5;
}

/* мелкая подпись внизу настроек — автор и поддержка звёздами */
.settings-footer { margin-top: 28px; padding-top: 14px; border-top: 1px solid var(--line); }
.settings-footer p { margin: 0 0 6px; font-size: 12px; color: var(--muted); }
.footer-link {
  background: none; border: none; padding: 0; margin: 0;
  font: inherit; font-size: 12px; color: var(--gold-dim);
  cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.footer-link:hover { color: var(--gold); }

.toast {
  position: fixed;
  left: 50%; bottom: 24px;
  transform: translateX(-50%);
  z-index: 40;
  padding: 10px 16px;
  border-radius: 20px;
  background: rgba(20,22,31,.96);
  border: 1px solid var(--line);
  font-size: 13.5px;
  max-width: 90vw;
  display: flex; align-items: center; gap: 12px;
}
.toast-msg { white-space: nowrap; }
.toast-action {
  flex-shrink: 0;
  border: none; background: none; padding: 0;
  font: inherit; font-size: 13.5px; font-weight: 700;
  color: var(--gold);
  white-space: nowrap;
}

.loader {
  position: fixed; inset: 0;
  display: none; align-items: center; justify-content: center;
  background: rgba(20,22,31,.6);
  z-index: 50;
}
.loader.on { display: flex; flex-direction: column; gap: 12px; }
/* подпись под спиннером — что именно грузится: пустой оверлей выглядел как
   зависание, и по экрану начинали тыкать, не дождавшись загрузки */
.loader-hint { font-size: 13px; color: var(--muted); text-align: center; max-width: 70vw; }
.spin {
  width: 34px; height: 34px;
  border: 3px solid var(--line);
  border-top-color: var(--gold);
  border-radius: 50%;
  animation: sp .8s linear infinite;
}
@keyframes sp { to { transform: rotate(360deg); } }

/* ── достижения ──────────────────────────────────────────────────────── */

/* Версий полсотни — .slot-tabs (равноширинные чипы в один ряд) их бы
   раздавил до нечитаемости. Тут чипы своей ширины, переносятся на новую
   строку и разбиты на подписанные разделы (v1, v2, ...) — только заголовки
   для ориентира, кликабелен исключительно сам чип версии; выбор
   множественный, см. achState.ver в app.js. */
.ach-ver-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.ach-ver-tab {
  flex: 0 0 auto;
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  color: var(--muted);
  font-size: 13px; font-weight: 600;
}
.ach-ver-tab.active { background: var(--card-hi); color: var(--text); border-color: var(--gold-dim); }
.ach-ver-all { margin-bottom: 10px; }
.ach-ver-section { margin-bottom: 10px; }
.ach-ver-section-title { font-size: 11px; color: var(--muted); font-weight: 600; margin-bottom: 4px; }

/* Свой чекбокс в стиле приложения вместо системного — тот же язык, что и у
   остальных переключателей (карточные тона, золото на отметке). appearance:
   none снимает нативный вид, дальше рисуем сами: рамка в цвет .card/.line,
   на отметке — заливка золотом с галочкой из двух повёрнутых полосок
   (border, не текст/иконка — так галочка всегда ровно по центру и своего
   цвета без лишних SVG). */
.ach-checkbox {
  appearance: none; -webkit-appearance: none;
  width: 20px; height: 20px; flex-shrink: 0;
  border: 1.5px solid var(--line);
  border-radius: 6px;
  background: var(--card);
  position: relative;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.ach-checkbox:checked {
  background: var(--gold-dim);
  border-color: var(--gold-dim);
}
.ach-checkbox:checked::after {
  content: '';
  position: absolute;
  left: 6px; top: 2px;
  width: 5px; height: 10px;
  border: solid var(--bg);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

.ach-hide-done-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 14px; padding: 4px 0;
}

.ach-total {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 13px; color: var(--muted); margin: 4px 2px 10px;
}
.ach-total-percent { font-weight: 700; flex-shrink: 0; }
/* 100% — золото, 80-99% — зелёный, 40-79% — жёлтый, ниже — красный (см. просьбу) */
.pct-gold   { color: var(--gold); }
.pct-green  { color: var(--good); }
.pct-yellow { color: var(--warn); }
.pct-red    { color: var(--bad); }

.ach-group {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  margin-bottom: 8px;
  overflow: hidden;
}
.ach-group summary {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 12px;
  cursor: pointer;
  list-style: none;
  font-size: 14px;
  font-weight: 600;
  min-height: 44px;
}
.ach-group summary::-webkit-details-marker { display: none; }
.ach-group-icon {
  width: 32px; height: 32px; flex-shrink: 0;
  border-radius: 6px;
  object-fit: cover;
}
.ach-group-name { flex: 1; min-width: 0; }
.ach-group summary small { flex-shrink: 0; font-weight: 400; color: var(--muted); font-size: 12px; }
.ach-group-check { display: flex; flex-shrink: 0; cursor: pointer; }

.ach-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 12px;
  border-top: 1px solid var(--line);
  cursor: pointer;
}
.ach-row .ach-checkbox { margin-top: 3px; }
.ach-row-body { flex: 1; min-width: 0; }
.ach-row-name { font-size: 13.5px; font-weight: 500; }
.ach-row.done .ach-row-name { color: var(--muted); text-decoration: line-through; }
.ach-row-desc { font-size: 12px; color: var(--muted); margin-top: 2px; }
.ach-row-meta {
  display: flex; flex-direction: column; align-items: flex-end; gap: 3px;
  font-size: 11px; color: var(--muted); flex-shrink: 0;
}
.ach-ver { opacity: .8; }
.ach-reward { color: var(--gold-dim); }
.ach-sync-badge { font-size: 10.5px; color: var(--gold-dim); font-weight: 400; }

/* ── сундуки/феи/испытания по регионам ───────────────────────────────── */

#ach-top-tabs { margin-bottom: 4px; }

.chest-region {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--card);
  padding: 12px;
  margin-bottom: 8px;
}
.chest-region-head {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-bottom: 10px;
}
/* title растягивается на всё свободное место — иначе с justify-content:
   space-between на трёх элементах (title/percent/toggle) чип процента
   гулял по разной позиции в зависимости от длины названия региона вместо
   того, чтобы всегда стоять у правого края (см. просьбу) */
.chest-region-title { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 1; }
.chest-region-icon {
  width: 28px; height: 28px; flex-shrink: 0;
  border-radius: 6px;
  object-fit: cover;
}
.chest-region-name { font-size: 14px; font-weight: 600; }
.chest-region-percent {
  flex-shrink: 0;
  font-size: 12px; font-weight: 600;
  background: var(--card-hi);
  border-radius: 8px;
  padding: 3px 8px;
}
.chest-collapse-btn {
  flex-shrink: 0;
  width: 26px; height: 26px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card-hi);
  color: var(--text);
  font-size: 13px; line-height: 1;
}
.chest-info-btn {
  flex-shrink: 0;
  width: 20px; height: 20px;
  border: none; background: none;
  color: var(--muted);
  font-size: 15px; line-height: 1;
  margin-left: 4px;
  vertical-align: middle;
}
/* один пункт (сундуки/феи/...) — строго одна строка, без переноса на
   мобиле: слева подпись фиксированной ширины, справа минус/поле/плюс/максимум
   плотной группой — раньше при переносе строки два ряда контролов съезжались
   боком друг к другу (плюс от сундуков прилипал к минусу от фей) */
.chest-counters { display: flex; flex-direction: column; gap: 8px; }
.chest-counter { display: flex; align-items: center; gap: 8px; }
.chest-cat-label { font-size: 12px; color: var(--muted); flex: 1; min-width: 0; }
.chest-counter-controls { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.chest-btn {
  width: 36px; height: 36px; flex-shrink: 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--card-hi);
  color: var(--text);
  font-size: 18px; font-weight: 600;
  line-height: 1;
}
.chest-input {
  width: 52px; flex-shrink: 0;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--bg);
  color: var(--text);
  padding: 7px 2px;
  font-size: 14px;
}
/* фиксированная ширина — иначе «из 1139» и «из 16» занимают разную
   ширину и сдвигают −/+ левее/правее от строки к строке (см. просьбу) */
.chest-remain {
  font-size: 11px; color: var(--muted);
  flex-shrink: 0; white-space: nowrap;
  width: 50px;
}
