:root{
  /* тема только тёмная: тема-токены = dark-блок 2902 (светлая выпилена) */
  --g:#2AABEE; --g2:#229ED9; --lime:#5AB8F0;
  --shell:#0A0F16; --sheet:#0a0a0c;
  --card:#131316; --mint:#1a1a1e; --line:#232327;
  --t1:#f5f5f5; --t2:#a8a8ad; --t3:#6c6c72;
  --ok:#22C55E; --warn:#EBB14A; --off:#D8DED8; --bad:#E0533B;
  --bar:#1a1a1e;
  --ctl:#131316; --ctl-h:#1a1a1e; --mint-bd:rgba(42,171,238,.16);
  /* Скелетоны: холодные нейтральные тона под bluish --sheet, мягкий шиммер
     (раньше зеленоватый --ctl + белый 38% читался как тёплая жёлтая подсветка). */
  --skel-base:#131316; --skel-sheen:rgba(255,255,255,.05);
  --r-card:22px; --r-sheet:26px; --r-ctl:13px;
  --ff-head:'Bricolage Grotesque',sans-serif;
  --ff-body:'Hanken Grotesk',system-ui,sans-serif;
  --ff-num:'Poppins',sans-serif;
  --accent-1:#e040fb; --accent-2:#7c4dff;
  --accent-grad:linear-gradient(135deg,#e040fb,#7c4dff);
  /* strong custom easings (built-in CSS easings are too weak) */
  --ease-out:cubic-bezier(0.23,1,0.32,1);
  --ease-out-soft:cubic-bezier(0.33,1,0.68,1);
  /* Пружина со СДЕРЖАННЫМ отскоком — появление нового пузыря в чате.
     Отскок намеренно слабый (1.4, не 1.56): оператор видит эту анимацию
     сотни раз в день, заметная пружина приедается на третий день. */
  --ease-spring:cubic-bezier(0.34,1.4,0.5,1);
  /* Длительности движения. Единый словарь: до этого тайминги были разбросаны
     вразнобой (.1s/.12s/.15s/.18s/160ms/380ms/1.3s) и не согласованы. */
  --dur-1:120ms;   /* нажатие, hover */
  --dur-2:180ms;   /* галочки, мелкие переходы */
  --dur-3:240ms;   /* поповеры, кроссфейды, ВЫХОД элемента */
  --dur-4:360ms;   /* появление пузыря, панели */
  /* depth language — нейтральные мягкие тени (Batch 3) */
  --shadow-card:0 1px 2px rgba(16,22,15,.04), 0 8px 20px -14px rgba(16,22,15,.16);
  --shadow-card-hover:0 2px 5px rgba(16,22,15,.06), 0 22px 44px -22px rgba(16,22,15,.26);
  --shadow-pop:0 2px 6px rgba(16,22,15,.06), 0 16px 38px -12px rgba(16,22,15,.24);
  /* scrollbars — тема-зависимые (Batch 5) */
  --scroll-thumb:#232327; --scroll-thumb-hover:#2e2e33;
}
/* ===== RESPONSIVE BREAKPOINTS (канон) =====
   lg ≤1024px — узкий ноут | md ≤768px — планшет/нав→бар | sm ≤480px — телефон
   Только эти 3 порога в max-width. prefers-reduced-motion/hover — не размерные. */
:root{ --safe-b: env(safe-area-inset-bottom, 0px); }
*{box-sizing:border-box}
body{font-family:var(--ff-body)}
h1,h2,h3,.page-heading{font-family:var(--ff-head);letter-spacing:-.012em;color:var(--t1)}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

:root {
  --bg:         #141414;
  --bg-sidebar: #111111;
  --bg-card:    #1c1c1c;
  --bg-input:   #1c1c1c;
  --bg-hover:   #222222;
  --border:     rgba(255,255,255,.06);
  --hdr-h:      56px;
  /* legacy lime accent unified to brand blue (--g); see spec 2026-06-04 */
  --green:      var(--g);
  --green-dim:  rgba(42,171,238,.12);
  --green-glow: rgba(42,171,238,.3);
  /* status / positive-value green — kept lime, used only by online/active/sent/trend */
  --online:     #a3e635;
  --amber:      #fbbf24;
  --red:        #f87171;
  --text:       #f1f5f9;
  --text-2:     #94a3b8;
  --text-3:     #4b5563;
  /* бренд-голубой акцент (= --g), задан тема-агностично, чтобы var(--accent)
     резолвился и в светлой теме; тёмная тема даёт свои surface-токены сверху */
  --accent:     #2aabee; --accent-dim:#1d7fb3; --accent-glow:rgba(42,171,238,.20); --accent-soft:rgba(42,171,238,.08);
  --sidebar-w:  230px;
  --right-w:    270px;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--ff-body);
  min-height: 100vh;
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}


.form-group { margin-bottom: 14px; }
.form-label { display: block; font-size: 12px; color: var(--text-2); margin-bottom: 6px; font-weight: 500; }

.form-input {
  width: 100%;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl);
  padding: 10px 13px;
  color: var(--text);
  font-size: 13.5px;
  font-family: inherit;
  outline: none;
  transition: border-color .15s;
}

.form-input:focus { border-color: var(--auth-accent-soft, rgba(42,171,238,.4)); }
textarea.form-input { resize: vertical; min-height: 88px; line-height: 1.55; }
select.form-input { height: 42px; padding-top: 0; padding-bottom: 0; }

.form-input:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.field-row-disabled .field-label {
  opacity: 0.4;
}

.checkbox-row {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-size: 13.5px;
  color: var(--text);
}

.checkbox-row input[type="checkbox"] {
  width: 16px;
  height: 16px;
  cursor: pointer;
}

/* responsive: стек на узких экранах — сверху белая (QR), снизу «Как войти?» */

/* ── BUTTONS ──────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 10px 18px; border-radius: var(--r-ctl);
  font-size: 13px; font-weight: 600;
  cursor: pointer; border: none; transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s, transform .15s;
  font-family: inherit; white-space: nowrap; width: 100%;
  letter-spacing: -.1px;
}

.btn-primary {
  background: var(--green); color: #111;
  box-shadow: 0 4px 14px var(--green-glow);
}
.btn-primary:hover { transform: translateY(-1px); }

/* Находка 5: у .btn/.btn-primary не было :disabled — заблокированная кнопка
   (напр. «Сохранить» на черновике категорий, dlgCatDraftSave) выглядела и
   ощущалась активной, cursor:pointer оставался. Тот же приём, что у
   .dlg-composer-tool и .scn-pk-sel по соседству. */
.btn:disabled, .btn-primary:disabled { opacity: .35; cursor: not-allowed; }
.btn-primary:disabled:hover { transform: none; }

.btn-ghost {
  background: rgba(255,255,255,.05); color: var(--text-2);
  border: 1px solid var(--border); width: auto;
}
.btn-ghost:hover { background: rgba(255,255,255,.09); color: var(--text); }

.btn-sm { padding: 8px 14px; width: auto; font-size: 12.5px; }

.btn-danger {
  background: rgba(248,113,113,.12); color: var(--red);
  border: 1px solid rgba(248,113,113,.25); width: auto;
}
.btn-danger:hover { background: rgba(248,113,113,.22); border-color: rgba(248,113,113,.45); }

.error-msg {
  color: var(--red); font-size: 12px; margin-top: 6px;
  padding: 8px 12px; background: rgba(248,113,113,.08);
  border: 1px solid rgba(248,113,113,.15); border-radius: var(--r-ctl);
}

/* ── LAYOUT ───────────────────────────────────────────────────────── */
.layout { display: flex; min-height: 100dvh; }

/* ── SIDEBAR ──────────────────────────────────────────────────────── */
.sidebar {
  width: var(--sidebar-w); flex-shrink: 0;
  background: var(--bg-sidebar);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow: hidden;
}

.sidebar-user {
  padding: 20px 18px 16px;
  display: flex; align-items: center; gap: 11px;
}

.user-avatar-img {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--green);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: #111; flex-shrink: 0;
}

.sidebar-user-name  { font-size: 13.5px; font-weight: 600; color: #c9d1d4; line-height: 1.2; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.sidebar-user-name .role-badge { margin-left: 0; }
.sidebar-user-role  { font-size: 11px; color: var(--text-3); }
.sidebar-balance { font-size: 11.5px; margin-top: 4px; line-height: 1.3; }
.sidebar-balance .balance-label { color: var(--text-3); font-weight: 500; }
.sidebar-balance .balance-amount { color: var(--online); font-weight: 700; }

.sidebar-search {
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
}

.search-box {
  display: flex; align-items: center; gap: 8px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-ctl); padding: 7px 11px;
  cursor: text;
}

.search-icon  { font-size: 12px; color: var(--text-3); }
.search-text  { font-size: 12.5px; color: var(--text-3); flex: 1; }
.search-kbd   { background: var(--bg-hover); color: var(--text-3); font-size: 10px; padding: 2px 5px; border-radius: 4px; border: 1px solid var(--border); }

.nav { padding: 14px 12px; flex: 1; overflow-y: auto; }
.nav-section { margin-bottom: 20px; }

.nav-section-label {
  font-size: 10.5px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: 1.2px;
  padding: 0 8px; margin-bottom: 6px;
}

.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 10px; border-radius: var(--r-ctl);
  font-size: 13px; font-weight: 500;
  color: var(--text-2); cursor: pointer;
  transition: background-color .12s, border-color .12s, color .12s, box-shadow .12s, transform .12s; margin-bottom: 2px;
  user-select: none;
}

.nav-item:hover { color: var(--text); background: var(--bg-hover); }

/* active state — overridden by Task 3 rules below */
.nav-item.active {
  background: rgba(255,255,255,.07);
  color: #fff;
  font-weight: 600;
}

.nav-item.active .nav-badge { background: rgba(0,0,0,.15); color: #111; }

.nav-icon { font-size: 15px; width: 20px; text-align: center; flex-shrink: 0; }

.nav-badge {
  margin-left: auto;
  background: rgba(255,255,255,.08); color: var(--text-2);
  font-size: 11px; font-weight: 600;
  padding: 1px 8px; border-radius: 20px;
}

.nav-live-dot {
  margin-left: auto;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--online); box-shadow: 0 0 5px var(--online);
  animation: livepulse 2s ease-in-out infinite;
}

@keyframes livepulse { 0%,100%{opacity:1} 50%{opacity:.3} }

.sidebar-bottom {
  padding: 14px 16px;
  border-top: 1px solid var(--border);
}

.logout-btn {
  width: 100%; background: none; border: 1px solid var(--border);
  color: var(--text-3); font-size: 13px; font-weight: 500; cursor: pointer;
  padding: 8px 12px; border-radius: var(--r-ctl); transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s, transform .15s;
  text-align: center;
}
.logout-btn:hover { color: var(--text-1); border-color: var(--text-3); }

/* ── MAIN ─────────────────────────────────────────────────────────── */
.main { flex: 1; min-width: 0; overflow-y: auto; display: flex; flex-direction: column; }

.topbar-nav {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--hdr-h);
  padding: 0 28px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  position: sticky; top: 0; z-index: 10;
}

.breadcrumb { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.breadcrumb-parent { color: var(--text-3); }
.breadcrumb-sep { color: var(--text-3); font-size: 11px; }
.breadcrumb-current { color: var(--text); font-weight: 500; }

.topbar-icons { display: flex; align-items: center; gap: 6px; }

.topbar-icon-btn {
  width: 32px; height: 32px; border-radius: var(--r-ctl);
  background: var(--bg-card); border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 14px; cursor: pointer; color: var(--text-2);
  transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s, transform .15s;
}
.topbar-icon-btn:hover { background: var(--bg-hover); color: var(--text); }

.main-content { padding: 24px 28px; flex: 1; }

/* ── PAGE HEADER ──────────────────────────────────────────────────── */
.page-header {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 22px;
}

.page-heading { font-size: 22px; font-weight: 700; letter-spacing: -.4px; }
.page-sub     { font-size: 12.5px; color: var(--text-2); margin-top: 2px; }

/* ── STATS GRID ───────────────────────────────────────────────────── */
.stats-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 12px; margin-bottom: 22px;
}

.stat {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-card); padding: 20px 18px;
}

.stat-label  { font-size: 12px; color: var(--text-2); margin-bottom: 10px; font-weight: 500; }
.stat-num    { font-size: 28px; font-weight: 800; letter-spacing: -1px; line-height: 1; color: var(--text); }
.stat-trend  {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 11.5px; font-weight: 600; margin-top: 8px;
  color: var(--online);
}
.stat-trend.amber { color: var(--amber); }
.stat-trend.muted { color: var(--text-3); }

/* ── SECTION ──────────────────────────────────────────────────────── */
.section-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 12px;
}

.section-title {
  font-size: 16px; font-weight: 700; color: var(--text);
  letter-spacing: -.2px;
}

.filter-tabs { display: flex; gap: 4px; }
.filter-tab {
  padding: 5px 12px; border-radius: 20px;
  font-size: 12px; font-weight: 500;
  color: var(--text-2); cursor: pointer;
  border: 1px solid transparent; transition: background-color .12s, border-color .12s, color .12s, box-shadow .12s, transform .12s;
}
.filter-tab:hover { color: var(--text); }
.filter-tab.active { background: var(--green); color: #111; border-color: transparent; font-weight: 600; }

/* ── ACCOUNT CARDS ────────────────────────────────────────────────── */

.acc-top-bar { height: 2px; }
.acc-top-bar.active      { background: linear-gradient(90deg, var(--online) 0%, transparent 60%); }
.acc-top-bar.sleeping    { background: linear-gradient(90deg, var(--amber) 0%, transparent 60%); }
.acc-top-bar.disconnected{ background: transparent; }

.acc-row {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 18px;
}

/* Status dot with pulse ring */
.status-pulse { position: relative; width: 10px; height: 10px; flex-shrink: 0; }
.s-dot  { width: 10px; height: 10px; border-radius: 50%; }
.s-ring {
  position: absolute; top: -3px; left: -3px;
  width: 16px; height: 16px; border-radius: 50%;
  border: 1.5px solid; animation: s-pulse 2s ease-in-out infinite;
}
@keyframes s-pulse { 0%{opacity:.8;transform:scale(1)} 100%{opacity:0;transform:scale(1.8)} }

.s-dot.active      { background: var(--online); }
.s-ring.active     { border-color: var(--online); }
.s-dot.sleeping    { background: var(--amber); }
.s-ring.sleeping   { border-color: var(--amber); animation: none; opacity: .3; }
.s-dot.disconnected{ background: var(--text-3); }
.s-ring.disconnected{ display: none; }

.acc-info { min-width: 0; flex: 1; }
.acc-phone     { font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; }
.acc-phone-sub { font-size: 11px; color: var(--text-3); margin-top: 1px; white-space: nowrap; }

.char-tag {
  display: inline-flex; align-items: center; gap: 6px;
  background: rgba(42,171,238,.08); border: 1px solid rgba(42,171,238,.15);
  color: var(--green); font-size: 12px; font-weight: 500;
  padding: 4px 11px; border-radius: 20px; flex-shrink: 0;
}
.char-tag-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--green); }

.acc-spacer { flex: 1; }

.chat-list-section {
  border-top: 1px solid var(--border);
  padding: 8px 14px 10px;
}
.chat-list-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  font-size: 12px;
  border-bottom: 1px solid rgba(255,255,255,.03);
}
.chat-list-row:last-child { border-bottom: none; }
.chat-uid {
  color: var(--text-3);
  font-family: monospace;
  font-size: 11px;
  min-width: 72px;
  flex-shrink: 0;
}
.chat-name {
  color: var(--text-2);
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chat-msgs {
  color: var(--text-3);
  font-size: 11px;
  white-space: nowrap;
  flex-shrink: 0;
}
.chat-sleep-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
.chat-sleep-select {
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 4px;
  padding: 2px 6px;
  font-size: 11px;
  font-family: inherit;
  cursor: pointer;
  flex-shrink: 0;
}
.chat-sleep-desc {
  color: var(--text-3);
  font-size: 10px;
  white-space: nowrap;
}

.status-tag {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 12px; border-radius: 20px;
  font-size: 12px; font-weight: 600;
  min-width: 120px; justify-content: center;
}
.status-tag.active      { background: rgba(163,230,53,.1);  color: var(--online); border: 1px solid rgba(163,230,53,.2); }
.status-tag.sleeping    { background: rgba(251,191,36,.1);  color: var(--amber); border: 1px solid rgba(251,191,36,.2); }
.status-tag.disconnected{ background: rgba(75,85,99,.2);    color: var(--text-3); border: 1px solid rgba(75,85,99,.3); }

.acc-actions { display: flex; gap: 5px; }
.icon-btn {
  width: 30px; height: 30px; border-radius: 7px;
  background: var(--bg-hover); border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; cursor: pointer; color: var(--text-3);
  transition: background-color .12s, border-color .12s, color .12s, box-shadow .12s, transform .12s;
}
.icon-btn:hover { border-color: rgba(255,255,255,.12); color: var(--text-2); }

/* ── ADD CARD ─────────────────────────────────────────────────────── */
.add-card {
  border: 1px dashed rgba(42,171,238,.2);
  border-radius: var(--r-card); padding: 16px 20px;
  display: flex; align-items: center; gap: 18px;
  cursor: pointer; transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s, transform .15s;
  background: rgba(42,171,238,.02); margin-top: 6px;
}
.add-card:hover { border-color: rgba(42,171,238,.45); background: rgba(42,171,238,.05); }

.auth-options { display: flex; gap: 8px; }
.auth-opt {
  background: var(--bg-hover); border: 1px solid var(--border);
  border-radius: 9px; padding: 10px 14px;
  text-align: center; min-width: 68px; cursor: pointer; transition: background-color .12s, border-color .12s, color .12s, box-shadow .12s, transform .12s;
}
.auth-opt:hover { border-color: rgba(42,171,238,.3); }
.auth-opt-icon  { font-size: 18px; margin-bottom: 3px; }
.auth-opt-label { font-size: 11px; color: var(--text-2); }

.add-info strong { font-size: 13.5px; font-weight: 600; color: var(--text); display: block; margin-bottom: 2px; }
.add-info p      { font-size: 12px; color: var(--text-3); }

/* ── MODAL ────────────────────────────────────────────────────────── */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,.8);
  backdrop-filter: blur(8px); z-index: 100;
  display: flex; align-items: center; justify-content: center;
}
.modal {
  background: var(--bg-sidebar); border: 1px solid rgba(255,255,255,.09);
  border-radius: var(--r-card); padding: 30px; width: 420px; max-width: 95vw;
  box-shadow: 0 24px 60px rgba(0,0,0,.7);
}
.modal-box {
  background: var(--bg-sidebar); border: 1px solid rgba(255,255,255,.09);
  border-radius: var(--r-card); padding: 24px; width: 100%; max-width: 95vw;
  box-shadow: 0 24px 60px rgba(0,0,0,.7); display: flex; flex-direction: column; gap: 16px;
}
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; }
.modal-title { font-size: 18px; font-weight: 700; margin-bottom: 4px; }
.modal-confirm-icon { font-size: 32px; margin-bottom: 4px; }
.modal-confirm-sub { font-size: 13px; color: var(--text-3); margin-bottom: 8px; }
/* Блок «что будет необратимо» внутри модалки: сколько аккаунтов погаснет вместе
   с персонажем, что история останется на старой строке аккаунта. Мягкий красный
   как у .pill.r на дашборде — но токены --crit/--crit-dim там объявлены под
   .ndash, а модалки живут вне него, поэтому те же значения через фоллбэк var()
   (тот же приём, что у .pm-del:hover с --bad). Читается как предупреждение, а не
   как ошибка: .error-msg рядом остаётся про «сервер сказал нет». */
.modal-confirm-warn {
  font-size: 12.5px; line-height: 1.5; text-align: left;
  color: var(--crit, #e06b6b); background: var(--crit-dim, rgba(224,107,107,.10));
  border-radius: 10px; padding: 11px 12px;
}
/* Базовая ширина подтверждения (была инлайном в index.html). С раскрытым
   warn-блоком текста втрое больше — даём ему воздуха, но ТОЛЬКО когда блок
   реально показан: остальные ~14 подтверждений остаются 360px. */
#modal-confirm .modal-box { max-width: 360px; }
#modal-confirm .modal-box:has(> #modal-confirm-warn:not(.hidden)) { max-width: 420px; }
/* Гейт «наберите имя» в модалке подтверждения (opts.requireText). Скрыт классом
   .hidden по умолчанию — обычные подтверждения его не видят. */
.modal-confirm-gate { display: flex; flex-direction: column; gap: 7px; text-align: left; margin-bottom: 8px; }
.modal-confirm-gate__label { font-size: 12px; color: var(--text-3); }
.modal-confirm-gate .form-input { font-size: 13.5px; }
.modal-sub   { font-size: 12.5px; color: var(--text-2); margin-bottom: 22px; }

.qr-container { text-align: center; padding: 16px; background: #fff; border-radius: var(--r-card); display: inline-block; }
.qr-container canvas { display: block; }
.qr-hint { font-size: 12px; color: var(--text-2); margin-top: 10px; text-align: center; }

.select-input {
  width: 100%; background: var(--bg-input);
  border: 1px solid var(--border); border-radius: var(--r-ctl);
  padding: 10px 13px; color: var(--text); font-size: 13.5px;
  font-family: inherit; outline: none; appearance: none; cursor: pointer;
}
.select-input:focus { border-color: rgba(42,171,238,.4); }

/* ── CHARACTERS ───────────────────────────────────────────────────── */
.chars-grid { display: grid; grid-template-columns: repeat(auto-fill,minmax(260px,1fr)); gap: 10px; }

.char-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: 18px; cursor: pointer; transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s, transform .15s;
}
.char-card:hover { border-color: var(--line); transform: translateY(-2px); }
.char-card-name    { font-size: 15px; font-weight: 600; margin-bottom: 4px; }
.char-card-preview { font-size: 12px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.char-editor { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-card); padding: 24px; }
.char-editor-title { font-size: 18px; font-weight: 700; }
.field-group { margin-bottom: 14px; }
.field-label { display: block; font-size: 11px; font-weight: 600; color: var(--text-2); text-transform: uppercase; letter-spacing: .6px; margin-bottom: 6px; }
/* Подсказка под полем — канон платформы (12px, приглушённый). Раньше класс
   не имел стиля → крупный белый текст «не по канону». */
.field-hint { font-size: 12px; color: var(--t3); margin-top: 6px; line-height: 1.45; }

/* Внешние реквизиты (донаты) — репитер строк ярлык+значение */
.pm-list { display: flex; flex-direction: column; gap: 8px; }
.pm-row { display: flex; gap: 8px; align-items: center; }
.pm-row .pm-label { flex: 0 0 38%; min-width: 0; }
.pm-row .pm-value { flex: 1; min-width: 0; }
.pm-del {
  flex: none; width: 38px; align-self: stretch;
  background: transparent; border: 1px solid var(--border); border-radius: 10px;
  color: var(--text-3); cursor: pointer; font-size: 14px; line-height: 1;
  transition: color .12s, border-color .12s;
}
.pm-del:hover { color: var(--bad, #E0533B); border-color: var(--bad, #E0533B); }
.pm-add {
  margin-top: 8px; background: var(--ctl); border: 1px solid var(--border);
  color: var(--text-1); border-radius: 10px; padding: 8px 14px;
  font-size: 13px; font-weight: 500; cursor: pointer; transition: background .12s;
}
.pm-add:hover { background: var(--ctl-h); }

.slider-row { display: flex; align-items: center; gap: 12px; }
.prob-slider {
  flex: 1; -webkit-appearance: none; appearance: none;
  height: 4px; border-radius: 2px; outline: none; cursor: pointer;
  background: linear-gradient(to right, var(--green) 0%, var(--green) calc(var(--pct, 33%) ), rgba(255,255,255,.12) calc(var(--pct, 33%)));
}
.prob-slider::-webkit-slider-thumb {
  -webkit-appearance: none; width: 16px; height: 16px; border-radius: 50%;
  background: var(--green); box-shadow: 0 0 6px var(--green-glow); cursor: pointer;
}
.prob-value { font-size: 13px; font-weight: 600; color: var(--green); min-width: 34px; text-align: right; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* Динамическая цена — ползунки */
.price-knobs { margin-top: 16px; display: flex; flex-direction: column; gap: 20px; }
.price-ctrl-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
.price-ctrl-label { font-size: 13.5px; color: var(--t2); }
.price-ctrl-val {
  font-size: 13.5px; font-weight: 700; letter-spacing: .2px;
  font-variant-numeric: tabular-nums; color: var(--accent-1);
}
.price-ctrl-val.is-off { color: var(--t3); font-weight: 500; }
.price-slider {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 6px; border-radius: 999px; cursor: pointer; outline: none;
  background:
    linear-gradient(90deg, var(--accent-1), var(--accent-2)) no-repeat,
    rgba(255,255,255,.09);
  background-size: var(--pct, 0%) 100%, 100% 100%;
}
.price-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; border-radius: 50%;
  background: #fff; border: 2px solid var(--accent-2);
  box-shadow: 0 2px 7px rgba(0,0,0,.45);
  transition: transform .12s ease, box-shadow .12s ease;
}
.price-slider:hover::-webkit-slider-thumb { transform: scale(1.15); box-shadow: 0 0 0 6px rgba(124,77,255,.14); }
.price-slider:active::-webkit-slider-thumb { transform: scale(1.05); }
.price-slider::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--accent-2);
  background: #fff; box-shadow: 0 2px 7px rgba(0,0,0,.45); cursor: pointer;
}
.price-slider::-moz-range-progress { height: 6px; border-radius: 999px; background: linear-gradient(90deg, var(--accent-1), var(--accent-2)); }

/* Концепт: слайдеры цены/энергии — голубой акцент, не бренд-фиолет (тёмная тема) */
[data-theme="dark"] .price-slider {
  background:
    linear-gradient(90deg, var(--accent-dim), var(--accent)) no-repeat,
    rgba(255,255,255,.09);
  background-size: var(--pct, 0%) 100%, 100% 100%;
}
[data-theme="dark"] .price-slider::-webkit-slider-thumb { border-color: var(--accent); }
[data-theme="dark"] .price-slider::-moz-range-thumb { border-color: var(--accent); }
[data-theme="dark"] .price-slider::-moz-range-progress { background: linear-gradient(90deg, var(--accent-dim), var(--accent)); }
[data-theme="dark"] .price-slider:hover::-webkit-slider-thumb { box-shadow: 0 0 0 6px var(--accent-glow); }
[data-theme="dark"] .price-ctrl-val { color: var(--accent); }

.save-bar { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--border); }

/* ── RIGHT PANEL ──────────────────────────────────────────────────── */
.right-panel {
  width: var(--right-w); flex-shrink: 0;
  background: var(--bg-sidebar); border-left: 1px solid var(--border);
  padding: 0; display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}

.panel-section { padding: 20px 18px; border-bottom: 1px solid var(--border); }
.panel-section:last-child { border-bottom: none; }

.panel-heading { font-size: 14px; font-weight: 700; color: var(--text); margin-bottom: 14px; }

.activity-item {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.activity-item:last-child { border-bottom: none; padding-bottom: 0; }

.activity-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  flex-shrink: 0; display: flex; align-items: center; justify-content: center;
  font-size: 14px; background: var(--bg-hover); border: 1px solid var(--border);
}

.activity-text  { font-size: 12.5px; color: var(--text-2); flex: 1; line-height: 1.4; }
.activity-text strong { color: var(--text); }
.activity-time  { font-size: 10.5px; color: var(--text-3); margin-top: 2px; }

.stat-mini {
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 0; border-bottom: 1px solid var(--border);
}
.stat-mini:last-child { border-bottom: none; }
.stat-mini-label { font-size: 12.5px; color: var(--text-2); }
.stat-mini-val   { font-size: 14px; font-weight: 700; color: var(--text); }
.stat-mini-val.green { color: var(--online); }

/* WS status badge */
.ws-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 20px; font-size: 11.5px; font-weight: 500;
  background: rgba(75,85,99,.2); color: var(--text-3); border: 1px solid var(--border);
  transition: background-color .3s, border-color .3s, color .3s, box-shadow .3s, transform .3s;
}
.ws-badge.live { background: rgba(163,230,53,.1); color: var(--online); border-color: rgba(163,230,53,.2); }
.ws-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.ws-badge.live .ws-dot { box-shadow: 0 0 5px var(--online); }

/* ── TG AVATAR ────────────────────────────────────────────────────── */
.tg-avatar {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--bg-hover); border: 1.5px solid var(--border);
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; flex-shrink: 0;
}

/* ── ROLE BADGE ───────────────────────────────────────────────────── */
.role-badge {
  display: inline-flex;
  background: rgba(75,85,99,.2);
  border: 1px solid rgba(75,85,99,.3);
  color: var(--text-3);
  font-size: 9.5px; font-weight: 600;
  padding: 1px 6px; border-radius: 20px;
  text-transform: uppercase; letter-spacing: .4px;
  margin-left: 5px; vertical-align: middle;
}
.role-badge.admin {
  background: rgba(42,171,238,.1);
  border-color: rgba(42,171,238,.2);
  color: var(--green);
}

/* ── INLINE CHAR SELECT ───────────────────────────────────────────── */
.char-select-inline {
  background-color: rgba(42,171,238,.08);
  border: 1px solid rgba(42,171,238,.15);
  color: var(--green);
  font-size: 12px; font-weight: 500;
  padding: 5px 28px 5px 11px;
  border-radius: 20px;
  font-family: inherit;
  outline: none;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  max-width: 180px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%232AABEE' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
.char-select-inline { transition: background-color .15s, border-color .15s; }
.char-select-inline:hover { background-color: rgba(42,171,238,.15); border-color: rgba(42,171,238,.35); }
.char-select-inline:focus { border-color: rgba(42,171,238,.5); background-color: rgba(42,171,238,.15); }
.char-select-inline option { background: var(--bg-card); color: var(--text); }

/* ── UTILITIES ────────────────────────────────────────────────────── */
.hidden  { display: none !important; }
/* No-flash auth boot: hide the wrong page before app.js runs.
   dataset.auth is set pre-paint in index.html and kept in sync by
   showAuth()/showApp()/demo in app.js. */
html[data-auth="in"]  #page-auth { display: none !important; }
html[data-auth="out"] #page-app  { display: none !important; }
.mt-2    { margin-top: 8px; }
.mt-4    { margin-top: 16px; }
.flex    { display: flex; }
.gap-2   { gap: 8px; }
.items-center     { align-items: center; }
.justify-between  { justify-content: space-between; }
.text-center { text-align: center; }
.text-muted  { color: var(--text-2); font-size: 13px; }
/* приглушённые подписи-описания (использовались в app.js без CSS → были чёрными) */
.muted { color: var(--t2); }
.small { font-size: 12px; }

/* ── EDITCHAR: вертикальный сгруппированный сайдбар вкладок ───────── */
.editchar-layout {
  display: grid;
  grid-template-columns: 232px 1fr;
  gap: 18px;
  align-items: start;
}
.editchar-side {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: 8px;
  position: sticky; top: 16px; align-self: start;
  max-height: calc(100vh - 32px); overflow-y: auto;
}
.editchar-sgh {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-3); font-weight: 700; padding: 11px 10px 5px;
}
.editchar-sgh:first-child { padding-top: 4px; }
.editchar-tab {
  padding: 8px 10px; border-radius: var(--r-ctl);
  font-size: 13px; font-weight: 500;
  color: var(--text-2); cursor: pointer;
  user-select: none;
  border-left: 2px solid transparent;
  display: flex; align-items: center; gap: 9px;
}
.editchar-tab:hover { color: var(--text); background: var(--bg-hover); }
.editchar-tab.active {
  background: var(--bg-hover); color: var(--text); font-weight: 600;
  border-left-color: var(--g);
}
.editchar-tab .et-ic {
  width: 16px; height: 16px; flex: none; opacity: .85;
  fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.editchar-tab.is-star .et-ic { opacity: 1; }
.editchar-pane.hidden { display: none; }
/* мягкий вход панели при переключении вкладки (вход → ease-out, <300ms, opacity/transform) */
.editchar-pane:not(.hidden) { animation: editcharPaneIn 140ms var(--ease-out); }
@keyframes editcharPaneIn {
  from { opacity: 0; transform: translateY(3px); }
  to   { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .editchar-pane:not(.hidden) { animation: none; }
}
/* медиа-пресеты 2×2 */
.media-preset-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 18px; align-items: start; margin-bottom: 6px; }
.media-hint { font-size: 12px; margin-top: 4px; }

/* адаптив: на узких экранах двухколоночный layout редактора → 1 колонка.
   Навигация-рейл превращается в чип-сетку — правила ниже, в блоке
   «АДАПТИВ ПЛОТНЫХ ВЬЮХ» (после OLED-рескина, чтобы перебить его специфичность). */
@media (max-width: 720px) {
  .editchar-layout { grid-template-columns: 1fr; }
  .media-preset-grid { grid-template-columns: 1fr; }
}

/* ── ADMIN TABS ───────────────────────────────────────────────────── */
.admin-tabs {
  display: flex; gap: 4px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: 4px;
  margin-bottom: 20px; overflow-x: auto;
}

.admin-tab {
  padding: 8px 16px; border-radius: var(--r-ctl);
  font-size: 13px; font-weight: 500;
  color: var(--text-2); cursor: pointer;
  transition: background-color .12s, border-color .12s, color .12s, box-shadow .12s, transform .12s; user-select: none; white-space: nowrap;
}
.admin-tab:hover { color: var(--text); background: var(--bg-hover); }
.admin-tab.active { background: var(--bg-hover); color: var(--text); font-weight: 600; }

/* ── DATA TABLE ───────────────────────────────────────────────────── */
.data-table-wrap {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--r-card); overflow: hidden;
}

.table-meta {
  padding: 12px 18px 10px;
  font-size: 11px; font-weight: 600; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .8px;
  border-bottom: 1px solid var(--border);
}

.data-table { width: 100%; border-collapse: collapse; font-size: 13px; }

.data-table th {
  text-align: left; padding: 11px 18px;
  font-size: 10.5px; font-weight: 600;
  color: var(--text-3); text-transform: uppercase; letter-spacing: .7px;
  border-bottom: 1px solid var(--border);
  background: rgba(255,255,255,.02);
  white-space: nowrap;
}

.data-table td {
  padding: 12px 18px; border-bottom: 1px solid var(--border);
  color: var(--text-2); vertical-align: middle;
}

.data-table tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover td { background: rgba(255,255,255,.025); }

/* ── TABLE CELLS ──────────────────────────────────────────────────── */
.table-user-cell {
  display: flex; align-items: center; gap: 10px;
}

.table-avatar {
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--green);
  display: flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: #111; flex-shrink: 0;
}

.table-actions { display: flex; gap: 6px; align-items: center; }

.td-primary { font-weight: 600; color: var(--text) !important; }
.td-mono    { font-family: monospace; letter-spacing: .4px; font-size: 12px; }
.td-muted   { font-size: 12px; color: var(--text-3) !important; }

/* ── ADMIN STAT CARDS ─────────────────────────────────────────────── */
.admin-stats-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 12px; margin-bottom: 24px;
}

.admin-stat-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: 20px 18px; text-align: center;
}
.admin-stat-icon  { font-size: 24px; margin-bottom: 10px; }
.admin-stat-val   { font-size: 32px; font-weight: 800; letter-spacing: -1.5px; color: var(--text); line-height: 1; }
.admin-stat-label { font-size: 12px; font-weight: 600; color: var(--text-2); margin-top: 6px; }
.admin-stat-sub   { font-size: 11px; color: var(--text-3); margin-top: 3px; }

.admin-section-title {
  font-size: 14px; font-weight: 700; color: var(--text);
  margin-bottom: 12px; margin-top: 4px;
}

/* ── RESPONSIVE ───────────────────────────────────────────────────── */
@media (max-width: 900px) {
  .right-panel { display: none; }
}

@media (max-width: 800px) {
  .main-content { padding: 16px 18px; }

  /* Stats: 2x2 grid */
  .stats-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; }

  .status-tag { min-width: 90px; font-size: 11px; padding: 4px 10px; }
}

@media (max-width: 640px) {
  /* Bottom tab bar layout */
  #page-app { flex-direction: column; height: 100dvh; overflow: hidden; }

  .sidebar {
    width: 100%; height: auto; flex-shrink: 0;
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 100;
    border-right: none; border-top: 1px solid var(--border); border-bottom: none;
    flex-direction: row; align-items: center;
    padding: 0; height: 56px; overflow: hidden;
    background: var(--bg-sidebar);
  }

  /* Hide user block and logout in sidebar — shown in top-nav instead */
  .sidebar-user { display: none; }
  .sidebar-bottom { display: none; }

  /* Nav becomes bottom tabs */
  .nav { flex: 1; height: 100%; padding: 0; }
  .nav-section { display: flex; flex-direction: row; height: 100%; padding: 0; gap: 0; }
  .nav-section-label { display: none; }
  .nav-item {
    flex: 1; display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 2px; padding: 6px 4px;
    border-radius: 0; font-size: 10px; color: var(--text-3);
    border-top: 2px solid transparent;
  }
  .nav-item.active { background: none; border-top-color: var(--green); color: var(--text); }
  .nav-icon { font-size: 18px; }
  .nav-badge { display: none; }
  .nav-live-dot { display: none !important; }

  /* Main scrolls above the tab bar */
  .main { flex: 1; overflow-y: auto; padding-bottom: 56px; }
  .top-nav { padding: 10px 14px; }
  .top-nav .breadcrumb { font-size: 13px; }
  .main-content { padding: 14px; }

  /* Top nav: show username + logout */
  .top-nav { display: flex; align-items: center; justify-content: space-between; }
  .top-nav-mobile-user {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px; font-weight: 600; color: var(--text);
  }
  .top-nav-mobile-logout {
    background: none; border: 1px solid var(--border);
    color: var(--text-3); font-size: 12px; padding: 5px 10px;
    border-radius: var(--r-ctl); cursor: pointer;
  }

  /* .topbar-logout-mobile («Выйти») — рудимент старого сайдбара. В новом хедере
     логаут живёт в меню аватара (.hdr-user). Форс-show распирал .hdr-right за
     вьюпорт → горизонтальный скролл всей страницы. Держим скрытой. */
  .topbar-logout-mobile { display: none !important; }

  /* Stats grid 2 columns */
  .stats-grid { grid-template-columns: repeat(2, 1fr); gap: 8px; }

  /* Account card mobile */
  .acc-row { gap: 8px; padding: 10px 12px; }
  .acc-row .char-select-inline { max-width: 140px; }
}


.field-subgroup {
  font-size: 11px; font-weight: 600;
  color: var(--text-3);
  text-transform: none; letter-spacing: 0;
  margin: 14px 0 8px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.field-subgroup:first-child { margin-top: 4px; }


/* ── TASK 9: Accounts stat cards + action row ─────────────────────── */
.acc-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px; }
.acc-stat-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: 14px 16px;
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
}
.acc-stat-card--all          { border-left: 3px solid var(--text-2); }
.acc-stat-card--active       { border-left: 3px solid var(--green); }
.acc-stat-card--sleeping     { border-left: 3px solid var(--amber); }
.acc-stat-card--disconnected { border-left: 3px solid var(--text-3); }
.acc-stat-card--selected     { background: var(--bg-hover); }
.acc-stat-card .num  { font-size: 22px; font-weight: 700; line-height: 1; }
.acc-stat-card .lbl  { font-size: 11px; color: var(--text-2); text-transform: uppercase; letter-spacing: .5px; margin-top: 3px; }
.acc-actionrow { display: flex; gap: 10px; margin-bottom: 14px; align-items: center; }
.acc-search {
  flex: 1;
  background: var(--bg-input);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 8px 12px;
  border-radius: var(--r-ctl);
  font-size: 13px;
  font-family: inherit;
  outline: none;
}
.acc-search:focus { border-color: var(--green); }

/* [dead CSS удалён: .acc-table и .acc-table-wrap — экран Аккаунты рендерит .table-wrap кита] */
.acc-avatar-sm{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;background:var(--bg-hover);overflow:hidden;flex-shrink:0}
.acc-id-mono{font-size:11px;color:var(--text-3);font-family:monospace}

/* Task 11: clickable status badge */
.status-pill{padding:3px 9px;border-radius:20px;font-size:11px;font-weight:600;cursor:pointer;display:inline-block}
.status-pill--active{background:rgba(74,222,128,.14);color:#4ade80}
.status-pill--sleeping{background:rgba(251,191,36,.14);color:#fbbf24}
.status-pill--disconnected{background:rgba(107,114,128,.18);color:#9ca3af}
.status-pill--paused{opacity:.5}
.acc-proxy-pill{padding:3px 9px;border-radius:20px;font-size:11px;font-weight:600;cursor:pointer;display:inline-block;background:rgba(96,165,250,.14);color:#60a5fa}
.acc-proxy-pill--off{background:rgba(255,255,255,.04);color:#6b7280}


/* Task 13: bulk action bar + row selection */
.bulk-bar{position:fixed;bottom:28px;left:50%;transform:translateX(-50%);z-index:9998;display:flex;flex-wrap:nowrap;gap:4px;align-items:center;max-width:calc(100vw - 32px);overflow-x:auto;scrollbar-width:none;-ms-overflow-style:none;background:var(--bg-card);border:1px solid var(--border);border-radius:16px;padding:7px 8px 7px 14px;box-shadow:0 16px 48px rgba(0,0,0,.5),0 2px 8px rgba(0,0,0,.3);animation:bulkbar-in .24s var(--ease-out)}
.bulk-bar::-webkit-scrollbar{display:none}
@keyframes bulkbar-in{from{opacity:0;transform:translateX(-50%) translateY(10px) scale(.98)}to{opacity:1;transform:translateX(-50%) translateY(0) scale(1)}}
.bulk-bar__count{display:inline-flex;align-items:baseline;gap:5px;flex:none;white-space:nowrap;font-size:12px;font-weight:500;color:var(--text-2);padding:0 6px 0 0}
.bulk-bar__count-n{font-size:15px;font-weight:700;color:var(--g)}
.bulk-bar__sep{width:1px;height:22px;flex:none;background:var(--border);margin:0 2px}
.bulk-bar__btn{display:inline-flex;align-items:center;gap:6px;flex:none;white-space:nowrap;padding:8px 12px;border-radius:10px;font-size:12.5px;font-weight:600;cursor:pointer;border:1px solid transparent;background:transparent;color:var(--text)}
.bulk-bar__btn .bic{color:var(--text-2)}
.bulk-bar__btn:hover{background:var(--bg-hover)}
.bulk-bar__btn:hover .bic{color:var(--text)}
.bulk-bar__btn--ghost{color:var(--text-2);font-weight:500}
.bulk-bar__btn--danger{color:var(--red)}
.bulk-bar__btn--danger .bic{color:var(--red)}
.bulk-bar__btn--danger:hover{background:color-mix(in srgb,var(--red) 15%,transparent)}

/* Task 15: Dialogs two-pane skeleton */


/* Result toast (criterion 6) */
/* z-index 10001 — тост обязан быть НАД ВСЕМ, включая лайтбокс (.dlg-lightbox, 10000):
   иначе «Не удалось загрузить превью» из openLibraryLightbox показался бы ПОД чёрной
   подложкой. Был 9999, поднят вместе с лайтбоксом (целых чисел между 9998 и 9999 нет). */
.app-toast{position:fixed;bottom:28px;left:50%;display:flex;align-items:center;gap:9px;transform:translateX(-50%);background:var(--bg-card);color:var(--text);border:1px solid var(--border);border-left:3px solid var(--border);border-radius:var(--r-card);padding:10px 18px;font-size:13px;font-weight:500;z-index:10001;box-shadow:0 4px 24px rgba(0,0,0,.5);pointer-events:auto;cursor:pointer;white-space:nowrap;opacity:1;transition:opacity .18s var(--ease-out),transform .18s var(--ease-out)}
.app-toast__icon{font-size:14px;line-height:1;font-weight:700}
.app-toast[data-variant="success"]{border-left:3px solid var(--ok)}
.app-toast[data-variant="success"] .app-toast__icon{color:var(--ok)}
.app-toast[data-variant="error"]{border-left:3px solid var(--bad)}
.app-toast[data-variant="error"] .app-toast__icon{color:var(--bad)}
.app-toast[data-hide="1"]{opacity:0;transform:translate(-50%,8px)}
/* ── Updates (changelog) ─────────────────────────────────────────── */
.updates-empty { color: var(--text-3); padding: 24px 4px; font-size: 14px; }
/* [dead CSS удалён: .update-* (changelog-карта) — рендер renderUpdateCard использует .panel/.nbtn кита; .updates-empty живой оставлен] */

/* ── Dialogs page (Task 9) ── */
/* Dialogs page — uses platform theme tokens */
.dlg-wrap{display:flex;height:calc(100vh - 160px);background:var(--bg-card);border:1px solid var(--border);border-radius:var(--r-card);overflow:hidden}
.dlg-rail{width:64px;background:var(--bg-sidebar);border-right:1px solid var(--border);display:flex;flex-direction:column;align-items:center;gap:12px;padding:14px 0;overflow:auto}
.dlg-rail .av{width:42px;height:42px;border-radius:10px;background:var(--bg-hover);border:1px solid var(--border);display:flex;align-items:center;justify-content:center;font-size:11px;color:var(--text-2);cursor:pointer;overflow:hidden}
.dlg-rail .av.on{border-color:var(--online);color:var(--online);box-shadow:0 0 0 1px var(--online)}
.dlg-rail .av img{width:100%;height:100%;object-fit:cover}
.dlg-list{width:280px;display:flex;flex-direction:column;border-right:1px solid var(--border)}
.dlg-list-hd{padding:12px;border-bottom:1px solid var(--border)}
.dlg-search{width:100%;box-sizing:border-box;background:var(--bg-input);border:1px solid var(--border);border-radius:var(--r-ctl);padding:8px 10px;color:var(--text);font-size:12px}
/* Одна строка с прокруткой вместо переноса: чипов стало девять (4 фильтра +
   3 авто-папки + свои папки), а .dlg-list шириной 280px — перенос давал пять
   строк шапки и съедал список. */
.dlg-seg{display:flex;gap:6px;margin-top:10px;flex-wrap:nowrap;overflow-x:auto;
  scrollbar-width:none;-webkit-overflow-scrolling:touch}
.dlg-seg::-webkit-scrollbar{display:none}
.dlg-seg > span{flex:0 0 auto;white-space:nowrap}
.dlg-seg span{padding:4px 9px;border-radius:var(--r-ctl);background:var(--bg-input);color:var(--text-2);font-size:11px;cursor:pointer}
.dlg-seg span.act{background:var(--green);color:#111;font-weight:600}
.dlg-chats{flex:1;overflow:auto}
.dlg-ch{display:flex;gap:9px;padding:10px 12px;border-bottom:1px solid var(--border);align-items:center;cursor:pointer}
.dlg-ch:hover{background:var(--bg-hover)}
.dlg-ch.sel{background:var(--green-dim);border-left:2px solid var(--green)}
.dlg-ch .cav{width:34px;height:34px;border-radius:50%;background:var(--bg-hover);flex:none;overflow:hidden;position:relative;display:flex;align-items:center;justify-content:center;color:var(--text-2);font-weight:600;font-size:14px}
.dlg-ch .cav img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.dlg-ch .cmid{flex:1;min-width:0}
.dlg-ch .cn{display:flex;align-items:center;font-weight:600;color:var(--text);font-size:12px}
.dlg-ch .cn .cn-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
/* Флаг+код страны телефона рядом с именем в списке диалогов (Task 7 гео-блеклиста).
   flex:none — не сжимается, длинное имя усекается через .cn-name раньше бейджа. */
.dlg-ch .cn .dlg-geo{flex:none;margin-left:6px;font-size:10px;font-weight:600;color:var(--text-2);white-space:nowrap}
/* Бейдж контакта — ОДИН круглый тировый значок-ОВЕРЛЕЙ в углу аватара (обёртка
   .cav-wrap position:relative не обрезает). Одно число = покупки медиа + донаты
   вместе: синий 1–4, золотой (.whale) ≥5 = «Кит». Кольцо var(--bg) отделяет от
   аватара. Класс НЕ .dlg-paid (тот = крупная карточка медиа в теле сообщения). */
.dlg-stats-badge{position:absolute;right:-3px;bottom:-3px;z-index:1;
  display:inline-flex;align-items:center;justify-content:center;
  min-width:16px;height:16px;padding:0 4px;border-radius:999px;
  font-size:9.5px;font-weight:800;line-height:1;letter-spacing:.01em;pointer-events:none;
  color:#fff;background:linear-gradient(180deg,#4aa3ff,#1f7fe0);
  box-shadow:0 0 0 2px var(--bg),0 1px 2px rgba(0,0,0,.25)}
.dlg-stats-badge.whale{color:#5a4200;background:linear-gradient(180deg,#ffd24a,#f5b301);
  box-shadow:0 0 0 2px var(--bg),0 1px 2px rgba(0,0,0,.25)}
.dlg-ch .cp{color:var(--text-2);font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:2px}
.dlg-ch .cright{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex:none}
.dlg-badge{min-width:17px;height:17px;line-height:17px;background:var(--green);color:#111;border-radius:9px;font-size:10px;font-weight:700;text-align:center;padding:0 4px}
/* Число непрочитанных выросло → бейдж коротко «клюёт»: молча подменённая цифра
   проходит мимо взгляда, а оператор следит именно за ней. */
.dlg-bump{animation:dlg-bump var(--dur-3) var(--ease-spring)}
@keyframes dlg-bump{from{transform:scale(.55)}60%{transform:scale(1.12)}to{transform:none}}
@media (prefers-reduced-motion:reduce){.dlg-bump{animation:none}}
/* iOS-style switch (трек + бегунок); .d = трек, ::after = бегунок, текст = подпись Вкл/Выкл */
.nc-pill{display:inline-flex;align-items:center;gap:8px;padding:0;border:0;background:none;font-size:12px;font-weight:600;cursor:pointer;white-space:nowrap;color:var(--t2)}
.nc-pill .d{position:relative;flex:none;width:34px;height:20px;border-radius:999px;background:#c2c8cf;transition:background .18s var(--ease-out)}
.nc-pill .d::after{content:'';position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .18s var(--ease-out)}
.nc-pill.on .d{background:#22c55e}
.nc-pill.on .d::after{transform:translateX(14px)}
.nc-pill.off .d{background:#c2c8cf}
.nc-pill.on{color:var(--t1)}
.nc-pill.off{color:var(--t3)}
.dlg-conv{flex:1;display:flex;flex-direction:column;background:var(--bg);min-width:0}
.dlg-empty{margin:auto;color:var(--text-3)}
.dlg-chd{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;border-bottom:1px solid var(--border)}
.dlg-chd b{color:var(--text)}.dlg-chd small{color:var(--text-2)}
.dlg-chd .lbl{font-size:9px;letter-spacing:.06em;color:var(--text-3);text-transform:uppercase;margin-bottom:5px;text-align:right}
.dlg-body{flex:1;padding:16px;display:flex;flex-direction:column;gap:8px;overflow:auto}
/* Разделитель дня — центрированная плашка между сообщениями («Сегодня»/«5 июня») */
.dlg-daysep{display:flex;align-items:center;justify-content:center;margin:14px 0 10px}
.dlg-daysep span{font-size:11.5px;font-weight:600;color:var(--text-2);background:var(--bg-card);border:1px solid var(--border);padding:4px 12px;border-radius:999px}
#page-dialogs .dlg-daysep span{color:var(--t2);background:var(--card);border-color:var(--line);box-shadow:0 1px 2px rgba(0,0,0,.06)}
/* Подарок Telegram — служебная строка по центру, зеркалит разделитель дня выше:
   это тоже событие ленты, а не чьё-то сообщение. */
.dlg-giftsep{display:flex;align-items:center;justify-content:center;margin:2px 0}
.dlg-giftsep span{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:600;
  color:var(--text-2);background:var(--bg-card);border:1px solid var(--border);padding:5px 13px;border-radius:999px}
.dlg-giftsep b{font-weight:600;color:var(--text)}
#page-dialogs .dlg-giftsep span{color:var(--t2);background:var(--card);border-color:var(--line);box-shadow:0 1px 2px rgba(0,0,0,.06)}
#page-dialogs .dlg-giftsep b{color:var(--t1)}
.dlg-dot{display:inline-block;width:9px;height:9px;border-radius:50%;flex-shrink:0;vertical-align:middle}
.dlg-dot--on{background:var(--online)}
.dlg-dot--paused{background:var(--amber)}
.dlg-dot--off{background:var(--t3);opacity:.5}
.dlg-msg{max-width:460px;padding:8px 12px;border-radius:12px;font-size:12px;line-height:1.35;word-break:break-word}
.dlg-msg.in{align-self:flex-start;background:var(--bg-card);color:var(--text);border-bottom-left-radius:4px}
.dlg-msg.out{align-self:flex-end;background:var(--green-dim);color:var(--text);border:1px solid var(--green-glow);border-bottom-right-radius:4px}
.dlg-msg .mt{font-size:9px;color:var(--text-3);margin-top:3px;text-align:right}
/* Кластеризация: подряд идущие сообщения одной стороны жмутся ближе и сшиваются углами */
#page-dialogs .dlg-msg.grp-mid,
#page-dialogs .dlg-msg.grp-last { margin-top:-5px; }
#page-dialogs .dlg-msg.out.grp-first { border-bottom-right-radius:5px; }
#page-dialogs .dlg-msg.out.grp-mid   { border-top-right-radius:5px; border-bottom-right-radius:5px; }
#page-dialogs .dlg-msg.out.grp-last  { border-top-right-radius:5px; }
#page-dialogs .dlg-msg.in.grp-first  { border-bottom-left-radius:5px; }
#page-dialogs .dlg-msg.in.grp-mid    { border-top-left-radius:5px; border-bottom-left-radius:5px; }
#page-dialogs .dlg-msg.in.grp-last   { border-top-left-radius:5px; }
.dlg-msg .dlg-tick{ color: var(--text-3); margin-left:3px; line-height:0; }
.dlg-msg .dlg-tick--read{ color:#53bdeb; }
.dlg-tick-svg{ display:inline-block; vertical-align:-1px; }
/* height:auto ОБЯЗАТЕЛЕН: у <img> теперь есть атрибуты width/height (натуральные
   размеры с сервера). Без height:auto браузер взял бы их буквально, а max-width
   сжал бы только ширину — фото раздавило бы по вертикали. С height:auto пара
   width/height работает как пропорция и резервирует место до загрузки файла. */
.dlg-msg img,.dlg-msg video{max-width:100%;max-height:360px;border-radius:8px;display:block;height:auto;
  transition:opacity var(--dur-3) ease, filter var(--dur-3) ease}
/* Пока файл летит — на зарезервированном месте ВИДИМЫЙ плейсхолдер с бегущим
   бликом, а не тёмное пятно. Первая версия ставила просто --skel-base (#131316):
   на тёмной теме он сливался с фоном тела, и оператор видел не «тут грузится
   фото», а чёрную дыру в треде (особенно при подгрузке истории вверх, где
   картинок сразу несколько). Класс снимается по onload/onerror → фото проявляется. */
.dlg-msg img.dlg-media-in{
  opacity:.5;
  background-color:var(--raise-2);
  background-image:linear-gradient(100deg,
    rgba(255,255,255,0) 20%,
    rgba(255,255,255,.07) 50%,
    rgba(255,255,255,0) 80%);
  background-size:220% 100%;
  background-repeat:no-repeat;
  animation:dlg-media-sheen 1.4s ease-in-out infinite;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.05);
}
@keyframes dlg-media-sheen{from{background-position:-60% 0}to{background-position:160% 0}}
@media (prefers-reduced-motion:reduce){.dlg-msg img.dlg-media-in{animation:none}}
/* Платное медиа (sender-view placeholder): глянцевая карточка «запертого» контента,
   а не мутный чёрный чип. Живёт в .out-бабле (синий градиент, белый текст). */
.dlg-paid{display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:12px;
  background:rgba(255,255,255,.15);border:1px solid rgba(255,255,255,.22)}
.dlg-paid + .dlg-msg-text{margin-top:6px}
.dlg-paid-ic{flex:none;width:34px;height:34px;border-radius:9px;display:grid;place-items:center;
  font-size:17px;background:rgba(255,255,255,.18)}
.dlg-paid-main{display:flex;flex-direction:column;gap:4px;min-width:0}
.dlg-paid-title{font-size:12.5px;font-weight:600;line-height:1;letter-spacing:-.01em}
.dlg-paid-price{align-self:flex-start;display:inline-flex;align-items:center;gap:3px;
  font-size:11px;font-weight:600;line-height:1;padding:3px 7px;border-radius:999px;
  background:rgba(255,255,255,.22)}
.dlg-paid-status{margin-left:auto;flex:none;display:inline-flex;align-items:center;gap:3px;
  font-size:10.5px;font-weight:700;line-height:1;padding:4px 8px;border-radius:999px;
  background:var(--online);color:#1a2e05}
.dlg-paid.is-purchased .dlg-paid-ic{background:rgba(163,230,53,.25)}
/* Платный НАБОР: имя пака мелкой строкой под заголовком «Набор · N». */
.dlg-paid-pack{font-size:11px;font-weight:600;line-height:1.1;letter-spacing:-.01em;opacity:.82;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:200px}
/* Бейдж «📦 Набор · N» над бесплатным альбомом. Тёмный чип — читается и на
   прозрачном медиа-бабле (фон страницы), и поверх синего .out-градиента. */
.dlg-album-badge{display:inline-flex;align-items:center;gap:4px;align-self:flex-start;
  font-size:10.5px;font-weight:700;line-height:1;padding:4px 8px;margin-bottom:5px;
  border-radius:999px;background:rgba(0,0,0,.5);color:#fff;backdrop-filter:blur(2px)}
/* Inline-кнопка сообщения (карта dropp «🔒 Unlock $X»). В Telegram она — отдельная
   плашка ПОД пузырём во всю ширину; повторяем, чтобы оператор видел то же, что
   клиент. Кликабельна (тот же чекаут). Ширина по пузырю: block + width:100%. */
/* width:auto (не 100%) — иначе width:100% + боковые margin складываются и кнопка
   вылезает за правый край медиа на ширину margin. block сам заполняет строку. */
.dlg-msg-btn{display:block;width:auto;box-sizing:border-box;margin:6px 0 0;padding:7px 10px;
  border-radius:9px;background:rgba(255,255,255,.12);color:inherit;text-decoration:none;
  font-size:12px;font-weight:650;line-height:1;text-align:center;
  border:1px solid rgba(255,255,255,.16);transition:background .12s ease}
.dlg-msg-btn:hover{background:rgba(255,255,255,.2)}
/* У медиа-пузыря padding нулевой → кнопка встаёт ровно по ширине картинки. */
.dlg-msg--media.dlg-msg--cap .dlg-msg-btn{margin:6px 9px 9px}
/* ===== Платное медиа: превью с ценой (как в Telegram) =====
   Файл Telegram отправителю не отдаёт — только эскиз ~190 байт. Растягиваем
   его на весь кадр и размываем: получается ровно та картинка, что видит
   покупатель до оплаты. Раньше здесь висела глухая плашка, и оператор не
   понимал, ЧТО он отправил. */
.dlg-paidprev{
  position:relative;width:260px;max-width:100%;
  border-radius:12px;overflow:hidden;
  background:var(--raise-2);
}
.dlg-paidprev img{
  width:100%;height:100%;object-fit:cover;display:block;
  /* Эскиз крошечный (30×40 от Telegram) — увеличение само по себе мылит; blur
     лишь доводит его до телеграмного вида. transform:scale прячет края, которые
     blur размазывает. Кликабельности НЕТ намеренно: файла платного медиа
     Telegram отправителю не отдаёт, чётче не станет — клик обещал бы то, чего
     мы дать не можем. */
  filter:blur(14px) saturate(1.15);
  transform:scale(1.12);
}
/* НЕ куплено — плашка с ценой по центру, как в Telegram: это призыв к действию,
   он и должен быть в фокусе. */
.dlg-paidprev-badge{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  display:inline-flex;align-items:center;gap:5px;white-space:nowrap;
  padding:9px 14px;border-radius:999px;
  background:rgba(0,0,0,.55);backdrop-filter:blur(6px);
  color:#fff;font-size:13px;font-weight:600;letter-spacing:-.01em;
  box-shadow:0 2px 12px rgba(0,0,0,.35);
}
/* КУПЛЕНО — центральная плашка, но ЗОЛОТОМ, а не аптечно-зелёным: оплата идёт
   в звёздах, и факт продажи должен читаться как награда, а не как системный
   статус. Тёмный текст на золоте + внутренний блик сверху дают «металл», а не
   плоскую заливку; тёплое свечение снизу отрывает плашку от размытого кадра. */
.dlg-paidprev.is-purchased img{filter:blur(11px) saturate(1.12);transform:scale(1.1)}
.dlg-paidprev.is-purchased .dlg-paidprev-badge{
  background:linear-gradient(160deg,#FFE08A 0%,#F7C244 45%,#E8A21C 100%);
  color:#3A2606;
  font-weight:800;letter-spacing:0;
  padding:10px 16px;
  backdrop-filter:none;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.65),      /* блик — «металл», а не заливка */
    inset 0 -1px 0 rgba(140,90,10,.25),
    0 4px 20px rgba(232,162,28,.38),          /* тёплое свечение на кадре */
    0 2px 6px rgba(0,0,0,.25);
}
/* ===== Пыль поверх платного превью =====
   Клиент видит на платном медиа живые частицы (Telegram рисует их сам), а
   оператор до сих пор смотрел на мёртвый блюр и не понимал, что именно ушло в
   чат. Канва с частицами вешается на .dlg-paidprev из ui/dust.js — на ОБА вида
   превью, звёздное и карточное: клиенту пыль показывают в обоих случаях.
   Позиция частиц, их вспышки и возрождение — целиком в JS; CSS только держит
   слой на месте.
   width/height:100% ОБЯЗАТЕЛЬНЫ: canvas — замещаемый элемент, при auto-размерах
   он берёт свои внутренние 300×150 и inset:0 его не растянет. */
.dust-layer{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  pointer-events:none;   /* декорация: не перехватывает ни клик, ни выделение */
  z-index:1;
}
/* Пыль ложится НАД размытым кадром, но ПОД плашкой цены: плашка — призыв к
   действию (и единственный носитель факта покупки), перекрывать её нельзя.
   Порядок в DOM тут не помощник — канву дописывают последней, поэтому решает
   z-index, а оба слоя позиционированы. */
.dlg-paidprev .dlg-paidprev-badge{z-index:2}
/* На КУПЛЕННОМ кадре (.is-purchased) пыль НАМЕРЕННО остаётся, и правила,
   гасящего её, здесь нет. Файл платного медиа Telegram отправителю не отдаёт
   вовсе (см. комментарий у .dlg-paidprev img выше) — после оплаты оператор
   видит ровно тот же блюр, что и до неё. Убранная пыль означала бы «кадр
   раскрылся», чего не происходит, и просто убила бы превью. Факт продажи несёт
   золотая плашка. */
/* prefers-reduced-motion: гасить нечего — CSS-анимации у слоя нет, а ui/dust.js
   при этой настройке рисует ОДИН статичный кадр и не запускает rAF вовсе
   (глобальное правило на :46 канву бы не остановило — оно про animation). */

/* Самоуничтожившееся медиа — компактная плашка вместо пустого пузыря. */
.dlg-selfdestruct{display:flex;align-items:center;gap:9px;padding:8px 11px;border-radius:12px;
  background:rgba(255,255,255,.13);border:1px solid rgba(255,255,255,.2)}
.dlg-selfdestruct + .dlg-msg-text{margin-top:6px}
.dlg-sd-ic{flex:none;width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  font-size:16px;background:rgba(255,255,255,.16)}
.dlg-sd-title{font-size:12.5px;font-weight:600;line-height:1.2;letter-spacing:-.01em;opacity:.92}
/* классы из app.js (надёжнее :has/clamp — они не везде поддержаны) */
/* единый потолок ширины для любого медиа-баббла (без огромных фото на широком экране) */
.dlg-msg--media{max-width:420px}
/* визуальное медиа БЕЗ подписи — без баббл-фона/рамки (только картинка) */
.dlg-msg--media:not(.dlg-msg--cap){padding:0;background:transparent;border:none}
/* визуальное медиа С подписью — фикс. ширина (не зависит от длины подписи), фото заполняет её, верх скруглён, низ прямой */
.dlg-msg--media.dlg-msg--cap{width:340px;max-width:100%;padding:0}
.dlg-msg--media.dlg-msg--cap > img,.dlg-msg--media.dlg-msg--cap > video{width:100%;max-width:none;max-height:380px;object-fit:cover;border-radius:12px 12px 0 0;display:block}
.dlg-msg--media.dlg-msg--cap > .dlg-album{width:100%;max-width:none;border-radius:12px 12px 0 0}
/* Платное превью — не <img>, а блок: без этого правила оно оставалось уже пузыря
   (340px) и справа торчала полоса фона. Видно стало на пузырях с подписью+кнопкой. */
.dlg-msg--media.dlg-msg--cap > .dlg-paidprev{width:100%;max-width:none;border-radius:12px 12px 0 0}
.dlg-msg--media.dlg-msg--cap .dlg-msg-text{padding:6px 9px 0}
.dlg-msg--media.dlg-msg--cap .dlg-msg-orig{padding:0 9px}
.dlg-msg--media.dlg-msg--cap .mt{padding:2px 9px 6px}
.dlg-album{display:grid;grid-template-columns:1fr 1fr;gap:3px;border-radius:8px;overflow:hidden;max-width:360px}
.dlg-album img,.dlg-album video{width:100%;height:100%;aspect-ratio:1/1;object-fit:cover;border-radius:0}
.dlg-album :only-child{aspect-ratio:auto}
.dlg-msg.vn video{width:160px;height:160px;border-radius:50%;object-fit:cover}
.dlg-file{display:flex;align-items:center;gap:8px;color:var(--green);text-decoration:none}
.dlg-comp{display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--border)}
.dlg-comp input{flex:1;background:var(--bg-input);border:1px solid var(--border);border-radius:var(--r-ctl);padding:10px 12px;color:var(--text);font-size:12px}
.dlg-comp button{background:var(--green);color:#111;font-weight:700;border:none;border-radius:var(--r-ctl);padding:10px 18px;font-size:12px;cursor:pointer}

/* Парсинг */
.parser-controls { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; align-items: flex-start; flex-direction: column; }
.parser-controls-actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.parser-kw { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; width: 100%; }
.parser-kw > input { flex: 1; min-width: 200px; }
.parser-kw-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0; min-height: 0; }
.parser-kw-chip { display: inline-flex; align-items: center; gap: 4px; padding: 3px 10px; border-radius: 14px; background: var(--surface-2, #1e2330); font-size: 13px; }
.parser-chip-x, .parser-chip-add { border: 0; background: none; color: inherit; cursor: pointer; font-size: 14px; line-height: 1; padding: 0 2px; }
.parser-kw-chips-sugg .parser-kw-chip { opacity: .75; }
.parser-status { margin: 0 0 10px; color: var(--text-2, #888); font-size: 13px; }

.parser-body { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.parser-panel { flex: 1 1 300px; max-width: 340px; min-width: 260px; display: flex; flex-direction: column; gap: 15px; }
.parser-main { flex: 100 1 320px; min-width: 280px; }

.parser-grp { display: flex; flex-direction: column; gap: 5px; }
.parser-grp-l { font-size: 10px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3, #9AA39A); }
.parser-grp-row { display: flex; gap: 6px; }
.parser-grp-row input { width: 50%; }
.parser-check { display: flex; align-items: center; gap: 6px; font-size: 12px; white-space: nowrap; }
.parser-scan-btn { width: 100%; }
.parser-act-grp { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.parser-act-grp .btn { width: 100%; }

.parser-row { display: flex; align-items: center; gap: 12px; padding: 11px 14px; border-bottom: 1px solid rgba(255,255,255,.06); }
.parser-av { width: 34px; height: 34px; border-radius: 9px; flex: none; display: flex; align-items: center; justify-content: center; color: #fff; font-weight: 700; font-size: 14px; }
.parser-row-main { flex: 1; min-width: 0; }
.parser-row-top { display: flex; align-items: center; gap: 8px; }
.parser-title { font-weight: 600; }
.parser-verified { color: #3ea6ff; }
.parser-badge { font-size: 10px; padding: 2px 6px; border-radius: 4px; background: rgba(62,166,255,.15); color: #3ea6ff; }
.parser-badge.parser-group { background: rgba(120,200,120,.15); color: #6ec96e; }
.parser-row-sub { color: var(--text-2, #888); font-size: 12px; margin-top: 2px; }
.parser-row-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex: none; }
.parser-subs { font-weight: 600; font-size: 13px; }
.parser-chips { display: flex; gap: 4px; }
.parser-chip { font-size: 10px; padding: 2px 8px; border-radius: 999px; background: rgba(62,166,255,.12); color: #3ea6ff; white-space: nowrap; }
.parser-link { text-decoration: none; opacity: .6; flex: none; }
.parser-empty { padding: 24px; color: var(--text-2, #888); text-align: center; }
.dlg-banner{background:var(--bg-card);color:var(--text-2);border:1px solid var(--border);padding:8px 12px;font-size:12px;text-align:center;border-radius:var(--r-card);margin:12px}

/* ── TASK 2: Dark shell + merged sidebar + content sheet ─────────── */
.layout{height:100vh;background:var(--shell);position:relative;overflow:hidden;display:flex;padding:20px 20px 20px 0}
/* Декоративное свечение фона: radial-gradient вместо filter:blur(160px). Блюр
   такого радиуса патологически дорог в растеризации — при смене дерева слоёв
   (старт drag-and-drop карточки сцены) браузер синхронно пере-растеризует слой
   и подвисает на 1-2с в момент нажатия. Градиент даёт то же мягкое свечение
   почти бесплатно (composited, без попиксельного блюр-ядра). */
.layout::before{content:"";position:absolute;width:520px;height:520px;border-radius:50%;background:radial-gradient(circle,var(--g) 0%,transparent 68%);opacity:.12;left:-160px;bottom:-200px;animation:eg-drift 26s ease-in-out infinite alternate}
.layout::after{content:"";position:absolute;width:420px;height:420px;border-radius:50%;background:radial-gradient(circle,var(--g2) 0%,transparent 68%);opacity:.10;right:-160px;top:-160px}
@keyframes eg-drift{0%{transform:translate(0,0) scale(1)}100%{transform:translate(7%,5%) scale(1.14)}}
.sidebar{width:236px;flex-shrink:0;padding:0 22px;display:flex;flex-direction:column;position:relative;z-index:2;background:transparent;border:none}
.main{flex:1;background:var(--sheet);border-radius:var(--r-sheet);overflow-y:scroll;padding:0;position:relative;z-index:2;display:block;box-shadow:0 30px 60px -30px rgba(0,0,0,.6)}
.right-panel{display:none}
.main{scrollbar-width:thin;scrollbar-color:var(--scroll-thumb) transparent}
.main::-webkit-scrollbar{width:12px}
.main::-webkit-scrollbar-track{background:transparent;border-radius:8px;margin:8px 0}
.main::-webkit-scrollbar-thumb{background:var(--scroll-thumb);border-radius:8px;border:3px solid transparent;background-clip:padding-box}
.main::-webkit-scrollbar-thumb:hover{background:var(--scroll-thumb-hover);background-clip:padding-box}

/* ── TASK 3: Sidebar redesign (brand/workspace/search/nav) ─────────── */
.sidebar .brand{display:flex;align-items:center;gap:11px;color:#fff;font-family:var(--ff-head);font-weight:700;font-size:19px;height:var(--hdr-h);padding:0 4px;margin-bottom:8px}
.sidebar .brand .mk{width:30px;height:30px;border-radius:9px;background:linear-gradient(135deg,var(--g),var(--g2));display:flex;align-items:center;justify-content:center;flex-shrink:0}
.sidebar-user{display:flex;align-items:center;gap:11px;padding:12px 6px 4px;margin-top:14px;border-top:1px solid rgba(255,255,255,.07)}
.nav-section-label{font-size:10px;letter-spacing:.18em;color:#48524A;font-weight:700;margin:20px 6px 11px}
.nav-item{display:flex;align-items:center;gap:13px;padding:11px 13px;border-radius:12px;color:#8B948C;font-size:13.5px;font-weight:500;cursor:pointer;transition:.2s;margin-bottom:3px;position:relative}
.nav-item:hover{color:#fff;background:rgba(255,255,255,.045)}
.nav-item.active{color:#fff;background:rgba(255,255,255,.07)}
.nav-item.active::after{content:"";position:absolute;right:11px;width:6px;height:6px;border-radius:50%;background:var(--g);box-shadow:0 0 9px var(--g)}
.nav-item.active:has(.nav-badge)::after,.nav-item.active:has(.nav-live-dot:not(.hidden))::after{display:none}
.nav-badge{margin-left:auto;font-size:10px;font-weight:700;color:#06314A;background:var(--g);border-radius:20px;padding:3px 9px}
.sidebar-bottom{margin-top:auto}
.logout-btn{width:100%}
/* Workspace card */
.sb-workspace{display:flex;align-items:center;gap:11px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.07);border-radius:var(--r-card);padding:11px 12px;cursor:pointer;transition:.2s;margin-bottom:0}
.sb-workspace:hover{background:rgba(255,255,255,.08)}
.sb-workspace-ic{width:30px;height:30px;border-radius:9px;background:rgba(42,171,238,.16);display:flex;align-items:center;justify-content:center;color:var(--g);flex-shrink:0}
.sb-workspace-nm{flex:1;min-width:0}.sb-workspace-nm b{display:block;color:#fff;font-size:13px;font-weight:600}.sb-workspace-nm span{font-size:11px;color:#7C857D}
.sb-workspace-kbd{font-size:10px;color:#7C857D;border:1px solid rgba(255,255,255,.13);border-radius:6px;padding:2px 6px;font-family:inherit;background:none}
/* Search row */
.sb-search{display:flex;align-items:center;gap:9px;margin:13px 0 4px;background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.07);border-radius:var(--r-ctl);padding:10px 12px;color:#7C857D;font-size:13px;cursor:text}
/* Nav section spacing override */
.nav{padding:4px 0;flex:1;overflow-y:auto}
.nav-section{margin-bottom:0}
/* Settings row in bottom */
.sb-settings-row{display:flex;align-items:center;gap:11px;padding:8px 6px;color:#8B948C;font-size:13px;font-weight:500;border-radius:12px;cursor:pointer;transition:.2s;margin-bottom:4px}
.sb-settings-row:hover{color:#fff;background:rgba(255,255,255,.045)}
.sb-user-info{flex:1;min-width:0}
.sb-user-dots{color:#7C857D;flex-shrink:0;cursor:pointer}
.nav-item.active .nav-badge{background:var(--g);color:#06314A}

/* ── TASK 4: Core components on design tokens ─────────────────────── */
.page-header{display:flex;align-items:flex-start;gap:14px;margin-bottom:18px}
.page-heading{font-size:26px;font-weight:700}
.page-sub{color:var(--t3);font-size:13px}
.card,.add-card,.panel-section{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);padding:22px;transition:transform .28s cubic-bezier(.2,.7,.3,1),box-shadow .28s}
.card:hover,.add-card:hover{transform:translateY(-3px);box-shadow:0 22px 40px -26px rgba(34,158,217,.28)}
.btn{font-family:var(--ff-body);font-weight:600;border-radius:var(--r-ctl);cursor:pointer;border:none;transition:.2s;display:inline-flex;align-items:center;gap:8px;width:auto}
.btn-primary{background:linear-gradient(135deg,var(--g),var(--g2));color:#fff;padding:0 20px;height:42px}
.btn-primary:hover{filter:brightness(1.07)}
.btn-ghost,.btn-secondary{background:var(--ctl);color:var(--t2)}
.btn-danger{background:rgba(224,83,59,.10);color:var(--bad);border:1px solid rgba(224,83,59,.28)}
.btn-danger:hover{background:rgba(224,83,59,.18);border-color:rgba(224,83,59,.45);color:var(--bad)}
.btn-sm{height:34px;padding:0 14px;font-size:12px}
.form-input,.select-input,.dlg-search{font-family:var(--ff-body);background:var(--card);border:1px solid var(--line);border-radius:10px;padding:9px 12px;color:var(--t1);width:100%}
.form-input:focus,.select-input:focus{outline:2px solid rgba(42,171,238,.35);border-color:var(--g)}
/* z-index 9999, а НЕ 1000 (как было). Фактическая шкала оверлеев проекта снизу
   вверх: дровер сцены #scn-drawer-root 500; бэкдропы модалок пикера
   (.dlg-modal-backdrop) и лендинга (.lnd-modal) 1000; просмотр набора
   (.dlg-mp-ppv) 1050; конфирм закрытия пикера (.dlg-mp-confirm) 1060; редактор
   кружка (.video-edit-modal) 1150; плавающие панели действий (.bulk-bar /
   #char-actionbar) 9998; лайтбокс (.dlg-lightbox) 10000; тосты (.app-toast) 10001.
   На 1000 блокирующая модалка оказывалась ПОД панелью действий: над затемнением
   торчала живая кнопка «Удалить» из #char-actionbar — та самая, чьё подтверждение
   модалка и показывает. Ставим ВЫШЕ панелей (9998), но НИЖЕ лайтбокса (10000) и
   тостов (10001): лайтбокс — полноэкранный просмотр, из-под которого модалку всё
   равно не достать, а тост обязан читаться поверх всего, включая эту модалку
   (её же ошибки он и показывает). 9999 — единственное целое в этом зазоре. */
.modal-overlay{position:fixed;inset:0;background:rgba(11,15,12,.55);display:flex;align-items:center;justify-content:center;z-index:9999}
/* max-height + свой скролл: модалка подтверждения выросла на гейт «наберите имя»
   (лейбл + поле, ~55px), и на низком экране (или в альбомной ориентации телефона)
   нижний край с кнопками «Отменить/Удалить» уходил за пределы вьюпорта — оверлей
   центрирует flex'ом и наружу не скроллится. dvh, а не vh: на мобиле адресная
   строка съедает часть vh. */
.modal,.modal-box{background:var(--card);border-radius:var(--r-card);padding:24px;max-width:440px;width:92%;max-height:calc(100dvh - 32px);overflow-y:auto}
.error-msg{color:var(--bad);font-size:13px}
.nav-live-dot{width:7px;height:7px;border-radius:50%;background:var(--g);box-shadow:0 0 8px var(--g)}
.topbar-nav{display:flex;align-items:center;gap:14px;margin-bottom:18px}
.breadcrumb{color:var(--t3);font-size:13px}
.ws-badge{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--t2)}
.ws-dot{width:8px;height:8px;border-radius:50%;background:var(--off)}
.ws-badge.online .ws-dot{background:var(--g);box-shadow:0 0 8px var(--g)}
.pill,.badge-status{font-weight:600;font-size:11px;padding:3px 9px;border-radius:20px}

/* Status pill — actual DOM classes from app.js (status-pill--active/sleeping/disconnected) */
.status-pill{font-weight:600;font-size:11px;padding:3px 9px;border-radius:20px;cursor:pointer;display:inline-block}
.status-pill--active{background:#EAF6EE;color:#15803D}
.status-pill--sleeping{background:#FBF1DE;color:#9A7B2E}
.status-pill--disconnected{background:#F1F3F1;color:var(--t3)}
/* gated: модуль включён, но аккаунт спит/отключён — приглушённый зелёный
   («работает, но сейчас отдыхает»), НЕ серый и НЕ зачёркнутый */
.status-pill--paused{background:#EAF6EE;color:#15803D;opacity:.55}
.btn-ghost:hover,.btn-secondary:hover{background:var(--ctl-h)}

/* ── Overview page ───────────────────────────────────────────────── */
.ov-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:16px}
.ov-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);padding:22px;position:relative;transition:transform .28s cubic-bezier(.2,.7,.3,1),box-shadow .28s}
.ov-card:hover{transform:translateY(-3px);box-shadow:0 22px 40px -26px rgba(34,158,217,.28)}
.ov-card.mint{background:var(--mint);border-color:var(--mint-bd)}
.ov-cap{font-size:11px;letter-spacing:.13em;text-transform:uppercase;color:var(--t3);font-weight:600}
.ov-big{font-family:var(--ff-num);font-weight:400;color:var(--t1);font-variant-numeric:tabular-nums;font-size:42px;line-height:1;letter-spacing:-.018em;margin:16px 0 6px}
.ov-of{font-size:18px;color:var(--t3);font-weight:500}
.ov-delta{color:var(--g2);font-weight:600;font-size:12.5px}
/* Фиат рядом со звёздами в обзорной карточке — зелёный акцент реальных денег. */
.ov-fiat{color:#16a34a;font-weight:700;font-size:15px;font-variant-numeric:tabular-nums;margin:2px 0 4px}
[data-theme="dark"] .ov-fiat{color:#4ade80}
.chart{display:flex;margin-top:18px}
.yax{display:flex;flex-direction:column;justify-content:space-between;padding-right:12px;height:150px;text-align:right}
.yax span{font-size:10px;color:var(--t3)}
.plot{position:relative;height:150px}
.gl{position:absolute;left:0;right:0;border-top:1px dashed var(--line)}
.barsd{position:absolute;inset:0;display:flex;align-items:flex-end;gap:1px}
.ov-card.mint .barsd{position:relative;height:56px;margin-top:20px}
.bd{flex:1;border-radius:1.5px;background:var(--bar);min-width:1px}
.bd.hi{background:linear-gradient(180deg,var(--lime),var(--g2));opacity:.92}
.mark{position:absolute;top:0;bottom:0;width:0;border-left:1.5px dashed var(--shell)}
.mark .pt{position:absolute;left:-4px;width:8px;height:8px;border-radius:50%;background:var(--shell);box-shadow:0 0 0 3px #fff}
.tip{position:absolute;left:50%;transform:translateX(-50%);background:var(--shell);color:#fff;font-size:11px;font-weight:600;padding:5px 10px;border-radius:8px;white-space:nowrap}
.tip::after{content:"";position:absolute;left:50%;bottom:-4px;transform:translateX(-50%);border:4px solid transparent;border-top-color:var(--shell)}
.spark{height:48px;width:100%;margin-top:14px;display:block}
.ring{width:122px;height:122px;border-radius:50%;display:flex;align-items:center;justify-content:center;margin:6px auto 14px}
.ring .in{width:86px;height:86px;border-radius:50%;background:var(--card);display:flex;flex-direction:column;align-items:center;justify-content:center}
.ring .in b{font-family:var(--ff-num);font-weight:500;font-size:23px;color:var(--t1)}
.ring .in span{font-size:11px;color:var(--t3)}
.ov-stat{display:flex;align-items:center;gap:11px;padding:8px 0;border-bottom:1px solid var(--border)}
.ov-stat:last-child{border-bottom:none}
.ov-stat b{margin-left:auto;font-family:var(--ff-num);font-weight:500;color:var(--t1)}
.ov-stat .d{width:8px;height:8px;border-radius:50%}
.ov-stat .d.ok{background:var(--ok)}.ov-stat .d.warn{background:var(--warn)}.ov-stat .d.off{background:var(--off)}

/* ── TASK 6-1: Accounts page ─────────────────────────────────────── */
/* KPI stat cards */
#page-accounts .acc-stats { margin-bottom: 18px; }
#page-accounts .acc-stat-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 13px 18px;
}
#page-accounts .acc-stat-card--all          { border-left: 3px solid var(--t3); }
#page-accounts .acc-stat-card--active       { border-left: 3px solid var(--ok); }
#page-accounts .acc-stat-card--sleeping     { border-left: 3px solid var(--warn); }
#page-accounts .acc-stat-card--disconnected { border-left: 3px solid var(--off); }
#page-accounts .acc-stat-card--selected     { background: var(--mint); }
#page-accounts .acc-stat-card .num { color: var(--t1); font-family: var(--ff-num); font-size: 27px; }
#page-accounts .acc-stat-card .lbl { color: var(--t2); }
/* Цветовой код числа по состоянию — карточка читается с одного взгляда,
   а не как бледный пустой блок. «Всего» остаётся нейтральным. */
#page-accounts .acc-stat-card--active .num       { color: var(--ok); }
#page-accounts .acc-stat-card--sleeping .num     { color: var(--warn); }
#page-accounts .acc-stat-card--disconnected .num { color: var(--t3); }

/* Action row — search input */
#page-accounts .acc-search {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  color: var(--t1);
  padding: 9px 13px;
}
#page-accounts .acc-search:focus { outline: 2px solid rgba(42,171,238,.3); border-color: var(--g); }

/* Account table wrapper */
#page-accounts .acc-table-wrap {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}
#page-accounts .acc-table thead tr {
  background: var(--mint);
  color: var(--t2);
}
#page-accounts .acc-table tbody tr { border-top: 1px solid var(--line); color: var(--t1); }
#page-accounts .acc-table tbody tr:hover { background: var(--mint); }
#page-accounts .acc-table td { color: var(--t2); }
#page-accounts .acc-table td:first-child+td+td { color: var(--t1); font-weight: 600; }
#page-accounts .acc-id-mono { color: var(--t3); }
#page-accounts .acc-avatar-sm { background: var(--mint); }
#page-accounts .acc-table tr.row-selected { background: rgba(42,171,238,.07); }

/* icon-btn in light context */
#page-accounts .icon-btn {
  background: var(--mint);
  border: 1px solid var(--line);
  color: var(--t2);
}
#page-accounts .icon-btn:hover { background: var(--line); color: var(--t1); }

/* char-select-inline in light context */
#page-accounts .char-select-inline {
  background-color: rgba(42,171,238,.08);
  border-color: rgba(42,171,238,.2);
  color: var(--g2);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23229ED9' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
#page-accounts .char-select-inline option { background: var(--card); color: var(--t1); }

/* Add-card (dashed) */
#page-accounts .add-card {
  border: 1.5px dashed var(--line);
  background: var(--card);
}
#page-accounts .add-card:hover { border-color: var(--g); background: var(--mint); }
#page-accounts .add-info strong { color: var(--t1); }
#page-accounts .add-info p { color: var(--t2); }
#page-accounts .auth-opt {
  background: var(--mint);
  border: 1px solid var(--line);
}
#page-accounts .auth-opt:hover { border-color: var(--g); }
#page-accounts .auth-opt-label { color: var(--t2); }

/* Bulk bar — light elevated card */
.bulk-bar {
  background: var(--card);
  border: 1px solid var(--line);
  box-shadow: 0 16px 48px rgba(10,15,22,.16), 0 2px 8px rgba(10,15,22,.07);
}
.bulk-bar__count   { color: var(--t2); }
.bulk-bar__count-n { color: var(--g); }
.bulk-bar__sep     { background: var(--line); }
.bulk-bar__btn     { background: transparent; color: var(--t1); border: 1px solid transparent; }
.bulk-bar__btn .bic { color: var(--t2); }
.bulk-bar__btn:hover { background: var(--mint); }
.bulk-bar__btn:hover .bic { color: var(--t1); }
.bulk-bar__btn--ghost { color: var(--t2); }
.bulk-bar__btn--danger { background: transparent; color: var(--bad); }
.bulk-bar__btn--danger .bic { color: var(--bad); }
.bulk-bar__btn--danger:hover { background: color-mix(in srgb, var(--bad) 12%, transparent); }

/* ── TASK 6-2: Dialogs page ──────────────────────────────────────── */
#page-dialogs .dlg-wrap {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}
/* Account rail */
#page-dialogs .dlg-rail {
  background: var(--mint);
  border-right: 1px solid var(--line);
}
#page-dialogs .dlg-rail .av {
  background: var(--card);
  border: 1px solid var(--line);
  color: var(--t2);
}
#page-dialogs .dlg-rail .av.on {
  border-color: var(--g);
  color: var(--g2);
  box-shadow: 0 0 0 2px rgba(42,171,238,.2);
}
/* Chat list column */
#page-dialogs .dlg-list { border-right: 1px solid var(--line); }
#page-dialogs .dlg-list-hd { border-bottom: 1px solid var(--line); background: var(--card); }
#page-dialogs .dlg-search {
  background: var(--mint);
  border: 1px solid var(--line);
  color: var(--t1);
  border-radius: var(--r-ctl);
}
#page-dialogs .dlg-search:focus { outline: 2px solid rgba(42,171,238,.3); border-color: var(--g); }
/* Segment tabs */
#page-dialogs .dlg-seg span {
  background: var(--mint);
  color: var(--t2);
  border-radius: var(--r-ctl);
}
#page-dialogs .dlg-seg span.act { background: var(--g); color: #fff; font-weight: 600; }
/* Chat row */
#page-dialogs .dlg-ch { border-bottom: 1px solid var(--line); }
#page-dialogs .dlg-ch:hover { background: var(--mint); }
#page-dialogs .dlg-ch.sel { background: rgba(42,171,238,.08); border-left: 2px solid var(--g); }
#page-dialogs .dlg-ch .cav { background: var(--mint); color: var(--t2); }
#page-dialogs .dlg-ch .cn { color: var(--t1); }
#page-dialogs .dlg-ch .cp { color: var(--t2); }
/* Unread badge */
#page-dialogs .dlg-badge { background: var(--g); color: #fff; }
/* Neurochat pill */
#page-dialogs .nc-pill.on  { background: none; border: 0; color: var(--t1); }
#page-dialogs .nc-pill.on .d  { background: #22c55e; }
#page-dialogs .nc-pill.off { background: none; border: 0; color: var(--t3); }
#page-dialogs .nc-pill.off .d { background: #c2c8cf; }
/* Conversation pane */
#page-dialogs .dlg-conv { background: var(--sheet); }
#page-dialogs .dlg-empty { color: var(--t3); }
#page-dialogs .dlg-chd { border-bottom: 1px solid var(--line); background: var(--card); }
#page-dialogs .dlg-chd b { color: var(--t1); }
#page-dialogs .dlg-chd small { color: var(--t2); }
#page-dialogs .dlg-chd .lbl { color: var(--t3); }
/* Messages */
#page-dialogs .dlg-body { background: var(--sheet); }
#page-dialogs .dlg-msg.in {
  background: var(--card);
  color: var(--t1);
  box-shadow: 0 1px 3px rgba(10,15,22,.06);
}
#page-dialogs .dlg-msg.out {
  background: linear-gradient(135deg, var(--g), var(--g2));
  color: #fff;
  border: none;
}
#page-dialogs .dlg-msg .mt { color: rgba(255,255,255,.6); }
#page-dialogs .dlg-msg.in .mt { color: var(--t3); }
/* Compose row */
#page-dialogs .dlg-comp { border-top: 1px solid var(--line); background: var(--card); }
#page-dialogs .dlg-comp input {
  background: var(--mint);
  border: 1px solid var(--line);
  color: var(--t1);
}
#page-dialogs .dlg-comp button { background: linear-gradient(135deg,var(--g),var(--g2)); color: #fff; }
/* Banner */
#page-dialogs .dlg-banner {
  background: var(--mint);
  color: var(--t2);
  border: 1px solid var(--line);
}

/* ── TASK 6-3: Characters page ───────────────────────────────────── */
/* Toolbar / search */
#page-characters .chars-toolbar { margin: 0 0 14px; }
#page-characters .chars-toolbar.hidden { display: none; }
#page-characters .chars-search { position: relative; max-width: 360px; }
#page-characters .chars-search svg {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  width: 15px; height: 15px; fill: none; stroke: var(--t3);
  stroke-width: 2; stroke-linecap: round; pointer-events: none;
}
#page-characters .chars-search .form-input { padding-left: 32px; }

/* Card grid */
#page-characters .chars-grid {
  gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
#page-characters .char-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 16px 16px 13px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  cursor: pointer;
  transition: border-color .18s var(--ease-out), transform .18s var(--ease-out), box-shadow .18s var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  #page-characters .char-card:hover {
    border-color: var(--line);
    transform: translateY(-3px);
    box-shadow: 0 18px 40px -26px rgba(0,0,0,.75);
  }
  #page-characters .char-card:hover .char-avatar { transform: scale(1.05) rotate(-1.5deg); }
}
#page-characters .char-card:active { transform: translateY(-1px) scale(.994); }

/* Head: avatar · name+preview · IQ ring */
#page-characters .char-card-head { display: flex; gap: 12px; align-items: center; }
#page-characters .char-avatar {
  width: 46px; height: 46px; border-radius: 14px; flex: none;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-weight: 700; font-size: 18px; letter-spacing: .2px;
  box-shadow: 0 6px 16px -8px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.25);
  transition: transform .2s var(--ease-out);
}
#page-characters .char-card-id { flex: 1; min-width: 0; }
#page-characters .char-card-name {
  color: var(--t1); font-size: 15px; font-weight: 650; margin-bottom: 3px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
#page-characters .char-card-preview {
  color: var(--t2); font-size: 12px; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
#page-characters .char-card-preview.is-empty { color: var(--t3); font-style: italic; opacity: .7; }

/* IQ ring gauge */
#page-characters .char-iq-ring {
  position: relative; flex: none;
  width: 40px; height: 40px;
  display: grid; place-items: center;
  cursor: default;
}
#page-characters .char-iq-ring svg { width: 40px; height: 40px; display: block; }
#page-characters .char-iq-ring-track { fill: none; stroke: var(--bar); stroke-width: 3.5; }
#page-characters .char-iq-ring-prog {
  fill: none; stroke: var(--iq-color); stroke-width: 3.5; stroke-linecap: round;
  stroke-dasharray: var(--iq-circ);
  stroke-dashoffset: var(--iq-dash);
  transform: rotate(-90deg); transform-origin: center;
}
#page-characters .char-iq-ring-num {
  position: absolute;
  font-family: var(--ff-num); font-size: 11.5px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--iq-color); line-height: 1;
  margin-top: .5px; /* оптическое выравнивание цифр Poppins к центру */
}

/* Footer meta */
#page-characters .char-card-foot {
  display: flex; align-items: center; gap: 10px;
  padding-top: 11px; border-top: 1px solid var(--line);
}
#page-characters .char-stat {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 11px; font-weight: 600; color: var(--t2); white-space: nowrap;
}
#page-characters .char-stat--acc { color: var(--t3); }
#page-characters .char-dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--t3);
}
#page-characters .char-dot.is-active {
  background: #2aabee; box-shadow: 0 0 0 3px rgba(42,171,238,.16);
}
#page-characters .char-card-owner {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 10px; font-weight: 600;
  padding: 3px 9px; border-radius: 999px;
  background: var(--ctl); color: var(--t2);
  max-width: 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* One-shot entrance — ring fill + staggered card reveal, only on fresh render */
#page-characters .chars-grid.is-fresh .char-card {
  opacity: 0; animation: char-card-in .42s var(--ease-out) forwards;
}
#page-characters .chars-grid.is-fresh .char-card:nth-child(1) { animation-delay: 0ms; }
#page-characters .chars-grid.is-fresh .char-card:nth-child(2) { animation-delay: 45ms; }
#page-characters .chars-grid.is-fresh .char-card:nth-child(3) { animation-delay: 90ms; }
#page-characters .chars-grid.is-fresh .char-card:nth-child(4) { animation-delay: 135ms; }
#page-characters .chars-grid.is-fresh .char-card:nth-child(5) { animation-delay: 180ms; }
#page-characters .chars-grid.is-fresh .char-card:nth-child(6) { animation-delay: 215ms; }
#page-characters .chars-grid.is-fresh .char-card:nth-child(n+7) { animation-delay: 240ms; }
#page-characters .chars-grid.is-fresh .char-iq-ring-prog {
  animation: char-iq-fill .8s var(--ease-out) both;
}
@keyframes char-card-in {
  from { opacity: 0; transform: translateY(10px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes char-iq-fill {
  from { stroke-dashoffset: var(--iq-circ); }
  to   { stroke-dashoffset: var(--iq-dash); }
}
@media (prefers-reduced-motion: reduce) {
  #page-characters .chars-grid.is-fresh .char-card,
  #page-characters .chars-grid.is-fresh .char-iq-ring-prog { animation: none; opacity: 1; }
}

/* Editor */
#page-characters .char-editor {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 26px;
}
#page-characters .field-label { color: var(--t2); }
#page-characters .field-subgroup { color: var(--t3); border-bottom: 1px solid var(--line); }
#page-characters .save-bar { border-top: 1px solid var(--line); }

/* Плавающая панель действий редактора персонажа (#char-actionbar в <body>, стиль bulk-bar).
   Клиренс, чтобы бар не перекрывал последние поля при скролле. */
#page-characters .char-editor { padding-bottom: 88px; }
.char-actionbar .bulk-bar__btn--primary { background: var(--accent); color: #04121b; font-weight: 700; }
.char-actionbar .bulk-bar__btn--primary .bic { color: #04121b; }
.char-actionbar .bulk-bar__btn--primary:hover { background: var(--accent); filter: brightness(1.06); box-shadow: 0 0 18px var(--accent-glow); }
.char-actionbar .bulk-bar__btn--primary:hover .bic { color: #04121b; }
/* Пока открыт дровер сцены — бара персонажа на экране нет. Он в <body> с z-index
   9998, дровер — 500, поэтому бар физически висел ПОВЕРХ окна сцены (на телефоне
   прямо на его контенте), и «Удалить» из него принимали за удаление сцены.
   Класс ставит scnOpenDrawer, снимает scnCloseDrawer. */
body.scn-drawer-open #char-actionbar { display: none; }

/* Ползунок вероятности голосового. Незалитая часть трека была #D9E6EF —
   остаток выпиленной светлой темы: на OLED-фоне она светилась белым. */
#page-characters .prob-slider {
  background: linear-gradient(to right, var(--g) 0%, var(--g) var(--pct, 33%), rgba(255,255,255,.12) var(--pct, 33%));
}
#page-characters .prob-slider::-webkit-slider-thumb {
  background: var(--g2);
  box-shadow: 0 0 6px rgba(34,158,217,.3);
}
#page-characters .prob-value { color: var(--g2); }

/* Checkbox row in light mode */
#page-characters .checkbox-row { color: var(--t1); }
#page-characters .checkbox-row input[type="checkbox"] { accent-color: var(--g); }


/* Two-pane split */
/* Header bar */


/* History log */


/* ── Единые «красивые» чекбоксы/радио на всём сайте ───────────────────────────
   Фиксированный размер + appearance:none → консистентно и не «распирает» flex-ряды.
   Частные правила секций (.checkbox-row size, и т.п.) при необходимости переопределяют. */
input[type="checkbox"],
input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  border: 1.5px solid var(--line, #c3c8cf);
  border-radius: 5px;
  background: var(--card, #fff);
  cursor: pointer;
  display: inline-grid;
  place-content: center;
  vertical-align: middle;
  transition: background .12s, border-color .12s;
}
input[type="radio"] { border-radius: 50%; }
input[type="checkbox"]:hover,
input[type="radio"]:hover { border-color: var(--g, #2AABEE); }
input[type="checkbox"]:checked,
input[type="radio"]:checked,
input[type="checkbox"]:indeterminate {
  background: var(--g, #2AABEE);
  border-color: var(--g, #2AABEE);
}
input[type="checkbox"]:checked::after {
  content: "";
  width: 4px; height: 8px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: translateY(-1px) rotate(45deg);
}
input[type="checkbox"]:indeterminate::after {
  content: "";
  width: 8px; height: 2px;
  background: #fff;
  border-radius: 1px;
}
input[type="radio"]:checked::after {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: #fff;
}
input[type="checkbox"]:disabled,
input[type="radio"]:disabled { opacity: .5; cursor: default; }
input[type="checkbox"]:focus-visible,
input[type="radio"]:focus-visible { outline: 2px solid rgba(42,171,238,.45); outline-offset: 1px; }

/* --- Parser --- */
#page-parser .parser-controls select,
#page-parser .parser-controls input[type="text"],
#page-parser .parser-controls input[type="number"],
#page-parser .parser-controls input[type="search"],
#page-parser .parser-panel select,
#page-parser .parser-panel input[type="text"],
#page-parser .parser-panel input[type="number"],
#page-parser .parser-panel input[type="search"] {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  color: var(--t1);
  padding: 8px 11px;
  font-family: var(--ff-body);
  width: 100%;
  box-sizing: border-box;
}
/* Выбор аккаунтов → выпадающий список с поиском и «выбрать все» (масштаб на 50+) */
.parser-acc-dd { position: relative; }
#page-parser .parser-kw .parser-acc-dd { flex: 0 0 auto; }
#page-parser .parser-acc-trigger {
  display: inline-flex; align-items: center; gap: 10px;
  min-width: 200px; height: 42px; padding: 0 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-ctl);
  color: var(--t1); font: inherit; font-size: 13px; cursor: pointer;
}
#page-parser .parser-acc-trigger:hover { border-color: var(--t3); }
#page-parser .parser-acc-trigger:disabled { opacity: .6; cursor: default; }
.parser-acc-caret {
  margin-left: auto;
  width: 14px; height: 14px; flex: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23868E9C' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  transition: transform .15s ease;
}
.parser-acc-dd:has(.parser-acc-pop:not(.hidden)) .parser-acc-caret { transform: rotate(180deg); }
#page-parser .parser-acc-pop {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 30;
  width: 280px; max-width: 84vw;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--r-ctl);
  box-shadow: 0 10px 30px rgba(0,0,0,.35); padding: 10px;
  display: flex; flex-direction: column; gap: 8px;
}
#page-parser .parser-acc-pop .parser-acc-search {
  width: 100%; box-sizing: border-box; height: 34px; padding: 0 10px;
  background: var(--sheet); border: 1px solid var(--line); border-radius: var(--r-ctl);
  color: var(--t1); font: inherit; font-size: 13px;
}
.parser-acc-all {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px; color: var(--t2); padding: 2px 2px 8px;
  border-bottom: 1px solid var(--line); cursor: pointer;
}
.parser-acc-list { display: flex; flex-direction: column; max-height: 240px; overflow-y: auto; }
.parser-acc-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 6px; border-radius: 8px; cursor: pointer;
}
#page-parser .parser-acc-item:hover { background: var(--mint); }
.parser-acc-txt { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; flex: 1 1 auto; }
#page-parser .parser-acc-nm,
#page-parser .parser-acc-ph { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#page-parser .parser-acc-nm { color: var(--t1); font-size: 13px; font-weight: 600; }
#page-parser .parser-acc-ph { color: var(--t2); font-size: 11px; }
#page-parser .parser-controls { align-items: flex-start; }
/* Keyword input row: equal 42px height, input stretches */
#page-parser .parser-kw > input,
#page-parser .parser-kw .btn {
  height: 42px;
  box-sizing: border-box;
}
#page-parser .parser-kw > input { padding: 0 12px; }
#page-parser .parser-kw .btn { flex: 0 0 auto; }
#page-parser .parser-controls-actions .btn { flex: 0 0 auto; }
#page-parser .parser-kw-chip { background: var(--card); border: 1px solid var(--line); color: var(--t1); }
#page-parser .parser-chip-x, #page-parser .parser-chip-add { color: var(--t2); }
#page-parser .parser-chip-x:hover, #page-parser .parser-chip-add:hover { color: var(--g); }
#page-parser .parser-controls input:focus,
#page-parser .parser-panel input:focus,
#page-parser .parser-panel select:focus { outline: 2px solid rgba(42,171,238,.3); border-color: var(--g); }
#page-parser .parser-status { color: var(--t2); }
#page-parser .parser-panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 18px 18px 20px;
}
/* Card title — единый язык с редизайном «Настроек» (.set-card__title) */
.parser-panel-title {
  font-family: var(--ff-head, inherit);
  font-size: 15px;
  color: var(--t1);
  letter-spacing: -.012em;
  padding-bottom: 13px;
  margin-bottom: 2px;
  border-bottom: 1px solid var(--line);
}
#page-parser .parser-grp { gap: 7px; }
/* Группа-лейбл: читаемее, но без «крика» */
#page-parser .parser-grp-l {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .055em;
  color: var(--t2);
}
/* Контролы панели — ритм как у set-field */
#page-parser .parser-panel select,
#page-parser .parser-panel input[type="text"],
#page-parser .parser-panel input[type="number"] {
  padding: 9px 12px;
  font-size: 13px;
  color: var(--t1);
}
/* Кастомная стрелка у select вместо нативной «качельки» */
#page-parser .parser-panel select {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  padding-right: 30px;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23868E9C' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 11px center;
}
/* Убрать спиннеры у number-полей (мин/макс/возраст/рейтинг) */
#page-parser .parser-panel input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
#page-parser .parser-panel input[type="number"]::-webkit-outer-spin-button,
#page-parser .parser-panel input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* Чекбоксы-строки (ИИ-защита, «только с обсуждением») — крупнее, читаемее */
#page-parser .parser-grp > .parser-check { font-size: 13px; color: var(--t1); }
/* Языки → компактные пилюли-тогглы (scope строго #parser-langs) */
#page-parser #parser-langs { display: flex; flex-wrap: wrap; gap: 6px; }
#page-parser #parser-langs .parser-check {
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--t2);
  cursor: pointer;
  user-select: none;
  transition: background .12s, border-color .12s, color .12s;
}
#page-parser #parser-langs .parser-check input {
  position: absolute;
  width: 1px; height: 1px; opacity: 0; margin: 0; pointer-events: none;
}
#page-parser #parser-langs .parser-check:hover { border-color: var(--t3); color: var(--t1); }
#page-parser #parser-langs .parser-check:has(input:checked) {
  background: rgba(42,171,238,.14);
  border-color: var(--g);
  color: var(--g2);
}
/* Глубокий скан — заметная primary-кнопка панели */
#page-parser .parser-scan-btn { width: 100%; padding: 11px; font-weight: 600; margin-top: 2px; }
#page-parser .parser-act-grp { border-top: 1px solid var(--line); padding-top: 12px; gap: 7px; }
#page-parser #parser-results {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
}
#page-parser .parser-row { border-bottom: 1px solid var(--line); transition: background .12s; }
#page-parser .parser-row:hover { background: var(--mint); }
#page-parser .parser-row:last-child { border-bottom: none; }
#page-parser .parser-title { color: var(--t1); }
#page-parser .parser-row-sub { color: var(--t2); }
#page-parser .parser-badge { background: rgba(42,171,238,.12); color: var(--g2); }
#page-parser .parser-chip { background: rgba(42,171,238,.12); color: var(--g2); }
#page-parser .parser-subs { color: var(--t1); }
#page-parser .parser-empty { color: var(--t2); }
#page-parser .parser-grp-row input { width: 50%; box-sizing: border-box; }
#page-parser .parser-verified { color: var(--g); }
#page-parser .parser-badge.parser-group { background: rgba(94,184,94,.16); color: #3a9e3a; }
#page-parser .parser-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#page-parser .parser-badge { flex: none; }

/* --- Updates --- */
#page-updates .update-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 18px 20px;
  margin-bottom: 12px;
}
#page-updates .update-date  { color: var(--t3); }
#page-updates .update-title { color: var(--t1); }
#page-updates .update-body  { color: var(--t2); }
#page-updates .update-status-draft {
  background: var(--mint);
  color: var(--t3);
}
#page-updates .update-status-pub {
  background: rgba(34,197,94,.12);
  color: #15803D;
}
#page-updates .updates-empty { color: var(--t3); }
#page-updates .update-form {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 18px 20px;
  margin-bottom: 16px;
}
#page-updates .update-input {
  background: var(--mint);
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  color: var(--t1);
  font-family: var(--ff-body);
}
#page-updates .update-input:focus { outline: 2px solid rgba(42,171,238,.3); border-color: var(--g); }

/* ── TASK 6-6: Admin page ────────────────────────────────────────── */
/* Tab strip */
#page-admin .admin-tabs {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 5px;
}
#page-admin .admin-tab { color: var(--t2); border-radius: var(--r-ctl); }
#page-admin .admin-tab:hover { background: var(--mint); color: var(--t1); }
#page-admin .admin-tab.active { background: var(--mint); color: var(--t1); font-weight: 700; }

/* Page-access: сегмент из 3 режимов (Доступна всем / В разработке / Только админам) */
.pa-seg { display: inline-flex; gap: 4px; background: var(--sheet); border: 1px solid var(--line); border-radius: var(--r-ctl); padding: 3px; flex: 0 0 auto; }
.pa-seg-btn {
  border: none; background: transparent; color: var(--t2);
  font-size: 12px; font-weight: 500; line-height: 1; white-space: nowrap;
  padding: 6px 11px; border-radius: calc(var(--r-ctl) - 4px); cursor: pointer;
  transition: color 120ms ease, background 120ms ease, transform 120ms ease;
}
.pa-seg-btn:hover { color: var(--t1); }
.pa-seg-btn:active { transform: scale(0.97); }
.pa-seg-btn.active { background: var(--g); color: #fff; font-weight: 600; cursor: default; }
.pa-seg-btn.active:hover { color: #fff; }

/* Data table wrapper */
#page-admin .data-table-wrap {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
}
#page-admin .table-meta { color: var(--t3); border-bottom: 1px solid var(--line); }
#page-admin .data-table th {
  background: var(--mint);
  color: var(--t2);
  border-bottom: 1px solid var(--line);
}
#page-admin .data-table td {
  border-bottom: 1px solid var(--line);
  color: var(--t2);
}
#page-admin .data-table tr:last-child td { border-bottom: none; }
#page-admin .data-table tbody tr:hover td { background: var(--mint); }
#page-admin .td-primary { color: var(--t1) !important; }
#page-admin .td-muted   { color: var(--t3) !important; }

/* Admin stat cards */
#page-admin .admin-stats-grid { gap: 14px; margin-bottom: 24px; }
#page-admin .admin-stat-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 20px 18px;
}
#page-admin .admin-stat-val   { color: var(--t1); font-family: var(--ff-num); }
#page-admin .admin-stat-label { color: var(--t2); }
#page-admin .admin-stat-sub   { color: var(--t3); }

/* Smaller stat cards used in stats tab */
#page-admin .stat {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 18px;
}
#page-admin .stat-label { color: var(--t2); }
#page-admin .stat-num   { color: var(--t1); font-family: var(--ff-num); }
#page-admin .stat-trend { color: var(--ok); }
#page-admin .stat-trend.amber { color: var(--warn); }
#page-admin .stat-trend.muted { color: var(--t3); }

/* Section title inside admin panels */
#page-admin .admin-section-title { color: var(--t1); }

/* Table avatar (users) */
#page-admin .table-avatar { background: var(--g); color: #fff; }
#page-admin .table-user-cell { gap: 10px; }

/* Role badge */
#page-admin .role-badge {
  background: var(--mint);
  border-color: var(--line);
  color: var(--t3);
}
#page-admin .role-badge.admin {
  background: rgba(42,171,238,.1);
  border-color: rgba(42,171,238,.2);
  color: var(--g2);
}

/* Form inputs inside admin (balance field, filter inputs) */
#page-admin .form-input {
  background: var(--mint);
  border: 1px solid var(--line);
  color: var(--t1);
}
#page-admin .form-input:focus { outline: 2px solid rgba(42,171,238,.3); border-color: var(--g); }

/* DB browser table buttons */
#page-admin #db-view-data .data-table-wrap {
  overflow-x: auto;
}
#page-admin #db-view-data .data-table th { background: var(--mint); }
#page-admin #db-view-data .data-table td { color: var(--t2); }

/* ── TASK 6-7: Auth page + modals ────────────────────────────────── */
/* Auth page остаётся в тёмной палитре независимо от темы — см. блок AUTH выше. */

/* Modals — light sheet language */
.modal-overlay { background: rgba(10,15,22,.45); backdrop-filter: blur(8px); }
.modal, .modal-box {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  box-shadow: 0 24px 60px rgba(10,15,22,.15);
  color: var(--t1);
}
.modal .text-muted, .modal-box .text-muted { color: var(--t2); }
.modal-title { color: var(--t1); font-family: var(--ff-head); }
.modal-sub   { color: var(--t2); }
.modal-confirm-icon { color: var(--t1); }
.modal-confirm-sub  { color: var(--t2); }
.modal-confirm-gate__label { color: var(--t2); }

/* Add-account modal: auth-opt cards.
   .modal-box в селекторах — ради модалки подъёма аккаунта: она собрана на
   .modal-box (как соседняя «Прокси аккаунта»), а плитки выбора входа в ней те
   же самые. Тот же парный селектор уже применён ниже к .form-input/.select-input. */
.modal .auth-opt, .modal-box .auth-opt {
  background: var(--mint);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  transition: border-color .15s, background .15s;
}
.modal .auth-opt:hover, .modal-box .auth-opt:hover { border-color: var(--g); background: rgba(42,171,238,.07); }
.modal .auth-opt-label, .modal-box .auth-opt-label { color: var(--t2); }

/* QR container */
.qr-hint { color: var(--t2); }
.qr-container { background: #fff; border-radius: var(--r-card); }

/* Inputs inside modals */
.modal .form-input, .modal-box .form-input {
  background: var(--mint);
  border: 1px solid var(--line);
  color: var(--t1);
}
.modal .form-input:focus, .modal-box .form-input:focus { outline: 2px solid rgba(42,171,238,.3); border-color: var(--g); }
.modal .select-input, .modal-box .select-input {
  background: var(--mint);
  border: 1px solid var(--line);
  color: var(--t1);
}
.modal .select-input:focus, .modal-box .select-input:focus { outline: 2px solid rgba(42,171,238,.3); border-color: var(--g); }
.modal .error-msg {
  color: var(--bad);
  background: rgba(224,83,59,.07);
  border: 1px solid rgba(224,83,59,.15);
}
/* Плашка ошибок мастера привязки. Тексты здесь бывают двухчастными («Telegram не
   ответил за 20 с…» + «код мог всё же прийти»), и перевод строки в них смысловой —
   pre-line сохраняет его вместо склейки в одну простыню. */
#modal-error { white-space: pre-line; }

/* Cancel / ghost buttons inside modals */
.modal .btn-ghost, .modal-box .btn-ghost, .modal-box .btn-secondary {
  background: var(--mint);
  color: var(--t2);
  border: 1px solid var(--line);
}
.modal .btn-ghost:hover, .modal-box .btn-ghost:hover { background: var(--line); color: var(--t1); }

/* Toast — light elevated */
.app-toast {
  background: var(--card);
  color: var(--t1);
  border: 1px solid var(--line);
  box-shadow: 0 4px 24px rgba(10,15,22,.12);
}

/* ── TASK 7: Motion layer ─────────────────────────────────────────── */
@keyframes eg-fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}
.main-content:not(.hidden){animation:eg-fade .45s ease both}

/* ── TWEAK: sidebar nav line-icons (replace emoji) ───────────────── */
.nav-icon{width:20px;height:18px;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:0}
.nav-icon svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}

/* ── TWEAK: SVG icons for admin tabs / auth options ── */
.admin-tab svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;vertical-align:-3px;margin-right:7px}
.auth-opt-icon{font-size:0}
.auth-opt-icon svg{width:30px;height:30px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;color:var(--t2)}
.admin-stat-icon{font-size:0;margin-bottom:10px}
.admin-stat-icon svg{width:26px;height:26px;fill:none;stroke:var(--g);stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.bulk-bar__btn svg.bic{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;flex:none;margin:0}

/* ── TWEAK 2: topbar→dark shell, sidebar full-width, green→blue, toggles ── */
.shell-main{flex:1;display:flex;flex-direction:column;min-width:0}
.topbar-nav{background:transparent;border:none;padding:0 24px;position:static}
.topbar-nav .breadcrumb-parent{color:#7C857D}
.topbar-nav .breadcrumb-sep{color:#3a4250}
.topbar-nav .breadcrumb-current{color:#fff;font-weight:600}
.topbar-icon-btn{width:34px;height:34px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.09);color:#aab2c0;border-radius:10px}
.topbar-icon-btn:hover{background:rgba(255,255,255,.10);color:#fff}
.topbar-nav .ws-badge{color:#aab2c0}

.sidebar{padding:0 12px 18px}
.nav{padding:0;flex:0 1 auto;overflow-y:auto}
.nav-section{margin-bottom:14px}
.nav-section-label{margin:14px 8px 8px}
.sidebar-bottom{margin-top:auto;margin-left:-12px;margin-right:-12px;padding:18px 20px 22px;border-top:1px solid rgba(255,255,255,.08)}
.sidebar-user{border-top:none;margin-top:0;padding:0 0 2px}
.logout-btn{margin-top:18px}

.btn-primary{background:linear-gradient(135deg,var(--g),var(--g2));color:#fff;box-shadow:0 6px 16px -6px rgba(34,158,217,.5)}
.btn-primary:hover{background:linear-gradient(135deg,var(--g),var(--g2));filter:brightness(1.07);transform:none}

.btn-ghost,.btn-secondary{background:var(--ctl);color:var(--t2);border:1px solid var(--line)}
.btn-ghost:hover,.btn-secondary:hover{background:var(--ctl-h);color:var(--t1)}

.nc-pill.on,#page-dialogs .nc-pill.on{background:none;border:0;color:var(--t1)}
.nc-pill.on .d,#page-dialogs .nc-pill.on .d{background:#22c55e}
.nc-pill.off,#page-dialogs .nc-pill.off{background:none;border:0;color:var(--t3)}
.nc-pill.off .d,#page-dialogs .nc-pill.off .d{background:#c2c8cf}

/* ── UNIFIED DLG SHELL ───────────────────────────────────────────────
   3-zone layout (rail · list · detail) — Диалоги (#page-dialogs).
   Token-based; wins cascade over legacy .dlg-* rules.
─────────────────────────────────────────────────────────────────── */

/* Page wrapper — strips legacy padding so .zones fills the pane */
#page-dialogs {
  padding: 0;
  display: flex;
  flex-direction: column;
}

/* 3-zone row */
.zones {
  display: flex;
  flex: 1;
  min-height: 0;
  height: calc(100vh - 160px); /* matches proven .dlg-wrap offset */
  background: var(--sheet);
  overflow: hidden;
}

/* ── Zone ①: avatar rail ── */
.zones > .rail,
#page-dialogs .dlg-rail {
  width: 66px !important;
  background: var(--card) !important;
  border-right: 1px solid var(--line) !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  gap: 12px !important;
  padding: 16px 0 !important;
  overflow-y: auto;
  flex-shrink: 0;
}

/* Unified avatar tile */
.zones > .rail .av,
#page-dialogs .dlg-rail .av {
  width: 38px !important;
  height: 38px !important;
  border-radius: 12px !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  font-weight: 700 !important;
  font-size: 12px !important;
  cursor: pointer !important;
  position: relative !important;
  transition: box-shadow .15s !important;
  overflow: hidden;
  flex-shrink: 0;
  border: none !important;
  box-shadow: none !important;
  color: #fff !important;
}

/* Selected state — accent ring + left bar */
.zones > .rail .av.sel,
#page-dialogs .dlg-rail .av.on {
  box-shadow: 0 0 0 2px var(--g), 0 0 0 4px rgba(42,171,238,.18) !important;
}

/* ── Zone ②: middle list ── */
.zones > .list,
#page-dialogs .dlg-list {
  width: 340px !important;
  background: var(--card) !important;
  border-right: 1px solid var(--line) !important;
  display: flex !important;
  flex-direction: column !important;
  flex-shrink: 0;
  min-height: 0;
}

/* List header area */
.zones > .list .list-hd,
#page-dialogs .dlg-list-hd {
  padding: 12px 12px 10px !important;
  background: var(--card) !important;
  border-bottom: 1px solid var(--line) !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 8px !important;
}

/* Unified search input */
.zones > .list .u-search,
#page-dialogs .dlg-search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--sheet) !important;
  border: 1px solid var(--line) !important;
  border-radius: var(--r-ctl) !important;
  padding: 8px 11px !important;
  color: var(--t3) !important;
  font-size: 12.5px !important;
  width: 100%;
  box-sizing: border-box;
  font-family: var(--ff-body);
}
.zones > .list .u-search:focus,
#page-dialogs .dlg-search:focus {
  outline: 2px solid rgba(42,171,238,.25) !important;
  border-color: var(--g) !important;
}

/* Chip row (segment tabs). Этот блок сильнее старого `.dlg-seg{flex-wrap:
   nowrap;overflow-x:auto}` (~1106) из-за #page-dialogs в селекторе — раз он
   всё равно выигрывает каскад, прокрутка должна быть объявлена здесь, а не
   в перебиваемом легаси-правиле. Чипов стало девять (базовые + авто-папки +
   свои папки) — ряд должен ехать вбок одной строкой, а не переноситься. */
.zones > .list .u-chips,
#page-dialogs .dlg-seg {
  display: flex !important;
  gap: 6px !important;
  flex-wrap: nowrap !important;
  overflow-x: auto !important;
  scrollbar-width: none !important;
}
/* Fade-затухание справа — из утверждённого макета (docs/mockups/auto-folders.html,
   .fade::after): в список шириной 280px влезает 2-3 чипа, а три авто-папки стоят
   ПОСЛЕ четырёх фильтров — на первой отрисовке их не видно вовсе, и без намёка на
   прокрутку (нативный скроллбар скрыт строкой выше) владелец решит, что фичи нет.
   ВАЖНО: ::after ДОЛЖЕН висеть на .dlg-seg-fade — обёртке ВОКРУГ скроллящегося
   #dlg-seg (index.html), а не на самом #dlg-seg. Проверено снимками headless-
   браузера: абсолютно спозиционированный потомок ТОГО ЖЕ элемента, что имеет
   overflow-x:auto, уезжает вместе с прокручиваемым содержимым (после scrollLeft
   в конец фейд пропадает с экрана вместе с чипами) — контейнеру нужен отдельный
   НЕскроллящийся предок с position:relative, тогда ::after остаётся пришпилен к
   правому краю независимо от scrollLeft. pointer-events:none — иначе полоса из
   34px перехватывала бы клик по последнему видимому чипу под градиентом. */
#page-dialogs .dlg-seg-fade {
  position: relative;
}
#page-dialogs .dlg-seg-fade::after {
  content: '';
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 34px;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--sheet));
}
.zones > .list .u-chip,
#page-dialogs .dlg-seg span {
  font-size: 11.5px !important;
  font-weight: 600 !important;
  color: var(--t2) !important;
  background: var(--sheet) !important;
  border-radius: var(--r-ctl) !important;
  padding: 4px 10px !important;
  cursor: pointer !important;
  border: none !important;
  margin: 0 !important;
}
.zones > .list .u-chip.act,
#page-dialogs .dlg-seg span.act {
  background: var(--g) !important;
  color: #fff !important;
}

/* Чипы категорий в фильтр-баре */
#page-dialogs .dlg-cat-chip {
  font-size: 11.5px; font-weight: 600; color: var(--t2); background: var(--sheet);
  border-radius: var(--r-ctl); padding: 4px 10px; cursor: pointer; white-space: nowrap;
}
#page-dialogs .dlg-cat-chip:hover { background: var(--mint); color: var(--t1); }
#page-dialogs .dlg-cat-chip.act { background: var(--g); color: #fff; }
#page-dialogs .dlg-cat-chip .dlg-cat-cnt { opacity: .6; margin-left: 5px; font-variant-numeric: tabular-nums; }
#page-dialogs .dlg-cat-add {
  font-size: 12px; font-weight: 700; color: var(--g); background: transparent;
  border: 1px dashed rgba(42,171,238,.4); border-radius: var(--r-ctl); padding: 3px 9px; cursor: pointer;
}
#page-dialogs .dlg-cat-add:hover { background: var(--accent-soft); }

/* Селектор категорий в панели чата */
.dlg-catsel { display: flex; flex-wrap: wrap; gap: 6px; }
.dlg-catsel-tog {
  font-size: 11px; font-weight: 600; padding: 5px 11px; border-radius: 999px; cursor: pointer;
  border: 1px solid var(--line); background: var(--sheet); color: var(--t2); transition: background-color .13s, border-color .13s, color .13s, box-shadow .13s, transform .13s;
}
.dlg-catsel-tog:hover { border-color: rgba(42,171,238,.5); color: var(--t1); }
.dlg-catsel-tog.on { background: var(--green-dim); border-color: var(--g); color: var(--g); }
.dlg-catsel-tog.add { border-style: dashed; color: var(--g); border-color: rgba(42,171,238,.45); background: transparent; }

/* Контекст-меню управления категорией */
.dlg-ctxmenu {
  position: fixed; z-index: 1000; background: var(--card); border: 1px solid var(--line);
  border-radius: 11px; padding: 5px; min-width: 178px; box-shadow: var(--shadow-pop);
}
.dlg-ctxmenu button {
  width: 100%; text-align: left; background: none; border: none; color: var(--t1);
  font-family: inherit; font-size: 12.5px; padding: 8px 10px; border-radius: 8px; cursor: pointer;
}
.dlg-ctxmenu button:hover { background: var(--mint); }
.dlg-ctxmenu button.danger { color: var(--bad); }
.dlg-ctxmenu button.danger:hover { background: rgba(224,83,59,.1); }

/* Scrollable rows area */
.zones > .list .u-rows,
#page-dialogs .dlg-chats {
  flex: 1 !important;
  overflow-y: auto !important;
  padding: 4px 6px !important;
}

/* Chat/channel row */
#page-dialogs .dlg-ch {
  border-radius: 10px !important;
  border-bottom: none !important;
  margin-bottom: 2px !important;
  padding: 9px 10px !important;
}
#page-dialogs .dlg-ch:hover {
  background: var(--sheet) !important;
  border-radius: 0 !important;
  margin-left: -6px !important;
  margin-right: -6px !important;
  padding: 9px 16px !important;
}
#page-dialogs .dlg-ch.sel {
  background: rgba(42,171,238,.08) !important;
  border-left: none !important;
  box-shadow: inset 3px 0 0 var(--g) !important;
  /* full-bleed выделение: гасим паддинг контейнера (6px) отрицательным margin,
     компенсируем паддингом — контент не сдвигается, фон на всю ширину, без скруглений */
  border-radius: 0 !important;
  margin-left: -6px !important;
  margin-right: -6px !important;
  padding: 9px 16px !important;
}

/* ── Zone ③: detail ── */
.zones > .detail,
#page-dialogs .dlg-conv {
  flex: 1 !important;
  display: flex !important;
  flex-direction: column !important;
  background: var(--sheet) !important;
  min-width: 0;
  min-height: 0;
}

/* Unified detail header */
#page-dialogs .dlg-chd {
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  padding: 14px 20px !important;
  background: var(--card) !important;
  border-bottom: 1px solid var(--line) !important;
  flex-shrink: 0;
}

/* Override legacy dlg-chd inside dialogs */
#page-dialogs .dlg-chd {
  padding: 14px 20px !important;
}
#page-dialogs .dlg-chd b { color: var(--t1) !important; }
#page-dialogs .dlg-chd small { color: var(--t2) !important; }
#page-dialogs .dlg-chd .lbl { color: var(--t3) !important; }

/* Scrollable detail body */

/* Pinned bottom bar */
#page-dialogs .dlg-comp {
  padding: 12px 20px !important;
  background: var(--card) !important;
  border-top: 1px solid var(--line) !important;
  display: flex !important;
  align-items: center !important;
  gap: 10px !important;
  flex-shrink: 0;
}
#page-dialogs .dlg-comp input {
  background: var(--sheet) !important;
  border: 1px solid var(--line) !important;
  color: var(--t1) !important;
  border-radius: var(--r-ctl) !important;
}
#page-dialogs .dlg-comp button {
  background: linear-gradient(135deg,var(--g),var(--g2)) !important;
  color: #fff !important; border-radius: var(--r-ctl) !important;
}

/* ── Unified status pill ── */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 11px; font-weight: 600;
  padding: 3px 9px; border-radius: 20px; white-space: nowrap;
  border: 1px solid transparent;
}
.pill .d { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.pill.on  { background: rgba(34,197,94,.12);  color: #15803D; border-color: rgba(34,197,94,.3); }
.pill.off { background: var(--sheet); color: var(--t3); border-color: var(--line); }
.pill.warn { background: rgba(235,177,74,.12); color: #9A7B2E; border-color: rgba(235,177,74,.3); }

/* Map nc-pill to pill styles inside unified zones */
.zones .nc-pill.on  { background: none !important; border: 0 !important; color: var(--t1) !important; }
.zones .nc-pill.on .d  { background: #22c55e !important; }
.zones .nc-pill.off { background: none !important; border: 0 !important; color: var(--t3) !important; }
.zones .nc-pill.off .d { background: #c2c8cf !important; }


/* ── END UNIFIED COMM/DLG SHELL ─────────────────────────────────── */


/* ── TWEAK: comm/dlg zones fill container height (robust, no viewport math) ── */
#page-dialogs {height:100%}
.zones{height:100%}
#page-dialogs .dlg-wrap{height:100%}

/* ── DARK THEME (Graphite) — token override; semantic accent/status unchanged ── */
[data-theme="dark"]{
  /* OLED «Neon Ledger» — ЕДИНАЯ палитра концепта для ВСЕХ страниц. Концепт-имена
     (--black, --raise-…, --text-…, --accent) и легаси-семейство (--bg-…, --card,
     --sheet, --t1..t3) заданы ВМЕСТЕ и одними значениями → каждая страница
     наследует концепт без локальных переопределений. Значения = .ndash.
     Светлая :root не тронута.
     ВНИМАНИЕ: не писать «звёздочка-слеш» подряд — комментарий закроется досрочно,
     и парсер съест следующее объявление. Тут так терялся --black (шапка в тёмной
     теме оставалась прозрачной). Пинится css-comment-integrity.test.js. */
  /* концепт-имена (канон) */
  --black:#0a0a0c; --raise-1:#131316; --raise-2:#1a1a1e; --raise-3:#212126;
  --line-soft:#1c1c20;
  --text:#f5f5f5; --text-2:#a8a8ad; --text-3:#6c6c72;
  --accent:#2aabee; --accent-dim:#1d7fb3; --accent-glow:rgba(42,171,238,.20); --accent-soft:rgba(42,171,238,.08);
  /* легаси-семейство → мапится на концепт (те же значения) */
  --bg:#0a0a0c; --bg-sidebar:#0a0a0c; --bg-input:#0a0a0c;
  --bg-card:#131316; --bg-hover:#1a1a1e; --border:#232327;
  --sheet:#0a0a0c;
  --card:#131316;
  --mint:#1a1a1e;
  --line:#232327;
  --t1:#f5f5f5;
  --t2:#a8a8ad;
  --t3:#6c6c72;
  --bar:#1a1a1e;
  --ctl:#131316; --ctl-h:#1a1a1e; --mint-bd:rgba(42,171,238,.16);
  --skel-base:#131316; --skel-sheen:rgba(255,255,255,.05);
  --scroll-thumb:#232327; --scroll-thumb-hover:#2e2e33;
}

/* Канвас ВСЕХ страниц в тёмной теме = чёрный концепта + два еле заметных голубых
   радиала (как на дашборде и в нейрочате). Единый источник — фон не дублируется
   по страницам, поэтому все экраны совпадают «из коробки». */
[data-theme="dark"] .main{
  background:
    radial-gradient(1200px 600px at 78% -8%, rgba(42,171,238,.03), transparent 60%),
    radial-gradient(900px 500px at 0% 100%, rgba(42,171,238,.018), transparent 55%),
    #0a0a0c;
  /* хедер сверху во всю ширину → скруглённые углы «листа» лишние, убираем */
  border-radius: 0;
  box-shadow: none;
}

/* ── SETTINGS page / segmented control ── */
.settings-wrap{padding:4px 0}
/* настройки — две колонки: широкая левая (формы + интеграции) и узкая правая
   «шапка аккаунта», закреплённая при скролле (sticky). Ниже 880px — одна
   колонка, рейл уезжает наверх. */
.set-grid{display:grid;grid-template-columns:1.7fr .9fr;gap:18px;align-items:start;max-width:920px;margin:0 auto}
.set-col{display:flex;flex-direction:column;gap:14px;min-width:0}
.set-col--rail{position:sticky;top:18px;align-self:start}
.set-grouplbl{font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--t3);margin:2px 2px -2px}
.set-col--main .set-grouplbl:not(:first-child){margin-top:12px}
.set-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-card);padding:22px 24px}
/* hero-карточка кабинета (.set-card--hero и .set-hero__*) снята 22.08.2026 вместе
   с разметкой: сумма за всё время и имя владельца стоят в шапке приложения. */
@media (max-width:880px){
  .set-grid{grid-template-columns:1fr;max-width:560px}
  /* order:-1 поднимал рейл ради hero-карточки «Обзор», снятой 22.08.2026. Без неё
     первым экраном телефона шёл «Вход через Telegram», к которому приходят раз в
     жизни. Порядок теперь тот же, что на десктопе: бот, склад, уведомления, вход. */
  .set-col--rail{position:static}
}
.set-card__title{font-family:var(--ff-head);font-size:17px;font-weight:600;color:var(--t1);letter-spacing:-.014em}
.set-card__sub{font-size:12px;color:var(--t2);margin:4px 0 16px;line-height:1.5}
.set-steps{margin:8px 0;padding-left:18px;font-size:13px;line-height:1.5}
.set-warn{margin:8px 0;font-size:12px;color:var(--t2)}
/* margin-top 14px, а не 12: сверху ряд кнопок почти всегда стоит за .set-field,
   у которого в скине .ndash margin-bottom:12px (style.css ниже), и отступы
   схлопываются в больший. 12 сюда не давало НИ ОДНОГО пикселя. */
.set-btnrow{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:14px}
/* сворачиваемая инструкция (напр. «как подключить бота») — чтобы карточка не была текстовой стеной */
.set-details{margin:0 0 14px;border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--sheet)}
/* Инструкция «Как подключить бота» у подключённого бота стоит последней: её 14px
   снизу давали 36px мёртвого низа против 22px сверху, а сверху она липла к ряду
   кнопок (пустой .set-msg между ними схлопнут). Отступ переезжает вверх. */
.set-card > .set-details:last-child{margin:14px 0 0}
.set-details>summary{list-style:none;cursor:pointer;padding:10px 14px;font-size:13px;color:var(--t1);display:flex;align-items:center;gap:8px;user-select:none}
.set-details>summary::-webkit-details-marker{display:none}
.set-details>summary::before{content:"";width:6px;height:6px;border-right:1.5px solid var(--t2);border-bottom:1.5px solid var(--t2);transform:rotate(-45deg);transition:transform 160ms ease-out;flex:none}
.set-details[open]>summary::before{transform:rotate(45deg)}
.set-details__body{padding:2px 14px 12px;font-size:12px;color:var(--t2);line-height:1.55}
.set-details__body ol{margin:4px 0;padding-left:18px}
.set-details__body li{margin:4px 0}
/* акцентная плашка-предупреждение */
.set-callout{display:flex;gap:8px;align-items:flex-start;margin:0 0 14px;padding:10px 12px;border-radius:var(--r-ctl);font-size:12px;line-height:1.5;
  background:color-mix(in srgb,#e0a93a 14%,transparent);border:1px solid color-mix(in srgb,#e0a93a 38%,transparent);color:var(--t1)}
.set-callout .ico{flex:none}
/* строка-статус с цветной точкой (подключён / привязано) */
.set-status{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--t1);margin:0 0 8px}
.set-status .dot{width:8px;height:8px;border-radius:50%;flex:none;background:var(--t2)}
.set-status.ok .dot{background:var(--online,#2e9e5b)}
.set-status.off .dot{background:var(--t2)}
.set-status strong{font-weight:600}
/* прогресс перезалива контента в dropp при смене Partner API-ключа (карточка dropp.fans) */
.dropp-progress{margin:8px 0}
.dropp-progress__label{font-size:13px;color:var(--t2);margin-bottom:4px}
.dropp-progress__bar{height:6px;border-radius:999px;background:var(--line);overflow:hidden}
.dropp-progress__fill{height:100%;width:0;background:var(--g,#2AABEE);transition:width .3s ease}
.seg{display:inline-flex;background:var(--sheet);border:1px solid var(--line);border-radius:var(--r-ctl);padding:3px;gap:3px}
.seg-btn{font:inherit;font-size:13px;color:var(--t2);background:transparent;border:0;padding:7px 16px;border-radius:calc(var(--r-ctl) - 3px);cursor:pointer}
.seg-btn:hover{color:var(--t1)}

/* ── Task 4: per-chat management panel (4th column) ── */
/* Override the column direction set by #page-dialogs .dlg-conv (specificity 1,1,0 + !important) */
/* using higher-specificity #page-dialogs #dlg-conv (2,0,0) + !important */
#page-dialogs #dlg-conv {
  flex-direction: row !important;
  align-items: stretch;
  min-height: 0;
}
.dlg-convmain {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  position: relative; /* якорь для кнопки «вниз» (.dlg-jump) */
}
.dlg-panel {
  width: 360px;
  flex: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  overflow-y: auto;
  border-left: 1px solid var(--line);
  background: var(--card);
}

.dlg-panel-h { font-weight: 600; color: var(--t1); }
.dlg-pn-row { display: flex; justify-content: space-between; align-items: center; }
/* Лейблы/поля панели — язык полей концепта (.field label + .field .ctl):
   обычный регистр 12px text-3, поля круглее (10px), просторнее, шрифт 13px. */
.dlg-pn-lbl { font-size: 12px; letter-spacing: 0; opacity: 1; color: var(--text-3); margin-bottom: 2px; }
.dlg-pn-input, .dlg-pn-note {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 13px;
  padding: 9px 12px; border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--sheet); color: var(--t1);
}
.dlg-pn-note { height: 90px; min-height: 90px; flex-shrink: 0; resize: vertical; }
/* Список сцен per-chat в панели диалога (пин + показ/скрытие). Тумблер видимости —
   реюз .nc-pill on/off. Новое здесь: строка/акцент пина/приглушение скрытой. */
/* flex:none ОБЯЗАТЕЛЬНО: .dlg-panel = flex-колонка, а flex-item с overflow:hidden
   получает min-height:0 → без flex:none список сжимался в 0 высоты и строки (в DOM!)
   обрезались overflow'ом = невидимы. Классическая гоча флексбокса. */
.scn-list{flex:none;display:flex;flex-direction:column;border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--card);margin-top:4px}
.scn-row{display:flex;align-items:center;gap:10px;padding:10px 12px;border-bottom:1px solid var(--line);border-left:2px solid transparent}
.scn-row:last-child{border-bottom:0}
.scn-row .scn-nm{flex:1;font-size:13px;color:var(--t1);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.scn-row.pinned{background:var(--accent-soft);border-left-color:var(--accent)}
.scn-pin{font-size:11px;font-weight:600;color:var(--t3);cursor:pointer;white-space:nowrap;letter-spacing:.2px}
.scn-pin:hover{color:var(--accent)}
.scn-pin.active{color:var(--accent);cursor:default}
/* Скрытая сцена: имя гаснет, а причину говорит подпись на втором этаже.
   Перечёркивание было костылём при отсутствии подписи и читалось как поломка. */
.scn-row.is-hidden .scn-nm{color:var(--t3)}
.nc-pill.locked{cursor:default;opacity:.4}
.scn-off{font-size:10px;font-weight:600;color:var(--t3);white-space:nowrap;letter-spacing:.4px;text-transform:uppercase;opacity:.75}
/* Двухэтажная строка сцены: имя сверху, состояние снизу. На телефоне подсказки при
   наведении нет, поэтому состояние написано текстом, а не спрятано в title. */
.scn-row.two{align-items:flex-start;padding:9px 12px 10px}
/* Растяжение задано ЛЮБОЙ строке, не только двухэтажной: иначе у строки без подписи
   тумблер прилипает к тексту вместо правого края. */
.scn-row .scn-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.scn-row.two .nc-pill{margin-top:1px}
.scn-sub{font-size:11px;line-height:1.35;color:var(--t3);white-space:normal;overflow-wrap:anywhere}
.scn-sub.act{color:var(--accent);font-weight:600;cursor:pointer}
.scn-sub.act:hover{color:var(--accent-dim)}
.scn-sub.live{color:var(--accent);font-weight:600}
/* Задача владельцу: янтарный, а не красный. Ничего не сломано, просто не настроено. */
.scn-sub.task{color:#e8a33d;cursor:pointer}
.scn-sub.task .do{font-weight:600;white-space:nowrap}
.scn-sub.task:hover .do{text-decoration:underline}

/* Полоса над списком сцен: канал оплаты общий для чата, поэтому причина одна, а не
   в каждой строке. Тон янтарный: ничего не сломано, просто не подключено. */
.scn-note{
  --nt:#e8a33d;
  display:flex;align-items:center;gap:10px;margin:6px 0 4px;
  padding:9px 10px 9px 11px;border-radius:10px;
  background:rgba(232,163,61,.07);font-size:11px;line-height:1.4;
}
.scn-note-txt{color:var(--nt);flex:1;min-width:0}
.scn-note-ic{
  flex:none;width:17px;height:17px;border-radius:50%;display:grid;place-items:center;
  background:rgba(232,163,61,.16);color:var(--nt);
}
/* Кнопка стоит на системном .btn, свой у неё только тон (образец — .btn-danger).
   transition у .btn задан как «.2s», то есть all: переопределяем на конкретные
   свойства, чтобы не гонять лишнего. */
.btn-warn{
  background:rgba(232,163,61,.12);color:#e8a33d;border:1px solid rgba(232,163,61,.32);
  transition:background 160ms ease,transform 160ms cubic-bezier(.23,1,.32,1);flex:none;
}
.btn-warn-sm{height:30px;padding:0 12px;font-size:12px;border-radius:9px}
.btn-warn:active{transform:scale(.97)}
.btn-arr{transition:transform 160ms cubic-bezier(.23,1,.32,1)}
@media (hover:hover) and (pointer:fine){
  .btn-warn:hover{background:rgba(232,163,61,.2)}
  .btn-warn:hover .btn-arr{transform:translateX(2px)}
}
/* нативный select рендерится ниже текст-инпутов и с чужой стрелкой ⇕ —
   снимаем appearance, чтобы высота совпала с .dlg-pn-input, и рисуем свой шеврон */
select.dlg-pn-input {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  line-height: 1.4; cursor: pointer;
  padding-right: 28px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%235E6A60' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
}
.dlg-pn-status { font-size: 10px; min-height: 12px; opacity: .7; color: var(--t2); }
.dlg-pn-info {
  font-size: 11px; opacity: .7; display: flex; flex-direction: column; gap: 4px;
  border-top: 1px solid var(--line); padding-top: 10px; color: var(--t2);
}
.dlg-pn-info > div { display: flex; justify-content: space-between; gap: 8px; }
.dlg-pn-id { display: flex; align-items: center; gap: 10px; }
.dlg-pn-id .cav { width: 44px; height: 44px; flex: none; border-radius: 50%; overflow: hidden; position: relative; display: flex; align-items: center; justify-content: center; background: var(--mint); color: var(--t2); font-weight: 600; font-size: 16px; }
.dlg-pn-id .cav img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.dlg-pn-idtext { min-width: 0; flex: 1; }
.dlg-pn-name { font-weight: 600; display: flex; align-items: center; gap: 6px; min-width: 0; }
.dlg-pn-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.dlg-pn-info-btn {
  flex: none; width: 18px; height: 18px; border-radius: 50%;
  background: transparent; border: 1px solid currentColor;
  color: var(--t2, #8b949e); opacity: .55;
  font-size: 11px; font-weight: 600; font-style: italic; font-family: Georgia, serif;
  line-height: 16px; padding: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.dlg-pn-info-btn:hover { opacity: 1; }
.dlg-pn-sub { font-size: 11px; opacity: .6; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.seg-btn.on{background:var(--card);color:var(--t1);box-shadow:0 1px 3px rgba(0,0,0,.12)}

/* ── Sheet default text color: themed primary (was inheriting legacy near-white --text) ── */
.main{color:var(--t1)}

/* ── Personal cabinet (Settings page) ── */
.set-field { display:flex; flex-direction:column; gap:4px; margin:10px 0; max-width:360px; }

/* Подпись под полем настройки. Отдельный класс, а не .cell-sub: тот внутри .ndash
   однострочный (white-space:nowrap + ellipsis) и такой текст обрезает на первой
   строке. Отрицательный верхний отступ подтягивает подпись к своему полю, иначе она
   читается как заголовок следующего. */
.set-note { color: var(--t2); font-size: 12px; line-height: 1.45; margin: -4px 0 10px; max-width:360px; }
.set-field span { font-size:12px; color:var(--t2); }
.set-field input { padding:9px 12px; border:1px solid var(--line); border-radius:var(--r-ctl);
  background:var(--card); color:var(--t1); font-size:14px; }
.set-field { max-width:none; }
.set-field input:disabled { opacity:.6; }
.set-msg { display:inline-block; margin-left:10px; font-size:13px; }
/* Пустой inline-block держит строку в 21px ровно на стыке «кнопки / следующий
   блок» — а пуст он в 99% визитов. */
.set-msg:empty { display:none; }
/* Слот ссылки привязки склада: пока ссылки нет, узла на экране быть не должно. */
#cab-bot-storage-link:empty { display:none; }
#cab-bot-storage-link { margin-top:6px; }
.set-msg.ok { color:#2e9e5b; }
.set-msg.err { color:#d4504e; }

/* ── Карточка подключения провайдера оплаты в редакторе персонажа (dropp / Fanvue) ──
   Переиспользует .set-status / .set-field / .btn; акцент — платформенный синий --accent. */
.pay-card { border:1px solid var(--line); border-radius:12px; background:var(--mint); padding:15px 16px; }
.pay-card__t { font-size:11px; font-weight:700; letter-spacing:.05em; text-transform:uppercase; color:var(--t3); margin:0 0 12px; }
.pay-card .set-status { font-size:14.5px; margin:6px 0; }
.pay-card .set-field { margin:12px 0 0; }
.pay-card__note { font-size:12.5px; color:var(--t3); margin:10px 0 0; line-height:1.5; }
.pay-card__readbox { background:var(--bg-input); border:1px solid var(--line); border-radius:8px; padding:11px 13px;
  font-size:14px; font-weight:600; color:var(--t1); display:flex; align-items:center; justify-content:space-between; gap:10px; margin-top:12px; }
.pay-card__readbox .ro { font-size:11px; font-weight:600; color:var(--t3); }
.pay-card__row { display:flex; gap:9px; flex-wrap:wrap; align-items:center; margin-top:14px; }
.pay-card__row .sp { flex:1; }
.pay-card__reup { margin-top:12px; font-size:12.5px; color:var(--t3); }
.pay-card__reup a { color:var(--t2); border-bottom:1px dashed #3a3a42; padding-bottom:1px; cursor:pointer; text-decoration:none; }
.pay-card__reup a:hover { color:var(--t1); }
/* Свёртка с ручным ключом (2026-08-25). Ключ остаётся дорогой для агентств и
   запасным ходом, если согласие сорвалось, но новый владелец видит одну кнопку. */
.pay-card__fold { margin-top:14px; }
.pay-card__fold > summary { cursor:pointer; list-style:none; font-size:12.5px; color:var(--t3);
  border-bottom:1px dashed #3a3a42; display:inline-block; padding-bottom:1px; }
.pay-card__fold > summary::-webkit-details-marker { display:none; }
.pay-card__fold > summary:hover { color:var(--t2); }
.pay-card__fold[open] > summary { color:var(--t2); margin-bottom:4px; }
.pay-card__ref { margin-top:15px; padding-top:13px; border-top:1px solid var(--line); font-size:12.5px; color:var(--t3); }
.pay-card__ref a { color:var(--t2); text-decoration:none; font-weight:600; }
.pay-card__ref a .arw { color:var(--accent); }
.pay-card__ref a:hover { color:var(--t1); }

/* Выбор провайдера карты — РАДИО-КАРТОЧКИ (не сегмент-«вкладки»): точка-радио +
   акцентная рамка/заливка на выбранной = однозначный «выбери один», а не переключение вида. */
.pay-rcards { display:grid; grid-template-columns:repeat(auto-fit, minmax(190px, 1fr)); gap:10px; }
.pay-rcard { display:flex; align-items:center; gap:12px; padding:14px 15px; border:1.5px solid var(--line);
  border-radius:12px; background:var(--sheet); cursor:pointer; transition:border-color .15s, background .15s; }
.pay-rcard:hover { border-color:#3a3a42; }
.pay-rcard.on { border-color:var(--accent); background:var(--accent-soft); }
.pay-rdot { width:18px; height:18px; border-radius:50%; border:2px solid var(--t3); flex:none; position:relative; transition:border-color .15s; }
.pay-rcard.on .pay-rdot { border-color:var(--accent); }
.pay-rcard.on .pay-rdot::after { content:""; position:absolute; inset:3px; border-radius:50%; background:var(--accent); }
/* Марка провайдера — опознавательный знак, НЕ элемент управления: выбор по-прежнему
   показывает радио-точка слева. На невыбранной карточке приглушаем, иначе фирменный
   цвет перетягивает внимание на неактивный вариант. */
.pay-rcard .pay-rc-logo { width:30px; height:30px; border-radius:8px; flex:none;
  opacity:.55; filter:saturate(.7); transition:opacity .15s, filter .15s; }
.pay-rcard.on .pay-rc-logo { opacity:1; filter:none; }
/* Легаси fiat_only: Stars реально выключены и кружки перестали предлагаться.
   Единственное состояние, где про Stars вообще есть что сказать — в норме этой
   строки на экране нет. */
.pay-stars-fact { display:flex; align-items:center; gap:9px; font-size:13px;
  padding:11px 13px; border-radius:11px; color:#e7bd76;
  border:1px solid rgba(217,155,63,.32); background:rgba(217,155,63,.07); }
.pay-stars-fact .dot { width:7px; height:7px; border-radius:50%; background:#d99b3f; flex:none; }
.pay-rc-name { font-weight:650; font-size:14.5px; color:var(--t1); }
.pay-rcard.on .pay-rc-name { color:#fff; }
.pay-rc-sub { color:var(--t3); font-size:11.5px; margin-top:1px; }
/* Метка «бета» у Stacked: провайдер подключён третьим и работает меньше суток,
   владелец просил пометить его на плитке выбора. Чип нарочно тихий (тот же приём,
   что у .status-pill--sleeping): он не должен спорить с названием провайдера. */
.pay-rc-beta { display:inline-block; margin-left:6px; padding:1px 6px; border-radius:20px;
  font-size:9.5px; font-weight:700; line-height:1.5; vertical-align:middle;
  letter-spacing:.05em; color:#fbbf24; background:rgba(251,191,36,.14); }
@media (max-width:520px){ .pay-rcards { grid-template-columns:1fr; } }
.cab-balance { font-size:28px; font-weight:600; color:var(--t1); margin:6px 0 14px; }
.cab-balance.is-zero { color:var(--t2); }
.cab-hist { width:100%; border-collapse:collapse; font-size:13px; }
.cab-hist th, .cab-hist td { text-align:left; padding:6px 8px; border-bottom:1px solid var(--line); }
.cab-hist td.pos { color:#2e9e5b; }
.cab-hist td.neg { color:#d4504e; }

/* ── DARK THEME: status pills ──────────────────────────────────────────
   Base pills (lines 1274-1277/1990/2330-2342) use hard-coded light colors
   (#EAF6EE / #F1F3F1) that read as pale blobs on the dark sheet. Re-tint
   them with translucent fills + brighter text for dark mode. */
[data-theme="dark"] .status-pill--active{
  background:rgba(74,222,128,.13);color:#5cd98a;
  box-shadow:inset 0 0 0 1px rgba(74,222,128,.22)}
[data-theme="dark"] .status-pill--sleeping{
  background:rgba(251,191,36,.13);color:#f1c14b;
  box-shadow:inset 0 0 0 1px rgba(251,191,36,.22)}
[data-theme="dark"] .status-pill--disconnected {
  background:rgba(255,255,255,.05);color:#8b93a3;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.07)}
/* gated: модуль включён, но аккаунт спит — приглушённый зелёный,
   читается «вкл, но сейчас не работает», отличим от серого «Выключено» */
[data-theme="dark"] .status-pill--paused{
  background:rgba(74,222,128,.10);color:#7fcf9c;
  box-shadow:inset 0 0 0 1px rgba(74,222,128,.16);opacity:.7}

/* ── MEDIA VAULT ───────────────────────────────────────────────────────── */
.mv-toolbar { display:flex; align-items:flex-end; gap:14px; }

.mv-upload-card { padding: 20px; }
.mv-upload-row {  /* legacy: используется только в disabled-плейсхолдере */
  display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end;
}

.mv-up-head { margin-bottom: 14px; }
.mv-up-title { font-size: 15px; font-weight: 650; color: var(--t1); letter-spacing: -.01em; }
.mv-up-sub { font-size: 12.5px; color: var(--t2); margin-top: 3px; }

/* Дропзона */
.mv-dropzone {
  display: block; cursor: pointer;
  border: 1.5px dashed var(--border); border-radius: 14px;
  background: rgba(255,255,255,.02);
  padding: 22px 18px; margin-bottom: 16px; text-align: center;
  transition: border-color .15s ease, background .15s ease;
}
.mv-dropzone:hover { border-color: rgba(42,171,238,.5); background: rgba(42,171,238,.04); }
.mv-dropzone.mv-dz-over { border-color: var(--g); background: rgba(42,171,238,.1); }

.mv-dz-idle { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.mv-dz-icon {
  width: 42px; height: 42px; display: grid; place-items: center; margin-bottom: 2px;
  border-radius: 50%; background: rgba(42,171,238,.12); color: var(--g);
}
.mv-dz-icon svg { width: 20px; height: 20px; }
.mv-dz-text { font-size: 14px; color: var(--t1); }
.mv-dz-link { color: var(--g); font-weight: 600; }
.mv-dz-hint { font-size: 12px; color: var(--t2); }

.mv-dz-grid { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.mv-dz-tile {
  width: 58px; height: 58px; border-radius: 9px; overflow: hidden;
  background: var(--bg-input); border: 1px solid var(--border);
  display: grid; place-items: center; font-size: 22px;
}
.mv-dz-tile img { width: 100%; height: 100%; object-fit: cover; }
.mv-dz-tile-vid { color: var(--t2); }
.mv-dz-more { font-size: 15px; font-weight: 600; color: var(--t2); }
.mv-dz-summary { margin-top: 11px; font-size: 13px; color: var(--t2); }

/* Ряд контролов */
.mv-up-controls { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.mv-up-field { display: flex; flex-direction: column; gap: 6px; min-width: 130px; }
.mv-up-field .field-label { margin: 0; }
.mv-up-submit { margin-left: auto; align-self: flex-end; height: 42px; padding: 0 24px; }
@media (max-width: 760px) {
  .mv-up-field { min-width: 0; flex: 1 1 calc(50% - 6px); }
  .mv-up-submit { margin-left: 0; flex: 1 1 100%; }
}

/* Card grid */
.mv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 14px;
}

.mv-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform .15s, box-shadow .15s;
}
.mv-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 30px -18px rgba(34,158,217,.25);
}
.mv-card[hidden] { display: none !important; }
/* Несортированную карточку можно тащить на плитку сцены — курсор-захват как аффорданс. */
.mv-card[draggable="true"] { cursor: grab; }
.mv-card[draggable="true"]:active { cursor: grabbing; }
/* Drag-reorder «Несортированного» (_mvInitUnsortedDragDrop) — тот же язык, что
   у .scn-card-over реордера сцен/лесенки. */
.mv-card.mv-card-over {
  border-color: var(--g);
  box-shadow: 0 0 0 2px rgba(42,171,238,.25);
}

.mv-preview {
  background: var(--mint, #e7f4fb);
  aspect-ratio: 1 / 1;
  display: flex; align-items: center; justify-content: center;
  overflow: hidden; position: relative;
}
.mv-preview-loading {
  color: var(--t3); font-size: 20px;
}
.mv-preview-err {
  color: var(--bad, #E0533B); font-size: 22px;
}
.mv-preview-media {
  width: 100%; height: 100%; object-fit: cover; display: block;
  cursor: pointer;
  /* Иначе нативный drag <img>/<video> перехватывает драг карточки — reorder в
     «Несортированном» не срабатывает (карточка draggable, но тащится картинка). */
  -webkit-user-drag: none; user-drag: none; user-select: none;
}
video.mv-preview-media { background: #000; }
/* ▶ поверх thumb-кадра bot-видео: сигнал, что превью кликабельно (откроет видео). */
.mv-play-badge {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, 0.5); color: #fff; font-size: 18px;
  padding-left: 3px; pointer-events: none; z-index: 1;
}

/* Несортированное = инбокс: бейджи-оверлеи убраны (не actionable вне сцены,
   накал всегда дефолт). Бейджи живут в лесенке сцены. */
.mv-thumb-wrap { position: relative; }

.mv-card-body { padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }

/* «Удалить» — тихое вторичное действие: акцентный селект «в сцену» должен вести.
   Без рамки, приглушённый текст; деструктивный красный проявляется на hover. */
.mv-del-btn {
  width: 100%; padding: 6px 10px; font-size: 11px; font-weight: 500;
  border: none; border-radius: var(--r-ctl); cursor: pointer;
  background: transparent; color: var(--t3);
  transition: background-color .15s ease-out, color .15s ease-out, transform .15s ease-out;
}
.mv-del-btn:hover { color: #f87171; background: rgba(248,113,113,.08); }
.mv-del-btn:active { transform: scale(.98); }

/* Карточка пака в «Несортированном» (после нарезки крупного медиа) — реюз
   попапа пак-плашки лесенки сцены (.scn-pk-coverwrap/.scn-pk-cover/
   .scn-pk-cover-badge/.scn-pk-strip, pkTogglePhotos): та же разметка, но
   обложка растянута под сетку .mv-grid, а не фиксированные 56px ладдера, и
   попап должен уметь вылезти за пределы карточки (overflow:visible + z-index
   на открытом состоянии, иначе соседние карточки грида его обрежут/перекроют). */
.mv-pack-card { overflow: visible; }
.mv-pack-card .mv-thumb-wrap { overflow: visible; }
.mv-pack-card .scn-pk-coverwrap { display: block; width: 100%; }
.mv-pack-card .scn-pk-cover {
  width: 100%; height: auto; aspect-ratio: 1 / 1;
  border-radius: 0; border: none;
}
.mv-pack-card .scn-pk-cover-badge { right: 8px; bottom: 8px; }
.mv-pack-card:has(.scn-pk-coverwrap.pop-open) { z-index: 5; }
.mv-pack-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.mv-pack-title { font-size: 12px; font-weight: 600; color: var(--t2); }
.mv-pack-price { font-size: 12px; font-weight: 600; color: var(--t3); }
.mv-pack-price.paid { color: var(--g); }

/* Dark theme overrides */
[data-theme="dark"] .mv-preview { background: var(--bg-hover, #222); }
[data-theme="dark"] .mv-card    { background: var(--bg-card, #1c1c1c); border-color: var(--border); }
/* ── End Media Vault ───────────────────────────────────────────────────── */

/* chip-input component (Phase 3-A) */
.chip-input-row { display: flex; gap: 8px; align-items: center; margin-top: 6px; }
.chip-input-row .chip-text { flex: 1; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; min-height: 28px; }
.chips:empty { display: none; }
.chip { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-ctl);
        padding: 4px 10px; display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.chip-remove { background: none; border: none; color: var(--text-2); cursor: pointer;
        font-size: 16px; line-height: 1; padding: 0; }
.chip-remove:hover { color: var(--red); }
.chip-bank-popup { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px;
        padding: 12px; background: var(--bg); border: 1px dashed var(--border); border-radius: var(--r-card); }
.chip-bank-popup::before {
  content: 'из банка — клик чтобы добавить';
  width: 100%; display: block;
  font-size: 11px; font-weight: 600;
  letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 4px;
}
.chip-bank-option { background: transparent; border: 1px dashed var(--border); border-radius: var(--r-ctl);
        padding: 4px 10px; cursor: pointer; font-size: 13px; color: var(--text-2); }
.chip-bank-option::before { content: '+ '; opacity: 0.5; }
.chip-bank-option:hover { background: var(--green-dim); color: var(--text);
        border-style: solid; border-color: var(--green); }
.chip-bank-option:hover::before { opacity: 1; }

.section-title {
  margin: 24px 0 10px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-2);
  border-top: 1px solid var(--border);
  padding-top: 16px;
}

/* Phase 3-A: Behavioral Tone cards */
.voice-rule-grid { display: flex; flex-direction: column; gap: 6px;
                   background: var(--bg-card); border: 1px solid var(--border);
                   border-radius: var(--r-card); padding: 10px; margin-bottom: 6px; }
.voice-rule-row { display: grid; grid-template-columns: 40px 1fr 36px;
                  gap: 10px; align-items: center; min-height: 36px; }
.voice-rule-temp { font-weight: 700; padding: 5px 0; border-radius: 6px;
                   font-size: 11px; text-align: center; letter-spacing: 0.04em;
                   color: #fff; }
/* Цветовой градиент cool → hot по температуре, как у Engagement Classifier. */
.voice-rule-temp-0 { background: #4a7fb8; }   /* холодно */
.voice-rule-temp-1 { background: #5e9fbf; }
.voice-rule-temp-2 { background: #7eb88f; }
.voice-rule-temp-3 { background: #d6a55a; }
.voice-rule-temp-4 { background: #d97a4a; }
.voice-rule-temp-5 { background: #c44949; }   /* горячо */
.voice-rule-chips { min-height: 32px; }
.voice-rule-chips .chips { margin-bottom: 4px; }
.voice-rule-chips .chip-input-row { gap: 6px; }
.voice-rule-preview { padding: 4px 8px; min-width: 32px; font-size: 14px;
                      line-height: 1; }
.voice-rule-preview:disabled { opacity: 0.5; cursor: wait; }
.voice-rule-status { grid-column: 1 / -1; font-size: 11px; color: var(--text-2);
                     padding: 2px 4px 0 50px; line-height: 1.3; }
.voice-rule-status-error { color: #ff6b6b; }
.voice-rule-hint { margin-top: 8px; }

.stab-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 6px; }
.stab-btn { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-ctl);
            padding: 9px 10px; cursor: pointer; color: var(--text-1); font-size: 13px;
            transition: border-color 0.15s, background 0.15s; }
.stab-btn:hover { border-color: var(--text-3); }
.stab-btn.selected { background: rgba(42,171,238,.10); border-color: var(--g); font-weight: 600; }

.tone-cards { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 8px; }
.tone-cards .tone-card:nth-child(5) { grid-column: 1 / 3; }
.tone-card { background: var(--bg-card); border: 1px solid var(--border); border-radius: var(--r-card);
             padding: 14px 16px; cursor: pointer;
             transition: border-color 0.15s, background 0.15s; }
.tone-card:hover { border-color: var(--text-3); }
.tone-card.selected { background: rgba(42,171,238,.10); border-color: var(--g); }
.tone-card-label { font-weight: 600; font-size: 14px; }

.tone-preview-box {
  margin-top: 14px;
  padding: 12px 16px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  font-size: 13px;
  font-style: italic;
  color: var(--text-2);
  line-height: 1.45;
}

/* Phase 3-A: Language mode radio rows */
.lang-modes { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.lang-mode-row { display: flex; gap: 12px; padding: 10px 14px; background: var(--bg-card);
                 border: 1px solid var(--border); border-radius: var(--r-ctl); cursor: pointer;
                 transition: border-color 0.15s, background 0.15s; }
.lang-mode-row:hover { border-color: var(--text-3); }
.lang-mode-row.selected { border-color: var(--g); background: rgba(42,171,238,.10); }
.lang-mode-text { flex: 1; }
.lang-mode-label { font-weight: 500; margin-bottom: 2px; font-size: 14px; }
.lang-mode-preview { font-size: 12px; color: var(--text-2); font-style: italic; }

/* ── Sticker pack section ─────────────────────────────────────────── */
.sticker-pack-status { font-size: 13px; color: var(--text-2); margin-top: 6px; }
.sticker-pack-status.sticker-pack-ok  { color: var(--ok); }
.sticker-pack-status.sticker-pack-err { color: var(--bad); }

.form-range {
  width: 100%;
  accent-color: var(--green);
}

.sticker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: 8px;
  margin-top: 8px;
  margin-bottom: 8px;
  max-height: 320px;
  overflow-y: auto;
  padding: 8px;
  background: var(--bg-card);
  border-radius: 6px;
}

.sticker-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 4px;
  border: 2px solid transparent;
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.sticker-cell:hover {
  background: var(--bg-hover);
}

.sticker-cell.selected {
  border-color: var(--ok);
  background: var(--bg-hover);
}

.sticker-cell img {
  width: 56px;
  height: 56px;
  object-fit: contain;
}

.sticker-alt {
  font-size: 14px;
}

/* ── Engagement verdict block (правая панель чата) ───────────────────── */

/* ═══ Карточка «Покупатель» в панели чата (ультра-MVP) ══════════════════════
   Read-only: бот эти числа не видит, править нечего — отсюда ни курсора, ни
   подсветки строк, ни одного интерактивного элемента.
   Каркас — калька .dlg-pn-verdict по всем значениям (--mint / var(--r-card) /
   1px var(--line) / padding 12 / flex:none), чтобы встать в столбец панели без
   собственного языка.
   Три вида по тиру (канон buyer-tiers.js: покупки + чаевые >= 3):
     none  — ни бейджа, ни суммы; «$0.00» крупным кеглем это не информация, а укор
     payer — синий бейдж, рант обычный
     whale — золотой бейдж + тёплая подсветка; золото достаётся ТОЛЬКО киту,
             иначе тёплый акцент перестаёт что-либо значить
   Оба бейджа — родные градиенты .dlg-stats-badge (style.css:1108-1114), дословно.
   ═══════════════════════════════════════════════════════════════════════════ */
.mc { flex: none; margin: 12px 0 0; padding: 12px; background: var(--mint);
  border: 1px solid var(--line); border-radius: var(--r-card); font-size: 12px; line-height: 1.4; }
/* ГОЧА: шорткат `border` затирает `border-color` — порядок объявлений важен,
   иначе тёплый рант молча не рисуется. */
.mc.is-whale {
  background: linear-gradient(180deg, rgba(235,177,74,.055) 0%, rgba(235,177,74,0) 46%), var(--mint);
  border-color: rgba(235,177,74,.22);
  box-shadow: inset 0 1px 0 rgba(255,214,140,.10);
}
.mc-head { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.mc-title { font-size: 12px; font-weight: 600; color: var(--t1); }
.mc-tier { flex: none; padding: 2px 7px; border-radius: 999px;
  font-size: 8.5px; font-weight: 800; letter-spacing: .5px; text-transform: uppercase; }
.mc-tier.is-whale { color: #5a4200; background: linear-gradient(180deg,#ffd24a,#f5b301); }
.mc-tier.is-payer { color: #fff;    background: linear-gradient(180deg,#4aa3ff,#1f7fe0); }
/* auto 1fr: число забирает свою ширину, рельс прижат к правому канту — цифры
   выстраиваются в один столбец, как в выписке. */
.mc-body { display: grid; grid-template-columns: auto 1fr; column-gap: 18px; align-items: center; }
.mc-sum { font-family: var(--ff-num); font-size: 34px; font-weight: 600; line-height: 1;
  letter-spacing: -.8px; color: var(--t1); font-variant-numeric: tabular-nums;
  white-space: nowrap; cursor: help; }
.mc-stats { display: grid; grid-template-columns: 1fr auto; column-gap: 10px; row-gap: 5px; }
.mc-stats dt { font-size: 10px; color: var(--t3); line-height: 1.3; }
.mc-stats dd { font-size: 12px; font-weight: 600; color: var(--t1); line-height: 1.3;
  text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.mc-single { font-size: 11.5px; color: var(--t2); line-height: 1.5; }
.mc-single b { color: var(--t1); font-weight: 600; }
/* Неплативший — 93.3% контактов по замеру прода, то есть основной вид карточки. */
.mc-none { font-size: 12px; color: var(--t2); line-height: 1.55; }
.mc-none b { color: var(--t1); font-weight: 600; }
.mc-none .n { color: var(--t1); font-weight: 700; font-variant-numeric: tabular-nums; }
/* Три отказа и больше — не украшение, а сигнал «дожимать бессмысленно».
   Порог взят по проду: столько раз отказались 3 825 человек. */
.mc-none.is-cold .n { color: var(--bad); }
/* Черта во всю ширину: отрицательные поля выводят её из-под padding 12. */
.mc-foot { margin: 12px -12px 0; padding: 9px 12px 0; border-top: 1px solid var(--line);
  font-size: 11px; color: var(--t2); line-height: 1.5; }
.mc-foot b { color: var(--t1); font-weight: 600; }
.mc-foot > div + div { margin-top: 2px; }
/* Строка подвала карточки «Покупатель»: слева стаж, справа съеденная энергия. */
.mc-enrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* ⚡ чата — тёплая капсула: расход отличается по цвету и от синего дохода, и от
   золотого бейджа кита (тот заливной, эта — с прозрачным фоном). */
.mc-en { flex: none; padding: 3px 9px; border-radius: 999px; line-height: 1; font-size: 11.5px;
  color: #f0c674; background: rgba(235, 177, 74, .10); border: 1px solid rgba(235, 177, 74, .22); }
.mc-en b { color: #ffd995; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }

.dlg-pn-verdict {
  margin: 12px 0;
  padding: 12px;
  background: var(--raise-2);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  font-size: 12px;
  line-height: 1.4;
}
.dlg-pn-verdict-titlerow {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}
.dlg-pn-verdict-title {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 1.2px;
  color: var(--text-3);
}
/* Ссылка «сброс» рядом с лейблом «Слоу-мод» (видна когда стоит ручной оверрайд) */
.dlg-pn-reset {
  font-size: 10px;
  color: var(--text-3);
  cursor: pointer;
  text-decoration: underline dotted;
}
.dlg-pn-reset:hover { color: var(--text-2); }

/* Gauge: label + value on one row, bar full-width below */
.dlg-pn-gauge { margin: 8px 0; }
.dlg-pn-gauge-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 4px;
  white-space: nowrap;
}
.dlg-pn-gauge-l { color: var(--text-2); font-size: 11px; }
.dlg-pn-gauge-v {
  color: var(--text);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.dlg-pn-trend { display: inline-block; margin-left: 4px; font-weight: 700; }

.dlg-pn-bar {
  display: flex;
  gap: 4px;
  width: 100%;
}
.dlg-pn-bar-cell {
  flex: 1;
  height: 6px;
  background: var(--line);
  border-radius: 3px;
}
/* Заполненные сегменты — стиль «Накал сцены» концепта: градиент по тону + glow.
   вовлечённость=синий, градус=оранжевый, сопротивление=красный. */
.dlg-pn-bar-cell.on.tone-blue   { background: linear-gradient(90deg, var(--accent-dim), var(--accent)); box-shadow: 0 0 8px var(--accent-glow); }
.dlg-pn-bar-cell.on.tone-orange { background: linear-gradient(90deg, #b4611f, #e0a952); box-shadow: 0 0 8px rgba(224,169,82,.35); }
.dlg-pn-bar-cell.on.tone-red    { background: linear-gradient(90deg, #a83a3a, #e06b6b); box-shadow: 0 0 8px rgba(224,107,107,.30); }

/* Recommendation: label column + value column, no wrapping issues */
.dlg-pn-verdict-rec {
  margin: 12px 0 10px;
  padding: 9px 12px;
  background: var(--black);
  border-radius: 10px;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 8px;
  row-gap: 4px;
}
.dlg-pn-rec-row { display: contents; }
.dlg-pn-rec-l { color: var(--text-3); font-size: 11px; }
.dlg-pn-rec-v { color: var(--text); font-size: 12px; }

.dlg-pn-chip { margin: 4px 0; color: var(--text); font-size: 11px; line-height: 1.5; }
.dlg-pn-chip-l { color: var(--text-3); }
.dlg-pn-chip-l::after { content: ':'; }

.dlg-pn-verdict-reason {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  font-style: italic;
  color: var(--text-2);
  font-size: 11px;
  line-height: 1.45;
}
.dlg-pn-verdict-ts {
  margin-top: 8px;
  font-size: 10px;
  color: var(--text-3);
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.dlg-pn-verdict-ts::before { content: 'обновлено '; }
.dlg-pn-verdict-ts--stale { color: #c99a2e; }
.dlg-pn-verdict-ts--very-stale { color: var(--t3); font-weight: 400; }

/* Stats tab — funnel rows */
.funnel-row {
  display: grid;
  grid-template-columns: 110px 1fr 40px;
  align-items: center;
  gap: 10px;
  margin: 6px 0;
  font-size: 13px;
}
.funnel-lbl { color: var(--text-muted, #888); }
.funnel-bar {
  height: 10px;
  background: rgba(255,255,255,0.05);
  border-radius: 4px;
  overflow: hidden;
}
.funnel-bar > span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, #229ED9, #6BC6FF);
  transition: width 0.3s ease;
}
.funnel-val { text-align: right; font-variant-numeric: tabular-nums; }

/* Stats tab — top characters table */
.tc-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 8px;
  font-size: 13px;
}
.tc-table th {
  text-align: left;
  color: var(--text-muted, #888);
  font-weight: 500;
  padding: 6px 8px;
  border-bottom: 1px solid rgba(255,255,255,0.06);
}
.tc-table td {
  padding: 6px 8px;
  border-bottom: 1px solid rgba(255,255,255,0.04);
}

/* Stats tab — trend chip in ov-big */
.trend {
  font-size: 14px;
  margin-left: 8px;
  font-weight: 500;
}
.trend.ok  { color: #4ade80; }
.trend.err { color: #f87171; }

/* B1: Composer — Telegram-style (icons inline + send arrow) */
.dlg-composer {
  display: flex; align-items: flex-end; gap: 4px;
  margin: 10px 16px 14px;
  padding: 6px 8px;
  background: var(--bg-input, #131316);
  border: 1px solid var(--border, #232327);
  border-radius: var(--r-card);
}
.dlg-composer-tool {
  background: transparent; border: 0;
  padding: 6px 8px; line-height: 0;
  color: #8b929c; cursor: pointer;
  border-radius: var(--r-ctl);
  transition: background .15s var(--ease-out), color .15s var(--ease-out), transform .12s var(--ease-out);
  align-self: center;
  display: inline-flex; align-items: center; justify-content: center;
}
.dlg-composer-tool:hover:not(:disabled) { background: rgba(255,255,255,.06); color: #cfd3d8; }
.dlg-composer-tool:active:not(:disabled) { transform: scale(.9); }
.dlg-composer-tool:disabled { opacity: 0.35; cursor: not-allowed; }
/* Разделитель смысловых групп кнопок (медиа | голос | помощь). Композер всегда
   на тёмном --bg-input, поэтому белый-альфа читается в обеих темах. */
.dlg-composer-sep {
  width: 1px; align-self: center; height: 20px; flex-shrink: 0;
  background: rgba(255,255,255,.10); margin: 0 3px;
}
/* Пилюля «Озвучить» в режиме озвучки — primary-действие, запускает генерацию. */
.dlg-vc-generate {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  align-self: center; height: 32px; padding: 0 14px;
  border: 0; border-radius: 16px; cursor: pointer;
  background: linear-gradient(135deg, var(--g, #2AABEE), var(--g2, #229ED9));
  color: #fff; font-family: inherit; font-size: 12.5px; font-weight: 600;
  transition: filter .15s var(--ease-out), transform .12s var(--ease-out);
}
.dlg-vc-generate:hover { filter: brightness(1.1); }
.dlg-vc-generate:active { transform: scale(.97); }
#dlg-ai-btn.loading { pointer-events: none; }
#dlg-ai-btn.loading svg path { transform-box: fill-box; transform-origin: center; }
#dlg-ai-btn.loading svg path:nth-child(1) { animation: dlg-ai-twinkle 1.1s var(--ease-out) infinite; }
#dlg-ai-btn.loading svg path:nth-child(2) { animation: dlg-ai-twinkle 1.1s var(--ease-out) .55s infinite; }
@keyframes dlg-ai-twinkle {
  0%, 100% { opacity: .35; transform: scale(.75); }
  50%      { opacity: 1;   transform: scale(1.1); }
}
@media (prefers-reduced-motion: reduce) {
  #dlg-ai-btn.loading svg path { animation: none; }
  #dlg-ai-btn.loading { opacity: .5; }
}
.dlg-composer textarea {
  flex: 1; resize: none;
  background: transparent; border: 0; outline: none; box-shadow: none;
  color: #e3e6ea;
  font-family: inherit; font-size: 13px; line-height: 22px;
  min-height: 30px; max-height: 132px;
  padding: 4px 6px;
}
.dlg-composer textarea::placeholder { color: #6b727c; }
.dlg-composer-send {
  background: linear-gradient(135deg, var(--g, #2AABEE), var(--g2, #229ED9));
  color: #fff; border: 0;
  width: 32px; height: 32px; padding: 0;
  border-radius: 50%; cursor: pointer; line-height: 0;
  display: inline-flex; align-items: center; justify-content: center;
  align-self: center; flex-shrink: 0;
  transition: filter .15s;
}
.dlg-composer-send:hover { filter: brightness(1.1); }
.dlg-composer-send svg { transform: translateX(-1px); }
/* Кнопка отвечает на нажатие — интерфейс должен показывать, что услышал. */
.dlg-composer-send:active { transform: scale(.94); }
/* Пусто в поле — отправлять нечего, кнопка приглушена (но кликабельна: Enter
   всё равно ничего не отправит, а мигающий disabled раздражал бы). */
.dlg-composer-send.is-idle { filter: saturate(.25) brightness(.75); }
/* Поле ввода растёт плавно (высоту ставит _dlgComposerWire покадрово). */
#dlg-input { transition: height var(--dur-2) var(--ease-out); }

/* B3b: Emoji popover */
.dlg-composer { position: relative; }
/* Поповеры композера раскрываются от своего триггера (origin-aware): эмодзи 🙂
   слева, теги 🏷 — справа (в режиме озвучки кнопка стоит у правого края). */
@keyframes dlg-pop-in {
  from { opacity: 0; transform: scale(.96) translateY(4px); }
  to   { opacity: 1; transform: scale(1)   translateY(0); }
}
#dlg-emoji-pop {
  position: absolute; bottom: 56px; left: 8px; z-index: 40;
  display: grid; grid-template-columns: repeat(9, 1fr); gap: 2px;
  padding: 8px; max-width: 320px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-ctl); box-shadow: var(--shadow-pop);
  transform-origin: bottom left;
  animation: dlg-pop-in 160ms var(--ease-out);
}
.dlg-emoji-cell {
  background: none; border: none; cursor: pointer;
  font-size: 20px; line-height: 1; padding: 4px; border-radius: 6px;
  transition: background .12s var(--ease-out), transform .1s var(--ease-out);
}
.dlg-emoji-cell:hover { background: var(--ctl-h); }
.dlg-emoji-cell:active { transform: scale(.9); }

/* B3c: Voice-tags popover (palette ручной вставки v3 audio-тегов) */
#dlg-tags-pop {
  position: absolute; bottom: 56px; right: 8px; left: auto; z-index: 40;
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 8px; max-width: 360px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-ctl); box-shadow: var(--shadow-pop);
  transform-origin: bottom right;
  animation: dlg-pop-in 160ms var(--ease-out);
}
.dlg-tags-pop-title {
  width: 100%; font-size: 11px; text-transform: uppercase;
  color: var(--t3); margin-bottom: 4px;
}
.dlg-tag-cell {
  background: var(--ctl); border: 1px solid var(--line);
  color: var(--t1); font-family: monospace; font-size: 12px;
  padding: 4px 8px; border-radius: 4px; cursor: pointer;
  transition: background .12s var(--ease-out), transform .1s var(--ease-out);
}
.dlg-tag-cell:hover { background: var(--ctl-h); }
.dlg-tag-cell:active { transform: scale(.96); }
@media (prefers-reduced-motion: reduce) {
  #dlg-emoji-pop, #dlg-tags-pop, #dlg-tip-bar { animation: none; }
}

/* Ручной счёт на чай — инлайн-полоса во всю ширину НАД композером (как reply-bar).
   Все контролы держат единую высоту 36px, чтобы инпут/селект/кнопка стояли на одной линии. */
#dlg-tip-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; margin: 0 16px 8px;
  background: rgba(255,255,255,.04);
  border: 1px solid var(--line);
  border-left: 2px solid var(--g, #2AABEE);
  border-radius: 10px;
  animation: dlg-pop-in 160ms var(--ease-out);
}
.dlg-tip-bar-icon { flex: none; font-size: 15px; line-height: 1; opacity: .9; }
#dlg-tip-bar input { flex: 1; min-width: 0; }
#dlg-tip-bar input, #dlg-tip-bar select {
  height: 36px; box-sizing: border-box;
  background: var(--ctl); border: 1px solid var(--line); color: var(--t1);
  border-radius: 8px; padding: 0 10px; font-size: 13px; font-family: inherit; outline: none;
  transition: border-color .12s var(--ease-out), box-shadow .12s var(--ease-out);
}
#dlg-tip-bar select { flex: none; cursor: pointer; }
#dlg-tip-bar input:focus, #dlg-tip-bar select:focus {
  border-color: var(--g, #2AABEE);
  box-shadow: 0 0 0 3px rgba(42,171,238,.15);
}
/* спиннеры number-инпута ломали высоту и выглядели грязно — срезаем */
#dlg-tip-bar input[type=number] { -moz-appearance: textfield; }
#dlg-tip-bar input[type=number]::-webkit-outer-spin-button,
#dlg-tip-bar input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.dlg-tip-bar-send {
  height: 36px; box-sizing: border-box; flex: none;
  display: inline-flex; align-items: center;
  background: linear-gradient(135deg, var(--g, #2AABEE), var(--g2, #229ED9));
  color: #fff; border: 0; cursor: pointer; white-space: nowrap;
  border-radius: 8px; padding: 0 16px; font-size: 13px; font-weight: 600;
  transition: filter .12s var(--ease-out), transform .12s var(--ease-out);
}
.dlg-tip-bar-send:hover { filter: brightness(1.08); }
.dlg-tip-bar-send:active { transform: scale(.97); }
/* Концепт: primary-кнопка = сплошной accent + ТЁМНЫЙ текст #04121b (не белый), glow на hover */
[data-theme="dark"] .dlg-tip-bar-send { background: var(--accent); color: #04121b; }
[data-theme="dark"] .dlg-tip-bar-send:hover { filter: brightness(1.06); box-shadow: 0 0 18px var(--accent-glow); }
.dlg-tip-bar-send:disabled { opacity: .6; cursor: default; }
.dlg-tip-bar-x {
  height: 36px; width: 36px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: none; color: var(--t3); cursor: pointer;
  font-size: 14px; border-radius: 8px;
  transition: background .12s var(--ease-out), color .12s var(--ease-out), transform .12s var(--ease-out);
}
.dlg-tip-bar-x:hover { color: var(--t1); background: rgba(255,255,255,.06); }
.dlg-tip-bar-x:active { transform: scale(.92); }

/* Шкала z-index модалок пикера «Отправить медиа» (снизу вверх):
   бэкдропы модалок — 1000; оверлей просмотра набора (.dlg-mp-ppv) — 1050;
   конфирм закрытия (.dlg-mp-confirm) — 1060; редактор кружка (video-edit-modal) —
   1150, поверх пикера; плавающие панели действий (.bulk-bar / #char-actionbar) —
   9998; общие модалки приложения (.modal-overlay, в т.ч. подтверждение удаления) —
   9999, поверх панелей действий; лайтбокс полного просмотра (.dlg-lightbox) —
   10000; тосты — 10001, поверх всего.
   Лайтбокс ушёл ВЫШЕ редактора кружка (был 1100, под ним): редактор открывается
   только из выбора ЛОКАЛЬНОГО файла на заливку (openVideoEditModal), а лайтбокс
   накрывает экран целиком — дотянуться до кнопки заливки из-под него нельзя,
   так что пересечься эти двое не могут. */
/* B3: Media picker modal */
.dlg-modal-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.6);
  display: flex; align-items: center; justify-content: center; z-index: 1000;
}
/* Память переписки (rolling dialog summary) — модалка с текстом сводки. */
.dlg-sum {
  width: 560px; max-width: 92vw; max-height: 80vh; overflow: auto;
  background: #1a1a1e; border-radius: var(--r-card); padding: 16px 18px;
  color: #cfd3d8; font-size: 13px; line-height: 1.5;
}
.dlg-sum-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; }
.dlg-sum-close { cursor: pointer; opacity: .65; font-size: 16px; }
.dlg-sum-close:hover { opacity: 1; }
.dlg-sum-text { white-space: normal; word-wrap: break-word; }
.dlg-sum-meta { margin-top: 14px; padding-top: 10px; border-top: 1px solid #232327; font-size: 11px; opacity: .55; }
.dlg-sum-empty { text-align: center; padding: 20px 10px; opacity: .65; font-size: 12px; line-height: 1.6; }
/* Инфо-модал: табы (память переписки + общие медиа). Базовые правила тёмные — как .dlg-sum. */
.dlg-info-tabs { display: flex; gap: 4px; margin-bottom: 12px; flex-wrap: wrap; }
.dlg-info-tab {
  background: none; border: none; cursor: pointer; padding: 6px 10px;
  border-radius: var(--r-ctl); font-size: 12px; color: #aab1bb; opacity: .8;
}
.dlg-info-tab.on { background: rgba(255,255,255,.08); opacity: 1; color: #fff; }
.dlg-info-body { min-height: 80px; }
.dlg-info-sub { font-size: 12px; opacity: .65; margin-bottom: 3px; }
.dlg-info-memhead { font-weight: 600; margin: 12px 0 8px; font-size: 13px; }
.dlg-info-count { font-size: 12px; opacity: .6; margin-bottom: 10px; }
.dlg-info-loading { text-align: center; padding: 24px; opacity: .6; font-size: 12px; }
.dlg-info-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.dlg-info-cell {
  position: relative; aspect-ratio: 1; border-radius: 6px; overflow: hidden;
  cursor: pointer; background: rgba(255,255,255,.05);
}
.dlg-info-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dlg-info-cell.broken, .dlg-info-cell--paid {
  display: flex; align-items: center; justify-content: center; color: #888; font-size: 20px;
}
.dlg-info-play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 22px; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,.6); pointer-events: none;
}
.dlg-info-list { display: flex; flex-direction: column; gap: 10px; }
.dlg-info-row { display: flex; flex-direction: column; gap: 4px; word-break: break-word; }
.dlg-info-row audio { width: 100%; height: 32px; }
.dlg-info-row a { color: #6ea8fe; }
.dlg-info-row-meta { font-size: 11px; opacity: .5; }
.dlg-info-more {
  display: block; margin: 12px auto 0; padding: 7px 16px; cursor: pointer;
  background: rgba(255,255,255,.08); border: none; border-radius: var(--r-ctl);
  color: inherit; font-size: 12px;
}
/* z-index 10000, а НЕ 1100 (как было): лайтбокс — прямой ребёнок <body>, и так же в
   <body> висит панель действий редактора персонажа #char-actionbar (.bulk-bar, 9998).
   На 1100 поверх чёрной подложки оставалась кликабельная кнопка «Удалить» — она сносит
   ПЕРСОНАЖА, а не фото. Фактические соседи по стеку: бэкдропы пикера 1000, просмотр
   набора 1050, конфирм закрытия 1060, редактор кружка 1150, .bulk-bar 9998,
   .modal-overlay 9999, тост 10001.
   Выше .bulk-bar и ниже тоста (ошибка загрузки должна читаться поверх подложки);
   зазор 9999 занят общими модалками приложения, поэтому тост стоит на 10001. */
.dlg-lightbox {
  position: fixed; inset: 0; background: rgba(0,0,0,.85); z-index: 10000;
  display: flex; align-items: center; justify-content: center;
}
.dlg-lightbox-media { max-width: 92vw; max-height: 88vh; border-radius: 8px; }
.dlg-lightbox-close {
  position: absolute; top: 18px; right: 24px; color: #fff; font-size: 26px;
  cursor: pointer; opacity: .8;
}
.dlg-lightbox-close:hover { opacity: 1; }
/* Обёртка «кадр + подпись». Нужна потому, что .dlg-lightbox — flex-СТРОКА: без неё
   подпись встала бы сбоку от кадра, а не под ним. Подпись появляется только когда
   сервер отдал превью вместо оригинала (vault-лот либо фолбэк после неудачного
   ?full=1) — в обычном случае внутри лежит один элемент и обёртка ничего не меняет. */
.dlg-lightbox-stack {
  display: flex; flex-direction: column; align-items: center; gap: 10px; max-width: 92vw;
}
.dlg-lightbox-note {
  color: rgba(255,255,255,.72); font-size: 13px; line-height: 1.35;
  text-align: center; max-width: 92vw;
}

/* ── Полировка инфо-модала: motion + интерактив, строго в рамках дизайн-системы.
   Глобальный @media(prefers-reduced-motion) (*{animation/transition:none}) гасит всё.
   Модал/лайтбокс пересоздаются при каждом открытии → keyframes проигрываются заново. */
@keyframes dlg-info-backdrop { from { opacity: 0; } to { opacity: 1; } }
@keyframes dlg-info-pop { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: none; } }
@keyframes dlg-lightbox-pop { from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: none; } }

/* вход модала: фон проявляется, контент «всплывает» из центра (модал → origin center) */
#dlg-summary-modal { animation: dlg-info-backdrop .18s var(--ease-out); }
#dlg-summary-modal .dlg-info { animation: dlg-info-pop .2s var(--ease-out); transform-origin: center; }

/* ФИКС ВЫСОТЫ: окно не «прыгает» при переключении вкладок (контент разной высоты).
   Карточка фиксирована, скроллится ТОЛЬКО тело — переключение без reflow/перецентровки.
   Шапка+табы остаются на месте; пустое место на «Инфо» — осознанный размен на стабильность. */
#dlg-summary-modal .dlg-info {
  display: flex; flex-direction: column;
  height: min(80vh, 620px); overflow: hidden;
}
#dlg-summary-modal .dlg-info-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
/* переключение вкладок — мгновенное (частое действие, без анимации по Emil) */

/* табы: фидбэк нажатия + ховер (только hover-устройства, без ложных тапов) */
.dlg-info-tab { transition: background .15s var(--ease-out), color .15s var(--ease-out), transform .12s var(--ease-out); }
.dlg-info-tab.on { font-weight: 600; }
.dlg-info-tab:active { transform: scale(.96); }
@media (hover: hover) and (pointer: fine) {
  .dlg-info-tab:not(.on):hover { opacity: 1; color: #e7eaee; background: rgba(255,255,255,.05); }
}

/* миниатюры: зум по ховеру + фидбэк нажатия (анимируем только transform — GPU) */
.dlg-info-cell { transition: transform .14s var(--ease-out); }
.dlg-info-cell:active { transform: scale(.97); }
.dlg-info-cell img { transition: transform .22s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .dlg-info-cell:hover img { transform: scale(1.06); }
}

/* «Показать ещё» + закрытие ✕: фидбэк */
.dlg-info-more { transition: background .15s var(--ease-out), transform .12s var(--ease-out); }
.dlg-info-more:active { transform: scale(.97); }
@media (hover: hover) and (pointer: fine) {
  .dlg-info-more:hover { background: rgba(255,255,255,.14); }
}
.dlg-sum-close { transition: opacity .15s var(--ease-out), transform .12s var(--ease-out); }
.dlg-sum-close:active { transform: scale(.9); }

/* лайтбокс: фон проявляется, картинка «всплывает»; круглая кнопка закрытия */
.dlg-lightbox { animation: dlg-info-backdrop .18s var(--ease-out); }
.dlg-lightbox-media { animation: dlg-lightbox-pop .22s var(--ease-out); }
.dlg-lightbox-close {
  top: 16px; right: 16px; width: 36px; height: 36px; font-size: 20px;
  display: flex; align-items: center; justify-content: center; border-radius: 50%;
  background: rgba(0,0,0,.45); transition: background .15s var(--ease-out), transform .12s var(--ease-out);
}
.dlg-lightbox-close:active { transform: scale(.92); }
@media (hover: hover) and (pointer: fine) {
  .dlg-lightbox-close:hover { background: rgba(0,0,0,.7); }
}
.dlg-mp {
  width: 560px; max-width: 92vw; max-height: 86vh; overflow: auto;
  background: #000; border: 1px solid #1e1e26; border-radius: 16px; padding: 16px;
  color: #cfd3d8; font-size: 13px;
  animation: dlg-mp-in 120ms var(--ease-out);
}
@keyframes dlg-mp-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .dlg-mp { animation: none; } }
/* Шапка: заголовок + тихий счётчик слева одной строкой, табы и крестик справа. */
.dlg-mp-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 12px; }
.dlg-mp-head-left { display: flex; align-items: baseline; gap: 8px; min-width: 0; overflow: hidden; }
.dlg-mp-head-right { display: flex; align-items: center; gap: 10px; flex: none; }
.dlg-mp-title { font-weight: 700; font-size: 14px; color: #e8eaed; white-space: nowrap; flex: none; }
.dlg-mp-close { cursor: pointer; color: #5f6368; font-size: 16px; transition: color .15s var(--ease-out), transform .16s var(--ease-out); }
.dlg-mp-close:active { transform: scale(.9); }
/* Табы «Библиотека | Загрузить», сегмент «Файлы | Кружок» и капсула категорий
   фильтра — одна тихая капсула. */
.dlg-mp-maintabs, .dlg-mp-seg, .dlg-mp-catseg { background: #0c0c10; border-color: #1e1e26; border-radius: 9px; padding: 2px; gap: 2px; }
.dlg-mp-maintabs .seg-btn, .dlg-mp-seg .seg-btn, .dlg-mp-catseg .seg-btn { padding: 5px 14px; font-size: 11px; border-radius: 7px; color: #9aa0a6; }
.dlg-mp-maintabs .seg-btn.on, .dlg-mp-seg .seg-btn.on, .dlg-mp-catseg .seg-btn.on { background: #1b2531; color: #7cc9f2; box-shadow: none; font-weight: 600; }
/* Клиент ещё не ответил на прошлое медиа — тонкий баннер, не орёт. */
.dlg-mp-awaiting-banner {
  display: flex; align-items: center; gap: 6px;
  padding: 5px 10px; margin-bottom: 10px;
  background: rgba(214,84,84,.12); border: 1px solid rgba(214,84,84,.27);
  border-radius: 8px; color: #ff9d9d; font-size: 11px; font-weight: 400;
}
/* Тулбар: капсула категорий (Все|Бесплатно|Платно) на всю ширину; вторая
   строка — тумблер «Не отпр.» + чипы сцен. */
.dlg-mp-filters { display: flex; gap: 8px; align-items: center; margin-bottom: 10px; flex-wrap: wrap; }
.dlg-mp-filters .dlg-mp-catseg { flex: 1 1 100%; display: flex; }
.dlg-mp-catseg .seg-btn { flex: 1 1 0; }
/* «Не отпр.» среди чипов сцен — другой смысл (тумблер), лёгкий пунктир отличает */
.dlg-mp-chip.unsent { border-style: dashed; }
.dlg-mp-chip.unsent.on { border-style: solid; }
.dlg-mp-chip {
  flex: none; padding: 4px 10px; border-radius: 999px;
  background: #111116; color: #9aa0a6; border: 1px solid #23232b;
  cursor: pointer; font-size: 11px; line-height: 1.4;
  transition: background .15s var(--ease-out), border-color .15s var(--ease-out), color .15s var(--ease-out), transform .16s var(--ease-out);
}
.dlg-mp-chip.on { background: rgba(42,171,238,.14); border-color: var(--g); color: #7cc9f2; }
.dlg-mp-chip:active { transform: scale(.97); }
.dlg-mp-count { color: #5f6368; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.dlg-mp-filters.scenes { flex-wrap: nowrap; overflow-x: auto; margin-top: -2px; padding-bottom: 4px; }
.dlg-mp-filters.scenes .dlg-mp-chip { flex: 0 0 auto; }
.dlg-mp-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
.dlg-mp-card {
  position: relative; aspect-ratio: 3/4;
  background: #131316; border-radius: 10px; overflow: hidden; cursor: pointer;
  outline: 2px solid transparent; outline-offset: -2px;
  transition: outline-color .15s var(--ease-out), box-shadow .15s var(--ease-out), opacity .15s var(--ease-out);
}
.dlg-mp-card img { width: 100%; height: 100%; object-fit: cover; display: block; background: #000; }
.dlg-mp-card.sel { outline-color: var(--g); box-shadow: 0 0 12px rgba(42,171,238,.35); }
.dlg-mp-card.sent { opacity: .32; }
.dlg-mp-card.sent::after {
  content: '✓'; position: absolute; top: 6px; right: 6px;
  width: 15px; height: 15px; line-height: 15px; text-align: center;
  background: rgba(0,0,0,.6); color: #5dd39e; border-radius: 50%; font-size: 9px;
}
/* «Куплено» этим собеседником — ПЕРЕИСПОЛЬЗУЕМ золотой язык бейджа «Куплено» из
   переписки (.dlg-paidprev.is-purchased .dlg-paidprev-badge): оплата в звёздах,
   продажа читается как награда, а не системный статус — золото, НЕ зелёный (см.
   комментарий там же). Тот же градиент/тёмный текст/металл-блик, только компактнее
   под плитку. Картинку гасим как «отправлено» (.sent=.32), но гасим только <img>
   (карточка opacity:1), чтобы бейдж оставался чётким. Бейдж встаёт на место цены;
   ::after определён ПОСЛЕ .sent::after → у купленного мелкую ✓ не показываем. */
.dlg-mp-card.purchased { opacity: 1; }
.dlg-mp-card.purchased img { opacity: .32; }
.dlg-mp-card.purchased .dlg-mp-badge.price { display: none; }
.dlg-mp-card.purchased::after {
  content: '✓ Куплено'; position: absolute; top: 6px; left: 6px; z-index: 4;
  /* ОБЯЗАТЕЛЬНО сбросить width/height/right/text-align: у .sent::after они 15px/
     center (мелкий кружок ✓), а купленная карточка ещё и .sent → без сброса
     «✓ Куплено» впихивалось в 15×15 и обрезалось. */
  width: auto; height: auto; right: auto; text-align: left;
  white-space: nowrap; line-height: 1.25;
  padding: 3px 8px; border-radius: 999px;
  background: linear-gradient(160deg, #FFE08A 0%, #F7C244 45%, #E8A21C 100%);
  color: #3A2606; font-size: 9px; font-weight: 800; letter-spacing: 0;
  /* только внутренний металл-блик; внешнее свечение срезал бы overflow:hidden карточки */
  box-shadow: inset 0 1px 0 rgba(255,255,255,.6), inset 0 -1px 0 rgba(140,90,10,.25);
}
/* Часть набора у собеседника уже КУПЛЕНА поштучно (packOwnedLabel). Язык тот же
   золотой, что у «✓ Куплено» — оплата читается как награда, — но БЕЗ слова «куплено»:
   на плитке 3/4 длинная пилюля съедала бы обложку. Угол правый-верхний, а не левый:
   слева стоит цена набора, и она оператору нужна ровно в этот момент (он решает,
   слать ли руками то, что бот уже не предлагает). С .mp-pick не пересекается —
   мультивыбор собирает одиночки, паки в него не входят. */
.dlg-mp-own {
  position: absolute; top: 6px; right: 6px; z-index: 4;
  padding: 3px 8px; border-radius: 999px; white-space: nowrap; line-height: 1.25;
  background: linear-gradient(160deg, #FFE08A 0%, #F7C244 45%, #E8A21C 100%);
  color: #3A2606; font-size: 9px; font-weight: 800;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.6), inset 0 -1px 0 rgba(140,90,10,.25);
}
/* Мультивыбор для альбома — синяя галочка в правом-ВЕРХНЕМ углу (лупа заняла низ-право). */
.dlg-mp-card.mp-pick::before {
  content: '✓'; position: absolute; top: 6px; right: 6px; z-index: 4;
  width: 18px; height: 18px; line-height: 18px; text-align: center;
  background: var(--g); color: #fff; border-radius: 50%;
  font-size: 11px; font-weight: 700; box-shadow: 0 0 0 2px rgba(0,0,0,.35);
}
/* Лупа — полноразмерный просмотр из карточки; появляется по hover (на тач — всегда). */
.dlg-mp-zoom {
  position: absolute; right: 6px; bottom: 6px; z-index: 3;
  width: 18px; height: 18px; display: flex; align-items: center; justify-content: center;
  border-radius: 5px; background: rgba(0,0,0,.6); color: #c9cdd3;
  font-size: 10px; cursor: pointer; opacity: 0;
  transition: opacity .15s var(--ease-out), background .15s var(--ease-out);
}
@media (hover: none), (pointer: coarse) { .dlg-mp-zoom { opacity: .8; } }
.dlg-mp-badge {
  position: absolute; padding: 2px 7px; border-radius: 999px;
  background: rgba(0,0,0,.65); color: #fff; font-size: 10px; font-weight: 600; line-height: 1.2;
}
.dlg-mp-badge.price { left: 6px; top: 6px; }
.dlg-mp-badge.vid { left: 6px; bottom: 6px; top: auto; background: rgba(0,0,0,.65); color: #c9cdd3; font-size: 9px; font-weight: 500; }
/* video_note (кружок) — круглая маска по центру карточки */
.dlg-mp-card.is-note img {
  width: 78%; aspect-ratio: 1; height: auto; border-radius: 50%;
  position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); object-fit: cover;
}
.dlg-mp-empty { grid-column: 1/-1; padding: 24px; text-align: center; opacity: .55; }
/* Пак-карточка — сигнал набора несёт бейдж-стопка «Набор · N», без спец-рамки. */
.dlg-mp-card.is-disabled { opacity: .42; cursor: not-allowed; }
.dlg-mp-pack-noart { width: 100%; height: 100%; background: linear-gradient(135deg,#1a1a1e,#131316); }
.dlg-mp-pack-scrim {
  position: absolute; left: 0; right: 0; bottom: 0; height: 46%;
  background: linear-gradient(transparent, rgba(0,0,0,.55)); pointer-events: none;
}
.dlg-mp-stack {
  position: absolute; left: 6px; bottom: 6px; z-index: 2;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 8px 2px 7px; border-radius: 999px;
  background: rgba(0,0,0,.65); color: #fff; font-size: 10px; font-weight: 600; line-height: 1.2;
}
.dlg-mp-stack svg { flex: none; opacity: .9; }
.dlg-mp-adhoc { border-top: 1px solid #232327; padding-top: 12px; margin-bottom: 12px; }
.dlg-mp-adhoc-label { font-size: 11px; text-transform: none; letter-spacing: 0; color: #8b929c; margin-bottom: 8px; }

/* выбор типа медиа — сегмент-контрол в стиле табов (капсула задана выше), только отступ */
.dlg-mp-seg { margin-bottom: 12px; }

/* зона перетаскивания / выбора файла — компактная */
.dlg-mp-drop {
  display: flex; align-items: center; justify-content: center;
  min-height: 86px; padding: 14px;
  border: 1.5px dashed #2a2a33; border-radius: 10px;
  background: #0c0c10; cursor: pointer; text-align: center;
  transition: border-color .18s var(--ease-out), background .18s var(--ease-out), transform .14s var(--ease-out);
}
.dlg-mp-drop.drag { border-color: var(--g); border-style: solid; background: rgba(42,171,238,.12); transform: scale(1.01); }
.dlg-mp-drop.has-file { min-height: 0; padding: 12px 14px; border-style: solid; border-color: rgba(42,171,238,.5); background: rgba(42,171,238,.08); }
.dlg-mp-drop-inner { pointer-events: none; display: flex; flex-direction: column; align-items: center; gap: 5px; max-width: 100%; }
.dlg-mp-drop.has-file .dlg-mp-drop-inner { flex-direction: row; align-items: center; gap: 12px; width: 100%; }
/* 2-10 файлов (будущий пак) — превью-лента 40px, реюз мозаики mv-dz-*. */
.dlg-mp-drop.has-file.multi .dlg-mp-drop-inner { flex-direction: column; align-items: stretch; gap: 6px; }
.dlg-mp-drop.multi .mv-dz-grid { justify-content: flex-start; }
.dlg-mp-drop .mv-dz-tile { width: 40px; height: 40px; border-radius: 8px; font-size: 16px; }
#dlg-mp-upload-body { margin-bottom: 12px; }
.dlg-mp-drop-ic { color: var(--g); opacity: .9; }
.dlg-mp-drop-text { font-size: 13px; color: #e3e6ea; font-weight: 500; }
.dlg-mp-drop-sub { font-size: 11px; color: #8b929c; }
.dlg-mp-file-ic { flex: none; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; border-radius: 8px; background: rgba(42,171,238,.16); color: var(--g); }
.dlg-mp-file-meta { min-width: 0; text-align: left; }
.dlg-mp-file-name { font-size: 13px; color: #e3e6ea; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dlg-mp-file-size { font-size: 11px; color: #8b929c; margin-top: 1px; }
/* number-инпуты кассы (★ у adhoc-файла) — без вебкит-спиннеров, они рвут 68px поле */
.dlg-mp-price-ovr::-webkit-outer-spin-button, .dlg-mp-price-ovr::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input.dlg-mp-price-ovr[type="number"] { -moz-appearance: textfield; appearance: textfield; }
/* Кнопка повторной подгонки кружка (кроп/длина) — тихий ghost в кассе-строке. */
.dlg-mp-note-edit {
  flex: none; padding: 8px 12px; border-radius: 8px;
  background: #111116; color: #9aa0a6; border: 1px solid #23232b; cursor: pointer;
  font-size: 12px; line-height: 1.4;
  transition: color .15s var(--ease-out), border-color .15s var(--ease-out), transform .16s var(--ease-out);
}
.dlg-mp-note-edit:active { transform: scale(.97); }
.dlg-mp-foot { display: flex; flex-direction: column; gap: 10px; }
.dlg-mp-foot-opts { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.dlg-mp-foot-send { display: flex; justify-content: flex-end; }
.dlg-mp-spoiler, .dlg-mp-sd { display: flex; align-items: center; gap: 6px; font-size: 12px; color: #cfd3d8; white-space: nowrap; cursor: pointer; }
.dlg-mp-sd-modes { display: flex; flex-wrap: wrap; gap: 6px; }
.dlg-mp-send {
  padding: 9px 20px; min-width: 110px;
  background: linear-gradient(135deg, var(--g, #2AABEE), var(--g2, #229ED9));
  color: #fff; border: 0; border-radius: var(--r-ctl); cursor: pointer;
  font-size: 13px; font-weight: 600;
  box-shadow: 0 2px 10px rgba(34,158,217,.28);
  transition: filter .15s var(--ease-out), transform .16s var(--ease-out), box-shadow .15s var(--ease-out);
}
.dlg-mp-send:active:not(:disabled) { transform: scale(.97); }
.dlg-mp-send:disabled {
  background: transparent; color: #6b727c; cursor: not-allowed;
  border: 1px solid #232327; font-weight: 400; box-shadow: none;
}

/* Прогресс аплоада — тонкая полоска + «N МБ из M», низ пикера. */
.dlg-mp-progress { display: flex; flex-direction: column; gap: 5px; margin-top: 10px; }
/* Слот под индикатор в НИЗУ ПИКЕРА (только он — грид/сцены монтируют такую же
   полоску в свой узел с другим id, его правила ниже не касаются).
   Зачем слот: #dlg-mp-bottom — последний блок внутри скроллируемой .dlg-mp, и
   узел, добавленный в конец, оказывался НИЖЕ кромки скролла: замеры headless
   (домотано до низа, как у оператора) давали видимыми 6px из 26 на 1440x1000 и
   4px из 26 на 390x844 — текста стадии не видно вовсе, т.е. вся информационная
   часть индикатора до оператора не доезжала. Место резервируется ЗАРАНЕЕ и
   постоянно, а сам индикатор ложится в него absolute — поэтому показ не растит
   scrollHeight (замер: +0px против +35px), ничего не сдвигает (кнопка и касса
   Δx=0/Δy=0), не перекрывает кнопку и не режет текст даже на 390px.
   Числа подтянуты (раунд 5): слот держит не всю высоту индикатора, а только её
   часть — остальное индикатор занимает в УЖЕ существующем нижнем padding'е .dlg-mp
   (16px на десктопе, 14px+safe-area в мобильном медиа-запросе), сместившись туда
   через bottom:-14px. Инвариант, из которого взяты числа: индикатор высотой 26px не
   должен подниматься выше слота, иначе он перекроет кнопку/чекбоксы/чипы, т.е.
   26 - смещение ≤ слот → 26 - 14 = 12. Смещение при этом не больше нижнего padding'а
   контейнера (14 ≤ 14 на мобиле, ≤ 16 на десктопе), иначе индикатор вышел бы за
   padding-box и обрезался. Итог: зазор в покое 30/28px на десктопе и 26px на мобиле
   вместо 52/50 и 48 — при тех же нулях по перекрытию, сдвигу и росту scrollHeight. */
#dlg-mp-bottom { position: relative; padding-bottom: 12px; }
#dlg-mp-progress { position: absolute; left: 0; right: 0; bottom: -14px; margin-top: 0; }
.dlg-mp-progress-bar { height: 4px; border-radius: 2px; background: #232327; overflow: hidden; }
.dlg-mp-progress-fill {
  height: 100%; border-radius: 2px;
  background: linear-gradient(90deg, var(--g, #2AABEE), var(--g2, #229ED9));
  transition: width .12s linear;
}
/* Байты долетели (loaded>=total), но сервер ещё режет/льёт куски — процент
   врать нечем, поэтому вместо мёртвых 100% гоняем полоску туда-сюда, чтобы
   было видно, что процесс жив. */
.dlg-mp-progress-fill.indeterminate {
  width: 40% !important;
  animation: dlg-mp-progress-indeterminate 1.1s ease-in-out infinite;
}
@keyframes dlg-mp-progress-indeterminate {
  0% { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}
.dlg-mp-progress-text { font-size: 11px; color: #8b929c; text-align: right; }

/* Касса: цена + сплит-кнопка канала для платного лота/пака — одна строка */
.dlg-mp-kassa { display: flex; align-items: center; gap: 8px; }
.dlg-mp-kassa-thumb { flex: none; width: 40px; height: 40px; border-radius: 8px; overflow: hidden; background: #131316; }
.dlg-mp-kassa-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.dlg-mp-kassa-thumb-ph { width: 100%; height: 100%; background: linear-gradient(135deg,#1a1a1e,#131316); }
/* стандалон-поле цены (upload-пак) — во всю строку */
.dlg-mp-kassa-price {
  position: relative;
  display: flex; align-items: center; gap: 7px; padding: 0 11px; min-width: 0;
  background: #0c0c10; border: 1px solid #232327; border-radius: 10px;
  transition: border-color .15s var(--ease-out);
}
.dlg-mp-kassa-price:focus-within { border-color: var(--g); }
/* Плашка «ты получишь» — поповер под полем цены (зеркало .scn-lad-dropp):
   position:absolute → ноль reflow, всплывает на hover/focus-within пилюли цены. */
.dlg-mp-breakdown {
  position: absolute; bottom: calc(100% + 7px); top: auto; left: 0; z-index: 40;
  min-width: 196px; width: max-content; max-width: 300px;
  padding: 9px 11px; text-align: left;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 2px 6px rgba(0,0,0,.28), 0 16px 38px -14px rgba(0,0,0,.6);
  opacity: 0; pointer-events: none;
  transform: translateY(4px) scale(.96); transform-origin: bottom left;
  transition: opacity .16s var(--ease-out), transform .16s var(--ease-out);
}
.dlg-mp-breakdown:empty { display: none; }
.dlg-mp-kassa-price:hover .dlg-mp-breakdown,
.dlg-mp-kassa-price:focus-within .dlg-mp-breakdown {
  opacity: 1; pointer-events: auto; transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .dlg-mp-breakdown { transform: none; }
  .dlg-mp-kassa-price:hover .dlg-mp-breakdown,
  .dlg-mp-kassa-price:focus-within .dlg-mp-breakdown { transform: none; }
}
/* поле цены внутри кассы-строки — фикс 68px по центру, акцент-рамка, жирное значение */
.dlg-mp-kassa .dlg-mp-kassa-price { flex: none; width: 68px; justify-content: center; gap: 2px; padding: 0 6px; border-color: #2AABEE44; }
.dlg-mp-kassa-hint { color: #8b929c; font-size: 12px; flex: none; }
.dlg-mp-kassa .dlg-mp-kassa-hint { color: #7cc9f2; font-weight: 700; }
.dlg-mp-kassa-static { color: #7cc9f2; font-size: 13px; font-weight: 700; padding: 8px 0; width: 100%; text-align: center; }
.dlg-mp-price-ovr { flex: 1; min-width: 0; padding: 8px 0; background: transparent; border: 0; color: #e3e6ea; font-size: 13px; }
.dlg-mp-price-ovr:focus { outline: none; }
.dlg-mp-kassa .dlg-mp-price-ovr { text-align: center; color: #7cc9f2; font-weight: 700; }
.dlg-mp-kassa-mid { flex: 1; min-width: 0; color: #8b929c; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#dlg-mp-kassa-actions, #dlg-mp-group-actions, #dlg-mp-upload-pack-actions, #dlg-mp-single-actions { flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.dlg-mp-kassa-err { color: #e0554f; font-size: 11px; text-align: right; }
.dlg-mp-split { position: relative; display: inline-flex; align-items: stretch; }
/* Полный радиус по умолчанию — стрелки рядом может не быть (бесплатная отправка,
   один канал, дизейбл). Срезаем правые углы только когда за кнопкой РЕАЛЬНО
   следует .dlg-mp-split-arrow — иначе главная кнопка выглядит обрубленной справа
   (симптом с прода: «Отправить пак бесплатно» без стрелки). :has() уже принят в
   проекте (см. .nav-item.active:has(...), .parser-acc-dd:has(...) и др. в этом файле). */
.dlg-mp-split-main { min-width: 0; padding: 9px 16px; border-radius: var(--r-ctl); }
.dlg-mp-split-main:has(+ .dlg-mp-split-arrow) { border-radius: var(--r-ctl) 0 0 var(--r-ctl); }
.dlg-mp-split-arrow {
  display: flex; align-items: center; padding: 0 11px; margin-left: 1px;
  background: linear-gradient(135deg, var(--g, #2AABEE), var(--g2, #229ED9));
  color: #fff; border: 0; border-left: 1px solid rgba(0,0,0,.2);
  border-radius: 0 var(--r-ctl) var(--r-ctl) 0; cursor: pointer; font-size: 11px;
  transition: filter .15s var(--ease-out), transform .16s var(--ease-out);
}
.dlg-mp-split-arrow:active:not(:disabled) { transform: scale(.97); }
.dlg-mp-split-arrow:disabled { opacity: .5; cursor: not-allowed; }
.dlg-mp-split-menu {
  position: absolute; right: 0; bottom: calc(100% + 6px); z-index: 5;
  background: #1f1f24; border: 1px solid #2c2c31; border-radius: var(--r-ctl);
  box-shadow: 0 8px 24px rgba(0,0,0,.4); overflow: hidden; min-width: 200px;
  transform-origin: bottom right;
  transition: opacity .15s var(--ease-out), transform .15s var(--ease-out);
}
.dlg-mp-split-menu[hidden] { display: block; opacity: 0; transform: scale(.95); pointer-events: none; }
.dlg-mp-split-item {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 10px 14px;
  background: transparent; border: 0; color: #e3e6ea; font-size: 13px; text-align: left;
  cursor: pointer; white-space: nowrap;
}
/* hover-эффекты — только под настоящей мышью (тач-тап не должен их триггерить) */
@media (hover: hover) and (pointer: fine) {
  .dlg-mp-chip:hover:not(.on) { border-color: var(--g); color: var(--t1); }
  .dlg-mp-close:hover { color: #cfd3d8; }
  .dlg-mp-card:hover .dlg-mp-zoom { opacity: 1; }
  .dlg-mp-zoom:hover { background: rgba(0,0,0,.85); }
  .dlg-mp-drop:hover { border-color: var(--g); background: #131316; }
  .dlg-mp-send:hover:not(:disabled) { filter: brightness(1.07); }
  .dlg-mp-split-arrow:hover:not(:disabled) { filter: brightness(1.07); }
  .dlg-mp-split-item:hover:not(:disabled) { background: #26262c; }
  .dlg-mp-note-edit:hover { color: #cfd3d8; border-color: rgba(42,171,238,.4); }
}

/* Просмотр набора: оверлей со всеми членами пака. Слой 1050 — над пикером
   (backdrop 1000), под лайтбоксом (1100): тап по плитке открывает полный
   просмотр члена ПОВЕРХ оверлея. */
.dlg-mp-ppv {
  position: fixed; inset: 0; z-index: 1050;
  background: rgba(0,0,0,.72);
  display: flex; align-items: center; justify-content: center;
}
.dlg-mp-ppv-panel {
  width: 440px; max-width: 92vw; max-height: 80vh; overflow: auto;
  background: #000; border: 1px solid #1e1e26; border-radius: 14px; padding: 14px;
  animation: dlg-mp-in 120ms var(--ease-out);
}
@media (prefers-reduced-motion: reduce) { .dlg-mp-ppv-panel { animation: none; } }
.dlg-mp-ppv-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 10px; color: #e8eaed; font-size: 13px; font-weight: 600;
}
.dlg-mp-ppv-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.dlg-mp-ppv-cell {
  position: relative; aspect-ratio: 3/4; border-radius: 10px; overflow: hidden;
  background: #131316; cursor: pointer;
}
.dlg-mp-ppv-cell img { width: 100%; height: 100%; object-fit: cover; display: block; background: #000; }

/* Свой конфирм закрытия пикера (вместо нативного confirm) — слой 1060. */
.dlg-mp-confirm {
  position: fixed; inset: 0; z-index: 1060;
  background: rgba(0,0,0,.6);
  display: flex; align-items: center; justify-content: center;
}
.dlg-mp-confirm-panel {
  width: 320px; max-width: 88vw;
  background: #0f0f13; border: 1px solid #26262c; border-radius: 14px;
  padding: 18px; display: flex; flex-direction: column; gap: 14px;
  animation: dlg-mp-in 120ms var(--ease-out);
}
@media (prefers-reduced-motion: reduce) { .dlg-mp-confirm-panel { animation: none; } }
.dlg-mp-confirm-text { color: #e3e6ea; font-size: 13px; line-height: 1.45; }
.dlg-mp-confirm-actions { display: flex; justify-content: flex-end; gap: 8px; }
.dlg-mp-confirm-actions .dlg-mp-chip { padding: 8px 14px; font-size: 12px; }
.dlg-mp-confirm-actions .dlg-mp-send { padding: 8px 16px; }

/* Мобильный пикер: bottom-sheet на всю ширину, сетка 3 колонки, касса
   переносом (подпись/середина — своей строкой), счётчик в шапке скрыт. */
@media (max-width: 560px) {
  #dlg-mp-modal.dlg-modal-backdrop { align-items: stretch; }
  .dlg-mp {
    width: 100%; max-width: 100%; height: 100dvh; max-height: 100dvh;
    border-radius: 0; border: 0;
    padding: calc(12px + env(safe-area-inset-top)) 12px calc(14px + env(safe-area-inset-bottom));
  }
  .dlg-mp-count { display: none; }
  .dlg-mp-title { font-size: 13px; }
  .dlg-mp-head { gap: 8px; }
  .dlg-mp-head-right { gap: 8px; }
  .dlg-mp-maintabs .seg-btn { padding: 5px 10px; }
  .dlg-mp-grid { grid-template-columns: repeat(3, 1fr); gap: 6px; }
  .dlg-mp-kassa { flex-wrap: wrap; row-gap: 8px; }
  .dlg-mp-kassa-mid { order: 10; flex: 1 1 100%; }
  #dlg-mp-kassa-actions, #dlg-mp-group-actions, #dlg-mp-upload-pack-actions, #dlg-mp-single-actions,
  .dlg-mp-kassa > .dlg-mp-foot-send { margin-left: auto; }
  .dlg-mp-split-main { padding: 9px 12px; }
  .dlg-mp-ppv { align-items: flex-end; }
  .dlg-mp-ppv-panel { width: 100%; max-width: 100%; border-radius: 14px 14px 0 0; }
}

/* B4: Voice picker modal — custom mini-player */
/* Voice composer (inline) */
.dlg-vc-pending {
  flex: 1; padding: 6px 10px; color: #8b929c; font-size: 12px;
  display: flex; align-items: center; gap: 8px;
}
.dlg-vc-pending::before {
  content: ''; width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid #232327; border-top-color: var(--g2, #229ED9);
  animation: dlg-vc-spin .8s linear infinite;
}
@keyframes dlg-vc-spin { to { transform: rotate(360deg); } }
.dlg-vc-play {
  background: linear-gradient(135deg, var(--g, #2AABEE), var(--g2, #229ED9));
  color: #fff; border: 0;
  width: 30px; height: 30px; padding: 0;
  border-radius: 50%; cursor: pointer; line-height: 0;
  display: inline-flex; align-items: center; justify-content: center;
  align-self: center; flex-shrink: 0;
}
.dlg-vc-play .vc-icn-pause { display: none; }
.dlg-vc-play.playing .vc-icn-play  { display: none; }
.dlg-vc-play.playing .vc-icn-pause { display: block; }
.dlg-vc-play .vc-icn-play { transform: translateX(1px); }
.dlg-vc-wave {
  flex: 1; height: 32px; align-self: center;
  display: flex; align-items: center; justify-content: space-between;
  gap: 2px; padding: 0 6px; cursor: pointer;
}
.dlg-vc-wave > span {
  flex: 1; min-width: 2px;
  height: calc(100% * var(--h, 0.15));
  min-height: 3px;
  background: #232327; border-radius: 2px;
  transition: background .12s linear;
}
.dlg-vc-wave > span.played { background: var(--g2, #229ED9); }
.dlg-vc-time {
  align-self: center; font-size: 11px; color: #8b929c;
  min-width: 38px; text-align: right;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

.mv-preview-circle {
  border-radius: 50%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

/* Video-note editor modal — z-index 1150, см. легенду слоёв у .dlg-modal-backdrop
   (поверх пикера: редактор кружка открывается из его формы заливки). */
.video-edit-modal {
  position: fixed; inset: 0; z-index: 1150;
  background: rgba(0,0,0,0.85);
  display: flex; align-items: center; justify-content: center;
}
.vem-content {
  background: var(--bg, #1a1a1a); color: var(--t1, #fff);
  border-radius: var(--r-card); padding: 20px;
  display: flex; flex-direction: column; gap: 14px;
  max-width: 90vw; max-height: 90vh;
}
.vem-head { display: flex; justify-content: space-between; align-items: center; }
.vem-head h3 { margin: 0; font-size: 16px; }
.vem-head .vem-close { cursor: pointer; font-size: 20px; opacity: 0.7; }
.vem-head .vem-close:hover { opacity: 1; }
.vem-preview {
  position: relative;
  max-width: 70vw; max-height: 60vh;
  display: flex; align-items: center; justify-content: center;
  background: #000; border-radius: var(--r-card); overflow: hidden;
}
.vem-preview video { display: block; max-width: 100%; max-height: 60vh; }
.vem-crop-frame {
  position: absolute;
  border: 2px solid white;
  box-shadow: 0 0 0 9999px rgba(0,0,0,0.5);
  cursor: move;
  touch-action: none;
  box-sizing: border-box;
}
.vem-trim-section { display: flex; flex-direction: column; gap: 6px; }
.vem-trim-label { font-size: 13px; opacity: 0.85; }
.vem-trim-track {
  position: relative; height: 32px;
  background: rgba(255,255,255,0.1); border-radius: 16px;
}
.vem-trim-range {
  position: absolute; top: 0; bottom: 0;
  background: rgba(79, 140, 255, 0.4);
  border-radius: 16px;
  pointer-events: none;
}
.vem-trim-handle {
  position: absolute; top: -4px;
  width: 16px; height: 40px;
  background: white; border-radius: 8px;
  cursor: ew-resize; touch-action: none;
  transform: translateX(-50%);
}
.vem-buttons { display: flex; justify-content: flex-end; gap: 10px; }


/* Dual-transport: per-account capability бейджи в списке аккаунтов. */
.acct-cap-badge {
  padding: 2px 7px;
  border-radius: 6px;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
  cursor: default;
}
.acct-cap-badge.dual   { background: #2d6df0; color: #fff; }
.acct-cap-badge.gramjs { background: #232327; color: #a8a8ad; }

/* Attach Telegram Business modal (single-bot) */
.attach-bot-username {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  padding: 10px 12px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: var(--r-ctl);
}
.attach-bot-username-code {
  flex: 1;
  font-family: var(--ff-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 15px;
  font-weight: 600;
  color: var(--t1);
  background: transparent;
  letter-spacing: 0.01em;
  user-select: all;
}
.attach-bot-username-code.is-copied { color: #6cd66c; }
.attach-bot-steps {
  margin: 14px 0 0 0;
  padding-left: 20px;
  color: var(--t2);
  line-height: 1.5;
}
.attach-bot-steps li { margin: 6px 0; }
.attach-bot-hint { color: var(--t3, #888); font-size: 0.92em; }

/* Translation bubble layers */
.dlg-msg-text { line-height: 1.4; cursor: pointer; }
.dlg-msg-text.translating-pending,
/* расшифровка голосового ждёт перевода так же, как обычный текст */
.dlg-voice-tr.translating-pending { opacity: 0.55; font-style: italic; }
.dlg-msg-orig {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
  font-size: 11.5px;
  color: var(--text-2);
  line-height: 1.35;
}
.dlg-msg-orig[data-show="0"] { display: none; }
.dlg-msg-orig.operator::before { content: "✍️ "; }
/* On out-bubbles (var(--green-dim) background) the muted --text-2 grey is
   too low-contrast. Force a higher-opacity inherit so the original reads. */
.dlg-msg.out .dlg-msg-orig {
  color: rgba(255,255,255,0.78);
  border-top-color: rgba(255,255,255,0.25);
}

/* Edit/Delete modal shared styles (модалка перевода удалена — перевод инлайн) */
#dlg-edit-modal .dtm-title,
#dlg-delete-modal .dtm-title {
  font-size: 13px; font-weight: 600; color: #e3e6ea;
}
#dlg-edit-modal .dtm-lbl,
#dlg-delete-modal .dtm-lbl {
  font-size: 10px; text-transform: uppercase; letter-spacing: .5px;
  opacity: .55; color: #cfd3d8; margin: 4px 0 -4px;
}
#dlg-edit-modal .dtm-en,
#dlg-delete-modal .dtm-en {
  font: inherit; font-size: 13px; color: #e3e6ea; line-height: 1.45;
  background: #131316;
  border: 1px solid rgba(255,255,255,.08);
  border-radius: var(--r-ctl); padding: 9px 11px; min-height: 72px;
  resize: vertical; outline: none;
  transition: border-color .15s, box-shadow .15s;
}
#dlg-edit-modal .dtm-en:focus,
#dlg-delete-modal .dtm-en:focus {
  border-color: var(--g, #2AABEE);
  box-shadow: 0 0 0 3px rgba(42,171,238,.18);
}
#dlg-edit-modal .dtm-actions,
#dlg-delete-modal .dtm-actions {
  display: flex; gap: 8px; justify-content: flex-end; margin-top: 2px;
}
#dlg-edit-modal .dtm-btn,
#dlg-delete-modal .dtm-btn {
  padding: 8px 16px; border-radius: var(--r-ctl);
  font-size: 12.5px; font-weight: 600; cursor: pointer;
  border: 1px solid rgba(255,255,255,.1);
  background: rgba(255,255,255,.05); color: #cfd3d8;
  transition: background .15s, border-color .15s, color .15s;
  font-family: inherit;
}
#dlg-edit-modal .dtm-btn:hover,
#dlg-delete-modal .dtm-btn:hover {
  background: rgba(255,255,255,.09); color: #e3e6ea;
}
#dlg-edit-modal .dtm-btn.primary,
#dlg-delete-modal .dtm-btn.primary {
  background: var(--accent); color: #04121b; border-color: var(--accent);
  font-weight: 700; box-shadow: none;
}
#dlg-edit-modal .dtm-btn.primary:hover,
#dlg-delete-modal .dtm-btn.primary:hover { filter: brightness(1.06); box-shadow: 0 0 22px var(--accent-glow); }

/* Исходящий перевод: ошибка отправки — ⚠ маркер + тап-меню (ноль хрома) */
.dlg-tx-warn { color: #ff6b6b; font-weight: 700; margin-left: 6px; cursor: pointer; font-size: 12px; }
.dlg-tx-menu {
  position: absolute; right: 8px; bottom: -6px; transform: translateY(100%); z-index: 20;
  background: #1a1a1e; border: 1px solid var(--border); border-radius: var(--r-ctl);
  box-shadow: 0 12px 32px rgba(0,0,0,.5); overflow: hidden;
  display: flex; flex-direction: column; min-width: 190px;
}
.dlg-tx-menu button {
  background: none; border: none; border-bottom: 1px solid var(--border);
  color: #e3e6ea; text-align: left; padding: 9px 14px;
  font-size: 12.5px; cursor: pointer; font-family: inherit;
}
.dlg-tx-menu button:last-child { border-bottom: none; }
.dlg-tx-menu button:first-child { color: var(--accent); }
.dlg-tx-menu button:hover { background: rgba(255,255,255,.06); }

/* Hover-actions on bubbles */
.dlg-msg { position: relative; }
.dlg-msg-actions {
  position: absolute; top: -6px;
  opacity: 0; transition: opacity .15s;
  display: flex; gap: 4px;
}
.dlg-msg.out .dlg-msg-actions { right: -6px; }
.dlg-msg.in  .dlg-msg-actions { left: -6px; }
.dlg-msg:hover .dlg-msg-actions { opacity: 1; }
.dlg-msg-actions button {
  width: 24px; height: 24px; padding: 0;
  border-radius: 50%;
  background: #1a1a1e;
  border: 1px solid rgba(255,255,255,.08);
  color: #cfd3d8;
  cursor: pointer; font-size: 12px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.dlg-msg-actions button:hover {
  background: #1a1a1e; color: #e3e6ea;
}

/* Reply bar above composer */
#dlg-reply-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; margin: 0 16px 6px;
  background: rgba(255,255,255,.04);
  border-left: 2px solid var(--g, #2AABEE);
  border-radius: 6px;
  font-size: 12px; color: #cfd3d8;
}
#dlg-reply-bar .reply-icon { color: var(--g, #2AABEE); flex: none; }
#dlg-reply-bar .reply-text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#dlg-reply-bar button {
  background: transparent; border: none; color: var(--text-2);
  cursor: pointer; padding: 2px 6px; font-size: 12px;
}

/* Reply quote inside an incoming/outgoing bubble — показывает, на какое
   сообщение это сообщение является ответом (зеркало Telegram-цитаты). */
.dlg-reply-quote {
  display: flex; flex-direction: column; gap: 1px;
  margin: 0 0 5px; padding: 3px 8px;
  border-left: 3px solid var(--g, #2AABEE);
  border-radius: 4px;
  background: rgba(127,127,127,.12);
  cursor: pointer; max-width: 100%; min-width: 0;
  line-height: 1.3;
}
.dlg-reply-quote:hover { background: rgba(127,127,127,.2); }
.dlg-reply-quote .rq-author { font-size: 11px; font-weight: 600; color: var(--g, #2AABEE); }
.dlg-reply-quote .rq-text {
  font-size: 11.5px; opacity: .72;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* На media-без-подписи пузырь прозрачный — даём цитате собственный фон/отступ. */
.dlg-msg--media:not(.dlg-msg--cap) .dlg-reply-quote { margin: 0 0 4px; }
/* На out-пузыре (зелёный фон) акцент/текст должны читаться поверх него. */
.dlg-msg.out .dlg-reply-quote { border-left-color: rgba(255,255,255,.6); background: rgba(255,255,255,.12); }
.dlg-msg.out .dlg-reply-quote:hover { background: rgba(255,255,255,.2); }
.dlg-msg.out .dlg-reply-quote .rq-author { color: rgba(255,255,255,.92); }
/* Подсветка-вспышка при переходе к исходному сообщению по клику на цитату. */
@keyframes dlgMsgFlash {
  0% { box-shadow: 0 0 0 2px var(--g, #2AABEE); }
  100% { box-shadow: 0 0 0 2px transparent; }
}
.dlg-msg--flash { animation: dlgMsgFlash 1.3s var(--ease-out, ease-out); }

/* Edit/Delete modals — re-use translate-modal styles */
#dlg-edit-modal, #dlg-delete-modal {
  position: fixed; inset: 0; z-index: 1000;
  background: rgba(0,0,0,.6);
  display: flex; align-items: center; justify-content: center;
}
#dlg-edit-modal .dtm-box, #dlg-delete-modal .dtm-box {
  background: #1a1a1e; border: 1px solid rgba(255,255,255,.06);
  border-radius: var(--r-card); padding: 16px 18px;
  width: min(560px, 92vw); color: #cfd3d8; font-size: 13px;
  display: flex; flex-direction: column; gap: 12px;
  box-shadow: 0 24px 60px rgba(0,0,0,.5);
}
.dtm-btn.danger {
  background: rgba(248,113,113,.12); color: var(--red, #f87171);
  border-color: rgba(248,113,113,.28);
}
.dtm-btn.danger:hover {
  background: rgba(248,113,113,.22); border-color: rgba(248,113,113,.45);
}

/* ── ЭТАП 1: Top header navigation (replaces sidebar) ─────────────── */
.layout{flex-direction:column;padding:0;gap:0}

/* z-index:70 — шапка создаёт КОНТЕКСТ НАЛОЖЕНИЯ, поэтому её меню и поповеры
   (hdr-user-menu / hdr-more-menu z-index:30, energy-popover z-index:50) снаружи
   считаются единым слоем со значением самой шапки, а не своими числами. На
   прежних 5 их перекрывал тултип графика дашборда (.dash-tip, position:fixed
   z-index:60): наведение на график поверх открытого поповера закрывало кнопку
   «Активировать». Поднимать z-index самого поповера бесполезно — он заперт в
   этом контексте. 70 выше тултипа, но ниже модалок (1000), панелей действий
   (9998), лайтбокса (10000) и тостов (10001) — они обязаны перекрывать шапку. */
.app-header{
  position:relative;z-index:70;flex-shrink:0;
  display:flex;align-items:center;gap:18px;
  height:var(--hdr-h);padding:0 18px;
  background:linear-gradient(180deg,#131316,#0a0a0c);
  border-bottom:1px solid #1c1c20;
  box-shadow:0 1px 0 rgba(255,255,255,.025) inset,0 6px 22px -16px rgba(0,0,0,.9);
}
.hdr-left{display:flex;align-items:center;gap:12px;flex-shrink:0}
.hdr-burger{display:none;background:none;border:none;cursor:pointer;color:#c9c9d2;padding:6px;border-radius:var(--r-ctl)}
.hdr-burger svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.hdr-brand{display:flex;align-items:center;gap:10px;color:#fff;font-family:var(--ff-head);font-weight:700;font-size:17px;white-space:nowrap}
.hdr-mk{width:26px;height:26px;border-radius:var(--r-ctl);background:var(--accent-grad);display:flex;align-items:center;justify-content:center;box-shadow:0 0 14px rgba(160,80,255,.45)}
.hdr-mk svg{width:15px;height:15px;fill:none;stroke-linecap:round;stroke-linejoin:round}
/* PODIUM wordmark + neon glow (эмуляция Figma drop-shadow: FF0059 100% blur24 + FF008C 30% blur52, spread→стопка) */
.hdr-mark{position:relative;display:block;line-height:0}
.hdr-logo-svg{display:block;height:18px;width:auto}
/* свечение как на ленде: размытая копия дышит, при наведении разгорается */
.hdr-logo-glow{position:absolute;left:0;top:0;filter:blur(6px);pointer-events:none;
  transition:filter .4s ease;animation:hdrLogoBreath 3.6s ease-in-out infinite}
@keyframes hdrLogoBreath{0%,100%{opacity:.55}50%{opacity:1}}
.hdr-brand:hover .hdr-logo-glow{filter:blur(9px);animation-play-state:paused}
@media (prefers-reduced-motion:reduce){.hdr-logo-glow{animation:none}}

/* SVG icons in header — stroke style, NOT emoji */
.app-header .nav-icon svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;display:block}

/* Primary nav */
.hdr-nav{display:flex;align-items:center;gap:4px;flex:1;min-width:0}
.app-header .nav-item{
  display:flex;align-items:center;gap:8px;
  padding:8px 13px;border-radius:var(--r-ctl);
  color:#9a98a4;font-size:13.5px;font-weight:500;
  cursor:pointer;white-space:nowrap;position:relative;margin:0;
  transition:color .18s var(--ease-out),background-color .18s var(--ease-out),transform .12s var(--ease-out);
}
.app-header .nav-item .nav-icon{transition:color .18s var(--ease-out)}
.app-header .nav-item:hover{color:#fff;background:rgba(255,255,255,.055)}
.app-header .nav-item:active{transform:scale(.97)}
.app-header .nav-item.active{
  color:#fff;
  background:linear-gradient(135deg,rgba(224,64,251,.22),rgba(124,77,255,.2));
  box-shadow:inset 0 0 0 1px rgba(190,120,255,.34),0 2px 14px -6px rgba(160,80,255,.55);
}
.app-header .nav-item.active .nav-icon{color:#f3c8ff}
.app-header .nav-item.active::after{display:none}
.app-header .nav-label{line-height:1}
.app-header .nav-badge{
  margin-left:2px;min-width:18px;height:18px;padding:0 6px;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:10px;font-weight:700;line-height:1;color:#fff;
  font-feature-settings:"tnum";letter-spacing:.01em;
  background:var(--accent-grad);border-radius:20px;
  box-shadow:0 2px 8px -3px rgba(160,80,255,.6);
}
.app-header .nav-item.active .nav-badge{background:rgba(255,255,255,.92);color:#3a1546;box-shadow:none}
.app-header .nav-live-dot{width:7px;height:7px;border-radius:50%;background:var(--accent-1);box-shadow:0 0 8px var(--accent-1)}
.app-header .nav-live-dot.hidden{display:none}

/* «Ещё» dropdown */
.hdr-more{position:relative}
.hdr-more-btn{
  display:flex;align-items:center;gap:6px;
  background:none;border:none;cursor:pointer;
  padding:8px 13px;border-radius:var(--r-ctl);
  color:#9a98a4;font-size:13.5px;font-weight:500;font-family:inherit;position:relative;
  transition:color .18s var(--ease-out),background-color .18s var(--ease-out),transform .12s var(--ease-out);
}
.hdr-more-btn:hover{color:#fff;background:rgba(255,255,255,.055)}
.hdr-more-btn:active{transform:scale(.97)}
.hdr-caret{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;transition:.18s}
.hdr-more.hdr-open .hdr-caret{transform:rotate(180deg)}
.hdr-more:has(.nav-item.active) .hdr-more-btn{color:#fff;background:linear-gradient(135deg,rgba(224,64,251,.22),rgba(124,77,255,.22))}
.hdr-more-dot{display:none;position:absolute;top:6px;right:8px;width:6px;height:6px;border-radius:50%;background:var(--accent-1);box-shadow:0 0 7px var(--accent-1)}
.hdr-more:has(.nav-live-dot:not(.hidden)) .hdr-more-dot{display:block}

.hdr-more-menu{
  position:absolute;top:calc(100% + 8px);left:0;z-index:30;
  min-width:210px;padding:7px;
  background:#16151b;border:1px solid #28262f;border-radius:var(--r-card);
  box-shadow:0 22px 48px -22px rgba(0,0,0,.7);
  display:none;flex-direction:column;gap:2px;
  transform-origin:top left;
}
.hdr-more.hdr-open .hdr-more-menu{display:flex;animation:hdr-pop .16s var(--ease-out)}
@keyframes hdr-pop{from{opacity:0;transform:scale(.96) translateY(-4px)}to{opacity:1;transform:none}}
.hdr-more-menu .nav-item{width:100%}

/* Right cluster */
.hdr-right{display:flex;align-items:center;gap:9px;flex-shrink:0;margin-left:auto}
.hdr-icon-btn{
  width:32px;height:32px;border-radius:var(--r-ctl);background:rgba(255,255,255,.05);
  border:none;cursor:pointer;color:#b3b1bd;display:flex;align-items:center;justify-content:center;
  transition:color .18s var(--ease-out),background-color .18s var(--ease-out),transform .12s var(--ease-out);
}
.hdr-icon-btn:hover{background:rgba(255,255,255,.1);color:#fff}
.hdr-icon-btn:active{transform:scale(.93)}
.app-header .hdr-icon-nav{transition:color .18s var(--ease-out),background-color .18s var(--ease-out),transform .12s var(--ease-out)}
.app-header .hdr-icon-nav:active{transform:scale(.93)}
.hdr-icon-btn svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.app-header .hdr-icon-nav{padding:7px;border-radius:var(--r-ctl)}
.app-header .hdr-icon-nav .nav-icon svg{width:17px;height:17px}

/* ws-badge in header (override light-theme rule) */
.app-header .ws-badge{
  display:inline-flex;align-items:center;gap:7px;
  font-size:12px;font-weight:500;color:#9a98a4;
  padding:5px 11px;border-radius:999px;
  background:rgba(255,255,255,.04);border:1px solid rgba(255,255,255,.06);
  transition:color .2s var(--ease-out),background-color .2s var(--ease-out),border-color .2s var(--ease-out);
}
.app-header .ws-badge .ws-dot{width:7px;height:7px;border-radius:50%;background:#5b5b63;transition:background-color .2s var(--ease-out)}
.app-header .ws-badge.online,.app-header .ws-badge.live{
  color:#f1c6ec;background:rgba(224,64,251,.1);border-color:rgba(224,64,251,.24);
}
.app-header .ws-badge.online .ws-dot,.app-header .ws-badge.live .ws-dot{
  background:var(--accent-1);box-shadow:0 0 8px var(--accent-1);animation:ws-pulse 2s var(--ease-out-soft) infinite;
}
@keyframes ws-pulse{0%,100%{box-shadow:0 0 0 0 rgba(224,64,251,.5)}50%{box-shadow:0 0 0 4px rgba(224,64,251,0)}}
@media (prefers-reduced-motion:reduce){.app-header .ws-badge .ws-dot{animation:none}}

/* balance */
.hdr-balance{
  font-size:12px;color:#e3c2ff;white-space:nowrap;
  padding:5px 11px;border-radius:999px;
  background:linear-gradient(135deg,rgba(224,64,251,.12),rgba(124,77,255,.12));
  border:1px solid rgba(180,110,255,.26);
  transition:border-color .2s var(--ease-out),background-color .2s var(--ease-out);
}
.hdr-balance:hover{border-color:rgba(180,110,255,.45)}
.hdr-balance .balance-amount{color:inherit;font-weight:700;font-feature-settings:"tnum"}

/* user menu */
.hdr-user{position:relative}
.hdr-user-btn{background:none;border:none;cursor:pointer;padding:0;border-radius:50%;transition:transform .12s var(--ease-out)}
.hdr-user-btn:active{transform:scale(.93)}
.app-header .user-avatar-img{
  width:32px;height:32px;border-radius:50%;background:var(--accent-grad);
  display:flex;align-items:center;justify-content:center;color:#fff;font-size:13px;font-weight:600;overflow:hidden;
  box-shadow:0 0 0 1px rgba(255,255,255,.08),0 2px 10px -3px rgba(42,171,238,.5);
  transition:box-shadow .2s var(--ease-out);
}
.hdr-user-btn:hover .user-avatar-img{box-shadow:0 0 0 2px rgba(42,171,238,.55),0 2px 12px -2px rgba(42,171,238,.6)}
.hdr-user-btn:focus-visible{outline:2px solid rgba(42,171,238,.6);outline-offset:2px;border-radius:50%}
.app-header .user-avatar-img img{width:100%;height:100%;object-fit:cover}
.hdr-user-menu{
  position:absolute;top:calc(100% + 8px);right:0;z-index:30;
  min-width:190px;padding:13px;display:none;flex-direction:column;gap:11px;
  background:#16151b;border:1px solid #28262f;border-radius:var(--r-card);box-shadow:0 22px 48px -22px rgba(0,0,0,.7);
  transform-origin:top right;
}
.hdr-user.hdr-open .hdr-user-menu{display:flex;animation:hdr-pop .16s var(--ease-out)}
.hdr-user-name{display:flex;align-items:center;gap:8px;color:#fff;font-size:13.5px;font-weight:600;flex-wrap:wrap}
.hdr-user-menu .logout-btn{width:100%}

/* ── ЭТАП 1: header responsive → нав уехал в нижний таб-бар (#mtabbar) ── */
@media (max-width:860px){
  .hdr-brand-name{display:none}
  .hdr-nav{display:none}      /* горизонтальный хедер-нав скрыт — он теперь снизу */
  #hdr-burger{display:none}   /* бургер + верхний drawer больше не нужны */
  .hdr-balance{display:none}
  .topbar-logout-mobile{display:none}
}
@media (max-width:520px){
  .ws-badge #ws-label{display:none}
}

/* ── Мобильный нижний таб-бар (#mtabbar) + «Ещё» bottom-sheet (≤860) ── */
#mtabbar{display:none}
#more-sheet{display:none}
#mtabbar .nav-icon svg{width:22px;height:22px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;display:block}
#more-sheet .nav-icon svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;display:block}
@media (max-width:860px){
  /* отступ под таб-бар — на .main-content (сам контент), НЕ на .main:
     flex+overflow-контейнер браузеры не резервируют padding-bottom для скролла
     → последний контент прятался под баром. */
  .main-content{padding-bottom:calc(60px + var(--safe-b) + 16px)}
  #mtabbar{
    display:flex;position:fixed;left:0;right:0;bottom:0;z-index:120;
    height:calc(60px + var(--safe-b));padding-bottom:var(--safe-b);
    background:linear-gradient(180deg,#131316,#0a0a0c);
    border-top:1px solid #1c1c20;box-shadow:0 -6px 22px -16px rgba(0,0,0,.9);
  }
  #mtabbar .mtab-item{
    flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:4px;min-height:44px;margin:0;padding:6px 2px;border:0;border-radius:0;
    background:none;color:var(--t3);font-family:inherit;font-size:10px;font-weight:500;
    cursor:pointer;transition:color .15s var(--ease-out);
  }
  /* активный акцент — один сигнал: violet-капсула за иконкой + violet-лейбл
     (пилюля-за-иконкой = язык нижних баров; сплошная верхняя черта убрана) */
  #mtabbar .mtab-item .nav-icon{
    display:flex;align-items:center;justify-content:center;color:var(--t3);
    width:auto;height:auto;                 /* снять глобальный .nav-icon{width:20px;height:18px} —
                                               иначе border-box + padding даёт нулевой content-box → svg исчезает */
    padding:3px 14px;border-radius:13px;
    transition:background-color .18s var(--ease-out),color .15s var(--ease-out),transform .12s var(--ease-out);
  }
  #mtabbar .mtab-item span:last-child{line-height:1;white-space:nowrap}
  #mtabbar .mtab-item:active .nav-icon{transform:scale(.92)}   /* тактильный отклик на тап */
  /* Акцент навигации — голубой --g, а не бренд-магента: фиолет в этом файле
     закреплён за айдентикой (лого, хедер-марка), контрольный хром весь на --g
     (кнопки, фокус, чекбоксы). Таб-бар — контрол, а не логотип. */
  #mtabbar .mtab-item.active{color:var(--g)}
  #mtabbar .mtab-item.active .nav-icon{background:rgba(42,171,238,.15);color:var(--g)}
  /* глушим протёкшую синюю точку глобального .nav-item.active::after (бар + шит) */
  #mtabbar .mtab-item.active::after,
  .msheet-list .nav-item.active::after{display:none}
  /* «Ещё» bottom-sheet */
  #more-sheet{display:block;position:fixed;inset:0;z-index:200;visibility:hidden;transition:visibility 0s .24s}
  #more-sheet.open{visibility:visible;transition:visibility 0s 0s}
  .msheet-backdrop{position:absolute;inset:0;background:rgba(0,0,0,.55);opacity:0;transition:opacity .22s var(--ease-out)}
  #more-sheet.open .msheet-backdrop{opacity:1}
  .msheet-panel{
    position:absolute;left:0;right:0;bottom:0;
    background:linear-gradient(180deg,#16151b,#0e0d12);
    border-top:1px solid #28262f;border-radius:18px 18px 0 0;
    padding:8px 12px calc(16px + var(--safe-b));max-height:80dvh;overflow-y:auto;
    transform:translateY(101%);transition:transform .24s var(--ease-out);
  }
  #more-sheet.open .msheet-panel{transform:translateY(0)}
  .msheet-grab{width:38px;height:4px;border-radius:2px;background:#3a3a42;margin:8px auto 12px}
  .msheet-list{display:flex;flex-direction:column;gap:2px}
  .msheet-list .nav-item{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;
    gap:12px;min-height:46px;padding:10px 12px;font-size:14px}
  .msheet-list .nav-item .nav-icon{flex:0 0 auto;display:flex}
  .msheet-list .nav-item.active{color:var(--g);background:rgba(42,171,238,.1)}
}

/* Page-access: выключенные ("в разработке") пункты навигации */
.nav-item.nav-disabled {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}
.nav-wip-badge {
  margin-left: 6px;
  font-size: 10px;
  line-height: 1;
  padding: 2px 5px;
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.08);
  color: var(--text-muted, #9aa);
  white-space: nowrap;
  vertical-align: middle;
}

/* ════════════════════════════════════════════════════════════════════
   EMIL POLISH LAYER — универсальные микровзаимодействия (Batch 1)
   Применяется ко всей платформе. Только transform/opacity + кастомные
   easing. Цвета/раскладку не трогает. Уважает prefers-reduced-motion
   (глобальный guard в строке 22 отключает все анимации/transition).
   ════════════════════════════════════════════════════════════════════ */

/* — Press feedback: интерфейс «слышит» нажатие. scale subtle 0.96–0.97 — */
.btn, .btn-sm, .seg-btn, .bulk-bar__btn, .acc-proxy-pill, .status-pill, .dlg-seg span, .dlg-comp button, .tone-card, .lang-mode-row, .stab-btn, .chip-bank-option, .editchar-tab, .modal .btn, .modal-box .btn {
  transition: transform .14s var(--ease-out),
              background-color .18s var(--ease-out),
              border-color .18s var(--ease-out),
              color .18s var(--ease-out),
              box-shadow .2s var(--ease-out),
              filter .18s var(--ease-out);
}
.btn:active, .btn-sm:active, .seg-btn:active, .bulk-bar__btn:active, .acc-proxy-pill:active, .status-pill:active, .dlg-seg span:active, .dlg-comp button:active, .tone-card:active, .lang-mode-row:active, .stab-btn:active, .chip-bank-option:active, .editchar-tab:active, .modal .btn:active, .modal-box .btn:active {
  transform: scale(.97);
}
/* мелкие иконочные кнопки жмём чуть сильнее (как в хедере) */
.dlg-sum-close:active,
.dlg-mp-close:active,
.vem-close:active,
.chip-remove:active,
.parser-chip-x:active,
.parser-chip-add:active { transform: scale(.92); }

/* — Модалки: появление из центра (origin центр — для модалок корректно,
     они не привязаны к триггеру). Ничего не возникает из scale(0). — */
.modal-overlay { animation: emil-overlay-in .18s var(--ease-out); }
.modal-overlay > .modal,
.modal-overlay > .modal-box,
.modal,
.modal-box { animation: emil-modal-in .22s var(--ease-out); }
@keyframes emil-overlay-in { from { opacity: 0 } to { opacity: 1 } }
@keyframes emil-modal-in {
  from { opacity: 0; transform: scale(.96) }
  to   { opacity: 1; transform: none }
}

/* — Hover-«подъём» вместо резкой смены: лёгкий transform у карточек-кнопок — */
.tone-card:not(.selected):hover,
.lang-mode-row:not(.selected):hover { transform: translateY(-1px); }
/* лёгкое размытие фона под модалкой — премиальная подача, только когда модалка открыта */
.modal-overlay { backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px); }

/* ════════════════════════════════════════════════════════════════════
   DARK DEPTH (Batch 4) — паритет глубины для тёмной темы.
   На тёмном фоне глубину даёт верхний внутренний хайлайт («свет сверху»)
   + мягкая тёмная drop-тень, а не насыщенная цветная тень.
   Scoped [data-theme="dark"] → светлая тема не тронута.
   ════════════════════════════════════════════════════════════════════ */
[data-theme="dark"]{
  --shadow-card:inset 0 1px 0 rgba(255,255,255,.045), 0 6px 18px -10px rgba(0,0,0,.55);
  --shadow-card-hover:inset 0 1px 0 rgba(255,255,255,.07), 0 16px 36px -16px rgba(0,0,0,.66);
  --shadow-pop:inset 0 1px 0 rgba(255,255,255,.06), 0 24px 56px -16px rgba(0,0,0,.72);
}
[data-theme="dark"] .card,
[data-theme="dark"] .ov-card,
[data-theme="dark"] .set-card,
[data-theme="dark"] .add-card,
[data-theme="dark"] .panel-section,
[data-theme="dark"] .acc-sheet { box-shadow: var(--shadow-card); }

[data-theme="dark"] .card:hover,
[data-theme="dark"] .ov-card:hover,
[data-theme="dark"] .add-card:hover {
  box-shadow: var(--shadow-card-hover);
  border-color: rgba(255,255,255,.12);
}

[data-theme="dark"] .modal,
[data-theme="dark"] .modal-box { box-shadow: var(--shadow-pop); }

/* ════════════════════════════════════════════════════════════════════
   POLISH (Batch 5) — empty-states, тосты, tabular-nums, скроллбары
   ════════════════════════════════════════════════════════════════════ */

/* — 1. Empty-states: иконка + центрирование вместо голой серой строки — */
.dlg-empty, .parser-empty, .updates-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 12px; text-align: center; padding: 40px 20px;
  font-size: 14px; font-weight: 500; line-height: 1.5;
}
.dlg-empty::before, .parser-empty::before, .updates-empty::before {
  content: ''; width: 42px; height: 42px; flex: none; opacity: .45;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 13h4l2 3h6l2-3h4'/%3E%3Cpath d='M5 13V6a2 2 0 012-2h10a2 2 0 012 2v7'/%3E%3C/svg%3E") center/contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 13h4l2 3h6l2-3h4'/%3E%3Cpath d='M5 13V6a2 2 0 012-2h10a2 2 0 012 2v7'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* — 2. Тосты: выезд снизу + fade (пространственная логика Emil) — */
.app-toast--enter { animation: toast-in .26s var(--ease-out) both; }
@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, 10px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
@media (prefers-reduced-motion: reduce) {
  .app-toast--enter { animation: toast-fade .2s ease both; }
  .app-toast[data-hide="1"] { transform: translate(-50%, 0); }
  @keyframes toast-fade { from { opacity: 0; } to { opacity: 1; } }
}

/* — 3. Tabular-nums: моноширинные цифры в метриках/таблицах (не прыгают) — */
.acc-stat-card .num, .stat-mini-val, .ring .in b, .ov-stat b, .admin-stat-val, .stat-num, .big, .hdr-balance, .acc-table td, .dlg-pn-info, [class*="-val"], [class*="-num"] { font-variant-numeric: tabular-nums; }

/* — 4. Скроллбары: тонкие, тема-зависимые, единый стиль в скролл-зонах — */
.dlg-panel, .dlg-list, .dlg-conv, .dlg-body, .modal-box, .dlg-mp-grid, .editchar-body {
  scrollbar-width: thin;
  scrollbar-color: var(--scroll-thumb) transparent;
}
.dlg-panel::-webkit-scrollbar, .dlg-list::-webkit-scrollbar, .dlg-conv::-webkit-scrollbar, .dlg-body::-webkit-scrollbar, .modal-box::-webkit-scrollbar, .dlg-mp-grid::-webkit-scrollbar, .editchar-body::-webkit-scrollbar { width: 10px; height: 10px; }
.dlg-panel::-webkit-scrollbar-track, .dlg-list::-webkit-scrollbar-track, .dlg-conv::-webkit-scrollbar-track, .dlg-body::-webkit-scrollbar-track, .modal-box::-webkit-scrollbar-track, .dlg-mp-grid::-webkit-scrollbar-track, .editchar-body::-webkit-scrollbar-track { background: transparent; }
.dlg-panel::-webkit-scrollbar-thumb, .dlg-list::-webkit-scrollbar-thumb, .dlg-conv::-webkit-scrollbar-thumb, .dlg-body::-webkit-scrollbar-thumb, .modal-box::-webkit-scrollbar-thumb, .dlg-mp-grid::-webkit-scrollbar-thumb, .editchar-body::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb); border-radius: 8px;
  border: 2px solid transparent; background-clip: padding-box;
}
.dlg-panel::-webkit-scrollbar-thumb:hover, .dlg-list::-webkit-scrollbar-thumb:hover, .dlg-conv::-webkit-scrollbar-thumb:hover, .dlg-body::-webkit-scrollbar-thumb:hover, .modal-box::-webkit-scrollbar-thumb:hover, .dlg-mp-grid::-webkit-scrollbar-thumb:hover, .editchar-body::-webkit-scrollbar-thumb:hover {
  background: var(--scroll-thumb-hover); background-clip: padding-box;
}

/* ════════════════════════════════════════════════════════════════════
   POLISH (Batch 6) — плавная смена темы + skeleton-загрузка
   ════════════════════════════════════════════════════════════════════ */

/* — A1. Плавный переход при переключении темы (класс на <html> на ~320мс) — */
html.theme-anim,
html.theme-anim *,
html.theme-anim *::before,
html.theme-anim *::after {
  transition: background-color .26s var(--ease-out),
              color .26s var(--ease-out),
              border-color .26s var(--ease-out),
              box-shadow .26s var(--ease-out),
              fill .26s var(--ease-out) !important;
  transition-delay: 0s !important;
}

/* — A2. Skeleton-загрузка: shimmer-плейсхолдеры вместо «Загрузка…» — */
.skeleton {
  position: relative; overflow: hidden;
  background: var(--skel-base); border-radius: var(--r-ctl);
}
.skeleton::after {
  content: ''; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, var(--skel-sheen), transparent);
  animation: skel-shimmer 1.3s var(--ease-out-soft) infinite;
}
@keyframes skel-shimmer { to { transform: translateX(100%); } }
.skel-row { display: flex; gap: 10px; align-items: center; padding: 11px 12px; }
.skel-av { width: 34px; height: 34px; border-radius: 50%; flex: none; }
.skel-lines { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.skel-line { height: 10px; border-radius: 6px; }
.skel-line.w70 { width: 70%; }
.skel-line.w45 { width: 45%; }

/* Скелетон ленты сообщений (холодное открытие чата) */
.dlg-skel-conv { display: flex; flex-direction: column; gap: 12px; padding: 16px; }
.dlg-skel-row { display: flex; }
.dlg-skel-row.dlg-skel-right { justify-content: flex-end; }
.dlg-skel-bubble { height: 34px; border-radius: var(--r-card); max-width: 70%; }

/* ════════════════════════════════════════════════════════════════════
   RESPONSIVE + A11Y (Batch 7)
   Адаптив целит ЖИВУЮ раскладку (.app-header / .main / .dlg-wrap / таблицы);
   старый bottom-tab-bar блок (≤640) относился к мёртвому .sidebar.
   ════════════════════════════════════════════════════════════════════ */

/* — Единый keyboard-focus (только при навигации с клавиатуры) — */
button:focus-visible, a:focus-visible, [tabindex]:focus-visible,
.nc-pill:focus-visible, .status-pill:focus-visible, .seg-btn:focus-visible,
.nav-item:focus-visible, .chip-bank-option:focus-visible {
  outline: 2px solid var(--g); outline-offset: 2px; border-radius: var(--r-ctl);
}

/* min-width:0 — чтобы широкая таблица (min-width:680) скроллилась ВНУТРИ
   .acc-table-wrap, а не растягивала flex-контейнер .main-content наружу */
.main, .main-content{ min-width: 0; }
#page-accounts .acc-table-wrap{ max-width: 100%; }

/* — Планшет и уже (≤860, совпадает с брейкпоинтом хедера) — */
@media (max-width: 860px){
  .main-content{ padding: 18px 16px; }
  /* Диалоги: правая панель управления уходит — чат занимает её место (flex) */
  #page-dialogs .dlg-panel{ display: none; }
  /* Таблица аккаунтов: горизонтальный скролл вместо обреза (overflow:hidden) */
  #page-accounts .acc-table-wrap{ overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .acc-table{ min-width: 680px; }
  /* Статы 4 → 2 колонки */
  .acc-stats{ grid-template-columns: repeat(2, 1fr); }
}

/* — Телефон (≤560) — */
@media (max-width: 560px){
  .main-content{ padding: 14px 12px; }
  .main{ padding-bottom: 0; }   /* убрать фантомный отступ под несуществующий таб-бар */
  /* Диалоги: ужать рейл и список, чтобы окно диалога не схлопывалось */
  #page-dialogs .dlg-rail{ width: 52px; }
  #page-dialogs .dlg-list{ width: 44vw; min-width: 140px; max-width: 210px; }
  /* Статы плотнее */
  .acc-stats{ grid-template-columns: repeat(2, 1fr); gap: 8px; }
  /* Модалки: почти во весь экран, меньше паддинг */
  .modal, .modal-box{ padding: 18px; width: 94%; max-width: none; }
}

.hdr-icon-btn.active { color: #04121b; background: var(--accent); }
.hdr-icon-btn.active svg { stroke: #04121b; }

.dlg-ch .cav-wrap { position: relative; flex: none; }

/* ── МЕНЕДЖЕРЫ ─────────────────────────────────────────────────────── */
/* Тема-зависимые токены (--card/--line/--t*) — работает и в светлой, и в тёмной. */

/* Выбор аккаунтов в модалке менеджера: аватар + имя, кликабельная строка
   с состоянием выбора (вместо нативных галочек). Палитра/радиусы — канон. */
.mgr-acc-list {
  display: flex; flex-direction: column; gap: 6px;
  max-height: 280px; overflow-y: auto;
  margin: 2px -4px -2px; padding: 0 4px 2px;
}
.mgr-acc-opt {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 7px 10px; border-radius: var(--r-ctl);
  background: var(--ctl); border: 1px solid var(--line);
  text-align: left; cursor: pointer; font: inherit; color: inherit;
  transition: background .16s var(--ease-out),
              border-color .16s var(--ease-out),
              transform .12s var(--ease-out);
}
.mgr-acc-opt:hover { background: var(--mint); }
.mgr-acc-opt:active { transform: scale(.985); }
.mgr-acc-opt.is-on {
  border-color: var(--g);
  background: color-mix(in srgb, var(--g) 12%, transparent);
}
.mgr-acc-av {
  position: relative; width: 34px; height: 34px; flex: none; overflow: hidden;
  border-radius: 10px; display: flex; align-items: center; justify-content: center;
  font-family: var(--ff-head); font-weight: 700; font-size: 14px; color: var(--g2);
  background: color-mix(in srgb, var(--g) 14%, transparent);
}
.mgr-acc-av img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.mgr-acc-nm {
  flex: 1; min-width: 0; font-size: 14px; font-weight: 500; color: var(--t1);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mgr-acc-tick {
  width: 20px; height: 20px; flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line); color: transparent;
  transition: background .16s var(--ease-out),
              border-color .16s var(--ease-out),
              color .16s var(--ease-out);
}
.mgr-acc-tick svg { width: 12px; height: 12px; display: block; }
.mgr-acc-opt.is-on .mgr-acc-tick { background: var(--g); border-color: var(--g); color: #fff; }

/* ── Managers page: master-detail (список слева, панель справа) ──
   Живёт внутри .ndash (см. index.html) — .nbtn/.grouplbl/.cell-sub/.row-actions/
   .nd-empty/.pill наследуются оттуда, здесь только сам layout + .mgr-ch/.mgr-acct-row.
   Токены — корневые (--sheet/--card/--line/--t1..t3/--g), те же, что у Диалогов
   (.dlg-search, .dlg-catsel-…, .dlg-dot-… переиспользуются как есть, без переопределений).
   ВНИМАНИЕ: не писать в комментариях «звёздочка-слеш» подряд (напр. «.dlg-catsel*» + «/») —
   это закрывает комментарий досрочно и парсер съедает СЛЕДУЮЩЕЕ правило целиком.
   Ровно так тут годом ранее потерялась высота .zones. Пинится css-comment-integrity.test.js. */
/* Оболочка НЕ дублируется: .zones / .list / .detail / .list-hd / .u-search / .u-rows
   приезжают из блока «UNIFIED DLG SHELL» (~2285) — там же контраст колонок
   (.list = --card, .detail = --sheet), который и делает вид «как Диалоги».
   Здесь — только то, чего в системе нет, + посадка оболочки под шапку страницы. */
/* Высота — цепочкой от контейнера, БЕЗ viewport-математики.
   ИСТОРИЯ, чтобы не переоткрывать. Здесь стояло `#page-managers .zones { height:
   calc(100vh - 230px); min-height: 420px }` — и оно НИКОГДА не применялось: комментарий
   выше закрывался досрочно (в прозе шла звёздочка вплотную к слешу), и парсер съедал
   это правило целиком. .zones падал на глобальный `.zones{height:100%}` (:2567) от
   родителя с height:auto → схлопывался по контенту, отсюда «узкая коробка и пустота
   под ней». Формула была не виновата — её просто никто ни разу не видел.
   Цепочка теперь: .layout(100vh) → .main(flex:1) → #page-managers(100%) → .ndash(flex-col)
   → .zones(flex:1). Ни одно звено не auto, поэтому проценты резолвятся. Тот же приём,
   что у Диалогов (:2565, «robust, no viewport math»). Прежний floor min-height:420px
   не возвращён осознанно: он не работал и раньше, а #page-dialogs живёт без него. */
#page-managers { height: 100%; }
#page-managers .ndash { height: 100%; display: flex; flex-direction: column; }
#page-managers .zones { flex: 1; min-height: 0; height: auto; border: 1px solid var(--line); border-radius: var(--r-card); }
/* .detail в системе — flex-колонка (под шапку+тред чата); у менеджеров это
   простое прокручиваемое полотно. */
#page-managers .zones > .detail { display: block; overflow-y: auto; padding: 20px 22px; }
#page-managers .mgr-ch { display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 10px; cursor: pointer; margin-bottom: 2px; }
#page-managers .mgr-ch:hover { background: var(--mint); }
#page-managers .mgr-ch.sel { background: rgba(42,171,238,.08); box-shadow: inset 3px 0 0 var(--g); }
#page-managers .mgr-ch .cav { width: 34px; height: 34px; border-radius: 50%; background: var(--mint); display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--t2); font-size: 13px; flex-shrink: 0; }
#page-managers .mgr-ch .cn { font-weight: 600; color: var(--t1); font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#page-managers .mgr-ch .dlg-dot { margin-left: auto; flex-shrink: 0; }
#page-managers .mgr-detail-hd { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
#page-managers .mgr-detail-av { width: 44px; height: 44px; border-radius: 50%; background: var(--mint); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 16px; color: var(--t1); flex-shrink: 0; }
#page-managers .mgr-detail-nm { font-weight: 700; font-size: 16px; color: var(--t1); margin-bottom: 4px; }
#page-managers .mgr-acct-row { display: flex; flex-direction: column; gap: 8px; padding: 12px 0; border-bottom: 1px solid var(--line); }
#page-managers .mgr-acct-row:last-child { border-bottom: none; }
#page-managers .mgr-acct-top { display: flex; align-items: center; gap: 10px; }
#page-managers .mgr-acct-top .rm { margin-left: auto; color: var(--t3); cursor: pointer; background: none; border: none; font-size: 15px; line-height: 1; padding: 4px; }
#page-managers .mgr-acct-top .rm:hover { color: var(--bad); }
@media (max-width: 860px) {
  /* На узком экране колонки складываются вертикально и страница скроллится
     целиком — фиксировать высоту вьюпортом тут нечем и незачем. Отпускаем всю
     цепочку в auto, иначе flex:1 у .zones зажал бы список в остаток экрана. */
  #page-managers, #page-managers .ndash { height: auto; display: block; }
  #page-managers .zones { flex-direction: column; height: auto; }
  #page-managers .zones > .list { width: 100% !important; border-right: none !important; border-bottom: 1px solid var(--line); max-height: 300px; }
  #page-managers .zones > .detail { padding: 16px; }
}

/* ── Dashboard page ────────────────────────────────────────────────────── */
/* Тема-корректность: используем КАНОН-вокабуляр токенов (--card / --line / --t1..t3
   / --bar), который определён И в светлой :root, И в [data-theme="dark"].
   Раньше тут стояли --bg-card / --border — они заданы ТОЛЬКО в dark-:root,
   в светлой теме давали тёмные поверхности. Единственный акцент — --g (синий). */

/* Сетка KPI-карточек: 4 колонки на десктопе, 2 на мобиле */
.dash-kpis { display:grid; grid-template-columns:repeat(4,1fr); gap:16px; }
/* Карточка — мягкая тень + радиус роли «карточка» */
.dash-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 18px 20px;
  box-shadow: var(--shadow-card);
}
.dash-card-h  { font-size:12px; font-weight:600; letter-spacing:.01em;
  text-transform:uppercase; color:var(--t3); margin-bottom:10px; }
/* KPI-число — крупное, табличные цифры, плотный трекинг */
.dash-card-v  { font-size:30px; font-weight:700; line-height:1.05; color:var(--t1);
  letter-spacing:-.02em; font-variant-numeric:tabular-nums; }
/* OLED: голубой glow только на hero-числе дохода (Emil: свет — сигнал, один герой).
   Остальные KPI остаются белыми (--t1). Не трогает светлую тему. */
[data-theme="dark"] .dash-card-hero .dash-card-v{color:var(--g);text-shadow:0 0 26px var(--green-glow)}
/* ── Неон-ряд KPI (концепт «Neon Ledger») ─────────────────────────────
   4 метрики единым hairline-блоком: ячейки = --card, разделители = зазор
   1px на --line. Hero-ячейка «Доход» (.hot) светится голубым в тёмной теме. */
.dash-neon-row{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;
  background:var(--line);border:1px solid var(--line);border-radius:var(--r-card);
  overflow:hidden;margin-bottom:16px}
.dash-neon{background:var(--card);padding:20px 22px 18px;min-width:0}
.dash-neon-lbl{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:var(--t3);margin-bottom:12px}
.dash-neon-v{font-size:32px;font-weight:700;letter-spacing:-.02em;line-height:1;
  color:var(--t1);font-variant-numeric:tabular-nums;
  display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}
.dash-neon-v small{font-size:16px;color:var(--t3);font-weight:500}
.dash-neon-v .dash-trend{font-size:12.5px}
[data-theme="dark"] .dash-neon.hot .dash-neon-v{color:var(--g);text-shadow:0 0 26px var(--green-glow)}
[data-theme="dark"] .dash-neon.hot .dash-neon-v .dash-trend{text-shadow:none}
.dash-neon-sub{margin-top:11px;font-size:12.5px;color:var(--t2);font-variant-numeric:tabular-nums}
.dash-neon-fiat{margin-top:4px;font-weight:600;color:#16a34a}
[data-theme="dark"] .dash-neon-fiat{color:#4ade80}
@media (max-width:820px){.dash-neon-row{grid-template-columns:repeat(2,1fr)}}

/* ── Дашборд Neon Ledger: ряд график+воронка, area-line, газетная таблица ── */
.dash-grid2{display:grid;grid-template-columns:1.65fr 1fr;gap:16px;margin-bottom:16px}
@media (max-width:1000px){.dash-grid2{grid-template-columns:1fr}}
.dash-chart-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.dash-chart-sub{font-size:12px;color:var(--t3);margin-top:4px}
.dash-chart-big{font-family:var(--ff-num);font-size:38px;font-weight:600;letter-spacing:-.022em;
  line-height:1;margin:14px 0 2px;color:var(--t1);font-variant-numeric:tabular-nums}
[data-theme="dark"] .dash-chart-big .cur{color:var(--g);text-shadow:0 0 30px var(--green-glow)}
.dash-chart-big small{font-size:19px;color:var(--t3);font-weight:500}
.dash-area-svg{width:100%;height:150px;display:block;margin-top:8px}
.dash-area-svg .dash-grid{stroke:var(--line)}
.dash-line{fill:none;stroke:var(--g);stroke-width:2.5;stroke-linejoin:round;stroke-linecap:round}
[data-theme="dark"] .dash-line{filter:drop-shadow(0 0 6px var(--green-glow))}
.dash-dot{fill:var(--g)}
[data-theme="dark"] .dash-dot{filter:drop-shadow(0 0 7px var(--green-glow))}
.dash-hit{fill:transparent;cursor:pointer}
/* газетная таблица поступлений (namespace .dash-tbl — не трогает другие table) */
.dash-tbl-wrap{overflow-x:auto;margin-top:4px}
.dash-tbl{width:100%;border-collapse:collapse;font-size:13.5px}
.dash-tbl thead th{text-align:left;font-size:11px;font-weight:600;color:var(--t3);
  text-transform:uppercase;letter-spacing:.06em;padding:2px 20px 12px;white-space:nowrap}
.dash-tbl th.r,.dash-tbl td.r{text-align:right}
.dash-tbl tbody td{padding:13px 20px;border-top:1px solid var(--line);
  font-variant-numeric:tabular-nums;color:var(--t1);white-space:nowrap}
.dash-tbl tbody tr{transition:background 140ms var(--ease-out)}
.dash-tbl tbody tr:hover{background:rgba(42,171,238,.05)}
.dash-tbl .coin{display:flex;align-items:center;gap:10px}
.dash-tbl .cell-2{color:var(--t2)}
.dash-tbl .cell-3{color:var(--t3)}
.dash-tbl-av{width:28px;height:28px;border-radius:50%;flex:none;display:grid;place-items:center;
  font-size:11px;font-weight:600;color:#fff;overflow:hidden;position:relative}
.dash-tbl-av img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* ═══════════ ДАШБОРД «NEON LEDGER» — пиксель-в-пиксель клон концепта ═══════════
   Все селекторы scoped под .ndash со СВОИМИ токенами и системным шрифтом (как в
   макете) — не зависит от токенов/шрифтов платформы и не течёт в остальной UI. */
.ndash{
  --black:#0a0a0c; --raise-1:#131316; --raise-2:#1a1a1e; --raise-3:#212126;
  --line:#232327; --line-soft:#1c1c20;
  --text:#f5f5f5; --text-2:#a8a8ad; --text-3:#6c6c72;
  --accent:#2aabee; --accent-dim:#1d7fb3; --accent-glow:rgba(42,171,238,.20); --accent-soft:rgba(42,171,238,.08);
  --ava-bg:#1e1e22; --ava-fg:#8f9297;
  --good:#3fc97a; --good-dim:rgba(63,201,122,.12); --crit:#e06b6b; --crit-dim:rgba(224,107,107,.10);
  --nease:cubic-bezier(.23,1,.32,1);
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Display","Segoe UI",Roboto,sans-serif;
  color:var(--text); -webkit-font-smoothing:antialiased;
}
.ndash *{box-sizing:border-box}
.ndash .screen{font-size:13px;text-transform:uppercase;letter-spacing:.13em;color:var(--text-3);font-weight:600;margin:0 0 22px;font-family:inherit}
.ndash .screen-row{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:22px}
.ndash .screen-row .screen{margin:0}
/* нативный select macOS игнорит background без appearance:none → сбрасываем и
   рисуем свой шеврон (--text-3). Список опций остаётся ОС-нативным (не стилизуется). */
.ndash .nacc{-webkit-appearance:none;appearance:none;
  background:var(--raise-1) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236c6c72' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 11px center/13px;
  border:1px solid var(--line);border-radius:9px;color:var(--text);
  font-size:13px;font-family:inherit;padding:8px 34px 8px 12px;cursor:pointer;
  transition:border-color .15s var(--nease),background-color .15s var(--nease)}
.ndash .nacc:hover{border-color:var(--line);background-color:var(--raise-2)}
.ndash .nacc:focus{outline:none;border-color:var(--accent-dim)}
/* ── неон-ряд ── */
.ndash .neon-row{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line-soft);
  border:1px solid var(--line-soft);border-radius:16px;overflow:hidden;margin-bottom:22px}
.ndash .neon{background:var(--black);padding:22px 24px 20px;min-width:0}
.ndash .neon .lbl{font-size:12px;color:var(--text-3);letter-spacing:.04em;margin-bottom:12px}
.ndash .neon .val{font-size:34px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1;
  display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.ndash .neon.hot .val{color:var(--accent);text-shadow:0 0 26px var(--accent-glow)}
.ndash .neon.hot .val .delta{text-shadow:none}
.ndash .neon .val small{font-size:17px;color:var(--text-3);font-weight:500}
.ndash .neon .delta{margin-top:11px;font-size:12.5px;font-variant-numeric:tabular-nums;display:inline-flex;align-items:center;gap:5px;font-weight:600}
.ndash .neon .sub{margin-top:11px;font-size:12.5px;color:var(--text-2);font-variant-numeric:tabular-nums}
.ndash .neon .fiat{margin-top:4px;font-size:12.5px;font-weight:600;color:var(--good)}
.ndash .up{color:var(--good)} .ndash .down{color:var(--crit)}
/* ── панели: график + ранкед-лист ── */
.ndash .grid-2{display:grid;grid-template-columns:1.65fr 1fr;gap:20px;margin-bottom:22px}
.ndash .panel{background:var(--raise-1);border:1px solid var(--line-soft);border-radius:16px;padding:22px 24px;min-width:0}
.ndash .panel-h{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:4px}
.ndash .panel-h h2{font-size:16px;font-weight:600;margin:0;font-family:inherit}
.ndash .panel-h .sub{font-size:12px;color:var(--text-3)}
.ndash .big-num{font-size:42px;font-weight:750;letter-spacing:-.025em;font-variant-numeric:tabular-nums;margin:14px 0 2px}
.ndash .big-num .cur{color:var(--accent);text-shadow:0 0 30px var(--accent-glow)}
.ndash .big-num small{font-size:22px;color:var(--text-3);font-weight:500}
.ndash .chart{display:block;margin-top:8px}
.ndash .chart svg{width:100%;height:150px;display:block}
.ndash .ngrid{stroke:var(--line-soft)}
.ndash .narea{fill:url(#ndashGrad)}
.ndash .nline{fill:none;stroke:var(--accent);stroke-width:2.5;stroke-linejoin:round;stroke-linecap:round;filter:drop-shadow(0 0 6px var(--accent-glow))}
/* Плоскость графика: svg + точка последнего дня + вертикальная нить наведения.
   Точка и нить — обычные div-ы поверх svg, а не фигуры внутри него: svg растянут
   preserveAspectRatio="none", и <circle> в нём рисуется эллипсом. */
.ndash .chart-plot{position:relative}
.ndash .ndot{position:absolute;width:9px;height:9px;margin:-4.5px 0 0 -4.5px;border-radius:50%;
  background:var(--accent);box-shadow:0 0 8px var(--accent-glow);pointer-events:none}
.ndash .nhair{position:absolute;top:12%;bottom:12%;width:1px;margin-left:-.5px;
  background:var(--line);pointer-events:none}
.ndash .nhit{fill:transparent;cursor:pointer}

/* ── Фаза 1: адаптив контента (моб) ──────────────────────────────── */
@media (max-width:768px){
  /* дашборд: тумблер периода (.seg, 4 кнопки) не влезает рядом с заголовком в
     .panel-h → распирал страницу в горизонтальный скролл. Переносим под заголовок. */
  .ndash .panel-h{flex-wrap:wrap}
  .ndash .panel-h .seg{max-width:100%;overflow-x:auto;scrollbar-width:none}
  .ndash .panel-h .seg::-webkit-scrollbar{display:none}
}
@media (max-width:860px){
  /* плавающие .bulk-bar (выделение аккаунтов + бар редактора персонажа) сидели
     на bottom:28px — в зоне нижнего таб-бара → перекрывали нав. Поднимаем над ним. */
  .bulk-bar{bottom:calc(60px + var(--safe-b) + 14px)}
}
@media (max-width:480px){
  /* Хедер распирал страницу на телефоне: бренд-лого ~174px + все правые иконки
     (.hdr-right не ужимается) > вьюпорт → весь контент ехал влево (клиппинг).
     Компактим: лого меньше, тайтнее гэпы/иконки. Глаз суперрежима (админ) НУЖЕН —
     вместо него на телефоне прячем refresh (перезагрузка доступна и так), ширина
     хедера не растёт (свап 32px-иконки на 32px). */
  .app-header{gap:8px;padding:0 12px}
  .hdr-logo-svg{height:13px}
  .hdr-right{gap:5px;min-width:0}
  #hdr-refresh-btn{display:none}
  .app-header .hdr-icon-btn{width:32px;height:32px;padding:6px}
  .hdr-energy{padding:5px 8px}
}
.ndash .x-labels{display:flex;justify-content:space-between;width:100%;margin-top:8px;font-size:11px;color:var(--text-3);font-variant-numeric:tabular-nums}
.ndash .x-labels span{white-space:nowrap}
.ndash .chart svg{max-width:100%}
/* ── сегмент ── */
.ndash .seg{display:inline-flex;background:var(--black);border:1px solid var(--line);border-radius:9px;padding:3px;gap:2px}
.ndash .seg button{border:none;background:transparent;color:var(--text-3);font-size:12px;font-weight:500;font-family:inherit;
  padding:5px 12px;border-radius:6px;cursor:pointer;transition:color .15s var(--nease),background .15s var(--nease)}
.ndash .seg button.on{color:var(--text);background:var(--raise-2)}
.ndash .seg button:hover:not(.on){color:var(--text-2)}
/* ── ранкед-лист (воронка) ── */
.ndash .rank{display:flex;flex-direction:column;gap:2px;margin-top:8px}
.ndash .rank-item{display:flex;align-items:center;gap:12px;padding:11px 0;border-bottom:1px solid var(--line-soft)}
.ndash .rank-item:last-child{border-bottom:none}
.ndash .rank-n{font-size:12px;color:var(--text-3);width:16px;font-variant-numeric:tabular-nums}
.ndash .rank-name{flex:1;font-size:13.5px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ndash .rank-bar{height:4px;border-radius:2px;background:var(--line);width:70px;overflow:hidden;flex:none}
.ndash .rank-bar i{display:block;height:100%;background:linear-gradient(90deg,var(--accent-dim),var(--accent));box-shadow:0 0 10px var(--accent-glow)}

/* ── Секция «Аудитория и платежи» (ndash) ──
   Платежи: тонкая полоса-пропорция (.aud-split) + легенда. Гео: таблица колонок
   (.aud-geo2 — Страна | полоса | Клиентов | Доля | Купили | Конв. | Доход | Ср. чек). Токены/шрифт/акцент
   унаследованы от .ndash («Neon Ledger»). */
.ndash .aud-head{display:flex;align-items:center;gap:12px;margin:24px 0 14px}
.ndash .aud-eyebrow{font-size:11px;text-transform:uppercase;letter-spacing:.13em;color:var(--text-3);font-weight:600}
.ndash .aud-chip{font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent);
  background:var(--accent-soft);border:1px solid rgba(42,171,238,.28);padding:2.5px 8px;border-radius:6px}
.ndash .aud-grid{display:flex;flex-direction:column;gap:16px;margin-bottom:22px}
.ndash .aud-empty{margin-top:16px;font-size:13px;color:var(--text-3)}
.ndash .aud-pay-cols{display:grid;grid-template-columns:1fr 1fr;gap:34px;margin-top:16px}

/* легенда платежей: числа в ink-токенах, свотчи повторяют тона .dlg-pn-bar-cell */
.ndash .aud-leg{display:flex;flex-wrap:wrap;gap:6px 18px;margin-top:12px}
.ndash .aud-lg{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--text-2);font-variant-numeric:tabular-nums}
.ndash .aud-lg b{color:var(--text);font-weight:600}
.ndash .aud-lg em{color:var(--text-3);font-style:normal}
.ndash .aud-sw{width:14px;height:6px;border-radius:3px;flex:none}
.ndash .aud-sw.st{background:linear-gradient(90deg,#b4611f,#e0a952)}
.ndash .aud-sw.fi{background:linear-gradient(90deg,var(--accent-dim),var(--accent))}
.ndash .aud-sw.bo{background:var(--line)}

/* платежи: тонкая сплошная полоса-пропорция (доли способов). Сегменты — своей ширины,
   при 100/0 остаётся одна цельная полоса. Тон st=янтарь(звёзды)/fi=синий(карта)/bo=серый(оба). */
.ndash .aud-split{display:flex;gap:2px;height:8px;margin:2px 0 12px;background:var(--black);border:1px solid var(--line-soft);border-radius:5px;overflow:hidden}
.ndash .aud-split i{display:block;height:100%;border-radius:3px;min-width:5px}
.ndash .aud-split i.st{background:linear-gradient(90deg,#b4611f,#e0a952);box-shadow:0 0 12px rgba(232,184,75,.25)}
.ndash .aud-split i.fi{background:linear-gradient(90deg,var(--accent-dim),var(--accent));box-shadow:0 0 12px var(--accent-glow)}
.ndash .aud-split i.bo{background:var(--text-3)}

/* гео — таблица колонок: Страна | полоса(доля писавших) | Клиентов+доля | Купили |
   Конв. | Доход | Ср. чек. Полоса в 1fr-колонке тянется на середину; числа выровнены
   по правому краю. Треков ровно семь — столько же, сколько детей в строке.
   Отдельной колонки «Доля» здесь БОЛЬШЕ НЕТ: процент стоит второй строкой в ячейке
   «Клиентов» (.r.people), потому что это те же клиенты, только в процентах. */
.ndash .aud-geo2{display:flex;flex-direction:column;margin-top:14px}
.ndash .aud-geo2-head,.ndash .aud-geo2-row{display:grid;grid-template-columns:minmax(140px,1.1fr) 2fr 74px 62px 54px 72px 64px;align-items:center;gap:16px}
.ndash .aud-geo2-head{padding-bottom:9px;font-size:10.5px;text-transform:uppercase;letter-spacing:.07em;color:var(--text-3);border-bottom:1px solid var(--line-soft)}
.ndash .aud-geo2-row{padding:10px 0;border-bottom:1px solid var(--line-soft);font-size:13px}
.ndash .aud-geo2-row:last-child{border-bottom:none}
.ndash .aud-geo2 .c-name{display:flex;align-items:center;gap:9px;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ndash .aud-geo2 .c-name .fl{font-size:15px;flex:none}
.ndash .aud-geo2 .bar{height:4px;border-radius:2px;background:var(--line);overflow:hidden}
.ndash .aud-geo2 .bar i{display:block;height:100%;background:linear-gradient(90deg,var(--accent-dim),var(--accent));box-shadow:0 0 8px var(--accent-glow)}
.ndash .aud-geo2 .r{text-align:right;font-variant-numeric:tabular-nums}
.ndash .aud-geo2 .r.muted{color:var(--text-2)}
/* «Клиентов» — число и его доля от всех писавших одной ячейкой, в две строки.
   Доля мельче и тусклее: она пояснение к числу, а не самостоятельная величина. */
.ndash .aud-geo2 .r.people{line-height:1.25}
.ndash .aud-geo2 .r.people b{display:block;font-weight:500}
.ndash .aud-geo2 .r.people small{display:block;font-size:10.5px;color:var(--text-3)}
/* «Купили» БЕЗ своего цвета: синий здесь спорил с зелёными деньгами и зелёной
   горячей конверсией, и глаз не понимал, за что цепляться. Цвет в этой таблице
   остался только у денег и у конверсии выше порога. */
.ndash .aud-geo2 .r.buy{color:var(--text);font-weight:600}

@media(max-width:720px){
  .ndash .aud-pay-cols{grid-template-columns:1fr}
  /* Своего списка треков для гео здесь БОЛЬШЕ НЕТ: 720 целиком внутри 900, и блок
     ≤900 (ниже по файлу, та же специфичность) всё равно выигрывал. Два разных
     списка треков на один и тот же экран уже приводили к тому, что числа
     приземлялись не на свои ячейки. Полосу гасим — она и там не нужна. */
  .ndash .aud-geo2 .bar{display:none}
}

/* emil: вход секции в существующем каскаде .nd-enter (keyframes/easing не новые) */
.ndash.nd-enter .aud-head{animation:ndash-viewin 420ms var(--nease) 240ms backwards}
.ndash.nd-enter .aud-grid > .panel{animation:ndash-cardin 500ms var(--nease) 250ms backwards}
.ndash .rank-val{font-size:13px;color:var(--accent);font-variant-numeric:tabular-nums;min-width:56px;text-align:right;flex:none;white-space:nowrap}
/* аватар клиента в списке */
.ndash .rank-av{width:26px;height:26px;border-radius:50%;flex:none;display:grid;place-items:center;
  font-size:10px;font-weight:600;background:var(--ava-bg);color:var(--ava-fg);border:1px solid var(--line);
  overflow:hidden;position:relative}
.ndash .rank-av img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* «Топ клиенты» тянется по высоте вровень с графиком (сетка stretch + панель 100%) */
.ndash #dash-podium>.panel{height:100%}
/* ── газетная таблица ── */
.ndash .table-wrap{border:1px solid var(--line-soft);border-radius:16px;overflow:hidden;background:var(--raise-1)}
.ndash .table-head{padding:18px 24px 14px;display:flex;align-items:center;gap:14px}
.ndash .table-head h2{font-size:16px;font-weight:600;margin:0;flex:1;font-family:inherit}
.ndash .tbl-scroll{overflow-x:auto;max-height:440px;overflow-y:auto}
/* Страницы, где таблица И ЕСТЬ страница: высота от экрана, а не жёсткие 440 px.
   На 230 аккаунтах в 440 px видно шесть строк, а под карточкой остаётся полэкрана
   пустоты. Вычитаемое — то, что стоит над таблицей (шапка приложения, заголовок
   экрана, плитки счётчиков), замерено на живой странице.
   Нижний предел — через max(), то есть ПОТОЛОК не ниже 340 px на коротком окне.
   Через min-height нельзя: он растягивал карточку до 340 px даже с одной строкой
   внутри (на stage с единственным аккаунтом выходил пустой прямоугольник). */
#page-accounts .tbl-scroll{max-height:max(340px, calc(100vh - 282px))}
#page-proxies .tbl-scroll{max-height:max(340px, calc(100vh - 172px))}
.ndash .tbl-scroll thead th{position:sticky;top:0;z-index:1;background:var(--raise-1)}
.ndash table{width:100%;border-collapse:collapse;font-size:13.5px}
.ndash thead th{text-align:left;font-size:11px;font-weight:500;color:var(--text-3);text-transform:uppercase;letter-spacing:.06em;padding:10px 24px;white-space:nowrap}
.ndash thead th.r,.ndash td.r{text-align:right}
.ndash tbody td{padding:14px 24px;border-top:1px solid var(--line-soft);font-variant-numeric:tabular-nums;white-space:nowrap}
.ndash tbody tr{transition:background .14s var(--nease)}
/* hover — нейтральная поверхность (не голубой отлив: серый текст на accent-soft
   смотрелся грязно). Выбор помечаем акцентной полоской, а не заливкой. */
.ndash tbody tr:hover{background:var(--raise-2)}
.ndash .price-cell{color:var(--text);font-weight:600}
.ndash .time-cell{color:var(--text-3)}
.ndash .coin{display:flex;align-items:center;gap:11px}
.ndash .badge-ic{width:30px;height:30px;border-radius:8px;display:grid;place-items:center;font-size:12px;font-weight:600;
  background:var(--ava-bg);color:var(--ava-fg);border:1px solid var(--line);overflow:hidden;position:relative;flex:none}
.ndash .badge-ic img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.ndash .pill{display:inline-flex;align-items:center;gap:5px;padding:3px 9px;border-radius:999px;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}
.ndash .pill.g{color:var(--good);background:var(--good-dim)}
.ndash .pill.r{color:var(--crit);background:var(--crit-dim)}
@media (max-width:1000px){.ndash .grid-2{grid-template-columns:minmax(0,1fr)}}
/* minmax(0,1fr) — иначе 1fr(=minmax(auto,1fr)) раздувает трек под min-content
   панели (график/подиум) → панели шире вьюпорта → горизонтальный скролл всей
   страницы на телефоне. Подтверждено CDP-инъекцией на живом DOM (382px). */

/* ── Диалоги: master-detail → single-panel на телефоне (≤768) ─────── */
.dlg-mback{display:none}
@media (max-width:768px){
  /* Высота = экран минус шапка минус таб-бар. Раньше здесь стояло магическое
     «128px» — подгонка на глаз из addc13ea, тогда как реальная сумма
     --hdr-h(56) + #mtabbar(60) = 116. Лишние 12px вылезали чёрной полосой
     между списком чатов и таб-баром (замер на живом проде: низ .dlg-list 772,
     верх #mtabbar 784). Тот же диагноз уже записан на :7816 — там его закрыли
     только для manager-mode, у владельца полоса оставалась. */
  #page-dialogs .dlg-wrap{position:relative;height:calc(100dvh - var(--hdr-h,56px) - 60px - var(--safe-b));border-radius:0;border-left:0;border-right:0;border-bottom:0}
  #page-dialogs.main-content{padding-bottom:0}   /* убираем нижний зазор блока диалогов */
  /* !important — существующие правила диалогов сидят на !important (2690: conv display:flex!important)
     и клампах (4855: list max-width:210px), иначе перебивают. */
  /* Рельса аккаунтов: НЕ скрываем. dlgPickAcct зовётся только отсюда (app.js:5097),
     поэтому со скрытой рельсой сменить аккаунт на телефоне НЕЛЬЗЯ вообще — ни
     владельцу, ни менеджеру. Кладём горизонтальной полосой сверху: вертикальная
     колонка съела бы ширину списка. Компонент тот же (dlgRenderRail/.av). */
  #page-dialogs .dlg-wrap{ flex-direction: column !important; }
  #page-dialogs .dlg-rail{
    display: flex !important;
    flex-direction: row !important;
    width: 100% !important;
    height: auto !important;
    border-right: none !important;
    border-bottom: 1px solid var(--line) !important;
    padding: 8px 10px !important;
    gap: 8px !important;
    overflow-x: auto; overflow-y: hidden;
    flex-shrink: 0;
  }
  /* Один аккаунт — переключать не на что: полоса только ест высоту на телефоне.
     Десктоп НЕ трогаем: там рельса была всегда, менять её поведение — лишний риск. */
  #page-dialogs .dlg-rail.rail-solo{ display: none !important; }
  #page-dialogs .dlg-list{width:100% !important;max-width:none !important;min-width:0 !important;border-right:none} /* список на всю ширину */
  #page-dialogs .dlg-list{ flex: 1 1 auto !important; min-height: 0 !important; } /* .dlg-wrap теперь column — списку нужен flex-grow по высоте, не только width:100% */
  #page-dialogs .dlg-conv{position:absolute;inset:0;display:none !important;z-index:3;background:var(--card)}
  #page-dialogs .dlg-wrap.m-conv .dlg-list{display:none !important}                   /* открыт чат → прячем список */
  #page-dialogs .dlg-wrap.m-conv .dlg-conv{display:flex !important}                   /* …тред на всю ширину */
  /* кнопка «назад к чатам» поверх шапки треда */
  /* кнопка «назад» — только стрелка-кружок (текст «Чаты» убран из HTML) */
  /* кнопка «назад» — теперь ПЕРВЫЙ flex-ребёнок шапки; .dlg-chd{align-items:center}
     центрирует её по вертикали сам, без absolute/магических top. */
  #page-dialogs .dlg-wrap.m-conv .dlg-mback{
    display:inline-flex;align-items:center;justify-content:center;flex:none;
    width:34px;height:34px;padding:0;border-radius:50%;
    background:var(--mint);border:1px solid var(--line);color:var(--t1);
    font:inherit;cursor:pointer;
  }
  #page-dialogs .dlg-wrap.m-conv .dlg-mback:active{transform:scale(.92)}
}

/* ── Редактор персонажа: бар действий влезает на телефоне ─────────── */
@media (max-width:480px){
  .char-actionbar.bulk-bar{padding:6px 8px;gap:4px;max-width:calc(100vw - 16px)}
  .char-actionbar .bulk-bar__btn{padding:8px 10px;font-size:12.5px;gap:5px}
  /* «Копировать» → иконка-only, иначе «Сохранить» обрезался. «Удалить персонажа»
     подпись СОХРАНЯЕТ: без неё это была голая мусорка, неотличимая от мусорки
     сцены, — на этом и промахивались. Бар и так скроллится по горизонтали. */
  .char-actionbar .bulk-bar__btn[data-act="copy"]{font-size:0;padding:8px}
  .char-actionbar .bulk-bar__btn[data-act="delete"]{font-size:11.5px;padding:8px 9px}
  .char-actionbar .bulk-bar__btn .bic{width:16px;height:16px}
  /* Одного «Копировать» не хватало: на 390px содержимое бара всё равно шире самой
     панели (427px против 372px), и «Сохранить» обрезан — до него надо доскроллить
     бар вбок, а скроллбар спрятан (.bulk-bar{overflow-x:auto;scrollbar-width:none}),
     то есть подсказки, что тут вообще можно скроллить, нет. Тем же приёмом добираем
     «Отмену» и убираем разделитель. */
  .char-actionbar .bulk-bar__btn[data-act="cancel"]{font-size:0;padding:8px}
  .char-actionbar .bulk-bar__sep{display:none}
  .char-actionbar.bulk-bar{padding-left:10px}
}
/* Парные поля (.field-row — жёсткие 2 колонки) на телефоне: длинные лейблы соседних
   ячеек переносятся на разное число строк, и сами поля встают на разной высоте —
   видно в «Защите энергии» и «Follow-up пингах». Одна колонка лечит это разом. */
@media (max-width:560px){ .field-row{grid-template-columns:1fr} }
@media (max-width:820px){.ndash .neon-row{grid-template-columns:repeat(2,1fr)}}

/* ═══════════ КОНЦЕПТ-КИТ СТРАНИЦ (переиспользуется всеми экранами) ═══════════
   Та же типографика/поверхности/токены .ndash, что у дашборда. Кнопки, поля,
   кликабельные неон-карточки (фильтры), пилюли статусов, иконки-действия,
   инлайн-контролы таблиц — единый словарь для Аккаунтов/Персонажей/Настроек/etc. */
.ndash .screen-actions{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.ndash input[type=checkbox]{accent-color:var(--accent);cursor:pointer}
/* кнопки — по спеке концепта: primary=сплошной accent + ТЁМНЫЙ текст (#04121b),
   glow ТОЛЬКО на hover (не в покое), active=scale; ghost=raise-2+line. */
.ndash .nbtn{box-sizing:border-box;display:inline-flex;align-items:center;justify-content:center;gap:7px;height:36px;padding:0 16px;
  border-radius:10px;border:1px solid var(--line);background:var(--raise-2);color:var(--text-2);
  font:inherit;font-size:13px;font-weight:600;line-height:1;cursor:pointer;white-space:nowrap;
  transition:border-color .16s var(--nease),background .16s var(--nease),color .16s var(--nease),box-shadow .2s var(--nease),filter .16s var(--nease),transform .12s var(--nease)}
/* Наведение поднимает ПОВЕРХНОСТЬ и рамку, а не белит текст. Раньше менялся ровно
   один цвет — подпись из серой в белую, фон и рамка те же, — и кнопка не столько
   подсвечивалась, сколько моргала текстом. Гейт по мыши обязателен: на тач-экране
   тап оставляет :hover висеть до следующего касания в другом месте. */
@media (hover:hover) and (pointer:fine){
  .ndash .nbtn:hover{background:var(--raise-3);border-color:#2f2f36}
}
.ndash .nbtn:active{transform:scale(.97)}
.ndash .nbtn.primary{background:var(--accent);border-color:var(--accent);color:#04121b;font-weight:700}
.ndash .nbtn.primary:hover{background:var(--accent);border-color:var(--accent);color:#04121b;filter:brightness(1.06);box-shadow:0 0 22px var(--accent-glow)}
.ndash .nbtn.sm{height:32px;padding:0 13px;font-size:12.5px;border-radius:9px}
.ndash .nbtn.ghost{background:var(--raise-2);border-color:var(--line)}
@media (hover:hover) and (pointer:fine){
  .ndash .nbtn.ghost:hover{background:var(--raise-3);border-color:#2f2f36}
  /* Опасное действие — единственное исключение: тут цвет и есть предупреждение. */
  .ndash .nbtn.danger:hover{border-color:var(--crit);color:var(--crit);background:var(--crit-dim)}
}
/* ВСЕ primary-кнопки приложения в тёмной теме → спека концепта: сплошной accent,
   ТЁМНЫЙ текст, БЕЗ градиента и тяжёлой тени в покое, glow только на hover.
   Scoped #page-app → экран входа (#page-auth) не трогаем. Бьёт градиент-правила
   .btn-primary (1767/2761) и белый текст по ID-специфичности. */
[data-theme="dark"] #page-app .btn-primary{
  background:var(--accent);color:#04121b;border-color:var(--accent);
  border-radius:10px;font-weight:700;box-shadow:none;
  transition:filter .16s var(--nease),box-shadow .2s var(--nease),transform .12s var(--nease);
}
[data-theme="dark"] #page-app .btn-primary:hover{filter:brightness(1.06);box-shadow:0 0 22px var(--accent-glow)}
[data-theme="dark"] #page-app .btn-primary:active{transform:scale(.97)}
/* ЕДИНЫЙ РАЗМЕР ВСЕХ .btn в тёмном приложении — гасим накопившийся зоопарк:
   .btn-primary был h42, .btn-sm h34, .btn-ghost/.btn-danger без height (по контенту),
   + border у ghost/danger но НЕ у primary при content-box → строка кнопок скакала
   по ±2-8px. box-sizing:border-box + фикс-высота + border:1px у всех = ровный ряд.
   Обычная 36px, .btn-sm 32px. Иконки-размеры (квадратные .btn) не трогаем. */
[data-theme="dark"] #page-app .btn:not(.btn-icon):not(.et-ic){
  box-sizing:border-box;height:36px;min-height:36px;padding:0 16px;
  border-radius:10px;font-size:13px;font-weight:600;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  border:1px solid transparent;width:auto;
}
[data-theme="dark"] #page-app .btn-sm{height:32px;min-height:32px;padding:0 13px;font-size:12.5px;border-radius:9px}
/* ghost/danger сохраняют видимую рамку (у primary рамка = accent из правила выше) */
[data-theme="dark"] #page-app .btn-ghost,
[data-theme="dark"] #page-app .btn-secondary{border-color:var(--line)}
[data-theme="dark"] #page-app .btn-danger{border-color:rgba(224,107,107,.4)}
/* исключение: квадратная ✕-кнопка удаления тира энергии остаётся 32×32 */
[data-theme="dark"] #page-app .energy-tier-row .btn-ghost{width:32px;height:32px;min-height:32px;padding:0;border-radius:9px}
/* Кнопки поповера энергии (оплата + промокод) перебивались правилом выше:
   специфичность id+4 класса против id+2/id+1 у .energy-buy-actions .btn и
   .energy-promo-btn (проверено в браузере — доставалось 149px из 300px
   доступных). Поднимаем специфичность тем же приёмом, что и у ✕-кнопки тира
   выше (повтор приставки темы + доп. класс), без !important — при равной
   специфичности побеждает более позднее по файлу правило. */
[data-theme="dark"] #page-app .energy-buy-actions .btn.btn{width:100%}
[data-theme="dark"] #page-app .btn.btn-ghost.energy-promo-btn{width:100%;margin-top:8px}
/* поля ввода */
.ndash .ninput{height:34px;padding:0 12px;border-radius:9px;border:1px solid var(--line);
  background:var(--black);color:var(--text);font:inherit;font-size:13px;
  transition:border-color .15s var(--nease)}
.ndash .ninput::placeholder{color:var(--text-3)}
.ndash .ninput:focus{outline:none;border-color:var(--accent-dim)}
.ndash textarea.ninput{height:auto;min-height:80px;padding:9px 12px;line-height:1.5;resize:vertical;width:100%}
.ndash .ninput--search{min-width:230px;padding-left:34px;
  background:var(--black) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236c6c72' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E") no-repeat left 11px center/14px}
/* кликабельная неон-карточка = фильтр (выбранная — акцент + подчёркивание) */
.ndash .neon{position:relative}
.ndash .neon.click{cursor:pointer;transition:background .15s var(--nease)}
.ndash .neon.click:hover{background:var(--raise-1)}
.ndash .neon.on{background:var(--raise-1)}
.ndash .neon.on .val{color:var(--accent);text-shadow:0 0 22px var(--accent-glow)}
.ndash .neon.on::after{content:'';position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--accent)}
/* пилюли статусов (расширение .pill дашборда) */
.ndash .pill.m{color:var(--text-2);background:var(--raise-2)}
.ndash .pill.a{color:#e0a93a;background:rgba(224,169,58,.13)}
.ndash .pill.click{cursor:pointer}
.ndash .pill.click:hover{filter:brightness(1.15)}
/* инлайн-контролы таблиц */
.ndash .badge-ic.round{border-radius:50%}
.ndash td .nacc{padding:6px 26px 6px 10px;font-size:12.5px}
.ndash .cell-sub{color:var(--text-3);font-size:11.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ndash .cell-strong{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ndash .iconbtn{width:28px;height:28px;border-radius:7px;display:inline-grid;place-items:center;
  color:var(--text-2);border:1px solid transparent;background:transparent;cursor:pointer;
  transition:color .15s var(--nease),border-color .15s var(--nease),background .15s var(--nease)}
.ndash .iconbtn:hover{color:var(--accent);border-color:var(--line);background:var(--raise-2)}
.ndash .row-actions{display:flex;gap:5px;align-items:center}
/* выбранная строка — нейтральная поверхность + акцентная полоска слева (без
   серого-на-бирюзе), чтобы вторичный текст оставался читаемым */
.ndash tbody tr.row-selected{background:var(--raise-2);box-shadow:inset 2px 0 0 var(--accent)}
.ndash tbody tr.disconnected{opacity:.5}
/* пустое состояние в панели/таблице */
.ndash .nd-empty{padding:44px 20px;text-align:center;color:var(--text-3);font-size:13px}
/* панель-форма: группы полей (Настройки/Персонажи) */
.ndash .field{margin-bottom:14px}
.ndash .field:last-child{margin-bottom:0}
.ndash .field>label{display:block;font-size:12px;color:var(--text-3);margin-bottom:6px}
.ndash .field-hint{font-size:11.5px;color:var(--text-3);margin-top:5px;line-height:1.45}
.ndash .grouplbl{font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);margin:0 0 12px}
/* сетка карточек-панелей (Менеджеры/Персонажи и т.п.) */
.ndash .panel-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px}
.ndash .panel-hd{display:flex;align-items:center;gap:11px;margin-bottom:14px}
.ndash .panel-hd .nm{flex:1;min-width:0;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ndash .chips{display:flex;flex-wrap:wrap;gap:6px}
/* ── Парсинг: концепт-язык поверх существующей .parser-* разметки ── */
.ndash .parser-controls{background:var(--raise-1);border:1px solid var(--line-soft);border-radius:16px;padding:16px 18px;margin-bottom:18px}
.ndash .parser-kw{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.ndash .parser-controls input[type=text],
.ndash .parser-body input[type=text],.ndash .parser-body input[type=number],.ndash .parser-body input[type=search],
.ndash .parser-acc-search{height:34px;padding:0 12px;border-radius:9px;border:1px solid var(--line);background:var(--black);color:var(--text);font:inherit;font-size:13px}
.ndash .parser-controls input::placeholder,.ndash .parser-body input::placeholder{color:var(--text-3)}
.ndash .parser-controls input:focus,.ndash .parser-body input:focus{outline:none;border-color:var(--accent-dim)}
.ndash .parser-body select,.ndash .parser-acc-trigger{height:34px;border-radius:9px;border:1px solid var(--line);background:var(--raise-1);color:var(--text);font:inherit;font-size:13px;padding:0 12px;cursor:pointer}
.ndash .parser-controls .btn,.ndash .parser-body .btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;height:34px;padding:0 14px;border-radius:9px;
  border:1px solid var(--line);background:var(--raise-1);color:var(--text);font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:border-color .15s var(--nease),background .15s var(--nease)}
.ndash .parser-controls .btn:hover,.ndash .parser-body .btn:hover{border-color:var(--accent-dim);background:var(--raise-2)}
.ndash .parser-controls .btn-primary,.ndash .parser-body .btn-primary{background:var(--accent);border-color:var(--accent);color:#04121b}
.ndash .parser-controls .btn-primary:hover,.ndash .parser-body .btn-primary:hover{background:var(--accent-dim);border-color:var(--accent-dim)}
.ndash .parser-body{display:flex;gap:18px;align-items:flex-start}
.ndash .parser-panel,.ndash aside.parser-actions{background:var(--raise-1);border:1px solid var(--line-soft);border-radius:16px;padding:18px;width:260px;flex:none}
.ndash .parser-panel-title{font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--text-3);margin-bottom:14px}
.ndash .parser-grp{margin-bottom:14px}
.ndash .parser-grp-l{font-size:12px;color:var(--text-3);margin-bottom:6px}
.ndash .parser-grp-row{display:flex;gap:8px}
.ndash .parser-main{flex:1;min-width:0}
.ndash .parser-kw-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
.ndash .parser-kw-chip{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;border-radius:999px;font-size:12px;background:var(--raise-2);color:var(--text-2);border:1px solid var(--line)}
.ndash .parser-kw-chip-sugg{background:var(--accent-soft);border-color:var(--accent-dim);color:var(--text)}
.ndash .parser-check{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;color:var(--text-2)}
.ndash .parser-status{color:var(--text-3);font-size:12.5px;margin-bottom:12px}
/* ── Настройки: концепт-язык поверх .set-* разметки ── */
.ndash .set-card{background:var(--raise-1);border:1px solid var(--line-soft);border-radius:16px}
.ndash .set-grouplbl{color:var(--text-3)}
.ndash .set-card__title{color:var(--text)}
.ndash .set-card__sub{color:var(--text-2)}
.ndash .set-field{display:flex;flex-direction:column;gap:6px;margin-bottom:12px}
.ndash .set-field>span{font-size:12px;color:var(--text-3)}
/* :not(.ec-card) — карточки редактора персонажа исключены намеренно. Селектор
   (0,3,1) специфичнее .form-input (0,1,0), и как только поля редактора переехали
   внутрь .set-card, они молча получали чужой компактный скин «Настроек»: textarea
   оставались высокими, а соседние input схлопывались в 34px, .pb-input ценника
   терял свою ширину. Скин «Настроек» нужен только их собственным карточкам. */
.ndash .set-field input,.ndash .set-input,.ndash input.set-input,
.ndash .set-card:not(.ec-card) input[type=text],.ndash .set-card:not(.ec-card) input[type=password],.ndash .set-card:not(.ec-card) input[type=number]{
  height:34px;padding:0 12px;border-radius:9px;border:1px solid var(--line);background:var(--black);color:var(--text);font:inherit;font-size:13px}
.ndash .set-card input::placeholder{color:var(--text-3)}
.ndash .set-card input:focus{outline:none;border-color:var(--accent-dim)}
.ndash .set-card:not(.ec-card) .btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:34px;padding:0 15px;border-radius:9px;
  border:1px solid var(--line);background:var(--raise-1);color:var(--text);font:inherit;font-size:13px;font-weight:600;cursor:pointer;transition:border-color .15s var(--nease),background .15s var(--nease)}
.ndash .set-card:not(.ec-card) .btn:hover{border-color:var(--accent-dim);background:var(--raise-2)}
.ndash .set-card:not(.ec-card) .btn-primary{background:var(--accent);border-color:var(--accent);color:#04121b}
.ndash .set-card:not(.ec-card) .btn-primary:hover{background:var(--accent-dim);border-color:var(--accent-dim)}
.ndash .set-msg{font-size:12px;color:var(--text-3);margin-left:10px}
/* Специфичность .ndash .set-msg (0,2,0) равна .set-msg.err (0,2,0), и поздний
   побеждал: ошибка сохранения токена печаталась серым, неотличимо от подсказки. */
.ndash .set-msg.err{color:var(--crit)}
.ndash .set-msg.ok{color:var(--good)}
/* hero-карта обзора снята 22.08.2026 — её правила рескина ушли вместе с ней */
/* ── Персонажи: карточки-панели концепта + поиск ── */
.ndash .chars-toolbar{margin:0 0 18px}
.ndash .chars-search{position:relative;max-width:320px}
.ndash .chars-search svg{position:absolute;left:11px;top:50%;transform:translateY(-50%);width:15px;height:15px;fill:none;stroke:var(--text-3);stroke-width:2;pointer-events:none}
.ndash .chars-search input{width:100%;height:34px;padding:0 12px 0 34px;border-radius:9px;border:1px solid var(--line);background:var(--black);color:var(--text);font:inherit;font-size:13px}
.ndash .chars-search input::placeholder{color:var(--text-3)}
.ndash .chars-search input:focus{outline:none;border-color:var(--accent-dim)}
.ndash .chars-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}
.ndash .char-card{background:var(--raise-1);border:1px solid var(--line-soft);border-radius:16px;padding:18px;cursor:pointer;
  transition:border-color .15s var(--nease),background .15s var(--nease),transform .12s var(--nease)}
/* hover/active карточки заданы ниже более специфичным #page-characters
   .char-card:hover (нейтральный подъём, без синего кольца) — тут не дублируем */
.ndash .char-card-head{display:flex;align-items:flex-start;gap:12px}
.ndash .char-card-id{flex:1;min-width:0}
.ndash .char-card-name{font-weight:600;font-size:15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ndash .char-card-preview{font-size:12.5px;color:var(--text-2);line-height:1.45;margin-top:4px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.ndash .char-card-preview.is-empty{color:var(--text-3);font-style:italic}
.ndash .char-card-foot{display:flex;align-items:center;gap:14px;margin-top:14px;padding-top:14px;border-top:1px solid var(--line-soft);
  font-size:12px;color:var(--text-2)}
.ndash .char-stat{display:inline-flex;align-items:center;gap:6px}
.ndash .char-dot{width:7px;height:7px;border-radius:50%;flex:none}
.ndash .char-dot.is-active{background:var(--good);box-shadow:0 0 8px var(--good-dim)}
.ndash .char-dot.is-idle{background:var(--text-3)}
.ndash .char-card-owner{color:var(--text-3)}
/* ── Корзина мягко удалённых персонажей (под списком) ──
   Приглушённая, свёрнутая, без своего «веса» на экране: это архив, к которому
   заходят раз в жизни, а не рабочая часть страницы. Аватар обесцвечен — сигнал
   «персонаж выключен» читается ещё до текста. */
.ndash .chars-deleted{margin-top:22px}
.ndash .chars-deleted__box{border:1px solid var(--line-soft);border-radius:14px;background:var(--raise-1)}
.ndash .chars-deleted__box>summary{list-style:none;cursor:pointer;padding:11px 16px;font-size:12.5px;color:var(--text-3);
  display:flex;align-items:center;gap:9px;user-select:none;transition:color .15s var(--nease)}
.ndash .chars-deleted__box>summary::-webkit-details-marker{display:none}
.ndash .chars-deleted__box>summary::before{content:"";width:6px;height:6px;flex:none;
  border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
  transform:rotate(-45deg);transition:transform 160ms var(--nease)}
.ndash .chars-deleted__box[open]>summary::before{transform:rotate(45deg)}
.ndash .chars-deleted__box>summary:hover{color:var(--text-2)}
.ndash .chars-deleted__count{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;
  padding:0 5px;border-radius:9px;background:var(--raise-2);color:var(--text-2);font-size:11px;font-weight:600}
.ndash .chars-deleted__list{padding:0 14px 14px;display:flex;flex-direction:column;gap:8px}
.ndash .chars-deleted__row{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:12px;
  background:var(--black);border:1px solid var(--line-soft)}
.ndash .chars-deleted__av{width:34px;height:34px;border-radius:10px;flex:none;display:flex;align-items:center;
  justify-content:center;color:#fff;font-weight:700;font-size:14px;filter:grayscale(.85);opacity:.7}
.ndash .chars-deleted__id{flex:1;min-width:0}
.ndash .chars-deleted__name{font-size:13.5px;font-weight:600;color:var(--text-2);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ndash .chars-deleted__meta{font-size:11.5px;color:var(--text-3);margin-top:2px}
.ndash .chars-deleted__btn{flex:none}
@media (max-width:600px){
  .ndash .chars-deleted__row{flex-wrap:wrap}
  .ndash .chars-deleted__btn{width:100%}
}
/* ── Админка: концепт-табы + панели ── */
.ndash .admin-tabs{display:flex;gap:2px;flex-wrap:wrap;background:var(--black);border:1px solid var(--line);border-radius:11px;padding:3px;margin-bottom:20px}
.ndash .admin-tab{display:inline-flex;align-items:center;gap:7px;padding:8px 13px;border-radius:8px;font-size:13px;font-weight:500;
  color:var(--text-3);cursor:pointer;border:none;background:transparent;transition:color .15s var(--nease),background .15s var(--nease)}
.ndash .admin-tab svg{width:15px;height:15px}
.ndash .admin-tab:hover{color:var(--text-2)}
.ndash .admin-tab.active{color:var(--text);background:var(--raise-2)}
.ndash .admin-panel{min-width:0}

/* ═══════════ ХЕДЕР в языке концепта «Neon Ledger» ═══════════
   OLED-бар + hairline-низ; весь розово-фиолет (accent-1/2/grad) сведён к голубому
   концепту. Лого — чистый белый вордмарк (нейтральная константа), «бренд-цвет»
   теперь несут акцент-элементы: активная навигация, бейджи, аватар. Правила
   идут ПОЗЖЕ базовых (4616-4745) → выигрывают при равной специфичности. */
[data-theme="dark"] .app-header{background:var(--black);border-bottom:1px solid var(--line);box-shadow:none}
/* лого — РОЗОВЫЙ, как было (бренд-константа): fill/glow не трогаем */
.hdr-mk{background:var(--accent);box-shadow:0 0 14px var(--accent-glow)}
/* навигация */
.app-header .nav-item:hover{color:var(--text);background:var(--raise-2)}
.app-header .nav-item.active{
  color:var(--text);
  background:var(--accent-soft);
  box-shadow:inset 0 0 0 1px var(--accent-dim);
}
.app-header .nav-item.active .nav-icon{color:var(--accent)}
/* бейджи-счётчики: розово-фиолет → приглушённо-голубой; на активной — сплошной акцент */
.app-header .nav-badge{background:var(--accent-soft);color:var(--accent);box-shadow:none}
.app-header .nav-item.active .nav-badge{background:var(--accent);color:#fff}
/* live-точки + точка «Ещё» — голубые */
.app-header .nav-live-dot{background:var(--accent);box-shadow:0 0 8px var(--accent-glow)}
.hdr-more-dot{background:var(--accent);box-shadow:0 0 7px var(--accent-glow)}
/* «Ещё» с активным вложенным пунктом — нейтральная плашка (не фиолет-градиент) */
.hdr-more:has(.nav-item.active) .hdr-more-btn{color:var(--text);background:var(--raise-2)}
.app-header .hdr-more-btn:hover{color:var(--text);background:var(--raise-2)}
/* иконки-кнопки: нейтраль, hover — голубой */
.app-header .hdr-icon-btn{color:var(--text-3)}
.app-header .hdr-icon-btn:hover{background:var(--raise-2);color:var(--accent)}
/* аватар: фиолет → голубой градиент концепта */
.app-header .user-avatar-img{background:linear-gradient(135deg,var(--accent),var(--accent-dim));color:#fff}
/* баланс ★: фиолет-плашка → нейтральная поверхность; ★ остаётся золотым (валюта) */
.app-header .hdr-balance{background:var(--raise-2);border:1px solid var(--line);color:#e0a93a}
.hdr-balance:hover{border-color:var(--accent-dim)}
/* entrance для таблиц/панелей/карточек на любых страницах (не только #dash-sales) */
.ndash.nd-enter .table-wrap{animation:ndash-cardin 500ms var(--nease) 240ms backwards}
.ndash.nd-enter .panel{animation:ndash-cardin 500ms var(--nease) 200ms backwards}
.ndash.nd-enter .set-card,.ndash.nd-enter .char-card{animation:ndash-cardin 500ms var(--nease) 200ms backwards}
.ndash.nd-enter .admin-tabs,.ndash.nd-enter .chars-toolbar,.ndash.nd-enter .parser-controls{animation:ndash-cardin 460ms var(--nease) 120ms backwards}

/* ── entrance-анимации концепта (играют по классу .nd-enter — только при заходе на
      вкладку/первой загрузке, не на фоновом refresh; см. renderDashboard). ── */
@keyframes ndash-viewin{from{opacity:0;transform:translateY(6px);filter:blur(4px)}to{opacity:1;transform:none;filter:blur(0)}}
@keyframes ndash-cardin{from{opacity:0;transform:translateY(10px);filter:blur(3px)}to{opacity:1;transform:none;filter:blur(0)}}
.ndash.nd-enter{animation:ndash-viewin 420ms var(--nease)}
.ndash.nd-enter .neon{animation:ndash-cardin 500ms var(--nease) backwards}
.ndash.nd-enter .neon:nth-child(1){animation-delay:40ms}
.ndash.nd-enter .neon:nth-child(2){animation-delay:90ms}
.ndash.nd-enter .neon:nth-child(3){animation-delay:140ms}
.ndash.nd-enter .neon:nth-child(4){animation-delay:190ms}
.ndash.nd-enter .grid-2 .panel{animation:ndash-cardin 500ms var(--nease) 340ms backwards}
/* emil: вход секции готовности в существующем каскаде .nd-enter */
.ndash.nd-enter .rd-strip{animation:ndash-viewin 420ms var(--nease) 200ms backwards}
.ndash.nd-enter .rd-card{animation:ndash-cardin 460ms var(--nease) backwards}
.ndash.nd-enter .rd-card:nth-child(1){animation-delay:215ms}
.ndash.nd-enter .rd-card:nth-child(2){animation-delay:250ms}
.ndash.nd-enter .rd-card:nth-child(3){animation-delay:285ms}
.ndash.nd-enter .rd-card:nth-child(4){animation-delay:320ms}

.ndash.nd-enter #dash-sales .table-wrap{animation:ndash-cardin 500ms var(--nease) 300ms backwards}
/* пульс live-индикатора «Онлайн» (концепт) */
@keyframes ndash-pulse{0%,100%{opacity:1}50%{opacity:.35}}
.ndash .live-dot i{animation:ndash-pulse 2.4s var(--nease) infinite}

/* ── прелоадер: шиммер по тёмному OLED (низкий контраст, linear, бесконечно) ── */
@keyframes ndash-shimmer{100%{transform:translateX(100%)}}
.ndash .nd-sh{position:relative;overflow:hidden;background:var(--raise-2);border-radius:8px}
.ndash .nd-sh::after{content:'';position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.05),transparent);
  animation:ndash-shimmer 1.4s linear infinite}
.ndash .nd-line{border-radius:6px}
.ndash .nd-skel .neon{display:flex;flex-direction:column}
.ndash .nd-skel-trow{display:flex;align-items:center;gap:16px;padding:14px 24px;border-top:1px solid var(--line-soft)}
.ndash .nd-skel-trow .nd-line:nth-child(2){flex:1}

@media (prefers-reduced-motion:reduce){
  .ndash.nd-enter,.ndash.nd-enter *{animation:none!important}
  .ndash .live-dot i{animation:none!important}
  .ndash .nd-sh::after{animation:none!important}
}

.dash-card-sub{ font-size:12px; color:var(--t2); margin-top:8px; }
.dash-empty   { padding:40px; text-align:center; color:var(--t3); }

/* Hero KPI (Доход): число + тренд в строке, под ними мини-спарклайн */
.dash-card-vrow{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; }
/* Бейдж тренда vs прошлый период. Цвета — семантика роста/падения (не акцент-токен). */
.dash-trend{ font-size:12.5px; font-weight:700; font-variant-numeric:tabular-nums;
  letter-spacing:-.01em; line-height:1; white-space:nowrap; }
.dash-trend.up  { color:#16a34a; }
.dash-trend.down{ color:#dc2626; }
.dash-trend.flat{ color:var(--t3); }
[data-theme="dark"] .dash-trend.up  { color:#4ade80; }
[data-theme="dark"] .dash-trend.down{ color:#f87171; }
/* Спарклайн: тонкая полоска ритма дохода, не конкурирует с большим чартом ниже */
.dash-spark{ margin-top:10px; height:28px; }
.dash-spark-svg{ width:100%; height:28px; display:block; }
.dash-spark-bar{ fill:var(--g); opacity:.34; }
.dash-card-hero .dash-card-sub{ margin-top:10px; }
/* Накопительный итог «всего …» — приглушённая 4-я строка, поджата под сводный ≈$
   (рисуется только когда период ≠ всё время), чтобы не спорить с ним по весу. */
.dash-card-hero .dash-card-sub-all{ margin-top:3px; color:var(--t3);
  font-variant-numeric:tabular-nums; }
/* Фиат рядом со звёздами (раздельно, точно): вторая денежная строка дохода —
   зелёный акцент «реальных денег», табличные цифры, чуть мельче KPI-числа. */
.dash-card-fiat{ margin-top:6px; font-size:15px; font-weight:700; line-height:1.1;
  color:#16a34a; letter-spacing:-.01em; font-variant-numeric:tabular-nums; }
[data-theme="dark"] .dash-card-fiat{ color:#4ade80; }

@media (max-width:900px){ .dash-kpis{ grid-template-columns:repeat(2,1fr); } }

/* ── Фильтры (период + аккаунт) — контролы первого класса ──
   Селект и сегмент — одна семья: общая высота 36px, общая поверхность
   (--sheet + --line), общий радиус. Нативная стрелка селекта заменена
   кастомным шевроном (appearance:none). */
.dash-filters { display:flex; gap:10px; align-items:center; margin-bottom:18px; flex-wrap:wrap; }
.dash-acc { appearance:none; -webkit-appearance:none;
  height:36px; padding:0 32px 0 13px; border-radius:var(--r-ctl);
  background:var(--sheet) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%235E6A60' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 10px center;
  color:var(--t1); border:1px solid var(--line); font:inherit; font-size:13px; font-weight:500;
  cursor:pointer; transition: border-color .15s var(--ease-out), box-shadow .15s var(--ease-out); }
.dash-acc:hover { border-color:var(--mint-bd); }
.dash-acc:focus-visible { outline:none; border-color:var(--g); box-shadow:0 0 0 3px rgba(42,171,238,.15); }
/* Сегмент периода — обёртка-таблетка той же высоты/поверхности, что и селект */
.dash-seg { display:inline-flex; height:36px; align-items:center;
  background:var(--sheet); border:1px solid var(--line);
  border-radius:var(--r-ctl); padding:3px; gap:2px; }
.dash-seg-btn { height:28px; padding:0 14px; border-radius:calc(var(--r-ctl) - 4px); border:0;
  background:transparent; color:var(--t2); font:inherit; font-size:13px; font-weight:600;
  cursor:pointer; display:inline-flex; align-items:center;
  transition: color .15s var(--ease-out), background-color .15s var(--ease-out), transform .12s var(--ease-out); }
.dash-seg-btn:hover:not(.active) { color:var(--t1); background:var(--ctl); }
.dash-seg-btn.active { background:var(--g); color:#fff; box-shadow:0 1px 2px rgba(42,171,238,.4); }
.dash-seg-btn:active { transform:scale(.96); }

.dash-card { margin-top:16px; }
/* Шапка карточки + правый итог в одной строке */
.dash-card-h .dash-card-h-aside { float:right; color:var(--t2); font-weight:600;
  text-transform:none; letter-spacing:0; }

/* ── График дохода (area-line, см. .dash-area-svg выше) ── */
/* Горизонтальная сетка (0/50/100%) — даёт каркас разреженным данным */
.dash-grid { stroke:var(--line); stroke-width:1; opacity:.45; }
/* .dash-bar теперь только прозрачные хит-колонки area-графика (.dash-hit) для
   тултипа — визуальной заливки НЕТ (бывшие бары удалены). Явно держим прозрачным,
   иначе полноразмерные колонки заливались бы синим (был баг «синего блока»). */
.dash-bar { fill:transparent; cursor:pointer; }
/* Подписи диапазона по оси X (первый … последний день периода) */
.dash-axis { display:flex; justify-content:space-between; margin-top:6px;
  font-size:11px; color:var(--t3); font-variant-numeric:tabular-nums; }
.dash-chart-empty { font-size:12px; color:var(--t3); text-align:center; padding:6px 0 2px; }
/* Подсказка дня на графике дохода (hover + клик/тап). position:fixed, живёт на body,
   позиционируется из JS по getBoundingClientRect бара. pointer-events:none — не ловит
   мышь (нет мерцания при наведении на саму плашку).
   ГОЧА, на которой обожглись: max-width вместе с white-space:nowrap на самой плашке
   не переносит текст, а выпускает его ЗА рамку. Поэтому ширину плашке не ограничиваем,
   nowrap висит на строках, которые ломать нельзя, а длинное разведено по строкам.
   transform занят ПОЗИЦИЕЙ (её ведёт JS, чтобы плашка ехала между соседними днями,
   а не перескакивала), поэтому появление — только через opacity. */
.dash-tip { position:fixed; z-index:60; left:0; top:0; pointer-events:none;
  background:var(--card); border:1px solid var(--line); border-radius:9px;
  box-shadow:0 8px 28px rgba(0,0,0,.32); padding:8px 11px;
  font-size:12px; color:var(--t1); font-variant-numeric:tabular-nums;
  opacity:0; transition:opacity .14s var(--ease-out), transform 90ms var(--ease-out); }
.dash-tip.is-on { opacity:1; }
.dash-tip-d { color:var(--t3); font-size:11px; margin-bottom:1px; white-space:nowrap; }
.dash-tip-v { font-weight:600; font-size:13px; white-space:nowrap; }
.dash-tip-b { display:block; margin-top:2px; color:var(--t2); font-weight:400; font-size:11.5px; white-space:nowrap; }
.dash-tip-note { margin-top:4px; color:var(--t3); font-size:11px; }
@media (prefers-reduced-motion: reduce) {
  .dash-tip { transition:opacity .12s ease; transform:none; }
  .dash-tip.is-on { transform:none; }
}

/* ── Воронка PPV ── */
.dash-podium { display:grid; grid-template-columns:2fr 1fr 1fr; gap:16px; }
.dash-funnel-step { margin:12px 0; }
.dash-funnel-track { height:8px; border-radius:999px; background:var(--bar); overflow:hidden; }
.dash-funnel-bar { height:100%; border-radius:999px; background:var(--g);
  transition: width .4s var(--ease-out); }
.dash-funnel-label { display:flex; justify-content:space-between; gap:8px;
  font-size:12.5px; color:var(--t2); margin-top:6px; }
.dash-funnel-label b { color:var(--t1); font-variant-numeric:tabular-nums; }
.dash-funnel-pct { color:var(--t3); }

/* ── Последние продажи ── */
.dash-sale-row { display:flex; align-items:center; gap:12px; padding:10px 0;
  border-top:1px solid var(--line); }
.dash-sale-row:first-of-type { border-top:0; }
/* Аватар: реальное фото из Telegram (overlay <img>) поверх кружка с инициалами;
   цвет фолбэка привязан к покупателю (см. _dashAvatarColor) */
.dash-sale-av { position:relative; overflow:hidden; flex:0 0 auto;
  width:34px; height:34px; border-radius:50%;
  display:inline-flex; align-items:center; justify-content:center;
  font-size:12.5px; font-weight:700; color:#fff; letter-spacing:.02em; }
.dash-sale-av img { position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; display:block; }
/* Имя + @username в две строки */
.dash-sale-id { flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; }
.dash-sale-name { font-weight:600; color:var(--t1);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.dash-sale-user { font-size:11.5px; color:var(--t3);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Правый блок строки: сумма сверху, время · $ снизу — right-aligned колонка */
.dash-sale-meta { flex:0 0 auto; display:flex; flex-direction:column; align-items:flex-end; gap:2px; text-align:right; }
.dash-sale-amount { display:inline-flex; align-items:center; gap:6px; font-weight:700; color:var(--t1);
  font-variant-numeric:tabular-nums; white-space:nowrap; font-size:14px; }
.dash-sale-kind { font-size:13px; line-height:1; }
.dash-sale-stars { font-variant-numeric:tabular-nums; white-space:nowrap; }
.dash-sale-sub { color:var(--t3); font-size:11.5px; font-variant-numeric:tabular-nums; white-space:nowrap; }

@media (max-width:900px){ .dash-podium{ grid-template-columns:1fr; } }

/* Движение тонкое и безопасное для prefers-reduced-motion (глобальный гард в шапке
   уже снимает transition при reduce; ширина воронки приходит готовой из инлайна) */

/* ── Цветной акцент меню вкладок редактора персонажа (вариант B: один синий) ──
   Иконки — фирменный синий; активная вкладка — синяя заливка + полоска (border-left
   уже задан выше). Перебивает light-override .editchar-tab.active порядком в файле. */
.editchar-tab .et-ic { color: var(--g); opacity: .9; }
.editchar-tab:hover .et-ic,
.editchar-tab.active .et-ic { opacity: 1; }
.editchar-tab.active { background: rgba(42,171,238,.12); }

/* ── Иконка-тогл перевода в шапке переписки (.dlg-chd) ──────────────────────
   Перенесён сюда из правой панели; «文A» = перевод RU↔EN. ВКЛ — синий с
   подсветкой, ВЫКЛ — серый призрак. */
/* Аватар собеседника в шапке переписки (заполняет «мёртвую» зону, держит центр) */
#page-dialogs .dlg-chd-av{
  width:42px; height:42px; flex:none; border-radius:50%; overflow:hidden; position:relative;
  display:flex; align-items:center; justify-content:center;
  background:var(--mint); color:var(--t2); font-weight:700; font-size:16px;
  box-shadow:0 0 0 1px var(--line), 0 1px 3px rgba(0,0,0,.18);
}
#page-dialogs .dlg-chd-av img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
/* Колонка имя + подстрока (@юзернейм · активность) */
.dlg-chd-who{ flex:1; min-width:0; display:flex; flex-direction:column; justify-content:center; }
.dlg-chd-sub{ font-size:12px; color:var(--t3); margin-top:1px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* Плашка «потрачено»: сколько денег оставил собеседник (★ + единый ≈$). Самодостаточный
   амбер-пилл — читается на свету и в тёмной теме, не зависит от контраста с фоном.
   Живёт в правой зоне шапки чата (между блоком имени и кнопками ⓘ/文A): margin-left:auto
   прижимает к правому краю, flex:none держит размер при сжатии имени. */
.dlg-chd-spent{ flex:none; margin-left:auto; margin-right:10px;
  display:inline-flex; align-items:center;
  padding:6px 13px; border-radius:999px; font-size:13.5px; font-weight:700;
  line-height:1.25; letter-spacing:.01em; white-space:nowrap; cursor:default;
  color:#8a6d00; background:rgba(245,179,1,.20); border:1px solid rgba(245,179,1,.46); }
[data-theme="dark"] .dlg-chd-spent{ color:#ffcf4d; background:rgba(245,179,1,.15); border-color:rgba(245,179,1,.32); }
.dlg-chd-tr{
  flex:none; width:34px; height:34px; display:flex; align-items:center; justify-content:center;
  border-radius:9px; border:1px solid transparent; background:transparent; color:var(--t3);
  cursor:pointer; transition:background .15s var(--ease-out), color .15s var(--ease-out),
              border-color .15s var(--ease-out), transform .1s var(--ease-out);
}
.dlg-chd-tr:hover{ background:rgba(127,127,127,.12); color:var(--t1); }
.dlg-chd-tr:active{ transform:scale(.9); }
.dlg-chd-tr.on{ color:var(--g); background:rgba(42,171,238,.14); border-color:rgba(42,171,238,.35); }
.dlg-tr-glyph{ font-size:14px; font-weight:700; letter-spacing:-.5px; line-height:1; }

/* ── Редактируемое имя/алиас прямо в шапке переписки (заменило статичное имя+ID) ──
   Выглядит как заголовок, подсвечивается на ховер, на фокусе — поле с синей рамкой. */
.dlg-chd-name{
  flex:none; align-self:flex-start; max-width:100%; box-sizing:border-box;
  font-family:var(--ff-head,inherit); font-size:15px; font-weight:700;
  letter-spacing:-.01em; color:var(--t1); background:transparent;
  border:1px solid transparent; border-radius:8px; padding:6px 9px; margin-left:-9px;
  outline:none; transition:background .15s var(--ease-out), border-color .15s var(--ease-out), box-shadow .15s var(--ease-out);
}
.dlg-chd-name::placeholder{ color:var(--t2); font-weight:600; }
.dlg-chd-name:hover{ background:rgba(127,127,127,.10); }
.dlg-chd-name:focus{ background:var(--card); border-color:var(--g); box-shadow:0 0 0 3px rgba(42,171,238,.16); }

/* ── Scenes UI (папки-сцены + drawer + лесенка медиа) ─────────────────────
   Токены: только themed (--card, --line, --t1, --t2, --g, --mint, --bar,
   --r-card, --r-ctl, --ctl, --ctl-h). Без легаси --text/--bg-input/--border.
   Анимации: только transform + opacity; iOS-кривая на drawer. */

/* ── Section header above unsorted grid */
.scn-unsorted-section { margin-bottom: 28px; }
.scn-section-hd {
  display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 12px;
  flex-wrap: wrap;   /* на узкой ширине контролы объединения переносятся, а не обрезаются */
}
/* Кнопки объединения в пак — в шапке секции (обычный поток, без position:fixed).
   flex-wrap + min-width:0 → на узком экране переносятся на новую строку целиком. */
.scn-pk-hd {
  display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-left: auto; align-self: center; min-width: 0;
}
.scn-pk-hd:empty { display: none; }
.scn-pk-hd .scn-pk-bar-go, .scn-pk-hd .scn-pk-bar-reset, .scn-pk-hd .scn-pk-bar-del { white-space: nowrap; }
@media (max-width: 640px) {
  /* На мобиле контролы — отдельной строкой во всю ширину, кнопка растягивается. */
  .scn-pk-hd { flex-basis: 100%; margin-left: 0; margin-top: 8px; }
  .scn-pk-hd .scn-pk-bar-go, .scn-pk-hd .scn-pk-bar-del { flex: 1; }
}
.scn-section-title {
  font-family: var(--ff-head); font-size: 15px; font-weight: 700;
  color: var(--t1); letter-spacing: -.012em;
}
.scn-section-count { font-size: 12px; color: var(--t2); }
/* Значок видимости в шапке секции. Оба состояния приглушены одинаково: смысл несёт
   ФОРМА (перечёркнут или нет), а не цвет — «не показывается» это нормальное
   положение дел у несортированного, а не тревога, красить его в предупреждающий
   было бы ложным сигналом. align-self:center — контейнер выровнен по baseline,
   а у svg её нет, иначе значок съезжает вниз. */
.scn-section-eye { color: var(--t3); display: inline-flex; align-self: center; }
.scn-empty-hint {
  font-size: 13px; color: var(--t2); padding: 14px 0;
  text-align: center; border: 1px dashed var(--line); border-radius: var(--r-ctl);
}

/* ── Assign-to-scene select on unsorted cards */
/* «в сцену» — primary-действие карточки-инбокса. Нативная стрелка скрыта
   (appearance:none), вместо неё кастомный SVG-шеврон в акценте; лёгкая
   акцент-заливка + текст в --g делают селект похожим на акцентную кнопку. */
.mv-assign-select {
  width: 100%;
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  padding: 8px 34px 8px 12px;
  font-size: 12px; font-weight: 600; color: var(--g);
  background-color: rgba(42,171,238,.08);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%232aabee' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
  border: 1px solid rgba(42,171,238,.28); border-radius: var(--r-ctl);
  cursor: pointer;
  transition: background-color .15s ease-out, border-color .15s ease-out, box-shadow .15s ease-out, transform .15s ease-out;
}
.mv-assign-select:hover { background-color: rgba(42,171,238,.14); border-color: rgba(42,171,238,.5); }
.mv-assign-select:focus-visible { outline: none; border-color: var(--g); box-shadow: 0 0 0 3px rgba(42,171,238,.25); }
.mv-assign-select:active { transform: scale(.98); }
.mv-assign-select option { color: var(--t1); background: var(--card); font-weight: 500; }

/* ── Scene folder grid */
.scn-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}

/* ── Scene folder card */
.scn-card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  overflow: hidden;
  cursor: pointer;
  display: flex; flex-direction: column;
  transition: transform .18s var(--ease-out), box-shadow .18s var(--ease-out);
  will-change: transform;
}
@media (hover: hover) and (pointer: fine) {
  .scn-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-card-hover);
  }
}
.scn-card:active { transform: scale(.98); }
.scn-card-dragging { opacity: .4; }
.scn-card.scn-card-over {
  border-color: var(--g);
  box-shadow: 0 0 0 2px rgba(42,171,238,.25);
}

/* Cover image area */
.scn-cover {
  height: 72px; overflow: hidden; position: relative;
  background: var(--bar);
  display: flex; align-items: center; justify-content: center;
}
.scn-cover-placeholder { font-size: 28px; opacity: .35; }
.scn-cover-media { width: 100%; height: 100%; object-fit: cover; display: block; }

.scn-card-body { padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }

/* Названия карточек НАМЕРЕННО легче заголовка секции (.scn-section-title): секция —
   уровень выше, карточка внутри неё. Уравнять их весом — значит сплющить иерархию. */
.scn-card-title {
  font-size: 13px; font-weight: 600; color: var(--t1);
  display: flex; align-items: center; gap: 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.scn-disabled-dot { color: var(--t2); font-size: 11px; flex: none; }

/* Ladder strip (free→★ pills on card; обзор градации выдачи без миниатюр) */
.scn-strip { display: flex; gap: 4px; flex-wrap: wrap; min-height: 18px; }
.scn-th-pill {
  font-size: 10px; font-weight: 700; line-height: 1.4;
  padding: 1px 7px; border-radius: 999px; flex: none;
  border: 1px solid transparent; letter-spacing: -.01em;
}
.scn-th-pill.free { background: rgba(42,138,58,.16);  color: #2a8a3a; border-color: rgba(42,138,58,.3); }
.scn-th-pill.paid { background: rgba(184,144,10,.16); color: #b8900a; border-color: rgba(184,144,10,.3); }

/* Chips row on card */
.scn-chips { display: flex; gap: 4px; flex-wrap: wrap; }
.scn-chip {
  font-size: 10px; padding: 2px 7px; border-radius: 999px;
  background: var(--ctl); border: 1px solid var(--line);
  color: var(--t2); white-space: nowrap;
}

/* Card actions: грип-ручка (drag) слева + удаление справа */
.scn-card-actions {
  display: flex; align-items: center; justify-content: space-between;
  padding-top: 2px;
}
.scn-card-grip {
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--t3); cursor: grab; opacity: .45;
  padding: 4px; border-radius: 6px;
  transition: opacity .12s var(--ease-out), color .12s var(--ease-out);
}
.scn-card:hover .scn-card-grip { opacity: 1; }
.scn-card-grip:active { cursor: grabbing; }
/* Кнопка подписана словом «сцену»: та же мусорка без подписи стояла на экране
   рядом с «Удалить» бара персонажа (на узких — вообще иконка-в-иконку), и их
   путали. Текст мелкий, чтобы не спорить с названием сцены выше. */
.scn-card-del {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  background: transparent; border: none; color: var(--t2);
  font-family: var(--ff-body); font-size: 11px; font-weight: 600; white-space: nowrap;
  cursor: pointer; opacity: .55; padding: 5px 6px; border-radius: 6px;
  transition: opacity .12s var(--ease-out), color .12s var(--ease-out), background .12s var(--ease-out);
}
.scn-card-del:hover { opacity: 1; color: var(--bad, #E0533B); background: rgba(224,83,59,.08); }
.scn-card-del:active { transform: scale(.9); }

/* Add-new card */
.scn-add-card {
  border: 1.5px dashed var(--line); border-radius: var(--r-card);
  min-height: 130px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px;
  font-size: 13px; color: var(--t2); cursor: pointer;
  transition: border-color .18s, color .18s, background .18s;
}
.scn-add-icon { font-size: 22px; opacity: .6; }
@media (hover: hover) and (pointer: fine) {
  .scn-add-card:hover {
    border-color: var(--g); color: var(--g); background: rgba(42,171,238,.05);
  }
}
.scn-add-card:active { transform: scale(.98); }

/* ── Drawer shell */
#scn-drawer-root { position: fixed; inset: 0; z-index: 500; pointer-events: none; }
.scn-scrim {
  position: absolute; inset: 0;
  background: rgba(0,0,0,.42);
  opacity: 0; pointer-events: none;
  transition: opacity 240ms var(--ease-out);
}
.scn-drawer {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: clamp(360px, 52vw, 640px);
  background: var(--card); border-left: 1px solid var(--line);
  box-shadow: -16px 0 48px rgba(0,0,0,.22);
  display: flex; flex-direction: column;
  transform: translateX(100%);
  /* iOS-like drawer curve (from Ionic Framework) */
  transition: transform 280ms cubic-bezier(0.32,0.72,0,1);
  pointer-events: all;
}
.scn-drawer--open { transform: translateX(0); }
/* When drawer is open, scrim becomes visible + interactive */
.scn-drawer--open ~ .scn-scrim,
#scn-drawer-root:has(.scn-drawer--open) .scn-scrim {
  opacity: 1; pointer-events: all;
}

.scn-drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 20px; border-bottom: 1px solid var(--line); flex: none;
}
.scn-drawer-title {
  font-family: var(--ff-head); font-size: 18px; font-weight: 700;
  color: var(--t1); letter-spacing: -.013em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  /* Жмётся заголовок, а не кнопки: длинное название сцены иначе выталкивало бы
     «Удалить сцену» и ✕ за правый край дровера. */
  flex: 1 1 auto; min-width: 0;
}
.scn-drawer-head-act { display: flex; align-items: center; gap: 8px; flex: none; }
/* СВОЯ кнопка удаления у сцены. Раньше единственная жила на карточке за
   затемнением, поэтому из открытой сцены удаляли ближайшей кнопкой — «Удалить»
   в баре персонажа — и сносили персонажа. Подписана словом: голая мусорка
   повторяла бы иконку персонажа один-в-один. */
.scn-drawer-del {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  background: transparent; border: 1px solid var(--line); border-radius: 8px;
  padding: 6px 10px; font-family: var(--ff-body); font-size: 12.5px; font-weight: 600;
  color: var(--t2); white-space: nowrap; cursor: pointer;
  transition: color .12s, border-color .12s, background .12s;
}
.scn-drawer-del:hover {
  color: var(--bad, #E0533B); border-color: rgba(224,83,59,.45); background: rgba(224,83,59,.10);
}
.scn-drawer-del:active { transform: scale(.97); }
.scn-drawer-close {
  flex: none; width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid transparent;
  border-radius: 8px; color: var(--t2); cursor: pointer; font-size: 16px;
  transition: background .12s, color .12s, border-color .12s;
}
.scn-drawer-close:hover { background: var(--ctl); color: var(--t1); border-color: var(--line); }
.scn-drawer-close:active { transform: scale(.93); }

.scn-drawer-body {
  flex: 1; overflow-y: auto; padding: 20px;
  scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent;
}

/* ── Group sections inside drawer */
.scn-grp { margin-bottom: 24px; }
.scn-grp-h {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 12px; font-weight: 600; text-transform: uppercase;
  letter-spacing: .07em; color: var(--t2);
  border-bottom: 1px solid var(--line); padding-bottom: 9px; margin-bottom: 14px;
}
.scn-grp-hint { font-size: 11px; font-weight: 400; text-transform: none; letter-spacing: 0; opacity: .7; }

/* Fields */
.scn-fld { margin-bottom: 14px; }
.scn-fld-row { display: flex; gap: 12px; }
.scn-fld-row > .scn-fld { flex: 1; }
.scn-lbl {
  display: block; font-size: 12.5px; color: var(--t2);
  margin-bottom: 6px; line-height: 1.3;
}
.scn-inp {
  width: 100%; box-sizing: border-box;
  background: var(--ctl); border: 1px solid var(--line);
  border-radius: var(--r-ctl); padding: 10px 13px;
  color: var(--t1); font-size: 14px; font-family: var(--ff-body);
  transition: border-color .15s, box-shadow .15s;
  outline: none;
}
.scn-inp:focus {
  border-color: var(--g); box-shadow: 0 0 0 3px rgba(42,171,238,.14);
}
.scn-ta { resize: vertical; min-height: 68px; line-height: 1.45; }
select.scn-inp {
  cursor: pointer;
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  padding-right: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238b93a1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
}

/* Enabled toggle label */
.scn-toggle-label {
  display: flex; align-items: center; gap: 7px;
  font-size: 13.5px; color: var(--t2); cursor: pointer;
  user-select: none;
}
.scn-toggle-label input[type=checkbox] { accent-color: var(--g); width: 17px; height: 17px; cursor: pointer; }

/* ── Ladder rows */
.scn-ladder { display: flex; flex-direction: column; gap: 10px; }
.scn-lad-empty {
  font-size: 14px; color: var(--t2); text-align: center;
  padding: 22px 0; border: 1px dashed var(--line); border-radius: var(--r-ctl);
}
.scn-lad-row {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--ctl); border: 1px solid var(--line);
  border-radius: 14px; padding: 10px 12px;
  transition: border-color .16s var(--ease-out), background .16s var(--ease-out),
              box-shadow .16s var(--ease-out), opacity .15s;
  cursor: default;
  position: relative;
}

/* ── Общий скелет карточки лесенки: одиночный лот И пак рисуются одинаково ─────
   main-строка [ручка · превью/обложка · контролы · действие] → (лента пака) →
   описание-внизу. Разница лот/пак — явная: лот=превью+free/paid, пак=стопка+📦. */
.scn-card-main { display: flex; align-items: flex-start; gap: 11px; width: 100%; }
.scn-card-ctl  { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.scn-card-row1 { display: flex; align-items: center; gap: 7px 9px; flex-wrap: wrap; min-height: 30px; }
.scn-card-row2 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; min-width: 0; }

/* Правый блок действий карточки: шеврон описания + удалить/разбить */
.scn-card-trail { flex: none; align-self: flex-start; display: flex; align-items: center; gap: 4px; }

/* Описание — скрыто, разворачивается шевроном справа на всю ширину карточки внизу */
.scn-card-cap { width: 100%; display: none; }
.scn-ucard.cap-open > .scn-card-cap { display: block; }
.scn-cap-toggle {
  flex: none; position: relative; width: 28px; height: 28px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--line); border-radius: 8px;
  color: var(--t3); cursor: pointer; opacity: .75;
  transition: color .12s, border-color .12s, background .12s, opacity .12s;
}
.scn-ucard:hover .scn-cap-toggle { opacity: 1; }
.scn-cap-toggle:hover { color: var(--t1); border-color: rgba(42,171,238,.4); background: rgba(42,171,238,.08); }
.scn-cap-toggle:active { transform: scale(.94); }
.scn-cap-chev { transition: transform .18s var(--ease-out); }
.scn-ucard.cap-open .scn-cap-chev { transform: rotate(180deg); }
/* Точка-индикатор «есть текст» */
.scn-cap-toggle.has::after {
  content: ''; position: absolute; top: -2px; right: -2px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--g); border: 2px solid var(--ctl);
}
.scn-ucard.cap-open .scn-cap-toggle { color: var(--t1); border-color: rgba(42,171,238,.4); background: rgba(42,171,238,.1); }
.scn-lad-row:hover { border-color: var(--mint-bd); }
.scn-lad-row.scn-lad-dragging {
  opacity: .96; box-shadow: 0 12px 30px rgba(0,0,0,.32);
  border-color: var(--g); cursor: grabbing;
}
/* Соседи сдвигаются трансформом с короткой кривой — без репейнта контента */
.scn-lad-row.scn-lad-shifting { transition: transform .16s cubic-bezier(0.2,0,0,1); }
.scn-lad-row.scn-lad-over {
  border-color: var(--g); background: rgba(42,171,238,.07);
}
.scn-lad-handle {
  align-self: flex-start; display: flex; align-items: center; height: 56px;
  color: var(--t3); font-size: 14px; letter-spacing: -1px;
  cursor: grab; flex: none; padding: 0 2px; line-height: 1; user-select: none;
  border-radius: 8px;
  touch-action: none;   /* pointer-drag не должен скроллить страницу на тач-устройствах */
  opacity: .45; transition: opacity .12s, color .12s, background .12s;
}
.scn-lad-row:hover .scn-lad-handle { opacity: 1; }
.scn-lad-handle:hover { color: var(--t1); background: var(--ctl-h); }
.scn-lad-handle:active { cursor: grabbing; }

.scn-lad-thumb {
  width: 56px; height: 56px; flex: none; align-self: flex-start;
  border-radius: 11px; background: var(--bar);
  border: 1px solid var(--line); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.scn-lad-thumb-media {
  width: 100%; height: 100%; object-fit: cover; display: block;
  /* Превью кликабельно — открывает лайтбокс на весь экран (scnLoadLadderThumb). */
  cursor: zoom-in;
  /* Как у эталона .mv-preview-media: иначе нативный drag <img>/<video> перехватывает
     жест — чуть смазал мышью при клике, браузер начал тащить картинку, click не
     приходит вовсе и лайтбокс «открывается через раз». Заодно не мешает драгу строки. */
  -webkit-user-drag: none; user-drag: none; user-select: none;
}
.scn-lad-thumb-circle { border-radius: 50%; }

.scn-lad-mid { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }

/* Tier 1 — primary controls: free/paid · price · накал — one prominent row */
.scn-lad-tier1 {
  display: flex; align-items: center; gap: 7px 10px; flex-wrap: wrap;
}

/* Tier 2 — secondary controls: эффект + collapsed description */
.scn-lad-tier2 {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  min-width: 0;
}

/* Единая мини-подпись контрола («накал», «эффект») */
.scn-mini-label {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--t3); user-select: none; white-space: nowrap;
}

/* Сегмент-переключатель (free/paid и эффект) — «колодец» с пилюлей внутри */
.scn-seg {
  display: inline-flex; gap: 2px; padding: 3px; flex: none;
  background: var(--bg-input); border: 1px solid var(--line); border-radius: 10px;
}
.scn-seg-btn {
  font-size: 12px; font-weight: 600; padding: 6px 11px; border-radius: 7px;
  background: transparent; border: none; cursor: pointer; color: var(--t2); line-height: 1.1;
  transition: background .14s var(--ease-out), color .14s var(--ease-out), transform .1s var(--ease-out);
}
.scn-seg-btn:hover { color: var(--t1); background: var(--ctl-h); }
.scn-seg-btn:active { transform: scale(.95); }

/* Price input */
.scn-lad-price {
  width: 76px; background: var(--bg-input); border: 1px solid var(--line);
  border-radius: 9px; padding: 6px 9px; font-size: 13px; color: var(--t1);
  text-align: right; outline: none;
  transition: border-color .14s;
}
.scn-lad-price:focus { border-color: var(--g); }

/* Накал — компактный «меттер»: 5 тонких делений с тёплой нарастающей заливкой.
   Раньше были 5 широких ярких coral-кнопок с цифрами — доминировали по весу и
   ширине. Теперь форма читается как шкала жара; цифры спрятаны, уровень = число
   залитых делений. Слова «накал» нет — крошечный 🌶 + tooltip несут смысл. */
.scn-spice-ctl { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.scn-spice-hint { font-size: 12px; line-height: 1; flex: none; filter: saturate(.85); cursor: default; }
.scn-spice-btns {
  display: inline-flex; gap: 2px; padding: 3px;
  background: var(--bg-input); border: 1px solid var(--line); border-radius: 8px;
}
.scn-spice-btn {
  width: 13px; height: 20px; border-radius: 3px; border: 0;
  background: var(--ctl); cursor: pointer; padding: 0;
  font-size: 0; color: transparent;       /* цифру прячем — меттер читается формой */
  transition: background .14s var(--ease-out), transform .1s var(--ease-out);
}
.scn-spice-btn:hover { background: var(--ctl-h); }
.scn-spice-btn:active { transform: scaleY(.86); }
/* Тёплая нарастающая шкала: чем выше уровень, тем горячее цвет залитого деления */
.scn-spice-btn.on:nth-child(1) { background: #e7b24c; }
.scn-spice-btn.on:nth-child(2) { background: #ea9a45; }
.scn-spice-btn.on:nth-child(3) { background: #ec7f3f; }
.scn-spice-btn.on:nth-child(4) { background: #e76a44; }
.scn-spice-btn.on:nth-child(5) { background: #e0594e; }

/* ── Collapsed description disclosure (.scn-cap = <details>) ────────────────── */
/* Remove browser default marker; add our own rotating arrow via CSS */
.scn-cap { min-width: 0; }
.scn-cap > summary { list-style: none; }
.scn-cap > summary::-webkit-details-marker { display: none; }

.scn-cap-sum {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer;
  font-size: 11.5px; font-weight: 500; color: var(--t3);
  padding: 4px 8px; border-radius: 7px; user-select: none;
  background: transparent; border: 1px solid transparent;
  transition: color .12s var(--ease-out), background .12s var(--ease-out),
              border-color .12s var(--ease-out), transform .1s var(--ease-out);
  white-space: nowrap; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
}
.scn-cap-sum:active { transform: scale(0.98); }
/* Описание — всегда отдельная строка внизу карточки, на всю ширину (для лота и
   пака одинаково). Раньше у лота сидело в одном ряду с «эффект» → разнобой. */
.scn-card-cap > .scn-cap-sum { padding-left: 2px; }
.scn-cap-sum::before {
  content: '▸'; font-size: 10px; flex: none;
  transition: transform .15s var(--ease-out);
  display: inline-block;
}
.scn-cap[open] > .scn-cap-sum::before { transform: rotate(90deg); }
.scn-cap-sum:hover {
  color: var(--t2); background: var(--ctl-h);
}
/* Точка-индикатор «есть текст» рядом со словом «описание» */
.scn-cap-dot { color: var(--g); font-size: 7px; vertical-align: middle; margin-left: 1px; }

/* Caption — autosize-textarea: высота под содержимое (JS scnCapGrow), от одной
   строки (min-height) до потолка 240px (дальше скролл). Без обрезки текста на
   полстроки — длинная подсказка видна целиком. height анимируется транзишеном. */
.scn-lad-cap {
  width: 100%; box-sizing: border-box; display: block;
  background: var(--bg-input); border: 1px solid var(--line);
  border-radius: 9px; padding: 9px 12px; font-size: 13px;
  color: var(--t1); outline: none;
  font-family: inherit; line-height: 1.45;
  min-height: calc(1.45em + 20px); max-height: 240px;
  resize: none; overflow-y: auto;
  transition: border-color .14s, background .14s, height .18s var(--ease-out);
  margin-top: 6px;
}
.scn-lad-cap::placeholder { color: var(--t3); }
.scn-lad-cap:focus { border-color: var(--g); }

/* Delete/unassign button */
.scn-lad-del {
  flex: none; align-self: flex-start; background: transparent; border: none;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--t3); cursor: pointer; opacity: .4;
  padding: 6px; border-radius: 8px;
  transition: opacity .12s, background .12s, color .12s, transform .1s var(--ease-out);
}
.scn-lad-row:hover .scn-lad-del { opacity: .75; }
.scn-lad-del:hover { opacity: 1; color: var(--bad, #E0533B); background: rgba(224,83,59,.12); }
.scn-lad-del:active { transform: scale(.9); }

/* Pack-select checkbox: hidden at rest, revealed on row hover; always shown when checked */
.scn-pk-selwrap { opacity: 0; transition: opacity .14s var(--ease-out); }
.scn-lad-row:hover .scn-pk-selwrap { opacity: 1; }
/* Несортированное (.mv-card) — та же оверлей-разметка чекбокса, что у лесенки сцены. */
.mv-card:hover .scn-pk-selwrap { opacity: 1; }
.scn-pk-selwrap:has(.scn-pk-sel:checked) { opacity: 1; }
/* Fallback for browsers without :has() — checkbox keeps native opacity when checked
   (the checkbox itself will still be visible due to browser focus ring) */

/* ── dropp-расклад — origin-aware поповер, привязанный к полю ЦЕНЫ ──────────── */
/* Главная правка: раньше расклад проявлялся на hover ВСЕЙ карточки → в редакторе
   мышь почти всегда над какой-то строкой, и цифры «маячили». Теперь он всплывает
   ТОЛЬКО при наведении/фокусе на саму цену — там, где он и нужен. position:absolute
   → ноль reflow, карточки не дёргаются. Scale из верх-лево = из-под цены (emil). */
.scn-lad-dropp, .scn-pk-dropp {
  position: absolute; top: calc(100% + 7px); left: 0; z-index: 40;
  min-width: 196px; width: max-content; max-width: 300px;
  padding: 9px 11px; text-align: left;
  background: var(--bg-card); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 2px 6px rgba(0,0,0,.28), 0 16px 38px -14px rgba(0,0,0,.6);
  opacity: 0; pointer-events: none;
  transform: translateY(-4px) scale(.96); transform-origin: top left;
  transition: opacity .16s var(--ease-out), transform .16s var(--ease-out);
}
.scn-price:hover .scn-lad-dropp,  .scn-price:focus-within .scn-lad-dropp,
.scn-price:hover .scn-pk-dropp,   .scn-price:focus-within .scn-pk-dropp {
  opacity: 1; pointer-events: auto; transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .scn-lad-dropp, .scn-pk-dropp { transform: none; }
  .scn-price:hover .scn-lad-dropp, .scn-price:focus-within .scn-lad-dropp,
  .scn-price:hover .scn-pk-dropp,  .scn-price:focus-within .scn-pk-dropp { transform: none; }
  .scn-cap-sum::before { transition: none; }
  .scn-cap-sum:active { transform: none; }
}

/* Ladder add-to-scene footer */
.scn-lad-add {
  display: flex; gap: 8px; margin-top: 10px; align-items: stretch;
}
.scn-lad-kind {
  flex: none; font-size: 12px; padding: 8px 8px;
  background: var(--ctl); border: 1px solid var(--line);
  border-radius: 8px; color: var(--t2); cursor: pointer;
  transition: border-color .15s, color .15s;
}
.scn-lad-kind:hover { border-color: var(--g); color: var(--t1); }
.scn-lad-kind:focus { outline: none; border-color: var(--g); }
.scn-lad-add-btn {
  flex: 1; text-align: center; font-size: 12px; font-weight: 500;
  border: 1.5px dashed var(--line); border-radius: 8px; padding: 8px 10px;
  color: var(--t2); background: transparent; cursor: pointer;
  transition: border-color .15s, color .15s, background .15s;
  line-height: 1.3;
}
.scn-lad-add-btn:hover { border-color: var(--g); color: var(--g); background: rgba(42,171,238,.05); }

/* ── Stock picker (inline inside drawer) */
.scn-stock-picker {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-card); padding: 12px;
  margin-bottom: 12px;
}
.scn-stock-head {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 13px; font-weight: 600; color: var(--t1); margin-bottom: 10px;
}
.scn-stock-head button {
  background: transparent; border: none; color: var(--t2);
  font-size: 16px; cursor: pointer; padding: 2px 6px; border-radius: 5px;
  transition: background .12s;
}
.scn-stock-head button:hover { background: var(--ctl); }
.scn-stock-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 6px;
  margin-bottom: 10px;
}
.scn-stock-item {
  position: relative; aspect-ratio: 1; border-radius: 8px;
  border: 2px solid var(--line); overflow: hidden; cursor: pointer;
  transition: border-color .14s, transform .14s;
}
.scn-stock-item:hover { border-color: var(--g); }
.scn-stock-item.selected { border-color: var(--g); }
.scn-stock-item.selected .scn-stock-sel { opacity: 1; }
.scn-stock-prev { width: 100%; height: 100%; background: var(--bar); }
.scn-stock-sel {
  position: absolute; top: 3px; right: 3px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--g); color: #fff; font-size: 11px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .14s;
}
/* Тайл пака в стоковом пикере (склад → сцена): счётчик снизу-слева, симметрично
   .scn-stock-sel снизу-справа — пак виден как один выбираемый юнит, а не N. */
.scn-stock-pack-badge {
  position: absolute; left: 3px; bottom: 3px; z-index: 2;
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px;
  background: rgba(0,0,0,.65); color: #fff; font-size: 10px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.scn-stock-foot { display: flex; justify-content: flex-end; }

/* Dark-theme surface overrides (surfaces already themed via --card/--ctl tokens,
   these are guards for elements that have hard-coded fallback colors above) */
[data-theme="dark"] .scn-th-pill.free { background: rgba(42,138,58,.22);  color: #4ade80; border-color: rgba(42,138,58,.4); }
[data-theme="dark"] .scn-th-pill.paid { background: rgba(184,144,10,.22); color: #fbbf24; border-color: rgba(184,144,10,.4); }
/* ── End Scenes UI ────────────────────────────────────────────────────────── */

/* Per-media effect control (spoiler / self-destruct) */
.scn-fx-ctl { display: flex; align-items: center; gap: 9px; }
.scn-fx-seg .scn-seg-btn { min-width: 34px; padding: 5px 8px; font-size: 14px; }
.scn-fx-seg .scn-seg-btn.on { background: var(--ctl-h); }
.scn-fx-ttl {
  padding: 7px 10px; border-radius: 9px; font-size: 13px; cursor: pointer; outline: none;
  background: var(--bg-input); color: var(--t1); border: 1px solid var(--line);
  transition: border-color .14s;
}
.scn-fx-ttl:focus { border-color: var(--g); }

/* ── Цена Stars: постоянная метка ★ (не placeholder, не путается с фиатом) ── */
.scn-stars {
  display: inline-flex; align-items: stretch; flex: none;
  background: var(--bg-input); border: 1px solid var(--line);
  border-radius: 9px; overflow: hidden; transition: border-color .14s;
}
.scn-stars:focus-within { border-color: var(--g); }
.scn-stars-tag {
  display: flex; align-items: center; padding: 0 7px; font-size: 12px;
  color: #e3b341; background: rgba(227,179,65,.12);
  border-right: 1px solid var(--line); user-select: none;
}
.scn-stars-inp.scn-lad-price {
  width: 52px; border: 0; border-radius: 0; background: transparent;
}

/* ── dropp.fans (оплата картой): единый обведённый «колодец», переносится целиком ── */
.scn-dropp-box {
  display: inline-flex; align-items: center; gap: 3px; flex: none;
  padding: 2px 4px 2px 8px; border-radius: 9px;
  background: var(--bg-input); border: 1px solid var(--line);
  transition: border-color .14s;
}
.scn-dropp-tag {
  font-size: 11px; font-weight: 600; letter-spacing: .01em;
  color: var(--t3); white-space: nowrap; user-select: none; padding-right: 2px;
}
.scn-dropp-price.scn-lad-price {
  width: 50px; border: 1px solid transparent; background: transparent; padding-left: 2px;
}
.scn-dropp-price.scn-lad-price:focus { border-color: var(--g); background: var(--ctl); }
.scn-dropp-ccy.scn-fx-ttl {
  padding: 4px 4px; font-size: 12px; border-color: transparent; background: transparent;
}
.scn-dropp-ccy.scn-fx-ttl:focus { border-color: var(--g); background: var(--ctl); }

/* Чип-приглашение, когда dropp у владельца не привязан */
.scn-dropp-chip {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  font-size: 11.5px; font-weight: 500; color: var(--t2);
  padding: 7px 12px; border-radius: 9px; cursor: pointer;
  background: transparent; border: 1px dashed var(--line);
  transition: border-color .15s, color .15s, background .15s;
}
.scn-dropp-chip:hover { border-color: var(--g); color: var(--g); background: rgba(42,171,238,.06); }

/* ── Обёртка превью лота: система координат для оверлеев ──
   position:relative нужен чекбоксу пака (.scn-pk-selwrap, position:absolute).
   Бейджи статуса заливки (.scn-thumb-badge и состояния) отсюда УДАЛЕНЫ вместе с
   рендером в scnLadderRow — статус живёт только в поповере пилюли цены. */
.scn-lad-thumb-wrap { position: relative; flex: none; align-self: flex-start; }

/* ══ Паки: мульти-выбор медиа лесенки → альбом / платный набор ══════════════ */

/* Чекбокс выбора — ОВЕРЛЕЙ на углу превью (не в потоке), иначе он сдвигал бы ручку
   и превью одиночки вправо → левый край не совпадал бы с паком (у пака чекбокса нет). */
.scn-pk-selwrap {
  position: absolute; top: 4px; left: 4px; z-index: 4;
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0; cursor: pointer;
  background: rgba(8,10,14,.55); border-radius: 7px;
}
.scn-pk-sel {
  width: 17px; height: 17px; cursor: pointer; accent-color: var(--g);
  margin: 0; flex: none;
}
.scn-pk-sel:disabled { cursor: not-allowed; opacity: .35; }
.scn-pk-selwrap:has(.scn-pk-sel:disabled) { cursor: not-allowed; }

/* ── Плашка пака: один пак = одна строка лесенки (контролы уровня пака) ── */
.scn-pk-plaque {
  display: flex; flex-direction: column; gap: 8px;
  padding: 10px 12px; border-radius: 14px;
  background:
    linear-gradient(rgba(42,171,238,.05), rgba(42,171,238,.05)),
    var(--ctl);
  border: 1px solid rgba(42,171,238,.38);
  position: relative;
}
/* Обложка пака = РЕАЛЬНОЕ первое фото (параллель превью одиночки), слоистая тень
   = «их несколько», бейдж справа-внизу = счётчик. Остальные фото — флай-аут ниже
   по наведению на обложку (в покое набор = компактная карточка как одиночный лот). */
.scn-pk-coverwrap { flex: none; align-self: flex-start; position: relative; }
/* Фрейм обложки = ровно как превью одиночки (.scn-lad-thumb): нейтральная рамка,
   тот же радиус/фон. «Их несколько» несёт бейдж-счётчик, не рамка. */
.scn-pk-cover {
  width: 56px; height: 56px; position: relative;
  border-radius: 11px; background: var(--bar);
  border: 1px solid var(--line); overflow: visible;
  display: flex; align-items: center; justify-content: center;
}
.scn-pk-cover .scn-pk-thumb-media, .scn-pk-cover img, .scn-pk-cover video {
  width: 100%; height: 100%; object-fit: cover; border-radius: 11px; display: block;
}
.scn-pk-cover-badge {
  position: absolute; right: -7px; bottom: -7px; z-index: 3;
  display: inline-flex; align-items: center; gap: 3px;
  background: var(--g); color: #06243a; font-weight: 800; font-size: 10.5px; line-height: 1;
  border-radius: 20px; padding: 3px 7px 3px 5px; border: 2px solid var(--ctl);
}
.scn-pk-cover-badge svg { display: block; }
/* Лента членов набора — ПОПОВЕР-окошко: клик по обложке → плавающая карточка со
   всеми фото (как тултип). Anchored к обложке (origin top-left), скролл если много.
   Закрывается кликом вне (JS pkTogglePhotos). Без reflow карточки. */
.scn-pk-cover { cursor: pointer; }
.scn-pk-strip {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 45;
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  width: max-content; max-width: 480px; max-height: 300px; overflow-y: auto;
  padding: 11px; background: var(--bg-card); border: 1px solid var(--line);
  border-radius: 14px; box-shadow: 0 2px 6px rgba(0,0,0,.3), 0 18px 46px -14px rgba(0,0,0,.66);
  opacity: 0; pointer-events: none; transform: translateY(-6px) scale(.96); transform-origin: top left;
  transition: opacity .16s var(--ease-out), transform .16s var(--ease-out);
}
.scn-pk-coverwrap.pop-open .scn-pk-strip { opacity: 1; pointer-events: auto; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .scn-pk-strip { transform: none; }
  .scn-pk-coverwrap.pop-open .scn-pk-strip { transform: none; }
}
/* Плашка подсвечена как drop-зона: тащим одиночку и зависли над набором. */
.scn-pk-plaque--drop-target {
  border-color: var(--g); box-shadow: 0 0 0 2px rgba(42,171,238,.35);
}

/* ── Извлечение фото из пака: тащим тумбу за пределы полоски ── */
/* Полоска — попап с overflow-y:auto, поэтому вынесенную тумбу везёт «призрак» в
   <body> (position:fixed), а исходная гаснет на месте. */
.scn-pk-ghost {
  border-radius: 10px; overflow: hidden; border: 1px solid var(--g);
  box-shadow: 0 14px 34px -8px rgba(0,0,0,.7); opacity: .95;
  transform-origin: center; will-change: transform;
}
.scn-pk-thumb-lifted { opacity: .3; }
.scn-pk-plaque--extracting { border-color: rgba(224,83,59,.45); }
/* Линия в лесенке = место, где фото станет обычной строкой, если отпустить. */
.scn-lad-insert-mark {
  height: 3px; border-radius: 2px; margin: 5px 0;
  background: var(--g); box-shadow: 0 0 0 3px rgba(42,171,238,.16);
}
/* Новая строка не «выскакивает»: подъезжает под прилетающий призрак. */
@keyframes scnRowIn {
  from { opacity: 0; transform: translateY(-6px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
.scn-lad-row--enter { animation: scnRowIn .26s cubic-bezier(.2,.7,.3,1) both; }
@media (prefers-reduced-motion: reduce) {
  .scn-lad-row--enter { animation: none; }
}
.scn-pk-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.scn-pk-handle {
  align-self: flex-start; display: flex; align-items: center; height: 56px;
  color: var(--t3); font-size: 14px; letter-spacing: -1px; cursor: grab;
  flex: none; padding: 0 2px; line-height: 1; user-select: none; border-radius: 8px;
  touch-action: none; opacity: .45; transition: opacity .12s, color .12s, background .12s;
}
.scn-pk-plaque:hover .scn-pk-handle { opacity: 1; }
.scn-pk-handle:hover { color: var(--t1); background: var(--ctl-h); }
.scn-pk-handle:active { cursor: grabbing; }
/* Пилюля цены платного лота/пака — то же золото: цена и есть признак платности. */
.scn-price.paid { border-color: rgba(227,179,65,.35); }
.scn-price.paid .scn-price-tag,
.scn-price.paid .scn-price-inp { color: #e3b341; }
[data-theme="dark"] .scn-price.paid .scn-price-tag,
[data-theme="dark"] .scn-price.paid .scn-price-inp { color: #fbbf24; }
.scn-pk-spacer { flex: 1; }
.scn-pk-disband, .scn-pk-unassign {
  flex: none; align-self: flex-start;
  background: transparent; border: 1px solid var(--line); color: var(--t3); cursor: pointer;
  padding: 5px 9px; border-radius: 8px; font-size: 11.5px; font-weight: 600;
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; opacity: .8;
  transition: color .12s, border-color .12s, background .12s, opacity .12s;
}
.scn-pk-plaque:hover .scn-pk-disband, .scn-pk-plaque:hover .scn-pk-unassign { opacity: 1; }
.scn-pk-disband:hover {
  color: var(--t1); border-color: rgba(42,171,238,.4); background: rgba(42,171,238,.08);
}
/* «убрать из сцены» — тот же смысл, что trash у одиночного медиа (scn-lad-del):
   пак покидает сцену целиком, но не расформировывается — красный (destructive-lite)
   hover отличает её от нейтрально-синего «разбить». */
.scn-pk-unassign:hover {
  color: var(--bad, #E0533B); border-color: rgba(224,83,59,.4); background: rgba(224,83,59,.08);
}
.scn-pk-strip { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.scn-pk-thumb {
  width: 60px; height: 60px; flex: none; position: relative;
  border-radius: 10px; overflow: hidden; border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center; color: var(--t3);
}
.scn-pk-thumb-media {
  width: 100%; height: 100%; object-fit: cover; display: block;
  /* Как у эталона .mv-preview-media: без запрета нативный drag <img>/<video>
     перехватывает жест — клик по превью члена набора не доходит до лайтбокса, а
     драг миниатюры внутри полоски (перестановка/вынос из набора) тащит картинку. */
  -webkit-user-drag: none; user-drag: none; user-select: none;
}
/* Курсор только у превью В ПОЛОСКЕ набора: там клик открывает лайтбокс. У обложки
   (.scn-pk-cover) тот же класс, но клик по ней разворачивает полоску — не lightbox,
   поэтому zoom-in ей давать нельзя, соврал бы. */
.scn-pk-thumb > .scn-pk-thumb-media { cursor: zoom-in; }
.scn-pk-ord {
  position: absolute; left: 3px; top: 3px;
  width: 16px; height: 16px; border-radius: 5px;
  background: rgba(0,0,0,.6); color: #fff; font-size: 10px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; pointer-events: none;
}
/* Маленькая ручка ⠿ для реордера фото ВНУТРИ набора (горизонтальный драг). */
.scn-pk-thumb-handle {
  position: absolute; right: 3px; bottom: 3px; z-index: 2;
  font-size: 11px; line-height: 1; letter-spacing: -1px; color: #fff;
  background: rgba(0,0,0,.5); border-radius: 4px; padding: 1px 3px;
  opacity: .7; cursor: grab; user-select: none; touch-action: none;
  transition: opacity .12s;
}
.scn-pk-thumb:hover .scn-pk-thumb-handle { opacity: .95; }
.scn-pk-thumb-handle:active { cursor: grabbing; }
.scn-pk-thumb.dragging {
  z-index: 20; transition: none; cursor: grabbing;
  box-shadow: 0 8px 20px rgba(0,0,0,.4); border-color: var(--g);
}
/* Соседи едут трансформом с короткой кривой — без репейнта превью. */
.scn-pk-thumb-shifting { transition: transform .16s cubic-bezier(0.2,0,0,1); }
.scn-pk-count {
  font-size: 11.5px; font-weight: 700; color: var(--t3);
  background: var(--bg-input); border: 1px solid var(--line); border-radius: 20px; padding: 3px 9px;
}
.scn-pk-cap {
  width: 100%; box-sizing: border-box; display: block;
  background: var(--bg-input); border: 1px solid var(--line);
  border-radius: 9px; padding: 9px 12px; font-size: 13px; color: var(--t1);
  outline: none; font-family: inherit; line-height: 1.45;
  min-height: calc(1.45em + 20px); max-height: 240px;
  resize: none; overflow-y: auto;
  transition: border-color .14s, background .14s, height .18s var(--ease-out);
  margin-top: 6px;
}
.scn-pk-cap::placeholder { color: var(--t3); }
.scn-pk-cap:focus { border-color: var(--g); }
/* Pack-level description disclosure — same <details>/<summary> pattern as single lots */
.scn-pk-cap-disc { width: 100%; }

/* dropp-блок набора (оплата картой) — position:absolute hover-overlay, без flow-space. */
/* .scn-pk-dropp: позиционирование/раскрытие — в общем правиле поповера у цены
   (секция «dropp-расклад — origin-aware поповер»). Здесь больше ничего не нужно. */

/* Плавающая панель «Объединить» — липнет к низу тела дровера.
   flex-wrap обязателен: волна 2 добавила сюда третью кнопку («Снять со сцены»),
   и без переноса счётчик с кнопками выдавливали друг друга за край дровера —
   на узком экране это ровно та ситуация, из-за которой жмут не ту кнопку. */
.scn-pk-bar {
  position: sticky; bottom: 0; z-index: 5;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 14px -20px -20px; padding: 13px 20px;
  background: var(--card); border-top: 1px solid var(--line);
  box-shadow: 0 -8px 24px rgba(0,0,0,.12);
  animation: scnPkBarIn .18s var(--ease-out);
}
@keyframes scnPkBarIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.scn-pk-bar-count { font-size: 13px; font-weight: 600; color: var(--t1); }
.scn-pk-bar-actions { margin-left: auto; display: flex; gap: 8px; flex-wrap: wrap; }
.scn-pk-bar-reset {
  font-size: 13px; padding: 8px 13px; border-radius: 9px;
  background: var(--ctl); border: 1px solid var(--line); color: var(--t2);
  cursor: pointer; transition: background .12s, color .12s;
}
.scn-pk-bar-reset:hover { background: var(--ctl-h); color: var(--t1); }
.scn-pk-bar-go {
  font-size: 13px; font-weight: 600; padding: 8px 15px; border-radius: 9px;
  background: var(--g); border: 1px solid var(--g); color: #fff; cursor: pointer;
  transition: filter .12s, transform .1s;
}
.scn-pk-bar-go:hover { filter: brightness(1.08); }
.scn-pk-bar-go:active { transform: scale(.97); }
/* «Объединить» гаснет при <2 и >10 выбранных (пак = TG-альбом 2..10), а не
   прячется вместе со всей панелью — причина в title кнопки. */
.scn-pk-bar-go:disabled { opacity: .42; cursor: not-allowed; filter: none; transform: none; }
/* «Снять со сцены» — обратимое действие, поэтому НЕ красное. Но и не близнец
   «Сброса»: контрастнее текст и заметная рамка, чтобы две соседние кнопки в
   дровере не сливались в одну. */
.scn-pk-bar-off {
  font-size: 13px; font-weight: 600; padding: 8px 13px; border-radius: 9px;
  background: var(--ctl); border: 1px solid var(--line); color: var(--t1);
  cursor: pointer; transition: background .12s, border-color .12s;
}
.scn-pk-bar-off:hover { background: var(--ctl-h); border-color: var(--g); }
/* Групповое удаление — danger-вариант той же панели. Цвет от .bulk-bar__btn--danger
   (панель аккаунтов), чтобы «опасная» кнопка везде читалась одинаково. */
.scn-pk-bar-del {
  font-size: 13px; font-weight: 600; padding: 8px 13px; border-radius: 9px;
  background: transparent; border: 1px solid var(--line); color: var(--bad);
  cursor: pointer; transition: background .12s, border-color .12s;
}
.scn-pk-bar-del:hover {
  background: color-mix(in srgb, var(--bad) 14%, transparent);
  border-color: color-mix(in srgb, var(--bad) 45%, transparent);
}

/* ── Реф-кнопка регистрации на dropp.fans в онбординге привязки ── */
.set-dropp-reg {
  display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
  margin: 2px 0 0; padding: 9px 14px; border-radius: 9px;
  font-size: 13px; font-weight: 600; text-decoration: none;
  color: #fff; background: var(--g); border: 1px solid var(--g);
  transition: filter .15s, transform .1s;
}
/* dropp: пошаговое подключение (состояние «Не подключён») */
.set-step { margin: 0 0 14px; }
.set-step__head { display: flex; align-items: center; gap: 9px; margin: 0 0 9px; }
.set-step__num {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 12px; font-weight: 600; line-height: 1; color: #fff;
  background: var(--g);
}
.set-step__title { font-size: 13px; font-weight: 600; color: var(--t1); letter-spacing: -.01em; }
.set-step__desc { font-size: 12px; color: var(--t2); line-height: 1.5; margin: 0 0 12px; }
.set-step--get {
  border: 1px solid var(--line); border-radius: var(--r-ctl);
  background: var(--sheet); padding: 14px 16px;
}
.set-step .set-field { margin: 4px 0 0; }
.set-btn-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.set-dropp-reg:hover { filter: brightness(1.08); }
.set-dropp-reg:active { transform: scale(.98); }
.set-dropp-reg__arr { transition: transform .15s; }
.set-dropp-reg:hover .set-dropp-reg__arr { transform: translateX(3px); }
.set-card--flash { animation: setCardFlash 1.6s var(--ease-out); }
@keyframes setCardFlash {
  0%, 100% { box-shadow: 0 0 0 0 rgba(42,171,238,0); }
  14% { box-shadow: 0 0 0 3px rgba(42,171,238,.5); }
}

/* Dashboard sales row enrichments (Task 4) */
.dash-sale-model{margin-left:6px;font-size:11px;color:var(--text-3)}
.dash-sales-head{display:flex;align-items:center}
.dash-sales-list{max-height:340px;overflow-y:auto;margin:0 -4px;padding:0 4px}

/* ── Дашборд: график+воронка слева, последние поступления колонкой справа ── */
/* Правая карточка тянется ровно на высоту левой колонки (график+воронка) и
   снизу выравнивается с ней — аккуратный прямоугольник. Список скроллится
   ВНУТРИ: карточка позиционируется absolute, поэтому её высоту задаёт растянутая
   ячейка грида (= левая колонка), а длинный список не раздувает ряд. */
.dash-main{display:grid;grid-template-columns:minmax(0,1fr) clamp(300px,30%,380px);grid-template-rows:minmax(0,1fr);gap:16px}
.dash-main-left{min-width:0;display:flex;flex-direction:column;min-height:0}
.dash-main-right{min-width:0;display:flex;flex-direction:column;min-height:0}
/* В левой колонке KPI-строка из 3 карточек (Доход уехал в правую колонку) */
.dash-kpis-3{grid-template-columns:repeat(3,1fr)}
/* Правая колонка: Доход-герой сверху (фикс), карточка поступлений тянет остаток */
.dash-main-right>.dash-card-hero{flex:none}
.dash-main-right>#dash-sales{flex:1;min-height:0;display:flex;flex-direction:column}
.dash-main-right>#dash-sales>.dash-card{flex:1;display:flex;flex-direction:column;min-height:0}
.dash-main-right .dash-sales-list{flex:1;max-height:none;min-height:0}

/* Весь дашборд — в один экран без вертикального скролла: страница занимает
   высоту .main, под фильтрами и KPI остаток забирает .dash-main, а внутри
   левой колонки график тянется/сжимается, воронка остаётся фикс. */
/* Дашборд .ndash — обычный поток, скроллится в .main. Бывшие flex-fill правила
   (график тянулся на весь экран) удалены: они ломали новый лейаут и блокировали скролл. */
/* Канвас дашборда наследуется от [data-theme="dark"] .main (единый источник) —
   локальный фон убран, чтобы не дублировать радиалы. */
#page-dashboard{display:block}

/* ═══════════ Нейрочат (Диалоги) в языке концепта «Neon Ledger» ═══════════
   Палитра и канвас теперь глобальные ([data-theme="dark"]); локальный токен-блок
   и фон убраны как дубли. Остаётся только специфика страницы: системный шрифт
   и пузыри в языке концепта. Структуру/JS не трогаем. */
#page-dialogs {
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Display","Segoe UI",Roboto,sans-serif;
}
/* hover строки чата — светлее панели (zones ставит --sheet=чёрный → было бы темнее) */
#page-dialogs .dlg-ch:hover{background:var(--raise-2)!important}
/* пузыри в языке концепта: them=raise-2, me=rgba-blue, radius 16 + msgin.
   Воздух как в концепте: шрифт 14/1.45, паддинг 11/15, ширина 62%, интервал 14. */
#page-dialogs .dlg-msg{font-size:14px;line-height:1.45;border-radius:16px}
/* Появление анимируем ТОЛЬКО у новых пузырей (класс вешает diff-рендер), а не у
   всех подряд. Раньше animation висела на .dlg-msg — и любое событие (даже
   галочка «прочитано») перерисовывало тело, заставляя все 50 пузырей заново
   проигрывать 380мс с blur. Теперь: пришло одно сообщение — оживает один пузырь,
   история при открытии чата просто есть, без фейерверка.
   Пружина сдержанная (--ease-spring): оператор видит это сотни раз в день. */
#page-dialogs .dlg-msg--new{animation:dlg-msg-in var(--dur-4) var(--ease-spring) backwards}
/* Амплитуда сдержанная: сильный сдвиг+сжатие читались как рывок, особенно на
   своих же сообщениях, которые оператор видит сотни раз за смену. Пружина
   осталась, «прыжок» ушёл. */
@keyframes dlg-msg-in{
  from{opacity:0;transform:translateY(9px) scale(.97)}
  55%{opacity:1}
  to{opacity:1;transform:none}
}
/* Статус отправки живёт в боксе ФИКСИРОВАННОЙ ширины.
   Спиннер, одинарная галочка и двойная галочка — разной ширины, и при их
   подмене строка времени меняла длину, дёргая весь пузырь. Теперь место под
   статус зарезервировано, а иконки просто перетекают друг в друга. */
#page-dialogs .dlg-msg .dlg-tick{
  display:inline-flex;position:relative;
  width:16px;height:10px;margin-left:3px;vertical-align:-1px;
}
#page-dialogs .dlg-msg .dlg-tick-svg{
  position:absolute;right:0;top:0;
  transition:opacity var(--dur-2) var(--ease-out);
}
/* Отправляется: вместо галочки крутится точка. Класс вешается ТОЛЬКО если
   отправка затянулась (см. dlgSend) — на быстрой сети спиннер мелькнул бы на
   долю секунды и читался бы как дёрганье, а не как статус. */
#page-dialogs .dlg-msg--pending .dlg-tick-svg{opacity:0}
#page-dialogs .dlg-msg--pending .dlg-tick::before{
  content:'';position:absolute;right:2px;top:0;
  width:9px;height:9px;
  border:1.5px solid currentColor;border-top-color:transparent;border-radius:50%;
  animation:dlg-tick-spin .7s linear infinite;
}
/* Время приглушаем, а не весь пузырь: раньше он мигал яркостью целиком. */
#page-dialogs .dlg-msg--pending .mt{opacity:.65}
@keyframes dlg-tick-spin{to{transform:rotate(360deg)}}
/* Доставлено: галочка мягко проявляется, без прыжка. */
#page-dialogs .dlg-msg--sent .dlg-tick-svg{animation:dlg-tick-in var(--dur-3) var(--ease-out) backwards}
@keyframes dlg-tick-in{from{opacity:0}to{opacity:1}}
/* Уходит: выход ВСЕГДА быстрее входа (--dur-3 против --dur-4) — система должна
   реагировать мгновенно, даже если появление вальяжное. */
#page-dialogs .dlg-msg--gone{
  animation:dlg-msg-out var(--dur-3) var(--ease-out) forwards;
  pointer-events:none;
}
@keyframes dlg-msg-out{
  to{opacity:0;transform:translateY(-4px) scale(.96);max-height:0;margin-top:-14px}
}
/* Перевод перетекает, а не подменяется рывком. */
#page-dialogs .dlg-msg-text{transition:opacity var(--dur-3) ease, filter var(--dur-3) ease}
#page-dialogs .dlg-msg-text.dlg-tx-out{opacity:0;filter:blur(3px)}
#page-dialogs .dlg-msg:not(.dlg-msg--media){padding:11px 15px;max-width:62%}
/* Telegram-стиль (по просьбе): исходящие — сплошной синий + белый текст,
   входящие — плотный серый. Отход от «тихого» концепта — так захотел юзер. */
#page-dialogs .dlg-msg.in{background:#26262c;color:var(--text);border:none;border-bottom-left-radius:5px}
#page-dialogs .dlg-msg.out{background:#2aabee;color:#fff;border:none;border-bottom-right-radius:5px}
#page-dialogs .dlg-msg.out .mt{color:rgba(255,255,255,.75)}
#page-dialogs .dlg-msg.out .dlg-tick,#page-dialogs .dlg-msg.out .dlg-tick--read{color:rgba(255,255,255,.9)}
#page-dialogs .dlg-body{padding:24px 22px;gap:14px}
/* медиа БЕЗ подписи — оставить прозрачным (иначе синий фон/рамка налезут на фото) */
#page-dialogs .dlg-msg--media:not(.dlg-msg--cap){background:transparent!important;border:none!important}
/* ndash-msgin УДАЛЁН: висел на .dlg-msg (= на всех пузырях сразу) и жёг blur на
   каждом ререндере тела. Заменён на dlg-msg-in, который играет только у новых. */
@media (prefers-reduced-motion:reduce){#page-dialogs .dlg-msg--new,#page-dialogs .dlg-msg--gone{animation:none}}

/* ===== «Собеседник печатает» =====
   Живёт в самом низу треда, как отдельный пузырь со стороны собеседника.
   Появляется той же пружиной, что и обычное входящее — он и есть предвестник
   сообщения. Гаснет по таймеру (Telegram отмену печати шлёт не всегда). */
#page-dialogs .dlg-typing{
  align-self:flex-start;
  display:flex;align-items:center;gap:5px;
  padding:11px 13px;border-radius:16px;border-bottom-left-radius:5px;
  background:#26262c;
  animation:dlg-msg-in var(--dur-4) var(--ease-spring) backwards;
}
#page-dialogs .dlg-typing i{
  width:6px;height:6px;border-radius:50%;background:#8b8f99;display:block;
  animation:dlg-typing-dot 1.2s infinite ease-in-out;
}
#page-dialogs .dlg-typing i:nth-child(2){animation-delay:.16s}
#page-dialogs .dlg-typing i:nth-child(3){animation-delay:.32s}
@keyframes dlg-typing-dot{
  0%,60%,100%{transform:translateY(0);opacity:.45}
  30%{transform:translateY(-4px);opacity:1}
}
#page-dialogs .dlg-typing-tx{
  margin-left:4px;font-size:12px;color:var(--t2);letter-spacing:-.01em;
}
/* Только «печатает» — подпись избыточна, точки говорят сами. Голос/файл важнее. */
#page-dialogs .dlg-typing-tx:empty{display:none}
@media (prefers-reduced-motion:reduce){
  #page-dialogs .dlg-typing{animation:none}
  #page-dialogs .dlg-typing i{animation:none;opacity:.7}
}

/* Скелетон → сообщения: тело проявляется целиком, а не подменяется рывком. */
#page-dialogs .dlg-body--in{animation:dlg-body-in var(--dur-3) var(--ease-out)}
@keyframes dlg-body-in{from{opacity:0}to{opacity:1}}
@media (prefers-reduced-motion:reduce){#page-dialogs .dlg-body--in{animation:none}}

/* ===== Кнопка «вниз» + счётчик непрочитанных =====
   Если оператор отлистал историю вверх, входящие раньше уходили в пустоту:
   он их просто не видел. Теперь — якорь возврата с числом новых. */
#page-dialogs .dlg-jump{
  position:absolute;right:22px;bottom:92px;z-index:5;
  width:42px;height:42px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  background:var(--raise-2);color:var(--t1);border:1px solid var(--line);
  box-shadow:var(--shadow-pop);cursor:pointer;
  transition:transform var(--dur-2) var(--ease-out), opacity var(--dur-2) var(--ease-out);
  opacity:0;transform:translateY(8px) scale(.9);pointer-events:none;
}
#page-dialogs .dlg-jump.on{opacity:1;transform:none;pointer-events:auto}
#page-dialogs .dlg-jump:hover{background:var(--ctl-h)}
#page-dialogs .dlg-jump:active{transform:scale(.94)}
/* Счётчик — «клюёт» пружиной при каждом новом сообщении, чтобы его заметили. */
#page-dialogs .dlg-jump-n{
  position:absolute;top:-5px;right:-4px;min-width:19px;height:19px;padding:0 5px;
  border-radius:10px;background:#2AABEE;color:#04121a;
  font:700 11px/19px var(--ff-num);text-align:center;
  animation:dlg-jump-pop var(--dur-2) var(--ease-spring);
}
#page-dialogs .dlg-jump-n:empty{display:none}
@keyframes dlg-jump-pop{from{transform:scale(.5)}to{transform:none}}
@media (prefers-reduced-motion:reduce){#page-dialogs .dlg-jump-n{animation:none}}

@media (max-width:900px){
  .dash-main{grid-template-columns:1fr;grid-template-rows:none}
  .dash-main-left,.dash-main-right{display:block}
  .dash-kpis-3{grid-template-columns:repeat(2,1fr)}
  .dash-main-right>#dash-sales{display:block}
  .dash-main-right>#dash-sales>.dash-card{flex:none}
  .dash-main-right .dash-sales-list{flex:none;max-height:340px}
  /* На мобиле возвращаем естественный поток со скроллом */
  #page-dashboard{height:auto;display:block;overflow:visible}
  #page-dashboard #dash-root{display:block}
  #page-dashboard .dash-main-left{display:block}
  #page-dashboard #dash-chart{display:block}
  #page-dashboard #dash-chart .dash-svg{height:200px;min-height:0}
}

/* ── Энергия: шкала в шапке + поповер пополнения ───────────────────────── */
.hdr-energy{display:flex;align-items:center;gap:6px;cursor:pointer;padding:4px 8px;border-radius:10px;background:var(--bg-card);border:1px solid var(--border);user-select:none}
.hdr-energy-num{font-size:12px;color:var(--text-2);white-space:nowrap}
.hdr-energy--zero .hdr-energy-num{color:#f87171}
.hdr-energy--off{opacity:.45}
.energy-popover{position:absolute;top:56px;right:16px;z-index:50;min-width:300px;max-height:60vh;overflow-y:auto;background:var(--bg-card);border:1px solid var(--border);border-radius:12px;padding:10px;box-shadow:0 8px 28px rgba(0,0,0,.4)}
.energy-pop-head{font-size:12px;font-weight:600;color:var(--text-2);margin-bottom:8px}
.energy-pop-row{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:13px}
/* Цена пачки энергии в админ-вкладке «Пользователи» */
/* Вкладка «Монетизация» — родной язык настроек (.set-card) + голубой контрол-акцент платформы (--g) */
.econ-wrap{max-width:960px;margin:0 auto;padding:2px 2px 12px}
.econ-section + .econ-section{margin-top:28px}
.econ-grouplbl{display:flex;align-items:center;gap:9px;margin:0 0 13px 2px;font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--t3)}
.econ-grouplbl::before{content:"";width:4px;height:13px;border-radius:2px;background:var(--g)}
.econ-grid{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:stretch}
@media(max-width:760px){.econ-grid{grid-template-columns:1fr}}
.econ-card{display:flex;flex-direction:column;animation:econIn .34s var(--ease-out) both;transition:border-color .18s var(--ease-out)}
.econ-card:hover{border-color:color-mix(in srgb,var(--g) 26%,var(--line))}
.econ-grid .econ-card:nth-child(2){animation-delay:.06s}
.econ-head{display:flex;align-items:center;gap:12px;margin-bottom:11px}
.econ-ic{width:32px;height:32px;flex:none;display:grid;place-items:center;border-radius:9px;color:var(--g);
  background:var(--sheet);border:1px solid var(--line)}
.econ-ic svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.econ-head .set-card__title{margin:0}
.econ-card .set-card__sub{margin:0 0 2px;flex:1 1 auto}
.econ-stat{display:inline-flex;align-items:center;gap:7px;align-self:flex-start;margin-top:15px;padding:8px 12px;border-radius:10px;background:var(--sheet);border:1px solid var(--line);font-size:12px;color:var(--t2);font-variant-numeric:tabular-nums}
.econ-stat b{color:var(--t1);font-weight:600}
.econ-foot{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:18px}
.econ-card .btn{transition:transform .14s var(--ease-out),filter .18s var(--ease-out),box-shadow .2s var(--ease-out)}
.econ-card .btn:active{transform:scale(.97)}
/* числовой/денежный ввод — единый pill с фокус-рингом платформы, без нативных спиннеров */
.econ-field{display:inline-flex;align-items:center;gap:7px;height:40px;padding:0 13px;background:var(--sheet);
  border:1px solid var(--line);border-radius:var(--r-ctl);transition:border-color .16s var(--ease-out),box-shadow .16s var(--ease-out)}
.econ-field:focus-within{border-color:var(--g);box-shadow:0 0 0 2px rgba(42,171,238,.35)}
.econ-unit{color:var(--t3);font-size:14px;font-weight:500;line-height:1}
.econ-input{border:none;background:none;outline:none;color:var(--t1);font-size:14px;width:66px;padding:0;font-variant-numeric:tabular-nums;-moz-appearance:textfield}
.econ-input::-webkit-inner-spin-button,.econ-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
.paid-invite-toggle{display:inline-flex;align-items:center;gap:7px;white-space:nowrap;font-size:13px;color:var(--t2);cursor:pointer}
.paid-invite-toggle input{accent-color:var(--g);width:15px;height:15px;cursor:pointer}
@keyframes econIn{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:translateY(0)}}
@media(prefers-reduced-motion:reduce){.econ-card{animation:none}}
/* Покупка энергии (поповер) + редактор скидочной лесенки (NOWPayments) */
/* Ползунок объёма: тащишь больше ⚡ → выше скидка (плавно) */
.energy-buy{padding:6px 4px 2px}
.energy-buy-amount{font-size:24px;font-weight:700;color:var(--text);text-align:center;font-variant-numeric:tabular-nums;letter-spacing:.3px}
.energy-buy-price{display:flex;align-items:center;justify-content:center;gap:8px;margin:4px 0 16px;font-size:15px;color:var(--text-2);font-variant-numeric:tabular-nums}
.energy-buy-disc{opacity:0;transform:scale(.8);transition:opacity .15s ease,transform .15s ease;font-weight:700;color:#34d399;background:rgba(52,211,153,.12);border:1px solid rgba(52,211,153,.32);border-radius:999px;padding:1px 9px;font-size:13px}
.energy-buy-disc.on{opacity:1;transform:scale(1)}
.energy-slider-wrap{position:relative;padding:0 2px}
.energy-slider-ticks{position:relative;height:14px;margin-top:7px}
.energy-slider-tick{position:absolute;transform:translateX(-50%);font-size:10px;color:var(--text-3);white-space:nowrap;font-variant-numeric:tabular-nums}
.energy-slider-ends{display:flex;justify-content:space-between;font-size:11px;color:var(--text-3);margin-top:1px;font-variant-numeric:tabular-nums}
.energy-buy-actions{justify-content:space-between;margin-top:6px}
/* Промокод в поповере: вход второстепенной кнопкой той же ширины, что оплата,
   и отдельный режим ввода — покупка и код вместе не показываются. */
.energy-buy-actions .btn{width:100%}
.energy-promo-btn{width:100%;margin-top:8px}
.energy-pop-back{cursor:pointer;color:var(--text-3);margin-right:5px}
.energy-code{padding:14px 4px 6px;display:flex;flex-direction:column;gap:10px}
.energy-code-input{height:46px;text-align:center;font-family:monospace;font-size:17px;letter-spacing:.16em;text-transform:uppercase}
.energy-code-msg{font-size:12px;text-align:center;color:var(--bad)}
.energy-code-msg:empty{display:none}
.energy-tiers-list{display:flex;flex-direction:column;gap:8px;margin:12px 0 2px}
.energy-tier-row{display:flex;align-items:center;gap:9px;font-size:13px;color:var(--t2)}
.energy-tier-row .form-input{padding:8px 10px;height:36px;background:var(--sheet);border:1px solid var(--line);border-radius:10px;color:var(--t1);font-variant-numeric:tabular-nums;-moz-appearance:textfield;transition:border-color .16s var(--ease-out),box-shadow .16s var(--ease-out)}
.energy-tier-row .form-input:focus{outline:none;border-color:var(--g);box-shadow:0 0 0 2px rgba(42,171,238,.35)}
.energy-tier-row .form-input::-webkit-inner-spin-button,.energy-tier-row .form-input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
.energy-tier-row .btn-ghost{width:32px;height:32px;padding:0;flex:none;justify-content:center;color:var(--t3);font-size:15px;border-radius:9px;transition:color .16s var(--ease-out),background .16s var(--ease-out)}
.energy-tier-row .btn-ghost:hover{color:#d4504e;background:color-mix(in srgb,#d4504e 12%,transparent)}
/* Ячейка «залить энергию» в строке таблицы «Пользователи» */
.en-cell{display:inline-flex;align-items:center;gap:9px}
.en-cell-ic{color:#f59e0b;font-size:15px;line-height:1}
.en-cell-input{width:88px;background:var(--bg-input);border:1px solid var(--border);border-radius:var(--r-ctl);padding:8px 11px;color:var(--text);font-size:13px;font-variant-numeric:tabular-nums;outline:none;transition:border-color .15s}
.en-cell-input:focus{border-color:var(--auth-accent-soft,rgba(124,92,255,.45))}
.en-cell-input::-webkit-outer-spin-button,.en-cell-input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.en-cell-input[type=number]{-moz-appearance:textfield;appearance:textfield}
.en-cell-btn:active{transform:scale(.97)}

/* Маркер ручного режима в бейдже статуса: «вручную» как вторичная метаданность
   (дивайдер + приглушение), а не дописанный к статусу текст. */
.status-pill__mode {
  margin-left: 7px; padding-left: 7px;
  border-left: 1px solid currentColor; opacity: .62; font-weight: 500;
}

/* ── Поповер режима сна аккаунта ────────────────────────────────────────── */
.acct-sleep-pop {
  position: absolute; z-index: 1000; min-width: 236px;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--r-ctl); padding: 5px; box-shadow: var(--shadow-pop);
  transform-origin: top left;             /* масштабируется от триггера, не от центра */
  animation: acctSleepPopIn 160ms var(--ease-out);
}
@keyframes acctSleepPopIn { from { opacity: 0; transform: scale(.96) translateY(-4px); } }
.acct-sleep-item {
  display: flex; align-items: center; gap: 11px; width: 100%;
  padding: 9px 11px; background: none; border: 0; border-radius: 9px;
  color: var(--t1); text-align: left; cursor: pointer; font: inherit;
  transition: background 120ms ease, transform 120ms var(--ease-out);
}
.acct-sleep-item:hover,
.acct-sleep-item.is-cur { background: var(--ctl); }
.acct-sleep-item:active { transform: scale(.985); }   /* отклик на нажатие */
.acct-sleep-ic { font-size: 15px; line-height: 1; flex: none; }
.acct-sleep-lbl { font-weight: 600; font-size: 13px; }
.acct-sleep-check { margin-left: auto; color: var(--g); font-weight: 700; }

/* ── Нотис «аккаунты на ручном форсе» в редакторе «Сон» ───────────────────── */
.cf-sleep-warn {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 14px; padding: 11px 14px;
  background: color-mix(in srgb, var(--warn) 12%, var(--card));
  border: 1px solid color-mix(in srgb, var(--warn) 36%, transparent);
  border-radius: var(--r-ctl); color: var(--t1); font-size: 13px; line-height: 1.4;
  animation: cfSleepWarnIn 200ms var(--ease-out);   /* появляется после async-fetch — мягкий вход вместо рывка */
}
@keyframes cfSleepWarnIn { from { opacity: 0; transform: translateY(4px); } }
.cf-sleep-warn__btn {
  margin-left: auto; flex: none; padding: 7px 13px; border-radius: 9px; cursor: pointer;
  background: var(--g); color: #fff; border: 0; font: inherit; font-weight: 600; font-size: 12.5px;
  transition: filter 140ms ease, transform 120ms var(--ease-out);
}
.cf-sleep-warn__btn:hover { filter: brightness(1.06); }
.cf-sleep-warn__btn:active { transform: scale(.97); }

/* «IQ бота» — компактный чип заполненности профиля в шапке редактора */
.char-iq {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 14px;
  padding: 7px 12px;
  border-radius: 999px;
  background: var(--ctl);
  border: 1px solid var(--line);
  font-family: var(--ff-num);
  font-size: 13px;
  line-height: 1;
  white-space: nowrap;
  user-select: none;
  cursor: default;
}
.char-iq-emoji { font-size: 15px; line-height: 1; }
.char-iq-label {
  color: var(--t2);
  font-weight: 600;
  letter-spacing: .3px;
}
.char-iq-value {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  min-width: 2.4ch;
  text-align: right;
  transition: color .25s var(--ease-out-soft);
}
.char-iq-bar {
  flex: 1;
  min-width: 36px;
  margin-left: 3px;
  height: 4px;
  border-radius: 999px;
  background: var(--bar);
  overflow: hidden;
}
.char-iq-fill {
  display: block;
  height: 100%;
  width: 100%;
  border-radius: 999px;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .35s var(--ease-out), background .25s var(--ease-out-soft);
}

/* ── Подсказки по продажам — блок внизу окна сцены ── */
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; color: var(--text-3); padding: 10px 2px;
}
  display: flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 700; color: var(--text); margin-bottom: 8px;
}
  background: none; border: none; color: #8fd2f7; font-weight: 600;
  font-size: 12.5px; cursor: pointer; padding: 0; white-space: nowrap; font-family: inherit;
}
.scn-lad-row--flash { animation: scn-lad-flash 1.4s var(--ease-out); }
@keyframes scn-lad-flash {
  0%, 100% { box-shadow: none; }
  15% { box-shadow: 0 0 0 2px var(--g); }
}

/* ── dropp: поле цены карты + расклад + статус-строка (Task 11) ── */
.scn-price {
  display: inline-flex; align-items: center; gap: 4px;
  position: relative;            /* якорь для dropp-поповера */
  background: var(--bg-input); border: 1px solid var(--line);
  border-radius: 9px; padding: 0 9px 0 10px; flex: none;
  transition: border-color .14s var(--ease-out);
}
.scn-price:focus-within { border-color: var(--g); }
.scn-price-tag { opacity: .6; font-weight: 600; font-size: 12px; color: var(--t2); }
/* input живёт внутри пилюли цены — свой бордюр/фон убираем */
.scn-price-inp, .scn-lad-price, .scn-pk-price {
  width: 62px; background: transparent; border: 0; outline: none;
  padding: 6px 0; font-size: 13px; color: var(--t1); text-align: right;
}
/* dropp-поповер: компактная карточка «ты получишь», 2 строки */
.scn-price-breakdown { font-size: 11.5px; color: var(--t2); line-height: 1.5; }
.scn-pb-head {
  font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--t3); margin-bottom: 5px;
}
.scn-pb-row { display: flex; justify-content: space-between; gap: 14px; white-space: nowrap; }
.scn-pb-row + .scn-pb-row { margin-top: 2px; }
.scn-pb-row b { color: var(--t1); font-weight: 700; }
/* Недоступный канал: гасим САМУ СУММУ, но не строку целиком и без перечёркивания.
   Зачёркнутая строка выглядела дёшево и была избыточной — смысл уже несёт слово
   «не отправится» справа, а его как раз надо оставить читаемым. */
.scn-pb-row-off > span:first-child { opacity: .5; }
/* Два уровня, не один: .scn-pb-warn — цену НЕ СОХРАНИМ (отправить нечем), красный;
   .scn-pb-note — цена законная, теряется только звёздный канал, янтарный.
   Раньше обе ситуации красились одинаково янтарным, и «не сохранится» читалось
   так же мягко, как «продастся картой». */
.scn-pb-warn {
  margin-top: 5px; padding: 5px 8px; border-radius: 6px;
  background: rgba(224,83,59,.12); border: 1px solid rgba(224,83,59,.34);
  color: #f0917f; font-size: 11px; line-height: 1.4; white-space: normal;
}
.scn-pb-note {
  margin-top: 5px; padding: 5px 8px; border-radius: 6px;
  background: rgba(240,173,78,.12); border: 1px solid rgba(240,173,78,.32);
  color: #f0ad4e; font-size: 11px; line-height: 1.4; white-space: normal;
}
/* «не отправится» вместо суммы: это НЕ доход, поэтому и не выглядит как доход —
   без жирного акцента, приглушённым цветом подписи. */
.scn-pb-row b.scn-pb-dead { color: var(--t3); font-weight: 500; }
/* Расклад и чип «подключить» теперь живут в одном поповере друг под другом
   (раньше чип стоял ВМЕСТО расклада). */
.scn-price-breakdown + .scn-dropp-chip { margin-top: 7px; display: inline-flex; }
.scn-dropp-chip {
  border: 1px dashed var(--line); background: transparent; color: var(--g);
  font-size: 11px; padding: 5px 8px; border-radius: 8px; cursor: pointer;
  white-space: normal; line-height: 1.35; text-align: left;
}
.scn-dropp-chip:hover { background: rgba(42,171,238,.1); border-color: var(--g); }
.scn-dropp-status-line { font-size: 11px; margin-top: 2px; color: var(--t3); }
/* Standalone color modifiers (применяются к .scn-dropp-tag и тексту статуса) */
.scn-dropp-live { color: #3fb950; }
.scn-dropp-todo { color: var(--t2); }   /* «заливается…» — процесс, не призыв нажать */

/* Селект под общий вид инпута + единый кастомный шеврон: нативный контрол ОС
   (двойные стрелки) выглядел чужеродно среди стилизованных полей. */
.set-field select, .set-select {
  padding: 9px 34px 9px 12px; border: 1px solid var(--line); border-radius: var(--r-ctl);
  background: var(--card); color: var(--t1); font-size: 14px; font-family: inherit;
  appearance: none; -webkit-appearance: none; -moz-appearance: none; cursor: pointer; width: 100%;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa3b2' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
  transition: border-color .15s, box-shadow .15s;
}
.set-field select:hover, .set-select:hover { border-color: var(--t2); }
.set-field select:focus, .set-select:focus { outline: none; border-color: var(--g2, #229ED9); box-shadow: 0 0 0 3px rgba(34,158,217,.18); }


/* ── notify-prefs: тумблеры уведомлений в кабинете ── */
.notify-pref-row { display:flex; align-items:center; gap:8px; padding:4px 0; cursor:pointer; }
.notify-pref-row input { width:16px; height:16px; accent-color: var(--accent-2); }
/* Лендинг вынесен в landing.css (ленд v2, 07.09.2026) */


/* ============================================================
   OLED depth: char editor (CSS-only re-skin, live markup untouched)
   ============================================================ */
/* нейтрализуем внешнюю карту — глубину дают две панели кита (рейл + контент) на чёрном */
#page-characters .char-editor{ background:transparent; border:0; border-radius:0; padding:0 0 88px; }

/* сайдбар-рейл как панель кита */
#page-characters .editchar-side{
  background:var(--raise-1); border:1px solid var(--line);
  border-radius:16px; padding:10px 8px;
}
#page-characters .editchar-sgh{
  font-size:10px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--text-3); padding:12px 10px 5px;
}
#page-characters .editchar-tab{
  padding:8px 11px; border-radius:9px; border-left:2px solid transparent;
  color:var(--text-2); font-size:13px; font-weight:500;
}
#page-characters .editchar-tab:hover{ background:var(--raise-2); color:var(--text); }
#page-characters .editchar-tab.active{
  background:var(--accent-soft); color:var(--accent);
  border-left-color:var(--accent); font-weight:600;
}
#page-characters .editchar-tab.active .et-ic{ opacity:1; }

/* контент-пейн как панель кита */
#page-characters .editchar-content{ min-width:0; }
/* ПАНЕЛЬЮ СТАЛА КАРТОЧКА, А НЕ ВКЛАДКА (пересборка редактора 09.08.2026).
   Раньше панель рисовалась здесь, у пейна целиком, а секции внутри были голыми
   .section-title в сплошной колонке; .set-card поверх такого пейна красился в тот
   же самый цвет (var(--card) === var(--raise-1) === #131316) и читался только по
   волосяной рамке — отсюда «всё слиплось в кучу». Панель снята со вкладки и отдана
   карточкам ТЕМИ ЖЕ значениями, что были у пейна, а вкладка стала flex-колонкой с
   зазором 18px — тем же, что у .editchar-layout между рейлом и контентом. */
#page-characters .editchar-pane:not(.hidden){
  background:transparent; border:0; border-radius:0; padding:0;
  display:flex; flex-direction:column; gap:18px;
}
.editchar-content .ec-card,
.editchar-content .set-details{
  background:var(--raise-1); border:1px solid var(--line);
  border-radius:16px; margin:0;
}
.editchar-content .ec-card{ padding:22px 24px; }
/* Первое/последнее поле карточки: у .set-card__sub уже есть margin-bottom:16px,
   а .field-group несёт свой margin-bottom:14px — гасим двойной воздух по краям. */
.editchar-content .ec-card > .field-group:first-child,
.editchar-content .ec-card > .field-row:first-child{ margin-top:0; }
.editchar-content .ec-card > .field-group:last-child{ margin-bottom:0; }
/* Вложенный блок той же темы (live-карточка подключения провайдера внутри
   «Оплаты картой») — без собственной рамки, чтобы не читаться второй панелью. */
.ec-sub{ margin-top:14px; }
/* Свёрнутая секция редактора («Примеры и манера», «Отладка»). В «Настройках»
   .set-details — узкая полоска под текст-инструкцию; здесь внутрь кладутся ПОЛЯ,
   поэтому нужен нормальный внутренний отступ и обычный цвет текста. Фон/рамку/
   радиус даёт правило выше: свёрнутая секция — такая же панель, как карточка. */
.editchar-content .set-details__body{ padding:4px 24px 20px; color:var(--t1); font-size:inherit; }
.editchar-content .set-details > summary{ padding:20px 24px; font-weight:600; font-family:var(--ff-head); font-size:17px; letter-spacing:-.014em; }
.editchar-content .set-details .fold-note{ font-size:12px; color:var(--t2); font-weight:400; margin-left:8px; font-family:var(--ff-body); letter-spacing:0; }
/* Рейл: 9 пунктов вместо 12 — группа «Режим работы» схлопнулась в один пункт,
   и у последней группы больше нет собственного нижнего воздуха. */
.editchar-side > .editchar-tab:last-child{ margin-bottom:2px; }
/* Клиренс под плавающей панелью действий (#char-actionbar, position:fixed).
   На мобиле он уже есть (см. блок @media max-width:720px ниже), на десктопе —
   нет, и панель висит поверх содержимого последней карточки. */
.editchar-content{ padding-bottom:92px; }
/* Шапка свёрнутой секции: заголовок и пояснение в одну строку на телефоне не влезают,
   заголовок рвётся посередине. Разрешаем перенос. Блок стоит СРАЗУ ПОСЛЕ правил
   .fold-note выше — при равной специфичности выигрывает порядок, вынести его в
   общий адаптив-раздел (он раньше по файлу) значит потерять margin-left:0. */
@media (max-width:560px){
  .editchar-content .set-details > summary{ flex-wrap:wrap; }
  .editchar-content .set-details .fold-note{ margin-left:0; flex-basis:100%; }
}

#page-characters .field-label{ color:var(--text-3); }
#page-characters .field-hint{ color:var(--text-3); }

/* инпуты под .ninput (char/settings; в #page-admin выигрывает свой #page-admin .form-input=mint — намеренно не трогаем) */
.ndash .form-input{
  background:var(--black); border:1px solid var(--line); border-radius:10px;
  color:var(--text); transition:border-color .15s;
}
.ndash .form-input:focus{ border-color:var(--accent-dim); outline:none; }
.ndash .form-input::placeholder{ color:var(--text-3); }

/* репитер реквизитов + чекбоксы */
#page-characters .pm-del{ background:var(--raise-2); border:1px solid var(--line); color:var(--text-3); border-radius:8px; }
#page-characters .pm-del:hover{ color:var(--crit); border-color:var(--crit); }
#page-characters .pm-add{ background:var(--raise-2); border:1px solid var(--line); color:var(--text-2); border-radius:9px; }
#page-characters .pm-add:hover{ color:var(--accent); border-color:var(--accent-dim); }
#page-characters .checkbox-row input[type="checkbox"]{ accent-color:var(--accent); }

/* экшен-бар редактора персонажа (монтируется в <body>, вне .ndash → литералы канона) */
.char-actionbar{
  background:#131316; border:1px solid #1c1c20; border-radius:14px;
  box-shadow:0 8px 32px rgba(0,0,0,.5);
}
.char-actionbar .bulk-bar__btn{ background:#1a1a1e; border:1px solid #232327; color:#a8a8ad; border-radius:10px; }
.char-actionbar .bulk-bar__btn--primary{ background:#2aabee; border-color:#2aabee; color:#04121b; font-weight:700; }
/* Наведение поднимает поверхность и рамку, текст остаётся серым. Раньше здесь
   менялся ровно один цвет — подпись из серой в белую (#f5f5f5), — и кнопка не
   подсвечивалась, а моргала текстом. Иконку держим в тон подписи по той же причине
   (общее правило .bulk-bar__btn:hover .bic белит её). Гейт по мыши: на тач-экране
   :hover залипает до касания в другом месте. */
@media (hover:hover) and (pointer:fine){
  .char-actionbar .bulk-bar__btn:hover{ background:#212126; border-color:#2f2f36; }
  .char-actionbar .bulk-bar__btn:hover .bic{ color:#a8a8ad; }
  .char-actionbar .bulk-bar__btn--primary:hover{ filter:brightness(1.06); box-shadow:0 0 22px rgba(42,171,238,.20); }
  .char-actionbar .bulk-bar__btn--danger:hover{ color:#e06b6b; border-color:#e06b6b; background:#1a1a1e; }
  .char-actionbar .bulk-bar__btn--danger:hover .bic{ color:#e06b6b; }
}

/* ═══════════ АДАПТИВ ПЛОТНЫХ ВЬЮХ (телефон) ═══════════════════════════
   Плотные редакторы/таблицы на узком экране. #page-characters-scoped правила
   стоят ПОСЛЕ OLED-рескина (7275+): равная специфичность, поздний порядок →
   перебивают старую h-scroll-ленту редактора. Верифицировано CDP на stage. */

/* КРИТ: клиренс под таб-баром. padding-bottom из 4529 сбрасывался padding-
   shorthand'ами адаптива (4835/4847 `.main-content{padding:14px 12px}` → bottom
   схлопывался в 14px, последний контент уходил под бар). Пере-ассертим longhand
   ПОСЛЕ всех shorthand'ов — иначе «Последние поступления» и низ пейнов режутся. */
@media (max-width:860px){
  .main-content{ padding-bottom:calc(60px + var(--safe-b) + 16px); }
}

/* КРИТ: iOS зумит вьюпорт при фокусе на поле с font-size < 16px. Официальный фикс
   Apple — 16px на полях (не user-scalable=no, чтобы не убивать pinch-zoom картинок).
   !important — перебивает классовые размеры полей (.ninput 13px и т.п.). */
@media (max-width:768px){
  input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=color]),
  textarea, select{ font-size:16px !important; }
}

/* — Навигация редактора на телефоне: вместо горизонтальной ленты/чипов —
     нативный <select> (выпадающий список разделов, выбор юзера). Чипы+заголовки
     групп скрыты, рейл-панель схлопнута в прозрачный контейнер (IQ + селект). */
@media (max-width:720px){
  #page-characters .editchar-side{
    position:static; display:block; overflow:visible; max-height:none;
    padding:0; margin-bottom:14px; background:none; border:0;
  }
  #page-characters .char-iq{ margin:0 0 8px; }
  #page-characters .editchar-side .editchar-tab,
  #page-characters .editchar-side .editchar-sgh{ display:none; }
  #page-characters .editchar-navsel{ display:block; }
  /* клиренс под плавающим #char-actionbar, иначе он закрывает низ пейна (issue 6) */
  #page-characters .editchar-content{ padding-bottom:82px; }
}

/* Нативный селект-навигация редактора: десктоп — скрыт (видны чипы), моб — блок.
   Стрелка — accent-шеврон data-uri; список раскрывает системный пикер ОС. */
.editchar-navsel{
  display:none; width:100%; box-sizing:border-box;
  height:46px; padding:0 40px 0 14px; border-radius:12px;
  background-color:var(--raise-2); color:var(--text); border:1px solid var(--line);
  font:inherit; font-size:14.5px; font-weight:600; cursor:pointer;
  -webkit-appearance:none; -moz-appearance:none; appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%232AABEE' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 14px center;
}
.editchar-navsel:focus{ outline:none; border-color:var(--accent-dim); }
.editchar-navsel optgroup{ font-weight:700; color:var(--text-3); }
.editchar-navsel option{ font-weight:500; color:var(--text); }

/* — Лесенка сцены (issue 5): дровер full-width на телефоне (был clamp min 360px →
     шире 356px-экрана и толкал контент), + эффект-контрол переносится, а не вылезает.
     Клиренс снизу — плавающий #char-actionbar висит и над дровером, закрывал
     нижние подсказки сцены (issue 6, скрин 6). */
@media (max-width:600px){
  .scn-drawer{ width:100vw; }
  /* Клиренс под бар персонажа больше не нужен: пока дровер открыт, бар скрыт
     (body.scn-drawer-open). Оставляем только отступ под системную полосу —
     иначе внизу сцены зияла пустая треть экрана. */
  .scn-drawer-body{ padding-bottom:calc(24px + var(--safe-b)); }
  /* Шапка на узком: подпись «Удалить сцену» дороже длины заголовка. */
  .scn-drawer-head{ padding:14px 14px; gap:8px; }
  .scn-drawer-del{ padding:6px 8px; font-size:12px; }
  /* Панель выделения в дровере: три действия + счётчик в одну строку на телефоне
     не влезают. Раскладка та же, что у панели склада (.scn-pk-hd @640) — счётчик
     отдельной строкой, кнопки во всю ширину и растягиваются поровну, чтобы
     соседние действия («Снять со сцены» и «Объединить») не слипались. */
  /* margin/padding НЕ трогаем: отрицательные поля должны совпадать с padding
     .scn-drawer-body (20px, на узком меняется только padding-bottom) — иначе
     панель перестанет доходить до краёв дровера. */
  .scn-pk-bar{ gap:8px; align-items:flex-start; }
  .scn-pk-bar-count{ flex:1 0 100%; }
  .scn-pk-bar-actions{ margin-left:0; width:100%; }
  .scn-pk-bar-actions > button{ flex:1 1 auto; min-width:0; white-space:nowrap; }
  .scn-fx-ctl{ flex-wrap:wrap; min-width:0; }
  .scn-fx-ttl{ min-width:0; max-width:100%; }
}

/* — Композер диалога: textarea на всю ширину сверху, инструменты рядом снизу —
     иначе 6 кнопок сжимают поле и плейсхолдер рвётся по буквам (issue 2). */
@media (max-width:600px){
  .dlg-composer{ flex-wrap:wrap; align-items:center; }
  .dlg-composer textarea{ order:-1; flex:1 0 100%; width:100%; }
  .dlg-composer-send{ margin-left:auto; }
  /* На мобиле у клавиатуры своя панель эмодзи — наша кнопка лишняя (фидбэк п.7) */
  #dlg-emoji-btn{ display:none; }
}

/* — Шапка экрана (Аккаунты и др.): заголовок и действия в стек, поиск жмётся —
     иначе search min-width:230px + кнопка не влезают рядом с заголовком (issue 7). */
@media (max-width:600px){
  .ndash .screen-row{ flex-direction:column; align-items:stretch; gap:12px; }
  .ndash .screen-row .screen{ margin:0; }
  #acc-actionrow{ width:100%; }
  .ndash .screen-actions{ width:100%; }
  .ndash .screen-actions .ninput--search{ flex:1; min-width:0; }
}

/* — Лента поступлений: прячем вторичные колонки (персонаж/статус/время) и жмём
     ячейки — 6 колонок × padding 24px не влезают, лента скроллит (issue 1). */
@media (max-width:600px){
  #dash-sales thead th, #dash-sales td{ padding-left:12px; padding-right:12px; }
  #dash-sales th:nth-child(2), #dash-sales td:nth-child(2),   /* Персонаж */
  #dash-sales th:nth-child(5), #dash-sales td:nth-child(5),   /* Статус */
  #dash-sales th:nth-child(6), #dash-sales td:nth-child(6){   /* Время */
    display:none;
  }
  /* остаётся Клиент | Позиция | Цена. Ячейке клиента отдаём ВЕСЬ остаток
     ширины, а двум колонкам-константам разрешаем ровно их контент
     (width:1% + nowrap — классический приём «жать к содержимому»). Без
     width:100% ячейка клиента схлопывалась в минимум и имя резалось до двух
     букв: на живом проде целиком читались 6 имён из 30, стало 29 из 30.
     max-width:0 ОБЯЗАТЕЛЕН — без него ellipsis в table-layout:auto не
     срабатывает и таблица распирается (замер: 395 при контейнере 364). */
  #dash-sales table{ width:100%; table-layout:auto; }
  #dash-sales th:first-child, #dash-sales td:first-child{ max-width:0; width:100%; }
  #dash-sales th:nth-child(3), #dash-sales td:nth-child(3),
  #dash-sales th:nth-child(4), #dash-sales td:nth-child(4){ width:1%; white-space:nowrap; }
  #dash-sales .coin{ min-width:0; }
  #dash-sales .coin > span:last-child{
    min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }
  #dash-sales .coin .time-cell{ display:none; }
  /* лента «Последние поступления» не должна уходить под таб-бар: снимаем
     вложенный скролл на телефоне → таблица течёт в скролл страницы (там клиренс) */
  #dash-sales .tbl-scroll{ max-height:none; overflow:visible; }
}

/* — Верх дашборда на телефоне: eyebrow «ОБЗОР ЗА МЕСЯЦ» дублирует активную
     кнопку сегмента («Месяц» и так подсвечен), а сам сегмент был прижат вправо
     при полноширинном селекторе аккаунта — левая кромка получалась рваной.
     Тот же приём уже применён к .rd-strip-s на ≤900 («подпись дублирует то,
     что сказано точками»). Замер на живом проде: карточка дохода поднимается
     со 148px до 117px от верха контента. */
@media (max-width:600px){
  .ndash .screen-row > .screen{ display:none; }
  .ndash .screen-ctl{ width:100%; gap:10px; }
  .ndash .screen-ctl .seg{ display:flex; width:100%; }
  .ndash .screen-ctl .seg button{ flex:1; }
  /* Селектор аккаунта тоже во всю ширину. Иначе правая кромка снова рваная:
     сегмент растянут на 390, а триггер упирается в max-width:260px (:8305) и
     обрывается на две трети экрана. Оба ряда шапки должны кончаться на одной
     вертикали, ради чего и убирался eyebrow. */
  .ndash .screen-ctl .dash-acc-dd{ display:block; width:100%; }
  .ndash .screen-ctl .dash-acc-dd .parser-acc-trigger{
    width:100%; min-width:0; max-width:none; box-sizing:border-box;
  }
}

/* — Админка: широкая таблица данных обрезалась намертво. Базовое правило
     .data-table-wrap (:828) ставит overflow:hidden ради скруглённых углов —
     на телефоне это прятало 890px колонок без единого способа их достать
     (замер: контент 1254 в контейнере 364). Отдаём в горизонтальный скролл. */
@media (max-width:900px){
  #page-admin .data-table-wrap{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
}

/* — Диалоги на телефоне: текст-бабблы шире. На десктопе «воздух 62%» (концепт,
     строка 6657) — но на телефоне 62% слишком узко; тот же селектор+специфичность,
     позже в файле → перебивает только на моб. Медиа-бабблы уже full-width. */
@media (max-width:600px){
  #page-dialogs .dlg-msg:not(.dlg-msg--media){ max-width:92%; }
}

/* — Таблица аккаунтов на телефоне → КАРТОЧКИ. Table-layout шире экрана давал
     горизонтальный скролл; здесь строка = flex-wrap-карточка, ячейки переносятся
     → скролл невозможен в принципе. thead скрыт (ячейки самоочевидны). CSS-only. */
@media (max-width:860px){
  #page-accounts .tbl-scroll{ overflow:visible; max-height:none; }
  #page-accounts table, #page-accounts thead, #page-accounts tbody{ display:block; width:100%; }
  #page-accounts thead{ display:none; }
  #page-accounts .table-wrap{ background:none; border:0; overflow:visible; }
  #page-accounts tbody tr{
    display:flex; flex-wrap:wrap; align-items:center; gap:9px 10px;
    padding:12px 14px; margin:0 0 10px;
    border:1px solid var(--line); border-radius:14px; background:var(--raise-1);
  }
  #page-accounts tbody tr:last-child{ margin-bottom:0; }
  #page-accounts tbody td{ display:block; padding:0; border:0; }
  #page-accounts tbody td:nth-child(1){ order:1; flex:none; }              /* чекбокс */
  #page-accounts tbody td:nth-child(2){ order:2; flex:1; min-width:0; }    /* аккаунт (аватар+имя) */
  #page-accounts tbody td:nth-child(3){ order:3; flex-basis:100%; }        /* персонаж-селект — своя строка */
  #page-accounts tbody td:nth-child(3) .nacc{ width:100%; box-sizing:border-box; }
  #page-accounts tbody td:nth-child(4){ order:4; }                         /* статус */
  #page-accounts tbody td:nth-child(5){ order:5; text-align:left; color:var(--text-2); font-size:12.5px; }
  #page-accounts tbody td:nth-child(5)::before{ content:"💬 "; opacity:.75; } /* «Диалогов» без шапки */
  #page-accounts tbody td:nth-child(6){ order:6; }                         /* прокси */
  #page-accounts tbody td:nth-child(7){ order:7; }                         /* бизнес-бот */
  #page-accounts tbody td:nth-child(9){ order:8; margin-left:auto; }       /* действия — вправо */
  #page-accounts tbody td:nth-child(8){ order:9; flex-basis:100%; }        /* защита от флуда — своя строка */
  #page-accounts tbody td:nth-child(8) .nacc{ width:100%; box-sizing:border-box; }
  #page-accounts tbody td.r{ text-align:left; }
}

/* — Контекст-панель чата (Нейрочат/Слоу-мод/вовлечённость/Режим/Заметка) была
     display:none на моб (4837) — недоступна. Теперь ВЫЕЗЖАЮЩИЙ СНИЗУ ЛИСТ по кнопке
     в шапке. Только ≤768 (там .dlg-conv position:absolute — single-panel); position:
     absolute, НЕ fixed (eg-fade держит transform на .main-content → ломает fixed).
     Позже в файле того же веса → перебивает display:none из 4837. */
@media (max-width:768px){
  #page-dialogs .dlg-panel{
    /* flex+gap как на десктопе — display:block убивал gap:12px → строки слипались */
    display:flex; flex-direction:column; gap:14px;
    position:absolute; left:0; right:0; bottom:0; width:auto; z-index:210;
    max-height:85%; overflow-y:auto; box-sizing:border-box;
    background:linear-gradient(180deg,#16151b,#0e0d12);
    border-top:1px solid #28262f; border-radius:18px 18px 0 0;
    padding:16px 16px calc(18px + var(--safe-b));
    /* visibility (как #more-sheet): закрытый лист НЕ виден/не кликается, даже если
       translateY уводит его в зону таб-бара — иначе торчал бы поверх (z-index 210). */
    visibility:hidden; transform:translateY(101%);
    transition:transform .26s cubic-bezier(0.32,0.72,0,1), visibility 0s .26s;
    box-shadow:0 -16px 48px rgba(0,0,0,.5);
  }
  #page-dialogs .dlg-panel::before{
    content:''; flex:none; width:38px; height:4px; border-radius:2px;
    background:#3a3a42; margin:0 auto 2px;
  }
  #page-dialogs .dlg-wrap.pn-open .dlg-panel{
    visibility:visible; transform:translateY(0);
    transition:transform .26s cubic-bezier(0.32,0.72,0,1), visibility 0s 0s;
  }
  #page-dialogs .dlg-pn-scrim{
    display:block; position:absolute; inset:0; z-index:205;
    background:rgba(0,0,0,.5); opacity:0; pointer-events:none;
    transition:opacity .22s var(--ease-out);
  }
  #page-dialogs .dlg-wrap.pn-open .dlg-pn-scrim{ opacity:1; pointer-events:auto; }
  .dlg-chd-tr.dlg-chd-panel{ display:flex; }
}
/* десктоп/планшет >768: триггер и скрим не нужны (панель инлайн либо скрыта) */
@media (min-width:769px){
  .dlg-chd-tr.dlg-chd-panel{ display:none; }
  #page-dialogs .dlg-pn-scrim{ display:none; }
}

/* ============================================================
   OLED depth: scene editor — ПОВЕРХНОСТИ ТОЛЬКО (CSS-only).
   НЕ трогаем семантику: .scn-price.paid / .scn-pk-chip (золото = платно),
   .scn-spice-btn (тёплый тепловой меттер), .scn-th-pill,
   Грид под #page-characters (токены кита); дровер/стокпикер в <body> (литералы).
   ============================================================ */
/* --- сетка сцен (media-пейн, под .ndash) --- */
#page-characters .scn-card{ background:var(--raise-1); border:1px solid var(--line); border-radius:16px; overflow:hidden; transition:border-color .15s, transform .15s; }
#page-characters .scn-card:hover{ border-color:var(--accent-dim); transform:translateY(-2px); }
#page-characters .scn-cover{ background:var(--black); }
#page-characters .scn-card-title{ color:var(--text); font-weight:600; }
#page-characters .scn-chip{ background:var(--raise-2); border:1px solid var(--line); color:var(--text-2); border-radius:7px; }
#page-characters .scn-add-card{ background:transparent; border:1px dashed var(--line); border-radius:16px; color:var(--text-3); transition:border-color .15s, color .15s; }
#page-characters .scn-add-card:hover{ border-color:var(--accent-dim); color:var(--accent); }
#page-characters .scn-section-title{ color:var(--text-2); }
#page-characters .scn-section-count{ color:var(--text-3); }
#page-characters .scn-empty-hint{ color:var(--text-3); }
#page-characters .mv-card{ background:var(--raise-1); border:1px solid var(--line); border-radius:14px; overflow:hidden; }
#page-characters .mv-preview{ background:var(--black); }
#page-characters .mv-assign-select{ background:var(--black); border:1px solid var(--line); color:var(--text); border-radius:9px; }
#page-characters .mv-del-btn{ background:var(--raise-2); border:1px solid var(--line); color:var(--text-3); border-radius:8px; }

/* --- дровер-инспектор (в <body>, вне .ndash → литералы канона) --- */
.scn-scrim{ background:rgba(0,0,0,.62); }
.scn-drawer{ background:#0a0a0c; border-left:1px solid #232327; }
.scn-drawer-head{ background:#131316; border-bottom:1px solid #1c1c20; }
.scn-drawer-title{ color:#f5f5f5; font-weight:600; }
.scn-drawer-close{ background:#1a1a1e; border:1px solid #232327; color:#a8a8ad; border-radius:8px; }
.scn-drawer-close:hover{ color:#f5f5f5; }
/* Кнопка удаления сцены — та же поверхность, что у ✕; красной становится только
   на ховере, чтобы не тянуть взгляд к деструктивному действию в шапке. */
.scn-drawer-del{ background:#1a1a1e; border:1px solid #232327; color:#a8a8ad; border-radius:8px; }
.scn-drawer-del:hover{ color:#E0533B; border-color:rgba(224,83,59,.45); background:rgba(224,83,59,.12); }
.scn-grp{ background:#131316; border:1px solid #232327; border-radius:14px; padding:16px; }
.scn-grp-h{ color:#f5f5f5; }
.scn-grp-hint{ color:#6c6c72; }
.scn-lbl{ color:#6c6c72; }
.scn-inp{ background:#0a0a0c; border:1px solid #232327; border-radius:10px; color:#f5f5f5; }
.scn-inp:focus{ border-color:#1d7fb3; outline:none; }
.scn-toggle-label{ color:#a8a8ad; }

/* --- ucard-строки лесенки + пак-плашки (raise-2, слоятся на raise-1 grp) --- */
.scn-lad-row, .scn-pk-plaque{ background:#1a1a1e; border:1px solid #232327; border-radius:12px; }
.scn-lad-row:hover, .scn-pk-plaque:hover{ border-color:#1d7fb3; }
.scn-lad-thumb, .scn-pk-cover, .scn-pk-thumb{ background:#0a0a0c; }
.scn-card-cap{ border-top:1px solid #1c1c20; }
.scn-lad-cap, .scn-pk-cap{ background:#0a0a0c; border:1px solid #232327; border-radius:9px; color:#f5f5f5; }

/* --- кнопки добавления в лесенку (seg/spice/price НЕ трогаем — семантика/ок) --- */
.scn-lad-add-btn{ background:#1a1a1e; border:1px solid #232327; color:#a8a8ad; border-radius:10px; }
.scn-lad-add-btn:hover{ color:#2aabee; border-color:#1d7fb3; }
.scn-lad-kind{ background:#0a0a0c; border:1px solid #232327; color:#f5f5f5; border-radius:9px; }
.scn-mini-label{ color:#6c6c72; }

/* --- стокпикер (в <body>) --- */
.scn-stock-picker{ background:#131316; border:1px solid #232327; border-radius:16px; box-shadow:0 12px 48px rgba(0,0,0,.6); }
.scn-stock-head{ color:#f5f5f5; border-bottom:1px solid #1c1c20; }
.scn-stock-item{ background:#0a0a0c; border:1px solid #232327; border-radius:10px; }
.scn-stock-item.selected{ border-color:#2aabee; }
.scn-stock-foot .btn-primary{ background:#2aabee; border-color:#2aabee; color:#04121b; font-weight:700; border-radius:10px; }

/* ============================================================
   OLED depth: settings — точечные добивки (карты/поля/кнопки уже мигрированы
   ранней OLED-работой в .ndash .set-* блоке; здесь только off-canon остатки).
   ============================================================ */
/* callout: янтарный платформ-цвет ломал единый синий язык → нейтральный inset,
   смысл несёт иконка ℹ️/⚠️ */
#page-settings .set-callout{ background:var(--black); border:1px solid var(--line-soft); color:var(--text-2); }
#page-settings .set-callout .ico{ opacity:.9; }
/* Та же нейтрализация для модалки подъёма аккаунта. Базовое .set-callout —
   ЯНТАРНОЕ (предупреждение), а этот блок сообщает ровно обратное: «вход заново
   обычно возвращает в тот же аккаунт, история на месте». Жёлтая рамка читается
   как «осторожно» и отговаривает от безопасного шага — того самого, из-за
   которого лежащие аккаунты не чинили. Нейтральный тон здесь несёт смысл. */
#modal-acct-revive .set-callout{ background:var(--black); border:1px solid var(--line-soft); color:var(--text-2); }
#modal-acct-revive .set-callout .ico{ opacity:.9; }

/* ============================================================
   OLED depth: admin (уже под .ndash; перебиваем #page-admin платформ-токены на канон кита)
   ============================================================ */
/* сегмент-контрол табов: recolor + accent-soft активный */
#page-admin .admin-tabs{ background:var(--raise-1); border:1px solid var(--line); border-radius:12px; padding:5px; gap:4px; }
#page-admin .admin-tab{ border-radius:9px; color:var(--text-2); border:1px solid transparent; }
#page-admin .admin-tab:hover{ background:var(--raise-2); color:var(--text); }
#page-admin .admin-tab.active{ background:var(--accent-soft); border-color:var(--accent-dim); color:var(--accent); font-weight:600; }
#page-admin .admin-tab svg{ width:15px; height:15px; }

/* таблицы под кит-рецепт (raise-1 карта + хайрлайн-строки + uppercase-шапка) */
#page-admin .data-table-wrap{ background:var(--raise-1); border:1px solid var(--line); border-radius:16px; }
#page-admin .table-meta{ color:var(--text-3); border-bottom:1px solid var(--line-soft); }
#page-admin .data-table th{ background:transparent; color:var(--text-3); border-bottom:1px solid var(--line-soft); }
#page-admin .data-table td{ border-bottom:1px solid var(--line-soft); color:var(--text-2); }
#page-admin .data-table tbody tr:hover td{ background:var(--raise-2); }

/* server-панель стат-карт (ЖИВОЙ .acc-stat-card) */
#page-admin .acc-stat-card{ background:var(--raise-1); border:1px solid var(--line); border-radius:14px; }

/* легаси-нутро admin-таблиц → язык кита (статус как .pill, «Удалить» как .nbtn ghost-danger),
   консистентно с гл. Аккаунтами (.pill.g/.iconbtn) и Обновлениями/Прокси (.nbtn ghost danger).
   Рендер admin эмитит .status-tag/.btn-danger (loadAdminAccounts/Users/Characters/Invites). */
#page-admin .status-tag{ border:0; font-weight:600; }
#page-admin .status-tag.active{ background:var(--good-dim); color:var(--good); }
#page-admin .status-tag.sleeping{ background:rgba(224,169,58,.13); color:#e0a93a; }
#page-admin .status-tag.disconnected{ background:var(--raise-2); color:var(--text-3); }
#page-admin .btn-danger{ background:var(--raise-2); border:1px solid var(--line); color:var(--text-2); }
#page-admin .btn-danger:hover{ background:var(--crit-dim); border-color:var(--crit); color:var(--crit); }

/* ── Реферальная программа ───────────────────────────────────────────
   Экран собран из деталей дашборда: панели raise-1/16px, счётчики .neon-row,
   таблица .table-wrap. Свои классы — только раскладка и hero-типографика. */
#referral-body { display: flex; flex-direction: column; gap: 14px; }
.ref-top { display: grid; grid-template-columns: 3fr 2fr; gap: 14px; align-items: stretch; }
.ndash .ref-hero, .ndash .ref-how {
  background: var(--raise-1); border: 1px solid var(--line-soft);
  border-radius: 16px; min-width: 0;
}
.ndash .ref-hero { padding: 26px 28px 24px; display: flex; flex-direction: column; gap: 10px; }
.ref-hero-title { font-size: 24px; font-weight: 700; letter-spacing: -.01em; }
.ref-hero-sub { font-size: 13.5px; color: var(--text-2); line-height: 1.55; max-width: 56ch; }
/* Ссылка — главный объект: прижата к низу hero, лейбл в стиле thead дашборда */
.ref-link-lbl {
  margin-top: auto; padding-top: 18px; font-size: 11px; font-weight: 500;
  color: var(--text-3); text-transform: uppercase; letter-spacing: .06em;
}
.ref-linkrow { display: flex; gap: 10px; margin-top: 8px; flex-wrap: wrap; }
.ref-linkrow input {
  flex: 1; min-width: 220px; height: 44px; padding: 0 14px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--black); color: var(--text);
  font: inherit; font-size: 13.5px; font-variant-numeric: tabular-nums;
}
.ref-linkrow input:focus { outline: none; border-color: var(--accent); }
.ref-linkrow .btn { height: 44px; border-radius: 12px; padding: 0 18px; }
.ref-notice {
  margin-top: auto; padding: 13px 15px; border: 1px dashed var(--line);
  border-radius: 12px; font-size: 13px; color: var(--text-3);
}
.ndash .ref-how { padding: 22px 24px; }
.ref-how-title { font-size: 16px; font-weight: 600; margin-bottom: 16px; }
.ref-step { display: flex; gap: 12px; align-items: flex-start; }
.ref-step + .ref-step { margin-top: 14px; }
.ref-step-n {
  flex: 0 0 24px; height: 24px; border-radius: 50%; background: var(--raise-2);
  color: var(--text-2); font-size: 12px; font-weight: 600;
  display: flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums;
}
.ref-step-t { font-size: 13.5px; font-weight: 600; }
.ref-step-s { font-size: 12.5px; color: var(--text-3); margin-top: 2px; line-height: 1.45; }
/* Колл-аут для владельцев групп/каналов — отделён линейкой от шагов */
.ref-partner {
  margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line-soft);
  font-size: 12.5px; color: var(--text-3); line-height: 1.5;
}
.ref-partner a { color: var(--accent); text-decoration: none; font-weight: 600; }
.ref-partner a:hover { text-decoration: underline; }
/* Счётчики — тот же .neon-row, что стата дашборда, но 3 ячейки и без нижнего
   отступа (интервал держит flex-gap #referral-body). Позже дашбордных правил
   в файле → перебивает и базовые 4 колонки, и мобильные 2 из @820. */
.ndash .ref-neon { grid-template-columns: repeat(3, 1fr); margin-bottom: 0; }
@media (max-width: 980px) { .ref-top { grid-template-columns: 1fr; } }
@media (max-width: 640px) { .ndash .ref-neon { grid-template-columns: 1fr; } }

/* ── Консоль менеджера (body.manager-mode, Task 4/5) ──────────────────────
   Менеджер — полноценный оператор ВНУТРИ диалога, но не администратор:
   дашборд показывает ТОЛЬКО «Диалоги» — вся прочая owner-навигация и
   владельческие хедер-кнопки скрыты. Верифицировано по ui/index.html:
   .nav-item живёт в трёх местах (десктоп-хедер #hdr-nav + выпадашка «Ещё»
   #hdr-more-menu, мобильный таб-бар #mtabbar с классом .mtab-item, мобильный
   шит «Ещё» #more-sheet) — все три покрыты одним селектором ниже, кроме
   пункта dialogs (data-page="dialogs" есть и на десктопе, и в таб-баре —
   оба остаются). #hdr-more/#mtab-more — доп.: сами триггеры дропдауна/шита
   «Ещё», чьё содержимое и так становится пустым (все его пункты — owner-only
   .nav-item), иначе кнопка вела бы в пустой дропдаун. */
body.manager-mode .nav-item:not([data-page="dialogs"]),
body.manager-mode #hdr-more,
body.manager-mode #mtab-more,
body.manager-mode #hdr-user-btn,
body.manager-mode #super-view-btn { display: none !important; }

/* Task 2: обе полосы над/под «Диалогами» мертвы в консоли. Хедер несёт только
   логотип + плашку энергии (энергия — owner-only /api/me/energy, показывала
   бы «—», её намеренно не зовём). Таб-бар после гашения owner-пунктов (правило
   выше) остаётся с ОДНОЙ вкладкой «Диалоги» — не навигация, а балласт. На
   телефоне это ~116px мёртвой высоты (--hdr-h:56px + #mtabbar:60px). */
body.manager-mode .app-header{ display: none !important; }
body.manager-mode #mtabbar{ display: none !important; }

/* Возвращаем эту высоту чатам. Мобильная формула диалогов (:4812) —
   height:calc(100dvh - 128px - var(--safe-b)) — не раскладывается в чистую
   сумму: --hdr-h(56)+#mtabbar(60)=116, а не 128, и .main-content{padding-
   bottom:…} (:4180/:7034) на #page-dialogs НЕ действует (#page-dialogs{padding:0}
   в :2291 — ID-селектор, бьёт .main-content по специфичности вне зависимости
   от порядка). Проверено правкой: живой источник лишних ~12px — не отдельное
   CSS-правило, а подгонка на глаз при внедрении (commit addc13ea, 2026-07-06,
   до появления #mtabbar-паддингов). Копировать «128» в консоли, где хедера и
   таб-бара нет вовсе, было бы гаданием. Вместо этого переиспользуем уже
   рабочую desktop-цепочку .layout→.main→#page-dialogs→.dlg-wrap
   (height:100%, см. :2566-2568) — она не завязана на магические числа и
   автоматически даёт .dlg-wrap всю высоту, которую .main реально имеет. */
body.manager-mode #page-dialogs .dlg-wrap{ height: 100% !important; }

/* Хедер и таб-бар скрыты, .dlg-wrap занимает весь экран → нижний край треда
   совпадает с физическим низом. Раньше зазор под home-indicator давали формула
   .dlg-wrap (- var(--safe-b)) и сам #mtabbar (padding-bottom: var(--safe-b)) —
   в консоли нет ни того, ни другого, а у .dlg-comp своего --safe-b нет.
   Поэтому клиренс даём композеру, а не отбираем высоту у чатов. */
body.manager-mode #page-dialogs .dlg-comp{
  padding-bottom: calc(12px + var(--safe-b)) !important;
}
/* Тот же зазор нужен списку чатов: когда тред ЗАКРЫТ, .dlg-list (flex:1 в
   колонке .dlg-wrap) тоже достаёт до физического низа, и последняя строка
   #dlg-chats попадала бы под индикатор — тем же путём, что и композер. */
body.manager-mode #page-dialogs .dlg-chats{
  padding-bottom: calc(4px + var(--safe-b)) !important;
}

/* ── «Персональный ценник»: список в редакторе персонажа ─────────────── */
.pricebook { margin-top: 12px; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.pb-row { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-top: 1px solid var(--line-soft); }
.pb-row:first-child { border-top: none; }
.pb-ico { width: 22px; text-align: center; flex-shrink: 0; font-size: 14px; }
.pb-name { font-size: 13.5px; color: var(--t1); font-weight: 600; flex: 0 1 auto; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pb-note { font-size: 12px; color: var(--t3); margin-left: 7px; font-weight: 400; }
.pb-row.off .pb-name { color: var(--t2); font-weight: 500; }
.pb-sep { display: flex; align-items: center; gap: 8px; padding: 7px 16px; background: rgba(255,255,255,.015);
  border-top: 1px solid var(--line-soft); font-size: 11px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--t3); }
.pb-sep::after { content: ''; flex: 1; height: 1px; background: var(--line-soft); }
.pb-arr { color: var(--accent-dim); font-size: 12px; }
/* Контрол значения — компактное поле со знаком справа (строка настроек в стиле macOS:
   имя слева, значение справа). Ползунок выпилен: точное число мышью не выставить,
   а рельса на всю ширину читалась «простынёй» (фидбек 24.07). */
.pb-spacer { flex: 1; }
.pb-val { display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0; }
.pb-input { width: 84px; text-align: right; background: var(--bg-input); border: 1px solid var(--line);
  border-radius: 10px; color: var(--accent); font-weight: 700; font-size: 13.5px; padding: 7px 10px;
  outline: none; font-variant-numeric: tabular-nums; font-family: inherit; transition: border-color .13s; }
.pb-input::placeholder { color: var(--t3); font-weight: 500; }
.pb-input:hover { border-color: rgba(42,171,238,.4); }
.pb-input:focus { border-color: var(--accent); }
.pb-unit { font-size: 12.5px; color: var(--t3); font-weight: 600; }

/* Корректировка цены папки на чипе НЕ отображается (фидбек 24.07: третья цифра на
   фильтр-таблетке сливалась в кашу) — чип остался как до фичи (имя+счётчик), значение
   живёт в «Персональном ценнике», панели чата и title-тултипе чипа. */
/* Счётчик чипа — пузырёк в ОБОИХ состояниях: generic-фон var(--sheet) на неактивном
   чипе сливался с его же фоном (пузырёк был виден только на синем активном). Зазор
   имя↔счётчик тоже тем же весом — generic глушит margin !important'ом. */
#page-dialogs .dlg-seg .dlg-cat-chip .dlg-cat-cnt {
  margin-left: 7px !important; background: rgba(255,255,255,.10) !important;
  padding: 1px 7px !important; border-radius: 999px !important;
  font-size: 10.5px !important; font-variant-numeric: tabular-nums;
  opacity: 1; color: var(--t2);
}
#page-dialogs .dlg-seg .dlg-cat-chip.act .dlg-cat-cnt {
  background: rgba(10, 10, 12, .5) !important; color: #fff;
}

/* «⋯» курирования папки (Находка 3) — вторая, тач-доступная точка входа в
   dlgCatMenu, у чипов с can_curate===1. Свой блок с !important по той же причине,
   что и у .dlg-cat-cnt чуть выше: generic .dlg-seg span клобберит padding/background.
   Отдельный элемент ПОСЛЕ счётчика — не наезжает на него и не меняет его раскладку. */
#page-dialogs .dlg-seg .dlg-cat-chip .dlg-cat-curate {
  /* Скрыта по умолчанию: на всех папках сразу «⋯» превращала полосу фильтров
     в частокол. Показываем только у ВЫБРАННОГО чипа — курирование почти всегда
     идёт после того, как папку открыли, так что лишнего шага это не добавляет. */
  display: none !important; align-items: center; justify-content: center;
  width: 15px !important; height: 15px !important; padding: 0 !important;
  margin-left: 5px !important; border-radius: 50% !important;
  background: rgba(255,255,255,.14) !important; color: var(--t2);
  font-size: 10px !important; line-height: 1; cursor: pointer;
}
#page-dialogs .dlg-seg .dlg-cat-chip.act .dlg-cat-curate {
  display: inline-flex !important;
  background: rgba(10,10,12,.5) !important; color: #fff;
}
#page-dialogs .dlg-seg .dlg-cat-chip.act .dlg-cat-curate:hover { background: rgba(10,10,12,.72) !important; }

/* ── Секция «Готовность к работе» на дашборде ───────────────────────────── */
.ndash .rd{margin-bottom:22px}

/* Свёрнутая строка — то, что видно при полной готовности. */
.ndash .rd-strip{display:flex;align-items:center;gap:13px;width:100%;padding:14px 20px;
  border:1px solid var(--line-soft);border-radius:16px;background:var(--raise-1);
  font-family:inherit;color:inherit;text-align:left;cursor:pointer;
  transition:border-color var(--dur-2) var(--nease),background var(--dur-2) var(--nease),
             transform var(--dur-1) var(--ease-out)}
.ndash .rd-strip:hover{border-color:var(--line);background:var(--raise-2)}
.ndash .rd-strip:active{transform:scale(.997)}
.ndash .rd-strip:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.ndash .rd-strip.alarm{border-color:rgba(224,107,107,.34);background:rgba(224,107,107,.05)}
.ndash .rd-strip-skel{cursor:default;pointer-events:none}
.ndash .rd:not(.expanded) .rd-count,
.ndash .rd:not(.expanded) .rd-check{display:none}
.ndash .rd-strip-t{font-size:13.5px;font-weight:650;flex:none;white-space:nowrap}
.ndash .rd-strip-s{font-size:12.5px;color:var(--text-3);margin-right:auto;
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ndash .rd-strip.alarm .rd-strip-s{color:var(--crit)}
.ndash .rd-dots{display:flex;gap:5px;flex:none}
.ndash .rd-dots i{width:7px;height:7px;border-radius:50%;background:var(--text-3);display:block;
  transition:background var(--dur-3) var(--nease)}
.ndash .rd-dots i.ok{background:var(--good)}
.ndash .rd-dots i.warn{background:#ebb14a}
.ndash .rd-dots i.crit{background:var(--crit)}
.ndash .rd-dots i.idle,.ndash .rd-dots i.na{background:transparent;border:1px solid var(--text-3)}
.ndash .rd-dots i.unknown{background:transparent;border:1px dashed var(--text-3)}
.ndash .rd-chev{color:var(--text-3);font-size:12px;flex:none;
  transition:transform var(--dur-3) var(--nease)}
.ndash .rd.expanded .rd-chev{transform:rotate(180deg)}

/* Развёрнутая часть: та же техника, что у панели шага. */
.ndash .rd-full{display:grid;grid-template-rows:0fr;
  transition:grid-template-rows var(--dur-4) var(--nease)}
.ndash .rd.expanded .rd-full{grid-template-rows:1fr}
.ndash .rd-full-in{overflow:hidden;min-height:0;transition:opacity var(--dur-3) var(--nease)}
.ndash .rd:not(.expanded) .rd-full-in{opacity:0}
.ndash .rd-body{margin-top:10px;border:1px solid var(--line-soft);border-radius:16px;overflow:hidden;
  background:var(--raise-1);transition:border-color .3s var(--nease)}
.ndash .rd.has-blocker .rd-body{border-color:rgba(224,107,107,.35)}
.ndash .rd-count{font-size:12px;font-variant-numeric:tabular-nums;color:var(--text-3);
  padding:3px 9px;border-radius:20px;background:var(--raise-2);font-weight:600;
  flex:none;white-space:nowrap}
.ndash .rd-count.ok{color:var(--good);background:var(--good-dim)}
.ndash .rd-count.blocked{color:var(--crit);background:var(--crit-dim)}
.ndash .rd-check{border:1px solid var(--line);background:var(--black);
  color:var(--text-2);font-family:inherit;font-size:12px;font-weight:550;padding:6px 13px;
  border-radius:9px;cursor:pointer;display:inline-flex;align-items:center;gap:7px;
  flex:none;white-space:nowrap;
  transition:color var(--dur-2) var(--nease),border-color var(--dur-2) var(--nease),
             transform var(--dur-1) var(--ease-out)}
.ndash .rd-check:hover{color:var(--text);border-color:var(--accent-dim)}
.ndash .rd-check:active{transform:scale(.97)}
.ndash .rd-check:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.ndash .rd-check.busy{opacity:.6;pointer-events:none}
.ndash .rd-check.busy::before{content:'';width:11px;height:11px;border-radius:50%;
  border:1.5px solid var(--line);border-top-color:var(--accent);
  animation:rd-spin 620ms linear infinite}
@keyframes rd-spin{to{transform:rotate(360deg)}}
.ndash .rd-row{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line-soft)}
.ndash .rd-card{background:var(--black);border:none;text-align:left;font-family:inherit;
  font-size:14px;color:inherit;padding:22px 24px 20px;cursor:pointer;min-width:0;display:flex;
  flex-direction:column;position:relative;
  transition:background var(--dur-2) var(--nease),transform var(--dur-1) var(--ease-out)}
.ndash .rd-card:hover,.ndash .rd-card.open{background:var(--raise-2)}
.ndash .rd-card:active{transform:scale(.995)}
.ndash .rd-card:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.ndash .rd-card::before{content:'';position:absolute;inset:0 0 auto 0;height:2px;
  background:var(--stripe,transparent);transition:background .25s var(--nease)}
.ndash .rd-card.s-ok{--stripe:var(--good)}
.ndash .rd-card.s-warn{--stripe:#ebb14a}
.ndash .rd-card.s-crit{--stripe:var(--crit)}
.ndash .rd-card.s-na,.ndash .rd-card.s-unknown,.ndash .rd-card.s-idle{--stripe:var(--line)}
.ndash .rd-top{display:flex;align-items:center;gap:8px;margin-bottom:11px;padding-right:26px}
.ndash .rd-step{position:absolute;top:14px;right:14px;width:18px;height:18px;border-radius:5px;
  background:var(--raise-2);color:var(--text-3);font-size:10.5px;font-weight:700;
  display:grid;place-items:center;font-variant-numeric:tabular-nums}
.ndash .s-ok .rd-step{background:var(--good-dim);color:var(--good)}
.ndash .s-warn .rd-step{background:rgba(235,177,74,.12);color:#ebb14a}
.ndash .s-crit .rd-step{background:var(--crit-dim);color:var(--crit)}
.ndash .rd-dot{width:7px;height:7px;border-radius:50%;flex:none;background:var(--text-3)}
.ndash .s-ok .rd-dot{background:var(--good);box-shadow:0 0 8px rgba(63,201,122,.5)}
.ndash .s-warn .rd-dot{background:#ebb14a;box-shadow:0 0 8px rgba(235,177,74,.45)}
.ndash .s-crit .rd-dot{background:var(--crit);box-shadow:0 0 9px rgba(224,107,107,.55)}
.ndash .s-na .rd-dot,.ndash .s-idle .rd-dot{background:var(--line);border:1px solid var(--text-3)}
.ndash .s-unknown .rd-dot{background:transparent;border:1.5px dashed var(--text-3)}
.ndash .rd-name{font-size:12px;color:var(--text-3);letter-spacing:.04em;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
.ndash .rd-val{font-size:19px;font-weight:650;letter-spacing:-.015em;
  font-variant-numeric:tabular-nums;line-height:1.2}
.ndash .s-warn .rd-val{color:#ebb14a}
.ndash .s-crit .rd-val{color:var(--crit)}
.ndash .s-na .rd-val,.ndash .s-unknown .rd-val,.ndash .s-idle .rd-val{color:var(--text-3)}
.ndash .rd-sub{font-size:12px;color:var(--text-2)}
.ndash .rd-sub:not(:empty){margin-top:7px}
.ndash .rd-where{margin-top:auto;padding-top:14px;font-size:10.5px;text-transform:uppercase;
  letter-spacing:.09em;color:var(--text-3);font-weight:600}
.ndash .rd-panel{background:var(--raise-1);display:grid;grid-template-rows:0fr;
  border-top:1px solid transparent;
  transition:grid-template-rows var(--dur-4) var(--nease),border-top-color var(--dur-2) var(--nease)}
.ndash .rd-panel[data-open="true"]{grid-template-rows:1fr;border-top-color:var(--line-soft)}
.ndash .rd-panel-in{overflow:hidden;min-height:0;
  transition:opacity var(--dur-3) var(--nease),filter var(--dur-3) var(--nease)}
.ndash .rd-panel[data-open="false"] .rd-panel-in{opacity:0}
/* Подмена содержимого при переключении карточек: blur сшивает два состояния,
   иначе видно, как один текст наложился на другой. */
.ndash .rd-panel-in.rd-swapping{opacity:0;filter:blur(3px)}
.ndash .rd-panel-grid{padding:22px 24px 24px;display:grid;grid-template-columns:1fr 1fr;gap:26px 34px}
.ndash .rd-blk h4{font-size:11px;text-transform:uppercase;letter-spacing:.11em;
  color:var(--text-3);font-weight:650;margin:0 0 10px}
.ndash .rd-blk p{font-size:13.5px;color:var(--text-2);margin:0;max-width:52ch}
.ndash .rd-why{list-style:none;display:flex;flex-direction:column;gap:8px;padding:0;margin:0}
.ndash .rd-why li{font-size:13.5px;color:var(--text-2);padding-left:16px;position:relative}
.ndash .rd-why li::before{content:'';position:absolute;left:0;top:.55em;width:5px;height:5px;
  border-radius:50%;background:var(--crit);opacity:.65}
.ndash .rd-how{list-style:none;counter-reset:s;display:flex;flex-direction:column;gap:9px;padding:0;margin:0}
.ndash .rd-how li{counter-increment:s;font-size:13.5px;color:var(--text-2);padding-left:26px;position:relative}
.ndash .rd-how li::before{content:counter(s);position:absolute;left:0;top:1px;width:17px;height:17px;
  border-radius:5px;background:var(--raise-2);color:var(--text-3);font-size:10.5px;font-weight:700;
  display:grid;place-items:center;font-variant-numeric:tabular-nums}
/* Подзаголовок провайдера в «Оплате картой»: появляется ТОЛЬКО когда провайдеров
   два — иначе подписывать нечего и лишний ярус заголовков только шумит. Счётчик
   шагов сбрасываем: у каждого провайдера своя инструкция «с единицы». */
.ndash .rd-sub{font-size:11px;letter-spacing:.07em;text-transform:uppercase;font-weight:700;
  color:var(--text-3);margin:16px 0 9px}
.ndash .rd-sub:first-child{margin-top:0}
.ndash .rd-why + .rd-sub, .ndash .rd-how + .rd-sub{margin-top:18px}
.ndash .rd-blk .rd-hint{margin-top:14px;font-size:12.5px;color:var(--text-2);
  padding:9px 12px;background:var(--raise-2);border-radius:9px;max-width:52ch;line-height:1.45}
.ndash .rd-blk .rd-hint b{color:var(--accent);font-weight:650}
.ndash .rd-blk .rd-done{margin-top:20px;font-size:12.5px;color:var(--good);padding:10px 13px;
  background:var(--good-dim);border-radius:9px;max-width:52ch;line-height:1.45}
.ndash .rd-span{grid-column:1/-1}
.ndash .rd-accs{display:flex;flex-direction:column;gap:1px;background:var(--line-soft);
  border:1px solid var(--line-soft);border-radius:11px;overflow:hidden}
.ndash .rd-acc{display:flex;align-items:center;gap:10px;padding:10px 13px;background:var(--black);font-size:13px}
.ndash .rd-acc .nm{font-weight:600;flex:none}
.ndash .rd-acc .rs{color:var(--text-3);font-size:12.5px;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.ndash .rd-acc.a-ok .nm{color:var(--good)}
.ndash .rd-acc.a-warn .nm{color:#ebb14a}
.ndash .rd-acc.a-crit .nm{color:var(--crit)}
.ndash .rd-acts{display:flex;gap:9px;flex-wrap:wrap}
@media (max-width:900px){
  .ndash .rd-row{grid-template-columns:repeat(2,1fr)}
  .ndash .rd-panel-grid{grid-template-columns:1fr}
  /* Подпись дублирует то, что уже сказано точками и счётчиком, — жертвуем ею. */
  .ndash .rd-strip-s{display:none}
  .ndash .rd-dots{margin-right:auto}
}
@media (max-width:560px){
  .ndash .rd-strip{gap:10px;padding:13px 16px}
  .ndash .rd-strip-t{font-size:13px}
  /* Ничто в строке не сжимается, поэтому на узком экране сумма шире контейнера
     и шеврон выдавливается за край. Жертвуем счётчиком: «4 из 4» — ровно то,
     что уже сказано четырьмя зелёными точками рядом. */
  .ndash .rd-count{display:none}
  .ndash .rd-dots{margin-right:auto}
  /* Карточки не сжимаем в нечитаемые полоски — ряд уходит в скролл со снапом. */
  .ndash .rd-row{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none}
  .ndash .rd-row::-webkit-scrollbar{display:none}
  .ndash .rd-card{flex:0 0 72%;scroll-snap-align:start}
}

/* ============================================================
   Батч 10: защита от флуда в таблице аккаунтов + плашка отказа dropp
   ============================================================ */
.ndash td.acc-flood{ min-width:150px; }

/* Статус режима флуд-защиты в админке, вкладка «Аккаунты» (виден только админу).
   Это индикатор, а не объявление: одна строка, подробности — в title.
   Точка янтарная в наблюдении, зелёная в боевом. */
.flood-chip{
  display:inline-flex; gap:8px; align-items:baseline;
  margin:0 0 12px; font-size:12px; color:var(--text-2);
}
.flood-chip__dot{
  align-self:center; flex:none; width:6px; height:6px; border-radius:50%;
  background:#e0a93a;
}
.flood-chip--on .flood-chip__dot{ background:#2e9e5b; }
.flood-chip__txt b{ color:var(--text); font-weight:600; }
.flood-chip__btn{
  padding:0; border:0; background:none; cursor:pointer;
  font:inherit; color:var(--accent); text-decoration:underline;
  text-underline-offset:2px;
}
.flood-chip__btn:hover{ opacity:.8; }

/* Плашка-отказ в карточке (агентский ключ dropp). ВАЖНО: у .set-callout стоит
   display:flex, поэтому атрибут hidden сам по себе её НЕ прячет — гасим явно. */
.set-callout[hidden]{ display:none; }
.set-callout--err{
  background:color-mix(in srgb,#e06b6b 12%,transparent);
  border-color:color-mix(in srgb,#e06b6b 42%,transparent);
}
#page-settings .set-callout--err{
  background:color-mix(in srgb,#e06b6b 12%,transparent);
  border:1px solid color-mix(in srgb,#e06b6b 42%,transparent);
  color:var(--text);
}

/* ── Дашборд: верхний денежный блок ─────────────────────────────────────
   Деньги слева, существующий график дохода справа. Период переехал в шапку
   страницы: внутри карточки он управлял бы только ею. */
.ndash .screen-ctl{display:flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:flex-end}
.ndash .screen-row{flex-wrap:wrap}
.ndash .nacc{max-width:100%}
.ndash .vB{display:grid;grid-template-columns:minmax(290px,1fr) 1.8fr;background:var(--raise-1);
  border:1px solid var(--line-soft);border-radius:16px;overflow:hidden;margin-bottom:16px}
.ndash .vB-left{padding:20px 24px;background:linear-gradient(150deg,var(--accent-soft),transparent 65%)}
.ndash .vB-lbl{font-size:11px;text-transform:uppercase;letter-spacing:.13em;color:var(--text-3);font-weight:600}
.ndash .vB-val{margin-top:10px;font-size:40px;line-height:1;font-weight:750;letter-spacing:-.03em;
  color:var(--accent);text-shadow:0 0 36px var(--accent-glow);font-variant-numeric:tabular-nums;
  display:flex;align-items:baseline;gap:12px}
.ndash .vB-val .delta{font-size:14px;font-weight:650;text-shadow:none}
.ndash .vB-sub{margin-top:9px;font-size:12px;color:var(--text-2);font-variant-numeric:tabular-nums}
.ndash .vB-keys{margin-top:16px;padding-top:14px;border-top:1px solid var(--line-soft);
  display:grid;grid-template-columns:1fr 1fr;gap:11px 18px}
.ndash .vB-keys div{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  font-size:12px;color:var(--text-3)}
.ndash .vB-keys b{color:var(--text);font-size:15px;font-weight:650;font-variant-numeric:tabular-nums}
.ndash .vB-right{padding:8px 22px 14px;border-left:1px solid var(--line-soft);
  display:flex;flex-direction:column;min-width:0}
.ndash .vB-right .panel{background:none;border:0;padding:0;height:100%;display:flex;flex-direction:column}
.ndash .vB-right .big-num{display:none}   /* сумма уже стоит слева, второй раз не нужна */
.ndash .vB-right .chart svg{height:190px}
/* Заголовок правой половины — той же микро-подписью, что «ДОХОД ЗА ПЕРИОД» слева;
   пояснение про курс уходит вправо на ту же строку. Отступы обеих половин общие. */
.ndash .vB-right{padding:20px 24px 16px}
.ndash .vB-rlbl{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.ndash .vB-rlbl span{text-transform:none;letter-spacing:0;font-size:11.5px;color:var(--text-3);font-weight:400}
.ndash .vB-right .chart{margin-top:12px}
/* незакрытые сутки: обрыв линии вниз не должен читаться как падение дохода */
.ndash .ndot.today{background:var(--text-3);box-shadow:none}

/* ── Сетка нижней части: 8/4, 8/4, лента 12 ─────────────────────────────── */
.ndash .bento{display:grid;grid-template-columns:repeat(12,1fr);gap:16px;margin-bottom:22px}
.ndash .bento>*{min-width:0}
.ndash .b-12{grid-column:span 12} .ndash .b-8{grid-column:span 8} .ndash .b-4{grid-column:span 4}
.ndash .bento>*>.panel{height:100%;display:flex;flex-direction:column}
.ndash .bento>*>.panel>*{min-width:0}   /* min-width:auto у flex-детей распирал карточку */
.ndash .bento .panel{padding:18px 20px;border-radius:14px}
.ndash .bento .tbl-scroll{max-height:330px}
.ndash .col-quiet{display:flex;flex-direction:column;gap:16px}

/* ── Дашборд: нагрузка переписки ────────────────────────────────────────
   Хитмап 7×24 по локальному времени + полоса по дням. Сетка скроллится ВНУТРИ
   карточки: min-width:0 обязателен, иначе flex-ребёнок (min-width:auto) распирает
   страницу на телефоне. */
.ndash .hm{margin-top:16px;min-width:0;overflow-x:auto;overscroll-behavior-x:contain}
.ndash .hm-grid{display:grid;grid-template-columns:28px repeat(24,minmax(17px,1fr));gap:3px;min-width:560px}
.ndash .hm-h{font-size:10px;color:var(--text-3);text-align:center;font-variant-numeric:tabular-nums;padding-bottom:3px}
.ndash .hm-d{font-size:11px;color:var(--text-3);display:flex;align-items:center}
.ndash .hm-c{height:18px;border-radius:3px;background:var(--accent);opacity:var(--a);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.03);cursor:pointer;transition:box-shadow 120ms ease}
.ndash .hm-c.z{background:var(--raise-2);opacity:1}
@media (hover:hover) and (pointer:fine){
  .ndash .hm-c:hover{box-shadow:inset 0 0 0 1.5px var(--accent),0 0 0 2px var(--black)}
}
.ndash .hm-foot{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-top:14px;flex-wrap:wrap}
.ndash .hm-facts{display:flex;gap:20px;flex-wrap:wrap}
.ndash .hm-fact{font-size:12.5px;color:var(--text-2);font-variant-numeric:tabular-nums}
.ndash .hm-fact b{color:var(--text-3);font-weight:600;font-size:10.5px;text-transform:uppercase;
  letter-spacing:.07em;margin-right:7px}
.ndash .hm-leg{display:flex;align-items:center;gap:4px;font-size:10.5px;color:var(--text-3)}
.ndash .hm-leg i{width:12px;height:12px;border-radius:3px;background:var(--accent);opacity:var(--a);display:block}
.ndash .hm-leg i:first-of-type{margin-left:4px} .ndash .hm-leg i:last-of-type{margin-right:4px}
.ndash .ld-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  margin-top:auto;padding-top:16px;border-top:1px solid var(--line-soft);
  font-size:10.5px;text-transform:uppercase;letter-spacing:.07em;color:var(--text-3);font-weight:600}
.ndash .ld-head .sub{text-transform:none;letter-spacing:0;font-weight:400;font-size:11.5px}
.ndash .ld{display:flex;align-items:flex-end;gap:3px;height:44px;margin-top:10px}
.ndash .ld i{flex:1;min-width:2px;border-radius:2px 2px 0 0;cursor:pointer;
  background:linear-gradient(180deg,var(--accent),var(--accent-dim));opacity:.7;transition:opacity 120ms ease}
@media (hover:hover) and (pointer:fine){.ndash .ld i:hover{opacity:1}}
/* Полоса расхода энергии — тёплая: карточка вокруг синяя и рассказывает про
   людей, полоса рассказывает про потраченный ресурс. Тот же тон, что у капсулы
   ⚡ в карточке «Покупатель». */
.ndash .ld i.en{background:linear-gradient(180deg,#EBB14A,#8a6620)}

/* ── Дашборд: клиентская база ───────────────────────────────────────────── */
.ndash .cb{display:flex;flex-direction:column;flex:1;margin-top:6px}
.ndash .cb-row{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  padding:11px 0;border-bottom:1px solid var(--line-soft)}
.ndash .cb-row:last-child{border-bottom:none;padding-bottom:0}
.ndash .cb-l{font-size:12.5px;color:var(--text-2);min-width:0}
.ndash .cb-l small{display:block;font-size:11px;color:var(--text-3);margin-top:4px;line-height:1.4}
.ndash .cb-v{font-size:23px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums;
  flex:none;white-space:nowrap}
.ndash .cb-v small{font-size:13px;color:var(--text-3);font-weight:500;letter-spacing:0}
.ndash .cb-spark{display:flex;align-items:flex-end;gap:2px;height:34px;margin:2px 0 13px;
  padding-bottom:13px;border-bottom:1px solid var(--line-soft)}
.ndash .cb-spark i{flex:1;border-radius:1px;background:var(--accent);opacity:.42;
  position:relative;cursor:pointer;transition:opacity 120ms ease}
/* Цель наведения — вся колонка, а не сам столбик: у дня с одним лидом столбик
   ростом в пару пикселей, мышью в него не попасть. Высота = контентная высота
   полосы (34px минус её padding-bottom:13px), поэтому подложка никогда не
   вылезает вверх и не перехватывает наведение у числа над полосой. */
.ndash .cb-spark i::after{content:"";position:absolute;left:0;right:0;bottom:0;height:21px}
@media (hover:hover) and (pointer:fine){.ndash .cb-spark i:hover{opacity:1}}
.ndash .cb-note{margin-top:12px;font-size:11px;color:var(--text-3)}

/* ── Дашборд: приглушённые виджеты (смотрят редко) ──────────────────────── */
.ndash .quiet{background:transparent;border:1px solid var(--line-soft);border-radius:14px;padding:16px 18px;flex:1}
.ndash .quiet h3{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  margin:0 0 12px;font-size:12.5px;font-weight:600;color:var(--text-2)}
.ndash .quiet h3 span{font-size:11px;color:var(--text-3);font-weight:400}
.ndash .q-row{display:grid;grid-template-columns:14px minmax(0,1fr) 72px 54px;align-items:center;gap:10px;
  padding:6px 0;font-size:12.5px}
.ndash .q-n{color:var(--text-3);font-size:11px;font-variant-numeric:tabular-nums}
.ndash .q-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-2)}
/* Полоска была 3 px на 46 px — разницу между $1 994 и $1 129 в такой не увидеть.
   Шире и толще: либо она сравнивает клиентов, либо ей нечего тут делать. */
.ndash .q-bar{height:5px;border-radius:3px;background:var(--line);overflow:hidden}
.ndash .q-bar i{display:block;height:100%;background:var(--accent-dim)}
.ndash .q-val{text-align:right;font-variant-numeric:tabular-nums;color:var(--text)}
.ndash .q-split{display:flex;gap:2px;height:7px;border-radius:4px;overflow:hidden;background:var(--black);margin:2px 0 11px}
.ndash .q-split i{display:block;height:100%}
.ndash .q-split i.st{background:linear-gradient(90deg,#b4611f,#e0a952)}
.ndash .q-split i.fi{background:linear-gradient(90deg,var(--accent-dim),var(--accent))}
.ndash .q-leg{display:flex;flex-wrap:wrap;gap:6px 16px;font-size:12px;color:var(--text-2);font-variant-numeric:tabular-nums}
.ndash .q-leg span{display:flex;align-items:center;gap:6px}
.ndash .q-leg em{color:var(--text-3);font-style:normal;font-size:11px}
/* «Кто чем платит» — доли ЛЮДЕЙ под долями денег, отбиты линией: это ответ на
   другой вопрос, и мешать его с суммами в одну легенду нельзя. */
.ndash .q-sep{margin:14px 0 8px;padding-top:12px;border-top:1px solid var(--line-soft);
  font-size:10.5px;text-transform:uppercase;letter-spacing:.07em;color:var(--text-3);font-weight:600}
.ndash .q-prow{display:flex;align-items:center;gap:9px;padding:5px 0;font-size:12.5px;
  color:var(--text-2);font-variant-numeric:tabular-nums}
.ndash .q-prow .q-pl{flex:1;min-width:0}
.ndash .q-prow b{color:var(--text);font-weight:600}
.ndash .q-prow em{color:var(--text-3);font-style:normal;font-size:11px;min-width:30px;text-align:right}

/* ── Дашборд: полный список стран ─────────────────────────────────────────
   Семь треков: страна, полоса, клиентов(+доля), купили, конв., доход, ср. чек.
   Числовые колонки ужаты, а gap 16→12: две колонки денег иначе выдавливают
   название страны в многоточие уже на 1180 px. */
.ndash .aud-geo2-head,.ndash .aud-geo2-row{
  grid-template-columns:minmax(110px,1fr) minmax(40px,1.1fr) 68px 52px 50px 72px 64px;gap:12px}
/* Десять строк вместо шести: карточка стоит рядом с колонкой в две плитки, и на
   246 px под ней зияла пустота, а список стран из 176 строк выглядел глазком. */
.ndash .aud-geo2-scroll{max-height:430px;overflow-y:auto;scrollbar-width:thin;scrollbar-color:var(--line) transparent}
.ndash .aud-geo2-scroll::-webkit-scrollbar{width:6px}
.ndash .aud-geo2-scroll::-webkit-scrollbar-thumb{background:var(--line);border-radius:3px}
/* Фильтр карточки — сегментом в её шапке (тот же .seg, что период страницы). */
.ndash .geo-h{align-items:center}
.ndash .geo-h .sub{margin-right:auto}
.ndash .seg.geo-seg{flex:none;padding:2px}
.ndash .seg.geo-seg button{font-size:11.5px;padding:4px 11px}
.ndash .th-sort{position:relative;background:none;border:0;padding:0;font:inherit;font-size:10.5px;text-transform:uppercase;
  letter-spacing:.07em;color:var(--text-3);cursor:pointer;text-align:right;transition:color 120ms ease;
  white-space:nowrap;border-radius:4px}
/* Стрелка сортировки стоит ЗА правым краем заголовка, в зазоре между колонками.
   Внутри ячейки она съедала бы ширину и отжимала подпись влево от своих чисел,
   а если резервировать место всем заголовкам — уезжают сразу все. */
.ndash .th-sort i{position:absolute;right:-11px;top:0;font-style:normal}
@media (hover:hover) and (pointer:fine){.ndash .th-sort:hover{color:var(--text-2)}}
.ndash .th-sort.is-on{color:var(--accent)}
.ndash .th-sort:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.ndash .aud-geo2 .r.conv{color:var(--text-2);font-variant-numeric:tabular-nums}
.ndash .aud-geo2 .r.conv.hot{color:var(--good);font-weight:600}
/* Доход — тем же тоном, что фиат в KPI (.ndash .neon .fiat): деньги на дашборде
   уже зелёные, свой цвет заводить незачем. Средний чек рядом приглушён — он
   производная, а не сумма, и не должен спорить с доходом за внимание. */
.ndash .aud-geo2 .r.money{color:var(--good);font-weight:600}
.ndash .aud-geo2 .r.avg{color:var(--text-2)}
/* размер пака в ленте */
.ndash .pos-sub{color:var(--text-3);font-size:11.5px}

/* ── Дашборд: адаптив ───────────────────────────────────────────────────
   ≤1180 — пары «широкое + узкое» схлопываются, приглушённые виджеты встают в ряд.
   ≤900  — СВОЙ порядок блоков: деньги, что уже упало, нагрузка, люди, страны,
   редкое. Схлопывать десктопный порядок нельзя: на телефоне первым смотрят ленту. */
@media (max-width:1180px){
  .ndash .b-8{grid-column:span 12}
  .ndash .b-4{grid-column:span 6}
  /* Порядок обязателен: в DOM за узкой «базой» идёт широкое «Откуда пишут», оно
     не влезает в остаток строки и уезжает вниз, оставляя рядом с базой дыру.
     Ставим парой две узкие карточки: нагрузка → база + редкое → страны → лента. */
  .ndash .m-load{order:1} .ndash .m-base{order:2} .ndash .m-quiet{order:3}
  .ndash .m-geo{order:4} .ndash .m-feed{order:5}
}
@media (max-width:900px){
  .ndash .vB{grid-template-columns:1fr}
  .ndash .vB-left{padding:16px 16px}
  .ndash .vB-val{font-size:32px}
  .ndash .vB-right{border-left:0;border-top:1px solid var(--line-soft);padding:10px 16px 10px}
  .ndash .vB-right .chart svg{height:120px}
  .ndash .vB-keys{grid-template-columns:1fr 1fr}
  .ndash .bento{display:flex;flex-direction:column;gap:14px}
  .ndash .m-feed{order:1} .ndash .m-load{order:2} .ndash .m-base{order:3}
  .ndash .m-geo{order:4} .ndash .m-quiet{order:5}
  .ndash .col-quiet{flex-direction:column}
  /* Семь колонок в 430 px не живут → оставляем страну, клиентов, конверсию и ДОХОД.
     Спрятаны: полоса (2), «Купили» (4) и «Ср. чек» (7). «Купили» читается из конверсии,
     а из двух денежных колонок на телефоне нужнее сумма: средний чек смотрят,
     когда уже выбрали страну по доходу. Доля отдельной колонкой больше не идёт —
     она внутри ячейки «Клиентов» и уезжает на телефон вместе с ней.
     ГОЧА: скрытые ячейки убраны через display:none, а такой grid-элемент выпадает
     из сетки И НЕ ЗАНИМАЕТ ТРЕК. Список из шести треков с нулями поэтому съезжал:
     нули приземлялись не на те ячейки, «Клиентов» доставался трек 0px, и число
     вылезало наружу (замер на живом проде: ячейка w=0 при scrollWidth=36, левый
     край 195, а проценты начинались на 207 — цифры наезжали друг на друга).
     Треков должно быть ровно столько, сколько ВИДИМЫХ детей: страна, клиенты, конв., доход.
     Ширина числовых колонок — max-content, а не фикс: при 62px заголовок
     «КЛИЕНТОВ ↓» не влезал и сталкивал «КОНВ.» на вторую строку. */
  .ndash .aud-geo2-head,.ndash .aud-geo2-row{grid-template-columns:minmax(0,1fr) max-content max-content max-content;gap:10px}
  /* Вторая ячейка шапки — пустой span БЕЗ класса .bar, поэтому правило ниже её
     не убирало: в шапке оставалось четыре видимых ребёнка против трёх в строке,
     и «Конв.» переносился на вторую строку. Прячем её явно. */
  .ndash .aud-geo2-head>*:nth-child(2),
  .ndash .aud-geo2 .bar,
  .ndash .aud-geo2-head>*:nth-child(4),.ndash .aud-geo2-row>*:nth-child(4),
  .ndash .aud-geo2-head>*:nth-child(7),.ndash .aud-geo2-row>*:nth-child(7){display:none}
  .ndash .th-sort{font-size:10px;letter-spacing:.04em}
  .ndash .th-sort i{right:-9px}   /* зазор между колонками здесь 10 px, а не 16 */
  /* Сегмент фильтра в шапке карточки: на телефоне он уходит на свою строку целиком. */
  .ndash .geo-h .sub{margin-right:0}
  .ndash .seg.geo-seg{width:100%;justify-content:center}
  .ndash .cb-v{font-size:20px}
}

/* ── Селектор аккаунта на дашборде ─────────────────────────────────────────
   Метрики берём у прежнего контрола .ndash .nacc (радиус 9, фон --raise-1,
   13px, паддинги 8/12), а не у компонента страницы «Парсер»: на дашборде свой
   язык контролов, и поповер с чужими радиусами/высотами читался как инородный.
   Переиспользуется поведение и структура, а не оформление. */
.dash-acc-dd { position: relative; display: inline-block; }
.ndash .dash-acc-dd .parser-acc-trigger,
.dash-acc-dd .parser-acc-trigger {
  display: inline-flex; align-items: center; gap: 8px;
  min-width: 190px; max-width: 260px; height: auto;
  padding: 8px 12px;
  background: var(--raise-1); border: 1px solid var(--line); border-radius: 9px;
  color: var(--text); font-family: inherit; font-size: 13px; cursor: pointer;
  transition: border-color .15s var(--nease), background-color .15s var(--nease);
}
.ndash .dash-acc-dd .parser-acc-trigger:hover,
.dash-acc-dd .parser-acc-trigger:hover { background-color: var(--raise-2); border-color: var(--line); }
.dash-acc-dd .dash-acc-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-acc-dd .parser-acc-caret { width: 13px; height: 13px; margin-left: auto; opacity: .75; }

/* Поповер: тот же радиус и фон, что у карточек-контролов дашборда. Открывается
   влево — селектор стоит у правого края шапки. */
.ndash .dash-acc-dd .parser-acc-pop,
.dash-acc-dd .parser-acc-pop {
  position: absolute; top: calc(100% + 6px); left: auto; right: 0; z-index: 40;
  width: 288px; max-width: 88vw;
  padding: 8px; gap: 6px;
  background: var(--raise-1); border: 1px solid var(--line); border-radius: 11px;
  box-shadow: var(--shadow-pop);
  display: flex; flex-direction: column;
}
.dash-acc-dd .parser-acc-pop.hidden { display: none; }
.ndash .dash-acc-dd .parser-acc-search,
.dash-acc-dd .parser-acc-search {
  width: 100%; height: 32px; padding: 0 10px;
  background: var(--bg-input, var(--sheet)); border: 1px solid var(--line);
  border-radius: 8px; color: var(--text); font-family: inherit; font-size: 12.5px;
}
.dash-acc-dd .parser-acc-search:focus { outline: none; border-color: var(--accent-dim); }
.dash-acc-dd .parser-acc-list { max-height: 300px; overflow-y: auto; display: block; }
.dash-acc-dd .parser-acc-item {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 8px; border-radius: 8px; cursor: pointer;
}
.dash-acc-dd .parser-acc-item:hover { background: var(--raise-2); }
.dash-acc-dd .parser-acc-item.on { background: var(--green-dim); }
.dash-acc-dd .parser-acc-nm { font-size: 12.5px; font-weight: 600; color: var(--text); }
.dash-acc-dd .parser-acc-ph { font-size: 11px; color: var(--t3); }

/* Заголовок группы. Липкий: при прокрутке трёх десятков тёзок должно быть
   видно, к кому они относятся. В админском режиме это КЛИЕНТ и по нему можно
   кликнуть — тогда дашборд считает все его аккаунты сразу. */
.dash-acc-dd .acc-grp-h {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 8px 5px; margin-top: 2px;
  font-size: 10.5px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--t3); font-weight: 600;
  background: var(--raise-1); border-top: 1px solid var(--line);
}
.dash-acc-dd .acc-grp:first-child .acc-grp-h { border-top: 0; margin-top: 0; }
.dash-acc-dd .acc-grp-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-acc-dd .acc-grp-n { margin-left: auto; font-variant-numeric: tabular-nums; opacity: .8; }
.dash-acc-dd .acc-grp-h--pick { cursor: pointer; border-radius: 8px; }
.dash-acc-dd .acc-grp-h--pick:hover { color: var(--text); background: var(--raise-2); }
.dash-acc-dd .acc-grp-h--pick.on { color: var(--green); background: var(--green-dim); }

@media (max-width: 480px) {
  .dash-acc-dd, .dash-acc-dd .parser-acc-trigger { width: 100%; max-width: none; }
  .dash-acc-dd .parser-acc-pop { width: 100%; }
}

/* Расшифровка голосового под плеером — у обеих сторон треда. Отделена тонкой
   линией, как «оригинал» у переведённых сообщений: это вторичный текст, он не
   должен спорить с самим сообщением. */
.dlg-voice-tr {
  margin-top: 7px; padding-top: 7px;
  border-top: 1px solid var(--line);
  font-size: 13px; line-height: 1.4; color: var(--t1);
  white-space: pre-wrap; word-break: break-word;
}
.dlg-msg.out .dlg-voice-tr { border-top-color: rgba(255,255,255,.14); }
.dlg-voice-tr-none { color: var(--t3); font-size: 12px; font-style: italic; }
/* Оригинал расшифровки под переводом — раскрывается кликом, как у текстовых
   сообщений (dlgToggleOrigInline ищет .dlg-msg-orig, класс совпадает). */
.dlg-voice-orig { margin-top: 4px; }
.dlg-voice-tr[onclick] { cursor: pointer; }

/* ── Экран «Аккаунты» на телефоне ──────────────────────────────────────────
   Собрано за один заход, порядок правил = порядок разбора проблем.
   Позже в файле того же веса → перебивает блок ~7609. */

/* 1. Фильтры сверху: квадрат 2×2 → строка чипов.
      Эти четыре ячейки — не статистика, а ФИЛЬТРЫ (setAccountsFilter). Плитка с
      цифрой в 34px занимала четверть экрана, и до самих аккаунтов приходилось
      листать: замер 215px под блок, 341px до первой карточки. Стало 42 и 167. */
@media (max-width:600px){
  .ndash #acc-stats .neon-row{
    display:flex; gap:8px; background:none; border:0; border-radius:0;
    overflow-x:auto; scrollbar-width:none; padding-bottom:2px;
  }
  .ndash #acc-stats .neon-row::-webkit-scrollbar{ display:none; }
  .ndash #acc-stats .neon{
    display:flex; align-items:baseline; gap:7px; flex:none;
    padding:9px 14px; border-radius:999px;
    border:1px solid var(--line); background:var(--raise-1);
  }
  .ndash #acc-stats .neon .lbl{ font-size:13px; margin:0; color:var(--text-2); letter-spacing:0; }
  .ndash #acc-stats .neon .val{ font-size:14px; font-weight:650; line-height:1.2; }
  /* Приставка ёмкости («2 / 3») наследует .val small: 17px десктопных — крупнее
     самого числа (14px здесь). Не перекрытая в этом блоке, она читалась бы
     как главная цифра, а число как довесок. */
  .ndash #acc-stats .neon .val small{ font-size:11px; }
  /* Активный фильтр — голубой контрол-акцент --g, не бренд-фиолет. */
  .ndash #acc-stats .neon.on{ border-color:var(--g); background:rgba(42,171,238,.10); }
  .ndash #acc-stats .neon.on .lbl{ color:var(--text); }
  .ndash #acc-stats .neon.on .val{ color:var(--g); }
  .ndash #acc-stats .neon::after{ display:none; }

  /* Подсказка поиска обрывалась на «перс». Уменьшаем ТОЛЬКО ::placeholder —
     сам инпут остаётся 16px, поэтому iOS не вернёт зум при фокусе (он смотрит
     на размер поля, не подсказки). Обрыв смещается, но не исчезает: строка
     длиннее поля в принципе, добить можно только сократив её в JS. */
  .ndash .screen-actions .ninput--search::placeholder{ font-size:13.5px; }
}

/* 2. Карточка аккаунта: grid вместо flex-wrap.
      Строка была flex-wrap, поэтому чипы переносились по-разному в зависимости
      от длины текста: у одного аккаунта «Подключён» падал в отдельный ряд, у
      другого влезал в общий и вниз уезжали иконки — карточки «плясали».
      Здесь ячейка получает своё место и не может толкнуть соседей.
      Две колонки идут одной вертикалью от статусов до селектов. */
@media (max-width:860px){
  #page-accounts tbody tr{
    position:relative;
    display:grid;
    grid-template-columns:1fr 1fr;
    align-items:center;
    gap:10px;
    padding:14px 14px 14px 44px;
  }
  /* Чекбокс вне сетки: колонка «auto» под него ломала равные половины. */
  #page-accounts tbody td:nth-child(1){ position:absolute; left:14px; top:20px; }

  /* Ряд 1 — кто это и что с ним можно сделать. */
  #page-accounts tbody td:nth-child(2){ grid-column:1; grid-row:1; min-width:0; }
  #page-accounts tbody td:nth-child(9){ grid-column:2; grid-row:1; margin-left:0; justify-self:end; }

  /* Ряд 2 — состояния: жив ли аккаунт, жив ли бот. Родственные сигналы рядом. */
  #page-accounts tbody td:nth-child(4){ grid-column:1; grid-row:2; justify-self:start; }
  #page-accounts tbody td:nth-child(7){ grid-column:2; grid-row:2; justify-self:start; }

  /* Ряд 3 — подключение: как подключён и сколько диалогов. */
  #page-accounts tbody td:nth-child(6){ grid-column:1; grid-row:3; justify-self:start; min-width:0; }
  #page-accounts tbody td:nth-child(5){ grid-column:2; grid-row:3; justify-self:start; }

  /* Цветная плашка в карточке ровно одна — состояние аккаунта, и она же
     кликабельна. «Активен» и «Подключён» красились одинаковым зелёным и спорили
     за внимание, хотя означают разное. Разный вес здесь осмыслен: по плашке
     можно нажать, по тексту нет. */
  #page-accounts tbody td:nth-child(6) .pill,
  #page-accounts tbody td:nth-child(7) .pill{
    background:none !important; border:0 !important; padding:0 !important;
    color:var(--text-2) !important; font-size:12.5px; font-weight:500;
  }
  #page-accounts tbody td:nth-child(7) .pill.g::before{
    content:"● "; color:var(--good); font-size:10px;
  }
  #page-accounts tbody td:nth-child(5),
  #page-accounts tbody td:nth-child(6),
  #page-accounts tbody td:nth-child(7){
    min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  }

  /* Счётчик диалогов: голое «384» не отвечало, 384 чего. Иконка-пузырь в том же
     stroke-языке, что и действия рядом (24×24, stroke 2) — не эмодзи: набор
     _accIcon заведён именно взамен цветных глифов. Маска, а не content:url(),
     чтобы иконка наследовала currentColor. */
  #page-accounts tbody td:nth-child(5){
    display:flex; align-items:center; justify-content:flex-start; gap:6px;
    color:var(--text-2); font-size:12.5px; font-variant-numeric:tabular-nums;
  }
  #page-accounts tbody td:nth-child(5)::before{
    content:""; flex:none; width:14px; height:14px;
    background-color:currentColor; opacity:.75;
    -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 11.5a8.4 8.4 0 0 1-9 8.4 9.9 9.9 0 0 1-3.6-.7L3 21l1.9-5a8.2 8.2 0 0 1-.9-3.8 8.4 8.4 0 0 1 8.5-8.2h.5a8.4 8.4 0 0 1 8 8v.5z'/%3E%3C/svg%3E") no-repeat center/contain;
    mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 11.5a8.4 8.4 0 0 1-9 8.4 9.9 9.9 0 0 1-3.6-.7L3 21l1.9-5a8.2 8.2 0 0 1-.9-3.8 8.4 8.4 0 0 1 8.5-8.2h.5a8.4 8.4 0 0 1 8 8v.5z'/%3E%3C/svg%3E") no-repeat center/contain;
  }

  /* Ряд 4 — оба контрола рядом и подписаны. Без подписей селекты выглядели
     близнецами, и «Авто» не читался как защита от флуда. «Антифлуд» — тот же
     термин, что в шапке десктопной таблицы, только короче. */
  #page-accounts tbody td:nth-child(3){ grid-column:1; grid-row:4; min-width:0; }
  #page-accounts tbody td:nth-child(8){ grid-column:2; grid-row:4; min-width:0; }
  #page-accounts tbody td:nth-child(8).acc-flood{ min-width:0; }
  #page-accounts tbody td:nth-child(3) .nacc,
  #page-accounts tbody td:nth-child(8) .nacc{ width:100%; box-sizing:border-box; }
  #page-accounts tbody td:nth-child(3)::before,
  #page-accounts tbody td:nth-child(8)::before{
    display:block; margin:0 0 5px 2px;
    font-size:10.5px; letter-spacing:.08em; text-transform:uppercase;
    color:var(--text-3); font-weight:600; white-space:nowrap;
  }
  #page-accounts tbody td:nth-child(3)::before{ content:"Персонаж"; }
  #page-accounts tbody td:nth-child(8)::before{ content:"Антифлуд"; }

  /* Тап-цели: иконки действий были ~24px, ниже порога в 32. */
  #page-accounts .row-actions{ display:flex; gap:2px; }
  #page-accounts .row-actions .iconbtn{
    width:36px; height:36px; display:flex; align-items:center; justify-content:center;
  }
}

/* ── Окно пополнения энергии на телефоне ──────────────────────────────────
   Было: position:absolute; right:16px; min-width:300px и ни одного мобильного
   правила — на 390px окно висело узкой колонкой у правого края, слева мёртвая
   полоса. Растягиваем по ширине экрана с равными полями. */
.energy-buy-hint{text-align:center;font-size:11px;color:var(--text-3);margin-top:8px}
@media (max-width:600px){
  .energy-popover{
    left:12px; right:12px; min-width:0; width:auto;
    top:calc(var(--hdr-h,56px) + 6px);
    max-height:calc(100dvh - var(--hdr-h,56px) - 90px);
    padding:14px;
  }
  /* Единственное действие в окне — оно же главное, поэтому во всю ширину.
     .energy-buy-actions стоит на justify-content:space-between (рассчитано на
     два элемента), и одинокая кнопка прижималась влево. */
  .energy-buy-actions{ justify-content:stretch; }
  .energy-buy-actions .btn{ flex:1; width:100%; padding-top:11px; padding-bottom:11px; }
}

.dlg-catsel-save { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.dlg-catsel-warn { font-size: 11px; color: var(--t3); line-height: 1.35; }


/* ── Дожим неоплаченных счетов (админка) ──────────────────────────────────
   Все значения взяты из кита .ndash: панели/таблицы 16px, кнопки 10px,
   мелкие контролы 9px. Своих цветов не заводим — только токены темы. */
#page-admin .stage { border: 1px solid var(--line); border-radius: 14px; margin-bottom: 12px; overflow: hidden; background: var(--raise-1); }
#page-admin .stage-h { display: flex; align-items: center; gap: 12px; padding: 13px 16px; border-bottom: 1px solid var(--line-soft); flex-wrap: wrap; }
#page-admin .stage-idx { width: 26px; height: 26px; border-radius: 8px; background: var(--accent-soft); color: var(--accent); display: grid; place-items: center; font-size: 12px; font-weight: 700; flex: none; border: 1px solid rgba(42,171,238,.24); }
#page-admin .stage-name { font-size: 14px; font-weight: 600; }
#page-admin .stage-when { display: flex; align-items: center; gap: 8px; margin-left: auto; font-size: 12.5px; color: var(--text-3); }
#page-admin .stage-body { padding: 16px; }

/* Панель форматирования сидит НА текстарее: общая рамка читается как один
   контрол, поэтому у текстареи снизу свои радиусы и нет верхней границы. */
#page-admin .fmt { display: flex; align-items: center; gap: 2px; background: var(--raise-2); border: 1px solid var(--line); border-radius: 9px 9px 0 0; padding: 5px 6px; flex-wrap: wrap; }
#page-admin .fmt-b { min-width: 28px; height: 26px; padding: 0 6px; border-radius: 6px; display: grid; place-items: center; font-size: 12.5px; color: var(--text-2); border: 1px solid transparent; cursor: pointer; user-select: none; }
#page-admin .fmt-b:hover { background: var(--raise-1); border-color: var(--line); color: var(--text); }
#page-admin .fmt-b.bold { font-weight: 800; }
#page-admin .fmt-b.ital { font-style: italic; font-family: Georgia, serif; }
#page-admin .fmt-b.strike { text-decoration: line-through; }
#page-admin .fmt-b.mono { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; }
#page-admin .fmt-sep { width: 1px; height: 17px; background: var(--line); margin: 0 4px; }
#page-admin .fmt-count { margin-left: auto; font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums; padding-right: 4px; }
#page-admin .fmt-count.warn { color: var(--warn, #ebb14a); }
#page-admin .stage-body textarea.ninput { border-radius: 0 0 9px 9px; border-top: none; min-height: 86px; resize: vertical; line-height: 1.55; }

#page-admin .media-slot { display: flex; align-items: center; gap: 12px; border: 1px dashed var(--line); border-radius: 11px; padding: 11px 13px; margin-top: 12px; background: var(--black); }
#page-admin .media-thumb { width: 52px; height: 52px; border-radius: 9px; flex: none; background: var(--raise-2); display: grid; place-items: center; font-size: 17px; border: 1px solid var(--line); }
#page-admin .media-meta { flex: 1; min-width: 0; }
#page-admin .media-name { font-size: 13px; font-weight: 500; margin-bottom: 3px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#page-admin .media-sub { font-size: 11.5px; color: var(--text-3); }
#page-admin .media-empty { display: flex; align-items: center; justify-content: center; gap: 9px; border: 1px dashed var(--line); border-radius: 11px; padding: 16px; margin-top: 12px; font-size: 13px; color: var(--text-3); background: var(--black); }
#page-admin .media-empty:hover { border-color: var(--accent); color: var(--text-2); }

#page-admin .warnbox { border: 1px solid rgba(235,177,74,.3); background: rgba(235,177,74,.12); border-radius: 13px; padding: 14px 16px; display: flex; gap: 12px; align-items: flex-start; }
#page-admin .warnbox .ic { font-size: 15px; line-height: 1.3; flex: none; }
#page-admin .warnbox .tx { font-size: 13px; color: var(--text-2); line-height: 1.55; }
#page-admin .warnbox .tx b { color: var(--text); font-weight: 600; }

/* Карточки аудитории рассылки. Число крупное: админ выбирает по размеру. */
#page-admin .seg-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(214px, 1fr)); gap: 11px; }
#page-admin .seg-card { border: 1px solid var(--line); border-radius: 13px; padding: 14px; background: var(--raise-1); display: flex; flex-direction: column; gap: 5px; cursor: pointer; }
#page-admin .seg-card:hover { border-color: var(--text-3); }
#page-admin .seg-card.on { border-color: var(--accent); background: var(--accent-soft); }
#page-admin .seg-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
#page-admin .seg-n { font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
#page-admin .seg-name { font-size: 13px; font-weight: 600; }
#page-admin .seg-desc { font-size: 11.5px; color: var(--text-3); line-height: 1.45; }
#page-admin .radio { width: 16px; height: 16px; border-radius: 50%; border: 1px solid var(--line); flex: none; }
#page-admin .radio.on { border: 5px solid var(--accent); background: var(--black); }

/* Превью сообщения рядом с редактором: видно, что реально придёт человеку.
   Колонка фиксированная — пузырь не должен растягиваться на полэкрана. */
#page-admin .stage-body { display: grid; grid-template-columns: 1fr 300px; gap: 20px; }
@media (max-width: 900px) { #page-admin .stage-body { grid-template-columns: 1fr; } }
#page-admin .tg { background: #0e1621; border: 1px solid var(--line); border-radius: 14px; padding: 14px; display: flex; flex-direction: column; gap: 9px; }
#page-admin .tg-who { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--text-3); }
#page-admin .tg-ava { width: 19px; height: 19px; border-radius: 50%; background: var(--accent); color: #04121b; display: grid; place-items: center; font-size: 10px; font-weight: 700; flex: none; }
#page-admin .bubble { background: #212121; border-radius: 13px 13px 13px 4px; padding: 11px 13px; font-size: 13.5px; line-height: 1.5; color: #f0f0f0; white-space: pre-wrap; word-break: break-word; }
#page-admin .bubble.with-media { padding: 0; overflow: hidden; }
#page-admin .bubble .ph { height: 110px; background: var(--raise-2); display: grid; place-items: center; font-size: 20px; color: var(--text-3); }
#page-admin .bubble .cap { padding: 10px 13px 11px; }
#page-admin .tg-btn { background: #2b2b2b; border-radius: 9px; padding: 9px 12px; text-align: center; font-size: 13px; color: #6ab3f3; font-weight: 500; }

/* .row — горизонтальная группа контролов. В ките её не было, и два поля кнопки
   вставали друг под друга вместо ряда. */
#page-admin .row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
#page-admin .field { margin-bottom: 14px; }
#page-admin .fl { display: block; font-size: 12.5px; color: var(--text-2); margin-bottom: 6px; }
#page-admin .fh { font-size: 11.5px; color: var(--text-3); margin-top: 6px; line-height: 1.45; }
/* Заголовок таблицы: подпись слева, легенда справа, а не слипшимся текстом. */
#page-admin .table-wrap { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; background: var(--raise-1); }
#page-admin .table-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line-soft); }
#page-admin .table-head .t { font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); }

/* ── Рассылки: вертикальный ритм и переключатель разделов ─────────────────
   У .ndash .panel нет собственного отступа снизу — блоки шли вплотную и
   экран читался как одна сплошная простыня. */
#page-admin .panel,
#page-admin .neon-row,
#page-admin .warnbox,
#page-admin .stage { margin-bottom: 16px; }
#page-admin .panel:last-child { margin-bottom: 0; }
#page-admin .table-wrap { margin-top: 4px; }
#page-admin .panel-h { margin-bottom: 18px; }

/* Шапка раздела: переключатель слева, пояснение справа. */
#page-admin .mail-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 20px; }
#page-admin .mail-hint { font-size: 12.5px; color: var(--text-3); }
#page-admin .seg { display: inline-flex; background: var(--black); border: 1px solid var(--line); border-radius: 10px; padding: 3px; gap: 2px; }
#page-admin .seg-btn { border: none; background: transparent; color: var(--text-3); font-size: 13px; font-weight: 500; font-family: inherit;
  padding: 7px 14px; border-radius: 8px; cursor: pointer; transition: color 160ms ease, background-color 160ms ease; }
#page-admin .seg-btn.on { color: var(--text); background: var(--raise-2); }
#page-admin .seg-btn:hover:not(.on) { color: var(--text-2); }
#page-admin .seg-btn:active { transform: scale(0.97); }

/* Карточка аудитории — кликабельная, значит обязана отзываться на нажатие. */
#page-admin .seg-card { transition: border-color 160ms ease, background-color 160ms ease, transform 160ms cubic-bezier(.23,1,.32,1); }
#page-admin .seg-card:active { transform: scale(0.99); }

/* Ступень: заголовок и тело дышат, поля не липнут к краю. */
#page-admin .stage-h { padding: 14px 18px; }
#page-admin .stage-body { padding: 18px; }
#page-admin .stage:last-child { margin-bottom: 0; }
#page-admin .grouplbl { margin-bottom: 10px; }
#page-admin .media-slot, #page-admin .media-empty { transition: border-color 160ms ease, color 160ms ease; }

@media (prefers-reduced-motion: reduce) {
  #page-admin .seg-btn:active,
  #page-admin .seg-card:active { transform: none; }
}

/* ── Окно покупки слотов ────────────────────────────────────────────────────
   Живёт на общем .modal-overlay/.modal (mgrModal). Форма повторяет карточки
   монетизации: контролы на --sheet, рамка --line, радиус --r-ctl. */
.slot-modal__title{font-family:var(--ff-head);font-size:18px;font-weight:600;letter-spacing:-.014em;margin:0 0 7px}
.slot-modal__lead{font-size:13px;color:var(--t2);line-height:1.5;margin:0}
.slot-buyrow{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-top:18px;
  padding:12px 14px;border:1px solid var(--line);border-radius:var(--r-ctl);background:var(--sheet)}
.slot-qty{display:inline-flex;align-items:center;gap:2px}
.slot-qty__btn{width:30px;height:30px;border-radius:9px;border:1px solid var(--line);background:var(--mint);
  color:var(--t2);font-size:16px;line-height:1;cursor:pointer;display:grid;place-items:center;font-family:var(--ff-body)}
.slot-qty__btn:hover:not(:disabled){background:var(--ctl-h);color:var(--t1)}
.slot-qty__btn:disabled{opacity:.35;cursor:not-allowed}
.slot-qty__n{min-width:40px;text-align:center;font-family:var(--ff-num);font-size:16px;font-weight:600;
  color:var(--t1);font-variant-numeric:tabular-nums}
.slot-price{font-family:var(--ff-num);font-size:17px;font-weight:600;color:var(--t1);font-variant-numeric:tabular-nums}
.slot-price--short{color:var(--warn)}
.slot-modal__actions{display:flex;gap:10px;align-items:center;margin-top:18px}
/* CTA берёт форму .nbtn.primary с экрана аккаунтов, откуда окно и открывается:
   плоский акцент и ТЁМНЫЙ текст, а не градиент с белым. */
.slot-modal .slot-cta{flex:1;background:var(--accent);color:#04121b;font-weight:700;
  border:1px solid var(--accent);box-shadow:none}
.slot-modal .slot-cta:hover{filter:brightness(1.06);box-shadow:0 0 22px var(--accent-glow)}
.slot-modal__foot{margin-top:12px;font-size:12px;color:var(--t3);text-align:center;font-variant-numeric:tabular-nums}

/* Ячейка слотов в админ-таблице: та же форма, что у энергии (.en-cell),
   но без иконки — синий квадрат читался как галочка. */
.en-cell-input--slot{width:62px}
.slot-unit{font-size:12px;color:var(--text-3)}
.slot-hint{display:block;font-size:11px;color:var(--text-3);margin-top:5px}

/* ═══════════ ДОСКА ЗАДАЧ (админка, вкладка «Задачи») ═══════════
   Разметка построена в ui/task-board.js. Классы kb-* это доска и карточки,
   tm-* это модалка карточки, tag это метка. Сегмент приоритета переиспользует
   живые .pa-seg / .pa-seg-btn со вкладки «Страницы». */
.kb-wrap { overflow-x: auto; padding-bottom: 14px; margin: 0 -4px; }
.kb { display: flex; gap: 12px; align-items: flex-start; padding: 0 4px; min-height: 60vh; }
.kb-col { flex: 0 0 288px; background: var(--card); border: 1px solid var(--line);
          border-radius: var(--r-card); padding: 13px 11px 11px;
          transition: border-color 160ms ease, background 160ms ease; }
.kb-col.over { border-color: var(--g); background: #17171b; }

.kb-head { display: flex; align-items: center; gap: 8px; padding: 0 5px 11px; position: relative; }
.kb-dot  { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.kb-name { font-size: 12px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
           color: var(--t2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kb-count{ font-size: 11px; font-weight: 600; color: var(--t3); background: var(--mint);
           border-radius: 20px; padding: 2px 8px; }
.kb-menu-btn { margin-left: auto; background: none; border: none; color: var(--t3); cursor: pointer;
               font-size: 15px; line-height: 1; padding: 2px 5px; border-radius: 6px; opacity: 0;
               transition: opacity 120ms ease, background 120ms ease; }
.kb-col:hover .kb-menu-btn { opacity: 1; }
.kb-menu-btn:hover { background: var(--mint); color: var(--t1); }
.kb-name-input { flex: 1; min-width: 0; background: var(--mint); border: 1px solid var(--g);
                 border-radius: 8px; color: var(--t1); font-family: var(--ff-body); font-size: 12px;
                 font-weight: 700; text-transform: uppercase; letter-spacing: .09em; padding: 4px 7px; outline: none; }

.kb-menu { position: absolute; top: 26px; right: 0; z-index: 30; width: 186px; background: var(--mint);
           border: 1px solid var(--line); border-radius: 12px; padding: 6px; box-shadow: 0 14px 34px rgba(0,0,0,.55); }
.kb-menu-item { display: block; width: 100%; text-align: left; background: none; border: none; color: var(--t1);
                font-family: var(--ff-body); font-size: 13px; padding: 8px 9px; border-radius: 8px; cursor: pointer; }
.kb-menu-item:hover { background: #26262c; }
.kb-menu-item.danger { color: #e06b6b; }
.kb-swatches { display: flex; gap: 6px; padding: 8px 9px 6px; flex-wrap: wrap; }
.kb-sw { width: 18px; height: 18px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; }
.kb-sw.on { border-color: var(--t1); }
.kb-menu-sep { height: 1px; background: var(--line); margin: 5px 4px; }

.kb-card { background: var(--mint); border: 1px solid var(--line); border-radius: var(--r-ctl);
           padding: 11px 12px; margin-bottom: 8px; cursor: grab; position: relative;
           transition: transform 140ms ease, box-shadow 140ms ease, border-color 140ms ease, opacity 140ms ease; }
.kb-card:hover { border-color: #35353d; transform: translateY(-1px); box-shadow: 0 6px 18px rgba(0,0,0,.35); }
.kb-card.dragging { opacity: .3; }
.kb-title { font-size: 13.5px; line-height: 1.42; color: var(--t1); font-weight: 500; word-wrap: break-word; }
.kb-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.tag { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600;
       padding: 3px 8px; border-radius: 20px; line-height: 1.3; white-space: nowrap; }
.tag i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.kb-foot { display: flex; align-items: center; gap: 11px; margin-top: 9px; font-size: 11px; color: var(--t3); }
.prio { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 600; }
.prio.high { color: #e06b6b; } .prio.mid { color: #f0a63a; } .prio.low { color: #6c6c72; }
.kb-badge { display: inline-flex; align-items: center; gap: 4px; }
.kb-badge svg { width: 13px; height: 13px; fill: none; stroke: currentColor; stroke-width: 1.8;
                stroke-linecap: round; stroke-linejoin: round; }
.kb-thumb-strip { display: flex; gap: 4px; margin-top: 9px; }
.kb-thumb-strip img, .kb-thumb-strip .kb-vid { width: 100%; height: 54px; object-fit: cover; border-radius: 8px; }
.kb-vid { background: #000; display: grid; place-items: center; color: var(--t2); font-size: 16px; }

.kb-add { width: 100%; text-align: left; background: none; border: 1px dashed #2a2a30; border-radius: var(--r-ctl);
          color: var(--t3); font-family: var(--ff-body); font-size: 13px; padding: 9px 12px; cursor: pointer;
          transition: color 120ms ease, border-color 120ms ease, background 120ms ease; }
.kb-add:hover { color: var(--t1); border-color: var(--g); background: rgba(42,171,238,.05); }
.kb-new { width: 100%; background: var(--mint); border: 1px solid var(--g); border-radius: var(--r-ctl);
          color: var(--t1); font-family: var(--ff-body); font-size: 13.5px; line-height: 1.42;
          padding: 11px 12px; resize: none; outline: none; }
.kb-hint { font-size: 11px; color: var(--t3); padding: 6px 4px 0; }
.kb-addcol { flex: 0 0 210px; background: none; border: 1px dashed #2a2a30; border-radius: var(--r-card);
             color: var(--t3); font-family: var(--ff-body); font-size: 13px; padding: 15px; cursor: pointer;
             transition: color 120ms ease, border-color 120ms ease; }
.kb-addcol:hover { color: var(--t1); border-color: var(--g); }

.tm-back { position: fixed; inset: 0; background: rgba(0,0,0,.66); backdrop-filter: blur(3px);
           z-index: 100; display: grid; place-items: center; padding: 28px; }
.tm { width: min(720px, 100%); max-height: 88vh; overflow-y: auto; background: var(--card);
      border: 1px solid var(--line); border-radius: var(--r-sheet); padding: 26px 28px 24px; position: relative; }
.tm-top { display: flex; align-items: flex-start; gap: 14px; }
.tm-title { flex: 1; background: none; border: 1px solid transparent; border-radius: 10px; color: var(--t1);
            font-family: var(--ff-body); font-size: 20px; font-weight: 600; line-height: 1.3;
            padding: 6px 8px; margin: -6px -8px; resize: none; outline: none; }
.tm-title:hover { border-color: var(--line); }
.tm-title:focus { border-color: var(--g); background: var(--mint); }
.tm-x { background: none; border: none; color: var(--t3); font-size: 22px; line-height: 1; cursor: pointer;
        padding: 2px 6px; border-radius: 8px; }
.tm-x:hover { background: var(--mint); color: var(--t1); }
.tm-sub { display: flex; align-items: center; gap: 10px; margin: 15px 0 22px; font-size: 12px; color: var(--t3); }
.tm-sel { background: var(--mint); border: 1px solid var(--line); border-radius: 9px; color: var(--t1);
          font-family: var(--ff-body); font-size: 12px; padding: 6px 9px; outline: none; cursor: pointer; }
.tm-lbl { font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--t3); margin: 0 0 9px; }
.tm-sec { margin-bottom: 24px; }
.tm-row { display: flex; gap: 34px; flex-wrap: wrap; }
.tm-desc { width: 100%; background: var(--mint); border: 1px solid var(--line); border-radius: 12px; color: var(--t1);
           font-family: var(--ff-body); font-size: 14px; line-height: 1.55; padding: 12px 13px;
           resize: vertical; min-height: 84px; outline: none; }
.tm-desc:focus { border-color: var(--g); }

.tm-tags { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; position: relative; }
.tag-add { border: 1px dashed #35353d; background: none; color: var(--t3); font-family: var(--ff-body);
           font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 20px; cursor: pointer; }
.tag-add:hover { color: var(--t1); border-color: var(--g); }
.tag-pop { position: absolute; top: 30px; left: 0; z-index: 40; width: 250px; background: var(--mint);
           border: 1px solid var(--line); border-radius: 14px; padding: 9px; box-shadow: 0 16px 38px rgba(0,0,0,.6); }
.tag-opt { display: flex; align-items: center; gap: 9px; padding: 7px 8px; border-radius: 9px; cursor: pointer; }
.tag-opt:hover { background: #26262c; }
.tag-opt .chk { margin-left: auto; color: var(--g); font-size: 13px; }
.tag-new { width: 100%; background: var(--card); border: 1px solid var(--line); border-radius: 9px; color: var(--t1);
           font-family: var(--ff-body); font-size: 12.5px; padding: 8px 9px; outline: none; margin-top: 4px; }
.tag-new:focus { border-color: var(--g); }

/* Правый край строки метки: галочка «висит на карточке» и вход в правку.
   Держим их одной группой, иначе margin-left:auto у галочки и у кнопки
   поделили бы свободное место между собой и кнопка уехала бы от края. */
.tag-opt-side { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; flex: none; }
.tag-opt-side .chk { margin-left: 0; }
.tag-edit-btn { background: none; border: none; color: var(--t3); cursor: pointer; font-size: 12px;
                line-height: 1; padding: 3px 5px; border-radius: 6px; opacity: 0;
                transition: opacity 120ms ease, background 120ms ease, color 120ms ease; }
.tag-opt:hover .tag-edit-btn { opacity: 1; }
.tag-edit-btn:hover { background: var(--card); color: var(--t1); }

/* Метка в режиме правки: имя, палитра, снос — на месте своей строки. */
.tag-edit { padding: 7px 8px; border-radius: 9px; background: #26262c; }
.tag-edit .tag-new { margin-top: 0; }
.tag-edit .kb-swatches { padding: 9px 0 4px; }
.tag-edit .kb-menu-item { padding: 6px 0; font-size: 12.5px; }

/* Подвал модалки: разрушительное действие за чертой, отдельно от правки полей. */
.tm-foot { display: flex; justify-content: flex-end; padding-top: 16px; margin-top: 6px;
           border-top: 1px solid var(--line); }

/* Переход перечислен по свойствам, а в макете тут стоит transition: all.
   Расхождение намеренное: «all» разрешает браузеру анимировать что угодно, в
   том числе то, что меняться не должно, и в этой таблице стилей он запрещён
   (tests/dashboard-ui-blocks.test.js). Меняются ровно три величины. */
.tm-drop { border: 1px dashed #2a2a30; border-radius: 12px; padding: 14px; text-align: center; color: var(--t3);
           font-size: 12.5px; cursor: pointer;
           transition: border-color 140ms ease, color 140ms ease, background 140ms ease; }
.tm-drop:hover, .tm-drop.over { border-color: var(--g); color: var(--t1); background: rgba(42,171,238,.05); }
.tm-files { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 9px; margin-bottom: 10px; }
.tm-file { position: relative; border-radius: 11px; overflow: hidden; border: 1px solid var(--line); background: #000; }
.tm-file img, .tm-file video { width: 100%; height: 88px; object-fit: cover; display: block; }
.tm-file-x { position: absolute; top: 5px; right: 5px; width: 22px; height: 22px; border: none; border-radius: 7px;
             background: rgba(0,0,0,.62); color: #fff; cursor: pointer; font-size: 14px; line-height: 1; }
.tm-file-x:hover { background: rgba(224,107,107,.9); }

.tm-cmt { display: flex; gap: 10px; padding: 11px 0; border-bottom: 1px solid var(--line); }
.tm-cmt:last-of-type { border-bottom: none; }
.tm-cmt-av { width: 26px; height: 26px; flex: none; border-radius: 50%; background: var(--g);
             display: grid; place-items: center; color: #fff; font-size: 11px; font-weight: 700; }
.tm-cmt-when { font-size: 11px; color: var(--t3); margin-bottom: 3px; }
.tm-cmt-txt { font-size: 13.5px; line-height: 1.5; color: var(--t1); white-space: pre-wrap; }
.tm-cmt-new { width: 100%; background: var(--mint); border: 1px solid var(--line); border-radius: 12px; color: var(--t1);
              font-family: var(--ff-body); font-size: 13.5px; line-height: 1.5; padding: 11px 12px;
              resize: none; outline: none; margin-top: 8px; }
.tm-cmt-new:focus { border-color: var(--g); }

/* ═══════════ КОНЕЦ ДОСКИ ЗАДАЧ ═══════════
   Маркер конца, а не украшение: tests/task-board-ui-mirror.test.js берёт
   отпечаток секции от её заголовка ДО ЭТОЙ СТРОКИ. Без него секция считалась бы
   до конца файла, и любой чужой блок, дописанный в конец (домашний приём),
   менял бы отпечаток и красил тест доски чужой правкой. Новые разделы пиши
   НИЖЕ этой строки. */

/* ── Заработок менеджеров: страница «Менеджеры» ──────────────────────────────
   Перенос утверждённого макета ui/preview-payouts.html. Классы там названы pv-*
   (preview), здесь earn-* — смысл тот же, префикс говорит о фиче, а не о черновике. */

/* Панель фильтров под шапкой страницы. */
.earn-bar { display:flex; flex-wrap:wrap; align-items:center; gap:10px; margin:0 0 14px; }
.earn-bar .form-input { width:136px; }
.earn-flabel { font-size:12px; color:var(--t3); }

/* Сумма заработка прямо в строке списка слева: главное число видно, не открывая карточку. */
#page-managers .mgr-ch .earn-sum { margin-left:auto; font-size:12.5px; font-weight:600;
    color:var(--accent); font-variant-numeric:tabular-nums; }
#page-managers .mgr-ch .earn-sum + .dlg-dot { margin-left:8px; }
#page-managers .mgr-ch.earn-all { margin-bottom:8px; }
#page-managers .mgr-ch .cav { background:rgba(42,171,238,.10); color:var(--accent); }
#page-managers .mgr-ch.earn-all .cav { background:rgba(42,171,238,.14); color:var(--g); }

/* Плитки сводки. Все одинаковые: заголовок и число, без подписей — разное число строк
   ломало ряд, а флекс растягивал короткие по самой высокой и давал воздух. */
.earn-tiles { display:flex; gap:10px; flex-wrap:wrap; margin-bottom:16px; }
.earn-tile { flex:1 1 124px; background:var(--card); border:1px solid var(--line);
    border-radius:var(--r-card); padding:13px 15px; }
/* Канон подписи в системе: 11px / 600 / капс / --text-3. Так сделаны .grouplbl и .vB-lbl. */
.ndash .earn-tile-l { font-size:11px; font-weight:600; letter-spacing:.13em; text-transform:uppercase;
    color:var(--text-3); margin-bottom:8px; }
.ndash .earn-tile-v { font-size:22px; font-weight:700; letter-spacing:-.02em; color:var(--text);
    font-variant-numeric:tabular-nums; line-height:1.1; }
/* Голубая заливка с рамкой в системе значит «выбрано» (.pay-rcard.on, .mgr-ch.sel,
   .seg button.on). Плитка ничего не выбирает, поэтому подложки у неё НЕТ: важность
   несёт только цвет самой цифры, иначе плитка читается как активная вкладка. */
.ndash .earn-tile.is-key .earn-tile-v { color:var(--accent); }
.ndash .earn-tile.is-neg .earn-tile-v { color:var(--crit); }

/* Цвет по смыслу, а не для красоты:
     голубой = человек и его заработок (то, ради чего страницу открыли),
     красный = возврат, деньги ушли обратно,
     белый   = доход, нейтральная величина.
   Зелёный освобождён: на именах он значил «хорошо», хотя не значил ничего. */
.ndash .earn-who { color:var(--accent); background:var(--accent-soft); }
.ndash td .earn-amount, #page-managers .detail td .earn-amount { color:var(--accent); font-weight:600; }
/* Ставка мелкой строкой под заработком: она объясняет цифру, но не спорит с ней. */
.ndash .earn-sub { display:block; font-size:11.5px; font-weight:400; letter-spacing:0;
    color:var(--text-3); font-variant-numeric:tabular-nums; }


/* Ставка это отдельный орган, но на ОДНО число: строка, а не карточка в пять строк
   ради одного поля. В шапку карточки её тоже нельзя — шапка это идентификация, и поле
   ввода рядом с именем читается как правка имени. */
.earn-rate-row { display:flex; align-items:center; gap:9px; flex-wrap:wrap;
    background:var(--card); border:1px solid var(--line); border-radius:var(--r-card);
    padding:10px 14px; }
/* .form-input в системе width:100%. Без явной ширины он распирает строку, и ряд
   ломается на четыре. */
.earn-rate-row .form-input { width:72px; flex:none; text-align:center; padding:7px 8px; }
.earn-rate-lbl { font-size:11px; font-weight:600; letter-spacing:.1em; text-transform:uppercase;
    color:var(--text-3); }
.earn-rate-pct { color:var(--text-2); font-size:13.5px; }
.earn-rate-note { margin-left:auto; font-size:12px; color:var(--text-3); }

/* Пять плиток одним рядом (карточка менеджера). Кегль числа и подписи следует за
   шириной ряда: на панели 600px «$6 480.00» и «ПРЕДЛОЖЕНО» в 22px/11px вылезали из
   плитки (скрин владельца 07.09), а ряд 3+2 он отверг. Контейнер это сам ряд. */
.earn-tiles.five { container-type: inline-size; }
.earn-tiles.five .earn-tile { flex:1 1 0; min-width:0; padding:11px 10px; }
.ndash .earn-tiles.five .earn-tile-l { font-size: clamp(9px, 1.7cqw, 11px); letter-spacing:.1em; white-space:nowrap; }
.ndash .earn-tiles.five .earn-tile-v { font-size: clamp(15px, 3.1cqw, 22px); white-space: nowrap; }
/* Уже 480px (телефон) пять в ряд не живут: по две, обычным кеглем. */
@container (max-width: 480px) {
  .earn-tiles.five .earn-tile { flex:1 1 45%; }
  .ndash .earn-tiles.five .earn-tile-l { font-size:11px; letter-spacing:.13em; }
  .ndash .earn-tiles.five .earn-tile-v { font-size:22px; }
}
/* Панель графика в панели менеджеров: ритм задаёт gap контейнера. */
#page-managers .detail .panel { margin:0; }
/* Метка «до 24.08» второй строкой под именем, под аватаром (24px + 8px). */
.ndash td .earn-under { margin:3px 0 0 32px; }

/* Ритм панели задаёт флекс на КОНТЕЙНЕРЕ, а не margin-ы поверх продуктовых
   компонентов: !important на .grouplbl или .table-wrap сломал бы их на всех остальных
   экранах кабинета. 16px между группами, 8px между заголовком и его содержимым. */
#page-managers .detail { display:flex; flex-direction:column; gap:16px; }
#page-managers .detail > .grouplbl { margin:0; }
#page-managers .detail > .grouplbl + * { margin-top:-8px; }
#page-managers .detail > .table-wrap { margin:0; }
#page-managers .detail > .earn-tiles { margin:0; }
#page-managers .detail .mgr-detail-hd { margin-bottom:0; }

/* Плотный вариант таблицы: полная ширина страницы и панель мастер-детали (~700px) это
   разные поверхности, продуктовые ячейки по 24px там не влезают — шесть колонок уезжают
   за край и сводка живёт в горизонтальной прокрутке. 8px, а не 10: с колонками
   «Предложено» и «Конверсия» их шесть. */
#page-managers .detail thead th,
#page-managers .detail tbody td { padding-left:8px; padding-right:8px; }
#page-managers .detail .table-head { padding-left:10px; padding-right:10px; }
#page-managers .detail .badge-ic { width:24px; height:24px; font-size:11px; }
#page-managers .detail .coin { gap:8px; }

/* ── Консоль менеджера: экран «Продажи» ──────────────────────────────────────
   Консоль одноэкранная не случайно: showPage отбивает всё, кроме диалогов, шапка и
   таб-бар погашены наглухо, освободившаяся высота отдана чатам. Поэтому «Продажи» не
   новая страница, а экран внутри диалогов — на широком он встаёт вместо треда, на
   телефоне занимает всё. */

/* Ряд шапки списка: поиск плюс пилюля входа. Шапка это КОЛОНКА (поиск, под ним чипы
   фильтров), поэтому пилюля кладётся в ряд С ПОИСКОМ, а не рядом с самой шапкой. */
.earn-hdrow { display:flex; align-items:center; gap:8px; }
.earn-hdrow .dlg-search { flex:1 1 auto; min-width:0; width:auto; }

/* Пилюля называет то, что за ней, и заодно показывает главное число, не заставляя
   открывать экран. Голая иконка «$» отвергнута как ребус. */
.earn-money-btn { flex:none; display:flex; align-items:center; gap:5px; height:36px; padding:0 11px;
    border-radius:10px; border:1px solid rgba(42,171,238,.32); background:rgba(42,171,238,.10);
    color:var(--accent); font-size:13.5px; font-weight:700; font-variant-numeric:tabular-nums;
    white-space:nowrap; cursor:pointer; }
.earn-money-btn .earn-chev { opacity:.65; font-weight:400; }

.earn-screen { display:none; flex:1 1 auto; min-width:0; overflow-y:auto; padding:14px 16px; }
#page-dialogs .dlg-wrap.m-sales .dlg-conv { display:none !important; }
#page-dialogs .dlg-wrap.m-sales .earn-screen { display:block; }

/* Шапка экрана повторяет шапку треда: кнопка-кружок «назад» первым ребёнком, следом
   название. Подписи у кнопки нет — в продукте текст «Чаты» из неё убран осознанно. */
.earn-scr-hd { display:flex; align-items:center; gap:10px; padding:0 0 12px; }
.earn-scr-back { width:34px; height:34px; flex:none; border-radius:50%; background:var(--mint);
    border:1px solid var(--line); color:var(--t1); display:flex; align-items:center;
    justify-content:center; cursor:pointer; }
.earn-scr-back:active { transform:scale(.92); }
.earn-scr-t { font-size:15px; font-weight:600; color:var(--t1); }
/* Пять кнопок периода в 360px не помещаются: сегмент едет горизонтально, как чипы
   фильтров в списке чатов. */
.earn-screen .seg { overflow-x:auto; scrollbar-width:none; margin-bottom:14px; }
.earn-screen .seg::-webkit-scrollbar { display:none; }

/* Строка продажи в ДВА яруса: шесть колонок в 336px не живут. Сверху что и кому плюс
   сумма, снизу когда, чем оплачено и сколько причитается. */
.earn-srows { display:flex; flex-direction:column; }
.earn-srow { display:flex; flex-direction:column; gap:3px; padding:9px 12px;
    border-top:1px solid var(--line-soft); }
.earn-srow:first-child { border-top:0; }
.earn-srow-t, .earn-srow-b { display:flex; align-items:baseline; gap:8px; }
.earn-srow-pos { font-size:13px; color:var(--text); white-space:nowrap; overflow:hidden;
    text-overflow:ellipsis; }
.earn-srow-sum { margin-left:auto; font-size:13.5px; font-weight:600; color:var(--text);
    font-variant-numeric:tabular-nums; white-space:nowrap; }
.earn-srow-meta { font-size:11.5px; color:var(--text-3); font-variant-numeric:tabular-nums; }
.earn-srow-earn { margin-left:auto; font-size:12.5px; font-weight:600; color:var(--accent);
    font-variant-numeric:tabular-nums; }

/* Телефон. Список чатов прячется так же, как при открытом треде: экран один.
   Кнопка «назад» на широком экране не нужна — там список остаётся слева. */
@media (max-width: 768px) {
  #page-dialogs .dlg-wrap.m-sales .dlg-list { display:none !important; }
  #page-dialogs .dlg-wrap.m-sales .earn-screen { position:absolute; inset:0; z-index:3;
      background:var(--card); display:block; }
}
@media (min-width: 769px) { .earn-scr-back { display:none; } }

/* Метка «Beta» у пункта меню. Отдельный класс, а не .nav-badge: тот зелёный и несёт
   ЧИСЛО (непрочитанные, аккаунты), и метка в его виде читалась бы как счётчик. Здесь
   нужен приглушённый ярлык — он говорит «раздел новый», а не «тут что-то случилось». */
.nav-beta { margin-left:auto; font-size:9.5px; font-weight:700; letter-spacing:.09em;
    text-transform:uppercase; color:var(--t3); }
/* Выбранный пункт светлеет (background:rgba(255,255,255,.07), текст белый), поэтому
   тёмная заливка и тёмный текст на нём тонут — метка читалась как дыра. Никакой
   подложки у неё и нет: чип соревновался бы со счётчиками соседних пунктов, а метка
   всего лишь помечает. На выбранном она просто чуть светлеет вместе с пунктом. */
.nav-item.active .nav-beta { color:var(--t2); }
/* Зелёная точка активного пункта стоит справа, ровно там же, где метка. Правило
   гашения знало только про счётчики — метку надо было в него дописать, иначе точка
   ложится поверх букв. */
.nav-item.active:has(.nav-beta)::after { display:none; }
/* Гасим метку ТОЛЬКО в нижней панели вкладок: там пункт это иконка с подписью в
   10px, и ярлыку рядом места нет. В шторке «Ещё» метка обязана остаться — на телефоне
   «Менеджеры» живут именно там, и общее правило по ширине убирало её насовсем. */
#mtabbar .nav-beta { display:none; }

/* Подпись в рядах менеджеров. Отдельный класс, а не .cell-sub: тот определён ТОЛЬКО
   внутри .ndash (style.css: `.ndash .cell-sub`), а модалка «Новый менеджер» живёт вне
   этой области — текст оставался без стилей вовсе и выводился обычным абзацем рядом
   с чипом. Та же ловушка области видимости, что и у токенов цвета. */
.mgr-hint { font-size: 12px; color: var(--t3); align-self: center; }

/* Блок денег в карточке менеджера. Ритм панели задан gap на #page-managers .detail, а
   он действует ТОЛЬКО на её прямых детей: обёртка блока их спрятала, и ставка, плитки
   и таблица склеились впритык. Повторяем тот же ритм внутри обёртки, а не возвращаем
   margin-ы на продуктовые компоненты — они бы поехали на остальных экранах. */
#page-managers .detail > #mgr-earn-block {
  display: flex; flex-direction: column; gap: 16px;
}
#page-managers .detail > #mgr-earn-block > .earn-tiles { margin: 0; }
#page-managers .detail > #mgr-earn-block > .table-wrap { margin: 0; }

/* Плашка «комплект неполный» над таблицей аккаунтов (тексты 30.08). */
.ndash .kit-warnbar{margin:0 0 12px;background:var(--crit-dim);border:1px solid rgba(224,107,107,.28);
  border-radius:10px;padding:10px 14px;color:var(--crit);font-size:13px;font-weight:600}

/* Комплект неполный в «Диалогах» (30.08): ава гаснет с точкой, заглушка вместо чатов */
.dlg-rail .av.kit-dim{opacity:.38;position:relative}
.dlg-rail .av .kit-dot{position:absolute;right:-3px;top:-3px;width:10px;height:10px;border-radius:50%;
  background:var(--crit,#e06b6b);border:2px solid var(--bg,#0a0a0c)}
#page-dialogs .dlg-empty.kit-stub{max-width:36ch;margin:auto;line-height:1.6}
/* Заглушка «бот отключён от чата» (не аккаунтная, у неё текст длиннее): общий
   max-width:36ch на .kit-stub жал её в пять-шесть строк на широком экране.
   Свой класс поверх .kit-stub — трогать общий нельзя, на нём висит и
   аккаунтная заглушка комплекта. width% + max-width — тот же приём, что у
   .modal, а не голая фикс-ширина: на узком экране блок всё равно ужимается
   вместе с колонкой, горизонтальной прокрутки нет. */
#page-dialogs .dlg-empty.chatoff-stub{width:92%;max-width:74ch}
/* «Диалоги» живут вне скоупа .ndash, и .nbtn там разваливается в системную
   кнопку — дублируем продуктовый вид локально для кнопки заглушки. */
#page-dialogs .kit-stub .nbtn{display:inline-flex;align-items:center;justify-content:center;height:32px;
  padding:0 13px;border-radius:9px;border:1px solid var(--accent,#2aabee);background:var(--accent,#2aabee);
  color:#04121b;font:inherit;font-size:12.5px;font-weight:700;line-height:1;cursor:pointer}

/* Строка чата, от которого отключён бот. Тот же приём, что у аватарки аккаунта
   без комплекта в рейле: гасим, но НЕ прячем. Внезапная пропажа строки уже
   путала владельцев (решение 30.08). */
.dlg-ch.chatoff .cav,
.dlg-ch.chatoff .cn,
.dlg-ch.chatoff .cp { opacity: .42; }
.dlg-ch.chatoff.sel .cav,
.dlg-ch.chatoff.sel .cn,
.dlg-ch.chatoff.sel .cp { opacity: .7; }
.dlg-dot--chatoff { background: var(--bad); }

/* ── Сегменты «Темп продаж» (редактор персонажа, вкладка «Цель») ─────────── */
.tempo-seg { display: flex; gap: 6px; margin: 2px 0 8px; }
.tempo-seg__btn {
  flex: 1; padding: 9px 0; border-radius: 9px;
  border: 1px solid var(--border); background: var(--bg-input);
  color: var(--text-2); font-size: 14px; font-weight: 600; cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.tempo-seg__btn:hover { background: var(--bg-hover); }
.tempo-seg__btn.on {
  background: var(--accent); border-color: var(--accent);
  color: #08131a; box-shadow: 0 0 14px var(--accent-glow);
}

/* ── Касса: виджет оплаты USDT (ui/pay-widget.js, ui/pay.html, #modal-pay) ────
   Разметка и классы из утверждённого макета 04.09, цвета переведены на токены
   приложения (--bg-sidebar/--bg-card/--border/--text…/--g/--ok/--warn). Все
   правила под .pay: .chip/.field/.dot/.cp/.btn уже заняты в приложении другими
   компонентами, без префикса они бы перебили друг друга. Тема только тёмная. */
/* Токены кассы: --bad уже объявлен в общем :root наверху файла, здесь только
   мягкий фон под красную плашку .warn.bad (решение владельца 05.09: жёлтая
   «ровно сумма» и красная «комиссия биржи» — теперь одна красная плашка). */
:root{ --bad-soft:rgba(224,83,59,.12); }
.pay{background:var(--bg-sidebar);border:1px solid rgba(255,255,255,.09);border-radius:var(--r-card);padding:26px 26px 22px;width:100%;max-width:420px;box-shadow:0 24px 60px rgba(0,0,0,.55);display:flex;flex-direction:column;gap:16px;color:var(--text);font:14px/1.5 var(--ff-body);text-align:left}
.pay-top{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
.pay-title{font:700 18px/1.2 var(--ff-head);letter-spacing:-.01em;margin:0;color:var(--text)}
.pay-sub{color:var(--text-2);font-size:12.5px;margin-top:3px}
.pay-x{width:30px;height:30px;border-radius:9px;border:1px solid var(--border);background:transparent;color:var(--text-3);font-size:16px;line-height:1;cursor:pointer;flex:none}
.pay-x:hover{color:var(--text);background:var(--bg-hover)}
.pay-price{display:flex;align-items:baseline;gap:8px}
.pay-price .n{font:600 30px/1 var(--ff-num);font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.pay-price .u{font:600 14px/1 var(--ff-body);color:var(--text-2)}
.pay-price .fiat{margin-left:auto;color:var(--text-3);font-size:12.5px}

.pay .nets{display:flex;flex-direction:column;gap:6px}
.pay .net{display:flex;align-items:center;gap:12px;padding:11px 13px;border-radius:var(--r-ctl);border:1px solid var(--border);background:var(--bg-card);cursor:pointer;text-align:left;color:var(--text);width:100%;font:inherit;transition:border-color 120ms,background 120ms}
.pay .net:hover{background:var(--bg-hover);border-color:rgba(255,255,255,.14)}
.pay .net.on{border-color:var(--g);box-shadow:0 0 0 1px var(--g) inset;background:rgba(42,171,238,.08)}
.pay .net:focus-visible{outline:2px solid var(--g);outline-offset:2px}
.pay .net-name{font-weight:600;font-size:13.5px}
.pay .net-tag{font-size:11.5px;color:var(--text-3);margin-left:6px;font-family:'SF Mono',Menlo,Consolas,monospace;white-space:nowrap}
.pay .net-fee{margin-left:auto;font-size:11.5px;color:var(--text-3);text-align:right;max-width:38%} /* подсказка комиссии переносится, тег сети (USDT TRC20) нет: на 390px иначе тег рвался на две строки */
.pay .net-fee.hi{color:var(--warn)}

/* Монета USDT с бейджем сети: платим всегда в USDT, сеть — только маршрут,
   поэтому кружок один на все сети, а сеть подписана логотипом в углу монеты.
   Рамка и фон бейджа цветом карточки: монета лежит и на .net, и на .chip, у
   обоих фон --bg-card, поэтому бейдж выглядит вырезанным из монеты. Цвет
   несёт сам логотип сети; шрифт и цвет буквы — запас для сети без логотипа. */
.pay .coin{position:relative;width:32px;height:32px;flex:none}
.pay .coin svg{width:32px;height:32px;display:block}
.pay .coin .badge{position:absolute;right:-5px;bottom:-5px;width:19px;height:19px;border-radius:50%;border:2px solid var(--bg-card);background:var(--bg-card);display:grid;place-items:center;overflow:hidden;font:700 9px/1 var(--ff-body);color:#0b0b0d}
.pay .chip .coin{width:22px;height:22px}
.pay .chip .coin svg{width:22px;height:22px}
.pay .chip .coin .badge{width:14px;height:14px;border-width:1.5px;right:-3px;bottom:-3px;font-size:7px}
/* Логотип сети на весь бейдж. Правило стоит ПОСЛЕ размера монеты в чипе:
   специфичность у них одинаковая (0,3,1), побеждает последнее. */
.pay .coin .badge svg{width:100%;height:100%;display:block}

/* Окно оплаты энергии (renderEnergyCheckout): объём и цена крупно по центру,
   ползунок объёма тот же, что в поповере шапки (.price-slider), метки скидок
   под ним, ссылка промокода внизу. */
.pay .amt{display:flex;flex-direction:column;align-items:center;gap:6px;padding:6px 0 2px}
.pay .amt .e{font:700 34px/1 var(--ff-head);color:var(--text);letter-spacing:-.01em}
.pay .amt .p{display:flex;align-items:center;gap:8px;font:500 17px/1 var(--ff-num);color:var(--text-2)}
.pay .amt .disc{font:600 12px/1 var(--ff-body);color:var(--ok);background:rgba(34,197,94,.10);border:1px solid rgba(34,197,94,.25);border-radius:20px;padding:5px 9px}
.pay .slider{padding:4px 2px 0}
.pay .slider .ticks{position:relative;height:16px;margin-top:8px;font:500 11px/1 var(--ff-body);color:var(--text-3)}
.pay .slider .ticks span{position:absolute;top:0;transform:translateX(-50%)}
.pay .slider .ends{display:flex;justify-content:space-between;font:500 11.5px/1 var(--ff-body);color:var(--text-3);margin-top:2px}
.pay .pay-link{background:none;border:0;color:var(--text-2);font:500 13px/1 var(--ff-body);cursor:pointer;padding:6px;align-self:center}
.pay .pay-link:hover{color:var(--text)}

.pay .chip{display:inline-flex;align-items:center;gap:8px;padding:6px 10px 6px 6px;border-radius:20px;background:var(--bg-card);border:1px solid var(--border);font-size:12.5px;color:var(--text-2);width:max-content}
.pay .chip b{color:var(--text);font-weight:600}
.pay .chip button{border:0;background:transparent;color:var(--g);font:inherit;font-size:12px;cursor:pointer;padding:0 2px 0 6px;border-left:1px solid var(--border)}

.pay .field{display:flex;flex-direction:column;gap:6px}
.pay .field-l{font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--text-3);font-weight:600}
.pay .copyrow{display:flex;align-items:center;gap:8px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--r-ctl);padding:10px 8px 10px 13px}
.pay .copyrow code{font:12.5px/1.4 'SF Mono',Menlo,Consolas,monospace;color:var(--text);word-break:break-all;flex:1;min-width:0}
.pay .copyrow .big{font:600 22px/1 var(--ff-num);font-variant-numeric:tabular-nums;letter-spacing:-.01em;flex:1}
.pay .copyrow .big small{font:600 12px/1 var(--ff-body);color:var(--text-2);margin-left:6px}
.pay .cp{flex:none;border:1px solid var(--border);background:var(--bg-hover);color:var(--text-2);border-radius:9px;padding:7px 10px;font:inherit;font-size:12px;font-weight:600;cursor:pointer;transition:background 120ms,color 120ms}
.pay .cp:hover{color:var(--text);background:#202026}
.pay .cp.done{color:var(--ok);border-color:rgba(34,197,94,.35)}

.pay .qr-wrap{display:flex;gap:16px;align-items:stretch}
.pay .qr{width:132px;height:132px;flex:none;background:#fff;border-radius:14px;padding:8px;display:grid;place-items:center;overflow:hidden}
.pay .qr canvas{width:116px!important;height:116px!important;display:block}
.pay .qr-side{display:flex;flex-direction:column;gap:10px;flex:1;min-width:0}

/* Полоска ошибки опроса НАД уже показанным экраном: моргнувшая сеть не стирает
   адрес и сумму из-под пальцев клиента, экран остаётся под полоской. */
.pay .err-bar{background:rgba(224,83,59,.12);border:1px solid var(--bad);color:var(--warn);border-radius:var(--r-ctl);padding:9px 12px;font-size:12.5px;line-height:1.4}
.pay .warn{display:flex;gap:10px;align-items:flex-start;background:rgba(235,177,74,.12);border:1px solid rgba(235,177,74,.28);color:#f1d8a0;border-radius:12px;padding:10px 12px;font-size:12.5px;line-height:1.45}
.pay .warn b{color:#ffe1a6;font-weight:600}
.pay .warn .i{flex:none;width:18px;height:18px;border-radius:50%;background:var(--warn);color:#1a1400;display:grid;place-items:center;font:700 12px/1 var(--ff-body);margin-top:1px}
/* Красная плашка (комиссия биржи + «ровно сумма»): поверх базового .warn по цвету,
   структуру (flex/padding/radius) наследует от .pay .warn выше. */
.pay .warn.bad{background:var(--bad-soft);border-color:rgba(224,83,59,.32);color:#f4c4ba}
.pay .warn.bad b{color:#ffd9d0}
.pay .warn.bad .i{background:var(--bad);color:#fff}

.pay .status{display:flex;align-items:center;gap:10px;padding:11px 13px;border-radius:var(--r-ctl);background:var(--bg-card);border:1px solid var(--border);font-size:13px}
.pay .dot{width:8px;height:8px;border-radius:50%;background:var(--warn);flex:none;position:relative}
.pay .dot.pulse::after{content:"";position:absolute;inset:-5px;border-radius:50%;border:2px solid var(--warn);opacity:.6;animation:pay-pulse 1.6s ease-out infinite}
.pay .dot.ok{background:var(--ok)}.pay .dot.bad{background:#E0533B}.pay .dot.g{background:var(--g)}
.pay .dot.g.pulse::after{border:2px solid var(--g)} /* полный shorthand: одна лишь border-color в Safari иногда не перекрывает border из .dot.pulse::after */
@keyframes pay-pulse{from{transform:scale(.5);opacity:.7}to{transform:scale(1.5);opacity:0}}
@media (prefers-reduced-motion: reduce){.pay .dot.pulse::after{animation:none}}
.pay .status .t{flex:1;min-width:0}
.pay .status .t small{display:block;color:var(--text-3);font-size:11.5px;margin-top:1px}
.pay .status .pay-timer{font:600 13px/1 var(--ff-num);font-variant-numeric:tabular-nums;color:var(--text-2)}

.pay .prog{height:6px;border-radius:6px;background:var(--bg-hover);overflow:hidden}
.pay .prog i{display:block;height:100%;background:var(--g);border-radius:6px}

.pay .btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;padding:11px 18px;border-radius:var(--r-ctl);font-size:13.5px;font-weight:600;cursor:pointer;border:none;width:100%;letter-spacing:-.1px;text-decoration:none;font-family:inherit;transition:transform 120ms,background 120ms}
.pay .btn-primary{background:var(--g);color:#111;box-shadow:0 4px 14px rgba(42,171,238,.20)}
.pay .btn-primary:hover{transform:translateY(-1px)}
.pay .btn-ghost{background:rgba(255,255,255,.05);color:var(--text-2);border:1px solid var(--border);width:100%}
.pay .btn-ghost:hover{background:rgba(255,255,255,.09);color:var(--text)}
.pay .btn:focus-visible{outline:2px solid var(--g);outline-offset:2px}
.pay .btn:disabled{opacity:.35;cursor:not-allowed;transform:none}
.pay-foot{font-size:12px;color:var(--text-3);text-align:center;line-height:1.45}

.pay .done-ico{width:56px;height:56px;border-radius:50%;background:rgba(34,197,94,.10);border:1px solid rgba(34,197,94,.35);display:grid;place-items:center;margin:4px auto 0}
.pay .done-ico svg{width:26px;height:26px}
.pay.centered{text-align:center}
.pay.centered .pay-title{font-size:20px}
.pay .kv{display:grid;grid-template-columns:1fr auto;gap:8px 16px;font-size:13px;padding:12px 14px;background:var(--bg-card);border:1px solid var(--border);border-radius:var(--r-ctl)}
.pay .kv span{color:var(--text-2)}.pay .kv b{font-weight:600;font-variant-numeric:tabular-nums;text-align:right}
.pay .kv b.ok{color:var(--ok)}.pay .kv b.warn{color:var(--warn)}
.pay .kv a{color:var(--g);text-decoration:none}

/* Модалка в приложении: .modal-box только позиционирует, рамка и фон у .pay. */
#modal-pay .modal-box{padding:0;background:transparent;border:0;box-shadow:none;gap:0;width:min(420px,92%);max-width:420px;overflow:visible}
#modal-pay .pay{width:100%;max-width:none}

/* Голая страница /pay/<id> для покупателя из бота: фон, знак Podium, виджет, подпись.
   Класс .pay-brand, а не .mark: .mark уже занят маркером графика (см. правило
   выше в этом файле), без префикса .pay-page они пересеклись бы. */
body.pay-page{margin:0;min-height:100dvh;background:var(--bg);color:var(--text);font:14px/1.5 var(--ff-body)}
.pay-page .bare{min-height:100dvh;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;padding:36px 20px}
.pay-page .pay{box-shadow:none}
.pay-page .fine{font-size:12px;color:var(--text-3);text-align:center;max-width:36ch}
/* Голая страница на телефоне: карточка во весь экран, без отступов и скруглений (владелец 05.09) */
@media (max-width:520px){
  .pay-page .bare{padding:0;justify-content:flex-start;gap:0}
  .pay-page .pay{max-width:none;min-height:100dvh;border:0;border-radius:0;padding:max(22px,env(safe-area-inset-top)) 18px max(28px,env(safe-area-inset-bottom))}
}

@media (max-width:520px){
  .pay{padding:20px 18px}
  .pay .qr-wrap{flex-direction:column}
  .pay .qr{width:100%;height:auto;aspect-ratio:1;max-width:200px;margin:0 auto}
}

/* Кнопка «Открыть бота» в модалке привязки Telegram кабинета (#modal-tg-bind).
   Парные правила для ленда переехали в landing.css, а эта половина осталась здесь:
   у неё своя палитра (--ac), переменные ленда вне .lnd не существуют. */
#modal-tg-bind .btn-tg-open{display:flex;align-items:center;justify-content:center;gap:9px;height:46px;
  border-radius:12px;background:#2AABEE;color:#04121b;font-weight:600;font-size:15px;text-decoration:none;
  box-shadow:0 0 20px rgba(42,171,238,.25);transition:filter .15s,box-shadow .25s,transform .1s}
#modal-tg-bind .btn-tg-open.hidden{display:none}
#modal-tg-bind .btn-tg-open:active{transform:scale(.97)}
#modal-tg-bind .btn-tg-ic{width:18px;height:18px}

/* Таймер флуд-паузы в пилюле статуса: цифры табличные, иначе строка дёргается
   на каждом тике (12:47 → 12:46 меняет ширину на пропорциональных цифрах). */
.ndash .pill .fp-t{font-variant-numeric:tabular-nums}
