:root { --line: #e3e3e0; --ink: #1c1c1a; --muted: #6b6b66; --accent: #2f6f4f; }
* { box-sizing: border-box; }
/* ---------- Размеры текста: пять ступеней ----------
   Размеров было пятнадцать — от 11 до 34 пикселей, и разница в один пиксель
   ничего не значила: одно и то же по смыслу писалось то 13-м, то 14-м, то
   15-м. Оставлено пять ступеней, каждая со своим назначением:
     12px — подпись: время, счётчик, пояснение мелким серым;
     14px — обычный текст, его больше всего;
     16px — поля ввода. Меньше нельзя: айфон зумит страницу на поле мельче
            16px и обратно её не уменьшает (внизу файла есть общее правило,
            которое дотягивает до 16px все поля разом);
     20px — заголовок раздела и крупный значок-кнопка (☰, ⋮, ×, стрелка
            «отправить»);
     26px — крупный заголовок.
   Размеры 30px и 34px оставлены как были: это не текст, а смайлики в беседе
   и код подключения в профиле, который диктуют вслух. */
/* Высота страницы считается от html: на телефоне 100dvh оказывается больше
   видимого окна (замерено в установленном приложении: окно 857 px, экран 915),
   и низ страницы — поле вопроса, кнопки итога — уезжает за край. 100% берётся
   от html и даёт ровно видимое окно. max-height: 100dvh оставлен как потолок
   для Safari, где адресная строка съезжает. */
html { height: 100%; }

/* Ступени — и для того, что размера не просило.
   Правило по самому тегу — самое слабое, какое бывает (специфичность 0,0,1):
   его перебивает любое правило с классом. Поэтому всё оформленное остаётся
   как было, а «голые» поля и заголовки перестают брать размер у браузера.
   Браузер даёт полю 13.3px — айфон на таком поле зумит страницу и обратно её
   не уменьшает; заголовку h2 даёт 24px — мимо ступеней. */
input, select, textarea { font-size: 16px; max-width: 100%; }
/* max-width нужен из-за полей, ширина которых задана в разметке числом символов
   (`size="46"` у ссылки-подписки в «Настройках»): в символах она считается от
   шрифта, а шрифт мы подняли до 16px — и поле стало шире телефона. */
h1, h2 { font-size: 20px; }
h3 { font-size: 16px; }
body { margin: 0; font: 16px/1.5 -apple-system, "Segoe UI", Roboto, sans-serif; color: var(--ink); background: #faf9f7; }
.login-box { max-width: 320px; margin: 15vh auto; padding: 24px; background: #fff; border: 1px solid var(--line); border-radius: 8px; }
.login-box h1 { margin: 0 0 16px; font-size: 20px; }
.login-box .face { display: block; width: 96px; height: 96px; margin: 0 auto 12px; border-radius: 50%; }
.login-box input, .login-box button { width: 100%; padding: 10px 12px; margin-bottom: 10px; border: 1px solid var(--line); border-radius: 8px; font: inherit; }
.login-box button { background: var(--accent); color: #fff; border: none; cursor: pointer; }
.err { color: #a12; margin: 4px 0 0; }

/* Верхний отступ с запасом на строку состояния: с viewport-fit=cover страница
   рисуется во весь экран, включая часы и значки, и шапка ушла бы под них.
   На компьютере env(...) равен нулю — правило там ничего не меняет. */
.top { display: flex; align-items: center; gap: 10px;
  padding: calc(10px + env(safe-area-inset-top)) 16px 10px; background: #fff; border-bottom: 1px solid var(--line); }
.brand-face { width: 26px; height: 26px; border-radius: 50%; }
.brand { font-weight: 600; }
.spacer { flex: 1; }
/* Имя в шапке сжимается первым: длинное ФИО переносилось на две строки
   и выдавливало «Выйти» за экран. */
/* Имя в шапке — ссылка на свою карточку, но выглядит как обычная подпись:
   цветной ссылкой оно спорило бы с разделами меню. Кликабельность
   подсказывают курсор и подчёркивание под указателем. */
#who { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
       color: inherit; text-decoration: none; cursor: pointer; }
#who:hover { text-decoration: underline; }
/* «Выйти» — не кнопка действия, а запасной выход: серая надпись, которая
   не спорит с разделами шапки. */
#logout { padding: 0; border: 0; background: none; font: inherit; font-size: 14px; color: var(--muted); cursor: pointer; }
#logout:hover { color: var(--ink); text-decoration: underline; }
/* «⟳ Обновить» — сосед «Выйти» и выглядит так же: это не действие раздела,
   а служебный пункт. Нужен потому, что в установленном ярлыке нет адресной
   строки, а значит нет и кнопки перезагрузки браузера. */
.reload-btn { padding: 0; border: 0; background: none; font: inherit; font-size: 14px; color: var(--muted); cursor: pointer; white-space: nowrap; }
.reload-btn:hover { color: var(--ink); text-decoration: underline; }
/* Шапка на широком экране — одна строка, как и была: меню-обёртка просто
   растягивается, а гамбургер не показывается. */
.top-menu { display: flex; align-items: center; gap: 10px; flex: 1; }
.menu-btn { display: none; }
/* Крестик живёт только в раскрытой панели на телефоне: на широком экране
   меню и так всегда на виду, закрывать нечего. */
.menu-close { display: none; }
/* Пункты разделов в шапке. Без отступа они слипались в «ВопросыОбзвон»,
   а текущий раздел ничем не отличался от соседнего. */
.top-nav { display: flex; gap: 14px; }
.top-nav a { color: var(--accent); text-decoration: none; }
.top-nav a.active { color: inherit; font-weight: 600; }
.link { background: none; border: none; color: var(--accent); cursor: pointer; font: inherit; }
.fresh { padding: 6px 16px; font-size: 14px; color: var(--muted); background: #fff; border-bottom: 1px solid var(--line); }
.fresh.warn { background: #fff6d8; color: #6a5200; }
.layout { display: flex; height: calc(100vh - 84px); }
.chats { width: 240px; border-right: 1px solid var(--line); padding: 12px; overflow-y: auto; }
.chats .new { width: 100%; padding: 8px; margin-bottom: 12px; border: 1px solid var(--line); border-radius: 8px; background: #fff; cursor: pointer; font: inherit; }
.chats ul { list-style: none; margin: 0; padding: 0; }
.chats li { display: flex; align-items: center; gap: 6px; padding: 8px; border-radius: 8px; cursor: pointer; }
.chats li:hover { background: #f1f0ed; }
.chats li.active { background: #e7efe9; }
.chats .title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; }
.chats .when { font-size: 12px; color: var(--muted); }
.chats .del { border: none; background: none; color: var(--muted); cursor: pointer; font-size: 16px; }
.templates { margin: 8px 0 12px; }
.tpl-toggle {
  width: 100%; text-align: left; background: none; border: 0; padding: 4px 0;
  font: inherit; color: var(--muted); cursor: pointer;
}
.tpl-toggle::before { content: '▸ '; }
.templates.open .tpl-toggle::before { content: '▾ '; }
.templates #templates-list { display: none; list-style: none; margin: 4px 0 0; padding: 0; }
.templates.open #templates-list { display: block; }
.tpl-topic { margin: 6px 0 2px; font-size: 12px; color: var(--muted); }
.tpl-item {
  width: 100%; text-align: left; background: none; border: 0; padding: 4px 6px;
  font: inherit; color: inherit; cursor: pointer; border-radius: 8px;
}
.tpl-item:hover { background: #f2f1ed; }
/* min-height: 0 — чтобы разговор мог сжаться до экрана. Без него на телефоне,
   где .layout встаёт колонкой, лента сообщений растягивается на всю свою
   высоту и поле ввода уезжает далеко за низ экрана. */
.talk { flex: 1; min-height: 0; display: flex; flex-direction: column; }
#thread { flex: 1; overflow-y: auto; padding: 16px; }
/* .page — колонка обычной страницы (настройки, расходы, профиль).
   Раньше эти страницы брали класс .msg, но .msg — это реплика в беседе с ИИ
   со своими потомками (.author, .text, .face). Совпадали они только шириной,
   и любая правка реплики поехала бы по трём чужим страницам. */
/* width: 100% обязателен. На телефоне body — флекс-колонка, и колонка страницы
   растянулась бы на всю ширину сама. Но горизонтальные `auto` в margin отменяют
   растяжение: вместо ширины окна колонка берёт ширину самого широкого, что в ней
   лежит. Одна непереносимая строка — таблица «Расходов», поле ссылки в
   «Настройках» — и вся страница уезжает вбок. С width: 100% ширина задана
   заранее, и таблица снова прокручивается внутри своего ящика, как и задумано. */
.page { width: 100%; max-width: 760px; margin: 0 auto 20px; }
.msg { max-width: 760px; margin: 0 auto 20px; }
.msg .author { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.msg .face { width: 22px; height: 22px; border-radius: 50%; }
.msg .text { white-space: pre-wrap; }
.msg.user .text { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 8px 12px; }
/* Длинные таблицы (много строк и столбцов) держим в собственном окне со своей
   прокруткой — иначе горизонтальный ползунок уезжает в самый низ страницы,
   и до него нужно домотать всю таблицу. Шапка и первый столбец (обычно
   название товара/клиента) закреплены, чтобы при скролле вбок или вниз не
   терять, к какой строке и колонке относится ячейка. */
.table-box { margin-top: 12px; max-height: min(60vh, 480px); overflow: auto; background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 10px; }
.table-title { position: sticky; left: 0; font-size: 14px; color: var(--muted); margin-bottom: 6px; }
.table-box table { border-collapse: separate; border-spacing: 0; font-size: 14px; width: 100%; }
.table-box th, .table-box td { border-bottom: 1px solid var(--line); padding: 5px 8px; text-align: left; white-space: nowrap; }
.table-box thead th { position: sticky; top: 0; background: #fff; z-index: 1; box-shadow: inset 0 -1px 0 var(--line); }
.table-box th:first-child, .table-box td:first-child { position: sticky; left: 0; background: #fff; z-index: 1; }
.table-box thead th:first-child { z-index: 2; }
/* Зебра для строк-данных: на широкой таблице глаз иначе теряет строку,
   переходя от левого столбца к правому. Чётный фон продублирован и для
   sticky-ячейки первого столбца — иначе при скролле вбок она остаётся белой
   и полосы обрываются на границе закреплённого столбца. */
.table-box tbody tr:nth-child(even) td { background: #f5f3ef; }
.table-box tbody tr:nth-child(even) td:first-child { background: #f5f3ef; }
.note { font-size: 14px; color: #6a5200; margin: 6px 0 0; }

/* Настройки: один человек — одна карточка. Таблица из восьми колонок читалась
   через весь экран, и к последней галочке было уже не вспомнить, чья это
   строка; в карточке имя стоит над каждой настройкой. Круг клиентов свёрнут:
   полтора десятка фамилий разворачивались в простыню, а знать обычно надо
   только «кто в круге» — это написано в самой свёрнутой строке. */
.person { background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 10px 12px; margin-top: 10px; }
.person.off { opacity: .6; }
.person .who { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.person .who b { font-size: 14px; }
.person .state { font-size: 12px; color: var(--muted); }
.person.off .state { color: #b00; }
.person .line { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 4px 0; font-size: 14px; }
.person .line label { display: inline-flex; align-items: center; gap: 4px; }
.person .line input.ext { width: 120px; }
.person .acts { margin-top: 8px; gap: 4px; }
.circle-box summary { cursor: pointer; font-size: 14px; padding: 4px 0; }
.circle-box .circle { display: flex; flex-wrap: wrap; gap: 4px 14px; padding: 6px 0 2px 14px; font-size: 14px; }
.pass-shown { background: #fff8dc; border: 1px solid #e0c96a; border-radius: 8px; padding: 10px 12px; margin-top: 10px; font-size: 14px; }
.pass-shown .pass { font-size: 16px; font-weight: 600; background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 2px 8px; user-select: all; }
.muted { color: var(--muted); }
/* Панель ввода — одна карточка: вопрос сверху во всю ширину, служебная
   строка снизу. Рамка у карточки, а не у поля: так поле выглядит просторным,
   а подсветка при наборе охватывает всё разом. */
.composer { border-top: 1px solid var(--line); padding: 12px 16px 14px; background: #fff; }
.composer .box {
  max-width: 760px; margin: 0 auto;
  border: 1px solid var(--line); border-radius: 8px; background: #fff;
  padding: 10px 12px 8px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .04);
  transition: border-color .15s, box-shadow .15s;
}
.composer .box:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px rgba(0, 128, 0, .10); }
/* Высоту задаёт скрипт по набранному тексту, здесь только пределы: меньше
   трёх строк поле не станет, выше половины экрана — не полезет. */
.composer textarea {
  display: block; width: 100%; box-sizing: border-box;
  border: none; outline: none; background: none; resize: none;
  font: inherit; line-height: 1.45; padding: 2px 2px 6px;
  min-height: 66px; max-height: 40vh; overflow-y: auto;
}
.composer .tools { display: flex; align-items: center; gap: 8px; }
.composer select {
  border: 1px solid var(--line); border-radius: 999px; background: #fafafa;
  font: inherit; font-size: 16px; padding: 3px 10px; cursor: pointer; color: #444;
}
.composer .model-note { font-size: 12px; color: var(--muted); flex: 1; min-width: 0; }
.composer button { border: 1px solid var(--line); border-radius: 999px; background: #fff; font: inherit; padding: 6px 12px; cursor: pointer; }
.composer #stop { font-size: 14px; }
.composer #send {
  background: var(--accent); color: #fff; border: none;
  width: 38px; height: 38px; padding: 0; border-radius: 50%;
  font-size: 20px; line-height: 1; flex: none;
}
.trail .step { margin: 8px 0; padding-left: 10px; border-left: 2px solid var(--line); }
.trail-box { margin-top: 12px; }
.trail-box > summary { cursor: pointer; color: var(--muted); font-size: 14px; }
.step-text { color: #666; font-size: 14px; margin-bottom: 4px; }
.sql-box summary { cursor: pointer; color: #666; font-size: 14px; }
.sql-box pre.sql { white-space: pre-wrap; font-size: 14px; background: #f6f6f6; padding: 8px; border-radius: 8px; }

/* Телефон. Представители работают с Советником в машине и у клиента, поэтому
   колонка бесед не может занимать треть экрана: она превращается в ленту
   сверху, а разговор получает всё остальное. Высота считается через flex, а не
   вычитанием пикселей шапки: у неё бывает и полоска «данные от…», и
   предупреждение про интернет. Высота — 100% от html, а не 100dvh:
   в установленном приложении Android dvh больше видимого окна. */
@media (max-width: 700px) {
  body { display: flex; flex-direction: column; height: 100%; max-height: 100dvh; }
  .top { padding: calc(8px + env(safe-area-inset-top)) 12px 8px; gap: 8px; flex: none; }
  .top .brand { font-size: 14px; }
  /* На телефоне шапка не вмещает и навигацию, и имя, и «Выйти»: имя
     обрезалось многоточием. Прячем всё это за гамбургер — раскрывается
     чекбоксом, без скрипта, поэтому работает и на старом браузере. */
  /* «Настройки», «Расходы», «Мой профиль» и «Объявление» своей раскладки не
     имеют: у них просто одна колонка под шапкой. Из-за предельной высоты
     body страница переполняла его, и шапка с гамбургером уезжала за верхний
     край — уйти в другой раздел можно было только пролистав всё обратно.
     Даём им ту же схему, что у «Задач» и «Нашего чата»: прокручивается
     колонка, шапка стоит. У .bc-page нет своей ширины, а горизонтальные
     auto в margin отменяют растяжение колонки — отсюда width. */
  body > main.page, body > main.bc-page { flex: 1; min-height: 0; overflow-y: auto; }
  body > main.bc-page { width: 100%; }
  /* Шапка липнет к верху экрана. Страницы бывают длинные («Настройки» —
     восемь экранов), и без этого гамбургер уезжал наверх вместе со
     страницей: уйти в другой раздел можно было только пролистав всё
     обратно. position: relative нужен выпадающему меню — sticky его
     тоже даёт. */
  .top { position: sticky; top: 0; z-index: 25; }
  .menu-btn { display: block; position: relative; font-size: 20px; line-height: 1; padding: 2px 8px; cursor: pointer; }
  /* Красный кружок с числом новых сообщений — прямо на гамбургере. Само
     число живёт в пункте меню «Наш чат», но меню на телефоне закрыто, и
     без этого кружка человек про новые сообщения просто не узнаёт. */
  .menu-count {
    position: absolute; top: -4px; right: -2px; min-width: 18px; height: 18px;
    padding: 0 5px; box-sizing: border-box;
    border-radius: 999px; background: #e5484d; color: #fff;
    font-size: 12px; font-weight: 600; line-height: 18px; text-align: center;
  }
  .top-menu { display: none; }
  .menu-toggle:checked ~ .top-menu {
    display: flex; flex-direction: column; align-items: stretch; gap: 12px;
    position: absolute; top: 100%; right: 8px; z-index: 30; min-width: 200px;
    padding: 12px 16px; background: #fff;
    border: 1px solid var(--line); border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .15);
  }
  /* Привычный крестик: он тот же самый выключатель, что и гамбургер, —
     нажатие снимает галочку с menu-toggle и панель закрывается. Раньше её
     закрывали только повторным нажатием на ☰ или тычком мимо меню. */
  .menu-toggle:checked ~ .top-menu .menu-close {
    display: block; align-self: flex-end;
    margin: -8px -10px 0 0; padding: 4px 10px;
    font-size: 20px; line-height: 1; color: var(--muted); cursor: pointer;
  }
  .top-menu .spacer { display: none; }
  .top-menu .top-nav { flex-direction: column; gap: 12px; }
  .top-nav { gap: 10px; }
  .top #logout, .top .reload-btn { white-space: nowrap; text-align: left; }
  .fresh { flex: none; font-size: 14px; padding: 5px 12px; }
  .layout { flex: 1; min-height: 0; flex-direction: column; height: auto; }
  .chats { width: auto; height: auto; padding: 8px 12px; border-right: none; border-bottom: 1px solid var(--line); display: flex; gap: 8px; align-items: center; overflow-x: auto; overflow-y: hidden; background: #fff; }
  .chats .new { width: auto; flex: none; margin: 0; white-space: nowrap; padding: 6px 10px; font-size: 14px; }
  .chats ul { display: flex; gap: 8px; }
  .chats li { flex: none; padding: 6px 10px; border: 1px solid var(--line); }
  .chats .title { max-width: 140px; }
  .chats .when { display: none; }
  /* На телефоне левая панель — горизонтальная полоса. Раскладушка в ней
     остаётся кнопкой, а открытый список выезжает листом снизу поверх беседы:
     втиснуть его в полосу нельзя, а прятать шаблоны от телефона — значит
     оставить их тем, кто и так за компьютером. */
  .templates { margin: 0; flex: 0 0 auto; }
  .templates.open #templates-list {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
    max-height: 60vh; overflow-y: auto;
    background: #fff; border-top: 1px solid var(--line);
    padding: 12px 16px 20px; box-shadow: 0 -8px 24px rgba(0, 0, 0, .18);
  }
  #thread { padding: 12px; }
  .msg, .page { margin-bottom: 16px; }
  /* 24px — высота полосы жестов Android. Держим её как запас: в оболочке
     установленного приложения env(...) иногда приходит нулевым, и без
     запаса кнопка «Отправить» оказывается под самой полосой. */
  .composer { padding: 8px 10px; padding-bottom: max(24px, env(safe-area-inset-bottom)); }
  .composer .box { padding: 8px 10px 6px; border-radius: 8px; }
  /* На телефоне экран короткий: поле начинается с двух строк и всё так же
     растёт под текст, но не съедает больше трети экрана. */
  .composer textarea { min-height: 48px; max-height: 32vh; }
  .composer .model-note { display: none; }
}

/* Обзвон: слева очередь, справа карточка. На телефоне — одна колонка. */
.calls { display: grid; grid-template-columns: minmax(260px, 340px) 1fr; gap: 16px; padding: 16px; }
@media (max-width: 760px) { .calls { grid-template-columns: 1fr; } }
/* На широком экране страница целиком не прокручивается — прокручивается
   каждая колонка сама по себе. Раньше колонки жили в общей прокрутке
   страницы: оператор долистывал очередь до нужной группы, открывал клиента —
   и вместе с карточкой в начало уезжала очередь. Теперь наверх поднимается
   только карточка, а очередь остаётся ровно там, где её оставили. */
@media (min-width: 761px) {
  body.calls-page { display: flex; flex-direction: column; height: 100%; max-height: 100dvh; }
  body.calls-page .top, body.calls-page .ringing { flex: none; }
  body.calls-page .calls { flex: 1; min-height: 0; }
  body.calls-page .calls .queue, body.calls-page .calls .card {
    overflow-y: auto; min-height: 0; padding-right: 6px; }
}
/* Менеджеры сложены в раскладушку (.circle-box), поэтому ряду галочек
   больше не нужен свой flex — им занимается сама раскладушка. */
.calls .managers { margin-bottom: 8px; }
.calls .manager { display: inline-flex; align-items: center; gap: 4px; font-size: 14px; }
/* «Все» стоит первой в том же ряду, что и фамилии, — жирная и с полосой
   справа, чтобы её не принимали за ещё одного менеджера. */
.calls .manager.pick-all { font-weight: 600; padding-right: 12px;
  border-right: 1px solid #d8d8d8; margin-right: 2px; }
.calls .count { color: #777; font-size: 14px; }
.calls #search { width: 100%; padding: 8px; margin-bottom: 8px; }
/* Фильтр по проблемам: три значка-переключателя над поиском. Нажатый значок
   тёмный, чтобы «включено» читалось без подписи. */
.calls .signals-filter { display: flex; flex-wrap: wrap; align-items: center;
  gap: 6px; margin-bottom: 8px; }
.calls .signals-filter .label { font-size: 14px; color: var(--muted); }
.calls .signal { display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px; border: 1px solid #d8d8d8; border-radius: 999px;
  background: #fff; font-size: 14px; cursor: pointer; }
.calls .signal.on { background: #2f2f2f; border-color: #2f2f2f; color: #fff; }
.calls .signal.on .count { background: #fff; color: #2f2f2f; }
.calls .signal[disabled] { opacity: .4; cursor: default; }
.calls .signal.reset { font-size: 14px; }
.calls .signals-filter .note { font-size: 14px; color: var(--muted); }
/* «Что предложить»: четыре свёрнутых списка вместо четырёх простыней. */
.calls .offer summary { cursor: pointer; font-weight: 600; padding: 4px 0; }
/* Группа очереди — раскладушка: заголовок нажимается и складывает список.
   Заголовок липнет к верху колонки, пока листаешь длинную группу, — иначе
   в середине «Теряем» уже не видно, что это за список. */
.calls .group { margin-bottom: 6px; }
.calls .group > summary { position: sticky; top: 0; z-index: 1;
  margin: 0 0 6px; padding: 6px 0; font-size: 14px; font-weight: 600;
  background: var(--bg, #faf9f7); cursor: pointer; }
.calls .group > summary:hover { color: var(--accent); }
/* Пустая группа не занимает два ряда («заголовок» плюс «Пусто») — она
   сворачивается в одну серую строку: в обычный день пустых групп половина. */
.calls .group.is-empty { margin: 6px 0; padding: 6px 0; font-size: 14px;
  color: var(--muted); font-weight: 600; }
.calls .group.is-empty .count { font-weight: 400; }
.calls .count { display: inline-block; min-width: 20px; padding: 0 6px;
  border-radius: 999px; background: #ececea; color: #555;
  font-size: 12px; font-weight: 600; text-align: center; }
.calls .group.is-empty .count { background: none; padding: 0; }
.calls .client { display: grid; width: 100%; text-align: left; padding: 8px; margin-bottom: 4px;
  border: 1px solid #ddd; border-radius: 8px; background: #fff; cursor: pointer; }
.calls .client .name { font-weight: 600; }
.calls .client .money, .calls .client .when { color: #666; font-size: 14px; }
.calls .client .note { color: #8a6d00; font-size: 14px; font-weight: 600; }
/* Полоска слева вместо заливки: заливка читается как «ошибка» и спорит
   с красными плашками стоп-признаков в карточке. Оранжевая — один сигнал,
   красная — два и больше. */
.calls .client:hover { border-color: #bdbdb8; }
/* Клиент, который сейчас открыт справа. Очередь больше не уезжает при
   открытии карточки, поэтому по списку видно, на ком остановились. */
.calls .client.is-open { background: #eef4f0; border-color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent); }
.calls .client.warn { border-left: 4px solid #c08a00; }
.calls .client.alarm { border-left: 4px solid #b3261e; }
/* График звонков из 1С и телефоны с подписью вида. Первый номер — тот, по
   которому обычно звонят за заказом, поэтому он крупнее остальных. */
.calls .schedule { margin: 2px 0 8px; color: #0b6b3a; font-weight: 600; }
/* День рождения контактного лица — рядом с графиком звонков, но своим цветом. */
.calls .birthday { margin: 2px 0 8px; color: #b3261e; font-weight: 600; }
/* Своя акция по брошенной марке — отдельным видом внутри «Действующих акций»,
   у неё есть механика, которую нужно проговорить оператору. */
.calls .brand-promo { margin: 2px 0 8px; padding: 6px 8px; border-radius: 8px; background: #eaf5ee; }
.calls .brand-promo .mech { display: block; color: var(--accent); }
.calls ul.phones { list-style: none; margin: 6px 0; padding: 0; }
.calls ul.phones li { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.calls ul.phones li.main { font-size: 16px; }
.calls ul.phones .kind { color: #666; font-size: 14px; }
.calls .stop { background: #b3261e; color: #fff; padding: 8px 10px; border-radius: 8px; margin-bottom: 8px; }
.calls .stop.claim { background: #8a6d00; }
.calls .figures { display: flex; flex-wrap: wrap; gap: 12px; margin: 10px 0; color: #333; }
/* Соседние точки на том же телефоне. Свёрнуты: у сети их бывает десяток, и
   развёрнутый список вытеснял цифры за нижний край экрана телефона. Строго по
   строке на точку и по левому краю — как остальная карточка. */
.calls .siblings { margin: 6px 0; color: #333; text-align: left; }
.calls details.siblings > summary { cursor: pointer; color: #555; }
.calls details.siblings ul { list-style: none; margin: 4px 0 0; padding: 0 0 0 14px; }
.calls details.siblings li { margin-bottom: 2px; }
.calls .siblings .link { display: inline-block; text-align: left; padding: 3px 0; }
/* Блок ларей в карточке. Цвет берёт только полоска слева: заливка спорила бы
   с красными плашками стоп-признаков над ней. Список свёрнут по умолчанию —
   четыре строки моделей вытесняют с экрана телефона то, ради чего карточку
   открыли. */
.calls .freezers { border-left: 4px solid #ccc; padding: 6px 10px; margin: 8px 0; background: #f6f8fa; border-radius: 8px; }
.calls .freezers.green { border-left-color: #1e7a3c; }
.calls .freezers.yellow { border-left-color: #c08a00; }
.calls .freezers.red, .calls .freezers.black { border-left-color: #b3261e; }
.calls .freezers .head { margin: 0; font-weight: 600; }
.calls .freezers .norm { color: #666; font-weight: 400; }
.calls .freezers .owner { margin: 2px 0 0; color: #666; font-size: 14px; }
/* «Показать лари» — такая же нажимаемая строка, как заголовки в «Что
   предложить»: 13-й серый шрифт читался как подпись, палец в него не попадал,
   и раскладушку просто не замечали. */
.calls .freezers summary { cursor: pointer; font-weight: 600; padding: 4px 0; }
.calls .freezers ul { margin: 4px 0 0; padding-left: 18px; }
.calls .freezers .also { color: #8a6d00; }
/* «Коровка из Кореновки». Строка-вывод в блоке ларей и метка у самого ларя
   в списке оборудования: продавцу важно с одного взгляда понять, чей ларь. */
.calls .freezers .kik { margin: 4px 0 0; font-size: 14px; color: #444; }
.calls .freezers .kik.alarm { color: #b3261e; font-weight: 600; }
.calls .freezers .kik.ok { color: #1e7a3c; }
.calls .freezers .kik-tag { display: inline-block; padding: 0 6px; border-radius: 999px;
  background: #e7f0ff; color: #1c4e9c; font-size: 12px; font-weight: 600; vertical-align: 1px; }
.calls .talk summary { cursor: pointer; }
.calls .talk .sum { color: #555; }
.calls .transcript { white-space: pre-wrap; background: #f6f6f6; padding: 8px; border-radius: 8px; }
.calls .offer ul { margin: 4px 0 12px; padding-left: 18px; }
.calls .offer .why { color: #666; font-size: 14px; }
/* Брошенная марка внутри «Пропало из заказов»: заголовок с подписью и кнопкой,
   под ним — позиции этой марки. Полоса слева отделяет группу от остальных
   пропавших позиций, которые идут ниже общим списком. */
.calls .lost-brand { border-left: 3px solid #d9534f; padding-left: 8px; margin: 6px 0 10px; }
.calls .lost-brand .head { margin: 0 0 2px; font-weight: 600; }
.calls .lost-brand .head .why { font-weight: 400; display: block; }
.calls .lost-brand ul { margin: 4px 0 0; }
.calls .promos li.fits { background: #fff6d6; }
.calls .outcomes { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.calls .outcomes button { padding: 10px 14px; font-size: 14px; }
.calls .empty { color: #777; }
/* Кнопка возврата к списку. На широком экране обе колонки видны сразу —
   возвращаться некуда, поэтому кнопка живёт только на узком. */
/* Строка со свежестью и кнопкой возврата. На широком экране кнопки нет, и
   полоса свежести занимает строку целиком — как раньше. */
.topbar { display: flex; align-items: center; }
.back { display: none; }
/* Кнопка «Обсудить» на карточке клиента/задачи. Видимость держит JS
   (атрибут hidden при открытии/закрытии карточки) — CSS только про то,
   как она выглядит, когда видна. */
.btn-flat { padding: 8px 12px; font-size: 14px; border: 1px solid var(--line);
  border-radius: 8px; background: #fff; cursor: pointer; margin-left: 8px; }
.calls .callback-box { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
/* Панель прячется атрибутом hidden, а он проигрывает display: flex выше:
   без этой строки поле даты видно всегда, ещё до нажатия «Позже». */
.calls .callback-box[hidden] { display: none; }
.calls .callback-box button, .calls .callback-box input { padding: 10px 14px; font-size: 16px; }
/* Кнопки итога прижаты к низу экрана — и на телефоне, и на компьютере: до них
   дотягивается большой палец, а на длинной карточке не нужно листать обратно
   вверх после разговора. Липнет весь хвост целиком, вместе с панелью даты:
   когда липли одни кнопки, панель «Позже» открывалась ниже края экрана и
   выглядела как «не нажалось». */
.calls .tail { position: sticky; bottom: 0; z-index: 2; background: #fff;
  padding: 8px 0 calc(8px + env(safe-area-inset-bottom)); }
.calls .tail .outcomes { margin-top: 0; }
/* Липкий хвост стоит поверх конца карточки и накрывал последние блоки
   («Действующие акции», нижние предложения). Пустое место под ним даёт
   доскроллить: хвост доходит до своего места в потоке и отлипает. */
.calls #card-body { padding-bottom: 96px; }

@media (max-width: 760px) {
  .calls { padding: 12px; gap: 0; }
  /* Список и карточка — две страницы: показываем ровно одну. */
  .calls .card { display: none; }
  body.card-open .calls .queue { display: none; }
  body.card-open .calls .card { display: block; }
  /* Служебная строка одна на всех: слева «← К списку», справа свежесть
     данных. По умолчанию её нет вовсе — иначе у оператора (пакета ему не
     собирают) и в списке она висела бы пустой серой полосой. */
  .topbar { display: none; gap: 8px; padding: 6px 12px;
    background: #f4f4f2; border-bottom: 1px solid var(--line); }
  body.card-open .topbar, .topbar:has(> .freshness:not([hidden])) { display: flex; }
  /* Полоса теперь рисуется строкой целиком, поэтому своё оформление свежесть
     отдаёт наверх — кроме тревожного цвета «без связи». */
  .topbar .freshness { padding: 0; background: none; border: 0; justify-content: flex-end; }
  /* На широком экране полоса идёт во всю ширину, и дату разумно держать
     слева. В общей строке она бы висела посреди пустого места — прижимаем
     её к «Обновить», одной группой справа. */
  .topbar .freshness button { margin-left: 0; }
  .topbar:has(> .freshness.offline) { background: #fdf3e3; }
  body.card-open .back { display: inline-block; padding: 8px 12px; font-size: 14px; }
  /* Телефон — главное действие на этом экране: кнопка во всю ширину,
     чтобы попадать пальцем не глядя. */
  .calls ul.phones li { display: block; margin-bottom: 8px; }
  .calls ul.phones li a, .calls ul.phones li .dial {
    display: block; width: 100%; box-sizing: border-box; text-align: center;
    padding: 14px; font-size: 20px; font-weight: 600; border-radius: 8px;
    border: 1px solid #0b6b3a; color: #0b6b3a; text-decoration: none; background: #fff; }
  .calls ul.phones li.main a, .calls ul.phones li.main .dial { background: #0b6b3a; color: #fff; }
  .calls ul.phones .kind { display: block; text-align: center; margin-top: 2px; }
  .calls .client { padding: 12px; }
  .calls .outcomes button, .calls .callback-box button, .calls .callback-box input {
    flex: 1 1 45%; padding: 14px; font-size: 16px; }
}

/* Плашка «звонит такой-то»: узкая полоса под шапкой. Звука нет — телефон
   и так звонит. Экран сам не меняется, плашка только предлагает открыть. */
/* Звонок из карточки: кнопка вместо ссылки tel:, под ней ответ Сипуни. */
.dial { font-size: 14px; padding: 4px 10px; border-radius: 8px; cursor: pointer; }
.dial-msg { font-size: 14px; color: var(--muted); margin: 4px 0 0; }
.dial-msg.bad { color: #b00; }

.ringing { background: #0b6b3a; color: #fff; padding: 8px 16px; }
.ringing .call { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.ringing .label { text-transform: uppercase; font-size: 12px; letter-spacing: 0.06em; opacity: 0.85; }
.ringing .phone { font-size: 16px; font-weight: 600; }
.ringing .pick { display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px;
  border: 1px solid rgba(255,255,255,0.5); border-radius: 8px; background: transparent;
  color: inherit; font: inherit; cursor: pointer; }
.ringing .pick:hover { background: rgba(255,255,255,0.15); }
.ringing .zone { opacity: 0.85; font-size: 14px; }
/* Не кнопка: подпись внутри кнопки звонка, подчёркнута как ссылка. */
.ringing .link-text { text-decoration: underline; }
.ringing .more { opacity: 0.85; font-size: 14px; }
@media (max-width: 760px) { .ringing { padding: 8px 12px; } }

/* Полоска свежести данных: без связи торгпред должен видеть, на какой момент
   у него сведения, а не гадать. */
.freshness {
  display: flex; align-items: center; flex: 1; gap: 8px;
  padding: 6px 12px; font-size: 14px; color: #555;
  background: #f4f4f2; border-bottom: 1px solid var(--line);
}
.freshness[hidden] { display: none; }
.freshness.offline { background: #fdf3e3; color: #8a5a00; }
.freshness button { margin-left: auto; padding: 4px 10px; font-size: 14px; }
.need-net { margin: 6px 0 0; font-size: 14px; color: #8a5a00; }
/* Раздел «Задачи». Первая версия шла голой разметкой: браузерные кнопки,
   активная вкладка отличалась только жирностью, поля ввода в нитку. Здесь
   тот же язык, что и в «Клиентах» — белые карточки на сером поле. */
.tasks { display: flex; gap: 14px; align-items: flex-start; padding: 14px; }
/* На широком экране страница целиком не прокручивается — прокручивается
   каждая колонка сама по себе, как в «Клиентах». Иначе, кликнув по задаче
   внизу длинного списка, человек оставался внизу страницы, а карточка
   открывалась выше экрана — и казалось, что ничего не произошло. */
@media (min-width: 761px) {
  body.tasks-page { display: flex; flex-direction: column; height: 100%; max-height: 100dvh; }
  body.tasks-page .top { flex: none; }
  body.tasks-page .tasks { flex: 1; min-height: 0; }
  /* align-items: flex-start у .tasks мерил бы колонки по их содержимому, и
     своя прокрутка у них не появилась бы вовсе: длинный список по-прежнему
     тянул бы вниз всю страницу. Обеим колонкам — высота во всю полосу. */
  body.tasks-page .tasks { align-items: stretch; }
  body.tasks-page .tasks .task-list, body.tasks-page .tasks .task-card {
    overflow-y: auto; min-height: 0; padding-right: 6px; }
}
.task-list { flex: 1 1 340px; min-width: 0; }
.task-card { flex: 2 1 420px; min-width: 0;
  background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 14px; }
.task-card h2 { margin: 0 0 6px; font-size: 20px; }
.task-card .props { color: #555; font-size: 14px; margin: 0 0 10px; }
.task-card .empty { color: #888; margin: 0; }

/* Вкладки — сегменты, у выбранной видна заливка, а не только жирность. */
.tabs { display: flex; gap: 0; margin-bottom: 10px;
  border: 1px solid #d5d5d5; border-radius: 8px; overflow: hidden; background: #fff; }
.tabs button { flex: 1; padding: 8px 6px; font-size: 14px; border: 0;
  background: #fff; color: #333; cursor: pointer; }
.tabs button + button { border-left: 1px solid var(--line); }
.tabs button.active { background: var(--accent); color: #fff; font-weight: 600; }

.list-tools { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
#new-task { margin-left: auto; padding: 7px 12px; border: 0; border-radius: 8px;
  background: var(--accent); color: #fff; font-size: 14px; cursor: pointer; }
#new-task[hidden] { display: none; }

/* «Включить уведомления» — рядом с «Новой задачей», но тише её: это
   разовая настройка, а не ежедневное действие. Пропадает, как только
   уведомления включены. */
.push-on { padding: 7px 12px; border: 1px solid #d5d5d5; border-radius: 8px;
  background: #fff; color: #444; font-size: 14px; font-family: inherit; cursor: pointer; }
.push-on[hidden] { display: none; }
/* Кнопки над списком разговоров. Свой класс, а не «.list-tools button»:
   тот же блок используют «Клиенты» и «Задачи». */
.room-tool { padding: 7px 12px; border: 1px solid #d5d5d5; border-radius: 8px;
  background: #fff; color: #444; font-size: 14px; font-family: inherit; cursor: pointer; }
.room-tool:hover { background: #f4f4f2; }
.room-tool.primary { border-color: var(--accent); background: var(--accent); color: #fff; }
.room-tool.primary:hover { background: #275e43; }
.room-tool[hidden] { display: none; }

/* Фильтр «кому поручено» — слева, «Новая задача» остаётся справа (её
   margin-left: auto). Длинное имя ужимаем многоточием, чтобы на телефоне
   строка не разъезжалась. */
#who-filter { max-width: 60%; padding: 6px 8px; font-size: 16px; font-family: inherit;
  border: 1px solid #d5d5d5; border-radius: 8px; background: #fff; color: inherit; }
#who-filter[hidden] { display: none; }

/* Группа задач — раскладушка: заголовок со счётчиком, список можно свернуть.
   Имя корзины в классе пишем с приставкой b-: без неё «fresh» ловил чужой
   стиль полосы свежести и группа «Свежие» съезжала белой карточкой. */
.bucket { margin: 12px 0 6px; }
.bucket > summary { font-size: 14px; color: #666; margin-bottom: 6px; padding: 2px 0;
  text-transform: uppercase; letter-spacing: .03em; cursor: pointer; }
.bucket > summary:hover { color: var(--accent); }
.bucket .count { display: inline-block; min-width: 20px; padding: 0 6px;
  border-radius: 999px; background: #ececea; color: #555;
  font-size: 12px; font-weight: 600; text-align: center; letter-spacing: 0; }
.task-row { padding: 10px 12px; margin-bottom: 6px; cursor: pointer;
  background: #fff; border: 1px solid var(--line); border-radius: 8px; }
.task-row:hover { border-color: #bcd6c6; }
.task-row.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.task-row .title { display: block; font-weight: 600; margin-bottom: 2px; }
.task-row .meta { color: #666; font-size: 14px; }
.bucket.b-overdue > summary, .bucket.b-overdue .task-row .title { color: #b3261e; }
/* Точка «в задаче что-то новое с вашего прошлого захода» — на вкладке
   «Я поручил». Пропадает сама, как только карточку открыли. */
.task-row.new .title::before { content: '•'; color: var(--accent); margin-right: 5px; }
.bucket.b-silent > summary { color: #b3261e; }
/* Задачи одной торговой точки внутри корзины — общей рамкой с шапкой,
   чтобы три дела по одному магазину не читались как три разных клиента. */
.outlet { border: 1px solid #dfe7e1; border-radius: 8px; padding: 6px;
  margin-bottom: 8px; background: #f4f8f5; }
.outlet-head { font-size: 14px; font-weight: 600; color: var(--accent); padding: 2px 6px 6px; }
.outlet .task-row:last-child { margin-bottom: 0; }

.feed { margin-top: 10px; }
.feed .entry { padding: 6px 0; border-bottom: 1px dashed #eee; }
.feed .entry.system { color: #777; font-size: 14px; }
.feed .when { color: #999; margin-right: 6px; font-size: 12px; }

/* Поля в карточке — во всю ширину. */
.task-card input[type="text"], .task-card textarea {
  width: 100%; box-sizing: border-box; padding: 8px 10px; font-size: 16px;
  border: 1px solid #d5d5d5; border-radius: 8px; font-family: inherit; }

/* Строка ответа: поле и «Отправить» в общей рамке, как в переписке. Рамку
   рисует обёртка, у самого поля её нет — иначе получилась бы рамка в рамке.
   Место под кнопку освобождает padding-right у поля, поэтому текст под
   кнопку не заезжает. */
.task-card .reply { position: relative; margin-top: 10px;
  border: 1px solid #d5d5d5; border-radius: 8px; background: #fff; }
.task-card .reply:focus-within { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.task-card .reply input[type="text"] { border: 0; background: none; padding: 10px 108px 10px 12px; }
.task-card .reply input[type="text"]:focus { outline: none; }
.task-card .reply button { position: absolute; top: 4px; right: 4px; bottom: 4px;
  padding: 0 14px; border: 0; border-radius: 8px;
  background: var(--accent); color: #fff; font-size: 14px; cursor: pointer; }

/* Шапка карточки: заголовок слева, «Закрыть задачу» справа. Наверху, а не
   под строкой ответа, — иначе кнопка стоит вплотную к «Отправить» и в неё
   легко ткнуть мимо. Длинный заголовок кнопку не сжимает (flex-shrink: 0),
   а на узком экране она переносится под него. */
.task-card .card-head { display: flex; flex-wrap: wrap; align-items: flex-start;
  justify-content: space-between; gap: 8px 12px; margin-bottom: 6px; }
.task-card .card-head h2 { margin: 0; }
.task-card .card-head button { flex: 0 0 auto; padding: 7px 14px;
  border: 1px solid #d5d5d5; border-radius: 8px; background: #fff;
  font-size: 14px; cursor: pointer; }
/* Главное действие карточки — контурное, а не залитое: карточек в списке
   много, и десяток зелёных плашек забивал бы сам список. */
.task-card .card-head button.card-main { color: var(--accent); border-color: #bcd6c6; font-weight: 600; }
.task-card .card-head button.card-main:hover { background: #eef5f0; }

/* Окно «Новая задача». */
.task-dialog { border: 0; border-radius: 8px; padding: 0; width: min(420px, 92vw); }
.task-dialog::backdrop { background: rgba(0,0,0,.35); }
.task-dialog form { padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.task-dialog h3 { margin: 0; font-size: 20px; }
.task-dialog label { display: flex; flex-direction: column; gap: 4px; font-size: 14px; color: #555; }
.task-dialog .hint { color: #999; }
/* Досье по точке в окне заведения: что тут уже поручали. Свёрнуто — открывают
   те, кому есть о чём вспомнить; совпавшее по поводу подсвечено. */
.task-dialog .past { font-size: 14px; }
.task-dialog .past summary { cursor: pointer; color: #555; }
.task-dialog .past-list { max-height: 220px; overflow-y: auto; margin-top: 6px; }
.task-dialog .past-row { padding: 6px 8px; border-radius: 8px; background: #f6f6f6; margin-bottom: 4px;
  display: flex; flex-direction: column; gap: 2px; }
.task-dialog .past-row.same { background: #fff4d6; }
.task-dialog .past-row .meta { color: #888; font-size: 12px; }
.task-dialog .past-row .outcome { color: #555; }
.task-dialog input, .task-dialog select, .task-dialog textarea {
  padding: 8px 10px; font-size: 16px; border: 1px solid #d5d5d5; border-radius: 8px;
  font-family: inherit; color: #222; }
.task-dialog .err { margin: 0; color: #b3261e; font-size: 14px; }
.task-dialog .row { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }
.task-dialog .row button { padding: 8px 14px; border-radius: 8px; font-size: 14px; cursor: pointer;
  border: 1px solid #d5d5d5; background: #fff; }
.task-dialog .row button.primary { background: var(--accent); color: #fff; border-color: var(--accent); }

/* Размножение задачи по партнёрам с той же пропавшей позицией. Свёрнуто:
   обычно заводят одну задачу, и лишний блок не должен мешать. */
.task-dialog .spread { border: 1px solid #e6e6e6; border-radius: 8px; padding: 8px 10px; }
.task-dialog .spread summary { font-size: 14px; color: var(--accent); cursor: pointer; }
.task-dialog .spread > *:not(summary) { margin-top: 8px; }
.task-dialog .spread p { margin: 8px 0 0; font-size: 14px; }
.task-dialog .people { display: flex; flex-wrap: wrap; gap: 4px 12px; }
/* Галочка и подпись в строку: общее правило окна ставит поля столбиком. */
.task-dialog .people .one, .task-dialog .found-row {
  flex-direction: row; align-items: baseline; gap: 6px; color: #222; }
.task-dialog .people .one input, .task-dialog .found-row input { flex: none; }
.task-dialog .howmany { flex-direction: row; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.task-dialog .howmany input { width: 70px; }
.task-dialog .spread .pick { padding: 6px 12px; border-radius: 8px; font-size: 14px;
  cursor: pointer; border: 1px solid #d5d5d5; background: #fff; align-self: flex-start; }
.task-dialog .found { display: flex; flex-direction: column; gap: 6px;
  max-height: 40vh; overflow-y: auto; }
.task-dialog .found-row { flex-wrap: wrap; padding: 4px 0; border-top: 1px solid #f0f0f0; }
.task-dialog .found-row .who { font-size: 14px; }
.task-dialog .found-row .meta { flex-basis: 100%; padding-left: 22px; font-size: 14px; color: #777; }

/* Ссылка на клиента в зелёном строе страницы, а не браузерная синяя. */
.task-card .link a { color: var(--accent); }

/* На компьютере служебной строки нет — там из карточки никуда возвращаться.
   Кроме случая, когда в ней висит свежесть запаса: торгпреду нужно видеть
   «Нет связи. Данные на …» и кнопку «Обновить» так же, как в «Клиентах». */
body.tasks-page .topbar:not(:has(> .freshness:not([hidden]))) { display: none; }
@media (max-width: 760px) {
  .tasks { flex-direction: column; padding: 10px; }
  /* Список и карточка — две страницы: показываем ровно одну. */
  .tasks .task-card { display: none; }
  body.card-open .tasks .task-list { display: none; }
  body.card-open .tasks .task-card { display: block; }
  /* Тот же :not(...), что и в правиле выше без медиа-запроса, повторён
     намеренно: медиа-запрос сам по себе веса не добавляет, и без этого
     довеска правило «на компьютере строки нет» перебивало это и кнопка
     «← К списку» на телефоне не показывалась вовсе. */
  body.tasks-page.card-open .topbar:not(:has(> .freshness:not([hidden]))) { display: flex; }
  body.tasks-page.card-open .back { display: inline-block; padding: 8px 12px; font-size: 14px; }
  /* Карточка задачи длинная. Если прокручивать страницу целиком, шапка с
     гамбургером и кнопка возврата уезжают за верхний край и уйти с экрана
     нечем. Схема та же, что в «Нашем чате»: высота считается через flex,
     прокручивается только список или только карточка. */
  body.tasks-page { display: flex; flex-direction: column; height: 100%; max-height: 100dvh; }
  body.tasks-page .top, body.tasks-page .topbar { flex: none; }
  body.tasks-page .tasks { flex: 1; min-height: 0; }
  body.tasks-page .tasks .task-list, body.tasks-page.card-open .tasks .task-card {
    overflow-y: auto; min-height: 0; }
}

/* «В задачи» стоит внутри строки беды и в списке пропавших позиций —
   маленькая, чтобы не спорить с кнопками итога разговора. */
.to-task {
  margin-left: 8px;
  padding: 2px 8px;
  font-size: 12px;
  border: 1px solid var(--accent);
  border-radius: 8px;
  background: #fff;
  color: var(--accent);
  cursor: pointer;
}
.to-task[disabled] { border-color: #bbb; color: #888; cursor: default; }

/* Открытые задачи по клиенту — блок в его карточке, сразу под бедами.
   Набран той же коробкой, что и лари: полоска слева, светлая заливка,
   жирная шапка с числом и строки под ней. Гамма своя, зелёная: это не
   проблема, а работа по ней. */
.client-tasks { margin: 8px 0; padding: 6px 10px; border-left: 4px solid var(--accent);
  background: #f2f7f4; border-radius: 8px; }
.client-tasks .head { margin: 0; color: var(--accent); font-weight: 600; }
.client-tasks .task-line { display: block; padding: 4px 0; color: #222; text-decoration: none; }
.client-tasks .task-line + .task-line { border-top: 1px solid #e0eae4; }
.client-tasks .task-line .title { display: block; }
.client-tasks .task-line .meta { color: #666; font-size: 14px; }
.client-tasks .task-line.overdue .title { color: #b3261e; }
.client-tasks .task-line:hover .title { text-decoration: underline; }
.client-tasks .more { display: inline-block; margin-top: 6px; font-size: 12px; color: var(--accent); }
/* Архив закрытых задач точки: свёрнут, шапка со счётчиком — как у групп в
   «Задачах». Строки бледнее открытых: это память, а не работа. */
.client-tasks .past { margin-top: 6px; border-top: 1px solid #e0eae4; padding-top: 4px; }
.client-tasks .past > summary { cursor: pointer; color: var(--accent); font-size: 14px; }
.client-tasks .past > summary .count { color: #666; }
.client-tasks .task-line.done .title { color: #555; }
.client-tasks .task-line.done .outcome { display: block; color: #444; font-size: 14px; }

/* ===== Раздел «Наш чат» ===================================================
   Две колонки: слева разговоры, справа лента сообщений. На телефоне колонки
   становятся двумя страницами — как в «Задачах»: список прячется, когда
   открыт разговор (класс on-room на body ставит rooms.js). Имена классов
   начинаются на .room-, потому что .msg в проекте занят беседой с ИИ. */
/* Поля по краям — как в «Клиентах» и «Задачах». Без них кнопки и карточки
   липли к самому краю окна, а шапка сверху отступала: строй ломался. */
.rooms { display: flex; gap: 16px; align-items: flex-start; padding: 14px; }
.room-list { flex: 1 1 300px; min-width: 0; }
.room-view { flex: 2 1 420px; min-width: 0;
  background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 14px; }
#room-title { margin: 0 0 2px; font-size: 16px; }
/* Должность: под именем в шапке беседы и в строке списка. Мелко и серым —
   это подсказка «кто это», а не само имя. */
.room-post { margin: 0 0 2px; color: #777; font-size: 14px; }
/* Черта отделяет шапку разговора от ленты: раньше между ними был заметный
   провал, и заголовок будто висел сам по себе. */
.room-view > .room-feed { margin-top: 10px; padding-top: 10px; border-top: 1px solid #eee; }
.room-item .room-post { display: block; margin: 1px 0 0; }

/* Полоска дня рождения над списком разговоров. Видна всем и только в сам
   день; нажатие открывает личную переписку с именинником. */
.bday-bar { margin: 10px 14px 0; display: flex; flex-direction: column; gap: 6px; }
.bday-one { width: 100%; text-align: left; padding: 9px 12px; cursor: pointer;
  background: #fdf6e3; border: 1px solid #ecdcae; border-radius: 8px;
  font: inherit; font-size: 14px; color: #6b5417; }
.bday-one:hover { background: #f9edcf; }

/* Строка разговора в списке: имя сверху, последнее сообщение серым снизу,
   справа — сколько непрочитанных. */
/* Аватарка. Круг одного размера и для фотографии, и для букв — иначе строки
   списка прыгали бы в зависимости от того, у кого фото есть, а у кого нет.
   flex: none, чтобы длинное имя рядом не сплющивало кружок. */
.ava { display: inline-flex; align-items: center; justify-content: center;
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  overflow: hidden; object-fit: cover;
  color: #fff; font-size: 14px; font-weight: 600; line-height: 1;
  background: #4a5568; }
.ava.sm { width: 30px; height: 30px; font-size: 12px; }
/* Распорка под аватаркой у второго и следующих сообщений подряд: место
   занимает, сама не видна — пузыри стоят одной колонкой. */
.ava.hole { visibility: hidden; }

.room-item { display: flex; align-items: center; gap: 10px;
  width: 100%; text-align: left; padding: 10px 12px;
  margin-bottom: 6px; cursor: pointer;
  background: #fff; border: 1px solid var(--line); border-radius: 8px; font: inherit; }
/* Тексты строки — своей колонкой справа от кружка. min-width: 0 обязателен:
   без него длинное последнее сообщение не даёт колонке сжаться и «…» в конце
   не появляется. */
.room-body { flex: 1 1 auto; min-width: 0; }
.room-item.on { border-color: var(--accent); background: #f5f9f7; }
.room-name { display: block; font-weight: 600; color: #222; }
.room-last { display: block; margin-top: 2px; color: #666; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Когда в разговоре последний раз что-то говорили. Своей колонкой справа,
   flex: none — иначе дата переносится по словам и строка распухает. */
.room-when { flex: none; color: #999; font-size: 12px; white-space: nowrap; }
.room-unread { flex: none; display: inline-block; min-width: 20px; padding: 0 6px;
  border-radius: 999px; background: var(--accent); color: #fff;
  font-size: 12px; font-weight: 600; text-align: center; }

/* Лента сообщений. Прокручивается сама, чтобы поле ввода всегда было внизу
   и не уезжало за край экрана. */
.room-feed { display: flex; flex-direction: column; gap: 6px;
  height: 60vh; overflow-y: auto; padding-right: 6px; }
/* Пузырь сжимается по содержимому: у своих он прижат вправо, у чужих влево.
   Без align-self чужой пузырь растягивался на все 80% ленты — у обычного
   текста это почти не видно, а у одного крупного смайлика время улетало
   к правому краю за полэкрана. Заметнее всего было в группах. */
.room-msg { align-self: flex-start; max-width: 80%; padding: 8px 10px; border-radius: 8px;
  background: #f4f4f2; border: 1px solid #e6e6e6; word-wrap: break-word; }
.room-msg.mine { align-self: flex-end; background: #f2f7f4; border-color: #cfe0d6; }
.room-msg .room-text { white-space: pre-wrap; }
/* Имя написавшего над сообщением. Только в группах и только у чужих: в личке
   и в заметках и так понятно, кто говорит. */
.room-who { display: block; margin-bottom: 2px; color: var(--accent); font-size: 12px; font-weight: 600; }
/* Время, галочка и ⋮ — своей строкой под текстом. Раньше они вклинивались
   в конец фразы, и пузырь читался рвано. */
.room-meta { display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  margin-top: 3px; line-height: 1; }
.room-msg .room-time { color: #999; font-size: 12px; }
/* Плашка с датой между днями. Стоит по центру ленты отдельной строкой:
   align-self обязателен, иначе она растянулась бы на всю ширину колонки. */
.room-day { align-self: center; margin: 6px 0 2px; }
.room-day span { display: inline-block; padding: 2px 10px; border-radius: 999px;
  background: #ececea; color: #666; font-size: 12px; }
.room-msg i { color: #888; }
/* Нарисованный значок (скрепка): линия в цвет текста рядом, без заливки.
   Размер задан в пикселях, чтобы значок не зависел от шрифта. */
.ico { display: block; width: 15px; height: 15px; fill: none; stroke: currentColor;
  stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
/* Одна кнопка ⋮ вместо трёх значков под пузырём. На компьютере она появляется
   при наведении, на телефоне видна всегда: там наводить нечем, и раньше под
   каждым сообщением постоянно висели «переслать», «скачать» и «удалить». */
.room-more { position: relative; padding: 2px 4px; border: 0; background: none; color: #6b6b6b;
  font-size: 20px; line-height: 1; cursor: pointer; }
/* Невидимый «воротник» вокруг точек. Сами точки узкие, и пальцем в них не
   попасть: раньше область нажатия была меньше 20 px при нужных 44. Расширяем
   псевдоэлементом, а не отступами, чтобы строка времени не разъехалась. */
.room-more::after { content: ''; position: absolute; left: 50%; top: 50%;
  width: 44px; height: 40px; transform: translate(-50%, -50%); }
.room-more:hover { color: var(--accent); }
@media (hover: hover) {
  .room-more { opacity: 0; transition: opacity .12s; }
  .room-msg:hover .room-more, .room-more:focus { opacity: 1; }
}

/* Список действий над сообщением. Лежит поверх страницы (position: fixed),
   место ему считает JS от кнопки ⋮. Правило [hidden] обязательно: display
   у блока задан явно и сам по себе перебил бы скрытие. */
.msg-menu { position: fixed; z-index: 40; min-width: 150px; padding: 4px;
  display: flex; flex-direction: column;
  background: #fff; border: 1px solid #e0e0e0; border-radius: 8px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .14); }
.msg-menu[hidden] { display: none; }
.msg-menu-i { display: block; width: 100%; padding: 9px 12px; border: 0; border-radius: 8px;
  background: none; color: #222; font: inherit; font-size: 14px;
  text-align: left; text-decoration: none; cursor: pointer; }
.msg-menu-i:hover { background: #f2f5f3; }
.msg-menu-i.danger { color: #b3261e; }

/* Шапка разговора: имя слева, трубка следом. Правый отступ такой же, как у
   ленты, иначе имя стоит правее пузырей и шапка выглядит съехавшей. */
.room-head { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding-right: 6px; }

/* Зелёная трубка: кружок сразу за именем (margin-right: auto отодвигает от неё
   всё остальное вправо). Размер 40×40 — в такую попадают пальцем на телефоне. */
.room-call { display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; margin-right: auto; flex: none; border-radius: 50%;
  background: #2f9e5e; color: #fff; text-decoration: none; }
.room-call:hover { background: #268650; }
.room-call[hidden] { display: none; }

/* Та же трубка в списке коллег: строка — кнопка во всю ширину и трубка справа. */
.room-pick .pick-line { display: flex; align-items: center; gap: 8px; }
.room-pick .pick-line .pick-one { flex: 1 1 auto; min-width: 0; }
.room-pick .pick-call { display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: none; border-radius: 50%;
  background: #2f9e5e; color: #fff; text-decoration: none; }
.room-pick .pick-call:hover { background: #268650; }

/* Полоска выбора вместо строки ввода: сколько отмечено, «Переслать», «Отмена».
   Полоса идёт во всю ширину и лежит на светлой подложке — она занимает место
   строки ввода, и без подложки кнопки выглядели брошенными у левого края.
   Подпись прижата влево, кнопки — вправо (margin-right: auto у подписи). */
.sel-bar { display: flex; align-items: center; gap: 10px; margin-top: 10px;
  padding: 8px 12px; background: #f4f6f5; border: 1px solid var(--line); border-radius: 999px; }
.sel-bar[hidden] { display: none; }
.sel-count { margin-right: auto; color: #555; font-size: 14px; }
/* Пока ничего не отмечено, «Переслать» не должна выглядеть почти нажимаемой:
   гасим не только прозрачность, но и зелёный цвет. */
.room-tool:disabled { opacity: 1; cursor: default;
  background: #eee; border-color: #e0e0e0; color: #999; }

/* Строка во время выбора: галочка отдельной колонкой слева, справа от неё —
   обычный пузырь. Раньше галочка стояла внутри пузыря с обтеканием: у текста
   она сдвигала первую строку, у крупных смайликов (там пузыря нет) висела
   отдельно и растягивала блок, из-за чего время уезжало к правому краю.
   Курсор-палец подсказывает, что тыкать можно в любое место строки. */
.room-row { display: flex; align-items: center; gap: 8px; }
/* Колонка галочек стоит слева у всех строк, и у своих сообщений тоже: вправо
   уезжает сам пузырь (margin-left: auto), а не строка целиком. Иначе кружок
   прижимался к пузырю и гулял по горизонтали вслед за его шириной. */
.room-row.mine .room-msg { margin-left: auto; }
/* Внутри строки выбора пузырь выравнивает сама строка. Обычное правило
   .room-msg.mine { align-self: flex-end } здесь означало бы «прижать вниз». */
.room-row .room-msg { align-self: auto; }
/* Строка с аватаркой в ленте: кружок стоит у нижнего края пузыря, как в
   привычных мессенджерах, а не по его середине. */
.room-row.ava-row { align-items: flex-end; }
.room-row[data-pick] { cursor: pointer; }
.room-row.picked .room-msg { border-color: var(--accent); background: #eaf3ee; }
.room-row.picked .room-msg.big { border-color: transparent; background: none; }
/* Кружок нарисован рамкой, галочка внутри — двумя сторонами повёрнутого
   уголка. Символы ☐ и ☑ отпали: в каждом шрифте они своего размера и веса,
   и ряд галочек выглядел разнобоем. */
.room-tick { flex: none; width: 19px; height: 19px; box-sizing: border-box;
  border: 2px solid #bbb; border-radius: 50%; background: #fff; }
.room-tick.on { border-color: var(--accent); background: var(--accent); }
.room-tick.on::after { content: ''; display: block; width: 4px; height: 8px;
  margin: 2px auto 0; border: solid #fff; border-width: 0 2px 2px 0;
  transform: rotate(45deg); }
/* Удалённое и ещё не отправленное не выбирают: место под галочку остаётся,
   чтобы пузыри стояли на одной вертикали. */
.room-tick.off { visibility: hidden; }
.room-msg.pickable { cursor: pointer; }

/* Разговор в окне «Куда переслать?»: та же строка, что и в списке слева.
   Коллеги без начатого разговора (.pick-new) выглядят так же — разница
   только в подзаголовке над ними. */
.pick-room, .pick-new, .pick-open { display: block; width: 100%; text-align: left; padding: 9px 12px;
  margin-bottom: 6px; cursor: pointer;
  background: #fff; border: 1px solid var(--line); border-radius: 8px; font: inherit; }
.pick-room:hover, .pick-new:hover, .pick-open:hover { background: #f5f9f7; border-color: var(--accent); }
.pick-head { margin: 12px 0 6px; color: #888; font-size: 12px; }
/* След от удалённого: без пузыря и рамки, серым — чтобы он не читался как
   полноценная реплика. */
.room-msg.gone { background: none; border-color: transparent; padding: 2px 4px; }
.room-msg.gone .room-time { color: #bbb; }
/* Сообщение из одних смайликов — крупно и без пузыря, как в Ватсапе. */
.room-msg.big { background: none; border-color: transparent; padding: 2px 4px; }
.room-msg.big .room-text { font-size: 34px; line-height: 1.2; }

/* Ссылки на дело внутри сообщения («/tasks/12», «/calls/Пятёрочка»,
   decorateLinks в rooms.js) — без правила они рисовались бы браузером по
   умолчанию, синим и подчёркнутым, не в тон остальной переписке. */
.room-links { margin-top: 4px; font-size: 14px; }
.room-links a { color: var(--accent); text-decoration: underline; }
.room-links a:hover { color: #24593f; }

/* Вложения в ленте: фото — сразу картинкой, остальное — строкой с именем. */
.room-pic { display: block; max-width: 220px; border-radius: 8px; margin-bottom: 4px; }
.room-doc { text-decoration: underline; }
/* Отдельной строки со «скачать» под вложением больше нет: значок переехал в
   нижнюю строку пузыря, к «переслать» и «удалить». */

/* Строка про очередь: «отправим, когда появится связь». */
.queue-note { margin: 6px 0 0; color: #b3261e; font-size: 14px; }

/* Поле ввода — одной строкой с кнопкой и скрепкой слева от текста. */
/* Поле растёт вниз под текст, поэтому кнопка и скрепка прижаты к низу строки,
   а не к середине. Потолок — шесть строк (примерно 132px), дальше поле
   прокручивается внутри себя. Тянуть поле уголком мышью незачем: высоту
   считает сам браузер по тексту. */
/* position: relative — чтобы панель смайликов встала над строкой ввода. */
/* Плашка «Обсудить»: кого мы сейчас обсуждаем. Стоит над строкой ввода,
   ссылка приклеится к тексту при отправке. Крестик убирает прицеп. */
.room-pin { display: flex; align-items: center; gap: 8px; margin-top: 10px;
  padding: 6px 8px 6px 10px; border: 1px solid #d7e3d9; border-left: 3px solid #2e7d32;
  border-radius: 8px; background: #f2f8f3; font-size: 14px; }
.room-pin[hidden] { display: none; }
.room-pin-txt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Превью снимка, вставленного из буфера: картинка слева в плашке — видно,
   что именно уйдёт, до нажатия «отправить». Квадрат 72px: при 40px белый
   снимок экрана в плашке не читался, владелец его просто не замечала. */
.room-pin-pic { flex: none; width: 72px; height: 72px; object-fit: cover;
  border-radius: 8px; border: 1px solid #d7e3d9; background: #fff; }
.room-pin-pic[hidden] { display: none; }
.room-pin-pic { cursor: zoom-in; }
/* Снимок во весь экран по щелчку на квадратике. Слой выше всего остального
   (полоска обновления — 60), клик по нему в любом месте закрывает. */
.pic-big { position: fixed; inset: 0; z-index: 70; display: flex;
  align-items: center; justify-content: center; padding: 16px;
  background: rgba(0, 0, 0, .85); cursor: zoom-out; }
.pic-big[hidden] { display: none; }
.pic-big-img { max-width: 94vw; max-height: 94vh; object-fit: contain;
  border-radius: 8px; background: #fff; }
/* Двойной селектор: общее правило .room-send button красит кнопки зелёным,
   а крестику нужна прозрачная кнопка. */
.room-pin .room-pin-off, .room-pin button.room-pin-off { flex: none; padding: 2px 6px;
  border: 0; background: none; color: #5b6b5e; font-size: 14px; line-height: 1; cursor: pointer; }
.room-pin .room-pin-off:hover { color: #1b5e20; }

.room-send { position: relative; display: flex; align-items: flex-end; gap: 8px; margin-top: 10px; }
/* Голого атрибута hidden мало: display:flex выше его перебивает. */
.room-send[hidden] { display: none; }
/* Подсказка вместо строки ввода, пока разговор не выбран. */
.room-hint { margin: 10px 0 0; color: #667; font-size: 14px; }
/* Смайлик живёт внутри поля, у правого края, а не отдельной кнопкой снаружи —
   как в Телеграме. Он прижат к низу: когда поле вырастает под длинный текст,
   смайлик остаётся на уровне последней строки. Селектор двойной, иначе кнопку
   красит общее правило .room-send button (зелёный кружок). */
.room-send .emoji-btn { position: absolute; right: 6px; bottom: 5px;
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0; border: 0; border-radius: 50%;
  background: none; color: inherit; font-size: 20px; line-height: 1; cursor: pointer;
  opacity: .55; }
.room-send .emoji-btn:hover { opacity: 1; background: #f1f1ef; }
.room-send .emoji-btn.on { opacity: 1; background: #eef4f0; }
/* Панель — сплошная светлая заливка во всю ширину строки ввода, как в
   Телеграме: там смайлики лежат на общем светлом фоне, а не в белой
   коробке с рамкой. Рамку и жирную тень убрали, осталась мягкая тень,
   чтобы панель читалась поверх переписки. */
.emoji-panel { position: absolute; left: 0; right: 0; bottom: calc(100% + 8px); z-index: 5;
  padding: 10px; background: #eef4f0; border-radius: 8px;
  box-shadow: 0 4px 14px rgba(47, 111, 79, .14); }
.emoji-panel[hidden] { display: none; }
.emoji-row { display: grid; grid-template-columns: repeat(8, minmax(0, 1fr)); gap: 4px; }
/* Разделитель на зелёной заливке: серый #eee на ней выглядел грязным. */
.emoji-sep { height: 1px; margin: 8px 2px; background: rgba(47, 111, 79, .18); }
/* Клетка и сам смайлик крупные — как в Телеграме. При 21px в мелкой клетке
   рисунок не разбирался: «палец вверх» и «сложенные руки» сливались в жёлтое
   пятно. Шрифт указан цветной эмодзиевый: без него Windows и часть Android
   рисуют смайлики чёрно-белым контуром. */
/* Селектор нарочно двойной — .emoji-panel .emoji-one. Иначе клетки красит
   общее правило .room-send button (зелёный фон, белый текст): оно сильнее
   одиночного класса, и смайлики сидели тёмно-зелёными квадратами. */
.emoji-panel .emoji-one { width: 100%; height: 46px; padding: 0; border: 0; border-radius: 8px;
  background: none; color: inherit; font-size: 34px; line-height: 1; cursor: pointer;
  font-family: 'Apple Color Emoji', 'Segoe UI Emoji', 'Noto Color Emoji', sans-serif; }
/* На светлой заливке подсветка наведённого смайлика — белая: так видно,
   на что наводишь, а сам смайлик остаётся самым ярким пятном клетки. */
.emoji-panel .emoji-one:hover { background: #fff; }
/* На узком телефоне колонка сетки уже сорока пикселей, поэтому смайлик
   немного меньше, чем на компьютере, но клетку занимает целиком — как в
   Телеграме, где вокруг смайлика почти нет пустого места. */
@media (max-width: 420px) {
  .emoji-panel .emoji-one { height: 42px; font-size: 30px; }
}
/* Поле и смайлик — одна «капсула»: смайлик стоит внутри неё абсолютом,
   поэтому обёртке нужен position: relative. */
.room-box { position: relative; flex: 1; min-width: 0; display: flex; }
/* Справа в поле оставлено место под смайлик, иначе текст заезжал бы под него. */
.room-send textarea { flex: 1; min-width: 0; padding: 9px 42px 9px 14px;
  border: 1px solid var(--line); border-radius: 999px; font: inherit; font-size: 16px;
  line-height: 1.35; max-height: 132px; overflow-y: auto; resize: none;
  /* Android рисовал полосу прокрутки чёрной палочкой у правого края поля —
     она вылезала прямо между смайликом и кружком отправки. Прокрутка пальцем
     остаётся, видимой полосы больше нет. */
  scrollbar-width: none; }
.room-send textarea::-webkit-scrollbar { width: 0; height: 0; }
/* Кнопка отправки — наш кружок со стрелкой, тот же, что на «Вопросах». */
.room-send button { width: 38px; height: 38px; padding: 0; flex: none;
  border: 0; border-radius: 50%; background: var(--accent); color: #fff;
  font-size: 20px; line-height: 1; cursor: pointer; }
/* Кружок появляется, только когда есть что отправить: пустая кнопка рядом с
   пустым полем — лишний шум, место под неё держит скрепка слева. */
.room-send button[hidden] { display: none; }
/* Скрепка видна всегда и тоже круглая — пара к кнопке отправки. Рисуем её
   значком: смайлик 📎 на Windows выходил невнятным серым овалом. */
.room-send .attach { display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: none; border: 0; border-radius: 50%;
  color: #666; cursor: pointer; background: #f1f1ef; }
.room-send .attach .ico { width: 19px; height: 19px; }
.room-send .attach:hover { background: #e6e6e2; }

/* Широкий экран: колонки прокручиваются сами, страница целиком — нет.
   Иначе открытый разговор уезжал бы выше верха экрана. */
@media (min-width: 761px) {
  body.rooms-page { display: flex; flex-direction: column; height: 100%; max-height: 100dvh; }
  body.rooms-page .top { flex: none; }
  body.rooms-page .rooms { flex: 1; min-height: 0; align-items: stretch; }
  body.rooms-page .rooms .room-list { overflow-y: auto; min-height: 0; padding-right: 6px; }
  body.rooms-page .rooms .room-view { display: flex; flex-direction: column; min-height: 0; }
  body.rooms-page .room-feed { flex: 1; height: auto; }
}

/* Телефон: список и разговор — две страницы, между ними кнопка «← К списку». */
body.rooms-page .topbar { display: none; }
@media (max-width: 760px) {
  .rooms { display: block; }
  .room-view { display: none; }
  body.rooms-page.on-room .room-list { display: none; }
  body.rooms-page.on-room .room-view { display: block; }
  body.rooms-page.on-room .topbar { display: flex; }
  body.rooms-page.on-room .back { display: inline-block; padding: 8px 12px; font-size: 14px; }
}

/* Скрытое поле остаётся скрытым: общее правило диалога (label { display:flex })
   иначе перебивает атрибут hidden, и в окнах «Группы» и «Куда переслать?»
   вылезало лишнее поле «Название группы». */
.room-pick label[hidden] { display: none; }

/* Окно выбора людей в «Нашем чате». Строка человека — кнопка во всю ширину:
   на телефоне в такую попадают пальцем, а не в мелкое имя. */
.room-pick .found { max-height: 46vh; overflow-y: auto; }
.room-pick .pick-one { display: flex; align-items: center; gap: 8px;
  width: 100%; text-align: left; padding: 10px 12px;
  background: #fff; border: 1px solid var(--line); border-radius: 8px; font-size: 14px; }
/* Имя с должностью — колонкой справа от кружка, и в списке, и в галочках. */
.room-pick .who { flex: 1 1 auto; min-width: 0; }
.room-pick .pick-one:hover { background: #f3f7f4; border-color: var(--accent); }
.room-pick .found-row { display: flex; align-items: flex-start; gap: 8px; padding: 8px 2px;
  border-top: 1px solid #f0f0f0; font-size: 14px; cursor: pointer; }
.room-pick .found-row input { width: 18px; height: 18px; margin-top: 6px; }
/* В строке с галочкой кружок стоит вровень с именем, а не с должностью. */
.room-pick .found-row .ava { align-self: flex-start; }
/* Должность в окне выбора — второй строкой под именем, мелко и серым. */
.room-pick .who-post { display: block; margin-top: 1px; color: #777; font-size: 14px; }

/* ── Страница «Мой профиль» ────────────────────────────────────────────────
   Свои классы .prof-*, а не .person/.line: те же имена носит карточка
   сотрудника в «Настройках», и правка под профиль перекосила бы ту страницу.
   Раньше отступы и размер заголовка стояли прямо в разметке — переносим сюда,
   чтобы вид страницы правился в одном месте. */
.prof-page { padding: 16px; }
.prof-h1 { font-size: 20px; }
.prof-card { background: #fff; border: 1px solid var(--line); border-radius: 8px;
  padding: 18px; margin-top: 12px; max-width: 520px; }

/* Шапка карточки: крупный кружок и рядом имя с должностью. */
.prof-top { display: flex; align-items: center; gap: 18px; }
.prof-who { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.prof-name { font-size: 20px; }
.prof-post { color: var(--muted); font-size: 14px; }

/* Кружок с фотографией — он же кнопка выбора файла. Рамки и заливки кнопки
   сняты: должен читаться как кружок, а не как кнопка. */
.prof-ava-box { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.prof-ava { position: relative; flex: none; width: 96px; height: 96px; padding: 0;
  border: 0; border-radius: 50%; overflow: hidden; background: #4a5568;
  cursor: pointer; }
.prof-ava img { display: block; width: 100%; height: 100%; object-fit: cover; }
.prof-ava-txt { display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; color: #fff; font-size: 34px; font-weight: 600; }
/* Значок камеры лежит поверх кружка и притемняет его — так видно, что по
   кружку нажимают. На телефоне наводить нечем, поэтому там он виден всегда. */
.prof-ava-cam { position: absolute; inset: 0; display: flex;
  align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .35); color: #fff; font-size: 26px; }
@media (hover: hover) {
  .prof-ava-cam { opacity: 0; transition: opacity .12s; }
  .prof-ava:hover .prof-ava-cam, .prof-ava:focus .prof-ava-cam { opacity: 1; }
}
.prof-drop { padding: 0; border: 0; background: none; color: var(--muted);
  font: inherit; font-size: 14px; text-decoration: underline; cursor: pointer; }
.prof-drop:hover { color: #b3261e; }

/* Поле с подписью сверху: подпись мелкая и серая, поле во всю ширину. */
.prof-fields { display: flex; flex-direction: column; gap: 12px; margin-top: 20px; }
.prof-field { display: block; }
.prof-label { display: block; margin-bottom: 4px; color: var(--muted); font-size: 14px; }
.prof-field input { width: 100%; box-sizing: border-box; padding: 9px 10px;
  border: 1px solid var(--line); border-radius: 8px; font: inherit; font-size: 16px; }
.prof-field input:focus { outline: none; border-color: var(--accent); }

.prof-acts { display: flex; align-items: center; gap: 12px; margin-top: 18px; }
.prof-save { padding: 10px 20px; border: 0; border-radius: 8px;
  background: var(--accent); color: #fff; font: inherit; font-size: 14px; cursor: pointer; }
.prof-msg { color: var(--accent); font-size: 14px; transition: opacity .6s; }
.prof-msg.fade { opacity: 0; }

/* На телефоне кружок встаёт сверху по центру, а кнопка — во всю ширину:
   в строку из кружка и имени экран не помещается. */
@media (max-width: 560px) {
  .prof-top { flex-direction: column; text-align: center; gap: 10px; }
  .prof-who { align-items: center; }
  .prof-acts { flex-direction: column; align-items: stretch; }
  .prof-save { width: 100%; }
  .prof-msg { text-align: center; }
}

/* Блок «Дублировать в MAX» внизу карточки профиля. Отделён чертой: это не
   часть анкеты, а отдельное дело — подключение второго канала. */
.prof-max { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }
.prof-max-h { display: block; font-size: 16px; margin-bottom: 8px; }
.prof-max-body { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.prof-max-note { margin: 0; color: #666; font-size: 14px; line-height: 1.45; }
.prof-max-ok { margin: 0; color: var(--accent); font-size: 14px; }
/* Код диктуют вслух и набирают на телефоне: крупно, вразрядку, моноширинно. */
.prof-max-code { font-family: ui-monospace, Menlo, Consolas, monospace;
  font-size: 30px; letter-spacing: 4px; font-weight: 700; color: var(--accent);
  background: #f2f7f4; border: 1px solid #cfe0d6; border-radius: 8px;
  padding: 10px 16px; user-select: all; }
.prof-max-steps { margin: 0; padding-left: 20px; color: #444; font-size: 14px; line-height: 1.6; }
.prof-max-btn { padding: 9px 16px; border: 1px solid var(--accent); border-radius: 8px;
  background: #fff; color: var(--accent); font: inherit; font-size: 14px; cursor: pointer; }

@media (max-width: 560px) {
  .prof-max-body { align-items: stretch; }
  .prof-max-btn { width: 100%; }
  .prof-max-code { text-align: center; font-size: 26px; }
}

/* Полоска «Умник обновился». Висит поверх страницы у верхнего края и
   появляется только тогда, когда на сервере действительно сменилась версия. */
.upd-bar { position: fixed; z-index: 60; left: 50%; top: 10px; transform: translateX(-50%);
  display: flex; align-items: center; gap: 10px;
  max-width: calc(100% - 20px); padding: 8px 12px;
  background: var(--accent); color: #fff; border-radius: 8px; font-size: 14px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, .2); }
.upd-bar button { padding: 5px 12px; border: 0; border-radius: 8px;
  background: #fff; color: var(--accent); font: inherit; font-size: 14px;
  font-weight: 600; cursor: pointer; }

/* Страница «Рассылка». Как и карточка профиля, набрана своими классами
   .bc-*: общих правил для заголовков, кнопок и полей ввода в проекте нет,
   и без них браузер рисовал страницу как голый бланк. */
.bc-page { max-width: 720px; margin: 0 auto;
  padding: 16px 16px calc(24px + env(safe-area-inset-bottom)); }
.bc-h1 { margin: 0 0 6px; font-size: 20px; }
.bc-h2 { margin: 22px 0 10px; font-size: 14px; color: var(--muted); font-weight: 600; }
.bc-note { margin: 0; color: var(--muted); font-size: 14px; }

/* Само объявление — отдельная белая карточка: она главная на странице,
   а список получателей ниже — подсобный. */
.bc-card { margin-top: 14px; padding: 14px; background: #fff;
  border: 1px solid var(--line); border-radius: 8px; }
.bc-text { display: block; width: 100%; min-height: 110px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 8px; font: inherit;
  color: var(--ink); background: #fff; resize: vertical; }
.bc-text:focus { outline: none; border-color: var(--accent); }
.bc-send-row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 12px; }
.bc-send { padding: 10px 22px; border: 0; border-radius: 8px;
  background: var(--accent); color: #fff; font: inherit; font-weight: 600; cursor: pointer; }
.bc-count { color: var(--muted); font-size: 14px; }
.bc-done { color: var(--accent); font-size: 14px; }

/* Кнопки-наборы: не действия, а быстрые галочки, поэтому светлые и мелкие. */
.bc-picks { display: flex; flex-wrap: wrap; gap: 8px; }
.bc-pick { padding: 7px 14px; border: 1px solid var(--line); border-radius: 999px;
  background: #fff; color: var(--ink); font: inherit; font-size: 14px; cursor: pointer; }
.bc-pick:hover { border-color: var(--accent); color: var(--accent); }

.bc-search { display: block; width: 100%; margin-top: 10px; padding: 9px 12px;
  border: 1px solid var(--line); border-radius: 8px; font: inherit; background: #fff; }
.bc-search:focus { outline: none; border-color: var(--accent); }

/* Список получателей — иначе сплошной поток текста нечитаем на телефоне.
   На телефоне список НЕ ограничиваем по высоте: свой скролл внутри страницы
   перехватывает палец, и до остального содержимого не долистать. Растёт как
   есть, страница листается целиком. Внутренний скролл включаем только на
   широком экране, где мышью это удобно. */
.bc-people { margin-top: 10px;
  background: #fff; border: 1px solid var(--line); border-radius: 8px; padding: 0 12px; }
.bc-row { display: flex; align-items: center; gap: 10px; padding: 10px 0;
  border-bottom: 1px solid var(--line); cursor: pointer; }
.bc-row:last-child { border-bottom: none; }
.bc-row input { width: 18px; height: 18px; flex: none; accent-color: var(--accent); }
.bc-name { flex: 1; min-width: 0; }
.bc-you { color: var(--muted); font-size: 14px; }
/* Должность прижата вправо и обрезается: на телефоне длинное название
   выдавливало имя за край. */
.bc-post { flex: 0 1 auto; min-width: 0; color: var(--muted); font-size: 14px;
  text-align: right; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (min-width: 700px) {
  .bc-people { max-height: 420px; overflow-y: auto; }
}
/* Пометка Умника: заметная, но не тревожная — это повод посмотреть, а не авария. */
.task-row.flagged .flag { color: #b26a00; font-weight: 600; }
.check-note { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 8px 0; padding: 8px 10px; border-radius: 8px;
  background: #fff6e5; color: #7a4a00; font-size: 14px; }
.check-note button { margin-left: auto; }

/* ── Поля ввода на телефоне ──
   Safari на айфоне увеличивает всю страницу, когда встаёшь в поле со шрифтом
   мельче 16px, и обратно её уже не уменьшает: написал сообщение в чате,
   вернулся к списку разговоров — а он остался чуть увеличенным. Поэтому у
   всех полей, куда набирают текст, размер ровно 16px. Блок идёт последним,
   чтобы перебить размеры, заданные выше у самих полей. */
.room-send textarea,
.task-card input[type="text"],
.task-card textarea,
.task-dialog input,
.task-dialog select,
.task-dialog textarea,
.calls .callback-box input,
.calls #search,
.prof-field input,
#new-login, #new-name, #new-pass, #purge-before, #url { font-size: 16px; }

/* Цитата в пузыре — ответ на сообщение («Ответить» в меню ⋮). Отдельной
   строкой над текстом, приглушённая, с зелёной чертой слева: как в Телеграме,
   чтобы цитата не спорила с самим ответом. Клик по ней прыгает к оригиналу. */
.room-quote { display: block; margin: 0 0 4px; padding: 2px 0 2px 7px;
  border-left: 3px solid #2e7d32; color: #4b5b4e; font-size: 14px; line-height: 1.3;
  cursor: pointer; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.room-msg.mine .room-quote { border-left-color: #7cb342; color: #40513f; }
.room-quote b { display: block; font-weight: 600; color: #2e7d32; }
.room-msg.mine .room-quote b { color: #33691e; }
/* Подсветка на секунду, когда прыгнули к исходному сообщению по цитате. */
.room-msg.flash { animation: room-flash 1.2s ease-out; }
@keyframes room-flash { from { background: #fff3c4; } to { background: inherit; } }

/* Раздел «Акции» */
/* width и min-width здесь не украшение. На телефоне body — флекс-колонка, а
   горизонтальные `auto` в margin отменяют растяжение: колонка берёт ширину
   самого широкого непереносимого содержимого. Плюс у флекс-элемента по
   умолчанию `min-width: auto` — широкая таблица распирает его изнутри, и
   тогда вбок едет вся страница, а рамка с прокруткой бессильна. */
.promos { padding: 12px; max-width: 1100px; width: 100%; min-width: 0; margin: 0 auto; }
/* Возврат к доске марок. Кнопка живёт в общей шапке, а там .back по
   умолчанию скрыта (на страницах обзвона на широком экране возвращаться
   некуда). В «Акциях» панели сменяют друг друга на любом экране, поэтому
   показываем кнопку всегда, когда её не спрятал JS атрибутом hidden. */
/* На доске марок возвращаться некуда — там кнопка скрыта, и полоса шапки
   не должна висеть пустой серой строкой. */
body.promos-page .topbar:has(> .back:not([hidden])) { display: flex; gap: 8px; padding: 6px 12px;
  background: #f4f4f2; border-bottom: 1px solid var(--line); }
body.promos-page .back:not([hidden]) { display: inline-block; padding: 8px 12px;
  font-size: 14px; border: 1px solid var(--line); border-radius: 8px;
  background: #fff; cursor: pointer; }
.promos .pane-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.promos .pane-head h1 { font-size: 20px; margin: 8px 0; }
.promos .pane-tools, .promos .form-row { display: flex; gap: 8px; flex-wrap: wrap; margin: 10px 0; }
/* Ровно 16px: на iPhone поле мельче этого зумит страницу и не возвращает. */
.promos #client-search { flex: 1 1 180px; padding: 7px 9px; border: 1px solid #ccc; border-radius: 8px; font-size: 16px; }
.promos #pick-count { align-self: center; }
.promos table.board { width: 100%; border-collapse: collapse; font-size: 14px; }
.promos table.board th, .promos table.board td { padding: 8px 6px; border-bottom: 1px solid #e6e6e6; text-align: left; }
/* Заголовок-кнопка: по нему сортируют, поэтому текст не выделяем. */
.promos table.board th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.promos table.board th.sortable:hover { background: #f3f8f5; }
/* Подпись фильтра стоит в строку со своим полем. */
.promos .filt { display: flex; align-items: center; gap: 6px; font-size: 14px; color: #555; }
.promos .filt input { font-size: 16px; padding: 6px 8px; border: 1px solid #ccc; border-radius: 8px; }
.promos .filt input[type=number] { width: 120px; }
.promos table.board tbody tr[data-key] { cursor: pointer; }
.promos table.board tbody tr[data-key]:hover { background: #f3f8f5; }

/* Таблица клиентов брошенной марки: восемь колонок против 390px телефона.
   Раньше она растягивала страницу вбок целиком, и часть колонок просто
   уезжала за край. Теперь таблица живёт в своей рамке и возится пальцем, а
   галочка и название клиента приморожены слева — иначе при прокрутке не
   видно, о ком строка. Приморозка требует `separate`: при `collapse` у ячеек
   нет собственного фона, и приклеенный столбец просвечивает насквозь.
   На компьютере таблица влезает целиком, поэтому там всё остаётся как было. */
.promos .scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
@media (max-width: 700px) {
  /* width: auto обязателен. Общее правило .promos table.board задаёт width: 100%,
     и таблица ужимается ровно до рамки: прокручивать нечего, а колонки с третьей
     по восьмую лежат под приклеенной колонкой «Клиент» — у приклеенной ячейки
     непрозрачный фон, она их просто накрывает. min-width: 100% нужен на случай
     короткого списка, чтобы таблица не оказалась уже своей рамки. */
  .promos table.clients-table {
    border-collapse: separate; border-spacing: 0; width: auto; min-width: 100%; }
  .promos table.clients-table th, .promos table.clients-table td { white-space: nowrap; background: #fff; }
  /* Ширина колонки с галочкой зажата с трёх сторон намеренно. Одного width мало:
     в таблице это лишь пожелание, и колонка отрисовывалась в 28px по размеру
     чекбокса. А соседняя колонка приклеена ровно по `left: 32px` — из-за
     четырёх лишних пикселей она заезжала на «Менеджера». Теперь 32px настоящие,
     каким бы браузер ни рисовал сам чекбокс. */
  .promos table.clients-table th:first-child, .promos table.clients-table td:first-child {
    position: sticky; left: 0; z-index: 1; padding: 8px 4px; box-sizing: border-box;
    width: 32px; min-width: 32px; max-width: 32px; }
  /* Длинное название клиента с nowrap заняло бы весь экран, и приклеенная
     колонка снова накрыла бы цифры. Поэтому имя обрезается многоточием.
     width и max-width парой: одного max-width мало — он ограничивает саму
     ячейку, а ширину колонки таблица считает своим счётом, и приклеенная
     ячейка заезжает на соседнюю. */
  .promos table.clients-table th:nth-child(2), .promos table.clients-table td:nth-child(2) {
    position: sticky; left: 32px; z-index: 1; box-shadow: 6px 0 6px -6px rgba(0, 0, 0, .25);
    width: 42vw; max-width: 42vw; overflow: hidden; text-overflow: ellipsis; }
}
.promos .promo-items { list-style: none; padding: 0; margin: 0; }
.promos .promo-items li { padding: 10px 8px; border-bottom: 1px solid #e6e6e6; cursor: pointer; display: flex; gap: 10px; flex-wrap: wrap; align-items: baseline; }
.promos .state { border-radius: 999px; padding: 2px 8px; font-size: 14px; }
.promos .state.draft { background: #eee; color: #555; }
.promos .state.live { background: #dff0e4; color: var(--accent); }
.promos .state.done { background: #e7edf5; color: #3a5570; }
.promos .dim { color: #777; font-size: 14px; }
.promos .result { font-size: 16px; margin: 12px 0; }
.promos .err { color: #b03030; }
.promos .danger { color: #b3261e; }
/* Подсказка на опустевшем черновике: выхода из тупика нет, кроме удаления. */
.promos .hint-empty { color: #b3261e; font-size: 14px; margin: 12px 0; }
.promos .promo-form { display: grid; gap: 8px; margin: 10px 0; }
/* Поле мельче 16px заставляет iPhone зумить страницу и не возвращать её. */
.promos input, .promos select { font-size: 16px; padding: 8px; }
.promos .mech { display: grid; gap: 4px; max-width: 520px; }
/* Подпись над полем, а не сбоку: короткие «Начало» и «Окончание» иначе
   прижимались к краю, и строка ломалась пополам. Даты — в один ряд. */
.promos .promo-form label, .promos .mech { font-size: 14px; color: #555; }
.promos .promo-form label { display: grid; gap: 4px; max-width: 520px; }
.promos .promo-form input, .promos .mech input {
  width: 100%; box-sizing: border-box; border: 1px solid #ccc; border-radius: 8px; }
.promos .promo-form .dates { display: flex; gap: 12px; flex-wrap: wrap; max-width: 520px; }
.promos .promo-form .dates label { flex: 1 1 170px; max-width: 240px; }
/* Кнопки раздела были системными и разнокалиберными — приводим к виду
   остальных страниц (см. .composer button). */
.promos button { font: inherit; font-size: 14px; padding: 8px 14px; border: 1px solid #ccc;
  border-radius: 8px; background: #fff; cursor: pointer; }
.promos button:hover { background: #f3f8f5; }
.promos .primary { background: var(--accent); border-color: var(--accent); color: #fff; }
/* Зелёная кнопка при наведении и нажатии остаётся зелёной: общее правило
   button:hover выше по специфичности и делало её белой — текст пропадал. */
.promos .primary:hover { background: #27593f; border-color: #27593f; color: #fff; }
.promos .primary:active { background: #1f4833; border-color: #1f4833; color: #fff; }
.promos button:active { background: #eee; }
.promos button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.promos table.board button { font-size: 14px; padding: 5px 10px; }
.copy-hatch { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

/* ---------- Общий вид кнопки ----------
   Отдельного класса вроде .btn заводить не пришлось: правило по самому тегу
   «кнопка» — самое слабое из возможных (специфичность 0,0,1), его перебивает
   любое правило с классом. Поэтому кнопки, у которых вид уже описан выше,
   остаются какими были, а «голые» (их в разметке 28 — «Настройки», «Акции»,
   «Отмена» в выборе беседы и другие) наконец выглядят по-нашему, а не
   системной серой кнопкой браузера. */
button {
  padding: 9px 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-size: 14px;
  cursor: pointer;
}

/* ---------- Отклик кнопки на нажатие ----------
   На телефоне :hover не срабатывает вовсе: палец нажимает — кнопка выглядит
   ровно так же, как до нажатия, и сотрудник тыкает второй раз. Даём отклик
   одним общим правилом на все кнопки сразу.
   Цвет здесь намеренно не трогаем. Общее правило с фоном перебило бы по
   специфичности собственные цвета зелёных кнопок (эту граблю мы уже ловили
   на .primary). Затемнение и лёгкое вдавливание работают на кнопке любого
   цвета и ничего не перекрашивают. */
button:active:not(:disabled), .dial:active {
  transform: scale(.97); filter: brightness(.93);
}
/* Погашенная кнопка выглядит одинаково везде. Раньше видов было три: где-то
   приглушали прозрачностью, где-то подменяли фон серым (#b9c9b9, #cfcfcf) —
   и один и тот же «нельзя нажать» читался по-разному от страницы к странице.
   Прозрачность работает на кнопке любого цвета и ничего не перекрашивает.
   Исключение — .room-tool ниже: там гасить нужно сильнее, и своё правило
   с большей специфичностью это общее перебивает. */
button:disabled, .dial:disabled { opacity: .6; cursor: default; }
/* Видимая рамка при ходьбе по клавиатуре — только для клавиатуры
   (:focus-visible), мышью и пальцем она не появляется. */
button:focus-visible, .dial:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* ---------- Зона под палец ----------
   Палец накрывает примерно 44 пиксела — кнопки мельче этого на телефоне
   промахиваются. Высоту задаём только там, где кнопка и правда мелкая, и
   только через min-height: сама надпись и отступы остаются прежними, кнопка
   просто дорастает снизу и сверху. Мелкие значки внутри узких полосок
   (открепить беседу, ответ в карточке задачи) не трогаем — они привязаны к
   высоте своей строки и от 44px её бы разорвало. */
button:not([class]),
.dial,
.freshness button,
.tabs button,
.composer button,
.room-tool,
.push-on,
.pick-room, .pick-new, .pick-open,
.msg-menu-i,
.task-card .card-head button,
.task-dialog .row button,
.task-dialog .spread .pick,
.promos button,
.upd-bar button,
.bc-pick {
  min-height: 44px;
}
/* Кружок «отправить» в беседе — тоже под палец, но ему нужна и ширина,
   иначе из круга вышел бы овал. Скрепка рядом — его пара, растёт вместе,
   иначе кружки станут разного размера. */
.room-send button, .room-send .attach { width: 44px; height: 44px; }
