/* ============================================================
   Стиль — как в Maripos (см. Maripos/app/web/src/styles.css):
   теплый крафтовый беж + лесной зеленый, Trebuchet MS, щедрые
   скругления, мягкие тени. Темный вариант — по системной теме
   (prefers-color-scheme), без отдельного переключателя.
   ============================================================ */
:root {
  --green-deep: #0E3D00;
  --green: #2F6F2F;
  --green-soft: #4D8B48;

  --st-waiting: #E39A45;
  --st-human: #2F6F2F;
  /* Точка состояния "отвечает бот" на аватаре (см. .avatar-status) — тот же синий
     регистр, что и пузыри бота в ленте (--bot-bg/--bot-text), чтобы цвет читался как
     "это бот", а не как еще один статус оператора. */
  --st-bot: #5B8FC7;

  --page-gutter: #EEE8DA;
  --cream: #F4EFE3;
  --paper: #FFFFFF;

  --ink: #1C2418;
  --ink-2: #6B6450;
  --ink-3: #A89F88;

  --line-base: 14, 61, 0;
  --line: rgba(var(--line-base), .18);
  --line-30: rgba(var(--line-base), .3);

  /* Фон рабочей области — теплый бежевый (не бледно-зеленый --beige-bg,
     который Maripos использует для своего .shell): в плотном UI чата
     зелень заливает слишком большую площадь и читается как "все зеленое"
     вместо "бежевый с зеленым акцентом" (см. запрос — "светло-зеленые"). */
  --bg: var(--page-gutter);
  --surface: var(--paper);
  --surface-2: var(--cream);
  --text: var(--ink);
  --text-dim: var(--ink-2);

  --danger: #C0392B;
  --warning: #D99720;

  --radius-sm: 12px;
  --radius: 18px;
  --radius-lg: 24px;
  --shadow-sm: 0 1px 2px rgba(14,61,0,.06), 0 2px 6px rgba(14,61,0,.05);
  --shadow: 0 4px 10px rgba(14,61,0,.07), 0 10px 24px rgba(14,61,0,.07);
  --focus-ring: rgba(47,111,47,.45);

  --accent: var(--green-deep);
  --accent-hover: var(--green);
  --accent-contrast: #F9F2DB;

  --bot-bg: #DDEBFC;
  --bot-text: #123A63;
  --bot-border: rgba(18,58,99,.16);

  --sidebar-bg: var(--green-deep);
  --sidebar-text: #D8D1B6;
  --sidebar-divider: #506F3D;
  --sidebar-active: #F9F2DB;
  --sidebar-active-text: var(--green-deep);
  --sidebar-hover: rgba(249,242,219,.14);
}

/* Темная тема — как у Maripos: авто по системной теме, если оператор не выбрал вручную
   (переключатель в шапке сайдбара, ops.js), плюс явный [data-theme] всегда побеждает. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) { --bg: #090D0A; --surface: #101711; --surface-2: #172119;
    --line-base: 255, 255, 255; --line: rgba(var(--line-base), .12); --line-30: rgba(var(--line-base), .2);
    --text: #EEF5EE; --text-dim: #AAB8AC; --danger: #F06C72; --warning: #F0B35B;
    --st-waiting: #F0B35B; --st-human: #3D9D58; --st-bot: #6FA8E0; --accent: #3D9D58; --accent-hover: #62BC78;
    --bot-bg: #14304E; --bot-text: #D9EAFE; --bot-border: rgba(217,234,254,.18);
    --accent-contrast: #F2FAF1; --focus-ring: rgba(61,157,88,.48); --sidebar-bg: #102E19;
    --sidebar-text: #B8D0BE; --sidebar-divider: #1C572F; --sidebar-active: #1C572F;
    --sidebar-active-text: #F2FAF1; --sidebar-hover: rgba(98,188,120,.14);
  }
}
:root[data-theme="dark"] { --bg: #090D0A; --surface: #101711; --surface-2: #172119;
  --line-base: 255, 255, 255; --line: rgba(var(--line-base), .12); --line-30: rgba(var(--line-base), .2);
  --text: #EEF5EE; --text-dim: #AAB8AC; --danger: #F06C72; --warning: #F0B35B;
  --st-waiting: #F0B35B; --st-human: #3D9D58; --st-bot: #6FA8E0; --accent: #3D9D58; --accent-hover: #62BC78;
  --bot-bg: #14304E; --bot-text: #D9EAFE; --bot-border: rgba(217,234,254,.18);
  --accent-contrast: #F2FAF1; --focus-ring: rgba(61,157,88,.48); --sidebar-bg: #102E19;
  --sidebar-text: #B8D0BE; --sidebar-divider: #1C572F; --sidebar-active: #1C572F;
  --sidebar-active-text: #F2FAF1; --sidebar-hover: rgba(98,188,120,.14);
}

/* Встроено в Desk (см. index.html — ?embed=1): рядом уже есть тёмно-зелёное
   меню Maripos, вторая тёмная колонка подряд читалась бы одним сплошным
   пятном, поэтому сайдбар чатов здесь светлый (--surface/--text — те же
   переменные, что и у самого Desk). Переопределяем именно --sidebar-*,
   а не переписываем каждое правило: все селекторы .session-item уже
   ссылаются на эти переменные. --accent-contrast трогать нельзя — он общий
   для всей страницы (например, текст на зелёных кнопках), поэтому место,
   которое красило текст именно им ради контраста на тёмном фоне,
   переопределено точечно ниже. */
:root[data-embed] {
  --sidebar-bg: var(--surface);
  --sidebar-text: var(--text);
  --sidebar-divider: var(--line);
  --sidebar-active: var(--surface-2);
  --sidebar-active-text: var(--text);
  --sidebar-hover: var(--surface-2);
}
:root[data-embed] .session-item.unread .name { color: var(--text); }

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font: 14px/1.45 'Trebuchet MS', 'Segoe UI', Tahoma, sans-serif;
  color: var(--text);
  background: var(--page-gutter);
  -webkit-font-smoothing: antialiased;
}
button {
  font: inherit; color: inherit;
  transition: transform .1s ease, opacity .15s ease, background .2s ease, color .2s ease, border-color .2s ease;
}
button:active:not(:disabled) { transform: scale(.97); }
button:focus-visible, textarea:focus-visible, input:focus-visible { outline: 2px solid var(--accent-hover); outline-offset: 2px; }

#app { display: grid; grid-template-columns: 300px minmax(0, 1fr) 300px; height: 100vh; background: var(--bg); }
/* Карточка клиента справа сворачивается кнопкой в шапке диалога (как панель
   "Информация о чате" в Telegram) — переписке достается вся освободившаяся ширина. */
#app.info-hidden { grid-template-columns: 300px minmax(0, 1fr) 0; }
#app.info-hidden #customer { display: none; }
aside, main { overflow-y: auto; }

/* Standalone-режим (не iframe в Desk, см. index.html) грузит suite-nav.js —
   тот же переключатель языка/аккаунта, что и у остальных продуктов Marisuite.
   Без своего .sidebar-nav он рисует плавающую 224px-панель поверх страницы
   (см. auth/server.js mountNavigation) — сдвигаем layout вправо на ту же
   ширину, иначе она перекрывает список чатов. */
body:has(.marisuite-nav--floating) #app { margin-left: 224px; }
@media (max-width: 560px) {
  body:has(.marisuite-nav--floating) #app { margin-left: min(224px, calc(100vw - 44px)); }
}

/* ---------- сайдбар чатов ----------
   Раскладка строки — как в списке чатов Telegram: слева кружок-аватар (фото профиля или
   буква имени на своем цвете, поверх — значок мессенджера и точка состояния диалога),
   справа две строки — "имя + время" и "последняя реплика + счетчик непрочитанных".
   Раньше это была таблица из четырех строк подряд (имя с пилюлей статуса, превью, дата,
   оператор), из-за чего десяток чатов занимал весь экран и читался как отчет. */
#sessions {
  background: var(--sidebar-bg); color: var(--sidebar-text);
  display: flex; flex-direction: column; overflow: hidden;
}
#sessionsSearch {
  flex: none; display: flex; align-items: center; gap: 8px; padding: 10px 12px;
  border-bottom: 1px solid var(--sidebar-divider);
}
#sessionsSearch svg { flex: none; width: 16px; height: 16px; opacity: .55; margin-left: 2px; }
#sessionsSearchInput {
  flex: 1; min-width: 0; font: inherit; font-size: 13px; padding: 7px 12px;
  border-radius: 999px; border: 1px solid var(--sidebar-divider);
  background: var(--sidebar-hover); color: var(--sidebar-text);
}
#sessionsSearchInput::placeholder { color: var(--sidebar-text); opacity: .55; }
#sessionsSearchInput:focus { outline: none; border-color: var(--accent-hover); }
#sessionsList { flex: 1; overflow-y: auto; padding: 6px; }
.empty { padding: 24px; color: var(--text-dim); text-align: center; font-size: 13px; }
#sessions .empty { color: var(--sidebar-text); opacity: .7; }

.session-item {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px; margin: 0 0 2px; border-radius: 12px; cursor: pointer;
  transition: background .18s ease;
}
.session-item:hover { background: var(--sidebar-hover); }
.session-item.active { background: var(--sidebar-active); }
.session-body { flex: 1; min-width: 0; }
.session-top { display: flex; align-items: baseline; gap: 6px; }
.session-item .name {
  flex: 1; min-width: 0; font-weight: 600; font-size: 14px; color: var(--sidebar-text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.session-rating { flex: none; font-size: 12px; }
.session-time { flex: none; font-size: 11.5px; color: var(--sidebar-text); opacity: .6; }
.session-bottom { display: flex; align-items: center; gap: 8px; margin-top: 1px; }
.channel-icon { display: flex; flex: none; width: 15px; height: 15px; }
.channel-icon svg { width: 100%; height: 100%; }
.session-item.active .name, .session-item.active .session-time,
.session-item.active .preview { color: var(--sidebar-active-text); }
.session-item .preview {
  flex: 1; min-width: 0; font-size: 12.5px; color: var(--sidebar-text); opacity: .75;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.session-item.unread .preview { opacity: .95; }
.session-item.unread .name { font-weight: 800; color: var(--accent-contrast); }
:root[data-embed] .session-item.unread .name { color: var(--text); }
/* Счетчик непрочитанных — цифра в кружке справа от превью, как в Telegram; "·" остается
   на случай, если сервер посчитал сам факт непрочитанного, а число не прислал. */
.unread-count {
  flex: none; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px;
  background: var(--accent); color: var(--accent-contrast);
  font-size: 11.5px; font-weight: 700; display: grid; place-items: center;
}
.session-item.active .unread-count { background: var(--accent-hover); }

/* ---------- аватар ---------- */
.avatar { position: relative; flex: none; width: 44px; height: 44px; }
.avatar-initials, .avatar-photo {
  position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 50%;
}
.avatar-initials {
  display: grid; place-items: center; color: #fff; font-weight: 700; font-size: 17px;
}
.avatar-photo { object-fit: cover; }
/* Кольцо вокруг аватара — цвет мессенджера (класс ch-<channel> в avatarNode), с зазором
   цветом фона панели, как у историй в Instagram. */
.avatar::before {
  content: ''; position: absolute; inset: -3px; border-radius: 50%; background: var(--ring, transparent);
}
.avatar-initials, .avatar-photo { box-shadow: 0 0 0 1.5px var(--surface); }
#sessions .avatar-initials, #sessions .avatar-photo { box-shadow: 0 0 0 1.5px var(--sidebar-bg); }
.session-item:hover .avatar-initials, .session-item:hover .avatar-photo { box-shadow: 0 0 0 1.5px var(--sidebar-hover); }
.session-item.active .avatar-initials, .session-item.active .avatar-photo { box-shadow: 0 0 0 1.5px var(--sidebar-active); }
.avatar.ch-telegram { --ring: #2AABEE; }
.avatar.ch-whatsapp { --ring: #25D366; }
.avatar.ch-web { --ring: #D9C39A; }
.avatar.ch-instagram { --ring: linear-gradient(45deg, #FEDA75, #FA7E1E, #D62976, #962FBF, #4F5BD5); }
.avatar.ch-viber { --ring: #7360F2; }
.avatar.ch-sms { --ring: #F2C230; }
/* Значок мессенджера — маленькой медалькой в углу аватара (раньше стоял перед именем и
   отбирал место у самого имени). Обводка цветом фона панели, чтобы кружок читался. */
.avatar-channel {
  position: absolute; right: -2px; bottom: -2px; width: 17px; height: 17px; border-radius: 50%;
  background: var(--surface); color: var(--text-dim); display: grid; place-items: center;
  z-index: 1; /* фото Telegram догружается позже и встает в DOM после значка */
}
.avatar-channel svg { width: 11px; height: 11px; }
#sessions .avatar-channel { box-shadow: 0 0 0 2px var(--sidebar-bg); }
.session-item.active .avatar-channel { box-shadow: 0 0 0 2px var(--sidebar-active); }
.chat-header .avatar-channel { box-shadow: 0 0 0 2px var(--surface); }

/* ---------- переписка ---------- */
main { display: flex; flex-direction: column; background: var(--bg); align-items: center; position: relative; }
main > .empty { margin: auto; }

/* Шапка диалога — аватар, имя собеседника и строка состояния ("отвечает бот · имя
   оператора", а пока клиент набирает — "печатает…"), как в Telegram. Раньше шапки не
   было вовсе: кто пишет и из какого мессенджера, приходилось искать в списке слева.
   Занимает всю ширину колонки, поэтому стоит вне ограничения ширины ленты ниже. */
.chat-header {
  flex: none; width: 100%; display: flex; align-items: center; gap: 10px;
  padding: 9px 16px; background: var(--surface); border-bottom: 1px solid var(--line);
}
.chat-header .avatar { width: 38px; height: 38px; }
.chat-header .avatar-initials { font-size: 15px; }
.chat-header-info { flex: 1; min-width: 0; }
.chat-header-name { font-weight: 700; font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-header-sub {
  font-size: 12.5px; color: var(--text-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.chat-header-sub.typing { color: var(--accent-hover); font-style: italic; }
.chat-header-btn {
  flex: none; width: 34px; height: 34px; border-radius: 50%; border: none; padding: 0;
  background: transparent; color: var(--text-dim); display: grid; place-items: center; cursor: pointer;
}
.chat-header-btn svg { width: 20px; height: 20px; }
.chat-header-btn:hover { background: var(--surface-2); color: var(--text); }

/* На широких экранах колонка чата растягивалась во всю ширину между сайдбарами
   (могло быть 1000px+) — читать длинные ответы бота построчно неудобно. Ограничиваем
   и центрируем колонку, а не пузыри сообщений: так canned/replybar остаются
   выровнены с текстом, а не расползаются на всю ширину. */
main > #msgs { width: 100%; max-width: 760px; }
/* Шаблоны ответов и баннер "отвечаем на…" выровнены по краям панели ответа (см.
   #replybar ниже), а не по ленте: иначе они торчали бы на 16px шире капсулы. */
main > .canned, main > .reply-banner { width: calc(100% - 32px); max-width: 728px; }
#msgs { flex: 1; padding: 12px 18px 6px; overflow-y: auto; }
.older-loading { text-align: center; padding: 6px; margin-bottom: 4px; color: var(--text-dim); font-size: 12px; }
/* "Прилипающий" заголовок дня — как в Telegram, всегда видно, какой день сейчас в
   кадре, при прокрутке следующий разделитель просто выталкивает предыдущий. */
.date-sep { position: sticky; top: 4px; z-index: 3; text-align: center; margin: 12px 0 6px; }
.date-sep span {
  display: inline-block; background: var(--surface); border: 1px solid var(--line);
  color: var(--text-dim); font-size: 12px; font-weight: 600; padding: 4px 14px;
  border-radius: 999px; box-shadow: var(--shadow-sm);
}
/* Черта "непрочитанные сообщения" — то место, где оператор в прошлый раз остановился
   (см. renderConversation: operator_read_at приезжает в истории до того, как открытие
   чата пометит ее прочитанной). Открытие чата прокручивает ленту именно сюда. */
.unread-sep {
  display: flex; align-items: center; justify-content: center; gap: 10px; margin: 14px 0 8px;
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--st-waiting);
}
.unread-sep::before, .unread-sep::after {
  content: ''; flex: 1; height: 1px; background: color-mix(in srgb, var(--st-waiting) 45%, transparent);
}

/* Пузырь — ширина по содержимому, а не по колонке: кнопка реакции (см. .react-trigger)
   позиционируется от края самого пузыря, поэтому обертка обжимает его, а сторону
   выбирает margin'ом, а не align-items у ленты. */
.msg-wrap { position: relative; display: flex; flex-direction: column; width: fit-content; max-width: 82%; margin: 7px 0; }
.msg-wrap.customer { align-items: flex-start; margin-right: auto; }
.msg-wrap.bot, .msg-wrap.operator { align-items: flex-end; margin-left: auto; }
/* Серия сообщений подряд от одного отправителя в пределах нескольких минут (см.
   GROUP_WINDOW_MS в ops.js) — сжимаем отступ и не повторяем подпись отправителя;
   закругление "хвостика" пузыря остается только на последнем в серии. */
.msg-wrap.grouped-prev { margin-top: 2px; }
.msg-wrap.grouped-prev .who { display: none; }
.msg-wrap.grouped-next.customer .msg { border-bottom-left-radius: var(--radius); }
.msg-wrap.grouped-next.bot .msg, .msg-wrap.grouped-next.operator .msg { border-bottom-right-radius: var(--radius); }

.msg {
  max-width: 100%; padding: 6px 12px 4px; border-radius: var(--radius);
  word-break: break-word; box-shadow: var(--shadow-sm); animation: msg-in .14s ease;
  /* Время и реакция — в правом нижнем углу пузыря, как в Telegram: если строка текста
     короткая, они встают на ту же строку, если длинная — переносятся под нее. */
  display: flex; flex-wrap: wrap; align-items: flex-end; row-gap: 2px;
}
.msg > * { flex: 0 0 100%; min-width: 0; }
@keyframes msg-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: translateY(0); } }
.msg.customer { background: var(--surface); border: 1px solid var(--line); border-bottom-left-radius: 6px; }
.msg.bot { background: var(--bot-bg); color: var(--bot-text); border: 1px solid var(--bot-border); border-bottom-right-radius: 6px; }
.msg.operator { background: var(--accent); color: var(--accent-contrast); border-bottom-right-radius: 6px; }
.msg .who { font-size: 11px; opacity: .6; margin-bottom: 1px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; }
.msg .msg-text { flex: 1 1 auto; white-space: pre-wrap; }
.msg-meta {
  flex: 0 0 auto; margin-left: auto; padding-left: 10px;
  display: flex; align-items: center; gap: 6px; line-height: 1.6;
}
.msg-time { font-size: 10.5px; opacity: .55; }
.msg-edited { font-size: 10.5px; opacity: .5; font-style: italic; }
/* Автор ответа оператора — появляется в строке времени только при наведении. */
.msg-operator { display: none; font-size: 10.5px; opacity: .6; }
.msg-wrap:hover .msg-operator { display: inline; }
.msg-quote {
  border-left: 3px solid currentColor; opacity: .8; padding: 2px 8px; margin-bottom: 6px;
  font-size: 12.5px; border-radius: 4px; background: rgba(127,127,127,.12);
}
.msg-quote.clickable { cursor: pointer; }
.msg-quote.clickable:hover { opacity: 1; }
.msg-quote-sender { font-weight: 700; }
.msg-quote-text { white-space: pre-wrap; word-break: break-word; opacity: .85; }
.msg img, .msg video { max-width: 260px; border-radius: 12px; display: block; margin-top: 6px; }
.msg img { cursor: zoom-in; }
.msg a { color: inherit; }
/* Подсветка сообщения, к которому перешли кликом по цитате (см. jumpToMessage). */
@keyframes jump-flash { 0%, 100% { box-shadow: var(--shadow-sm); } 25%, 70% { box-shadow: 0 0 0 3px var(--focus-ring); } }
.msg-wrap.jump-highlight .msg { animation: jump-flash 1.5s ease; }

/* Кнопка "вниз" — появляется, когда лента прокручена вверх, и считает пришедшие за это
   время сообщения, чтобы новые не выдергивали ленту из-под читающего оператора. */
.scroll-down {
  position: absolute; right: 22px; bottom: 116px; z-index: 6;
  width: 42px; height: 42px; border-radius: 50%; padding: 0;
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow);
  color: var(--text-dim); display: grid; place-items: center; cursor: pointer;
}
.scroll-down:hover { color: var(--text); }
.scroll-down svg { width: 20px; height: 20px; }
.scroll-down-count {
  position: absolute; top: -6px; right: -6px; min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 999px; background: var(--accent); color: var(--accent-contrast);
  font-size: 11px; font-weight: 700; display: grid; place-items: center;
}
.scroll-down[hidden], .scroll-down-count[hidden] { display: none; }

/* Просмотр картинки во весь экран по клику (см. openLightbox) — как в Telegram,
   поверх переписки, а не отдельной вкладкой браузера. */
.lightbox {
  position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.82);
  display: grid; place-items: center; padding: 32px;
}
.lightbox img { max-width: 92vw; max-height: 92vh; border-radius: 12px; }
.lightbox-close {
  position: absolute; top: 14px; right: 18px; width: 38px; height: 38px; border-radius: 50%;
  border: none; background: rgba(255,255,255,.16); color: #fff; font-size: 24px; line-height: 1; cursor: pointer;
}
.lightbox-close:hover { background: rgba(255,255,255,.28); }

/* ---------- реакции на чужие сообщения (не операторские) ---------- */
/* Поставленная реакция живет внутри пузыря рядом со временем, а кнопка "поставить"
   висит сбоку и проявляется при наведении — раньше пунктирный "+" стоял под каждым
   сообщением клиента и бота, добавляя каждому пузырю лишнюю строку высоты. */
.react-trigger {
  position: absolute; bottom: 2px; opacity: 0; transition: opacity .15s ease;
  border: 1px solid var(--line); background: var(--surface); color: var(--text-dim);
  border-radius: 50%; width: 24px; height: 24px; font-size: 13px; line-height: 1;
  display: grid; place-items: center; cursor: pointer; box-shadow: var(--shadow-sm);
}
.msg-wrap.customer .react-trigger { left: calc(100% + 6px); }
.msg-wrap.bot .react-trigger { right: calc(100% + 6px); }
.msg-wrap:hover .react-trigger, .react-trigger:focus-visible { opacity: 1; }
.react-trigger:hover { background: var(--surface-2); color: var(--text); }
.react-trigger[hidden] { display: none; }
/* Сообщения бота выровнены по правому краю — пикер там должен открываться влево от
   кнопки, иначе 268px-панель вылезает за край окна (см. .emoji-picker: left:0 по умолчанию,
   верно только для сообщений клиента слева). */
.msg-wrap.bot .emoji-picker { left: auto; right: 0; }
.reaction-pill {
  border: none; background: rgba(127,127,127,.18); border-radius: 999px;
  padding: 1px 7px; font-size: 12px; cursor: pointer; display: inline-flex; align-items: center; gap: 2px;
}
.reaction-pill:hover { background: rgba(127,127,127,.3); }
.msg-edit-form { margin-top: 6px; display: flex; flex-direction: column; gap: 6px; width: 260px; max-width: 60vw; }
.msg-edit-form textarea {
  width: 100%; resize: vertical; font: inherit; padding: 6px 8px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
}
.msg-edit-actions { display: flex; gap: 6px; justify-content: flex-end; }
/* Правый клик по сообщению — Ответить/Скопировать/Редактировать (см. openMessageContextMenu
   в ops.js), тот же принцип, что нативное контекстное меню Telegram. .has-context-menu
   только подсказывает курсором, что клик что-то даст — своей иконки/подсветки нет
   намеренно: как и в самом Telegram, обнаруживается через привычку, а не UI-подсказку. */
.msg.has-context-menu { cursor: context-menu; }
.msg-context-menu {
  position: fixed; z-index: 40; min-width: 180px; padding: 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: var(--shadow-lg); display: flex; flex-direction: column;
}
.msg-context-menu-item {
  border: none; background: none; text-align: left; padding: 8px 12px; font: inherit;
  font-size: 13px; color: var(--text); border-radius: 6px; cursor: pointer;
}
.msg-context-menu-item:hover { background: var(--surface-2); }
.msg-context-menu-item.danger { color: var(--danger); }
/* Плейсхолдер удаленного сообщения (см. applyMessageDeleted в ops.js) — приглушенный
   курсив вместо текста, тот же прием, что и у "(изменено)" рядом. */
.msg-deleted-text { font-style: italic; opacity: .6; }
/* Пикер пересылки (см. openForwardPicker) — тот же визуальный язык, что и
   canned-add-popover/msg-context-menu ниже, только с полем поиска и списком чатов. */
.forward-picker {
  position: fixed; z-index: 40; width: 240px; max-height: 320px; padding: 8px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); display: flex; flex-direction: column; gap: 6px;
}
.forward-picker input {
  font: inherit; padding: 8px 10px; border-radius: 10px; color: var(--text);
  background: var(--bg); border: 1px solid var(--line);
}
.forward-picker input:focus { outline: none; border-color: var(--accent-hover); box-shadow: 0 0 0 3px var(--focus-ring); }
.forward-picker-list { overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.forward-picker-row {
  padding: 7px 10px; border-radius: 8px; cursor: pointer;
  display: flex; flex-direction: column; gap: 2px; min-width: 0;
}
.forward-picker-row:hover { background: var(--surface-2); }
/* Иконка канала + имя — тот же порядок фолбэков, что у customerLabel() в открытом
   диалоге (имя → @username → телефон → "Гость"), иначе большинство телеграм-сессий
   без имени/телефона неотличимы друг от друга в списке. */
.forward-picker-name {
  display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.forward-picker-preview { font-size: 11px; opacity: .6; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.forward-picker-empty { padding: 7px 10px; font-size: 13px; opacity: .6; }
/* Баннер "отвечаем на..." над полем ввода — виден, пока не отправлено или не отменено. */
.reply-banner {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 12px; margin: 6px 16px -4px; border-left: 3px solid var(--accent);
  border-radius: 8px; background: var(--surface-2); font-size: 12.5px;
}
/* display:flex выше побеждает браузерный [hidden]{display:none} при равной специфичности
   (автор всегда важнее UA-стилей) — без этого правила .hidden=true в JS не прятал бы баннер. */
.reply-banner[hidden] { display: none; }
.reply-banner-text { flex: 1; min-width: 0; }
.reply-banner-sender { font-weight: 700; }
.reply-banner-snippet { opacity: .75; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.reply-banner-close { border: none; background: transparent; color: var(--text-dim); font-size: 18px; cursor: pointer; line-height: 1; padding: 0 4px; }
.reply-banner-close:hover { color: var(--text); }

/* ---------- пикер эмодзи (реплики оператора + панель реакций) ---------- */
.emoji-btn {
  flex: none; width: 40px; height: 40px; border-radius: 12px;
  display: grid; place-items: center; background: var(--surface); border: 1px solid var(--line); cursor: pointer;
  color: var(--text-dim);
}
.emoji-btn svg { width: 19px; height: 19px; }
.emoji-btn:hover { background: var(--surface-2); color: var(--text); }
.emoji-picker-anchor { position: relative; display: flex; align-items: center; }
.emoji-picker {
  position: absolute; bottom: calc(100% + 8px); left: 0; z-index: 20;
  width: 268px; max-height: 220px; overflow-y: auto; padding: 8px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); display: grid; grid-template-columns: repeat(8, 1fr); gap: 0;
}
.emoji-picker button {
  /* Без явного background/border кнопка наследует нативный вид ОС (Windows красит
     безымянные <button> в акцентный цвет — отсюда были зелёные "таблетки"). */
  width: 30px; height: 30px; font-size: 18px; border-radius: 6px; display: grid; place-items: center;
  background: none; border: none; padding: 0; margin: 0; appearance: none; cursor: pointer;
}
.emoji-picker button:hover { background: var(--surface-2); }
img.emoji { height: 1.15em; width: 1.15em; vertical-align: -0.2em; margin: 0 .02em; }
.emoji-btn img.emoji, .emoji-picker button img.emoji { height: 20px; width: 20px; vertical-align: middle; margin: 0; }

/* ---------- шаблоны ответов — горизонтальная прокрутка, не перенос строк:
   список растёт (см. CANNED_REPLIES в ops.js + свои шаблоны оператора),
   перенос в несколько строк толкал бы поле ответа вниз при каждом чате. */
.canned { flex: none; padding: 8px 0 0; background: var(--bg); }
.canned-scroll {
  display: flex; gap: 6px; overflow-x: auto; padding-bottom: 6px;
  scrollbar-width: none; cursor: grab;
}
.canned-scroll::-webkit-scrollbar { display: none; }
.canned-scroll.dragging { cursor: grabbing; user-select: none; }
.canned-btn {
  flex: none; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  border: 1px solid var(--line); background: var(--surface); color: var(--text-dim);
  border-radius: 999px; padding: 5px 12px; font-size: 12px; cursor: pointer;
}
.canned-btn:hover { background: var(--surface-2); color: var(--text); border-color: var(--line-30); }
.canned-del {
  opacity: .55; font-size: 13px; line-height: 1; margin: -1px -2px -1px 0;
}
.canned-del:hover { opacity: 1; color: var(--danger); }
.canned-add-anchor { position: relative; flex: none; }
.canned-add-btn {
  flex: none; width: 28px; height: 28px; border-radius: 999px; cursor: pointer;
  border: 1px dashed var(--line-30); background: transparent; color: var(--text-dim);
  font-size: 16px; line-height: 1; display: grid; place-items: center;
}
.canned-add-btn:hover { background: var(--surface-2); color: var(--text); }
.canned-add-popover {
  position: absolute; bottom: calc(100% + 8px); left: 0; z-index: 20; width: 260px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 10px; display: flex; flex-direction: column; gap: 8px;
}
.canned-add-popover input, .canned-add-popover textarea {
  font: inherit; padding: 8px 10px; border-radius: 10px; color: var(--text);
  background: var(--bg); border: 1px solid var(--line); resize: vertical;
}
.canned-add-popover input:focus, .canned-add-popover textarea:focus {
  outline: none; border-color: var(--accent-hover); box-shadow: 0 0 0 3px var(--focus-ring);
}
.canned-add-actions { display: flex; gap: 8px; justify-content: flex-end; }
.canned-add-actions button {
  border: none; border-radius: 999px; padding: 6px 14px; font-size: 13px;
  font-weight: 700; cursor: pointer;
}
.canned-add-actions button.save { background: var(--accent); color: var(--accent-contrast); }
.canned-add-actions button.save:hover { background: var(--accent-hover); }

/* Панель ответа — одна "капсула", как поле ввода Telegram: эмодзи и скрепка внутри неё
   слева, текст посередине, круглая кнопка отправки справа. Раньше это были три отдельных
   плашки в ряд, а поле было ровно 46px высотой и текст в нём уезжал вверх при переносе. */
#replybar {
  flex: none; display: flex; align-items: flex-end; gap: 4px;
  width: calc(100% - 32px); max-width: 728px; margin: 0 16px 14px; padding: 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 22px;
  transition: border-color .2s ease, box-shadow .2s ease;
}
#replybar:focus-within { border-color: var(--accent-hover); box-shadow: 0 0 0 3px var(--focus-ring); }
#replybar textarea {
  flex: 1; resize: none; min-height: 34px; max-height: 150px; padding: 7px 4px; color: var(--text);
  background: transparent; border: none; font: inherit; line-height: 1.35; overflow-y: auto;
}
#replybar textarea:focus { outline: none; }
#replybar .emoji-btn { width: 34px; height: 34px; border: none; background: transparent; border-radius: 50%; }
#replybar .emoji-btn:hover { background: var(--surface-2); }
/* > (не просто пробел) — иначе эта ID-специфичность (сильнее любого .class) перекрашивает
   и вложенные кнопки эмодзи-пикера/триггера внутри #replybar в зелёный акцент. */
#replybar > button {
  flex: none; width: 36px; height: 36px; padding: 0; border: none; border-radius: 50%;
  background: var(--accent); color: var(--accent-contrast);
  display: grid; place-items: center; cursor: pointer;
}
#replybar > button:hover { background: var(--accent-hover); }
#replybar > button svg { width: 17px; height: 17px; margin-left: -1px; }
.btn-secondary { background: var(--surface-2); color: var(--text-dim); border: 1px solid var(--line); }
.btn-secondary:hover { background: var(--surface); color: var(--text); }

/* ---------- карточка клиента ---------- */
#customer { background: var(--surface); border-left: 1px solid var(--line); padding: 18px; }
.bot-mute-btn {
  display: block; width: 100%; margin: 0 0 14px; padding: 8px 10px;
  border-radius: var(--radius-sm); cursor: pointer; font-size: 13px; font-weight: 700; text-align: center;
}
.bot-mute-btn.active { background: var(--danger); color: var(--accent-contrast); border-color: var(--danger); }
.bot-mute-btn.active:hover { opacity: .9; background: var(--danger); }
.customer-avatar { display: block; width: 56px; height: 56px; border-radius: 50%; object-fit: cover; margin: 0 0 10px; }
#customer h3 { margin: 0 0 10px; font-size: 17px; }
#customer h4 { margin: 16px 0 6px; font-size: 12px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; color: var(--accent); }
#customer > div { color: var(--text-dim); font-size: 13px; margin: 3px 0; }
.order-row {
  padding: 8px 10px; margin: 6px 0; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface-2); font-size: 13px;
}
.order-row .status { color: var(--text-dim); margin-top: 2px; }

/* Скролл — тонкая приглушенная полоска, проявляется при наведении на колонку.
   Сплошная зеленая полоса во всю высоту ленты спорила по яркости с самими пузырями. */
#sessionsList, #msgs, #customer {
  scrollbar-width: thin; scrollbar-color: var(--line-30) transparent;
}
#sessionsList:hover, #msgs:hover, #customer:hover {
  scrollbar-color: color-mix(in srgb, var(--accent-hover) 55%, transparent) transparent;
}
#sessionsList::-webkit-scrollbar, #msgs::-webkit-scrollbar, #customer::-webkit-scrollbar { width: 6px; }
#sessionsList::-webkit-scrollbar-thumb, #msgs::-webkit-scrollbar-thumb, #customer::-webkit-scrollbar-thumb {
  background: var(--line-30); border-radius: 999px;
}
#sessionsList:hover::-webkit-scrollbar-thumb, #msgs:hover::-webkit-scrollbar-thumb, #customer:hover::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--accent-hover) 55%, transparent);
}
#sessionsList::-webkit-scrollbar-track, #msgs::-webkit-scrollbar-track, #customer::-webkit-scrollbar-track { background: transparent; }
