/* ============================================================
   AVE DM — стили вкладки мессенджера (E2 роадмапа).
   Значения СВЕРЕНЫ с исходником прототипа (source/AVE Chat.dc.html, блок `showMessages`,
   строки ~466-560, плюс JS-маппер `dmConversations`/`activeDM` в renderVals) — не с прикидкой
   на глаз. Где значения не расходятся значимо с уже проверенным чатом каналов (например
   .msg/.msg-avatar), они по-прежнему ПЕРЕИСПОЛЬЗУЮТСЯ из ave-chat.css напрямую.

   [2026-07-04] #dm-pane ограничен РЯДОМ 2 грида .app — персистентная шапка (.main-head, ДНБ/
   самочувствие/уведомления/команда) теперь отдельный элемент ряда 1 (см. style.css/index.html),
   по прототипу она ВСЕГДА видна, ни одна вкладка её не перекрывает. #dm-pane сам по-прежнему
   непрозрачный на всю свою область (ряд 2) — картинка-«поле» под ним видна только вокруг
   центрированной карточки .dm-stage у #tasks-pane/.bds-overlay; для мессенджера решил не
   усложнять (решение №11 не обязательно один-в-один для каждой новой панели).
   ============================================================ */

/* ---------- каркас / грид ---------- */
.ave-root #dm-pane { display: none; }
body.ave-root.dm-active #dm-pane {
  display: flex; flex-direction: column; grid-column: 2 / -1; grid-row: 2; min-width: 0; min-height: 0;
  /* E-fin-3: прозрачный фон — карточка .dm-stage «плывёт на поле», как #tasks-pane/.bds-overlay. Раньше
     тут был сплошной var(--bg) (обход просвечивавшей шапки, до структурного фикса .main-head) — причина
     ушла, фон возвращён к прозрачному. #main под панелью и так скрыт (body.dm-active #main{display:none}). */
  background: transparent; color: var(--ink-dim);
}
/* по образцу tasks-ui.js/boards-ui.js (у обоих уже было ровно такое правило для tk-active/bds-open —
   я его не добавил при первой сборке мессенджера, хотя сам приём давно устоялся в проекте) */
body.dm-active #main, body.dm-active aside.members { display: none !important; }

/* ---------- карточка мессенджера (1-в-1 из прототипа: width:calc(100% - 32px);max-width:1040px;
   margin:14px auto;border-radius:14px;overflow:hidden;flex-direction:row) ---------- */
.ave-root .dm-stage {
  flex: 1; min-height: 0; width: calc(100% - 32px); max-width: 1040px; margin: 14px auto;
  display: flex; flex-direction: row;
  background: color-mix(in srgb, var(--panel) 30%, var(--bg));
  border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
  box-shadow: var(--shadow-sm);
}

/* ---------- левая колонка: список диалогов (248px, из прототипа) ---------- */
.ave-root .dm-list-col {
  width: 248px; flex: none; display: flex; flex-direction: column; min-height: 0;
  border-right: 1px solid var(--line);
  background: color-mix(in srgb, var(--panel) 75%, var(--bg)); /* [фикс скрина владельца] было 45% — темновато, попросили светлее */
}
.ave-root .dm-list-head { flex: none; padding: 16px 15px 13px; border-bottom: 1px solid var(--line-2); }
.ave-root .dm-list-headrow { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.ave-root .dm-list-title { font: 600 13px var(--font-mono); color: var(--ink-dim); }
.ave-root .dm-top-sp { flex: 1; }
.ave-root .dm-iconbtn {
  width: 30px; height: 30px; border-radius: 9px; flex: none; padding: 0;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
}
.ave-root .dm-composebtn {
  background: color-mix(in srgb, var(--ch-text) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--ch-text) 36%, transparent); color: var(--ch-text);
}
.ave-root .dm-composebtn:hover { background: color-mix(in srgb, var(--ch-text) 22%, transparent); }
.ave-root .dm-closebtn { background: transparent; border: 1px solid var(--line-2); color: var(--muted); font-size: 13px; }
.ave-root .dm-closebtn:hover { background: var(--panel-2); color: var(--ink); }
/* [фикс скрина владельца] кнопка «Команда» — тот же вид, что у соседней кнопки закрытия, явно
   заданный (без этого была бы та же «белая плашка», что уже ловили у скрепки) */
.ave-root #dm-team-btn { background: transparent; border: 1px solid var(--line-2); }
.ave-root #dm-team-btn:hover { background: var(--panel-2); }
/* [фидбек владельца, боевой тест] активный тумблер «начать новый чат» — сигнальный тинт (как активные фильтры) */
.ave-root #dm-team-btn.active {
  background: color-mix(in srgb, var(--signal) 16%, transparent);
  border-color: color-mix(in srgb, var(--signal) 42%, transparent);
}
/* [фикс скрина владельца] кнопка вложения без плашки совсем — раньше наследовала браузерные
   дефолты <button> (сероватый фон+рамка), выглядело как «белая плашка»; убираем полностью,
   лёгкая подсветка остаётся только по наведению как обратная связь. */
.ave-root #dm-attach-btn { background: transparent; border: none; }
.ave-root #dm-attach-btn:hover { background: var(--field); }
/* поиск по людям — из прототипа дословно (искал заново под именем "Поиск по людям…") */
/* [фикс скрина владельца] прошлый раз сузил (width:50%) — оказалось, наоборот, нужно шире по
   ширине, но ниже (компактнее) по высоте. Вертикальный паддинг вдвое меньше (8px→4px). */
.ave-root .dm-search {
  display: flex; align-items: center; gap: 8px;
  background: var(--field); border: 1px solid var(--line); border-radius: 10px; padding: 4px 11px;
}
.ave-root .dm-search svg { color: var(--muted-2); flex: none; }
.ave-root #dm-search-input {
  flex: 1; min-width: 0; border: none; background: transparent; outline: none;
  font: 500 12.5px var(--font-mono); color: var(--ink-dim);
}
.ave-root #dm-search-input::placeholder { color: var(--muted-2); }

/* ---------- список диалогов ---------- */
.ave-root .dm-list { flex: 1; min-height: 0; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 3px; }
.ave-root .dm-list-empty { padding: 24px 14px; color: var(--muted-2); font: 12.5px var(--font-mono); text-align: center; line-height: 1.5; }
.ave-root .dm-row {
  position: relative; display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  cursor: pointer; border: 1px solid transparent; background: transparent; border-radius: 12px; padding: 9px 10px;
  transition: background .12s, border-color .12s;
}
.ave-root .dm-row:hover { background: var(--field); }
.ave-root .dm-row.active {
  border-color: color-mix(in srgb, var(--ch-text) 40%, transparent);
  background: color-mix(in srgb, var(--ch-text) 13%, transparent);
}
.ave-root .dm-row.active:hover { background: color-mix(in srgb, var(--ch-text) 13%, transparent); }
.ave-root .dm-row-avwrap, .ave-root .dm-conv-avwrap { position: relative; flex: none; }
.ave-root .dm-row-av {
  width: 40px; height: 40px; border-radius: 12px; border: 1px solid var(--line);
  background-position: center; background-size: cover; background-color: var(--panel-2);
  display: flex; align-items: center; justify-content: center; font: var(--fw-bold) 15px var(--font-mono); color: var(--muted);
}
.ave-root .dm-row-dot, .ave-root .dm-conv-dot {
  position: absolute; right: -2px; bottom: -2px; width: 11px; height: 11px; border-radius: 50%;
  border: 2.5px solid var(--panel); background: var(--muted-2);
}
.ave-root .dm-row-dot.online, .ave-root .dm-conv-dot.online { background: var(--ok); box-shadow: 0 0 7px -1px var(--ok); }
.ave-root .dm-row-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ave-root .dm-row-top { display: flex; align-items: baseline; gap: 8px; }
.ave-root .dm-row-name {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 700 13.5px var(--font-mono); color: var(--ink-dim);
}
.ave-root .dm-row.active .dm-row-name { color: var(--ink); }
.ave-root .dm-row.has-unread .dm-row-name { font-weight: 800; }
.ave-root .dm-row-time { flex: none; font: 500 9.5px/1 var(--font-mono); color: var(--muted-2); }
.ave-root .dm-row-bottom { display: flex; align-items: center; gap: 7px; }
.ave-root .dm-row-prev {
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font: 500 11.5px/1.3 var(--font-mono); color: var(--muted-2);
}
.ave-root .dm-row.has-unread .dm-row-prev { font-weight: 600; color: var(--ink-dim); }
.ave-root .dm-row-badge {
  flex: none; min-width: 17px; height: 17px; padding: 0 5px; border-radius: 9px;
  display: inline-flex; align-items: center; justify-content: center;
  font: 700 10px/1 var(--font-mono); background: var(--signal); color: var(--on-signal);
}
/* «начать переписку» — не из прототипа (там отдельного экрана поиска/старта нет за пределами
   этого же списка), собственная минимальная пометка, чтобы не путать с уже открытым диалогом */
.ave-root .dm-row-new .dm-row-prev { color: var(--ch-text); font-style: italic; }

/* ---------- правая колонка: диалог / пустое состояние ---------- */
.ave-root .dm-conv-col { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.ave-root .dm-conv-empty {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 24px; text-align: center;
}
.ave-root .dm-conv-empty-ic {
  width: 66px; height: 66px; border-radius: 20px; display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--ch-text) 11%, transparent);
  border: 1px solid color-mix(in srgb, var(--ch-text) 26%, transparent); color: var(--ch-text);
}
.ave-root .dm-conv-empty-tt { font: 700 16px var(--font-mono); color: var(--ink); }
.ave-root .dm-conv-empty-sub { font: 500 13px/1.5 var(--font-mono); color: var(--muted-2); max-width: 300px; margin-top: 5px; }
.ave-root .dm-conv { flex: 1; display: flex; flex-direction: column; min-height: 0; }
.ave-root .dm-conv-head { display: flex; align-items: center; gap: 11px; padding: 12px 18px; border-bottom: 1px solid var(--line); flex: none; }
.ave-root .dm-conv-avatar {
  width: 38px; height: 38px; border-radius: 11px; border: 1px solid var(--line);
  background-position: center; background-size: cover; background-color: var(--panel-2);
  display: flex; align-items: center; justify-content: center; font: var(--fw-bold) 13px var(--font-mono); color: var(--muted);
}
.ave-root .dm-conv-headinfo { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ave-root .dm-conv-name { font: 700 14.5px var(--font-mono); color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ave-root .dm-conv-status { font: 500 11px/1 var(--font-mono); color: var(--muted-2); }
.ave-root .dm-conv-status.typing { color: var(--signal); }

/* ---------- сообщения — переиспользуют .msg/.msg-avatar/.msg-text и т.д. из ave-chat.css;
   отступ скролл-зоны — из прототипа (padding:18px 22px) ---------- */
.ave-root #dm-messages { flex: 1; overflow-y: auto; padding: 18px 22px; }

/* [блок 3] подгрузка старой истории — простая строка-кнопка над списком, не автоскролл-триггер
   (владелец не просил бесконечный скролл, кнопка — контролируемее и меньше кода) */
.ave-root .dm-loadmore { display: flex; justify-content: center; padding: 10px 0 0; flex: none; }
.ave-root .dm-loadmore.hidden { display: none; }
.ave-root #dm-loadmore-btn {
  font: var(--fw-medium) 12px var(--font-mono); padding: 7px 14px; border-radius: 9px;
  background: var(--field); border: 1px solid var(--line-2); color: var(--muted); cursor: pointer;
}
.ave-root #dm-loadmore-btn:hover:not(:disabled) { background: var(--panel-2); color: var(--ink); }
.ave-root #dm-loadmore-btn:disabled { opacity: .6; cursor: default; }

/* [правка владельца, скрин ТГ] отдельный, более читаемый шрифт для самой переписки (не моно AVE) —
   владелец сравнил с ТГ и попросил что-то попроще; системный sans-serif стек, тот же, что
   использует сам Telegram Web. Токена под это в AVE нет — берём буквально, как и hex-цвета у
   canvas-иконок (харнес это уже не считает нарушением токенов, т.к. это не цвет). */
.ave-root #dm-messages .msg-text,
.ave-root #dm-messages .msg-time-foot, .ave-root #dm-messages .msg-edited,
.ave-root #dm-emoji-pop button {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}
.ave-root #dm-messages .msg-text { font-size: 14.5px; line-height: 1.45; }

/* [правка владельца, скрин ТГ] «пузыри» сообщений: у каждого своя мягкая плашка-фон (не только
   по hover, как раньше — общий приём ave-chat.css для каналов, там сообщения одним потоком без
   пузырей, эту схему туда НЕ переносил — Фаза 3/парити канала уже принята роадмапом, не трогаю).
   Свои/чужие — разным цветом; ответ/цитата внутри пузыря — уже свой акцент (--ch-text), просто
   теперь виден на фоне плашки, а не голого поля. */
.ave-root #dm-messages .msg { max-width: 78%; padding: 0; margin: 12px 0 0; }
.ave-root #dm-messages .msg.cont { margin-top: 6px; } /* [фикс скрина владельца] было margin-top:-2px при margin-bottom:2px у соседа — схлопывалось почти в 0, пузыри визуально сливались/наслаивались. Теперь только margin-top, без коллапса с отрицательными числами: 12px между разными отправителями, 6px — видимый, но плотный зазор между подряд идущими своими. */
/* [правка владельца] в ЛС больше нет ни аватарки, ни шапки с ником ни у кого — а общее правило
   ave-chat.css `.msg.cont > .msg-body{margin-left:50px}` (отступ под аватар у каналов) селектором
   НЕ ограничено контейнером и продолжает действовать и здесь, раз не переопределить явно.
   Обнуляю — отступать тут больше не подо что. */
.ave-root #dm-messages .msg.cont > .msg-body { margin-left: 0; }
.ave-root #dm-messages .msg:hover { background: transparent; } /* отменяем общий hover-фон ave-chat.css — фон теперь у .msg-body всегда, не по наведению */
.ave-root #dm-messages .msg-body {
  flex: 0 1 auto; min-width: 0;
  background: var(--panel-2); border-radius: 15px; padding: 7px 12px 6px;
  transition: filter .1s;
}
.ave-root #dm-messages .msg:hover .msg-body { filter: brightness(1.08); }
.ave-root #dm-messages .msg.mine .msg-body { background: color-mix(in srgb, var(--ch-text) 20%, var(--panel-2)); }
.ave-root #dm-messages .msg.is-pinned .msg-body { background: color-mix(in srgb, var(--carrot) 16%, var(--panel-2)); }
.ave-root #dm-messages .msg.is-pinned.mine .msg-body { background: color-mix(in srgb, var(--carrot) 16%, color-mix(in srgb, var(--ch-text) 20%, var(--panel-2))); }
/* [правка владельца, скрин ТГ] время — ВСЕГДА внизу пузыря, правее текста, у КАЖДОГО сообщения
   (раньше было только у первого в группе, в шапке рядом с именем — убрано оттуда полностью). */
.ave-root #dm-messages .msg-time-foot { display: block; margin-top: 2px; font-size: 11px; color: var(--muted-2); text-align: right; }

/* [фикс скрина владельца] стандартный вид ЛС: свои сообщения — справа, собеседника — слева.
   В общем чате каналов (.msg в ave-chat.css) такого деления нет и не нужно — там много участников,
   это чисто ЛС-паттерн, поэтому правило живёт здесь, а не в общем ave-chat.css. */
/* [фикс скрина владельца — реальный баг с прошлого апдейта] «мои» пузыри уезжали не в правый
   край, а куда-то в середину. Причина: .msg — блочный flex-контейнер шириной ДО 78% (сам занимает
   всю эту полосу, а не только место под текст), а .msg-body внутри — flex:0 1 auto (по контенту).
   margin-left:auto двигает вправо ВСЮ 78%-широкую полосу-.msg, но без justify-content пузырь
   внутри неё всё равно жмётся к ЛЕВОМУ краю этой невидимой полосы — то есть просто «уезжал» не
   до истинного правого края экрана, а до правого края невидимого 78%-контейнера минус его же
   ширина. Раньше это маскировал flex-direction:row-reverse — я его убрал в апдейте «без аватарки»,
   посчитав бесполезным (визуально нечего реверсировать с одним ребёнком) — но row-reverse ЗАОДНО
   переопределяет, к какому краю крепится justify-content:flex-start по умолчанию; без него пузырь
   вернулся к обычному «прижат к началу», а не к концу. Правильный фикс — explicit
   justify-content:flex-end, не полагаться на побочный эффект row-reverse. */
.ave-root #dm-messages .msg.mine { margin-left: auto; justify-content: flex-end; }
/* [правка владельца, скрин ТГ] «сравни ориентацию текста нашу и ТГ» — текст ВСЕГДА слева, разным
   выравнивается только положение самого пузыря (справа/слева), не текст внутри него. */
.ave-root #dm-messages .msg.mine .reactions { justify-content: flex-end; }
/* [блок 2] превью ответа у своих сообщений — зеркалим акцентную полосу на правый край */
.ave-root #dm-messages .msg.mine .reply-quote {
  flex-direction: row-reverse; margin-left: auto;
  border-left: none; border-right: 2px solid var(--ch-text); border-radius: 7px 0 0 7px;
}
/* кнопка «Цитировать», всплывающая у выделенного текста (position:fixed — как у .react-pick) */
.ave-root .msg-quote-btn {
  position: fixed; z-index: 70; display: flex; align-items: center; gap: 5px;
  padding: 7px 12px; border-radius: 9px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--ink); font: var(--fw-medium) 12.5px var(--font-mono);
  cursor: pointer; box-shadow: var(--shadow-float);
}
.ave-root .msg-quote-btn:hover { border-color: var(--signal); color: var(--signal); }

/* ---------- композер — наследует .composer/.btn-primary из ave-chat.css (общий класс),
   здесь — точечные поправки под конкретные цифры ЭТОГО экрана из прототипа ---------- */
/* [правка владельца, скрин ТГ] align-items:flex-end — когда textarea растёт вверх, кнопки
   (скрепка/эмодзи/отправить) остаются прижаты к НИЗУ композера, а не едут вверх вместе с полем,
   как в любом мессенджере. Раньше был center — годился для однострочного input. */
.ave-root .dm-composer { padding: 14px 18px; gap: 9px; align-items: flex-end; }
.ave-root #dm-composer-input {
  flex: 1; padding: 10px 12px; border-radius: 8px; resize: none; overflow-y: hidden;
  border: 1px solid var(--line); background: var(--field); color: var(--ink);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px; line-height: 1.4;
}
.ave-root #dm-composer-input::placeholder { color: var(--muted-2); }
.ave-root #dm-composer-input:focus {
  outline: none; border-color: color-mix(in srgb, var(--signal) 55%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--signal) 14%, transparent);
}
/* [правка владельца, скрин ТГ] кнопка «Отправить» — была широкой текстовой плашкой, теперь
   квадратная иконочная (тот же приём, что у Telegram: акцентный фон остаётся, текст убран,
   вместо него — пиксельная стрелка) */
.ave-root .dm-composer .btn-primary.dm-sendbtn {
  width: 38px; height: 38px; padding: 0; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
}
/* [правка владельца, скрин ТГ] кнопка эмодзи — слева от «Отправить», тот же .dm-iconbtn, без
   плашки в покое (тот же принцип, что уже сделан для скрепки) */
.ave-root #dm-emoji-btn { background: transparent; border: none; font-size: 17px; }
.ave-root #dm-emoji-btn:hover { background: var(--field); }
/* всплывающий эмодзи-пикер композера — своя, DM-специфичная разметка (ID, не общий класс
   .emoji-pop — тот совпадает с попапом основного чата каналов, стилить его отсюда было бы
   риском задеть чужой экран; #dm-emoji-pop гарантированно бьёт только по этому попапу) */
.ave-root #dm-emoji-pop {
  position: absolute; right: 14px; bottom: 62px; z-index: 65;
  width: 280px; max-height: 220px; overflow-y: auto;
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 13px;
  padding: 9px; box-shadow: var(--shadow-float);
}
.ave-root #dm-emoji-pop button { background: transparent; border: none; border-radius: 7px; font-size: 19px; padding: 5px; line-height: 1; cursor: pointer; }
.ave-root #dm-emoji-pop button:hover { background: var(--field); }
/* [фикс скрина владельца — ИСПРАВЛЕНО, прошлая версия чинила не то] юзербар «в эфире · N»
   (position:fixed, bottom:14px, см. ave-office.css) должен быть визуально СНАРУЖИ окна ЛС, а не
   торчать отдельно от него с дырой внутри. Прошлый приём (margin-bottom на #dm-composer) двигал
   вверх только поле ввода — а САМА карточка `.dm-stage` (видимая рамка окна) как была высотой во
   весь #dm-pane, так и осталась: внутри окна образовывалась пустая полоса ПОД композером, а
   юзербар при этом оставался снаружи, у самого низа экрана — окно визуально «не доходило» до
   юзербара, а обрывалось где-то с дыркой внутри. Правильно — сжимать саму карточку `.dm-stage`
   целиком (margin-bottom вместо базовых 14px), тогда composer, будучи последним элементом
   внутри неё, сам естественно окажется у НОВОГО, более высокого нижнего края — без своего
   отдельного margin-bottom (убрал, дублировал бы отступ). */
.ave-ub-on.ave-root .dm-stage { margin-bottom: 72px; }

/* [блок 3] кнопка «Закреплённые» в шапке диалога — переиспользует .dm-iconbtn (тот же вид, что
   у карандаша/крестика в списке диалогов слева) */
.ave-root #dm-pins-btn { background: transparent; border: 1px solid var(--line-2); color: var(--muted); }
.ave-root #dm-pins-btn:hover { background: var(--panel-2); color: var(--ink); }

/* [блок 3] панель закреплённых — своя AVE-нативная разметка (не переиспользует старую .pins-panel
   из app.js, та ещё не переведена на токены, см. F5 в роадмапе) */
.ave-root .dm-pins-panel {
  position: fixed; z-index: 70; width: 320px; max-height: 400px; display: flex; flex-direction: column;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 13px; box-shadow: var(--shadow-float);
}
.ave-root .dm-pins-head { display: flex; align-items: center; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--line-2); flex: none; }
.ave-root .dm-pins-title { flex: 1; font: var(--fw-semibold) 13.5px var(--font-mono); color: var(--ink); }
.ave-root .dm-pins-close {
  flex: none; width: 24px; height: 24px; border-radius: 7px; border: none; background: transparent;
  color: var(--muted); font-size: 15px; line-height: 1; cursor: pointer;
}
.ave-root .dm-pins-close:hover { background: var(--field); color: var(--ink); }
.ave-root .dm-pins-list { overflow-y: auto; padding: 7px; display: flex; flex-direction: column; gap: 3px; }
.ave-root .dm-pins-empty { padding: 20px 10px; color: var(--muted-2); font: 12.5px var(--font-mono); text-align: center; line-height: 1.5; }
.ave-root .dm-pins-row { padding: 9px 10px; border-radius: 9px; cursor: pointer; }
.ave-root .dm-pins-row:hover { background: var(--field); }
.ave-root .dm-pins-row-top { display: flex; align-items: baseline; gap: 7px; margin-bottom: 2px; }
.ave-root .dm-pins-row-author { font: var(--fw-semibold) 12.5px var(--font-mono); color: var(--ink); }
.ave-root .dm-pins-row-time { font: 10.5px var(--font-mono); color: var(--muted-2); }
.ave-root .dm-pins-row-text { font: 12.5px var(--font-mono); color: var(--ink-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ave-root .dm-pins-row-unpin {
  margin-top: 5px; font: var(--fw-medium) 11px var(--font-mono); padding: 4px 9px; border-radius: 7px;
  background: transparent; border: 1px solid var(--line-2); color: var(--muted); cursor: pointer;
}
.ave-root .dm-pins-row-unpin:hover { border-color: var(--danger); color: var(--danger); }

/* [правка владельца, скрин ТГ] контекстное меню по ПКМ — ряд быстрых реакций + список действий,
   заменяет прежнюю hover-панель (.ave-msg-actions). Своя разметка (не переиспользует старое
   .pins-panel-подобное — тот же принцип, что и панель закрепов: не тащить нестилизованный код). */
.ave-root .dm-ctxmenu {
  position: fixed; z-index: 80; width: 210px; background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-float);
  padding: 8px; display: flex; flex-direction: column; gap: 1px;
}
.ave-root .dm-ctxmenu-emojis { display: flex; justify-content: space-between; padding: 2px 2px 8px; margin-bottom: 5px; border-bottom: 1px solid var(--line-2); }
.ave-root .dm-ctxmenu-emojis button { width: 28px; height: 28px; border-radius: 8px; border: none; background: transparent; font-size: 16px; cursor: pointer; line-height: 1; }
.ave-root .dm-ctxmenu-emojis button:hover { background: var(--field); }
.ave-root .dm-ctxmenu-item {
  display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  padding: 8px 9px; border-radius: 9px; border: none; background: transparent;
  color: var(--ink-dim); font: var(--fw-medium) 13px var(--font-mono); cursor: pointer;
}
.ave-root .dm-ctxmenu-item:hover { background: var(--field); color: var(--ink); }
.ave-root .dm-ctxmenu-item.danger:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.ave-root .dm-ctxmenu-ic { flex: none; width: 16px; text-align: center; font-size: 13px; }

/* Точки входа («Сообщения»/«Мои задачи»/«Доски»/«Встречи» в сайдбаре/рейле) строит ave-shell.js
   (единый навигационный блок, решение №20) — id `dm-nav-btn`/`dm-nav-badge` сохранены как контракт,
   их читает hookChannelExit()/updateBadges() в ave-dm.js, кто бы элемент ни построил. */

/* ============================================================
   M2 · МОБАЙЛ (≤760px) — мессенджер как в Telegram: ОДНА колонка на весь экран.
   По умолчанию виден СПИСОК чатов; тап по чату → body.dm-thread-open → ПЕРЕПИСКА на весь экран (список
   скрыт); «←» в шапке чата → назад к списку (ave-dm.js). Десктопные ДВЕ колонки не тронуты. ?ave=0 — тоже.
   ============================================================ */
.ave-root .dm-backbtn {
  display: none; align-items: center; justify-content: center;
  background: transparent; border: 1px solid var(--line-2);   /* без явного фона кнопка наследует белые браузерные дефолты */
}
.ave-root .dm-backbtn canvas { width: 16px; height: 16px; display: block; pointer-events: none; }
.ave-root .dm-backbtn:hover { background: color-mix(in srgb, var(--ink) 7%, transparent); }
@media (max-width: 760px) {
  /* ПЕЙН на всю ширину. Базовый `#dm-pane{grid-column:2/-1}` (выше в ЭТОМ файле, без media) на 1-колоночном
     мобильном гриде вырождается и уводил карточку в неявную ПРАВУЮ колонку (баг: «Сообщения» уезжали вбок).
     Перебиваем на 1/-1 ЗДЕСЬ ЖЕ (ниже базового → выигрывает). Прежний override жил в ave-shell.css, но тот
     грузится РАНЬШЕ ave-dm.css и при равной специфичности проигрывал базовому правилу. */
  body.ave-root.dm-active #dm-pane { grid-column: 1 / -1; }
  /* карточка — на весь экран пейна, без 1040px-центрирования/скруглений/полей */
  .ave-root .dm-stage { width: 100%; max-width: none; margin: 0; border: 0; border-radius: 0; box-shadow: none; }
  /* обе колонки на всю ширину; показываем ОДНУ */
  .ave-root .dm-list-col { width: 100%; border-right: none; }
  .ave-root .dm-conv-col { width: 100%; }
  body.ave-root.dm-active .dm-conv-col { display: none; }                       /* по умолчанию — только список */
  body.ave-root.dm-active.dm-thread-open .dm-list-col { display: none; }        /* тред открыт — список прячем */
  body.ave-root.dm-active.dm-thread-open .dm-conv-col { display: flex; }        /* ...и показываем переписку */
  .ave-root .dm-backbtn { display: inline-flex; }                              /* «назад» — только на мобайле */
}

/* ============================================================
   E3 · КОМПАКТ-ОКНО МЕССЕНДЖЕРА В ОФИСЕ (решение №21, компакт-вариант). Плавающее окно .avo-dmwin
   (renderOfficeDmWindow в app.js, персистентный оверлей как радиалка/пины) содержит ТОТ ЖЕ живой
   .dm-stage с классом .dm-compact — одна колонка, тг-паттерн список↔тред через body.dm-thread-open
   (та же механика, что мобайл, но без @media). Полноэкранный #dm-pane и мобайл не тронуты.
   ============================================================ */
.ave-root .avo-dmwin {
  position: fixed; z-index: 55;                 /* width/height задаёт JS инлайном (перетаскивание/ресайз + персист) */
  display: flex; flex-direction: column;
  background: color-mix(in srgb, var(--panel) 92%, var(--stage));
  border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
  box-shadow: 0 24px 60px -18px rgba(0, 0, 0, .7);
}
/* уголок ресайза (как .avo-wg-resize у виджетов): низ-право, диагональные штрихи */
.ave-root .avo-dmwin-rz {
  position: absolute; right: 0; bottom: 0; width: 18px; height: 18px; z-index: 2;
  cursor: nwse-resize; touch-action: none;
  background:
    linear-gradient(135deg, transparent 0 55%, color-mix(in srgb, var(--muted) 55%, transparent) 55% 62%,
      transparent 62% 72%, color-mix(in srgb, var(--muted) 55%, transparent) 72% 79%, transparent 79%);
}
.ave-root .avo-dmwin-rz:hover { background:
    linear-gradient(135deg, transparent 0 55%, var(--signal) 55% 62%,
      transparent 62% 72%, var(--signal) 72% 79%, transparent 79%); }
.ave-root .avo-dmwin-head {
  flex: none; display: flex; align-items: center; gap: 8px; padding: 8px 10px;
  border-bottom: 1px solid var(--line-2); cursor: grab; user-select: none;
  background: color-mix(in srgb, var(--panel-2) 60%, transparent);
}
.ave-root .avo-dmwin-head:active { cursor: grabbing; }
.ave-root .avo-dmwin-grip { width: 20px; height: 3px; border-radius: 2px; background: var(--line-2); flex: none; }
.ave-root .avo-dmwin-ttl { flex: 1; font: 700 10px var(--font-mono); letter-spacing: .14em; color: var(--muted); }
.ave-root .avo-dmwin-x {
  width: 24px; height: 24px; border-radius: 7px; flex: none;
  background: transparent; border: 1px solid var(--line-2); color: var(--muted); cursor: pointer;
}
.ave-root .avo-dmwin-x:hover { color: var(--ink); background: var(--panel-2); }
.ave-root .avo-dmwin-body { flex: 1; min-height: 0; display: flex; }

/* компактный .dm-stage: заполняет окно, одна колонка, без 1040-центрирования/рамок */
.ave-root .dm-stage.dm-compact {
  flex: 1; width: 100%; max-width: none; margin: 0; min-height: 0;
  border: 0; border-radius: 0; box-shadow: none;
}
.ave-root .dm-compact .dm-list-col { width: 100%; border-right: none; }
.ave-root .dm-compact .dm-conv-col { width: 100%; display: none; }              /* по умолчанию — список */
.ave-root .dm-compact #dm-close { display: none; }                             /* закрывает окно шапка .avo-dmwin, не список */
.ave-root .dm-compact .dm-list-title { display: none; }                        /* дубль заголовка — «СООБЩЕНИЯ» уже в шапке окна */
body.ave-root.dm-thread-open .dm-compact .dm-list-col { display: none; }        /* тред открыт — список прячем */
body.ave-root.dm-thread-open .dm-compact .dm-conv-col { display: flex; }        /* ...и показываем переписку */
.ave-root .dm-compact .dm-backbtn { display: inline-flex; }                     /* «назад» к списку — как на мобайле */
