/* ── T-FIN-SMOOTH-2: фон страницы до загрузки inline-стилей ──
   Чтобы избежать flash of white между рендером каркаса и применением
   per-page <style>. Значение совпадает с переменной --bg на светлой теме.
   Тёмная тема переопределит через :root[data-theme="dark"]. */
html, body {
  background: #F2F5F3;
  font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  color-scheme: light;
}
html[data-theme="dark"] { color-scheme: dark; }
/* Единый вид нативных инпутов даты/времени под платформу (сам пикер остаётся нативным, но следует теме через color-scheme) */
input[type="date"], input[type="datetime-local"], input[type="time"]{
  height:38px; padding:0 12px; border:1.5px solid var(--bdr); border-radius:var(--rm,10px);
  background:var(--gp); font-family:inherit; font-size:13px; color:var(--t); outline:none;
}
input[type="date"]:focus, input[type="datetime-local"]:focus, input[type="time"]:focus{ border-color:var(--gm); }
:root[data-theme="dark"] html,
:root[data-theme="dark"] body,
html[data-theme="dark"],
html[data-theme="dark"] body {
  background: #0F1A14;
}

:root{
  /* Z-index система (18.05): один source of truth для всей платформы.
     Используем семантические уровни вместо магических чисел.
     Шаг между уровнями 200-1000 чтобы между ними можно было вставить
     промежуточный без переделки. */
  --z-sticky: 100;
  --z-dropdown: 300;
  --z-panel: 500;
  --z-modal: 1000;
  --z-overlay: 2000;
  --z-toast: 3000;
  --z-topbar-dd: 800; /* дропдауны топбара (уведомления/профиль) — выше контента (.add-card=300), ниже модалок */
}

/*
 * ══════════════════════════════════════════════════════════════
 *  LASTOP GROUP — Shell Layout (unified)
 *  Файл: web/assets/shell-layout.css
 *
 *  Единый каркас: левый сайдбар (nav) 240px, топбар 56px,
 *  правый сайдбар (right) 300px. Эталон — home-auth.html.
 *
 *  Применяется через класс .lt-shell на <html>. Повышенная
 *  специфичность (html.lt-shell .shell) гарантированно
 *  перекрывает любые .shell{} из inline <style> без !important.
 *
 *  Для двухколоночного каркаса (без правой панели, как chat.html)
 *  используется класс .lt-shell-2col.
 * ══════════════════════════════════════════════════════════════
 */

/* ─────────────────────────────────────────────────────────────
   ТРЁХКОЛОНОЧНЫЙ КАРКАС (по умолчанию, как на home-auth)
   ───────────────────────────────────────────────────────────── */
html.lt-shell .shell{
  display:grid;
  grid-template-columns:240px 1fr 300px;
  grid-template-rows:56px 1fr;
  grid-template-areas:
    "logo topbar topbar"
    "nav  main   right";
  height:100vh;
  height:100dvh;
  gap:10px;
  padding:10px;
}

/* iOS legacy: 100dvh не поддерживается, используем fill-available */
@supports (-webkit-touch-callout: none) and (not (height: 100dvh)){
  html.lt-shell{height:-webkit-fill-available}
  html.lt-shell body{min-height:-webkit-fill-available}
  html.lt-shell .shell{height:-webkit-fill-available}
}

/* Большие экраны 1201–1400 — без промежуточного сжатия.
   Исключаем ошибочные «1400px» брейкпоинты из некоторых страниц. */

/* Средние экраны: компактнее */
@media (max-width:1200px){
  html.lt-shell .shell{
    grid-template-columns:220px 1fr 260px;
  }
}

/* Узкие: прячем правую панель */
@media (max-width:1000px){
  html.lt-shell .shell{
    grid-template-columns:220px 1fr;
    grid-template-areas:
      "logo topbar"
      "nav  main";
  }
  html.lt-shell .right{display:none}
  html.lt-shell .search-wrap{max-width:100%}
}

/* Мобильный альбомный: иконочный nav */
@media (max-width:740px){
  html.lt-shell .shell{
    grid-template-columns:52px 1fr;
  }
  html.lt-shell .nav-item span,
  html.lt-shell .nav-group,
  html.lt-shell .logo-text{display:none}
  html.lt-shell .nav-item{justify-content:center;padding:10px}
}

/* 4K / large desktop — zoom для читаемости */
@media (min-width:1921px) and (min-height:1081px){
  html.lt-shell{zoom:1.18}
  html.lt-shell .shell{
    grid-template-columns:250px 1fr 340px !important; /* !important бьёт inline .shell{280px 1fr 360px !important} — сетка и топбар совпадают */
    gap:12px;
    padding:12px;
    height:calc(100vh / 1.18);
  }
  html.lt-shell .nav{padding:14px 12px 12px}
}

/* ─────────────────────────────────────────────────────────────
   ДВУХКОЛОНОЧНЫЙ КАРКАС (chat.html)
   Никакой правой панели. nav + main.
   ───────────────────────────────────────────────────────────── */
html.lt-shell-2col .shell{
  display:grid;
  grid-template-columns:240px 1fr;
  grid-template-rows:56px 1fr;
  grid-template-areas:
    "logo topbar"
    "nav  main";
  height:100vh;
  height:100dvh;
  gap:10px;
  padding:10px;
}

@supports (-webkit-touch-callout: none) and (not (height: 100dvh)){
  html.lt-shell-2col{height:-webkit-fill-available}
  html.lt-shell-2col body{min-height:-webkit-fill-available}
  html.lt-shell-2col .shell{height:-webkit-fill-available}
}

@media (max-width:1200px){
  html.lt-shell-2col .shell{grid-template-columns:220px 1fr}
}

@media (max-width:1000px){
  html.lt-shell-2col .shell{grid-template-columns:220px 1fr}
}

@media (max-width:740px){
  html.lt-shell-2col .shell{grid-template-columns:52px 1fr}
  html.lt-shell-2col .nav-item span,
  html.lt-shell-2col .nav-group,
  html.lt-shell-2col .logo-text{display:none}
  html.lt-shell-2col .nav-item{justify-content:center;padding:10px}
}

@media (min-width:1921px) and (min-height:1081px){
  html.lt-shell-2col{zoom:1.18}
  html.lt-shell-2col .shell{
    /* !important: перебивает паразитное .shell{...360px!important} из inline-стилей
       обычных 3-колоночных страниц, которое может застрять в #spa-page-style при
       SPA-переходе на чат. Без important оно навязывало чату 3-ю колонку (360px). */
    grid-template-columns:250px 1fr !important;
    gap:12px;
    padding:12px;
    height:calc(100vh / 1.18);
  }
  html.lt-shell-2col .nav{padding:14px 12px 12px}
}

/* ─────────────────────────────────────────────────────────────
   ОБЩИЕ ПРАВИЛА ДЛЯ ЯЧЕЕК КАРКАСА
   (не размеры, но они должны быть едиными: назначение grid-area)
   ───────────────────────────────────────────────────────────── */
html.lt-shell .logo-cell,
html.lt-shell-2col .logo-cell{grid-area:logo}

html.lt-shell .topbar,
html.lt-shell-2col .topbar{grid-area:topbar}

html.lt-shell .nav,
html.lt-shell-2col .nav{grid-area:nav}

html.lt-shell .main,
html.lt-shell-2col .main{grid-area:main}

html.lt-shell .right{grid-area:right}

/* ═══════════════════════════════════════════════════════════════
   ТОПБАР — внутренняя сетка повторяет колонки .shell
   ───────────────────────────────────────────────────────────────
   Цель: правый край поиска совпадает с правым краем main,
         левый край карточки профиля совпадает с левым краем right.

   Сейчас в каждой странице .topbar объявлен через display:flex.
   Мы перекрываем его на display:grid с теми же двумя правыми
   колонками что и в .shell: 1fr 300px (на 1200px — 260px,
   на 1920+ — 340px). Колоночный gap совпадает с .shell (10px,
   на 1920+ — 12px).

   Селектор html.lt-shell .topbar даёт специфичность (0,1,1) и
   перекрывает inline .topbar{display:flex; ...} (0,1,0) без
   !important. flex: initial на потомках сбрасывает остаточные
   inline flex-grow.

   Двухколоночный каркас (.lt-shell-2col, chat.html) сохраняет
   flex — там нет правого сайдбара, к чему выравнивать профиль.
   ═══════════════════════════════════════════════════════════════ */

/* ── Базовый трёхколоночный каркас: 1fr 300px ── */
html.lt-shell .topbar{
  display: grid;
  /* Колонки топбара статично совпадают с main+right из .shell на каждом
     брейкпоинте (оверрайды ниже). БЕЗ subgrid — чтобы не было мигания при
     асинхронном наполнении топбара shell-injector. */
  grid-template-columns: 1fr 300px;
  grid-template-rows: 100%;
  align-items: center;
  column-gap: 10px;
}

html.lt-shell .topbar > .search-wrap{
  grid-column: 1;
  flex: initial;
  width: 100%;
  min-width: 0;
}

html.lt-shell .topbar > .profile-dd-wrap{
  grid-column: 2;
  flex: initial;
  width: 100%;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px; /* зазор между колокольчиком и карточкой профиля */
}

/* ── Карточка профиля растягивается на всю ширину обёртки ── */
html.lt-shell .topbar .topbar-profile{
  min-width: 0;
  flex: 1 1 auto;
  /* По умолчанию padding 6px 52px 6px 12px — большой правый padding для стрелки.
     В растянутой карточке стрелка прижимается к правому краю автоматически
     через margin-left:auto на .tp-arrow, поэтому правый padding можно убавить. */
  padding-right: 12px;
}

/* Внутри растянутой карточки: имя+аватар слева, стрелка справа через margin auto */
html.lt-shell .topbar .topbar-profile .tp-arrow,
html.lt-shell-2col .topbar .topbar-profile .tp-arrow{
  margin-left: auto;
}

/* ── Средние экраны: 1fr 260px (как .shell) ── */
@media (max-width: 1200px){
  html.lt-shell .topbar{
    grid-template-columns: 1fr 260px;
  }
}

/* ── Узкие экраны: правый сайдбар скрыт, топбар одноколоночный ── */
@media (max-width: 1000px){
  html.lt-shell .topbar{
    grid-template-columns: 1fr auto;
  }
  /* На мобиле обёртка профиля остаётся, но карточка профиля скрыта — виден только колокольчик */
  html.lt-shell .topbar > .profile-dd-wrap > .topbar-profile{
    display: none;
  }
  html.lt-shell .topbar > .profile-dd-wrap{
    width: auto;
  }
}

/* ── Мобильный: профиль уже скрыт правилом 1000px, добавлять ничего не нужно ── */

/* ── 4K / large desktop: 1fr 340px (как .shell) ── */
@media (min-width: 1921px) and (min-height: 1081px){
  html.lt-shell .topbar{
    grid-template-columns: 1fr 340px !important; /* !important бьёт inline .topbar{1fr 360px !important} в страницах */
    column-gap: 12px;
  }
}

/* ── Двухколоночный каркас (chat.html): без grid внутри топбара ──
   В chat.html нет правого сайдбара под топбаром, поэтому нет
   границы куда выравнивать профиль. Оставляем flex и просто
   прижимаем профиль к правому краю.
*/
html.lt-shell-2col .topbar{
  display: flex;
  align-items: center;
  gap: 12px;
}

html.lt-shell-2col .topbar > .search-wrap{
  flex: 1 1 auto;
  min-width: 0;
}

html.lt-shell-2col .topbar > .profile-dd-wrap{
  flex: 0 0 300px;
  width: 300px;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Средние экраны: 260px (как .shell на 1200px) */
@media (max-width: 1200px){
  html.lt-shell-2col .topbar > .profile-dd-wrap{
    flex: 0 0 260px;
    width: 260px;
  }
}

/* Узкие: профиль скрывается, остаётся колокольчик в шапке */
@media (max-width: 1000px){
  html.lt-shell-2col .topbar > .profile-dd-wrap{
    flex: 0 0 auto;
    width: auto;
  }
}

/* 4K: 340px */
@media (min-width: 1921px) and (min-height: 1081px){
  html.lt-shell-2col .topbar > .profile-dd-wrap{
    flex: 0 0 340px;
    width: 340px;
  }
}

/* ═══════════════════════════════════════════════════════════════
   ВАРИАНТ B: топбар — две самостоятельные карточки
   ───────────────────────────────────────────────────────────────
   Топбар (.topbar) теряет свою плашку и становится чисто
   grid-контейнером. Поиск (.search-wrap) и обёртка профиля
   (.profile-dd-wrap) становятся отдельными белыми карточками
   шириной по своей grid-cell — то есть ровно по сетке колонок
   .shell под ним.

   Селекторы html.lt-shell X имеют специфичность (0,1,1) и
   гарантированно перекрывают inline-стили .topbar/.search-wrap/
   .topbar-profile из <style> каждой страницы (0,1,0) без
   !important.
   ═══════════════════════════════════════════════════════════════ */

/* ── Общая плашка топбара становится прозрачной ── */
html.lt-shell .topbar,
html.lt-shell-2col .topbar{
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  gap: 10px;
  min-height: 56px;
}

/* ── Поиск — отдельная белая карточка ── */
html.lt-shell .topbar > .search-wrap,
html.lt-shell-2col .topbar > .search-wrap{
  background: var(--w);
  border: 1px solid var(--bdr);
  border-radius: var(--rl);
  box-shadow: var(--sh);
  padding: 0 14px 0 14px;
  min-height: 56px;
  height: 56px;
  align-items: center;
  position: relative;
  display: flex;
}

/* Иконка лупы внутри новой карточки поиска — выровнять под padding */
html.lt-shell .topbar > .search-wrap > .search-icon,
html.lt-shell-2col .topbar > .search-wrap > .search-icon{
  left: 14px;
}

/* Сам input — без собственной обводки и фона, живёт внутри карточки */
html.lt-shell .topbar > .search-wrap > input,
html.lt-shell-2col .topbar > .search-wrap > input{
  background: transparent;
  border: none;
  border-radius: 0;
  height: 36px;
  padding: 0 0 0 22px;
  width: 100%;
  outline: none;
  box-shadow: none;
}
html.lt-shell .topbar > .search-wrap > input:focus,
html.lt-shell-2col .topbar > .search-wrap > input:focus{
  border: none;
  box-shadow: none;
}

/* ── Обёртка профиля — отдельная белая карточка ── */
html.lt-shell .topbar > .profile-dd-wrap{
  background: var(--w);
  border: 1px solid var(--bdr);
  border-radius: var(--rl);
  box-shadow: var(--sh);
  padding: 6px 6px 6px 16px;
  min-height: 56px;
  height: 56px;
  align-items: center;
  /* существующие grid-cell правила оставляем как есть */
}

/* Сама карточка профиля внутри обёртки — теряет свою плашку,
   потому что родитель теперь белая карточка целиком */
html.lt-shell .topbar > .profile-dd-wrap > .topbar-profile{
  background: transparent;
  border: none;
  border-radius: 10px;
  padding: 6px 10px;
  width: 100%;
  cursor: pointer;
  transition: background .15s;
}
html.lt-shell .topbar > .profile-dd-wrap > .topbar-profile:hover{
  background: var(--gp);
}
html.lt-shell .topbar > .profile-dd-wrap > .topbar-profile.open{
  background: var(--gl);
}

/* Дропдаун профиля — позиционирование от обёртки-карточки */
html.lt-shell .topbar > .profile-dd-wrap > .profile-dd{
  top: calc(100% + 8px);
  right: 0;
}

/* ── Двухколоночный каркас (chat.html): обёртка профиля — отдельная белая карточка ── */
html.lt-shell-2col .topbar > .profile-dd-wrap{
  background: var(--w);
  border: 1px solid var(--bdr);
  border-radius: var(--rl);
  box-shadow: var(--sh);
  padding: 6px 6px 6px 16px;
  min-height: 56px;
  height: 56px;
  align-items: center;
}

/* Сама карточка профиля внутри обёртки — теряет свою плашку (родитель уже белая карточка) */
html.lt-shell-2col .topbar > .profile-dd-wrap > .topbar-profile{
  background: transparent;
  border: none;
  border-radius: 10px;
  padding: 6px 10px;
  width: 100%;
  cursor: pointer;
  transition: background .15s;
  flex: 1 1 auto;
  min-width: 0;
}
html.lt-shell-2col .topbar > .profile-dd-wrap > .topbar-profile:hover{
  background: var(--gp);
}
html.lt-shell-2col .topbar > .profile-dd-wrap > .topbar-profile.open{
  background: var(--gl);
}

/* Дропдаун профиля — позиционирование от обёртки-карточки */
html.lt-shell-2col .topbar > .profile-dd-wrap > .profile-dd{
  top: calc(100% + 8px);
  right: 0;
}

/* ── Двухколоночный каркас (chat.html) ── */
/* В chat.html правого сайдбара под топбаром нет, профиль скрыт.
   Поиск — единственная карточка топбара. Она занимает всю ширину
   родителя через flex. */
html.lt-shell-2col .topbar > .search-wrap{
  flex: 1 1 auto;
}

/* ═══════════════════════════════════════════════════════════════
   ГЛОБАЛЬНЫЕ НАСТРОЙКИ — применяются по data-attr на <html>
   Управляются через global-settings.js
   ═══════════════════════════════════════════════════════════════ */

/* Гостевая навигация — заблокированные пункты с замочком */
.nav-item.locked{color:#C8D8D0!important;cursor:pointer}
.nav-item.locked:hover{background:transparent;color:#5A8A6A!important}
.nav-item.locked svg:not(.nav-lock){stroke:#C8D8D0}

/* Адаптивные сайдбары — на больших экранах автоматически расширяются */
@media (min-width: 1400px){
  .shell{
    grid-template-columns: 240px 1fr 240px;
  }
  /* Чат двухколоночный — голое .shell выше навязывает ему 3-ю колонку.
     Возвращаем 2 колонки. Верхняя граница 1920: на zoom-экранах (1921+)
     действует zoom-правило (250px 1fr), чтобы первая колонка чата совпадала
     с обычными страницами (иначе сайдбар/логотип на 10px у́же). */
  @media (max-width: 1920px){
    html.lt-shell-2col .shell{
      grid-template-columns: 240px 1fr !important;
    }
  }
}
@media (min-width: 1700px){
  .shell{
    grid-template-columns: 260px 1fr 280px;
  }
  /* Верхняя граница 1920: на zoom-экранах (1921+) действует zoom-правило выше
     (250px 1fr), чтобы первая колонка чата совпадала с обычными страницами —
     иначе сайдбар/логотип чата на 10px шире. */
  @media (max-width: 1920px){
    html.lt-shell-2col .shell{
      grid-template-columns: 260px 1fr !important;
    }
  }
}
@media (min-width: 1400px){
  html.lt-shell .topbar,
  html.lt-shell-2col .topbar{
    grid-template-columns: 1fr 300px;
  }
}

/* Скрытие кнопки «Написать» на профилях, если получатель не разрешает писать всем.
   Кнопка скрывается только если у текущего юзера в настройках стоит "только контакты" / "никто".
   Реальная проверка получателя делается в самой странице profile_user.html (см. часть E). */
html[data-msg-perm="contacts"] [data-action="write-message"],
html[data-msg-perm="none"] [data-action="write-message"]{
  display: none;
}

/* ═══════════════════════════════════════════════════════════════
   РЕКЛАМНАЯ ПЛАШКА — единый стиль для всех страниц
   Появляется в правом сайдбаре через global-settings.js
   ═══════════════════════════════════════════════════════════════ */
/* ═══ РЕКЛАМНЫЙ БЛОК ═══
   Карточка в палитре платформы: белый фон, зелёный акцент. Раньше блок был
   фиолетовым — чужим цветом, который нигде больше не встречается.
   Рекламодатель показан явно: на деловой площадке имя компании даёт доверие. */
.ad-block{
  background:var(--w); border:1px solid var(--bdr); border-radius:var(--rl,18px);
  overflow:hidden; box-shadow:var(--sh); transition:box-shadow .2s
}
.ad-block:hover{box-shadow:var(--shm)}
.ad-img{width:100%;aspect-ratio:16/9;object-fit:cover;display:block;background:var(--gl)}
.ad-body{padding:14px 15px 15px}
.ad-adv{display:flex;align-items:center;gap:7px;margin-bottom:8px}
.ad-logo{width:22px;height:22px;border-radius:6px;background:var(--gl);display:grid;place-items:center;font-size:10px;font-weight:800;color:var(--g);flex:none;overflow:hidden}
.ad-logo img{width:100%;height:100%;object-fit:cover}
.ad-name{font-size:11px;font-weight:700;color:var(--tm);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ad-label{margin-left:auto;font-size:9px;color:var(--tm);opacity:.6;letter-spacing:.04em;flex:none}
.ad-title{font-size:14px;font-weight:800;line-height:1.3;margin-bottom:5px;color:var(--t)}
.ad-sub{font-size:12px;color:var(--tm);line-height:1.45}
.ad-cta{display:inline-flex;align-items:center;gap:5px;margin-top:11px;font-size:12px;font-weight:700;color:var(--g);text-decoration:none;background:none;border:0;padding:0;cursor:pointer;font-family:inherit}
.ad-cta svg{width:13px;height:13px;stroke:currentColor;stroke-width:2.2;fill:none}

/* Тёмная тема — фиолетовый остаётся, фон чуть приглушаем */
/* Тёмная тема отдельных правил не требует: блок построен на переменных
   палитры, и они сами меняются вместе с темой. */

/* ═══════════════════════════════════════════════════════════════
   КОЛОКОЛЬЧИК УВЕДОМЛЕНИЙ — единый стиль на всех страницах
   ═══════════════════════════════════════════════════════════════ */
.notif-bell-wrap{
  position:relative;
  display:inline-flex;
  align-items:center;
  flex-shrink:0
}
.notif-bell{
  position:relative;
  display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;
  border-radius:var(--rm, 10px);
  border:1.5px solid var(--bdr);
  background:var(--gp);
  cursor:pointer;
  transition:all .15s;
  user-select:none
}
.notif-bell:hover{border-color:var(--gb);background:var(--gl)}
.notif-bell.open{border-color:var(--gb);background:var(--gl)}
.notif-bell svg{
  width:18px;height:18px;
  fill:none;stroke:var(--t);
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round
}
.notif-bell-badge{
  position:absolute;top:-4px;right:-4px;
  min-width:18px;height:18px;
  border-radius:99px;
  background:var(--red);
  color:#fff;
  font-size:10px;font-weight:800;
  display:none;
  align-items:center;justify-content:center;
  padding:0 5px;
  border:2px solid var(--w);
  pointer-events:none;
  font-family:inherit
}
.notif-bell-badge.has-unread{display:inline-flex}
@keyframes notifBadgePulse{
  0%{transform:scale(1)}
  30%{transform:scale(1.35);box-shadow:0 0 0 4px rgba(224,64,64,.35)}
  60%{transform:scale(.95)}
  100%{transform:scale(1);box-shadow:0 0 0 0 rgba(224,64,64,0)}
}
.notif-bell-badge.pulse{animation:notifBadgePulse .6s ease}

/* Dropdown */
.notif-dd{
  position:absolute;
  top:calc(100% + 8px);
  right:0;
  width:380px;
  max-width:calc(100vw - 32px);
  background:var(--w);
  border:1px solid var(--bdr);
  border-radius:var(--rl, 12px);
  box-shadow:0 12px 36px rgba(30,138,76,.15);
  opacity:0;
  pointer-events:none;
  transform:translateY(-6px);
  transition:opacity .2s,transform .2s;
  z-index:var(--z-topbar-dd);
  overflow:hidden
}
.notif-dd.open{opacity:1;pointer-events:all;transform:translateY(0)}
.notif-dd-head{
  padding:14px 16px;
  border-bottom:1px solid var(--bdr);
  display:flex;align-items:center;justify-content:space-between
}
.notif-dd-title{
  font-size:13px;font-weight:800;color:var(--t)
}
.notif-mark-all{
  font-size:11px;font-weight:600;
  color:var(--g);
  background:none;border:none;
  cursor:pointer;
  font-family:inherit;
  padding:4px 8px;
  border-radius:6px;
  transition:background .15s
}
.notif-mark-all:hover{background:var(--gl)}
.notif-mark-all:disabled{color:var(--gmt);cursor:default}
.notif-list{
  max-height:420px;
  overflow-y:auto
}
.notif-item{
  display:flex;gap:12px;
  padding:12px 16px 12px 22px;
  border-bottom:1px solid var(--bdr);
  cursor:pointer;
  transition:background .12s;
  position:relative;
  text-decoration:none;
  color:inherit
}
.notif-item:hover{background:var(--gp)}
.notif-item:last-child{border-bottom:none}
.notif-item.unread{background:rgba(30,138,76,.04)}
.notif-item.unread::before{
  content:'';
  position:absolute;left:8px;top:50%;
  width:5px;height:5px;
  border-radius:50%;
  background:var(--g);
  transform:translateY(-50%)
}
.notif-av{
  width:36px;height:36px;
  border-radius:10px;
  flex-shrink:0;
  display:grid;place-items:center;
  font-size:13px;font-weight:800;
  color:#fff
}
.notif-av-system{
  background:var(--gl);
  color:var(--g);
  border:1px solid var(--gb)
}
.notif-body{flex:1;min-width:0}
.notif-title{
  font-size:12px;font-weight:600;
  color:var(--t);
  line-height:1.4;
  margin-bottom:2px
}
.notif-preview{
  font-size:11px;
  color:var(--gmt);
  line-height:1.4;
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
  margin-bottom:3px
}
.notif-time{
  font-size:10px;
  color:var(--gmt);
  font-weight:500
}
.notif-empty{
  padding:36px 20px;
  text-align:center;
  font-size:12px;
  color:var(--gmt)
}
.notif-empty .nei{
  font-size:32px;
  margin-bottom:10px;
  display:block;
  opacity:.6
}
.notif-dd-foot{
  border-top:1px solid var(--bdr);
  padding:10px;
  text-align:center
}
.notif-dd-foot a{
  font-size:12px;font-weight:600;
  color:var(--g);
  text-decoration:none;
  padding:6px 12px;
  border-radius:var(--rm, 10px);
  display:inline-block;
  transition:background .15s
}
.notif-dd-foot a:hover{background:var(--gp)}

/* Тёмная тема */
html[data-theme="dark"] .notif-bell-badge{
  border-color:var(--w)
}
html[data-theme="dark"] .notif-item.unread{
  background:rgba(34,160,90,.08)
}

/* ═══════════════════════════════════════════════════════════════
   SHELL ELEMENTS — единые стили topbar+nav+dropdown.
   Префикс html.lt-shell для перебивания inline <style> страниц.
   Эталон — home-auth.html.
   ═══════════════════════════════════════════════════════════════ */

/* Search */
html.lt-shell .search-icon,
html.lt-shell-2col .search-icon{
  position:absolute;left:11px;top:50%;transform:translateY(-50%);
  width:14px;height:14px;display:grid;place-items:center;
  pointer-events:none;flex-shrink:0
}
html.lt-shell .search-icon svg,
html.lt-shell-2col .search-icon svg{
  width:14px;height:14px;stroke:var(--g);fill:none;
  stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round
}
html.lt-shell .search-wrap input,
html.lt-shell-2col .search-wrap input{
  width:100%;height:36px;padding:0 14px 0 30px;
  border:1.5px solid var(--bdr);border-radius:99px;background:#fff;
  font-family:inherit;font-size:13px;color:var(--t);outline:none;
  transition:border-color .2s
}
html.lt-shell .search-wrap input:focus,
html.lt-shell-2col .search-wrap input:focus{border-color:var(--gm)}
html.lt-shell .search-wrap input::placeholder,
html.lt-shell-2col .search-wrap input::placeholder{color:var(--gmt)}

/* Topbar profile button */
html.lt-shell .topbar-profile,
html.lt-shell-2col .topbar-profile{
  display:flex;align-items:center;gap:10px;padding:6px 12px;
  border-radius:var(--rm);border:1.5px solid var(--bdr);background:var(--gp);
  cursor:pointer;transition:all .15s;flex-shrink:0;user-select:none
}
html.lt-shell .topbar-profile:hover,
html.lt-shell-2col .topbar-profile:hover,
html.lt-shell .topbar-profile.open,
html.lt-shell-2col .topbar-profile.open{border-color:var(--gb);background:var(--gl)}
html.lt-shell .topbar-profile.open .tp-arrow,
html.lt-shell-2col .topbar-profile.open .tp-arrow{transform:rotate(180deg)}
html.lt-shell .tp-av,
html.lt-shell-2col .tp-av{
  width:30px;height:30px;border-radius:8px;background:var(--g);
  display:grid;place-items:center;font-size:11px;font-weight:800;color:#fff;flex-shrink:0
}
html.lt-shell .tp-info,
html.lt-shell-2col .tp-info{display:flex;flex-direction:column;line-height:1.25}
html.lt-shell .tp-name,
html.lt-shell-2col .tp-name{font-size:12px;font-weight:700;color:var(--t)}
html.lt-shell .tp-role,
html.lt-shell-2col .tp-role{font-size:10px;color:var(--gmt)}
html.lt-shell .tp-arrow,
html.lt-shell-2col .tp-arrow{
  width:14px;height:14px;stroke:var(--gmt);fill:none;
  stroke-width:2;stroke-linecap:round;stroke-linejoin:round;
  flex-shrink:0;transition:transform .2s
}

/* Dropdown profile menu */
html.lt-shell .profile-dd-wrap,
html.lt-shell-2col .profile-dd-wrap{
  position:relative;display:flex;align-items:center;
  justify-content:flex-end;min-width:0;padding:0 16px
}
html.lt-shell .profile-dd,
html.lt-shell-2col .profile-dd{
  position:absolute;top:calc(100% + 8px);right:0;
  width:280px;background:var(--w);border:1px solid var(--bdr);
  border-radius:var(--rl);box-shadow:0 12px 36px rgba(30,138,76,.15);
  opacity:0;pointer-events:none;transform:translateY(-6px);
  transition:opacity .2s,transform .2s;z-index:var(--z-topbar-dd);overflow:hidden
}
html.lt-shell .profile-dd.open,
html.lt-shell-2col .profile-dd.open{opacity:1;pointer-events:all;transform:translateY(0)}
html.lt-shell .pdd-head,
html.lt-shell-2col .pdd-head{
  padding:14px;border-bottom:1px solid var(--bdr);
  display:flex;align-items:center;gap:10px;background:var(--gp)
}
html.lt-shell .pdd-av,
html.lt-shell-2col .pdd-av{
  width:40px;height:40px;border-radius:10px;background:var(--g);
  display:grid;place-items:center;font-size:13px;font-weight:800;color:#fff;flex-shrink:0
}
html.lt-shell .pdd-info,
html.lt-shell-2col .pdd-info{min-width:0;flex:1}
html.lt-shell .pdd-name,
html.lt-shell-2col .pdd-name{
  font-size:13px;font-weight:800;color:var(--t);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis
}
html.lt-shell .pdd-role,
html.lt-shell-2col .pdd-role{
  font-size:10px;color:var(--gmt);margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis
}
html.lt-shell .pdd-view,
html.lt-shell-2col .pdd-view{
  display:block;margin:10px 14px 0;padding:6px;border-radius:var(--rm);
  background:var(--gl);border:1px solid var(--gb);color:var(--g);
  font-family:inherit;font-size:11px;font-weight:700;
  cursor:pointer;text-align:center;text-decoration:none;transition:all .15s
}
html.lt-shell .pdd-view:hover,
html.lt-shell-2col .pdd-view:hover{background:var(--g);color:#fff;border-color:var(--g)}
html.lt-shell .pdd-body,
html.lt-shell-2col .pdd-body{padding:6px}
html.lt-shell .pdd-item,
html.lt-shell-2col .pdd-item{
  display:flex;align-items:center;gap:10px;padding:9px 10px;
  border-radius:var(--r);cursor:pointer;text-decoration:none;
  color:var(--tm);font-size:13px;font-weight:500;
  transition:background .15s,color .15s
}
html.lt-shell .pdd-item:hover,
html.lt-shell-2col .pdd-item:hover{background:var(--gp);color:var(--g)}
html.lt-shell .pdd-item svg,
html.lt-shell-2col .pdd-item svg{
  width:16px;height:16px;flex-shrink:0;stroke:currentColor;fill:none;
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round
}
html.lt-shell .pdd-item-label,
html.lt-shell-2col .pdd-item-label{flex:1}
html.lt-shell .pdd-count,
html.lt-shell-2col .pdd-count{
  font-size:10px;font-weight:700;color:var(--g);
  background:var(--gl);border:1px solid var(--gb);border-radius:99px;
  padding:1px 7px;flex-shrink:0
}
html.lt-shell .pdd-div,
html.lt-shell-2col .pdd-div{height:1px;background:var(--bdr);margin:4px 6px}
html.lt-shell .pdd-item.logout,
html.lt-shell-2col .pdd-item.logout{color:var(--red)}
html.lt-shell .pdd-item.logout:hover,
html.lt-shell-2col .pdd-item.logout:hover{background:#FFF5F5;color:var(--red)}

/* Nav body */
html.lt-shell .nav,
html.lt-shell-2col .nav{
  grid-area:nav;background:var(--w);border-radius:var(--rxl);
  border:1px solid var(--bdr);box-shadow:var(--sh);
  overflow-y:auto;overflow-x:hidden;display:flex;flex-direction:column;
  padding:12px 10px 10px;gap:1px
}
html.lt-shell .nav::-webkit-scrollbar,
html.lt-shell-2col .nav::-webkit-scrollbar{display:none}
html.lt-shell .nav-group,
html.lt-shell-2col .nav-group{
  font-size:10px;font-weight:700;color:var(--gmt);
  letter-spacing:.1em;text-transform:uppercase;
  padding:10px 8px 5px;margin-top:2px
}
html.lt-shell .nav-group:first-child,
html.lt-shell-2col .nav-group:first-child{padding-top:2px;margin-top:0}
html.lt-shell .nav-div,
html.lt-shell-2col .nav-div{height:1px;background:var(--bdr);margin:6px 4px}
html.lt-shell .nav-item,
html.lt-shell-2col .nav-item{
  display:flex;align-items:center;gap:10px;padding:9px 10px;
  border-radius:var(--r);cursor:pointer;text-decoration:none;
  color:var(--tm);font-size:13px;font-weight:500;
  transition:background .15s,color .15s;white-space:nowrap
}
.nav-badge{
  margin-left:auto;flex-shrink:0;
  min-width:18px;height:18px;padding:0 5px;
  border-radius:99px;background:var(--g);color:#fff;
  font-size:10px;font-weight:700;line-height:18px;text-align:center;
  box-sizing:border-box
}
html.lt-shell .nav-item.active .nav-badge,
html.lt-shell-2col .nav-item.active .nav-badge{
  background:#fff;color:var(--g)
}
html.lt-shell .nav-item:hover,
html.lt-shell-2col .nav-item:hover{background:var(--gp);color:var(--g)}
html.lt-shell .nav-item.active,
html.lt-shell-2col .nav-item.active{background:var(--gl);color:var(--g);font-weight:700}
html.lt-shell .nav-item svg,
html.lt-shell-2col .nav-item svg{
  width:18px;height:18px;flex-shrink:0;fill:none;stroke:currentColor;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round
}
html.lt-shell .nav-bottom,
html.lt-shell-2col .nav-bottom{margin-top:auto;padding-top:8px;border-top:1px solid var(--bdr)}

/* Адаптив (повторяем существующие правила сжатия nav-item на узких экранах) */
@media (max-width:740px){
  html.lt-shell .nav-group,
  html.lt-shell-2col .nav-group{display:none}
}

/* Тёмная тема — не нужны явные правила, переменные --w/--gp/--bdr уже инвертируются */


/* ─────────────────────────────────────────────────────────────
   ГЛОБАЛЬНЫЙ ГОРИЗОНТАЛЬНЫЙ СКРОЛЛБАР
   Помеченные [data-hw="1"] контейнеры (выставляется JS-хелпером
   из shell-injector.js) получают тонкий зелёный скроллбар
   и поддержку колеса мыши для горизонтального скролла.
   ───────────────────────────────────────────────────────────── */
[data-hw="1"]{
  scrollbar-width:thin !important;
  scrollbar-color:var(--gb,#C0DECA) transparent !important;
}
[data-hw="1"]::-webkit-scrollbar{
  height:6px !important;
  width:6px;
}
[data-hw="1"]::-webkit-scrollbar-track{
  background:transparent !important;
}
[data-hw="1"]::-webkit-scrollbar-thumb{
  background:var(--gb,#C0DECA) !important;
  border-radius:99px !important;
}
[data-hw="1"]::-webkit-scrollbar-thumb:hover{
  background:var(--gm,#22A05A) !important;
}


/* ── T14-C1: резервируем высоту для контейнеров фильтров,
   чтобы они не подпрыгивали при загрузке данных ── */
.filter-tabs,
.filter-row,
.filters-row,
.ftab-row{
  min-height: 32px
}
.ftab{
  min-height: 28px
}

/* ── D1 (18.05): единая hover-анимация для всех фильтр-чипов
   разных страниц. Раньше «подпрыгивание» работало только в
   Проектах (.ptab) и Сообществах (.ctab); теперь — везде где
   используется фильтр-чип (.cat-chip — Главная/Форум/Компании/
   Уведомления, .ec-cat-pill — Выставки, .ftab — общий контейнер).
   Каждая страница уже задаёт свои hover-цвета; здесь добавляется
   ТОЛЬКО transform, чтобы не перебивать остальные стили.
   transition:all .15s в исходных классах уже есть — анимация плавная. */
.cat-chip:not(.active):hover,
.ec-cat-pill:not(.active):hover,
.ftab:not(.active):hover{
  transform: translateY(-1px);
}

/* ── T-FIN-SMOOTH-2: фон под не-загруженными картинками ──
   Если у <img> прописана высота (через style/CSS), но src ещё не пришёл,
   браузер покажет «дырку». Серый фон делает плейсхолдер незаметным. */
img[loading="lazy"]:not([src]),
img:not([src]) {
  background: var(--gp);
}

/* ─── Единое состояние ОШИБКИ загрузки списка (lastopListError из utils.js) ───
   Отделяет «ошибку сети» от «пусто»: показывает иконку, сообщение и кнопку
   «Повторить». Единый вид на всех списках (компании/мероприятия/проекты/
   сообщества/вакансии и др.). «Пусто» остаётся своим (дружелюбным) у каждого
   списка — этот класс ТОЛЬКО для реального сбоя загрузки. */
.lt-list-error{
  background:var(--w);
  border:1px solid var(--bdr);
  border-radius:var(--rxl);
  padding:40px 24px;
  text-align:center;
  box-shadow:var(--sh);
}
.lt-list-error-ic{
  width:40px;height:40px;
  margin:0 auto 12px;
  color:var(--gmt);
  opacity:.7;
}
.lt-list-error-ic svg{width:100%;height:100%;stroke:currentColor;fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
.lt-list-error-t{
  font-size:14px;font-weight:700;color:var(--t);
  margin-bottom:6px;
}
.lt-list-error-d{
  font-size:12px;color:var(--gmt);
  margin-bottom:16px;
}
.lt-list-error-btn{
  display:inline-flex;align-items:center;gap:6px;
  border:1px solid var(--bdr);
  background:var(--w);
  color:var(--g);
  font-weight:700;font-size:13px;font-family:inherit;
  padding:9px 18px;border-radius:var(--rl,12px);
  cursor:pointer;
  transition:background .15s,border-color .15s;
}
.lt-list-error-btn:hover{background:var(--gl);border-color:var(--g)}
.lt-list-error-btn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}

/* Guest topbar (login/register) — moved to global CSS so it survives the SPA <style> strip in spa-router. Mirror of home-guest.html inline. */
.topbar-guest{display:flex;align-items:center;gap:8px;background:var(--w);border:1px solid var(--bdr);border-radius:var(--rl);box-shadow:var(--sh);height:56px;padding:6px 6px 6px 16px}
.topbar-guest .btn-login,.topbar-guest .btn-reg{flex:1;justify-content:center}
.topbar-guest .btn-login{height:36px;padding:0 18px;border-radius:99px;border:1.5px solid var(--bdr);background:var(--w);font-family:inherit;font-size:13px;font-weight:600;color:var(--tm);cursor:pointer;transition:all .15s;text-decoration:none;display:inline-flex;align-items:center}
.topbar-guest .btn-login:hover{border-color:var(--gb);color:var(--g);background:var(--gp)}
.topbar-guest .btn-reg{height:36px;padding:0 20px;border-radius:99px;border:none;background:var(--g);font-family:inherit;font-size:13px;font-weight:700;color:#fff;cursor:pointer;transition:background .15s;text-decoration:none;display:inline-flex;align-items:center;gap:6px;box-shadow:0 2px 8px rgba(30,138,76,.25)}
.topbar-guest .btn-reg:hover{background:var(--gm)}
.topbar-guest .btn-reg svg{width:13px;height:13px;stroke:#fff;fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}


/* ══════════════════════════════════════════════════════════════
 *  ЗВОНКИ — окна входящего и активного вызова.
 *  Показываются на любой странице: входящий должен доходить,
 *  где бы человек ни находился.
 *
 *  Цвета — только через переменные платформы (--w, --t, --tm, --bdr,
 *  --g). Тёмная тема переопределяет их в dark-theme.css, поэтому
 *  хардкод здесь недопустим: получится белая плашка на чёрном фоне.
 * ══════════════════════════════════════════════════════════════ */
/* ЗВОНКИ НА ВРЕМЯ ДОВОДКИ.
   Пока механика не обкатана, кнопки видны только администрации. Прячем
   их разом, а не в каждом месте отдельно: признак ставит calls.js после
   ответа сервера. */
html.calls-off #chatCallBtn,
html.calls-off #chatVideoBtn,
html.calls-off #btnCallUser,
html.calls-off #btnVideoCallUser,
html.calls-off .m-call-btn{display:none !important}

/* ОКНА ЗВОНКОВ ВСЕГДА ТЁМНЫЕ.
 *
 * Раньше цвета брались из темы платформы. В светлой теме фон окна становился
 * светлым, а кнопки заданы полупрозрачным белым с белыми значками — и они
 * пропадали совсем. Отсюда жалобы «иконок не видно» и «правые полупрозрачные».
 *
 * Так же поступают Zoom, Телеграм и Meet: окно звонка тёмное независимо от
 * темы. Видео на тёмном смотрится лучше, и глаза меньше устают.
 */
/* Отметка о сохранённой записи — со ссылкой на файл. */
.msg-call.rec a{color:var(--cgreen);text-decoration:none;font-weight:600}
.msg-call.rec a:hover{text-decoration:underline}

#callLayer, #roomLayer{
  --cbg:#0E1A14; --cpanel:#16241D; --ctext:#F6F8F5;
  --cmuted:#8AA394; --cborder:#25382E; --cgreen:#1E8A4C;
  color:#F6F8F5;
}

#callLayer .call-win{
  position:fixed; right:24px; bottom:24px; z-index:var(--z-modal,1000);
  width:min(300px, calc(100vw - 32px)); padding:26px 22px 22px;
  background:var(--cpanel); border:1px solid var(--cborder);
  border-radius:20px; box-shadow:0 16px 48px rgba(0,0,0,.28);
  text-align:center; font-family:inherit; color:var(--ctext);
  animation:callPop .22s cubic-bezier(.2,.9,.3,1.1);
  /* Окно можно перетащить: во время разговора оно не должно закрывать
     нужное место интерфейса. */
  cursor:grab; touch-action:none; user-select:none; -webkit-user-select:none;
}
/* Пока тащим окно, выделение текста по всей странице отключено: иначе
   вместе с окном «подхватывается» текст интерфейса. */
body.lastop-call-dragging{user-select:none;-webkit-user-select:none;cursor:grabbing}

@keyframes callPop{from{opacity:0;transform:translateY(12px) scale(.96)}to{opacity:1;transform:none}}

/* Аватар — крупный круг, как в мессенджерах. */
#callLayer .call-av{
  width:88px; height:88px; margin:0 auto 14px; border-radius:50%;
  background:rgba(30,138,76,.22); color:var(--cgreen);
  display:grid; place-items:center; font-size:32px; font-weight:700; overflow:hidden;
}
#callLayer .call-av img{width:100%;height:100%;object-fit:cover;display:block}
/* Пульсация при входящем — «телефон звонит». */
#callLayer #callIncoming .call-av{animation:callRing 1.6s ease-in-out infinite}
@keyframes callRing{
  0%,100%{box-shadow:0 0 0 0 currentColor; opacity:1}
  50%    {box-shadow:0 0 0 12px transparent; opacity:.92}
}
#callLayer .call-name{font-size:19px;font-weight:600;letter-spacing:-.01em}
#callLayer .call-sub{margin-top:5px;font-size:14px;color:var(--cmuted)}
#callLayer .call-dur{margin-top:5px;font-size:15px;color:var(--cmuted);
  font-variant-numeric:tabular-nums}

/* Эмодзи-подтверждение — как в Телеграме: четыре символа в рамке. */
#callLayer .call-emoji{
  margin:16px auto 0; padding:10px 14px; display:inline-block;
  background:rgba(255,255,255,.06); border-radius:14px;
  font-size:24px; letter-spacing:8px; line-height:1;
}
#callLayer .call-emoji-hint{margin-top:8px;font-size:11px;line-height:1.45;
  color:var(--cmuted); padding:0 6px}

/* Круглые кнопки, как в мессенджерах: иконка + подпись под ней. */
#callLayer .call-btns{display:flex;gap:26px;justify-content:center;margin-top:22px;position:relative;z-index:1}
#callLayer .call-btn{
  display:flex; flex-direction:column; align-items:center; gap:6px;
  background:none; border:0; padding:0; cursor:pointer; font:inherit;
  font-size:11px; color:var(--cmuted);
}
#callLayer .call-btn i{
  width:56px; height:56px; border-radius:50%; display:grid; place-items:center;
  font-style:normal; font-size:24px; line-height:1; transition:transform .12s, filter .12s;
}
#callLayer .call-btn:hover i{transform:scale(1.06)}
#callLayer .call-btn:active i{transform:scale(.95)}
#callLayer .call-btn.ok i{background:var(--cgreen);color:#fff}
#callLayer .call-btn.no i{background:#E5484D;color:#fff}
/* Трубка «положить» — повёрнутая, как принято в интерфейсах звонков. */
#callLayer .call-btn.no i svg{transform:rotate(135deg)}
#callLayer .call-btn.mic i{background:rgba(255,255,255,.06);color:var(--ctext);
  border:1px solid var(--cborder)}
#callLayer .call-btn.mic.off i{background:#E5484D;color:#fff;border-color:#E5484D}
#callLayer .call-btn svg{width:24px;height:24px;fill:currentColor;display:block}

/* Сцена: аватар при голосовом звонке, видео — при включённой камере.
   Окно расширяется только когда появилась картинка. */
#callLayer .call-stage{position:relative;display:grid;place-items:center;margin-bottom:14px}
#callLayer .call-win.video{width:min(420px, calc(100vw - 32px));padding:16px 16px 20px}
#callLayer .call-win.video .call-stage{
  aspect-ratio:16/9; background:#000; border-radius:14px; overflow:hidden; margin-bottom:12px;
}
#callLayer #callRemoteVideo{width:100%;height:100%;object-fit:cover;display:block;background:#000}
/* Своё видео — маленьким окном в углу, зеркально: так привычнее. */
#callLayer #callLocalVideo{
  position:absolute; right:10px; bottom:10px; width:88px; height:auto; max-height:64px;
  object-fit:cover; border-radius:9px; border:2px solid rgba(255,255,255,.85);
  /* Камеру зеркалим — человек привык видеть себя как в зеркале.
     Показ экрана НЕ зеркалим: текст читался бы задом наперёд. */
  transform:scaleX(-1); background:#000;
}
#callLayer #callLocalVideo.screen{transform:none}
#callLayer .call-win.video .call-emoji{font-size:20px;letter-spacing:6px;padding:8px 12px;margin-top:10px}
#callLayer .call-win.video .call-emoji-hint{font-size:10.5px}
/* Камера включена — кнопка подсвечена, как в мессенджерах. */
#callLayer .call-btn.cam i{background:rgba(255,255,255,.06);color:var(--ctext);
  border:1px solid var(--cborder)}
#callLayer .call-btn.cam.on i{background:var(--cgreen);color:#fff;border-color:var(--cgreen)}
/* Микрофон выключен — перечёркнут. */
#callLayer .call-btn.mic.off i::after{
  content:''; position:absolute; width:34px; height:2px; background:currentColor;
  transform:rotate(-45deg); border-radius:2px;
}
#callLayer .call-btn.mic i{position:relative;overflow:hidden}
#callLayer .call-btns{gap:20px}
/* Микрофон собеседника выключен — иначе человек говорит в тишину. */
/* Кнопка «свернуть» и индикатор связи — в углах окна. */
/* Полный экран — нужен только при видео: в голосовом звонке разворачивать
   нечего, там аватар. */
#callLayer .call-fs{
  position:absolute; right:76px; top:12px; width:26px; height:26px; border-radius:8px;
  border:1px solid var(--cborder); background:transparent; color:var(--cmuted);
  cursor:pointer; display:none; place-items:center; padding:0;
}
#callLayer .call-win.video .call-fs{display:grid}
#callLayer .call-fs:hover{background:rgba(255,255,255,.06)}
#callLayer .call-fs svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
#callLayer .call-fs.on{background:var(--cgreen);color:#fff;border-color:var(--cgreen)}

/* Развёрнуто на весь экран: видео занимает всё, остальное поверх него. */
#callLayer .call-win.fs{
  width:100vw; max-width:none; height:100vh; border-radius:0; padding:0;
  display:flex; flex-direction:column; justify-content:flex-end;
  background:#000; border:0; box-shadow:none;
}
#callLayer .call-win.fs .call-stage{
  position:absolute; inset:0; margin:0; aspect-ratio:auto; border-radius:0;
}
#callLayer .call-win.fs #callRemoteVideo{width:100%;height:100%;object-fit:contain}
#callLayer .call-win.fs #callLocalVideo{width:160px;max-height:120px;right:20px;bottom:20px}
#callLayer .call-win.fs .call-name,
#callLayer .call-win.fs .call-dur,
#callLayer .call-win.fs .call-sub,
#callLayer .call-win.fs .call-emoji,
#callLayer .call-win.fs .call-emoji-hint,
#callLayer .call-win.fs .call-rec-badge{position:relative;z-index:2;color:#F6F8F5}
#callLayer .call-win.fs .call-btns,
#callLayer .call-win.fs .call-more{position:relative;z-index:2;margin-bottom:26px}
#callLayer .call-win.fs .call-emoji{background:rgba(0,0,0,.45)}
#callLayer .call-win.fs .call-mid{position:relative;z-index:2;margin-bottom:10px}

/* Качество связи видно и в свёрнутом виде — место есть, а знать полезно. */
#callLayer .call-win.mini .call-quality{
  display:flex; position:static; order:-1; margin-right:2px;
}

#callLayer .call-mini{
  position:absolute; right:14px; top:12px; width:26px; height:26px; border-radius:8px;
  border:1px solid var(--cborder); background:transparent; color:var(--cmuted);
  font:inherit; font-size:15px; line-height:1; cursor:pointer;
}
#callLayer .call-mini:hover{background:rgba(255,255,255,.06)}
/* Выбор микрофона и камеры — шестерёнка рядом со сворачиванием. */
#callLayer .call-gear{
  position:absolute; right:46px; top:12px; width:26px; height:26px; border-radius:8px;
  border:1px solid var(--cborder); background:transparent; color:var(--cmuted);
  cursor:pointer; display:grid; place-items:center; padding:0;
}
#callLayer .call-gear:hover{background:rgba(255,255,255,.06)}
#callLayer .call-gear svg{width:16px;height:16px;fill:none;stroke:currentColor;
  stroke-width:1.7;stroke-linecap:round}
#callLayer .call-gear svg circle{fill:var(--cpanel)}
#callLayer .call-dev{
  /* Панель была в потоке и растягивала окно: при открытых настройках оно
     переставало вмещаться и уезжало под панель браузера. Теперь всплывает
     поверх — окно сохраняет размер. */
  position:absolute; left:12px; right:12px; bottom:88px; z-index:20;
  max-height:46vh; overflow-y:auto;
  padding:10px; background:var(--cpanel); border:1px solid var(--cborder);
  border-radius:12px; display:flex; flex-direction:column; gap:10px;
  box-shadow:0 12px 32px rgba(0,0,0,.5);
}
#callLayer .call-dev-row{display:flex;flex-direction:column;gap:4px;font-size:11px;color:var(--cmuted)}
/* Свой выпадающий список: у системного раскрытый вид рисует ОС,
   и под оформление платформы его не подогнать. */
#callLayer .call-dev-row{position:relative}
#callLayer .call-dev-btn{
  display:flex; align-items:center; gap:8px; width:100%; text-align:left;
  font:inherit; font-size:12.5px; padding:7px 10px; border-radius:9px;
  border:1px solid var(--cborder); background:var(--cpanel);
  color:var(--ctext); cursor:pointer;
}
#callLayer .call-dev-btn:hover{border-color:var(--cgreen)}
#callLayer .call-dev-btn span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#callLayer .call-dev-caret{
  flex:none; width:0; height:0; border-left:4px solid transparent;
  border-right:4px solid transparent; border-top:5px solid var(--cmuted);
}
#callLayer .call-dev-list{
  position:absolute; left:0; right:0; top:100%; margin-top:4px;
  /* Поверх всего содержимого окна: список может выходить за нижнюю границу,
     это нормально — окно не обрезает содержимое. */
  z-index:30;
  background:var(--cpanel); border:1px solid var(--cborder); border-radius:10px;
  box-shadow:0 8px 24px rgba(0,0,0,.14); overflow:hidden; max-height:180px; overflow-y:auto;
}
#callLayer .call-dev-item{
  display:block; width:100%; text-align:left; font:inherit; font-size:12.5px;
  padding:8px 10px; border:0; background:transparent; color:var(--ctext);
  cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
#callLayer .call-dev-item:hover{background:rgba(255,255,255,.06)}
#callLayer .call-dev-item.on{background:rgba(30,138,76,.22);color:var(--cgreen);font-weight:600}
#callLayer .call-win.mini .call-gear,
#callLayer .call-win.mini .call-dev{display:none}

#callLayer .call-quality{position:absolute; left:14px; top:16px; display:flex; align-items:flex-end; gap:2px; height:14px}
#callLayer .call-quality i{width:3px; border-radius:1px; background:var(--cborder)}
#callLayer .call-quality i:nth-child(1){height:6px}
#callLayer .call-quality i:nth-child(2){height:10px}
#callLayer .call-quality i:nth-child(3){height:14px}
#callLayer .call-quality.q3 i{background:var(--cgreen)}
#callLayer .call-quality.q2 i:nth-child(-n+2){background:#E5A23D}
#callLayer .call-quality.q1 i:nth-child(1){background:#E5484D}

/* Демонстрация экрана — активная кнопка подсвечена, как камера. */
#callLayer .call-btn.scr i{background:rgba(255,255,255,.06);color:var(--ctext);
  border:1px solid var(--cborder)}
#callLayer .call-btn.scr.on i{background:var(--cgreen);color:#fff;border-color:var(--cgreen)}

/* СВЁРНУТОЕ ОКНО — скруглённый прямоугольник: аватар собеседника с
   пульсацией по его речи, микрофон и сброс. Всё остальное скрыто, чтобы
   не закрывать интерфейс во время разговора. */
#callLayer .call-win.mini{
  width:auto; min-width:0; padding:10px 12px; border-radius:999px;
  display:flex; align-items:center; gap:12px; text-align:left; cursor:pointer;
}
#callLayer .call-win.mini .call-stage{margin:0}
#callLayer .call-win.mini .call-av{
  width:44px; height:44px; margin:0; font-size:17px;
  transition:box-shadow .08s linear;   /* пульсация по громкости речи */
}
/* Видео в свёрнутом виде не показываем — только аватар. */
#callLayer .call-win.mini #callRemoteVideo,
#callLayer .call-win.mini #callLocalVideo,
#callLayer .call-win.mini .call-sub,
#callLayer .call-win.mini .call-emoji,
#callLayer .call-win.mini .call-emoji-hint,
#callLayer .call-win.mini .call-peer-mic,
#callLayer .call-win.mini .call-mini,
#callLayer .call-win.mini .call-fs,
#callLayer .call-win.mini .call-btn.cam,
#callLayer .call-win.mini .call-btn.scr{display:none}
#callLayer .call-win.mini.video .call-stage{aspect-ratio:auto;background:none;overflow:visible}
#callLayer .call-win.mini .call-av{display:grid}
#callLayer .call-win.mini .call-mid{display:flex;flex-direction:column;gap:2px;min-width:0}
#callLayer .call-win.mini .call-name{font-size:13.5px;max-width:130px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
#callLayer .call-win.mini .call-dur{margin:0;font-size:12px}
#callLayer .call-win.mini .call-btns{margin:0;gap:8px}
#callLayer .call-win.mini .call-btn i{width:40px;height:40px;font-size:18px}
#callLayer .call-win.mini .call-btn span{display:none}

/* Запись разговора: индикатор виден обоим и приходит через сигналинг —
   подделать его нельзя. */
/* Дополнительные действия — под кнопкой «Ещё». Демонстрация экрана и
   запись нужны редко, а место в основном ряду занимали, и кнопки
   выходили за границы окна. */
#callLayer .call-more{
  display:flex; gap:20px; justify-content:center; margin-top:14px;
  padding-top:14px; border-top:1px solid var(--cborder);
}
#callLayer .call-more[hidden]{display:none}
#callLayer .call-btn.more i{background:rgba(255,255,255,.06);color:var(--ctext);
  border:1px solid var(--cborder)}
#callLayer .call-btn.more svg{
  width:22px; height:22px; fill:none; stroke:currentColor; stroke-width:2.2;
  stroke-linecap:round; stroke-linejoin:round;
  transition:transform .18s ease;
}
/* Блок раскрыт — стрелка смотрит вниз, как принято. */
#callLayer .call-btn.more.on svg{transform:rotate(180deg)}
#callLayer .call-btn.more.on i{background:var(--cgreen);color:#fff;border-color:var(--cgreen)}
/* Пока идёт дозвон, дополнительных действий нет — они бессмысленны. */
#callLayer .call-win:not(.talking) .call-btn.more,
#callLayer .call-win:not(.talking) .call-more{display:none}
#callLayer .call-win.mini .call-btn.more,
#callLayer .call-win.mini .call-more{display:none}
/* Кнопок в ряду немного, поэтому они помещаются без переноса. */
#callLayer .call-btns{flex-wrap:nowrap}

#callLayer .call-rec-badge{
  display:inline-flex; align-items:center; gap:6px; margin:0 auto 8px;
  padding:4px 10px; border-radius:999px; background:rgba(229,72,77,.14);
  color:#E5484D; font-size:11.5px; font-weight:700;
}
#callLayer .call-rec-badge i{
  width:8px; height:8px; border-radius:50%; background:#E5484D;
  animation:callRecPulse 1.4s ease-in-out infinite;
}
@keyframes callRecPulse{0%,100%{opacity:1}50%{opacity:.25}}

/* Запрос согласия: без явного «Разрешаю» запись не стартует. */
#callLayer .call-rec-ask{
  margin-top:12px; padding:12px; border-radius:12px;
  background:rgba(255,255,255,.06); border:1px solid var(--cgreen);
}
#callLayer .call-rec-ask-t{font-size:12.5px;line-height:1.4;color:var(--ctext);margin-bottom:10px}
#callLayer .call-rec-ask-b{display:flex;gap:8px}
#callLayer .call-rec-yes,#callLayer .call-rec-no{
  flex:1; padding:8px 10px; border-radius:9px; font:inherit; font-size:12.5px;
  font-weight:600; cursor:pointer; border:1px solid transparent;
}
#callLayer .call-rec-yes{background:var(--cgreen);color:#fff}
#callLayer .call-rec-no{background:transparent;border-color:var(--cborder);color:var(--ctext)}
#callLayer .call-btn.rec i{background:rgba(255,255,255,.06);color:var(--ctext);
  border:1px solid var(--cborder)}
#callLayer .call-btn.rec.on i{background:#E5484D;color:#fff;border-color:#E5484D}
#callLayer .call-win.mini .call-btn.rec,
#callLayer .call-win.mini .call-rec-ask{display:none}

#callLayer .call-peer-mic{
  margin-top:6px; font-size:12px; font-weight:600; color:#E5484D;
}

/* ══════════════════════════════════════════════════════════════
 *  ЗВОНКИ НА ТЕЛЕФОНЕ
 *  Окно в углу здесь не годится: экран узкий, попасть пальцем в
 *  маленькую кнопку тяжело. Разворачиваем на всю ширину снизу —
 *  привычный для телефона вид, — увеличиваем кнопки и учитываем
 *  вырезы экрана.
 * ══════════════════════════════════════════════════════════════ */
@media(max-width:640px){
  /* На телефоне звонок занимает весь экран — как в мессенджерах. Свернуть
     можно кнопкой: тогда он превращается в компактную плашку, которую
     разрешено таскать пальцем куда удобно. */
  #callLayer .call-win{
    left:0; right:0; bottom:0; top:0; width:auto; max-width:none;
    border-radius:0; border:0;
    padding:calc(28px + env(safe-area-inset-top, 0px)) 16px calc(24px + env(safe-area-inset-bottom, 0px));
    display:flex; flex-direction:column; justify-content:center;
    cursor:default;
  }
  /* Содержимое по центру, кнопки — к нижнему краю: так их удобнее нажимать
     большим пальцем, и это привычный вид звонка на телефоне. */
  #callLayer .call-win:not(.mini) .call-stage,
  #callLayer .call-win:not(.mini) .call-mid,
  #callLayer .call-win:not(.mini) .call-emoji,
  #callLayer .call-win:not(.mini) .call-emoji-hint{margin-left:auto;margin-right:auto}
  #callLayer .call-win:not(.mini) .call-btns{margin-top:auto;padding-top:28px}
  #callLayer .call-win:not(.mini) .call-more{margin-bottom:4px}
  #callLayer .call-av{width:96px;height:96px;font-size:34px}
  #callLayer .call-name{font-size:20px}

  /* Кнопки под палец: минимум 60 точек, подписи крупнее. */
  #callLayer .call-btns{gap:14px}
  #callLayer .call-btn i{width:62px;height:62px;font-size:26px}
  #callLayer .call-btn svg{width:26px;height:26px}
  #callLayer .call-btn{font-size:12px}
  #callLayer .call-more{gap:14px}

  /* Служебные кнопки в углу тоже увеличиваем — иначе не попасть. */
  #callLayer .call-mini{width:34px;height:34px;font-size:19px;right:12px;top:14px}
  #callLayer .call-gear{width:34px;height:34px;right:54px;top:14px}
  #callLayer .call-gear svg{width:18px;height:18px}
  #callLayer .call-fs{width:34px;height:34px;right:96px;top:14px}
  #callLayer .call-quality{left:16px;top:20px}

  /* Видео: на узком экране полезнее вертикальная картинка. */
  #callLayer .call-win.video .call-stage{aspect-ratio:3/4;max-height:52vh}
  #callLayer #callLocalVideo{width:74px;max-height:100px;right:8px;bottom:8px}

  /* Входящий звонок разворачиваем крупнее: его надо заметить и попасть. */
  #callLayer #callIncoming{padding-top:28px}
  #callLayer #callIncoming .call-av{width:110px;height:110px;font-size:40px}
  #callLayer #callIncoming .call-btns{gap:34px;margin-top:26px}
  #callLayer #callIncoming .call-btn i{width:70px;height:70px}

  /* Свёрнутое окно — компактная плашка, её можно перетаскивать пальцем. */
  #callLayer .call-win.mini{
    top:auto; left:8px; right:auto; bottom:calc(12px + env(safe-area-inset-bottom, 0px));
    width:auto; min-width:0; max-width:calc(100vw - 16px);
    border-radius:999px; border:1px solid var(--cborder);
    padding:10px 12px; display:flex; flex-direction:row; justify-content:flex-start;
    cursor:grab;
  }
  #callLayer .call-win.mini .call-av{width:42px;height:42px;font-size:16px}
  #callLayer .call-win.mini .call-btn i{width:44px;height:44px}

  /* Выбор устройств: список во всю ширину, чтобы читались названия. */
  #callLayer .call-dev{padding:12px}
  #callLayer .call-dev-btn{font-size:13.5px;padding:10px 12px}
  #callLayer .call-dev-item{padding:11px 12px;font-size:13.5px}

  /* Полный экран на телефоне — по сути то же окно, но без отступов. */
  #callLayer .call-win.fs{left:0;right:0;bottom:0;padding:0}
  #callLayer .call-win.fs .call-btns{margin-bottom:calc(26px + env(safe-area-inset-bottom, 0px))}
}

/* Совсем узкие экраны: подписи под кнопками съедают место. */
@media(max-width:360px){
  #callLayer .call-btn span{display:none}
  #callLayer .call-btns{gap:18px}
}


/* ══════════════════════════════════════════════════════════════
 *  ГРУППОВЫЕ ЗВОНКИ
 *  Сетка участников, своё видео отдельным окошком в углу.
 *  Цвета — только через переменные платформы: тёмная тема
 *  переопределяет их, хардкод дал бы белое окно на чёрном.
 * ══════════════════════════════════════════════════════════════ */
#grLayer .gr-win{
  position:fixed; inset:auto 24px 24px auto; z-index:var(--z-modal,1000);
  width:min(720px, calc(100vw - 48px)); padding:16px;
  background:var(--cpanel); border:1px solid var(--cborder);
  border-radius:18px; box-shadow:0 16px 48px rgba(0,0,0,.28); color:var(--ctext);
}
#grLayer .gr-head{display:flex;align-items:center;gap:10px;margin-bottom:12px;flex-wrap:wrap}
#grLayer .gr-count{font-size:13px;font-weight:700}
/* Честная пометка: в групповом звонке потоки идут через сервер. */
#grLayer .gr-warn{
  font-size:11px; padding:3px 8px; border-radius:999px;
  background:rgba(229,72,77,.12); color:#E5484D; font-weight:600;
}
#grLayer .gr-status{font-size:12px;color:var(--cmuted);margin-left:auto}

#grLayer .gr-grid{display:grid;gap:8px;grid-template-columns:repeat(2,1fr)}
#grLayer .gr-grid.n0{display:none}
#grLayer .gr-grid.n1{grid-template-columns:1fr}
#grLayer .gr-grid.n2,#grLayer .gr-grid.n3,#grLayer .gr-grid.n4{grid-template-columns:repeat(2,1fr)}
#grLayer .gr-grid.n5,#grLayer .gr-grid.n6,
#grLayer .gr-grid.n7,#grLayer .gr-grid.n8,#grLayer .gr-grid.n9{grid-template-columns:repeat(3,1fr)}

#grLayer .gr-tile{
  position:relative; aspect-ratio:4/3; background:rgba(255,255,255,.06);
  border-radius:12px; overflow:hidden; display:grid; place-items:center;
}
#grLayer .gr-tile video{width:100%;height:100%;object-fit:cover;display:block}
#grLayer .gr-av{
  width:56px; height:56px; border-radius:50%; background:rgba(30,138,76,.22);
  color:var(--cgreen); display:grid; place-items:center;
  font-size:22px; font-weight:700;
}
#grLayer .gr-name{
  position:absolute; left:8px; bottom:6px; max-width:calc(100% - 16px);
  font-size:11.5px; color:#fff; background:rgba(0,0,0,.45);
  padding:2px 8px; border-radius:999px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

/* Своё видео — отдельным окошком, а не плиткой в сетке. */
#grLayer .gr-self{
  position:absolute; right:20px; bottom:84px; width:150px; max-height:112px;
  object-fit:cover; border-radius:10px; border:2px solid rgba(255,255,255,.85);
  background:#000; transform:scaleX(-1);
}

#grLayer .gr-btns{display:flex;gap:10px;justify-content:center;margin-top:14px}
#grLayer .gr-btn{
  padding:10px 18px; border-radius:12px; border:1px solid var(--cborder);
  background:transparent; color:var(--ctext); font:inherit; font-size:13px;
  font-weight:600; cursor:pointer;
}
#grLayer .gr-btn:hover{background:rgba(255,255,255,.06)}
#grLayer .gr-btn.off,#grLayer .gr-btn.no{background:#E5484D;color:#fff;border-color:#E5484D}

@media(max-width:640px){
  #grLayer .gr-win{
    inset:0; width:auto; border-radius:0; border:0;
    padding:calc(16px + env(safe-area-inset-top,0px)) 12px calc(16px + env(safe-area-inset-bottom,0px));
    display:flex; flex-direction:column;
  }
  #grLayer .gr-grid{flex:1;align-content:start;overflow-y:auto}
  #grLayer .gr-self{width:104px;max-height:80px;right:12px;bottom:96px}
  #grLayer .gr-btns{margin-top:auto}
}


/* ══════════════════════════════════════════════════════════════
 *  ГРУППОВОЙ ЗВОНОК
 *  Медиа идёт через сервер, поэтому сквозного шифрования здесь нет —
 *  и это честно помечено в шапке окна. Сверки эмодзи, в отличие от
 *  звонка на двоих, тоже нет: подтверждать нечего.
 * ══════════════════════════════════════════════════════════════ */

#roomLayer .room-win{
  position:fixed; inset:0; z-index:var(--z-modal,1000);
  background:var(--cbg); color:var(--ctext);
  display:flex; flex-direction:column; padding:16px;
}
#roomLayer .room-head{
  display:flex; align-items:center; gap:12px; flex:none; margin-bottom:12px;
  /* Шапка должна переноситься, а не выталкивать значки за край экрана. */
  flex-wrap:wrap; min-width:0; padding-right:4px;
}
#roomLayer .room-head > *{min-width:0}
#roomLayer .room-title{font-size:15px;font-weight:700}
#roomLayer .room-count{font-size:13px;color:var(--cmuted)}
/* Состояние связи: человек должен знать, что его не слышат. */
#roomLayer .room-status{font-size:12px;color:#E5A23D;font-weight:600}
#roomLayer .room-status[hidden]{display:none}
/* Пометка о шифровании. Раньше была красной и читалась как тревога —
   хотя это не поломка, а честное описание того, как устроен групповой
   созвон: медиа идёт через сервер, поэтому сквозного шифрования нет.
   Делаем спокойной: суть та же, паники меньше. */
#roomLayer .room-open{
  margin-left:auto; font-size:11px; padding:4px 10px; border-radius:999px;
  background:rgba(255,255,255,.08); color:var(--cmuted); font-weight:500; cursor:help;
}
#roomLayer .room-open:hover{background:rgba(255,255,255,.14);color:var(--ctext)}
#roomLayer .room-grid{
  flex:1; display:grid; gap:10px; align-content:center; overflow:auto; min-height:0;
}
#roomLayer .room-tile{
  position:relative; background:#000; border-radius:14px; overflow:hidden;
  aspect-ratio:16/9; display:grid; place-items:center;
  /* Без потолка одна плитка растягивается на весь экран и выглядит
     нелепо — особенно когда в созвоне ты один. */
  max-height:min(58vh, 460px); max-width:min(100%, 820px);
  margin:0 auto; width:100%;
}
/* Видео НЕ прячем через display:none: скрытый элемент Safari не
   воспроизводит, и запуск отклоняется до появления картинки. Но и делать
   его абсолютным нельзя: при скрытии аватара плитке нечем держать высоту,
   она схлопывалась в ноль — картинка была, а показывать её было негде.
   Поэтому видео остаётся в потоке и всегда занимает всю плитку. */
#roomLayer .room-tile video{
  width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity .2s;
  grid-area:1/1;   /* плитка — grid, видео и аватар в одной ячейке */
}
#roomLayer .room-tile.video video{opacity:1}
/* Аватар поверх видео, пока картинки нет. */
#roomLayer .room-tile .room-ava{grid-area:1/1;place-self:center;z-index:1}
#roomLayer .room-tile.video .room-ava{opacity:0;pointer-events:none}
#roomLayer .room-ava{
  width:72px;height:72px;border-radius:50%;background:#1B3A28;
  color:#4ED88A;display:grid;place-items:center;font-size:26px;font-weight:700;
}
/* Кто говорит — подсветка плитки. В звонке на пятерых без неё непонятно,
   особенно когда камеры выключены и на экране одни аватары. */
#roomLayer .room-tile.talking{box-shadow:inset 0 0 0 3px var(--cgreen)}
#roomLayer .room-tile.talking .room-ava{box-shadow:0 0 0 4px rgba(30,138,76,.35)}

#roomLayer .room-name{
  position:absolute;left:10px;bottom:8px;font-size:12px;
  background:rgba(0,0,0,.5);padding:3px 8px;border-radius:8px;max-width:70%;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* Своя плитка — как у остальных, но с пометкой. Пока никто не подключился,
   на экране должен быть хотя бы ты, а не чернота. */
#roomLayer .room-tile.self{outline:2px solid rgba(30,138,76,.5);outline-offset:-2px}
#roomLayer .room-tile.self video{transform:scaleX(-1)}
/* Экран не зеркалим — иначе текст задом наперёд. */
#roomLayer .room-tile.self.screen video{transform:none}

/* Полоса: в центре — говорящий (или закреплённый) крупно, справа узкой
   колонкой остальные аватарками. Видео в боковых плитках не показываем:
   оно там нечитаемо, а канал и процессор экономятся заметно. */
#roomLayer .room-grid.strip{
  display:grid !important;
  grid-template-columns:1fr 150px !important;
  grid-template-rows:1fr;
  gap:12px; align-content:stretch;
}
#roomLayer .room-grid.strip .room-tile{
  grid-column:2; width:100%; aspect-ratio:4/3; max-height:96px; border-radius:10px;
}
#roomLayer .room-grid.strip .room-tile.main{
  grid-column:1; grid-row:1 / -1; max-height:none; max-width:none;
  aspect-ratio:auto; height:100%; width:100%; align-self:stretch;
  justify-self:stretch; border-radius:14px; margin:0;
}
/* Один в созвоне — боковой колонки нет, центр занимает всё. */
#roomLayer .room-grid.strip:not(:has(.room-tile:not(.main))){
  grid-template-columns:1fr !important;
}
/* В боковых плитках видео скрыто — только аватар и имя. */
#roomLayer .room-grid.strip .room-tile:not(.main) video{opacity:0}
#roomLayer .room-grid.strip .room-tile:not(.main) .room-ava{opacity:1}
#roomLayer .room-grid.strip .room-tile:not(.main) .room-ava{display:grid;width:40px;height:40px;font-size:16px}
#roomLayer .room-grid.strip .room-name{font-size:10px;left:6px;bottom:5px;padding:2px 6px}
#roomLayer .room-grid.strip{overflow:hidden}
/* Качество связи и сворачивание — в шапке окна. */
#roomLayer .room-quality{display:flex;align-items:flex-end;gap:2px;height:14px}
#roomLayer .room-quality i{width:3px;border-radius:1px;background:rgba(255,255,255,.25)}
#roomLayer .room-quality i:nth-child(1){height:6px}
#roomLayer .room-quality i:nth-child(2){height:10px}
#roomLayer .room-quality i:nth-child(3){height:14px}
#roomLayer .room-quality.q3 i{background:#4ED88A}
#roomLayer .room-quality.q2 i:nth-child(-n+2){background:#E5A23D}
#roomLayer .room-quality.q1 i:nth-child(1){background:#E5484D}
#roomLayer .room-mini{
  width:28px;height:28px;border-radius:8px;border:1px solid rgba(255,255,255,.2);
  background:transparent;color:#F6F8F5;font:inherit;font-size:16px;line-height:1;cursor:pointer;
}
#roomLayer .room-mini:hover{background:rgba(255,255,255,.08)}

/* Свёрнутый вид: компактная плашка, работать можно, звонок не потерян. */
#roomLayer .room-win.mini{
  /* Свёрнутое окно — узкая плашка внизу справа. Раньше сетка оставалась
     в потоке и растягивала его в вертикальную полосу на весь экран. */
  inset:auto 20px 20px auto !important; width:auto !important; min-width:210px;
  height:auto !important; max-height:none;
  border-radius:16px; padding:12px 16px; border:1px solid var(--cborder);
  box-shadow:0 12px 40px rgba(0,0,0,.4); cursor:pointer;
}
#roomLayer .room-win.mini .room-grid,
#roomLayer .room-win.mini .room-tile,
#roomLayer .room-win.mini #roomSelf,
#roomLayer .room-win.mini .room-open,
#roomLayer .room-win.mini .room-mini,
#roomLayer .room-win.mini .room-btn.cam,
#roomLayer .room-win.mini #roomScrBtn,
#roomLayer .room-win.mini #roomViewBtn{display:none}
#roomLayer .room-win.mini .room-head{margin-bottom:10px}
#roomLayer .room-win.mini .room-grid{display:none !important}
#roomLayer .room-win.mini .room-btns{padding-top:0;gap:14px}
#roomLayer .room-win.mini .room-btn i{width:44px;height:44px}
#roomLayer .room-win.mini .room-btn span{display:none}

/* Выбор устройств и запись. */
#roomLayer .room-dev{
  position:absolute; right:16px; top:52px; z-index:5; width:min(280px,80vw);
  background:var(--cpanel); border:1px solid var(--cborder);
  border-radius:12px; padding:10px; display:flex; flex-direction:column; gap:10px;
  box-shadow:0 10px 30px rgba(0,0,0,.4);
}
#roomLayer .room-dev[hidden]{display:none}
#roomLayer .room-dev-row{display:flex;flex-direction:column;gap:4px;font-size:11px;color:var(--cmuted)}
#roomLayer .room-dev-item{
  text-align:left;font:inherit;font-size:12.5px;padding:7px 10px;border-radius:8px;
  border:1px solid var(--cborder);background:transparent;color:#F6F8F5;cursor:pointer;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
#roomLayer .room-dev-item:hover{background:rgba(255,255,255,.06)}
#roomLayer .room-dev-item.on{background:var(--cgreen);border-color:var(--cgreen);font-weight:600}
#roomLayer .room-mini svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round}
#roomLayer .room-mini circle{fill:var(--cpanel)}

#roomLayer .room-rec-badge{
  position:absolute; left:50%; top:16px; transform:translateX(-50%); z-index:5;
  display:inline-flex; align-items:center; gap:6px; padding:5px 12px;
  border-radius:999px; background:rgba(229,72,77,.16); color:#E5484D;
  font-size:12px; font-weight:700;
}
#roomLayer .room-rec-badge[hidden]{display:none}
#roomLayer .room-rec-badge i{width:8px;height:8px;border-radius:50%;background:#E5484D;
  animation:callRecPulse 1.4s ease-in-out infinite}
#roomLayer .room-rec-ask{
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); z-index:6;
  width:min(340px,86vw); padding:16px; border-radius:14px;
  background:var(--cpanel); border:1px solid var(--cborder);
  box-shadow:0 16px 44px rgba(0,0,0,.5);
}
#roomLayer .room-rec-ask[hidden]{display:none}
#roomLayer .room-rec-t{font-size:13px;line-height:1.45;margin-bottom:12px}
#roomLayer .room-rec-b{display:flex;gap:8px}
#roomLayer .room-rec-yes,#roomLayer .room-rec-no{
  flex:1;padding:9px;border-radius:9px;font:inherit;font-size:12.5px;font-weight:600;
  cursor:pointer;border:1px solid transparent;
}
#roomLayer .room-rec-yes{background:var(--cgreen);color:#fff}
#roomLayer .room-rec-no{background:transparent;border-color:var(--cborder);color:#F6F8F5}
#roomLayer .room-btn.rec.on i,#roomLayer #roomRecBtn.on i{background:#E5484D}
#roomLayer .room-win.mini #roomRecBtn,
#roomLayer .room-win.mini .room-dev,
#roomLayer .room-win.mini .room-rec-ask{display:none}

/* Список участников: в сетке видно не всех — при выключенных камерах и
   режиме «активные» часть людей на экране отсутствует. */
#roomLayer .room-people{
  position:absolute; right:16px; top:52px; z-index:6; width:min(320px,86vw);
  max-height:60vh; overflow:auto; padding:12px;
  background:var(--cpanel); border:1px solid var(--cborder);
  border-radius:12px; box-shadow:0 12px 34px rgba(0,0,0,.45);
}
#roomLayer .room-people[hidden]{display:none}
#roomLayer .room-people-t{font-size:12px;color:var(--cmuted);margin-bottom:10px}
#roomLayer .room-people-row{
  display:flex;align-items:center;gap:8px;padding:7px 0;font-size:13px;
  border-bottom:1px solid var(--cborder);
}
#roomLayer .room-people-row span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#roomLayer .room-p-btn{
  font:inherit;font-size:11px;padding:4px 8px;border-radius:7px;cursor:pointer;
  border:1px solid var(--cborder);background:transparent;color:#F6F8F5;
}
#roomLayer .room-p-btn:hover{background:rgba(255,255,255,.08)}
#roomLayer .room-p-btn.no{color:#E5484D;border-color:rgba(229,72,77,.4)}
#roomLayer .room-people-host{
  margin-top:12px;padding-top:10px;border-top:1px solid var(--cborder);
  display:flex;flex-direction:column;gap:8px;font-size:12px;color:var(--cmuted);
}
#roomLayer .room-people-host label{display:flex;align-items:center;gap:9px;cursor:pointer}
/* Свои переключатели: системные выглядят чужеродно в тёмном окне созвона. */
#roomLayer .room-people-host input[type=checkbox]{
  appearance:none; -webkit-appearance:none; margin:0; flex:none;
  width:36px; height:20px; border-radius:999px; cursor:pointer;
  background:rgba(255,255,255,.14); border:1px solid var(--cborder);
  position:relative; transition:background .15s;
}
#roomLayer .room-people-host input[type=checkbox]::after{
  content:''; position:absolute; left:2px; top:1px; width:16px; height:16px;
  border-radius:50%; background:#F6F8F5; transition:transform .15s;
}
#roomLayer .room-people-host input[type=checkbox]:checked{
  background:var(--cgreen); border-color:var(--cgreen);
}
#roomLayer .room-people-host input[type=checkbox]:checked::after{transform:translateX(16px)}

/* Кто просится в созвон — видит только ведущий. */
#roomLayer .room-waiting{
  position:absolute; left:50%; top:16px; transform:translateX(-50%); z-index:7;
  width:min(360px,88vw); padding:12px;
  background:var(--cpanel); border:1px solid var(--cgreen);
  border-radius:12px; box-shadow:0 12px 34px rgba(0,0,0,.45);
}
#roomLayer .room-waiting[hidden]{display:none}
#roomLayer .room-wait-t{font-size:12px;color:var(--cmuted);margin-bottom:8px}
#roomLayer .room-wait-row{display:flex;align-items:center;gap:8px;padding:5px 0;font-size:13px}
#roomLayer .room-wait-row span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#roomLayer .room-wait-ok,#roomLayer .room-wait-no{
  font:inherit;font-size:11px;padding:5px 10px;border-radius:7px;cursor:pointer;border:0;
}
#roomLayer .room-wait-ok{background:var(--cgreen);color:#fff}
#roomLayer .room-wait-no{background:transparent;color:#E5484D;border:1px solid rgba(229,72,77,.4)}

/* Ожидание впуска — то, что видит сам гость. */
#roomLayer .room-waitme{
  grid-column:1/-1;text-align:center;font-size:14px;color:var(--cmuted);padding:40px 20px;
}
#roomLayer .room-win.waiting-me .room-btn.cam,
#roomLayer .room-win.waiting-me #roomScrBtn,
#roomLayer .room-win.waiting-me #roomRecBtn,
#roomLayer .room-win.waiting-me #roomViewBtn,
#roomLayer .room-win.waiting-me #roomPeopleBtn,
#roomLayer .room-win.waiting-me #roomSelf{display:none}
#roomLayer .room-win.mini .room-people,
#roomLayer .room-win.mini .room-waiting{display:none}

/* Поднятая рука, реакции, закрепление выступающего. */
#roomLayer .room-tile.hand::after{
  content:'\270B'; position:absolute; right:8px; top:6px; font-size:20px;
  filter:drop-shadow(0 1px 2px rgba(0,0,0,.6));
}
#roomLayer .room-hand{flex:none;font-size:15px}
#roomLayer .room-btn.on i{background:var(--cgreen)}
#roomLayer .room-react-bar{
  position:absolute; left:50%; bottom:100px; transform:translateX(-50%); z-index:7;
  display:flex; gap:6px; padding:8px 10px; border-radius:999px;
  background:var(--cpanel); border:1px solid var(--cborder);
  box-shadow:0 10px 28px rgba(0,0,0,.45);
}
#roomLayer .room-react-bar[hidden]{display:none}
#roomLayer .room-react-bar button{
  font-size:22px; line-height:1; background:none; border:0; cursor:pointer;
  padding:4px 6px; border-radius:10px;
}
#roomLayer .room-react-bar button:hover{background:rgba(255,255,255,.1)}
/* Реакция всплывает и гаснет: она про «сейчас», а не про историю. */
#roomLayer .room-react{
  position:fixed; z-index:9; font-size:34px; pointer-events:none;
  animation:roomReact 2.2s ease-out forwards;
}
@keyframes roomReact{
  0%{opacity:0;transform:translate(-50%,0) scale(.6)}
  15%{opacity:1;transform:translate(-50%,-10px) scale(1.1)}
  100%{opacity:0;transform:translate(-50%,-90px) scale(1)}
}
/* Закреплённый — крупно, остальные полосой. */
#roomLayer .room-grid.has-spot{grid-template-columns:1fr !important;grid-auto-rows:min-content}
#roomLayer .room-grid.has-spot .room-tile{display:none}
#roomLayer .room-grid.has-spot .room-tile.spot{display:grid;aspect-ratio:16/9}

/* Приглашение гостя. */
#roomLayer .room-inv-open{
  width:100%;margin-top:10px;padding:8px;border-radius:9px;font:inherit;font-size:12.5px;
  font-weight:600;cursor:pointer;border:1px solid var(--cgreen);
  background:transparent;color:#4ED88A;
}
#roomLayer .room-invite{
  position:absolute; right:16px; top:52px; z-index:7; width:min(300px,84vw);
  max-height:50vh; overflow:auto; padding:12px;
  background:var(--cpanel); border:1px solid var(--cborder);
  border-radius:12px; box-shadow:0 12px 34px rgba(0,0,0,.45);
}
#roomLayer .room-invite[hidden]{display:none}
#roomLayer .room-inv-t{font-size:12px;color:var(--cmuted);margin-bottom:8px}
#roomLayer .room-inv-item{
  display:block;width:100%;text-align:left;font:inherit;font-size:13px;
  padding:8px 10px;border-radius:8px;margin-bottom:4px;cursor:pointer;
  border:1px solid var(--cborder);background:transparent;color:#F6F8F5;
}
#roomLayer .room-inv-item:hover:not(:disabled){background:rgba(255,255,255,.07)}
#roomLayer .room-inv-item:disabled{opacity:.5;cursor:default}
#roomLayer .room-win.mini .room-invite,
#roomLayer .room-win.mini .room-react-bar,
#roomLayer .room-win.mini #roomHandBtn,
#roomLayer .room-win.mini #roomReactBtn,
#roomLayer .room-win.mini #roomPeopleBtn{display:none}

#roomLayer .room-btns{display:flex;gap:22px;justify-content:center;flex:none;padding-top:14px}
#roomLayer .room-btn{
  display:flex;flex-direction:column;align-items:center;gap:6px;
  background:none;border:0;padding:0;cursor:pointer;font:inherit;
  font-size:11px;color:var(--cmuted);
}
#roomLayer .room-btn i{
  width:58px;height:58px;border-radius:50%;display:grid;place-items:center;
  background:rgba(255,255,255,.10);color:#F6F8F5;
}
#roomLayer .room-btn svg{width:24px;height:24px;fill:currentColor;display:block}
#roomLayer .room-btn.on i{background:var(--cgreen)}
#roomLayer .room-btn.off i{background:#E5484D}
#roomLayer .room-btn.no i{background:#E5484D}
@media(max-width:640px){
  #roomLayer .room-win{padding:12px calc(10px + env(safe-area-inset-right,0px))
    calc(14px + env(safe-area-inset-bottom,0px)) calc(10px + env(safe-area-inset-left,0px))}
  #roomLayer #roomSelf{width:110px;max-height:90px;right:12px;bottom:96px}
  #roomLayer .room-btn i{width:56px;height:56px}
}


/* ══════════════════════════════════════════════════════════════
 *  ПОМОЩНИК АДМИНИСТРАЦИИ — плавающее окно
 *  Кнопка в углу, доступна из любого раздела админки. Отвечает о
 *  состоянии платформы обычным языком.
 * ══════════════════════════════════════════════════════════════ */
#asstLayer{position:fixed;right:22px;bottom:22px;z-index:9000}
.asst-fab{
  width:56px;height:56px;border-radius:50%;border:0;cursor:pointer;
  background:var(--g,#1E8A4C);color:#fff;display:grid;place-items:center;
  box-shadow:0 8px 24px rgba(0,0,0,.35);position:relative;
  transition:transform .15s;
}
.asst-fab:hover{transform:scale(1.05)}
.asst-fab.on{background:var(--w,#16241D);border:1px solid var(--bdr,#25382E)}
.asst-fab svg{width:26px;height:26px;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
/* Точка на кнопке: что-то требует внимания. */
.asst-dot{
  position:absolute;top:4px;right:4px;width:12px;height:12px;border-radius:50%;
  background:#E5A23D;border:2px solid var(--bg,#0E1A14);
}
.asst-dot.danger{background:#E5484D}
.asst-dot[hidden]{display:none}

.asst-win{
  position:absolute;right:0;bottom:70px;width:min(400px,calc(100vw - 40px));
  max-height:min(600px,calc(100vh - 120px));
  background:var(--w,#16241D);border:1px solid var(--bdr,#25382E);
  border-radius:16px;box-shadow:0 16px 48px rgba(0,0,0,.45);
  display:flex;flex-direction:column;overflow:hidden;
}
.asst-win[hidden]{display:none}
.asst-top{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:14px 16px;border-bottom:1px solid var(--bdr,#25382E);flex:none;
}
.asst-name{font-size:14px;font-weight:700}
.asst-note{font-size:11px;color:var(--tm,#8AA394);margin-top:2px}
.asst-close{
  width:28px;height:28px;border-radius:8px;border:0;cursor:pointer;
  background:transparent;color:var(--tm,#8AA394);font-size:22px;line-height:1;
}
.asst-close:hover{background:rgba(255,255,255,.07);color:var(--t,#F6F8F5)}

.asst-body{flex:1;overflow-y:auto;padding:14px 16px;display:flex;flex-direction:column;gap:10px;min-height:80px}
.asst-msg{font-size:13.5px;line-height:1.55;max-width:100%}
.asst-msg.me{
  align-self:flex-end;background:var(--g,#1E8A4C);color:#fff;
  padding:8px 12px;border-radius:12px 12px 4px 12px;max-width:85%;
}
.asst-msg.bot{
  background:var(--bg,#0E1A14);padding:12px;border-radius:12px 12px 12px 4px;
  border-left:3px solid var(--g,#1E8A4C);
}
.asst-msg.bot.warn{border-left-color:#E5A23D}
.asst-msg.bot.danger{border-left-color:#E5484D}
.asst-msg.wait{color:var(--tm,#8AA394);border-left-color:var(--bdr,#25382E)}
.asst-head{font-size:14px;font-weight:700;margin-bottom:6px}
.asst-msg.bot.warn .asst-head{color:#E5A23D}
.asst-msg.bot.danger .asst-head{color:#E5484D}
.asst-text{color:var(--t,#F6F8F5)}
.asst-lbl{font-size:10.5px;color:var(--tm,#8AA394);text-transform:uppercase;
  letter-spacing:.04em;margin-bottom:4px}
.asst-act{margin-top:10px;padding-top:10px;border-top:1px solid var(--bdr,#25382E)}
.asst-act ul{margin:0;padding-left:16px}
.asst-act li{font-size:12.5px;line-height:1.55}
.asst-facts{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.asst-fact{
  display:flex;flex-direction:column;gap:1px;padding:6px 10px;border-radius:8px;
  background:rgba(255,255,255,.05);min-width:96px;
}
.asst-fact span{font-size:10px;color:var(--tm,#8AA394)}
.asst-fact b{font-size:12.5px;font-weight:600}
.asst-fact.warn b{color:#E5A23D}
.asst-fact.danger b{color:#E5484D}

.asst-quick{display:flex;flex-wrap:wrap;gap:6px;padding:0 16px 10px;flex:none}
.asst-chip{
  padding:6px 11px;border-radius:999px;cursor:pointer;font:inherit;font-size:11.5px;
  border:1px solid var(--bdr,#25382E);background:transparent;color:var(--tm,#8AA394);
}
.asst-chip:hover{background:rgba(255,255,255,.06);color:var(--t,#F6F8F5)}

.asst-ask{display:flex;gap:8px;padding:12px 16px;border-top:1px solid var(--bdr,#25382E);flex:none}
.asst-ask input{
  flex:1;padding:10px 12px;border-radius:10px;font:inherit;font-size:13px;
  border:1px solid var(--bdr,#25382E);background:var(--bg,#0E1A14);color:var(--t,#F6F8F5);
}
.asst-ask input:focus{outline:none;border-color:var(--g,#1E8A4C)}
.asst-ask button{
  width:40px;flex:none;border-radius:10px;border:0;cursor:pointer;
  background:var(--g,#1E8A4C);color:#fff;display:grid;place-items:center;
}
.asst-ask button svg{width:18px;height:18px;fill:currentColor}

@media(max-width:640px){
  #asstLayer{right:14px;bottom:14px}
  .asst-win{width:calc(100vw - 28px);max-height:calc(100vh - 100px)}
  .asst-fab{width:50px;height:50px}
}
