/* ═══════════════════════════════════════════════════════════════
   mobile-v3.css — Мобильная адаптация LASTOP GROUP
   ═══════════════════════════════════════════════════════════════
   Версия: 3.0 (вторая попытка, начата 15.05.26)
   Killswitch: env MOBILE_V3_DISABLE=1 + restart lastop сервиса

   ПРАВИЛА:
   - Все правила обёрнуты в @media (max-width: XXXpx)
   - Top-level только для CSS-переменных и универсальных
     нормализаций (touch-action и т.п.)
   - Каждое правило снабжено комментарием с целью
   - Никаких !important без обоснования в комментарии

   См. также:
   - web/assets/mobile-injector.js — мобильная JS-логика
   - cmd/server/main.go renderHTMLInject() — точка подключения
   - Obsidian: 07 — Правила работы с Codex (раздел «📱»)
   - Obsidian: 23 — Дорожная карта мобильной адаптации
   ═══════════════════════════════════════════════════════════════ */

/* ───────────────────────────────────────────────────────────────
   TOP-LEVEL: CSS-переменные и универсальные нормализации
   Допустимы по правилу И2 (см. Obsidian 07 раздел «📱»)
   ─────────────────────────────────────────────────────────────── */

:root {
  /* Fluid font-size: на узких экранах слегка меньше, на широких — обычный.
     clamp(min, preferred, max) — на 360px даст ~13px, на 640px ~14px. */
  --m-fs-sm: clamp(12.5px, 3.4vw, 14px);
  --m-fs-md: clamp(13.5px, 3.6vw, 15px);

  /* Высота будущего bottom-nav (используется на этапе 2+ для padding-bottom main). */
  --m-bn-height: 64px;

  /* Безопасная зона снизу (notch / home indicator на iPhone). */
  --m-safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* Универсальные нормализации для touch-устройств.
   Top-level допустимо: правила безопасны для десктопа
   (touch-action на не-touch устройствах = no-op,
   tap-highlight видим только на touch). */
button,
a,
[role="button"],
.nav-item,
.icon-btn,
.ftab {
  /* Убираем синюю подсветку при тапе на iOS Safari. И2: универсальная норма. */
  -webkit-tap-highlight-color: transparent;
  /* Убирает 300ms задержку double-tap zoom на старых iOS. */
  touch-action: manipulation;
}

/* ─── iOS Safari: предотвращение авто-зума при фокусе на инпуте ───
   Safari на iOS автоматически зумит страницу когда фокус попадает
   на <input>/<textarea> с font-size меньше 16px. После зума
   viewport расползается, и важные элементы (кнопка отправки в
   чате, кнопка submit формы) уходят за пределы видимой области.
   Apple сама рекомендует font-size:16px+ для редактируемых полей
   на мобильных страницах. На Android поведение не вызывает зум,
   но 16px нейтрально для UX.

   Применяем правило в двух вариантах:
   1) общий — input/textarea/select/contenteditable в фокусе
   2) точечный — для .ci-textarea (поле сообщения в чате), чтобы
      перебить специфичные стили класса. */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  input:focus,
  textarea:focus,
  select:focus,
  [contenteditable="true"]:focus,
  .ci-textarea,
  .ci-textarea:focus {
    font-size: 16px !important;
  }
  /* Чат-инпут раскрывался на 2 строки: autoGrow ставит min-height 22px
     (под десктопный 13px × 1.5 = 19.5px), а тут шрифт форсится в 16px →
     16 × 1.5 = 24px не влезает в 22px → scrollHeight даёт высоту 2 строк.
     Снижаем line-height до 1.375 (16 × 1.375 = 22px — ровно одна строка). */
  .ci-textarea {
    line-height: 1.375 !important;
  }
}

/* ───────────────────────────────────────────────────────────────
   @media ≤640px — основная мобильная зона
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* Чуть-чуть уменьшаем базовый шрифт чтобы текст не ломал layout
     на узких экранах. Не агрессивно — fluid через clamp. */
  html.lt-shell body,
  html.lt-shell-2col body {
    font-size: var(--m-fs-sm);
  }

  /* Главное переопределение grid: одна колонка, две строки.
     Прячем areas logo/nav/right — оставляем только topbar и main.
     specificity (0,2,1) перебивает все @media-зоны в shell-layout.css
     которые работают до ≤740, и top-level html.lt-shell .shell (0,2,1). */
  html.lt-shell .shell,
  html.lt-shell-2col .shell {
    grid-template-columns: 1fr;
    grid-template-rows: 56px 1fr;
    grid-template-areas:
      "topbar"
      "main";
    gap: 8px;
    padding: 8px;
  }

  /* Скрываем элементы которые не помещаются в мобильный layout.
     Логотип убираем — место занимает топбар.
     .nav скрываем — его заменит bottom-nav на этапе 2.
     .right уже скрыт с ≤1000 в shell-layout.css, дублируем для надёжности. */
  html.lt-shell .logo-cell,
  html.lt-shell-2col .logo-cell,
  html.lt-shell .nav,
  html.lt-shell-2col .nav,
  html.lt-shell .right,
  html.lt-shell-2col .right {
    display: none;
  }

  /* ── B-M-NEWS-CRUMB: крошки новости не влезают → горизонтальный скролл ── */
  html.lt-shell .breadcrumb,
  html.lt-shell-2col .breadcrumb {
    overflow-x: auto;
    flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  html.lt-shell .breadcrumb::-webkit-scrollbar,
  html.lt-shell-2col .breadcrumb::-webkit-scrollbar {
    display: none;
  }

  /* На мобиле main скроллится сам (на десктопе шеллом).
     Без этого контент уезжает за пределы viewport. */
  html.lt-shell .main,
  html.lt-shell-2col .main {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    min-height: 0;
  }

  /* Topbar — единственный survivor сверху. Убедимся что он
     не пытается растянуть какие-то ячейки колонок. */
  html.lt-shell .topbar,
  html.lt-shell-2col .topbar {
    grid-template-columns: 1fr auto;
  }

  /* ── B-ADMIN-MOBILE (5): bulk-бары + тулбар фильтров ── */
  /* bulk-бары массовых действий — перенос кнопок, не выходят за край */
  html.lt-shell #usersBulkBar,
  html.lt-shell #companiesBulkBar,
  html.lt-shell #communitiesBulkBar,
  html.lt-shell #complaintsBulkBar,
  html.lt-shell-2col #usersBulkBar,
  html.lt-shell-2col #companiesBulkBar,
  html.lt-shell-2col #communitiesBulkBar,
  html.lt-shell-2col #complaintsBulkBar {
    flex-wrap: wrap;
    gap: 8px;
  }
  /* поиск в тулбаре — не распирать (min-width:200px → авто) */
  html.lt-shell .users-toolbar input[type=search],
  html.lt-shell-2col .users-toolbar input[type=search] {
    min-width: 0;
    flex: 1 1 100%;
  }
  /* селекты фильтров — на всю ширину для удобного тапа */
  html.lt-shell .users-toolbar select,
  html.lt-shell-2col .users-toolbar select {
    flex: 1 1 auto;
  }

  /* ── Settings «Управление платформой» (#panel-admin) под мобилку ── */
  /* ряды «текст + контрол» (тумблер/кнопка) — в столбик, контрол под текстом */
  html.lt-shell #panel-admin .panel-section > div[style*="space-between"],
  html.lt-shell-2col #panel-admin .panel-section > div[style*="space-between"] {
    flex-direction: column;
    align-items: stretch !important;
    gap: 10px !important;
  }
  /* кнопки в секции — на всю ширину для удобного тапа */
  html.lt-shell #panel-admin button,
  html.lt-shell-2col #panel-admin button {
    width: 100%;
  }
  /* тумблеры остаются как есть (не растягивать) — выравниваем влево */
  html.lt-shell #panel-admin label[style*="width:42px"],
  html.lt-shell-2col #panel-admin label[style*="width:42px"] {
    align-self: flex-start;
    width: 42px !important;
  }
  /* Контент секции «Управление платформой» не должен вылезать за край */
  html.lt-shell #panel-admin,
  html.lt-shell #panel-admin *,
  html.lt-shell-2col #panel-admin,
  html.lt-shell-2col #panel-admin * {
    max-width: 100%;
    box-sizing: border-box;
    min-width: 0;
  }
  html.lt-shell #panel-admin,
  html.lt-shell-2col #panel-admin {
    overflow-x: hidden;
  }
  /* грид-обёртки настроек: разорвать цепочку переполнения (min-width:auto → 0) */
  html.lt-shell .settings-body,
  html.lt-shell .settings-panels,
  html.lt-shell-2col .settings-body,
  html.lt-shell-2col .settings-panels {
    min-width: 0;
    max-width: 100%;
    overflow-x: hidden;
  }
  html.lt-shell .settings-panels > .s-panel,
  html.lt-shell-2col .settings-panels > .s-panel {
    min-width: 0;
    max-width: 100%;
  }
  /* длинные слова/текст в описаниях и textarea — переносить */
  html.lt-shell #panel-admin div,
  html.lt-shell #panel-admin textarea,
  html.lt-shell-2col #panel-admin div,
  html.lt-shell-2col #panel-admin textarea {
    word-break: break-word;
    overflow-wrap: anywhere;
  }
}

/* ───────────────────────────────────────────────────────────────
   @media ≤375px — узкие устройства (iPhone SE и подобные)
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 375px) {

  /* Ещё компактнее padding shell. */
  html.lt-shell .shell,
  html.lt-shell-2col .shell {
    gap: 6px;
    padding: 6px;
  }
}

/* ───────────────────────────────────────────────────────────────
   Э2 — Bottom-nav и sheet-меню (только ≤640)
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* Bottom-nav: floating-капсула в стиле iOS (liquid glass) — оторвана
     от краёв, скруглена, полупрозрачное стекло с блюром. Цвет стекла —
     под тему (светлое/тёмное). z-index выше карточек, ниже модалок.
     При скролле вниз получает .m-bn-shrink (ниже + прозрачнее, см. ниже). */
  .m-bn {
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: calc(18px + var(--m-safe-bottom));
    z-index: var(--z-sticky);
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    align-items: center;
    height: var(--m-bn-height);
    padding: 0 6px;
    border-radius: 30px;
    background: rgba(255, 255, 255, 0.60);
    -webkit-backdrop-filter: blur(12px) saturate(180%);
    backdrop-filter: blur(12px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.6);
    box-shadow: 0 8px 32px rgba(30, 138, 76, 0.15), 0 2px 8px rgba(0, 0, 0, 0.06);
    transition: height 280ms cubic-bezier(0.4, 0, 0.2, 1),
                bottom 280ms cubic-bezier(0.4, 0, 0.2, 1),
                transform 240ms cubic-bezier(0.4, 0, 0.2, 1),
                opacity 200ms ease,
                background 280ms ease, box-shadow 280ms ease;
  }

  /* Скрытие навбара при открытой клавиатуре (чат, формы): уезжает вниз
     за экран, чтобы не перекрывать поле ввода и не мешать набору. */
  .m-bn.m-bn-hidden {
    transform: translateY(170%);
    opacity: 0;
    pointer-events: none;
  }

  /* Сжатое состояние при скролле вниз: ниже, компактнее, прозрачнее,
     подписи скрываются, иконки чуть крупнее (как на референсе iOS). */
  .m-bn.m-bn-shrink {
    height: 52px;
    bottom: calc(12px + var(--m-safe-bottom));
    background: rgba(255, 255, 255, 0.42);
  }
  .m-bn.m-bn-shrink .m-bn-lbl {
    opacity: 0;
    max-height: 0;
  }
  .m-bn.m-bn-shrink .m-bn-ico {
    width: 24px;
    height: 24px;
  }
  .m-bn.m-bn-shrink .m-bn-pill {
    height: 40px;
  }

  /* Пункт bottom-nav: иконка сверху, подпись снизу.
     position:relative — нужно для абсолютного ::before (риска активного).
     transition охватывает color и transform для плавности. */
  .m-bn-item {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    height: 100%;
    text-decoration: none;
    color: var(--gmt, #5A8A6A);
    background: transparent;
    border: 0;
    cursor: pointer;
    font-family: inherit;
    transition: color 200ms cubic-bezier(0.4, 0, 0.2, 1),
                transform 120ms cubic-bezier(0.4, 0, 0.2, 1);
  }

  /* Scale-down при тапе — тактильный feedback в iOS-стиле. */
  .m-bn-item:active {
    transform: scale(0.92);
  }

  /* Единая «плавающая» таблетка под активным пунктом. Один элемент на весь
     навбар — JS двигает его (left/top/width/height) к активному пункту.
     ВАЖНО: по умолчанию БЕЗ transition — первая установка позиции должна
     быть мгновенной (иначе таблетка «приедет» из левого угла = дёрганье).
     Плавный переезд включается классом .m-bn-pill-anim (его добавляет JS
     уже ПОСЛЕ первой установки). Позади иконок (z-index 0). */
  .m-bn-pill {
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 48px;
    border-radius: 22px;
    background: rgba(30, 138, 76, 0.14);
    opacity: 0;
    z-index: 0;
    pointer-events: none;
  }
  .m-bn-pill.m-bn-pill-anim {
    transition: left 340ms cubic-bezier(0.4, 0, 0.2, 1),
                top 260ms cubic-bezier(0.4, 0, 0.2, 1),
                width 340ms cubic-bezier(0.4, 0, 0.2, 1),
                height 260ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  .m-bn-pill.m-bn-pill-on {
    opacity: 1;
  }

  .m-bn-ico {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    transition: width 280ms cubic-bezier(0.4, 0, 0.2, 1),
                height 280ms cubic-bezier(0.4, 0, 0.2, 1),
                transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1);
  }

  .m-bn-lbl {
    font-size: 10px;
    font-weight: 600;
    line-height: 1;
    overflow: hidden;
    transition: opacity 200ms ease, max-height 280ms ease, font-weight 200ms ease;
    max-height: 14px;
  }

  /* Активный пункт — зелёный + иконка чуть крупнее + подпись жирнее.
     Таблетку рисует общий .m-bn-pill (двигается JS), не ::before. */
  .m-bn-active {
    color: var(--g, #1E8A4C);
  }
  .m-bn-active .m-bn-ico {
    transform: scale(1.04);
  }
  .m-bn-active .m-bn-lbl {
    font-weight: 700;
  }

  /* Reduce-motion: пользователи с включённой настройкой получают
     мгновенные смены без анимаций (a11y-best-practice). */
  @media (prefers-reduced-motion: reduce) {
    .m-bn-item,
    .m-bn-pill,
    .m-bn-ico,
    .m-bn-lbl {
      transition: none;
    }
    .m-bn-item:active {
      transform: none;
    }
  }

  /* Компенсация под bottom-nav: контент main не должен уезжать под него. */
  html.lt-shell .main,
  html.lt-shell-2col .main {
    padding-bottom: calc(var(--m-bn-height) + var(--m-safe-bottom) + 34px);
  }

  /* Sheet-меню: затемнение фона. */
  .m-menu-bg {
    position: fixed;
    inset: 0;
    z-index:var(--z-dropdown);
    background: rgba(15, 25, 18, 0.45);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    opacity: 0;
    pointer-events: none;
    transition: opacity 200ms ease;
  }
  .m-menu-bg.m-open {
    opacity: 1;
    pointer-events: auto;
  }

  /* Sheet-меню: сам контейнер, выезжает снизу.
     Использую display:grid для прямого размещения дочерних .m-menu-item
     в плитки 3 в ряд. Header (.m-menu-handle, .m-menu-title)
     растягивается на всю ширину через grid-column:1/-1. */
  .m-menu {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index:var(--z-dropdown);
    max-height: 80vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background: var(--w, #fff);
    border-top-left-radius: 20px;
    border-top-right-radius: 20px;
    padding: 6px 14px calc(18px + var(--m-safe-bottom));
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    transform: translateY(100%);
    transition: transform 240ms cubic-bezier(0.25, 0.8, 0.25, 1);
  }
  .m-menu.m-open {
    transform: translateY(0);
  }

  /* Полоска-«ручка»: растягивается на все 3 колонки grid. */
  .m-menu-handle {
    grid-column: 1 / -1;
    width: 36px;
    height: 4px;
    border-radius: 99px;
    background: var(--bdr, #DDE8E2);
    margin: 8px auto 4px;
  }

  /* Заголовок sheet: на всю ширину. */
  .m-menu-title {
    grid-column: 1 / -1;
    font-size: 11px;
    font-weight: 700;
    color: var(--gmt, #5A8A6A);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    padding: 2px 4px 6px;
  }

  /* Плитка sheet-меню: вертикальная композиция — иконка сверху, текст снизу.
     aspect-ratio:1 даёт квадратные плитки.
     Светло-зелёный фон + граница в стиле карточек платформы. */
  .m-menu-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    aspect-ratio: 1;
    padding: 10px 6px;
    border-radius: 14px;
    background: var(--gp, #F0FAF4);
    border: 1px solid var(--bdr, #DDE8E2);
    text-decoration: none;
    color: var(--t, #1A2A22);
    font-size: 11.5px;
    font-weight: 600;
    line-height: 1.25;
    text-align: center;
    transition: background 120ms ease, transform 120ms ease, border-color 120ms ease;
  }
  .m-menu-item:active {
    background: var(--gl, #E8F5EE);
    border-color: var(--gb, #C0DECA);
    transform: scale(0.97);
  }
  .m-menu-item svg {
    width: 26px;
    height: 26px;
    color: var(--g, #1E8A4C);
    flex-shrink: 0;
  }

  /* При открытом меню — запретить скролл фона. */
  html.m-menu-locked,
  html.m-menu-locked body {
    overflow: hidden;
  }

  /* ─── Топбар на мобиле: компактный профиль вместо широкой плашки ─── */

  /* Колокольчик: функцию забирает пункт «Уведомления» в bottom-nav. */
  html.lt-shell .notif-bell-wrap,
  html.lt-shell-2col .notif-bell-wrap {
    display: none;
  }

  /* Обёртка профиля: снимаем «карточные» стили — фон, рамку, тень, padding.
     На десктопе .profile-dd-wrap — белая карточка с min-height:56px и border,
     из-за чего без колокольчика выглядела как пустая плашка («призрак»).
     На мобиле делаем её просто контейнером под аватар + dropdown. */
  html.lt-shell .topbar > .profile-dd-wrap,
  html.lt-shell-2col .topbar > .profile-dd-wrap {
    background: transparent;
    border: 0;
    box-shadow: none;
    min-height: 0;
    height: auto;
    padding: 0;
    width: auto;
    flex: 0 0 auto;
  }

  /* Карточка профиля: на ≤1000 в shell-layout.css она display:none.
     На мобиле возвращаем как компактный кружок-аватар без имени/роли/стрелки.
     Перебиваем specificity (0,4,1) — выше чем (0,3,1) из shell-layout.css. */
  html.lt-shell .topbar > .profile-dd-wrap > .topbar-profile,
  html.lt-shell-2col .topbar > .profile-dd-wrap > .topbar-profile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    min-width: 0;
    padding: 0;
    border: 1.5px solid var(--bdr, #DDE8E2);
    border-radius: 50%;
    background: var(--gp, #F0FAF4);
    flex: 0 0 36px;
  }

  /* Аватар внутри: занимает весь круг, без скруглений-квадрата с десктопа. */
  html.lt-shell .topbar > .profile-dd-wrap > .topbar-profile > .tp-av,
  html.lt-shell-2col .topbar > .profile-dd-wrap > .topbar-profile > .tp-av {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    font-size: 12px;
  }

  /* Имя+роль и стрелка-шеврон — на мобиле в круглой кнопке не помещаются. */
  html.lt-shell .topbar > .profile-dd-wrap > .topbar-profile > .tp-info,
  html.lt-shell .topbar > .profile-dd-wrap > .topbar-profile > .tp-arrow,
  html.lt-shell-2col .topbar > .profile-dd-wrap > .topbar-profile > .tp-info,
  html.lt-shell-2col .topbar > .profile-dd-wrap > .topbar-profile > .tp-arrow {
    display: none;
  }

  /* Dropdown профиля: открывается от кнопки-аватара. Выравниваем по правому краю,
     ширина с учётом viewport. */
  html.lt-shell .topbar > .profile-dd-wrap > .profile-dd,
  html.lt-shell-2col .topbar > .profile-dd-wrap > .profile-dd {
    right: 0;
    left: auto;
    width: min(280px, calc(100vw - 16px));
  }

  /* ─── Sheet-меню: Настройки отдельным блоком в самом низу ─── */

  /* Тонкий divider перед последним пунктом (Настройки), растянутый
     на все 3 колонки grid. Визуально отделяет «системный» пункт от контентных плиток. */
  .m-menu-item.m-menu-settings {
    grid-column: 1 / -1;
    aspect-ratio: auto;
    flex-direction: row;
    justify-content: flex-start;
    gap: 14px;
    padding: 14px 16px;
    margin-top: 6px;
    border-radius: 12px;
    background: var(--w, #fff);
    border-color: var(--bdr, #DDE8E2);
    font-size: 14px;
    text-align: left;
    /* Псевдоэлемент-разделитель сверху имитирует визуальный gap-блок */
    position: relative;
  }
  .m-menu-item.m-menu-settings::before {
    content: "";
    position: absolute;
    top: -8px;
    left: 8px;
    right: 8px;
    height: 1px;
    background: var(--bdr, #DDE8E2);
  }
  .m-menu-item.m-menu-settings svg {
    width: 22px;
    height: 22px;
  }
  /* Стрелка-шеврон справа: подсказка что это list-row, а не плитка. */
  .m-menu-item.m-menu-settings::after {
    content: "›";
    margin-left: auto;
    font-size: 22px;
    line-height: 1;
    color: var(--gmt, #5A8A6A);
    font-weight: 400;
  }

  /* E-market — флагманский раздел: плитка как остальные, но с фиолетовым
     акцентом (зелёный — основной цвет платформы, фиолетовый сразу читается
     как «особое»). Цвета из дизайн-кода платформы (рекламные блоки). */
  .m-menu-item.m-menu-emarket {
    background: #F8F5FF;
    border-color: #DDD0F0;
    color: #6040A0;
  }
  .m-menu-item.m-menu-emarket svg {
    color: #9060C0;
  }
  .m-menu-item.m-menu-emarket:active {
    background: #EAE0FA;
    border-color: #C9B8EC;
  }
}

/* ───────────────────────────────────────────────────────────────
   Э6 — Главная (home-auth) на мобиле
   Селекторы привязаны к классам в самой home-auth.html.
   Все правила внутри @media ≤640.
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* ── Баннер «Добрый день, …» ── */
  /* На десктопе .home-banner — flex row (привет слева, статистики справа).
     На мобиле растягиваем в вертикальный стек чтобы не давить контент. */
  .home-banner {
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    padding: 14px 16px;
  }
  /* Статистики (Участников / Новостей / Событий) занимают всю ширину
     родителя — три цифры в ряд, без правого выравнивания. */
  .hb-stats {
    width: 100%;
    justify-content: space-between;
    gap: 8px;
  }
  /* Цифры чуть мельче, чтобы 3 пункта точно влезали на 360-390px. */
  .hbs-num {
    font-size: 22px;
  }
  .hbs-lbl {
    font-size: 10px;
  }

  /* ── Compose-bar ── */
  /* Уменьшаем padding и размер кнопки «Опубликовать», иначе
     placeholder обрезается слишком сильно. */
  .compose-bar {
    padding: 8px 10px;
    gap: 8px;
  }
  .compose-bar .cb-ph {
    font-size: 13px;
    /* Многоточие если фраза не помещается. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .compose-bar .cb-btn {
    padding: 8px 14px;
    font-size: 12px;
    flex-shrink: 0;
  }

  /* ── Feed-toolbar (фильтры Все/Новости/Проекты/Компании/Форум) ── */
  /* Горизонтальный скролл вместо переполнения — паттерн iOS Safari. */
  .feed-toolbar {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    flex-wrap: nowrap;
    /* Скрываем нативный scrollbar (стиль уже есть в shell-layout.css но дублируем для надёжности). */
    scrollbar-width: none;
  }
  .feed-toolbar::-webkit-scrollbar {
    display: none;
  }
  .feed-toolbar .ftab {
    flex-shrink: 0;
  }

  /* ── Post-card в ленте ── */
  /* Компактнее padding, иначе на 390px карточки выглядят пустоватыми. */
  .post-card {
    padding: 12px;
    border-radius: 14px;
  }
  /* Аватар автора чуть меньше. */
  .post-card .pc-av {
    width: 36px;
    height: 36px;
    font-size: 13px;
  }
  .post-card .pc-name {
    font-size: 13px;
  }
  .post-card .pc-text {
    font-size: 13px;
  }
}

/* ───────────────────────────────────────────────────────────────
   Э6.1 — Календарь на мобиле: убрать статичные «Сегодня/Скоро»,
   при тапе на день — выезжает блок со списком событий этого дня
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* Скрываем правую колонку календаря — карточки «Сегодня», «Скоро»
     и кнопку «Создать событие». На мобиле они обрезаются и выглядят
     неаккуратно. Создание события — через тап на день. */
  .cal-hero-right {
    display: none;
  }

  /* Календарь и его внутренний блок берут всю ширину виджета. */
  .cal-hero-body {
    grid-template-columns: 1fr;
  }
  .cal-hero-left {
    width: 100%;
  }

  /* Блок «события выбранного дня» — выезжает снизу календаря.
     Появляется только когда .m-cal-daysheet получает класс .m-open. */
  .m-cal-daysheet {
    margin-top: 10px;
    padding: 12px;
    border-radius: 12px;
    background: var(--gp, #F0FAF4);
    border: 1px solid var(--bdr, #DDE8E2);
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    transition: max-height 280ms cubic-bezier(0.4, 0, 0.2, 1),
                opacity 200ms ease,
                padding 220ms cubic-bezier(0.4, 0, 0.2, 1),
                margin-top 220ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  .m-cal-daysheet.m-open {
    max-height: 70vh;
    opacity: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .m-cal-daysheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
  }
  .m-cal-daysheet-title {
    font-size: 14px;
    font-weight: 700;
    color: var(--t, #1A2A22);
  }
  .m-cal-daysheet-close {
    width: 28px;
    height: 28px;
    border-radius: 8px;
    background: transparent;
    border: 0;
    color: var(--gmt, #5A8A6A);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    font-family: inherit;
  }
  .m-cal-daysheet-close:active {
    background: var(--w, #fff);
  }
  .m-cal-daysheet-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
  /* Пункт-событие в day-sheet: иконка-цвет слева, заголовок+мета справа. */
  .m-cal-evrow {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 10px;
    background: var(--w, #fff);
    border: 1px solid var(--bdr, #DDE8E2);
    text-decoration: none;
    color: var(--t, #1A2A22);
  }
  .m-cal-evrow-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
    margin-top: 6px;
  }
  .m-cal-evrow-body {
    flex: 1;
    min-width: 0;
  }
  .m-cal-evrow-title {
    font-size: 13px;
    font-weight: 700;
    line-height: 1.3;
    margin-bottom: 2px;
    /* Многоточие если не помещается */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .m-cal-evrow-meta {
    font-size: 11px;
    color: var(--gmt, #5A8A6A);
  }
  .m-cal-daysheet-empty {
    font-size: 12px;
    color: var(--gmt, #5A8A6A);
    text-align: center;
    padding: 16px 8px;
  }
}

/* ───────────────────────────────────────────────────────────────
   Э7.1 — Settings (/settings.html) на мобиле
   Меню разделов → компактный dropdown-селектор сверху.
   Тап на триггер → меню выезжает сверху вниз.
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* Контейнер: одна колонка вместо двух. */
  .settings-body {
    grid-template-columns: 1fr;
    gap: 10px;
    /* position:relative нужен — внутри будет absolute-меню. */
    position: relative;
  }

  /* Триггер-кнопка инжектируется через mobile-injector.js как
     первый child .settings-body на /settings.html. */
  .m-set-trigger {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 12px 16px;
    border-radius: 12px;
    background: var(--w, #fff);
    border: 1.5px solid var(--bdr, #DDE8E2);
    color: var(--t, #1A2A22);
    font-family: inherit;
    font-size: 14px;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
    /* sticky сверху — даже при прокрутке длинной панели триггер всегда виден. */
    position: sticky;
    top: 0;
    z-index: 6;
  }
  .m-set-trigger:active {
    background: var(--gp, #F0FAF4);
  }
  .m-set-trigger-ico {
    width: 18px;
    height: 18px;
    color: var(--g, #1E8A4C);
    flex-shrink: 0;
  }
  .m-set-trigger-lbl {
    flex: 1;
    min-width: 0;
    /* Многоточие если название раздела не помещается. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .m-set-trigger-chevron {
    width: 16px;
    height: 16px;
    color: var(--gmt, #5A8A6A);
    flex-shrink: 0;
    transition: transform 220ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  /* Когда выпадашка открыта — шеврон поворачивается. */
  .m-set-trigger.m-open .m-set-trigger-chevron {
    transform: rotate(180deg);
  }

  /* Меню привязано к viewport (position:fixed), а не к .settings-body
     (M-S2, 18.05). Раньше при position:absolute и скролле страницы
     меню оказывалось выше viewport — оставалось вне видимой области.
     Координаты top/left/right выставляет JS из mobile-injector через
     getBoundingClientRect() триггера в момент открытия. */
  .settings-menu {
    position: fixed;
    z-index: 7;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px;
    background: var(--w, #fff);
    border: 1.5px solid var(--bdr, #DDE8E2);
    border-radius: 12px;
    box-shadow: 0 8px 24px rgba(30, 138, 76, 0.12);
    /* Начальное состояние: скрыта, готова выехать сверху. */
    opacity: 0;
    transform: translateY(-8px);
    pointer-events: none;
    transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1),
                transform 240ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  .settings-menu.m-open {
    opacity: 1;
    transform: translateY(0);
    pointer-events: auto;
  }

  /* Пункты меню: иконка слева, текст справа, полная ширина. */
  .settings-menu .sm-item {
    width: 100%;
    justify-content: flex-start;
    padding: 12px 14px;
    border-radius: 8px;
    border: 0;
    background: transparent;
    font-size: 14px;
    text-align: left;
  }
  .settings-menu .sm-item:active {
    background: var(--gp, #F0FAF4);
  }
  .settings-menu .sm-item.active {
    background: var(--gl, #E8F5EE);
    color: var(--g, #1E8A4C);
    font-weight: 700;
  }
  .settings-menu .sm-item svg {
    width: 18px;
    height: 18px;
  }

  /* Divider в выпадашке: визуально отделяет «Выйти» от обычных пунктов. */
  .settings-menu .sm-div {
    display: block;
    margin: 6px 4px;
  }

  /* «Выйти» виден в выпадашке (M-S2, 18.05) — раньше скрывался, но
     пользователи ожидают видеть его именно тут. Стиль кнопки уже
     задан inline (color:var(--red)), достаточно не прятать. */

  /* Backdrop удалён (M-S2-TWEAK, 18.05) — пользователь предпочёл
     более лёгкий паттерн dropdown поверх контента, без затемнения.
     Закрытие меню по клику вне него теперь через обработчик в JS. */

  /* Карточки внутри панелей: компактные отступы. */
  .settings-card {
    padding: 14px !important;
  }

  /* Заголовок панели чуть меньше — экономим место. */
  .panel-title {
    font-size: 14px;
  }

  /* Сетки полей формы внутри панелей: на мобиле 1 колонка. */
  .s-panel .form-grid2,
  .s-panel .form-grid3,
  .s-panel [style*="grid-template-columns: 1fr 1fr"],
  .s-panel [style*="grid-template-columns:1fr 1fr"] {
    display: flex !important;
    flex-direction: column !important;
    gap: 10px;
  }

  /* ═══ D: модалки → bottom-sheet на мобиле ═══
     Покрывает 3 модальные системы: .modal (основная), .mng-modal (project-detail),
     .sv-modal (emarket-saved). На мобиле модалка прилипает к низу экрана, выезжает
     снизу, во всю ширину, верхние углы скруглены, футер прилипает к низу.
     Только @media ≤640, только классы модалок — десктоп/логика/HTML не трогаются. */

  /* Оверлей: контент к низу экрана, без боковых полей */
  .modal-bg,
  .mng-modal-bg,
  .sv-modal {
    align-items: flex-end !important;
    padding: 0 !important;
  }

  /* Сам лист: во всю ширину, верхние углы, выезд снизу, ограничение высоты по dvh */
  .modal-bg .modal,
  .mng-modal-bg .mng-modal,
  .sv-modal .sv-modal-box {
    max-width: 100% !important;
    width: 100% !important;
    max-height: 92dvh !important;
    border-radius: 18px 18px 0 0 !important;
    display: flex !important;
    flex-direction: column !important;
    overflow-x: hidden !important;
  }

  /* Страховка от горизонтального «уезжания» контента внутри листа:
     ничего не должно быть шире контейнера. */
  .modal-bg .modal *,
  .mng-modal-bg .mng-modal *,
  .sv-modal .sv-modal-box * {
    max-width: 100%;
  }

  /* Жёсткая фиксация: лист и его прямые секции не скроллятся вбок,
     поля ввода тянутся по ширине, а не своей внутренней шириной. */
  .modal-bg .modal,
  .mng-modal-bg .mng-modal,
  .sv-modal .sv-modal-box,
  .modal-head, .modal-body, .modal-foot,
  .mng-head, .mng-body,
  .sv-modal-head, .sv-modal-body, .sv-modal-foot {
    overflow-x: hidden !important;
  }
  .modal-body input,
  .modal-body select,
  .modal-body textarea,
  .mng-body input,
  .mng-body select,
  .mng-body textarea,
  .sv-modal-body input,
  .sv-modal-body select,
  .sv-modal-body textarea {
    width: 100% !important;
    box-sizing: border-box !important;
    min-width: 0 !important;
  }

  /* iOS: input[type=date|time|datetime-local] имеют «родную» внутреннюю
     ширину, которую width:100% не перебивает без сброса appearance. */
  .modal-body input[type="date"],
  .modal-body input[type="time"],
  .modal-body input[type="datetime-local"],
  .mng-body input[type="date"],
  .mng-body input[type="time"],
  .mng-body input[type="datetime-local"],
  .sv-modal-body input[type="date"],
  .sv-modal-body input[type="time"],
  .sv-modal-body input[type="datetime-local"] {
    -webkit-appearance: none !important;
    appearance: none !important;
    max-width: 100% !important;
  }

  /* Ручка-полоска сверху листа (визуальный намёк «лист снизу») */
  .modal-bg .modal::before,
  .mng-modal-bg .mng-modal::before,
  .sv-modal .sv-modal-box::before {
    content: "";
    display: block;
    width: 36px;
    height: 4px;
    border-radius: 99px;
    background: var(--bdr, #DDE8E2);
    margin: 8px auto 4px;
    flex-shrink: 0;
  }

  /* Тело модалки скроллится, остальное (шапка/футер) — нет */
  .modal-body,
  .mng-body,
  .sv-modal-body {
    overflow-y: auto !important;
    flex: 1 1 auto !important;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 16px !important;
  }

  /* Футер прилипает к низу листа — кнопки «Сохранить/Отмена» всегда видны.
     Покрывает оба типа: .modal-foot (flex-архитектура) и .modal-footer (в потоке). */
  .modal-foot,
  .modal-footer,
  .sv-modal-foot {
    position: sticky !important;
    bottom: 0 !important;
    background: var(--w, #FFF) !important;
    margin-top: 0 !important;
    flex-shrink: 0 !important;
    z-index: 2;
  }

  /* Тип-2 модалки (padding+overflow на самой .modal, футер в потоке):
     даём нижний отступ, чтобы контент не прятался под прилипшим футером */
  .modal-bg .modal { padding-bottom: 0 !important; }

  /* Поля формы парами → в одну колонку (на узком экране пары жмутся) */
  .modal .form-grid2,
  .modal .form-grid3,
  .modal .mf-row,
  .modal .mf-row2,
  .modal .mf-row3,
  .mng-modal .form-grid2,
  .mng-modal .form-grid3,
  .mng-modal .mf-row,
  .mng-modal .mf-row2,
  .mng-modal .mf-row3,
  .sv-modal-box .form-grid2,
  .sv-modal-box .form-grid3,
  .sv-modal-box .mf-row,
  .sv-modal-box .mf-row2,
  .sv-modal-box .mf-row3,
  .modal [style*="grid-template-columns: 1fr 1fr"],
  .modal [style*="grid-template-columns:1fr 1fr"],
  .mng-modal [style*="grid-template-columns: 1fr 1fr"],
  .mng-modal [style*="grid-template-columns:1fr 1fr"] {
    display: flex !important;
    flex-direction: column !important;
    gap: 10px !important;
  }
}

/* ───────────────────────────────────────────────────────────────
   Э8 — Списочные страницы: toolbar в 2 строки на мобиле
   - companies.html (.toolbar + .mode-switch + .btn-create)
   - communities.html (.toolbar)
   - exhibitions.html (.ex-toolbar + .ex-tabs + .toolbar-right)
   - projects.html отложен (другой баг)
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* ─── COMPANIES (общий .toolbar) ─── */
  /* Унифицируем со страницами проектов/выставок/сообществ: column-flex,
     заголовок отдельной строкой сверху, mode-switch ниже со скроллом,
     btn-create скрыт (дублируется с FAB в топбаре). */
  .toolbar {
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: stretch;
  }
  .toolbar-title {
    align-self: flex-start;
  }
  .toolbar .mode-switch {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    flex-wrap: nowrap;
    align-self: flex-start;
  }
  .toolbar .mode-switch::-webkit-scrollbar {
    display: none;
  }
  .toolbar .mode-switch .mode-btn {
    flex-shrink: 0;
  }
  /* btn-create дублируется с m-fab-action в топбаре. Скрываем ТОЛЬКО
     когда FAB реально смонтирован (m-fab-mounted), иначе findTargetBtn
     не найдёт кнопку (offsetParent=null) и FAB вообще не появится. */
  html.m-fab-mounted .toolbar .btn-create {
    display: none;
  }

  /* ─── EXHIBITIONS (.ex-toolbar) ─── */
  /* Здесь 6 элементов: ex-title + ex-tabs + (btn-create + viewGrid + viewList + btn-add).
     2-строчный layout: title+tabs сверху, controls снизу. */
  .ex-toolbar {
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: stretch;
  }
  /* Заголовок раздела — отдельной строкой сверху. */
  .ex-title {
    align-self: flex-start;
    display: block;
  }
  /* Tabs — горизонтальный скролл. */
  .ex-tabs {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 4px;
    /* M-S1-FIX5: ограничиваем ширину родителем, иначе flex:1 из
       десктопного CSS раздувает контейнер по сумме детей. */
    width: 100%;
    min-width: 0;
    flex: 0 0 auto;
  }
  .ex-tabs::-webkit-scrollbar {
    display: none;
  }
  .ex-tabs .etab {
    flex-shrink: 0;
  }
  /* Кнопка «+ Создать выставку», «+ Заявка на стенд» и view-switch
     (grid/list) на мобиле скрыты: создание доступно через зелёный
     FAB рядом с аватаром в топбаре (m-fab-action), а list-view на
     мобиле визуально идентичен grid-view (одна колонка). */
  /* В .toolbar-right лежат переключатели вида (grid/list) И кнопка
     «Заявка на стенд» / «Создать выставку». Переключатели вида прячем
     всегда (на мобиле одна колонка), но саму кнопку НЕ прячем здесь —
     иначе FAB не найдёт её при монтировании. Кнопка скрывается ниже
     через m-fab-mounted, когда FAB уже появился. */
  .ex-toolbar .toolbar-right {
    display: flex;
    align-items: center;
    gap: 6px;
  }
  .ex-toolbar .toolbar-right .view-btn {
    display: none;
  }

  /* ─── EXHIBITIONS filter row ─── */
  /* На скрине селекты «Тематика», «Город» слишком узкие. Делаем wrap. */
  .ex-filter-row {
    flex-wrap: wrap;
    gap: 6px;
  }
}

/* ───────────────────────────────────────────────────────────────
   Э8 — Глобальная контекстная кнопка действия в топбаре на мобиле
   FAB-action инжектируется в .profile-dd-wrap (левее круглого аватара)
   и программно кликает родную кнопку страницы.
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* Зелёный круг с белым плюсом — стиль соответствует .btn-create
     на страницах (тот же фон, тень, размеры). Размер 36px = аватар. */
  .m-fab-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--g, #1E8A4C);
    border: 0;
    color: #fff;
    cursor: pointer;
    font-family: inherit;
    flex-shrink: 0;
    box-shadow: 0 2px 8px rgba(30, 138, 76, 0.22);
    transition: background 150ms ease,
                transform 120ms cubic-bezier(0.4, 0, 0.2, 1),
                box-shadow 200ms ease;
    /* Зазор между FAB и аватаром справа */
    margin-right: 8px;
  }
  .m-fab-action:active {
    transform: scale(0.92);
    background: var(--gm, #22A05A);
    box-shadow: 0 1px 4px rgba(30, 138, 76, 0.18);
  }
  .m-fab-action svg {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.6;
    stroke-linecap: round;
  }

  /* Reduce-motion для accessibility. */
  @media (prefers-reduced-motion: reduce) {
    .m-fab-action,
    .m-fab-action:active {
      transition: none;
      transform: none;
    }
  }

  /* Скрытие родных кнопок «Создать ...» на страницах — их функцию
     забрал FAB в топбаре. Скрываем ТОЛЬКО когда FAB реально работает,
     иначе пользователь окажется без точки действия.
     mobile-injector.js ставит класс .m-fab-mounted на <html> когда
     FAB успешно прицепился к рабочей кнопке. */

  /* Скрытие родных кнопок «Создать ...» на всех 8 списочных страницах.
     Используем descendant-selector (без `>`) на случай если кнопка
     лежит в дополнительной обёртке внутри toolbar. */
  html.m-fab-mounted .toolbar .btn-create,
  html.m-fab-mounted .toolbar a.btn-create,
  html.m-fab-mounted .ev-toolbar .btn-create,
  html.m-fab-mounted .proj-toolbar .btn-create,
  html.m-fab-mounted .forum-toolbar .btn-create,
  html.m-fab-mounted .comm-toolbar .btn-create,
  html.m-fab-mounted .cat-toolbar .btn-create {
    display: none;
  }
  /* Jobs — отдельный класс .btn-create-job */
  html.m-fab-mounted .jobs-toolbar .btn-create-job {
    display: none;
  }
  /* Exhibitions — .btn-add (Заявка на стенд) + (опц.) #btnCreateExhibition */
  html.m-fab-mounted .ex-toolbar .btn-add,
  html.m-fab-mounted .ex-toolbar #btnCreateExhibition {
    display: none;
  }
  /* Dashboard (Новости) — кнопка «+ Написать» с уникальным классом */
  html.m-fab-mounted .news-toolbar .btn-write {
    display: none;
  }
}

/* ───────────────────────────────────────────────────────────────
   Э10 — Чат (/chat.html) на мобиле
   Двухэкранный iOS-паттерн: список диалогов и открытый чат как
   отдельные view, переключаются классами на .chat-panel.
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* Сначала ПЕРЕОПРЕДЕЛЯЕМ inline-правило chat.html строка 717:
     `.chat-panel{grid-template-columns:1fr} .dialogs{display:none}`
     на ≤740. Возвращаем диалоги в DOM, делаем chat-panel flex-row.
     Высоту берём от .main напрямую через flex:1 (родитель .main —
     flex-column через shell-layout). Это надёжнее чем height:100%
     через цепочку: shell → main → chat-panel → chat. */
  html.lt-shell-2col .chat-panel {
    display: flex !important;
    flex-direction: row !important;
    grid-template-columns: none !important;
    width: 100%;
    flex: 1 1 0;
    min-height: 0;
    overflow: hidden;
  }

  /* Возвращаем dialogs в видимость, делаем full-width на всю высоту. */
  html.lt-shell-2col .dialogs {
    display: flex !important;
    flex-direction: column;
    flex: 0 0 100%;
    width: 100%;
    height: 100%;
    min-height: 100%;
    align-self: stretch;
    border-right: 0;
  }

  /* Чат — full-width, по умолчанию скрыт.
     В flex-row контейнере align-items по умолчанию stretch — но это
     даёт высоту равную самому высокому элементу. Если .dialogs выше
     или короче — .chat встаёт по нему. Поэтому фиксируем height:100%
     явно + min-height чтобы не сжимался. */
  html.lt-shell-2col .chat-panel .chat {
    flex: 0 0 100%;
    width: 100%;
    height: 100%;
    min-height: 100%;
    min-width: 0;
    align-self: stretch;
  }

  /* Кнопка-крестик закрытия диалога — только для десктопа; на мобилке есть свой возврат к списку */
  html.lt-shell #chatCloseBtn,
  html.lt-shell-2col #chatCloseBtn {
    display: none !important;
  }

  /* ─── ДЕФОЛТНОЕ СОСТОЯНИЕ: показываем диалоги ─── */
  /* Когда mobile-injector ставит .m-show-dialogs (по умолчанию) —
     диалоги видны, чат уезжает за правый край. */
  .chat-panel.m-show-dialogs .dialogs {
    transform: translateX(0);
  }
  .chat-panel.m-show-dialogs .chat {
    transform: translateX(100%);
    /* После анимации убираем из layout flow чтобы не было пустого скролла. */
    pointer-events: none;
  }

  /* ─── СОСТОЯНИЕ «открыт чат»: показываем чат, диалоги уехали влево ─── */
  .chat-panel.m-show-chat .dialogs {
    transform: translateX(-100%);
    pointer-events: none;
  }
  .chat-panel.m-show-chat .chat {
    transform: translateX(-100%);
    pointer-events: auto;
  }

  /* Плавный переход. */
  html.lt-shell-2col .chat-panel .dialogs,
  html.lt-shell-2col .chat-panel .chat {
    transition: transform 280ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  @media (prefers-reduced-motion: reduce) {
    html.lt-shell-2col .chat-panel .dialogs,
    html.lt-shell-2col .chat-panel .chat {
      transition: none;
    }
  }

  /* ─── КНОПКА «Назад» в хедере чата ─── */
  /* Инжектится через mobile-injector.js левее аватара собеседника. */
  .m-chat-back {
    width: 32px;
    height: 32px;
    border-radius: 8px;
    background: var(--gp, #F0FAF4);
    border: 1.5px solid var(--bdr, #DDE8E2);
    color: var(--g, #1E8A4C);
    display: grid;
    place-items: center;
    cursor: pointer;
    flex-shrink: 0;
    margin-right: 8px;
    font-family: inherit;
    transition: background 150ms ease, transform 120ms ease;
  }
  .m-chat-back:active {
    background: var(--gl, #E8F5EE);
    transform: scale(0.94);
  }
  .m-chat-back svg {
    width: 16px;
    height: 16px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.2;
    stroke-linecap: round;
    stroke-linejoin: round;
  }

  /* ─── Скрываем bottom-nav в режиме открытого чата ─── */
  /* На экране переписки нижняя навигация мешает (input для сообщений
     должен быть у самого низа). Возвращаем bottom-nav на экране списка. */
  .chat-panel.m-show-chat ~ #mobileBottomNav,
  body:has(.chat-panel.m-show-chat) #mobileBottomNav {
    display: none;
  }

  /* ─── На /chat.html шелл должен занимать всю высоту ─── */
  /* Чтобы переписка занимала весь экран без скролла страницы. */
  html.lt-shell-2col body {
    overflow: hidden;
  }

  /* ─── iOS Safari address bar fix ─── */
  /* 100vh на iOS включает address bar, поэтому реальная высота больше
     экрана и контент уезжает вверх. dvh (dynamic viewport height) даёт
     актуальную высоту с учётом текущего состояния address bar.
     Поддержка: iOS Safari 15.4+, актуально для всех наших пользователей. */
  html.lt-shell,
  html.lt-shell body,
  html.lt-shell-2col,
  html.lt-shell-2col body {
    height: 100dvh;
    min-height: 100dvh;
  }
  html.lt-shell .shell,
  html.lt-shell-2col .shell {
    height: 100dvh;
  }

  /* ─── РЕЖИМ ОТКРЫТОГО ЧАТА: спрятать всё кроме переписки ─── */
  /* Мессенджер-паттерн как Telegram: на экране переписки скрываем
     топбар платформы, логотип. Видны только: шапка чата + переписка +
     input. Кнопка ◀ Назад в шапке возвращает к списку диалогов
     (там топбар снова виден). */
  body:has(.chat-panel.m-show-chat) .topbar,
  body:has(.chat-panel.m-show-chat) .logo-cell {
    display: none;
  }
  /* Когда скрыли топбар — шелл становится grid в одну строку,
     чат занимает всю высоту экрана. */
  body:has(.chat-panel.m-show-chat) .shell {
    grid-template-rows: 1fr;
    grid-template-areas: "main";
  }
  body:has(.chat-panel.m-show-chat) .nav {
    display: none;
  }

  /* В режиме открытого чата bottom-nav скрыт, поэтому компенсационный
     padding-bottom из Э1 фундамента (calc + m-bn-height + safe-area)
     создаёт пустую полосу ~76px под input для сообщений. Сбрасываем.
     Также убираем overflow-y:auto — внутри chat сам управляет скроллом
     (chat-body имеет свой overflow-y). */
  body:has(.chat-panel.m-show-chat) .main {
    padding-bottom: 0 !important;
    padding-top: 0 !important;
    overflow: hidden !important;
  }

  /* ─── .ch-actions: дать сжиматься на узком экране ─── */
  /* На мобиле в шапке чата много кнопок (поиск/звонок/видео/«В друзьях»),
     они не помещаются в строке вместе с именем. Поэтому
     ch-actions может сжиматься, а малозначительные кнопки скрываем. */
  .chat-head .ch-actions {
    flex-shrink: 1;
    min-width: 0;
    gap: 4px;
  }
  /* Кнопка «В друзьях» — дубль функционала /profile_user, на узком
     экране только мешает. Скрываем на мобиле. */
  .chat-head .ch-actions .chat-friend-btn {
    display: none !important;
  }
  /* Кнопки «Аудиозвонок» и «Видеозвонок» — пока заглушки
     (показывают тост «будут доступны в следующей версии»),
     на мобиле тоже не нужны. */
  .chat-head .ch-actions .ch-act[title*="удиозвон"],
  .chat-head .ch-actions .ch-act[title*="идеозвон"] {
    display: none;
  }

  /* ─── Имя в шапке чата — отдать ему всё доступное место ─── */
  .chat-head .ch-info {
    flex: 1;
    min-width: 0;
  }
  .chat-head .ch-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* ─── Чтобы input для сообщений был у самого низа экрана ─── */
  /* В режиме открытого чата bottom-nav скрыт, шелл grid-template-areas
     стал "main" — chat-panel занимает всё. chat внутри — flex column,
     ch-input-wrap снизу естественно. Добавляем safe-area-inset для
     iPhone X+ (notch снизу). */
  body:has(.chat-panel.m-show-chat) .chat-input-wrap {
    padding-bottom: max(12px, env(safe-area-inset-bottom));
  }

  /* ─── Э10.7: голосовые сообщения .msg-voice на мобиле ───
     Десктопное правило: min-width:220px, max-width:280px. На узком
     мобиле родитель .msg.them/me ограничен 70% ширины .chat-body
     (~250px), и плеер вылазит за рамки.
     Сбрасываем min-width и max-width:100%, дополнительно ужимаем
     внутренний padding и gap для компактности. */
  .msg-voice {
    min-width: 0 !important;
    max-width: 100% !important;
    padding: 6px 10px;
    gap: 8px;
  }
  /* Кнопка play — чуть меньше (36→32). */
  .msg-voice-play {
    width: 32px;
    height: 32px;
  }
  /* Аватар + контент: бывают сценарии когда даже после сжатия плеера
     общий .msg всё ещё узкий. Разрешаем сообщению с голосовым растянуться
     чуть шире обычных текстовых (max-width:85% вместо 70%). */
  .msg:has(.msg-voice) {
    max-width: 85%;
  }
}

/* ───────────────────────────────────────────────────────────────
   Э12 — Страницы входа и регистрации (/login.html, /register.html)
   - Убрать горизонтальный скролл (не свайпать в сторону)
   - Капча переносится корректно (не выходит за границы)
   - .auth-card без min-height — нет пустоты под короткой формой
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* Запрещаем горизонтальный скролл на гостевых auth-страницах.
     На обычных страницах с .shell этот скролл и так не возникает
     (overflow:hidden на body), но login.html и register.html имеют
     свою верстку с .page (min-height:100vh, flex center) — там нужно
     явно. */
  html.lt-shell body:has(.page > .auth-card) {
    overflow-x: hidden;
  }
  html.lt-shell .page {
    /* На мобиле padding 20px по сторонам сжимает форму и подталкивает
       контент за края. Уменьшаем. */
    padding: 12px;
    max-width: 100vw;
    overflow-x: hidden;
  }

  /* .auth-card на мобиле — без жёсткого min-height. Десктопное правило
     min-height:600px центрирует карточку красиво, но на мобиле создаёт
     пустую область под короткой формой. */
  html.lt-shell .auth-card {
    min-height: 0;
    max-width: 100%;
  }

  /* .auth-form padding — ещё компактнее на узком экране (320px). */
  html.lt-shell .auth-form {
    padding: 24px 18px;
  }

  /* ─── КАПЧА ─── */
  /* .captcha-row на десктопе — flex row с детьми quote + input + check + reload.
     На узком экране (320-390px) сумма ширин превышает контейнер
     → элементы вылезают за границу .captcha-wrap.
     
     Делаем wrap, уменьшаем gap, разрешаем quote-блоку сжиматься. */
  html.lt-shell .captcha-row {
    flex-wrap: wrap;
    gap: 8px;
  }
  /* Quote-блок (например "3 + 7 = ?") — может сжиматься, но не меньше
     своего content. flex-shrink:1 разрешает усадку, min-width:0 ломает
     дефолтное «не сжиматься» поведение. */
  html.lt-shell .captcha-q {
    flex-shrink: 1;
    min-width: 0;
    padding: 7px 12px;
  }
  /* Input — на всю ширину если переносится на новую строку. */
  html.lt-shell .captcha-input {
    flex: 1 1 140px;
    min-width: 0;
  }
  /* Reload-кнопка остаётся фикс-размером (32px). */
  html.lt-shell .captcha-reload {
    flex-shrink: 0;
  }

  /* ─── ОБЩИЕ ФОРМЫ ─── */
  /* Любой input/textarea в auth-форме — max-width 100% чтобы не вылез
     за родительский контейнер из-за внутреннего min-width браузера. */
  html.lt-shell .auth-form input,
  html.lt-shell .auth-form textarea,
  html.lt-shell .auth-form select {
    max-width: 100%;
    box-sizing: border-box;
  }
}

/* ───────────────────────────────────────────────────────────────
   Э14 — Страница /friends.html
   - .tabs-bar горизонтальный скролл работает корректно
   - .friends-grid одна колонка
   - .add-card компактный padding
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* .tabs-bar — overflow-x:auto уже есть в inline-стилях, но без
     дополнительных правил он не работает: max-width не задан, дети
     с flex-shrink:0 переполняют родителя, и весь shell начинает
     свайпаться вбок. Принудительно ограничиваем по ширине и
     скрываем scrollbar для нативного iOS-feel. */
  html.lt-shell-2col .main > .tabs-bar,
  html.lt-shell .main > .tabs-bar {
    max-width: 100%;
    width: 100%;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  html.lt-shell-2col .main > .tabs-bar::-webkit-scrollbar,
  html.lt-shell .main > .tabs-bar::-webkit-scrollbar {
    display: none;
  }

  /* .friends-grid: десктоп использует auto-fill minmax(220px,1fr), что
     на 390px экране даёт 1 колонку но иногда переполняется из-за gap
     или padding'ов карточек. Принудительно ровно одна колонка. */
  html.lt-shell-2col .friends-grid,
  html.lt-shell .friends-grid {
    grid-template-columns: 1fr !important;
  }

  /* .add-card padding 18px 22px → 14px 16px на мобиле. */
  html.lt-shell-2col .add-card,
  html.lt-shell .add-card {
    padding: 14px 16px;
  }

  /* Хлебные крошки могут переноситься на 2 строки — это норма, не трогаем. */
}

/* Следующие этапы добавляют сюда PWA и т.д. */

/* ───────────────────────────────────────────────────────────────
   M-S1 (18.05) — глобальная защита от horizontal overflow
   ─────────────────────────────────────────────────────────────── */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {

  /* ════════════════════════════════════════════════════════════════
     M-S1 (18.05): глобальная защита от horizontal overflow.

     Семь страниц на мобилке имели общий баг — тулбары/строки с
     display:flex + flex-shrink:0 не помещались в viewport и
     выпирали за край. Чтобы не патчить каждую страницу отдельно
     (их классы все разные: ex-toolbar, comm-toolbar, news-sort-row,
     compose-actions, s-sort-row, t-quickadd-hint), используем
     двухуровневую защиту.

     Уровень 1: корневая страховка. body и .main с overflow-x:hidden
     и max-width:100vw гарантируют, что никакая часть страницы не
     может «вылететь» за viewport, даже если мы пропустим какой-то
     внутренний контейнер.

     Уровень 2: точечные правила для проблемных тулбаров, чтобы
     контент не просто обрезался, а корректно переносился на
     новую строку. ════════════════════════════════════════════════ */
  html,
  body {
    overflow-x: hidden;
    max-width: 100vw;
  }
  .main {
    overflow-x: hidden;
    max-width: 100%;
  }

  /* M3 — communities: .comm-toolbar содержит title + 2x mode-switch +
     comm-tabs + btn-create. На мобиле перестраиваем в column-flex,
     каждая логическая зона на своей строке. mode-switch и comm-tabs
     скроллятся горизонтально, если не помещаются. */
  .comm-toolbar {
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: stretch;
  }
  /* Заголовок раздела — отдельной строкой сверху. */
  .comm-title {
    align-self: flex-start;
    display: block;
  }
  /* mode-switch не нуждается в overflow — кнопки короткие, помещаются
     всегда. justify-content:flex-start чтобы прижать к левому краю
     и убрать «прозрачное поле» справа от скроллбара. */
  .comm-toolbar .mode-switch {
    flex-wrap: nowrap;
    justify-content: flex-start;
    align-self: flex-start;
  }
  .comm-toolbar .mode-switch .mode-btn {
    flex-shrink: 0;
  }
  .comm-tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    flex-wrap: nowrap;
    width: 100%;
    min-width: 0;
    flex: 0 0 auto;
  }
  .comm-tabs::-webkit-scrollbar {
    display: none;
  }
  .comm-tabs .ctab {
    flex-shrink: 0;
  }
  /* Кнопка «+ Создать сообщество» дублируется с FAB в топбаре — скрываем.
     Селектор: последний div внутри .comm-toolbar (там обёрнут btn-create). */
  .comm-toolbar > div:last-child:has(.btn-create) {
    display: none;
  }

  /* M4 — exhibitions: .ex-toolbar layout уже есть в блоке выше
     ("EXHIBITIONS .ex-toolbar") — flex-direction:column, ex-tabs
     с overflow-x:auto. Старый M-S1 случайно добавил конфликтующий
     flex-wrap — он удалён. */

  /* (Новое) Проекты: .proj-toolbar по структуре идентичен ex-toolbar
     (title + tabs + toolbar-right с view-switch и btn-create), но
     раньше адаптации для мобилки не было. Применяем тот же
     column-flex паттерн. */
  .proj-toolbar {
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: stretch;
  }
  /* Заголовок раздела — отдельной строкой сверху, не inline с табами,
     чтобы не пересекался с другими элементами тулбара. */
  .proj-title {
    align-self: flex-start;
    display: block;
  }
  .proj-tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    flex-wrap: nowrap;
    /* M-S1-FIX5: ограничиваем ширину родителем, иначе flex:1 из
       десктопного CSS раздувает контейнер по сумме детей. */
    width: 100%;
    min-width: 0;
    flex: 0 0 auto;
  }
  .proj-tabs::-webkit-scrollbar {
    display: none;
  }
  .proj-tabs .ptab {
    flex-shrink: 0;
  }
  /* Кнопка «+ Создать проект» и view-switch (grid/list) на мобиле скрыты:
     создание доступно через зелёный FAB рядом с аватаром в топбаре
     (m-fab-action), а list-view на мобиле визуально идентичен grid-view. */
  .proj-toolbar .toolbar-right {
    display: flex;
    align-items: center;
    gap: 6px;
  }
  .proj-toolbar .toolbar-right .view-btn {
    display: none;
  }

  /* M7 — tasks: .t-quickadd (label + input + hint). На мобиле hint
     уходит на новую строку под input. */
  .t-quickadd {
    flex-wrap: wrap;
  }
  .t-quickadd-hint {
    width: 100%;
    margin-top: 4px;
  }

  /* M8 — search: .s-sort-row (Сортировка: + 3 кнопки). */
  .s-sort-row {
    flex-wrap: wrap;
  }

  /* M11 — login: SmartCaptcha — 320px iframe, нельзя сжать.
     Даём horizontal scroll внутри обёртки. */
  .captcha-wrap {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .captcha-wrap::-webkit-scrollbar {
    display: none;
  }

  /* M12 — dashboard: .news-sort-row (Новые/Популярные/Обсуждаемые). */
  .news-sort-row {
    flex-wrap: wrap;
  }

  /* M13 — dashboard: .compose-actions (Фото/Тег/Отмена/Опубликовать). */
  .compose-actions {
    flex-wrap: wrap;
    gap: 6px;
  }

  /* ════════════════════════════════════════════════════════════════
     M-S1-FIX4 (18.05): универсальный горизонтальный скролл для любых
     тулбаров/табов/фильтр-строк на мобиле. Раньше каждый класс лечился
     точечно — теперь одно правило покрывает зоопарк типовых имён:
     *-toolbar, *-tabs, *-filter-row, *-sort-row, плюс именованные
     .mode-switch, .cat-chips, .filter-row, .filters.

     Логика: если контейнер построен на display:flex и не помещается
     по ширине, его содержимое скроллится горизонтально по свайпу.
     Скроллбар скрыт (паттерн iOS), детям задаём flex-shrink:0 чтобы
     они не сжимались до нечитаемых размеров.

     Конкретные точечные блоки выше (.proj-tabs, .comm-tabs, .ex-tabs)
     остаются — они задают тот же overflow-x:auto и просто согласуются
     с этим общим правилом. ═══════════════════════════════════════ */
  [class*="-toolbar"],
  [class*="-tabs"],
  [class*="-filter-row"],
  [class*="-sort-row"],
  .mode-switch,
  .cat-chips,
  .filter-row,
  .filters {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  [class*="-toolbar"]::-webkit-scrollbar,
  [class*="-tabs"]::-webkit-scrollbar,
  [class*="-filter-row"]::-webkit-scrollbar,
  [class*="-sort-row"]::-webkit-scrollbar,
  .mode-switch::-webkit-scrollbar,
  .cat-chips::-webkit-scrollbar,
  .filter-row::-webkit-scrollbar,
  .filters::-webkit-scrollbar {
    display: none;
  }
  /* Дети флекс-контейнеров не должны сжиматься меньше своего
     контента, иначе чипы превратятся в обрезанные «кв...» вместо скролла. */
  [class*="-tabs"] > *,
  [class*="-filter-row"] > *,
  [class*="-sort-row"] > *,
  .mode-switch > *,
  .cat-chips > *,
  .filter-row > *,
  .filters > * {
    flex-shrink: 0;
  }

  /* Исключение: тулбары которые мы намеренно построили в column-flex
     (.proj-toolbar, .ex-toolbar, .comm-toolbar, .toolbar) — у них
     overflow-x должен быть hidden, а скроллятся внутренние табы/
     mode-switch. Иначе колонка сама пытается скроллиться, что
     ломает layout. */
  .proj-toolbar,
  .ex-toolbar,
  .comm-toolbar,
  .toolbar {
    overflow-x: hidden;
  }

  /* M-S3 (18.05): на узких экранах карточки событий могут не вмещать
     длинные заголовки в 2 строки. Увеличиваем до 3, добавляем
     word-break чтобы дефисы и цифры переносились правильно. */
  .ev-card .ev-title {
    -webkit-line-clamp: 3;
    word-break: break-word;
  }

  /* M-S3-CAL (18.05): в режиме «Неделя» календаря (.cal-time-days.week)
     колонка дня всего ~60-70px шириной — название события физически
     не вмещается и обрезается до «3...» без смысла. Скрываем title,
     оставляем только время крупно. Название читается по тапу в детальке.
     В режиме «День» (одна колонка на весь экран) title остаётся видимым. */
  .cal-time-days.week .cal-time-event-title {
    display: none;
  }
  .cal-time-days.week .cal-time-event {
    padding: 2px 3px;
    border-left-width: 2px;
  }
  .cal-time-days.week .cal-time-event-time {
    font-size: 10px;
  }
}

/* ═══ B-ADMIN-MOBILE (1): каркас + overview + detail-panel ═══ */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  /* overview-сетка карточек: 4 кол → 2 */
  html.lt-shell .ov-grid,
  html.lt-shell-2col .ov-grid {
    grid-template-columns: 1fr 1fr;
    gap: 8px;
  }
  /* вкладки админки — компактнее, горизонтальный скролл уже есть */
  html.lt-shell .admin-tabs,
  html.lt-shell-2col .admin-tabs {
    padding: 4px;
    border-radius: 14px;
  }
  html.lt-shell .admin-tab,
  html.lt-shell-2col .admin-tab {
    padding: 8px 11px;
    font-size: 12px;
  }
  /* выезжающая detail-панель — на весь экран */
  html.lt-shell .detail-panel,
  html.lt-shell-2col .detail-panel {
    width: 100vw;
    right: -100vw;
  }
  html.lt-shell .detail-panel.open,
  html.lt-shell-2col .detail-panel.open {
    right: 0;
  }

  /* ── B-ADMIN-MOBILE (3): audit + sanctions → карточки ── */
  html.lt-shell .audit-thead,
  html.lt-shell .sanct-thead,
  html.lt-shell-2col .audit-thead,
  html.lt-shell-2col .sanct-thead {
    display: none !important;
  }
  html.lt-shell .audit-row,
  html.lt-shell .sanct-row,
  html.lt-shell-2col .audit-row,
  html.lt-shell-2col .sanct-row {
    display: flex !important;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    grid-template-columns: none !important;
    padding: 12px 14px;
    font-size: 12px;
  }
  /* sanct: аватар не сжимается */
  html.lt-shell .sanct-row .u-av,
  html.lt-shell-2col .sanct-row .u-av {
    flex-shrink: 0;
  }
  /* блоки внутри строк переносятся, текст не обрезается жёстко */
  html.lt-shell .audit-row > div,
  html.lt-shell .sanct-row > div,
  html.lt-shell-2col .audit-row > div,
  html.lt-shell-2col .sanct-row > div {
    white-space: normal;
    word-break: break-word;
    min-width: 0;
  }
  /* во вторых колонках (основной контент) — растягиваем на ширину */
  html.lt-shell .audit-row > div:nth-child(2),
  html.lt-shell .sanct-row > div:nth-child(2),
  html.lt-shell-2col .audit-row > div:nth-child(2),
  html.lt-shell-2col .sanct-row > div:nth-child(2) {
    flex: 1 1 100%;
  }
  /* ── B-ADMIN-MOBILE (2): таблицы → карточки ── */
  /* шапка таблицы не нужна на мобилке */
  html.lt-shell .users-thead,
  html.lt-shell-2col .users-thead {
    display: none !important;
  }
  /* строку-грид → гибкая карточка с переносом */
  html.lt-shell .users-row,
  html.lt-shell-2col .users-row {
    display: flex !important;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    grid-template-columns: none !important;
    padding: 12px 14px;
  }
  /* аватар не сжимается */
  html.lt-shell .users-row .u-av,
  html.lt-shell-2col .users-row .u-av {
    flex-shrink: 0;
  }
  /* блок имя+подзаголовок занимает основную ширину */
  html.lt-shell .users-row > div:nth-child(3),
  html.lt-shell-2col .users-row > div:nth-child(3) {
    flex: 1;
    min-width: 0;
  }
  /* имя/email/дата — переносятся, не обрезаются жёстко в одну строку */
  html.lt-shell .users-row .u-name,
  html.lt-shell .users-row .u-pos,
  html.lt-shell .users-row .u-email,
  html.lt-shell-2col .users-row .u-name,
  html.lt-shell-2col .users-row .u-pos,
  html.lt-shell-2col .users-row .u-email {
    white-space: normal;
    word-break: break-word;
  }
  /* email и дата — на всю ширину под именем (перенос) */
  html.lt-shell .users-row .u-email,
  html.lt-shell .users-row .u-date,
  html.lt-shell-2col .users-row .u-email,
  html.lt-shell-2col .users-row .u-date {
    flex-basis: 100%;
    font-size: 12px;
  }
  /* скрыть колонку-стрелку "→" (последний div) — на мобилке тап по всей карточке */
  html.lt-shell .users-row > div:last-child,
  html.lt-shell-2col .users-row > div:last-child {
    display: none;
  }

  /* ── B-ADMIN-MOBILE (4): воронка + словари ── */
  /* колонки воронки уже flex:0 0 220px + скролл — сужаем для мобилки */
  html.lt-shell #funnelBoard > div,
  html.lt-shell-2col #funnelBoard > div {
    flex: 0 0 78vw !important;
    max-width: 300px;
  }
  /* словари: грид-строку → карточка с переносом */
  html.lt-shell .dict-row,
  html.lt-shell-2col .dict-row {
    display: flex !important;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 10px;
    grid-template-columns: none !important;
    padding: 12px 14px;
  }
  html.lt-shell .dict-row > div:first-child,
  html.lt-shell-2col .dict-row > div:first-child {
    flex: 1 1 60%;
    min-width: 0;
  }
  html.lt-shell .dict-row .u-name,
  html.lt-shell .dict-row .u-pos,
  html.lt-shell-2col .dict-row .u-name,
  html.lt-shell-2col .dict-row .u-pos {
    white-space: normal;
    word-break: break-word;
  }
  /* блок кнопок действий — на всю ширину под контентом */
  html.lt-shell .dict-row > div:last-child,
  html.lt-shell-2col .dict-row > div:last-child {
    flex-basis: 100%;
    justify-content: flex-start !important;
  }
}


/* ═══ Пласт B: действия деталки — кнопка ⋯ в топбаре + bottom-sheet ═══
   Кнопка-триггер согласована с FAB (m-fab-action). Лист действий выезжает
   снизу (та же механика, что модалки D). Только @media ≤640. */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  .m-da-trigger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--gp, #F0FAF4);
    border: 1.5px solid var(--bdr, #DDE8E2);
    color: var(--g, #1E8A4C);
    cursor: pointer;
    font-family: inherit;
    flex-shrink: 0;
    margin-right: 8px;
    transition: background 150ms ease, transform 120ms cubic-bezier(0.4, 0, 0.2, 1);
  }
  .m-da-trigger:active {
    transform: scale(0.92);
    background: var(--gl, #E8F5EE);
  }
  .m-da-trigger svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
  }

  .m-da-overlay {
    position: fixed;
    inset: 0;
    background: rgba(15, 25, 18, 0.45);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    z-index: 1000;
    display: flex;
    align-items: flex-end;
    opacity: 0;
    pointer-events: none;
    transition: opacity 200ms ease;
  }
  .m-da-overlay.m-open {
    opacity: 1;
    pointer-events: auto;
  }
  .m-da-sheet {
    width: 100%;
    max-width: 100%;
    background: var(--w, #fff);
    border-radius: 18px 18px 0 0;
    padding: 8px 14px calc(16px + env(safe-area-inset-bottom, 0px));
    box-shadow: 0 -8px 30px rgba(15, 25, 18, 0.18);
    transform: translateY(100%);
    transition: transform 260ms cubic-bezier(0.32, 0.72, 0, 1);
    max-height: 80dvh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  .m-da-overlay.m-open .m-da-sheet {
    transform: translateY(0);
  }
  .m-da-handle {
    width: 38px;
    height: 4px;
    border-radius: 99px;
    background: var(--bdr, #DDE8E2);
    margin: 4px auto 10px;
  }
  .m-da-title {
    font-size: 12px;
    font-weight: 800;
    color: var(--gmt, #5A8A6A);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    padding: 0 6px 8px;
  }
  .m-da-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .m-da-item {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 13px 12px;
    border: none;
    background: transparent;
    border-radius: 12px;
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    color: var(--t, #1A2A22);
    cursor: pointer;
    text-align: left;
    transition: background 120ms ease;
  }
  .m-da-item:active {
    background: var(--gp, #F0FAF4);
  }
  .m-da-item svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: var(--g, #1E8A4C);
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
  }
  .m-da-item.m-da-danger {
    color: var(--red, #E04040);
  }
  .m-da-item.m-da-danger svg {
    stroke: var(--red, #E04040);
  }

  /* Вкладки Действия / Подробнее */
  .m-da-tabs {
    display: flex;
    gap: 4px;
    background: var(--gp, #F0FAF4);
    border: 1px solid var(--bdr, #DDE8E2);
    border-radius: 12px;
    padding: 3px;
    margin: 0 6px 12px;
  }
  .m-da-tab {
    flex: 1;
    padding: 9px 10px;
    border: none;
    background: transparent;
    border-radius: 9px;
    font-family: inherit;
    font-size: 14px;
    font-weight: 700;
    color: var(--gmt, #5A8A6A);
    cursor: pointer;
    transition: background 120ms ease, color 120ms ease;
  }
  .m-da-tab.m-active {
    background: var(--w, #fff);
    color: var(--g, #1E8A4C);
    box-shadow: 0 1px 6px rgba(30, 138, 76, 0.10);
  }
  .m-da-body {
    min-height: 60px;
  }
  .m-da-empty {
    text-align: center;
    color: var(--gmt, #5A8A6A);
    font-size: 14px;
    padding: 24px 12px;
  }
  /* Клон инфо-карточек сайдбара во вкладке «Подробнее» */
  .m-da-info {
    display: flex;
    flex-direction: column;
    gap: 10px;
  }
  .m-da-info .card {
    display: block !important;
    background: var(--gp, #F0FAF4);
    border: 1px solid var(--bdr, #DDE8E2);
    border-radius: 14px;
    padding: 14px;
    margin: 0;
  }
  .m-da-info .block-title {
    font-size: 11px;
    font-weight: 800;
    color: var(--gmt, #5A8A6A);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 10px;
  }

  @media (prefers-reduced-motion: reduce) {
    .m-da-overlay, .m-da-sheet, .m-da-trigger {
      transition: none;
    }
  }
}


   Таргет — именно тач (hover:none + pointer:coarse), чтобы десктоп с узким окном
   не пострадал. Покрывает opacity:0-паттерны (display:none-поповер чата — отдельно, tap-reveal). */
@media (hover: none) and (pointer: coarse) {
  .t-actions { opacity: 1 !important; }
  .disc-msg-actions { opacity: 1 !important; }
  .subtask-delete { opacity: 1 !important; }
  .photo-thumb .photo-remove { opacity: 1 !important; }

  /* C2: действия сообщения в чате — поповер (display:none → flex на hover).
     На тач hover нет, показываем по тапу: injector вешает .m-tap на пузырь.
     Только активный пузырь показывает действия — иначе поповеры наложатся. */
  .msg-bubble.m-tap .msg-actions { display: flex !important; }
}


/* ═══════════════════════════════════════════════════════════════
   ПЛАСТ E — Таблицы и графики на мобиле (analytics / emarket)
   ───────────────────────────────────────────────────────────────
   Широкие таблицы (.an-table / .wms-tbl / .dp-table) на узком
   экране выходят за вьюпорт. Делаем сами таблицы горизонтально
   прокручиваемыми (display:block + overflow-x), не трогая HTML.
   Графики (.chart-box) — резиновая высота поменьше.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  /* Таблицы: горизонтальный скролл внутри своей области.
     display:block нужен, чтобы overflow-x сработал на <table>. */
  .an-table,
  .wms-tbl,
  .dp-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
    max-width: 100%;
  }
  /* Тонкий скроллбар, чтобы не съедал высоту */
  .an-table::-webkit-scrollbar,
  .wms-tbl::-webkit-scrollbar,
  .dp-table::-webkit-scrollbar {
    height: 4px;
  }
  .an-table::-webkit-scrollbar-thumb,
  .wms-tbl::-webkit-scrollbar-thumb,
  .dp-table::-webkit-scrollbar-thumb {
    background: var(--gb, #C0DECA);
    border-radius: 99px;
  }
  /* Графики: чуть ниже, чтобы не занимали пол-экрана на телефоне */
  .chart-box {
    height: 200px;
  }
  .chart-box.chart-tall {
    height: 240px;
  }
}

/* ═══════════════════════════════════════════════════════════════
   A1 — Тост injector (мобильные уведомления)
   ───────────────────────────────────────────────────────────────
   Тёмная плашка снизу по центру (стиль .toast платформы), но поднята
   над bottom-nav. Самодостаточный — рисуется из mobile-injector.js.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  .m-toast {
    position: fixed;
    left: 50%;
    bottom: calc(var(--m-bn-height, 60px) + var(--m-safe-bottom, 0px) + 16px);
    transform: translateX(-50%) translateY(16px);
    max-width: calc(100vw - 32px);
    background: #1A2A22;
    color: #fff;
    padding: 11px 18px;
    border-radius: 12px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.35;
    text-align: center;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.28);
    z-index: 9999;
    opacity: 0;
    transition: opacity .25s ease, transform .25s ease;
    pointer-events: none;
  }
  .m-toast.m-toast-show {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
  }
}

/* ═══════════════════════════════════════════════════════════════
   A2 — E-market витрина (emarket.html)
   ───────────────────────────────────────────────────────────────
   У страницы нет своего мобильного @media. Глобальный шелл + flex-wrap
   уже дают рабочую раскладку. Здесь — два улучшения под покупателя:
   1) карточки товаров/услуг в 2 колонки (стандарт маркетплейсов —
      обзорнее, чем одна гигантская колонка);
   2) карусель-баннер повыше (на узком экране aspect 6/1 = тонкая
      полоска, реклама нечитаема → делаем 2.5/1).
   Только классы витрины, HTML не тронут.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  /* Карточки в 2 колонки (товары, услуги, featured) */
  .em-grid,
  .em-featured-scroll {
    grid-template-columns: 1fr 1fr;
    gap: 10px;
  }
  /* Компактнее под узкую карточку: паддинги/шрифты */
  .em-feedwrap {
    padding: 10px;
  }
  .em-card-body {
    padding: 10px 11px;
    gap: 4px;
  }
  .em-card-title {
    font-size: 13px;
  }
  .em-card-price {
    font-size: 14px;
  }
  /* Карусель-баннер: выше, чтобы реклама читалась на телефоне */
  .em-carousel {
    aspect-ratio: 2.5 / 1;
  }

  /* Селекторы магазинов (вкладка «Магазины»): на десктопе min-width:170px,
     два в ряд не влезают на телефон → режутся. Делаем резиновыми: два
     в ряд по половине ширины. Контейнер уже flex-wrap. */
  .em-shop-filters {
    width: 100%;
    gap: 8px;
  }
  .em-shop-filters .em-fselect.lt-sel-wrap {
    flex: 1 1 0;
    min-width: 0;
  }
  .em-shop-filters .em-fselect.lt-sel-wrap .lt-sel-btn {
    min-width: 0;
    width: 100%;
  }
  /* Фильтры в панели (Регион/Категория) — тоже без жёсткого min-width */
  .em-fgroup {
    flex: 1 1 140px;
    min-width: 0;
  }
  .em-fgroup select,
  .em-fgroup input {
    min-width: 0;
    width: 100%;
  }

  /* Меню «Мои покупки» в тулбаре витрины (моб., добавляется injector).
     Иконка-кнопка раскрывает dropdown: Корзина / Заказы / Сохранённое. */
  .m-em-shopping {
    position: relative;
    flex-shrink: 0;
  }
  .m-em-shopping.m-open {
    z-index: 1100;
  }
  .m-em-shopping-btn {
    height: 42px;
    width: 42px;
    border: 1.5px solid var(--bdr, #DDE8E2);
    border-radius: var(--rm, 12px);
    background: var(--w, #fff);
    color: var(--g, #1E8A4C);
    display: grid;
    place-items: center;
    cursor: pointer;
    transition: background .15s, border-color .15s;
  }
  .m-em-shopping-btn:active {
    background: var(--gl, #E8F5EE);
    border-color: var(--gb, #C0DECA);
  }
  .m-em-shopping-btn svg {
    width: 18px;
    height: 18px;
  }
  /* Dropdown-меню */
  .m-em-shopping-menu {
    position: fixed;
    min-width: 190px;
    background: var(--w, #fff);
    border: 1px solid var(--bdr, #DDE8E2);
    border-radius: var(--rm, 12px);
    box-shadow: 0 12px 32px rgba(30, 138, 76, .15);
    padding: 5px;
    z-index: 99999;
    display: none;
    flex-direction: column;
    gap: 2px;
  }
  .m-em-shopping.m-open .m-em-shopping-menu,
  .m-em-shopping-menu.m-open {
    display: flex;
  }
  .m-em-shopping-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--t, #1A2A22);
    text-decoration: none;
    transition: background .12s, color .12s;
  }
  .m-em-shopping-item:active {
    background: var(--gp, #F0FAF4);
    color: var(--g, #1E8A4C);
  }
  .m-em-shopping-item svg {
    width: 17px;
    height: 17px;
    color: var(--g, #1E8A4C);
    flex-shrink: 0;
  }
  /* Разделитель: отделяет функции продавца (Кабинет) от функций
     покупателя (Корзина/Заказы/Сохранённое) выше. */
  .m-em-shopping-sep {
    height: 1px;
    background: var(--bdr, #DDE8E2);
    margin: 5px 8px;
  }
}

/* ═══════════════════════════════════════════════════════════════
   A3 — E-market кабинет: скрыть блок конструктора на мобиле
   ───────────────────────────────────────────────────────────────
   Конструктор магазина (drag-and-drop) недоступен на мобиле, поэтому
   секцию «Дизайн сайта» с кнопкой «Открыть конструктор» (вкладка
   Настройки) на телефоне не показываем.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  .cab-section-builder {
    display: none;
  }
}

/* ═══════════════════════════════════════════════════════════════
   A3.2 — E-market кабинет: карточки листингов
   ───────────────────────────────────────────────────────────────
   На десктопе .lst-card — одна строка: [thumb | инфо | 3 кнопки].
   На узком экране 3 кнопки действий съедают ширину, название режется
   в «…». Перестраиваем: первый ряд [thumb + инфо] во всю ширину
   (название видно в 2 строки), действия — отдельным рядом снизу,
   выровнены вправо и крупнее для пальца.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  .lst-card {
    flex-wrap: wrap;
    align-items: flex-start;
    row-gap: 12px;
  }
  /* Название: до 2 строк вместо обрезки в одну. */
  .lst-name {
    white-space: normal;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  /* Действия уходят на отдельный ряд во всю ширину, прижаты вправо. */
  .lst-actions {
    width: 100%;
    justify-content: flex-end;
    gap: 8px;
  }
  /* Кнопки чуть крупнее — удобнее тапать. */
  .lst-iconbtn {
    width: 40px;
    height: 40px;
  }
}

/* ── B-M-GUEST: гостевая главная (/home-guest) под мобилку ──────────────
   home-guest наследует общую мобильную сетку (.shell→1 колонка, .nav/.right
   скрыты, bottom-nav снизу). Здесь — специфика гостевых блоков. */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  /* Hero компактнее: меньше padding и заголовок */
  html.lt-shell .guest-hero,
  html.lt-shell-2col .guest-hero {
    padding: 20px 18px 18px;
  }
  html.lt-shell .gh-h1,
  html.lt-shell-2col .gh-h1 {
    font-size: 20px;
  }
  html.lt-shell .gh-p,
  html.lt-shell-2col .gh-p {
    font-size: 13px;
  }
  /* Кнопки hero — на всю ширину, в столбик */
  html.lt-shell .gh-actions,
  html.lt-shell-2col .gh-actions {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;
  }
  html.lt-shell .gh-btn-reg,
  html.lt-shell-2col .gh-btn-reg,
  html.lt-shell .gh-btn-login,
  html.lt-shell-2col .gh-btn-login {
    justify-content: center;
    text-align: center;
  }
  /* Возможности платформы — в 1 колонку (было repeat(3,1fr)) */
  html.lt-shell .features-grid,
  html.lt-shell-2col .features-grid {
    grid-template-columns: 1fr;
  }
  /* Гостевой поиск (мобилка): search-wrap → круглая кнопка-блок с лупой,
     отдельный блок слева от кнопок Войти/Регистрация. Тап → /search (там
     полноценный поиск). Строка/инпут скрыты. ТОЛЬКО гостевой топбар. */
  html.lt-shell .topbar:has(.topbar-guest) .search-wrap input,
  html.lt-shell-2col .topbar:has(.topbar-guest) .search-wrap input,
  html.lt-shell .topbar:has(.topbar-guest) .search-wrap .search-icon,
  html.lt-shell-2col .topbar:has(.topbar-guest) .search-wrap .search-icon {
    display: none;
  }
  /* search-wrap = круглая кнопка-блок (как капсула кнопок рядом) */
  html.lt-shell .topbar:has(.topbar-guest) .search-wrap,
  html.lt-shell-2col .topbar:has(.topbar-guest) .search-wrap {
    flex: 0 0 auto;
    min-width: 0;
    width: 56px;
    height: 56px;
    border-radius: 50%;
    background: var(--w, #fff);
    border: 1px solid var(--bdr, rgba(0,0,0,.08));
    box-shadow: var(--sh, 0 2px 8px rgba(0,0,0,.06));
    display: grid;
    place-items: center;
    padding: 0;
  }
  /* лупа по центру круглой кнопки */
  html.lt-shell .topbar:has(.topbar-guest) .search-wrap .m-search-btn,
  html.lt-shell-2col .topbar:has(.topbar-guest) .search-wrap .m-search-btn {
    display: grid;
    place-items: center;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    border: 0;
    background: transparent;
    box-shadow: none;
    flex-shrink: 0;
    -webkit-tap-highlight-color: transparent;
  }
  html.lt-shell .topbar:has(.topbar-guest) .search-wrap .m-search-btn svg,
  html.lt-shell-2col .topbar:has(.topbar-guest) .search-wrap .m-search-btn svg {
    width: 22px;
    height: 22px;
    stroke: var(--t, #1A2A22);
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
  /* Топбар гостевой: круглая кнопка слева (auto) + капсула кнопок справа (1fr) */
  html.lt-shell .topbar:has(.topbar-guest),
  html.lt-shell-2col .topbar:has(.topbar-guest) {
    grid-template-columns: auto 1fr;
  }
}

/* ── M3-P1-TAP: тактильный тап-фидбэк на карточках списков ──────────────
   На десктопе карточки реагируют на :hover, на тач hover нет — добавляем
   лёгкое «проминание» scale(.985) на :active, чтобы тап ощущался отзывчиво.
   transition НЕ задаём — у всех этих карточек он уже есть (transform в нём),
   плавность берётся из их собственных правил, мы ничего не перетираем. */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  .co-card:active,
  .ev-card:active,
  .comm-card:active,
  .job-card:active,
  .cv-card:active,
  .post-card:active,
  .em-card:active,
  .feat-card:active {
    transform: scale(0.985);
  }
  .co-card,
  .ev-card,
  .comm-card,
  .job-card,
  .cv-card,
  .post-card,
  .em-card,
  .feat-card {
    -webkit-tap-highlight-color: transparent;
  }
  /* post-card: её собственный transition только border-color → добавляем
     transform, чтобы scale-фидбэк был плавным (у остальных transform уже есть) */
  .post-card {
    transition: border-color .15s, transform 140ms cubic-bezier(0.4, 0, 0.2, 1);
  }
}

/* ── M3-P5-PTR: pull-to-refresh индикатор ──────────────────────────────
   Спиннер появляется сверху при оттягивании .main вниз от верха. */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  .m-ptr {
    position: fixed;
    top: calc(70px + env(safe-area-inset-top, 0px));
    left: 50%;
    transform: translateX(-50%) translateY(-60px) scale(0.8);
    z-index: 10005;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--w, #fff);
    box-shadow: 0 3px 14px rgba(15, 25, 18, 0.18);
    display: grid;
    place-items: center;
    opacity: 0;
    pointer-events: none;
    transition: transform 200ms cubic-bezier(0.4, 0, 0.2, 1), opacity 200ms ease;
  }
  .m-ptr.m-ptr-armed {
    transform: translateX(-50%) translateY(0) scale(1);
    opacity: 1;
  }
  .m-ptr.m-ptr-spinning {
    transform: translateX(-50%) translateY(0) scale(1);
    opacity: 1;
  }
  .m-ptr svg {
    width: 20px;
    height: 20px;
    stroke: var(--g, #1E8A4C);
    fill: none;
    stroke-width: 2.2;
    stroke-linecap: round;
  }
  .m-ptr.m-ptr-spinning svg {
    animation: m-ptr-spin 0.7s linear infinite;
  }
  @keyframes m-ptr-spin {
    to { transform: rotate(360deg); }
  }
}

/* ── M3-P6-GLASS: liquid-glass топбар-капсула (вариант B1) ──────────────
   Топбар становится плавающей стеклянной капсулой сверху (парный к bottom-nav).
   fixed → контент .main проезжает под ним (настоящее стекло с блюром).
   Стиль согласован с .m-bn: та же прозрачность, blur, тень, граница. */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  /* Топбар — плавающая капсула поверх контента */
  html.lt-shell .topbar,
  html.lt-shell-2col .topbar {
    position: fixed;
    top: calc(8px + env(safe-area-inset-top, 0px));
    left: 12px;
    right: 12px;
    z-index: var(--z-sticky, 100);
    height: 52px;
    padding: 0 14px;
    border-radius: 26px;
    background: rgba(255, 255, 255, 0.60);
    -webkit-backdrop-filter: blur(12px) saturate(180%);
    backdrop-filter: blur(12px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.6);
    box-shadow: 0 8px 32px rgba(30, 138, 76, 0.15), 0 2px 8px rgba(0, 0, 0, 0.06);
  }
  /* Топбар больше не занимает строку grid — освобождаем её, контент на всю высоту.
     Контент .main получает отступ сверху под парящую капсулу. */
  html.lt-shell .shell,
  html.lt-shell-2col .shell {
    grid-template-rows: 1fr;
    grid-template-areas: "main";
  }
  html.lt-shell .main,
  html.lt-shell-2col .main {
    padding-top: calc(80px + env(safe-area-inset-top, 0px));
  }
  /* Поиск внутри стеклянной капсулы: убираем его собственную белую карточку
     (фон/рамку/тень/высоту 56px) — иначе «карточка в карточке» выпирает.
     Сливаем с капсулой: прозрачный, компактный. */
  html.lt-shell .topbar > .search-wrap,
  html.lt-shell-2col .topbar > .search-wrap {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    min-height: 0 !important;
    height: 40px !important;
    padding: 0 !important;
    padding-left: 6px !important;
  }
  html.lt-shell .topbar > .search-wrap > .search-icon,
  html.lt-shell-2col .topbar > .search-wrap > .search-icon {
    left: 6px !important;
  }
  html.lt-shell .topbar > .search-wrap > input,
  html.lt-shell-2col .topbar > .search-wrap > input {
    height: 40px !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    -webkit-tap-highlight-color: transparent;
  }
  html.lt-shell .topbar > .search-wrap > input:focus,
  html.lt-shell-2col .topbar > .search-wrap > input:focus {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
  }
  /* Вместо серого выделения поля — подсвечиваем обводку всей капсулы топбара
     системным зелёным при фокусе внутри (поиск в фокусе). */
  html.lt-shell .topbar:focus-within,
  html.lt-shell-2col .topbar:focus-within {
    border-color: var(--g, #1E8A4C);
    box-shadow: 0 0 0 1px var(--g, #1E8A4C), 0 8px 32px rgba(30, 138, 76, 0.20), 0 2px 8px rgba(0, 0, 0, 0.06);
  }
  /* Аватар профиля — центрируем по высоте капсулы */
  html.lt-shell .topbar > .profile-dd-wrap,
  html.lt-shell-2col .topbar > .profile-dd-wrap {
    align-self: center;
  }
  /* Гостевые кнопки Войти/Регистрация: убираем их собственную белую карточку
     (фон/рамка/тень/высота 56px) — иначе «карточка в карточке» распирает
     капсулу и обрезает кнопку «Войти» о её край. Сливаем со стеклом капсулы. */
  html.lt-shell .topbar > .topbar-guest,
  html.lt-shell-2col .topbar > .topbar-guest {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    height: auto !important;
    padding: 0 !important;
  }
}

/* ── M3-P6-CHATINPUT: убрать серый фон-квадрат в чат-инпуте при фокусе ───
   .ci-input-box:focus-within ставит background:var(--w) — в тёмной теме это
   серый прямоугольник, ломающий вид. Убираем смену фона на мобилке, оставляя
   только зелёную рамку-обводку (как у поиска в топбаре). */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  .ci-input-box:focus-within {
    background: transparent !important;
  }
  .ci-textarea,
  .ci-textarea:focus {
    background: transparent !important;
    -webkit-tap-highlight-color: transparent;
  }
}

/* ── M3-P6-MAINHEIGHT: фикс обрезки контента под плавающим навбаром ──────
   Корень бага (профиль и др.): .main занимает весь грид-трек (100dvh) и его
   низ физически уходит под fixed bottom-nav. При коротком контенте (maxScroll=0,
   скролла нет) хвост контента оказывается под навбаром без возможности доскролла
   (padding-bottom помогает только когда скролл уже есть). На длинных лентах
   проявлялось реже. Решение: ограничить высоту .main так, чтобы её низ был НАД
   навбаром. Тогда короткий контент весь в видимой зоне, длинный — скроллится
   внутри. Высота = вьюпорт − верхний отступ под топбар (80) − зона навбара
   (bottom 18 + height 64 + запас 8 = 90) − safe-area-bottom.
   padding-bottom (стр 411) при этом убираем в 0 — его роль берёт ограничение. */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  html.lt-shell .main,
  html.lt-shell-2col .main {
    height: calc(100dvh - 90px - var(--m-safe-bottom, 0px));
    max-height: calc(100dvh - 90px - var(--m-safe-bottom, 0px));
    padding-bottom: 12px;
  }
  /* В режиме открытого чата высота управляется отдельно — не вмешиваемся. */
  body:has(.chat-panel.m-show-chat) .main {
    height: auto !important;
    max-height: none !important;
  }
}

/* ── M3-P6-SEARCHPAGE: страница /search для гостя (мобилка) ──────────────
   Финальная логика гостевого поиска: лупа на главной → /search, и здесь
   убираем гостевые кнопки Войти/Регистрация из топбара (их вставляет
   guest-nav.js как #guestTopbarBtns), оставляем строку #searchInput на всю
   ширину. ТОЛЬКО на /search (lt-search-page) и ТОЛЬКО мобилка. */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  html.lt-search-page #guestTopbarBtns {
    display: none !important;
  }
  /* строка поиска на всю ширину топбара */
  html.lt-search-page .topbar .search-wrap {
    flex: 1 1 auto !important;
    min-width: 0 !important;
  }
  html.lt-search-page .topbar .search-wrap input {
    width: 100% !important;
  }
}

/* ── M3-P6-GUESTSEARCH-FIX: гостевой топбар — единая капсула (Вариант 1) ──────
   Топбар = ОДНА цельная капсула (фон/бордер/тень/скруглённая). Внутри:
   круглый сегмент лупы слева + тонкий разделитель + кнопки Войти/Регистрация.
   Лупа — органичная часть капсулы, а не одинокий кружок. Перебивает GLASS
   (идёт после, с !important). ТОЛЬКО гостевой топбар (.topbar-guest), мобилка. */
@media (max-width: 640px), (orientation: landscape) and (max-height: 640px) and (pointer: coarse) {
  /* Сам топбар — единая капсула */
  html.lt-shell .topbar:has(.topbar-guest),
  html.lt-shell-2col .topbar:has(.topbar-guest) {
    display: flex !important;
    align-items: center !important;
    gap: 0 !important;
    height: 56px !important;
    padding: 0 8px 0 4px !important;
    border-radius: 28px !important;
    background: var(--w, #fff) !important;
    border: 1px solid var(--bdr, rgba(0,0,0,.08)) !important;
    box-shadow: var(--sh, 0 2px 8px rgba(0,0,0,.06)) !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  /* Лупа — круглый сегмент слева внутри капсулы, с разделителем справа */
  html.lt-shell .topbar:has(.topbar-guest) > .search-wrap,
  html.lt-shell-2col .topbar:has(.topbar-guest) > .search-wrap {
    flex: 0 0 auto !important;
    width: 48px !important;
    height: 48px !important;
    min-height: 48px !important;
    border-radius: 50% !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    display: grid !important;
    place-items: center !important;
    padding: 0 !important;
    margin: 0 4px 0 0 !important;
    position: relative !important;
  }
  /* тонкий разделитель между лупой и кнопками */
  html.lt-shell .topbar:has(.topbar-guest) > .search-wrap::after,
  html.lt-shell-2col .topbar:has(.topbar-guest) > .search-wrap::after {
    content: "" !important;
    position: absolute !important;
    right: -4px !important;
    top: 50% !important;
    transform: translateY(-50%) !important;
    width: 1px !important;
    height: 24px !important;
    background: var(--bdr, rgba(0,0,0,.10)) !important;
  }
  html.lt-shell .topbar:has(.topbar-guest) > .search-wrap > .m-search-btn,
  html.lt-shell-2col .topbar:has(.topbar-guest) > .search-wrap > .m-search-btn {
    position: static !important;
    width: 100% !important;
    height: 100% !important;
    display: grid !important;
    place-items: center !important;
    background: transparent !important;
  }
  /* скрыть инпут/иконку строки у гостя */
  html.lt-shell .topbar:has(.topbar-guest) > .search-wrap > input,
  html.lt-shell-2col .topbar:has(.topbar-guest) > .search-wrap > input,
  html.lt-shell .topbar:has(.topbar-guest) > .search-wrap > .search-icon,
  html.lt-shell-2col .topbar:has(.topbar-guest) > .search-wrap > .search-icon {
    display: none !important;
  }
  /* Кнопки Войти/Регистрация — продолжение внутри капсулы, без своей подложки */
  html.lt-shell .topbar:has(.topbar-guest) > .topbar-guest,
  html.lt-shell-2col .topbar:has(.topbar-guest) > .topbar-guest {
    flex: 1 1 auto !important;
    height: 48px !important;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    border-radius: 0 !important;
    padding: 0 0 0 8px !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
}
