:root{
  --bg:#0c0a0b; --surface:#171214; --surface-2:#1f181a; --surface-3:#271e21;
  --ghost-hover:#31262a;
  --border:#2e2226; --text:#f5f2f3; --muted:#a39196;
  --red:#e5484d; --red-2:#f26a6e; --red-soft:rgba(229,72,77,.14);
  --red-deep-a:#b21f27; --red-deep-b:#7c1119;
  /* Глубокий зелёный для карточки рефералов. Прежний светлый --green давал
     белому тексту контраст 2.53 — сумма на карточке не читалась. */
  --green-deep-a:#227046; --green-deep-b:#124d31;
  --green:#3fb871; --green-soft:rgba(63,184,113,.14);
  --amber:#e0a458; --amber-soft:rgba(224,164,88,.16); --danger:#f26a6e;
  /* Пауза и предупреждение о раздаче раньше красились одним янтарным. Для человека
     это разные вещи: паузу он поставил сам, предупреждение — претензия к нему. */
  --pause:#8ea3c4; --pause-soft:rgba(142,163,196,.16);
  /* Акцент для текста и ссылок. В тёмной теме светлый красный читается отлично
     (контраст 6.2), в светлой — всего 2.97 при норме 4.5, поэтому там он свой. */
  --accent:#f26a6e;
  /* Кнопка: белым по #e5484d выходит 3.91 — ниже нормы. Тёмная заливка даёт 5.3. */
  --btn-primary:#c8323a; --btn-primary-hover:#e5484d;

  /* Шкала кеглей. Раньше их было 12 штук между .72 и .95rem — разницу между .84 и
     .85 не видит никто, а ощущение неаккуратности она создаёт. */
  --fs-xs:.78rem; --fs-sm:.86rem; --fs-md:1rem; --fs-lg:1.15rem; --fs-xl:1.9rem;

  /* Скругления. Объявлено было два, а в коде жило шесть — четыре мимо переменных. */
  --r:16px; --r-sm:11px; --r-xs:9px; --r-pill:999px;

  --shadow:0 18px 50px -20px rgba(0,0,0,.75);
  /* Заголовки и цифры. Веб-шрифт не тянем: у системных есть отдельные «дисплейные»
     начертания, они плотнее и с более узкими просветами, чем текстовые. */
  --font-display:"SF Pro Display","Segoe UI Variable Display",-apple-system,
    BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;
}
*{box-sizing:border-box}
html,body{margin:0;height:100%}
body{
  background:var(--bg); color:var(--text);
  font:15px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI","Inter",Roboto,sans-serif;
  -webkit-font-smoothing:antialiased;
}
button{font:inherit;cursor:pointer;color:inherit;border:0;background:none}
h1{font:700 var(--fs-xl)/1.15 var(--font-display);letter-spacing:-.025em;margin:0 0 18px}
h2{font:650 var(--fs-lg)/1.3 var(--font-display);letter-spacing:-.015em;margin:0}
/* Цифры выравниваем по разрядам: в столбцах баланса и трафика прыгающая ширина
   знаков мешает сравнивать значения глазами. */
.balance-card-value,.stat-value,.side-balance,.urow-bal{font-variant-numeric:tabular-nums}
[hidden]{display:none !important}
.muted{color:var(--muted)}
/* Классы шкалы. Нужны, чтобы кегль задавался ссылкой на шкалу, а не числом в
   разметке: раньше в index.html и app.js жили 53 инлайновых размера десяти разных
   значений, и экраны неизбежно расходились между собой. */
.t-xs{font-size:var(--fs-xs)}
.t-sm{font-size:var(--fs-sm)}
.t-md{font-size:var(--fs-md)}
.t-lg{font-size:var(--fs-lg)}

/* ---------- Buttons ---------- */
.btn{padding:11px 18px;border-radius:var(--r-sm);font-weight:600;font-size:var(--fs-md);
  transition:transform .08s ease,background .15s ease,box-shadow .15s ease;
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  position:relative;min-height:44px}
.btn:active{transform:translateY(1px)}
.btn--primary{background:var(--btn-primary);color:#fff;box-shadow:0 8px 24px -8px var(--red)}
.btn--primary:hover{background:var(--btn-primary-hover)}
.btn--block{width:100%}
/* Theme-aware "glass" (home balance card is graphite in dark, light in light). */
.btn--glass{background:color-mix(in srgb,var(--text) 10%,transparent);color:var(--text);
  border:1px solid var(--border);backdrop-filter:blur(6px)}
.btn--glass:hover{background:color-mix(in srgb,var(--text) 18%,transparent)}
.btn--danger{background:var(--surface-3);color:var(--accent)}
.btn--danger:hover{background:rgba(229,72,77,.18)}
/* Единственная кнопка в карточке клиента, ведущая к живому человеку. Остальные
   меняют настройки, поэтому она выделена цветом и стоит первой. */
.btn--amber{background:var(--amber-soft);color:var(--amber);
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--amber) 35%,transparent);font-weight:700}
.btn--amber:hover{background:color-mix(in srgb,var(--amber) 26%,transparent)}
.btn--ghost{background:var(--surface-3);color:var(--text)}
/* Цвет наведения был вбит намертво тёмным (#31262a) — в светлой теме кнопка под
   курсором чернела. Токен: в тёмной теме наведение осветляет, в светлой затемняет. */
.btn--ghost:hover{background:var(--ghost-hover)}

/* Видимый фокус клавиатуры. Раньше на весь кабинет было пять правил :focus — идущий
   табом человек почти не видел, где находится. :focus-visible не мешает мыши: рамка
   появляется только при навигации с клавиатуры. */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:2px solid var(--accent);outline-offset:2px;border-radius:var(--r-xs)}
/* Маленькая кнопка остаётся маленькой НА ВИД, но нажимается по 44 px: невидимая
   зона выходит за границы. Иначе на телефоне промахиваешься мимо каждой второй. */
.btn--sm{padding:7px 12px;font-size:var(--fs-sm);border-radius:var(--r-xs);min-height:32px}
.btn--sm::after{content:"";position:absolute;left:0;right:0;top:50%;
  height:44px;transform:translateY(-50%)}
.link{color:var(--accent);font-weight:600;font-size:var(--fs-sm)}
.link:hover{text-decoration:underline}

/* ---------- Auth ---------- */
/* iOS-PWA: index.html объявляет viewport-fit=cover и полупрозрачную статус-строку,
   поэтому содержимое рисуется ПОД часами и «чёлкой». Везде, где что-то прижато к
   краю экрана, добавляем системный отступ env(safe-area-inset-*). Фолбэк 0px нужен
   браузерам без поддержки: без него всё правило отбрасывается целиком. */
.auth{min-height:100%;display:grid;place-items:center;padding:24px;
  padding-top:calc(24px + env(safe-area-inset-top,0px));
  padding-bottom:calc(24px + env(safe-area-inset-bottom,0px));
  background:radial-gradient(1200px 600px at 50% -10%,rgba(229,72,77,.18),transparent 60%)}
.auth-card{width:100%;max-width:392px;background:var(--surface);
  border:1px solid var(--border);border-radius:22px;padding:34px 28px;box-shadow:var(--shadow)}
.brand{display:flex;align-items:center;gap:12px}
.brand--lg{flex-direction:column;text-align:center;gap:6px;margin-bottom:26px}
.brand-logo{width:52px;height:52px;border-radius:15px;display:grid;place-items:center;
  font-size:22px;color:#fff;background:linear-gradient(145deg,var(--red),var(--red-deep-a));
  box-shadow:0 10px 30px -8px var(--red)}
.brand--lg .brand-logo{width:60px;height:60px;font-size:26px}
.brand-name{font-weight:700;font-size:var(--fs-lg);letter-spacing:-.01em}
.brand--lg .brand-name{font-size:1.7rem;margin-top:6px}
.brand-sub{color:var(--muted);font-size:var(--fs-sm)}
.tabs{display:flex;gap:4px;background:var(--surface-2);border-radius:var(--r-sm);padding:4px;margin-bottom:20px}
.tab{flex:1;padding:11px;border-radius:var(--r-xs);font-weight:600;color:var(--muted);min-height:44px}
.tab.is-active{background:var(--red);color:#fff}
.form{display:flex;flex-direction:column;gap:14px}
.field{display:flex;flex-direction:column;gap:7px;font-size:var(--fs-sm);color:var(--muted)}
.field input{background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r-sm);
  padding:12px 14px;color:var(--text);font-size:var(--fs-md);transition:border .15s}
.field input:focus{outline:none;border-color:var(--red)}
.error{color:var(--accent);font-size:var(--fs-sm);margin:0}

/* ---------- Layout ---------- */
.layout{display:grid;grid-template-columns:250px 1fr;min-height:100%}
.sidebar{background:var(--surface);border-right:1px solid var(--border);
  padding:22px 16px;display:flex;flex-direction:column;gap:26px;position:sticky;top:0;height:100vh;
  /* На невысоких экранах меню вместе с нижним блоком перестаёт влезать, и нижний
     просто обрезается краем окна. Прокрутка — чтобы до него можно было дойти. */
  overflow-y:auto}
.nav{display:flex;flex-direction:column;gap:4px}
/* Подпись группы меню: разрядка вместо размера — так она читается как ориентир,
   а не спорит за внимание с самими пунктами. */
.nav-group{margin:14px 0 2px 13px;font-size:var(--fs-xs);font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;color:var(--muted);opacity:.75}
.nav-item{display:flex;align-items:center;gap:12px;padding:11px 13px;border-radius:var(--r-sm);
  color:var(--muted);font-weight:600;font-size:var(--fs-md);text-align:left;transition:.12s}
.nav-item:hover{background:var(--surface-2);color:var(--text)}
.nav-item.is-active{background:var(--red-soft);color:var(--accent)}
.nav-ico{width:20px;text-align:center;font-size:1.05rem}
/* Счётчик непрочитанных новостей: прижат к правому краю пункта меню. */
.nav-badge{margin-left:auto;min-width:20px;height:20px;padding:0 6px;border-radius:var(--r-pill);
  background:var(--red);color:#fff;font-size:var(--fs-xs);font-weight:700;
  display:inline-flex;align-items:center;justify-content:center}
.news-post{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  padding:16px 18px;margin-bottom:12px}
.news-post h3{margin:0 0 4px;font-size:var(--fs-lg)}
.news-post .news-meta{color:var(--muted);font-size:var(--fs-xs);margin-bottom:10px}
.news-post .news-body{white-space:pre-wrap;line-height:1.6}
.side-foot{margin-top:auto}
.side-user{display:flex;align-items:center;gap:11px;padding:10px;
  border-radius:14px;background:var(--surface-2)}
.avatar{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;
  font-weight:700;color:#fff;background:linear-gradient(145deg,var(--red),var(--red-deep-a))}
.side-user-meta{min-width:0}
.side-email{font-size:var(--fs-sm);font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:150px}
.side-balance{font-size:var(--fs-xs);color:var(--green);font-weight:600}
/* Ссылка на другие проекты автора. Кнопка — но тихая: она не должна спорить с
   навигацией, ради которой человек сюда пришёл. */
.side-more{margin-top:10px;width:100%;min-height:38px;padding:9px 11px;gap:9px;
  font-size:var(--fs-xs);font-weight:600;line-height:1.3;
  /* Значок слева и текст по левому краю — как у пунктов меню выше. По центру
     двухстрочная подпись без значка выглядела обрывком, а не пунктом. */
  justify-content:flex-start;text-align:left;
  color:var(--muted);text-decoration:none}
.side-more:hover{color:var(--text)}
.side-more-ico{font-size:1.05rem;line-height:1;flex:none;opacity:.85}
.side-more-txt{flex:1}
.side-more-out{flex:none;opacity:.6;font-size:.9em}
.main{padding:38px 40px;max-width:960px;width:100%}

/* ---------- Home ---------- */
.hello{color:var(--muted);margin:0}
.hello-name{font-size:2rem;font-weight:700;margin:2px 0 22px;letter-spacing:-.02em}
/* Карточка баланса — единственный «герой» кабинета, и у каждой темы он свой:
   графит в тёмной, тёплый серый в светлой. Раньше светлая собиралась из тех же
   слоёв, что и тёмная — серый градиент, чёрная тень и красное пятно поверх, — и на
   светлом фоне это давало муть с размытой кляксой справа.
   Насыщенный красный занят действиями и тревогой, поэтому фон здесь нейтральный:
   красная карточка читалась бы как «у вас проблема». */
.balance-card{position:relative;overflow:hidden;border-radius:22px;padding:26px 28px;margin-bottom:20px;
  background:linear-gradient(140deg,#2b2023 0%,#191316 55%,#140f11 100%);
  border:1px solid #33262a;
  box-shadow:0 24px 50px -30px rgba(20,8,12,.65), inset 0 0 0 1px rgba(242,106,110,.16)}
/* Свечение мягче и меньше прежнего: раньше это было заметное пятно, теперь подсветка
   угла, которую замечаешь, только если искать. */
.balance-card::after{content:"";position:absolute;right:-70px;top:-90px;width:260px;height:260px;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(229,72,77,.30),rgba(229,72,77,.08) 45%,transparent 72%)}
/* В ТЁМНОЙ теме на графите текст светлый. */
:root:not([data-theme="light"]) .balance-card:not(.balance-card--flat):not(.balance-card--on-dark) .balance-card-label{color:rgba(255,255,255,.72)}
:root:not([data-theme="light"]) .balance-card:not(.balance-card--flat):not(.balance-card--on-dark) .balance-card-value{color:#fff}
:root:not([data-theme="light"]) .balance-card:not(.balance-card--flat):not(.balance-card--on-dark) .btn--glass{background:rgba(255,255,255,.13);
  color:#fff;border-color:rgba(255,255,255,.20)}
:root:not([data-theme="light"]) .balance-card:not(.balance-card--flat):not(.balance-card--on-dark) .btn--glass:hover{background:rgba(255,255,255,.22)}

/* В СВЕТЛОЙ теме карточка светлая — тёплый серый, на полтона глубже страницы.
   Ей достаточно быть чуть плотнее окружения: тогда она читается как главная, но не
   выглядит чужеродной плашкой. Тёмный вариант здесь пробовали — смотрится тяжело. */
:root[data-theme="light"] .balance-card:not(.balance-card--flat):not(.balance-card--on-dark){
  background:linear-gradient(140deg,#e7ded9 0%,#f1eae6 55%,#f6f1ee 100%);
  border:1px solid #ded1cb;
  box-shadow:0 16px 34px -26px rgba(80,45,40,.45), inset 0 0 0 1px rgba(184,36,45,.07)}
/* Свечение почти убрано: на светлом любое цветное пятно читается как грязь. */
:root[data-theme="light"] .balance-card:not(.balance-card--flat):not(.balance-card--on-dark)::after{
  background:radial-gradient(circle,rgba(184,36,45,.10),transparent 65%)}
:root[data-theme="light"] .balance-card:not(.balance-card--flat):not(.balance-card--on-dark) .balance-card-label{color:#6e5d61}
:root[data-theme="light"] .balance-card:not(.balance-card--flat):not(.balance-card--on-dark) .balance-card-value{color:#1b1416}
/* Кнопки на серой подложке: белые, чтобы отделяться от неё, а не растворяться. */
:root[data-theme="light"] .balance-card:not(.balance-card--flat):not(.balance-card--on-dark) .btn--glass{
  background:rgba(255,255,255,.75);color:#1b1416;border-color:rgba(120,90,85,.18)}
:root[data-theme="light"] .balance-card:not(.balance-card--flat):not(.balance-card--on-dark) .btn--glass:hover{background:#fff}
.balance-card--flat{background:linear-gradient(135deg,var(--red-deep-a),var(--red-deep-b));box-shadow:none}
/* Карточка заработка на «Рефералах». Раньше цвет и тень задавались прямо в разметке
   инлайновым стилем — поменять их можно было только правкой HTML, а контраст никто
   не проверял. */
.balance-card--green{background:linear-gradient(135deg,var(--green-deep-a),var(--green-deep-b));
  box-shadow:0 22px 55px -28px rgba(18,77,49,.75)}
/* Default (graphite home card) follows the theme; the coloured cards keep white text. */
.balance-card-label{color:var(--muted);font-size:var(--fs-sm);position:relative}
.balance-card-value{font-size:2.4rem;font-weight:700;margin:4px 0 18px;position:relative;letter-spacing:-.02em;color:var(--text)}
/* Цветные карточки (красная на «Балансе», зелёная на «Рефералах») ВСЕГДА с белым
   текстом: фон у них насыщенный и от темы не зависит. Вес селектора поднят намеренно —
   правила темы выше по файлу оказались тяжелее и однажды уже перекрасили текст на
   зелёной карточке в серый, сделав сумму нечитаемой. */
:root .balance-card--flat .balance-card-label,
:root .balance-card--on-dark .balance-card-label{color:rgba(255,255,255,.85)}
:root .balance-card--flat .balance-card-value,
:root .balance-card--on-dark .balance-card-value{color:#fff}
:root .balance-card--flat .btn--glass,
:root .balance-card--on-dark .btn--glass{background:rgba(255,255,255,.16);color:#fff;
  border-color:rgba(255,255,255,.28)}
:root .balance-card--flat .btn--glass:hover,
:root .balance-card--on-dark .btn--glass:hover{background:rgba(255,255,255,.26)}
.balance-card-actions{display:flex;gap:10px;position:relative;flex-wrap:wrap}
.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:30px}
.stat{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:16px 18px}
.stat--link{cursor:pointer;transition:border-color .15s,transform .15s}
.stat--link:hover{border-color:var(--green);transform:translateY(-2px)}
.stat-ico{width:34px;height:34px;border-radius:var(--r-xs);display:grid;place-items:center;font-size:1.1rem;margin-bottom:12px}
.stat-ico--green{background:var(--green-soft);color:var(--green)}
.stat-ico--amber{background:rgba(226,165,82,.14);color:var(--amber)}
.stat-ico--red{background:var(--red-soft);color:var(--accent)}
.stat-label{color:var(--muted);font-size:var(--fs-sm)}
.stat-value{font-size:1.6rem;font-weight:700;margin-top:2px}
.stat-value--sm{font-size:var(--fs-md)}
.stat-sub{color:var(--muted);font-size:var(--fs-md);font-weight:600}
.section-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:14px}

/* ---------- Devices ---------- */
.page-top{display:flex;justify-content:space-between;align-items:center;margin-bottom:22px;flex-wrap:wrap;gap:12px}
.page-top h1{margin:0}
.device{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  padding:16px 18px;margin-bottom:12px}
.device-head{display:flex;align-items:center;gap:14px}
.device-ico{width:42px;height:42px;border-radius:12px;background:var(--surface-3);
  display:grid;place-items:center;font-size:1.2rem}
.device-name{font-weight:650}
.device-proto{color:var(--muted);font-size:var(--fs-sm)}
.pill{margin-left:auto;padding:5px 11px;border-radius:var(--r-pill);font-size:var(--fs-xs);font-weight:600}
.pill--active{background:var(--green-soft);color:var(--green)}
/* Заморожено (кончились деньги, лимит) — янтарный: состояние сервиса.
   Предупреждение о раздаче конфига — красный: это претензия к человеку.
   Пауза — спокойный синий: её человек поставил сам, тревожить его незачем. */
.pill--frozen{background:rgba(226,165,82,.16);color:var(--amber)}
.pill--warn{background:var(--red-soft);color:var(--accent)}
.pill--paused{background:var(--pause-soft);color:var(--pause)}
.banner{display:flex;align-items:center;gap:12px;flex-wrap:wrap;border-radius:14px;padding:13px 16px;margin-bottom:18px;
  font-size:var(--fs-sm);font-weight:600;line-height:1.4}
.banner--warn{background:rgba(226,165,82,.16);border:1px solid rgba(226,165,82,.5);color:var(--amber)}
.banner--red{background:var(--red-soft);border:1px solid rgba(220,80,80,.5);color:var(--accent)}
.banner--info{background:rgba(90,140,210,.14);border:1px solid rgba(90,140,210,.45);color:var(--blue,#7fa8dd)}
.banner span{flex:1;min-width:180px}
.banner-cta{background:var(--amber);color:#1a1210;border:0;white-space:nowrap}
.banner--red .banner-cta{background:var(--red-2);color:#fff}
/* Why a device was frozen (red) or warned (yellow) for config sharing — inside the card, full view only. */
.device-note{margin-top:12px;padding:9px 12px;border-radius:10px;font-size:var(--fs-sm);line-height:1.4;
  background:var(--red-soft);border:1px solid rgba(220,80,80,.4);color:var(--accent)}
.device-note--warn{background:rgba(226,165,82,.16);border-color:rgba(226,165,82,.5);color:var(--amber)}
.device-actions{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
/* Drag handle (grip) — grab to reorder devices/folders (touch + mouse). */
.drag-handle{flex:none;width:34px;height:38px;display:grid;place-items:center;cursor:grab;
  color:var(--muted);font-size:1.1rem;border-radius:var(--r-xs);touch-action:none;user-select:none}
.drag-handle:hover{background:var(--surface-2);color:var(--text)}
.dragging{opacity:.85;box-shadow:0 14px 40px -12px #000;position:relative;z-index:5;cursor:grabbing}
body.dragging-active{cursor:grabbing;user-select:none}
body.dragging-active *{cursor:grabbing !important}
/* Devices toolbar + folders */
.dev-toolbar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:14px}
/* One-time "smart routing" (Happ) setup card at the top of the devices page. */
.route-card{display:flex;align-items:center;gap:12px 14px;flex-wrap:wrap;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r);padding:14px 16px;margin-bottom:14px}
.route-card-txt{flex:1;min-width:200px}
.route-steps{margin:4px 0 14px;padding-left:20px;line-height:1.5;font-size:var(--fs-sm)}
.route-steps li{margin-bottom:5px}
.folder{margin-bottom:12px}
.folder-head{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:12px;
  background:var(--surface-2);border:1px solid var(--border)}
.folder-title{font-weight:650;font-size:var(--fs-md)}
.folder-count{font-size:var(--fs-xs);margin-left:2px}
.folder-tools{margin-left:auto;display:flex;gap:4px}
.icon-btn{width:30px;height:30px;border-radius:8px;border:1px solid var(--border);background:var(--surface);
  color:var(--muted);display:grid;place-items:center;cursor:pointer;font-size:var(--fs-sm)}
.icon-btn:hover{color:var(--text);border-color:var(--accent)}
.folder-body{padding:8px 0 2px;min-height:14px}
.folder .folder-body{padding-left:8px;border-left:2px solid var(--border);margin:6px 0 2px 18px}
.folder-empty{font-size:var(--fs-sm);padding:10px 12px;border:1px dashed var(--border);border-radius:12px}
/* Admin: 30-day mini chart + search field */
.chart-row{display:flex;align-items:flex-end;gap:2px;height:46px}
.chart-bar{flex:1;min-width:3px;border-radius:2px 2px 0 0;background:var(--surface-3)}
.chart-bar--green{background:var(--green)}
.chart-bar--red{background:var(--red-2)}
#adm-search{background:var(--surface-2);border:1px solid var(--border);border-radius:12px;
  padding:10px 14px;color:var(--text);font-size:var(--fs-md)}
#adm-search:focus{outline:none;border-color:var(--accent)}
/* Admin users: compact Excel-like table with expandable rows */
.utable-head,.urow-main{display:grid;grid-template-columns:20px 1fr 74px 56px 92px;align-items:center;gap:10px}
.utable-head{padding:4px 12px 8px;font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.03em}
.utable-head span:nth-child(3),.utable-head span:nth-child(4){text-align:center}
.urow-traf{text-align:center;font-size:var(--fs-sm)}
.utable-head span:last-child{text-align:right}
.urow{background:var(--surface);border:1px solid var(--border);border-left:3px solid var(--border);border-radius:var(--r-sm);margin-bottom:5px;overflow:hidden}
.urow--active{border-left-color:var(--green)}
.urow--expired{border-left-color:var(--accent)}
.urow--paused{border-left-color:var(--amber)}
/* Молчит: доступ выдан и работает, но человек через нас не ходит. Тот же зелёный,
   но полый — сразу видно, что это не «пользуется», и не путается с ошибкой. */
.urow--silent{border-left-color:var(--pause)}
.udot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:7px;vertical-align:middle;flex:none}
.udot--active{background:var(--green)}
.udot--expired{background:var(--red-2)}
.udot--paused{background:var(--amber)}
.udot--no_devices{background:var(--muted)}
.udot--silent{background:transparent;box-shadow:inset 0 0 0 2px var(--pause)}
.urow-main{padding:10px 12px;cursor:pointer}
.urow-main:hover{background:var(--surface-2)}
.urow-chev{color:var(--muted);transition:transform .15s;font-size:var(--fs-sm)}
.urow.open .urow-chev{transform:rotate(90deg)}
.urow-name{font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.urow-dev{text-align:center;font-size:var(--fs-sm)}
.urow-bal{text-align:right;font-weight:650}
.urow-detail{padding:12px 14px;border-top:1px solid var(--border);background:var(--surface-2)}
/* Карточка клиента. Раньше это были четыре строки фактов через точку: чтобы найти
   дату входа, приходилось прочитать всё подряд. Теперь три блока по смыслу —
   что человеку выдано, как он этим пользуется, кто он. */
.udet{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
.udet-block{background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r-xs);padding:9px 11px}
.udet-cap{font-size:var(--fs-xs);font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--muted);opacity:.75;margin-bottom:6px}
.udet-row{display:flex;justify-content:space-between;align-items:baseline;gap:10px;
  font-size:var(--fs-sm);line-height:1.7}
.udet-k{color:var(--muted);white-space:nowrap}
.udet-v{text-align:right;font-variant-numeric:tabular-nums}
/* Запасной вход в карточке устройства. Тихий блок: он нужен меньшинству, но нужен
   срочно — человек с закрытым портом иначе просто уходит, решив, что мы сломались. */
.alt-entry{margin-top:12px;padding:10px 12px;border:1px dashed var(--border);
  border-radius:var(--r-xs);background:var(--surface-2)}
.udet-acts{display:flex;gap:6px;flex-wrap:wrap;align-items:center;margin-top:12px}
/* Переписка в окне «Написать». Ограничена по высоте: разговор может быть длинным,
   а поле ввода должно оставаться на виду — иначе окно уезжает за край экрана. */
.msg-hist{max-height:220px;overflow-y:auto;margin:12px 0 4px;
  display:flex;flex-direction:column;gap:8px;
  /* Рамка обязательна: без неё обрезанное на прокрутке сообщение выглядит не как
     «лента продолжается», а как сломанная вёрстка. */
  border:1px solid var(--border);border-radius:var(--r-xs);padding:8px;
  background:var(--surface-2)}
.msg-hist--empty{max-height:none;padding:10px;align-items:center}
.msg{border-radius:var(--r-xs);padding:8px 10px;font-size:var(--fs-sm)}
/* Наши ответы — янтарные, как кнопка «Написать»; обращения клиента — нейтральные.
   Без разницы в цвете лента читается как один сплошной монолог. */
.msg--out{background:var(--amber-soft);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--amber) 25%,transparent)}
.msg--in{background:var(--surface);border:1px solid var(--border)}
.msg-meta{font-size:var(--fs-xs);color:var(--muted);margin-bottom:3px}
.msg-text{white-space:pre-wrap;word-break:break-word;line-height:1.45}
/* Тонкая черта между группами кнопок: связь с человеком, настройки, деньги. */
.udet-sep{width:1px;align-self:stretch;background:var(--border);margin:2px 4px}
.udet-danger{margin-left:auto}
@media (max-width:760px){
  .udet{grid-template-columns:1fr}
  /* Кнопки переносятся по две-три в ряд, и вертикальные разделители повисают
     посреди строки, ничего не разделяя. */
  .udet-sep{display:none}
  /* «Удалить» — на отдельную строку: рядом с «Историей» в неё легко попасть пальцем
     мимо, а действие необратимое. */
  .udet-danger{margin-left:0;width:100%;margin-top:4px}
}
.pager{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:12px}
/* Read-only copy field (referral link) — grey pill with docked Copy button */
.copy-field{display:flex;align-items:center;gap:8px;background:var(--surface-2);
  border:1px solid var(--border);border-radius:12px;padding:6px 6px 6px 14px}
.copy-field a{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  color:var(--text);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--fs-sm);text-decoration:none}
.copy-field a:hover{color:var(--accent)}
.copy-field .btn{flex:none}
/* First-run onboarding card on the empty home */
.onboard-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  padding:28px 24px;text-align:center}
.onboard-ico{font-size:2.2rem;margin-bottom:8px}
.onboard-card h3{font-size:var(--fs-lg);margin-bottom:6px}
.onboard-card p{max-width:420px;margin:0 auto}
.onboard-card .btn{margin-top:16px}
.config{margin-top:14px;background:var(--surface-2);border:1px solid var(--border);
  border-radius:12px;padding:12px 14px;display:none}
.config.open{display:block}
.config code{display:block;word-break:break-all;font-size:var(--fs-xs);color:var(--accent);
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;margin-bottom:10px;line-height:1.5}

/* ---------- misc ---------- */
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);padding:6px 18px;margin-bottom:18px}
.help-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);margin-top:18px;overflow:hidden}
.help-card>summary{cursor:pointer;padding:14px 18px;font-weight:600;font-size:var(--fs-sm);list-style:none}
.help-card>summary::-webkit-details-marker{display:none}
.help-card>summary::after{content:"▾";float:right;color:var(--muted);transition:.15s}
.help-card[open]>summary::after{transform:rotate(180deg)}
.help-card-body{padding:2px 18px 16px;font-size:var(--fs-sm);line-height:1.55;color:var(--text)}
.help-card-body ul{margin:8px 0 8px 2px;padding-left:18px;display:flex;flex-direction:column;gap:7px}
.help-card-body p{margin:6px 0}
.row{display:flex;justify-content:space-between;padding:14px 0;border-bottom:1px solid var(--border)}
.row:last-child{border-bottom:0}
.notice{display:flex;gap:14px;background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r);padding:16px 18px}
.notice-ico{width:34px;height:34px;border-radius:10px;background:var(--red-soft);
  color:var(--accent);display:grid;place-items:center;flex:none}
.empty{text-align:center;color:var(--muted);padding:46px 20px;border:1px dashed var(--border);border-radius:var(--r)}
.empty-ico{font-size:2rem;opacity:.5;margin-bottom:10px}

/* ---------- Modal ---------- */
.modal{position:fixed;inset:0;background:rgba(0,0,0,.62);display:grid;place-items:center;padding:20px;z-index:50}
.modal-card{position:relative;width:100%;max-width:440px;background:var(--surface);
  border:1px solid var(--border);border-radius:20px;padding:26px;box-shadow:var(--shadow)}
.modal-close{position:absolute;right:16px;top:14px;font-size:1.5rem;color:var(--muted);line-height:1;
  width:36px;height:36px;border-radius:10px}
.modal-close:hover{background:var(--surface-2)}
.modal h2{margin-bottom:16px}
/* Modal form fields + shared input */
.mform{display:flex;flex-direction:column;gap:14px}
.mfield{display:flex;flex-direction:column;gap:6px;font-size:var(--fs-sm)}
.mfield span{color:var(--muted)}
.input,.mfield input{background:var(--surface-2);border:1px solid var(--border);border-radius:12px;
  padding:12px 14px;color:var(--text);font-size:var(--fs-md);width:100%}
.input:focus,.mfield input:focus{outline:none;border-color:var(--accent)}
/* Toast */
#toast-box{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:80;
  display:flex;flex-direction:column;gap:8px;align-items:center;pointer-events:none;width:max-content;max-width:92vw}
.toast{padding:12px 18px;border-radius:12px;font-weight:600;font-size:var(--fs-sm);box-shadow:var(--shadow);
  background:var(--surface-3);border:1px solid var(--border);color:var(--text);animation:toast-in .25s ease}
.toast--ok{border-color:rgba(46,160,90,.5)}
.toast--err{border-color:rgba(220,80,80,.5);color:var(--accent)}
.toast--out{opacity:0;transform:translateY(8px);transition:opacity .3s,transform .3s}
@keyframes toast-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
.qr{background:#fff;border-radius:12px;padding:14px;display:grid;place-items:center;margin:12px 0}
.qr img{width:200px;height:200px;image-rendering:pixelated}

/* ---------- Light theme ---------- */
/* ---- Готовые ответы поддержки ----
   Экран нужен в одном сценарии: на том конце ЖДЁТ человек. Поэтому список свёрнут —
   сначала глазами по названиям, текст раскрывается по нажатию. Семь распахнутых
   ответов превращали экран в стену серого, где названия терялись.
   «Скопировать» стоит в шапке и не съезжает от длины текста: у кнопки, которой
   пользуются каждый день, должно быть постоянное место. */
.reply-bar{display:flex;gap:8px;align-items:center;margin-bottom:10px}
.reply-search{flex:1;min-width:0}
.reply-seg{flex:none}
.reply-total{font-size:var(--fs-xs);margin:0 2px 12px}
.reply-grid{display:grid;gap:10px}
@media(min-width:1080px){.reply-grid{grid-template-columns:1fr 1fr;align-items:start}}

.reply{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  overflow:hidden;transition:border-color .15s,box-shadow .15s}
.reply:hover{border-color:var(--surface-3)}
.reply.is-open{border-color:var(--accent);box-shadow:var(--shadow)}
/* Раскрытая карточка занимает обе колонки: текст ответа читают целиком, а не
   в узкой колонке рядом с соседним. */
@media(min-width:1080px){.reply.is-open,.reply--edit{grid-column:1 / -1}}

.reply-head{display:flex;align-items:center;gap:10px;padding:12px 14px;cursor:pointer;
  user-select:none}
.reply-head:focus-visible{outline:2px solid var(--red-2);outline-offset:-2px}
.reply-chev{flex:none;color:var(--muted);font-size:1.1rem;line-height:1;
  transition:transform .15s}
.reply.is-open .reply-chev{transform:rotate(90deg);color:var(--accent)}
.reply-title{font-weight:650;font-size:var(--fs-md);flex:1;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* Сколько раз ответ ушёл в переписку. Цифра, а не украшение: по ней строится
   режим «Частые», и видно, что спрашивают правда часто. */
.reply-uses{flex:none;min-width:22px;padding:2px 7px;border-radius:20px;
  background:var(--surface-3);color:var(--muted);font-size:var(--fs-xs);font-weight:600;
  text-align:center}
.reply-copy{flex:none}
.reply-preview{margin:0;padding:0 14px 12px 36px;color:var(--muted);font-size:var(--fs-sm);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.reply-body{padding:0 14px 14px}
/* Переносы строк сохраняем: ответ вставляют в переписку ровно таким, как он выглядит. */
.reply-text{white-space:pre-wrap;font-size:var(--fs-sm);line-height:1.6;color:var(--text);
  background:var(--surface-2);border-radius:var(--r-sm);padding:12px 14px}
.reply-acts{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-top:10px}
.reply-hint{font-size:var(--fs-xs)}
.reply-del{color:var(--danger)}
.reply-ord{display:flex;gap:4px;margin-left:auto}
.iconb{width:30px;height:30px;flex:none;border-radius:var(--r-xs);position:relative;border:1px solid var(--border);
  background:var(--surface-2);color:var(--muted);font-size:11px;cursor:pointer;line-height:1}
.iconb:hover:not([disabled]){color:var(--text);border-color:var(--accent)}
.iconb[disabled]{opacity:.3;cursor:default}

.reply--edit{border-color:var(--accent);display:grid;gap:10px;padding:14px}
.reply-area{width:100%;resize:vertical;font-family:inherit;line-height:1.55}
@media(max-width:560px){
  .reply-bar{flex-wrap:wrap}
  .reply-bar .btn,.reply-seg{width:100%}
  .reply-seg{display:flex}
  .reply-seg .seg-btn{flex:1}
  .reply-acts .btn{flex:1 1 auto}
}
@media(prefers-reduced-motion:reduce){
  .reply,.reply-chev{transition:none}
}

/* ---------- Light theme ---------- */
/* ---- Готовые ответы поддержки ----
   Раньше это был плоский список: заголовок, три обрезанные строки и кнопка
   «Скопировать». Текст ответа — главное в этом экране, поэтому он читается
   целиком, а правка, порядок и удаление лежат рядом с ним, а не в коде. */
.reply-bar{display:flex;gap:8px;align-items:center;margin-bottom:12px}
.reply-search{flex:1;min-width:0}
.reply{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  padding:14px 16px;margin-bottom:10px}
.reply-head{display:flex;align-items:center;gap:10px;margin-bottom:8px}
.reply-title{font-weight:650;font-size:var(--fs-md);flex:1;min-width:0}
.reply-ord{display:flex;gap:4px;flex:none}
.iconb{width:30px;height:30px;flex:none;border-radius:8px;border:1px solid var(--border);
  background:var(--surface-2);color:var(--muted);font-size:11px;cursor:pointer;line-height:1}
.iconb:hover:not([disabled]){color:var(--text);border-color:var(--accent)}
.iconb[disabled]{opacity:.3;cursor:default}
/* Перенос строк сохраняем: ответ вставляют в переписку ровно таким, как он выглядит. */
.reply-text{white-space:pre-wrap;font-size:var(--fs-sm);line-height:1.55;color:var(--muted);
  background:var(--surface-2);border-radius:var(--r-sm);padding:11px 13px}
/* Обрезаем по высоте с растворением, а не по числу строк: в ответах есть пустые
   строки между абзацами, и line-clamp на них оставлял в срезе половину буквы. */
.reply-text--clip{max-height:6.4em;overflow:hidden;
  -webkit-mask-image:linear-gradient(#000 70%,transparent);mask-image:linear-gradient(#000 70%,transparent)}
.linkb{background:none;border:0;padding:8px 2px 2px;color:var(--accent);font:inherit;
  font-size:var(--fs-sm);cursor:pointer;text-decoration:underline}
.reply-acts{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.reply-del{color:var(--danger)}
.reply--edit{border-color:var(--accent);display:grid;gap:10px}
.reply-area{width:100%;resize:vertical;font-family:inherit;line-height:1.55}
@media(max-width:560px){
  .reply-bar{flex-wrap:wrap}
  .reply-bar .btn{width:100%}
  .reply-acts .btn{flex:1 1 auto}
}

/* Светлая тема выглядела выцветшей копией тёмной: белые карточки на сером фоне без
   собственного характера. Теперь фон тёплый, «бумажный», а карточки СВЕТЛЕЕ фона —
   так они выступают вперёд, как лист на столе, а не проваливаются в него. */
:root[data-theme="light"]{
  --bg:#efe9e7; --surface:#fffdfc; --surface-2:#f6f0ed; --surface-3:#ebe2de;
  --ghost-hover:#e0d6d1;
  --border:#e0d4cf; --text:#1b1416; --muted:#6e5d61;
  /* Свой акцент: светлый красный из тёмной темы давал на белом контраст 2.97
     при норме 4.5 — ссылки и «Забыли пароль?» читались плохо. Тёмный даёт 5.6. */
  --accent:#b8242d;
  --red-soft:rgba(200,50,58,.10); --green-soft:rgba(45,140,85,.14);
  /* Оттенки подобраны по контрасту: на подложке дают 5.0 и 4.7 при норме 4.5. */
  --green:#237544; --amber:#976014; --amber-soft:rgba(151,96,20,.13); --danger:#b8242d;
  --pause:#4a6596; --pause-soft:rgba(74,101,150,.14);
  --shadow:0 14px 40px -22px rgba(60,20,30,.30);
}
/* ---------- Switch (toggle) ---------- */
.switch{position:relative;display:inline-block;width:44px;height:26px;flex:none}
.switch input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer;z-index:1}
.switch-track{position:absolute;inset:0;background:var(--surface-3);border-radius:20px;transition:background .15s}
.switch-track::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;
  border-radius:50%;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.3);transition:transform .16s}
.switch input:checked + .switch-track{background:var(--green)}
.switch input:checked + .switch-track::after{transform:translateX(18px)}

/* ---------- Segmented control ---------- */
.seg{display:inline-flex;background:var(--surface-2);border:1px solid var(--border);border-radius:11px;padding:3px;gap:2px}
.seg-btn{padding:7px 14px;border-radius:8px;font-weight:600;font-size:var(--fs-sm);color:var(--muted);transition:.12s}
.seg-btn:hover{color:var(--text)}
.seg-btn.is-active{background:var(--red);color:#fff}

/* ---------- Telegram login divider ---------- */
.tg-divider{display:flex;align-items:center;gap:12px;color:var(--muted);font-size:var(--fs-sm)}
.tg-divider::before,.tg-divider::after{content:"";flex:1;height:1px;background:var(--border)}

/* ---------- Badge ---------- */
.badge{display:inline-block;padding:3px 9px;border-radius:20px;font-size:var(--fs-xs);font-weight:600;vertical-align:middle}
.badge--muted{background:var(--surface-3);color:var(--muted)}
.badge--ok{background:var(--green-soft);color:var(--green)}

/* ---------- Device wizard ---------- */
.pf-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.pf-btn{display:flex;flex-direction:column;align-items:center;gap:8px;padding:18px 10px;
  background:var(--surface-2);border:1px solid var(--border);border-radius:14px;
  color:var(--text);font-weight:600;font-size:var(--fs-sm);transition:.12s}
.pf-btn:hover{background:var(--surface-3);border-color:var(--red)}
.pf-ico{font-size:1.8rem;line-height:1}
/* Инструкция внутри карточки устройства. Отделена подложкой: иначе шаги сливаются
   с QR-кодом и строкой конфига в одну кашу. */
.pf-hint{background:var(--surface-2);border-radius:var(--r-sm);padding:12px 14px;margin-bottom:12px}
.pf-hint-head{font-size:var(--fs-sm);font-weight:600;margin-bottom:4px}
.pf-steps{margin:4px 0 0;padding-left:20px;color:var(--muted);font-size:var(--fs-sm);line-height:1.55}
.pf-steps li{margin-bottom:6px}
.pf-steps b{color:var(--text)}

/* ---------- Theme toggle (icons) ---------- */
.theme-toggle{display:inline-flex;gap:2px;background:var(--surface-2);border:1px solid var(--border);border-radius:10px;padding:3px}
.theme-toggle button{width:32px;height:28px;border-radius:7px;font-size:var(--fs-md);line-height:1;display:grid;place-items:center;opacity:.5;transition:.12s}
.theme-toggle button:hover{opacity:.85}
.theme-toggle button.is-active{background:var(--red-soft);opacity:1;box-shadow:inset 0 0 0 1px var(--red)}
.theme-btn{width:38px;height:34px;border-radius:var(--r-xs);font-size:1.05rem;line-height:1;flex:none;
  background:var(--surface-2);border:1px solid var(--border);display:inline-grid;place-items:center}
.theme-btn:hover{background:var(--surface-3)}
.side-theme{margin:0}
.side-tools{display:flex;gap:6px;margin:2px 0 0}
/* Язык — обычная кнопка кабинета (.btn--ghost), а не значок. Квадратик из двух букв
   рядом с иконкой темы читался как подпись, и нажимать на него никто не пробовал.
   Отсюда же глобус и подпись словом: сразу видно орган управления. */
.lang-btn{height:34px;min-height:34px;padding:0 10px;gap:6px;flex:none;
  border:1px solid var(--border);font-weight:700;letter-spacing:.03em}
.lang-btn .lang-ico{font-size:.95em;line-height:1}

/* ---------- Mobile header + burger ---------- */
.mobile-header{display:none}
.burger-menu{display:none}

/* ---------- Responsive ---------- */
@media (max-width:760px){
  .layout{grid-template-columns:1fr}
  /* No bottom bar on mobile — the whole sidebar nav would overflow. The burger
     (top-left) carries all navigation instead. */
  .sidebar{display:none}
  /* Снизу — «домашняя полоска» жестов, по бокам — скруглённые углы экрана. */
  .main{padding:0 18px 28px;
    padding-left:calc(18px + env(safe-area-inset-left,0px));
    padding-right:calc(18px + env(safe-area-inset-right,0px));
    padding-bottom:calc(28px + env(safe-area-inset-bottom,0px))}
  .stats{grid-template-columns:1fr 1fr}

  /* Шапка липнет к самому верху экрана — значит уезжает под часы и индикатор сети.
     Поднимаем её содержимое на высоту статус-строки. */
  .mobile-header{display:flex;align-items:center;gap:12px;position:sticky;top:0;z-index:45;margin:0 -18px 18px;
    background:var(--surface);border-bottom:1px solid var(--border);padding:11px 16px;
    padding-top:calc(11px + env(safe-area-inset-top,0px));
    /* .main получил боковые safe-area отступы — компенсируем их, чтобы полоса шапки
       по-прежнему доходила до краёв экрана (в альбомной ориентации они не нули). */
    margin-left:calc(-18px - env(safe-area-inset-left,0px));
    margin-right:calc(-18px - env(safe-area-inset-right,0px))}
  /* Оформление и язык читаются как пара, поэтому между ними зазор уже, чем
     общий шаг шапки. */
  .mobile-header .lang-btn{margin-left:-6px}
  .mh-burger{width:34px;height:34px;border-radius:var(--r-xs);font-size:1.15rem;color:var(--text);
    background:var(--surface-2);border:1px solid var(--border);display:grid;place-items:center;flex:none}
  .mh-brand{display:flex;align-items:center;gap:8px;font-weight:700;font-size:1.05rem}
  .mh-brand .brand-logo{width:26px;height:26px;font-size:13px;border-radius:8px}
  .mh-right{margin-left:auto}
  .burger-menu.open{display:block;position:fixed;top:calc(58px + env(safe-area-inset-top,0px));left:14px;z-index:50;
    background:var(--surface);border:1px solid var(--border);border-radius:14px;padding:8px;
    box-shadow:var(--shadow);min-width:190px}
  .burger-menu button,.burger-menu a{display:flex;align-items:center;gap:10px;width:100%;text-align:left;
    padding:11px 14px;border-radius:10px;color:var(--text);font-weight:600;font-size:var(--fs-md);text-decoration:none}
  .burger-menu button:hover,.burger-menu a:hover{background:var(--surface-2)}
  /* Последним пунктом и отчёркнуто: это уже не про VPN. */
  .burger-menu a.burger-more{margin-top:6px;border-top:1px solid var(--border);
    border-radius:0 0 10px 10px;padding-top:13px;font-size:var(--fs-sm);color:var(--muted)}
  .burger-menu .nav-ico{opacity:.8;width:20px;text-align:center}
  /* Bigger grab handle on touch. */
  .drag-handle{width:40px;height:44px;font-size:1.25rem}
  /* 16px inputs so iOS Safari doesn't auto-zoom on focus. */
  .field input,#topup-input,#gift-to,#gift-amount,#adm-search,.input,.mfield input{font-size:16px}
}
*:focus-visible{outline:2px solid var(--red-2);outline-offset:2px}
@media (prefers-reduced-motion:reduce){*{transition:none !important}}

/* Рамка «вы в профиле близкого». Липкая и контрастная: забыть, в чьём профиле
   находишься, — значит завести устройство не тому человеку. */
#acting-banner{position:fixed;left:0;right:0;bottom:0;z-index:120;display:flex;
  align-items:center;justify-content:center;gap:12px;flex-wrap:wrap;
  padding:10px 16px;font-size:var(--fs-sm);
  background:var(--red-2,#c0392b);color:#fff;box-shadow:0 -6px 20px rgba(0,0,0,.28)}
#acting-banner .btn{background:rgba(255,255,255,.18);color:#fff;border:1px solid rgba(255,255,255,.35)}
#acting-banner .btn:hover{background:rgba(255,255,255,.28)}
/* Рамку рисуем по краю ЭКРАНА, а не документа: inset-тень на body повторяет высоту
   body, а она меньше прокручиваемого содержимого — и «рамка» превращается в красную
   черту поперёк страницы. */
body.is-acting::before{content:"";position:fixed;inset:0;z-index:119;pointer-events:none;
  border:3px solid var(--red-2,#c0392b)}
body.is-acting .main{padding-bottom:64px}
