/* chat-panel.css — стили вкладки «Чат» (модуль сообщений, ТЗ р.11). ВСЕ селекторы заскоуплены под #tab-messages,
   как zay-panel.css под #tab-requests и por-panel.css под #tab-tasks. :root / html / body / chrome-классы НЕ
   переопределяем — токены и .card/.btn/.badge приходят из app.css. Свои классы — с префиксом .chat-*.

   ⚠️ INLINE <style> В ПАНЕЛИ ЗАПРЕЩЁН, и причина не та, что обычно называют. Браузер тут ни при чём: <style>
      внутри <body> он применяет штатно — живой пример app.php:2958 (модалка пополнения), она работает и в shell.
      Настоящих причин две.
      1. Стиль в файле-панели штатно кладут в преамбулу, а преамбула обёрнута в `if (!defined('SHELL_EMBED'))`
         (porucheniya.php:30…465, notifications.php:24…84) — в embed PHP её не печатает вовсе. Стиль исчезает не
         при рендере, а раньше: он просто не попадает в вывод.
      2. Даже уцелевший inline-стиль дороже. Этот файл подключён с ?v=filemtime (shell.php) и лежит в HTTP-кэше
         между заходами, а тело панели перепечатывается на КАЖДЫЙ показ shell и едет по сети каждый раз.

   ⚠️ Классы .tc-* (task-comments.css) НЕ дублируем. Пузыри, аватар, группировка сообщений, миниатюры вложений и
      строка ввода там уже сделаны и подключены глобально (shell.php:55), файл лежит в SHELL — лента диалога
      возьмёт их как есть (части 7.2+). Здесь только то, чего в .tc-* нет: каркас панели, шапка, список диалогов. */

/* Нижний отступ = высота нав-бара плюс воздух. ⚠️ Здесь он нужен для режима, когда страница скроллится сама
   (узкий экран, экран списка) — там панель не занимает ровно 100dvh, и вычитать нечего. Раньше тут стояло 60px,
   списанное у поручений и заявок; переменная убирает магическое число: 60 было высотой бара плюс запас, но бар
   на узком экране выше (53px против 51px), и константа врала в одну из сторон. */
#tab-messages .chat-wrap { max-width: 960px; margin: 0 auto; padding: 20px 18px calc(var(--bnav-h, 56px) + 12px); }
/* Высота панели в режиме «прокручивается содержимое, а не страница». Задаётся ЗДЕСЬ, а не в оболочке: раньше это
   же правило стояло в shell.php вместе с display:flex и перебивало двухколоночную сетку по специфичности. */
body.shell-messages-dialog #tab-messages .chat-wrap { height: 100%; min-height: 0; padding-bottom: 0; }
body.shell-messages-dialog #tab-messages .chat-wrap:not(.is-wide) { display: flex; flex-direction: column; }
/* ⚠️ Экран диалога обязан ТЯНУТЬСЯ на остаток высоты, иначе `.chat-dlg { height: 100% }` берёт сто процентов от
   блока, высота которого определяется содержимым, — то есть остаётся авто. Лента тогда не получает своей
   прокрутки: она растёт вниз вместе с сообщениями, открывается на первом сообщении вместо последнего, а поле
   ввода уезжает за нижний край экрана. На широком это делает grid-строка (minmax(0, 1fr)), на узком — flex. */
body.shell-messages-dialog #tab-messages .chat-wrap:not(.is-wide) > #chatDialogScreen { flex: 1 1 auto; min-height: 0; }
body.shell-messages-dialog #tab-messages .chat-wrap:not(.is-wide) > #chatListScreen { flex: 1 1 auto; min-height: 0; overflow-y: auto; }

/* ── Шапка: заголовок, строка состояния и кнопка «новый чат» ──
   ⚠️ КНОПКА ЗДЕСЬ НЕ ТАКАЯ, КАК В ЗАЯВКАХ, и это осознанно. Раньше она была зеркалом .zay-add — круглая,
      залитая акцентом, с тенью. В чате её сменила контурная иконка «карандаш в квадрате»: та же, что в
      мессенджерах, где действие называется «написать», а не «добавить запись». Правя .zay-add, сюда не
      переносить — расхождение намеренное. */
#tab-messages .chat-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
#tab-messages .chat-head__t { min-width: 0; }
/* ⚠️ Высота строки заголовка задана ЯВНО и вынесена в переменную: по ней кнопка выравнивается на заголовок,
      а не на весь блок с подзаголовком (иначе она уезжает вниз, к строке состояния). Меняешь размер
      заголовка — меняешь переменную, и выравнивание идёт следом; двух разъезжающихся чисел не возникает. */
#tab-messages .chat-head { --chat-title-line: 30px; }
#tab-messages .chat-title { margin: 0; font-size: 22px; line-height: var(--chat-title-line); font-weight: 700; color: #111827; }
#tab-messages .chat-sub { margin-top: 2px; font-size: 13px; color: #6b7280; }
/* ⚠️ ОБЛАСТЬ НАЖАТИЯ 40×40, хотя рисунок 22px. На телефоне палец попадает не в иконку, а в прямоугольник
      вокруг неё; 22 пикселя — это промах через раз. Отрицательный отступ сверху ставит центр кнопки на центр
      строки заголовка: (30 - 40) / 2. */
/* ⚠️ РАЗМЕРЫ И ЦЕНТРИРОВАНИЕ — ТЕ ЖЕ, ЧТО У .tc-send (task-comments.css:47): 38×38, круг, flex по центру.
      Своих чисел не подбираем: это две кнопки одного языка — «написать» и «отправить», — и разъехавшись на
      пару пикселей, они начинают читаться как разные элементы. Отступ сверху считается от той же переменной
      строки заголовка, что и раньше, только от новой высоты. */
#tab-messages .chat-add {
    flex: none; width: 38px; height: 38px; margin-top: calc((var(--chat-title-line) - 38px) / 2);
    display: flex; align-items: center; justify-content: center;
    border: 0; border-radius: 50%; padding: 0;
    background: var(--fill-accent, #4f46e5); color: var(--on-accent, #fff);
    cursor: pointer; font-family: inherit;
}
#tab-messages .chat-add:hover { filter: brightness(1.06); }   /* как .tc-send:hover */
#tab-messages .chat-add:active { filter: brightness(.94); }
#tab-messages .chat-add[hidden] { display: none; }

#tab-messages .msg { font-size: 13px; color: var(--danger, #d1242f); min-height: 16px; }

/* ── Экраны: список ↔ диалог. Видимость переключает chat.js через [hidden] ── */
#tab-messages .chat-screen[hidden] { display: none; }

/* Диалог занимает высоту панели целиком: прокручивается ЛЕНТА, а не страница — поле ввода обязано остаться на
   экране, пока человек листает переписку. Раскладку включает shell (body.shell-messages-dialog), здесь — только
   поведение внутреннего контейнера. */
#tab-messages .chat-screen--dialog { display: flex; flex-direction: column; min-height: 0; }

/* Пустое состояние и «Загрузка…» — один класс: оба подменяют содержимое списка, тон нейтральный (не ошибка). */
#tab-messages .chat-empty { padding: 28px 4px; text-align: center; font-size: 14px; color: #6b7280; }
#tab-messages .chat-empty-link { display: block; margin: 10px auto 0; border: 0; background: none; padding: 0; font: inherit; font-size: 13px; color: #4f46e5; cursor: pointer; text-decoration: underline; }

/* ── Чипы-фильтры. Класс .chip общий (app.css), здесь — только раскладка ряда: на телефоне он скроллится вбок,
      поэтому запрещаем перенос и прячем полосу прокрутки. ── */
/* ⚠️ ЗНАЧЕНИЯ ВЗЯТЫ У ПОИСКА ЗАЯВОК (zay-panel.css:25-31) один в один — это один и тот же компонент в двух
      разделах, и расходиться им нельзя. Отдельного общего класса не завожу: это правка чата, а вынос
      компонента в app.css трогает вторую панель и просится отдельным заходом. */
/* ⚠️ ВЫСОТА И ЗАЗОР — ПЕРЕМЕННЫМИ, И ЭТО НЕ УКРАШЕНИЕ. От них считается положение кнопки «Новый чат»: она
      вынесена из потока и стоит поверх ряда чипов, а ряд теперь второй — над ним поиск. Оставь тут обычные
      числа, и они разъедутся с отступом кнопки при первой правке размера поля; замер поймал ровно это —
      кнопка налезла на строку поиска. */
#tab-messages .chat-wrap { --chat-search-h: 38px; --chat-search-gap: 10px; }
#tab-messages .chat-search {
    display: flex; align-items: center; gap: 8px; box-sizing: border-box;
    height: var(--chat-search-h); margin-bottom: var(--chat-search-gap); padding: 0 14px;
    background: #fff; border: 1px solid #d1d5db; border-radius: 20px; color: var(--muted, #6b7280);
}
#tab-messages .chat-search input {
    width: auto; flex: 1; min-width: 0; border: 0; background: none; outline: none;
    font-size: 15px; font-family: inherit; color: var(--text, #111827); -webkit-appearance: none; padding: 0;
}
#tab-messages .chat-search input::placeholder { color: #9aa1ab; }
#tab-messages .chat-search .ic { flex: none; }
#tab-messages .chat-search-x {
    flex: none; display: none; align-items: center; justify-content: center; width: 20px; height: 20px;
    padding: 0; border: 0; border-radius: 50%; background: #e2e6ec; color: var(--muted, #6b7280);
    font-size: 12px; line-height: 1; cursor: pointer;
}
#tab-messages .chat-search-x.is-visible { display: inline-flex; }
#tab-messages .chat-search-x:hover { background: #d3d8e0; color: var(--text, #111827); }

#tab-messages .chat-chips { display: flex; gap: 6px; overflow-x: auto; padding: 0 0 12px; scrollbar-width: none; }
#tab-messages .chat-chips::-webkit-scrollbar { display: none; }
#tab-messages .chat-chips .chip { flex: none; }
/* ⚠️ ИКОНКА В ЧИПЕ — ТОЛЬКО В ЧАТЕ. .chip общий на четыре панели (app.css:762), и добавлять ему flex-раскладку
      глобально значило бы менять вид чипов в поручениях, заявках и планировщике ради одной. Скоуп узкий:
      контейнер чата.
   ⚠️ Цвет НЕ ЗАДАЁМ — глиф рисуется currentColor и берёт цвет самого чипа: в обычном приглушённый текст, в
      активном белый на индиго. Своё значение здесь разошлось бы с состоянием чипа при первой же правке
      палитры.
   ⚠️ flex: none у иконки и nowrap у чипа (app.css) — ряд по-прежнему прокручивается горизонтально и не
      переносится: иконка занимает место внутри чипа, а не ломает ряд. */
#tab-messages .chat-chips .chip { display: inline-flex; align-items: center; gap: 6px; }
#tab-messages .chat-chips .chip__ic { flex: none; display: inline-flex; width: 14px; height: 14px; opacity: .85; }
#tab-messages .chat-chips .chip__ic svg { width: 100%; height: 100%; }

/* ⚠️ РЯД ОСТАЁТСЯ ОДНОЙ СТРОКОЙ НА ЛЮБОЙ ШИРИНЕ. Перенос на вторую строку здесь пробовали: он снимал вопрос
      достижимости, но забирал у списка вторую строку высоты на каждом заходе и разводил вид фильтров по
      ширинам. Достижимость решена иначе — протаскиванием мышью (chat.js: bindChipsDrag), и одна раскладка
      осталась одна.
   ⚠️ КУРСОР — ПО СПОСОБУ ВВОДА, А НЕ ПО ШИРИНЕ, тем же приёмом, что и правило выделения ниже: «можно тянуть»
      имеет смысл только там, где есть указатель. На касании ряд едет за пальцем и без подсказки.
   ⚠️ grabbing вешает chat.js классом is-dragging — CSS не знает, началась ли поездка: у неё есть порог в
      пикселях, и до него нажатие остаётся обычным нажатием на чип. */
@media (hover: hover) and (pointer: fine) {
    #tab-messages .chat-chips { cursor: grab; }
    #tab-messages .chat-chips.is-dragging { cursor: grabbing; -webkit-user-select: none; user-select: none; }
}

/* ── Строка диалога ── */
#tab-messages .chat-rows { display: flex; flex-direction: column; gap: 2px; }
#tab-messages .chat-row {
    display: flex; align-items: center; gap: 12px; width: 100%; box-sizing: border-box;
    padding: 10px 8px; border: 0; border-radius: 12px; background: none;
    font-family: inherit; text-align: left; cursor: pointer;
}
#tab-messages .chat-row:hover { background: #f4f6fb; }
#tab-messages .chat-row--pin { background: rgba(79, 70, 229, .04); }
#tab-messages .chat-row--pin:hover { background: #f4f6fb; }

/* Иконка. ⚠️ ТИП ЗАКОДИРОВАН ДВАЖДЫ, ФОРМОЙ И ЦВЕТОМ, и оси независимы намеренно.
   Форма работает на боковое зрение: круг = человек или группа людей, скруглённый квадрат = документ (поручение,
   заявка) — это видно раньше, чем прочитана подпись. Цвет работает на другое: различить строки в ДЛИННОМ списке,
   где формы всего две и половина экрана занята одинаковыми квадратами.
   ⚠️ Поэтому пара близких оттенков недопустима: она не «чуть менее заметна», она ОТКЛЮЧАЕТ вторую ось целиком —
   тип снова читается только формой, и вся разница между поручением и заявкой держится на мелком контуре внутри
   иконки. Так и было: заявка стояла на #4338ca при личном #4f46e5, то есть на том же индиго.
   Четыре типа — четыре различимых тона: индиго / бирюза / янтарь / синий. */
#tab-messages .chat-ava {
    flex: none; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center;
    font-size: 15px; font-weight: 700; color: #fff; background: #4f46e5; /* личный диалог — индиго */
}
#tab-messages .chat-ava--round { border-radius: 50%; }
#tab-messages .chat-ava--sq { border-radius: 12px; }
#tab-messages .chat-ava--grp { background: #0f766e; }      /* группа и общий чат — бирюза */
#tab-messages .chat-ava--task { background: #b45309; }     /* поручение — янтарь */
#tab-messages .chat-ava--request { background: #0369a1; }  /* заявка — синий (не индиго: см. правило выше) */
#tab-messages .chat-ava svg { width: 22px; height: 22px; }

#tab-messages .chat-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
#tab-messages .chat-row__top { display: flex; align-items: baseline; gap: 8px; }
#tab-messages .chat-row__ttl {
    flex: 1; min-width: 0; font-size: 15px; font-weight: 600; color: #111827;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#tab-messages .chat-row--unread .chat-row__ttl { font-weight: 700; }
#tab-messages .chat-row__pinic { font-size: 11px; margin-right: 4px; }
#tab-messages .chat-row__at { flex: none; font-size: 12px; color: #9ca3af; }
#tab-messages .chat-row__bottom { display: flex; align-items: center; gap: 8px; }
/* Превью — ОДНА строка с многоточием. Два факта в одной ширине: без nowrap длинное сообщение растянет строку и
   список перестанет быть списком (у заявок это правило записано на .zay-row). */
#tab-messages .chat-row__pv {
    flex: 1; min-width: 0; font-size: 13px; color: #57606a;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#tab-messages .chat-row__pv b { font-weight: 600; color: #374151; }
/* ⚠️ .chat-row__subj (префикс «Поручение №31» перед превью) УДАЛЁН вместе с его показом в строке: он отъедал
   у превью начало — ту часть, по которой строку узнают. Номер живёт в шапке диалога (chat.js: renderDlgSub),
   поле subject_label с сервера на месте. Класс в разметке больше не появляется; если понадобится вернуть —
   возвращать вместе с правилами, а не осиротевший селектор. */
#tab-messages .chat-row__pv--muted { color: #9ca3af; font-style: italic; }
#tab-messages .chat-row__badge {
    flex: none; min-width: 18px; height: 18px; box-sizing: border-box; padding: 0 5px;
    border-radius: 999px; background: #d1242f; color: #fff;
    font-size: 11px; font-weight: 700; line-height: 18px; text-align: center;
}

/* ══════════════════ ДВЕ КОЛОНКИ НА ШИРОКОМ ЭКРАНЕ ══════════════════
   ⚠️ ЗДЕСЬ НЕТ @media ПО ШИРИНЕ, И ЭТО НАМЕРЕННО. Порог живёт в ОДНОМ месте — в chat.js (matchMedia), откуда
      на .chat-wrap вешается класс .is-wide. Продублируй его тут @media-запросом — и число 900 окажется в двух
      файлах: разъедутся при первой правке, причём молча, дав полосу ширин, где CSS уже двухколоночный, а JS
      ещё считает экран узким. Симптом такого расхождения — «кнопка назад пропала, а списка нет». */
/* Сетка: шапка панели во всю ширину, под ней две колонки — список 320px и резиновая лента. Третий ряд
   minmax(0, 1fr) обязателен: без нулевого минимума колонки растянулись бы по содержимому и прокрутка уехала бы
   на страницу вместо колонок. */
#tab-messages .chat-wrap.is-wide {
    display: grid; grid-template-columns: 320px minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr);
    height: 100%; min-height: 0; max-width: 1280px; padding-bottom: 0;
}
#tab-messages .chat-wrap.is-wide > .chat-head,
#tab-messages .chat-wrap.is-wide > .msg { grid-column: 1 / -1; }
#tab-messages .chat-wrap.is-wide > #chatListScreen {
    grid-column: 1; grid-row: 3; min-height: 0; overflow-y: auto;   /* своя прокрутка, независимая от ленты */
    border-right: 1px solid #eaeef2; padding-right: 12px;
}
#tab-messages .chat-wrap.is-wide > #chatDialogScreen { grid-column: 2; grid-row: 3; min-width: 0; min-height: 0; padding-left: 16px; }

/* Выделение открытой строки — только на широком (класс вешает chat.js). */
#tab-messages .chat-row.is-selected { background: rgba(79, 70, 229, .10); }
#tab-messages .chat-row.is-selected:hover { background: rgba(79, 70, 229, .14); }

/* Правая колонка без выбранного диалога. Тон нейтральный: это не ошибка и не пустой раздел. */
#tab-messages .chat-pick { height: 100%; display: flex; align-items: center; justify-content: center; color: #9ca3af; font-size: 14px; }

/* ══════════════════ ЭКРАН ДИАЛОГА ══════════════════
   ⚠️ БЕЛАЯ ПОДЛОЖКА ОБЯЗАТЕЛЬНА, а не декоративна. В app.css --bg (фон страницы) и --surface-1 (фон ЧУЖОГО
      пузыря в task-comments.css) — одно и то же значение #f4f6fb. В поручениях лента живёт внутри белой
      карточки, поэтому пузырь на ней виден; положи её прямо на фон страницы, как здесь, — и чужие сообщения
      исчезнут: текст без подложки, неотличимый от системной врезки. Нашлось это только глазами на статике,
      никакой линтер такого не покажет. Правим подложкой, а НЕ цветом .tc-bubble: тот общий с поручениями и
      заявками, и перекрашивать его ради чата значит менять вид сразу трёх разделов. */
#tab-messages .chat-dlg {
    display: flex; flex-direction: column; height: 100%; min-height: 0;
    background: #fff; border-radius: 14px; padding: 12px 14px;
}
#tab-messages .chat-dlg__head {
    flex: 0 0 auto; display: flex; align-items: center; gap: 10px;
    padding: 0 0 10px; border-bottom: 1px solid #eaeef2; margin-bottom: 8px;
}
#tab-messages .chat-dlg__head .chat-ava { width: 36px; height: 36px; font-size: 13px; }
#tab-messages .chat-dlg__head .chat-ava svg { width: 18px; height: 18px; }
#tab-messages .chat-dlg__t { flex: 1; min-width: 0; }
/* ⚠️ ЗАГОЛОВОК ПЕРЕНОСИТСЯ, А НЕ ОБРЕЗАЕТСЯ. У заявки он длинный — «Заявка на ремонт (пультовая охрана)
   № 260828-005 от 28.08.2026», и на 390px однострочный ellipsis резал его на «Заявка на ремонт (пульт…»:
   пропадали и номер, и дата, то есть ровно то, ради чего они в заголовок и вынесены. Две строки максимум
   (line-clamp) — дальше многоточие, чтобы шапка не выросла на пол-экрана. */
#tab-messages .chat-dlg__ttl {
    font-size: 16px; font-weight: 700; color: #111827; overflow: hidden;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
}
/* Подпись — уже не одна строка текста: в ней ряд чипов участников, который переносится. */
#tab-messages .chat-dlg__sub { font-size: 12px; color: #6b7280; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; margin-top: 2px; }
#tab-messages .chat-dlg__subtxt { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
/* ⚠️ ЧИПЫ УЧАСТНИКОВ — ВИД ЗЕРКАЛИТ .empp-chip ИЗ ПИКЕРА (zay-panel.css:403): те же фон, цвет, радиус и
   размер, чтобы «выбранный сотрудник» выглядел одинаково во всём кабинете. Своим классом, а не переиспользо-
   ванием: .empp-chip заскоуплен под #tab-requests / #zayTplRoot, и тянуть селектор чата в панель заявок
   значило бы связать два несвязанных экрана. Кнопки «убрать» здесь нет — состав диалога правится не отсюда.
   ⚠️ Ряд ограничен по высоте: два ряда чипов максимум, остальное скрыто — сколько именно скрыто, показывает
   счётчик .chat-dlg__more ниже, а полный состав есть в title ряда. */
/* ⚠️ ВЫСОТА РЯДА — РОВНО ДВА ЧИПА, И ЭТО СЧИТАЕТСЯ, А НЕ ПОДБИРАЕТСЯ НА ГЛАЗ. Было max-height: 46px при
   фактической потребности 48px (22 + 4 + 22): второй ряд обрезался на два пикселя — визуально почти целый,
   а по замеру уже «скрытый». Счётчик из-за этого врал: при 12 участниках показывал «+8», хотя на экране
   было видно 8 чипов из 12. Высота чипа (--chip-h) = font-size 12px × line-height 1.5 + padding 2px сверху
   и снизу; поменяется кегль чипа — правится одно место, а не магическое число.
   ⚠️ min-width: 0 — ряд лежит во flex-контейнере подписи и без него отказывался ужиматься. */
#tab-messages .chat-dlg__chips {
    --chip-h: 22px;
    display: flex; flex-wrap: wrap; gap: 4px; flex: 1 1 auto; min-width: 0;
    max-height: calc(var(--chip-h) * 2 + 4px); overflow: hidden;
}
/* Счётчик скрытых участников: тот же чип, но приглушённый — он про количество, а не про человека.
   ⚠️ ЖИВЁТ ВНУТРИ РЯДА, последним элементом. Снаружи он не обрезался, но вставал ТРЕТЬЕЙ строкой под двумя
   рядами чипов, то есть растил шапку там, где её и ограничивали. Место под него внутри ряда резервирует
   расчёт (chat.js: syncChipsOverflow прячет лишние чипы), а не CSS.
   ⚠️ flex: none — счётчик не сжимается: «+91» должно читаться целиком, даже когда рядом длинные имена. */
#tab-messages .chat-dlg__more {
    flex: none; display: inline-flex; align-items: center; background: #f1f3f7; color: #6b7280;
    border-radius: 20px; padding: 2px 8px; font-size: 12px; line-height: 1.5; white-space: nowrap; cursor: default;
}
#tab-messages .chat-dlg__chip {
    display: inline-flex; align-items: center; background: #eef2ff; color: #3730a3;
    border-radius: 20px; padding: 2px 8px; font-size: 12px; line-height: 1.5; white-space: nowrap;
    max-width: 180px; overflow: hidden; text-overflow: ellipsis;
}
/* ⚠️ ОБА ПРАВИЛА [hidden] ОБЯЗАТЕЛЬНЫ: display:inline-flex выше перебивает встроенный display:none атрибута
   hidden, и без них спрятанные расчётом чипы продолжали бы занимать место — счётчик считал бы «вхолостую». */
#tab-messages .chat-dlg__more[hidden] { display: none; }
#tab-messages .chat-dlg__chip[hidden] { display: none; }
/* ⚠️ НА УЗКОМ ЭКРАНЕ ЗАГОЛОВКУ НУЖНА ТРЕТЬЯ СТРОКА. При 390px в строку влезает ~24 символа, и на двух
   строках «Заявка на ремонт (пультовая охрана) № 260828-005 от 28.08.2026» обрывалось ровно на дате —
   то есть терялось то, ради чего номер и дату в заголовок и вынесли (проверено рендером). */
#tab-messages .chat-wrap:not(.is-wide) .chat-dlg__ttl { -webkit-line-clamp: 3; line-clamp: 3; font-size: 15px; }
#tab-messages .chat-dlg__subj {
    flex: none; display: inline-flex; align-items: center; gap: 6px;
    border: 1px solid var(--border, #e5e7eb); background: #fff; color: #4f46e5;
    border-radius: 999px; padding: 6px 12px; font-size: 13px; font-family: inherit; cursor: pointer; white-space: nowrap;
}
#tab-messages .chat-dlg__subj:hover { border-color: #4f46e5; }
/* На узком экране остаётся одна иконка: подпись «Открыть поручение» рядом с заголовком съедала имя собеседника
   до многоточия, а в переписке важнее понимать, с кем говоришь. Полный текст доступен в aria-label и title. */
#tab-messages .chat-wrap:not(.is-wide) .chat-dlg__subj { padding: 7px; border-radius: 50%; }
#tab-messages .chat-wrap:not(.is-wide) .chat-dlg__subj-t { display: none; }
#tab-messages .chat-back {
    flex: none; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px;
    border: 0; background: none; padding: 0; color: #4f46e5; cursor: pointer;
}

/* Лента. Базовые классы .tc-* приходят из task-comments.css; здесь переопределяем ТОЛЬКО высоту: там она
   рассчитана на встроенный в карточку блок (max-height 340px), а тут лента занимает весь экран. */
/* ⚠️ Боковые отступы СИММЕТРИЧНЫ и заметны (10px), а не 4px «чтобы просто было». Свои сообщения прижаты к
   правому краю (tc-row--own), чужие — к левому, и при узком отступе пузырь почти касается границы колонки:
   слева его визуально отодвигает аватар, справа отодвигать нечем, и лента выглядит съехавшей вправо. */
#tab-messages .chat-feed { flex: 1 1 auto; min-height: 0; max-height: none; overflow-y: auto; padding: 2px 10px 8px; }
/* ⚠️ ПЕРЕПИСКА ПРИЖИМАЕТСЯ К НИЗУ, а пустое место остаётся сверху: короткий диалог должен стоять у поля
      ввода, а не висеть под шапкой — читают и пишут внизу, туда и смотрят.
   ⚠️ margin-top: auto У ПЕРВОГО РЕБЁНКА, А НЕ justify-content: flex-end У КОНТЕЙНЕРА. Второе выглядит прямее,
      но у прокручиваемого flex-контейнера ломает доступ к началу: содержимое, не влезшее сверху, выходит за
      край и прокруткой не достаётся — то есть «Показать более ранние» и вся история становятся недосягаемы.
      Автоматический отступ ведёт себя иначе: пока место есть, он его съедает; как только содержимое переросло
      контейнер, он превращается в ноль, и прокрутка работает ровно как раньше.
   ⚠️ Правило на ПЕРВОГО РЕБЁНКА, каким бы он ни был: это и кнопка «Показать более ранние», и разделитель
      даты, и первое сообщение, и пустое состояние. Подгрузка вверх вставляет новый первый элемент — отступ
      переезжает на него сам, без единой строки в коде. */
#tab-messages .chat-feed > :first-child { margin-top: auto; }
#tab-messages .chat-compose { flex: 0 0 auto; padding-top: 4px; }
#tab-messages .chat-compose .tc-input { margin-top: 0; }

/* Разделитель дат — тонкая линия с подписью посередине. */
#tab-messages .chat-daysep { display: flex; align-items: center; gap: 10px; margin: 14px 0 8px; color: #9ca3af; font-size: 12px; }
#tab-messages .chat-daysep::before,
#tab-messages .chat-daysep::after { content: ""; flex: 1; height: 1px; background: #eaeef2; }

/* Системное событие: по центру, без пузыря — это отметка о том, что произошло с диалогом, а не чья-то реплика. */
#tab-messages .chat-sys { margin: 8px auto; max-width: 80%; text-align: center; font-size: 12px; color: #6b7280; }

/* Удалённое/скрытое сообщение: место в ленте остаётся, текста нет. */
#tab-messages .chat-gone { font-style: italic; opacity: .75; }
#tab-messages .chat-edited { margin-left: 6px; font-style: italic; opacity: .8; }

/* Ассистент: тот же кружок аватара, но своим цветом и с иконкой вместо инициалов. */
#tab-messages .tc-ava.chat-ava-ai { background: #0f766e; color: #fff; }
#tab-messages .chat-ai-tag { font-size: 10px; font-weight: 700; color: #0f766e; border: 1px solid #99f6e4; border-radius: 4px; padding: 0 3px; }

/* Кнопка действий над своим сообщением — появляется при наведении, на тач-устройствах видна всегда. */
/* ⚠️ .chat-msg-menu УДАЛЁН вместе с кнопкой «⋯» у сообщения: меню теперь вызывается долгим нажатием по
   пузырю, правым кликом и клавишей Menu. Класс в разметке не появляется; понадобится вернуть — возвращать
   вместе с правилами, а не осиротевший селектор.

   ⚠️ ПРАВИЛО МОДУЛЯ: ВНУТРИ #tab-messages СИСТЕМНОЙ ПАНЕЛИ ДОЛГОГО НАЖАТИЯ НЕТ НИГДЕ, КРОМЕ ПОЛЕЙ ВВОДА.
      Это та же граница, что у правого клика (chat.js: onBubbleContext), только для касания: iOS вызывает
      свою панель «Скопировать / Найти» с увеличительным стеклом НЕ через contextmenu, и обработчиком её не
      погасить — только -webkit-touch-callout. Перечня мест здесь нет намеренно: правило накрывает панель
      целиком, и добавленный завтра экран подпадёт под него сам.
   ⚠️ ИСКЛЮЧЕНИЕ РОВНО ОДНО — ПОЛЯ ВВОДА, тем же списком тегов, что в isTextEntry. Там панель iOS — рабочий
      инструмент: выделить, вставить, поправить набранное.
   ⚠️ ПРИЁМ НЕ НОВЫЙ: так же погашен просмотр вложений (por-panel.css: .attm__img) и навигация
      (bottom_nav.php). */
#tab-messages { -webkit-touch-callout: none; }
#tab-messages input,
#tab-messages textarea,
#tab-messages [contenteditable=""],
#tab-messages [contenteditable="true"] { -webkit-touch-callout: default; }
/* ⚠️ ОТКЛИК СВАЙПА ЦИТИРОВАНИЯ: строка едет за пальцем и возвращается плавно. Возврат — переходом, а сам
      сдвиг — без него (класс is-swiping выключает переход на время жеста): иначе строка тянулась бы за
      пальцем с задержкой и жест ощущался бы вязким. Ставит и снимает класс chat.js (resetSwipe). */
#tab-messages .tc-row { transition: transform .18s ease; }
#tab-messages .tc-row.is-swiping { transition: none; }

/* ⚠️ ВЫДЕЛЕНИЕ ЗАПРЕЩАЕМ ТОЛЬКО ТАМ, ГДЕ НЕТ МЫШИ. На сенсорном вводе долгое нажатие — это ВЫЗОВ МЕНЮ, и
      системное выделение с «лупой» перекрывает его собой: человек целится в «Ответить», а получает панель
      «Скопировать / Найти». Скопировать текст там есть чем — пункт «Копировать» в самом меню.
      На десктопе долгого нажатия не существует вовсе, зато выделение мышью — частая операция, и отнимать её
      нельзя. Поэтому граница модуля здесь та же, что у callout, но действует только на сенсорном вводе.
   ⚠️ РАЗДЕЛЯЕМ ПО ВОЗМОЖНОСТЯМ ВВОДА, А НЕ ПО ШИРИНЕ. Ширина не отвечает на вопрос «есть ли мышь»: узкое
      окно на десктопе — это мышь без места, планшет с клавиатурой — место без мыши. hover: none + pointer:
      coarse описывают ровно то, что нам нужно знать, — что указателя, умеющего наводиться и точно попадать,
      здесь нет.
   ⚠️ ИСКЛЮЧЕНИЕ ТО ЖЕ САМОЕ — ПОЛЯ ВВОДА: без user-select: text в них не встают курсором и не правят
      набранное. Список тегов повторяет isTextEntry, и это единственное место, где он повторён: правишь
      там — правь здесь. */
@media (hover: none) and (pointer: coarse) {
    #tab-messages { -webkit-user-select: none; user-select: none; }
    #tab-messages input,
    #tab-messages textarea,
    #tab-messages [contenteditable=""],
    #tab-messages [contenteditable="true"] { -webkit-user-select: text; user-select: text; }
}
/* Фокус на пузыре виден: он теперь достижим с клавиатуры (tabindex), и без метки непонятно, где ты. */
#tab-messages .tc-bubble:focus-visible { outline: 2px solid var(--fill-accent, #4f46e5); outline-offset: 2px; }

#tab-messages .chat-more {
    display: block; margin: 4px auto 10px; border: 1px solid var(--border, #e5e7eb); background: #fff;
    border-radius: 999px; padding: 5px 14px; font: inherit; font-size: 13px; color: #57606a; cursor: pointer;
}
#tab-messages .chat-more:hover { border-color: #4f46e5; color: #4f46e5; }
#tab-messages .chat-more:disabled { opacity: .6; cursor: default; }

/* ── Чипы выбранных файлов над полем ввода. Контейнер .tc-fileslist — из task-comments.css (там же отступ,
      когда список непуст); здесь только сам чип, которого в эталоне нет: там файлы показывались строкой без
      прогресса и без возможности снять. ── */
/* ⚠️ align-self: flex-start — по той же причине, что у вложений в ленте: .tc-fileslist это flex-колонка, и без
   него чип растягивается во всю ширину композера, превращаясь в строку таблицы вместо пилюли. */
#tab-messages .chat-file {
    display: inline-flex; align-items: center; gap: 6px; position: relative; align-self: flex-start;
    max-width: 100%; padding: 4px 6px 4px 10px; border-radius: 999px;
    background: var(--surface-1, #f4f6fb); font-size: 12px; color: #374151; overflow: hidden;
}
#tab-messages .chat-file--err { background: #fef2f2; color: #b91c1c; }
#tab-messages .chat-file__nm { max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#tab-messages .chat-file__st { flex: none; color: #6b7280; font-variant-numeric: tabular-nums; }
#tab-messages .chat-file--err .chat-file__st { color: #b91c1c; }
#tab-messages .chat-file__st--err { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#tab-messages .chat-file__x { flex: none; border: 0; background: none; padding: 0 2px; color: #9ca3af; font-size: 13px; line-height: 1; cursor: pointer; }
#tab-messages .chat-file__x:hover { color: #d1242f; }
/* Полоса прогресса — по нижнему краю чипа: доля видна, а высоту строки она не меняет. */
#tab-messages .chat-file__bar { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: #e5e7eb; }
#tab-messages .chat-file__bar > span { display: block; height: 100%; background: var(--fill-accent, #4f46e5); transition: width .15s linear; }

/* Размер рядом с именем НЕ-картинки: у .tc-att-item эталон показывает только имя, а в переписке полезно сразу
   видеть, стоит ли открывать файл на мобильном интернете.
   ⚠️ Чип обязан быть ПО СОДЕРЖИМОМУ. Контейнер .tc-att — flex-колонка, и её элементы по умолчанию тянутся на
      всю ширину: имя ломалось на две строки, а размер уезжал к правому краю отдельным столбцом, будто это
      таблица. align-self: flex-start возвращает чипу собственную ширину, nowrap держит размер одной строкой. */
#tab-messages .tc-att-item { align-self: flex-start; max-width: 100%; }
#tab-messages .chat-att-nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#tab-messages .chat-att-size { flex: none; margin-left: 6px; color: #9ca3af; font-size: 12px; white-space: nowrap; }
#tab-messages .tc-bubble--own .chat-att-size { color: rgba(255, 255, 255, .75); }

/* Диалог, в который нельзя писать: вместо поля — объяснение. */
#tab-messages .chat-readonly { padding: 10px 12px; border-radius: 10px; background: #f4f6fb; color: #57606a; font-size: 13px; text-align: center; }

/* ── Строки офлайн-очереди в ленте. Это ещё НЕ сообщения: у них нет id, их нельзя править и удалять, поэтому
      и выглядят они иначе — приглушённо, с состоянием вместо времени. ── */
#tab-messages .chat-row-queued .tc-bubble { opacity: .72; }
#tab-messages .chat-qstate { font-style: italic; }
#tab-messages .chat-qstate--err { color: #fecaca; }
#tab-messages .chat-qbtn {
    margin-left: 8px; border: 0; background: none; padding: 0; font: inherit; font-size: 11px;
    color: #fff; text-decoration: underline; cursor: pointer; opacity: .9;
}
#tab-messages .chat-qbtn:hover { opacity: 1; }

/* ── Строка ассистента 1С: свой тон иконки, без бейджа (счётчика у него нет по замыслу). ── */
/* ⚠️ color ЗДЕСЬ ОБЯЗАТЕЛЕН, а не «унаследуется». База (.chat-ava выше) задаёт белые буквы — они годились
   тёмному фону, но на жёлтом белый текст даёт контраст 1.36:1, то есть «1С» просто исчезает с иконки.
   С #111827 выходит 13.09:1. Тон не новый: им набран текст всего этого файла (:45, :169, :244).
   ⚠️ Жёлтый — ПЯТЫЙ тон в палитре типов (индиго личные / бирюза группы / янтарь поручения / синий заявки,
   :157-163), и главная опасность у него одна — слиться с янтарным в том же списке. Не сливается: ΔE до
   #b45309 равен 66.8 при 35 у amber-500, который для этого и был отвергнут. */
#tab-messages .chat-ava--assistant { background: #ffdc03; color: #111827; font-size: 13px; letter-spacing: .02em; }

/* ── Кнопки-иконки в шапке диалога (участники, действия) ── */
#tab-messages .chat-dlg__icon {
    flex: none; width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center;
    border: 1px solid var(--border, #e5e7eb); border-radius: 50%; background: #fff;
    color: #57606a; font-size: 15px; line-height: 1; cursor: pointer; font-family: inherit;
}
#tab-messages .chat-dlg__icon:hover { border-color: #4f46e5; color: #4f46e5; }

/* ── Экран состава группы (добавление участников): простая колонка форм ──
   ⚠️ Создания диалога тут больше нет: и личный чат, и группа делаются в панели «Новый чат» (.chat-newpanel).
      Осталось только добавление участников в СУЩЕСТВУЮЩУЮ группу — оно живёт в правой колонке. */
#tab-messages .chat-newbox { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; padding: 4px 2px; }
#tab-messages .chat-input {
    width: 100%; box-sizing: border-box; padding: 9px 11px; border: 1px solid var(--border, #e5e7eb);
    border-radius: 10px; font-size: 14px; font-family: inherit;
}
#tab-messages .chat-newactions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 8px; }
#tab-messages .chat-member { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 2px; border-bottom: 1px solid #f0f2f7; }
#tab-messages .chat-member__nm { font-size: 14px; color: #111827; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#tab-messages .chat-member__x { flex: none; border: 0; background: none; padding: 0; font: inherit; font-size: 13px; color: #d1242f; cursor: pointer; }
#tab-messages .chat-leave { margin-top: 12px; border: 0; background: none; padding: 8px 0; font: inherit; font-size: 14px; color: #d1242f; cursor: pointer; text-align: left; }

/* ══════════════════ ПАНЕЛЬ «НОВЫЙ ЧАТ» ══════════════════
   ⚠️ ДВЕ РАСКЛАДКИ ПО ТОМУ ЖЕ ПОРОГУ, что и весь экран: класс задаёт chat.js из matchMedia (см. .is-wide).
      Второго порога здесь нет и быть не должно — иначе поповер и нижний лист начнут переключаться на разных
      ширинах, и появится полоса, где не работает ни то ни другое.
   ⚠️ Нижний лист повторяет геометрию оверлея «Меню» (bottom_nav.php: .bmenu__sheet) — тот же радиус, та же
      подложка, тот же safe-area. Свой вариант отличался бы на пиксели и читался бы как чужой элемент. */
#tab-messages .chat-newpanel { position: fixed; inset: 0; z-index: 60; }
#tab-messages .chat-newpanel__backdrop { position: absolute; inset: 0; background: rgba(15, 23, 42, .42); }
#tab-messages .chat-newpanel__box {
    position: absolute; display: flex; flex-direction: column; background: #fff;
    box-shadow: 0 -10px 34px rgba(15, 23, 42, .2); overflow: hidden;
}
/* Узкий — нижний лист. */
#tab-messages .chat-newpanel--sheet .chat-newpanel__box {
    left: 50%; bottom: 0; transform: translateX(-50%); width: 100%; max-width: 460px;
    box-sizing: border-box; border-radius: 16px 16px 0 0; max-height: 76dvh;
    padding-bottom: calc(8px + env(safe-area-inset-bottom));
}
/* Широкий — поповер под кнопкой «+»: она в правом верхнем углу панели. */
#tab-messages .chat-newpanel--pop .chat-newpanel__backdrop { background: transparent; }
/* ⚠️ top/right — ЗАПАСНЫЕ. Настоящие ставит anchorNewPanel (chat.js) по измеренной кнопке «+»: высота шапки
      зависит от подписи под заголовком и от масштаба шрифта, и одним числом её не описать. Эти значения
      работают, только если измерить не удалось (кнопка скрыта) — тогда поповер хотя бы не улетит за экран. */
#tab-messages .chat-newpanel--pop .chat-newpanel__box {
    right: max(18px, calc((100vw - 1280px) / 2 + 18px)); top: 96px;
    width: 340px; max-height: 60dvh; border-radius: 14px; border: 1px solid #eaeef2;
    box-shadow: 0 18px 40px rgba(15, 23, 42, .18);
}
#tab-messages .chat-newpanel__head { flex: none; display: flex; align-items: center; justify-content: space-between; padding: 12px 14px 8px; }
#tab-messages .chat-newpanel__ttl { font-size: 16px; font-weight: 700; color: #111827; }
#tab-messages .chat-newpanel__x { border: 0; background: none; font-size: 18px; line-height: 1; color: #6b7280; cursor: pointer; padding: 2px 4px; }
#tab-messages .chat-newpanel__search { flex: none; position: relative; padding: 0 14px 10px; }
#tab-messages .chat-newpanel__search .ic { position: absolute; left: 24px; top: 9px; color: #9ca3af; }
#tab-messages .chat-newpanel__search input {
    width: 100%; box-sizing: border-box; padding: 8px 10px 8px 32px; border: 1px solid var(--border, #e5e7eb);
    border-radius: 999px; font-size: 14px; font-family: inherit;
}
#tab-messages .chat-newpanel__list { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 0 8px 8px; }
#tab-messages .chat-np-item {
    display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box;
    padding: 8px 6px; border: 0; border-radius: 10px; background: none;
    font-family: inherit; text-align: left; cursor: pointer;
}
#tab-messages .chat-np-item:hover { background: #f4f6fb; }
#tab-messages .chat-np-item .chat-ava { width: 36px; height: 36px; font-size: 13px; }
#tab-messages .chat-np-item .chat-ava svg { width: 18px; height: 18px; }
#tab-messages .chat-np-item__nm { flex: 1; min-width: 0; font-size: 15px; color: #111827; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* «Новая группа» — отделена от списка людей чертой: это действие, а не собеседник. */
#tab-messages .chat-np-item--group { margin: 0 8px 6px; border-bottom: 1px solid #f0f2f7; border-radius: 10px 10px 0 0; padding-bottom: 12px; }
#tab-messages .chat-np-item--group .chat-np-item__nm { font-weight: 600; }

/* ══════ МАСТЕР ГРУППЫ: три шага внутри той же панели ══════
   ⚠️ Шаги — три контейнера, видимость которых задаёт ОДНА функция (npStep в chat.js) через hidden. Здесь
      только само правило скрытия: показывать и прятать по месту вызова — верный способ однажды увидеть два
      шага сразу или ни одного. */
#tab-messages .chat-np-step[hidden] { display: none; }
#tab-messages .chat-np-step { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }

/* Шапка шагов 2-3: «назад» слева, действие справа, заголовок ровно по центру коробки.
   ⚠️ ЗАГОЛОВОК ВЫНЕСЕН ИЗ ПОТОКА НАМЕРЕННО. Слева иконка (32px), справа текст («Далее» короче, чем
      «Создать») — при любой раскладке долями заголовок сдвигался бы на половину этой разницы и «ездил» от
      шага к шагу. absolute + translateX(-50%) центрирует его по коробке, а не по остатку места. */
#tab-messages .chat-np-head {
    position: relative; flex: none; display: flex; align-items: center; justify-content: space-between;
    gap: 8px; padding: 10px 10px 8px; min-height: 44px;
}
#tab-messages .chat-np-head__t {
    position: absolute; left: 50%; transform: translateX(-50%); text-align: center;
    max-width: calc(100% - 150px);   /* не наезжать на «назад» и на кнопку действия */
    pointer-events: none;            /* заголовок не перехватывает нажатия у кнопок под ним */
}
#tab-messages .chat-np-head__ttl { font-size: 15px; font-weight: 700; color: #111827; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#tab-messages .chat-np-head__sub { font-size: 12px; color: #6b7280; margin-top: 1px; }
#tab-messages .chat-np-back {
    flex: none; width: 32px; height: 32px; display: inline-flex; align-items: center; justify-content: center;
    border: 0; border-radius: 8px; background: none; padding: 0; color: #374151; cursor: pointer;
}
#tab-messages .chat-np-back:hover { background: #f4f6fb; }
#tab-messages .chat-np-act {
    flex: none; border: 0; border-radius: 8px; padding: 7px 12px; background: none;
    font-family: inherit; font-size: 14px; font-weight: 600; color: var(--fill-accent, #4f46e5); cursor: pointer;
}
#tab-messages .chat-np-act:hover:not(:disabled) { background: rgba(79, 70, 229, .10); }
/* ⚠️ Заблокированная кнопка обязана ВЫГЛЯДЕТЬ заблокированной. disabled без вида — это кнопка, которая
      молча не работает: человек жмёт её и решает, что сломано приложение. */
#tab-messages .chat-np-act:disabled { color: #9ca3af; cursor: default; }

/* Галочка выбора на шаге 2. Пустой контур → залитый акцентом кружок с птицей. */
#tab-messages .chat-np-check {
    flex: none; width: 20px; height: 20px; margin-left: auto; box-sizing: border-box;
    display: inline-flex; align-items: center; justify-content: center;
    border: 1.5px solid #d0d7de; border-radius: 50%; color: transparent;
}
#tab-messages .chat-np-check.is-on { background: var(--fill-accent, #4f46e5); border-color: var(--fill-accent, #4f46e5); color: #fff; }
/* Строка выбранного на шаге 3 — не кнопка: нажимать там нечего, состав меняется шагом «назад». */
#tab-messages .chat-np-item--static { cursor: default; }
#tab-messages .chat-np-item--static:hover { background: none; }

/* Шаг 3: название группы. */
#tab-messages .chat-np-name { flex: none; padding: 2px 14px 8px; }
#tab-messages .chat-np-name .chat-input { width: 100%; box-sizing: border-box; }
#tab-messages .chat-np-name .msg { min-height: 0; margin-top: 6px; }
#tab-messages .chat-np-chosen-ttl { flex: none; padding: 0 16px 6px; font-size: 12px; font-weight: 600; color: #6b7280; text-transform: uppercase; letter-spacing: .02em; }

/* ══════════════════ ЦИТАТА (ответ на сообщение) ══════════════════
   ⚠️ Полоска слева + приглушённый текст — та же идея, что у .eh-row::before в поручениях: цитата обязана
      читаться как ВСТАВКА в пузырь, а не как ещё одно сообщение. Своей рамки и фона у неё нет намеренно —
      два вложенных прямоугольника в ленте создают ощущение, что сообщений вдвое больше, чем есть. */
#tab-messages .chat-reply {
    display: flex; flex-direction: column; gap: 1px; width: 100%; box-sizing: border-box;
    margin: 0 0 6px; padding: 3px 0 3px 8px; border: 0; border-left: 2px solid currentColor;
    background: none; font: inherit; text-align: left; color: inherit; opacity: .78;
}
/* Кликабельна ТОЛЬКО когда оригинал в ленте — вид отличается, чтобы «нажал и ничего» не выглядело поломкой. */
#tab-messages .chat-reply--go { cursor: pointer; }
#tab-messages .chat-reply--go:hover { opacity: 1; }
#tab-messages .chat-reply__nm { font-size: 12px; font-weight: 700; }
#tab-messages .chat-reply__tx { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#tab-messages .chat-reply__tx--gone { font-style: italic; opacity: .8; }
/* Подсветка оригинала после перехода: короткая вспышка, потом сама гаснет. */
#tab-messages .tc-row.is-flash .tc-bubble { animation: chatFlash 1.2s ease-out; }
@keyframes chatFlash { 0%, 40% { background: rgba(79, 70, 229, .18); } 100% { background: none; } }

/* Панель «отвечаете на …» над полем ввода. */
#tab-messages .chat-replybar {
    display: flex; align-items: center; gap: 8px; padding: 6px 10px; margin-bottom: 6px;
    border-left: 2px solid var(--fill-accent, #4f46e5); border-radius: 0 8px 8px 0; background: #f4f6fb;
}
#tab-messages .chat-replybar[hidden] { display: none; }
#tab-messages .chat-replybar__ic { flex: none; color: var(--fill-accent, #4f46e5); font-size: 14px; }
#tab-messages .chat-replybar__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; color: #374151; }
#tab-messages .chat-replybar__x { flex: none; border: 0; background: none; padding: 2px 4px; font-size: 15px; line-height: 1; color: #6b7280; cursor: pointer; }
#tab-messages .chat-replybar__x:hover { color: #111827; }

/* ══════════════════ КОНТЕКСТНОЕ МЕНЮ ══════════════════
   ⚠️ ОБОЛОЧКА ПЕРЕИСПОЛЬЗУЕТСЯ, а не дублируется: .chat-newpanel даёт подложку, поповер на широком и нижний
      лист на узком, .chat-ctx — только вид самих пунктов. Свой оверлей рядом с существующим означал бы два
      всплывающих окна в одном модуле, с разной геометрией и разным закрытием. */
#tab-messages .chat-ctx .chat-newpanel__box { padding: 6px; }
/* ⚠️ Ширина по содержимому, но не шире экрана: на 360px коробка в 280px плюс отступы ещё помещается, а на
      узких Android-экранах — уже нет, и её обрезало бы краем. max-height тоже своя: у списка из трёх пунктов
      60dvh панели «Новый чат» ни к чему, а вот у длинного меню прокрутка нужнее, чем уход за край. */
#tab-messages .chat-newpanel--pop.chat-ctx .chat-newpanel__box {
    width: auto; min-width: 200px; max-width: min(280px, calc(100vw - 16px)); max-height: min(60dvh, calc(100dvh - 16px));
}
#tab-messages .chat-ctx__item {
    display: block; width: 100%; box-sizing: border-box; padding: 10px 12px;
    border: 0; border-radius: 8px; background: none; font-family: inherit; font-size: 15px;
    color: #111827; text-align: left; cursor: pointer; white-space: nowrap;
}
#tab-messages .chat-ctx__item:hover { background: #f4f6fb; }
/* Разрушающее действие — красным, как .chat-leave и кнопки danger в ui-dialogs. */
#tab-messages .chat-ctx__item--danger { color: #d1242f; }
#tab-messages .chat-ctx__item--danger:hover { background: rgba(209, 36, 47, .08); }

/* ══════════════════ ШАПКА РАЗДЕЛА НА УЗКОМ ЭКРАНЕ ══════════════════
   ⚠️ В ОТКРЫТОМ ДИАЛОГЕ ШАПКА «Чат / N чатов» И КНОПКА СОЗДАНИЯ ПРЯЧУТСЯ. Они относятся к СПИСКУ, а на узком
      экране списка в этот момент не видно: заголовок раздела над чужой перепиской не сообщает ничего, зато
      занимает строку, которой не хватает ленте — особенно с открытой клавиатурой.
   ⚠️ Условие — ДВА УЖЕ СУЩЕСТВУЮЩИХ КЛАССА (.is-dialog и отсутствие .is-wide), оба ставит showScreen. Третьего
      переключателя не заводим: он неизбежно разошёлся бы с раскладкой, которую эти классы и описывают.
   ⚠️ На широком шапка ОСТАЁТСЯ ЦЕЛИКОМ: там список виден слева, и заголовок раздела относится именно к нему. */
#tab-messages .chat-wrap.is-dialog:not(.is-wide) > .chat-head { display: none; }

/* ⚠️ НА УЗКОМ ЗАГОЛОВОК РАЗДЕЛА УБРАН И СО СПИСКА. «Чат» и «7 диалогов, 2 непрочитанных» не отвечают ни на
      один вопрос человека, который уже открыл вкладку «Чат» и видит эти диалоги перед собой, — а строку
      занимают. Кнопка создания остаётся: она действие, а не подпись.
   ⚠️ ЧИСЛО НЕПРОЧИТАННЫХ НЕ ПОТЕРЯНО — оно живёт в бейдже нижней панели (chat.js: setNavChat из
      unread_total), и там оно полезнее: видно с любой вкладки, а не только когда ты уже в чате.
   ⚠️ Отрицательный отступ кнопки сбрасываем: он поднимал её к строке заголовка, которой здесь больше нет. */
#tab-messages .chat-wrap:not(.is-wide) > .chat-head > .chat-head__t { display: none; }

/* ══════ УЗКИЙ ЭКРАН: КНОПКА «НОВЫЙ ЧАТ» — В СТРОКЕ ЧИПОВ ══════
   ⚠️ ОСВОБОДИВШАЯСЯ СТРОКА ОТДАНА СПИСКУ. После снятия заголовка шапка осталась ради одной кнопки и занимала
      целую строку ни за чем. Кнопка переезжает в ряд фильтров — там она рядом с тем, чем управляют, и высота
      возвращается списку.
   ⚠️ КНОПКА РЯДОМ С РЯДОМ ЧИПОВ, А НЕ ВНУТРИ НЕГО. Чипы прокручиваются горизонтально; будь кнопка их
      соседом по потоку, она уезжала бы вместе с ними и пропадала с экрана ровно тогда, когда до неё тянутся.
      Поэтому шапка выносится из потока и стоит поверх правого края ряда.
   ⚠️ ФОН У ШАПКИ ОБЯЗАТЕЛЕН: чипы прокручиваются ПОД ней, и без подложки они просвечивали бы сквозь иконку.
      Цвет — фон страницы (--bg), тот же, на котором лежит панель.
   ⚠️ ПУСТУЮ СТРОКУ ОШИБКИ СХЛОПЫВАЕМ. .msg держит min-height: 16px под будущий текст; пока текста нет, эти
      16 пикселей сдвигали бы ряд чипов вниз, и кнопка, привязанная к верху, не совпала бы с ним. */
#tab-messages .chat-wrap:not(.is-wide) { position: relative; }
/* ⚠️ ОТСЧЁТ ОТ НИЗА ПОИСКА, А НЕ ОТ ВЕРХА ОБЁРТКИ. Кнопка стоит в ряду ЧИПОВ, а ряд теперь второй — первым
      идёт поиск. Числа берём из его же переменных: одно место, обе величины следуют за ним сами. */
#tab-messages .chat-wrap:not(.is-wide) > .chat-head {
    position: absolute; top: calc(var(--chat-search-h, 38px) + var(--chat-search-gap, 10px));
    right: 0; z-index: 3; margin: 0; height: 40px;
    align-items: center; justify-content: flex-end; padding-left: 8px; padding-right: 4px;
    background: var(--bg, #f4f6fb);
}
/* ⚠️ Отступ сверху здесь СБРАСЫВАЕМ. Он считался от строки заголовка, которой на узком нет вовсе; оставь
      его — и кружок повиснет на пару пикселей выше центра ряда чипов. Совмещение проверяется ПО ЦЕНТРАМ:
      у чипа высота ~30px, у кружка 38px, верхние края у них совпасть не могут в принципе. */
#tab-messages .chat-wrap:not(.is-wide) > .chat-head > .chat-add { margin-top: 0; }
#tab-messages .chat-wrap:not(.is-wide) > .msg:empty { min-height: 0; }
/* Ряд чипов той же высоты, что кнопка, — иначе они стоят на разных уровнях. Отступ справа — место под кнопку:
   последний чип не должен доезжать до неё и прятаться под подложкой. */
/* ⚠️ ЗАЗОР ДО СПИСКА — margin, А НЕ padding. При box-sizing: border-box нижний padding входит в min-height:
      ряд остаётся высотой 40, но содержимое центрируется в оставшихся 32 — и чип встаёт на 4 пикселя выше
      центра кружка, который центрируется по своим честным 40. Замер это и показал. margin в высоту блока не
      входит, поэтому обе коробки ровно 40, и центры совпадают. */
#tab-messages .chat-wrap:not(.is-wide) .chat-chips {
    min-height: 40px; align-items: center; padding: 0 46px 0 10px; margin-bottom: 8px;
}

/* ══════ УЗКИЙ ЭКРАН: ПОЛЯ ВОКРУГ ЛЕНТЫ И СПИСКА — МИНИМАЛЬНЫЕ ══════
   ⚠️ БОКОВЫЕ И ВЕРХНИЙ ОТСТУПЫ У ОБЁРТКИ СНЯТЫ, а не уменьшены: 18 пикселей с каждой стороны на экране в 390
      это почти десятая часть ширины, отданная пустоте. Содержимое держит собственный отступ в 10 пикселей —
      столько, чтобы аватар, время и пузыри не слипались с краями, и не больше.
   ⚠️ СКРУГЛЕНИЕ КАРТОЧКИ ДИАЛОГА НА УЗКОМ УБРАНО. При нулевых полях оно упирается в края экрана и перестаёт
      читаться как форма: получается белый прямоугольник со срезанными углами, а не карточка. На широком
      скругление остаётся — там карточка лежит на фоне и границы видны. */
#tab-messages .chat-wrap:not(.is-wide) { padding-top: 0; padding-left: 0; padding-right: 0; }
#tab-messages .chat-wrap:not(.is-wide) .chat-dlg { border-radius: 0; padding: 10px 0 0; }
#tab-messages .chat-wrap:not(.is-wide) .chat-dlg__head { padding-left: 10px; padding-right: 10px; }
#tab-messages .chat-wrap:not(.is-wide) .chat-compose { padding-left: 10px; padding-right: 10px; }
#tab-messages .chat-wrap:not(.is-wide) .chat-row { padding-left: 10px; padding-right: 10px; }
/* Поиск на узком — с теми же боковыми полями, что и содержимое: обёртка их не даёт. */
#tab-messages .chat-wrap:not(.is-wide) .chat-search { margin-left: 10px; margin-right: 10px; }
