/* Road24 Analytics — design tokens */
/* X2Y8 — плавная смена темы: переход активен только в момент переключения (класс theme-anim ~460мс) */
html.theme-anim, html.theme-anim *, html.theme-anim *::before, html.theme-anim *::after {
  transition: background-color .42s ease, border-color .42s ease, color .34s ease, fill .42s ease, box-shadow .42s ease !important;
}
:root {
  --bg: #0f1419;
  --bg-2: #131a21;
  --bg-3: #1d2832;     /* hover/средний — равен card-2 */
  --card: #172029;
  --card-2: #1d2832;
  --border: #202a35;
  --border-1: #202a35; /* алиас для legacy CSS, == border */
  --border-2: #2f3e4c;
  --text: #e8eef2;
  --text-1: #e8eef2;   /* алиас, == text */
  --text-2: #98a6b0;
  --text-3: #6e7d86;
  /* --bg-1: светлее bg-2 для активного состояния табов/чипов */
  --bg-1: #1a232d;
  --cyan: #2dd4bf;
  --cyan-glow: rgba(45, 212, 191, 0.30);
  --cyan-dim: rgba(45, 212, 191, 0.12);
  --cyan-rgb: 45, 212, 191;
  --on-cyan: #001821;   /* контрастный текст поверх cyan-fill */
  --on-accent: #001016; /* контрастный текст поверх любых accent-кружков (аватары) */
  --green: #4ade80;
  --green-glow: rgba(74, 222, 128, 0.28);
  --green-dim: rgba(74, 222, 128, 0.12);
  --warn: #fbbf24;
  --warn-dim: rgba(251, 191, 36, 0.14);
  --warn-glow: rgba(255, 140, 0, 0.5);
  --warn-glow-soft: rgba(255, 140, 0, 0.3);
  --danger: #fb7185;
  --danger-dim: rgba(251, 113, 133, 0.14);
  --violet: #a78bfa;
  --violet-dim: rgba(167, 139, 250, 0.14);
  --r-card: 12px;
  --r-btn: 8px;
  --r-pill: 999px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;
  --space-9: 56px;
}

/* Theme B — Warm Amber (гармонизирована: тёплая палитра без кислотного лайма) */
html.theme-amber {
  --bg: #18120d;
  --bg-2: #1e1710;
  --bg-3: #2e2319;
  --bg-1: #261d15;
  --card: #241b13;
  --card-2: #2e2319;
  --border: #2f241a;
  --border-1: #2f241a;
  --border-2: #43331f;
  --text: #f3ece3;
  --text-1: #f3ece3;
  --text-2: #b8a892;
  --text-3: #83725f;
  --cyan: #efa637;
  --cyan-glow: rgba(239, 166, 55, 0.30);
  --cyan-dim: rgba(239, 166, 55, 0.13);
  --cyan-rgb: 239, 166, 55;
  --green: #5fc98a;
  --green-glow: rgba(95, 201, 138, 0.26);
  --green-dim: rgba(95, 201, 138, 0.13);
  --warn: #f6993a;
  --warn-dim: rgba(246, 153, 58, 0.14);
  --danger: #f2674e;
  --danger-dim: rgba(242, 103, 78, 0.14);
  --violet: #d09be6;
  --violet-dim: rgba(208, 155, 230, 0.14);
}

/* Theme C — Light Clean */
html.theme-light {
  --bg: #eef2f7;
  --bg-2: #e7edf4;
  --bg-3: #f4f7fb;
  --bg-1: #ffffff;
  --card: #ffffff;
  --card-2: #f4f7fb;
  --border: #dde4ec;
  --border-1: #dde4ec;
  --border-2: #c5cfda;
  --text: #0f172a;
  --text-1: #0f172a;
  --text-2: #4a5663;
  --text-3: #6e7a89;
  --cyan: #2563eb;
  --cyan-glow: rgba(37, 99, 235, 0.25);
  --cyan-dim: rgba(37, 99, 235, 0.10);
  --cyan-rgb: 37, 99, 235;
  --green: #16a34a;
  --green-glow: rgba(22, 163, 74, 0.22);
  --green-dim: rgba(22, 163, 74, 0.10);
  --warn: #d97706;
  --warn-dim: rgba(217, 119, 6, 0.10);
  --danger: #dc2626;
  --danger-dim: rgba(220, 38, 38, 0.10);
  --violet: #7c3aed;
  --violet-dim: rgba(124, 58, 237, 0.10);
}

html.theme-light ::-webkit-scrollbar-thumb { background: #cbd5e1; }
html.theme-light ::-webkit-scrollbar-thumb:hover { background: #94a3b8; }

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  scrollbar-gutter: stable;
}
/* GJTZ — постоянный вертикальный скроллбар: ширина окна не меняется при смене высоты
   контента (открытие модалок/меню, переключение секций настроек), поэтому sticky-меню
   слева больше НЕ прыгает. Надёжнее, чем один scrollbar-gutter (зависит от браузера). */
html { overflow-y: scroll; }
/* NO0X — пока открыта модалка, фон не скроллится и не дёргается. Скроллбар-гаттер
   зарезервирован (scrollbar-gutter: stable выше), поэтому ширина окна не меняется и
   sticky-меню слева НЕ съезжает при «Редактировать». */
html:has(.modal-backdrop) { overflow: hidden; }

.mono {
  font-family: 'JetBrains Mono', 'Menlo', monospace;
  font-feature-settings: 'tnum' 1;
}

button {
  font-family: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

input, select, textarea {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-track {
  background: transparent;
}
::-webkit-scrollbar-thumb {
  background: #2a2a3e;
  border-radius: 6px;
}
::-webkit-scrollbar-thumb:hover {
  background: #353550;
}

/* App shell — sidebar + content (MUBU): plain left rail, no dropdowns */
.app-shell {
  --sidenav-w: 232px;
  --rp-banner-h: 0px;
  min-height: 100vh;
  display: grid;
  grid-template-columns: var(--sidenav-w) 1fr;
  background: var(--bg);
}
.app-shell.has-rp-banner { --rp-banner-h: 38px; }

.sidenav {
  background: var(--bg-2, #0d0e14);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 0;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: thin;
  z-index: 40;
}
.sidenav::-webkit-scrollbar { width: 6px; }
.sidenav::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 3px; }

.sidenav-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 18px 18px 14px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 8px;
}
.sidenav-brand-mark {
  flex: none;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.sidenav-brand-text { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.sidenav-brand-name { font-size: 14px; font-weight: 600; color: var(--text); }
.sidenav-brand-sub { font-size: 10.5px; color: var(--text-3); letter-spacing: 0.2px; margin-top: 2px; }

.sidenav-groups {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 6px 12px 24px;
  flex: 1;
}
.sidenav-section { display: flex; flex-direction: column; gap: 2px; }
.sidenav-section-head {
  padding: 14px 10px 6px;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.7px;
  color: var(--text-3);
  font-weight: 600;
}
.sidenav-section-items { display: flex; flex-direction: column; gap: 1px; }

.sidenav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--text-2);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  text-align: left;
  transition: background 120ms, color 120ms;
  position: relative;
}
.sidenav-item:hover { background: var(--card); color: var(--text); }
.sidenav-item.active {
  background: var(--cyan-dim);
  color: var(--cyan);
}
.sidenav-item.active::before {
  content: '';
  position: absolute;
  left: -12px;
  top: 6px;
  bottom: 6px;
  width: 3px;
  background: var(--cyan);
  border-radius: 0 3px 3px 0;
}
.sidenav-item-ico { display: inline-flex; align-items: center; flex: none; opacity: 0.85; }
.sidenav-item.active .sidenav-item-ico { opacity: 1; }
.sidenav-item-lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.app-content { display: flex; flex-direction: column; min-width: 0; }

/* Global appbar (поиск/role/user). Не путать с .topbar — это sub-bar внутри страниц. */
.appbar {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 28px;
  height: 60px;
  box-sizing: border-box;
  background: rgba(18, 18, 26, 0.92);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 30;
}
.appbar-search {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text-3);
  font-size: 13px;
  cursor: pointer;
  min-width: 320px;
  max-width: 460px;
  transition: border-color 140ms, background 140ms;
}
.appbar-search:hover { border-color: var(--border-2); }
.appbar-search > span:first-of-type { flex: 1; text-align: left; }
.appbar-kbd {
  font-family: var(--mono);
  font-size: 10.5px;
  padding: 2px 6px;
  background: var(--bg);
  border: 1px solid var(--border-2);
  border-radius: 4px;
  color: var(--text-2);
}
.appbar-spacer { flex: 1; }
.appbar-role { position: relative; }
.appbar-role-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  transition: border-color 140ms;
}
.appbar-role-btn.preview { border-color: rgba(var(--cyan-rgb), 0.4); }
.appbar-role-btn:hover { border-color: var(--border-2); }
.appbar-role-btn .rp-dot { width: 8px; height: 8px; border-radius: 50%; }
.appbar-user { display: flex; align-items: center; gap: 12px; padding-left: 12px; border-left: 1px solid var(--border); }
.appbar-user-name { font-size: 13px; color: var(--text-2); }
.appbar-logout {
  background: transparent;
  border: 0;
  color: var(--text-3);
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 6px;
  cursor: pointer;
  transition: color 120ms, background 120ms;
}
.appbar-logout:hover { color: var(--text); background: var(--card); }

/* Legacy compat: некоторые места ещё могут использовать .app-h — оставили оба */
.app-h {
  --rp-banner-h: 0px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
.app-h.has-rp-banner { --rp-banner-h: 38px; }

.topnav {
  background: rgba(18, 18, 26, 0.92);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 50;
}
.topnav-inner {
  /* 3H8Q — раньше был max-width: 1600px + margin auto, из-за чего справа/слева
     оставалась «пустота» на широких экранах. Сейчас занимает всю ширину окна. */
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 14px 28px;
  display: flex;
  align-items: center;
  gap: 16px;
  box-sizing: border-box;
}

/* Grouped nav — DROPDOWN style.
   flex: 0 0 auto — НЕ сжимаем кнопки навигации (иначе они переполняют родителя и налезают на search). */
.topnav-groups {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}
.topnav-dropdown {
  position: relative;
}

.topnav-link {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px;
  border-radius: 8px;
  color: var(--text-2);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.2;
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 140ms, color 140ms, border-color 140ms;
  white-space: nowrap;
  box-sizing: border-box;
}
.topnav-link:hover {
  color: var(--text);
  background: var(--card);
  border-color: var(--border);
}
.topnav-link.active {
  color: var(--cyan);
  background: var(--cyan-dim);
  border-color: rgba(var(--cyan-rgb), 0.25);
}
.topnav-link.open {
  background: var(--card);
  color: var(--text);
  border-color: var(--border-2);
}

/* Иконка-кнопка в топбаре (например, Настройки) — без текста, только svg */
.topnav-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--text-2);
  cursor: pointer;
  transition: background 140ms, color 140ms, border-color 140ms;
  flex: none;
}
.topnav-icon-btn:hover {
  color: var(--text);
  background: var(--card);
  border-color: var(--border);
}
.topnav-icon-btn.active {
  color: var(--cyan);
  background: var(--cyan-dim);
  border-color: rgba(var(--cyan-rgb), 0.25);
}

/* Dropdown menu */
@keyframes navpop {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}
.topnav-menu-pop {
  position: absolute;
  top: calc(100% + 10px);
  left: 0;
  min-width: 280px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 12px;
  padding: 6px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.5), 0 0 0 1px rgba(var(--cyan-rgb),0.04);
  z-index: 80;
  animation: navpop 140ms ease;
}
.topnav-menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  background: transparent;
  border: 0;
  width: 100%;
  cursor: pointer;
  transition: background 120ms;
  color: var(--text);
}
.topnav-menu-item:hover { background: var(--card); }
.topnav-menu-item.active { background: var(--cyan-dim); }

/* Subheaders inside dropdown — visual grouping of items */
.topnav-menu-pop .menu-subhead {
  padding: 8px 12px 6px 12px;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-3);
  font-weight: 600;
}
.topnav-menu-pop .menu-subhead + .topnav-menu-item { margin-top: 0; }
.topnav-menu-pop .menu-subhead:not(:first-child) {
  margin-top: 4px;
  border-top: 1px solid var(--border);
  padding-top: 10px;
}
.topnav-menu-item .ico {
  width: 30px; height: 30px;
  border-radius: 7px;
  background: var(--card);
  border: 1px solid var(--border);
  display: grid; place-items: center;
  color: var(--text-2);
  flex-shrink: 0;
}
.topnav-menu-item.active .ico {
  background: rgba(var(--cyan-rgb),0.15);
  color: var(--cyan);
  border-color: rgba(var(--cyan-rgb),0.3);
}
.topnav-menu-item .lbl {
  font-size: 13.5px;
  font-weight: 500;
}
.topnav-menu-item.active .lbl { color: var(--cyan); }
.topnav-menu-item .sub {
  font-size: 11.5px;
  color: var(--text-3);
  margin-top: 1px;
}
.topnav-menu-foot {
  border-top: 1px solid var(--border);
  margin-top: 4px;
  padding: 6px;
  display: flex;
}
.topnav-menu-foot .btn { flex: 1; justify-content: center; }

/* Search-trigger: тянется по всей доступной ширине между navgroups и role-picker.
   Без max-width — на FHD/2K заполняет всё пространство, без воздуха. */
.topnav-search {
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 11px 16px;
  color: var(--text-3);
  font-size: 13.5px;
  cursor: pointer;
  transition: border-color 140ms, color 140ms, background 140ms;
  min-width: 240px;
  flex: 1 1 auto;
}
.topnav-search:hover {
  border-color: var(--cyan);
  color: var(--text-2);
  background: var(--card-2);
}
.topnav-search > span:not(.topnav-kbd) {
  flex: 1;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.topnav-kbd {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--text-3);
  background: var(--bg-2);
  border: 1px solid var(--border);
  padding: 2px 7px;
  border-radius: 4px;
}

.app-h .main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.app-h .page {
  /* FIX 2026-06-11 (Фаза 4): max-width 1600 как стандарт — таблицы не разъезжаются.
     Для settings-страницы (где есть sidebar 240px + content) разрешён full-width
     отдельным правилом ниже — иначе на 1920px карточка профиля занимает только
     половину после sidebar. */
  max-width: 1600px;
  width: 100%;
  margin: 0 auto;
  padding: 32px 28px 64px;
}
/* Settings — full-width: sidebar 240px справа всегда нужно место для content. */
.app-h .page.settings-page {
  max-width: 100%;
}

@media (max-width: 1100px) {
  .topnav-inner { flex-wrap: wrap; }
  .topnav-search { min-width: 100%; }
}

/* FIX 2026-06-11 (агент-аудит): .notif-shade / .notif-pop объявлены дважды.
   Этот удалён, канонический полный блок на ~1413. */

.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-radius: 8px;
  color: var(--text-2);
  border-left: 2px solid transparent;
  cursor: pointer;
  transition: background 160ms, color 160ms, border-color 160ms;
  font-size: 13.5px;
  white-space: nowrap;
}
.nav-item:hover {
  background: var(--card);
  color: var(--text);
}
.nav-item.active {
  background: var(--cyan-dim);
  color: var(--cyan);
  border-left-color: var(--cyan);
  box-shadow: inset 0 0 0 1px rgba(var(--cyan-rgb), 0.08);
}
.nav-item .ico {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  display: grid;
  place-items: center;
}
.collapsed .sidebar .brand-name,
.collapsed .sidebar .brand-sub,
.collapsed .sidebar .nav-item span.lbl {
  display: none;
}
.collapsed .sidebar .nav-item {
  justify-content: center;
  padding-left: 8px;
  padding-right: 8px;
}

.sidebar-foot {
  margin-top: auto;
  border-top: 1px solid var(--border);
  padding-top: 12px;
}
.collapse-btn {
  width: 100%;
  padding: 8px;
  border-radius: 8px;
  color: var(--text-2);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-size: 12px;
}
.collapse-btn:hover { background: var(--card); color: var(--text); }

/* Main */
.main {
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.topbar {
  height: 60px;
  border-bottom: 1px solid var(--border);
  padding: 0 28px;
  display: flex;
  align-items: center;
  gap: 16px;
  background: rgba(18, 18, 26, 0.85);
  backdrop-filter: blur(8px);
  position: sticky;
  /* L31V — прижимаемся под верхнюю навигацию (60px) и баннер роли (если он есть) */
  top: calc(60px + var(--rp-banner-h, 0px));
  z-index: 5;
}
.topbar h1 {
  font-size: 16px;
  font-weight: 600;
  margin: 0;
}
.topbar .crumb {
  color: var(--text-3);
  font-size: 12px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  margin-bottom: 1px;
}
.topbar .grow { flex: 1; }
.topbar-search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 12px;
  width: 280px;
  color: var(--text-2);
}
.topbar-search input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--text);
  font-size: 13px;
}
.topbar .user {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: linear-gradient(135deg, #2a2a3e, #1c1c2e);
  border: 1px solid var(--border-2);
  display: grid;
  place-items: center;
  font-weight: 600;
  font-size: 12px;
  color: var(--text);
}
.bell {
  width: 34px;
  height: 34px;
  border-radius: 8px;
  display: grid;
  place-items: center;
  color: var(--text-2);
  position: relative;
}
.bell:hover { background: var(--card); color: var(--text); }
.bell::after {
  content: '';
  position: absolute;
  top: 8px; right: 9px;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--cyan);
  box-shadow: 0 0 8px var(--cyan-glow);
}

.page {
  padding: 24px 28px 64px 28px;
  animation: fadein 280ms ease;
}
/* Embedded-страница внутри табов «Аналитика»: внешний .page уже даёт боковой
   padding 28px, поэтому вложенный контент должен идти БЕЗ собственных боковых
   отступов — иначе графики уезжают правее, а табы остаются слева (визуальный
   «разъехавшийся» дизайн). Сохраняем только нижний отступ и анимацию. */
.page-embedded {
  padding: 0 0 32px 0;
  animation: fadein 280ms ease;
}
@keyframes fadein {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}

/* Cards */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: 18px;
}
.card-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.card-h h3 {
  font-size: 13px;
  font-weight: 600;
  margin: 0;
  color: var(--text);
  letter-spacing: 0.2px;
}
.card-h .sub {
  color: var(--text-2);
  font-size: 11.5px;
}
@media (max-width: 1100px) {
  .card-h .sub { display: none; }
}
@media (max-width: 720px) {
  .card-h { flex-wrap: wrap; }
}

/* Grid helpers */
.grid { display: grid; gap: 16px; }
.g-6 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g-2-asym-30-70 { grid-template-columns: 30% 1fr; }

/* Metric card */
.metric {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  position: relative;
  transition: border-color 160ms, transform 160ms;
}
/* H0UU — без ховер-подсветки у некликабельных статов (остаток от кликабельности убран);
   подсветка только у действительно кликабельных карточек (.clickable ниже). */
.metric.clickable {
  cursor: pointer;
}
.metric.clickable:hover {
  border-color: var(--cyan);
  transform: translateY(-1px);
}
.metric.clickable .metric-arrow {
  position: absolute;
  right: 14px;
  top: 14px;
  color: var(--text-3);
  opacity: 0;
  transition: opacity 140ms, transform 140ms;
}
.metric.clickable:hover .metric-arrow {
  opacity: 1;
  color: var(--cyan);
  transform: translateX(2px);
}

/* Anomaly banner */
.anomaly-banner {
  background: linear-gradient(90deg, rgba(255, 140, 0, 0.10), rgba(255, 140, 0, 0.02));
  border: 1px solid rgba(255, 140, 0, 0.25);
  border-radius: var(--r-card);
  padding: 14px 18px;
}
.metric .label {
  font-size: 12px;
  color: var(--text-2);
  letter-spacing: 0.2px;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 6px;
}
@media (max-width: 1100px) {
  .metric .label { line-height: 1.2; flex-wrap: wrap; row-gap: 4px; }
  .metric .label .badge { flex-shrink: 0; }
}
.metric .extra {
  margin-left: auto;
  justify-self: flex-end;
  display: inline-flex;
  align-items: center;
}
.metric .value {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.5px;
  font-family: 'JetBrains Mono', monospace;
}
.metric .delta {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  font-weight: 500;
}
.delta.up { color: var(--green); }
.delta.down { color: var(--danger); }
.delta.flat { color: var(--text-2); }

/* Pulse dot */
.pulse-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 8px var(--green-glow);
  position: relative;
}
/* pulse-dot: спокойная статичная точка. Анимация-кольцо убрана — мерцала вечно (5804). */

/* История пинов на проде — popup-панель справа */
.hist-backdrop {
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.45);
  z-index: 200;
  display: flex; justify-content: flex-end;
  animation: histfade 160ms ease;
}
@keyframes histfade { from { opacity: 0 } to { opacity: 1 } }
.hist-panel {
  width: min(480px, 100vw);
  height: 100vh;
  background: var(--bg-2, #0d0e14);
  border-left: 1px solid var(--border);
  display: flex; flex-direction: column;
  box-shadow: -12px 0 36px rgba(0,0,0,0.5);
  animation: histslide 180ms ease;
}
@keyframes histslide { from { transform: translateX(20px); opacity: 0 } to { transform: none; opacity: 1 } }
.hist-head {
  display: flex; justify-content: space-between; align-items: flex-start;
  padding: 16px 18px; border-bottom: 1px solid var(--border);
}
.hist-list {
  flex: 1; overflow-y: auto; padding: 6px 8px 24px;
  display: flex; flex-direction: column; gap: 4px;
}
.hist-item {
  text-align: left; background: transparent; border: 1px solid transparent; border-radius: 8px;
  padding: 10px 12px; cursor: pointer; color: var(--text);
  display: flex; flex-direction: column; gap: 4px;
  transition: background 120ms, border-color 120ms;
}
.hist-item:hover { background: var(--card); border-color: var(--border); }
.hist-item-h { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.hist-item-pin { font-family: var(--mono); font-size: 10.5px; color: var(--cyan); background: var(--cyan-dim); padding: 2px 7px; border-radius: 5px; }
.hist-item-ts { font-size: 10.5px; color: var(--text-3); }
.hist-item-title { font-size: 13px; font-weight: 500; line-height: 1.35; }
.hist-item-after { font-size: 11.5px; color: var(--text-3); line-height: 1.45; }

/* Badge */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 3px 8px;
  border-radius: var(--r-pill);
  font-size: 11px;
  font-weight: 500;
  border: 1px solid transparent;
  white-space: nowrap;
  min-width: 78px;
  text-align: center;
}
/* Canonical AlertBanner — единый стиль для алертов/баннеров аномалий.
   Используется в Dashboard (аномалия), Server (требуется внимание) и т.д.
   Modifiers: .alert-banner.warn / .danger / .info / .success */
.alert-banner {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid var(--border);
  background: var(--card-2);
  position: relative;
  overflow: hidden;
}
.alert-banner::before {
  content: '';
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: var(--text-3);
}
.alert-banner.warn { background: rgba(255, 140, 0, 0.06); border-color: rgba(255, 140, 0, 0.25); }
.alert-banner.warn::before { background: var(--warn); }
.alert-banner.danger { background: rgba(255, 71, 87, 0.06); border-color: rgba(255, 71, 87, 0.25); }
.alert-banner.danger::before { background: var(--danger); }
.alert-banner.info { background: rgba(var(--cyan-rgb), 0.05); border-color: rgba(var(--cyan-rgb), 0.22); }
.alert-banner.info::before { background: var(--cyan); }
.alert-banner.success { background: rgba(74, 222, 128, 0.05); border-color: rgba(74, 222, 128, 0.22); }
.alert-banner.success::before { background: var(--green); }
.alert-banner__icon {
  width: 38px; height: 38px;
  border-radius: 10px;
  display: grid;
  place-items: center;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
}
.alert-banner.warn .alert-banner__icon { background: var(--warn-dim); color: var(--warn); border-color: rgba(255, 140, 0, 0.3); }
.alert-banner.danger .alert-banner__icon { background: var(--danger-dim); color: var(--danger); border-color: rgba(255, 71, 87, 0.3); }
.alert-banner.info .alert-banner__icon { background: var(--cyan-dim); color: var(--cyan); border-color: rgba(var(--cyan-rgb), 0.3); }
.alert-banner.success .alert-banner__icon { background: var(--green-dim); color: var(--green); border-color: rgba(74, 222, 128, 0.3); }
.alert-banner__body { flex: 1; min-width: 0; }
.alert-banner__title { font-size: 14px; font-weight: 500; color: var(--text); }
.alert-banner__sub { font-size: 11.5px; color: var(--text-3); margin-top: 3px; }
.alert-banner__actions { display: flex; gap: 8px; flex-shrink: 0; align-items: center; }
@media (max-width: 560px) {
  .alert-banner { flex-wrap: wrap; }
  .alert-banner__body { min-width: 100%; }
  .alert-banner__actions { width: 100%; justify-content: flex-end; }
}

/* Canonical EmptyState — единый стиль для всех пустых таблиц/списков.
   Используется через window.EmptyState({icon, title, sub, cta}) — см. data.js */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  text-align: center;
  gap: 12px;
}
.empty-state-icon {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background: var(--card-2);
  border: 1px solid var(--border);
  display: grid;
  place-items: center;
  color: var(--text-3);
  margin-bottom: 4px;
}
.empty-state-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  margin: 0;
}
.empty-state-sub {
  font-size: 12.5px;
  color: var(--text-2);
  line-height: 1.5;
  max-width: 380px;
  margin: 0;
}
.empty-state-cta {
  margin-top: 6px;
}

/* Глобально убираем дефолтные HTML-стрелки у input[type=number] — везде в проекте.
   Это убирает «школьный вид» из формы Авто-чек доменов и других мест. */
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}
/* для совсем коротких бейджей которым широкая капсула не нужна */
.badge.badge-tight { min-width: 0; }
.badge.cyan { background: var(--cyan-dim); color: var(--cyan); border-color: rgba(var(--cyan-rgb), 0.25); }
.badge.green { background: var(--green-dim); color: var(--green); border-color: rgba(0, 255, 136, 0.25); }
.badge.warn { background: var(--warn-dim); color: var(--warn); border-color: rgba(255, 140, 0, 0.3); }
.badge.danger { background: var(--danger-dim); color: var(--danger); border-color: rgba(255, 71, 87, 0.3); }
.badge.violet { background: var(--violet-dim); color: var(--violet); border-color: rgba(167, 139, 250, 0.3); }
.badge.gray { background: rgba(255,255,255,0.04); color: var(--text-2); border-color: var(--border-2); }
.badge.badge-clickable { transition: color 140ms, border-color 140ms, background 140ms; }
.badge.badge-clickable:hover { color: var(--cyan); border-color: rgba(var(--cyan-rgb), 0.4); background: rgba(var(--cyan-rgb), 0.08); }

/* Buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  border-radius: var(--r-btn);
  font-size: 13px;
  font-weight: 500;
  border: 1px solid var(--border-2);
  background: var(--card);
  color: var(--text);
  white-space: nowrap;
  transition: background 140ms, border-color 140ms, box-shadow 140ms;
}
.btn:hover { background: var(--card-2); border-color: var(--border-2); }
/* FIX 5E.1: focus-visible для клавиатурной навигации. Затрагивает СОТНИ кнопок
   по проекту — раньше Tab по кнопкам не показывал фокус нигде. */
.btn:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(var(--cyan-rgb), 0.18);
}
.btn:disabled, .btn[disabled] { opacity: 0.45; cursor: not-allowed; box-shadow: none; }
.btn:disabled:hover, .btn[disabled]:hover { background: var(--card); border-color: var(--border-2); }
.btn.primary {
  background: var(--cyan);
  color: #001821;
  border-color: var(--cyan);
  box-shadow: 0 0 8px rgba(var(--cyan-rgb), 0.18);
}
.btn.primary:hover { filter: brightness(1.08); box-shadow: 0 0 12px var(--cyan-glow); }
.btn.ghost { background: transparent; }
.btn.sm { padding: 5px 10px; font-size: 12px; }
.btn.icon { padding: 6px; min-width: 30px; justify-content: center; }

/* Pill / chip */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px;
  border-radius: var(--r-pill);
  font-size: 12px;
  background: var(--card);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  transition: all 140ms;
}
.chip:hover { border-color: var(--border-2); }
.chip.active { background: var(--cyan-dim); color: var(--cyan); border-color: rgba(var(--cyan-rgb), 0.4); }
.chip .x { color: var(--text-3); font-size: 10px; margin-left: 2px; }
.chip.tag {
  font-size: 11px;
  padding: 2px 8px;
  border: 0;
}

/* Select / input */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.field label {
  font-size: 11.5px;
  color: var(--text-2);
  letter-spacing: 0.3px;
}
.input, .select {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 12px;
  color: var(--text);
  font-size: 13px;
  outline: none;
  transition: border-color 140ms, box-shadow 140ms;
  min-width: 0;
}
.input:focus, .select:focus {
  border-color: var(--border-2);
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.03);
}
.select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-2) 50%), linear-gradient(135deg, var(--text-2) 50%, transparent 50%);
  background-position: calc(100% - 14px) 13px, calc(100% - 9px) 13px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 28px;
}

/* Table */
.table-wrap {
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--card);
  overflow: hidden;
}
table.t {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
table.t th {
  text-align: left;
  font-size: 11px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-2);
  font-weight: 500;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.012);
  white-space: nowrap;
  transition: padding 180ms ease, font-size 180ms ease;
}
table.t td {
  padding: 13px 14px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  transition: padding 180ms ease, font-size 180ms ease;
}
table.t tr:last-child td { border-bottom: 0; }
/* Числовые колонки: моноширинные tabular-цифры + right-align — числа не «прыгают» */
table.t th.right, table.t td.right { text-align: right; }
table.t td.right, table.t td.num,
table.t .mono, table.t .num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
/* зебра для длинных таблиц — мягкий контраст, не отвлекает */
table.t tbody tr:nth-child(even) td { background: rgba(255,255,255,0.012); }
html.theme-light table.t tbody tr:nth-child(even) td { background: rgba(0,0,0,0.018); }
table.t tbody tr {
  transition: background 140ms, box-shadow 140ms;
  cursor: pointer;
}
table.t tbody tr:hover {
  background: rgba(var(--cyan-rgb), 0.04);
  box-shadow: inset 2px 0 0 var(--cyan);
}
table.t tbody tr.selected {
  background: rgba(var(--cyan-rgb), 0.06);
  box-shadow: inset 2px 0 0 var(--cyan);
}
table.t th.sortable {
  cursor: pointer;
  user-select: none;
  transition: color 140ms, background 140ms;
}
table.t th.sortable:hover {
  color: var(--cyan);
  background: rgba(var(--cyan-rgb), 0.06);
}
table.t th.sortable .sort-arrow {
  display: inline-block;
  margin-left: 4px;
  opacity: 0.85;
  transition: transform 150ms ease;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
}
table.t th.sortable .sort-arrow.asc { transform: rotate(180deg); }

input[type="checkbox"].ck {
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 4px;
  border: 1px solid var(--border-2);
  background: var(--card);
  cursor: pointer;
  position: relative;
  transition: all 140ms;
  margin: 0;
  display: inline-block;
  vertical-align: middle;
}
input[type="checkbox"].ck:hover { border-color: var(--cyan); }
input[type="checkbox"].ck:checked {
  background: var(--cyan);
  border-color: var(--cyan);
  box-shadow: 0 0 6px rgba(var(--cyan-rgb),0.4);
}
/* Sidebar — tooltip in collapsed mode */
.nav-wrap {
  position: relative;
}
.collapsed .nav-tip {
  position: absolute;
  left: calc(100% + 12px);
  top: 50%;
  transform: translateY(-50%);
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 8px;
  padding: 8px 12px;
  white-space: nowrap;
  font-size: 12.5px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 140ms;
  z-index: 100;
  box-shadow: 0 6px 20px rgba(0,0,0,0.35);
}
.collapsed .nav-tip::before {
  content: '';
  position: absolute;
  left: -5px; top: 50%;
  transform: translateY(-50%) rotate(45deg);
  width: 8px; height: 8px;
  background: var(--bg-2);
  border-left: 1px solid var(--border-2);
  border-bottom: 1px solid var(--border-2);
}
.collapsed .nav-wrap:hover .nav-tip {
  opacity: 1;
}

/* Topbar search button */
.topbar-search-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 14px;
  width: 320px;
  color: var(--text-3);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  transition: border-color 140ms, color 140ms;
}
.topbar-search-btn:hover {
  border-color: var(--border-2);
  color: var(--text-2);
}
.topbar-search-btn span {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Bell with badge */
.bell-badge {
  position: absolute;
  top: 2px; right: 2px;
  min-width: 16px; height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--danger);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  display: grid;
  place-items: center;
  border: 2px solid var(--bg);
  font-family: 'JetBrains Mono', monospace;
}
.bell[data-unread="true"]::after {
  display: none;
}

/* Command Palette */
@keyframes cmdfade {
  from { opacity: 0; transform: translateY(-12px); }
  to { opacity: 1; transform: none; }
}
.cmd-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(6px);
  z-index: 200;
  display: grid;
  align-items: start;
  justify-items: center;
  padding-top: 12vh;
  animation: cmdfade 180ms ease;
}
.cmd {
  width: min(640px, 92vw);
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 24px 60px rgba(0,0,0,0.5), 0 0 0 1px rgba(var(--cyan-rgb),0.08);
}
.cmd-search {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}
.cmd-search input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--text);
  font-size: 15px;
}
.cmd-kbd {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  color: var(--text-3);
  background: var(--card);
  border: 1px solid var(--border);
  padding: 2px 6px;
  border-radius: 4px;
}
.cmd-list {
  max-height: 50vh;
  overflow-y: auto;
  padding: 6px;
}
.cmd-section {
  font-size: 10px;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 10px 12px 4px;
}
.cmd-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 120ms;
}
.cmd-item.sel {
  background: var(--cyan-dim);
}
.cmd-ico {
  width: 32px; height: 32px;
  border-radius: 8px;
  background: var(--card);
  border: 1px solid var(--border);
  display: grid; place-items: center;
  flex-shrink: 0;
}
.cmd-item.sel .cmd-ico {
  background: rgba(var(--cyan-rgb),0.15);
  border-color: rgba(var(--cyan-rgb),0.35);
}
.cmd-label {
  font-size: 13.5px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cmd-sub {
  font-size: 11.5px;
  color: var(--text-3);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cmd-empty {
  padding: 32px 12px;
  text-align: center;
  color: var(--text-3);
  font-size: 13px;
}
.cmd-foot {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 14px;
  border-top: 1px solid var(--border);
  font-size: 11px;
  color: var(--text-3);
}
.cmd-foot kbd {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  background: var(--card);
  border: 1px solid var(--border);
  padding: 1px 5px;
  border-radius: 3px;
  margin-right: 3px;
}

/* Notifications dropdown */
.notif-shade {
  position: fixed;
  inset: 60px 0 0 var(--sidebar-w, 232px);
  z-index: 50;
}
.collapsed .notif-shade { left: 68px; }
.notif-pop {
  position: absolute;
  top: 56px;
  right: 64px;
  width: 380px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 12px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.45);
  z-index: 51;
  overflow: hidden;
  animation: cmdfade 160ms ease;
}
.notif-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}
.notif-list {
  max-height: 50vh;
  overflow-y: auto;
}
.notif-item {
  display: flex;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  transition: background 140ms;
  cursor: pointer;
}
.notif-item:hover { background: rgba(255,255,255,0.02); }
.notif-item.read { opacity: 0.65; }
.notif-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  margin-top: 6px;
  flex-shrink: 0;
}
.notif-foot {
  padding: 10px 14px;
  border-top: 1px solid var(--border);
}

/* Skeleton */
@keyframes skel {
  0% { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Density */
body[data-density="compact"] table.t td { padding: 7px 12px; font-size: 12px; }
body[data-density="compact"] table.t th { padding: 8px 12px; }
body[data-density="spacious"] table.t td { padding: 18px 14px; }
body[data-density="spacious"] table.t th { padding: 16px 14px; }

/* Settings page — clean sub-nav */
.settings-page {
  padding-top: 32px !important;
}
.settings-grid {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  gap: 32px;
  align-items: start;
  /* FOPQ — двухпанельный режим с фикс-высотой: страница не скроллится,
     контент и меню скроллятся внутри своих колонок => меню НИКОГДА не двигается. */
  height: calc(100vh - 168px - var(--rp-banner-h, 0px));
}
/* FIX 2026-06-11 (Фаза 4): на узких экранах sidebar уезжал за экран и контент
   выходил за viewport (~414px). Делаем 1-колоночный layout: sidebar сверху,
   ниже — контент. Высота auto, чтобы вся страница скроллилась как обычно. */
@media (max-width: 900px) {
  .settings-grid {
    grid-template-columns: 1fr;
    gap: 16px;
    height: auto;
  }
  .settings-nav {
    position: static;
    width: 100%;
    height: auto;
    overflow-y: visible;
  }
}
.settings-nav {
  position: sticky;
  /* L31V — учитываем баннер роли, чтобы сайдбар не подныривал под плашку */
  top: calc(110px + var(--rp-banner-h, 0px));
  display: flex;
  flex-direction: column;
  width: 240px;
  flex-shrink: 0;
  /* FOPQ — меню скроллится внутри своей колонки фикс-высоты, страница неподвижна => не «плавает». */
  height: 100%;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--border-2) transparent;
}
.settings-nav::-webkit-scrollbar { width: 7px; }
.settings-nav::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 4px; }
.settings-nav::-webkit-scrollbar-track { background: transparent; }
.settings-nav-title {
  padding: 0 4px 18px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 16px;
}
.settings-nav-group {
  margin-bottom: 18px;
}
.settings-nav-group-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 0 12px;
  margin-bottom: 4px;
}
.settings-nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 12px;
  border-radius: 6px;
  color: var(--text-2);
  cursor: pointer;
  font-size: 13px;
  transition: background 140ms, color 140ms;
  position: relative;
}
.settings-nav-item:hover {
  background: var(--card);
  color: var(--text);
}
.settings-nav-item.active {
  background: var(--cyan-dim);
  color: var(--cyan);
}
.settings-nav-item.active::before {
  content: '';
  position: absolute;
  left: -8px;
  top: 6px; bottom: 6px;
  width: 2px;
  background: var(--cyan);
  border-radius: 2px;
  box-shadow: 0 0 8px var(--cyan-glow);
}
.settings-nav-item.locked {
  opacity: 0.45;
  cursor: not-allowed;
}
.settings-nav-item .lbl {
  flex-shrink: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.settings-nav-item .ct {
  font-size: 10px;
  background: var(--bg-2);
  color: var(--text-2);
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid var(--border);
  font-family: 'JetBrains Mono', monospace;
}
.settings-nav-item.active .ct {
  background: rgba(var(--cyan-rgb),0.18);
  color: var(--cyan);
  border-color: rgba(var(--cyan-rgb),0.3);
}
.settings-nav-footer {
  margin-top: auto;
  padding: 14px 12px 0;
  border-top: 1px solid var(--border);
}
.settings-content {
  min-width: 0;
  /* FOPQ — контент скроллится внутри своей колонки (страница неподвижна). */
  height: 100%;
  overflow-y: auto;
  padding-right: 8px;
  scrollbar-width: thin;
  scrollbar-color: var(--border-2) transparent;
}
.settings-content::-webkit-scrollbar { width: 8px; }
.settings-content::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 4px; }
.settings-content::-webkit-scrollbar-track { background: transparent; }
/* Мягкое появление контента при переключении раздела настроек (WY2D) */
@keyframes section-fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
.section-fade {
  animation: section-fade-in 220ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) {
  .section-fade { animation: none; }
}
/* Подсветка блока при переходе из Истории студии (?focus=) */
@keyframes pinFlash {
  0%   { box-shadow: 0 0 0 3px var(--cyan), 0 0 24px 6px var(--cyan-dim); }
  70%  { box-shadow: 0 0 0 3px var(--cyan), 0 0 24px 6px var(--cyan-dim); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.pin-flash { animation: pinFlash 2.1s ease-out; border-radius: 10px; scroll-margin: 110px; position: relative; z-index: 6; }
/* U9UD — переключатель серверов (бэкенд / панель) */
.srv-tabs { display: inline-flex; gap: 4px; background: var(--card-2); border: 1px solid var(--border); border-radius: 10px; padding: 4px; margin-bottom: 16px; }
.srv-tab { display: inline-flex; align-items: center; gap: 7px; padding: 8px 16px; border: 0; background: transparent; color: var(--text-2); font-size: 13px; font-weight: 500; border-radius: 7px; cursor: pointer; transition: background-color 180ms ease, color 180ms ease; }
.srv-tab:hover { color: var(--text); }
.srv-tab.active { background: var(--cyan-dim); color: var(--cyan); }
/* Переключение Активные↔Архив в SMS — мягкая перерисовка ленты (9KDP) */
@keyframes sms-switch-in {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
.sms-switch {
  animation: sms-switch-in 200ms cubic-bezier(0.2, 0.7, 0.3, 1);
}
@media (prefers-reduced-motion: reduce) {
  .sms-switch { animation: none; }
}
.settings-content .card {
  padding: 28px;
}
.settings-content .card + .card,
.settings-content .col > .card + .card {
  margin-top: 0;
}

/* Announcement actions — always visible (touch-friendly), highlight on hover */
.ann-actions {
  display: flex;
  gap: 4px;
  margin-top: 10px;
  max-height: 40px;
  overflow: hidden;
  opacity: 0.55;
  transition: opacity 140ms;
}
.announcement:hover .ann-actions,
.announcement.pinned .ann-actions,
.announcement:focus-within .ann-actions { opacity: 1; }
@media (hover: none) {
  .ann-actions { opacity: 1; }
}
.ann-action {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 6px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-3);
  font-size: 11px;
  cursor: pointer;
  transition: all 140ms;
}
.ann-action:hover { color: var(--text); border-color: var(--border-2); background: var(--card); }
.ann-action.active { color: var(--cyan); border-color: rgba(var(--cyan-rgb),0.3); background: var(--cyan-dim); }

/* Improved perm-legend (no colored backgrounds) */
/* FIX 2026-06-11 (агент-аудит): первый блок .perm-legend дублировал 1780+
   с конфликтующими padding/gap/margin (нижний побеждал по каскаду).
   Оставлены только legend-item/legend-dot которые в нижнем блоке отсутствуют. */
.perm-legend .legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-2);
}
.perm-legend .legend-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.session-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 14px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  transition: border-color 140ms;
}
.session-card:hover { border-color: var(--border-2); }

/* Role switcher in settings nav */
.role-switcher {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
  margin-bottom: 18px;
}
.role-switcher-pills {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 4px;
}
.role-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  border-radius: 6px;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-2);
  font-size: 11.5px;
  cursor: pointer;
  transition: all 140ms;
  white-space: nowrap;
}
.role-pill:hover {
  color: var(--text);
  background: var(--card-2);
}
.role-pill.active {
  color: var(--cyan);
  background: var(--cyan-dim);
  border-color: rgba(var(--cyan-rgb), 0.3);
}

/* Role card */
.role-card {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  transition: border-color 140ms;
  display: flex;
  flex-direction: column;
  min-height: 156px;
}
.role-card:hover { border-color: var(--border-2); }
/* описание тянется, прижимая кнопки к низу — карточки выровнены независимо от длины текста */
.role-card > .muted { flex: 1 1 auto; }

/* Матрица доступа: видимый горизонтальный скролл, когда ролей много */
.perm-matrix-scroll { scrollbar-width: thin; scrollbar-color: var(--border-2) transparent; }
.perm-matrix-scroll::-webkit-scrollbar { height: 10px; }
.perm-matrix-scroll::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 5px; }
.perm-matrix-scroll::-webkit-scrollbar-thumb:hover { background: var(--text-3); }
.perm-matrix-scroll::-webkit-scrollbar-track { background: transparent; }

/* Permission matrix legend */
.perm-legend {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  padding: 10px 14px;
  margin-top: 14px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 12px;
}
.perm-legend .legend-sep {
  width: 1px;
  height: 14px;
  background: var(--border);
  margin: 0 4px;
}

/* Permission matrix */
.perm-matrix th { background: var(--card-2); }
.perm-matrix .perm {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 500;
  border: 1px solid;
}
.perm.full { background: var(--cyan-dim); color: var(--cyan); border-color: rgba(var(--cyan-rgb),0.3); }
.perm.view { background: rgba(167,139,250,0.12); color: var(--violet); border-color: rgba(167,139,250,0.3); }
.perm.none { background: rgba(255,255,255,0.03); color: var(--text-3); border-color: var(--border); }

/* SMS tabs */
.sms-tabs {
  display: flex;
  gap: 4px;
  padding: 3px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
}
.sms-tab {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--text-2);
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: background 140ms, color 140ms;
  position: relative;
}
.sms-tab:hover { color: var(--text); }
.sms-tab.active {
  background: var(--card);
  color: var(--text);
  box-shadow: 0 1px 4px rgba(0,0,0,0.25);
}
.sms-tab .ct {
  font-size: 10px;
  background: var(--bg);
  padding: 1px 6px;
  border-radius: 999px;
  font-family: 'JetBrains Mono', monospace;
  color: var(--text-3);
}
.sms-tab.active .ct {
  background: var(--cyan-dim);
  color: var(--cyan);
}

/* Device link in SMS */
.device-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(var(--cyan-rgb), 0.06);
  border: 1px solid rgba(var(--cyan-rgb), 0.18);
  border-radius: 6px;
  padding: 3px 8px;
  font-size: 11.5px;
  color: var(--cyan);
  cursor: pointer;
  transition: all 140ms;
  font-family: 'JetBrains Mono', monospace;
}
.device-link:hover {
  background: var(--cyan-dim);
  border-color: rgba(var(--cyan-rgb),0.4);
}

/* Чип имени пакета в настройках «Категории приложений» */
.pkg-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px 4px 10px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 7px;
  font-size: 12px;
  color: var(--text-2);
}
.pkg-chip-x {
  display: grid;
  place-items: center;
  width: 17px;
  height: 17px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text-3);
  cursor: pointer;
  transition: background 120ms, color 120ms;
}
.pkg-chip-x:hover { background: rgba(255,71,87,0.14); color: var(--danger); }

/* SMS rows */
@keyframes sms-in {
  from { opacity: 0; transform: translateX(-12px); }
  to { opacity: 1; transform: none; }
}
@keyframes fade-slide-in {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}
@keyframes expand-down {
  from { opacity: 0; max-height: 0; transform: translateY(-4px); }
  to { opacity: 1; max-height: 600px; transform: none; }
}
@keyframes select-pop-in {
  from { opacity: 0; transform: translateY(-4px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
@keyframes tab-fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: none; }
}
@keyframes row-enter {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}
.row-enter { animation: row-enter 200ms ease both; }
@media (prefers-reduced-motion: reduce) { .row-enter { animation: none; } }
@keyframes apk-card-slide-down {
  from { opacity: 0; max-height: 0; transform: translateY(-6px); }
  to { opacity: 1; max-height: 800px; transform: none; }
}
.sms-row:hover {
  background: rgba(var(--cyan-rgb), 0.04);
}
/* Unread indicator is now only a left dot in the message, no full-row tint */

/* SMS archive button — clear column */
.sms-archive-btn {
  display: grid;
  place-items: center;
  width: 32px;
  height: 28px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text-3);
  cursor: pointer;
  transition: all 140ms;
}
.sms-archive-btn:hover {
  color: var(--cyan);
  background: var(--cyan-dim);
  border-color: rgba(var(--cyan-rgb), 0.3);
}

/* Density toggle (segmented icon group) */
.density-toggle {
  display: inline-flex;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
.density-toggle button {
  padding: 6px 9px;
  color: var(--text-3);
  background: transparent;
  border: 0;
  cursor: pointer;
  border-right: 1px solid var(--border);
  transition: background 140ms, color 140ms;
}
.density-toggle button:last-child { border-right: 0; }
.density-toggle button:hover { color: var(--text-2); }
.density-toggle button.active {
  background: var(--cyan-dim);
  color: var(--cyan);
  /* inset box-shadow обрезался у крайней левой кнопки из-за overflow:hidden родителя.
     Заменили на верх/низ-only border-color чтобы edge-кнопки выглядели одинаково. */
  border-top: 1px solid rgba(var(--cyan-rgb), 0.5);
  border-bottom: 1px solid rgba(var(--cyan-rgb), 0.5);
  margin-top: -1px;
  margin-bottom: -1px;
}

/* Saved views row */
.saved-views {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* Toggle disabled */
.toggle.disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.btn.primary.danger {
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
  box-shadow: 0 0 12px rgba(255, 71, 87, 0.35);
}
.btn.primary.danger:hover { background: #ff6c79; }

/* ============================ HOME PAGE ============================ */
.home-hero {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 24px;
  align-items: center;
  padding: 12px 0 24px;
  border-bottom: 1px solid var(--border);
}
.home-shortcuts {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
/* KPI-карточка hero-стиль: ДОМИНИРУЕТ число (28px bold), подпись subscript (11.5px).
   Иконка — decoration в правом верхнем углу. Раньше всё было наоборот (лейбл главное, цифра sub). */
.home-shortcut {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 16px 18px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 12px;
  color: var(--text);
  cursor: pointer;
  text-align: left;
  transition: border-color 140ms, transform 140ms, background 140ms, box-shadow 240ms;
  min-width: 150px;
  min-height: 100px;
  overflow: hidden;
}
.home-shortcut:hover {
  border-color: var(--cyan);
  background: var(--card-2);
  transform: translateY(-1px);
}
.home-shortcut:active { transform: scale(0.98); }
.home-shortcut.flash {
  border-color: var(--cyan);
  background: var(--card-2);
  box-shadow: 0 0 0 1px rgba(var(--cyan-rgb), 0.35), 0 0 22px rgba(var(--cyan-rgb), 0.22);
  transform: scale(0.99);
}
.shortcut-delta {
  display: inline-flex;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.3px;
  vertical-align: middle;
  font-family: 'JetBrains Mono', monospace;
  animation: navpop 220ms ease;
}
.shortcut-delta.up { background: var(--green-dim); color: var(--green); border: 1px solid rgba(0,255,136,0.3); }
.shortcut-delta.down { background: var(--danger-dim); color: var(--danger); border: 1px solid rgba(255,71,87,0.3); }
/* Иконка — decoration в правом верхнем углу, не занимает место в потоке */
.home-shortcut > svg {
  position: absolute;
  top: 14px;
  right: 16px;
  color: var(--cyan);
  opacity: 0.4;
  transition: opacity 140ms;
}
.home-shortcut:hover > svg { opacity: 0.85; }
/* Подпись (label) — теперь supporting текст НАВЕРХУ caption-стилем */
.home-shortcut .lbl {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text-2);
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
/* Hero-число — ДОМИНИРУЕТ */
.home-shortcut .sub {
  font-size: 24px;
  font-weight: 600;
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: -0.5px;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  margin-top: 2px;
}
/* Под hero-числом мелкий пояснительный текст (опционально через .sub-hint) */
.home-shortcut .sub-hint {
  font-size: 11px;
  color: var(--text-3);
  margin-top: 2px;
}

/* Announcement */
.announcement {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  position: relative;
  transition: border-color 140ms;
}
.announcement:hover { border-color: var(--border-2); }
.announcement.pinned {
  border-color: rgba(var(--cyan-rgb), 0.3);
  background: linear-gradient(180deg, var(--cyan-dim) 0%, var(--card-2) 100%);
}
.announcement.flash {
  border-color: var(--cyan);
  box-shadow: 0 0 0 1px rgba(var(--cyan-rgb), 0.45), 0 0 24px rgba(var(--cyan-rgb), 0.18);
  transition: border-color 600ms ease, box-shadow 600ms ease;
}
.pin-marker {
  position: absolute;
  top: -10px;
  left: 16px;
  background: var(--bg-2);
  border: 1px solid rgba(var(--cyan-rgb), 0.4);
  color: var(--cyan);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.5px;
  padding: 3px 9px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  gap: 5px;
  text-transform: uppercase;
}

/* Changelog */
.changelog-row {
  padding: 12px 0;
  border-bottom: 1px dashed var(--border);
}
.changelog-row:last-child { border-bottom: 0; padding-bottom: 0; }
.changelog-list {
  margin: 0;
  padding-left: 18px;
  font-size: 13px;
  color: var(--text-2);
  line-height: 1.7;
}
.changelog-list li::marker { color: var(--cyan); }

.changelog-form {
  background: var(--card-2);
  border: 1px solid rgba(var(--cyan-rgb), 0.25);
  border-radius: 10px;
  padding: 14px;
  margin-bottom: 16px;
}
/* Collapsible wrapper for forms (smooth open/close without unmount) */
.collapsible {
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 240ms cubic-bezier(0.2, 0.7, 0.3, 1), opacity 200ms ease;
  pointer-events: none;
}
.collapsible.open {
  max-height: 1400px;
  opacity: 1;
  pointer-events: auto;
}
.changelog-textarea {
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 12px;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
  line-height: 1.6;
  resize: vertical;
  outline: none;
  min-height: 100px;
}
/* Announcement form */
.ann-form {
  background: var(--card-2);
  border: 1px solid rgba(var(--cyan-rgb), 0.25);
  border-radius: 10px;
  padding: 14px;
  margin-bottom: 14px;
}
.ann-form-h {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 12px;
  margin-bottom: 12px;
  border-bottom: 1px solid var(--border);
}

.ann-cats {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
}
.cat-chip {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 0;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  color: var(--text-2);
  font-size: 12px;
  transition: all 140ms;
}
.cat-chip:not(.cat-add):not(.active):hover { border-color: var(--border-2); }
.cat-chip.active {
  border-color: var(--cat-color, var(--cyan));
  background: rgba(var(--cyan-rgb), 0.08);
  color: var(--text);
}
.cat-chip-main {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px 5px 10px;
  background: transparent;
  border: 0;
  cursor: pointer;
  color: inherit;
  font-size: 12px;
}
.cat-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.cat-edit {
  display: grid; place-items: center;
  width: 18px; height: 18px;
  background: transparent;
  border: 0;
  color: var(--text-3);
  cursor: pointer;
  border-radius: 50%;
  transition: all 140ms;
  opacity: 0;
}
.cat-chip:hover .cat-edit { opacity: 1; }
.cat-edit:hover { background: var(--card); color: var(--cyan); }
.cat-x {
  display: grid; place-items: center;
  width: 18px; height: 18px;
  background: transparent;
  border: 0;
  color: var(--text-3);
  cursor: pointer;
  margin-right: 4px;
  border-radius: 50%;
  transition: all 140ms;
  opacity: 0;
}
.cat-chip:hover .cat-x { opacity: 1; }
.cat-x:hover { background: rgba(255,71,87,0.15); color: var(--danger); }
.cat-chip.cat-add {
  border-style: dashed;
  color: var(--text-3);
  padding: 5px 12px 5px 10px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 12px;
}
.cat-chip.cat-add:hover {
  color: var(--cyan);
  border-color: var(--cyan);
  border-style: solid;
}
.cat-add-row {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px;
}
.cat-colors {
  display: flex;
  gap: 4px;
}
.cat-colors button {
  width: 20px; height: 20px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  padding: 0;
  transition: transform 120ms;
}
.cat-colors button:hover { transform: scale(1.1); }
.cat-colors button.sel { border-color: var(--text); }

/* Notes */
.note-input {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px;
}
.note-input textarea {
  width: 100%;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--text);
  font-size: 13px;
  resize: none;
  min-height: 50px;
  font-family: inherit;
  line-height: 1.5;
}
.note-colors {
  display: flex;
  gap: 8px;
}
.note-colors .nc {
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform 150ms ease, box-shadow 150ms ease, border-color 150ms ease;
  padding: 0;
  outline: 0;
}
.note-colors .nc:hover { transform: scale(1.15); }
.note-colors .nc.sel {
  border-color: var(--bg);
  transform: scale(1.15);
  box-shadow: 0 0 0 2px var(--text), 0 0 10px rgba(255,255,255,0.12);
}

/* visible-feedback + минимализм: красная "Очистить всё" по дефолту приглушена,
   проявляется при ховере на шапку заметок - чтобы не спорила за внимание с серым каунтером. */
.notes-clear-btn { opacity: 0.5; transition: opacity 160ms ease; }
.notes-card-h:hover .notes-clear-btn,
.notes-clear-btn:focus-visible,
.notes-clear-btn:hover { opacity: 1; }

.note {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 11px 12px;
  border: 1px solid;
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.5;
  transition: opacity 140ms;
}
.note.done { opacity: 0.55; }
.note.done .note-text { text-decoration: line-through; color: var(--text-3); }
.note-check {
  width: 18px; height: 18px;
  border-radius: 5px;
  border: 1.5px solid;
  background: transparent;
  cursor: pointer;
  flex-shrink: 0;
  margin-top: 1px;
  display: grid;
  place-items: center;
  padding: 0;
}
.note-text {
  flex: 1;
  color: var(--text);
}
.note-x {
  background: transparent;
  border: 0;
  color: var(--text-3);
  cursor: pointer;
  padding: 2px;
  border-radius: 4px;
  opacity: 0;
  transition: opacity 140ms, color 140ms;
}
.note:hover .note-x { opacity: 1; }
.note-x:hover { color: var(--danger); }

/* Fixed-height scrollable notes area */
.notes-scroll {
  max-height: 360px;
  overflow-y: auto;
  padding-right: 4px;
  margin-right: -4px;
  scrollbar-gutter: stable;
}

@media (max-width: 1100px) {
  .home-hero { grid-template-columns: 1fr; }
  .home-shortcuts { grid-template-columns: repeat(2, 1fr); }
}

/* ============================ DEVICES PAGE ============================ */

/* Drill banner */
.drill-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--cyan-dim);
  border: 1px solid rgba(var(--cyan-rgb), 0.3);
  border-radius: 10px;
  padding: 10px 14px;
}

/* Header row */
.dev-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 18px;
}
.dev-bulk {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px 6px 12px;
  background: var(--card);
  border: 1px solid rgba(var(--cyan-rgb), 0.3);
  border-radius: 10px;
  animation: navpop 180ms ease;
}

/* Toolbar */
.dev-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 16px;
  flex-wrap: wrap;
}
.dev-search {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 12px;
  min-width: 220px;
  flex: 1;
}
.dev-search input {
  flex: 1;
  background: transparent;
  border: 0;
  outline: 0;
  color: var(--text);
  font-size: 13px;
  min-width: 0;
}
.dev-search-clear {
  background: transparent;
  border: 0;
  color: var(--text-3);
  cursor: pointer;
  padding: 2px;
  border-radius: 4px;
  display: grid;
  place-items: center;
}
.dev-search-clear:hover { color: var(--text); background: var(--card); }

.dev-select {
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 30px 7px 12px;
  color: var(--text);
  font-size: 12.5px;
  outline: none;
  cursor: pointer;
  transition: border-color 140ms;
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--text-2) 50%), linear-gradient(135deg, var(--text-2) 50%, transparent 50%);
  background-position: calc(100% - 14px) 13px, calc(100% - 9px) 13px;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}
.dev-select:hover { border-color: var(--border-2); }
.dev-select:focus { border-color: var(--cyan); }

/* Saved views dropdown */
.views-dd { position: relative; }
.views-pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 260px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 10px;
  padding: 8px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.5);
  z-index: 60;
  animation: dropdown-in 140ms ease-out both;
  transform-origin: top center;
}
.views-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 7px;
  cursor: pointer;
  font-size: 13px;
  background: transparent;
  border: 0;
  width: 100%;
  text-align: left;
  color: var(--text);
  transition: background 120ms;
}
.views-item:hover { background: var(--card); }
.views-item.active { background: var(--cyan-dim); color: var(--cyan); }
.views-item.add { color: var(--text-2); justify-content: center; padding: 8px; }
.views-item.add:disabled { opacity: 0.4; cursor: not-allowed; }
.views-item .x {
  background: transparent;
  border: 0;
  color: var(--text-3);
  cursor: pointer;
  padding: 3px;
  border-radius: 4px;
  display: grid; place-items: center;
}
.views-item:hover .x { color: var(--text); }
.views-item .x:hover { color: var(--danger); background: rgba(255,71,87,0.1); }

/* Anomaly cause block */
.anomaly-cause {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.anomaly-cause .ac-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
.anomaly-cause .ac-row:last-child { border-bottom: 0; }
.anomaly-cause .ac-label {
  font-size: 11.5px;
  color: var(--text-3);
  letter-spacing: 0.4px;
  text-transform: uppercase;
  flex: 1;
  min-width: 0;
}

/* Color swatch in modals */
.color-swatch {
  width: 32px; height: 32px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  padding: 0;
  transition: transform 120ms;
}
.color-swatch:hover { transform: scale(1.1); }
.color-swatch.sel { border-color: var(--text); box-shadow: 0 0 0 3px var(--bg-2); }
.color-swatch-add {
  background: var(--card-2);
  border: 1px dashed var(--border-2);
  color: var(--text-3);
  display: grid;
  place-items: center;
  transition: border-color 140ms, color 140ms, transform 120ms;
}
.color-swatch-add:hover { color: var(--cyan); border-color: var(--cyan); }
.color-swatch-add.sel { border-style: solid; border-color: var(--cyan); color: var(--cyan); box-shadow: none; }
.custom-color-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.cc-swatch {
  position: relative;
  width: 34px;
  height: 34px;
  border-radius: 8px;
  border: 1px solid var(--border-2);
  cursor: pointer;
  flex-shrink: 0;
  overflow: hidden;
}

/* Permission matrix — clickable cells */
.perm-btn {
  cursor: pointer;
  background: transparent;
  font-family: inherit;
  font-size: 11px;
  font-weight: 500;
  transition: all 140ms;
}
.perm-btn:not(.locked):hover {
  filter: brightness(1.2);
  transform: scale(1.05);
}
.perm-btn.locked { cursor: not-allowed; opacity: 0.85; }

/* Filter applied toast */
@keyframes toast-in {
  from { opacity: 0; transform: translate(-50%, -10px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
.filter-toast {
  position: fixed;
  top: 90px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 200;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  background: var(--bg-2);
  border: 1px solid rgba(0, 255, 136, 0.35);
  border-radius: 10px;
  font-size: 13px;
  font-weight: 500;
  color: var(--text);
  box-shadow: 0 8px 24px rgba(0,0,0,0.4), 0 0 0 1px rgba(0,255,136,0.1);
  animation: toast-in 200ms ease;
}

/* Spinner */
@keyframes spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
.spin { animation: spin 0.9s linear infinite; }

/* visible-feedback: лёгкая active-pulse для уже активных tab/chip - чтобы клик не казался пустым */
@keyframes road24-tab-pulse {
  0% { transform: scale(1); }
  45% { transform: scale(0.97); }
  100% { transform: scale(1); }
}
.sms-tab.pulse, .chip.pulse { animation: road24-tab-pulse 120ms ease-out; }
.spinner {
  display: inline-block;
  width: 12px; height: 12px;
  border: 2px solid var(--border-2);
  border-top-color: var(--cyan);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}

/* Topbar role switcher */
.topnav-role { position: relative; }
.topnav-role-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color 140ms, background 140ms, color 140ms;
  white-space: nowrap;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 1;
  min-width: 0;
}
.topnav-role-btn > span { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.topnav-role-btn:hover { border-color: var(--border-2); }
.topnav-role-btn.preview {
  border-color: var(--warn);
  background: var(--warn-dim);
  color: var(--warn);
}

/* Role preview banner (sub-topbar) */
.role-preview-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 28px;
  background-color: var(--bg);
  background-image: linear-gradient(var(--warn-dim), var(--warn-dim));
  backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(255, 140, 0, 0.3);
  font-size: 12.5px;
  color: var(--text);
  position: sticky;
  top: 60px;
  z-index: 49;
  flex-wrap: nowrap;
  animation: navpop 200ms ease;
}
.role-preview-banner .grow { flex: 1; }
.role-preview-banner .rp-banner-sub {
  color: var(--text-3);
  flex-shrink: 0;
  padding: 2px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.03);
  line-height: 1.6;
}
@media (max-width: 720px) {
  .role-preview-banner { padding: 8px 16px; gap: 8px; }
  .rp-banner-sub { display: none; }
}
.role-picker { position: relative; min-width: 160px; }
.role-picker-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 12.5px;
  cursor: pointer;
  width: 100%;
  transition: border-color 140ms, background 140ms;
}
.role-picker-btn:hover { border-color: var(--border-2); }
.role-picker-btn.open { border-color: var(--cyan); background: var(--card); }
.role-picker-btn.disabled {
  opacity: 0.7;
  cursor: not-allowed;
  border-style: dashed;
}
.role-picker-btn > svg { margin-left: auto; }
.rp-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.role-picker-pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 280px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 10px;
  padding: 6px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.5);
  z-index: 80;
  max-height: 320px;
  overflow-y: auto;
  animation: navpop 140ms ease;
}
.role-picker-pop.up { top: auto; bottom: calc(100% + 6px); }
.role-picker-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 12px;
  background: transparent;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  width: 100%;
  color: var(--text);
  transition: background 120ms;
}
.role-picker-item:hover { background: var(--card); }
.role-picker-item.active { background: var(--cyan-dim); }
.role-picker-item:disabled { opacity: 0.4; cursor: not-allowed; }
.role-picker-item .rp-dot { margin-top: 5px; }
.rp-name { font-size: 13px; font-weight: 500; }
.rp-desc { font-size: 11.5px; color: var(--text-3); margin-top: 2px; line-height: 1.45; }

/* Кастомный селект (замена голых <select>) */
.ui-select { position: relative; width: 100%; }
.ui-select-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 8px;
  color: var(--text);
  font-size: 13px;
  cursor: pointer;
  text-align: left;
  transition: border-color 140ms, box-shadow 140ms, background 140ms;
}
.ui-select-btn:hover { border-color: var(--border-2); }
.ui-select-btn.open {
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px var(--cyan-dim);
}
.ui-select-btn.disabled { opacity: 0.5; cursor: not-allowed; }
.ui-select-val {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ui-select-chev {
  margin-left: auto;
  color: var(--text-3);
  flex-shrink: 0;
  transition: transform 160ms, color 160ms;
}
.ui-select-btn.open .ui-select-chev { transform: rotate(180deg); color: var(--cyan); }
.ui-select-pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 10px;
  padding: 6px;
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.5);
  z-index: 80;
  max-height: 280px;
  overflow-y: auto;
  animation: select-pop-in 140ms ease both;
  transform-origin: top center;
}
.ui-select-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 12px;
  background: transparent;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  color: var(--text);
  font-size: 13px;
  transition: background 120ms, color 120ms;
}
.ui-select-item-lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ui-select-item:hover { background: var(--card); }
.ui-select-item.active { background: var(--cyan-dim); color: var(--cyan); }

/* 2026-06-25 — строки выпадашки с action-кнопками (например, edit/delete на шаблонах APK). */
.ui-select-item-wactions { outline: none; }
.ui-select-item-wactions:focus-visible { box-shadow: inset 0 0 0 2px var(--cyan); }
.ui-select-item-actions {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-left: 8px;
  flex-shrink: 0;
}
.ui-select-item-act {
  width: 26px; height: 26px;
  border-radius: 6px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text-2);
  display: inline-grid; place-items: center;
  cursor: pointer;
  padding: 0;
  transition: color 120ms, background 120ms, border-color 120ms;
}
.ui-select-item-act:hover { color: var(--cyan); background: var(--card); border-color: var(--border); }
/* Деструктивные actions (удаление) — мягкий розовый #fb7185 как в «Забыть устройство». */
.ui-select-item-act-danger:hover { color: #fb7185; border-color: rgba(251,113,133,0.4); }

/* Страница "Доступ запрещён" */
.access-denied {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: grid;
  place-items: center;
  padding: 24px;
  background:
    radial-gradient(1200px 600px at 50% -10%, rgba(255, 71, 87, 0.12), transparent 60%),
    var(--bg);
  animation: adfade 240ms ease;
}
@keyframes adfade { from { opacity: 0; } to { opacity: 1; } }
.access-denied-card {
  max-width: 480px;
  width: 100%;
  text-align: center;
  background: var(--card);
  border: 1px solid var(--border-2);
  border-radius: 18px;
  padding: 40px 32px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
  animation: adpop 380ms cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes adpop {
  from { transform: translateY(18px) scale(0.95); opacity: 0; }
  to { transform: none; opacity: 1; }
}
.ad-icon {
  width: 84px;
  height: 84px;
  margin: 0 auto 24px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--danger);
  background: var(--danger-dim);
  border: 1px solid rgba(255, 71, 87, 0.35);
  position: relative;
}
.ad-icon::after {
  content: '';
  position: absolute;
  inset: -8px;
  border-radius: 50%;
  border: 2px solid var(--danger);
  opacity: 0.4;
  animation: adpulse 2s ease-out infinite;
}
@keyframes adpulse {
  0% { transform: scale(0.9); opacity: 0.5; }
  100% { transform: scale(1.5); opacity: 0; }
}
.access-denied-card h1 {
  font-size: 24px;
  margin: 0 0 10px;
  color: var(--text);
  font-weight: 700;
}
.access-denied-card p {
  color: var(--text-2);
  font-size: 14px;
  line-height: 1.6;
  margin: 0 0 18px;
}
.ad-ip { font-size: 13px; color: var(--text-2); margin-bottom: 18px; }
.ad-ip .mono { color: var(--danger); }
.ad-hint {
  font-size: 12.5px;
  color: var(--text-3);
  line-height: 1.55;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 24px;
}
.ad-actions { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* Групповой подзаголовок в матрице прав */
.perm-group-row td {
  background: var(--bg-2) !important;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-3);
  padding: 8px 12px !important;
}

/* Модалка выбора темы */
.theme-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.theme-card {
  text-align: left;
  background: var(--card-2);
  border: 1.5px solid var(--border);
  border-radius: 12px;
  padding: 10px;
  cursor: pointer;
  transition: border-color 140ms, transform 120ms;
}
.theme-card:hover { transform: translateY(-2px); border-color: var(--border-2); }
.theme-card.sel { border-color: var(--cyan); box-shadow: 0 0 0 3px var(--cyan-dim); }
.theme-preview {
  position: relative;
  height: 74px;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid rgba(255,255,255,0.08);
  padding: 9px;
}
.theme-preview-bar { height: 9px; width: 46%; border-radius: 3px; margin-bottom: 9px; }
.theme-preview-line { height: 6px; width: 80%; border-radius: 3px; margin-bottom: 6px; }
.theme-preview-line.short { width: 55%; }
.theme-preview-dot { position: absolute; right: 9px; bottom: 9px; width: 16px; height: 16px; border-radius: 50%; }
@media (max-width: 560px) { .theme-grid { grid-template-columns: 1fr; } }

/* Анимация смены вкладок */
.retention-tab {
  animation: tab-fade-in 180ms ease both;
}
@keyframes tabfade {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

/* Поле пароля с глазком */
.pw-form { display: flex; flex-direction: column; gap: 14px; }
.pw-wrap { position: relative; }
.pw-wrap .input { width: 100%; }
.pw-eye {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: 0;
  padding: 4px;
  cursor: pointer;
  color: var(--text-3);
  display: grid;
  place-items: center;
  transition: color 140ms;
}
.pw-eye:hover { color: var(--cyan); }

/* Мини-редактор текста алёрта */
.tpl-editor {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  margin: 0 0 12px;
  animation: navpop 160ms ease;
}
.tpl-editor code {
  font-family: var(--mono, monospace);
  font-size: 11px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 1px 5px;
  color: var(--cyan);
}
.tpl-textarea {
  width: 100%;
  resize: vertical;
  font-family: inherit;
  line-height: 1.45;
}
.tpl-preview {
  margin-top: 10px;
  padding: 10px 12px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
}

/* Invite role grid */
.role-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}
.role-card-btn {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  text-align: left;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  cursor: pointer;
  transition: all 140ms;
}
.role-card-btn:hover { border-color: var(--border-2); }
.role-card-btn.active {
  border-color: var(--cyan);
  background: var(--cyan-dim);
}

/* Invite preview */
.invite-preview {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.invite-preview-h {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--border);
  font-size: 11.5px;
  color: var(--text-3);
  letter-spacing: 0.4px;
  text-transform: uppercase;
}
.invite-preview-body {
  padding: 16px;
}
.invite-preview-form {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.invite-preview-form .input {
  background: var(--card-2);
  border-style: dashed;
}
.funnel-v3 {
  padding: 4px 0;
}
.funnel-hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  background: linear-gradient(135deg, rgba(var(--cyan-rgb),0.10) 0%, rgba(var(--cyan-rgb),0.02) 100%);
  border: 1px solid rgba(var(--cyan-rgb), 0.18);
  border-radius: 12px;
  margin-bottom: 20px;
}
.fh-left {
  display: flex;
  align-items: center;
  gap: 18px;
}
.fh-from, .fh-to {
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.5px;
  color: var(--text);
}
.fh-from { opacity: 0.7; }
.fh-arc {
  text-align: right;
}
.fh-arc-pct {
  font-family: 'JetBrains Mono', monospace;
  font-size: 44px;
  font-weight: 700;
  color: var(--cyan);
  letter-spacing: -1px;
  line-height: 1;
}
.fh-arc-lbl {
  font-size: 12px;
  letter-spacing: 0.9px;
  text-transform: uppercase;
  color: var(--text-2);
  margin-top: 4px;
}

/* Horizontal flow */
.funnel-flow {
  display: flex;
  align-items: stretch;
  gap: 12px;
  height: 96px;
  margin-bottom: 16px;
  padding-right: 28px;
}
.ff-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-width: 110px;
  transition: filter 200ms;
}
.ff-stage:hover { filter: brightness(1.15); }
.ff-bar {
  height: 44px;
  background: var(--stage-color);
  border-radius: 6px;
  box-shadow: 0 0 10px var(--stage-color), inset 0 1px 0 rgba(255,255,255,0.15);
  opacity: 0.85;
  transition: opacity 140ms;
}
.ff-stage:hover .ff-bar { opacity: 1; }
.ff-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 2px 0;
  min-width: 0;
}
.ff-name {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ff-stats {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.ff-count {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  font-family: 'JetBrains Mono', monospace;
}
.ff-pct {
  font-size: 11px;
  color: var(--stage-color);
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
}
.ff-drop {
  position: absolute;
  top: -12px;
  right: -10px;
  z-index: 2;
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--text-3);
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 999px;
  white-space: nowrap;
}
.ff-drop.worst {
  border-color: rgba(255, 71, 87, 0.4);
  color: var(--danger);
  background: var(--danger-dim);
}
.ff-stage.worst .ff-bar {
  box-shadow: 0 0 12px var(--stage-color), inset 0 1px 0 rgba(255,255,255,0.15), 0 0 0 2px rgba(255,71,87,0.35);
}

.funnel-callout {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  background: var(--danger-dim);
  border: 1px solid rgba(255, 71, 87, 0.25);
  border-radius: 8px;
  font-size: 13px;
  color: var(--text-2);
}
.funnel-callout strong { color: var(--text); font-weight: 500; }

@media (max-width: 900px) {
  .funnel-hero { flex-direction: column; align-items: flex-start; gap: 12px; }
  .funnel-flow { flex-direction: column; height: auto; }
  .ff-stage { min-width: 100%; }
  .ff-bar { width: var(--stage-w, 100%); }
  .ff-drop { position: static; align-self: flex-end; margin-top: 4px; }
}
.funnel-v2 {
  padding: 4px 0;
}
.funnel-summary {
  display: flex;
  align-items: stretch;
  gap: 20px;
  padding: 16px 20px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  margin-bottom: 20px;
}
.fs-item {
  flex: 1;
  min-width: 0;
}
.fs-item .fs-label {
  font-size: 10.5px;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 6px;
}
.fs-item .fs-value {
  font-size: 22px;
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
  letter-spacing: -0.4px;
  color: var(--text);
}
.fs-divider {
  width: 1px;
  background: var(--border);
}

.funnel-stages {
  display: grid;
  grid-template-columns: 1fr 80px 1fr 80px 1fr 80px 1fr;
  align-items: stretch;
  gap: 0;
}
.funnel-stage {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-top: 3px solid var(--stage-color, var(--cyan));
  border-radius: 10px;
  padding: 18px 18px 16px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  transition: transform 200ms, border-color 200ms, box-shadow 200ms;
  cursor: default;
}
.funnel-stage:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}
.funnel-stage .fs-head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.funnel-stage .fs-num {
  width: 22px; height: 22px;
  border-radius: 6px;
  background: var(--stage-color);
  color: #001016;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  display: grid;
  place-items: center;
  box-shadow: 0 0 10px rgba(var(--cyan-rgb), 0.25);
  flex-shrink: 0;
}
.funnel-stage .fs-name {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.funnel-stage .fs-count {
  font-family: 'JetBrains Mono', monospace;
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.5px;
  color: var(--text);
}
.funnel-stage .fs-bar-wrap {
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.04);
  overflow: hidden;
}
.funnel-stage .fs-bar {
  height: 100%;
  background: var(--stage-color);
  border-radius: 2px;
  box-shadow: 0 0 6px var(--stage-color);
  transition: width 600ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.funnel-stage .fs-meta {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 11.5px;
}
.funnel-stage .fs-meta-pct {
  color: var(--stage-color);
  font-weight: 600;
  font-size: 13px;
}

/* Connector arrow */
.funnel-connector {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--text-3);
  padding: 0 4px;
  gap: 8px;
}
.funnel-connector svg {
  opacity: 0.5;
  transition: opacity 140ms, color 140ms;
}
.funnel-connector .fc-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
}
.funnel-connector .fc-pct {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-2);
}
.funnel-connector .fc-lost {
  font-size: 9.5px;
  color: var(--text-3);
  font-family: 'JetBrains Mono', monospace;
  white-space: nowrap;
}
.funnel-connector.worst {
  color: var(--danger);
}
.funnel-connector.worst svg { opacity: 1; }
.funnel-connector.worst .fc-pct { color: var(--danger); }
.funnel-connector.worst .fc-lost { color: rgba(255, 71, 87, 0.7); }

@media (max-width: 1100px) {
  .funnel-stages {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .funnel-connector {
    flex-direction: row;
    justify-content: center;
    padding: 4px 0;
  }
  .funnel-connector svg { transform: rotate(90deg); }
  .funnel-summary {
    flex-wrap: wrap;
    gap: 14px;
  }
  .fs-divider { display: none; }
}
.styled-select { position: relative; flex: 1; min-width: 0; }
.styled-select-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 12px;
  color: var(--text);
  font-size: 12.5px;
  cursor: pointer;
  transition: border-color 140ms, background 140ms;
  white-space: nowrap;
}
.styled-select-btn:hover { border-color: var(--border-2); }
.styled-select-btn.open {
  border-color: var(--cyan);
  background: var(--card);
}
@keyframes dropdown-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: none; }
}
.styled-select-pop {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 100%;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 10px;
  padding: 6px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.5);
  z-index: 60;
  animation: dropdown-in 140ms ease-out both;
  transform-origin: top center;
  max-height: 320px;
  overflow-y: auto;
}
.styled-select-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12.5px;
  background: transparent;
  border: 0;
  width: 100%;
  text-align: left;
  color: var(--text);
  transition: background 120ms;
  white-space: nowrap;
}
.styled-select-item:hover { background: var(--card); }
.styled-select-item.active { background: var(--cyan-dim); color: var(--cyan); }
.styled-select-item .dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* USSD templates inside action modal */
.ussd-tpl-form {
  background: var(--bg-2);
  border: 1px solid rgba(var(--cyan-rgb), 0.25);
  border-radius: 6px;
  padding: 10px;
  margin-bottom: 8px;
  animation: navpop 160ms ease;
}
.ussd-tpl {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  margin-top: 4px;
}
.ussd-tpl-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 220px;
  overflow-y: auto;
  padding-right: 4px;
  margin-right: -4px;
  scrollbar-gutter: stable;
}
.ussd-tpl-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  border: 1px solid transparent;
  transition: background 140ms, border-color 140ms;
}
.ussd-tpl-item:hover { background: var(--card); }
.ussd-tpl-item.active {
  background: var(--cyan-dim);
  border-color: rgba(var(--cyan-rgb), 0.3);
}
.ussd-tpl-apply {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  background: transparent;
  border: 0;
  cursor: pointer;
  padding: 0;
  text-align: left;
  color: var(--text);
  min-width: 0;
}
.ussd-tpl-code {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--cyan);
  min-width: 60px;
  letter-spacing: 0.2px;
}
.ussd-tpl-name {
  font-size: 12.5px;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ussd-tpl-author {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: #001016;
  font-weight: 700;
  font-size: 9.5px;
  flex-shrink: 0;
  font-family: 'JetBrains Mono', monospace;
}
.ussd-tpl-del {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: var(--text-3);
  cursor: pointer;
  opacity: 0;
  transition: opacity 140ms, color 140ms, background 140ms;
}
.ussd-tpl-item:hover .ussd-tpl-del { opacity: 1; }
.ussd-tpl-del:hover { color: var(--danger); background: rgba(255,71,87,0.12); }

/* Success modal */
@keyframes success-pop {
  0% { transform: scale(0.5); opacity: 0; }
  60% { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes success-ring {
  0% { transform: scale(0.8); opacity: 0.8; }
  100% { transform: scale(2.4); opacity: 0; }
}
.success-modal {
  padding: 32px 28px 24px;
  text-align: center;
}
.success-burst {
  position: relative;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: linear-gradient(135deg, #00ff88, #00cc6c);
  display: grid;
  place-items: center;
  margin: 0 auto 4px;
  box-shadow: 0 0 24px rgba(0, 255, 136, 0.45);
  animation: success-pop 360ms cubic-bezier(0.2, 0.9, 0.3, 1.4);
}
.success-burst::before,
.success-burst::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid rgba(0, 255, 136, 0.7);
  animation: success-ring 900ms ease-out forwards;
}
.success-burst::after {
  animation-delay: 180ms;
}

.archive-info {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 4px 16px;
  text-align: left;
}
.archive-info .ar-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
}
.archive-info .ar-row:last-child { border-bottom: 0; }
.ussd-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 360px;
  overflow-y: auto;
  padding-right: 4px;
  margin-right: -4px;
  scrollbar-gutter: stable;
  transition: mask-image 200ms;
}
/* Плавное затухание снизу — подсказка, что список можно прокрутить дальше.
   Появляется только когда внизу есть ещё контент (класс ставится из JS). */
.ussd-list.has-more {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent);
}

.sim-history-scroll {
  max-height: 360px;
  overflow-y: auto;
  padding-right: 4px;
  margin-right: -4px;
  scrollbar-gutter: stable;
}
.ussd-item {
  background: rgba(0,0,0,0.22);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ussd-cmd, .ussd-resp {
  display: flex;
  align-items: center;
  gap: 10px;
}
.ussd-arrow {
  width: 22px; height: 22px;
  border-radius: 50%;
  display: grid; place-items: center;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  font-weight: 700;
  flex-shrink: 0;
}
.ussd-arrow.out { background: var(--violet-dim); color: var(--violet); border: 1px solid rgba(167,139,250,0.3); }
.ussd-arrow.in { background: var(--green-dim); color: var(--green); border: 1px solid rgba(0,255,136,0.3); }
.ussd-cmd-body { flex: 1; min-width: 0; }
.ussd-cmd-label {
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 1px;
}
.ussd-cmd-code {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}
.ussd-resp-text {
  font-size: 13px;
  color: var(--text);
}
.ussd-cmd-tag {
  padding: 2px 8px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 999px;
}
.apps-hero {
  display: flex;
  align-items: stretch;
  gap: 20px;
  padding: 16px 22px;
  background: linear-gradient(135deg, rgba(var(--cyan-rgb),0.05) 0%, rgba(var(--cyan-rgb),0.02) 100%);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.apps-hero-item { flex: 1; min-width: 0; }
.apps-hero-item .muted.tiny { font-size: 10.5px; letter-spacing: 0.5px; text-transform: uppercase; }
.apps-hero-v {
  font-family: 'JetBrains Mono', monospace;
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.5px;
  color: var(--text);
  margin: 4px 0 2px;
  line-height: 1;
}
.apps-hero-divider { width: 1px; background: var(--border); }

.apps-groups {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.apps-group { }
.apps-group-h {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
  padding: 0 4px;
}
.apps-group-name {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--text-3);
}
.apps-group-ct {
  font-size: 10px;
  color: var(--text-3);
  background: var(--card-2);
  padding: 1px 7px;
  border-radius: 999px;
  border: 1px solid var(--border);
}
.apps-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 8px;
}
.app-card {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  transition: border-color 140ms, transform 140ms;
}
.app-card:hover {
  border-color: var(--border-2);
  transform: translateY(-1px);
}
.app-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 6px currentColor;
}
.app-info {
  flex: 1;
  min-width: 0;
}
.app-name {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 2px;
}
.app-pkg {
  font-size: 10.5px;
  color: var(--text-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 5px;
}
.app-match {
  display: flex;
  align-items: center;
  gap: 8px;
}
.app-match-bar {
  flex: 1;
  height: 4px;
  background: rgba(255,255,255,0.04);
  border-radius: 2px;
  overflow: hidden;
}
.app-match-fill {
  height: 100%;
  border-radius: 2px;
  transition: width 240ms;
}
.tl-hero {
  display: flex;
  align-items: stretch;
  gap: 20px;
  padding: 18px 22px;
  background: linear-gradient(135deg, rgba(var(--cyan-rgb),0.05) 0%, rgba(0,255,136,0.03) 100%);
  border: 1px solid var(--border);
  border-radius: 12px;
  margin-bottom: 18px;
}
.tl-hero-item { flex: 1; min-width: 0; }
.tl-hero-item .muted.tiny { font-size: 10.5px; letter-spacing: 0.5px; text-transform: uppercase; }
.tl-hero-v {
  font-family: 'JetBrains Mono', monospace;
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.5px;
  color: var(--text);
  margin: 4px 0 2px;
  line-height: 1;
}
.tl-hero-divider {
  width: 1px;
  background: var(--border);
}

.tl-chart-card {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
  overflow: hidden;
}
.tl-chart-card svg {
  width: 100%;
  height: auto;
}

.tl-detail {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 16px 18px;
}
.tl-ticks-row,
.tl-row {
  display: grid;
  grid-template-columns: 56px 1fr 64px;
  align-items: center;
  gap: 14px;
  padding: 6px 0;
}
.tl-ticks-row {
  padding: 0 4px 8px;
  color: var(--text-3);
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}
.tl-row {
  padding: 10px 4px;
  border-top: 1px solid var(--border);
}
.tl-row:first-of-type { border-top: 0; }
.tl-day-col { font-size: 13px; font-weight: 600; color: var(--text); padding-left: 4px; }
.tl-day-col .tl-day-name { padding-left: 0; }
.tl-pct-col { text-align: right; padding-right: 4px; font-size: 13px; }
.tl-track-col {
  position: relative;
  height: 22px;
  background: rgba(255,255,255,0.02);
  border-radius: 5px;
  overflow: hidden;
}
.tl-ticks-row .tl-track-col {
  background: transparent;
  height: 14px;
  overflow: visible;
}
.tl-ticks-row .tl-pct-col,
.tl-ticks-row .tl-day-col { font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-3); font-weight: 400; }
.tl-tick {
  position: absolute; top: 0;
  transform: translateX(-50%);
}
.tl-tick-label { font-size: 9.5px; }
.tl-grid {
  position: absolute;
  top: 0; bottom: 0;
  width: 1px;
  background: rgba(255,255,255,0.04);
}
.tl-night {
  position: absolute;
  top: 0; bottom: 0;
  background: rgba(0,0,0,0.18);
  border-left: 1px solid var(--border);
  border-right: 1px solid var(--border);
}
.tl-session {
  position: absolute;
  top: 3px; bottom: 3px;
  background: linear-gradient(180deg, #00ff88 0%, #00cc6c 100%);
  border-radius: 3px;
  box-shadow: 0 0 8px rgba(0,255,136,0.35), inset 0 1px 0 rgba(255,255,255,0.18);
  min-width: 3px;
  cursor: pointer;
  transition: transform 140ms, box-shadow 140ms, filter 140ms;
}
.tl-session:hover {
  transform: scaleY(1.15);
  filter: brightness(1.1);
  box-shadow: 0 0 14px rgba(0,255,136,0.55), inset 0 1px 0 rgba(255,255,255,0.25);
  z-index: 2;
}
.tl-legend {
  display: flex;
  gap: 16px;
  padding-top: 14px;
  margin-top: 8px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}

@media (max-width: 800px) {
  .tl-hero { flex-direction: column; gap: 12px; padding: 14px; }
  .tl-hero-divider { display: none; }
}
.timeline-v2 {
  display: flex;
  flex-direction: column;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  overflow: hidden;
}
.timeline-v2-ticks {
  display: grid;
  grid-template-columns: 60px 1fr 70px;
  align-items: center;
  padding: 0 4px 8px;
  font-size: 10px;
  color: var(--text-3);
  gap: 12px;
}
.timeline-v2-ticks .tlv-uptime-col {
  text-align: right;
  font-size: 10px;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--text-3);
  padding-right: 14px;
  font-weight: 400;
}
.tlv-row {
  display: grid;
  grid-template-columns: 60px 1fr 70px;
  align-items: center;
  padding: 12px 4px;
  border-bottom: 1px solid var(--border);
  gap: 12px;
}
.tlv-row:last-child { border-bottom: 0; }
.tlv-day-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-left: 14px;
}
.tlv-day-label .day {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}
.tlv-track {
  position: relative;
  height: 28px;
  background: rgba(255, 255, 255, 0.025);
  border-radius: 6px;
  overflow: hidden;
}
.tlv-grid-line {
  position: absolute;
  top: 0; bottom: 0;
  width: 1px;
  background: rgba(255, 255, 255, 0.04);
}
.tlv-tick {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
}
.tlv-tick-label {
  font-size: 9.5px;
  color: var(--text-3);
}
.tlv-session {
  position: absolute;
  top: 4px; bottom: 4px;
  background: linear-gradient(180deg, #00ff88, #00cc6c);
  border-radius: 3px;
  box-shadow: 0 0 8px rgba(0, 255, 136, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.15);
  transition: transform 140ms;
  min-width: 3px;
}
.tlv-session:hover {
  transform: scaleY(1.1);
  box-shadow: 0 0 12px rgba(0, 255, 136, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.2);
  z-index: 2;
}
.tlv-uptime-col {
  text-align: right;
  font-size: 14px;
  font-weight: 600;
  padding-right: 14px;
}

.tlv-stat {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.tlv-stat-v {
  font-family: 'JetBrains Mono', monospace;
  font-size: 22px;
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.4px;
  margin-top: 2px;
}

/* ============================ PERMISSIONS LIST ============================ */
.perm-group {
  margin-bottom: 16px;
}
.perm-group:last-child { margin-bottom: 0; }
.perm-group-label {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.7px;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 6px;
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
}
.perm-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 0;
  border-bottom: 1px dashed var(--border);
}
.perm-row:last-child { border-bottom: 0; }
.perm-info {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.perm-name {
  font-size: 12.5px;
  color: var(--text);
}
.perm-key {
  font-size: 10.5px;
  color: var(--text-3);
  letter-spacing: 0.2px;
}

.comment-btn {
  position: relative;
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 9px;
  color: var(--text-3);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  transition: all 140ms;
  min-width: 32px;
  line-height: 1;
}
.comment-btn:hover {
  color: var(--text);
  border-color: var(--border-2);
}
.comment-btn.has {
  color: var(--cyan);
  background: var(--cyan-dim);
  border-color: rgba(var(--cyan-rgb), 0.3);
}
.comment-btn .ct {
  font-size: 10.5px;
  font-weight: 600;
  font-family: 'JetBrains Mono', monospace;
  line-height: 1;
}

@keyframes comment-pop-in {
  from { opacity: 0; transform: scale(0.95); }
  to { opacity: 1; transform: scale(1); }
}
.comment-pop {
  position: absolute;
  width: 360px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 12px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.5);
  z-index: 90;
  display: flex;
  flex-direction: column;
  max-height: 480px;
  animation: comment-pop-in 150ms cubic-bezier(.2, .8, .2, 1) both;
  transform-origin: top left;
}
.comment-pop-h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.comment-pop-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px 16px;
  max-height: 260px;
}
.comment-item {
  display: flex;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}
.comment-item:last-child { border-bottom: 0; }
.comment-pop-foot {
  border-top: 1px solid var(--border);
  padding: 12px 16px;
}
.comment-pop-foot textarea {
  width: 100%;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  color: var(--text);
  font-size: 12.5px;
  font-family: inherit;
  resize: none;
  min-height: 60px;
  outline: none;
}
.comment-pop-foot textarea:focus { border-color: var(--cyan); }

/* Comment edit/delete actions */
.comment-actions {
  display: flex;
  gap: 2px;
  opacity: 0;
  transition: opacity 140ms;
}
.comment-item:hover .comment-actions { opacity: 1; }
.comment-action-btn {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 5px;
  color: var(--text-3);
  cursor: pointer;
  transition: all 140ms;
}
.comment-action-btn:hover {
  color: var(--cyan);
  background: var(--cyan-dim);
  border-color: rgba(var(--cyan-rgb), 0.3);
}
.comment-action-btn.danger:hover {
  color: var(--danger);
  background: rgba(255, 71, 87, 0.1);
  border-color: rgba(255, 71, 87, 0.3);
}

/* FIX 2026-06-11 (агент-аудит): .modal-* объявлены дважды (этот блок и 4713+).
   Этот удалён, канонический блок ниже. Раньше нижний побеждал по каскаду, но
   путал отладку. */

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
}
.status-dot.online { background: var(--green); box-shadow: 0 0 8px var(--green-glow); }
.status-dot.offline { background: var(--text-3); }
.status-dot.warn { background: var(--warn); box-shadow: 0 0 8px rgba(255, 140, 0, 0.4); }

.health-bar {
  width: 36px;
  height: 6px;
  border-radius: 999px;
  background: rgba(255,255,255,0.06);
  position: relative;
  overflow: hidden;
}
.health-bar .fill {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: 999px;
}

.copy-btn {
  margin-left: 6px;
  padding: 2px 5px;
  border-radius: 4px;
  color: var(--text-3);
  font-size: 11px;
  border: 1px solid transparent;
  background: transparent;
  transition: all 140ms;
}
.copy-btn:hover {
  color: var(--cyan);
  background: var(--cyan-dim);
}

.copy-phone {
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  color: var(--text);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  padding: 3px 8px;
  white-space: nowrap;
  cursor: pointer;
  transition: all 140ms;
  position: relative;
  text-decoration: underline dashed rgba(var(--cyan-rgb), 0.28);
  text-underline-offset: 3px;
}
.copy-phone:hover {
  background: var(--cyan-dim);
  color: var(--cyan);
  text-decoration-color: rgba(var(--cyan-rgb), 0.7);
  border-color: rgba(var(--cyan-rgb), 0.2);
}
.copy-phone.copied {
  background: var(--green-dim);
  color: var(--green);
  border-color: rgba(0, 255, 136, 0.3);
}
.copy-phone.copied::after {
  content: '✓ copied';
  position: absolute;
  left: 50%;
  bottom: calc(100% + 4px);
  transform: translateX(-50%);
  font-size: 10px;
  background: var(--card);
  color: var(--green);
  border: 1px solid rgba(0,255,136,0.3);
  padding: 2px 6px;
  border-radius: 4px;
  white-space: nowrap;
  font-family: 'Inter', sans-serif;
  pointer-events: none;
}

/* Tabs */
.tabs {
  display: flex;
  gap: 4px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
}
.tab {
  padding: 10px 16px;
  font-size: 13px;
  color: var(--text-2);
  background: transparent;
  border: 0;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color 140ms, border-color 140ms;
  margin-bottom: -1px;
  font-family: inherit;
}
.tab:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; border-radius: 4px; }
.tab:hover { color: var(--text); }
.tab.active {
  color: var(--cyan);
  border-bottom-color: var(--cyan);
}

.kv {
  display: grid;
  grid-template-columns: 130px 1fr;
  gap: 12px 18px;
  font-size: 13px;
}
.kv .k { color: var(--text-2); }
.kv .v { color: var(--text); }

/* Filter bar */
.filter-bar {
  display: flex;
  align-items: end;
  gap: 12px;
  padding: 14px 16px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  margin-bottom: 20px;
  flex-wrap: wrap;
}
.filter-bar .field { min-width: 140px; }
.filter-bar .grow { flex: 1; }
/* Expanding "more filters" row */
@keyframes filtersExpand {
  from { opacity: 0; max-height: 0; transform: translateY(-4px); }
  to { opacity: 1; max-height: 500px; transform: none; }
}
.filter-more-row {
  animation: filtersExpand 180ms ease both;
  overflow: hidden;
}

/* Number counter */
.count {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* ============================ FUNNEL V4 (vertical) ============================ */
.funnel-v4 { padding: 4px 0; }

.funnel-vertical {
  display: flex;
  flex-direction: column;
  padding: 0 4px;
  margin-bottom: 18px;
}
.fv-step { display: flex; flex-direction: column; }

.fv-connector {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 0 8px 234px;
  height: 32px;
}
.fv-conn-line {
  flex: 1;
  height: 1px;
  background: repeating-linear-gradient(to right, var(--border) 0 6px, transparent 6px 12px);
}
.fv-drop {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 4px 12px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  white-space: nowrap;
}
.fv-drop-pct { font-size: 12px; font-weight: 600; color: var(--text-2); }
.fv-drop-lost { font-size: 10.5px; color: var(--text-3); }
.fv-connector.worst .fv-drop {
  border-color: rgba(255, 71, 87, 0.4);
  background: var(--danger-dim);
}
.fv-connector.worst .fv-drop-pct { color: var(--danger); }
.fv-connector.worst .fv-drop-lost { color: rgba(255, 71, 87, 0.75); }

.fv-row {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 14px;
  align-items: center;
  padding: 4px 0;
}
.fv-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.fv-num {
  width: 28px; height: 28px;
  border-radius: 8px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  color: var(--stage-color);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
  font-weight: 700;
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.fv-name {
  font-size: 13.5px;
  font-weight: 500;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.fv-sub {
  font-size: 10.5px;
  color: var(--text-3);
  margin-top: 2px;
}
.fv-bar-wrap {
  height: 36px;
  background: rgba(255, 255, 255, 0.025);
  border-radius: 6px;
}
.fv-bar {
  height: 100%;
  background: var(--stage-color);
  border-radius: 6px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 0 14px rgba(var(--cyan-rgb), 0.12);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 0 14px;
  min-width: 80px;
  transition: filter 200ms;
}
.fv-bar:hover { filter: brightness(1.1); }
.fv-bar { transition: width 0.6s cubic-bezier(.4,0,.2,1), filter 200ms; }
.fv-count {
  font-size: 13.5px;
  font-weight: 600;
  color: #001016;
}

@media (max-width: 820px) {
  .fv-connector { padding-left: 12px; }
  .fv-row { grid-template-columns: 160px 1fr; gap: 10px; }
  .fv-name { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.25; }
}
@media (max-width: 560px) {
  .fv-row { grid-template-columns: 1fr; gap: 8px; }
  .fv-meta { width: 100%; }
  .fv-bar-wrap { width: 100%; }
  .fv-connector { padding-left: 0; height: auto; padding-top: 6px; padding-bottom: 6px; }
}

/* Hide v3 horizontal flow when v4 is present (just in case both render) */
.funnel-v4 .funnel-flow { display: none; }
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: 16px;
  padding: 10px 0;
}
.funnel-bar {
  height: 38px;
  border-radius: 8px;
  background: linear-gradient(90deg, rgba(var(--cyan-rgb), 0.6), rgba(var(--cyan-rgb), 0.15));
  border: 1px solid rgba(var(--cyan-rgb), 0.4);
  display: flex;
  align-items: center;
  padding: 0 14px;
  font-size: 13px;
  color: var(--text);
  font-weight: 500;
  position: relative;
}
.funnel-bar .pct {
  position: absolute;
  right: 14px;
  color: var(--cyan);
  font-family: 'JetBrains Mono', monospace;
  font-size: 12px;
}
.funnel-drop {
  font-size: 11px;
  color: var(--danger);
  font-family: 'JetBrains Mono', monospace;
  white-space: nowrap;
}
.funnel-num {
  font-family: 'JetBrains Mono', monospace;
  font-size: 14px;
  color: var(--text);
  text-align: right;
  min-width: 100px;
}

/* Heatmap */
.heatmap {
  display: grid;
  grid-template-columns: 40px repeat(24, 1fr);
  gap: 3px;
}
.heatmap .lbl { font-size: 10px; color: var(--text-3); display: grid; place-items: center; }
.heatmap .cell {
  aspect-ratio: 1;
  border-radius: 3px;
  background: rgba(var(--cyan-rgb), 0.06);
  transition: transform 120ms, box-shadow 120ms;
  cursor: pointer;
}
.heatmap .cell:hover { transform: scale(1.3); box-shadow: 0 0 8px var(--cyan-glow); z-index: 1; position: relative; }

/* Tag cloud */
.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.tag-cloud .t {
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--card-2);
  border: 1px solid var(--border);
  font-size: 13px;
  cursor: pointer;
  transition: all 140ms;
}
.tag-cloud .t:hover { border-color: var(--cyan); color: var(--cyan); }
.tag-cloud .t .n {
  color: var(--text-3);
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px;
  margin-left: 6px;
}

/* SMS log */
.sms-feed {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.sms-feed .row {
  display: grid;
  grid-template-columns: 90px 130px 130px 1fr 80px;
  gap: 14px;
  padding: 11px 16px;
  border-bottom: 1px solid var(--border);
  align-items: center;
  font-size: 12.5px;
  animation: slidein 280ms ease;
}
@keyframes slidein {
  from { opacity: 0; transform: translateY(-6px); background: var(--cyan-dim); }
  to { opacity: 1; transform: none; background: transparent; }
}
.sms-feed .row:hover { background: rgba(var(--cyan-rgb), 0.03); }
.sms-feed .ts { color: var(--text-3); font-family: 'JetBrains Mono', monospace; font-size: 11.5px; }
.sms-feed .did { color: var(--cyan); font-family: 'JetBrains Mono', monospace; font-size: 11.5px; }
.sms-feed .sender { color: var(--text); font-weight: 500; }
.sms-feed .msg { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Big banner */
.banner {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 24px 28px;
  border-radius: var(--r-card);
  margin-bottom: 24px;
  transition: opacity 200ms ease, transform 200ms ease, max-height 200ms ease, margin-bottom 200ms ease, padding 200ms ease;
  opacity: 1;
  transform: none;
  max-height: 320px;
  overflow: hidden;
}
.banner.closing {
  opacity: 0;
  transform: translateY(-8px) scale(0.98);
  max-height: 0;
  margin-bottom: 0;
  padding-top: 0;
  padding-bottom: 0;
  pointer-events: none;
}
.banner.ok {
  background: linear-gradient(90deg, rgba(0, 255, 136, 0.12), rgba(0, 255, 136, 0.02));
  border: 1px solid rgba(0, 255, 136, 0.3);
  border-left: 3px solid var(--green);
}
.banner.bad {
  background: linear-gradient(90deg, rgba(255, 71, 87, 0.14), rgba(255, 71, 87, 0.02));
  border: 1px solid rgba(255, 71, 87, 0.35);
}
.banner .big {
  width: 52px; height: 52px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  font-size: 24px;
  font-weight: 700;
}
.banner.ok .big { background: rgba(0, 255, 136, 0.15); color: var(--green); box-shadow: 0 0 20px var(--green-glow); }
.banner.bad .big { background: rgba(255, 71, 87, 0.15); color: var(--danger); }
.banner h2 { margin: 0; font-size: 20px; font-weight: 600; }
.banner p { margin: 4px 0 0; color: var(--text-2); font-size: 13px; }

/* Settings form */
.form-section {
  border-top: 1px solid var(--border);
  padding: 22px 0;
}
.form-section:first-of-type { border-top: 0; }
.form-section h3 { margin: 0 0 4px; font-size: 15px; font-weight: 600; }
.form-section p.desc { margin: 0 0 16px; color: var(--text-2); font-size: 12.5px; }

.toggle {
  width: 36px;
  height: 20px;
  background: var(--border);
  border-radius: 999px;
  position: relative;
  cursor: pointer;
  transition: background 160ms;
  flex-shrink: 0;
}
.toggle::after {
  content: '';
  position: absolute;
  width: 16px; height: 16px;
  border-radius: 50%;
  background: var(--text);
  top: 2px; left: 2px;
  transition: left 160ms;
}
.toggle.on { background: var(--cyan); box-shadow: 0 0 10px var(--cyan-glow); }
.toggle.on::after { left: 18px; background: #001016; }

/* Misc utility */
.hbar {
  height: 1px;
  background: var(--border);
  margin: 16px 0;
}
.row { display: flex; align-items: center; gap: 10px; }
.col { display: flex; flex-direction: column; gap: 10px; }
.muted { color: var(--text-2); }
.tiny { font-size: 11px; }
.right { text-align: right; }
.center { text-align: center; }
.nowrap { white-space: nowrap; }
.gap-3 { gap: 12px; }
.gap-2 { gap: 8px; }
.mt-2 { margin-top: 8px; }
.mt-3 { margin-top: 12px; }
.mt-4 { margin-top: 16px; }
.mb-2 { margin-bottom: 8px; }
.mb-3 { margin-bottom: 12px; }
.mb-4 { margin-bottom: 16px; }
.flex { display: flex; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.flex-1 { flex: 1; }

/* Modal */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(8, 8, 14, 0.6);
  backdrop-filter: blur(4px);
  display: grid;
  place-items: center;
  z-index: 100;
  animation: fadein 160ms ease;
}
.modal {
  width: 560px;
  max-width: calc(100vw - 40px);
  background: var(--card);
  border: 1px solid var(--border-2);
  border-radius: var(--r-card);
  /* мягкая тень без «жирной» подложки на фоне */
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
  animation: modal-in 200ms cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes modal-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
.modal-h {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.modal-body { padding: 20px; }
.modal-foot {
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(255,255,255,0.012);
  border-radius: 0 0 var(--r-card) var(--r-card);
}

/* C-markup-prod — режим разметки на проде, виден только владельцу.
   Кнопка-карандашик в топбаре включает оверлей; клик по любому DOM-узлу → попап с textarea → POST /api/markup-pin. */
.topnav-icon-btn--markup.active {
  background: var(--cyan-dim);
  color: var(--cyan);
  border-color: var(--cyan);
}
body.markup-on { cursor: crosshair; }
body.markup-on .topnav-icon-btn--markup { cursor: pointer; }
.mk-pop {
  position: fixed;
  z-index: 9999;
  width: 360px;
  max-width: calc(100vw - 24px);
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 14px;
  box-shadow: 0 24px 60px -16px rgba(0, 0, 0, .75);
  padding: 12px;
  color: var(--text-1, #e6edf3);
  font-family: inherit;
}
.mk-pop__h {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
  font-weight: 600;
  margin-bottom: 8px;
  cursor: move;
  user-select: none;
}
.mk-pop__h span { pointer-events: none; }
.mk-pop__x {
  border: 0;
  background: transparent;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  color: var(--text-3, #8b97a3);
  padding: 0 4px;
}
.mk-pop__x:hover { color: var(--text-1, #e6edf3); }
.mk-pop__tgt {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 11px;
  background: var(--bg, #0f1419);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 6px 9px;
  margin-bottom: 9px;
  overflow: hidden;
}
.mk-pop__tgt b {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--cyan);
  font-weight: 500;
  flex: none;
}
.mk-pop__tgt span {
  color: var(--text-2, #a4b1bd);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.mk-pop textarea {
  width: 100%;
  min-height: 96px;
  resize: vertical;
  box-sizing: border-box;
  font: inherit;
  font-size: 13px;
  padding: 9px 11px;
  border: 1px solid var(--border-2);
  border-radius: 10px;
  outline: none;
  background: var(--bg, #0f1419);
  color: var(--text-1, #e6edf3);
}
.mk-pop textarea:focus {
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px var(--cyan-dim);
}
.mk-pop textarea::placeholder { color: var(--text-3, #8b97a3); }
.mk-pop__row {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 10px;
}
.mk-pop__btn {
  font: inherit;
  font-size: 12.5px;
  border-radius: 999px;
  padding: 7px 14px;
  cursor: pointer;
  border: 1px solid var(--border-2);
  background: var(--bg, #0f1419);
  color: var(--text-1, #e6edf3);
}
.mk-pop__btn:hover { background: var(--bg-2); }
.mk-pop__btn--primary {
  background: var(--cyan);
  border-color: var(--cyan);
  color: #0b0c0e;
  font-weight: 600;
}
.mk-pop__btn--primary:hover:not(:disabled) { filter: brightness(1.08); }
.mk-pop__btn--primary:disabled { opacity: .45; cursor: default; }
.mk-toast {
  position: fixed;
  bottom: 22px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10000;
  background: rgba(11, 12, 14, .92);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border-2);
  color: #fff;
  font-size: 13px;
  padding: 9px 16px;
  border-radius: 999px;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s;
  box-shadow: 0 12px 30px -8px rgba(0, 0, 0, .6);
}
.mk-toast.show { opacity: 1; }

/* ===== THEMES-FIX: контраст в Light Clean / Teal Calm / Warm Amber ===== */
/* 1) Done-заметка: на бледной плашке текст-3 нечитаем во всех темах.
      Поднимаем opacity и используем text-2 вместо text-3. */
.note.done { opacity: 0.78; }
.note.done .note-text { color: var(--text-2); }

/* 2) Light: пилл «User» в приветствии — синий на белом не выделен,
      добавим лёгкий фон и подложку как у chip. */
html.theme-light .home-hero h1 > span {
  background: var(--cyan-dim);
  padding: 2px 9px;
  border-radius: 6px;
  border: 1px solid rgba(var(--cyan-rgb), 0.22);
}

/* 3) Light: primary-кнопка («+ Добавить») — текст #001821 на синем #2563eb
      достаточный, но disabled на opacity 0.45 теряется на белом фоне.
      Для светлой темы поднимаем минимальный контраст disabled-кнопки. */
html.theme-light .btn.primary { color: #ffffff; }
html.theme-light .btn:disabled,
html.theme-light .btn[disabled] { opacity: 0.6; }
/* ===== /THEMES-FIX ===== */

/* ===== Унифицированный pill-tabs паттерн ====================================
   Эталон: cyan-fill для активного состояния. Используется в Сети, Аналитике,
   Билдере APK (там inline-стиль), SMS, Device-detail, Server, CF-accounts.
   .net-tab(s) оставлен как алиас для обратной совместимости. */
.net-tabs, .tab-pills {
  display: flex;
  gap: 4px;
  margin: 14px 0 16px;
  padding: 4px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  width: fit-content;
  max-width: 100%;
  overflow-x: auto;
  flex-wrap: wrap;
}
.net-tab, .tab-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  background: transparent;
  border: none;
  border-radius: 7px;
  color: var(--text-2);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  transition: background 140ms ease, color 140ms ease;
  font-family: inherit;
}
.net-tab:hover, .tab-pill:hover {
  background: var(--card-2);
  color: var(--text);
}
.net-tab.active, .tab-pill.active {
  background: var(--cyan);
  color: #0a0a0d;
}
.net-tab.active:hover, .tab-pill.active:hover {
  background: var(--cyan);
  color: #0a0a0d;
}
.net-tab svg, .tab-pill svg { opacity: 0.9; }
.net-tab.active svg, .tab-pill.active svg { opacity: 1; }
.net-tab-body { margin-top: 6px; }

@media (max-width: 720px) {
  .net-tabs { width: 100%; flex-wrap: nowrap; }
  .net-tab { flex: 1 1 0; justify-content: center; padding: 7px 8px; font-size: 12px; }
}

/* ===== Topnav overflow fix at studio-frame widths (1340-1500px) =====
   Студия Йохана рендерит панель в фрейме шириной ~1280-1380px.
   На этой ширине нужно: сжать поиск (убрать Ctrl K), кнопку Выйти превратить в иконку,
   уменьшить gap между правыми элементами. */
@media (max-width: 1500px) {
  .topnav-kbd { display: none; }
  .topnav-search { padding: 9px 13px; min-width: 180px; }
}
@media (max-width: 1380px) {
  .topnav-logout-icon { display: inline !important; }
  .topnav-logout-text { display: none; }
  .topnav-logout { padding: 6px 8px !important; }
  .topnav-search { min-width: 80px; padding: 9px 11px; }
  .topnav-search > span:not(.topnav-kbd) {
    max-width: 120px;
  }
}
@media (max-width: 1300px) {
  .topnav-search { min-width: 44px; padding: 9px; }
  .topnav-search > span:not(.topnav-kbd) {
    display: none;
  }
  /* Минимум 32x32 для попадания пальцем даже на узких экранах. */
  .topnav-icon-btn { width: 32px !important; height: 32px !important; }
  .topnav-inner { gap: 8px; }
  .topnav-role-btn { max-width: 160px; padding: 7px 10px; }
}
@media (max-width: 1100px) {
  /* Адаптация между 1100 и 1024: сжимаем подписи групп до иконок. */
  .topnav-link > span { display: none; }
  .topnav-link { padding: 6px 8px; }
  .topnav-role-btn { max-width: 120px; font-size: 12px; }
  .topnav-logout > span { display: none; }
}
@media (max-width: 900px) {
  /* Очень узкие: скрываем имя пользователя - оставляем только иконки. */
  .topnav-search { display: none; }
  .topnav-inner { padding: 10px 14px; gap: 6px; }
}

/* ===== HelpTip (KR58 2026-06-08) — кликабельная подсказка с fade+slide.
   Фикс: попап теперь position:fixed на этапе раскрытия не нужен — z-index:300
   и контейнер с isolation, чтобы overflow:hidden у родителя НЕ обрезал попап. */
.help-tip-wrap {
  display: inline-flex;
  align-items: center;
  position: relative;
  margin-left: 6px;
  isolation: isolate; /* свой контекст наложения, попап будет всегда поверх */
}
.help-tip-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: transparent;
  color: var(--text-3);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: border-color 140ms, color 140ms, background 140ms, transform 140ms;
}
.help-tip-trigger.with-label {
  width: auto;
  height: auto;
  padding: 3px 9px;
  border-radius: 12px;
  font-size: 11px;
}
.help-tip-trigger:hover,
.help-tip-trigger.open {
  border-color: var(--cyan);
  color: var(--cyan);
  background: rgba(var(--cyan-rgb), 0.08);
  transform: scale(1.06);
}
.help-tip-pop {
  position: absolute;
  z-index: 300;
  top: calc(100% + 10px);
  min-width: 220px;
  max-width: 320px;
  padding: 10px 12px;
  background: var(--bg-2);
  border: 1px solid var(--border-2);
  border-radius: 10px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.28), 0 2px 6px rgba(0, 0, 0, 0.14);
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--text-2);
  opacity: 0;
  transform: translateY(-6px);
  animation: helpTipIn 180ms cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
  pointer-events: auto;
}
.help-tip-pop.wide { max-width: 420px; }
.help-tip-pop.side-right { left: 0; }
.help-tip-pop.side-left { right: 0; }
.help-tip-pop.side-center { left: 50%; transform: translate(-50%, -6px); animation-name: helpTipInCenter; }
.help-tip-arrow {
  position: absolute;
  top: -5px;
  width: 10px;
  height: 10px;
  background: var(--bg-2);
  border-left: 1px solid var(--border-2);
  border-top: 1px solid var(--border-2);
  transform: rotate(45deg);
}
.help-tip-pop.side-right .help-tip-arrow { left: 14px; }
.help-tip-pop.side-left .help-tip-arrow { right: 14px; }
.help-tip-pop.side-center .help-tip-arrow { left: 50%; margin-left: -5px; }
.help-tip-body { display: block; color: var(--text-2); }
.help-tip-body b, .help-tip-body strong { color: var(--text-1); font-weight: 600; }
.help-tip-body code { font-family: 'JetBrains Mono', monospace; background: var(--bg-3); padding: 1px 5px; border-radius: 3px; font-size: 11.5px; color: var(--cyan); }

@keyframes helpTipIn {
  from { opacity: 0; transform: translateY(-6px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0)    scale(1); }
}
@keyframes helpTipInCenter {
  from { opacity: 0; transform: translate(-50%, -6px) scale(0.97); }
  to   { opacity: 1; transform: translate(-50%, 0)    scale(1); }
}

/* На теплой/светлой темах подкорректировать фон стрелки */
html.theme-amber .help-tip-pop,
html.theme-light .help-tip-pop { box-shadow: 0 8px 18px rgba(0,0,0,0.10), 0 2px 4px rgba(0,0,0,0.06); }

/* LAYDES: tap-area закрытия баннера */
.srv-banner-x {
  display: grid;
  place-items: center;
  border-radius: 8px;
  transition: background 140ms;
}
.srv-banner-x:hover {
  background: rgba(255,255,255,0.06);
}

/* pipeline: на <1100px у баннера серверов прячем вторую колонку статов, чтобы заголовок дышал */
@media (max-width: 1100px) {
  .srv-banner-stat-2 { display: none; }
}

/* ZIPB 2026-06-08: подсветка-якорь при переходе с focus= в URL.
   Используется при переходе из Билдера APK «Подключить нового бота» →
   Настройки → Алёрты → блок «Командный бот установок». */
.focus-pulse {
  animation: focus-pulse-anim 2.4s ease-out;
  scroll-margin-top: 80px;
}
@keyframes focus-pulse-anim {
  0%   { box-shadow: 0 0 0 0 rgba(var(--cyan-rgb), 0.5); border-color: var(--cyan); }
  35%  { box-shadow: 0 0 0 8px rgba(var(--cyan-rgb), 0.18); border-color: var(--cyan); }
  100% { box-shadow: 0 0 0 0 rgba(var(--cyan-rgb), 0); }
}

/* FIX 2026-06-11 (агент-аудит): второй блок .ui-select-pop с backdrop-filter blur
   удалён. Из-под попапа просвечивали фиолетовые WS-badges (мы наблюдали баг в авто-чек попапе).
   Основной блок .ui-select-pop на 2812 с непрозрачным фоном — этого достаточно. */

/* Drawer (slide-in справа) — для детального просмотра CF-аккаунта.
   Backdrop затемняет страницу, drawer выезжает 240мс с правого края. */
.drawer-backdrop {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 480;
  animation: drawerBackdropIn 200ms ease both;
}
.drawer-panel {
  position: fixed;
  top: 0; right: 0; bottom: 0;
  width: 100%;
  max-width: 560px;
  background: var(--card);
  border-left: 1px solid var(--border);
  box-shadow: -12px 0 36px rgba(0, 0, 0, 0.5);
  z-index: 481;
  display: flex; flex-direction: column;
  animation: drawerSlideIn 280ms cubic-bezier(0.2, 0.9, 0.3, 1) both;
  overflow-y: auto;
}
.drawer-panel-h {
  position: sticky; top: 0; z-index: 2;
  background: var(--card);
  border-bottom: 1px solid var(--border);
  padding: 18px 22px;
  display: flex; align-items: center; gap: 14px;
}
.drawer-panel-body { padding: 18px 22px; }
@keyframes drawerBackdropIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes drawerSlideIn {
  from { transform: translateX(40px); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}

/* CF row hover — намёк что строка кликабельная. */
.cf-accounts-table tbody tr {
  cursor: pointer;
  transition: background 140ms ease;
}
.cf-accounts-table tbody tr:hover {
  background: rgba(45, 212, 191, 0.05);
}

/* Save-кнопка стабильной ширины. Применяется к кнопкам, у которых текст
   меняется (Сохранить → Сохраняю → Сохранено) — фиксирует ширину, чтобы
   кнопка не «прыгала» при переключении состояний. */
.btn-stable {
  min-width: 140px;
  justify-content: center;
}

/* Архивные строки таблицы устройств — менее яркие. Без бейджей и новых колонок,
   просто приглушение чтоб визуально отделить от активного парка. */
.t tr.row-archived td { opacity: 0.55; }
.t tr.row-archived:hover td { opacity: 0.8; }

/* Popover разрешений остаётся непрозрачным даже на архивной (тусклой) строке */
.t tr.row-archived td .perms-popover { opacity: 1; }
.t tr.row-archived:hover td .perms-popover { opacity: 1; }

/* Подсказка над таблицей про приглушённые строки. Появляется только если
   в выборке реально есть архивные устройства. */
.dev-archive-hint {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  margin: 0 0 10px;
  font-size: 12px;
  color: var(--text-2);
  background: rgba(var(--cyan-rgb), 0.04);
  border: 1px solid rgba(var(--cyan-rgb), 0.16);
  border-radius: 7px;
}
.dev-archive-hint svg { color: var(--cyan); flex-shrink: 0; }
.dev-archive-hint .muted { margin-left: 4px; padding-left: 8px; border-left: 1px solid var(--border-2); }


/* Прогресс-бар сверху таблицы при reload — тонкая cyan-волна 1.4s туда-сюда. */
.table-loading-bar {
  position: absolute;
  top: 0; left: 0;
  height: 2px;
  width: 30%;
  background: linear-gradient(90deg, transparent, var(--cyan), transparent);
  animation: tableLoadingSweep 1.4s linear infinite;
  pointer-events: none;
  z-index: 5;
}
@keyframes tableLoadingSweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(450%); }
}

/* Пульсация cyan-фона строки во время проверки конкретного домена. */
.row-checking td {
  animation: rowCheckingPulse 1.2s ease-in-out infinite;
}
@keyframes rowCheckingPulse {
  0%, 100% { background-color: transparent; }
  50%      { background-color: rgba(45, 212, 191, 0.07); }
}

/* Auto-check popover — собственный класс, без blur (на тёмной теме просвечивали
   фиолетовые WS-badges из-под попапа). Полностью непрозрачный, без scroll. */
.popover-flat {
  background: var(--card);
  border: 1px solid var(--border-2, var(--border));
  border-radius: 10px;
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.55);
  animation: select-pop-in 140ms ease both;
  transform-origin: top center;
  overflow: visible !important;
  max-height: none !important;
}

/* View-only mode: блокирует мутирующие действия для ролей с perm = 'view'.
   Класс вешает app.jsx по текущей странице. Управляющие элементы (нав, фильтры,
   role-switcher) НЕ блокируются — добавляем .ro-allow для исключений. */
body.role-view-only .btn.primary,
body.role-view-only .btn.danger,
body.role-view-only .btn-stable,
body.role-view-only input[type="text"]:not(.search-input):not([data-ro-allow]),
body.role-view-only input[type="email"]:not([data-ro-allow]),
body.role-view-only input[type="password"]:not([data-ro-allow]),
body.role-view-only input[type="number"]:not([data-ro-allow]),
body.role-view-only textarea:not([data-ro-allow]),
body.role-view-only input[type="file"] {
  pointer-events: none !important;
  opacity: 0.45;
  cursor: not-allowed !important;
  filter: grayscale(0.3);
}
body.role-view-only .ro-allow,
body.role-view-only .topnav-role-btn,
body.role-view-only .topnav-icon-btn,
body.role-view-only .topnav-menu-pop,
body.role-view-only .cmd-search input,
body.role-view-only .search-input,
body.role-view-only [data-ro-allow] {
  pointer-events: auto !important;
  opacity: 1 !important;
  filter: none !important;
  cursor: auto !important;
}
/* Баннер сверху страницы — рендерится из RoleGuard. */
.ro-banner {
  /* НЕ sticky — иначе наезжает на .topnav (тоже sticky top:0 z:50) и получается каша. */
  position: relative; z-index: 1;
  display: flex; gap: 10px; align-items: center;
  padding: 10px 18px;
  background: rgba(45, 212, 191, 0.08);
  border-bottom: 1px solid rgba(45, 212, 191, 0.25);
  color: var(--cyan);
  font-size: 12.5px;
  letter-spacing: 0.2px;
}

/* Топбар никогда не блокируется в view-only — нужны навигация и role-switcher. */
body.role-view-only .topnav,
body.role-view-only .topnav *,
body.role-view-only .ro-banner,
body.role-view-only .ro-banner * {
  pointer-events: auto !important;
  opacity: 1 !important;
  filter: none !important;
  cursor: auto !important;
}

/* Точечные исключения: chip-удалители, всё что не покрыто базовым правилом. */
body.role-view-only .pkg-chip-x,
body.role-view-only .views-item .x,
body.role-view-only .cat-x,
body.role-view-only .comment-action-btn,
body.role-view-only [data-mutator] {
  pointer-events: none !important;
  opacity: 0.45 !important;
  cursor: not-allowed !important;
}

/* perms-popover (devices таблица) — fade-in появление вместо jump. */
.perms-popover {
  animation: select-pop-in 140ms ease-out both;
  transform-origin: top center;
}

/* drill-banner на dashboard — fade-in 220ms. */
.drill-banner {
  animation: fade-slide-in 220ms ease-out both;
}

/* Главная: основная сетка адаптивная.
   Десктоп: широкая колонка с доской + узкая со списками.
   На узких (≤1024) — складывается в одну колонку. */
.home-grid {
  grid-template-columns: 1.4fr 1fr;
}
@media (max-width: 1100px) {
  .home-grid { grid-template-columns: 1.2fr 1fr; gap: 16px; }
}
@media (max-width: 1024px) {
  .home-grid { grid-template-columns: 1fr; }
}

/* Devices: появление строк таблицы при первом рендере / смене страницы. */
.t tbody tr.row-fade {
  animation: row-fade 220ms ease-out both;
}
@keyframes row-fade {
  from { opacity: 0; transform: translateY(-2px); }
  to   { opacity: 1; transform: none; }
}

/* Device-detail: плавное переключение табов. */
.dd-tab-pane {
  animation: section-fade-in 200ms ease-out both;
}

/* Devices: toolbar адаптив. На узких приоритизируем поиск, фильтры в одной строке. */
@media (max-width: 1024px) {
  .dev-toolbar { flex-wrap: wrap; gap: 8px; }
  .dev-toolbar .views-dd { order: 10; }
}
@media (max-width: 820px) {
  .density-toggle button > svg { width: 14px; height: 14px; }
  .dev-toolbar input[type="text"] { min-width: 160px; }
}

/* Device-detail: на 1100-768 убираем sticky левую колонку и складываем в одну. */
@media (max-width: 1100px) {
  .device-detail-info { position: static !important; top: auto !important; }
}
@media (max-width: 900px) {
  .device-detail .g-2-asym-30-70 { grid-template-columns: 1fr !important; }
}

/* SMS: адаптив toolbar на узких. */
@media (max-width: 1024px) {
  .sms-toolbar { gap: 8px; }
  .sms-toolbar > .row > input { font-size: 12.5px; }
}
@media (max-width: 768px) {
  /* На очень узких экранах позволяем тексту SMS переноситься. */
  .sms-feed .msg { white-space: normal; overflow: visible; text-overflow: clip; max-height: 60px; overflow-y: auto; }
}

/* KPI плавная смена значения — для server.jsx KPIValue. */
.kpi-tick { animation: section-fade-in 200ms ease-out both; }

/* Global focus ring — клавиатурная навигация, видно на тёмном фоне. */
:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
}

/* KPI-сетка 6 карточек: не растягивать на 1920+, центрировать. */
.grid.g-6 {
  max-width: 1640px;
  margin-left: auto;
  margin-right: auto;
}

/* На ≤480 в карточке «Онлайн сейчас» pulse-dot уже даёт live-индикатор —
   стрелка hover-перехода лишняя на тач-устройствах. */
@media (max-width: 480px) {
  .metric:has(.pulse-dot) .metric-arrow { display: none; }
}

/* Уважение к prefers-reduced-motion — выключаем анимации/переходы. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* =========================================================================
   OVR-37: пакет правок «оставшиеся средние после сегодняшних правок» (2026-06-15).
   Только override и добавления, существующие правила не удалены.
   ========================================================================= */

/* (1) Гарантия cyan-only в шапке воронки. Перебиваем любые случайные фиолетовые
       gradient/box-shadow, которые могли прийти inline-стилем из dashboard.jsx. */
.funnel-hero {
  background: linear-gradient(135deg, rgba(var(--cyan-rgb), 0.10) 0%, rgba(var(--cyan-rgb), 0.02) 100%) !important;
  border-color: rgba(var(--cyan-rgb), 0.18) !important;
  box-shadow: none;
}
.funnel-hero .badge.violet,
.funnel-hero [class*="violet"] {
  background: var(--cyan-dim) !important;
  color: var(--cyan) !important;
  border-color: rgba(var(--cyan-rgb), 0.25) !important;
}

/* (2) В модалке аномалии (.anomaly-cause / .modal) — нейтральный бейдж вместо
       фиолетового. Override для .badge.violet ВНУТРИ модалок и anomaly блоков. */
.modal .badge.violet,
.anomaly-cause .badge.violet {
  background: var(--cyan-dim);
  color: var(--cyan);
  border-color: rgba(var(--cyan-rgb), 0.25);
}

/* (3) KPI на 1024-1100px — одинаковая min-height + уменьшенный лейбл, чтобы
       перенос длинных русских лейблов не делал карточки разной высоты. */
@media (min-width: 561px) and (max-width: 1100px) {
  .grid.g-3 .metric,
  .grid.g-4 .metric,
  .grid.g-6 .metric {
    min-height: 110px;
  }
  .metric .label {
    font-size: 11.5px;
    letter-spacing: 0.1px;
  }
}

/* (4) KPI на 1920px — ограничиваем grid g-3, чтобы карточки не растягивались
       и числа не терялись в пустоте. (.grid.g-6 уже ограничен на 5428 max-width 1640.) */
@media (min-width: 1700px) {
  .grid.g-3 {
    max-width: 1640px;
    margin-left: auto;
    margin-right: auto;
  }
  .grid.g-3 .metric {
    max-width: 460px;
  }
}

/* (5) Лейблы KPI — отказываемся от КАПС и поднимаем до 12.5px (с 12 базовой).
       Если text-transform приходит inline из .jsx — перебиваем явно. */
.metric .label {
  font-size: 12.5px;
  text-transform: none !important;
  letter-spacing: 0.15px;
}

/* (6) Suffix в .metric .value (%, дн, /100) — уменьшаем отступ marginLeft.
       Делаем через CSS-фоллбэк: любой <small> или .suffix внутри .value. */
.metric .value small,
.metric .value .suffix,
.metric .value [data-suffix] {
  margin-left: 2px;
  font-weight: 500;
}

/* (7) Карточка «Ср. время жизни»: suffix «дн» — крупнее, цвет text-3 для
       визуального отделения от числа. Целимся по data-suffix или классу. */
.metric .value [data-suffix="дн"],
.metric .value .suffix-days,
.metric .value small.days {
  font-size: 16px;
  color: var(--text-3);
  margin-left: 3px;
  font-weight: 500;
}

/* (8) Баланс шрифтов в шапке воронки: «12 488» сейчас 28px/600 рядом с
       «47.4%» 44px/700. Уменьшаем .fh-to до 24px/500 — главным остаётся %. */
.fh-to {
  font-size: 24px;
  font-weight: 500;
}
.fh-from {
  font-size: 22px;
  font-weight: 500;
}

/* (16) Подпись «конверсия» в шапке воронки — гарантированно читаемо на мобиле. */
.fh-arc-lbl {
  font-size: 11.5px;
  color: var(--text-2);
  letter-spacing: 0.7px;
}

/* (9) Карточка «Кривая удержания» на телефоне — .card-h в flex-wrap на ≤560,
       чтобы бейдж и подпись не налезали. */
@media (max-width: 560px) {
  .card-h {
    flex-wrap: wrap;
    align-items: flex-start;
  }
  .card-h .sub {
    display: block;
    flex-basis: 100%;
  }
}

/* (10) Блок фильтров на 768 — auto-fit grid для filter-bar / filter-more-row.
        Сейчас .filter-bar = flex-wrap; добавляем grid-вариант для подбоковок
        с пятью полями, и одинаковую ширину минимум 150px. */
@media (max-width: 900px) {
  .filter-bar {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    align-items: end;
  }
  .filter-bar .grow,
  .filter-bar > button {
    grid-column: 1 / -1;
  }
  .filter-more-row {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
  }
}

/* (11) На телефоне — фильтры в одну колонку, чтобы 5 выпадашек не занимали
        пол-экрана пирамидой. (Сам toggle «Фильтры (5)» должен делать jsx.) */
@media (max-width: 560px) {
  .filter-bar {
    grid-template-columns: 1fr;
  }
  .filter-more-row {
    grid-template-columns: 1fr !important;
  }
}

/* (12) Щель между filter-bar и «ещё фильтров» — убираем margin-top, делаем
        визуально одну карточку. */
.filter-bar + .filter-more-row {
  margin-top: 0;
  border-top: 1px dashed var(--border);
  padding-top: 12px;
}

/* (15) MiniBar transition — плавное расширение полоски за 600ms.
        Применяется ко всем элементам с типичными классами mini-bar/bar-fill
        внутри .metric — синхронизируется с count-up числа. */
.metric .mini-bar > *,
.metric [class*="bar"] > [style*="width"],
.metric [data-mini-bar] > [data-fill],
.metric .bar-fill,
.metric .stat-bar-fill {
  transition: width 600ms cubic-bezier(0.4, 0, 0.2, 1);
}

/* (24) Аномалия закрывается с collapse-height. .anomaly-banner уже использует
        max-height transition? Если нет — добавляем .anomaly-closing вариант. */
.anomaly-banner,
.alert-banner.anomaly {
  transition: opacity 280ms ease, max-height 320ms cubic-bezier(0.4, 0, 0.2, 1),
              margin 280ms ease, padding 280ms ease, transform 280ms ease;
  max-height: 600px;
  overflow: hidden;
}
.anomaly-banner.anomaly-closing,
.alert-banner.anomaly-closing {
  opacity: 0;
  max-height: 0;
  margin-top: 0;
  margin-bottom: 0;
  padding-top: 0;
  padding-bottom: 0;
  transform: translateY(-8px);
  pointer-events: none;
}

/* (27) Графики (LineChart / BarChart) — плавное появление svg-линий.
        Класс .chart-fade-in вешает дашборд на впервые отрендеренный график. */
.chart svg,
.line-chart svg,
.bar-chart svg,
[data-chart] svg {
  animation: chart-draw-in 340ms cubic-bezier(0.2, 0.7, 0.3, 1) both;
}
@keyframes chart-draw-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
.chart path[data-line],
.line-chart path,
[data-chart] path[stroke] {
  stroke-dasharray: 1200;
  stroke-dashoffset: 1200;
  animation: chart-stroke 700ms cubic-bezier(0.2, 0.7, 0.3, 1) 120ms forwards;
}
@keyframes chart-stroke {
  to { stroke-dashoffset: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .chart svg, .line-chart svg, .bar-chart svg, [data-chart] svg { animation: none; }
  .chart path[data-line], .line-chart path, [data-chart] path[stroke] {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
    animation: none;
  }
}

/* (28) Skeleton → контент: плавный cross-fade. Когда исчезает .skeleton и
        появляется .skeleton-loaded — opacity transition. */
.skeleton {
  transition: opacity 220ms ease-out;
}
.skeleton-hidden,
[data-skeleton="loaded"] {
  opacity: 1;
  animation: skeleton-fade-in 240ms ease-out both;
}
@keyframes skeleton-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton-hidden, [data-skeleton="loaded"] { animation: none; }
}

/* (30) Focus-ring чётче на тёмном фоне. На 5421 уже есть :focus-visible с
        outline 2px, но без glow и без явного выделения внутри табов/чипов
        и FieldSelect-кнопок. Усиливаем универсально. */
:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px rgba(var(--cyan-rgb), 0.18);
  border-radius: 6px;
}
/* Для элементов где outline-offset 2px ломает layout — fallback inset shadow. */
.field-select:focus-visible,
.ui-select-btn:focus-visible,
.styled-select-btn:focus-visible,
.dev-select:focus-visible {
  outline: 2px solid var(--cyan);
  outline-offset: 1px;
  box-shadow: 0 0 0 3px rgba(var(--cyan-rgb), 0.22);
}

/* OVR-37 #11: на ≤560 фильтры — одна кнопка-тогл «Фильтры (N)», блоки спрятаны
   пока не раскрыли. На десктопе тогл скрыт. */
.filter-mobile-toggle {
  display: none;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 12px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  color: var(--text);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  transition: border-color 160ms, background 160ms;
}
.filter-mobile-toggle:hover { border-color: var(--cyan); }
.filter-mobile-toggle:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
@media (max-width: 560px) {
  .filter-mobile-toggle { display: inline-flex; margin-bottom: 8px; }
  [data-mobile-filters-open="false"] > .filter-bar { display: none !important; }
}
/* /OVR-37 ================================================================== */

/* ===== RETENTION-FIX ======================================================
   Точечные правки таба Аналитика → Удержание.
   Скоп: всё ограничено .retention-tab + точечные атрибут-селекторы,
   чтобы не задеть Конверсию/Устройства/Время жизни/USSD/Активность.
   Каноном остаются var(--*) переменные. */

/* (1) Корневой контейнер таба не должен раздувать страницу: min-width:0
   ломает default min-content у flex/grid-детей. Скролл — внутри таба. */
.retention-tab { min-width: 0; }
.retention-tab > div { min-width: 0; }

/* (1, 2) Таблица .t внутри таба аналитики — горизонтальный скролл ВНУТРИ
   карточки на узких. Без обёртки .table-wrap (JSX не трогаем): включаем
   block+overflow на самой таблице, чтобы не уезжала вся страница.
   Брейк 720px — на этом пороге уже виден перенос колонок D14/D30. */
@media (max-width: 720px) {
  .retention-tab .card > table.t {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    width: 100%;
  }
  .retention-tab .card > table.t thead,
  .retention-tab .card > table.t tbody {
    display: table;
    width: 100%;
    min-width: 520px;
  }
}

/* (2) Sticky первая колонка «Когорта» — остаётся видна при скролле.
   Только внутри .retention-tab — другие таблицы (Сеть/Домены/SMS) не трогаем. */
@media (max-width: 720px) {
  .retention-tab .card > table.t th:first-child,
  .retention-tab .card > table.t td:first-child {
    position: sticky;
    left: 0;
    background: var(--card);
    z-index: 2;
  }
  /* зебра для sticky-колонки — иначе чётные строки просвечивают */
  .retention-tab .card > table.t tbody tr:nth-child(even) td:first-child {
    background: var(--card-2, var(--card));
  }
}

/* (2) Уплотняем padding ячеек на 360px — D14/D30 влезают полностью. */
@media (max-width: 480px) {
  .retention-tab .card > table.t th,
  .retention-tab .card > table.t td {
    padding: 6px 8px;
    font-size: 12px;
  }
  .retention-tab .card > table.t th { padding: 8px 8px; }
}

/* (3) Три плитки-вехи (День 1 / Неделя / Месяц): горизонтальная карточка
   на телефоне, чтобы подпись и цифра не рвались на 3 строки.
   Скоп: первый .grid внутри .retention-tab — это milestones (см. JSX:147). */
@media (max-width: 480px) {
  .retention-tab > div > .grid:first-child {
    grid-template-columns: 1fr !important;
    gap: 8px !important;
  }
  .retention-tab > div > .grid:first-child > .card {
    flex-direction: row !important;
    align-items: center !important;
    justify-content: space-between !important;
    gap: 12px !important;
    padding: 12px 14px !important;
  }
  .retention-tab > div > .grid:first-child > .card > div:nth-child(1) {
    flex: 1;
  }
  .retention-tab > div > .grid:first-child > .card > div:nth-child(2) {
    margin-top: 0 !important;
    font-size: 20px !important;
  }
  .retention-tab > div > .grid:first-child > .card > div:nth-child(3) {
    display: none;
  }
}

/* На промежутке 481-720px — авто-fit, чтобы не было дыр и подписи не рвались */
@media (min-width: 481px) and (max-width: 720px) {
  .retention-tab > div > .grid:first-child {
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)) !important;
  }
}

/* (5) Когортные ячейки — убираем «чип» (padding+border-radius+inline-block),
   заливку переносим на саму td. JSX трогать нельзя, поэтому глушим inline-стиль
   через !important. Селектор узкий: только div с inline-block+cyan-rgb внутри
   центрированных моно-ячеек таблицы аналитики. */
.retention-tab .card > table.t td.center.mono > div[style*="inline-block"][style*="cyan-rgb"] {
  display: block !important;
  padding: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  color: var(--text) !important;
  min-width: 0 !important;
  font-weight: 500 !important;
}
/* Заливку переносим на td. Базовая cyan-плёнка — мягкая, не пестрит.
   Конкретные оттенки задаются через :has() где доступно — иначе остаётся
   единая мягкая заливка. */
.retention-tab .card > table.t td.center.mono:has(> div[style*="inline-block"][style*="cyan-rgb"]) {
  background: rgba(var(--cyan-rgb), 0.06);
  transition: background 140ms ease;
}
.retention-tab .card > table.t tbody tr:hover td.center.mono:has(> div[style*="inline-block"][style*="cyan-rgb"]) {
  background: rgba(var(--cyan-rgb), 0.12);
}

/* (8) Подвкладки аналитики на ≤480 — горизонтальная лента с snap, без переноса.
   Скоп строго через aria-label, чтобы не задеть .tab-pills в других местах
   (Сеть, SMS, Server и т.д. — у них другие aria-label или их нет). */
@media (max-width: 480px) {
  .tab-pills[aria-label="Разделы аналитики"] {
    width: 100%;
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .tab-pills[aria-label="Разделы аналитики"]::-webkit-scrollbar { display: none; }
  .tab-pills[aria-label="Разделы аналитики"] > .tab-pill {
    flex: 0 0 auto;
    scroll-snap-align: start;
  }
}

/* (11) Подзаголовок «% удержанных · последние 6 недель» — на широких
   ограничиваем ширину, чтобы не висел в правом краю. */
@media (min-width: 1100px) {
  .retention-tab .card-h .sub {
    max-width: 60%;
    text-align: right;
  }
}

/* (12) ОТКАЧЕНО — единый канон активной подвкладки (плотная cyan-заливка)
   используется во всех табах сайта (SMS «Активные/Архив», Сеть, Server и т.д.).
   Менять локально только в аналитике — нарушение единства дизайн-системы. */

/* (13) ОТКАЧЕНО — кнопки Период/Экспорт должны оставаться справа (стандартное
   место всех панелей). Сдвиг влево ломал вёрстку шапки. */

/* (6) ОТКАЧЕНО — узить только Отчёты ломало единство с соседями (Обзор/
   Атрибуция/Устройства всё ещё на полную ширину). Это вопрос общего
   канона для всего сайта, не локальная правка одной вкладки. */

/* (5) Когортные ячейки — растянутый диапазон opacity по проценту через
   data-bucket. Базовая мягкая плёнка остаётся, плюс точечные градации.
   Применяется к .cohort-cell (класс уже стоит на td в JSX). */
.retention-tab .cohort-cell { background: rgba(var(--cyan-rgb), 0.06); }
.retention-tab .cohort-cell[data-bucket="0"] { background: rgba(var(--cyan-rgb), 0.06); }
.retention-tab .cohort-cell[data-bucket="1"] { background: rgba(var(--cyan-rgb), 0.10); }
.retention-tab .cohort-cell[data-bucket="2"] { background: rgba(var(--cyan-rgb), 0.16); }
.retention-tab .cohort-cell[data-bucket="3"] { background: rgba(var(--cyan-rgb), 0.24); }
.retention-tab .cohort-cell[data-bucket="4"] { background: rgba(var(--cyan-rgb), 0.34); }
.retention-tab .cohort-cell[data-bucket="5"] { background: rgba(var(--cyan-rgb), 0.46); }

/* ===== /RETENTION-FIX ===================================================== */

/* =========================================================================
   CONVERSION-FIX: пакет правок подвкладки Аналитика → Отчёты → Конверсия
   (2026-06-15). Только override и добавления, существующее не удалено.
   Все правила скоупим под .funnel-v4 чтобы не задеть дашборд (общие классы).
   ========================================================================= */

/* (6) «КОНВЕРСИЯ» каплоком — убираем text-transform: uppercase у подписи
       в шапке воронки. Letter-spacing оставляем как в OVR-37 (0.7px) —
       читается нормально и без верхнего регистра. */
.funnel-v4 .fh-arc-lbl {
  text-transform: none;
}

/* (11) Кружки-номера ступеней (1-6) — на бледных нижних ступенях цифра
        цвета stage-color почти не видна. Делаем цифру всегда читабельной
        (var(--text)), а stage-color оставляем в рамке кружка для индикации
        шага. */
.funnel-v4 .fv-num {
  color: var(--text);
  border-color: var(--stage-color);
}

/* (13) На 1920 бары не доходят до правого края — гарантируем, что
        контейнер бара занимает всю доступную ширину ячейки grid. */
.funnel-v4 .fv-bar-wrap {
  width: 100%;
}

/* (12) Шапка воронки на 360 разваливается — крупный % сам по себе,
        счётчики ниже плохо помещаются. На ≤480 уменьшаем .fh-arc-pct
        с 44px до ~32px и переводим .funnel-hero в колонку. */
@media (max-width: 480px) {
  .funnel-v4 .funnel-hero {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }
  .funnel-v4 .fh-arc-pct {
    font-size: 32px;
    letter-spacing: -0.5px;
  }
  .funnel-v4 .fh-arc-lbl {
    font-size: 11px;
    margin-top: 2px;
  }
}

/* (4) Каскадное появление баров: JSX выставляет inline animationDelay
        (i * 80ms) для .fv-bar. При prefers-reduced-motion обнуляем
        задержку и длительность, чтобы пользователь не ждал «стекания».
        Глобальный wildcard выше уже глушит animation-duration, но
        inline style имеет приоритет — здесь добавляем !important на
        animation-delay/animation-duration именно для .fv-bar. */
@media (prefers-reduced-motion: reduce) {
  .funnel-v4 .fv-bar {
    animation-delay: 0ms !important;
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ===== /CONVERSION-FIX ==================================================== */

/* ===== DEVICES-FIX ========================================================
   Точечные правки таба Аналитика → Отчёты → Устройства. */

/* (DEV-4) На планшете (700-1023px) третья карточка «Версии Android» одна слева
   в нижнем ряду, справа пустота. Растягиваем её на оба столбца. */
@media (min-width: 700px) and (max-width: 1023px) {
  .devices-tab > .card:nth-child(3) {
    grid-column: 1 / -1;
  }
}

/* ===== /DEVICES-FIX ======================================================= */

/* ===== LIFETIME-FIX =======================================================
   Точечные правки таба Аналитика → Отчёты → Время жизни. */

/* (LT-anim) Keyframes для отрисовочной анимации графиков (используются опт-ин
   через prop animate={true} в BarChart/LineChart). */
@keyframes chart-bar-grow {
  from { transform: scaleY(0); opacity: 0; }
  to   { transform: scaleY(1); opacity: 1; }
}
@keyframes chart-draw-line {
  to { stroke-dashoffset: 0; }
}
@keyframes chart-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  /* Уважение к системной настройке — анимации мгновенны. */
  [style*="chart-bar-grow"],
  [style*="chart-draw-line"],
  [style*="chart-fade-in"] {
    animation-duration: 0.01ms !important;
    animation-delay: 0ms !important;
  }
}

/* (LT-4) На 360 таблица «Долгоживущие устройства» обрезается — оборачиваем
   через .table-wrap, в JSX уже стоит. Здесь добавляем зебру и sticky 1-й колонке
   для удобства скролла. */
@media (max-width: 480px) {
  .lifetime-tab .card > .table-wrap > table.t th,
  .lifetime-tab .card > .table-wrap > table.t td {
    padding: 8px 10px;
    font-size: 12px;
    white-space: nowrap;
  }
}

/* (LT-5) На 768 подзаголовки шапки карточек пропадают. Глобальное правило
   .card-h .sub { display:none } на ≤1100 прячет их по всему сайту — перебиваем
   локально для lifetime-tab и пускаем на новую строку под h3. */
@media (max-width: 1023px) {
  .lifetime-tab .card-h {
    flex-wrap: wrap;
    row-gap: 4px;
  }
  .lifetime-tab .card-h .sub {
    display: block !important;
    flex-basis: 100%;
  }
}

/* ===== /LIFETIME-FIX ====================================================== */

/* ===== USSD-FIX ===========================================================
   Точечные правки таба Аналитика → Отчёты → USSD. */

/* (USSD-5) На 768/1024 подзаголовки шапки карточек («за 24ч», «372 ошибки сегодня»)
   пропадают из-за глобального правила .card-h .sub display:none на ≤1100.
   Перебиваем локально и пускаем sub на новую строку под h3. */
@media (max-width: 1023px) {
  .ussd-tab .card-h {
    flex-wrap: wrap;
    row-gap: 4px;
  }
  .ussd-tab .card-h .sub {
    display: block !important;
    flex-basis: 100%;
  }
}

/* (USSD-2 SKIP) На 1600+ бары растянуты — useContainerWidth внутри BCA не
   реагирует на CSS max-width родителя, нужна правка самого BarChart. Оставил
   как есть (minor) — на 1920 читаемость не страдает, просто карточки шире
   чем у премиум-эталона. К общесайтовой задаче «макс-ширина контента». */

/* ===== /USSD-FIX ========================================================== */

/* ===== ACTIVITY-FIX =======================================================
   Точечные правки таба Аналитика → Отчёты → Активность. */

/* (ACT-2) На 768/1024 подзаголовки шапки карточек («час × день недели · ярче =
   больше активности», «% оставшихся через 7 дней») пропадают из-за глобального
   правила .card-h .sub display:none на ≤1100. Перебиваем для activity-tab. */
@media (max-width: 1023px) {
  .activity-tab .card-h {
    flex-wrap: wrap;
    row-gap: 4px;
  }
  .activity-tab .card-h .sub {
    display: block !important;
    flex-basis: 100%;
  }
}

/* ===== /ACTIVITY-FIX ====================================================== */

/* ===== ATTRIBUTION-FIX ====================================================
   Точечные правки таба Аналитика → Атрибуция. */

/* (ATTR-1) На 360 шапка зажата — описание сжимается в 80-120px и переносится
   по 1 слову на строку. На ≤640 кнопки уходят под текст в отдельную строку. */
@media (max-width: 640px) {
  .attribution-head {
    flex-direction: column;
    gap: 12px;
    align-items: stretch !important;
  }
  .attribution-head > .row.gap-2 {
    width: 100%;
    justify-content: flex-end;
  }
}

/* (ATTR-2) На 360 таблицы «Топ-10 источников» и «Все установки» обрезаются —
   .table-wrap уже стоит обёрткой, но overflow-x:auto на ней может быть
   перебит inline border:0. Явно ставим скролл. */
.attribution-page .table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* (ATTR-3) Левая карточка «Топ-10 источников» провисает — равняем высоту с
   соседней (с диаграммой). */
.attribution-charts {
  align-items: stretch;
}
.attribution-charts > .card {
  display: flex;
  flex-direction: column;
}
.attribution-charts > .card > .table-wrap {
  flex: 1;
}

/* (ATTR-leg) Компактная легенда доната — ограничиваем ширину и центрируем,
   чтобы имена и числа не разбегались огромным коридором. */
.attribution-legend {
  max-width: 320px;
  margin-left: auto;
  margin-right: auto;
  width: 100%;
}

/* (ATTR-5) На 768/1024 подзаголовки шапок карточек («сборки и установки
   по тегам», «доля по источникам») пропадают — глобальное правило
   .card-h .sub display:none на ≤1100 прячет их. Перебиваем для attribution. */
@media (max-width: 1023px) {
  .attribution-page .card-h {
    flex-wrap: wrap;
    row-gap: 4px;
  }
  .attribution-page .card-h .sub {
    display: block !important;
    flex-basis: 100%;
  }
}

/* ===== /ATTRIBUTION-FIX =================================================== */

/* ===== AV-VERSIONS-FIX ====================================================
   Правки подвкладки Инфраструктура → Билдер APK → Версии. */

@media (max-width: 480px) {
  .av-page .av-kpi-grid > .card > div:first-child {
    letter-spacing: 0.15px !important;
    font-size: 10px !important;
  }
  .av-page .av-kpi-grid > .card {
    padding: 12px 14px !important;
  }
}

@media (max-width: 720px) {
  .av-page .table-wrap {
    scrollbar-width: thin;
  }
  .av-page .table-wrap::-webkit-scrollbar { height: 6px; }
  .av-page .table-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
  .av-page .table-wrap > table.t {
    min-width: 720px;
  }
  .av-page .filter-bar {
    flex-wrap: wrap;
  }
  .av-page .filter-bar > .field {
    flex-basis: 100% !important;
    min-width: 0 !important;
  }
}

/* ===== /AV-VERSIONS-FIX =================================================== */

/* ===== CF-FIX =============================================================
   Правки страницы Инфраструктура → Cloudflare-аккаунты. */

@media (max-width: 900px) {
  /* (1) Таблица CF-аккаунтов имеет суммарный min-width ~790px (включая колонку
     действий) и не помещается на 768 и ниже. Включаем видимый тонкий
     горизонтальный скроллбар внутри карточки и фиксируем минимальную ширину. */
  .cf-page .table-wrap {
    overflow-x: auto;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
  }
  .cf-page .table-wrap::-webkit-scrollbar { height: 6px; }
  .cf-page .table-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
  .cf-page .table-wrap > table.t {
    min-width: 820px;
  }

  /* (2) Ряд фильтров «Все / Живые / Не работают / Не проверены» обрезается
     на узких — даём родителю прокрутку, плашки сохраняют ширину. */
  .cf-page .cf-filter-pills {
    overflow-x: auto;
    scrollbar-width: thin;
    max-width: 100%;
  }
  .cf-page .cf-filter-pills::-webkit-scrollbar { height: 4px; }
  .cf-page .cf-filter-pills > button { flex-shrink: 0; }

  /* (3) Поиск на узких — на всю ширину строки под фильтрами. */
  .cf-page .cf-search-wrap { width: 100%; }
  .cf-page .cf-search-wrap > input { width: 100% !important; }
}

/* ===== /CF-FIX ============================================================ */

/* ===== DOM-FIX ============================================================
   Правки страницы Инфраструктура → Домены. */

@media (max-width: 900px) {
  /* (1) Таблица доменов широкая (домен+статус+авточек+алерт+действия) — на
     360/768 не помещается. Включаем видимый тонкий скроллбар + min-width. */
  .dom-page .table-wrap {
    overflow-x: auto;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
  }
  .dom-page .table-wrap::-webkit-scrollbar { height: 6px; }
  .dom-page .table-wrap::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
  .dom-page .table-wrap > table.t {
    min-width: 780px;
  }
}

@media (max-width: 480px) {
  /* (2) На 360 шапка действий «Авто-чек / Купить через Dynadot / Добавить»
     уезжает за край — позволяем переносить. */
  .dom-page > .row.justify-between > .row.gap-2 {
    flex-wrap: wrap;
    justify-content: flex-start;
  }
}

/* (3) Анимация раскрытия формы добавления домена/CF-аккаунта.
   Йохан попросил — на CF тоже работает (общий класс). */
.dom-add-form-anim,
.cf-add-form-anim {
  animation: domFormSlideDown 220ms cubic-bezier(0.2, 0.7, 0.2, 1);
  transform-origin: top center;
  overflow: hidden;
}
@keyframes domFormSlideDown {
  0%   { opacity: 0; transform: translateY(-6px) scaleY(0.96); max-height: 0; }
  100% { opacity: 1; transform: translateY(0)    scaleY(1);    max-height: 1500px; }
}

/* ===== /DOM-FIX =========================================================== */

/* ===== PROFILE-FIX 2026-06-16 ============================================
   Перенос inline-стилей ProfileSection / ThemeSwitcher в классы,
   stagger-анимация карточек, читаемый focus-ring у .input,
   .avatar/.avatar-lg общий, max-width формы на 1920.
   ========================================================================= */

/* — стопка карточек профиля — */
.profile-stack { gap: 20px; }
.profile-form { display: flex; flex-direction: column; gap: 16px; }

/* — строка с аватаром — */
.profile-avatar-row {
  display: flex; flex-wrap: wrap; gap: 16px;
  align-items: center; padding: 4px 0;
}
.profile-avatar-actions {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; justify-content: center;
}

/* — поля формы профиля: max-width чтобы на 1920 не растягивало — */
.profile-fields { gap: 16px; max-width: 880px; }
.profile-card-anim form .pw-form,
.profile-card-anim .pw-form { max-width: 880px; }

/* — ряд кнопок Сохранить/Отменить — */
.profile-actions {
  align-items: center; gap: 10px; flex-wrap: wrap;
}

/* — единый аватар, переиспользуется в Команде/Профиле — */
.avatar {
  display: inline-grid; place-items: center;
  border-radius: 50%; overflow: hidden;
  flex-shrink: 0;
  background: var(--card-2);
  color: var(--text-1);
  font-weight: 600;
}
img.avatar { object-fit: cover; }
.avatar.avatar-lg { width: 72px; height: 72px; font-size: 24px; }
.avatar.avatar-sm { width: 28px; height: 28px; font-size: 11px; }
.avatar.avatar-initials {
  background: linear-gradient(135deg, var(--cyan), var(--cyan-dim));
  color: var(--bg);
  font-weight: 700;
}

/* — Theme Switcher (вынос inline) — */
.theme-block { margin-top: 4px; }
.theme-block-label {
  letter-spacing: .5px; text-transform: uppercase; font-weight: 600;
}
.theme-grid {
  display: grid; grid-template-columns: repeat(3, minmax(180px, 1fr));
  gap: 10px; max-width: 720px;
}
.theme-card {
  background: var(--card-2);
  border: 2px solid transparent;
  border-radius: 10px;
  padding: 14px 12px 12px;
  cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  transition: border-color 160ms ease, background-color 160ms ease, box-shadow 160ms ease;
  color: var(--text-2);
}
.theme-card:hover { border-color: var(--border); }
.theme-card.active {
  background: var(--cyan-dim);
  border-color: var(--cyan);
  color: var(--cyan);
}
.theme-card:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(45, 212, 191, .25);
}
.theme-card-label { font-size: 12px; font-weight: 500; }
.theme-dots { display: flex; gap: 6px; }
.theme-dot {
  width: 14px; height: 14px; border-radius: 50%;
  border: 1px solid var(--border-2);
  display: inline-block;
}
@media (max-width: 480px) {
  .theme-grid {
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  }
  .theme-card { min-height: 96px; }
  .profile-actions > .btn { flex: 1; min-width: 110px; }
}

/* — читаемый focus-ring на .input (заменяет 3% белый) — */
.input:focus,
.input:focus-visible {
  outline: none;
  border-color: var(--cyan);
  box-shadow: 0 0 0 3px rgba(45, 212, 191, .18);
}

/* — stagger-появление трёх карточек профиля — */
/* Только opacity — без transform. Иначе translateY оставляет родителю
   containing block, и position:fixed модалок внутри карточки лочится в ней,
   а не на весь viewport (модалка обрезается размером карточки). */
@keyframes profileCardFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.profile-card-anim {
  animation: profileCardFadeIn 280ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.profile-card-anim-1 { animation-delay: 0ms; }
.profile-card-anim-2 { animation-delay: 120ms; }
.profile-card-anim-3 { animation-delay: 240ms; }
@media (prefers-reduced-motion: reduce) {
  .profile-card-anim { animation: none; }
}

/* ===== /PROFILE-FIX ====================================================== */

/* ===== SECURITY-FIX 2026-06-16 ===========================================
   Перенос inline-стилей SecuritySection в классы, stagger карточек,
   mobile table-wrap, btn-danger варианты, Toggle transition,
   live-dot, sec-modal-*.
   ========================================================================= */

.sec-stack { gap: 20px; }

.sec-toggle-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 0 16px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 16px;
  gap: 16px;
}
.sec-toggle-title { font-weight: 500; }

.sec-info-strip {
  margin-top: 4px;
  padding: 10px 12px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  display: flex; align-items: center; gap: 8px;
  color: var(--text-3);
  font-size: 12.5px;
}

/* — обёртка для скролла таблиц на мобайле — */
.sec-table-wrap {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 8px;
}
.sec-table {
  background: var(--card-2);
  border-radius: 8px;
  overflow: hidden;
  min-width: 560px;
  transition: opacity 200ms ease;
}
.sec-table tr { cursor: default; }
.sec-ip-cell { color: var(--cyan); font-size: 12.5px; }
.sec-loc-cell { font-size: 12px; color: var(--text-2); }
.sec-user-badge { font-size: 10px; }
.sec-this-badge { font-size: 10px; }
.sec-live { color: var(--green); font-size: 12.5px; }
.nowrap-sm { white-space: nowrap; }

@media (max-width: 1024px) {
  .sec-table th:nth-child(2),
  .sec-table td:nth-child(2) { display: none; }
}

/* — live pulse точка — */
.live-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--green);
  display: inline-block; margin-right: 4px;
  box-shadow: 0 0 0 0 rgba(45, 212, 191, .6);
  animation: liveDotPulse 1.8s ease-in-out infinite;
}
@keyframes liveDotPulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(45, 212, 191, .55); }
  50%      { box-shadow: 0 0 0 6px rgba(45, 212, 191, 0); }
}

/* — форма добавления IP — */
.sec-add-form {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: 12px;
}
.sec-add-form > .input.mono { flex: 1 1 220px; min-width: 180px; font-size: 12.5px; }
.sec-add-form > .input:not(.mono) { flex: 2 1 220px; min-width: 200px; font-size: 12.5px; }
.sec-add-form .sec-add-select { flex: 1 1 200px; min-width: 180px; }
@media (max-width: 768px) {
  .sec-add-form > * { flex: 1 1 100% !important; min-width: 0 !important; }
}

/* — danger варианты кнопок (вынос из inline) — */
.btn.btn-danger-outline {
  color: var(--danger);
  border-color: var(--danger-border, rgba(255, 71, 87, 0.3));
  transition: border-color 140ms ease, background-color 140ms ease;
}
.btn.btn-danger-outline:hover:not(:disabled) {
  border-color: var(--danger);
  background: rgba(255, 71, 87, 0.08);
}
.btn.btn-danger-ghost {
  background: transparent;
  border: 1px solid transparent;
  color: var(--danger);
  transition: background-color 140ms ease, border-color 140ms ease;
}
.btn.btn-danger-ghost:hover:not(:disabled) {
  background: rgba(255, 71, 87, 0.10);
  border-color: var(--danger-border, rgba(255, 71, 87, 0.3));
}

/* — модалки security: иконка + текст + карточка — */
.sec-modal-icon {
  width: 38px; height: 38px; border-radius: 10px;
  background: var(--danger-dim);
  display: grid; place-items: center;
  color: var(--danger);
  border: 1px solid var(--danger-border, rgba(255, 71, 87, 0.3));
  flex-shrink: 0;
}
.sec-modal-text {
  font-size: 13.5px; color: var(--text-2);
  line-height: 1.55; margin-bottom: 12px;
}
.sec-modal-desc {
  font-size: 13px; line-height: 1.6; margin-bottom: 12px;
}
.sec-modal-card {
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  font-size: 12.5px;
}
.sec-kill-list {
  display: flex; flex-direction: column; gap: 8px;
  max-height: 240px; overflow-y: auto;
}
.sec-kill-list-row {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px;
}

/* — stagger карточек Security — */
.sec-card-anim {
  animation: profileCardFadeIn 280ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.sec-card-anim-1 { animation-delay: 0ms; }
.sec-card-anim-2 { animation-delay: 120ms; }
.sec-card-anim-3 { animation-delay: 240ms; }

/* — Toggle transition box-shadow (фикс резкого glow) — */
.toggle { transition: background 160ms ease, box-shadow 200ms ease, opacity 160ms ease; }

/* ===== /SECURITY-FIX ===================================================== */

/* ===== APPCATS-FIX 2026-06-16 ============================================
   Категории приложений: max-width форм, mobile-стэк, .btn-icon-danger,
   stagger, empty-state.
   ========================================================================= */

.appcat-stack { gap: 20px; }

.appcat-card-anim {
  animation: profileCardFadeIn 280ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
.appcat-card-anim-1 { animation-delay: 0ms; }

/* — формы привязки и новой категории на всю ширину карточки — */
.appcat-bind-form,
.appcat-new-cat-form {
  display: flex; flex-wrap: wrap; gap: 8px;
  align-items: flex-end;
  margin-bottom: 20px;
}
.appcat-bind-form .field,
.appcat-new-cat-form .field {
  margin-bottom: 0;
}
.appcat-field-pkg { flex: 1 1 240px; min-width: 200px; }
.appcat-field-cat { flex: 0 0 220px; min-width: 180px; }
.appcat-btn-add { white-space: nowrap; }

@media (max-width: 600px) {
  .appcat-bind-form .field,
  .appcat-new-cat-form .field,
  .appcat-field-pkg,
  .appcat-field-cat {
    flex: 1 1 100% !important;
    min-width: 0 !important;
  }
  .appcat-btn-add {
    width: 100%;
    justify-content: center;
  }
}

/* — блок «Категории» — */
.appcat-cats-block {
  border-top: 1px solid var(--border);
  padding-top: 16px;
}
.appcat-cats-label {
  letter-spacing: .5px; text-transform: uppercase; font-weight: 600;
}
.appcat-cats-list { gap: 16px; }
.appcat-cat-row {
  padding: 10px 12px;
  background: var(--card-2);
  border: 1px solid transparent;
  border-radius: 8px;
  transition: border-color 140ms ease;
}
.appcat-cat-row:hover { border-color: var(--border); }

.appcat-rename-input {
  width: 220px; padding: 4px 10px; font-size: 13px;
}

/* — danger вариант для .btn.icon — */
.btn.icon.btn-icon-danger {
  color: var(--danger);
  transition: background-color 140ms ease, color 140ms ease;
}
.btn.icon.btn-icon-danger:hover:not(:disabled) {
  background: rgba(255, 71, 87, 0.10);
  color: var(--danger);
}

/* — empty-state — */
.appcat-empty {
  display: flex; gap: 12px; align-items: center;
  padding: 16px 14px;
  background: var(--card-2);
  border: 1px dashed var(--border);
  border-radius: 8px;
  color: var(--text-3);
  margin-bottom: 20px;
}

/* ===== /APPCATS-FIX ====================================================== */

/* ===== USERS-FIX 2026-06-16 ==============================================
   Пользователи: mobile overflow-x, search-row margin-left auto,
   stagger карточки, иерархия action-кнопок, btn-icon-danger reuse.
   ========================================================================= */

.users-stack { gap: 20px; }

.users-card-anim {
  animation: profileCardFadeIn 280ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

/* — search row: счётчик отъезжает вправо — */
.users-search-row {
  align-items: center;
  flex-wrap: wrap;
}
.users-search-wrap {
  position: relative;
  flex: 1 1 280px;
  max-width: 360px;
}
.users-search-count {
  margin-left: auto;
  padding-left: 8px;
  white-space: nowrap;
}

/* — таблица: горизонтальный скролл на мобайле — */
.users-table-wrap {
  border-radius: 8px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--card-2);
}
.users-table {
  background: var(--card-2);
  border-radius: 8px;
  width: 100%;
  min-width: 720px;
}

.users-name-wrap { min-width: 0; }
.users-name {
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 240px;
}
.users-pending {
  margin-top: 3px; font-size: 10px;
  display: inline-flex; align-items: center; gap: 4px;
}
.users-pending-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--warn); display: inline-block;
}

.users-actions { justify-content: flex-end; flex-wrap: wrap; }

@media (max-width: 768px) {
  .users-name { max-width: 160px; }
  .users-table { min-width: 640px; }
}
@media (max-width: 480px) {
  .users-search-wrap { max-width: 100%; }
  .users-search-count { margin-left: 0; padding-left: 0; }
}

/* ===== /USERS-FIX ======================================================== */

/* ===== ROLES-FIX 2026-06-16 ==============================================
   Роли: responsive grid (2 на 1308), role-card header без обрезки имени,
   .role-color-* классы, stagger карточек, перевод .perm-btn hover в translateY.
   ========================================================================= */

.roles-stack { gap: 20px; }

.roles-card-anim {
  animation: profileCardFadeIn 280ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

.roles-actions {
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.roles-saved-flash {
  font-size: 12px; color: var(--green);
  display: inline-flex; align-items: center; gap: 6px;
  animation: profileCardFadeIn 200ms ease-out both;
}

/* — сетка карточек ролей — на 1308 две колонки, чтобы имена не обрезались — */
.roles-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 1500px) {
  .roles-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 1100px) and (max-width: 1499px) {
  .roles-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 600px) {
  .roles-grid { grid-template-columns: 1fr; }
}

/* — stagger карточек ролей — */
.role-card-anim {
  animation: profileCardFadeIn 280ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

/* — header карточки роли: имя растягивается, бейджи прижаты — */
.role-card-head {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 8px;
  min-width: 0;
}
.role-card-dot {
  width: 10px; height: 10px; border-radius: 50%;
  flex-shrink: 0;
}
.role-card-name {
  font-weight: 600;
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.role-card-lock {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: 9px;
  flex-shrink: 0;
  padding: 2px 5px;
  border-radius: 4px;
  background: var(--cyan-dim);
  color: var(--cyan);
}
.role-card-count {
  flex-shrink: 0;
  font-family: var(--mono, ui-monospace, SFMono-Regular, monospace);
  font-size: 11px;
  color: var(--text-3);
  background: var(--card-2);
  border: 1px solid var(--border);
  padding: 1px 7px;
  border-radius: 10px;
  min-width: 24px;
  text-align: center;
}
.role-card-desc {
  font-size: 12px;
  line-height: 1.5;
  min-height: 34px;
}

/* — палитра выбора цвета — */
.role-color-picker {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}
.role-color-swatch {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  padding: 0;
  transition: border-color 140ms ease, transform 140ms ease;
}
.role-color-swatch:hover:not(:disabled) {
  transform: scale(1.08);
}
.role-color-swatch:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(45, 212, 191, 0.25);
}
.role-color-swatch.active {
  border-color: var(--text);
}
.role-color-custom {
  display: grid; place-items: center;
  position: relative;
  overflow: hidden;
  color: var(--text-3);
  border-style: dashed;
  border-color: var(--text-3);
}
.role-color-custom.active {
  border-style: solid;
  border-color: var(--text);
}
.role-color-custom input[type="color"] {
  position: absolute; inset: 0;
  opacity: 0;
  cursor: pointer;
  padding: 0; border: 0;
}

/* — .perm-btn hover: убрать scale (соседи прыгают) — */
.perm-btn { transition: background-color 140ms ease, border-color 140ms ease, filter 140ms ease, transform 140ms ease; }
.perm-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  filter: brightness(1.08);
}

/* ===== /ROLES-FIX ======================================================== */

/* Матрица ролей: нижние углы скролл-обёртки наследуют border-radius карточки */
.perm-matrix-scroll {
  border-bottom-left-radius: 12px;
  border-bottom-right-radius: 12px;
  overflow: auto;
}
.perm-matrix-scroll > table.perm-matrix {
  border-bottom-left-radius: 12px;
  border-bottom-right-radius: 12px;
  overflow: hidden;
}

/* ===== AUDIT-FIX 2026-06-16 ==============================================
   История действий: фильтры, table-wrap mobile, audit-row clickable,
   audit-detail модалка.
   ========================================================================= */

.audit-card-anim {
  animation: profileCardFadeIn 280ms cubic-bezier(0.2, 0.7, 0.2, 1) both;
}

.audit-actions { align-items: center; flex-wrap: wrap; gap: 8px; }

.audit-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
}
.audit-search-wrap {
  position: relative;
  flex: 1 1 280px;
  max-width: 360px;
}
.audit-filter-block {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.audit-filter-label {
  align-self: center; margin-right: 2px;
}
.audit-who-select {
  min-width: 160px;
}

/* — таблица с горизонт. скроллом на мобайле — */
.audit-table-wrap {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border-radius: 8px;
  background: var(--card-2);
}
.audit-table {
  background: var(--card-2);
  border-radius: 8px;
  width: 100%;
  min-width: 720px;
}

/* Зарезервированная высота — таблица не «прыгает» когда последняя страница неполная.
   8 строк × 49px + thead (~42) + paddings ≈ 480. */
.audit-table-wrap { min-height: 480px; }
.audit-table tbody tr { height: 49px; max-height: 49px; }
.audit-table tbody td {
  vertical-align: middle;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* «Детали» с моноширинным текстом — обрезаем многоточием на одну строку */
.audit-table tbody td.audit-what { max-width: 360px; }
/* Бейджи типов — единая ширина чтобы колонка не «дышала» */
.audit-table .badge {
  min-width: 130px;
  display: inline-flex;
  justify-content: center;
  box-sizing: border-box;
  font-size: 10.5px;
  padding: 3px 8px;
  white-space: nowrap;
}
/* Колонка «Тип» — фиксированная ширина под самый длинный бейдж */
.audit-table th:last-child,
.audit-table td:last-child { width: 150px; min-width: 150px; }

.audit-row { cursor: pointer; transition: background-color 140ms ease; outline: none; }
.audit-row:hover { background: var(--card); }
/* Focus только цвет фона, без outline-обводки (tr выглядел как «линия на весь экран» из-за outline). */
.audit-row:focus,
.audit-row:focus-visible {
  outline: none;
  background: var(--card);
  box-shadow: inset 3px 0 0 var(--cyan);
}
.audit-time { font-size: 12px; }
.audit-live-dot { margin-right: 5px; vertical-align: middle; }
.audit-who-cell { align-items: center; }
.audit-what { font-size: 12px; color: var(--text-2); }

.audit-detail-row {
  display: flex; align-items: center; gap: 12px;
  padding: 6px 0;
  border-bottom: 1px dashed var(--border);
}
.audit-detail-row:last-child { border-bottom: none; }
.audit-detail-row .muted { min-width: 90px; }

.audit-pager {
  flex-wrap: wrap; gap: 8px;
}

@media (max-width: 600px) {
  .audit-search-wrap { max-width: 100%; flex-basis: 100%; }
  .audit-filters { gap: 8px; }
  .audit-actions .btn { flex: 1 1 auto; justify-content: center; }
}

/* ===== /AUDIT-FIX ======================================================== */

/* 2026-06-19 Phase 8 fix #7: скрывать текст в кнопках шапки на узких экранах. */
@media (max-width: 480px) {
  .hide-on-narrow { display: none !important; }
}

/* ===== APK BUILD PROGRESS FLOATER ======================================== */
/* 2026-06-25: плавашка прогресса сборки APK, видна на любой странице. */
.bpf-wrap {
  position: fixed;
  right: 18px;
  bottom: 18px;
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
}
.bpf-item {
  pointer-events: auto;
  width: 280px;
  background: var(--card-2);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  box-shadow: 0 12px 32px rgba(0,0,0,0.35);
  animation: bpfIn 220ms cubic-bezier(.2,.7,.3,1);
}
@keyframes bpfIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.bpf-row1 {
  display: flex;
  align-items: center;
  gap: 8px;
}
.bpf-lbl {
  flex: 1;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-1, #d8dde4);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bpf-close {
  width: 22px; height: 22px;
  border: 0;
  background: transparent;
  color: var(--text-2);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  border-radius: 4px;
}
.bpf-close:hover { background: var(--card); color: var(--text-1, #d8dde4); }
.bpf-meta {
  margin-top: 6px;
  font-size: 11.5px;
  color: var(--text-2);
}
.bpf-meta-ok  { color: var(--cyan); }
.bpf-meta-err { color: #ef4444; }
.bpf-bar {
  margin-top: 8px;
  height: 4px;
  background: var(--border);
  border-radius: 3px;
  overflow: hidden;
}
.bpf-bar-fill {
  height: 100%;
  background: var(--cyan);
  border-radius: 3px;
  transition: width 380ms linear;
}
.bpf-dl {
  display: inline-flex !important;
  align-items: center;
  margin-top: 10px;
  text-decoration: none;
}
.bpf-error { border-color: rgba(239,68,68,0.4); }

