/* ClientsChat dev-тест-клиент — стиль. Ванильный CSS, без зависимостей.
   Тёмная тема, минимум декора: это QA-инструмент, не продакшн-UI. */

:root {
  /* 🧭🧭 ДОРОЖКА ЛЕВОГО БЛОКА = рейка хабов. ВТОРОЕ МЕНЮ ВИДОВ (`--hub-w`) открывается при
     наведении ПОВЕРХ контента и в дорожку НЕ входит (согласовано владельцем 2026-10-11,
     раунд 7: «подменю… при наведении, на всю высоту, рядом с рельсом, поверх контента —
     контент не смещается»). Раунд 5 резервировал под панель постоянные 232px дорожки —
     владелец увидел «подменю смещает контент справа» и вернул.
     🔴 ОДНО МЕСТО: все, кому нужна «область справа от левого блока» (сетка `.chat`,
     полноэкранные страницы, острова `island.css`), читают `--rail-track`, а не число. */
  --rail-w: 96px;
  --hub-w: 300px;
  --hub-gap: 8px;
  --rail-track: var(--rail-w);
  --bg: #0f1115;
  --panel: #171a21;
  --panel-2: #1e222b;
  --panel-3: #262b36;     /* поднятый слой: тултипы/меню/поповеры/undo-тост (раньше токен был
                             «битым» — инжекты/таймлайн падали в тёмный фолбэк даже в светлой) */
  --line: #2a2f3a;
  --line-strong: #353b48; /* границы контролов / hover-границы */
  --text: #e6e9ef;
  --muted: #8b93a3;
  /* select-chevron-ink-light-1 · шеврон селекта — ОДНА картинка на продукт, по значению на тему. В url()
     переменная не подставляется, поэтому чернила — значение --muted своей темы: #8b93a3 здесь, #5c5c61 в блоке
     html[data-theme="light"]. Три начертания: обычное · компактное (select.tw-select, .td-field) · жирное (окно
     настроек). Новый селект берёт var(--sel-chev*), своего data-URI шеврона не заводит. */
  --sel-chev: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238b93a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  --sel-chev-sm: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238b93a3' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  --sel-chev-b: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%238b93a3' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
  --text-dim: #9aa4b2;    /* третичный текст (плейсхолдеры/мета) = бывший фолбэк в коде */
  --primary: #667eea;     /* индиго — старт фирменного градиента */
  --primary-2: #8b9cf5;   /* светлый акцент: имена/кольца/цитаты */
  --primary-hi: #7b8bf1;  /* hover primary-кнопки */
  --accent: #667eea;      /* = --primary. Раньше НЕ определён → cli/dir-оверлеи (поиск/
                             компании/клиенты) падали в случайный #5b8def. Гармонизирует. */
  /* 🔴 ЛЕГАСИ-АЛИАСЫ: инжектируемый CSS (co-/cli-/dir-/tip-/v2-/stf-) использует НЕсуществовавшие
     токены с хардкод-фолбэками → рассинхрон. Определение алиасов «самозалечивает» БЕЗ правки JS. */
  --border: var(--line);
  --input-bg: #141821;    /* поля УТОПЛЕНЫ относительно панели (были = --panel-2 — светлее панели,
                             читались как кнопки). Фокус «всплывает» до --panel (см. §3). */
  --surface: var(--panel);      /* алиас: staffEnsureStyles (.stf-*) юзал несуществующий токен */
  --surface2: var(--panel-2);   /* — тот же случай */
  --surface-2: var(--panel-2);  /* — и он же ЧЕРЕЗ ДЕФИС (.eh-ver): разное написание одного смысла */
  --text-secondary: var(--muted);
  /* 🔴 «ПРИЗРАЧНЫЕ» ТОКЕНЫ — вторая волна того же класса (СРЕД-30, «блоки не выделены»).
     var(--нет-такого-токена) — это НЕ «возьмём фолбэк»: если фолбэка нет, вся декларация
     становится invalid at computed-value time и движок её ВЫБРАСЫВАЕТ. Замерено настоящим
     Chromium на этом же файле ДО правки:
       .dvm-row.sel  → background: color-mix(… var(--fg) 5% …)   = rgba(0,0,0,0)  ← выделения
                       border-color: color-mix(… var(--fg) 22% …) = currentColor    НЕ ВИДНО,
                       т.е. вместо мягкой подложки+тинта рамки — пусто и жёсткая рамка в цвет текста;
       .dvs-accbtn   → border: 1px solid color-mix(… var(--fg) …) = 0px none      ← рамки НЕТ;
       .v2bld-log    → background: var(--bg-soft, transparent)   = прозрачный      ← лог сливается с панелью.
     А где фолбэк ЕСТЬ — правило живёт, но красится ЗАШИТЫМ цветом мимо обеих тем
     (--warn был написан с ПЯТЬЮ разными фолбэками: #b26a00/#b7791f/#E5A23C/#EF9F27/#d99b27 —
     «предупреждение» выглядело пятью цветами и ни один не слушал тему).
     Лечение — тем же приёмом, что абзацем выше: объявить алиасы. `var()` внутри значения
     кастомного свойства подставляется на ЭЛЕМЕНТЕ, где свойство объявлено, — а объявлено оно
     на <html>, где и живёт data-theme. Значит ОДНОГО объявления в :root хватает на ОБЕ темы
     и на все концепты, и JS/инжекты править не нужно. Сторож: tools/design_lint.js → GHOST_TOKENS. */
  --fg: var(--text);            /* текст (61 правило: среда разработки, сборки, превью, терминал) */
  --warn: var(--warning);       /* предупреждение — ОДИН цвет продукта, приглушается концептом */
  --hairline: var(--line);      /* волосяная граница (.avt-* редактор аватара, .eh-ver) */
  --fs-spc: var(--primary);     /* цвет ПРОСТРАНСТВА файлов (CLIE-985·2): строка ставит свой
                                   инлайном (цвет проекта), без своего цвета — акцент темы */
  --kind-meeting: var(--primary); /* вид «Встреча» (PLAN_KINDS: календарь, напоминания, плашка в чате) —
                                   акцент ШАБЛОНА: в базе те же пиксели #667eea, «Штиль» берёт свой
                                   акцент вместо чужого старого индиго (свип волны 3, 20.10.2026);
                                   «Глубина» ставит свой в depth.css */
  --lineStrong: var(--line-strong);  /* то же имя в camelCase (.dash-*) */
  --textSecondary: var(--muted);     /* — и вторичный текст в camelCase (.cs-*, .gs-*) */
  --text-2: var(--text);
  --muted-2: var(--muted);
  --card: var(--panel);
  --bg-soft: var(--input-bg);   /* УТОПЛЕННАЯ плоскость: лог сборки, вывод терминала, сцена превью */
  --ccfx-accent: var(--primary);/* панель эффектов камеры (callfx.js) — брала свой #6d5cf0 мимо бренда */
  /* 🗺️ CLIE-905 «Карта проекта»: подложка карточки-ЗАМЕТКИ на холсте. Токен, а не литерал —
     иначе в тёмной теме жёлтый стикер светится, а чернила на нём становятся невидимыми
     (класс THEMECONTRAST). Значение берётся от поверхности предупреждения продукта. */
  --brd-note: color-mix(in srgb, var(--warning) 22%, var(--panel));
  /* 🗺️ CLIE-905·2: подложка КОММЕНТАРИЯ на холсте («комментарии ставить» — просьба владельца).
     Тоже токен: прибитый #dbeafe в тёмной теме светится, а чернила на нём пропадают. */
  --brd-cmt: color-mix(in srgb, var(--primary) 20%, var(--panel));
  --msg-max: 680px;             /* потолок ширины пузыря — был «ручкой», которую забыли объявить */
  --msg-max-doc: 1100px;        /* потолок пузыря-ДОКУМЕНТА (таблица/код): мера чтения тут другая */
  --grad: linear-gradient(135deg, #667eea, #764ba2);
  /* 🔴 Заливка ПУЗЫРЯ СВОЕГО сообщения — отдельный токен от общего --grad (задача
     «Контрастность», 10.09.2026). На пузыре лежит длинный БЕЛЫЙ текст, поэтому у него своя
     проверка (AA 4.5), а --grad носят ещё кнопки и аватары с крупным кеглем (AA 3.0).
     Пока это был один токен, «сделать заливку читаемой» значило «перекрасить полпродукта».
     Переопределяется в концепте (concept-6.css, обе темы). */
  --bub-fill: var(--grad);
  /* 🔴 АКЦЕНТНАЯ ЗАЛИВКА ПОД БЕЛЫМИ ЧЕРНИЛАМИ — тоже отдельно от --primary/--grad, и по той же
     причине: --primary в ТЁМНОЙ теме служит ещё и ЧЕРНИЛАМИ на тёмном холсте (ссылки, статусы),
     где он обязан быть СВЕТЛЫМ. Один токен на две роли и был причиной, по которой остаток
     CLIE-888·2 («13 мест белым по акценту, 3.21:1») год назывался «решением о дизайне»:
     углубить --primary целиком значило погасить акцентный ТЕКСТ. Теперь роли разведены —
     заливка углубляется, чернила не трогаются («Контрастность», 10.09.2026). */
  --acc-fill: var(--primary);
  --acc-grad: var(--grad);
  /* hover залитой кнопки под белым (была --primary-hi: в тёмной она СВЕТЛЕЕ заливки — 2.7:1) */
  --acc-fill-hi: var(--primary-hi);
  /* тот же приём для тревожной заливки: в тёмной теме --danger служит и ЧЕРНИЛАМИ */
  --danger-fill: var(--danger);
  /* и ЧЕРНИЛА тревоги на её же тинте — третья роль того же цвета (канон
     contrast-runtime-audit: «акцентный ТЕКСТ на подложке — не тот же токен, что заливка») */
  --danger-ink: var(--danger);
  --glow: rgba(102,126,234,.4);
  /* Состояния (вместо россыпи случайных rgba) */
  --hover: rgba(230,233,239,.05);
  --active: rgba(230,233,239,.09);
  --sel: rgba(102,126,234,.16);
  /* Единый таб/сегмент (CLIE-249) */
  --seg-track: var(--panel-2);
  --seg-thumb: #323847;
  --seg-thumb-bd: rgba(255,255,255,.09);
  --seg-thumb-sh: 0 1px 1px rgba(0,0,0,.5), 0 3px 8px rgba(0,0,0,.4), inset 0 1px 0 rgba(255,255,255,.06);
  --seg-div: rgba(255,255,255,.075);
  /* 🔴 РАЗМЕРНЫЙ КЛАСС СТРОКИ КОНТРОЛОВ (CLIE-505 «дизайн везде разный»).
     Контролы, стоящие в ОДНОМ ряду (фильтр-пилюля, селект, поле поиска, кнопка-действие,
     сегмент), обязаны быть ОДНОЙ высоты, одного радиуса и одного кегля — иначе ряд
     «рассыпается» (владелец: «смотри как отличается выбор Везде … от других элементов»).
     31px — фактическая живая высота ряда тулбара: паддинг 7+7 + строка 15 + рамка 1+1.
     Новый контрол в такой ряд НЕ придумывает свои числа, а берёт эти токены. */
  --ctl-h: 31px;          /* высота контрола строки тулбара */
  --ctl-r: 9px;           /* радиус контрола строки тулбара */
  --ctl-fs: 13px;         /* кегль подписи контрола */
  /* Тени: плотные и короткие; в тёмной глубину держит цвет слоёв, тень — усилитель */
  --shadow-1: 0 1px 2px rgba(0,0,0,.45), 0 2px 8px rgba(0,0,0,.28);
  --shadow-2: 0 4px 10px rgba(0,0,0,.38), 0 16px 32px -8px rgba(0,0,0,.5);
  --shadow-3: 0 8px 20px rgba(0,0,0,.45), 0 32px 72px -12px rgba(0,0,0,.6);
  --edge: inset 0 1px 0 rgba(255,255,255,.04);  /* верхний «блик» поднятых слоёв (только тёмная) */
  --scrim: rgba(8,10,16,.6);                    /* единый бэкдроп модалок */
  --danger: #ef4444;      --danger-soft: rgba(239,68,68,.14);
  --ok: #22c55e;          --ok-soft: rgba(34,197,94,.13);
  --warning: #e5a23c;     --warning-soft: rgba(229,162,60,.14);  /* раньше --warning был не определён */
  /* 🔴 ЗАЛИВКИ ГРАФИКИ ≠ ТЕКСТ. Семантические токены в светлой теме затемняются под AA-контраст
     ТЕКСТА (--warning там #9a6a00) — как заливка полосы/столбца это выглядит грязно-оливковым.
     Для графических плоскостей (план-факт, столбцы) — свои fill-токены, одинаковые в обеих темах. */
  --fill-warn: #e5a23c;   --fill-danger: #ef4444;   --fill-ok: #22c55e;
  --info: #7ea6f5;        --info-soft: rgba(102,126,234,.16);    /* «в работе» (взамен сырого var(--info)) */
  /* семантические цвета срочности/статуса — токенами, чтобы не было сырых hex */
  --urg-overdue: #F2607A; --urg-overdue-soft: rgba(242,96,122,.14);
  --urg-today: #E5A23C;   --urg-today-soft: rgba(229,162,60,.14);
  /* чернила «просрочено» (текст/иконка) — отдельно от заливки точки/полосы: шаблон углубляет
     только чернила, если его --urg-overdue на своём тинте ниже 4.5 («Штиль» тёмная: 3.7) */
  --urg-overdue-ink: var(--urg-overdue);
  --urg-done: #5DCAA5;    --urg-done-soft: rgba(93,202,165,.13);
  --mine: #2b3553;
  --theirs: #222637;
  --system: #3a2f12;
  --radius: 14px;
  /* Единая высота ВСЕХ шапок столбцов (Проекты/Мои задачи/Чаты/тред) — чтобы верхняя
     кромка ленты сообщений и списков шла ровной линией. Задаёт самый высокий контент
     (кнопки звонка в треде = 44px) + вертикальные отступы. Меняется в ОДНОМ месте. */
  --head-h: 60px;
  /* Высота ВЕРХНЕЙ ПАНЕЛИ приложения (.topbar) — и ровно её же вычитает .screen.
     🔴 Раньше .screen жёстко вычитал 49px, а реальная .topbar давно выросла до 57px
     (самый высокий её ребёнок — кнопка «Настройки» 36px + паддинги 10/10 + бордер 1).
     Разница 8px делала .screen на 8px выше свободного места, и body{overflow:hidden}
     срезал нижние 8px композера: сверху пилюли ввода зазор 12px, снизу — только 4px
     («сверху пространство есть, снизу нет»). Теперь высота задаётся в ОДНОМ месте и
     разъехаться не может. Меняешь высоту/паддинги .topbar — меняй эту переменную. */
  --topbar-h: 57px;
  /* шкала радиусов вторичных элементов (--radius 14 — контейнеры) */
  --r-xs: 6px; --r-sm: 8px; --r-md: 10px; --r-lg: 16px; --r-full: 999px;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  /* движение: единая шкала (микро / поповеры / модалки-шторки) */
  --dur-1: 120ms; --dur-2: 200ms; --dur-3: 260ms;
  --ease: cubic-bezier(.2,.8,.2,1);
  --ease-spring: cubic-bezier(.34,1.4,.64,1);
  --ease-exit: cubic-bezier(.4,0,1,1);
  --ui-scale: 1;          /* масштаб интерфейса (доступность): 1 = 100%. Ставит бутстрап в index.html <head> */
  font-synthesis: none;
}

* { box-sizing: border-box; }

/* 🔴 ГЛОБАЛЬНЫЙ дефолт размера иконок svgIcon: без width/height у <svg> в гибком/блочном
   контейнере иконка растягивается на всю ширину («гигантские иконки»). Базовый размер
   16px + flex:none. Контексты переопределяют (рельс 22px, звонок 24px и т.п.). */
svg.ic { width: 16px; height: 16px; flex: none; vertical-align: middle; }

html, body {
  margin: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  font-size: 14px;
}

/* ══ РАЗМЕР ИНТЕРФЕЙСА (доступность для возрастной аудитории) ═══════════════════
   Весь CSS в px → менять корневой font-size бесполезно. Единственный надёжный
   глобальный масштаб — CSS zoom на <html> (Chromium/Safari/Firefox 126+; PWA и
   Flutter-WebView как раз на них). Zoom заодно магнифицирует и iframe документа.
   Бутстрап в <head> ставит зум и data-uis ещё до отрисовки (без мигания).
   Грабли, проверенные на живом проде инъекцией:
   (1) height:100dvh НЕ пересчитывается под zoom (985px×1.3=1281 > экран) →
       вертикальный overflow. Лечим компенсацией высоты html/body (÷ масштаб).
   (2) Оверлеи с max-height:NNvh так же переполняются под zoom (модалка 88vh при
       1.4× вылезает за экран, крестик уходит вверх) → кап высоты 96dvh/scale
       (после зума ≤96% реального экрана). Явный список оверлеев — без широких
       substring-селекторов, чтобы не задеть layout-элементы. */
html[data-uis], html[data-uis] body { height: calc(100dvh / var(--ui-scale, 1)); }
html[data-uis] :is(
  .modal-box, .lightbox-content, .cc-sheet, .cli-modal, .cli-panel, .co-panel,
  .ev-modal, .pinned-sheet, .pr-panel, .notif-panel, .today-panel, .task-info-panel,
  .ticket-info-panel, .v2-drawer, .v2-modal, .ai-assist-box, .ck-composer, .rec-report-body,
  .msged-box
) { max-height: calc(96dvh / var(--ui-scale, 1)) !important; }

/* Контролы «А− А+» в шапке (всегда на виду — пожилой человек сразу находит) */
.ui-scale-ctl { display: inline-flex; align-items: center; gap: 2px; margin: 0 2px; }
.ui-scale-btn {
  min-width: 30px; padding: 4px 8px; font-weight: 700; line-height: 1;
  font-size: 13px; letter-spacing: .5px;
}
.ui-scale-btn .ui-scale-sign { font-size: 15px; }
/* Секция «Размер интерфейса» в Настройках */
.ui-scale-presets { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 12px; }
.ui-scale-preset {
  flex: 1 1 auto; min-width: 120px; padding: 12px 14px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  font-size: 15px; font-weight: 600; cursor: pointer; transition: border-color .12s, background .12s;
}
.ui-scale-preset:hover { border-color: var(--primary-2); }
.ui-scale-preset.active { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary-2); }
.ui-scale-stepper { display: flex; align-items: center; gap: 14px; }
.ui-scale-step {
  min-width: 56px; padding: 12px 0; border-radius: 10px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); font-size: 20px; font-weight: 700; cursor: pointer;
}
.ui-scale-step:hover { border-color: var(--primary-2); }
.ui-scale-value { font-size: 20px; font-weight: 700; min-width: 74px; text-align: center; }

.muted { color: var(--muted); }
.small { font-size: 12px; }
.hidden { display: none !important; }
code {
  background: var(--panel-2);
  padding: 1px 5px;
  border-radius: 5px;
  font-size: 12px;
}
/* CLIE-1946 · светлая: --panel-2 = холст (#f5f5f7) — голый <code> на холсте сливался (1.00).
   Тон дорожки колонки (чуть темнее холста) виден и на холсте, и на белом. :where держит вес тега
   (0,0,1): любое правило с классом (.md-body code, pre code…) сильнее и не задето. */
:where(html[data-theme="light"]) code,
html[data-theme="light"] .ai-connect code { background: color-mix(in srgb, var(--bg) 92%, var(--text)); } /* .ai-connect-url code красит --panel-2 стиль из app.js (0,2,1) */

/* ---- topbar ---- */
/* 🔴🔴 ШАПКА — СПЛОШНАЯ ЛЕНТА ВО ВСЮ ШИРИНУ (CLIE-975·3, владелец 09.09.2026: «Ты добавил
   отступы и сделал как островок, ТУТ ЭТО НЕ В СТИЛЕ ДИЗАЙНА, верни обратно. Я лишь говорил
   про элементы ВНУТРИ»). Выбор «вариант 5» относился к РАССТАНОВКЕ элементов, а не к плите:
   поля/скругление/тень у ОДНОГО блока делали шапку чужой среди сплошных колонок продукта.
   🔴 Островной вид не выброшен, а поднят на уровень ВСЕГО продукта и стал НЕОБЯЗАТЕЛЬНОЙ
   шкурой (`html[data-ui="island"]`, island.css) — владелец там же сказал «либо давай ВСЕ
   блоки в таком стиле, посмотрим и решим». База продукта — лента, шкура — по выбору. */
.topbar {
  display: flex;
  align-items: center;
  gap: 16px;
  /* высота фиксирована токеном (см. --topbar-h) — .screen вычитает ровно её */
  height: var(--topbar-h); box-sizing: border-box; flex: none;
  padding: 10px 24px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 2px 10px rgba(0,0,0,.2);
  position: relative; z-index: 2;
}
/* Кнопки шапки — всегда в ОДНУ строку. На узких экранах подпись («Установить»,
   «Включить уведомления») переносилась на 2 строки → кнопка 44px вместо 30px и
   шапка распиралась выше --topbar-h. Высота шапки фиксирована, поэтому перенос
   здесь недопустим: текст ужимается многоточием, а не ломает сетку. */
.topbar button { white-space: nowrap; }
/* Крайние элементы шапки не должны липнуть к кромке/обрезаться: у первого и
   последнего — гарантированный отступ от края (свыше основного padding). */
.topbar > :first-child { margin-left: 2px; }
.topbar > :last-child { margin-right: 2px; }
.topbar .conn { flex-shrink: 0; }
.topbar .brand { flex-shrink: 0; }
/* 🔴🔴 ШАПКА НЕ СХЛОПЫВАЕТСЯ НИ ПРИ КАКОМ МАСШТАБЕ (CLIE-459).
   При «А+» (масштаб 130–200%) макетная ширина окна падает (1440 → 1108 → 720), а медиазапросы
   этого НЕ видят — они меряют настоящее окно. Раньше нехватку ширины разбирал flex: элементы
   шапки ужимались НИЖЕ своего содержимого (у .mode-toggle ещё и overflow:hidden → минимальный
   размер 0), и подписи «Личное|Работа» налезали друг на друга и обрезались («ЛиРа»).
   Теперь: элементы шапки НЕ ужимаются, а лишнее убирается ступенями — их считает topbarFit()
   ИЗМЕРЕНИЕМ (см. app.js), поэтому работает при любом окне И любом масштабе, а новая кнопка
   в шапке получает то же поведение сама. Порядок ступеней — от наименее ценного к самому нужному. */
.topbar > * { flex: 0 0 auto; }
.who .who-name { max-width: 240px; }
.topbar.tb-fit-1 .conn .muted,
.topbar.tb-fit-1 .who .who-st-line { display: none; }
/* topbar-bells-1 · ступень 1b: предложения короче, а не сразу одни значки. «Установить» остаётся значком
   «скачать», у «Включить уведомления» — колокольчик с плюсом и слово «Включить» (хвост .ntb-tail уходит).
   Без неё в окне 1440 рядом стояли два колокольчика без подписи. Ступень 2 — по-прежнему одни значки. */
.topbar.tb-fit-1b #installBtn { font-size: 0; gap: 0; }
.topbar.tb-fit-1b #notifyTopBtn .ntb-tail { display: none; }
.topbar.tb-fit-2 #installBtn,
.topbar.tb-fit-2 #notifyTopBtn { font-size: 0; gap: 0; } /* остаётся иконка + подсказка (title) */
.topbar.tb-fit-3 .who .who-name { display: none; }
.topbar.tb-fit-4 .mode-seg > span:not(.mode-badge) { display: none; }
.topbar.tb-fit-4 .mode-seg { padding: 5px 9px; }
.topbar.tb-fit-4 { gap: 10px; padding-left: 14px; padding-right: 14px; }
.topbar.tb-fit-5 .brand { display: none; }
.topbar.tb-fit-5 { gap: 7px; padding-left: 8px; padding-right: 8px; }
/* Предпоследняя ступень — убрать ПРЕДЛОЖЕНИЯ (установить приложение, включить уведомления):
   они не действие «сейчас», их же место есть в Настройках и в нижнем баннере. Заодно уходит
   путаница «два одинаковых колокольчика» (предложение и панель уведомлений), когда от кнопок
   остались одни иконки. */
.topbar.tb-fit-6 #installBtn,
.topbar.tb-fit-6 #notifyTopBtn { display: none; }
/* …и заодно поджимаем сами кнопки-иконки: лучше 6 компактных кнопок, чем 5 просторных и
   одна за краем. Ниже этого не ужимаем — иначе палец не попадает. */
.topbar.tb-fit-6 { gap: 6px; }
.topbar.tb-fit-6 .ghost.small { padding: 6px 7px; }
.topbar.tb-fit-6 .ui-scale-btn { min-width: 26px; padding: 4px 6px; }
/* Последний рубеж: телефон + масштаб 130–200% (макетная ширина ~300px) — даже одни иконки
   физически не влезают. Тогда шапка становится прокручиваемой, а НЕ обрезает «А−/А+» и
   «Настройки»: именно ими человек уменьшает масштаб обратно — отрезать их нельзя. */
.topbar.tb-fit-7 { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; overscroll-behavior-x: contain; }
.topbar.tb-fit-7::-webkit-scrollbar { display: none; }
.brand { font-weight: 700; background: var(--grad); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.who { margin-left: auto; font-weight: 600; }
/* ── #who как кликабельный чип: аватар + имя + короткая строка кастом-статуса. Клик → поповер
   статуса. Apple-grade: компактный, hover-подсветка, hairline, плавный переход. ── */
.who.who-status {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 8px; margin-left: auto; border-radius: 10px; cursor: pointer;
  max-width: 260px; transition: background .14s ease;
}
.who.who-status:hover { background: var(--hover); }
.who.who-status:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--sel); }
.who .who-av {
  width: 26px; height: 26px; border-radius: 50%; flex: none;
  background: var(--acc-grad); color: #fff; font-size: 11px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  background-size: cover; background-position: center;
}
.who .who-av.has-img { color: transparent; }
.who .who-name { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.who .who-st-line { display: inline-flex; align-items: center; gap: 4px; min-width: 0; max-width: 130px; color: var(--muted); font-weight: 500; }
.who .who-st-line .who-st-e { font-size: 13px; line-height: 1; }
.who .who-st-line .who-st-moon { display: inline-flex; }
.who .who-st-line .who-st-moon svg.ic { width: 13px; height: 13px; color: #7c8db3; }
.who .who-st-line .who-st-t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 12px; }
.who .who-st-line::before { content: "·"; color: var(--line); margin-right: 2px; }

/* ═══════════════════════════════════════════════════════════════════════════════
   🧭 ШАПКА — CLIE-975. Правая группа, действия со СЛОВАМИ и витрина компоновок.
   Владелец: «зачем тут показывать элементы, которые должны быть в настройках
   оформления? … уведомления рядом с идеями, у них похожи иконки … размести идеи
   слева от профиля». Тема и «А− А+» из шапки убраны (их дом — Настройки →
   Оформление / Размер интерфейса), шестерёнка уехала в меню профиля.
   Размерный класс ряда — общий `--ctl-h/--ctl-r/--ctl-fs` (канон control-size): все
   кнопки шапки одной высоты, «на глаз» тут ничего не подбирается.
   ═════════════════════════════════════════════════════════════════════════════ */
/* Распорка: единственный ГИБКИЙ элемент строки — с неё начинается правая группа.
   `flex:1 1 0` вместо `margin-left:auto` у #who: профиль перестал быть первым справа. */
.topbar .tb-gap { flex: 1 1 0 !important; min-width: 0; }
.topbar .who.who-status { margin-left: 0; height: var(--ctl-h); box-sizing: border-box; }
/* Действие шапки: иконка + (по компоновке) слово + бейдж. */
.topbar .hdr-act {
  position: relative; display: inline-flex; align-items: center; gap: 6px;
  height: var(--ctl-h); border-radius: var(--ctl-r); padding: 0 9px;
  color: var(--muted); font-size: var(--ctl-fs); font-weight: 600;
  transition: background .14s ease, color .14s ease;
}
.topbar .hdr-act:hover, .topbar .hdr-act.active { color: var(--text); background: var(--hover); }
.topbar .hdr-act svg.ic { width: 18px; height: 18px; }
.topbar .hdr-act .ideas-btn-ico, .topbar .hdr-act .today-btn-ico { display: inline-flex; }
/* Подпись действия. Слово есть только у «Идей» — их спутали с колокольчиком (просьба
   владельца): у остальных действий подпись живёт подсказкой (canon instant-tooltip). */
.topbar .hdr-lbl { white-space: nowrap; }
.topbar #todayBtn .hdr-lbl { display: none; }
/* 🤝 Чип «Мой ИИ у …» (владелец 15.09.2026: «где страница управления?»). Виден только пока есть
   чем управлять, поэтому он — мягкая капсула акцента (подложка 11% + хэйрлайн-кольцо 24%, канон
   CLIE-483), а не ghost-иконка: это состояние, которое надо заметить. Ждёт заявка — янтарь.
   Чернила смешаны с --text: тон держит контраст и на светлой, и на тёмной подложке.
   🔴 `.ghost` в селекторе — вес (0,3,0): в светлой теме `html[data-theme="light"] .ghost` (0,2,1)
   снимал подложку и кольцо — на кадре фон чипа 247,250,253 = фон шапки (в тёмной 41,43,66 на 29,31,41).
   `.wait` ниже того же веса и стоит позже — янтарь не перебит. */
.topbar .hdr-aimine.ghost {
  color: color-mix(in srgb, var(--accent) 78%, var(--text));
  background: color-mix(in srgb, var(--accent) 11%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 24%, transparent);
  animation: stPopIn .16s cubic-bezier(.3,.8,.4,1);
}
.topbar .hdr-aimine.ghost:hover { color: color-mix(in srgb, var(--accent) 78%, var(--text)); background: color-mix(in srgb, var(--accent) 17%, transparent); }
.topbar .hdr-aimine.wait {
  color: color-mix(in srgb, var(--warning) 62%, var(--text));
  background: color-mix(in srgb, var(--warning) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 34%, transparent);
}
.topbar .hdr-aimine.wait:hover { color: color-mix(in srgb, var(--warning) 62%, var(--text)); background: color-mix(in srgb, var(--warning) 20%, transparent); }
.topbar .hdr-aimine .hdr-aimine-ico { display: inline-flex; }
.topbar .hdr-aimine .hdr-aimine-ico svg.ic { width: 16px; height: 16px; }
/* Имя коллеги длинное — подпись режется многоточием, а не ломает ряд (min-width:0 + ellipsis). */
.topbar .hdr-aimine .hdr-lbl { min-width: 0; max-width: 240px; overflow: hidden; text-overflow: ellipsis; }
.topbar.tb-fit-3 .hdr-aimine .hdr-lbl { max-width: 150px; }
/* Состояние сети: точка молчит, пока всё хорошо; слово возвращается на любой беде
   (прогрессивное раскрытие — не отбирать экран под то, что и так в порядке). */
.topbar .conn:has(.dot-on) .muted { display: none; }

/* 🔴 Витрины компоновок (`[data-hdr="island|words|quiet|more|float"]`) здесь БОЛЬШЕ НЕТ:
   владелец выбрал «Плавающую», и она стала базовой шапкой выше. Возврат витрины ловит
   сторож ФОРМОЙ (design_lint → HDRONE_MECH). */

/* ── 👤 Меню профиля (#pfPop) ───────────────────────────────────────────────────
   Слой берёт общая дверь `ccLayerLift` (CC_LAYER_SEL), своих z-index нет. */
.pf-pop {
  position: fixed; width: 320px; padding: 8px;
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 18px 50px rgba(0,0,0,.28);
  animation: stPopIn .14s cubic-bezier(.3,.8,.4,1);
  max-height: min(82vh, calc(100vh - 24px)); overflow-y: auto; overscroll-behavior: contain;
}
.pf-pop-head { display: flex; align-items: center; gap: 10px; padding: 6px 8px 10px; }
.pf-pop-av {
  width: 36px; height: 36px; border-radius: 50%; flex: none;
  background: var(--acc-grad); color: #fff; font-size: 13px; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
  background-size: cover; background-position: center;
}
.pf-pop-av.has-img { color: transparent; }
.pf-pop-id { display: flex; flex-direction: column; min-width: 0; }
.pf-pop-nm { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-pop-ph { color: var(--muted); font-size: 12px; }
.pf-pop-row {
  display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box;
  padding: 9px 8px; border: 0; border-radius: 10px; background: transparent;
  color: var(--text); text-align: left; cursor: pointer;
  transition: background .12s ease;
}
.pf-pop-row:hover { background: var(--hover); }
.pf-pop-row.on { background: color-mix(in srgb, var(--primary) 12%, transparent); }
.pf-pop-ic { display: inline-flex; color: var(--muted); flex: none; }
.pf-pop-ic svg.ic { width: 18px; height: 18px; }
.pf-pop-tx { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.pf-pop-t { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-pop-s { color: var(--muted); font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-pop-ch { display: inline-flex; color: var(--muted); flex: none; opacity: .55; }
.pf-pop-ch svg.ic { width: 16px; height: 16px; }
/* Подвал «Оформление»: тема и размер интерфейса ушли из шапки, но не на три клика вглубь. */
.pf-pop-look {
  display: flex; align-items: center; gap: 6px;
  margin-top: 6px; padding: 8px 8px 4px; border-top: 1px solid var(--line);
}
/* 🧠 0363 · модели выдачи токенов: группы по провайдеру внутри тех же галочек `.aig-acc`;
   в пикере модели Среды запрещённая коллегой строка погашена, а не спрятана. */
.aig-models .aig-prov { flex-basis: 100%; display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; margin: 6px 0 2px; }
.aig-models .aig-prov button { font: inherit; text-transform: none; letter-spacing: 0; background: none; border: 0; padding: 0; color: var(--accent); cursor: pointer; }
.tip-aimodelpick button[disabled] { opacity: .45; cursor: not-allowed; }
/* 👤 CLIE-1147 · вход в настройку меню профиля — тихой строкой подвала: вход стоит у самой
   вещи (CLIE-857·2), но не спорит с пунктами, которые человек сюда вывел. */
.pf-pop-cfg { margin-top: 2px; border-top: 1px solid var(--line); padding-top: 8px; }
.pf-pop-cfg .pf-pop-t { font-weight: 500; color: var(--muted); font-size: 13px; }
.pf-pop-cfg .pf-pop-s { display: none; }
.pf-pop-lk { color: var(--muted); font-size: 12px; font-weight: 600; margin-right: auto; }
.pf-look-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 32px; height: 28px; padding: 0 8px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  font-size: 12px; font-weight: 700; cursor: pointer; transition: border-color .12s, background .12s;
}
.pf-look-btn:hover { border-color: var(--primary-2); background: var(--hover); }
.pf-look-btn svg.ic { width: 16px; height: 16px; }
.pf-pop-zoom { color: var(--muted); font-size: 12px; min-width: 38px; text-align: right; }

/* ── Поповер статуса (#stPop) — как Slack «Update your status». Крепится к #who в топбаре. ── */
.st-pop {
  position: fixed; z-index: 9700; width: 320px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px; box-shadow: 0 18px 50px rgba(0,0,0,.32);
  animation: stPopIn .14s cubic-bezier(.3,.8,.4,1);
  /* 🔴 CLIE-620: у поповера НЕ БЫЛО ни потолка, ни скролла, а positionStPop клампит только
     `top`. Внутри — шапка, энергия, 6 пресетов, поле, сетка эмодзи, «Очистить через», чипы
     и «Не беспокоить» с расписанием: на невысоком окне низ уходил за экран безвозвратно.
     Потолок + свой скролл, как у эталонного `.tc-pop`. */
  max-height: min(82vh, calc(100vh - 24px)); overflow-y: auto; overscroll-behavior: contain;
}
@keyframes stPopIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.st-head { font-weight: 700; font-size: 14px; margin-bottom: 10px; color: var(--text); }
.st-pop .st-sub { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin: 14px 0 8px; font-weight: 600; }
.st-presets { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 10px; }
.st-preset {
  display: flex; align-items: center; gap: 7px; padding: 7px 9px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  cursor: pointer; font-size: 12.5px; text-align: left; transition: border-color .12s ease, background .12s ease;
}
.st-preset:hover { border-color: var(--primary); background: var(--hover); }
/* Кнопка пресета применяет статус сразу — значит обязана показывать, выбран он или нет
   (та же пара токенов, что у .st-chip.on: акцентная заливка-тинт + акцентные чернила). */
.st-preset.on { background: var(--sel); border-color: var(--primary); color: var(--primary); font-weight: 600; }
.st-preset .st-preset-e { font-size: 15px; line-height: 1; flex: none; }
.st-preset .st-preset-t { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-custom { display: flex; align-items: center; gap: 7px; }
.st-emoji-btn {
  width: 36px; height: 36px; flex: none; border-radius: 9px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); cursor: pointer; font-size: 17px;
  display: flex; align-items: center; justify-content: center; transition: border-color .12s ease;
}
.st-emoji-btn:hover { border-color: var(--primary); }
.st-emoji-btn .st-emoji-ph svg.ic { width: 18px; height: 18px; color: var(--muted); }
.st-text {
  flex: 1; min-width: 0; height: 36px; border-radius: 9px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); padding: 0 11px; font-size: 13px; outline: none;
  transition: border-color .12s ease;
}
.st-text:focus { border-color: var(--primary); }
.st-clear-inline {
  width: 30px; height: 36px; flex: none; border: none; background: transparent; color: var(--muted);
  cursor: pointer; display: flex; align-items: center; justify-content: center; border-radius: 8px;
}
.st-clear-inline:hover { background: var(--hover); color: var(--text); }
.st-clear-inline svg.ic { width: 15px; height: 15px; }
.st-emoji-grid {
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; margin-top: 8px;
  padding: 6px; background: var(--panel-2); border-radius: 10px; border: 1px solid var(--line);
  max-height: 148px; overflow-y: auto;
}
.st-emoji-opt {
  border: none; background: transparent; cursor: pointer; font-size: 18px; line-height: 1;
  padding: 5px 0; border-radius: 7px; transition: background .1s ease;
}
.st-emoji-opt:hover { background: var(--hover); }
.st-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.st-chip {
  font-size: 12px; padding: 5px 10px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); cursor: pointer; transition: all .12s ease;
}
.st-chip:hover { border-color: var(--primary); }
.st-chip.on { background: var(--sel); border-color: var(--primary); color: var(--primary); font-weight: 600; }
.st-dnd { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.st-dnd-row { display: flex; align-items: center; gap: 9px; }
.st-dnd-ic { display: inline-flex; flex: none; }
.st-dnd-ic svg.ic { width: 17px; height: 17px; color: #7c8db3; }
.st-dnd-lbl { flex: 1; font-weight: 600; font-size: 13px; color: var(--text); }
.st-dnd-sw { flex: none; }
.st-dnd-state { margin: 6px 0 8px 26px; }
.st-dnd-opts { margin-left: 26px; }
.st-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 14px; }
.st-foot .st-clear { color: var(--danger); }
.st-foot .ghost.small { font-size: 12.5px; padding: 7px 14px; border-radius: 9px; }
.st-foot .st-saved { text-align: right; }

/* Настройки: строки «Не беспокоить»/«Авто-статус» (подпись + переключатель). */
.notif-set-row.ndar-row { align-items: flex-start; }
.ndar-row .ndar-lbl { display: flex; flex-direction: column; gap: 2px; font-weight: 600; }
.ndar-row .ndar-sub { font-weight: 400; }
.conn { display: flex; align-items: center; gap: 6px; }
.dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.dot-on { background: var(--ok); box-shadow: 0 0 8px var(--ok); }
.dot-off { background: #555; }

/* 🔌 ОФЛАЙН и НЕОТПРАВЛЕННОЕ — то же самое место состояния в шапке (второго индикатора
   сети не заводим). Спокойная янтарная пилюля: работа офлайн — это НОРМА, а не авария,
   поэтому без красного. Обе темы — через переменные. */
.dot-warn { background: var(--warning); box-shadow: 0 0 0 3px color-mix(in srgb, var(--warning) 22%, transparent); }
.conn.conn-warn {
  background: var(--warning-soft);
  border: 1px solid color-mix(in srgb, var(--warning) 30%, transparent);
  border-radius: 999px; padding: 3px 10px 3px 8px;
  transition: background .14s ease, border-color .14s ease;
}
.conn.conn-warn .muted { color: var(--warning); font-weight: 600; }
/* Узкая шапка прячет подпись состояния (ступень tb-fit-1) — но «нет сети / N ждут
   отправки» человек обязан видеть на ЛЮБОЙ ширине: это про сохранность его правок. */
.topbar.tb-fit-1 .conn.conn-warn .muted,
.topbar.tb-fit-2 .conn.conn-warn .muted,
.topbar.tb-fit-3 .conn.conn-warn .muted { display: inline; }
@media (min-width: 761px) {
  /* 📏 Размерный класс ряда (канон control-size; перепись «Глубины» I, lead-topbar-chip-size-1):
     пилюля «N ждут отправки» с полями 3px сверху/снизу была 25px (кадр lead: y16–40) в ряду кнопок
     шапки по --ctl-h (там 36px, y11–46) и «проваливалась». Теперь она берёт --ctl-h/--ctl-r/--ctl-fs,
     как .hdr-act; боковые поля прежние (10/8), янтарная окраска состояния — та же. */
  .topbar .conn.conn-warn {
    height: var(--ctl-h); box-sizing: border-box; padding-top: 0; padding-bottom: 0;
    border-radius: var(--ctl-r);
  }
  .topbar .conn.conn-warn .muted { font-size: var(--ctl-fs); }
}

/* ---- screens ---- */
/* 📲 CLIE-897: над шапкой может стоять плашка «Установите приложение» (телефон в браузере).
   Её РЕАЛЬНУЮ высоту меряет app.js (ccInstBarMeasure) и кладёт в --cc-instbar-h — экран
   вычитает ровно её. Плашки нет → переменной нет → 0px, поведение прежнее до байта. */
/* 🔒 11.10.2026: под шапкой может висеть плашка «пространство не оплачено» — её высоту меряет
   payBarMeasure (app.js) в --cc-paybar-h, и экран вычитает ровно её. Нет плашки → 0px. */
/* 🔔 23.10.2026 (CLIE-2020, замер прода 1440×900 под тест-аккаунтом): у нижней кромки стоит полоса
   «Включите уведомления» (#notifyBanner, fixed, 835–900) — она ложилась на поле ввода (832–878), и
   `elementFromPoint` в его центре отдавал полосу: человек без включённых уведомлений жал в поле —
   и ничего. Высоту прижатых к низу полос уже меряет дверь нижней кромки (ccBottomGap →
   --cc-bottom-gap), экран вычитает её так же, как плашки сверху. Нет полосы → 0px. */
.screen { height: calc(100% - var(--topbar-h) - var(--cc-instbar-h, 0px) - var(--cc-paybar-h, 0px) - var(--cc-bottom-gap, 0px)); }

/* ---- login ---- */
.login {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.card {
  width: 100%;
  max-width: 460px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
}
.card h1 { margin: 0 0 8px; font-size: 20px; }
.field { display: flex; flex-direction: column; gap: 6px; margin: 14px 0; }
.field > span { font-size: 12px; color: var(--muted); }
.row { display: flex; gap: 10px; align-items: flex-end; }
.grow { flex: 1; }
.hint { margin: -6px 0 8px; }

/* ── Знакомство (онбординг нового пользователя): аватар-герой + поля + тумблер ── */
#stepOnboard .ob-avw { position: relative; width: 96px; height: 96px; margin: 6px auto 16px; }
.ob-av { width: 96px; height: 96px; border-radius: 50%; background: var(--panel-2) center/cover no-repeat; box-shadow: 0 0 0 3px var(--panel), 0 0 0 5px var(--primary); display: flex; align-items: center; justify-content: center; color: var(--muted); overflow: hidden; cursor: pointer; transition: transform .13s ease; }
.ob-av:hover { transform: scale(1.03); }
.ob-av .ic { width: 40px; height: 40px; }
.ob-av-cam { position: absolute; right: -2px; bottom: -2px; width: 30px; height: 30px; border-radius: 50%; background: var(--acc-fill); color: #fff; border: 3px solid var(--panel); display: flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; transition: filter .12s ease; }
.ob-av-cam:hover { filter: brightness(1.08); }
.ob-av-cam svg { width: 15px; height: 15px; }
#stepOnboard textarea { resize: none; }
.ob-uname { display: flex; align-items: center; gap: 4px; }
.ob-uname .ob-at { color: var(--muted); flex: 0 0 auto; }
.ob-uname input { flex: 1; min-width: 0; }
.ob-toggle { display: flex; align-items: center; gap: 14px; margin: 18px 0 6px; }
.ob-toggle-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ob-toggle-tx b { font-size: 14px; font-weight: 600; color: var(--text); }
.ob-toggle-tx small { font-size: 11.5px; color: var(--text-dim); line-height: 1.35; }

/* ── iOS-тумблер (переиспользуемый: онбординг + Настройки→Профиль) ── */
.cc-switch { position: relative; flex: 0 0 auto; width: 46px; height: 28px; cursor: pointer; display: inline-block; }
.cc-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
/* Дорожка ВЫКЛЮЧЕННОГО тумблера — 24 % чернил (`--text`), а не хэйрлайн `--line`: на нём она была
   1.06 к `--panel-2` в тёмной и 1.23 в светлой (рендер 16.10.2026) — виден только кружок. Тот же
   рецепт у дизайна depth (`.cc-switch-tr`, «выкл. — 24 % чернил») и у тумблера «Разбора встреч»:
   ≈2.0 / ≈1.6 к подложке. Включённая — прежняя `--ok`. */
.cc-switch-tr { position: absolute; inset: 0; border-radius: 999px; background: color-mix(in srgb, var(--text) 24%, transparent); transition: background .18s ease; }
.cc-switch-tr::before { content: ""; position: absolute; left: 3px; top: 3px; width: 22px; height: 22px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.35); transition: transform .18s cubic-bezier(.3,.8,.4,1); }
.cc-switch input:checked + .cc-switch-tr { background: var(--ok); }
.cc-switch input:checked + .cc-switch-tr::before { transform: translateX(18px); }
.cc-switch input:focus-visible + .cc-switch-tr { box-shadow: 0 0 0 3px var(--sel); }

/* 🔴 БАЗА элементов = эталон дизайн-системы. Любая НОВАЯ страница на «голых»
   input/select/textarea/button получает единый вид (радиус 11, фокус-кольцо, свой
   шеврон) БЕЗ пер-компонентного CSS. Пер-компонентные *-input/*-select — легаси. */
input, select, textarea {
  background: var(--panel-2);
  border: 1px solid var(--line);
  color: var(--text);
  border-radius: 11px;
  padding: 11px 14px;
  font-size: 14px;
  outline: none;
  transition: border-color .15s, box-shadow .15s;
}
/* 🔴 Галочка и радио — НЕ текстовое поле: паддинг текстового поля им не положен.
   При `box-sizing: border-box` ширина не имеет права стать меньше паддинга, поэтому
   `padding: 11px 14px` выше МОЛЧА съедал объявленный `width: 18px` и превращал
   квадратную галочку в прямоугольник 30×24 (замер на проде, CRMC-695). Правим у базы:
   в проекте 17 правил чекбоксов и ни одно паддинг не гасило — значит воевали все. */
input[type="checkbox"], input[type="radio"] { padding: 0; }
input:focus, select:focus, textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--glow);
}
/* 🔴🔴 ОДНО КОЛЬЦО НА ПОЛЕ (CLIE-1120, владелец: «во всех поисках есть ненужная внутренняя
   подсветка»). Кольцо принадлежит той коробке, которую человек ВИДИТ рамкой. Поле, у которого
   своей рамки нет (компонент снял `border`, потому что рамку рисует обёртка поиска), кольца
   базы НЕ рисует — иначе внутри рамки загорается вторая «пилюля» (радиус 11 на поле высотой
   17 читается именно так). Кто внутри рамки, а кто сам рамка — решает ЗАМЕР рендера:
   `ccRingPlace` в app.js по фокусу ставит `data-cc-noring` полю и `data-cc-ring` обёртке.
   Из CSS этот вопрос не задать (селектора по вычисленному стилю нет), а список обёрток —
   белый список с дырой на следующем экране. Специфичность 0,2,1 — выше базы и выше
   пер-компонентных `.x-search input:focus`, чтобы легаси-заплатки не воевали с дверью. */
input[data-cc-noring][data-cc-noring]:focus,
textarea[data-cc-noring][data-cc-noring]:focus {
  box-shadow: none;
  /* «Утоплены → всплывают на фокусе» (§3.4) — про поле, которое САМО себе рамка. У поля
     ВНУТРИ рамки это рисует вторую коробку: в светлой теме `html[data-theme="light"]
     input:focus { background:#fff }` (0,2,2) перебивал `background: transparent` компонента
     (0,2,1) и печатал белую «пилюлю» внутри бежевой строки поиска — та же беда, что кольцо,
     только цветом. Возвращаем замысел компонента: фон рисует рамка. Имя атрибута повторено
     нарочно — 0,3,1 выше и базы, и темовой заплатки. */
  background: transparent;
}
/* …а подсветку берёт на себя рамка: линия — цветом границы, залитая коробка без границы —
   тонким внутренним контуром (ореол сюда НЕ возвращаем: это и была лишняя подсветка).
   🔴 Имя атрибута повторено НАРОЧНО: 0,3,0 перебивает `border: 1px solid var(--line)` самих
   обёрток (`.projects-list .proj-searchbar` = 0,2,0, и она ниже по файлу — при равной силе
   выигрывала бы она, и поле осталось бы вовсе без признака фокуса). */
[data-cc-ring][data-cc-ring="line"]:focus-within { border-color: var(--primary); }
[data-cc-ring][data-cc-ring="fill"]:focus-within { box-shadow: inset 0 0 0 1px var(--primary); }
select {
  appearance: none; -webkit-appearance: none;
  background-image: var(--sel-chev);
  background-repeat: no-repeat; background-position: right 12px center; padding-right: 34px;
}

/* 🔴🔴 СРЕД-34 · ВЫРАВНИВАНИЕ ВНУТРИ <button> ЗАДАЁМ САМИ, А НЕ БЕРЁМ У ДВИЖКА.
   У кнопки `align-items` приходит из UA-таблицы браузера, и она РАЗНАЯ:
     Chromium 130 (движок ПК-версии, Electron 33) и WebKit → `flex-start`
     Chromium 151 (свежий Chrome, на котором стоял наш стенд) → `normal` (= растянуть)
   Разница не косметическая. У flex-КОЛОНКИ `flex-start` даёт ребёнку ширину ПО СОДЕРЖИМОМУ:
   строка с `white-space:nowrap; overflow:hidden; text-overflow:ellipsis` получает коробку ШИРЕ
   родителя, обрезает себя по СВОЕЙ коробке (то есть не обрезает вовсе) и печатается поверх
   соседей. Замер ОДНОГО И ТОГО ЖЕ кода: коробка 232.9px внутри кнопки 208px (130) против
   192px с честным «…» (151). Именно поэтому «налезает» видел владелец, а стенд — нет.
   Фиксируем явно: `stretch` — то, что видит большинство (современный Chrome) и на чём рисовали
   дизайн. Кому нужно другое — пишет своё значение у себя, как и раньше. */
button, input[type="button"], input[type="submit"], input[type="reset"] { align-items: stretch; }

button {
  cursor: pointer;
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 10px 14px;
  font-size: 14px;
  color: var(--text);
  background: var(--panel-2);
  transition: background .12s, border-color .12s, opacity .12s;
}
button:hover { border-color: var(--primary); }
button:disabled { opacity: .45; cursor: not-allowed; }
.primary {
  background: var(--acc-grad);
  border-color: transparent;
  color: #fff;
  font-weight: 600;
  width: 100%;
  margin-top: 6px;
  box-shadow: 0 6px 16px -4px var(--glow);
}
.primary:hover { border-color: transparent; box-shadow: 0 8px 22px -4px var(--glow); }
.danger { background: var(--danger); border-color: transparent; color: #fff; font-weight: 600; }
.ghost { background: transparent; }
/* 🔴 ТА ЖЕ ГЕОМЕТРИЯ, ЧТО У `.primary.small` (см. большой комментарий ниже): `.ghost.small` —
   её родной брат, только не залитый, и значок внутри обязан стоять В СТРОКУ с подписью.
   Почему это правило класса, а не заплатка по месту: глобальное `button svg.ic { display:
   block }` (ниже) делает значок БЛОКОМ, а кнопка без флекса переносит подпись на вторую
   строку. Лечили это посайтово (`.crmw-head-acts button` — кадр лида 14.09.2026), и каждое
   новое место рождало ту же ступеньку заново: замер прода 14.09.2026 по выходам пустой доски
   CRM (`tools/shots/crmc1115-empty-acts.js`) — кнопка 100×50, значок y=372, подпись y=394,
   «ОДНА СТРОКА: false». Теперь геометрию задаёт САМ модификатор, и новая кнопка со значком
   выглядит правильно без единой строки CSS. */
.ghost.small {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 6px 10px; font-size: 12px;
}
.ghost.small svg.ic { width: 14px; height: 14px; }
/* 🔴 ПРАВИЛО КЛАССА: `.small` у ПЕРВИЧНОЙ кнопки = компактный ИНЛАЙН-контрол, родной брат
   `.ghost.small` (та же высота и шрифт, только залитый). Базовый `.primary` — кнопка ФОРМЫ
   (логин, подвал модалки): `width:100%` + `margin-top`. Внутри карточки/тулбара/поповера он
   превращался в исполинскую полосу с иконкой у левого края и текстом по центру — владелец
   2026-08-12 о баннере «на паузе» в карточке задачи: «Это что за пиздец?». Лечили это ПОСАЙТОВО
   (`.pm-foot .primary`, `.v2-cm-add button`, `#twNew`, `.v2pt-acts .primary`, `.composer .primary`,
   `.rec-bar .primary`… — KB «Шапка задач: кнопка Задача распирала строку», там же вывод «`.primary`
   в любом flex-ряду ВСЕГДА переопределять width»), и КАЖДОЕ новое место рождало новую полосу.
   Теперь геометрию задаёт САМ модификатор `.small`: новая кнопка в новом месте выглядит правильно
   без единой строки CSS. Осознанная полоса во всю ширину = `.primary` БЕЗ `.small` либо своё
   правило со специфичностью ≥ 2 классов (как `.tip-tm-btn` — кнопка таймера в карточке задачи). */
.primary.small {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: auto; margin-top: 0; padding: 6px 12px; font-size: 12px;
  box-shadow: 0 2px 8px -3px var(--glow);
}
.primary.small:hover { box-shadow: 0 4px 12px -4px var(--glow); }
.primary.small svg.ic { width: 14px; height: 14px; }
/* Только иконка (отправить/добавить) — КВАДРАТНАЯ и вровень с полем ввода рядом (поле ~35px). */
.primary.small.icon-btn { padding: 8px; }
.primary.small.icon-btn svg.ic { width: 17px; height: 17px; }
.error { color: var(--danger); min-height: 18px; margin: 10px 0 0; font-size: 13px; }
.picker { margin-top: 8px; }

/* ---- международный ввод телефона: селектор страны + маска ----
   ВНИМАНИЕ: базовая раскладка (flex/ширины/размер шеврона) продублирована
   инлайном в <head> index.html — чтобы протухший в кеше style.css не ломал
   вёрстку. Здесь — тема, отступы, состояния. */
.phone-row { display: flex; gap: 8px; align-items: stretch; }
.phone-row #phoneInput { flex: 1; min-width: 0; }
.cc-cc-btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 0 11px 0 13px; margin: 0; flex: 0 0 auto; height: 46px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px;
  color: var(--text); font-size: 15px; line-height: 1; white-space: nowrap;
  transition: border-color .12s, box-shadow .12s, background .12s;
}
.cc-cc-btn:hover { border-color: var(--primary); }
.cc-cc-btn:active { background: var(--panel); }
.cc-cc-btn[aria-expanded="true"] { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.cc-cc-flag { font-size: 19px; line-height: 1; }
.cc-cc-dial { font-variant-numeric: tabular-nums; font-weight: 600; letter-spacing: .2px; }
.cc-cc-chev { width: 18px; height: 18px; color: var(--muted); flex: 0 0 auto; }
.cc-cc-btn[aria-expanded="true"] .cc-cc-chev { transform: rotate(180deg); }
.cc-cc-chev { transition: transform .16s ease; }
/* поповер списка стран */
.cc-cc-pop {
  position: relative; margin-top: 8px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 20px 48px -20px rgba(0,0,0,.55); overflow: hidden;
}
/* строка поиска с иконкой */
.cc-cc-search { padding: 10px 10px 8px; border-bottom: 1px solid var(--line); position: relative; }
.cc-cc-search-ic { position: absolute; left: 22px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--muted); pointer-events: none; }
.cc-cc-search input { width: 100%; margin: 0; padding-left: 36px; height: 40px; }
.cc-cc-list { max-height: min(46vh, 320px); overflow-y: auto; overscroll-behavior: contain; padding: 6px; }
.cc-cc-item {
  display: flex; align-items: center; gap: 12px; width: 100%; box-sizing: border-box;
  min-height: 46px; padding: 7px 12px; margin: 0; border: 0; border-radius: 10px;
  background: transparent; color: var(--text); font-size: 15px; text-align: left;
  cursor: pointer; transition: background .1s;
}
.cc-cc-item:hover, .cc-cc-item.active { background: var(--panel-2); }
.cc-cc-item .cc-cc-flag { font-size: 22px; flex: 0 0 auto; }
.cc-cc-item .cc-cc-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-cc-item .cc-cc-code { color: var(--muted); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.cc-cc-item .cc-cc-check { width: 18px; height: 18px; flex: 0 0 auto; color: var(--primary); opacity: 0; }
.cc-cc-item.sel .cc-cc-name { font-weight: 600; }
.cc-cc-item.sel .cc-cc-code { color: var(--primary); font-weight: 600; }
.cc-cc-item.sel .cc-cc-check { opacity: 1; }
.cc-cc-empty { padding: 22px 10px; text-align: center; color: var(--muted); font-size: 13.5px; }

/* ---- chat layout ---- */
/* колонки: рельс | мои задачи | список чатов | тред.
   Ширины задач/чатов — в CSS-переменных (тянутся мышью, см. .col-resizer
   и initColumnResize в app.js); значения сохраняются в localStorage.
   (Контакты раньше были этой колонкой — теперь они в модалке с рельса.) */
.chat {
  display: grid;
  /* «render-width» столбцов проектов/задач: по умолчанию = пользовательская ширина
     (--w-*), но состояния «свернуть»/«скрыть»/«режим Личное» переопределяют их на
     42px/0 (см. uiColsEnsureStyles в app.js). Так все комбинации свёрнуто/скрыто ×
     инфо-панель складываются БЕЗ комбинаторного перечисления grid-template-columns. */
  --rw-projects: var(--w-projects, 200px);
  --rw-tasks: var(--w-tasks, 250px);
  /* 🔴 БАГ «чат улетел по ширине, не видно кнопок справа» (CLIE-265): боковые
     столбцы (проекты/задачи/чаты) — перетаскиваемые и капаются до 480/560px. Если
     сумма их пользовательских ширин + рельс не помещается в узкое окно, столбец
     треда 1fr сжимался до нуля, а его шапка (поиск/переводчик/звонок/видео/⋯)
     выдавливалась ЗА правую кромку — визуально «пропадала». Лечение: боковые
     треки → minmax(0, ширина) (усыхают, когда места мало, вместо того чтобы
     давить тред), а тред → minmax(--thread-min, 1fr) — НИКОГДА не уже, чем нужно
     шапке. На широком экране всё как было: боковые получают полную ширину,
     тред — остаток. Общего горизонтального overflow нет: минимум сетки
     96+0+0+--thread-min < любой ширины, где применяется этот грид (>1080px). */
  --thread-min: 420px;
  grid-template-columns: var(--rail-track) minmax(0, var(--rw-projects)) minmax(0, var(--rw-tasks)) minmax(0, var(--w-chats, 280px)) minmax(var(--thread-min), 1fr);
}

/* ---- левый вертикальный рельс папок/фильтров (Telegram-style) ---- */
.chat-rail {
  /* 🧭🧭 ЛЕВЫЙ БЛОК = рейка хабов `.rail-col` + второе меню видов `.rail-hub`, которое
     ПРИСТЁГНУТО к правой кромке рейки и показывается ТОЛЬКО при наведении (владелец,
     раунд 7). 🔴 Панель живёт ВНУТРИ `.chat-rail` намеренно: остров (`island.css`)
     одевает именно его, и второе меню получает плиту ЛЕВОГО блока даром (владелец: «оно
     должно быть частью левого блока, а не правого»). В раунде 3 панель стояла в
     `.projects-col` — дорожке КОНТЕНТА — и приносила с собой плиту правого блока.
     🔴 `position: relative` + `overflow: visible` — якорь и выход для панели: она висит за
     коробкой рейки (`left: 100%`), поверх контента. Клипает содержимое теперь `.rail-col`
     (с унаследованным скруглением плиты), а не сама рейка. */
  position: relative;
  display: flex; flex-direction: row; align-items: stretch;
  gap: 0; padding: 0;
  background: linear-gradient(180deg, var(--cm-0e1018, #0e1018), var(--cm-0b0d14, #0b0d14));
  /* 🔴 Цвет ПОД градиентом — не украшение, а опора для `background-color: inherit` у липкой
     «Аи»: сам по себе градиент оставляет background-color прозрачным, и подложка липкого
     элемента стала бы дырой. Виду это ничего не меняет — градиент рисуется поверх, а его
     нижний стоп и есть этот цвет. Оформления (`data-concept`) красят рельс плоским токеном,
     и `inherit` подхватывает уже его. */
  background-color: var(--cm-0b0d14, #0b0d14);
  border-right: 1px solid var(--line);
  /* 🔴🔴 РАЗДЕЛЕНИЕ РОЛЕЙ (канон `section-body-column`): сама рейка НЕ прокручивается —
     прокручивается её тело `.rail-scroll`, а хром («Ещё ждут» и прикреплённая «Ая») стоит
     рядом и БЕРЁТ СВОЮ ВЫСОТУ. Пока прокруткой была сама рейка, липкий хвост НАКРЫВАЛ
     последние ряды: замер боевого прода 04.10.2026 (окно 1440×900) — «Ая» top=827 поверх
     ряда «CRM» top=837..892, то есть ряд «в рейке», а человеку не виден. Числа в calc()
     вместо этого подгонять ЗАПРЕЩЕНО: высота хрома зависит от состава полоски признаков. */
  overflow: visible; min-height: 0;
}
/* Колонка хабов: прежняя рейка целиком (ряды + «Ещё ждут» + прижатая «Ая»). Клипает себя
   сама и наследует скругление плиты острова — без этого липкий хвост «Аи» вылезал бы за
   нижние углы плиты, когда рейка перестала клипать (`overflow: visible` ради панели). */
.rail-col {
  flex: 1 1 auto; width: 100%; min-width: 0;
  display: flex; flex-direction: column; align-items: stretch;
  gap: 6px; padding: 10px 8px 0; min-height: 0; overflow: hidden;
  border-radius: inherit;
}
/* 🧭 МЕТРИКИ РЕЙКИ — ПРЕЖНИЕ (владелец 11.10.2026, раунд 8: «дизайн меню слева нужно вернуть
   как было — было больше пространства, больше размеры, просто верни как было»). Раунд 7 ужал
   ряд до 6/3, зазор 2, значок 20, чтобы рейка влезала в 1440×900 без прокрутки, — владелец
   этого не просил. Ряды берут базу `.rail-item` (8/4, зазор 3, значок 22), тело — зазор 6;
   не влезло в экран — рейка прокручивается, «Ая» прижата хвостом, как и до хабов.
   🔴 Своих ужатых метрик для `.rail-col` не заводить: размер ряда — одно место, `.rail-item`. */

/* 🧭🧭 ВТОРОЕ МЕНЮ ВИДОВ — ПРИ НАВЕДЕНИИ, РЯДОМ С РЕЙКОЙ, НА ВСЮ ЕЁ ВЫСОТУ, ПОВЕРХ КОНТЕНТА
   (согласовано владельцем 2026-10-11, раунд 7, кадры макета: «Да, делай так»).
   🔴 ПОВЕРХ, а не в сетке: `position: absolute` от рейки — контент не двигается ни на пиксель
   (замер: кромка треда 634 → 634, списка 354 → 354). Раунд 5 держал панель постоянной
   колонкой сетки — владелец увидел «подменю смещает контент» и вернул.
   🔴 В покое панели НЕТ (`display: none`): открывает её класс `.hub-open` на рейке, который
   ставит `renderRailHubPane` по наведению на хаб с видами; уход курсора с левого блока снимает.
   Высота — ровно высота рейки (`top: 0; bottom: 0`): «на всю высоту» без своих чисел.
   🏝 ОТДЕЛЬНЫЙ ОСТРОВОК (владелец 11.10.2026, раунд 8: «выезжающее меню пусть выглядит как
   отдельный островок с такими же скруглениями»): зазор `--hub-gap` от рейки, полное скругление
   плиты (`--isl-r`), кольцо и тень своего острова. Подложка — та же, что у рейки (`inherit`).
   🔴 Зазор — НЕ дыра для курсора: мост `.chat-rail.hub-open::after` лежит в зазоре и
   принадлежит рейке, поэтому путь «хаб → островок» не роняет `mouseleave` левого блока. */
.rail-hub {
  position: absolute; left: calc(100% + var(--hub-gap)); top: 0; bottom: 0; z-index: 60;
  width: var(--hub-w); box-sizing: border-box;
  display: none; flex-direction: column; min-height: 0; overflow: visible;
  padding: 16px 12px 12px;
  background: inherit;
  border-radius: var(--isl-r, 14px);
  box-shadow: inset 0 0 0 1px var(--line), 0 22px 50px -14px rgba(0, 0, 0, .6);
}
html[data-theme="light"] .rail-hub { background: var(--panel); box-shadow: inset 0 0 0 1px var(--line), 0 22px 50px -16px var(--cm-14285a-28, rgba(20, 40, 90, .28)); }
.chat-rail.hub-open .rail-hub { display: flex; }
/* 🔴 МОСТ ЗАЗОРА ПРИНАДЛЕЖИТ ОСТРОВКУ (12.10.2026, раунд 9): островок встаёт в полосу слоёв
   (`ccLayerRaise`), и мост обязан встать туда же — мост рейки оставался под страницей сделки
   (`#dealDrawer` 300002), курсор по пути «хаб → островок» падал на неё, и `mouseleave` закрывал
   меню. Ради моста у островка `overflow: visible` (прокручивает своё тело `.rh-body`). */
.rail-hub::before { content: ""; position: absolute; right: 100%; top: 0; bottom: 0; width: var(--hub-gap); }
.rail-hub.hidden { display: none; }
/* Вариант 6 (выбор владельца 11.10.2026, раунд 8: «6 берём на подменю»): крупный список —
   шапка со значком хаба в плашке, ряды 52 px, значок вида в своей плашке, текст 15.5 px.
   Раунд 7 был 38 px / 13.5 px — «всё мелкое и некрасивое, места много». */
.rh-head {
  flex: 0 0 auto; display: flex; align-items: center; gap: 12px;
  padding: 2px 8px 16px; font-size: 20px; font-weight: 750;
  letter-spacing: -.01em; color: var(--text); min-width: 0;
}
.rh-head .rh-ht { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rh-head .rh-hic {
  flex: none; width: 38px; height: 38px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--acc-fill) 18%, transparent); color: var(--primary-2);
}
.rh-head .rh-hic svg.ic { width: 21px; height: 21px; }
.rh-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; }
.rh-row {
  display: flex; align-items: center; gap: 13px; flex: none;
  height: 52px; padding: 0 10px; border-radius: 13px; border: 0;
  background: transparent; color: var(--text); cursor: pointer;
  text-align: left; width: 100%;
  transition: background .12s, color .12s;
}
.rh-row:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }
.rh-row .rh-ic {
  display: flex; align-items: center; justify-content: center; line-height: 1; flex: none;
  width: 34px; height: 34px; border-radius: 10px;
  background: color-mix(in srgb, var(--text) 7%, transparent); color: var(--text);
  transition: background .12s, color .12s;
}
.rh-row .rh-ic svg.ic { width: 19px; height: 19px; }
.rh-row .rh-t { flex: 1 1 auto; min-width: 0; font-size: 15.5px; font-weight: 560; line-height: 1.25;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rh-row .rh-n {
  flex: none; min-width: 22px; height: 20px; padding: 0 7px; border-radius: 10px;
  background: color-mix(in srgb, var(--acc-fill) 16%, transparent); color: var(--primary-2);
  font-size: 11.5px; font-weight: 650;
  display: flex; align-items: center; justify-content: center;
}
/* Открытый вид — подложка акцентом 15 % (канон `accent`), значок — в залитой плашке. */
.rh-row.active { background: color-mix(in srgb, var(--acc-fill) 15%, transparent); color: var(--primary-2); font-weight: 620; }
.rh-row.active .rh-ic { background: var(--acc-fill); color: #fff; }

/* 👁 «Активное навиду» — ВЫБРАННЫЙ ПОДПУНКТ ОТДЕЛЬНОЙ ПЛИТКОЙ под активным хабом: та же форма,
   что у пункта главного меню (значок + подпись, база `.rail-item`), только ДРУГОЙ ЦВЕТ
   (владелец 11.10.2026, раунд 8: «подменю в главном сделаем так же как и главное, просто цвет
   другой»; капсула раунда 7 — «не очень»). Хаб залит градиентом/акцентом, плитка — акцентным
   тинтом 14 % с кольцом 26 % и акцентными чернилами `--primary-2` (канон `foreign-brand-own-mark`:
   акцентный ТЕКСТ и акцентная ЗАЛИВКА — разные токены). Обе темы — одни токены. */
.rail-item.rail-hubsub {
  background: color-mix(in srgb, var(--acc-fill) 14%, transparent);
  color: var(--primary-2, var(--primary));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--acc-fill) 26%, transparent);
}
.rail-item.rail-hubsub .rail-label { color: inherit; font-weight: 650; }
/* 🧩 ВАРИАНТ 1 (выбор владельца 12.10.2026, раунд 9): хаб и плитка его вида — ОДНО целое на
   общей подложке: акцентный тинт 11 % с кольцом 30 %, внутри плитка без своей рамки. Наведение
   на любую точку блока открывает меню хаба (`wireRailHubHover`). Обе темы — одни токены. */
.rail-hubgrp {
  display: flex; flex-direction: column; gap: 4px; flex: none;
  padding: 4px; border-radius: calc(var(--radius, 12px) + 4px);
  background: color-mix(in srgb, var(--acc-fill) 11%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--acc-fill) 30%, transparent);
}
/* 🚫 У плитки выбранного вида НЕТ наведения: этот вид уже открыт, нажимать на неё незачем
   (владелец 12.10.2026, р.10: «тут не нужно на подменю ховер, там ведь действия нет никакого»).
   Гасим всё, что даёт наведение кнопке: фон `.rail-item:hover` (и светлую тему 0,3,1), рамку
   глобального `button:hover`, смену чернил, курсор-«палец». Наведение на блок по-прежнему
   открывает меню хаба — это слушатель `wireRailHubHover`, а не стиль. */
.rail-hubgrp > .rail-item.rail-hubsub,
.rail-hubgrp > .rail-item.rail-hubsub:hover {
  background: transparent; box-shadow: none; border-color: transparent;
  color: var(--primary-2, var(--primary)); cursor: default;
}
.rail-item.rail-hub-peek:not(.active) { background: color-mix(in srgb, var(--acc-fill) 14%, transparent); color: var(--text); }

/* Тело рейки: ряды разделов (и «Настроить меню» — он остаётся в прокрутке, см. renderRail). */
.rail-scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  display: flex; flex-direction: column; align-items: stretch; gap: 6px;
  /* devspace-rail-active-clipped-1 · запас под нижний край (полоса 12 px ниже): его читает railRevealActive
     (app.js), когда докручивает открытый раздел, и браузер — при фокусе с клавиатуры */
  scroll-padding-bottom: 12px;
}
/* 13.10.2026: тело рейки — `.cc-scroll-in` (край тает, пока ниже есть ряды, CLIE-620). Край не занимает
   места: −высота и −6 зазора колонки (иначе на кромке прокрутки рейка прыгала бы на 6 px). */
.rail-scroll.cc-scroll-in.more-t::before { margin-bottom: -32px; }
/* approvals-rail-chevron-1 · knowledge-rail-overflow-fade-1 (раунд R, 1440×900): нижний край 26 px гасил ЦЕЛИКОМ
   видимый ряд — «Среда разработчика» кончается на y 802 при кромке прокрутки 814, и вторая строка «разработчика»
   тускнела (свет: 68,70,85 → 133,134,144). Край — полоса 12 px, сплошная 4 px у самой кромки: видимый ряд не
   гаснет, срезанный уходит под неё краем. Места не занимает, как и прежде: −12 высоты и −6 зазора колонки. */
.rail-scroll.cc-scroll-in.more-b::after {
  height: 12px; margin-top: -18px;
  background: linear-gradient(to top, var(--cc-fade, var(--panel)) 4px, transparent);
}
/* myrequests-rail-vpn-1 · partners-rail-vpn-1 · rail-devspace-missing-approvals · rail-devspace-missing-files ·
   wiki-rail-lost-entry-1: край тает краской стекла и по пустому месту не виден — нужен знак «ниже есть ещё»,
   на любой ширине (и в рейке 62 px), только пока ccScrollInEdges держит .more-b.
   rail-chevron-1 · rail-chevron-vpn-1 · rail-overflow-chevron-1 · rail-overflow-chevron-1@k_vpn.device-dark ·
   approvals-rail-chevron-1 (раунд R): голый шеврон в самом крае висел по центру под последним рядом — подпись
   VPN y 785–792, шеврон 804–810 при шаге рядов ~27 px, у активной пилюли VPN (низ 803) зазор 0 — читался
   «VPN ▾». Теперь знак — СВОЯ капсула 26×12 (кромка --line, заливка --panel-2, шеврон --muted) на шве ПОД
   кромкой прокрутки: на линии над «Аей» (::before хвоста), при прикреплённых рядах — в зазоре над ними
   (::before полоски). absolute в position: relative соседа — места не занимает, клики проходят. Ни хвоста,
   ни полоски — капсулой становится сам край и липнет к низу рейки. «Ещё ждут» (.rail-pin-rest) несёт свой
   шеврон — капсулы нет. Рейка 62 px (≤720): поле 52 px, шов тот же 6 px — капсула 26 px встаёт так же. */
.rail-scroll.cc-scroll-in.more-b + .rail-more:empty + .rail-tail::before,
.rail-scroll.cc-scroll-in.more-b + .rail-more:not(:empty):not(:has(> .rail-pin-rest))::before,
.rail-col:not(:has(> .rail-tail)):has(> .rail-more:empty) > .rail-scroll.cc-scroll-in.more-b::after {
  content: ""; width: 26px; height: 12px; box-sizing: border-box; pointer-events: none;
  border: 1px solid var(--line); border-radius: 999px;
  background:
    linear-gradient(45deg, transparent calc(50% - 1.4px), var(--muted) calc(50% - .6px) calc(50% + .6px), transparent calc(50% + 1.4px)) calc(50% - 3px) 50% / 6px 6px no-repeat,
    linear-gradient(-45deg, transparent calc(50% - 1.4px), var(--muted) calc(50% - .6px) calc(50% + .6px), transparent calc(50% + 1.4px)) calc(50% + 3px) 50% / 6px 6px no-repeat,
    var(--panel-2);
}
.rail-scroll.cc-scroll-in.more-b + .rail-more:empty + .rail-tail::before,
.rail-scroll.cc-scroll-in.more-b + .rail-more:not(:empty):not(:has(> .rail-pin-rest))::before {
  position: absolute; z-index: 1; left: calc(50% - 13px); top: -6px;
}
/* над полоской признаков шва нет — капсула садится на саму кромку прокрутки (верхние 6 px — над сплошной
   полосой края, нижние — в зазоре колонки 6 px) и кончается ровно у верха ряда-признака: ни ряд, ни его
   бейдж (на телефоне он в углу, right 0) она не накрывает */
.rail-scroll.cc-scroll-in.more-b + .rail-more:not(:empty):not(:has(> .rail-pin-rest))::before { top: -12px; }
.rail-col:not(:has(> .rail-tail)):has(> .rail-more:empty) > .rail-scroll.cc-scroll-in.more-b::after {
  align-self: center; bottom: 4px;
}
/* 📌 «АЯ» ВСЕГДА НА ВИДУ (владелец 16.09.2026). Она стояла внизу ровно до тех пор, пока меню
   помещалось на экран: `margin-top:auto` прижимает хвост только в НЕпрокручиваемом столбце. У
   человека с полутора десятками разделов рельс прокручивается, и «Ая» уезжала за нижний край —
   самая нужная кнопка пряталась первой (замер: вне окна на 785px).
   🔴 ЛИПНЕТ ТОЛЬКО ОНА. Первый заход обернул ВЕСЬ хвост, и вместе с ней прилипло «Настроить
   меню», которого никто не просил.
   🔴 ФОН БЕРЁТСЯ У РЕЛЬСА, А НЕ ВЫДУМЫВАЕТСЯ. Липкому элементу нужна непрозрачная подложка
   (иначе сквозь него едут пункты), и первый заход залил её КОНСТАНТОЙ, взятой из кода
   (#0b0d14). Замер на живом проде: рельс там покрашен `rgb(20,26,33)` БЕЗ градиента (его
   перекрывает оформление), то есть константа промахнулась на глаз — и человек увидел тёмный
   прямоугольник вместо прежнего вида. `background-color: inherit` берёт ровно тот цвет,
   которым покрашен рельс, в любой теме и любом оформлении — цвет СОВПАДАЕТ по построению,
   поэтому никакого шва и никакой «коробки» не возникает. Растушёвка тут была бы враньём:
   она маскирует расхождение вместо того, чтобы его не допускать. */
/* 📌 ШОВ КРЕПИТСЯ К «АЕ» + НЕБОЛЬШАЯ ВНЕШНЯЯ ТЕНЬ (владелец 16.09.2026: «полоска сверху должна
   крепиться и там должна быть небольшая внешняя тень»). Шов теперь ВНУТРИ `.rail-tail` (renderRail
   берёт `tailAt` ДО него): пока он оставался в прокрутке, верхняя кромка «Аи» была видна только
   когда рельс домотан донизу, а на прокрутке вверх липкая кнопка висела прямо на списке — без
   границы и без признака, что под ней что-то едет. Тень направлена ВВЕРХ (иначе её негде увидеть:
   низ блока — это кромка рельса) и намеренно короткая: рельс в светлой теме сам карточка со своей
   тенью, вторая жирная полоса превратила бы низ меню в «ящик».
   🔴 ТЕНЬ ИДЁТ ОТ САМОЙ ПОЛОСКИ, А НЕ ОТ КРОМКИ БЛОКА (владелец 16.09.2026: «на скрине не бьётся
   тень с полоской»). `box-shadow` рисуется от border-box, а у шва своё `margin: 6px 4px` — значит
   первый заход развёл их на 6px: сверху тень, ниже белая щель, ещё ниже линия, и низ меню читался
   ДВУМЯ границами вместо одной. Гасим шву верхнее поле ВНУТРИ липкой обёртки: кромка блока и линия
   совпадают, и тень идёт ровно из-под линии.
   🔴 ЦВЕТ ТЕНИ — СИНЕВАТЫЙ (он же): нейтрально-чёрная тень на фирменном синем рельсе читалась
   грязью. Светлая берёт сам акцент (#0071e3), тёмная — глубокую синеву: тень обязана быть ТЕМНЕЕ
   панели, светлый индиго на тёмном дал бы не тень, а свечение. */
/* 🔴 ЛИПКОСТЬ СНЯТА, ВИД СОХРАНЁН (04.10.2026). «Ая» всегда на виду по-прежнему — но
   теперь потому, что она ВНЕ прокручиваемого тела и берёт свою высоту, а не потому, что
   перекрывает его собой. `position: relative; z-index: 3` оставлены ради ТЕНИ: она
   рисуется поверх тела рейки, как и раньше. `background-color: inherit` тоже остаётся —
   цвет берётся у рейки (любая тема, любое оформление), шва не возникает по построению. */
.rail-tail {
  position: relative; z-index: 3; flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: stretch;
  padding-bottom: 10px;
  background-color: inherit;
  box-shadow: 0 -6px 12px -4px var(--cm-0a1030-75, rgba(10, 16, 48, .75));
}
.rail-tail > .rail-sep { margin-top: 0; }
html[data-theme="light"] .rail-tail { box-shadow: 0 -6px 12px -4px rgba(0, 90, 190, .13); }

.rail-item {
  position: relative;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 8px 4px; border-radius: var(--radius);
  cursor: pointer; color: var(--muted); border: 1px solid transparent;
  background: transparent; width: 100%; text-align: center;
  transition: background .12s, color .12s, border-color .12s;
}
.rail-item:hover { background: var(--panel-2); color: var(--text); }
.rail-item .rail-ic { display: flex; align-items: center; justify-content: center; line-height: 1; }
.rail-item .rail-ic svg.ic { width: 22px; height: 22px; }
/* 🔴 «Контрастность» 10.09.2026: подпись пункта рельса — акцентные ЧЕРНИЛА на тёмной
   панели, значит --primary-2 (замер: --primary 4.40:1, стало 6.14:1). */
.rail-item.active .rail-label { color: var(--primary-2, var(--primary)); }
.rail-item .rail-label {
  font-size: 10.5px; line-height: 1.12; max-width: 100%;
  /* Рельс расширен 76→96px (жалоба владельца: «одна буква не влезает» —
     «Помощни/к», «Обращен/ия», «Пользова/т.» рубились). При 96px обычные
     ОДНОсловные ярлыки помещаются в одну строку. Клэмп ниже — уже ФОЛБЭК:
     на 2 строки с word-break (без «…») переносятся лишь редкие сверхдлинные
     («Приглашения») и пользовательские имена папок; ellipsis — только если и
     в 2 строки не влезло. */
  white-space: normal; overflow-wrap: anywhere; word-break: break-word;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.rail-item.active {
  background: var(--acc-grad); color: #fff;
  box-shadow: 0 6px 16px -4px var(--glow); border-color: transparent;
}
.rail-badge {
  position: absolute; top: 4px; right: 8px;
  min-width: 17px; height: 17px; padding: 0 4px; border-radius: 9px;
  background: var(--acc-fill); color: #fff;
  font-size: 10px; font-weight: 700; line-height: 17px; text-align: center;
  box-shadow: 0 2px 6px -1px var(--glow);
}
.rail-item.active .rail-badge { background: #fff; color: var(--acc-fill); }
.rail-sep { height: 1px; background: var(--line); margin: 6px 4px; flex: none; }
/* «Ая» — голосовой ИИ в самом низу рельса: премиальная «звёздная» кнопка (градиент-подпись,
   акцентная иконка со свечением, мягкое пульсирующее сияние). В активном виде — как обычный active. */
.rail-item.rail-aya { position: relative; }
.rail-item.rail-aya .rail-ic { color: var(--primary-2); filter: drop-shadow(0 0 6px var(--glow)); position: relative; z-index: 1; }
.rail-item.rail-aya .rail-label { position: relative; z-index: 1; font-weight: 650; background: var(--grad); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent; }
.rail-item.rail-aya::after { content: ""; position: absolute; inset: 4px; border-radius: 12px; background: radial-gradient(62% 60% at 50% 38%, var(--glow), transparent 72%); opacity: .3; pointer-events: none; z-index: 0; animation: railAyaGlow 3.4s ease-in-out infinite; }
@keyframes railAyaGlow { 0%, 100% { opacity: .24; } 50% { opacity: .5; } }
.rail-item.rail-aya.active .rail-ic { color: #fff; filter: none; }
.rail-item.rail-aya.active .rail-label { background: none; -webkit-text-fill-color: #fff; color: #fff; }
@media (prefers-reduced-motion: reduce) { .rail-item.rail-aya::after { animation: none; } }
/* «Папки» — последний пункт верхнего блока (управление папками) */
.rail-folders {
  border: 1px dashed var(--line); color: var(--muted);
}
.rail-folders:hover { border-color: var(--primary); color: var(--text); background: transparent; }
/* «Пользователи» — отдельный пункт в самом низу рельса.
   🔴 CLIE-857: `margin-top:auto` отсюда УБРАН. Он прижимал хвост меню вниз, опираясь на
   то, что «Пользователи» стоят предпоследними — а с личным порядком (человек может
   поднять их наверх) это утащило бы вниз половину меню. Прижимает теперь ПОСЛЕДНИЙ шов
   (`.rail-sep.rail-sep-push`), который renderRail ставит перед последним блоком. */
.rail-users {
  border: 1px dashed var(--line); color: var(--muted);
}
.rail-users:hover { border-color: var(--primary); color: var(--text); background: transparent; }
/* Последний шов меню прижимает хвост («Ая») к низу рельса — см. renderRail/CLIE-857. */
.rail-sep.rail-sep-push { margin-top: auto; }
/* 🧭 CLIE-857·2 — «Настроить меню»: ВХОД В НАСТРОЙКУ СТОИТ В САМОМ МЕНЮ (владелец: «от сюда
   убери, сделай прям в самом меню кнопку настройки»). Это ИНСТРУМЕНТ меню, а не раздел:
   тихий вид (без заливки и без active), тонкий волосок сверху отделяет его от последнего
   пункта. Своих чисел размера нет — коробка та же `.rail-item`.
   🔴 `margin-top:auto` сюда НЕ ставим: он уже стоит у `.rail-sep-push`, и второе авто-поле
   поделило бы свободное место пополам — хвост меню («Ая») повис бы посередине. */
.rail-item.rail-navcfg {
  margin-top: 2px; padding-top: 10px;
  border-top: 1px solid var(--line); border-radius: 0 0 var(--radius) var(--radius);
  color: var(--muted); opacity: .82;
}
.rail-item.rail-navcfg:hover { opacity: 1; color: var(--text); background: var(--panel-2); }
.rail-item.rail-navcfg .rail-ic svg.ic { width: 19px; height: 19px; }
html[data-theme="light"] .nmbar-lock { opacity: 1; } /* CLIE-1946: «всегда» в «Настроить меню» (стиль — app.js, .75) на светлом = 3.68:1 */
/* 🔄 «Поменять местами» (владелец): «Настроить меню» встаёт НАД «Ая» и оказывается сразу
   под прижимающим швом `.rail-sep-push`. Тогда собственный волосок-`border-top` кнопки лишний
   — иначе линия задваивается. Шов между «Настроить меню» и «Ая» даёт обычный `.rail-sep`. */
.rail-sep.rail-sep-push + .rail-item.rail-navcfg { margin-top: 0; padding-top: 6px; border-top: 0; }

/* ── 🔔 СЧЁТЧИК РАЗДЕЛА ЗА СГИБОМ: признак у нижней кромки рейки ────────────────────────
   Значок-число стоит на разделе ровно для того, чтобы его увидели НЕ ОТКРЫВАЯ раздел. Ряд
   за сгибом (замер прода 04.10.2026: видно 14 рядов из 28 при окне 1440×900) делает его
   бесполезным — поэтому строка такого раздела ПРИКРЕПЛЯЕТСЯ к кромке, и нажатие открывает
   ИМЕННО ЕГО (канон `press-once-and-done`: одно нажатие, без «прокрути и найди»).
   🔴 Пустая полоска не занимает НИ ПИКСЕЛЯ (`:empty`) — ждать нечего, значит и места нет
   (канон `progressive-disclosure`). Коробка строки та же `.rail-item` — своих чисел
   размера нет (канон `control-size`).
   🔴 Акцент — формулой канона `accent`: подложка color-mix 12% + кольцо inset 22%, а НЕ
   левая рейка и не прибитый цвет: признак обязан читаться в обеих темах. */
.rail-more {
  position: relative; z-index: 2; flex: 0 0 auto;
  display: flex; flex-direction: column; align-items: stretch; gap: 6px;
  background-color: inherit;
}
.rail-more:empty { display: none; }
.rail-item.rail-pin {
  color: var(--text);
  background: color-mix(in srgb, var(--acc-fill) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--acc-fill) 22%, transparent);
}
.rail-item.rail-pin:hover { background: color-mix(in srgb, var(--acc-fill) 20%, transparent); }
/* 🔴 СВЕТЛАЯ ТЕМА НЕ СЪЕДАЕТ НАВЕДЕНИЕ. `html[data-theme="light"] .rail-item:hover` имеет
   вес (0,3,1) и перебивал наш (0,3,0) — на светлой тему признак терял акцент и падал в
   var(--hover) (ревью 04.10.2026). Канон `accent`: подложка остаётся формулой color-mix. */
html[data-theme="light"] .rail-item.rail-pin:hover { background: color-mix(in srgb, var(--acc-fill) 20%, transparent); }
.rail-item.rail-pin .rail-label { color: var(--text); }
.rail-item.rail-pin-rest .rail-ic svg.ic { width: 18px; height: 18px; }

.sidebar {
  background: var(--panel);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  min-height: 0;
  position: relative; /* якорь для .col-resizer на правой кромке */
}
.sidebar-head {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--head-h); flex: none;
  padding: 0 14px; border-bottom: 1px solid var(--line); font-weight: 600;
}
.conv-list { list-style: none; margin: 0; padding: 6px; }
/* Хэйрлайн, отделяющий «шапку» (поиск + истории + фильтр-табы) от прокручиваемого списка
   чатов. Стоит на верхе скролл-контейнера → всегда во всю ширину, не подтаивает маской табов
   и не зависит от того, показаны истории или нет. */
.sidebar-scroll { flex: 1; overflow-y: auto; min-height: 0; border-top: 1px solid var(--line); }

/* 🗄 АРХИВ (CLIE-372) — плашка входа как в Telegram: скрыта (высота 0), проявляется, когда
   пользователь тянет список ВНИЗ у самого верха (jest на .sidebar-scroll). Тап → раздел архива.
   Живёт НАД скроллом (между лентой фильтров и списком) — не мешает якорению прокрутки. */
.conv-arch-bar {
  height: var(--cab-h, 0px);
  overflow: hidden;
  display: flex; align-items: center; gap: 9px;
  padding: 0 14px; margin: 0;
  color: var(--text-dim); cursor: pointer; user-select: none;
  transition: height .16s cubic-bezier(.4, 0, .2, 1), background .12s;
}
.conv-arch-bar[hidden] { display: none; } /* архив пуст: убрать из потока (иначе .conv-arch-bar{display:flex} перебьёт UA [hidden]) */
.conv-arch-bar.revealed { --cab-h: 52px; border-bottom: 1px solid var(--line); }
.conv-arch-bar:hover { background: var(--hover); }
.conv-arch-bar .ic { width: 19px; height: 19px; flex: 0 0 auto; color: var(--text-dim); transition: color .12s; }
.conv-arch-bar .cab-t { font-weight: 600; font-size: 14px; color: var(--text); }
.conv-arch-bar .cab-n { font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.conv-arch-bar .cab-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); flex: 0 0 auto; }
.conv-arch-bar > .ic:last-child { margin-left: auto; width: 17px; height: 17px; opacity: .5; }
/* Порог оттяжки достигнут — подсветка «отпусти/тапни, чтобы открыть». */
.conv-arch-bar.ready { color: var(--accent); }
.conv-arch-bar.ready .cab-t { color: var(--accent); }
.conv-arch-bar.ready .ic { color: var(--accent); }

/* Компактная шапка раздела «Архив» вместо ленты фильтров (стрелка назад → к чатам). */
.conv-arch-head {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 5px 12px 8px; margin: 0; background: none; border: 0; cursor: pointer;
  color: var(--text); font: inherit; text-align: left; transition: color .12s;
}
.conv-arch-head:hover { color: var(--accent); }
.conv-arch-head .ic { width: 20px; height: 20px; flex: 0 0 auto; }
.conv-arch-head-t { font-weight: 700; font-size: 15px; }
.conv-arch-head-n { color: var(--muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.sidebar-subhead {
  padding: 10px 14px 4px; font-size: 11px; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
  border-top: 1px solid var(--line); margin-top: 6px;
}
/* Подзаголовок первым в теле окна («Папки чатов» → «Ваши папки»): кромку уже даёт шапка окна
   (.modal-head border-bottom), своя border-top рисовала вторую линию через 25 px (кадр: y=372 и y=397).
   Разделитель нужен только между секциями тела, у первой — ни кромки, ни внешнего отступа. */
.modal-body > .sidebar-subhead:first-child { border-top: 0; margin-top: 0; padding-top: 0; }
.conv-item {
  display: flex; align-items: center; gap: 11px; position: relative;
  padding: 9px 11px; border-radius: 12px; cursor: pointer; margin-bottom: 2px;
  border: 1px solid transparent; transition: background .12s, border-color .12s;
}
/* ── 🔴 Акцент статуса у чата задачи / «Чата с ИИ» — КОЛЬЦО-ПРОГРЕСС ВОКРУГ АВАТАРА.
   Цвет статуса — `--conv-accent`, длина дуги — `--arc` (оба ставит convRowHtml).

   История одной метки: полоса во всю высоту строки → точка 6px слева (CLIE-483, «слева
   полоски — твой фирменный паттерн») → CLIE-538: владелец посмотрел 10 вариантов и выбрал
   «В8 · кольцо-прогресс». Поэтому МЕТКИ СЛЕВА БОЛЬШЕ НЕТ ВООБЩЕ: строка чата задачи по
   геометрии равна обычной (padding как у всех), а статус живёт на аватаре и несёт БОЛЬШЕ,
   чем оттенок — видно, ДОКУДА задача дошла по воронке, а не «какой-то цвет, надо помнить».

   🔴 Дугу считает СЕРВЕР (`task_status_progress` = место столбца в воронке проекта/личной
   доски), клиент только рисует. Числа нет (личная задача без столбика зрителя) → падаем на
   грубую раскладку по КАТЕГОРИИ ниже; нет и её → остаётся одна дорожка, стадию не выдумываем.
   🔴 Полосы во всю высоту тут нет ни в каком виде — правило акцента (CLIE-483) соблюдено. ── */
.conv-item.tkc-conv, .conv-item.aic-item { padding-left: 11px; }
/* Раскладка по КАТЕГОРИИ — только фолбэк: инлайновый `--arc` с сервера (точная позиция в
   воронке) всегда перебивает эти правила, потому что инлайн-стиль сильнее таблицы стилей. */
.conv-item[data-tkcat="backlog"] { --arc: 8%; }
.conv-item[data-tkcat="unstarted"] { --arc: 22%; }
.conv-item[data-tkcat="started"] { --arc: 62%; }
.conv-item[data-tkcat="done"] { --arc: 100%; }
.conv-item[data-tkcat="cancelled"] { --arc: 0%; }
/* Кольцо: `::before` аватара, дуга — conic-gradient, «бублик» — радиальной маской.
   `:not(.has-story)` — у аватара с историей ::before уже занят её кольцом (личные чаты;
   у чата задачи истории не бывает, но гейт держим, чтобы кольца не подрались). */
.conv-item.tkc-conv .conv-av:not(.has-story)::before,
.conv-item.aic-item .conv-av:not(.has-story)::before {
  content: ""; position: absolute; inset: -6px; border-radius: 50%; pointer-events: none;
  background: conic-gradient(from -90deg,
    var(--conv-accent, #5DCAA5) 0 var(--arc, 0%),
    color-mix(in srgb, var(--conv-accent, #5DCAA5) 18%, transparent) var(--arc, 0%) 100%);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
  transition: opacity .15s ease;
}
/* Открытая беседа — то же кольцо, но с мягким ореолом: строка уже выделена подложкой,
   кольцу достаточно чуть «зажечься», а не менять форму. 🔴 Родную тень аватара
   (`0 4px 12px -4px var(--glow)`) НЕ теряем — дописываем ореол ВТОРЫМ слоем, иначе
   у открытого чата аватар «плющило» бы: тень исчезала бы вместе с объёмом. */
.conv-item.tkc-conv.active .conv-av:not(.has-story),
.conv-item.aic-item.active .conv-av:not(.has-story) {
  box-shadow: 0 4px 12px -4px var(--glow),
              0 0 12px -3px color-mix(in srgb, var(--conv-accent, #5DCAA5) 60%, transparent);
}
/* ── Строка ТИКЕТА (`.tk-item`, вкладка «Тикеты») — у неё акцент это ПРИОРИТЕТ, а не стадия
   воронки: кольцо-прогресс там читалось бы как «выполнено на N%». Поэтому у тикета остаётся
   прежняя точка 6px слева — она никогда не встречается со строками чатов в одном списке. ── */
.conv-item.tk-item[style*="--conv-accent"] { padding-left: 18px; }
.conv-item.tk-item[style*="--conv-accent"]::before {
  content: ""; position: absolute; left: 6px; top: 50%; transform: translateY(-50%);
  width: 6px; height: 6px; border-radius: 50%; background: var(--conv-accent, #5DCAA5);
  box-shadow: 0 0 7px -1px color-mix(in srgb, var(--conv-accent, #5DCAA5) 65%, transparent);
}

.conv-av {
  width: 42px; height: 42px; border-radius: 50%; flex: none;
  background: var(--acc-grad); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 15px;
  box-shadow: 0 4px 12px -4px var(--glow);
}
.conv-item-body { min-width: 0; flex: 1; }
/* онлайн-статус: зелёная точка на аватаре, когда собеседник 1-на-1 «в сети» */
.conv-av { position: relative; }
.conv-item.online .conv-av::after {
  content: ""; position: absolute; right: -1px; bottom: -1px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--ok); border: 2px solid var(--panel);
  box-shadow: 0 0 6px var(--ok);
}
/* ── CLIE-388: КРУПНЫЕ аватары в списке чатов (42→56px) — паритет с WhatsApp/Telegram
   (владелец: «нужны фотки больше размера в списке чатов»). Scoped к `#convList .conv-item`,
   чтобы бампнуть ТОЛЬКО строки списка (личные/группы/тикеты/чаты-задач/эфиры/поиск) и НЕ
   задеть аватар в форвард-модалке (#fwdList), тостах, мини-звонке (.vmini-av) и шапке
   (.thread-av) — там размер прежний. Строка тянется по высоте сама (align-items:center),
   фикс-высоты нет. Инициалы и онлайн-точка масштабируются пропорционально. ── */
#convList .conv-item { gap: 13px; }
#convList .conv-item .conv-av { width: 56px; height: 56px; font-size: 20px; }
#convList .conv-item.online .conv-av::after { width: 13px; height: 13px; }
/* фото/видео-аватар беседы в списке (постер видео = <url>.jpg) */
.conv-av.has-img { background-size: cover; background-position: center; color: transparent; }
/* 🔴🔴 CLIE-903 · ЛЕСТНИЦА КРУЖКА-АВАТАРА: буквы ЛЕЖАТ ПОД фото и остаются, если фото
   не пришло. Раньше ветка «есть url» рисовала ПУСТОЙ div с `background-image` — у него нет
   `onerror` в принципе, а `color: transparent` выше гасил бы буквы, даже если бы они были.
   Любой 404/403/обрыв (в списке из тысяч строк браузер отменяет загрузки сам) давал
   ПРОЗРАЧНЫЙ кружок без единого признака — это и есть «аватарка не отображается».
   Буквы носят СВОЙ цвет (`--av-ink`), поэтому гашение `color` на `.has-img` их не трогает;
   `<img>` ложится поверх и при ошибке снимает себя и класс `has-img` (см. ccAvatarFace). */
.cc-av-ini {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: var(--av-ink, #fff); border-radius: inherit; pointer-events: none;
}
.cc-av-img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  border-radius: inherit; display: block; pointer-events: none;
}
/* 🔴🔴 ЗНАК ЧУЖОГО БРЕНДА (CLIE-1396·р4, владелец 20.09.2026: «делать бренду свои, не чужие»).
   Дверь одна — `ccBrandMark(name)` в `app.js`; здесь только её вид, один раз на продукт.
   Кружок — ЧЕЛОВЕК (`.cc-av-ini` выше), плитка — СУЩНОСТЬ (канон иконки компании CLIE-621):
   у знака сервиса/приложения/сайта скруглённый квадрат, а не круг.
   🔴 Цвет — ТОЛЬКО наши токены; прибитых фирменных hex чужих брендов (зелёный WhatsApp,
   синий Telegram, красный YouTube, розовый Instagram …) здесь не бывает НИКОГДА.
   🔴 Чернила — `--primary-2`, а не `--primary` (канон contrast-runtime-audit: «акцентный
   ТЕКСТ на подложке — --primary-2»). Замер знака на СВОЁМ тинте 16%: --primary даёт 3.76
   (светлая, концепт 6) и 3.95 (тёмная) при AA 4.5 для кегля 10.5px; --primary-2 — 5.27 и
   5.51. В выбранном чипе знак заливается акцентом, и там белым — 4.70 / 4.85. */
.cc-bmark {
  width: 18px; height: 18px; border-radius: 6px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 800; line-height: 1; letter-spacing: .2px;
  background: color-mix(in srgb, var(--primary) 16%, transparent);
  color: var(--primary-2);
}
.conv-av .conv-av-vid {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  font-size: 11px; color: #fff; text-shadow: 0 1px 3px rgba(0,0,0,.65);
  pointer-events: none;
}
/* ── ВИДЕО-АВАТАР: играющий кружок вместо картинки. Единое правило для ВСЕХ мест показа
   аватара (список чатов, шапка, участники, поиск, реакции, задачи, клиенты, упоминания).
   `.av-vid` заполняет круглый контейнер точь-в-точь как background-image (cover), радиус
   наследует от родителя (круг/скруглённый квадрат). Постер `<url>.jpg` виден мгновенно —
   без сдвигов и мерцания. Тема-нейтрально (чёрный бэк под видео на время буфера). */
.av-vid {
  width: 100%; height: 100%; object-fit: cover; display: block;
  border-radius: inherit; background: #000; pointer-events: none;
}
/* Контейнеры аватара с видео: позиционирование + гашение фолбэка. НЕ ставим overflow:hidden
   на контейнер — иначе обрежется кольцо истории (::before с отрицательным inset). Клип по
   кругу делает сам `.av-vid` через border-radius:inherit + object-fit:cover (видео —
   replaced-элемент, его контент режется по скруглению без обрезки контейнера). */
.conv-av.has-video, .thread-av.has-video, .tw-av.has-video, .tp-av.has-video,
.mention-av.has-video, .cli-av.has-video, .cli-avs.has-video,
.rc-av.has-video, .gs-mem-av.has-video {
  position: relative; background-image: none; color: transparent;
}
/* Реакции: базовый .rc-av — <img> (18px круг). В видео-варианте это <span> с <video>. */
.rc-av.has-video { width: 18px; height: 18px; border-radius: 50%; }

/* ── 😴 Бейдж кастом-статуса / «Не беспокоить» на аватаре (правый-нижний угол). Сидит РЯДОМ с
   онлайн-точкой (та ::after справа-снизу; бейдж чуть выше/левее, чтобы не наезжать). Обведён
   цветом фона (--panel) — чёткий кружок поверх фото. Apple-grade: маленький, хэйрлайн-обводка,
   мягкая тень, крепится ОТДЕЛЬНЫМ узлом (hydrateStatusBadges), не ломая точку/кольцо истории. */
.conv-av, .thread-av, .who-av { position: relative; }
.cc-stbadge {
  position: absolute; right: -3px; bottom: -3px; z-index: 3;
  width: 18px; height: 18px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel); border: 2px solid var(--panel);
  box-shadow: 0 1px 3px rgba(0,0,0,.35), 0 0 0 1px var(--line);
  font-size: 11px; line-height: 1; pointer-events: none; overflow: hidden;
}
/* Явный цвет текста: аватар с фото имеет color:transparent — эмодзи-бейдж НЕ должен исчезать. */
.cc-stbadge-emoji { font-size: 11px; color: var(--text); }
.cc-stbadge-dnd { background: #5b6b8c; border-color: var(--panel); }
.cc-stbadge-dnd svg.ic { width: 11px; height: 11px; color: #fff; }
/* Крупные аватары списка чатов (56px) → чуть больше бейдж, чтобы читался. */
#convList .conv-item .cc-stbadge { width: 20px; height: 20px; font-size: 12px; right: -2px; bottom: -2px; }
#convList .conv-item .cc-stbadge-dnd svg.ic { width: 12px; height: 12px; }
/* Аватар профиля в шапке (26px): бейдж 18px у края закрывал инициалы — на кадре кружок x1119–1136
   лёг на буквы x1115–1125, «NI» читалось как «N». Меньше и наружу: 14px со сдвигом −5 — кружок
   (с кольцом r 8) отстоит от букв на 2px и остаётся на кромке аватара. */
.who .who-av .cc-stbadge { width: 14px; height: 14px; font-size: 9px; border-width: 1.5px; right: -5px; bottom: -5px; }
.who .who-av .cc-stbadge-dnd svg.ic { width: 9px; height: 9px; }
/* Если у собеседника И онлайн-точка, И бейдж — точку сдвигаем левее, чтобы не слипались. */
.conv-item.online .conv-av:has(.cc-stbadge)::after { right: 13px; }
/* Телефон: в #convList бейдж 20 px со сдвигом −2 (выше) — его край с кольцом --line в 19 px от правого
   края аватара, а точка (::after, content-box: 13 + кант 2·2 = 17 px) стояла на 13 px и заходила под
   бейдж на 5 px: домик срезал зелёную точку (кадр 390, «Ефакин Никита Бэк», обе темы). Точка — вплотную
   к кольцу бейджа: в ряд, не друг на друге; бейдж остаётся в углу. */
@media (max-width: 720px) {
  #convList .conv-item.online .conv-av:has(.cc-stbadge)::after { right: 19px; }
}
/* ── 📞 ЗВОН-696: ЖИВОЙ ЗВОНОК — не такой же значок, как статус, выставленный месяц назад.
   Состояние идёт ПРЯМО СЕЙЧАС и кончится само, поэтому у него тихое зелёное кольцо и
   медленное «дыхание». Без прыжков размера (соседи не должны ездить) и с уважением к
   «уменьшить движение»: там остаётся ровное кольцо без анимации. */
/* 🔴 14.10.2026 «грузит сильно»: «дыхание» было анимацией box-shadow — её композитор НЕ умеет,
   и одна такая метка держала ВСЮ страницу на 60 перерисовках в секунду на главном потоке
   (замер на проде, аккаунт владельца: 2 метки «на звонке» в списке — главный поток 27.7%
   против 12.3% без них, кадров 59.5/с против 8). Теперь кольцо — ОТДЕЛЬНЫЙ слой-псевдоэлемент,
   а дышит только его opacity: это композитор делает сам, главный поток не трогается.
   Вид тот же: ровное кольцо 1px всегда + внешний ореол до 3px на вдохе. */
.cc-stbadge-call {
  border-color: var(--ok, #22c55e);
  box-shadow: 0 1px 3px rgba(0,0,0,.35), 0 0 0 1px color-mix(in srgb, var(--ok, #22c55e) 55%, transparent);
  overflow: visible;                       /* ореол живёт ЗА кромкой метки; эмодзи 11–12px в круге 18–20px и так влезает */
}
.cc-stbadge-call::after {
  content: ""; position: absolute; inset: -2px; border-radius: 50%; pointer-events: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok, #22c55e) 26%, transparent);
  opacity: 0;
  animation: ccStBadgeCall 2.4s ease-in-out infinite;
}
@keyframes ccStBadgeCall { 0%, 100% { opacity: 0; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .cc-stbadge-call::after { animation: none; } }
/* 🔴 Человек на звонке ОЧЕВИДНО в сети — вторая зелёная точка вплотную к зелёному кольцу
   читается как шум (два одинаковых кружка, замер кадром на проде). Одно пятно смысла:
   пока горит «на звонке», онлайн-точку не рисуем. Во Flutter это уже так по построению —
   ветки бейджа там взаимоисключающие (user_avatar.dart). */
.conv-item.online .conv-av:has(.cc-stbadge-call)::after,
.thread-av:has(.cc-stbadge-call)::after,
.who-av:has(.cc-stbadge-call)::after { display: none; }
/* ── Кольцо ИСТОРИИ вокруг любого аватара (список чатов, шапка беседы, профиль). Instagram-градиент
   для непросмотренных, серое для просмотренных. Рисуем ::before (::after занят онлайн-точкой). ── */
.has-story { position: relative; }
.has-story::before {
  content: ""; position: absolute; inset: -5px; border-radius: 50%; padding: 2.5px;
  background: linear-gradient(135deg,#feda75,#d62976 45%,var(--cm-962fbf, #962fbf) 80%,var(--cm-4f5bd5, #4f5bd5));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude; pointer-events: none;
}
.has-story.seen::before { background: var(--line); }
.has-story.clickable { cursor: pointer; }
#convList .conv-av.has-story::before { inset: -3.5px; }
/* Компания — ЗОЛОТАЯ обводка (отличить от личной цветной). */
.has-story.company::before { background: linear-gradient(135deg,#ffd93b,#f6a821 60%,#e8850c); }
.has-story.company.seen::before { background: linear-gradient(135deg,#ffe08a,#e8a51c); }

/* ── Полоса ИСТОРИЙ вверху списка «Чаты» — ВСЕГДА на виду (Telegram/WhatsApp Status). ── */
/* Истории теперь САМЫМ ВЕРХОМ (над фильтр-табами) — разделитель-хэйрлайн больше НЕ здесь,
   он опущен на низ всей «шапки» (.conv-tabs), чтобы истории и табы читались одним блоком, а
   единственная линия отделяла шапку от списка чатов. */
.chat-stories { padding: 10px 12px 12px; transition: padding .18s var(--ease-standard, ease); }
.chat-stories[hidden], .chat-stories:empty { display: none; }
.chat-stories .cs-full { display: flex; gap: 12px; overflow-x: auto; scrollbar-width: none; }
.chat-stories .cs-full::-webkit-scrollbar { display: none; }
/* Мини-кластер (перекрытые аватары) — виден при свёрнутом состоянии (скролл вниз). */
.chat-stories .cs-mini { display: none; align-items: center; cursor: pointer; padding: 1px 2px; }
.cs-mini-av { width: 30px; height: 30px; border-radius: 50%; padding: 2px; background: linear-gradient(135deg,#feda75,#d62976 45%,var(--cm-962fbf, #962fbf) 80%,var(--cm-4f5bd5, #4f5bd5)); display: inline-flex; flex: 0 0 auto; }
.cs-mini-av.company { background: linear-gradient(135deg,#ffd93b,#f6a821 60%,#e8850c); }
.cs-mini-av .feed-av { width: 100% !important; height: 100% !important; border: 2px solid var(--panel); border-radius: 50% !important; overflow: hidden; }
.cs-mini-lbl { font-size: 12.5px; font-weight: 600; color: var(--text); margin-left: 8px; }
.chat-stories.collapsed { padding: 6px 12px; }
.chat-stories.collapsed .cs-full { display: none; }
.chat-stories.collapsed .cs-mini { display: flex; }
.cs-item { flex: 0 0 auto; width: 62px; text-align: center; cursor: pointer; }
.cs-ring { position: relative; width: 58px; height: 58px; margin: 0 auto; border-radius: 50%; padding: 2.5px; background: var(--line); display: flex; align-items: center; justify-content: center; }
.cs-item.unseen .cs-ring { background: linear-gradient(135deg,#feda75,#d62976 45%,var(--cm-962fbf, #962fbf) 80%,var(--cm-4f5bd5, #4f5bd5)); }
.cs-item.company.unseen .cs-ring { background: linear-gradient(135deg,#ffd93b,#f6a821 60%,#e8850c); }
.cs-item.company .cs-ring { background: linear-gradient(135deg,#ffe08a,#e8a51c); }
/* Только сам аватар заполняет кольцо; «+»-бейдж (.cs-add) НЕ трогаем (иначе он раздувался на весь круг). */
.cs-ring > :not(.cs-add) { width: 100% !important; height: 100% !important; border: 2.5px solid var(--panel); border-radius: 50% !important; overflow: hidden; box-sizing: border-box; }
.cs-ring img { width: 100%; height: 100%; object-fit: cover; }
.cs-add { box-sizing: border-box; padding: 0; position: absolute; right: -3px; bottom: -3px; z-index: 3; width: 22px; height: 22px; border-radius: 50%; background: var(--acc-fill); color: #fff; border: 2.5px solid var(--panel); display: flex; align-items: center; justify-content: center; font-size: 15px; font-weight: 700; line-height: 1; box-shadow: 0 1px 4px rgba(0,0,0,.3); }
.cs-item .cs-add { transition: transform var(--motion-fast, 120ms) var(--ease-standard, ease); }
.cs-item .cs-add:hover { transform: scale(1.12); }
/* Насечки-сегменты поверх кольца (по числу сториз) — над аватаром, под «+». Тот же приём
   в дорожке страницы «Лента» (.feed-story .ring) — паритет со списком «Чаты». */
.cs-ring .cs-seg, .feed-story .ring .cs-seg { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2; }
.cs-name { margin-top: 5px; font-size: 11px; color: var(--textSecondary, var(--cm-9aa0b4, #9aa0b4)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cs-item.me .cs-name { color: var(--text); font-weight: 600; }
/* Телефон: своя плитка подписана в две строки, как «Ваша история» в «Ленте» (.feed-story.me .st-name,
   app.js) — в одну строку в плитке 62 px было «Ваша ист…» (кадр 390, обе темы). Не больше двух
   строк; высота строки 1.2 — хвост «р» под обрезкой второй строки не срезается. */
@media (max-width: 720px) {
  .cs-item.me .cs-name { white-space: normal; line-height: 1.2; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
}
.conv-item:hover { background: var(--panel-2); }
.conv-item.active {
  background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 22%, transparent), color-mix(in srgb, var(--primary) 16%, transparent));
  border-color: var(--cm-7c74dc-35, rgba(124,116,220,.35));
  box-shadow: 0 4px 14px -6px var(--glow);
}
/* 🔴 «Контрастность» 10.09.2026: имя беседы — акцентные ЧЕРНИЛА, значит --primary-2
   (замер прода: --primary давал 4.23:1 на тёплом холсте при AA 4.5, стало 5.55:1). */
.conv-name { font-weight: 600; }
.conv-item.active .conv-name, .conv-item .conv-name.accent { color: var(--primary-2, var(--primary)); }

/* ── 0189 · РУЧНОЙ ПОРЯДОК ЗАКРЕПЛЁННЫХ ЧАТОВ (drag-and-drop) ─────────────────────────────
   Владелец: «нужен дрег енд дроп на закреплённые чаты». Ни одного НОВОГО элемента на экране:
   грип — та самая скрепка 📌, что и так стоит ровно у закреплённых. Мышью тянется вся строка
   (курсор-хват появляется ТОЛЬКО на наведении и только у закреплённых — экран не отбираем).
   Визуал драга — ровно как у карточек «Моих задач» (.tw-lift/.tw-reordering): один язык жеста. */
@media (hover: hover) and (pointer: fine) {
  #convList .conv-item.pinned { cursor: grab; }
  #convList .conv-item.pinned:active { cursor: grabbing; }
}
/* Скрепка = хваталка порядка. На тач тянут именно за неё → снимаем с неё браузерный
   скролл-жест (touch-action) и расширяем область попадания невидимыми полями (HIG: цель
   пальца больше иконки), не меняя визуальный размер и не сдвигая соседние метки. */
#convList .conv-item.pinned .conv-pin-ic {
  cursor: grab; touch-action: none; position: relative;
  padding: 8px 4px; margin: -8px -4px;
  transition: opacity .14s ease, transform .14s ease;
}
#convList .conv-item.pinned .conv-pin-ic:hover { opacity: 1; transform: scale(1.12); }
#convList .conv-item.pinned .conv-pin-ic:active { cursor: grabbing; transform: scale(.96); }
/* Пока идёт перестановка: хват-курсор на всём списке, без выделения текста и без
   браузерного скролла (тач ведёт строку, а не полотно). */
#convList.conv-reordering { cursor: grabbing; user-select: none; -webkit-user-select: none; touch-action: none; }
/* Тянущаяся строка — приподнята над остальными, мягкая «яблочная» тень, hover соседей погашен. */
#convList.conv-reordering .conv-item:hover { background-color: transparent; }
/* background-COLOR (а не background): у открытого чата подсветка `.active` — это
   background-IMAGE (градиент), и она остаётся видна поверх заливки. Иначе тянущийся
   активный чат терял бы выделение на время жеста. */
#convList .conv-item.conv-lift {
  z-index: 30; background-color: var(--panel-2);
  border-color: var(--line);
  box-shadow: 0 14px 34px rgba(0,0,0,.34), 0 2px 8px rgba(0,0,0,.20);
}
html[data-theme="light"] #convList .conv-item.conv-lift {
  background-color: #fff;
  box-shadow: 0 14px 34px rgba(0,0,0,.16), 0 2px 8px rgba(0,0,0,.10);
}
#convList.conv-reordering .conv-item.conv-lift:hover { background-color: var(--panel-2); }
html[data-theme="light"] #convList.conv-reordering .conv-item.conv-lift:hover { background-color: #fff; }
@media (prefers-reduced-motion: reduce) {
  #convList .conv-item.pinned .conv-pin-ic { transition: none !important; }
}
/* .logout (кнопка внизу сайдбара) удалена — «Выйти» переехала в Настройки → Профиль (pf-logout-btn) */

/* кнопка-📌 на строке чата: видна на hover/закреплённых, не мешает клику по чату */
.conv-pin-mark { margin-right: 4px; font-size: 12px; opacity: .9; }
.conv-pin-btn, .contact-pin-btn {
  flex: none; border: none; background: transparent; cursor: pointer;
  font-size: 14px; line-height: 1; padding: 4px; border-radius: 8px;
  opacity: 0; filter: grayscale(1); transition: opacity .12s, filter .12s, background .12s;
}
.conv-item:hover .conv-pin-btn,
.contact-row:hover .contact-pin-btn { opacity: .55; }
.conv-pin-btn.on, .contact-pin-btn.on { opacity: 1; filter: none; }
.conv-pin-btn:hover, .contact-pin-btn:hover { opacity: 1; filter: none; background: var(--panel-2); }
/* булавка строки контакта — svgIcon("pin") (база `button svg.ic` дала бы 22 px — крупнее «Написать» 18 px);
   закреплённый — акцентные чернила вместо красного эмодзи */
.contact-pin-btn svg.ic { width: 18px; height: 18px; }
.contact-pin-btn.on { color: var(--primary-2); }

/* ---- мои контакты (телефонная книга) ---- */
/* ---- колонка «Мои задачи» (на месте бывших контактов) ------------------- */
.tasks-col {
  background: var(--panel);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column; min-height: 0;
  position: relative; /* якорь для .col-resizer на правой кромке */
}
.tasks-head {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--head-h); flex: none;
  padding: 0 14px; border-bottom: 1px solid var(--line); font-weight: 600;
}
.tasks-head-actions { display: flex; gap: 6px; }
.tasks-list { list-style: none; margin: 0; padding: 6px; overflow-y: auto; flex: 1; min-height: 0; }
.tasks-empty { padding: 14px; line-height: 1.4; }
/* Хвост окна столбика (CLIE-685·5): окно растёт САМО при подходе к низу, эта строка — вход для
   тех, кто листает рывком/клавиатурой, и честный ответ «сколько уже показано из скольких».
   Не «кап» (CLIE-620): под ней ничего не спрятано, счётчики секций считают ВСЕ задачи.
   Размеры кнопки — общие токены ряда (--ctl-h/--ctl-r/--ctl-fs), своих чисел не заводим. */
.tasks-more {
  list-style: none; display: flex; align-items: center; gap: 10px;
  padding: 10px 8px 16px; justify-content: center; flex-wrap: wrap;
}
.tasks-more-btn {
  height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs);
  padding: 0 14px; border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  cursor: pointer; transition: background .14s ease, border-color .14s ease;
}
.tasks-more-btn:hover { background: var(--panel); }
.tasks-more-n { white-space: nowrap; }
/* 💤 Строка «Ещё N тихих чатов задач и ИИ — без движения D+ дн.» длиннее узкой колонки чатов
   (замер 16.10.2026: 346 px текста в строке 267 px — начало и конец срезались): переносится и
   центрируется, а не режется. */
.conv-dorm .tasks-more-n { white-space: normal; text-align: center; max-width: 100%; }
/* 🔴 Хвост окна В ТЕЛЕ СТОЛБЦА ДОСКИ (CLIE-1769). `.tw-col-body` — flex-колонка, а у flex-
   элемента по умолчанию `flex-shrink: 1`: без `flex: none` хвост сжимался бы в полоску ровно
   так же, как сжимались карточки под `content-visibility` (замер того же столбца: 31 566px
   вместо 227 586px). Отступ сверху — чтобы строка не липла к последней карточке. */
.tw-col-body > .tasks-more.tw-col-more { flex: none; padding: 6px 2px 10px; gap: 8px; }
/* Подвал страницы канона: та же форма «Показать ещё · Показано N из M», что у задач
   (одна реализация), плюс отбивка от последней карточки. Токены обеих тем — общие. */
.kn-canon-more { margin-top: 6px; border-top: 1px solid var(--line); }

/* ---- колонка «Проекты» (слева от задач): фильтр столбика «Мои задачи» по проекту ----
   «Все проекты» вверху = без фильтра; выбор проекта = только его задачи; «Без проекта» =
   задачи вне проектов. Счётчики — из state.tasks (renderProjectsRail), живут в реалтайме. */
.projects-col {
  background: var(--panel);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column; min-height: 0;
  position: relative; /* якорь для .col-resizer на правой кромке */
  /* ⏳ CLIE-591: столбец — КОНТЕЙНЕР для запросов по ЕГО ширине (рельс тянется мышью, поэтому
     медиазапрос по окну тут бесполезен). Отметка «ждёт ответа» на узком рельсе ужимается,
     чтобы не съедать имя проекта (см. @container projrail ниже). */
  container: projrail / inline-size;
}
.projects-head {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--head-h); flex: none;
  padding: 0 14px; border-bottom: 1px solid var(--line); font-weight: 600;
}
.projects-head-actions { display: flex; gap: 6px; }
.projects-list { list-style: none; margin: 0; padding: 6px; overflow-y: auto; flex: 1; min-height: 0; }
.projects-empty { padding: 14px 12px; line-height: 1.45; color: var(--muted); font-size: 12.5px; }
/* 🔴 CLIE-631 (правило выхода): пустой под фильтром рельс НАЗЫВАЕТ причину и даёт кнопку выхода
   рядом — «сузил и забыл» не должен читаться как «всё пропало». */
.projects-empty .proj-flreset { display: block; margin-top: 9px; }
.projects-sep { height: 1px; background: var(--line); margin: 6px 8px; }

/* Заголовки секций рельса «Проекты» по этапам воронки (0176) — эталон .task-section-title
   столбика «Мои задачи»: цветная точка этапа + КАПС-подпись + счётчик, клик — свернуть. */
.projects-list .proj-section-title {
  list-style: none; padding: 12px 8px 5px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted);
  display: flex; align-items: center; gap: 7px;
  cursor: pointer; user-select: none; border-radius: 8px;
  transition: background .12s ease;
}
.projects-list .proj-section-title:hover { background: color-mix(in srgb, var(--panel-2) 60%, transparent); }
.projects-list .proj-section-title .psec-caret {
  display: inline-flex; width: 12px; height: 12px; flex: none; opacity: .55; transition: transform .14s ease;
}
.projects-list .proj-section-title .psec-caret svg { width: 12px; height: 12px; }
.projects-list .proj-section-title.collapsed .psec-caret { transform: rotate(-90deg); }
.projects-list .proj-section-title .psec-swatch {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 16%, transparent);
}
.projects-list .proj-section-title .psec-lbl { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.projects-list .proj-section-title .psec-n { flex: none; font-variant-numeric: tabular-nums; opacity: .6; font-weight: 600; }
/* 🏢 CLIE-490 — заголовок КОМПАНИИ тянется мышью (личный порядок компаний). Хваталки-иконки нет:
   тянется сам заголовок, курсор объясняет жест (как перетаскивание списков в Reminders). */
.projects-list .proj-section-title[data-co] { cursor: grab; }
.projects-list .proj-section-title[data-co]:active { cursor: grabbing; }
.projects-list .proj-section-title[data-co].dragging {
  opacity: .55; background: color-mix(in srgb, var(--panel-2) 82%, transparent);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .18); cursor: grabbing;
}
/* Пока тащим компанию — соседние заголовки не «мигают» ховером под курсором.
   🔴 pointer-events у строк НЕ гасим: dragover целится в заголовок ЧЕРЕЗ строку под курсором,
   иначе длинную компанию не перепрыгнуть (над её строками цели бы не было). */
.projects-list.co-reordering .proj-section-title:not(.dragging) { background: transparent; }

.proj-item {
  position: relative; /* якорь для .proj-qacts (пилюля быстрых действий справа) */
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: 11px; cursor: pointer; margin-bottom: 2px;
  border: 1px solid transparent; color: var(--text);
  transition: background .12s, border-color .12s, box-shadow .12s;
}
.proj-item:hover { background: var(--panel-2); }
.proj-item.active {
  background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 22%, transparent), color-mix(in srgb, var(--primary) 16%, transparent));
  border-color: var(--cm-7c74dc-35, rgba(124,116,220,.35));
  box-shadow: 0 4px 14px -6px var(--glow);
}
/* цветная «монета» проекта (буква/иконка) */
.proj-dot {
  width: 26px; height: 26px; border-radius: 8px; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 700; color: #fff; line-height: 1;
  background: var(--acc-grad);
  box-shadow: 0 3px 10px -5px var(--glow);
  overflow: hidden;
}
.proj-dot svg { width: 15px; height: 15px; }
.proj-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.proj-count {
  flex: none; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px;
  background: var(--panel-2); color: var(--muted);
  font-size: 11px; font-weight: 700; line-height: 20px; text-align: center;
}
/* активная строка: счётчик читаемым в ОБЕИХ темах (белый на светлой теме пропадал) */
.proj-item.active .proj-count { background: var(--panel-2); color: var(--text); }
/* «Все проекты» — фирменная строка-иконка; «Без проекта» — приглушённая пунктирная */
.proj-item.all .proj-dot { background: linear-gradient(135deg, #5b8def, var(--cm-7c74dc, #7c74dc)); }
.proj-item.none .proj-dot { background: transparent; color: var(--muted); box-shadow: none; border: 1px dashed var(--line); }
/* Архивный проект в рельсе: приглушён + пометка «архив» (задачи тоже в архиве; вернуть через ✎). */
.proj-item.archived { opacity: .5; }

/* Плашка активного фильтра по проекту над списком чатов (0099) УБРАНА по требованию владельца:
   проект уже подсвечен в рельсе «Проекты», дублирующий индикатор над «Историями» лишний и
   создавал пустое пространство. Сужение списка по проекту работает как прежде (без плашки). */
.proj-item.archived:hover { opacity: .75; }
/* 🧩 CLIE-1050 — проект НЕ в рабочем пространстве (заведён из CRM и ещё не взят в работу).
   Не прячем (невидимых записей не бывает) и не глушим до нечитаемости: приглушаем чуть
   слабее архива и называем словом (подпись `.proj-ghost-in` рисует сам рельс). */
.proj-item.notwork { opacity: .68; }
.proj-item.notwork:hover, .proj-item.notwork.active { opacity: 1; }
/* Drag-перестановка проектов = ручной приоритет (position/0075). Курсор-«захват», плавный сдвиг
   соседей, приподнятая полупрозрачная строка под курсором — как перетаскивание в Finder/Reminders. */
.proj-item[draggable="true"] { cursor: grab; }
.proj-item[draggable="true"]:active { cursor: grabbing; }
.projects-list.reordering .proj-item[draggable="true"] { transition: transform .14s cubic-bezier(.2,.7,.3,1), background .12s, border-color .12s, box-shadow .12s; }
.proj-item.dragging {
  opacity: .6; cursor: grabbing;
  background: var(--panel-2);
  border-color: var(--cm-7c74dc-35, rgba(124,116,220,.35));
  box-shadow: 0 10px 24px -10px var(--glow);
}
.proj-item.archived .proj-name::after { content: " · архив"; color: var(--muted); font-size: 10px; font-weight: 600; }

/* быстрые действия строки проекта: пилюля справа, всплывает по наведению (перекрывает счётчик,
   как на карточках доски .tw-qacts). «Перейти в задачи» / «Новая задача» / «Изменить». */
.proj-qacts {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; gap: 1px; padding: 2px;
  border-radius: 9px; background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 3px 12px rgba(0,0,0,.28);
  opacity: 0; pointer-events: none; transition: opacity .12s;
}
.proj-item:hover .proj-qacts { opacity: 1; pointer-events: auto; }

/* ═══ ПОДПРОЕКТЫ в рельсе «Проекты» (0184, CLIE-412) ═══════════════════════════════════
   Подпроект = часть общего дела (ЕТТИ → мобилка / сайт / 1С). Рисуем как раскрытие в
   Finder/Reminders: тонкий «локоть»-хэйрлайн от родителя к ребёнку + отступ уровня, шеврон
   ветки в левом жёлобе. 🔴 Жёлоб появляется ТОЛЬКО когда иерархия реально есть (класс
   .has-tree ставит renderProjectsRail) — у тенанта без подпроектов рельс пиксель-в-пиксель
   прежний, экран у пользователя не отбираем. Шаг уровня 14px — читаемо и не съедает имя. */
.projects-list.has-tree .proj-item { padding-left: 24px; }
.projects-list.has-tree .proj-item.sub { padding-left: calc(24px + var(--pdepth, 1) * 14px); }
/* «локоть»: вертикаль от родителя + скругление к строке ребёнка */
.projects-list .proj-item.sub::before {
  content: ""; position: absolute; pointer-events: none;
  left: calc(11px + (var(--pdepth, 1) - 1) * 14px);
  top: -3px; height: calc(50% + 3px); width: 9px;
  border-left: 1px solid var(--line); border-bottom: 1px solid var(--line);
  border-bottom-left-radius: 7px; opacity: .8;
}
/* CLIE-627: у НЕ-последнего ребёнка направляющая идёт дальше вниз — линия ветки читается сплошной,
   а не пунктиром из отдельных «локтей». 1px-направляющая дерева, а НЕ акцент-рейка (CLIE-483). */
.projects-list .proj-item.sub:not(.sub-last)::after {
  content: ""; position: absolute; pointer-events: none;
  left: calc(11px + (var(--pdepth, 1) - 1) * 14px);
  top: 50%; bottom: -3px; width: 1px; background: var(--line); opacity: .8;
}
/* шеврон ветки: в жёлобе, не сдвигает содержимое строки (у соседей без детей — ровно) */
.proj-branch {
  position: absolute; left: calc(3px + var(--pdepth, 0) * 14px); top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; padding: 0; border: 0; border-radius: 6px;
  display: flex; align-items: center; justify-content: center;
  background: transparent; color: var(--muted); cursor: pointer;
  transition: background .12s, color .12s, transform .14s cubic-bezier(.2,.7,.3,1);
}
.proj-branch svg { width: 12px; height: 12px; }
.proj-branch:hover { background: var(--panel-2); color: var(--text); }
.proj-branch.collapsed { transform: translateY(-50%) rotate(-90deg); }
/* ═══ ЯКОРЬ ВЕТКИ (CLIE-627) ═══════════════════════════════════════════════════════════
   Родитель почти всегда лежит в ДРУГОЙ секции, чем его подпроекты (он «сейчас», они «в
   бэклоге»). Раньше ребёнок оставался корнем секции с немым глифом «↳», и дети одного
   родителя расползались по списку между чужими проектами — это и есть «бардак». Теперь
   ветка собирается под тихой строкой-якорем: то же имя, тот же цвет монеты, но это НЕ
   проект этой секции — поэтому у него нет счётчика, нет быстрых действий, он не тянется
   и не принимает выделение. Читается как заголовок ветки, а не как ещё один проект.
   🔴 Никаких вертикальных полос-акцентов (CLIE-483): связь несёт тот же 1px «локоть»
   .proj-item.sub::before, что и у обычного дерева — второй визуальный язык не заводим. */
.proj-item.ghost { color: var(--muted); cursor: pointer; }
.proj-item.ghost .proj-name { font-weight: 500; }
.proj-item.ghost .proj-dot { opacity: .62; transform: scale(.86); transform-origin: center; }
.proj-item.ghost:hover { color: var(--text); }
.proj-item.ghost:hover .proj-dot { opacity: 1; }
/* «· в «Сейчас»» — в каком блоке живёт сам родитель. Лежит ВНУТРИ .proj-name, поэтому на узком
   рельсе уезжает под то же отточие, что и имя: имя важнее подписи, огрызка «в «…»» не бывает. */
.proj-ghost-in { color: var(--muted); font-size: 11.5px; opacity: .75; font-weight: 400; }
/* сколько подпроектов спрятано под свёрнутой веткой */
.proj-subn {
  flex: none; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: transparent; border: 1px solid var(--line); color: var(--muted);
  font-size: 10px; font-weight: 700; line-height: 16px; text-align: center;
}
/* подпись-подсказка и правый суб-текст в поповерах (родитель/группа в меню строки) */
.tc-pop-hint { padding: 2px 8px 8px; color: var(--muted); font-size: 11.5px; line-height: 1.35; }
.tc-pop-sub { flex: none; max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: 11px; }

/* 🔴 ЖИВОЙ ИНДИКАТОР ТАЙМЕРА — ЕДИНАЯ реализация для рельса «Проекты» (renderProjectsRail →
   .proj-coin-wrap) и каталога проектов (v2ProjCoin → .v2-pc-coinwrap). Пульсирующая точка на
   «монете» проекта, когда внутри есть задача с идущим ПРЯМО СЕЙЧАС учётом времени. Цвет — та же
   семья, что бейдж таймера .tw-pill-timer (var(--info)); мягкое расходящееся кольцо читается как
   «живое», в духе индикатора записи/присутствия у Apple. Точка — сиблинг монеты в обёртке (не её
   потомок), поэтому overflow:hidden монеты её не режет, а угол не обрезается строкой/карточкой. */
.proj-coin-wrap, .v2-pc-coinwrap { position: relative; display: inline-flex; flex: none; }
.cc-timer-pip {
  position: absolute; right: -3px; bottom: -3px; z-index: 1;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--info);
  border: 2px solid var(--panel);   /* «вырез» вокруг точки — отделяет её от монеты и фона */
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--info) 55%, transparent);
  pointer-events: none;             /* тултип берёт обёртка; клик проходит к строке/карточке */
  animation: ccTimerPip 1.8s cubic-bezier(.4, 0, .2, 1) infinite;
}
@keyframes ccTimerPip {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--info) 55%, transparent); }
  70%  { box-shadow: 0 0 0 7px color-mix(in srgb, var(--info) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--info) 0%, transparent); }
}

/* ═══ ⏳ CLIE-591 → CLIE-631 — «ЖДЁТ ОТВЕТА» НА СТРОКЕ ПРОЕКТА ═══════════════════════════
   Владелец: «если в проектах есть задачи, которые ждут ответа, нужно тут это отобразить
   дизайном». Витрину из пяти скинов показали, вариант выбрали — и переключатель УБРАН
   (CLIE-631: «а там первый вариант у всех и выбор не нужен»). Вид ОДИН: янтарная пилюля
   ⏳N у счётчика. Разметка — .proj-item.is-await + .proj-await. Второго вида не заводить:
   вернувшийся data-awstyle ловит сторож design_lint (блок LISTCFG_MECH).
   Цвет — семейство «внимание» (--warning), как у пилюли «⏳ ИИ ждёт ответа» на карточке
   задачи: рельс и карточка говорят одним языком.
   🔴 Левых полосок-реек тут нет и не будет (правило CLIE-483): акцент несут иконка+число. */
/* Отрицательный margin съедает половину общего gap:10px строки: отметка стоит ВПЛОТНУЮ к
   счётчику (это одна информационная группа «справа»), а не отбирает ещё 10px у имени. */
.proj-await {
  flex: none; font-variant-numeric: tabular-nums; margin-right: -4px;
  display: inline-flex; align-items: center; gap: 3px;
  height: 20px; padding: 0 7px 0 5px; border-radius: 10px;
  background: var(--warning-soft); color: var(--warning-ink, var(--warning));
  border: 1px solid color-mix(in srgb, var(--warning) 30%, transparent);
  font-size: 11px; font-weight: 700; line-height: 1;
}
.proj-await .ic { width: 11px; height: 11px; }

/* 🔴 УЗКИЙ РЕЛЬС (дефолтная ширина 200px, а с деревом подпроектов ещё -14px): имя проекта
   ВАЖНЕЕ иконки. Пруф на живом проде показал «Курьерское приложение» ужатым до «К.» — поэтому
   на узком рельсе в отметке остаётся ТОЛЬКО число (смысл несут янтарь и подсказка строки),
   а на широком возвращается иконка-часы. Запрос по ширине СТОЛБЦА, а не окна: рельс тянется
   мышью, и окно про его ширину ничего не знает. */
@container projrail (max-width: 268px) {
  .proj-await .ic { display: none; }
  .proj-await { padding: 0 6px; }
  /* CLIE-627: на узком рельсе подпись «в каком блоке родитель» УХОДИТ ЦЕЛИКОМ, а не превращается
     в огрызок «· Се…». Имя родителя важнее подписи; полное «ЛюблюЕду · Сейчас» вернётся, как
     только рельс растянут мышью. Тот же контейнер, что у отметки «ждёт ответа» — второго
     механизма «узкий рельс» не заводим. */
  .proj-ghost-in { display: none; }
}

@media (prefers-reduced-motion: reduce) { .cc-timer-pip { animation: none; } }

.proj-qa {
  width: 26px; height: 26px; flex: none; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: transparent; border-radius: 7px;
  color: var(--muted); cursor: pointer; transition: background .12s, color .12s;
}
.proj-qa:hover { background: var(--panel-2); color: var(--text); }
.proj-qa .ic { width: 15px; height: 15px; }

/* секции: этапы (Бэклог/К выполнению/В работе/На проверке/Готово) · срок · проект */
.tasks-list .task-section-title {
  list-style: none; padding: 12px 10px 5px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--muted);
  display: flex; align-items: center; gap: 7px;
}
.tasks-list .task-section-title[data-group] { cursor: pointer; user-select: none; border-radius: 8px; transition: background .12s ease; }
.tasks-list .task-section-title[data-group]:hover { background: color-mix(in srgb, var(--panel-2) 60%, transparent); }
.tasks-list .task-section-title .ic { width: 14px; height: 14px; flex: none; }
.tasks-list .task-section-title .tsec-lbl { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tasks-list .task-section-title .tsec-n { flex: none; font-variant-numeric: tabular-nums; }
/* каретка сворачивания: вниз = раскрыто, вправо (−90°) = свёрнуто */
.tasks-list .task-section-title .tsec-caret { display: inline-flex; width: 12px; height: 12px; flex: none; opacity: .6; transition: transform .14s ease; }
.tasks-list .task-section-title .tsec-caret .ic { width: 12px; height: 12px; }
.tasks-list .task-section-title.collapsed .tsec-caret { transform: rotate(-90deg); }
.tasks-list .task-section-title .tsec-swatch { width: 9px; height: 9px; border-radius: 50%; flex: none; box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 18%, transparent); }
.tasks-list .task-section-title:first-child { padding-top: 6px; }
/* «Идёт таймер» — одна семья с бейджем таймера (.task-chip.wip / .tw-pill-timer): тот же
   var(--info) и тот же мягкий пульс на иконке. Заливки строки НЕТ — только цвет и хэйрлайн. */
.tasks-list .tst-running { color: var(--info); }
.tasks-list .tst-running svg.ic { animation: wipPulse 1.8s ease-in-out infinite; }
.tasks-list .tst-backlog { color: #8b93a3; }
.tasks-list .tst-todo    { color: var(--primary-2); }
.tasks-list .tst-wip     { color: var(--info); }
.tasks-list .tst-test    { color: #d08b1f; }
.tasks-list .tst-project { color: var(--text); }
.tasks-list .tst-overdue { color: var(--urg-overdue-ink); }
.tasks-list .tst-today   { color: var(--urg-today); }
.tasks-list .tst-soon    { color: var(--primary-2); }
.tasks-list .tst-none    { color: #6B7280; }
.tasks-list .tst-done    { color: var(--urg-done); }
.tasks-list .tst-cancelled { color: #8b93a3; }

/* ── Панель управления столбиком «Мои задачи» (группировка · сортировка · этапы) ── */
.tasks-list .task-ctrlbar { list-style: none; display: flex; align-items: center; gap: 6px; padding: 2px 4px 8px; }
.tasks-list .tcol-btn {
  display: inline-flex; align-items: center; gap: 5px; min-width: 0;
  padding: 5px 8px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--panel); color: var(--text-2, var(--text)); font-size: 12px; font-weight: 600;
  cursor: pointer; transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.tasks-list .tcol-btn:first-child { flex: 1 1 auto; }
.tasks-list .tcol-btn:hover { background: var(--panel-2); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.tasks-list .tcol-btn .ic { width: 14px; height: 14px; flex: none; opacity: .75; }
.tasks-list .tcol-btn .ic:last-child { width: 12px; height: 12px; opacity: .5; margin-left: auto; }
.tasks-list .tcol-btn-lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tasks-list .tcol-sortglyph { font-size: 13px; font-weight: 800; opacity: .7; line-height: 1; }
.tasks-list .tcol-gear {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 28px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--panel); color: var(--muted); cursor: pointer; transition: all .12s ease;
}
.tasks-list .tcol-gear:hover { background: var(--panel-2); color: var(--primary-2); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.tasks-list .tcol-gear .ic { width: 15px; height: 15px; }
/* ── Панель управления рельсом «Проекты» (0176): группировка · сортировка — эталон .tcol-btn
      столбика «Мои задачи», но в контексте .projects-list. Обе темы наследуются от переменных. ── */
/* 🎚 CLIE-631: кнопок в панели стало три (группировка · ⏱ · ⚙ сортировка-фильтры) — отступы
   ужаты ровно настолько, чтобы САМАЯ ДЛИННАЯ подпись группировки («По воронке») влезала целиком
   при дефолтной ширине рельса 200px. Замер стенда: было 68/62 (обрезка), стало влезает. */
.projects-list .task-ctrlbar { list-style: none; display: flex; align-items: center; gap: 4px; padding: 2px 2px 8px; }
.projects-list .tcol-btn {
  display: inline-flex; align-items: center; gap: 4px; min-width: 0;
  padding: 5px 7px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--panel); color: var(--text-2, var(--text)); font-size: 12px; font-weight: 600;
  cursor: pointer; transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.projects-list .tcol-btn:first-child { flex: 1 1 auto; }
.projects-list .tcol-btn:hover { background: var(--panel-2); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.projects-list .tcol-btn .ic { width: 13px; height: 13px; flex: none; opacity: .75; }
.projects-list .tcol-btn .ic:last-child { width: 12px; height: 12px; opacity: .5; margin-left: auto; }
.projects-list .tcol-btn-lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.projects-list .tcol-sortglyph { font-size: 13px; font-weight: 800; opacity: .7; line-height: 1; }
/* Компактные кнопки рельса (↕ сортировка, ⚙️ этапы воронки): узкий столбик → группировка на всю
   ширину, вторичные — иконками (как компактный gear у «Мои задачи»). */
.projects-list .projrail-sort, .projects-list .projrail-cfg {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--panel); color: var(--muted); cursor: pointer; transition: all .12s ease;
}
.projects-list .projrail-sort:hover, .projects-list .projrail-cfg:hover { background: var(--panel-2); color: var(--primary-2); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
/* ⏱ CLIE-462 (раунд 3): фильтр «Идёт таймер» — тумблер той же семьи, что ↕/⚙️. Включён —
   «таймерный» var(--info) (одна семья с бейджем таймера и пульсом .cc-timer-pip), а не акцент
   приложения: цвет сам подсказывает, ЧТО отфильтровано. Кнопки нет, пока таймеров нет. */
.projects-list .projrail-run {
  flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 3px;
  min-width: 30px; height: 30px; padding: 0 5px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--panel); color: var(--muted); cursor: pointer; transition: all .12s ease;
}
.projects-list .projrail-run .ic { width: 15px; height: 15px; }
.projects-list .projrail-run .prrailrun-n { font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; opacity: .75; }
.projects-list .projrail-run:hover { background: var(--panel-2); color: var(--info); border-color: color-mix(in srgb, var(--info) 40%, var(--line)); }
.projects-list .projrail-run.on {
  color: var(--info); border-color: color-mix(in srgb, var(--info) 55%, var(--line));
  background: color-mix(in srgb, var(--info) 14%, transparent);
}
.projects-list .projrail-run.on .prrailrun-n { opacity: 1; }
.projects-list .projrail-sort .tcol-sortglyph { opacity: .85; }
.projects-list .projrail-cfg .ic { width: 15px; height: 15px; }
/* 🎚 CLIE-631: сколько фильтров сейчас включено — числом прямо на кнопке. Иначе сузивший список
   человек назавтра видит «пустой рельс» и считает это поломкой (правило «состояние видно там,
   где его встречают»). Включённый фильтр красим акцентом приложения — как #pcatFilter в каталоге. */
.projects-list .projrail-cfg { position: relative; }
.projects-list .projrail-cfg.on {
  color: var(--primary-2); border-color: color-mix(in srgb, var(--primary) 55%, var(--line));
  background: color-mix(in srgb, var(--primary) 14%, transparent);
}
.projects-list .prrail-fbadge {
  position: absolute; right: -4px; top: -4px; min-width: 15px; height: 15px; padding: 0 3px;
  display: inline-flex; align-items: center; justify-content: center; border-radius: 8px;
  background: var(--acc-fill); color: #fff; border: 2px solid var(--panel);
  font-size: 9.5px; font-weight: 800; line-height: 1; font-variant-numeric: tabular-nums; pointer-events: none;
}
/* Цветная точка этапа в строках ⚙️-конфига «Этапы воронки» (popover .tc-pop вне .projects-list). */
.tc-pop .tcol-cfg-ic .psec-swatch { width: 10px; height: 10px; border-radius: 50%; display: inline-block; box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 14%, transparent); }
/* Секция-цель при переносе проекта между этапами: тонкий акцент (не заливка на всю строку). */
.projects-list .proj-section-title.drop-target {
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 42%, transparent);
}
/* мягкая строка «скрыто N задач» */
.tasks-list .task-hidden-note { list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 9px 10px; margin-top: 4px; color: var(--muted); font-size: 11.5px; }
.tasks-list .task-hidden-note .thn-txt { display: inline-flex; align-items: center; gap: 6px; }
.tasks-list .task-hidden-note .ic { width: 13px; height: 13px; opacity: .7; }
.tasks-list .task-hidden-note .thn-cfg { background: none; border: none; color: var(--primary-2); font-size: 11.5px; font-weight: 600; cursor: pointer; padding: 2px 4px; border-radius: 6px; }
.tasks-list .task-hidden-note .thn-cfg:hover { background: color-mix(in srgb, var(--primary) 14%, transparent); }

/* ── Поповер «Настроить этапы» ── */
.tc-pop .tcol-cfg-head { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); padding: 2px 4px 6px; }
.tc-pop .tcol-cfg-hint { font-size: 11.5px; line-height: 1.45; color: var(--muted); padding: 0 4px 10px; }
.tc-pop .tcol-cfg-list { display: flex; flex-direction: column; gap: 3px; }
.tc-pop .tcol-cfg-row {
  display: flex; align-items: center; gap: 9px; padding: 7px 8px; border-radius: 9px;
  background: var(--panel); border: 1px solid transparent; cursor: grab; transition: background .12s ease, opacity .12s ease, border-color .12s ease;
}
.tc-pop .tcol-cfg-row:hover { background: var(--panel-2); }
.tc-pop .tcol-cfg-row.dragging { opacity: .55; border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); cursor: grabbing; }
.tc-pop .tcol-cfg-row.off { opacity: .5; }
.tc-pop .tcol-cfg-row.off .tcol-cfg-lbl { text-decoration: line-through; }
.tc-pop .tcol-drag { display: inline-flex; color: var(--muted); flex: none; }
.tc-pop .tcol-drag .ic { width: 15px; height: 15px; }
.tc-pop .tcol-cfg-ic { display: inline-flex; flex: none; }
.tc-pop .tcol-cfg-ic .ic { width: 15px; height: 15px; }
.tc-pop .tcol-cfg-lbl { flex: 1 1 auto; font-size: 13px; font-weight: 600; color: var(--text); }
.tc-pop .tcol-eye { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: none; background: none; color: var(--muted); border-radius: 7px; cursor: pointer; transition: all .12s ease; }
.tc-pop .tcol-eye .ic { width: 15px; height: 15px; }
.tc-pop .tcol-eye.on { color: var(--primary-2); }
.tc-pop .tcol-eye:hover { background: color-mix(in srgb, var(--primary) 14%, transparent); }
.tc-pop .tcol-cfg-foot { display: flex; justify-content: flex-end; padding-top: 8px; }

/* CLIE-599 (В1): левый акцент-бордюр по приоритету снят и здесь. Разметка `.task-row`
   (taskRowHtml) сейчас не рендерится — столбик у чатов давно на `.tw-card`, — но правило
   жило и вернуло бы запрещённую рейку любому, кто оживит строку. Приоритет = точка. */
.tasks-list .task-row {
  position: relative; /* якорь для .task-hover-acts (плавают top-right) */
  padding: 8px 8px; border-radius: 10px; cursor: pointer;
}
/* Верх карточки: круглешок-чекбокс + заголовок на ВСЮ ширину (заголовок больше не ужимается
   аватарами справа — они уехали в нижнюю полосу причастных .tr-ppl). */
.tasks-list .tr-top { display: flex; align-items: flex-start; gap: 9px; }
.tasks-list .task-row:hover { background: var(--panel-2); }
.tasks-list .task-row:hover .task-del { opacity: .65; }

.tasks-list .task-check {
  flex: none; margin-top: 1px;
  width: 19px; height: 19px; border-radius: 50%;
  border: 2px solid var(--line); background: transparent;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; color: transparent; padding: 0;
  transition: background .12s, border-color .12s, color .12s;
}
.tasks-list .task-check:hover { border-color: var(--primary); }
.tasks-list .task-check svg { width: 12px; height: 12px; }
.tasks-list .task-row.done .task-check {
  background: var(--acc-grad); border-color: transparent; color: #fff;
}
/* Отменённая задача: приглушена + серый «×» (НЕ зелёная галка — это не «выполнено»,
   а «отменено»; кружок-кнопка = «вернуть в работу»). Заголовок зачёркнут ниже. */
.tasks-list .task-row.cancelled { opacity: .6; }
.tasks-list .task-row.cancelled .task-check {
  background: transparent; border-color: var(--muted); color: var(--muted);
}
.tasks-list .task-row.cancelled .task-check:hover { border-color: var(--primary); color: var(--primary); }

.tasks-list .task-main { min-width: 0; flex: 1; }
.tasks-list .task-title {
  flex: 1; min-width: 0; /* заголовок занимает всю ширину строки .tr-top */
  font-size: 13.5px; line-height: 1.3; color: var(--text);
  word-break: break-word;
}
.tasks-list .task-row.done .task-title { color: var(--muted); text-decoration: line-through; }
.tasks-list .task-row.cancelled .task-title { color: var(--muted); text-decoration: line-through; }
/* Мета и полоса причастных выровнены под ЗАГОЛОВОК (28px = 19px чекбокс + 9px gap). */
.tasks-list .task-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin-top: 3px; margin-left: 28px; font-size: 11px;
}
.tasks-list .task-chip {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 1px 6px; border-radius: 6px;
  background: var(--panel-2); color: var(--muted); white-space: nowrap;
}
.tasks-list .task-chip.due-overdue { background: var(--urg-overdue-soft); color: var(--urg-overdue-ink); }
.tasks-list .task-chip.due-today   { background: var(--urg-today-soft); color: var(--urg-today); }
.tasks-list .task-chip.conv { max-width: 130px; overflow: hidden; text-overflow: ellipsis; }
/* CLIE-481: чип «Проект · Чат» в строке задачи — flex, чтобы усекались ОБЕ половины
   (у голого текстового узла text-overflow не работает: анонимный flex-item). */
.tasks-list .task-chip.conv { display: inline-flex; align-items: center; gap: 4px; }
.tasks-list .task-chip.conv .tw-pill-main { flex: 0 0 auto; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tasks-list .task-chip.conv .tw-pill-sub { flex: 0 1 auto; min-width: 0; }
.tasks-list .task-chip.chat.unread { background: color-mix(in srgb, var(--primary) 22%, transparent); color: var(--primary-2); position: relative; }
.tasks-list .task-chip .task-chip-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--urg-overdue); display: inline-block; margin-left: 1px; }
.tasks-list .task-chip.sub, .tasks-list .task-chip.link { color: var(--primary-2); }
.tasks-list .task-chip.parent { color: var(--muted); font-weight: 700; padding-inline: 6px; }
.tasks-list .task-chip.rel { cursor: pointer; }
.tasks-list .task-chip.rel:hover { background: color-mix(in srgb, var(--primary) 24%, transparent); color: var(--primary-2); }
/* Задача «В работе» (status=in_progress): синий чип + мягкая заливка строки — чтобы с
   одного взгляда было видно, что по задаче идёт работа/учёт времени (левый акцент строки
   не трогаем — там приоритет). */
.tasks-list .task-row.in-progress { background: color-mix(in srgb, #3B82F6 8%, transparent); }
.tasks-list .task-row.in-progress:hover { background: color-mix(in srgb, #3B82F6 13%, transparent); }
.tasks-list .task-chip.wip { background: var(--info-soft); color: var(--info); font-weight: 600; font-variant-numeric: tabular-nums; }
.tasks-list .task-chip.wip .ic { animation: wipPulse 1.8s ease-in-out infinite; }
@keyframes wipPulse { 0%, 100% { opacity: .5; } 50% { opacity: 1; } }
html[data-theme="light"] .tasks-list .task-chip.wip { color: var(--cm-1d4ed8, #1d4ed8); }
/* Бейдж «в работе» (живой таймер учёта времени) — доска/плитки/список/таймлайн. Иконка пульсирует
   как у .task-chip.wip; tabular-nums чтобы секундомер не дёргал ширину. Не путать со статусом (колонкой). */
.tw-pill.tw-pill-timer { background: var(--info-soft); color: var(--info); font-weight: 600; font-variant-numeric: tabular-nums; }
/* ── Поиск задач (CLIE-469) ──────────────────────────────────────────────────
   Пилюля «почему задача в выдаче»: рисуется ТОЛЬКО когда совпало не в названии
   (в описании / чек-листе / комментарии / файле) — название и так подсвечено. */
.tw-pill.tw-pill-match { background: color-mix(in srgb, var(--accent) 13%, transparent); color: var(--accent); font-weight: 600; }
.tw-pill.tw-pill-match svg.ic { width: 11px; height: 11px; }
/* Сегмент «Название | Везде» = КАНОНИЧЕСКИЙ сегмент продукта `.cc-seg` в размере строки
   тулбара (`.cc-seg-md`) — см. блок CLIE-249/CLIE-505 ниже. Своего вида у него БОЛЬШЕ НЕТ.
   🔴 CLIE-505: раньше здесь жила рукописная копия (дорожка color-mix 13%, радиус 7, кегль
   11.5) — она была на 5.5px ниже соседних «Все задачи ▾»/поля поиска и с другим радиусом,
   т.е. ровно то, на что жаловался владелец («дизайн везде разный»). Осталась ТОЛЬКО
   раскладка (где стоит), вид берётся из канона. */
.tq-seg { display: inline-flex; }
.tq-seg button:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--glow); }
/* Тулбар доски: поле поиска и сегмент — один блок, сегмент прижат к правому краю поля.
   align-items:stretch — чтобы сегмент физически не мог оказаться ниже поля (CLIE-505). */
/* 🔴 CLIE-805: базис 220px + shrink — обёртка поля поиска ПЕРЕНОСИТСЯ вместе с сегментом
   «Название | Везде», а не схлопывается в ноль, оставляя сам <input> висеть под кнопками
   («поиск не видно, если экран небольшой»). min-width НЕ ноль: ниже своей подписи контрол не
   сжимается (СРЕД-33) — не влезло, значит переносим. */
.tw-search-wrap { display: inline-flex; align-items: stretch; gap: 8px; flex: 1 1 220px; min-width: 150px; }
/* Столбик «Мои задачи»: сегмент внутри той же строки-поиска, перед крестиком «сбросить». */
/* 🔴 Столбик «Мои задачи» узкий (~230px): сегмент в ОДНОМ ряду с полем съедал ввод —
   от «выгружать» оставалось видно «вы». Поэтому здесь (в отличие от широкого тулбара
   доски) сегмент уходит НА ВТОРУЮ СТРОКУ — то же правило «поле + кнопка на двух
   строках», что во Flutter-версии этого же поиска. Порядок: [лупа][поле][×] / [сегмент]. */
.tasks-list .task-searchbar { flex-wrap: wrap; row-gap: 7px; }
.tasks-list .task-searchbar .tsb-clr { order: 2; }
.tasks-list .task-searchbar .tq-seg { order: 3; margin-left: 22px; }
/* Минимум ширины поля задан в самом правиле .task-search-input ниже: не влезли вместе —
   сегмент САМ съезжает вниз (адаптивно, без брейкпоинта). */
/* Строка ЗАДАЧИ в глобальном поиске (секция «Задачи»): вместо аватара — знак задачи. */
.search-task-av { display: inline-flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--accent) 12%, var(--panel-2)); color: var(--accent); }
.search-task-av svg.ic { width: 17px; height: 17px; }
.search-task-where { color: var(--accent); font-weight: 600; }
.tw-pill.tw-pill-timer .ic { animation: wipPulse 1.8s ease-in-out infinite; }
html[data-theme="light"] .tw-pill.tw-pill-timer { color: var(--cm-1d4ed8, #1d4ed8); background: rgba(37,99,235,.12); }
.tw-pill.tw-pill-timer.tl-timer { font-size: 10.5px; padding: 1px 6px; margin-left: 6px; flex: 0 0 auto; }
/* Таймер ведёт ИИ: та же плашка, но ИИ-акцент (фиолет) + иконка-искры + метка «ИИ» — чтобы на
   карточке/доске/списке/таймлайне было видно, что время пишет ИИ, а не человек. Одна ИИ-семья с
   .tip-tm-*.ai. Тёмная — светлый фиолет #a78bfa; светлая — насыщенный #6d28d9 (контраст на белом). */
.tw-pill.tw-pill-timer.ai, .tasks-list .task-chip.wip.ai { background: var(--cm-a78bfa-16, rgba(167,139,250,.16)); color: var(--cm-a78bfa, #a78bfa); }
html[data-theme="light"] .tw-pill.tw-pill-timer.ai,
html[data-theme="light"] .tasks-list .task-chip.wip.ai { color: var(--cm-6d28d9, #6d28d9); background: var(--cm-7c3aed-11, rgba(124,58,237,.11)); }
/* Метка «ИИ» — кеглем чипа: на .82em заглавные «ИИ» вставали ниже цифр таймера и читались строчными «ии». */
.tw-tm-ai { font-weight: 700; letter-spacing: .3px; }
/* Время в РАБОЧЕЙ стадии (started-столбцы) — янтарный чип «портфель», пульс-точка пока в работе. */
.tw-pill.tw-pill-worktime { background: rgba(245,166,35,.16); color: #e0912a; font-weight: 600; font-variant-numeric: tabular-nums; }
.tw-pill.tw-pill-worktime.running::after { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; display: inline-block; animation: wipPulse 1.8s ease-in-out infinite; }
html[data-theme="light"] .tw-pill.tw-pill-worktime { color: #b5710f; background: rgba(245,166,35,.14); }
/* «Раунд N» — задачу возвращали в работу. Янтарный чип (тон разделителей раундов в «Заметках»),
   виден на карточке доски/плиток и в списке. Тонкая рамка — чтобы читался как «важный статус». */
.tw-pill.tw-pill-round { background: var(--warning-soft); color: var(--warning); font-weight: 650; letter-spacing: .1px; border: 1px solid color-mix(in srgb, var(--warning) 32%, transparent); }
.tw-pill.tw-pill-round .ic { width: 12px; height: 12px; opacity: .9; }
/* ── «ЗАДАЧА СЕЙЧАС НА СТОРОНЕ КЛИЕНТА» (мяч у клиента, CLIE-169) ─────────────────────────
   Отдельная бирюзовая семья: НЕ синяя (там наш таймер), НЕ янтарная (раунды/время в стадии),
   НЕ красная (это не авария) — «ждём не нас». В карточке задачи та же пилюля работает КНОПКОЙ
   (нажал → переключилось), поэтому у неё есть hover/active и мягкий переход 140ms.
   `.long` (ждём ≥ 7 дней) — тон уходит в янтарь: «клиент молчит неделю» обязано цеплять глаз;
   класс переключает живой тик data-live="waitsince", без перерисовки карточки. */
.tw-pill.tw-pill-wait { background: rgba(79,195,217,.15); color: #6fd3e4; font-weight: 640; letter-spacing: .1px; border: 1px solid color-mix(in srgb, #4FC3D9 30%, transparent); }
.tw-pill.tw-pill-wait .ic { width: 12px; height: 12px; opacity: .95; }
.tw-pill.tw-pill-wait.long { background: var(--warning-soft); color: var(--warning); border-color: color-mix(in srgb, var(--warning) 34%, transparent); }
button.tw-pill.tw-pill-wait { cursor: pointer; transition: background .14s ease, color .14s ease, border-color .14s ease, transform .12s ease; font: inherit; font-size: 11.5px; font-weight: 640; }
button.tw-pill.tw-pill-wait:hover { background: rgba(79,195,217,.24); }
button.tw-pill.tw-pill-wait.long:hover { background: color-mix(in srgb, var(--warning) 26%, transparent); }
button.tw-pill.tw-pill-wait:active { transform: scale(.97); }
button.tw-pill.tw-pill-wait:disabled { opacity: .5; cursor: default; }
/* Выключенное состояние в карточке — «тихая» контурная кнопка: подсказывает, что так можно,
   но не отбирает внимание у статуса (прогрессивное раскрытие). */
/* 🔴 Пунктир по --line в тёмной теме почти не виден (#2a2f3a на #1a1e27) — кнопка читалась
   как статичная подпись. Берём контур от --muted: видно, что это КНОПКА, но тон остаётся тихим. */
button.tw-pill.tw-pill-wait.off { background: transparent; color: var(--muted); border: 1px dashed color-mix(in srgb, var(--muted) 46%, transparent); font-weight: 600; }
button.tw-pill.tw-pill-wait.off:hover { color: #6fd3e4; border-color: color-mix(in srgb, #4FC3D9 40%, transparent); border-style: solid; background: rgba(79,195,217,.10); }
html[data-theme="light"] .tw-pill.tw-pill-wait { color: #0e7490; background: rgba(14,116,144,.11); border-color: rgba(14,116,144,.26); }
html[data-theme="light"] .tw-pill.tw-pill-wait.long { color: #9a6a00; background: rgba(229,162,60,.16); border-color: rgba(229,162,60,.38); }
html[data-theme="light"] button.tw-pill.tw-pill-wait:hover { background: rgba(14,116,144,.18); }
html[data-theme="light"] button.tw-pill.tw-pill-wait.off { color: var(--muted); background: transparent; }
html[data-theme="light"] button.tw-pill.tw-pill-wait.off:hover { color: #0e7490; background: rgba(14,116,144,.09); border-color: rgba(14,116,144,.34); }
/* Тот же маркер в строке списка задач (компактнее, без рамки — там чипы плоские). */
.tasks-list .task-chip.wait { background: rgba(79,195,217,.16); color: #6fd3e4; font-weight: 620; }
.tasks-list .task-chip.wait.long { background: var(--warning-soft); color: var(--warning); }
html[data-theme="light"] .tasks-list .task-chip.wait { color: #0e7490; background: rgba(14,116,144,.11); }
html[data-theme="light"] .tasks-list .task-chip.wait.long { color: #9a6a00; background: rgba(229,162,60,.16); }

/* Бейдж раунда в ШАПКЕ открытой задачи (рядом с пилюлей статуса). */
.tip-round-badge { display: inline-flex; align-items: center; gap: 5px; background: var(--warning-soft); color: var(--warning); border: 1px solid color-mix(in srgb, var(--warning) 34%, transparent); border-radius: 999px; padding: 3px 10px; font-size: 12px; font-weight: 700; letter-spacing: .2px; white-space: nowrap; }
.tip-round-badge .ic { width: 13px; height: 13px; }
/* Чип раунда в инбоксе «Моя работа» (v2). */
.v2-chip.mini.round { color: var(--warning); background: var(--warning-soft); font-weight: 650; }
/* Подсветка связанных/подзадач (по клику на чип): столбик «Мои задачи» и карточки доски.
   Тонкий 2px-glow терялся на плотной доске (владелец: «перестали подсвечиваться») — усилили:
   яркое кольцо + цветной ореол + разовый «пинг»-пульс, чтобы сразу увидеть связанные карточки. */
/* База (ТЁМНАЯ тема): яркое 2px-кольцо + цветной ореол — карточка остаётся тёмной/читаемой,
   заливку НЕ даём (на тёмном тинт выглядел бы «серым/приглушённым»). */
.task-row.rel-hl { box-shadow: inset 3px 0 0 var(--primary), 0 0 0 2px var(--primary), 0 6px 20px color-mix(in srgb, var(--primary) 32%, transparent); border-radius: 8px; position: relative; z-index: 2; }
.tw-card.rel-hl { box-shadow: 0 0 0 2px var(--primary), 0 6px 22px color-mix(in srgb, var(--primary) 42%, transparent); z-index: 2; }
/* CLIE-1014·2: строка вида «Очередь» — тот же приём (кольцо + ореол), чтобы приход из карточки
   («Вся очередь →») сразу показывал, ГДЕ эта задача стоит. Левой рейки тут нет намеренно. */
.wsq-row.rel-hl { box-shadow: 0 0 0 2px var(--primary), 0 6px 20px color-mix(in srgb, var(--primary) 32%, transparent); border-radius: 10px; position: relative; z-index: 2; }
.task-row.rel-hl, .tw-card.rel-hl, .wsq-row.rel-hl { animation: relHlPing 1.5s ease-out 1; transition: box-shadow .15s ease; }
/* СВЕТЛАЯ тема: на белом тонкое кольцо/ореол теряются → добавляем тинт-заливку через inset
   box-shadow (реальный background не трогаем — не ломаем done/cancelled). Читается как выбранный
   элемент в Reminders: мягкая заливка + акцентное кольцо. `data-theme="light"` ставит и режим
   «Система» (index.html), так что покрыт и системный светлый. */
html[data-theme="light"] .tw-card.rel-hl { box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--primary) 12%, transparent), 0 0 0 2px var(--primary), 0 6px 22px color-mix(in srgb, var(--primary) 26%, transparent); }
html[data-theme="light"] .task-row.rel-hl { box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--primary) 12%, transparent), inset 3px 0 0 var(--primary), 0 0 0 2px var(--primary), 0 6px 20px color-mix(in srgb, var(--primary) 22%, transparent); }
html[data-theme="light"] .wsq-row.rel-hl { box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--primary) 12%, transparent), 0 0 0 2px var(--primary), 0 6px 20px color-mix(in srgb, var(--primary) 22%, transparent); }
/* «Пинг»: цветное кольцо разово расходится наружу, затем оседает в постоянный ореол. */
@keyframes relHlPing {
  0%   { box-shadow: 0 0 0 2px var(--primary), 0 0 0 0   color-mix(in srgb, var(--primary) 60%, transparent); }
  65%  { box-shadow: 0 0 0 2px var(--primary), 0 0 0 13px color-mix(in srgb, var(--primary) 0%,  transparent); }
  100% { box-shadow: 0 0 0 2px var(--primary), 0 6px 22px color-mix(in srgb, var(--primary) 42%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .task-row.rel-hl, .tw-card.rel-hl { animation: none; } }
/* Пульс «идёт таймер» (бейдж, заголовок секции, тумблер «Идёт») гасим при reduce-motion:
   смысл несут цвет и текст, мигание — только акцент. */
@media (prefers-reduced-motion: reduce) {
  .tasks-list .task-chip.wip .ic,
  .tw-pill.tw-pill-timer .ic,
  .tw-pill.tw-pill-worktime.running::after,
  .tasks-list .tst-running svg.ic,
  .tw-run-btn.active svg.ic { animation: none; }
}
/* «Прыжок» по кнопке «На доске»: разовый пульс, чтобы сразу увидеть куда переместились. */
.tw-card.tw-jump, .task-row.tw-jump { animation: twJumpPulse 1.5s ease-out 2; }
@keyframes twJumpPulse {
  0%   { box-shadow: 0 0 0 2px var(--primary), 0 0 0 7px color-mix(in srgb, var(--primary) 45%, transparent); }
  55%  { box-shadow: 0 0 0 2px var(--primary), 0 0 0 15px color-mix(in srgb, var(--primary) 0%, transparent); }
  100% { box-shadow: 0 0 0 2px var(--primary); }
}
/* «Требует внимания» (push/WS событие notify по задаче) — красная точка перед названием. */
.tasks-list .task-title .task-attention-dot, .tw-card-title .task-attention-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--urg-overdue); display: inline-block; margin-right: 5px; vertical-align: middle; flex: none; }
/* ── «Задача изменена другим участником или ИИ, я ещё не смотрел» ──────────────────
   🔴 ИСТОРИЯ ПРАВКИ (не откатывать в «скромную точку»): сначала метка была одиночным
   кругом 7px перед названием. Владелец открыл доску, где 23 карточки «ИИ выполнил»
   стоят в «На проверке», и написал «ничего не видно, они никак не выделяются». На
   плотной доске точка такого размера просто не читается — её не видно, пока не
   присматриваешься. В задаче дословно просили «помечать ЦВЕТОМ или ВЫДЕЛЕНИЕМ».
   Поэтому метка теперь двухуровневая:
     1) заливка карточки/строки — мягкая подложка цветом --primary (то, что ловит глаз
        при беглом взгляде на колонку);
     2) точка 9px с гало + плотный заголовок — то, что говорит «вот именно эта».
   Чтобы это НЕ стало ёлкой, заливка намеренно слабая (7–10% primary) и живёт только до
   первого взгляда: наведение/открытие её гасят. Левую полосу карточки не трогаем — она
   занята ПРИОРИТЕТОМ (.tw-card.prio-*), второй цветной акцент там читался бы как ошибка.
   --primary объявлен и в тёмной (:root), и в светлой (html[data-theme="light"]) теме,
   поэтому базовые правила намеренно БЕЗ префикса темы — одно на обе; ниже только та
   пара мест, где светлой нужен свой замес (карточка красится var(--panel)).
   Гашение по наведению/открытию — класс .seen: точка растворяется и схлопывает свою
   ширину за 140мс, а не пропадает рывком (сам узел уберёт ближайшая перерисовка). */
.task-changed-dot {
  width: 9px; height: 9px; border-radius: 50%; background: var(--primary);
  display: inline-block; margin-right: 7px; vertical-align: middle; flex: none;
  /* Гало — тот же приём, что у .tw-card.rel-hl: делает точку заметной на любом фоне,
     не увеличивая её саму (иначе она спорит с чекбоксом и красной «требует внимания»). */
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 20%, transparent);
  transition: opacity .14s ease, width .14s ease, margin-right .14s ease, box-shadow .14s ease;
}
.task-changed-dot.seen { opacity: 0; width: 0; margin-right: 0; box-shadow: none; }
/* .tw-row-title — флекс с gap: собственный отступ точки там лишний (иначе двойной зазор). */
.tw-row-title .task-changed-dot { margin-right: 0; }
/* Пока не просмотрено — заголовок плотнее. :has() снимает выделение САМ, как только точка
   получила .seen, — второй класс в JS для этого не нужен. */
.tw-card-title:has(> .task-changed-dot:not(.seen)),
.tw-row-title:has(> .task-changed-dot:not(.seen)),
.tl-name:has(> .task-changed-dot:not(.seen)) { font-weight: 600; }
/* Уровень 1 — подложка. :has() на КОНТЕЙНЕРЕ: точка лежит внутри заголовка, поэтому
   селектор без `>`. Как только JS повесил на точку .seen (наведение/открытие), правило
   перестаёт совпадать и заливка уходит сама — отдельного класса на карточку не нужно,
   и точечное гашение не требует пересборки DOM (см. taskSeenRepaint в app.js). */
/* 🔴 ПЕРФ (CLIE-444): у КАРТОЧКИ — класс .has-unseen (ставит boardCardHtml, снимает
   taskSeenRepaint), а НЕ :has(). Контейнерный :has() заставлял браузер переоценивать
   предка на любую мутацию внутри карточки, а тикер живых меток переписывает [data-live]
   внутри карточек раз в секунду; на 900 карточках это 36.6 мс против 13.4 мс.
   У .tw-row/.tl-row (дашборд, таймлайн) их единицы — там :has() оставлен как был. */
html[data-theme="light"] {
  --task-unseen-accent: var(--cm-565be8, #565be8);
}
.tw-card.has-unseen,
.tw-row:has(.task-changed-dot:not(.seen)),
.tl-row:has(.task-changed-dot:not(.seen)) {
  background: color-mix(in srgb, var(--task-unseen-accent, var(--primary)) 10%, var(--panel));
  transition: background .16s ease, box-shadow .16s ease;
}
/* Карточка доски — плюс тонкий контур цветом акцента: на светлой колонке одной заливки
   мало, карточка должна «оторваться» от соседей. Не border (он занят приоритетом слева
   и рамкой), а inset-кольцо — оно не двигает геометрию и не ломает hover-состояние. */
.tw-card.has-unseen {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--task-unseen-accent, var(--primary)) 34%, transparent);
}
/* Наведение на непросмотренную карточку: кольцо остаётся, но подъём-тень с .tw-card:hover
   надо вернуть руками — правило выше перебивает её по специфичности, а без тени карточка
   под курсором перестаёт «подниматься» и hover ощущается сломанным. */
.tw-card.has-unseen:hover {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--task-unseen-accent, var(--primary)) 34%, transparent),
              0 6px 18px -8px rgba(0,0,0,.5);
}
/* Светлая карточка: подпись «Есть изменения» вместо угловой точки и усиленной
   рамки. У гашения по наведению сохраняем место до следующей перерисовки: соседние
   карточки не должны прыгать под курсор и отмечаться просмотренными сами. */
.task-change-caption { display: none; }
html[data-theme="light"] .tw-card .task-change-caption {
  display: block; margin: 0 0 9px;
  font-size: 11px; line-height: 15px; font-weight: 500; letter-spacing: .1px;
  color: var(--muted); opacity: 1; transition: opacity .14s ease;
}
html[data-theme="light"] .tw-card:not(.has-unseen) .task-change-caption {
  opacity: 0; visibility: hidden;
}
html[data-theme="light"] .tw-card.has-unseen:where(:not(.ai-self)),
html[data-theme="light"] .tasks-list .tw-card.has-unseen:where(:not(.ai-self)),
html[data-theme="light"] .tw-row:has(.task-changed-dot:not(.seen)),
html[data-theme="light"] .tl-row:has(.task-changed-dot:not(.seen)) {
  background: var(--panel);
}
html[data-theme="light"] .tw-card.has-unseen:where(:not(.rel-hl, .ai-self)),
html[data-theme="light"] .tasks-list .tw-card.has-unseen:where(:not(.rel-hl, .ai-self)) {
  border-color: var(--line); box-shadow: none;
}
html[data-theme="light"] .tw-card.has-unseen:hover:where(:not(.rel-hl, .ai-self)),
html[data-theme="light"] .tasks-list .tw-card.has-unseen:hover:where(:not(.rel-hl, .ai-self)) {
  border-color: var(--line-strong); box-shadow: var(--shadow-1);
}
html[data-theme="light"] .task-changed-dot { background: var(--task-unseen-accent); box-shadow: none; }
/* Чип комментариев на карточке «Мои задачи»: непрочитанные → акцент + красная точка. */
/* 🔴🔴 CLIE-1585 · АКЦЕНТ КАК ЧЕРНИЛА — ЭТО --primary-2, А НЕ --accent/--primary.
   Канон `contrast-runtime-audit`, и это НЕ вкусовщина: в светлой теме --accent = #0071e3,
   а на инсете --panel-2 #f5f5f7 он даёт ровно 4.31:1 при AA 4.5. Замер живого прода
   28.09.2026 нашёл ПЯТЬ таких мест сразу — значит правило подключали по одному месту,
   а не классом. --primary-2 (#005bb8 в светлой, #8b9cf5 в тёмной) — тот же тон той же
   семантики, заливки и оттенки не тронуты, и он работает в ОБЕИХ темах без light-only
   заплатки: в тёмной «чернила акцента» и есть светлый вариант акцента. */
.tw-pill.chat.unread { color: var(--primary-2, var(--accent)); }
.tw-pill .tw-pill-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--urg-overdue); display: inline-block; margin-left: 1px; }
.tasks-list .task-del {
  flex: none; background: transparent; border: 0; cursor: pointer;
  color: var(--muted); font-size: 13px; line-height: 1; padding: 2px 4px;
  opacity: 0; transition: opacity .12s, color .12s;
}
.tasks-list .task-del:hover { color: var(--urg-overdue-ink); opacity: 1; }
.tasks-list .task-del svg.ic { width: 14px; height: 14px; }
/* секции с иконками (без эмодзи) */
.tasks-list .task-section-title { display: flex; align-items: center; gap: 6px; }
.tasks-list .task-section-title svg.ic { width: 13px; height: 13px; }
/* счётчик раздела приглушён ЧЕРНИЛАМИ, а не прозрачностью: .65 давала 3.55 в тёмной (было правилом только светлой) */
.tasks-list .task-section-title .tsec-n { margin-left: auto; font-weight: 600; color: var(--text-dim); }
.tasks-list .task-chip svg.ic { width: 12px; height: 12px; }
.tasks-list .task-row-side { flex: none; display: flex; align-items: center; gap: 5px; margin-top: 1px; }

/* ── Полоса причастных (нижняя строка карточки): ответственный + соисполнители + наблюдатели,
   с явной МОЕЙ ролью. Крупнее аватары (26px), «я» — всегда яркая пилюля, не кружок. ───────── */
.tasks-list .tr-ppl {
  display: flex; align-items: center; gap: 7px;
  margin: 7px 0 0 28px; padding-top: 7px;
  border-top: 1px solid var(--line); min-width: 0; overflow: hidden;
}
.tasks-list .tr-ppl .tp-clu { display: inline-flex; align-items: center; min-width: 0; }
/* Кластер наблюдателей: отделён вертикальной чертой + ведущий глаз, аватары мельче/приглушены. */
.tasks-list .tr-ppl .tp-watch { margin-left: 6px; padding-left: 8px; border-left: 1px solid var(--line); }
.tasks-list .tr-ppl .tp-watch > svg.ic { width: 13px; height: 13px; color: var(--muted); margin-right: 4px; flex: none; }
.tasks-list .tr-ppl .tp-av {
  width: 26px; height: 26px; border-radius: 50%;
  border: 2px solid var(--panel);
  background-size: cover; background-position: center;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 600; color: #fff; flex: none; position: relative;
}
/* Наложение — только МЕЖДУ соседними аватарами (и первый аватар — на пилюлю «я»). Не
   :first-child (первым в кластере может быть глаз/пилюля) — берём смежных соседей. */
.tasks-list .tr-ppl .tp-av + .tp-av { margin-left: -8px; }
.tasks-list .tr-ppl .tp-me + .tp-av { margin-left: -8px; }
/* Ответственный — единственное золотое кольцо на карточке (кольцо box-shadow не клипается соседом). */
.tasks-list .tr-ppl .tp-av.tp-resp { box-shadow: 0 0 0 2px var(--urg-today); z-index: 2; }
.tasks-list .tr-ppl .tp-av.tp-more { background: var(--panel-2); color: var(--muted); font-size: 10px; }
/* Наблюдатели: мельче и приглушены (без grayscale — паритет с Flutter). Прозрачность — только у ФОТО
   (пустой узел / видео): у буквы-заглушки она гасила букву ниже нормы (4.12 в тёмном «Штиле», свип волны 3,
   20.10.2026) — буква наблюдателя отличается размером, а не прозрачностью (класс «приглушать чернилами»). */
.tasks-list .tr-ppl .tp-watch .tp-av { width: 22px; height: 22px; font-size: 10px; }
.tasks-list .tr-ppl .tp-watch .tp-av:is(:empty, .has-video) { opacity: .82; }
.tasks-list .tr-ppl .tp-watch .tp-av + .tp-av { margin-left: -7px; }
/* «Я» — пилюля с ролью (никогда не прячется в +N). */
.tasks-list .tr-ppl .tp-me {
  display: inline-flex; align-items: center; gap: 4px; flex: none;
  height: 26px; padding: 0 9px 0 3px; border-radius: 13px;
  font-size: 10px; font-weight: 700; white-space: nowrap;
  background: var(--acc-fill); color: #fff; z-index: 5;
}
.tasks-list .tr-ppl .tp-me svg.ic { width: 11px; height: 11px; flex: none; }
.tasks-list .tr-ppl .tp-me-dot {
  width: 20px; height: 20px; border-radius: 50%; flex: none;
  background: rgba(255,255,255,.22); background-size: cover; background-position: center;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 9px; font-weight: 700; color: #fff;
}
/* Ответственный-«я» — золотая пилюля, тёмный текст (читаемо и на светлой теме). */
.tasks-list .tr-ppl .tp-me-resp { background: var(--urg-today); color: #20242c; }
.tasks-list .tr-ppl .tp-me-resp .tp-me-dot { background: rgba(0,0,0,.18); color: #20242c; }
/* Наблюдатель-«я» — светлый контурный вариант (пассивная роль). */
.tasks-list .tr-ppl .tp-me-watch {
  height: 24px; background: var(--panel-2); color: var(--primary-2);
  border: 1.5px solid var(--accent); font-weight: 600;
}
.tasks-list .tr-ppl .tp-me-watch .tp-me-dot { width: 18px; height: 18px; background: var(--accent); }
/* Выполненная задача — вся полоса приглушена. */
.tasks-list .task-row.done .tr-ppl { opacity: .5; }
/* «Не назначено» — явный чип вместо пустоты/висящего аватара (жалоба «почему нет аватарки»).
   Полоса держит min-height, чтобы карточки не «прыгали» по высоте. */
.tasks-list .tr-ppl { min-height: 34px; }
.tp-noone {
  display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 11px;
  border: 1px dashed var(--line); border-radius: 14px; background: transparent;
  color: var(--muted); font-size: 11.5px; cursor: pointer; white-space: nowrap;
}
.tp-noone:hover { border-color: var(--accent); color: var(--primary-2); }
.tp-noone svg.ic { width: 13px; height: 13px; flex: none; }
/* Меню «⋯» задачи: разделитель + опасное действие (удаление отделено и подкрашено). */
.tc-pop-sep { height: 1px; background: var(--line); margin: 5px 4px; }
.tc-pop-row.danger { color: var(--danger); }
.tc-pop-row.danger:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); }

/* ── V3 карточка ДОСКИ: ручка перетаскивания, действия ⋯, полоса причастных ──────────
   Раньше карточки доски (v1/v2) показывали лишь плоские аватары исполнителей — теперь та же
   полоса, что в списке: ответственный в золотом кольце, наблюдатели за глазом, «Не назначено». */
.tw-card { position: relative; }
.tw-card-grip { position: absolute; left: 1px; top: 10px; color: var(--muted); opacity: 0; cursor: grab; transition: opacity .12s; }
.tw-card-grip .ic { width: 14px; height: 14px; }
.tw-card:hover .tw-card-grip { opacity: .4; }
.tw-card-acts { position: absolute; top: 7px; right: 7px; display: flex; gap: 3px; opacity: 0; transition: opacity .12s; z-index: 3; }
.tw-card:hover .tw-card-acts { opacity: 1; }
.tw-card-acts button { width: 24px; height: 24px; border: 1px solid var(--line); background: var(--panel-2); border-radius: 7px; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0; }
.tw-card-acts button:hover { color: var(--text); border-color: var(--primary); }
.tw-card-acts .ic { width: 15px; height: 15px; }
/* Быстрые кнопки карточки (исполнитель/метка/срок/приоритет/⋯) — плавающая «пилюля» по
   наведению, как .task-hover-acts в строке списка: сплошной фон + тень, бордерлесс-кнопки. */
.tw-card-acts.tw-qacts { top: 6px; right: 6px; gap: 1px; padding: 2px; border-radius: 9px; background: var(--bg); border: 1px solid var(--line); box-shadow: 0 3px 12px rgba(0,0,0,.3); }
.tw-card-acts.tw-qacts button { width: 26px; height: 26px; border: none; background: transparent; border-radius: 7px; }
.tw-card-acts.tw-qacts button:hover { background: var(--panel-2); color: var(--text); border-color: transparent; }
.tw-card-acts.tw-qacts .tw-qa[data-qprio]:hover { color: var(--warn, var(--urg-today)); }
/* Плей/пауза таймера в быстрых кнопках: активная пауза («мой таймер идёт») — синий акцент,
   как .tqact-running в строке списка. */
.tw-card-acts.tw-qacts .tw-qa[data-qstart]:hover { color: var(--urg-done); }
.tw-card-acts.tw-qacts .tw-qa.tw-qa-running { color: var(--info); }
.tw-card-acts.tw-qacts .tw-qa.tw-qa-running:hover { background: var(--info-soft); color: var(--info); }
html[data-theme="light"] .tw-card-acts.tw-qacts .tw-qa.tw-qa-running { color: var(--cm-1d4ed8, #1d4ed8); }
/* Задачу выполняет ИИ — статичный значок таймера (не кнопка), 0099. */
.tw-card-acts.tw-qacts .tw-qa.tw-qa-ai { color: var(--cm-a78bfa, #a78bfa); cursor: default; }
.tw-card-acts.tw-qacts .tw-qa.tw-qa-ai:hover { background: transparent; }
/* «Мои задачи»: та же ЕДИНАЯ карточка (boardCardHtml), обёрнутая в <li> (список — <ul>).
   Верх карточки = чекбокс «Готово» + заголовок (флекс), как раньше в .tr-top у строки. */
.tasks-list .tw-card-li { list-style: none; margin: 0 0 7px 0; }
.tasks-list .tw-card-li:last-child { margin-bottom: 0; }
/* Перетаскивание порядка (ручной приоритет внутри секции) — ПЛАВНЫЙ pointer-движок ccStartRowDrag:
   тянущаяся карточка приподнимается и едет за курсором (transform ставит движок инлайном на <li>),
   соседи мягко расступаются (их transition тоже ставит движок), на отпускании — мягкая посадка. */
.tasks-list .tw-card-li.tw-drag .tw-card { cursor: grab; transition: box-shadow .14s ease; }
.tasks-list .tw-card-li.tw-drag .tw-card:active { cursor: grabbing; }
/* Во время перетаскивания: курсор-хват, без выделения текста и без мигания hover-кнопок карточек. */
.tasks-list.tw-reordering { cursor: grabbing; user-select: none; -webkit-user-select: none; touch-action: none; }
.tasks-list.tw-reordering .tw-card-acts { opacity: 0 !important; }
/* Невидимые (до наведения) быстрые кнопки НЕ должны перехватывать хват карточки: иначе верх-право
   карточки = «мёртвая зона» для драга (особенно на тач, где наведения нет). На наведении — кликабельны. */
.tasks-list .tw-card-acts { pointer-events: none; }
.tasks-list .tw-card:hover .tw-card-acts { pointer-events: auto; }
/* Приподнятая (тянущаяся) карточка: над остальными + мягкая, «яблочная» тень. */
.tasks-list .tw-card-li.tw-lift { z-index: 30; position: relative; }
.tasks-list .tw-card-li.tw-lift .tw-card { cursor: grabbing; box-shadow: 0 14px 34px rgba(0,0,0,.30), 0 2px 8px rgba(0,0,0,.18); }
html[data-theme="light"] .tasks-list .tw-card-li.tw-lift .tw-card { box-shadow: 0 14px 34px rgba(0,0,0,.16), 0 2px 8px rgba(0,0,0,.10); }
@media (prefers-reduced-motion: reduce) { .tasks-list .tw-card-li.tw-drag .tw-card, .tasks-list .tw-card-li { transition: none !important; } }
.tw-card-head { display: flex; align-items: flex-start; gap: 9px; }
.tw-card-head .tw-card-title { flex: 1; min-width: 0; }
.tw-card-head .task-check { flex: none; }
.tasks-list .tw-card.done .task-check { background: var(--acc-grad); border-color: transparent; color: #fff; }
.tasks-list .tw-card.cancelled .task-check { background: transparent; border-color: var(--muted); color: var(--muted); }
.tasks-list .tw-card.cancelled .task-check:hover { border-color: var(--primary); color: var(--primary); }
@media (hover: none) { .tw-card-grip, .tw-card-acts { opacity: 1; } }
/* Тач (оба шаблона): навести нельзя — быстрые кнопки карточки задачи видны всегда (строка выше),
   а абсолютом в правом верхнем углу плашка в 167 px ложилась НА заголовок: на телефоне от
   «Товары в продаже» оставалось «Товары в пр». Здесь плашка — своя строка над заголовком, на
   том же месте угла (6 px от кромки): ничего не накрывает. Мышь — как прежде, по наведению. */
@media (hover: none) { .tw-card > .tw-card-acts.tw-qacts { position: static; width: fit-content; max-width: 100%; margin: -5px -6px 6px auto; } }
/* …и нажимаема: в «Моих задачах» плашка ждёт наведения (`pointer-events` ниже), а на таче его
   нет — видимые кнопки пропускали палец сквозь себя и открывали задачу. Своей строкой она
   хват карточки больше не накрывает. */
@media (hover: none) { .tasks-list .tw-card > .tw-card-acts.tw-qacts { pointer-events: auto; } }
/* tasks-hover-toolbar-1 · телефон (тач, ≤760): плашка из шести быстрых кнопок шла своей строкой над
   заголовком КАЖДОЙ карточки (+30 px на карточку, цели 26 px). На карточке остаётся одна «⋯» 32 px в
   углу; плей/пауза таймера, исполнитель, метка, срок, приоритет и ценность — верхними строками того же
   меню «⋯» (cardQuickRows → taskMore, app.js). Мышь и тач шире 760 — как прежде. */
@media (hover: none) and (max-width: 760px) {
  .tw-card > .tw-card-acts.tw-qacts { position: absolute; top: 3px; right: 3px; width: auto; max-width: none; margin: 0; padding: 0; gap: 0; background: transparent; border-color: transparent; box-shadow: none; }
  .tw-card > .tw-card-acts.tw-qacts > :is([data-qstart], [data-qpause], [data-qassign], [data-qlabel], [data-qdate], [data-qprio], [data-tbval], .tw-qa-ai) { display: none; }
  .tw-card > .tw-card-acts.tw-qacts > .tw-card-more { width: 32px; height: 32px; border-radius: 9px; }
  .tasks-list .tw-card > .tw-card-acts.tw-qacts ~ .tw-card-title,
  .tasks-list .tw-card > .tw-card-acts.tw-qacts ~ .tw-card-head > .tw-card-title { padding-right: 30px; }
}
/* CLIE-599: полоса причастных больше не отдельный «подвал» с разделителем на всю ширину —
   это просто последняя строка карточки (−17px высоты на каждой карточке). Разделитель и
   прежние отступы возвращает сравнение ?card=0. */
/* 🔴 CLIE-892: полосу причастных теперь показывает и строка панели «Сегодня» (когда в
   задаче есть кто-то КРОМЕ меня). Второй копии аватаров не заводим — тот же блок,
   просто в списке селекторов появилась вторая поверхность.
   🔴 CLIE-1058: и ТРЕТЬЯ — строка вида «Очередь ИИ» (`.wsq-row`). Она такая же плотная, как
   строка дня, поэтому берёт и общий блок, и его компактный размер ниже. Добавить поверхность
   = дописать селектор сюда, а не завести четвёртую копию тех же аватаров. */
:is(.wsq-row, .ctp-row) .tr-ppl, .tw-card .tr-ppl, .tdy-row .tr-ppl { display: flex; align-items: center; gap: 7px; margin-top: 8px; padding-top: 0; border-top: none; min-height: 26px; }
/* Карточка столбика «Мои задачи»: строка .tasks-list .tr-ppl даёт полю слева 28 px (под кружок строки),
   а у карточки кружок свёрнут (см. .tasks-list .tw-card-head) — аватары стояли на 27 px правее заголовка и чипов. */
.tasks-list .tw-card .tr-ppl { margin-left: 0; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-clu, .tw-card .tr-ppl .tp-clu, .tdy-row .tr-ppl .tp-clu { display: inline-flex; align-items: center; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-av, .tw-card .tr-ppl .tp-av, .tdy-row .tr-ppl .tp-av { width: 24px; height: 24px; border-radius: 50%; border: 2px solid var(--panel); background-size: cover; background-position: center; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; font-weight: 600; color: #fff; position: relative; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-av + .tp-av, :is(.wsq-row, .ctp-row) .tr-ppl .tp-me + .tp-av, .tw-card .tr-ppl .tp-av + .tp-av, .tw-card .tr-ppl .tp-me + .tp-av, .tdy-row .tr-ppl .tp-av + .tp-av, .tdy-row .tr-ppl .tp-me + .tp-av { margin-left: -8px; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-av.tp-resp, .tw-card .tr-ppl .tp-av.tp-resp, .tdy-row .tr-ppl .tp-av.tp-resp { box-shadow: 0 0 0 2px var(--urg-today); z-index: 2; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-av.tp-more, .tw-card .tr-ppl .tp-av.tp-more, .tdy-row .tr-ppl .tp-av.tp-more { background: var(--panel-2); color: var(--muted); }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-watch, .tw-card .tr-ppl .tp-watch, .tdy-row .tr-ppl .tp-watch { margin-left: 6px; padding-left: 8px; border-left: 1px solid var(--line); display: inline-flex; align-items: center; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-watch > .ic, .tw-card .tr-ppl .tp-watch > .ic, .tdy-row .tr-ppl .tp-watch > .ic { width: 13px; height: 13px; color: var(--muted); margin-right: 4px; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-watch .tp-av, .tw-card .tr-ppl .tp-watch .tp-av, .tdy-row .tr-ppl .tp-watch .tp-av { width: 22px; height: 22px; }
:is(.wsq-row, .ctp-row, .tw-card, .tdy-row) .tr-ppl .tp-watch .tp-av:is(:empty, .has-video) { opacity: .82; }  /* только фото — см. .tasks-list выше */
:is(.wsq-row, .ctp-row) .tr-ppl .tp-me, .tw-card .tr-ppl .tp-me, .tdy-row .tr-ppl .tp-me { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 8px 0 3px; border-radius: 12px; font-size: 10px; font-weight: 700; background: var(--acc-fill); color: #fff; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-me .ic, .tw-card .tr-ppl .tp-me .ic, .tdy-row .tr-ppl .tp-me .ic { width: 11px; height: 11px; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-me-dot, .tw-card .tr-ppl .tp-me-dot, .tdy-row .tr-ppl .tp-me-dot { width: 18px; height: 18px; border-radius: 50%; background: rgba(255,255,255,.22); background-size: cover; background-position: center; display: inline-flex; align-items: center; justify-content: center; font-size: 9px; color: #fff; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-me-resp, .tw-card .tr-ppl .tp-me-resp, .tdy-row .tr-ppl .tp-me-resp { background: var(--urg-today); color: #20242c; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-me-resp .tp-me-dot, .tw-card .tr-ppl .tp-me-resp .tp-me-dot, .tdy-row .tr-ppl .tp-me-resp .tp-me-dot { background: rgba(0,0,0,.18); color: #20242c; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-me-watch, .tw-card .tr-ppl .tp-me-watch, .tdy-row .tr-ppl .tp-me-watch { height: 24px; background: var(--panel-2); color: var(--primary-2); border: 1.5px solid var(--accent); }
:is(.wsq-row, .ctp-row).done .tr-ppl, .tw-card.done .tr-ppl, .tdy-row.done .tr-ppl { opacity: .5; }
/* 🔴 CLIE-892: строка панели «Сегодня» ПЛОТНЕЕ карточки доски — там же список на весь день,
   а не отдельная карточка. Поэтому у полосы причастных здесь свой РАЗМЕР (тот же блок, тот
   же язык, просто компактнее), а не своя вторая отрисовка. */
:is(.wsq-row, .ctp-row) .tr-ppl, .tdy-row .tr-ppl { margin-top: 6px; min-height: 22px; gap: 6px; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-av, .tdy-row .tr-ppl .tp-av { width: 20px; height: 20px; font-size: 9px; border-width: 1.5px; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-watch .tp-av, .tdy-row .tr-ppl .tp-watch .tp-av { width: 18px; height: 18px; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-me, .tdy-row .tr-ppl .tp-me { height: 20px; font-size: 9px; }
:is(.wsq-row, .ctp-row) .tr-ppl .tp-me-dot, .tdy-row .tr-ppl .tp-me-dot { width: 15px; height: 15px; font-size: 8px; }
/* Заголовок оставляем место под ручку/действия слева-справа. */
.tw-card .tw-card-title { padding-right: 30px; }

/* ── Звезда-бейдж ответственного + ЕДИНЫЙ вид полосы причастных (список = доска) ──────
   Ответственного показываем ОДИНАКОВО везде: реальный аватар (фото) в золотом кольце + звезда.
   Никаких пилюль «отв.»/«соисп.» и опоры на state.me — только данные задачи. */
.tp-star { position: absolute; right: -3px; bottom: -3px; width: 14px; height: 14px; border-radius: 50%; background: var(--urg-today); color: #20242c; display: inline-flex; align-items: center; justify-content: center; border: 1.5px solid var(--panel); z-index: 3; }
.tp-star .ic { width: 9px; height: 9px; }
/* Звезда/кольцо не должны обрезаться контейнером полосы. */
.tasks-list .tr-ppl { overflow: visible; }
/* Единый размер аватаров причастных на доске = как в списке (26px / наблюдатели 22px). */
.tw-card .tr-ppl .tp-av { width: 26px; height: 26px; }
.tw-card .tr-ppl .tp-watch .tp-av { width: 22px; height: 22px; }

/* линза ролей: Мне / Я поставил / Наблюдаю */
.tasks-list .task-lens { list-style: none; display: flex; gap: 5px; padding: 8px 6px 10px;
  /* Sticky-бар фильтра ролей: фон = фон КОЛОНКИ (--panel), а не --bg (тот темнее панели →
     читался «тёмной полосой» над списком). Совпадает с .tasks-col → полоса не выделяется. */
  position: sticky; top: 0; background: var(--panel); z-index: 2;
  overflow-x: auto; overflow-y: hidden; flex-wrap: nowrap; scrollbar-width: none; -ms-overflow-style: none; }
.tasks-list .task-lens::-webkit-scrollbar { height: 0; display: none; }
.tasks-list .task-lens-btn { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  padding: 6px 10px; border-radius: 8px; border: 1px solid var(--line); background: transparent;
  color: var(--muted); cursor: pointer; font-size: 11px; white-space: nowrap; }
.tasks-list .task-lens-btn svg.ic { width: 14px; height: 14px; flex: none; }
.tasks-list .task-lens-btn .tl-label { white-space: nowrap; }
.tasks-list .task-lens-btn.active { background: var(--panel-2); color: var(--text); border-color: var(--primary); }
/* Двойной счётчик чипа: [К выполнению] · [В работе и тестирование]. Первый — приглушён
   (очередь), второй — акцент/жирный (активная работа). Разделены тонким хэйрлайном. */
.tasks-list .task-lens-n { flex: none; display: inline-flex; align-items: center; gap: 5px;
  background: var(--panel); border-radius: 6px; padding: 1px 6px; font-size: 10px; line-height: 1.4; }
.tasks-list .task-lens-n .tln-todo { color: var(--muted); }
.tasks-list .task-lens-n .tln-work { color: var(--primary); font-weight: 600; }
.tasks-list .task-lens-n .tln-sep { width: 1px; height: 9px; border-radius: 1px; background: var(--line); }
/* Число внутри выбранной «линзы» лежит на заливке вида (§2C: --acc-grad) под БЕЛЫМИ цифрами: подложка числа
   ТЕМНИТ заливку, а не белит её (белая 18 % давала 2.57/3.47 в тёмном «Штиле», свип волны 3, 20.10.2026);
   то же решение, что в светлой теме базы и в «Глубине» — одно на все шаблоны. */
.tasks-list .task-lens-btn.active .task-lens-n { background: var(--cm-0b1020-24, rgba(11,16,32,.24)); }
.tasks-list .task-lens-btn.active .task-lens-n .tln-todo { color: rgba(255,255,255,.86); }
.tasks-list .task-lens-btn.active .task-lens-n .tln-work { color: #fff; }
.tasks-list .task-lens-btn.active .task-lens-n .tln-sep { background: rgba(255,255,255,.38); }
/* Поиск по столбику «Мои задачи» */
.tasks-list .task-searchbar { list-style: none; display: flex; align-items: center; gap: 7px; margin: 0 6px 8px; padding: 7px 10px; border-radius: 10px; background: var(--panel-2); border: 1px solid var(--line); }
.tasks-list .task-searchbar .tsb-ic { display: inline-flex; color: var(--muted); }
.tasks-list .task-searchbar .tsb-ic svg.ic { width: 15px; height: 15px; }
/* min-width НЕ 0: поле обязано вмещать читаемый запрос, иначе сегмент «Название|Везде»
   ужимал его до «вы…» в узком столбике (CLIE-469). Не влезли вместе — сегмент переносится. */
.tasks-list .task-search-input { flex: 1; min-width: 96px; border: none; background: transparent; color: var(--text); font-size: 13px; outline: none; padding: 0; }
.tasks-list .task-search-input::placeholder { color: var(--muted); }
.tasks-list .task-searchbar .tsb-clr { flex: none; display: inline-flex; padding: 0; border: none; background: transparent; color: var(--muted); cursor: pointer; }
.tasks-list .task-searchbar .tsb-clr:hover { color: var(--text); }
.tasks-list .task-searchbar .tsb-clr svg.ic { width: 13px; height: 13px; }
/* Поиск по рельсу «Проекты» (0286) — тот же вид, что поиск столбика задач */
.projects-list .proj-searchbar { list-style: none; display: flex; align-items: center; gap: 7px; margin: 0 6px 8px; padding: 7px 10px; border-radius: 10px; background: var(--panel-2); border: 1px solid var(--line); }
.projects-list .proj-searchbar .tsb-ic { display: inline-flex; color: var(--muted); }
.projects-list .proj-searchbar .tsb-ic svg.ic { width: 15px; height: 15px; }
.projects-list .proj-search-input { flex: 1; min-width: 0; border: none; background: transparent; color: var(--text); font-size: 13px; outline: none; padding: 0; }
.projects-list .proj-search-input::placeholder { color: var(--muted); }
.projects-list .proj-searchbar .tsb-clr { flex: none; display: inline-flex; padding: 0; border: none; background: transparent; color: var(--muted); cursor: pointer; }
.projects-list .proj-searchbar .tsb-clr:hover { color: var(--text); }
.projects-list .proj-searchbar .tsb-clr svg.ic { width: 13px; height: 13px; }
/* Свой аккуратный крестик × вместо нативного webkit-сброса type=search — один чистый affordance */
.tasks-list .task-search-input::-webkit-search-cancel-button,
.projects-list .proj-search-input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
/* Плашка «скрыто фильтром компании» (вариант A): объясняет пустой столбик и снимает фильтр одним кликом. */
.tasks-list .task-company-hidden { list-style: none; display: flex; align-items: center; gap: 8px; margin: 0 6px 8px; padding: 8px 10px; border-radius: 10px; background: var(--panel-2); border: 1px dashed var(--line); font-size: 12px; color: var(--muted); }
.tasks-list .task-company-hidden .tch-txt { flex: 1 1 auto; display: inline-flex; align-items: center; gap: 6px; line-height: 1.3; min-width: 0; }
.tasks-list .task-company-hidden .tch-txt svg.ic { width: 14px; height: 14px; flex: none; }
.tasks-list .task-company-hidden .tch-txt b { color: var(--text); font-weight: 600; }
.tasks-list .task-company-hidden .tch-showall { flex: none; background: transparent; border: none; color: var(--primary); font-weight: 600; font-size: 12px; cursor: pointer; padding: 2px 4px; white-space: nowrap; }
.tasks-list .task-company-hidden .tch-showall:hover { text-decoration: underline; }
/* Та же плашка «скрыто фильтром компании», но в пространстве задач (доска/список/плитки/таймлайн). */
.tw-company-hidden { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; padding: 8px 12px; border-radius: 10px; background: var(--panel-2); border: 1px dashed var(--line); font-size: 12px; color: var(--muted); }
.tw-company-hidden .tch-txt { flex: 1 1 auto; display: inline-flex; align-items: center; gap: 6px; line-height: 1.3; min-width: 0; }
.tw-company-hidden .tch-txt svg.ic { width: 14px; height: 14px; flex: none; }
.tw-company-hidden .tch-txt b { color: var(--text); font-weight: 600; }
.tw-company-hidden .tch-showall { flex: none; background: transparent; border: none; color: var(--primary); font-weight: 600; font-size: 12px; cursor: pointer; padding: 2px 4px; white-space: nowrap; }
.tw-company-hidden .tch-showall:hover { text-decoration: underline; }

/* списки в модалках (контакты/задачи) не должны растягиваться на весь экран */
.contacts-list.in-modal,
.tasks-list.in-modal { flex: none; max-height: 62vh; padding: 2px; }
/* contacts-clip-1 · «Мои контакты»: список (max-height 62vh) срезался жёсткой горизонталью посередине
   строки, под срезом — пустой нижний отступ тела окна (18 px в «Глубине», 14 в «Штиле»). Тот же приём,
   что у тела окна «Компания» (.co-body, app.js companyEnsureStyles): затухание 18 px у кромки и такой же
   запас внизу прокрутки, тело окна без нижнего отступа — затухание доходит до края окна. */
@media (min-width: 761px) {
  .contacts-list.in-modal {
    padding-bottom: 18px;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 18px), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 18px), transparent);
  }
  #contactsModal .modal-body { padding-bottom: 0; }
}
/* contacts-list-clipped-empty-band · телефон: окно во весь экран, а список держал max-height 62vh (523 из 844 px)
   и срезался по y≈678, под срезом пусто до низа экрана. Список берёт всю высоту тела окна и остаётся
   прокручиваемым сам (ленивая дорисовка слушает scroll #contactsList), низ тает тем же затуханием 18 px. */
@media (max-width: 760px) {
  #contactsModal .modal-body { display: flex; flex-direction: column; min-height: 0; padding-bottom: 0; }
  .contacts-list.in-modal {
    flex: 1 1 auto; min-height: 0; max-height: none; padding-bottom: 18px;
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 18px), transparent);
    mask-image: linear-gradient(to bottom, #000 calc(100% - 18px), transparent);
  }
}

/* поля модалки задачи */
.task-fields-row { display: flex; gap: 10px; }
.task-fields-row .field { flex: 1; min-width: 0; }
.task-conv-row {
  display: flex; align-items: center; gap: 8px; margin-top: 10px;
  font-size: 13px; color: var(--muted); cursor: pointer;
}
.task-conv-row input { width: auto; margin: 0; }
/* подвал модалки задачи — две кнопки в ряд (общий .modal-foot .primary тянет на 100%) */
#taskModal .modal-foot { display: flex; gap: 10px; }
#taskModal .modal-foot .primary { width: auto; flex: 1; }
#taskModal .modal-foot .ghost { flex: none; }

/* ---- перетаскиваемые границы колонок ------------------------------------
   Ничего лишнего «на виду»: зона захвата прозрачна и сидит ровно на шве
   между колонками. Тонкая акцентная линия проявляется ТОЛЬКО при наведении
   на шов (или во время перетаскивания). Двойной клик — сброс ширины. */
.col-resizer {
  position: absolute; top: 0; bottom: 0; right: -4px;
  width: 9px;               /* удобная зона захвата, перекрывает шов */
  z-index: 15; cursor: col-resize;
  touch-action: none;       /* чтобы pointermove не превращался в скролл/жест */
  -webkit-user-select: none; user-select: none;
}
.col-resizer::after {       /* и есть та самая линия, что показываем у шва */
  content: ""; position: absolute; top: 0; bottom: 0; left: 50%;
  width: 2px; transform: translateX(-50%);
  background: var(--primary); border-radius: 2px;
  box-shadow: 0 0 8px -1px var(--glow);
  opacity: 0; transition: opacity .15s ease;
}
.col-resizer:hover::after,
.col-resizer.dragging::after { opacity: 1; }
/* 🔴 CLIE-1150: шов упёрся в потолок — линия ЖЕЛТЕЕТ прямо в жесте, а не молчит. Молчащий
   упор человек читает как «ширина не меняется, функция пропала»; слова и выход прилетают
   тостом на отпускании (winCapExit в app.js), но ответ обязан быть УЖЕ под курсором. */
.col-resizer.at-cap::after { background: var(--warn); box-shadow: none; opacity: 1; }
body.col-resizing .col-resizer.at-cap { cursor: not-allowed; }
/* во время перетаскивания курсор/без-выделения на весь экран */
body.col-resizing { cursor: col-resize; -webkit-user-select: none; user-select: none; }

/* ══ Раздвижные окна (initWindowResize в app.js) — ширина модалок, шторок и внутренних
   колонок. Вид/курсор/скрытие на мобиле наследуем от .col-resizer выше: язык у всех
   «швов» продукта ОДИН. Здесь только посадка:
   • .cc-wgrip — хваталка на кромке ДИАЛОГА или на шве КОЛОНКИ: её left/top/height ставит
     JS по реальной геометрии окна, поэтому гасим right/bottom из базового правила. Живёт
     она в оверлее (а не внутри окна) — иначе легла бы на полосу прокрутки содержимого;
   • .cc-wgrip-in — хваталка боковой ШТОРКИ: сидит на её внутренней (левой) кромке, где
     полосы прокрутки нет, поэтому обычная посадка через CSS. ══ */
.cc-wgrip { right: auto; bottom: auto; width: 11px; z-index: 40; }
/* 🔴 Сенсорный ввод: медиазапрос ниже прячет хваталки только на ≤720px, а планшет — 1024+.
   Прозрачная полоса с `touch-action:none` вдоль кромки окна съедала бы там свайп-прокрутку,
   начатую пальцем у края карточки. Тянуть окно пальцем всё равно незачем — прячем. */
@media (pointer: coarse) { .cc-wgrip { display: none; } }
.cc-wgrip-in { left: 0; top: 0; bottom: 0; height: auto; width: 12px; }
/* • .cc-wgrip-ir — та же внутренняя хваталка, но у ПРАВОЙ кромки: так тянутся плавающие
     окна, прибитые к своему left/top (PiP созвона комнаты) — они растут вправо. */
.cc-wgrip-ir { left: auto; right: 0; }
/* линия шва у окон чуть короче кромки — так рама читается как рама, а не как «разрез» */
.cc-wgrip::after { top: 10px; bottom: 10px; }
.contacts-head-actions { display: flex; gap: 6px; }
/* статус формы «Новый контакт» */
.addcontact-status { margin: 4px 0 0; }
.contacts-list { list-style: none; margin: 0; padding: 6px; overflow-y: auto; flex: 1; min-height: 0; }
.contacts-empty { padding: 14px; line-height: 1.4; }

/* заголовки секций: «В ПРИЛОЖЕНИИ · N» (зелёный), «ИЗ ТЕЛЕФОННОЙ КНИГИ» (серый), «📌 ЗАКРЕПЛЁННЫЕ» */
.contacts-list .contact-section-title {
  list-style: none; padding: 12px 10px 5px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
}
.contacts-list .contact-section-title:first-child { padding-top: 6px; }
/* contacts-caption-icon-1 · у каждой подписи секции — значок из набора (sectionHtml, app.js) в строку
   с текстом: «Закреплённые» — pin, «Уже в ClientsChat» — checkCircle, «Из телефонной книги» — contact.
   Цвет — у всей подписи, значок берёт его через currentColor; зелёный «уже здесь» остаётся смысловым. */
.contacts-list .contact-section-title:has(> svg.ic) { display: flex; align-items: center; gap: 5px; }
.contacts-list .contact-section-title > svg.ic { flex: none; width: 12px; height: 12px; }
.contacts-list .contact-section-title:has(> .cst-inapp) { color: var(--urg-done); }
.contacts-list .contact-section-title:has(> .cst-book)  { color: #6B7280; }
.contacts-list .contact-section-title:has(> .cst-pin)   { color: var(--primary-2); }

/* строка контакта */
.contacts-list .contact-row {
  display: flex; align-items: center; gap: 11px;
  padding: 7px 10px; border-radius: 12px; margin-bottom: 1px;
  border: 1px solid transparent; transition: background .12s;
}
.contacts-list .contact-row.matched { cursor: pointer; }
.contacts-list .contact-row:hover { background: var(--panel-2); }

/* плоский цветной аватар-инициалы (цвет задаётся inline по имени) */
.contacts-list .contact-avatar {
  position: relative;
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  color: #fff; font-weight: 600; font-size: 14px;
  display: flex; align-items: center; justify-content: center;
  background-size: cover; background-position: center;
}
.contacts-list .contact-row.unmatched .contact-avatar { opacity: .92; }
.contacts-list .contact-avatar.has-img { color: transparent; }

/* зелёная точка-индикатор (правый-нижний угол) у matched */
.contacts-list .contact-online-dot {
  position: absolute; right: -1px; bottom: -1px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--urg-done); border: 2px solid var(--panel);
  box-shadow: 0 0 0 1px rgba(0,0,0,.15);
}

.contacts-list .contact-body { min-width: 0; flex: 1; }
.contacts-list .contact-name {
  font-weight: 600; font-size: 14px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* «Пригласить» — лёгкая ссылка-текст (без рамки/фона) */
.contacts-list .contact-invite-link {
  flex: none; cursor: pointer;
  color: var(--cm-818cf8, #818CF8); font-weight: 600; font-size: 13px;
  padding: 4px 4px; border: none; background: none; border-radius: 6px;
  transition: color .12s, background .12s;
}
.contacts-list .contact-invite-link:hover { color: var(--cm-a5b0fa, #a5b0fa); text-decoration: underline; }
.contacts-list .contact-invite-link:focus-visible { outline: none; background: var(--panel-2); }
/* 👋 CLIE-961: уже звали — слово «Позвать ещё» спокойнее (состояние, а не призыв),
   а под именем стоит честная строка «Приглашён <когда>». */
.contacts-list .contact-invite-link.done { color: var(--muted); font-weight: 500; }
.contacts-list .contact-sub { margin-top: 1px; font-size: 11.5px; line-height: 1.25; }

/* иконка «сообщение» (accent) у matched-строк */
.contacts-list .contact-msg-btn {
  flex: none; border: none; background: transparent; cursor: pointer;
  color: var(--primary-2); padding: 5px; border-radius: 9px; line-height: 0;
  opacity: .85; transition: opacity .12s, background .12s, color .12s;
}
.contacts-list .contact-msg-btn:hover { opacity: 1; color: #fff; background: var(--acc-grad); }

/* ── имя на ВСЮ ширину; действия (Пригласить/написать/пин) скрыты и появляются ПРИ
   НАВЕДЕНИИ поверх правого края (плавное затемнение фона), чтобы имя не обрезалось ── */
.contacts-list .contact-row { position: relative; }
.contacts-list .contact-body { flex: 1; min-width: 0; }
.contacts-list .contact-actions {
  position: absolute; right: 6px; top: 0; bottom: 0;
  display: flex; align-items: center; gap: 2px;
  padding-left: 34px; opacity: 0; pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--panel-2) 44%);
  transition: opacity .12s;
}
.contacts-list .contact-row:hover .contact-actions { opacity: 1; pointer-events: auto; }

/* ── Скроллбары: СКРЫТЫ по умолчанию, ПОЯВЛЯЮТСЯ при наведении на блок (владелец, 2026-07-15).
   Ширину на :hover НЕ меняем (иначе контент дёргается) — держим ПОСТОЯННЫЙ прозрачный жёлоб, а
   видимость даём ЦВЕТОМ бегунка: прозрачный → видимый. :hover поднимается по предкам, поэтому
   бегунок показывается у скролл-блока под курсором. Цвета через токены → адаптивно к теме.
   (border+padding-box = бегунок с отступом, визуально тоньше жёлоба.) ── */
*::-webkit-scrollbar { width: 11px; height: 11px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: transparent; border-radius: 8px; border: 3px solid transparent; background-clip: padding-box; transition: background .15s; }
*:hover::-webkit-scrollbar-thumb { background: var(--text-dim); background-clip: padding-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--muted); background-clip: padding-box; }
*::-webkit-scrollbar-corner { background: transparent; }
/* Firefox: тот же приём (Safari 18+ идёт по ::-webkit- выше). Жёлоб постоянный (thin), цвет
   бегунка прозрачный → видимый на hover блока. */
@supports (-moz-appearance: none) {
  * { scrollbar-width: thin; scrollbar-color: transparent transparent; }
  *:hover { scrollbar-color: var(--text-dim) transparent; }
}
/* Рельс (96px) — ИСКЛЮЧЕНИЕ из правила выше: жёлоб скрыт ПОЛНОСТЬЮ, без резервирования места.
   Постоянный 11px-жёлоб на узкой иконочной навигации сдвигал иконки влево, а справа зияла
   пустая полоса (жалоба владельца «справа лишнее пространство»). Рельс скролл не показывает
   вовсе (Telegram/macOS-sidebar): иконки центрируются во всю ширину — ровно. Прокрутка
   колёсиком/тачпадом сохраняется. */
.chat-rail, .rail-scroll { scrollbar-width: none; -ms-overflow-style: none; }
.chat-rail::-webkit-scrollbar, .rail-scroll::-webkit-scrollbar { width: 0; height: 0; display: none; }

/* ── 🔴🔴 CLIE-620 · ВЛОЖЕННЫЙ СКРОЛЛ ОБЯЗАН СЕБЯ ПОКАЗАТЬ (.cc-scroll-in) ─────────────
   Правило продукта, не стиль одного списка. Бегунок у нас ПРОЗРАЧНЫЙ до наведения (см.
   блок «Скроллбары» выше — решение владельца, не трогаем). Значит любой список, зажатый
   в max-height ВНУТРИ уже скроллящейся панели, для человека выглядит как «обрезано и
   не достать»: ровно на этом владелец обжигался дважды — чипы разделов уезжали за правый
   край при скрытой полосе (лечили масками .more-l/.more-r, см. convTabsEdges в app.js) и
   участники группы резались пополам (CLIE-620).
   Доктрина:
     1) список внутри скроллящейся панели НЕ капим — он растёт, скроллит внешняя панель;
     2) кап оправдан ТОЛЬКО у каталога/поисковой выдачи, которая иначе растянет панель на
        тысячи пикселей. Тогда вешаем .cc-scroll-in — вертикальный брат .more-l/.more-r:
        бегунок виден ВСЕГДА (не только под курсором), а край мягко тает, пока за ним
        реально есть строки. Классы .more-t/.more-b ставит ccScrollInEdges() в app.js. */
.cc-scroll-in { overflow-y: auto; overscroll-behavior: contain; }
.cc-scroll-in::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 40%, transparent); background-clip: padding-box; }
.cc-scroll-in::-webkit-scrollbar-thumb:hover { background: var(--muted); background-clip: padding-box; }
@supports (-moz-appearance: none) {
  .cc-scroll-in { scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--muted) 40%, transparent) transparent; }
}
/* 🔴🔴 CLIE-1116 · КРАЙ ТАЕТ КРАСКОЙ, А НЕ МАСКОЙ — маска на САМОМ прокручиваемом блоке
   съедала строки. Замер пикселей скрина владельца («проблема в вёрстке… когда выбираю кому
   напомнить»): в списке людей провал ЧИСТО ЧЁРНЫЙ (0,0,0) ровно в высоту списка — 170 CSS px
   при `max-height:172px` — с растушёвкой ровно по 26px с обоих концов, то есть формой
   один-в-один `mask-image` этого правила; три человека (Вика · Александр · Алёна) просто
   исчезали, а верхняя строка была наполовину затемнена. `mask-image` вместе с `overflow:auto`
   уводит блок в отдельный слой композитора, и там, где маска непрозрачна, слой у владельца
   рисуется чёрным. У нас в headless (программный растеризатор) того же слоя не возникает —
   поэтому «по коду» и на нашем скрине дефекта не видно, а у человека список чёрный.
   Лечение КЛАССА: ничего не «выключать» маской. Край тает обычным градиентом-накладкой на
   липких псевдоэлементах: это простая КРАСКА в 26px у самой кромки — она не может съесть
   содержимое ни в одном движке, и даже если цвет подложки угадан неточно, это лёгкий оттенок,
   а не провал. Цвет берётся ЗАМЕРОМ фактической подложки (`ccScrollInFade` → `--cc-fade`),
   а не догадкой про `--panel`: списки живут и в модалке, и в поповере, и в шторке.
   🔴 Псевдоэлементы не занимают места (отрицательное поле гасит их высоту) — раскладка
   списков остаётся прежней, а `pointer-events:none` оставляет строки под ними кликабельными. */
.cc-scroll-in.more-t::before, .cc-scroll-in.more-b::after {
  content: ""; display: block; position: sticky; left: 0; right: 0; z-index: 3;
  height: 26px; flex: none; pointer-events: none; }
.cc-scroll-in.more-t::before { top: 0; margin-bottom: -26px;
  background: linear-gradient(to bottom, var(--cc-fade, var(--panel)) 18%, transparent); }
.cc-scroll-in.more-b::after { bottom: 0; margin-top: -26px;
  background: linear-gradient(to top, var(--cc-fade, var(--panel)) 18%, transparent); }
/* 🔴 13.10.2026 · ГОРИЗОНТАЛЬНЫЙ БРАТ: прокручиваемый РЯД (вкладки канала, шапка на ступени tb-fit-7)
   срезал слово краем посреди буквы («Автоответ|», «Заявка на токен|») и ничем не говорил, что листается.
   Классы more-l/more-r ставит ccRowFadeEdges (реестр ROW_FADE_SEL в app.js), цвет — замер подложки
   (`--cc-fade`). Псевдоэлемент НЕ занимает места: поле гасит его ширину и зазор ряда (`--cc-row-gap`),
   поэтому ряд не прыгает, когда край появляется или гаснет. Маской нельзя: у шапки фон, радиус и тень —
   сама плита, маска съела бы её край (урок CLIE-1116). */
:root :is(.cc-rowfade, .topbar.tb-fit-7.cc-rowfade).more-l::before,
:root :is(.cc-rowfade, .topbar.tb-fit-7.cc-rowfade).more-r::after {
  content: ""; display: block; position: sticky; z-index: 3; flex: none; align-self: stretch;
  top: auto; bottom: auto; width: 26px; height: auto; inset-block: auto; border-radius: 0; box-shadow: none;
  pointer-events: none;
}
:root :is(.cc-rowfade, .topbar.tb-fit-7.cc-rowfade).more-l::before {
  left: calc(-1 * var(--cc-row-pad-l, 0px)); right: auto; order: -1; margin: 0 calc(-26px - var(--cc-row-gap, 0px)) 0 0;
  background: linear-gradient(to right, var(--cc-fade, var(--panel)) 18%, transparent);
}
:root :is(.cc-rowfade, .topbar.tb-fit-7.cc-rowfade).more-r::after {
  right: calc(-1 * var(--cc-row-pad-r, 0px)); left: auto; order: 99; margin: 0 0 0 calc(-26px - var(--cc-row-gap, 0px));
  background: linear-gradient(to left, var(--cc-fade, var(--panel)) 18%, transparent);
}

/* ---- тост (напр. «Ссылка скопирована») ---- */
.cc-toast {
  /* 🔔🔔 CLIE-1146·2 · КРОМКА У ТОСТА — НИЖНЯЯ (владелец 15.09: «Уведомления которые были
     внизу теперь переехали вверх… Верни их положение как было. Те что наверху которые там
     всегда и так были, их не трогай»). Верх занят и занят давно: там живут heads-up
     плашки `.cc-inapp-wrap` — «пришло событие». Тост отвечает на ДЕЙСТВИЕ человека и
     годами стоял у нижней кромки, рядом с рукой. Точное место всё так же считает
     `ccToastPlace` (обход поля, в которое печатают) — ему и принадлежит `style.bottom`. */
  position: fixed; left: 50%; bottom: calc(env(safe-area-inset-bottom, 0px) + 26px); top: auto; transform: translateX(-50%) translateY(12px);
  /* 🔴 CRMC-30/1: был z-index 90 — НИЖЕ шторки сделки (.deal-backdrop 120 / .deal-drawer 121),
     поэтому каждый toast(...) из карточки сделки («Не удалось сохранить», ошибки Интеллекта)
     рисовался ПОД шторкой и человек видел «кнопка мёртвая». Тост — самый верхний слой.
     🔴🔴 CLIE-692: тост стоит НАД полосой динамических слоёв (CC_Z_BASE=300000 в app.js, растёт
     по порядку открытия). Он говорит о том, ЧТО ТОЛЬКО ЧТО ПРОИЗОШЛО, — прятать его под тем,
     что это вызвало, нельзя; поэтому у него не «число побольше», а свой ярус НАД полосой. */
  /* 🔴 CLIE-1146·4: ширина по СОДЕРЖИМОМУ с потолком. Без `max-content` флекс с бейджем
     схлопывал текстовую колонку до самого узкого слова, и «Задача отправлена в ИИ»
     печаталось лесенкой в три строки с разрывом посреди слова. */
  z-index: 2000000000; width: max-content; max-width: min(86vw, 460px);
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 12px;
  padding: 11px 12px; font-size: 13px; line-height: 1.35;
  box-shadow: 0 12px 32px -10px rgba(0,0,0,.6);
  opacity: 0; pointer-events: none;
  transition: opacity .18s, transform .18s;
  overflow-wrap: break-word; text-align: left;
  /* 🔴 ЗВОН-32: тост смахивается ВБОК (см. ccToastSwipe в app.js). `pan-y` отдаёт браузеру
     вертикальную прокрутку, а горизонталь забираем себе — иначе на iOS свайп вбок уходит в
     системное «назад», а не в жест плашки. Выделение текста на время перетаскивания только
     мешает: тост живёт 2 секунды и не для копирования. */
  touch-action: pan-y; -webkit-user-select: none; user-select: none;
}
/* 🔔🔔 CLIE-1146·4 · АНАТОМИЯ ТОСТА — ТА ЖЕ, ЧТО У ПЛАШЕК ПРОДУКТА (владелец 16.09: «ну
   вот это не наш дизайн»). Бейдж · заголовок · крестик — ровно как у heads-up `.cc-inapp`
   рядом и как у `CcPlateRow` в приложении. Голая центрированная строка 13px выглядела
   системным алертом чужой ОС, а не нашим уведомлением. */
/* 🔴 CLIE-1146·4·2 (владелец: «не ровно текст стоит»): середина строки совпадает с
   серединой бейджа — у плашки продукта это ИЗМЕРЯЕТСЯ (прибор сверяет центры), а не
   ставится на глаз. */
.cc-toast { display: flex; align-items: center; gap: 12px; }
.cc-toast-badge {
  flex: none; width: 32px; height: 32px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  font-size: 17px; line-height: 1;
  background: color-mix(in srgb, var(--accent) 14%, transparent); color: var(--accent);
}
.cc-toast-badge svg { width: 18px; height: 18px; }
.cc-toast-text { min-width: 0; flex: 1 1 auto; overflow-wrap: break-word;
  font-size: 15px; font-weight: 600; letter-spacing: -.3px; line-height: 1.2; color: var(--text); }
.cc-toast-close { flex: none; border: 0; background: transparent; color: var(--muted); font: inherit; font-size: 20px; line-height: 1; width: 30px; height: 30px; border-radius: 50%; cursor: pointer; }
.cc-toast-close:hover { background: color-mix(in srgb, var(--text) 6%, transparent); color: var(--text); }
.cc-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto; }

/* Тост с ДЕЙСТВИЕМ («Таймер на паузе → Снять „В работе“»). Не отдельный компонент, а второй
   слот того же тоста: класс вешает toast() при наличии action. Центровка текста уступает
   место флексу, иначе подпись и кнопка слипаются. Цвет — через --accent, поэтому светлая
   тема (там --accent переопределён) подхватывается сама, без отдельного правила. */
.cc-toast.has-act { gap: 10px; padding-right: 6px; }

.cc-toast-act {
  flex: none; appearance: none; border: 0; background: transparent;
  /* 🔴 На тёмной панели тоста чистый --accent (#667eea на #262b36) даёт контраст 3.87 —
     ниже порога WCAG AA 4.5 для текста 13px (послабление 3:1 действует только от 18.66px
     bold). Осветляем акцент к белому; светлая тема ниже возвращает чистый --accent, там
     на белом фоне он и так даёт 5.78. Измерено в браузере, а не на глаз. */
  color: color-mix(in srgb, var(--accent) 62%, #fff);
  font: inherit; font-weight: 600; cursor: pointer;
  padding: 5px 10px; border-radius: 8px; white-space: nowrap;
  transition: background var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.cc-toast-act:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.cc-toast-act:active { transform: scale(.97); }
.cc-toast-act:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Длинное слово с действиями (класс ставит toast(), когда текст рядом с кнопками длиннее двух
   строк): первая строка — бейдж · текст · крестик, ниже — кнопки под текстом. Разрыв строки
   делает `::after` во всю ширину; первая кнопка встаёт под начало текста (бейдж 32 + зазор 10
   − свой отступ 10). */
.cc-toast.stack { flex-wrap: wrap; align-items: flex-start; row-gap: 4px; }
/* первая строка текста — на середине бейджа: (32 − 18) / 2 */
.cc-toast.stack .cc-toast-text { flex: 1 1 0; padding-top: 7px; }
.cc-toast.stack .cc-toast-close { order: 1; }
.cc-toast.stack::after { content: ""; order: 1; flex-basis: 100%; height: 0; }
.cc-toast.stack .cc-toast-act { order: 2; }
.cc-toast.stack .cc-toast-act:first-of-type { margin-left: 32px; }

/* ---- thread ---- */
/* position:relative — система координат для плавающей даты (#dateFloat) поверх ленты */
/* min-width:0 — тред это грид-элемент трека minmax(--thread-min,1fr): без него
   его min-content (широкие пузыри/пиннед-бар/шапка) не давал бы треку усохнуть до
   трека и распирал сетку в overflow (см. --thread-min в .chat, CLIE-265). */
.thread { display: flex; flex-direction: column; min-height: 0; min-width: 0; position: relative; }
.thread-head {
  display: flex; align-items: center; justify-content: space-between;
  height: var(--head-h); flex: none;
  /* шапка чата = белая (--panel), как остальные шапки столбцов; лента ниже остаётся
     на градиенте .thread. Иначе тред-шапка показывала бы фон .thread (в светлой —
     голубоватый градиент) и отличалась от «Проекты/Мои задачи/Чаты». */
  background: var(--panel);
  padding: 0 18px; border-bottom: 1px solid var(--line);
}
.thread-title { font-weight: 700; font-size: 16px; }
/* шапка кликабельна (cursor/title ставятся в openConversation) → лёгкая подсветка имени */
.thread-title[style*="pointer"]:hover { text-decoration: underline; text-underline-offset: 3px; }
.thread-av[style*="pointer"]:hover { filter: brightness(1.08); }
/* аватар беседы в шапке чата (группа — своя аватарка/постер видео, личка — собеседник) */
.thread-av {
  width: 38px; height: 38px; border-radius: 50%; flex: none;
  background: var(--acc-grad); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 14px;
}
.thread-av.has-img { background-size: cover; background-position: center; color: transparent; }
.thread-av.hidden { display: none; }
/* Заголовок беседы: имя на всю ширину (первая строка), а МЕТКА ПРОЕКТА (к какому проекту
   относится чат) — ОТДЕЛЬНОЙ строкой ниже, в одну строку с подписью (.thread-meta-row), чтобы
   длинное имя не резалось чипом. Видна только при фильтре «Все проекты» (ставит openConversation). */
.thread-titlewrap { min-width: 0; }
.thread-title-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.thread-title-row #threadTitle { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thread-meta-row { display: flex; align-items: center; gap: 8px; min-width: 0; margin-top: 2px; }
.thread-meta-row #threadSub { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thread-proj { flex: none; max-width: 60%; display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 600; line-height: 1.35;
  letter-spacing: .01em; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); }
.thread-proj.hidden { display: none; }
.thread-proj .pj-dot { flex: none; width: 7px; height: 7px; border-radius: 50%;
  background: var(--cpj, var(--primary));
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--cpj, var(--primary)) 20%, transparent); }
.thread-proj .pj-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* кнопки действий в шапке (звонки + настройки группы) — держим рядом справа */
.head-actions { display: flex; align-items: center; gap: 8px; flex: none; }
/* ── «Умная шапка» (вариант C): кнопка, которой не хватило ширины, уезжает в «⋯» ──
   Класс ставит замер fitChatHeader() — он НЕ конфликтует с собственным .hidden кнопки
   (прогрессивное раскрытие: «Что я пропустил» появляется только при непрочитанных). */
.head-actions .hdr-fold { display: none !important; }
/* Крупные ПОДПИСАННЫЕ кнопки в карточке беседы (паритет с карточкой чата в приложении):
   ничего не надо угадывать по значку, действие = та же кнопка шапки. */
.cc-cardacts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin: 14px 0 18px; }
.cc-cardact { display: inline-flex; flex-direction: column; align-items: center; gap: 6px;
  width: 88px; padding: 10px 4px 8px; background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 12px; cursor: pointer;
  transition: background .14s ease, border-color .14s ease, transform .12s ease; }
.cc-cardact:hover { background: var(--hover); border-color: var(--line-strong, var(--line)); }
.cc-cardact:active { transform: scale(.97); }
.cc-cardact .cc-cardact-ic { display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; color: var(--text); }
.cc-cardact .cc-cardact-ic .ic, .cc-cardact .cc-cardact-ic svg { width: 20px; height: 20px; }
.cc-cardact .cc-cardact-lb { font-size: 11px; line-height: 1.15; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }

/* Строка меню «⋯»: иконка · слово · значение (вкл/выкл) · скрепка «в шапке». */
.tc-pop .hdr-row { gap: 10px; padding: 9px 10px; }
.tc-pop .hdr-row .hdr-ic { display: inline-flex; align-items: center; justify-content: center;
  width: 18px; flex: none; color: var(--muted); }
.tc-pop .hdr-row .hdr-ic .ic, .tc-pop .hdr-row .hdr-ic svg { width: 17px; height: 17px; }
.tc-pop .hdr-row .tc-pop-name { flex: 1 1 auto; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.tc-pop .hdr-row .hdr-val { flex: none; font-size: 11.5px; color: var(--muted); }
/* Значение ВКЛЮЧЁННОГО режима — акцентом (паритет с приложением: `color: cc.accent`).
   «Исчезающие сообщения · 1 час» обязано бросаться в глаза: это режим, который физически
   уничтожает написанное у обоих участников. Выключенное остаётся тихим «выкл». */
.tc-pop .hdr-row .hdr-val.on { color: var(--primary-2); font-weight: 700; }
/* Скрепка: закреплённое — акцентом, остальное — еле заметный контур (подсказка «сюда можно
   закрепить», но экран она не отбирает). Появляется чётче на hover строки. */
.tc-pop .hdr-row .hdr-pin { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; border-radius: 6px; color: var(--muted); opacity: .3;
  transition: opacity .14s ease, color .14s ease, background .14s ease; }
.tc-pop .hdr-row .hdr-pin .ic, .tc-pop .hdr-row .hdr-pin svg { width: 13px; height: 13px; }
.tc-pop .hdr-row:hover .hdr-pin { opacity: .7; }
.tc-pop .hdr-row .hdr-pin:hover { opacity: 1; background: var(--hover); color: var(--text); }
.tc-pop .hdr-row .hdr-pin.on { opacity: 1; color: var(--primary); }
/* Тихая строка («Уже в CRM · нет доступа»): действие не моё, но строка НАЖИМАЕТСЯ и говорит
   причину тостом — слово приглушено токеном, а не прозрачностью (контраст обеих тем держит --muted). */
.tc-pop .hdr-row.dim .tc-pop-name { color: var(--muted); }
.call-btn {
  background: var(--acc-grad);
  border-color: transparent; color: #fff; font-weight: 600;
  box-shadow: 0 5px 14px -5px var(--glow);
}

.messages { flex: 1; min-width: 0; overflow-y: auto; padding: 18px; display: flex; flex-direction: column; gap: 8px; }
/* Ширина пузыря: 70% узкого треда, но НЕ шире --msg-max (иначе на широком мониторе/десктопе
   и в «Чате с ИИ» длинные сообщения растягивались во всю ширину — строки по 120+ символов
   не читаются, а «свои» (справа) уезжали к дальнему краю). Кап = комфортная мера ~85 символов,
   как в iMessage/Telegram. На узком экране min() отдаёт 70% — прежнее поведение не меняется. */
.msg { display: flex; flex-direction: column; min-width: 0; max-width: min(70%, var(--msg-max, 680px)); }
.msg.mine { align-self: flex-end; align-items: flex-end; }
.msg.theirs { align-self: flex-start; align-items: flex-start; }
.msg.system { align-self: center; align-items: center; max-width: min(80%, var(--msg-max, 680px)); }
.msg.system .meta { justify-content: center; text-align: center; }
/* 📄 СООБЩЕНИЕ-ДОКУМЕНТ (таблица или блок кода) БЕРЁТ ЛЕНТУ ЦЕЛИКОМ, а не долю.
   70% — мера ЧТЕНИЯ сплошного текста (~85 знаков в строке), и для неё правило остаётся.
   Но отчёт ИИ с таблицей покрытия — не текст: в 240px из 379px он превращается в лестницу
   по одному слову в ячейке. Потолок при этом никуда не девается (`--msg-max-doc`), чтобы на
   широком мониторе таблица не растягивалась бесконечно, — он просто считается ОТ ЛЕНТЫ. */
.msg:has(.md-tablewrap), .msg:has(.md-pre) { max-width: min(100%, var(--msg-max-doc, 1100px)); }
.bubble {
  padding: 9px 13px; border-radius: 14px; line-height: 1.35; position: relative;
  /* 📖 ЧИТАЕМОСТЬ ТЕКСТА ПЕРЕПИСКИ (жалоба владельца «сложно читается, давай как в телеге»).
     Тело сообщения читают дольше всего остального в продукте, поэтому оно НЕ живёт на
     глобальных 14px body: кегль 15px + межстрочный 1.45 (≈21.8px) — метрики Telegram
     Web/Desktop; трекинг слегка отрицательный, как любит SF Pro (-apple-system).
     Паритет с Flutter: там те же метрики в одном месте — CcMsgText (client/lib/theme/cc_theme.dart). */
  font-size: 15px; letter-spacing: -.01em;
  /* overflow-wrap:anywhere (не word-break:break-word) — рвёт длинные ссылки/пути
     И уменьшает min-content, чтобы длинный URL не раздувал грид-трек треда в overflow. */
  overflow-wrap: anywhere; word-break: break-word; min-width: 0;
  /* 🔴 Потолок ленты действует и на ПУЗЫРЬ, а не только на `.msg`: без него широкое
     содержимое (таблица, код) вытягивало пузырь наружу ленты — см. `.md-pre` выше. */
  max-width: 100%;
}
/* ⇄ Смена раскладки на сообщении (CLIE-288): аккуратная иконочная кнопка СНАРУЖИ пузыря
   (как swipe-reply) — НЕ перекрывает текст и не двигает ленту. Видна при наведении на
   сообщение; в состоянии .on (показана правильная раскладка) — залита и видна всегда.
   На тач-устройствах hover нет → показываем всегда (плюс есть пункт контекст-меню).

   🔴🔴 ДО КОНТРОЛА, ВИДИМОГО ПО НАВЕДЕНИЮ, ДОЛЖНА ВЕСТИ СПЛОШНАЯ ДОРОГА (жалоба владельца
   16.09.2026: «между ними есть пространство, и когда веду мышку, она слетает»).
   Замер на проде ДО правки (tools/laytoggle_hover_prod.js, настоящая мышь по 1px):
   из 25 шагов от пузыря к кнопке 17 приходились на `div.messages` — между пузырём и
   кнопкой было 5px ПУСТОТЫ (кнопка 26px при left:-31px), а пустота эта не принадлежит
   `.msg`. Как только курсор в неё входил, `.msg:hover` гас, кнопка получала
   `pointer-events:none` — и в точке, где она НАРИСОВАНА, под курсором уже был
   `div.messages` (opacity=0, pointer-events=none): кнопка убегала из-под руки и нажать
   её можно было только рывком мыши. Поэтому:
     1. Коробка кнопки ПРИМЫКАЕТ к пузырю (width 31px = круг 26 + 5 «моста»), а КРУГ
        рисует `::before` у дальнего края. Дорога сплошная, текст пузыря не перекрыт —
        мост кончается ровно на его кромке.
     2. `pointer-events` ВСЕГДА `auto`: доступность контрола не имеет права зависеть от
        `:hover` предка, который гаснет и от пересборки ленты (renderMessages рисует
        `#messages` целиком через innerHTML, после чего `:hover` не встаёт, пока мышь не
        двинется). Кнопка сама показывает себя по `:hover`/`:focus-visible`, а после
        пересборки под неподвижным курсором — по классу `.lay-hot` (app.js, layRehot). */
.lay-toggle {
  position: absolute; top: 3px; z-index: 4;
  display: inline-flex; align-items: center; justify-content: center;
  width: 31px; height: 26px; padding: 0;
  background: none; border: 0; box-shadow: none;
  color: var(--primary-2, var(--primary));
  cursor: pointer; opacity: 0; transform: scale(.78);
  pointer-events: auto;
  transition: opacity .14s ease, transform .14s cubic-bezier(.34,1.56,.64,1), color .12s ease;
}
/* сам круг — псевдоэлемент у дальнего от пузыря края; остаток коробки = мост к пузырю */
.lay-toggle::before {
  content: ""; position: absolute; top: 0; width: 26px; height: 26px; border-radius: 50%;
  background: color-mix(in srgb, var(--primary) 16%, var(--panel-2));
  border: 1px solid color-mix(in srgb, var(--primary) 30%, var(--line));
  box-shadow: 0 3px 10px -4px rgba(0,0,0,.4);
  transition: background .12s ease, border-color .12s ease, box-shadow .12s ease;
}
.lay-toggle > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } /* подпись только для тултипа/скринридера — кнопка иконочная */
.lay-toggle svg { width: 14px; height: 14px; flex: none; position: relative; }
.msg.theirs .lay-toggle { right: -31px; padding-left: 5px; }
.msg.theirs .lay-toggle::before { right: 0; }
.msg.mine .lay-toggle { left: -31px; padding-right: 5px; }
.msg.mine .lay-toggle::before { left: 0; }
.msg:hover .lay-toggle, .lay-toggle:hover, .lay-toggle:focus-visible, .lay-toggle.lay-hot, .lay-toggle.on { opacity: 1; transform: none; }
.lay-toggle:hover::before { background: color-mix(in srgb, var(--primary) 30%, var(--panel-2)); border-color: var(--primary); }
.lay-toggle:hover { color: var(--text); }
.lay-toggle.on::before { background: var(--primary); border-color: var(--primary); box-shadow: 0 3px 12px -3px color-mix(in srgb, var(--primary) 60%, transparent); }
.lay-toggle.on { color: #fff; }
@media (hover: none) { .lay-toggle { opacity: 1; transform: none; } }
/* 🔴🔴 ПУЗЫРЬ ОБЪЯВЛЯЕТ СВОИ ЧЕРНИЛА (задача «Контрастность», 10.09.2026).
   Пузырь СВОЕГО сообщения — это ЗАЛИТАЯ АКЦЕНТОМ поверхность внутри светлого/тёмного
   холста. Всё, что кладут в него потом (чип «Одноразовый», кнопка «разобрать речь»,
   цитата, превью ссылки, упоминание), по умолчанию красится токенами ХОЛСТА — и
   проваливается: замер живого прода дал `--muted` на индиго = 1.45:1 (светлая) и
   1.40:1 (тёмная) при норме AA 4.5. Ровно этот чип владелец и прислал скрином.
   Лечится это НЕ подкраской каждого нового элемента, а тем же приёмом, что у окна
   (канон contrast-runtime-audit: «поверхность взяла у темы фон — обязана взять и color»):
   поверхность объявляет НАБОР своих чернил, а вложенное берёт ИХ.
     --bub-ink      — основные чернила пузыря
     --bub-ink-dim  — приглушённые (подписи, вторая строка)
     --bub-tint     — подложка вложенного блока/чипа. 🔴 ВНУТРИ ЗАЛИВКИ ОНА ИДЁТ ТЕМНЕЕ
                      САМОЙ ЗАЛИВКИ (канон contrast-runtime-audit, CLIE-888·3):
                      осветляющая rgba(255,255,255,.14…26) поднимает подложку под белыми
                      чернилами и рушит контраст (замер: цитата 3.59:1 светлая / 2.70:1 тёмная).
     --bub-line     — кант вложенного блока (он и делает границу видимой, WCAG 1.4.11) */
.msg .bubble {
  --bub-ink: var(--text);
  --bub-ink-dim: var(--muted);
  --bub-tint: color-mix(in srgb, var(--text) 7%, transparent);
  --bub-line: color-mix(in srgb, var(--text) 18%, transparent);
}
.msg.mine .bubble:not(.has-media) {
  --bub-ink: #fff;
  --bub-ink-dim: rgba(255,255,255,.94);
  --bub-tint: rgba(11,16,32,.22);
  --bub-line: rgba(255,255,255,.42);
}
/* 🔴 ПУЗЫРЬ БЕЗ ЗАЛИВКИ ВОЗВРАЩАЕТ ЧЕРНИЛА ХОЛСТА. `.bubble.has-media` снимает фон
   (`background: transparent !important`), а `color:#fff` от `.msg.mine .bubble` оставался —
   белым по светлой ленте. Точечно это уже лечили у `.att-cap`; правило класса лечит все
   остальные подписи разом (дубляж, расшифровка, строка файла). */
.msg.mine .bubble.has-media { color: var(--text); }
/* 🔴 ЗАЛИВКА СВОЕГО ПУЗЫРЯ — СВОЙ ТОКЕН, а не общий --grad: --grad носят ещё кнопки,
   аватары и чипы, где рядом с ним живут ДРУГИЕ кегли и своя проверка. Замер белых чернил
   на прежней заливке: светлая 4.16:1 (верхний стоп) · тёмная 3.21:1 — то есть КАЖДОЕ своё
   слово в тёмной теме было ниже AA. Значение живёт в концепте (concept-6.css). */
.msg.mine .bubble { background: var(--bub-fill, var(--grad)); color: #fff; border-bottom-right-radius: 4px; box-shadow: 0 4px 14px -5px var(--glow); }
.msg.theirs .bubble { background: var(--theirs); border: 1px solid rgba(255,255,255,.05); border-bottom-left-radius: 4px; }
.msg.system .bubble { background: var(--system); color: #f0d9a0; font-size: 12px; }
/* 0151: сообщение ИИ в «Чате с ИИ» — тот же .theirs слева, но с мягкой акцентной подложкой и
   ровной акцентной рамкой, чтобы сразу отличать ответ ИИ от сообщения человека. Через
   --accent → светлая/тёмная темы подхватываются сами. Идёт ПОСЛЕ .theirs (та же специфичность). */
/* CLIE-483: рейку сняли — акцент подложкой и равномерной рамкой 1px, без левой полосы */
.msg.ai .bubble {
  background: color-mix(in srgb, var(--accent) 13%, var(--theirs));
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-bottom-left-radius: 4px;
}
.meta { display: flex; gap: 6px; align-items: center; font-size: 10px; color: var(--muted); margin-top: 2px; }
.seq { opacity: .7; }
/* время сообщения (HH:MM) вместо служебного #seq (Task 7) */
.msg-time { opacity: .65; font-variant-numeric: tabular-nums; letter-spacing: .2px; }
/* CLIE-1946 · светлая: приглушение прозрачностью роняло время и «изменено» до 2.6–2.9:1. Пометка
   «изменено» глушится ИНЛАЙН-стилем app.js (opacity .6), поэтому там !important — только в светлой. */
html[data-theme="light"] .msg-time { opacity: .9; }
html[data-theme="light"] .msg-edited { opacity: .9 !important; }
.status.sending { color: var(--muted); }
.status.queued { color: var(--muted); cursor: pointer; } /* «ждёт сети» (офлайн-очередь) — тап переотправит вручную; авто-уйдёт при сети */
/* 📥 CLIE-1847·Н2 (S2.13): ответ посетителю ждёт выбранные секунды — «отправится через N с» и
   «Отменить» (текст вернётся в поле). Отсчёт ведёт wcDeskHoldTicker. */
.status.held { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); }
.msg-hold-t { font-variant-numeric: tabular-nums; }
.msg-hold-x { border: 0; padding: 1px 8px; border-radius: 999px; background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--primary); font: inherit; font-size: 11px; font-weight: 600; cursor: pointer; transition: background .12s ease; }
.msg-hold-x:hover { background: color-mix(in srgb, var(--primary) 24%, transparent); }
.status.failed { color: var(--danger); cursor: pointer; } /* «ошибка ⟳» кликабельна → переотправить */
.status.sent { color: var(--ok); }
.status.read { color: var(--primary-2); } /* двойная галка — прочитано собеседником (индиго) */
/* 0195 «Чат с ИИ»: третье состояние — ИИ не просто прочитал, а УЧЁЛ (написал ответ / завершил
   проход после прочтения). Те же две галки, но насыщенным акцентом — «прочитал» остаётся
   спокойным индиго, чтобы состояния читались рядом, а не сливались. */
.status.read.acted { color: var(--primary); }
/* Галки доставки рисуются SVG-иконкой (svgIcon check/checkAll), а НЕ текстом «✓»/«✓✓».
   Прежний хак (letter-spacing:-.34em чтобы стянуть текстовые галки) слипался в нечитаемую
   кашу на части устройств/браузеров — постоянно «возвращался». SVG стабилен везде. */
.status.sent, .status.read { display: inline-flex; align-items: center; line-height: 1; }
.status.sent svg.ic, .status.read svg.ic { width: 16px; height: 16px; display: block; }
/* .uploading/.sending — текстовые состояния («загрузка 40%»), их не центрируем как иконку */

/* разделитель-дата по центру (Сегодня / Вчера / «5 июн») — Task 7 */
.day-divider { align-self: center; margin: 10px 0 4px; }
.day-divider span {
  display: inline-block; padding: 3px 12px; border-radius: 12px;
  background: var(--system, rgba(255,255,255,.06)); color: var(--muted);
  font-size: 11px; font-weight: 600; letter-spacing: .2px;
}
/* 📜 строка истории вверх над первым сообщением: «Загружаю более ранние…» / «Не удалось…
   Повторить» / «Начало переписки». Шрифт и цвет — как у разделителя-даты (лента не получает
   нового «языка»); высота одна во всех состояниях, чтобы смена надписи не двигала ленту. */
.msg-hist {
  align-self: center; display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 30px; margin: 2px 0 6px; color: var(--muted);
  font-size: 11px; font-weight: 600; letter-spacing: .2px; text-align: center;
}
.msg-hist-spin {
  width: 12px; height: 12px; flex: 0 0 auto; border-radius: 50%;
  border: 1.6px solid currentColor; border-right-color: transparent;
  animation: msgHistSpin .8s linear infinite;
}
@keyframes msgHistSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .msg-hist-spin { animation: none; } }
/* разделитель «Непрочитанные сообщения» — тонкая линия во всю ширину с подписью-пилюлей
   по центру, лёгкий акцент. Аналог Telegram/WhatsApp: точка «где я остановился». */
.unread-divider {
  align-self: stretch; display: flex; align-items: center; gap: 10px;
  margin: 12px 2px 6px; color: var(--primary-2, var(--primary, var(--cm-6c5ce7, #6c5ce7)));
}
.unread-divider::before, .unread-divider::after {
  content: ""; flex: 1 1 auto; height: 1px;
  background: linear-gradient(to var(--_d, right),
    color-mix(in srgb, var(--primary, var(--cm-6c5ce7, #6c5ce7)) 42%, transparent), transparent);
}
.unread-divider::after { --_d: left; }
.unread-divider span {
  flex: none; padding: 3px 12px; border-radius: 999px;
  background: color-mix(in srgb, var(--primary, var(--cm-6c5ce7, #6c5ce7)) 14%, transparent);
  color: var(--primary-2, var(--primary, var(--cm-6c5ce7, #6c5ce7)));
  font-size: 11px; font-weight: 700; letter-spacing: .2px; white-space: nowrap;
}
/* крестик отмены загрузки рядом с «загрузка N%» */
.upload-cancel { display: inline-block; margin-left: 4px; padding: 0 3px; cursor: pointer; color: var(--muted); font-weight: 700; line-height: 1; }
.upload-cancel:hover { color: var(--danger); }

/* ---- поиск по чату (панель под шапкой) ---- */
.chat-search-bar {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px; border-bottom: 1px solid var(--line);
  background: var(--panel, rgba(255,255,255,.02));
}
.chat-search-bar.hidden { display: none; }
.chat-search-input {
  flex: 1; min-width: 0; padding: 7px 12px; border-radius: 10px;
  background: var(--input-bg, rgba(255,255,255,.05)); color: inherit;
  border: 1px solid var(--line); font-size: 14px;
}
.chat-search-input:focus { outline: none; border-color: var(--primary, var(--cm-6c5ce7, #6c5ce7)); }
/* 🔴 Счётчик «N из M» — подпись, а не число в две цифры: не сжимаем его ниже
   собственной ширины (правило СРЕД-33), иначе «12 из 340» напечатается поверх соседа. */
.chat-search-count { flex: none; min-width: max-content; text-align: center; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- 🔎 CLIE-899 · СПИСОК НАЙДЕННОГО в чате («Показать списком», эталон Telegram) ----
   Живёт под баром поиска и НАД лентой: состояние видно там, где его встретят. */
.chat-search-list {
  border-bottom: 1px solid var(--line);
  background: var(--panel, rgba(255,255,255,.02));
  max-height: 42vh; overflow-y: auto;
}
.chat-search-list.hidden { display: none; }
.chat-search-say { padding: 10px 14px; }
.chat-search-say:empty { display: none; }
.chat-search-rows:empty { display: none; }
.csr-row {
  padding: 9px 14px; cursor: pointer;
  border-top: 1px solid var(--line);
  transition: background .12s ease;
}
.csr-row:first-child { border-top: 0; }
.csr-row:hover { background: var(--hover, rgba(127,127,127,.08)); }
/* 🔴 Текущее совпадение помечено ПОДЛОЖКОЙ, а не полосой слева (правило CLIE-483). */
.csr-row.cur { background: color-mix(in srgb, var(--primary) 12%, transparent); }
.csr-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 2px; }
.csr-who { font-weight: 600; font-size: 13px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.csr-when { flex: none; margin-left: auto; }
.csr-snip { font-size: 13px; line-height: 1.35; color: var(--muted); overflow-wrap: anywhere; }

/* 🔎 CLIE-899 · «Найдено N · по релевантности» в столбике «Мои задачи»: под поиском
   выдача плоская, и это сказано СЛОВАМИ, а не молча (иначе «где моя группировка?»). */
.task-found { padding: 6px 12px 4px; list-style: none; }

/* ---- плавающая дата поверх ленты (Telegram-style) ---- */
.date-float {
  position: absolute; left: 50%; transform: translateX(-50%);
  z-index: 6; pointer-events: none; opacity: 0; transition: opacity .25s ease;
}
.date-float.show { opacity: 1; }
.date-float span {
  display: inline-block; padding: 3px 12px; border-radius: 12px;
  background: var(--system, rgba(28,28,34,.92)); color: var(--muted);
  font-size: 11px; font-weight: 600; letter-spacing: .2px;
  box-shadow: 0 4px 12px -4px rgba(0,0,0,.5);
}

/* Кнопка «в конец чата» — появляется при прокрутке вверх от низа ленты (как в Telegram).
   Позиционируется относительно .thread (position: relative), над композером. */
.jump-down {
  position: absolute; right: 20px; bottom: 90px; z-index: 6;
  width: 44px; height: 44px; border-radius: 50%; padding: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,.45);
  opacity: 0; transform: translateY(8px) scale(.92); pointer-events: none;
  transition: opacity .18s ease, transform .18s ease, border-color .12s, background .12s;
}
.jump-down svg { width: 22px; height: 22px; display: block; }
.jump-down .jd-ic { display: flex; align-items: center; justify-content: center; }
.jump-down.show { opacity: 1; transform: none; pointer-events: auto; }
.jump-down:hover { border-color: var(--primary); background: var(--panel); }
/* 🔙 CLIE-1241 · «вернуться к сообщению, с которого перешёл»: пока жив обратный билет, у
   кнопки ДРУГОЕ дело — значит и вид другой (акцентный контур + значок возврата ⤶), иначе
   один и тот же кружок молча делает два разных перехода. Подпись меняет updateJumpDown. */
.jump-down .jd-ic-back { display: none; }
.jump-down.to-msg .jd-ic-end { display: none; }
.jump-down.to-msg .jd-ic-back { display: flex; }
.jump-down.to-msg { color: var(--primary); border-color: var(--primary); }

/* Подсветка ТЕКУЩЕГО совпадения поиска (стойкая, живёт дольше кратковременного .flash).
   CLIE-520: кольцо ОДНО на продукт — та же формула, что у цели перехода (см. `.msg.flash`
   ниже): 2px зазор цветом панели + контур `--primary-2`. Читается на любом пузыре.
   `!important` — не украшение: в СВЕТЛОЙ теме `html[data-theme="light"] .msg.mine .bubble`
   (0,4,1) перебивал `.msg.search-current.mine .bubble` (0,3,1), и у СВОИХ пузырей кольца
   текущего совпадения не было ВООБЩЕ (проверено на проде computed-стилем). */
.msg.search-current .bubble,
.msg.search-current.theirs .bubble,
.msg.search-current.mine .bubble,
.msg.search-current .bubble.has-media {
  box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px var(--primary-2) !important;
}
/* Подсветка САМОГО искомого текста при поиске по чату (find-in-page).
   Все совпадения — мягкая заливка (текст остаётся читаемым), ТЕКУЩЕЕ (навигация ▲▼) —
   насыщенный чип с мягким свечением, чтобы сразу выделить, где ты сейчас. Обе темы. */
mark.search-hit {
  background: color-mix(in srgb, var(--primary) 30%, transparent);
  color: inherit;
  border-radius: 4px;
  padding: 0 1.5px;
  margin: 0 -0.5px;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 26%, transparent) inset;
  transition: background .14s ease, box-shadow .14s ease, color .14s ease;
}
mark.search-hit.search-hit-current {
  background: var(--acc-fill);
  color: #fff;
  box-shadow: 0 0 0 1px var(--primary), 0 0 10px 1px var(--glow);
}
/* На СВОЁМ пузыре (индиго-градиент, текст белый) индиго-заливка слилась бы —
   как и у чипов на своём пузыре (.msg-mention), берём белую плашку: мягкая —
   полупрозрачная белая, текущая — плотная белая с индиго-текстом (инверсия, пик контраста). */
.msg.mine .bubble mark.search-hit {
  background: rgba(255, 255, 255, .28);
  color: #fff;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .26) inset;
}
.msg.mine .bubble mark.search-hit.search-hit-current {
  background: #fff;
  color: var(--primary);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, .9), 0 0 10px 1px rgba(255, 255, 255, .4);
}

/* 🔴 CLIE-592 (паритет с Flutter): полоса «печатает…» больше НЕ резервирует высоту,
   когда никто не печатает. Раньше `height:16px` держались всегда — над композером
   (и над строкой инструментов .comp-tools, которая всплывает при наборе) висела мёртвая
   полоса 20px. Прыжка нет и без резерва: высота едет тем же 140ms-переходом, что и
   раскрытие .comp-tools. `:empty` срабатывает ровно там, где код чистит подпись
   (`el.typing.textContent = ""`). */
.typing { padding: 0 18px 4px; height: 16px; overflow: hidden; transition: height .14s cubic-bezier(.2,.8,.2,1), padding .14s cubic-bezier(.2,.8,.2,1); }
.typing:empty { height: 0; padding-top: 0; padding-bottom: 0; }

/* Композер — вертикальный стек из 2 строк: .comp-tools (инструменты, всплывают) над .comp-main
   (скрепка · поле · правый столбик). См. блок «Композер: 2 строки» ниже. */
.composer { display: flex; flex-direction: column; align-items: stretch; gap: 0; padding: 10px 16px 12px; border-top: 1px solid var(--line); }
/* 🔴🔴 CLIE-1049 — ПОЛЕ ВВОДА ЧАТА: ЖИВОЕ, НЕ `<textarea>`.
   Владелец 12.09.2026: «после применения сочетания не должно появляться символы, а текст
   должен приобретать нужный вид». `<textarea>` физически не умеет нарисовать жирный внутри
   себя, поэтому поле — contenteditable на движке живого markdown (`.rd-ce`), а размеры/подложка
   остались ТЕМИ ЖЕ, что были у textarea (высота одной строки … 120px, радиус 18, те же отступы):
   человек не должен увидеть «переезд» композера. Селектор `.composer textarea` сохранён рядом
   намеренно — на случай любого другого текстового поля внутри композера. */
.composer textarea, .composer .cmp-ce {
  flex: 1; resize: none; min-height: 40px; max-height: 120px; overflow-y: auto;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  border-radius: 18px; padding: 9px 14px; font-size: 14px; line-height: 1.35;
  font-family: inherit; outline: none;
}
.composer textarea:focus, .composer .cmp-ce:focus { border-color: var(--primary); }
/* Подсказка пустого поля — тем же приёмом, что у описания/заметок (`data-ph`), а не
   `::placeholder` (у div его нет). Каретка стоит слева от подсказки, как в textarea, —
   это обеспечивает ОБЩАЯ ДВЕРЬ `[data-ph]::before { position: absolute }` в конце файла
   (CLIE-1181): без неё подсказка была содержимым строки и уводила каретку вправо. */
.composer .cmp-ce.is-empty::before { content: attr(data-ph); color: var(--muted); pointer-events: none; }
/* Беседа не открыта → поле не редактируется (прежний `disabled` у textarea). */
.composer .cmp-ce.is-disabled { opacity: .6; cursor: default; }
/* 🔴🔴 РЕЖИМ WYSIWYG: СИМВОЛОВ РАЗМЕТКИ НЕ ВИДНО ВООБЩЕ (нулевая ширина).
   Символы ОСТАЮТСЯ в DOM — инвариант «textContent == markdown» цел, иначе разъехались бы
   каретка, орфография (она считает смещения тем же `ceLocate`) и отправка. Их просто не
   видно: `font-size:0`. Тот же приём уже носит чек-бокс (`.rd-task-mk`), а в приложении так
   же прячет маркеры `MarkdownEditingController._hidden` — модель продукта одна.
   🔴 Каретка внутрь невидимого маркера не попадает: её перескок — `ceWysStep`/`ceWysSnap`
   в `app.js` (без него стрелка «не двигала» каретку на экране). */
.rd-ce.rd-wys .rd-mk { font-size: 0; line-height: 0; letter-spacing: 0; }
/* Маркер списка/цитаты в WYSIWYG остаётся ВИДИМЫМ (это и есть вид пункта), но символ решётки
   заголовка и парные обёртки — нет: их место занимает сам стиль текста. */
.rd-ce.rd-wys .rd-q-mk, .rd-ce.rd-wys .rd-li-mk { font-size: inherit; line-height: inherit; }
/* 🔴 В режиме ДОКУМЕНТА («Полотно») маркер цитаты — такая же разметка, как «#» и «**»:
   прячем его, полосу слева рисует .rd-lquote. Правило идёт ПОСЛЕ исключения выше, иначе
   одинаковая специфичность вернула бы «>» на экран. */
.rd-ce.rd-doc .rd-mk.rd-q-mk { font-size: 0; line-height: 0; letter-spacing: 0; }
.composer .primary { width: auto; margin: 0; padding: 10px 20px; }
/* Все кнопки композера центрируют иконку; конкретные размеры — в блоке «Композер: 2 строки». */
.composer button.ghost, .composer button.primary { display: inline-flex; align-items: center; justify-content: center; }

/* ═══════════ Композер: 2 строки + компактные кнопки (CLIE-349, владелец) ═══════════
   Нижняя строка (.comp-main) = скрепка(всегда слева) · поле · правый столбик (⛶ «Полотно»
   НАД отправкой). Верхняя строка (.comp-tools) = эмодзи/стикеры · черновики · ✨ИИ — всплывает
   при фокусе поля ИЛИ наборе текста (прогрессивное раскрытие «не отбирать экран»): пусто и вне
   фокуса → свёрнута в ноль, экран не занят. Отступы урезаны (просьба «компактнее, меньше отступы»). */
.comp-main { display: flex; align-items: flex-end; gap: 7px; }

.comp-tools {
  display: flex; align-items: center; gap: 2px; margin-left: -2px;
  height: 0; opacity: 0; overflow: hidden; pointer-events: none;
  transition: height var(--dur-1) var(--ease), opacity var(--dur-1) var(--ease),
              margin-bottom var(--dur-1) var(--ease);
}
.composer:focus-within .comp-tools,
.composer.tools-open .comp-tools {
  height: 34px; opacity: 1; pointer-events: auto; margin-bottom: 3px;
}
.comp-tools > button { width: 34px; height: 34px; min-height: 34px; padding: 0; border-radius: 9px; flex: 0 0 auto; }
.comp-tools > button svg.ic { width: 20px; height: 20px; }

.comp-main > .attach-btn { width: 40px; height: 40px; min-height: 40px; padding: 0; flex: 0 0 auto; border-radius: 12px; }
.comp-main > .attach-btn svg.ic { width: 21px; height: 21px; }

.comp-right { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 4px; flex: 0 0 auto; }
.comp-right > button { width: 40px; height: 40px; min-height: 40px; padding: 0; flex: 0 0 auto; }
.comp-right > button svg.ic { width: 21px; height: 21px; }
.composer .comp-right button.primary { width: 40px; min-width: 40px; height: 40px; padding: 0; border-radius: 13px; }
.composer .comp-right button.primary svg.ic { width: 20px; height: 20px; }
/* Квадрат «Полотно» (раскрыть полноэкранный редактор) живёт в ВЕРХНЕЙ строке (.comp-tools),
   прижат ВПРАВО (margin-left:auto) — на ОДНОМ УРОВНЕ с эмодзи/черновиками/✨ и ровно НАД кнопкой
   «Отправить» (владелец CLIE-349: «квадрат на одном уровне с элементами, чтобы красиво»). Всплывает
   вместе со строкой инструментов → НИЧЕГО не сдвигает и не создаёт лишнего зазора на ЛЮБОМ размере
   текста (раньше оверлей у .comp-right орфанил квадрат по центру при многострочном поле). Размер
   34px и радиус — из общего правила .comp-tools > button; margin-right:3px центрует над 40-px «Отправить». */
.comp-tools .expand-btn {
  margin-left: auto; margin-right: 3px; border-radius: 9px;
  opacity: 1; transform: scale(1); transform-origin: center;
  transition: opacity var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.comp-tools .expand-btn svg.ic { width: 19px; height: 19px; }
/* Нет контента → квадрат гаснет НА МЕСТЕ (in-flow, opacity+scale), держит свой правый слот, чтобы
   при появлении текста ничего не прыгало. inline-flex !important глушит глобальный .hidden{display:none}. */
.comp-tools .expand-btn.hidden {
  display: inline-flex !important; opacity: 0; transform: scale(.72); pointer-events: none;
}
/* единая кнопка режима (кружок/голос); при записи — крупнее и красная */
.mode-btn { padding: 9px 12px; font-size: 20px; flex: none; transition: transform .12s, color .12s; touch-action: none; user-select: none; }
.mode-btn.recording { transform: scale(1.3); color: var(--danger); }
/* ✨ ИИ-улучшение текста */
.ai-btn { padding: 9px 12px; font-size: 18px; flex: none; }
.ai-btn.loading { animation: recpulse .8s infinite; pointer-events: none; }
/* ═══════════ ✍️ ОРФОГРАФИЯ В ПОЛЕ ВВОДА (CLIE-870) ═══════════
   Слой-двойник ПОВЕРХ textarea: его текст ПРОЗРАЧЕН, видно только подчёркивание, а сам
   текст и фон рисует по-прежнему само поле — так подложку и тему трогать не пришлось
   вовсе. Геометрию слоя ставит ЗАМЕРОМ spellPaint (поле растёт, «Крупный текст» меняет
   кегль — числа из CSS тут врали бы). Указатель слой НЕ ловит: иначе он украл бы
   выделение текста и клик по полю.
   🔴 Никаких заливок под словом: акцент несёт САМА линия (доктрина CLIE-483). */
.spell-layer {
  position: absolute; z-index: 2; pointer-events: none; overflow: hidden;
  white-space: pre-wrap; overflow-wrap: break-word; word-break: break-word;
  color: transparent; background: none; border: 1px solid transparent;
  box-sizing: border-box; margin: 0;
  -webkit-user-select: none; user-select: none;
}
.comp-main { position: relative; } /* система координат слоя = сама строка композера */
.sp-err {
  text-decoration: underline; text-decoration-style: wavy; text-decoration-thickness: 1px;
  text-decoration-color: var(--danger); text-underline-offset: 2px;
  -webkit-text-decoration-skip-ink: none; text-decoration-skip-ink: none;
}
.sp-fix { /* моя правка: тихая пунктирная линия — «это можно вернуть», а не «это ошибка» */
  text-decoration: underline; text-decoration-style: dotted; text-decoration-thickness: 1px;
  text-decoration-color: var(--primary); text-underline-offset: 2px;
  -webkit-text-decoration-skip-ink: none; text-decoration-skip-ink: none;
}
/* Полоска НАД полем: варианты замены / «вернуть свой вариант». Тот же язык, что у
   подсказки раскладки (.layout-suggest) — мягкая подложка + хэйрлайн, без реек. */
/* 🔴 CLIE-1010: полоска стала ПЛАВАЮЩЕЙ и ОДНОЙ на продукт — она обслуживает ЛЮБОЕ
   прозаическое поле (композер, блок «Полотна», описание, заметку, поле CRM), а не только
   строку сообщения. Место считает замер (`spellBarPlace`), поэтому здесь только вид.
   Ярус — ниже тоста (сообщение важнее подписи) и выше полосы слоёв `ccLayerLift`: поле
   ввода бывает внутри модалки, и подсказка к нему не имеет права оказаться под ней. */
.spell-bar {
  position: fixed; left: 0; top: 0; z-index: 1998000000;
  /* Ширина — по содержимому, потолок один и тот же здесь и в `spellBarPlace` (560). */
  display: flex; align-items: center; gap: 8px; max-width: min(560px, calc(100vw - 16px));
  padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--r-md, 10px);
  background: var(--panel); box-shadow: var(--shadow-2, 0 10px 30px rgba(0, 0, 0, .18));
  color: var(--text); animation: lsIn .16s ease-out; min-width: 0;
}
/* Подчёркивание в contenteditable: ни одного своего узла — красит сам движок
   (CSS Custom Highlight API). Волна = «возможно, ошибка», тихий пунктир = «моя правка,
   можно вернуть» — те же два языка, что у слоя-двойника (.sp-err / .sp-fix). */
::highlight(cc-spell-err) {
  text-decoration: underline; text-decoration-style: wavy;
  text-decoration-color: color-mix(in srgb, var(--danger, #e5484d) 78%, transparent);
  text-decoration-thickness: 1px; text-underline-offset: 2px; text-decoration-skip-ink: none;
}
::highlight(cc-spell-fix) {
  text-decoration: underline; text-decoration-style: dotted;
  text-decoration-color: color-mix(in srgb, var(--muted) 70%, transparent);
  text-decoration-thickness: 1px; text-underline-offset: 2px;
}
/* 🔴 Кто кому уступает место (CLIE-1010·R4·3): первой ужимается ПОДПИСЬ, затем дорожка
   вариантов, а ГЛАВНОЕ действие (`.sp-bar-main`) не сжимается никогда — иначе человек не
   видит того, ради чего полоска показана (СРЕД-32·3). */
.spell-bar .sp-bar-hint { display: flex; align-items: baseline; gap: 6px; font-size: 11px; color: var(--muted); flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.spell-bar .sp-bar-cap { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spell-bar .sp-bar-main { display: flex; align-items: center; gap: 6px; flex: none; }
.spell-bar .sp-bar-word { font-size: 12px; font-weight: 600; color: var(--text); max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spell-bar .sp-chips { display: flex; align-items: center; gap: 6px; overflow-x: auto; flex: 1; min-width: 0; scrollbar-width: none; }
.spell-bar .sp-chips::-webkit-scrollbar { display: none; }
.spell-bar .sp-chip {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  height: 26px; padding: 0 10px; border-radius: 8px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  font-size: 13px; font-weight: 500; line-height: 1;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.spell-bar .sp-chip:hover { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, var(--panel)); }
.spell-bar .sp-chip:active { transform: scale(.97); }
.spell-bar .sp-chip-skip, .spell-bar .sp-chip-back { color: var(--muted); }
.spell-bar .sp-chip-back { color: var(--primary-2); }
/* «Исправить всё» (CLIE-926) — ГЛАВНОЕ действие полоски, поэтому носит вес главного:
   заливка акцентом, а не серый текст. Ровно тот урок, что СРЕД-32·3 — прозрачную кнопку
   с серой подписью человек не находит, и функция для него не существует. Контрол не
   сжимается ниже своей подписи (СРЕД-33): счётчик обязан быть виден целиком. */
.spell-bar .sp-chip-all {
  border-color: transparent;
  background: var(--acc-fill);
  color: #fff;
  font-weight: 600;
  min-width: max-content;
}
.spell-bar .sp-chip-all:hover { background: var(--primary-2, var(--primary)); border-color: transparent; }
.spell-bar .sp-chip svg.ic { width: 14px; height: 14px; }
.spell-bar .sp-bar-x { flex: none; width: 26px; height: 26px; padding: 0; border: none; background: none; color: var(--muted); cursor: pointer; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; }
.spell-bar .sp-bar-x:hover { background: var(--panel-2); color: var(--text); }
.spell-bar .sp-bar-x svg.ic { width: 14px; height: 14px; }
.thread.cc-pane-active > #spellBar { display: none !important; }

/* ⌨ Подсказка смены раскладки (ghbdtn → привет) — плашка НАД полем ввода.
   Появляется только когда текст похож на русский латиницей; тап = заменить. */
.layout-suggest {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 14px; margin: 0; text-align: left; cursor: pointer;
  border: none; border-top: 1px solid var(--line);
  background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 16%, transparent), color-mix(in srgb, var(--primary) 12%, transparent));
  color: var(--text); border-radius: 0;
  animation: lsIn .16s ease-out;
}
.layout-suggest:hover { background: linear-gradient(135deg, color-mix(in srgb, var(--primary) 26%, transparent), color-mix(in srgb, var(--primary) 20%, transparent)); border-top-color: var(--primary); }
.layout-suggest .ls-icon { display: inline-flex; color: var(--primary-2); flex: none; }
.layout-suggest .ls-icon svg.ic { width: 18px; height: 18px; }
.layout-suggest .ls-body { display: flex; flex-direction: column; min-width: 0; flex: 1; line-height: 1.25; }
.layout-suggest .ls-hint { font-size: 11px; color: var(--muted); }
.layout-suggest .ls-preview {
  font-size: 14px; font-weight: 600; color: var(--primary-2);
  overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.layout-suggest .ls-key {
  flex: none; font-size: 11px; color: var(--muted);
  border: 1px solid var(--line); border-radius: 6px; padding: 2px 7px;
}
@keyframes lsIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.rec-bar.cancel { color: var(--danger); }
.rec-bar.cancel .rec-dot { background: var(--danger); }

/* ---- call overlay (ПОЛНОЭКРАННО, как у топ-мессенджеров) ---- */
.call-overlay { position: fixed; inset: 0; z-index: 50; background: #000; }
/* 🔴🔴 ЖИВОЙ СОЗВОН — ВСЕГДА ПОВЕРХ МОДАЛОК (ЗВОН-606).
   Правило существовало, но жило в СТИЛЯХ ПУЗЫРЯ БЫСТРОГО ЧАТА (quickChatEnsureStyles в
   app.js) — то есть применялось, только если на этой поверхности успел появиться пузырь.
   Там, где пузыря нет, идущий звонок оказывался ПОД модалкой/скримом (60…13800): звук
   есть, окна не видно — ровно жалоба «на фоне идут звонки». Правило про созвон живёт в
   стилях созвона; свёрнутое окно сюда не входит — оно и так плавает поверх содержимого. */
.call-overlay:not(.hidden) { z-index: 10000; }
.groupcall-overlay:not(.hidden) { z-index: 10000; }
.call-box {
  position: absolute; inset: 0; width: 100%; height: 100%;
  background: #000; border: none; border-radius: 0; padding: 0;
}
.videos {
  position: absolute; inset: 0; background: #000; overflow: hidden;
  /* 📐 ГЕОМЕТРИЯ ВРЕЗКИ ЖИВЁТ ЗДЕСЬ, ОДНИМ НАБОРОМ (ЗВОН-693). Дефолты — ровно те числа,
     что стояли у врезки до правки, поэтому до первого касания вид не меняется ни на пиксель.
     Дальше их ПЕРЕЗАПИСЫВАЕТ замером `ccSelfViewPaint` (app.js): доля кадра, а не px, —
     окошко переживает и разворот, и раздвижение окна браузера. */
  --sv-l: auto;
  --sv-t: calc(env(safe-area-inset-top) + 14px);
  --sv-r: 14px;
  --sv-w: min(32%, 150px);
  --sv-ar: 3 / 4;
}
/* 🔴 CLIE-606·5: участника здесь рисует КАНОН (`CallUi.tile` → `.gtile`, callui.css).
   Ниже — только РАСКЛАДКА поверхности: где лежит крупный кадр и где врезка своей камеры.
   Ровно так же устроены конференция (`.group-grid`), созвон комнаты и гостевая страница —
   «другой вид — это раскладка, а не второй компонент». */
/* ══ 🔴🔴 КТО КРУПНО, А КТО ВО ВРЕЗКЕ — ЭТО РОЛЬ-КЛАСС, А НЕ ВТОРАЯ ВЁРСТКА (ЗВОН-693) ══
   Владелец: «нужна возможность увеличивать своё окошко при видеозвонке. Увеличивать и
   перетаскивать по экрану. А при нажатии чтобы переключалось и я видел себя на большом
   экране, а с кем говорю — в маленьком».
   До правки геометрия врезки была ПРИБИТА к своей камере (`.local-tile`: `top:14 right:14
   width:32% max-width:150 aspect 3/4`), и рядом лежала ВТОРАЯ её копия — для аннотаций над
   своим экраном (`.videos.cc-ink-own .remote`). Причём вторая копия была МЁРТВОЙ: она
   двигала `<video class="remote">`, который после CLIE-606·5 лежит ВНУТРИ плитки и занимает
   её целиком (`position: static`), то есть не двигался никуда — «свой экран крупно, а
   собеседник уголком» не работало вовсе.
   Поэтому геометрия ОДНА и адресована РОЛИ, а не человеку: `.cc-stage` — крупный кадр,
   `.cc-inset` — врезка. Кто в какой роли — решает `ccSelfViewPaint` (app.js), он же кладёт
   в `--sv-*` замеренные числа. Второй раскладки врезки в продукте быть не должно. */
.videos > .cc-stage {
  position: absolute; inset: 0; width: auto; height: auto; max-width: none;
  aspect-ratio: auto; border: 0; border-radius: 0; box-shadow: none;
  background: #000; z-index: 1; cursor: default;
}
.videos > .cc-inset {
  position: absolute;
  left: var(--sv-l); top: var(--sv-t);
  right: var(--sv-r); bottom: auto;
  width: var(--sv-w); max-width: none; height: auto;
  aspect-ratio: var(--sv-ar);
  border-radius: 14px; border: 2px solid rgba(255,255,255,.25);
  background: #111; z-index: 3;
  box-shadow: 0 4px 18px rgba(0,0,0,.5);
  cursor: grab; touch-action: none;
}
.videos > .cc-inset.sv-busy { cursor: grabbing; }
/* Человек убрал себя с экрана («Скрыть себя» у топ-продуктов) — врезки нет, вместо неё
   тихая пилюля возврата: пропавший без следа контрол читается как поломка. */
.videos.sv-hidden > .cc-inset { display: none; }
/* Зеркало своей камеры — выбор человека (Zoom «Mirror my video»). Класс на `.videos`
   сильнее канонического `.gtile-local video`, поэтому отменяет именно его. */
.videos.sv-unmirror .local { transform: none; }
/* Имя и «свернуть» во врезке не нужны: места нет, а себя человек узнаёт без таблички.
   Правило адресовано РОЛИ — иначе после обмена местами подпись всплывёт в окошке 150px. */
.videos > .local-tile .gname,
.videos > .cc-inset .gname { display: none; }

/* ── Хват размера и «⋯» врезки ──────────────────────────────────────────────────────────
   🔴 ВИДНЫ ВСЕГДА, а не по наведению (СРЕД-32·3: «вход, который не находят, равен
   отсутствующему»; на тач-экране наведения нет вовсе). В покое — приглушены, под курсором
   и в работе — в полную силу. Угол хвата считает JS: он всегда СМОТРИТ ВНУТРЬ кадра,
   иначе тянуть окошко пришлось бы за экран. */
.sv-grip, .sv-more {
  position: absolute; z-index: 5; display: none;
  align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: 9px;
  background: var(--cm-090b10-62, rgba(9,11,16,.62)); color: #fff; opacity: .62;
  transition: opacity .14s var(--ease, ease), background-color .14s var(--ease, ease);
}
.videos > .cc-inset > .sv-grip, .videos > .cc-inset > .sv-more { display: inline-flex; }
.sv-grip svg, .sv-more svg { width: 15px; height: 15px; display: block; }
.videos > .cc-inset:hover > .sv-grip,
.videos > .cc-inset:hover > .sv-more { opacity: .95; background: var(--cm-090b10-8, rgba(9,11,16,.8)); }
.sv-grip { cursor: nwse-resize; touch-action: none; }
.sv-grip.at-l { left: 3px; cursor: nesw-resize; }
.sv-grip.at-r { right: 3px; cursor: nwse-resize; }
.sv-grip.at-t { top: 3px; }
.sv-grip.at-b { bottom: 3px; }
.sv-grip.at-l.at-t, .sv-grip.at-r.at-b { cursor: nwse-resize; }
.sv-grip.at-r.at-t, .sv-grip.at-l.at-b { cursor: nesw-resize; }
.sv-more { cursor: pointer; }
.sv-more.at-l { left: 3px; } .sv-more.at-r { right: 3px; }
.sv-more.at-t { top: 3px; }  .sv-more.at-b { bottom: 3px; }

/* Пилюля «Показать себя» — единственный след спрятанной врезки. */
.sv-show {
  position: absolute; z-index: 4; right: 14px; top: calc(env(safe-area-inset-top) + 14px);
  display: none; align-items: center; gap: 7px; height: 32px; padding: 0 12px;
  border-radius: 999px; border: 1px solid rgba(255,255,255,.14);
  background: var(--cm-090b10-72, rgba(9,11,16,.72)); color: #fff;
  font-size: 12.5px; font-weight: 600; line-height: 1; cursor: pointer;
}
.sv-show svg { width: 15px; height: 15px; }
.videos.sv-hidden > .sv-show { display: inline-flex; }

/* Меню врезки: обмен местами · зеркало · скрыть · вернуть на место. Своих кнопок в ряд
   контролов звонка не добавляем — там и так одиннадцать штук (правило «не отбирать экран»). */
.sv-menu {
  position: absolute; z-index: 6; display: none; flex-direction: column; min-width: 214px;
  padding: 6px; border-radius: 14px; border: 1px solid rgba(255,255,255,.1);
  background: var(--cm-14161e-96, rgba(20,22,30,.96)); box-shadow: 0 18px 44px -12px rgba(0,0,0,.7);
}
.sv-menu.open { display: flex; }
.sv-menu button {
  display: flex; align-items: center; gap: 9px; width: 100%;
  height: var(--ctl-h, 30px); padding: 0 9px; border: 0; border-radius: 9px;
  background: none; color: #fff; font-size: var(--ctl-fs, 13px); font-weight: 500;
  text-align: left; cursor: pointer;
}
.sv-menu button:hover { background: rgba(255,255,255,.1); }
.sv-menu button[disabled] { opacity: .42; cursor: default; }
.sv-menu button svg { width: 16px; height: 16px; flex: 0 0 auto; opacity: .82; }
.sv-menu .sv-on { margin-left: auto; opacity: .8; }

/* ══ 🔴 «КТО ГОВОРИТ» В ЗВОНКЕ 1:1 — ТОЛЬКО В АУДИО-РАСКЛАДКЕ (ЗВОН-693) ═════════════════
   Владелец: «в звонке видео 1 на 1, когда говорит оппонент, появляется синяя рамка. Тут это
   не нужно, там всего 2 участника, не нужная функция там. В конференции нужна — там оставь».
   Он прав и по делу, и «как у всех»: ни Zoom, ни Meet, ни Teams, ни FaceTime, ни Telegram,
   ни WhatsApp активного спикера в разговоре ДВОИХ не подсвечивают — подсвечивать нечего.
   Кольцо гасит ШТАТНЫЙ выключатель канона `.no-ring` (его ставит `ccCallTilesBoot`), а
   бейдж-эквалайзер на кадре — это правило. 🔴 АУДИО-раскладку не трогаем: там строка голоса
   — ЕДИНСТВЕННЫЙ признак живого разговора, владелец сам просил её вернуть (CLIE-657). */
.call-overlay:not(.audio-mode) .videos > .gtile.speaking .gt-eq { display: none; }
.videos .remote { width: 100%; height: 100%; object-fit: cover; background: #000; }
.videos .local { width: 100%; height: 100%; object-fit: cover; }
/* Демонстрация экрана (1-на-1): широкий экран ПК показываем ЦЕЛИКОМ (contain), чтобы на
   телефоне собеседника не обрезались края. .peer-screen — собеседник показывает экран
   (сигнал screen_state), .local.screen — я сам показываю (моё превью тоже целиком). */
.videos.peer-screen .remote { object-fit: contain; }
.videos .local.screen { object-fit: contain; transform: none; }
/* Кнопка формата (1-на-1): пользователь выбрал показывать видео собеседника ЦЕЛИКОМ
   (contain) — вертикальный кадр телефона (9:16) не обрезается на широком экране ПК.
   Выбор запоминается (localStorage cc_call_video_fit). Показ экрана (.peer-screen) всегда
   рисуется целиком независимо от этого выбора. */
.videos .remote.fit-contain { object-fit: contain; }
/* В аудио-дизайне видео скрыто → кнопка формата не нужна. */
.call-overlay.audio-mode #videoFitBtn { display: none; }
.call-status {
  position: absolute; left: 0; right: 0;
  top: calc(env(safe-area-inset-top) + 18px);
  z-index: 2; text-align: center; font-size: 18px; font-weight: 700;
  /* Экран звонка ВСЕГДА тёмный (`.call-overlay` — #000) в обеих темах: без своего цвета строка брала
     тёмный текст светлой темы — «Связь прервана…», «не восстановилась» и секундомер на чёрном фоне
     голосового звонка/обрыва были почти невидимы (кадр прибора C 06.10). Как у `.ca-status`. */
  color: #fff;
  padding: 0 16px; text-shadow: 0 1px 6px rgba(0,0,0,.7);
}
/* 🩹 ЗВОН-945 · «Переподключить» — ручной выход у лестницы лечения связи. Появляется
   ПОД строкой статуса и ТОЛЬКО в стадии `lost` (лестница сдалась). Пока она пробует
   сама — кнопки нет вовсе: прогрессивное раскрытие, мёртвых контролов не держим.
   Размер ряда — общий размерный класс (--ctl-h/--ctl-r/--ctl-fs), своего числа не пишем. */
.call-heal-row {
  position: absolute; left: 0; right: 0;
  /* 🔴 Ниже чипа кода защиты (`.call-sas`, +52px): при +48px они ложились друг на друга и
     чип накрывал кнопку — мерилка `tools/call_heal_prod.js` показала это буквально
     (`elementFromPoint` в центре кнопки возвращал `.gc-sas`, настоящий клик не доходил).
     ВИДНО ≠ РАБОТАЕТ — канон `feature-entry-must-be-clickable`. */
  top: calc(env(safe-area-inset-top) + 92px);
  z-index: 3; display: flex; justify-content: center; gap: 8px; padding: 0 16px;
  /* Полоса на всю ширину не имеет права съедать нажатия по кадру под ней — кликабельна
     только сама кнопка (тот же приём, что у `.call-sas` и `.call-up-bar`). */
  pointer-events: none;
}
.call-heal-row > * { pointer-events: auto; }
/* В аудио-дизайне заголовок статуса скрыт, и чип кода поднимается к +18px — ряд следом. */
.call-overlay.audio-mode .call-heal-row { top: calc(env(safe-area-inset-top) + 58px); }
.call-heal-row.hidden { display: none; }
/* 🔴 Кнопки ряда носят `.ghost`, а `html[data-theme="light"] .ghost` (0,2,1) гасит фон и рамку
   сильнее `.call-heal-row > button` (0,1,1): в светлой теме «Переподключить» / «Завершить»
   превращались в строку текста на чёрном экране обрыва (кадр прибора C 06.10, тёмная — кнопки
   есть). Экран звонка всегда тёмный — кнопка держит СВОЮ плашку в обеих темах, селектор
   `.call-overlay … button.ghost` (0,3,1) — как у дока звонка. */
.call-heal-row > button,
.call-overlay .call-heal-row > button.ghost {
  flex: 0 0 auto; width: auto; margin: 0;
  height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs);
  padding: 0 14px; font-weight: 600; white-space: nowrap;
  color: #ffd7c2; background: rgba(255,107,94,.16); border: 1px solid rgba(255,107,94,.34);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  transition: background 140ms ease, border-color 140ms ease;
}
.call-heal-row > button:hover,
.call-overlay .call-heal-row > button.ghost:hover { background: rgba(255,107,94,.26); border-color: rgba(255,107,94,.5); }
.call-overlay.minimized .call-heal-row { display: none; } /* в PiP места нет — только точка статуса */

/* «Идёт запись» в звонке 1:1 — та же пилюля, что в конференции (.gc-rec-dot), но своя
   позиция: слева сверху, центр занят #callStatus. Кликов не ловит — это индикатор.
   В свёрнутом окне (PiP) текст уходит, остаётся пульсирующая точка: места нет, а факт
   записи человек обязан видеть всегда. */
.ca-rec-dot {
  position: absolute; z-index: 3;
  left: calc(env(safe-area-inset-left) + 14px); top: calc(env(safe-area-inset-top) + 14px);
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px;
  border-radius: 9px; font-size: 12px; font-weight: 600; letter-spacing: .1px;
  color: #ffd6d6; background: rgba(239,68,68,.16); border: 1px solid rgba(239,68,68,.34);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  pointer-events: none; white-space: nowrap;
}
.call-overlay.minimized .ca-rec-dot { left: 8px; top: 8px; height: 18px; padding: 0 6px; border-radius: 7px; }
.call-overlay.minimized .ca-rec-label { display: none; }
/* Кнопка записи в панели звонка 1:1 — тот же язык, что у конференции (#gcRecBtn.recording):
   индиго-заливка + красная точка-бейдж, а не сплошной красный (красный = «Завершить»). */
#caRecBtn { position: relative; }
#caRecBtn.recording { color: #fff; background: var(--acc-grad); border-color: transparent; }
#caRecBtn.recording::before {
  content: ""; position: absolute; top: 5px; right: 5px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 2px rgba(0,0,0,.45);
}
/* «Готовим запись…» — окно между тапом и стартом (POST /recordings + микрофон). Кнопка
   обязана ответить на нажатие СРАЗУ, иначе человек жмёт второй раз. Точка-бейдж пульсирует
   приглушённо, сама кнопка не кликается — один тап = одна запись. Одинаково для 1:1 и
   конференции (#gcRecBtn), язык состояний общий. */
#caRecBtn.rec-pending, #gcRecBtn.rec-pending { pointer-events: none; opacity: .72; }
#caRecBtn.rec-pending::before, #gcRecBtn.rec-pending::before {
  content: ""; position: absolute; top: 5px; right: 5px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 2px rgba(0,0,0,.45);
  animation: recPendingPulse 1s ease-in-out infinite;
}
@keyframes recPendingPulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  #caRecBtn.rec-pending::before, #gcRecBtn.rec-pending::before { animation: none; opacity: .7; }
}
/* ЗАПИСЬ ПО РАЗРЕШЕНИЮ ВЕДУЩЕГО (ЗВОН-28). Кнопка одна и та же — меняется её СМЫСЛ,
   и это должно быть видно ДО нажатия, а не только из подсказки:
   `rec-ask`  — права ещё нет: кнопка приглушена, вместо красной точки — янтарная
                (не «идёт запись», а «нужно спросить»);
   `rec-wait` — запрос ушёл, ждём ведущего: та же янтарная точка, но пульсирует,
                и второй тап не проходит (одна заявка = один вопрос ведущему). */
#caRecBtn.rec-ask, #gcRecBtn.rec-ask { opacity: .78; }
#caRecBtn.rec-ask::before, #gcRecBtn.rec-ask::before,
#caRecBtn.rec-wait::before, #gcRecBtn.rec-wait::before {
  content: ""; position: absolute; top: 5px; right: 5px; width: 8px; height: 8px;
  border-radius: 50%; background: #f59e0b; box-shadow: 0 0 0 2px rgba(0,0,0,.45);
}
#caRecBtn.rec-wait, #gcRecBtn.rec-wait { pointer-events: none; opacity: .72; }
#caRecBtn.rec-wait::before, #gcRecBtn.rec-wait::before { animation: recPendingPulse 1s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) {
  #caRecBtn.rec-wait::before, #gcRecBtn.rec-wait::before { animation: none; opacity: .7; }
}
/* 🔴🔴 CLIE-1219 · РЯД ЗВОНКА 1-НА-1 — ЭТО ТОТ ЖЕ ДОК, ЧТО В КОНФЕРЕНЦИИ.
   Раскладка, стекло, размер кнопки, подпись словом, «Ещё» и адаптив живут ОДНИМ
   набором правил рядом с `.groupcall-controls` (блок «ДОК ЗВОНКА 1-НА-1» ниже по
   файлу). Здесь остаются только состояния, которых у дока конференции нет:
   «Принять»/«Отклонить»/«Завершить» — текстовые пилюли входящего, а не иконки ряда. */
.call-controls .primary { background: var(--acc-grad); }
.call-controls .danger { background: var(--danger); }
/* «Идёт показ экрана» — общее состояние обеих поверхностей (`.sharing` в блоке дока). */
.call-diag {
  position: absolute; left: 0; right: 0; bottom: calc(env(safe-area-inset-bottom) + 4px);
  z-index: 2; text-align: center; font-size: 10px; opacity: .5;
}

/* ─────────── Аудиозвонок: красивый режим (градиент, аватар с пульсацией) ───────────
   🔴 CLIE-606·5 — ЭТО РАСКЛАДКА, А НЕ ВТОРОЙ РЕНДЕР ЧЕЛОВЕКА.
   Раньше здесь стоял свой блок `.ca-avatar` + `.ca-initial` + `.ca-wave`: свой кружок,
   монограмма В ОДНУ БУКВУ, свой градиент (один на всех — тёзки неразличимы) и эквалайзер
   из девяти полос, который анимировался ВСЕГДА, даже в полной тишине. Теперь лицо, имя,
   значок «микрофон выключен» и эквалайзер даёт та же плитка `.gtile`, что в конференции,
   а «аудио-дизайн» — это её РАСКЛАДКА: крупный кружок по центру, имя под ним, пульс-кольца
   на гудках. Правится в одном месте — правится везде (правило CLIE-606·2).
   Своя вертикаль: --hero-av — диаметр кружка, --hero-c — его центр (чуть выше середины,
   чтобы имя и статус не наезжали на панель кнопок). */
.call-audio { display: none; }
.call-overlay.audio-mode .call-box {
  background: linear-gradient(180deg, var(--cm-7a6cf0, #7A6CF0) 0%, var(--cm-5b57d8, #5B57D8) 52%, var(--cm-3b368f, #3B368F) 100%);
}
.call-overlay.audio-mode .videos {
  --hero-av: clamp(168px, 46vmin, 224px);
  --hero-c: calc(50% - clamp(40px, 9vh, 92px));
  background: transparent;
}
.call-overlay.audio-mode .call-status { display: none; } /* дублируется по центру в .ca-status */
.call-overlay.audio-mode .call-audio {
  display: block; position: absolute; inset: 0; z-index: 2; pointer-events: none;
}
/* В голосовом звонке своей камеры нет по определению — врезка не нужна. */
/* 🔴 Адресуемся к РОЛИ, а не к человеку (ЗВОН-693): после обмена местами во врезке лежит
   собеседник, и правило «в аудио врезки нет» обязано гасить именно врезку. */
.call-overlay.audio-mode .videos > .cc-inset { display: none; }
/* Плитка собеседника лежит на градиенте: ни рамки, ни своей заливки, ни скрима. */
.call-overlay.audio-mode .videos > .remote-tile { background: transparent; }
.call-overlay.audio-mode .videos > .remote-tile::after { display: none; }
/* Водяной знак «кто и когда смотрел» — про КАДР. Кадра нет (голосовой звонок) — знака
   тоже нет: снимать нечего (та же логика, что `.gtile.cam-off .cc-wm` в каноне).
   Раньше это делалось само, потому что весь `.videos` был display:none. */
.call-overlay.audio-mode .videos .cc-wm { display: none; }
/* КРУПНЫЙ кружок: ~46vmin, но в пределах 168–224px — большой на телефоне, аккуратный на
   десктопе. Фото заполняет круг (cover); нет фото — ДВЕ буквы на детерминированном
   градиенте (`CallUi.face`), то есть тёзки различимы. */
.call-overlay.audio-mode .videos > .remote-tile .gt-avatar {
  display: flex; top: var(--hero-c); width: var(--hero-av); height: var(--hero-av);
  font-size: clamp(48px, 18vmin, 88px); letter-spacing: 0;
  border: 3px solid rgba(255,255,255,.30);
  box-shadow: 0 18px 54px var(--cm-141246-6, rgba(20,18,70,.6));
}
/* Имя — крупной строкой под кружком (та же `.gname`, что в плитке: значок выключенного
   микрофона едет вместе с ней и наконец виден и в 1:1). */
.call-overlay.audio-mode .videos > .remote-tile .gname {
  left: 50%; right: auto; bottom: auto; transform: translateX(-50%);
  top: calc(var(--hero-c) + var(--hero-av) / 2 + 20px);
  max-width: min(90%, 620px); height: auto; padding: 0 8px;
  background: transparent; border: 0; backdrop-filter: none; -webkit-backdrop-filter: none;
  font-size: 27px; font-weight: 700; letter-spacing: .3px; gap: 9px;
}
.call-overlay.audio-mode .videos > .remote-tile .gt-mic svg.ic { width: 20px; height: 20px; }
/* 🔊 СТРОКА ГОЛОСА (CLIE-657). Эквалайзер тот же общий `.gt-eq`, но в аудио-режиме он не
   бейдж в углу кадра, а ГЛАВНЫЙ признак экрана: кадра тут нет вовсе, и «человек говорит»
   больше сообщить нечем. Поэтому три отличия от бейджа — и все три раскладочные:
     · ДЕВЯТЬ полосок вместо трёх (`opts.eq` у канона) и масштаб 1.6 — видно с метра;
     · строка живёт ВЕСЬ разговор: молчание рисуется ПОКОЕМ (ровная нить), а не
       исчезновением. Владелец: «на ПК не видно линий, что кто-то говорит» — пропадающий
       индикатор читается как «сломалось», а вечно бегущий (мобилка) просто врёт;
     · яркость говорит то же, что высота: покой приглушён, речь — в полную силу. */
.call-overlay.audio-mode .videos > .remote-tile .gt-eq {
  top: calc(var(--hero-c) + var(--hero-av) / 2 + 96px); right: auto; left: 50%;
  transform: translateX(-50%); background: transparent; backdrop-filter: none;
  -webkit-backdrop-filter: none; height: 30px; padding: 0; gap: 5px;
  --eq-s: 2.2; --eq-min: 3px;
  opacity: .42; transition: opacity 160ms ease;
}
.call-overlay.audio-mode.in-call .videos > .remote-tile .gt-eq { display: flex; }
.call-overlay.audio-mode .videos > .remote-tile.speaking .gt-eq { opacity: 1; }
.call-overlay.audio-mode .videos > .remote-tile .gt-eq i { background: rgba(255,255,255,.92); border-radius: 3px; }
.call-overlay.audio-mode.ringing .videos > .remote-tile .gt-avatar::before,
.call-overlay.audio-mode.ringing .videos > .remote-tile .gt-avatar::after {
  content: ""; position: absolute; inset: -2px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.55);
  animation: caPulse 2.4s cubic-bezier(.2,.6,.3,1) infinite;
}
.call-overlay.audio-mode.ringing .videos > .remote-tile .gt-avatar::after { animation-delay: 1.2s; }
@keyframes caPulse { 0% { transform: scale(1); opacity: .6; } 100% { transform: scale(1.6); opacity: 0; } }
/* Статус звонка («Вызываем…», «03:17») — это про ЗВОНОК, а не про человека, поэтому он
   остаётся своим текстом поверхности; кладём его под имя. */
.ca-status {
  position: absolute; left: 0; right: 0;
  top: calc(50% - clamp(40px, 9vh, 92px) + clamp(168px, 46vmin, 224px) / 2 + 62px);
  text-align: center; font-size: 15px; color: rgba(255,255,255,.85);
}
/* панель кнопок поверх градиента — читаемый фон */
/* 🔴 Стекло ряда в аудио-режиме — ТО ЖЕ, что и всегда (`--ov-plate`, CLIE-1055):
   отдельной белёсой заливки у дока звонка больше нет, иначе на светлом кадре кнопка
   снова сливается, а «выключено» тонет в полупрозрачности. */
.call-overlay.audio-mode .call-controls .danger { background: var(--danger); }

/* ═══ Свёрнутое окно 1-на-1 звонка (PiP) — стеклянный минимализм, Apple-grade ═══
   Перетаскивается по ВСЕМУ экрану (без прилипания к краю), меняет размер (угловой хват),
   контролы (микрофон·камера·сброс, развернуть·вбок) проявляются при наведении — в покое
   видно только видео + пилюлю таймера (прогрессивное раскрытие). Ширина/высота задаются
   инлайн из JS (drag/resize + запомненный размер), дефолт — тут. */
.call-overlay.minimized {
  inset: auto; bottom: 84px; right: 16px;
  width: 150px; height: 214px; border-radius: 20px; overflow: hidden;
  background: var(--cm-0b0d12, #0b0d12);
  border: 1px solid rgba(255,255,255,.12);
  box-shadow: 0 12px 40px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.32);
  cursor: grab;
}
.call-overlay.minimized.dragging { cursor: grabbing; }
.call-overlay.minimized.resizing { cursor: nwse-resize; }
.call-overlay.minimized .videos > .cc-inset { display: none; } /* в мини — только крупный кадр */
/* В окошке 150px хвату размера, «⋯» и меню врезки места нет — это чрома полноэкранного
   звонка. Тот же приём, что у поверхностей интерактива (`.call-overlay.minimized .cc-ink`). */
.call-overlay.minimized .sv-grip, .call-overlay.minimized .sv-more,
.call-overlay.minimized .sv-show, .call-overlay.minimized .sv-menu,
.call-overlay.audio-mode .sv-show, .call-overlay.audio-mode .sv-menu { display: none; }
/* Имя и «свернуть» в окошке 150px не читаются — окно и так про одного человека. */
.call-overlay.minimized .videos > .remote-tile .gname,
.call-overlay.minimized .videos > .remote-tile .gt-collapse { display: none; }
.call-overlay.minimized .call-controls,
.call-overlay.minimized .call-diag { display: none; }

/* Пилюля с таймером/статусом — единственный постоянно видимый элемент (слева сверху) */
.call-overlay.minimized .call-status {
  position: absolute; left: 8px; top: 8px; right: auto; bottom: auto;
  z-index: 5; width: max-content; max-width: calc(100% - 16px);
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 9px 4px 7px; border-radius: 999px;
  font-size: 11px; font-weight: 650; line-height: 1; letter-spacing: .2px;
  color: #fff; text-align: left; text-shadow: none;
  background: rgba(10,12,16,.5); -webkit-backdrop-filter: blur(12px) saturate(1.4); backdrop-filter: blur(12px) saturate(1.4);
  border: 1px solid rgba(255,255,255,.08);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  pointer-events: none;
}
.call-overlay.minimized .call-status::before {
  content: ""; flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: #f5a623;
}
.call-overlay.minimized.in-call .call-status::before { background: #34d399; animation: cmDot 2.2s ease-out infinite; }
@keyframes cmDot { 0% { box-shadow: 0 0 0 0 rgba(52,211,153,.55); } 70%, 100% { box-shadow: 0 0 0 6px rgba(52,211,153,0); } }
/* аудио-звонок в мини: пилюлю показываем (в полноэкранном аудио она скрыта) */
.call-overlay.audio-mode.minimized .call-status { display: inline-flex; }
.call-overlay.minimized.docked .call-status { display: none; }

/* Плавающие панели-контролы: скрыты в покое, проявляются при наведении / drag / resize */
.cm-top, .cm-bottom, .cm-grip {
  position: absolute; z-index: 6; opacity: 0;
  transition: opacity .16s ease; pointer-events: none;
}
.call-overlay:not(.minimized) .cm-top,
.call-overlay:not(.minimized) .cm-bottom,
.call-overlay:not(.minimized) .cm-grip { display: none; }   /* в полноэкранном звонке мини-хрома нет */
.call-overlay.minimized.docked .cm-top,
.call-overlay.minimized.docked .cm-bottom,
.call-overlay.minimized.docked .cm-grip { display: none; }  /* прижато вбок — контролов нет */
.call-overlay.minimized:not(.docked):hover .cm-top,
.call-overlay.minimized:not(.docked):hover .cm-bottom,
.call-overlay.minimized:not(.docked):hover .cm-grip,
.call-overlay.minimized.dragging .cm-top, .call-overlay.minimized.dragging .cm-bottom,
.call-overlay.minimized.resizing .cm-top, .call-overlay.minimized.resizing .cm-bottom, .call-overlay.minimized.resizing .cm-grip {
  opacity: 1; pointer-events: auto;
}
/* тач-устройства (нет hover) — контролы видны всегда */
@media (hover: none) {
  .call-overlay.minimized:not(.docked) .cm-top,
  .call-overlay.minimized:not(.docked) .cm-bottom,
  .call-overlay.minimized:not(.docked) .cm-grip { opacity: 1; pointer-events: auto; }
}
/* верхний/нижний скрим-градиенты под контролами (читаемость) */
.cm-top {
  top: 0; left: 0; right: 0; height: 54px; padding: 7px;
  display: flex; align-items: flex-start; justify-content: flex-end;
  background: linear-gradient(180deg, rgba(0,0,0,.4), rgba(0,0,0,0));
  border-radius: 20px 20px 0 0;
}
.cm-actions { display: flex; align-items: center; gap: 6px; }
.cm-bottom {
  bottom: 0; left: 0; right: 0; min-height: 54px; padding: 8px;
  display: flex; align-items: flex-end; justify-content: center; gap: 12px;
  background: linear-gradient(0deg, rgba(0,0,0,.52), rgba(0,0,0,0));
  border-radius: 0 0 20px 20px;
}
/* круглые стеклянные кнопки мини-окна */
.cm-btn {
  width: 30px; height: 30px; flex: 0 0 auto; padding: 0; border: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; cursor: pointer;
  color: #fff; font-size: 17px; line-height: 1;
  background: var(--cm-16181e-5, rgba(22,24,30,.5)); -webkit-backdrop-filter: blur(12px) saturate(1.4); backdrop-filter: blur(12px) saturate(1.4);
  box-shadow: 0 1px 4px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.1);
  transition: background .13s ease, transform .12s ease;
}
.cm-btn:hover { background: var(--cm-2c2e36-72, rgba(44,46,54,.72)); transform: translateY(-1px); }
.cm-btn:active { transform: translateY(0) scale(.93); }
.cm-btn svg { width: 16px; height: 16px; display: block; }
.cm-bottom .cm-btn { width: 38px; height: 38px; }
.cm-bottom .cm-btn svg { width: 18px; height: 18px; }
.cm-btn.danger { background: var(--danger); box-shadow: 0 3px 10px rgba(255,59,48,.42), inset 0 0 0 1px rgba(255,255,255,.16); }
.cm-btn.danger:hover { background: #ff5147; }
.cm-btn.off { background: rgba(255,59,48,.86); box-shadow: 0 2px 8px rgba(255,59,48,.4), inset 0 0 0 1px rgba(255,255,255,.16); } /* микрофон/камера выключены */
.cm-btn.hidden { display: none; }
/* хват изменения размера — правый нижний угол */
.cm-grip {
  right: 1px; bottom: 1px; width: 24px; height: 24px; z-index: 7;
  display: flex; align-items: flex-end; justify-content: flex-end; padding: 4px;
  color: rgba(255,255,255,.82); cursor: nwse-resize; touch-action: none;
}
.cm-grip svg { width: 13px; height: 13px; display: block; filter: drop-shadow(0 1px 2px rgba(0,0,0,.7)); }
/* Аудио-звонок в мини-окне: кружок заполняет окно, без пульс-колец, имени и эквалайзера.
   Та же плитка канона — просто ещё одна раскладка (CLIE-606·5). */
.call-overlay.audio-mode.minimized .ca-status { display: none; }
.call-overlay.audio-mode.minimized .videos { --hero-c: 50%; }
.call-overlay.audio-mode.minimized .videos > .remote-tile .gt-avatar {
  width: 100%; height: 100%; border-radius: 0; border: none; box-shadow: none;
  font-size: 46px;
}
.call-overlay.audio-mode.minimized .videos > .remote-tile .gt-avatar::before,
.call-overlay.audio-mode.minimized .videos > .remote-tile .gt-avatar::after { display: none; }
.call-overlay.audio-mode.minimized .videos > .remote-tile .gname,
.call-overlay.audio-mode.minimized .videos > .remote-tile .gt-eq { display: none; }
.mini-bar {
  display: none; position: absolute; left: 0; right: 0; bottom: 8px; z-index: 4;
  align-items: center; justify-content: center; gap: 12px;
}
/* 🔴 КОРЕНЬ «иконки не ровно»: без flex-центрирования текстовая «›» и SVG-иконки сидят на
   РАЗНОЙ базовой линии → скачут по высоте. Центрируем содержимое каждой круглой кнопки. */
.mini-bar button {
  width: 36px; height: 36px; border-radius: 50%; padding: 0; font-size: 18px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,.18); border-color: transparent; color: #fff;
}
.mini-bar button svg.ic { display: block; }
.mini-bar .danger { background: var(--danger); }

/* ---- перетаскивание + прижатие вбок свёрнутой плашки ---- */
.call-overlay.minimized { transition: transform .22s ease; touch-action: none; }
/* ручное позиционирование (drag) перебивает угловые bottom/right из .minimized */
.call-overlay.minimized.placed { bottom: auto; right: auto; }
/* прижато к краю: уезжает почти за экран, виден ярлычок ~26px (стрелка возврата) */
.call-overlay.minimized.docked[data-dock="right"] { transform: translateX(calc(100% - 26px)); }
.call-overlay.minimized.docked[data-dock="left"]  { transform: translateX(calc(-100% + 26px)); }
.call-overlay.minimized.docked .mini-bar { display: none; } /* в доке кнопки прячем */
/* стрелка возврата (общая для личного и группового окна) — видна только в доке */
.mini-restore {
  display: none; align-items: center; justify-content: center;
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 22px; height: 46px; padding: 0; z-index: 6; font-size: 16px; color: #fff;
  background: rgba(255,255,255,.22); border: none; border-radius: 8px;
}
.minimized.docked .mini-restore { display: flex; }
/* видимый ярлычок: при доке вправо видна ЛЕВАЯ кромка окна, при доке влево — правая */
.minimized.docked[data-dock="right"] .mini-restore { left: 3px; }
.minimized.docked[data-dock="left"]  .mini-restore { right: 3px; }

/* кнопка «развернуть» на свёрнутой плашке — слева сверху, иконка «2 стрелки навстречу»
   (как у всех PiP). Видна только когда звонок свёрнут и НЕ прижат вбок. */
.mini-tl-btn { display: none; }
.minimized .mini-tl-btn {
  display: flex; align-items: center; justify-content: center;
  position: absolute; top: 8px; left: 8px; z-index: 6;
  width: 36px; height: 36px; padding: 0; border-radius: 50%;
  background: rgba(0,0,0,.5); color: #fff; border: none;
}
.minimized .mini-tl-btn svg.ic { width: 18px; height: 18px; display: block; }
.minimized.docked .mini-tl-btn { display: none; }

/* кнопка «показать всех участников» — справа сверху свёрнутой плашки (только группа) */
.mini-tr-btn { display: none; }
.minimized .mini-tr-btn {
  display: flex; align-items: center; justify-content: center;
  position: absolute; top: 8px; right: 8px; z-index: 6;
  width: 36px; height: 36px; padding: 0; border-radius: 50%;
  background: rgba(0,0,0,.5); color: #fff; border: none;
}
.minimized .mini-tr-btn svg.ic { width: 18px; height: 18px; display: block; }
.minimized.docked .mini-tr-btn { display: none; }

/* ---- свёрнутый ГРУППОВОЙ созвон: плавающее окно со ВСЕМИ участниками ----
   Было: фикс. 150×200 + сетка тайлов min-height:140 → даже ОДИН участник обрезался,
   несколько не влезали вовсе. Стало: мини = вертикальная лента маленьких тайлов;
   окно тянется по контенту до max-height и скроллит остаток. Кнопка ↕ (gcListBtn)
   ПРЯЧЕТ/ПОКАЗЫВАЕТ саму ленту участников (класс .gc-collapsed): свёрнуто = только
   шапка + подвал; развёрнуто = все участники вертикально. НЕ ресайз поля. */
.groupcall-overlay.minimized {
  inset: auto; bottom: 84px; right: 16px;
  width: 176px; height: auto; max-height: 62vh;
  border-radius: 18px; overflow: hidden;
  box-shadow: 0 16px 44px rgba(0,0,0,.55);
  border: 1px solid rgba(255,255,255,.08);
  background: linear-gradient(180deg, var(--cm-141822, #141822), var(--cm-0b0d12, #0b0d12));
  cursor: pointer; touch-action: none;
  transition: transform .22s ease, width .18s ease, max-height .18s ease, right .18s ease;
  display: flex; flex-direction: column;
}
/* 🔴 ЗВОН-905·4 — СВЁРНУТЫЙ СОЗВОН ОТХОДИТ ОТ ПРАВОЙ ШТОРКИ, А НЕ УХОДИТ ПОД НЕЁ.
   Карточку доски (`.task-info-panel.as-overlay`, 480px) человек открывает ПОВЕРХ идущего
   звонка — и она ложилась ровно на свёрнутое окно: «не потеряв ни звонок, ни переписку»
   переставало выполняться в первой же половине. Зазор считает ОДНА дверь `ccRightGap`
   (брат `ccBottomGap`) по РАЗМЕТКЕ, а не по списку экранов. `.placed`/`.docked` исключены
   намеренно: окно, переставленное рукой, правило не двигает (канон `hand-beats-rule-order`). */
.groupcall-overlay.minimized:not(.placed):not(.docked),
.call-overlay.minimized:not(.placed):not(.docked) {
  right: calc(16px + var(--cc-right-gap, 0px));
  transition: right .18s ease;
}
.groupcall-overlay.minimized.placed { bottom: auto; right: auto; }
/* шапка — компактная, заголовок по центру между угловыми кнопками */
.groupcall-overlay.minimized .groupcall-head {
  flex: 0 0 auto; flex-wrap: nowrap; font-size: 11px; padding: 8px 34px 6px; gap: 6px;
  justify-content: center; text-align: center; color: #fff;
  background: rgba(255,255,255,.04); border-bottom: 1px solid rgba(255,255,255,.06);
}
.groupcall-overlay.minimized .groupcall-title {
  flex: 0 1 auto; min-width: 0; font-size: 12px; font-weight: 700;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.groupcall-overlay.minimized .groupcall-head .small { flex: 0 0 auto; white-space: nowrap; }
.groupcall-overlay.minimized .groupcall-controls { display: none; }
/* сетка → вертикальная лента: влезают ВСЕ участники (скролл, если очень много) */
.groupcall-overlay.minimized .group-grid,
.groupcall-overlay.minimized .group-grid.spotlight {
  display: flex; flex-direction: column; gap: 8px; padding: 8px; margin: 0;
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden;
  align-content: flex-start; /* тонкий скролл — через общий ::-webkit-scrollbar (Safari/Chrome) */
}
.groupcall-overlay.minimized .group-grid .gtile,
.groupcall-overlay.minimized .group-grid.spotlight .gtile,
.groupcall-overlay.minimized .group-grid .gtile.main {
  flex: 0 0 auto; width: 100%; height: 92px; min-height: 0;
  aspect-ratio: auto; order: 0; border-radius: 12px;
}
.groupcall-overlay.minimized .gname { font-size: 10px; padding: 2px 7px; left: 6px; bottom: 6px; height: auto; }
/* активный спикер в мини — рамка ВНУТРЬ тайла (не задевает соседей/шапку); пульс гасим,
   иначе кольцо «дышало» бы на ленте 92-пиксельных плиток свёрнутого окна.
   🔴 ЗВОН-34: пульс переехал с самой плитки на её слой `.gtile.speaking::before`
   (там анимируется ТОЛЬКО opacity, а не box-shadow поверх живого видео) — поэтому
   одного `animation: none` на `.gtile` больше не хватает, гасим и слой. */
.groupcall-overlay.minimized .gtile.speaking { box-shadow: inset 0 0 0 2px var(--primary); animation: none; }
.groupcall-overlay.minimized .gtile.speaking::before { display: none; }
/* ── совместимость редизайна со свёрнутым (PiP) режимом ── */
.groupcall-overlay.minimized .gc-stage { flex: 1 1 auto; min-height: 0; display: flex; padding: 0; }
.groupcall-overlay.minimized .gc-head-main { flex-direction: row; align-items: center; gap: 6px; }
.groupcall-overlay.minimized .gc-head-sub, .groupcall-overlay.minimized .gc-head-right { display: none; }
/* 🔴 Исключение: «Восстанавливаем связь…» показываем ДАЖЕ в свёрнутом (PiP) окне. Это
   состояние ПРОБЛЕМЫ: без него замерший кадр в мини-окне неотличим от «всё сломалось»,
   и человек кладёт трубку ровно в тот момент, когда связь уже восстанавливается. */
.groupcall-overlay.minimized .gc-head-right:has(> #gcNetChip) { display: flex; }
.groupcall-overlay.minimized .gc-head-right:has(> #gcNetChip) > :not(#gcNetChip) { display: none; }
.groupcall-overlay.minimized #gcNetChip { height: 24px; padding: 0 9px; font-size: 11px; }
.groupcall-overlay.minimized .gt-eq { display: none; }
.groupcall-overlay.minimized .gt-avatar { width: 44px; font-size: 16px; box-shadow: none; }
/* «Скрыть участников» — прячем ленту целиком; окно = шапка + подвал (тонкая плашка) */
.groupcall-overlay.minimized.gc-collapsed { max-height: none; }
.groupcall-overlay.minimized.gc-collapsed .group-grid { display: none; }
/* нижняя панель (свернуть вбок / выйти) — обычная строка-подвал, не поверх видео.
   🔴 Владелец 10.10.2026 («кнопки свернуть», раунд 3): В МИНИ-ОКНЕ кнопки стоят ПОСЕРЕДИНЕ —
   «там кнопки должны быть посередине, а не сбоку». Правка 09.10 (flex-end) ОТКАЧЕНА: просьба
   «кнопки окна у края» касалась ДОКА звонка (ccDockWinLast в app.js), а не этого подвала.
   Здесь кнопок всего две на узкой плашке 176px, и центр — её исходный вид. НЕ менять без слова
   владельца. */
.groupcall-overlay.minimized .gc-mini-bar {
  position: static; flex: 0 0 auto; display: flex; justify-content: center; gap: 12px;
  padding: 7px; background: rgba(0,0,0,.28); border-top: 1px solid rgba(255,255,255,.06);
}
/* угловые кнопки в мини — компактнее, чтобы не давить шапку */
.groupcall-overlay.minimized .mini-tl-btn,
.groupcall-overlay.minimized .mini-tr-btn {
  width: 28px; height: 28px; top: 7px; background: rgba(0,0,0,.45);
}
.groupcall-overlay.minimized .mini-tl-btn { left: 7px; }
.groupcall-overlay.minimized .mini-tr-btn { right: 7px; }
.groupcall-overlay.minimized .mini-tl-btn svg.ic,
.groupcall-overlay.minimized .mini-tr-btn svg.ic { width: 15px; height: 15px; }
/* прижатие вбок (док) */
.groupcall-overlay.minimized.docked[data-dock="right"] { transform: translateX(calc(100% - 26px)); }
.groupcall-overlay.minimized.docked[data-dock="left"]  { transform: translateX(calc(-100% + 26px)); }
.groupcall-overlay.minimized.docked .gc-mini-bar,
.groupcall-overlay.minimized.docked .mini-tr-btn { display: none; }

/* ---- log ---- */
.log-panel {
  position: fixed; bottom: 0; left: 0; right: 0;
  background: var(--panel); border-top: 1px solid var(--line);
  max-height: 40vh; z-index: 20;
}
.log-panel summary { padding: 6px 12px; cursor: pointer; color: var(--muted); font-size: 12px; }
.log {
  margin: 0; padding: 8px 12px; max-height: 32vh; overflow-y: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; color: #9fb0c8; white-space: pre-wrap;
}

/* ---- login polish ---- */
.card .logo { font-size: 44px; text-align: center; margin-bottom: 6px; }
.card h1 { text-align: center; }
#stepPhone > p.muted, #stepCode > p.muted { text-align: center; margin: 0 0 18px; }
#codeInput { letter-spacing: .35em; text-align: center; font-size: 22px; font-weight: 600; }
.hint { text-align: center; }
#backBtn { width: 100%; margin-top: 8px; }

.thread-head-info { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* 🔴 CLIE-1190 «Зачем тут стрелка?»: стрелка «назад к списку» нужна ТОЛЬКО там, где списка
   бесед не видно (узкое окно/мобила). На широком окне список слева на месте, а клик по стрелке
   лишь снимает класс show-thread — видимого эффекта НЕТ, это мёртвый контрол в шапке.
   🔴 ПРЯЧЕМ ПО ID, а не по классу: `.back-mobile` (0,1,0) проигрывал по весу `.ghost.small`
   (0,2,0, style.css выше по файлу) — правило НИКОГДА не срабатывало, и стрелка висела в шапке
   на любой ширине. Хосты-встройки (карточка задачи, CRM, миничат) гасят её своим !important —
   он по-прежнему сильнее. */
#backToList.back-mobile { display: none; }
.composer .primary { width: auto; min-width: 52px; margin: 0; padding: 10px 18px; font-size: 16px; }

/* средние экраны: прячем колонку «Мои контакты», оставляя рельс+чаты+тред.
   Ширина чатов остаётся перетаскиваемой (var сохраняется). */
/* рельс-кнопка «Задачи» видна ВЕЗДЕ, включая десктоп (задача fa8dd2a0, владелец: «самый
   левый рейл, между Проекты и События»). Раньше на десктопе пряталась (дубль столбика
   «Мои задачи»), но рейл открывает ПОЛНОЕ пространство задач — это не дубль столбика. */

@media (max-width: 1080px) and (min-width: 721px) {
  /* тот же принцип, что в базовой сетке (CLIE-265): чаты усыхают, тред держит
     --thread-min и не выдавливает свою шапку за край. */
  .chat { grid-template-columns: var(--rail-track) minmax(0, var(--w-chats, 280px)) minmax(var(--thread-min, 420px), 1fr); }
  .tasks-col { display: none; }                 /* мало места — задачи прячем (как раньше контакты) */
  .projects-col { display: none; }              /* столбик проектов прячем вместе с задачами */
}

/* узкие экраны / мобила */
@media (max-width: 720px) {
  /* 🧭 Узкий экран: рейка уже, ВТОРОГО МЕНЮ НЕТ (наведения на касании нет, ширины тоже).
     Функция не теряется — нажатие по хабу открывает его активный/первый вид той же дверью. */
  :root { --rail-w: 62px; }
  .chat-rail.hub-open .rail-hub { display: none; }
  /* рельс остаётся слева, уже. Дорожка — minmax(0,1fr), не голый 1fr: у 1fr минимум = min-content
     колонки, а ряд вкладок чатов (11 разделов в строку) даёт ~1840 px — на телефоне 390 строки, время
     и поиск уезжали за край (замер 20.10.2026, «Штиль»; «Глубина» чинила это у себя с волны 1). */
  .chat { grid-template-columns: var(--rail-track) minmax(0, 1fr); }
  .tasks-col { display: none; }                 /* столбик задач прячем — мало места */
  .projects-col { display: none; }              /* столбик проектов тоже прячем */
  .col-resizer { display: none; }               /* на мобиле колонки не тянем */
  .rail-col { padding: 8px 5px 0; }
  .rail-tail { padding-bottom: 8px; }
  .rail-item { padding: 7px 2px; }
  .rail-item .rail-ic svg.ic { width: 20px; height: 20px; }
  /* rail-badge-covers-icon-1 · ideas-rail-active-badge-1 · mail-rail-badge-cover-1 · crm-mobile-rail-1.
     Бейдж стоит от края кнопки (top 4 · right 8 — мерка рейки 96 px). В рейке 62 px поле кнопки 44 px,
     значок 20 px по центру, и «99+»/«34» ложились прямо на значок (замер 390: бейдж x 19–48, значок 24–44).
     В угол поля кнопки — бейдж садится на верхний правый угол значка, как на компьютере, и не вылезает
     из кнопки (её режет прокрутка .rail-scroll). */
  .rail-badge { top: 0; right: 0; }
  /* mail-rail-label-cut-1 · «Среда разработчика» резалась в «Среда разра-…»: две строки по слогам
     не вмещают слово из 12 букв в 44 px. Третья строка нужна только редким длинным подписям. */
  .rail-item .rail-label { -webkit-line-clamp: 3; }
  /* crm-mobile-rail-1 · пузырь миничата (#qcFab: left 16 · bottom 16 · 52 px) стоит над рельсом
     (y 776–828, плита до 836) и закрывал «Аю», нижнюю кнопку хвоста. Хвост отдаёт ему низ:
     16 + 52 + 8 воздуха. Поднятый пол (--cc-bottom-gap) здесь НЕ прибавляем: его уже вычел сам экран
     (`.screen`, 23.10.2026) — рейка кончается над полосой, второй подъём оставил бы пустую дыру. */
  :root.cc-qc-shown .rail-tail { padding-bottom: 76px; }
  /* crm-companies-topbar-clip-1 · crm-contacts-topbar-clip-1 · crm-shell-topbar-clip-1 · deal390-topbar-ai-clip ·
     deal-topbar-aya-clip-1 · topbar-ai-clip-1 · topbar-ai-clip-1-2 · project-topbar-clip-1 (раунд J; заменяет
     ступень раунда G на tb-fit-7: crm-topbar-overflow-1 · phone-topbar-overflow-1 · chats-topbar-overflow-1 ·
     mail-topbar-clip-1). На 390 шапка доходила до tb-fit-7 и листалась. Золотая ✦ (x 348) резалась кромкой
     плиты (385), профиль и колокольчик уходили за край. Теперь ряд влезает в 370 px плиты уже на tb-fit-6.
     Худший случай: режим с «99+» 112 + 2 · компания 53 · проекты с тремя монетами 61 · ✦ 36 · профиль 36 ·
     колокольчик 36 · связь 0 + 2 · 7 зазоров по 4 = 366. Что уходит из ряда и куда:
     — имена компании и проектов: остаются для чтеца экрана и в title; на виду значок/монеты и шеврон/крестик;
     — подпись ✦: на виду значок и янтарь «ждёт заявка», имя — в title и aria-label; та же дверь есть в меню профиля;
     — «Идеи»: строка меню профиля (hdrHiddenActs) и пункт рельса;
     — «Сегодня»: строка меню профиля, пока на виду ✦ (без ✦ кнопка стоит в ряду);
     — точка «связь в порядке»: молчит, а офлайн, очередь и обрыв возвращают точку (и пилюлю conn-warn).
     tb-fit-7 (прокрутка) остаётся последним рубежом: масштаб 130–200 % и янтарная пилюля со словом. */
  .topbar.tb-fit-6 { gap: 4px; }
  .topbar.tb-fit-6 .mode-toggle { margin-left: 2px; }
  .topbar.tb-fit-6 .proj-scope-hdr { margin-left: 0; }
  .topbar.tb-fit-6 .company-selector .company-selector-btn,
  .topbar.tb-fit-6 .proj-scope-btn { position: relative; gap: 5px; padding: 0 6px; }
  .topbar.tb-fit-6 .company-selector .csb-name,
  .topbar.tb-fit-6 .proj-scope-btn .csb-name {
    position: absolute; width: 1px; height: 1px; max-width: none; margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  .topbar.tb-fit-6 .hdr-aimine { min-width: var(--ctl-h); justify-content: center; }
  .topbar.tb-fit-6 .hdr-aimine .hdr-lbl,
  .topbar.tb-fit-6 #ideasBtn,
  .topbar.tb-fit-6:has(#aiMineBtn.ai-mine-shown) #todayBtn { display: none; }
  .topbar.tb-fit-6 .who.who-status { padding: 4px; }
  .topbar.tb-fit-6 .conn:not(.conn-warn):has(.dot-on) .dot { display: none; }
  /* leads-topbar-clip-1 · lead-topbar-clip-1 · deal-topbar-orb-clipped · topbar-orb-clipped-1 (раунд Q):
     «золотая орба» за колокольчиком — пилюля связи .conn.conn-warn (офлайн или N правок ждут отправки).
     Бюджет ступени 6 (366 из 370) её не считал, а исключение выше (tb-fit-1/2/3 → слово inline) держало в ряду
     слово: пилюля уходила за кромку плиты. На ступени 6 она — плитка --ctl-h с янтарной точкой; слово остаётся
     в разметке для чтеца экрана, title «Отправить отложенные правки сейчас» и нажатие «отправить» прежние.
     Место (36 + 4) отдаёт ✦: «Мой ИИ у коллег» и «Сегодня» переезжают в меню профиля (hdrHiddenActs берёт
     живую видимость) — пока висит янтарь. Ступени 1–5 (шире) показывают пилюлю со словом, как раньше. */
  .topbar.tb-fit-6:has(.conn.conn-warn) .hdr-aimine,
  .topbar.tb-fit-6:has(.conn.conn-warn) #todayBtn { display: none; }
  .topbar.tb-fit-6 .conn.conn-warn {
    position: relative; width: var(--ctl-h); height: var(--ctl-h); box-sizing: border-box;
    padding: 0; justify-content: center; border-radius: var(--ctl-r);
  }
  .topbar.tb-fit-6 .conn.conn-warn .muted {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
  /* topbar-bell-badge-overlap-1 · topbar-bell-badge-1 · topbar-bell-badge-1@crm_deals-dark ·
     topbar-bell-badge-1@crm_stock-dark · topbar-bell-badge-covers-glyph-1 · lead-topbar-badge-2 (раунд Q):
     ОДНО правило для всех бейджей шапки (колокольчик, «Сегодня», «Идеи» — все .notif-badge). «99+» (18 px,
     шрифт 10.5) стоял почти по центру кнопки и закрывал верх колокольчика. Теперь пилюля меньше (16 px,
     шрифт 10), в правом верхнем углу и вынесена наружу на 35 % своей ширины, как бейдж пузыря миничата;
     низ бейджа — на 8 px выше центра кнопки: глиф по центру (14–18 px) открыт, кроме ≤1 px. Точка .dot — база. */
  .topbar .notif-badge:not(.dot) {
    top: calc(50% - 24px); right: 0; transform: translateX(35%);
    min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; font-size: 10px; line-height: 16px;
  }
  /* ступень 7 — ряд сам плита с overflow-y:hidden (высота --topbar-h − 2·--isl-gy, поле 4): бейдж на 2 px
     ниже, чтобы верх не срезался кромкой */
  .topbar.tb-fit-7 .notif-badge:not(.dot) { top: calc(50% - 22px); }
  /* подпись переносится по слогам, а не «Событи/я», «Работ/а» по букве (замер 20.10.2026, «Штиль»;
     «Глубина» чинила у себя с волны 1); берёт и поля кнопки: «События» шире 40 px */
  .rail-item .rail-label {
    font-size: 10px; overflow-wrap: normal; word-break: normal; hyphens: auto; -webkit-hyphens: auto;
    margin-inline: -2px; max-width: calc(100% + 4px);
  }
  /* rail-label-hyphen-1 · в капсуле «хаб + открытый вид» (.rail-hubgrp, поле 4) кнопка была на 8 px уже
     соседей: коробка подписи 36 px против 44, и «Проекты» рвалось «Про-/екты». Поле капсулы 2, боковое
     поле кнопок внутри 0 — подпись снова 44 px, как у соседей; кольцо капсулы и её ширина прежние. */
  .rail-hubgrp { padding-inline: 2px; }
  .rail-hubgrp > .rail-item { padding-inline: 0; }
  .chat .sidebar { display: flex; }            /* список чатов — главный экран */
  .chat .thread { display: none; }
  .chat.show-thread .chat-rail { display: none; } /* в треде рельс скрыт, тред во всю ширину */
  .chat.show-thread { grid-template-columns: minmax(0, 1fr); }
  .chat.show-thread .sidebar { display: none; }
  .chat.show-thread .thread { display: flex; }
  #backToList.back-mobile { display: inline-flex; align-items: center; }  /* CLIE-1190: узкое окно — списка нет, стрелка = единственный выход */
  .login { padding: 16px; align-items: flex-start; padding-top: 8vh; }
  .card { border: none; background: transparent; padding: 10px; }
  .messages { padding: 14px; }
  .composer { padding: 12px 12px; padding-bottom: max(12px, env(safe-area-inset-bottom)); }
  .topbar { padding: 10px 16px; gap: 10px; }
  /* 🔴 CLIE-356: на мобиле мини-плеер — во всю ширину над композером/списком (в списке чатов
     композера нет, поэтому просто над нижним краем, с учётом safe-area). */
  .vmini { left: 8px; right: 8px; width: auto; bottom: calc(env(safe-area-inset-bottom) + 74px); }
}

/* ---- модалка: контакты / новый чат ---- */
.sidebar-head-actions { display: flex; gap: 6px; }
.modal-overlay {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(8,10,14,.72);
  /* меньший внешний отступ → модалка использует больше площади окна (CLIE-250) */
  display: flex; align-items: center; justify-content: center; padding: 10px;
}
/* ── Панель участников созвона: выезжает справа, поверх сетки ──────────────────
   Содержимое строит общий модуль participants.js (он же на странице гостя).
   Здесь только «рама»: положение, стекло, движение. */
.gc-people {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 12;
  width: min(348px, 92vw);
  display: flex; flex-direction: column;
  background: var(--cm-12151c-94, rgba(18, 21, 28, .94));
  -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  border-left: 1px solid rgba(255, 255, 255, .10);
  box-shadow: -18px 0 46px rgba(0, 0, 0, .42);
  transition: transform .16s cubic-bezier(.2,.8,.2,1), opacity .16s cubic-bezier(.2,.8,.2,1);
}
.gc-people.hidden { display: flex !important; transform: translateX(102%); opacity: 0; pointer-events: none; }
.gc-people > #gcPeopleMount { flex: 1 1 auto; min-height: 0; }
.gc-people-x {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  width: 30px; height: 30px; padding: 0; border-radius: 8px; border: 0;
  display: flex; align-items: center; justify-content: center;
  background: transparent; color: rgba(238,241,247,.62); cursor: pointer;
  transition: background .14s, color .14s;
}
.gc-people-x:hover { background: rgba(255,255,255,.12); color: #fff; }
.gc-people-x .ic { width: 16px; height: 16px; }
/* на узком экране панель занимает всю ширину — список важнее сетки */
@media (max-width: 560px) { .gc-people { width: 100%; border-left: 0; } }
/* свёрнутый в PiP созвон панель не показывает — там нет места */
.groupcall-overlay.minimized .gc-people { display: none !important; }

/* ═══════════ ЧАТ КОНФЕРЕНЦИИ (0114) — та же тёмная стеклянная панель ═══════════ */
.gc-chat {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 12;
  width: min(360px, 94vw);
  display: flex; flex-direction: column;
  background: var(--cm-12151c-94, rgba(18, 21, 28, .94));
  -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  border-left: 1px solid rgba(255, 255, 255, .10);
  box-shadow: -18px 0 46px rgba(0, 0, 0, .42);
  transition: transform .16s cubic-bezier(.2,.8,.2,1), opacity .16s cubic-bezier(.2,.8,.2,1);
}
.gc-chat.hidden { display: flex !important; transform: translateX(102%); opacity: 0; pointer-events: none; }
.gc-chat-head {
  flex: 0 0 auto; display: flex; align-items: center; height: 50px;
  padding: 0 46px 0 16px; border-bottom: 1px solid rgba(255,255,255,.08);
}
.gc-chat-title { font-size: 13px; font-weight: 650; letter-spacing: .01em; color: #eef1f7; }
.gc-chat-body {
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column; gap: 9px; padding: 14px 14px 8px;
}
.gc-chat-empty { margin: auto; text-align: center; color: rgba(238,241,247,.42); font-size: 12.5px; line-height: 1.55; padding: 24px 18px; }
.gcm { display: flex; flex-direction: column; max-width: 86%; animation: gcmIn .16s ease; }
.gcm.me { align-self: flex-end; align-items: flex-end; }
@keyframes gcmIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.gcm-a { font-size: 11px; font-weight: 600; color: rgba(238,241,247,.56); margin: 0 0 3px 3px; display: flex; align-items: center; gap: 5px; }
.gcm-guest { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: rgba(255,255,255,.62); background: rgba(255,255,255,.11); border-radius: 5px; padding: 1px 5px; }
.gcm-b {
  font-size: 13.5px; line-height: 1.42; color: #f2f4f9;
  background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.05);
  border-radius: 13px; padding: 7px 11px; word-break: break-word; white-space: pre-wrap;
}
.gcm.me .gcm-b { background: var(--acc-fill, var(--cm-5b7cfa, #5b7cfa)); border-color: transparent; color: #fff; }
.gcm-t { font-size: 10px; color: rgba(238,241,247,.32); margin: 3px 3px 0; }
.gc-chat-compose {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  padding: 10px 12px 12px; border-top: 1px solid rgba(255,255,255,.08);
}
.gc-chat-input {
  flex: 1 1 auto; min-width: 0; height: 38px; padding: 0 14px; border-radius: 19px;
  background: rgba(255,255,255,.06); border: 1px solid rgba(255,255,255,.10);
  color: #f2f4f9; font-size: 13.5px; outline: none; transition: border-color .14s, background .14s;
}
.gc-chat-input::placeholder { color: rgba(238,241,247,.36); }
/* 🔴 БЕЛЫМ ПО БЕЛОМУ (замер 11.09.2026, светлая тема, кадр clie1010r5-callchat-light): у поля
   computed `color: rgb(242,244,249)` и `background: rgb(255,255,255)` — человек печатал и видел
   ТОЛЬКО красную волну орфографии, своих букв не видел. Побеждало глобальное
   `html[data-theme="light"] input:focus { background:#fff }` (специфичность 0,2,2 против 0,2,0 у
   `.gc-chat-input:focus`). Оверлей созвона тёмный ВСЕГДА и в теме страницы не участвует, поэтому
   фон поля диктует он — `!important` осознанный, ровно как у соседнего `.gc-ai-input` ниже.
   `color-scheme: dark` — чтобы каретка и выделение тоже были из тёмной палитры. */
.gc-chat-compose { color-scheme: dark; }
.groupcall-overlay .gc-chat-input,
.gc-chat-input { background: rgba(255,255,255,.06) !important; }
.groupcall-overlay .gc-chat-input:focus,
.gc-chat-input:focus { border-color: var(--primary, var(--cm-5b7cfa, #5b7cfa)); background: rgba(255,255,255,.11) !important; }
.gc-chat-send {
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: 50%; border: 0; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  background: var(--acc-fill, var(--cm-5b7cfa, #5b7cfa)); color: #fff; transition: transform .12s, filter .12s, opacity .12s;
}
.gc-chat-send:hover { filter: brightness(1.08); }
.gc-chat-send:active { transform: scale(.92); }
.gc-chat-send .ic { width: 17px; height: 17px; }
.gc-chat-send:disabled { opacity: .4; cursor: default; }

/* ── 🔴 ЗВОН-932: в панель ПЕРЕЕХАЛ единый <main.thread> ──
   Пока он тут, лёгкая пара «своя лента + свой input» не рисуется вовсе: два чата рядом —
   это ровно тот дубль, из-за которого чат конференции и был «сторонним». Хост занимает всю
   высоту панели; сам тред уже умеет и ленту, и композер со скрепкой/эмодзи/голосовыми. */
.gc-chat-host { display: none; }
.gc-chat.thread-on .gc-chat-body,
.gc-chat.thread-on .gc-chat-compose { display: none; }
.gc-chat.thread-on .gc-chat-host { display: flex; flex: 1 1 auto; min-height: 0; flex-direction: column; }
.gc-chat-host > main.thread { flex: 1 1 auto; min-height: 0; min-width: 0; width: 100%; display: flex; flex-direction: column; background: transparent; }
/* Шапка беседы в панели лишняя: как называется встреча, написано СТРОКОЙ ВЫШЕ («Чат
   конференции»), а её кнопки звонка внутри идущего созвона предлагали бы позвонить из звонка. */
.gc-chat-host > main.thread > .thread-head,
.gc-chat-host > main.thread > header { display: none !important; }
@media (max-width: 560px) { .gc-chat { width: 100%; border-left: 0; } }
/* на широком экране открытый чат ужимает сцену, чтобы плитки не пряталась под панелью */
@media (min-width: 561px) {
  .groupcall-overlay.gc-chat-open .gc-stage,
  .groupcall-overlay.gc-people-open:not(.minimized) .gc-stage,
  .groupcall-overlay.gc-prop-open:not(.minimized) .gc-stage { padding-right: 360px; transition: padding-right .16s ease; }
  /* 🔴 CLIE-937: ряд кнопок — СОСЕДКА сцены, а не её ребёнок, поэтому отступ сцены его не
     двигал: на окне поуже открытая панель чата ЛОЖИЛАСЬ ПОВЕРХ правого края ряда, и
     «Окно поверх других программ», «Свернуть в окно» и «На весь экран» переставали
     нажиматься вовсе. Поймано прибором на живом проде (клик по #gcPipBtn перехватывал
     #attachBtn панели). Мёртвая по перекрытию кнопка неотличима от сломанной — а жалоба
     владельца была ровно про эту кнопку.
     Двигаем ДВУМЯ вещами сразу: `max-width` не даёт ряду вырасти под панель, а сдвиг на
     ПОЛОВИНУ её ширины возвращает ряд в оптический центр СВОБОДНОЙ части (одного max-width
     мало — ряд центрируется `margin:auto` по ВСЕЙ ширине, и правый край уходит лишь на 180px). */
  .groupcall-overlay.gc-chat-open .groupcall-controls,
  /* «Участники» (.gc-people, 348px) — та же правая шторка, тот же сдвиг (07.10.2026). */
  .groupcall-overlay.gc-people-open:not(.minimized) .groupcall-controls,
  .groupcall-overlay.gc-prop-open:not(.minimized) .groupcall-controls {
    max-width: calc(100vw - 28px - 360px);
    transform: translateX(-180px);
    transition: max-width .16s ease, transform .16s ease;
  }
}
/* свёрнутый в PiP созвон чат не показывает */
.groupcall-overlay.minimized .gc-chat { display: none !important; }
/* в режиме ЭФИРА — у зрителей свой эфемерный чат (#stPanel); сохраняемый чат конфы прячем */
.groupcall-overlay.stream-mode #gcChatBtn,
.groupcall-overlay.stream-mode .gc-chat { display: none !important; }

/* Счётчик «сколько ждёт входа» на кнопке участников — единственный способ
   заметить гостя, если панель закрыта. */
.gc-badge {
  position: absolute; top: 2px; right: 2px; min-width: 17px; height: 17px; padding: 0 4px;
  border-radius: 999px; background: var(--danger, #ef4444); color: #fff;
  font-size: 10.5px; font-weight: 700; line-height: 17px; text-align: center;
  box-shadow: 0 0 0 2px var(--cm-0b0d12-9, rgba(11,13,18,.9));
}
.groupcall-controls .ghost { position: relative; }

/* 🔴 Модалка, поднятая в ВЕРХНИЙ СЛОЙ поверх полноэкранного созвона (initModalsTopLayer в
   app.js). Popover приносит свои UA-стили (fit-content, рамка, своя подложка, margin:auto) —
   гасим их, чтобы модалка выглядела ТОЧНО так же, как в обычном режиме. Без этого сброса
   всплывшая модалка съезжала бы в угол с чужой рамкой. */
.modal-overlay[popover] {
  position: fixed; inset: 0; margin: 0; border: 0; padding: 16px;
  width: auto; height: auto; max-width: none; max-height: none;
  overflow: visible; color: inherit;
  /* background НЕ задаём: пусть работает общая тема (.modal-overlay → var(--scrim) + блюр),
     иначе всплывшая модалка отличалась бы фоном от обычной. UA-фон поповера перебит автором. */
}
.modal-overlay[popover]:popover-open { display: flex; }
.modal-overlay[popover]::backdrop { background: transparent; }
.modal-box {
  /* Размер модалок увеличен (задача CLIE-250 «Размер модальных окон»): базовые диалоги
     стали шире и выше, чтобы содержимое было легче разглядеть. Крупные контентные
     модалки (set2/gs2/up2/tc/task-detail и т.д.) переопределяют это ниже. */
  width: 100%; max-width: 540px; max-height: 88vh;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  display: flex; flex-direction: column; overflow: hidden;
}
/* 🔴🔴 CLIE-620: рама выше клипает (`overflow:hidden`) — модалка, у которой внутри НЕТ ни
   одного скроллящегося тела, обязана скроллить себя сама, иначе на невысоком окне за краем
   остаются её собственные кнопки и выйти из неё нечем. Класс ставит `ccModalSelfScroll()`
   в app.js ПО ЗАМЕРУ (правило от обратного — новая модалка получает это даром). */
.modal-box.cc-selfscroll { overflow-y: auto; overscroll-behavior: contain; }
/* 🔴🔴 CLIE-888·2: ОКНО ЗАДАЁТ СВОИ ЧЕРНИЛА, А НЕ НАСЛЕДУЕТ ИХ У КОНТЕКСТА.
   Рама берёт ФОН у темы (var(--panel)/var(--card)/var(--bg)) — значит и ЧЕРНИЛА обязана
   брать у темы. Пока `color` не задан, текст наследуется от предка, а предок бывает прибит
   тёмным: модалка «Пригласить в созвон» живёт ВНУТРИ #groupCallOverlay (`color:#fff`,
   оверлей звонка всегда тёмный) — и в СВЕТЛОЙ теме её заголовок и имена участников
   печатались БЕЛЫМ ПО БЕЛОМУ. Замер на живом проде: рама 1.00:1, «Пригласить в созвон»
   1.00:1, имя участника 1.00:1 (скрин владельца 05.09.2026 — аватары есть, имён нет).
   🔴 Правило КЛАССОВОЕ: перечислять «какие окна открываются внутри тёмного» ЗАПРЕЩЕНО —
   белый список поверхностей уже трижды рождал дыры. Чернила задаёт САМА рама, где бы её
   ни смонтировали. Сторож: tools/design_lint.js → THEMECONTRAST_MECH (клауза «рама окна»);
   замер: node tools/contrast_audit.js (проход «окна», обе темы). */
.modal-box, .v2-modal, .cc-pop, .tc-pop, .attach-menu, .docviewer-box { color: var(--text); }
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--line); font-weight: 600;
}
.modal-box .conv-list { overflow-y: auto; flex: 1; }
@media (max-width: 720px) {
  .modal-overlay { padding: 0; align-items: stretch; }
  .modal-box { max-width: none; max-height: none; height: 100dvh; border: none; border-radius: 0; }
}

/* ══════ ИИ-Помощник (со-пилот, DeepSeek) — полноценный чат ══════ */
/* Широкая двухколоночная модалка: слева столбик бесед, справа диалог. */
.ai-assist-box { max-width: 1160px; width: 96vw; flex-direction: row; padding: 0; overflow: hidden; position: relative; }
/* Оверлей при перетаскивании файла с компьютера на панель Помощника */
.ai-assist-box.ai-drag::after { content: "Отпустите файл — добавлю в Помощника 📎"; position: absolute; inset: 0; z-index: 30; display: flex; align-items: center; justify-content: center; text-align: center; padding: 24px; background: color-mix(in srgb, var(--primary) 16%, transparent); border: 2px dashed var(--primary); border-radius: inherit; color: var(--text); font-weight: 600; font-size: 15px; pointer-events: none; }
@media (min-width: 721px) { .ai-assist-box { height: 90vh; } }

/* ── левый столбик бесед ── */
/* 🔴 CLIE-1179: столбик шире на ширину рельсы (56px) — список бесед остался ровно таким,
   каким был до неё, а не «съехал» на треть ширины названия. */
.ai-assist-side { width: 308px; flex: none; display: flex; flex-direction: column; background: var(--panel-2); border-right: 1px solid var(--line); }
.ai-assist-side-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 14px; font-weight: 700; border-bottom: 1px solid var(--line); }
.ai-assist-brand { font-size: 15px; }
.ai-assist-new { width: 30px; height: 30px; flex: none; border: none; border-radius: 9px; background: var(--acc-fill); color: #fff; display: inline-flex; align-items: center; justify-content: center; line-height: 1; cursor: pointer; }
.ai-assist-new:hover { filter: brightness(1.08); }
.ai-assist-new .ic { width: 17px; height: 17px; }
.ai-assist-brand { display: inline-flex; align-items: center; gap: 7px; }
.ai-assist-brand-ic { display: inline-flex; color: var(--primary); }
.ai-assist-brand-ic .ic { width: 17px; height: 17px; }
/* ── фильтр Активные/Архив + поиск бесед ── */
/* Вкладка Активные/Архив стоит В НИЗУ столбика (вариант 4): наверху — рельса и список. */
/* Канон сегмента (.ai-assist-filter в блоке iOS-сегмента) сделал фильтр дорожкой со своей кромкой,
   а поля ей никто не дал: дорожка легла вплотную к низу окна и к кромке столбика (кадр
   k_assistant: дорожка y 803–844, низ окна 845). Поля — те же 10px, что у поиска бесед. */
/* aya-footer-misalign-1 · дорожка стоит в одном нижнем ряду окна с композером (поле и круглые кнопки 44 px,
   низ .ai-assist-foot — 12 px): было 42 px и низ 10 — кромки расходились на 4 и 2 px (кадр k_assistant:
   дорожка y 793–834, композер 789–832, обе темы). Высота — размерный класс ряда --ctl-h, низ — 12. */
.ai-assist-filter { display: flex; gap: 6px; padding: 8px 10px; border-top: 1px solid var(--line); margin: 8px 10px 12px; --ctl-h: 44px; height: var(--ctl-h); }
.ai-assist-filter > .ai-filter-tab { align-self: stretch; }
.ai-filter-tab { flex: 1; border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); border-radius: 8px; padding: 6px 8px; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.ai-filter-tab:hover { color: var(--text); }
.ai-filter-tab.active { background: color-mix(in srgb, var(--primary) 18%, transparent); border-color: var(--primary); color: var(--text); }
.ai-assist-search { display: flex; align-items: center; gap: 7px; margin: 8px 10px 2px; padding: 0 10px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px; }
.ai-assist-search:focus-within { border-color: var(--primary); }
.ai-assist-search-ic { display: inline-flex; flex: none; opacity: .6; }
.ai-assist-search-ic .ic { width: 15px; height: 15px; }
.ai-assist-search input { flex: 1; min-width: 0; border: none; background: none; color: var(--text); font-size: 13px; padding: 8px 0; outline: none; }
.ai-chat-arch { flex: none; opacity: 0; border: none; background: transparent; color: var(--muted); cursor: pointer; padding: 2px 4px; border-radius: 6px; display: inline-flex; }
.ai-chat-arch .ic { width: 14px; height: 14px; }
.ai-chat-item:hover .ai-chat-arch { opacity: .8; }
.ai-chat-arch:hover { opacity: 1 !important; color: var(--text); background: rgba(255,255,255,.08); }
.ai-chat-empty { padding: 22px 14px; text-align: center; color: var(--muted); font-size: 13px; line-height: 1.5; }
.ai-chat-del .ic { width: 14px; height: 14px; }
/* ── 🔴 CLIE-1179 · ВАРИАНТ 4: МИНИ-РЕЛЬСА РАЗДЕЛОВ БЕСЕД ──
   Узкая колонка значков слева от списка — тем же языком, что рельс продукта. Список
   становится уже на 56px и НИЧЕГО не теряет по высоте. Раздел беседы считает сервер
   (ai_conversations.category, миграция 0385), кнопки рисует renderAssistantRail().
   Обе темы даром: цвета берутся из токенов (--primary/--line/--text), а не прибиты. */
.ai-conv-split { display: flex; flex: 1; min-height: 0; }
.ai-conv-rail { width: 56px; flex: none; display: flex; flex-direction: column; align-items: center; gap: 2px;
                padding: 8px 0; border-right: 1px solid var(--line); overflow-y: auto; overflow-x: hidden; }
.ai-conv-col { flex: 1; min-width: 0; display: flex; flex-direction: column; }
/* Цель 44×44 — палец попадает по ВСЕЙ плашке, а не по коробке глифа (канон tap-target). */
.ai-conv-tab { width: 44px; height: 44px; flex: none; padding: 0; border: none; border-radius: 12px; background: transparent;
               color: var(--muted); cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center;
               gap: 1px; line-height: 1; transition: background .14s ease, color .14s ease, box-shadow .14s ease; }
.ai-conv-tab:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }
.ai-conv-tab:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.ai-conv-tab .ic { width: 17px; height: 17px; }
.ai-conv-tab-ic { display: inline-flex; }
.ai-conv-tab-n { font-size: 9.5px; font-weight: 700; opacity: .85; min-height: 11px; }
html[data-theme="light"] .ai-conv-tab-n { opacity: 1; } /* CLIE-1946: 4.33 → --muted целиком */
/* Выбранный раздел: заливка + кольцо акцентом — читается и в светлой, и в тёмной. */
.ai-conv-tab.active { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--text);
                      box-shadow: inset 0 0 0 1px var(--primary); }
/* Пустой раздел ВИДЕН (тут просто пусто), но не тянет на себя внимание. */
.ai-conv-tab.empty { opacity: .5; }
.ai-conv-tab.empty:hover, .ai-conv-tab.empty.active { opacity: 1; }
/* Выход из пустого состояния стоит рядом с причиной: «очистить поиск» / «показать все». */
.ai-chat-empty-acts { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 10px; }
.ai-chat-empty-act { border: 1px solid var(--line-strong); background: transparent; color: var(--text); cursor: pointer;
                     border-radius: 8px; padding: 5px 10px; font: inherit; font-size: 12px; font-weight: 600; }
.ai-chat-empty-act:hover { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.ai-assist-list { flex: 1; overflow-y: auto; list-style: none; margin: 0; padding: 6px; }
.ai-chat-item { display: flex; align-items: center; gap: 8px; padding: 9px 10px; border-radius: 9px; cursor: pointer; color: var(--muted); }
.ai-chat-item:hover { background: rgba(255,255,255,.05); color: var(--text); }
.ai-chat-item.active { background: color-mix(in srgb, var(--primary) 18%, transparent); color: var(--text); }
/* Значок строки = РАЗДЕЛ беседы и вход в «переложить» (кнопка, а не украшение). */
.ai-chat-ic { flex: none; display: inline-flex; align-items: center; justify-content: center; opacity: .7;
              width: 24px; height: 24px; padding: 0; border: none; border-radius: 7px; background: transparent;
              color: inherit; cursor: pointer; }
.ai-chat-ic:hover { opacity: 1; background: color-mix(in srgb, var(--text) 10%, transparent); }
.ai-chat-ic:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; opacity: 1; }
.ai-chat-ic .ic { width: 15px; height: 15px; }
.ai-chat-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; }
.ai-chat-del { flex: none; opacity: 0; border: none; background: transparent; color: var(--muted); cursor: pointer; font-size: 12px; padding: 2px 4px; border-radius: 6px; }
.ai-chat-item:hover .ai-chat-del { opacity: .8; }
.ai-chat-del:hover { opacity: 1 !important; color: var(--text); background: rgba(255,255,255,.08); }

/* ── правая часть: заголовок + диалог + ввод ── */
.ai-assist-main { flex: 1; min-width: 0; display: flex; flex-direction: column; position: relative; }
.ai-assist-head .ai-assist-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-assist-menu, .ai-assist-head > .ai-assist-menu { display: none; }
.ai-assist-body { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; }
.ai-thread { width: 100%; max-width: 760px; margin: 0 auto; display: flex; flex-direction: column; gap: 4px; }
.ai-msg { display: flex; flex-direction: column; max-width: 88%; }
.ai-msg.mine { align-self: flex-end; align-items: flex-end; }
.ai-msg.bot { align-self: flex-start; align-items: flex-start; }
.ai-bubble { padding: 10px 14px; border-radius: 15px; font-size: 14.5px; line-height: 1.45; white-space: pre-wrap; word-break: break-word; max-width: 100%; }
/* 📄 Ответ Аи с таблицей/кодом — такой же документ, как отчёт ИИ в чате: берёт ленту целиком. */
.ai-msg:has(.md-tablewrap), .ai-msg:has(.md-pre) { max-width: 100%; }
.ai-msg.mine .ai-bubble { background: var(--acc-fill); color: #fff; border-bottom-right-radius: 5px; }
.ai-msg.bot .ai-bubble { background: var(--panel-2); color: var(--text); border-bottom-left-radius: 5px; }
.ai-msg.bot.err .ai-bubble { background: #3a1f24; color: #ffb4b4; }
.ai-bubble strong { font-weight: 700; }
/* ⏳ «ИДЁТ ПРОЦЕСС» (CLIE-1500·Р2·3) — вместо немого «…»: пульс + СЛОВА + живые секунды
   + выход. Пузырь тот же (.ai-msg.bot .ai-bubble), поэтому обе темы достаются даром. */
.ai-wait { display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  color: var(--muted); font-size: 13px; line-height: 1.45; white-space: normal; }
.ai-wait-dots { display: inline-flex; gap: 3px; flex: 0 0 auto; }
/* Та же строка вне ленты переписки (мастер сборки сайта): без хрома пузыря, но с той же
   типографикой — человек читает «идёт процесс» одинаково во всех местах продукта. */
.ai-wait-bare { padding: 2px 0; }
.ai-wait-dots i { width: 5px; height: 5px; border-radius: 50%;
  background: var(--primary-2, var(--primary)); animation: ccAiWait 1.1s infinite ease-in-out; }
.ai-wait-dots i:nth-child(2) { animation-delay: .15s; }
.ai-wait-dots i:nth-child(3) { animation-delay: .3s; }
@keyframes ccAiWait { 0%, 80%, 100% { opacity: .25; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-2px); } }
@media (prefers-reduced-motion: reduce) { .ai-wait-dots i { animation-duration: 2.4s; } }
.ai-wait-t { min-width: 0; }
.ai-wait-x { flex: 0 0 auto; padding: 3px 9px; border-radius: 999px; cursor: pointer;
  font-size: 12px; font-weight: 560; color: var(--text);
  border: 1px solid var(--line); background: var(--panel); }
.ai-wait-x:hover { background: var(--hover); }
.ai-actions { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 2px; }
/* 🔴 Кнопка НЕ сжимается ниже своей подписи (канон СРЕД-33). `.ai-actions` — флекс, а
   флекс-элемент ужимался до min-content: значок уезжал на свою строку, и «⟳ Повторить»
   читалось как две строки (поймано снимком CLIE-655). inline-flex + nowrap — ровно то,
   что уже стояло у карточки действия (`.ai-act-card .ai-action`); теперь это база. */
.ai-action { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; flex: none; background: var(--acc-fill); color: #fff; border: none; border-radius: 8px; padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.ai-action:hover { filter: brightness(1.08); }
.ai-assist-foot { display: flex; flex-direction: column; gap: 8px; align-items: stretch; padding: 12px 16px; border-top: 1px solid var(--line); }
.ai-assist-inputrow { display: flex; gap: 8px; align-items: flex-end; }
.ai-assist-foot textarea { flex: 1; resize: none; background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 12px; padding: 11px 14px; font: inherit; font-size: 14.5px; line-height: 20px; min-height: 44px; max-height: 140px; overflow-y: auto; box-sizing: border-box; }
.ai-assist-foot textarea:focus { outline: none; border-color: var(--primary); }
/* 🔴 13.10.2026 (ревью кадров, телефон): окно Аи — «место» сквозного пузыря чатов (QC_PLACE_SEL), и пузырь
   (left 16 · bottom 16) лёг ровно на скрепку прибитого композера. Гасить его нельзя (окно Аи — страница, не
   временный диалог), поэтому на узком экране он стоит НАД подвалом (69 px + 13 воздуха). Скрепка и микрофон
   прижаты к низу ряда (align-items: flex-end), так что растущее поле пузырь не задевает; ленте — запас
   снизу на высоту пузыря, чтобы последний ответ можно было докрутить из-под него. */
@media (max-width: 720px) {
  :root.cc-ai-open #chatScreen > #qcFab { bottom: 82px; }
  :root.cc-qc-shown #aiAssistantModal .ai-assist-body { padding-bottom: 76px; }
  /* newproj-fab-over-modal-1 (класс «пузырь поверх окна», раунд Q): «Папки» — тоже «место» пузыря
     (QC_PLACE_SEL), гасить его нельзя, а прибитый подвал окна во весь экран клал «Готово» прямо под пузырь
     (кадр k_folders.chats: пузырь — left 16 · 52 px — лежал на левом крае кнопки). Кнопке — поле слева на пузырь:
     16 + 52 + 12 воздуха; бейдж «99+» пузыря тоже остаётся левее кнопки. */
  :root.cc-qc-shown #foldersModal .modal-foot { padding-left: 80px; }
}
.ai-assist-send { flex: none; width: 44px; height: 44px; padding: 0; border-radius: 50%; border: none; background: var(--acc-fill); color: #fff; font-size: 17px; line-height: 1; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.ai-assist-send:hover { filter: brightness(1.08); }
.ai-assist-attach { flex: none; width: 44px; height: 44px; padding: 0; border-radius: 50%; border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); font-size: 18px; cursor: pointer; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.ai-assist-attach:hover { border-color: var(--primary); color: var(--text); }
.ai-assist-attach:disabled { opacity: .5; cursor: default; }
/* Голосовой режим (hands-free): кнопка микрофона + оверлей */
.ai-assist-mic { flex: none; width: 44px; height: 44px; padding: 0; border-radius: 50%; border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); font-size: 18px; cursor: pointer; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }
.ai-assist-mic:hover { border-color: var(--primary); color: var(--text); }
.ai-assist-mic.on { background: var(--acc-fill); color: #fff; border-color: var(--acc-fill); }
/* размеры SVG-иконок Помощника (эмодзи → иконки) */
.ai-assist-attach .ic, .ai-assist-mic .ic { width: 19px; height: 19px; }
.ai-assist-send .ic { width: 18px; height: 18px; }
.ai-msg-file .ic { width: 13px; height: 13px; }
.ai-action .ic { width: 14px; height: 14px; vertical-align: -2px; }
.ai-assist-chip .ai-chip-ic .ic { width: 14px; height: 14px; }
.ai-assist-chip .rm .ic { width: 12px; height: 12px; }
/* ══════════════════════════════════════════════════════════════════════════
   ГОЛОСОВОЙ РЕЖИМ — премиальный speech-to-speech (OpenAI Realtime).
   Живой орб на canvas + аврора-фон + плавные субтитры + пикеры голоса/тарифа.
   ══════════════════════════════════════════════════════════════════════════ */
.ai-voice-overlay {
  position: absolute; inset: 0; z-index: 40; overflow: hidden;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; padding: 24px 22px calc(20px + env(safe-area-inset-bottom)); text-align: center;
  background:
    radial-gradient(120% 90% at 50% -10%, color-mix(in srgb, var(--primary) 14%, transparent) 0%, transparent 60%),
    linear-gradient(180deg, var(--panel) 0%, var(--bg) 100%);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  animation: aiVoiceIn .28s var(--ease, cubic-bezier(.2,.8,.2,1)) both;
}
.ai-voice-overlay.hidden { display: none; }
@keyframes aiVoiceIn { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: scale(1); } }

/* ── Аврора-фон: мягкие дрейфующие пятна, глубина без нагрузки ── */
.ai-voice-aurora { position: absolute; inset: -12%; pointer-events: none; z-index: 0; filter: blur(46px); opacity: .55; }
.ai-voice-aurora span { position: absolute; display: block; width: 46%; height: 46%; border-radius: 50%; mix-blend-mode: screen; will-change: transform; }
.ai-voice-aurora span:nth-child(1) { left: 6%;  top: 8%;  background: radial-gradient(circle, color-mix(in srgb, var(--primary) 85%, #38bdf8) 0%, transparent 70%); animation: aiAur1 19s ease-in-out infinite; }
.ai-voice-aurora span:nth-child(2) { right: 4%; top: 22%; background: radial-gradient(circle, color-mix(in srgb, var(--primary-2) 80%, var(--cm-a855f7, #a855f7)) 0%, transparent 70%); animation: aiAur2 23s ease-in-out infinite; }
.ai-voice-aurora span:nth-child(3) { left: 30%; bottom: 4%; background: radial-gradient(circle, color-mix(in srgb, var(--primary) 60%, #22d3ee) 0%, transparent 72%); animation: aiAur3 27s ease-in-out infinite; }
@keyframes aiAur1 { 0%,100% { transform: translate(0,0) scale(1); } 50% { transform: translate(14%, 10%) scale(1.15); } }
@keyframes aiAur2 { 0%,100% { transform: translate(0,0) scale(1.05); } 50% { transform: translate(-12%, 8%) scale(.9); } }
@keyframes aiAur3 { 0%,100% { transform: translate(0,0) scale(.95); } 50% { transform: translate(8%, -12%) scale(1.1); } }
html[data-theme="light"] .ai-voice-aurora { opacity: .4; }

/* ── Верхняя строка: чип модели + закрыть ── */
.ai-voice-top { position: absolute; top: 12px; left: 14px; right: 14px; z-index: 3; display: flex; align-items: center; justify-content: space-between; }
.ai-voice-chip { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 600; letter-spacing: .01em; color: var(--muted); background: color-mix(in srgb, var(--panel-2) 78%, transparent); border: 1px solid var(--line); padding: 4px 11px; border-radius: 999px; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.ai-voice-chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); transition: background .25s, box-shadow .25s; }
.ai-voice-overlay.is-live .ai-voice-chip .dot { background: var(--ok, #22c55e); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok, #22c55e) 26%, transparent); }
.ai-voice-x { width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--line); background: color-mix(in srgb, var(--panel-2) 80%, transparent); color: var(--muted); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: color var(--dur-1,.12s), border-color var(--dur-1,.12s), transform var(--dur-1,.12s); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.ai-voice-x .ic { width: 17px; height: 17px; }
.ai-voice-x:hover { color: var(--text); border-color: var(--primary); }
.ai-voice-x:active { transform: scale(.94); }

/* ── Орб (canvas) ── */
.ai-voice-orb { position: relative; z-index: 2; width: 216px; height: 216px; display: flex; align-items: center; justify-content: center; }
.ai-voice-canvas { width: 100%; height: 100%; display: block; }
.ai-voice-ico { display: none; }         /* иконка не нужна — рисует canvas; классик-фолбэк тоже на canvas */

.ai-voice-status { position: relative; z-index: 2; font-size: 21px; font-weight: 650; letter-spacing: -.01em; color: var(--text); min-height: 26px; transition: color var(--dur-2,.2s); }
.ai-voice-captions { position: relative; z-index: 2; display: flex; flex-direction: column; gap: 6px; width: 100%; max-width: 520px; min-height: 58px; justify-content: flex-start; }
.ai-voice-said { font-size: 14px; line-height: 1.4; color: var(--muted); font-weight: 500; opacity: .9; }
.ai-voice-said:not(:empty) { animation: aiCapIn .22s var(--ease, cubic-bezier(.2,.8,.2,1)) both; }
.ai-voice-reply { font-size: 18px; line-height: 1.5; color: var(--text); font-weight: 500; max-width: 520px; }
@keyframes aiCapIn { from { opacity: 0; transform: translateY(4px); } to { opacity: .9; transform: none; } }

/* ── Живой транскрипт разговора (mode-rt): ВЕСЬ диалог виден и прокручивается, ничего «не
   улетает»; под ходом с созданной задачей — кнопка «Открыть задачу» (реюз .ai-msg/.ai-action
   из панели). В классик-фолбэке (mode-classic) остаются построчные субтитры. ── */
.ai-voice-overlay.mode-classic .ai-voice-log { display: none; }
.ai-voice-overlay.mode-rt .ai-voice-captions { display: none; }
/* В rt: колонка сверху вниз, орб фикс, транскрипт растягивается и прокручивается внутри —
   контролы всегда прижаты к низу (не улетают за экран на невысоких модалках). */
.ai-voice-overlay.mode-rt { justify-content: flex-start; }
.ai-voice-overlay.mode-rt .ai-voice-orb { flex: none; }
.ai-voice-log {
  position: relative; z-index: 2; width: 100%; max-width: 560px;
  flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; text-align: left;
  display: flex; flex-direction: column; gap: 8px; padding: 6px 4px 2px; scrollbar-width: thin;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 12px, #000 100%);
          mask-image: linear-gradient(180deg, transparent 0, #000 12px, #000 100%);
}
.ai-voice-log::-webkit-scrollbar { width: 6px; }
.ai-voice-log::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 38%, transparent); border-radius: 3px; }
.ai-voice-log::-webkit-scrollbar-track { background: transparent; }
.ai-voice-thread, .ai-voice-live { display: flex; flex-direction: column; gap: 8px; }
.ai-voice-log-empty { color: var(--muted); font-size: 13px; text-align: center; padding: 20px 8px; opacity: .75; }
.ai-voice-live .ai-msg.ai-live .ai-bubble { animation: aiCapIn .18s var(--ease, cubic-bezier(.2,.8,.2,1)) both; }

/* ── Тост действия (создаю задачу…) ── */
.ai-voice-act { position: relative; z-index: 2; display: inline-flex; align-items: center; gap: 9px; max-width: 460px; padding: 9px 14px; border-radius: 12px; background: color-mix(in srgb, var(--primary) 14%, var(--panel-2)); border: 1px solid color-mix(in srgb, var(--primary) 40%, var(--line)); color: var(--text); font-size: 13.5px; font-weight: 500; box-shadow: var(--shadow-1, 0 6px 18px rgba(0,0,0,.2)); animation: aiActIn .24s var(--ease-spring, cubic-bezier(.34,1.4,.64,1)) both; }
.ai-voice-act.hidden { display: none; }
.ai-voice-act.ok { background: color-mix(in srgb, var(--ok, #22c55e) 15%, var(--panel-2)); border-color: color-mix(in srgb, var(--ok, #22c55e) 42%, var(--line)); }
.ai-voice-act.err { background: color-mix(in srgb, var(--danger, #ef4444) 14%, var(--panel-2)); border-color: color-mix(in srgb, var(--danger, #ef4444) 42%, var(--line)); }
/* «нужно уточнить» — инструмент НЕ выполнен, но это и не ошибка: янтарный, не зелёный и не красный */
.ai-voice-act.warn { background: color-mix(in srgb, var(--warning, #e5a23c) 15%, var(--panel-2)); border-color: color-mix(in srgb, var(--warning, #e5a23c) 44%, var(--line)); }
.ai-voice-act .ic { width: 16px; height: 16px; flex: none; }
.ai-voice-act .spin { width: 15px; height: 15px; border-radius: 50%; border: 2px solid color-mix(in srgb, var(--primary) 40%, transparent); border-top-color: var(--primary); animation: aiVoiceSpin .7s linear infinite; flex: none; }
@keyframes aiActIn { from { opacity: 0; transform: translateY(8px) scale(.96); } to { opacity: 1; transform: none; } }

/* ══ КАРТОЧКА ДЕЙСТВИЯ В ЛЕНТЕ РАЗГОВОРА (голос + текст) ══════════════════════════════════════
   Ход ассистента как ОБЪЕКТ, а не исчезающая плашка: «Создаю задачу…» → «✅ Задача …» +
   «Открыть», либо янтарное «какой именно?» с КНОПКАМИ-кандидатами (тап = выбор). Остаётся
   в истории беседы. Светлая и тёмная темы — на общих токенах. */
.ai-act-card { align-self: stretch; display: flex; flex-direction: column; gap: 8px; padding: 11px 13px; border-radius: 14px; border: 1px solid color-mix(in srgb, var(--primary) 26%, var(--line)); background: color-mix(in srgb, var(--primary) 8%, var(--panel-2)); box-shadow: 0 1px 2px rgba(0,0,0,.04); text-align: left; animation: aiActIn .22s var(--ease-spring, cubic-bezier(.34,1.4,.64,1)) both; }
.ai-act-card.ok   { border-color: color-mix(in srgb, var(--ok, #22c55e) 34%, var(--line)); background: color-mix(in srgb, var(--ok, #22c55e) 9%, var(--panel-2)); }
.ai-act-card.warn { border-color: color-mix(in srgb, var(--warning, #e5a23c) 36%, var(--line)); background: color-mix(in srgb, var(--warning, #e5a23c) 9%, var(--panel-2)); }
.ai-act-card.err  { border-color: color-mix(in srgb, var(--danger, #ef4444) 34%, var(--line)); background: color-mix(in srgb, var(--danger, #ef4444) 8%, var(--panel-2)); }
.ai-act-head { display: flex; align-items: flex-start; gap: 9px; }
.ai-act-title { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--text); }
.ai-act-sub { font-size: 12.5px; line-height: 1.4; color: var(--muted); padding-left: 25px; }
.ai-act-card .icw { display: inline-flex; flex: none; margin-top: 1px; }
.ai-act-card .ic { width: 16px; height: 16px; }
.ai-act-card.ok .icw { color: var(--ok, #22c55e); }
.ai-act-card.warn .icw { color: var(--warning, #e5a23c); }
.ai-act-card.err .icw { color: var(--danger, #ef4444); }
.ai-act-card .spin { width: 15px; height: 15px; flex: none; margin-top: 1px; border-radius: 50%; border: 2px solid color-mix(in srgb, var(--primary) 34%, transparent); border-top-color: var(--primary); animation: aiVoiceSpin .7s linear infinite; }
.ai-act-picks { display: flex; flex-wrap: wrap; gap: 8px; padding-left: 25px; }
.ai-pick { appearance: none; display: inline-flex; flex-direction: column; align-items: flex-start; gap: 1px; min-height: 32px; padding: 6px 13px; border-radius: 14px; border: 1px solid var(--line); background: var(--panel); color: var(--text); font: inherit; font-size: 13px; font-weight: 600; line-height: 1.25; text-align: left; cursor: pointer; transition: background .14s var(--ease, cubic-bezier(.2,.8,.2,1)), border-color .14s, transform .14s; }
.ai-pick:not(:has(.ai-pick-h)) { border-radius: 999px; }
/* Различающая подпись под названием (компания проекта / роль человека): два ОДНОИМЁННЫХ
   варианта без неё — выбор вслепую. */
.ai-pick-h { font-size: 11.5px; font-weight: 500; color: var(--muted); }
.ai-pick.on .ai-pick-h { color: color-mix(in srgb, #fff 82%, transparent); }
.ai-pick:hover { background: color-mix(in srgb, var(--primary) 10%, var(--panel)); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.ai-pick:active { transform: scale(.97); }
.ai-pick:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 60%, transparent); outline-offset: 2px; }
.ai-pick.on { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; }
.ai-pick[disabled] { opacity: .55; cursor: default; }
.ai-act-card .ai-actions { padding-left: 25px; margin-top: 0; }
/* Кнопка «Открыть задачу» внутри карточки: иконка и подпись В ОДНУ строку (в общем .ai-action
   svg — инлайн, и в узкой колонке подпись уезжала под иконку). */
.ai-act-card .ai-action { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; padding: 7px 13px; border-radius: 10px; }

.ai-voice-hint { position: relative; z-index: 2; font-size: 12.5px; color: var(--muted); max-width: 460px; line-height: 1.5; }

/* ── Контролы: пикер голоса + тариф + мьют + завершить ── */
.ai-voice-controls { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 12px; width: 100%; max-width: 520px; margin-top: 2px; }
.ai-voice-voices { display: flex; gap: 7px; overflow-x: auto; max-width: 100%; padding: 3px 2px; scrollbar-width: none; -webkit-mask-image: linear-gradient(90deg, transparent, #000 18px, #000 calc(100% - 18px), transparent); mask-image: linear-gradient(90deg, transparent, #000 18px, #000 calc(100% - 18px), transparent); }
.ai-voice-voices::-webkit-scrollbar { display: none; }
.ai-voice-voice { flex: none; padding: 7px 14px; border-radius: 999px; border: 1px solid var(--line); background: color-mix(in srgb, var(--panel-2) 70%, transparent); color: var(--text-dim, var(--muted)); font-size: 13px; font-weight: 550; cursor: pointer; white-space: nowrap; transition: color var(--dur-1,.12s), border-color var(--dur-1,.12s), background var(--dur-1,.12s), transform var(--dur-1,.12s); }
.ai-voice-voice:hover { color: var(--text); border-color: var(--line-strong, var(--line)); }
.ai-voice-voice.on { color: #fff; background: var(--acc-grad, linear-gradient(135deg, var(--primary), var(--primary-2))); border-color: transparent; box-shadow: 0 4px 14px color-mix(in srgb, var(--primary) 40%, transparent); animation: aiChipPop .18s var(--ease-spring, cubic-bezier(.34,1.4,.64,1)); }
@keyframes aiChipPop { 0% { transform: scale(.92); } 100% { transform: scale(1); } }
.ai-voice-cluster { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: center; }
.ai-voice-seg { display: inline-flex; padding: 3px; border-radius: 11px; background: color-mix(in srgb, var(--panel-3, var(--panel-2)) 80%, transparent); border: 1px solid var(--line); }
.ai-voice-seg button { border: 0; background: transparent; color: var(--muted); padding: 7px 14px; border-radius: 8px; font-size: 13px; font-weight: 600; cursor: pointer; transition: color var(--dur-1,.12s), background var(--dur-1,.12s), box-shadow var(--dur-1,.12s); }
.ai-voice-seg button.on { color: var(--text); background: var(--panel); box-shadow: 0 1px 3px rgba(0,0,0,.2), 0 0 0 1px color-mix(in srgb, var(--primary) 34%, transparent); }
.ai-voice-round { width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line); background: color-mix(in srgb, var(--panel-2) 78%, transparent); color: var(--text); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: transform var(--dur-1,.12s), border-color var(--dur-1,.12s), color var(--dur-1,.12s), background var(--dur-1,.12s); }
.ai-voice-round .ic { width: 19px; height: 19px; }
.ai-voice-round:hover { border-color: var(--line-strong, var(--line)); }
.ai-voice-round:active { transform: scale(.93); }
.ai-voice-round.muted { color: var(--danger, #ef4444); border-color: color-mix(in srgb, var(--danger, #ef4444) 50%, var(--line)); background: color-mix(in srgb, var(--danger, #ef4444) 12%, transparent); }
.ai-voice-end { display: inline-flex; align-items: center; gap: 8px; padding: 11px 20px; border-radius: 999px; border: none; background: var(--danger, #ef4444); color: #fff; font-size: 14px; font-weight: 650; cursor: pointer; box-shadow: 0 6px 18px color-mix(in srgb, var(--danger, #ef4444) 38%, transparent); transition: transform var(--dur-1,.12s), filter var(--dur-1,.12s); }
.ai-voice-end:hover { filter: brightness(1.06); }
.ai-voice-end:active { transform: scale(.97); }
.ai-voice-end-ic { width: 11px; height: 11px; border-radius: 3px; background: currentColor; display: inline-block; }

/* Статус-пилюля = кнопка входа в настройки голоса/режима (тукнуто; паритет с Flutter). */
.ai-voice-chip-btn { cursor: pointer; }
.ai-voice-chip-btn:hover { border-color: var(--primary); color: var(--text); }
.ai-voice-chip-chev { width: 0; height: 0; margin-left: 1px; border-left: 4px solid transparent; border-right: 4px solid transparent; border-top: 5px solid currentColor; opacity: .65; }

/* Тукнутая слайд-панель голоса/режима поверх оверлея (низ остаётся чистым). */
.ai-voice-sheet-scrim { position: absolute; inset: 0; z-index: 6; background: rgba(0,0,0,.44); opacity: 0; pointer-events: none; transition: opacity var(--dur-2,.16s); }
.ai-voice-sheet { position: absolute; left: 0; right: 0; bottom: 0; z-index: 7; display: flex; flex-direction: column; gap: 10px; padding: 10px 20px calc(18px + env(safe-area-inset-bottom)); background: var(--panel); border-top: 1px solid var(--line); border-radius: 22px 22px 0 0; transform: translateY(100%); transition: transform var(--dur-2,.16s) cubic-bezier(.22,.61,.36,1); box-shadow: 0 -12px 40px rgba(0,0,0,.32); }
.ai-voice-overlay.sheet-open .ai-voice-sheet-scrim { opacity: 1; pointer-events: auto; }
.ai-voice-overlay.sheet-open .ai-voice-sheet { transform: translateY(0); }
.ai-voice-sheet-grip { width: 38px; height: 4px; border-radius: 999px; background: var(--line); align-self: center; margin-bottom: 2px; }
.ai-voice-sheet-label { font-size: 13px; font-weight: 600; color: var(--muted); }
.ai-voice-sheet .ai-voice-voices { flex-wrap: wrap; overflow: visible; -webkit-mask-image: none; mask-image: none; }
.ai-voice-sheet .ai-voice-seg { align-self: flex-start; }
.ai-voice-sheet-done { margin-top: 6px; padding: 12px; border: 0; border-radius: 14px; background: var(--acc-fill); color: #fff; font-size: 15px; font-weight: 650; cursor: pointer; transition: filter var(--dur-1,.12s), transform var(--dur-1,.12s); }
.ai-voice-sheet-done:hover { filter: brightness(1.06); }
.ai-voice-sheet-done:active { transform: scale(.98); }

/* Классик-фолбэк (STT→TTS): нет выбора голоса/тарифа/мьюта — прячем их. */
.ai-voice-overlay.mode-classic .ai-voice-voices,
.ai-voice-overlay.mode-classic .ai-voice-seg,
.ai-voice-overlay.mode-classic #aiVoiceMuteBtn,
.ai-voice-overlay.mode-classic #aiVoiceModelChip { display: none; }

@media (max-width: 720px) {
  .ai-voice-orb { width: 176px; height: 176px; }
  .ai-voice-status { font-size: 19px; }
  .ai-voice-reply { font-size: 16px; }
}
@media (prefers-reduced-motion: reduce) {
  .ai-voice-overlay, .ai-voice-aurora span, .ai-voice-act, .ai-voice-voice.on, .ai-voice-said:not(:empty) { animation: none !important; }
}
/* Чипы прикреплённых файлов над полем ввода */
.ai-assist-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ai-assist-chips.hidden { display: none; }
.ai-assist-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 260px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 5px 10px; font-size: 12.5px; color: var(--text); }
.ai-assist-chip .name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-assist-chip .rm { flex: none; cursor: pointer; color: var(--muted); font-size: 14px; line-height: 1; border: none; background: none; padding: 0; }
.ai-assist-chip .rm:hover { color: var(--danger, #e5484d); }
.ai-assist-chip.uploading { opacity: .7; }
.ai-assist-chip.failed { border-color: var(--danger, #e5484d); color: var(--danger, #e5484d); }
/* Значок файла внутри пузыря сообщения пользователя */
/* 📎 CRMC-1135: вложения реплики живут СВОЕЙ строкой под текстом — inline-flex пускал чип по
   строке текста, и имя файла наезжало на хвост фразы (жалоба владельца 25.09.2026). */
.ai-msg-files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; width: 100%; }
.ai-msg-file { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 4px 9px; border-radius: 8px; background: rgba(255,255,255,.14); font-size: 12.5px; }
.ai-msg-file > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 🖼🔴 КАРТОЧКА РАЗБИРАЕМОГО СООБЩЕНИЯ (CLIE-1249) — первое, что видно в беседе «Разбор
   сообщения»: автор · где · когда · превью. Стоит ПЕРВОЙ в треде и остаётся на месте, когда
   разговор пошёл. Красим ролями темы (--panel-2/--line/--muted/--primary), чтобы карточка
   читалась в обеих темах; акцент — тонкой подложкой и рамкой, без левой рейки (канон accent). */
.ai-src { display: block; width: 100%; box-sizing: border-box; margin: 0 0 10px; padding: 10px 12px; border-radius: 12px;
  background: color-mix(in srgb, var(--primary) 7%, var(--panel-2)); border: 1px solid color-mix(in srgb, var(--primary) 22%, var(--line));
  color: var(--text); text-align: left; }
.ai-src.hit { cursor: pointer; transition: background .13s, border-color .13s; }
.ai-src.hit:hover { background: color-mix(in srgb, var(--primary) 12%, var(--panel-2)); border-color: color-mix(in srgb, var(--primary) 42%, var(--line)); }
.ai-src.hit:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.ai-src-h { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--muted); }
.ai-src-h .ic { width: 15px; height: 15px; flex: none; color: var(--primary); }
.ai-src-who { font-weight: 650; color: var(--text); }
.ai-src-conv, .ai-src-when { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.ai-src-conv::before, .ai-src-when::before { content: "·"; margin-right: 6px; opacity: .6; }
.ai-src-go { margin-left: auto; display: inline-flex; color: var(--primary); }
.ai-src-go .ic { width: 14px; height: 14px; }
/* Текст сообщения — до четырёх строк: карточка показывает, ЧТО разбираем, а не пересказывает
   весь диалог. Переносы человека сохраняем (pre-wrap), длинное слово рвём, чтобы не тянуло ленту. */
.ai-src-t { margin-top: 5px; font-size: 13.5px; line-height: 1.45; color: var(--text); white-space: pre-wrap;
  overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
/* Подсказка «напишите, что сделать» — ПОДСКАЗКА, а не подставленный вопрос (CLIE-1249). */
.ai-src-ask { display: flex; align-items: flex-start; gap: 8px; padding: 2px 2px 0; font-size: 13px; line-height: 1.45; color: var(--muted); }
.ai-src-ask .ic { width: 15px; height: 15px; flex: none; margin-top: 2px; color: var(--primary); }
/* 🔴 МЕРА СТРОКИ И МЕРА БЛОКА — РАЗНЫЕ ВЕЛИЧИНЫ. Текст читается при 55–70 знаках в строке
   (тут это ~420px), а строкам разделов нужна ширина, иначе они складываются в рваный столбик
   и уезжают под композер. Поэтому контейнер шире (620), а абзацы держат свою меру сами. */
.ai-welcome { margin: auto; text-align: center; max-width: 620px; padding: 24px 8px; color: var(--muted); }
.ai-welcome-ic { width: 60px; height: 60px; margin: 0 auto 16px; border-radius: 50%; background: color-mix(in srgb, var(--primary) 16%, transparent); display: flex; align-items: center; justify-content: center; color: var(--primary); }
.ai-welcome-ic .ic { width: 30px; height: 30px; }
.ai-welcome-title { font-size: 22px; font-weight: 700; color: var(--text); margin-bottom: 8px; }
.ai-welcome-sub { font-size: 14px; line-height: 1.5; margin: 0 auto; max-width: 420px; }
/* Расстояние ниже принадлежит тому, что идёт СЛЕДОМ (шкала 24 / 20), а не абзацу: иначе два
   margin'а складываются и между текстом и кнопками зияет 44px. */
.ai-welcome .ai-suggest { margin-top: 20px; }
.ai-suggest { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.ai-sugg { background: var(--panel-2); color: var(--text); border: 1px solid var(--line); border-radius: 8px; padding: 8px 13px; font-size: 13px; cursor: pointer; }
.ai-sugg:hover { border-color: var(--primary); color: var(--primary-2); background: var(--sel); }
/* Готовая просьба «во весь рост»: сводка по всему продукту — первое, за чем сюда приходят. */
/* Сводка по всему продукту — главный чипс ОБЩЕГО блока, а не отдельный элемент экрана
   (владелец: «это всё один общий блок… просто „что важного сегодня“ самый главный»). Он стоит
   своей строкой внутри блока, расстояние до соседних чипсов — общие 8px (.ai-qb-b gap). */
.ai-sugg-hero { display: inline-flex; align-items: center; gap: 7px; background: color-mix(in srgb, var(--primary) 12%, var(--panel-2)); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); color: var(--primary-2); font-weight: 600; }
.ai-sugg-hero .ic { width: 15px; height: 15px; }
/* 🔷 Быстрые действия по разделам (CRMC-1136) — РАЗДЕЛ = ОДНА СТРОКА.
   Владелец 16.09.2026, глядя на первый вариант: «отступы и всё не красиво… в чём проблема
   нормально пространство использовать?». Он прав, и вот что было не так:
     • всё центрировано → ни одной общей оси, каждая строка начиналась в своём месте;
     • отступы взяты на глаз (7/12/14/16 px) вместо одной шкалы;
     • 22 элемента на пустом экране в узкой центральной колонке при ширине панели ~900 px →
       низ списка уезжал под композер, а ширина простаивала.
   Решение: подпись раздела СЛЕВА фиксированной колонкой, чипсы — вправо от неё. Две оси
   (край подписей и край чипсов), шкала отступов 8 / 16 / 24, бюджет — три чипса на раздел.
   В УЗКОМ месте (док почты/CRM ~440 px) строка складывается: подпись над чипсами — та же
   разметка, без второго компонента. */
/* 🔷 БЫСТРЫЕ ДЕЙСТВИЯ: подпись раздела по центру, под ней чипсы одним потоком со СВОИМИ
   ширинами и ЕСТЕСТВЕННЫМ переносом. Ряды выходят разной длины — так и задумано.
   🔴 ИСТОРИЯ, ЧТОБЫ НЕ ПОВТОРИТЬ. Владелец сказал «некрасиво», и я дважды прочитал это как
   «неровно»: сначала выровнял чипсы по колонкам одинаковой ширины, потом порезал ряды на
   ровные пары. Оба раза он отвечал «нет» — ему нравился именно живой поток. Настоящая
   причина была ДРУГАЯ и названа им прямо: «небольшие отступы между блоками, из-за чего всё
   плохо считывается». То есть лечится РАССТОЯНИЕМ, а не выравниванием.
   Шкала теперь разговаривает: 8 внутри раздела (между чипсами и от подписи к ним) и 28
   между разделами — в три с половиной раза больше, поэтому группы читаются как группы.
   Высоту не экономим: блок прокручивается вместе с лентой (решение владельца). */
.ai-qb { display: flex; flex-direction: column; gap: 28px; width: 100%; margin: 26px 0 8px; }
.ai-qb-b { display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: 0; }
.ai-qb-h { display: inline-flex; align-items: center; justify-content: center; gap: 6px; font-size: 11px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; color: var(--muted); }
.ai-qb-h .ic { width: 13px; height: 13px; flex: none; }
.ai-qb-row { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.ai-qb-a { white-space: nowrap; }
/* В узкой раме (док ~412px) воздуха нужно чуть меньше — там и строк больше. */
.cc-aya-body .ai-qb { gap: 22px; margin: 18px 0 4px; }

/* ── мобильный: столбик бесед выезжает поверх по кнопке ☰ ── */
@media (max-width: 720px) {
  .ai-assist-side { position: absolute; left: 0; top: 0; bottom: 0; z-index: 6; transform: translateX(-100%); transition: transform .2s ease; box-shadow: 2px 0 18px rgba(0,0,0,.45); }
  .ai-assist-box.show-side .ai-assist-side { transform: translateX(0); }
  .ai-assist-menu, .ai-assist-head > .ai-assist-menu { display: inline-flex; }
  /* aya-sheet-1 (раунд Q) · окно Аи на телефоне — во весь экран, как любая .modal-box ≤720: 96vw оставлял
     полосы затемнения по 8 px (кадр k_assistant.aya: окно x 8–381). Тень спрятанного столбика бесед
     (2px 0 18px) ложилась полосой на левую кромку (x 9–22) — у закрытого столбика её нет. */
  .ai-assist-box { width: 100%; }
  .ai-assist-box:not(.show-side) .ai-assist-side { box-shadow: none; }
}

/* подсветка пункта интерфейса по подсказке ассистента */
.cc-guide-pulse { animation: ccGuidePulse 1.3s ease-in-out 2; border-radius: 10px; }
@keyframes ccGuidePulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 0%, transparent); }
  50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 60%, transparent); background: color-mix(in srgb, var(--primary) 14%, transparent); }
}
/* ЯРКАЯ подсветка конкретной кнопки: кольцо + метка «👉 Нажмите здесь» */
.cc-spot { position: fixed; z-index: 9999; pointer-events: none; }
.cc-spot-ring {
  border: 3px solid var(--primary); border-radius: 11px;
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 35%, transparent), 0 0 22px 7px color-mix(in srgb, var(--primary) 55%, transparent);
  animation: ccSpotPulse 1s ease-in-out infinite;
}
.cc-spot-label {
  background: var(--acc-fill); color: #fff; font-size: 13px; font-weight: 700;
  padding: 6px 12px; border-radius: 999px; white-space: nowrap;
  box-shadow: 0 6px 18px rgba(0,0,0,.4);
}
@keyframes ccSpotPulse {
  0%, 100% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 30%, transparent), 0 0 18px 5px color-mix(in srgb, var(--primary) 45%, transparent); }
  50%      { box-shadow: 0 0 0 7px color-mix(in srgb, var(--primary) 16%, transparent), 0 0 30px 11px color-mix(in srgb, var(--primary) 70%, transparent); }
}

/* ---- вложения (фото/видео/файл) ---- */
.attach-btn { padding: 9px 12px; font-size: 18px; flex: none; }
/* Task 11: у медиа-пузыря отступы почти в ноль — медиа во всю ширину пузыря */
.bubble.has-media { padding: 0; background: transparent !important; box-shadow: none !important; border-radius: 0 !important; border: none !important; overflow: hidden; }
/* кружок + кольцо прогресса выходят за края круга — баббл их НЕ клипает (иначе кольцо обрезается) */
.bubble.has-media:has(.upl-circle), .bubble.has-media:has(.circle-wrap) { overflow: visible; }
/* Одиночное фото/видео крупнее (владелец: «когда фотка или видео одно — ещё чуть больше»).
   Фото и видео = ОДИН размер 384×432 (было 240×300 / 336×384): единичное медиа консистентно,
   и превью загрузки совпадает с итоговым (.upl-thumb тоже 384×432 ниже). Альбом НЕ трогаем. */
.att-image { max-width: 384px; max-height: 432px; border-radius: 10px; display: block; cursor: pointer; }
.att-video { max-width: 384px; max-height: 432px; border-radius: 10px; display: block; background: #000; }
/* ── Инлайн-видео в чате — плашка как в Telegram (CLIE-465) ────────────────────
   ЦЕНТР = ▶ смотреть (стрим сразу); УГОЛ СЛЕВА = [↓ загрузить В ПРИЛОЖЕНИЕ] +
   «0:47 · 12,4 МБ · MP4»; УГОЛ СПРАВА = «Сохранить на компьютер» (лоток, на hover).
   Стекло поверх кадра одинаково читается в обеих темах — токенов темы тут не надо
   (подложка = сам кадр видео, всегда тёмный оверлей). Раскладка = как в приложении
   (client/lib/widgets/video_msg_bubble.dart), логика — ccVid в app.js. */
.att-vid {
  position: relative; display: block; width: -moz-fit-content; width: fit-content;
  max-width: 100%; line-height: 0;
  border-radius: 10px; overflow: hidden; /* угловая строка не вылезает за кадр на узком ролике */
}
.att-vid-dl {
  position: absolute; top: 8px; right: 8px; width: 34px; height: 34px; border-radius: 50%;
  border: none; cursor: pointer; color: #fff; background: rgba(0,0,0,.5);
  display: flex; align-items: center; justify-content: center; z-index: 4; opacity: 0;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: opacity var(--motion-fast,.14s) var(--ease-standard,ease), background var(--motion-fast,.14s) ease;
}
/* 🔴 В состоянии постера кнопка видна СРАЗУ (не только на hover): «скачать на компьютер»
   и «загрузить в приложение» — два РАЗНЫХ действия, человек должен видеть оба и не
   искать. Во время просмотра гаснет, чтобы не лезть на кадр (возвращается на hover). */
.att-vid:not(.is-playing) .att-vid-dl { opacity: .9; }
.att-vid:hover .att-vid-dl { opacity: 1; }
.att-vid-dl:hover { background: rgba(0,0,0,.72); }
.att-vid-dl:active { transform: scale(.92); }
.att-vid-dl svg.ic { width: 18px; height: 18px; display: block; }
@media (hover: none) { .att-vid-dl { opacity: 1; } }

/* Слой поверх постера: гаснет, как только человек начал смотреть (не мешаем кадру). */
.att-vid-ov { position: absolute; inset: 0; z-index: 2; line-height: 1; }
.att-vid.is-playing .att-vid-ov { pointer-events: none; }
/* прозрачный слой «тап по постеру = смотреть» — под пилюлей, над кадром */
.att-vid-hit {
  position: absolute; inset: 0; z-index: 1; border: 0; padding: 0; margin: 0;
  background: transparent; cursor: pointer; border-radius: 10px;
  /* лёгкое затемнение сверху/снизу — вес и ▶ читаются на любом кадре */
  background-image: linear-gradient(to bottom, rgba(0,0,0,.34) 0%, rgba(0,0,0,0) 32%, rgba(0,0,0,0) 72%, rgba(0,0,0,.22) 100%);
  transition: opacity var(--motion-fast,.14s) var(--ease-standard,ease);
}
.att-vid.is-playing .att-vid-hit { opacity: 0; pointer-events: none; }
/* ▶ по центру: стекло + тонкая рамка (эталон — плашка видео в приложении) */
.att-vid-play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); z-index: 2;
  width: 56px; height: 56px; border-radius: 50%; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  color: #fff; background: rgba(0,0,0,.42); border: 1.5px solid rgba(255,255,255,.9);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  box-shadow: 0 6px 18px rgba(0,0,0,.28);
  transition: opacity var(--motion-fast,.14s) var(--ease-standard,ease), transform var(--motion-fast,.14s) var(--ease-standard,ease);
}
.att-vid-play svg.ic { width: 30px; height: 30px; display: block; margin-left: 3px; }
.att-vid-hit:hover ~ .att-vid-play { transform: translate(-50%,-50%) scale(1.06); }
.att-vid-hit:active ~ .att-vid-play { transform: translate(-50%,-50%) scale(.94); }
.att-vid.is-playing .att-vid-play { opacity: 0; }
/* угол слева: [↓] + «длительность · вес · формат» */
.att-vid-lead {
  position: absolute; top: 8px; left: 8px; z-index: 3;
  display: flex; align-items: center; gap: 7px; pointer-events: none;
  /* правее — кнопка «на компьютер» (34+8): на вертикальном ролике строка «0:47 · 12,4 МБ
     · MP4» иначе налезала на неё; лишнее подрезаем, а не ломаем раскладку */
  max-width: calc(100% - 58px);
  transition: opacity var(--motion-fast,.14s) var(--ease-standard,ease);
}
.att-vid.is-playing .att-vid-lead { opacity: 0; }
/* загрузка идёт — угол остаётся виден и кликабелен даже во время просмотра */
.att-vid.is-playing[data-vphase="downloading"] .att-vid-lead { opacity: 1; pointer-events: auto; }
.att-vid-meta {
  color: #fff; font-size: 12.5px; font-weight: 650; letter-spacing: .2px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; min-width: 0;
  text-shadow: 0 1px 4px rgba(0,0,0,.55), 0 0 2px rgba(0,0,0,.4);
}
.att-vid-meta:empty { display: none; }
.att-vid-get {
  position: relative; width: 30px; height: 30px; border-radius: 50%; flex: none;
  border: none; padding: 0; cursor: pointer; color: #fff; background: rgba(0,0,0,.46);
  display: flex; align-items: center; justify-content: center; pointer-events: auto;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: background var(--motion-fast,.14s) ease, transform var(--motion-fast,.14s) var(--ease-standard,ease), opacity var(--motion-fast,.14s) ease;
}
.att-vid-get:hover { background: rgba(0,0,0,.72); }
.att-vid-get:active { transform: scale(.92); }
.att-vid-get svg.ic { width: 16px; height: 16px; display: block; }
.att-vid-get .vg-ic { display: none; align-items: center; justify-content: center; }
.att-vid[data-vphase="idle"] .vg-idle,
.att-vid[data-vphase="downloading"] .vg-stop,
.att-vid[data-vphase="cached"] .vg-ok,
.att-vid[data-vphase="failed"] .vg-retry { display: flex; }
.att-vid[data-vphase="downloading"] .vg-stop svg.ic { width: 13px; height: 13px; }
/* 🔴 Скачано — стрелки НЕТ (как в Telegram и в приложении, `SizedBox.shrink()`):
   мёртвых контролов не держим. Галочку показываем 1,6с сразу после загрузки
   (класс just-cached), чтобы человек увидел «получилось», и убираем. */
.att-vid[data-vphase="cached"] .att-vid-get { display: none; }
.att-vid.just-cached[data-vphase="cached"] .att-vid-get { display: flex; background: rgba(0,0,0,.32); }
.att-vid[data-vphase="cached"] .att-vid-get svg.ic { width: 14px; height: 14px; }
/* пока выясняем, лежит ли ролик в кеше — кнопку не мигаем (фаза checking, как в апке) */
.att-vid[data-vphase="checking"] .att-vid-get { visibility: hidden; }
/* кольцо прогресса по РЕАЛЬНЫМ байтам (см. ccVid.download) */
.att-vid-ring { position: absolute; inset: 0; width: 30px; height: 30px; transform: rotate(-90deg); display: none; }
.att-vid[data-vphase="downloading"] .att-vid-ring { display: block; }
.att-vid-ring .rbg { fill: none; stroke: rgba(255,255,255,.28); stroke-width: 2.4; }
.att-vid-ring .rfg {
  fill: none; stroke: #fff; stroke-width: 2.4; stroke-linecap: round;
  transition: stroke-dashoffset var(--motion-fast,.14s) linear;
}
/* нет service worker (первый заход / приват-режим) — грузить «в приложение» некуда:
   кнопку не показываем вовсе, остаётся честное «Сохранить на компьютер» */
.att-vid.no-sw .att-vid-get { display: none; }
/* подпись под медиа прижата к краю, без широких полей.
   🔴 Пузырь медиа ПРОЗРАЧНЫЙ (has-media снимает фон), но `.msg.mine .bubble{color:#fff}`
   наследовался в подпись → на СВЕТЛОЙ канве белый текст был НЕВИДИМ. Красим подпись
   в основной цвет текста (читаемо и в тёмной, и в светлой теме — как в Telegram). */
.bubble.has-media .att-cap { padding: 4px 2px 0; color: var(--text); }

/* ---- альбом: мозаика фото/видео (Telegram-стиль), крупные миниатюры ----
   Ряды с флекс-ячейками; высота ряда задаётся его aspect-ratio (инлайн). Одна и та
   же модель рядов на вебе (albumRows) и во Flutter (album_grid.dart) — паритет. */
.album-grid { display: flex; flex-direction: column; gap: 3px; width: min(100%, 576px); border-radius: 16px; overflow: hidden; } /* плитка −20% (владелец: громоздко) 720→576 */
/* 🔴 КРУПНЫЕ миниатюры (владелец: «в 2-3 раза больше»). Альбому нужна ОПРЕДЕЛЁННАЯ ширина
   родителя: `.msg.mine/.theirs` — shrink-to-fit, а `width:min(100%,576px)` без определённого
   родителя резолвится в min-content (ячейки `position:absolute`, своей ширины не имеют) —
   и альбом схлопывался до ширины ПОДПИСИ.
   🔴🔴 CLIE-470: определённость даёт `width` НА САМОМ `.msg` (он — флекс-элемент ленты, а у
   неё ширина определена, значит процент считается честно), а НЕ `align-self: stretch`, как
   было раньше. `stretch` тут — ловушка: `.msg:has(.album-grid)` имеет ТУ ЖЕ специфичность
   (0,2,0), что и `.msg.mine{align-self:flex-end}` (`:has()` берёт вес аргумента и своего не
   добавляет), но идёт НИЖЕ по файлу → перебивал сторону, и СВОЙ альбом уезжал ВЛЕВО, туда,
   где чужие сообщения (владелец: «отображаются не там, где мои, а где чужие»).
   Кап 576 (а не 720) = ширина самой сетки: подпись переносится ровно по краю альбома.
   На узком экране 74% < 576 → альбом ужимается вместе с пузырём (мобильный НЕ обрезается).
   🔴 НЕ возвращать сюда `align-self` — сторону задают только `.msg.mine/.theirs`. */
.msg:has(.album-grid) { width: min(74%, 576px); max-width: min(74%, 720px); } /* плитка −20% (92%→74%) */
.msg:has(.album-grid) > .bubble.has-media { width: 100%; }
.msg:has(.album-grid) .upl-album { width: 100%; } /* превью загрузки: inline-block-обёртка → на всю ширину */
.album-row { display: flex; gap: 3px; width: 100%; }
.album-cell { position: relative; overflow: hidden; cursor: pointer; background: #0b1220; min-width: 0; align-self: stretch; }
.album-cell img, .album-cell video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .3s ease; }
.album-cell:hover img { transform: scale(1.05); }
/* значок ▶ на видео-ячейке: полупрозрачный диск + иконка по центру */
.album-play { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; pointer-events: none; }
.album-play::before { content: ""; position: absolute; width: 54px; height: 54px; border-radius: 50%; background: rgba(0,0,0,.42); backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
.album-play .ic { position: relative; z-index: 1; width: 27px; height: 27px; color: #fff; filter: drop-shadow(0 1px 2px rgba(0,0,0,.5)); }
/* «+N» на последней ячейке, если вложений больше показанных */
.album-more { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,.5); color: #fff; font-size: 24px; font-weight: 600; letter-spacing: .5px; pointer-events: none; }
/* загрузка альбома: мозаика локальных превью + общий % поверх */
.upl-album { position: relative; display: inline-block; line-height: 0; border-radius: 16px; overflow: hidden; }
.upl-album .album-grid.uploading .album-cell { filter: brightness(.6); cursor: default; }

/* ---- Task 10: превью загрузки (миниатюра + прогресс + крестик ПО ЦЕНТРУ) ---- */
.upl-preview { position: relative; display: inline-block; line-height: 0; border-radius: 10px; overflow: hidden; }
.upl-thumb { max-width: 384px; max-height: 432px; border-radius: 10px; display: block; object-fit: cover; filter: brightness(.7); } /* превью загрузки = размер итогового медиа (384×432). Кружок upl (.att-circle 220) увеличение маскирует */
.upl-overlay {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 8px; pointer-events: none;
}
.upl-pct { color: #fff; font-size: 14px; font-weight: 700; text-shadow: 0 1px 6px rgba(0,0,0,.6); font-variant-numeric: tabular-nums; }
.upl-cancel-center {
  pointer-events: auto; width: 44px; height: 44px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0,0,0,.55); border: 2px solid rgba(255,255,255,.85); color: #fff;
  cursor: pointer; padding: 0; transition: background .15s, transform .1s;
}
.upl-cancel-center:hover { background: var(--danger); transform: scale(1.06); }
.upl-cancel-center .ic { width: 22px; height: 22px; }
/* тонкая полоса прогресса по низу превью */
.upl-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: rgba(255,255,255,.2); }
.upl-bar span { display: block; height: 100%; background: var(--primary-2); transition: width .2s ease; }
/* Фаза «Проверка…» (локальный sha256 + дедуп-проба): файл ещё НЕ льётся, поэтому вместо
   «0%» и статичной полосы — компактная метка и индетерминированный «бегунок» (как в iOS). */
.upl-pct.checking { font-size: 12px; font-weight: 600; letter-spacing: .01em; }
.upl-file-pct.checking { color: var(--primary-2); }
.upl-bar.indet { overflow: hidden; }
.upl-bar.indet span, .upl-file-bar.indet span {
  width: 40% !important; transition: none;
  animation: uplIndet 1.15s cubic-bezier(.65,.05,.36,1) infinite;
}
@keyframes uplIndet { 0% { transform: translateX(-110%); } 100% { transform: translateX(275%); } }
/* строка загрузки ФАЙЛА-документа: иконка + имя + полоса % + отмена (видно, что идёт upload) */
.upl-file { display: flex; align-items: center; gap: 8px; min-width: 200px; max-width: 300px; }
.upl-file .att-file-ic { flex: 0 0 auto; }
.upl-file-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.upl-file-body .att-file-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.upl-file-bar { height: 3px; border-radius: 2px; background: rgba(255,255,255,.2); overflow: hidden; }
.upl-file-bar span { display: block; height: 100%; background: var(--primary-2); transition: width .2s ease; }
.upl-file-pct { flex: 0 0 auto; font-size: 11px; color: var(--muted); }
.upl-file-x { flex: 0 0 auto; border: 0; background: transparent; color: var(--muted); cursor: pointer; padding: 2px; line-height: 0; }
.upl-file-x:hover { color: var(--text); }
/* кружок во время загрузки: первый кадр + КРУГЛОЕ кольцо прогресса + % и отмена по центру */
.upl-circle { position: relative; width: 220px; height: 220px; display: inline-block; line-height: 0; }
.upl-circle .att-circle { filter: brightness(.55); }
.upl-circle-blank { width: 220px; height: 220px; border-radius: 50%; background: var(--cm-1b1f2a, #1b1f2a); display: block; }
.upl-circle-ring { position: absolute; inset: -4px; width: 228px; height: 228px; transform: rotate(-90deg); pointer-events: none; }
.upl-circle-ring .r-bg { fill: none; stroke: rgba(255,255,255,.2); stroke-width: 4; }
.upl-circle-ring .r-fg { fill: none; stroke: var(--primary-2); stroke-width: 4; stroke-linecap: round; transition: stroke-dashoffset .2s ease; }
.upl-circle-center { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; line-height: normal; }
.upl-circle-center .upl-pct { color: #fff; font-size: 18px; font-weight: 700; text-shadow: 0 1px 6px rgba(0,0,0,.7); font-variant-numeric: tabular-nums; }
.att-file {
  display: inline-flex; gap: 8px; align-items: center;
  padding: 10px 14px; background: var(--panel-2); border-radius: 12px;
  color: var(--text); text-decoration: none; cursor: pointer; max-width: 100%;
}
.att-file:hover { filter: brightness(1.12); }
.att-file .att-file-ic { flex: 0 0 auto; display: inline-flex; color: var(--primary-2, var(--text)); }
.att-file .att-file-ic svg.ic { width: 20px; height: 20px; }
.att-file .att-file-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att-file .att-file-dl {
  flex: 0 0 auto; margin-left: 2px; color: var(--muted); text-decoration: none;
  line-height: 1; padding: 4px 6px; border-radius: 8px; display: inline-flex;
}
.att-file .att-file-dl svg.ic { width: 16px; height: 16px; }
.att-file .att-file-dl:hover { background: rgba(255,255,255,.12); color: var(--text); }
/* 🖼 CLIE-1136: картинка, посланная КАК ФАЙЛ, — та же строка, но с живой миниатюрой слева.
   Человек сразу видит, ЧТО ему прислали, и тапом открывает просмотрщик (как в Телеграме). */
.att-file-img { padding: 6px 12px 6px 6px; gap: 10px; }
.att-file-img .att-file-thumb {
  flex: 0 0 auto; width: 44px; height: 44px; border-radius: 9px; overflow: hidden;
  background: var(--panel); display: block; box-shadow: inset 0 0 0 1px rgba(128,128,128,.18);
}
.att-file-img .att-file-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Пузырь-«моё»: чип файла тоже светлый (контраст на ярком градиенте) */
.msg.mine .att-file .att-file-ic { color: var(--bub-ink-dim, rgba(255,255,255,.92)); }
.msg.mine .att-file .att-file-dl { color: var(--bub-ink-dim, rgba(255,255,255,.85)); }
.msg.mine .att-file .att-file-dl:hover { color: #fff; }
.att-cap { margin-top: 4px; padding: 0 4px; }

/* ───── Просмотрщик документов в чате (iframe /app/docviewer.html) ─────
   На ВЕСЬ экран (редактору OnlyOffice нужна вся ширина; владелец просил). */
#docViewer.modal-overlay { padding: 0; }
.docviewer-box {
  width: 100vw; height: 100dvh; max-width: none;
  background: var(--panel); border: 0; border-radius: 0;
  overflow: hidden; display: flex;
}
#docViewerFrame { width: 100%; height: 100%; border: 0; background: #fff; }
/* Свёрнуто: модалка прозрачна и СКВОЗНАЯ (клики уходят в сервис), но iframe жив —
   сессия OnlyOffice/автосейв/соавторы продолжаются. */
#docViewer.dv-min { opacity: 0; pointer-events: none; }
/* Плашка «свёрнутый документ» — снизу справа, поверх сервиса. */
.dv-pill {
  position: fixed; right: 16px; bottom: 16px; z-index: 90;
  display: flex; align-items: center; gap: 8px; max-width: 340px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 8px 8px 8px 12px; box-shadow: 0 12px 40px rgba(0,0,0,.5);
  cursor: move; user-select: none; touch-action: none; /* тащим мышью/пальцем */
}
.dv-pill button { cursor: pointer; }
.dv-pill.hidden { display: none; }
.dv-pill .dv-pill-ic { display: inline-flex; color: var(--primary-2, var(--text)); }
.dv-pill .dv-pill-ic svg.ic { width: 18px; height: 18px; }
.dv-pill .dv-pill-name {
  min-width: 0; flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; color: var(--text);
}
.dv-pill button { border: 0; cursor: pointer; border-radius: 8px; }
.dv-pill .dv-pill-open { background: var(--acc-fill, #5b8def); color: #fff; padding: 6px 12px; font-size: 13px; font-weight: 600; white-space: nowrap; }
.dv-pill .dv-pill-open:hover { filter: brightness(1.08); }
.dv-pill .dv-pill-x { background: transparent; color: var(--muted); padding: 6px; display: inline-flex; }
.dv-pill .dv-pill-x:hover { color: var(--text); }
.dv-pill .dv-pill-x svg.ic { width: 15px; height: 15px; }

/* ───── Меню скрепки: файл / создать документ ───── */
.attach-menu {
  position: fixed; z-index: 80; min-width: 216px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 12px;
  padding: 6px; box-shadow: 0 12px 40px rgba(0,0,0,.5);
}
.attach-menu button {
  display: flex; align-items: center; gap: 10px; width: 100%;
  background: transparent; border: 0; color: var(--text); cursor: pointer;
  padding: 9px 10px; border-radius: 8px; font-size: 14px; text-align: left;
}
.attach-menu button:hover { background: rgba(255,255,255,.08); }
.attach-menu button svg { width: 18px; height: 18px; flex: 0 0 auto; }
.attach-menu .am-ic { font-size: 17px; width: 18px; text-align: center; flex: 0 0 auto; }
.attach-menu .am-h {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted); padding: 8px 10px 4px; margin: 2px 0 0;
  border-top: 1px solid var(--line);
}

/* ---- Перетаскивание файлов: оверлей поверх .thread ---- */
.drop-overlay {
  position: absolute; inset: 0; z-index: 40;
  display: flex; align-items: center; justify-content: center;
  background: rgba(15, 17, 21, 0.82);
  border: 2px dashed var(--accent); border-radius: 14px;
  pointer-events: none;
}
.drop-overlay.hidden { display: none; }
.drop-inner { text-align: center; color: var(--accent); font-weight: 600; }
.drop-inner .drop-ico { font-size: 40px; line-height: 1; margin-bottom: 8px; }

/* ---- Лоток прикреплённых файлов (staging) над композером ---- */
.attach-tray {
  display: flex; gap: 10px; flex-wrap: wrap;
  padding: 10px 12px; margin: 0 6px;
  background: var(--panel-2); border: 1px solid var(--border);
  border-radius: 12px 12px 0 0;
}
.attach-tray.hidden { display: none; }
/* 🔴 РАЗМЕР МИНИАТЮРЫ — ПРОСЬБА ВЛАДЕЛЬЦА (CLIE-1742): «Размер миниатюр чуть больше
   сделай, неудобно сейчас». 84 → 96: кадр видео и лицо на фото читаются, а лоток
   по-прежнему укладывается в одну строку из четырёх плиток при ширине треда 440. */
.att-tile { display: flex; flex-direction: column; align-items: center; gap: 5px; width: 96px; }
.att-tile-thumb {
  position: relative; width: 96px; height: 96px; border-radius: 10px;
  overflow: hidden; background: var(--panel);
  display: flex; align-items: center; justify-content: center;
}
.att-tile-thumb img, .att-tile-thumb video { width: 100%; height: 100%; object-fit: cover; }
/* Правка картинки — по клику на САМУ миниатюру (никаких карандашей и «режимов правки»).
   Подпись «Изменить» всплывает только при наведении/фокусе: пустое состояние плитки
   экран у пользователя не отбирает. */
.att-tile-thumb.att-editable { cursor: pointer; }
.att-tile-thumb.att-editable:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.att-tile-edit {
  position: absolute; left: 0; right: 0; bottom: 0; height: 21px;
  display: flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 640; letter-spacing: -.01em; color: #fff;
  background: linear-gradient(to top, rgba(0,0,0,.66), rgba(0,0,0,0));
  opacity: 0; transition: opacity .14s var(--ease-standard, ease); pointer-events: none;
}
.att-tile-thumb.att-editable:hover .att-tile-edit,
.att-tile-thumb.att-editable:focus-visible .att-tile-edit { opacity: 1; }
/* «Изменено» — точка-бейдж (акцент точкой, а не полосой) */
.att-tile-dot {
  position: absolute; left: 6px; top: 6px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--primary); box-shadow: 0 0 0 2px rgba(0,0,0,.34);
}
.att-tile-file { font-size: 34px; }
/* ▶ по центру кадра (как у пузыря видео в ленте), а не в углу: угол занят бейджем
   длительности и точкой «изменено». */
/* ▶ на плитке лотка — ТОТ ЖЕ знак, что на видео в переписке (`.att-vid-play`), только
   под размер плитки. Текстовым глифом «▶» он быть не может: у каждой ОС своя форма, своя
   толщина и своя базовая линия — именно это владелец и снял на скриншоте. */
.att-tile-badge {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  color: #fff; pointer-events: none;
  background-image: linear-gradient(to bottom, rgba(0,0,0,.26) 0%, rgba(0,0,0,0) 40%, rgba(0,0,0,0) 62%, rgba(0,0,0,.3) 100%);
}
.att-tile-badge::before {
  content: ""; position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
  width: 34px; height: 34px; border-radius: 50%;
  background: rgba(0,0,0,.42); border: 1.5px solid rgba(255,255,255,.9);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  box-shadow: 0 4px 12px rgba(0,0,0,.26);
}
.att-tile-badge svg.ic { position: relative; width: 17px; height: 17px; display: block; margin-left: 2px; }
/* Длительность видео — вместо служебного имени файла: человек только что выбрал файл
   сам, ему нужна ДЛИНА ролика, а не `image_picker_…`. */
.att-tile-dur {
  position: absolute; right: 4px; bottom: 4px; padding: 1px 5px; border-radius: 6px;
  background: rgba(0,0,0,.58); color: #fff; font-size: 10.5px; font-weight: 650;
  line-height: 15px; pointer-events: none;
}
/* Кадр в плитке: первый кадр виден сразу (src c #t=0.1), поэтому фон не «чёрный ящик». */
.att-tile-thumb video { background: #000; }
.att-tile-x {
  position: absolute; top: 3px; right: 3px; width: 20px; height: 20px;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(0,0,0,0.6); color: #fff; font-size: 12px; line-height: 20px; padding: 0;
}
.att-tile-x:hover { background: rgba(0,0,0,0.85); }
/* Сегмент «Фото/Файл» = РОВНО по ширине плитки (84px), кнопки делят её поровну и не
   вылезают наружу. Раньше inline-flex без ширины → две кнопки шире плитки НАЛЕЗАЛИ на
   соседнюю плитку (баг владельца, паритет с Flutter-фиксом FittedBox). */
.att-tile-mode { display: flex; width: 100%; max-width: 96px; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.att-mode-btn {
  flex: 1 1 0; min-width: 0; border: 0; background: transparent; color: var(--muted);
  font-size: 11px; padding: 2px 4px; cursor: pointer; white-space: nowrap; text-align: center;
}
.att-mode-btn.on { background: var(--acc-fill); color: #fff; }

/* ---- office-документ в лотке: право правки + режим сохранения (0098) ----
   Плитка ШИРЕ обычной (лоток flex-wrap → просто переносится): узкая обрезала «Новый файл».
   Сегмент-контрол в стиле iOS: трек-подложка + внутренние скруглённые кнопки. */
.att-tile.att-tile-wide { width: 176px; }
.att-tile-oo { display: flex; flex-direction: column; gap: 5px; width: 100%; }
.att-oo-perm {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; border: 1px solid var(--border); border-radius: 9px; background: transparent;
  color: var(--muted); font-size: 11.5px; font-weight: 600; padding: 5px 8px; cursor: pointer;
  white-space: nowrap; transition: background .13s ease, color .13s ease, border-color .13s ease;
}
.att-oo-perm svg.ic { width: 14px; height: 14px; flex: 0 0 auto; }
.att-oo-perm.on { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.att-oo-perm:hover { border-color: var(--accent); }
.att-oo-mode {
  display: flex; width: 100%; gap: 2px; padding: 2px; border-radius: 9px;
  background: color-mix(in srgb, var(--text) 7%, transparent);
}
.att-oo-mbtn {
  flex: 1 1 0; min-width: 0; border: 0; background: transparent; color: var(--muted);
  font-size: 11px; font-weight: 600; padding: 5px 6px; cursor: pointer; white-space: nowrap;
  text-align: center; border-radius: 7px; transition: background .13s ease, color .13s ease;
}
.att-oo-mbtn.on { background: var(--acc-fill); color: #fff; }
.att-oo-mbtn:not(.on):hover { color: var(--text); }
/* «только просмотр» бейдж на пузыре файла */
.att-file .att-file-ro { display: inline-flex; vertical-align: -2px; margin-left: 4px; color: var(--muted); }
.att-file .att-file-ro svg.ic { width: 14px; height: 14px; }

/* ---- карточка контакта (поделились контактом) ---- */
.contact-card { min-width: 180px; }
.contact-row { display: flex; align-items: center; gap: 10px; }
.contact-avatar {
  width: 40px; height: 40px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  background: var(--acc-grad); color: #fff; font-weight: 600; font-size: 18px;
}
.contact-meta { min-width: 0; }
.contact-name { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.contact-phone { margin-top: 1px; }
.contact-write { margin-top: 8px; width: 100%; }
.msg.mine .contact-phone { color: var(--bub-ink-dim, rgba(255,255,255,.9)); }
/* Кликабельная строка контакта → профиль: курсор, мягкий hover, шеврон-подсказка. */
.contact-row.contact-open { cursor: pointer; border-radius: 9px; margin: -3px -5px; padding: 3px 5px; transition: background .13s ease; }
.contact-row.contact-open:hover { background: rgba(127,127,127,.10); }
.msg.mine .contact-row.contact-open:hover { background: var(--bub-tint); }
.contact-chev { margin-left: auto; flex: none; display: flex; align-items: center; opacity: .4; }
.contact-chev svg { width: 16px; height: 16px; }
.contact-row.contact-open:hover .contact-chev { opacity: .7; }
.msg.mine .contact-chev { opacity: .55; }

/* ---- голосовые ---- */
.mic-btn { padding: 9px 12px; font-size: 18px; flex: none; }
.rec-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 18px; border-top: 1px solid var(--line);
  /* 🔴 CLIE-940 — якорь для капсулы-замка: она стоит НАД полосой, там же, где палец. */
  position: relative;
}
.rec-bar .rec-hint { flex: 1; min-width: 0; }

/* ── 🔴🔴 CLIE-940·2 · ДВЕ МИШЕНИ ЖЕСТА ЗАПИСИ (варианты А + Б, «ровно») ───────────────
   Владелец 06.09.2026: «чтобы записывать голосовое без удержания пальца на экране нужно
   сдвинуть палец вверх. Но в интерфейсе нет визуальных элементов которые бы говорили
   пользователю что делать». И следом, вернув задачу: «Давай оба варианта А и Б. Только
   сделай ровно, сейчас у тебя не ровно все стоит».

   Он прав ЧИСЛАМИ. Замер живого прода (tools/shots/clie940-aim.js) ДО правки: капсула
   стояла на 40.6 px ПРАВЕЕ центра кнопки записи и на 79 px вверх при пороге 64, потому
   что была прибита к КРАЮ полосы (`right: 14px`), а не к кнопке, под которой палец.

   Теперь мишеней ДВЕ (вариант Б — «видно сразу обе возможности»), у каждой своя честная
   шкала-кольцо (вариант А), и обе стоят НА ПОРОГЕ жеста:
     • «замок»  — ровно НАД центром кнопки, на --rt-up  (= HOLD_LOCK_DY);
     • «отмена» — на одной линии с ним, левее на --rt-left (= HOLD_CANCEL_DX).
   🔴 Числа тут не «на глаз»: их паритет с порогами жеста сторож VHINT_MECH сверяет СЧЁТОМ.
   Мишень, стоящая не на пороге, врёт о жесте так же, как чужая арифметика шкалы: довёл
   палец ДО мишени — а порог ещё не взят.
   Центр кнопки (--aim-x/--aim-y) кладёт ЗАМЕР `voiceAim()`, а не прибитое число: полоса
   перекладывается («Удалить» на узком экране становится значком), и прибитое промахнётся. */
#recBar {
  --rt-size: 48px;   /* диаметр мишени */
  --rt-up: 64px;     /* ≡ HOLD_LOCK_DY   — вверх до замка */
  --rt-left: 72px;   /* ≡ HOLD_CANCEL_DX — влево до отмены */
  /* Центр кнопки записи внутри полосы. Значения по умолчанию — на случай, если замер ещё
     не отработал; настоящие кладёт `voiceAim()` инлайном (он сильнее таблицы стилей). */
  --aim-x: 50%;
  --aim-y: 50%;
}
.rec-tgt {
  position: absolute; display: none; pointer-events: none;
  width: var(--rt-size); height: var(--rt-size); border-radius: 50%;
  --t: 0; --rt-ink: var(--primary);
  --rt-rail: color-mix(in srgb, var(--text) 14%, transparent);
  /* 🔴 CLIE-940·5 — СВЕЧЕНИЕ РАСТЁТ С ДОЛЕЙ ПУТИ: «горячо» видно боковым зрением, даже
     когда палец закрывает саму мишень. Тень и свечение — один слой, разные роли. */
  box-shadow:
    0 10px 24px rgba(0, 0, 0, .18),
    0 0 calc(26px * var(--t, 0)) color-mix(in srgb, var(--rt-ink) calc(34% * var(--t, 0)), transparent);
  /* Мишень НЕ ездит за пальцем (она цель, а не бегунок) — но подрастает, когда палец
     близко: движение принято, порог вот-вот. Центр при этом остаётся на месте. */
  transform: scale(calc(1 + .07 * var(--t, 0)));
  /* 🔴 «КАК ВОДА»: доля пути и цвет догоняют палец ПЛАВНО, а не прыгают по кадрам. */
  transition: transform .16s cubic-bezier(.34, 1.4, .64, 1), box-shadow .16s ease-out;
  /* …и появляется мишень ПРУЖИНОЙ, вырастая из кнопки (`both` тут нельзя: залипший
     кадр анимации перебил бы живой `transform` выше — и подрастание умерло бы молча). */
  animation: rt-grow .28s cubic-bezier(.34, 1.56, .64, 1);
}
@keyframes rt-grow {
  from { transform: scale(.62); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}
/* 🔴🔴 CLIE-940·5 · У КАЖДОЙ МИШЕНИ СВОЯ ОСЬ — та, по которой её порог и срабатывает.
   Владелец, ПЯТЫЙ возврат: «ты изменил логику. Раньше отмена была слева, а теперь сверху».
   Пока обе висели на одной линии НАД кнопкой, «отмена» стояла по ДИАГОНАЛИ, где отмена не
   срабатывает вовсе (вертикаль перевешивает → замок). Теперь: «замок» — строго вверх на
   --rt-up, «отмена» — строго влево на --rt-left, на горизонтали пальца. */
.rec-tgt-lock {
  left: calc(var(--aim-x) - var(--rt-size) / 2);
  top: calc(var(--aim-y) - var(--rt-up) - var(--rt-size) / 2);
}
.rec-tgt-cancel {
  left: calc(var(--aim-x) - var(--rt-left) - var(--rt-size) / 2);
  top: calc(var(--aim-y) - var(--rt-size) / 2);
  --rt-ink: var(--danger);
}
/* Видны РОВНО пока держат палец. Под замком (.locked) подсказывать нечего — руки уже
   свободны, в полосе стоят «Удалить»/«Отправить». При взведённой отмене мишени ОСТАЮТСЯ:
   палец сейчас ровно на ней, и гасить цель в момент попадания — обман. */
#recBar:not(.locked) .rec-tgt { display: block; }
/* 🔴 CLIE-940·8 · ПАУЗА видна РОВНО под замком: пока держат кнопку записи, нажать её
   нечем (вторая рука занята жестом) — это то же правило «не отбирать экран до
   необходимости», что у мишеней, только зеркальное. Правило по `#recBar`, а НЕ по
   `.rec-bar`: тот же класс носит полоса ДИКТОВКИ (`#dictBar`), у которой паузы нет. */
#recBar .rec-pause { display: none; padding: 6px 8px; }
#recBar.locked .rec-pause { display: inline-flex; align-items: center; }
#recBar.locked .rec-pause svg.ic { width: 18px; height: 18px; }
/* 🔥 CLIE-940·9 · ОДНОРАЗОВОЕ ГОЛОСОВОЕ — тумблер «1» в полосе записи.
   В отличие от паузы он виден В ОБОИХ состояниях: доминирующий путь голосового —
   «нажал-сказал-отпустил» (без замка), и спрятать решение под замок значило бы, что на
   этом пути фичи нет вовсе. Включённое состояние читается И цветом, И цифрой (правило
   акцента: уровень называем знаком, а не одним оттенком). */
#recBar .rec-once {
  display: inline-flex; align-items: center; gap: 4px; padding: 6px 8px;
  border-radius: 999px;
}
#recBar .rec-once svg.ic { width: 17px; height: 17px; }
#recBar .rec-once .rec-once-n { font-size: 11px; font-weight: 700; line-height: 1; }
#recBar .rec-once.on {
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent);
}
/* Узкий экран: полоса записи и без того тесная — у тумблера остаётся значок с цифрой. */
@media (max-width: 520px) { #recBar .rec-once { padding: 6px; } }
/* Одноразовое голосовое в ленте: волна — ПОКАЗАТЕЛЬ, а не перемотка (второе
   прослушивание того же = обход одноразовости), поэтому курсор не обещает драг. */
.msg.theirs .voice-msg.voice-once .vp-wave { cursor: default; }
.msg.theirs .voice-msg.voice-once .vp-knob { display: none; }
/* На паузе точка гаснет (обводка вместо заливки), а таймер тускнеет: «горящая» красная
   точка рядом с замершим таймером — состояние, которого нет. */
#recBar.paused .rec-dot { background: transparent; box-shadow: inset 0 0 0 2px var(--muted); }
#recBar.paused .rec-timer { color: var(--muted); }
/* Честная шкала: кольцо заполнено ровно на долю пройденного пути (её считает `holdGauge`
   — та же формула, по которой срабатывает жест). */
.rec-tgt .rt-ring {
  position: absolute; inset: 0; border-radius: 50%;
  background: conic-gradient(var(--rt-ink) calc(var(--t, 0) * 360deg), var(--rt-rail) 0);
  transition: background .08s linear;
}
/* 🔴 CLIE-940·5 · СТЕКЛО И ВОДА. Мишень висит НАД перепиской и над полосой записи —
   матовое размытие единственный материал, который не притворяется частью ни того, ни
   другого (то же решение, что у островка композера). А доля пути НАЛИВАЕТСЯ уровнем: это
   и есть просьба владельца «сейчас делают все как вода». 🔴 Тон воды имеет ПОТОЛОК: она
   подложка под собственным значком и словом, и, став плотнее чернил, сама сделала бы то,
   против чего заведено правило контраста (CLIE-888). */
.rec-tgt .rt-body {
  position: absolute; inset: 3px; border-radius: 50%; overflow: hidden;
  background-color: color-mix(in srgb, var(--panel) 84%, transparent);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  color: color-mix(in srgb, var(--rt-ink) calc(100% * var(--t, 0)), var(--muted));
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1px;
  transition: color .16s ease-out;
}
.rec-tgt .rt-body::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  opacity: calc(.14 + .32 * var(--t, 0));
  background: linear-gradient(to top, var(--rt-ink) calc(var(--t, 0) * 100%), transparent 0);
  transition: opacity .16s ease-out, background .16s ease-out;
}
.rec-tgt .rt-ic { width: 17px; height: 17px; display: block; }
.rec-tgt .rt-cap { font-size: 9px; font-weight: 700; line-height: 1; letter-spacing: .2px; }
/* Порог взят — мишень «горячая»: замок закрывается, цвет становится своим (акцент у замка,
   красный у отмены). Это тот же миг, в который сработает жест. */
/* Порог взят: значок «отмены» становится корзиной, замок закрывается, кольцо и свечение
   уже полные — доливать цвет поверх воды нельзя, чернила обязаны остаться читаемыми. */
.rec-tgt.hot .rt-body { color: var(--rt-ink); }
.rec-tgt-cancel .rt-ic-hot, .rec-tgt-cancel.hot .rt-ic-idle { display: none; }
.rec-tgt-cancel.hot .rt-ic-hot { display: block; }
.rec-tgt .rl-shut, .rec-tgt.hot .rl-open { display: none; }
.rec-tgt.hot .rl-shut { display: block; }
#recBar #recCancel svg.ic { display: none; width: 17px; height: 17px; }
/* 🔴 CLIE-940·5 · КНОПКА ЗАПИСИ В ПОЛОСЕ — КРУГЛАЯ, КАК В ПРИЛОЖЕНИИ. Мишень «отмена»
   стоит на своём пороге (72 px влево от пальца), а широкая кнопка-текст «Отправить»
   занимала ровно это место: стекло мишени накрывало живой выход (CLIE-686). Круг 46 px —
   тот же размер, что `VoiceRecRow.kButtonSize`, и тот же язык жеста на обоих клиентах. */
#recBar #recStop {
  width: 46px; height: 46px; padding: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; flex: none;
}
#recBar #recStop span { display: none; }
#recBar #recStop svg.ic { display: block; width: 20px; height: 20px; }
@media (max-width: 560px) {
  /* Узкая полоса телефона: «Удалить» становится значком (кнопка ОСТАЁТСЯ на месте и
     кликабельной — обещание CLIE-686 не про слово, а про наличие выхода; в приложении
     она значком и нарисована). Освободившееся место отдаём подсказке жеста — ради неё
     всё и делалось. */
  #recBar #recCancel svg.ic { display: inline-block; }
  #recBar #recCancel span { display: none; }
  #recBar #recCancel { padding: 8px 10px; }
}
@media (prefers-reduced-motion: reduce) {
  .rec-tgt, .rec-tgt .rt-ring { transition: none; }
}

/* ── 🎙️ ДИКТОВКА (Typeless): кнопка у скрепки, полоса записи, панель результата ──
   Кнопка стоит РЯДОМ СО СКРЕПКОЙ и видна всегда: диктуют в ПУСТОЕ поле, а верхняя
   строка .comp-tools всплывает только когда человек уже печатает (CLIE-189).
   Размеры — токены ряда (--ctl-h/--ctl-r), своих чисел не заводим (CLIE-505).       */
.dict-btn { position: relative; flex: 0 0 auto; }
.dict-btn.on { color: var(--danger); }
.dict-btn.on .ic { animation: dictPulse 1.1s ease-in-out infinite; }
/* 🔴🔴 «ИДЁТ ОБРАБОТКА» — ЭТО КОЛЬЦО, А НЕ БЛЕДНАЯ ИКОНКА (CLIE-1100). Прежний
   `opacity:.6` был единственным следом процесса на всём экране: полоса записи с подписью
   к этому моменту уже спрятана, и человек 10–60 секунд смотрел на чуть тусклый микрофон.
   Бледность читается как «кнопка выключена», а не как «ИИ работает». */
.dict-btn.busy { opacity: 1; pointer-events: none; }
.dict-btn.busy .ic { opacity: .3; }
.dict-btn.busy::after {
  content: ""; position: absolute; inset: 3px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--accent) 20%, transparent);
  border-top-color: var(--accent);
  animation: dictSpin .8s linear infinite;
}
@keyframes dictPulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
@keyframes dictSpin { to { transform: rotate(360deg); } }
/* Уважаем системную настройку «меньше движения»: пульс — украшение, а не смысл. */
@media (prefers-reduced-motion: reduce) { .dict-btn.on .ic { animation: none; } }
/* 🔴 А вот кольцо обработки движение НЕ теряет: остановленный спиннер = «залипло», то есть
   ровно та беда, ради которой он и заведён. Замедляем, но не гасим. */
@media (prefers-reduced-motion: reduce) {
  .dict-btn.busy::after, .dictp-spin { animation-duration: 2.4s; }
}

/* 🔴 СТРОКА «ИИ РАБОТАЕТ НАД ТЕКСТОМ» (CLIE-1100): слово + живой счётчик секунд. Ровно
   тот же язык поверхности, что у панели результата ниже (та же подложка, та же линия,
   тот же кегль), — это одно состояние одного композера, а не второй виджет. */
.dict-proc {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; border-top: 1px solid var(--line); background: var(--panel-2);
  font-size: 12.5px; color: var(--text);
}
.dictp-spin {
  width: 14px; height: 14px; flex: 0 0 auto; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--accent) 20%, transparent);
  border-top-color: var(--accent);
  animation: dictSpin .8s linear infinite;
}
.dictp-say { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dictp-secs { flex: 0 0 auto; color: var(--muted); font-variant-numeric: tabular-nums; }

.dict-bar .rec-dot { background: var(--danger); }

/* Панель результата: стиль/язык/убрать. Живёт НАД композером, экран не отбирает —
   появляется только после диктовки и закрывается крестиком. */
.dict-panel { padding: 8px 14px; border-top: 1px solid var(--line); background: var(--panel-2); }
.dict-panel.busy { opacity: .55; pointer-events: none; }
.dict-panel-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* 🔴 Своих правил у кнопок сегмента НЕТ: дорожку, пилюлю, разделители и высоту
   рисует КАНОН `.cc-seg > *` (CLIE-505). Здесь только ширина ряда. */
.dict-seg { max-width: 100%; }
.dict-lang {
  height: 26px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--panel); color: var(--text); font-size: 12.5px; padding: 0 6px; max-width: 190px;
}
/* 🔴 ПОДАЧА (CLIE-1100) — тот же размерный класс ряда, что у выбора языка: один ряд —
   один контрол (CLIE-505). Шире языка, потому что подпись длиннее («Подача: дружеский»). */
.dict-tone { max-width: 220px; }
.dict-x { margin-left: auto; padding: 0 8px; height: 26px; }
/* «ИИ поменял: «…»» — что именно сделала правка голосом (CLIE-950·38). Не кнопка, а
   подпись: подложка акцента и кольцо-хэйрлайн вместо рейки (правило акцента CLIE-483),
   высота та же 26px, что у соседей ряда (правило единого контрола CLIE-505). */
.dict-chg {
  height: 26px; display: inline-flex; align-items: center; padding: 0 10px;
  border-radius: 8px; font-size: 12.5px; max-width: 320px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; color: var(--text);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent);
}
/* «По вашей просьбе: «…»» — просьба человека в самой речи перебила выбранную подачу
   (CLIE-1100·3). Своя краска, чтобы чип не путался с «ИИ поменял: …»; форма та же —
   подложка и кольцо-хэйрлайн, без реек (CLIE-483). */
.dict-own {
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 26%, transparent);
}
/* 💬 «Вижу чат: …» / «Открытого чата не вижу» — какой чат попал в ход ИИ (CLIE-1217·Р4).
   Форма та же, что у соседей ряда (подложка + кольцо-хэйрлайн, высота 26px, CLIE-483/505):
   это НЕ новая деталь, а тот же чип состояния. Видимый — кнопка (ведёт в беседу), пустой —
   подпись без краски акцента: хвалиться нечем, и красить это акцентом было бы враньём. */
.dict-ctx {
  height: 26px; padding: 0 10px; border-radius: 8px; font-size: 12.5px; white-space: nowrap;
  max-width: 320px; overflow: hidden; text-overflow: ellipsis;
  display: inline-flex; align-items: center; flex: 0 0 auto; cursor: pointer;
  border: 1px solid transparent; color: var(--text);
  background: color-mix(in srgb, var(--ok) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 34%, transparent);
  transition: background .14s ease, box-shadow .14s ease;
}
.dict-ctx:hover {
  background: color-mix(in srgb, var(--ok) 24%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 52%, transparent);
}
/* Чата нет — хвалиться нечем: краски акцента тут не будет, только честная нейтральная
   подпись. Своя подложка, а не наследство `.dict-chg`: у того подложка акцентная. */
.dict-ctx-none {
  color: var(--muted);
  background: color-mix(in srgb, var(--text) 7%, transparent);
  box-shadow: inset 0 0 0 1px var(--line);
}

/* Стикер, подобранный ИИ по смыслу (CLIE-950·5). Показываем САМ стикер, а не слово
   «стикер»: человек выбирает картинку глазами. Высота — та же 26px, что у соседей ряда
   (правило единого контрола CLIE-505). */
.dict-sticker {
  height: 26px; width: 26px; padding: 0; border-radius: 6px; flex: 0 0 auto;
  border: 1px solid var(--line); background: var(--panel); overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color .14s ease, transform .14s ease;
}
.dict-sticker img { width: 100%; height: 100%; object-fit: contain; display: block; }
.dict-sticker:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); transform: scale(1.06); }

/* «Выполнить задание» / «Это мой текст» — переиграть решение ИИ одним нажатием.
   Высота та же 26px, что у соседей ряда (правило единого контрола CLIE-505): один ряд —
   один размерный класс. Состояние «ИИ выполнил» несёт подложку и кольцо-хэйрлайн, а не
   левую рейку (правило акцента CLIE-483). */
.dict-intent {
  height: 26px; padding: 0 10px; border-radius: 8px; font-size: 12.5px; white-space: nowrap;
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  transition: background .14s ease, border-color .14s ease, color .14s ease;
}
.dict-intent:hover { border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); }
.dict-intent.did {
  background: color-mix(in srgb, var(--accent) 12%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent);
  border-color: transparent;
  color: var(--text);
}

/* Настройки → «Диктовка»: словарь терминов. */
.dict-term-add { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 10px 0; }
.dict-term-add input {
  flex: 1 1 190px; min-width: 150px; height: var(--ctl-h, 32px);
  border-radius: var(--ctl-r, 10px); border: 1px solid var(--line);
  background: var(--panel); color: var(--text); padding: 0 10px; font-size: var(--ctl-fs, 13px);
}
.dict-term-list { display: flex; flex-direction: column; gap: 6px; }
.dict-term {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel);
}
.dict-term-w { font-weight: 600; }
/* 🔴 Вариант «как слышится» — КАПСУЛА СО СВОИМ «убрать» (CLIE-950·42): у одного написания
   их несколько, и убирать нужно поштучно. Подложка акцента и кольцо-хэйрлайн вместо рейки
   (правило акцента CLIE-483). */
.dict-term-h {
  font-size: 12px; display: inline-flex; align-items: center; gap: 2px;
  padding: 2px 4px 2px 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 20%, transparent);
}
.dict-term-del { margin-left: auto; padding: 0 8px; height: 26px; }
/* Внутри капсулы «убрать» не растягивает ряд: оно относится к СВОЕМУ варианту. */
.dict-term-h .dict-term-del { margin-left: 0; height: 20px; padding: 0 5px; font-size: 11px; }
.dict-set-row { display: flex; align-items: center; gap: 10px; margin: 10px 0; flex-wrap: wrap; }
.dict-set-row label { flex: 0 0 190px; color: var(--text-2); font-size: 13px; }
.dict-set-row select {
  flex: 1 1 240px; min-width: 180px; height: var(--ctl-h, 32px);
  border-radius: var(--ctl-r, 10px); border: 1px solid var(--line);
  background: var(--panel); color: var(--text); padding: 0 8px; font-size: var(--ctl-fs, 13px);
}

.rec-bar .primary { width: auto; margin: 0; padding: 10px 18px; }
/* 🔴 CLIE-686. Раньше здесь стояло `.rec-bar:not(.locked) #recCancel, #recStop
   { display:none }` — «пока держат, кнопки нажать нечем». На деле это оставляло
   состояние БЕЗ ЕДИНОГО выхода: композер на время записи `display:none`, а отпускание
   могло не доехать (потеря pointer capture, перенос узла `<main.thread>`, alt-tab).
   Человеку оставалось закрыть приложение. Кнопки «Удалить» и «Отправить» стоят ВСЕГДА —
   разница между «держат» и «замок» только в подсказке. */
.rec-bar.locked .rec-dot { animation: recPulse 1.6s ease-in-out infinite; }
@keyframes recPulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
@media (prefers-reduced-motion: reduce) { .rec-bar.locked .rec-dot { animation: none; } }

/* ── Черновик кружка над композером (CLIE-548) ──
   Показывается ТОЛЬКО когда запись есть, но ещё не отправлена. Кружок-миниатюра слева
   кликается (открыть предпросмотр), справа — «Удалить»/«Отправить». Рейки слева нет:
   акцент несут круглая миниатюра и слово (правило CLIE-483). */
.circle-draft {
  display: flex; align-items: center; gap: 12px; margin: 0 12px 8px;
  padding: 8px 10px; border-radius: 14px;
  background: color-mix(in srgb, var(--primary) 8%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}
.circle-draft .cd-thumb {
  width: 44px; height: 44px; flex: 0 0 44px; padding: 0; border: none; cursor: pointer;
  border-radius: 50%; overflow: hidden; background: #000;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 55%, transparent);
  transition: transform .14s ease;
}
.circle-draft .cd-thumb:hover { transform: scale(1.05); }
.circle-draft .cd-video { width: 100%; height: 100%; object-fit: cover; transform: scaleX(-1); }
.circle-draft .cd-meta { display: flex; flex-direction: column; gap: 1px; flex: 1; min-width: 0; }
.circle-draft .cd-title { font-size: 13px; font-weight: 600; color: var(--text); }
.circle-draft .cd-dur { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.circle-draft .ghost, .circle-draft .primary { width: auto; margin: 0; padding: 7px 14px; font-size: 13px; }
.rec-dot {
  width: 12px; height: 12px; border-radius: 50%; background: var(--danger);
  animation: recpulse 1s infinite; flex: none;
}
@keyframes recpulse { 0%,100% { opacity: 1; } 50% { opacity: .25; } }
.rec-timer { font-variant-numeric: tabular-nums; font-weight: 600; }
/* ── Голосовое сообщение: кастомный плеер (play + волна + время), как в приложении.
   Раньше был сырой <audio controls> («ерунда» на вебе). Тема адаптируется под пузырь:
   в СВОИХ (градиент) — белым, у СОБЕСЕДНИКА — акцентным индиго. ──────────────────── */
.voice-msg {
  display: flex; align-items: center; gap: 11px;
  padding: 3px 2px 2px; min-width: 226px;
  --vp-w: 168px;                       /* ширина волны = ширине «залитого» слоя (бары совпадают) */
  --vp-dim: rgba(255,255,255,.8);      /* непройденные бары */
  --vp-lit: #fff;                      /* пройденные бары / ползунок / время */
  --vp-btn-bg: #fff;  /* фон кнопки play */
  --vp-btn-fg: var(--acc-fill, var(--primary));         /* значок play */
  /* 🔴 подложка чипа скорости идёт ТЕМНЕЕ заливки пузыря (канон contrast-runtime-audit):
     осветляющая rgba(255,255,255,.2) поднимала фон под белыми цифрами «1×» («Контрастность», 10.09.2026) */
  --vp-chip-bg: var(--cm-0b1020-26, rgba(11,16,32,.26));    /* фон чипа скорости (свой пузырь) */
}
.msg.theirs .voice-msg {
  --vp-dim: var(--muted);
  --vp-lit: var(--primary-2);
  --vp-btn-bg: var(--acc-fill, var(--primary));
  --vp-btn-fg: #fff;
  --vp-chip-bg: color-mix(in srgb, var(--primary-2) 15%, transparent);
}
/* The bubble owns player colors; theme-wide button skins must not repaint them. */
.msg .voice-msg .vp-play {
  flex: none; width: 42px; height: 42px; border-radius: 50%;
  border: none; padding: 0; cursor: pointer; margin: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--vp-btn-bg); color: var(--vp-btn-fg);
  box-shadow: 0 2px 8px -2px rgba(0,0,0,.4);
  transition: transform .12s ease, box-shadow .18s ease, filter .18s ease;
}
.vp-play:hover { transform: scale(1.06); filter: brightness(1.03); }
.vp-play:active { transform: scale(.93); }
.vp-play svg.ic { width: 20px; height: 20px; }
.vp-play:not(.playing) svg.ic { margin-left: 2px; } /* треугольник ▶ — оптический центр */

.vp-body { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.vp-wave {
  position: relative; width: var(--vp-w); height: 26px;
  cursor: pointer; touch-action: none; outline: none;
}
.vp-bars {
  position: absolute; top: 0; bottom: 0; left: 0;
  display: flex; align-items: center; gap: 2px; pointer-events: none;
}
.vp-wave > .vp-bars { right: 0; }              /* базовый слой = вся ширина волны */
.vp-bar {
  flex: 1 1 0; min-width: 2px; height: 40%;
  border-radius: 2px; background: var(--vp-dim);
  transition: background .1s linear;
}
.vp-fill {
  position: absolute; top: 0; bottom: 0; left: 0; width: 0%;
  overflow: hidden; pointer-events: none;
}
.vp-fill .vp-bars { width: var(--vp-w); }      /* фикс. ширина → пройденные бары точно над базовыми */
.vp-fill .vp-bar { background: var(--vp-lit); }
.vp-knob {
  position: absolute; top: 50%; left: 0; width: 11px; height: 11px;
  border-radius: 50%; background: var(--vp-lit);
  transform: translate(-50%, -50%); pointer-events: none;
  box-shadow: 0 1px 5px rgba(0,0,0,.4);
  opacity: 0; transition: opacity .15s ease;
}
.vp-wave:hover .vp-knob, .voice-msg.playing .vp-knob { opacity: 1; }

.vp-meta { display: flex; align-items: center; gap: 5px; min-height: 16px; }
.vp-time {
  font-size: 12px; font-variant-numeric: tabular-nums;
  color: var(--vp-lit); opacity: 1; line-height: 1;
}
.vp-meta svg.ic { width: 13px; height: 13px; color: var(--vp-lit); opacity: .55; }
/* ── чип скорости 1×/1.5×/2× — прогрессивное раскрытие: виден ТОЛЬКО у активного трека
   (пузырь, что сейчас слушают), чтобы не «отбирать экран» до старта воспроизведения. ── */
.vp-speed {
  display: none; flex: none; align-items: center; justify-content: center;
  margin-left: 4px; height: 16px; padding: 0 6px;
  border: none; border-radius: 8px; cursor: pointer;
  font-weight: 700; font-size: 10.5px; line-height: 1; font-variant-numeric: tabular-nums;
  letter-spacing: .01em; background: var(--vp-chip-bg); color: var(--vp-lit);
  transition: background .14s ease, transform .12s ease;
}
.voice-msg.vp-active .vp-speed { display: inline-flex; }
.vp-speed:hover { filter: brightness(1.12); }
.vp-speed:active { transform: scale(.9); }

/* ── #voiceMini — фоновый мини-плеер «сейчас слушаю» (над композером). Играет, не
   прерываясь при переходе в другой чат; аватар+имя, прогресс, плей/пауза, скорость,
   закрыть, тап → к сообщению. Тема (свет/тьма) — через токены. ─────────────────────── */
.vmini {
  /* 🔴 CLIE-356: плавающий «сейчас слушаю» ПОВЕРХ всего (как #mediaPip): z-index 9300 —
     выше страниц-оверлеев (Работа/Клиенты/Компании = 9000–9200) и модалок (9250), ниже
     звонка (10000). Живёт body-level (см. ensureVoiceMini), поэтому виден и в списке чатов
     на мобиле, и на любой полноэкранной странице. Десктоп: над композером у правого края. */
  position: fixed; z-index: 9300;
  right: 20px; bottom: 92px; left: auto; width: min(430px, calc(100vw - 40px));
  display: flex; align-items: center; gap: 10px;
  padding: 7px 9px 7px 7px;
  border-radius: 15px; background: var(--panel); border: 1px solid var(--line);
  box-shadow: 0 18px 46px -16px rgba(0,0,0,.62), 0 1px 0 rgba(255,255,255,.03) inset;
  -webkit-backdrop-filter: saturate(1.35) blur(12px); backdrop-filter: saturate(1.35) blur(12px);
  animation: vmini-in .19s cubic-bezier(.22,.61,.36,1);
  /* 🔴 CLIE-356 · плашку можно ТАСКАТЬ по экрану (как виджет записи экрана): курсор-хват,
     касание по ней не скроллит страницу, текст не выделяется при перетаскивании. */
  cursor: grab; touch-action: none; -webkit-user-select: none; user-select: none;
}
.vmini[hidden] { display: none; }
/* 🔴 CLIE-356 · перетащили → фиксируем через inline left/top/width (см. applyVminiPos), а
   right/bottom выключаем; во время драга — «хватаем» и гасим анимации/переходы для чёткости. */
.vmini.placed { right: auto; bottom: auto; left: auto; top: auto; }
.vmini.dragging {
  cursor: grabbing; animation: none; transition: none; will-change: left, top;
  box-shadow: 0 30px 64px -18px rgba(0,0,0,.72), 0 1px 0 rgba(255,255,255,.05) inset;
}
@keyframes vmini-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.vmini-play {
  flex: none; width: 34px; height: 34px; border-radius: 50%; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
  background: var(--acc-grad); color: #fff; box-shadow: 0 3px 10px -3px color-mix(in srgb, var(--primary) 65%, transparent);
  transition: transform .12s ease, filter .16s ease;
}
.vmini-play:hover { filter: brightness(1.05); }
.vmini-play:active { transform: scale(.92); }
.vmini-play svg.ic { width: 16px; height: 16px; }
.vmini-play:not(.playing) svg.ic { margin-left: 1px; }
.vmini-av { flex: none; width: 30px; height: 30px; border-radius: 50%; overflow: hidden; cursor: pointer; }
.vmini-av .conv-av { width: 100%; height: 100%; margin: 0; font-size: 12px; border-radius: 50%; }
.vmini-main { flex: 1 1 auto; min-width: 0; cursor: pointer; }
.vmini-top { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.vmini-name {
  font-size: 12.5px; font-weight: 600; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.vmini-time { flex: none; font-size: 11px; font-variant-numeric: tabular-nums; color: var(--muted); }
.vmini-track {
  position: relative; height: 4px; margin-top: 6px; border-radius: 2px;
  background: var(--line); cursor: pointer; touch-action: none;
}
.vmini-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0%; border-radius: 2px; background: var(--grad); }
.vmini-knob {
  position: absolute; top: 50%; left: 0; width: 10px; height: 10px; border-radius: 50%;
  background: #fff; border: 1px solid var(--line); transform: translate(-50%, -50%);
  box-shadow: 0 1px 3px rgba(0,0,0,.3); opacity: 0; transition: opacity .14s ease;
}
.vmini-track:hover .vmini-knob { opacity: 1; }
.vmini-speed {
  flex: none; height: 24px; padding: 0 9px; border: none; border-radius: 9px; cursor: pointer;
  font-weight: 700; font-size: 11.5px; line-height: 1; font-variant-numeric: tabular-nums;
  background: var(--panel-2); color: var(--text); transition: background .14s ease, transform .12s ease;
}
.vmini-speed:hover { background: var(--line); }
.vmini-speed:active { transform: scale(.92); }
.vmini-close {
  flex: none; width: 27px; height: 27px; border: none; border-radius: 9px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0;
  background: transparent; color: var(--muted); transition: background .14s ease, color .14s ease;
}
.vmini-close:hover { background: var(--hover); color: var(--text); }
.vmini-close svg.ic { width: 15px; height: 15px; }
/* 🔴🔴 CLIE-940·10 · ЗАГРУЗКА НЕ ГАСИТ ЕДИНСТВЕННЫЙ КОНТРОЛ.
   Было (CLIE-356): пульс прозрачности всей кнопки `opacity: 1 → .45`. На своём пузыре
   кнопка белая, а значок — акцентный индиго: на 45% оба сливаются с сиреневой заливкой,
   и человек видит бледный кружок без значка — ровно тот скрин, который прислал владелец
   09.09.2026 («контрастность не выполнена не видно»). Контраст решает РЕНДЕР в обеих
   темах (CLIE-888), поэтому состояние несёт КОЛЬЦО ВОКРУГ кнопки, а сама кнопка стоит в
   полном контрасте. Доля известна (Content-Length) — дуга заполнена ровно на неё; доля
   неизвестна или сеть тянет посреди игры — кольцо вращается. */
.vp-play, .vmini-play { position: relative; }
.voice-msg { --vp-ring-ink: #fff; --vp-ring-rail: rgba(255,255,255,.3); }
.msg.theirs .voice-msg {
  --vp-ring-ink: var(--primary-2);
  --vp-ring-rail: color-mix(in srgb, var(--primary-2) 26%, transparent);
}
.vmini { --vp-ring-ink: var(--primary); --vp-ring-rail: color-mix(in srgb, var(--primary) 26%, transparent); }
.voice-msg.vp-load .vp-play::after,
.voice-msg.vp-buffering .vp-play::after,
.vmini.vmini-buffering .vmini-play::after {
  /* Кольцо стоит С ЗАЗОРОМ от кнопки (inset −9px, полоса 3px): вплотную белая дуга на
     белом кружке своего пузыря читалась бы как «кнопка чуть толще», а не как состояние. */
  content: ""; position: absolute; inset: -9px; border-radius: 50%; pointer-events: none;
  background: conic-gradient(var(--vp-ring-ink) calc(var(--vp-load, .28) * 360deg), var(--vp-ring-rail) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
}
@keyframes vp-ring { to { transform: rotate(360deg); } }
.voice-msg.vp-load-x .vp-play::after,
.voice-msg.vp-buffering .vp-play::after,
.vmini.vmini-buffering .vmini-play::after { animation: vp-ring 1.1s linear infinite; }
@media (prefers-reduced-motion: reduce) {
  .voice-msg.vp-load-x .vp-play::after,
  .voice-msg.vp-buffering .vp-play::after,
  .vmini.vmini-buffering .vmini-play::after { animation: none; }
}

/* ---- видео-кружки ---- */
.circle-btn { padding: 9px 12px; font-size: 18px; flex: none; }
.circle-wrap { position: relative; width: 220px; height: 220px; cursor: pointer; }
.att-circle {
  width: 220px; height: 220px; border-radius: 50%;
  object-fit: cover; background: #000; display: block;
}
/* кольцо прогресса по краю кружка */
.circle-ring { position: absolute; inset: -3px; width: 226px; height: 226px; transform: rotate(-90deg); pointer-events: none; }
.circle-ring .ring-bg { fill: none; stroke: rgba(255,255,255,.18); stroke-width: 3; }
.circle-ring .ring-fg { fill: none; stroke: var(--primary-2); stroke-width: 3; stroke-linecap: round; transition: stroke-dashoffset .12s linear; }
/* большой ▶ когда на паузе; прячется во время проигрывания */
.circle-play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 46px; color: rgba(255,255,255,.92); pointer-events: none; text-shadow: 0 2px 10px rgba(0,0,0,.6);
}
.circle-wrap.playing .circle-play { display: none; }
/* видео-кружок УВЕЛИЧИВАЕТСЯ на время просмотра (как в Telegram). 🔴 Меняем РЕАЛЬНЫЙ
   размер (width/height), а НЕ transform:scale — scale выходил за пределы .messages
   (overflow-y:auto → overflow-x тоже клипует) и кружок обрезался сверху/снизу. При
   изменении размера в потоке .messages просто доскролливается, ничего не режется.
   Кольцо (inset:-3px) тянется за кружком; размер задаём и ему (симметрично +3px). */
.circle-wrap,
.circle-wrap .att-circle,
.circle-wrap .circle-ring {
  transition: width .22s cubic-bezier(.22,.61,.36,1), height .22s cubic-bezier(.22,.61,.36,1);
}
/* 🔴 CLIE-549: растём на просмотре СО ЗВУКОМ (`.soundon`), а не на любом `.playing` —
   немой автоплей по появлению в кадре не должен «дёргать» ленту размером. */
.circle-wrap.soundon,
.circle-wrap.soundon .att-circle { width: 300px; height: 300px; }
.circle-wrap.soundon .circle-ring { width: 306px; height: 306px; }
@media (max-width: 560px) {
  .circle-wrap.soundon,
  .circle-wrap.soundon .att-circle { width: 264px; height: 264px; }
  .circle-wrap.soundon .circle-ring { width: 270px; height: 270px; }
}

/* ⭕ CLIE-549 · ПРОСМОТР КРУЖКА «как у топов»: автоплей без звука по появлению в кадре,
   тап = звук с начала, перемотка тем же кольцом, скорость/фуллскрин/скачать/расшифровка.
   Правило «не отбирать экран»: в ПОКОЕ виден только кружок, длительность и (как у
   голосового) вход в расшифровку. Остальные действия проявляются, когда человек уже
   смотрит (наведение или воспроизведение). Кружок РАСТЁТ только на просмотре СО ЗВУКОМ
   (`.soundon`) — немой автоплей ленту не «дёргает».
   🔴 Кольцо — это и есть полоса прогресса: тянем мышью по нему (перемотка), поэтому
   в состоянии просмотра кольцо ловит события (см. .circle-wrap.playing .circle-ring). */
.circle-row { display: flex; align-items: flex-end; gap: 8px; }
.circle-side { display: flex; flex-direction: column; align-items: center; gap: 6px; padding-bottom: 4px; }
/* Кнопка-действие лежит НЕ в пузыре, а на самой канве ленты (медиа-пузырь прозрачный),
   поэтому материал у неё «карточный» (--panel + граница --line-strong + мягкая тень), а не
   инсетный --panel-2: на тёплой канве Концепта 6 инсет почти сливался с фоном и кнопка
   читалась как «просто иконка». */
.circle-side .cs-act {
  width: 30px; height: 30px; padding: 0; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; border: 1px solid var(--line-strong, var(--line)); background: var(--panel); color: var(--text);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .07);
  cursor: pointer; opacity: 0; pointer-events: none; transform: translateY(3px);
  transition: opacity .14s ease, transform .14s ease, background .14s ease, border-color .14s ease;
}
.circle-side .cs-act svg.ic { width: 15px; height: 15px; }
.circle-side .cs-act.vp-speed { width: auto; min-width: 34px; height: 30px; border-radius: 15px; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
/* 📱 CLIE-1175 · ПАЛЕЦ, А НЕ КУРСОР (жалоба владельца «элементы справа сильно близко к
   краю, сложно нажать»): 30px — мышиная цель. На тач-экране (телефон, планшет, тач-ноут)
   клетка столбика добирается до минимума 44px: плашка 40 + поле промаха ::after ±2. Ряд
   при этом остаётся уже пузыря: 264 (кружок ≤560px) + 8 + 44 = 316 при 92% ширины. */
@media (pointer: coarse) {
  .circle-side { gap: 10px; }
  .circle-side .cs-act { width: 40px; height: 40px; position: relative; }
  .circle-side .cs-act.vp-speed { min-width: 44px; height: 40px; border-radius: 20px; font-size: 13px; }
  .circle-side .cs-act svg.ic { width: 17px; height: 17px; }
  /* поле промаха: зона нажатия больше нарисованной плашки и НЕ двигает раскладку */
  .circle-side .cs-act::after { content: ""; position: absolute; inset: -2px; border-radius: 50%; }
}
.circle-side .cs-act:hover { background: var(--panel); }
.circle-side .cs-act:active { transform: scale(.94); }
/* Проявляем действия: наведение на ряд (десктоп) или человек СМОТРИТ этот кружок со
   звуком (`.soundon` — то же условие, что во Flutter `CircleFeed.watchingSeq`). 🔴 НЕ
   `.playing`: немой автоплей стартует сам, ничего не «начиналось» — вываливать под него
   столбик кнопок значит отбирать экран до действия человека. */
.circle-row:hover .circle-side .cs-act,
.circle-row:focus-within .circle-side .cs-act,
.circle-row:has(.circle-wrap.soundon) .circle-side .cs-act {
  opacity: 1; pointer-events: auto; transform: none;
}
/* вход в расшифровку — как у голосового: виден сразу (это не «лишний элемент», а фича).
   Материал тот же «карточный», что у соседних действий: они стоят в одном столбике, и
   разный материал в одном ряду — ровно то, за что правило единого контрола. */
.circle-side .vp-tr-ic {
  opacity: 1; pointer-events: auto; transform: none;
  /* 🔴 «Контрастность» 10.09.2026: кант КОНТРОЛА не хэйрлайн — у --line-strong контраст к
     поверхности ~1.4 ПО ЗАМЫСЛУ, и кнопку у кружка не было видно (замер прода 1.11:1).
     🔴 CLIE-1055·2: 42% давали 2.52:1 на белом пузыре при пороге WCAG 1.4.11 = 3:1 —
     заливка кнопки почти в цвет пузыря, весь контрол держится на канте. 55% = 3.6:1. */
  background: var(--panel); border-color: color-mix(in srgb, var(--text) 55%, transparent);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .07);
}
/* длительность на пузыре кружка (сервер считает duration_ms) → во время просмотра
   превращается в «прошло / всего», как таймер плеера */
.circle-dur {
  position: absolute; left: 50%; bottom: 8px; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 4px; max-width: 84%;
  /* 🔴 CLIE-1585 · ТОТ ЖЕ КЛАСС, ЧТО У .att-vid-meta: тёмное стекло поверх ЧУЖОГО КАДРА.
     Пока кадр не подъехал (спящий кружок, медленная сеть), под пилюлей светлая карточка, и
     .46 давала белым чернилам 3.74:1 (замер прода 28.09.2026). .62 — 6.8:1 в этом худшем
     случае и по-прежнему стекло на кадре. Тень кадром не является. */
  padding: 2px 8px; border-radius: 10px; background: rgba(0,0,0,.62);
  color: #fff; font-size: 11px; line-height: 16px; font-variant-numeric: tabular-nums;
  backdrop-filter: saturate(140%) blur(6px); -webkit-backdrop-filter: saturate(140%) blur(6px);
  pointer-events: none; white-space: nowrap;
}
.circle-dur:empty { display: none; }
/* CLIE-2019: вид «Сторис» (полоска сверху, ▶ слева внизу) живёт только в шаблоне «Глубина» — depth.css */
.circle-sx, .upl-circle-bar { display: none; }
.circle-dur svg.ic { width: 12px; height: 12px; }
/* немой автоплей: значок «звука нет» прямо в таймере — иначе человек думает, что
   кружок записан без звука, и не знает, что тап его включит */
.circle-dur .circle-mute { display: inline-flex; align-items: center; opacity: .9; }
/* перемотка кольцом: тянем по САМОЙ кромке кружка (внешние ~18% радиуса). Слушатель —
   на `.circle-wrap` с проверкой радиуса, а НЕ pointer-events на <svg>: svg-бокс накрывает
   весь квадрат и «съел» бы тап по видео. Пока тянем — кольцо без сглаживания (идёт за курсором). */
.circle-wrap.seeking { cursor: ew-resize; }
.circle-wrap.seeking .circle-ring .ring-fg { transition: none; }

/* ── Плавающее мини-видео (PiP): остаётся на фоне при переходе на другую страницу ──
   Живёт поверх всего (как свёрнутый звонок). Перетаскивается, ✕ закрывает,
   тап по кадру — вернуться в исходный чат.
   🔴 z-index ВЫШЕ полноэкранных оверлеев-«страниц» (Работа/Клиенты/Спец-ты/Компании
   = 9000–9200), иначе при открытии такой страницы PiP прятался бы ЗА ней. */
#mediaPip {
  position: fixed; z-index: 9300; right: 20px; bottom: 92px;
  display: none; cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
}
#mediaPip.placed { right: auto; bottom: auto; }
#mediaPip .pip-media { display: block; }
#mediaPip .pip-video {
  display: block; width: 210px; height: auto; max-height: 300px;
  border-radius: 14px; background: #000; box-shadow: 0 10px 34px rgba(0,0,0,.5);
}
#mediaPip.circle .pip-video {
  width: 176px; height: 176px; border-radius: 50%; object-fit: cover;
  box-shadow: 0 10px 30px rgba(0,0,0,.55);
}
#mediaPip .pip-close {
  position: absolute; top: -8px; right: -8px; width: 26px; height: 26px; border-radius: 50%;
  border: none; cursor: pointer; color: #fff; background: var(--cm-14161e-92, rgba(20,22,30,.92));
  font-size: 14px; line-height: 1; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 8px rgba(0,0,0,.5); z-index: 2;
}
#mediaPip .pip-close:hover { background: #ef4444; }
.circle-overlay {
  position: fixed; inset: 0; z-index: 55;
  background: rgba(8,10,14,.92);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.circle-rec-box { display: flex; flex-direction: column; align-items: center; gap: 14px; }
/* Сцена кружка = сам кадр + кольцо снаружи + хваталка смены камеры на кромке.
   Размер задаём ЗДЕСЬ один раз (переменная), кадр и кольцо считают от неё. */
.circle-stage {
  --csz: min(480px, 88vw, 56vh);
  position: relative; width: var(--csz); height: var(--csz);
}
.circle-preview {
  /* Кружок РЕЗИНОВЫЙ, а не прибитые 280px: во всю ширину минус поля, но не выше
     свободной высоты (под таймером и кнопками остаётся ~140px). Владелец просил
     «больше кружок, когда снимаем, чтобы больше видеть» — CLIE-546. */
  position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 50%;
  object-fit: cover; background: #000;
  box-shadow: 0 24px 64px rgba(0,0,0,.45), inset 0 0 0 1px rgba(255,255,255,.10);
  transform: scaleX(-1);  /* зеркалим превью как селфи (запись не зеркалится) */
}
.circle-preview.no-mirror { transform: none; }   /* тыловая камера — зеркалить нечего */
/* 🔴 CLIE-2019: зеркало предпросмотра записи даёт `.circle-preview` выше (с `.no-mirror` для тыла).
   Отдельное `.circle-play { scaleX(-1) }` цепляло и ▶ на кружке в ленте — треугольник смотрел влево. */
/* Кольцо лимита 60 с (и позиции воспроизведения в предпросмотре) — СНАРУЖИ кадра,
   поэтому svg на 9px больше сцены с каждой стороны. r=49 при stroke 2.2 кладёт
   дорожку ровно в этот зазор и не режет кадр. */
.circle-ring {
  position: absolute; inset: -9px; width: calc(100% + 18px); height: calc(100% + 18px);
  transform: rotate(-90deg); pointer-events: none;
}
/* 🔴 stroke-width задан в единицах viewBox и МАСШТАБИРУЕТСЯ вместе с кружком: 2.2 из
   сотни на 480px давало жирный «обруч» 11px. `non-scaling-stroke` держит толщину в
   экранных пикселях — тонкий хэйрлайн одинаков и на мобиле, и на десктопе. */
.circle-ring .cr-track,
.circle-ring .cr-bar { vector-effect: non-scaling-stroke; }
.circle-ring .cr-track { fill: none; stroke: rgba(255,255,255,.15); stroke-width: 3; }
.circle-ring .cr-bar {
  fill: none; stroke: var(--primary); stroke-width: 3; stroke-linecap: round;
  transition: stroke .16s ease;
}
.circle-overlay[data-st="pause"] .cr-bar { stroke: #f5a623; }
.circle-overlay.cancel .cr-bar,
.circle-overlay.cancel .rec-dot { stroke: var(--danger); background: var(--danger); }
/* Хваталка смены камеры сидит на кромке круга (45°): 14.64% = 1−cos45°, как в апке. */
.circle-knob {
  position: absolute; right: calc(14.64% - 21px); bottom: calc(14.64% - 21px);
  width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; cursor: pointer; color: #fff; border: 1px solid rgba(255,255,255,.22);
  background: var(--cm-12141a-62, rgba(18,20,26,.62)); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  box-shadow: 0 6px 18px rgba(0,0,0,.38); transition: background .14s ease, transform .14s ease;
}
.circle-knob:hover { background: var(--cm-262a34-82, rgba(38,42,52,.82)); transform: scale(1.06); }
.circle-knob .ic { width: 20px; height: 20px; }
.circle-hint {
  min-height: 18px; font-size: 13px; line-height: 18px; color: rgba(255,255,255,.62);
  text-align: center; letter-spacing: .01em; transition: color .14s ease;
}
.circle-overlay.cancel .circle-hint { color: #ffb4b4; }
.circle-lock { width: 15px; height: 15px; color: rgba(255,255,255,.8); }
.circle-rec-info { display: flex; align-items: center; gap: 8px; font-weight: 600; font-variant-numeric: tabular-nums; }
/* Кнопки по состоянию — одна разметка, показывает CSS (второго оверлея не заводим). */
.circle-overlay[data-st="idle"] #circlePause,
.circle-overlay[data-st="idle"] #circleStop,
.circle-overlay[data-st="idle"] #circleSend,
.circle-overlay[data-st="idle"] #circleRetake,
.circle-overlay[data-st="rec"] #circleStart,
.circle-overlay[data-st="rec"] #circleSend,
.circle-overlay[data-st="rec"] #circleRetake,
.circle-overlay[data-st="pause"] #circleStart,
.circle-overlay[data-st="pause"] #circleSend,
.circle-overlay[data-st="pause"] #circleRetake,
.circle-overlay[data-st="prev"] #circleStart,
.circle-overlay[data-st="prev"] #circleStop,
.circle-overlay[data-st="prev"] #circlePause,
.circle-overlay[data-st="prev"] #circleCancel { display: none; }
/* Пока кнопку ДЕРЖАТ — нажать нечего (палец на кнопке режима): прячем весь ряд,
   на экране только кольцо, таймер и подсказка жестов. Замок ряд возвращает. */
.circle-overlay.held .circle-rec-controls { display: none; }
.circle-overlay.held #circleFlip { display: none; }
.circle-rec-controls { display: flex; gap: 14px; align-items: center; }
/* Подложка обоих рекордеров всегда ТЁМНАЯ, а `.ghost` и таймер берут `--text` темы →
   в светлой теме «Отмена» и «0:04» были тёмными на тёмном и почти не читались.
   Фиксируем светлую пару. */
.circle-overlay .circle-rec-info,
.media-rec-overlay .circle-rec-info { color: #fff; }
.circle-overlay .circle-rec-controls .ghost,
.media-rec-overlay .circle-rec-controls .ghost {
  color: rgba(255,255,255,.78); border-color: rgba(255,255,255,.22);
}
.circle-overlay .circle-rec-controls .ghost:hover,
.media-rec-overlay .circle-rec-controls .ghost:hover {
  color: #fff; border-color: rgba(255,255,255,.44); background: rgba(255,255,255,.10);
}
.circle-rec-controls .primary { width: auto; margin: 0; }
/* Кнопка = подпись + глиф в ОДНУ строку: без этого «Отправить ✈» переносило иконку
   на вторую строку и ряд «прыгал» по высоте при смене состояния. */
.circle-rec-controls .primary,
.circle-rec-controls .ghost {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; white-space: nowrap;
}

/* запись видео с камеры / экрана (прямоугольный оверлей, тот же язык, что у кружка) */
.media-rec-overlay {
  position: fixed; inset: 0; z-index: 55;
  background: rgba(8,10,14,.92);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
.media-rec-box { display: flex; flex-direction: column; align-items: center; gap: 18px; max-width: 100%; }
.media-rec-preview {
  width: min(560px, 92vw); max-height: 62vh; aspect-ratio: 16 / 9;
  border-radius: 14px; object-fit: contain; background: #000; border: 2px solid var(--primary);
}
.media-rec-preview.mirror { transform: scaleX(-1); }  /* селфи-камеру зеркалим, экран — нет */

/* тумблер «со звуком / без звука» записи (виден только в превью, до старта) */
.media-rec-sound {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px; border-radius: 999px; cursor: pointer;
  font-size: 14px; font-weight: 600; line-height: 1;
  border: 1.5px solid var(--primary);
  background: color-mix(in srgb, var(--primary) 16%, transparent);
  color: #fff;
}
.media-rec-sound .ic { width: 18px; height: 18px; }
.media-rec-sound[aria-pressed="false"] {
  border-color: rgba(255,255,255,.35);
  background: rgba(255,255,255,.06);
  color: rgba(255,255,255,.72);
}
.media-rec-sound.hidden { display: none; }

/* Подсказка «экран записывается чёрным» — браузеру не выдан системный доступ к записи
   экрана (macOS). Оверлей всегда тёмный, поэтому карточка — янтарная на тёмном. */
.media-rec-blackhint {
  display: flex; gap: 12px; align-items: flex-start; text-align: left;
  width: min(560px, 92vw); box-sizing: border-box;
  padding: 14px 16px; border-radius: 14px;
  background: rgba(231,163,62,.12); border: 1px solid rgba(231,163,62,.55);
  color: #fff; animation: mrbhIn .18s ease;
}
.media-rec-blackhint.hidden { display: none; }
.media-rec-blackhint .ic { width: 22px; height: 22px; color: #E7A33E; flex: 0 0 auto; margin-top: 1px; }
.media-rec-blackhint .mrbh-title { font-size: 14px; font-weight: 700; margin-bottom: 3px; }
.media-rec-blackhint .mrbh-desc { font-size: 12.5px; line-height: 1.45; color: rgba(255,255,255,.82); }
.media-rec-blackhint .mrbh-desc b { color: #fff; font-weight: 600; }
@keyframes mrbhIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* Во время записи оверлей сворачивается в компактную плавающую «пилюлю»:
   большое превью убирается, тёмная подложка снимается, клики проходят СКВОЗЬ
   к приложению под пилюлей. Иначе фуллскрин-оверлей снимал бы сам себя, а не
   записываемое веб-приложение (и свернуть его было нельзя). Пилюлю можно таскать. */
.media-rec-overlay.mini {
  inset: auto 0 0 0;                                   /* прижать к низу экрана */
  z-index: 9400;                                       /* HUD выше модалок (9250), ниже звонка (>10000) */
  align-items: flex-end;
  padding: 0 12px max(16px, env(safe-area-inset-bottom));
  background: transparent;
  pointer-events: none;                                /* сквозь оверлей — к записываемому приложению */
}
.media-rec-overlay.mini .media-rec-preview,
.media-rec-overlay.mini .media-rec-sound { display: none; }
.media-rec-overlay.mini .media-rec-box {
  flex-direction: row; align-items: center; gap: 12px;
  padding: 9px 10px 9px 16px;
  max-width: calc(100vw - 24px);
  border-radius: 999px;
  background: var(--panel-3, var(--cm-232732, #232732));
  border: 1px solid var(--line);
  box-shadow: 0 16px 40px rgba(0,0,0,.45), 0 1px 0 rgba(255,255,255,.05) inset;
  color: var(--text);
  pointer-events: auto;                                /* сама пилюля кликабельна/таскается */
  cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
  animation: recPillIn .18s cubic-bezier(.22,.61,.36,1);
}
.media-rec-overlay.mini .media-rec-box.dragging { cursor: grabbing; }
@keyframes recPillIn { from { opacity: 0; } to { opacity: 1; } }
.media-rec-overlay.mini .circle-rec-info { font-size: 15px; }
.media-rec-overlay.mini .circle-rec-controls { gap: 8px; }
.media-rec-overlay.mini .circle-rec-controls .primary,
.media-rec-overlay.mini .circle-rec-controls .ghost {
  width: auto; margin: 0; padding: 8px 15px; font-size: 14px; border-radius: 999px;
}

/* ---- группы ---- */
.modal-body { padding: 14px 16px; overflow-y: auto; flex: 1; }
.modal-foot { padding: 12px 16px; border-top: 1px solid var(--line); }
.modal-foot .primary { width: 100%; margin: 0; }
.group-users { padding: 4px 0; }
.group-user label { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 8px; cursor: pointer; }
.group-user label:hover { background: var(--panel-2); }
.group-user input { width: auto; }
.sender-name { font-size: 11px; color: var(--primary-2); font-weight: 600; margin: 0 4px 2px; }
/* CLIE-401: продолжение серии одного автора (подпись свёрнута) — пузырь прижат к
   предыдущему (.messages gap 8px → 4px), серия читается одним блоком, как в iMessage. */
.msg.run-cont { margin-top: -4px; }
/* 0151: подпись «ИИ» с иконкой-искрами — акцентная, компактная (иконка + текст в ряд). */
.sender-name.ai-name { display: inline-flex; align-items: center; gap: 4px; color: var(--accent); }
.sender-name.ai-name svg { width: 13px; height: 13px; }
/* 🪝 Подпись сообщения входящего вебхука («бот»): имя из metadata.bot_name + иконка + чип «бот». */
.sender-name.bot-name { display: inline-flex; align-items: center; gap: 4px; color: var(--text-dim, #9aa4b2); }
.sender-name.bot-name svg { width: 13px; height: 13px; opacity: .85; }
.sender-name.bot-name .bot-badge { font-size: 9.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--line); border-radius: 5px; padding: 0 4px; line-height: 1.5; }
/* 🤖 CLIE-917: подпись бота, у которого ЕСТЬ своё правило (metadata.workflow_id), — это ВХОД
   в этот автоответ. Пунктир на наведении: «сюда можно нажать», но подпись сообщения не должна
   выглядеть кнопкой в спокойном состоянии. */
.sender-name.bot-name.bot-wf { cursor: pointer; }
.sender-name.bot-name.bot-wf:hover span:not(.bot-badge) { text-decoration: underline dotted; text-underline-offset: 2px; }
.sender-name.bot-name.bot-wf:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 6px; }

/* 🔴 CLIE-917·3 «ОТ КОГО ИДЁТ АВТООТВЕТ». У ответа появился ГОЛОС: бот со своим именем, лицо
   беседы (аватар + название) или конкретный человек. Голос МЕНЯЕТ имя и лицо — значит рядом
   обязана стоять пометка, что говорил автомат: выбор голоса не имеет права превращать продукт
   в генератор подделок. Пометка — тот же чип `.bot-badge`, тот же вход по клику (`.bot-wf`). */
.sender-name .bot-face { width: 14px; height: 14px; border-radius: 4px; object-fit: cover; flex: 0 0 auto; }
.sender-name.bot-wf { cursor: pointer; }
.sender-name .bot-badge { font-size: 9.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--line); border-radius: 5px; padding: 0 4px; line-height: 1.5; margin-left: 4px; }
/* Свой автоответ рисуется обычным «моим» пузырём — пометка живёт в мета-строке рядом с
   временем и галочками (там же, где остальные знаки о судьбе сообщения). */
.msg .meta .msg-auto-mark { font-size: 9.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--line); border-radius: 5px; padding: 0 4px; line-height: 1.5; }
.msg .meta .msg-auto-mark.bot-wf { cursor: pointer; }
.msg .meta .msg-auto-mark.bot-wf:hover { color: var(--text); }

/* 🔴🔴 CLIE-807: АВАТАР АВТОРА В ЛЕНТЕ (беседа, где авторов больше одного).
   Кружок стоит СЛЕВА от пузыря, у ПОСЛЕДНЕГО сообщения серии, и его низ = низ пузыря
   (CLIE-2015, владелец: «везде в других мессенджерах снизу» — Telegram/iMessage); имя
   остаётся на первом. Продолжения серии несут ТОТ ЖЕ отступ (класс has-av), поэтому
   пузыри серии стоят ровно, а не ступенькой.
   🔴 Как прижат к низу: `.msg-av` — поток-нулёвка СРАЗУ ПОСЛЕ `.bubble` (0×0, flex:none),
   его верх = низ пузыря; сам кружок `.conv-av` висит на нём абсолютно (`bottom:0`,
   `left:-отступ`). Низ `.msg` для этого не годится: под пузырём ещё перевод, кнопки,
   реакции и время. Раскладка `.msg` (flex-column, shrink-to-fit) не меняется ни на
   пиксель, значит альбомы, медиа и `.msg:has(.album-grid){width:…}` остаются как были,
   а догрузка картинки двигает кружок вместе с низом пузыря без пересчёта. box-sizing
   ЯВНЫЙ: в продукте нет глобального border-box, а без него отступ прибавился бы К
   max-width, и пузырь в группе стал бы ШИРЕ, чем в личке. */
.msg.theirs.has-av { box-sizing: border-box; padding-left: 40px; }
.msg-av { position: relative; flex: none; align-self: flex-start; width: 0; height: 0; }
.msg-av > .conv-av { position: absolute; left: -40px; bottom: 0; }
.msg-av .conv-av { width: 32px; height: 32px; font-size: 12.5px; box-shadow: none; }
.msg-av.prof-hit { cursor: pointer; }
.msg-av.prof-hit:hover .conv-av { filter: brightness(1.06); }
.msg-av .conv-av svg { width: 16px; height: 16px; }
.msg-av .conv-av.msg-av-ai { background: var(--acc-fill, var(--cm-6c7bff, #6c7bff)); color: #fff; }
.msg-av .conv-av.msg-av-bot { background: var(--panel-2, #2a2f3a); color: var(--text-dim, #9aa4b2); border: 1px solid var(--line); }
/* Узкий экран: кружок меньше, отступ короче — на 360px 40px из ширины пузыря дорого. */
@media (max-width: 520px) {
  .msg.theirs.has-av { padding-left: 34px; }
  .msg-av > .conv-av { left: -34px; }
  .msg-av .conv-av { width: 28px; height: 28px; }
  .msg-av .conv-av { font-size: 11.5px; }
}

/* ═══════════ ГРУППОВОЙ ВИДЕО-СОЗВОН — десктоп-редизайн ═══════════
   Сетка масштабируется JS (relayoutGroupGrid): под N участников выбирается
   оптимальная раскладка cols×rows (макс. площадь тайла при 16:9), а размер тайла
   задаётся --gt-w/--gt-h; flex-центрирование раскладывает и центрирует ряды в
   .gc-stage. Плитки НЕ пересоздаются при ресайзе (живут <video>). */
.groupcall-overlay {
  position: fixed; inset: 0; z-index: 56; display: flex; flex-direction: column; color: #fff;
  background:
    radial-gradient(120% 80% at 50% -10%, color-mix(in srgb, var(--primary) 10%, transparent), transparent 55%),
    radial-gradient(90% 70% at 100% 108%, color-mix(in srgb, var(--primary) 12%, transparent), transparent 60%),
    var(--cm-0b0d12, #0b0d12);
  --gc-hair: rgba(255,255,255,.08); --gc-hair-2: rgba(255,255,255,.14);
  --gc-tile: var(--cm-171a22, #171a22); --gc-tile-off: var(--cm-14161f, #14161f);
  --gc-dock: var(--cm-161921-72, rgba(22,25,33,.72)); --gc-btn: rgba(255,255,255,.06); --gc-btn-h: rgba(255,255,255,.13);
}
/* ── шапка: тонкий двухколоночный бар ── */
.groupcall-head { flex: 0 0 auto; display: flex; align-items: center; gap: 14px; padding: calc(env(safe-area-inset-top) + 14px) 22px 8px; color: #fff; min-width: 0; }
.gc-head-main { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.groupcall-title { font-weight: 650; font-size: 15.5px; letter-spacing: .1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* оверлей всегда тёмный → фиксированный светлый slate (не var(--muted), он темнеет в светлой теме) */
.gc-head-sub { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: #9aa3b4; }
.gc-elapsed { font-variant-numeric: tabular-nums; color: var(--cm-c7ccd8, #c7ccd8); letter-spacing: .3px; }
.gc-elapsed:empty { display: none; }
.gc-head-dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .55; flex: 0 0 auto; }
.gc-elapsed:empty + .gc-head-dot { display: none; }
.gc-head-count { white-space: nowrap; }
.gc-head-right { margin-left: auto; display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
/* «идёт запись» — пилюля (заменяет старый инлайн «● REC») */
.gc-rec-dot { display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px; border-radius: 9px; font-size: 12px; font-weight: 600; color: #ffd6d6; background: rgba(239,68,68,.13); border: 1px solid rgba(239,68,68,.30); }
.gc-rec-blob { width: 8px; height: 8px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 0 rgba(239,68,68,.6); animation: gcRecPulse 2s infinite; }
.gc-rec-time { font-variant-numeric: tabular-nums; letter-spacing: .3px; }
@keyframes gcRecPulse { 0%{box-shadow:0 0 0 0 rgba(239,68,68,.5)} 70%{box-shadow:0 0 0 6px rgba(239,68,68,0)} 100%{box-shadow:0 0 0 0 rgba(239,68,68,0)} }

/* 🧠 M11.2 — пилюля «ИИ-двойник слушает». Сознательно ТИШЕ, чем «Запись»: запись
   про необратимое, а двойник — про помощь. Тот же силуэт (30px, хэйрлайн, точка-пульс),
   но холодный сине-фиолетовый, а не тревожный красный. Оверлей созвона ТЁМНЫЙ всегда,
   поэтому цвета заданы явно и в светлой теме не «белеют». Клик — выключить. */
.gc-agent-pill {
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px;
  border-radius: 9px; font-size: 12px; font-weight: 600; letter-spacing: .1px;
  color: var(--cm-d8dcff, #d8dcff); background: color-mix(in srgb, var(--primary) 14%, transparent); border: 1px solid var(--cm-8c9eff-3, rgba(140,158,255,.30));
  cursor: pointer; transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
  font-family: inherit;
}
.gc-agent-pill:hover { background: color-mix(in srgb, var(--primary) 22%, transparent); border-color: var(--cm-8c9eff-46, rgba(140,158,255,.46)); color: var(--cm-eceeff, #eceeff); }
.gc-agent-pill:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--cm-8c9eff-7, rgba(140,158,255,.7)); }
.gc-agent-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--cm-8c9eff, #8c9eff); flex: none;
  box-shadow: 0 0 0 0 var(--cm-8c9eff-6, rgba(140,158,255,.6)); animation: gcAgentPulse 2.6s infinite;
}
/* «Думает» — пульс заметно живее: человек должен видеть, что ИИ сейчас работает,
   а не гадать, завис он или молчит по делу. */
.gc-agent-pill.thinking .gc-agent-dot { animation-duration: 1s; }
@keyframes gcAgentPulse {
  0%   { box-shadow: 0 0 0 0 var(--cm-8c9eff-55, rgba(140,158,255,.55)); }
  70%  { box-shadow: 0 0 0 6px var(--cm-8c9eff-0, rgba(140,158,255,0)); }
  100% { box-shadow: 0 0 0 0 var(--cm-8c9eff-0, rgba(140,158,255,0)); }
}
/* 🎙 Пилюля режима записи задач — та же рама, что у пилюли согласия (второго вида пилюли в
   комнате не заводим). Режим «всё в одну» несёт СЛОВО в подписи, подложка лишь чуть плотнее:
   акцент словом читается и в ч/б (правило акцента, CLIE-483). */
.gc-agent-task.single,
.gc-agent-notes.on,
.gc-prop-pill.on {
  color: var(--cm-eceeff, #eceeff); background: color-mix(in srgb, var(--primary) 26%, transparent); border-color: var(--cm-8c9eff-48, rgba(140, 158, 255, .48));
}
/* 🗒 «Конспект: вкл/выкл» и ☑️ «Ая предлагает 3 задачи · Выбрать» — та же рама пилюли двойника
   (второго вида пилюли в комнате не заводим). Состояние несёт СЛОВО в подписи, подложка лишь
   плотнее. Слово действия («Выбрать» / «Свернуть», как у полосы приложения) отделено точкой,
   а не чертой-рейкой: оно часть той же подписи, а не вторая кнопка. */
.gc-prop-pill #gcPropPillText { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.gc-prop-pill #gcPropPillText .ic { width: 14px; height: 14px; flex: none; opacity: .9; }
.gc-prop-pill #gcPropPillText span { font-variant-numeric: tabular-nums; }
.gc-prop-pill #gcPropPillText .gc-prop-act { color: var(--cm-eceeff, #eceeff); }
.gc-prop-pill #gcPropPillText .gc-prop-act::before { content: "·"; margin-right: 6px; color: var(--cm-d8dcff, #d8dcff); }
/* Новое предложение, пока шторка закрыта, — два мягких импульса кольцом, без мигания
   заливкой: заметно боковым зрением, но не дёргает, как всплывашка поверх видео. */
.gc-prop-pill.fresh { animation: gcPropFresh 1.3s ease-out 2; }
@keyframes gcPropFresh {
  0%   { box-shadow: 0 0 0 0 var(--cm-8c9eff-55, rgba(140,158,255,.55)); }
  70%  { box-shadow: 0 0 0 8px var(--cm-8c9eff-0, rgba(140,158,255,0)); }
  100% { box-shadow: 0 0 0 0 var(--cm-8c9eff-0, rgba(140,158,255,0)); }
}
@media (prefers-reduced-motion: reduce) { .gc-prop-pill.fresh { animation: none; } }
/* В эфире (вебинар) предложений нет: там свой интерфейс ведущего/зрителя. */
.groupcall-overlay.stream-mode #gcPropPill { display: none !important; }
/* Пилюлям двойника тесно в одной строке с названием встречи (узкий экран, открытая шторка) —
   шапка переносит их вторым рядом, а не выталкивает за край и не прячет под шторку. Пока всё
   помещается, ряд один: перенос включается только нехваткой места. Подпись пилюли — одной
   строкой с многоточием (двухстрочный текст в пилюле 30px вылезал за её рамку). */
.groupcall-overlay:not(.minimized) .groupcall-head { flex-wrap: wrap; row-gap: 8px; }
.groupcall-overlay:not(.minimized) .gc-head-right { flex: 0 1 auto; max-width: 100%; min-width: 0; flex-wrap: wrap; justify-content: flex-end; row-gap: 6px; }
.gc-agent-pill { white-space: nowrap; max-width: 100%; min-width: 0; }
#gcAgentPillText { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 560px) { .groupcall-overlay:not(.minimized) .gc-head-right { gap: 6px; } }
/* Открытая шторка справа (предложения · чат · интерактив) начинается от самого верха — шапка
   отступает на её ширину, иначе пилюли, включая ту, что открыла шторку, уходили ПОД неё.
   🔴 `:not(.minimized)` у КАЖДОГО селектора (ревью 01.10.2026): «Свернуть» классы шторок не
   снимает, а правило идёт позже `.groupcall-overlay.minimized .groupcall-head` и перебивало его —
   в окне 176px отступ 382px схлопывал название встречи до нуля. */
@media (min-width: 561px) {
  .groupcall-overlay.gc-prop-open:not(.minimized) .groupcall-head,
  .groupcall-overlay.gc-chat-open:not(.minimized) .groupcall-head,
  .groupcall-overlay.gcx-panel-open:not(.minimized) .groupcall-head { padding-right: calc(min(360px, 94vw) + 22px); transition: padding-right .16s ease; }
}

/* ☑️ ШТОРКА «Ая предлагает задачи» — рама чата конференции (.gc-chat), здесь только тело.
   Оверлей созвона тёмный ВСЕГДА → тёмная шкала токенов ЛОКАЛЬНО (тот же приём, что у
   .gcx-panel в ccroom.css): список предложений — ОДИН компонент с разбором встречи
   (`mpropListHtml`, токены темы), и второй «звонковой» вёрстки ему не нужно. */
.gc-prop {
  --bg: #0f1115; --panel: var(--cm-171a21, #171a21); --panel-2: #1e222b; --panel-3: #262b36;
  --line: #2a2f3a; --line-strong: #3a4150; --border: #2a2f3a;
  --text: #e6e9ef; --muted: #8b93a3; --text-dim: #9aa4b2;
  --primary: var(--cm-667eea, #667eea); --primary-2: var(--cm-8b9cf5, #8b9cf5); --accent: var(--cm-8b9cf5, #8b9cf5);
  --acc-fill: var(--primary); --acc-fill-hi: var(--primary); /* своя шкала: заливка под белым — своя */
  --hover: rgba(230,233,239,.06); --sel: var(--cm-667eea-16, rgba(102,126,234,.16));
  --danger: #ef4444; --danger-soft: rgba(239,68,68,.14);
  color: var(--text); color-scheme: dark;
}
.gc-prop-body { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; padding: 12px 12px 14px; gap: 10px; }
.gc-prop .mprop-lead { font-size: 12.5px; line-height: 1.45; color: var(--muted); padding: 0 4px; }
.gc-prop .mprop-list { flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; margin: 0 -4px; padding: 0 4px; }
.gc-prop .mprop-list::-webkit-scrollbar { width: 8px; }
.gc-prop .mprop-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); border-radius: 999px; }
/* Действие шторки — внизу во всю ширину, как у листа iOS: одна главная кнопка, её видно всегда. */
.gc-prop .mprop-foot { margin-top: auto; padding-top: 10px; border-top: 1px solid var(--line); }
.gc-prop .mprop-go { width: 100%; height: 40px; font-size: 13.5px; border-radius: 12px; }
/* Компактный подвал шторки: «Выбрать уверенные» — тихая строка над главной кнопкой, справа. */
.gc-prop .mprop-foot.is-compact { justify-content: flex-end; row-gap: 6px; }
.gc-prop .mprop-foot.is-compact .mprop-conf { order: -1; }

/* Тумблер в доке во включённом состоянии — та же холодная гамма, что у пилюли. */
.gc-dock .ghost#gcAgentBtn.active,
#gcAgentBtn.active {
  color: var(--cm-cfd6ff, #cfd6ff); background: color-mix(in srgb, var(--primary) 20%, transparent); border-color: var(--cm-8c9eff-36, rgba(140,158,255,.36));
}
@media (prefers-reduced-motion: reduce) { .gc-agent-dot { animation: none; } }

/* ── сцена: центрирует масштабируемую сетку ── */
.gc-stage { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 10px 22px 6px; }
/* 🔴 САМА ПЛИТКА СОЗВОНА ЖИВЁТ НЕ ЗДЕСЬ, а в `callui.css` (пара к `callui.js`) — CLIE-606.
   Туда переехали `.group-grid`, `.gtile`, `.gt-avatar`, `.gname`, `.gt-mic`, `.gt-eq`,
   `.gt-cq`, `.gt-collapse`, `.cc-wm`, спотлайт и зеркало своей камеры: этот файл грузит
   только приложение, а участника созвона рисуют ТРИ поверхности — конференция беседы,
   созвон игровой комнаты и гостевая страница (у неё своего style.css нет вовсе).
   Ниже остаётся только то, что специфично ДЛЯ ЭТОГО оверлея. Правишь вид плитки —
   правишь `callui.css`, а не дописываешь сюда четвёртую копию. */
/* ── 🔊 M11.1 · плитка ИИ-бота: «говорящая голова» ─────────────────────────────
   Плитка — ТА ЖЕ .gtile (раскладка/спотлайт/пин работают без правок); отличается
   только «лицо»: вместо круга с инициалами — живой орб (canvas, общий рисовальщик с
   голосовым ассистентом) и подпись реплики. Фон плитки чуть глубже и с холодным
   свечением, чтобы участник ЧИТАЛСЯ как не-человек с первого взгляда. */
.gtile.gtile-ai { background: radial-gradient(120% 100% at 50% 8%, var(--cm-1b2036, #1b2036) 0%, var(--cm-12141d, #12141d) 62%, var(--cm-0f1119, #0f1119) 100%); }
.gtile.gtile-ai .gt-avatar {
  width: clamp(74px, 20vh, 168px); background: none !important; box-shadow: none;
}
.gt-orb { width: 100%; height: 100%; display: block; border-radius: 50%; }
/* Подпись: что бот сейчас делает или что сказал. Появляется только когда есть текст —
   пустая плитка не должна нести пустую плашку. */
.gt-ai-cap {
  position: absolute; left: 8px; right: 8px; bottom: 34px; z-index: 3;
  margin: 0 auto; max-width: 92%; width: max-content;
  padding: 5px 10px; border-radius: 9px;
  font-size: 11.5px; line-height: 1.35; text-align: center; color: rgba(255,255,255,.92);
  background: var(--cm-090b10-56, rgba(9,11,16,.56)); border: 1px solid rgba(255,255,255,.08);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  opacity: 0; transform: translateY(4px); transition: opacity .16s ease, transform .16s ease;
  pointer-events: none;
}
.gt-ai-cap.show { opacity: 1; transform: none; }

/* Строка вопроса над доком. Ровно одна строка: ответ бот говорит вслух, ленты тут нет. */
.gc-ai-ask {
  flex: 0 0 auto; align-self: center; width: min(560px, calc(100vw - 32px));
  display: flex; align-items: center; gap: 8px; margin: 0 auto -2px;
  padding: 7px 8px 7px 12px;
  background: var(--gc-dock); border: 1px solid var(--gc-hair-2); border-radius: 16px;
  -webkit-backdrop-filter: blur(24px) saturate(1.3); backdrop-filter: blur(24px) saturate(1.3);
  box-shadow: 0 20px 48px -20px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05);
  animation: gcAiRise .16s ease-out both;
}
@keyframes gcAiRise { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
/* 🔴 Оверлей созвона ВСЕГДА тёмный (свои переменные --gc-*), а глобальный `input`
   в СВЕТЛОЙ теме даёт светлый фон и тёмный текст — поле стало бы белым прямоугольником
   с невидимым плейсхолдером прямо поверх стекла. Поэтому здесь фон/рамку/фокус
   глушим явно, а не полагаемся на каскад. */
.groupcall-overlay .gc-ai-input,
.gc-ai-input {
  flex: 1 1 auto; min-width: 0; height: 34px; padding: 0 4px;
  background: transparent; border: 0; outline: none; box-shadow: none;
  color: #fff; font-size: 14px; border-radius: 0;
}
.gc-ai-input:focus { outline: none; border: 0; box-shadow: none; background: transparent; }
.gc-ai-input::placeholder { color: rgba(255,255,255,.45); }
/* 🔴 Оверлей созвона тёмный ВСЕГДА, тема страницы на него не влияет. Поле делаем
   ЯВНО непрозрачным «утопленным» (как композер iMessage): иначе в светлой теме под
   стекло просвечивала системная отрисовка поля и оно читалось белой полосой. */
.gc-ai-ask { color-scheme: dark; }
.groupcall-overlay .gc-ai-input,
.gc-ai-input {
  /* 🔴 !important здесь ОСОЗНАННО. В живом созвоне поле всё равно получало глобальный
     `input { background: var(--panel-2) }`, и в СВЕТЛОЙ теме на тёмном доке это была
     белая полоса во всю строку (видно на скриншоте стенда, computed = rgb(255,255,255)).
     Оверлей созвона тёмный ВСЕГДА и не участвует в теме страницы — фон поля здесь
     диктует он, а не каскад темы. */
  background: rgba(255,255,255,.07) !important;
  border-radius: 11px; padding: 0 10px;
}
.gc-ai-input:focus { background: rgba(255,255,255,.11) !important; }
/* «Думает»: поле не принимает ввод (readonly, а не disabled — у disabled системная
   отрисовка своя и спорит с тёмным стеклом), это видно по приглушённому тексту. */
.gc-ai-input[readonly] { color: rgba(255,255,255,.5); -webkit-text-fill-color: rgba(255,255,255,.5); }
.gc-ai-input[readonly]::placeholder { color: rgba(255,255,255,.3); }
.gc-ai-send {
  flex: 0 0 auto; width: 34px; height: 34px; display: grid; place-items: center;
  border: 0; border-radius: 11px; cursor: pointer; color: #fff;
  background: linear-gradient(135deg, var(--primary), var(--primary-2));
  transition: transform .12s ease, filter .12s ease, opacity .12s ease;
}
.gc-ai-send:hover { filter: brightness(1.08); }
.gc-ai-send:active { transform: scale(.94); }
.gc-ai-send:disabled { opacity: .45; cursor: default; }
.gc-ai-send .ic { width: 17px; height: 17px; }
/* «Думает…» — контролы заблокированы, и это ВИДНО: бегущая полоска по кромке строки. */
.gc-ai-ask.busy { position: relative; overflow: hidden; }
.gc-ai-ask.busy::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--primary-2), transparent);
  animation: gcAiScan 1.1s linear infinite;
}
@keyframes gcAiScan { from { transform: translateX(-100%); } to { transform: translateX(100%); } }

/* (кольцо говорящего, эквалайзер, кнопка «свернуть», подпись имени, показ экрана и сам
   спотлайт — в `callui.css`: они принадлежат ПЛИТКЕ, а не этому оверлею) */

/* ── ДОК управления: плавающая стеклянная пилюля (в потоке — сцена авто-освобождает место) ── */
.groupcall-controls {
  /* 🔴🔴 ЗВОН-951: ДОК — ПЛАВАЮЩАЯ ПАНЕЛЬ УПРАВЛЕНИЯ, А НЕ ЧАСТЬ СЦЕНЫ. Здесь не было ни
     `position`, ни `z-index` — то есть ряд кнопок лежал в обычном потоке, а холст доски
     созвона (`.cc-board`, `position:absolute; z-index:9`, `bottom:92px`) рисуется ПОВЕРХ.
     Док при широком окне упирается в свой `max-width` и переносится на ДВА ряда (>92px), и
     верхний ряд уходил ПОД доску: `elementFromPoint` в центре ▣/⌄/⛶ возвращал `#brdVP`
     (замер прибором на живом проде, чат конференции закрыт). Нажатие до кнопки не доходило
     вовсе — а жалоба владельца была ровно про эти кнопки. Это ТОТ ЖЕ класс, которым ▣ уже
     была мертва однажды (CLIE-937: панель чата ложилась на правый край ряда), поэтому лечим
     не числом у доски, а природой дока: он всегда над сценой. */
  position: relative; z-index: 12;
  flex: 0 0 auto; align-self: center; width: max-content; max-width: calc(100vw - 28px);
  /* 🔴🔴 ПРАВИЛО ДОКА · РЯД НЕ ПЕРЕНОСИТСЯ (16.09.2026). `flex-wrap: wrap` здесь и был
     причиной мёртвых кнопок: при 24 кнопках ряду нужно 1507px, при окне 1440 есть 1412 —
     док уезжал во ВТОРОЙ ряд, а второй ряд ложится под холст доски (ЗВОН-951, CLIE-937) и
     нажатие до кнопки не доходит. Теперь лишнее уносит в «Ещё» дверь `ccDockFit()`. */
  display: flex; align-items: center; flex-wrap: nowrap; justify-content: center; gap: 8px;
  padding: 8px 10px; margin: 6px auto calc(env(safe-area-inset-bottom) + 18px);
  background: var(--gc-dock); border: 1px solid var(--gc-hair-2); border-radius: 18px;
  -webkit-backdrop-filter: blur(24px) saturate(1.3); backdrop-filter: blur(24px) saturate(1.3);
  box-shadow: 0 24px 60px -20px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05);
}
/* ─────────────────────────────────────────────────────────────────────────────
   🔴🔴 ДОК ЗВОНКА 1-НА-1 = ДОК КОНФЕРЕНЦИИ (CLIE-1219, владелец 17.09.2026:
   «Не ровно иконки взаимодействия в звонке 1 на 1. Давай сделаем как в видео
   конференции. Там сейчас все хорошо реализовано»).

   ЗАМЕР ДО ПРАВКИ (прибор `tools/shots/call1to1-dock.js`, окно 1440): в ряду 18
   кнопок, ряду нужно 1440 при доступных 1440 → `flex-wrap: wrap` уносил хвост во
   ВТОРУЮ строку. А кнопки интерактива (реакции · рука · опрос · совместная работа ·
   ИИ) в звонок 1:1 ПЕРЕЕЗЖАЮТ из дока конференции (`gcxMount`) вместе со своей
   подписью `.gcw-lbl` — и, поскольку правило `button:not(.has-word) .gcw-lbl` было
   прибито к `.groupcall-controls`, в звонке слово показывалось ВСЕГДА: круглые
   иконки 70px вперемешку с пилюлями по 200px. Ровно это на снимке владельца.

   ЛЕЧИМ НЕ ЧИСЛОМ, А ПРИРОДОЙ: ряд звонка — ТОТ ЖЕ док. Один набор правил на обе
   поверхности (селекторными группами ниже), одна дверь раскладки `ccDockFit()`,
   один «Ещё», одно слово по НАСТОЯЩЕМУ замеру. Второй размерный класс в звонке
   больше не заводится.

   🔴 ЧЕМ ДОК ЗВОНКА ЗАКОННО ОТЛИЧАЕТСЯ: он лежит `absolute` ПОВЕРХ полноэкранного
   живого кадра собеседника (в конференции — в потоке под сеткой) и НЕ БЕРЁТ
   `backdrop-filter` (ЗВОН-34: блюр поверх живого видео читает кадр обратно из
   композитора на каждую кнопку — цена самая высокая именно здесь).
   ───────────────────────────────────────────────────────────────────────────── */
.call-controls {
  position: absolute; left: 50%; right: auto; transform: translateX(-50%);
  bottom: calc(env(safe-area-inset-bottom) + 24px); z-index: 2;
  flex: 0 0 auto; width: max-content; max-width: calc(100vw - 28px);
  display: flex; align-items: center; flex-wrap: nowrap; justify-content: center; gap: 8px;
  padding: 8px 10px; margin: 0;
  background: var(--gc-dock); border: 1px solid var(--gc-hair-2); border-radius: 18px;
  box-shadow: 0 24px 60px -20px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05);
}
.gc-grp { display: flex; align-items: center; gap: 6px; }
.gc-sep { width: 1px; height: 26px; background: var(--gc-hair-2); margin: 0 2px; flex: 0 0 auto; }
/* 🔴 CLIE-1219 · ПУСТАЯ ГРУППА НЕ ЗАНИМАЕТ МЕСТО И НЕ ТАЩИТ ЗА СОБОЙ ВОЛОСОК.
   В звонке 1:1 состав ряда меняется по фазе: на входящем видны ТОЛЬКО «Принять» и
   «Отклонить», остальные кнопки прячет роль. Без этого правила от пустых групп
   остались бы зазоры `gap` и висящие разделители — ровно та неровность, на которую
   жаловался владелец, только в другой фазе. */
.call-controls .gc-grp.gc-empty { display: none; }
.call-controls .gc-grp.gc-empty + .gc-sep { display: none; }
/* Входящий звонок — две пилюли и ничего больше: волоски ряда там нечего разделять. */
.call-overlay.ringing .call-controls > .gc-sep { display: none; }
.groupcall-controls button,
.call-controls button {
  position: relative; width: 44px; height: 44px; min-width: 0; padding: 0; border-radius: 12px;
  /* 🔴 CLIE-1219 · МАРЖИ ОБНУЛЕНЫ ЯВНО. Замер 17.09 на входящем звонке: «Принять»
     (`.primary`) приезжал с `margin-top: 6px` от общего правила кнопок формы и стоял
     на 3px ниже «Отклонить» — ряд из ДВУХ кнопок уже был неровным. Док задаёт свои
     умолчания сам (правило движка, СРЕД-34), а не наследует чужие. */
  margin: 0;
  /* 🔴 CLIE-1219 · КНОПКА ДОКА НЕ СЖИМАЕТСЯ. Замер 17.09: ряд 1:1 упёрся в `max-width`, и
     flex молча ужал «Завершить» и «В окошко» до 18px вместо 44 — при этом `scrollWidth`
     сравнялся с `clientWidth`, то есть ряд «влез», и `ccDockFit` не увёз в «Ещё» НИЧЕГО.
     Ряд обязан решать переполнение замером, а не усадкой мишеней (канон `tap-target`). */
  flex: 0 0 auto;
  border: 1px solid transparent; background: var(--gc-btn); color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; transition: background .16s, color .16s, transform .1s;
}
.groupcall-controls button:hover,
.call-controls button:hover { background: var(--gc-btn-h); border-color: transparent; }
.groupcall-controls button:active,
.call-controls button:active { transform: scale(.94); }
.groupcall-controls button svg.ic,
.call-controls button svg.ic { width: 20px; height: 20px; }
/* «Принять» · «Отклонить» — текстовые пилюли той же высоты, что и ряд: это ровно форма
   «Выйти» из дока конференции. Кнопки-иконки остаются 44×44. 🔴 Без `width:auto` слово
   не помещалось в квадрат 44px, и кнопка ужималась. */
/* 🔴 CLIE-1785·В: второй вход «Без видео» живёт в ЭТОМ ЖЕ блоке, а не рядом со своим.
   Пока его тут не было, он наследовал квадрат 44×44 — и подпись ломалась на две строки
   («Без» / «видео»), сжимая весь ряд. Ровно тот случай, что описан абзацем выше. */
.call-controls #acceptBtn, .call-controls #rejectBtn, .call-controls #acceptAudioBtn {
  width: auto; min-width: auto; padding: 0 18px; gap: 8px;
  font-weight: 600; font-size: 13.5px; white-space: nowrap;
}
.call-controls #acceptBtn svg.ic, .call-controls #rejectBtn svg.ic,
.call-controls #acceptAudioBtn svg.ic { width: 18px; height: 18px; }
.call-controls #acceptBtn span, .call-controls #rejectBtn span,
.call-controls #acceptAudioBtn span { white-space: nowrap; }
/* выключено (мик/камера) — приглушённо-красный, БЕЗ перечёркивания.
   🔴 CLIE-1219: то же состояние и теми же чернилами в звонке 1:1 — раньше там был свой
   язык (`opacity:.5`), и одна и та же выключенная камера выглядела на двух экранах
   по-разному. Одна суть — одна реализация. */
.groupcall-controls .off,
.call-controls .off { opacity: 1; text-decoration: none; background: rgba(239,68,68,.16); border-color: rgba(239,68,68,.34); color: #ffb0b0; }
.groupcall-controls .off:hover,
.call-controls .off:hover { background: rgba(239,68,68,.24); }
/* демонстрация экрана активна */
.groupcall-controls .sharing,
.call-controls .sharing { background: var(--acc-grad); box-shadow: 0 0 0 2px rgba(255,255,255,.28) inset; color: #fff; }
/* 🔴🔴 ЗВОН-951 · ТРИ КНОПКИ ОКНА НАЗЫВАЮТ СЕБЯ СЛОВОМ (▣ «Поверх программ» · ⌄ «В окошко» ·
   ⛶ «Весь экран»). Владелец дважды про один и тот же угол дока: «не знаю что означает…
   объясни что он делает» и затем «почему не исправлено???». Подсказка при наведении этот
   вопрос не закрывает: её надо найти мышью и подержать, а три соседних глифа-рамки читаются
   как одно и то же. Форма — ТА ЖЕ, что у «Выйти» ниже (width:auto + текст рядом с глифом),
   второго размерного класса в ряду не заводим: высота остаётся 44px у всех соседей.
   🔴 `min-width: auto` — канон `label-fit`: у соседей по доку стоит `min-width: 0`, и подпись
   схлопывалась бы в многоточие вместо того, чтобы занять свою ширину.
   🔴 СЛОВО СНИМАЕТ ТОЛЬКО ШИРИНА. Первая редакция гасила подпись ещё и при открытом чате
   конференции (`.gc-chat-open`) — и это было ровно возвращение жалобы: снимок прода показал,
   что с открытым чатом человек снова видит ТРИ НЕМЫХ ГЛИФА, а чат в созвоне открыт почти
   всегда. Замер там же: док и так переносится на два ряда, во втором ряду 8 кнопок ≈ 500px,
   подписи добавляют ≈250px — при ширине окна ≥1280 это помещается в док (≈1050px при 1440,
   ≈890px при 1280). Ниже 1280 слово честно уходит: там место реально кончилось.
   🔴🔴 16.09.2026 — ПОДПИСЬ ЕСТЬ У КАЖДОЙ КНОПКИ ДОКА, А НЕ У ТРЁХ, и показывает её
   НАСТОЯЩИЙ ЗАМЕР, а не media-query. Порог «1279px» был угадан по одной раскладке: с
   открытым чатом конференции, в мини-окне и на планшете ширина дока совсем другая, и
   слово то пропадало там, где место было, то распирало ряд там, где его не было.
   Теперь ширину меряет `ccDockFit()` (app.js) и ставит класс `has-word` тем кнопкам,
   которым слово поместилось; в списке «Ещё» слово видно ВСЕГДА. */
.groupcall-controls .gcw-lbl,
.call-controls .gcw-lbl { font-size: 13px; font-weight: 500; white-space: nowrap; letter-spacing: -.1px; }
/* 🔴 CLIE-1219: то же правило и для звонка 1:1. Без него переехавшая из конференции
   кнопка показывала слово ВСЕГДА — отсюда и брались пилюли «Опрос и вопросы» /
   «Совместная работа» вперемешку с круглыми иконками на снимке владельца. */
.groupcall-controls button:not(.has-word) .gcw-lbl,
.call-controls button:not(.has-word) .gcw-lbl { display: none; }
.groupcall-controls button.has-word,
.call-controls button.has-word { width: auto; min-width: auto; padding: 0 12px; gap: 7px; }
.groupcall-controls .gc-wbtn,
.call-controls .gc-wbtn { min-width: auto; }

/* ── СЕГМЕНТ «ВИД»: размер окна созвона — ОДИН контрол с тремя положениями ──
   🔴 Это КАНОН `.cc-seg` (модификатор `-md` = высота ряда), а не новый компонент: своей
   дорожки с пилюлей продукт больше не рисует (канон `segment`). Док лежит на стекле
   поверх видео, поэтому переопределяем ВЕСЬ набор `--seg-*`, а не одну дорожку — они
   одно целое, и половина набора даёт невидимую пилюлю в тёмной теме. */
.groupcall-controls .gc-vseg {
  --seg-track: var(--gc-btn);
  --seg-thumb: rgba(255,255,255,.22);
  --seg-thumb-bd: rgba(255,255,255,.18);
  --seg-thumb-sh: 0 1px 2px rgba(0,0,0,.40);
  /* 🔴 ЗАЗОР ВМЕСТО ВОЛОСКА. Замер на проде: три положения стояли ВПЛОТНУЮ (зазоры 0 и 0),
     а канонный разделитель — хэйрлайн rgba(255,255,255,.14) — на тёмном стекле дока не
     читается вовсе, и три глифа сливались в одно пятно (владелец: «отступов нет»). Ставим
     настоящий зазор 3px; разделитель тогда лишний — два способа разделить сразу это шум. */
  --seg-div: transparent;
  --ctl-h: 44px; --ctl-r: 12px;
  gap: 3px; flex: 0 0 auto; align-self: center; border-color: transparent; overflow: visible;
}
/* Дети сегмента внутри дока — иконочные, а не текстовые: подпись приезжает по замеру. */
.groupcall-controls .gc-vseg > button {
  width: 38px; height: 38px; padding: 0; background: none; border-radius: 9px;
}
.groupcall-controls .gc-vseg > button.has-word { width: auto; padding: 0 11px; }
.groupcall-controls .gc-vseg > button:hover:not(.on) { background: var(--gc-btn-h); }

/* ── «ЕЩЁ»: то, чему не хватило ширины. Здесь кнопка — СТРОКА СО СЛОВОМ ── */
.gc-more-wrap { position: relative; flex: 0 0 auto; display: flex; align-items: center; }
.groupcall-controls .gc-more-pop,
.call-controls .gc-more-pop {
  position: absolute; bottom: calc(100% + 10px); right: 0; z-index: 14;
  /* 🔴 ПОТОЛОК ПО МЕСТУ НАД ДОКОМ, А НЕ ДОЛЯ ЭКРАНА. На телефоне в «Ещё» уезжает почти
     весь док (16 пунктов ≈ 670px), и потолок 58vh резал список ровно посередине строки —
     читается как обрезанная кнопка, а не как «дальше есть». Берём всё, что есть над доком;
     `dvh` — чтобы адресная строка браузера не врала о высоте. Не влезло — честный скролл. */
  min-width: 246px; max-height: calc(100dvh - 150px); overflow: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 2px; padding: 7px;
  /* 🔴 МЕНЮ НЕПРОЗРАЧНО. Замер на проде (телефон, 14 пунктов): сперва фон был стеклянный,
     как у самого дока, и сквозь список читались плитки участников. Подняли до .96 — на
     снимке с прода имя «Марина» ВСЁ РАВНО проступало сквозь пункт: `backdrop-filter`
     рисует размытую подложку в полную силу, и оставшихся 4% хватало на призрак. Меню — не
     стекло дока, а список, который читают: фон сплошной, размытия нет вовсе (оно тут ещё и
     дорогое — блюр поверх живого видео). Ровно тот же вывод, что у панели дока в приложении
     (CallDockPalette.panelDark: «полупрозрачная панель без настоящего блюра показывает видео
     НАСКВОЗЬ»). */
  border-radius: 14px; background: var(--cm-161a24, #161a24); border: 1px solid var(--gc-hair-2);
  box-shadow: 0 30px 70px -24px rgba(0,0,0,.8);
}
.groupcall-controls .gc-more-pop.hidden,
.call-controls .gc-more-pop.hidden { display: none; }
/* 🔴 СТРОКА МЕНЮ НЕ СЖИМАЕТСЯ. Замер на проде (16 пунктов, потолок 58vh): у строк было
   `flex: 0 1 auto`, содержимое в потолок не влезало — и флекс УЖАЛ каждую до 25.8px при
   заданных 40, а три строки сегмента (у них `flex: 0 0 auto`) остались полными. Ровно это
   владелец увидел как «всё не ровно»: тонкие пункты вперемешку с толстыми. Потолок есть —
   значит прокрутка (`overflow:auto` выше), а не ужатие строк. */
.groupcall-controls .gc-more-pop button,
.call-controls .gc-more-pop button {
  flex: 0 0 auto;
  width: 100%; height: 40px; padding: 0 10px; gap: 10px; border-radius: 9px;
  justify-content: flex-start; background: transparent;
}
.groupcall-controls .gc-more-pop button:hover,
.call-controls .gc-more-pop button:hover { background: var(--gc-btn-h); }
.groupcall-controls .gc-more-pop button .gcw-lbl,
.call-controls .gc-more-pop button .gcw-lbl { display: inline; font-size: 14px; font-weight: 400; }
/* 🔴 В МЕНЮ сегмент стоит КОЛОНКОЙ (канон `segment`: в узком поповере — «на всю ширину»).
   Замер на проде: три подписи («Поверх программ» · «В окошко» · «Весь экран») в ряд 246px
   не помещаются и режутся многоточием — то есть кнопка снова становится немой. Колонкой
   каждая называет себя целиком и читается ровно как остальные пункты. */
.groupcall-controls .gc-more-pop .gc-vseg {
  /* 🔴 В МЕНЮ СЕГМЕНТ — ТАКОЙ ЖЕ СТОЛБЕЦ СТРОК, БЕЗ СВОЕЙ РАМКИ И ВЫСОТЫ. Замер: рамка
     `.cc-seg` 1px сдвигала его строки на 1px и отнимала 2px ширины (12/284 против 13/282),
     а `min-height` от `-md` добавляла свой воздух — поэтому три пункта окна стояли не по
     той же сетке, что остальные. */
  width: 100%; flex-direction: column; align-items: stretch; gap: 2px;
  background: none; padding: 0; border: 0; min-height: 0; align-self: stretch; flex: 0 0 auto;
}
.groupcall-controls .gc-more-pop .gc-vseg > button {
  /* 🔴 РАМКА — ТОЖЕ СЕТКА. У соседних строк меню есть прозрачная рамка 1px (от общего
     правила кнопок дока), и без неё содержимое сегмента вставало на 1px левее: иконки
     22 против 23, подписи 52 против 53. Один пиксель — ровно то, что читается как «не
     ровно», когда строк полтора десятка. */
  flex: 0 0 auto; width: 100%; height: 40px; justify-content: flex-start; padding: 0 10px; gap: 10px;
  border: 1px solid transparent;
}
.groupcall-controls .gc-more-pop .gc-badge,
.call-controls .gc-more-pop .gc-badge { position: static; margin-left: auto; }

/* ── АДАПТИВНОСТЬ: одна раскладка, разный шаг. Что показать — решает замер, а не порог ── */
@media (max-width: 760px) {
  .groupcall-controls, .call-controls { gap: 6px; padding: 7px 8px; border-radius: 16px; }
  .groupcall-controls .gc-grp, .call-controls .gc-grp { gap: 4px; }
  .groupcall-controls .gc-leave, .call-controls .gc-leave { padding: 0 14px; }
  .groupcall-controls .gc-more-pop, .call-controls .gc-more-pop { min-width: 0; width: min(78vw, 300px); }
}
/* Телефон лёжа: по высоте дороже, чем по ширине — ряд ниже, но цель касания не меньше 44
   (канон `tap-target`), поэтому ужимаем только там, где указатель НЕ палец. */
@media (max-height: 560px) and (orientation: landscape) and (pointer: fine) {
  .groupcall-controls { padding: 6px 8px; margin-bottom: calc(env(safe-area-inset-bottom) + 10px); }
  .call-controls { padding: 6px 8px; bottom: calc(env(safe-area-inset-bottom) + 10px); }
  .groupcall-controls button, .call-controls button { width: 40px; height: 40px; }
  .groupcall-controls .gc-vseg { height: 40px; }
  .groupcall-controls .gc-vseg button { width: 34px; height: 34px; }
}
/* «Выйти» — отдельная форма/цвет, всегда отличима от красной записи */
.groupcall-controls .gc-leave,
.call-controls .gc-leave { width: auto; padding: 0 18px; gap: 8px; border-radius: 12px; background: var(--danger); color: #fff; font-weight: 600; font-size: 13.5px; }
.groupcall-controls .gc-leave:hover,
.call-controls .gc-leave:hover { background: #dc2f2f; }
.groupcall-controls .gc-leave svg.ic,
.call-controls .gc-leave svg.ic { width: 18px; height: 18px; }
.groupcall-controls .gc-leave span,
.call-controls .gc-leave span { white-space: nowrap; }
/* 🔴🔴 ЗВОН-932 — ПОДСКАЗКА ДОКА ЖИВЁТ В `/app/cctip.js`, А НЕ ЗДЕСЬ.
   Тут стоял свой CSS-пузырь `.groupcall-controls button[data-tip]::after` — ТРЕТЬЯ
   реализация подсказки в продукте (плюс всплывашка рельса `.cc-railtip` и нативный `title`
   у звонка 1:1 и у всей гостевой страницы). Из-за этого на один вопрос «что это за кнопка»
   продукт отвечал по-разному, у пяти кнопок дока показывались ДВЕ подсказки сразу (в
   разметке `data-tip="Показать экран"`, а живой код пишет `title="Остановить показ"`), а
   гостю CSS-пузырь не доставался вовсе — `guest.html` не грузит этот файл.
   Теперь подсказку рисует ОДНА дверь `CcTip` (см. ccMountCallTips в app.js). Возврат
   правила сюда = возврат расхождения, его ловит сторож TIP_MECH. */

/* ---- управление группой ---- */
.gs-wide { width: 100%; margin: 0; }
.gs-member { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 10px; }
.gs-member:hover { background: var(--panel-2); }
.gs-mem-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; }
.gs-member .conv-name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gs-badge { font-size: 10px; background: var(--mine); color: var(--primary-2); padding: 2px 7px; border-radius: 8px; flex: none; }
/* «Гость» — сторонний участник проектной группы (не в проекте): мягкая янтарная метка, тема-aware */
.gs-badge.guest { background: var(--warning-soft); color: var(--warning); font-weight: 600; }
.gs-mem-actions { display: flex; align-items: center; gap: 4px; flex: none; }
.gs-mem-actions .ghost.small { padding: 4px 8px; font-size: 12px; }
.gs-role { color: var(--primary-2); }
.gs-remove { color: var(--danger); flex: none; }
#gsAddBtn { margin-top: 6px; }
#gsAddBtn:disabled { opacity: .5; cursor: default; }
.gs-add-search { margin: 4px 0 6px; }
/* 🔴 CLIE-620 «Нет скролла и не влезает». Здесь стоял кап
   `#gsMembers,#gsAddList{max-height:240px;overflow-y:auto}` — «чтобы модал не растягивался».
   Мотивация умерла вместе со старой модалкой: карточка группы (.gs2-body) скроллится сама,
   одним куском. Кап остался и РЕЗАЛ: 240px — это ровно 4 строки по 56px и огрызок пятой,
   причём `#groupSettingsModal .gs-card{overflow:hidden}` (gs2) перебивает `overflow-y:auto`
   по специфичности (id+class > id) → доскроллить было НЕЧЕМ вообще. Плюс бегунок у нас
   прозрачный до наведения (см. «Скроллбары» выше) — вложенный скролл человек не видит.
   Участники — ДАННЫЕ ОБЪЕКТА: прятать их за внутренним скроллом нельзя (то же решение уже
   принято для «Записей коллабов», см. .rec-list в gs2). Кандидатов на добавление капим,
   но ВИДИМЫМ скроллом — класс .cc-scroll-in (кап живёт рядом с остальными его стилями,
   в gs2-блоке app.js: два источника одной высоты — это следующий такой же баг). */
#gsMembers { max-height: none; }

/* 🔗 ОБЩИЙ КАНАЛ (Shared/Connect, 0155): секция «Компании в канале» + чип «Общий · {компания}».
   Хэйрлайн-пилюли, токены темы (свет/тёмная едины), без жирных заливок. Apple-grade. */
.gs-badge.host { background: var(--mine); color: var(--primary-2); font-weight: 600; }
.gs-comp { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 10px; }
.gs-comp:hover { background: var(--panel-2); }
.gs-comp-logo { flex: none; width: 34px; height: 34px; border-radius: 9px; border: 1px solid var(--line);
  background: var(--panel-2) center/cover no-repeat; display: flex; align-items: center; justify-content: center; color: var(--primary-2); }
.gs-comp-logo svg { width: 16px; height: 16px; }
.gs-comp-main { flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.gs-comp-main .conv-name { font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gs-comp-cnt { font-size: 11px; color: var(--textSecondary); }
.gs-comp-act { flex: none; display: flex; align-items: center; gap: 4px; }
.gs-comp-remove { color: var(--danger); }
.gs-chan-btns { display: flex; gap: 8px; align-items: center; margin-top: 8px; flex-wrap: wrap; }
.gs-wide-btn { flex: 1 1 auto; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 10px 14px; border-radius: 10px; border: 1px solid var(--line-strong); background: var(--panel-2); color: var(--text);
  font-size: 13px; font-weight: 600; cursor: pointer; transition: background .14s ease, border-color .14s ease, transform .1s ease; }
.gs-wide-btn:hover { background: var(--panel); border-color: var(--primary); }
.gs-wide-btn:active { transform: translateY(1px); }
.gs-wide-btn svg { width: 16px; height: 16px; }
.gs-chan-note { padding: 8px 10px; line-height: 1.45; }
.gs-comp-pick { margin-top: 6px; padding: 6px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.gs-label.sub { font-size: 11px; color: var(--textSecondary); padding: 4px 6px; }
.gs-pick-row { width: 100%; display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px;
  border: 0; background: transparent; color: var(--text); cursor: pointer; text-align: left; transition: background .12s ease; }
.gs-pick-row:hover { background: var(--panel-2); }
.gs-pick-row:disabled { opacity: .5; cursor: default; }

/* Чип «Общий · {компания}» в строке списка чатов и в шапке треда — хэйрлайн-пилюля со звеном. */
.conv-row-shared { margin-top: 3px; display: flex; min-width: 0; }
.conv-shared { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; padding: 1px 8px 1px 6px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--panel-2); color: var(--textSecondary); font-size: 11px; line-height: 1.6; }
.conv-shared .cs-ic { flex: none; display: inline-flex; align-items: center; width: 12px; height: 12px; margin-top: 0; color: var(--primary-2); }
.conv-shared .cs-ic svg { width: 12px; height: 12px; }
.conv-shared .cs-name { margin-top: 0; font-size: 11px; color: var(--textSecondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.thread-shared { display: inline-flex; align-items: center; min-width: 0; }
.thread-shared.hidden { display: none; }

/* 🏢 CLIE-442 Э4 — чип-провенанс «чей это чат» у ВНЕШНЕГО (ещё не прикреплённого) канала.
   Акцент несут ИКОНКА и СЛОВО (имя компании) + мягкая подложка и хэйрлайн-кольцо — НЕ левая
   полоса-рейка (правило продукта CLIE-483). Размер и форма — те же, что у .conv-shared. */
.conv-shared.conv-ext { background: color-mix(in srgb, var(--primary-2) 10%, transparent);
  border-color: color-mix(in srgb, var(--primary-2) 22%, transparent); }
.conv-shared.conv-ext .cs-name { color: var(--text); }

/* Подпись под блоком «Моя сторона» в карточке группы (CLIE-442 Э4): объясняет, что имя
   локальное. Отступ, чтобы не липла к нижней кромке карточки. */
.gs-side-hint { margin: 9px 2px 0; line-height: 1.45; }

/* 🔗 Журнал действий общего канала (кросс-компанийный аудит) — в настройках группы, host-admin */
.gs-audit { margin-top: 12px; }
.gs-audit.hidden { display: none; }
.gs-audit > .gs-label.sub { padding: 0 2px 6px; }
.gs-audit-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 1px; }
.gs-audit-row { display: flex; align-items: center; gap: 9px; padding: 7px 8px; border-radius: 8px;
  font-size: 12.5px; color: var(--text); transition: background .12s ease; }
.gs-audit-row:hover { background: var(--panel-2); }
.gs-audit-ic { flex: none; width: 15px; height: 15px; display: inline-flex; align-items: center; color: var(--primary-2); }
.gs-audit-ic svg { width: 15px; height: 15px; }
.gs-audit-txt { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gs-audit-when { flex: none; font-size: 11px; color: var(--textSecondary); font-variant-numeric: tabular-nums; }
.gs-audit-empty { padding: 7px 8px; }

/* кружок-аватар участника (фото/постер видео или инициалы) + точка онлайна */
.gs-mem-av-wrap { position: relative; flex: none; width: 34px; height: 34px; }
.gs-mem-av {
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--acc-grad); color: #fff;
  display: flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 13px;
}
.gs-mem-av.has-img { background-size: cover; background-position: center; color: transparent; }
.gs-mem-dot {
  position: absolute; right: -1px; bottom: -1px; width: 10px; height: 10px;
  border-radius: 50%; background: var(--ok); border: 2px solid var(--panel);
}
.group-user label .conv-name { flex: 1; min-width: 0; }

/* ---- папки чатов (рельс) ---- */
.folder-row { display: flex; align-items: center; gap: 8px; padding: 9px 12px; border-radius: 10px; }
.folder-row.active { background: var(--panel-2); }
.folder-row .folder-open { flex: 1; min-width: 0; font-weight: 500; cursor: pointer; text-align: left; background: transparent; border: none; color: var(--text); padding: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.folder-row .folder-open:hover { color: var(--primary-2); }
.folder-row .folder-count { font-size: 11px; color: var(--muted); flex: none; min-width: 18px; text-align: right; }
.folder-act { flex: none; }
.folder-act.del { color: var(--danger); }
#folderNewBtn { margin-top: 6px; }
/* пилюля-хинт «краткое имя» в строке папки */
.folder-row .folder-short-tag {
  flex: none; max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 10.5px; font-weight: 600; color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  border-radius: 6px; padding: 1px 8px;
}
/* поле «краткое имя» в панели наполнения папки */
.folder-short-row { display: block; margin: 4px 0 8px; }
.folder-short-lbl { display: block; font-size: 12px; color: var(--muted); margin-bottom: 5px; }
.folder-short-row #folderShortName { margin: 0; }

/* ── всплывашка рельса (мгновенная, на body → не срезается overflow рельса) ── */
/* 🔴 ЗВОН-932: всплывашка рельса переехала в единую дверь `/app/cctip.js` (`.cc-tip`).
   Здесь она жила со своим z-index 10000 — то есть НИЖЕ полосы слоёв (CC_Z_BASE=300000), и
   над открытым созвоном её всё равно не было бы видно. Своего правила `.cc-railtip` в
   продукте больше нет: одна суть — одна реализация. */
#folderEditWrap { margin-top: 8px; border-top: 1px solid var(--line); padding-top: 10px; }

/* Пикер наполнения папки: поиск + сегменты категорий + список кандидатов */
.folder-pick-search {
  width: 100%; box-sizing: border-box; margin: 2px 0 8px;
  padding: 9px 12px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); font-size: 13px; outline: none;
}
.folder-pick-search:focus { border-color: var(--primary, var(--cm-6c5ce7, #6c5ce7)); }
.folder-pick-search::placeholder { color: var(--muted); }
.folder-pick-segs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 8px; }
.folder-pick-seg {
  padding: 6px 12px; border-radius: 8px; border: 1px solid var(--line);
  background: transparent; color: var(--muted); font-size: 12px; font-weight: 600;
  cursor: pointer; transition: background var(--dur-1, .12s), color var(--dur-1, .12s), border-color var(--dur-1, .12s);
}
.folder-pick-seg:hover { color: var(--text); }
.folder-pick-seg.active { background: var(--acc-fill, var(--cm-6c5ce7, #6c5ce7)); border-color: var(--acc-fill, var(--cm-6c5ce7, #6c5ce7)); color: #fff; }
/* 🔴 CLIE-620: был `max-height:44vh;overflow-y:auto` — второй бегунок внутри уже
   скроллящегося `.modal-body`. Два скролла на одном экране человек не различает, а наш
   бегунок прозрачен до наведения: чаты для папки просто «кончались». Скроллит тело —
   своего правила у `.folder-pick-list` больше нет и не нужно. */
.folder-pick-item label { display: flex; align-items: center; gap: 10px; }
.folder-pick-item .fp-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.folder-pick-item .fp-sub {
  flex: none; font-size: 10px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 6px; background: var(--panel-2); color: var(--muted);
}
.folder-pick-item .fp-sub.fp-user { background: rgba(46,204,113,.16); color: #2ecc71; }
.folder-pick-item .fp-sub.fp-project { background: var(--cm-6c5ce7-16, rgba(108,92,231,.16)); color: var(--primary-2, var(--cm-a29bfe, #a29bfe)); }

/* ---- ответить / переслать / удалить ---- */
.msg { position: relative; touch-action: pan-y; -webkit-touch-callout: none; transition: transform .18s ease; }
/* Task 5: иконка ответа ↩ — плавнее проявляется и «подскакивает» при достижении порога */
.swipe-reply {
  position: absolute; left: -34px; top: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--mine, var(--cm-7c6dff-15, rgba(124,109,255,.15))); color: var(--primary-2);
  font-size: 15px; opacity: 0;
  transform: translateY(-50%) scale(.5);
  transition: opacity .14s ease, transform .14s cubic-bezier(.34,1.56,.64,1);
  pointer-events: none;
}
.msg.swipe-armed .swipe-reply { opacity: 1; transform: translateY(-50%) scale(1); }
/* подсветка пузыря при достижении порога свайпа */
.msg.swipe-armed .bubble {
  box-shadow: 0 0 0 2px var(--primary-2);
  transition: box-shadow .14s ease;
}
/* ═══ Подсветка цели перехода «к сообщению» — CLIE-520 ═══════════════════════
   (тап по цитате-ответу, переход из закреплённых/напоминания/поиска)
   БЫЛО: индиго-кольцо `--primary` + ореол `--glow` вокруг пузыря — то же самое, что у
   `.search-current`. В СВЕТЛОЙ теме это почти не читалось: у СВОЕГО пузыря фон сам индиго
   (`--grad`) → кольцо сливалось с пузырём, а `--glow` в светлой = alpha .20 и на белом
   пузыре поверх тёплого холста не виден вовсе.
   СТАЛО — «прожектор», другой приём, а не тот же ободок погромче:
     • мягкая подложка-карточка ПОД ВСЕМ сообщением (пузырь + имя + время), на 8px шире
       пузыря, с хэйрлайн-кольцом и мягкой тенью → цель видно раньше, чем прочитан текст;
     • обводка пузыря КОНТРАСТНА ЕГО СОБСТВЕННОМУ ФОНУ: на индиго-пузыре (свои) — светлая,
       на белом/панельном (чужие) — глубокий индиго `--primary-2` (AA в светлой);
     • держится ~4.2с и гаснет за 0.9с (класс `.flash-out` вешает JS) — было 2.2с.
   Обе темы и все концепты: цвета — только color-mix от `--primary` текущей палитры.
   Полосок-реек нет (правило CLIE-483): акцент несут подложка + кольцо. */
.msg.flash {
  border-radius: 18px;                       /* форма подложки и тени (свой фон у .msg отсутствует) */
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow:
    0 0 0 9px color-mix(in srgb, var(--primary) 12%, transparent),  /* подложка шире пузыря */
    0 0 0 10px color-mix(in srgb, var(--primary) 26%, transparent), /* хэйрлайн-кромка */
    0 0 22px 8px color-mix(in srgb, var(--primary) 15%, transparent), /* мягкий ореол наружу */
    0 10px 26px -14px color-mix(in srgb, var(--primary) 55%, transparent);
  transition: transform .18s ease, background-color .18s ease, box-shadow .18s ease;
}
/* Кольцо пузыря — «apple focus ring»: сначала 2px ЗАЗОР цветом панели, затем индиго-контур.
   Зазор и делает кольцо читаемым на ЛЮБОМ пузыре: свой (сплошной индиго), чужой (белый),
   ИИ (мятная подложка), медиа-кадр. !important + варианты mine/theirs/has-media — иначе тень
   своих пузырей и особенно `.bubble.has-media{box-shadow:none!important}` (ответ на фото/
   видео/кружок) перебивали подсветку → «на ответах подсветки нет». */
.msg.flash .bubble,
.msg.flash.mine .bubble,
.msg.flash.theirs .bubble,
.msg.flash .bubble.has-media,
.msg.flash.mine .bubble.has-media {
  box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px var(--primary-2) !important;
  transition: box-shadow .18s ease;
}
/* гашение: те же тени/фон → прозрачные, но за 0.9с (класс вешает JS после паузы) */
.msg.flash.flash-out {
  background: transparent;
  box-shadow: 0 0 0 9px transparent, 0 0 0 10px transparent, 0 0 22px 8px transparent,
              0 10px 26px -14px transparent;
  transition: transform .18s ease, background-color .9s ease, box-shadow .9s ease;
}
/* `:not(.search-current)` — у ТЕКУЩЕГО совпадения поиска кольцо стойкое и той же формулы:
   гасить его вместе с прожектором нельзя, иначе на каждом шаге ▲▼ кольцо моргало бы. */
.msg.flash.flash-out:not(.search-current) .bubble,
.msg.flash.flash-out:not(.search-current).mine .bubble,
.msg.flash.flash-out:not(.search-current).theirs .bubble,
.msg.flash.flash-out:not(.search-current) .bubble.has-media,
.msg.flash.flash-out:not(.search-current).mine .bubble.has-media {
  box-shadow: 0 0 0 2px transparent, 0 0 0 4px transparent !important;
  transition: box-shadow .9s ease;
}
/* 🔴🔴 CLIE-899·2 · «ТИХАЯ» ВСПЫШКА — БЕЗ ПРОЖЕКТОРА.
   Владелец, вернув задачу со скрином поиска: «Лишняя обводка появилась, достаточно обводки
   самого сообщения и текста который ищем». Разбор его кадра по пикселям (и тот же замер на
   живом проде) дал у ОДНОГО сообщения ТРИ пометки: прожектор `.msg.flash` (подложка акцент
   12% = rgb(33,39,55) + кромка 9/10px), обводка пузыря (зазор `--panel` + контур
   `--primary-2` = rgb(156,166,238)) и подсвеченное слово `mark.search-hit-current`.
   Прожектор адресован ПРИХОДУ ИЗВНЕ (цитата · закреп · напоминание), где у цели нет ни
   одной своей пометки. У совпадения поиска они ЕСТЬ и обе стойкие — значит прожектор тут
   третья обводка о том же, и загорается он на КАЖДОМ шаге ▲▼.
   Класс вешает JS (`flashMsg(seq, {spot:false})`) — не CSS-условием по `.search-current`:
   иначе при закрытии поиска класс `.search-current` снимается, а `.flash` живёт ещё до 4.2с,
   и прожектор ВСПЛЫЛ БЫ уже после того, как человек закрыл поиск.
   Кольцо пузыря и слово НЕ трогаем — они и есть то, что владелец просил оставить. */
.msg.flash.flash-quiet,
.msg.flash.flash-quiet.flash-out {
  background: transparent;
  box-shadow: none;
}

/* цитата отвечаемого сообщения внутри пузыря */
/* CLIE-483: рейку сняли — акцент именем (.rq-name) и подложкой с тонким кольцом */
.reply-quote {
  display: flex; flex-direction: column; gap: 1px; cursor: pointer;
  border-radius: 6px;
  background: rgba(255,255,255,.06); padding: 3px 8px; margin-bottom: 5px; max-width: 100%;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary-2) 22%, transparent);
}
.rq-name { color: var(--primary-2); font-size: 12px; font-weight: 600; }
.rq-text { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 240px; }

/* 🔆 На СВОЁМ пузыре фон — яркий градиент (--grad), а не тёмный список. Цитаты/превью/пилюли
   по умолчанию красятся под тёмный фон (--muted #8b93a3 / --primary(-2)) и на градиенте почти
   сливаются («плохо текст видно на который отвечают»). Перекрываем на бело-контрастные. */
/* CLIE-483: рейку сняли — на градиенте акцент даёт белое кольцо + белое имя (.rq-name/.lp-site) */
/* 🔴 ПОДЛОЖКА ВНУТРИ ЗАЛИВКИ ИДЁТ ТЕМНЕЕ ЗАЛИВКИ (канон contrast-runtime-audit; замер
   прода 10.09.2026: осветляющая rgba(255,255,255,.14) поднимала фон под белыми чернилами и
   давала цитате 3.59:1 в светлой и 2.70:1 в тёмной). Вид тот же — «блок внутри пузыря», —
   а чернила на нём выигрывают: подложка одна на все вложенные блоки, --bub-tint. */
.msg.mine .reply-quote,
.msg.mine .link-preview       { background: var(--bub-tint); box-shadow: inset 0 0 0 1px var(--bub-line); }
.msg.mine .rq-name,
.msg.mine .lp-site            { color: var(--bub-ink); }
.msg.mine .rq-text,
.msg.mine .lp-desc            { color: var(--bub-ink-dim); }
.msg.mine .bubble .msg-link   { color: #fff; }
.msg.mine .msg-task-ref       { color: var(--bub-ink); background: var(--bub-tint); border-color: var(--bub-line); }
.msg.mine .msg-task-ref:hover { background: var(--cm-0b1020-34, rgba(11,16,32,.34)); }
.msg.mine .bubble .msg-event-ref { background: var(--bub-tint); border-color: var(--bub-line); }
.msg.mine .bubble .mer-title  { color: var(--bub-ink); }
.msg.mine .bubble .mer-when   { color: var(--bub-ink-dim); }

/* панель «ответ на …» над композером */
.reply-bar { display: flex; align-items: center; gap: 10px; padding: 8px 18px; border-top: 1px solid var(--line); background: var(--panel); }
.reply-bar-icon { color: var(--primary-2); font-size: 18px; flex: none; }
.reply-bar-text { flex: 1; font-size: 13px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.reply-bar-text b { color: var(--primary-2); }
/* Правка ПОДПИСИ к вложению: в плашке показываем саму миниатюру, чтобы было
   видно, к чему подпись, — редактор подписи не должен быть голым полем.
   Хэйрлайн вместо жирной рамки; цвет берётся из токена → светлая и тёмная темы
   одинаково аккуратны. Размер совпадает с высотой строки плашки (8+32+8 = 48). */
.reply-bar-icon .edit-thumb {
  width: 32px; height: 32px; display: block; object-fit: cover;
  border-radius: 7px; border: 1px solid var(--line); background: var(--panel-2);
}

/* контекст-меню сообщения */
.msg-menu {
  position: fixed; z-index: 70; min-width: 162px; padding: 6px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px;
  display: flex; flex-direction: column; box-shadow: 0 10px 34px rgba(0,0,0,.55);
}
/* 🔴 CLIE-1505 · СТРОКА МЕНЮ — ТОЛЬКО ПРЯМОЙ РЕБЁНОК. Было `.msg-menu button` — и любая
   кнопка, ВЛОЖЕННАЯ в меню (сегмент разделов, плитка сетки, палитра реакций), получала
   вид строки списка и перебивала собственный канон компонента (`.cc-seg > *` весит 0,1,0
   против 0,1,1 у `.msg-menu button`): неактивный сегмент красился как активный, плитка
   растягивалась в строку. У всех потребителей класса (#folderMenu, #convMenu,
   .pin-scope-menu) строки — прямые дети, так что сужение их не трогает. */
.msg-menu > button { background: transparent; border: none; text-align: left; padding: 10px 12px; border-radius: 8px; color: var(--text); font-size: 14px; }
.msg-menu > button:hover { background: var(--panel); }
.msg-menu .msg-menu-del { color: var(--danger); }

/* ═══════════ CLIE-1505 · РАСКЛАДКА МЕНЮ СООБЩЕНИЯ (#msgMenu · msgMenuLayout) ═══════════
   Повод — кадр владельца 24.09.2026: «Неудобно читать информацию. Акцентов почти нет,
   данных много». В меню до 23 строк одного веса без групп и приоритета.
   Реестр (что показываем) отделён от раскладки (как показываем): метаданные группы и веса
   живут в MSG_ACT_META (app.js), раскладку строит ОДНА дверь msgMenuLayout().
   Раскладка одна — «СЕТКА» (выбор владельца 24.09.2026); близнец в приложении —
   client/lib/widgets/msg_actions_sheet.dart.
   🔴 Витрина из пяти подач кончилась выбором и удалена целиком вместе со своими правилами
   (.mm-grp · .mm-more · .mm-tailrow · .mm-tight · .mm-off · .mm-segrow · .mm-find · .mm-none)
   — канон variant-showcase: второй раскладки в продукте не остаётся. */

#msgMenu { min-width: 248px; max-width: 320px; }
/* 🔴 ПОВЕРХНОСТЬ МЕНЮ — `--panel-3`, А НЕ `--panel-2`. `.msg-menu` объявлен ДВАЖДЫ: первый
   раз здесь (строка ~6650), второй — в блоке «3.8 Меню/поповеры/тултипы: поднятый слой»,
   и фон задаёт ВТОРОЙ (та же специфичность, побеждает поздний). Липкие накладки и подложка
   плитки обязаны считаться от ФАКТИЧЕСКОЙ поверхности: в светлой теме `--panel` и
   `--panel-3` оба `#ffffff`, и плитка на `--panel` совпадала с меню один-в-один (замер
   ревью на проде: menu=tile=rgb(255,255,255), контраст 1.000 — «плиток нет»). */
#msgMenu { --mm-surface: var(--panel-3);
  /* Ступень от поверхности — ЧЕРНИЛАМИ темы, а не соседним токеном панели: в светлой теме
     это затемняет, в тёмной осветляет, и обе темы получают плитку одинаковой силы
     (1.20 и 1.25 к поверхности против 1.000 и 1.219 у прежней пары токенов). */
  --mm-inset: color-mix(in srgb, var(--text) 8%, var(--panel-3)); }
/* Шапка «над чем работаем»: человек не теряет само сообщение за меню. ЛИПНЕТ к верхней
   кромке — меню прокручиваемое (max-height min(86vh,640px) ставит app.js), и уехавшая
   шапка — ровно та же потеря, ради которой её и завели. Фон — РОВНО поверхность меню:
   накладка обязана быть невидимой, пока под ней ничего не проезжает. */
#msgMenu .mm-head { position: sticky; top: 0; z-index: 2; padding: 4px 10px 8px;
  background: var(--mm-surface); }
#msgMenu .mm-head b { display: block; font-size: 11px; font-weight: 700; letter-spacing: .2px; color: var(--primary-2, var(--primary)); }
#msgMenu .mm-head span { display: block; font-size: 12.5px; line-height: 1.25; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#msgMenu .mm-sep { height: 1px; margin: 5px 8px; background: var(--line); }
/* Акцентная строка — ровно одна на меню (самое частое действие). Акцент = значок цветом
   + СЛОВО жирнее (канон accent), никаких заливок строки и левых реек. */
#msgMenu > button.mm-primary { font-weight: 620; }
#msgMenu > button.mm-primary svg.ic { color: var(--primary-2, var(--primary)); }
/* Главные действия — плитками: значок над подписью, 4 в ряд. Крупная мишень и воздух —
   ровно то, чего не было у 23 одинаковых строк. */
#msgMenu .mm-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; padding: 4px 4px 8px; }
/* 🔴 Плитка ВИДНА: подложка — ступень от поверхности меню (--mm-inset) ПЛЮС хэйрлайн.
   Держать видимость одним хэйрлайном нельзя: у --line контраст к поверхности ~1.1 ПО
   ЗАМЫСЛУ (канон theme-contrast-runtime), сторож на него краснеть не умеет, и первая же
   уборка «лишней тени» вернула бы «плиток нет». Тон и кант — вместе, не вместо. */
#msgMenu .mm-grid button { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 5px;
  min-height: 70px; padding: 8px 4px; border: none; border-radius: 12px; cursor: pointer;
  background: var(--mm-inset); box-shadow: inset 0 0 0 1px var(--line);
  color: var(--text); font: inherit; font-size: 10.5px; line-height: 1.15;
  font-weight: 600; text-align: center; }
#msgMenu .mm-grid button:hover { background: color-mix(in srgb, var(--primary) 10%, var(--mm-inset));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 55%, var(--line)); }
#msgMenu .mm-grid button svg.ic { width: 19px; height: 19px; flex: none; }
#msgMenu .mm-grid button.mm-primary svg.ic { color: var(--primary-2, var(--primary)); }
#msgMenu .mm-grid button span { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* Хвост под сеткой — компактные строки: 15 оставшихся действий не имеют права отобрать
   экран целиком (паритет с Flutter, там у хвоста dense-строка). */
#msgMenu > button { padding: 7px 12px; font-size: 13px; }
/* 🔴 ОПАСНОЕ — ВНЕ ПРОКРУТКИ. В приложении строка «Удалить…» стоит ЗА пределами
   SingleChildScrollView; на вебе роль прокрутки играет само меню, поэтому строка липнет
   к нижней кромке. Иначе при 16 строках хвоста «Удалить…» уезжает под край и человек,
   не докрутив, считает, что удалить нечем. Фон свой — под ней проезжает список. */
#msgMenu > button.mm-danger { position: sticky; bottom: 0; z-index: 2;
  padding: 9px 12px; font-size: 14px; background: var(--mm-surface);
  box-shadow: 0 -1px 0 var(--line); }
/* Ховер — тот же, что у «Удалить» во всех меню продукта (.msg-menu .msg-menu-del:hover):
   у правила с #id специфичность выше, и без этой строки канонический ховер не доехал бы. */
#msgMenu > button.mm-danger:hover { background: var(--danger-soft); }

/* ---- SVG-иконки на кнопках ---- */
button svg.ic { width: 22px; height: 22px; display: block; }
.ic-rot135 svg.ic { transform: rotate(135deg); }
#createMenuBtn, #logoutBtn { display: inline-flex; align-items: center; gap: 6px; }
#createMenuBtn svg.ic, #logoutBtn svg.ic { width: 18px; height: 18px; }
.msg-menu > button { display: flex; align-items: center; gap: 10px; }
.msg-menu > button svg.ic { width: 18px; height: 18px; flex: none; }
.reply-bar-icon { display: inline-flex; }
.reply-bar-icon svg.ic { width: 18px; height: 18px; }
.circle-play svg.ic { width: 46px; height: 46px; filter: drop-shadow(0 2px 8px rgba(0,0,0,.5)); }
.mini-bar button svg.ic { width: 18px; height: 18px; }

/* ---- поиск по чатам ---- */
.conv-search {
  width: calc(100% - 16px);
  margin: 8px;
  background: var(--panel-2);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 8px 12px;
  color: var(--text);
  font-size: 14px;
  outline: none;
  /* длинный плейсхолдер («Поиск: чаты, сообщения, контакты…») на узком списке резался краем
     посреди слова («…конта»), без многоточия — режем многоточием */
  text-overflow: ellipsis;
}
.conv-search::placeholder { text-overflow: ellipsis; }
.conv-search:focus { border-color: var(--primary); }

/* ── Таб-фильтры списка: Все / Чаты / Группы / Тикеты ── */
/* Лента табов: ОДНА строка с горизонтальной прокруткой. Для ряда РАЗДЕЛОВ (#convTabs) прокрутка
   не страховка, а рабочий режим — 11 названных словами разделов в 280px не влезают (CLIE-1496·3,
   владелец: «давай сделаем в одну строку и добавим скролл»); чтобы за краем ничего не терялось,
   у неё есть выходы — подтаявший край и подвоз выбранного, см. блок #convTabs ниже. */
.conv-tabs { display: flex; gap: var(--tab-gap, 2px); padding: 0 8px 8px; overflow-x: auto; overflow-y: hidden;
  flex-wrap: nowrap; scrollbar-width: none; -ms-overflow-style: none;
  /* Подвоз выбранного (convTabScrollLead → scrollIntoView) не обязан ставить чип впритык к
     подтаявшему краю: отступ прокрутки даёт ему воздух, и слово читается целиком. */
  scroll-padding-inline: 18px;
  /* 🔴 scroll-snap УБРАН ОСОЗНАННО (визуальный добор CLIE-461, владелец: «всё дёргается»).
     Чипы шириной 27px снапить не за чем, зато КАЖДОЕ изменение ширин (развернулась подпись,
     включилась ступень .tight) заставляло браузер ПЕРЕСНАПИТЬ прокрутку — ряд уезжал вбок сам
     по себе, без участия человека. Прокрутка ленты остаётся обычной, инерционной. */
  /* Тон капсулы выделения. ОПАКОВЫЙ (mix с --panel, фоном сайдбара), а не полупрозрачный:
     соседние выбранные чипы сливаются в один «мазок» перекрытием на 3px с каждой стороны —
     у полупрозрачной заливки в месте нахлёста была бы тёмная полоса-шов. */
  --tabsel: color-mix(in srgb, var(--primary) 24%, var(--panel));
  --tabsel-hi: color-mix(in srgb, var(--primary) 34%, var(--panel));
  --tabsel-fg: var(--primary-2);
  /* Верх капсулы чуть светлее низа и тонкий кант по краю — «материал», а не плоская заливка
     (владелец о первой версии: «очень черновой вариант в плане визуала»). Оба параметра
     НЕПРЕРЫВНЫ вдоль ряда: градиент вертикальный, кант рисуется только по ВНЕШНИМ сторонам
     мазка (см. .run-l/.run-r ниже) — внутри склейки шва нет. */
  --tabsel-top: color-mix(in srgb, var(--primary) 31%, var(--panel));
  --tabsel-line: color-mix(in srgb, var(--primary) 44%, var(--panel));
  /* 🔀 Волосок ВНУТРИ слитой группы: на шаг плотнее канта, потому что лежит НА заливке, а не
     на панели. Он и отличает «группу из трёх разделов» от «одного длинного пятна» — см.
     .conv-tab::after. Значение не на глаз: пара 52/32 к канту 44/27, тот же шаг. */
  --tabsel-div: color-mix(in srgb, var(--primary) 52%, var(--panel));
  /* Геометрия ряда — ОДНИМ набором чисел: зазор между чипами, нахлёст капсул (им закрывается
     этот зазор у слитых), ширина подтаявшего края и радиус капсулы. Ряд со своей плотностью
     (#convTabs) переопределяет ИХ, а не переписывает правила капсулы заново. */
  --tab-gap: 2px; --tab-bridge: 3px; --tab-fade: 34px; --tab-cap-r: 10px; }
html[data-theme="light"] .conv-tabs { --tabsel: color-mix(in srgb, var(--primary) 14%, var(--panel));
  --tabsel-hi: color-mix(in srgb, var(--primary) 22%, var(--panel));
  --tabsel-top: color-mix(in srgb, var(--primary) 19%, var(--panel));
  --tabsel-line: color-mix(in srgb, var(--primary) 27%, var(--panel));
  --tabsel-div: color-mix(in srgb, var(--primary) 32%, var(--panel)); }
.conv-tabs::-webkit-scrollbar { height: 0; display: none; }
/* 🔴 ЛЕНТА, КОТОРАЯ НЕ ПРЯЧЕТ СЕБЯ. Колонка чатов узкая (--w-chats, по умолчанию 280px),
   чипов 7 — часть ВСЕГДА за краем. Полоса прокрутки здесь скрыта намеренно (она уродлива и
   ест 11px, см. rail-scrollbar-gutter), но без неё не остаётся НИ ОДНОГО признака, что за
   краем есть ещё вкладки: владелец так и не нашёл «Эфиры» — раздел был на экране, но за
   границей видимости. Лечим тем же приёмом, что Safari/App Store: край подтаивает маской,
   когда есть куда скроллить. Маска — на самой ленте (обёртки нет, DOM не трогаем), классы
   ставит convTabsEdges() по факту измерения, а не «на глазок». */
.conv-tabs.more-r { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--tab-fade, 34px)), transparent 100%);
  mask-image: linear-gradient(to right, #000 calc(100% - var(--tab-fade, 34px)), transparent 100%); }
.conv-tabs.more-l { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--tab-fade, 34px));
  mask-image: linear-gradient(to right, transparent 0, #000 var(--tab-fade, 34px)); }
.conv-tabs.more-l.more-r { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--tab-fade, 34px), #000 calc(100% - var(--tab-fade, 34px)), transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 var(--tab-fade, 34px), #000 calc(100% - var(--tab-fade, 34px)), transparent 100%); }
/* Идёт эфир — чип «Эфиры» не имеет права прятаться за краем: подсвечиваем его,
   а convTabsEdges() доскроллит ленту так, чтобы он был виден (см. app.js). */
.conv-tab.is-live { color: var(--text); }
/* 🔴🔴 СХЛОПЫВАНИЕ ПОДПИСИ ДО ВЕДУЩЕГО ЧИПА — МЕХАНИЗМ РЯДОВ БЕЗ `.words`. Он родился из
   требования «одна строка любой ценой»: подпись держал ТОЛЬКО ВЕДУЩИЙ чип (`.lead` = первый
   выбранный), остальные схлопывались до иконки, и ширина ряда не зависела от мультивыбора.
   🔴 РЯД РАЗДЕЛОВ ЭТОГО БОЛЬШЕ НЕ ДЕЛАЕТ (CLIE-1496): там слово есть у КАЖДОГО, а «одна
   строка» оплачена прокруткой, а не потерей имён. Механизм оставлен для рядов, где он честен:
   набор фиксирован, значок узнаваем и подпись не единственный способ понять раздел.
   🔴 Схлопывание — через max-width подписи, а НЕ display:none: иначе смена активного
   чипа была бы рывком и соседи прыгали бы. Переход 150ms — см. .conv-tab-l ниже. */
/* 🔴 НИ ОДИН чип не сжимается (flex: 0 0 auto) — ни иконка, ни подпись активного. Пробовал
   отдать подпись под flex-shrink «чтобы точно влезло»: измерение стенда показало, что она
   схлопывается в 0–2px, то есть у выбранного раздела ПРОПАДАЕТ имя, а ряд рапортует «влез».
   Это ровно тот обман, из-за которого «Эфиры» и потерялись. Правило: подпись либо видна
   целиком, либо ряд честно прокручивается (третья ступень, .more-l/.more-r). */
.conv-tab { position: relative; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  height: 28px; padding: 0 4px; border-radius: var(--tab-cap-r, 10px); border: 1px solid transparent; background: transparent;
  color: var(--muted); cursor: pointer; font-size: 12px; white-space: nowrap;
  /* 🔴 padding в transition НЕ входит осознанно. Ступень .tight меняет отступы, а решение
     о ней convTabsEdges() принимает ПО ИЗМЕРЕНИЮ сразу после смены класса — анимированный
     padding отдавал бы в этот момент ещё старое значение, ряд «не влезал» и ступень не
     срабатывала (поймано на стенде). Разворот чипа и так плавный: его несут max-width и
     margin подписи, а 2px отступа рядом с 40px подписи глазом не читаются. */
  transition: background .14s cubic-bezier(.4,0,.2,1), color .16s cubic-bezier(.4,0,.2,1),
    transform .12s cubic-bezier(.4,0,.2,1); }
/* 🔴🔴 КАПСУЛА ВЫДЕЛЕНИЯ — ОТДЕЛЬНЫЙ СЛОЙ (::before), А НЕ ЗАЛИВКА САМОГО ЧИПА (визуальный
   добор CLIE-461). Слой не участвует в раскладке: выделение появляется, растёт по ряду и
   гаснет, НИЧЕГО не сдвигая, поэтому его не страшно анимировать пружинкой прямо под курсором.
   Заливка + акцентный глиф вместо прежней 1px-обводки --primary: два обведённых квадратика
   рядом читались как «черновик», а мягкая капсула — как выделение в macOS. */
/* 🔴 АНИМИРУЕМ ТОЛЬКО opacity И transform — И ЭТО ПРИНЦИПИАЛЬНО. Их браузер крутит на
   КОМПОЗИТОРЕ: даже если главный поток занят тяжёлой пересборкой ленты чатов (замер на боевых
   данных: самый длинный кадр 150–450мс на 1800 строках), капсула продолжает ехать плавно. Стоит
   добавить сюда `left`/`right`/`border-radius` (геометрию склейки) — они считаются в главном
   потоке, замирают на этом же кадре и доезжают РЫВКОМ, то есть ровно то, на что жаловался
   владелец. Поэтому геометрия «мазка» меняется мгновенно (её всё равно не видно за появлением
   капсулы), а плавность несут прозрачность и пружинка. */
/* 🔴 ПЕРЕЕЗД КАПСУЛЫ — ЧЕРЕЗ ПЕРЕМЕННУЮ `--tab-dx`, И ЭТО НЕ УКРАШЕНИЕ. Смена раздела
   обычным кликом (99% нажатий) раньше читалась как «одна подсветка погасла, другая зажглась» —
   глаз не связывал их в одно движение, и ряд выглядел «черновым». Теперь applyConvTabSelState()
   ставит новому чипу `--tab-dx` = расстояние ДО ПРЕЖНЕГО выбранного (а уходящему — до нового):
   капсула ВЫЕЗЖАЕТ с прежнего места и уезжает к новому, как бегунок сегмент-контрола iOS.
   Переменная участвует в `transform`, поэтому переход по transform интерполирует её штатно —
   всё та же композиторная анимация, главный поток не участвует. */
/* 🔴 РАДИУС КАПСУЛЫ — ЧЕРЕЗ ТОКЕН `--tab-cap-r`, А НЕ ЧИСЛОМ В ПРАВИЛЕ РЯДА. Так и родились
   «сосиски», на которые пожаловался владелец (23.09.2026, скриншот группы «Чаты · Группы ·
   Задачи»): своя плотность ряда была записана как `#convTabs .conv-tab::before{border-radius:8px}`,
   а спрямление ВНУТРЕННИХ углов у слитых — как `.conv-tab.run-l::before{border-*-radius:0}`.
   Селектор с id весит больше двух классов и МОЛЧА побеждал: внутри «мазка» оба угла оставались
   круглыми, и группа читалась как связка сосисок, а не как одна капсула. Токен уравнивает вес:
   ряд меняет ЧИСЛО, спрямление остаётся за классами склейки. */
.conv-tab::before { content: ""; position: absolute; z-index: 0; inset: 0;
  border-radius: var(--tab-cap-r, 10px);
  background: linear-gradient(180deg, var(--tabsel-top) 0%, var(--tabsel) 100%);
  /* Кант — ЧЕТЫРЬМЯ ОТДЕЛЬНЫМИ inset-тенями, а не одним кольцом `inset 0 0 0 1px`. Кольцо
     рисуется по КАЖДОМУ чипу, а склеенные капсулы перекрываются на 3px — внутри «мазка»
     оставалась бы вертикальная волосинка-шов на каждом стыке. Стороны, которыми чип срастается
     с соседом, просто выключаются ниже (.run-l/.run-r) — снаружи кант непрерывный, внутри его нет.
     Цвет ОПАКОВЫЙ (mix с --panel): у полупрозрачного на скруглениях накладывались бы две
     «дольки» и углы темнели. */
  box-shadow: inset 0 1px 0 var(--tabsel-line), inset 0 -1px 0 var(--tabsel-line),
    inset 1px 0 0 var(--tabsel-line), inset -1px 0 0 var(--tabsel-line);
  opacity: 0; transform: translateX(var(--tab-dx, 0px)) scale(.62);
  transform-origin: var(--tab-org, center);
  transition: opacity .15s cubic-bezier(.4,0,.2,1),
    transform .3s cubic-bezier(.22,.9,.28,1.25);
  pointer-events: none; }
.conv-tab.active::before { opacity: 1; transform: translateX(var(--tab-dx, 0px)) scale(1); }
/* Служебный класс на один кадр: поставить капсулу в стартовую точку переезда БЕЗ анимации
   (у ::before инлайн-стиля не бывает — гасим переход классом). Снимается тут же, см. convTabTravel. */
.conv-tab.nodx::before { transition: none; }
/* Содержимое — НАД капсулой (::before рисуется поверх фона элемента, но под его детьми только
   если у детей есть свой слой; у svg/подписи его нет — задаём явно). */
.conv-tab > svg.ic { position: relative; z-index: 1; }
.conv-tab .conv-tab-l { position: relative; z-index: 1; }
.conv-tab svg.ic { width: 15px; height: 15px; flex: none; }
/* 🔴🔴 РАЗВЁРНУТ — РОВНО ОДИН ЧИП (.lead = первый выбранный), А НЕ «каждый выбранный».
   Раньше подпись носил КАЖДЫЙ активный: выбрал второй раздел — ряду понадобились две подписи,
   он не влезал в 280px, включались ступени .tight/.micro, подпись первого пропадала и весь ряд
   уезжал (замер: соседи прыгали на 65px вправо, через 280мс на 103px влево). Теперь ширина ряда
   зависит ТОЛЬКО от того, кто ведущий, и добавление/снятие разделов не двигает НИЧЕГО. */
.conv-tab.lead { padding: 0 6px; }
.conv-tab .conv-tab-l { display: block; max-width: 0; opacity: 0; margin-left: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: max-width .2s cubic-bezier(.4,0,.2,1), margin-left .2s cubic-bezier(.4,0,.2,1), opacity .14s linear; }
.conv-tab.lead .conv-tab-l { max-width: 110px; opacity: 1; margin-left: 5px; font-weight: 600; }
.conv-tab:hover { background: var(--panel-2); color: var(--text); }
.conv-tab.active, .conv-tab.active:hover { color: var(--tabsel-fg); background: transparent; }
/* Наведение на УЖЕ выбранный: капсула чуть плотнее — иначе выбранный чип единственный в ряду
   не отвечает на мышь (у остальных hover-подложка есть, у него её закрывает капсула). */
.conv-tab.active:hover::before { background: var(--tabsel-hi); }
/* Клавиатура: кольцо по контуру чипа, не сбивая раскладку (outline не занимает места). */
.conv-tab:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; border-radius: var(--tab-cap-r, 10px); }
/* 🔴 ОТКЛИК НА САМО НАЖАТИЕ (правило «нажал → изменил»): значок выбранного раздела коротко
   «клюёт». Раньше подтверждением была только смена цвета — на мелком глифе 15px её почти не
   видно, и клик читался как «ничего не произошло». Класс .pop живёт 280мс (снимает app.js по
   animationend), анимируется ТОЛЬКО transform → композитор, тяжёлый кадр ленты его не рвёт.
   Ставится лишь на явное нажатие/Ctrl-клик: под кистью разделы вспыхивают пачками, там пульс
   был бы визуальным шумом. */
@keyframes ccTabPop { 0% { transform: scale(1); } 42% { transform: scale(1.17); } 100% { transform: scale(1); } }
.conv-tab.pop > svg.ic { animation: ccTabPop .28s cubic-bezier(.34,1.4,.5,1); }
@media (prefers-reduced-motion: reduce) { .conv-tab.pop > svg.ic { animation: none; } }
/* Нажатие — тактильный отклик (правило «нажал → изменил»): чип чуть проседает. transform НЕ
   влияет на раскладку, но влияет на getBoundingClientRect — а по нему кисть снимает полосы
   чипов, поэтому на время жеста отклик гасим (иначе якорь «уже 93%» и попадание съедет). */
.conv-tab:active { transform: scale(.93); }
.conv-tabs.painting .conv-tab:active { transform: none; }
/* Счётчик «Все» дублирует «Новые» (тот же агрегат) → у НЕвыбранного «Все» его не показываем;
   у выбранного точное число остаётся инлайн. Раньше это решалось в разметке (dupAll) — но
   разметка обязана быть НЕЗАВИСИМОЙ от выбора, иначе ряд пересобирается на каждый клик. */
.conv-tab[data-ctab="all"]:not(.active) .conv-tab-n { display: none; }
/* 🔀 МУЛЬТИВЫБОР РАЗДЕЛОВ (CLIE-461: «нужно сразу несколько — например чаты и группы»).
   Ряд перестал быть радио-кнопкой: Ctrl/⌘-клик, протяжка мышью по соседям и долгий тап
   набирают НЕСКОЛЬКО разделов, список показывает их объединение.
   🔴 Выделение обязано читаться и БЕЗ подписей (подпись носит только ведущий чип): его
   несёт капсула-заливка + акцентный глиф, а соседние выбранные склеиваются в один «мазок»
   (.run-l/.run-r ниже) — группа видна одним взглядом, как выделение диапазона в Finder.
   user-select/touch-callout — чтобы протяжка по ряду не выделяла подписи текстом и не
   вызывала на телефоне системное меню поверх долгого тапа. */
.conv-tabs { user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
/* 🔀🔴 СЛИТЫЙ «МАЗОК»: соседние выбранные разделы — ОДНА непрерывная капсула, а не два
   отдельных квадратика впритык (как выделение диапазона дат в Календаре или диапазона строк
   в Finder). Внешние углы скруглены, внутренние — прямые, зазор 2px закрашивается нахлёстом
   по 3px с каждой стороны (заливка опаковая → шва не видно). Классы .run-l/.run-r ставит
   applyConvTabSelState() одним проходом по ряду — на глаз выбор читается как ОДНА группа. */
.conv-tab.run-l::before { left: calc(-1 * var(--tab-bridge, 3px)); border-top-left-radius: 0; border-bottom-left-radius: 0;
  box-shadow: inset 0 1px 0 var(--tabsel-line), inset 0 -1px 0 var(--tabsel-line), inset -1px 0 0 var(--tabsel-line); }
.conv-tab.run-r::before { right: calc(-1 * var(--tab-bridge, 3px)); border-top-right-radius: 0; border-bottom-right-radius: 0;
  box-shadow: inset 0 1px 0 var(--tabsel-line), inset 0 -1px 0 var(--tabsel-line), inset 1px 0 0 var(--tabsel-line); }
.conv-tab.run-l.run-r::before { box-shadow: inset 0 1px 0 var(--tabsel-line), inset 0 -1px 0 var(--tabsel-line); }
/* 🔀🔴 ВОЛОСОК НА СТЫКЕ — ТО, ЧЕГО ГРУППЕ НЕ ХВАТАЛО (владелец 23.09.2026: «сделай дизайн когда
   несколько объединены посимпатичнее»). Без него три выбранных раздела сливались в ОДНО длинное
   пятно, и «Чаты 46 Группы 7 Задачи 49» читались как одна фраза: где кончается один раздел и
   начинается другой — на глаз не разобрать, а нажимать надо по отдельности.
   Волосок стоит РОВНО в середине зазора (отсюда `--tab-gap / -2`), подрезан сверху и снизу на
   5px — не касается кромки капсулы, иначе он читался бы как разрез, а не как деление внутри
   одной группы (тот же приём, что у разделителя сегмента, --seg-div).
   🔴 Живёт на ::after, а НЕ добавочным слоем в background капсулы: фон ::before — это градиент
   «материала», и дописывать в него полоску пришлось бы, повторяя весь градиент в правиле
   склейки (две копии одного тона расходятся молча). ::after рисуется НАД капсулой и ПОД
   подписью (z-index 1 у .conv-tab-l) — буквы он не задевает.
   Появляется вместе с капсулой: пустой слой есть всегда, класс склейки только зажигает его,
   поэтому переход играет, а не «щёлкает». */
.conv-tab::after { content: ""; position: absolute; z-index: 0; top: 5px; bottom: 5px;
  left: calc(var(--tab-gap, 2px) / -2); width: 1px; border-radius: 1px;
  background: var(--tabsel-div); opacity: 0; pointer-events: none;
  transition: opacity .15s cubic-bezier(.4,0,.2,1); }
.conv-tab.run-l::after { opacity: 1; }
/* 🔴 СЕРЕДИНА МАЗКА НЕ ПРУЖИНИТ. Капсула появляется через scale(.62)→1; у чипа ВНУТРИ склейки
   это распирало бы его границы наружу и «мазок» дышал бы посередине. Внутренние звенья
   проявляются только прозрачностью, а форму держат края — растёт ровно вся группа. */
.conv-tab.run-l.run-r::before { transform: translateX(var(--tab-dx, 0px)) scale(1); }
/* Растём ОТ ТОЧКИ НАЖАТИЯ: чип правее якоря кисти распускается от левого края, левее — от правого.
   Мазок тянется за курсором, а не «проявляется пятнами» (--tab-org ставит applyConvTabSelState). */
.conv-tabs.painting .conv-tab::before { transition: opacity .11s cubic-bezier(.4,0,.2,1),
  transform .2s cubic-bezier(.22,.9,.28,1.1); }
/* 🔴 РЕЖИМ КИСТИ (зажали мышь и тянут по ряду). Раскладка ряда за жест не меняется НИ ОТ ЧЕГО:
   подпись носит только `.lead`, а его на время жеста замораживает app.js (`_paintLead`) —
   значит ширины чипов постоянны, а выделение живёт в отдельном слое-капсуле и ничего не двигает.
   Переходы гасить БОЛЬШЕ НЕ НУЖНО (раньше приходилось: подписи схлопывались прямо под курсором) —
   наоборот, именно они и рисуют «мазок», растущий за курсором. */
.conv-tabs.painting { cursor: grabbing; }
/* 🔴🔴 ИНДИКАТОР СВЁРНУТОГО ЧИПА — ТОЧКА, А НЕ ЧИСЛО (CLIE-379). Владелец: «Цифры перекрывают
   иконки и не понятно что там внутри». Так и было: счётчик стоял `top:0;right:0` поверх значка
   15px, а «99+» шириной ~22px закрывал его ЦЕЛИКОМ — раздел не узнать. В тесной иконочной ленте
   значок обязан оставаться читаемым, поэтому на свёрнутом чипе показываем ПРИСУТСТВИЕ (точку —
   «здесь есть новое»), а точное ЧИСЛО живёт там, где есть место: на ВЕДУЩЕМ чипе (инлайн, ниже)
   и в title/aria (наведение/скринридер). Тот же `<span class="conv-tab-n">` — просто прячем в нём
   цифры (`font-size:0`) и делаем его 7px-кружком: разметка НЕ меняется (identity-guard __tabsHtml,
   детект эфира по наличию .conv-tab-n и лесенка .tight/.micro остаются целы). Кольцо цветом панели
   отделяет точку от штрихов любого глифа в светлой И тёмной теме. Точка — в углу ЧИПА (top/right 4),
   где у центрированного значка ~6px «мёртвого» поля: садится максимально в сторону от тела глифа. */
.conv-tab-n { position: absolute; top: 3px; right: 3px; z-index: 1;
  width: 5px; height: 5px; min-width: 0; padding: 0; border-radius: 50%;
  background: var(--primary); box-shadow: 0 0 0 1.5px var(--panel);
  font-size: 0; line-height: 0; color: transparent; overflow: hidden;
  transition: box-shadow .16s cubic-bezier(.4,0,.2,1); }
/* Точка на ВЫБРАННОМ (но не ведущем) чипе стоит на капсуле — кольцо берём цветом капсулы,
   иначе вокруг точки светилось бы «окно» цвета панели поверх акцентной заливки. Именно ВЕРХНИМ
   тоном: точка сидит у верхней кромки, а заливка капсулы — вертикальный градиент, и плоский
   средний тон дал бы вокруг точки заметный ореол. */
.conv-tab.active .conv-tab-n { box-shadow: 0 0 0 1.5px var(--tabsel-top); }
/* 🔴 У ВЕДУЩЕГО чипа подпись развёрнута → место есть: тот же span становится ЧИСЛОВОЙ ПИЛЮЛЕЙ
   В СТРОКЕ после подписи (цифры возвращаются `font-size:9`, раскладка relative — никогда не
   поверх глифа). Полный сброс dot-свойств, чтобы «4»/«80»/«99+» рисовались как пилюля, а не
   кружок. 🔴 Ключ — именно `.lead`, а НЕ `.active`: инлайн-пилюля меняет ширину чипа, и будь
   она у каждого выбранного, ряд снова ехал бы на каждый Ctrl-клик. */
.conv-tab.lead .conv-tab-n { position: relative; top: auto; right: auto; margin-left: 5px;
  width: auto; height: 14px; min-width: 14px; padding: 0 4px; line-height: 14px;
  border-radius: 7px; box-shadow: none; overflow: visible;
  font-size: 9px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
/* Идёт эфир — точка/пилюля красная (правило ПОСЛЕ .conv-tab-n: равная специфичность, выигрывает
   последнее). Свёрнутая красная точка мягко «дышит» = «эфир прямо сейчас», отличая её от статичной
   accent-точки «непрочитано». Активная (в строке) — сплошная красная, без пульса. Уважаем
   prefers-reduced-motion. Каденс 1.8s — как таймерная точка (ccTimerPip/LiveTimerDot). */
.conv-tab.is-live .conv-tab-n { background: #e0245e; color: #fff; }
.conv-tab.is-live:not(.lead) .conv-tab-n { animation: convLivePulse 1.8s ease-in-out infinite; }
@keyframes convLivePulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.16); opacity: .6; } }
@media (prefers-reduced-motion: reduce) { .conv-tab.is-live .conv-tab-n { animation: none; } }
/* 🔴🔴 РЯД РАЗДЕЛОВ СПИСКА ЧАТОВ — СЛОВАМИ, В ОДНУ СТРОКУ, С ПРОКРУТКОЙ
   (CLIE-1496·3, владелец 23.09.2026: «Оставь вариант который сейчас. Но сделай дизайн когда
   несколько объединены посимпатичнее» → «Хотя нет, давай сделаем в одну строку и добавим скролл»).

   ЧТО БЫЛО ДО СЛОВ (раунд 1). Одиннадцать значков 15px в колонке 280px, словом назывался ТОЛЬКО
   открытый раздел (замер на проде: «видно словами 1 из 11»), 77px ряда уезжало за край, а
   лестница ужима `.tight/.micro` гасила и эту единственную подпись.

   ЧТО БЫЛО ПОСЛЕ СЛОВ (раунд 2). Слово получил КАЖДЫЙ раздел — и ряд поехал на строки: замер на
   живом проде 23.09.2026 дал ЧЕТЫРЕ строки и 121px высоты (не три, как считали при 9 разделах:
   «Ждут» и «Сделки» добавились позже). Три с лишним сантиметра шапки над списком бесед —
   слишком дорого, и владелец выбрал обратный размен явно.

   ЧТО СТАЛО (раунд 3). Слово у каждого раздела ОСТАЁТСЯ (это и просили сохранить), а ряд снова
   ОДНА СТРОКА — и не ужимается, а честно ПРОКРУЧИВАЕТСЯ. Размен назван вслух: ряд занимает 34px
   вместо 121px, зато часть разделов лежит за краем.
   🔴 Цена прокрутки оплачена ТРЕМЯ выходами, иначе это тот самый класс «раздел есть, найти
   нечем» (так когда-то потерялись «Эфиры»):
     1) край ПОДТАИВАЕТ маской (.more-l/.more-r), пока есть куда листать, — видно, что лента
        длиннее окна (полоса прокрутки здесь скрыта намеренно, см. выше);
     2) выбранный раздел САМ доезжает в кадр (convTabScrollLead), уступая руке;
     3) идёт эфир — чип «Эфиры» подвозится в кадр отдельно (convTabsEdgesNow).
   🔴 ЛЕСТНИЦА УЖИМА НЕ ВОЗВРАЩАЕТСЯ. Прокрутка и ужим — РАЗНЫЕ вещи: прокрутка показывает всё,
   просто не сразу, а ужим отнимал у раздела имя — ровно то, из-за чего задачу и завели.
   🔴 ОБЛАСТЬ ДЕЙСТВИЯ — РОВНО #convTabs. Рецепт «ряд словами» (подпись у каждого чипа, а не у
   одного ведущего) общий и живёт в `.conv-tabs.words` — его же носит ряд областей поиска
   (#searchScopes, CLIE-904), второй реализации не заводим. Различия между рядами — только
   собственная геометрия (токены --tab-*) и вид числа. */
.conv-tabs.words .conv-tab .conv-tab-l { max-width: none; opacity: 1; margin-left: 0; }
/* Своя плотность ряда — ТОЛЬКО через токены геометрии (см. .conv-tabs): зазор 4px, нахлёст
   капсул 4px (закрывает зазор ровно встык), край подтаивает на 26px (колонка узкая, 34px
   съедали бы целое слово), радиус капсулы 12px = ПОЛОВИНА высоты чипа, то есть пилюля.
   Пилюля здесь не косметика: у слитой группы прямые внутренние углы и круглые внешние читаются
   как ОДИН объект с крышками, а не как связка прямоугольников. */
#convTabs { padding: 1px 8px 9px;
  --tab-gap: 4px; --tab-bridge: 4px; --tab-fade: 26px; --tab-cap-r: 12px; }
#convTabs .conv-tab { height: 24px; padding: 0 9px; font-size: 12px; }
#convTabs .conv-tab .conv-tab-l { font-weight: 560; }
#convTabs .conv-tab.active .conv-tab-l { font-weight: 700; }
/* Число — акцентной цифрой СРАЗУ ЗА СЛОВОМ: точка/пилюля в углу были ответом на тесноту
   иконочного чипа, у словесного они стали бы вторым значком рядом со словом. */
#convTabs .conv-tab-n { position: static; margin-left: 4px; width: auto; height: auto; min-width: 0;
  padding: 0; border-radius: 0; background: none; box-shadow: none; overflow: visible;
  color: var(--primary-2); font-size: 10.5px; font-weight: 700; line-height: 1; }
/* Идёт эфир — единственное число, которое обязано кричать: красная пилюля, без пульса
   (пульс сдвигал бы соседние слова строки). */
#convTabs .conv-tab.is-live .conv-tab-n { padding: 0 5px; height: 14px; line-height: 14px;
  border-radius: 7px; background: #e0245e; color: #fff; animation: none; }
/* Отклик на само нажатие «клюёт» подписью: глифа у словесного чипа нет (был .conv-tab.pop > svg.ic). */
#convTabs .conv-tab.pop .conv-tab-l { display: inline-block; animation: ccTabPop .28s cubic-bezier(.34,1.4,.5,1); }
/* Уважаем системное «меньше движения»: капсула и подпись меняются мгновенно, без пружинки. */
@media (prefers-reduced-motion: reduce) {
  .conv-tab, .conv-tab::before, .conv-tab .conv-tab-l, .conv-tab .conv-tab-n { transition-duration: .01ms !important; }
}
/* строка-тикет в списке (вкладка «Тикеты») */
.tk-av { background: color-mix(in srgb, var(--primary) 18%, var(--panel-2)); display: flex; align-items: center; justify-content: center; color: var(--primary-2); }
.tk-av svg.ic { width: 20px; height: 20px; }
/* строка приватного чата задачи в списке «Все» — иконка красится в цвет статуса задачи
   (--conv-accent, задаётся инлайн на .conv-item), тон капсулы и иконки совпадают (0141). */
.tkc-av { background: color-mix(in srgb, var(--conv-accent, var(--urg-done)) 18%, var(--panel-2)); display: flex; align-items: center; justify-content: center; color: var(--conv-accent, var(--urg-done)); }
.tkc-av svg.ic { width: 19px; height: 19px; }
/* 💬 0367 · аватар строки ОБСУЖДЕНИЯ карточки CRM («С коллегами»): воронка у лида, портфель
   у сделки. Форма и размеры — те же, что у чата задачи (.tkc-av): это тот же класс «беседа
   про сущность», а не третья разметка кружка. Цвет — акцент продукта, подложка через
   color-mix, поэтому обе темы берутся одним правилом (канон «акцент блока»). */
.crmc-av { display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--primary) 16%, var(--panel-2)); color: var(--primary); }
.crmc-av-deal { background: color-mix(in srgb, var(--urg-done, #23a06b) 16%, var(--panel-2)); color: var(--urg-done, #23a06b); }
.crmc-av svg.ic { width: 19px; height: 19px; }
.tkc-proj { display: inline-flex; align-items: center; gap: 3px; }
.tkc-proj svg.ic { width: 11px; height: 11px; }
.conv-item.tkc-item.unread .conv-name { font-weight: 700; }
.conv-item.tk-item .conv-marks { display: flex; align-items: center; gap: 5px; }
/* поиск внутри модалки «Пользователи» — на всю ширину тела модалки */
.users-search { width: 100%; margin: 0 0 8px; }

/* ---- глобальный поиск: секции «Чаты / Сообщения / Контакты» ---- */
.search-section {
  list-style: none;
  padding: 10px 12px 4px; margin: 4px 0 0;
  font-size: 11px; font-weight: 700; color: var(--muted);
  text-transform: uppercase; letter-spacing: .04em;
}
.search-section:first-child { margin-top: 0; }
/* подгруппы результата: «В компании «X»» (акцент) → «Другие» (приглушённо).
   На уровень ниже секции: без CAPS, лёгкий вес, чуть меньше — читается как под-заголовок. */
.search-subsection {
  list-style: none;
  padding: 6px 12px 3px; margin: 0;
  font-size: 11.5px; font-weight: 600; letter-spacing: .01em; line-height: 1.2;
  color: var(--muted);
  display: flex; align-items: center; gap: 6px;
}
.search-subsection.in-company { color: var(--accent); }
.search-subsection .ss-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex: 0 0 auto;
}
.search-empty { padding: 14px; line-height: 1.4; }

/* 🔎 CLIE-1406 · «область не ответила» — это СОСТОЯНИЕ, а не пустота: строка не должна
   читаться как обычная серая подпись. Красим ролями темы (color-mix по --warn/--line),
   чтобы обе темы получились сами, без второго набора прибитых цветов. */
.search-down {
  padding: 12px 14px;
  line-height: 1.45;
  border-radius: 12px;
  margin: 6px 8px;
  background: color-mix(in srgb, var(--warn, #b26a00) 9%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn, #b26a00) 24%, transparent);
}
/* Отказ по праву — не авария: тон спокойный, «Повторить» у него и нет. */
.search-down.denied {
  background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.search-down .linklike { margin-left: 4px; }
/* 🔎 CLIE-904 · СНИППЕТ РЕЗУЛЬТАТА — ДВЕ СТРОКИ, А НЕ ОДНА С МНОГОТОЧИЕМ.
   Было `white-space:nowrap` + ellipsis: в 320-пиксельную рельсу влезало ~35 символов, а
   сервер клал совпадение на 61-й — совпавшие слова были ФИЗИЧЕСКИ за краем строки. Замер
   на живом проде (запрос владельца «ссылка на», 40 строк): видно 3 из 40. Теперь сервер
   даёт короткий разбег до совпадения (@snippet_lead), а строка — две строки по ширине. */
.search-snippet {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden; line-height: 1.35; word-break: break-word;
}
/* автор — ОТДЕЛЬНОЙ строкой над сниппетом: он не должен съедать место у самого текста */
.search-sender { color: var(--text); font-weight: 600; font-size: 11.5px; line-height: 1.3; }
/* верхняя строка результата: где нашлось (слева, режется) + когда (справа, не режется) */
.search-row-top { display: flex; align-items: baseline; gap: 8px; }
.search-row-top .conv-name {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.search-when { flex: 0 0 auto; font-variant-numeric: tabular-nums; }
/* «Найдено: N» и «Показать ещё» — состояние выдачи видно там же, где выдача */
.search-found { list-style: none; padding: 8px 12px 2px; margin: 0; }
.search-more { list-style: none; padding: 8px 12px 14px; margin: 0; text-align: center; }
.search-more .linklike, .search-empty .linklike {
  background: none; border: 0; padding: 4px 8px; cursor: pointer;
  color: var(--accent); font: inherit; font-weight: 600; border-radius: 8px;
}
.search-more .linklike:hover, .search-empty .linklike:hover { background: var(--panel-2); }

/* 🔎 ОБЛАСТИ ПОИСКА — ряд на месте #convTabs. Тот же контейнер (.conv-tabs), но подпись
   видна У ВСЕХ чипов: у папок подпись носит только ведущий (у них есть иконки), а у
   областей иконок нет — свернуть подпись значило бы показать пустые прямоугольники. */
/* 🔴 `hidden` ОБЯЗАН ПРЯТАТЬ. У `.conv-tabs` стоит `display:flex`, а правило браузера
   `[hidden]{display:none}` слабее любого селектора класса — то есть атрибут молча не
   работал, и в поиске на экране висели ДВА ряда сразу (снято кадром на проде: ряд
   областей и под ним живой ряд папок). Тот же класс, что СРЕД-34 «значения по умолчанию
   задаём МЫ»: полагаться на UA-правило нельзя. */
.conv-tabs[hidden], .search-filters[hidden] { display: none !important; }
.search-scopes .conv-tab { padding: 0 9px; }
/* подпись у каждого чипа — общий рецепт `.conv-tabs.words` (см. блок CLIE-1496·2 выше) */
.search-scopes .conv-tab.active .conv-tab-l { font-weight: 600; }
.search-scopes .conv-tab .conv-tab-n {
  position: relative; top: auto; right: auto; margin-left: 5px;
  width: auto; height: 14px; min-width: 14px; padding: 0 4px; line-height: 14px;
  border-radius: 7px; box-shadow: none; overflow: visible;
  font-size: 9px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums;
}
/* область, где по этому запросу НЕТ НИЧЕГО, гасим — но НЕ прячем: исчезнувший чип
   читается как «пропало», а погашенный честно говорит «тут пусто» (канон dead-rows). */
.search-scopes .conv-tab.dead { opacity: .42; }
.search-scopes .conv-tab.dead .conv-tab-n { background: var(--muted); }

/* Фильтры выдачи (автор · чат · дата) — КАНОНИЧЕСКИЕ пилюли тулбара (.tw-scope-btn), свой
   размер им НЕ навязываем: высота/радиус/кегль живут в --ctl-h/--ctl-r/--ctl-fs (CLIE-505).
   В узкой рельсе пилюли просто переносятся на вторую строку (СРЕД-33: не влезло — переносим,
   а не сжимаем контрол ниже его подписи). */
.search-filters {
  display: flex; flex-wrap: wrap; gap: 6px; padding: 0 8px 6px; margin: 0;
}
.search-filters .tw-scope-lbl { max-width: 118px; overflow: hidden; text-overflow: ellipsis; }
.search-inapp { color: var(--ok); }

/* 👋 CLIE-961 · ЧЕЛОВЕК, КОТОРОГО ЕЩЁ НЕТ В CLIENTSCHAT, — ВИДИМОЕ ДЕЙСТВИЕ В СТРОКЕ.
   Владелец: «нажал, а чат с ним не появляется… нужно ПОКАЗАТЬ ДИЗАЙНОМ это, а не просто
   ничего не делать». До правки строка несла ГОЛЫЙ ТЕЛЕФОН и не имела обработчика вовсе.
   Кнопка — как «Tap Invite next to the person» у WhatsApp и как в нашем же Flutter-поиске.
   🔴 Размеры берём у ряда (--ctl-*), своих чисел не заводим (канон control-size, CLIE-505).
   🔴 Чернила на подложке — var(--primary-2), а не var(--primary): акцентный ТЕКСТ на тинте
   меряется рантайм-аудитом контраста (канон contrast-runtime-audit). */
.search-invite-btn {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  height: calc(var(--ctl-h) - 6px); padding: 0 10px; border-radius: var(--ctl-r);
  font: inherit; font-size: calc(var(--ctl-fs) - 1px); font-weight: 600; cursor: pointer;
  color: var(--primary-2); background: color-mix(in srgb, var(--primary) 12%, transparent);
  border: 0; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 26%, transparent);
  transition: background .12s ease;
}
.search-invite-btn:hover { background: color-mix(in srgb, var(--primary) 20%, transparent); }
.search-invite-btn .ic { width: 14px; height: 14px; }
/* 🔴 СРЕД-33 «контрол не сжимается ниже своей подписи» — но и ИМЯ ЧЕЛОВЕКА не режем ради
   кнопки. Ширину МЕРЯЕМ (рельсу тянут мышью, медиазапрос смотрит на ОКНО и тут врёт):
   узкая строка → кнопка становится значком, слово уходит в подпись под именем, где для
   него есть место. Замер: пилюля со словом занимает ~112px из ~300px узкой рельсы. */
.search-contact { container-type: inline-size; }
@container (max-width: 330px) {
  .search-invite-btn span { display: none; }
  .search-invite-btn { padding: 0 9px; }
}
/* Уже звали — та же кнопка спокойнее и говорит другое слово (состояние, а не действие). */
.search-contact.invited .search-invite-btn {
  color: var(--muted); background: none;
  box-shadow: inset 0 0 0 1px var(--border);
}
/* Пригласить человека, которого нет НИ В КНИГЕ, ни в системе (набрали номер и не нашли
   никого): пустая выдача перестаёт быть тупиком — у неё есть выход. */
.search-empty .search-invite-num {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 10px;
  height: var(--ctl-h); padding: 0 12px; border-radius: var(--ctl-r);
  font: inherit; font-size: var(--ctl-fs); font-weight: 600; cursor: pointer;
  color: var(--primary-2); background: color-mix(in srgb, var(--primary) 12%, transparent);
  border: 0; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 26%, transparent);
}
.search-empty .search-invite-num .ic { width: 15px; height: 15px; }

/* подсветка совпадения запроса в имени/сниппете результата поиска */
.search-hl { color: var(--accent); font-weight: 700; }

/* 🔎 CLIE-1794 · ЦИТАТА ИЗ СОДЕРЖИМОГО ФАЙЛА (одна разметка на менеджер «Файлы» и глобальный
   поиск — её собирает ccFileHitHtml). Цвета — токенами, поэтому обе темы получают одно и то
   же без второго набора правил (канон theme-contrast). Подсвеченное внутри цитаты красит
   та же .search-hl, что и совпадение в имени: один язык выделения на весь поиск. */
.fs-hit { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text); opacity: .88; }
.fs-hit-tag { font-style: normal; color: var(--muted); margin-right: 6px; font-size: .92em; }
.fs-hit-tag::after { content: ":"; }

/* ---- настройки: уведомления ---- */
.settings-section { display: flex; flex-direction: column; gap: 10px; }
.settings-title { font-size: 16px; font-weight: 700; }
.settings-hint { margin: 0; line-height: 1.4; }
.notify-status {
  font-size: 16px; font-weight: 700; text-align: center;
  padding: 14px 12px; border-radius: 12px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.notify-status.on { color: var(--ok); border-color: rgba(34,197,94,.4); background: rgba(34,197,94,.08); }
.notify-status.off { color: var(--muted); }
.notify-status.blocked { color: var(--danger); border-color: rgba(239,68,68,.4); background: rgba(239,68,68,.08); }
.notify-help {
  margin: 0; padding: 12px 14px; border-radius: 10px; line-height: 1.45;
  background: rgba(239,68,68,.08); border: 1px solid rgba(239,68,68,.3);
  color: var(--text); font-size: 13px;
}
.notify-big-btn { width: 100%; margin: 0; padding: 14px; font-size: 15px; }
/* CLIE-1946 · светлая, настройки (вид кнопок задаёт <style> из app.js): прибитый #e5484d «Выйти» /
   «Выйти на всех остальных» на светлом — 3.6–3.9:1, ссылка-инструкция ИИ на своём тинте --primary — 3.8:1.
   Чернила тревоги — --danger-ink, акцент-чернила — --primary-2; тёмная не задета. */
html[data-theme="light"] #settingsModal .session-revoke,
html[data-theme="light"] #sessionsRevokeOthersBtn { color: var(--danger-ink); }
html[data-theme="light"] .ai-howto { color: var(--primary-2); }

/* ---- настройки: подключить Telegram (синхронизация личного аккаунта) ---- */
.tg-connect { display: flex; flex-direction: column; gap: 12px; }
.tg-card {
  display: flex; flex-direction: column; gap: 14px;
  padding: 16px; border-radius: 14px;
  background: var(--panel-2); border: 1px solid var(--line);
}
.tg-card.tg-ok { border-color: rgba(34,197,94,.35); background: rgba(34,197,94,.06); }
.tg-card > p { margin: 0; line-height: 1.45; }
.tg-row { display: flex; align-items: flex-start; gap: 12px; }
.tg-row > div { min-width: 0; }
.tg-row b { display: block; font-weight: 650; }
.tg-dot {
  flex: 0 0 auto; width: 9px; height: 9px; margin-top: 5px; border-radius: 50%;
  background: var(--muted);
}
.tg-dot.on  { background: var(--ok); box-shadow: 0 0 0 4px rgba(34,197,94,.15); }
.tg-dot.mid { background: #f0b34e; box-shadow: 0 0 0 4px rgba(240,179,78,.15); }
.tg-steps { margin: 2px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 7px; font-size: 13px; color: var(--muted); line-height: 1.4; }
.tg-steps li { padding-left: 2px; }
.tg-steps b { color: var(--text); font-weight: 600; }
.tg-hint { margin: 0 0 4px; color: var(--muted); line-height: 1.45; }
.tg-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.tg-actions .notify-big-btn { width: auto; flex: 1 1 auto; padding: 12px 16px; }
.tg-link {
  align-self: flex-start; margin-top: 4px; font-size: 13px; font-weight: 600;
  color: #229ED9; text-decoration: none;
}
.tg-link:hover { text-decoration: underline; }

/* ── CLIE-934: НЕСКОЛЬКО личных Telegram-аккаунтов ──────────────────────────────
   Строка аккаунта в настройках: точка состояния · имя (правится ПО КЛИКУ, канон
   inline-edit — без карандаша и без «Сохранить») · подпись · действия. */
.tg-accs { display: flex; flex-direction: column; gap: 0; }
.tg-acc {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 0; border-top: 1px solid var(--line);
}
.tg-acc:first-child { border-top: 0; padding-top: 2px; }
.tg-acc > div { min-width: 0; flex: 1 1 auto; }
/* цветная точка аккаунта — цвет приходит С СЕРВЕРА (Business.color_of/1), своей
   палитры у клиента нет: две копии разъехались бы (CLIE-881). */
.tg-acc-dot { flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; }
.tg-acc-name {
  font-weight: 620; border-radius: 6px; padding: 1px 4px; margin: -1px -4px;
  cursor: text; outline: none; word-break: break-word;
}
.tg-acc-name:hover { background: var(--hover); }
.tg-acc-name:focus { background: var(--panel); box-shadow: 0 0 0 2px var(--glow); }
.tg-acc-sub { font-size: 12.5px; color: var(--muted); line-height: 1.35; margin-top: 1px; }
.tg-acc-acts { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; }
.tg-add { align-self: flex-start; }

/* бейдж «из Telegram» у строки чата */
.conv-src-tg {
  display: inline-flex; vertical-align: -2px; margin-right: 4px; color: #229ED9;
}
/* 📡 CRMC-709 · ЯДРО КАНАЛОВ: значок канала у строки чата рисуется по РЕЕСТРУ (любой канал,
   не только Telegram), поэтому цвет приезжает инлайном из ответа сервера и перебивает
   прибитый #229ED9 выше. Класс `.conv-src-tg` остаётся на том же узле НАМЕРЕННО — на нём
   висит раскладка (отступ, выравнивание), и второй копии этих правил заводить незачем. */
.conv-src-ch > svg, .conv-src-ch .ic { width: 13px; height: 13px; flex: 0 0 auto; }
/* ── CLIE-934: МЕТКА «из какого Telegram-аккаунта» — строка списка и шапка чата.
   Показывается, ТОЛЬКО когда сервер прислал `tg_account` (а он присылает его лишь
   при ДВУХ и более подключённых аккаунтах). Цвет — из ответа сервера. */
.conv-tg-acc, .thread-tg-acc {
  display: inline-flex; align-items: center; gap: 4px; flex: 0 0 auto;
  max-width: 140px; padding: 1px 7px 1px 5px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; line-height: 1.5;
  border: 1px solid currentColor; background: color-mix(in srgb, currentColor 12%, transparent);
}
.conv-tg-acc > span, .thread-tg-acc > span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.conv-tg-acc::before, .thread-tg-acc::before {
  content: ""; flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%;
  background: currentColor;
}
.thread-tg-acc { max-width: 180px; }

/* Первый вход: одно-кнопочная карточка включения уведомлений. */
.notify-prompt {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 12px; max-width: 340px; padding: 32px 26px;
  animation: notifyPromptIn .28s cubic-bezier(.2,.8,.2,1);
}
@keyframes notifyPromptIn {
  from { opacity: 0; transform: translateY(14px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
/* Иконка-колокол в градиентном круге (вместо эмодзи) + лёгкий «звон» при появлении. */
.notify-prompt-icon {
  width: 78px; height: 78px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--acc-grad);
  box-shadow: 0 10px 26px color-mix(in srgb, var(--primary) 42%, transparent);
  margin-bottom: 4px;
}
.notify-prompt-icon svg {
  width: 38px; height: 38px; stroke: #fff;
  transform-origin: 50% 18%;
  animation: bellRing 1.1s ease .35s 1;
}
@keyframes bellRing {
  0%, 100% { transform: rotate(0); }
  12% { transform: rotate(14deg); }
  24% { transform: rotate(-11deg); }
  36% { transform: rotate(8deg); }
  48% { transform: rotate(-5deg); }
  60% { transform: rotate(2deg); }
}
.notify-prompt-title { font-size: 18px; font-weight: 700; }
.notify-prompt-sub { font-size: 13px; margin-bottom: 8px; }
.notify-prompt .notify-big-btn { max-width: 260px; }
/* Уважаем «уменьшить движение». */
@media (prefers-reduced-motion: reduce) {
  .notify-prompt, .notify-prompt-icon svg { animation: none; }
}

/* ---- настройки: профиль ---- */
.profile-section { padding-bottom: 16px; margin-bottom: 16px; border-bottom: 1px solid var(--line); }
.profile-avatar-row { display: flex; align-items: center; gap: 14px; }
.profile-avatar {
  width: 64px; height: 64px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-size: 30px; background: var(--panel-2); border: 1px solid var(--line);
  background-size: cover; background-position: center; overflow: hidden;
}
.profile-avatar.has-img { border-color: var(--primary); cursor: pointer; }
.profile-avatar-actions { display: flex; flex-direction: column; gap: 4px; }

/* ---- настройки группы: аватар (фото/видео) ---- */
.gs-avatar-row { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.gs-avatar {
  width: 72px; height: 72px; border-radius: 50%; flex: none;
  display: flex; align-items: center; justify-content: center;
  font-size: 32px; background: var(--panel-2); border: 1px solid var(--line);
  background-size: cover; background-position: center; overflow: hidden;
}
.gs-avatar.has-img { border-color: var(--primary); }
.gs-avatar video { width: 100%; height: 100%; object-fit: cover; display: block; }
.gs-avatar-actions { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.profile-status {
  font-size: 13px; text-align: center; padding: 8px 10px; border-radius: 8px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
}
.profile-status.ok { color: var(--ok); border-color: rgba(34,197,94,.4); background: rgba(34,197,94,.08); }
.profile-status.error { color: var(--danger); border-color: rgba(239,68,68,.4); background: rgba(239,68,68,.08); }

/* ---- аудиозвонок: та же плашка, чуть приглушённый акцент ---- */
.call-btn-audio { margin-right: 0; }

/* ======================================================================= *
 *  ГАЛЕРЕЯ ПРОФИЛЯ (фото/видео «о себе») + просмотр профиля + лайтбокс
 * ======================================================================= */
.profile-gallery-block { margin-top: 14px; }
.profile-gallery {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 6px; margin: 8px 0;
}
.profile-gallery .gi {
  position: relative; aspect-ratio: 1; border-radius: 10px; overflow: hidden;
  background: var(--panel-2); border: 1px solid var(--line); cursor: pointer;
}
.profile-gallery .gi img { width: 100%; height: 100%; object-fit: cover; display: block; }
.profile-gallery .gi .gi-play {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  font-size: 22px; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,.6); pointer-events: none;
}
.profile-gallery .gi .gi-del {
  position: absolute; top: 3px; right: 3px; width: 22px; height: 22px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 13px; line-height: 1;
  color: #fff; background: rgba(8,10,14,.66); cursor: pointer;
}
.profile-gallery .gi .gi-del:hover { background: var(--danger, #ef4444); }
.profile-gallery .gi-empty { grid-column: 1 / -1; padding: 10px 2px; }

/* шапка профиля пользователя */
.profile-avatar.lg { width: 92px; height: 92px; font-size: 42px; }
.user-profile-head { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 6px 0 14px; }
.user-profile-name { font-size: 20px; font-weight: 700; color: var(--text); text-align: center; }
.user-profile-bio { color: var(--text); font-size: 14px; line-height: 1.4; margin: 10px 0; white-space: pre-wrap; }

/* лайтбокс: полноэкранный просмотр фото/видео */
/* z-index 90 был НИЖЕ файлового браузера (.fsb-dim 9670): «Открыть»/Пробел по картинке в пикере
   открывали лайтбокс ЗА модалкой — визуально «ничего не произошло», а Esc закрывал не то (CLIE-409). */
.lightbox-overlay {
  position: fixed; inset: 0; z-index: 9700; background: rgba(0,0,0,.92);
  display: flex; align-items: center; justify-content: center; padding: 16px;
}
/* 📝🎬 CLIE-1136·2: `position: relative` — слой Live Text (.lb-ocr) кладётся offset-координатами
   картинки; `.lb-fade` включает затухание фона ТОЛЬКО на время полёта кадра (свайп-вниз красит
   фон инлайном на каждый кадр — там переход был бы лагом). `.lb-closing` прячет хром, пока кадр
   летит обратно в ячейку. Клип-путь и матрица полёта — инлайном из lbFlipOpen/closeLightbox. */
.lightbox-content { max-width: 96vw; max-height: 92vh; display: flex; position: relative; }
.lightbox-overlay.lb-fade { transition: background-color .22s ease; }
.lightbox-overlay.lb-closing .lb-prev, .lightbox-overlay.lb-closing .lb-next, .lightbox-overlay.lb-closing .lb-counter,
.lightbox-overlay.lb-closing .lightbox-close,
.lightbox-overlay.lb-closing .lb-acts { opacity: 0; pointer-events: none; transition: opacity .14s ease; }
@media (prefers-reduced-motion: reduce) {
  .lightbox-overlay.lb-fade { transition: none; }
  .lightbox-overlay .lightbox-content { transition: none !important; }
}
.lightbox-content img, .lightbox-content video { max-width: 96vw; max-height: 92vh; object-fit: contain; border-radius: 6px; }
/* 🔍 CLIE-1136 ЗУМ КАДРА. `will-change` держит слой на GPU — увеличенная картинка едет за
   пальцем без единого пропущенного кадра («отклик моментальный»). `touch-action: none` на
   увеличенном кадре забирает жест у страницы, иначе браузер начинает свой скролл-зум и
   картинка дёргается. Курсор сам рассказывает, что кадр можно приблизить и возить. */
.lightbox-content img { cursor: zoom-in; will-change: transform; transform-origin: center center; }
.lightbox-overlay.lb-zoomed .lightbox-content img { cursor: grab; }
.lightbox-overlay.lb-zoomed .lightbox-content { touch-action: none; }
.lightbox-close {
  position: absolute; top: 14px; right: 16px; width: 40px; height: 40px; border-radius: 50%;
  border: none; cursor: pointer; font-size: 18px; color: #fff; background: rgba(255,255,255,.14);
}
.lightbox-close:hover { background: rgba(255,255,255,.26); }
/* 🔴 13.10.2026: крестик — над кадром, как и ряд действий `.lb-acts` (z-index 2). Без этого высокий кадр
   (картинка — позиционированный сосед ПОЗЖЕ в разметке) рисовался поверх него: от креста оставалась «V». */
.lightbox-close { z-index: 2; }
/* листалка: стрелки ‹ › по краям + счётчик «i / N» снизу */
.lightbox-overlay .lb-prev, .lightbox-overlay .lb-next {
  position: absolute; top: 50%; transform: translateY(-50%); width: 48px; height: 48px;
  border-radius: 50%; border: none; cursor: pointer; color: #fff; background: rgba(255,255,255,.14);
  font-size: 30px; line-height: 1; display: flex; align-items: center; justify-content: center;
  z-index: 2; -webkit-user-select: none; user-select: none;
}
.lightbox-overlay .lb-prev { left: 16px; }
.lightbox-overlay .lb-next { right: 16px; }
.lightbox-overlay .lb-prev:hover, .lightbox-overlay .lb-next:hover { background: rgba(255,255,255,.26); }
/* «Сохранить» медиа на устройство — круглая кнопка слева от крестика (top-right) */
/* Круглые действия кадра: «Сохранить на компьютер» (CLIE-202 «Поделиться» рядом) и
   «Сохранить в Файлы ClientsChat» (CLIE-692 — до неё выход у кадра был только на диск ПК).
   ОДНО правило вида на все три: разъехавшись, они читались бы как из разных приложений. */
/* 🖼 CLIE-1048 добавил к ним «Изменить» (нарисовать поверх фото) и «Вернуть оригинал» —
   ТЕМ ЖЕ правилом вида: пять кнопок одного кадра обязаны читаться как одна панель. */
/* 📝 CLIE-1136·2 добавил шестую — «Текст на картинке» (Live Text): тем же правилом, слот 314px. */
/* ↪️ CLIE-1714: седьмая кнопка («Переслать») добила прибитые позиции. Теперь ряд —
   ОДИН flex-контейнер `.lb-acts`, растущий ВЛЕВО от крестика (`row-reverse`): скрытая
   кнопка выпадает из раскладки САМА (раньше на её месте оставалась дыра — напр. у
   фото без сохранённого оригинала между «Изменить» и «Текст»), а ряд не уезжает за
   край узкого телефона. Клик МИМО кнопок = фон (закрывает кадр), поэтому указатель
   ловят только кнопки, а не контейнер. */
.lightbox-overlay .lb-acts {
  position: absolute; top: 14px; right: 64px; z-index: 2;
  display: flex; flex-direction: row-reverse; align-items: center; gap: 10px;
  pointer-events: none;
}
.lightbox-overlay .lb-acts > button {
  position: relative; flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%;
  border: none; cursor: pointer; color: #fff; background: rgba(255,255,255,.14);
  display: flex; align-items: center; justify-content: center; pointer-events: auto;
  transition: background var(--motion-fast,.14s) var(--ease-standard,ease);
}
.lightbox-overlay .lb-acts > button:hover { background: rgba(255,255,255,.26); }
.lightbox-overlay .lb-acts > button:active { transform: scale(.92); }
.lightbox-overlay .lb-acts > button svg.ic { width: 19px; height: 19px; display: block; }
/* ↪️ CLIE-1714: «Сохранить на компьютер» носит значок на пиксель крупнее остальных (так
   было с CLIE-202). В ряду правило соседей стало специфичнее, поэтому исключение названо
   ПОСЛЕ них и тем же адресом — иначе 20px молча превратились бы в 19px. */
.lightbox-overlay .lb-acts > button.lb-dl svg.ic { width: 20px; height: 20px; }
/* «Готовлю картинку…»: кадр качается секунды — кнопка обязана СКАЗАТЬ, что работа идёт
   (правило №8: «нажал — ничего» запрещено). Кольцо-прогресс вместо подмены иконки. */
/* 📝 CLIE-1136·2: то же кольцо у «Текст на картинке», пока сервер распознаёт (1–3 с). */
.lightbox-overlay .lb-edit.busy, .lightbox-overlay .lb-text.busy { pointer-events: none; opacity: .75; }
.lightbox-overlay .lb-edit.busy::after, .lightbox-overlay .lb-text.busy::after {
  content: ""; position: absolute; inset: -3px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.28); border-top-color: #fff;
  animation: lb-edit-spin .8s linear infinite;
}
@keyframes lb-edit-spin { to { transform: rotate(360deg); } }
/* Live Text включён — кнопка «горит» акцентом (как у Telegram: белый кружок с тёмной иконкой). */
.lightbox-overlay .lb-text.on { background: #fff; color: #111; box-shadow: 0 0 0 2px rgba(255,255,255,.35); }
.lightbox-overlay .lb-text.on:hover { background: #f2f2f2; }
/* 📝 Слой распознанного текста: РОВНО по коробке картинки (left/top/width/height ставит
   lbOcrSync), матрица зума — та же, что у <img> (lbZoomApply). Строки — мягкая подсветка,
   слова — прозрачный текст, который выделяется как обычный; подсвечивается только выделение.
   Клики МИМО слов проваливаются к картинке (зум, панорама, свайп остаются живыми). */
.lightbox-overlay .lb-ocr {
  position: absolute; z-index: 1; pointer-events: none; transform-origin: center center;
  will-change: transform; --lbh: 100px;
}
.lightbox-overlay .lb-ocr-line {
  position: absolute; border-radius: 3px; background: rgba(255,255,255,.10);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.22);
  animation: lb-ocr-in .18s ease both;
}
@keyframes lb-ocr-in { from { opacity: 0; } to { opacity: 1; } }
.lightbox-overlay .lb-ocr-w {
  position: absolute; display: block; pointer-events: auto; cursor: text;
  color: transparent; -webkit-text-fill-color: transparent;
  white-space: nowrap; line-height: 1; overflow: visible;
  transform-origin: 0 50%;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; font-weight: 500;
  -webkit-user-select: text; user-select: text;
}
.lightbox-overlay .lb-ocr-w::selection { background: color-mix(in srgb, var(--primary) 45%, transparent); background: color-mix(in srgb, var(--primary) 45%, transparent); color: transparent; -webkit-text-fill-color: transparent; }
.lightbox-overlay .lb-ocr-w::-moz-selection { background: color-mix(in srgb, var(--primary) 45%, transparent); color: transparent; }
.lightbox-overlay.lb-ocr-on .lightbox-content img { cursor: default; }
/* нижняя пилюля «Скопировать всё · Готово» и плавающая «Скопировать» у выделения */
.lightbox-overlay .lb-ocr-bar {
  position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); z-index: 3;
  display: flex; align-items: center; gap: 4px; padding: 4px;
  background: rgba(28,28,30,.78); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-radius: 999px; box-shadow: 0 8px 24px -8px rgba(0,0,0,.6), inset 0 0 0 1px rgba(255,255,255,.08);
  animation: lb-ocr-in .18s ease both;
}
.lightbox-overlay .lb-ocr-bar button {
  border: 0; cursor: pointer; color: #fff; background: transparent; font: inherit; font-size: 13px; font-weight: 600;
  height: 34px; padding: 0 14px; border-radius: 999px; display: inline-flex; align-items: center; gap: 7px; white-space: nowrap;
  transition: background .14s ease, transform .07s ease;
}
.lightbox-overlay .lb-ocr-bar button svg.ic { width: 16px; height: 16px; }
.lightbox-overlay .lb-ocr-bar button:hover { background: rgba(255,255,255,.14); }
.lightbox-overlay .lb-ocr-bar button:active { transform: scale(.96); }
.lightbox-overlay .lb-ocr-bar .lb-ocr-done { background: #fff; color: #111; }
.lightbox-overlay .lb-ocr-bar .lb-ocr-done:hover { background: #ececec; }
/* 📷➡️🔤 CLIE-1972: текст без координат (дочитало зрение) — панель над пилюлей, выделяемая */
.lightbox-overlay .lb-ocr-plain {
  position: absolute; left: 50%; bottom: 72px; transform: translateX(-50%); z-index: 3;
  width: min(560px, calc(100% - 32px)); max-height: 42vh; overflow: auto; overscroll-behavior: contain;
  padding: 14px 16px; border-radius: 16px; color: #fff; font-size: 15px; line-height: 1.4;
  white-space: pre-wrap; word-break: break-word; -webkit-user-select: text; user-select: text; cursor: text;
  background: rgba(28,28,30,.82); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 8px 24px -8px rgba(0,0,0,.6), inset 0 0 0 1px rgba(255,255,255,.08);
  animation: lb-ocr-in .18s ease both;
}
.lightbox-overlay .lb-ocr-plain::selection { background: color-mix(in srgb, var(--primary) 45%, transparent); }
.lightbox-overlay .lb-ocr-pill {
  position: fixed; z-index: 9710; transform: translate(-50%, -100%);
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 14px;
  border: 0; border-radius: 999px; cursor: pointer; color: #fff; font: inherit; font-size: 13px; font-weight: 600;
  background: rgba(28,28,30,.92); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 8px 22px -8px rgba(0,0,0,.65), inset 0 0 0 1px rgba(255,255,255,.1);
  white-space: nowrap; animation: lb-ocr-in .14s ease both;
}
.lightbox-overlay .lb-ocr-pill.below { transform: translate(-50%, 0); }
.lightbox-overlay .lb-ocr-pill svg.ic { width: 16px; height: 16px; }
.lightbox-overlay .lb-ocr-pill:hover { background: rgba(48,48,52,.95); }
.lightbox-overlay .lb-ocr-pill:active { transform: translate(-50%, -100%) scale(.96); }
.lightbox-overlay .lb-ocr-pill.below:active { transform: translate(-50%, 0) scale(.96); }
.lightbox-overlay .lb-counter {
  position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%);
  color: #fff; font-size: 14px; font-variant-numeric: tabular-nums;
  background: rgba(0,0,0,.45); padding: 4px 12px; border-radius: 999px; z-index: 2;
}
@media (max-width: 540px) {
  .lightbox-overlay .lb-prev { left: 6px; }
  .lightbox-overlay .lb-next { right: 6px; }
}
/* 📝 CLIE-1136·2: на узком телефоне круглые действия ужимаются, чтобы ряд не уходил
   за край. ↪️ CLIE-1714: ужимаем РЯД (размер кнопки + зазор), а не каждую позицию —
   поэтому седьмая кнопка не требует седьмой строки, и ряд честно считает свою ширину. */
/* 🔴 13.10.2026 (ревью кадров, телефон): ряд кнопок кадра и сам кадр делили верх экрана — картинка
   начиналась на y≈34 под кнопками высотой до 50, а полупрозрачные круги на 92 % фоне пропускали шапку
   приложения («99+», «Все проекты»). На узком экране кадр стоит НИЖЕ ряда (поле сверху = ряд + воздух),
   фон сплошной, круги — сплошные (тон того же «белого 14 % на чёрном»). Свайп вниз по-прежнему красит
   фон инлайном — инлайн сильнее, после жеста возвращается этот сплошной. */
@media (max-width: 720px) {
  .lightbox-overlay {
    background: #000;
    padding-top: calc(64px + env(safe-area-inset-top, 0px));
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  }
  .lightbox-content, .lightbox-content img, .lightbox-content video {
    max-height: calc(100vh - 76px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
    max-height: calc(100dvh - 76px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));
  }
  .lightbox-close, .lightbox-overlay .lb-acts { top: calc(14px + env(safe-area-inset-top, 0px)); }
  .lightbox-close, .lightbox-overlay .lb-acts > button { background: #252527; }
  .lightbox-close:hover, .lightbox-overlay .lb-acts > button:hover { background: #424245; }
}
@media (max-width: 420px) {
  .lightbox-close { width: 36px; height: 36px; right: 10px; }
  .lightbox-overlay .lb-acts { right: 54px; gap: 8px; }
  .lightbox-overlay .lb-acts > button { width: 36px; height: 36px; }
  .lightbox-overlay .lb-ocr-bar { bottom: max(14px, env(safe-area-inset-bottom, 0px)); }
  .lightbox-overlay .lb-ocr-plain { bottom: calc(max(14px, env(safe-area-inset-bottom, 0px)) + 56px); }
}

/* имя автора в группе — кликабельно (открывает профиль) */
.sender-name[data-uid] { cursor: pointer; }
.sender-name[data-uid]:hover { text-decoration: underline; }

/* ───────────── Запись коллабов: кнопка, индикатор, список, отчёт ───────────── */
/* активная кнопка записи в панели созвона — красная */
/* Кнопка записи активна — фирменный индиго + красная точка-бейдж (НЕ красная, как «Выйти»). */
#gcRecBtn.recording { color: #fff; background: var(--acc-grad); border-color: transparent; }
#gcRecBtn.recording::before { content: ""; position: absolute; top: 5px; right: 5px; width: 8px; height: 8px; border-radius: 50%; background: var(--danger); box-shadow: 0 0 0 2px var(--cm-1b1e27, #1b1e27); }
/* индикатор «● REC 0:00» в шапке созвона */
.gc-rec-dot {
  display: inline-flex; align-items: center; gap: 4px; margin-left: 10px;
  color: var(--danger); font-size: 12px; font-weight: 600;
  animation: gcRecBlink 1.4s ease-in-out infinite;
}
@keyframes gcRecBlink { 0%,100% { opacity: 1; } 50% { opacity: .45; } }

/* секция записей в «Управление группой» */
.gs-recordings { margin-top: 6px; }
.rec-list { max-height: 240px; overflow-y: auto; }
.rec-item {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 10px; border-radius: 10px;
}
.rec-item:hover { background: var(--panel-2); }
.rec-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
.rec-icon { font-size: 18px; flex: none; }
.rec-meta { min-width: 0; line-height: 1.25; }
.rec-actions { display: flex; align-items: center; gap: 6px; flex: none; }

/* модалка отчёта */
.rec-report-box { max-width: 760px; width: 94vw; }
.rec-report-body { max-height: 64vh; overflow-y: auto; }
.rec-report-body h4 { margin: 16px 0 6px; font-size: 13px; color: var(--primary-2); }
.rec-report-body ul { margin: 0; padding-left: 20px; }
.rec-report-body li { margin: 4px 0; }
.rec-summary { margin: 0 0 4px; line-height: 1.45; }
/* Встроенный плеер записи в модалке отчёта — смотреть прямо тут, не только скачивать. */
.rec-player {
  display: block; width: 100%; margin: 0 0 14px; border-radius: 10px;
  background: #000; outline: none;
}
.rec-video { max-height: 46vh; }
/* Видео записи + СВОЯ кнопка «на весь экран». Нативный фуллскрин <video> внутри модалки
   с backdrop-filter в Chromium не разворачивается — прячем сломанную нативную кнопку и
   даём свою (⛶ → openLightbox, единый полноэкранный плеер приложения). */
.rec-video-wrap { position: relative; display: block; margin: 0 0 14px; }
.rec-video-wrap .rec-video { margin: 0; }
.rec-video::-webkit-media-controls-fullscreen-button { display: none !important; }
.rec-fs-btn {
  position: absolute; top: 10px; right: 10px; width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 9px; cursor: pointer; color: #fff;
  background: var(--cm-090b10-55, rgba(9, 11, 16, .55));
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  opacity: .9; transition: opacity .12s ease, background .12s ease;
}
.rec-fs-btn:hover { opacity: 1; background: var(--cm-090b10-74, rgba(9, 11, 16, .74)); }
.rec-fs-btn .ic, .rec-fs-btn svg { width: 18px; height: 18px; }
.rec-audio { background: var(--panel-2); }
.rec-regen-wrap { margin: 12px 0 4px; }
.rec-regen { display: inline-flex; align-items: center; gap: 6px; }
.rec-tasks { list-style: none; padding-left: 0 !important; margin: 4px 0 0; }
.rec-task { padding: 10px 0; border-bottom: 1px solid var(--line); }
.rec-task:last-child { border-bottom: 0; }
.rec-task-head { display: flex; align-items: center; gap: 10px; }
.rec-task-ck { flex: 0 0 auto; width: 17px; height: 17px; accent-color: var(--primary); cursor: pointer; }
/* Инлайн-правка заголовка: поле невидимо, тонкий хэйрлайн проявляется на hover/focus. */
.rec-task-title {
  flex: 1 1 auto; min-width: 0; font: inherit; color: var(--text);
  background: transparent; border: 0; border-bottom: 1px solid transparent;
  padding: 3px 2px; border-radius: 4px;
  transition: border-color .13s ease, background .13s ease;
}
.rec-task-title::placeholder { color: var(--muted); }
.rec-task-title:hover { border-bottom-color: var(--line); }
.rec-task-title:focus {
  outline: none; border-bottom-color: var(--primary);
  background: color-mix(in srgb, var(--primary) 7%, transparent);
}
/* Снят чекбокс → задача гаснет: мгновенная обратная связь «нажал → изменил». */
.rec-task:has(.rec-task-ck:not(:checked)) .rec-task-title { opacity: .45; text-decoration: line-through; }
.rec-task:has(.rec-task-ck:not(:checked)) .rec-task-meta { opacity: .45; }
.rec-task-meta {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 8px 0 0 27px;
}
.rec-task-as { flex: 0 1 auto; max-width: 220px; }
.rec-task-duewrap {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--muted); font-size: 13px; cursor: pointer;
}
.rec-task-duewrap svg, .rec-task-duewrap .ic { width: 15px; height: 15px; opacity: .75; }
.rec-task-due {
  display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px;
  font: inherit; font-size: 13px; color: var(--muted); background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 8px; cursor: pointer; white-space: nowrap;
  font-variant-numeric: tabular-nums; transition: border-color .13s ease, color .13s ease;
}
.rec-task-due.on { color: var(--text); }
.rec-task-due:hover { border-color: var(--line-strong); color: var(--text); }
.rec-task-due:focus-visible { outline: none; border-color: var(--primary); }
.rec-task-hint { color: var(--muted); font-size: 12px; font-style: italic; }
.rec-transcript-wrap { margin-top: 16px; }
.rec-transcript-wrap summary { cursor: pointer; color: var(--muted); font-size: 13px; }
.rec-transcript {
  margin-top: 8px; padding: 10px; border-radius: 10px; background: var(--panel-2);
  white-space: pre-wrap; line-height: 1.5; font-size: 13px; color: var(--text);
}
.rec-report-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rec-report-foot a { text-decoration: none; }

/* ── M3: кликабельная расшифровка с тайм-кодами ─────────────────────────────
 * Реплика = строка «тайм-код · текст». Тайм-код — моноширинный (tabular-nums),
 * чтобы колонка не «плясала». Активная реплика — тонкая акцентная полоса слева
 * и мягкая подложка (без жирной заливки на всю строку). 4/8-сетка, хэйрлайны. */
.rec-tr { margin-top: 18px; }
.rec-tr-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.rec-tr-head h4 { margin: 0 0 6px; }
.rec-tr-hint { color: var(--muted); font-size: 12px; flex: none; }
.rec-tr-list {
  max-height: 300px; overflow-y: auto; overscroll-behavior: contain;
  border: 1px solid var(--line); border-radius: 12px; padding: 4px;
  background: var(--panel-2); scroll-behavior: smooth;
}
.rec-tr-seg {
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  padding: 6px 8px; border: none; border-radius: 8px; background: transparent;
  color: var(--text); text-align: left; font: inherit; cursor: pointer;
  position: relative; transition: background-color .14s ease, color .14s ease;
}
.rec-tr-seg + .rec-tr-seg { margin-top: 1px; }
.rec-tr-seg:hover { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.rec-tr-seg:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.rec-tr-t {
  flex: none; min-width: 46px; font-size: 12px; font-weight: 600;
  font-variant-numeric: tabular-nums; color: var(--muted);
  padding-top: 1px; letter-spacing: .01em; transition: color .14s ease;
}
.rec-tr-x { flex: 1 1 auto; min-width: 0; font-size: 13.5px; line-height: 1.5; }
.rec-tr-seg.on { background: color-mix(in srgb, var(--primary) 12%, transparent); }
.rec-tr-seg.on .rec-tr-t { color: var(--primary); }
.rec-tr-seg.on::before {
  content: ""; position: absolute; left: 2px; top: 7px; bottom: 7px; width: 2px;
  border-radius: 2px; background: var(--primary);
}

/* ── M3: чип шаблона разбора (прогрессивное раскрытие) ──────────────────── */
.rec-tpl { margin: 0 0 12px; }
.rec-tpl.busy { opacity: .55; pointer-events: none; }
.rec-tpl-cur {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--panel-2); color: var(--muted); font: inherit; font-size: 12.5px;
  cursor: pointer; transition: border-color .14s ease, color .14s ease, background-color .14s ease;
}
.rec-tpl-cur b { color: var(--text); font-weight: 600; }
.rec-tpl-cur:hover { border-color: var(--primary); color: var(--text); }
.rec-tpl-cur svg.ic { width: 14px; height: 14px; flex: none; }
.rec-tpl-cur svg.ic:last-child { transition: transform .16s ease; opacity: .7; }
.rec-tpl.open .rec-tpl-cur svg.ic:last-child { transform: rotate(180deg); }
.rec-tpl-opts { display: none; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.rec-tpl.open .rec-tpl-opts { display: flex; }
.rec-tpl-opt {
  padding: 5px 11px; border: 1px solid var(--line); border-radius: 999px;
  background: transparent; color: var(--text); font: inherit; font-size: 12.5px;
  cursor: pointer; transition: border-color .14s ease, background-color .14s ease;
}
.rec-tpl-opt:hover { border-color: var(--primary); }
.rec-tpl-opt.on { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 14%, transparent); font-weight: 600; }

/* ── M3: настройки интеллекта встреч (над списком записей) ──────────────── */
.meet-set { margin: 0 0 10px; }
.meet-set-cur {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 7px 10px; border: 1px solid var(--line); border-radius: 10px;
  background: transparent; color: var(--muted); font: inherit; font-size: 12.5px;
  cursor: pointer; text-align: left; transition: border-color .14s ease, background-color .14s ease;
}
.meet-set-cur:hover { border-color: var(--primary); }
.meet-set-cur b { color: var(--text); font-weight: 600; }
.meet-set-cur span { flex: 1 1 auto; min-width: 0; }
.meet-set-cur svg.ic { width: 14px; height: 14px; flex: none; opacity: .75; }
.meet-set-cur svg.ic:last-child { transition: transform .16s ease; }
.meet-set-cur.open svg.ic:last-child { transform: rotate(180deg); }
.meet-set-body {
  margin-top: 8px; padding: 10px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel-2); display: flex; flex-direction: column; gap: 10px;
}
.meet-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.meet-row-lb { font-size: 13px; color: var(--text); }
.meet-tpl {
  font: inherit; font-size: 13px; color: var(--text); background: var(--panel);
  border: 1px solid var(--line); border-radius: 8px; padding: 4px 8px; cursor: pointer;
}
.meet-tpl:focus { outline: none; border-color: var(--primary); }
/* Тумблер в стиле системных: дорожка 34×20, кружок 16, мягкая анимация.
   🔴 Дорожка ВЫКЛЮЧЕННОГО — ЧЕРНИЛА, а не хэйрлайн (канон theme-contrast-runtime: «токен линии —
   не токен чернил»). На `--line` она была 1.06 к подложке `.meet-set-body` в тёмной теме (прод
   16.10.2026, «Разбор встреч»): видно только белый кружок, положение не читается. Тот же рецепт,
   что у тумблера на стекле (`.dz-pane .cc-switch-tr`): 24 % `--text` поверх подложки — ≈2.0 в
   тёмной и ≈1.6 в светлой; включённая дорожка — прежняя `--primary`. */
.meet-sw { display: flex; align-items: center; gap: 10px; cursor: pointer; }
.meet-sw input { position: absolute; opacity: 0; width: 0; height: 0; }
.meet-sw-tr {
  flex: none; width: 34px; height: 20px; border-radius: 999px;
  background: color-mix(in srgb, var(--text) 24%, transparent);
  position: relative; transition: background-color .16s ease;
}
.meet-sw-tr::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.28);
  transition: transform .16s cubic-bezier(.4,0,.2,1);
}
.meet-sw input:checked + .meet-sw-tr { background: var(--primary); }
.meet-sw input:checked + .meet-sw-tr::after { transform: translateX(14px); }
.meet-sw input:focus-visible + .meet-sw-tr { outline: 2px solid var(--primary); outline-offset: 2px; }
.meet-sw-lb { font-size: 13px; color: var(--text); line-height: 1.3; }

/* ── M4 · оглавление встречи (главы) + имя спикера в реплике ────────────────
 * Главы — те же кнопки .rec-tr-seg (одна реализация перемотки), поэтому наследуют
 * состояния hover/focus/on; здесь только своя раскладка «таймкод | заголовок+подпись».
 * Имя спикера — компактная строка над текстом реплики, цвет аватара хэшируется по имени
 * (совпадает с живой панелью субтитров и Flutter). Обе темы — на токенах. */
.rec-ch-wrap { margin-top: 16px; }
.rec-ch-list {
  border: 1px solid var(--line); border-radius: 12px; padding: 4px;
  /* 🔴 CLIE-620: был `max-height:240px;overflow-y:auto` — родной брат капа, который уже
     сняли у «Записей коллабов». Тело отчёта (`.rec-report-body`) скроллится само, а здесь
     240px прятали всё после 4–5 главы под НЕВИДИМЫЙ бегунок: оглавление встречи для того и
     существует, чтобы видеть встречу целиком. Растёт вместе с содержимым. */
  background: var(--panel-2); overscroll-behavior: contain;
}
.rec-ch .rec-ch-b { display: flex; flex-direction: column; gap: 2px; min-width: 0; text-align: left; }
.rec-ch-title { font-size: 13.5px; font-weight: 600; line-height: 1.35; }
.rec-ch-sum { font-size: 12.5px; color: var(--muted); line-height: 1.4; }

.rec-tr-who { display: inline-flex; align-items: center; gap: 6px; margin-right: 8px; font-weight: 600; font-size: 12.5px; }
.rec-tr-av {
  width: 18px; height: 18px; flex: 0 0 18px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700; color: #fff;
  background: hsl(var(--h,220) 52% 48%); box-shadow: inset 0 0 0 1px rgba(255,255,255,.12);
}

/* ============================================================== *
 *  ЗАДАЧНИК — рабочее пространство (Список / Плитки / Доска-канбан)
 *  Оверлей поверх области справа от рельса (96px). Открывается из
 *  рельса «Задачи», из шапки группы и из заголовка столбика задач.
 * ============================================================== */
.chat { position: relative; }                 /* контекст для абсолютного оверлея */
.tasks-workspace {
  position: absolute; inset: 0 0 0 var(--rail-track); z-index: 40;
  background: var(--bg); display: flex; flex-direction: column; min-height: 0;
}
.tasks-workspace.hidden { display: none; }

.tw-head { display: flex; align-items: center; gap: 12px; padding: 12px 16px 12px; border-bottom: 1px solid var(--line); }
.tw-title { font-size: 18px; font-weight: 650; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; flex: 0 1 auto; }
.tw-count { color: var(--muted); font-size: 13px; flex: 0 0 auto; }
.tw-spacer { flex: 1; }
/* «＋ Задача» — резиновая: тянется по остатку строки, но сжимается ПЕРВОЙ
   (высокий flex-shrink), уступая место заголовку и сегментам. Без этого
   .primary{width:100%} распирал шапку и левый контент не влезал. */
#twNew { width: auto; margin-top: 0; flex: 1 100 auto; min-width: 116px; white-space: nowrap; }
#twClose { flex: 0 0 auto; }
.tw-seg { flex: 0 0 auto; display: flex; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 2px; gap: 2px; }
.tw-seg button { display: flex; align-items: center; gap: 6px; background: transparent; border: none; color: var(--muted); padding: 7px 12px; border-radius: 8px; cursor: pointer; font-size: 13px; transition: background .12s, color .12s; }
.tw-seg button .ic { width: 16px; height: 16px; }
.tw-seg button:hover { color: var(--text); }
/* Активное состояние .tw-seg (переключатель вида: Список/Плитки/Доска/Таймлайн/Схема)
   задаёт ЕДИНЫЙ таб-движок ниже (#twSeg — подчёркивание, .cc-tabs; прочие .tw-seg —
   iOS-thumb, .cc-seg): и фон, и цвет активной вкладки = var(--text) в ОБЕИХ темах.
   🔴 Иконка активной вкладки НАСЛЕДУЕТ цвет текста (currentColor), а НЕ #fff: старое
   правило `.ic{color:#fff}` осталось от прежней «залитой» вкладки и в СВЕТЛОЙ теме делало
   иконку белой на светлом/прозрачном фоне → она ИСЧЕЗАЛА (CLIE-380: «активная белым, не
   видно»). Фон/цвет самой кнопки здесь не трогаем — их перекрывают #twSeg/.cc-seg ниже. */
.tw-seg button.active .ic { color: inherit; }
.tw-seg .tw-seg-label { } /* на узких — скрываем подпись (см. медиа) */

.tw-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; padding: 10px 16px; border-bottom: 1px solid var(--line); }
/* рамка ряда пилюль задач — прозрачна для раскладки (пилюли = дети тулбара); ленту из неё
   делает только «Глубина» на телефоне (depth.css TP6) */
.tw-fstrip { display: contents; }
.tw-filter-group { display: flex; align-items: center; gap: 6px; }
/* кастом-селект (не голый <select>): chevron + focus-ring (правило «дизайн=UX») */
select.tw-select {
  appearance: none; -webkit-appearance: none;
  background: var(--panel-2) var(--sel-chev-sm) no-repeat right 9px center;
  border: 1px solid var(--line); color: var(--text); border-radius: var(--ctl-r);
  padding: 7px 28px 7px 11px; font-size: var(--ctl-fs); cursor: pointer; max-width: 220px;
  min-height: var(--ctl-h); box-sizing: border-box;
  transition: border-color .12s, box-shadow .12s;
}
select.tw-select:hover { border-color: var(--primary); }
select.tw-select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.tw-chips { display: flex; gap: 4px; flex-wrap: wrap; }
/* Подписанная группа фильтра-чипов (Статус / Важность). Раньше чипы шли БЕЗ подписи и терялись
   среди кнопок-списков — владелец не находил «Статус» (CLIE-393). Подпись слева = группа сразу
   читается как отдельный фильтр, единообразно с v2-fl-lbl. Разделитель-хэйрлайн слева отделяет
   её от соседних контролов, не отбирая экран. */
.tw-fl { display: inline-flex; align-items: center; gap: 8px; padding-left: 10px; border-left: 1px solid var(--line); }
.tw-fl-lbl { font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; user-select: none; flex: none; }
/* 🔴 CLIE-505: чип тулбара — тот же РАЗМЕРНЫЙ КЛАСС, что соседние пилюли/поле/кнопки
   (--ctl-h / --ctl-r / --ctl-fs). Был на 2px ниже и на полкегля мельче соседей. */
.tw-chip {
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
  min-height: var(--ctl-h); box-sizing: border-box;
  padding: 6px 12px; border-radius: var(--ctl-r); font-size: var(--ctl-fs); cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.tw-chip:hover { color: var(--text); }
.tw-chip.active { background: var(--acc-grad); color: #fff; border-color: transparent; }
/* «Сбросить» — тонкий чип с крестиком, появляется лишь когда фильтр активен. По умолчанию
   приглушён (как остальные неактивные чипы), на hover уводит в семью --danger: сразу читается
   как «убрать/очистить», но без агрессивной заливки. Работает и в светлой, и в тёмной теме. */
.tw-reset-chip { display: inline-flex; align-items: center; gap: 5px; }
.tw-reset-chip svg.ic { width: 13px; height: 13px; flex: none; }
.tw-reset-chip:hover {
  color: var(--danger, #e5484d);
  border-color: color-mix(in srgb, var(--danger, #e5484d) 45%, var(--line));
  background: color-mix(in srgb, var(--danger, #e5484d) 9%, transparent);
}
.tw-reset-chip:focus-visible { outline: none; border-color: var(--danger, #e5484d); box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger, #e5484d) 22%, transparent); }
/* Поиск + действия (Архив/Выбрать) — своя строка на всю ширину тулбара: поиск слева
   умеренной ширины, кнопки прижаты вправо (margin-left:auto). Раньше .tw-search был
   flex:1 и распирался на весь ряд, не оставляя места кнопкам. */
/* 🔴 CLIE-805: НЕ ВЛЕЗЛО — ПЕРЕНОСИМ, А НЕ ПРЯЧЕМ ПОД КНОПКИ. Замер на живом проде (окно 920px,
   тулбар 824px): поле `#twSearch` имело ширину 150px, из которых 142px лежали ПОД «Архив/Выбрать»,
   `elementFromPoint` в центре поля возвращал чужой SPAN — то есть поиска на экране не было вовсе,
   а из-под кнопок торчал огрызок плейсхолдера (ровно скрин владельца). Причина: строка поиска
   сжималась (`min-width:0`) вместо переноса, а `.tw-toolbar-acts` был `flex:none` и не уступал
   ни пикселя. Лечение — ЛЕСТНИЦА (СРЕД-33): пока влезает — один ряд; не влезло — строка поиска
   уезжает на свою линию, а кнопки-действия переносятся под неё. Без брейкпоинтов: решает ЗАМЕР
   самого флексбокса, а не ширина окна (тулбар живёт и в узкой колонке проекта, и под А+). */
.tw-search-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex: 1 1 100%; min-width: 0; }

/* ─────────────────────────────────────────────────────────────────────────────
   🔴🔴 CLIE-1298 · СТРОКА РЕЗУЛЬТАТОВ ПОИСКА ЗАДАЧ («сколько нашлось и из каких мест»).
   Одна разметка на весь веб (taskFoundBarHtml): доска/список и столбик «Мои задачи».
   Тон — служебный: это ПОДПИСЬ под поиском, а не ещё один ряд фильтров, поэтому чипы
   мельче тулбарных (--ctl-* здесь НЕ берём осознанно: строка не стоит в одном ряду с
   полем и пилюлями, она под ними; canon-exception: control-size — другой ряд).
   Цвета — только токены темы: строка обязана читаться и в светлой, и в тёмной.
   ───────────────────────────────────────────────────────────────────────────── */
.tw-found-row { padding: 0 16px; }
.tw-found-row.on { padding: 8px 16px 9px; border-bottom: 1px solid var(--line); }
.cc-found { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 12.5px; color: var(--muted); }
.cc-found-n { display: inline-flex; align-items: center; gap: 6px; color: var(--text); font-weight: 600; white-space: nowrap; }
.cc-found-n b { font-weight: 800; }
.cc-found-n svg.ic { width: 14px; height: 14px; flex: none; color: var(--muted); }
.cc-found-diff { color: var(--muted); }
/* 🔴 CLIE-1839: мягкое совпадение названо словами, а не оставлено на догадку. */
.cc-found-soft { color: var(--muted); }
.cc-found-l { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); white-space: nowrap; }
.cc-found-sep { width: 1px; align-self: stretch; min-height: 14px; background: var(--line); }
.cc-found-chip {
  display: inline-flex; align-items: center; gap: 5px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted);
  border-radius: 999px; padding: 3px 9px; font-size: 12px; line-height: 1.35; cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.cc-found-chip svg.ic { width: 12px; height: 12px; flex: none; }
.cc-found-chip b { color: var(--text); font-weight: 700; }
.cc-found-chip:hover { color: var(--text); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.cc-found-chip.on {
  color: var(--text);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  border-color: color-mix(in srgb, var(--primary) 45%, var(--line));
}
.cc-found-chip.on b { color: var(--primary); }
.cc-found-chip:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--glow); }
.cc-found-act {
  background: transparent; border: 0; color: var(--primary); cursor: pointer;
  font-size: 12px; padding: 3px 8px; border-radius: 8px;
}
.cc-found-act:hover { background: color-mix(in srgb, var(--primary) 12%, transparent); }
.cc-found-act:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--glow); }
.cc-found-empty .cc-found-n { color: var(--text); }
.cc-found-wait { opacity: .75; }
.tw-search {
  flex: 1 1 auto; min-width: 150px; max-width: 360px; background: var(--panel-2); border: 1px solid var(--line);
  color: var(--text); border-radius: var(--ctl-r); padding: 7px 12px; font-size: var(--ctl-fs);
  min-height: var(--ctl-h); box-sizing: border-box;
}
.tw-search:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
/* Лупа поиска задач — та же, что у «Поиск проектов…» (.pcat-search: значок 16px, --muted). Кадр 21.10:
   плейсхолдер «Поиск задач…» начинался у края поля (x≈137), у соседнего поиска проектов слева лупа.
   Значок лежит поверх поля (справа в обёртке живёт сегмент «Название | Везде»), поле отодвигает текст. */
.tw-search-wrap { position: relative; }
.tw-search-wrap > svg.ic { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--muted); pointer-events: none; }
.tw-search-wrap > svg.ic + .tw-search { padding-left: 36px; }
/* proj-members-search-1 · поиск «Участников» — та же лупа, что у «Поиск задач…»/«Поиск файлов»: значок
   первым ребёнком ряда, поле стоит в ряду первым, поэтому left 12px = внутри поля. Класс .tw-search-wrap
   не берём — его ищет глобальный querySelector доски задач (wsSyncQSeg). */
.v2mem-searchrow { position: relative; }
.v2mem-searchrow > svg.ic { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: var(--muted); pointer-events: none; }
.v2mem-searchrow > svg.ic + .v2mem-search { padding-left: 36px; }
/* Кнопки-действия: прижаты вправо, но при нехватке ширины переносятся (сами по себе они не
   сжимаются — .tw-tool-btn это flex:none, и раньше блок просто наезжал на поле поиска). */
.tw-toolbar-acts { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: 8px; margin-left: auto; flex: 0 1 auto; }
/* Кнопки-действия тулбара (иконка+подпись). НЕ .tw-select — то правило для голых <select>
   рисует фоновый шеврон и +34px правого паддинга → на кнопке был фантомный «вниз» и перекос. */
.tw-tool-btn {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  border-radius: var(--ctl-r); padding: 7px 12px; font-size: var(--ctl-fs); cursor: pointer;
  min-height: var(--ctl-h); box-sizing: border-box;
  transition: border-color .12s, box-shadow .12s, color .12s;
}
.tw-tool-btn:hover { border-color: var(--primary); }
.tw-tool-btn:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.tw-tool-btn svg.ic { width: 15px; height: 15px; flex: none; color: var(--muted); }
.tw-tool-btn.active { color: var(--primary); border-color: var(--primary); }
.tw-tool-btn.active svg.ic { color: var(--primary); }
/* «Идёт» — тумблер задач с моим запущенным таймером. Активное состояние в семье var(--info)
   (а не --primary), чтобы кнопка читалась как один объект с бейджем таймера, который она
   фильтрует. Тонкая рамка + мягкая подложка, без сплошной заливки. */
.tw-run-btn:hover { border-color: var(--info); }
.tw-run-btn:focus { border-color: var(--info); box-shadow: 0 0 0 3px var(--info-soft); }
.tw-run-btn.active { color: var(--info); border-color: var(--info); background: var(--info-soft); }
.tw-run-btn.active svg.ic { color: var(--info); animation: wipPulse 1.8s ease-in-out infinite; }
.tw-run-btn.active span { font-variant-numeric: tabular-nums; font-weight: 600; }
/* «Ждёт ответа» — тумблер задач, где ИИ остановился и ждёт человека (awaiting/pending).
   Янтарная семья (#f59e0b) — ровно та же, что у пилюли .ai-waiting, полосы .ai-strip-await
   и баннера карточки: фильтр, бейдж и баннер обязаны читаться как ОДИН объект. Тонкая рамка +
   мягкая подложка, без сплошной заливки; иконка в неактивном состоянии уже подсвечена янтарём —
   чип появляется, только когда ждать действительно есть чего, и обязан звать глазом. */
.tw-await-btn svg.ic { color: #f59e0b; }
.tw-await-btn:hover { border-color: rgba(245,158,11,.55); }
.tw-await-btn:focus { border-color: rgba(245,158,11,.55); box-shadow: 0 0 0 3px rgba(245,158,11,.18); }
.tw-await-btn.active { color: #f4bd63; border-color: rgba(245,158,11,.5); background: rgba(245,158,11,.12); }
.tw-await-btn.active svg.ic { color: #f4bd63; }
.tw-await-btn span { font-variant-numeric: tabular-nums; }
.tw-await-btn.active span { font-weight: 600; }
html[data-theme="light"] .tw-await-btn svg.ic { color: #d97706; }
html[data-theme="light"] .tw-await-btn:hover { border-color: rgba(217,119,6,.5); }
html[data-theme="light"] .tw-await-btn:focus { border-color: rgba(217,119,6,.5); box-shadow: 0 0 0 3px rgba(217,119,6,.16); }
html[data-theme="light"] .tw-await-btn.active { color: #b45309; border-color: rgba(217,119,6,.42); background: rgba(217,119,6,.10); }
html[data-theme="light"] .tw-await-btn.active svg.ic { color: #b45309; }

/* Область задач — кнопка-триггер поискового пикера (замена голого <select>). */
.tw-scope-btn {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  border-radius: var(--ctl-r); padding: 7px 10px 7px 11px; font-size: var(--ctl-fs); cursor: pointer;
  min-height: var(--ctl-h); box-sizing: border-box;
  max-width: 260px; min-width: 150px; transition: border-color .12s, box-shadow .12s;
}
.tw-scope-btn:hover { border-color: var(--primary); }
.tw-scope-btn:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.tw-scope-btn .tw-scope-lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-scope-btn svg.ic { width: 15px; height: 15px; flex: none; }
.tw-scope-btn svg.ic:first-child { color: var(--muted); }
.tw-scope-btn svg.ic:last-child { color: var(--muted); opacity: .8; }
/* 🤝 CLIE-1046·2 — пилюля «Общие с <Имя>» на странице задач. Своего размера не заводит:
   это тот же .tw-scope-btn (--ctl-h/--ctl-r/--ctl-fs), только всегда акцентная (фильтр
   включён по определению — он и есть причина, по которой страницу открыли) и со снятием
   на ✕. Акцент — подложка + цвет, НЕ левая рейка (правило акцента). */
.tw-peer-pill {
  color: var(--primary); cursor: pointer; max-width: 320px;
  border-color: color-mix(in srgb, var(--primary) 40%, var(--line));
  background: color-mix(in srgb, var(--primary) 12%, var(--panel-2));
}
.tw-peer-pill svg.ic:first-child { color: var(--primary); }
.tw-peer-pill .tw-peer-n {
  flex: none; font-size: 11.5px; font-weight: 650; line-height: 1;
  padding: 3px 6px; border-radius: 999px; color: var(--primary);
  background: color-mix(in srgb, var(--primary) 16%, transparent);
}
.tw-peer-pill .tw-peer-x {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; margin-left: 1px; border-radius: 50%;
  color: var(--muted); transition: background .12s ease, color .12s ease;
}
.tw-peer-pill .tw-peer-x svg.ic { width: 13px; height: 13px; color: inherit; }
.tw-peer-pill .tw-peer-x:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); color: var(--primary); }
.tw-peer-pill .tw-peer-x:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--glow); }

/* 🤝 CLIE-1293 · ПОДПИСЬ СОСТОЯНИЯ страницы «задачи с человеком»: «компания шапки эту страницу
   не сужает — N из M вне неё». Своя линия тулбара (flex: 1 1 100% — тот же приём, что у
   .tw-search-row), тон СЛУЖЕБНЫЙ: это подпись под фильтрами, а не ещё один ряд контролов,
   поэтому --ctl-* здесь не берём (canon-exception: control-size — другой ряд). Цвета только
   токенами: читается в обеих темах. Акцент — подложка и кольцо, НЕ левая рейка (CLIE-483). */
.tw-peer-note {
  flex: 1 1 100%; min-width: 0; display: flex; align-items: center; gap: 8px;
  margin: -2px 0 2px; padding: 6px 10px; border-radius: 10px;
  font-size: 12.5px; line-height: 1.35; color: var(--muted);
  background: color-mix(in srgb, var(--primary) 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 20%, transparent);
}
.tw-peer-note svg.ic { flex: none; width: 15px; height: 15px; color: var(--primary); }
.tw-peer-note b { color: var(--text); font-weight: 650; }

.tw-scope-pop {
  /* z-index 13850: пикер якорится к КОНТЕКСТУ, который может быть в шторке сделки (121)
     или в модалке (.pm-scrim 13800) — иначе попап уезжает ПОД них (CRMC-30/1). */
  position: fixed; z-index: 13850; background: var(--panel-3, var(--panel-2)); border: 1px solid var(--line);
  border-radius: 14px; padding: 8px; box-shadow: 0 12px 32px rgba(0,0,0,.28), 0 3px 10px rgba(0,0,0,.18);
  display: flex; flex-direction: column; gap: 6px;
  box-sizing: border-box; max-height: calc(100dvh - 24px);
}
.tw-scope-search { position: relative; display: flex; align-items: center; }
.tw-scope-search svg.ic { position: absolute; left: 10px; width: 15px; height: 15px; color: var(--muted); pointer-events: none; }
.tw-scope-search input {
  width: 100%; box-sizing: border-box; background: var(--input-bg); border: 1px solid var(--line);
  border-radius: 10px; color: var(--text); font-size: 13px; padding: 9px 12px 9px 32px; outline: none;
}
.tw-scope-search input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.tw-scope-list { flex: 1 1 auto; min-height: 0; max-height: 340px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.tw-scope-sec { display: flex; align-items: center; gap: 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); padding: 9px 8px 3px; }
.tw-scope-sec svg.ic { width: 13px; height: 13px; flex: none; }
.tw-scope-row { display: flex; align-items: center; gap: 9px; width: 100%; background: none; border: none; color: var(--text); text-align: left; padding: 8px 9px; border-radius: 8px; cursor: pointer; font-size: 13px; }
.tw-scope-row:hover, .tw-scope-row.kb { background: var(--panel); }
.tw-scope-row.on { background: color-mix(in srgb, var(--primary) 12%, transparent); }
.tw-scope-row.on:hover, .tw-scope-row.on.kb { background: var(--panel); } /* видимый курсор наведения/клавиатуры даже на уже выбранной строке */
.tw-scope-row > svg.ic { width: 15px; height: 15px; flex: none; color: var(--muted); }
.tw-scope-row.on > svg.ic { color: var(--primary); }
.tw-scope-row .tc-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.tw-scope-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Вторая строка в строке пикера («группа · 12 участников», «уже привязана к сделке …») — CRMC-30/1 */
.tw-scope-name .tw-scope-sub { display: block; font-size: 11.5px; color: var(--muted); line-height: 1.25; margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-scope-n { font-size: 11px; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 0 6px; flex: none; } /* рамка — чтобы пилюля не сливалась с фоном строки при hover/клавиатуре */
/* Ряд сортировки пикера областей (CLIE-593) — тот же контрол и та же геометрия, что у .ccpp-bar
   единого пикера проектов: сортировка в продукте выглядит и работает одинаково везде. */
.tw-scope-bar { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.tw-scope-total { margin-left: auto; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.tw-scope-empty { padding: 14px 8px; text-align: center; }
/* Мультивыбор проектов в фильтре области (0065-ext) — Apple-grade: чёткий чекбокс у КАЖДОГО
   проекта (пустой/залитый), субтильная подсветка выбранного (не заливка всей строки), плавно. */
.tw-scope-row.multi { padding-right: 10px; }
.tw-scope-row.multi .tw-scope-n { margin-left: auto; }         /* счётчик прижат вправо, перед чекбоксом */
.tw-scope-chk {
  position: relative;
  width: 20px; height: 20px; flex: none; box-sizing: border-box;
  border: 1.5px solid var(--line-strong); border-radius: 6px; background: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background-color .15s ease, border-color .15s ease, transform .15s ease;
}
/* Комфортная зона клика по галке (шире визуального квадрата) — чтобы легко попадать в мультивыбор. */
.tw-scope-chk::before { content: ""; position: absolute; inset: -9px -8px -9px -8px; }
.tw-scope-row.multi:active .tw-scope-chk { transform: scale(.9); }
.tw-scope-row.multi:hover .tw-scope-chk { border-color: var(--muted); }
.tw-scope-chk.on {
  background: var(--primary); border-color: var(--primary);
  box-shadow: 0 1px 4px color-mix(in srgb, var(--primary) 45%, transparent);
}
.tw-scope-chk > svg.ic { width: 13px; height: 13px; color: #fff; stroke-width: 3; transform: scale(.9); }
.tw-scope-chk.on > svg.ic { animation: twChkPop .18s ease; }
@keyframes twChkPop { from { transform: scale(.4); opacity: .4; } to { transform: scale(.9); opacity: 1; } }
/* Выбранный проект: НЕ заливаем строку целиком — лёгкий tint + акцентная граница слева. */
.tw-scope-row.multi.on { background: color-mix(in srgb, var(--primary) 9%, transparent); box-shadow: inset 2px 0 0 var(--primary); }
.tw-scope-row.multi.on:hover, .tw-scope-row.multi.on.kb { background: color-mix(in srgb, var(--primary) 15%, transparent); }
.tw-scope-row.multi .tc-dot { box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 14%, transparent); }
/* Проекты в пикере области сгруппированы ПО КОМПАНИЯМ: шапка компании (бренд-цвет + имя + счётчик)
   = «выбрать все её проекты» (мультивыбор), три-состояние в чекбоксе; проекты слегка сдвинуты вправо. */
.tw-scope-cogrp { display: flex; flex-direction: column; gap: 2px; }
.tw-scope-cohead {
  display: flex; align-items: center; gap: 9px; width: 100%; margin-top: 4px;
  background: none; border: none; color: var(--text); text-align: left;
  padding: 7px 10px 7px 9px; border-radius: 8px; cursor: pointer; /* right 10 = один столбец чекбоксов со строками (.multi padding-right:10) */
  font-size: 12.5px; font-weight: 600; letter-spacing: -.01em;
}
.tw-scope-cohead:hover { background: var(--panel); }
.tw-scope-cohead .tc-dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.tw-scope-cohead > svg.ic { width: 15px; height: 15px; flex: none; color: var(--muted); }
.tw-scope-cohead .tw-scope-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-scope-cohead .tw-scope-n { font-size: 11px; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 0 6px; flex: none; }
.tw-scope-cohead .tw-scope-chk { margin-left: 8px; }
.tw-scope-cohead:hover .tw-scope-chk { border-color: var(--muted); }
/* 🔴 Индент проектов под шапкой компании — через PADDING, НЕ margin: при width:100%+box-sizing:border-box
   строка с margin-left вылезает за контейнер на 12px, и overflow-y:auto списка (= overflow-x:auto) режет
   правый край — ровно где чекбокс (баг «чекбоксы обрезаются»). padding не увеличивает внешнюю ширину. */
.tw-scope-cogrp .tw-scope-row { padding-left: 21px; }
/* Частичный выбор компании — чекбокс с «тире» (несколько из группы выбрано, как у Apple). */
.tw-scope-chk.mixed { background: var(--primary); border-color: var(--primary); box-shadow: 0 1px 4px color-mix(in srgb, var(--primary) 45%, transparent); }
.tw-scope-chk.mixed::after { content: ""; position: absolute; left: 4px; right: 4px; top: 50%; height: 2px; margin-top: -1px; background: #fff; border-radius: 1px; }
/* Футер «Выбрано N · Сбросить». */
.tw-scope-foot { flex: none; }
.tw-scope-foot:not(:empty) { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 9px 6px 3px; margin-top: 2px; border-top: 1px solid var(--line); }
.tw-scope-foot-lbl { font-size: 12.5px; color: var(--muted); }
.tw-scope-foot-lbl b { color: var(--text); font-weight: 600; }
.tw-scope-reset {
  background: var(--panel); border: 1px solid var(--line-strong); color: var(--text);
  border-radius: 8px; padding: 6px 13px; font-size: 12.5px; font-weight: 500; cursor: pointer;
  transition: border-color .14s ease, color .14s ease, background-color .14s ease;
}
.tw-scope-reset:hover { border-color: var(--primary); color: var(--primary); background: color-mix(in srgb, var(--primary) 8%, var(--panel)); }
.tw-scope-btn.multi { color: var(--primary); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.tw-scope-btn.multi svg.ic:first-child { color: var(--primary); }

.tw-body { flex: 1; min-height: 0; overflow: auto; }
.tw-empty { color: var(--muted); font-size: 14px; text-align: center; padding: 48px 24px; }
.tw-empty-btn { display: inline-block; margin-top: 10px; padding: 7px 14px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--panel-2); color: var(--text); font-size: 13px; font-weight: 600; cursor: pointer; transition: background .12s, border-color .12s; }
.tw-empty-btn:hover { background: var(--panel); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }

/* ── общая карточка задачи (плитки + канбан) ──
   🔴 CLIE-599 (владелец 2026-08-21, скрин доски с телефона): «в задачах слева полоски, которые
   очень близко и в целом занимают много места». Капсула-приоритет слева СНЯТА со ВСЕХ видов
   карточки — не только в столбике у чатов, где её убрали ещё в CLIE-187. Причина ровно та же и
   теперь признана владельцем везде: цвет капсулы = приоритет, а у «обычного» он ЗЕЛЁНЫЙ, поэтому
   светилась почти каждая карточка и не сообщала ничего (зелёный ещё и читается как «готово»).
   Замена — ТОЧКА у заголовка и ТОЛЬКО «срочно»/«высокий» (Apple Reminders: нет метки = обычный).
   Отсюда же −6px жёлоба слева.
   🔴 2026-08-21, второй заход: владелец выбрал вариант **В1 «Тихая»** («Давай B1») → капсула и
   времянка сравнения `?card=0` УДАЛЕНЫ насовсем. Держать рядом скрытую вторую отрисовку карточки
   нельзя (правило «ОДНА реализация, не плодить дубли»): пока `.tw-card::before` жил в CSS, любая
   правка карточки должна была помнить про два вида, а `html[data-card="0"]` тихо возвращал
   запрещённую рейку в бою. Приоритет несёт ТОЛЬКО точка у заголовка (ниже). */
.tw-card {
  position: relative;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 12px; padding: 11px 12px; cursor: pointer;
  transition: border-color .12s, transform .08s, box-shadow .12s;
}
.tw-card:hover { border-color: var(--primary); box-shadow: 0 6px 18px -8px rgba(0,0,0,.5); }
/* 🔴🔴 CLIE-892 · ТОЧКА ВАЖНОСТИ — ОДНА ДЕКЛАРАЦИЯ НА ВСЕ ПОВЕРХНОСТИ ЗАДАЧ.
   Приоритет = деликатная точка у заголовка, только у ЖИВОЙ задачи и только двух верхних
   уровней. Геометрия и мягкое кольцо 16% — ровно те, что владелец принял в CLIE-187.

   Владелец (скрин панели «Сегодня» с телефона): «Не видно важности меток и много нужного
   в задачах дня». Замер в ту минуту: 7 из 11 задач его дня — `urgent`, и ни одной точки
   на экране. Правило жило ДВУМЯ копиями (карточка доски и строка списка), а панель дня
   в них не входила — поэтому копий больше нет, есть один список селекторов: добавить
   поверхность = дописать сюда строку, а не третий блок с теми же семью пикселями.
   Цвет каждая поверхность объявляет ОДИН раз ниже через `--prio-dot`. */
.tw-card.prio-urgent:not(.done):not(.cancelled) .tw-card-title::before,
.tw-card.prio-high:not(.done):not(.cancelled)   .tw-card-title::before,
.tw-row.prio-urgent:not(.done):not(.cancelled)  .tw-row-title::before,
.tw-row.prio-high:not(.done):not(.cancelled)    .tw-row-title::before,
/* 🔎 Окно выбора задачи `ccTaskPick` — та же точка, а не пятая копия семи пикселей. */
.ctp-row.prio-urgent:not(.done):not(.cancelled) .ctp-tt::before,
.ctp-row.prio-high:not(.done):not(.cancelled)   .ctp-tt::before,
/* 🔴 CLIE-1058 · ОЧЕРЕДЬ ИИ (владелец: «Здесь не отображены важные данные. Например не указана
   срочность задачи»). И ждущая строка, и строка идущей работы — тот же список селекторов, а не
   четвёртая копия тех же семи пикселей. Закрытых задач в очереди не бывает, поэтому :not() тут
   не нужен: ai_queue отдаёт только ai_status='queued', ai_running — только 'working'. */
.wsq-row.prio-urgent                            .wsq-t::before,
.wsq-row.prio-high                              .wsq-t::before,
.wsq-wrow.prio-urgent                           .wsq-t::before,
.wsq-wrow.prio-high                             .wsq-t::before,
.tdy-row.prio-urgent:not(.done)                 .tdy-t::before,
.tdy-row.prio-high:not(.done)                   .tdy-t::before,
.tdy-pl-row.prio-urgent                         .tdy-pl-t::before,
.tdy-pl-row.prio-high                           .tdy-pl-t::before,
.tdy-rv-row.prio-urgent:not(.ok)                .tdy-pl-t::before,
.tdy-rv-row.prio-high:not(.ok)                  .tdy-pl-t::before {
  content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 7px; vertical-align: middle; position: relative; top: -1px;
  background: var(--prio-dot);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--prio-dot) 16%, transparent);
}
.prio-urgent { --prio-dot: var(--urg-overdue); }
.prio-high   { --prio-dot: var(--urg-today); }
/* 🔴 РОВНО ОДНА точка у заголовка = приоритет — теперь на ВСЁМ продукте, а не только в
   столбике у чатов. Решение владельца из CLIE-187 («2 раза красная точка и ещё синяя, очень
   всё непонятно; тут нужно только ОДНУ точку — приоритет») до CLIE-599 действовало лишь в
   `.tasks-list`, потому что на доске приоритет рисовала полоска и точка была одна. Сняли
   полоску → на доске рядом встали бы ДВЕ точки. Синюю «изменено» гасим (в DOM остаётся —
   `:has()`-правила выше продолжают ловить непросмотренное), сигнал не теряется: жирный
   заголовок + оформление `.tw-card.has-unseen`. В светлой теме над заголовком стоит подпись «Есть изменения». */
.tw-card-title .task-changed-dot,
.tw-card-title .task-attention-dot,
.tw-row-title .task-changed-dot { display: none; }

/* ── Столбик задач СЛЕВА ОТ ЧАТОВ (.tasks-list): CLIE-187, владелец 2026-07-28 ──
   В узком столбике толстая капсула-приоритет перегружала карточку и путала («зелёная = ок/готово»).
   ЗДЕСЬ капсулу убираем; приоритет — деликатной точкой у заголовка ТОЛЬКО «Срочно»/«Высокий»
   (Apple Reminders: нет метки = обычный), только у активных.
   🔴 СТАТУС — явной МЕТКОЙ прямо на карточке (showStatusPill в myTasksCardAdapter): «В работе»/
   «К выполнению»/«На проверке»… в цвет статуса. Раньше статус читался только по заголовку секции
   (и только в группировке «по этапам») — по сроку/проекту/списком его не было нигде, владелец не
   видел «в работе». Метка со СЛОВОМ читается однозначно (полоску цветом как раз убрали). У
   выполненных/отменённых метку прячем — карточка и так зачёркнута.
   🔴 CLIE-599 (2026-08-21): исключение «на доске капсула остаётся» ОТМЕНЕНО самим владельцем —
   капсулы больше нет НИГДЕ, а точка-приоритет и жёлоб 12px переехали в базовые правила
   `.tw-card` выше. Здесь остаётся только то, что действительно про столбик у чатов:
   гашение двух ЛИШНИХ точек в заголовке (см. ниже, «РОВНО ОДНА точка»). */
/* ── РОВНО ОДНА точка = ПРИОРИТЕТ (CLIE-187, владелец 2026-07-28, финальная правка) ──
   Владелец (скрин): «2 раза красная точка и ещё синяя, очень всё непонятно; статус же текстом
   пилюлей ниже — тут нужно только ОДНУ точку, отображающую приоритет, и всё». В заголовке
   карточки столбика рядом с точкой-приоритетом стакались ещё две: 🔴 .task-attention-dot
   («требует внимания», тот же красный → и есть «2 раза красная») и 🔵 .task-changed-dot
   («изменено/не просмотрено»). Прячем ОБЕ — но ТОЛЬКО в столбике у чатов (.tasks-list); на
   доске/плитках (вне .tasks-list) они остаются как были. Статус несёт текстовая пилюля ниже.
   🔴 Непрочитанное НЕ теряем (владелец ранее просил «вернуть непрочитанные»): .task-changed-dot
   остаётся в DOM (display:none, не удалён из разметки), поэтому :has()-правила ниже по файлу
   продолжают ловить «:not(.seen)» → плотный заголовок + мягкая подложка карточки работают как
   прежде, только без конкурирующей точки. */
/* CLIE-599: гашение обеих лишних точек переехало в базовые правила `.tw-card-title` выше —
   оно теперь действует на весь продукт. Здесь остаётся только ВЕС заголовка столбика (700). */
/* Синей точки в столбике больше нет → «не просмотрено» держит сам заголовок: делаем его чуть
   плотнее (700 против общего 600), чтобы непрочитанное уверенно читалось и без точки. */
.tasks-list .tw-card-title:has(> .task-changed-dot:not(.seen)) { font-weight: 700; }
/* Метка-статус в столбике у чатов = ведущий, чуть акцентированный чип (цвет/фон приходят
   inline из statusPillTint — тут только вес и лёгкое кольцо для читаемости на любой теме). */
.tasks-list .tw-card .tw-pill[class*="status-"] {
  font-weight: 600; letter-spacing: .1px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 22%, transparent);
}
/* Выполнено/Отменено — метку не дублируем (карточка уже зачёркнута и приглушена). */
.tasks-list .tw-card.done .tw-pill[class*="status-"],
.tasks-list .tw-card.cancelled .tw-pill[class*="status-"] { display: none; }
/* ── Заголовок на ВСЮ ширину + кружок «Готово» по наведению (CLIE-187, владелец 2026-07-28) ──
   Владелец: «ширину названия сделаем на всю ширину; элемент принятия в готово (кружок) пусть
   появляется при наведении». В узком столбике у чатов кружок-чекбокс раньше постоянно съедал
   слева ~30px → заголовок съезжал и не совпадал по левому краю с описанием/чипами ниже.
   Решение: чекбокс по умолчанию СВЁРНУТ (ширина 0, невидим, вне фокуса мыши) → заголовок встаёт
   ЗАПОДЛИЦО с описанием и занимает всю ширину. Навёл мышью на карточку — кружок плавно
   раскрывается слева (160мс), заголовок мягко уступает ему место. На тач-устройствах (нет hover)
   кружок виден всегда — иначе его не нажать. Скоуп СТРОГО .tasks-list: на доске/плитках/странице
   «Задачи» чекбокса нет вовсе (showCheck только у myTasksCardAdapter) — их не трогаем. */
.tasks-list .tw-card-head { gap: 0; }                          /* жёлоб под кружок появляется только на hover */
.tasks-list .tw-card .tw-card-title { padding-right: 8px; }    /* было общее 30px → тут заголовку почти вся ширина справа */
.tasks-list .tw-card-head .task-check {
  box-sizing: border-box; overflow: hidden;
  width: 0; border-width: 0; margin-right: 0; opacity: 0; pointer-events: none;
  transition: width .16s ease, border-width .16s ease, margin-right .16s ease,
              opacity .14s ease, background .12s, border-color .12s, color .12s;
}
.tasks-list .tw-card:hover .task-check,
.tasks-list .tw-card:focus-within .task-check {
  width: 19px; border-width: 2px; margin-right: 9px; opacity: 1; pointer-events: auto;
}
@media (hover: none) {   /* тач: навести нельзя → кружок виден всегда */
  .tasks-list .tw-card-head .task-check {
    width: 19px; border-width: 2px; margin-right: 9px; opacity: 1; pointer-events: auto;
  }
}
.tw-card.done .tw-card-title { color: var(--muted); text-decoration: line-through; }
/* Отменённая карточка (доска/плитки/v2): зачёркнута + приглушена (паритет со столбиком). */
.tw-card.cancelled { opacity: .6; }
.tw-card.cancelled .tw-card-title { color: var(--muted); text-decoration: line-through; }
.tw-card.cancelled .tr-ppl { opacity: .5; }
.tw-card-title { font-size: 14px; color: var(--text); line-height: 1.35; margin-bottom: 6px; word-break: break-word; }
.tw-card-desc { font-size: 12.5px; color: var(--muted); line-height: 1.4; margin-bottom: 8px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tw-card-foot { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* Прогресс-бар чек-листа на карточке: полоса во всю ширину + счётчик N/M. Зелёный при 100%. */
.tw-card-ck { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.tw-card-foot + .tw-card-ck { margin-top: 6px; }
.tw-ck-bar { flex: 1 1 auto; min-width: 40px; height: 5px; border-radius: 999px; background: var(--line); overflow: hidden; }
/* Полоска прогресса — акцент ШАБЛОНА (--primary → --primary-2), а не прибитое старое индиго #667eea→#8b9cf5:
   в «Штиле» оно торчало на каждой карточке задачи чужим цветом (свип волны 3, 20.10.2026). В базе — те же пиксели. */
.tw-ck-bar i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--primary), var(--primary-2)); transition: width .3s ease; }
.tw-card-ck.done .tw-ck-bar i { background: var(--ok); }
.tw-ck-n { flex: none; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.tw-card-ck.done .tw-ck-n { color: var(--ok); }
.tw-pill { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; padding: 3px 8px; border-radius: 6px; background: var(--panel-2); color: var(--muted); }
.tw-pill.sub, .tw-pill.link { color: var(--primary-2); }
.tw-pill.parent { color: var(--muted); }
.tw-pill.rel { cursor: pointer; }
.tw-pill.rel:hover { background: color-mix(in srgb, var(--primary) 22%, transparent); color: var(--primary-2); }
.tw-pill.status-open        { background: rgba(139,147,163,.16); color: #aeb6c6; }
.tw-pill.status-in_progress { background: var(--info-soft); color: var(--info); }
.tw-pill.status-done        { background: rgba(34,197,94,.16); color: var(--urg-done); }
.tw-pill.status-cancelled   { background: rgba(107,114,128,.16); color: #8b93a3; }
.tw-pill.lbl { background: color-mix(in srgb, var(--lc, var(--muted)) 16%, transparent); color: color-mix(in srgb, var(--lc, var(--muted)) 74%, #fff); font-weight: 600; }
.tw-pill.lbl .tw-lbl-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--lc, var(--muted)); flex: none; }
/* Пилюля-кнопка смены статуса в карточке задачи (клик открывает меню статусов). */
.tip-status-btn { border: none; cursor: pointer; font: inherit; line-height: 1; }
.tip-status-btn:hover { filter: brightness(1.15); }
.tip-status-btn svg { width: 13px; height: 13px; opacity: .7; }
.tw-pill.due-overdue { background: var(--urg-overdue-soft); color: var(--urg-overdue-ink); }
.tw-pill.due-today   { background: var(--urg-today-soft); color: var(--urg-today); }
.tw-pill .ic { width: 13px; height: 13px; }
.tw-avs { display: inline-flex; align-items: center; }
.tw-av { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--panel); margin-left: -7px; background-size: cover; background-position: center; display: inline-flex; align-items: center; justify-content: center; font-size: 10px; color: #fff; }
.tw-av:first-child { margin-left: 0; }

/* ── вид «Плитки» ── */
.tw-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 12px; padding: 16px; }

/* ── вид «Список» (секции по срочности, как в столбике) ── */
.tw-list { padding: 10px 16px 24px; }
.tw-sec-title { font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; padding: 16px 2px 8px; }
.tw-sec-title:first-child { padding-top: 4px; }
.tw-sec-title.tst-overdue { color: var(--urg-overdue-ink); } .tw-sec-title.tst-today { color: var(--urg-today); }
.tw-sec-title.tst-soon { color: var(--primary-2); } .tw-sec-title.tst-none { color: #6B7280; }
.tw-sec-title.tst-done { color: var(--urg-done); }
.tw-sec-title.tst-cancelled { color: #8b93a3; }
/* Список пространства: «Идёт таймер» / «В работе» — та же семья var(--info), что бейдж таймера. */
.tw-sec-title.tst-running, .tw-sec-title.tst-wip { color: var(--info); }
/* ══════════ 🗑 ВИД «КОРЗИНА» (CLIE-1792) — строки удалённого в той же поверхности задач ══════════
   Своих цветов НЕ заводим: только токены темы (--line/--panel/--muted/--danger), поэтому светлая
   и тёмная получают вид бесплатно и не разъезжаются. Геометрия — как у `.tw-row` рядом. */
.tw-trash { display: flex; flex-direction: column; gap: 6px; padding: 4px 2px 18px; }
.tw-trash-head { display: flex; align-items: center; gap: 10px; padding: 6px 10px 10px; }
.tw-trash-say { color: var(--muted); font-size: 13px; flex: 1; min-width: 0; }
.tw-trash-back { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--line); border-radius: 9px;
  background: transparent; color: var(--text); font-size: 13px; cursor: pointer; }
.tw-trash-back:hover { background: var(--panel); }
.tw-trash-back svg { width: 14px; height: 14px; }
.tw-trash-row { display: flex; align-items: center; gap: 11px; padding: 9px 12px; border: 1px solid var(--line); border-radius: 11px; }
.tw-trash-row:hover { background: var(--panel); }
.tw-trash-ic { flex: 0 0 auto; color: var(--muted); display: flex; }
.tw-trash-ic svg { width: 17px; height: 17px; }
.tw-trash-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.tw-trash-t { font-size: 14px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-trash-sub { font-size: 12px; color: var(--muted); }
.tw-trash-act { display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; border: 1px solid var(--line); border-radius: 9px;
  background: transparent; color: var(--text); font-size: 13px; cursor: pointer; }
.tw-trash-act:hover { background: var(--panel); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.tw-trash-act[disabled] { opacity: .5; cursor: default; }
.tw-trash-act svg { width: 14px; height: 14px; }
.tw-trash-del { color: var(--danger); }
.tw-trash-del:hover { border-color: color-mix(in srgb, var(--danger) 50%, var(--line)); }
.tw-trash-hint { color: var(--muted); font-size: 12px; padding: 8px 12px; line-height: 1.45; }
.tw-row { position: relative; display: flex; align-items: center; gap: 11px; padding: 10px 12px; border-radius: 11px; border: 1px solid transparent; cursor: pointer; }
/* CLIE-599 (В1): та же капсула, что у карточки, только у строки списка — снята НАСОВСЕМ.
   Приоритет здесь несёт точка у заголовка (`.tw-row-title::before`), жёлоб слева не нужен.
   🔴 CLIE-892: сама точка объявлена ОДИН раз выше («ТОЧКА ВАЖНОСТИ»), тут остался только
   ховер — своей копии семи пикселей у строки списка больше нет. */
.tw-row:hover { background: var(--panel); }
.tw-row.done .tw-row-title { color: var(--muted); text-decoration: line-through; }
.tw-row.cancelled { opacity: .6; }
.tw-row.cancelled .tw-row-title { color: var(--muted); text-decoration: line-through; }
.tw-check { flex: 0 0 auto; width: 20px; height: 20px; border-radius: 6px; border: 2px solid var(--line); background: transparent; cursor: pointer; display: flex; align-items: center; justify-content: center; color: #fff; }
.tw-check:hover { border-color: var(--primary); }
.tw-row.done .tw-check { background: var(--ok); border-color: var(--ok); }
.tw-check svg { width: 12px; height: 12px; }
.tw-row-main { flex: 1; min-width: 0; }
.tw-row-title { font-size: 14px; color: var(--text); }
.tw-row-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
/* «Присоединиться» у события-созвона в календаре рабочего пространства. Прямое действие
   на самой строке (нажал → зашёл), без «сначала откройте карточку». Токены → обе темы. */
.v2cal-join {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 11px; border-radius: 8px; border: 1px solid transparent;
  background: var(--ok); color: #fff; font: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer; transition: filter .14s ease, transform .14s cubic-bezier(.32,.72,.35,1);
}
.v2cal-join:hover { filter: brightness(1.07); }
.v2cal-join:active { transform: scale(.97); }
.v2cal-join:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--primary); }
.v2cal-join svg.ic { width: 14px; height: 14px; }

/* ── вид «Доска» (канбан) ── */
/* Гуттеры: слева даёт padding-left, справа — трейлинг ::after (обычный padding-right при
   горизонтальном скролле «схлопывается» → последняя колонка липла к краю). Симметрично 16px. */
/* 🔴🔴 «ВИЖУ СТОЛБИК» = «МОГУ СЮДА ПОЛОЖИТЬ» — для ВСЕХ досок, а не только CRM (CRMC-716 лечил
   лиды и сделки, доска задач осталась с `flex-start`). Владелец 07.10.2026: «Перестало работать
   перетаскивание по столбикам». Замер на живом проде (проект «Маркетинг - ProArt», 1700×1000):
   пустой столбик — коробка «пусто» ~55px, а карточку ведут на её высоте по ДОРОЖКЕ столбика →
   курсор над фоном доски, бросок не принимается, на сервер не уходит ни одного запроса.
   Столбик тянется во всю высоту доски; цель дропа — весь `.tw-col` (wireBoardUnified,
   wireWorkspaceCards, crmBoardDnd). */
.tw-board { display: flex; gap: 12px; padding: 16px 0 16px 16px; height: 100%; align-items: stretch; box-sizing: border-box; }
.tw-board::after { content: ""; flex: 0 0 16px; align-self: stretch; }
/* 🔴 ДОРОЖКА КОЛОНКИ СЧИТАЕТСЯ ОТ КАРТОЧКИ, КОТОРУЮ ДЕРЖИТ, А НЕ ОТ ХОЛСТА.
   Было `--col-bg: var(--panel-2)`. В боевой светлой палитре --panel-2 РАВЕН --bg
   (#f5f5f7), и тело колонки становилось невидимым: замер живого прода — колонка
   #f5f5f7 на холсте #f5f5f7 = 1.000, от колонки оставался только хэйрлайн (тот же
   класс, что «серые блоки на сером фоне» у карточки CRM, 15.09.2026).
   🔴 ПРАВИМ ТОЛЬКО СВЕТЛУЮ, И ЭТО НЕ БЕЛЫЙ СПИСОК: схлопывание «инсет = холст» —
   свойство СВЕТЛЫХ палитр (боевая #f5f5f7/#f5f5f7 = 1.000, базовая #f4f6fb/#eef1f7 = 1.03),
   а в тёмной --panel-2 честно поднят над холстом (1.211). Одна формула на обе темы уже была
   написана и ОТКАЧЕНА замером: подняв тёмную дорожку до #252b32, она сблизила её с тинтом
   карточки «есть изменения» (#262c3e) — 1.071 → 1.035, и 650 карточек из 2364 растворились
   в дорожке. Тёмная остаётся ровно такой, какой была.
   Замер на стенде (боевые данные, 7 колонок × 2362 карточки):
     светлая дорожка #e4e4e6 на #f5f5f7 = 1.169 (было 1.000), карточка в дорожке 1.273 (было 1.089)
     тёмная  без изменений: #232a34 на #141a21 = 1.211, «есть изменения» в дорожке 1.071
   Мерилка — tools/shots/surface-merge-audit.js. */
.tw-col { flex: 1 1 0; min-width: 230px; max-width: 360px; --col-bg: var(--panel-2); background: var(--col-bg); border: 1px solid var(--line); border-radius: 14px; display: flex; flex-direction: column; max-height: 100%; }
.tw-col.drop-hover { border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow) inset; }
.tw-col-head { display: flex; align-items: center; gap: 8px; padding: 12px 14px 8px; font-size: 13px; font-weight: 650; color: var(--text); position: relative; }
.tw-col-dot { width: 9px; height: 9px; border-radius: 50%; }
.tw-col-dot.status-open { background: #aeb6c6; } .tw-col-dot.status-in_progress { background: #3B82F6; }
.tw-col-dot.status-done { background: var(--ok); } .tw-col-dot.status-cancelled { background: #6B7280; }
.tw-col-count { color: var(--muted); font-weight: 500; }
.tw-col-body { padding: 4px 10px 12px; overflow-y: auto; display: flex; flex-direction: column; gap: 9px; flex: 1; min-height: 36px; }
.tw-card.dragging { opacity: .4; }
.tw-card[draggable="true"] { cursor: grab; }
/* «+» в шапке столбца + инлайн-композер новой задачи */
.tw-col-add { margin-left: auto; flex: none; width: 26px; height: 26px; border-radius: 8px; border: 0; background: transparent; color: var(--muted); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.tw-col-add:hover { background: var(--panel-2); color: var(--primary-2); }
.tw-col-add svg.ic { width: 16px; height: 16px; }
.tw-add-box { display: flex; flex-direction: column; gap: 7px; background: var(--panel-2); border: 1px solid var(--primary); border-radius: 12px; padding: 9px 10px; }
.tw-add-input { background: transparent; border: 0; color: var(--text); font: inherit; font-size: 13.5px; outline: none; }
.tw-add-input::placeholder { color: var(--muted); }
.tw-add-row { display: flex; align-items: center; gap: 10px; }
.tw-add-detail { display: inline-flex; align-items: center; gap: 5px; background: var(--panel); border: 1px solid var(--line); color: var(--text); font: inherit; font-size: 12px; padding: 5px 9px; border-radius: 8px; cursor: pointer; }
.tw-add-detail:hover { border-color: var(--primary); }
.tw-add-detail svg.ic { width: 13px; height: 13px; }
.tw-add-hint { color: var(--muted); font-size: 11px; margin-left: auto; }

/* Строка «куда уедет задача» в быстром композере (2026-07-19). Владелец: показанное
   ОБЯЗАНО совпадать с созданным. Тон — служебная подпись, а не второй заголовок:
   хэйрлайн сверху, мелкий текст, ярлыки приглушены. Тёмная/светлая — на переменных. */
.tw-target { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px;
  margin: 6px 0 0; padding: 6px 2px 0; border-top: 1px solid var(--line);
  font-size: 11.5px; line-height: 1.35; color: var(--text); }
.tw-target-i { color: var(--muted); font-size: 10.5px; letter-spacing: .01em; }
.tw-target-sep { color: var(--muted); opacity: .55; margin: 0 2px; }
.tw-target-warn { color: var(--warn, #b26a00); }
.tw-target-warn .tw-target-i { color: inherit; opacity: .75; }

/* ── Trello-стиль: управление столбцами прямо на доске ── */
.tw-col.col-dragging { opacity: .45; }
.tw-col.col-drop-before { box-shadow: -3px 0 0 0 var(--primary); }
.tw-col.col-drop-after  { box-shadow: 3px 0 0 0 var(--primary); }
.tw-col-head.editable { cursor: grab; }
.tw-col-head .tw-col-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; outline: none; border-radius: 5px; padding: 1px 4px; margin: -1px -2px; }
.tw-col-head .tw-col-name[contenteditable="true"] { white-space: normal; overflow: visible; background: var(--panel); box-shadow: 0 0 0 2px var(--glow); cursor: text; }
.tw-col-dot.clickable { cursor: pointer; }
.tw-col-dot.clickable:hover { box-shadow: 0 0 0 3px var(--glow); }
/* Навигация столбца (выделить всё/следить/добавить/меню) — оверлей поверх ХВОСТА
   заголовка, вне потока и скрыт по умолчанию: раньше эти иконки навсегда резервировали
   ширину (менюшки opacity:0, но место держали; колокольчик — opacity:.55 всегда виден),
   из-за чего название столбца обрезалось многоточием почти сразу («К вы…», «В раб…» —
   жалоба владельца, скрин задачи). Теперь в потоке только точка+имя+счётчик (имя получает
   всю свободную ширину), а .tw-col-tools всплывает по hover столбца поверх хвоста имени;
   градиент фона столбца под иконками — чтобы обрезанный текст под ними не резался жёстко.
   Грипа нет: весь столбец draggable, тащить можно прямо за название (cursor:grab на шапке). */
.tw-col-tools {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; gap: 1px;
  padding-left: 22px; border-radius: 8px;
  background: linear-gradient(to right, transparent, var(--col-bg) 20px, var(--col-bg));
  opacity: 0; pointer-events: none; transition: opacity .14s ease;
}
.tw-col:hover .tw-col-tools,
.tw-col-tools:has(.tw-col-menu-btn.open),
.tw-col-tools:has(.tw-col-selall) { opacity: 1; pointer-events: auto; }
.tw-col-tools .tw-col-menu-btn, .tw-col-tools .tw-col-selall { flex: none; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border: none; background: transparent; color: var(--muted); border-radius: 7px; cursor: pointer; transition: background .12s, color .12s; padding: 0; }
.tw-col-tools .tw-col-menu-btn:hover, .tw-col-tools .tw-col-menu-btn.open, .tw-col-tools .tw-col-selall:hover { background: var(--panel); color: var(--text); }
.tw-col-tools .tw-col-menu-btn svg.ic, .tw-col-tools .tw-col-selall svg.ic { width: 16px; height: 16px; }
/* 0066/0097: тумблер «отслеживать столбец» (колокольчик, доска проекта). Строго по hover,
   как остальная навигация — без исключения для включённой подписки (было раньше, владелец
   попросил убрать: «видно осталось, пусть только при наведении появляется»). */
.tw-col-tools .tw-col-watch { flex: none; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border: none; background: transparent; color: var(--muted); border-radius: 7px; cursor: pointer; transition: background .12s, color .12s; padding: 0; }
.tw-col-tools .tw-col-watch:hover { background: var(--panel); color: var(--text); }
.tw-col-tools .tw-col-watch.on { color: var(--primary); }
.tw-col-tools .tw-col-watch svg.ic { width: 16px; height: 16px; }
/* плитка «добавить столбец» */
.tw-addcol { flex: 0 0 auto; width: 240px; min-width: 240px; }
.tw-addcol-btn { width: 100%; display: flex; align-items: center; gap: 7px; padding: 12px 14px; border: 1.5px dashed var(--line); border-radius: 14px; background: transparent; color: var(--muted); font-size: 13px; font-weight: 600; cursor: pointer; }
.tw-addcol-btn:hover { border-color: var(--primary); color: var(--text); background: var(--panel-2); }
.tw-addcol-btn svg.ic { width: 16px; height: 16px; }
.tw-addcol-form { background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px; padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.tw-addcol-form input, .tw-addcol-form select { background: var(--panel); border: 1px solid var(--line); color: var(--text); border-radius: 8px; padding: 8px 10px; font-size: 13px; box-sizing: border-box; width: 100%; }
.tw-addcol-form input:focus, .tw-addcol-form select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.tw-addcol-actions { display: flex; gap: 6px; }
.tw-addcol-actions button { flex: 1; }
/* 🗂 0420: «Свой порядок · вернуть общий» — выход из своего порядка столбцов проекта, под «+ Столбец». */
.tw-own-order { width: 100%; margin-top: 8px; display: flex; align-items: center; gap: 7px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); color: var(--muted); font-size: 12px; font-weight: 600; cursor: pointer; text-align: left; }
.tw-own-order:hover { color: var(--text); border-color: var(--primary); }
.tw-own-order svg.ic { width: 14px; height: 14px; flex: none; }
/* поповер: меню/цвет/категория столбца */
.tw-pop { position: fixed; z-index: 9600; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; box-shadow: 0 14px 44px rgba(0,0,0,.5); padding: 7px; min-width: 192px; }
.tw-pop-item { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 8px; cursor: pointer; font-size: 13px; color: var(--text); }
.tw-pop-item:hover { background: var(--panel-2); }
/* danger-пункт меню: красный ТЕКСТ на прозрачном (глобальный .danger + light-override красят фон
   в красный с спецификой 0,2,1 → перебиваем равной/большей спецификой в обеих темах). */
.tw-pop-item.danger, html[data-theme="light"] .tw-pop-item.danger { color: var(--danger); background: transparent; }
.tw-pop-item.danger:hover, html[data-theme="light"] .tw-pop-item.danger:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.tw-pop-item svg.ic { width: 15px; height: 15px; flex: none; }
.tw-pop-sep { height: 1px; background: var(--line); margin: 5px 4px; }
.tw-pop-label { font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; padding: 6px 8px 4px; }
.tw-pop-swatches { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; padding: 4px 8px 8px; }
.tw-swatch { width: 22px; height: 22px; border-radius: 50%; cursor: pointer; border: 2px solid transparent; box-sizing: border-box; }
.tw-swatch:hover { transform: scale(1.14); }
.tw-swatch.sel { border-color: var(--text); }
.tw-pop-cats { padding: 2px 6px 6px; display: flex; flex-direction: column; gap: 2px; }
.tw-pop-cat { display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: 7px; cursor: pointer; font-size: 13px; color: var(--text); }
.tw-pop-cat:hover { background: var(--panel-2); }
.tw-pop-cat.sel { background: var(--panel-2); font-weight: 600; }
.tw-pop-cat .tw-cat-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }

/* ── модалка детали/редактора задачи ── */
.task-detail-box { max-width: 900px; max-height: 92vh; }
.td-body { display: flex; flex-direction: column; gap: 14px; }
.td-title-input { font-size: 17px; font-weight: 600; width: 100%; background: transparent; border: none; border-bottom: 1px solid transparent; color: var(--text); padding: 4px 2px; }
.td-title-input:hover { border-bottom-color: var(--line); }
.td-title-input:focus { outline: none; border-bottom-color: var(--primary); }
.td-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; }
.td-field { display: flex; flex-direction: column; gap: 5px; }
.td-field > span { font-size: 12px; color: var(--muted); }
.td-field select, .td-field input[type="date"], .td-desc {
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  border-radius: 9px; padding: 8px 10px; font-size: 13px; width: 100%;
}
.td-field select { appearance: none; -webkit-appearance: none; background-image: var(--sel-chev-sm); background-repeat: no-repeat; background-position: right 9px center; padding-right: 28px; cursor: pointer; }
.td-field select:focus, .td-desc:focus, .td-field input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
/* ⏰ 0076 «Весь день» под полем срока: аккуратная строка-чип (не голый чекбокс), 4/8-grid,
   мягкий hover и выраженное checked-состояние. Смысл: срок = календарный день, одинаковый
   во всех часовых поясах (протокол — время 23:59). */
.td-allday {
  display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
  margin-top: 2px; padding: 5px 9px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel-2); color: var(--muted); font-size: 12px; cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
}
.td-allday:hover { border-color: var(--primary); color: var(--text); }
.td-allday input { width: 14px; height: 14px; margin: 0; accent-color: var(--primary); cursor: pointer; }
.td-allday:has(input:checked) { border-color: var(--primary); color: var(--text); background: var(--glow); }
.td-allday input:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.td-desc { resize: vertical; min-height: 56px; line-height: 1.4; }
.td-section-h { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 2px; }
/* карточка задачи: режим ПРОСМОТРА (редактирование — по кнопке «Изменить») */
.td-view-head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 4px; }
.td-view-title { flex: 1; font-size: 18px; font-weight: 700; color: var(--text); line-height: 1.3; word-break: break-word; }
.td-view-head .td-title-input { flex: 1; }
.td-view-head .td-edit-toggle { flex: none; width: auto; display: inline-flex; align-items: center; gap: 5px; }
.td-edit-toggle svg.ic { width: 15px; height: 15px; }
/* 2 колонки: слева контент, справа боковая карточка с мета */
.td-layout { display: flex; gap: 18px; align-items: flex-start; margin-top: 6px; }
.td-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 16px; }
.td-side { width: 232px; flex: none; display: flex; flex-direction: column; gap: 12px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 13px 14px; }
.td-side-row { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; min-width: 0; }
.td-side-row .tw-pill { align-self: flex-start; }
.td-side .td-field { gap: 5px; }
.td-side-sec { display: flex; flex-direction: column; gap: 6px; }
.td-view-k { font-size: 11.5px; color: var(--muted); }
.td-view-v { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: var(--text); }
.td-view-v svg.ic { width: 14px; height: 14px; color: var(--muted); }
.td-view-v .td-prio-dot, .td-prio-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none; }
.td-view-desc { font-size: 14px; color: var(--text); white-space: pre-wrap; word-break: break-word; line-height: 1.45; }
.td-asg.view { padding-right: 10px; }
/* футер карточки: иконки в кнопках инлайн (а не блоком-сверху) */
.td-foot-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.td-foot-row .tw-spacer { flex: 1; }
.td-foot-row button { display: inline-flex; align-items: center; gap: 6px; }
.td-foot-row svg.ic { width: 15px; height: 15px; display: inline-block; }
@media (max-width: 720px) { .td-layout { flex-direction: column; } .td-side { width: auto; } }
/* табы карточки: Задача / Чат задачи */
.td-tabs { display: flex; gap: 6px; margin: 4px 0 12px; border-bottom: 1px solid var(--line); }
.td-tabs button { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: 0;
  border-bottom: 2px solid transparent; color: var(--muted); cursor: pointer; font-size: 13px; padding: 8px 4px; margin-bottom: -1px; }
.td-tabs button svg.ic { width: 15px; height: 15px; }
.td-tabs button:hover { color: var(--text); }
.td-tabs button.active { color: var(--text); border-bottom-color: var(--primary); }
/* чат задачи */
.td-chat-attached { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 11px; margin-bottom: 10px; }
.td-chat-attached svg.ic { width: 15px; height: 15px; color: var(--muted); flex: none; }
.td-chat-attached button { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; }
.td-chat-attached button svg.ic { width: 13px; height: 13px; }
.td-parts { display: flex; flex-wrap: wrap; gap: 14px; padding: 4px 2px 12px; margin-bottom: 8px; border-bottom: 1px solid var(--line); }
.td-part-grp { display: flex; flex-direction: column; gap: 5px; }
.td-part-grp .td-view-k { display: inline-flex; align-items: center; gap: 5px; }
.td-part-grp .td-view-k svg.ic { width: 13px; height: 13px; }
.td-part-list { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.td-chat-msgs { max-height: 42vh; overflow-y: auto; padding: 4px 2px; margin-bottom: 8px; }
/* чат задачи в ОСНОВНОЙ панели треда (как беседа) */
.taskchat-head { padding: 10px 14px; border-bottom: 1px solid var(--line); background: var(--panel); }
.taskchat-msgs { padding: 14px; }
.thread-av.tkc-av { display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--urg-done) 20%, var(--panel-2)); color: var(--urg-done); }
.thread-av.tkc-av svg.ic { width: 22px; height: 22px; }
/* ── Правый информ-столбик чата задачи ── */
.task-info-panel { width: var(--w-taskinfo, 330px); flex: none; border-left: 1px solid var(--line); background: var(--panel);
  display: flex; flex-direction: column; min-height: 0; position: relative; /* якорь для .col-resizer на левой кромке */ }
/* Ресайзер на ЛЕВОЙ кромке панели (в отличие от колонок — тянем за левый шов). */
.col-resizer.col-resizer-left { right: auto; left: -4px; }
/* В режиме ШТОРКИ-модалки (`.as-overlay`) хваталка тянет САМУ модалку задачи (её ширину) —
   поэтому её ПОКАЗЫВАЕМ (раньше пряталась: там она двигала невидимую грид-колонку).
   Ставим ВНУТРИ панели (у оверлея overflow:hidden клипнул бы left:-4px). На мобиле скрыта
   общим правилом `@media(max-width:720){.col-resizer{display:none}}`; ниже возвращаем её на
   узком десктопе (561–720), где модалка всё ещё уже вьюпорта. */
.task-info-panel.as-overlay .col-resizer.col-resizer-left { left: 0; width: 12px; }
/* Светящуюся линию держим НА самом шве (левой кромке панели), как у всех прочих ресайзеров —
   иначе она «висит» отступя внутрь и смотрится неровно. Внешнюю половину свечения слегка
   срежет overflow:hidden оверлея — это допустимо (линия важнее ровности свечения). */
.task-info-panel.as-overlay .col-resizer.col-resizer-left::after { left: 0; transform: none; }
@media (min-width: 561px) { .task-info-panel.as-overlay .col-resizer.col-resizer-left { display: block; } }
.tip-head { padding: 13px 16px; border-bottom: 1px solid var(--line); flex: none; display: flex; align-items: center; gap: 8px; }
.tip-title { flex: 1; min-width: 0; font-weight: 700; font-size: 14px; color: var(--text); line-height: 1.3; border-radius: 6px; }
.tip-title[role=button] { cursor: text; padding: 2px 6px; margin: -2px -6px; transition: background .12s; }
.tip-title[role=button]:hover { background: var(--panel-2); }
.tip-title.editing { background: var(--panel-2); outline: 1.5px solid var(--accent); cursor: text; }
.tip-title-edit { flex: none; opacity: .55; }
.tip-title-edit:hover { opacity: 1; }
/* Вкладки шторки задачи: Карточка | Чат */
.tip-tabs { display: flex; gap: 4px; padding: 6px 12px 0; border-bottom: 1px solid var(--line); flex: none; }
.tip-tab { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: 0; border-bottom: 2px solid transparent; color: var(--muted); font: inherit; font-size: 13px; padding: 8px 10px; cursor: pointer; margin-bottom: -1px; }
.tip-tab:hover { color: var(--text); }
.tip-tab.active { color: var(--primary-2); border-bottom-color: var(--primary); }
.tip-tab svg.ic { width: 15px; height: 15px; }
/* «Ая» — ПОСЛЕДНЯЯ вкладка ряда (CLIE-1000 р2, владелец: «отдельной вкладкой в самом конце»).
   Значок в акценте (`--primary-2`, как у активной вкладки — доктрина контраста): помощник это
   ДЕЙСТВИЕ, и человек находит его глазами, не читая подписи. Подпись остаётся спокойной, как у
   соседей, — крикливой пилюли рядом с ними не заводим. */
.tip-tab-assist svg.ic { color: var(--primary-2); }
/* Докнутая карточка (сплит-вид: чат СЛЕВА + карточка справа): вкладка «Чат» не нужна —
   чат уже открыт слева, дублировать его в карточке незачем → её прячем. Но «Карточка» и
   «История» полезны и тут, поэтому сами вкладки ОСТАВЛЯЕМ видимыми (раньше прятали всю
   панель). Оверлей-режим (`.as-overlay`, из списка/доски) показывает все три вкладки. */
.task-info-panel:not(.as-overlay) .tip-tab[data-tiptab="chat"] { display: none; }
.tip-collapse { background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 4px; border-radius: 8px; display: none; flex: none; }
.tip-collapse svg.ic { width: 17px; height: 17px; }
.tip-collapse:hover { background: var(--panel-2); color: var(--text); }
.task-info-panel:not(.as-overlay) .tip-collapse { display: inline-flex; }
/* «Поделиться» — ВИДНА ВСЕГДА (и в докнутой шторке, и в оверлей-модалке): свернуть/раскрыть
   (.tip-collapse) прячутся по режиму, а share нужна в обоих. Свой класс, вид как у соседних иконок. */
.tip-share-btn { background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 4px; border-radius: 8px; display: inline-flex; flex: none; transition: background .12s, color .12s; }
.tip-share-btn svg.ic { width: 17px; height: 17px; }
.tip-share-btn:hover { background: var(--panel-2); color: var(--text); }
/* «Наблюдать / Наблюдаю» — тумблер-глаз в шапке карточки, ВИДЕН В ОБОИХ режимах (как share).
   Приглушённый глаз = не наблюдаю; акцент (--primary) = наблюдаю. Одно касание. CLIE-221. */
.tip-watch-btn { background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 4px; border-radius: 8px; display: inline-flex; flex: none; transition: background .12s, color .12s; }
.tip-watch-btn svg.ic { width: 17px; height: 17px; }
.tip-watch-btn:hover { background: var(--panel-2); color: var(--text); }
.tip-watch-btn.on { color: var(--primary); }
.tip-watch-btn.on:hover { color: var(--primary-hi); background: var(--panel-2); }
/* «Раскрыть в модалку» — та же панель шторкой поверх чата (докнутый столбец 330px слишком
   узок для работы). Иконка maximize оптически крупнее «свернуть» из-за угловых штрихов —
   гасим на полпикселя и приглушаем, чтобы группа кнопок в шапке читалась как один ряд. */
.tip-expand svg.ic { width: 16px; height: 16px; }
.tip-expand { opacity: .72; }
.tip-expand:hover { opacity: 1; }
.tip-scroll { flex: 1; overflow-y: auto; padding: 13px 14px; display: flex; flex-direction: column; gap: 15px; }
.tip-status-sec { display: flex; flex-direction: column; align-items: flex-start; gap: 9px; }
.tip-actions { display: flex; flex-wrap: wrap; gap: 6px; }
.tip-actions button { width: auto; display: inline-flex; align-items: center; gap: 5px; }
.tip-actions svg.ic { width: 14px; height: 14px; }
.tip-time { display: flex; align-items: center; gap: 8px; }
.tip-time .td-view-k { display: inline-flex; align-items: center; gap: 5px; }
.tip-time .td-view-k svg.ic { width: 13px; height: 13px; }
.tip-time-v { margin-left: auto; font-size: 13px; color: var(--text); }
.tip-running { color: var(--urg-done); font-weight: 600; }
.tip-meta { display: flex; flex-direction: column; gap: 9px; }
.tip-sec { display: flex; flex-direction: column; gap: 7px; }
.tip-sec .td-section-h { display: inline-flex; align-items: center; gap: 5px; }
.tip-sec .td-section-h svg.ic { width: 13px; height: 13px; }
.tip-check { display: flex; align-items: flex-start; gap: 11px; padding: 9px 2px; }
.tip-check + .tip-check { border-top: 1px solid var(--line); }
.tip-check > span { flex: 1; font-size: 14.5px; line-height: 1.45; color: var(--text); padding-top: 1px; }
.tip-check.done > span { text-decoration: line-through; color: var(--text); opacity: .72; }
.tip-check .td-check-box, .tip-check .tip-x { margin-top: 1px; }
/* ─── «Выполнено» — Apple-grade залитый статус (CLIE-354) ──────────────────────
   Было: у чекбокса выполненного пункта карточки задачи НЕ было заливки — зелёное
   правило .td-check-item.done .td-check-box к .tip-check НЕ применяется, и в светлой
   теме получалась белая галочка (color:#fff) на прозрачном квадрате → «выполнено»
   не читалось, выглядело блёкло. Теперь: залитый чекбокс с мягкой глубиной, крепкая
   белая галочка, поп при отметке и деликатная подложка строки (как «выполнено» в
   Apple Reminders). Через var(--ok)/color-mix одинаково вылизано в светлой и тёмной. */
.tip-check .td-check-box { transition: background .18s, border-color .18s, box-shadow .18s, transform .12s; }
.tip-check .td-check-box:not([disabled]):hover { border-color: var(--primary); }
.tip-check.done .td-check-box {
  background: linear-gradient(160deg, color-mix(in srgb, var(--ok) 74%, #fff), var(--ok));
  border-color: transparent; color: #fff;
  box-shadow: 0 1px 4px color-mix(in srgb, var(--ok) 42%, transparent),
              inset 0 1px 0 rgba(255,255,255,.34);
}
.tip-check.done .td-check-box svg { stroke-width: 3; }
/* поп-анимация при отметке (класс .just-checked вешает tipToggleCheck) */
.tip-check .td-check-box.just-checked { animation: tipckpop .34s cubic-bezier(.34,1.56,.64,1); }
@keyframes tipckpop { 0% { transform: scale(.6); } 55% { transform: scale(1.16); } 100% { transform: scale(1); } }
/* деликатная подложка выполненной строки — читается отдельной «сделанной» группой,
   без хэйрлайна поверх пилюли (снимаем разделитель у done-строки и у следующей за ней) */
.tip-check.done { background: color-mix(in srgb, var(--ok) 7%, transparent); border-radius: 10px; }
.tip-check.done, .tip-check.done + .tip-check { border-top-color: transparent; }
.tip-check.done > .tip-ck-t { opacity: 1; color: var(--muted);
  text-decoration-thickness: 1.4px; text-decoration-color: color-mix(in srgb, var(--muted) 50%, transparent); }
/* ☑️ CLIE-1147 · «кто и когда отметил» — тихая подпись справа от текста выполненного пункта.
   Не растёт и не режет строку: ужимается первой и отдаёт место тексту пункта. */
.tip-ck-when { flex: 0 1 auto; min-width: 0; margin-left: 6px; color: var(--muted); font-size: 11.5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; opacity: .85; }
/* Ручка-грип для перетаскивания порядка пунктов чек-листа (drag&drop мышкой) */
.tip-ck-grip { flex: 0 0 auto; background: transparent; border: 0; color: var(--muted); cursor: grab; padding: 2px 0; margin-top: 1px; display: inline-flex; opacity: .45; touch-action: none; transition: opacity .12s; }
.tip-ck-grip:hover { opacity: 1; }
.tip-ck-grip svg.ic { width: 15px; height: 15px; }
/* Приподнятая («лифт») строка при перетаскивании — Apple-grade: непрозрачная карточка, мягкая
   тень, лёгкий scale (в transform из JS). z-index держит её над соседями. */
.tip-check.ck-dragging { position: relative; z-index: 6; background: var(--panel-2); border-radius: 10px;
  box-shadow: 0 10px 28px rgba(0,0,0,.20), 0 2px 6px rgba(0,0,0,.10); }
.tip-check.ck-dragging .tip-ck-grip { cursor: grabbing; opacity: 1; }
/* Во время реордера: без выделения текста, без хэйрлайнов-разделителей (чтобы линия не «резала»
   приподнятую карточку), плавность через will-change. */
.tip-checks.ck-reordering { user-select: none; -webkit-user-select: none; }
.tip-checks.ck-reordering .tip-check { will-change: transform; }
.tip-checks.ck-reordering .tip-check + .tip-check { border-top-color: transparent; }
/* Видимый карандаш-«изменить» на строке (паритет с Flutter Icons.edit_outlined): всегда виден
   субтильно, ярче на hover строки. Раньше правка была только по клику на текст (title-тултип) —
   пользователь её не находил → «редактирование пропало». */
.tip-ck-editbtn { flex: 0 0 auto; background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 2px; margin-top: 1px; display: inline-flex; border-radius: 5px; opacity: .5;
  transition: opacity .12s, color .12s, background .12s; }
.tip-ck-editbtn svg.ic { width: 14px; height: 14px; }
.tip-check:hover .tip-ck-editbtn { opacity: 1; }
.tip-ck-editbtn:hover { color: var(--primary); background: var(--panel-2); opacity: 1; }
/* Клик по тексту пункта тоже открывает правку; курсор-«текст» + мягкая подсветка подсказывают */
.tip-check > span.tip-ck-t[data-ckedit] { cursor: text; border-radius: 5px; padding: 0 3px; margin: 0 -3px; transition: background .12s; }
.tip-check > span.tip-ck-t[data-ckedit]:hover { background: var(--panel-2); }
/* В режиме правки строки — прячем грип и карандаш, поле правки занимает строку целиком */
.tip-check.ck-editing .tip-ck-grip, .tip-check.ck-editing .tip-ck-editbtn { display: none; }
.tip-check input.tip-ck-edit { flex: 1; min-width: 0; background: var(--input-bg); color: var(--text); border: 1px solid var(--primary); border-radius: 7px; padding: 4px 7px; font: inherit; font-size: 14.5px; line-height: 1.4; outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent); }
.tip-x { background: transparent; border: 0; color: var(--muted); cursor: pointer; padding: 2px; display: inline-flex; border-radius: 5px; }
.tip-x:hover { color: var(--urg-overdue-ink); background: var(--panel-2); }
.tip-x svg.ic { width: 13px; height: 13px; }
/* Видимая кнопка «Прокомментировать в чате» на строке чек-листа (паритет с заметками
   data-notecomment): субтильна, ярче на hover строки. Раньше это действие было ТОЛЬКО в
   ПКМ/долгом-тапе — пользователь его не находил → «прокомментировать не работает». */
.tip-ck-cmtbtn { flex: 0 0 auto; background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 2px; margin-top: 1px; display: inline-flex; border-radius: 5px; opacity: .5;
  transition: opacity .12s, color .12s, background .12s; }
.tip-ck-cmtbtn svg.ic { width: 14px; height: 14px; }
.tip-check:hover .tip-ck-cmtbtn { opacity: 1; }
.tip-ck-cmtbtn:hover { color: var(--primary); background: var(--panel-2); opacity: 1; }
.tip-check.ck-editing .tip-ck-cmtbtn { display: none; }

/* ☑️ 0422 · ИСПОЛНИТЕЛЬ И СРОК ПУНКТА — аватар и дата ПРЯМО В СТРОКЕ, БЕЗ нового компонента.
   Размерный класс строки не меняем (канон `control-size`): аватар — тот же `.tw-av` 22px, что во
   всём продукте, дата — та же типографика 11.5px, что у тихой подписи `.tip-ck-when`. Обе темы
   получаются сами: цвета взяты ТОКЕНАМИ (`--urg-overdue`, `--warn`, `--panel-2`), а не числами.
   🔴 Селектор пишем `.tip-check > span.tip-ck-*` / `> button.tip-ck-*`: у безымянного
   `.tip-check > span { flex: 1; font-size: 14.5px }` специфичность (0,1,1) — она СИЛЬНЕЕ одного
   класса, и read-only вид (у кого нет права правки — это `<span>`, а не кнопка) растянулся бы
   на всю строку шрифтом текста пункта. */
.tip-check > button.tip-ck-who, .tip-check > span.tip-ck-who {
  flex: 0 0 auto; background: transparent; border: 0; padding: 0; margin: 0; color: var(--muted);
  display: inline-flex; align-items: center; border-radius: 50%; cursor: pointer;
  transition: opacity .12s, color .12s, box-shadow .12s; }
.tip-check > span.tip-ck-who { cursor: default; }
/* Пустое состояние (поручить ещё некому) — субтильный знак, как у грипа и «прокомментировать»:
   не ярче данных, но и НЕ невидимка. `opacity: 0` тут запрещён — на тач-экране hover не
   случается никогда, и контрол был бы мёртвым. */
.tip-check > button.tip-ck-who:not(.has) { opacity: .38; padding: 2px; border-radius: 5px; }
.tip-check:hover > button.tip-ck-who:not(.has) { opacity: 1; }
.tip-check > button.tip-ck-who:not(.has):hover { color: var(--primary); background: var(--panel-2); }
.tip-ck-who svg.ic { width: 14px; height: 14px; }
/* Выполненному пункту исполнитель уже не нужен — пустую заглушку убираем совсем (минимум). */
.tip-check.done > button.tip-ck-who:not(.has), .tip-check.done > button.tip-ck-due:not(.has) { display: none; }
.tip-check > button.tip-ck-who.has:hover .tw-av { box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 55%, transparent); }
.tip-ck-who .tw-av { margin-left: 0; }

/* Срок — пилюля с датой словами (`ccCkDue`), а не сырая ISO-строка. Не режет текст пункта:
   `flex: 0 0 auto` + `nowrap`, место отдаёт текст. */
.tip-check > button.tip-ck-due, .tip-check > span.tip-ck-due {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 3px; margin-top: 2px;
  background: transparent; border: 0; padding: 2px; border-radius: 5px; cursor: pointer;
  color: var(--muted); font: inherit; font-size: 11.5px; line-height: 1.3; white-space: nowrap;
  transition: opacity .12s, color .12s, background .12s; }
.tip-check > span.tip-ck-due { cursor: default; }
.tip-check > button.tip-ck-due:not(.has) { opacity: .38; }
.tip-check:hover > button.tip-ck-due:not(.has) { opacity: 1; }
.tip-check > button.tip-ck-due:not(.has):hover { color: var(--primary); background: var(--panel-2); }
.tip-ck-due svg.ic { width: 13px; height: 13px; }
/* Есть дата — это ДАННЫЕ: видно всегда, подложка + кольцо (левых полосок-реек нет, CLIE-483). */
.tip-check > button.tip-ck-due.has, .tip-check > span.tip-ck-due.has {
  padding: 2px 7px; border-radius: 999px; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 22%, transparent); }
.tip-check > button.tip-ck-due.has:hover { color: var(--text); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 45%, transparent); }
/* Срок сегодня-завтра — предупреждение; срок прошёл — тот же красный, которым продукт красит
   просроченную задачу. Выполненному пункту состояния срока не даём вовсе (`ccCkDueState`). */
.tip-check > button.tip-ck-due.soon, .tip-check > span.tip-ck-due.soon {
  color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 30%, transparent); }
.tip-check > button.tip-ck-due.over, .tip-check > span.tip-ck-due.over {
  color: var(--urg-overdue-ink); background: var(--urg-overdue-soft);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--urg-overdue) 32%, transparent); }
.tip-check > button.tip-ck-due.over:hover { color: var(--urg-overdue-ink); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--urg-overdue) 60%, transparent); }
/* Клавиатура видит фокус (состояния hover/selected/focus вылизаны одинаково). */
.tip-ck-who:focus-visible, .tip-ck-due:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; opacity: 1; }
/* Правка текста занимает строку целиком — чипы на это время уходят, как грип и карандаш. */
.tip-check.ck-editing .tip-ck-who, .tip-check.ck-editing .tip-ck-due { display: none; }
/* Поповер срока пункта — та же рама, что «Когда начинать задачу» (`.tip-startpop`). */
.tip-ckduepop .tip-startpop-lbl { margin-bottom: 6px; }

/* ═══ НЕСКОЛЬКО ИМЕНОВАННЫХ ЧЕК-ЛИСТОВ В ЗАДАЧЕ (0081) ═══
   Список = блок: тонкая шапка (имя + карандаш + свой счётчик + «…») → своя полоса прогресса →
   свои пункты → свой композер. Разделяем ВОЗДУХОМ и хэйрлайном, БЕЗ вторых плашек-заливок:
   карточка задачи уже стоит на --panel-2, ещё один фон превратил бы её в «лестницу коробок».
   Всё на токенах → светлая и тёмная темы одинаково выверены. */
.tip-ck-groups { display: flex; flex-direction: column; gap: 14px; }
.tip-ckg { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.tip-ckg + .tip-ckg { border-top: 1px solid var(--line); padding-top: 14px; }
.tip-ckg-h { display: flex; align-items: center; gap: 6px; min-height: 22px; min-width: 0; }
/* Имя списка — на ступень тише заголовка карточки (тот индиго/uppercase): это подуровень */
.tip-ckg-t { min-width: 0; font-size: 13.5px; font-weight: 650; line-height: 1.35; color: var(--text);
  letter-spacing: -.005em; border-radius: 6px; padding: 1px 4px; margin: 0 -4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: background .14s; }
.tip-ckg-t[data-ckgedit] { cursor: text; }
.tip-ckg-t[data-ckgedit]:hover { background: var(--panel); }
/* Карандаш «переименовать» и «…» — та же субтильная манера, что у карандаша пункта:
   всегда видны едва-едва, проявляются на hover блока, акцент — на самом hover кнопки. */
.tip-ckg-pen, .tip-ckg-menu { flex: 0 0 auto; background: transparent; border: 0; color: var(--muted);
  cursor: pointer; padding: 3px; display: inline-flex; border-radius: 6px; opacity: .45;
  transition: opacity .14s, color .14s, background .14s; }
.tip-ckg-pen svg.ic, .tip-ckg-menu svg.ic { width: 14px; height: 14px; }
.tip-ckg:hover .tip-ckg-pen, .tip-ckg:hover .tip-ckg-menu { opacity: 1; }
.tip-ckg-pen:hover, .tip-ckg-menu:hover { color: var(--primary); background: var(--panel); opacity: 1; }
.tip-ckg-pen:focus-visible, .tip-ckg-menu:focus-visible { outline: none; opacity: 1; box-shadow: 0 0 0 3px var(--glow); }
.tip-ckg-cnt { margin-left: auto; flex: none; font-size: 12px; font-weight: 600; color: var(--muted);
  font-variant-numeric: tabular-nums; }
/* «в повтор не едет» — состояние служебного списка у ПОВТОРЯЕМОЙ задачи. Пилюля тише имени
   списка и не спорит со счётчиком: это сноска, а не акцент. Токены общие, значит обе темы
   берутся одним правилом (в тёмной --panel/--muted уже перевёрнуты). */
.tip-ckg-sys { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px;
  font-size: 11px; font-weight: 600; line-height: 1; white-space: nowrap; cursor: help;
  color: var(--muted); background: var(--panel); border-radius: 999px; padding: 3px 7px 3px 5px; }
.tip-ckg-sys svg.ic { width: 11px; height: 11px; opacity: .8; }
.tip-ckg-menu { margin-left: 2px; }
/* «…» единственного (свёрнутого) списка живёт в шапке КАРТОЧКИ — hover-родитель там другой */
.tip-ck-hdmenu { opacity: .45; margin-left: 0; }
.tip-card:hover .tip-ck-hdmenu { opacity: 1; }
/* Инлайн-переименование списка — то же поле-с-кольцом, что у правки пункта (.tip-ck-edit) */
.tip-ckg.ckg-editing .tip-ckg-pen { display: none; }
.tip-ckg-edit { flex: 1; min-width: 0; background: var(--input-bg); color: var(--text);
  border: 1px solid var(--primary); border-radius: 7px; padding: 3px 7px; font: inherit;
  font-size: 13.5px; font-weight: 650; line-height: 1.4; outline: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent); }
/* Полоса прогресса СПИСКА — тоньше общей (4 против 5): визуальная иерархия «карточка → список» */
.tip-ckg-bar { height: 4px; }
/* «＋ Чек-лист» — тихое действие, а не CTA: пунктирная рамка как у .tip-chipbtn.dash */
.tip-ck-newlist { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px;
  background: transparent; border: 1px dashed var(--line-strong); color: var(--muted);
  font: inherit; font-size: 13px; line-height: 1.2; padding: 6px 11px; border-radius: 10px;
  cursor: pointer; transition: color .14s, border-color .14s, background .14s, box-shadow .14s; }
.tip-ck-newlist svg.ic { width: 14px; height: 14px; }
.tip-ck-newlist:hover { color: var(--primary-2); border-color: var(--primary); background: var(--panel); }
.tip-ck-newlist:focus-visible { outline: none; border-color: var(--primary); color: var(--primary-2);
  box-shadow: 0 0 0 3px var(--glow); }

/* Быстрое контекст-меню сущности карточки (ПКМ / долгий тап по заметке или пункту чек-листа).
   Плавающий поповер уровня системного меню macOS: хэйрлайн, мягкая тень, лёгкое появление.
   🔴 Раньше у .cc-entmenu НЕ было ни одного правила — без position:fixed left/top игнорировались,
   меню падало неоформленным блоком в конец <body>. */
.cc-entmenu { position: fixed; z-index: 9700; min-width: 214px; max-width: 320px; padding: 6px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px;
  display: flex; flex-direction: column; gap: 1px;
  box-shadow: 0 16px 46px rgba(0,0,0,.5), 0 2px 8px rgba(0,0,0,.28);
  animation: ccEntIn .13s cubic-bezier(.2,.8,.2,1); transform-origin: top left; }
@keyframes ccEntIn { from { opacity: 0; transform: scale(.96) translateY(-2px); } to { opacity: 1; transform: none; } }
.cc-entmenu-b { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
  background: transparent; border: 0; cursor: pointer; padding: 9px 11px; border-radius: 8px;
  color: var(--text); font: inherit; font-size: 14px; line-height: 1.2; transition: background .1s; }
.cc-entmenu-b:hover { background: var(--panel); }
.cc-entmenu-b svg.ic { width: 17px; height: 17px; flex: none; color: var(--muted); }
.cc-entmenu-b.pri { color: var(--primary); font-weight: 600; }
.cc-entmenu-b.pri svg.ic { color: var(--primary); }
.cc-entmenu-b.dng { color: var(--danger); }
.cc-entmenu-b.dng svg.ic { color: var(--danger); }
.tip-check-add { display: flex; gap: 6px; align-items: center; }
.tip-check-add input { flex: 1; background: var(--input-bg); color: var(--text); border: 1px solid var(--line); border-radius: 8px; padding: 6px 9px; font: inherit; outline: none; }
.tip-check-add input:focus { border-color: var(--primary); }
.tip-rels { display: flex; flex-direction: column; gap: 8px; }
.tip-rel-grp { display: flex; flex-direction: column; gap: 4px; }
.tip-rel { display: flex; align-items: center; gap: 7px; width: 100%; text-align: left; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 7px 9px; color: var(--text); font-size: 13px; }
.tip-rel:hover { border-color: var(--primary); }
.tip-rel-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-full { display: inline-flex; align-items: center; gap: 5px; }
.tip-desc { width: 100%; min-height: 54px; background: var(--input-bg); color: var(--text); border: 1px solid var(--line);
  border-radius: 8px; padding: 7px 9px; font: inherit; resize: vertical; outline: none; }
.tip-desc:focus { border-color: var(--primary); }
.tip-add-sub { margin-top: 4px; display: inline-flex; align-items: center; gap: 5px; align-self: flex-start; }
.tip-foot { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }
.tip-foot button { display: inline-flex; align-items: center; gap: 5px; }

/* ── Карточка задачи: секции-карточки + ролевые права (редизайн 2026-07) ── */
.tip-scroll { gap: 10px; }
.tip-card { background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px; padding: 12px 13px; display: flex; flex-direction: column; gap: 10px; }
.tip-card .td-section-h { display: inline-flex; align-items: center; gap: 6px; margin: 0; }
.tip-card .td-section-h svg.ic { width: 13px; height: 13px; color: var(--primary-2); }
.tip-hd-cnt { margin-left: auto; font-weight: 600; letter-spacing: 0; text-transform: none; font-size: 12px; color: var(--muted); }
.tip-statusbar { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.tip-statusbar .tip-actions { margin-left: auto; }
.tip-prop { display: flex; align-items: center; gap: 12px; min-height: 30px; }
.tip-prop + .tip-prop { border-top: 1px solid var(--line); padding-top: 8px; }
.tip-prop-k { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); font-size: 13px; flex: none; }
.tip-prop-k svg.ic { width: 15px; height: 15px; color: var(--muted); }
/* 🔴 ФИКС «ДЕРГАЕТСЯ»: значение свойства — ОДНА строка стабильной высоты (nowrap + скрытый
   перелив), длинный текст усекаем по … в .tip-chiplbl. Раньше content-sized чип менял ширину/
   раскладку при смене значения или фон-пересборке → строки уезжали и клик промахивался. */
.tip-prop-v { margin-left: auto; display: inline-flex; align-items: center; gap: 6px; min-width: 0; justify-content: flex-end; flex-wrap: nowrap; overflow: hidden; }
.tip-prop-v.tip-labels-v { flex-wrap: wrap; overflow: visible; } /* меток бывает много — им перенос нужен */
.tip-chiplbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.tip-prop-ro { color: var(--text); font-size: 13px; }
.tip-chipbtn { display: inline-flex; align-items: center; gap: 7px; max-width: 100%; min-width: 0; background: var(--panel); border: 1px solid var(--line); color: var(--text); font: inherit; font-size: 13px; padding: 6px 10px; border-radius: 10px; cursor: pointer; }
.tip-chipbtn:hover { border-color: var(--primary); }
.tip-chipbtn.dash { border-style: dashed; color: var(--muted); background: transparent; }
.tip-chipbtn svg.ic { width: 14px; height: 14px; }
.tip-chipbtn .cev { color: var(--muted); display: inline-flex; }
.tip-chipbtn.due-set { background: color-mix(in srgb, var(--primary) 14%, transparent); border-color: color-mix(in srgb, var(--primary) 34%, transparent); color: var(--primary-2); }
.tip-chipbtn.due-over { background: rgba(242,96,122,.14); border-color: rgba(242,96,122,.34); color: var(--urg-overdue-ink); }
/* «Начало» привязано к предшественнику (задача идёт следом за другой): связь-чип «после «X»»
   вместо пустого «Указать начало» + тонкая иконка-подсказка рядом с уже заданной датой. */
.tip-chipbtn.tip-start-after { background: color-mix(in srgb, var(--primary) 10%, transparent); border-color: color-mix(in srgb, var(--primary) 30%, transparent); color: var(--primary-2); border-style: solid; }
.tip-chipbtn.tip-start-after:hover { border-color: var(--primary); }
/* Тумблер «Из предыдущих» (генерация): вкл — мягкий акцентный фон, как активная due-set. */
.tip-chipbtn.tip-toggle.on { background: rgba(52,199,89,.14); border-color: rgba(52,199,89,.34); color: var(--ok, #34c759); }
/* 🧪 «Полное тестирование» (0190, CLIE-430): список проверок протокола под галкой. Появляется
   ТОЛЬКО когда галка включена (прогрессивное раскрытие) — пустое состояние экран не отбирает.
   Стиль системный: хэйрлайн-разделители, чекбокс 16px со скруглением 5px, строка 28px, ховер
   мягкий, никакой заливки на всю строку. Одинаково выверен в светлой и тёмной темах. */
/* 🧪 РЕЖИМ ПРОВЕРОК (владелец 21.09.2026): «Авто» · «Максимум» · «Свой» — сегмент под строкой
   «Полное тестирование». Тот же отступ 23px, что и у списка проверок ниже: режим и проверки
   читаются как ОДНА настройка, а не два спорящих блока. Канон сегмента — общий (.cc-seg),
   но здесь он живёт внутри строки свойства и потому компактнее. */
.tip-tmode { display: inline-flex; gap: 2px; margin: 4px 0 0 23px; padding: 2px; border-radius: 9px; background: var(--hover, rgba(127,127,127,.08)); }
.tip-tmode-b { min-height: 24px; padding: 3px 10px; border: 0; border-radius: 7px; background: transparent; color: var(--muted); font: inherit; font-size: 12.5px; cursor: pointer; transition: background .13s ease, color .13s ease; }
.tip-tmode-b:hover:not(:disabled) { color: var(--text); }
.tip-tmode-b.on { background: var(--bg, #fff); color: var(--text); font-weight: 600; box-shadow: 0 1px 2px rgba(0,0,0,.06); }
.tip-tmode-b:disabled { cursor: default; opacity: .7; }
.tip-tmode-say { margin: 4px 0 2px 23px; color: var(--muted); font-size: 11.5px; line-height: 1.35; }
/* 🎨 0478 «Результат: дизайн / код»: пометка «авто» — подсказка классификатора воркера, ещё не решение человека. */
.tip-rk-auto { margin-left: 6px; color: var(--muted); font-size: 11.5px; }
.tip-tests { display: flex; flex-direction: column; margin: 1px 0 4px; padding: 5px 0 1px; border-top: 1px solid var(--line); }
/* Отступ 23px = иконка строки (15) + её зазор (8): подписи проверок встают ровно под текстом
   «Полное тестирование», и список читается как ЕГО настройки, а не как отдельный блок. */
.tip-test { display: flex; align-items: center; gap: 9px; width: 100%; min-height: 27px; margin-left: 23px; width: calc(100% - 23px); padding: 3px 6px 3px 0; background: transparent; border: 0; border-radius: 7px; color: var(--text); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; transition: background .13s ease, color .13s ease; }
.tip-test:hover { background: var(--hover, rgba(127,127,127,.08)); }
.tip-test:disabled { cursor: default; opacity: .7; }
.tip-test:disabled:hover { background: transparent; }
/* Включено — МЯГКАЯ заливка + зелёная галочка (как пилюля «Максимум» выше), а не 8 сплошных
   плашек: столбик из ярких квадратов кричит и спорит с типографикой карточки. */
.tip-test-box { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; border-radius: 5px; border: 1px solid var(--line); background: transparent; color: var(--ok, #34c759); transition: background .13s ease, border-color .13s ease; }
.tip-test-box svg.ic { width: 10px; height: 10px; stroke-width: 3.2; }
.tip-test.on .tip-test-box { background: rgba(52,199,89,.16); border-color: rgba(52,199,89,.42); }
.tip-test:not(.on) .tip-test-lbl { color: var(--muted); }
.tip-test-lbl { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-test:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.tip-after-hint { display: inline-flex; align-items: center; margin: 0 -1px 0 3px; color: var(--primary-2); opacity: .75; }
.tip-after-hint svg.ic { width: 12px; height: 12px; }
/* Пространство Личное/Работа (0036): сегментированный переключатель на карточке задачи */
.tip-scope-seg { display: inline-flex; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.tip-scope-btn { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: 0; color: var(--muted); font: inherit; font-size: 13px; padding: 6px 12px; cursor: pointer; }
.tip-scope-btn + .tip-scope-btn { border-left: 1px solid var(--line); }
.tip-scope-btn svg.ic { width: 14px; height: 14px; }
.tip-scope-btn:hover { color: var(--text); }
.tip-scope-btn.active { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary-2); }
.tip-prop-ro svg.ic { width: 14px; height: 14px; vertical-align: -2px; margin-right: 5px; }
.tip-due-input { background: var(--input-bg); color: var(--text); border: 1px solid var(--primary); border-radius: 9px; padding: 6px 8px; font: inherit; outline: none; }
.tip-lock { display: inline-flex; align-items: center; gap: 7px; color: var(--muted); font-size: 13px; cursor: pointer; }
.tip-lock .lk { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border-radius: 7px; background: rgba(229,162,60,.12); color: var(--urg-today); flex: none; }
.tip-lock .lk svg.ic { width: 13px; height: 13px; }
.tip-tm-top { display: flex; align-items: center; gap: 9px; }
.tip-tm-run { width: 8px; height: 8px; border-radius: 50%; background: var(--urg-done); box-shadow: 0 0 0 4px rgba(93,202,165,.18); flex: none; }
.tip-tm-total { font-size: 17px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.tip-tm-actions { margin-left: auto; }
/* Пуск/пауза таймера — единый контрол в блоке «Время» (под строкой «Факт»). */
.tip-tm-ctl { margin-top: 10px; }
/* Кнопка таймера («Взять в работу» / «Продолжить» / «Пауза») — ОСОЗНАННО во всю ширину блока
   «Время». Специфичность 2 класса, чтобы пережить `.primary.small` (компактный инлайн по умолчанию);
   высоту и шрифт при этом берём у `.small` — оба состояния (primary «Взять в работу» и ghost
   «Пауза») наконец одинаковы по высоте. */
.primary.tip-tm-btn, .tip-tm-btn { width: 100%; justify-content: center; gap: 7px; }
.tip-tm-btn.running { color: var(--urg-done); border-color: rgba(93,202,165,.4); background: rgba(93,202,165,.10); }
.tip-tm-btn.running:hover { background: rgba(93,202,165,.18); }
.tip-tm-users { display: flex; flex-direction: column; gap: 2px; }
.tip-tm-uhead { display: flex; align-items: center; gap: 6px; font-size: 10.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; border-top: 1px solid var(--line); padding-top: 8px; margin-top: 2px; }
.tip-tm-uhead svg { width: 13px; height: 13px; opacity: .7; }
.tip-tm-nowork { display: inline-flex; align-items: center; gap: 3px; margin-left: auto; text-transform: none; letter-spacing: 0; color: #5DCAA5; font-weight: 600; }
.tip-tm-nowork svg { width: 12px; height: 12px; }
.tip-tm-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12.5px; color: var(--muted); padding: 3px 6px; margin: 0 -6px; border-radius: 7px; transition: background .12s ease; }
.tip-tm-row.running { background: rgba(93,202,165,.08); color: var(--text); }
.tip-tm-who { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.tip-tm-nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-tm-live { flex: none; width: 7px; height: 7px; border-radius: 50%; background: #5DCAA5; box-shadow: 0 0 0 3px rgba(93,202,165,.16); animation: tipTmPulse 1.6s ease-in-out infinite; }
.tip-tm-live.ai { background: var(--cm-a78bfa, #a78bfa); box-shadow: 0 0 0 3px var(--cm-a78bfa-16, rgba(167,139,250,.16)); }
@keyframes tipTmPulse { 0%,100% { opacity: 1; } 50% { opacity: .45; } }
.tip-tm-aichip { flex: none; display: inline-flex; align-items: center; gap: 2px; font-size: 11px; color: var(--cm-a78bfa, #a78bfa); background: var(--cm-a78bfa-12, rgba(167,139,250,.12)); border-radius: 6px; padding: 0 5px; line-height: 17px; }
/* светлая — насыщенный фиолет, как у таймера ИИ: #a78bfa на белой карточке давал 2.25 (свип 19.10) */
html[data-theme="light"] .tip-tm-aichip { color: var(--cm-6d28d9, #6d28d9); background: var(--cm-7c3aed-11, rgba(124,58,237,.11)); }
.tip-tm-row .tip-tm-min { flex: none; color: var(--text); font-variant-numeric: tabular-nums; }
.tip-tm-row .tip-tm-min.run { color: #5DCAA5; font-weight: 600; }
/* Индикатор «ИИ работает» в блоке управления таймером (вместо кнопки «Пауза», 0099). */
.tip-tm-btn.tip-tm-ai-run { display: inline-flex; align-items: center; gap: 6px; color: var(--cm-a78bfa, #a78bfa); background: var(--cm-a78bfa-12, rgba(167,139,250,.12)); border: 1px solid var(--cm-a78bfa-28, rgba(167,139,250,.28)); border-radius: 8px; padding: 5px 10px; font-size: 12.5px; font-weight: 600; font-variant-numeric: tabular-nums; cursor: default; }
.tip-tm-btn.tip-tm-ai-run svg { width: 14px; height: 14px; }
/* CLIE-1946 · светлая: мятный #5DCAA5 и сиреневый #a78bfa — чернила ТЁМНОЙ (на светлом 1.8–2.3:1).
   Тон тот же, чернила глубже: зелёный #166534 (как «В работе» ИИ и status-done), ИИ #6d28d9 (как .tw-pill-timer.ai). Строка «идёт» —
   тинт --ok-soft: прежние 8% мяты на светлом холсте не отделяли строку (1.05). */
html[data-theme="light"] .tip-tm-nowork,
html[data-theme="light"] .tip-tm-row .tip-tm-min.run { color: #166534; }
html[data-theme="light"] .tip-tm-row.running { background: var(--ok-soft); }
html[data-theme="light"] .tip-tm-aichip,
html[data-theme="light"] .tip-tm-btn.tip-tm-ai-run { color: #6d28d9; }
.tip-grp { font-size: 10.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; margin-top: 2px; }
/* Пояснение к роли рядом с её названием («В обсуждении · задачу не отслеживают») — строчными,
   тише заголовка: роль гостя иначе не отличить от наблюдателя. */
.tip-grp-h { text-transform: none; letter-spacing: 0; opacity: .62; }
.tip-grp-h::before { content: "·"; margin: 0 5px; }
html[data-theme="light"] .tip-grp-h { opacity: .9; } /* CLIE-1946: .62 на светлом = 2.7:1 */
.tip-ck-bar { height: 5px; border-radius: 999px; background: var(--panel); overflow: hidden; }
.tip-ck-bar i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--primary), var(--primary-2)); transition: width .3s; }
.tip-desc.view { min-height: 0; white-space: pre-wrap; word-break: break-word; line-height: 1.45; background: transparent; border: 0; padding: 0; }

/* ═══ Rich-описание (Markdown-редактор + рендер) — задачи/тикеты/проекты ═══ */
.tip-desc-card .rd { margin-top: -2px; }
.rd { display: block; }
.rd-view { font-size: 14.5px; line-height: 1.6; color: var(--text); word-break: break-word; cursor: text; padding: 2px; border-radius: 8px; min-height: 24px; }
.rd.editable .rd-view:hover { background: rgba(255,255,255,.03); }
.rd-empty { color: var(--muted); display: inline-flex; align-items: center; gap: 5px; }
.rd-empty svg.ic { width: 14px; height: 14px; opacity: .8; }

/* Рендер Markdown (общий для просмотра и предпросмотра) */

/* 🔴🔴 ШИРОКИЙ БЛОК РАЗМЕТКИ НЕ РАЗДУВАЕТ СВОЙ НОСИТЕЛЬ И НЕ РЕЖЕТСЯ (владелец 16.09.2026:
   «часто ИИ в чатах отправляет сообщения, которые по ширине большие и не влезают в окно.
   Нужен адаптив. Это не только в чате разработки, а во всех чатах, где ИИ работает над задачей»).
   Замер на проде ДО правки (`node tools/aiwidth_prod.js`): лента «Чата с ИИ» 379px, а пузырь
   отчёта — 864px; 543px содержимого уходили ЗА ленту — без переноса, без прокрутки, молча.
   🔴 Причина НЕ в ширине ленты и не в `max-width` сообщения (он стоял и был верным: 240px).
   Пузырь — flex-элемент, и в ПОПЕРЕЧНОЙ оси его ширина = fit-content, а `min-width:0` там не
   работает: нижней границей остаётся min-content, то есть «самая длинная строка кода» и
   «минимальная ширина таблицы». Они и раздували пузырь наружу.
   Лечим КЛАССОМ, одной дверью на весь продукт: у самих широких блоков собственная ширина 0
   (раздувать нечем), рисуются они во всю ширину носителя (`min-width:100%`) и листаются
   ВНУТРИ себя (`overflow` ниже). Правило не знает ни одной поверхности поимённо, поэтому
   действует и в чате, и в «Чате с ИИ», и в Среде, и у Аи, и в заметках — и на той
   поверхности, которую заведут завтра. Сторож: MSGWIDTH_MECH в tools/design_lint.js. */
.md-pre, .md-tablewrap { width: 0; min-width: 100%; max-width: 100%; }

.md-body > *:first-child { margin-top: 0; }
.md-body > *:last-child { margin-bottom: 0; }
.md-body p { margin: 0 0 10px; }
.md-body h1 { font-size: 19px; font-weight: 800; margin: 14px 0 8px; line-height: 1.3; }
.md-body h2 { font-size: 16.5px; font-weight: 800; margin: 14px 0 6px; line-height: 1.3; }
.md-body h3 { font-size: 14.5px; font-weight: 700; margin: 12px 0 5px; color: var(--primary-2); }
.md-body ul, .md-body ol { margin: 0 0 10px; padding-left: 22px; }
.md-body li { margin: 3px 0; }
.md-body ul.md-tasklist { list-style: none; padding-left: 2px; }
.md-body .md-task { display: flex; align-items: flex-start; gap: 9px; margin: 5px 0; }
/* Чекбокс. В ОПИСАНИИ задачи — мёртвый <span> (своя механика правки), в ТЕЛЕ СООБЩЕНИЯ —
   настоящая <button> (§7 спеки, жмёт любой участник). Геометрия общая, интерактив — ниже
   по тегу button, чтобы описание визуально не поехало. */
.md-body .md-cb {
  flex: none; width: 17px; height: 17px; margin-top: 1px; padding: 0;
  border: 1.7px solid var(--muted); border-radius: 5px; position: relative;
  background: transparent; -webkit-appearance: none; appearance: none;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
              box-shadow var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.md-body .md-cb.on { background: var(--primary); border-color: var(--primary); }
/* Галочка существует ВСЕГДА (снятая — прозрачна и поджата): иначе появление нечем
   анимировать, а переключение выглядит рубленым. */
.md-body .md-cb::after {
  content: ""; position: absolute; left: 5px; top: 1.5px; width: 4px; height: 8px;
  border: solid #fff; border-width: 0 2px 2px 0;
  opacity: 0; transform: rotate(45deg) scale(.5); transform-origin: center;
  transition: opacity var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.md-body .md-cb.on::after { opacity: 1; transform: rotate(45deg) scale(1); }
/* Зона нажатия 24×24 (контракт §7) — псевдоэлементом ПОВЕРХ: раскладку (17px в потоке)
   не трогает. 🔴 БЕЗ border-radius: скругление съедает углы, и в углу 24×24 уже не 24×24
   (проверено elementFromPoint). Псевдоэлемент невидим, скруглять в нём нечего. */
button.md-cb { cursor: pointer; }
button.md-cb::before {
  content: ""; position: absolute; left: 50%; top: 50%; width: 24px; height: 24px;
  transform: translate(-50%, -50%);
}
button.md-cb:hover { border-color: var(--primary); background: var(--hover); }
button.md-cb.on:hover { background: var(--primary-2); border-color: var(--primary-2); }
button.md-cb:active { transform: scale(.88); }
button.md-cb:focus-visible { outline: none; box-shadow: 0 0 0 1px var(--primary), 0 0 0 4px var(--glow); }
@media (prefers-reduced-motion: reduce) {
  .md-body .md-cb, .md-body .md-cb::after { transition: none; }
}
.md-body .md-task-t.done { color: var(--muted); text-decoration: line-through; }
/* CLIE-483: рейку сняли — цитата держится мягкой подложкой со скруглением */
.md-body blockquote { margin: 0 0 10px; padding: 6px 10px; border-radius: var(--r-md); background: var(--hover); opacity: .92; }
.md-body code { background: var(--cm-8b9cf5-14, rgba(139,156,245,.14)); color: var(--primary-2); padding: 1.5px 5px; border-radius: 5px; font-size: 12.8px; font-family: var(--mono); word-break: break-word; }
.md-body pre { background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 11px 13px; overflow: auto; margin: 0 0 10px; }
.md-body pre code { background: none; padding: 0; color: var(--text); font-size: 12.6px; line-height: 1.5; }
/* Markdown-картинка `![](url)` (в т.ч. картинки от ИИ-воркера в «Чате с ИИ»). Клик → in-app
   лайтбокс (делегат el.messages для img.md-img[data-nlb]), не внешняя вкладка браузера. */
.md-body img.md-img { display: block; max-width: min(100%, 420px); max-height: 340px; height: auto; border-radius: 10px; margin: 4px 0 8px; cursor: zoom-in; border: 1px solid var(--line); background: var(--panel); }
.md-body a { color: var(--primary-2); text-decoration: none; border-bottom: 1px solid var(--cm-8b9cf5-4, rgba(139,156,245,.4)); }
.md-body a:hover { border-bottom-color: var(--primary-2); }
/* 🔴 CLIE-887: ссылка markdown теперь носит класс `.msg-link` (единственный контракт жеста
   «палец на ссылке»). Вид от этого меняться НЕ должен: у ПОДПИСИ (`[Смета (RU)](url)`)
   слова не рвём — `word-break: break-all` из .msg-link нужен только голым длинным URL. */
.md-body a.md-lbl { word-break: normal; overflow-wrap: anywhere; }
.md-body hr { border: 0; border-top: 1px solid var(--line); margin: 12px 0; }
.md-body strong { font-weight: 750; color: inherit; }
.md-body del { color: var(--muted); }

/* Редактор */
.rd-edit { border: 1.5px solid var(--primary); border-radius: 12px; background: var(--input-bg); overflow: hidden; }
.rd-tb { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; padding: 6px 7px; border-bottom: 1px solid var(--line); background: rgba(255,255,255,.02); }
.rd-tb button { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; border: 0; background: none; color: var(--muted); border-radius: 7px; cursor: pointer; padding: 0; transition: background .13s ease, color .13s ease; }
.rd-tb button:hover { background: rgba(255,255,255,.08); color: var(--text); border-color: transparent; }
.rd-tb button.on { background: color-mix(in srgb, var(--primary) 22%, transparent); color: var(--primary-2); }
/* Активный формат под кареткой — мягкая акцентная подсветка (паритет с мобильным тулбаром). */
.rd-tb button.active { background: color-mix(in srgb, var(--primary) 22%, transparent); color: var(--primary-2); }
.rd-tb button.active:hover { background: color-mix(in srgb, var(--primary) 30%, transparent); color: var(--primary-2); }
.rd-tb button:disabled { opacity: .32; cursor: default; pointer-events: none; }
.rd-tb .rd-sep { width: 1px; height: 18px; background: var(--line); margin: 0 4px; }
.rd-tb svg.ic { width: 16px; height: 16px; }

/* 🔴🔴 CLIE-1049 · ПАНЕЛИ ФОРМАТИРОВАНИЯ В КОМПОЗЕРЕ НЕТ (решение владельца 12.09.2026):
   «Букву Т нужно убрать… у нас и так есть функция раскрыть и стилизовать текст». Правила
   `.rd-tb.cmp-fmt` удалены вместе с кнопкой `#fmtBtn` и панелью `#cmpFmtBar`. Видимая дверь
   оформления — ⛶ «Полотно» (⌘↑) со своей панелью на 16 действий; само поле теперь ПОКАЗЫВАЕТ
   результат сочетания (см. `.rd-ce.rd-wys` выше). */
.rd-ta { width: 100%; min-height: 96px; resize: vertical; border: 0; background: none; color: var(--text); padding: 12px 13px; font-family: inherit; font-size: 14.5px; line-height: 1.6; outline: none; display: block; }
.rd-ta::placeholder { color: var(--muted); }
.rd-prev { padding: 12px 13px; min-height: 96px; }
.rd-foot { display: flex; align-items: center; gap: 8px; padding: 7px 9px; border-top: 1px solid var(--line); background: rgba(255,255,255,.02); }
.rd-hint { font-size: 11.5px; color: var(--muted); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rd-foot button { border: 1px solid var(--line); background: var(--panel-2); color: var(--text); height: 30px; padding: 0 12px; border-radius: 8px; font-size: 12.5px; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; }
.rd-foot button.primary { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; }
.rd-foot button:hover { filter: brightness(1.08); }
.rd-foot button svg.ic { width: 14px; height: 14px; }
.rd-foot .rd-toggle { color: var(--muted); background: none; border: 0; padding: 0 6px; }
.rd-foot .rd-toggle.on { color: var(--primary-2); }

/* ── «Живой» markdown-редактор (contenteditable): форматирование видно СРАЗУ ── */
.rd-ce { width: 100%; min-height: 96px; max-height: 52vh; overflow: auto; border: 0; background: none; color: var(--text); padding: 12px 13px; font-family: inherit; font-size: 14.5px; line-height: 1.6; outline: none; white-space: pre-wrap; overflow-wrap: break-word; word-break: break-word; box-sizing: border-box; caret-color: var(--primary); }
.rd-ce:focus { outline: none; }
.rd-ce.is-empty::before { content: attr(data-ph); color: var(--muted); pointer-events: none; }
.rd-ce .rd-mk { color: var(--muted); opacity: .55; }
.rd-ce .rd-code { font-family: var(--mono); font-size: 13px; color: var(--primary-2); background: var(--cm-8b9cf5-14, rgba(139,156,245,.14)); border-radius: 4px; padding: 0 2px; }
.rd-ce .rd-link { color: var(--primary-2); text-decoration: underline; text-underline-offset: 2px; }
.rd-ce .rd-h { font-weight: 800; }
.rd-ce .rd-h1 { font-size: 20px; } .rd-ce .rd-h2 { font-size: 17px; } .rd-ce .rd-h3 { font-size: 15px; color: var(--primary-2); }
.rd-ce .rd-hr { color: var(--muted); letter-spacing: 2px; }
.rd-ce .rd-q-mk { color: var(--primary); font-weight: 700; }
.rd-ce .rd-q { color: var(--muted); font-style: italic; }
.rd-ce .rd-li-mk { color: var(--primary); font-weight: 700; }
/* Настоящая коробочка вместо буквального «[ ]»/«[x]» — геометрия 1-в-1 с .md-cb готового
   вида задачи, чтобы чек-лист не «прыгал» между редактированием и просмотром. Буквы
   «[ ]»/«[x]» физически остаются в DOM (font-size:0 только прячет их) — textContent не
   меняется, курсор не разъезжается. */
.rd-ce .rd-task-mk { font-size: 0; line-height: 0; }
.rd-ce .rd-task-box {
  display: inline-block; position: relative; vertical-align: -3px;
  width: 15px; height: 15px; margin: 0 1px; border-radius: 5px;
  border: 1.7px solid var(--muted); background: transparent;
  font-size: 0; line-height: 0; color: transparent; overflow: hidden;
  transition: background .12s ease, border-color .12s ease;
}
.rd-ce .rd-task-box.on { background: var(--primary); border-color: var(--primary); }
.rd-ce .rd-task-box::after {
  content: ""; position: absolute; left: 4.3px; top: 1px; width: 3.4px; height: 7px;
  border: solid #fff; border-width: 0 2px 2px 0;
  opacity: 0; transform: rotate(45deg) scale(.5); transform-origin: center;
  transition: opacity .12s ease, transform .12s ease;
}
.rd-ce .rd-task-box.on::after { opacity: 1; transform: rotate(45deg) scale(1); }
.rd-ce .rd-task-done { color: var(--muted); text-decoration: line-through; }
.rd-ce .rd-hl { background: rgba(231,163,62,.28); border-radius: 3px; }
.rd-ce .rd-spoiler-e { color: var(--muted); }
.rd-ce .rd-fence { font-family: var(--mono); font-size: 13px; color: var(--muted); }
.rd-ce strong { font-weight: 750; }
.rd-ce em { font-style: italic; }
.rd-ce del { text-decoration: line-through; color: var(--muted); }

/* ── Подзадачи (иерархия) ── */
.tip-subs { display: flex; flex-direction: column; }
.tip-sub { display: flex; align-items: center; gap: 8px; padding: 5px 0; }
.tip-sub-box { width: 20px; height: 20px; border-radius: 6px; border: 1.6px solid var(--line); background: transparent; flex: none; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; color: transparent; }
.tip-sub-box.done { background: var(--urg-done); border-color: var(--urg-done); color: #08160f; }
.tip-sub-box svg.ic { width: 13px; height: 13px; }
.tip-sub-box[disabled] { cursor: default; opacity: .55; }
.tip-sub-open { flex: 1; min-width: 0; display: inline-flex; align-items: center; gap: 8px; background: transparent; border: 0; color: var(--text); font: inherit; font-size: 13px; text-align: left; cursor: pointer; padding: 0; }
.tip-sub-open .tip-rel-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-sub-open:hover .tip-rel-t { color: var(--primary-2); }
.tip-rel-t.done { text-decoration: line-through; color: var(--muted); }
.tip-parent { display: flex; align-items: center; gap: 9px; width: 100%; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 9px 11px; color: var(--text); font: inherit; font-size: 13.5px; cursor: pointer; text-align: left; }
.tip-parent:hover { border-color: var(--primary); }
.tip-parent svg.ic { width: 15px; height: 15px; color: var(--muted); flex: none; }
.tip-parent .tip-rel-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-parent .tip-rel-t.done { text-decoration: line-through; color: var(--muted); }
.tip-parent-card .td-section-h { color: var(--primary-2); }

/* ── 🔗 CRMC-680 · СДЕЛКА ИЛИ ЛИД, к которым прикреплена задача (та же `entity_links`) ──
   Строка отвечает «какая это сделка» целиком: значок сути · #номер · название · этап · сумма ·
   компания. Акцент несут ЗНАЧОК и СЛОВО этапа, а не левая рейка (правило CLIE-483): у чипа
   этапа — мягкая подложка своего цвета (--sc) и хэйрлайн-кольцо, читается и в ч/б. */
.tip-crms { display: flex; flex-direction: column; gap: 6px; }
.tip-crms:empty { display: none; }
.tip-crm { display: flex; align-items: center; gap: 6px; }
.tip-crm-open { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 9px; padding: 7px 8px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); color: var(--text); font: inherit; text-align: left; cursor: pointer; transition: background .13s ease, border-color .13s ease; }
.tip-crm-open:hover { background: var(--hover); border-color: var(--accent); }
.tip-crm-ic { flex: none; width: 26px; height: 26px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--primary-2) 12%, transparent); color: var(--primary-2); }
.tip-crm-ic svg { width: 14px; height: 14px; }
.tip-crm-b { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.tip-crm-t { display: flex; align-items: baseline; gap: 6px; min-width: 0; font-size: 13px; font-weight: 600; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-crm-num { flex: none; color: var(--muted); font-weight: 500; font-variant-numeric: tabular-nums; }
.tip-crm-m { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-size: 11.5px; line-height: 1.3; color: var(--muted); }
.tip-crm-stage { --sc: var(--muted); padding: 1px 7px; border-radius: 999px; font-weight: 600; color: var(--sc); background: color-mix(in srgb, var(--sc) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sc) 22%, transparent); }
.tip-crm-sum { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.tip-crm-co { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-crm.arch .tip-crm-t { color: var(--muted); text-decoration: line-through; }
.tip-crm-card .tip-chipbtn.dash { margin-top: 8px; }

/* ───────── КОНТЕКСТ СДЕЛКИ/ЛИДА В КАРТОЧКЕ ЗАДАЧИ: ФАКТ и ДЕТАЛИ ─────────
   Повод владельца: «задача выглядит из воздуха» — человек без права на сделку не видел блок
   ВООБЩЕ (гейт стоял внутри SQL). Строка приезжает всегда, детали — по единственному
   предикату сервера (`CrmAccess.detail_sql/5`).
   🔴 ОБЕ ТЕМЫ держатся на ТОКЕНАХ (--danger/--warning/--ok/--line/--panel-2): светлая тема
   переопределяет их в одном месте, своих hex здесь НЕТ. Акцент важности читается и в ч/б —
   иконка + СЛОВО, а не только цвет (канон accent); токен линии ≠ токен чернил. */
.tip-crm-v3 { flex-direction: column; align-items: stretch; gap: 7px; padding: 8px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); }
.tip-crm-v3 .tip-crm-open { border: 0; border-radius: 8px; background: transparent; padding: 2px; }
.tip-crm-v3 .tip-crm-open:hover { background: var(--hover); border-color: transparent; }
.tip-crm-head { display: flex; align-items: center; gap: 6px; }
/* Канон accent: пилюля на СВОЕЙ строке и ПО СОДЕРЖИМОМУ, а не во всю ширину блока. */
.tip-crm-acc { --sc: var(--warning); display: flex; width: fit-content; max-width: 100%; align-items: center; gap: 6px; padding: 3px 9px; border-radius: 999px; font-size: 11.5px; line-height: 1.25; color: var(--sc); background: color-mix(in srgb, var(--sc) 13%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sc) 22%, transparent); }
.tip-crm-acc.lvl-high { --sc: var(--danger); }
.tip-crm-acc svg { flex: none; width: 13px; height: 13px; }
.tip-crm-acc b { font-weight: 800; letter-spacing: .03em; }
.tip-crm-why { min-width: 0; color: var(--text); opacity: .72; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Сумма — крупным планом: это первое, за чем человек идёт в блок. «0 ₽» показываем честно. */
.tip-crm-amt { font-size: 17px; font-weight: 700; line-height: 1.15; font-variant-numeric: tabular-nums; }
.tip-crm-f { display: inline-flex; align-items: center; gap: 4px; min-width: 0; }
.tip-crm-f svg { flex: none; width: 12px; height: 12px; opacity: .75; }
.tip-crm-f.over { color: var(--danger); font-weight: 600; }
.tip-crm-src { font-style: normal; opacity: .7; }
.tip-crm-st { padding: 1px 7px; border-radius: 999px; font-weight: 600; background: color-mix(in srgb, var(--muted) 14%, transparent); }
.tip-crm-st.st-won { color: var(--ok); background: var(--ok-soft); }
.tip-crm-st.st-lost { color: var(--danger); background: var(--danger-soft); }
.tip-crm-grade { padding: 1px 7px; border-radius: 999px; font-weight: 800; color: var(--warning); background: var(--warning-soft); }
.tip-crm-grade.g-A, .tip-crm-grade.g-B { color: var(--ok); background: var(--ok-soft); }
.tip-crm-archp { padding: 1px 7px; border-radius: 999px; background: color-mix(in srgb, var(--muted) 16%, transparent); }
/* Скрытые детали: замок, причина СЛОВАМИ и ВЫХОД. Ни одной цифры здесь быть не может — их
   нет в самих данных (сервер не кладёт ключи amount/title вовсе, а не кладёт null). */
.tip-crm-v3.nodet { background: transparent; border-style: dashed; }
.tip-crm-v3 .tip-crm-open.static { flex: 1 1 auto; display: flex; align-items: center; gap: 9px; min-width: 0; padding: 2px; cursor: default; }
.tip-crm-v3.nodet .tip-crm-ic { background: color-mix(in srgb, var(--muted) 14%, transparent); color: var(--muted); }
.tip-crm-v3.gone .tip-crm-ic { background: var(--danger-soft); color: var(--danger); }
.tip-crm-hid { color: var(--muted); }
.tip-crm-say { font-size: 12px; line-height: 1.35; color: var(--muted); }
.tip-crm-fix { width: fit-content; }
/* Этапы работ — progressive-disclosure: закрыты по умолчанию, экран заранее не занимают. */
details.tip-crm-ph { border-top: 1px solid var(--line); padding-top: 6px; }
details.tip-crm-ph > summary { display: flex; align-items: center; gap: 6px; list-style: none; cursor: pointer; font-size: 12px; color: var(--muted); }
details.tip-crm-ph > summary::-webkit-details-marker { display: none; }
details.tip-crm-ph > summary svg { flex: none; width: 13px; height: 13px; }
details.tip-crm-ph > summary:hover { color: var(--text); }
.tip-crm-ph-n { padding: 0 6px; border-radius: 999px; background: color-mix(in srgb, var(--muted) 16%, transparent); font-variant-numeric: tabular-nums; }
.tip-crm-ph-prog { margin-left: auto; color: var(--primary-2); font-weight: 600; }
.tip-crm-ph-list { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.tip-crm-ph-row { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 12px; }
.tip-crm-ph-row.done .tip-crm-ph-t { color: var(--muted); text-decoration: line-through; }
.tip-crm-ph-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--sc, var(--muted)); }
.tip-crm-ph-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-crm-ph-s { flex: none; font-size: 11px; color: var(--sc, var(--muted)); }
.tip-crm-ph-row .tip-crm-f { flex: none; margin-left: auto; font-size: 11px; color: var(--muted); }
.tip-crm-more { margin: 2px 0 0; }

/* ── 🧭 CLIE-1543 · «Источник» задачи (письмо · контакт · сообщение) ──
   Строка ТА ЖЕ, что у сделки/лида (.tip-crm*): одна суть «с чем связана задача» — одна
   разметка. Своё тут ровно две вещи: подпись-капитель вида источника и цвет знака
   (акцент CRM у источника читался бы как «это сделка»). Токены — из темы, обе схемы. */
.tip-src .tip-crm-ic { background: color-mix(in srgb, var(--accent) 13%, transparent); color: var(--accent); }
.tip-src-cap { flex: none; font-size: 10.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
.tip-src-sub { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-src-card .td-section-h svg { color: var(--accent); }

/* 🚐 0480 · ВЫЕЗД В КАРТОЧКЕ (ИДЕИ-1860): куда · когда · к кому · шаги со временем · ОДНА
   главная кнопка следующего шага. Токены темы — обе схемы; цвет шага — акцент, выполнено — ok. */
.tip-visit-card .td-section-h svg { color: var(--accent); }
.tip-visit-st { margin-left: auto; font-size: 11.5px; font-weight: 600; padding: 2px 8px; border-radius: 999px; background: color-mix(in srgb, var(--accent) 13%, transparent); color: var(--accent); }
.tip-visit-card.st-done .tip-visit-st { background: color-mix(in srgb, var(--ok) 15%, transparent); color: var(--ok); }
.tip-visit-addr { font-size: 14.5px; font-weight: 600; color: var(--text); line-height: 1.35; word-break: break-word; }
.tip-visit-note { margin-top: 3px; font-size: 12.5px; color: var(--muted); white-space: pre-wrap; word-break: break-word; }
.tip-visit-meta { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 8px; font-size: 12.5px; color: var(--text); }
.tip-visit-m { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.tip-visit-m svg { width: 14px; height: 14px; color: var(--muted); flex: none; }
.tip-visit-m a { color: var(--accent); text-decoration: none; }
.tip-visit-steps { display: flex; gap: 6px; margin-top: 10px; }
.tip-visit-step { flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 5px; padding: 6px 8px; border-radius: 9px; border: 1px solid color-mix(in srgb, var(--muted) 30%, transparent); font-size: 12px; color: var(--muted); }
.tip-visit-step i { flex: none; width: 14px; height: 14px; border-radius: 50%; border: 1.5px solid color-mix(in srgb, var(--muted) 55%, transparent); display: inline-flex; align-items: center; justify-content: center; }
.tip-visit-step i svg { width: 10px; height: 10px; }
.tip-visit-step b { margin-left: auto; font-weight: 600; font-variant-numeric: tabular-nums; }
.tip-visit-step.on { color: var(--text); border-color: color-mix(in srgb, var(--ok) 45%, transparent); background: color-mix(in srgb, var(--ok) 8%, transparent); }
.tip-visit-step.on i { border-color: var(--ok); background: var(--ok); color: #fff; }
.tip-visit-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.tip-visit-acts .ghost svg { width: 13px; height: 13px; }
.tip-visit-go { min-width: 110px; }
.tip-visit-go svg { width: 14px; height: 14px; }
/* 🧾 0488 · АКТ ЗАЯВКИ: строка «Акт № N · статус» + «Подписание». Акцент — подложка 10–14 % и
   кольцо 22 %, без левой рейки; подписан — ok, отклонён — danger, ждёт подписи — accent. */
.tip-visit-act { display: flex; align-items: center; gap: 8px; margin-top: 10px; padding: 7px 8px 7px 10px; border-radius: 10px; font-size: 12.5px; color: var(--text);
  background: color-mix(in srgb, var(--accent) 10%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent); }
.tip-visit-act > svg { width: 14px; height: 14px; flex: none; color: var(--accent); }
.tip-visit-act > span { flex: 1 1 auto; min-width: 0; font-weight: 600; }
.tip-visit-act.ok { background: color-mix(in srgb, var(--ok) 11%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 22%, transparent); }
.tip-visit-act.ok > svg { color: var(--ok); }
.tip-visit-act.bad { background: color-mix(in srgb, var(--danger) 10%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent); }
.tip-visit-act.bad > svg { color: var(--danger); }
/* 📍 0487 · ТОЧКА ШАГА: строка на шаг — «на карте ±N м» кругу координат, «точка отмечена» прочим,
   причина словами у шага без точки. Без рейки: иконка + слово, акцент — цвет иконки. */
.tip-visit-geo { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; font-size: 12px; color: var(--muted); }
.tip-visit-geo-r { display: inline-flex; align-items: center; gap: 5px; min-width: 0; }
.tip-visit-geo-r .ic { width: 12px; height: 12px; flex: none; opacity: .7; }
.tip-visit-geo-r.on .ic { color: var(--ok); opacity: 1; }
.tip-visit-geo-r b { font-weight: 600; color: var(--text); }
.tip-visit-geo-r a { color: var(--primary); text-decoration: none; font-weight: 600; }
.tip-visit-geo-r a:hover { text-decoration: underline; }
/* 📷 0486 · ФОТО «ДО/ПОСЛЕ» У ПУНКТА ЗАЯВКИ: вторая строка пункта (кнопка-камера + миниатюры)
   и блок «Фотоотчёт» в карточке выезда. Отступ строки = грип + чекбокс, чтобы снимки стояли
   под текстом пункта, а не под галочкой. Ожидание сети — приглушённый кадр + часы, без цвета-тревоги. */
.tip-check.has-ph { flex-wrap: wrap; row-gap: 7px; }
.tip-ck-ph { flex: 1 0 100%; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 16px; padding-left: 55px; }
.tip-check.has-ph:not(:has(> .tip-ck-grip)) .tip-ck-ph { padding-left: 29px; }
.tip-ck-phg { display: inline-flex; align-items: center; gap: 5px; }
.tip-ck-phb { display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 11px 0 9px; border-radius: 14px;
  border: 1px solid var(--line); background: var(--panel); color: var(--text); font-size: 12.5px; font-weight: 500; cursor: pointer;
  transition: background .14s ease, border-color .14s ease; }
.tip-ck-phb svg.ic { width: 14px; height: 14px; color: var(--muted); }
.tip-ck-phb:hover { border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); background: color-mix(in srgb, var(--primary) 7%, var(--panel)); }
.tip-ck-phb:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 60%, transparent); outline-offset: 1px; }
.tip-ck-phl { font-size: 12px; color: var(--muted); }
.tip-ck-pht { position: relative; flex: none; width: 30px; height: 30px; padding: 0; border: 0; border-radius: 7px; overflow: hidden;
  cursor: zoom-in; background: var(--panel-2); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 12%, transparent); }
.tip-ck-pht img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tip-ck-pht.wait img { opacity: .5; }
.tip-ck-pht.wait i { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: #fff; }
.tip-ck-pht.wait i svg.ic { width: 13px; height: 13px; filter: drop-shadow(0 1px 2px rgba(0,0,0,.55)); }
.tip-ck-phmore { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.tip-phr { margin-top: 12px; padding-top: 11px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
.tip-phr-h { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 13px; font-weight: 600; color: var(--text); }
.tip-phr-h > svg.ic { width: 14px; height: 14px; color: var(--muted); }
.tip-phr-sum { font-size: 12px; font-weight: 500; color: var(--muted); font-variant-numeric: tabular-nums; }
.tip-phr-wait { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px; border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--muted) 30%, transparent); background: transparent; color: var(--muted); font-size: 11.5px; font-weight: 500; cursor: pointer; }
.tip-phr-wait svg.ic { width: 12px; height: 12px; }
.tip-phr-wait:hover { color: var(--text); border-color: var(--line); }
.tip-phr-row { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; border-radius: 10px; background: color-mix(in srgb, var(--text) 3.5%, transparent); }
.tip-phr-t { font-size: 13px; color: var(--text); line-height: 1.35; word-break: break-word; }
.tip-phr-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tip-phr-col { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.tip-phr-k { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.tip-phr-th { display: flex; flex-wrap: wrap; gap: 5px; }
.tip-phr-th .tip-ck-pht { width: 54px; height: 54px; border-radius: 9px; }
.tip-phr-none { font-size: 12px; color: var(--muted); }
.tip-phr-empty { font-size: 12.5px; color: var(--muted); line-height: 1.4; }
.vf-grid { display: flex; flex-direction: column; gap: 6px; }
.vf-grid .pm-label { margin-top: 4px; }
.vf-grid .pm-input.err { border-color: var(--danger, #e5484d); }

/* ── Связанные задачи (entity_links) ── */
.tip-links { display: flex; flex-direction: column; gap: 7px; }
.tip-link { display: flex; flex-direction: column; align-items: stretch; gap: 5px; }
.tip-link-row { display: flex; align-items: center; gap: 8px; }
/* Инлайн-чип статуса-триггера зависимости «старт после: <статус>» — компактная пилюля под строкой связи.
   Клик открывает выбор статуса предшественника (tipPickLinkTrigger). Токены → авто светлая/тёмная. */
.tip-link-trig { align-self: flex-start; margin-left: 2px; display: inline-flex; align-items: center; gap: 5px; padding: 3px 8px 3px 8px; border: 1px solid var(--line); border-radius: 999px; background: var(--panel-2); color: var(--muted); font-size: 11.5px; font-weight: 500; line-height: 1.35; cursor: pointer; transition: background .13s ease, border-color .13s ease, color .13s ease; }
.tip-link-trig svg { width: 13px; height: 13px; opacity: .75; flex: none; }
.tip-link-trig svg:last-child { width: 11px; height: 11px; opacity: .5; margin-left: -2px; }
.tip-link-trig b { color: var(--text); font-weight: 600; }
.tip-link-trig:hover { background: var(--hover); border-color: var(--accent); color: var(--text); }
.tip-trigpick .tip-trig-def { border-bottom: 1px solid var(--line); border-radius: 8px 8px 0 0; }
.tip-link-rel { flex: none; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; padding: 3px 7px; border-radius: 6px; background: rgba(139,147,163,.16); color: #aeb6c6; }
.tip-link-rel.lt-blocks { background: var(--urg-overdue-soft); color: var(--urg-overdue-ink); }
.tip-link-rel.lt-blocked { background: var(--urg-today-soft); color: var(--urg-today); }
.tip-link-rel.lt-duplicate { background: var(--cm-8b9cf5-16, rgba(139,156,245,.16)); color: var(--primary-2); }
/* Чип типа связи — кликабелен (инлайн-смена типа без пересоздания). Каретка = аффорданс; hover —
   тонкое кольцо в цвет типа (currentColor), одинаково хорошо в светлой и тёмной теме. */
button.tip-link-rel { border: 0; cursor: pointer; display: inline-flex; align-items: center; gap: 3px; font-family: inherit; transition: box-shadow .13s ease; }
button.tip-link-rel svg { width: 9px; height: 9px; opacity: .6; flex: none; margin-right: -1px; }
button.tip-link-rel:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, currentColor 45%, transparent); }
/* Пикер типа связи (tipPickLinkRel) — точка в цвет типа, как на чипе. Шелл наследует .td-userpick. */
.tip-relpick { min-width: 216px; }
.tip-relpick .tip-rel-dot { width: 9px; height: 9px; border-radius: 3px; flex: none; background: #8b93a3; }
.tip-relpick .tip-rel-dot.lt-blocks { background: var(--urg-overdue); }
.tip-relpick .tip-rel-dot.lt-blocked { background: var(--urg-today); }
.tip-relpick .tip-rel-dot.lt-duplicate { background: var(--primary-2); }

/* ── Пикер связи ── */
/* .td-userpick.tip-linkpick — специфичнее голого .td-userpick (перебивает его max-height:280px
   и overflow:auto): раньше весь попап упирался в 280px, а типы связи занимали 4 строки во всю
   ширину → списку задач оставалось ~2 строки. Теперь: типы = компактная сетка 2×2, а список —
   единственная прокручиваемая зона с нормальной высотой. */
.td-userpick.tip-linkpick { width: 300px; max-width: 92vw; max-height: min(72vh, 470px); padding: 10px; display: flex; flex-direction: column; gap: 8px; overflow: hidden; }
.tip-linkrels { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; flex-shrink: 0; }
.tip-linkrels .tip-link-hint { grid-column: 1 / -1; }
/* Компактные пилюли типа связи. Перебиваем .td-userpick button (width:100%; display:flex) —
   без этого каждая пилюля растягивалась на всю строку (те самые «4 строки»). */
.tip-linkpick .tip-relchip { width: 100%; display: inline-flex; align-items: center; justify-content: center; text-align: center; font-size: 12px; line-height: 1.25; padding: 6px 8px; border-radius: 9px; border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); cursor: pointer; transition: background .13s ease, border-color .13s ease, color .13s ease; }
.tip-linkpick .tip-relchip:hover { border-color: var(--muted); color: var(--text); }
.tip-linkpick .tip-relchip.on { border-color: var(--primary); color: var(--text); background: color-mix(in srgb, var(--primary) 16%, transparent); }
.tip-linksearch { flex-shrink: 0; background: var(--input-bg); border: 1px solid var(--line); border-radius: 8px; padding: 7px 9px; color: var(--text); font: inherit; outline: none; }
.tip-linksearch:focus { border-color: var(--primary); }
.tip-linklist { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-height: 0; max-height: 340px; overflow-y: auto; }
.tip-linklist button { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: transparent; border: 0; color: var(--text); font: inherit; font-size: 13px; padding: 7px 8px; border-radius: 7px; cursor: pointer; }
.tip-linklist button:hover { background: var(--panel-2); }
.tip-linklist button span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Секции пикера участников задачи (tipPickResponsible/tipPickUser): «Участники проекта /
   Сотрудники компании / Остальные» + роль/должность в строке. Apple-grade: тонкий аптечный
   заголовок группы, мягкая пилюля роли справа, вторичный @ник. */
.tip-linklist .up-sec { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); padding: 10px 8px 3px; user-select: none; pointer-events: none; }
.tip-linklist .up-sec:first-child { padding-top: 2px; }
.tip-linklist button .up-name { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-linklist button .up-hint { flex: 0 0 auto; color: var(--muted); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 34%; }
/* 🏢 CRMC-705·4: выбор компании клиента — шире, подписи «＋ Новая компания клиента» и «ваше пространство» не режутся */
.td-userpick.tip-linkpick.up-wide { width: 400px; }
.td-userpick.up-wide .tip-linklist button .up-hint { max-width: 48%; }
/* Строка-СУЩНОСТЬ (роль компании) вместо человека: цветная точка на месте аватара —
   ширина та же (10px + поля), поэтому имена в списке остаются на одной вертикали. */
.tip-linklist button .up-dot { flex: 0 0 auto; width: 10px; height: 10px; margin: 0 7px; border-radius: 50%; background: var(--rb, var(--muted)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--rb, var(--muted)) 16%, transparent); }
/* 👥 CRMC-671 · МНОГОВЫБОР в поповере людей (контакты сделки). Выбранная строка помечается
   галочкой и мягкой подложкой — тот же язык, что у `.ccpp-row.on` в пикере проектов; второго
   «мультипикера» продукт не заводит. */
.tip-linklist button.on { background: color-mix(in srgb, var(--primary) 10%, transparent); }
.tip-linklist button.on:hover { background: color-mix(in srgb, var(--primary) 16%, transparent); }
.tip-linklist button .up-check { flex: 0 0 auto; margin-left: auto; display: inline-flex; color: var(--primary); }
.tip-linklist button .up-check .ic { width: 15px; height: 15px; }
.tip-linklist button .up-role { flex: 0 0 auto; margin-left: auto; font-size: 11px; line-height: 1.35; padding: 2px 8px; border-radius: 999px; border: 1px solid color-mix(in srgb, var(--rb, var(--muted)) 42%, transparent); color: color-mix(in srgb, var(--rb, var(--muted)) 78%, var(--text)); background: color-mix(in srgb, var(--rb, var(--muted)) 13%, transparent); white-space: nowrap; max-width: 46%; overflow: hidden; text-overflow: ellipsis; }
/* «＋ Создать «…»» — строка создания новой связанной задачи прямо из пикера (акцентная,
   с иконкой в мягкой плашке). Специфичность .tip-linkpick .X (0,2,0) перебивает базовый
   .tip-linklist button (color:var(--text)). Светлая и тёмная темы — через var(--primary). */
.tip-linkpick .tip-linkcreate { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: color-mix(in srgb, var(--primary) 7%, transparent); border: 1px solid color-mix(in srgb, var(--primary) 20%, transparent); color: var(--primary); font: inherit; font-size: 13px; font-weight: 600; padding: 8px; border-radius: 8px; margin-bottom: 5px; cursor: pointer; transition: background .13s ease, border-color .13s ease; }
.tip-linkpick .tip-linkcreate:hover { background: color-mix(in srgb, var(--primary) 14%, transparent); border-color: color-mix(in srgb, var(--primary) 34%, transparent); }
.tip-linkpick .tip-linkcreate.ready { background: color-mix(in srgb, var(--primary) 12%, transparent); border-color: color-mix(in srgb, var(--primary) 32%, transparent); }
.tip-linkpick .tip-linkcreate .tip-lc-ic { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border-radius: 6px; background: color-mix(in srgb, var(--primary) 16%, transparent); flex: 0 0 auto; }
.tip-linkpick .tip-linkcreate .tip-lc-ic svg { width: 13px; height: 13px; }
.tip-linkpick .tip-linkcreate .tip-lc-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* Богатая строка попапа связей/подзадач: мини-карточка с ключевыми данными задачи. */
.tip-linklist button.rel-item { flex-direction: column; align-items: stretch; gap: 5px; padding: 8px 9px; }
.rel-item-top { display: flex; align-items: center; gap: 8px; }
.rel-item-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rel-item.done .rel-item-title { text-decoration: line-through; color: var(--muted); }
.rel-linktype { flex: none; font-size: 10px; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); }
.rel-item-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding-left: 17px; }
.rel-item-meta span:last-child { overflow: visible; }
.rel-status { flex: none; font-size: 10.5px; padding: 2px 7px; border-radius: 6px; background: rgba(139,147,163,.16); color: #aeb6c6; display: inline-flex; align-items: center; gap: 3px; }
.rel-status.s-done { background: var(--urg-done-soft); color: var(--urg-done); }
.rel-status.s-in_progress { background: var(--info-soft); color: var(--info); }
.rel-status.s-cancelled { background: rgba(107,114,128,.16); color: #8b93a3; }
.rel-status svg.ic { width: 11px; height: 11px; }
.rel-chip { flex: none; display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--muted); }
.rel-chip svg.ic { width: 12px; height: 12px; }
.rel-chip.due-overdue { color: var(--urg-overdue-ink); }
.rel-chip.due-today { color: var(--urg-today); }
.rel-avs { margin-left: auto; display: inline-flex; }
@media (max-width: 1080px) { .task-info-panel { display: none !important; } }
/* Та же рич-панель задачи, но как МОДАЛКА поверх чата — на узких экранах (где докнутая
   скрыта правилом выше). Тап по шапке чата задачи открывает её здесь. Класс `.as-overlay`
   двухклассовой специфичностью + !important перебивает `display:none` медиа-правила. */
.task-info-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,.55); z-index: 60; }
.task-info-backdrop.hidden { display: none; }
.task-info-panel.as-overlay {
  display: flex !important; position: fixed; z-index: 61;
  top: 0; right: 0; left: auto; bottom: 0; transform: none;
  /* Ширина модалки задачи. По умолчанию 480px, но пользователь может ТЯНУТЬ левую кромку —
     сохранённое значение приходит в --w-taskinfo-ov (см. bindResizer/applyTaskOverlayWidth).
     min(…, 96vw) всегда прижимает к вьюпорту (напр. если окно сузили после сохранения). */
  width: min(var(--w-taskinfo-ov, 480px), 96vw); height: 100dvh; max-height: none;
  border: 0; border-left: 1px solid var(--line); border-radius: 0;
  box-shadow: -18px 0 50px rgba(0,0,0,.5); overflow: hidden;
  animation: taskDrawerIn .22s ease;
}
@keyframes taskDrawerIn { from { transform: translateX(100%); } to { transform: translateX(0); } }
.tip-close { background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 4px; border-radius: 8px; display: none; flex: none; }
.tip-close svg.ic { width: 16px; height: 16px; }
.tip-close:hover { background: var(--panel-2); color: var(--text); }
.task-info-panel.as-overlay .tip-close { display: inline-flex; }

/* ══ 🪟 СВЁРНУТОЕ ОКНО ЗАДАЧИ (CLIE-602) ══
   «Свернуть» — третье состояние карточки между «открыто» и «закрыто»: окно уезжает
   вправо (обратная анимация появления) и остаётся живым ярлыком в доке внизу.
   Кнопка — брат-близнец ✕ (тот же размер/радиус/тон), стоит слева от него: порядок
   системных кнопок окна «свернуть → закрыть». Видна только у шторки-оверлея. */
.tip-min { background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 4px; border-radius: 8px; display: none; flex: none; }
.tip-min svg.ic { width: 16px; height: 16px; }
.tip-min:hover { background: var(--panel-2); color: var(--text); }
.task-info-panel.as-overlay .tip-min { display: inline-flex; }
.task-info-panel.as-overlay.minimizing { animation: taskDrawerMin .17s ease forwards; }
@keyframes taskDrawerMin { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: .55; } }

/* ── Свёрнутое окно задачи ──
   Сквозной элемент: `position:fixed` на <body>, поэтому видно на ЛЮБОМ экране без
   единой строки кода в этом экране (правило CLIE-434 «от обратного»). Исходное место —
   низ слева, рядом с пузырём быстрого чата; --mw-bottom считает JS по контракту
   BOTTOM_FIXED_SEL, чтобы не влезть под чужую нижнюю полосу.

   🔴 ЭТО ОКНО, А НЕ ПИЛЮЛЯ (владелец: «плохо видно свёрнутую задачу, и нужна
   возможность её перетаскивать»). Значит: живая рама с тенью и хваталкой, название
   ЦЕЛИКОМ в две строки, перетаскивание (общий makeFloatingWindow → класс `.placed`
   и инлайн left/top) и тянущаяся ширина (WIN_PANES → `.col-resizer` внутри рамы).
   Прибитой ширины здесь быть не может — только исходная. */
.cc-min-dock { position: fixed; left: 160px; bottom: var(--mw-bottom, 20px); z-index: 9120;
  width: 320px; max-width: calc(100vw - 32px); box-sizing: border-box;
  padding: 5px 6px 7px; border: 1px solid var(--line); border-radius: 16px;
  background: var(--panel); color: var(--text);
  box-shadow: 0 22px 50px rgba(0,0,0,.30), 0 3px 10px rgba(0,0,0,.14), inset 0 1px 0 rgba(255,255,255,.06);
  backdrop-filter: saturate(1.6) blur(18px);
  cursor: grab; touch-action: none;
  /* 🔴 Появление — ТОЛЬКО прозрачностью, без transform. Трансформ на самой раме врал бы
     геометрию окна: getBoundingClientRect во время анимации отдаёт смещённый и суженный
     прямоугольник (замер на проде: 320×102 в (630,458) читались как 310×99 в (635,470)),
     а по этому прямоугольнику окно пере-ставляют кламп ресайза и общий механизм окна —
     то есть окно тихо «сползало» бы при каждом показе. Пружинку показываем на самой
     строке (`.mw-chip.pop`), она в геометрии рамы не участвует. */
  animation: mwWin .18s ease; }
.cc-min-dock:active { cursor: grabbing; }
/* Человек передвинул окно — верх/лево задаёт JS, исходная привязка к низу снимается. */
.cc-min-dock.placed { bottom: auto; }
.cc-min-dock.hidden { display: none; }
@keyframes mwWin { from { opacity: 0; } to { opacity: 1; } }
/* Хваталка окна — та же метафора, что у системного листа: «возьми и перетащи». */
.mw-grab { display: block; width: 34px; height: 4px; margin: 1px auto 6px; border-radius: 3px;
  background: color-mix(in srgb, var(--muted) 55%, transparent); }
.mw-stack { display: flex; flex-direction: column; gap: 1px; touch-action: pan-y;
  max-height: min(46vh, 380px); overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
.mw-chip { display: flex; align-items: flex-start; gap: 9px; padding: 7px 6px 8px 7px;
  border-radius: 11px; background: transparent; color: var(--text); cursor: pointer;
  transition: background .14s ease; }
/* Разделитель между свёрнутыми окнами — хэйрлайн СВЕРХУ (левых полосок-реек не держим). */
.mw-chip + .mw-chip { border-top: 1px solid var(--line); border-radius: 0 0 11px 11px; }
.mw-chip:hover { background: var(--panel-2); }
.mw-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.mw-chip.pop { animation: mwPop .19s cubic-bezier(.22,.9,.32,1.2); }
@keyframes mwPop { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
/* Плитка-«иконка окна»: строка читается как СВЁРНУТОЕ ОКНО, а не как фильтр-пилюля. */
.mw-ic { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 8px; margin-top: 1px; color: var(--accent);
  background: color-mix(in srgb, var(--accent) 14%, transparent); }
.mw-ic svg.ic { width: 15px; height: 15px; }
.mw-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* Название ЦЕЛИКОМ, до трёх строк: обрубок «Нужна возможност…» — то, на что жаловались.
   Три строки — это ~100 символов на исходной ширине окна; длиннее названий у задач почти
   не бывает, а если попадётся — окно РАСТЯГИВАЕТСЯ мышью (правило «ни одной прибитой ширины»). */
.mw-t { font-size: 13.5px; font-weight: 600; line-height: 1.3; letter-spacing: -.005em;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.mw-meta { display: flex; align-items: center; gap: 6px; min-width: 0;
  font-size: 11.5px; font-weight: 500; color: var(--muted); }
.mw-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; }
.mw-code { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mw-x { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; border: 0; border-radius: 8px; margin-top: 1px;
  background: transparent; color: var(--muted); cursor: pointer; opacity: .55;
  transition: opacity .12s ease, background .12s ease, color .12s ease; }
.mw-x svg.ic { width: 14px; height: 14px; }
.mw-chip:hover .mw-x, .mw-chip:focus-within .mw-x { opacity: .9; }
.mw-x:hover { opacity: 1; background: var(--panel-2); color: var(--text); }
/* Тач: наводить нечем — крестик виден всегда (мёртвых контролов не держим). */
@media (hover: none) { .mw-x { opacity: .75; } }
@media (max-width: 720px) {
  .cc-min-dock { left: 12px; width: min(320px, calc(100vw - 24px)); bottom: var(--mw-bottom, 16px); }
}
.task-info-panel.as-overlay .tip-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
@media (max-width: 560px) {
  .task-info-panel.as-overlay { width: 100vw; height: 100dvh; max-height: 100dvh;
    top: 0; left: 0; transform: none; border: 0; border-radius: 0; }
}
/* ── Вкладка «Чат» шторки задачи: сюда ФИЗИЧЕСКИ переносится единый узел <main.thread> ──
   Одна реализация чата (голосовые/кружочки/переводы/документы/«в ИИ»/ответы/стикеры) —
   тред просто «переезжает» в шторку и обратно; шторка шире, чтобы чат был удобен. */
.tip-chat-host { display: none; }
/* Вкладка «Чат» специально ШИРЕ (760 vs 480) и имеет СВОЮ сохраняемую ширину
   (--w-taskinfo-ov-chat), чтобы ресайз чата не затирал ширину карточки и наоборот. */
.task-info-panel.as-overlay.tab-chat { width: min(var(--w-taskinfo-ov-chat, 760px), 96vw); flex-direction: column; }
.task-info-panel.tab-chat .tip-scroll { display: none; }
.task-info-panel.tab-chat .tip-chat-host { display: flex; flex: 1 1 auto; min-height: 0; flex-direction: column; overflow: hidden; }
/* 🔴 РАСКЛАДКА ПЕРЕЕХАВШЕГО ТРЕДА ОПИСАНА ПО КЛАССУ ХОСТА, А НЕ ПО ЕГО ID (CLIE-942·3).
   Копий этих трёх строк было ТРИ (#tipChatHost задачи, #tkChatHost тикета, #brdChatHost
   карточки доски), и КАЖДОЙ новой карточке с вкладкой «Обсуждение» их приходилось заводить
   заново — у карточки идеи их не завели вовсе, и переехавший <main.thread> оставался без
   высоты. Класс `.tip-chat-host` носят ВСЕ хосты (его ставит та же строка, что создаёт узел),
   поэтому новая карточка получает раскладку БЕЗ единой строки CSS. */
.task-info-panel.tab-chat .tip-chat-host > main.thread { display: flex; flex: 1 1 auto; min-height: 0; width: auto; }
.task-info-panel.tab-chat .tip-chat-host .thread-head { padding-left: 14px; }
/* внутри шторки не нужна мобильная кнопка «назад к списку» */
.task-info-panel.tab-chat .tip-chat-host #backToList { display: none !important; }
/* 🔴 «ОБСУЖДЕНИЕ» СУЩНОСТИ ≠ ЭКРАН БЕСЕДЫ: полоса каналов («Чат · Canvas · Карта ·
   Автоответы · Оповещения») принадлежит экрану беседы, а внутри карточки она и лишняя, и
   врёт (подсвечена не та вкладка). Помечается САМ ХОСТ (`as-discussion`), а не
   перечисляются id — белый список поверхностей уже трижды рождал дыры. */
.task-info-panel.tab-chat .tip-chat-host.as-discussion .cc-chan-tabs,
.task-info-panel.tab-chat .tip-chat-host.as-discussion #ccChanTabs { display: none !important; }
/* Кнопка «Открыть переписку с клиентом» на вкладке «Карточка» — во всю ширину, иконка+текст снугом по центру. */
.ticket-info-panel .tkd-openchat { margin-top: 2px; }
.ticket-info-panel .tkd-openchat button { width: 100%; display: inline-flex; align-items: center; justify-content: center; gap: 7px; }
/* ticketcard-hero-flat-1: статус обращения (селект или пилюля) и SLA — факты героя: они стоят в шапке рамы
   второй строкой под именем (renderTicketInfoPanel), как статус · автор · голоса у идеи. */
.ticket-info-panel > .tip-head { flex-wrap: wrap; }
.ticket-info-panel > .tip-head > .tkd-head { flex: 1 1 100%; min-width: 0; }
@media (max-width: 560px) { .task-info-panel.as-overlay.tab-chat { width: 100vw; } }
@media (max-width: 760px) {
  /* ticket-chat-title-trunc-1: обращение в отказе («не удалось открыть» · «Повторить») — пять кругов 44 в шапке
     (x120–372), имя «Переписка …» сжато до 106 px. Поиск и звонки запирает ccThreadCtlLock, «Спросить ИИ» и
     «Переводчик» выключены разметкой до первой беседы, а fitChatHeader складывает в «⋯» только живые (hdrBtnActs
     пропускает disabled). Выключенная кнопка — не вход: в карточке на телефоне её нет. Вес — как у .hdr-fold. */
  .task-info-panel > .tip-chat-host .thread-head .head-actions > button:disabled { display: none !important; }
}

/* ══ 💬 ЧАТ СЛЕВА ОТ КАРТОЧКИ — СПЛИТ РАМЫ КАРТОЧКИ (CLIE-1047) ══
   Владелец: «слева много пустого места, которое можно использовать под чат. Подефолту чат
   слева отображается и ширина модалки вместе с чатом 80% экрана… можно выбрать какой чат
   отобразить слева: с участниками, с ИИ или с Ая… всё можно скрыть во вкладку или отобразить
   слева». Раньше чат и карточка были ВЗАИМОИСКЛЮЧАЮЩИМИ вкладками одной шторки 480/760px:
   читать карточку и вести разговор одновременно было нечем, а 2/3 экрана слева пустовали.

   🔴 ОДНА РАМА — ЧЕТЫРЕ ПОВЕРХНОСТИ. Класс `.tip-split` встаёт на ТУ ЖЕ раму
   `.task-info-panel.as-overlay`, которой уже живут карточка задачи (#taskInfoPanel), карточка
   доски (#brdCardPanel), карточка идеи (#ideaCardPanel) и тикет (#ticketInfoPanel) — сплит
   достаётся всем четырём без единой копии вёрстки (тот же приём, что `.tip-chat-host`).

   🔴 РАСКЛАДКА — ГРИД ПО САМОЙ ПАНЕЛИ, БЕЗ ОБЁРТОК. Завести контейнер-столбец и перенести в
   него хост чата нельзя: в хосте живёт ЕДИНЫЙ <main.thread>, а перевешивание узла в DOM
   обнуляет прокрутку ленты (человек теряет место в разговоре на каждой перерисовке карточки).
   Поэтому столбцы задаются `grid-area` у тех же прямых детей панели.

   Ширину левого столбца держит ПЕРЕМЕННАЯ на панели (--w-tip-side) — как у грид-колонок чата
   (--w-projects/--w-tasks/--w-chats): её пишет то же drag-ядро bindResizer (COL_SPECS.tipside)
   через хваталку `.col-resizer.col-resizer-seam`. Прибитой ширины тут нет ни одной. */
/* 🔴 `:not(.hidden)` обязателен: `.hidden{display:none!important}` слабее по специфичности, и
   без оговорки закрытая панель с оставшимся классом снова показалась бы на экране. */
.task-info-panel.as-overlay.tip-split:not(.hidden) {
  width: min(var(--w-taskinfo-ov-split, 80vw), 96vw);
  display: grid !important;
  grid-template-columns: var(--w-tip-side, 380px) minmax(300px, 1fr);
  grid-template-rows: auto auto minmax(0, 1fr);
}
.tip-split > .tip-sidebar { grid-area: 1 / 1 / 2 / 2; }
.tip-split > .tip-chat-host { grid-area: 2 / 1 / 4 / 2;
  display: flex; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden;
  border-right: 1px solid var(--line); }
.tip-split > .tip-head { grid-area: 1 / 2 / 2 / 3; }
.tip-split > .tip-tabs { grid-area: 2 / 2 / 3 / 3; }
.tip-split > .tip-scroll,
.tip-split > .tip-history-host,
.tip-split > .tip-media-host { grid-area: 3 / 2 / 4 / 3; min-width: 0; }
/* Высоту переехавшему треду даёт КЛАСС хоста, а не id (правило CLIE-942·3): новая карточка
   с обсуждением получает раскладку сплита без единой собственной строки CSS. */
.tip-split > .tip-chat-host > main.thread { display: flex; flex: 1 1 auto; min-height: 0; width: auto; }
.tip-split > .tip-chat-host .thread-head { padding-left: 14px; }
.tip-split > .tip-chat-host #backToList { display: none !important; }
/* «Обсуждение» сущности ≠ экран беседы — полоса каналов внутри карточки лишняя (см. .tab-chat). */
.tip-split > .tip-chat-host.as-discussion .cc-chan-tabs,
.tip-split > .tip-chat-host.as-discussion #ccChanTabs { display: none !important; }
/* Собеседник, который УЖЕ стоит слева, не дублируется вкладкой в ряду: метку `tip-tab-side`
   вешает сама дверь (`ccCardSideSync`) по СПИСКУ доступных собеседников — белого списка
   `data-tiptab`/`data-brdtab`/… в стилях нет, иначе новая рама молча не попала бы в правило. */
.task-info-panel.tip-split .tip-tab.tip-tab-side { display: none; }
/* Полоса собеседника над чатом: ровно строка шапки карточки, чтобы шов читался одной линией.
   Переключатель — КАНОН `.cc-seg` (своей дорожки с пилюлей не заводим, правило CLIE-505). */
.tip-sidebar { display: flex; align-items: center; gap: 8px; min-width: 0;
  padding: 8px 12px; border-bottom: 1px solid var(--line); border-right: 1px solid var(--line);
  background: var(--panel); }
.tip-sidebar .cc-seg { min-width: 0; }
.tip-side-t { display: inline-flex; align-items: center; gap: 7px; min-width: 0;
  font-size: 13px; font-weight: 640; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-side-t svg.ic { width: 15px; height: 15px; flex: none; color: var(--primary-2); }
/* Шов «чат | карточка»: у панели overflow:hidden, поэтому хваталка сидит ВНУТРИ, ровно на
   границе столбцов, и едет вместе с переменной ширины. */
.col-resizer.col-resizer-seam { right: auto; left: var(--w-tip-side, 380px); width: 11px; margin-left: -5px; z-index: 16; }
.col-resizer.col-resizer-seam::after { left: 5px; transform: none; }
/* «Чат слева / спрятать во вкладку» — брат-близнец соседних иконок шапки (глаз, «Поделиться»). */
.tip-sidebtn { background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 4px; border-radius: 8px; display: inline-flex; flex: none; transition: background .12s, color .12s; }
.tip-sidebtn svg.ic { width: 17px; height: 17px; }
.tip-sidebtn:hover { background: var(--panel-2); color: var(--text); }
.tip-sidebtn.on { color: var(--primary); }
/* Узкий экран: двум столбцам места нет — рама возвращается к прежнему виду (чат вкладкой).
   JS снимает `.tip-split` сам по resize, это страховка на кадр между событием и пересборкой. */
@media (max-width: 899px) {
  .task-info-panel.as-overlay.tip-split:not(.hidden) { display: flex !important; width: min(var(--w-taskinfo-ov, 480px), 96vw); }
  /* `:not(.tab-chat)` у хоста: JS снимает `tip-split` сам (`ccCardSideSync` на `resize`), но до
     его первого тика правило не должно спорить с обычной вкладкой «Чат» — иначе на узком экране
     человек нажал бы «Чат» и увидел пустоту. */
  .tip-split > .tip-sidebar, .tip-split > .col-resizer-seam { display: none; }
  .tip-split:not(.tab-chat) > .tip-chat-host { display: none; }
  .task-info-panel.tip-split .tip-tab.tip-tab-side { display: inline-flex; }
}
/* Вкладка «История» задачи — свой хост-пейн #tipHistoryHost (по аналогии с #tipChatHost).
   Активна по классу .tab-history: карточку и чат прячем, показываем историю. Хост — ЕДИНСТВЕННЫЙ
   скролл на всю высоту вкладки; история = чистый список во всю ширину (не карточка-коробка).
   🔴 Глобальное `.td-activity{max-height:150px;overflow:auto}` (от старой модалки) душило список в
   мелкий внутренний скролл с пустотой снизу — гасим его тут селектором выше по специфичности. */
.tip-history-host { display: none; }
.task-info-panel.tab-history .tip-scroll { display: none; }
/* `:not(.tip-split)` — в сплите (чат СЛЕВА, CLIE-1047) вкладка «История» меняет только ПРАВЫЙ
   столбец; левый столбец с чатом при этом остаётся на месте, иначе переключение вкладки
   выкидывало бы человека из разговора, который он специально держит открытым. */
.task-info-panel.tab-history:not(.tip-split) .tip-chat-host { display: none; }
.task-info-panel.tab-history .tip-history-host { display: flex; flex: 1 1 auto; min-height: 0; flex-direction: column; overflow-y: auto; padding: 14px 16px 24px; }
.task-info-panel.tab-history .tip-history { background: transparent; border: 0; border-radius: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.task-info-panel.tab-history .tip-history .td-section-h { color: var(--primary-2); margin: 0 0 2px; }
.task-info-panel.tab-history .td-source { margin: 0 0 4px; }
.task-info-panel.tab-history .td-activity { max-height: none; overflow: visible; gap: 0; margin-top: 0; }
.task-info-panel.tab-history .td-act-row { padding: 9px 2px; border-bottom: 1px solid var(--line); font-size: 13px; line-height: 1.4; }
.task-info-panel.tab-history .td-act-row:last-child { border-bottom: 0; }
/* Вкладка «Медиа и файлы» — свой хост-пейн #tipMediaHost (по аналогии с #tipHistoryHost).
   Активна по классу .tab-media: карточку/чат/историю прячем, показываем медиа во всю высоту. */
.tip-media-host { display: none; }
.task-info-panel.tab-media .tip-scroll { display: none; }
/* `:not(.tip-split)` — см. пояснение у `.tab-history` выше: в сплите вкладка меняет ПРАВЫЙ столбец. */
.task-info-panel.tab-media:not(.tip-split) .tip-chat-host { display: none; }
.task-info-panel.tab-media .tip-history-host { display: none; }
.task-info-panel.tab-media .tip-media-host { display: flex; flex: 1 1 auto; min-height: 0; flex-direction: column; overflow-y: auto; padding: 14px 16px 24px; }
/* Панель = 5-я колонка grid .chat (только на широких экранах, где она показывается).
   Тикет-панель (.with-ticket-info) — тот же приём: беседа-источник в центре, инфа тикета справа. */
@media (min-width: 1081px) {
  /* --rw-projects/--rw-tasks — см. базовый .chat: сворачивание/скрытие столбцов
     проектов/задач переопределяет их, а инфо-панель (330px) остаётся хвостом. */
  .chat.with-task-info { grid-template-columns: var(--rail-track) var(--rw-projects) var(--rw-tasks) var(--w-chats, 280px) 1fr var(--w-taskinfo, 330px); }
  .chat.with-ticket-info { grid-template-columns: var(--rail-track) var(--rw-projects) var(--rw-tasks) var(--w-chats, 280px) 1fr 330px; }
  /* Панель задачи свёрнута → 6-я колонка схлопывается в 0, чат (5-я, 1fr) занимает всё место. */
  .chat.with-task-info.taskinfo-collapsed { grid-template-columns: var(--rail-track) var(--rw-projects) var(--rw-tasks) var(--w-chats, 280px) 1fr 0; }
}
/* Свёрнуто прячем только ДОКНУТУЮ карточку задачи (по id, не по .task-info-panel — чтобы не
   задеть панель тикета) и только в докнутом виде (оверлей — фиксированная шторка, её не трогаем). */
.chat.taskinfo-collapsed #taskInfoPanel:not(.as-overlay) { display: none; }
/* Тикет-панель: селекты статуса/приоритета/ответственного — во всю ширину секции. */
.ticket-info-panel .tw-select { width: 100%; }
.ticket-info-panel .tip-title { display: inline-flex; align-items: center; gap: 6px; }
.ticket-info-panel .tip-title svg.ic { width: 15px; height: 15px; color: var(--primary); flex: none; }
.ticket-info-panel #tipTkCsat { display: inline-flex; gap: 2px; }
.td-assignees { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.td-asg { display: inline-flex; align-items: center; gap: 6px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 4px 6px 4px 4px; font-size: 12.5px; }
.td-asg .tw-av { width: 22px; height: 22px; margin: 0; }
.td-asg button { background: none; border: none; color: var(--muted); cursor: pointer; padding: 0 2px; font-size: 14px; }
.td-asg button:hover { color: var(--urg-overdue-ink); }
.td-asg-add { border-style: dashed; cursor: pointer; color: var(--muted); }
.td-asg-add:hover { color: var(--text); border-color: var(--primary); }
.td-check-list { display: flex; flex-direction: column; gap: 6px; }
.td-check-item { display: flex; align-items: flex-start; gap: 11px; padding: 11px 8px; border-radius: 8px; }
.td-check-item:hover { background: var(--panel-2); }
.td-check-item.done span { color: var(--text); opacity: .72; text-decoration: line-through; }
.td-check-box { flex: 0 0 auto; width: 18px; height: 18px; border-radius: 5px; border: 2px solid var(--line); background: transparent; cursor: pointer; display: flex; align-items: center; justify-content: center; color: #fff; }
.td-check-item.done .td-check-box { background: var(--ok); border-color: var(--ok); }
.td-check-box svg { width: 11px; height: 11px; }
.td-check-item span { flex: 1; font-size: 14.5px; line-height: 1.45; }
.td-check-item .td-check-del { opacity: 0; background: none; border: none; color: var(--muted); cursor: pointer; }
.td-check-item:hover .td-check-del { opacity: .7; }
.td-check-add { display: flex; gap: 8px; margin-top: 4px; }
.td-check-add input { flex: 1; background: var(--panel-2); border: 1px solid var(--line); color: var(--text); border-radius: 9px; padding: 7px 10px; font-size: 13px; }
.td-check-add input:focus { outline: none; border-color: var(--primary); }
.td-activity { display: flex; flex-direction: column; gap: 6px; max-height: 150px; overflow-y: auto; }
.td-act-row { font-size: 12px; color: var(--muted); }
.td-act-row b { color: var(--text); font-weight: 600; }
.td-source { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--primary-2); }

/* мини-пикер исполнителей (popover у кнопки «добавить») */
.td-userpick { position: fixed; z-index: 80; min-width: 220px; max-height: 280px; overflow-y: auto; background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 6px; box-shadow: 0 14px 40px rgba(0,0,0,.55); }
.td-userpick button { display: flex; align-items: center; gap: 9px; width: 100%; background: none; border: none; color: var(--text); text-align: left; padding: 8px 9px; border-radius: 8px; cursor: pointer; font-size: 13px; }
.td-userpick button:hover { background: var(--panel); }
/* заголовок секции в пикере проекта/чата («Проекты», «Чаты и группы») */
.td-userpick .td-pick-sec { padding: 8px 9px 3px; font-size: 10.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); pointer-events: none; }
.td-userpick .td-pick-sec:first-child { padding-top: 3px; }
/* Подпись-объяснение в пикере (CLIE-1191): «воронка проекта не доехала — вот базовые статусы».
   Мёртвая кнопка и молчание запрещены: короткий список обязан сказать, ПОЧЕМУ он короткий.
   Чернила — var(--muted) к подложке var(--panel-2) самого пикера (канон contrast-runtime-audit:
   меряем к СВОЕЙ подложке, а не к белой карточке). */
.td-userpick .td-pick-note { padding: 7px 9px 8px; margin-top: 4px; border-top: 1px solid var(--line); font-size: 11.5px; line-height: 1.35; color: var(--muted); white-space: normal; pointer-events: none; }
/* Пикер «Модель ИИ» — СНАЧАЛА по способности (Текст/Картинки/Видео), внутри по провайдерам. */
.td-userpick.tip-aimodelpick { min-width: 252px; max-width: 304px; }
.td-userpick .td-pick-cap { padding: 9px 9px 4px; margin-top: 4px; border-top: 1px solid var(--line); font-size: 11px; font-weight: 700; letter-spacing: .02em; color: var(--text); pointer-events: none; }
.td-userpick .td-pick-cap:first-child { margin-top: 0; border-top: 0; padding-top: 4px; }
.td-userpick .aim-name { flex: 1 1 auto; display: inline-flex; align-items: center; gap: 7px; min-width: 0; }
.td-userpick .aim-def { flex: 0 0 auto; font-size: 10px; font-weight: 600; color: var(--accent); border: 1px solid var(--accent); border-radius: 5px; padding: 0 5px; }
.td-userpick .td-pick-sec .aim-vendor { margin-left: 6px; font-size: 10px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--muted); }
/* Модель картинок/видео в пикере задачи — пока НЕ исполняется агентным воркером (серверной
   генерации ещё нет). Показываем, но выбрать нельзя («Скоро») — чтобы не было «мёртвого» выбора
   и задачи, зависшей в очереди навсегда. Включим, когда появится генерация. */
.td-userpick .aim-soon { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 9px; border-radius: 8px; color: var(--muted); cursor: default; opacity: .72; }
.td-userpick .aim-soon .aim-name { color: var(--muted); }
.td-userpick .aim-soon-tag { flex: 0 0 auto; font-size: 9.5px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px; }
.td-userpick .tip-aim-note { padding: 5px 10px 6px; font-size: 10.5px; line-height: 1.35; color: var(--muted); pointer-events: none; }
/* Мультипроект (0065): строка проекта в пикере — имя тянется, ★ задаёт основной. */
.td-userpick .tip-projrow .tip-projname { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-userpick .tip-projrow.on { background: var(--panel); }
.td-userpick .tip-primary { flex: 0 0 auto; font-size: 13px; line-height: 1; color: var(--muted); opacity: .5; padding: 2px 4px; border-radius: 6px; cursor: pointer; }
.td-userpick .tip-primary:hover { opacity: .9; background: var(--panel-2); }
.td-userpick .tip-primary.is { color: #f5a623; opacity: 1; }

/* на узких экранах подписи видов в сегменте прячем, оставляем иконки */
@media (max-width: 860px) {
  .tw-seg .tw-seg-label { display: none; }
  .tw-board { flex-direction: column; height: auto; padding: 12px 16px; }
  .tw-board::after { display: none; }
  .tw-col { max-width: none; width: 100%; }
}

/* ───────────────────────── Стикеры (анимированные Lottie) ─────────────────────────
   Кнопка-пикер в композере (.picker-btn — единый эмодзи+стикеры), докированная панель
   НАД полем, рендер стикера в треде. Состояние «открыто» — .picker-btn.on (ниже, у сегмента). */

/* Стикер в треде: бордерлесс (.bubble.has-media уже снимает фон/тень). */
.sticker-msg { width: 170px; height: 170px; max-width: 46vw; max-height: 46vw; }
.sticker-msg svg { width: 100% !important; height: 100% !important; display: block; }
/* Картиночный стикер (паки getstickerpack.com) — тот же размер, что Lottie, БЕЗ пузыря.
   Мягкий ореол/тень держит контраст на любой теме: белый ореол в тёмной (чёрный контур
   виден), мягкая тёмная тень в светлой (см. html[data-theme="light"] ниже). */
.sticker-msg-img { width: 170px; height: 170px; max-width: 46vw; max-height: 46vw;
  object-fit: contain; display: block; -webkit-user-drag: none; user-select: none;
  /* Симметричный ореол (не направленная тень — её обрезал бы overflow:hidden пузыря):
     белый в тёмной теме держит контраст чёрного лайн-арта (Кругляш/коты). */
  filter: drop-shadow(0 0 1.2px rgba(255,255,255,.5)); }

/* Докированная панель (живёт между layout-suggest и composer, флекс-колонка чата
   ужимает messages под неё). */
.sticker-panel {
  display: flex; flex-direction: column;
  /* Окно выше и адаптивное: больше рядов видно за раз, но не съедает весь чат
     на низком окне (пол 360 > прежних 340, растёт до 540 на высоком экране). */
  height: clamp(360px, 54vh, 540px); min-height: 360px;
  background: var(--panel); border-top: 1px solid var(--line); overflow: hidden;
  animation: spIn .2s cubic-bezier(.34,1.56,.64,1);
}
.sticker-panel.hidden { display: none; }
@keyframes spIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

.sp-search { display: flex; align-items: center; gap: 8px; height: 38px; margin: 8px 10px 6px;
  background: var(--panel-2); border-radius: 11px; padding: 0 11px; flex: 0 0 auto; }
.sp-search-ic { color: var(--muted); display: inline-flex; }
.sp-search-ic svg.ic { width: 16px; height: 16px; }
.sp-search-input { flex: 1; background: transparent; border: 0; outline: none; color: var(--text);
  font-size: 13px; height: 100%; }
.sp-search-input::placeholder { color: var(--muted); }

.sp-body { flex: 1; overflow-y: auto; position: relative; padding: 0 10px 8px; }
.sp-sect { } 
.sp-head { position: sticky; top: 0; z-index: 1; background: var(--panel); color: var(--muted);
  font-size: 11px; font-weight: 600; letter-spacing: .02em; padding: 9px 2px 6px;
  display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.sp-head-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ⭐ «Пак в избранное» — звезда справа в заголовке пака (только у паков, не у Недавних/Избранного).
   По умолчанию приглушённый контур; hover — ярче; активная (пак избран) — золотая залитая. */
.sp-head-fav { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 22px; padding: 0; border: 0; background: transparent; cursor: pointer;
  color: var(--muted); opacity: .5; border-radius: 7px;
  transition: color .14s, opacity .14s, transform .1s, background .12s; }
.sp-head-fav:hover { opacity: 1; color: var(--text); background: rgba(255,255,255,.06); }
.sp-head-fav:active { transform: scale(.85); }
.sp-head-fav svg.ic { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; }
.sp-head-fav.on { opacity: 1; color: var(--warning); }
.sp-head-fav.on svg.ic { fill: currentColor; stroke: currentColor; }
html[data-theme="light"] .sp-head-fav:hover { background: rgba(0,0,0,.06); }
/* Плитки адаптивные: колонок столько, сколько влезает по ширине (auto-fill, цель ~108px).
   Размер +50% от версии 72px, на которую владелец сказал «сильно мелкие» (72→108). auto-fill
   (не auto-fit) держит размер и в разреженных секциях (Недавние/Избранное), не растягивая
   одиночные плитки на всю строку. */
.sp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(108px, 1fr)); gap: 6px; }
.sp-cell { aspect-ratio: 1; padding: 5px; border: 0; background: transparent; border-radius: 10px;
  cursor: pointer; transition: background .12s, transform .1s; display: flex; }
.sp-cell:hover { background: rgba(255,255,255,.05); }
.sp-cell:active { transform: scale(.9); }
.sp-lot { width: 100%; height: 100%; pointer-events: none; }
.sp-lot svg, .sp-cover svg { width: 100% !important; height: 100% !important; display: block; }
.sp-img { width: 100%; height: 100%; object-fit: contain; pointer-events: none;
  -webkit-user-drag: none; filter: drop-shadow(0 0 1px rgba(255,255,255,.32)); }
.sp-empty { color: var(--muted); font-size: 13px; text-align: center; padding: 36px 10px; }

.sp-tabs { position: relative; display: flex; align-items: center; gap: 2px; height: 48px;
  padding: 0 8px; background: var(--cm-13161d, #13161d); border-top: 1px solid var(--line); overflow-x: auto;
  flex: 0 0 auto; scrollbar-width: none; }
.sp-tabs::-webkit-scrollbar { display: none; }
.sp-tabs.dim .sp-tab { opacity: .45; }
.sp-tab { width: 40px; height: 40px; flex: 0 0 auto; display: flex; align-items: center;
  justify-content: center; border: 0; background: transparent; color: var(--muted);
  border-radius: 10px; cursor: pointer; transition: color .15s, background .12s; padding: 6px; }
.sp-tab:hover { background: rgba(255,255,255,.05); }
.sp-tab.on { color: var(--primary-2); }
.sp-tab svg.ic { width: 21px; height: 21px; }
.sp-cover { width: 26px; height: 26px; display: block; pointer-events: none; }
/* Обложка-вкладка картиночного пака — на тёмном тулбаре всегда, ореол держит контраст. */
.sp-cover-img { width: 26px; height: 26px; object-fit: contain; display: block; pointer-events: none;
  filter: drop-shadow(0 0 1px rgba(255,255,255,.5)); }
.sp-bar { position: absolute; bottom: 0; height: 2.5px; border-radius: 3px; background: var(--grad);
  left: 8px; width: 40px; transition: left .22s cubic-bezier(.34,1.56,.64,1), width .22s ease; }

/* Увеличенный превью (long-press) */
.sp-preview { position: fixed; inset: 0; z-index: 90; display: flex; align-items: center;
  justify-content: center; background: rgba(8,10,14,.74); backdrop-filter: blur(3px);
  animation: spIn .18s ease; }
.sp-preview.hidden { display: none; }
.sp-pv-box { display: flex; flex-direction: column; align-items: center; gap: 16px; }
.sp-pv-lot { width: 220px; height: 220px; max-width: 70vw; max-height: 70vw; }
.sp-pv-lot svg { width: 100% !important; height: 100% !important; }
.sp-pv-img { width: 220px; height: 220px; max-width: 70vw; max-height: 70vw; object-fit: contain;
  display: block; filter: drop-shadow(0 0 1.5px rgba(255,255,255,.5)) drop-shadow(0 8px 24px rgba(0,0,0,.5)); }
.sp-pv-fav { display: inline-flex; align-items: center; gap: 7px; background: var(--panel-2);
  border: 1px solid var(--line); color: var(--text); font-size: 13px; padding: 9px 16px;
  border-radius: 8px; cursor: pointer; }
.sp-pv-fav svg.ic { width: 17px; height: 17px; }
.sp-pv-fav.on { color: #ffd54a; border-color: #ffd54a55; }
/* Светлая тема: белый ореол не нужен (светлый фон) — мягкая тёмная тень для глубины/контраста.
   Превью (.sp-pv-img) не трогаем: его подложка всегда тёмная. */
html[data-theme="light"] .sticker-msg-img { filter: drop-shadow(0 0 1.2px rgba(0,0,0,.22)); }
html[data-theme="light"] .sp-img { filter: none; }

@media (max-width: 480px) {
  /* Телефон: плитки +50% (было 72px → 90px), по просьбе владельца «сильно мелкие». */
  .sp-grid { grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); }
  .sticker-panel { height: clamp(340px, 60vh, 470px); min-height: 340px; }
}

/* ───────── Эмодзи-пикер (веб / «ПК-версия»), паритет с приложением ─────────
   Переиспользует ВЕСЬ хром панели стикеров (.sticker-panel/.sp-search/.sp-body/.sp-head/
   .sp-tabs/.sp-tab/.sp-bar) — одна реализация. Отличается лишь плотная сетка глифов. */
.emoji-panel .sp-body { padding: 0 8px 8px; }
.ep-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(40px, 1fr)); gap: 2px; }
.ep-cell { aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
  border: 0; background: transparent; border-radius: 9px; cursor: pointer; padding: 0;
  font-size: 25px; line-height: 1; transition: background .12s, transform .08s; user-select: none;
  font-family: "Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","Twemoji Mozilla",sans-serif;
  -webkit-font-smoothing: antialiased; }
.ep-cell:hover { background: rgba(255,255,255,.06); }
.ep-cell:active { transform: scale(.82); }
.ep-tab-emo { font-size: 21px; line-height: 1; display: block;
  font-family: "Apple Color Emoji","Segoe UI Emoji","Noto Color Emoji","Twemoji Mozilla",sans-serif; }
html[data-theme="light"] .ep-cell:hover { background: rgba(0,0,0,.06); }
@media (max-width: 480px) {
  .ep-grid { grid-template-columns: repeat(auto-fill, minmax(38px, 1fr)); }
  .ep-cell { font-size: 24px; }
}

/* ───────── Единый пикер: сегмент «Эмодзи | Стикеры» в одном окне (CLIE-349) ─────────
   Владелец: «эмодзи и стикеры в одно окно, там разделение». Одна панель .picker-panel
   (реюз всего хрома .sticker-panel) + сегмент-переключатель сверху со скользящим «пером». */
/* CLIE-505: вид сегмента = канон .cc-seg + .cc-seg-md. Отдельное «перо» (.pk-seg-thumb)
   удалено вместе с узлом разметки: приподнятый thumb в каноне рисует САМА активная
   кнопка, поэтому второго механизма (и второй геометрии) быть не должно. */
.picker-panel .pk-seg { display: flex; flex: 0 0 auto; margin: 9px 10px 5px; }
.picker-panel .pk-seg > .pk-seg-btn { flex: 1 1 0; }
.picker-btn.on { color: var(--primary-2); }

/* ════════════════ Работа v2: Проекты / Тикеты / Моя работа ════════════════ */
/* НЕ переопределять position: #workspaceV2 наследует .tasks-workspace
   (position:absolute; inset:0 0 0 96px) — это и есть оверлей поверх .chat.
   position:relative роняло панель в нормальный поток (стили «летели» вниз). */
.tw-muted { color: var(--muted); font-size: 12px; }
.tw-muted.small { font-size: 11px; }
.tw-empty.small { padding: 10px; font-size: 12px; }

/* 🏢🔴 CRMC-1115 · ПУСТОЙ РАЗДЕЛ СДЕЛОК НАЗЫВАЕТ ПРИЧИНУ И ДАЁТ ВЫХОД.
   Владелец 13.09.2026: «Не понятно где выбор компании» — глядя на пустую доску, где
   было написано ровно «Ничего не найдено под текущие фильтры» без причины и без единой
   кнопки. Разметку собирает `salesEmptyHtml()` (app.js), провода — `wireSalesEmpty()`.
   Цвета — только токены, поэтому обе темы получают вид сразу (правило контраста CLIE-888). */
.sales-empty { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.sales-empty .se-head { color: var(--text); font-size: 16px; font-weight: 700; }
.sales-empty .se-why { color: var(--muted); font-size: 13.5px; line-height: 1.4; max-width: 460px; }
/* Кнопки — СВОЕЙ строкой под текстом, естественной ширины (правило «поле + кнопка», CLIE-425). */
.sales-empty .se-acts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 10px; }
/* НАД ДОСКОЙ причина стоит полосой: колонки воронки остаются на экране (они же мишень для
   «Неразобранного»), поэтому вертикаль экономим и держим блок несжимаемым — `.tw-body-board`
   раздаёт `flex: 0 0 auto` поимённо, и новый ребёнок обязан назваться сам. */
.sales-empty.over-board { padding: 16px 24px 14px; gap: 4px; }
.sales-empty.over-board .se-acts { margin-top: 8px; }
.tw-body.tw-body-board > .sales-empty { flex: 0 0 auto; }

/* 🔒 CLIE-1454 · СТРОКА ЗАМКА — ОТКАЗ ПО ПРАВУ В ПУСТОМ РАЗДЕЛЕ (доска и списки сделок,
   лиды, CRM-контакты, окно выгрузки). Тон тот же, что у отказа в поиске (`.search-down.denied`):
   это НЕ авария и НЕ пустая база — спокойная плашка с кольцом по `--line`, чтобы её нельзя было
   прочитать как обычную серую подпись «ничего нет». Цвета берём ролями темы: светлая и тёмная
   получаются сами, второго набора прибитых значений нет. */
.tw-empty.denied, .crm-empty.denied {
  border-radius: 12px;
  background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.tw-empty.denied { margin: 8px; line-height: 1.45; }
.crm-empty.denied { padding: 32px 24px; }
.crm-empty.denied .crm-empty-s { max-width: 460px; }
/* 🔎 CLIE-1466 · ВЫХОДЫ ОТКАЗА — В ОДНУ СТРОКУ. `.crm-empty` это колонка с зазором, и две
   кнопки («Что делать» от сервера и «Снять фильтры») встали бы друг под другом лесенкой.
   Пустой ряд не занимает места сам — отдельного `hidden` по месту не требуется. */
.crm-empty-acts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 6px; }
.crm-empty-acts:empty { display: none; }
.cio-cnt.denied { color: var(--text); }
.tw-row-side { display: flex; align-items: center; gap: 8px; flex: none; }
.tw-col-body.drop { outline: 2px dashed var(--primary); outline-offset: -3px; border-radius: var(--radius); background: color-mix(in srgb, var(--primary) 8%, transparent); }
.tw-card.dragging { opacity: .4; }

/* отступы страниц */
.v2-wrap { padding: 16px 22px 28px; }
.icon-btn { display: inline-flex; align-items: center; justify-content: center; }
.icon-btn svg.ic { width: 18px; height: 18px; }

/* верхние табы с иконками */
.v2-seg button { display: inline-flex; align-items: center; gap: 6px; }
.v2-seg button svg.ic { width: 16px; height: 16px; }

/* тулбары/секции */
/* flex-wrap: у доски «Проекты» тулбар несёт 7 кнопок (Проект/Аналитика/Роли/Группа/
   Архив/Выбрать/Задача) + название + аватары — без переноса на узкой ширине они кримятся/
   вылезают. Переносим (как .tw-toolbar), название сжимается с многоточием. */
.v2-toolbar { display: flex; align-items: center; gap: 10px; row-gap: 8px; flex-wrap: wrap; padding: 2px 0 16px; }
.v2-toolbar-title { font-size: 16px; font-weight: 500; color: var(--text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-toolbar button { display: inline-flex; align-items: center; gap: 6px; flex: none; width: auto; }
/* Toggle-состояние (Выбрать/Архив) у ghost-кнопок тулбара — индиго-подсветка (иначе «Выбрать»
   нажатая выглядела так же, как ненажатая). */
.v2-toolbar .ghost.small.active { color: var(--primary); border-color: var(--primary); }
.v2-toolbar button svg.ic, .v2-tabs button svg.ic, .v2-sec svg.ic { width: 15px; height: 15px; }
.v2-pill { font-size: 11px; padding: 2px 8px; border-radius: 6px; background: var(--panel-2); color: var(--muted); }
.v2-sec { font-size: 12px; color: var(--muted); margin: 18px 0 8px; display: flex; align-items: center; gap: 7px; text-transform: uppercase; letter-spacing: .04em; }

/* карточки-кнопки списка (проекты/очереди) */
.v2-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px; }
.v2-card { display: flex; align-items: center; gap: 12px; text-align: left;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; cursor: pointer; }
.v2-card:hover { border-color: var(--primary); }
.v2-card-key { flex: none; width: 40px; height: 40px; display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600; color: #fff; border-radius: 9px; }
.v2-card-key svg.ic { width: 20px; height: 20px; }
.v2-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.v2-card-name { font-size: 15px; font-weight: 500; color: var(--text); }
.v2-card-meta { font-size: 12px; color: var(--muted); }
.v2-card-go { color: var(--muted); display: inline-flex; }
.v2-card-go svg.ic { width: 18px; height: 18px; }
.v2-num { font-size: 11px; color: var(--muted); }

/* ── Каталог проектов (главная страница «Проекты») ── */
.pcat-toolbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 2px 0 16px; }
.pcat-search { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 160px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); }
.pcat-search svg.ic { width: 16px; height: 16px; color: var(--muted); flex: none; }
.pcat-search input { flex: 1; border: 0; background: transparent; color: var(--text); font-size: 14px; outline: none; min-width: 0; }
/* Размерный класс ряда (канон control-size): поле поиска — ровня селектам `.tw-select` того же тулбара.
   Вложенный input носил ОБЩИЙ паддинг поля формы (11px) внутри рамки с паддингом 8px — рамка выходила
   выше соседей в полтора раза. Рамка держит --ctl-h/--ctl-r, input — тот же вертикальный паддинг, что у селекта. */
.pcat-search { min-height: var(--ctl-h); padding: 0 12px; border-radius: var(--ctl-r); box-sizing: border-box; }
.pcat-search input { padding: 7px 0; font-size: var(--ctl-fs, 14px); box-shadow: none; }
/* «+ Проект» — в шапке страницы «Проекты», рядом с крестиком (как «+ Задача» у задач). Атрибут hidden
   ставит каталог (пустой каталог и страница проекта — без кнопки); `.primary.small{display:inline-flex}`
   сильнее UA-правила [hidden], поэтому прячем явно. «+ Очередь» «Обращений» — там же и так же
   (была 30px в строке подзаголовка, у соседей «Работы» главная кнопка — в шапке). */
#v2NewProj, #v2NewQueue { flex: none; white-space: nowrap; }
#v2NewProj[hidden], #v2NewQueue[hidden] { display: none; }
.pcat-sort { flex: none; }
.pcat-viewtog { display: flex; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; flex: none; }
.pcat-vbtn { display: inline-flex; align-items: center; padding: 8px 10px; background: var(--panel); border: 0; color: var(--muted); cursor: pointer; }
.pcat-vbtn svg.ic { width: 16px; height: 16px; }
.pcat-vbtn.on { background: var(--acc-fill); color: #fff; }
.pcat-empty { padding: 24px; color: var(--muted); text-align: center; }
.pcat-empty-big { display: flex; flex-direction: column; align-items: center; gap: 14px; padding: 46px 20px; }
.pcat-empty-big > svg.ic { width: 42px; height: 42px; color: var(--muted); opacity: .45; }
.pcat-empty-txt { display: flex; flex-direction: column; gap: 4px; text-align: center; }
.pcat-empty-txt b { font-size: 16px; color: var(--text); }
.pcat-empty-txt span { font-size: 13px; color: var(--muted); }
/* Кнопка «Создать проект» в пустом каталоге: общий `.primary` — это кнопка ФОРМЫ (width:100% + margin-top,
   не flex) — здесь значок вставал над словом во всю ширину. Своя геометрия: по содержимому, значок в строку. */
.pcat-empty-big .primary { display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: auto; margin-top: 0; padding: 10px 18px; }
.pcat-empty-big .primary svg.ic { width: 16px; height: 16px; }
.pcat-arch { margin-top: 22px; border-top: 1px solid var(--line); padding-top: 10px; }
.pcat-arch > summary { cursor: pointer; font-size: 13px; color: var(--muted); font-weight: 500; padding: 4px 0; user-select: none; }
.pcat-arch > summary:hover { color: var(--text); }
.pcat-arch .v2-pc-grid, .pcat-arch .v2-pc-list { margin-top: 12px; }
/* 🧍 CLIE-442 Э3 «Скрытые у меня»: та же рама, что «Архив» (второй раскрывашки не заводим) —
   отличается только иконкой-глазом в подписи. Скрытых нет → раздела нет вовсе (см. app.js). */
.pcat-hidden > summary { display: flex; align-items: center; gap: 7px; }
.pcat-hidden > summary svg { width: 15px; height: 15px; flex: none; opacity: .85; }
.pcat-hidden .v2-pc-card, .pcat-hidden .v2-pc-row { opacity: .72; }
.pcat-hidden .v2-pc-card:hover, .pcat-hidden .v2-pc-row:hover { opacity: 1; }
/* карточка-сетка */
.v2-pc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 12px; }
.v2-pc-card { position: relative; display: flex; flex-direction: column; gap: 8px; align-items: stretch; text-align: left; padding: 14px;
  border: 1px solid var(--line); border-radius: 13px; background: var(--panel); cursor: pointer; transition: border-color .12s ease, transform .12s ease; }
.v2-pc-card:hover { border-color: var(--primary); transform: translateY(-1px); }
/* Кнопка-планировщик: иконка в правом верхнем углу, появляется ПРИ НАВЕДЕНИИ (на тач — всегда). */
.v2-pc-planbtn { position: absolute; top: 8px; right: 8px; z-index: 2; display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--muted); cursor: pointer;
  opacity: 0; transform: translateY(-2px); transition: opacity .12s ease, transform .12s ease, color .12s ease, border-color .12s ease, background .12s ease; }
.v2-pc-card:hover .v2-pc-planbtn, .v2-pc-planbtn.open, .v2-pc-planbtn:focus-visible { opacity: 1; transform: none; }
.v2-pc-planbtn:hover, .v2-pc-planbtn.open { color: var(--text); border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }
.v2-pc-planbtn svg.ic { width: 15px; height: 15px; }
@media (hover: none) { .v2-pc-planbtn { opacity: 1; transform: none; } }
/* Список: планировщик — hover-иконка перед шевроном (в потоке, не в углу) */
.v2-pc-row .v2-pc-planbtn { position: static; flex: none; width: 26px; height: 26px; }
.v2-pc-row:hover .v2-pc-planbtn { opacity: 1; transform: none; }
.v2-pc-card.archived { opacity: .6; }
/* Мультивыбор каталога проектов (bulk edit, паритет с задачами/boardSel) */
.v2-pc-card.tsel, .v2-pc-row.tsel, .v2-pb-card.tsel { outline: 2px solid var(--primary); outline-offset: -2px; }
/* Справа, на месте hover-планировщика (тот скрыт в режиме выбора) — как чекбокс задач,
   слева перекрывал бы иконку+код проекта (.v2-pc-top). */
.v2-pc-selwrap { position: absolute; top: 8px; right: 8px; z-index: 3; }
body.cc-tsel-mode .v2-pc-card, body.cc-tsel-mode .v2-pc-row, body.cc-tsel-mode .v2-pb-card { cursor: pointer; }
/* 🔴 ФИКС «СКАЧЕТ» В СПИСКЕ (жалоба владельца): вход в режим выбора НЕ должен сдвигать строку.
   Ведущий слот — грип (обычный режим) и галочка (выбор) — ровно одной ширины 20px, без
   отрицательных полей грипа; хвостовой слот планировщика РЕЗЕРВИРУЕТСЯ (кнопка остаётся в
   потоке, но скрыта в режиме выбора). Иначе строка уезжала на ~10px вбок и по ней промахивались. */
.v2-pc-row > .v2-pc-grip, .v2-pc-row > .tw-card-sel { flex: none; width: 20px; height: 20px; margin: 0; box-sizing: border-box; }
.v2-pc-row > .v2-pc-grip { justify-content: center; }
body.cc-tsel-mode .v2-pc-row .v2-pc-planbtn { visibility: hidden; pointer-events: none; }
/* На доске проектов в режиме выбора шапка столбца не тащится (draggable=false) — курсор не «grab». */
body.cc-tsel-mode .v2-pb-colhead { cursor: default; }
.v2-pc-top { display: flex; align-items: center; gap: 8px; }
.v2-pc-coin { width: 34px; height: 34px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 14px; font-weight: 700; flex: none; }
.v2-pc-keychip { font-family: var(--mono, monospace); font-size: 10.5px; font-weight: 700; letter-spacing: .04em; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); border-radius: 5px; padding: 2px 6px; }
.v2-pc-name { font-size: 15px; font-weight: 600; color: var(--text); line-height: 1.25; }
.v2-pc-comp { display: inline-flex; align-items: center; align-self: flex-start; max-width: 100%; font-size: 11px; font-weight: 600;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); border-radius: 6px; padding: 2px 8px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-pc-meta { font-size: 12px; color: var(--muted); }
.v2-pc-prog { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.v2-pc-bar { flex: 1; height: 6px; border-radius: 100px; background: var(--panel-2); overflow: hidden; }
.v2-pc-bar > i { display: block; height: 100%; border-radius: 100px; background: var(--accent); }
.v2-pc-prog.done .v2-pc-bar > i { background: #22c55e; }
.v2-pc-prog.empty .v2-pc-bar { opacity: .5; }
.v2-pc-pct { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* строка-список */
.v2-pc-list { display: flex; flex-direction: column; gap: 6px; }
.v2-pc-row { display: flex; align-items: center; gap: 12px; text-align: left; padding: 9px 12px; border: 1px solid var(--line); border-radius: 11px; background: var(--panel); cursor: pointer; }
.v2-pc-row:hover { border-color: var(--primary); }
.v2-pc-row.archived { opacity: .6; }
.v2-pc-row .v2-pc-coin { width: 28px; height: 28px; border-radius: 8px; font-size: 12px; }
.v2-pc-rname { flex: 1; font-size: 14px; font-weight: 500; color: var(--text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-pc-rkey { font-family: var(--mono, monospace); font-size: 11px; color: var(--muted); flex: none; }
.v2-pc-rcomp { font-size: 11.5px; font-weight: 600; color: var(--accent); flex: none; max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-pc-rprog { width: 130px; flex: none; }
.v2-pc-go { color: var(--muted); display: inline-flex; flex: none; }
.v2-pc-go svg.ic { width: 16px; height: 16px; }
@media (max-width: 560px){ .v2-pc-rkey, .v2-pc-rprog, .v2-pc-rcomp { display: none; } }

/* ── Приоритизация проектов (0075): чипы важности/корзины/даты, доска, таймлайн ── */
/* Переключатель вида на 4 сегмента (Карточки · Список · Доска · Таймлайн) */
/* Высоту даёт канон .cc-seg-md (ccroom.css: дорожка = --ctl-h, как поиск и селекты в том же ряду);
   здесь — ТОЛЬКО боковой воздух. Замер 20.10.2026: с прежним padding 8px 12px дорожка была 44px при
   поиске 36 («Глубина») / 31 («Штиль») — канон control-size. */
.pcat-viewtog.seg4 .pcat-vbtn { gap: 6px; padding-inline: 12px; font-size: 13px; font-weight: 500; transition: background .12s ease, color .12s ease; }
/* Разделитель — канонический (тонкая черта между двумя НЕактивными пунктами, как у .cc-seg), а не
   border-left: у скруглённого пункта во всю высоту дорожки рамка рисовалась скобкой «(» (кадр 860, 20.10.2026). */
.pcat-viewtog.seg4 .pcat-vbtn:not(.on) + .pcat-vbtn:not(.on)::before { content: ""; position: absolute; left: 0; top: 24%; bottom: 24%; width: 1px; background: var(--seg-div); }
.pcat-viewtog.seg4 .pcat-vbtn:not(.on):hover { background: var(--panel-2); color: var(--text); }
.pcat-vlbl { white-space: nowrap; }
@media (max-width: 900px){ .pcat-vlbl { display: none; } .pcat-viewtog.seg4 .pcat-vbtn { padding-inline: 10px; } }
/* 🔴 Ряд фильтров каталога проектов уступает место СТУПЕНЯМИ, а не роняет одну кнопку на вторую строку.
   Замер 20.10.2026 (окно 1600): 8 контролов = 1444px при ряде 1444px — впритык; бейдж «Фильтр 1» (+24px) —
   и «Выбрать» одна уезжала вниз. Ступень 1 — подписи НЕактивных видов (у кнопок есть title, активный вид
   назван словом); ступень 2 — подписи «Группы · Фильтр · Выбрать» (значок + подсказка). Порог — ширина
   САМОГО ряда (@container), а не окна: рельс и шторки съедают ширину по-разному. Ряд с «Компании: …»
   (группировка по компании) шире на ~217px, режим выбора («Выбрать всё») — на ~130px: у них свои пороги. */
.pcat-toolbar { container: pcattb / inline-size; }
@container pcattb (max-width: 1280px) { .pcat-toolbar .pcat-viewtog .pcat-vbtn:not(.on) .pcat-vlbl { display: none; } }
@container pcattb (max-width: 1140px) { .pcat-toolbar > :is(.pcat-btn, .pcat-vbtn) .pcat-vlbl { display: none; } }
@container pcattb (max-width: 1500px) { .pcat-toolbar:has(#pcatCoSort, #pcatSelectAll) .pcat-viewtog .pcat-vbtn:not(.on) .pcat-vlbl { display: none; } }
@container pcattb (max-width: 1360px) { .pcat-toolbar:has(#pcatCoSort, #pcatSelectAll) > :is(.pcat-btn, .pcat-vbtn) .pcat-vlbl { display: none; } }
@container pcattb (max-width: 1640px) { .pcat-toolbar:has(#pcatCoSort):has(#pcatSelectAll) .pcat-viewtog .pcat-vbtn:not(.on) .pcat-vlbl { display: none; } }
@container pcattb (max-width: 1500px) { .pcat-toolbar:has(#pcatCoSort):has(#pcatSelectAll) > :is(.pcat-btn, .pcat-vbtn) .pcat-vlbl { display: none; } }
/* Важность P1..P4 (P3 «обычный» не показываем — не шумим) */
.v2-pc-prio { display: inline-flex; align-items: center; font-size: 10.5px; font-weight: 700; letter-spacing: .02em;
  padding: 2px 6px; border-radius: 6px; line-height: 1.35; flex: none; font-variant-numeric: tabular-nums; }
/* тёмная: чернила P1 светлее заливки — #E24B4A на своём тинте давал 4.07 (свип 19.10); тинт прежний */
.v2-pc-prio.p1 { color: #F26B6A; background: color-mix(in srgb, #E24B4A 16%, transparent); }
.v2-pc-prio.p2 { color: #EF9F27; background: color-mix(in srgb, #EF9F27 17%, transparent); }
.v2-pc-prio.p4 { color: var(--muted); background: var(--panel-2); }
html[data-theme="light"] .v2-pc-prio.p1 { color: #B42318; background: color-mix(in srgb, #E24B4A 12%, transparent); }
html[data-theme="light"] .v2-pc-prio.p2 { color: #B54708; background: color-mix(in srgb, #EF9F27 16%, transparent); }
/* Корзина «когда» + плановая дата */
.v2-pc-chips { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.v2-pc-spacer { flex: 1; }
.v2-pc-bucket { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.v2-pc-bucket > i { width: 7px; height: 7px; border-radius: 50%; background: var(--bk, var(--muted)); flex: none; }
.v2-pc-due { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; color: var(--muted); white-space: nowrap; }
.v2-pc-due svg.ic { width: 13px; height: 13px; opacity: .8; }
.v2-pc-rchips { display: flex; align-items: center; gap: 9px; flex: none; }
@media (max-width: 760px){ .v2-pc-rchips { display: none; } }
/* ⏸ CLIE-543 «ИИ на паузе» — состояние проекта на его же плитке/строке. Акцент несут ИКОНКА и
   СЛОВО + мягкая подложка с хэйрлайн-кольцом (правило «никаких левых реек»: никакой полосы во
   всю высоту и никакой заливки всей строки). Тон — янтарный «ждёт», как у ИИ-состояний задач. */
.v2-pc-aipause {
  display: inline-flex; align-items: center; gap: 4px; white-space: nowrap;
  font-size: 11px; font-weight: 600; line-height: 1;
  padding: 3px 7px; border-radius: 999px;
  color: var(--warn, #b7791f);
  background: color-mix(in srgb, var(--warn, #b7791f) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn, #b7791f) 22%, transparent);
}
.v2-pc-aipause svg.ic { width: 12px; height: 12px; opacity: .9; }
/* Метки проекта — тот же язык, что у меток задач (.tip-label): цветная точка + мягкая
   заливка/рамка по --lc. Плотный, маленький чип; светлая и тёмная темы через color-mix. */
.v2-pc-lbl { display: inline-flex; align-items: center; gap: 5px; max-width: 140px; font-size: 11px; font-weight: 600;
  padding: 2px 8px; border-radius: 7px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  background: color-mix(in srgb, var(--lc, var(--muted)) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--lc, var(--muted)) 38%, transparent);
  color: color-mix(in srgb, var(--lc, var(--muted)) 74%, var(--text)); }
.v2-pc-lbl > i { width: 6px; height: 6px; border-radius: 50%; background: var(--lc, var(--muted)); flex: none; }
.v2-pc-lbl.more { color: var(--muted); background: var(--panel-2); border-color: var(--line); }
/* ── Метки/фильтр/группировка каталога проектов (0109) ── */
/* Кнопка «Фильтр» в тулбаре (одиночная, со своей рамкой — .pcat-vbtn без неё) + счётчик активных условий */
.pcat-btn { display: inline-flex; align-items: center; gap: 6px; flex: none; padding: 8px 12px; font-size: 13px; font-weight: 500; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: 10px; cursor: pointer; transition: color .12s ease, border-color .12s ease, background .12s ease; }
.pcat-btn svg.ic { width: 16px; height: 16px; }
.pcat-btn:hover { color: var(--text); border-color: var(--primary); }
.pcat-btn.on { color: #fff; background: var(--acc-fill); border-color: var(--acc-fill); }
/* Канон control-size: «Группы»/«Фильтр» — той же высоты, что поиск и селекты ряда (замер 20.10, «Штиль»:
   34px против 31px — паддинг 8px вокруг значка вместо --ctl-h). */
.pcat-btn { min-height: var(--ctl-h); padding-block: 0; box-sizing: border-box; border-radius: var(--ctl-r); }
/* «Выбрать»/«Выбрать все» стоят в ряду ОДИНОЧКАМИ, но носят класс пункта сегмента (.pcat-vbtn) и брали его
   поля 7px → 34px при ряде 31 («Штиль»); через align-self:stretch .cc-seg-md это раздувало и переключатель
   вида. Пункты переключателя — во всю высоту дорожки: иконка-пункт без подписи был 17px, и подсветка
   наведения ложилась полоской (замер 20.10.2026). */
.pcat-toolbar > .pcat-vbtn { min-height: var(--ctl-h); padding-block: 0; box-sizing: border-box; border-radius: var(--ctl-r); }
/* Одиночка в ряду — по содержимому: канон пункта сегмента даёт ей `flex: 1 1 0`, и на узком окне, когда
   ряд с «Компании: …» не влезает и вид с «Выбрать» уезжают строкой ниже, «Выбрать» растягивалась на всю
   строку (замер 21.10, окно 1100: кнопка 699px, значок висел посередине). Вид и «Выбрать» на своей
   строке прижаты вправо (auto-поле); в одну строку поиск забирает свободное место — поле там 0. */
.pcat-toolbar > .pcat-vbtn { flex: none; }
/* «Выбрать»/«Выбрать все» — одиночки ряда, а не пункты сегмента: канон пункта (`.pcat-vbtn` в списке
   сегментов ниже по файлу) снял им подложку и рамку, и в ряду рамочных «Группы»/«Фильтр» (кромка
   на x=1016/1057 и 1068/1109) «Выбрать» висела голым значком на холсте (кадр 21.10, 1374–1402 ×
   228–256, рамки нет в обеих темах). Рамка, подложка и поля — как у соседней .pcat-btn;
   включённая (.on) остаётся пилюлей сегмента. */
.pcat-toolbar > .pcat-vbtn { padding-inline: 12px; }
.pcat-toolbar > .pcat-vbtn:not(.on) { background: var(--panel); border-color: var(--line); }
.pcat-toolbar > .pcat-vbtn:not(.on):hover { color: var(--text); border-color: var(--primary); }
.pcat-toolbar > .pcat-viewtog { margin-left: auto; }
.pcat-viewtog.seg4 .pcat-vbtn { align-self: stretch; }
.pcat-fbadge { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; font-size: 10.5px; font-weight: 700; background: rgba(255,255,255,.26); color: #fff; font-variant-numeric: tabular-nums; }
.pcat-group { max-width: 168px; }
/* projects-tools-5rows-1 · телефон (≤760): поиск, порядок, группировка, порядок компаний, группы, фильтр,
   вид и выбор переносились в 5 строк (~222 px до первого проекта). Теперь две: поиск — во всю ширину,
   под ним одна лента — фильтр · вид · выбрать · выбрать всё · порядок · группировка · порядок компаний ·
   группы. Не влезло — лента листается пальцем вбок, правый край подтаивает; поиск стоит на месте. */
@media (max-width: 760px) {
  .pcat-toolbar { display: grid; grid-template-columns: repeat(8, max-content) minmax(0, 1fr); grid-auto-columns: max-content; column-gap: 0; row-gap: 10px; align-items: center; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
  .pcat-toolbar::-webkit-scrollbar { display: none; }
  .pcat-toolbar > * { grid-row: 2; margin-inline-end: 8px; }
  .pcat-toolbar > .pcat-search { grid-row: 1; grid-column: 1 / -1; position: sticky; left: 0; width: 100cqw; min-width: 0; margin-inline-end: 0; justify-self: start; box-sizing: border-box; }
  .pcat-toolbar > .pcat-viewtog { margin-left: 0; }
  .pcat-toolbar > #pcatFilter { order: 1; }
  .pcat-toolbar > .pcat-viewtog { order: 2; }
  .pcat-toolbar > #pcatSelect { order: 3; }
  .pcat-toolbar > #pcatSelectAll { order: 4; }
  .pcat-toolbar > #pcatSort { order: 5; }
  .pcat-toolbar > #pcatGroup { order: 6; }
  .pcat-toolbar > #pcatCoSort { order: 7; }
  .pcat-toolbar > #pcatFolders { order: 8; }
  /* лента может не влезть (есть порядок/группировка или «выбрать всё»): строка поиска — без маски,
     строка ленты подтаивает справа на 16 px, в конце ленты — поле 16 px, последняя кнопка не тает */
  .pcat-toolbar:has(> #pcatSort), .pcat-toolbar:has(> #pcatSelectAll) {
    -webkit-mask-image: linear-gradient(#000 0 0), linear-gradient(to right, #000 calc(100% - 16px), transparent);
            mask-image: linear-gradient(#000 0 0), linear-gradient(to right, #000 calc(100% - 16px), transparent);
    -webkit-mask-size: 100% calc(2px + var(--ctl-h) + 5px), 100% 100%;
            mask-size: 100% calc(2px + var(--ctl-h) + 5px), 100% 100%;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  }
  .pcat-toolbar:has(> #pcatSort)::after, .pcat-toolbar:has(> #pcatSelectAll)::after { content: ""; grid-row: 2; order: 99; width: 16px; height: 1px; }
}
/* Строка «Метки» в панели «О проекте»: чипы (визуал меток задач) + удаление ✕ + «＋» добавить */
.v2ov-labels { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.v2ov-lchips { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.v2ov-lchip { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; padding: 3px 6px 3px 9px; border-radius: 8px; white-space: nowrap;
  background: color-mix(in srgb, var(--lc, var(--muted)) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--lc, var(--muted)) 38%, transparent);
  color: color-mix(in srgb, var(--lc, var(--muted)) 74%, var(--text)); }
.v2ov-lchip > i { width: 7px; height: 7px; border-radius: 50%; background: var(--lc, var(--muted)); flex: none; }
.v2ov-lchip-n { max-width: 170px; overflow: hidden; text-overflow: ellipsis; }
.v2ov-lchip-x { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: inherit; opacity: .55; cursor: pointer; transition: opacity .12s ease, background .12s ease; }
.v2ov-lchip-x:hover { opacity: 1; background: color-mix(in srgb, var(--lc, var(--muted)) 24%, transparent); }
.v2ov-lchip-x svg.ic { width: 11px; height: 11px; }
.v2ov-laddbtn { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; flex: none; border: 1px dashed var(--line); border-radius: 8px; background: transparent; color: var(--muted); cursor: pointer; transition: color .12s ease, border-color .12s ease, background .12s ease; }
.v2ov-laddbtn:hover { color: var(--primary); border-color: var(--primary); background: color-mix(in srgb, var(--primary) 8%, transparent); }
.v2ov-laddbtn svg.ic { width: 15px; height: 15px; }
.v2ov-lempty { color: var(--muted); font-size: 13px; }
/* Секции группировки (Карточки/Список): заголовок с точкой-цветом + счётчик. Сворачиваемые (0110). */
.v2-pg-wrap { display: flex; flex-direction: column; gap: 22px; }
.v2-pg-sec { display: flex; flex-direction: column; gap: 12px; }
.v2-pg-head { display: flex; align-items: center; gap: 9px; padding: 5px 8px; margin: 0 -6px; border-radius: 9px; cursor: pointer; user-select: none; transition: background .12s ease; }
.v2-pg-head:hover { background: color-mix(in srgb, var(--text) 5%, transparent); }
.v2-pg-head:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.v2-pg-chev { display: inline-flex; align-items: center; justify-content: center; width: 15px; height: 15px; color: var(--muted); flex: none; transform: rotate(90deg); transition: transform .16s ease; }
.v2-pg-chev svg.ic { width: 13px; height: 13px; }
.v2-pg-sec.collapsed .v2-pg-chev { transform: rotate(0deg); }
.v2-pg-sec.collapsed .v2-pg-body { display: none; }
.v2-pg-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--gc, var(--muted)); flex: none; }
.v2-pg-dot[data-nodot] { background: var(--muted); opacity: .45; }
.v2-pg-title { font-size: 13px; font-weight: 700; color: var(--text); letter-spacing: .01em; }
/* Подложка счётчика — подмес текста, а не --panel-2: в светлой теме --panel-2 = --bg (#f5f5f7
   «Штиль», #F4F5F8 «Глубина»), и пилюля сливалась с холстом — голая цифра, а в тёмной та же
   пилюля видна (кадр 21.10: (34,34,40) на (11,12,18) против (244,245,248) на (244,245,248)). */
.v2-pg-count { font-size: 12px; font-weight: 600; color: var(--muted); background: color-mix(in srgb, var(--text) 8%, transparent); border-radius: 20px; padding: 1px 8px; font-variant-numeric: tabular-nums; }
.v2-pg-menu { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 7px; background: transparent; color: var(--muted); cursor: pointer; opacity: 0; transition: opacity .12s ease, background .12s ease, color .12s ease; }
.v2-pg-head:hover .v2-pg-menu, .v2-pg-menu:focus-visible { opacity: 1; }
.v2-pg-menu:hover { background: var(--panel-2); color: var(--text); }
.v2-pg-menu svg.ic { width: 16px; height: 16px; }
.v2-pg-sec.is-folder.drop-on, .v2-pg-sec.is-company.drop-on { outline: 2px dashed color-mix(in srgb, var(--accent) 65%, transparent); outline-offset: 5px; border-radius: 12px; background: color-mix(in srgb, var(--accent) 6%, transparent); }
.v2-pg-empty { grid-column: 1 / -1; padding: 15px; text-align: center; font-size: 12px; color: var(--muted); border: 1px dashed var(--line); border-radius: 12px; min-height: 12px; }
.v2-pc-fdrag { cursor: grab; }
.v2-pc-fdrag:active { cursor: grabbing; }
.v2-pc-fdrag.v2-fdragging { opacity: .5; }
/* Группы (папки) проектов (0110): чип группы на плитке · строка «Группа» в «О проекте» · пикер/менеджер */
.v2-pc-fold { display: inline-flex; align-items: center; gap: 5px; max-width: 150px; font-size: 11px; font-weight: 600; padding: 2px 8px 2px 6px; border-radius: 7px; white-space: nowrap; cursor: pointer;
  color: color-mix(in srgb, var(--fc, var(--muted)) 82%, var(--text));
  background: color-mix(in srgb, var(--fc, var(--muted)) 13%, transparent);
  border: 1px solid color-mix(in srgb, var(--fc, var(--muted)) 34%, transparent);
  transition: background .12s ease, border-color .12s ease; }
.v2-pc-fold:hover { background: color-mix(in srgb, var(--fc, var(--muted)) 22%, transparent); }
.v2-pc-fold svg.ic { width: 12px; height: 12px; opacity: .9; flex: none; }
.v2-pc-fold > span { overflow: hidden; text-overflow: ellipsis; }
/* 🏢 CLIE-442 — ПРОВЕНАНС «проекта у обеих сторон»: чей объект на самом деле. Тот же чип, но
   read-only (не пикер) и приглушённый: он ИНФОРМИРУЕТ, а не приглашает нажать. */
.v2-pc-fold.v2-pc-owner { cursor: default; opacity: .82; }
.v2-pc-fold.v2-pc-owner:hover { background: color-mix(in srgb, var(--fc, var(--muted)) 13%, transparent); }
.v2pt-owner svg.ic { width: 11px; height: 11px; vertical-align: -1px; opacity: .85; }
/* Строка «Оригинал» в «О проекте»: компания-владелец + каноническое название, а кнопка возврата
   — ОТДЕЛЬНОЙ строкой (правило продукта «read-only поле и его кнопка — не в один ряд»). */
.v2ov-orig { flex: 1 1 100%; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-start; gap: 8px; }
.v2ov-orig-name { font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; }
.v2ov-orig-br { flex-basis: 100%; height: 0; }                  /* перенос строки внутри flex-ряда */
.v2ov-orig > button { flex: 0 0 auto; margin: 2px auto 0 0; }   /* строка НИЖЕ, слева, естественной ширины */
.v2ov-folder { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.v2ov-fchip { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 600; color: var(--text); background: var(--panel-2); border: 1px solid var(--line); border-radius: 9px; padding: 5px 10px; cursor: pointer; transition: border-color .12s ease, background .12s ease; }
.v2ov-fchip:hover { border-color: var(--primary); }
.v2ov-fchip[disabled] { cursor: default; }
.v2ov-fchip svg.ic { width: 14px; height: 14px; color: var(--muted); }
.v2ov-fdot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.v2ov-faddbtn { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; color: var(--muted); background: transparent; border: 1px dashed var(--line); border-radius: 9px; padding: 5px 11px; cursor: pointer; transition: color .12s ease, border-color .12s ease; }
.v2ov-faddbtn:hover { color: var(--text); border-color: var(--primary); }
.v2ov-faddbtn svg.ic { width: 14px; height: 14px; }
.v2-fold-newrow { display: flex; align-items: center; gap: 6px; margin-top: 8px; padding-top: 9px; border-top: 1px solid var(--line); }
.v2-fold-newrow .tc-mini { flex: 1; min-width: 0; }
.v2-nodot { width: 9px; height: 9px; border-radius: 50%; background: var(--muted); opacity: .4; display: inline-block; flex: none; }
.v2-fold-pick { max-height: 264px; overflow: auto; }
.v2-fold-menu { display: flex; flex-direction: column; gap: 11px; }
.v2-fold-colors { display: flex; flex-wrap: wrap; gap: 6px; }
.np-sw.np-sw-none { display: inline-flex; align-items: center; justify-content: center; color: var(--muted); background: var(--panel-2); box-shadow: 0 0 0 1px var(--line) inset; }
.np-sw.np-sw-none svg.ic { width: 12px; height: 12px; }
.np-sw.sm { width: 18px; height: 18px; border-radius: 6px; }
.v2-fold-delbtn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; font-size: 13px; font-weight: 500; color: var(--danger); background: transparent; border: 1px solid var(--line); border-radius: 8px; padding: 8px; cursor: pointer; transition: background .12s ease; }
.v2-fold-delbtn:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.v2-fold-delbtn svg.ic { width: 15px; height: 15px; }
.v2-foldm-h { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 700; color: var(--text); padding: 2px 2px 10px; }
.v2-foldm-h svg.ic { width: 15px; height: 15px; color: var(--muted); }
.v2-foldm-list { display: flex; flex-direction: column; gap: 1px; max-height: 300px; overflow: auto; }
.v2-foldm-row { display: flex; align-items: center; gap: 8px; padding: 5px 4px; border-radius: 8px; flex-wrap: wrap; }
.v2-foldm-row:hover { background: color-mix(in srgb, var(--text) 4%, transparent); }
.v2-foldm-row.dragging { opacity: .5; }
.v2-foldm-grip { display: inline-flex; color: var(--muted); cursor: grab; opacity: .5; flex: none; }
.v2-foldm-grip svg.ic { width: 14px; height: 14px; }
.v2-foldm-sw { width: 16px; height: 16px; border-radius: 5px; border: 0; cursor: pointer; flex: none; box-shadow: 0 0 0 1px color-mix(in srgb, var(--text) 14%, transparent) inset; }
.v2-foldm-name { flex: 1; min-width: 90px; font-size: 13px; font-weight: 500; color: var(--text); background: transparent; border: 1px solid transparent; border-radius: 6px; padding: 4px 6px; }
.v2-foldm-name:hover { border-color: var(--line); }
.v2-foldm-name:focus { border-color: var(--primary); background: var(--panel-2); outline: none; }
.v2-foldm-cnt { font-size: 11px; font-weight: 600; color: var(--muted); background: var(--panel-2); border-radius: 20px; padding: 1px 7px; flex: none; font-variant-numeric: tabular-nums; }
.v2-foldm-del { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 7px; background: transparent; color: var(--muted); cursor: pointer; opacity: 0; flex: none; transition: opacity .12s ease, background .12s ease, color .12s ease; }
.v2-foldm-row:hover .v2-foldm-del, .v2-foldm-del:focus-visible { opacity: 1; }
.v2-foldm-del:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.v2-foldm-del svg.ic { width: 14px; height: 14px; }
.v2-foldm-pal { display: flex; flex-wrap: wrap; gap: 5px; width: 100%; padding: 4px 2px 4px 30px; }
/* Поповер фильтра проектов: секции метки/важность/ещё, чипы-переключатели */
.v2-fl { width: 300px; max-width: 84vw; padding: 4px 2px; }
.v2-fl-h { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 4px 8px 8px; font-size: 13px; font-weight: 700; color: var(--text); }
.v2-fl-clear { border: 0; background: transparent; color: var(--primary); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; padding: 2px 4px; }
.v2-fl-clear:hover { text-decoration: underline; }
.v2-fl-sec { padding: 8px; border-top: 1px solid var(--line); }
.v2-fl-lbl { display: block; font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 7px; }
.v2-fl-wrap { display: flex; flex-wrap: wrap; gap: 6px; }
.v2-fl-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: 8px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted); transition: color .12s ease, border-color .12s ease, background .12s ease; }
.v2-fl-chip:hover { color: var(--text); border-color: var(--primary); }
.v2-fl-chip > i { width: 7px; height: 7px; border-radius: 50%; background: var(--lc, var(--muted)); flex: none; }
.v2-fl-chip.on { color: #fff; background: var(--acc-fill); border-color: var(--acc-fill); }
/* Активный чип метки — тот же мягкий язык, что и чипы важности ниже и .tip-label:
   заливка/рамка color-mix от цвета метки + семантический ТЕКСТ (не белым по светлой
   заливке — золото #cb9400 / небо #0ea5e9 давали 2.7:1, нечитаемо). Текст мешаем с --text,
   поэтому читается и в тёмной, и в светлой теме без отдельного оверрайда. */
.v2-fl-chip.lbl.on { background: color-mix(in srgb, var(--lc, var(--accent)) 18%, transparent); border-color: color-mix(in srgb, var(--lc, var(--accent)) 46%, transparent); color: color-mix(in srgb, var(--lc, var(--accent)) 72%, var(--text)); }
.v2-fl-chip.lbl.on > i { background: var(--lc, var(--accent)); }
/* Активные чипы важности: мягкая заливка + семантический ТЕКСТ (как бейдж .v2-pc-prio),
   а НЕ белым по светлому янтарю (P2 был нечитаем) и НЕ синим --accent для P3/P4 (проваливались
   в общий .on). Все 4 уровня — один визуальный язык, контраст читаем в обеих темах. */
.v2-fl-chip.prio.urgent.on { background: color-mix(in srgb, #E24B4A 18%, transparent); border-color: color-mix(in srgb, #E24B4A 46%, transparent); color: #E24B4A; }
.v2-fl-chip.prio.high.on   { background: color-mix(in srgb, #EF9F27 18%, transparent); border-color: color-mix(in srgb, #EF9F27 48%, transparent); color: #EF9F27; }
.v2-fl-chip.prio.normal.on { background: color-mix(in srgb, #3ba55d 18%, transparent); border-color: color-mix(in srgb, #3ba55d 46%, transparent); color: #3ba55d; }
.v2-fl-chip.prio.low.on    { background: color-mix(in srgb, var(--muted) 22%, transparent); border-color: color-mix(in srgb, var(--muted) 42%, transparent); color: var(--text); }
html[data-theme="light"] .v2-fl-chip.prio.urgent.on { color: #B42318; background: color-mix(in srgb, #E24B4A 12%, transparent); border-color: color-mix(in srgb, #E24B4A 34%, transparent); }
html[data-theme="light"] .v2-fl-chip.prio.high.on   { color: #B54708; background: color-mix(in srgb, #EF9F27 15%, transparent); border-color: color-mix(in srgb, #EF9F27 38%, transparent); }
html[data-theme="light"] .v2-fl-chip.prio.normal.on { color: #1f7a44; background: color-mix(in srgb, #3ba55d 14%, transparent); border-color: color-mix(in srgb, #3ba55d 34%, transparent); }
/* ── Массовое действие «Кто может отдавать в мой ИИ»: сегмент режима (Apple-grade, 0292) ── */
/* CLIE-505: режим массового действия = канон .cc-seg + .cc-seg-md. Здесь остаются
   раскладка (варианты делят ширину модалки) и смысловой цвет «Убрать». */
.bb-modeseg-wrap { display: flex; }
.bb-modeseg-wrap > .bb-modeseg { flex: 1 1 0; }
.bb-modeseg[data-mode="remove"].on { color: #E24B4A; }
/* ── Доска проектов: колонки-корзины ── */
.pcat-scroll.is-board { overflow-x: auto; overflow-y: hidden; padding-bottom: 6px; }
/* align-items:stretch → колонки РАВНОЙ высоты (как Trello/Linear): ровная сетка + пустая
   колонка остаётся крупной мишенью для drop, а не схлопывается в полоску. */
.v2-pb-board { display: flex; gap: 12px; align-items: stretch; min-height: 320px; }
.v2-pb-col { flex: 0 0 268px; width: 268px; display: flex; flex-direction: column; min-height: 0;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px; }
.v2-pb-colhead { display: flex; align-items: center; gap: 8px; padding: 12px 14px 8px; font-size: 13px; font-weight: 600; color: var(--text); flex: none; }
.v2-pb-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.v2-pb-coltitle { flex: 1; }
.v2-pb-colcount { font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; background: var(--panel); border: 1px solid var(--line); border-radius: 20px; padding: 1px 8px; }
.v2-pb-cards { display: flex; flex-direction: column; gap: 8px; padding: 4px 10px 12px; min-height: 72px; flex: 1;
  max-height: calc(100vh - 250px); overflow-y: auto; border-radius: 12px; transition: background .12s ease, box-shadow .12s ease; }
.v2-pb-cards.drop-on { background: color-mix(in srgb, var(--primary) 9%, transparent); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--primary) 38%, transparent); }
.v2-pb-card { cursor: grab; padding: 12px; border-radius: 11px; gap: 7px; }
.v2-pb-card:active { cursor: grabbing; }
.v2-pb-card.dragging { opacity: .45; }
.v2-pb-card .v2-pc-coin { width: 28px; height: 28px; border-radius: 8px; font-size: 12px; }
.v2-pb-card .v2-pc-name { font-size: 14px; }
.v2-pb-drop { min-height: 2px; flex: none; }
/* ── Таймлайн проектов (роадмап) ── */
.pcat-scroll.is-tl { overflow-x: auto; }
.v2-tl { min-width: 660px; position: relative; }
.v2-tl-axis { display: flex; align-items: flex-start; }
.v2-tl-axis-label { flex: 0 0 176px; }
.v2-tl-axis-ticks { position: relative; flex: 1; height: 24px; border-bottom: 1px solid var(--line); overflow: visible; }
.v2-tl-tick { position: absolute; top: 2px; transform: translateX(-50%); font-size: 11px; color: var(--muted); white-space: nowrap; }
/* Линия «сегодня» живёт ВНУТРИ .v2-tl-rows и тянется ровно на высоту строк (top/bottom),
   а не «9999px вниз» — иначе она протекала сквозь «Без дат» и низ страницы.
   Смещение = ширина колонки-подписи + доля от трека (calc, долю пишет JS). */
.v2-tl-now { position: absolute; top: -10px; bottom: 0; width: 2px; z-index: 0; border-radius: 2px;
  background: color-mix(in srgb, var(--primary) 55%, transparent); pointer-events: none; }
.v2-tl-rows { display: flex; flex-direction: column; gap: 6px; padding-top: 10px; position: relative; }
.v2-tl-row { display: flex; align-items: center; gap: 0; cursor: pointer; border-radius: 10px; padding: 3px 0; transition: background .12s ease; }
.v2-tl-row:hover { background: color-mix(in srgb, var(--text) 5%, transparent); }
.v2-tl-label { flex: 0 0 176px; display: flex; align-items: center; gap: 8px; padding-right: 12px; min-width: 0; }
.v2-tl-label .v2-pc-coin { width: 24px; height: 24px; border-radius: 7px; font-size: 10.5px; }
.v2-tl-name { font-size: 13px; font-weight: 500; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* «в «Родитель»» под именем на роадмапе (CLIE-593) — та же тихая вторая строка, что в пикерах. */
.v2-tl-name .v2-tl-sub { display: block; font-size: 11px; font-weight: 400; color: var(--muted); line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-tl-track { position: relative; flex: 1; height: 26px; }
.v2-tl-bar { position: absolute; top: 0; height: 26px; border-radius: 8px; overflow: hidden; display: flex; align-items: center;
  background: color-mix(in srgb, var(--bc, #5b8def) 34%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bc, #5b8def) 55%, transparent); }
.v2-tl-fill { position: absolute; left: 0; top: 0; bottom: 0; background: color-mix(in srgb, var(--bc, #5b8def) 62%, transparent); }
.v2-tl-barlbl { position: relative; z-index: 1; font-size: 10.5px; color: var(--text); font-weight: 600; padding: 0 8px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
/* Полоса тянется мышью: тело = сдвиг обеих дат, края = старт/цель */
.v2-tl-bar { cursor: grab; user-select: none; }
.v2-tl-bar:active { cursor: grabbing; }
.v2-tl-bar.dragging { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--bc, #5b8def) 75%, transparent), 0 6px 18px rgba(0,0,0,.32); z-index: 3; }
.v2-tl-h { position: absolute; top: 0; bottom: 0; width: 10px; z-index: 4; cursor: ew-resize; }
.v2-tl-h-l { left: 0; } .v2-tl-h-r { right: 0; }
.v2-tl-h::after { content: ""; position: absolute; top: 50%; transform: translateY(-50%); width: 3px; height: 46%; border-radius: 3px; background: #fff; opacity: 0; transition: opacity .12s ease; }
.v2-tl-h-l::after { left: 3px; } .v2-tl-h-r::after { right: 3px; }
.v2-tl-bar:hover .v2-tl-h::after { opacity: .8; }
.v2-tl-undated { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 18px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 12px; color: var(--muted); }
.v2-tl-chip { font-size: 12px; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: 8px; padding: 4px 9px; cursor: pointer; transition: border-color .12s ease, color .12s ease; }
.v2-tl-chip:hover { color: var(--text); border-color: var(--primary); }
/* Плановые даты в шторке проекта */
.v2-dr-dates { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; max-width: 100%; }
.v2-dr-date { padding: 5px 8px; font-size: 12.5px; min-width: 0; width: 132px; }
.v2-dr-dsep { color: var(--muted); font-size: 12px; }

/* ── Пилюля-планировщик на карточке проекта (кликабельна: «когда»+срок → попап) ── */
.v2-pc-sched { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; font-size: 11px; font-weight: 600; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 3px 8px; cursor: pointer; white-space: nowrap;
  transition: border-color .12s ease, color .12s ease, background .12s ease; }
.v2-pc-sched:hover { color: var(--text); border-color: var(--primary); }
.v2-pc-sched.open { color: var(--text); border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }
.v2-pc-sched svg.ic { width: 12px; height: 12px; opacity: .8; flex: none; }
.v2-pc-bk-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--bk, var(--muted)); flex: none; }
.v2-pc-schsep { opacity: .5; }
.v2-pc-schmuted { color: var(--muted); }
.v2-pc-schlbl { overflow: hidden; text-overflow: ellipsis; }
.v2-pc-rchips .v2-pc-sched { font-size: 11px; }
.v2-pb-card .v2-pc-sched { align-self: flex-start; }
/* «+» в шапке колонки доски — создать проект сразу в этой корзине */
.v2-pb-coladd { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 7px;
  border: 1px solid transparent; background: transparent; color: var(--muted); cursor: pointer; flex: none; transition: background .12s ease, color .12s ease, border-color .12s ease; }
.v2-pb-coladd:hover { background: var(--panel); color: var(--text); border-color: var(--line); }
.v2-pb-coladd svg.ic { width: 15px; height: 15px; }
/* Меню столбца (⋯) + добавить столбец + drag-перестановка колонок (0080) */
.v2-pb-colmenu { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border-radius: 7px;
  border: 1px solid transparent; background: transparent; color: var(--muted); cursor: pointer; flex: none; transition: background .12s ease, color .12s ease, border-color .12s ease; }
.v2-pb-colmenu:hover, .v2-pb-colmenu.open { background: var(--panel); color: var(--text); border-color: var(--line); }
.v2-pb-colmenu svg.ic { width: 15px; height: 15px; }
.v2-pb-colhead { cursor: grab; }
.v2-pb-colhead:active { cursor: grabbing; }
.v2-pb-col.col-dragging { opacity: .55; }
.v2-pb-addcol { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; align-self: flex-start; height: 42px; padding: 0 16px;
  border: 1px dashed var(--line); border-radius: 14px; background: transparent; color: var(--muted); cursor: pointer; font-size: 13px; font-weight: 600;
  transition: color .12s ease, border-color .12s ease, background .12s ease; }
.v2-pb-addcol:hover { color: var(--text); border-color: var(--primary); background: var(--panel-2); }
.v2-pb-addcol svg.ic { width: 16px; height: 16px; }
.v2-bkt-pop { min-width: 236px; padding: 9px; }
.v2-bkt-pop .tw-select { width: 100%; margin: 2px 0 2px; }

/* ── Попап планировщика проекта: «Когда · Важность · Сроки» ── */
.v2-sch-pop { min-width: 248px; max-width: 292px; padding: 9px; }
.v2-sch-h { font-size: 13px; font-weight: 700; color: var(--text); padding: 3px 8px 6px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.v2-sch-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 2px 6px 4px; }
.v2-sch-row { display: flex; gap: 6px; padding: 2px 6px 4px; }
/* CLIE-505: это НЕ сегмент-дорожка, а сетка чипов-выборов (корзина/важность,
   число вариантов задаёт тенант) — переименовано из .v2-sch-seg, чтобы имя не врало
   и линтер дизайн-системы не считал их «ещё одним сегментом мимо канона». */
.v2-sch-chip { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 7px 8px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); font-size: 12.5px; font-weight: 600; cursor: pointer;
  transition: border-color .12s ease, color .12s ease, background .12s ease; }
.v2-sch-row .v2-sch-chip { flex: 1; font-variant-numeric: tabular-nums; }
.v2-sch-chip:hover { color: var(--text); border-color: var(--primary); }
.v2-sch-chip.on { color: var(--text); border-color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.v2-sch-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.v2-sch-chip.pr-p1.on { border-color: #E24B4A; background: color-mix(in srgb, #E24B4A 15%, transparent); color: #E24B4A; }
.v2-sch-chip.pr-p2.on { border-color: #EF9F27; background: color-mix(in srgb, #EF9F27 16%, transparent); color: #C77A10; }
.v2-sch-dates { display: flex; align-items: center; gap: 8px; padding: 2px 6px 6px; }
.v2-sch-dates .tw-select { flex: 1; min-width: 0; padding: 6px 8px; font-size: 12.5px; }
.v2-sch-arrow { color: var(--muted); flex: none; }
.v2-sch-presets { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 6px 4px; }
.v2-sch-preset { font-size: 11.5px; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 4px 10px; cursor: pointer; transition: border-color .12s ease, color .12s ease; }
.v2-sch-preset:hover { color: var(--text); border-color: var(--primary); }
.v2-sch-preset.v2-sch-clear { color: var(--danger); }
.v2-sch-preset.v2-sch-clear:hover { color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); border-color: var(--danger); }
/* Таймлайн: пустое состояние + кликабельные чипы «без дат» */
.v2-tl-empty { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.v2-tl-undated-lbl { color: var(--muted); margin-right: 2px; }
.v2-tl-chip { display: inline-flex; align-items: center; gap: 6px; }
.v2-tl-chip .v2-pc-coin { width: 18px; height: 18px; border-radius: 5px; font-size: 9px; }
/* Список: ручка перетаскивания (приоритет мышкой) + подсветка перетаскиваемой строки */
.v2-pc-grip { display: inline-flex; align-items: center; color: var(--muted); cursor: grab; opacity: 0; flex: none; margin: -2px -4px -2px -2px; transition: opacity .12s ease; }
.v2-pc-row:hover .v2-pc-grip { opacity: .55; }
.v2-pc-grip:hover { opacity: 1; }
.v2-pc-grip:active { cursor: grabbing; }
.v2-pc-grip svg.ic { width: 16px; height: 16px; }
.v2-pc-row.dragging { opacity: .5; border-color: var(--primary); box-shadow: 0 8px 22px rgba(0,0,0,.28); }
@media (max-width: 560px){ .v2-pc-grip { opacity: .55; } }
/* Доска: «Бэклог» — колонка-инбокс слева (нераспределённый пул), чуть приглушена */
.v2-pb-col.is-inbox { background: color-mix(in srgb, var(--panel-2) 60%, transparent); border-style: dashed; }
.v2-pb-colhint { font-size: 10.5px; color: var(--muted); font-weight: 500; opacity: .8; margin-left: -2px; }

/* ── Внутренняя страница проекта: единый шелл (общая шапка + табы) ── */
/* Внутри проекта убираем документные отступы обёртки .v2-wrap (шелл/доска идут edge-to-edge). */
.tw-body.v2-wrap.flush { padding: 0; overflow: hidden; }
.v2pt { display: flex; flex-direction: column; height: 100%; min-height: 0; }
/* Общая шапка проекта — идентичность (назад · коин · имя · роль · участники · действия) ОДИН раз для всех вкладок */
.v2pt-head { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line); flex: none; }
.v2pt-back { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 9px; border: 1px solid var(--line); background: var(--panel); color: var(--muted); cursor: pointer; flex: none; }
.v2pt-back:hover { color: var(--text); border-color: var(--primary); }
.v2pt-back svg.ic { width: 17px; height: 17px; }
.v2pt-head .v2-pc-coin { width: 36px; height: 36px; font-size: 15px; }
.v2pt-idtext { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.v2pt-name { font-size: 16px; font-weight: 700; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; letter-spacing: -.01em; }
/* Имя проекта редактируется прямо в шапке (владелец/админ) — не в отдельной модалке (0148). */
input.v2pt-name-input { background: transparent; border: 1px solid transparent; border-radius: 6px; padding: 2px 6px; margin: -2px -6px; width: 100%; max-width: 320px; cursor: text; }
input.v2pt-name-input:hover { border-color: var(--line); }
input.v2pt-name-input:focus { border-color: var(--primary); background: var(--input-bg, var(--panel)); }
.v2pt-sub { display: flex; gap: 6px; align-items: center; margin-top: 2px; }
/* Хлебная крошка «Родитель ›» над именем открытого проекта (CLIE-593): сразу видно, что ты
   внутри ПОДПРОЕКТА, и одним кликом уходишь к родителю. Тише имени — она навигация, а не титул. */
.v2pt-crumb { display: inline-flex; align-items: center; gap: 5px; align-self: flex-start; max-width: 100%; margin-bottom: 1px; padding: 0; background: none; border: 0; cursor: pointer; color: var(--muted); font-size: 11.5px; font-weight: 600; letter-spacing: .01em; line-height: 1.2; transition: color 140ms ease; }
.v2pt-crumb > span:not(.v2pt-crumb-dot) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2pt-crumb .v2pt-crumb-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; }
.v2pt-crumb svg.ic { width: 11px; height: 11px; flex: none; opacity: .75; }
.v2pt-crumb:hover { color: var(--text); }
.v2pt-avs { flex: none; }
.v2pt-acts { display: flex; gap: 8px; align-items: center; flex: none; }
/* .primary глобально width:100%+margin-top:6px — в шапке проекта/участников кнопки в ряд, сбрасываем */
.v2pt-acts .primary, .v2mem-head .primary { width: auto; margin-top: 0; }
@media (max-width: 760px) { .v2pt-head { flex-wrap: wrap; } .v2pt-acts { width: 100%; justify-content: flex-end; } .v2pt-avs { display: none; } }
.v2pt-bar { flex: none; display: flex; gap: 2px; border-bottom: 1px solid var(--line); padding: 0 12px; overflow-x: auto; }
.v2pt-tab { padding: 11px 16px; background: transparent; border: 0; border-bottom: 2px solid transparent; color: var(--muted); font-size: 14px; font-weight: 500; cursor: pointer; white-space: nowrap; }
.v2pt-tab:hover { color: var(--text); }
.v2pt-tab.on { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }
.v2pt-body { flex: 1; min-height: 0; overflow: auto; }
/* Вкладка «Задачи»: СКРОЛЛ-КОЛЛАПС шапки. .v2pt(.tab-tasks) — вертикальный скроллер: шапка проекта +
   табы + бар видов уезжают вверх, тулбар фильтров ПРИЛИПАЕТ к верху (sticky), доска (#twBody) фикс-
   высоты (JS: экран − тулбар) → столбцы визуально «растут»; внутри столбцы скроллятся сами (.tw-col-body).
   Внутренний скролл столбцов включаем ТОЛЬКО когда шапка полностью свёрнута (.collapsed) — тогда скролл
   вниз сперва сворачивает шапку, и лишь затем листает карточки; скролл вверх (chaining) — наоборот. */
.v2pt.tab-tasks.board-scroll { display: block; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; }
.v2pt.tab-tasks.board-scroll .v2pt-head, .v2pt.tab-tasks.board-scroll .v2pt-bar { flex: none; }
.v2pt.tab-tasks.board-scroll .v2pt-body { display: block; height: auto; overflow: visible; }
.v2pt.tab-tasks.board-scroll .v2tasks { display: block; height: auto; overflow: visible; }
.v2pt.tab-tasks.board-scroll .tw-toolbar { position: sticky; top: 0; z-index: 6; background: var(--bg); }
.v2pt.tab-tasks.board-scroll .tw-body { overflow-x: auto; overflow-y: hidden; }
.v2pt.tab-tasks.board-scroll:not(.collapsed) .tw-col-body { overflow-y: hidden; }
.v2pt-media { padding: 16px 18px; }
/* Вкладка «Задачи» = встроенное пространство задач (переключатель видов) */
.v2tasks { display: flex; flex-direction: column; height: 100%; min-width: 0; }
.v2tasks-bar { flex: none; display: flex; align-items: center; gap: 10px; padding: 10px 16px 6px; }
.v2tasks .tw-toolbar { flex: none; padding: 8px 16px; }
.v2tasks .tw-body { flex: 1; min-height: 0; overflow: auto; }
/* Внутри вкладки «Задачи» проекта строка поиска стоит В ОДНОМ РЯДУ с фильтрами, пока хватает
   ширины. 🔴 CLIE-805: `min-width` не даёт ей ужаться до огрызка — не помещается целиком,
   значит уезжает на СВОЮ линию (там уже сработает внутренний перенос, см. .tw-search-row). */
.v2tasks .tw-search-row { flex: 1 1 260px; min-width: min(520px, 100%); }
/* Участники проекта */
.v2mem { padding: 16px 18px 26px; max-width: 820px; }
/* узкое тело (телефон: 316 px за рейкой) — кнопки шапки и правая часть строки переносятся СТРОКОЙ
   НИЖЕ, а не уезжают за край: замер 21.10 при 390 — «Пригласить» 372–487 при крае 384, селект роли
   и тип участника на 46 px за краем (тело листалось вбок). */
.v2mem-head { display: flex; align-items: center; gap: 8px 12px; margin-bottom: 14px; flex-wrap: wrap; }
.v2mem-title { font-size: 17px; font-weight: 700; color: var(--text); flex: 1 1 auto; min-width: 0; }
.v2mem-pcount { font-size: 12px; font-weight: 500; color: var(--muted); }
.v2mem-toolbar { display: flex; flex-direction: column; gap: 10px; margin-bottom: 12px; }
.v2mem-searchrow { display: flex; align-items: center; gap: 8px; }
.v2mem-search { width: 100%; padding: 9px 13px; border-radius: 10px; border: 1px solid var(--line); background: var(--panel); color: var(--text); font-size: 13.5px; outline: none; }
.v2mem-search:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.v2mem-searchrow .v2mem-search { flex: 1; min-width: 0; }
.v2mem-gflt { flex: none; }
/* j_project · project-members-search-1 (телефон 390, вкладка «Участники»): селект «Все группы» ширится по
   самому длинному пункту (162–357), и поиску оставалось 58px (95–153), от подсказки видно «Пс». На узком теле
   поиск и фильтр групп встают двумя строками во всю ширину. Лупа уходит в ту же клетку сетки, что и поле:
   абсолютная позиция с top 50% встала бы между строками. */
@media (max-width: 560px) {
  .v2mem-searchrow { display: grid; grid-template-columns: minmax(0, 1fr); row-gap: 8px; }
  .v2mem-searchrow > svg.ic { position: relative; z-index: 1; grid-area: 1 / 1; align-self: center; justify-self: start; top: auto; transform: none; }
  .v2mem-searchrow > .v2mem-search { grid-area: 1 / 1; }
  .v2mem-searchrow > .v2mem-gflt { grid-row: 2; width: 100%; max-width: none; }
}
.v2mem-filters { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 0; }
.v2mem-fchip { padding: 6px 12px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--muted); font-size: 13px; cursor: pointer; }
.v2mem-fchip.on { background: var(--acc-fill); color: #fff; border-color: transparent; }
.v2mem-fchip span { opacity: .8; font-variant-numeric: tabular-nums; }
.v2mem-list { display: flex; flex-direction: column; }
.v2mem-sec { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700; margin: 16px 0 6px; }
.v2mem-row { display: flex; align-items: center; gap: 8px 12px; padding: 10px 4px; border-bottom: 1px solid var(--line); transition: background .15s; flex-wrap: wrap; }
.v2mem-row:last-child { border-bottom: 0; }
.v2mem-row:hover { background: var(--panel-2); }
.v2mem-row .prof-hit { border-radius: 8px; }
.v2mem-row.pending { opacity: .92; }
.v2mem-l { display: flex; align-items: center; gap: 11px; flex: 1 1 180px; min-width: 0; }
.v2mem-name { font-size: 14.5px; font-weight: 500; color: var(--text); }
.v2mem-uname { font-size: 12px; color: var(--muted); }
.v2mem-pend { font-size: 11.5px; color: var(--warning); margin-top: 1px; }
.v2mem-r { display: flex; align-items: center; gap: 8px; flex: none; flex-wrap: wrap; margin-left: auto; max-width: 100%; }
.v2mem-role-chip { font-size: 12px; color: var(--muted); padding: 4px 10px; border-radius: 8px; background: var(--panel-2); white-space: nowrap; }
.v2mem-role, .v2mem-typesel { min-width: 96px; }
.v2mem-type { font-size: 11.5px; font-weight: 600; padding: 3px 9px; border-radius: 6px; white-space: nowrap; }
.v2mem-type.t-employee { background: var(--panel-2); color: var(--muted); }
.v2mem-type.t-client { background: rgba(91, 141, 239, .16); color: #5b8def; }
.v2mem-type.t-contractor { background: rgba(245, 166, 35, .16); color: #d99a2b; }
.v2mem-type.t-external { background: var(--cm-a36bff-16, rgba(163, 107, 255, .16)); color: var(--cm-a36bff, #a36bff); }
.v2mem-rm { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 8px; border: 0; background: transparent; color: var(--muted); cursor: pointer; }
.v2mem-rm:hover { background: rgba(239, 68, 68, .12); color: var(--danger); }
.v2mem-rm svg.ic { width: 15px; height: 15px; }
.v2inv-hint { font-size: 12px; color: var(--muted); line-height: 1.45; margin-top: 2px; }

/* Ссылка-приглашение в проект (модалка «Пригласить в проект», CLIE-346): «приглашать извне».
   Аккуратный блок над поиском людей — свет/тёмная через токены, 4/8-grid, тонкие хэйрлайны. */
.v2inv-linkbox { display: flex; flex-direction: column; gap: 8px; padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); }
.v2inv-linkcap { font-size: 13px; font-weight: 600; color: var(--text); }
.v2inv-linkcap .small { font-weight: 400; }
.v2inv-linkrow { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.v2inv-linkinp { flex: 1 1 220px; min-width: 0; background: var(--input-bg); color: var(--text); border: 1px solid var(--line);
  border-radius: 9px; padding: 9px 11px; font-size: 13px; font-family: inherit; user-select: all; transition: border-color .14s ease; }
.v2inv-linkinp:focus { outline: none; border-color: var(--primary); }
.v2inv-lbtn { display: inline-flex; align-items: center; gap: 6px; border-radius: 9px; padding: 9px 12px; font-size: 13px; font-weight: 600;
  cursor: pointer; border: 1px solid transparent; white-space: nowrap; transition: filter .14s ease, background .14s ease, border-color .14s ease; }
.v2inv-lbtn svg { width: 15px; height: 15px; }
.v2inv-lbtn.primary { background: var(--acc-fill); color: #fff; }
.v2inv-lbtn.primary:hover:not(:disabled) { filter: brightness(1.07); }
.v2inv-lbtn.ghost { background: transparent; color: var(--text); border-color: var(--line-strong); }
.v2inv-lbtn.ghost:hover:not(:disabled) { background: var(--hover); }
.v2inv-lbtn:disabled { opacity: .5; cursor: default; }
.v2inv-rot { align-self: flex-start; background: none; border: none; color: var(--muted); font-size: 12px; cursor: pointer; padding: 2px 0; }
.v2inv-rot:hover { color: var(--primary-2); text-decoration: underline; }
.v2inv-or { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 12px; margin: 4px 0 0; }
.v2inv-or::before, .v2inv-or::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--line); }
/* 👤 CLIE-119 «Добавить в проект»: тип-первым (сегмент наверху), сворачиваемые блоки (ссылка / клиент
   из CRM), нота ограниченного доступа. Прогрессивное раскрытие: пусто = минимум. Тем через токены. */
/* CLIE-505: тип участника = канон .cc-seg + .cc-seg-md, здесь только раскладка
   (четыре варианта делят ширину модалки поровну). */
.v2inv-typeseg { display: flex; }
.v2inv-typeseg > .v2inv-typebtn { flex: 1 1 0; }
.v2inv-typehint { font-size: 12px; color: var(--muted); line-height: 1.45; margin: 8px 2px 4px; min-height: 16px; }
.v2inv-rolef { margin-top: 4px; }
.v2inv-restrict { display: flex; gap: 8px; font-size: 12.5px; line-height: 1.45; color: var(--text); background: color-mix(in srgb, var(--accent) 8%, transparent); border: 1px solid color-mix(in srgb, var(--accent) 28%, var(--line)); border-radius: 10px; padding: 10px 12px; margin-top: 8px; }
.v2inv-restrict[hidden] { display: none; }
.v2inv-collapse { margin-top: 10px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); overflow: hidden; }
.v2inv-collapse[hidden] { display: none; }
.v2inv-csum { list-style: none; cursor: pointer; padding: 11px 13px; font-size: 13px; font-weight: 600; color: var(--text); user-select: none; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.v2inv-csum::-webkit-details-marker { display: none; }
.v2inv-csum::after { content: "⌄"; margin-left: auto; color: var(--muted); font-size: 15px; line-height: 1; transition: transform .18s ease; }
.v2inv-collapse[open] .v2inv-csum::after { transform: rotate(180deg); }
.v2inv-csum .small { font-weight: 400; }
.v2inv-collapse[open] .v2inv-csum { border-bottom: 1px solid var(--line); }
.v2inv-collapse .v2inv-linkbox { border: none; border-radius: 0; background: transparent; padding: 12px 13px; }
.v2inv-linkacts { display: flex; gap: 8px; flex-wrap: wrap; }
.v2inv-crmbox { display: flex; flex-direction: column; gap: 8px; padding: 12px 13px; }
.v2inv-crmlist { display: flex; flex-direction: column; gap: 2px; max-height: 230px; overflow: auto; }
.v2inv-crmrow { display: flex; align-items: center; gap: 10px; padding: 8px 9px; border-radius: 9px; }
.v2inv-crmrow:hover { background: var(--panel); }
.v2inv-crmmeta { flex: 1; min-width: 0; }
.v2inv-crmname { font-size: 13.5px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.v2inv-crmsub { margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.v2inv-crmadd { flex: none; padding: 6px 12px; }
.v2inv-crmempty { padding: 12px 4px; text-align: center; }
/* Приватность групп (0102): пикер «в какие группы включить» — в модалках приглашения/добавления
   и в массовом действии над участниками. */
.v2-gp-tools { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.v2-gp-search { flex: 1; min-width: 0; padding: 7px 11px; border-radius: 9px; border: 1px solid var(--line); background: var(--panel); color: var(--text); font-size: 13px; outline: none; }
.v2-gp-search:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.v2-gp-all { flex: none; white-space: nowrap; }
.v2-inv-groups { display: flex; flex-direction: column; gap: 2px; max-height: 220px; overflow: auto; margin-top: 6px; padding: 2px; border: 1px solid var(--line); border-radius: 10px; }
.v2-chk { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--text); padding: 7px 9px; border-radius: 7px; cursor: pointer; }
.v2-chk:hover { background: var(--panel-2); }
.v2-chk input { width: 15px; height: 15px; accent-color: var(--primary); flex: none; }
.v2-gp-empty { padding: 12px 4px 2px; text-align: center; }
.v2mem-chk { width: 16px; height: 16px; accent-color: var(--primary); flex: none; cursor: pointer; }
.v2mem-chkspace { width: 16px; flex: none; } /* невидимый спейсер: держит аватар выровненным у строк без чекбокса (владелец) в режиме выбора */
.v2mem-bulkbar { border-radius: 10px; margin-bottom: 12px; }
.v2mem-bulkbar .sb-act[disabled] { opacity: .45; cursor: default; pointer-events: none; }
.sb-act.sb-danger { color: #e5484d; }
.sb-act.sb-danger:hover:not([disabled]) { background: rgba(229,72,77,.12); }
/* ── Единая шторка «Доступ» (0106→0161, владелец: «дизайн плохой, всё в куче»): раздельные вкладки
   [Группы | Задачи] сегмент-контролом. Apple-grade = СДЕРЖАННОСТЬ: чистый flush-список без иконок-
   плиток, статус — ОДНА тихая точка (не плитка+точка+жирный цветной текст), ведущий скруглённый
   КВАДРАТ-чекбокс (однозначно мультивыбор, не радио-кружок), счётчик — только бейджи на вкладках
   (без дублирующей строки-сводки), без заливки-«свечения» на всю строку. ── */
.v2acc { display: flex; flex-direction: column; gap: 12px; margin-top: 4px; }
.v2acc-pane { display: flex; flex-direction: column; gap: 10px; }
.v2acc-cap { font-size: 12px; font-weight: 600; color: var(--muted); margin: 12px 0 2px; letter-spacing: .01em; }
/* сегмент-контрол iOS: трек-подложка, активная «таблетка» с мягкой тенью */
.v2acc-segs { display: flex; gap: 3px; padding: 3px; background: var(--panel-2); border-radius: 10px; }
.v2acc-seg { flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 7px; padding: 7px 10px; border: none; background: transparent; color: var(--muted); font-size: 13px; font-weight: 600; border-radius: 8px; cursor: pointer; transition: background .16s ease, color .16s ease, box-shadow .16s ease; }
.v2acc-seg svg.ic { width: 15px; height: 15px; opacity: .9; }
.v2acc-seg:hover { color: var(--text); }
.v2acc-seg.on { background: var(--panel); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,.12), 0 0 0 .5px var(--line); }
.v2acc-badge { min-width: 18px; height: 18px; padding: 0 5px; display: inline-flex; align-items: center; justify-content: center; border-radius: 9px; background: var(--acc-fill); color: #fff; font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; }
.v2acc-badge:empty { display: none; }
/* короткая контекстная подпись — одна строка */
.v2acc-hint { font-size: 12px; color: var(--muted); line-height: 1.4; margin: 0 2px; }
.v2acc-hint b { color: var(--text); font-weight: 600; }
/* тулбар: поиск с иконкой + «Выбрать все» тихой текст-кнопкой */
.v2acc-tools { display: flex; align-items: center; gap: 8px; }
.v2acc-searchwrap { position: relative; flex: 1; min-width: 0; display: flex; align-items: center; }
.v2acc-searchwrap > svg.ic { position: absolute; left: 10px; width: 15px; height: 15px; color: var(--muted); pointer-events: none; }
.v2acc-search { flex: 1; min-width: 0; padding: 8px 11px 8px 32px; border-radius: 9px; border: 1px solid var(--line); background: var(--panel); color: var(--text); font-size: 13px; outline: none; transition: border-color .16s ease, box-shadow .16s ease; }
.v2acc-search:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.v2acc-all { flex: none; white-space: nowrap; padding: 7px 10px; border-radius: 8px; border: none; background: transparent; color: var(--accent); font-size: 12.5px; font-weight: 600; cursor: pointer; transition: background .16s ease; }
.v2acc-all:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.v2acc-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.v2acc-chip { padding: 4px 11px; border-radius: 7px; border: 1px solid var(--line); background: transparent; color: var(--muted); font-size: 12px; font-weight: 500; cursor: pointer; transition: background .16s ease, color .16s ease, border-color .16s ease; }
.v2acc-chip:hover { color: var(--text); }
.v2acc-chip.on { background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); border-color: color-mix(in srgb, var(--accent) 34%, transparent); font-weight: 600; }
/* сгруппированный инсет-список с хэйрлайн-разделителями (iOS grouped table) */
/* 🔴 CLIE-620: был `max-height:300px;overflow:auto` внутри `.v2-modal`, которая скроллится
   сама. Это чек-листы «Группы»/«Задачи» в правах доступа — их проходят ЦЕЛИКОМ, отмечая
   галочки; спрятать хвост под невидимый бегунок = выдать неполный доступ и не заметить. */
.v2acc-list { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); }
.v2acc-row { display: flex; align-items: center; gap: 12px; margin: 0; padding: 11px 13px; border-radius: 0; border-bottom: 1px solid var(--line); cursor: pointer; transition: background .13s ease; }
.v2acc-row:last-child { border-bottom: none; }
.v2acc-row:hover { background: var(--panel-2); }
.v2acc-row.on-sel { background: color-mix(in srgb, var(--accent) 7%, transparent); }
/* ведущий скруглённый КВАДРАТ-чекбокс — однозначный мультивыбор (Reminders/Files edit): пусто = тонкий контур, выбрано = акцент + белая галочка */
.v2acc-row input[type="checkbox"] { appearance: none; -webkit-appearance: none; flex: none; margin: 0; width: 21px; height: 21px; border: 1.6px solid var(--line-strong); border-radius: 6px; background: var(--panel); cursor: pointer; position: relative; transition: background .13s ease, border-color .13s ease; }
.v2acc-row:hover input[type="checkbox"] { border-color: var(--muted); }
.v2acc-row input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); }
.v2acc-row input[type="checkbox"]:checked::after { content: ""; position: absolute; left: 7px; top: 3.5px; width: 4px; height: 8.5px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.v2acc-row input[type="checkbox"]:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--glow); }
.v2acc-rowmain { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; flex: 1; }
.v2acc-rowtitle { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; font-weight: 500; color: var(--text); max-width: 100%; }
/* подзаголовок задачи: ОДНА тихая цветная точка + приглушённый статус (не жирный, не цветной текст) */
.v2acc-rowsub { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 500; color: var(--muted); }
.v2acc-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--muted); flex: none; }
.v2acc-dot.cat-started { background: #e0982a; }
.v2acc-dot.cat-done { background: #26a969; }
.v2acc-dot.cat-todo { background: var(--line-strong); }
.v2acc-empty { padding: 16px 4px; text-align: center; }
.v2acc-none { padding: 20px 10px; text-align: center; line-height: 1.5; border: 1px dashed var(--line); border-radius: 12px; }
/* Список вариантов для массовых «Роль»/«Тип» (один тап = применить всем выбранным) */
.v2opt-list { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--panel); }
.v2opt-row { text-align: left; width: 100%; padding: 13px 15px; border: none; border-bottom: 1px solid var(--line); background: transparent; color: var(--text); font-size: 14px; font-weight: 500; cursor: pointer; transition: background .13s ease; }
.v2opt-row:last-child { border-bottom: none; }
.v2opt-row:hover { background: var(--panel-2); }
.v2opt-row:active { background: color-mix(in srgb, var(--accent) 12%, transparent); }
/* Пикер «Сотрудники компании» на создании проекта (0105) — поиск + фильтр «Все/Администраторы»
   + «Выбрать все», строка с аватаром и должностью. Тот же язык, что v2-gp (группы). */
.v2-pp-tools { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.v2-pp-search { flex: 1; min-width: 0; padding: 7px 11px; border-radius: 9px; border: 1px solid var(--line); background: var(--panel); color: var(--text); font-size: 13px; outline: none; }
.v2-pp-search:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.v2-pp-all { flex: none; white-space: nowrap; }
.v2-pp-filters { display: flex; gap: 7px; margin: 8px 0 2px; }
.v2-pp-fchip { padding: 5px 11px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--muted); font-size: 12.5px; cursor: pointer; }
.v2-pp-fchip.on { background: var(--acc-fill); color: #fff; border-color: transparent; }
.v2-pp-list { display: flex; flex-direction: column; gap: 2px; max-height: 240px; overflow: auto; margin-top: 6px; padding: 2px; border: 1px solid var(--line); border-radius: 10px; }
.v2-pp-name { display: flex; flex-direction: column; min-width: 0; }
.v2-pp-dn { font-size: 13.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-pp-title { font-size: 11.5px; color: var(--muted); }
.v2-pp-empty { padding: 12px 4px 2px; text-align: center; }
/* Массовый пикер участников (Добавить участников… в каталоге проектов) — поиск + секции
   «Сотрудники компании / Другие», паритет с пикерами задач. Apple-grade. */
.bmp { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
.bmp-search { display: flex; align-items: center; gap: 8px; padding: 0 11px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); transition: border-color .13s, box-shadow .13s; }
.bmp-search:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.bmp-search svg { width: 16px; height: 16px; color: var(--muted); flex: none; }
.bmp-search input { flex: 1; min-width: 0; border: 0; outline: none; background: transparent; color: var(--text); font-size: 14px; padding: 9px 0; }
/* Фокус рисует ОБЁРТКА (`:focus-within` выше) — поле внутри своего свечения не несёт. */
.bmp-search input:focus { border: 0; box-shadow: none; background: transparent; }
/* 🔴 Поле поиска списка — часть обёртки, а не поле формы-хозяина. `.deal-field input` (та же
   специфичность, объявлено НИЖЕ) навязывало ему свою рамку, фон, скругление, отступы и второе
   кольцо фокуса — двойная рамка «Поиск…» в списке стадии (кадр владельца 14.09.2026, замер
   getComputedStyle на стенде). Две классовые метки самой обёртки весомее правил формы. */
.bmp-search.ccpp-search input, .bmp-search.ccpp-search input:focus { border: 0; border-radius: 0; background: transparent; box-shadow: none; outline: none; padding: 8px 0; }
/* То же для пикера людей (ccMountPeoplePicker), вставленного в поле формы `.v2-f`: `.v2-modal .v2-f input`
   (0,2,1) и его `:focus` (0,3,1) объявлены НИЖЕ и рисовали полю свою рамку, заливку и радиус —
   «поле в поле» в окне «Новый проект» (кадр 21.10: рамка обёртки 517–922 × 444–483, внутри — рамка
   поля 553–910 × 445–482). Вес (0,3,1)/(0,4,1) — выше правил формы-хозяина. */
.bmp > .bmp-search > input[type="search"], .bmp > .bmp-search > input[type="search"]:focus { border: 0; border-radius: 0; background: transparent; box-shadow: none; outline: none; padding: 9px 0; }
.bmp-list { display: flex; flex-direction: column; gap: 14px; max-height: min(52vh, 440px); overflow: auto; margin: 0 -4px; padding: 2px 4px; }
.bmp-sec { display: flex; flex-direction: column; gap: 3px; }
.bmp-sec-h { display: flex; align-items: center; gap: 8px; padding: 2px 6px 6px; position: sticky; top: 0; background: var(--bg); z-index: 1; }
.bmp-sec-t { font-size: 12px; font-weight: 640; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
/* подложка — подмес текста (как .v2-pg-count): --panel-2 в светлой теме = --bg липкой шапки секции,
   и «9» в окне «Новый проект» стояла голой цифрой, а в тёмной — в пилюле (кадр 21.10) */
.bmp-sec-n { font-size: 11.5px; color: var(--muted); background: color-mix(in srgb, var(--text) 8%, transparent); border-radius: 20px; padding: 1px 8px; min-width: 20px; text-align: center; }
.bmp-all { margin-left: auto; border: 0; background: transparent; color: var(--primary); font-size: 12.5px; font-weight: 560; cursor: pointer; padding: 3px 6px; border-radius: 7px; transition: background .12s; }
.bmp-all:hover { background: color-mix(in srgb, var(--primary) 12%, transparent); }
/* newproj-pickall-wrap-1 · телефон (≤760): в шапке секции «СОТРУДНИКИ КОМПАНИИ · 9 · Выбрать всех» пилюля
   сжималась и ломалась посреди подписи («Выбрать / всех»). Пилюля не сжимается и не переносится;
   уступает заголовок — он переносится только между словами. */
@media (max-width: 760px) {
  .bmp-sec-h > .bmp-all { flex: none; white-space: nowrap; }
  .bmp-sec-t { min-width: 0; }
}
.bmp-rows { display: flex; flex-direction: column; gap: 2px; }
.bmp-row { display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; padding: 7px 10px; border: 1px solid transparent; border-radius: 11px; background: transparent; cursor: pointer; transition: background .12s, border-color .12s; }
.bmp-row:hover { background: var(--panel-2); }
/* Выделенная строка — деликатная подсветка (НЕ жирная заливка --glow на всю строку, что
   запрещено дизайн-правилом); главный сигнал выбора — кружок-галочка справа (.bmp-check). */
.bmp-row.on { background: color-mix(in srgb, var(--primary) 8%, transparent); border-color: color-mix(in srgb, var(--primary) 20%, transparent); }
.bmp-row .tw-avs { flex: none; }
/* Лицо строки — 28px, как .ccpp-av у строки с лицом (канон пикера ниже по файлу: «кружок 28px, воздух под
   две строки»). Общий .tw-av 22px с кольцом 2px --panel (кольцо разделяет СТОПКУ аватаров) давал лицо 18px
   (x 541–558) в строке «имя + @ник» высотой 50–55px — кадр 21.10, окно «Новый проект», обе темы. */
.bmp-row .tw-avs > .tw-av, .bmp-prow .tw-avs > .tw-av { width: 28px; height: 28px; border-width: 0; font-size: 11.5px; font-weight: 600; }
.bmp-name { display: flex; flex-direction: column; min-width: 0; flex: 1; gap: 1px; }
.bmp-dn { font-size: 14px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bmp-sub { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Кольцо невыбранного кружка — чернила (--muted 75%), а не хэйрлайн --line: кадр 21.10 — кромка 47,48,57 на
   22,23,33 (1.36:1) и 220,220,225 на 244,245,248 (1.25:1) при норме 3:1 для границы контрола. Расчёт по токенам:
   «Глубина» 5.9 / 4.4, «Штиль» 4.3 / 3.5 (тёмная / светлая). Одиночный выбор (.ccpp) прячет кольцо сам. */
.bmp-check { flex: none; width: 22px; height: 22px; border-radius: 50%; border: 1.5px solid color-mix(in srgb, var(--muted) 75%, transparent); display: inline-flex; align-items: center; justify-content: center; color: transparent; transition: background .12s, border-color .12s, color .12s; }
.bmp-check svg { width: 14px; height: 14px; }
/* ЗВОН-701 · «Пригласить в созвон» — тот же канонический пикер людей (.bmp) внутри
   .modal-box. Липкая шапка секции берёт фон РАМЫ модалки, иначе строки просвечивают
   сквозь неё (в v2Modal фон рамы --bg, у .modal-box — --panel). */
.ci-people .bmp-sec-h { background: var(--panel); }
.ci-people .bmp-list { max-height: min(46vh, 380px); }
/* ЗВОН-931 · «Позвать по ссылке» — второй ответ окна «Пригласить», для тех, у кого
   аккаунта нет. Тихая карточка над списком людей: она не отбирает экран (одна строка
   заголовка + строка-цена + поле + кнопки), но её видно СРАЗУ, а не за другой кнопкой.
   🔴 Цвета только токенами — светлая и тёмная темы обязаны быть читаемы обе. */
.ci-link { display: flex; flex-direction: column; gap: 8px; padding: 12px; margin-bottom: 12px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--bg-soft, var(--panel)); }
.ci-link-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ci-link-ttl { font-size: 13px; font-weight: 700; color: var(--text); }
.ci-link-say { font-size: 12px; line-height: 1.35; color: var(--muted); }
/* 🔴 CLIE-425: read-only поле-значение занимает СВОЮ строку целиком, кнопки — строкой
   ниже. Мелкое поле рядом с крупной кнопкой — ровно то, что владелец уже забраковал. */
.ci-link-url { width: 100%; box-sizing: border-box; padding: 8px 10px; font-size: 12px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel); color: var(--text); }
.ci-link-url:focus { outline: none; border-color: var(--primary); }
.ci-link-acts { display: flex; flex-wrap: wrap; gap: 8px; }
.bmp-row.on .bmp-check { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; }
.bmp-empty { padding: 22px 4px; text-align: center; }
/* «Уже в проекте» (CLIE-346): совпавшие при поиске участники/приглашённые — DISABLED-строка со
   статусом-пилюлей справа. Не кликается (нет .bmp-row), приглушена — сигнал «его добавлять не надо». */
.bmp-prow { display: flex; align-items: center; gap: 11px; width: 100%; text-align: left; padding: 7px 10px; border: 1px solid transparent; border-radius: 11px; opacity: .6; cursor: default; }
.bmp-prow .tw-avs { flex: none; }
.bmp-pbadge { flex: none; font-size: 11px; font-weight: 560; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); border-radius: 20px; padding: 2px 9px; white-space: nowrap; }
/* ── ЕДИНЫЙ ПИКЕР ПРОЕКТОВ (CLIE-590) ────────────────────────────────────────────────────────
   Владелец о нативном селекте «Родительский проект»: «как тут найти проект — глазами? а когда их
   будет 1000? Везде должен быть поиск и понятный список с сортировкой и отображением всех данных».
   Геометрия наследуется от канона пикера людей (.bmp-*) — выбор проекта и выбор человека выглядят
   ОДИНАКОВО; здесь только то, чего у людей нет: цветная точка проекта, счётчик задач и свёрнутое
   поле формы. Акцент строки — точка и кружок-галочка, НИКАКИХ левых полос (CLIE-483).
   --ccpp-bg = поверхность, на которой лежит пикер: под ней «липкие» заголовки секций и панель
   раскрытого поля, иначе на прокрутке под заголовок просвечивают строки. */
.ccpp, .ccpp-inline { --ccpp-bg: var(--panel-2); }
.v2-modal .ccpp, .v2-modal .ccpp-inline { --ccpp-bg: var(--bg); }
.ccpp { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ccpp-search { padding: 0 10px; border-radius: 10px; }
.ccpp-search input { font-size: 13.5px; padding: 8px 0; }
.ccpp-bar { display: flex; align-items: center; gap: 8px; }
.ccpp-total { margin-left: auto; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.ccpp-list { max-height: min(46vh, 340px); gap: 10px; }
/* «Такого ещё нет» — последняя строка того же списка (СРЕД-40): отделена хэйрлайном,
   носит знак «+» и подпись словами; действием она не спорит с выбором выше. */
.ccpp-create {
  display: flex; align-items: center; gap: 8px; width: 100%; margin-top: 6px;
  padding: 9px 10px; border: 0; border-top: 1px solid var(--line); border-radius: 0 0 10px 10px;
  background: transparent; color: var(--primary); font: inherit; font-size: 13px;
  text-align: left; cursor: pointer; transition: background 120ms ease;
}
.ccpp-create svg { width: 15px; height: 15px; flex: 0 0 auto; }
.ccpp-create:hover { background: var(--hover); }
.ccpp-create:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--glow); }
.ccpp .bmp-sec-h { background: var(--ccpp-bg); padding-bottom: 4px; }
.ccpp .bmp-sec-n { background: transparent; border: 1px solid var(--line); }
/* Выбор ОДИНОЧНЫЙ: пустых кружков-чекбоксов на каждой строке быть не должно (это язык
   мульти-выбора и он шумит) — кольцо проявляется только у выбранной строки. */
.ccpp .bmp-check { border-color: transparent; }
.ccpp .bmp-row.on .bmp-check { border-color: var(--primary); }
/* Пункт-сброс («Без родителя» / «Без проекта») отделён хэйрлайном, а не заливкой. */
.ccpp-pins { padding-bottom: 6px; border-bottom: 1px solid var(--line); }
.ccpp-row { gap: 10px; padding: 6px 9px; }
.ccpp-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--muted); }
.ccpp-dot-none { background: transparent; box-shadow: inset 0 0 0 1.5px var(--line); }
.ccpp-ic { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 10px; height: 10px; color: var(--muted); }
.ccpp-ic svg { width: 14px; height: 14px; }
.ccpp-n { flex: none; min-width: 18px; text-align: center; font-size: 11.5px; font-variant-numeric: tabular-nums; color: var(--muted); border: 1px solid var(--line); border-radius: 20px; padding: 1px 7px; }
/* 🔴 КОНТРАСТ ДВУХ СТРОК — как в выборе аккаунта Google (владелец 16.09.2026: «сделай
   контрастнее… название ящика и имя ниже»). Первая строка — плотная и тёмная (это ответ на
   вопрос «что выбираю»), вторая — мягкая подпись. Живёт у КАНОНА пикера, а не у почты: один
   вид у всех списков выбора продукта. */
.ccpp .bmp-dn { font-weight: 600; letter-spacing: -.01em; color: var(--text); }
.ccpp .bmp-sub { font-size: 12px; color: var(--muted); }
/* Строка с ЛИЦОМ (ящик почты, человек): кружок 28px, воздух под две строки. */
.ccpp-row-face { gap: 11px; padding: 7px 9px; min-height: 46px; }
.ccpp-av { flex: none; width: 28px; height: 28px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; font-size: 11.5px; font-weight: 600; color: #fff;
  background-size: cover; background-position: center; overflow: hidden; }
.ccpp-av.mail-avx img, .ccpp-av img { width: 100%; height: 100%; object-fit: cover; }
/* Непрочитанные — акцентной пилюлей: число, которое зовёт открыть, не должно быть серым. */
.ccpp-n.hot { color: color-mix(in srgb, var(--primary) 78%, var(--text)); border-color: transparent;
  background: color-mix(in srgb, var(--primary) 14%, transparent); font-weight: 600; }
/* Кольцо выбора рядом с лицом и счётчиком тише — иначе три сигнала об одном. */
.ccpp .bmp-check { width: 18px; height: 18px; }
.ccpp .bmp-check svg { width: 12px; height: 12px; }
/* Клавиатурная подсветка (↑/↓): та же мягкая подложка, что у hover — чтобы «где я сейчас» читалось. */
.ccpp-row.cur { background: var(--panel-2); }
.v2-modal .ccpp-row.cur, .tc-pop .ccpp-row.cur { background: color-mix(in srgb, var(--text) 6%, transparent); }
/* Поле формы: закрытая строка = текущий выбор со всеми данными, клик раскрывает список ЗДЕСЬ ЖЕ
   (вложенный поповер снёс бы саму форму — tcPopover одноместный). */
.ccpp-field { display: flex; align-items: center; gap: 9px; width: 100%; box-sizing: border-box; min-height: var(--ctl-h); padding: 0 10px; border: 1px solid var(--line); border-radius: var(--ctl-r); background: var(--input-bg); color: var(--text); font-size: var(--ctl-fs); text-align: left; cursor: pointer; transition: border-color .13s, box-shadow .13s; }
.ccpp-field:hover { border-color: color-mix(in srgb, var(--primary) 35%, var(--line)); }
.ccpp-field.open { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.ccpp-fname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ccpp-field-svg-size-1 · `button` в селекторе — вес 0,1,2, как у общего `button svg.ic` (22 px, выше по файлу):
   правило ниже по файлу и потому побеждает, 15 px доходит до шеврона каждого пикера (.ccpp-field — всегда <button>). */
button.ccpp-field > svg { flex: none; width: 15px; height: 15px; color: var(--muted); transition: transform .16s; }
.ccpp-field.open > svg { transform: rotate(180deg); }
/* Обёртка автонакрытого <select>: ширину задаёт место, где стоял селект. */
.ccpp-wrap { min-width: 0; }
.ccpp-inline { margin-top: 8px; padding: 8px; border: 1px solid var(--line); border-radius: 12px; background: var(--ccpp-bg); }
.ccpp-inline .ccpp-list { max-height: min(40vh, 264px); }
/* 🔴 CLIE-993 · РАСКРЫТЫЙ СПИСОК = СЛОЙ НАД ФОРМОЙ. Место считает ccppRaise ЗАМЕРОМ поля;
   здесь только «как выглядит слой»: своя подложка (он лежит ПОВЕРХ чужого содержимого, а не
   внутри панели), тень и собственная прокрутка списка. `fixed` — потому что хост бывает с
   overflow:hidden (окно «Сохранить в Файлы»), и абсолютный слой срезало бы кромкой окна. */
.ccpp-inline.ccpp-raised { position: fixed; z-index: 1000; margin: 0; display: flex; flex-direction: column;
  min-height: 0; --ccpp-bg: var(--panel); background: var(--panel); box-shadow: var(--shadow-2, 0 18px 44px rgba(0,0,0,.28)); }
.ccpp-inline.ccpp-raised > .ccpp { min-height: 0; }
.ccpp-inline.ccpp-raised .ccpp-list { min-height: 0; flex: 0 1 auto; }
/* Обзор */
.v2ov { padding: 18px 20px 26px; }
.v2ov-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; row-gap: 10px; }
.v2ov-coin { width: 42px; height: 42px; border-radius: 12px; display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 17px; font-weight: 700; flex: none; }
.v2ov-htext { min-width: 0; }
.v2ov-name { font-size: 19px; font-weight: 700; color: var(--text); letter-spacing: -.01em; }
.v2ov-hsub { display: flex; gap: 7px; align-items: center; margin-top: 3px; flex-wrap: wrap; }
.v2ov-acts { display: flex; gap: 8px; align-items: center; }
.v2ov-grid { display: grid; grid-template-columns: 1.5fr 1fr; gap: 14px; align-items: start; }
@media (max-width: 720px){ .v2ov-grid { grid-template-columns: 1fr; } }
.v2ov-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.v2ov-card { background: var(--panel); border: 1px solid var(--line); border-radius: 13px; padding: 15px 16px; }
.v2ov-h { font-size: 11px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); font-weight: 700; margin-bottom: 11px; }

/* ── Вкладка «Виджет» проекта (renderV2ProjWidget): hero + «как это работает» + ЖИВОЙ предпросмотр +
   настройки. Apple-grade, светлая и тёмная. Раньше это была закопанная карточка в «Обзоре» (CLIE-369). */
.v2wg { padding: 16px 18px 26px; max-width: 1120px; margin: 0 auto; }
.v2wg-loading { padding: 24px 4px; }
.v2wg-hero { display: flex; align-items: center; gap: 15px; padding: 16px 18px; border: 1px solid var(--line); border-radius: 15px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 7%, var(--panel)), var(--panel)); margin-bottom: 16px; }
.v2wg-hero-ic { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 13px; display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 15%, transparent); color: var(--accent); }
.v2wg-hero-ic svg { width: 24px; height: 24px; }
.v2wg-hero-tx { flex: 1; min-width: 0; }
.v2wg-hero-title { font-size: 17px; font-weight: 750; color: var(--text); letter-spacing: -.01em; }
.v2wg-hero-sub { font-size: 12.5px; color: var(--muted); line-height: 1.45; margin-top: 3px; }
.v2wg-hero-toggle { flex: 0 0 auto; display: flex; align-items: center; gap: 11px; }
.v2wg-status { font-size: 11px; font-weight: 700; padding: 4px 10px; border-radius: 999px; letter-spacing: .02em; white-space: nowrap; }
.v2wg-status.on { color: var(--ok); background: var(--ok-soft); }
.v2wg-status.off { color: var(--muted); background: color-mix(in srgb, var(--muted) 14%, transparent); }
.v2wg-grid { display: grid; grid-template-columns: 1.02fr .98fr; gap: 16px; align-items: start; }
@media (max-width: 860px) { .v2wg-grid { grid-template-columns: 1fr; } }
.v2wg-col { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.v2wg-card { background: var(--panel); border: 1px solid var(--line); border-radius: 14px; padding: 16px 17px; }
/* «Как это работает» — нумерованные шаги */
.v2wg-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 13px; }
.v2wg-steps li { display: flex; gap: 12px; align-items: flex-start; }
.v2wg-stepn { flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 15%, transparent); color: var(--accent); font-size: 12px; font-weight: 750; margin-top: 1px; }
.v2wg-steptx { min-width: 0; }
.v2wg-steptx b { display: block; font-size: 13.5px; font-weight: 640; color: var(--text); line-height: 1.35; }
.v2wg-steptx small { display: block; font-size: 12px; color: var(--muted); line-height: 1.42; margin-top: 2px; }
/* Настройки */
.v2wg-baserow { display: flex; flex-direction: column; gap: 7px; }
.v2wg-label { display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600; color: var(--text); }
.v2wg-label svg { width: 15px; height: 15px; color: var(--muted); flex: 0 0 auto; }
.v2wg-baserow .tc-mini { width: 100%; box-sizing: border-box; }
.v2wg-hint { font-size: 12.5px; color: var(--muted); line-height: 1.45; margin-top: 12px; padding: 11px 13px; border-radius: 10px;
  background: var(--panel-2); border: 1px dashed var(--line-strong); }
.v2wg-embed { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--line); }
.v2wg-embed-row { display: flex; gap: 8px; align-items: flex-start; }
.v2wg-embed-ta { flex: 1; min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; line-height: 1.5;
  resize: none; white-space: pre-wrap; word-break: break-all; }
.v2wg-embed-actions { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
/* Живой предпросмотр — «устройство» с настоящим iframe виджета (то, что видит клиент) */
.v2wg-previewcard { position: sticky; top: 8px; }
.v2wg-preview-h { display: flex; align-items: center; gap: 8px; }
.v2wg-live { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 700; color: var(--ok);
  text-transform: none; letter-spacing: 0; }
.v2wg-live-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px var(--ok-soft); animation: v2wgPulse 1.8s ease-in-out infinite; }
@keyframes v2wgPulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
.v2wg-device { height: 560px; border-radius: 18px; overflow: hidden; background: var(--bg); border: 1px solid var(--line-strong);
  box-shadow: 0 18px 44px -20px rgba(0,0,0,.5), 0 2px 8px -3px rgba(0,0,0,.25); }
.v2wg-frame { width: 100%; height: 100%; border: 0; display: block; background: transparent; }
.v2wg-frame-empty { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; text-align: center; padding: 24px; }
.v2wg-frame-ic { width: 52px; height: 52px; border-radius: 15px; display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 12%, transparent); color: var(--accent); }
.v2wg-frame-ic svg { width: 27px; height: 27px; }
.v2wg-frame-emptytx { font-size: 13px; color: var(--muted); line-height: 1.5; }
.v2wg-devicecap { font-size: 11.5px; color: var(--muted); text-align: center; margin-top: 10px; line-height: 1.4; }
.v2ov-meta .v2-dr-meta { margin-top: -4px; }
.v2ov-swatches { display: flex; flex-wrap: wrap; gap: 7px; }
/* Палитра цвета проекта — общий вид для создания проекта (openNewProjectPopover) и «О проекте» на Обзоре.
   Кольцо через box-shadow (не border), чтобы выделение было видно и на светлой, и на тёмной теме. */
.np-sw { width: 22px; height: 22px; border-radius: 7px; border: 0; cursor: pointer; padding: 0; flex: 0 0 auto; box-shadow: 0 0 0 2px transparent; transition: box-shadow .12s; }
.np-sw:hover { box-shadow: 0 0 0 2px var(--line, rgba(0,0,0,.12)); }
.np-sw.on { box-shadow: 0 0 0 2px var(--bg, #fff), 0 0 0 4px var(--text, #111); }
.v2ov-danger { border-color: var(--danger, #e5484d); }
/* 🗂 CLIE-1791 «Шаблон проекта» — раздел рядом с проектом: строка заготовки, её числа и
   действия. Токены цвета те же, что у соседних карточек Обзора, своих значений нет — раздел
   обязан читаться в ОБЕИХ темах без отдельной правки. */
.v2ov-tplrow { border-top: 1px solid var(--line); padding: 8px 2px 9px; }
.v2ov-tplrow:first-child { border-top: 0; }
.v2ov-tplhead { display: flex; align-items: center; gap: 7px; font-size: 13.5px; color: var(--text); }
.v2ov-tplacts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; align-items: center; }
.v2ov-tpl .np-tpl-say { margin-top: 4px; }
/* Строка «что развернётся» под полем выбора шаблона в формах создания проекта. */
.np-tpl-say { font-size: 12px; color: var(--muted); line-height: 1.45; padding: 2px 0 4px; }
.v2ov-prog { display: flex; align-items: center; gap: 12px; }
.v2ov-bar { flex: 1; height: 9px; border-radius: 100px; background: var(--panel-2); overflow: hidden; }
.v2ov-bar > i { display: block; height: 100%; border-radius: 100px; background: var(--accent); transition: width .3s ease; }
.v2ov-bar.done > i { background: #22c55e; }
.v2ov-pct { font-size: 14px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; min-width: 40px; text-align: right; }
.v2ov-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 13px; }
.v2ov-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; padding: 4px 10px; }
.v2ov-chip b { color: var(--text); font-variant-numeric: tabular-nums; }
.v2ov-chip.ok b { color: var(--ok); } /* чернила смысла темы: #22c55e на светлом чипе — 2.1:1 */
.v2ov-chip.bad { background: rgba(239,68,68,.12); border-color: transparent; }
.v2ov-chip.bad b { color: var(--danger); }
.v2ov-list { display: flex; flex-direction: column; }
.v2ov-row { display: flex; align-items: center; gap: 10px; padding: 8px 4px; font-size: 13.5px; border-bottom: 1px solid var(--line); background: transparent; border-left: 0; border-right: 0; border-top: 0; text-align: left; cursor: pointer; width: 100%; color: var(--text); }
.v2ov-row:last-child { border-bottom: 0; }
.v2ov-row:hover { background: var(--panel-2); border-radius: 8px; }
.v2ov-due { font-size: 11.5px; color: var(--muted); min-width: 56px; flex: none; font-variant-numeric: tabular-nums; }
.v2ov-due.bad { color: var(--danger); font-weight: 600; }
.v2ov-rt { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2ov-member { display: flex; align-items: center; gap: 9px; padding: 6px 2px; font-size: 13.5px; }
/* Команда в «О проекте» кликабельна → профиль: мягкий hover-хайлайт (как строки Reminders). */
.v2ov-member.prof-hit { border-radius: 8px; cursor: pointer; transition: background 130ms ease; }
.v2ov-member.prof-hit:hover { background: var(--panel-2); }
.v2ov-mn { color: var(--text); }
.v2ov-mrole { margin-left: auto; font-size: 11.5px; color: var(--muted); }

/* чипы */
.v2-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; padding: 3px 9px; border-radius: 6px;
  background: var(--panel-2); color: var(--muted); white-space: nowrap; }
.v2-chip svg.ic { width: 13px; height: 13px; }
.v2-chip.mini { padding: 2px 7px; }
.v2-chip.ok { background: color-mix(in srgb, var(--ok) 18%, transparent); color: var(--ok); }
.v2-chip.warn { background: color-mix(in srgb, #EF9F27 22%, transparent); color: #d08a14; }
.v2-chip.bad { background: color-mix(in srgb, var(--danger) 18%, transparent); color: var(--danger); }
.v2-flag { display: inline-flex; }
.v2-flag svg.ic { width: 14px; height: 14px; }

/* доска: больше воздуха */
.v2-card-foot-l { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tw-col-ph { padding: 14px 0; text-align: center; color: var(--muted); font-size: 12px; }

/* строки списков */
.v2-list .tw-row { padding: 11px 12px; }
.tw-row-title { display: flex; align-items: center; gap: 8px; }

/* аватары имён */
.v2-uname { font-size: 12px; color: var(--text); }

/* ── Календарь сроков: настоящая месячная сетка ── */
.v2cal-bar { display: flex; align-items: center; gap: 12px; padding: 2px 0 14px; }
.v2cal-nav { display: flex; align-items: center; gap: 6px; }
.v2cal-month { font-size: 16px; font-weight: 600; color: var(--text); min-width: 158px; text-align: center; text-transform: capitalize; }
.v2cal-vtoggle { flex: none; }
.v2cal-vtoggle button { display: inline-flex; align-items: center; gap: 6px; }
.v2cal-vtoggle button svg.ic { width: 15px; height: 15px; }

.v2cal-grid-wrap { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.v2cal-wdrow, .v2cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); }
.v2cal-wd { padding: 9px 10px; font-size: 11px; color: var(--muted); text-transform: uppercase;
  letter-spacing: .04em; border-bottom: 1px solid var(--line); }
.v2cal-wd.we { color: #b78f8f; }
/* контраст-аудит: на СВЕТЛОЙ теме #b78f8f по белому = 2.86:1 (заголовок «Сб/Вс» невидим);
   углубляем оттенок только в светлой (в тёмной он лежит на тёмном фоне и читается). */
html[data-theme="light"] .v2cal-wd.we { color: #8f6668; }
.v2cal-cell { min-height: 96px; padding: 6px 6px 5px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  cursor: pointer; display: flex; flex-direction: column; gap: 4px; overflow: hidden; }
.v2cal-cell:nth-child(7n) { border-right: none; }
.v2cal-grid > .v2cal-cell:nth-last-child(-n+7) { border-bottom: none; }
.v2cal-cell.we { background: rgba(255,255,255,.018); }
.v2cal-cell.oom { background: rgba(0,0,0,.14); }
/* hover после .we/.oom + равная им специфичность по классам, иначе static-фон перебивал ховер */
.v2cal-cell:hover, .v2cal-cell.we:hover, .v2cal-cell.oom:hover { background: var(--panel-2); }
/* 🔴 CLIE-1585: «число чужого месяца» приглушают РОЛЬЮ темы, а не прибитым #545b69 — у
   прибитого цвета нет темы. Замер прода 28.09: на тёмной подложке rgb(24,29,37) это давало
   2.48:1, то есть число просто не читалось; --muted гасит так же, но по своей теме. */
.v2cal-cell.oom .v2cal-dn { color: var(--muted); }
.v2cal-cell.sel { box-shadow: inset 0 0 0 2px var(--primary); }
.v2cal-dn { font-size: 12px; color: var(--text); width: 24px; height: 22px; flex: none;
  display: inline-flex; align-items: center; justify-content: center; border-radius: 7px; }
.v2cal-cell.today .v2cal-dn { background: var(--acc-grad); color: #fff; font-weight: 600; }
.v2cal-evs { display: flex; flex-direction: column; gap: 3px; min-height: 0; }
.v2cal-ev { display: flex; align-items: center; gap: 4px; font-size: 11px; line-height: 1.35; color: var(--text);
  background: color-mix(in srgb, var(--evc) 17%, transparent); border-left: 3px solid var(--evc);
  border-radius: 4px; padding: 2px 5px; white-space: nowrap; overflow: hidden; }
.v2cal-ev:hover { background: color-mix(in srgb, var(--evc) 32%, transparent); }
.v2cal-ev.od { opacity: .6; }
.v2cal-ev-t { color: var(--muted); flex: none; font-variant-numeric: tabular-nums; }
.v2cal-ev-x { overflow: hidden; text-overflow: ellipsis; }
.v2cal-more { font-size: 10px; color: var(--muted); padding: 0 4px; }
.v2-sec.v2cal-sec-bad { color: var(--danger); }

/* ── Правая ШТОРКА (деталь) ── */
.v2-drawer-scrim { position: fixed; inset: 0; background: rgba(0,0,0,.45); z-index: 60; }
.v2-drawer { position: fixed; top: 0; right: 0; height: 100vh; width: min(480px, 94vw); z-index: 61;
  background: var(--bg); border-left: 1px solid var(--line); display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform .18s ease; box-shadow: -12px 0 40px -12px rgba(0,0,0,.5); }
.v2-drawer.open { transform: translateX(0); }
.v2-dr-head { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 14px 18px; border-bottom: 1px solid var(--line); }
.v2-dr-type { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.v2-dr-scroll { flex: 1; overflow-y: auto; padding: 16px 18px 28px; }
.v2-dr-title { width: 100%; background: transparent; border: none; color: var(--text); font-size: 18px; font-weight: 500;
  padding: 4px 0 10px; outline: none; }
.v2-dr-title:focus { border-bottom: 1px solid var(--primary); }
.v2-dr-meta { display: flex; flex-direction: column; }
/* значение уже 170 px (телефон, узкая карточка «О проекте») — встаёт СВОЕЙ строкой под подписью,
   а не выталкивает даты «Старт → Цель» за край (замер 21.10 при 390: 239–527 при крае 384) */
.v2-d-row { display: flex; align-items: center; gap: 6px 12px; padding: 9px 0; border-bottom: 1px solid var(--line); min-height: 40px; flex-wrap: wrap; }
.v2-d-label { width: 130px; flex: none; color: var(--muted); font-size: 13px; display: inline-flex; align-items: center; gap: 7px; }
.v2-d-label svg.ic { width: 15px; height: 15px; }
.v2-d-val { flex: 1 1 170px; min-width: 0; max-width: 100%; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 14px; }
.v2-d-val .tw-select, .v2-d-val input[type="date"] { background-color: var(--input-bg); color: var(--text);
  border: 1px solid var(--line); border-radius: 8px; padding: 6px 8px; font: inherit; }
/* у селекта значения — шеврон базы (select.tw-select): шорткат `background` здесь его стирал, и
   «Важность» / «Приоритет» / «Память» в «О проекте» и статус в шторке читались плашкой, а не выбором.
   Справа место под шеврон; полям даты и срока (тоже .tw-select) он не нужен — у них свой значок. */
.v2-d-val select.tw-select, .v2-drawer .v2-d-val select.tw-select { padding-right: 30px; }
.v2-d-val input.tw-select { background-image: none; }
/* Строка «Память» (0202) — единственная строка «О проекте» с подписью-следствием под контролом:
   выбор области знаний не самоочевиден, и подпись обязана сказать, ЧТО именно сейчас происходит.
   Поэтому у неё контрол и текст идут колонкой, а сама строка выравнивается по верху. */
.v2-d-row-wide { align-items: flex-start; }
.v2-d-row-wide .v2-d-label { padding-top: 7px; }
.v2ov-mem { flex-direction: column; align-items: stretch; gap: 5px; }
.v2ov-mem .tw-select { align-self: flex-start; max-width: 100%; }
.v2ov-memhint { line-height: 1.35; }
.v2-dr-section-h { font-size: 12px; color: var(--muted); margin: 16px 0 6px; text-transform: uppercase; letter-spacing: .04em; }
/* Группы проекта (0104): поиск + список строк + свёрнутый архив «Чат с ИИ · задача».
   Раньше все группы (в т.ч. сотни приватных ИИ-бесед по задачам) шли одной стеной
   одинаковых серых кнопок — нечитаемо на масштабе (жалоба владельца на дизайн). */
.v2-grp-search { position: relative; margin-bottom: 6px; }
.v2-grp-search input { width: 100%; background: var(--input-bg); color: var(--text); border: 1px solid var(--line);
  border-radius: 9px; padding: 7px 10px 7px 32px; font: inherit; font-size: 13px; outline: none; transition: border-color .12s; }
.v2-grp-search input:focus { border-color: var(--primary); }
.v2-grp-search svg.ic { position: absolute; left: 9px; top: 50%; transform: translateY(-50%); width: 14px; height: 14px; color: var(--muted); pointer-events: none; }
.v2-grp-list { display: flex; flex-direction: column; gap: 2px; }
/* 🔴 CLIE-620: класс `.scroll` вешался ровно при «групп стало больше 6» — то есть буквально
   «выросло → спрячем», внутри уже скроллящегося `.v2pt-body`. Кап снят (сам класс на разметке
   оставлен: `padding-right` держит воздух под бегунок родителя). */
.v2-grp-list.scroll { padding-right: 2px; }
.v2-grp-row { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; cursor: pointer;
  background: transparent; border: 0; border-radius: 9px; padding: 7px 6px; color: var(--text); font: inherit; font-size: 13.5px; transition: background .12s; }
.v2-grp-row:hover { background: var(--panel-2); }
/* project-groups-avatar-1: шеврон — ПРЯМОЙ ребёнок строки. Потомковый `svg.ic:last-child` ловил и
   единственный значок внутри кружка .v2-grp-ic и гасил его (opacity:0) — кружок был пустым. */
.v2-grp-row > svg.ic:last-child { width: 14px; height: 14px; color: var(--muted); flex: none; opacity: 0; transition: opacity .12s; }
.v2-grp-row:hover > svg.ic:last-child { opacity: 1; }
.v2-grp-ic { flex: none; width: 28px; height: 28px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--panel-2); color: var(--muted);
  /* слои ccAvatarFace (.cc-av-ini / .cc-av-img) лежат absolute inset:0 — кружку нужна своя коробка */
  position: relative; overflow: hidden; font-size: 11px; font-weight: 700; letter-spacing: .02em; }
.v2-grp-ic svg.ic { width: 14px; height: 14px; }
.v2-grp-ic.ai { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary-2); }
.v2-grp-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2-grp-empty, .v2-grp-no-results { display: block; padding: 6px; }
.v2-grp-ai-h { cursor: pointer; user-select: none; }
.v2-grp-ai-h .v2-grp-chev { order: 2; display: inline-flex; width: 14px; height: 14px; transition: transform .16s; }
.v2-grp-ai-h .v2-grp-chev svg.ic { width: 14px; height: 14px; }
.v2-grp-ai-h.open .v2-grp-chev { transform: rotate(90deg); }
.v2-grp-ai-body { display: none; }
.v2-grp-ai-body.open { display: block; animation: v2GrpAiIn .14s ease; }
@keyframes v2GrpAiIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: translateY(0); } }
/* участники проекта + статусы доски (шторка проекта) */
.v2-members, .v2-statuses { display: flex; flex-direction: column; gap: 4px; }
.v2-member { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 4px; border-radius: 8px; }
.v2-member:hover { background: var(--panel-2); }
.v2-member-l { display: flex; align-items: center; gap: 8px; min-width: 0; }
.v2-member-r { display: flex; align-items: center; gap: 6px; flex: none; }
.v2-member-r .tw-select { padding: 3px 24px 3px 8px; font-size: 12px; }
.v2-status-row { display: flex; align-items: center; gap: 8px; padding: 6px 4px; }
.v2-status-row .v2-uname { flex: 1; }
.v2-asg-rm { background: transparent; border: 0; cursor: pointer; color: var(--muted); padding: 2px; border-radius: 6px; display: inline-flex; }
.v2-asg-rm:hover { color: var(--urg-overdue-ink); background: var(--panel); }
.v2-asg-rm svg.ic { width: 14px; height: 14px; }
.v2-add-btn { margin-top: 6px; display: inline-flex; align-items: center; gap: 5px; }
.v2-proj-avs { display: inline-flex; align-items: center; margin-left: 6px; }
.v2-d-desc { width: 100%; min-height: 64px; background: var(--input-bg); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 9px 11px; font: inherit; resize: vertical; }
.v2-asg { display: inline-flex; align-items: center; gap: 5px; background: var(--panel-2); border-radius: 8px; padding: 2px 4px 2px 2px; }
.v2-asg-rm { background: transparent; border: none; color: var(--muted); cursor: pointer; display: inline-flex; padding: 2px; }
.v2-asg-rm svg.ic { width: 12px; height: 12px; }

/* вкладки детали */
.v2-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin: 16px 0 12px; }
.v2-tabs button { display: inline-flex; align-items: center; gap: 6px; background: transparent; border: none;
  border-bottom: 2px solid transparent; color: var(--muted); padding: 9px 8px; cursor: pointer; font: inherit; font-size: 13px; }
.v2-tabs button.active { color: var(--text); border-bottom-color: var(--primary); }

/* обсуждение */
.v2-cms { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
/* обсуждение как чат: чужие слева с аватаром, свои справа без аватара */
.v2-cm { display: flex; align-items: flex-end; gap: 7px; max-width: 88%; }
.v2-cm.own { margin-left: auto; flex-direction: row-reverse; }
.v2-cm-bubble { background: var(--theirs); border: 1px solid var(--line); border-radius: 14px; border-bottom-left-radius: 5px; padding: 7px 11px; min-width: 0; }
.v2-cm.own .v2-cm-bubble { background: var(--mine); border-color: transparent; border-bottom-left-radius: 14px; border-bottom-right-radius: 5px; }
.v2-cm.internal .v2-cm-bubble { background: color-mix(in srgb, #EF9F27 12%, var(--theirs)); border-color: color-mix(in srgb, #EF9F27 32%, var(--line)); }
.v2-cm-h { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); margin-bottom: 3px; }
.v2-cm-h b { color: var(--primary-2); font-weight: 600; }
.v2-cm.own .v2-cm-h { justify-content: flex-end; }
.v2-cm-h .tw-muted { margin-left: auto; }
.v2-cm-b { font-size: 14px; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.v2-cm-add { display: flex; align-items: center; gap: 6px; position: sticky; bottom: 0; background: var(--bg); padding-top: 6px; }
.v2-cm-add input[type="text"] { flex: 1; background: var(--input-bg); color: var(--text); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 9px 11px; font: inherit; }
.v2-cm-add .icon-btn.on { color: #d08a14; }
/* кнопки в строке ввода (отправить/замок) не должны растягиваться (primary = full-width) */
.v2-cm-add button { flex: none; width: auto; }
.v2-act { font-size: 13px; color: var(--text); padding: 6px 0; border-bottom: 1px solid var(--line); }
.v2-time-total { font-size: 14px; margin-bottom: 8px; }
.v2-star { cursor: pointer; color: var(--line); display: inline-flex; }
.v2-star svg.ic { width: 20px; height: 20px; }
.v2-star.on { color: #ffd54a; }

/* модалка создания / пикер */
/* z-index ВЫШЕ полосы «страничных» оверлеев (.cli-overlay/#compOverlay=9000, .cli-scrim=9100,
   .pr-ov=9200), иначе модалка v2 (аналитика проекта/компании, новое обращение), открытая ИЗ
   «Компаний»/«Клиентов», уходит ЗА оверлей и выглядит как «ничего не открылось». Держим под
   PiP(9300)/tw-pop(9600)/cc-spot(9999) — они по дизайну поверх всего. */
.v2-modal-scrim { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 9250; display: flex; align-items: center; justify-content: center; padding: 20px; }
.v2-modal { width: min(440px, 96vw); max-height: 86vh; overflow: auto; background: var(--bg); border: 1px solid var(--line); border-radius: 14px; }
/* 🔴🔴 ШАПКА И ПОДВАЛ НЕ УЕЗЖАЮТ ВМЕСТЕ С СОДЕРЖИМЫМ (CLIE-683·6).
   Замер на живом проде, движок ПК-версии (Chromium 130), окно 1440×900, конструктор
   открытки: рама `.v2-modal` — `max-height:86vh` (=774px) и `overflow:auto`, а содержимое
   1132px. То есть прокручивается САМА РАМА, и вместе с ней уезжают её собственные шапка и
   подвал: кнопка «Отправить» стояла на 1183px при окне 900 — открытку НЕ ОТПРАВИТЬ, пока
   не домотаешь до самого низа, а бегунок в продукте прозрачен, пока на блок не навели мышь
   (решение владельца, CLIE-620). Ровно тот класс, ради которого заведён `ccModalSelfScroll`:
   «отрезает она не хвост текста, а САМИ КНОПКИ». Семейство `.v2-modal` в тот канон не
   входит — он знает только `.modal-box`.
   Лечим ЛИПКОСТЬЮ, а не перестройкой на «рама клипает + тело скроллит»: `position:sticky`
   не создаёт обрезки, поэтому выпадашки и пикеры внутри ЛЮБОЙ v2-модалки продолжают
   рисоваться как рисовались. Смена `overflow` их бы обрезала — это чинило бы открытку и
   ломало соседей. */
.v2-modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--line); font-weight: 500;
  position: sticky; top: 0; z-index: 2; background: var(--bg); border-radius: 14px 14px 0 0;
}
.v2-modal-body { padding: 14px 16px; display: flex; flex-direction: column; gap: 12px; }
.v2-modal-foot {
  display: flex; justify-content: flex-end; gap: 8px;
  padding: 12px 16px; border-top: 1px solid var(--line);
  position: sticky; bottom: 0; z-index: 2; background: var(--bg); border-radius: 0 0 14px 14px;
}

/* Настройки очереди обращений: «Кто отвечает» (агенты/должности Куратор·Оператор + навыки)
   и распределение. Светлая+тёмная — на токенах. */
.qs-modal { width: min(560px, 96vw); }
.qs-body { gap: 0; padding: 0; }
.qs-sec { padding: 16px; border-top: 1px solid var(--line); }
.qs-sec:first-child { border-top: none; }
.qs-sec-h { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 650; letter-spacing: .02em; text-transform: uppercase; color: var(--muted); margin-bottom: 12px; }
.qs-sec-h svg.ic { width: 15px; height: 15px; }
.qs-roster { display: flex; flex-direction: column; }
.qs-agent { display: flex; align-items: center; gap: 10px; padding: 9px 0; border-top: 1px solid var(--line); }
.qs-agent:first-child { border-top: none; }
.qs-agent-main { flex: 1 1 auto; min-width: 0; }
.qs-agent-name { font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.qs-skills { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; }
.qs-skill { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; padding: 2px 4px 2px 7px; border-radius: 6px; background: var(--accent-tint); color: var(--text-2); }
.qs-skill button { display: inline-flex; align-items: center; border: none; background: none; padding: 0; cursor: pointer; color: var(--muted); }
.qs-skill button svg.ic { width: 11px; height: 11px; }
.qs-skill button:hover { color: var(--danger); }
.qs-skilladd { display: inline-flex; align-items: center; gap: 2px; font-size: 11px; padding: 2px 7px; border-radius: 6px; border: 1px dashed var(--line-strong); background: none; color: var(--muted); cursor: pointer; transition: color .12s, border-color .12s; }
.qs-skilladd svg.ic { width: 11px; height: 11px; }
.qs-skilladd:hover { color: var(--accent); border-color: var(--accent); }
/* CLIE-505: роль агента очереди = канон .cc-seg + .cc-seg-sm (была слитная
   группа кнопок с accent-заливкой выбранного — свой вид на весь продукт). */
.qs-rolebadge { font-size: 12px; font-weight: 550; padding: 4px 10px; border-radius: 8px; background: var(--surface); color: var(--text-2); flex: 0 0 auto; }
.qs-rolebadge.lead { background: var(--accent-tint); color: var(--accent); }
.qs-rm { flex: 0 0 auto; color: var(--muted); transition: color .12s, background .12s; }
.qs-rm:hover { color: var(--danger); }
.qs-rm.armed { color: #fff; background: var(--danger); }
.qs-add { margin-top: 12px; }
.qs-note { font-size: 12px; color: var(--muted); margin-top: 8px; line-height: 1.4; }
.qs-radio { display: flex; flex-direction: column; gap: 6px; }
.qs-radio-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; transition: border-color .12s, background .12s; }
.qs-radio-row.on { border-color: var(--accent); background: var(--accent-tint); }
.qs-radio-row input { margin-top: 2px; accent-color: var(--accent); flex: 0 0 auto; }
.qs-radio-main { display: flex; flex-direction: column; gap: 1px; }
.qs-radio-lbl { font-size: 14px; font-weight: 550; color: var(--text); }
.qs-radio-hint { font-size: 12px; color: var(--muted); }
.qs-radio-row:has(input:disabled) { cursor: default; opacity: .7; }
/* promptModal — async in-app замена браузерного prompt() (работает в Electron/везде).
   🔴 z-index ВЫШЕ любого другого оверлея (композер сториз 13200, карусель/просмотрщик
   13000, «Закреплённые»-модалка макс. 13600) — иначе, будучи вызванным ИЗНУТРИ них
   (напр. «+ Новая группа» в композере сториз), рендерится ПОД ними: невидим и некликабелен.
   Ровно это скрывало выбор группы на «следующем шаге» и читалось как «пропавшая кнопка» —
   жалоба владельца 2026-07-24. Нативный prompt() браузера ВСЕГДА поверх всего — этот дроп-ин
   должен вести себя так же. */
.pm-scrim { position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 13800; display: flex; align-items: center; justify-content: center; padding: 20px; }
/* 🔴 ОКНО НЕ ВЫШЕ ЭКРАНА, ТЕЛО ПРОКРУЧИВАЕТСЯ — свойство РАМЫ, а не отдельных окон (владелец
   15.09.2026, окно выдачи токенов с 26 моделями: «Сильно узко, не скроллится»). Раньше
   прокрутка была только у `.pm-wide`; обычное окно с длинным телом уезжало за низ экрана без
   бегунка. Карточка — колонка: шапка · тело (min-height:0 + overflow) · подвал всегда виден. */
.pm-card { width: min(420px, 96vw); max-height: calc(100dvh - 40px); display: flex; flex-direction: column; background: var(--bg); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 24px 60px -12px rgba(0,0,0,.5); overflow: hidden; }
.pm-card.pm-lg { width: min(760px, 96vw); }
.pm-head { padding: 15px 18px; font-weight: 600; font-size: 15px; color: var(--text); border-bottom: 1px solid var(--line); }
.pm-body { padding: 16px 18px; display: flex; flex-direction: column; gap: 8px; min-height: 0; overflow: auto; }
.pm-label { font-size: 12.5px; color: var(--muted); font-weight: 500; }
.pm-input { width: 100%; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel); color: var(--text); font-size: 14px; outline: none; font-family: inherit; }
.pm-input:focus { border-color: var(--accent); }
.pm-hint { font-size: 12px; color: var(--muted); white-space: pre-line; }
.pm-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--line); }
.pm-foot .primary, .pm-foot .ghost { width: auto; margin: 0; }
/* 🔴 ВТОРОЙ ВЫХОД ОТКАЗА (CRMC-704). Отказ «нет расчётного счёта» даёт ДВА пути: вписать р/с
   руками (основное действие в подвале) и подключить банк по API (этот). Второй путь стоит в
   ТЕЛЕ окна, а не в подвале: подвал — это «сделать или отменить», третья кнопка там читается
   как ещё одно «ОК». Замер обеих тем 13.09.2026: `.ghost` берёт рамку `--line` (её контраст
   к панели ~1.1 ПО ЗАМЫСЛУ — это токен ЛИНИИ, канон theme-contrast-runtime), и на фоне `--bg`
   контрол не читается как контрол вовсе. Красим каноном акцента — подложка 12% + кольцо 30%,
   без левых реек; чернила остаются `--text`, акцент несёт подложка. */
/* 🔴 Класс СВОЙ (`.errfix-altbtn`), а НЕ `.ghost` — тот же урок, что у `.dvs-accbtn` ниже:
   `.ghost, html[data-theme="light"] .ghost` гасит фон И рамку, и его специфичность (0,2,1)
   выше любого `.обёртка .ghost` (0,2,0), поэтому перекрасить призрак снаружи нельзя — можно
   только перестать им быть. Замер в живом браузере 13.09.2026 перечислил все 4 правила,
   красящие кнопку: победителем оказалось именно тематическое. Второй выход отказа — такой же
   восстановительный CTA, как `.dvs-accbtn`, и наследовать «призрачный» стиль он не должен. */
.errfix-alt { margin-top: 12px; }
.errfix-altbtn {
  border: 1px solid color-mix(in srgb, var(--primary) 34%, var(--line));
  background: color-mix(in srgb, var(--primary) 12%, var(--panel-2));
  color: var(--text); font-weight: 560;
  padding: 6px 12px; border-radius: 8px; font-size: 12.5px; cursor: pointer;
  transition: background .14s ease, border-color .14s ease;
}
.errfix-altbtn:hover { background: color-mix(in srgb, var(--primary) 20%, var(--panel-2)); border-color: color-mix(in srgb, var(--primary) 52%, var(--line)); }
.errfix-alt-say { margin-top: 6px; }
.v2-f { display: flex; flex-direction: column; gap: 5px; font-size: 13px; color: var(--muted); }
.v2-f input, .v2-f textarea, .v2-f select { background: var(--input-bg); color: var(--text); border: 1px solid var(--line);
  border-radius: 9px; padding: 9px 11px; font: inherit; }
.v2-f2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.v2-pick { display: flex; flex-direction: column; gap: 4px; max-height: 50vh; overflow: auto; }
.v2-pick-row { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--line);
  border-radius: 9px; background: var(--panel); cursor: pointer; color: var(--text); }
.v2-pick-row.on { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, var(--panel)); }
.v2-pick-row svg.ic { width: 16px; height: 16px; margin-left: auto; color: var(--primary); }

/* плашка «по задаче» на сообщении-зеркале обсуждения в общем чате */
.msg-task-ref { display: inline-flex; align-items: center; gap: 5px; margin: 0 0 6px; padding: 3px 9px; border-radius: 8px;
  background: color-mix(in srgb, var(--primary) 15%, transparent); color: var(--primary);
  border: 1px solid color-mix(in srgb, var(--primary) 38%, transparent); font-size: 11px; cursor: pointer; }
.msg-task-ref svg.ic { width: 13px; height: 13px; }
.msg-task-ref:hover { background: color-mix(in srgb, var(--primary) 24%, transparent); }

/* svg-иконки в пилюлях v1-воркспейса и бейдже источника задачи */
.tw-pill { display: inline-flex; align-items: center; gap: 4px; }
.tw-pill svg.ic { width: 12px; height: 12px; }
.td-source { display: inline-flex; align-items: center; gap: 5px; }
.td-source svg.ic { width: 13px; height: 13px; }

/* дашборд аналитики */
.v2-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin-bottom: 6px; }
.v2-stat { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 13px 15px; }
.v2-stat-v { font-size: 22px; font-weight: 500; color: var(--text); }
.v2-stat-l { font-size: 12px; color: var(--muted); margin-top: 3px; }
/* 🔴 БАГ (был на проде): карточка ловила ГЛОБАЛЬНЫЙ стиль КНОПКИ `.danger`
   (background:var(--danger); color:#fff — ниже по файлу, поэтому выигрывал) → вся плашка
   заливалась красным, а число красилось var(--danger) = красное на красном → цифру
   просрочек было НЕ ВИДНО. Возвращаем карточный вид: мягкая подложка + читаемое число.
   🔴 Специфичность: голое `.v2-stat.danger` (0,2,0) ПРОИГРЫВАЕТ светлому
   `html[data-theme="light"] .danger` (0,2,1) — поэтому дублируем селектор под светлую (0,3,1). */
.v2-stat.danger,
html[data-theme="light"] .v2-stat.danger { background: var(--danger-soft); color: var(--text); border-color: rgba(239,68,68,.32); box-shadow: none; }
.v2-stat.danger .v2-stat-v,
html[data-theme="light"] .v2-stat.danger .v2-stat-v { color: var(--danger); }
.v2-stat.danger .v2-stat-l,
html[data-theme="light"] .v2-stat.danger .v2-stat-l { color: var(--muted); }

/* ═══════ Дашборд аналитики эффективности (Компания/Сотрудники/Проекты) ═══════ */
.dash-bar { display: flex; align-items: center; gap: 10px; padding: 2px 0 12px; }
.dash-scope { display: inline-flex; margin: 0 0 16px; }
.dash-period button, .dash-scope button { font-size: 12.5px; }
.dash-kpis { grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); }
.dash-idx { border-color: var(--accent); background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 14%, transparent), color-mix(in srgb, var(--primary) 2%, transparent)); }
.dash-idx.s-hi { border-color: var(--ok); background: linear-gradient(180deg, rgba(34,197,94,.14), rgba(34,197,94,.02)); }
.dash-idx.s-mid { border-color: var(--urg-today); background: linear-gradient(180deg, rgba(229,162,60,.14), rgba(229,162,60,.02)); }
.dash-idx.s-lo { border-color: var(--danger); background: linear-gradient(180deg, rgba(239,68,68,.14), rgba(239,68,68,.02)); }
.dash-idx .v2-stat-v { font-weight: 700; }
.dash-idx-u { font-size: 13px; font-weight: 500; color: var(--muted); margin-left: 2px; }

/* Карточки сами добавляют колонки по мере ширины (2 на ~1000, 3 на ~1400, 4 на ~1850) —
   растущие данные просто втекают в сетку, а не удлиняют скролл. */
.dash-grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 14px; margin: 14px 0; align-items: start; }
.dash-card { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 13px 15px; }
.dash-card-h { font-size: 13px; font-weight: 600; color: var(--text); margin-bottom: 10px; display: flex; align-items: baseline; gap: 8px; }
.dash-hint { font-size: 10.5px; font-weight: 400; color: var(--muted); }
/* ── Графики: фикс-высота, свободная ширина, БЕЗ растяжения геометрии ──────────
   Плот-зона = content-box (.dchart минус паддинги под значения сверху и подписи снизу).
   Сетка/линия/точки позиционируются в тот же inset — совпадают пиксель-в-пиксель. */
.dchart { position: relative; height: 200px; padding: 20px 0 24px; }
.dchart-grid { position: absolute; inset: 20px 0 24px; display: flex; flex-direction: column; justify-content: space-between; pointer-events: none; }
.dchart-grid i { display: block; height: 1px; background: var(--line); opacity: .75; position: relative; }
.dchart-grid.pct i::after { content: attr(data-v) "%"; position: absolute; right: 0; top: -7px; font-size: 9.5px; line-height: 14px; color: var(--muted); background: var(--panel); padding: 0 4px; border-radius: var(--r-xs); }
.dchart-bars { position: relative; height: 100%; display: flex; align-items: flex-end; gap: 8px; }
.dbar { position: relative; flex: 1 1 0; min-width: 0; height: 100%; }
.dbar-fill { position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); width: 100%; max-width: 40px; height: var(--h, 0%);
  background: rgba(139,147,163,.34); border-radius: var(--r-xs) var(--r-xs) 2px 2px; transition: height var(--dur-2) var(--ease), background var(--dur-1) var(--ease); }
.dbar.hot .dbar-fill { background: var(--primary); }
.dbar:hover .dbar-fill { background: var(--primary-2); }
.dbar-v { position: absolute; left: 0; right: 0; bottom: var(--h, 0%); margin-bottom: 5px; text-align: center; font-size: 11px; font-weight: 600; color: var(--text); }
.dbar-v.zero { color: var(--text-dim); font-weight: 400; }
.dbar-x { position: absolute; left: 0; right: 0; bottom: -20px; text-align: center; font-size: 10px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dbar.hot .dbar-x { color: var(--text); font-weight: 600; }

/* Линия «в срок»: stroke не масштабируется (non-scaling-stroke), точки — CSS по % */
/* 🔴 Размер SVG задаём ЯВНО (width/height), а не через inset: <svg> — replaced element,
   для него `width/height:auto` = интринсик-размер, inset его НЕ растягивает (с `height:auto`
   график раздувался и вылезал за карточку). calc(100% - 44px) = высота плот-зоны (padding 20+24). */
.dline { position: absolute; top: 20px; left: 0; width: 100%; height: calc(100% - 44px); display: block; overflow: visible; }
.dline-p { fill: none; stroke: var(--primary); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.dline-area { fill: var(--primary); opacity: .1; stroke: none; }
.dline-dots { position: absolute; inset: 20px 0 24px; pointer-events: none; }
.dline-dot { position: absolute; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; background: var(--panel); border: 2px solid var(--primary); pointer-events: auto; transition: transform var(--dur-1) var(--ease); }
.dline-dot:hover { transform: scale(1.35); }
.dline-dot.hot { width: 11px; height: 11px; margin: -5.5px 0 0 -5.5px; background: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent); }
/* 🔴 height задаём явно: базовое `.dchart-bars{height:100%}` (=200px padding-box) перебивало
   пару top/bottom из inset → блок уезжал на 20px ниже, а подписи дат — под карточку. */
.dchart-bars.ghost { position: absolute; top: 20px; left: 0; right: 0; height: calc(100% - 44px); pointer-events: none; }

/* 📊 CcCharts (CLIE-1847·②): стопка в столбце, плотный ряд (>16 точек), сетка со значениями */
.dbar-fill.stack { display: flex; flex-direction: column-reverse; overflow: hidden; background: transparent; }
.dbar:hover .dbar-fill.stack { background: transparent; filter: brightness(1.08); }
.dpart { display: block; min-height: 0; background: rgba(139,147,163,.34); }
.dpart.ok { background: var(--primary); }
.dpart.miss { background: var(--danger-fill); }
.dpart.etc { background: rgba(139,147,163,.45); }
.dchart.dense .dchart-bars { gap: 2px; }
.dchart.dense .dbar-fill { border-radius: 2px 2px 1px 1px; }
.dchart.dense .dbar-x { overflow: visible; text-overflow: clip; left: -20px; right: -20px; }
.dchart.dense .dline-dot { width: 6px; height: 6px; margin: -3px 0 0 -3px; border-width: 1.5px; }
.dchart.dense .dline-dot.hot { width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; }
.dchart-grid.vals i::after { content: attr(data-v); position: absolute; left: 0; top: -16px; font-size: 10.5px; line-height: 14px; color: var(--muted); white-space: nowrap; }
.dchart-grid.vals i[data-v=""]::after { display: none; }
.dchart.xdense .dchart-bars { gap: 1px; }
.dchart.xdense .dbar-fill { border-radius: 1px 1px 0 0; }

.dchart-empty { height: 200px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 9px; color: var(--muted); font-size: 12.5px; }
.dchart-empty .ic { width: 22px; height: 22px; opacity: .4; }

/* План-факт живёт ВНУТРИ .dash-card → своя рамка/фон не нужны (была карточка в карточке). */
.dash-pf { padding: 2px 0 0; }
.dash-pf-row { margin: 0 0 14px; }
.dash-pf-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.dash-pf-lab { font-size: 12.5px; color: var(--muted); }
/* Тонкие треки-линии (999 на 10px = линия, не «пилюля» — см. правило «квадратного» UI). */
.dash-pf-bar { flex: 1; background: rgba(139,147,163,.14); border-radius: var(--r-full); height: 10px; overflow: hidden; }
.dash-pf-bar i { display: block; height: 100%; border-radius: var(--r-full); transition: width var(--dur-2) var(--ease); }
.dash-pf-bar i.plan { background: var(--text-dim); opacity: .55; }
.dash-pf-bar i.fact { background: var(--primary); }
/* Перерасход — янтарный fill-токен (НЕ var(--warning): в светлой теме он #9a6a00 под
   AA-контраст текста и давал грязно-оливковую полосу во всю строку). */
.dash-pf-bar i.fact.over { background: var(--fill-warn); }
.dash-pf-num { text-align: right; font-size: 13.5px; font-weight: 600; color: var(--text); white-space: nowrap; }
.dash-pf-num.over { color: var(--warning); }
.dash-pf-num em { font-style: normal; font-size: 11px; opacity: .85; }
.dash-pf-legend { font-size: 11.5px; color: var(--muted); margin-top: 14px; border-top: 1px solid var(--line); padding-top: 11px; }
.dash-pf-legend b { color: var(--text); }

.dash-tblwrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.dash-tbl { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 460px; }
.dash-tbl th { text-align: center; font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 600; padding: 0 10px 9px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.dash-tbl th:first-child, .dash-tbl td:first-child { text-align: left; }
/* Широкий экран: ширину таблицы заполняем ДАННЫМИ (доп. колонки), а не растяжкой пустоты.
   Колонка имени ограничена, иначе забирала ~1200px и до цифр глазу было далеко. */
.dash-tbl th:first-child, .dash-tbl td:first-child { max-width: 420px; }
.dash-tbl td:first-child { overflow: hidden; text-overflow: ellipsis; }
.dash-tbl td { padding: 10px; border-bottom: 1px solid var(--line); color: var(--text); text-align: center; white-space: nowrap; }
.dash-tbl tbody tr { cursor: pointer; transition: background .1s; }
.dash-tbl tbody tr:hover { background: color-mix(in srgb, var(--primary) 7%, transparent); }
.dash-tbl tbody tr:last-child td { border-bottom: none; }
.dash-name { display: flex; align-items: center; gap: 8px; }
.dash-ava { display: inline-flex; width: 24px; height: 24px; border-radius: 50%; align-items: center; justify-content: center; font-size: 10px; font-weight: 700; color: #fff; background: var(--acc-grad); flex-shrink: 0; }
.dash-pdot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 7px; vertical-align: middle; }
.dash-ok { color: var(--ok); } .dash-mid { color: var(--urg-today); } .dash-bad { color: var(--danger); }
.v2-chip.dash-ok { color: var(--ok); border-color: rgba(34,197,94,.4); }
.v2-chip.dash-mid { color: var(--urg-today); border-color: rgba(229,162,60,.4); }
.v2-chip.dash-bad { color: var(--danger); border-color: rgba(239,68,68,.4); }
.dash-score { display: inline-block; min-width: 30px; padding: 2px 8px; border-radius: 7px; font-weight: 700; font-size: 12.5px; background: rgba(139,147,163,.16); color: var(--muted); }
.dash-score.s-hi { background: rgba(34,197,94,.16); color: var(--ok); }
.dash-score.s-mid { background: var(--urg-today-soft); color: var(--urg-today); }
.dash-score.s-lo { background: rgba(239,68,68,.16); color: var(--danger); }

.dash-back { margin-bottom: 8px; }
.dash-detail-h { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.dash-detail-name { font-size: 17px; font-weight: 600; color: var(--text); }
.dash-funnel { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 15px; }
.dash-funnel-row { display: flex; align-items: center; gap: 12px; margin: 7px 0; }
.dash-funnel-lab { width: 130px; font-size: 12.5px; color: var(--text); flex-shrink: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-funnel-bar { flex: 1; background: rgba(139,147,163,.14); border-radius: 6px; height: 13px; }
.dash-funnel-bar i { display: block; height: 100%; border-radius: 6px; background: rgba(139,147,163,.5); }
.dash-funnel-bar i.cat-started { background: var(--accent); }
.dash-funnel-bar i.cat-done { background: var(--ok); }
.dash-funnel-bar i.cat-cancelled { background: var(--danger); }
.dash-funnel-num { width: 40px; text-align: right; font-size: 12.5px; font-weight: 600; color: var(--text); }
.tw-row-sub { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

/* Чипы «план/факт по времени» и «факт-дата» на карточке/строке задачи. */
.tw-pill-pf, .task-chip.pf { color: var(--muted); }
/* разделитель «план / факт» — чернилами пилюли: прозрачность .5 давала 2.16 на светлой (свип 19.10) */
.tw-pill-pf .pf-sep { margin: 0 1px; }
.tw-pill-pf.over, .task-chip.pf.over { color: var(--urg-today); }
.tw-pill-sched.ok, .task-chip.sched.ok { color: var(--ok); }
.tw-pill-sched.over, .task-chip.sched.over { color: var(--danger); }

/* Дашборд аналитики в модалке (кнопки «Аналитика» проекта/компании, клик по человеку). */
/* КРУПНАЯ модалка (90vw × 90vh), НЕ фуллскрин: у нас нет 100%-оверлеев, вокруг ДОЛЖЕН
   быть виден затемнённый фон — иначе не читается как модалка (владелец, 2026-07-21).
   Раньше капали 1560px/94vh → на широком мониторе «плавало мелко». Теперь 90% (кап
   2200px на ультравайде для читаемости), скругление+бордер+тень = чистая модалка;
   внутри — липкий тулбар (blur, хэйрлайн) и скролл. Scoped на .dash-modal — вкладка
   «Аналитика» (.dash-page) не затрагивается (renderDash общий). */
.dash-scrim { background: rgba(0,0,0,.55); animation: dashScrimIn .16s ease; }
.dash-modal {
  width: min(90vw, 2200px); height: 90vh; max-height: 90vh;
  display: flex; flex-direction: column; position: relative; padding: 0;
  border: 1px solid var(--line); border-radius: 16px; overflow: hidden;
  box-shadow: 0 24px 80px -24px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.18);
  animation: dashModalIn .18s cubic-bezier(.22, .61, .36, 1);
}
.dash-modal-x { position: absolute; top: 12px; right: 14px; z-index: 6; background: var(--panel); border: 1px solid var(--line); border-radius: 9px; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; color: var(--muted); transition: color .12s, border-color .12s, background .12s; }
.dash-modal-x:hover { color: var(--text); border-color: var(--lineStrong); background: var(--panel-2); }
.dash-modal-body { --dash-pad: clamp(16px, 2.6vw, 40px); overflow-y: auto; overflow-x: hidden; padding: 0 var(--dash-pad); }
/* Липкий тулбар во всю ширину окна (full-bleed через отриц. поля = −внутр. отступ
   скроллера), но его СОДЕРЖИМОЕ выровнено с контентом. Полупрозрачный фон + blur. */
.dash-modal-body .dash-controls { margin: 0 calc(-1 * var(--dash-pad)); padding: 14px var(--dash-pad) 12px; z-index: 3; border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--bg) 84%, transparent); -webkit-backdrop-filter: saturate(1.6) blur(16px); backdrop-filter: saturate(1.6) blur(16px); }
.dash-modal-body .dash-content { padding: 18px 0 40px; margin-top: 0; }
.dash-modal-body .v2-toolbar-title { font-size: 17px; font-weight: 600; }
.dash-modal-body .dash-bar { padding-right: 44px; flex-wrap: wrap; }
@keyframes dashModalIn { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: none; } }
@keyframes dashScrimIn { from { opacity: 0; } to { opacity: 1; } }
.dash-content { margin-top: 2px; }
.dash-clickrow { cursor: pointer; }
.dash-clickrow:hover { background: color-mix(in srgb, var(--primary) 7%, transparent); }
.dash-clickrow .tw-row-side svg.ic { width: 14px; height: 14px; opacity: .5; }
.dash-tip { margin: 2px 0 12px; padding: 8px 11px; background: var(--panel); border: 1px solid var(--line); border-radius: 9px; color: var(--muted); }
/* 🧾 Срез «ИИ» дашборда (14.10.2026): шапка с сегментом, проблемы точкой (не полосой — канон
   accent), подписи KPI, строка очереди. Остальное — общие .dash-card / .dash-pf-* / .dash-tbl. */
.dash-ai-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 10px; }
.dash-ai-queue { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text); margin: 0 0 12px; }
.dash-ai-queue .ic, .dash-ai-fin .ic { width: 15px; height: 15px; color: var(--muted); flex: none; }
.dash-ai-kh { font-size: 10.5px; color: var(--muted); margin-top: 3px; line-height: 1.3; }
.dash-ai-probs { margin: 0 0 12px; }
.dash-ai-prob { display: flex; gap: 9px; align-items: flex-start; padding: 9px 0; border-top: 1px solid var(--line); }
.dash-ai-prob:first-of-type { border-top: 0; }
.dash-ai-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--muted); flex: none; margin: 6px 6px 0 0; vertical-align: middle; }
.dash-ai-dot.bad { background: var(--danger); }
.dash-ai-dot.warn { background: var(--fill-warn); }
.dash-ai-pb { min-width: 0; }
.dash-ai-pt { font-size: 13.5px; font-weight: 600; color: var(--text); }
.dash-ai-ps { font-size: 12.5px; color: var(--text); margin-top: 3px; overflow-wrap: anywhere; }
.dash-ai-pl { font-size: 12px; color: var(--muted); margin-top: 3px; }
.dash-ai-pl b { color: var(--text); font-weight: 600; }
.dash-ai-fin { display: flex; align-items: flex-start; gap: 7px; font-size: 12.5px; color: var(--text); margin: 0 0 12px; overflow-wrap: anywhere; }
.dash-card .dash-pf-lab { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
button.tw-row.dash-ai-task { width: 100%; text-align: left; background: none; border: 0; font: inherit; color: inherit; cursor: pointer; }
.dash-ai-tbl td:first-child { font-weight: 600; }
/* 👔 0475 · «Все · Моя команда» над таблицей «Сотрудники» — канонический .cc-seg, подпись рядом. */
.dash-teambar { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; margin: 2px 0 10px; }
.dash-tbl tbody tr[data-emp], .dash-tbl tbody tr[data-proj] { cursor: pointer; }
.v2-member-click { cursor: pointer; border-radius: 8px; padding: 2px 5px; margin: -2px -5px; transition: background .1s; }
.v2-member-click:hover { background: color-mix(in srgb, var(--primary) 12%, transparent); }

/* ── Полностраничная аналитика: вкладка «Аналитика» пространства задач (в #twBody). ──
   Хост фикс-высоты (флекс-родитель), скролл ТОЛЬКО контента, липкие контролы сверху —
   поэтому страница не «прыгает высотой» как прежняя модалка. */
/* 🔴 Ширина: раньше max-width 1180 на любом мониторе → на 1920 простаивало 644px (35%),
   на 2560 — половина экрана. Дашборд — плотный экран данных (их будет больше), поэтому
   отдаём ему всю ширину; 2200 — санитарный кап для ультравайда, чтобы строки не «разъезжались». */
.dash-page { padding: 18px clamp(16px, 1.6vw, 28px) 40px; max-width: 2200px; margin: 0 auto; }
.dash-controls { position: sticky; top: 0; z-index: 4; background: var(--bg); padding: 6px 0 10px; }
.dash-controls .dash-bar { flex-wrap: wrap; }
.dash-controls .dash-scope { margin-bottom: 0; }
.dash-me-badge { font-size: 11px; font-weight: 600; color: var(--accent); background: color-mix(in srgb, var(--primary) 14%, transparent); border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent); border-radius: 6px; padding: 2px 10px; margin-left: 2px; }
html[data-theme="light"] .dash-me-badge { color: var(--primary-2); } /* CLIE-1946: акцент-чернила на акцент-тинте — --primary-2 (3.72 → AA) */

/* «Свой период» (кнопка + поповер дат) и мультивыбор проектов для сводной аналитики. */
/* 🔴 ВЫБРАННЫЙ «СВОЙ ПЕРИОД» ВИДЕН В ОБЕИХ ТЕМАХ (CLIE-1442). Прежнее правило было
   `.dash-custom.active` (0,2,0) и проигрывало ТЕМАТИЧЕСКОМУ `html[data-theme="light"] .ghost`
   (0,2,1) — тот же класс, что у `.dvs-accbtn` и `.errfix-altbtn`: призрак гасит фон И рамку, и
   «снаружи» его не перекрасить. `!important` спасал только рамку, поэтому на СВЕТЛОЙ подложка
   выбранного чипа оставалась прозрачной: выбранный «01.03–31.03» читался как ссылка, а
   выбранным выглядел первый чип дорожки — «Всё время», хотя числа под ним считались за март
   (замер в живом браузере: computed background = rgba(0,0,0,0), победитель — тематический
   `.ghost`; в тёмной теме подложка была, поэтому дефект жил только в светлой).
   Лечим тематической веткой (0,3,1) и отдельным `:hover` (0,3,2), а не ещё одним `!important`:
   hover призрака тоже тематический и иначе стирал бы «выбрано» под курсором.
   🔴 ЧЕРНИЛА ДАТ — `--text`, а не `--accent`: акцент по акцентной подложке замерен близнецом в
   приложении как 3.26:1 (светлая) / 3.65:1 (тёмная), ниже AA (`client/lib/widgets/cc_period_lens.dart`,
   канон theme-contrast-runtime). «Выбрано» говорят подложка, кольцо и значок; сами даты человек
   ЧИТАЕТ. Подложка/кольцо — по канону `accent` (10–14% / ~22–36%). */
.dash-custom.active, html[data-theme="light"] .dash-custom.active {
  background: color-mix(in srgb, var(--accent) 13%, transparent);
  border-color: color-mix(in srgb, var(--accent) 36%, transparent);
  color: var(--text); font-weight: 600;
}
.dash-custom.active:hover, html[data-theme="light"] .dash-custom.active:hover {
  background: color-mix(in srgb, var(--accent) 20%, transparent);
  border-color: color-mix(in srgb, var(--accent) 52%, transparent);
}
.dash-custom.active .ic { color: var(--accent); }
.dash-pop .tc-pop-presets { margin-bottom: 8px; }
.dash-pop input[type="date"] { color-scheme: dark; }
html[data-theme="light"] .dash-pop input[type="date"] { color-scheme: light; }

.dash-cbcell { width: 36px; text-align: center; cursor: pointer; }
.dash-cb { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border: 1.5px solid var(--lineStrong); border-radius: 6px; color: transparent; transition: background .12s, border-color .12s, color .12s; vertical-align: middle; }
.dash-cbcell:hover .dash-cb { border-color: var(--accent); }
.dash-cb.on { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; }
.dash-cb .ic { width: 12px; height: 12px; }
.dash-tbl-sel tbody tr.dash-rowsel { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.dash-tbl-sel tbody tr.dash-rowsel:hover { background: color-mix(in srgb, var(--primary) 13%, transparent); }

/* Полоса выбора — компактная плашка по содержимому (не растянутая на всю ширину:
   на 1800px текст слева и кнопка у правого края читались как две разные вещи). */
.dash-selbar { display: inline-flex; align-items: center; gap: 12px; margin: 2px 0 14px; padding: 7px 8px 7px 13px; background: var(--sel); border: 1px solid color-mix(in srgb, var(--primary) 32%, transparent); border-radius: var(--r-md); }
.dash-selbar-t { font-size: 13px; color: var(--text); }
.dash-selbar-t b { color: var(--accent); }
/* svgIcon+подпись в кнопке должны идти в строку (без inline-flex «✕» вставал над текстом). */
.dash-selbar .ghost { display: inline-flex; align-items: center; gap: 6px; }
.dash-selbar .ghost .ic { width: 14px; height: 14px; }
.dash-combined { margin-bottom: 16px; }

/* «Я vs команда» — бенчмарк-карточки в личном срезе. */
.dash-bench { margin: 14px 0 4px; }
.dash-bench-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.dash-bench-item { background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 11px 13px; }
.dash-bench-lab { font-size: 11.5px; color: var(--muted); margin-bottom: 5px; }
.dash-bench-mine { font-size: 20px; font-weight: 600; color: var(--text); display: flex; align-items: baseline; gap: 6px; }
.dash-bench-mine.dash-ok { color: var(--ok); }
.dash-bench-mine.dash-bad { color: var(--danger); }
.dash-bench-arrow { font-size: 12px; }
.dash-bench-team { font-size: 11.5px; color: var(--muted); margin-top: 3px; }

@media (max-width: 720px) { .dash-grid2 { grid-template-columns: 1fr; } }

/* Уведомления: «колокол» в шапке с красной точкой, когда granted, но подписка не прошла. */
#notifyTopBtn.has-error::after {
  content: "●";
  color: #e5484d;
  margin-left: 4px;
  font-size: 10px;
  line-height: 1;
  vertical-align: middle;
}

/* ═══════════════════════════════════════════════════════════════════════════
 *  ЕДИНАЯ ДИЗАЙН-СИСТЕМА (эталон — редизайн профиля): применяем к оверлеям
 *  поиска специалистов / компаний / клиентов (.cli-* / .dir-*) и к Работе v2
 *  (задачи/тикеты, .tw-* / .v2-*). Блок В КОНЦЕ + повышенная специфичность
 *  (⚠️ не писать звёздочку-слэш слитно в комментах — закрывает коммент раньше
 *  времени и «съедает» первое правило блока; было с ?v=125)
 *  (.cli-overlay …, #workspaceV2 …, .v2-drawer …) → перебивает и инжектируемые
 *  оверлей-стили, и базовые v2, БЕЗ правки их HTML/JS. Токены: см. :root + --accent.
 * ═══════════════════════════════════════════════════════════════════════════ */

/* — Поля ввода: единый радиус 11, ровные отступы, фокус-кольцо (как в профиле) — */
.cli-overlay .cli-input, .cli-overlay .cli-select, .cli-overlay .cli-search,
#workspaceV2 .v2-f input, #workspaceV2 .v2-f select, #workspaceV2 .v2-f textarea,
.v2-drawer .v2-cm-add input[type="text"], .v2-drawer .v2-d-val .tw-select,
.v2-drawer .v2-d-val input[type="date"] {
  border-radius: 11px; padding: 10px 13px;
  transition: border-color .15s, box-shadow .15s;
}
.cli-overlay .cli-input:focus, .cli-overlay .cli-select:focus, .cli-overlay .cli-search:focus,
#workspaceV2 .v2-f input:focus, #workspaceV2 .v2-f select:focus, #workspaceV2 .v2-f textarea:focus,
.v2-drawer .v2-cm-add input[type="text"]:focus, .v2-drawer .v2-d-val .tw-select:focus,
.v2-drawer .v2-d-val input[type="date"]:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow);
}

/* — Заголовки секций: индиго-акцент всем; линию-разделитель (как .rsm-head) вешаем
   ТОЛЬКО на одиночные заголовки деталей (dir-d-sec, v2-dr-section-h). .cli-sec/.v2-sec
   имеют двухчастную вёрстку (заголовок + кнопка) → им только цвет/жирность, БЕЗ ::after. */
.cli-overlay .cli-sec, .cli-overlay .dir-d-sec,
#workspaceV2 .v2-sec, .v2-drawer .v2-dr-section-h {
  font-weight: 700; letter-spacing: .05em; color: var(--primary-2);
}
.cli-overlay .dir-d-sec, .v2-drawer .v2-dr-section-h {
  display: flex; align-items: center; gap: 10px;
}
.cli-overlay .dir-d-sec::after, .v2-drawer .v2-dr-section-h::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}

/* Док-панель задачи/тикета (.task-info-panel, рядом с чатом) — её заголовки секций
   (.tip-sec .td-section-h: ПОСТАНОВЩИК/СОИСПОЛНИТЕЛИ/СТАТУС/…) НЕ попадали под #workspaceV2.
   Одиночные (иконка+текст, кнопки в соседнем .td-part-list) → индиго + линия. */
.task-info-panel .td-section-h {
  color: var(--primary-2); display: flex; align-items: center; gap: 10px;
}
.task-info-panel .td-section-h::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}

/* — Чипы: крупнее пилюли, градиент на активном (как .pr-emp.on) — */
.cli-overlay .dir-emp { border-radius: 8px; padding: 7px 14px; font-size: 13px; transition: all .15s; }
.cli-overlay .dir-emp:hover { border-color: var(--primary); color: var(--text); }
.cli-overlay .dir-emp.on { background: var(--acc-grad); border-color: transparent; color: #fff; }
.cli-overlay .dir-chip { border-radius: 8px; padding: 5px 11px; font-size: 12.5px; }
/* v2: активные статус-чипы — лёгкая рамка-свечение вместо плоского фона */
#workspaceV2 .v2-chip, .v2-drawer .v2-chip { border-radius: 6px; }

/* — Сегменты/табы: активный = фирменный градиент — */
.cli-overlay .cli-seg button { border-radius: 9px; padding: 7px 14px; transition: all .15s; }
.cli-overlay .cli-seg button.active { background: var(--acc-grad); border-color: transparent; color: #fff; }

/* — Кнопки: primary/add = градиент (были плоский --accent) — */
.cli-overlay .cli-add, .cli-overlay .cli-btn.primary { background: var(--acc-grad); border: 0; }
.cli-overlay .cli-add:hover, .cli-overlay .cli-btn.primary:hover { box-shadow: 0 6px 18px -6px var(--glow); }

/* — Ссылки/зарплата в каталоге: светлый акцент для читаемости — */
.cli-overlay .dir-link, .cli-overlay .dir-pay { color: var(--primary-2); }

/* — Карточки/строки: приятный ховер с подъёмом — */
.cli-overlay .cli-row { border-radius: 12px; transition: background .12s; }
.cli-overlay .cli-row:hover { background: var(--panel-2); }
#workspaceV2 .tw-card:hover, #workspaceV2 .v2-card:hover {
  box-shadow: 0 10px 24px -12px rgba(0,0,0,.65);
}

/* — Модалки оверлеев (создать компанию/клиента): поля тоже с фокус-кольцом — */
.cli-scrim .cli-input, .cli-scrim .cli-select { border-radius: 11px; padding: 10px 13px; }
.cli-scrim .cli-input:focus, .cli-scrim .cli-select:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow);
}
.cli-scrim .cli-btn.primary { background: var(--acc-grad); border: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
 *  ДИЗАЙН-СИСТЕМА — РАСШИРЕНИЕ (аудит 70 находок → корни). Легаси-namespace-классы
 *  запекли свой радиус/фокус/заливку выше базы → точечные оверрайды. НОВЫЕ страницы
 *  сюда добавлять НЕ НАДО — они наследуют базу (голые input/select/button + .field/.primary).
 * ─── Конвенция новых страниц: только токены (--panel/--line/--primary/--grad/--glow),
 *     поля = голые/.field (радиус-11+фокус-кольцо+шеврон даром), кнопки = .primary/.ghost/.danger,
 *     чипы radius 999px (активный=var(--grad)), заголовки секций = --primary-2 700 (+линия у одиночных),
 *     скрим модалок rgba(8,10,14,.72), радиус панели var(--radius). Фокус ВСЕГДА кольцо var(--glow).
 * ═══════════════════════════════════════════════════════════════════════════ */

/* §2A. Namespace-поля: радиус 11 + фокус-кольцо + шеврон (база их не достаёт по спецификe) */
.co-input, .co-sel, .cli-input, .cli-select, .cli-search,
.ev-row input, .ev-row textarea, .ev-row select, .pr-select,
.conv-search, .users-search, .gs-add-search, .chat-search-input,
.td-check-add input, .tip-check-add input, .tip-desc,
.tw-addcol-form input, .tw-addcol-form select,
.v2-modal .v2-f input, .v2-modal .v2-f select, .v2-modal .v2-f textarea, .tw-select {
  border-radius: 11px; transition: border-color .15s, box-shadow .15s;
}
.co-input:focus, .co-sel:focus, .cli-input:focus, .cli-select:focus, .cli-search:focus,
.ev-row input:focus, .ev-row textarea:focus, .ev-row select:focus, .pr-select:focus,
.conv-search:focus, .users-search:focus, .gs-add-search:focus, .chat-search-input:focus,
.td-check-add input:focus, .tip-check-add input:focus, .tip-desc:focus,
.v2-modal .v2-f input:focus, .v2-modal .v2-f select:focus, .v2-modal .v2-f textarea:focus, .tw-select:focus {
  outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow);
}
/* users-sort-select-no-chevron · сортировка окна «Пользователи» (#usersSort): шорткат `input, select,
   textarea { background }` («3.4 Поля ввода») и его :focus стирали шеврон; вес id держит его и на фокусе. */
.co-sel, .cli-select, .ev-row select, .pr-select, .tw-select, #usersSort, .lead-cfg-cat, .meet-tpl, .tw-addcol-form select, .v2-f select, #workspaceV2 .v2-f select, .cli-overlay .cli-select, .cli-scrim .cli-select { /* select-shorthand-chevron-2: правила этих селектов выше пишут сокращение background и padding — шеврон и место под него возвращаем здесь, после них */
  appearance: none; -webkit-appearance: none;
  background-image: var(--sel-chev);
  background-repeat: no-repeat; background-position: right 12px center; padding-right: 34px;
}
.chat-search-input { background: var(--panel-2); }
.sp-search { border: 1px solid var(--line); transition: border-color .15s, box-shadow .15s; }
.sp-search:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }

/* §2B. Заголовки секций (одиночные) → индиго + линия */
.task-detail-box .td-section-h, .co-permgroup, .pr-permgrp,
.search-section, .td-section-h {
  color: var(--primary-2); font-weight: 700; display: flex; align-items: center; gap: 10px;
}
.task-detail-box .td-section-h::after, .co-permgroup::after, .pr-permgrp::after,
.search-section::after, .td-section-h::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}
.tw-pop-label { color: var(--primary-2); font-weight: 700; }

/* §2C. Активные сегменты/чипы/primary-CTA → фирменный градиент; семантика → токены */
.mode-seg.active, .co-seg button.active, .pr-seg button.active,
.cli-seg button.active, .cli-add, .cli-btn.primary,
.dir-emp.on, .ev-chip.on, .ev-btn.primary,
.tasks-list .task-lens-btn.active, .call-msg-join {
  background: var(--acc-grad); border-color: transparent; color: #fff;
}
.mode-seg.active .mode-badge { color: var(--primary); }
.ev-chip, .tasks-list .task-chip { border-radius: 6px; }
.ev-btn.danger, #coDelRole { color: var(--danger); }
.mode-badge, .mode-seg .mode-badge { background: var(--danger-fill, var(--danger)); }
.dir-pay, .dir-link { color: var(--primary-2); }
.ev-parse .pchip { color: var(--primary-2); }
.notify-prompt-icon { background: var(--acc-grad); }  /* белый значок → заливка, не чернила (--grad) */

/* §2D. Скримы модалок → единый; радиус cli-modal → как панель */
.co-overlay, .cli-scrim, .cli-modal-scrim, .ev-overlay, .pr-ov { background: rgba(8,10,14,.72); }
.cli-modal { border-radius: var(--radius); }

/* SFU companion: бейдж «телефон подключён как микрофон+колонки» */
.gc-companion-badge{position:absolute;left:12px;bottom:64px;z-index:5;background:rgba(20,20,22,.82);color:#fff;font-size:12px;line-height:1;padding:7px 10px;border-radius:14px;pointer-events:none;box-shadow:0 2px 8px rgba(0,0,0,.35)}

/* ═══════════ Каталог компаний — hero-поиск + большие карточки (редизайн) ═══════════ */
.comp-body { display: flex; flex-direction: column; }
.comp-hero { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-bottom: 12px; }
.comp-search { flex: 1 1 320px; display: flex; align-items: center; gap: 10px; padding: 0 14px; height: 46px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; color: var(--muted);
  transition: border-color .12s, box-shadow .12s; }
.comp-search:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.comp-search svg { flex: 0 0 auto; color: var(--muted); }
.comp-search input { flex: 1; min-width: 0; background: transparent; border: 0; outline: 0; color: var(--text); font-size: 15px; }
.comp-search input::placeholder { color: var(--muted); }
.comp-seg { flex: 0 0 auto; }
.comp-filters { margin-bottom: 10px; }
.comp-count { color: var(--muted); font-size: 12.5px; margin: 2px 2px 10px; }

.comp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(272px, 1fr)); gap: 14px; padding-bottom: 12px; }
/* Заголовки секций «Мои компании» / «Где я сотрудник» (scope=mine) */
.comp-sec-title { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; color: var(--muted); margin: 16px 2px 8px; }
.comp-sec-title:first-child { margin-top: 4px; }
.comp-sec-n { font-weight: 600; color: var(--text-dim, #9aa4b2); background: var(--panel-2); border-radius: 8px; padding: 1px 8px; font-size: 12px; }
.comp-card { position: relative; background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; cursor: pointer;
  transition: transform .12s ease, border-color .12s, box-shadow .12s; }
.comp-card:hover { transform: translateY(-2px); border-color: var(--primary); box-shadow: 0 10px 26px rgba(0,0,0,.38); }
.cc-cover { height: 78px; background: var(--grad); }
.cc-logo { position: absolute; top: 52px; left: 16px; width: 50px; height: 50px; border-radius: 13px;
  overflow: hidden; border: 2px solid var(--panel); background: var(--panel-2); }
.cc-logo > * { width: 100% !important; height: 100% !important; border-radius: 0 !important; font-size: 18px !important; }
.cc-body { padding: 30px 16px 16px; }
.cc-title { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-weight: 700; font-size: 16px; color: var(--text); line-height: 1.25; }
.cc-verified { display: inline-flex; align-items: center; justify-content: center; width: 17px; height: 17px;
  border-radius: 50%; background: var(--acc-fill); color: #fff; font-size: 11px; font-weight: 700; }
.cc-chip { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 6px; white-space: nowrap; }
.cc-chip.hiring { background: rgba(34,197,94,.16); color: var(--ok-ink, var(--ok)); }
.cc-chip.draft { background: var(--panel-2); color: var(--muted); }
.cc-tag { margin-top: 6px; color: var(--muted); font-size: 13px; line-height: 1.42;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.cc-meta { margin-top: 8px; color: var(--text); opacity: .82; font-size: 12.5px; }
/* Численность «11-50 чел.» не рвётся: по дефису диапазона мета-строка переносилась как «11-» / «50 чел.» */
.cc-headcount { white-space: nowrap; }
.cc-foot { margin-top: 11px; display: flex; align-items: center; gap: 8px; font-size: 12.5px; flex-wrap: wrap; }
.cc-star { color: var(--urg-today); font-weight: 700; }
.cc-dim { color: var(--muted); }
.cc-sep { color: var(--line); }
@media (max-width: 560px) { .comp-grid { grid-template-columns: 1fr; } .comp-search { flex-basis: 100%; } }

/* ═══════════ Страница «Мои компании» (полноэкранная, каркас .tasks-workspace) ═══════════
   Владелец: «Давай полноценную» + «общий поиск и фильтр убрать, там же мои компании а не
   все». Поэтому здесь НЕТ hero-поиска и фильтров каталога — только две секции с карточками.
   Токены только из общей палитры → светлая и тёмная темы работают без отдельных правил. */
/* .primary — width:100%+margin-top (для форм). В шапке страницы это распирает кнопку,
   а иконка уезжает на строку выше → приводим к компактной инлайн-кнопке. */
.myc-add { display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  width: auto; margin-top: 0; flex: 0 0 auto; white-space: nowrap; padding: 8px 14px; font-size: 13px; }
.myc-add .ic { width: 16px; height: 16px; flex: 0 0 auto; }
#myCompaniesPage .tw-title { display: inline-flex; align-items: center; gap: 9px; min-width: 0; overflow: hidden; }
#myCompaniesPage .tw-title > span { overflow: hidden; text-overflow: ellipsis; }
#myCompaniesPage .tw-title .ic { width: 19px; height: 19px; flex: 0 0 auto; color: var(--muted); }
.myc-wrap { background: var(--bg); }
.myc-inner { max-width: 1160px; margin: 0 auto; padding: 22px 24px 48px; }

.myc-sec + .myc-sec { margin-top: 30px; }
.myc-sec-title { display: flex; align-items: center; gap: 9px; margin: 0 2px 12px;
  font-size: 15px; font-weight: 650; letter-spacing: -.01em; color: var(--text); }
.myc-sec-n { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 20px;
  padding: 0 7px; border-radius: 7px; background: var(--panel-2); border: 1px solid var(--line);
  color: var(--muted); font-size: 12px; font-weight: 600; }

/* min(304px,100%) + min-width:0 — иначе на узком экране минимальный размер трека
   (min-content карточки) распирает сетку шире контейнера и карточки уезжают за экран. */
.myc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(304px, 100%), 1fr)); gap: 16px; }
.myc-grid > .comp-card { min-width: 0; }

/* Карточка на странице: мягче, чем в каталоге (там жёсткая тень под тёмную тему). */
.myc-grid .comp-card { transition: transform .14s ease, border-color .14s ease, box-shadow .14s ease; }
.myc-grid .comp-card:hover { transform: translateY(-2px); border-color: var(--line-strong); box-shadow: var(--shadow-2); }
.myc-grid .comp-card:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* Плитка тянется по высоте ряда сетки (stretch), а полоса «Настройки · Сотрудники» стояла сразу
   под текстом — ниже висел пустой хвост тела (кадр «Мои компании»: ~68 px у коротких карточек).
   Колонка: тело забирает остаток, полоса уходит к низу; 13 px до неё держит предпоследний узел. */
.myc-grid .comp-card.cc-mine { display: flex; flex-direction: column; }
.myc-grid .comp-card.cc-mine > .cc-cover { flex: none; }
.myc-grid .comp-card.cc-mine > .cc-body { flex: 1 1 auto; display: flex; flex-direction: column; }
.myc-grid .comp-card.cc-mine > .cc-body > .cc-acts { margin-top: auto; }
.myc-grid .comp-card.cc-mine > .cc-body > :nth-last-child(2) { margin-bottom: 13px; }

/* Роль: владелец — акцентная плашка, сотрудник — нейтральная. */
.cc-role { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 6px; white-space: nowrap; letter-spacing: .01em; }
/* 🔴 CLIE-1585: «Владелец» — акцентные чернила на акцентном тинте. --primary-hi это ЦВЕТ
   НАВЕДЕНИЯ заливки (#0066cc), а не чернила: на тинте #cce3f9 он даёт 4.22:1 при AA 4.5. */
/* запасной тинт 16 %: --glow (33 %) в тёмном «Штиле» давал «Владелец» 4.1 */
.cc-role.own { background: var(--accent-tint, color-mix(in srgb, var(--primary) 16%, transparent)); color: var(--primary-2, var(--primary-hi, var(--primary))); border: 1px solid var(--line); }
.cc-role.emp { background: var(--panel-2); color: var(--muted); border: 1px solid var(--line); }

/* Быстрые действия прямо на карточке — «Настройки» / «Сотрудники». */
.cc-acts { display: flex; align-items: center; gap: 8px; margin: 13px -16px -16px; padding: 10px 14px;
  border-top: 1px solid var(--line); background: var(--panel-2); }
.cc-act { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; border-radius: 8px;
  background: transparent; border: 1px solid transparent; color: var(--muted); font-size: 12.5px; font-weight: 550;
  cursor: pointer; transition: background .12s, color .12s, border-color .12s; }
.cc-act svg, .cc-act .ic { width: 15px; height: 15px; }
.cc-act:hover { background: var(--panel); border-color: var(--line); color: var(--text); }
.cc-act:active { background: var(--active); }
.cc-act:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

/* Пустое состояние — с понятным действием. */
.myc-blank { max-width: 420px; margin: 0 auto; padding: 84px 24px; text-align: center; }
.myc-blank-ic { width: 60px; height: 60px; margin: 0 auto 18px; border-radius: 17px;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--muted); }
.myc-blank-ic svg, .myc-blank-ic .ic { width: 27px; height: 27px; }
.myc-blank-t { font-size: 17px; font-weight: 650; letter-spacing: -.01em; color: var(--text); }
.myc-blank-s { margin-top: 7px; color: var(--muted); font-size: 13.5px; line-height: 1.5; }
.myc-blank-btn { width: auto; margin: 22px auto 0; display: inline-flex; align-items: center; justify-content: center;
  gap: 7px; padding: 9px 16px; font-size: 13px; }
.myc-blank-btn .ic { width: 16px; height: 16px; flex: 0 0 auto; }
.myc-retry { margin-top: 14px; }
.myc-retry button { width: auto; margin: 0 auto; display: inline-flex; }

@media (max-width: 860px) { .myc-inner { padding: 18px 16px 40px; } .myc-grid { gap: 13px; } }
@media (max-width: 560px) {
  .myc-grid { grid-template-columns: minmax(0, 1fr); }  /* НЕ 1fr: min-content распирает сетку */
  .myc-add { padding: 8px 10px; }        /* на узком — только «＋», подпись прячем */
  .myc-add span { display: none; }
  #myCompaniesPage .tw-count { display: none; }
  #myCompaniesPage .tw-head { gap: 8px; padding: 11px 12px; }
}

/* Рельс на узких сжимается до 62px (см. медиа выше), а полноэкранные страницы остаются
   отодвинутыми на 96px → между рельсом и страницей зияла полоса фона. Общая правка для
   всех страниц (Задачи/Проекты/События/Мои компании). */
@media (max-width: 720px) { .tasks-workspace { inset: 0 0 0 var(--rail-track); } }

/* ═══════════ Селектор активной компании в хедере (0028, справа от «Работа») ═══════════ */
.company-selector { display: inline-flex; align-items: center; }
.company-selector.hidden { display: none; }
.company-selector-btn {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 12px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px;
  color: var(--text); font-size: 13px; font-weight: 500; cursor: pointer;
  transition: border-color .12s, background .12s;
}
.company-selector-btn:hover { border-color: var(--primary); }
.company-selector-btn.active { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 14%, transparent); }
/* svg.ic, а не svg: глобальное `button svg.ic` (0,1,2) перебивало 15px, и портфель «Все» рисовался 22px рядом
   с 15px значком «Все проекты» (tasks-topbar-bare-1) */
.company-selector-btn svg.ic { width: 15px; height: 15px; opacity: .8; }
/* CLIE-621: выбранная компания носит в кнопке СВОЮ плитку (coAvatar) — 20px, чтобы кнопка
   осталась ростом 34px и не распирала шапку. Кольцо у плитки уже есть, второго не надо. */
.company-selector-btn .cli-avs { width: 20px; height: 20px; font-size: 9.5px; }
.company-selector-btn .csb-name { max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* стрелка — значок chevronDown (renderCompanySelector/renderProjScopeHdr), а не текстовый «▾» 11px */
.company-selector-btn .csb-caret { display: inline-flex; color: var(--muted); }
.company-selector-btn .csb-caret svg.ic { width: 14px; height: 14px; }
/* 🗂 CLIE-1842 · «Проекты» в шапке — пилюля той же формы, что компания слева от неё */
.proj-scope-hdr { display: inline-flex; align-items: center; margin-left: 8px; }
.proj-scope-hdr.hidden { display: none; }
.proj-scope-btn { cursor: pointer; }
.proj-scope-btn:active { cursor: grabbing; }
.proj-scope-btn .psh-ico { display: inline-flex; }
.proj-scope-btn .psh-ico svg { width: 15px; height: 15px; opacity: .8; }
.proj-scope-btn .psh-dots { display: inline-flex; align-items: center; }
.proj-scope-btn .psh-dot { width: 10px; height: 10px; border-radius: 50%; box-shadow: 0 0 0 2px var(--panel-2); }
.proj-scope-btn .psh-dots .psh-dot + .psh-dot { margin-left: -4px; }
.proj-scope-btn .psh-clear { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border-radius: 50%; color: var(--muted); margin-left: 2px; }
.proj-scope-btn .psh-clear:hover { background: var(--hover); color: var(--text); }
.proj-scope-btn .psh-clear svg { width: 12px; height: 12px; }
/* зона приёма в шапке, пока тянут заголовок столбика */
body.proj-dnd-to-hdr .proj-scope-hdr.hidden { display: inline-flex !important; } /* глобальный .hidden — !important */
body.proj-dnd-to-hdr .proj-scope-hdr:empty::before { content: "Проекты — сюда"; display: inline-flex; align-items: center; height: 34px; padding: 0 12px; box-sizing: border-box; border: 1.5px dashed var(--primary); border-radius: 10px; color: var(--primary); font-size: 13px; opacity: .72; transition: opacity .12s, background .12s; }
body.proj-dnd-to-hdr .topbar.proj-drop-over .proj-scope-hdr:empty::before { opacity: 1; background: color-mix(in srgb, var(--primary) 14%, transparent); }
/* ручка-заголовок столбика */
.projects-head .ph-drag { cursor: grab; display: inline-flex; align-items: center; gap: 6px; }
.projects-head .ph-drag:active { cursor: grabbing; }
.projects-head .ph-grip { width: 12px; height: 12px; opacity: .45; }
.projects-head .ph-drag:hover .ph-grip { opacity: .9; }
/* призрачный столбик-приёмник, пока тянут пилюлю из шапки */
@media (min-width: 1081px) {
  body.proj-dnd-to-col .chat.hide-projects { --rw-projects: 168px; }
  body.proj-dnd-to-col .chat.hide-projects #projectsCol { position: relative; overflow: visible; }
  body.proj-dnd-to-col .chat.hide-projects #projectsCol::after { content: "Столбик «Проекты» — отпустите здесь"; position: absolute; inset: 10px 8px; border: 1.5px dashed var(--primary); border-radius: 12px; display: flex; align-items: center; justify-content: center; text-align: center; padding: 12px; box-sizing: border-box; color: var(--primary); font-size: 13px; line-height: 1.3; opacity: .72; transition: opacity .12s, background .12s; }
  body.proj-dnd-to-col .chat.hide-projects.proj-drop-over #projectsCol::after { opacity: 1; background: color-mix(in srgb, var(--primary) 12%, transparent); }
}
/* настройки → «Столбцы»: место «Проектов» — сегмент */
.col-toggle.col-toggle-proj { justify-content: space-between; cursor: default; }
/* строка с подсказкой (it.hint): имя и подсказка — ДВУМЯ строками, не склейкой */
.tw-scope-row.two .tw-scope-name { display: flex; flex-direction: column; white-space: normal; }
.tw-scope-row.two .tw-scope-name > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-scope-row.two .tw-scope-hint { display: block; font-size: 11.5px; color: var(--muted); line-height: 1.25; margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ряд действий под списком пикера (openTwMultiPicker · actions) */
.tw-scope-acts { flex: none; display: flex; flex-direction: column; gap: 2px; padding-top: 6px; margin-top: 2px; border-top: 1px solid var(--line); }
.tw-scope-act { display: flex; align-items: center; gap: 9px; width: 100%; background: none; border: none; color: var(--text); text-align: left; padding: 8px 9px; border-radius: 8px; cursor: pointer; font-size: 13px; }
.tw-scope-act:hover { background: var(--panel); }
.tw-scope-act svg.ic { width: 15px; height: 15px; color: var(--muted); flex: none; }

/* CLIE-621 · «плитка компании» — ОПЦИЯ канонического аватара .cli-avs (cliAvatarSmall(…,{square}))
   а не второй компонент. Человек = кружок с заливкой, компания = скруглённый квадрат с мягкой
   подложкой и буквой цветом бренда: спокойно, читаемо в обеих темах, ч/б не разваливается.
   Цвет приходит инлайном в --av-c (taskAvatarColor), кольцо-хэйрлайн вместо жирной заливки.
   🔴 База = ТЁМНАЯ тема: у неё атрибута нет вовсе (index.html ставит data-theme только для
   светлой), поэтому селектор html[data-theme="dark"] не сработал бы никогда. */
.cli-avs.sq {
  /* 🔴 Скругление — ДОЛЯ стороны, а не прибитые 8px: тот же kAvatarSquareRatio = 0.3, что
     во Flutter (GAME-598, «число одно на продукт»). Плитка живёт в трёх размерах — 26px в
     поповере, 20px в кнопке шапки, 28px по базе — и с прибитым px они скруглены по-разному,
     то есть читаются как из разных приложений. Бокс всегда квадратный, поэтому % точен. */
  border-radius: 30%; font-weight: 700; letter-spacing: .01em;
  background-color: color-mix(in srgb, var(--av-c, var(--primary)) 34%, transparent);
  color: color-mix(in srgb, var(--av-c, var(--primary)) 45%, #fff);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--av-c, var(--primary)) 46%, transparent);
}
html[data-theme="light"] .cli-avs.sq {
  background-color: color-mix(in srgb, var(--av-c, var(--primary)) 15%, transparent);
  /* 🔴 CLIE-1585 · БУКВА ЧИТАЕТСЯ НА СВОЕЙ ЖЕ ПОДЛОЖКЕ. Было 82% цвета бренда — на 15%-й
     подложке это 3.2–3.4:1 при 14px, то есть ниже AA (замер прода 28.09, 4 плитки на экране
     «Сотрудники и роли»). Палитра плитки — `hsl(h 52% 46%)` для ЛЮБОГО оттенка, поэтому
     считали не «на глаз», а по всему кругу: при 60% худший случай (жёлтый, hue 60) даёт
     4.65:1 на панели и 4.99:1 на белом. Оттенок бренда сохраняется — буква просто темнее. */
  color: color-mix(in srgb, var(--av-c, var(--primary)) 60%, #000);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--av-c, var(--primary)) 24%, transparent);
}

.company-pop {
  position: fixed; z-index: 1000; min-width: 248px; max-width: min(320px, calc(100vw - 16px));
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 18px 44px rgba(0,0,0,.34), 0 2px 8px rgba(0,0,0,.14);
  padding: 6px; max-height: 60vh; overflow-y: auto;
}
.company-pop-item {
  display: flex; align-items: center; gap: 10px; padding: 5px 8px; border-radius: 10px;
  color: var(--text); font-size: 13.5px; cursor: pointer; min-height: 38px;
  transition: background .12s ease;
}
.company-pop-item:hover { background: var(--panel-2); }
.company-pop-item.sel { background: color-mix(in srgb, var(--primary) 13%, transparent); font-weight: 600; }
/* CLIE-621: ведущий глиф — ОДНА колонка 26px. Служебная иконка (16–18px) и плитка компании
   (26px) занимают одинаковое место, поэтому названия во ВСЕХ секциях идут по одной вертикали. */
.company-pop-item > svg { width: 18px; height: 18px; opacity: .6; flex: 0 0 auto; margin: 0 4px; }
.company-pop-item .cli-avs { width: 26px; height: 26px; font-size: 11.5px; }
.company-pop-item > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Шестерёнка — тихий спутник строки, а не шесть одинаковых пятен в столбик: приглушена,
   проявляется на наведении. Там, где наведения нет (тач), остаётся различимой. */
.company-pop-gear {
  margin-left: auto; background: transparent; border: 0; color: var(--muted); cursor: pointer;
  padding: 4px; border-radius: 8px; display: flex; opacity: .3;
  transition: opacity .12s ease, background .12s ease, color .12s ease;
}
.company-pop-item:hover .company-pop-gear, .company-pop-gear:focus-visible { opacity: 1; }
.company-pop-gear:hover { background: var(--panel-2); color: var(--text); }
.company-pop-gear svg { width: 15px; height: 15px; }
@media (hover: none) { .company-pop-gear { opacity: .55; } }
/* Drag-сортировка компаний в переключателе (эталон .v2-pc-row / .proj-item, светлая+тёмная). */
.company-pop-item[data-cid] { cursor: grab; }
.company-pop-item[data-cid]:active { cursor: grabbing; }
.company-pop.reordering { user-select: none; -webkit-user-select: none; }
.company-pop.reordering .company-pop-item[data-cid] { transition: transform .14s cubic-bezier(.2,.7,.3,1), background .12s, box-shadow .12s; }
.company-pop-item.dragging { opacity: .5; cursor: grabbing; box-shadow: 0 8px 22px rgba(0,0,0,.28); }
.company-pop-sep { height: 1px; background: var(--line); margin: 6px 4px; }
.company-pop-loading { padding: 8px 10px; }
/* 🔒 Запертое за неоплату пространство в переключателе (CLIE-882·2). Строка ОСТАЁТСЯ и
   остаётся ЧИТАЕМОЙ: замок значит «нужна оплата», а не «компанию удалили», — гасить её
   значило бы соврать ровно в ту сторону, в которую замок как раз НЕ работает.
   🔴 Метка — пилюля со ЗНАКОМ и СЛОВОМ «не оплачено», а не цветная кромка слева (CLIE-483)
   и не один только цвет. Подложка мягкая (color-mix) + хэйрлайн-кольцо; тон из --danger,
   поэтому обе темы выверены одной парой правил. */
.company-pop-item.co-locked { background: color-mix(in srgb, var(--danger) 8%, transparent); }
.company-pop-item.co-locked:hover { background: color-mix(in srgb, var(--danger) 15%, transparent); }
.co-lock {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 7px; border-radius: 999px;
  color: var(--danger); font-size: 11.5px; font-weight: 600; line-height: 1.5;
  background: color-mix(in srgb, var(--danger) 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 28%, transparent);
}
/* Замок здесь — часть ПИЛЮЛИ, а не ведущий глиф строки: 12px и полная непрозрачность,
   иначе он спорил бы с плиткой компании за левую колонку (канон CLIE-621). */
.co-lock svg { width: 12px; height: 12px; flex: 0 0 auto; opacity: 1; margin: 0; }
.co-lock-t { white-space: nowrap; }
html[data-theme="light"] .company-pop-item.co-locked { background: color-mix(in srgb, var(--danger) 7%, #fff); }
html[data-theme="light"] .company-pop-item.co-locked:hover { background: color-mix(in srgb, var(--danger) 12%, #fff); }

/* ── 🔗 превью ссылок в текстовых сообщениях (metadata.link_preview) ──
   карточка в стиле .reply-quote; кликабельные ссылки в тексте = .msg-link */
/* CLIE-483: рейку сняли — акцент названием сайта (.lp-site) и подложкой с тонким кольцом */
.link-preview {
  display: block; margin-top: 6px; padding: 6px 10px;
  border-radius: 8px;
  background: rgba(255,255,255,.06); max-width: 320px;
  text-decoration: none; color: inherit; overflow: hidden;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary-2) 22%, transparent);
}
.lp-site { display: block; font-size: 12px; font-weight: 600; color: var(--primary-2); }
.lp-title {
  display: block; font-size: 13px; font-weight: 600; line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.lp-desc {
  display: block; font-size: 12px; color: var(--muted);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.lp-img { display: block; width: 100%; max-height: 160px; object-fit: cover; border-radius: 6px; margin-top: 6px; }
/* 🔴 CLIE-887: длинное нажатие по ссылке — НАШЕ меню действий (Открыть · Копировать ·
   Сохранить · Поделиться). Нативную «выноску» iOS гасим у самой ссылки, иначе поверх
   нашего листа приезжает системное меню — раньше это правило стояло только у `.msg`,
   и вне ленты (вики, описание, ответ Помощника) человек получал чужое меню. */
.msg-link { color: var(--primary-2); text-decoration: underline; word-break: break-all; -webkit-touch-callout: none; }
/* 📇 CLIE-685 — СУЩНОСТЬ-КОНТАКТ в теле сообщения (телефон/почта). Тот же цвет, что у
   ссылки (это тоже «живой» элемент), но БЕЗ сплошного подчёркивания: номер и адрес
   человек читает как данные, а не как адрес перехода, — подчёркиваем пунктиром,
   как это делают почтовые клиенты и мессенджеры. Тап показывает быстрые действия. */
.msg-ent { text-decoration: none; border-bottom: 1px dashed currentColor; word-break: normal; cursor: pointer; }
.msg-ent[data-ent="tel"] { white-space: nowrap; }


/* ═══════════ Индикатор «идёт групповой созвон» ═══════════ */
@keyframes ccLivePulse { 0%,100% { box-shadow: 0 0 0 0 rgba(93,202,165,.55); } 70% { box-shadow: 0 0 0 6px rgba(93,202,165,0); } }
.conv-call-pill {
  display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto;
  padding: 2px 8px 2px 6px; border-radius: 6px;
  background: var(--urg-done-soft); color: var(--ok, var(--urg-done));
  font-size: 11px; font-weight: 700; line-height: 1.4; white-space: nowrap;
}
.conv-call-pill .ccp-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok, var(--urg-done)); animation: ccLivePulse 1.8s infinite; }
.thread-call-banner {
  display: flex; align-items: center; gap: 10px; padding: 8px 12px; margin: 0;
  background: rgba(93,202,165,.12); border-bottom: 1px solid rgba(93,202,165,.28);
  color: var(--text); font-size: 13px;
}
.thread-call-banner.hidden { display: none; }
.tip-scroll > .thread-call-banner { border-radius: 10px; border: 1px solid rgba(93,202,165,.28); margin-bottom: 10px; }
.thread-call-banner .tcb-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--ok, var(--urg-done)); flex: 0 0 auto; animation: ccLivePulse 1.8s infinite; }
.thread-call-banner .tcb-text { flex: 1 1 auto; font-weight: 600; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.thread-call-banner .tcb-join { flex: 0 0 auto; border: 0; cursor: pointer; color: #fff; background: var(--acc-grad); border-radius: 8px; padding: 6px 14px; font-size: 12.5px; font-weight: 700; }
.thread-call-banner .tcb-join:hover { filter: brightness(1.06); }
/* 🔁 Пилюля открытого звонка двоих: рядом с «Вернуться» — «Завершить» (тот же отбой, что красная кнопка). */
.thread-call-banner .tcb-end { flex: 0 0 auto; cursor: pointer; color: var(--text); background: transparent; border: 1px solid var(--line); border-radius: 8px; padding: 5px 12px; font-size: 12.5px; font-weight: 600; }
.thread-call-banner .tcb-end:hover { background: var(--panel-2, rgba(127,127,127,.12)); }

/* ======================================================================= *
 *  ЦЕНТР УВЕДОМЛЕНИЙ («колокольчик»)
 * ======================================================================= */
.notif-bell { position: relative; color: var(--muted); }
.notif-bell:hover, .notif-bell.active { color: var(--text); background: var(--panel-2); }
.notif-bell-ico { display: inline-flex; }
.notif-bell-ico .ic { width: 18px; height: 18px; }
.notif-badge {
  position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 9px; background: var(--danger-fill, var(--danger)); color: #fff;
  font-size: 10.5px; font-weight: 700; line-height: 18px; text-align: center;
  box-shadow: 0 0 0 2px var(--panel);
}
.notif-badge.dot { min-width: 9px; width: 9px; height: 9px; padding: 0; border-radius: 50%; top: -1px; right: -1px; background: var(--acc-fill); }

/* Хост — позиционированный слой, в нём живёт хваталка ресайза (шов на левой кромке).
   Ширина панели — ДЕФОЛТНАЯ, её тянет мышью общий механизм окон (WIN_PANES → #notifPanel):
   правило продукта «ни одной прибитой ширины». До CLIE-473 ширина стояла числом в JS. */
.notif-host { position: fixed; z-index: 95; }
.notif-host.hidden { display: none; }
.notif-panel {
  /* 520, а не 420: вкладок стало шесть, и на 420 две последние («Сохранённые», «Архив»)
     физически не помещались — полоса прокручивалась, а её скроллбар скрыт CSS, то есть
     вкладка была, но её НЕ БЫЛО ВИДНО (замерено на стенде: нужно 458px, доступно 318).
     560 берёт с запасом на счётчик у «Инцидентов». Число не «прибитое»: это дефолт,
     ширину тянут мышью и она запоминается (WIN_PANES → #notifPanel). */
  width: 560px; max-width: calc(100vw - 16px);
  max-height: min(74vh, 660px); display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 24px 60px -16px rgba(0,0,0,.72), 0 2px 8px rgba(0,0,0,.28); overflow: hidden;
  animation: ccPopIn var(--dur-2) var(--ease-spring);
}
.notif-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 12px 10px; }
.notif-tabs { display: flex; gap: 4px; flex: 1 1 auto; overflow-x: auto; scrollbar-width: none; }
.notif-tabs::-webkit-scrollbar { display: none; }
.notif-tab {
  border: 0; background: transparent; color: var(--muted); cursor: pointer;
  padding: 6px 12px; border-radius: 8px; font-size: 13px; font-weight: 600; white-space: nowrap;
  transition: background .12s, color .12s;
}
/* Счётчик НА ВКЛАДКЕ («Инциденты · 3»): человек видит, что там что-то есть, ещё до
   переключения. Тонкая пилюля в тон акценту — не «красный крик»: он уже есть на самом
   колокольчике, второй такой же рядом читался бы как две разные тревоги. */
.notif-tab-cnt {
  display: inline-flex; align-items: center; justify-content: center; margin-left: 6px;
  min-width: 16px; height: 16px; padding: 0 5px; border-radius: 8px;
  background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger);
  font-size: 10.5px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
  vertical-align: middle;
}
.notif-tab-cnt.hidden { display: none; }
.notif-tab:hover { color: var(--text); }
.notif-tab.active { background: color-mix(in srgb, var(--primary) 20%, var(--panel-2)); color: var(--text); }
/* Плотнее общего таб-компонента (CLIE-249): у него `padding: 9px 12px 11px` рассчитан на
   широкую страницу, а тут шесть вкладок в поповере. Селектор из двух классов — чтобы
   перебить алиас, не трогая канон (он общий на 10+ мест продукта). */
.notif-tabs .notif-tab { padding: 9px 8px 11px; gap: 5px; }
.notif-tabs .notif-tab.active::after { left: 6px; right: 6px; }
/* Полоса всё-таки не влезла (узкое окно, крупный масштаб интерфейса) — показываем это
   затуханием справа. Без него скрытый CSS-скроллбар делает лишние вкладки невидимыми,
   и человек не знает, что они есть (ровно так «Архив» и терялся). */
.notif-tabs.scrolls {
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
          mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
}
/* ✉️ CLIE-1153 · ВТОРАЯ СТРОКА вкладки «Почта» — фильтр по ящикам. Отдельного семейства
   контролов не заводим: это та же полоса `.notif-tabs` и те же пилюли `.notif-tab`, только
   рангом ниже (мельче кегль, приглушённый фон) — чтобы «вкладка» и «фильтр внутри вкладки»
   не читались как два равных ряда. Строки нет на других вкладках (прогрессивное раскрытие). */
/* Селекторы с `.notif-panel` НЕ для красоты: канон-алиас таб-компонента (блок CLIE-249
   ниже по файлу) перекрывает `.notif-tabs`/`.notif-tab` и лежит ПОЗЖЕ — при равной
   специфичности он бы съел и отступы полосы, и вид пилюли, и нарисовал бы им чернильное
   подчёркивание вкладки. */
.notif-panel .notif-boxes {
  padding: 2px 12px 10px; gap: 6px; border-bottom: 1px solid var(--line);
  margin-bottom: 2px; flex: 0 0 auto; align-items: center;
}
.notif-panel .notif-boxes.hidden { display: none; }
.notif-panel .notif-boxes .notif-box {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; line-height: 16px;
  background: var(--panel-2); color: var(--muted); max-width: 240px;
}
.notif-panel .notif-boxes .notif-box .notif-box-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notif-panel .notif-boxes .notif-box:hover { color: var(--text); }
.notif-panel .notif-boxes .notif-box.active {
  background: color-mix(in srgb, var(--primary) 20%, var(--panel-2));
  color: var(--text); font-weight: 650;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 34%, transparent);
}
/* Пилюля-фильтр — не вкладка: чернильного подчёркивания у неё нет (его рисует канон-алиас). */
.notif-panel .notif-boxes .notif-box.active::after { content: none; }
/* Непрочитанные письма ящика — тон почты (акцент), а не аварийный красный: красный в этой
   панели занят инцидентами, и второй такой же читался бы как вторая тревога. */
.notif-panel .notif-boxes .notif-tab-cnt.mail {
  margin-left: 0; background: color-mix(in srgb, var(--primary) 18%, transparent); color: var(--primary);
}
/* «Всего» у ящика без непрочитанных — бледное число, чтобы объём был виден, но не кричал. */
.notif-panel .notif-boxes .notif-box-n { font-size: 10.5px; font-weight: 700; color: var(--muted); opacity: .8; font-variant-numeric: tabular-nums; }
.notif-head-actions { display: flex; gap: 2px; flex: 0 0 auto; }
.notif-hbtn { display: inline-flex; align-items: center; justify-content: center; border: 0; background: transparent; color: var(--muted); cursor: pointer; width: 32px; height: 32px; border-radius: 9px; }
.notif-hbtn:hover { background: var(--panel-2); color: var(--text); }
.notif-hbtn .ic { width: 18px; height: 18px; }
/* 📭 CLIE-2016·2 · значок «только непрочитанные» включён — залит акцентом (состояние видно). */
.notif-hbtn.notif-unread-tg.on { background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--primary); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.notif-hbtn.notif-unread-tg.on:hover { background: color-mix(in srgb, var(--primary) 20%, transparent); color: var(--primary); }

.notif-list { overflow-y: auto; flex: 1 1 auto; padding: 4px 8px 8px; }
.notif-empty { display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center; padding: 46px 16px; color: var(--muted); font-size: 13px; }
.notif-empty-ic { display: inline-flex; width: 44px; height: 44px; border-radius: 50%; align-items: center; justify-content: center; background: var(--panel-2); color: var(--muted); }
.notif-empty-ic .ic { width: 20px; height: 20px; }

/* Переход «непрочитано → прочитано» — не рывком: фон тает, точка-акцент сжимается и гаснет,
   плашка иконки и заголовок приглушаются одной волной (160ms, длительность продублирована
   в app.js как NOTIF_READ_ANIM_MS — по ней ждём перед уходом на сущность). Работает только
   потому, что клиент красит строку НА МЕСТЕ (patchNotifReadRow), а не пересобирает ленту. */
.notif-item {
  position: relative; display: flex; gap: 12px; align-items: flex-start;
  padding: 11px 12px 11px 14px; border-radius: 12px; cursor: pointer;
  transition: background 160ms var(--ease);
}
.notif-item:hover { background: var(--panel-2); }
.notif-item.unread { background: color-mix(in srgb, var(--nc) 8%, transparent); }
.notif-item.unread:hover { background: color-mix(in srgb, var(--nc) 13%, transparent); }
/* CLIE-483: полосу 3×24 заменили круглой точкой 6px по центру строки */
.notif-accent {
  position: absolute; left: 5px; top: 50%; width: 6px; height: 6px;
  border-radius: 50%; background: var(--nc); opacity: 0;
  transform: translateY(-50%) scale(.4);
  transition: transform 160ms var(--ease), opacity 160ms var(--ease);
}
.notif-item.unread .notif-accent { opacity: 1; transform: translateY(-50%) scale(1); }

.notif-ico {
  flex: 0 0 auto; width: 38px; height: 38px; border-radius: 11px; display: flex; align-items: center;
  justify-content: center; background: color-mix(in srgb, var(--nc) 16%, transparent); color: var(--nc);
  transition: background-color 160ms var(--ease), color 160ms var(--ease);
}
/* прочитанное живёт тише: та же палитра категории, но приглушённая — строка не исчезает,
   а «отходит на второй план» (одинаково читается в светлой и тёмной теме) */
.notif-item:not(.unread) .notif-ico {
  background: color-mix(in srgb, var(--nc) 9%, transparent);
  color: color-mix(in srgb, var(--nc) 60%, var(--muted));
}
.notif-item:not(.unread) .notif-reason { color: color-mix(in srgb, var(--nc) 62%, var(--muted)); }
.notif-ico .ic { width: 19px; height: 19px; }

.notif-main { flex: 1 1 auto; min-width: 0; padding-top: 1px; }
.notif-row1 { display: flex; align-items: center; gap: 8px; font-size: 11.5px; margin-bottom: 2px; }
.notif-reason { font-weight: 600; color: var(--nc); letter-spacing: .1px; flex: 0 0 auto; }
/* 🏷️ Проект инцидента — вторым голосом после причины: точка-разделитель вместо рамки-чипа
   (одна лишняя плашка в плотной строке ленты читается как кнопка). Сжимается первым и
   обрезается многоточием: длинное «Е7 Керчь, Горького 3Ж (АЗК АТАН)» не имеет права
   вытолкнуть время. Цвет — та же приглушённая шкала, что у прочитанной причины, поэтому
   светлая и тёмная темы совпадают без отдельного правила. */
.notif-src { min-width: 0; flex: 0 1 auto; margin-left: -2px; color: var(--muted); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.notif-src::before { content: "·"; margin-right: 6px; opacity: .7; }
.notif-item.unread .notif-src { color: color-mix(in srgb, var(--text) 62%, var(--muted)); }
.notif-time { margin-left: auto; flex: 0 0 auto; font-size: 11px; color: var(--muted); }
.notif-count { flex: 0 0 auto; min-width: 17px; height: 17px; padding: 0 5px; border-radius: 9px; background: color-mix(in srgb, var(--nc) 24%, transparent); color: var(--nc); font-size: 10.5px; font-weight: 700; line-height: 17px; text-align: center; }
/* 🔴 CLIE-1946 · светлая: --nc — цвет КАТЕГОРИИ (задаёт app.js), чернилами тёмной темы. На своём
   светлом тинте он давал 2.0–3.4:1 (янтарь «Запрос ИИ» — 2.02). Чернила = тот же тон, углублённый к
   чёрному: причина 60 %, счётчик на плотном тинте 50 % — ≥ 4.5:1 у всех категорий. Прочитанная
   строка — та же приглушённая шкала поверх углублённых чернил; кусок ИИ (.ai-self) не трогаем. */
html[data-theme="light"] .notif-reason { color: color-mix(in srgb, var(--nc) 60%, #000); }
html[data-theme="light"] .notif-item:not(.unread, .ai-self) .notif-reason { color: color-mix(in srgb, color-mix(in srgb, var(--nc) 60%, #000) 62%, var(--muted)); }
html[data-theme="light"] .notif-count { color: color-mix(in srgb, var(--nc) 50%, #000); }
.notif-title { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: color 160ms var(--ease); }
.notif-item.unread .notif-title { font-weight: 700; }
/* вес шрифта анимировать нечем — гасим ЦВЕТОМ, он и несёт переход глазу */
.notif-item:not(.unread) .notif-title { color: color-mix(in srgb, var(--text) 74%, var(--muted)); }
.notif-reason { transition: color 160ms var(--ease); }
.notif-body { font-size: 12.5px; color: var(--muted); margin-top: 2px; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* тень из токена — иначе в светлой теме поповер лежал под чёрной кляксой .45 */
.notif-acts { position: absolute; right: 8px; top: 8px; display: none; gap: 2px; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 3px; box-shadow: var(--shadow-2); }
.notif-item:hover .notif-acts { display: flex; }
.notif-act { display: inline-flex; align-items: center; justify-content: center; border: 0; background: transparent; color: var(--muted); cursor: pointer; width: 28px; height: 28px; border-radius: 8px; }
.notif-act:hover { background: var(--panel-2); color: var(--text); }
.notif-act .ic { width: 16px; height: 16px; }
.notif-act.on, .notif-act.on:hover { color: var(--primary); }

.notif-foot { border-top: 1px solid var(--line); padding: 8px; text-align: center; }
.notif-clear { border: 0; background: transparent; color: var(--muted); cursor: pointer; font-size: 12.5px; font-weight: 500; padding: 7px 14px; border-radius: 9px; }
.notif-clear:hover { background: var(--panel-2); color: var(--text); }

.notif-snooze-menu { position: fixed; z-index: 97; background: var(--panel); border: 1px solid var(--line); border-radius: 12px; padding: 5px; box-shadow: 0 16px 36px rgba(0,0,0,.55); display: flex; flex-direction: column; min-width: 190px; }
.notif-snooze-menu button { border: 0; background: transparent; color: var(--text); text-align: left; padding: 10px 12px; border-radius: 8px; font-size: 13px; cursor: pointer; }
.notif-snooze-menu button:hover { background: var(--panel-2); }

.notif-settings { border-top: 1px solid var(--line); padding: 12px 14px; max-height: 46vh; overflow-y: auto; }
.notif-set-title { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; color: var(--muted); margin: 8px 0 6px; }
.notif-set-row { display: flex; align-items: center; gap: 8px; padding: 7px 0; font-size: 13px; color: var(--text); }
.notif-set-row span:first-child { flex: 1 1 auto; }
.notif-set-row input[type="time"] { background: var(--panel-2); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 4px 7px; }
.notif-set-foot { margin-top: 14px; }
/* Открытые настройки скрывают ленту/футер и занимают панель целиком (скроллятся) —
   иначе панель настроек наезжала на список уведомлений и была непригодна. */
.notif-panel.settings-open .notif-list,
.notif-panel.settings-open .notif-foot { display: none; }
.notif-panel.settings-open .notif-settings { flex: 1 1 auto; max-height: none; }
/* ══ 🔔 CLIE-941 · ГЛАВНАЯ ГАЛКА «ВСЕ УВЕДОМЛЕНИЯ» + плашка «выключено» ══════════════
   Строка мастера крупнее соседей: это единственный контрол, ради которого сюда заходят
   срочно («выключи всё сейчас»). Погашенное состояние подкрашено — видно с одного взгляда. */
.ntf-all-row { padding: 10px 0; border-bottom: 1px solid var(--line); }
.ntf-all-row .ndar-lbl { font-weight: 650; font-size: 14px; }
.ntf-all-row .ndar-sub { font-weight: 400; }
.ntf-all-row.off .ndar-lbl { color: var(--danger); }
/* Плашка в самом центре уведомлений: пустая лента без объяснения читается как «сломалось». */
.notif-offbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 8px 12px 0; padding: 9px 11px; border-radius: 10px;
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent);
}
.notif-offbar-t { flex: 1 1 auto; font-size: 12.5px; line-height: 1.35; color: var(--text); }
.notif-offbar-btn {
  flex: 0 0 auto; min-width: max-content; padding: 5px 11px; border-radius: 8px;
  border: 0; background: var(--acc-fill); color: #fff; font-size: 12.5px; font-weight: 600; cursor: pointer;
}
.notif-offbar-btn:hover { filter: brightness(1.06); }
/* Перечёркнутый колокольчик — состояние видно там, где его встретят (СРЕД-31·2). */
.notif-bell.bell-off .notif-bell-ico { opacity: .75; }
.notif-bell.bell-off::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 22px; height: 2px;
  background: var(--danger); border-radius: 2px; transform: translate(-50%, -50%) rotate(-45deg);
  pointer-events: none;
}
.notif-set-note { font-size: 12.5px; line-height: 1.4; color: var(--muted); padding: 2px 0 10px; }
.notif-set-note.warn { color: var(--danger); }
.notif-enable-row { display: flex; align-items: center; gap: 10px; padding: 2px 0 10px; }
.notif-enable-row .notif-enable-status { flex: 1 1 auto; font-size: 12.5px; line-height: 1.4; color: var(--text); }
#notifEnableBtn { display: flex; align-items: center; justify-content: center; gap: 8px; }

/* Триплет «Важное · Обычное · Выкл» на категорию — сегмент-контрол в стиле macOS.
   Одна реализация: и в узком поповере колокольчика, и в широкой панели настроек. */
.notif-cat-row { gap: 12px; }
.notif-cat-row > span:first-child { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* CLIE-505: геометрия и дорожка — из канона .cc-seg + .cc-seg-sm. Здесь остаётся
   ТОЛЬКО смысловая раскраска выбранного (она несёт значение, а не «свой дизайн»). */
/* «Важное» — янтарный акцент (как категория ИИ #f59e0b); «Выкл» — приглушённый. */
.notif-seg-btn[data-level="important"].on { color: #b45309; background: color-mix(in srgb, #f59e0b 20%, var(--panel));
  box-shadow: 0 1px 2px rgba(0,0,0,.14), 0 0 0 .5px color-mix(in srgb, #f59e0b 45%, transparent); }
.notif-seg-btn[data-level="off"].on { color: var(--muted); background: var(--panel); }
html[data-theme="light"] .notif-seg-btn[data-level="important"].on { color: #92400e; }

/* 🚨 «Звонки при оповещениях» (prefs.alerts) — тот же словарь, что у категорий (.notif-seg),
   но подписи длиннее: сегмент уезжает на СВОЮ строку и тянется на всю ширину. Так блок
   одинаково читается и в узком поповере колокольчика, и в широкой панели настроек. */
.notif-alerts .notif-alert-row { flex-direction: column; align-items: stretch; gap: 8px; padding-bottom: 4px; }
.notif-alerts .notif-alert-row > span:first-child { flex: 0 0 auto; font-weight: 600; }
.notif-alerts .notif-alert-row .notif-seg { width: 100%; }
/* СРЕД-33: `min-width: 0` тут возвращал ровно то, что вылечено в каноне, — кнопка
   «Только важные» становилась уже своей подписи, и текст лез на соседнюю. Не влезло —
   ужмёт `ccSegFit` (ступень .tight), а не молчаливое налезание. */
.notif-alerts .notif-alert-row .notif-seg-btn { flex: 1 1 0; text-align: center; }
/* Активный сегмент звонка — акцент опасности (звонок будит человека, это не «обычное»). */
.notif-alerts .notif-seg-btn[data-alcall="always"].on,
.notif-alerts .notif-seg-btn[data-alcall="critical"].on { color: var(--danger);
  background: color-mix(in srgb, var(--danger) 14%, var(--panel));
  box-shadow: 0 1px 2px rgba(0,0,0,.14), 0 0 0 .5px color-mix(in srgb, var(--danger) 42%, transparent); }
.notif-alerts .notif-seg-btn[data-alcall="never"].on { color: var(--muted); background: var(--panel); }

/* ─────────── 🔔 Keyword-алерты: чипы-слова + лента срабатываний (Apple-grade) ─────────── */
.tc-pop-head { padding: 6px 9px 4px; font-size: 11.5px; font-weight: 600; letter-spacing: .02em;
  text-transform: uppercase; color: var(--muted); }
.kw-input-row { display: flex; gap: 8px; align-items: center; padding: 6px 0 2px; }
.kw-input { flex: 1 1 auto; min-width: 0; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 9px; color: var(--text); padding: 7px 10px; font-size: 13px; outline: none;
  transition: border-color .14s ease, box-shadow .14s ease; }
.kw-input:focus { border-color: color-mix(in srgb, var(--primary) 55%, var(--line));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent); }
.kw-chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 0 2px; }
.kw-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 6px 3px 10px;
  background: color-mix(in srgb, var(--primary) 12%, var(--panel-2)); color: var(--text);
  border: 1px solid color-mix(in srgb, var(--primary) 24%, var(--line));
  border-radius: 999px; font-size: 12.5px; line-height: 1.5; }
.kw-chip-t { max-width: 180px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kw-chip-x { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px;
  padding: 0; border: 0; background: transparent; color: var(--muted); cursor: pointer; border-radius: 50%;
  transition: color .12s ease, background .12s ease; }
.kw-chip-x:hover { color: var(--text); background: color-mix(in srgb, var(--text) 12%, transparent); }
.kw-chip-x .ic, .kw-chip-x svg { width: 12px; height: 12px; }
.kw-empty { font-size: 12.5px; }
.kw-hits { display: flex; flex-direction: column; gap: 2px; margin-top: 10px; }
.kw-hits-title { font-size: 11.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .02em;
  padding: 2px 0 4px; }
.kw-hit { display: flex; align-items: baseline; gap: 8px; width: 100%; text-align: left; cursor: pointer;
  background: none; border: 0; border-radius: 8px; padding: 7px 8px; color: var(--text);
  transition: background .12s ease; }
.kw-hit:hover { background: var(--hover); }
.kw-hit-kw { flex: none; font-weight: 600; font-size: 12px; color: #b45309;
  background: color-mix(in srgb, #f59e0b 18%, transparent); padding: 1px 7px; border-radius: 6px; }
html[data-theme="light"] .kw-hit-kw { color: #92400e; }
.kw-hit-snip { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12.5px; color: var(--muted); }
.kw-hit-when { flex: none; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.conv-mode-at { font-weight: 700; font-size: 12px; color: var(--muted); }

@media (max-width: 560px) {
  .notif-host { left: 8px; right: 8px !important; }
  .notif-panel { width: auto !important; max-width: none; max-height: 80vh; }
}

/* ───────────────── 🌅 «Мой день» — чек-лист на сегодня (шапка) ─────────────────
   Фон/рамку/тень задаёт семейство поповеров (§3.8) — здесь только геометрия и состояния,
   иначе тема «поплывёт» при следующей правке токенов. Ширина панели — ДЕФОЛТНАЯ, её тянет
   мышью общий механизм окон (WIN_PANES → #todayPanel), поэтому число тут не «прибитое».
   Хост — позиционированный слой: в нём живёт хваталка шва, панель прижата вправо к кнопке. */
.tdy-host { position: fixed; z-index: 95; }
.tdy-host.hidden { display: none; }
.today-panel {
  width: 420px; max-width: calc(100vw - 16px);
  max-height: min(74vh, 660px);
  display: flex; flex-direction: column; border-radius: 16px; overflow: hidden;
  animation: ccPopIn var(--dur-2) var(--ease-spring);
}
.today-btn { position: relative; color: var(--muted); }
.today-btn:hover, .today-btn.active { color: var(--text); background: var(--panel-2); }
.today-btn-ico { display: inline-flex; }
.today-btn-ico .ic { width: 18px; height: 18px; }
/* Осталось — акцентом (а не тревожно-красным: это план, а не авария); всё закрыто — зелёная точка. */
/* 🔴 счётчик — БЕЛЫМ ПО ЗАЛИВКЕ: берём --acc-fill (тёмная 3.21 → 4.85) */
.today-badge { background: var(--acc-fill); }
.today-badge.tdy-ok { background: var(--ok); }

.tdy-head { display: flex; align-items: center; gap: 12px; padding: 14px 14px 10px; }
.tdy-ringwrap { position: relative; flex: none; width: 40px; height: 40px; display: grid; place-items: center; }
.tdy-ring { position: absolute; inset: 0; width: 40px; height: 40px; transform: rotate(-90deg); }
.tdy-ring-tr { fill: none; stroke: var(--line); stroke-width: 3; }
.tdy-ring-pr {
  fill: none; stroke: var(--primary); stroke-width: 3; stroke-linecap: round;
  transition: stroke-dashoffset .5s cubic-bezier(.5,.05,.2,1);
}
.tdy-ring-t { position: relative; font-size: 12px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.tdy-ring-s { color: var(--muted); font-weight: 600; }
.tdy-ttl { flex: 1 1 auto; min-width: 0; }
.tdy-h1 { font-size: 15px; font-weight: 700; color: var(--text); letter-spacing: -0.01em; }
.tdy-h2 { font-size: 12px; color: var(--muted); margin-top: 1px; }
.tdy-hbtn {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: transparent; color: var(--muted); cursor: pointer;
  width: 30px; height: 30px; border-radius: 9px; padding: 0;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.tdy-hbtn:hover { background: var(--panel-2); color: var(--text); }
.tdy-hbtn .ic { width: 16px; height: 16px; }

.tdy-body { flex: 1 1 auto; overflow-y: auto; padding: 2px 8px 8px; }
.tdy-hint { padding: 4px 6px 8px; font-size: 12px; color: var(--muted); }
.tdy-sec + .tdy-sec { margin-top: 10px; }
.tdy-sec-h {
  display: flex; align-items: center; gap: 7px; padding: 5px 6px;
  font-size: 12px; font-weight: 700; color: var(--muted); letter-spacing: .01em;
  border-radius: 8px; user-select: none;
}
.tdy-sec-h[data-tact] { cursor: pointer; }
.tdy-sec-h[data-tact]:hover { background: var(--hover); color: var(--text); }
.tdy-sec-i { display: inline-flex; }
.tdy-sec-i .ic { width: 14px; height: 14px; }
.tdy-sec-l { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tdy-sec-n {
  flex: none; min-width: 18px; padding: 0 5px; border-radius: 9px; text-align: center;
  background: var(--panel-2); color: var(--muted); font-size: 10.5px; line-height: 17px;
}
.tdy-caret { display: inline-flex; color: var(--muted); transition: transform var(--dur-1) var(--ease); }
.tdy-caret .ic { width: 14px; height: 14px; }
.tdy-sec.folded .tdy-caret { transform: rotate(-90deg); }
.tdy-sec-act {
  margin-left: auto; flex: none; border: 0; background: transparent; cursor: pointer;
  color: var(--primary); font-size: 11.5px; font-weight: 600; padding: 3px 6px; border-radius: 7px;
}
.tdy-sec-act:hover { background: var(--sel); }
/* 🗺 0487: значок и слово — ОДНОЙ строкой (иначе значок встаёт над «Маршрут»). */
.tdy-sec-act { display: inline-flex; align-items: center; gap: 4px; white-space: nowrap; }
.tdy-sec-act .ic { width: 12px; height: 12px; flex: none; }

.tdy-list { display: flex; flex-direction: column; gap: 2px; }
.tdy-row {
  position: relative; display: flex; align-items: flex-start; gap: 8px;
  padding: 8px 8px 8px 6px; border-radius: 10px; cursor: pointer;
  transition: background var(--dur-1) var(--ease);
}
.tdy-row:hover { background: var(--hover); }
.tdy-row.done .tdy-t { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--line-strong); }
.tdy-grip {
  flex: none; display: inline-flex; align-items: center; align-self: center; margin: -2px -4px -2px -2px;
  color: var(--text-dim); opacity: 0; cursor: grab; touch-action: none;
  transition: opacity var(--dur-1) var(--ease);
}
.tdy-row:hover .tdy-grip { opacity: .65; }
.tdy-grip:active { cursor: grabbing; }
.tdy-grip .ic { width: 14px; height: 14px; }
@media (hover: none) { .tdy-grip { opacity: .5; } }
/* Подсказка — без ручки и чекбокса, но заголовок в ТОЙ ЖЕ колонке, что у моих строк. */
.tdy-lead { flex: none; width: 39px; }
.tdy-ck {
  flex: none; width: 19px; height: 19px; margin-top: 1px; padding: 0; border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--muted) 45%, var(--line-strong));
  background: transparent; color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease-spring);
}
.tdy-ck:hover { border-color: var(--primary); }
.tdy-ck:active { transform: scale(.9); }
.tdy-ck.on { background: var(--ok); border-color: var(--ok); }
.tdy-ck .ic { width: 12px; height: 12px; stroke-width: 3; }
.tdy-main { flex: 1 1 auto; min-width: 0; }
.tdy-t { font-size: 13.5px; line-height: 1.35; color: var(--text); word-break: break-word; }
.tdy-m { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 5px; }
/* 🔴 CLIE-579 «в задачах на сегодня не понятно, что происходит»: строка дня показывает ХОД
   РАБОТЫ теми же пилюлями, что карточка доски (одна реализация). Панель узкая — здесь только
   геометрия: длинная активность ИИ («ИИ работает: собираю образ») режется многоточием в ОДНУ
   строку, а не разваливает строку дня; полоса чек-листа чуть тоньше и ближе к тексту. */
.tdy-m .tw-pill { max-width: 100%; min-width: 0; }
.tdy-m .tw-pill > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* 🚐 0480 · выезд в строке «Моего дня»: время · адрес · ОДНА кнопка следующего шага. */
.tdy-visit { display: flex; align-items: center; gap: 6px; margin-top: 6px; min-width: 0; font-size: 12.5px; color: var(--text); }
.tdy-visit-i { flex: none; display: inline-flex; color: var(--accent); }
.tdy-visit-i svg { width: 14px; height: 14px; }
.tdy-visit-t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tdy-visit-t b { font-weight: 600; font-variant-numeric: tabular-nums; }
.tdy-visit-go { flex: none; padding: 4px 11px; border-radius: 999px; border: 0; background: var(--acc-fill); color: #fff; font-size: 12px; font-weight: 600; cursor: pointer; font-family: inherit; }
.tdy-visit-go:hover { filter: brightness(1.06); }
.tdy-visit-st { flex: none; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.tdy-visit.st-done .tdy-visit-st { color: var(--ok); }
.tdy-row .tw-card-ck { margin-top: 6px; }
.tdy-row .tw-ck-bar { height: 4px; }
.tdy-x, .tdy-plus {
  flex: none; width: 24px; height: 24px; padding: 0; border: 0; border-radius: 7px;
  background: transparent; color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; opacity: 0;
  transition: opacity var(--dur-1) var(--ease), background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.tdy-row:hover .tdy-x, .tdy-row:hover .tdy-plus { opacity: 1; }
.tdy-plus { opacity: .8; color: var(--primary); }
.tdy-x:hover { background: var(--danger-soft); color: var(--danger); }
.tdy-plus:hover { background: var(--sel); }
.tdy-x .ic, .tdy-plus .ic { width: 15px; height: 15px; }
@media (hover: none) { .tdy-x, .tdy-plus { opacity: 1; } }
/* Перетаскивание порядка дня — тот же вид, что у строк списка задач. */
.tdy-row.tdy-lift { background: var(--panel-2); box-shadow: var(--shadow-2); z-index: 2; }
.tdy-list.tdy-reordering .tdy-row { transition: transform 160ms var(--ease); }

.tdy-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 38px 20px 34px; }
.tdy-empty-ic {
  display: inline-flex; width: 44px; height: 44px; border-radius: 50%;
  align-items: center; justify-content: center; background: var(--panel-2); color: var(--primary);
}
.tdy-empty-ic .ic { width: 21px; height: 21px; }
.tdy-empty-t { font-size: 14px; font-weight: 650; color: var(--text); }
.tdy-empty-s { font-size: 12.5px; color: var(--muted); line-height: 1.45; max-width: 30ch; }

.tdy-foot { flex: none; border-top: 1px solid var(--line); padding: 8px; }
.tdy-newrow { padding: 2px 2px 8px; }
.tdy-newrow.hidden { display: none; }
.tdy-new-input {
  width: 100%; box-sizing: border-box; border: 1px solid var(--line-strong); border-radius: 10px;
  background: var(--panel-2); color: var(--text); font-size: 13.5px; padding: 9px 11px;
  transition: border-color var(--dur-1) var(--ease);
}
.tdy-new-input:focus { outline: none; border-color: var(--primary); }
.tdy-foot-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.tdy-fbtn {
  display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); border-radius: 9px;
  padding: 7px 11px; font-size: 12.5px; font-weight: 600; cursor: pointer;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.tdy-fbtn:hover { border-color: var(--primary); }
.tdy-fbtn.primary-ish { color: var(--primary); }
.tdy-fbtn .ic { width: 14px; height: 14px; }

/* ═══ «Мой день», ФАЗА 2 (0241): объём дня · слоты · док «Завтра» · ритуалы ═══════════
   Акценты — иконка + слово + мягкая подложка (без левых реек-акцентов, CLIE-483).
   Все размеры на 4/8-сетке, микроанимации 120–160мс, обе темы через токены. */

/* 📊 Полоса объёма дня. Честное предупреждение: цвет и цифра, НИКАКИХ запретов. */
.tdy-load { flex: none; padding: 0 14px 10px; }
.tdy-load.hidden { display: none; }
.tdy-loadbar {
  position: relative; height: 6px; border-radius: 999px; overflow: hidden;
  background: var(--line); margin-bottom: 6px;
}
.tdy-loadbar-fill { position: absolute; inset: 0 auto 0 0; border-radius: 999px; background: var(--primary); transition: width .16s var(--ease); }
.tdy-loadbar.over .tdy-loadbar-fill { background: var(--warning); }
/* Перегруз — тонкая штриховка поверх полосы: «через край», а не «ошибка». */
.tdy-loadbar-over {
  position: absolute; inset: 0; border-radius: 999px; opacity: .5;
  background: repeating-linear-gradient(135deg, transparent 0 4px, color-mix(in srgb, var(--warning) 55%, transparent) 4px 8px);
}
.tdy-load-t { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.tdy-load-m { display: inline-flex; align-items: center; gap: 5px; color: var(--text); font-weight: 600; }
.tdy-load-m.over { color: var(--warning); }
.tdy-load-m .ic { width: 13px; height: 13px; }
.tdy-load-x { color: var(--muted); }

/* 🌅🌙 Разделители времени суток — строки того же потока, что и задачи (drag-цель). */
.tdy-slot { display: flex; align-items: center; gap: 7px; padding: 9px 8px 3px; user-select: none; }
.tdy-slot-i { display: inline-flex; color: var(--muted); }
.tdy-slot-i .ic { width: 13px; height: 13px; }
.tdy-slot-l { font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
.tdy-slot-ln { flex: 1 1 auto; height: 1px; background: var(--line); }
/* Во время перетаскивания разделители подсвечиваются: видно, куда можно положить. */
.tdy-list.tdy-reordering .tdy-slot-l,
.tdy-list.tdy-reordering .tdy-slot-i { color: var(--primary); }
.tdy-list.tdy-reordering .tdy-slot-ln { background: color-mix(in srgb, var(--primary) 35%, var(--line)); }

/* ⬇️ Док «На завтра». В покое НЕ отбирает экран (высота 0), раскрывается на перетаскивании. */
.tdy-dock { height: 0; overflow: hidden; opacity: 0; transition: height .14s var(--ease), opacity .14s var(--ease); }
.tdy-list.tdy-reordering .tdy-dock { height: 40px; opacity: 1; margin-top: 4px; }
.tdy-dock-in {
  display: flex; align-items: center; justify-content: center; gap: 7px; height: 38px;
  border: 1px dashed var(--line-strong); border-radius: 10px; color: var(--muted);
  font-size: 12.5px; font-weight: 600; transition: border-color .14s var(--ease), background .14s var(--ease), color .14s var(--ease);
}
.tdy-dock-in .ic { width: 15px; height: 15px; }
.tdy-list.tdy-dock-hot .tdy-dock-in {
  border-color: var(--primary); color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}

/* 🌙 Полоса «разобрать день» над списком. */
.tdy-evening {
  display: flex; align-items: center; gap: 8px; margin: 2px 2px 8px; padding: 8px 10px;
  border-radius: 11px; font-size: 12.5px; color: var(--text);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}
.tdy-evening-i { display: inline-flex; color: var(--primary); }
.tdy-evening-i .ic { width: 15px; height: 15px; }
.tdy-evening-t { flex: 1 1 auto; min-width: 0; }

/* 🌅 Ритуалы (утренний сбор и вечерний разбор) — ОТДЕЛЬНОЕ состояние тела панели. */
.tdy-plan { padding: 6px 6px 10px; }
.tdy-plan-h { padding: 6px 6px 10px; }
.tdy-plan-t { font-size: 16px; font-weight: 700; letter-spacing: -.01em; color: var(--text); }
.tdy-plan-s { margin-top: 4px; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.tdy-plan-list { display: flex; flex-direction: column; gap: 2px; }
.tdy-pl-row, .tdy-rv-row {
  display: flex; align-items: flex-start; gap: 9px; padding: 7px 8px; border-radius: 10px;
  cursor: pointer; transition: background .12s var(--ease);
}
.tdy-pl-row:hover, .tdy-rv-row:hover { background: var(--hover); }
.tdy-pl-native { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.tdy-pl-ck {
  flex: none; width: 19px; height: 19px; margin-top: 1px; border-radius: 50%;
  border: 1.5px solid var(--line-strong); display: inline-flex; align-items: center; justify-content: center;
  color: #fff; transition: background .12s var(--ease), border-color .12s var(--ease);
}
.tdy-pl-ck.on { background: var(--primary); border-color: var(--primary); }
.tdy-pl-ck .ic { width: 12px; height: 12px; stroke-width: 3; }
.tdy-pl-main { flex: 1 1 auto; min-width: 0; }
.tdy-pl-t { display: block; font-size: 13.5px; line-height: 1.35; color: var(--text); word-break: break-word; }
.tdy-pl-m { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.tdy-pl-why, .tdy-pl-est {
  font-size: 11px; padding: 1px 7px; border-radius: 999px;
  background: var(--panel-2); color: var(--muted);
}
.tdy-pl-why.zomb { background: var(--warning-soft); color: var(--warning); }
.tdy-rv-sec { padding: 12px 8px 5px; font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
.tdy-rv-row.ok { cursor: default; }
.tdy-rv-row.ok .tdy-pl-t { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--line-strong); }
.tdy-rv-ok { flex: none; width: 19px; height: 19px; margin-top: 1px; border-radius: 50%; background: var(--ok); color: #fff; display: inline-flex; align-items: center; justify-content: center; }
.tdy-rv-ok .ic { width: 12px; height: 12px; stroke-width: 3; }
.tdy-plan-sum { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; padding: 12px 8px 4px; font-size: 12.5px; color: var(--muted); }
/* Разделитель «·» — именно разделитель, а не точка в конце фразы: приподнят и приглушён. */
.tdy-plan-sum .dot { opacity: .45; line-height: 1; transform: translateY(-1px); }
.tdy-plan-sum.over { color: var(--warning); }
.tdy-plan-warn { display: inline-flex; align-items: center; gap: 5px; color: var(--warning); }
.tdy-plan-warn .ic { width: 13px; height: 13px; }
.tdy-plan-acts { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 6px 2px; }
.tdy-fbtn.ghost { border-color: transparent; background: transparent; color: var(--muted); font-weight: 500; }
.tdy-fbtn.ghost:hover { background: var(--hover); border-color: transparent; color: var(--text); }

/* ⚙️ Настройки дня в поповере: строка = текст + канонический .cc-switch / счётчик. */
.tdy-pref { display: flex; align-items: center; gap: 12px; padding: 9px 9px; border-radius: 10px; cursor: pointer; }
.tdy-pref:hover { background: var(--hover); }
.tdy-pref.num { cursor: default; }
.tdy-pref-tx { flex: 1 1 auto; min-width: 0; }
.tdy-pref-t { display: block; font-size: 13px; color: var(--text); }
.tdy-pref-h { display: block; margin-top: 2px; font-size: 11.5px; line-height: 1.4; color: var(--muted); }
.tdy-num { flex: none; display: inline-flex; align-items: center; gap: 4px; }
.tdy-num b { min-width: 46px; text-align: center; font-size: 12.5px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.tdy-num-b {
  width: 26px; height: 26px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--panel); color: var(--text); display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; transition: border-color .12s var(--ease), background .12s var(--ease);
}
.tdy-num-b:hover { border-color: var(--primary); color: var(--primary); }
.tdy-num-b .ic { width: 13px; height: 13px; }

/* Пилюля «Сегодня» на карточке задачи + «третий день тащу» (анти-зомби) + чип в свойствах. */
/* 🔴 CLIE-1055·2 (хвост): «Сегодня» — акцентный ТЕКСТ на своём тинте (--sel), а не на белой
   карточке: --primary давал 3.99:1 на светлой. Канон contrast-runtime-audit: акцентный текст
   на подложке берёт --primary-2 (5.24:1). Тёмная — тот же класс: --primary на тинте давал 4.0
   (свип 19.10), --primary-2 там светлее. */
.tw-pill.tdy-pill { background: var(--sel); color: var(--primary-2); }
.tw-pill.tdy-zombie { background: var(--warning-soft); color: var(--warning); }
/* Анти-зомби 2.0: пилюля стала кнопкой — по ней открывается «что с этим сделать». */
button.tw-pill.tdy-zbtn { border: none; cursor: pointer; font: inherit; transition: box-shadow .12s var(--ease); }
button.tw-pill.tdy-zbtn:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 45%, transparent); }
.tip-chipbtn.tdy-chip-on { color: var(--primary); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); opacity: 1; cursor: default; }

@media (max-width: 560px) {
  .tdy-host { left: 8px; right: 8px !important; }
  .today-panel { width: auto !important; max-width: none; max-height: 80vh; }
}

/* ───────────────── Чек-лист-сообщения (Apple-grade: Reminders/Things) ─────────────────
   Карточка рисуется в .bubble.has-media (media:true) — без фона пузыря, поэтому одинакова
   у отправителя и получателя. Круглые чекбоксы, кольцо прогресса, аватар «кто отметил». */
.ck-card {
  min-width: 250px; max-width: 366px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 18px; padding: 14px 6px 8px; color: var(--text);
  box-shadow: 0 1px 2px rgba(0,0,0,.10), 0 10px 28px -16px rgba(0,0,0,.40);
  -webkit-user-select: none; user-select: none;
}
html[data-theme="light"] .ck-card { box-shadow: 0 1px 2px var(--cm-141e3c-05, rgba(20,30,60,.05)), 0 10px 26px -16px var(--cm-1e2d5a-18, rgba(30,45,90,.18)); }

/* header: заголовок + подзаголовок + кольцо прогресса */
.ck-head { display: flex; align-items: center; gap: 12px; padding: 2px 12px 12px 14px; }
.ck-head-txt { flex: 1 1 auto; min-width: 0; }
.ck-title { display: block; font-weight: 600; font-size: 16px; line-height: 1.25; letter-spacing: -.01em; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ck-sub { margin-top: 3px; display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 500; color: var(--muted); }
.ck-sub .ck-dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .5; }
.ck-sub .ck-done-word { display: inline-flex; align-items: center; gap: 4px; color: var(--ok); font-weight: 600; }
.ck-sub .ck-done-word svg { width: 13px; height: 13px; }
.ck-titlebtn { flex: 0 0 auto; width: 26px; height: 26px; border: 0; background: transparent; cursor: pointer; border-radius: 8px; color: var(--muted); display: grid; place-items: center; opacity: 0; transition: opacity .15s, background .15s, color .15s; }
.ck-titlebtn svg { width: 15px; height: 15px; }
.ck-card:hover .ck-titlebtn { opacity: .72; }
.ck-titlebtn:hover { opacity: 1; background: var(--panel-2); color: var(--text); }
/* кольцо прогресса (rotate только у самого кольца — не у чек-иконки внутри) */
.ck-ring { flex: 0 0 auto; width: 40px; height: 40px; position: relative; }
.ck-ring > svg { transform: rotate(-90deg); display: block; }
.ck-ring .ck-ring-track { fill: none; stroke: var(--line); stroke-width: 4.2; }
.ck-ring .ck-ring-prog { fill: none; stroke: url(#ckgrad); stroke-width: 4.2; stroke-linecap: round; transition: stroke-dashoffset .5s cubic-bezier(.5,.05,.2,1); }
.ck-ring.complete .ck-ring-prog { stroke: var(--ok); }
.ck-ring-num { position: absolute; inset: 0; display: grid; place-items: center; font-size: 11.5px; font-weight: 600; letter-spacing: -.02em; color: var(--text); }
.ck-ring.complete .ck-ring-num { color: var(--ok); }
.ck-ring.complete .ck-ring-num svg { width: 16px; height: 16px; }

/* список пунктов */
.ck-items { display: flex; flex-direction: column; }
.ck-empty { padding: 4px 14px 8px; font-size: 13px; color: var(--muted); }
/* 🔴 CLIE-1661 · ПУНКТ МОЖЕТ БЫТЬ МНОГОСТРОЧНЫМ: строка выравнивается ПО ВЕРХУ (кружок
   у ПЕРВОЙ строки, как в Reminders), текст переносится по-настоящему (pre-wrap). */
.ck-item { position: relative; display: flex; align-items: flex-start; gap: 12px; padding: 9px 12px 9px 14px; border-radius: 12px; transition: background .13s; }
.ck-item + .ck-item::before { content: ""; position: absolute; left: 48px; right: 12px; top: 0; height: 1px; background: var(--line); opacity: .7; }
.ck-item:hover { background: var(--panel-2); }
.ck-item:hover::before, .ck-item:hover + .ck-item::before { opacity: 0; }
/* круглый чекбокс */
.ck-box { flex: 0 0 auto; width: 22px; height: 22px; padding: 0; margin: 0; border: 0; background: transparent; cursor: pointer; display: grid; place-items: center; position: relative; -webkit-tap-highlight-color: transparent; }
.ck-box .ck-box-ring { width: 22px; height: 22px; box-sizing: border-box; border-radius: 50%; border: 2px solid var(--line); background: transparent; transition: border-color .18s, background .18s; }
.ck-box:hover .ck-box-ring { border-color: var(--accent); }
.ck-box .ck-box-tick { position: absolute; inset: 0; display: grid; place-items: center; color: #fff; opacity: 0; transform: scale(.4); transition: opacity .16s, transform .2s cubic-bezier(.34,1.56,.64,1); }
.ck-box .ck-box-tick svg { width: 13px; height: 13px; }
.ck-item.done .ck-box .ck-box-ring { background: var(--ok); border-color: var(--ok); }
.ck-item.done .ck-box .ck-box-tick { opacity: 1; transform: scale(1); }
.ck-box.just-checked .ck-box-ring { animation: ckpop .34s cubic-bezier(.34,1.56,.64,1); }
@keyframes ckpop { 0% { transform: scale(.6); } 55% { transform: scale(1.14); } 100% { transform: scale(1); } }
/* текст пункта */
.ck-text { flex: 1 1 auto; min-width: 0; font-size: 15px; line-height: 1.35; letter-spacing: -.006em; color: var(--text); word-break: break-word; white-space: pre-wrap; padding-top: 1px; transition: color .18s; }
.ck-item.done .ck-text { color: var(--muted); text-decoration: line-through; text-decoration-thickness: 1.4px; }
/* 🔴 Аватар «кто отметил» (CLIE-1667) — ЛЕСТНИЦА `avatar-fallback-face`: кружок строит
   общая дверь `ccAvatarFace`, поэтому здесь только размер и место. `position: relative` +
   `overflow: hidden` обязательны: слои `.cc-av-ini` (буквы) и `.cc-av-img` (фото) лежат
   `position:absolute; inset:0` и режутся по кругу родителем. `background-image` ЗАПРЕЩЁН. */
.ck-who { position: relative; overflow: hidden; margin-top: 1px; flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-size: 9.5px; font-weight: 600; color: #fff; box-shadow: 0 0 0 2px var(--panel); cursor: default; }
.ck-item:hover .ck-who { box-shadow: 0 0 0 2px var(--panel-2); }
/* контролы автора (правка/удаление пункта) — оверлеем справа на hover: НЕ занимают
   место в потоке (иначе скрытые кнопки съедают ширину текста и он переносится). */
.ck-actions { position: absolute; right: 6px; top: 0; bottom: 0; display: flex; align-items: center; gap: 2px; padding-left: 18px; opacity: 0; transform: translateX(6px); pointer-events: none; transition: opacity .14s, transform .14s; background: linear-gradient(90deg, transparent, var(--panel-2) 34%); }
.ck-item:hover .ck-actions { opacity: 1; transform: none; pointer-events: auto; }
.ck-ic { width: 28px; height: 28px; border: 0; background: transparent; cursor: pointer; border-radius: 8px; color: var(--muted); display: grid; place-items: center; transition: background .13s, color .13s; }
.ck-ic svg { width: 15px; height: 15px; }
.ck-ic:hover { background: var(--panel); color: var(--text); }
.ck-ic.ck-del:hover { color: #ef4444; }
html[data-theme="light"] .ck-ic:hover { background: #fff; }
/* инлайн-правка (span → input) */
.ck-inline-edit { flex: 1 1 auto; width: 100%; min-width: 0; box-sizing: border-box; background: var(--bg); border: 1px solid var(--accent); border-radius: 8px; color: var(--text); font-size: 15px; padding: 4px 8px; outline: none; }
/* Правка пункта — textarea: переносит строку и растёт под текст (Shift+Enter — перенос,
   Enter — сохранить). Однострочный input уезжал текстом вбок, и конец был не виден. */
/* 🔴 CLIE-620: ПИКСЕЛЬНОГО потолка у поля НЕТ намеренно — пункт короткий (500 знаков),
   он умещается целиком, а скроллит ЛЕНТА сообщений. Кап здесь означал бы вложенный
   бегунок ровно там, где человек жаловался, что не видит конца набранного. */
.ck-inline-edit.ck-inline-multi { font-family: inherit; line-height: 1.35; resize: none; overflow-y: auto; min-height: 26px; }
/* строка добавления пункта (автор) */
.ck-add { position: relative; display: flex; align-items: flex-start; gap: 12px; padding: 8px 12px 6px 14px; margin-top: 3px; }
.ck-add::before { content: ""; position: absolute; left: 14px; right: 12px; top: 0; height: 1px; background: var(--line); opacity: .7; }
.ck-add-ring { margin-top: 4px; flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; border: 1.6px dashed var(--muted); display: grid; place-items: center; color: var(--muted); }
.ck-add-ring svg { width: 13px; height: 13px; }
/* Поле «Новый пункт…» — textarea: переносит строку и растёт под текст (высоту и каретку
   ведёт общая дверь ccGrowField). Потолок и ВИДИМЫЙ скролл — как у композера чата. */
.ck-add-input { flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent; font-size: 15px; line-height: 1.35; color: var(--text); padding: 5px 0; font-family: inherit; resize: none; overflow-y: auto; min-height: 26px; }
.ck-add-input::placeholder { color: var(--muted); opacity: .9; }
.ck-add-btn { margin-top: 1px; flex: 0 0 auto; height: 30px; padding: 0 14px; border: 0; border-radius: 9px; background: var(--acc-grad); color: #fff; cursor: pointer; font-size: 13px; font-weight: 600; display: inline-flex; align-items: center; gap: 5px; box-shadow: 0 2px 8px -3px var(--glow); opacity: .55; transition: opacity .15s, transform .1s; }
.ck-add-btn svg { width: 14px; height: 14px; }
.ck-add:focus-within .ck-add-btn { opacity: 1; }
.ck-add-btn:active { transform: scale(.96); }

/* 👥 CLIE-1661 · КТО ПРАВИТ ПУНКТЫ — строка в карточке (видит АВТОР) и форма выбора,
   ОДНА на композер и на шторку прав. Размерный класс ряда — общий (канон `control-size`):
   сегмент берёт `.cc-seg .cc-seg-sm`, своей дорожки с пилюлей здесь нет. */
.ck-access { display: flex; align-items: center; gap: 8px; width: calc(100% - 26px); margin: 2px 13px 2px; padding: 7px 9px; border: 0; border-radius: 10px; background: transparent; color: var(--muted); font-size: 12.5px; cursor: pointer; text-align: left; transition: background .13s, color .13s; }
.ck-access svg { width: 14px; height: 14px; flex: 0 0 auto; }
.ck-access span { min-width: 0; }
.ck-access b { font-weight: 600; color: var(--text); }
.ck-access .ck-access-go { margin-left: auto; flex: 0 0 auto; color: var(--accent); font-weight: 600; opacity: 0; transition: opacity .14s; }
.ck-access:hover { background: var(--panel-2); color: var(--text); }
.ck-access:hover .ck-access-go { opacity: 1; }
html[data-theme="light"] .ck-access:hover { background: #f4f6fb; }

.ck-cmp-acc { padding: 2px 22px 2px; }
.ck-acc-ctl { display: flex; flex-direction: column; gap: 8px; padding: 10px 0 2px; border-top: 1px solid var(--line); }
.ck-acc-lb { display: flex; align-items: center; gap: 7px; font-size: 12.5px; font-weight: 600; color: var(--muted); }
.ck-acc-lb svg { width: 14px; height: 14px; }
.ck-acc-seg { width: 100%; }
.ck-acc-seg button { flex: 1 1 0; min-width: 0; }
.ck-acc-hint { font-size: 12px; line-height: 1.4; color: var(--muted); }
.ck-acc-pick { display: flex; align-items: center; gap: 8px; width: 100%; min-height: var(--ctl-h, 34px); padding: 5px 10px; border: 1px solid var(--line); border-radius: var(--ctl-r, 10px); background: var(--panel-2); color: var(--text); font-size: 13px; cursor: pointer; text-align: left; }
.ck-acc-pick:hover { border-color: var(--accent); }
.ck-acc-chips { display: flex; flex-wrap: wrap; gap: 5px; min-width: 0; }
.ck-acc-chip { display: inline-block; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 2px 8px; border-radius: 999px; background: color-mix(in srgb, var(--primary, var(--cm-667eea, #667eea)) 16%, transparent); color: var(--primary-2, var(--accent)); font-size: 12px; font-weight: 600; }
.ck-acc-empty { color: var(--muted); }
/* 🔴 У карточки `user-select:none` (чтобы длинный тап не выделял пузырь) — но в ПОЛЯХ
   ввода выделение обязано работать: иначе в textarea нельзя ни выделить, ни поправить
   середину набранного пункта. */
.ck-card .ck-add-input, .ck-card .ck-inline-edit { -webkit-user-select: text; user-select: text; }
.ck-acc-go { margin-left: auto; flex: 0 0 auto; color: var(--accent); font-weight: 600; font-size: 12.5px; }
.ck-acc-sheet .ck-acc-body { padding: 4px 22px 10px; }
.ck-acc-sheet .ck-acc-ctl { border-top: 0; }
/* 🔴 Пикер людей лежит на z-index 80, а композер и шторка прав — на 1000: без своего слоя
   выбор открылся бы ПОД ними, и это ровно «нажал — ничего» (глоб. правило №8). */
.td-userpick.ck-up-top { z-index: 1200; }

/* Диалог создания чек-листа (Apple-sheet) */
.ck-composer-ov { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center; padding: 16px; background: radial-gradient(120% 90% at 50% -10%, color-mix(in srgb, var(--primary) 16%, transparent), transparent 60%), rgba(6,8,12,.55); backdrop-filter: blur(2px); }
/* 📊 0424 · ОПРОС В ПЕРЕПИСКЕ. Одежда САМОЙ карточки живёт в ccroom.css (`.gcx-poll`,
   `.gcx-opt`) — она ОДНА на комнату созвона и на чат, второй копии тут нет и не будет.
   Здесь только рама пузыря (ширина, чтобы карточка не растягивалась на всю ленту) и два
   переключателя композера. */
/* 🔴🔴 МЕСТО ПЕРЕОПРЕДЕЛЯЕТ ТОЛЬКО ПАЛИТРУ (правило одного опроса, 0424). Вёрстка и
   арифметика карточки одни на продукт — `CcRoom.pollHtml` в `ccroom.css`; разница переписки
   и созвона ровно в чернилах. Найдено РЕНДЕРОМ 30.09.2026: без этого блока вопрос и варианты
   в СВЕТЛОЙ теме были почти невидимы — карточка несла цвета тёмного стекла созвона на
   светлом пузыре. Берём РОЛИ темы (канон `theme-contrast-runtime`), а не свои цвета:
   роль знает обе темы, прибитый цвет не знает ни одной. */
.poll-card { width: min(360px, 76vw); }
.poll-card .gcx-poll { margin: 0; }
.poll-card {
  --gcp-ink: var(--text);
  --gcp-opt-ink: var(--text);
  --gcp-num: var(--muted);
  --gcp-opt-bg: var(--panel-2);
  --gcp-opt-bg-h: var(--panel);
  --gcp-opt-bd: var(--line);
  --gcp-opt-bd-h: var(--primary);
}
.poll-card .gcx-meta { color: var(--muted); }
.pl-rules { display: flex; flex-wrap: wrap; gap: 14px; padding: 4px 18px 2px; }
.pl-rule { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--muted); cursor: pointer; }
.pl-rule input { accent-color: var(--primary); width: 15px; height: 15px; }

html[data-theme="light"] .ck-composer-ov { background: radial-gradient(120% 90% at 50% -10%, color-mix(in srgb, var(--primary) 14%, transparent), transparent 60%), var(--cm-182038-38, rgba(24,32,56,.38)); }
.ck-composer { width: 100%; max-width: 400px; max-height: 86vh; overflow-y: auto; background: var(--panel); border: 1px solid var(--line); border-radius: 20px; color: var(--text); box-shadow: 0 24px 60px -20px rgba(0,0,0,.6), 0 4px 14px rgba(0,0,0,.25); }
html[data-theme="light"] .ck-composer { box-shadow: 0 26px 60px -22px var(--cm-1e2d5a-4, rgba(30,45,90,.4)), 0 3px 12px var(--cm-1e2d5a-14, rgba(30,45,90,.14)); }
.ck-cmp-head { padding: 20px 22px 14px; }
.ck-cmp-kicker { display: flex; align-items: center; gap: 6px; margin-bottom: 9px; font-size: 11px; font-weight: 600; letter-spacing: .11em; text-transform: uppercase; color: var(--accent); }
.ck-cmp-kicker svg { width: 14px; height: 14px; }
.ck-cmp-title-in { width: 100%; box-sizing: border-box; border: 0; outline: 0; background: transparent; font-size: 22px; font-weight: 600; letter-spacing: -.02em; color: var(--text); padding: 0; }
.ck-cmp-title-in::placeholder { color: var(--muted); opacity: .7; }
.ck-cmp-body { padding: 4px 14px 6px; }
.ck-cmp-row { display: flex; align-items: center; gap: 12px; padding: 6px 8px; border-radius: 12px; transition: background .12s; }
.ck-cmp-row:hover { background: var(--panel-2); }
.ck-cmp-pre { flex: 0 0 auto; width: 22px; height: 22px; box-sizing: border-box; border-radius: 50%; border: 2px solid var(--line); }
.ck-cmp-input { flex: 1 1 auto; min-width: 0; border: 0; outline: 0; background: transparent; font-size: 15.5px; line-height: 1.35; color: var(--text); padding: 6px 0; }
.ck-cmp-input::placeholder { color: var(--muted); opacity: .75; }
.ck-cmp-x { flex: 0 0 auto; width: 26px; height: 26px; border: 0; background: transparent; cursor: pointer; border-radius: 7px; color: var(--muted); display: grid; place-items: center; opacity: 0; transition: opacity .13s, background .13s, color .13s; }
.ck-cmp-x svg { width: 15px; height: 15px; }
.ck-cmp-row:hover .ck-cmp-x { opacity: .7; }
.ck-cmp-x:hover { opacity: 1; color: #ef4444; background: var(--panel); }
html[data-theme="light"] .ck-cmp-x:hover { background: #fff; }
.ck-cmp-ghost { display: flex; align-items: center; gap: 12px; width: 100%; padding: 8px; margin: 2px 0 4px; border: 0; border-radius: 12px; background: transparent; color: var(--accent); cursor: pointer; font-size: 15px; font-weight: 600; letter-spacing: -.01em; text-align: left; transition: background .12s; }
.ck-cmp-ghost:hover { background: var(--panel-2); }
.ck-cmp-ghost .ck-g-ring { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; border: 1.6px dashed var(--accent); display: grid; place-items: center; }
.ck-cmp-ghost .ck-g-ring svg { width: 13px; height: 13px; }
.ck-cmp-foot { display: flex; align-items: center; gap: 10px; justify-content: flex-end; padding: 14px 18px 18px; border-top: 1px solid var(--line); }
.ck-cmp-count { margin-right: auto; font-size: 12.5px; font-weight: 500; color: var(--muted); }
.ck-btn { height: 38px; padding: 0 18px; border: 0; border-radius: 11px; cursor: pointer; font-size: 14px; font-weight: 600; letter-spacing: -.005em; transition: transform .1s, background .13s, filter .13s; }
.ck-btn:active { transform: scale(.97); }
.ck-btn.ghost { background: var(--panel-2); color: var(--text); }
.ck-btn.ghost:hover { background: var(--line); }
.ck-btn.primary { display: inline-flex; align-items: center; gap: 6px; background: var(--acc-grad); color: #fff; box-shadow: 0 4px 14px -4px var(--glow); }
.ck-btn.primary:hover { filter: brightness(1.05); }
.ck-btn.primary svg { width: 15px; height: 15px; }

@media (prefers-reduced-motion: reduce) {
  .ck-ring .ck-ring-prog, .ck-box .ck-box-tick, .ck-box .ck-box-ring { transition: none; }
  .ck-box.just-checked .ck-box-ring { animation: none; }
}

/* ══════ Новая задача (Apple-grade создание): строка + чипы + Подробнее ══════ */

/* ══════════════════ 🎁 ОТКРЫТКИ (CLIE-683) ═══════════════════════════════════
   Открытка — ПРЕДМЕТ, а не поверхность интерфейса: её бумага, чернила, печать и
   градиент лица приходят из серверного шаблона переменными --cp/--ci/--ca/--cs/--ce/
   --cg1/--cg2 и ОДИНАКОВЫ в светлой и тёмной темах. Под тему подстраивается только
   обрамление — сцена, тени, рама конструктора. Это тот же канон «бумажных токенов»,
   что у листа документа: перекрасить подарок под тему значит превратить его в строку
   списка. */

/* ── Конверт в ленте (.bubble.has-media → своя рама, одинаково у обеих сторон) ── */
.card-env {
  display: flex; align-items: center; gap: 13px;
  min-width: 250px; max-width: 340px; text-align: left;
  padding: 12px 16px 12px 12px; border-radius: 18px; cursor: pointer;
  /* 🔴 СВЕТЛАЯ ПОДЛОЖКА ПОД ГРАДИЕНТОМ (CLIE-683·8, владелец: «тёмное на тёмном, ничего
     не прочитать»). Текст плашки — ЧЕРНИЛА ОТКРЫТКИ (--ci, тёмные по построению), и это
     верно, пока под ними светлая бумага. Но бумага рисовалась ТОЛЬКО градиентом
     (`background-image`): не прокрасился он — и чернила оказывались на тёмном холсте
     приложения, где их не видно. `background-color` держит светлый фон независимо от
     градиента: контраст больше не зависит от того, доехали ли переменные шаблона.
     🔴 В цвет ИНТЕРФЕЙСА текст не уводить: это уже делали, и в тёмной теме вышло БЕЛОЕ
     ПО СВЕТЛОМУ (см. комментарий у .cev-txt ниже). Фон и текст — из одной палитры. */
  /* 🔴 ЛИТЕРАЛЬНЫЙ цвет, а НЕ var(): `background-color: var(--cg1, …)` спасает только от
     ОТСУТСТВИЯ переменной. Если она объявлена, но невалидна (пустая строка, мусор из
     шаблона), `var()` отдаёт «гарантированно недопустимое значение», объявление
     ОТБРАСЫВАЕТСЯ целиком — и плашка снова прозрачная, то есть тёмная. Литерал не может
     быть отброшен ничем: светлая бумага под чернилами есть ВСЕГДА. */
  background-color: #ffeef0;
  background-image: linear-gradient(140deg, var(--cg1, #ffe7c2), var(--cg2, #ffc7d8));
  border: 1px solid rgba(0, 0, 0, .07);
  box-shadow: 0 1px 2px rgba(0,0,0,.10), 0 12px 30px -18px rgba(0,0,0,.45);
  transition: transform var(--dur-1, 120ms) var(--ease), box-shadow var(--dur-2, 200ms) var(--ease);
  -webkit-user-select: none; user-select: none;
}
/* 🔴🔴 НАВЕДЕНИЕ НЕ СМЕЕТ ЗАБИРАТЬ У ОТКРЫТКИ ЕЁ БУМАГУ (CLIE-683·8, жалоба владельца:
   «при наведении тёмное на тёмном, ничего не прочитать»).
   Конверт — это `<button>`, а в базе есть общее `button:hover { background: var(--active) }`
   (style.css ниже). Специфичность (0,1,1) ПЕРЕБИВАЕТ `.card-env` (0,1,0), и это ШОРТКАТ:
   он сносит разом и `background-color`, и `background-image`. В тёмной теме `--active` —
   полупрозрачное белое ≈ 8%, то есть плашка становится почти холстом чата, а чернила
   открытки (#463A35 у «бабушки и дедушки») дают контраст ≈1.2:1.
   🔴 Почему это пережило три моих замера: я мерил ПОКОЙ. Синтетические события мыши
   `:hover` не включают, поэтому прибор честно показывал 9:1 и молчал о беде, на которую
   человек показывал пальцем. Наведение теперь снимается по-настоящему —
   `node tools/uishot.js --hover ".card-env"`.
   Лечим ФОНОМ, а не цветом текста: одним цветом два взаимоисключающих фона (светлая
   бумага в покое, тёмный --active под курсором) закрыть нельзя — этим и объясняется
   прошлая попытка «увёл текст в цвет интерфейса», давшая белое по светлому. */
.card-env:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 4px rgba(0,0,0,.12), 0 18px 40px -18px rgba(0,0,0,.5);
  background-color: #fff5f6;
  background-image: linear-gradient(140deg, var(--cg1, #ffe7c2), var(--cg2, #ffc7d8));
}
.card-env:active { transform: translateY(0) scale(.994); }

.cev-paper { position: relative; flex: 0 0 auto; width: 78px; height: 56px; }
.cev-back {
  position: absolute; inset: 0; border-radius: 7px;
  background: var(--ce, #f7dcc0);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.08), 0 2px 6px rgba(0,0,0,.14);
}
/* Письмо, выглядывающее из конверта: у ОТКРЫТОГО поднимается — состояние видно сразу. */
.cev-letter {
  position: absolute; left: 9px; right: 9px; top: 8px; height: 34px; border-radius: 3px;
  background: var(--cp, #fffbf3);
  box-shadow: 0 1px 3px rgba(0,0,0,.16);
  transform: translateY(6px); opacity: 0;
  transition: transform var(--dur-3, 260ms) var(--ease), opacity var(--dur-2, 200ms) var(--ease);
}
.card-env.is-open .cev-letter { transform: translateY(-7px); opacity: 1; }
/* Клапан — треугольник поверх; у открытого отогнут вверх. */
.cev-flap {
  position: absolute; left: 0; right: 0; top: 0; height: 36px;
  background: color-mix(in srgb, var(--ce, #f7dcc0) 88%, #000 6%);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  transform-origin: top center;
  transition: transform var(--dur-3, 260ms) var(--ease);
}
.card-env.is-open .cev-flap { transform: rotateX(168deg); }
.cev-seal {
  position: absolute; left: 50%; top: 52%; transform: translate(-50%, -50%);
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  font-size: 13px; line-height: 1;
  background: var(--cs, #d9603a);
  box-shadow: 0 1px 3px rgba(0,0,0,.3), inset 0 -1px 2px rgba(0,0,0,.18);
}
.card-env.is-open .cev-seal { opacity: .55; }

.cev-txt { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
/* 🔴 ТЕКСТ И ФОН — ИЗ ОДНОЙ ПАЛИТРЫ. Плашка конверта залита ПАСТЕЛЬНЫМ ГРАДИЕНТОМ
   ОТКРЫТКИ (--cg1/--cg2, всегда светлым), поэтому подпись обязана быть её же чернилами
   (--ci, тёмными по построению). Я разово увёл подпись в цвет интерфейса — и в тёмной
   теме получилось БЕЛОЕ ПО СВЕТЛОМУ, читать нечем. Правило: берёшь фон из палитры
   сущности — бери оттуда же и текст, иначе контраст держится на совпадении тем. */
.cev-txt b {
  font-size: 15px; font-weight: 650; line-height: 1.25; letter-spacing: -.01em;
  color: var(--ci, #3e3228);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
/* 🔴 ПОДПИСЬ КОНВЕРТА НЕ ОБРЕЗАЕТСЯ ПОСРЕДИ СЛОВА (CLIE-683·8, скрин владельца:
   «Вы бабушка и дедушка! · посмотрет…»). Строка стояла `nowrap` + `ellipsis` в коробке
   219px при содержимом 285px — то есть обрезалась ВСЕГДА, при любом празднике: одно
   только «· нажмите, чтобы открыть» съедает половину. Отрезанный призыв к действию
   бессмысленен — человек не понимает, что с конвертом делать.
   Даём вторую строку (как у заголовка) и клипаем по СТРОКЕ, а не по букве. */
.cev-txt i {
  font-style: normal; font-size: 12px; font-weight: 550; letter-spacing: .01em;
  color: color-mix(in srgb, var(--ci, #3e3228) 72%, transparent);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

/* ── Холст частиц: ОДИН движок (CcFx) на продукт ─────────────────────────────── */
.ccfx-cv { position: absolute; inset: 0; pointer-events: none; z-index: 2; }

/* ── Сцена вскрытия ──────────────────────────────────────────────────────────── */
.card-scene {
  position: fixed; inset: 0; z-index: 9720;
  display: grid; place-items: center; padding: 20px;
  background: var(--scrim, var(--cm-080a10-6, rgba(8,10,16,.6)));
  -webkit-backdrop-filter: blur(18px) saturate(1.1); backdrop-filter: blur(18px) saturate(1.1);
  opacity: 0; transition: opacity var(--dur-2, 200ms) var(--ease);
}
.card-scene.in { opacity: 1; }
.card-scene .cs-fx { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
/* Та же беда, что у `.cm-x`: без сброса padding круглая кнопка центрирует глиф в
   остатке от padding, а не в круге (CLIE-683·8). */
.card-scene .cs-x {
  position: absolute; top: 14px; right: 16px; z-index: 4;
  width: 40px; height: 40px; padding: 0; border-radius: 50%; border: 0; cursor: pointer;
  color: #fff; background: rgba(255,255,255,.16); display: grid; place-items: center;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.card-scene .cs-x:hover { background: rgba(255,255,255,.26); }
.card-scene .cs-x svg, .card-scene .cs-x svg.ic { width: 20px; height: 20px; display: block; }
/* 🔴🔴 CLIE-917: СЕЛЕКТОР СЦЕНЫ ОБЯЗАН БЫТЬ ЗАПЕРТ В СВОЕЙ СЦЕНЕ.
   Класс `.cs-hint` в продукте ЗАНЯТ — это подпись под заголовком в блоках настроек
   (`.cs-block`/`.cs-h`/`.cs-hint`, стили инжектит csEnsureStyles в app.js), и таких
   подсказок 24 штуки: настройки компании, «Лиды», движок лидов, дисциплина воронки.
   Пока правило стояло БЕЗ рамы, оно накрывало их ВСЕ: `position:absolute; bottom:22px;
   left:0; right:0; text-align:center` — и каждая подсказка настроек уезжала в самый низ
   ближайшего позиционированного предка, ВСЕ В ОДНУ ТОЧКУ, поверх друг друга. Ровно это
   владелец прислал скрином 05.09 («внизу вёрстка полетела в тексте, наложение»).
   Инжект из app.js побеждал только по ЦВЕТУ/КЕГЛЮ (он объявлен позже) — `position` он не
   объявляет вовсе, поэтому раскладку продолжала решать эта строка. Сломалось 31.08
   (4274de7c, открытки CLIE-683), прожило 5 дней.
   Правило класса: у сцены/оверлея свой префикс И своя рама в селекторе; общий короткий
   класс без рамы = чужая вёрстка ломается молча и не там, где её правили. */
.card-scene .cs-hint {
  position: absolute; left: 0; right: 0; bottom: 22px; text-align: center;
  font-size: 12.5px; font-weight: 550; color: rgba(255,255,255,.62); pointer-events: none;
  animation: ccFade var(--dur-3, 260ms) var(--ease);
}

.cs-stage {
  position: relative; z-index: 3; width: min(420px, 92vw);
  display: grid; justify-items: center; perspective: 1200px;
}

/* Конверт-герой: живёт до вылета письма, потом уезжает вниз. */
.cs-env {
  position: relative; width: min(300px, 78vw); height: min(210px, 55vw);
  transform-style: preserve-3d;
  transition: transform 620ms var(--ease), opacity 420ms var(--ease);
}
.cse-back {
  position: absolute; inset: 0; border-radius: 14px;
  background: var(--ce, #f7dcc0);
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.09), 0 24px 60px -22px rgba(0,0,0,.6);
}
.cse-flap {
  position: absolute; left: 0; right: 0; top: 0; height: 62%;
  background: color-mix(in srgb, var(--ce, #f7dcc0) 90%, #000 7%);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
  transform-origin: top center; transform: rotateX(0deg);
  transition: transform 640ms cubic-bezier(.3, .9, .25, 1.1);
  border-radius: 14px 14px 0 0;
}
.cse-seal {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center;
  font-size: 25px; line-height: 1; background: var(--cs, #d9603a);
  box-shadow: 0 3px 10px rgba(0,0,0,.35), inset 0 -2px 4px rgba(0,0,0,.2);
  transition: transform 300ms var(--ease), opacity 300ms var(--ease);
}
.card-scene.s1 .cse-flap { transform: rotateX(-168deg); }
.card-scene.s1 .cse-seal { transform: translate(-50%, -50%) scale(.4); opacity: 0; }
.card-scene.s2 .cs-env { transform: translateY(38px) scale(.94); opacity: .55; }
.card-scene.s3 .cs-env { transform: translateY(120px) scale(.8); opacity: 0; }

/* Лицевая сторона — БУМАГА. Одна палитра на обе темы. */
.cs-card {
  position: relative; margin-top: -128px; width: min(380px, 88vw);
  max-height: min(74vh, 640px); overflow-y: auto; overscroll-behavior: contain;
  background: var(--cp, #fffbf3); color: var(--ci, #3e3228);
  border-radius: 22px; padding: 20px 22px 18px; text-align: center;
  box-shadow: 0 2px 6px rgba(0,0,0,.18), 0 40px 90px -30px rgba(0,0,0,.72);
  opacity: 0; transform: translateY(46px) scale(.86); pointer-events: none;
  transition: opacity 420ms var(--ease), transform 620ms cubic-bezier(.2, .9, .25, 1.05);
}
.card-scene.s2 .cs-card { opacity: 1; transform: translateY(-12px) scale(1); pointer-events: auto; }
.card-scene.s3 .cs-card { transform: translateY(-64px) scale(1); }
.cs-card::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 6px;
  border-radius: 22px 22px 0 0;
  background: linear-gradient(90deg, var(--cg1, #ffe7c2), var(--cg2, #ffc7d8));
}
.csc-top { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 4px 0 10px; }
.csc-emo { font-size: 30px; line-height: 1; }
.csc-kind {
  font-size: 11.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: color-mix(in srgb, var(--ci, #3e3228) 55%, transparent);
}
.csc-title {
  margin: 0 0 10px; font-size: 23px; line-height: 1.2; font-weight: 700; letter-spacing: -.015em;
  font-family: "Georgia", "Times New Roman", serif; color: var(--ci, #3e3228);
  overflow-wrap: anywhere;                 /* см. .csc-text ниже — заголовок пишет человек */
}
.csc-photo { margin: 0 0 12px; border-radius: 14px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,.16); }
.csc-photo img { display: block; width: 100%; max-height: 260px; object-fit: cover; }
/* 🔴 ДЛИННОЕ СЛОВО НЕ ВЫНОСИТ ОТКРЫТКУ (CLIE-683·6): ссылка или «ааааа…» без пробелов
   раздвигала бумагу и включала горизонтальную прокрутку сцены. `white-space: pre-wrap`
   сам по себе переносит только по пробелам. Поздравление пишет человек — значит в него
   попадёт и ссылка, и адрес, и слово капслоком. Тот же `anywhere` уже стоит у письма
   («Подробнее», .cm-text) — приводим лицевую сторону к нему. */
.csc-text { margin: 0; font-size: 15.5px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; color: color-mix(in srgb, var(--ci, #3e3228) 90%, transparent); }
.csc-text.csc-ph { opacity: .45; }
.csc-from {
  margin-top: 14px; font-size: 14px; font-style: italic; font-weight: 600;
  font-family: "Georgia", serif;
  /* Подпись «— от кого» — тот же акцент, но с долей чернил: чистый бледный акцент на
     кремовой бумаге читается на грани (у «бабушки и дедушки» это #EFA1A6 на #FFF9F6). */
  color: color-mix(in srgb, var(--ca, #e8823c) 62%, var(--ci, #3e3228) 38%);
}
/* 🔴 КНОПКИ ОТКРЫТКИ ДОСТУПНЫ ПРИ ЛЮБОЙ ДЛИНЕ ПИСЬМА (CLIE-683·6). Лист `.cs-card`
   капнут `max-height: min(74vh, 640px)` и прокручивается, а «Подробнее» и «Закрыть»
   лежат в самом низу — у длинного поздравления они уезжали под прокрутку, бегунок при
   этом прозрачен, пока на него не навели мышь (решение владельца, CLIE-620). Получалось
   «открытка без выхода»: главное действие есть, а найти его нечем. Липнем ко дну листа —
   ровно тем же приёмом, что подвал модалки конструктора. Фон обязателен: под кнопками
   проезжает текст. */
.csc-acts {
  margin-top: 16px; display: flex; gap: 8px; justify-content: center; align-items: center; flex-wrap: wrap;
  position: sticky; bottom: -18px; z-index: 1;
  padding: 10px 0 18px; margin-bottom: -18px;
  background: linear-gradient(transparent, var(--cp, #fffbf3) 34%);
}
/* 🔴 ПАРА КНОПОК — ОДНА ГЕОМЕТРИЯ. Высота и отступы были общими, но рамка у одной
   прозрачная, а у другой нет: box-sizing по умолчанию считает её СВЕРХ высоты, и кнопки
   вставали на разные базовые линии («кнопки не ровно»). Фиксируем box-sizing, ровняем
   содержимое по центру и не даём тексту менять высоту (line-height: 1). */
.cs-more, .cs-close, .cs-more-demo {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px; cursor: pointer;
  box-sizing: border-box; line-height: 1; vertical-align: middle;
  height: 38px; padding: 0 18px; border-radius: 999px; font-size: 14px; font-weight: 620;
  border: 1px solid transparent; transition: filter var(--dur-1, 120ms) var(--ease), transform var(--dur-1, 120ms) var(--ease);
}
.cs-more, .cs-more-demo { background: var(--ca, #e8823c); color: var(--cbi, #fff); }
.cs-more:hover { filter: brightness(1.06); }
.cs-more:active { transform: scale(.98); }
.cs-more svg { width: 16px; height: 16px; }
/* 🔴 ПАРА КНОПОК ЧИТАЕТСЯ КАК ПАРА: одна высота, одна форма, видимая рамка у второй.
   Раньше «Закрыть» была голым текстом (рамка 20% чернил на кремовой бумаге — почти
   невидима), и рядом с заливной «Подробнее» это выглядело как перекос, а не как выбор. */
.cs-close {
  background: color-mix(in srgb, var(--ci, #3e3228) 5%, transparent);
  color: color-mix(in srgb, var(--ci, #3e3228) 78%, transparent);
  border-color: color-mix(in srgb, var(--ci, #3e3228) 34%, transparent);
}
.cs-close:hover { background: color-mix(in srgb, var(--ci, #3e3228) 11%, transparent); }

/* ── «Подробнее»: большой текст на выбранном фоне ─────────────────────────────── */
.card-more-ov {
  position: fixed; inset: 0; z-index: 9740; display: grid; place-items: center; padding: 18px;
  background: rgba(0,0,0,.62); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  opacity: 0; transition: opacity var(--dur-2, 200ms) var(--ease);
}
.card-more-ov.in { opacity: 1; }
.card-more {
  position: relative; width: min(620px, 94vw); max-height: 88vh; border-radius: 22px;
  overflow: hidden; box-shadow: 0 30px 90px -24px rgba(0,0,0,.7);
  transform: scale(.96); transition: transform var(--dur-3, 260ms) var(--ease-spring, var(--ease));
}
.card-more-ov.in .card-more { transform: scale(1); }
/* 🔴 КРЕСТИК ЧИТАЕТСЯ НА ЛЮБОМ ФОНЕ, который выбрал человек: письмо бывает и светло-кремовым,
   и фотографией. Полупрозрачная чёрная плашка на светлом градиенте давала серый блин с белым
   крестиком — контраста нет. Берём плотную подложку + светлое кольцо: работает и на светлом,
   и на тёмном, и на фото. */
/* 🔴 КРЕСТИК СТОИТ ПО ЦЕНТРУ КРУГА (CLIE-683·8, владелец: «крестик закрыть не ровно
   посередине»). Замер в кадре: у кнопки было `padding: 10px 14px` (пришло от общего
   правила кнопок) при `box-sizing: border-box` и размере 34px — на содержимое оставалась
   коробка 6×14px, и `place-items: center` центрировал глиф В НЕЙ, а не в круге. Плюс сам
   глиф приходил 22px вместо 17. Итог на экране: смещение dx=8 dy=4 и вылет за круг на 2px
   справа. Круглой кнопке-иконке padding не нужен ВООБЩЕ — центрирует сетка. */
.cm-x {
  position: absolute; top: 12px; right: 12px; z-index: 3;
  width: 34px; height: 34px; padding: 0; border-radius: 50%; border: 0; cursor: pointer;
  background: rgba(0,0,0,.52); color: #fff; display: grid; place-items: center;
  box-shadow: 0 0 0 1px rgba(255,255,255,.38), 0 2px 8px rgba(0,0,0,.28);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.cm-x:hover { background: rgba(0,0,0,.66); }
.cm-x svg, .cm-x svg.ic { width: 17px; height: 17px; display: block; }
.cm-scroll { max-height: 88vh; overflow-y: auto; padding: 46px 34px 38px; }
.cm-text { font-size: 17px; line-height: 1.68; white-space: pre-wrap; word-break: break-word; }
.cmf-serif { font-family: "Georgia", "Times New Roman", serif; }
.cmf-sans  { font-family: inherit; }
/* 🔴🔴 РУКОПИСНЫЙ ШРИФТ — НАШ ФАЙЛ, А НЕ «ЧТО НАШЛОСЬ В СИСТЕМЕ» (CLIE-683·5).
   Здесь стоял список системных гарнитур: на маке подхватывалась "Bradley Hand", и на ПК
   всё выглядело рукописно. На телефоне НЕТ НИ ОДНОЙ из них, а в приложение свой шрифт не
   клали вовсе — поэтому «От руки» там оставался обычным Roboto, и владелец справедливо
   спросил, почему на телефоне не так, как на ПК. Теперь файл ОДИН на оба клиента:
   веб берёт его отсюда, Flutter — из `client/fonts/` (см. pubspec, family Caveat).
   Системные гарнитуры оставлены хвостом — на случай, если файл не доехал. */
@font-face {
  font-family: "Caveat";
  src: url("fonts/Caveat.ttf") format("truetype");
  font-weight: 400 700;   /* вариативная ось веса — «жирный» не подделывается синтетикой */
  font-display: swap;     /* текст виден сразу, гарнитура доезжает — открытка не мигает пустотой */
}
/* 🔴 Кегль у рукописной больше: у Caveat строчные заметно ниже, чем у гротеска, и на
   прежних 18.5px текст читался мельче соседних строк. */
.cmf-hand  { font-family: "Caveat", "Segoe Script", "Bradley Hand", "Comic Sans MS", cursive; font-size: 21px; }
.cma-left { text-align: left; }
.cma-center { text-align: center; }
/* Размер/начертание — ПЕРЕЧИСЛЕНИЯ (сервер режет их же): произвольный CSS в чужом
   сообщении был бы дверью для вёрстки поверх интерфейса получателя. */
.cms-s  { font-size: 15px; }
.cms-m  { font-size: 17px; }
.cms-l  { font-size: 20px; line-height: 1.6; }
.cms-xl { font-size: 24px; line-height: 1.55; }
.cm-b { font-weight: 700; }
.cm-i { font-style: italic; }

/* ── Конструктор открытки (внутри канонической .v2-modal) ───────────────────────
   🔴 Рама ШИРОКАЯ (владелец: «опять мельчить начал, зачем такое мелкое модальное окно,
   как тут работать?»). Причина прежней тесноты названа честно: конструктор жил в раме
   обычного диалога (~560px), а превью занимало фиксированные 260px — форме оставалось
   меньше 300px, и подписи полей переносились по слогам («Необязатель / но:»).
   Ширину НЕ прибиваем числом: `min(1120px, 94vw)` + окно тянется мышью штатным
   initWindowResize (правило CRMC-406 «ни одной прибитой ширины»). */
#v2Modal:has(.card-cmp) .v2-modal { width: min(1120px, 94vw); max-width: 94vw; }
#v2Modal:has(.card-cmp) .v2-modal-body { padding-top: 14px; }
.card-cmp { display: grid; grid-template-columns: minmax(300px, 1fr) minmax(0, 1.15fr); gap: 22px; align-items: start; }
@media (max-width: 900px) { .card-cmp { grid-template-columns: minmax(0, 1fr); } }
.cc-preview { position: sticky; top: 0; display: flex; flex-direction: column; gap: 12px; }
.csp-frame {
  border-radius: 18px; padding: 16px;
  background: linear-gradient(140deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line);
}
/* 🔴 ПРЕВЬЮ — ОДИН ПРЕДМЕТ, А НЕ СТОПКА ПРЯМОУГОЛЬНИКОВ (CLIE-683·9, владелец: «всё
   вылазиет, давай сделаем чтобы это было как одно целое, сейчас видно что из кусков
   собрано»). Замер на проде: у трёх вложенных коробок были ТРИ РАЗНЫХ скругления —
   рама 18px, карточка 16px, лист 14px, — а у карточки `overflow: visible`, из-за чего
   цветная полоса `::before` со своим радиусом давала уголки на скруглении.
   Открытка — предмет: лицевая сторона и вкладыш обязаны читаться одной вещью. Поэтому
   у карточки и листа скругление ОДНО (`--csp-r`), а карточка ОБРЕЗАЕТ своё содержимое —
   тогда полоса ложится точно по её краю. */
.csp-card {
  background: var(--cp, #fffbf3); color: var(--ci, #3e3228);
  border-radius: var(--csp-r, 16px); padding: 16px 16px 14px; text-align: center; position: relative;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,.14), 0 16px 34px -20px rgba(0,0,0,.5);
}
.csp-card::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 5px; border-radius: 16px 16px 0 0; background: linear-gradient(90deg, var(--cg1, #ffe7c2), var(--cg2, #ffc7d8)); }
.csp-card .csc-title { font-size: 21px; margin-bottom: 9px; }
.csp-card .csc-text { font-size: 14.5px; }
.csp-card .csc-photo img { max-height: 190px; }
.csp-card .csc-emo { font-size: 26px; }
.csp-card .csc-acts { margin-top: 12px; }
.cs-more-demo { height: 30px; padding: 0 13px; font-size: 12.5px; cursor: default; }
/* Живое превью «Подробнее» — стилизовать текст вслепую нельзя. */
/* 🔴 УЗОР ДОЛЖНО БЫТЬ ВИДНО, А НЕ УГАДЫВАТЬ ПО КАЙМЕ (CLIE-683·8, владелец: «паттерн
   когда выбираешь его видно очень плохо, нужно в превью больше пространства для фона»).
   Подложка под текстом (.cm-on-texture) растягивается на всю ширину блока, и при коротком
   письме от узора оставалась полоска в 16–18px по краям. Даём фону дышать: отступ вокруг
   листа больше, и он же задаёт минимальную высоту, чтобы узор читался даже под одним
   словом. Это ПРЕВЬЮ ФОНА — его работа показать фон. */
/* 🔴 ВОЗДУХ СВЕРХУ РАВЕН ВОЗДУХУ СНИЗУ (CLIE-683·8, владелец: «сделай такой же отступ
   внутри сверху как и снизу чтобы больше фона было и гармонично смотрелось»). Блок
   держит `min-height`, а содержимое лежало ПО ВЕРХУ — весь свободный запас собирался
   внизу, и лист выглядел сдвинутым. Центрируем по вертикали: тогда узор виден ровной
   рамкой со всех сторон. И отделяем лист от лицевой стороны (`margin-top`) — это два
   РАЗНЫХ предмета, а не один слипшийся блок. */
/* scroll-cap-ok: это ПРЕВЬЮ, а не текст для чтения — намеренно подрезано с растворением
   края (::after). Читают его в самой модалке «Подробнее», где скролл честный. */
.csp-more {
  display: none; border-radius: var(--csp-r, 16px); padding: 30px 28px; min-height: 150px;
  max-height: 230px; overflow: hidden; position: relative;
  margin-top: 14px;
  align-items: center; justify-content: center;
}
.csp-more.on { display: flex; }
.csp-more::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 34px; background: linear-gradient(transparent, rgba(0,0,0,.10)); pointer-events: none; }
.csp-more .cm-text { font-size: 14px; line-height: 1.6; }

.cc-form { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.cc-sec { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.cc-lbl { font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.cc-lbl i { font-style: normal; font-weight: 550; text-transform: none; letter-spacing: 0; opacity: .8; }

/* 🔴 БЕЗ ВЛОЖЕННОГО КАПА (CLIE-683·6). Стоял `max-height:262px; overflow-y:auto`, и замер
   на живом проде показал ровно то, что запрещает правило CLIE-620: содержимое 537px в
   коробке 262px, а обрез приходился НЕ на границу ряда — ЧЕТЫРЕ плитки повода были видны
   наполовину, разрезанные по названию. Плюс бегунок в продукте прозрачен, пока на блок не
   навели мышь, поэтому «Праздники» читались как «дальше ничего нет».
   Правило прямо говорит: список ВНУТРИ уже скроллящейся панели не капим — он растёт, а
   скроллит внешняя панель; кап оправдан только там, где иначе вырастут ТЫСЯЧИ пикселей.
   Здесь их 537, а модалка теперь держит шапку и подвал липкими, так что «Отправить»
   достаётся с любой прокрутки. Вложенного бегунка в конструкторе больше нет вовсе. */
.cc-tpls { padding-right: 4px; display: flex; flex-direction: column; gap: 10px; }
.cc-tgrp-h { font-size: 11px; font-weight: 650; color: var(--text-dim); margin-bottom: 6px; }
.cc-tgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; }
.cc-tpl {
  display: flex; flex-direction: column; align-items: center; gap: 5px; cursor: pointer;
  padding: 9px 6px; border-radius: 12px; border: 1px solid var(--line); background: var(--panel-2);
  transition: border-color var(--dur-1, 120ms) var(--ease), transform var(--dur-1, 120ms) var(--ease), background var(--dur-1, 120ms) var(--ease);
}
.cc-tpl:hover { background: var(--hover); }
.cc-tpl.on { border-color: var(--ca, var(--primary)); background: color-mix(in srgb, var(--cg1, #ffe7c2) 34%, var(--panel-2)); }
.cct-emo { font-size: 20px; line-height: 1; }
.cct-nm { font-size: 11.5px; font-weight: 580; line-height: 1.2; text-align: center; color: var(--text); }

.cc-in {
  width: 100%; box-sizing: border-box; background: var(--input-bg); color: var(--text);
  border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px; font-size: 14.5px;
  outline: none; font-family: inherit; resize: vertical;
  transition: border-color var(--dur-1, 120ms) var(--ease), box-shadow var(--dur-1, 120ms) var(--ease);
}
.cc-in:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
/* «Подробнее» — КАНОНИЧЕСКИЙ редактор продукта (mountRichBox), тот же, что у заметок задачи
   и страницы вики. Своего поля со своими классами стиля здесь нет и быть не должно:
   жирный/курсив принадлежат ВЫДЕЛЕННОМУ КУСКУ, а не всему письму. */
/* Ряд «ИИ пишет текст». Размеры — из общих токенов строки контролов (--ctl-*), а не свои
   числа: иначе кнопки рядом с полем окажутся другого роста, чем всё остальное (CLIE-505). */
.cc-ai { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.cc-aib {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  height: var(--ctl-h); padding: 0 12px; border-radius: var(--ctl-r); font-size: var(--ctl-fs);
  font-weight: 600; font-family: inherit; white-space: nowrap; min-width: max-content;
  background: transparent; color: var(--muted); border: 1px solid var(--line);
  transition: background var(--dur-1, 120ms) var(--ease), color var(--dur-1, 120ms) var(--ease);
}
.cc-aib:hover { background: var(--surface-2, rgba(127,127,127,.09)); color: var(--text); }
.cc-aib.primary { background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--primary); border-color: color-mix(in srgb, var(--primary) 30%, transparent); }
.cc-aib.primary:hover { background: color-mix(in srgb, var(--primary) 22%, transparent); }
.cc-aib svg { width: 15px; height: 15px; }
.cc-aib[disabled] { opacity: .6; cursor: default; }
.cc-more-host { min-width: 0; }
.cc-more-host .rd-box {
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 12px;
  transition: border-color var(--dur-1, 120ms) var(--ease), box-shadow var(--dur-1, 120ms) var(--ease);
}
.cc-more-host .rd-box:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
.cc-more-host .rd-ce { min-height: 96px; max-height: 34vh; overflow-y: auto; padding: 10px 12px; font-size: 14.5px; line-height: 1.5; }
/* Разметку внутри письма красят ЧЕРНИЛА ОТКРЫТКИ, а не палитра интерфейса: иначе заголовок
   или ссылка приедут цветом темы и утонут на кремовой бумаге. */
/* 🔴 ТЕКСТ НА УЗОРЕ ЛЕЖИТ НА ПОДЛОЖКЕ. Узор — фон ЛИСТА; буквы поверх него нечитаемы при
   любом цвете узора, который выберет человек (владелец: «зачем такие яркие, что текст не
   прочитать»). Так решают это все, у кого работает: обои Telegram, обложки Notion — рисунок
   остаётся фоном, содержимое едет на своей поверхности. Подложка полупрозрачная, поэтому
   узор виден по краям и «просвечивает», а не исчезает. */
/* 🔴 ПОДЛОЖКА ОБНИМАЕТ ТЕКСТ — И В ПРЕВЬЮ, И В ПИСЬМЕ (CLIE-683·8). Правило ОДНО на оба
   места, иначе «что видно, то и придёт» разъезжается: в превью лист жался к тексту, а у
   получателя растягивался во всю ширину. `fit-content` решает обе задачи разом — короткое
   письмо оставляет узор видимым со всех сторон (просьба владельца «больше пространства
   для фона»), длинное само занимает всю доступную ширину, как и раньше. */
.cm-text.cm-on-texture {
  max-width: fit-content; margin-left: auto; margin-right: auto;
  background: color-mix(in srgb, #fff 80%, transparent);
  -webkit-backdrop-filter: saturate(1.05) blur(2px); backdrop-filter: saturate(1.05) blur(2px);
  border-radius: 16px; padding: 18px 20px;
  box-shadow: 0 1px 2px rgba(0,0,0,.05), 0 10px 30px -18px rgba(0,0,0,.35);
}
.cm-text.md-body, .cm-text.md-body * { color: inherit; }
.cm-text.md-body a { color: inherit; text-decoration: underline; }
.cm-text.md-body > :first-child { margin-top: 0; }
.cm-text.md-body > :last-child { margin-bottom: 0; }
.cc-row2 { display: flex; gap: 8px; align-items: center; }
.cc-row2 .cc-in { flex: 1 1 auto; }
.cc-photo-btn, .cc-bgphoto-btn {
  display: inline-flex; align-items: center; gap: 7px; flex: 0 0 auto; cursor: pointer;
  height: 40px; padding: 0 14px; border-radius: 12px; font-size: 13.5px; font-weight: 600;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
}
.cc-photo-btn:hover, .cc-bgphoto-btn:hover { background: var(--hover); }
.cc-photo-btn svg, .cc-bgphoto-btn svg { width: 16px; height: 16px; }
.cc-photo-btn.busy, .cc-bgphoto-btn.busy { opacity: .6; cursor: progress; }
.cc-ph { position: relative; width: 84px; height: 60px; border-radius: 10px; overflow: hidden; border: 1px solid var(--line); }
.cc-ph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cc-ph button { position: absolute; top: 3px; right: 3px; width: 20px; height: 20px; border: 0; border-radius: 50%; background: rgba(0,0,0,.55); color: #fff; cursor: pointer; display: grid; place-items: center; }
.cc-ph button svg { width: 12px; height: 12px; }

/* Оформление «Подробнее» появляется, только когда там есть текст (не отбираем экран). */
/* 🔴 ВОЗДУХ МЕЖДУ РЯДАМИ ОФОРМЛЕНИЯ (CLIE-683·9, владелец: «как-то всё слишком близко,
   давай добавим немного пространства подышать, чтобы проще было пользоваться»). Замер на
   проде: зазоры между рядами были 7–10px при рядах высотой 22–43px — семь групп контролов
   подряд без единой паузы читались одной кашей. 14px даёт различимые группы и не тратит
   лишнюю высоту: панель и так живёт в прокручиваемой модалке. */
.cc-more-style, .cc-bg { display: none; flex-direction: column; gap: 14px; }
.cc-more-style.on, .cc-bg.on { display: flex; }
/* 🔴 СЕГМЕНТ ВИДА ФОНА — ПО ЛЕВОЙ КРОМКЕ, КАК ВСЕ (CLIE-683·9). Замер: он единственный
   стоял со сдвигом +149px, то есть по центру. Виновата ПУТАНИЦА ОСЕЙ: канон
   `.cc-seg-sm { align-self: center }` писался для сегмента В СТРОКЕ, где эта ось
   вертикальная («своя высота, по центру строки» — так и в комментарии канона). Панель
   фона — КОЛОНКА, и там та же ось горизонтальная: центровка по вертикали превратилась в
   центровку по горизонтали. В колонке равняем по началу. */
.cc-bg > .cc-seg-sm { align-self: flex-start; }
/* Пауза на границе ДВУХ смысловых групп: «как выглядит текст» и «на чём он лежит».
   Внутри группы ряды идут через 14px, между группами — заметно больше, иначе семь рядов
   подряд читаются одним полотном (CLIE-683·9). */
.cc-bg { margin-top: 8px; }
/* 🔴🔴 РЯДЫ НЕ СЖИМАЮТСЯ НИЖЕ СВОЕГО СОДЕРЖИМОГО (CLIE-683·5).
   Замер на живом проде (`tools/shots/clie683-squeeze.js`): `.cc-swatch` h=22 при содержимом 44,
   родитель `.cc-more-style` h=66 при нужных 88. Ни у кого нет `max-height` — коробки именно
   СЖИМАЮТСЯ: вся цепочка (`.cc-more-style` → `.cc-sec` → `.cc-form`) это flex-элементы со
   `flex-shrink: 1`, дефицит доходит до панели, та ужимается 88→66, а будучи `wrap`, делит
   66 на ТРИ ряда — ровно по 22px. Остаток рисуется наружу (`overflow: visible`) и ложится
   на соседа: подписи «Цвет текста»/«Фон»/«Узор» оказывались поверх кружков, сегмент
   «Градиент·Паттерн·Цвет·Фото» — поверх ряда выше.
   Лечение двумя строками, обе обязательны:
     • `align-content: flex-start` — ряды берут СВОЮ высоту, а не делят чужую поровну;
     • `flex-shrink: 0` — панель вообще перестаёт быть донором чужого дефицита.
   Дефицит после этого уходит туда, где ему и место, — в скролл тела модалки (CLIE-620:
   список не капим, оставшийся скролл показываем). */
.cc-more-style { flex-direction: row; flex-wrap: wrap; gap: 8px; align-content: flex-start; flex-shrink: 0; }
/* 🔴 `.cc-seg`, `.cc-seg button`, `.cc-seg button.on` переехали в `/app/ccroom.css`. */
.cc-bgbody { min-height: 0; }
.cc-bgp { display: none; flex-wrap: wrap; gap: 12px; align-items: center; }   /* воздух, CLIE-683·9 */
.cc-bgp.on { display: flex; }
.cbg-chip {
  width: 40px; height: 30px; border-radius: 9px; cursor: pointer; padding: 0;
  border: 1px solid var(--line); background-repeat: repeat;
  transition: transform var(--dur-1, 120ms) var(--ease), box-shadow var(--dur-1, 120ms) var(--ease);
}
.cbg-chip:hover { transform: translateY(-1px); }
.cbg-chip.on { box-shadow: 0 0 0 2px var(--primary); border-color: transparent; }
.cc-clr { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 580; color: var(--muted); }
/* 🎨 Ряд образцов цвета — ОДИН и тот же в вебе и в приложении. Нативный <input type=color>
   отсюда убран: в тёмной теме он тонул, а во Flutter его нет вовсе (там всегда был ряд
   кружков) — то есть одна вещь имела два разных интерфейса. */
.cc-sws { display: flex; flex-direction: column; gap: 14px; width: 100%; }   /* воздух, CLIE-683·9 */
/* 🔴 БЛОК ОБРАЗЦОВ — ЧЕСТНАЯ КОЛОНКА, а не «подпись + что-то ниже». Замер на живой панели:
   ряд кружков рисовался на 12–14px НИЖЕ своей коробки и ложился разом на подпись, на
   соседний ряд и на секцию фона (5 наездов). Колоночный флекс по построению вмещает своих
   детей — высота больше не может «не заметить» ряд. */
/* 🔴 БЕЗ `min-height: 0`. Он снимает автоминимум флекс-элемента и РАЗРЕШАЕТ сжать коробку
   ниже содержимого: замер на проде дал h=22px при содержимом 44px (подпись 15 + зазор 5 +
   ряд 24) — ровно половина, и ряд свисал наружу, ложась на подпись, соседний ряд и секцию
   фона. Дети тоже не сжимаются: колонка обязана вместить их целиком. */
/* 🔴 БЛОЧНЫЙ ПОТОК, А НЕ ФЛЕКС-КОЛОНКА. Замер на проде: коробка .cc-swatch держалась 22px при
   содержимом 44px (подпись 15 + зазор 5 + ряд 24) — и ряд свисал наружу, ложась на подпись,
   на соседний ряд и на секцию фона (8 наездов, видно глазами на кадре). Ни `min-height`,
   ни `flex-shrink`, ни `align-self` этого не меняли: как флекс-ЭЛЕМЕНТ этот блок получал
   высоту от строки родителя. Обычный блок вмещает свои дети ПО ПОСТРОЕНИЮ — здесь нужна
   предсказуемость, а не гибкость. */
.cc-swatch { width: 100%; display: block; }
.cc-sw-lbl { margin-bottom: 5px; }
.cc-sw-lbl { font-size: 12px; font-weight: 580; color: var(--muted); }
.cc-sw-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.cc-sw-b {
  width: 24px; height: 24px; border-radius: 50%; cursor: pointer; padding: 0;
  border: 1px solid var(--line-strong);
  transition: transform var(--dur-1, 120ms) var(--ease), box-shadow var(--dur-1, 120ms) var(--ease);
}
.cc-sw-b:hover { transform: translateY(-1px); }
.cc-sw-b.on { box-shadow: 0 0 0 2px var(--primary); border-color: transparent; }
/* 🔴 Ряд образцов занимает ВСЮ строку — в ЛЮБОМ контейнере, куда его положат.
   Две разные беды, обе замерены на живой панели:
   1) `width:100%` у флекс-элемента даёт БАЗИС ПО СОДЕРЖИМОМУ, когда ширина родителя
      неопределённа: `.cc-sws` («Фон» + «Узор») схлопывался до одного кружка (~75px),
      кружки уходили в вертикальную колонку и ложились на подпись;
   2) `flex-shrink:1` разрешал ужаться и ряду «Цвет текста» рядом с сегментами.
   Поэтому: базис задаём ФЛЕКСОМ (он резолвится от главной оси строки, а не от процента),
   и запрещаем сжатие (`0` вторым числом). Класс СРЕД-33 «контрол не сжимается ниже
   своей подписи». */
/* `align-self: flex-start` обязателен: по умолчанию флекс РАСТЯГИВАЕТ элемент до высоты
   строки, и если ряд оказался на одной строке с сегментами, его коробка становится ростом
   с сегмент (~31px), а содержимое (подпись 17 + кружки 24) вываливается вниз на 14px —
   ровно те наезды, что показал замер. Со своей высотой вываливаться нечему. */
.cc-more-style > .cc-swatch,
.cc-bgp > .cc-swatch,
.cc-bgp > .cc-sws { flex: 1 0 100%; min-width: 0; align-self: flex-start; }
/* 🔴🔴🔴 НАСТОЯЩАЯ ПРИЧИНА «22px ПРИ СОДЕРЖИМОМ 44» — СТОЛКНОВЕНИЕ ИМЁН, А НЕ ФЛЕКС
   (CLIE-683·6). Ряд образцов назывался `.cc-sw`, и ровно это имя в продукте УЖЕ занято
   ТУМБЛЕРОМ «вкл/выкл» из CRM (app.js, инлайновый стиль рядом с `.cc-toggle`):
       .cc-sw { width:38px; height:22px; border-radius:999px; background:… }
       .cc-sw::after { …белый кружок 18px… }
   Отсюда бралось ВСЁ разом: высота 22, тёмная пилюля во всю ширину ряда и белый кружок
   поверх подписи («…ет текста» вместо «Цвет текста» — видно на кадре). Замер стеком
   `elementsFromPoint` в точке подписи: сверху лежал `.cc-sw` с `bg=rgb(52,60,73)` и
   `border-radius:999px` — чужой компонент.
   Прошлые заходы лечили СИМПТОМ высоты (`align-self`, `flex-basis`, `min-height:
   max-content`) — цифра выправлялась, пилюля и кружок оставались на экране. Теперь ряд
   зовётся `.cc-swatch` (переименован НОВИЧОК — он в одном месте, тумблер в 17), и коробка
   становится 43 при содержимом 43 САМА, без единой подпорки: обычный блок вмещает своих
   детей по построению.
   🔴 Мораль шире открытки: прежде чем объяснять размер флексом, спроси у браузера, КТО
   вообще нарисован в этой точке. `.cc-sw`, `.cc-in`, `.cc-x`, `.cc-sec` — короткие общие
   имена, и в продукте они уже разобраны. */
/* Внутри .cc-sws контейнер — КОЛОНКА: там `flex:1 0 100%` означал бы базис по ВЫСОТЕ,
   и два ряда дрались бы за неё. Ширину в колонке даёт РАСТЯЖЕНИЕ по поперечной оси, а не
   процент: замер показал `.cc-swatch` = 38px при родителе 569px, то есть `width:100%` там не
   срабатывает (кружки уходили в колонку по одному — 12 штук в 12 строк). */
.cc-sws > .cc-swatch { flex: 0 0 auto; min-width: 0; width: auto; align-self: stretch; }

/* Светлая тема: тени мягче (единственное отличие — бумага открытки не меняется). */
html[data-theme="light"] .card-env { box-shadow: 0 1px 2px var(--cm-141e3c-06, rgba(20,30,60,.06)), 0 12px 28px -18px var(--cm-1e2d5a-28, rgba(30,45,90,.28)); }
html[data-theme="light"] .cs-card { box-shadow: 0 2px 6px var(--cm-141e3c-1, rgba(20,30,60,.10)), 0 40px 80px -30px var(--cm-141e3c-42, rgba(20,30,60,.42)); }
html[data-theme="light"] .csp-card { box-shadow: 0 1px 3px var(--cm-141e3c-07, rgba(20,30,60,.07)), 0 16px 30px -20px var(--cm-141e3c-28, rgba(20,30,60,.28)); }
html[data-theme="light"] .cs-seg button.on { box-shadow: 0 1px 2px var(--cm-141e3c-1, rgba(20,30,60,.10)); }
/* `html[data-theme="light"] .cc-seg button.on` — в `/app/ccroom.css` (канон сегмента). */

@media (prefers-reduced-motion: reduce) {
  .card-env, .cev-flap, .cev-letter, .cs-env, .cse-flap, .cse-seal, .cs-card, .card-more { transition-duration: .01ms !important; }
  .cs-hint { animation: none; }
}

/* 🎬 CLIE-515: рама формы — ещё и зона броска файла (position нужен оверлею-подсказке).
   Ширину НЕ прибиваем — max-width остаётся, окно тянется штатным initWindowResize. */
.tc-box { max-width: 680px; position: relative; }
/* Подсказка «отпустите» — ТА ЖЕ .drop-overlay, что в чате (одна реализация на продукт):
   здесь только радиус по раме модалки, слой над подвалом и вторая строка-пояснение.
   Обе темы приходят из базового правила .drop-overlay (светлая — ниже по файлу). */
.tc-drop { border-radius: var(--radius); z-index: 70; }
.tc-drop .drop-sub { margin-top: 5px; font-size: 12.5px; font-weight: 500; opacity: .74; }
.tc-head-actions { display: flex; align-items: center; gap: 6px; }
.tc-head-actions .ghost.small { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; padding: 0; }
.tc-head-actions .ic { width: 17px; height: 17px; }
.tc-body { padding: 14px 16px 4px; overflow-y: auto; }
/* 🎙 CLIE-1585: строка заголовка = поле + микрофон. Кнопка НЕ внутри поля (внутренний padding
   16px-шрифта съедал бы её на узком экране) и не третьей строкой — это тот же ряд. */
.tc-titlerow { display: flex; align-items: center; gap: 8px; }
.tc-titlerow > .tc-title { flex: 1 1 auto; min-width: 0; }
.tc-mic { flex: 0 0 auto; width: 44px; height: 44px; padding: 0; display: inline-flex; align-items: center; justify-content: center; border-radius: 12px; }
.tc-mic svg { width: 19px; height: 19px; }
.tc-dictbar { margin-top: 8px; }
.tc-dictx { display: inline-flex; align-items: center; gap: 6px; }
.tc-title { width: 100%; box-sizing: border-box; background: var(--input-bg); border: 1px solid var(--line); border-radius: 12px; color: var(--text); font-size: 16px; padding: 13px 14px; outline: none; }
.tc-title:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.tc-title::placeholder { color: var(--muted); }
.tc-preview { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }
.tc-tok { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; padding: 3px 8px; border-radius: 8px; background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary-2); border: 1px solid color-mix(in srgb, var(--primary) 34%, transparent); cursor: pointer; }
.tc-tok .ic { width: 13px; height: 13px; }
.tc-tok-x { display: inline-flex; opacity: .65; }
.tc-tok-x .ic { width: 11px; height: 11px; }
.tc-hint { font-size: 12px; color: var(--muted); margin: 7px 2px 0; min-height: 15px; }
.tc-chiprow { display: flex; flex-wrap: wrap; gap: 8px; margin: 13px 0 2px; }
.tc-chip { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; padding: 7px 11px; border-radius: 10px; background: var(--panel-2); border: 1px solid var(--line); color: var(--muted); cursor: pointer; transition: border-color .12s, color .12s; }
.tc-chip:hover { border-color: var(--primary); color: var(--text); }
.tc-chip.on { background: color-mix(in srgb, var(--primary) 16%, transparent); border-color: color-mix(in srgb, var(--primary) 45%, transparent); color: var(--text); }
.tc-chip .ic { width: 15px; height: 15px; }
.tc-chip-x { display: inline-flex; opacity: .6; margin-left: 1px; }
.tc-chip-x .ic { width: 12px; height: 12px; }
.tc-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; flex: none; }
.tc-more-toggle { display: inline-flex; align-items: center; gap: 6px; margin: 12px 0 0; background: none; border: none; color: var(--muted); font-size: 13px; cursor: pointer; padding: 4px 0; }
.tc-more-toggle .ic { width: 15px; height: 15px; transition: transform .15s; }
.tc-more-toggle.open .ic { transform: rotate(180deg); }
.tc-more { max-height: 0; overflow: hidden; transition: max-height .24s ease; }
.tc-more.open { max-height: 900px; overflow: visible; }
.tc-lbl { display: block; font-size: 12px; color: var(--muted); margin: 11px 2px 5px; }
.tc-ta, .tc-mini { width: 100%; box-sizing: border-box; background-color: var(--input-bg); border: 1px solid var(--line); border-radius: 10px; color: var(--text); font-size: 14px; padding: 10px 12px; outline: none; font-family: inherit; } select.tc-mini { padding-right: 34px; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.tc-ta:focus, .tc-mini:focus { border-color: var(--primary); }
.tc-pickbtn { text-align: left; cursor: pointer; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tc-two { display: flex; gap: 10px; }
.tc-two > div { flex: 1; min-width: 0; }
.tc-checklist { display: flex; flex-direction: column; gap: 5px; margin-bottom: 6px; }
.tc-ci { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--text); }
.tc-ci > span:first-child { display: inline-flex; }
.tc-ci > span:first-child .ic { width: 14px; height: 14px; color: var(--ok); }
.tc-ci-t { flex: 1; min-width: 0; }
.tc-ci-x { background: none; border: none; color: var(--muted); cursor: pointer; padding: 2px; display: inline-flex; }
.tc-ci-x .ic { width: 13px; height: 13px; }
.tc-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.tc-another { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--muted); cursor: pointer; }
.tc-foot-btns { display: flex; gap: 8px; }
/* Плавающие пикеры чипов (стиль td-userpick) */
/* 🔴 z-index ВЫШЕ плавающего бара мультивыбора (.board-bulk-bar = 9400) и mention/ref-меню
   (9400): popover «Ещё» массовых действий якорится к кнопке ВНУТРИ этого бара, поэтому при
   90 нижние строки меню («Переместить в столбец…») уходили ПОД бар и не кликались. */
/* 🔴 CLIE-620/631: поповер-меню — тоже «модалка без скроллящегося тела». Сортировка + фильтры
   + этапы легко перерастают экран, поэтому кап живёт ЗДЕСЬ, а видимый бегунок и подтаивающий
   край даёт канонический .cc-scroll-in (его вешает tcPopover, второго механизма нет). */
.tc-pop { position: fixed; z-index: 9600; min-width: 200px; max-height: min(74vh, calc(100vh - 24px)); background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 8px; box-shadow: 0 14px 40px rgba(0,0,0,.55); }
/* Галочка выбранного пункта стоит на месте всегда — строки не «прыгают» при переключении. */
.tc-pop-row .tc-pop-tick { margin-left: auto; display: inline-flex; opacity: 0; transition: opacity .12s var(--ease-standard, ease); }
.tc-pop-row.on .tc-pop-tick { opacity: 1; }
/* Чипы фильтра в меню — ТОТ ЖЕ набор .v2-fl-*, что в каталоге проектов (одна реализация).
   Внутри поповера у него уже есть свои 8px, поэтому секциям снимаем горизонтальный отступ:
   иначе чипы уезжают на 16px от подписи блока. */
.tc-pop .v2-fl-sec { padding: 8px 2px; }
.tc-pop .tcol-cfg-head { display: flex; align-items: center; gap: 8px; }
.tc-pop .tcol-cfg-head .v2-fl-clear { margin-left: auto; }
.tc-pop .tc-lbl { margin-top: 2px; }
.tc-pop-list { max-height: 260px; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
/* Пустое состояние пикера (напр. «прикрепить некуда»): объясняем, а не показываем пустоту. */
.tc-pop-empty { padding: 10px 9px; font-size: 12.5px; line-height: 1.35; color: var(--muted); }
.tc-pop-row { display: flex; align-items: center; gap: 9px; width: 100%; background: none; border: none; color: var(--text); text-align: left; padding: 8px 9px; border-radius: 8px; cursor: pointer; font-size: 13px; }
.tc-pop-row:hover { background: var(--hover); }
.tc-pop-row .ic { width: 15px; height: 15px; flex: none; }
.tc-pop-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tc-pop-presets { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.tc-pop-presets button { font-size: 12px; padding: 5px 9px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--text); cursor: pointer; }
.tc-pop-presets button:hover { border-color: var(--primary); }
.tc-pop-foot { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.tc-pop-foot .tc-mini { flex: 1; }
.tc-pop .primary.small, .tc-pop .ghost.small { font-size: 12px; padding: 6px 10px; border-radius: 8px; }
/* CLIE-505: .tc-seg удалён — правило было мёртвым (ни одной разметки в app.js).
   Новый переключатель здесь = .cc-seg + .cc-seg-md, а не свой вид. */
.tc-chk { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text); margin: 11px 2px 2px; cursor: pointer; }
.tc-chk input { width: 15px; height: 15px; accent-color: var(--primary); flex: none; }
.tc-chk .ic { width: 14px; height: 14px; color: var(--muted); }
.tc-pop-row.on { background: color-mix(in srgb, var(--primary) 16%, transparent); }

/* ── «Что я пропустил» (Catch me up): ИИ-саммари непрочитанного в поповере шапки чата ── */
.catchup-btn { color: var(--primary-2); }
.catchup-btn:hover { color: var(--primary); }
.cu-pop { width: 340px; max-width: calc(100vw - 24px); padding: 10px; }
.cu-head { display: flex; align-items: baseline; gap: 8px; padding: 2px 4px 8px; }
.cu-title { font-size: 13px; font-weight: 700; color: var(--text); letter-spacing: .1px; }
.cu-count { font-size: 11.5px; color: var(--muted); margin-left: auto; }
.cu-list { display: flex; flex-direction: column; gap: 2px; max-height: 60vh; overflow-y: auto; }
.cu-bullet { display: flex; align-items: flex-start; gap: 9px; width: 100%; box-sizing: border-box; background: none; border: none; color: var(--text); text-align: left; padding: 9px 8px; border-radius: 9px; cursor: pointer; font-size: 13px; line-height: 1.45; transition: background .12s; font-family: inherit; }
.cu-bullet:hover { background: var(--hover); }
.cu-bullet-static, .cu-bullet-static:hover { cursor: default; background: none; }
.cu-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--primary); margin-top: 6px; flex: none; opacity: .85; }
.cu-text { flex: 1; min-width: 0; }
.cu-jump { flex: none; align-self: center; color: var(--muted); font-size: 14px; opacity: 0; transform: translateX(-3px); transition: opacity .12s, transform .12s; }
.cu-bullet:hover .cu-jump { opacity: .8; transform: none; }
.cu-empty, .cu-error { padding: 15px 8px; text-align: center; color: var(--muted); font-size: 13px; }
.cu-hint { margin-top: 6px; padding: 4px 8px 0; font-size: 11px; color: var(--text-dim); text-align: right; }
.cu-loading { display: flex; align-items: center; justify-content: center; gap: 9px; padding: 20px 8px; color: var(--muted); font-size: 13px; }
.cu-spin { width: 15px; height: 15px; border: 2px solid var(--line-strong); border-top-color: var(--primary); border-radius: 50%; animation: cuSpin .7s linear infinite; flex: none; }
@keyframes cuSpin { to { transform: rotate(360deg); } }
.cu-retry { display: block; margin: 8px auto 2px; font-size: 12px; padding: 6px 14px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--text); cursor: pointer; }
.cu-retry:hover { border-color: var(--primary); }
/* ── ВЫЖИМКА ЧАТА (CLIE-669): та же панель, плюс переключатель окна, суть одной фразой и «Копировать».
   Отдельного набора классов НЕ заводим — «что я пропустил» и «выжимка» это одна панель с разным ОКНОМ. */
.digest-btn { color: var(--primary-2); }
.digest-btn:hover { color: var(--primary); }
.cu-scope { margin: 0 2px 8px; width: calc(100% - 4px); }
.cu-scope > button { flex: 1 1 0; }
.cu-body { display: flex; flex-direction: column; }
/* Суть разговора одной фразой — над пунктами: человек читает её первой и часто дальше не идёт. */
.cu-gist { padding: 2px 8px 10px; font-size: 13px; line-height: 1.5; color: var(--text); }
.cu-copy { flex: none; margin-left: auto; display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; padding: 0; border: none; border-radius: 7px; background: none; color: var(--muted); cursor: pointer; transition: background .12s, color .12s; }
.cu-copy:hover { background: var(--hover); color: var(--text); }
.cu-copy svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.cu-head .cu-count { margin-left: 0; }

/* 💬 «Спроси ИИ по этому чату» — поповер вопрос→ответ ИИ с цитатами (прецедент — .cu-*). Обе темы через переменные. */
.ask-head { display: flex; align-items: baseline; gap: 8px; padding: 2px 4px 8px; }
.ask-title { font-size: 13px; font-weight: 700; color: var(--text); letter-spacing: .1px; }
.ask-form { display: flex; align-items: center; gap: 7px; }
.ask-input { flex: 1; min-width: 0; box-sizing: border-box; height: 34px; padding: 0 11px; font-size: 13.5px; font-family: inherit; color: var(--text); background: var(--bg); border: 1px solid var(--line); border-radius: 9px; outline: none; transition: border-color .12s, box-shadow .12s; }
.ask-input::placeholder { color: var(--text-dim); }
.ask-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent); }
.ask-send { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border: none; border-radius: 9px; background: var(--acc-fill); color: #fff; cursor: pointer; transition: background .12s, transform .12s; }
.ask-send:hover { background: var(--acc-fill-hi); }
.ask-send:active { transform: scale(.94); }
.ask-send svg { width: 17px; height: 17px; }
.ask-results { margin-top: 4px; max-height: 46vh; overflow-y: auto; }
.ask-answer { padding: 10px 6px 4px; font-size: 13.5px; line-height: 1.5; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.ask-answer-muted { color: var(--muted); font-size: 12.5px; padding-bottom: 4px; }
.ask-cite { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 4px; margin: 0 1px; font-size: 10.5px; font-weight: 700; font-family: inherit; line-height: 1; vertical-align: 1px; color: var(--primary); background: color-mix(in srgb, var(--primary) 15%, transparent); border: none; border-radius: 5px; cursor: pointer; transition: background .12s; }
.ask-cite:hover { background: color-mix(in srgb, var(--primary) 32%, transparent); }
.ask-empty, .ask-error { padding: 15px 8px; text-align: center; color: var(--muted); font-size: 13px; }
.ask-src-list { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); }
.ask-src { display: flex; align-items: flex-start; gap: 8px; width: 100%; box-sizing: border-box; background: none; border: none; text-align: left; padding: 7px 6px; border-radius: 8px; cursor: pointer; font-family: inherit; transition: background .12s; }
.ask-src:hover { background: var(--hover); }
.ask-src-static, .ask-src-static:hover { cursor: default; background: none; }
.ask-src-n { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 17px; height: 17px; margin-top: 1px; font-size: 10.5px; font-weight: 700; color: var(--primary); background: color-mix(in srgb, var(--primary) 15%, transparent); border-radius: 5px; }
.ask-src-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.ask-src-who { font-size: 11.5px; font-weight: 600; color: var(--muted); }
.ask-src-text { font-size: 12.5px; line-height: 1.4; color: var(--text); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.ask-src-jump { flex: none; align-self: center; color: var(--muted); font-size: 14px; opacity: 0; transform: translateX(-3px); transition: opacity .12s, transform .12s; }
.ask-src:hover .ask-src-jump { opacity: .8; transform: none; }
.ask-loading { display: flex; align-items: center; justify-content: center; gap: 9px; padding: 20px 8px; color: var(--muted); font-size: 13px; }
.ask-spin { width: 15px; height: 15px; border: 2px solid var(--line-strong); border-top-color: var(--primary); border-radius: 50%; animation: cuSpin .7s linear infinite; flex: none; }
.ask-hint { margin-top: 6px; padding: 4px 8px 0; font-size: 11px; color: var(--text-dim); text-align: right; }
.ask-retry { display: block; margin: 8px auto 2px; font-size: 12px; padding: 6px 14px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--text); cursor: pointer; }
.ask-retry:hover { border-color: var(--primary); }
.tip-rem-flag { display: inline-flex; margin-left: 6px; color: var(--muted); }
.tip-rem-flag .ic { width: 13px; height: 13px; }
.tc-resp { margin-left: auto; opacity: .35; display: inline-flex; padding: 2px; }
.tc-resp.on { opacity: 1; color: var(--urg-today); }
.tc-resp .ic { width: 14px; height: 14px; }

/* Карточка задачи: метки / повтор / напоминания (Tier 3) */
.tip-labels-v { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; align-items: center; }
.tip-label { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 8px; background: color-mix(in srgb, var(--lc, var(--muted)) 17%, transparent); border: 1px solid color-mix(in srgb, var(--lc, var(--muted)) 40%, transparent); color: color-mix(in srgb, var(--lc, var(--muted)) 72%, #fff); }
.tip-label .td-prio-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--lc, var(--muted)); flex: none; }
.tip-label .tip-x { display: inline-flex; padding: 0; opacity: .75; }
.tip-label .tip-x:hover { opacity: 1; }
.tip-label .tip-x .ic { width: 11px; height: 11px; }
.tip-lbl-add .ic { width: 14px; height: 14px; }

/* ── Метки: цветные чипы на карточках + пикер с палитрой/заготовками (Trello/YouGile) ── */
.tasks-list .task-chip.lbl { background: color-mix(in srgb, var(--lc, var(--muted)) 16%, transparent); color: color-mix(in srgb, var(--lc, var(--muted)) 74%, #fff); font-weight: 600; }
.tasks-list .task-chip.lbl .tk-dot { width: 6px; height: 6px; border-radius: 50%; display: inline-block; flex: none; background: var(--lc, var(--muted)); }
/* Имя метки в строке пикера — окрашено в цвет метки */
.tc-pop-row.lbl-row .tc-pop-name { color: color-mix(in srgb, var(--lc, var(--text)) 80%, #fff); font-weight: 600; }
/* Заготовленные метки — чипы одним тапом создают/выбирают метку */
.lbl-presets { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 2px 4px; }
.lbl-preset { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; padding: 5px 10px; border-radius: 8px; cursor: pointer; background: color-mix(in srgb, var(--lc) 16%, transparent); border: 1px solid color-mix(in srgb, var(--lc) 38%, transparent); color: color-mix(in srgb, var(--lc) 74%, #fff); }
.lbl-preset:hover { background: color-mix(in srgb, var(--lc) 26%, transparent); border-color: color-mix(in srgb, var(--lc) 55%, transparent); }
.lbl-preset-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
/* Палитра цветов для своей метки */
.lbl-sw-row { display: flex; flex-wrap: wrap; gap: 7px; margin: 2px 2px 6px; }
.lbl-sw { width: 22px; height: 22px; padding: 0; border-radius: 50%; border: 2px solid transparent; cursor: pointer; box-shadow: inset 0 0 0 1px rgba(0,0,0,.28); transition: transform .1s; }
.lbl-sw:hover { transform: scale(1.14); border-color: transparent; }
.lbl-sw.on { border-color: #fff; box-shadow: 0 0 0 2px var(--primary); }
.lbl-make { border-top: 1px solid var(--line); margin-top: 8px; padding-top: 6px; }
/* Создание своей метки: поле на всю ширину, кнопка «Добавить» отдельной строкой снизу */
.lbl-foot { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.lbl-foot .lbl-new { width: 100%; box-sizing: border-box; }
.lbl-foot .lbl-add { width: 100%; }
/* 🔒 CLIE-1670·Р2-бис·6: ЗАМОК НА ВРЕМЯ ЗАПРОСА. Пока создание метки в полёте, кнопки и поле
   приглушены и не нажимаются: двойной тап обязан дать РОВНО один эффект (замер прода 03.10.2026:
   шесть одновременных POST одним именем давали шесть строк). Сам запрет — у двери `lblCreateReq`,
   здесь только его видимая половина: `disabled` у `<button>`/`<input>` красит именно она. */
.lbl-add:disabled, .lbl-preset:disabled, .lbl-new:disabled { opacity: .55; cursor: default; }
.lbl-add.is-busy { cursor: progress; }
/* 🏷 CLIE-1670 · УБРАТЬ МЕТКУ ИЗ СПИСКА (не удалить). Выбор — кнопка-строка, уборка — своя
   кнопка рядом: вложенная кнопка невалидна, поэтому обе лежат в общей обёртке. */
.lbl-rowwrap { display: flex; align-items: center; gap: 2px; }
.lbl-rowwrap > .tc-pop-row { flex: 1 1 auto; min-width: 0; }
.lbl-rowwrap > .tc-pop-row .tc-pop-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Крестик виден ВСЕГДА (приглушённо): на тач-экране нет наведения, а «появляется только при
   hover» там равно «кнопки нет». */
.lbl-x { flex: none; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: none; background: none; border-radius: 7px; cursor: pointer; color: var(--muted); opacity: .55; transition: opacity .12s var(--ease-standard, ease), background .12s var(--ease-standard, ease); }
.lbl-x .ic { width: 13px; height: 13px; }
.lbl-rowwrap:hover .lbl-x, .lbl-x:focus-visible { opacity: 1; }
.lbl-x:hover { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); opacity: 1; }
/* Убранные метки НЕ исчезают бесследно: свёрнутый раздел с возвратом (показ состояния + отмена). */
.lbl-hid { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 4px; }
.lbl-hid:empty { display: none; }
.lbl-hid-h { display: flex; align-items: center; gap: 6px; width: 100%; padding: 6px 8px; border: none; background: none; color: var(--muted); font-size: 12px; font-weight: 600; cursor: pointer; border-radius: 8px; text-align: left; }
.lbl-hid-h:hover { background: var(--hover); color: var(--text); }
.lbl-hid-h .ic { width: 13px; height: 13px; flex: none; transform: rotate(-90deg); transition: transform .14s var(--ease-standard, ease); }
.lbl-hid-h.open .ic { transform: rotate(0deg); }
.lbl-hid-list .lbl-rowwrap { opacity: .78; }
.lbl-hid-list .tc-pop-row { cursor: default; }
.lbl-back { flex: none; padding: 4px 9px; border-radius: 7px; border: 1px solid var(--line); background: none; color: var(--primary-2, var(--primary)); font-size: 12px; font-weight: 600; cursor: pointer; }
.lbl-back:hover { background: color-mix(in srgb, var(--primary) 14%, transparent); border-color: color-mix(in srgb, var(--primary) 46%, transparent); }
/* 🏷🏢 CLIE-1670·Р2 · ТРИ СЛОЯ МЕТОК В ОДНОМ ПИКЕРЕ (владелец 01.10.2026: «Чтобы все было
   рядом и в 1 клик… интуитивно понятно как у apple»). Секции, «где создаём» и наборы живут
   ЗДЕСЬ же, в пикере: отдельной страницы управления метками в продукте нет. Цвета — только
   токенами темы, поэтому светлая и тёмная получаются из одного описания. */
.lbl-top { padding: 2px 2px 6px; }
.lbl-top .lbl-new { width: 100%; box-sizing: border-box; }
/* Заголовок секции — «липкий», как в системных списках Apple: прокручивая длинный список,
   человек всегда видит, в каком слое он сейчас. */
.lbl-sec { position: sticky; top: 0; z-index: 1; padding: 7px 8px 4px; background: var(--surface, var(--bg)); font-size: 10.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.lbl-sec:not(:first-child) { margin-top: 2px; border-top: 1px solid var(--line); }
/* 🔒 «убрать нельзя» — НЕ мёртвая кнопка: она называет причину и даёт личный выход. */
.lbl-x.lbl-lock { opacity: .45; }
.lbl-x.lbl-lock:hover { background: var(--hover); color: var(--text); opacity: 1; }
.lbl-where { margin: 2px 2px 8px; display: inline-flex; }
/* Наборы меток — свёрнуты по умолчанию (прогрессивное раскрытие), раскрываются на месте. */
.lbl-sets { border-top: 1px solid var(--line); margin-top: 8px; padding-top: 4px; }
.lbl-sets-h { display: flex; align-items: center; gap: 6px; width: 100%; padding: 7px 8px; border: none; background: none; color: var(--muted); font-size: 12px; font-weight: 600; cursor: pointer; border-radius: 8px; text-align: left; }
.lbl-sets-h:hover { background: var(--hover); color: var(--text); }
.lbl-sets-h .ic { width: 13px; height: 13px; flex: none; transition: transform .14s var(--ease-standard, ease); }
.lbl-sets-h.open .ic { transform: rotate(45deg); }
.lbl-sets-body { display: flex; flex-direction: column; gap: 4px; padding: 2px 0 4px; }
.lbl-set-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 9px; }
.lbl-set-row:hover { background: var(--hover); }
.lbl-set-main { flex: 1 1 auto; min-width: 0; }
.lbl-set-name { font-size: 13px; font-weight: 600; color: var(--text); }
.lbl-set-items { display: flex; align-items: center; gap: 4px; margin-top: 2px; overflow: hidden; }
.lbl-set-items .muted { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lbl-set-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.lbl-set-foot { padding: 4px 8px 2px; }
.lbl-set-foot .lbl-back { width: 100%; text-align: center; }
.tc-pop { max-height: 82vh; overflow-y: auto; }
.tip-rems { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.tip-rem-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; color: var(--text); }
.tip-rem-row > span { display: inline-flex; align-items: center; min-width: 0; }
.tip-rem-row .ic { width: 14px; height: 14px; margin-right: 6px; flex: none; }

/* Список задач: hover-действия (Apple Reminders-стиль).
   Инлайн-строка быстрого добавления «Новая задача…» убрана по просьбе владельца (CLIE-223):
   дублировала кнопку «+» в шапке столбца «Мои задачи». */
/* Быстрые действия — плавают в правом-верхнем углу карточки (out of flow), чтобы НЕ отъедать
   ширину у заголовка. Появляются по наведению как мини-панель поверх хвоста заголовка. */
.task-hover-acts {
  position: absolute; top: 5px; right: 6px; z-index: 6;
  display: inline-flex; align-items: center; gap: 1px;
  padding: 2px; border-radius: 9px;
  background: var(--bg); border: 1px solid var(--line);
  box-shadow: 0 2px 10px rgba(0,0,0,.28);
  opacity: 0; pointer-events: none; transition: opacity .12s;
}
.task-row:hover .task-hover-acts { opacity: 1; pointer-events: auto; }
.tqact { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 7px; border: none; background: transparent; color: var(--muted); cursor: pointer; padding: 0; }
.tqact:hover { background: var(--panel); color: var(--text); }
.tqact.tqact-del:hover { color: var(--danger); }
/* Кнопка «пауза» когда МОЙ таймер идёт — синим (в тон бейджу «в работе»), чтобы было видно активное состояние. */
.tqact.tqact-running { color: var(--info); }
.tqact.tqact-running:hover { background: var(--info-soft); color: var(--info); }
html[data-theme="light"] .tqact.tqact-running { color: var(--cm-1d4ed8, #1d4ed8); }
.tqact .ic { width: 15px; height: 15px; }
.task-chip.due.tqclick { cursor: pointer; }
.task-chip.due.tqclick:hover { border-color: var(--primary); color: var(--text); }
.task-chip.lbl .tk-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; flex: none; }
.task-chip.rec .ic { width: 13px; height: 13px; }
@media (hover: none) { .task-hover-acts { opacity: 1; pointer-events: auto; } }

/* Доска: вид «По проектам» (колонка = контейнер) */
.tw-board-grp .tw-col-grp .tw-col-head { display: flex; align-items: center; gap: 7px; }
.tw-board-grp .tw-grp-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 1 auto; min-width: 0; }
/* Столбик-контейнер чата подписан своим проектом (CLIE-481) — ВТОРОЙ СТРОКОЙ, а не через точку
   в одном ряду: столбик узкий (замер: 250px), в одну строку «Приложение Менеджера · АртРест»
   ужималось до «Приложение … · А…» — то есть ответ на «какой же проект» опять пропадал. */
.tw-board-grp .tw-grp-titles { display: flex; flex-direction: column; min-width: 0; flex: 0 1 auto; line-height: 1.22; }
.tw-board-grp .tw-grp-sub { font-size: 11.5px; font-weight: 500; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-board-grp .tw-col-count { flex: none; align-self: center; }
.tw-board-grp .tw-col-head > .ic { width: 15px; height: 15px; color: var(--muted); flex: none; }
.tw-board-grp .tw-col-body { min-height: 20px; }
/* Группировка типов в выпадающем фильтре проектов/чатов/групп */
.tw-select optgroup { color: var(--muted); font-size: 11px; font-weight: 600; }
.tw-select option { color: var(--text); font-weight: 400; }

/* Доска: кастомные колонки (0034) — правка/добавление */
.tw-board-custom .tw-col-custom .tw-col-head { display: flex; align-items: center; gap: 6px; }
.tw-col-custom .tw-col-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tw-col-acts { display: inline-flex; gap: 1px; opacity: 0; transition: opacity .12s; margin-left: auto; }
.tw-col-custom:hover .tw-col-acts { opacity: 1; }
.tw-col-edit { background: none; border: none; color: var(--muted); cursor: pointer; padding: 2px; display: inline-flex; }
.tw-col-edit:hover { color: var(--text); }
.tw-col-edit .ic, .tw-col-custom .tw-col-add .ic { width: 14px; height: 14px; }
.tw-col-new { display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; flex: none; background: transparent; border: 1px dashed var(--line); color: var(--muted); border-radius: 12px; padding: 10px 16px; cursor: pointer; font-size: 13px; white-space: nowrap; height: fit-content; }
.tw-col-new:hover { border-color: var(--primary); color: var(--text); }
.tw-col-new .ic { width: 15px; height: 15px; }
.twc-swatches { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 4px; }
.twc-sw { width: 22px; height: 22px; border-radius: 6px; border: 2px solid transparent; cursor: pointer; padding: 0; }
.twc-sw.on { border-color: var(--text); }
/* Свой цвет — радужная плитка поверх нативного input[type=color] (v1 колонки + v2). */
.twc-custom, .tw-swatch-custom { position: relative; overflow: hidden; display: inline-flex; align-items: center; justify-content: center; background: conic-gradient(from 0deg, var(--urg-overdue), var(--urg-today), var(--urg-done), var(--info), #a78bfa, var(--urg-overdue)); }
.twc-custom input[type=color], .tw-swatch-custom input[type=color] { position: absolute; inset: -4px; width: calc(100% + 8px); height: calc(100% + 8px); opacity: 0; border: 0; padding: 0; margin: 0; cursor: pointer; }


/* ══════════════════════════════════════════════════════════════════════════════
   ТЕМА ОФОРМЛЕНИЯ — светлая версия (тумблер; тёмная остаётся по умолчанию).
   Механика: атрибут html[data-theme="light"] ставит бутстрап в index.html <head>
   (ДО отрисовки, без вспышки) и app.js (setTheme, localStorage cc_theme). Здесь —
   переопределение токенов + точечные фиксы хардкод-цветов, которые ломаются на светлом.
   Мультиагентный аудит CSS+JS: медиа/звонки/лайтбокс и «мой» пузырь (var(--grad))
   остаются ТЁМНЫМИ в обеих темах — их не трогаем.
   ────────────────────────────────────────────────────────────────────────────── */

/* Контролы тумблера (видны в ОБЕИХ темах — используют токены). */
.theme-toggle-btn { display: inline-flex; align-items: center; justify-content: center; padding: 5px 7px; }
.theme-toggle-btn svg.ic { width: 18px; height: 18px; }
.theme-presets { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 12px; }
.theme-preset {
  flex: 1 1 0; min-width: 92px; display: flex; flex-direction: column; align-items: stretch;
  gap: 8px; text-align: center; padding: 12px 10px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); font-size: 14px; font-weight: 600;
  cursor: pointer; transition: border-color .12s, background .12s;
}
.theme-preset:hover { border-color: var(--primary-2); }
.theme-preset.active { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary-2); }
.theme-swatch { width: 100%; height: 34px; border-radius: 6px; border: 1px solid var(--line); }
.theme-swatch-dark { background: linear-gradient(135deg, var(--cm-171a21, #171a21) 50%, var(--cm-2b3553, #2b3553) 50%); border-color: #2a2f3a; }
.theme-swatch-light { background: linear-gradient(135deg, #ffffff 50%, var(--cm-d9e0f6, #d9e0f6) 50%); border-color: #c5cddd; }
.theme-swatch-system { background: linear-gradient(135deg, var(--cm-171a21, #171a21) 50%, #ffffff 50%); border-color: #6b7280; }
/* 🎨 ШАБЛОН ДИЗАЙНА (0485): та же карточка .theme-preset, только с подписью «что это» и
   «что готово». Образец — картинка-намёк, цвета в ней фиксированы (как у образцов темы). */
.design-presets .design-preset { min-width: 200px; text-align: left; gap: 6px; padding: 12px; }
.design-swatch { height: 58px; display: flex; align-items: flex-end; gap: 5px; padding: 7px; margin-bottom: 2px; }
.design-swatch i { flex: 1 1 0; display: block; border-radius: 4px; }
.design-swatch-classic { background: #171a21; border-color: #2a2f3a; }
.design-swatch-classic i { background: #2b3553; }
.design-swatch-classic i:nth-child(1) { height: 70%; } .design-swatch-classic i:nth-child(2) { height: 100%; } .design-swatch-classic i:nth-child(3) { height: 52%; }
.design-swatch-depth { background: radial-gradient(120% 140% at 18% 0%, rgba(93,110,231,.62), rgba(93,110,231,0) 58%), radial-gradient(90% 120% at 100% 100%, rgba(56,189,248,.28), rgba(56,189,248,0) 60%), #101018; border-color: #323142; }
.design-swatch-depth i { background: rgba(255,255,255,.10); box-shadow: inset 0 0 0 1px rgba(255,255,255,.16); border-radius: 7px; }
.design-swatch-depth i:nth-child(1) { flex-grow: 2; height: 100%; } .design-swatch-depth i:nth-child(2) { height: 72%; } .design-swatch-depth i:nth-child(3) { height: 72%; }
.design-preset-say { font-size: 12.5px; font-weight: 400; line-height: 1.38; color: var(--muted); }
.design-preset-ready { font-size: 12px; font-weight: 600; line-height: 1.35; color: var(--text); }
.design-preset.active .design-preset-ready { color: var(--primary-2); }
/* образец показывает шаблон В ТЕКУЩЕЙ теме: в светлой «Штиль» и «Глубина» тоже светлые */
html[data-theme="light"] .design-swatch-classic { background: #eef1f7; border-color: #c5cddd; }
html[data-theme="light"] .design-swatch-classic i { background: #d3dbf2; }
html[data-theme="light"] .design-swatch-depth { background: radial-gradient(120% 140% at 18% 0%, rgba(127,183,244,.85), rgba(127,183,244,0) 60%), radial-gradient(90% 120% at 100% 100%, rgba(159,232,218,.6), rgba(159,232,218,0) 60%), #F3F4FB; border-color: #d9d6e6; }
html[data-theme="light"] .design-swatch-depth i { background: rgba(255,255,255,.72); box-shadow: inset 0 0 0 1px rgba(24,24,39,.10); }

/* ── СВЕТЛАЯ ТЕМА: переопределение токенов ────────────────────────────────────
   html[data-theme="light"] (0,1,1) перебивает :root (0,1,0). --border/--input-bg
   в :root = var(--line)/var(--panel-2) → сами подхватывают светлые значения. */
html[data-theme="light"] {
  /* Палитра admin.html (выбор владельца 15.09.2026): нейтральная канва, белые карточки,
     нейтральные границы и тени. Та же семья, что у боевого concept-6 и CcColors.light. */
  --bg: #f5f5f7;          /* канва: светлая, белые панели/карточки на ней читаются */
  --panel: #ffffff;       /* ур.1: карточки/панели/топбар/модалки/пузырь собеседника */
  --panel-2: #f5f5f7;     /* инсеты ВНУТРИ белого: табы, чипы, поиск, подложки */
  /* Единый таб/сегмент (CLIE-249) */
  --seg-track: #f5f5f7;
  --seg-thumb: #ffffff;
  --seg-thumb-bd: rgba(0,0,0,.07);
  --seg-thumb-sh: 0 1px 2px rgba(0,0,0,.12), 0 2px 6px rgba(0,0,0,.08);
  --seg-div: rgba(0,0,0,.07);
  --panel-3: #ffffff;     /* ур.2 ПОДНЯТОЕ (меню/тултипы/поповеры) = белый + --shadow-2 */
  /* 🔴 Тот же разбор, что в concept-6.css: хэйрлайн ОБЯЗАН быть виден и на холсте, и на
     белой карточке. Было #e7ebf3 на холсте #eef1f7 = 1.056 — граница есть в коде и нет
     на экране. Ориентир — системная линия macOS/iOS (#C6C6C8 на белом = 1.706), берём мягче.
     Сторож меряет это числом: tools/design_lint.js → CONTRAST. */
  --line: #dedee3;        /* нейтральный хэйрлайн на холсте и белой карточке */
  --line-strong: #c6c6c8; /* границы контролов / hover */
  --text: #1d1d1f;        /* основной тёмный текст */
  --muted: #5c5c61;       /* нейтральные вторичные чернила, AA и на серой подложке */
  /* select-chevron-ink-light-1 · шеврон селекта светлой темы — чернила светлого --muted #5c5c61: 6.11:1 на
     заливке поля #f5f5f7 (--input-bg / --panel-2), 6.65:1 на белом. Было #8b93a3 тёмной палитры — 2.84:1 и 3.09:1. */
  --sel-chev: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235c5c61' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  --sel-chev-sm: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%235c5c61' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  --sel-chev-b: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%235c5c61' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E");
  --text-dim: #636368;    /* третичный: плейсхолдеры/мета/счётчики */
  --primary: #0071e3;     /* синий акцент с белым текстом */
  --primary-2: #005bb8;   /* глубокий синий: имена/цитаты/текстовые акценты */
  --primary-hi: #0066cc;  /* hover primary: в светлой — темнее, не светлее */
  --accent: var(--primary);
  --input-bg: #f5f5f7;    /* поле УТОПЛЕНО в белую карточку; :focus «всплывает» до #fff (§3) */
  --glow: rgba(0,113,227,.20);
  /* состояния: hover нейтральный, голубой тинт ТОЛЬКО у выбранного (экономия бренда) */
  --hover: rgba(0,0,0,.05);
  --active: rgba(0,0,0,.09);
  --sel: rgba(0,113,227,.10);
  /* тени: двухслойные ambient+key, нейтральные (A — «воздух», не давит) */
  --shadow-1: 0 1px 2px rgba(0,0,0,.04), 0 6px 20px rgba(0,0,0,.06);
  --shadow-2: 0 4px 12px rgba(0,0,0,.08), 0 16px 34px -8px rgba(0,0,0,.16);
  --shadow-3: 0 10px 24px rgba(0,0,0,.12), 0 36px 72px -12px rgba(0,0,0,.24);
  --edge: inset 0 0 0 0 transparent;
  --scrim: rgba(0,0,0,.50);
  /* семантика: текст ≥AA на белом и на своей -soft подложке */
  --danger: #c53a56;      --danger-soft: rgba(197,58,86,.12);
  --ok: #1a7a4a;          --ok-soft: rgba(26,122,74,.12);
  --warning: #9a6a00;     --warning-soft: rgba(154,106,0,.13);
  --info: var(--cm-2f5bd0, #2f5bd0);        --info-soft: var(--cm-2f5bd0-12, rgba(47,91,208,.12));
  --urg-overdue: #c53a56; --urg-overdue-soft: rgba(197,58,86,.12);
  --urg-today: #9a6a00;   --urg-today-soft: rgba(154,106,0,.13);
  --urg-done: #1a7a4a;    --urg-done-soft: rgba(26,122,74,.12);
  --mine: var(--cm-ebedff, #ebedff);        /* тинт свайп-ответа/цитаты «моего» (сам пузырь = --grad) */
  --theirs: #ffffff;      /* пузырь собеседника — белый (на глубокой канве читается сам) */
  --system: #eeeef0;      /* системное сообщение — нейтральное */
  --grad: linear-gradient(135deg,#0071e3 0%,#0066cc 100%);
  /* Приглушённые сообщения отдельно от синего акцента кнопок. */
  --bub-fill: linear-gradient(135deg,var(--cm-565be8, #565be8) 0%,var(--cm-4c51d5, #4c51d5) 100%);
  color-scheme: light;
}

/* ── СВЕТЛАЯ ТЕМА: точечные фиксы хардкод-цветов (аудит) ─────────────────────── */
html[data-theme="light"] .msg.system .bubble { color: var(--muted); }
html[data-theme="light"] .msg.theirs .bubble { border-color: var(--line); }
html[data-theme="light"] .msg.theirs .reply-quote { background: rgba(0,0,0,.07); }
html[data-theme="light"] .msg.theirs .att-file .att-file-dl:hover { background: rgba(0,0,0,.10); }
html[data-theme="light"] .link-preview { background: rgba(0,0,0,.06); }
html[data-theme="light"] .drop-overlay { background: rgba(232,236,244,.88); }
/* .chat-rail светлый — ЕДИНСТВЕННОЕ правило в §3.11 (дубль тут удалён, чтобы правки не маскировались). */
/* автоскрытие: прозрачный по умолчанию, красится на :hover блока (см. §3.10) */
html[data-theme="light"] *::-webkit-scrollbar-thumb { background: transparent; }
html[data-theme="light"] *:hover::-webkit-scrollbar-thumb { background: rgba(0,0,0,.30); }
html[data-theme="light"] *::-webkit-scrollbar-thumb:hover { background: rgba(0,0,0,.48); }
@supports (-moz-appearance: none) {
  html[data-theme="light"] * { scrollbar-color: transparent transparent; }
  html[data-theme="light"] *:hover { scrollbar-color: rgba(0,0,0,.34) transparent; }
}
html[data-theme="light"] .ai-msg.bot.err .ai-bubble { background: #fdecec; color: #b3261e; }
html[data-theme="light"] .ai-msg.bot .ai-msg-file { background: rgba(0,0,0,.06); }
html[data-theme="light"] .ai-chat-item:hover { background: rgba(0,0,0,.06); }
html[data-theme="light"] .ai-chat-del:hover { background: rgba(0,0,0,.10); }
html[data-theme="light"] .ai-chat-arch:hover { background: rgba(0,0,0,.10); }
html[data-theme="light"] .attach-menu button:hover { background: rgba(0,0,0,.07); }
html[data-theme="light"] .sp-tabs { background: var(--panel-2); }
html[data-theme="light"] .sp-cell:hover { background: rgba(0,0,0,.06); }
html[data-theme="light"] .sp-tab:hover { background: rgba(0,0,0,.06); }
html[data-theme="light"] .sp-pv-fav.on { color: #b26f0d; border-color: #b26f0d66; }
html[data-theme="light"] .tw-pill.status-open { color: #4d5a70; }
html[data-theme="light"] .tw-pill.status-in_progress { color: var(--cm-1d4ed8, #1d4ed8); }
html[data-theme="light"] .tw-pill.status-done { color: #166534; }
html[data-theme="light"] .tw-pill.status-cancelled { color: #4d5a70; }
html[data-theme="light"] .tw-pill.due-today { color: #854d0e; }
html[data-theme="light"] .tip-link-rel:where(:not(.lt-blocks, .lt-blocked, .lt-duplicate)), html[data-theme="light"] .rel-status { color: #4d5a70; } /* CLIE-1946: «блокирует/заблокирована/дубль» держат свой цвет */
html[data-theme="light"] .rel-status.s-in_progress { color: var(--cm-1d4ed8, #1d4ed8); }
html[data-theme="light"] .rel-status.s-done { color: #166534; }
html[data-theme="light"] .rel-status.s-cancelled { color: #4d5a70; }
html[data-theme="light"] .tip-files-card .tf-thumb { background: var(--panel-2); border: 1px solid var(--line); }
html[data-theme="light"] .tip-files-card .tf-row { background: var(--panel-2); }
html[data-theme="light"] .tip-files-card .tf-row:hover { background: var(--active); }
html[data-theme="light"] .tip-files-card .tf-empty-sub { opacity: 1; } /* CLIE-1946: инлайн-стиль .8 на светлом = 3.87:1 */

/* ─── Единый клик по пользователю → профиль (data-profile-uid делегат в app.js) ───
   Любой аватар/имя/чип с этим атрибутом кликабелен и ведёт в ПОЛНЫЙ профиль. */
[data-profile-uid] { cursor: pointer; }
[data-profile-uid]:hover { opacity: .86; }
.prof-hit { cursor: pointer; }
/* Внутренняя обёртка аватар+имя внутри чипа: сохраняем flex-gap, который давал контейнер
   чипа (.td-asg/.v2-asg), т.к. кнопка «убрать» теперь сиблинг обёртки, а не в одном ряду. */
.prof-inline { display: inline-flex; align-items: center; gap: 6px; }

/* ─── @УПОМИНАНИЯ ─────────────────────────────────────────────────────────────
   Чип упоминания в тексте сообщения, пикер участников над полем и знак «@» у
   беседы в списке чатов («вас упомянули — посмотрите»). */
.msg-mention {
  color: var(--accent, var(--cm-667eea, #667eea));
  font-weight: 700;
  cursor: pointer;
  background: color-mix(in srgb, var(--accent, var(--cm-667eea, #667eea)) 18%, transparent);
  border-radius: 5px;
  padding: 0 3px;
  white-space: nowrap;
}
/* Упомянули МЕНЯ — ярче (акцентный фон, контрастный текст). */
.msg-mention-me {
  background: var(--acc-fill, var(--cm-667eea, #667eea));
  color: #fff;
}
/* 🔴 НА СВОЁМ (акцентном) пузыре акцентный текст сливается с фоном → белый чип на
   полупрозрачном белом (высокий контраст на любом градиенте пузыря). */
/* 🔴 упоминание внутри своего пузыря: подложка ТЕМНЕЕ заливки, иначе белые буквы на ней
   проваливаются (канон contrast-runtime-audit, «Контрастность» 10.09.2026). */
.msg.mine .bubble .msg-mention { color: #fff; background: var(--bub-tint); }
.msg.mine .bubble .msg-mention-me { color: #fff; background: var(--cm-0b1020-38, rgba(11,16,32,.38)); }
html[data-theme="light"] .msg-mention { color: var(--primary-2, var(--accent, #434dbb)); background: color-mix(in srgb, var(--accent, var(--cm-667eea, #667eea)) 16%, #fff); } /* CLIE-1946 · акцентный ТЕКСТ на тинте — --primary-2 (замер прода: «@Никита» 3.76) */
/* CLIE-1946 · светлый .msg-mention (0,2,1) перебивал заливку «меня» (0,1,0) — белые буквы на 16%-тинте, 1.25:1 */
html[data-theme="light"] .msg-mention-me { color: #fff; background: var(--acc-fill, var(--cm-667eea, #667eea)); }

/* Пикер участников (фикс-позиция, ставится над полем ввода из app.js). */
.mention-menu {
  position: fixed;
  z-index: 9400;
  background: var(--panel, var(--cm-171a21, #171a21));
  border: 1px solid var(--line, #2a2f3a);
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0,0,0,.4);
  padding: 6px;
  overflow-y: auto;
  max-height: 264px;
}
.mention-menu.hidden { display: none; }
.mention-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 9px;
  border-radius: 9px;
  cursor: pointer;
}
.mention-item.active, .mention-item:hover { background: var(--panel-2, #1e222b); }
.mention-av {
  width: 30px; height: 30px;
  border-radius: 50%;
  background-size: cover; background-position: center;
  flex: 0 0 auto;
}
.mention-av-ph {
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; font-size: 13px; font-weight: 700;
}
/* ✨ «Ая в чате» (12.10.2026): Ая — участник без профиля. Аватар-искра в пикере, чип со
   звёздочкой в тексте, пометка «Видно только вам» у личных сообщений и окно поверх чата. */
.mention-av-aya {
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff; background: var(--acc-fill, var(--cm-6d6af8, #6d6af8));
}
.mention-av-aya svg { width: 16px; height: 16px; }
.msg-mention-aya { cursor: default; display: inline-flex; align-items: center; gap: 2px; }
.msg-mention-aya svg { width: 12px; height: 12px; }
.msg-only-you {
  display: inline-flex; align-items: center; gap: 4px; margin: 3px 2px 0;
  font-size: 11.5px; color: var(--muted, #9aa0a6);
}
.msg.mine .msg-only-you { align-self: flex-end; }
.msg-only-you svg { width: 11px; height: 11px; }
/* Окно Аи поверх чата: рама fixed во весь экран, но мышь ловит только само окно. */
.cc-aya-chat-host { position: fixed; inset: 0; z-index: 9200; pointer-events: none; }
.cc-aya-chat-host .cc-aya-fab { display: none !important; }
.cc-aya-chat-host .cc-aya-pop { pointer-events: auto; }
.mention-name {
  font-size: 14px; font-weight: 500; color: var(--text, #e6e8ec);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Секции пикера @упоминаний + шаг «кем добавить» (CLIE-413) ─────────────────
   Список людей разложен по группам «Участники задачи / Участники проекта /
   Сотрудники компании / Другие пользователи» — ТОТ ЖЕ визуальный язык, что у
   секций пикера соисполнителей (.up-sec): тонкий аптечный заголовок, мягкая
   пилюля роли справа. Выбор человека, которого в задаче нет, разворачивает то
   же меню во второй шаг с тремя вариантами. Все цвета — через переменные темы,
   поэтому светлая и тёмная одинаково выверены. */
.mention-sec { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); padding: 10px 8px 3px; user-select: none; pointer-events: none; }
.mention-sec:first-child { padding-top: 2px; }
.mention-item .mention-name { flex: 0 1 auto; min-width: 0; }
.mention-role-b { flex: 0 0 auto; margin-left: auto; font-size: 11px; line-height: 1.35; padding: 2px 8px; border-radius: 999px; white-space: nowrap; max-width: 46%; overflow: hidden; text-overflow: ellipsis;
  border: 1px solid color-mix(in srgb, var(--rb, var(--muted)) 42%, transparent);
  color: color-mix(in srgb, var(--rb, var(--muted)) 78%, var(--text));
  background: color-mix(in srgb, var(--rb, var(--muted)) 13%, transparent); }
/* Пустой результат поиска: заголовок читаемым цветом + тихая подсказка второй строкой —
   меню больше НЕ исчезает молча (это выглядело как «поиск не работает»). */
.mention-empty { padding: 10px; font-size: 13px; color: var(--text); line-height: 1.3; }
.mention-empty small { display: block; margin-top: 3px; font-size: 11.5px; color: var(--muted); }
.mention-head { display: flex; align-items: center; gap: 8px; padding: 2px 6px 8px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
.mention-back { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; flex: 0 0 auto; border: 0; border-radius: 8px; background: transparent; color: var(--muted); cursor: pointer; transition: background .13s ease, color .13s ease; }
.mention-back:hover { background: var(--panel-2); color: var(--text); }
.mention-back .ic { width: 16px; height: 16px; }
.mention-hint { font-size: 11.5px; color: var(--muted); padding: 0 8px 6px; }
.mention-item.mention-role { align-items: center; }
.mention-ric { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; flex: 0 0 auto; border-radius: 9px; background: var(--panel-2); color: var(--primary); }
.mention-ric .ic { width: 16px; height: 16px; }
.mention-role .mention-name { display: flex; flex-direction: column; gap: 1px; white-space: normal; overflow: visible; }
.mention-role .mention-name small { font-size: 11.5px; font-weight: 400; color: var(--muted); }
/* Запрос «добавить» ушёл — строка занята: гасим её и снимаем hover, чтобы двойной клик
   не читался как «не сработало». Упоминание вставится ТОЛЬКО после ответа сервера. */
.mention-item.busy { opacity: .55; pointer-events: none; }

/* ═══════════ «/»-ссылки: чип-ссылка в сообщении + меню вставки над полем ═══════════
   Чип (задача/тикет/чат/пользователь/событие/клиент/проект) — иконка + заголовок,
   кликабелен (openRef). Меню над полем: список типов → живой поиск сущностей. */
.msg-ref {
  display: inline-flex; align-items: center; gap: 4px;
  vertical-align: bottom; max-width: 100%;
  padding: 1px 7px 1px 5px; border-radius: 7px;
  font-weight: 600; cursor: pointer; text-decoration: none;
  color: var(--accent, var(--cm-667eea, #667eea));
  background: color-mix(in srgb, var(--accent, var(--cm-667eea, #667eea)) 15%, transparent);
  line-height: 1.35;
}
.msg-ref:hover { background: color-mix(in srgb, var(--accent, var(--cm-667eea, #667eea)) 26%, transparent); }
.msg-ref .msg-ref-ic { display: inline-flex; flex: 0 0 auto; }
.msg-ref .msg-ref-ic .ic { width: 14px; height: 14px; }
.msg-ref .msg-ref-tx { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 240px; }
/* На своём (акцентном) пузыре — белый чип на полупрозрачном белом (контраст на градиенте). */
.msg.mine .bubble .msg-ref { color: #fff; background: rgba(255, 255, 255, .22); }
.msg.mine .bubble .msg-ref:hover { color: #fff; background: rgba(255, 255, 255, .34); }
html[data-theme="light"] .msg-ref:where(:not(.ai-self)) { background: color-mix(in srgb, var(--accent, var(--cm-667eea, #667eea)) 14%, #fff); } /* CLIE-1946: чип куска ИИ — свой сланцевый тинт (AISELF_LOOK) */

/* Меню вставки «/» (фикс-позиция, ставится над полем ввода из app.js). */
.ref-menu {
  position: fixed; z-index: 9400;
  background: var(--panel, var(--cm-171a21, #171a21));
  border: 1px solid var(--line, #2a2f3a);
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .4);
  padding: 6px;
  /* Меню = закреплённая шапка + список. Скроллит ТОЛЬКО .ref-list (один скроллбар),
     сама коробка не скроллит. 🔴 Список сутей (15 шт.) в высоту меню НЕ влезает — и это
     нормально ровно до тех пор, пока у обрезки есть ПРИЗНАК: без него меню читается как
     «тут всё, что есть» (на этом уже горели в приложении, CLIE-443).
     🔴 Признак берём КАНОНИЧЕСКИЙ, своего не заводим: `.cc-scroll-in` из реестра
     `SCROLL_IN_SEL` (CLIE-620 · CLIE-1116) — он и бегунок делает видимым (в продукте тот
     ПРОЗРАЧЕН до наведения), и подтапливает край краской, а не маской, и показывает ОБА
     края («выше есть ещё» тоже). Меню вставки — ровно тот случай, ради которого реестр и
     заведён: каталог с осознанным капом высоты. */
  display: flex; flex-direction: column;
  max-height: min(72vh, 480px); overflow: hidden;
}
.ref-menu.hidden { display: none; }
.ref-head {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 8px 8px; margin-bottom: 4px;
  border-bottom: 1px solid var(--line, #2a2f3a);
}
.ref-head-ic { display: inline-flex; flex: 0 0 auto; color: var(--text-dim, #9aa4b2); }
.ref-head-ic .ic { width: 18px; height: 18px; }
/* Поле поиска команд-палитры — «голое», сливается с шапкой меню; фокус живёт в нём. */
.ref-search-input {
  flex: 1 1 auto; min-width: 0;
  background: transparent; border: none; outline: none;
  color: var(--text, #e6e8ec); font: inherit; font-size: 15px;
  padding: 4px 2px;
}
.ref-search-input::placeholder { color: var(--text-dim, #9aa4b2); }
.ref-back {
  background: none; border: none; cursor: pointer; padding: 3px;
  display: inline-flex; border-radius: 6px; color: var(--text-dim, #9aa4b2); flex: 0 0 auto;
}
.ref-back:hover { background: var(--panel-2, #1e222b); color: var(--text, #e6e8ec); }
.ref-back .ic { width: 18px; height: 18px; }
/* `overflow` здесь намеренно НЕ дублируем — он приезжает каноном `.cc-scroll-in`
   (класс вешает app.js, реестр `SCROLL_IN_SEL`), вместе с видимым бегунком и краями. */
.ref-list { flex: 0 1 auto; min-height: 0; }
.ref-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 9px; border-radius: 9px; cursor: pointer;
}
.ref-row.active, .ref-row:hover { background: var(--panel-2, #1e222b); }
.ref-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; flex: 0 0 auto; color: var(--accent, var(--cm-667eea, #667eea));
}
.ref-ic .ic { width: 18px; height: 18px; }
.ref-av {
  width: 26px; height: 26px; border-radius: 50%; flex: 0 0 auto;
  background-size: cover; background-position: center; background-color: var(--panel-2, #1e222b);
}
.ref-main { display: flex; flex-direction: column; min-width: 0; flex: 1 1 auto; }
.ref-label {
  font-weight: 600; color: var(--text, #e6e8ec);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ref-sub {
  font-size: 12px; color: var(--text-dim, #9aa4b2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ref-chevron { display: inline-flex; color: var(--text-dim, #9aa4b2); flex: 0 0 auto; }
.ref-chevron .ic { width: 16px; height: 16px; }
.ref-empty { padding: 14px 10px; text-align: center; color: var(--text-dim, #9aa4b2); }
/* ⚡ Быстрый ответ в «/»-меню: ключ-ярлык и акцентная иконка (обе темы через --primary). */
.ref-key {
  display: inline-block; margin-left: 6px; padding: 0 6px;
  border: 1px solid var(--line, #2a2f3a); border-radius: 6px;
  font-size: 11px; font-weight: 600; line-height: 16px;
  color: var(--primary, var(--cm-667eea, #667eea)); vertical-align: middle;
}
.ref-ic-quick { color: var(--primary, var(--cm-667eea, #667eea)); }

/* ⚡ Менеджер быстрых ответов (Настройки → «Шаблоны сообщений») — обе темы через переменные */
.mtpl-mgr { display: flex; flex-direction: column; gap: 14px; max-width: 720px; }
.mtpl-hint { font-size: 13px; color: var(--muted, #9aa4b2); line-height: 1.55; }
.mtpl-hint code { background: var(--panel-2, #1e222b); border: 1px solid var(--line, #2a2f3a); border-radius: 5px; padding: 0 5px; font-size: 12px; }
.mtpl-add { display: inline-flex; align-items: center; gap: 8px; align-self: flex-start; padding: 9px 14px; border: 1px solid var(--line, #2a2f3a); border-radius: 10px; background: var(--panel-2, #1e222b); color: var(--text, #e6e8ec); font: inherit; font-weight: 600; cursor: pointer; transition: background .13s ease, border-color .13s ease; }
.mtpl-add:hover { background: var(--hover, rgba(127,127,127,.09)); border-color: var(--primary, var(--cm-667eea, #667eea)); }
.mtpl-add .ic { width: 18px; height: 18px; }
.mtpl-list { display: flex; flex-direction: column; gap: 12px; }
.mtpl-card { border: 1px solid var(--line, #2a2f3a); border-radius: 14px; background: var(--panel, var(--cm-171a21, #171a21)); padding: 12px 12px 10px; display: flex; flex-direction: column; gap: 6px; transition: border-color .13s ease; }
.mtpl-card:focus-within { border-color: var(--primary, var(--cm-667eea, #667eea)); }
.mtpl-title { border: 0; background: transparent; color: var(--text, #e6e8ec); font: inherit; font-weight: 600; font-size: 15px; padding: 2px 0; outline: none; }
.mtpl-body { border: 0; background: transparent; color: var(--text, #e6e8ec); font: inherit; font-size: 14px; line-height: 1.5; resize: vertical; min-height: 42px; outline: none; }
.mtpl-ctl { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding-top: 8px; margin-top: 2px; border-top: 1px solid var(--line, #2a2f3a); }
.mtpl-key { display: inline-flex; align-items: center; gap: 2px; border: 1px solid var(--line, #2a2f3a); border-radius: 8px; padding: 4px 8px; color: var(--muted, #9aa4b2); }
.mtpl-key span { color: var(--primary, var(--cm-667eea, #667eea)); font-weight: 700; }
.mtpl-key input { border: 0; background: transparent; color: var(--text, #e6e8ec); font: inherit; font-size: 13px; width: 92px; outline: none; }
/* CLIE-505: область видимости шаблона = канон .cc-seg + .cc-seg-md (стоит в одном ряду
   с полем-ключом и select'ом проекта). Была плотная brand-заливка выбранного — свой вид. */
.mtpl-proj { border: 1px solid var(--line, #2a2f3a); border-radius: 8px; background-color: var(--panel-2, #1e222b); color: var(--text, #e6e8ec); font: inherit; font-size: 13px; padding: 5px 34px 5px 8px; outline: none; max-width: 170px; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.mtpl-status { font-size: 12px; color: var(--muted, #9aa4b2); }
.mtpl-status.ok { color: #37c871; }
.mtpl-del { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--muted, #9aa4b2); cursor: pointer; transition: background .12s ease, color .12s ease; }
.mtpl-del:hover { background: rgba(255,90,90,.12); color: #ff5a5a; }
.mtpl-del .ic { width: 16px; height: 16px; }
.mtpl-empty { text-align: center; padding: 30px 16px; color: var(--muted, #9aa4b2); }
.mtpl-empty-ico { display: inline-flex; color: var(--primary, var(--cm-667eea, #667eea)); }
.mtpl-empty-ico .ic { width: 30px; height: 30px; }
.mtpl-empty-t { font-weight: 600; color: var(--text, #e6e8ec); margin-top: 8px; }
.mtpl-empty-s { font-size: 13px; margin-top: 4px; line-height: 1.5; }
.mtpl-others { margin-top: 4px; }
.mtpl-others-h { font-size: 11.5px; color: var(--muted, #9aa4b2); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 8px; }
.mtpl-other { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border: 1px solid var(--line, #2a2f3a); border-radius: 10px; margin-bottom: 6px; }
.mtpl-other-ic { color: var(--primary, var(--cm-667eea, #667eea)); display: inline-flex; } .mtpl-other-ic .ic { width: 16px; height: 16px; }
.mtpl-other-tx { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 13px; color: var(--text, #e6e8ec); }
.mtpl-other-tx b { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mtpl-other-tx i { font-style: normal; color: var(--muted, #9aa4b2); font-size: 12px; margin-left: auto; }
.mtpl-load { display: flex; justify-content: center; padding: 34px; }
/* 💬 CLIE-1847·⑩ · папки, поиск, вид «Ответы | Приглашения», метка набора — тот же менеджер в
   Настройках и во вкладке «Шаблоны» онлайн-чата. Только токены — обе темы. */
.mtpl-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.mtpl-q { flex: 1 1 220px; display: flex; align-items: center; gap: 8px; height: var(--ctl-h, 34px); box-sizing: border-box; padding: 0 10px; border: 1px solid var(--line, #2a2f3a); border-radius: 10px; background: var(--panel-2, #1e222b); color: var(--muted, #9aa4b2); transition: border-color .13s ease; }
.mtpl-q:focus-within { border-color: var(--primary, var(--cm-667eea, #667eea)); }
.mtpl-q .ic { width: 16px; height: 16px; flex: 0 0 auto; }
.mtpl-q input { flex: 1 1 auto; min-width: 0; border: 0; background: transparent; color: var(--text, #e6e8ec); font: inherit; font-size: 14px; outline: none; }
.mtpl-kinds { flex: 0 0 auto; }
.mtpl-folds { display: flex; gap: 6px; flex-wrap: wrap; }
.mtpl-fold { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 11px; border: 1px solid var(--line, #2a2f3a); border-radius: 999px; background: transparent; color: var(--text, #e6e8ec); font: inherit; font-size: 13px; cursor: pointer; transition: background .13s ease, border-color .13s ease, color .13s ease; }
.mtpl-fold span { font-size: 11.5px; color: var(--muted, #9aa4b2); font-variant-numeric: tabular-nums; }
.mtpl-fold:hover { background: var(--hover, rgba(127,127,127,.09)); }
.mtpl-fold.on { border-color: color-mix(in srgb, var(--primary, var(--cm-667eea, #667eea)) 45%, transparent); background: color-mix(in srgb, var(--primary, var(--cm-667eea, #667eea)) 13%, transparent); color: var(--primary, var(--cm-667eea, #667eea)); font-weight: 600; }
.mtpl-fold.on span { color: inherit; opacity: .75; }
/* CLIE-1946 · светлая: выбранная папка и её счёт — --primary-2 целиком (было 3.63 и 2.63:1). */
html[data-theme="light"] .mtpl-fold.on { color: var(--primary-2); }
html[data-theme="light"] .mtpl-fold.on span { opacity: 1; }
.mtpl-row1 { display: flex; align-items: center; gap: 8px; }
.mtpl-row1 .mtpl-title { flex: 1 1 auto; min-width: 0; }
.mtpl-seed { flex: 0 0 auto; font-size: 11px; font-weight: 600; letter-spacing: .02em; padding: 2px 8px; border-radius: 999px; color: var(--muted, #9aa4b2); background: var(--panel-2, #1e222b); border: 1px solid var(--line, #2a2f3a); }
.mtpl-folder { display: inline-flex; align-items: center; gap: 5px; border: 1px solid var(--line, #2a2f3a); border-radius: 8px; padding: 4px 8px; color: var(--muted, #9aa4b2); }
.mtpl-folder .ic { width: 14px; height: 14px; }
.mtpl-folder input { border: 0; background: transparent; color: var(--text, #e6e8ec); font: inherit; font-size: 13px; width: 110px; outline: none; }
.mtpl-more { font-size: 12.5px; color: var(--muted, #9aa4b2); text-align: center; padding: 6px 0; }
.mtpl-err { font-size: 13px; color: var(--danger, #ff5a5a); display: flex; align-items: center; gap: 8px; }
.mtpl-reset { margin-top: 10px; }
.wc-tpl-host { margin-top: 4px; }
.wc-tpl-host.mtpl-mgr { max-width: none; }
/* 📥 CLIE-1847·Н2 · у быстрого ответа — хваталка ручного порядка и свёрнутый блок «Клавиша,
   события, действия, файлы»: Alt+1…9, ещё ключи «/», при каких событиях обращения предлагать,
   что шаблон САМ делает с обращением после отправки, файлы из «Файлов». Только токены — обе темы. */
.mtpl-grip { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 28px; margin-left: -4px; border-radius: 6px; color: var(--muted, #9aa4b2); cursor: grab; opacity: 0; touch-action: none; transition: opacity .13s ease, background .13s ease; }
.mtpl-card:hover .mtpl-grip { opacity: .8; }
.mtpl-grip:hover { opacity: 1; background: var(--hover, rgba(127,127,127,.09)); }
.mtpl-grip .ic, .mtpl-grip svg { width: 15px; height: 15px; }
@media (hover: none) { .mtpl-grip { opacity: .7; } }
.mtpl-list.mtpl-reordering { cursor: grabbing; user-select: none; -webkit-user-select: none; touch-action: none; }
.mtpl-card.mtpl-lift { border-color: var(--primary, var(--cm-667eea, #667eea)); box-shadow: var(--shadow-2, 0 10px 30px rgba(0,0,0,.18)); }
.mtpl-card.mtpl-lift .mtpl-grip { opacity: 1; cursor: grabbing; }
.mtpl-x { margin-top: 2px; }
.mtpl-x > summary { list-style: none; display: inline-flex; align-items: center; gap: 7px; height: 28px; padding: 0 10px 0 8px; border-radius: 8px; color: var(--muted, #9aa4b2); font-size: 12.5px; font-weight: 500; cursor: pointer; user-select: none; transition: background .13s ease, color .13s ease; }
.mtpl-x > summary::-webkit-details-marker { display: none; }
.mtpl-x > summary:hover { background: var(--hover, rgba(127,127,127,.09)); color: var(--text, #e6e8ec); }
.mtpl-x > summary .ic, .mtpl-x > summary svg { width: 14px; height: 14px; }
.mtpl-x[open] > summary { color: var(--text, #e6e8ec); }
.mtpl-x-n { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; box-sizing: border-box; border-radius: 9px; background: color-mix(in srgb, var(--primary, var(--cm-667eea, #667eea)) 16%, transparent); color: var(--primary, var(--cm-667eea, #667eea)); font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; }
.mtpl-x-h { margin: 14px 0 6px; font-size: 11.5px; font-weight: 600; letter-spacing: .03em; text-transform: uppercase; color: var(--muted, #9aa4b2); }
.mtpl-x-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); gap: 8px 10px; margin-top: 8px; }
.mtpl-x-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mtpl-x-f > span { font-size: 12px; color: var(--muted, #9aa4b2); }
.mtpl-x-wide { grid-column: span 2; }
@media (max-width: 520px) { .mtpl-x-wide { grid-column: auto; } }
.mtpl-x-f input, .mtpl-x-f select { width: 100%; min-width: 0; height: var(--ctl-h, 34px); box-sizing: border-box; padding: 0 10px; border: 1px solid var(--line, #2a2f3a); border-radius: 8px; background-color: var(--panel-2, #1e222b); color: var(--text, #e6e8ec); font: inherit; font-size: 13px; outline: none; transition: border-color .13s ease; } .mtpl-x-f select { padding-right: 34px; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.mtpl-x-f input:focus, .mtpl-x-f select:focus { border-color: var(--primary, var(--cm-667eea, #667eea)); }
.mtpl-x-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.mtpl-x-chip { display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 11px 0 9px; border: 1px solid var(--line, #2a2f3a); border-radius: 999px; font-size: 13px; color: var(--text, #e6e8ec); cursor: pointer; user-select: none; transition: background .13s ease, border-color .13s ease, color .13s ease; }
.mtpl-x-chip:hover { background: var(--hover, rgba(127,127,127,.09)); }
.mtpl-x-chip input { width: 15px; height: 15px; margin: 0; accent-color: var(--primary, var(--cm-667eea, #667eea)); cursor: pointer; }
.mtpl-x-chip:has(input:checked) { border-color: color-mix(in srgb, var(--primary, var(--cm-667eea, #667eea)) 45%, transparent); background: color-mix(in srgb, var(--primary, var(--cm-667eea, #667eea)) 12%, transparent); color: var(--primary, var(--cm-667eea, #667eea)); }
.mtpl-x-files { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.mtpl-x-file { display: inline-flex; align-items: center; gap: 6px; max-width: 240px; height: 30px; padding: 0 4px 0 10px; box-sizing: border-box; border: 1px solid var(--line, #2a2f3a); border-radius: 8px; background: var(--panel-2, #1e222b); font-size: 12.5px; color: var(--text, #e6e8ec); }
.mtpl-x-file > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mtpl-x-file > .ic, .mtpl-x-file > svg { width: 13px; height: 13px; flex: 0 0 auto; color: var(--muted, #9aa4b2); }
.mtpl-x-file button { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 22px; height: 22px; border: 0; border-radius: 6px; background: transparent; color: var(--muted, #9aa4b2); cursor: pointer; transition: background .12s ease, color .12s ease; }
.mtpl-x-file button:hover { background: var(--hover, rgba(127,127,127,.09)); color: var(--danger, #ff5a5a); }
.mtpl-x-file button svg { width: 13px; height: 13px; }
.mtpl-x-files .ghost.small { display: inline-flex; align-items: center; gap: 6px; height: 30px; }
.mtpl-x-files .ghost.small svg { width: 14px; height: 14px; }

/* Знак «@» у беседы: вас упомянули (жёлто-акцентная пилюля рядом с бейджем). */
.conv-mention {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; box-sizing: border-box;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--acc-fill, var(--cm-667eea, #667eea));
  color: #fff;
  font-size: 12px; font-weight: 800; line-height: 1;
  flex: 0 0 auto;
}
/* 🔴 CLIE-1585: упоминание — акцентные ЧЕРНИЛА (4.31:1 → --primary-2). Тот же класс, что
   у активной беседы строкой выше: она этот токен уже берёт, а «есть упоминание» — нет. */
.conv-item.has-mention .conv-name { color: var(--primary-2, var(--accent, var(--cm-667eea, #667eea))); }

/* Единый профиль: строка действий Написать / Позвонить / Видео (паритет с Flutter). */
.user-profile-actions { display: flex; gap: 8px; margin: 4px 0 12px; }
.user-profile-actions button { flex: 1; min-width: 0; white-space: nowrap; }
/* Вкладки профиля пользователя: Профиль / Медиа */
.up-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); margin: 0 0 12px; }
.up-tab { flex: 1; background: transparent; border: 0; border-bottom: 2px solid transparent; color: var(--muted); font: inherit; font-size: 13.5px; font-weight: 600; padding: 9px 8px; cursor: pointer; margin-bottom: -1px; }
.up-tab:hover { color: var(--text); }
.up-tab.on { color: var(--primary-2); border-bottom-color: var(--primary); }

/* ═══════════════════════ Вид «Таймлайн» (Гант) ═══════════════════════ */
.tl-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.tl-tools { display: flex; align-items: center; gap: 12px; padding: 8px 14px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.tl-spacer { flex: 1; }
.tl-legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.tl-legend .lg { display: flex; align-items: center; gap: 6px; }
.tl-legend .sw { width: 20px; height: 10px; border-radius: 3px; display: inline-block; }
.tl-legend .sw.plan { background: var(--cm-4a5170, #4a5170); }
.tl-legend .sw.fact { height: 4px; background: rgba(255,255,255,.85); }
.tl-legend .sw.over { background: var(--urg-overdue); }
.tl-legend .sw.dep { width: 20px; height: 0; border: 0; border-top: 2px solid var(--primary); }
.tl-zoom { display: flex; gap: 2px; background: var(--panel-2); border-radius: 9px; padding: 3px; }
.tl-zoom button { border: 0; background: transparent; color: var(--muted); font-size: 12.5px; font-weight: 500; padding: 5px 11px; border-radius: 6px; cursor: pointer; }
.tl-zoom button:hover { color: var(--text); }
.tl-zoom button.on { background: var(--panel-3, var(--cm-232732, #232732)); color: var(--text); }
html[data-theme="light"] .tl-zoom { background: color-mix(in srgb, var(--bg) 92%, var(--text)); } /* CLIE-1946: дорожка = холст → тон дорожки колонки; белый «выбранный» на ней виден */
.tl-today { border: 1px solid var(--line); background: transparent; color: var(--primary-2); font-size: 12.5px; font-weight: 500; padding: 6px 12px; border-radius: 8px; cursor: pointer; }
.tl-today:hover { background: var(--panel-2); border-color: var(--primary); }

.tl-board { position: relative; overflow: auto; flex: 1; min-height: 260px; }
.tl-grid { position: relative; }
.tl-head { display: flex; position: sticky; top: 0; z-index: 8; background: var(--bg); }
.tl-railhead { width: 250px; min-width: 250px; position: sticky; left: 0; z-index: 9; background: var(--bg); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); display: flex; align-items: flex-end; padding: 0 14px 9px; font-size: 11px; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); font-weight: 600; }
.tl-axis { position: relative; border-bottom: 1px solid var(--line); }
.tl-mgroup { position: absolute; top: 7px; font-size: 11px; color: var(--muted); font-weight: 600; white-space: nowrap; padding-left: 7px; border-left: 1px solid var(--line); }
.tl-daycol { position: absolute; top: 28px; bottom: 0; border-left: 1px solid var(--line); display: flex; flex-direction: column; align-items: center; z-index: 0; }
.tl-daycol.wend { background: rgba(255,255,255,.014); }
.tl-dow { font-size: 10px; color: var(--muted); margin-top: 5px; text-transform: uppercase; font-weight: 600; }
.tl-dnum { font-size: 13px; color: var(--text); margin-top: 1px; opacity: .82; }
.tl-daycol.today .tl-dow, .tl-daycol.today .tl-dnum { color: var(--urg-today); opacity: 1; font-weight: 700; }

/* Режим «Часы»: часовые колонки одного дня + навигатор дня. */
.tl-daycol.work { background: var(--cm-7c8cf8-05, rgba(124,140,248,.05)); }               /* рабочие часы (9–19) */
.tl-daycol.nowh { background: rgba(229,162,60,.08); }                /* текущий час */
.tl-htime { font-size: 11px; color: var(--muted); margin-top: 7px; font-variant-numeric: tabular-nums; letter-spacing: -.2px; }
.tl-daycol.nowh .tl-htime { color: var(--urg-today); font-weight: 700; }
.tl-daycol.dayedge { border-left: 1px solid rgba(255,255,255,.16); }   /* граница суток (полночь) в непрерывной шкале «Часы» */
.tl-mgroup.today { color: var(--urg-today); }                                   /* подпись сегодняшнего дня */
.tl-daynav { display: flex; align-items: center; gap: 6px; }
.tl-daynav .tl-daybtn { border: 1px solid var(--line); background: transparent; color: var(--text); width: 26px; height: 26px; border-radius: 7px; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; }
.tl-daynav .tl-daybtn:hover { background: var(--panel-2); border-color: var(--primary); }
.tl-daynav .tl-daybtn svg { width: 15px; height: 15px; }
.tl-daylbl { font-size: 12.5px; font-weight: 600; color: var(--text); min-width: 132px; text-align: center; }
.tl-empty-day { padding: 44px 20px; text-align: center; color: var(--muted); font-size: 13.5px; line-height: 1.55; }

.tl-rows { position: relative; }
.tl-row { display: flex; position: relative; }
.tl-row:hover .tl-railcell { background: var(--panel); }
.tl-row:hover .tl-track { background: var(--cm-7c8cf8-05, rgba(124,140,248,.05)); }
.tl-railcell { width: 250px; min-width: 250px; position: sticky; left: 0; z-index: 6; background: var(--bg); border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 8px; padding-right: 12px; cursor: pointer; transition: background .14s ease; }
.tl-railcell:hover .tl-name { color: var(--primary-2); }
.tl-name { transition: color .12s ease; }
.tl-ind { flex: none; }
.tl-twist { flex: none; width: 18px; height: 18px; border: 0; background: transparent; color: var(--muted); cursor: pointer; display: flex; align-items: center; justify-content: center; border-radius: 5px; }
.tl-twist:hover { background: var(--panel-2); color: var(--text); }
.tl-twist svg { width: 13px; height: 13px; transition: transform .18s; }
.tl-twist.off svg { transform: rotate(-90deg); }
.tl-milemark { flex: none; color: var(--urg-today); font-size: 11px; }
.tl-stat { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.tl-name { font-size: 13.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 1; min-width: 0; }
.tl-name.done { color: var(--muted); text-decoration: line-through; }
.tl-railcell .tw-av { flex: none; }

.tl-track { flex: 1; position: relative; border-bottom: 1px solid var(--line); }
.tl-bar { position: absolute; height: 25px; top: 50%; transform: translateY(-50%); border-radius: 8px; z-index: 2; cursor: pointer; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,.3); user-select: none; touch-action: none; transition: box-shadow .16s ease, filter .16s ease; }
.tl-bar:active { cursor: grabbing; }
.tl-bar:hover { box-shadow: 0 0 0 2px var(--cm-7c8cf8-55, rgba(124,140,248,.55)), 0 4px 12px rgba(0,0,0,.4); filter: brightness(1.08); z-index: 4; }
.tl-bar .tl-fill { position: absolute; left: 0; top: 0; bottom: 0; background: rgba(255,255,255,.16); }
.tl-bar .tl-lbl { position: absolute; left: 9px; right: 12px; top: 0; bottom: 0; display: flex; align-items: center; font-size: 11.5px; font-weight: 600; color: #fff; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; z-index: 1; text-shadow: 0 1px 1px rgba(0,0,0,.35); }
.tl-bar.done { background: var(--urg-done); } .tl-bar.done .tl-lbl { color: #04342c; text-shadow: none; }
.tl-bar.wip { background: var(--cm-7c8cf8, #7c8cf8); }
.tl-bar.open { background: var(--cm-4a5170, #4a5170); }
/* подпись на тёмном #3a3f4d ФИКСИРОВАННАЯ (не var(--muted): в светлой muted тёмный → 1.5:1 нечитаемо) */
.tl-bar.cancelled { background: var(--cm-3a3f4d, #3a3f4d); } .tl-bar.cancelled .tl-lbl { color: rgba(255,255,255,.72); }
.tl-bar.over { box-shadow: inset 0 0 0 1.5px var(--urg-overdue), 0 1px 2px rgba(0,0,0,.35); }
.tl-bar .tl-handle { position: absolute; right: 0; top: 0; bottom: 0; width: 9px; cursor: ew-resize; z-index: 2; }
.tl-bar .tl-handle:hover { background: rgba(255,255,255,.22); }
.tl-overslice { position: absolute; top: 0; bottom: 0; right: 0; background: rgba(242,96,122,.55); z-index: 0; }
.tl-actual { position: absolute; height: 4px; bottom: 8px; background: rgba(255,255,255,.85); border-radius: 3px; z-index: 3; box-shadow: 0 0 0 1px rgba(0,0,0,.25); }
.tl-actual.over { background: var(--urg-overdue); }
.tl-parentbar { position: absolute; height: 9px; top: 50%; transform: translateY(-50%); z-index: 2; }
.tl-parentbar .pb { position: absolute; left: 0; right: 0; top: 1px; height: 7px; background: var(--primary); border-radius: 3px; opacity: .85; }
.tl-parentbar .cap { position: absolute; top: -2px; width: 2px; height: 13px; background: var(--primary); }
.tl-parentbar .cap.l { left: 0; } .tl-parentbar .cap.r { right: 0; }
.tl-mile { position: absolute; top: 50%; width: 15px; height: 15px; margin-left: -7px; transform: translateY(-50%) rotate(45deg); background: var(--urg-today); border-radius: 3px; z-index: 3; cursor: grab; box-shadow: 0 1px 3px rgba(0,0,0,.4); touch-action: none; }
.tl-mile:hover { box-shadow: 0 0 0 2px rgba(229,162,60,.5); }

.tl-deps { position: absolute; top: 0; left: 0; z-index: 3; pointer-events: none; overflow: visible; }
.tl-dep { fill: none; stroke: var(--primary-2); stroke-width: 1.6; opacity: .6; transition: stroke .15s ease, opacity .15s ease, stroke-width .15s ease; }
.tl-dep.hot { stroke: var(--primary); stroke-width: 2.4; opacity: 1; }
.tl-arrowhead { fill: context-stroke; }

.tl-nowline { position: absolute; top: 0; width: 0; border-left: 2px solid var(--urg-today); z-index: 4; pointer-events: none; box-shadow: 0 0 8px rgba(229,162,60,.4); }
.tl-nowline span { position: absolute; top: -1px; left: 6px; font-size: 10px; font-weight: 700; color: var(--urg-today); background: var(--bg); padding: 1px 4px; border-radius: 4px; }
.tl-nowline::before { content: ""; position: absolute; left: -4px; top: -1px; width: 8px; height: 8px; border-radius: 50%; background: var(--urg-today); }

.tl-tip { position: fixed; z-index: 200; background: var(--panel-3, var(--cm-232732, #232732)); border: 1px solid var(--line); border-radius: 10px; padding: 9px 12px; font-size: 12px; min-width: 190px; box-shadow: 0 12px 30px rgba(0,0,0,.5); pointer-events: none; opacity: 0; transform: translateY(4px); transition: opacity .12s, transform .12s; }
.tl-tip.on { opacity: 1; transform: translateY(0); }
.tl-tip .th { font-weight: 600; font-size: 13px; margin-bottom: 6px; }
.tl-tip .tr { display: flex; justify-content: space-between; gap: 16px; margin-top: 3px; color: var(--muted); }
.tl-tip .tr b { color: var(--text); font-weight: 500; }
.tl-tip .tr.f b { color: var(--cm-7c8cf8, #7c8cf8); } .tl-tip .tr.o b { color: var(--urg-overdue-ink); }
/* 🔎 Богатая подсказка таймлайна (CLIE-1672): статус · важность · метки · проект · счётчики ·
   план/факт/просрочка · готовность полосой · кто · время. Пилюли — ТЕ ЖЕ, что на карточке. */
.tl-tip { max-width: 360px; }
.tl-tip .th { display: flex; align-items: center; gap: 6px; }
.tl-tip-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.tl-tip-title { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-tip-code { flex: 0 0 auto; font-size: 10.5px; font-weight: 500; color: var(--muted); letter-spacing: .2px; }
.tl-tip-pills { display: flex; flex-wrap: wrap; gap: 4px; margin: 2px 0 6px; }
.tl-tip-pills .tw-pill { font-size: 10.5px; padding: 2px 6px; border-radius: 5px; max-width: 160px; }
.tl-tip-pills .tw-pill .tw-pill-main, .tl-tip-pills .tw-pill .tw-pill-sub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-tip-desc { margin: 0 0 7px; color: var(--muted); font-size: 11px; line-height: 1.35; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.tl-tip .tr > span { display: inline-flex; align-items: baseline; gap: 5px; min-width: 0; }
.tl-tip-why { font-style: normal; font-size: 10px; opacity: .7; }
.tl-tip-bar { height: 4px; margin: 5px 0 1px; border-radius: 3px; background: var(--line); overflow: hidden; }
.tl-tip-bar i { display: block; height: 100%; border-radius: 3px; background: var(--cm-7c8cf8, #7c8cf8); }
.tl-tip-bar.over i { background: var(--urg-overdue); }
.tl-tip-bar.done i { background: #5dcaa5; }
.tl-tip-who { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.tl-tip-who > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl-tip .tw-av { width: 18px; height: 18px; font-size: 9px; border-color: var(--panel-3); }
.tl-tip-foot { margin-top: 8px; padding-top: 6px; border-top: 1px solid var(--line); color: var(--muted); font-size: 10.5px; line-height: 1.3; }

.tl-undated { border-top: 1px solid var(--line); padding: 8px 14px; }
.tl-undated-h { width: 100%; background: transparent; border: 0; font: inherit; font-size: 12.5px; color: var(--muted); display: flex; align-items: center; gap: 7px; cursor: pointer; padding: 4px 0; text-align: left; }
.tl-undated-h:hover { color: var(--text); }
.tl-undated-h .tl-undated-t { font-weight: 500; }
.tl-undated-h svg { width: 13px; height: 13px; transition: transform .18s; transform: rotate(-90deg); }
.tl-undated.open .tl-undated-h svg { transform: none; }
.tl-undated-list { display: none; flex-wrap: wrap; gap: 8px; padding-top: 8px; }
.tl-undated.open .tl-undated-list { display: flex; }
.tl-urow { border: 1px solid var(--line); background: var(--panel); color: var(--text); font-size: 12.5px; padding: 5px 10px; border-radius: 8px; cursor: pointer; display: inline-flex; align-items: center; gap: 7px; }
.tl-urow:hover { border-color: var(--primary); }

.tl-undo-toast { position: fixed; left: 50%; bottom: 26px; transform: translateX(-50%) translateY(12px); z-index: 300; background: var(--panel-3, var(--cm-232732, #232732)); border: 1px solid var(--line); border-radius: 12px; padding: 11px 12px 11px 16px; display: flex; align-items: center; gap: 14px; box-shadow: 0 16px 40px rgba(0,0,0,.55); opacity: 0; pointer-events: none; transition: opacity .2s, transform .2s; }
.tl-undo-toast.show { opacity: 1; transform: translateX(-50%) translateY(0); pointer-events: auto; }
.tl-undo-toast button { border: 1px solid var(--line); background: transparent; color: var(--primary-2); font-size: 13px; font-weight: 600; padding: 5px 12px; border-radius: 8px; cursor: pointer; }
.tl-undo-toast button:hover { background: var(--panel-2); }

/* Карточка задачи: план/факт по времени (заложено vs затрачено) */
.tip-tm-planrow { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 3px 0; }
.tip-tm-lbl { font-size: 12px; color: var(--muted); }
.tip-tm-plan-v { display: flex; align-items: center; gap: 6px; }
.tip-tm-deltarow { margin-top: 6px; }
.tip-tm-delta { font-size: 12px; font-weight: 500; padding: 3px 9px; border-radius: 7px; display: inline-block; }
.tip-tm-delta.ok { background: var(--urg-done-soft); color: var(--urg-done); }
.tip-tm-delta.over { background: var(--urg-overdue-soft); color: var(--urg-overdue-ink); }

/* Карточка: редакторы оценки (ч/мин) и старта («После задачи»), подсказка в пикере связи */
.tip-est-edit, .tip-start-edit { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tip-est-sep { font-size: 12px; color: var(--muted); }
.tip-start-after { white-space: nowrap; }
.tip-start-after svg { width: 13px; height: 13px; }
.tip-link-hint { font-size: 12px; color: var(--muted); font-weight: 500; padding: 2px 0; }

/* Попап редактора «Начало»: понятный выбор — дата/время ИЛИ «после задачи» */
.td-userpick.tip-startpop { width: 300px; max-width: 92vw; max-height: none; padding: 12px; display: flex; flex-direction: column; align-items: stretch; gap: 8px; overflow: visible; box-sizing: border-box; }
.tip-startpop-h { font-size: 13px; font-weight: 600; color: var(--text); }
.tip-startpop-lbl { font-size: 11.5px; color: var(--muted); }
.tip-startpop-date { display: flex; gap: 8px; align-items: center; width: 100%; }
.tip-startpop-date input { flex: 1 1 0; min-width: 0; box-sizing: border-box; background: var(--input-bg); border: 1px solid var(--line); border-radius: 8px; padding: 8px 10px; color: var(--text); font: inherit; font-size: 13px; outline: none; }
.tip-startpop-date input:focus { border-color: var(--primary); }
.tip-startpop-date > button { flex: 0 0 auto; width: auto; }
.tip-startpop-or { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 11px; margin: 1px 0; }
.tip-startpop-or span { flex: none; }
.tip-startpop-or::before, .tip-startpop-or::after { content: ""; flex: 1; height: 1px; background: var(--line); }
.tip-startpop-after { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 11px 12px; color: var(--text); font: inherit; font-size: 13px; font-weight: 500; cursor: pointer; transition: border-color .14s, background .14s; }
.tip-startpop-after:hover { border-color: var(--primary); background: var(--panel); }
.tip-startpop-after svg { width: 16px; height: 16px; color: var(--primary-2); flex: none; }
.tip-startpop-clear { display: flex; align-items: center; justify-content: center; gap: 7px; width: 100%; background: transparent; border: 0; color: var(--muted); font: inherit; font-size: 12.5px; padding: 7px; border-radius: 8px; cursor: pointer; }
.tip-startpop-clear:hover { color: var(--urg-overdue-ink); background: var(--panel-2); }
.tip-startpop-clear svg { width: 14px; height: 14px; }

/* Никнейм (@username): вторичный идентификатор рядом с именем (Telegram-стиль).
   Тон акцента, чуть приглушён — виден как «@имя» под/рядом с display_name. */
.user-handle { color: var(--accent); opacity: .9; font-weight: 500; }
.mention-uname { margin-left: 6px; color: var(--accent); opacity: .9; }
#userProfileHandle { color: var(--accent); opacity: .95; margin-top: 2px; }

/* ── Баннер статуса уведомлений (fixed внизу) — чтобы «просто не приходят» не оставалось
      незамеченным. Понятный текст + кнопка «Включить» / «Как включить». ─────────────── */
/* 🔴 ЗАЗОР ПОД ЛЕВУЮ РЕЙКУ (замер прода 05.10.2026): при `left: 0` полоса ложилась НА
      рейку (z-index 9500), а у рейки внизу прижат хвост с «Аей» — `elementFromPoint` в
      центре ряда «Ая» отдавал #notifyBanner, то есть «нажал — ничего». Ширину рейки
      считает ОДНА дверь `ccLeftGap()` (брат `ccBottomGap`/`ccRightGap`) и кладёт её в
      `--cc-left-gap`; рейки нет (узкое окно, тред во всю ширину) — зазор 0. */
.notify-banner { position: fixed; left: var(--cc-left-gap, 0px); right: 0; bottom: 0; z-index: 9500;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 18px; font-size: 14px; line-height: 1.4;
  box-shadow: 0 -3px 18px rgba(0,0,0,.28); }
.notify-banner.hidden { display: none; }
.notify-banner .nb-msg { flex: 1 1 260px; }
.notify-banner.warn  { background: #4a3410; color: #ffd9a0; border-top: 3px solid #ff9800; }
.notify-banner.error { background: #4a1a16; color: #ffbcb4; border-top: 3px solid #ef4444; }
.notify-banner.info  { background: #12314f; color: #b9d8ff; border-top: 3px solid #3b82f6; }
.notify-banner .nb-btn { flex: 0 0 auto; border: none; border-radius: 8px;
  padding: 8px 16px; font-weight: 600; font-size: 14px; cursor: pointer; color: #fff; }
/* 🔴 CLIE-888·3: на ЯРКОЙ тёплой заливке белые чернила не читаются — «Включить» на
   #f57c00 давало 2.70:1 (замер живого прода, светлая тема), красная кнопка — 3.76:1.
   Тёмные чернила на той же заливке: 6.77 и 4.86 — оба ≥ AA, заливка и оттенок кнопки те
   же. Баннер сам по себе тёмный в ОБЕИХ темах (#4a3410) и токенов темы не читает — это
   не правка тёмной темы, а починка кнопки, сломанной одинаково везде. */
.notify-banner.warn  .nb-btn { background: #f57c00; color: #1f1206; }
.notify-banner.error .nb-btn { background: #ef4444; color: #1f1206; }
.notify-banner.info  .nb-btn { background: var(--primary); }
.notify-banner .nb-btn:hover { filter: brightness(1.08); }
.notify-banner .nb-link { flex: 0 0 auto; background: none; border: none; cursor: pointer;
  text-decoration: underline; font-size: 13px; color: inherit; opacity: .85; }
.notify-banner .nb-link:hover { opacity: 1; }
.notify-banner .nb-x { flex: 0 0 auto; background: none; border: none; cursor: pointer;
  font-size: 16px; line-height: 1; color: inherit; opacity: .6; padding: 4px 8px; }
.notify-banner .nb-x:hover { opacity: 1; }

/* Светлая тема — мягкий фон, тёмный текст */
html[data-theme="light"] .notify-banner.warn  { background: #fff4e0; color: #6d4300; }
html[data-theme="light"] .notify-banner.error { background: #fdeceb; color: #8b1a12; }
html[data-theme="light"] .notify-banner.info  { background: var(--info-soft); color: var(--info); }

/* Лист «Почему не приходят уведомления» (пошаговые инструкции под ОС/браузер) */
.notify-help-sheet { max-width: 540px; width: 92%; padding: 22px 24px; }
.notify-help-title { font-size: 18px; font-weight: 700; margin-bottom: 12px; }
.notify-help-body .nbh-lead { margin: 0 0 12px; opacity: .82; }
.notify-help-body .nbh-steps { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 12px; }
.notify-help-body .nbh-steps li { line-height: 1.5; }
.notify-help-actions { display: flex; gap: 10px; margin-top: 20px; justify-content: flex-end; flex-wrap: wrap; }

/* ══ 📲 CLIE-897 · ПЛАШКА «УСТАНОВИТЕ ПРИЛОЖЕНИЕ» (телефон в браузере) ══════════
   Спокойная строка над шапкой: иконка приложения · два слова о пользе · одно действие ·
   ✕. Тон — «предложение», а не тревога: цвета берём у панели, акцент несёт ТОЛЬКО кнопка
   (канон CLIE-483 — никаких левых реек и заливок во всю ширину). Обе темы получаются
   сами: всё на токенах --panel/--line/--text/--primary. */
.inst-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 12px; box-sizing: border-box;
  background: var(--panel); color: var(--text);
  border-bottom: 1px solid var(--line);
  cursor: pointer; user-select: none;
}
.inst-bar .inst-ico { flex: none; width: 34px; height: 34px; border-radius: 9px; overflow: hidden;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 12%, transparent); }
.inst-bar .inst-ico img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Единственное, что имеет право сжиматься и переноситься, — текст: у него для этого есть
   вторая строка. Контролы ниже своей подписи не жмутся (канон СРЕД-33). */
.inst-bar .inst-tx { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; line-height: 1.25; }
.inst-bar .inst-tx b { font-size: 13.5px; font-weight: 650; }
.inst-bar .inst-tx small { font-size: 11.5px; opacity: .68; }
.inst-bar .inst-go {
  flex: none; min-width: max-content;
  border: 0; border-radius: 8px; padding: 7px 14px;
  background: var(--acc-fill); color: #fff; font: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
}
.inst-bar .inst-x {
  flex: none; width: 28px; height: 28px; padding: 0;
  border: 0; border-radius: 8px; background: transparent; color: inherit;
  opacity: .5; font-size: 15px; line-height: 1; cursor: pointer;
}
.inst-bar .inst-x:hover { opacity: 1; background: color-mix(in srgb, var(--text) 8%, transparent); }
/* Пока плашка стоит, вход в установку ОДИН: кнопка шапки уступает ей место (и возвращается,
   как только человек плашку закроет — ничего не теряется). */
html.cc-instbar-on #installBtn { display: none; }

/* ── Модалка «Скачать приложение» (клик «⬇ Установить» в браузере) ──────────── */
.dl-modal { max-width: 600px; width: 94%; padding: 24px 26px; text-align: center; }
.dl-title { font-size: 20px; font-weight: 700; margin-bottom: 8px; }
.dl-sub { opacity: .8; margin: 0 0 18px; line-height: 1.45; }
.dl-cards { display: flex; gap: 14px; }
.dl-card { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 18px 14px; border-radius: 12px; border: 1px solid var(--border, #2c2d31);
  text-decoration: none; color: inherit; background: rgba(255,255,255,.03);
  transition: border-color .15s, transform .1s; }
.dl-card:hover { border-color: var(--primary); transform: translateY(-1px); }
.dl-card.dl-reco { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.dl-os { font-size: 17px; font-weight: 700; }
.dl-hint { font-size: 12px; opacity: .6; }
.dl-cta { margin-top: 6px; background: var(--acc-fill); color: #fff; border-radius: 8px; padding: 7px 18px; font-weight: 600; font-size: 14px; }
.dl-pwa { display: block; margin: 16px auto 0; background: none; border: none; color: inherit; opacity: .7; text-decoration: underline; cursor: pointer; font-size: 13px; }
.dl-pwa:hover { opacity: 1; }
.dl-close { margin-top: 16px; background: transparent; border: 1px solid var(--border, #2c2d31); border-radius: 8px; padding: 8px 20px; color: inherit; cursor: pointer; }
html[data-theme="light"] .dl-card { background: var(--cm-141e3c-05, rgba(20,30,60,.05)); }
/* Честная строка про первый запуск (сборка без подписи платформы). Появляется только
   для своей ОС — тон спокойный, не «предупреждение об опасности»: это шаг установки. */
.dl-note { margin: 14px 0 0; padding: 10px 12px; border-radius: 10px; font-size: 12.5px;
  line-height: 1.45; text-align: left; opacity: .85;
  background: rgba(255,255,255,.05); border: 1px solid var(--border, #2c2d31); }
html[data-theme="light"] .dl-note:where(:not(.dl-warn)) { background: var(--cm-141e3c-04, rgba(20,30,60,.04)); } /* CLIE-1946: цена (.dl-warn) держит свой тинт */
/* 🔴 CLIE-644. Тот же спокойный тон получает ЦЕНУ, когда ОС сборку не откроет вовсе:
   мягкая подложка акцента + хэйрлайн-кольцо (канон акцента — без левых реек). */
.dl-note.dl-warn { opacity: 1;
  background: var(--danger-soft);
  border-color: color-mix(in srgb, var(--danger) 34%, transparent); }
/* Вторая дверь: тихая строка под карточками — «есть ещё вот такой файл и вот его цена».
   Не кнопка и не карточка: главное действие должно оставаться одно. */
.dl-alt { margin: 10px 0 0; font-size: 12.5px; line-height: 1.45; text-align: left; opacity: .72; }
/* Код для камеры телефона («Установить на телефон» с компьютера). Плитка под кодом БЕЛАЯ в обеих
   темах намеренно: камеры телефонов читают тёмные модули на светлом поле, инверсия в тёмной теме
   сканируется хуже. Рамка и подпись — токенами темы. */
.dl-qr { display: flex; flex-direction: column; align-items: center; gap: 10px; margin: 2px 0 0; }
.dl-qr-code { width: 200px; height: 200px; padding: 10px; border-radius: 14px; background: #fff;
  box-shadow: 0 0 0 1px var(--line); display: grid; place-items: center; color: #111; font-size: 12.5px; line-height: 1.4; }
.dl-qr-code svg { width: 100%; height: 100%; display: block; }
.dl-qr-url { margin: 0; font-size: 12.5px; opacity: .72; word-break: break-all; user-select: all; }
.dl-alt a { color: var(--primary); text-decoration: none; border-bottom: 1px solid transparent; }
.dl-alt a:hover { border-bottom-color: currentColor; }
/* Android-карточка = <button>: сбрасываем дефолт кнопки, зелёный акцент у иконки Android */
button.dl-card { font: inherit; cursor: pointer; }
.dl-android .dl-os svg { color: #3ddc84; width: 20px; height: 20px; vertical-align: -3px; }
/* 🍏 Карточка Apple: иконка тем же кеглем, что у macOS/Android — один визуальный ряд */
.dl-ios .dl-os svg { width: 19px; height: 19px; vertical-align: -3px; }
.dl-card.dl-busy { opacity: .65; pointer-events: none; }
/* Панель загрузки APK: прогресс + шаги установки */
.dl-android-panel { margin-top: 16px; text-align: left; }
.dl-prog { height: 8px; border-radius: 6px; background: rgba(127,127,127,.18); overflow: hidden; }
.dl-prog-bar { height: 100%; width: 0; background: var(--primary); border-radius: 6px; transition: width .25s ease; }
.dl-prog-txt { font-size: 13px; opacity: .82; margin-top: 8px; text-align: center; min-height: 18px; }
.dl-steps { margin: 14px 0 0; padding-left: 20px; line-height: 1.5; font-size: 14px; }
.dl-steps li { margin: 6px 0; }
/* Шаги Apple лежат прямо в модалке (у неё text-align:center) — читаемый список только слева */
#dlIosSteps { text-align: left; }
.dl-steps b { font-weight: 650; }

/* ══════════════════════════════════════════════════════════════════════════════
   §3 РЕДИЗАЙН 2026-07 — премиальная система (светлая тема — первый класс).
   Принципы: (1) светлая = белые слои на холодной канве, разделение тенями/хэйрлайнами,
   а не рамками; поля УТОПЛЕНЫ и «всплывают» в фокус; (2) кнопки «тихие» — плоский
   индиго вместо градиентных плашек (градиент = только бренд-моменты: «мой» пузырь,
   логин-CTA, активный рельс, аватары); (3) hover нейтральный, индиго-тинт только у
   ВЫБРАННОГО; (4) единая моушн-шкала --dur/--ease, пружина только на появлении;
   (5) все цвета/тени — токенами (§1 :root / html[data-theme=light]).
   Блок идёт ПОСЛЕДНИМ в файле → при равной специфичности перебивает легаси выше.
   ────────────────────────────────────────────────────────────────────────────── */

/* ── 3.1 Типографика/рендеринг ── */
html, body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}
.thread-title, .modal-head, .tw-head-title, .sidebar-head, .tasks-head, .projects-head {
  letter-spacing: -0.01em;
}
.conv-time, .msg-time, .task-lens-n, .proj-count, .conv-badge, .rail-badge {
  font-variant-numeric: tabular-nums;
}
code, kbd, .md-body code { font-family: var(--mono); }

/* ── 3.2 Фокус-кольцо (доступность): видно ТОЛЬКО с клавиатуры ── */
:where(button, a, [role="button"], [tabindex]):focus-visible {
  outline: none;
  box-shadow: 0 0 0 1px var(--primary), 0 0 0 4px var(--glow);
}

/* ── 3.3 Кнопки: «тихие», нейтральный hover; акцент — только .primary ── */
button {
  border-radius: var(--r-md);
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease),
              color var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease),
              opacity var(--dur-1) var(--ease);
}
button:hover { border-color: var(--line-strong); background: var(--active); }
html[data-theme="light"] button:hover { border-color: var(--line-strong); }
/* ЗАЛИТАЯ кнопка держит СВОЙ фон под курсором. `button:hover` (0,1,1) специфичнее одиночного
   класса (0,1,0): у кнопок ниже свой `:hover` менял только яркость, и наведение красило заливку
   в серый `--active` под белым текстом — главное действие гасло ровно в миг нажатия (найдено на
   «Получить команду» среды, 17.10). Новая залитая кнопка с фоном одним классом — фон в `:hover`. */
.cs-add:hover, .ai-action:hover, .notif-offbar-btn:hover, .lt-done:hover, .cc-qadd-go:hover,
.crm-chat-start:hover, .kn-gap-add:hover, .ft-go:hover, .mdz-gap:hover { background: var(--acc-fill); }
.vmini-play:hover, .cli-add:hover, .call-msg-join:hover, .ck-add-btn:hover, .kn-add:hover,
.kn-ask-send:hover, .kn-wiki-new:hover, .kn-inbox-keep:hover, .cc-watch-go:hover,
.cc-bo-primary:hover, .cc-doc-chip-b:hover, .ank-pfbar-b:hover { background: var(--acc-grad); }
.tdy-visit-go:hover, .ccw-col-empty-cta:hover, .ccw-cform-ok:hover { background: var(--acc-fill); }
.dvterm-go:hover { background: var(--accent, var(--cm-5b5bd6, #5b5bd6)); }
.v2cal-join:hover { background: var(--ok); }
.cs-more:hover { background: var(--ca, #e8823c); }
.pl-pay:hover { background: var(--acc-fill, var(--primary)); }
/* кнопки ПОВЕРХ видео (звонок/PiP/групповой созвон): нейтральный тёмный hover не годится —
   возвращаем белёсый, иначе кнопка «гаснет» на видеокартинке */
.call-controls button:hover, .mini-bar button:hover,
.groupcall-overlay button:hover, .minimized button:hover {
  background: rgba(255,255,255,.26); border-color: transparent;
}
/* ghost остаётся прозрачным, hover — мягкий тинт без рамки */
.ghost, html[data-theme="light"] .ghost { background: transparent; box-shadow: none; border-color: transparent; }
.ghost:hover, html[data-theme="light"] .ghost:hover { background: var(--hover); border-color: transparent; }
/* primary: ПЛОСКИЙ индиго (не градиентная плашка). Ширина 100% — как раньше (легаси-лейауты).
   🔴 Белым по ЗАЛИВКЕ — `--acc-fill`, не `--primary` (CLIE-1847·⑤, замер рендером): в тёмной
   Concept 6 `--primary` #7b88ea — САМАЯ светлая поверхность экрана, белое по ней 3.21:1, ниже AA.
   `--acc-fill` там #5b68cf (4.85:1); в светлой и без концепта он равен `--primary`, вид тот же.
   Наведение ТЕМНЕЕ заливки (не светлее): светлый `--primary-hi` снова уронил бы контраст. */
.primary, html[data-theme="light"] .primary {
  background: var(--acc-fill, var(--primary));
  border-color: transparent; color: #fff;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 1px 2px var(--cm-171c2d-18, rgba(23,28,45,.18));
}
.primary:hover, html[data-theme="light"] .primary:hover {
  background: color-mix(in srgb, var(--acc-fill, var(--primary)) 88%, #000); border-color: transparent;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.12), 0 2px 6px var(--cm-171c2d-2, rgba(23,28,45,.2));
}
.primary:active { box-shadow: inset 0 1px 2px rgba(0,0,0,.18); }
/* бренд-моменты: герой-CTA логина остаётся фирменным градиентом */
.login .primary { background: var(--acc-grad); box-shadow: 0 6px 16px -4px var(--glow); }
.login .primary:hover { background: var(--acc-grad); box-shadow: 0 8px 22px -4px var(--glow); }

/* ── Вход через Telegram (иностранные номера, где SMS не доходит) ──────────────
   Вторичный путь: разделитель «или» + брендовая Telegram-blue кнопка + шаг ожидания. */
.tg-wrap { margin-top: 2px; }
.or-sep { display: flex; align-items: center; gap: 12px; margin: 18px 2px 14px; color: var(--text-dim); font-size: 12.5px; }
.or-sep::before, .or-sep::after { content: ""; height: 1px; flex: 1; background: var(--line); }
.tg-btn {
  width: 100%; display: flex; align-items: center; justify-content: center; gap: 9px;
  background: #229ED9; color: #fff; border-color: transparent; border-radius: 11px;
  padding: 11px 16px; font-weight: 600; font-size: 15px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.18), 0 1px 2px var(--cm-171c2d-18, rgba(23,28,45,.18));
  transition: background var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.tg-btn:hover { background: #1c8fc6; border-color: transparent; box-shadow: inset 0 1px 0 rgba(255,255,255,.18), 0 3px 10px rgba(34,158,217,.32); }
.tg-btn:active { transform: translateY(.5px); box-shadow: inset 0 1px 2px rgba(0,0,0,.14); }
.tg-btn:disabled { opacity: .6; }
.tg-btn svg { flex: none; }
.tg-hint { margin: 10px 4px 0; font-size: 12.5px; line-height: 1.45; text-align: center; }
/* шаг ожидания: спиннер Telegram-blue + подсказка */
.tg-wait { display: flex; flex-direction: column; align-items: center; gap: 15px; margin: 6px 0 22px; text-align: center; }
.tg-spinner { width: 34px; height: 34px; border-radius: 50%; border: 3px solid var(--line); border-top-color: #229ED9; animation: tg-spin .8s linear infinite; }
@keyframes tg-spin { to { transform: rotate(360deg); } }
/* CLIE-653: плашка «код входа» удалена целиком — вход без лишних этапов, цифр нет. */
/* кнопки звонка в шапке треда — тоже плоский индиго */
.call-btn, html[data-theme="light"] .call-btn { background: var(--acc-fill); border-color: transparent; color: #fff; box-shadow: none; }
.call-btn:hover, html[data-theme="light"] .call-btn:hover { background: var(--acc-fill-hi); border-color: transparent; }
.danger, html[data-theme="light"] .danger { background: var(--danger); color: #fff; border-color: transparent; box-shadow: none; }
.danger:hover, html[data-theme="light"] .danger:hover { filter: brightness(1.06); border-color: transparent; }

/* ── 3.4 Поля ввода: утоплены → «всплывают» на фокусе ── */
/* bare-select-chevron-1 · только ЦВЕТ фона. Сокращение `background:` той же специфичности (0,0,1) стояло ниже
   общего шеврона `select { background-image: var(--sel-chev) }` (стр. ~700) и стирало его у каждого select без
   своего класса. У input/textarea картинки нет — для них ничего не меняется. */
input, select, textarea { background-color: var(--input-bg); }
/* background-COLOR, не сокращение: сокращение на фокусе (0,1,1 / 0,2,2) обнуляло background-image у
   .tw-select / .co-sel / #usersSort (0,1,0), и у выбранного списка пропадал шеврон. */
input:focus, select:focus, textarea:focus { background-color: var(--panel); }
html[data-theme="light"] input:focus,
html[data-theme="light"] select:focus,
html[data-theme="light"] textarea:focus { background-color: #fff; }
.composer textarea, .composer .cmp-ce { background: var(--input-bg); transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease), box-shadow var(--dur-1) var(--ease); }
.composer textarea:focus, .composer .cmp-ce:focus { background: var(--panel); border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
html[data-theme="light"] .composer textarea:focus, html[data-theme="light"] .composer .cmp-ce:focus { background: #fff; }
/* контейнеры-«поля» (поиск в столбике задач) — та же логика */
.tasks-list .task-searchbar { background: var(--input-bg); }
.projects-list .proj-searchbar { background: var(--input-bg); }
.chat-search-input { background: var(--input-bg); }

/* ── 3.5 Карточки: light — тень покоя + подъём на hover; тёмная — цвет+граница ── */
.tw-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow-1); }
/* Светлая тема: карточка — ровный 1px-хэйрлайн по кругу (`border`, а не `border-color`:
   ровный хэйрлайн вместо старого leftover-`border-left`, который до 0141 дублировал капсулу —
   «осталась полоска слева», владелец 2026-07-27).
   🔴 CLIE-599: фраза «капсула-приоритет `.tw-card::before` НУЖНА и остаётся в ОБЕИХ темах»
   БОЛЬШЕ НЕ ДЕЙСТВУЕТ — владелец отменил её сам и выбрал вариант В1: капсулы нет нигде,
   приоритет несёт точка у заголовка. Оставляю строку историей, чтобы её не «починили» обратно. */
/* 🔴 CLIE-1946. Тема не съедает состояние: служебная карточка ИИ (.ai-self, AISELF_LOOK)
   исключена из светлых правил карточки через :where — вес тот же (0,2,1), а у неё выигрывает
   собственная декларация (пунктир, без заливки и тени), ровно как в тёмной. */
html[data-theme="light"] .tw-card:where(:not(.ai-self)) { box-shadow: var(--shadow-1); border: 1px solid var(--cm-171e34-1, rgba(23,30,52,.10)); }
html[data-theme="light"] .tw-card:where(:not(.ai-self)):hover {
  border-color: var(--cm-171e34-18, rgba(23,30,52,.18));
  box-shadow: 0 2px 6px var(--cm-0f1628-08, rgba(15,22,40,.08)), 0 10px 24px -6px var(--cm-0f1628-16, rgba(15,22,40,.16));
}
/* перетаскивание карточки — «подъём» */
.tw-card.dragging, .tw-card[draggable="true"]:active { box-shadow: var(--shadow-3); }
/* колонки доски в светлой: мягкий инсет чуть темнее канвы, без жёсткой рамки */
/* 🔴 СРЕД-30. Было `--col-bg: #d4dce9; border-color: transparent` — холодная сине-серая
   плита БЕЗ границы: на тёплом холсте боевого концепта колонки доски выглядели чужой
   палитрой, а держаться им было не на чем (границу сняли, а фон подобрали руками).
   Базовое правило .tw-col уже даёт --panel-2 + рамку var(--line) — а теперь эта рамка
   видна. Свой цвет колонке не нужен: она сама станет тёплой под концептом. */
html[data-theme="light"] .tw-col:where(:not(.drop-hover)) { border-color: var(--line); } /* CLIE-1946: рамка цели перетаскивания (.drop-hover) не съедается */
/* Тело колонки в СВЕТЛОЙ: см. разбор у `.tw-col` выше — здесь --panel-2 равен холсту. */
html[data-theme="light"] .tw-col { --col-bg: color-mix(in srgb, var(--bg) 92%, var(--text)); }

/* ── 3.6 Списки (беседы/проекты): hover нейтральный, активное — индиго-тинт ── */
.conv-item { border-radius: var(--r-md); transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease); }
.conv-item:hover { background: var(--hover); }
.conv-item.active { background: var(--sel); border-color: transparent; box-shadow: none; }
.proj-item:hover { background: var(--hover); }
.proj-item.active { background: var(--sel); border-color: transparent; box-shadow: none; }
.tasks-list .task-row:hover { background: var(--hover); }
.contacts-list .contact-row:hover { background: var(--hover); }
.mention-item.active, .mention-item:hover,
.ref-row.active, .ref-row:hover { background: var(--hover); }

/* ── 3.7 Пузыри сообщений: крупнее радиус, мягче хвост, light-тень ── */
.bubble { border-radius: 16px; line-height: 1.45; } /* межстрочный — см. .bubble выше (читаемость «как в телеге») */
.msg.mine .bubble { border-bottom-right-radius: 6px; }
.msg.theirs .bubble { border-bottom-left-radius: 6px; border: 1px solid var(--line); }
html[data-theme="light"] .msg.theirs .bubble { box-shadow: var(--shadow-1); border-color: var(--cm-171e34-09, rgba(23,30,52,.09)); }
html[data-theme="light"] .msg.mine .bubble { box-shadow: 0 1px 3px var(--cm-464092-28, rgba(70,64,146,.28)); }

/* ── 3.8 Меню/поповеры/тултипы: поднятый слой --panel-3 + тень-2 + пружина появления ── */
@keyframes ccPopIn {
  from { opacity: 0; transform: translateY(4px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
.mention-menu, .ref-menu, .attach-menu, .msg-menu, .tc-pop, .td-userpick, .notif-panel, .today-panel {
  background: var(--panel-3);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-2), var(--edge);
}
.mention-menu, .ref-menu, .attach-menu, .msg-menu, .tc-pop {
  animation: ccPopIn var(--dur-2) var(--ease-spring);
}
.attach-menu button:hover, .msg-menu > button:hover { background: var(--hover); }
.msg-menu .msg-menu-del:hover { background: var(--danger-soft); }
.tc-pop-row.danger:hover { background: var(--danger-soft); }
/* плавающие пилюли быстрых действий (карточки/строки) — тень токеном */
.tw-card-acts.tw-qacts, .proj-qacts { box-shadow: var(--shadow-2); background: var(--panel-3); }
.tl-tip, .tl-undo-toast { background: var(--panel-3); box-shadow: var(--shadow-2), var(--edge); }
.cc-toast { background: var(--panel-3); border: 1px solid var(--line); box-shadow: var(--shadow-2), var(--edge); color: var(--text); }
/* На белом фоне тоста осветление не нужно и вредно — чистый акцент даёт контраст 5.78.
   🔴 Префикс html[data-theme="light"] ОБЯЗАТЕЛЕН: в этом файле светлая тема задаётся
   префиксом, а не вложенностью, и правило без него перебило бы базовое в ОБЕИХ темах
   (ровно на это я и наступил — тёмная осталась с контрастом 3.87). */
html[data-theme="light"] .cc-toast-act { color: var(--accent); }
.jump-down { box-shadow: var(--shadow-2); }

/* ── 3.9 Модалки: единый скрим + блюр + появление ── */
@keyframes ccModalIn {
  from { opacity: 0; transform: translateY(10px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
.modal-overlay { background: var(--scrim); backdrop-filter: blur(6px) saturate(1.1); -webkit-backdrop-filter: blur(6px) saturate(1.1); }
.modal-box { box-shadow: var(--shadow-3), var(--edge); animation: ccModalIn var(--dur-3) var(--ease-spring); }
html[data-theme="light"] .modal-box { border-color: var(--cm-171e34-1, rgba(23,30,52,.10)); }

/* ── 3.10 Скроллбары: СКРЫТЫ по умолчанию, ПОЯВЛЯЮТСЯ при наведении на блок (владелец 2026-07-15).
   🔴 Это КАНОНИЧНОЕ правило (последнее в каскаде) — оно перебивает верхние *::-webkit-scrollbar,
   поэтому автоскрытие делаем ИМЕННО здесь. Бегунок прозрачный → красится на :hover блока
   (:hover поднимается по предкам → бегунок у блока под курсором). Ширину на hover НЕ меняем. ── */
*::-webkit-scrollbar { width: 11px; height: 11px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  border-radius: var(--r-full);
  border: 3px solid transparent;
  background-clip: padding-box;
  background-color: transparent;
  transition: background-color .15s;
}
*:hover::-webkit-scrollbar-thumb { background-color: rgba(230,233,239,.30); background-clip: padding-box; }
*::-webkit-scrollbar-thumb:hover { background-color: rgba(230,233,239,.5); background-clip: padding-box; }
html[data-theme="light"] *::-webkit-scrollbar-thumb { background: transparent; border: 3px solid transparent; background-clip: padding-box; }
html[data-theme="light"] *:hover::-webkit-scrollbar-thumb { background: var(--cm-171c2d-34, rgba(23,28,45,.34)); border: 3px solid transparent; background-clip: padding-box; }
html[data-theme="light"] *::-webkit-scrollbar-thumb:hover { background: var(--cm-171c2d-5, rgba(23,28,45,.5)); border: 3px solid transparent; background-clip: padding-box; }

/* ── 3.11 Каркас в светлой: топбар/рельс/тред ── */
html[data-theme="light"] .topbar { box-shadow: 0 1px 0 var(--line), 0 2px 8px var(--cm-0f1628-05, rgba(15,22,40,.05)); }
html[data-theme="light"] .chat-rail { background: var(--panel); border-right: 1px solid var(--line); } /* A: белый рельс */
html[data-theme="light"] .thread { background: var(--panel-2); } /* A: переписка на мягкой канве, белые пузыри всплывают */
/* активный пункт рельса — фирменный градиент остаётся (бренд-момент) */

/* ── 3.12 Точечные light-фиксы инжект-стилей (белые-альфы app.js в светлой) ── */
html[data-theme="light"] .tm-tile, html[data-theme="light"] .tm-row,
html[data-theme="light"] .tm-fthumb, html[data-theme="light"] .tm-voice { background: var(--panel-2); }
html[data-theme="light"] .tm-row:hover { background: var(--active); }
html[data-theme="light"] .contact-invite-link { color: var(--primary-2); }
html[data-theme="light"] .contact-invite-link:hover { color: var(--primary); }
html[data-theme="light"] .attach-menu button:hover { background: var(--hover); }
html[data-theme="light"] .rd-tb button:hover { background: var(--hover); }
/* Активный формат в светлой теме — тот же индиго-акцент, устойчивый к светлому hover-override выше. */
html[data-theme="light"] .rd-tb button.active,
html[data-theme="light"] .rd-tb button.active:hover { background: var(--cm-4338ca-14, rgba(67,56,202,.14)); color: var(--primary-2); }
html[data-theme="light"] .qc-fab-x:hover { background: var(--hover); }

/* ── 3.12b Светлая: элементы на белых альфах тёмной темы — невидимы на светлом (аудит 2026-07-14).
   Выходные календаря/таймлайна, граница суток, линия «факта», ховеры, градиент чек-ринга. ── */
html[data-theme="light"] .v2cal-cell.we:where(:not(.oom)) { background: rgba(15,20,31,.035); } /* CLIE-1946: выходной ЧУЖОГО месяца — фон .oom, как в тёмной */
html[data-theme="light"] .v2cal-cell.we:hover { background: var(--panel-2); } /* пара обязательна: иначе light-.we перебьёт базовый hover (грабля со стр. ~3389) */
html[data-theme="light"] .tl-daycol.wend { background: rgba(15,20,31,.04); }
html[data-theme="light"] .tl-daycol.dayedge { border-left-color: var(--line-strong); }
html[data-theme="light"] .tl-bar.done .tl-lbl { color: #fff; text-shadow: none; }
/* линия «факта»: тёмная с белым кольцом — читается и на светлом треке, и поверх тёмных баров; легенда = тот же вид */
html[data-theme="light"] .tl-actual { background: var(--cm-3b4560, #3b4560); box-shadow: 0 0 0 1px rgba(255,255,255,.75); }
html[data-theme="light"] .tl-actual.over { background: var(--urg-overdue); } /* CLIE-1946: перерасход красный, как в тёмной — светлая сажа его съедала */
/* CLIE-1946: плитка медиа профиля (стили — app.js, фон --panel-2) на светлом = холст: пустая плитка
   и видео без постера сливались, а белый ▶ на ней — 1.09:1. Тон дорожки + тёмный ▶, когда постер не
   загрузился (onerror помечает <img> классом). «Добавить» (.pfo-madd) держит свой вид. */
html[data-theme="light"] .mp-tile:where(:not(.pfo-madd)) { background: color-mix(in srgb, var(--bg) 92%, var(--text)); }
/* Не наблюдать [style] через :has(): Chromium 130 инвалидирует всю страницу при
   любом inline-изменении (в том числе росте поля ввода). Состояние локально у постера. */
.mp-tile > img.mp-poster-failed { visibility: hidden; }
html[data-theme="light"] .mp-tile > img.mp-poster-failed + .mp-play { color: var(--muted); filter: none; }
html[data-theme="light"] .tl-legend .sw.fact { background: var(--cm-3b4560, #3b4560); box-shadow: 0 0 0 1px rgba(255,255,255,.75); }
html[data-theme="light"] .rail-item:hover { background: var(--hover); } /* базовый var(--panel-2) на светлом рельсе не виден */
html[data-theme="light"] .rd.editable .rd-view:hover { background: var(--hover); }
html[data-theme="light"] .tip-files-card .tf-dl:hover { background: var(--hover); }
html[data-theme="light"] #ckgrad stop:first-child { stop-color: var(--primary-2); }
html[data-theme="light"] #ckgrad stop:last-child { stop-color: var(--cm-6d28d9, #6d28d9); }

/* ── 3.13 Движение: уважение reduced-motion ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}

/* ── 3.14 Пространство задач: компактный CTA вместо растянутой плашки ── */
#twNew { flex: 0 0 auto; margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }
#twNew svg.ic { width: 15px; height: 15px; }
/* активный вид в сегменте — плоский индиго (градиент = только бренд-моменты) */
.tw-seg button.active { background: var(--acc-fill); box-shadow: none; }

/* ── 3.15 Пилюля/полоса «ИИ» — классами по темам (были инлайн-лаванды, нечитаемые в светлой) ── */
.tw-pill.tw-pill-ai { background: var(--cm-7c6fff-14, rgba(124,111,255,.14)); color: var(--cm-a99bff, #a99bff); border: 1px solid var(--cm-7c6fff-3, rgba(124,111,255,.3)); }
/* 🔴 i_hubs · keyboard-aiblock-1 + tasks-board-aichip-overflow-1 — ОДИН дефект плашки «ИИ работает: …».
   Плашка — inline-flex, и её min-content = самый длинный НЕРАЗРЫВНЫЙ токен команды: «PATH=/opt/ccworker/
   flutter/bin» делал коробку шире ряда чипов карточки доски (k_tasks тёмная: срез на x1305 без кромки и
   скругления, «bin» обрезан посередине), «tests/order_status_bus_guard_r…» в «Мои задачи» съедал правый
   отступ карточки (k_keyboard светлая: заливка до x343 при кромке карточки x346; у соседней — до x333,
   отступ 13 px). Перенос в любом месте + потолок по ширине родителя: плашка всегда внутри карточки
   в любом виде (доска, список, «Мои задачи»).
   `.ai-sched` (nowrap + многоточие) не меняется: ему min-width:0 лишь даёт ужаться до многоточия. */
.tw-pill.tw-pill-ai { min-width: 0; max-width: 100%; box-sizing: border-box; overflow-wrap: anywhere; }
.tw-pill.tw-pill-ai .tw-aiq { min-width: 0; }
.tw-pill.tw-pill-ai.ai-working { background: var(--cm-7c6fff-22, rgba(124,111,255,.22)); color: var(--cm-c4b8ff, #c4b8ff); border-color: var(--cm-7c6fff-42, rgba(124,111,255,.42)); }
.tw-pill.tw-pill-ai.ai-failed { background: var(--danger-soft); color: #f7a2a2; border-color: rgba(239,68,68,.34); }
.tw-pill.tw-pill-ai.ai-pending { background: rgba(245,158,11,.16); color: #f0b34e; border-color: rgba(245,158,11,.4); }
/* CLIE-920: задача ПРОЛОЖЕНА вперёд очереди («Взять сейчас») — акцентнее обычной очереди, но
   тише «В работе»: это ещё ожидание, а не работа. Номер она называет сама (⚡ 2-я в очереди). */
.tw-pill.tw-pill-ai.ai-urgent { background: var(--cm-7c6fff-24, rgba(124,111,255,.24)); color: var(--cm-cfc6ff, #cfc6ff); border-color: var(--cm-7c6fff-5, rgba(124,111,255,.5)); font-weight: 600; }
html[data-theme="light"] .tw-pill.tw-pill-ai { background: var(--cm-6d5fe0-12, rgba(109,95,224,.12)); color: var(--cm-6d28d9, #6d28d9); border-color: var(--cm-6d5fe0-34, rgba(109,95,224,.34)); }
html[data-theme="light"] .tw-pill.tw-pill-ai.ai-urgent { background: var(--cm-6d5fe0-2, rgba(109,95,224,.2)); color: var(--cm-4c1d95, #4c1d95); border-color: var(--cm-6d5fe0-5, rgba(109,95,224,.5)); font-weight: 600; }
html[data-theme="light"] .tw-pill.tw-pill-ai.ai-working { background: var(--cm-6d5fe0-16, rgba(109,95,224,.16)); color: var(--cm-5b21b6, #5b21b6); border-color: var(--cm-6d5fe0-42, rgba(109,95,224,.42)); }
html[data-theme="light"] .tw-pill.tw-pill-ai.ai-failed { background: var(--danger-soft); color: var(--danger); border-color: rgba(220,38,38,.3); }
html[data-theme="light"] .tw-pill.tw-pill-ai.ai-pending { background: rgba(217,119,6,.14); color: #b45309; border-color: rgba(217,119,6,.4); }
.ai-strip-hl { color: var(--cm-c4b8ff, #c4b8ff); }
html[data-theme="light"] .ai-strip-hl { color: var(--cm-5b21b6, #5b21b6); }

/* ── 0133 «ИИ работает»: пульс-точка + ЧЕСТНАЯ шкала прогресса в «Чате с ИИ» ──────────────────
   Плашка tipAiStrip в состоянии working. ai_progress (число) → определённая полоса «NN%»;
   nil → деликатная «бегущая» (indeterminate) без выдуманных цифр. Виолет = как пилюля ИИ. */
.ai-strip-working .ai-strip-hl { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-work-dot { flex: 0 0 auto; width: 9px; height: 9px; border-radius: 50%; background: var(--cm-7c6fff, #7c6fff); box-shadow: 0 0 0 0 var(--cm-7c6fff-55, rgba(124,111,255,.55)); animation: aiWorkPulse 1.8s ease-in-out infinite; }
html[data-theme="light"] .ai-work-dot { background: var(--cm-6d28d9, #6d28d9); }
@keyframes aiWorkPulse { 0%, 100% { box-shadow: 0 0 0 0 var(--cm-7c6fff-5, rgba(124,111,255,.5)); } 70% { box-shadow: 0 0 0 6px var(--cm-7c6fff-0, rgba(124,111,255,0)); } }
.ai-strip-pct { flex: 0 0 auto; margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 700; font-size: 11.5px; color: var(--cm-c4b8ff, #c4b8ff); }
html[data-theme="light"] .ai-strip-pct { color: var(--cm-5b21b6, #5b21b6); }
.ai-strip-prog { position: absolute; left: 0; right: 0; bottom: -1px; height: 3px; background: var(--cm-7c6fff-14, rgba(124,111,255,.14)); overflow: hidden; }
html[data-theme="light"] .ai-strip-prog { background: var(--cm-6d5fe0-13, rgba(109,95,224,.13)); }
.ai-strip-prog > i { display: block; height: 100%; border-radius: 0 3px 3px 0; background: linear-gradient(90deg, var(--cm-7c6fff, #7c6fff), var(--cm-a78bfa, #a78bfa)); box-shadow: 0 0 8px var(--cm-7c6fff-5, rgba(124,111,255,.5)); transition: width .35s cubic-bezier(.4,0,.2,1); }
.ai-strip-prog.indet > i { width: 40%; border-radius: 3px; animation: aiStripSweep 1.15s ease-in-out infinite; will-change: transform; }
@keyframes aiStripSweep { 0% { transform: translateX(-110%); } 100% { transform: translateX(275%); } }

/* Список чатов: деликатный «дышащий» индикатор работы ИИ на строке «Чата с ИИ» (0133) — по
   требованию владельца «не сильно заметно». Точка среди марок + мягкое «дыхание» полосы-акцента. */
.conv-mark.conv-ai-work { opacity: 1; display: inline-flex; align-items: center; }
.conv-mark.conv-ai-work .caw-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--cm-7c6fff, #7c6fff); box-shadow: 0 0 0 0 var(--cm-7c6fff-5, rgba(124,111,255,.5)); animation: aiWorkPulse 1.9s ease-in-out infinite; }
html[data-theme="light"] .conv-mark.conv-ai-work .caw-dot { background: var(--cm-6d28d9, #6d28d9); }
/* Деликатная %-подпись рядом с дышащей точкой (по просьбе владельца «Добавь %»). Тонкая,
   моноширинные цифры, приглушённый фиолет — читается, но не кричит и не засоряет строку. */
.conv-mark.conv-ai-work .caw-pct { margin-left: 3px; font-variant-numeric: tabular-nums; font-weight: 600; font-size: 10.5px; line-height: 1; letter-spacing: -.2px; color: var(--cm-a99cff, #a99cff); }
html[data-theme="light"] .conv-mark.conv-ai-work .caw-pct { color: var(--cm-6d28d9, #6d28d9); }
.conv-item.aic-working::before { animation: aicBarBreathe 2.4s ease-in-out infinite; }
@keyframes aicBarBreathe { 0%, 100% { opacity: .6; } 50% { opacity: 1; } }

/* ── CLIE-371 «Чат с ИИ»: живая подпись состояния в шапке + явное «не работает» в плашке ──────
   Владелец: «пропала анимация что ИИ думает; не понятно, работает он или нет; если нет — покажи
   явно и причину». Подпись #threadSub у AI-чата теперь несёт статус: пульс-точка + «ИИ думает…»
   пока working; спокойная серая точка + «ИИ сейчас не работает · причина», когда не работает. */
.thread-sub .ai-sub { display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%; }
.thread-sub .ai-sub-txt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-sub-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--muted, #8b93a3); }
.ai-sub-dot.work { background: var(--cm-7c6fff, #7c6fff); box-shadow: 0 0 0 0 var(--cm-7c6fff-55, rgba(124,111,255,.55)); animation: aiWorkPulse 1.8s ease-in-out infinite; }
.ai-sub-dot.queued { background: var(--cm-7c6fff, #7c6fff); box-shadow: 0 0 0 0 var(--cm-7c6fff-45, rgba(124,111,255,.45)); animation: aiWorkPulse 2.4s ease-in-out infinite; }
.ai-sub-dot.await, .ai-sub-dot.pending { background: #f59e0b; box-shadow: 0 0 0 0 rgba(245,158,11,.55); animation: aiAwaitPulse 1.8s ease-in-out infinite; }
.ai-sub-dot.wait { background: #8196b2; }
.ai-sub-dot.failed { background: #ef6b6b; }
.ai-sub-dot.done { background: #4ea87a; }
.ai-sub.ai-sub-work .ai-sub-txt { color: var(--cm-b9adff, #b9adff); }
html[data-theme="light"] .ai-sub.ai-sub-work .ai-sub-txt { color: var(--cm-6d28d9, #6d28d9); }
.ai-sub.ai-sub-await .ai-sub-txt, .ai-sub.ai-sub-pending .ai-sub-txt { color: #e6a94f; }
html[data-theme="light"] .ai-sub.ai-sub-await .ai-sub-txt, html[data-theme="light"] .ai-sub.ai-sub-pending .ai-sub-txt { color: #b45309; }
.ai-sub.ai-sub-failed .ai-sub-txt { color: #e88a8a; }
/* CLIE-431: на светлой теме #e88a8a почти не читается на белом (проверено скриншотом) —
   даём тот же тёмный оттенок, что и у await-ветки выше. Контраст важнее оттенка. */
html[data-theme="light"] .ai-sub.ai-sub-failed .ai-sub-txt { color: #b91c1c; }
/* «Думает» — мягко пульсирующее многоточие (три точки друг за другом). */
.ai-sub-dots { display: inline-block; letter-spacing: 1px; }
.ai-sub-dots i { font-style: normal; opacity: .2; animation: aiSubDots 1.4s infinite both; }
.ai-sub-dots i:nth-child(2) { animation-delay: .2s; }
.ai-sub-dots i:nth-child(3) { animation-delay: .4s; }
@keyframes aiSubDots { 0%, 60%, 100% { opacity: .2; } 30% { opacity: 1; } }

/* Плашка tipAiStrip, состояние «ИИ не работает» — спокойная серая точка (красная при ошибке). */
#tipAiStrip.ai-strip-idle .ai-strip-hl { color: var(--muted, #8b93a3); }
.ai-idle-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: #8b93a3; }
.ai-idle-dot.failed { background: #ef6b6b; }

@media (prefers-reduced-motion: reduce) {
  .ai-work-dot, .conv-mark.conv-ai-work .caw-dot { animation: none; }
  .ai-strip-prog.indet > i { animation: none; width: 100%; opacity: .5; }
  .conv-item.aic-working::before { animation: none; opacity: 1; }
  .ai-sub-dot.work, .ai-sub-dot.queued, .ai-sub-dot.await, .ai-sub-dot.pending { animation: none; }
  .ai-sub-dots i { animation: none; opacity: .6; }
}

/* 🟡 ИИ ЖДЁТ ВАШЕГО ОТВЕТА (ai_status="awaiting") — янтарный «нужно действие», заметнее
   рядового статуса, но не тревожно-красный. Пилюля карточки/списка + полоска в шапке чата +
   баннер на карточке. Свет и тьма выверены; мягкая пульсация точки (внимание без мельтешения). */
.tw-pill.tw-pill-ai.ai-waiting { background: rgba(245,158,11,.18); color: #f4bd63; border-color: rgba(245,158,11,.46); }
html[data-theme="light"] .tw-pill.tw-pill-ai.ai-waiting { background: rgba(217,119,6,.14); color: #b45309; border-color: rgba(217,119,6,.42); }
/* «ИИ ждёт …» — отложенный старт / предшественник: спокойный сине-стальной, отличный от янтарного
   «ждёт ответа» и фиолетового «в очереди». Пассивное ожидание по расписанию, не требует действий. */
.tw-pill.tw-pill-ai.ai-sched { background: rgba(129,150,178,.16); color: #b8c4d6; border-color: rgba(129,150,178,.4); max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
html[data-theme="light"] .tw-pill.tw-pill-ai.ai-sched { background: rgba(71,85,105,.1); color: #475569; border-color: rgba(71,85,105,.32); }
/* ⏸ CLIE-543 «На паузе» — приглушённый нейтральный тон: задача НЕ работает и НЕ ждёт человека,
   она просто стоит. Ярче «ждёт ответа» быть не должна, иначе пауза кричит громче вопроса ИИ. */
.tw-pill.tw-pill-ai.ai-paused { background: rgba(129,150,178,.12); color: #9fb0c6; border-color: rgba(129,150,178,.32); }
html[data-theme="light"] .tw-pill.tw-pill-ai.ai-paused { background: rgba(71,85,105,.08); color: #64748b; border-color: rgba(71,85,105,.26); }

.ai-await-dot { flex:none; display:inline-block; width:8px; height:8px; border-radius:50%; background:#f59e0b; box-shadow:0 0 0 0 rgba(245,158,11,.55); animation: aiAwaitPulse 1.8s ease-in-out infinite; }
@keyframes aiAwaitPulse { 0% { box-shadow:0 0 0 0 rgba(245,158,11,.5); } 70% { box-shadow:0 0 0 6px rgba(245,158,11,0); } 100% { box-shadow:0 0 0 0 rgba(245,158,11,0); } }
@media (prefers-reduced-motion: reduce) { .ai-await-dot { animation: none; } }

/* Полоска в шапке «Чата с ИИ» — янтарный фон, акцентный текст. */
#tipAiStrip.ai-strip-await { background: rgba(245,158,11,.10); border-color: rgba(245,158,11,.26); color: var(--muted,#8b93a3); }
#tipAiStrip.ai-strip-await .ai-strip-hl { color: #f4bd63; font-weight: 600; }
html[data-theme="light"] #tipAiStrip.ai-strip-await { background: rgba(217,119,6,.08); border-color: rgba(217,119,6,.26); }
html[data-theme="light"] #tipAiStrip.ai-strip-await .ai-strip-hl { color: #b45309; }

/* Баннер на карточке задачи «ИИ ждёт вашего ответа». */
.tip-card.tip-ai-await { border:1px solid rgba(245,158,11,.42); background: rgba(245,158,11,.07); }
.tip-ai-await-row { display:flex; align-items:flex-start; gap:9px; line-height:1.45; }
.tip-ai-await-row b { color:#f4bd63; }
.tip-ai-await-row .ai-await-dot { margin-top:6px; }
.tip-ai-await-cta { margin-top:10px; }
/* 🎫 0520: два выхода в ряд («Запустить эту задачу» + «Открыть «ИИ-воркеры»») и пояснение под ними. */
.tip-ai-await-cta.tip-ai-cta2 { display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
.tip-ai-admit-say { margin-top:8px; font-size:12.5px; line-height:1.45; color: var(--muted); }
html[data-theme="light"] .tip-card.tip-ai-await { border-color: rgba(217,119,6,.42); background: rgba(217,119,6,.06); }
html[data-theme="light"] .tip-ai-await-row b { color:#b45309; }

/* Баннер на карточке «ИИ ждёт запланированного старта / предшественника» — сине-стальной, спокойный. */
.ai-sched-dot { flex:none; display:inline-block; width:8px; height:8px; border-radius:50%; background:#8196b2; box-shadow:0 0 0 0 rgba(129,150,178,.55); animation: aiSchedPulse 2.2s ease-in-out infinite; margin-top:6px; }
@keyframes aiSchedPulse { 0% { box-shadow:0 0 0 0 rgba(129,150,178,.45); } 70% { box-shadow:0 0 0 6px rgba(129,150,178,0); } 100% { box-shadow:0 0 0 0 rgba(129,150,178,0); } }
@media (prefers-reduced-motion: reduce) { .ai-sched-dot { animation: none; } }
.tip-card.tip-ai-sched { border:1px solid rgba(129,150,178,.38); background: rgba(129,150,178,.06); }
.tip-ai-sched .tip-ai-await-row b { color:#c3cede; }
html[data-theme="light"] .tip-card.tip-ai-sched { border-color: rgba(71,85,105,.34); background: rgba(71,85,105,.05); }
html[data-theme="light"] .tip-ai-sched .tip-ai-await-row b { color:#334155; }

/* Баннер «на паузе у ИИ» (0133) — нейтрально-серый, статичный (задача «спит», не ждёт события). */
.ai-paused-dot { flex:none; display:inline-block; width:8px; height:8px; border-radius:50%; background:#94a3b8; margin-top:6px; }
.tip-card.tip-ai-paused { border:1px solid rgba(148,163,184,.34); background: rgba(148,163,184,.06); }
.tip-ai-paused .tip-ai-await-row b { color:#cbd5e1; }
html[data-theme="light"] .tip-card.tip-ai-paused { border-color: rgba(100,116,139,.30); background: rgba(100,116,139,.05); }
html[data-theme="light"] .tip-ai-paused .tip-ai-await-row b { color:#475569; }

/* Кнопки «Взять сейчас» (0133) и «Продолжить» (снять с паузы) — тонкий брендовый акцент
   (главное действие состояния), без кричащей заливки. Одна семья, одно правило. */
.ghost.small.tip-ai-now, .ghost.small.tip-ai-go { color: var(--primary); }
.ghost.small.tip-ai-now svg.ic, .ghost.small.tip-ai-go svg.ic { color: var(--primary); }
.ghost.small.tip-ai-now:hover, .ghost.small.tip-ai-go:hover { background: color-mix(in srgb, var(--primary) 10%, transparent); border-color: color-mix(in srgb, var(--primary) 32%, transparent); }
/* CLIE-888·3, тот же класс: подпись — акцентные ЧЕРНИЛА --primary-2; --primary на светлой давал 4.31 (свип 19.10) */
html[data-theme="light"] :is(.ghost.small.tip-ai-now, .ghost.small.tip-ai-go) { color: var(--primary-2); }
html[data-theme="light"] :is(.ghost.small.tip-ai-now, .ghost.small.tip-ai-go) svg.ic,
html[data-theme="light"] .ai-conn-btn { color: var(--primary-2); } /* CLIE-1946: значок кнопки и «Подключить» — те же акцентные чернила */

/* Мгновенная обратная связь кнопок-действий карточки (задача «Взять сейчас не видно что нажата»):
   1) нажатие видно СРАЗУ — кнопка деликатно «вдавливается»;
   2) пока идёт запрос — состояние «занята»: акцентная подсветка + спиннер вместо иконки, чтобы
   было очевидно, что действие приняли и оно выполняется. */
.tip-actions button { transition: background .12s ease, border-color .12s ease, color .12s ease, transform .08s ease; }
.tip-actions button:active { transform: translateY(.5px) scale(.97); }
.tip-actions button.tip-busy {
  pointer-events: none;
  color: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 40%, transparent);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
}
.tip-actions button.tip-busy svg.ic { display: none; }
.tip-actions button.tip-busy::before {
  content: ""; flex: none; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--primary) 28%, transparent);
  border-top-color: var(--primary);
  animation: tip-busy-spin .6s linear infinite;
}
@keyframes tip-busy-spin { to { transform: rotate(360deg); } }

/* CLIE-309 — «Взять сейчас» показывает 3 состояния в ряду действий карточки:
   idle → кликабельная кнопка «Взять сейчас»; queued → некликабельный чип «Отдана в работу»;
   working → «В работе» (со спиннером). Раньше кнопка «Взять сейчас» оставалась после взятия —
   было непонятно, применилось ли. Чип чётко показывает этап. Светлая и тёмная — через color-mix. */
.tip-ai-state {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 11px; border-radius: 11px;
  font-size: 12px; font-weight: 600; line-height: 1; white-space: nowrap;
  border: 1px solid transparent; cursor: default; user-select: none;
}
.tip-ai-state .tip-ai-state-ind { display: inline-flex; align-items: center; justify-content: center; width: 12px; height: 12px; flex: none; }
.tip-ai-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; animation: tip-ai-pulse 1.7s ease-out infinite; }
@keyframes tip-ai-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 55%, transparent); } 70% { box-shadow: 0 0 0 5px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
.tip-ai-spin { width: 12px; height: 12px; border-radius: 50%; border: 2px solid color-mix(in srgb, currentColor 26%, transparent); border-top-color: currentColor; animation: tip-busy-spin .7s linear infinite; }
.tip-ai-state.st-queued  { color: var(--primary); background: color-mix(in srgb, var(--primary) 13%, transparent); border-color: color-mix(in srgb, var(--primary) 28%, transparent); }
.tip-ai-state.st-working { color: var(--ok);      background: color-mix(in srgb, var(--ok) 15%, transparent);      border-color: color-mix(in srgb, var(--ok) 32%, transparent); }
.tip-ai-state.st-awaiting{ color: #d97706;        background: color-mix(in srgb, #f59e0b 16%, transparent);        border-color: color-mix(in srgb, #f59e0b 34%, transparent); }
.tip-ai-state.st-pending { color: var(--primary); background: color-mix(in srgb, var(--primary) 11%, transparent); border-color: color-mix(in srgb, var(--primary) 24%, transparent); }
.tip-ai-state.st-paused  { color: var(--muted);   background: color-mix(in srgb, var(--muted) 13%, transparent);   border-color: color-mix(in srgb, var(--muted) 26%, transparent); }
/* CLIE-370: «Первая в очереди» — задача СРОЧНО проложена вперёд всей очереди (ai_take_now). Ярче
   спокойного st-queued: плотнее заливка + жирнее + чуть быстрее пульс точки («первая, вот-вот уйдёт»). */
.tip-ai-state.st-urgent  { color: var(--primary); background: color-mix(in srgb, var(--primary) 20%, transparent); border-color: color-mix(in srgb, var(--primary) 42%, transparent); font-weight: 650; }
.tip-ai-state.st-urgent .tip-ai-dot { animation-duration: 1.05s; }
html[data-theme="light"] .tip-ai-state.st-working { color: #166534; } /* CLIE-1946: #15803d на своём тинте 3.7:1 */
html[data-theme="light"] .tip-ai-state.st-awaiting { color: #b45309; }

/* CLIE-1014·2 — ЧИП «N-я в очереди» ЭТО КНОПКА (владелец: «Это не кликабильно»).
   Чип-подпись и чип-вход отличаются РОВНО признаком .is-act: курсор, шеврон, отклик на
   наведение и нажатие, кольцо фокуса с клавиатуры. Заливку и цвет не трогаем — состояние
   читается так же, меняется только «со мной можно говорить». */
button.tip-ai-state { font: inherit; font-size: 12px; font-weight: 600; margin: 0; }
.tip-ai-state.is-act { cursor: pointer; transition: background-color .14s ease, border-color .14s ease, transform .1s ease; }
.tip-ai-state.is-act:hover { background: color-mix(in srgb, currentColor 22%, transparent); border-color: color-mix(in srgb, currentColor 45%, transparent); }
.tip-ai-state.is-act:active { transform: scale(.97); }
.tip-ai-state.is-act:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.tip-ai-state-go { display: inline-flex; align-items: center; margin-left: 1px; margin-right: -3px; opacity: .62; transition: opacity .14s ease, transform .14s ease; }
.tip-ai-state-go svg { width: 13px; height: 13px; }
.tip-ai-state.is-act:hover .tip-ai-state-go { opacity: 1; transform: translateX(1px); }

/* Ответ на нажатие чипа: блок «Очередь ИИ» подкручивается к центру и мигает кольцом —
   «нажал → увидел», даже если блок и так был на экране. */
.tip-queue-card.is-hl { animation: tipQFlash 2.1s ease-out 1; }
@keyframes tipQFlash {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 55%, transparent); border-color: var(--primary); }
  35%  { box-shadow: 0 0 0 4px color-mix(in srgb, var(--primary) 22%, transparent); border-color: var(--primary); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
@media (prefers-reduced-motion: reduce) {
  .tip-ai-state.is-act, .tip-ai-state-go { transition: none; }
  .tip-queue-card.is-hl { animation: none; border-color: var(--primary); }
}

/* ═══ 0134: выбор режима учёта сообщения работающим ИИ — полоска У КОМПОЗЕРА + метка на пузыре ═══ */
/* flex-wrap: в узкой колонке (чат с ИИ в среде разработчика, 256 px) сегмент уходит на вторую
   строку, а не сжимает подпись до «Claude отв…» (замер 17.10: 83 из 256 px). */
.ai-nudge-bar { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 7px 14px; font-size: 12.5px; color: var(--muted); border-top: 1px solid var(--line); background: color-mix(in srgb, var(--primary) 6%, var(--panel)); }
/* Полоску прячут ДВУМЯ способами: класс .hidden (чат задачи) и атрибут hidden (#dvaiNudge в среде
   разработчика). display:flex выше перебивает UA-стиль [hidden] — полоска «Claude отвечает» висела
   всегда, без живого прогона (замер на проде 17.10: hidden=true, display=flex, 51 px). Тот же класс
   ошибки, что .conv-tabs[hidden]. */
.ai-nudge-bar.hidden, .ai-nudge-bar[hidden] { display: none; }
.ai-nudge-bar-hl { flex: 1 1 auto; display: inline-flex; align-items: center; gap: 6px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-nudge-bar-hl > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.ai-nudge-bar-hl svg.ic { flex: 0 0 auto; color: var(--primary); }
/* CLIE-505: вид = канон .cc-seg + .cc-seg-sm; здесь — только место в полоске
   и смысловой цвет варианта «Сейчас». Вправо сегмент толкает растущая подпись (flex 1 1 auto),
   а не margin-left:auto: перенесённый второй строкой, он встаёт под подпись слева — так же, как
   OverflowBar у близнеца CcAiNudgeBar (client/lib/widgets/ai_nudge.dart). */
.ai-nudge-seg { min-width: 0; max-width: 100%; }   /* сжимаемость оставлена: уже экрана даже одной строкой — лестница ccSegFit */
.ai-nudge-seg > button.active[data-nudge="now"] { color: var(--primary); }
html[data-theme="light"] .ai-nudge-seg button.active { box-shadow: 0 1px 2px var(--cm-141926-12, rgba(20,25,38,.12)); }

.ai-nudge-badge { display: inline-flex; align-items: center; gap: 4px; margin-top: 4px; padding: 2px 8px 2px 6px; border-radius: 999px; font-size: 11px; font-weight: 600; line-height: 1.55; border: 1px solid transparent; }
.ai-nudge-badge svg.ic { width: 12px; height: 12px; }
.ai-nudge-badge.now { color: var(--primary); background: color-mix(in srgb, var(--primary) 13%, transparent); border-color: color-mix(in srgb, var(--primary) 28%, transparent); }
.ai-nudge-badge.after { color: var(--muted); background: color-mix(in srgb, var(--muted) 12%, transparent); }
/* 0195: факт вместо обещания — «ИИ прочитал» (спокойный индиго) и «ИИ учёл» (акцент). */
.ai-nudge-badge.read { color: var(--primary-2); background: color-mix(in srgb, var(--primary-2) 12%, transparent); }
.ai-nudge-badge.done { color: var(--primary); background: color-mix(in srgb, var(--primary) 13%, transparent); border-color: color-mix(in srgb, var(--primary) 26%, transparent); }
.msg.mine .ai-nudge-badge { align-self: flex-end; }
/* CLIE-362: интерактивный «После текущего шага» — плашка состояния + акцентное действие «Сейчас».
   Пока ИИ работает и это ваше сообщение: тап «Сейчас» просит ИИ прочитать его сразу. */
.ai-nudge-wrap { display: inline-flex; align-items: center; gap: 6px; margin-top: 4px; }
.ai-nudge-wrap .ai-nudge-badge { margin-top: 0; }
.msg.mine .ai-nudge-wrap { align-self: flex-end; }
.ai-nudge-badge.act { appearance: none; font-family: inherit; cursor: pointer; padding: 3px 9px 3px 7px; transition: background .13s ease, box-shadow .13s ease, transform .04s ease; }
.ai-nudge-badge.act:hover { background: color-mix(in srgb, var(--primary) 22%, transparent); box-shadow: 0 1px 3px color-mix(in srgb, var(--primary) 20%, transparent); }
.ai-nudge-badge.act:active { transform: translateY(0.5px); }
.ai-nudge-badge.act:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 1px; }

/* 🔘 CRMC-1123 · КНОПКИ ПОД СООБЩЕНИЕМ ИИ-БОТА (быстрые ответы).
   Ряд-сосед пузыря, как .reactions и .ai-nudge-badge: .msg — flex-колонка, поэтому
   собственной раскладки ряду не нужно. Кнопка — ПРЕДЛОЖЕНИЕ, а не команда: спокойная
   подложка + акцентная рамка, при наведении заливка усиливается. Нажатая гаснет, но НЕ
   исчезает — человек должен видеть, что он выбрал (и что выбрал коллега в общем чате). */
.bot-btns { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; max-width: 100%; }
.msg.mine .bot-btns { justify-content: flex-end; }
.bot-btn {
  appearance: none; font-family: inherit; display: inline-flex; align-items: center; gap: 6px;
  max-width: 100%; padding: 6px 13px; border-radius: 999px; cursor: pointer;
  font-size: 13px; font-weight: 600; line-height: 1.35; text-align: left;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 30%, transparent);
  transition: background .13s ease, border-color .13s ease, box-shadow .13s ease, transform .04s ease;
}
.bot-btn:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); border-color: color-mix(in srgb, var(--primary) 46%, transparent); }
.bot-btn:active { transform: translateY(0.5px); }
.bot-btn:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 1px; }
.bot-btn svg.ic { width: 13px; height: 13px; flex: 0 0 auto; opacity: .85; }
/* Длинная подпись не рвёт пузырь: перенос внутри кнопки, а не горизонтальная прокрутка. */
.bot-btn .bb-t { overflow-wrap: anywhere; }
/* 🔴 РЯД ПОСЛЕ ВЫБОРА: выбранное — «галочка + текст» акцентом, остальные гаснут и
   перестают быть кнопками (pointer-events), но остаются читаемыми: это уже история
   разговора. `disabled` на них ставит и разметка — невидимый контрол = отсутствующий. */
.bot-btns.picked .bot-btn { cursor: default; pointer-events: none; }
.bot-btns.picked .bot-btn:not(.on) { color: var(--muted); background: transparent; border-color: var(--line); opacity: .62; }
.bot-btns.picked .bot-btn.on { color: #fff; background: var(--acc-fill); border-color: var(--acc-fill); }
.bot-btns.picked .bot-btn.on svg.ic { opacity: 1; }
/* Кто нажал — подпись рядом с рядом (в групповом чате выбор сделал конкретный человек). */
.bot-btns-by { margin-top: 3px; font-size: 11px; color: var(--muted); }
.msg.mine .bot-btns-by { align-self: flex-end; }
/* Светлая тема: на белом холсте 10% акцента почти не видно — поднимаем подложку и рамку
   (канон contrast-runtime-audit: контраст мерим к живому холсту, а не к токену). */
html[data-theme="light"] .bot-btn { background: color-mix(in srgb, var(--primary) 8%, #fff); border-color: color-mix(in srgb, var(--primary) 38%, transparent); }
html[data-theme="light"] .bot-btn:hover { background: color-mix(in srgb, var(--primary) 15%, #fff); }
html[data-theme="light"] .bot-btns.picked .bot-btn:not(.on) { background: #fff; }

/* ⭐ CRMC-1127 · КАРТОЧКА ОЦЕНКИ ОТВЕТА БОТА (CSAT).
   Ряд-сосед пузыря, как .bot-btns и .reactions: .msg — flex-колонка, своей раскладки карточке
   не нужно. 🔴 ЗВЁЗДЫ — ЕДИНСТВЕННЫЕ ЗВЁЗДЫ ПРОДУКТА (.v2-star + svgIcon("star")): второго
   набора иконок нет, здесь живым звёздам лишь возвращена кнопочная семантика (кнопка приносит
   свой appearance/border, их и гасим). Размеры поля и кнопок — токены ряда --ctl-h/--ctl-r/
   --ctl-fs, своих чисел не заводим (канон control-size). */
.csat-card { display: flex; flex-direction: column; gap: 6px; align-self: flex-start;
  max-width: 100%; margin-top: 6px; padding: 8px 11px; border-radius: 12px;
  background: color-mix(in srgb, var(--primary) 9%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 26%, transparent); }
.msg.mine .csat-card { align-self: flex-end; }
.csat-stars { display: inline-flex; align-items: center; gap: 2px; }
.csat-card .v2-star { appearance: none; border: 0; background: none; padding: 1px; font: inherit; }
.csat-card button.v2-star { cursor: pointer; transition: color .12s ease, transform .05s ease; }
.csat-card button.v2-star:hover { color: #ffd54a; transform: translateY(-1px); }
.csat-card button.v2-star:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent);
  outline-offset: 1px; border-radius: 5px; }
.csat-card.rated .v2-star { cursor: default; }
.csat-say { font-size: 12.5px; color: var(--text); line-height: 1.4; }
.csat-say.dim { font-size: 11.5px; color: var(--muted); }
.csat-say.good { display: flex; align-items: center; gap: 6px; color: var(--primary); }
.csat-say.good svg.ic { width: 13px; height: 13px; flex: none; }
.csat-by, .csat-cm-said { font-size: 11.5px; color: var(--muted); overflow-wrap: anywhere; }
/* Комментарий — ПОСЛЕ выбора звезды (прогрессивное раскрытие): до выбора спрашивать нечего. */
.csat-cm { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.csat-cm-i { flex: 1 1 180px; min-width: 140px; box-sizing: border-box; height: var(--ctl-h);
  padding: 0 10px; border: 1px solid var(--line); border-radius: var(--ctl-r);
  background: var(--input-bg); color: var(--text); font: inherit; font-size: var(--ctl-fs); outline: none;
  transition: border-color .13s ease, box-shadow .13s ease; }
.csat-cm-i:focus { border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); box-shadow: 0 0 0 3px var(--glow); }
.csat-send, .csat-call { appearance: none; font-family: inherit; display: inline-flex; align-items: center;
  gap: 6px; height: var(--ctl-h); padding: 0 12px; border: 1px solid transparent; border-radius: var(--ctl-r);
  background: var(--acc-fill); color: #fff; font-size: var(--ctl-fs); font-weight: 600; cursor: pointer;
  white-space: nowrap; transition: background .13s ease, opacity .13s ease; }
.csat-call { align-self: flex-start; }
.csat-send:hover, .csat-call:hover { background: color-mix(in srgb, var(--primary) 88%, #fff); }
.csat-send svg.ic, .csat-call svg.ic { width: 13px; height: 13px; flex: none; }
.csat-send[disabled], .csat-call[disabled] { opacity: .6; cursor: default; }
/* Плохая оценка — это ВЫХОД, а не тревога: тон карточки меняется, действие остаётся акцентным. */
.csat-card.bad { background: color-mix(in srgb, var(--danger) 9%, transparent);
  border-color: color-mix(in srgb, var(--danger) 28%, transparent); }
/* Светлая тема: на белом холсте 9% акцента почти не видно — поднимаем подложку и рамку
   (канон contrast-runtime-audit: контраст мерим к живому холсту, а не к токену). */
html[data-theme="light"] .csat-card { background: color-mix(in srgb, var(--primary) 7%, #fff);
  border-color: color-mix(in srgb, var(--primary) 32%, transparent); }
html[data-theme="light"] .csat-card.bad { background: color-mix(in srgb, var(--danger) 7%, #fff);
  border-color: color-mix(in srgb, var(--danger) 34%, transparent); }

/* ── 3.16 Логин: карточка с тенью + лёгкое брендовое свечение канвы ── */
.login { background: radial-gradient(90% 65% at 50% -12%, color-mix(in srgb, var(--primary) 9%, transparent), transparent 62%); }
html[data-theme="light"] .card { box-shadow: var(--shadow-2); border-color: var(--cm-171e34-09, rgba(23,30,52,.09)); }
.login .logo { display: flex; align-items: center; justify-content: center; }
/* брендовый знак (SVG-плитка с градиентом) на логине */
.brand-mark {
  width: 56px; height: 56px; border-radius: 16px;
  background: var(--grad);
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 10px 26px -8px var(--glow);
}
.brand-mark svg.ic { width: 30px; height: 30px; color: #fff; }
/* …но красная кнопка «положить трубку» на hover остаётся красной */
.call-controls .danger:hover, .mini-bar .danger:hover, .groupcall-overlay .danger:hover {
  background: var(--danger); filter: brightness(1.12);
}

/* ── 3.17 Кнопки «иконка + подпись» (index.html теперь на SVG вместо эмодзи):
   глобальное button svg.ic { 22px; display:block } ставит иконку НАД текстом —
   для комбинированных кнопок делаем inline-flex и соразмерную иконку 16px.
   (msgMenu, newGroupBtn, logoutBtn уже были flex — включаем для единообразия;
   dl-карточки скачивания НЕ трогаем — там колоночный лейаут.)
   🔴 НЕ писать внутри комментария последовательность «звёздочка+слэш» (как было в
   «msgMenu*<слэш>newGroupBtn»): CSS закрывает комментарий на ПЕРВОМ же таком сочетании,
   хвост уезжает в селектор и браузер ВЫБРАСЫВАЕТ следующее правило целиком. Здесь из-за
   этого правило #installBtn… ниже НЕ применялось на проде (проверено в CSSOM 2026-08-12):
   иконка вставала НАД подписью вместо «иконка + текст в строку». ── */
#installBtn, #notifyTopBtn, #backBtn, #gsAddBtn, #ciInviteBtn,
#recReportTasksBtn, #recReportDownload, #recReportVideo, #profileAddMediaBtn,
#userProfileRenameBtn, #folderNewBtn, #aiVoiceEndBtn,
#circleStart, #circleStop, #mediaRecStart, #mediaRecStop, #recStop {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  white-space: nowrap;
}
#installBtn svg.ic, #notifyTopBtn svg.ic, #backBtn svg.ic,
#gsAddBtn svg.ic, #ciInviteBtn svg.ic, #recReportTasksBtn svg.ic,
#recReportDownload svg.ic, #recReportVideo svg.ic, #profileAddMediaBtn svg.ic,
#userProfileRenameBtn svg.ic, #folderNewBtn svg.ic, #aiVoiceEndBtn svg.ic,
#circleStart svg.ic, #circleStop svg.ic, #mediaRecStart svg.ic, #mediaRecStop svg.ic,
#recStop svg.ic {
  width: 16px; height: 16px; display: inline-block; flex: none;
}
/* стрелки лайтбокса и док-стрелки мини-звонка теперь SVG — центрируем и размерим */
.lightbox-overlay .lb-prev svg.ic, .lightbox-overlay .lb-next svg.ic { width: 26px; height: 26px; display: block; }
.mini-restore svg.ic { width: 16px; height: 16px; display: block; }

/* ── 3.18 РЕДИЗАЙН «A · Ясный минимал» — компоненты светлой темы (владелец выбрал направление A из
   2 отрисованных на реальной разметке, 2026-07-15). Заменяет прежние итерации столбика задач.
   Язык A: белые панели/карточки на светлой канве, тонкие хэйрлайны, мягкие пилюли, индиго-акцент.
   ТОЛЬКО светлая тема; тёмную не трогаем. ── */

/* Сегмент «Личное/Работа»: трек + активная белая пилюля с тенью */
html[data-theme="light"] .mode-toggle { background: var(--panel-2); border-color: var(--line); border-radius: 11px; }
html[data-theme="light"] .mode-seg { color: var(--muted); border-radius: 8px; }
html[data-theme="light"] .mode-seg.active { background: var(--panel); color: var(--primary); box-shadow: 0 1px 3px var(--cm-141928-14, rgba(20,25,40,.14)); }
html[data-theme="light"] .mode-seg.active .mode-badge { background: var(--acc-fill); color: #fff; }

/* Рельс: активный пункт — сплошной бренд */
html[data-theme="light"] .rail-item.active { background: var(--acc-fill); color: #fff; }
html[data-theme="light"] .rail-item.active .rail-badge { background: #fff; color: var(--acc-fill); }

/* Табы (Мне/Я поставил и фильтры чатов): мягкая пилюля, активная — сплошной бренд */
html[data-theme="light"] .task-lens-btn { background: var(--panel-2); border: 1px solid transparent; border-radius: 9px; color: var(--muted); font-weight: 600; }
html[data-theme="light"] .task-lens-btn.active { background: var(--acc-fill); border-color: transparent; color: #fff; }
html[data-theme="light"] .task-lens-btn .task-lens-n { background: var(--cm-141928-06, rgba(20,25,40,.06)); color: var(--muted); }
/* 🔴 CLIE-888·3: подложка счётчика на АКТИВНОМ индиго-чипе была СВЕТЛЕЕ самого чипа
   (rgba(255,255,255,.26) поверх #5560cf = #8189db) — то есть белые цифры лежали на
   осветлённом индиго: 3.21:1 у «в работе» и 2.91:1 у «к выполнению». Замер живого прода.
   Правило класса: подложка ВНУТРИ залитой кнопки идёт в сторону ТЕМНЕЕ заливки, тогда
   белые чернила на ней только выигрывают. Стало: 7.20:1 и 5.71:1. */
html[data-theme="light"] .task-lens-btn.active .task-lens-n { background: rgba(11,16,32,.22); color: #fff; }
/* Светлая тема, двойной счётчик: хэйрлайн темнее (на почти-белой подложке неактивного чипа
   var(--line) не читался) + контраст числа «К выполнению» на АКТИВНОМ индиго-чипе.
   Тёмная тема уже норм — только light-override. */
html[data-theme="light"] .task-lens-btn .task-lens-n .tln-sep { background: var(--cm-141928-16, rgba(20,25,40,.16)); }
html[data-theme="light"] .task-lens-btn.active .task-lens-n .tln-todo { color: rgba(255,255,255,.85); }
/* 🔴 CLIE-888·3: АКЦЕНТНЫЕ ЧЕРНИЛА НА ПОДЛОЖКЕ — это --primary-2, а не --primary.
   У токенов светлой темы для этого и заведён отдельный «глубокий индиго: имена/цитаты/
   текст-акценты (AA)» (concept-6.css), но число «в работе» на пилюле счётчика брало
   --primary: 4.14:1 при AA 4.5. С --primary-2 — 5.44:1. Заливка/оттенок те же. */
html[data-theme="light"] .task-lens-btn .task-lens-n .tln-work { color: var(--primary-2); }
/* 🔴 CLIE-888·3, ТОТ ЖЕ КЛАСС в почте: выбранная папка — акцентные чернила на акцентном
   тинте (`.mail-folder.active{background:var(--accent-tint);color:var(--accent)}`), в
   светлой теме 3.68:1. Лечим чернилами того же семейства (--primary-2 → 4.82:1), заливку
   и оттенок не трогаем. Тёмная тема сюда не попадает — селектор light-only. */
html[data-theme="light"] .mail-folder.active { color: var(--primary-2); }
/* 🔴 CLIE-888·3: янтарь `#c9873a` у метки доступа файла прибит числом и подобран к ТЁМНОМУ
   фону — на белой строке таблицы это 3.00:1. В светлой теме берём янтарь ТОЙ ЖЕ семантики
   из палитры (--warning #8a5c14 = 5.80:1); заливка и кромка метки те же, тёмная не тронута. */
html[data-theme="light"] .fsb-acc-restricted { color: var(--warning); }
/* 🔴 CLIE-888·3, тот же класс в каталоге специалистов: зарплата `.dir-pay` красится
   `var(--accent)` из ПОЗЖЕ инжектируемого блока (он перебивает `.dir-pay{--primary-2}`
   выше по файлу), и на тёплом холсте это 4.23:1. Светлой теме отдаём те же чернила
   текст-акцента — 5.55:1; тёмная не тронута. */
html[data-theme="light"] .dir-pay,
html[data-theme="light"] .dir-link { color: var(--primary-2); }
/* 🔴 CLIE-888·3, ТОТ ЖЕ КЛАСС в воронке: зелёный `#22a06b` прибит числом и подобран к
   ТЁМНОМУ фону — на светлой колонке «Won» это 2.93:1 (замер живого прода). В светлой теме
   берём зелёный ТОЙ ЖЕ семантики из палитры (--urg-done = 5.23:1 на подложке колонки);
   заливки пилюль не тронуты, тёмная тема не тронута. */
html[data-theme="light"] .deal-col.cat-won .tw-col-name,
html[data-theme="light"] .deal-row-status.st-won,
html[data-theme="light"] .deal-status-pill.st-won { color: var(--urg-done); }
/* 🔴 CLIE-1585 · ТОЛЬКО У РАЗВЁРНУТОЙ КОЛОНКИ. В свёрнутой (`.mail-side.min`) бейдж — это
   ЗАЛИТАЯ пилюля (`background: var(--accent)` + белые чернила), и тёмно-синий `--primary-2`
   на синей заливке давал 1.4:1: замер прода 28.09 поймал его первым же прогоном. Правило темы
   сильнее по специфичности, чем правило формы, поэтому исключение стоит ЗДЕСЬ, а не там. */
html[data-theme="light"] .mail-side:not(.min) .mail-folder.active .mf-badge { color: var(--primary-2); }

/* Карточка задачи: белый остров на светлой канве (направление A, владелец 2026-07-15);
   тонкий бордер + скругление, тень.
   Планка приоритета слева убрана (владелец 2026-07-27) — ровный 1px-хэйрлайн по кругу.
   Чипы внутри → --panel-2 (ниже), чтобы читались на белой карточке. */
/* 🔴 СРЕД-30. Здесь стоял ХОЛОДНЫЙ хардкод #edf1f8 — «почти цвет холста»: против базовой
   светлой канвы #eef1f7 это контраст 1.001, т.е. карточка и фон под ней НЕРАЗЛИЧИМЫ (ровно
   «блоки не выделены»), а на тёплом холсте боевого концепта #e9e5df тот же цвет читается
   синеватой плиткой. При этом заявленный язык направления A — «БЕЛЫЕ карточки на светлой
   канве». Возвращаем белую карточку токеном: она сама тёплая под концептом и сама
   отделяется теперь видимым --line. */
html[data-theme="light"] .tasks-list .tw-card:where(:not(.ai-self)) {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 14px; box-shadow: var(--shadow-1);
}
/* Нейтральные чипы ВНУТРИ карточки задачи — белые инсет (читаются на off-white фоне карточки) */
html[data-theme="light"] .tasks-list .tw-card .tw-pill.tw-pill-area,
html[data-theme="light"] .tasks-list .tw-card .tw-pill.sub,
html[data-theme="light"] .tasks-list .tw-card .tw-pill.link,
html[data-theme="light"] .tasks-list .tw-card .tw-pill.parent,
html[data-theme="light"] .tasks-list .tw-card .tw-pill.chat:not(.unread) { background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
/* .tw-ck-bar: холодный #dde4ef убран — базовое правило уже красит дорожку в var(--line),
   который теперь виден и сам следует за темой/концептом. Второго значения не заводим. */
/* Планка приоритета слева убрана в светлой теме (владелец 2026-07-27) — без цветного
   border-left; приоритет виден в детали задачи и по наведению (кнопка-флаг). */
html[data-theme="light"] .tasks-list .tw-card:where(:not(.ai-self)):hover { border-color: var(--line-strong); box-shadow: 0 4px 14px -5px var(--cm-141928-18, rgba(20,25,40,.18)); }
/* CLIE-1946: «подъём» при перетаскивании (.dragging, база — у .tw-card.dragging) светлая тень
   покоя/ховера не съедает — близнец того же веса стоит ПОСЛЕ них. */
html[data-theme="light"] .tw-card.dragging:where(:not(.ai-self)),
html[data-theme="light"] .tasks-list .tw-card.dragging:where(:not(.ai-self)) { box-shadow: var(--shadow-3); }
/* Нейтральные чипы: мягкая подложка + тонкое кольцо, спокойный текст */
html[data-theme="light"] .tw-pill.tw-pill-area,
html[data-theme="light"] .tw-pill.sub,
html[data-theme="light"] .tw-pill.link,
html[data-theme="light"] .tw-pill.parent,
html[data-theme="light"] .tw-pill.chat:not(.unread) { background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); color: var(--muted); }
html[data-theme="light"] .tw-pill.tw-pill-area,
html[data-theme="light"] .tw-pill.parent,
html[data-theme="light"] .tw-pill.chat:not(.unread) { color: var(--muted); }
/* Чип «карточка ИЗ ДРУГОГО ПРОЕКТА» (CLIE-423): на доске проекта задача может быть видна сводкой
   — по проекту её чата или по родительскому проекту. Чип помечает такие карточки, чтобы «чужая»
   не выглядела родной. Тон — спокойный янтарный (тот же язык, что у предупреждающих состояний),
   без заливки-кричалки: тонкое кольцо + мягкая подложка. */
.tw-pill.tw-pill-foreign { background: rgba(214,158,46,.12); box-shadow: inset 0 0 0 1px rgba(214,158,46,.34); color: #8a6116; }
.tw-pill.tw-pill-foreign svg.ic { opacity: .8; }
html[data-theme="light"] .tw-pill.tw-pill-foreign,
html[data-theme="light"] .tasks-list .tw-card .tw-pill.tw-pill-foreign { background: rgba(191,138,32,.10); box-shadow: inset 0 0 0 1px rgba(191,138,32,.30); color: #8a6116; }
html[data-theme="dark"] .tw-pill.tw-pill-foreign,
html[data-theme="dark"] .tasks-list .tw-card .tw-pill.tw-pill-foreign { background: rgba(230,178,74,.14); box-shadow: inset 0 0 0 1px rgba(230,178,74,.32); color: #e0b866; }
/* 🔴 CLIE-481 «указал чат — не понятно, какой проект». ВТОРАЯ ПОЛОВИНА ПРИНАДЛЕЖНОСТИ —
   чат под проектом (или честное «вне проектов»). Одна пилюля, а не второй элемент рядом:
   проект — основным тоном, чат — тише, через тонкую точку-разделитель. Один класс на все
   поверхности (пилюля доски/списка, чип строки «Мои задачи», строка модалки). */
.tw-pill-sub, .tip-chipsub, .tc-pop-sub { color: var(--muted); font-weight: 400; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Пилюля с двумя половинами не имеет права вылезать за карточку доски (замер: карточка 240px,
   «АртРест · Приложение Менеджера» шире) — усекаем по …, проект остаётся читаемым целиком. */
.tw-pill.tw-pill-area { max-width: 100%; min-width: 0; }
/* Первым усекается ЧАТ, а не проект: проект — это ответ на «на чьей доске задача», его
   резать нельзя (замер на проде: «АртРест · Приложение Менеджера» в карточке 240px давал
   «Арт… · Приложение М…»). Поэтому main не сжимается (flex-shrink 0), но и не вылезает
   (max-width 100% + …), а sub отдаёт место первым. */
.tw-pill-main { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 0 0 auto; max-width: 100%; }
.tw-pill-area .tw-pill-sub { flex: 0 1 auto; min-width: 0; }
.tw-pill-sub::before, .tip-chipsub::before { content: "·"; margin: 0 .34em; opacity: .55; }
/* подпись пилюли тише ЦВЕТОМ (--muted выше), без opacity .82: та гасила её до 4.25:1 (волна 3) */
.tip-chipsub { display: inline-flex; align-items: center; gap: 4px; font-size: 12.5px; }
.tip-chipsub svg.ic { width: 12px; height: 12px; opacity: .75; }
.tc-pop-name .tc-pop-sub { display: block; font-size: 11.5px; line-height: 1.25; margin-top: 1px; }
/* .tw-ck-bar — дорожка берётся из базового правила (var(--line)); холодный #e7ebf4 убран (СРЕД-30). */
html[data-theme="light"] .tasks-list .tst-none { color: var(--text-dim); }
/* CLIE-1946 · «Отменено» #8a93a3 на белом 3.1:1, «Без срока» #6B7280 на тёплом холсте 3.8 — вторичные
   чернила темы (--muted: AA и на серой подложке). */
html[data-theme="light"] .tasks-list .tst-cancelled,
html[data-theme="light"] .tw-sec-title.tst-none,
html[data-theme="light"] .tw-sec-title.tst-cancelled { color: var(--muted); }
/* «Идёт таймер»: светлый var(--info) (#2f5bd0) на белом даёт бледный заголовок и слабую
   кнопку — берём тот же #1d4ed8 / rgba(37,99,235,…), что уже у бейджа .tw-pill-timer,
   чтобы секция, фильтр и бейдж читались как ОДНА семья и в светлой теме. */
html[data-theme="light"] .tasks-list .tst-running,
html[data-theme="light"] .tasks-list .tst-wip,
html[data-theme="light"] .tw-sec-title.tst-running,
html[data-theme="light"] .tw-sec-title.tst-wip { color: var(--cm-1d4ed8, #1d4ed8); }
html[data-theme="light"] .tw-run-btn:hover { border-color: var(--cm-1d4ed8, #1d4ed8); }
html[data-theme="light"] .tw-run-btn:focus { border-color: var(--cm-1d4ed8, #1d4ed8); box-shadow: 0 0 0 3px rgba(37,99,235,.16); }
html[data-theme="light"] .tw-run-btn.active { color: var(--cm-1d4ed8, #1d4ed8); border-color: rgba(37,99,235,.42); background: rgba(37,99,235,.12); }
html[data-theme="light"] .tw-run-btn.active svg.ic { color: var(--cm-1d4ed8, #1d4ed8); }

/* Список чатов: скруглённые строки, активная — бренд-софт */
html[data-theme="light"] .conv-item { border-radius: 13px; border: 1px solid transparent; }
html[data-theme="light"] .conv-item.active { background: var(--sel); border-color: transparent; }
html[data-theme="light"] .conv-item:hover:not(.active) { background: var(--panel-2); }

/* Переписка: белый пузырь собеседника с бордером всплывает на канве; свой — индиго */
html[data-theme="light"] .msg.theirs .bubble { background: #fff; border: 1px solid var(--line); box-shadow: 0 1px 2px var(--cm-141928-05, rgba(20,25,40,.05)); }

/* Композер: приподнятая скруглённая карточка */
html[data-theme="light"] .composer { background: var(--panel); border-top: 1px solid var(--line); }

/* ═══════════════════════════════════════════════════════════════════════════
   §3.14 БОГАТОЕ СООБЩЕНИЕ (format="md") — docs/rich-message-editor.md §3.
   .md-msg — тот же .md-body, но компактнее: внутри пузыря чата, а не карточки
   задачи. Плюс общие для обеих сред конструкции: таблица, callout, подсветка,
   спойлер. Только токены, обе темы вылизаны отдельно.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── типографика внутри пузыря: плотнее описания задачи ── */
.md-msg { font-size: inherit; line-height: 1.45; }
.md-msg > *:first-child { margin-top: 0; }
.md-msg > *:last-child { margin-bottom: 0; }
.md-msg p { margin: 0 0 6px; }
.md-msg h1 { font-size: 1.16em; font-weight: 700; margin: 10px 0 5px; line-height: 1.28; letter-spacing: -.01em; }
.md-msg h2 { font-size: 1.08em; font-weight: 700; margin: 9px 0 4px; line-height: 1.3; letter-spacing: -.005em; }
.md-msg h3 { font-size: 1em; font-weight: 650; margin: 8px 0 3px; color: inherit; opacity: .92; }
.md-msg ul, .md-msg ol { margin: 0 0 6px; padding-left: 18px; }
.md-msg li { margin: 2px 0; }
.md-msg ul.md-tasklist { padding-left: 0; }
.md-msg .md-task { gap: 8px; margin: 3px 0; }
.md-msg .md-cb { width: 15px; height: 15px; border-radius: 4px; }
.md-msg .md-cb::after { left: 4.3px; top: 1px; width: 3.4px; height: 7px; }
/* CLIE-483: рейку сняли — цитата держится мягкой подложкой (currentColor, годна и на «своём» пузыре) */
.md-msg blockquote { margin: 0 0 6px; padding: 5px 9px; border-radius: var(--r-md); background: color-mix(in srgb, currentColor 9%, transparent); opacity: .78; }
.md-msg pre { margin: 0 0 6px; padding: 8px 10px; border-radius: var(--r-md); background: rgba(0,0,0,.22); border-color: rgba(255,255,255,.07); }
.md-msg pre code { font-size: .86em; line-height: 1.5; }

/* ── Ответ помощника (ассистента) = markdown внутри .ai-bubble ──
   У пузыря white-space:pre-wrap (сохраняет пробелы «своих» реплик), но у markdown-тела
   переносы «\n» между блоками mdToHtml тогда рисовались бы пустыми строками — гасим их
   для .md-body. Свой текст (formatText) остаётся pre-wrap. */
.ai-bubble > .md-body { white-space: normal; }
.ai-bubble > .md-body hr { margin: 9px 0; }
.md-msg code { font-size: .87em; padding: 1px 4px; border-radius: var(--r-xs); }
.md-msg hr { margin: 9px 0; border: 0; border-top: 1px solid var(--line); opacity: .7; }
.md-msg a { color: inherit; border-bottom-color: currentColor; opacity: .95; }

/* ── .md-note: тот же .md-body, но компактнее — внутри узкой карточки заметки задачи,
   не описания. Копия .md-msg (тот же приём), другое место применения. ── */
.md-note { font-size: inherit; line-height: 1.42; }
.md-note > *:first-child { margin-top: 0; }
.md-note > *:last-child { margin-bottom: 0; }
.md-note p { margin: 0 0 6px; }
.md-note h1 { font-size: 1.16em; font-weight: 700; margin: 8px 0 4px; line-height: 1.28; letter-spacing: -.01em; }
.md-note h2 { font-size: 1.08em; font-weight: 700; margin: 7px 0 4px; line-height: 1.3; letter-spacing: -.005em; }
.md-note h3 { font-size: 1em; font-weight: 650; margin: 6px 0 3px; color: inherit; opacity: .92; }
.md-note ul, .md-note ol { margin: 0 0 6px; padding-left: 18px; }
.md-note li { margin: 2px 0; }
.md-note ul.md-tasklist { padding-left: 0; }
.md-note .md-task { gap: 8px; margin: 3px 0; }
.md-note .md-cb { width: 15px; height: 15px; border-radius: 4px; }
.md-note .md-cb::after { left: 4.3px; top: 1px; width: 3.4px; height: 7px; }
/* CLIE-483: рейку сняли — цитата держится мягкой подложкой (currentColor, обе темы) */
.md-note blockquote { margin: 0 0 6px; padding: 5px 9px; border-radius: var(--r-md); background: color-mix(in srgb, currentColor 9%, transparent); opacity: .78; }
.md-note pre { margin: 0 0 6px; padding: 8px 10px; border-radius: var(--r-md); background: var(--panel-3); border-color: var(--line); }
.md-note pre code { font-size: .86em; line-height: 1.5; }
.md-note code { font-size: .87em; padding: 1px 4px; border-radius: var(--r-xs); }
.md-note hr { margin: 8px 0; border: 0; border-top: 1px solid var(--line); opacity: .7; }

/* ── таблица (§3.1 п.2): тонкие хэйрлайны, без зебры, скролл по горизонтали ── */
.md-tablewrap { margin: 0 0 8px; overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--line); border-radius: var(--r-md); }
.md-tablewrap::-webkit-scrollbar { height: 6px; }
.md-tablewrap::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: var(--r-full); }
.md-table { border-collapse: collapse; width: 100%; font-size: .95em; font-variant-numeric: tabular-nums; }
/* 🔴 КОЛОНКА НЕ СХЛОПЫВАЕТСЯ В ЛЕСТНИЦУ ИЗ ОДНОГО СЛОВА. `width:100%` у таблицы честно
   вписывает её в ленту, но в узкой ленте (379px у «Чата с ИИ») пятиколоночная таблица
   отчёта превращалась в столбик по слову в строке — формально «влезло», читать нельзя.
   Нижняя граница ячейки переводит этот случай в ПРОКРУТКУ обёртки (она для того и есть):
   узко — листаем вбок, широко — таблица как была. */
.md-table th, .md-table td { padding: 6px 10px; text-align: left; vertical-align: top; min-width: 96px; border-bottom: 1px solid var(--line); border-right: 1px solid var(--line); }
.md-table th:last-child, .md-table td:last-child { border-right: 0; }
.md-table tbody tr:last-child td { border-bottom: 0; }
.md-table thead th { font-weight: 650; color: var(--muted); background: rgba(255,255,255,.03); white-space: nowrap; }

/* ── callout (§3.1 п.3): мягкая подложка семантическим цветом + цветной заголовок ── */
/* CLIE-483: рейку сняли — семантику несут заголовок .md-cal-h, подложка *-soft и кольцо 1px */
.md-callout { margin: 0 0 8px; padding: 8px 12px; border-radius: var(--r-md); background: var(--hover); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 22%, transparent); }
.md-callout .md-cal-h { font-weight: 650; font-size: .95em; letter-spacing: -.005em; margin-bottom: 2px; }
.md-callout .md-cal-b { opacity: .9; }
.md-callout .md-cal-b:first-child { margin-top: 0; }
/* 🔴 На СВОЁМ пузыре (яркий градиент --grad) семантические цвета не читаются: заголовок
   callout'а «Что важно» цвета --warning на фиолетовом почти сливался (пруф feedb-r2-*.png).
   Перекрываем на бело-контрастные — ровно как уже сделано для цитаты и превью ссылки. */
.msg.mine .md-callout { background: rgba(255,255,255,.16); box-shadow: inset 0 0 0 1px rgba(255,255,255,.30); }
.msg.mine .md-callout .md-cal-h { color: #fff; }
.msg.mine .md-callout .md-cal-b { color: rgba(255,255,255,.94); opacity: 1; }
.msg.mine .md-msg blockquote { background: rgba(255,255,255,.16); }
.md-cal-note { background: var(--info-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--info) 22%, transparent); }
.md-cal-note .md-cal-h { color: var(--info); }
.md-cal-tip { background: var(--ok-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 22%, transparent); }
.md-cal-tip .md-cal-h { color: var(--ok); }
.md-cal-warn { background: var(--warning-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 22%, transparent); }
.md-cal-warn .md-cal-h { color: var(--warning); }
.md-cal-danger { background: var(--danger-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent); }
.md-cal-danger .md-cal-h { color: var(--danger); }
.md-cal-quote { background: var(--sel); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.md-cal-quote .md-cal-h { color: var(--primary-2); }
.md-cal-quote .md-cal-b { font-style: italic; }

/* ══════════════════════════════════════════════════════════════════════════════
   🔴 CLIE-945 · ОФОРМЛЕНИЕ ТЕКСТА: цвет · фон · шрифт · размер · подчёркивание
   Разметка — ОДИН токен `[текст]{c=red;bg=yellow;f=serif;s=lg;u}` (контракт §3.2а),
   классы ставит mdStyleClasses(). Значения ТОЛЬКО из реестра, поэтому имя цвета
   разворачивается вот в эти переменные, а не в произвольный hex из текста.

   🔴 ПОЧЕМУ ИМЕНОВАННАЯ ПАЛИТРА, А НЕ СВОБОДНЫЙ ЦВЕТ (канон theme-contrast, CLIE-888):
   прибитый цвет виден ровно в ОДНОЙ из двух тем. Здесь у каждого имени ТРИ значения:
   тёмная тема, светлая тема и «на тёмной подложке» (--mdcd-*) — последнее для СВОЕГО
   пузыря (.msg.mine .bubble = индиго-градиент с белым текстом в обеих темах) и для
   любой другой тёмной поверхности.
   ══════════════════════════════════════════════════════════════════════════════ */
:root {
  --mdc-red: #ff7a6e;    --mdc-orange: #ffab5e; --mdc-yellow: #f2cf5b; --mdc-green: #6ede8a;
  --mdc-teal: #5fd4c8;   --mdc-blue: #7db3ff;   --mdc-purple: var(--cm-c39bff, #c39bff); --mdc-pink: #ff8ecb;
  --mdc-gray: #9aa4b2;
  /* «на тёмной подложке» = светлые варианты (свой пузырь тёмный ВСЕГДА) */
  --mdcd-red: #ff9f96;   --mdcd-orange: #ffc184; --mdcd-yellow: #ffe08a; --mdcd-green: #93e8a8;
  --mdcd-teal: #86e2d8;  --mdcd-blue: #a9ccff;   --mdcd-purple: var(--cm-d4b8ff, #d4b8ff); --mdcd-pink: #ffb0da;
  --mdcd-gray: #d3d9e2;
}
html[data-theme="light"] {
  --mdc-red: #c62828;    --mdc-orange: #a55200; --mdc-yellow: #7d6300; --mdc-green: #1a7431;
  --mdc-teal: #0f766e;   --mdc-blue: #1a56c4;   --mdc-purple: var(--cm-6b21a8, #6b21a8); --mdc-pink: #a81f63;
  --mdc-gray: #5b6472;
}
/* Фон-маркер: тинт 20% того же тона + чернила того же тона в полную силу. Правила фона
   стоят ВЫШЕ правил цвета намеренно: специфичность равная, поэтому при `c=` + `bg=`
   выигрывает цвет (последнее правило), и человек получает ровно то, что выбрал. */
.md-bg-red, .md-bg-orange, .md-bg-yellow, .md-bg-green, .md-bg-teal,
.md-bg-blue, .md-bg-purple, .md-bg-pink, .md-bg-gray {
  padding: 0 3px; border-radius: var(--r-xs, 6px);
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
.md-bg-red { background: color-mix(in srgb, var(--mdc-red) 20%, transparent); color: var(--mdc-red); }
.md-bg-orange { background: color-mix(in srgb, var(--mdc-orange) 20%, transparent); color: var(--mdc-orange); }
.md-bg-yellow { background: color-mix(in srgb, var(--mdc-yellow) 22%, transparent); color: var(--mdc-yellow); }
.md-bg-green { background: color-mix(in srgb, var(--mdc-green) 20%, transparent); color: var(--mdc-green); }
.md-bg-teal { background: color-mix(in srgb, var(--mdc-teal) 20%, transparent); color: var(--mdc-teal); }
.md-bg-blue { background: color-mix(in srgb, var(--mdc-blue) 20%, transparent); color: var(--mdc-blue); }
.md-bg-purple { background: color-mix(in srgb, var(--mdc-purple) 20%, transparent); color: var(--mdc-purple); }
.md-bg-pink { background: color-mix(in srgb, var(--mdc-pink) 20%, transparent); color: var(--mdc-pink); }
.md-bg-gray { background: color-mix(in srgb, var(--mdc-gray) 22%, transparent); color: var(--mdc-gray); }
.md-c-red { color: var(--mdc-red); }        .md-c-orange { color: var(--mdc-orange); }
.md-c-yellow { color: var(--mdc-yellow); }  .md-c-green { color: var(--mdc-green); }
.md-c-teal { color: var(--mdc-teal); }      .md-c-blue { color: var(--mdc-blue); }
.md-c-purple { color: var(--mdc-purple); }  .md-c-pink { color: var(--mdc-pink); }
.md-c-gray { color: var(--mdc-gray); }
/* 🔴 Свой пузырь — индиго-градиент с белым текстом в ОБЕИХ темах. Светлая палитра на нём
   даёт 1.5:1 и ниже, поэтому там всегда светлые варианты (тот же приём, что у callout'ов). */
.msg.mine .bubble .md-c-red, .msg.mine .bubble .md-bg-red { color: var(--mdcd-red); }
.msg.mine .bubble .md-c-orange, .msg.mine .bubble .md-bg-orange { color: var(--mdcd-orange); }
.msg.mine .bubble .md-c-yellow, .msg.mine .bubble .md-bg-yellow { color: var(--mdcd-yellow); }
.msg.mine .bubble .md-c-green, .msg.mine .bubble .md-bg-green { color: var(--mdcd-green); }
.msg.mine .bubble .md-c-teal, .msg.mine .bubble .md-bg-teal { color: var(--mdcd-teal); }
.msg.mine .bubble .md-c-blue, .msg.mine .bubble .md-bg-blue { color: var(--mdcd-blue); }
.msg.mine .bubble .md-c-purple, .msg.mine .bubble .md-bg-purple { color: var(--mdcd-purple); }
.msg.mine .bubble .md-c-pink, .msg.mine .bubble .md-bg-pink { color: var(--mdcd-pink); }
.msg.mine .bubble .md-c-gray, .msg.mine .bubble .md-bg-gray { color: var(--mdcd-gray); }
.msg.mine .bubble [class*="md-bg-"] { background: rgba(255,255,255,.2); }
/* шрифт · размер · подчёркивание */
.md-f-sans { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
.md-f-serif { font-family: Georgia, "Times New Roman", "Iowan Old Style", serif; }
.md-f-mono { font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: .94em; }
.md-s-xs { font-size: .78em; }  .md-s-sm { font-size: .88em; }
.md-s-lg { font-size: 1.2em; }  .md-s-xl { font-size: 1.45em; font-weight: 600; }
.md-u { text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1.5px; }

/* ── ==подсветка== ── */
.md-hl { background: var(--warning-soft); color: inherit; padding: 0 3px; border-radius: var(--r-xs); box-decoration-break: clone; -webkit-box-decoration-break: clone; }

/* ── ||спойлер||: скрыт до тапа, раскрывается плавно ── */
.md-spoiler {
  background: var(--panel-3); color: transparent; cursor: pointer;
  border-radius: var(--r-xs); padding: 0 3px; user-select: none;
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
  transition: background var(--dur-2) var(--ease), color var(--dur-2) var(--ease);
}
.md-spoiler:hover { background: var(--line-strong); }
.md-spoiler:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.md-spoiler > * { visibility: hidden; }
.md-spoiler.on { background: transparent; color: inherit; cursor: auto; user-select: text; }
.md-spoiler.on:hover { background: transparent; }
.md-spoiler.on > * { visibility: visible; }

/* ── светлая тема: подложки/хэйрлайны считаются заново (в тёмной они на прозрачном белом) ── */
html[data-theme="light"] .md-msg pre { background: var(--panel-2); border-color: var(--line); }
html[data-theme="light"] .md-table thead th { background: var(--panel-2); }
html[data-theme="light"] .md-callout { background: var(--panel-2); }
html[data-theme="light"] .md-cal-note { background: var(--info-soft); }
html[data-theme="light"] .md-cal-tip { background: var(--ok-soft); }
html[data-theme="light"] .md-cal-warn { background: var(--warning-soft); }
html[data-theme="light"] .md-cal-danger { background: var(--danger-soft); }
html[data-theme="light"] .md-cal-quote { background: var(--sel); }
html[data-theme="light"] .md-cal-quote .md-cal-h { color: var(--primary); }
html[data-theme="light"] .md-spoiler { background: var(--line-strong); }
html[data-theme="light"] .md-spoiler:hover { background: color-mix(in srgb, var(--text) 26%, var(--panel-2)); }
html[data-theme="light"] .md-spoiler.on,
html[data-theme="light"] .md-spoiler.on:hover { background: transparent; }

/* ══════════════════════════════════════════════════════════════════════════════
   §3.15  «ПОЛОТНО» — полноэкранный редактор сообщения: ОДИН НЕПРЕРЫВНЫЙ ДОКУМЕНТ
   Контракт: docs/rich-message-editor.md §6. Только токены дизайн-системы.
   🔴 CLIE-1206: документ — ОДНО поле (.msged-field, ccCeField в режиме документа), а не
   стопка блоков со своей <textarea> у каждого. Строка едет коробкой .rd-l (поэтому у неё
   есть выравнивание, отступ списка и полоса цитаты), символы разметки прячет .rd-mk, а
   выделение, ⌫, ⌘A и копирование работают РОДНЫМИ силами браузера — как в Word.
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── кнопка «раскрыть»/«Полотно» в композере ──
   Стили и поведение видимости живут в блоке «.comp-tools .expand-btn» (композер: 2 строки):
   квадрат — правый элемент ВЕРХНЕЙ строки, на одном уровне с эмодзи/черновиками и над «Отправить»,
   всплывает как только есть что отправить (CLIE-349). */

/* ── оверлей ── */
.msged-scrim {
  position: fixed; inset: 0; z-index: 9400;
  display: flex; align-items: center; justify-content: center; padding: 24px;
  background: var(--scrim);
  backdrop-filter: blur(6px) saturate(1.1); -webkit-backdrop-filter: blur(6px) saturate(1.1);
  animation: ccFadeIn var(--dur-2) var(--ease);
}
@keyframes ccFadeIn { from { opacity: 0; } to { opacity: 1; } }
.msged-box {
  display: flex; flex-direction: column; overflow: hidden;
  width: min(880px, 94vw); height: min(88dvh, 900px);
  background: var(--panel); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-3), var(--edge);
  animation: ccModalIn var(--dur-3) var(--ease-spring);
}

/* ── шапка: ✕ | контекст | undo/redo ── */
.msged-head {
  flex: none; display: flex; align-items: center; gap: 8px;
  height: var(--head-h, 60px); padding: 0 10px 0 8px;
  border-bottom: 1px solid var(--line);
}
.msged-title {
  flex: 1; min-width: 0; font-weight: 600; font-size: 14px; letter-spacing: -.01em;
  text-align: center; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--text);
}
.msged-hist { display: flex; gap: 2px; }
.msged-icb {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: none;
  border: none; border-radius: var(--r-md, 10px); background: transparent;
  color: var(--muted); cursor: pointer;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.msged-icb:hover { background: var(--hover); color: var(--text); }
.msged-icb:disabled { opacity: .32; cursor: default; background: transparent; }
.msged-icb svg.ic { width: 18px; height: 18px; }

/* ── ПОЛОТНО: ОДИН НЕПРЕРЫВНЫЙ ДОКУМЕНТ (CLIE-1206) ──
   Раньше здесь жила стопка блоков (.msged-b + своя <textarea> у каждого) — и выделение
   поперёк абзацев было невозможно ФИЗИЧЕСКИ. Теперь поле ОДНО (.msged-field = ccCeField
   в режиме документа), а «блок» — строка-коробка .rd-l внутри него: у неё есть
   выравнивание, отступ списка, полоса цитаты, и при этом каретка и выделение общие. */
.msged-doc {
  flex: 1; min-height: 0; overflow-y: auto;
  padding: 20px clamp(16px, 5vw, 44px) 28px;
  font-size: 15px; line-height: 1.55;
}
.msged-field, .msged-field:focus {
  outline: none; border: none; background: transparent; color: var(--text);
  white-space: pre-wrap; overflow-wrap: anywhere; -webkit-user-modify: read-write-plaintext-only;
}
.msged-field.is-empty::before {
  content: attr(data-ph); color: var(--muted); opacity: .62; pointer-events: none;
}
/* строка документа — своя коробка: без неё нечем выравнивать и нечем рисовать полосу цитаты */
.msged-field .rd-l { display: block; min-height: 1.55em; margin: 2px 0; border-radius: var(--r-md, 10px); }
.msged-field .rd-lh1 { font-size: 26px; font-weight: 700; letter-spacing: -.02em; line-height: 1.25; margin: 16px 0 4px; }
.msged-field .rd-lh2 { font-size: 21px; font-weight: 660; letter-spacing: -.015em; line-height: 1.3; margin: 14px 0 3px; }
.msged-field .rd-lh3 { font-size: 17px; font-weight: 640; letter-spacing: -.01em; line-height: 1.35; margin: 12px 0 2px; }
.msged-field .rd-l:first-child { margin-top: 0; }
/* список: висячий отступ — точка/номер стоят в поле слева, текст переноса не подлезает */
.msged-field .rd-llist { padding-left: 24px; text-indent: -24px; }
.msged-field .rd-llist > * { text-indent: 0; }
/* точку рисуем псевдоэлементом: сами символы «- » спрятаны как разметка (.rd-mk),
   поэтому каретка их перескакивает, а в тексте они остаются (инвариант курсора цел) */
.msged-field .rd-bul { display: inline-block; width: 24px; text-indent: 0; }
.msged-field .rd-bul::before {
  content: "•"; font-size: 15px; line-height: 1.55; color: var(--primary);
  display: inline-block; width: 24px; text-align: left; padding-left: 6px;
}
.msged-field .rd-li-mk { display: inline-block; min-width: 18px; text-indent: 0; font-variant-numeric: tabular-nums; }
/* 🔴 Цитата и код — мягкая подложка со скруглением, БЕЗ полосы слева: левая рейка как
   акцент запрещена (CLIE-483), и весь продукт рисует цитату именно так (.md-msg blockquote). */
.msged-field .rd-lquote {
  padding: 3px 12px; background: color-mix(in srgb, currentColor 9%, transparent);
  color: var(--muted-2, var(--muted)); font-style: italic;
}
.msged-field .rd-cal { font-style: normal; }
.msged-field .rd-lcode {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 13.5px;
  background: var(--panel-2); padding: 2px 12px;
}
.msged-field .rd-lhr { color: var(--muted); letter-spacing: 3px; opacity: .7; }
.msged-field .rd-tbl {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, monospace); font-size: 13px;
  background: var(--panel-2); padding: 1px 10px; cursor: cell;
}
/* чек-пункт: коробочка вместо «[ ]» (сами скобки остаются в тексте, их прячет .rd-task-box) */
.msged-field .rd-task-box { cursor: pointer; }

/* ── шторка таблицы: та же сетка ячеек и те же действия, что были у блочной таблицы ── */
.msged-tsheet {
  position: fixed; inset: 0; z-index: 9500; display: flex; align-items: center; justify-content: center;
  padding: 20px; background: var(--scrim); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  animation: ccFadeIn var(--dur-2) var(--ease);
}
.msged-tsbox {
  width: min(680px, 94vw); max-height: 86dvh; overflow: auto; padding: 12px 14px 14px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-3), var(--edge); animation: ccModalIn var(--dur-3) var(--ease-spring);
}
.msged-tshead { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.msged-tstitle { flex: 1; font-weight: 600; font-size: 14px; color: var(--text); }
.msged-tablewrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-md, 10px); }
.msged-table { border-collapse: collapse; width: 100%; }
.msged-table th, .msged-table td { padding: 0; border-bottom: 1px solid var(--line); border-right: 1px solid var(--line); }
.msged-table th:last-child, .msged-table td:last-child { border-right: 0; }
.msged-table tr:last-child th, .msged-table tr:last-child td { border-bottom: 0; }
.msged-cell, .msged-cell:focus {
  width: 100%; min-width: 96px; padding: 7px 9px; border: none; outline: none;
  background: transparent; color: var(--text); font: inherit; font-size: 14px;
}
.msged-table th .msged-cell { font-weight: 640; color: var(--text); }
.msged-cell:focus { background: var(--sel); }
.msged-tacts { display: flex; gap: 2px; margin-top: 8px; }
.msged-tacts button {
  display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  border: none; border-radius: var(--r-sm, 8px); background: transparent; color: var(--muted); cursor: pointer;
}
.msged-tacts button:hover { background: var(--hover); color: var(--text); }
.msged-tacts button:last-child:hover { background: var(--danger-soft); color: var(--danger); }
.msged-tacts svg.ic { width: 15px; height: 15px; }

/* ══════════════════════════════════════════════════════════════════════════════
   🔴 CLIE-945 · ПАНЕЛЬ ФОРМАТИРОВАНИЯ + ВЫДЕЛЕНИЕ НЕСКОЛЬКИХ БЛОКОВ
   Владелец: «Нет даже сделать текст жирным! Или цвет заменить, шрифт… каждая строка
   как отдельный блок… нельзя выделить всё или много и применить одни стили».
   Панель стоит СВЕРХУ, над документом (как лента Word): нижний ряд — про отправку и
   вставку, верхний — про оформление. На узком экране панель ПЕРЕНОСИТСЯ, а не
   прокручивается: спрятанная кнопка = отсутствующая (СРЕД-33/CLIE-620).
   ══════════════════════════════════════════════════════════════════════════════ */
.msged-fmt {
  flex: none; display: flex; align-items: center; flex-wrap: wrap; gap: 2px;
  padding: 6px 10px; border-bottom: 1px solid var(--line); background: var(--panel-2);
}
.msged-fs { width: 1px; height: 18px; background: var(--line); margin: 0 5px; flex: none; }
.msged-fmt-grow { flex: 1; min-width: 8px; }
.msged-selinfo { flex: none; font-size: 12px; color: var(--muted); padding: 0 4px; white-space: nowrap; }
.msged-fb {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 30px; flex: none;
  border: none; border-radius: var(--r-sm, 8px); background: transparent;
  color: var(--muted); cursor: pointer;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.msged-fb:hover { background: var(--hover); color: var(--text); }
.msged-fb.on { background: var(--sel); color: var(--primary-2); }
.msged-fb svg.ic { width: 17px; height: 17px; }
/* «есть ещё варианты» — крошечная стрелка в углу, как у любого нашего меню */
.msged-fb.has-caret::after {
  content: ""; position: absolute; right: 3px; bottom: 3px;
  border-left: 3px solid transparent; border-top: 3px solid currentColor; opacity: .5;
}
/* 🔴🔴 CLIE-1206·2 · ВЫХОДЫ ВЫБОРКИ — ПОЛОСА ПОД ДОКУМЕНТОМ, А НЕ КОНЕЦ ПАНЕЛИ.
   Показываются только при выделении (прогрессивное раскрытие, CLIE-1130): «копировать/
   вырезать/удалить» нужны там, где клавиатуры нет (телефон).
   Полоса стоит ПОСЛЕ .msged-field: пока она жила в конце .msged-fmt, её появление
   переносило панель на вторую строку и весь документ прыгал на 32px ВНИЗ прямо посреди
   протяжки мышью — выделение поперёк абзацев обрывалось на строку раньше (замер на проде:
   «поле 158 → 190, панель 43 → 75», 32 знака вместо 55). Снизу отнимается место у
   ПРОКРУТКИ, а не у текста: верх документа не двигается. */
.msged-selstrip { display: none; }
.msged-box.has-sel .msged-selstrip {
  flex: none; display: flex; align-items: center; gap: 2px;
  padding: 4px 10px; border-top: 1px solid var(--line); background: var(--panel-2);
}
/* Выделение — РОДНОЕ выделение одного поля (своих рамок у блоков больше нет: блоков нет). */
.msged-field::selection, .msged-field *::selection { background: color-mix(in srgb, var(--primary) 30%, transparent); }
/* ── поповер-палитра: сетка кружков вместо списка строк ── */
.msged-pop-grid { min-width: 0; width: 212px; display: grid; grid-template-columns: repeat(5, 1fr); gap: 2px; }
.msged-pop-grid button { padding: 6px 0; justify-content: center; }
.msged-pop-grid .mp-l, .msged-pop-grid .mp-ck { display: none; }
.msged-pop-grid .mp-ic { width: auto; }
.mp-sw {
  display: inline-block; width: 18px; height: 18px; border-radius: var(--r-full, 999px);
  background: var(--sw, transparent); box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--text) 22%, transparent);
}
.mp-sw.bg { border-radius: var(--r-xs, 6px); }
.msged-pop-grid button.on .mp-sw { box-shadow: 0 0 0 2px var(--panel-3), 0 0 0 4px var(--primary); }
/* превью шрифта и размера прямо в пункте меню — «видно, что выберешь» */
.mp-f-serif { font-family: Georgia, "Times New Roman", serif; }
.mp-f-mono { font-family: var(--mono, ui-monospace, Menlo, monospace); }
.mp-s-xs { font-size: 11px; } .mp-s-sm { font-size: 12.5px; }
.mp-s-lg { font-size: 16px; } .mp-s-xl { font-size: 18px; font-weight: 600; }

/* ── тулбар низа ── */
.msged-tb {
  flex: none; display: flex; align-items: center; gap: 4px;
  padding: 10px 12px; border-top: 1px solid var(--line); background: var(--panel-2);
}
.msged-tb-sep { width: 1px; height: 20px; background: var(--line); margin: 0 6px; flex: none; }
.msged-tb-grow { flex: 1; }
.msged-tbb {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: none;
  border: none; border-radius: var(--r-md, 10px); background: transparent;
  color: var(--muted); cursor: pointer;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.msged-tbb:hover { background: var(--hover); color: var(--text); }
.msged-tbb:disabled { opacity: .4; cursor: default; }
.msged-tbb.loading { animation: wipPulse 1s var(--ease) infinite; }
.msged-tbb svg.ic { width: 19px; height: 19px; }
.msged-send {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 36px; flex: none; border: none; border-radius: var(--r-md, 10px);
  cursor: pointer; transition: transform var(--dur-1) var(--ease), filter var(--dur-1) var(--ease);
}
.msged-send:hover { filter: brightness(1.06); }
.msged-send:active { transform: scale(.94); }
.msged-send svg.ic { width: 18px; height: 18px; }

/* ── поповеры тулбара (паттерн существующих меню: --panel-3 + --shadow-2 + ccPopIn) ── */
.msged-pop {
  position: fixed; z-index: 9500; min-width: 216px; padding: 6px;
  background: var(--panel-3); border: 1px solid var(--line); border-radius: var(--r-lg, 12px);
  box-shadow: var(--shadow-2), var(--edge);
  animation: ccPopIn var(--dur-2) var(--ease-spring);
}
.msged-pop button {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border: none; border-radius: var(--r-md, 10px);
  background: transparent; color: var(--text); font-size: 14px; text-align: left; cursor: pointer;
  transition: background var(--dur-1) var(--ease);
}
.msged-pop button:hover { background: var(--hover); }
.msged-pop .mp-ic { display: inline-flex; width: 18px; color: var(--muted); flex: none; }
.msged-pop .mp-ic svg.ic { width: 17px; height: 17px; }
.msged-pop .mp-l { flex: 1; min-width: 0; }
.msged-pop .mp-ck { display: inline-flex; width: 16px; color: var(--primary); flex: none; }
.msged-pop .mp-ck svg.ic { width: 16px; height: 16px; stroke-width: 2.5; }
.msged-pop button.on .mp-ic { color: var(--primary); }

/* ── узкий экран: редактор занимает весь экран ── */
@media (max-width: 720px) {
  .msged-scrim { padding: 0; }
  .msged-box { width: 100vw; height: 100dvh; max-height: 100dvh; border: none; border-radius: 0; }
  .msged-doc { padding: 16px 16px 24px; }
}

/* ── светлая тема: подложки пересчитываются (в тёмной они на прозрачном белом) ── */
html[data-theme="light"] .msged-box { border-color: var(--cm-171e34-1, rgba(23,30,52,.10)); }
html[data-theme="light"] .msged-field .rd-lcode { background: var(--panel-2); }

/* ══════════ 🔗👤 ССЫЛКА ДЛЯ ГОСТЕЙ (модалка #guestLinkModal) ══════════
   Гость без аккаунта заходит по ссылке в видеокомнату (как у Zoom). Одна модалка на
   всё приложение: открывается из шапки чата и из панели идущего созвона. Токены —
   общие (--panel/--line/--primary), поэтому светлая и тёмная темы получаются сами. */

/* 🔴 ПОВЕРХ ЭФИРА/СОЗВОНА. Эту модалку открывают КНОПКОЙ ВНУТРИ идущего созвона
   (#gcGuestBtn, панель эфира) — а оверлей эфира/звонка стоит на z-index:10000
   (.groupcall-overlay/.call-overlay, app.js). База .modal-overlay = z-index:60, поэтому
   без этого правила модалка «Ссылка для гостей» уходила ПОД эфир и владелец её не видел.
   Держим НИЖЕ pm-scrim/будильника (12000), чтобы подтверждения и входящий будильник
   оставались сверху. Правило: любая модалка, вызываемая ИЗ активного эфира/созвона,
   ОБЯЗАНА иметь z-index > 10000 (память modal-over-call-overlay-zindex). */
#guestLinkModal:not(.hidden) { z-index: 11000; }

.gl-box { width: min(560px, 94vw); }
.gl-body { display: flex; flex-direction: column; gap: 18px; padding: 18px 18px 20px; }

/* 🧭 CLIE-857·2 — модалка «Настроить меню». Ширины числом здесь достаточно только как
   СТАРТОВОЙ: рама `.modal-box` стоит в WIN_BOX_SEL, поэтому окно тянется мышью и помнит
   свою ширину (правило CRMC-406), а `.modal-body` даёт самопрокрутку длинному списку. */
.nav-menu-box { width: min(620px, 94vw); }
.nav-menu-body { display: flex; flex-direction: column; padding: 14px 18px 18px; }

.gl-sec { display: flex; flex-direction: column; gap: 8px; }
.gl-label { font-size: 12px; font-weight: 600; letter-spacing: .02em; color: var(--muted); }
.gl-hint { font-size: 12.5px; line-height: 1.45; color: var(--text-dim); }

/* поле со ссылкой + кнопка «скопировать» */
.gl-url-row { display: flex; gap: 8px; align-items: center; }
.gl-url {
  flex: 1; min-width: 0; padding: 10px 12px; font-size: 13.5px;
  background: var(--input-bg); color: var(--text);
  border: 1px solid var(--line); border-radius: 10px;
  text-overflow: ellipsis; transition: border-color 140ms ease, background 140ms ease;
}
.gl-url:focus { outline: none; border-color: var(--primary); background: var(--panel); }
.gl-icon { flex: 0 0 auto; }

/* сегмент «Свободная | С кодом» */
/* Тумблер «Комната ожидания» в модалке гостевой ссылки: строка-переключатель с
   пояснением, а не голый чекбокс (голые чекбоксы запрещены правилом дизайна). */
.gl-toggle {
  display: flex; align-items: flex-start; gap: 11px; cursor: pointer;
  margin: 4px 0 2px; padding: 11px 12px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2);
  transition: border-color .14s cubic-bezier(.2,.8,.2,1), background .14s cubic-bezier(.2,.8,.2,1);
}
.gl-toggle:hover { border-color: var(--line-strong); }
.gl-toggle:has(input:checked) { border-color: color-mix(in srgb, var(--primary) 42%, var(--line)); }
.gl-toggle input {
  flex: none; width: 18px; height: 18px; margin: 1px 0 0; cursor: pointer;
  accent-color: var(--primary);
}
.gl-toggle input:disabled { cursor: not-allowed; }
.gl-toggle-t { display: flex; flex-direction: column; gap: 2px; font-size: 13.5px; font-weight: 600; }
.gl-toggle-s { color: var(--muted); font-size: 12.5px; font-weight: 500; line-height: 1.4; }

.gl-seg {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 4px;
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 12px;
}
.gl-seg-btn {
  appearance: none; border: 0; cursor: pointer;
  padding: 9px 10px; border-radius: 9px; font-size: 13.5px; font-weight: 500;
  background: transparent; color: var(--muted);
  transition: background 140ms ease, color 140ms ease, box-shadow 140ms ease;
}
.gl-seg-btn:hover:not(.on):not(:disabled) { color: var(--text); background: var(--hover); }
.gl-seg-btn.on { background: var(--panel-2); color: var(--text); box-shadow: var(--shadow-1); }
.gl-seg-btn:disabled { opacity: .55; cursor: default; }
.gl-seg-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

/* Лимит участников звонка (0157) — группа пилюль «Без лимита / 2 / 3 / …» */
.gl-cap {
  display: flex; flex-wrap: wrap; gap: 6px; padding: 4px;
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 12px;
}
.gl-cap-btn {
  appearance: none; border: 1px solid transparent; cursor: pointer;
  padding: 7px 12px; border-radius: 9px; font-size: 13px; font-weight: 500;
  min-width: 34px; text-align: center; background: transparent; color: var(--muted);
  font-variant-numeric: tabular-nums;
  transition: background 140ms ease, color 140ms ease, box-shadow 140ms ease, border-color 140ms ease;
}
.gl-cap-btn:hover:not(.on):not(:disabled) { color: var(--text); background: var(--hover); }
.gl-cap-btn.on { background: var(--panel-2); color: var(--text); box-shadow: var(--shadow-1); border-color: var(--line); }
.gl-cap-btn:disabled { opacity: .55; cursor: default; }
.gl-cap-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

/* код доступа — крупно и с трекингом, его диктуют голосом */
.gl-pin-row { display: flex; gap: 10px; align-items: center; }
.gl-pin {
  flex: 0 0 auto; padding: 8px 14px; border-radius: 10px;
  background: var(--input-bg); border: 1px solid var(--line);
  font-size: 20px; font-weight: 600; letter-spacing: .18em;
  font-variant-numeric: tabular-nums; color: var(--text);
}

.gl-wide { width: 100%; margin: 0; }
.gl-body .gl-wide + .gl-wide { margin-top: 8px; }

/* пустое состояние: спокойная «продуктовая» карточка, а не голая форма */
.gl-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; padding: 8px 4px 4px; }
.gl-empty-ico {
  width: 52px; height: 52px; display: grid; place-items: center; margin-bottom: 2px;
  border-radius: 16px; background: var(--sel); color: var(--primary-2);
}
.gl-empty-ico .ic { width: 26px; height: 26px; }
.gl-empty-t { font-size: 15.5px; font-weight: 600; color: var(--text); }
.gl-empty-s { font-size: 13px; line-height: 1.5; color: var(--text-dim); max-width: 340px; margin-bottom: 6px; }

.gl-meta { display: flex; }
.gl-link-btn {
  appearance: none; background: none; border: 0; padding: 0; cursor: pointer;
  font-size: 12.5px; color: var(--muted); transition: color 140ms ease;
}
.gl-link-btn:hover { color: var(--text); }
.gl-link-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; border-radius: 4px; }

/* 🔴 CLIE-620: был `max-height:180px;overflow-y:auto` — видно ~7 строк, остальные под
   невидимым бегунком. Это ЖУРНАЛ «кто заходил по ссылке» внутри уже скроллящегося тела
   модалки: его читают целиком, и растёт он бесконечно. Кап снят — скроллит тело. */
.gl-guests { list-style: none; margin: -8px 0 0; padding: 10px 12px; display: flex; flex-direction: column; gap: 8px;
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 10px; }
.gl-guests li { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; }
.gl-g-name { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gl-g-time { flex: 0 0 auto; color: var(--text-dim); font-size: 12px; }

.gl-danger { display: flex; gap: 8px; padding-top: 4px; border-top: 1px solid var(--line); margin-top: 2px; }
.gl-danger > * { flex: 1; }
.gl-del { color: var(--danger); }
.gl-del:hover:not(:disabled) { background: var(--danger-soft); }

.gl-note { font-size: 12px; line-height: 1.5; color: var(--text-dim); }

/* 0088 · полоска состояния окна встречи у гостевой ссылки. Тонкий хэйрлайн + мягкая
   подложка на цветовом токене — без заливок «во всю строку» (правило дизайна). */
.gl-win {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; margin: 0 0 14px;
  border: 1px solid var(--line); border-radius: 10px;
  font-size: 12.5px; line-height: 1.45; color: var(--text-dim);
  background: var(--panel-2);
  transition: background .14s ease, border-color .14s ease;
}
.gl-win::before {
  content: ""; flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; opacity: .85;
}
.gl-win-ok   { color: #2e9e6f; border-color: color-mix(in srgb, #2e9e6f 26%, var(--line)); background: color-mix(in srgb, #2e9e6f 7%, var(--panel-2)); }
.gl-win-wait { border-color: color-mix(in srgb, #EF9F27 26%, var(--line)); background: color-mix(in srgb, #EF9F27 7%, var(--panel-2)); }
.gl-win-off  { color: var(--text-dim); }
/* Тема переключается атрибутом html[data-theme], а не системной схемой: в тёмной янтарный
   надо высветлить, иначе на тёмной подложке он уходит в грязь. */
.gl-win-wait { color: #EF9F27; }
html[data-theme="light"] .gl-win-wait { color: #b7791f; }

/* скелет загрузки — та же геометрия, что и содержимое, чтобы не «прыгало» */
.gl-skeleton { display: flex; flex-direction: column; gap: 14px; }
.gl-skeleton i { display: block; height: 40px; border-radius: 10px; background: var(--panel-2); animation: glShimmer 1.2s ease-in-out infinite; }
.gl-skeleton i:nth-child(2) { height: 56px; animation-delay: .12s; }
.gl-skeleton i:nth-child(3) { height: 40px; animation-delay: .24s; }
@keyframes glShimmer { 0%, 100% { opacity: .55; } 50% { opacity: .95; } }
@media (prefers-reduced-motion: reduce) { .gl-skeleton i { animation: none; } }

/* ══════════ 📡 ЭФИРЫ (СТРИМЫ) ══════════
   Стрим = группа + ссылка kind='stream'. UI не дублирует созвон: студия ведущего и вид
   зрителя живут в ТОМ ЖЕ #groupCallOverlay (классы .stream-mode / .st-viewer), а ссылку
   настраивает ТА ЖЕ модалка #guestLinkModal. Здесь только добавочные слои.
   Токены общие (--panel/--line/--primary) → светлая и тёмная темы получаются сами;
   внутри оверлея (он всегда тёмный) — фиксированные светлые значения, как у .gc-*. */

/* ── Тумблер «чат зрителей / реакции»: строка-переключатель в стиле системных ── */
.st-tog {
  appearance: none; width: 100%; display: flex; align-items: center; gap: 12px; text-align: left;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--input-bg); color: var(--text); cursor: pointer;
  transition: border-color 140ms var(--ease), background 140ms var(--ease);
}
.st-tog + .st-tog { margin-top: 8px; }
.st-tog:hover:not(:disabled) { border-color: var(--line-strong); }
.st-tog:disabled { opacity: .55; cursor: default; }
.st-tog:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.st-tog-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.st-tog-t { font-size: 13.5px; font-weight: 500; }
.st-tog-s { font-size: 12px; color: var(--text-dim); }
.st-tog-sw {
  flex: 0 0 auto; width: 40px; height: 24px; border-radius: 999px; padding: 2px;
  background: var(--line-strong); display: flex; align-items: center;
  transition: background 160ms var(--ease);
}
.st-tog-sw i {
  width: 20px; height: 20px; border-radius: 50%; background: #fff; display: block;
  box-shadow: 0 1px 2px rgba(0,0,0,.28); transition: transform 160ms var(--ease);
}
.st-tog.on .st-tog-sw { background: var(--primary); }
.st-tog.on .st-tog-sw i { transform: translateX(16px); }
@media (prefers-reduced-motion: reduce) { .st-tog-sw, .st-tog-sw i { transition: none; } }

/* ── Модалка «Новый эфир» ── */
.stm-box { width: min(560px, 94vw); }
.stm-body { display: flex; flex-direction: column; gap: 18px; padding: 18px 18px 20px; }
.stm-name { width: 100%; }
.stm-pin {
  flex: 0 0 auto; width: 148px; padding: 8px 14px; border-radius: 10px;
  background: var(--input-bg); border: 1px solid var(--line); color: var(--text);
  font-size: 20px; font-weight: 600; letter-spacing: .18em;
  font-variant-numeric: tabular-nums; transition: border-color 140ms var(--ease);
}
.stm-pin:focus { outline: none; border-color: var(--primary); background: var(--panel); }
.stm-done { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 4px 4px 0; }
.stm-done-ico {
  width: 52px; height: 52px; display: grid; place-items: center; margin-bottom: 2px;
  border-radius: 16px; background: var(--sel); color: var(--primary-2);
}
.stm-done-ico .ic { width: 26px; height: 26px; }
.stm-done-t { font-size: 15.5px; font-weight: 600; }
.stm-done-s { font-size: 13px; line-height: 1.5; color: var(--text-dim); max-width: 350px; }

/* ── Полоса «Эфир идёт / не начат» в модалке ссылки ── */
.st-livebar {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--input-bg);
  transition: border-color 140ms var(--ease), background 140ms var(--ease);
}
.st-livebar.on { border-color: rgba(239,68,68,.32); background: var(--danger-soft); }
.st-livebar-l { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.st-livebar-t { font-size: 13.5px; font-weight: 600; width: 100%; }
.st-livebar.on .st-livebar-t { width: auto; }
.st-livebar-s { font-size: 12px; color: var(--text-dim); width: 100%; }

/* ── Пилюля «В эфире» (шапка созвона + строка списка): сдержанная, хэйрлайн + точка ── */
.st-live {
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px;
  border-radius: 9px; font-size: 12px; font-weight: 600; letter-spacing: .02em;
  color: #ffd9d9; background: rgba(239,68,68,.13); border: 1px solid rgba(239,68,68,.30);
}
.st-live-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--danger); flex: 0 0 auto;
  animation: stLivePulse 2.4s ease-in-out infinite;
}
@keyframes stLivePulse { 0%,100% { box-shadow: 0 0 0 0 rgba(239,68,68,.45); } 60% { box-shadow: 0 0 0 5px rgba(239,68,68,0); } }
@media (prefers-reduced-motion: reduce) { .st-live-dot { animation: none; } }

/* ── Раскладка студии: тот же оверлей, справа — панель эфира ── */
.groupcall-overlay.stream-mode:not(.minimized) {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  grid-template-rows: auto minmax(0, 1fr) auto;
}
.groupcall-overlay.stream-mode:not(.minimized) .groupcall-head { grid-area: 1 / 1 / 2 / 3; }
.groupcall-overlay.stream-mode:not(.minimized) .gc-stage { grid-area: 2 / 1 / 3 / 2; }
.groupcall-overlay.stream-mode:not(.minimized) .st-panel { grid-area: 2 / 2 / 3 / 3; }
.groupcall-overlay.stream-mode:not(.minimized) .groupcall-controls { grid-area: 3 / 1 / 4 / 3; }
.groupcall-overlay.stream-mode.st-panel-off:not(.minimized) { grid-template-columns: minmax(0, 1fr) 0; }
.groupcall-overlay.stream-mode.st-panel-off .st-panel { display: none; }
.groupcall-overlay.minimized .st-panel, .groupcall-overlay.minimized .st-react-layer { display: none; }
/* зритель не публикует — собственная пустая плитка «Вы» ему не нужна */
.groupcall-overlay.st-viewer .gtile[data-uid="me"] { display: none; }

.st-panel {
  display: flex; flex-direction: column; min-height: 0;
  margin: 10px 16px 6px 0; border-radius: 16px;
  background: var(--cm-161921-7, rgba(22,25,33,.70)); border: 1px solid var(--gc-hair-2);
  -webkit-backdrop-filter: blur(20px) saturate(1.25); backdrop-filter: blur(20px) saturate(1.25);
  box-shadow: 0 20px 50px -22px rgba(0,0,0,.7), inset 0 1px 0 rgba(255,255,255,.05);
  overflow: hidden;
}
.st-panel-head {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  padding: 8px 8px 8px 10px; border-bottom: 1px solid var(--gc-hair);
}
.st-tabs { display: flex; gap: 4px; flex: 1; min-width: 0; }
.st-tab {
  appearance: none; border: 0; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: 9px; font-size: 13px; font-weight: 500;
  background: transparent; color: #9aa3b4;
  transition: background 140ms var(--ease), color 140ms var(--ease);
}
.st-tab:hover:not(.on) { background: rgba(255,255,255,.06); color: var(--cm-e8ebf2, #e8ebf2); }
.st-tab.on { background: rgba(255,255,255,.10); color: #fff; }
.st-tab:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.st-tab-n {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--acc-fill); color: #fff; font-size: 11px; font-weight: 600;
}
.st-panel .st-copy { flex: 0 0 auto; color: var(--cm-c7ccd8, #c7ccd8); background: transparent; border-color: transparent; }
.st-panel .st-copy:hover { background: rgba(255,255,255,.10); color: #fff; }
.st-panel.has-new .st-tab[data-sttab="chat"]::after {
  content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--primary);
}

.st-body { flex: 1; min-height: 0; overflow-y: auto; padding: 12px 12px 8px; display: flex; flex-direction: column; gap: 8px; }
.st-body::-webkit-scrollbar { width: 8px; }
.st-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,.14); border-radius: 999px; }
.st-empty { margin: auto 0; text-align: center; font-size: 12.5px; line-height: 1.6; color: #8b93a3; padding: 12px 6px; }
.st-sub { font-size: 11.5px; font-weight: 600; letter-spacing: .03em; color: #8b93a3; margin: 6px 0 -2px; }

.st-msg { font-size: 13px; line-height: 1.45; color: #e6e9ef; word-break: break-word; }
.st-msg-n { color: var(--primary-2); font-weight: 600; margin-right: 6px; }
.st-msg.mine .st-msg-n { color: #7fd3a8; }
.st-sys { font-size: 12px; color: #8b93a3; text-align: center; padding: 2px 0; }

.st-hand {
  display: flex; align-items: center; gap: 10px; padding: 9px 10px; border-radius: 12px;
  background: rgba(255,255,255,.05); border: 1px solid var(--gc-hair);
  transition: border-color 140ms var(--ease), background 140ms var(--ease);
}
.st-hand:hover { border-color: var(--gc-hair-2); background: rgba(255,255,255,.08); }
.st-hand.on { background: color-mix(in srgb, var(--primary) 14%, transparent); border-color: color-mix(in srgb, var(--primary) 32%, transparent); }
.st-hand-ic { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 9px; display: grid; place-items: center; background: rgba(255,255,255,.08); color: #e6e9ef; }
.st-hand-ic .ic { width: 15px; height: 15px; }
.st-hand-n { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; font-size: 13px; color: #e6e9ef; }
.st-hand-n, .st-hand-s { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-hand-s { font-size: 11.5px; color: #8b93a3; }
.st-hand-acts { flex: 0 0 auto; display: flex; gap: 6px; margin-left: auto; }
/* 🔴 `.st-mini` (7 правил) переехала в `/app/ccroom.css`. Причина — та же, что у всего
   блока интерактива: эту кнопку РИСУЕТ общая реализация `ccroom.js` («Завершить» у опроса,
   «Отвечено»/«Скрыть» у вопроса, «Пауза»/«Засечь» у повестки), значит её видит и гость, а
   `style.css` он не грузит. То, что `.st-mini` встречается ещё и в разметке `app.js`, —
   НЕ повод держать вторую копию правил: объявление остаётся ОДНО, просто теперь в файле,
   который грузят ОБЕ страницы. Контекстная надстройка `.st-air .st-mini` (ряд «эфира»)
   осталась ниже: `.st-air` — хром основного клиента, у гостя его нет. */

/* ── «В эфире»: кто сейчас вещает ───────────────────────────────────────────────
   Строка того же ритма, что .st-hand (одна сетка на всю панель эфира), но с
   монограммой вместо иконки и живым состоянием микрофона. Говорящего подсвечиваем
   тонким кольцом, а не заливкой: заливка на всю строку — ровно тот «жирный» приём,
   который в этом проекте запрещён. */
.st-air {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 12px;
  background: rgba(255,255,255,.05); border: 1px solid var(--gc-hair);
  transition: border-color 140ms var(--ease), background 140ms var(--ease), box-shadow 140ms var(--ease);
}
.st-air + .st-air { margin-top: 6px; }
.st-air:hover { border-color: var(--gc-hair-2); background: rgba(255,255,255,.08); }
.st-air.talking { border-color: rgba(127,211,168,.44); box-shadow: 0 0 0 1px rgba(127,211,168,.22); }
.st-air-av {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(255,255,255,.09); color: #e6e9ef; font-size: 12px; font-weight: 600;
}
.st-air-n { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; font-size: 13px; color: #e6e9ef; }
.st-air-n, .st-air-s { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-air-s { font-size: 11.5px; color: #8b93a3; }
.st-air-mic { flex: 0 0 auto; display: grid; place-items: center; color: #7fd3a8; }
.st-air-mic .ic { width: 15px; height: 15px; }
.st-air-mic.off { color: #8b93a3; }
.st-air .st-mini { margin-left: 2px; }

.st-compose { flex: 0 0 auto; border-top: 1px solid var(--gc-hair); padding: 8px 10px 10px; display: flex; flex-direction: column; gap: 8px; }
.st-reacts { display: flex; gap: 4px; }
.st-react {
  appearance: none; border: 0; cursor: pointer; flex: 1; padding: 6px 0; border-radius: 9px;
  font-size: 17px; line-height: 1; background: rgba(255,255,255,.05);
  transition: background 140ms var(--ease), transform 140ms var(--ease-spring);
}
.st-react:hover { background: rgba(255,255,255,.13); transform: translateY(-1px); }
.st-react:active { transform: scale(.92); }
.st-react:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.st-input-row { display: flex; gap: 6px; align-items: center; }
.st-input {
  flex: 1; min-width: 0; padding: 9px 12px; font-size: 13px; color: #e6e9ef;
  background: rgba(255,255,255,.06); border: 1px solid var(--gc-hair); border-radius: 10px;
  transition: border-color 140ms var(--ease), background 140ms var(--ease);
}
.st-input::placeholder { color: #7d8595; }
.st-input:focus { outline: none; border-color: var(--primary); background: rgba(255,255,255,.10); }
.st-send {
  appearance: none; border: 0; cursor: pointer; flex: 0 0 auto;
  width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center;
  background: var(--acc-fill); color: #fff; transition: background 140ms var(--ease), transform 140ms var(--ease);
}
.st-send:hover { background: var(--acc-fill-hi); }
.st-send:active { transform: scale(.94); }
.st-send .ic { width: 16px; height: 16px; }

/* ── Всплывающие реакции: лёгкий слой поверх сцены, кликов не ловит ── */
.st-react-layer { position: absolute; left: 0; right: 0; bottom: 96px; top: 20%; pointer-events: none; overflow: hidden; z-index: 3; }
.st-fly { position: absolute; bottom: 0; font-size: 26px; line-height: 1; animation: stFly 2.4s var(--ease) forwards; }
@keyframes stFly {
  0%   { opacity: 0; transform: translate(0, 10px) scale(.7); }
  12%  { opacity: 1; transform: translate(0, 0) scale(1); }
  100% { opacity: 0; transform: translate(var(--st-dx, 0), -100%) scale(1.15); }
}
@media (prefers-reduced-motion: reduce) { .st-fly { animation-duration: .01ms; } }

/* ══════════════ 🎛 M2 · ИНТЕРАКТИВ В СОЗВОНЕ (room_event) ══════════════
   Реакции · рука · опрос/Q&A/повестка · указка · звуки · celebration.
   Оверлей созвона ВСЕГДА тёмный, поэтому внутри него берём тёмные токены
   (--gc-hair/--gc-btn) и локальную тёмную шкалу (см. .gcx-panel ниже);
   «энергия команды» в поповере статуса живёт СНАРУЖИ и работает на обычных
   токенах темы — светлой и тёмной одинаково. */

/* Слой всплывающих реакций теперь работает и в ОБЫЧНОМ созвоне (не только в эфире):
   поднимаем над плитками и уводим из-под открытой боковой панели. Кликов не ловит. */
.groupcall-overlay:not(.stream-mode) .st-react-layer { top: 26%; bottom: 104px; z-index: 11; }
.groupcall-overlay.gcx-panel-open:not(.stream-mode) .st-react-layer { right: min(360px, 94vw); }
/* Тот же слой в звонке 1:1: над видео (.videos z-index 0) и под контролами (z-index 2),
   с запасом снизу под ряд кнопок — частица не выныривает из-под «Завершить». */
.call-overlay .st-react-layer { top: 22%; bottom: calc(env(safe-area-inset-bottom) + 96px); z-index: 1; }
.call-overlay.minimized .st-react-layer { display: none; }
.st-fly.gcx-spark { color: var(--primary-2); }
.st-fly.gcx-spark svg.ic { width: 22px; height: 22px; filter: drop-shadow(0 0 8px var(--cm-8b9cf5-55, rgba(139,156,245,.55))); }

/* группа интерактива живёт только в обычном SFU-созвоне */
.groupcall-overlay.stream-mode .gcx-grp,
.groupcall-overlay.stream-mode #gcxPanel,
.groupcall-overlay.minimized .gcx-grp,
.groupcall-overlay.minimized #gcxPanel,
.groupcall-overlay.minimized #gcxPointerLayer { display: none !important; }
.groupcall-controls #gcxHandBtn.on,
.groupcall-controls #gcxPointerBtn.on,
.groupcall-controls #gcxPanelBtn.on { background: var(--acc-grad); color: #fff; box-shadow: 0 0 0 2px rgba(255,255,255,.24) inset; }

/* ── 🎥 ТОТ ЖЕ интерактив в ЗВОНКЕ 1-НА-1 ───────────────────────────────────────
   Разметка одна: #gcxGrp / #gcxPanel / #gcxPointerLayer ПЕРЕЕЗЖАЮТ в #callOverlay
   (gcxMount в app.js). Здесь только их «одежда» для этого дома: док встаёт в общий
   ряд круглых кнопок звонка, панель — правой шторкой, указки — слоем поверх видео. */
.call-controls .gcx-grp { display: flex; align-items: center; gap: 6px; }   /* шаг дока, а не свой */
.call-controls .gcx-grp button { position: relative; }        /* бейджи считаются от кнопки */
.call-controls .gcx-grp .gc-badge { top: 4px; right: 4px; box-shadow: 0 0 0 2px rgba(0,0,0,.55); }
.call-controls #gcxHandBtn.on,
.call-controls #gcxPointerBtn.on,
.call-controls #gcxPanelBtn.on { background: var(--acc-grad); box-shadow: 0 0 0 2px rgba(255,255,255,.32) inset; }
.call-controls #gcxPanelBtn.has-live { box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 55%, transparent) inset; }
.call-overlay.gcx-pointing #remoteVideo,
.call-overlay.gcx-pointing #localVideo.screen { cursor: crosshair; }
/* Панель открыта — видео ужимается, а не прячется под ней (шире 560px; уже — панель во весь
   экран, как в конференции). Ряд кнопок и летящие реакции едут вместе с кадром. */
/* 🔴 :not(.minimized) — обязателен. Класс `gcx-panel-open` со свёрнутого звонка не
   снимается, а PiP шириной 150px: `right:360px` схлопывал .videos в НОЛЬ, и человек
   видел чёрную плашку вместо собеседника (панель в PiP и так скрыта правилами ниже). */
@media (min-width: 561px) {
  .call-overlay.gcx-panel-open:not(.minimized) .videos,
  .call-overlay.gcx-panel-open:not(.minimized) .st-react-layer,
  .call-overlay.gcx-panel-open:not(.minimized) .gcx-pointer-layer { right: min(360px, 94vw); transition: right .16s var(--ease); }
  /* 🔴 CLIE-1219: ряд звонка стал доком и центрируется `left: 50%` — сдвигать его
     `right`-ом больше НЕЛЬЗЯ (у absolute-элемента с заданным left правый край не
     работает). Открытая шторка отнимает у дока ровно свою ширину, как у кадра. */
  .call-overlay.gcx-panel-open:not(.minimized) .call-controls {
    left: calc(50% - min(360px, 94vw) / 2); transition: left .16s var(--ease);
    /* Место у ряда тоже отнимается шторкой — иначе его хвост уезжает ПОД панель, и
       раскладка (она мерит настоящую ширину) об этом не узнаёт. */
    max-width: calc(100vw - 28px - min(360px, 94vw));
  }
  /* 🤝 ЗВОН-24: совместные поверхности ужимаются ВМЕСТЕ с кадром — иначе правая шторка
     («Опрос · Q&A · Повестка») ложится ПОВЕРХ доски и её правый край не виден. Смещение
     чуть больше, чем у видео: у доски есть свои поля 14px, и стык не должен «слипаться». */
  .call-overlay.gcx-panel-open:not(.minimized) .cc-board,
  .groupcall-overlay.gcx-panel-open .cc-board { right: min(374px, 94vw); transition: right .16s var(--ease); }
  .call-overlay.gcx-panel-open:not(.minimized) .cc-watch,
  .groupcall-overlay.gcx-panel-open .cc-watch { right: min(374px, 94vw); transition: right .16s var(--ease); }
}
/* Свёрнутый звонок (PiP) — это плашка «идёт разговор», а не рабочая поверхность. */
.call-overlay.minimized .gcx-grp,
.call-overlay.minimized #gcxPanel,
.call-overlay.minimized #gcxPointerLayer { display: none !important; }
/* «есть что-то живое» — мягкая точка, а не крик: бейдж уже показывает число */
.groupcall-controls #gcxPanelBtn.has-live { box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 45%, transparent) inset; }
.groupcall-controls button:focus-visible { outline: 2px solid var(--primary-2); outline-offset: 2px; }

/* ── Поповер «реакции и звуки»: по нажатию, не «на всякий случай» ── */
.gcx-pop {
  position: absolute; z-index: 30; width: max-content; max-width: min(340px, 92vw);
  display: flex; flex-direction: column; gap: 8px; padding: 10px;
  background: var(--cm-161921-94, rgba(22,25,33,.94)); border: 1px solid var(--gc-hair-2); border-radius: 16px;
  -webkit-backdrop-filter: blur(22px) saturate(1.25); backdrop-filter: blur(22px) saturate(1.25);
  box-shadow: 0 24px 60px -20px rgba(0,0,0,.72), inset 0 1px 0 rgba(255,255,255,.05);
  animation: gcxPopIn var(--dur-2) var(--ease-spring) both;
}
@keyframes gcxPopIn { from { opacity: 0; transform: translateY(6px) scale(.97); } to { opacity: 1; transform: none; } }
.gcx-pop-row { display: flex; gap: 4px; }
.gcx-pop .st-react { min-width: 40px; }
.gcx-pop-sep { height: 1px; background: var(--gc-hair); margin: 2px 0; }
.gcx-pop-snd { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; }
.gcx-snd {
  appearance: none; border: 1px solid transparent; cursor: pointer; display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 10px; border-radius: 10px; font-size: 12.5px; font-weight: 500; text-align: left;
  background: rgba(255,255,255,.05); color: #e6e9ef;
  transition: background var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.gcx-snd svg.ic { width: 15px; height: 15px; color: var(--primary-2); flex: none; }
.gcx-snd:hover { background: rgba(255,255,255,.12); }
.gcx-snd:active { transform: scale(.97); }
.gcx-snd:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

/* ── 🧠 Всплывающее окно Аи над кнопкой дока (владелец 07.10.2026: «показать над кнопкой, что вкл»).
   Рама — `.gcx-pop`. Оверлей звонка всегда тёмный, поэтому окно НАКРЫВАЕТ токены базы, которые
   берут канон-переключатель `.cc-switch` и сегмент `.cc-seg` (иначе в светлой теме они взяли бы
   светлую палитру на тёмном стекле — канон control-size: локальный скоуп накрывает ВСЕ токены). */
.gc-ai-pop {
  position: fixed;   /* в body и в реестре слоёв — над плавающей «Расшифровкой» (см. CC_LAYER_SEL) */
  width: min(340px, calc(100vw - 20px)); gap: 6px; padding: 12px; color: #e6e9ef;
  --gc-hair: rgba(255,255,255,.08); --gc-hair-2: rgba(255,255,255,.14); --gc-btn: rgba(255,255,255,.06);
  --panel: rgba(255,255,255,.14); --panel-2: rgba(255,255,255,.06); --line: rgba(255,255,255,.16);
  --text: #fff; --text-dim: var(--cm-c7ccd8, #c7ccd8); --muted: #9aa3b4; --ok: #34c759; --sel: rgba(255,255,255,.10);
  /* канон сегмента: переопределяем ВЕСЬ набор --seg-* (в светлой теме пилюля была белой с белым словом) */
  --seg-track: rgba(255,255,255,.06); --seg-thumb: rgba(255,255,255,.22); --seg-thumb-bd: rgba(255,255,255,.18);
  --seg-thumb-sh: 0 1px 2px rgba(0,0,0,.40); --seg-div: rgba(255,255,255,.10);
}
.gc-ai-pop-h { display: flex; align-items: flex-start; gap: 10px; padding: 2px 2px 6px; }
.gc-ai-pop-h > svg.ic { width: 20px; height: 20px; color: var(--primary-2); flex: none; margin-top: 1px; }
.gc-ai-pop-h > span { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.gc-ai-pop-h b { font-size: 14px; font-weight: 650; color: #fff; }
.gc-ai-pop-h small, .gc-ai-pop-txt small { font-size: 12px; line-height: 1.35; color: #9aa3b4; }
.gc-ai-pop-x {
  appearance: none; border: 0; background: transparent; color: #9aa3b4; cursor: pointer; flex: none;
  width: 28px; height: 28px; margin: -4px -4px 0 0; border-radius: 8px; display: inline-grid; place-items: center;
}
.gc-ai-pop-x:hover { background: rgba(255,255,255,.10); color: #fff; }
.gc-ai-pop-x svg.ic { width: 16px; height: 16px; }
.gc-ai-pop-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 8px 10px; border-radius: 12px; background: rgba(255,255,255,.05); cursor: pointer;
}
.gc-ai-pop-seg { cursor: default; }
.gc-ai-pop-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.gc-ai-pop-txt b { font-size: 13.5px; font-weight: 600; color: #fff; }
.gc-ai-pop-heard {
  display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 12px; font-size: 13px; color: #fff;
  background: color-mix(in srgb, var(--primary) 16%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent);
}
.gc-ai-pop-heard svg.ic { width: 16px; height: 16px; color: var(--primary-2); flex: none; }
.gc-ai-pop-heard span { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.gc-ai-pop-heard em { font-style: normal; color: var(--cm-c7ccd8, #c7ccd8); flex: none; }
.gc-ai-pop-hush, .gc-ai-pop-ask button {
  appearance: none; border: 1px solid rgba(255,255,255,.16); background: rgba(255,255,255,.08); color: #fff; cursor: pointer;
  border-radius: 9px; padding: 5px 10px; font-size: 12.5px; font-weight: 600; display: inline-flex; align-items: center; gap: 6px; flex: none;
}
.gc-ai-pop-hush:hover, .gc-ai-pop-ask button:hover { background: rgba(255,255,255,.16); }
.gc-ai-pop-ask { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 4px 2px 0; font-size: 12.5px; color: var(--cm-c7ccd8, #c7ccd8); }
.gc-ai-pop-ask > span { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.gc-ai-pop-ask svg.ic { width: 15px; height: 15px; flex: none; color: var(--primary-2); }

/* 🔴 РАМА ПАНЕЛИ ПЕРЕЕХАЛА в `/app/ccroom.css`: `.gcx-panel`(+`.hidden`, +медиазапрос
   ≤560px), `.gcx-head`, `.gcx-seg`, `.gcx-seg > .gcx-seg-b`, `.gcx-seg-n`,
   `.gcx-panel .gc-people-x`. Гостевая страница рисует панель интерактива ТОЙ ЖЕ
   разметкой и с теми же id, а `style.css` не грузит.
   Остались ЗДЕСЬ (у гостя этого нет): контекстные компаунды с `.groupcall-overlay`/
   `.call-overlay` (гашение в мини-режиме и в эфире, ужимание сцены под открытую панель),
   строка «Кто ведёт» `.gcx-who*`, подсказки `.gcx-hint*`, поповер `.gcx-pop*`/`.gcx-snd`,
   композер ОПРОСА, руки, энергия и список повестки. */
@media (min-width: 561px) {
  .groupcall-overlay.gcx-panel-open .gc-stage { padding-right: 360px; transition: padding-right .16s var(--ease); }
}

/* 🔑 ЗВОН-607·2 «Кто ведёт» — строка ПОД разделами интерактива.
   Владелец: «Кто тогда организатор?» — раньше продукт этого не отвечал нигде, кроме
   боковой панели участников, и писал безличное «ждём ведущего». Строка узкая, экран
   не отбирает, но всегда называет ведущего ПОИМЁННО. */
.gcx-who {
  flex: 0 0 auto; display: flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-bottom: 1px solid rgba(255,255,255,.08);
  font-size: 12px; line-height: 1.35; color: #9aa2b2;
}
.gcx-who.hidden { display: none; }
.gcx-who .ic { width: 13px; height: 13px; flex: none; opacity: .75; }
.gcx-who b { color: var(--cm-e6e9f2, #e6e9f2); font-weight: 600; }

/* 🔴 `.gcx-body`(+скроллбар, +`.hidden`) и `.gcx-sub` — тоже в `/app/ccroom.css`. */
.gcx-hint { font-size: 11.5px; line-height: 1.5; color: #8b93a3; }
.gcx-hint-inline { text-transform: none; letter-spacing: 0; font-weight: 500; color: #6f7789; }

/* 🔴 `.gcx-empty`, `.gcx-empty-top`, `.gcx-meta` и ВЕСЬ блок опроса/квиза
   (`.gcx-poll*`, `.gcx-opt*`, `.gcx-right`) переехали в `/app/ccroom.css`: эту разметку
   строит ОБЩАЯ реализация `ccroom.js`, и её же рисует гостевая страница, которая
   `style.css` не грузит вовсе (канон `guest-call-parity`). Одна декларация на продукт —
   второй копии здесь заводить нельзя. */

/* ── Композер опроса: инлайн, без модалок и без «Сохранить» ── */
/* 🔴 Само поле `.gcx-input`(+`::placeholder`, +`:focus`) переехало в `/app/ccroom.css`:
   один контрол на панель, и им же набирают ВОПРОС в Q&A, который есть у гостя. Здесь
   остаётся ровно композер ОПРОСА — его гость не открывает (опрос запускает организатор). */
.gcx-comp { display: flex; flex-direction: column; gap: 6px; }
.gcx-comp-q { font-size: 14px; font-weight: 600; margin-bottom: 2px; }
.gcx-comp-opt { display: flex; align-items: center; gap: 6px; }
.gcx-x, .gcx-correct {
  appearance: none; cursor: pointer; flex: 0 0 auto; width: 30px; height: 30px; border-radius: 9px;
  display: grid; place-items: center; border: 1px solid var(--gc-hair);
  background: rgba(255,255,255,.04); color: #8b93a3;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.gcx-x:hover { background: rgba(239,68,68,.18); color: #ffb0b0; border-color: rgba(239,68,68,.34); }
.gcx-correct:hover { background: rgba(255,255,255,.10); color: #e6e9ef; }
.gcx-correct.on { background: rgba(93,202,165,.20); border-color: rgba(93,202,165,.5); color: #5DCAA5; }
.gcx-x svg.ic, .gcx-correct svg.ic { width: 14px; height: 14px; }
.gcx-x:focus-visible, .gcx-correct:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.gcx-add {
  appearance: none; cursor: pointer; align-self: flex-start; display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 9px; border: 1px dashed var(--gc-hair-2); background: transparent;
  color: #9aa3b4; font-size: 12.5px; font-weight: 550; font-family: inherit;
  transition: color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.gcx-add:hover { color: #e6e9ef; border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }
.gcx-add svg.ic { width: 14px; height: 14px; }
.gcx-add:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.gcx-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 2px; }
.gcx-chip {
  appearance: none; cursor: pointer; padding: 5px 10px; border-radius: 999px; font-family: inherit;
  border: 1px solid var(--gc-hair-2); background: rgba(255,255,255,.04); color: #9aa3b4;
  font-size: 11.5px; font-weight: 550;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease);
}
.gcx-chip:hover { color: #e6e9ef; background: rgba(255,255,255,.09); }
.gcx-chip.on { background: color-mix(in srgb, var(--primary) 20%, transparent); border-color: color-mix(in srgb, var(--primary) 52%, transparent); color: var(--cm-cfd6ff, #cfd6ff); }
.gcx-chip:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.gcx-wide {
  appearance: none; cursor: pointer; width: 100%; margin-top: 6px; padding: 10px 14px; border-radius: 11px;
  border: 1px solid var(--gc-hair-2); background: rgba(255,255,255,.06); color: #e6e9ef;
  font-size: 13px; font-weight: 600; font-family: inherit;
  transition: background var(--dur-1) var(--ease), filter var(--dur-1) var(--ease), transform var(--dur-1) var(--ease);
}
.gcx-wide:hover { background: rgba(255,255,255,.12); }
.gcx-wide:active { transform: scale(.99); }
.gcx-wide.primary { background: var(--acc-grad); border-color: transparent; color: #fff; }
.gcx-wide.primary:hover { filter: brightness(1.08); }
.gcx-wide:focus-visible { outline: 2px solid var(--primary-2); outline-offset: 2px; }

/* 🔴 Q&A (`.gcx-qa*`, `.gcx-up`) переехал в `/app/ccroom.css` — строку вопроса строит
   общая `CcRoom.qaRowHtml`, и её же рисует гость. Здесь остаётся ТОЛЬКО композер: поле,
   кнопка отправки и «спросить анонимно» — это хром шторки основного клиента. */

/* 🔴 Композер Q&A (`.gcx-compose`(+`.hidden`), `.gcx-input-row`, `.gcx-send`(+состояния),
   `.gcx-anon`(+`.hidden`, +`input`)) переехал в `/app/ccroom.css`: вопрос задаёт и гость,
   разметка та же. */

/* ── Повестка = задачи (живые .tw-row из renderWsList) ── */
/* 🔎 CLIE-687: собственный поиск повестки — над списком, шириной панели, той же
   геометрии, что поле вопроса Q&A (`.gcx-input`): один контрол на панель. */
.gcx-agenda-search { padding: 0 12px 8px; }
.gcx-agenda-search .gcx-input { width: 100%; }
.gcx-agenda-list { margin: 0 -12px; }
.gcx-agenda .tw-list { padding: 4px 12px 8px; }
.gcx-agenda .tw-sec-title { padding: 10px 2px 6px; }
.gcx-agenda .tw-row { padding: 8px 10px 8px 14px; }
.gcx-agenda .tw-row.gcx-row-focus { background: color-mix(in srgb, var(--primary) 14%, transparent); border-color: color-mix(in srgb, var(--primary) 40%, transparent); }
/* 🔴 Плашка «Сейчас обсуждаем» (`.gcx-focus*`) переехала в `/app/ccroom.css`: её строит
   общая `CcRoom.focusHtml` и видит в том числе гость. Список повестки выше — живые
   карточки задач (`.tw-row` из renderWsList), их у гостя нет, и они остаются здесь. */

/* ── Очередь поднятых рук + энергия команды в панели участников ── */
.gcx-hands, .gcx-energy-call { padding: 10px 14px 0; }
.gcx-hands.hidden, .gcx-energy-call.hidden { display: none; }
.gcx-hands .gcx-sub { margin-bottom: 6px; }
.gcx-hands .st-hand + .st-hand { margin-top: 6px; }
.gcx-hands .st-hand-acts { flex-wrap: wrap; justify-content: flex-end; }

/* «Энергия команды»: компактный свод. Внутри звонка — на тёмном; в поповере статуса
   (снаружи оверлея) — на обычных токенах темы, светлой и тёмной одинаково. */
.gcx-energy { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; }
.gcx-en {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--muted);
  white-space: nowrap;
}
.gcx-en b { font-weight: 650; color: var(--text); font-variant-numeric: tabular-nums; }
.gcx-en-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: var(--muted); }
.gcx-en-on .gcx-en-dot { background: #22c55e; }
.gcx-en-call .gcx-en-dot { background: var(--primary); }
.gcx-en-focus .gcx-en-dot { background: #E5A23C; }
.gcx-en-dnd .gcx-en-dot { background: #8b93a3; }
.gcx-energy-call { color: #9aa3b4; }
.gcx-energy-call .gcx-en { color: #8b93a3; }
.gcx-energy-call .gcx-en b { color: #e6e9ef; }
.gcx-energy-pop { padding: 2px 14px 8px; margin-top: -4px; }

/* 🔴 Сам слой указки и её точка с подписью (`.gcx-pointer-layer`, `.gcx-ptr`,
   `.gcx-ptr.flip`, `.gcx-ptr-dot`, `.gcx-ptr-n`) переехали в `/app/ccroom.css`: разметку
   точки строит общая `CcRoom.ptrHtml`, а геометрию кадра — `CcRoom.normXY/denormXY`.
   Здесь остаётся только «одежда под дом основного клиента» — курсор на плитке показа. */
/* курсор-крест на плитке показа, пока указка включена — понятно, что жест «живой» */
.groupcall-overlay.gcx-pointing .gtile.screen-share { cursor: crosshair; }

@media (prefers-reduced-motion: reduce) {
  .gcx-pop { animation: none; }
  /* `.gcx-opt-bar`, `.gcx-opt`, `.gcx-qa`, `.gcx-up`, `.gcx-panel`, `.gcx-seg-b`,
     `.gcx-input`, `.gcx-send` сняты отсюда вместе со своими правилами — их «без движения»
     живёт в `/app/ccroom.css`, чтобы доехало и до гостя. */
  .gcx-chip, .gcx-snd, .gcx-wide, .gcx-add, .gcx-x, .gcx-correct { transition: none; }
}

/* ── «Завершить эфир» — та же геометрия, что у «Выйти», но приглушённее ── */
.groupcall-controls #stEndBtn { background: rgba(239,68,68,.18); border: 1px solid rgba(239,68,68,.38); color: #ffc9c9; }
.groupcall-controls #stEndBtn:hover { background: rgba(239,68,68,.30); color: #fff; }
.groupcall-controls #stHandBtn.on { background: var(--acc-grad); color: #fff; box-shadow: 0 0 0 2px rgba(255,255,255,.24) inset; }

/* ── Строка эфира в списке чатов (вкладка «Эфиры») ── */
.conv-av.st-av { background: var(--sel); color: var(--primary-2); display: grid; place-items: center; }
.conv-av.st-av .ic { width: 18px; height: 18px; }
.st-item.live .conv-name { font-weight: 600; }
.st-pill {
  display: inline-flex; align-items: center; gap: 6px; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 600; color: var(--danger);
  background: var(--danger-soft); border: 1px solid rgba(239,68,68,.24);
}
.st-pill .st-live-dot { width: 6px; height: 6px; }
.st-rowcopy {
  appearance: none; border: 0; background: transparent; cursor: pointer; padding: 3px;
  border-radius: 6px; color: var(--muted); display: inline-grid; place-items: center;
  transition: background 140ms var(--ease), color 140ms var(--ease);
}
.st-rowcopy:hover { background: var(--hover); color: var(--text); }
.st-rowcopy .ic { width: 14px; height: 14px; }

/* ── Узкий экран: панель эфира уходит под сцену (телефон держит одну колонку) ── */
@media (max-width: 900px) {
  .groupcall-overlay.stream-mode:not(.minimized) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) minmax(0, 44vh) auto;
  }
  .groupcall-overlay.stream-mode:not(.minimized) .groupcall-head { grid-area: 1 / 1 / 2 / 2; }
  .groupcall-overlay.stream-mode:not(.minimized) .gc-stage { grid-area: 2 / 1 / 3 / 2; }
  .groupcall-overlay.stream-mode:not(.minimized) .st-panel { grid-area: 3 / 1 / 4 / 2; margin: 6px 12px; }
  .groupcall-overlay.stream-mode:not(.minimized) .groupcall-controls { grid-area: 4 / 1 / 5 / 2; }
  .groupcall-overlay.stream-mode.st-panel-off:not(.minimized) {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) 0 auto;
  }
}

/* ── Светлая тема: модалки берут токены, поэтому правим только «утопленные» подложки ── */
html[data-theme="light"] .st-tog { border-color: var(--cm-171e34-1, rgba(23,30,52,.10)); }
html[data-theme="light"] .st-tog-sw { background: var(--cm-171e34-18, rgba(23,30,52,.18)); }
html[data-theme="light"] .st-livebar:where(:not(.on)) { border-color: var(--cm-171e34-1, rgba(23,30,52,.10)); } /* CLIE-1946: в эфире (.on) рамка красная, как в тёмной */
html[data-theme="light"] .st-pill { border-color: rgba(239,68,68,.30); }

/* 🔴 Кнопка «иконка + подпись» на всю ширину была display:block → иконка падала на свою
   строку («Начать эфир» с иконкой сверху). Одна строка, центр, 8px зазор — и в модалке
   эфира, и в существующей модалке ссылки для гостей (класс общий). */
.gl-wide { display: flex; align-items: center; justify-content: center; gap: 8px; }
.gl-pin-row button, .st-livebar button { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
/* кнопка в полосе эфира не должна растягиваться (в модалке .primary — на всю ширину) */
.st-livebar > button { flex: 0 0 auto; width: auto; }
.st-livebar-l { flex: 1 1 auto; min-width: 0; }


/* В виде зрителя группа «мик/камера/переворот» пустеет целиком — прячем и её, и
   висящий за ней разделитель (иначе док открывается «сиротской» палочкой). */
.groupcall-overlay.stream-mode .gc-grp.gc-empty { display: none; }
.groupcall-overlay.stream-mode .gc-grp.gc-empty + .gc-sep { display: none; }

/* Кнопки шапки списка чатов («Группа» и «Эфир») — одна строка «иконка + подпись».
   Без этого вторая кнопка ломала подпись под иконку, когда места стало меньше. */
.sidebar-head-actions button {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; padding: 7px 10px;
}
.sidebar-head-actions { flex: 0 1 auto; min-width: 0; }

/* ══════════ 🪟 ВИТРИНА ЭФИРОВ (вкладка «Эфиры»: «Идут сейчас» / «Скоро») ══════════
   Живёт в том же узком столбце списка чатов — поэтому карточка одноколоночная, как в
   мобильных витринах: обложка 16:9, поверх неё статус, под ней текст и действия. */
.st-sc-head {
  display: flex; align-items: center; gap: 8px; list-style: none;
  padding: 14px 10px 6px; font-size: 11.5px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted);
}
.st-sc-head:first-child { padding-top: 8px; }
.st-sc-n {
  min-width: 18px; height: 18px; padding: 0 6px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--panel-2); color: var(--text-dim);
  font-size: 11px; font-weight: 600; letter-spacing: 0;
}

.stc {
  list-style: none; margin: 0 6px 10px; border-radius: 14px; overflow: hidden; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line);
  transition: border-color 140ms var(--ease), transform 140ms var(--ease), box-shadow 140ms var(--ease);
}
.stc:hover { border-color: var(--line-strong); transform: translateY(-1px); box-shadow: var(--shadow-1); }
.stc:active { transform: translateY(0); }
.stc:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* обложка 16:9: аватар беседы, иначе градиент от названия (алгоритм общий с guest.js) */
.stc-cover {
  position: relative; aspect-ratio: 16 / 9; width: 100%;
  background-size: cover; background-position: center;
  display: flex; align-items: flex-start; gap: 6px; padding: 8px;
}
.stc-cover.has-img::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,.42) 0%, rgba(0,0,0,0) 42%, rgba(0,0,0,.30) 100%);
}
.stc-cover > * { position: relative; z-index: 1; }
.stc-ph {
  position: absolute; inset: 0; z-index: 0; display: grid; place-items: center;
  font-size: 30px; font-weight: 650; letter-spacing: .04em; color: rgba(255,255,255,.92);
  text-shadow: 0 1px 2px rgba(0,0,0,.22);
}
/* «В эфире» — сдержанно: тёмная подложка + мягкая красная точка, без кислотной заливки */
.stc-badge, .stc-viewers, .stc-soon {
  display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 9px;
  border-radius: 8px; font-size: 11.5px; font-weight: 600; color: #fff;
  background: var(--cm-0c0e14-62, rgba(12,14,20,.62)); border: 1px solid rgba(255,255,255,.14);
  -webkit-backdrop-filter: blur(10px) saturate(1.2); backdrop-filter: blur(10px) saturate(1.2);
}
.stc-viewers .ic, .stc-soon .ic { width: 13px; height: 13px; }
.stc-lock {
  margin-left: auto; display: inline-grid; place-items: center; width: 24px; height: 24px;
  border-radius: 8px; color: #fff; background: var(--cm-0c0e14-62, rgba(12,14,20,.62));
  border: 1px solid rgba(255,255,255,.14);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
}
.stc-lock .ic { width: 13px; height: 13px; }

.stc-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 6px; }
.stc-title {
  font-size: 14.5px; font-weight: 600; line-height: 1.3; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.stc-host { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-dim); min-width: 0; }
.stc-host > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stc-host-av {
  flex: 0 0 auto; width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center; font-size: 9px; font-weight: 700; color: #fff;
  background-size: cover; background-position: center;
}
.stc-host-av.has-img { color: transparent; }
/* описание — ровно 2 строки, как договорились */
.stc-desc {
  font-size: 12.5px; line-height: 1.45; color: var(--text-dim);
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.stc-acts { display: flex; align-items: center; gap: 8px; margin-top: 2px; }
.stc-btn {
  appearance: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: 9px; font-size: 12.5px; font-weight: 500;
  background: var(--panel); border: 1px solid var(--line); color: var(--text);
  transition: background 140ms var(--ease), border-color 140ms var(--ease);
}
.stc-btn:hover { background: var(--hover); border-color: var(--line-strong); }
.stc-btn.primary { background: var(--acc-fill); border-color: transparent; color: #fff; }
.stc-btn.primary:hover { background: var(--acc-fill-hi); }
.stc-btn .ic { width: 14px; height: 14px; }
.stc-when {
  display: inline-flex; align-items: center; gap: 6px; margin-right: auto;
  font-size: 12.5px; color: var(--text-dim);
}
.stc-when .ic { width: 14px; height: 14px; }
.stc-acts .stc-btn:last-child:not(.primary) { margin-left: auto; }

/* пустая витрина — человеческий экран, а не пустота */
.st-sc-empty {
  list-style: none; display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 8px; padding: 42px 22px;
}
.st-sc-empty-ico {
  width: 52px; height: 52px; display: grid; place-items: center; margin-bottom: 2px;
  border-radius: 16px; background: var(--sel); color: var(--primary-2);
}
.st-sc-empty-ico .ic { width: 26px; height: 26px; }
.st-sc-empty-t { font-size: 15px; font-weight: 600; color: var(--text); }
.st-sc-empty-s { font-size: 12.5px; line-height: 1.55; color: var(--text-dim); max-width: 300px; }

/* скелет загрузки витрины — та же геометрия карточек, чтобы не «прыгало» */
.st-sc-skel { list-style: none; padding: 8px 6px; display: flex; flex-direction: column; gap: 10px; }
.st-sc-skel i {
  display: block; aspect-ratio: 16 / 9; border-radius: 14px; background: var(--panel-2);
  animation: glShimmer 1.2s ease-in-out infinite;
}
.st-sc-skel i:nth-child(2) { animation-delay: .12s; }
@media (prefers-reduced-motion: reduce) { .st-sc-skel i { animation: none; } .stc { transition: none; } }

/* поля витрины в модалках (описание + время начала) */
.st-area {
  width: 100%; resize: vertical; min-height: 56px; padding: 10px 12px; font: inherit; font-size: 13px;
  line-height: 1.45; color: var(--text); background: var(--input-bg);
  border: 1px solid var(--line); border-radius: 10px;
  transition: border-color 140ms var(--ease), background 140ms var(--ease);
}
.st-area:focus { outline: none; border-color: var(--primary); background: var(--panel); }
.st-area::placeholder { color: var(--text-dim); }
.st-when-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.st-when-lbl { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); }
.st-when-lbl .ic { width: 14px; height: 14px; }
.st-when-input {
  flex: 1 1 auto; min-width: 168px; padding: 9px 12px; font: inherit; font-size: 13px;
  color: var(--text); background: var(--input-bg); border: 1px solid var(--line); border-radius: 10px;
  transition: border-color 140ms var(--ease), background 140ms var(--ease);
}
.st-when-input:focus { outline: none; border-color: var(--primary); background: var(--panel); }
.gl-opt { font-weight: 400; text-transform: none; letter-spacing: 0; color: var(--text-dim); }

/* светлая тема: пересчитываем только «утопленные» подложки и хэйрлайны */
html[data-theme="light"] .stc { border-color: var(--cm-171e34-1, rgba(23,30,52,.10)); background: var(--panel); }
html[data-theme="light"] .stc:hover { box-shadow: 0 1px 2px var(--cm-171e34-06, rgba(23,30,52,.06)), 0 6px 16px -6px var(--cm-171e34-14, rgba(23,30,52,.14)); }
html[data-theme="light"] .st-area, html[data-theme="light"] .st-when-input { border-color: var(--cm-171e34-1, rgba(23,30,52,.10)); }
html[data-theme="light"] .st-sc-n { background: var(--panel-2); }

/* у «скоро» время стоит на обложке, поэтому кнопка ссылки остаётся слева, а не улетает вправо */
.stc.soon .stc-acts .stc-btn:last-child:not(.primary) { margin-left: 0; }

/* ═══════════════ Живая расшифровка + перевод (Otter/Zoom-стиль) ═══════════════ */
/* Панель на все типы звонка. Токены (--panel/--line/--text/--primary) сами адаптируют
   светлую и тёмную тему. z-index выше оверлея звонка (10000). */
.lt-panel {
  position: fixed; right: 20px; bottom: 100px; z-index: 10050;
  width: 384px; max-width: calc(100vw - 24px); max-height: min(62vh, 640px);
  display: flex; flex-direction: column;
  background: color-mix(in srgb, var(--panel) 92%, transparent);
  -webkit-backdrop-filter: saturate(160%) blur(20px); backdrop-filter: saturate(160%) blur(20px);
  border: 1px solid var(--line); border-radius: 18px;
  box-shadow: var(--shadow-3);
  overflow: hidden; color: var(--text);
  animation: ltIn .18s cubic-bezier(.2,.7,.3,1);
}
.lt-panel.hidden { display: none; }
.lt-panel.dragging { transition: none; user-select: none; }
@keyframes ltIn { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }

.lt-head {
  display: flex; align-items: center; gap: 8px; padding: 13px 12px 13px 16px;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
  cursor: grab;
}
.lt-panel.dragging .lt-head { cursor: grabbing; }
.lt-title { font-size: 15px; font-weight: 650; letter-spacing: -.01em; flex: 1; }
.lt-head-actions { display: flex; align-items: center; gap: 4px; }
.lt-head-actions .lt-sep { width: 1px; height: 20px; background: var(--line); margin: 0 2px; }

.lt-panel button { font: inherit; cursor: pointer; }
.lt-lang, .lt-min, .lt-pause {
  display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 8px;
  background: transparent; border: 1px solid transparent; border-radius: 9px;
  color: var(--muted); transition: background .13s ease, color .13s ease, border-color .13s ease;
}
.lt-lang svg, .lt-min svg, .lt-pause svg { width: 18px; height: 18px; }
.lt-lang:hover, .lt-min:hover, .lt-pause:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }
.lt-lang { border-color: var(--line); }
.lt-lang-code { font-size: 12px; font-weight: 650; letter-spacing: .02em; min-width: 20px; text-align: center; }

/* M9 · «Озвучивать перевод» — появляется, только когда выбран язык и сервер подтвердил
   синтез (прогрессивное раскрытие: смотришь оригинал — контрол не отбирает экран). */
.lt-voice {
  display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  background: transparent; border: 1px solid transparent; border-radius: 9px;
  color: var(--muted); transition: background .13s ease, color .13s ease, border-color .13s ease;
}
.lt-voice svg { width: 18px; height: 18px; }
.lt-voice:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }
.lt-voice.active { color: var(--primary); border-color: color-mix(in srgb, var(--primary) 35%, transparent); background: color-mix(in srgb, var(--primary) 10%, transparent); }
.lt-voice.hidden { display: none; }

/* M4 · «Догони меня» — появляется, только когда встреча известна (прогрессивное раскрытие) */
.lt-catch-btn {
  display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  background: transparent; border: 1px solid transparent; border-radius: 9px; color: var(--muted);
  transition: background .13s ease, color .13s ease;
}
.lt-catch-btn svg { width: 18px; height: 18px; }
.lt-catch-btn:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }
.lt-catch-btn.busy { color: var(--primary); animation: ltSpin 1s linear infinite; }
@keyframes ltSpin { to { transform: rotate(360deg); } }
.lt-catch {
  margin: 2px 0 10px; padding: 10px 12px; border-radius: 12px;
  background: color-mix(in srgb, var(--primary) 9%, var(--panel-2));
  border: 1px solid color-mix(in srgb, var(--primary) 22%, transparent);
  animation: ltIn .16s ease;
}
.lt-catch.empty, .lt-catch.err { background: var(--panel-2); border-color: var(--line); }
.lt-catch-h { font-size: 12px; font-weight: 650; letter-spacing: .01em; color: var(--primary); margin-bottom: 4px; }
.lt-catch.empty .lt-catch-h, .lt-catch.err .lt-catch-h { color: var(--muted); }
.lt-catch-b { font-size: 13.5px; line-height: 1.5; color: var(--text); }
.lt-catch-m { margin-top: 6px; font-size: 12px; color: var(--muted); }
.lt-catch.loading .lt-catch-b { color: var(--muted); }

.lt-body {
  flex: 1; overflow-y: auto; padding: 12px 14px 8px; display: flex; flex-direction: column; gap: 2px;
  scrollbar-width: thin;
}
.lt-body::-webkit-scrollbar { width: 8px; }
.lt-body::-webkit-scrollbar-thumb { background: var(--line); border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }

.lt-line { padding: 6px 0; }
.lt-line.cont { padding-top: 1px; margin-top: -3px; }
.lt-line-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.lt-avatar {
  width: 26px; height: 26px; flex: 0 0 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 12px; font-weight: 650; color: #fff;
  background: hsl(var(--h,220) 52% 48%);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.12);
}
.lt-name { font-size: 13px; font-weight: 600; color: var(--text); }
.lt-time { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.lt-text { font-size: 14.5px; line-height: 1.46; color: var(--text); padding-left: 34px; word-wrap: break-word; }
.lt-line.cont .lt-text { padding-top: 0; }
.lt-trans {
  font-size: 13.5px; line-height: 1.42; padding-left: 34px; margin-top: 3px;
  color: color-mix(in srgb, var(--primary) 82%, var(--text));
}
.lt-trans:empty { display: none; }
.lt-trans.loading::after { content: "…"; color: var(--muted); }

.lt-foot {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
}
.lt-timer { font-size: 13px; font-variant-numeric: tabular-nums; color: var(--muted); font-weight: 550; }
.lt-live { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); }
.lt-live-dot { width: 8px; height: 8px; border-radius: 50%; background: #e0483d; box-shadow: 0 0 0 0 rgba(224,72,61,.55); animation: ltPulse 1.6s infinite; }
.lt-panel.paused .lt-live-dot { background: var(--muted); animation: none; box-shadow: none; }
@keyframes ltPulse { 0% { box-shadow: 0 0 0 0 rgba(224,72,61,.5); } 70% { box-shadow: 0 0 0 7px rgba(224,72,61,0); } 100% { box-shadow: 0 0 0 0 rgba(224,72,61,0); } }
.lt-foot-sp { flex: 1; }
.lt-done {
  height: 32px; padding: 0 16px; border: none; border-radius: 9px;
  background: var(--acc-fill); color: #fff; font-size: 13.5px; font-weight: 600;
  transition: filter .13s ease, transform .08s ease;
}
.lt-done:hover { filter: brightness(1.06); }
.lt-done:active { transform: scale(.97); }
.lt-pause.resumed { color: var(--primary); }

/* Меню выбора языка перевода */
.lt-menu {
  position: fixed; z-index: 10060; min-width: 210px; max-height: 320px; overflow-y: auto;
  padding: 6px; background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow-3); animation: ltIn .14s ease;
}
.lt-menu-item {
  display: flex; align-items: center; width: 100%; padding: 8px 10px; gap: 8px;
  background: transparent; border: none; border-radius: 9px; color: var(--text);
  font-size: 13.5px; text-align: left; transition: background .1s ease;
}
.lt-menu-item:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.lt-menu-item.sel { color: var(--primary); font-weight: 600; }
.lt-menu-item.sel::after { content: "✓"; margin-left: auto; font-weight: 700; }

/* Активная кнопка «Расшифровка» в панели управления звонком */
#gcCcBtn.active, #caCcBtn.active { color: var(--primary); background: color-mix(in srgb, var(--primary) 16%, transparent); }

@media (max-width: 560px) {
  .lt-panel { right: 8px; left: 8px; bottom: 84px; width: auto; max-height: 56vh; }
}

/* ═══ «Рычаг качества» видеосвязи — поповер выбора (группа + 1-на-1). Единый компонент,
      светлая и тёмная темы едут на токенах (--panel-3 = поднятый слой меню, --shadow-3). ═══ */
.cc-quality-menu {
  position: fixed; z-index: 100000; min-width: 246px; max-width: calc(100vw - 16px);
  padding: 6px; background: var(--panel-3); border: 1px solid var(--border);
  border-radius: 14px; box-shadow: var(--shadow-3);
  opacity: 0; transform: translateY(6px) scale(.985); transform-origin: bottom center;
  transition: opacity .14s ease, transform .16s cubic-bezier(.32,.72,.35,1);
  -webkit-backdrop-filter: saturate(1.5) blur(20px); backdrop-filter: saturate(1.5) blur(20px);
}
.cc-quality-menu.open { opacity: 1; transform: translateY(0) scale(1); }
.cc-quality-menu .cq-head {
  font-size: 11px; font-weight: 600; letter-spacing: .045em; text-transform: uppercase;
  color: var(--text-dim); padding: 8px 10px 6px;
}
.cc-quality-menu .cq-item {
  display: flex; align-items: flex-start; gap: 10px; width: 100%;
  padding: 9px 10px; border: 0; border-radius: 10px; background: transparent;
  color: var(--text); text-align: left; cursor: pointer; transition: background .12s ease;
}
.cc-quality-menu .cq-item:hover { background: var(--panel-2); }
.cc-quality-menu .cq-item.active { background: color-mix(in srgb, var(--primary) 12%, transparent); }
.cc-quality-menu .cq-item:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--primary) inset; }
.cc-quality-menu .cq-check {
  flex: 0 0 18px; width: 18px; height: 18px; margin-top: 1px;
  display: flex; align-items: center; justify-content: center; color: var(--primary);
}
.cc-quality-menu .cq-check svg { width: 16px; height: 16px; }
.cc-quality-menu .cq-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cc-quality-menu .cq-label { font-size: 14px; font-weight: 600; line-height: 1.2; }
.cc-quality-menu .cq-item.active .cq-label { color: var(--primary); }
.cc-quality-menu .cq-hint { font-size: 11.5px; color: var(--muted); line-height: 1.3; white-space: normal; }
/* Разделитель секций меню (Качество видео ↔ Звук) — тонкий хэйрлайн, как в системных меню */
.cc-quality-menu .cq-sep { height: 1px; margin: 6px 10px; background: var(--border); opacity: .8; }
/* Адаптив (W0.4) опустил качество — РОВНО одна сдержанная строка, без «алярма». */
.cc-quality-menu .cq-note {
  margin: 4px 4px 2px; padding: 7px 8px; border-radius: 9px;
  font-size: 11.5px; line-height: 1.35; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--border);
}

/* ═══ M8 · Код безопасности созвона (SAS): чип в шапке + поповер сверки ═══
      Чип живёт в .gc-head-right (оверлей всегда тёмный → фиксированный светлый slate,
      как у .gc-elapsed/.gc-rec-dot). Поповер — тот же компонент, что меню качества
      (.cc-quality-menu), поэтому светлая/тёмная темы едут на общих токенах. */
.gc-sas {
  display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 10px;
  border-radius: 9px; border: 1px solid rgba(255,255,255,.14); background: rgba(255,255,255,.06);
  color: var(--cm-c7ccd8, #c7ccd8); font: inherit; font-size: 12px; cursor: pointer;
  transition: background .14s ease, border-color .14s ease;
}
.gc-sas:hover { background: rgba(255,255,255,.12); border-color: rgba(255,255,255,.22); }
.gc-sas:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--primary); }
.gc-sas-e { font-size: 13px; letter-spacing: 1px; line-height: 1; }
.gc-sas-d { font-variant-numeric: tabular-nums; letter-spacing: .6px; font-weight: 600; }
.cc-sas-pop { min-width: 268px; max-width: 320px; }
.cc-sas-pop .sas-code {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 10px 12px; margin: 0 4px; border-radius: 11px;
  background: var(--panel-2); border: 1px solid var(--border);
}
.cc-sas-pop .sas-e { font-size: 26px; letter-spacing: 4px; line-height: 1.15; }
.cc-sas-pop .sas-d {
  font-size: 20px; font-weight: 650; letter-spacing: 3px;
  font-variant-numeric: tabular-nums; color: var(--text);
}
.cc-sas-pop .sas-note { padding: 10px 10px 2px; font-size: 12.5px; line-height: 1.4; color: var(--text); }
.cc-sas-pop .sas-fine { padding: 6px 10px 8px; font-size: 11px; line-height: 1.35; color: var(--text-dim); }
/* Уровень проверки ЭТОЙ комнаты (пер-комнатный E2EE, ЗВОН-остаток 22.08). Стоит там же,
   где человек про защиту читает, — под кодом безопасности. Переключатель — КАНОН .cc-seg
   (второго вида в продукте нет), поэтому своих чисел высоты/радиуса тут нет. */
.cc-sas-pop .sas-lvl { padding: 8px 10px 10px; border-top: 1px solid var(--line); margin-top: 4px; }
.cc-sas-pop .sas-lvl-t { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--text-dim); margin-bottom: 7px; }
.cc-sas-pop .sas-lvl-seg { display: inline-flex; width: 100%; }
.cc-sas-pop .sas-lvl-seg > button { flex: 1 1 0; min-width: 0; }
.cc-sas-pop .sas-lvl .sas-fine { padding: 6px 0 0; }

/* ═══ M11.3 · КОД БЕЗОПАСНОСТИ В ЗВОНКЕ 1-НА-1 (анти-MITM) ═══
   Тот же чип `.gc-sas`, что в групповом созвоне (второй компонент не заводим), но живёт
   он в оверлее 1-на-1, где фон — видео или градиент: поэтому подложка тёмная с блюром,
   а не «светлый slate» шапки SFU. Появляется ТОЛЬКО когда код реально посчитан — до
   этого экран не отбираем (прогрессивное раскрытие). */
.call-sas {
  position: absolute; left: 0; right: 0;
  top: calc(env(safe-area-inset-top) + 52px);
  z-index: 3; display: flex; justify-content: center; padding: 0 16px;
  pointer-events: none;
}
.call-sas > * { pointer-events: auto; }
/* В аудио-дизайне заголовок статуса скрыт (дублируется по центру) → чип поднимается выше. */
.call-overlay.audio-mode .call-sas { top: calc(env(safe-area-inset-top) + 18px); }
/* Свёрнутый звонок (PiP) — только видео и две кнопки, чип бы не влез. */
.call-overlay.minimized .call-sas { display: none; }
/* 🎞️ ЗВОН-34: плотная подложка вместо блюра — чип висит на живом кадре ВЕСЬ звонок
   (появляется, как только код посчитан, и больше не уходит), а `backdrop-filter` над
   видео стоит readback фона на каждый кадр. .34 + блюр → .58: код безопасности так же
   читается на светлом кадре, вид «тёмного стекла» сохранён. */
.call-sas .gc-sas {
  max-width: 100%; background: rgba(0,0,0,.58); border-color: rgba(255,255,255,.18);
  color: #fff; box-shadow: 0 4px 18px rgba(0,0,0,.28);
}
.call-sas .gc-sas:hover { background: rgba(0,0,0,.68); border-color: rgba(255,255,255,.30); }
/* Проверка не прошла (подменённый отпечаток / битая подпись) — красный, без эмодзи-кода. */
.call-sas .gc-sas.bad { background: var(--danger); border-color: transparent; }
.call-sas .gc-sas-w { opacity: .85; font-size: 15px; line-height: 1; color: #ffd479; }

/* ═══ ⬆️ ПОВЫШЕНИЕ ЗВОНКА 1:1 ДО КОНФЕРЕНЦИИ — ЧЕСТНЫЙ ИНДИКАТОР ПЕРЕХОДА ═══
   Живёт там же, где чип кода безопасности (его как раз снимают в этот момент), и тем же
   языком: тёмная полупрозрачная подложка с блюром поверх видео, тонкое кольцо-хэйрлайн,
   без единой левой рейки. Появляется ТОЛЬКО на время перехода — пустое состояние экран
   не отбирает. Пока идёт переход, кнопки функций гасим: нажатие на них в этот момент
   ничего осмысленного не сделает, а «мёртвых» контролов у нас быть не должно. */
.call-up-bar {
  position: absolute; left: 0; right: 0;
  top: calc(env(safe-area-inset-top) + 52px);
  z-index: 4; display: flex; justify-content: center; padding: 0 16px;
  pointer-events: none;
  animation: cubIn 160ms ease-out both;
}
.call-up-bar > * { pointer-events: auto; }
@keyframes cubIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
/* Три span'а собираются в ОДНУ пилюлю: общая подложка + кольцо-хэйрлайн, скругления по краям. */
.call-up-bar .cub-spin,
.call-up-bar .cub-t,
.call-up-bar .cub-s {
  display: inline-flex; align-items: center; height: 30px;
  background: rgba(0,0,0,.34); backdrop-filter: blur(8px); color: #fff;
  box-shadow: inset 0 -1px 0 rgba(255,255,255,.18), inset 0 1px 0 rgba(255,255,255,.18);
}
.call-up-bar .cub-spin {
  width: 32px; justify-content: flex-end; border-radius: 999px 0 0 999px; padding-left: 11px;
  box-shadow: inset 1px 0 0 rgba(255,255,255,.18), inset 0 -1px 0 rgba(255,255,255,.18), inset 0 1px 0 rgba(255,255,255,.18);
}
.call-up-bar .cub-spin::before {
  content: ""; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.32); border-top-color: #fff;
  animation: cubSpin .8s linear infinite;
}
@keyframes cubSpin { to { transform: rotate(360deg); } }
.call-up-bar .cub-t { padding: 0 8px; font-size: 13px; font-weight: 600; letter-spacing: .1px; }
.call-up-bar .cub-s {
  padding: 0 13px 0 0; border-radius: 0 999px 999px 0; font-size: 13px; opacity: .78;
  box-shadow: inset -1px 0 0 rgba(255,255,255,.18), inset 0 -1px 0 rgba(255,255,255,.18), inset 0 1px 0 rgba(255,255,255,.18);
}
/* Свёрнутый звонок (PiP) — только видео и две кнопки, полоса бы не влезла. */
.call-overlay.minimized .call-up-bar { display: none; }
/* Переход идёт → функции звонка не трогаем (двойной тап и «нажал в полёте» = один эффект). */
/* 🔴 CLIE-1219: не `>`, а потомки — кнопки ряда теперь стоят группами `.gc-grp`
   (док), и прямой дочерний селектор перестал их находить: во время перехода в
   конференцию они снова стали бы нажимаемыми. */
.call-overlay.upgrading .call-controls button:not(#hangupBtn):not(#minimizeBtn) {
  opacity: .45; pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .call-up-bar { animation: none; }
  .call-up-bar .cub-spin::before { animation-duration: 2.4s; }
}

/* ═══ M8 · Чип «Восстанавливаем связь…» — ИНЛАЙН в шапке созвона, не модалка.
      Живёт в .gc-head-right рядом с «идёт запись»: сетка участников не прыгает,
      человек видит, что связь восстанавливают, и не жмёт «выйти». ═══ */
.gc-net-chip {
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px;
  border-radius: 9px; font-size: 12px; font-weight: 600; white-space: nowrap;
  color: #ffe6c2; background: rgba(245,166,35,.13); border: 1px solid rgba(245,166,35,.32);
}
.gc-net-dot {
  width: 8px; height: 8px; border-radius: 50%; background: #f5a623; flex: 0 0 auto;
  animation: gcNetPulse 1.6s ease-in-out infinite;
}
@keyframes gcNetPulse { 0%,100% { opacity: .35; transform: scale(.82); } 50% { opacity: 1; transform: scale(1); } }
/* 🔁 «Связь не восстановилась — пробуем снова»: выходы «Переподключить» / «Выйти» прямо в чипе
   (правило ОТКАЗА: не стена, а действие). Пока пробуем сами — кнопок нет.
   🔴 `.gc-net-act.ghost` (0,3,0): без него `html[data-theme="light"] .ghost` (0,2,1) снимал в светлой
   теме фон и рамку — кнопки чипа становились текстом (тот же капкан, что у ряда обрыва звонка 1:1). */
.gc-net-chip .gc-net-act,
.gc-net-chip .gc-net-act.ghost {
  flex: 0 0 auto; width: auto; margin: 0 0 0 4px; height: 22px; padding: 0 9px; border-radius: 7px;
  font-size: 11.5px; font-weight: 700; cursor: pointer; color: #ffe6c2;
  background: rgba(245,166,35,.18); border: 1px solid rgba(245,166,35,.42);
}
.gc-net-chip .gc-net-act:hover,
.gc-net-chip .gc-net-act.ghost:hover { background: rgba(245,166,35,.3); }
/* Узкий экран: слова переносятся, кнопки остаются на виду (чип не уезжает за левый край). */
.gc-net-chip { max-width: 100%; min-width: 0; }
@media (max-width: 600px) {
  .gc-net-chip:has(.gc-net-act) { height: auto; min-height: 30px; white-space: normal; flex-wrap: wrap; padding: 5px 10px; row-gap: 5px; }
  .gc-net-chip:has(.gc-net-act) .gc-net-t { flex: 1 1 calc(100% - 20px); }
}
@media (prefers-reduced-motion: reduce) { .gc-net-dot { animation: none; opacity: .9; } }

/* 🎵 ЗВОН 04.10.2026 · Чип «Музыкальный режим · Обычный» — режим живёт в аккаунте и приезжает на
   каждое устройство, поэтому пока он включён, его ВИДНО на экране звонка (1-на-1 — справа сверху,
   зеркально «Запись»; конференция — в шапке рядом с чипом связи). Одно нажатие «Обычный» — та же
   дверь, что пункт меню качества (ccCallMusicSet). Язык — сдержанный, как у соседних чипов; оттенок
   бирюзовый — свой: красный занят «Записью», янтарный — связью, сине-фиолетовый — ИИ-двойником.
   Оверлеи звонка тёмные в обеих темах — цвета заданы явно. */
.cc-music-chip {
  display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 6px 0 12px;
  border-radius: 9px; font-size: 12px; font-weight: 600; white-space: nowrap; max-width: 100%; min-width: 0;
  color: #c8f3ec; background: rgba(45,212,191,.13); border: 1px solid rgba(45,212,191,.34);
}
.cc-music-chip .cc-music-t { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.cc-music-chip .cc-music-act {
  flex: 0 0 auto; width: auto; margin: 0; height: 22px; padding: 0 9px; border-radius: 7px;
  font-size: 11.5px; font-weight: 700; cursor: pointer; color: #e6fbf7;
  background: rgba(45,212,191,.2); border: 1px solid rgba(45,212,191,.46);
}
.cc-music-chip .cc-music-act:hover { background: rgba(45,212,191,.32); }
#caMusicChip {
  position: absolute; z-index: 3;
  right: calc(env(safe-area-inset-right) + 14px); top: calc(env(safe-area-inset-top) + 14px);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
}
.call-overlay.minimized #caMusicChip { display: none; }
/* Узкий экран: статус звонка по центру сверху — чип уходит ниже, к правому краю, и короче. */
@media (max-width: 600px) {
  #caMusicChip { top: calc(env(safe-area-inset-top) + 132px); right: calc(env(safe-area-inset-right) + 10px); }
}

/* ═══════════════ Тикеты — Apple-grade карточка деталей (tkd-*) ═══════════════
   Единый визуальный язык детали обращения: и v2-шторка доски, и боковая панель
   #ticketInfoPanel. Всё на токенах (--panel/--line/--primary) → светлая И тёмная
   темы одинаково. НЕ трогает td- / tip- задач (см. предупреждение о «звёздочка+слэш»
   в комментарии к 3.17: из-за него правило .tkd ниже НЕ применялось на проде). */
.tkd { display: flex; flex-direction: column; gap: 12px; }

/* Шапка-гланс: статус (пилюля или select) + SLA */
.tkd-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tkd-head .tw-select { flex: none; width: auto; min-width: 150px; } /* width:auto бьёт .ticket-info-panel .tw-select{width:100%} — иначе SLA переносится */
.tkd-head .tkd-sla { margin-left: auto; }

/* Постановщик — герой (автор сообщения = постановщик обращения) */
.tkd-req { display: flex; align-items: center; gap: 11px; padding: 11px 13px;
  background: color-mix(in srgb, var(--primary) 8%, var(--panel-2));
  border: 1px solid color-mix(in srgb, var(--primary) 22%, var(--line));
  border-radius: 13px; }
.tkd-req-av { flex: none; display: inline-flex; }
.tkd-req-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.tkd-req-k { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--primary-2); }
.tkd-req-name { font-size: 15px; font-weight: 650; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tkd-chan { flex: none; }

/* Мета — сгруппированный список (стиль iOS Settings): хэйрлайны, скругление */
.tkd-list { border: 1px solid var(--line); border-radius: 13px; overflow: hidden; background: var(--panel); }
.tkd-row { display: flex; align-items: center; gap: 12px; padding: 10px 13px; min-height: 42px; }
.tkd-row + .tkd-row { border-top: 1px solid var(--line); }
.tkd-row-k { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; color: var(--muted); flex: none; min-width: 116px; }
.tkd-row-k svg.ic { width: 14px; height: 14px; opacity: .7; }
.tkd-row-v { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: flex-end; gap: 6px; font-size: 14px; color: var(--text); text-align: right; }
.tkd-row-v.muted, .tkd-row-v.tw-muted { color: var(--muted); }
.tkd-row-v .tw-select { max-width: 210px; width: auto; }
/* узкая шторка (телефон 390): список шире остатка строки, а .tkd-row-v прижимает его вправо
   (flex-end) — лишнее уходило ВЛЕВО, на подпись («Ответственны|Тест акк»). Список сжимается сам. */
.tkd-row-v > .tw-select { flex: 0 1 auto; min-width: 0; max-width: min(210px, 100%); text-overflow: ellipsis; }
.tkd-row-v .v2-star { cursor: pointer; }

/* Статус-пилюля (гланс) — мягкий цвет по категории, обе темы */
.tkd-pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 11px; border-radius: 999px;
  font-size: 12.5px; font-weight: 650; line-height: 1; white-space: nowrap; border: 1px solid transparent; }
.tkd-pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.tkd-pill[data-cat="new"], .tkd-pill[data-cat="open"] { color: #8fb0f5; background: color-mix(in srgb, #5b8def 15%, transparent); border-color: color-mix(in srgb, #5b8def 28%, transparent); }
.tkd-pill[data-cat="pending"] { color: #e3a955; background: color-mix(in srgb, #f5a623 16%, transparent); border-color: color-mix(in srgb, #f5a623 30%, transparent); }
.tkd-pill[data-cat="on_hold"] { color: var(--muted); background: color-mix(in srgb, var(--muted) 15%, transparent); border-color: color-mix(in srgb, var(--muted) 26%, transparent); }
.tkd-pill[data-cat="resolved"] { color: #5fcf8e; background: color-mix(in srgb, #2ecc71 15%, transparent); border-color: color-mix(in srgb, #2ecc71 30%, transparent); }
.tkd-pill[data-cat="closed"] { color: var(--text-dim); background: color-mix(in srgb, var(--text-dim) 14%, transparent); border-color: color-mix(in srgb, var(--text-dim) 24%, transparent); }
.tkd-pill.mini { padding: 2px 8px 2px 7px; font-size: 11px; font-weight: 600; }
.tkd-pill.mini::before { width: 6px; height: 6px; }

/* Приоритет-чип с цветной точкой (--pc задаётся инлайн по приоритету) */
.tkd-prio { display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; font-weight: 600; color: var(--text); }
.tkd-prio::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--pc, var(--muted)); flex: none; }
.tkd-prio.mini { font-size: 11.5px; font-weight: 600; color: var(--muted); }
.tkd-prio.mini::before { width: 6px; height: 6px; }
/* Светлая тема: затемняем текст статус-пилюль до AA на белой панели (как соседние чипы приложения) */
html[data-theme="light"] .tkd-pill[data-cat="new"], html[data-theme="light"] .tkd-pill[data-cat="open"] { color: var(--cm-2f5bd0, #2f5bd0); }
html[data-theme="light"] .tkd-pill[data-cat="pending"] { color: #9a6a00; }
html[data-theme="light"] .tkd-pill[data-cat="resolved"] { color: #1a7a4a; }

/* ═══════════════════ Вид «Схема» — граф зависимостей задач (n8n/Miro) ═══════════════════ */
/* Рама холста (.cc-schema · -vp · -canvas · -gl · -map) и стеклянный тулбар (.cc-schema-tools ·
   .cc-sch-btn · .cc-sch-zoom · .cc-sch-sep) живут в ccboard.css — ОДНОЙ декларацией на продукт и на
   окно онлайн-чата, где style.css не грузится (CLIE-1848·B, канон guest-call-parity). */
/* 🔴 CLIE-448: ВИД «СХЕМЫ» НЕ МЕНЯЕТСЯ ВО ВРЕМЯ ДВИЖЕНИЯ. Владелец: «изначально верно показывает,
   но во время перемещения экрана или приближения/удаления меняет дизайн на момент движения — так не
   нужно». Раньше на время жеста включалась «motion-mask»: гас backdrop-blur панелей и ярлыков, гасли
   тени карточек, а весь DOM-слой холста уходил в opacity:0, и вместо него показывалась canvas-копия
   карточек (другой шрифт, инициалы вместо фото, часть пилюль отсутствовала) — на глаз это и есть
   «дизайн поменялся». Ни одного такого правила здесь больше НЕТ: то, что человек видит в покое, он
   видит и в движении. Плавность держат ВИРТУАЛИЗАЦИЯ вьюпорта + LOD + мемоизация раскладки
   (syncViewport/schemaLayoutFor), а не подмена внешнего вида. НЕ возвращать motion-mask. */
/* ── ЕДИНЫЙ canvas НЕинтерактивного слоя (острова → рамки → связи → стрелки): ОДИН GPU-слой вместо СОТЕН
   SVG/HTML/blur-узлов → на ПК (живой GPU Chromium) больше нет «взрыва слоёв» компоновщика = конец
   мельтешанию/«видеокарта не тянет». Рисуется в координатах вьюпорта с текущим трансформом (а НЕ CSS-scale),
   поэтому чёткий на любом зуме, как figma/miro. pointer-events:none — клики/пан проходят к узлам и фону. ── */
/* ── полупрозрачные «острова» группировки по метке — ПОД связями и узлами (владелец: «задачи с
   одинаковой меткой визуально сгруппировать полупрозрачным квадратом цветом метки») ── */
.cc-schema-groups { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.cc-group { position: absolute; border-radius: 22px; background: color-mix(in srgb, var(--gc) 10%, transparent);
  border: 1.5px solid color-mix(in srgb, var(--gc) 30%, transparent);
  box-shadow: inset 0 0 40px color-mix(in srgb, var(--gc) 7%, transparent); }
.cc-group-tag { position: absolute; left: 16px; top: -12px; display: inline-flex; align-items: center; gap: 6px;
  height: 23px; padding: 0 11px; border-radius: 12px; font-size: 11px; font-weight: 700; letter-spacing: .01em; white-space: nowrap;
  background: color-mix(in srgb, var(--gc) 20%, var(--panel)); color: color-mix(in srgb, var(--gc) 52%, var(--text));
  border: 1px solid color-mix(in srgb, var(--gc) 38%, transparent); box-shadow: 0 2px 6px -2px rgba(0,0,0,.24); }
.cc-group-tag i { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--gc); box-shadow: 0 0 0 2px color-mix(in srgb, var(--gc) 22%, transparent); }
/* ── Рамки-контейнеры подзадач (вариант «Схема» 2, выбор владельца CLIE-293): родитель + его подзадачи
   в ОДНОМ фрейме, как frame в Figma/Miro. Слой ПОД связями и узлами; клики проходят к карточкам
   (pointer-events:none). Цвет = статус родителя (--fc). Светлая и тёмная темы — через color-mix. ── */
.cc-schema-frames { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.cc-frame { position: absolute; border-radius: 20px; box-sizing: border-box;
  background: color-mix(in srgb, var(--fc) 9%, transparent);
  border: 1.5px solid color-mix(in srgb, var(--fc) 34%, transparent);
  box-shadow: inset 0 0 44px color-mix(in srgb, var(--fc) 6%, transparent), 0 12px 36px -24px color-mix(in srgb, var(--fc) 55%, transparent);
  transition: background .16s, border-color .16s; }
.cc-frame.done { border-color: color-mix(in srgb, var(--ok) 38%, transparent); background: color-mix(in srgb, var(--ok) 7%, transparent); }
.cc-frame-tag { position: absolute; left: 16px; top: -14px; display: inline-flex; align-items: center; gap: 7px;
  height: 27px; padding: 0 12px 0 8px; border-radius: 13px; font-size: 11.5px; font-weight: 700; letter-spacing: .01em; white-space: nowrap;
  color: color-mix(in srgb, var(--fc) 55%, var(--text));
  background: color-mix(in srgb, var(--fc) 14%, var(--panel));
  border: 1px solid color-mix(in srgb, var(--fc) 34%, transparent);
  box-shadow: 0 3px 10px -4px rgba(0,0,0,.3); }   /* backdrop-blur убран (фон рамки-тега уже непрозрачный) — перф */
.cc-frame.done .cc-frame-tag { color: color-mix(in srgb, var(--ok) 62%, var(--text)); background: color-mix(in srgb, var(--ok) 14%, var(--panel)); border-color: color-mix(in srgb, var(--ok) 36%, transparent); }
.cc-frame-ring { flex: none; display: block; }
.cc-frame-ring .cfr-tr { fill: none; stroke: color-mix(in srgb, var(--fc) 20%, transparent); stroke-width: 3.4; }
.cc-frame-ring .cfr-pr { fill: none; stroke: color-mix(in srgb, var(--fc) 80%, var(--text)); stroke-width: 3.4; stroke-linecap: round; transition: stroke-dasharray .3s ease; }
.cc-frame.done .cc-frame-ring .cfr-tr { stroke: color-mix(in srgb, var(--ok) 22%, transparent); }
.cc-frame.done .cc-frame-ring .cfr-pr { stroke: var(--ok); }
.cc-frame-tx { font-variant-numeric: tabular-nums; }
/* (CLIE-448) blur ярлыка-кольца во время жеста больше НЕ гасим — вид в движении обязан совпадать с покоем. */
.cc-schema-wires { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; z-index: 1; }
.cc-schema-wires .cc-wire { pointer-events: auto; }
.cc-wire-hit { fill: none; stroke: transparent; stroke-width: 18; cursor: pointer; }
.cc-wire-line { fill: none; stroke: color-mix(in srgb, var(--text) 32%, transparent); stroke-width: 2; transition: stroke .12s; }
.cc-wire.solid  .cc-wire-line { stroke: color-mix(in srgb, var(--ok) 64%, var(--text)); }
.cc-wire.dashed .cc-wire-line { stroke: color-mix(in srgb, var(--warning) 66%, transparent); stroke-dasharray: 6 6; }
.cc-arrowhead { fill: color-mix(in srgb, var(--text) 40%, transparent); }
.cc-wire.solid  .cc-arrowhead { fill: color-mix(in srgb, var(--ok) 64%, var(--text)); }
.cc-wire.dashed .cc-arrowhead { fill: color-mix(in srgb, var(--warning) 72%, transparent); }
.cc-wire:hover .cc-wire-line { stroke: var(--primary); stroke-dasharray: none; }
.cc-wire:hover .cc-arrowhead { fill: var(--primary); }
/* связь-подзадача (parent_id): тонкий частый пунктир, без стрелки — «вложено», а не «после» */
.cc-wire.sub .cc-wire-line { stroke: color-mix(in srgb, var(--text) 26%, transparent); stroke-width: 1.6; stroke-dasharray: 2 5; }
.cc-wire.sub .cc-wire-hit { stroke-width: 16; }
/* связь «связана с» (related, симметрична): НЕнаправленная — без стрелки, нейтральный редкий пунктир;
   отличается от «после:» (сплошная/дэш со стрелкой) и подзадачи (частый пунктир) — владелец */
.cc-wire.rel .cc-wire-line { stroke: color-mix(in srgb, var(--primary) 48%, var(--muted)); stroke-width: 1.8; stroke-dasharray: 1 6; stroke-linecap: round; }
.cc-wire.rel:hover .cc-wire-line { stroke: var(--primary); stroke-dasharray: 1 6; }
/* ── узел = карточка задачи ── */
.cc-node { position: absolute; height: 118px; box-sizing: border-box; display: flex; flex-direction: column; z-index: 2;
  background: var(--panel); border: 1px solid var(--line); border-radius: 13px; padding: 10px 12px 14px 12px;
  cursor: grab; user-select: none; overflow: hidden; --sch-prio: var(--muted);
  box-shadow: 0 1px 2px rgba(0,0,0,.14), 0 8px 22px -14px rgba(0,0,0,.5);
  transition: box-shadow .13s ease, border-color .13s ease; }
/* CLIE-599 (В1): та же полоска-приоритет слева, что у карточки доски, — снята и у узла «Схемы»
   НАСОВСЕМ (у обычного приоритета она была зелёная и висела на каждом узле). Приоритет — точка у
   названия и только «срочно»/«высокий». `--sch-prio` остаётся: из него красится точка. */
.cc-node[data-prio="urgent"]:not(.done):not(.cancelled) .cc-node-title::before,
.cc-node[data-prio="high"]:not(.done):not(.cancelled) .cc-node-title::before {
  content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%;
  margin-right: 6px; vertical-align: middle; position: relative; top: -1px;
  background: var(--sch-prio); box-shadow: 0 0 0 3px color-mix(in srgb, var(--sch-prio) 16%, transparent);
}
.cc-node .cc-node-title .task-changed-dot { display: none; }   /* ровно одна точка = приоритет */
.cc-node[data-prio="urgent"] { --sch-prio: var(--urg-overdue); }
.cc-node[data-prio="high"]   { --sch-prio: var(--urg-today); }
.cc-node[data-prio="normal"] { --sch-prio: color-mix(in srgb, var(--ok) 60%, var(--line)); }
.cc-node[data-prio="low"]    { --sch-prio: var(--line-strong, var(--muted)); }
.cc-node:hover { border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); box-shadow: 0 2px 6px rgba(0,0,0,.18), 0 16px 30px -16px rgba(0,0,0,.6); z-index: 4; }
.cc-node.dragging { cursor: grabbing; z-index: 6; box-shadow: 0 12px 34px -8px rgba(0,0,0,.55); }
.cc-node.droptarget { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary), 0 16px 30px -14px rgba(0,0,0,.6); z-index: 5; }
.cc-node.done { opacity: .72; }
.cc-node.done .cc-node-title { text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--text) 40%, transparent); }
.cc-node.cancelled { opacity: .6; }
.cc-node.waiting { border-style: dashed; border-color: color-mix(in srgb, var(--warning) 46%, var(--line)); }
/* Перф на больших графах (владелец: «сильно лагает, когда много задач; еле можно уйти»): реальный
   фикс — ВИРТУАЛИЗАЦИЯ ВЬЮПОРТА в JS (в DOM только видимые узлы) + LOD (лёгкий узел при отдалении),
   см. syncViewport/schemaNodeHtml. content-visibility УБРАН намеренно: при пане он заставлял браузер
   проверять ВСЕ сотни узлов каждый кадр (местами делал хуже).
   🔴 CLIE-448: гашение теней узлов на время жеста УБРАНО — карточка в движении обязана выглядеть
   ровно так же, как в покое (владелец: «меняет дизайн на момент движения — так не нужно»). Слой
   карточек едет ОДНИМ CSS-трансформом холста, тени растрируются в тот же слой — платить за них
   заново на кадр пана не приходится. */
/* 🔴 CLIE-448: ЕДИНСТВЕННАЯ карточка «Схемы» — DOM (.cc-node). Canvas-копии карточек больше НЕТ:
   раньше на время пана/зума DOM-слой гас (opacity:0) и вместо него показывалась отрисовка тех же
   карточек на #ccSchemaGL — второй, ОТЛИЧАЮЩИЙСЯ рендер (свой шрифт, инициалы вместо фото, часть
   пилюль не рисовалась). Это и был «дизайн меняется на момент движения». Теперь холст рисует ТОЛЬКО
   то, у чего нет DOM-двойника (сетка/острова/рамки/связи/стрелки/ось времени), а карточки и стикеры
   всегда живут в DOM. 🔴 НЕ заводить второй рендер карточки — правило проекта «одна реализация». */
/* Лёгкий узел (обзор / очень много видимых): без пилюль/аватарок/портов/«⋯»/тени — дёшево на сотнях.
   Тот же размер 246×118 и цветовая метка приоритета/статуса, заголовок по центру, тонкий прогресс. */
.cc-node.lite { justify-content: flex-start; padding: 11px 13px; box-shadow: none; cursor: grab; }
.cc-node.lite .cc-node-head { padding-right: 0; }
.cc-node.lite .cc-node-title { -webkit-line-clamp: 2; line-clamp: 2; font-size: 13px; }
/* «лёгкая» карточка теперь несёт компактный подвал (статус/срок/прогресс/связи/аватары) —
   не голый заголовок. Пилюли чуть плотнее и меньше, чтобы влезали на узкой карточке обзора. */
.cc-node.lite .cc-node-foot { margin-top: 5px; gap: 4px; row-gap: 3px; }
.cc-node.lite .cc-node-foot .tw-pill { font-size: 10px; padding: 1.5px 6px; max-width: 108px; }
.cc-node.lite .tw-av { width: 17px; height: 17px; font-size: 9px; }
.cc-node.lite:hover { border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); box-shadow: 0 2px 6px rgba(0,0,0,.18), 0 16px 30px -16px rgba(0,0,0,.5); }
/* (CLIE-448) blur ярлыка-триггера при переносе узла НЕ гасим — вид в движении = вид в покое. */
/* выделенный узел (мультивыбор) — спокойное кольцо цветом акцента */
.cc-node.selected { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary), 0 12px 26px -16px rgba(0,0,0,.55); z-index: 5; }
.cc-node.selected.dragging { z-index: 6; }
/* рамка-выделения по фону (Shift/⌘ + протяжка) */
.cc-marquee { position: absolute; z-index: 8; pointer-events: none; border: 1.5px solid var(--primary); border-radius: 5px;
  background: color-mix(in srgb, var(--primary) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 20%, transparent); }
.cc-node-head { display: flex; align-items: flex-start; gap: 7px; flex: none; min-height: 0; padding-right: 18px; }
.cc-node-stat { width: 8px; height: 8px; border-radius: 50%; margin-top: 4px; flex: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--sch-stat) 22%, transparent); }
.cc-node-title { font-size: 13px; line-height: 1.29; font-weight: 600; color: var(--text); overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; }
.cc-node-foot { display: flex; flex-wrap: wrap; align-items: center; align-content: flex-start; gap: 5px; row-gap: 4px; margin-top: 6px; flex: 1; min-height: 0; overflow: hidden; }
.cc-node-foot > .tw-pill { flex: none; }
/* компактные пилюли внутри карточки «Схемы» (реюз .tw-pill доски, но плотнее — узел мал).
   Пилюли информационные: клик по карточке открывает задачу (pointer-events:none у пилюль,
   иначе .rel-пилюли выглядели бы кликабельными «в никуда» — запрет мёртвых контролов). */
.cc-node-foot .tw-pill, .cc-node-foot .cc-node-ppl { pointer-events: none; }
.cc-node-foot .tw-pill { font-size: 10.5px; padding: 2px 7px; height: auto; line-height: 1.5; gap: 3px; max-width: 122px; white-space: nowrap; overflow: hidden; }
.cc-node-foot .tw-pill .ic { width: 11px; height: 11px; }
.cc-node-foot .tw-pill[class*="status-"] { font-weight: 700; }
.cc-node-none { font-size: 11px; color: var(--muted); opacity: .7; }
/* ── n8n: иконка типа узла + подзаголовок (проект/родитель) под названием ── */
.cc-node-type { flex: none; width: 18px; height: 18px; margin-top: 1px; display: inline-flex; align-items: center; justify-content: center; color: var(--muted); opacity: .8; }
.cc-node-type .ic { width: 15px; height: 15px; }
.cc-node-type.type-ai { color: var(--primary); opacity: 1; }
.cc-node-type.type-epic { color: color-mix(in srgb, var(--ok) 80%, var(--text)); opacity: .95; }
.cc-node-type.type-sub { color: var(--muted); }
.cc-node-headtx { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.cc-node-sub { font-size: 11px; line-height: 1.3; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* есть подзаголовок → заголовок в одну строку (иначе не влезет в фикс-высоту карточки) */
.cc-node-headtx:has(.cc-node-sub) .cc-node-title { -webkit-line-clamp: 1; line-clamp: 1; }
.cc-node.lite .cc-node-headtx:has(.cc-node-sub) .cc-node-title { -webkit-line-clamp: 1; line-clamp: 1; }

/* ── n8n: СТИКЕРЫ-ЗАМЕТКИ ХОЛСТА (цветная аннотация графа; в покое редактируется/тянется/ресайзится) ── */
.cc-schema-notes { position: absolute; inset: 0; pointer-events: none; }   /* контейнер сквозной; сами стикеры кликабельны */
.cc-note { position: absolute; z-index: 1; pointer-events: auto; border-radius: 12px; background: var(--nbg); border: 1.5px solid var(--nbd);
  box-shadow: 0 1px 2px rgba(0,0,0,.08), 0 12px 28px -18px rgba(0,0,0,.45); display: flex; flex-direction: column; overflow: hidden; transition: box-shadow .14s ease; }
.cc-note:hover { box-shadow: 0 2px 6px rgba(0,0,0,.14), 0 18px 36px -18px rgba(0,0,0,.5); }
.cc-note-bar { height: 22px; flex: none; cursor: grab; display: flex; align-items: center; justify-content: flex-end; gap: 4px; padding: 0 6px; background: color-mix(in srgb, var(--nbd) 24%, transparent); }
.cc-note-bar:active { cursor: grabbing; }
.cc-note-color, .cc-note-del { width: 18px; height: 18px; border: none; border-radius: 6px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; padding: 0; transition: opacity .12s ease, background .12s ease; color: var(--ntx); }
.cc-note-del { background: transparent; opacity: 0; }
.cc-note-color { background: var(--nbd); opacity: .55; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--ntx) 30%, transparent); }
.cc-note:hover .cc-note-del { opacity: .8; }
.cc-note:hover .cc-note-color { opacity: 1; }
.cc-note-del:hover { opacity: 1; background: color-mix(in srgb, var(--nbd) 45%, transparent); }
.cc-note-del .ic { width: 13px; height: 13px; }
.cc-note-body { flex: 1; border: none; background: transparent; resize: none; outline: none; padding: 7px 12px 12px; font-family: inherit; font-size: 14px; font-weight: 500; line-height: 1.42; color: var(--ntx); }
.cc-note-body::placeholder { color: color-mix(in srgb, var(--ntx) 42%, transparent); }
.cc-note-resize { position: absolute; right: 1px; bottom: 1px; width: 15px; height: 15px; cursor: nwse-resize; opacity: 0; transition: opacity .12s ease; }
.cc-note:hover .cc-note-resize { opacity: .55; }
.cc-note-resize::after { content: ""; position: absolute; right: 3px; bottom: 3px; width: 7px; height: 7px; border-right: 2px solid var(--ntx); border-bottom: 2px solid var(--ntx); border-radius: 0 0 3px 0; }


/* ── n8n: контекстное меню (правый клик) ── */
.cc-ctx-menu { position: fixed; z-index: 10050; min-width: 214px; padding: 6px; border-radius: 12px;
  background: color-mix(in srgb, var(--panel) 97%, transparent); border: 1px solid var(--line);
  box-shadow: 0 8px 24px rgba(0,0,0,.22), 0 40px 80px -40px rgba(0,0,0,.6); backdrop-filter: blur(14px) saturate(160%); -webkit-backdrop-filter: blur(14px) saturate(160%); }
.cc-ctx-row { display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px; border: none; background: transparent; border-radius: 8px; cursor: pointer; font-size: 13.5px; color: var(--text); text-align: left; transition: background .1s ease; }
.cc-ctx-row .ic { width: 16px; height: 16px; flex: none; color: var(--muted); }
.cc-ctx-row:hover { background: color-mix(in srgb, var(--primary) 12%, transparent); }
.cc-ctx-row:hover .ic { color: var(--primary); }
/* «Опасный» пункт — класс `is-danger`, а не `danger`: голый `.danger` у кнопки в светлых
   концептах — это ЗАЛИТАЯ красная кнопка, и пункт меню «Удалить» становился плашкой. */
.cc-ctx-row.is-danger { color: var(--danger); }
.cc-ctx-row.is-danger .ic { color: var(--danger); }
.cc-ctx-row.is-danger:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }
/* Клавиатура, подменю, галочка, клавиша пункта (`ccCtxMenu`, 14.09.2026: меню письма). Мышь и
   клавиши ведут ОДНУ подсветку — фокус пункта выглядит как наведение. */
.cc-ctx-menu { color: var(--text); animation: ccCtxIn .12s ease-out; }
.cc-ctx-menu:focus { outline: none; }
@keyframes ccCtxIn { from { opacity: 0; transform: scale(.97); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .cc-ctx-menu { animation: none; } }
.cc-ctx-row:focus { outline: none; background: color-mix(in srgb, var(--primary) 12%, transparent); }
.cc-ctx-row:focus .ic, .cc-ctx-row.open .ic { color: var(--primary); }
.cc-ctx-row.is-danger:focus { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.cc-ctx-row.is-danger:focus .ic { color: var(--danger); }
.cc-ctx-row.open { background: color-mix(in srgb, var(--primary) 9%, transparent); }
.cc-ctx-row[disabled] { opacity: .45; cursor: default; }
.cc-ctx-ic { display: inline-flex; flex: none; }
.cc-ctx-ic.tint .ic, .cc-ctx-row:focus .cc-ctx-ic.tint .ic { color: inherit; }
.cc-ctx-l { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-ctx-hint { flex: none; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.cc-ctx-key { flex: none; min-width: 18px; text-align: center; font: 600 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; padding: 3px 5px; border-radius: 5px; border: 1px solid var(--line); color: var(--muted); background: transparent; }
.cc-ctx-more, .cc-ctx-chk { flex: none; display: inline-flex; }
.cc-ctx-row .cc-ctx-more .ic, .cc-ctx-row .cc-ctx-chk .ic { width: 14px; height: 14px; }
.cc-ctx-row .cc-ctx-chk .ic { color: var(--primary); }
.cc-ctx-sep { height: 1px; margin: 5px 6px; background: var(--line); }
.cc-ctx-head { padding: 6px 10px 4px; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.cc-node-ppl { margin-left: auto; display: inline-flex; flex: none; align-self: center; }
/* «⋯» быстрые действия — как на доске; показываем на hover (на тач — всегда) */
.cc-node-more { position: absolute; top: 7px; right: 7px; z-index: 3; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  background: color-mix(in srgb, var(--panel-2) 92%, transparent); color: var(--muted);
  opacity: 0; visibility: hidden; transition: opacity .12s, background .12s, color .12s; }
.cc-node-more .ic { width: 15px; height: 15px; }
.cc-node:hover .cc-node-more { opacity: 1; visibility: visible; }
.cc-node-more:hover { background: var(--panel); color: var(--text); }
@media (hover: none) { .cc-node-more { opacity: .75; visibility: visible; } }
/* ✕ «открепить от родителя» на подзадаче (замена ✕ на бывшем пунктире-подзадаче) — слева от «⋯» */
.cc-node-unsub { position: absolute; top: 7px; right: 33px; z-index: 3; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  background: color-mix(in srgb, var(--panel-2) 92%, transparent); color: var(--muted);
  opacity: 0; visibility: hidden; transition: opacity .12s, background .12s, color .12s; }
.cc-node-unsub .ic { width: 13px; height: 13px; }
.cc-node:hover .cc-node-unsub { opacity: 1; visibility: visible; }
.cc-node-unsub:hover { background: color-mix(in srgb, var(--warning) 16%, var(--panel)); color: var(--warning); }
@media (hover: none) { .cc-node-unsub { opacity: .7; visibility: visible; } }
/* ── порты (in=слева/предыдущая, out=справа/следующая, down=снизу/ветка-вниз·подзадача) ──
   ⊕: клик — создать в эту сторону, потяни на другую задачу — связать (n8n-паттерн) */
.cc-node-port { position: absolute; width: 15px; height: 15px; border-radius: 50%; z-index: 6;
  display: flex; align-items: center; justify-content: center; cursor: crosshair;
  background: var(--panel); border: 1.5px solid color-mix(in srgb, var(--text) 30%, transparent);
  box-shadow: 0 1px 2px rgba(0,0,0,.16); opacity: .5;
  transition: border-color .12s, background .12s, transform .12s, opacity .12s; }
.cc-node-port.in   { left: -7.5px;   top: 50%; transform: translateY(-50%); }
.cc-node-port.out  { right: -7.5px;  top: 50%; transform: translateY(-50%); }
.cc-node-port.down { bottom: -7.5px; left: 50%; transform: translateX(-50%); }
.cc-node:hover .cc-node-port { opacity: 1; border-color: color-mix(in srgb, var(--primary) 60%, var(--line)); }
.cc-node-port:hover { background: var(--primary); border-color: var(--primary); }
.cc-node-port.in:hover, .cc-node-port.out:hover { transform: translateY(-50%) scale(1.3); }
.cc-node-port.down:hover { transform: translateX(-50%) scale(1.3); }
.cc-node-port .ccp-ic { display: inline-flex; pointer-events: none; opacity: .92; transition: opacity .12s; }
.cc-node-port .ccp-ic .ic { width: 9px; height: 9px; color: var(--primary); transition: color .12s; }
.cc-node-port:hover .ccp-ic .ic { color: #fff; }
@media (hover: none) { .cc-node-port { opacity: .72; } }
.cc-wire-temp { fill: none; stroke: var(--primary); stroke-width: 2.4; stroke-dasharray: 5 4; pointer-events: none; }
/* тонкая линия прогресса (готовность подзадач/чек-листа) по нижней кромке карточки */
.cc-node-prog { position: absolute; left: 12px; right: 12px; bottom: 5px; height: 2.5px; border-radius: 999px;
  background: color-mix(in srgb, var(--line) 70%, transparent); overflow: hidden; pointer-events: none; }
.cc-node-prog i { display: block; height: 100%; border-radius: 999px; background: color-mix(in srgb, var(--ok) 82%, var(--primary)); transition: width .25s ease; }
.cc-node.done .cc-node-prog i { background: var(--ok); }
/* ── композер «⊕ создать следующую/подзадачу» (fixed-попап у порта) ── */
.cc-qadd { position: fixed; z-index: 4000; width: 264px; box-sizing: border-box; padding: 10px;
  border-radius: 14px; background: var(--panel); border: 1px solid var(--line);
  box-shadow: 0 12px 38px -12px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.16); display: flex; flex-direction: column; gap: 8px; }
.cc-qadd-seg { display: grid; grid-template-columns: 1fr 1fr; gap: 4px; padding: 3px; border-radius: 10px; background: color-mix(in srgb, var(--line) 42%, transparent); }
.cc-qadd-t { display: inline-flex; align-items: center; justify-content: center; gap: 5px; height: 30px; border: 0; border-radius: 8px;
  background: transparent; color: var(--muted); font-size: 12.5px; font-weight: 600; cursor: pointer; transition: background .12s, color .12s, box-shadow .12s; }
.cc-qadd-t .cc-qadd-gl { font-size: 14px; line-height: 1; opacity: .85; }
.cc-qadd-t:hover { color: var(--text); }
.cc-qadd-t.on { background: var(--panel-2); color: var(--text); box-shadow: 0 1px 3px rgba(0,0,0,.18); }
.cc-qadd-row { display: flex; align-items: center; gap: 6px; }
.cc-qadd-input { flex: 1 1 auto; min-width: 0; height: 34px; padding: 0 10px; box-sizing: border-box; border-radius: 9px; border: 1px solid var(--line);
  background: var(--bg); color: var(--text); font-size: 13px; outline: none; transition: border-color .12s, box-shadow .12s; }
.cc-qadd-input::placeholder { color: var(--muted); }
.cc-qadd-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent); }
.cc-qadd-go { flex: none; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; padding: 0;
  border: 0; border-radius: 9px; background: var(--acc-fill); color: #fff; cursor: pointer; transition: filter .1s, transform .06s; }
.cc-qadd-go:hover { filter: brightness(1.07); }
.cc-qadd-go:active { transform: scale(.93); }
.cc-qadd-go .ic { width: 16px; height: 16px; }
.cc-qadd-hint { font-size: 11px; line-height: 1.4; color: var(--muted); }
.cc-qadd-hint b { color: var(--text); font-weight: 600; }
/* кнопка «Статусы» (фильтр видимости) — активна, когда что-то скрыто + бейдж со счётчиком скрытых */
.cc-sch-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; margin-left: 1px; padding: 0 4px;
  border-radius: 8px; background: var(--acc-fill); color: #fff; font-size: 10px; font-weight: 800; font-variant-numeric: tabular-nums; }
/* поповер фильтра статусов «Схемы» (чек-лист К выполнению · В работе · Готово · Отменено) */
.cc-sch-pop { position: fixed; z-index: 4000; width: 218px; padding: 6px; border-radius: 13px; background: var(--panel); border: 1px solid var(--line);
  box-shadow: 0 12px 38px -12px rgba(0,0,0,.55), 0 2px 8px rgba(0,0,0,.16); animation: ccSchPop .12s ease; }
@keyframes ccSchPop { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.cc-sch-pop-hd { padding: 6px 10px 7px; font-size: 11px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; color: var(--muted); }
.cc-sch-pop-row { display: flex; align-items: center; gap: 10px; width: 100%; margin: 0; padding: 8px 10px; border: 0; border-radius: 9px;
  background: transparent; color: var(--text); font-size: 13px; font-weight: 500; text-align: left; cursor: pointer; transition: background .1s; }
.cc-sch-pop-row:hover { background: var(--panel-2); }
.cc-sch-pop-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; }
.cc-sch-pop-nm { flex: 1; }
.cc-sch-pop-ck { flex: none; width: 18px; height: 18px; border-radius: 6px; border: 1.5px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center; color: #fff; transition: background .1s, border-color .1s; }
.cc-sch-pop-row.on .cc-sch-pop-ck { background: var(--primary); border-color: var(--primary); }
.cc-sch-pop-ck .ic { width: 12px; height: 12px; opacity: 0; }
.cc-sch-pop-row.on .cc-sch-pop-ck .ic { opacity: 1; }
/* ── Шкала времени (CLIE-311): переключатель масштаба, липкая ось, чип даты, флажок-финиш ── */
.cc-sch-units { display: inline-flex; align-items: center; gap: 2px; padding: 2px; border-radius: 9px; background: var(--panel-2); }
.cc-sch-units.off { display: none; }
.cc-sch-unit { flex: none; height: 26px; padding: 0 9px; margin: 0; border: 0; background: transparent; color: var(--muted); border-radius: 7px;
  font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; transition: background .13s, color .13s; }
.cc-sch-unit:hover { color: var(--text); }
.cc-sch-unit.on { color: var(--text); background: var(--panel); box-shadow: 0 1px 2px rgba(0,0,0,.14); }
/* Ось-линейка живёт ТОЛЬКО в режиме шкалы (иначе [hidden]); опущена ПОД плавающий тулбар-таблетку
   (.cc-schema-tools: top:14 + высота ~44 → низ ~58), чтобы панель действий её не перекрывала
   (владелец CLIE-311: «ось перекрывается окном с действиями — опустить ниже, если шкала включена»). */
.cc-schema-axis { position: absolute; top: 62px; left: 0; right: 0; height: 30px; z-index: 8; pointer-events: none; overflow: hidden;
  background: color-mix(in srgb, var(--panel) 82%, transparent); backdrop-filter: blur(9px) saturate(1.3); -webkit-backdrop-filter: blur(9px) saturate(1.3);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.cc-schema-axis[hidden] { display: none; }
/* (CLIE-448) blur оси времени в движении НЕ гасим — вид в движении обязан совпадать с покоем. */
.cc-axis-tick { position: absolute; top: 0; height: 30px; display: flex; align-items: center; }
.cc-axis-tick::before { content: ""; position: absolute; left: 0; top: 17px; bottom: 0; width: 1px; background: var(--line); }
.cc-axis-tick > span { font-size: 11px; font-weight: 600; color: var(--muted); padding-left: 6px; letter-spacing: .01em; white-space: nowrap; }
.cc-axis-now { position: absolute; top: 0; height: 30px; display: flex; align-items: center; transform: translateX(-50%); }
.cc-axis-now > span { font-size: 10px; font-weight: 700; color: #fff; background: var(--acc-fill); padding: 2px 7px; border-radius: 7px; white-space: nowrap; box-shadow: 0 1px 4px rgba(0,0,0,.22); }
/* Грип на границе колонки шкалы времени: тянуть → менять «сколько задач в ряд» (ширина столбца). Хит-зона
   шире линии, тонкая ручка проявляется на hover/во время протяжки; курсор ↔. Живёт в pointer-events:none оси. */
.cc-axis-grip { position: absolute; top: 0; height: 30px; width: 16px; margin-left: -8px; z-index: 9;
  pointer-events: auto; cursor: col-resize; display: flex; align-items: flex-start; justify-content: center; }
.cc-axis-grip > i { display: block; width: 2px; height: 22px; margin-top: 4px; border-radius: 2px;
  background: var(--line); opacity: 0; transition: opacity .12s ease, background .12s ease; }
.cc-axis-grip:hover > i, .cc-schema-vp.col-resizing ~ .cc-schema-axis .cc-axis-grip > i { opacity: 1; background: var(--primary); }
body.cc-col-resizing, body.cc-col-resizing * { cursor: col-resize !important; user-select: none !important; }
/* HUD «↔ N задач в ряд» во время протяжки ширины — под опущенной осью-линейкой (top:62 + h:30 = 92) */
.cc-col-badge { position: absolute; top: 100px; left: 50%; transform: translateX(-50%); z-index: 12; pointer-events: none;
  padding: 6px 13px; border-radius: 999px; font: 600 12.5px/1 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  color: #fff; background: var(--cm-14161c-9, rgba(20,22,28,.9)); box-shadow: 0 8px 24px rgba(0,0,0,.32);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); letter-spacing: .01em; white-space: nowrap; }
.cc-node .tw-pill-created { color: var(--muted); background: color-mix(in srgb, var(--muted) 12%, transparent); }
.cc-node-finish { position: absolute; top: 7px; right: 33px; z-index: 3; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  background: color-mix(in srgb, var(--panel-2) 92%, transparent); color: var(--muted);
  opacity: 0; visibility: hidden; transition: opacity .12s, background .12s, color .12s; }
.cc-node-unsub + .cc-node-finish { right: 59px; }
.cc-node-finish .ic { width: 13px; height: 13px; }
.cc-node:hover .cc-node-finish, .cc-node-finish.on { opacity: 1; visibility: visible; }
.cc-node-finish:hover { background: var(--panel); color: var(--text); }
.cc-node-finish.on { color: #fff; background: var(--acc-fill); }
@media (hover: none) { .cc-node-finish { opacity: .75; visibility: visible; } }
/* ── легенда + подсказка ── */
.cc-schema-legend { position: absolute; left: 14px; bottom: 12px; z-index: 10; display: flex; flex-wrap: wrap; gap: 12px;
  padding: 8px 12px; border-radius: 11px; border: 1px solid var(--line); font-size: 12px; color: var(--muted);
  background: color-mix(in srgb, var(--panel) 80%, transparent); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); }
.cc-schema-legend .lg { display: inline-flex; align-items: center; gap: 6px; }
.cc-schema-legend .dot { width: 9px; height: 9px; border-radius: 50%; }
.cc-schema-legend .wire { width: 20px; height: 0; border-top: 2px solid color-mix(in srgb, var(--text) 40%, transparent); }
.cc-schema-legend .wire.solid  { border-color: color-mix(in srgb, var(--ok) 64%, var(--text)); }
.cc-schema-legend .wire.dashed { border-top-style: dashed; border-color: color-mix(in srgb, var(--warning) 66%, transparent); }
.cc-schema-legend .wire.sub { border-top-style: dotted; border-color: color-mix(in srgb, var(--text) 34%, transparent); }
.cc-schema-legend .wire.rel { border-top-style: dotted; border-top-width: 2px; border-color: color-mix(in srgb, var(--primary) 55%, var(--muted)); }
.cc-schema-legend .frame { width: 18px; height: 13px; border-radius: 5px; border: 1.5px solid color-mix(in srgb, var(--text) 34%, transparent); background: color-mix(in srgb, var(--text) 8%, transparent); }
.cc-schema-hint { position: absolute; right: 14px; bottom: 16px; z-index: 10; font-size: 12px; color: var(--muted); opacity: .78; pointer-events: none; max-width: 42%; text-align: right; }
.cc-schema-hint b { color: var(--text); font-weight: 600; opacity: .9; }
html[data-theme="light"] .cc-schema-hint { opacity: 1; } /* CLIE-1946: .78 на светлом = 3.7:1 */
@media (max-width: 760px) { .cc-schema-hint { display: none; } .cc-sch-btn.wide span { display: none; } .cc-sch-btn.wide { padding: 0 8px; } }
/* ── ярлык статуса-триггера на связи «после: <статус>» (CLIE-201) ── */
.cc-schema-labels { position: absolute; inset: 0; pointer-events: none; z-index: 3; }
/* Пилюля связи = ДВЕ части в одной оболочке: слева «после: <статус>» (клик = сменить условие),
   справа «×» (удалить связь). Разделены хэйрлайном и не перекрываются → «×» ВСЕГДА кликается
   (раньше «×» рисовался в SVG ровно под пилюлей — был спрятан, связь нельзя было удалить). */
.cc-wire-trig { position: absolute; transform: translate(-50%, -50%); pointer-events: auto;
  display: inline-flex; align-items: stretch; max-width: 232px; overflow: hidden;
  border-radius: 999px; border: 1px solid var(--line); background: var(--panel);
  color: var(--text); font-size: 11px; font-weight: 600; line-height: 1.35; white-space: nowrap;
  box-shadow: 0 1px 3px rgba(0,0,0,.14);   /* backdrop-blur УБРАН: по одному blur-слою на КАЖДУЮ связь = захлёб компоновщика; чистая непрозрачная пилюля (Apple-grade) — почти 0 GPU */
  transition: border-color .12s, background .12s, box-shadow .12s; }
.cc-wire-trig:hover { border-color: color-mix(in srgb, var(--primary) 42%, var(--line)); box-shadow: 0 3px 11px -2px rgba(0,0,0,.3); }
.cc-wire-trig .ccwt-main { display: inline-flex; align-items: center; gap: 5px; max-width: 182px;
  padding: 3px 8px; border: 0; background: transparent; color: inherit; font: inherit; cursor: pointer; }
.cc-wire-trig .ic { flex: none; width: 12px; height: 12px; color: var(--muted); transition: color .12s; }
.cc-wire-trig .ccwt-tx { overflow: hidden; text-overflow: ellipsis; }
.cc-wire-trig.def .ccwt-main { color: var(--muted); }
.cc-wire-trig .ccwt-main:hover { color: var(--text); }
.cc-wire-trig .ccwt-main:hover .ic { color: var(--primary); }
.cc-wire-trig .ccwt-del { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 25px; align-self: stretch; padding: 0; border: 0; border-left: 1px solid var(--line);
  background: transparent; color: var(--muted); cursor: pointer; transition: background .12s, color .12s; }
.cc-wire-trig .ccwt-del .ic { width: 12px; height: 12px; }
.cc-wire-trig .ccwt-del:hover { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
/* «＋» на связи (inline-insert как в n8n): скрыт, раскрывается по наведению на пилюлю (в пределах overflow — не вылезает) */
.cc-wire-trig .ccwt-ins { flex: none; width: 0; align-self: stretch; padding: 0; border: 0; overflow: hidden;
  display: inline-flex; align-items: center; justify-content: center; background: transparent; color: var(--primary);
  cursor: pointer; transition: width .14s ease, background .12s; }
.cc-wire-trig:hover .ccwt-ins { width: 24px; border-right: 1px solid var(--line); }
.cc-wire-trig .ccwt-ins:hover { background: color-mix(in srgb, var(--primary) 16%, transparent); }
.cc-wire-trig .ccwt-ins .ic { width: 13px; height: 13px; }
.cc-wire-trig.sub { background: color-mix(in srgb, var(--panel) 82%, transparent); }
.cc-wire-trig .ccwt-sublabel { display: inline-flex; align-items: center; padding: 3px 9px; font-size: 10.5px; color: var(--muted); cursor: default; }
.cc-wire-trig.rel .ccwt-sublabel { color: color-mix(in srgb, var(--primary) 62%, var(--muted)); font-weight: 700; }
.cc-schema-legend .lg .trig { display: inline-flex; }
.cc-schema-legend .lg .trig .ic { width: 13px; height: 13px; color: var(--muted); }
@media (max-width: 760px) { .cc-wire-trig { max-width: 128px; font-size: 10.5px; } }
/* ── модалка выбора статуса-триггера при связывании (реюз .modal-overlay/.modal-box) ── */
.cc-trig-box { width: min(384px, 94vw); max-height: 82vh; padding: 0; display: flex; flex-direction: column; overflow: hidden; }
.cc-trig-head { display: flex; align-items: center; gap: 10px; padding: 15px 12px 11px 18px; border-bottom: 1px solid var(--line); }
.cc-trig-head h3 { margin: 0; flex: 1; font-size: 15.5px; font-weight: 700; color: var(--text); letter-spacing: -.01em; }
.cc-trig-close { flex: none; width: 30px; height: 30px; padding: 0; border: 0; border-radius: 8px; background: transparent; color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: background .12s, color .12s; }
.cc-trig-close .ic { width: 17px; height: 17px; }
.cc-trig-close:hover { background: var(--panel-2); color: var(--text); }
.cc-trig-hint { padding: 12px 18px 4px; font-size: 12.5px; line-height: 1.44; color: var(--muted); }
.cc-trig-hint b { color: var(--text); font-weight: 600; }
.cc-trig-list { padding: 6px 8px 10px; overflow-y: auto; }
.cc-trig-row { display: flex; align-items: center; gap: 10px; width: 100%; margin: 0; padding: 9px 10px; border: 0; border-radius: 10px;
  background: transparent; color: var(--text); font-size: 13.5px; font-weight: 500; text-align: left; cursor: pointer; transition: background .1s; }
.cc-trig-row:hover { background: var(--panel-2); }
.cc-trig-row.on { background: color-mix(in srgb, var(--primary) 13%, transparent); }
.cc-trig-nm { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-trig-nm i { font-style: normal; color: var(--muted); font-size: 12px; }
.cc-trig-row > .ic { flex: none; width: 16px; height: 16px; color: var(--primary); }
.cc-trig-def { border-bottom: 1px solid var(--line); border-radius: 10px 10px 0 0; margin-bottom: 3px; padding-bottom: 11px; }
.cc-trig-load { padding: 12px 10px; font-size: 12.5px; color: var(--muted); }

/* ═══════════════ Встроенный переводчик чата (CLIE-203) ═══════════════════════ *
 * Реюз токенов темы (светлая/тёмная сами подхватываются) и языка дизайна .lt-*.  */
@keyframes trIn { from { opacity: 0; transform: translateY(4px) scale(.985); } to { opacity: 1; transform: none; } }

/* Кнопка-глобус в ШАПКЕ чата — активна (accent), когда в этом чате включён любой перевод */
.tr-head-btn.on { color: var(--primary); }
.tr-head-btn.on:hover { color: var(--primary-hi); }

/* Предпросмотр перевода МОЕГО сообщения — редактируемая панель над композером */
.tr-outbar { margin: 0 18px 6px; padding: 9px 12px 10px; background: color-mix(in srgb, var(--panel-2) 92%, transparent); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-1); animation: trIn .16s cubic-bezier(.2,.8,.3,1); }
.tr-outbar.hidden { display: none; }
.tr-outbar-head { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
.tr-outbar-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; color: var(--primary); }
.tr-outbar-badge svg { width: 14px; height: 14px; }
.tr-outbar-hint { font-size: 11.5px; color: var(--muted); }
.tr-outbar-hint.act { color: var(--primary); cursor: pointer; display: inline-flex; align-items: center; gap: 4px; font-weight: 600; }
.tr-outbar-hint.act svg { width: 13px; height: 13px; }
.tr-outbar-hint.act:hover { color: var(--primary-hi); }
.tr-outbar-off { margin-left: auto; background: transparent; border: none; color: var(--muted); cursor: pointer; padding: 3px; border-radius: 7px; display: inline-flex; transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease); }
.tr-outbar-off:hover { background: var(--hover); color: var(--text); }
.tr-outbar-off svg { width: 15px; height: 15px; }
.tr-outbar-text { width: 100%; box-sizing: border-box; resize: none; border: none; outline: none; background: transparent; color: var(--text); font: inherit; font-size: 14.5px; line-height: 1.46; min-height: 22px; max-height: 132px; padding: 0; }
.tr-outbar-text::placeholder { color: var(--muted); }
.tr-outbar.loading .tr-outbar-text { opacity: .5; }
/* Фокус-кольцо ложится на КОНТУР панели (Apple-grade), а не «висит» вокруг прозрачной
   textarea внутри — глобальный textarea:focus glow на самой textarea гасим. */
.tr-outbar:focus-within { border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); box-shadow: 0 0 0 3px var(--glow), var(--shadow-1); }
.tr-outbar-text:focus { box-shadow: none; }
/* Исходник сменился после ручной правки перевода — тонкая подсветка «перевод устарел». */
.tr-outbar.stale { border-color: color-mix(in srgb, var(--primary) 34%, var(--line)); }

/* Пилюля перевода под чужим (авто) / оригинала под своим сообщением — Apple-grade, реалтайм */
.tr-under { display: inline-flex; align-items: flex-start; gap: 7px; max-width: 100%; box-sizing: border-box; margin: 4px 2px 0; padding: 6px 8px 6px 10px; font-size: 13.5px; line-height: 1.44; border-radius: 13px; background: color-mix(in srgb, var(--primary) 9%, var(--panel-2)); border: 1px solid color-mix(in srgb, var(--primary) 20%, var(--line)); color: color-mix(in srgb, var(--primary) 24%, var(--text)); animation: trIn .16s cubic-bezier(.2,.8,.3,1); }
.tr-under-ico { flex: none; display: inline-flex; margin-top: 1px; color: var(--primary); opacity: .9; }
.tr-under-ico svg { width: 13px; height: 13px; }
.tr-under-tx { min-width: 0; white-space: pre-wrap; word-break: break-word; }
.tr-under.loading { color: var(--muted); font-style: italic; background: var(--panel-2); border-color: var(--line); }
.tr-under.loading .tr-under-ico { color: var(--muted); }
.tr-under.err { color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, var(--panel-2)); border-color: color-mix(in srgb, var(--danger) 22%, var(--line)); cursor: pointer; }
.tr-under.err .tr-under-ico { color: var(--danger); }
.tr-under-lbl { flex: none; margin-top: 2px; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; color: var(--muted); }
.tr-under-x { flex: none; align-self: center; margin: 0 -2px 0 1px; padding: 2px; background: transparent; border: none; color: var(--muted); cursor: pointer; line-height: 0; border-radius: 6px; display: inline-flex; transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease); }
.tr-under-x svg { width: 13px; height: 13px; }
.tr-under-x:hover { color: var(--text); background: var(--hover); }

/* Мелкая кнопка «Показать оригинал» под своим переведённым сообщением */
.tr-under-btn { margin: 3px 4px 0; padding: 3px 10px; font-size: 12px; display: inline-flex; align-items: center; gap: 5px; cursor: pointer; background: transparent; border: 1px solid var(--line); border-radius: 999px; color: var(--muted); transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease), border-color var(--dur-1) var(--ease); }
.tr-under-btn:hover { background: var(--hover); color: var(--text); border-color: var(--line-strong); }
.tr-under-btn svg { width: 13px; height: 13px; }

/* iOS-тумблеры, секции и вторичные строки в поповере переводчика (auto-first) */
.tr-sec { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); padding: 2px 2px 0; }
.tr-line { display: flex; align-items: center; gap: 10px; padding: 8px 2px; }
.tr-line-tx { flex: 1; font-size: 13.5px; color: var(--text); }
.tr-sw { flex: none; position: relative; width: 38px; height: 23px; padding: 0; border: none; border-radius: 999px; background: var(--line-strong); cursor: pointer; transition: background .18s var(--ease); }
.tr-sw.on { background: var(--primary); }
.tr-sw-knob { position: absolute; top: 2px; left: 2px; width: 19px; height: 19px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2.5px rgba(0,0,0,.35); transition: transform .18s var(--ease); }
.tr-sw.on .tr-sw-knob { transform: translateX(15px); }
.tr-sub { width: 100%; display: flex; align-items: center; gap: 8px; margin: 0 0 2px; padding: 6px 2px; background: transparent; border: none; border-radius: 8px; color: var(--muted); font-size: 12.5px; text-align: left; cursor: pointer; transition: color var(--dur-1) var(--ease); }
.tr-sub:hover { color: var(--text); }
.tr-sub-tx { flex: 1; }
.tr-sub-tx b { color: var(--text); font-weight: 600; }
.tr-sub-auto { margin-left: 6px; padding: 1px 6px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px; color: var(--primary); background: color-mix(in srgb, var(--primary) 14%, transparent); border-radius: 999px; }
.tr-sub-chev { flex: none; display: inline-flex; color: var(--muted); opacity: .7; }
.tr-sub-chev svg { width: 15px; height: 15px; }
.tr-sep { height: 1px; background: var(--line); margin: 8px 0; }

/* Поповер переводчика (открывает кнопка-глобус в шапке) */
.tr-menu { position: fixed; z-index: 10060; width: 290px; padding: 12px 12px 11px; background: var(--panel-3); border: 1px solid var(--line); border-radius: 16px; box-shadow: var(--shadow-3); animation: trIn .15s cubic-bezier(.2,.8,.3,1); }
.tr-menu.hidden { display: none; }
.tr-menu-title { display: flex; align-items: center; gap: 7px; font-size: 14px; font-weight: 650; color: var(--text); margin-bottom: 11px; }
.tr-menu-title svg { width: 16px; height: 16px; color: var(--primary); }
.tr-row { margin-bottom: 11px; }
.tr-row:last-of-type { margin-bottom: 0; }
.tr-row-label { font-size: 12px; color: var(--muted); margin-bottom: 5px; }
.tr-pill { width: 100%; display: flex; align-items: center; gap: 8px; padding: 8px 11px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; color: var(--text); font-size: 13.5px; cursor: pointer; text-align: left; transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease); }
.tr-pill:hover { border-color: var(--line-strong); }
.tr-pill.on { border-color: color-mix(in srgb, var(--primary) 52%, var(--line)); background: color-mix(in srgb, var(--primary) 10%, var(--panel-2)); }
.tr-pill-val { font-weight: 600; }
.tr-pill.on .tr-pill-val { color: var(--primary); }
.tr-pill-chev { margin-left: auto; display: inline-flex; color: var(--muted); }
.tr-pill-chev svg { width: 15px; height: 15px; }
.tr-menu-note { font-size: 11px; color: var(--muted); margin-top: 11px; opacity: .85; line-height: 1.4; }

/* ✨ СТРОКА РЕЖИМОВ «УЛУЧШИТЬ» (CLIE-1847·Н5, S8.29) — сосед полосы перевода над полем: та же
   рамка, тот же отступ. Чипы режимов — общий `.cc-seg.cc-seg-sm`; «Вернуть как было» — текст
   с иконкой, ✕ — «оставить как есть». Пока ИИ думает — `.busy`: чипы заблокированы, бегунок в чипе. */
.cc-polbar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; margin: 0 18px 6px; padding: 8px 10px 8px 12px; background: color-mix(in srgb, var(--panel-2) 92%, transparent); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-1); animation: trIn .16s cubic-bezier(.2,.8,.3,1); }
.cc-polbar.hidden { display: none; }
.cc-polbar-ic { display: inline-flex; color: var(--primary); }
.cc-polbar-ic svg { width: 16px; height: 16px; }
.cc-polbar-seg { flex: 1 1 auto; min-width: 0; }
.cc-polbar-t { font-size: 12.5px; font-weight: 600; color: var(--primary); }
.cc-polbar-acts { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }
.cc-polbar-undo { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 10px; border: 0; border-radius: 10px; background: transparent; color: var(--text); font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.cc-polbar-undo:hover { background: var(--hover); }
.cc-polbar-undo svg { width: 15px; height: 15px; }
.cc-polbar-x { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: 0; border-radius: 10px; background: transparent; color: var(--muted); cursor: pointer; }
.cc-polbar-x:hover { background: var(--hover); color: var(--text); }
.cc-polbar-x svg { width: 15px; height: 15px; }
.cc-polbar.busy .cc-seg button { cursor: progress; }
.cc-polbar .cc-spin { width: 12px; height: 12px; margin-right: 5px; }
.cc-polbar button:disabled { opacity: .55; cursor: default; }

/* ✨ КОПИЛОТ ОНЛАЙН-ЧАТА (CLIE-1847·Н5, S5.17 · S8.28) — полоса над полем ввода беседы с
   посетителем сайта. Три состояния: покой (кнопка-строка «Черновик ответа · на «вопрос»»),
   ход (`.busy`, «Ая думает…» с бегунком), черновик (`.has-draft`: заголовок · текст с внутренним
   скроллом · источники · «Вставить» / «Заново»). Близнец приложения — `webchat_copilot_bar.dart`. */
.wc-cop { margin: 0 18px 6px; padding: 6px 8px 6px 10px; background: color-mix(in srgb, var(--panel-2) 92%, transparent); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-1); animation: trIn .16s cubic-bezier(.2,.8,.3,1); display: flex; align-items: center; gap: 6px; }
.wc-cop.hidden { display: none; }
.wc-cop.has-draft { display: block; padding: 10px 12px 10px; }
.wc-cop-ask { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 10px; min-height: 36px; padding: 4px 8px; border: 0; border-radius: 10px; background: transparent; color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.wc-cop-ask:hover { background: var(--hover); }
.wc-cop-ask:disabled { cursor: progress; }
.wc-cop-ic { display: inline-flex; flex: 0 0 auto; color: var(--primary); }
.wc-cop-ic svg { width: 16px; height: 16px; }
.wc-cop-ic .cc-spin { width: 14px; height: 14px; }
.wc-cop-tx { display: flex; align-items: baseline; gap: 6px; min-width: 0; flex: 1 1 auto; font-size: 13px; line-height: 1.3; }
.wc-cop-tx b { font-weight: 650; color: var(--text); white-space: nowrap; }
.wc-cop-q, .wc-cop-sub { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.wc-cop-x { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 32px; height: 32px; border: 0; border-radius: 10px; background: transparent; color: var(--muted); cursor: pointer; }
.wc-cop-x:hover { background: var(--hover); color: var(--text); }
.wc-cop-x svg { width: 15px; height: 15px; }
.wc-cop-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }
.wc-cop-head .wc-cop-tx { flex: 1 1 auto; }
.wc-cop-body { max-height: 164px; overflow: auto; padding: 2px 2px 2px 0; font-size: 14px; line-height: 1.45; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.wc-cop-srcs { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.wc-cop-src { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; min-height: 28px; padding: 0 10px; border: 1px solid var(--line); border-radius: 999px; background: var(--input-bg); color: var(--text); font-size: 12px; text-decoration: none; }
.wc-cop-src span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wc-cop-src svg { width: 13px; height: 13px; color: var(--primary); flex: 0 0 auto; }
a.wc-cop-src:hover { border-color: var(--primary); }
.wc-cop-src.is-note { color: var(--muted); }
.wc-cop-src.is-note svg { color: var(--muted); }
.wc-cop-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.wc-cop-acts button { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; }
.wc-cop-acts button svg { width: 15px; height: 15px; }

/* 📥 РАБОЧЕЕ МЕСТО ОПЕРАТОРА (CLIE-1847·Н2) — две полосы над полем ввода беседы с посетителем:
   «Посетитель печатает» с хвостом набора (S2.5; бокс справа-налево, текст изолирован — виден
   КОНЕЦ набора) и подсказки (S5.9 · S5.14): шаблоны события с клавишей и «Вы отвечали» —
   прошлые ответы, похожие на набранное. Близнецы приложения — webchat_composer.dart. */
.wc-peek { margin: 0 18px 6px; padding: 7px 12px; display: flex; align-items: center; gap: 8px; min-width: 0; border: 1px dashed color-mix(in srgb, var(--primary) 40%, var(--line)); border-radius: 12px; background: color-mix(in srgb, var(--primary) 6%, var(--panel-2)); font-size: 13px; line-height: 1.35; animation: trIn .16s cubic-bezier(.2,.8,.3,1); }
.wc-peek.hidden { display: none; }
.wc-peek-ic { display: inline-flex; flex: 0 0 auto; color: var(--primary); }
.wc-peek-ic svg { width: 14px; height: 14px; }
.wc-peek-l { flex: 0 0 auto; font-weight: 600; color: var(--primary); white-space: nowrap; }
.wc-peek-t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left; color: var(--text); }
.wc-sug { margin: 0 18px 6px; padding: 5px 4px 5px 8px; display: flex; align-items: center; gap: 4px; background: color-mix(in srgb, var(--panel-2) 92%, transparent); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-1); animation: trIn .16s cubic-bezier(.2,.8,.3,1); }
.wc-sug.hidden { display: none; }
.wc-sug-row { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 6px; overflow-x: auto; scrollbar-width: none; padding: 1px 0; }
.wc-sug-row::-webkit-scrollbar { display: none; }
.wc-sug-lbl { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; padding: 0 2px 0 2px; font-size: 12px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.wc-sug-lbl ~ .wc-sug-lbl { margin-left: 4px; padding-left: 10px; border-left: 1px solid var(--line); }
.wc-sug-lbl svg { width: 13px; height: 13px; color: var(--primary); }
.wc-sug-chip { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px; max-width: 260px; height: 30px; padding: 0 11px; border: 1px solid var(--line); border-radius: 999px; background: var(--input-bg); color: var(--text); font: inherit; font-size: 13px; cursor: pointer; transition: background .13s ease, border-color .13s ease; }
.wc-sug-chip:hover { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 8%, var(--input-bg)); }
.wc-sug-tx { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wc-sug-n { flex: 0 0 auto; padding: 1px 6px; border-radius: 6px; background: var(--panel-3); color: var(--muted); font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums; }
.wc-sug-x { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 30px; height: 30px; border: 0; border-radius: 10px; background: transparent; color: var(--muted); cursor: pointer; }
.wc-sug-x:hover { background: var(--hover); color: var(--text); }
.wc-sug-x svg { width: 14px; height: 14px; }

/* 🧪 ПРОВЕРКА БОТА (CLIE-1847·Н5, S8.33) — секция вкладки «Знания» карточки бота: главная
   кнопка · раскрытие «Свои вопросы» · строка идущего прогона с «Остановить» · прошлые прогоны;
   выбранный прогон раскрывается на месте (вопрос → ответ, исход, время, источники). */
.aib-test { display: flex; flex-direction: column; gap: 10px; }
.aib-test-main { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.aib-test-main button { display: inline-flex; align-items: center; gap: 7px; }
.aib-test-main button svg { width: 15px; height: 15px; }
.aib-test-qtg { display: inline-flex; align-items: center; gap: 6px; min-height: 36px; padding: 0 10px; border: 0; border-radius: 10px; background: transparent; color: var(--text); font: inherit; font-size: 13px; cursor: pointer; }
.aib-test-qtg:hover { background: var(--hover); }
.aib-test-qtg svg { width: 14px; height: 14px; color: var(--muted); transition: transform .15s; }
.aib-test-qtg.on svg { transform: rotate(180deg); }
.aib-test-q { display: flex; flex-direction: column; gap: 8px; }
.aib-test-q textarea { width: 100%; min-height: 96px; resize: vertical; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--input-bg); color: var(--text); font: inherit; font-size: 13.5px; line-height: 1.45; }
.aib-test-q textarea:focus { outline: none; border-color: var(--primary); }
.aib-test-qa { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.aib-test-run { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid color-mix(in srgb, var(--primary) 45%, var(--line)); border-radius: 12px; background: color-mix(in srgb, var(--primary) 8%, var(--input-bg)); }
.aib-test-run .cc-spin { width: 14px; height: 14px; flex: 0 0 auto; }
.aib-test-run-t { flex: 1 1 auto; min-width: 0; font-size: 13px; color: var(--text); line-height: 1.4; }
.aib-test-run-t .aib-muted { display: block; }
.aib-test-h { font-size: 13px; font-weight: 650; color: var(--text); margin-top: 2px; }
.aib-test-row { display: grid; grid-template-columns: auto 1fr auto; gap: 2px 10px; align-items: center; width: 100%; padding: 9px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--input-bg); color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.aib-test-row:hover { border-color: var(--primary); }
.aib-test-row.on { border-color: var(--primary); }
.aib-test-st { grid-row: 1 / span 2; font-size: 12px; font-weight: 650; padding: 3px 9px; border-radius: 999px; background: var(--panel-3); color: var(--text); white-space: nowrap; }
.aib-test-st.ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 16%, transparent); }
.aib-test-st.warn { color: var(--warning); background: color-mix(in srgb, var(--warning) 18%, transparent); }
.aib-test-st.bad { color: var(--danger); background: color-mix(in srgb, var(--danger) 16%, transparent); }
.aib-test-st.run { color: var(--primary); background: color-mix(in srgb, var(--primary) 14%, transparent); }
.aib-test-row-t { font-size: 13px; color: var(--text); overflow-wrap: anywhere; }
.aib-test-row-m { grid-column: 2; font-size: 11.5px; color: var(--muted); }
.aib-test-row-w { grid-row: 1 / span 2; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.aib-test-det { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px 12px; border: 1px solid var(--line); border-top: 0; border-radius: 0 0 12px 12px; margin-top: -10px; background: color-mix(in srgb, var(--input-bg) 60%, transparent); }
.aib-test-say { font-size: 13px; line-height: 1.45; color: var(--text); }
.aib-test-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.aib-test-pill { font-size: 12px; font-weight: 600; padding: 3px 9px; border-radius: 999px; background: var(--panel-3); color: var(--text); }
.aib-test-pill.ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 16%, transparent); }
.aib-test-pill.info { color: var(--info); background: color-mix(in srgb, var(--info) 16%, transparent); }
.aib-test-pill.warn { color: var(--warning); background: color-mix(in srgb, var(--warning) 18%, transparent); }
.aib-test-pill.bad { color: var(--danger); background: color-mix(in srgb, var(--danger) 16%, transparent); }
.aib-test-pill.dim { color: var(--muted); }
.aib-test-acts { display: flex; justify-content: flex-end; gap: 8px; }
.aib-test-r { display: flex; flex-direction: column; gap: 4px; padding: 8px 0; border-top: 1px solid var(--line); }
.aib-test-r:first-of-type { border-top: 0; }
.aib-test-r-q { font-size: 13px; font-weight: 650; color: var(--text); overflow-wrap: anywhere; }
.aib-test-r-a { font-size: 13px; line-height: 1.45; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.aib-test-r-a.dim { color: var(--muted); font-style: italic; }
.aib-test-r-m { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; font-size: 11.5px; color: var(--muted); }
.aib-test-r-s { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.aib-test-r-s .wc-cop-src { min-height: 24px; font-size: 11.5px; }
.aib-test-more { align-self: flex-start; }

/* Список выбора языка (облик .lt-menu) */
.tr-lang-menu { position: fixed; z-index: 10070; min-width: 204px; max-height: 320px; overflow-y: auto; padding: 6px; background: var(--panel-3); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-3); animation: trIn .14s ease; }
.tr-lang-menu.hidden { display: none; }
.tr-lang-item { display: flex; align-items: center; width: 100%; padding: 8px 10px; gap: 8px; background: transparent; border: none; border-radius: 9px; color: var(--text); font-size: 13.5px; text-align: left; cursor: pointer; transition: background .1s ease; }
.tr-lang-item:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.tr-lang-item.sel { color: var(--primary); font-weight: 600; }
.tr-lang-check { margin-left: auto; display: inline-flex; align-items: center; color: var(--primary); }
.tr-lang-check svg { width: 15px; height: 15px; }
.tr-lang-item.off { color: var(--muted); }

/* ═══ Аналитика сотрудника (CLIE-225): селектор компаний, «Сейчас в работе», «Общие проекты» ═══ */
/* Тулбар вкладки «Аналитика» профиля: селектор компаний + мультиселект проектов (обе темы). */
.up-an-controls { display: flex; flex-direction: column; gap: 10px; }
.up-an-projs { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.up-an-projs.hidden { display: none; }
.up-an-projs-lbl { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-right: 2px; }
.up-an-chip { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; line-height: 1;
  padding: 6px 11px; border-radius: 999px; border: 1px solid var(--border); background: var(--panel-2); color: var(--text);
  cursor: pointer; transition: background .13s ease, color .13s ease, border-color .13s ease; }
.up-an-chip:hover { border-color: var(--primary); color: var(--primary); }
.up-an-chip.on { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; }
.up-an-chip.on .dash-pdot { box-shadow: 0 0 0 2px rgba(255,255,255,.35); }
.up-an-chip .dash-pdot { width: 8px; height: 8px; }
.up-an-chip-clear { color: var(--muted); }
.up-an-chip-clear:hover { color: var(--danger); border-color: var(--danger); }
/* «Сейчас в работе» — живой список задач в работе + индикатор «тикает» */
.dash-at-list { display: flex; flex-direction: column; gap: 1px; }
.dash-at-row { cursor: pointer; border-radius: 9px; transition: background .12s ease; }
.dash-at-row:hover { background: var(--panel-2); }
.dash-at-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 4px; font-size: 12px; color: var(--muted); }
.dash-at-proj { display: inline-flex; align-items: center; gap: 5px; }
.dash-at-col { padding: 1px 7px; border-radius: 5px; background: var(--panel-2); border: 1px solid var(--border); font-size: 11px; }
.dash-at-due.over { color: var(--danger); font-weight: 600; }
.dash-at-timer { display: inline-flex; align-items: center; gap: 6px; font-weight: 650; font-size: 12px; color: var(--ok); white-space: nowrap; }
.dash-live-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); flex: 0 0 auto;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 55%, transparent); animation: dashLivePulse 1.7s ease-out infinite; }
@keyframes dashLivePulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ok) 45%, transparent); }
  70% { box-shadow: 0 0 0 6px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
/* «Общие проекты» */
.dash-sp-row { cursor: pointer; border-radius: 9px; transition: background .12s ease; }
.dash-sp-row:hover { background: var(--panel-2); }
.v2-chip.accent { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary); }

/* ══════════ CLIE-225 доработка: цветные статусы, время, разбивка по статусам ══════════ */
/* Цветная ПИЛЮЛЯ статуса задачи (--pc = цвет статуса / категории) — «статус без цвета» починен. */
.dash-at-pill { display: inline-flex; align-items: center; padding: 1px 8px; border-radius: 6px; font-size: 11.5px; font-weight: 600; line-height: 1.55;
  color: var(--pc, var(--muted)); background: color-mix(in srgb, var(--pc, var(--muted)) 14%, transparent); border: 1px solid color-mix(in srgb, var(--pc, var(--muted)) 34%, transparent); }
/* «Сколько времени затрачено на задачу» */
.dash-at-spent { display: inline-flex; align-items: center; gap: 3px; font-size: 11.5px; color: var(--muted); font-weight: 500; }
.dash-at-spent svg.ic { width: 12px; height: 12px; opacity: .7; }
/* Бейдж «сколько активных» в чипе-проекте фильтра */
.up-an-chip-n { font-style: normal; font-size: 10.5px; font-weight: 700; padding: 0 5px; margin-left: 1px; border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary); }
.up-an-chip.on .up-an-chip-n { background: rgba(255,255,255,.26); color: #fff; }
/* «Загрузка по статусам» — цветные счётчики (сколько в работе / на проверке / бэклог) */
.dash-sb { display: flex; flex-wrap: wrap; gap: 8px; }
.dash-sb-chip { display: inline-flex; align-items: baseline; gap: 7px; padding: 8px 13px; border-radius: 11px; font-size: 12.5px; font-weight: 600; color: var(--text);
  background: color-mix(in srgb, var(--pc, var(--muted)) 11%, var(--panel)); border: 1px solid color-mix(in srgb, var(--pc, var(--muted)) 30%, transparent); }
.dash-sb-chip b { font-size: 17px; font-weight: 750; color: var(--pc, var(--text)); }

/* «Не мелко»: крупнее типографика на КАРТОЧКЕ аналитики сотрудника (вкладка профиля). */
#userProfileAnalytics .v2-sec { font-size: 13px; margin: 22px 0 10px; }
#userProfileAnalytics .v2-stat { padding: 15px 17px; }
#userProfileAnalytics .v2-stat-v { font-size: 27px; }
#userProfileAnalytics .v2-stat-l { font-size: 13px; }
#userProfileAnalytics .dash-kpis { grid-template-columns: repeat(auto-fit, minmax(145px, 1fr)); }
#userProfileAnalytics .tw-row-title { font-size: 14.5px; }
#userProfileAnalytics .dash-at-meta { font-size: 12.5px; gap: 9px; }
#userProfileAnalytics .v2-chip, #userProfileAnalytics .dash-at-pill, #userProfileAnalytics .dash-at-spent, #userProfileAnalytics .dash-at-timer { font-size: 12px; }
#userProfileAnalytics .up-an-chip { font-size: 12.5px; padding: 6px 11px; }
#userProfileAnalytics .dash-card-h { font-size: 13.5px; }

/* ══════════ CLIE-225 РЕДИЗАЙН: группировка по компаниям, «Загрузка сейчас», контекст задачи ══════════ */
/* «Загрузка сейчас» — снимок нагрузки: крупные цветные счётчики по НОРМАЛИЗОВАННЫМ статусам */
.dash-load { display: flex; flex-wrap: wrap; gap: 10px; }
.dash-load-chip { display: inline-flex; align-items: baseline; gap: 8px; padding: 10px 15px; border-radius: 13px; font-size: 13px; font-weight: 600; color: var(--text);
  background: color-mix(in srgb, var(--pc, var(--muted)) 12%, var(--panel)); border: 1px solid color-mix(in srgb, var(--pc, var(--muted)) 32%, transparent); }
.dash-load-chip b { font-size: 20px; font-weight: 780; color: var(--pc, var(--text)); line-height: 1; }
.dash-load-chip span { color: var(--muted); font-weight: 600; }
/* Контекст задачи «Компания · ●KEY» — сразу видно, к какой компании/проекту относится задача */
.dash-at-ctx { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.dash-at-co { color: var(--muted); font-weight: 600; }
.dash-at-sep { color: var(--border); }
/* «Завершено по проектам» — заголовок компании → её проекты */
.dash-cogroup { margin-bottom: 6px; }
.dash-cohdr { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 700; color: var(--text); margin: 12px 0 3px; }
.dash-cohdr svg.ic { width: 14px; height: 14px; color: var(--muted); }
/* Чипы-фильтры проектов, СГРУППИРОВАННЫЕ по компании (подпись компании перед её чипами) */
.up-an-cogrp { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.up-an-colbl { font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); margin: 0 1px 0 4px; }
/* Вкладка «Компания»: проекты ВЛОЖЕНЫ под своей компанией (guide-линия слева) */
.up-cogroup { overflow: hidden; }
.up-coprojs { margin: 2px 0 4px 22px; border-left: 2px solid var(--border); padding-left: 2px; }
.up-proj-crow .up-proj-ico { border-radius: 7px; }
/* Профиль: крупнее новые элементы (правило «не мелко») */
#userProfileAnalytics .dash-load-chip { font-size: 13.5px; }
#userProfileAnalytics .dash-load-chip b { font-size: 22px; }
#userProfileAnalytics .dash-cohdr { font-size: 12.5px; }
#userProfileAnalytics .dash-at-ctx, #userProfileAnalytics .dash-at-co { font-size: 12.5px; }
/* «Итоги за период» без данных — чистая заглушка вместо пустых графиков/«—» карточек */
.dash-empty-period { display: flex; align-items: center; gap: 15px; padding: 22px 24px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--panel);
  color: var(--muted); }
.dash-empty-period > svg.ic { width: 26px; height: 26px; flex: 0 0 auto; opacity: .38; }
.dash-empty-period > div { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.dash-empty-period b { color: var(--text); font-size: 14.5px; font-weight: 650; }
.dash-empty-period span { font-size: 12.5px; line-height: 1.45; }
/* «Завершено по проектам» — строки проектов внутри группы компании: аккуратный ряд-хэйрлайн */
.dash-cogroup .dash-pc-row { padding: 9px 4px; border-bottom: 1px solid var(--line); }
.dash-cogroup .dash-pc-row:last-child { border-bottom: 0; }
.dash-cogroup .dash-pc-row .tw-row-title { display: inline-flex; align-items: center; gap: 8px; font-size: 13.5px; font-weight: 550; }


/* ═══════════════════════════════════════════════════════════════════════════
   CLIE-225 РЕДИЗАЙН v2 — Аналитика сотрудника (Apple-grade, .ea-root scope).
   Разбор жалоб владельца: «непонятно какой проект к какой компании», «не красиво»,
   «кому он нужен». Сводка-плитки, человеческий вывод, работа по компаниям, свёрнутый
   фильтр, аккуратные итоги. Тревога — цветом цифры, без заливки строки. Обе темы.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Employee analytics — Apple-grade. Scoped to .ea-root. Light + dark. */
.ea-root{display:flex;flex-direction:column;gap:6px;--ea-hair:var(--line);}
.ea-root *{box-sizing:border-box;}

/* Section header */
.ea-sec{display:flex;align-items:center;gap:9px;margin:24px 2px 12px;font-size:15px;font-weight:650;color:var(--text);letter-spacing:-.01em;}
.ea-sec:first-child{margin-top:6px;}
.ea-sec .ic{width:18px;height:18px;color:var(--muted);flex:0 0 auto;}
.ea-sec-n{font-style:normal;margin-left:2px;font-size:12.5px;font-weight:600;color:var(--muted);padding:2px 9px;border-radius:999px;background:var(--panel-2);}
.ea-sec-period{margin-top:30px;}
.ea-sec-sub{font-size:13.5px;margin:20px 2px 10px;font-weight:600;}
.ea-sec-sub .ic{width:16px;height:16px;}

/* Summary hero stat tiles */
.ea-sum{display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));gap:12px;}
.ea-sum-sm{grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:10px;}
.ea-stat{position:relative;padding:16px 18px;border-radius:16px;background:var(--panel);border:1px solid var(--ea-hair);
  box-shadow:0 1px 2px rgba(0,0,0,.04);overflow:hidden;transition:transform .16s ease,box-shadow .16s ease;}
.ea-stat-ic{position:absolute;top:14px;right:14px;color:var(--muted);opacity:.5;}
.ea-stat-ic .ic{width:18px;height:18px;}
.ea-stat-v{font-size:27px;font-weight:700;line-height:1.05;letter-spacing:-.02em;color:var(--text);font-variant-numeric:tabular-nums;}
.ea-sum-sm{display:flex;flex-wrap:wrap;}
.ea-sum-sm .ea-stat{padding:12px 16px;min-width:148px;flex:0 1 auto;}
.ea-sum-sm .ea-stat-v{font-size:21px;}
.ea-stat-l{margin-top:6px;font-size:12.5px;font-weight:500;color:var(--muted);letter-spacing:.01em;}
.ea-stat.ea-ok .ea-stat-v{color:var(--ok);}
.ea-stat.ea-ok .ea-stat-ic{color:var(--ok);opacity:.55;}
.ea-stat.ea-warn .ea-stat-v{color:#e0902a;}
.ea-stat.ea-warn .ea-stat-ic{color:#e0902a;opacity:.55;}
/* «Просрочено» — тревога через ЦВЕТ цифры/иконки, без заливки всей карточки (правило владельца). */
.ea-stat.ea-danger .ea-stat-v{color:var(--danger);}
.ea-stat.ea-danger .ea-stat-ic{color:var(--danger);opacity:.7;}

/* Insight line — human verdict */
.ea-insight{display:flex;align-items:center;gap:10px;margin:14px 2px 2px;padding:11px 15px;border-radius:12px;
  background:color-mix(in srgb,var(--primary) 7%,var(--panel));border:1px solid color-mix(in srgb,var(--primary) 18%,var(--ea-hair));
  font-size:13.5px;font-weight:500;color:var(--text);}
.ea-insight>.ic{width:17px;height:17px;color:var(--primary);flex:0 0 auto;opacity:.9;}
.ea-ins-warn{color:var(--danger);font-weight:650;}

/* Status load bar */
.ea-load{display:flex;flex-direction:column;gap:12px;}
.ea-loadbar{display:flex;height:9px;border-radius:999px;overflow:hidden;background:var(--panel-2);gap:2px;padding:0;}
.ea-seg{display:block;min-width:8px;background:var(--pc);border-radius:2px;}
.ea-seg:first-child{border-top-left-radius:999px;border-bottom-left-radius:999px;}
.ea-seg:last-child{border-top-right-radius:999px;border-bottom-right-radius:999px;}
.ea-leg{display:flex;flex-wrap:wrap;gap:14px 20px;}
.ea-legi{display:inline-flex;align-items:center;gap:7px;font-size:13px;font-weight:500;color:var(--muted);}
.ea-legi b{color:var(--text);font-weight:700;font-variant-numeric:tabular-nums;}
.ea-dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto;}

/* Active work grouped by company */
.ea-cgroup{margin-bottom:14px;}
.ea-chead{display:flex;align-items:center;gap:11px;margin:0 2px 10px;}
.ea-cbadge{width:28px;height:28px;border-radius:8px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:700;letter-spacing:.02em;color:var(--muted);background:var(--panel-2);border:1px solid var(--ea-hair);
  background-size:cover;background-position:center;}
.ea-cbadge-logo{border:0;color:transparent;}
.ea-cname{font-size:14.5px;font-weight:650;color:var(--text);letter-spacing:-.01em;}
.ea-chead-n{font-style:normal;font-size:12px;font-weight:600;color:var(--muted);padding:1px 8px;border-radius:999px;background:var(--panel-2);}
.ea-chead-sm .ic{width:16px;height:16px;color:var(--muted);}
.ea-tasks{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:10px;}
.ea-task{padding:13px 15px;border-radius:14px;background:var(--panel);border:1px solid var(--ea-hair);cursor:pointer;
  transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease;box-shadow:0 1px 2px rgba(0,0,0,.03);}
.ea-task:hover{transform:translateY(-1px);border-color:color-mix(in srgb,var(--primary) 34%,var(--ea-hair));box-shadow:0 6px 18px -8px rgba(0,0,0,.28);}
.ea-task-top{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:5px;}
.ea-tproj{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:var(--muted);min-width:0;}
.ea-tproj-none{opacity:.7;}
.ea-task-title{font-size:15px;font-weight:600;color:var(--text);line-height:1.32;letter-spacing:-.01em;}
.ea-task-meta{display:flex;flex-wrap:wrap;align-items:center;gap:9px;margin-top:9px;}
.ea-pill{display:inline-flex;align-items:center;padding:3px 9px;border-radius:7px;font-size:11.5px;font-weight:650;line-height:1.4;
  color:var(--pc);background:color-mix(in srgb,var(--pc) 13%,transparent);border:1px solid color-mix(in srgb,var(--pc) 32%,transparent);}
.ea-tmeta{display:inline-flex;align-items:center;gap:4px;font-size:12px;font-weight:500;color:var(--muted);}
.ea-tmeta .ic{width:13px;height:13px;opacity:.75;}
.ea-tspent{font-weight:600;color:var(--text);}
.ea-tdue.over{color:var(--danger);font-weight:650;}
.ea-ttimer{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:650;color:var(--ok);white-space:nowrap;}
.ea-livedot{width:7px;height:7px;border-radius:50%;background:var(--ok);flex:0 0 auto;box-shadow:0 0 0 0 color-mix(in srgb,var(--ok) 55%,transparent);animation:eaPulse 1.7s ease-out infinite;}
@keyframes eaPulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--ok) 45%,transparent);}70%{box-shadow:0 0 0 6px transparent;}100%{box-shadow:0 0 0 0 transparent;}}

/* Project filter chips */
.ea-filter{display:flex;flex-wrap:wrap;align-items:center;gap:7px;margin-top:20px;padding:14px 15px;border:1px solid var(--ea-hair);border-radius:14px;background:var(--panel);}
.ea-flbl-top{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);margin-right:4px;width:100%;}
.ea-fgrp{display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px;}
.ea-flbl{font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);margin:0 2px 0 6px;}
.ea-fgrp:first-of-type .ea-flbl{margin-left:0;}
.ea-chip{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;line-height:1;padding:7px 12px;border-radius:999px;
  border:1px solid var(--ea-hair);background:var(--panel-2);color:var(--text);cursor:pointer;transition:all .13s ease;}
.ea-chip:hover{border-color:color-mix(in srgb,var(--primary) 50%,transparent);color:var(--primary);}
.ea-chip.on{background:var(--acc-fill);border-color:var(--acc-fill);color:#fff;}
.ea-chip.on .ea-dot{box-shadow:0 0 0 2px rgba(255,255,255,.4);}
.ea-chip-n{font-style:normal;font-size:10.5px;font-weight:700;padding:0 5px;border-radius:999px;background:color-mix(in srgb,var(--primary) 16%,transparent);color:var(--primary);}
.ea-chip.on .ea-chip-n{background:rgba(255,255,255,.26);color:#fff;}
.ea-chip-clear{color:var(--muted);}
.ea-chip-clear:hover{color:var(--danger);border-color:color-mix(in srgb,var(--danger) 50%,transparent);}
.ea-chip-more{color:var(--muted);background:transparent;border-style:dashed;}
.ea-chip-more:hover{color:var(--primary);border-color:color-mix(in srgb,var(--primary) 50%,transparent);border-style:solid;}

/* Completed-by-company rows */
.ea-cgroup-sm{margin-bottom:8px;}
.ea-pclist{display:flex;flex-direction:column;border:1px solid var(--ea-hair);border-radius:12px;overflow:hidden;background:var(--panel);}
.ea-pcrow{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 14px;border-bottom:1px solid var(--ea-hair);}
.ea-pcrow:last-child{border-bottom:0;}
.ea-pcname{display:inline-flex;align-items:center;gap:9px;font-size:13.5px;font-weight:550;color:var(--text);}
.ea-pcstats{display:inline-flex;flex-wrap:wrap;align-items:center;gap:6px;}
.ea-tag{font-size:11.5px;font-weight:600;color:var(--muted);padding:3px 9px;border-radius:999px;background:var(--panel-2);border:1px solid var(--ea-hair);}
.ea-tag.ea-ok{color:var(--ok);background:color-mix(in srgb,var(--ok) 12%,transparent);border-color:color-mix(in srgb,var(--ok) 28%,transparent);}
.ea-tag.ea-warn{color:#e0902a;background:color-mix(in srgb,#e0902a 12%,transparent);border-color:color-mix(in srgb,#e0902a 28%,transparent);}
.ea-tag.ea-danger{color:var(--danger);background:var(--danger-soft);border-color:color-mix(in srgb,var(--danger) 28%,transparent);}

/* Empty states */
.ea-empty{display:flex;align-items:center;gap:16px;padding:22px 24px;border:1px solid var(--ea-hair);border-radius:16px;background:var(--panel);color:var(--muted);}
.ea-empty>.ic{width:26px;height:26px;flex:0 0 auto;opacity:.4;}
.ea-empty>div{display:flex;flex-direction:column;gap:4px;min-width:0;}
.ea-empty b{color:var(--text);font-size:14.5px;font-weight:650;}
.ea-empty span{font-size:12.5px;line-height:1.5;}
.ea-empty-sm{padding:16px 18px;font-size:13px;gap:11px;}
.ea-empty-sm .ic{width:18px;height:18px;color:var(--ok);opacity:.8;}

/* ══════════════════════════════════════════════════════════════════════════
   CLIE-249 — ЕДИНЫЙ ТАБ-КОМПОНЕНТ на весь продукт (одна реализация).
   .cc-tabs = подчёркивание · .cc-seg = iOS сегмент. Реагирует на .active И .on. Обе темы.
   Семейства-алиасы перечислены рядом с каноном — старые CSS перекрываются, разметка/JS НЕ трогаются.
   ══════════════════════════════════════════════════════════════════════════ */

/* ─────────── ПОДЧЁРКИВАНИЕ (.cc-tabs) ─────────── */
/* контейнеры */
.cc-tabs,
.tip-tabs, .td-tabs, .v2-tabs, .up-tabs, .cx-tabs, .pr-seg, .v2pt-bar, .notif-tabs,
.tw-seg#twSeg, .tw-seg.v2-seg, #v2Seg {
  display: flex; align-items: stretch; gap: 2px;
  padding: 0 0; margin: 0; border: 0; border-bottom: 1px solid var(--line);
  background: none; border-radius: 0; box-shadow: none;
  overflow-x: auto; scrollbar-width: none;
}
.cc-tabs::-webkit-scrollbar, .tip-tabs::-webkit-scrollbar, .td-tabs::-webkit-scrollbar,
.v2-tabs::-webkit-scrollbar, .up-tabs::-webkit-scrollbar, .cx-tabs::-webkit-scrollbar,
.pr-seg::-webkit-scrollbar, .v2pt-bar::-webkit-scrollbar, .notif-tabs::-webkit-scrollbar,
.tw-seg#twSeg::-webkit-scrollbar, .tw-seg.v2-seg::-webkit-scrollbar { display: none; }
/* элементы */
.cc-tabs > *,
.tip-tab, .td-tabs button, .v2-tabs button, .up-tab, .cx-tab, .pr-seg button, .v2pt-tab,
.notif-tab, .tw-seg#twSeg button, .tw-seg.v2-seg button, #v2Seg button {
  position: relative; display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  flex: 0 0 auto; margin: 0; padding: 9px 12px 11px;
  background: none; border: 0; border-radius: 0; outline: none; box-shadow: none;
  color: var(--muted); font: inherit; font-size: 13px; font-weight: 530; line-height: 18px;
  white-space: nowrap; cursor: pointer; -webkit-appearance: none;
  transition: color var(--dur-1) ease;
}
.cc-tabs > *:hover,
.tip-tab:hover, .td-tabs button:hover, .v2-tabs button:hover, .up-tab:hover, .cx-tab:hover,
.pr-seg button:hover, .v2pt-tab:hover, .notif-tab:hover,
.tw-seg#twSeg button:hover, .tw-seg.v2-seg button:hover, #v2Seg button:hover { color: var(--text-dim); }
/* активный */
.cc-tabs > *.on, .cc-tabs > *.active,
.tip-tab.active, .td-tabs button.active, .v2-tabs button.active, .up-tab.active, .cx-tab.active,
.pr-seg button.active, .v2pt-tab.on, .v2pt-tab.active, .notif-tab.active,
.tw-seg#twSeg button.active, .tw-seg.v2-seg button.active, #v2Seg button.active {
  color: var(--text); font-weight: 640; background: none; border-color: transparent; box-shadow: none;
}
.cc-tabs > *.on::after, .cc-tabs > *.active::after,
.tip-tab.active::after, .td-tabs button.active::after, .v2-tabs button.active::after,
.up-tab.active::after, .cx-tab.active::after, .pr-seg button.active::after,
.v2pt-tab.on::after, .v2pt-tab.active::after, .notif-tab.active::after,
.tw-seg#twSeg button.active::after, .tw-seg.v2-seg button.active::after, #v2Seg button.active::after {
  content: ""; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px;
  border-radius: 3px; background: var(--primary); animation: ccTabInk var(--dur-2) ease;
}
@keyframes ccTabInk { from { opacity: 0; transform: scaleX(.35); } to { opacity: 1; transform: scaleX(1); } }
.cc-tabs svg.ic, .cc-tabs .ic,
.tip-tab svg.ic, .cx-tab svg.ic, .pr-seg button svg.ic, .tw-seg#twSeg button svg.ic,
.tw-seg.v2-seg button svg.ic, #v2Seg button svg.ic { width: 15px; height: 15px; flex: none; }

/* ─────────── iOS СЕГМЕНТ (.cc-seg) ─────────── */
/* дорожка (контейнеры) */
.tw-seg, .co-seg, .cli-seg, .stf-segrole, .cx-revseg, .folder-pick-segs, .rpm-seg,
.tip-scope-seg, .gl-seg, .pcat-viewtog, .v2acc-segs, .feed-seg, .mp-seg, .ai-assist-filter,
.cc-qadd-seg, .ai-voice-seg, .mode-toggle {
  display: inline-flex; align-items: center; gap: 0;
  padding: 3px; border-radius: 12px;
  background: var(--seg-track); border: 1px solid var(--line); box-shadow: none;
  max-width: 100%; overflow-x: auto; scrollbar-width: none;
}
/* сегменты (элементы) */
.tw-seg button, .co-seg button, .cli-seg button, .stf-segrole button, .cx-revseg button,
.folder-pick-seg, .rpm-seg button, .tip-scope-btn, .gl-seg-btn, .pcat-vbtn,
.v2acc-seg, .feed-seg button, .mp-seg button, .ai-filter-tab, .cc-qadd-t, .ai-voice-seg button,
.mode-seg {
  position: relative; flex: 1 1 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  /* 🔴🔴 СРЕД-33 · min-width: AUTO, А НЕ 0. `flex: 1 1 0` делит дорожку поровну, и с
     `min-width: 0` кнопка спокойно становилась УЖЕ собственной подписи; обрезки нет
     (`overflow: visible`) + `white-space: nowrap` → подпись рисовалась ПОВЕРХ соседа и
     поверх приподнятой пилюли. Замер прода (среда, «Файлы | Изменения | Ветки»): коробка
     73px, содержимое 81px → «Изменения» вылезало по 4px в каждую сторону и налезало на
     пилюлю «Файлы» — ровно скрин владельца. `auto` = автоматический минимум флекс-элемента
     (= min-content = вся подпись целиком): поровну делится ТОЛЬКО свободное место, ужать
     подпись до нечитаемого огрызка флекс больше не может. Не влезло совсем — этим
     занимаются ступени `.cc-segfit.tight` и подтаивающий край (ccSegFit в app.js). */
  margin: 0; padding: 7px 14px; min-width: auto;
  border: 1px solid transparent; border-radius: 9px; outline: none;
  background: none; color: var(--muted); font: inherit; font-size: 13px; font-weight: 530; line-height: 18px;
  white-space: nowrap; cursor: pointer; -webkit-appearance: none; box-shadow: none;
  transition: color var(--dur-1) ease, background var(--dur-1) ease, box-shadow var(--dur-1) ease;
}
.tw-seg button:hover:not(.active), .co-seg button:hover:not(.active), .cli-seg button:hover:not(.active),
.rpm-seg button:hover:not(.on), .tip-scope-btn:hover:not(.active), .gl-seg-btn:hover:not(.on),
.pcat-vbtn:hover:not(.on), .v2acc-seg:hover:not(.on), .feed-seg button:hover:not(.active),
.mp-seg button:hover:not(.on), .ai-filter-tab:hover:not(.active), .cc-qadd-t:hover:not(.on),
.mode-seg:hover:not(.active), .cx-revseg button:hover:not(.active), .folder-pick-seg:hover:not(.active),
.stf-segrole button:hover:not(.on) { color: var(--text-dim); }
/* iOS-разделитель между двумя НЕактивными сегментами */
.tw-seg:not(#twSeg):not(#v2Seg):not(.v2-seg) button:not(.active) + button:not(.active)::before,
.rpm-seg button:not(.on) + button:not(.on)::before,
.co-seg button:not(.active) + button:not(.active)::before,
.cli-seg button:not(.active) + button:not(.active)::before,
.feed-seg button:not(.active) + button:not(.active)::before {
  content: ""; position: absolute; left: 0; top: 24%; bottom: 24%; width: 1px; background: var(--seg-div);
}
/* активный сегмент = приподнятый thumb */
.tw-seg button.active, .co-seg button.active, .cli-seg button.active, .stf-segrole button.on,
.cx-revseg button.active, .folder-pick-seg.active, .rpm-seg button.on, .tip-scope-btn.active,
.gl-seg-btn.on, .pcat-vbtn.on, .v2acc-seg.on, .feed-seg button.active, .mp-seg button.on,
.ai-filter-tab.active, .cc-qadd-t.on, .ai-voice-seg button.on, .mode-seg.active {
  background: var(--seg-thumb); color: var(--text); font-weight: 640;
  border-color: var(--seg-thumb-bd); box-shadow: var(--seg-thumb-sh);
}
.tw-seg button svg.ic, .co-seg button svg.ic, .v2acc-seg svg.ic, .mode-seg svg.ic,
.tip-scope-btn svg.ic, .pcat-vbtn svg.ic, .gl-seg-btn svg.ic { width: 15px; height: 15px; flex: none; }

/* ─────────── РАЗМЕР и МЕСТО сегмента: ОДИН компонент, два независимых модификатора ───────────
   Раньше каждый новый сегмент рисовали руками «под место» — и получалось три разных
   вида в одном ряду (владелец: «дизайн везде разный»). Теперь это МОДИФИКАТОРЫ канона,
   а не новые компоненты, и они ОРТОГОНАЛЬНЫ (CLIE-505):

   РАЗМЕР — насколько крупный:
     .cc-seg              — крупный, страничный пикер (высота ≈42px)
     .cc-seg.cc-seg-md    — В СТРОКУ: ровно высота соседних полей/кнопок (--ctl-h)
     .cc-seg.cc-seg-sm    — КОМПАКТНЫЙ: в строке списка, в шапке панели, над композером
   МЕСТО — на чём лежит:
     .cc-seg.cc-seg-inset — лежит ВНУТРИ поля ввода/инсета (фон под ним = --seg-track),
                            поэтому дорожка опускается на шаг глубже, иначе сливается.

   🔴 Размер НЕ должен решать за цвет: пока `-sm` сам темнил дорожку, компактный сегмент
   на обычной панели (16 строк «Уведомлений») терял дорожку и читался как три слова.
   Оба «строчных» размера жмутся по содержимому (flex:0 0 auto) и тянутся до высоты ряда
   (align-self:stretch) — сегмент физически НЕ может снова оказаться ниже соседей. */
/* 🔴 Модификаторы `.cc-seg-md` / `.cc-seg-sm` / `.cc-seg-inset` — в `/app/ccroom.css`. */

/* ─────────── 🔴🔴 СРЕД-33 · СЕГМЕНТ, КОТОРОМУ НЕ ХВАТИЛО ШИРИНЫ ───────────
   Владелец прислал скрин среды: подпись «Изменения» нарисована ПОВЕРХ пилюли «Файлы»
   («проблемы в вёрстке… часто бывает при использовании А+ и А− при увеличении экрана»).
   Причину сняли выше (min-width: auto — подпись больше не сжимается ниже себя самой),
   но остаётся честный вопрос: а если подписи не влезают в дорожку ВООБЩЕ?
   Ответ у продукта уже есть — ровно та же лестница, что у ленты разделов (convTabsEdges):
     ступень 1 `.tight`  — ужать ВОЗДУХ (боковые отступы и зазор), подписи целы;
     ступень 2 края      — честно прокрутить и СКАЗАТЬ об этом подтаявшим краем.
   Второй лестницы не заводим: классы вешает ОДНА функция `ccSegFit()` в app.js по ОДНОМУ
   реестру дорожек (`SEG_FIT_SEL`), она же метит дорожку классом `.cc-segfit`.
   🔴 Почему край, а не полоса прокрутки: бегунок в продукте ПРОЗРАЧЕН, пока на блок не
   навели мышь (решение владельца 15.07) — «есть ещё» человек читает только по краю (CLIE-620).
   Меряем, а не гадаем: медиазапрос видит ОКНО, а сегмент жмёт КОЛОНКА (её тянут мышью) и
   масштаб интерфейса А−/А+, от которых окно не меняется вовсе. */
/* 🔴 Ступени `.cc-segfit.tight/.more-l/.more-r` — в `/app/ccroom.css` (часть канона). */

/* ═══════════════════════════════════════════════════════════════════════════ *
 *  ЧЕРНОВИКИ И ШАБЛОНЫ СООБЩЕНИЙ (CLIE-299) — поповер у поля ввода (иконка-закладка).
 *  Apple-grade: сегмент-переключатель (общие --seg-* токены), мягкие карточки,
 *  хэйрлайны, hover-раскрытие иконок, свет/тёмная — через общие переменные.
 * ═══════════════════════════════════════════════════════════════════════════ */
.drafts-btn { position: relative; }
.drafts-btn.is-open { color: var(--primary); background: var(--sel); }
/* тонкая точка: в этом чате есть отложенные черновики */
.drafts-btn.has-drafts::after {
  content: ""; position: absolute; top: 5px; right: 5px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--primary); box-shadow: 0 0 0 2px var(--panel);
}

#dtPop.dt-pop {
  position: fixed; z-index: 10000; width: 320px; max-width: calc(100vw - 24px);
  padding: 8px; box-sizing: border-box;
  background: var(--panel-3); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-3); color: var(--text);
  animation: dtPop .13s var(--ease, cubic-bezier(.2,.8,.2,1)); transform-origin: bottom left;
}
@keyframes dtPop { from { opacity: 0; transform: translateY(6px) scale(.98); } to { opacity: 1; transform: none; } }

/* сегмент-переключатель Черновики/Шаблоны = канон .cc-seg + .cc-seg-md (CLIE-505).
   Своего вида больше нет — здесь только РАСКЛАДКА: тянется на всю ширину поповера. */
.dt-seg { display: flex; margin-bottom: 8px; }
.dt-seg > .dt-seg-btn { flex: 1 1 0; }

.dt-scope { font-size: 11px; color: var(--muted); padding: 0 6px 8px; }

/* «В черновик» / «В шаблон» — мягкая акцент-плитка; неактивна, пока поле пустое */
.dt-save {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; padding: 9px 12px; margin-bottom: 8px;
  border: 1px solid transparent; border-radius: var(--r-md);
  background: var(--sel); color: var(--primary); font-size: 13px; font-weight: 600; cursor: pointer;
  transition: background var(--dur-1) var(--ease), opacity var(--dur-1) var(--ease);
}
.dt-save .ic { width: 16px; height: 16px; }
.dt-save:hover { background: color-mix(in srgb, var(--primary) 22%, transparent); }
.dt-save[disabled] { background: var(--input-bg); color: var(--muted); opacity: .6; cursor: default; }

.dt-list { max-height: 46vh; overflow-y: auto; margin: 0 -2px; padding: 0 2px; display: flex; flex-direction: column; gap: 2px; }
.dt-list::-webkit-scrollbar { width: 8px; }
.dt-list::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 8px; border: 2px solid transparent; background-clip: padding-box; }

.dt-item { display: flex; align-items: center; gap: 6px; padding: 8px 8px 8px 10px; border-radius: var(--r-md); cursor: pointer; transition: background var(--dur-1) var(--ease); }
.dt-item:hover { background: var(--hover); }
.dt-item.is-active { background: var(--sel); }
.dt-item-body { flex: 1; min-width: 0; }
.dt-item-text { font-size: 13px; line-height: 1.4; color: var(--text); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; word-break: break-word; }
.dt-item-meta { font-size: 11px; color: var(--muted); margin-top: 3px; }

.dt-icon {
  flex: none; width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: var(--r-sm); background: transparent; color: var(--muted); cursor: pointer;
  opacity: 0; transition: opacity var(--dur-1) var(--ease), background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.dt-item:hover .dt-icon, .dt-item:focus-within .dt-icon { opacity: 1; }
.dt-icon .ic { width: 16px; height: 16px; }
.dt-icon:hover { background: var(--hover); color: var(--text); }
.dt-send:hover { color: var(--primary); background: var(--sel); }
.dt-del:hover { color: var(--danger); background: var(--danger-soft); }
@media (hover: none) { .dt-icon { opacity: 1; } }  /* тач: hover нет — иконки всегда видны */

.dt-empty { text-align: center; padding: 22px 16px 18px; }
.dt-empty-ico { width: 44px; height: 44px; margin: 0 auto 10px; display: flex; align-items: center; justify-content: center; border-radius: var(--r-full); background: var(--sel); color: var(--primary); }
.dt-empty-ico .ic { width: 22px; height: 22px; }
.dt-empty-title { font-size: 13.5px; font-weight: 600; color: var(--text); margin-bottom: 4px; }
.dt-empty-sub { font-size: 12px; line-height: 1.45; color: var(--muted); max-width: 244px; margin: 0 auto; }

.dt-loading { display: flex; align-items: center; justify-content: center; padding: 26px; }
.dt-spin { width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line-strong); border-top-color: var(--primary); animation: dtSpin .7s linear infinite; }
@keyframes dtSpin { to { transform: rotate(360deg); } }

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   БАЗА ЗНАНИЙ (ИИ-память) — раздел рельса #knowledgeOverlay. Оверлей наследует .tasks-workspace
   (позиционирование/фон). Здесь — только собственные .kn-* : шапка+статы+поиск, карточки памяти
   (инлайн-правка), граф связей. Apple-grade: 4/8-сетка, тонкие хэйрлайны, мягкие тени, 120–160ms
   переходы; светлая и тёмная — на общих токенах (--panel/--line/--text/--muted/--primary/--sel…).
   ═══════════════════════════════════════════════════════════════════════════════════════════ */
/* ── Шапка ── */
.kn-head { gap: 10px; flex-wrap: nowrap; }
.kn-title .ic { width: 20px; height: 20px; color: var(--primary); }
.kn-stats { flex: 0 1 auto; font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.kn-search { flex: 0 1 300px; min-width: 150px; display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 12px;
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 10px; transition: border-color .14s, background .14s, box-shadow .14s; }
.kn-search:focus-within { border-color: var(--primary); background: var(--panel); box-shadow: 0 0 0 3px var(--sel); }
.kn-search-ic { display: inline-flex; flex: none; color: var(--muted); }
.kn-search-ic .ic { width: 15px; height: 15px; }
/* Поле внутри рамки .kn-search: базовый `input { padding: 11px 14px }` добавлял 14 px слева поверх
   зазора значка 8 px — «Поиск в памяти…»: лупа x 358–370, подсказка с x=394, пусто 23 px (кадр 22.10,
   обе темы); у поиска вики — 9. Отступы держит рамка, поле — во всю её высоту (как .kn-wiki-input). */
.kn-search-input { flex: 1; min-width: 0; align-self: stretch; padding: 0; border: none; background: transparent; color: var(--text); font-size: 13.5px; outline: none; }
.kn-search-input::placeholder { color: var(--text-dim); }
.kn-seg .ic { width: 15px; height: 15px; }
.kn-add { flex: none; display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 14px; border: none; border-radius: 10px;
  background: var(--acc-grad); color: #fff; font-size: 13px; font-weight: 650; cursor: pointer;
  box-shadow: 0 4px 12px -4px var(--glow); transition: filter .14s, transform .1s, box-shadow .14s; }
.kn-add .ic { width: 16px; height: 16px; }
.kn-add:hover { filter: brightness(1.06); box-shadow: 0 6px 16px -5px var(--glow); }
.kn-add:active { transform: translateY(1px); }

/* ── Тело ── */
.kn-body { padding: 0; }
.kn-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 14px; padding: 18px 20px 40px; align-content: start; }

/* ── Фильтр по проекту (домену): Все · ClientsChat · ADMMAIN · Food ─────────────
   Просмотровый одиночный выбор (серверный ?domain=); recall видит весь мозг. Пилюли
   с доменной точкой — та же палитра, что легенда графа. Свет+тёмная через токены. */
.kn-domfilter { display: flex; flex-wrap: wrap; gap: 7px; padding: 16px 20px 0; align-items: center; }
.kn-domchip { display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 13px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted); font-size: 12.5px; font-weight: 600;
  cursor: pointer; transition: border-color .13s, background .13s, color .13s, box-shadow .13s; -webkit-user-select: none; user-select: none; }
.kn-domchip:hover { color: var(--text); border-color: var(--line-strong); }
.kn-domchip .kn-domdot { width: 8px; height: 8px; border-radius: 50%; background: var(--kn-dc, var(--muted)); flex: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--kn-dc, var(--muted)) 16%, transparent); transition: box-shadow .13s; }
.kn-domchip.active { color: var(--text);
  border-color: color-mix(in srgb, var(--kn-dc, var(--primary)) 55%, var(--line));
  background: color-mix(in srgb, var(--kn-dc, var(--primary)) 12%, var(--panel));
  box-shadow: 0 2px 8px -5px color-mix(in srgb, var(--kn-dc, var(--primary)) 60%, transparent); }
.kn-domchip.active .kn-domdot { box-shadow: 0 0 0 3px color-mix(in srgb, var(--kn-dc, var(--muted)) 30%, transparent); }

/* ── Фильтр «Кто видит» (аудитория): первичный ряд-полки над доменным фильтром. Иконка+число.
   Отвечает на «кто видит эту запись» прямо в UI — плоская куча превращается в полки. Свет+тёмная. */
.kn-audfilter { display: flex; flex-wrap: wrap; gap: 7px; padding: 16px 20px 2px; align-items: center; }
.kn-audfilter-lbl { font-size: 11.5px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
  color: var(--muted); margin-right: 3px; opacity: .8; }
html[data-theme="light"] .kn-audfilter-lbl { opacity: 1; } /* CLIE-1946: .8 на светлом = 3.87:1 */
/* Подпись есть у ОБОИХ рядов («Кто видит», «Проект») и одной ширины: чипы второго ряда встают
   под колонку первого (кадр: «КТО ВИДИТ» 67 px, чипы первого ряда с x=201, второй ряд без подписи с x=124). */
.kn-audfilter-lbl { flex: none; min-width: 6.5em; }
.kn-audchip { display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 11px 0 9px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted); font-size: 12.5px; font-weight: 600;
  cursor: pointer; transition: border-color .13s, background .13s, color .13s, box-shadow .13s; -webkit-user-select: none; user-select: none; }
.kn-audchip:hover { color: var(--text); border-color: var(--line-strong); }
.kn-audchip .kn-audchip-ic { display: inline-flex; color: var(--kn-ac, var(--muted)); }
.kn-audchip .kn-audchip-ic svg { width: 14px; height: 14px; }
.kn-audchip-nm { line-height: 1; }
.kn-audchip-n { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 999px; font-size: 11px; font-weight: 700; color: var(--muted);
  background: color-mix(in srgb, var(--muted) 14%, transparent); }
.kn-audchip.active { color: var(--text);
  border-color: color-mix(in srgb, var(--kn-ac, var(--primary)) 55%, var(--line));
  background: color-mix(in srgb, var(--kn-ac, var(--primary)) 12%, var(--panel));
  box-shadow: 0 2px 8px -5px color-mix(in srgb, var(--kn-ac, var(--primary)) 60%, transparent); }
.kn-audchip.active .kn-audchip-n { color: var(--text);
  background: color-mix(in srgb, var(--kn-ac, var(--primary)) 22%, transparent); }
/* Доменный ряд под аудиторией — чуть плотнее сверху (общий блок фильтров). */
.kn-audfilter + .kn-domfilter { padding-top: 6px; }

/* ── Карточка памяти ── */
.kn-card { position: relative; display: flex; flex-direction: column; gap: 8px; padding: 14px 16px 13px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow-1);
  transition: border-color .14s, box-shadow .14s, transform .12s; }
.kn-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow-2); }
/* Закреплённая — кромка 1 px акцентом по ВСЕМУ контуру + включённая булавка. Левая рейка
   `inset 3px 0 0` запрещена каноном accent (кадр: 3 столбца сплошного акцента у каждой карточки). */
.kn-card.pinned { border-color: color-mix(in srgb, var(--primary) 42%, var(--line)); box-shadow: var(--shadow-1); }
.kn-card.kn-flash { animation: knFlash 1.4s ease; }
@keyframes knFlash { 0%,100% { box-shadow: var(--shadow-1); } 30% { box-shadow: 0 0 0 3px var(--primary), var(--shadow-2); } }

/* ── «Спроси базу» — разговорный RAG по всей памяти (свет+тёмная) ───────────── */
.kn-title { flex: 0 0 auto; }                 /* заголовок «База знаний» — не сжимаем, всегда целиком */
.kn-spin.sm { width: 16px; height: 16px; border-width: 2px; }
.kn-ask { display: flex; flex-direction: column; height: 100%; }
.kn-ask-thread { flex: 1; min-height: 0; overflow-y: auto; padding: 20px 20px 8px; display: flex; flex-direction: column; gap: 18px; }
.kn-ask-hero { margin: auto; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 24px 20px; max-width: 560px; }
.kn-ask-examples { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 12px; }
.kn-ask-ex { display: inline-flex; align-items: center; gap: 7px; padding: 8px 13px; border-radius: 999px; border: 1px solid var(--line); background: var(--panel); color: var(--text); font-size: 13px; cursor: pointer; transition: border-color .13s, background .13s, transform .13s; }
.kn-ask-ex:hover { border-color: var(--primary); background: var(--sel); transform: translateY(-1px); }
.kn-ask-ex .ic { width: 14px; height: 14px; color: var(--muted); }
.kn-ask-x { display: flex; flex-direction: column; gap: 12px; }
.kn-ask-q { align-self: flex-end; max-width: 82%; padding: 10px 15px; border-radius: 16px 16px 4px 16px; background: var(--acc-grad); color: #fff; font-size: 14.5px; line-height: 1.45; box-shadow: 0 6px 16px -8px var(--glow); word-break: break-word; }
.kn-ask-a { align-self: stretch; display: flex; flex-direction: column; gap: 14px; }
.kn-ask-thinking { flex-direction: row; align-items: center; gap: 10px; color: var(--muted); font-size: 13.5px; padding: 4px 2px; }
.kn-ask-prose { font-size: 14.5px; line-height: 1.62; color: var(--text); }
.kn-ask-prose p { margin: 0 0 10px; }
.kn-ask-prose p:last-child { margin-bottom: 0; }
.kn-ask-note { font-size: 13.5px; line-height: 1.5; color: var(--muted); }
.kn-ask-err { color: var(--danger, #e5484d); }
.kn-cite { display: inline-flex; align-items: center; justify-content: center; min-width: 17px; height: 17px; padding: 0 4px; margin: 0 1px; vertical-align: 2px; border: none; border-radius: 6px; background: var(--sel); color: var(--primary); font: 700 10.5px/1 -apple-system, system-ui, sans-serif; cursor: pointer; transition: background .12s, color .12s; }
.kn-cite:hover { background: var(--acc-fill); color: #fff; }
.kn-ask-src { display: flex; flex-direction: column; gap: 10px; }
.kn-ask-src-h { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 650; letter-spacing: .02em; text-transform: uppercase; color: var(--muted); }
.kn-ask-src-h .ic { width: 14px; height: 14px; }
.kn-ask-src-grid { padding: 0; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.kn-ask-srcc { cursor: pointer; gap: 6px; padding: 12px 13px; }
.kn-ask-srcc:hover { border-color: var(--primary); box-shadow: var(--shadow-2); }
.kn-ask-num { display: inline-flex; align-items: center; justify-content: center; width: 19px; height: 19px; border-radius: 6px; background: var(--acc-fill); color: #fff; font: 700 11px/1 -apple-system, system-ui, sans-serif; flex: none; }
.kn-ask-srctxt { font-size: 12.5px; color: var(--muted); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.kn-ask-bar { flex: none; border-top: 1px solid var(--line); padding: 12px 20px 14px; background: var(--panel); }
.kn-ask-field { display: flex; align-items: center; gap: 10px; height: 46px; padding: 0 8px 0 14px; border: 1px solid var(--line-strong); border-radius: 14px; background: var(--panel-2, var(--panel)); transition: border-color .13s, box-shadow .13s; }
.kn-ask-field:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
.kn-ask-ic { display: inline-flex; flex: none; color: var(--primary); }
.kn-ask-ic .ic { width: 17px; height: 17px; }
.kn-ask-input { flex: 1; min-width: 0; border: none; background: transparent; color: var(--text); font-size: 14.5px; outline: none; }
.kn-ask-input::placeholder { color: var(--text-dim); }
.kn-ask-send { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; border: none; border-radius: 10px; background: var(--acc-grad); color: #fff; cursor: pointer; box-shadow: 0 4px 12px -4px var(--glow); transition: filter .13s, transform .13s; }
.kn-ask-send:hover { filter: brightness(1.06); transform: translateY(-1px); }
.kn-ask-send:disabled { opacity: .5; cursor: default; transform: none; filter: none; }
.kn-ask-send .ic { width: 17px; height: 17px; }
.kn-ask-hint { margin-top: 8px; text-align: center; font-size: 11.5px; color: var(--text-dim); }
/* Верхняя строка: вид · область · достоверность · оценка · закреп · архив. С чипом достоверности
   (16.10) ряд вышел ~365 px при ~277 внутри карточки 311 px (4 колонки на 1440): точки и булавка
   уезжали за кромку. Не влезло — оценка с кнопками уходят второй строкой, прижатые вправо. */
.kn-card-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; row-gap: 6px; }
.kn-card-top > .kn-imp { margin-left: auto; }
/* …но второй строкой уезжали и КНОПКИ: кадр 21.10 — ряд действий висел под чипами справа, слева
   пусто (карточка 312, внутри 278: вид 66 + область 69 + «Проверено» 94 + зазоры = 245, оценке 42
   и двум кнопкам по 26 места нет). Закреп и архив теперь всегда в ПЕРВОЙ строке у правой кромки,
   ряд держит под них 68 px; переносятся только мета-чипы — «Проверено» и оценка второй строкой слева. */
.kn-card-top:has(> .kn-arch) { position: relative; padding-right: 68px; }
.kn-card-top:has(> .kn-arch) > .tw-spacer { display: none; }
.kn-card-top:has(> .kn-arch) > .kn-imp { margin-left: 0; }
.kn-card-top:has(> .kn-arch) > :is(.kn-pin, .kn-arch) { position: absolute; top: -3px; }
.kn-card-top:has(> .kn-arch) > .kn-pin { right: 34px; }
.kn-card-top:has(> .kn-arch) > .kn-arch { right: 0; }
.kn-badge { flex: none; height: 20px; display: inline-flex; align-items: center; padding: 0 9px; border-radius: 7px; font-size: 11px; font-weight: 700; letter-spacing: .01em;
  color: var(--primary); background: color-mix(in srgb, var(--primary) 13%, transparent); }
/* акцент бэйджа по типу знания (тонкие семантические оттенки, обе темы через color-mix/токены) */
.kn-badge.kn-kind-decision  { color: var(--info, var(--primary)); background: color-mix(in srgb, var(--info, var(--primary)) 13%, transparent); }
.kn-badge.kn-kind-lesson    { color: var(--warning); background: var(--warning-soft); }
.kn-badge.kn-kind-procedure { color: var(--ok); background: var(--ok-soft); }
.kn-badge.kn-kind-preference{ color: var(--primary-2, var(--primary)); background: color-mix(in srgb, var(--primary-2, var(--primary)) 15%, transparent); }
.kn-scope { flex: none; height: 20px; display: inline-flex; align-items: center; gap: 3px; padding: 0 6px 0 8px; border-radius: 7px; font-size: 11px; font-weight: 600;
  color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); cursor: pointer;
  transition: background .12s, color .12s, border-color .12s; }
.kn-scope:hover { background: var(--sel); color: var(--text); border-color: var(--line-strong); }
.kn-scope .ic { width: 12px; height: 12px; opacity: .6; margin-left: -1px; }
/* 0507 · статус правды записи — то же, что видит модель: «проверено» / «не проверено» / «опровергнуто» */
.kn-truth { --kt: var(--muted); flex: none; height: 20px; display: inline-flex; align-items: center; gap: 4px; padding: 0 8px; border-radius: 7px;
  font-size: 11px; font-weight: 650; border: none; cursor: pointer; color: var(--kt);
  background: color-mix(in srgb, var(--kt) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--kt) 22%, transparent);
  transition: background .12s; }
.kn-truth:hover { background: color-mix(in srgb, var(--kt) 18%, transparent); }
.kn-truth .ic { width: 12px; height: 12px; }
.kn-truth-verified { --kt: var(--ok); }
.kn-truth-refuted, .kn-truth-superseded { --kt: var(--danger); }
/* Пикер области «кто видит» — плавающее меню (Личное / Компании / Проекты / Все) */
.kn-scope-menu { position: fixed; z-index: 4200; min-width: 224px; max-width: 300px; max-height: 348px; overflow-y: auto; padding: 6px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 13px; box-shadow: 0 14px 44px rgba(0,0,0,.22), 0 2px 8px rgba(0,0,0,.10);
  animation: knScopeIn .13s cubic-bezier(.2,.7,.3,1); }
@keyframes knScopeIn { from { opacity: 0; transform: translateY(-5px) scale(.98); } to { opacity: 1; transform: none; } }
.kn-scope-sec { font-size: 10.5px; font-weight: 700; letter-spacing: .045em; text-transform: uppercase; color: var(--muted); padding: 9px 10px 4px; }
.kn-scope-sec:first-child { padding-top: 5px; }
.kn-scope-opt { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 10px; border: none; border-radius: 9px;
  background: transparent; color: var(--text); font-size: 13px; font-weight: 500; text-align: left; cursor: pointer; transition: background .1s; }
.kn-scope-opt:hover { background: var(--sel); }
.kn-scope-opt .ic { width: 15px; height: 15px; flex: none; color: var(--muted); }
.kn-scope-opt.on { font-weight: 650; color: var(--primary); }
.kn-scope-opt.on .ic { color: var(--primary); }
.kn-scope-nm { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-scope-ck { flex: none; width: 15px; height: 15px; display: inline-flex; align-items: center; justify-content: center; color: var(--primary); opacity: 0; transition: opacity .1s; }
.kn-scope-ck .ic { width: 15px; height: 15px; color: var(--primary); }
.kn-scope-opt.on .kn-scope-ck { opacity: 1; }
.kn-imp { flex: none; display: inline-flex; align-items: center; gap: 3px; }
.kn-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line-strong); transition: background .14s; }
.kn-dot.on { background: var(--primary); }
.kn-pin, .kn-arch { flex: none; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center; border: none; border-radius: 8px;
  background: transparent; color: var(--muted); cursor: pointer; transition: background .12s, color .12s; }
.kn-pin .ic, .kn-arch .ic { width: 15px; height: 15px; }
.kn-pin:hover { background: var(--sel); color: var(--primary); }
.kn-pin.on { color: var(--primary); }
.kn-arch:hover { background: var(--danger-soft); color: var(--danger); }
/* заголовок/тело — инлайн-правка по клику (contenteditable), БЕЗ карандаша/кнопок */
.kn-ttl { font-size: 15px; font-weight: 650; line-height: 1.3; color: var(--text); border-radius: 7px; padding: 2px 4px; margin: -2px -4px;
  cursor: text; outline: none; transition: background .12s, box-shadow .12s; white-space: pre-wrap; word-break: break-word; }
.kn-txt { font-size: 13.5px; line-height: 1.5; color: var(--muted); border-radius: 7px; padding: 2px 4px; margin: -2px -4px;
  cursor: text; outline: none; transition: background .12s, box-shadow .12s; white-space: pre-wrap; word-break: break-word; min-height: 20px; }
.kn-ttl:hover, .kn-txt:hover { background: var(--hover); }
.kn-ttl.editing, .kn-txt.editing { background: var(--panel-2); box-shadow: 0 0 0 2px var(--sel); cursor: text; }
.kn-txt:empty::before { content: "Добавьте описание…"; color: var(--text-dim); }
.kn-ttl.dirty, .kn-txt.dirty { box-shadow: 0 0 0 2px color-mix(in srgb, var(--warning) 40%, transparent); }
/* 🔴🔴 ФОРМА ЗАПИСИ (владелец 13.09.2026) — то, что реально читает МОДЕЛЬ: повод · причина ·
   лечение · пруф · запрет. До этого карточка рисовала только прозу, а форма — ради которой
   память и переписали — не была видна ни человеку, ни (в recall) самой модели. Правится
   инлайном, как заголовок и тело: писателя у формы тоже раньше не было. */
.kn-form { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 10px; margin-top: 2px;
  padding-top: 8px; border-top: 1px solid var(--line); }
.kn-form-lbl { font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  color: var(--text-dim); padding-top: 3px; white-space: nowrap; }
.kn-form-lbl.no { color: var(--danger); }
.kn-form-v { font-size: 13px; line-height: 1.45; color: var(--text); border-radius: 6px; padding: 2px 4px; margin: -2px -4px;
  cursor: text; outline: none; transition: background .12s, box-shadow .12s; white-space: pre-wrap; word-break: break-word; }
.kn-form-v:hover { background: var(--hover); }
.kn-form-v.editing { background: var(--panel-2); box-shadow: 0 0 0 2px var(--sel); }
.kn-form-v.dirty { box-shadow: 0 0 0 2px color-mix(in srgb, var(--warning) 40%, transparent); }
/* Простыня тела на карточке — СВЁРНУТА: сверху то, что читает модель (форма и адреса).
   Маска вместо «…»: видно, что текст продолжается, и слова не рвутся. */
.kn-txt.clamped { max-height: 6.4em; overflow: hidden;
  -webkit-mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 62%, transparent 100%); }
.kn-more { align-self: flex-start; height: 22px; padding: 0 8px; border: 0; border-radius: 6px;
  background: transparent; color: var(--primary); font-size: 12px; font-weight: 600; cursor: pointer;
  transition: background .12s; }
.kn-more:hover { background: var(--sel); }
.kn-files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.kn-file { height: 20px; max-width: 100%; display: inline-flex; align-items: center; padding: 0 7px; border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--line); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-card-foot { display: flex; align-items: center; gap: 10px; margin-top: 2px; }
.kn-tags { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 6px; }
.kn-tag { height: 20px; display: inline-flex; align-items: center; padding: 0 8px; border-radius: 6px; font-size: 11px; font-weight: 600;
  color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); }
.kn-recall { flex: none; display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 600; color: var(--primary-2, var(--primary)); }
.kn-recall .ic { width: 13px; height: 13px; }

/* ── 🔴🔴 КАНОН ПРОЕКТА (CLIE-604·3) ─────────────────────────────────────────────
   Вкладка «Канон» того же раздела: «что уже есть и чем обязана пользоваться новая вещь».
   Акцент раздела несёт ТОЧКА + слово (правило CLIE-483: никаких левых полосок-реек), высоты
   ряда — общие токены --ctl-* (CLIE-505), ширины не прибиты, вложенных капов со скроллом нет
   (CLIE-620): длинный канон прокручивает сама панель .kn-body. Обе темы — на токенах. */
.kn-canon-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 14px 16px 4px; }
.kn-canon-find { position: relative; flex: 1 1 260px; min-width: 0; display: flex; align-items: center; }
.kn-canon-find-ic { position: absolute; left: 10px; display: flex; color: var(--muted); pointer-events: none; }
.kn-canon-find-ic .ic { width: 15px; height: 15px; }
.kn-canon-input { height: var(--ctl-h); min-width: 0; width: 100%; box-sizing: border-box; padding: 0 10px; border-radius: var(--ctl-r);
  border: 1px solid var(--line); background: var(--panel); color: var(--text); font-size: var(--ctl-fs); outline: none;
  transition: border-color var(--dur-1) ease, box-shadow var(--dur-1) ease; }
.kn-canon-find .kn-canon-input { padding-left: 32px; }
.kn-canon-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 14%, transparent); }
.kn-canon-seg { height: var(--ctl-h); }
.kn-canon-add { height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs); }
.kn-canon-hint { padding: 2px 16px 10px; font-size: 12px; line-height: 1.5; color: var(--muted); }

/* строка создания новой сути — не модалка, прямо в списке (правило «нажал → изменил») */
.kn-canon-new { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 16px 12px; padding: 10px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); }
.kn-canon-new .kn-canon-input { flex: 1 1 160px; }
.kn-canon-new .kn-canon-input-wide { flex: 2 1 260px; }
.kn-canon-new .kn-add { height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs); }

.kn-canon-group { padding: 0 16px 6px; }
.kn-canon-gt { display: flex; align-items: center; gap: 8px; margin: 10px 0 8px; font-size: 12px; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.kn-canon-gn { display: inline-flex; align-items: center; height: 18px; padding: 0 7px; border-radius: 9px;
  background: var(--panel-2); border: 1px solid var(--line); font-size: 11px; font-weight: 700; letter-spacing: 0; }
.kn-canon-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); gap: 12px; }

.kn-canon-card { display: flex; flex-direction: column; gap: 8px; padding: 14px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow-1);
  transition: box-shadow var(--dur-1) ease, border-color var(--dur-1) ease; }
.kn-canon-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow-2, var(--shadow-1)); }
.kn-canon-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* акцент раздела = круглая точка, а не полоса слева */
.kn-canon-dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--muted); }
.kn-canon-gdot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--muted); }
[data-kncdot="design"] { background: var(--cm-7c5cff, #7c5cff); }
[data-kncdot="logic"] { background: #1f9d55; }
[data-kncdot="data"] { background: #c2761b; }
[data-kncdot="realtime"] { background: #0a84ff; }
[data-kncdot="ai"] { background: #c2418a; }
[data-kncdot="process"] { background: #5b6b7c; }
.kn-canon-ttl { min-width: 0; font-size: 14.5px; font-weight: 650; color: var(--text); border-radius: 6px; padding: 1px 3px; margin: -1px -3px;
  cursor: text; transition: background var(--dur-1) ease; }
.kn-canon-ttl:hover, .kn-canon-what:hover { background: var(--panel-2); }
.kn-canon-ttl.editing, .kn-canon-what.editing, .kn-canon-must.editing, .kn-canon-forb.editing {
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--primary); outline: none; white-space: pre-wrap; }
.kn-canon-key { flex: none; height: 19px; display: inline-flex; align-items: center; padding: 0 7px; border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--line); }
.kn-canon-guard { flex: none; display: inline-flex; align-items: center; gap: 4px; height: 20px; padding: 0 8px; border-radius: 6px;
  font-size: 11px; font-weight: 600; }
.kn-canon-guard .ic { width: 12px; height: 12px; }
.kn-canon-guard.on { color: var(--ok, #1f9d55); background: color-mix(in srgb, var(--ok, #1f9d55) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok, #1f9d55) 22%, transparent); }
.kn-canon-guard.off { color: var(--muted); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
/* 📍 0330 · ГДЕ СУТЬ ДЕЙСТВУЕТ — чип-кнопка отдельной строкой под заголовком (в верхней строке
   узкой карточки он сжимался до «Client…»): всё пространство · компания · проект. Нажал → пикер. */
.kn-canon-meta { display: flex; align-items: center; gap: 6px; min-width: 0; margin-top: -2px; }
.kn-canon-bind { flex: 0 1 auto; min-width: 0; max-width: 100%; display: inline-flex; align-items: center; gap: 5px;
  height: 22px; padding: 0 8px; border: 0; border-radius: 7px; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line); color: var(--text-2, var(--text)); font: inherit; font-size: 11.5px;
  font-weight: 600; cursor: pointer; transition: background var(--dur-1) ease, box-shadow var(--dur-1) ease, color var(--dur-1) ease; }
.kn-canon-bind span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-canon-bind .ic { flex: none; width: 12px; height: 12px; color: var(--muted); }
.kn-canon-bind:hover { color: var(--text); background: color-mix(in srgb, var(--primary) 8%, var(--panel-2));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 32%, var(--line)); }
.kn-canon-bind:hover .ic { color: var(--primary); }
.kn-canon-bind:focus-visible, .kn-canon-always:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
/* «Всегда» — прогрессивное раскрытие: выключенный переключатель проявляется у карточки под
   курсором/фокусом, включённый виден всегда. На сенсорных экранах наведения нет — виден сразу. */
.kn-canon-always { flex: none; display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 9px;
  border: 0; border-radius: 7px; background: transparent; box-shadow: inset 0 0 0 1px var(--line); color: var(--muted);
  font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer; opacity: 0;
  transition: opacity var(--dur-1) ease, background var(--dur-1) ease, color var(--dur-1) ease, box-shadow var(--dur-1) ease; }
.kn-canon-always .ic { width: 12px; height: 12px; }
.kn-canon-card:hover .kn-canon-always, .kn-canon-card:focus-within .kn-canon-always, .kn-canon-always.on { opacity: 1; }
.kn-canon-always:hover { color: var(--text); background: var(--panel-2); }
.kn-canon-always.on { color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 26%, transparent); }
@media (hover: none) { .kn-canon-always { opacity: 1; } }
.kn-canon-where { max-width: 240px; }
.kn-canon-where span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-canon-where.on { color: var(--primary); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, var(--line)); }
.kn-canon-what { font-size: 13px; line-height: 1.5; color: var(--text-2, var(--text)); border-radius: 6px; padding: 1px 3px; margin: -1px -3px; cursor: text; }
.kn-canon-sec { display: flex; flex-direction: column; gap: 3px; }
.kn-canon-lbl { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.kn-canon-impl, .kn-canon-must, .kn-canon-forb { margin: 0; padding: 0 0 0 15px; display: flex; flex-direction: column; gap: 3px;
  font-size: 12.5px; line-height: 1.5; color: var(--text-2, var(--text)); border-radius: 6px; }
.kn-canon-must, .kn-canon-forb { cursor: text; }
.kn-canon-impl { list-style: none; padding-left: 0; }
.kn-canon-impl li { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.kn-canon-impl code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 5px; padding: 0 5px; word-break: break-all; }
.kn-canon-layer { flex: none; font-size: 11px; font-weight: 700; color: var(--primary); }
.kn-canon-sym { color: var(--muted); font-size: 12px; }
.kn-canon-none { color: var(--muted); font-style: italic; list-style: none; margin-left: -15px; }
.kn-canon-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 2px; padding-top: 8px; border-top: 1px solid var(--line); }
.kn-canon-grd, .kn-canon-rule { font-size: 11.5px; color: var(--muted); }
.kn-canon-rule { font-weight: 600; }

/* Снять с вооружения — действие человека прямо на карточке: канон, из которого нельзя ничего
   вычеркнуть, протухает и начинает врать. Кнопка спокойная, проявляется на наведении. */
.kn-canon-dep { flex: none; height: 22px; padding: 0 8px; border-radius: 7px; font-size: 11.5px; font-weight: 600;
  color: var(--muted); background: transparent; border: 1px solid transparent; cursor: pointer;
  opacity: 0; transition: opacity var(--dur-1) ease, color var(--dur-1) ease, background var(--dur-1) ease, border-color var(--dur-1) ease; }
.kn-canon-card:hover .kn-canon-dep, .kn-canon-dep:focus-visible { opacity: 1; }
.kn-canon-dep:hover { color: var(--text); background: var(--panel-2); border-color: var(--line); }
.kn-canon-card.dep { opacity: .62; }
.kn-canon-card.dep .kn-canon-dep { opacity: 1; color: var(--primary); }
.kn-canon-old.on { color: var(--primary); background: var(--sel); }

/* Онбординг пустого канона: так вкладку видит КАЖДЫЙ новый проект (и любой другой вайбкодер).
   Пусто — это ответ, и он говорится словами: что это, с чего начать, как подключить своего ИИ. */
.kn-canon-onb .kn-empty-d { max-width: 460px; }
.kn-canon-steps { margin: 4px 0 2px; padding: 0; list-style: none; counter-reset: cst; display: flex; flex-direction: column; gap: 8px;
  max-width: 460px; text-align: left; }
.kn-canon-steps li { counter-increment: cst; position: relative; padding-left: 30px; font-size: 12.5px; line-height: 1.5; color: var(--text-2, var(--text)); }
.kn-canon-steps li::before { content: counter(cst); position: absolute; left: 0; top: 0; width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700;
  color: var(--primary); background: var(--sel); }
.kn-canon-steps b { font-weight: 650; color: var(--text); }
.kn-canon-onb-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: center; margin-top: 6px; }
.kn-canon-onb-acts .ghost.small { display: inline-flex; align-items: center; gap: 6px; height: var(--ctl-h); padding: 0 12px;
  border-radius: var(--ctl-r); font-size: var(--ctl-fs); }
.kn-canon-onb-acts .ghost.small .ic { width: 15px; height: 15px; }

/* ═══ ВИКИ КОМПАНИИ (вкладка «Вики») ══════════════════════════════════════════════════
   Две колонки: дерево статей ‖ страница. Ширина колонки НЕ прибита числом — её тянет мышью
   общий механизм окон (WIN_PANES, правило CRMC-406), поэтому здесь только БАЗОВАЯ ширина
   через flex-basis: инлайн-стиль от хваталки её перебивает. Скроллятся сами колонки
   (flex + min-height:0), капов max-height в px нет вовсе (CLIE-620). */
.kn-wiki { display: flex; align-items: stretch; height: 100%; min-height: 0; }
.kn-wiki-side { flex: 0 0 280px; min-width: 200px; display: flex; flex-direction: column; min-height: 0;
  border-right: 1px solid var(--line); background: var(--panel-2); }
/* CLIE-1946 · светлая: --panel-2 = холст — боковая колонка вики сливалась с текстом (1.00). Тон чуть
   темнее холста, а не белый: ховер строки (--panel-3 = белый), поиск и выбранная (--sel) остаются видны. */
html[data-theme="light"] .kn-wiki-side { background: color-mix(in srgb, var(--bg) 95%, var(--text)); }
.kn-wiki-side-top { flex: none; display: flex; align-items: center; gap: 8px; padding: 12px 12px 10px; }
.kn-wiki-find { flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 7px; height: var(--ctl-h);
  padding: 0 10px; border: 1px solid var(--line); border-radius: var(--ctl-r); background: var(--panel); }
.kn-wiki-find:focus-within { border-color: var(--primary); }
.kn-wiki-find-ic { display: flex; color: var(--muted); flex: none; }
.kn-wiki-find-ic .ic { width: 15px; height: 15px; }
/* Поле внутри рамки .kn-wiki-find: базовый `input { padding: 11px 14px }` добавлял 14 px слева
   и справа поверх паддинга рамки и значка — текст начинался в 48 px от кромки (x 116 → 164),
   подсказку резало до «Поиск по с» (кадр 21.10). Отступы держит рамка; поле — во всю её высоту. */
.kn-wiki-input { flex: 1 1 auto; min-width: 0; align-self: stretch; padding: 0; border: 0; outline: 0; background: none;
  color: var(--text); font-size: var(--ctl-fs); text-overflow: ellipsis; }
.kn-wiki-input::placeholder { color: var(--muted); }
/* Пустое поле: нативный «×» поиска невидим, но держит место. Кадр 21.10: поле x172–284, подсказка
   обрывалась на x≈264 («Поиск по вик…») — ~20 px справа съедал резерв кнопки, а целиком подсказке
   нужно до x≈271. Резерв снимаем, пока поле пустое; набран текст — «×» на месте. */
.kn-wiki-input:placeholder-shown::-webkit-search-cancel-button { display: none; }
.kn-wiki-new { flex: none; display: inline-flex; align-items: center; gap: 5px; height: var(--ctl-h); padding: 0 11px;
  border: 0; border-radius: var(--ctl-r); background: var(--acc-grad); color: #fff; font-size: var(--ctl-fs); font-weight: 600;
  cursor: pointer; box-shadow: 0 4px 12px -5px var(--glow); transition: filter .12s ease, transform .1s ease;
  min-width: max-content; }
.kn-wiki-new:hover { filter: brightness(1.06); }
.kn-wiki-new:active { transform: scale(.97); }
.kn-wiki-new .ic { width: 14px; height: 14px; }
.kn-wiki-tree { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 2px 8px 16px; }
/* Строка статьи: отступ ветки — ДОЛЯ шага, а не своё число на каждом уровне. */
.kn-wiki-row { display: flex; align-items: center; gap: 6px; width: 100%; padding: 6px 8px; border-radius: 9px;
  cursor: pointer; user-select: none; padding-left: calc(8px + var(--wdepth, 0) * 14px);
  transition: background .12s ease, color .12s ease; }
.kn-wiki-row:hover { background: var(--panel-3); }
.kn-wiki-row.on { background: var(--sel); }
.kn-wiki-row.on .kn-wiki-row-t { color: var(--text); font-weight: 600; }
.kn-wiki-row.dragging { opacity: .45; }
.kn-wiki-row.drop { background: color-mix(in srgb, var(--primary) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 42%, transparent); }
.kn-wiki-row-t { flex: 1 1 auto; min-width: 0; font-size: 13.5px; color: var(--text-2, var(--text));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kn-wiki-chev { flex: none; width: 18px; height: 18px; display: flex; align-items: center; justify-content: center;
  border: 0; background: none; padding: 0; color: var(--muted); cursor: pointer; border-radius: 5px;
  transition: transform .14s ease, background .12s ease; }
.kn-wiki-chev.on { transform: rotate(90deg); }
.kn-wiki-chev:hover { background: var(--panel); color: var(--text); }
.kn-wiki-chev .ic { width: 13px; height: 13px; }
.kn-wiki-chev.empty { pointer-events: none; }
/* Признак состояния — ТОЧКА, а не полоска слева (правило CLIE-483). */
.kn-wiki-dot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--muted); }
.kn-wiki-dot.draft { background: var(--muted); }
.kn-wiki-dot.stale { background: var(--warn, #e5a23c); }
.kn-wiki-rowadd { flex: none; width: 20px; height: 20px; display: flex; align-items: center; justify-content: center;
  border: 0; background: none; padding: 0; color: var(--muted); cursor: pointer; border-radius: 6px; opacity: 0;
  transition: opacity .12s ease, background .12s ease, color .12s ease; }
.kn-wiki-row:hover .kn-wiki-rowadd, .kn-wiki-rowadd:focus-visible { opacity: 1; }
.kn-wiki-rowadd:hover { background: var(--panel); color: var(--text); }
.kn-wiki-rowadd .ic { width: 13px; height: 13px; }
/* ↕️ РУЧНОЙ ПОРЯДОК (CLIE-1683): кромка строки = «поставить рядом», середина = «внутрь».
   Полосу рисует САМА строка (inset-тень), отдельного слоя-призрака не заводим — он бы
   перехватывал события и ломал dragover у соседей. */
.kn-wiki-row.drop-before { box-shadow: inset 0 2px 0 0 var(--primary); }
.kn-wiki-row.drop-after { box-shadow: inset 0 -2px 0 0 var(--primary); }
/* 🔎 СРЕЗ ВЫДАЧИ НАЗВАН И ИМЕЕТ ВЫХОД (канон CLIE-1582). */
.kn-wiki-more { display: block; width: 100%; margin: 6px 0 2px; padding: 8px 10px; border-radius: 9px;
  background: var(--panel-2); border: 1px dashed var(--line); color: var(--primary-2, var(--primary));
  font-size: 12px; font-weight: 600; cursor: pointer; text-align: center; }
.kn-wiki-more:hover { background: color-mix(in srgb, var(--primary) 10%, var(--panel-2)); }
.kn-wiki-more[disabled] { opacity: .6; cursor: default; }
.kn-wiki-cap { padding: 6px 10px 2px; font-size: 11.5px; color: var(--muted); }
.kn-wiki-hit { display: flex; flex-direction: column; gap: 2px; padding: 8px 10px; border-radius: 9px; cursor: pointer; }
.kn-wiki-hit:hover { background: var(--panel-3); }
.kn-wiki-hit.on { background: var(--sel); }
.kn-wiki-hit-t { font-size: 13.5px; font-weight: 600; color: var(--text); }
.kn-wiki-hit-s { font-size: 12px; color: var(--muted); line-height: 1.4; }
.kn-wiki-note { padding: 22px 14px; font-size: 13px; color: var(--muted); line-height: 1.5; text-align: center; }
.kn-wiki-note.err { color: var(--danger, #e0533d); }
/* ── Страница статьи ── */
.kn-wiki-main { flex: 1 1 auto; min-width: 0; min-height: 0; overflow-y: auto; }
.kn-wiki-page { max-width: 860px; margin: 0 auto; padding: 20px 28px 64px; display: flex; flex-direction: column; gap: 12px; }
.kn-wiki-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.kn-wiki-crumbs { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; min-width: 0; }
.kn-wiki-crumb { border: 0; background: none; padding: 2px 4px; border-radius: 6px; cursor: pointer;
  font-size: 12.5px; color: var(--muted); max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-wiki-crumb:hover { background: var(--panel-2); color: var(--text); }
.kn-wiki-crumb-sep { display: flex; color: var(--muted); opacity: .6; }
.kn-wiki-crumb-sep .ic { width: 12px; height: 12px; }
.kn-wiki-acts { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.kn-wiki-act { display: inline-flex; align-items: center; gap: 6px; height: var(--ctl-h); padding: 0 11px;
  border: 1px solid var(--line); border-radius: var(--ctl-r); background: var(--panel); color: var(--text);
  font-size: var(--ctl-fs); font-weight: 550; cursor: pointer; min-width: max-content;
  transition: background .12s ease, border-color .12s ease, color .12s ease; }
.kn-wiki-act:hover { background: var(--panel-3); }
.kn-wiki-act[disabled] { opacity: .5; cursor: default; }
.kn-wiki-act.danger:hover { color: var(--danger, #e0533d); border-color: color-mix(in srgb, var(--danger, #e0533d) 40%, transparent); }
.kn-wiki-act .ic { width: 14px; height: 14px; }
/* «Все статьи» — выход из статьи к дереву; нужен только телефону (≤760 ниже), на компьютере дерево рядом. */
.kn-wiki-act.kn-wiki-back { display: none; }
.kn-wiki-ttl { font-size: 27px; font-weight: 700; letter-spacing: -.02em; color: var(--text); line-height: 1.2;
  border-radius: 10px; padding: 2px 6px; margin-left: -6px; outline: none; }
.kn-wiki-ttl.can { cursor: text; transition: background .12s ease, box-shadow .12s ease; }
.kn-wiki-ttl.can:hover { background: var(--panel-2); }
.kn-wiki-ttl.editing { background: var(--panel-2); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 40%, transparent); }
.kn-wiki-ttl.dirty { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn, #e5a23c) 50%, transparent); }
.kn-wiki-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.kn-wiki-chip { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px; border-radius: 8px;
  background: var(--panel-2); border: 1px solid var(--line); font-size: 11.5px; color: var(--muted); }
.kn-wiki-chip .ic { width: 12px; height: 12px; }
.kn-wiki-chip.ok { color: var(--ok, #2fae60); border-color: color-mix(in srgb, var(--ok, #2fae60) 32%, transparent);
  background: color-mix(in srgb, var(--ok, #2fae60) 10%, transparent); }
.kn-wiki-chip.lvl { color: var(--text); }
.kn-wiki-chip.st-published { color: var(--ok, #2fae60); border-color: color-mix(in srgb, var(--ok, #2fae60) 32%, transparent);
  background: color-mix(in srgb, var(--ok, #2fae60) 10%, transparent); }
.kn-wiki-chip.st-archived { opacity: .75; }
/* 🗂 АДРЕС ЗНАНИЯ (CLIE-1683). Чип базы — не подпись, а ВХОД: у него курсор, наведение и
   фокус-кольцо кнопки. Нет права переложить — он гаснет, но остаётся виден: пропавшая
   кнопка читается как «сломалось» (правило «видно ≠ работает» наоборот). */
button.kn-wiki-chip { font: inherit; font-size: 11.5px; cursor: default; }
.kn-wiki-chip.base { color: var(--text); }
.kn-wiki-chip.base.can { cursor: pointer; }
.kn-wiki-chip.base.can:hover { background: color-mix(in srgb, var(--primary) 12%, var(--panel-2));
  border-color: color-mix(in srgb, var(--primary) 38%, transparent); color: var(--primary-2, var(--primary)); }
.kn-wiki-chip.base.can:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 1px; }
.kn-wiki-chip.base[disabled] { opacity: .6; }
/* ⏳ Чип срока пересмотра — ТОТ ЖЕ размерный класс и те же состояния, что у чипа базы:
   второго языка интерактивных чипов в карточке не заводим (правило единого контрола). */
.kn-wiki-chip.rev { color: var(--text); }
.kn-wiki-chip.rev.can { cursor: pointer; }
.kn-wiki-chip.rev.can:hover { background: color-mix(in srgb, var(--primary) 12%, var(--panel-2));
  border-color: color-mix(in srgb, var(--primary) 38%, transparent); color: var(--primary-2, var(--primary)); }
.kn-wiki-chip.rev.can:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 1px; }
.kn-wiki-chip.rev[disabled] { opacity: .6; }
/* «Устарело» — иконка + СЛОВА + мягкая подложка (акцент без левой рейки, CLIE-483). */
.kn-wiki-stale { display: flex; align-items: center; gap: 9px; padding: 10px 12px; border-radius: 12px;
  background: color-mix(in srgb, var(--warn, #e5a23c) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn, #e5a23c) 26%, transparent);
  font-size: 12.5px; color: var(--text); }
.kn-wiki-stale .ic { width: 15px; height: 15px; color: var(--warn, #e5a23c); flex: none; }
.kn-wiki-stale span { flex: 1 1 auto; min-width: 0; }
.kn-wiki-stale-b { flex: none; height: 28px; padding: 0 12px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--panel); color: var(--text); font-size: 12px; font-weight: 560; cursor: pointer; min-width: max-content; }
.kn-wiki-stale-b:hover { background: var(--panel-3); }
.kn-wiki-bodywrap { min-height: 220px; }
.kn-wiki-body { border-radius: 12px; padding: 8px 10px; margin-left: -10px; outline: none; }
.kn-wiki-body.can { cursor: text; transition: background .12s ease; }
.kn-wiki-body.can:hover { background: var(--panel-2); }
.kn-wiki-body-ph { color: var(--muted); font-size: 14px; }
.kn-wiki-editor .rd-box { border-radius: 12px; }
/* ── История версий ── */
.kn-wiki-hist { display: grid; grid-template-columns: minmax(0, 260px) minmax(0, 1fr); gap: 16px; align-items: start; }
@media (max-width: 900px) { .kn-wiki-hist { grid-template-columns: minmax(0, 1fr); } }
.kn-wiki-revs { display: flex; flex-direction: column; gap: 4px; }
.kn-wiki-rev { display: flex; align-items: flex-start; gap: 9px; width: 100%; padding: 9px 10px; border-radius: 10px;
  border: 1px solid transparent; background: none; cursor: pointer; text-align: left;
  transition: background .12s ease, border-color .12s ease; }
.kn-wiki-rev:hover { background: var(--panel-2); }
.kn-wiki-rev.on { background: var(--sel); border-color: color-mix(in srgb, var(--primary) 28%, transparent); }
.kn-wiki-rev-n { flex: none; font-size: 11.5px; font-weight: 700; color: var(--muted); padding-top: 1px; }
.kn-wiki-rev-m { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.kn-wiki-rev-t { font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kn-wiki-rev-s { font-size: 11.5px; color: var(--muted); }
.kn-wiki-revprev { min-width: 0; }
.kn-wiki-revhead { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.kn-wiki-revhead b { font-size: 14px; color: var(--text); }

/* ═══ ВИКИ 2.0 (CLIE-1117): пространства · отбор · метки · сейф доступов ══════════════════
   Всё на существующих токенах (--panel/--line/--text/--muted/--primary/--warning/--danger) и на
   размерном классе ряда (--ctl-h/--ctl-r/--ctl-fs, канон control-size): своих чисел высоты и
   своих цветов здесь нет, поэтому обе темы работают БЕЗ отдельных правил для светлой —
   оверрайды живут у самих токенов (html[data-theme="light"] выше).
   🔴 Акцентные ЧЕРНИЛА на акцентной подложке — var(--primary-2), а не var(--primary)
   (канон contrast-runtime-audit: --primary в тёмной теме сам служит чернилами на холсте). */

/* ── шапка колонки: какая это база знаний (пикер ‖ подпись у запертого пространства) ── */
.kn-wiki-space { flex: none; padding: 10px 12px 0; }
/* Шапка базы забирает верхний отступ строки поиска себе — иначе между ними двойной воздух. */
.kn-wiki-space + .kn-wiki-side-top { padding-top: 8px; }
.kn-wiki-space-btn { display: flex; align-items: center; gap: 7px; width: 100%; min-width: 0; height: var(--ctl-h);
  padding: 0 9px; border: 1px solid var(--line); border-radius: var(--ctl-r); background: var(--panel);
  color: var(--text); font-size: var(--ctl-fs); font-weight: 600; cursor: pointer; text-align: left;
  transition: background .14s ease, border-color .14s ease; }
.kn-wiki-space-btn:hover { background: var(--panel-3); border-color: var(--line-strong); }
.kn-wiki-space-btn > .ic { width: 15px; height: 15px; flex: none; color: var(--muted); }
.kn-wiki-space-btn > .ic:last-child { margin-left: auto; width: 13px; height: 13px; }
.kn-wiki-space-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-wiki-space-n { flex: none; font-size: 11.5px; font-weight: 500; color: var(--muted); }
.kn-wiki-space-lbl { display: flex; align-items: center; gap: 7px; height: var(--ctl-h); padding: 0 9px;
  border-radius: var(--ctl-r); background: var(--panel-3); color: var(--text);
  font-size: var(--ctl-fs); font-weight: 600; }
.kn-wiki-space-lbl .ic { width: 15px; height: 15px; color: var(--muted); flex: none; }

/* ── отбор и порядок: фишки-состояния + КАНОНИЧЕСКИЙ сегмент .cc-seg (своей дорожки нет) ── */
.kn-wiki-filters { flex: none; display: flex; flex-direction: column; gap: 7px; padding: 0 12px 8px; }
.kn-wiki-filters:empty { display: none; }
.kn-wiki-fchips { display: flex; align-items: center; flex-wrap: wrap; gap: 5px; }
.kn-wiki-fchip { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted); font-size: 11.5px; font-weight: 600;
  cursor: pointer; transition: background .14s ease, color .14s ease, border-color .14s ease; }
.kn-wiki-fchip:hover { color: var(--text); border-color: var(--line-strong); }
.kn-wiki-fchip.on { color: var(--primary-2, var(--primary)); border-color: color-mix(in srgb, var(--primary) 44%, transparent);
  background: color-mix(in srgb, var(--primary) 13%, transparent); }
.kn-wiki-fn { font-size: 10.5px; font-weight: 700; opacity: .75; font-variant-numeric: tabular-nums; }
.kn-wiki-freset { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 8px; border-radius: 8px;
  border: 1px dashed var(--line-strong); background: none; color: var(--muted); font-size: 11.5px; font-weight: 600; cursor: pointer; }
.kn-wiki-freset:hover { color: var(--text); background: var(--hover); }
.kn-wiki-freset .ic { width: 11px; height: 11px; }
.kn-wiki-sort { align-self: flex-start; max-width: 100%; }

/* ── плоский список (сервер сказал flat): без шевронов и отступов, зато с путём в подписи ── */
.kn-wiki-flat { display: flex; flex-direction: column; gap: 1px; padding: 7px 9px; border-radius: 9px; cursor: pointer;
  transition: background .12s ease; }
.kn-wiki-flat:hover { background: var(--panel-3); }
.kn-wiki-flat.on { background: var(--sel); }
.kn-wiki-flat-t { display: flex; align-items: center; gap: 6px; min-width: 0; font-size: 13.5px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kn-wiki-flat.on .kn-wiki-flat-t { font-weight: 600; }
.kn-wiki-flat-p { font-size: 11px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.kn-wiki-dot.sec { background: var(--primary); }

/* ── метки статьи: чип-вход в отбор + крестик «убрать» ── */
.kn-wiki-ptag { display: inline-flex; align-items: center; height: 24px; border-radius: 8px; overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--primary) 34%, transparent);
  background: color-mix(in srgb, var(--primary) 10%, transparent); }
.kn-wiki-ptag > button { border: 0; background: none; padding: 0 8px; height: 100%; cursor: pointer;
  color: var(--primary-2, var(--primary)); font-size: 11.5px; font-weight: 600; }
.kn-wiki-ptag > button:hover { background: color-mix(in srgb, var(--primary) 16%, transparent); }
.kn-wiki-ptag-x { display: inline-flex; align-items: center; padding: 0 6px;
  border-left: 1px solid color-mix(in srgb, var(--primary) 26%, transparent); }
.kn-wiki-ptag-x .ic { width: 10px; height: 10px; }
button.kn-wiki-ptag.add { border-style: dashed; border-color: var(--line-strong); background: none; padding: 0 9px; gap: 5px;
  color: var(--muted); font-size: 11.5px; font-weight: 600; cursor: pointer; }
button.kn-wiki-ptag.add:hover { color: var(--text); background: var(--hover); }
button.kn-wiki-ptag.add .ic { width: 12px; height: 12px; }

/* ── 🔐 сейф доступов статьи ── */
.kn-wiki-sec:empty { display: none; }
.kn-wiki-sec-box { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; padding: 14px 16px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--panel-2); }
.kn-wiki-sec-h { display: flex; align-items: center; gap: 8px; }
.kn-wiki-sec-h > .ic { width: 16px; height: 16px; color: var(--muted); }
.kn-wiki-sec-t { font-size: 14px; font-weight: 650; color: var(--text); }
.kn-wiki-sec-n { min-width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center;
  padding: 0 6px; border-radius: 999px; background: var(--panel-3); color: var(--muted);
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums; }
.kn-wiki-sec-warn { display: flex; align-items: flex-start; gap: 9px; padding: 9px 11px; border-radius: 11px;
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 26%, transparent);
  font-size: 12.5px; line-height: 1.45; color: var(--text); }
.kn-wiki-sec-warn .ic { width: 15px; height: 15px; flex: none; color: var(--warning); margin-top: 1px; }
.kn-wiki-sec-list { display: flex; flex-direction: column; gap: 6px; }
.kn-wiki-sec-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px 11px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--panel); }
.kn-wiki-sec-ic { flex: none; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
  border-radius: 9px; background: var(--panel-3); color: var(--muted); }
.kn-wiki-sec-ic .ic { width: 15px; height: 15px; }
.kn-wiki-sec-m { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.kn-wiki-sec-ttl { font-size: 13.5px; font-weight: 600; color: var(--text); }
.kn-wiki-sec-sub { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; font-size: 11.5px; color: var(--muted); }
.kn-wiki-sec-url { color: var(--primary-2, var(--primary)); text-decoration: none; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-wiki-sec-url:hover { text-decoration: underline; }
.kn-wiki-sec-lvl { padding: 1px 6px; border-radius: 6px; background: var(--panel-3); }
.kn-wiki-sec-valrow { display: flex; align-items: center; gap: 8px; min-width: 0; margin-top: 2px; }
.kn-wiki-sec-mask { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; letter-spacing: .12em; color: var(--muted); }
.kn-wiki-sec-open { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; min-width: 0; width: 100%; }
.kn-wiki-sec-in { min-width: 0; flex: 1 1 220px; height: var(--ctl-h); padding: 0 9px; border: 1px solid var(--line-strong);
  border-radius: var(--ctl-r); background: var(--panel-2); color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; }
.kn-wiki-sec-left { flex: none; font-size: 11.5px; font-weight: 700; color: var(--warning); font-variant-numeric: tabular-nums; }
.kn-wiki-sec-aud { font-size: 11px; color: var(--muted); }
.kn-wiki-sec-acts { flex: none; display: flex; align-items: center; flex-wrap: wrap; gap: 5px; justify-content: flex-end; }
.kn-wiki-sec-b { display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 9px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); font-size: 11.5px; font-weight: 600;
  cursor: pointer; transition: background .14s ease, color .14s ease, border-color .14s ease; }
.kn-wiki-sec-b:hover { color: var(--text); background: var(--panel-3); border-color: var(--line-strong); }
.kn-wiki-sec-b[disabled] { opacity: .45; cursor: default; }
.kn-wiki-sec-b.danger:hover { color: var(--danger-ink); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }
.kn-wiki-sec-b .ic { width: 13px; height: 13px; }

/* форма «завести/поправить доступ» — ВНУТРИ блока, не модалкой: соседние доступы видно */
.kn-wiki-sec-form { display: flex; flex-direction: column; gap: 9px; padding: 12px; border-radius: 12px;
  border: 1px solid var(--line-strong); background: var(--panel); }
.kn-wiki-sec-f2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 9px; }
@media (max-width: 760px) { .kn-wiki-sec-f2 { grid-template-columns: minmax(0, 1fr); } }
.kn-wiki-sec-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.kn-wiki-sec-f > span { font-size: 11.5px; font-weight: 600; color: var(--muted); }
.kn-wiki-sec-f input, .kn-wiki-sec-f select { width: 100%; box-sizing: border-box; height: var(--ctl-h); padding: 0 9px;
  border: 1px solid var(--line); border-radius: var(--ctl-r); background-color: var(--panel-2); color: var(--text);
  font-size: var(--ctl-fs); } .kn-wiki-sec-f select { padding-right: 34px; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.kn-wiki-sec-f input:focus, .kn-wiki-sec-f select:focus { outline: none; border-color: var(--primary); }
.kn-wiki-sec-seg { align-self: flex-start; max-width: 100%; }
.kn-wiki-sec-facts { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; margin-top: 2px; }
.kn-wiki-act.go { border-color: color-mix(in srgb, var(--primary) 46%, transparent); color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 12%, transparent); }
.kn-wiki-act.go:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); }

/* журнал показов — рама КАНОНА .modal-overlay/.modal-box, здесь только строки */
.kn-wiki-log { display: flex; flex-direction: column; gap: 2px; }
.kn-wiki-log-row { display: flex; align-items: center; gap: 9px; padding: 7px 9px; border-radius: 9px; font-size: 12.5px; }
.kn-wiki-log-row:nth-child(odd) { background: var(--panel-2); }
.kn-wiki-log-who { flex: 1 1 auto; min-width: 0; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-wiki-log-act { flex: none; padding: 1px 7px; border-radius: 7px; background: var(--panel-3); color: var(--muted); font-size: 11.5px; font-weight: 600; }
.kn-wiki-log-act.a-denied { color: var(--danger-ink); background: var(--danger-soft); }
.kn-wiki-log-act.a-reveal { color: var(--primary-2, var(--primary)); background: var(--sel); }
.kn-wiki-log-at { flex: none; color: var(--muted); font-size: 11.5px; }

/* вкладка «Вики» внутри проекта: то же тело, только на всю высоту вкладки */
.v2pt-wiki { height: 100%; min-height: 0; display: flex; flex-direction: column; }
.v2pt-wiki .kn-wiki { flex: 1 1 auto; min-height: 0; }

/* 📱 ВИКИ НА ТЕЛЕФОНЕ — одна колонка (22.10.2026). Кадр вкладки «Вики» проекта, 390: дерево брало свои
   280 px (x 68–347), а области статьи оставалось 36 px (x 348–383) — карточка «Создать статью» и сама
   статья читались столбиком по букве. Ниже 761 дерево и статья — ОДНА колонка, как список и разговор
   в чатах:
   · список — дерево во всю ширину, колонка листается целиком. Карточка «Создать статью» прячется:
     то же действие — «+ Статья» в шапке дерева (#knWikiAdd), очередь «Чего не хватает» — под деревом;
     «Выбрать компанию» (#knWikiPickCo) и ошибка (карточка без значка) остаются, ошибка — НАД деревом;
   · открыта статья, её история или идёт загрузка — дерево прячется, статья во всю ширину;
     назад к дереву — «Все статьи» (#knWikiBack) в начале ряда статьи, из истории — «К статье».
   Ширину, утянутую хваталкой на компьютере, ниже 761 снимает сама рама (WIN_PANES, vp: 761). */
@media (max-width: 760px) {
  .kn-wiki { flex-direction: column; overflow-x: hidden; overflow-y: auto; }
  .kn-wiki-side { flex: none; width: auto; min-width: 0; border-right: 0; }
  .kn-wiki-tree { flex: none; overflow: visible; }
  .kn-wiki-main { flex: none; overflow: visible; }
  .kn-wiki-main > .kn-empty:has(#knWikiEmptyAdd) { display: none; }
  /* Компания не выбрана: плита дерева на телефоне стоит НАД пустым состоянием, и одно состояние читалось
     дважды — нотой в плите и карточкой ниже. Остаётся карточка: в ней слова и единственный выход «Выбрать
     компанию» (#knWikiPickCo); нота места дерева (.kn-wiki-noco) прячется только здесь, ≤760. */
  .kn-wiki:has(#knWikiPickCo) .kn-wiki-tree:has(> .kn-wiki-noco) { display: none; }
  .kn-wiki-main:has(> .kn-empty > .kn-empty-t:first-child) { order: -1; }
  .kn-wiki-main > .kn-wiki-gaps { padding: 0 12px; }
  .kn-wiki:has(> .kn-wiki-main > :is(.kn-wiki-page, .kn-wiki-note)) { overflow: hidden; }
  .kn-wiki:has(> .kn-wiki-main > :is(.kn-wiki-page, .kn-wiki-note)) > .kn-wiki-side { display: none; }
  .kn-wiki:has(> .kn-wiki-main > :is(.kn-wiki-page, .kn-wiki-note)) > .kn-wiki-main { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
  .kn-wiki-page { padding: 14px 16px 48px; }
  .kn-wiki-act.kn-wiki-back { display: inline-flex; }
  /* Отбор вики — одна строка, которая листается (край подтаивает, ROW_FADE_SEL), а не две-три строки
     фишек над деревом; фишка — 32 px в рост, чтобы в неё попадал палец. */
  .kn-wiki-fchips { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
  .kn-wiki-fchips::-webkit-scrollbar { display: none; }
  .kn-wiki-fchip, .kn-wiki-freset { flex: none; height: 32px; white-space: nowrap; }
}

/* ══════════════ 🎓 ОБУЧЕНИЕ И АДАПТАЦИЯ (0456) ══════════════
   Третий раздел того же оверлея «База знаний» — своих рам и своих цветов не завёл: всё на
   токенах темы (--panel/--line/--primary/--ok/--danger), поэтому обе темы получаются сами,
   без второго набора правил. Сегменты — канон `.cc-seg`, срез — канон `.tasks-more`,
   пустое состояние — канон `.tw-empty`. */
.kn-lrn { display: flex; flex-direction: column; height: 100%; min-height: 0; gap: 10px; padding: 12px 14px 14px; }
.kn-lrn-top { display: flex; align-items: center; gap: 10px; flex: none; min-width: 0; }
.kn-lrn-tools { display: flex; align-items: center; gap: 8px; min-width: 0; }
.kn-lrn-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
.kn-lrn-rows { display: flex; flex-direction: column; gap: 4px; }
.kn-lrn-row { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel); color: var(--text);
  font: inherit; cursor: pointer; transition: background .12s, border-color .12s; }
.kn-lrn-row:hover { background: var(--panel-2); border-color: color-mix(in srgb, var(--primary) 32%, var(--line)); }
.kn-lrn-row-t { flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-lrn-meta, .kn-lrn-due, .kn-lrn-stuck { flex: none; font-size: 12px; color: var(--muted); }
.kn-lrn-stuck { font-weight: 600; color: var(--danger); }
/* Пилюля состояния: цвет — СМЫСЛ, а не украшение (пройдено · провалено · в работе). */
.kn-lrn-pill { flex: none; padding: 2px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
  color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); white-space: nowrap; }
.kn-lrn-pill.ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent); border-color: color-mix(in srgb, var(--ok) 26%, transparent); }
.kn-lrn-pill.bad { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); border-color: color-mix(in srgb, var(--danger) 26%, transparent); }
.kn-lrn-pill.warn { color: var(--warn, var(--primary)); background: color-mix(in srgb, var(--warn, var(--primary)) 12%, transparent); border-color: color-mix(in srgb, var(--warn, var(--primary)) 26%, transparent); }
/* Полоса прогресса: число рядом ОБЯЗАТЕЛЬНО — «пройдено 4 из 7» считает сервер, полоса лишь рисует. */
.kn-lrn-bar { flex: none; width: 96px; height: 6px; border-radius: 999px; background: var(--panel-2); border: 1px solid var(--line); overflow: hidden; }
.kn-lrn-bar > i { display: block; height: 100%; background: var(--primary); transition: width .2s ease; }
.kn-lrn-cnt { flex: none; font-size: 12px; font-weight: 650; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ── Карточка программы ── */
.kn-lrn-card { display: flex; flex-direction: column; gap: 10px; min-height: 0; }
.kn-lrn-card-h { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.kn-lrn-card-t { font-size: 16px; font-weight: 700; color: var(--text); }
.kn-lrn-card-sum { font-size: 13px; line-height: 1.5; color: var(--muted); white-space: pre-line; }
.kn-lrn-card-prog { display: flex; align-items: center; gap: 8px; }
.kn-lrn-tabs { align-self: flex-start; }
.kn-lrn-card-body { min-height: 0; }
.kn-lrn-steps { display: flex; flex-direction: column; gap: 4px; }
.kn-lrn-step { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--panel); }
.kn-lrn-step.failed { border-color: color-mix(in srgb, var(--danger) 34%, var(--line)); }
.kn-lrn-st { flex: none; width: 20px; height: 20px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 999px; color: var(--muted); background: var(--panel-2); }
.kn-lrn-st .ic { width: 13px; height: 13px; }
.kn-lrn-st.ok { color: #fff; background: var(--ok); border-color: var(--ok); }
.kn-lrn-st.bad { color: #fff; background: var(--danger); border-color: var(--danger); }
.kn-lrn-step-ic { flex: none; color: var(--muted); display: inline-flex; }
.kn-lrn-step-t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.kn-lrn-step-n { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-lrn-step-s { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-lrn-step-acts { flex: none; display: flex; align-items: center; gap: 6px; }

/* ── Проверка знаний. Вариант — КОНТРОЛ, а не строка текста (канон акцента: подложка + кольцо). ── */
.kn-lrn-quizbox:empty { display: none; }
.kn-lrn-quiz { display: flex; flex-direction: column; gap: 12px; margin: 2px 0 6px; padding: 12px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); }
.kn-lrn-q-t { font-size: 13.5px; font-weight: 650; color: var(--text); margin-bottom: 6px; }
.kn-lrn-opts { display: flex; flex-direction: column; gap: 4px; }
.kn-lrn-opt { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; padding: 8px 11px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel); color: var(--text);
  font: inherit; font-size: 13.5px; cursor: pointer; transition: background .12s, border-color .12s; }
.kn-lrn-opt:hover { background: var(--panel-2); }
.kn-lrn-opt.on { background: color-mix(in srgb, var(--primary) 11%, transparent); border-color: color-mix(in srgb, var(--primary) 30%, transparent); }
.kn-lrn-opt-r { flex: none; width: 15px; height: 15px; border: 1.5px solid var(--line); border-radius: 999px; }
.kn-lrn-opt.on .kn-lrn-opt-r { border-color: var(--primary); box-shadow: inset 0 0 0 3.5px var(--primary); }
.kn-lrn-opt-c { flex: none; margin-left: auto; color: var(--ok); display: inline-flex; }
.kn-lrn-opt-c .ic { width: 14px; height: 14px; }
.kn-lrn-quiz-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.kn-lrn-quiz-note { font-size: 12px; color: var(--muted); }

/* ── Экран руководителя ── */
.kn-lrn-team-stats { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 8px; font-size: 12.5px; color: var(--muted); }
.kn-lrn-team-stats b { color: var(--text); font-variant-numeric: tabular-nums; }
.kn-lrn-team-stats .ok b { color: var(--ok); }
.kn-lrn-team-stats .bad b { color: var(--danger); }
.kn-lrn-trows { display: flex; flex-direction: column; gap: 4px; }
.kn-lrn-trow { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); }
.kn-lrn-trow-n { flex: 0 1 auto; min-width: 0; font-size: 13.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── Поля окон раздела (подпись и галочка; сами поля — канон .pm-input) ── */
.kn-lrn-lbl { display: flex; flex-direction: column; gap: 5px; font-size: 12px; font-weight: 600; color: var(--muted); }
.kn-lrn-chk { flex-direction: row; align-items: center; gap: 8px; font-weight: 500; color: var(--text); }
.kn-lrn-chk input { flex: none; }
.kn-lrn-pick { display: flex; flex-direction: column; gap: 2px; }
/* 🎓 Рука порядка шагов (HANDORDER_MECH): грип виден всегда у того, кто правит программу —
   «скрытая до ховера» ручка на телефоне недостижима вовсе. */
.kn-lrn-steprow { display: block; }
.kn-lrn-grip { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 24px; padding: 0; border: 0; background: none; color: var(--muted);
  cursor: grab; opacity: .65; }
.kn-lrn-grip:hover { opacity: 1; color: var(--text); }
.kn-lrn-steprow.kn-lrn-dragging { position: relative; z-index: 6; }
.kn-lrn-steprow.kn-lrn-dragging .kn-lrn-step { background: var(--panel-2); border-radius: 10px; }
.kn-lrn-steprow.kn-lrn-dragging .kn-lrn-grip { cursor: grabbing; opacity: 1; }
.kn-lrn-steps.kn-lrn-reordering { user-select: none; -webkit-user-select: none; }
.kn-lrn-steps.kn-lrn-reordering .kn-lrn-steprow { will-change: transform; }
.kn-lrn-pick-row { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; padding: 7px 10px;
  border: 1px solid transparent; border-radius: 10px; background: transparent; color: var(--text); font: inherit; font-size: 13px; cursor: pointer; }
.kn-lrn-pick-row:hover { background: var(--panel-2); border-color: var(--line); }

/* ── Пустое состояние / загрузка ── */
.kn-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; height: 100%; min-height: 260px; padding: 40px 20px; text-align: center; }
.kn-empty-ic { width: 56px; height: 56px; display: flex; align-items: center; justify-content: center; border-radius: 18px; background: var(--sel); color: var(--primary); margin-bottom: 4px; }
.kn-empty-ic .ic { width: 28px; height: 28px; }
.kn-empty-t { font-size: 15px; font-weight: 650; color: var(--text); }
.kn-empty-d { font-size: 13px; line-height: 1.5; color: var(--muted); max-width: 320px; }
.kn-spin { width: 22px; height: 22px; border-radius: 50%; border: 2px solid var(--line-strong); border-top-color: var(--primary); animation: dtSpin .7s linear infinite; }

/* ── Граф связей (тонкий адаптер холста «Схемы»: те же токены/примитивы) ── */
.kn-graph { position: relative; width: 100%; height: 100%; overflow: hidden; border-radius: 0; container-type: inline-size; }
.kn-graph-vp { position: absolute; inset: 0; overflow: hidden; cursor: grab; }
.kn-graph-gl { position: absolute; inset: 0; }
.kn-graph-tools { position: absolute; top: 14px; left: 50%; transform: translateX(-50%); z-index: 10;
  width: max-content; max-width: calc(100% - 24px);
  display: flex; align-items: center; gap: 3px; padding: 5px; border-radius: 13px; border: 1px solid var(--line);
  background: color-mix(in srgb, var(--panel) 82%, transparent); backdrop-filter: blur(16px) saturate(1.4); -webkit-backdrop-filter: blur(16px) saturate(1.4);
  box-shadow: 0 8px 30px -12px rgba(0,0,0,.5); }
/* Легенда-фильтр графа: верх-справа. 🔴 ПОЛНЫЙ набор offset'ов (top/right/bottom/left) в ОДНОМ
   правиле — иначе частичный оверрайд (был инлайн в #knGraphCss: только top+right, без сброса
   bottom:12px) растягивал легенду на всю высоту вьюпорта. Держим здесь, инлайн-оверрайд убран. */
.kn-graph-legend { position: absolute; top: 14px; right: 14px; bottom: auto; left: auto; z-index: 10;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; max-width: 62%; }
.kn-graph-legend .lg { display: inline-flex; align-items: center; gap: 6px; }
.kn-lg-node { width: 14px; height: 10px; border-radius: 4px; border: 1.5px solid; box-sizing: border-box; }
.kn-lg-node.mem { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 16%, transparent); }
.kn-lg-node.ext { border-color: var(--muted); background: color-mix(in srgb, var(--muted) 14%, transparent); }
.kn-lg-wire { width: 20px; height: 0; border-top: 2px solid color-mix(in srgb, var(--primary) 45%, var(--muted)); }
/* пилюли-домены легенды (перенесены из инлайн #knGraphCss → одна каноничная точка) */
.kn-lg { display: inline-flex; align-items: center; gap: 7px; height: auto; flex: 0 0 auto; padding: 6px 11px 6px 9px;
  font: 600 12px -apple-system, system-ui, sans-serif; color: var(--text); background: var(--panel);
  border: 1px solid var(--line); border-radius: 999px; cursor: pointer; box-shadow: 0 2px 8px rgba(0,0,0,.05);
  transition: opacity .15s, transform .12s, box-shadow .15s; -webkit-user-select: none; user-select: none; }
.kn-lg:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(0,0,0,.10); }
.kn-lg i { width: 11px; height: 11px; border-radius: 50%; background: currentColor; box-shadow: 0 0 9px currentColor; }
.kn-lg.off { opacity: .42; filter: saturate(.35); }
/* тултип узла + подсказка-жесты (перенесены из инлайн #knGraphCss) */
.kn-graph-tip { position: absolute; z-index: 6; max-width: 290px; padding: 11px 13px; background: var(--panel);
  border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 14px 44px rgba(0,0,0,.20);
  pointer-events: none; transform: translate(-50%, calc(-100% - 16px)); }
.kn-graph-tip .tt-h { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; }
.kn-graph-tip .tt-dot { width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto; }
.kn-graph-tip .tt-t { font: 700 13px -apple-system, system-ui, sans-serif; color: var(--text); line-height: 1.25; }
.kn-graph-tip .tt-meta { font: 600 11px -apple-system, system-ui, sans-serif; color: var(--muted); margin-bottom: 5px; }
.kn-graph-tip .tt-b { font: 400 12px/1.4 -apple-system, system-ui, sans-serif; color: var(--muted); }
.kn-graph-hint { position: absolute; left: 50%; bottom: 15px; transform: translateX(-50%);
  font: 600 11px -apple-system, system-ui, sans-serif; color: var(--muted); background: var(--panel);
  border: 1px solid var(--line); border-radius: 999px; padding: 5px 12px; opacity: .85; z-index: 2; pointer-events: none; }
/* Адаптив: тулбар (центр) и легенда (право) СХОДЯТСЯ на узкой панели. 🔴 Порог считаем по ШИРИНЕ
   САМОГО ГРАФА через @container, а НЕ по вьюпорту: панель уже вьюпорта на ширину рельса (96px),
   из-за чего @media-порог срабатывал на ~96px позже и тулбар налезал на легенду (баг вёрстки,
   виден на окне ~1150px: панель 1054px, тулбар r=756 налезал на легенду l=731). Ниже 1100px
   ШИРИНЫ ГРАФА легенда уезжает ПОД тулбар (top:64px — тулбар высотой 44px от 14px = низ 58px,
   +6px зазор, чтобы не было даже 2px нахлёста); ещё уже — на всю ширину. @media оставлен
   фолбэком для движков без container-queries (порог поднят на ширину рельса). */
@container (max-width: 1100px) {
  .kn-graph-legend { top: 64px; right: 12px; max-width: calc(100% - 24px); gap: 6px; }
}
@container (max-width: 640px) {
  .kn-graph-legend { top: 64px; left: 12px; right: 12px; justify-content: center; max-width: calc(100% - 24px); }
  .kn-lg { padding: 5px 10px 5px 8px; font-size: 11.5px; }
  .kn-graph-hint { display: none; }
}
@media (max-width: 1196px) {
  .kn-graph-legend { top: 64px; right: 12px; max-width: calc(100% - 24px); gap: 6px; }
}
@media (max-width: 700px) {
  .kn-graph-legend { top: 64px; left: 12px; right: 12px; justify-content: center; max-width: calc(100% - 24px); }
  .kn-lg { padding: 5px 10px 5px 8px; font-size: 11.5px; }
  .kn-graph-hint { display: none; }
}

/* ── Сегмент «Инбокс»: пилюля-счётчик непросмотренных черновиков (Apple-grade, прячется на 0) ── */
.kn-seg button { position: relative; }
.kn-seg-badge { flex: none; min-width: 17px; height: 17px; display: inline-flex; align-items: center; justify-content: center;
  margin-left: 1px; padding: 0 5px; border-radius: 999px; font-size: 10.5px; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums; color: #fff; background: var(--acc-fill);
  box-shadow: 0 1px 3px -1px var(--glow); transition: opacity .14s, transform .12s; }
.kn-seg-badge[hidden] { display: none; }
.kn-seg button.active .kn-seg-badge { color: var(--primary); background: rgba(255,255,255,.92); box-shadow: none; }

/* ── Инбокс памяти: карточки-черновики на ревью (реюз .kn-grid/.kn-card + собственные штрихи) ── */
.kn-inbox-card { gap: 9px; }
.kn-inbox-card::before { content: ""; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px; border-radius: 0 3px 3px 0;
  background: color-mix(in srgb, var(--primary) 55%, transparent); }
.kn-inbox-ttl { cursor: default; }
.kn-inbox-txt { cursor: default; max-height: 6.2em; overflow: hidden; -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent);
  mask-image: linear-gradient(180deg, #000 72%, transparent); transition: max-height .18s ease; }
.kn-inbox-txt.expanded { max-height: none; -webkit-mask-image: none; mask-image: none; }
.kn-inbox-ttl:hover, .kn-inbox-txt:hover { background: transparent; }
.kn-inbox-more { align-self: flex-start; margin: -2px 0 0; padding: 0; border: none; background: none; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--primary); transition: opacity .12s; }
.kn-inbox-more:hover { opacity: .78; }
.kn-inbox-tags { margin-top: 0; }
.kn-inbox-src { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; color: var(--muted); }
/* M4: знание, добытое из созвона, — не подпись, а вход во встречу. Кликабельность даём
   сдержанно (та же типографика, подчёркнутый хвост, hover-подсветка), чтобы карточка
   Инбокса не превращалась в набор кнопок: «меньше элементов — лучше». Обе темы — через
   переменные, отдельных правил для тёмной не нужно. */
button.kn-inbox-src-link { align-self: flex-start; margin: 0; padding: 3px 7px; border: 1px solid transparent;
  border-radius: 7px; background: transparent; font: inherit; font-size: 12px; font-weight: 600; color: var(--muted);
  cursor: pointer; text-align: left; transition: background .14s, color .14s, border-color .14s; }
button.kn-inbox-src-link:hover { background: var(--hover); border-color: var(--line); color: var(--text); }
button.kn-inbox-src-link:focus-visible { outline: none; border-color: var(--line-strong); box-shadow: 0 0 0 3px var(--glow); }
.kn-inbox-src-go { text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; opacity: .85; }
button.kn-inbox-src-link:hover .kn-inbox-src-go { opacity: 1; }
.kn-inbox-acts { display: flex; gap: 8px; margin-top: 4px; padding-top: 11px; border-top: 1px solid var(--line); }
.kn-inbox-keep, .kn-inbox-hide { flex: 1 1 0; height: 34px; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border-radius: 9px; font-size: 13px; font-weight: 650; cursor: pointer; transition: filter .14s, background .14s, color .14s, transform .1s, box-shadow .14s; }
.kn-inbox-keep .ic, .kn-inbox-hide .ic { width: 16px; height: 16px; }
.kn-inbox-keep { border: none; color: #fff; background: var(--acc-grad); box-shadow: 0 4px 12px -5px var(--glow); }
.kn-inbox-keep:hover { filter: brightness(1.06); box-shadow: 0 6px 16px -6px var(--glow); }
.kn-inbox-keep:active { transform: translateY(1px); }
.kn-inbox-hide { border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); }
.kn-inbox-hide:hover { border-color: var(--line-strong); color: var(--text); background: var(--hover); }
.kn-inbox-hide:active { transform: translateY(1px); }
.kn-inbox-keep.busy, .kn-inbox-hide.busy { opacity: .6; pointer-events: none; }
.kn-inbox-keep:disabled, .kn-inbox-hide:disabled { opacity: .5; cursor: default; }
/* плавное удаление карточки после approve/dismiss (fade + схлоп высоты) */
.kn-inbox-card { transition: opacity .2s ease, transform .2s ease, margin .24s ease, max-height .24s ease, padding .24s ease, border-color .2s; max-height: 900px; }
.kn-inbox-card.kn-inbox-out { opacity: 0; transform: scale(.97); max-height: 0 !important; margin-top: -14px; padding-top: 0; padding-bottom: 0; border-color: transparent; pointer-events: none; overflow: hidden; }

@media (max-width: 720px) {
  .kn-stats { display: none; }
  .kn-search { flex-basis: 160px; }
  .kn-add span { display: none; }
  .kn-add { padding: 0 10px; }
  /* 🔴 12.10.2026 (проход по проду, телефон 390): `1fr` = minmax(auto, 1fr) — минимум колонки равен
     САМОМУ ДЛИННОМУ неразрывному слову карточки (пути, адреса, токены), и колонка раздувалась до
     580 px при 316 видимых: карточки срезались правым краем. Колонка — minmax(0, 1fr), длинное
     слово переносится внутри карточки. */
  .kn-grid { grid-template-columns: minmax(0, 1fr); padding: 14px 14px 40px; }
  .kn-grid > .kn-card { min-width: 0; overflow-wrap: anywhere; }
  /* верхняя строка карточки (вид · область · оценка · закреп · архив) — 266 px при 254: зазор плотнее,
     чип области ужимается с многоточием, кнопки остаются на месте */
  .kn-card-top { gap: 6px; }
  .kn-card-top > .kn-scope { flex: 0 1 auto; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
  /* Шапка на телефоне: поиск + четыре кнопки + «Закрыть» + шесть вкладок в 316 px не помещаются —
     «Закрыть» и вкладки уезжали за край. Три строки: «название · Закрыть», «поиск · действия
     значками» (подсказка — title кнопки), вкладки СВОЕЙ строкой во всю ширину (дорожка сама ужимает
     воздух и прокручивается с подтаявшим краем, ccSegFit). */
  .kn-head { flex-wrap: wrap; row-gap: 8px; }
  .kn-head > .kn-title { order: 0; flex: 1 0 calc(100% - 60px); min-width: 0; }
  .kn-head > #knClose { order: 1; }
  .kn-head > .tw-spacer { display: none; }
  .kn-head > .kn-search { order: 2; flex: 1 1 0; min-width: 72px; }
  .kn-head > :is(.kn-tidy, .kn-export, .kn-add) { order: 3; }
  .kn-head > :is(.kn-tidy, .kn-export) > span { display: none; }
  .kn-head > .kn-seg { order: 10; flex: 1 0 100%; min-width: 0; max-width: 100%; }
  /* knowledge-seg-nolabel-1 · вкладки базы знаний — значки (подписи гасит .tw-seg ≤860), у выбранной тоже: не видно,
     где ты. Подпись — только у выбранной, как у ленты разделов CRM; не влезло — ступень .tight и прокрутка
     с подтаявшим краем (ccSegFit), выбранную в окно выводит ccSegReveal. */
  .kn-head > .kn-seg > button.active > .tw-seg-label { display: inline; }
  /* Поле поиска делит ряд с тремя кнопками по 44 и получает 138 px (кадр k_knowledge, x 80–218): подсказка короче на телефоне
     (renderKnowledge), а то, что всё же не влезло, обрывается многоточием, а не посреди буквы. */
  .kn-search-input, .kn-search-input::placeholder { text-overflow: ellipsis; }
  /* «Кто видит» и «Проект» — по ОДНОЙ строке, которая листается (край подтаивает, ROW_FADE_SEL):
     на 390 фишки вставали в 3 и 2 ряда и отнимали пол-экрана у карточек. Поля — как у сетки (14). */
  .kn-audfilter, .kn-domfilter { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
  .kn-audfilter { padding: 12px 14px 2px; }
  .kn-domfilter { padding: 12px 14px 0; }
  .kn-audfilter::-webkit-scrollbar, .kn-domfilter::-webkit-scrollbar { display: none; }
  .kn-audchip, .kn-domchip { flex: none; height: 32px; white-space: nowrap; }
}
/* «Форма» карточки памяти на узком телефоне: колонка подписей `auto` равна самой длинной подписи (nowrap) —
   на кадре k_knowledge, 390, подписи x 100–151, а тексту оставалось x 170–351 (182 px, строки
   по 3–4 слова). Подпись встаёт НАД своим текстом, текст — во всю ширину карточки. */
@media (max-width: 560px) {
  .kn-form { grid-template-columns: minmax(0, 1fr); row-gap: 2px; }
  .kn-form-lbl { padding-top: 0; }
  .kn-form-v + .kn-form-lbl { margin-top: 8px; }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   ВСТРЕЧИ (M6) — ПЯТЫЙ вид «Базы знаний» (сегмент «Встречи»), живёт в том же #knBody.
   Список созвонов → поиск по репликам → карточка встречи (итоги, разбор говорения, тон,
   расшифровка с перемоткой, связанная память, личный коуч). Никакой своей палитры: всё на
   общих токенах (--panel/--panel-2/--line/--line-strong/--text/--muted/--text-dim/--primary/
   --sel/--grad/--glow/--shadow-1/--shadow-2/--ok/--warning/--danger), поэтому светлая и тёмная
   одинаково вылизаны. Сетка 4/8, хэйрлайны, переходы 120–160ms — как в остальных .kn-*.
   🔴 Полосы «кто сколько говорил» — CSS-геометрия (--w на .kn-tt-bar), как .dchart/.dbar в
   дашборде: фиксированная высота дорожки, свободная ширина → не плывут ни на какой ширине.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */
/* ── Каркас вида: липкая строка поиска + область списка/результатов ── */
.kn-meet { display: flex; flex-direction: column; min-height: 100%; }
.kn-meet-top { position: sticky; top: 0; z-index: 3; display: flex; align-items: center; gap: 10px;
  padding: 14px 20px 12px; background: var(--bg); border-bottom: 1px solid var(--line); }
.kn-meet-search { flex: 1 1 auto; max-width: 460px; }
.kn-meet-list { flex: 1; min-height: 0; }
.kn-meet-grid { padding-top: 16px; }
.kn-meet-hint { padding: 14px 20px 0; font-size: 11.5px; color: var(--text-dim); }

/* ── «Сводка за 30 дней» над списком (8c15480f): свой узел #knMeetStats и свой запрос
   (`knMeetLoadStats`). Плитки — облик плиток итогов встречи (.kn-mv-tile), но без нажатия;
   недели — CSS-столбики, высота = доля самой длинной недели (считает knMeetStatsModel). ── */
.kn-ms-host { padding: 16px 20px 0; }
.kn-ms-host[hidden] { display: none; }
.kn-ms { container: knms / inline-size; display: flex; flex-direction: column; gap: 12px; padding: 14px 16px 16px;
  border-radius: 14px; background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow-1); }
.kn-ms-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; min-width: 0; font-size: 14px; color: var(--text); }
.kn-ms-h .ic { width: 16px; height: 16px; flex: none; align-self: center; color: var(--primary); }
.kn-ms-h b { font-weight: 680; }
.kn-ms-h span { font-size: 12px; font-weight: 600; color: var(--muted); }
.kn-ms-body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(200px, 280px); gap: 10px 14px; align-items: stretch; }
.kn-ms-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(122px, 1fr)); gap: 8px; align-content: start; }
.kn-ms-tile { min-width: 0; display: flex; flex-direction: column; gap: 2px; padding: 10px 12px 11px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--panel-2); }
.kn-ms-tile b { font-size: 21px; font-weight: 720; line-height: 1.15; letter-spacing: -.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.kn-ms-tile span { font-size: 12px; font-weight: 600; line-height: 1.3; color: var(--muted); }
.kn-ms-tile em { font-style: normal; font-size: 11px; font-weight: 600; line-height: 1.35; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.kn-ms-weeks { display: flex; flex-direction: column; gap: 6px; min-height: 104px; padding: 8px 10px 8px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--panel-2); }
.kn-ms-wcap { font-size: 11px; font-weight: 650; color: var(--muted); line-height: 1.2; }
.kn-ms-wbars { flex: 1; min-height: 70px; display: flex; align-items: stretch; gap: 6px; }
.kn-ms-wk { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.kn-ms-wk-b { flex: 1; width: 100%; max-width: 34px; display: flex; align-items: flex-end; border-radius: 7px; overflow: hidden;
  background: color-mix(in srgb, var(--text) 7%, transparent); }
.kn-ms-wk-b i { display: block; width: 100%; border-radius: 7px; background: var(--primary); transition: height .3s ease; }
.kn-ms-wk:hover .kn-ms-wk-b i { background: color-mix(in srgb, var(--primary) 82%, var(--text)); }
.kn-ms-wk em { font-style: normal; font-size: 10.5px; font-weight: 600; line-height: 1.2; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }
.kn-ms-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.kn-ms-rl { font-size: 11.5px; font-weight: 650; color: var(--muted); margin-right: 2px; }
.kn-mv-topic em { font-style: normal; min-width: 18px; height: 16px; margin-left: 2px; padding: 0 5px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center; font-size: 10.5px; font-weight: 700; color: var(--text);
  background: color-mix(in srgb, var(--text) 9%, transparent); font-variant-numeric: tabular-nums; }
.kn-mv-topic[hidden] { display: none; }
.kn-ms-more { cursor: pointer; font: inherit; font-size: 12px; font-weight: 650; color: var(--primary); background: transparent;
  border: 1px dashed color-mix(in srgb, var(--primary) 40%, var(--line)); }
.kn-ms-more:hover { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.kn-ms-more:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--sel); }
.kn-ms.is-line { flex-direction: row; align-items: center; gap: 10px; padding: 11px 12px 11px 14px; font-size: 13px; line-height: 1.4; color: var(--muted); }
.kn-ms.is-line > .ic { width: 16px; height: 16px; flex: none; }
.kn-ms.is-line > span { flex: 1; min-width: 0; }
.kn-ms.is-err > .ic { color: var(--warn); }
.kn-ms.is-line > button { flex: none; }
.kn-ms-skel { display: grid; grid-template-columns: repeat(auto-fit, minmax(122px, 1fr)); gap: 8px; }
.kn-ms-skel i { display: block; height: 64px; border-radius: 12px; background: var(--panel-2); animation: knMsPulse 1.2s ease-in-out infinite; }
@keyframes knMsPulse { 50% { opacity: .5; } }
@media (prefers-reduced-motion: reduce) { .kn-ms-skel i { animation: none; } .kn-ms-wk-b i { transition: none; } }
@container knms (max-width: 700px) { .kn-ms-body { grid-template-columns: 1fr; } }
@media (max-width: 720px) { .kn-ms-host { padding: 14px 14px 0; } .kn-ms { padding: 12px 12px 14px; } }

/* ── Карточка встречи в списке ── */
.kn-meet-card { cursor: pointer; gap: 9px; }
.kn-meet-card:hover { border-color: var(--primary); box-shadow: var(--shadow-2); transform: translateY(-1px); }
.kn-meet-card:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
.kn-meet-ct { min-width: 0; font-size: 14.5px; font-weight: 650; line-height: 1.3; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-meet-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--ok);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 18%, transparent); }
.kn-meet-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.kn-meet-when { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.kn-meet-chip { display: inline-flex; align-items: center; gap: 5px; height: 20px; padding: 0 8px; border-radius: 7px;
  font-size: 11px; font-weight: 600; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); }
.kn-meet-chip .ic { width: 12px; height: 12px; opacity: .7; }
.kn-meet-chip-soft { color: var(--warning); background: var(--warning-soft); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }
.kn-meet-sum { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* ── Найденные реплики (поиск по расшифровкам) ── */
.kn-meet-hits { display: flex; flex-direction: column; gap: 10px; padding: 14px 20px 40px; max-width: 900px; }
.kn-meet-hit { cursor: pointer; gap: 7px; padding: 12px 14px; }
.kn-meet-hit:hover { border-color: var(--primary); box-shadow: var(--shadow-2); }
.kn-meet-hit:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
.kn-meet-hit-top { display: flex; align-items: center; gap: 8px; }
.kn-meet-hit-in { min-width: 0; max-width: 45%; font-size: 11.5px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-meet-hit-txt { color: var(--text); }
.kn-meet-tc { flex: none; height: 20px; display: inline-flex; align-items: center; padding: 0 7px; border-radius: 6px;
  font: 600 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums;
  color: var(--primary); background: var(--sel); }
.kn-meet-who { font-size: 12px; font-weight: 600; color: var(--muted); }
.kn-meet-hl { color: var(--text); background: color-mix(in srgb, var(--primary) 18%, transparent); border-radius: 4px; padding: 0 2px; font-weight: 650; }

/* ── Карточка встречи: шапка ── */
.kn-meet-detail { display: flex; flex-direction: column; min-height: 100%; }
.kn-meet-dh { position: sticky; top: 0; z-index: 3; display: flex; align-items: center; gap: 12px;
  padding: 12px 20px; background: var(--bg); border-bottom: 1px solid var(--line); }
.kn-meet-back { flex: none; display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 11px 0 8px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--muted);
  font-size: 12.5px; font-weight: 600; cursor: pointer; transition: color .13s, border-color .13s, background .13s; }
.kn-meet-back:hover { color: var(--text); border-color: var(--line-strong); background: var(--hover); }
.kn-meet-back .ic { width: 15px; height: 15px; }
.kn-empty .kn-meet-back { margin-top: 10px; }
.kn-meet-dh-t { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.kn-meet-dh-ttl { font-size: 15px; font-weight: 650; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-meet-dh-sub { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
/* ══ 🧠 РАЗБОР ВСТРЕЧИ v2 (8c15480f) — шапка · вкладки · панели · колонка расшифровки ═══════════
   Тело ОДНО на раздел «База знаний → Встречи» и модалку из чата (`knMeetBodyHtml`). Широко
   (`.kn-mv.wide` — контейнер ≥ 1100px, ЗАМЕР `knMeetFit`, а не медиазапрос: модалку тянут мышью)
   — две колонки: разбор ‖ липкая расшифровка; узко — расшифровка своей вкладкой. Видимая панель —
   по `data-seg`. Цвета — только токены: светлая и тёмная темы получаются даром. Левых реек нет. */
.kn-mv { --kn-mv-bg: var(--bg); display: flex; flex-direction: column; gap: 14px; width: 100%; max-width: 1480px;
  margin: 0 auto; padding: 16px 20px 40px; box-sizing: border-box; min-width: 0; }
.kn-mv.no-side { max-width: 1000px; }
.mti-detail .kn-mv { --kn-mv-bg: var(--panel); padding: 0 0 6px; max-width: none; }
.kn-mv [hidden] { display: none !important; }

/* Шапка: участники (цвет = доли речи и шкала) · кольцо «Индекс встречи» · плитки итогов. */
.kn-mv-hero { display: flex; flex-direction: column; gap: 14px; padding: 14px 16px 16px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow-1); }
.kn-mv-hero-top { display: flex; align-items: center; flex-wrap: wrap; gap: 12px 16px; }
.kn-mv-people { flex: 1 1 240px; min-width: 0; display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.kn-mv-people > .ic { width: 15px; height: 15px; flex: none; color: var(--muted); margin-right: 2px; }
.kn-mv-who { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px 0 9px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line); font-size: 12.5px; font-weight: 600; color: var(--text);
  white-space: nowrap; min-width: max-content; }
.kn-mv-who em { font-style: normal; font-size: 11.5px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.kn-mv-who.is-more { padding: 0 9px; color: var(--muted); }
.kn-mv-ring { --ring: var(--muted); flex: none; margin-left: auto; display: inline-flex; align-items: center; gap: 10px; cursor: help; }
.kn-mv-ring.is-ok { --ring: var(--ok); }
.kn-mv-ring.is-mid { --ring: var(--warning); }
.kn-mv-ring.is-low { --ring: var(--danger); }
.kn-mv-ring-g { position: relative; flex: none; width: 56px; height: 56px; display: inline-grid; place-items: center; }
.kn-mv-ring-g svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.kn-mv-ring-trk { fill: none; stroke: color-mix(in srgb, var(--text) 11%, transparent); stroke-width: 5; }
.kn-mv-ring-val { fill: none; stroke: var(--ring); stroke-width: 5; stroke-linecap: round; transition: stroke-dasharray .16s ease; }
.kn-mv-ring-g b { position: relative; font-size: 17px; font-weight: 750; letter-spacing: -.02em; color: var(--text);
  font-variant-numeric: tabular-nums; }
.kn-mv-ring-l { display: flex; flex-direction: column; gap: 1px; font-size: 12.5px; font-weight: 650; line-height: 1.25;
  color: var(--text); white-space: nowrap; }
.kn-mv-ring-l em { font-style: normal; font-size: 11.5px; font-weight: 500; color: var(--muted); }
.kn-mv-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(118px, 1fr)); gap: 8px; }
.kn-mv-tile { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 10px 12px 11px;
  border-radius: 12px; border: 1px solid var(--line); background: var(--panel-2); color: var(--text); font: inherit;
  text-align: left; cursor: pointer; transition: background .14s ease, border-color .14s ease, box-shadow .14s ease; }
.kn-mv-tile:hover { background: var(--hover); border-color: var(--line-strong); }
.kn-mv-tile:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
.kn-mv-tile b { font-size: 21px; font-weight: 720; line-height: 1.15; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.kn-mv-tile span { font-size: 12px; font-weight: 600; line-height: 1.3; color: var(--muted); }
.kn-mv-tile em { font-style: normal; font-size: 11px; font-weight: 650; color: var(--muted); }
.kn-mv-tile em.is-ok { color: var(--ok); }

/* Вкладки: полоса ЛИПКАЯ — листая длинные «Итоги», переключиться можно, не возвращаясь наверх. */
.kn-mv-bar { position: sticky; top: var(--kn-mv-top0, 0px); z-index: 2; display: flex; align-items: center;
  margin: -4px 0; padding: 4px 0; background: transparent; transition: box-shadow .16s ease; }
/* Фон — только у ПРИЛИПШЕЙ полосы (`.bar-stuck` ставит knMeetStuck по прокрутке): под ней едет
   текст, и его надо закрыть; в покое прозрачная полоса не ложится плашкой на градиент модалки. */
.kn-mv.bar-stuck .kn-mv-bar { background: var(--kn-mv-bg); box-shadow: 0 1px 0 var(--line); }
.kn-mv-seg { max-width: 100%; }
.kn-mv.wide .kn-mv-seg-tr { display: none; }

/* Колонки и панели. */
.kn-mv-cols { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; }
.kn-mv.wide .kn-mv-cols { grid-template-columns: minmax(0, 1fr) minmax(360px, 440px); gap: 18px; }
.kn-mv-main { min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.kn-mv-pane { min-width: 0; display: none; flex-direction: column; gap: 14px; }
.kn-mv[data-seg="sum"] .kn-mv-pane[data-knmvpane="sum"], .kn-mv[data-seg="tasks"] .kn-mv-pane[data-knmvpane="tasks"],
.kn-mv[data-seg="ana"] .kn-mv-pane[data-knmvpane="ana"], .kn-mv[data-seg="chat"] .kn-mv-pane[data-knmvpane="chat"],
.kn-mv.wide[data-seg="tr"] .kn-mv-pane[data-knmvpane="sum"] { display: flex; animation: knMvIn .16s ease; }
@keyframes knMvIn { from { opacity: 0; transform: translateY(3px); } to { opacity: 1; transform: none; } }
.kn-mv-side { min-width: 0; display: none; flex-direction: column; gap: 12px; }
.kn-mv[data-seg="tr"] .kn-mv-side { display: flex; animation: knMvIn .16s ease; }
.kn-mv.wide .kn-mv-side { display: flex; position: sticky; top: var(--kn-mv-top, 12px); animation: none;
  max-height: calc(var(--kn-mv-vh, 80vh) - var(--kn-mv-top, 12px) - 12px); }
.kn-mv.wide .kn-mv-side > .kn-meet-player { flex: none; }
.kn-mv.wide .kn-mv-side > .kn-mv-tr { flex: 1 1 auto; min-height: 0; }
.kn-mv.wide .kn-mv-tr-list { flex: 1 1 auto; min-height: 120px; overflow-y: auto; }
@media (prefers-reduced-motion: reduce) { .kn-mv-pane, .kn-mv-side { animation: none !important; } }
.kn-mv-panebar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; padding: 0 2px;
  font-size: 12.5px; color: var(--muted); }
.kn-mv-panebar .kn-mv-hbtn { margin-left: auto; }
.kn-mv-nodata-act { display: flex; }
.kn-mv-nodata-act .kn-mv-hbtn { margin-left: 0; }
.kn-mv-hbtn { margin-left: auto; align-self: center; text-transform: none; letter-spacing: 0; font-weight: 600;
  white-space: nowrap; min-width: max-content; }
.kn-meet-sec-note + .kn-mv-hbtn { margin-left: 10px; }
.kn-mv-hbtn.busy { opacity: .7; pointer-events: none; }
.kn-meet-sec { display: flex; flex-direction: column; gap: 10px; padding: 15px 17px 16px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow-1); }
.kn-meet-sec-h { display: flex; align-items: baseline; gap: 7px; font-size: 12px; font-weight: 650;
  letter-spacing: .02em; text-transform: uppercase; color: var(--muted); }
.kn-meet-sec-h .ic { width: 14px; height: 14px; align-self: center; flex: none; }
.kn-meet-sec-note { margin-left: auto; font-style: normal; font-size: 11px; font-weight: 500; letter-spacing: 0;
  text-transform: none; color: var(--text-dim); text-align: right; }
.kn-meet-nodata { background: var(--panel-2); box-shadow: none; }
.kn-meet-note { font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.kn-meet-summary { margin: 0; font-size: 14px; line-height: 1.6; color: var(--text); }
.kn-meet-ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 5px;
  font-size: 13.5px; line-height: 1.5; color: var(--text); }
.kn-meet-intr { list-style: none; padding-left: 0; }
.kn-meet-intr li { display: flex; align-items: center; gap: 7px; font-variant-numeric: tabular-nums; }
.kn-meet-plain { font-size: 13.5px; line-height: 1.6; color: var(--text); white-space: pre-wrap; word-break: break-word; }

/* ── 🔴🔴 CLIE-885 · ЗАДАЧИ ВСТРЕЧИ ПРАВЯТ ПРЯМО ЗДЕСЬ ─────────────────────────────
   Владелец: «должно быть пространство, где можно посмотреть задачи и отредактировать».
   До 04.09.2026 строка была `<button>` — только «открыть карточку»; теперь это РЯД
   КОНТРОЛОВ: чекбокс · название (contenteditable) · кому · срок · открыть · убрать.
   🔴 Строка-задача, а не «карточка в карточке»: она уже лежит внутри `.kn-meet-sec`.
   🔴 Принадлежность несут ИКОНКА и подложка — НЕ полоса слева (запрет CLIE-483).
   🔴 Контролы одного ряда живут в ОДНОМ размерном классе (--ctl-h/--ctl-r/--ctl-fs,
      CLIE-505) и НЕ сжимаются ниже собственной подписи (min-width:max-content, СРЕД-33).
   🔴 Все цвета — токенами, поэтому светлая и тёмная темы получаются даром. */
.kn-meet-tasks { display: flex; flex-direction: column; gap: 4px; }
.kn-mt-wrap { display: flex; flex-direction: column; gap: 10px; }
.kn-mt-row { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 6px 8px;
  border-radius: 10px; border: 1px solid transparent; background: transparent;
  transition: background .13s ease, border-color .13s ease; }
.kn-mt-row:hover { background: var(--panel-2); border-color: var(--line); }
.kn-mt-row:focus-within { background: var(--panel-2); border-color: var(--line); }
.kn-mt-row.arch { opacity: .62; }
.kn-mt-row.pending { opacity: .6; }

/* Чекбокс «Готово» — свой квадрат с рамкой (голых системных не держим, правило дизайна). */
.kn-mt-ck { flex: none; width: 19px; height: 19px; padding: 0; display: inline-flex;
  align-items: center; justify-content: center; border-radius: 6px; cursor: pointer;
  border: 1.6px solid var(--line-strong); background: var(--panel); color: transparent;
  transition: background .12s ease, border-color .12s ease, color .12s ease; }
.kn-mt-ck:hover { border-color: var(--primary); }
.kn-mt-ck:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.kn-mt-ck.on { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; }
.kn-mt-ck .ic { width: 12px; height: 12px; stroke-width: 3; }
.kn-mt-ck.ghostck { border-style: dashed; cursor: default; }
.kn-mt-ck.ghostck .kn-spin { width: 12px; height: 12px; border-width: 1.6px; }

/* Название — ПОЛЕ, а не текст: клик ставит каретку, уход фокусом сохраняет (канон CLIE-189). */
.kn-mt-t { flex: 1 1 220px; min-width: 140px; font-size: 13.5px; line-height: 1.4; color: var(--text);
  padding: 4px 6px; margin: -4px -6px; border-radius: 8px; cursor: text; word-break: break-word;
  border: 1px solid transparent; transition: background .12s ease, border-color .12s ease; }
.kn-mt-t:hover { background: var(--hover); }
.kn-mt-t.editing { background: var(--panel); border-color: var(--primary); cursor: text;
  box-shadow: 0 0 0 3px var(--sel); outline: none; }
.kn-mt-row.done .kn-mt-t { color: var(--muted); text-decoration: line-through; }

/* 🔴 `flex-wrap` обязателен: в узкой колонке ряд действий шире доступного места, и без
   переноса «×» уезжал БЕЗ ПОЛОСЫ ПРОКРУТКИ за край карточки — то есть кнопка становилась
   недостижимой (класс CLIE-620 «обрезано, а доскроллить нечем»). */
.kn-mt-acts { flex: none; display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-left: auto; }
.kn-mt-hint { font-size: 12px; color: var(--muted); }

/* «Кому» и «Срок» — контролы строки: одна высота, один радиус, один кегль. */
.kn-mt-who, .kn-mt-due { display: inline-flex; align-items: center; gap: 6px; height: var(--ctl-h);
  min-width: max-content; padding: 0 9px; border-radius: var(--ctl-r); border: 1px solid var(--line);
  background: var(--panel); color: var(--muted); font: inherit; font-size: var(--ctl-fs);
  font-weight: 550; cursor: pointer; white-space: nowrap; box-sizing: border-box;
  transition: background .12s ease, border-color .12s ease, color .12s ease; }
.kn-mt-who:hover, .kn-mt-due:hover { background: var(--hover); border-color: var(--line-strong); color: var(--text); }
.kn-mt-who:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.kn-mt-who.on, .kn-mt-due.on { color: var(--text); }
.kn-mt-who .ic, .kn-mt-due .ic { width: 14px; height: 14px; flex: none; opacity: .75; }
.kn-mt-who .tw-av { width: 18px; height: 18px; flex: none; font-size: 9px; }
/* Обрезаем ТОЛЬКО подпись, а не аватар рядом: правило `.kn-mt-who span` без исключения
   накрыло бы и `.tw-av` — контрол начал бы жить по чужой ширине. */
.kn-mt-who span:not(.tw-av) { max-width: 118px; overflow: hidden; text-overflow: ellipsis; }
/* «Срок» — кнопка-чип, а не голое поле даты: нажатие открывает окно срока (`ccDuePop`) с днём
   сеткой и временем. Прошедший срок у незакрытой задачи — красными чернилами, а не рейкой. */
.kn-mt-due:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.kn-mt-due span { max-width: 132px; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.kn-mt-due.is-late { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 38%, var(--line)); }
.kn-mt-due.is-late .ic { opacity: 1; }

/* «Открыть карточку» и «Убрать» — квадратные значки того же размерного класса. */
.kn-mt-go, .kn-mt-x { flex: none; width: var(--ctl-h); height: var(--ctl-h); display: inline-flex;
  align-items: center; justify-content: center; border-radius: var(--ctl-r);
  border: 1px solid transparent; background: transparent; color: var(--muted); cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease; }
.kn-mt-go:hover { background: var(--hover); border-color: var(--line); color: var(--text); }
.kn-mt-x:hover { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 30%, transparent); color: var(--danger); }
.kn-mt-go:focus-visible, .kn-mt-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.kn-mt-go .ic, .kn-mt-x .ic { width: 15px; height: 15px; }
.kn-mt-flag { flex: none; }

/* Предложенное моделью + кнопка «Завести задачи» (её видно, только пока задач НЕТ). */
.kn-mt-sug { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.kn-mt-suglist { color: var(--muted); }
.kn-mt-more { list-style: none; margin-left: -18px; font-size: 12.5px; }
.kn-mt-mk { display: inline-flex; align-items: center; gap: 7px; min-width: max-content; }
.kn-mt-mk .ic { width: 15px; height: 15px; }
.kn-mt-mk.busy { opacity: .7; pointer-events: none; }
.kn-mt-mk .kn-spin { border-top-color: currentColor; }

/* ── ☑️ ПРЕДЛОЖЕННЫЕ ЗАДАЧИ ВСТРЕЧИ — ОДИН список на две поверхности (владелец 30.09.2026) ──
   Разбор встречи (здесь, токены темы — светлая и тёмная даром) и шторка звонка (`.gc-prop` —
   локальная тёмная шкала тех же токенов). Галочка и «убрать» — канонические `.kn-mt-ck` /
   `.kn-mt-x` строк задач: второго чекбокса в продукте нет.
   🔴 Никаких левых реек (CLIE-483): снятая галочка = пустой квадрат и приглушённый текст.
   🔴 Контролы ряда — одного размерного класса (--ctl-h), подпись не жмётся (СРЕД-33). */
.mprop-list { display: flex; flex-direction: column; gap: 2px; }
.mprop-row { display: flex; align-items: flex-start; gap: 10px; padding: 8px 6px 8px 8px; border-radius: 10px;
  border: 1px solid transparent; cursor: pointer; transition: background .13s ease, border-color .13s ease; }
.mprop-row:hover { background: var(--hover); }
.mprop-row:focus-within { background: var(--hover); border-color: var(--line); }
.mprop-row .mprop-ck { margin-top: 1px; }
.mprop-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.mprop-t { font-size: 13.5px; line-height: 1.4; color: var(--text); word-break: break-word;
  transition: color .13s ease; }
.mprop-meta { display: flex; flex-wrap: wrap; gap: 4px 10px; font-size: 12px; line-height: 1.35; color: var(--muted); }
.mprop-meta span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.mprop-row.off .mprop-t { color: var(--muted); }
.mprop-row.off .mprop-meta { opacity: .75; }
/* «Убрать» проявляется по наведению (на касании виден всегда): строка не пестрит крестиками. */
.mprop-row .mprop-x { margin: -3px -2px -3px 0; opacity: .55; transition: opacity .13s ease, background .12s ease, color .12s ease, border-color .12s ease; }
.mprop-row:hover .mprop-x, .mprop-row .mprop-x:focus-visible { opacity: 1; }
@media (hover: none) { .mprop-row .mprop-x { opacity: 1; } }
.mprop-foot { display: flex; align-items: center; justify-content: flex-start; gap: 8px; }
.mprop-go { min-width: max-content; }
.mprop-go.is-empty { opacity: .55; box-shadow: none; }
.mprop-go.busy { opacity: .8; pointer-events: none; }
.mprop-go .kn-spin { border-color: rgba(255,255,255,.35); border-top-color: #fff; }
/* В разборе встречи предложения — отдельный остров над списком заведённых задач. */
.kn-mt-props { display: flex; flex-direction: column; gap: 8px; padding: 10px 10px 12px; border-radius: 12px;
  background: var(--panel-2); border: 1px solid var(--line); }
.kn-mt-props > .kn-meet-note { padding: 0 4px; }

/* ── ☑️ ПРЕДЛОЖЕНИЯ v2 (задача 8c15480f): чипы, цитата с моментом, подробности, свёрнутые
   неуверенные. Чипы — подложка `--panel` на острове `--panel-2` (обе темы токенами); тон несёт
   ЗНАЧОК, а слово всегда читаемых чернил (близнец `ccToneChip` приложения).
   🔴 Никаких левых реек (CLIE-483): сомнительная строка = снятая галочка и жёлтый значок «?». */
.kn-mt-props-h { display: flex; align-items: center; gap: 7px; padding: 0 4px; font-size: 13.5px; color: var(--text); }
.kn-mt-props-h .ic { width: 15px; height: 15px; flex: none; color: var(--accent); }
.kn-mt-props-h b { font-weight: 650; }
.mprop-row.is-full { padding: 10px 6px 10px 8px; }
.mprop-row.is-full .mprop-main { gap: 5px; }
.mprop-row.is-full .mprop-t { font-weight: 550; }
.mprop-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.mprop-chip { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; height: 21px; padding: 0 7px;
  border-radius: 6px; box-sizing: border-box; font-size: 11.5px; font-weight: 560; line-height: 1; white-space: nowrap;
  color: var(--muted); background: var(--panel); border: 1px solid var(--line); }
.mprop-chip > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.mprop-chip .ic { width: 12px; height: 12px; flex: none; opacity: .75; }
.mprop-chip.is-who { color: var(--text); }
.mprop-chip.is-prio.is-urgent .ic { color: var(--danger); opacity: 1; }
.mprop-chip.is-prio.is-high .ic { color: var(--warning); opacity: 1; }
.mprop-chip.is-conf .ic { color: var(--ok); opacity: 1; }
.mprop-chip.is-conf.is-low .ic { color: var(--warning); }
.mprop-q { display: flex; align-items: baseline; flex-wrap: wrap; gap: 3px 8px; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.mprop-q .kn-mv-tc { align-self: center; }
.mprop-q-t { font-style: italic; color: var(--text); opacity: .86; word-break: break-word; }
.mprop-q-who { font-size: 12px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.mprop-d { font-size: 12.5px; line-height: 1.5; color: var(--muted); word-break: break-word; }
.mprop-why { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; color: var(--text-dim); }
.mprop-why .ic { width: 12px; height: 12px; }
.mprop-row.off .mprop-chips, .mprop-row.off .mprop-q, .mprop-row.off .mprop-d { opacity: .72; }
/* «Ещё N неуверенных задач» — строка-раскрытие на языке строк списка, а не вторая кнопка. */
.mprop-more { display: flex; align-items: center; gap: 7px; width: 100%; min-height: 32px; margin-top: 2px; padding: 0 9px;
  border: 1px dashed var(--line-strong); border-radius: 10px; background: transparent; color: var(--muted);
  font: inherit; font-size: 12.5px; font-weight: 600; text-align: left; cursor: pointer;
  transition: background .13s ease, color .13s ease, border-color .13s ease; }
.mprop-more:hover { background: var(--hover); color: var(--text); }
.mprop-more:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.mprop-more.open { border-style: solid; border-color: transparent; background: transparent; }
.mprop-more .ic { width: 14px; height: 14px; flex: none; }
.mprop-more em { margin-left: auto; font-style: normal; font-weight: 500; font-size: 11.5px; color: var(--text-dim); }
.mprop-lows { display: flex; flex-direction: column; gap: 2px; }
.mprop-foot { flex-wrap: wrap; }
.mprop-conf, .mprop-drop { display: inline-flex; align-items: center; gap: 6px; min-width: max-content; }
.mprop-conf .ic, .mprop-drop .ic { width: 14px; height: 14px; }
.mprop-drop:hover { color: var(--danger); }
/* «Ая убрала · N» (8c15480f) — свёрнутый отчёт о том, что модель сняла при сверке итога. Строка без
   галочки: вместо «×» — «Вернуть», причина строкой. Нет ждущих — живёт строкой под задачами. */
.mprop-dropped { display: flex; flex-direction: column; gap: 2px; }
.kn-mt-props .mprop-dropped { margin-top: 2px; padding-top: 8px; border-top: 1px solid var(--line); }
.mprop-row.is-dropped { cursor: default; padding-left: 10px; }
.mprop-back { flex: none; display: inline-flex; align-items: center; gap: 6px; min-width: max-content; margin: -2px 0; }
.mprop-back .ic { width: 14px; height: 14px; }
.kn-mt-dropwrap { margin-top: 2px; }
/* Подзаголовок «Заведено · N» и важность заведённой задачи — то же слово, что у предложения. */
.kn-mt-subh { display: flex; align-items: center; gap: 7px; padding: 2px 4px 0; font-size: 12px; font-weight: 650;
  letter-spacing: .02em; text-transform: uppercase; color: var(--muted); }
.kn-mt-subh .ic { width: 14px; height: 14px; }
.kn-mt-prio { flex: none; }
.kn-mt-prio.is-urgent { color: var(--danger); background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.kn-mt-prio.is-high { color: var(--warning); background: var(--warning-soft); border-color: color-mix(in srgb, var(--warning) 30%, transparent); }

/* ⏱ МОМЕНТ ВСТРЕЧИ — ОДНА кнопка на весь разбор (решение, задача, вопрос, риск, факт, цитата):
   `data-knseek` → прокрутка и подсветка реплики В ЭТОЙ ЖЕ поверхности + перемотка записи.
   Вид — тот же моноширинный таймкод, что у найденной реплики (`.kn-meet-tc`). */
.kn-mv-tc { flex: none; display: inline-flex; align-items: center; height: 20px; padding: 0 7px; border: 0; border-radius: 6px;
  font: 600 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; font-variant-numeric: tabular-nums;
  color: var(--primary); background: var(--sel); cursor: pointer; transition: background .12s ease, box-shadow .12s ease; }
.kn-mv-tc:hover { background: color-mix(in srgb, var(--primary) 24%, transparent); }
.kn-mv-tc:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* «＋ Добавить задачу» — инлайн-строка, не модалка (правило «нажал → изменил»). */
.kn-mt-add { display: flex; align-items: center; gap: 8px; height: var(--ctl-h); padding: 0 10px;
  border-radius: var(--ctl-r); border: 1px dashed var(--line-strong); background: transparent;
  box-sizing: border-box; transition: border-color .12s ease, background .12s ease; }
.kn-mt-add:focus-within { border-style: solid; border-color: var(--primary); background: var(--panel); }
.kn-mt-add-ic { flex: none; display: inline-flex; color: var(--muted); }
.kn-mt-add-ic .ic { width: 15px; height: 15px; }
.kn-mt-add input { flex: 1 1 auto; min-width: 0; border: 0; background: transparent; color: var(--text);
  font: inherit; font-size: var(--ctl-fs); padding: 0; }
.kn-mt-add input:focus { outline: none; }
.kn-mt-add input::placeholder { color: var(--text-dim); }

/* ── 🤖 CLIE-885 · «ОБСУДИТЬ С ИИ» — В ТОМ ЖЕ ПРОСТРАНСТВЕ ────────────────────────
   Пузыри на языке карточки (токены темы), а не копия композера помощника: тут это
   секция разбора, а не второй мессенджер. */
.kn-meet-csec { gap: 12px; }
.kn-mc-clear { margin-left: 8px; flex: none; min-width: max-content; border: 0; background: transparent;
  padding: 0; font: inherit; font-size: 11px; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--text-dim); cursor: pointer; transition: color .12s ease; }
.kn-mc-clear:hover { color: var(--danger); }
.kn-mc-clear[hidden] { display: none; }
.kn-mc-thread { display: flex; flex-direction: column; gap: 8px; max-height: min(46vh, 420px);
  overflow-y: auto; margin: 0 -4px; padding: 0 4px; overscroll-behavior: contain; }
.kn-mc-thread:empty { display: none; }
.kn-mc-msg { display: flex; }
.kn-mc-msg.mine { justify-content: flex-end; }
.kn-mc-bub { max-width: 86%; padding: 9px 12px; border-radius: 14px; font-size: 13.5px; line-height: 1.55;
  color: var(--text); background: var(--panel-2); border: 1px solid var(--line); word-break: break-word; }
.kn-mc-msg.mine .kn-mc-bub { background: var(--sel); border-color: color-mix(in srgb, var(--primary) 32%, transparent);
  border-bottom-right-radius: 6px; white-space: pre-wrap; }
.kn-mc-msg.ai .kn-mc-bub { border-bottom-left-radius: 6px; }
.kn-mc-bub .md-body { font-size: 13.5px; line-height: 1.55; }
.kn-mc-bub.kn-mc-wait { display: inline-flex; align-items: center; gap: 9px; color: var(--muted);
  font-variant-numeric: tabular-nums; }
.kn-mc-bub.err { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 30%, transparent);
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.kn-mc-errt { font-size: 13px; line-height: 1.5; color: var(--text); }
.kn-mc-bub.err .ghost { min-width: max-content; }

/* Пустой тред не отбирает экран: три примера прямо над композером (прогрессивное раскрытие). */
.kn-mc-hints { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.kn-mc-hints-t { font-size: 12px; color: var(--text-dim); }
.kn-mc-hint { min-width: max-content; height: 26px; padding: 0 11px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--muted);
  font: inherit; font-size: 12px; cursor: pointer; transition: background .12s ease, color .12s ease, border-color .12s ease; }
.kn-mc-hint:hover { background: var(--hover); color: var(--text); border-color: var(--line-strong); }

.kn-mc-comp { display: flex; align-items: flex-end; gap: 8px; }
.kn-mc-input { flex: 1 1 auto; min-width: 0; min-height: var(--ctl-h); max-height: min(28vh, 132px);
  resize: none; overflow-y: auto; padding: 7px 11px; border-radius: var(--ctl-r);
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  font: inherit; font-size: var(--ctl-fs); line-height: 1.45; box-sizing: border-box;
  transition: border-color .12s ease, box-shadow .12s ease; }
.kn-mc-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
.kn-mc-input::placeholder { color: var(--text-dim); }
.kn-mc-input:disabled { opacity: .6; cursor: not-allowed; }
.kn-mc-send { flex: none; display: inline-flex; align-items: center; gap: 6px; min-width: max-content;
  height: var(--ctl-h); box-sizing: border-box; }
.kn-mc-send .ic { width: 15px; height: 15px; }
.kn-mc-send:disabled, .kn-mc-send.busy { opacity: .55; pointer-events: none; }

/* Телефон/узкая колонка: уступает ДЕКОРАЦИЯ, а не имя задачи (доктрина СРЕД-34).
   🔴 Чекбокс и название остаются НА ОДНОЙ строке — оторванная галочка над текстом читается
   как отдельный элемент; на свою линию уезжают только ДЕЙСТВИЯ, с отступом под текст.
   У кнопки отправки на такой ширине остаётся значок (подпись живёт в title) — это тот же
   размен, что «главное действие уезжает в ⋯» у шапки (CLIE-642), а не потеря контрола. */
@media (max-width: 720px) {
  .kn-mt-row { row-gap: 6px; }
  .kn-mt-acts { flex: 1 0 100%; margin-left: 0; padding-left: 27px; box-sizing: border-box; }
  .kn-mt-who span:not(.tw-av) { max-width: 92px; }
  .kn-mc-bub { max-width: 100%; }
  .kn-mc-send { padding: 0 10px; }
  .kn-mc-send span { display: none; }
}

/* ── 🧠 CLIE-884 · КАРТОЧКА «ВСТРЕЧА РАЗОБРАНА» В ЛЕНТЕ ПЕРЕПИСКИ ──────────────────
   Своя рама (media:true в bubbleHtml), поэтому оливкового системного пузыря под ней нет.
   Анатомия ОДНА с приложением: шапка → резюме → счётчики → действие. */
.mtc { display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--line); box-shadow: var(--shadow-1);
  cursor: pointer; max-width: 520px; transition: border-color .13s ease, box-shadow .13s ease; }
.mtc:hover { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); box-shadow: var(--shadow-2, var(--shadow-1)); }
.mtc:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.mtc-h { display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 650;
  letter-spacing: .02em; text-transform: uppercase; color: var(--muted); }
.mtc-h .ic { width: 14px; height: 14px; flex: none; }
.mtc-sum { font-size: 13.5px; line-height: 1.55; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
.mtc-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.mtc-chip { display: inline-flex; align-items: center; gap: 5px; height: 22px; padding: 0 9px;
  border-radius: 7px; font-size: 12px; font-weight: 600; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line); }
.mtc-chip .ic { width: 12px; height: 12px; opacity: .7; }
.mtc-act { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600;
  color: var(--accent); }
.mtc-act .ic { width: 14px; height: 14px; }
/* 🎙 «Созвон сохранён» (07.10.2026) — та же рама `.mtc`; главное действие «Сделать конспект» — кнопка. */
.mtc-meta { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.mtc-acts { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; }
.mtc-go { display: inline-flex; align-items: center; gap: 6px; }
.mtc-go .ic { width: 15px; height: 15px; }
/* 🎙 «Созвоны» в профиле человека — та же карточка встречи `.kn-meet-card`, в колонку профиля. */
#userProfileModal .up-meet-grid { padding: 4px 0 8px; grid-template-columns: 1fr; gap: 10px; }
/* «Конспекта нет» в теле разбора — акцент подложкой, без левых реек (канон accent). */
/* 🔴 `.kn-meet-sec` — колонка (flex-direction: column); без явного `row` основа 260px у текста уходила
   в ВЫСОТУ, и блок раздувался пустым (кадр живого прогона 07.10). */
.kn-meet-sumcta { display: flex; flex-direction: row; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  background: color-mix(in srgb, var(--accent) 10%, var(--panel)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent); }
.kn-meet-sumcta-t { display: flex; align-items: flex-start; gap: 10px; min-width: 0; flex: 1 1 260px; }
.kn-meet-sumcta-t > .ic { width: 18px; height: 18px; color: var(--accent); flex: none; margin-top: 2px; }
.kn-meet-sumcta-t > span { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.kn-meet-sumcta-t b { font-size: 14px; color: var(--text); }
.kn-meet-sumcta-t small { font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.kn-meet-sumcta .primary { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.kn-meet-sumcta .primary .ic { width: 15px; height: 15px; }

/* Модалка разбора: рама каноническая (.modal-overlay/.modal-box), здесь только ширина
   и то, что тело прокручивается САМО (иначе длинная расшифровка распирает окно). */
#meetIntelModal .modal-box { max-width: 1320px; width: 94vw; }
#meetIntelModal .modal-body { max-height: 78vh; overflow-y: auto; }
.mti-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin-bottom: 14px; }
.mti-head-t { flex: 1 1 220px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.mti-tokn { flex: none; white-space: nowrap; min-width: max-content; }
/* 🔗 Разбор встречи для гостя (/mr/<token>, `meetShareBoot`). Рама повторяет окно разбора:
   та же карточка var(--panel) с линией и радиусом `.modal-box`, ширина 1320, внутри — тот же
   `.kn-meet-detail.mti-detail`. Прокручивает `.mshare` — его знает `knMeetScroller`
   (переходы по ⏱ и главам). Своих правил тела разбора здесь НЕ заводить. */
html.cc-mshare, html.cc-mshare body { background: var(--bg); color: var(--text); }
.mshare { position: fixed; inset: 0; overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.mshare-in { max-width: 1320px; margin: 0 auto; padding: 16px 16px 40px; }
.mshare-top { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 4px 4px 12px; }
.mshare-kick { display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 15px; color: var(--text); }
.mshare-kick .ic { width: 18px; height: 18px; color: var(--primary); }
.mshare-brand { font-size: 13px; font-weight: 600; color: var(--muted); text-decoration: none; padding: 6px 10px; border-radius: 999px; border: 1px solid var(--line); }
.mshare-brand:hover { color: var(--text); background: var(--sel); }
.mshare-acts { display: inline-flex; align-items: center; gap: 8px; }
.mshare-acts .mshare-brand { display: inline-flex; align-items: center; height: var(--ctl-h, 31px); box-sizing: border-box; padding-block: 0; }
.mshare-theme { display: inline-flex; align-items: center; justify-content: center; width: var(--ctl-h, 32px); height: var(--ctl-h, 32px); padding: 0; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--muted); cursor: pointer; }
.mshare-theme:hover { color: var(--text); background: var(--sel); }
.mshare-theme .ic { width: 16px; height: 16px; }
.mshare-detail, .mshare-empty { background: var(--panel); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; }
.mshare-empty .ghost { margin-top: 8px; display: inline-flex; align-items: center; gap: 6px; }
@media (max-width: 720px) {
  .mshare-in { padding: 10px 0 32px; }
  .mshare-top { padding: 4px 14px 10px; }
  .mshare-detail, .mshare-empty { border-radius: 0; border-left: 0; border-right: 0; padding: 14px; }
}

/* ── Кто сколько говорил: горизонтальные полосы (геометрия в CSS, как .dchart/.dbar) ── */
.kn-tt { display: flex; flex-direction: column; gap: 9px; }
.kn-tt-row { display: grid; grid-template-columns: minmax(74px, 132px) 1fr auto; align-items: center; gap: 10px; }
.kn-tt-name { display: inline-flex; align-items: center; gap: 6px; min-width: 0; font-size: 12.5px; font-weight: 600;
  color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-tt-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.kn-tt-track { position: relative; height: 10px; border-radius: 999px; background: var(--panel-2);
  border: 1px solid var(--line); overflow: hidden; }
.kn-tt-bar { display: block; height: 100%; width: var(--w, 0%); border-radius: 999px;
  transition: width .16s cubic-bezier(.2,.7,.3,1); }
.kn-tt-val { display: inline-flex; align-items: baseline; gap: 6px; font-size: 12.5px; font-weight: 650;
  color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.kn-tt-ms { font-style: normal; font-weight: 500; font-size: 11px; color: var(--muted);
  font-variant-numeric: tabular-nums; }

/* ── Тон разговора: чип на спикера, оттенок по знаку оценки ── */
.kn-tone-row { display: flex; flex-wrap: wrap; gap: 8px; }
.kn-tone { display: inline-flex; align-items: baseline; gap: 6px; padding: 5px 11px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel-2); font-size: 12px; color: var(--muted); }
.kn-tone b { font-weight: 650; color: var(--text); }
.kn-tone-pos { color: var(--ok); background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
.kn-tone-neg { color: var(--danger); background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 30%, transparent); }
.kn-tone-neu { color: var(--muted); }

/* ── Плеер + расшифровка (клик по реплике перематывает запись) ── */
.kn-meet-player { width: 100%; display: block; border-radius: 12px; background: #000; }
.kn-meet-player:not(.kn-meet-video) { height: 38px; background: transparent; }
.kn-meet-video { aspect-ratio: 16 / 9; object-fit: contain; box-shadow: var(--shadow-1); }
.kn-meet-tr { display: flex; flex-direction: column; gap: 2px; margin: 0 -6px; padding: 0 6px 8px; scrollbar-width: thin; }
.kn-meet-seg { display: grid; grid-template-columns: auto minmax(0, 108px) minmax(0, 1fr); align-items: baseline; gap: 9px;
  width: 100%; padding: 7px 9px; border: 1px solid transparent; border-radius: 10px; background: transparent;
  text-align: left; cursor: pointer; font: inherit; transition: background .13s, border-color .13s; }
.kn-meet-seg:hover { background: var(--hover); }
.kn-meet-seg:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
.kn-meet-seg.on { background: var(--sel); border-color: color-mix(in srgb, var(--primary) 40%, transparent); }
.kn-meet-seg.kn-flash { animation: knFlash 1.4s ease; }
.kn-meet-seg-tc { font: 500 11px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--text-dim);
  font-variant-numeric: tabular-nums; }
.kn-meet-seg-who { display: inline-flex; align-items: baseline; gap: 6px; min-width: 0; font-size: 12px; font-weight: 600;
  color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-meet-seg-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; align-self: center; }
.kn-meet-seg-txt { font-size: 13.5px; line-height: 1.5; color: var(--text); word-break: break-word; }

/* ── «Итоги» v2: секции · ⏱ · вопросы/риски соседями · факты плитками · цитаты ── */
.kn-mv-sec { scroll-margin-top: var(--kn-mv-sm, 72px); }
.kn-mv-sec.kn-flash { animation: knFlash 1.4s ease; }
.kn-mv-tldr { background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 6%, var(--panel)), var(--panel)); }
.kn-mv-tldr .kn-meet-summary { font-size: 14.5px; line-height: 1.62; }
.kn-mv-topics { display: flex; flex-wrap: wrap; gap: 6px; }
.kn-mv-topic { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 9px 0 7px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line); font-size: 12px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.kn-mv-topic .ic { width: 12px; height: 12px; opacity: .7; flex: none; }
/* Длинная тема на узкой колонке не распирает раздел вбок: чип ужимается до ширины ряда, текст —
   с многоточием (полностью — в подсказке `data-tip`). Замер `--size mobile`: 482px при 328px. */
.kn-mv-topic { max-width: 100%; min-width: 0; }
.kn-mv-topic > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.kn-mv-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; }
.kn-mv-li { display: flex; align-items: flex-start; gap: 10px; padding: 7px 2px; }
.kn-mv-li + .kn-mv-li { border-top: 1px solid color-mix(in srgb, var(--line) 75%, transparent); }
.kn-mv-li-ic { flex: none; width: 20px; height: 20px; margin-top: 1px; border-radius: 50%; display: inline-grid; place-items: center;
  background: var(--panel-2); color: var(--muted); }
.kn-mv-li-ic .ic { width: 12px; height: 12px; }
.kn-mv-li-ic.is-ok { background: var(--ok-soft); color: var(--ok); }
.kn-mv-li-ic.is-q { background: color-mix(in srgb, var(--info) 15%, transparent); color: var(--info); }
.kn-mv-li-t { flex: 1 1 auto; min-width: 0; font-size: 13.5px; line-height: 1.5; color: var(--text); overflow-wrap: anywhere; }
.kn-mv-li > .kn-mv-tc { margin-top: 1px; }
.kn-mv-ul { gap: 6px; }
.kn-mv-owner { display: inline-flex; align-items: center; gap: 4px; height: 20px; margin-left: 4px; padding: 0 8px; border-radius: 999px;
  vertical-align: 1px; background: var(--panel-2); border: 1px solid var(--line); font-size: 11.5px; font-weight: 600;
  color: var(--muted); white-space: nowrap; }
.kn-mv-owner .ic { width: 11px; height: 11px; }
.kn-mv-sev { flex: none; width: 9px; height: 9px; margin: 6px 5px 0; border-radius: 50%; background: var(--warning);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--warning) 20%, transparent); }
.kn-mv-sev.is-high { background: var(--danger); box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 20%, transparent); }
.kn-mv-sev.is-low { background: var(--muted); box-shadow: 0 0 0 3px color-mix(in srgb, var(--muted) 18%, transparent); }
/* Итог неполный (часть окон длинной встречи модель не разобрала) — плашка ДО итогов: тон несёт
   значок и подложка (токены темы — светлая и тёмная даром), слова — читаемыми чернилами. */
.kn-mv-partial { display: flex; align-items: flex-start; gap: 9px; padding: 10px 12px; border-radius: 12px;
  font-size: 13px; line-height: 1.5; color: var(--text);
  background: color-mix(in srgb, var(--warn) 9%, var(--panel)); border: 1px solid color-mix(in srgb, var(--warn) 30%, var(--line)); }
.kn-mv-partial .ic { width: 16px; height: 16px; flex: none; margin-top: 2px; color: var(--warn); }
.kn-mv-partial b { font-weight: 650; }
.kn-mv-duo { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; align-items: start; }
.kn-mv-duo.is-two { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
/* 🔢 «Цифры и факты» — ЦИФРА ЗАГОЛОВКОМ, ПОЯСНЕНИЕ НА ВСЮ ШИРИНУ (владелец 14.10.2026: «сложно
   читать»). Раньше цифра и текст стояли колонками в одной строке: цифра забирала до половины
   карточки, таймкод — ещё 50px, и пояснению оставалось ~90px — слова рвались посреди
   («маркетин-гового»). Теперь: строка 1 — цифра и момент встречи, строка 2 — текст целиком.
   Факт без цифры — значок вида слева от текста, той же строкой. Так же устроен факт в
   приложении (`meeting_report_sections.dart → _facts`: значение крупно, текст под ним).
   🔴 `overflow-wrap: break-word`, а не `anywhere`: слово рвётся, только если не влезает целиком. */
.kn-mv-facts { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 10px; }
.kn-mv-fact { min-width: 0; display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "v tc" "t t";
  align-content: start; column-gap: 10px; row-gap: 5px; padding: 11px 12px 12px 13px; border-radius: 12px;
  background: var(--panel-2); border: 1px solid var(--line); }
.kn-mv-fact.no-v { grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "ic t tc"; align-items: start; }
.kn-mv-fact > .kn-mv-tc { grid-area: tc; align-self: start; }
.kn-mv-fact-v { grid-area: v; min-width: 0; font-size: 16px; font-weight: 720; line-height: 1.3; color: var(--primary-2);
  font-variant-numeric: tabular-nums; overflow-wrap: break-word; letter-spacing: -.005em; }
.kn-mv-fact-ic { grid-area: ic; flex: none; width: 22px; height: 22px; border-radius: 7px; display: inline-grid; place-items: center;
  background: var(--sel); color: var(--primary-2); }
.kn-mv-fact-ic .ic { width: 13px; height: 13px; }
.kn-mv-fact-t { grid-area: t; min-width: 0; font-size: 13px; line-height: 1.5; color: var(--text); overflow-wrap: break-word; }
.kn-mv-fact.no-v .kn-mv-fact-t { padding-top: 1px; }
.kn-mv-quotes { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 10px; }
.kn-mv-quote { margin: 0; display: flex; flex-direction: column; gap: 8px; padding: 12px 14px; border-radius: 12px;
  background: var(--panel-2); border: 1px solid var(--line); }
.kn-mv-quote blockquote { margin: 0; font-size: 13.5px; line-height: 1.55; font-style: italic; color: var(--text); }
.kn-mv-quote figcaption { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 600; color: var(--muted); }
.kn-mv-quote figcaption .kn-mv-tc { margin-left: auto; }

/* ── Расшифровка v2: поиск · чипы спикеров · главы разделителями · реплика в две строки ── */
.kn-mv-tr-tools { display: flex; flex-direction: column; gap: 8px; }
.kn-mv-tr-q { flex: none; width: 100%; min-width: 0; box-sizing: border-box; }
.kn-mv-spk { display: flex; flex-wrap: wrap; gap: 6px; }
.kn-mv-spk-c { display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); font: inherit; font-size: 12px; font-weight: 600;
  white-space: nowrap; min-width: max-content; cursor: pointer; transition: background .13s, color .13s, border-color .13s; }
.kn-mv-spk-c:hover { color: var(--text); border-color: var(--line-strong); background: var(--hover); }
.kn-mv-spk-c.on { color: var(--text); background: var(--sel); border-color: color-mix(in srgb, var(--primary) 45%, transparent); }
.kn-mv-spk-c:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
.kn-mv-spk-c em { font-style: normal; font-size: 11px; font-weight: 600; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.kn-mv-tr-list { position: relative; }
.kn-mv-tr-list .kn-meet-seg { grid-template-columns: 40px minmax(0, 1fr); column-gap: 8px; row-gap: 1px; padding: 6px 8px; }
.kn-mv-tr-list .kn-meet-seg-txt { grid-column: 2; }
.kn-mv-tr-ch { display: flex; align-items: center; gap: 7px; margin: 8px 0 2px; padding: 9px 8px 3px;
  border-top: 1px solid var(--line); font-size: 12px; font-weight: 650; color: var(--text); }
.kn-mv-tr-ch:first-child { margin-top: 0; padding-top: 2px; border-top: 0; }
.kn-mv-tr-ch .ic { width: 13px; height: 13px; flex: none; color: var(--primary); }
.kn-mv-tr-ch span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-mv-tr-ch em { margin-left: auto; font: 500 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; font-style: normal; color: var(--text-dim); }
.kn-mv-tr.is-filtered .kn-mv-tr-ch { display: none; }

/* ── «Аналитика» v2: индекс по частям · кто когда говорил · темп · паузы · баланс · главы · итог ── */
.kn-mv-agrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 14px; align-items: start; }
.kn-mv-score { display: flex; align-items: center; flex-wrap: wrap; gap: 16px 24px; }
.kn-mv-score .kn-mv-ring { margin-left: 0; }
.kn-mv-sp-list { flex: 1 1 300px; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.kn-mv-sp { display: grid; grid-template-columns: minmax(92px, 140px) minmax(0, 1fr) 64px; align-items: center; gap: 10px; }
.kn-mv-sp-l { font-size: 12.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-mv-sp-track { height: 8px; border-radius: 999px; background: var(--panel-2); border: 1px solid var(--line); overflow: hidden; }
.kn-mv-sp-track i { display: block; height: 100%; width: var(--w, 0%); border-radius: 999px; background: var(--primary);
  transition: width .16s cubic-bezier(.2,.7,.3,1); }
.kn-mv-sp.is-missing .kn-mv-sp-track { border-style: dashed; background: transparent; }
.kn-mv-sp-v { text-align: right; font-size: 12.5px; font-weight: 650; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.kn-mv-sp-v em { font-style: normal; font-weight: 500; color: var(--muted); }
.kn-mv-sp.is-missing .kn-mv-sp-v { color: var(--text-dim); cursor: help; }
.kn-mv-tl { display: flex; align-items: stretch; gap: 2px; height: 76px; }
.kn-mv-tl-col { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column-reverse; padding: 0; border: 0; border-radius: 4px;
  background: color-mix(in srgb, var(--text) 5%, transparent); overflow: hidden; cursor: pointer; transition: background .13s ease; }
.kn-mv-tl-col:hover { background: color-mix(in srgb, var(--text) 11%, transparent); }
.kn-mv-tl-col:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.kn-mv-tl-col i { display: block; flex: none; width: 100%; }
.kn-mv-tl-axis { display: flex; justify-content: space-between; margin-top: -4px;
  font: 500 10.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.kn-mv-tl-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12px; font-weight: 600; color: var(--muted); }
.kn-mv-tl-lg { display: inline-flex; align-items: center; gap: 6px; }
.kn-mv-pace { display: flex; flex-direction: column; }
.kn-mv-pace-r { display: grid; grid-template-columns: minmax(96px, 1.3fr) repeat(var(--kn-mv-pace-n, 3), minmax(72px, 1fr));
  align-items: center; gap: 10px; padding: 7px 2px; font-size: 13px; color: var(--text); font-variant-numeric: tabular-nums; }
.kn-mv-pace-r + .kn-mv-pace-r { border-top: 1px solid color-mix(in srgb, var(--line) 75%, transparent); }
.kn-mv-pace-r.is-h { padding-top: 0; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.kn-mv-pace-r > span:not(:first-child) { text-align: right; }
.kn-mv-pace-who { display: inline-flex; align-items: center; gap: 7px; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-mv-pace-c.is-none { color: var(--text-dim); }
.kn-mv-statgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); gap: 8px; }
.kn-mv-stat { min-width: 0; display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: 11px;
  background: var(--panel-2); border: 1px solid var(--line); }
.kn-mv-stat b { font-size: 19px; font-weight: 720; line-height: 1.2; letter-spacing: -.01em; color: var(--text); font-variant-numeric: tabular-nums; }
.kn-mv-stat span { font-size: 12px; line-height: 1.3; color: var(--muted); }
.kn-mv-bal { --bal: var(--warning); display: flex; align-items: center; gap: 14px; }
.kn-mv-bal.is-ok { --bal: var(--ok); }
.kn-mv-bal.is-low { --bal: var(--danger); }
.kn-mv-bal > b { flex: none; font-size: 26px; font-weight: 750; letter-spacing: -.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.kn-mv-bal > b em { font-style: normal; font-size: 15px; font-weight: 650; color: var(--muted); }
.kn-mv-bal-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.kn-mv-bal-track { height: 8px; border-radius: 999px; background: var(--panel-2); border: 1px solid var(--line); overflow: hidden; }
.kn-mv-bal-track i { display: block; height: 100%; width: var(--w, 0%); border-radius: 999px; background: var(--bal); }
.kn-mv-chs-bar { display: flex; height: 14px; border-radius: 999px; background: var(--panel-2); border: 1px solid var(--line); overflow: hidden; }
.kn-mv-chs-part { flex: none; width: var(--w, 0%); height: 100%; padding: 0; border: 0; border-radius: 0; cursor: pointer; transition: filter .13s ease; }
.kn-mv-chs-part + .kn-mv-chs-part { box-shadow: inset 1px 0 0 var(--panel); }
.kn-mv-chs-part:hover { filter: brightness(1.12) saturate(1.1); }
.kn-mv-chs-list { display: flex; flex-direction: column; gap: 1px; margin: 0 -6px; }
.kn-mv-chs-row { display: grid; grid-template-columns: 10px minmax(0, 1fr) auto auto; align-items: center; gap: 8px; width: 100%;
  padding: 5px 6px; border: 0; border-radius: 8px; background: transparent; color: var(--text); font: inherit; text-align: left;
  cursor: pointer; transition: background .13s ease; }
.kn-mv-chs-row:hover { background: var(--hover); }
.kn-mv-chs-row:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--sel); }
.kn-mv-chs-row > i { width: 9px; height: 9px; border-radius: 3px; }
.kn-mv-chs-row > span { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-mv-chs-row > b { font-size: 12.5px; font-weight: 650; font-variant-numeric: tabular-nums; }
.kn-mv-chs-row > em { font: 500 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; font-style: normal; color: var(--text-dim); }

/* ── Оглавление встречи: ТЕ ЖЕ строки, что в отчёте записи ──────────────────
 * Второй реализации глав в продукте нет: карточка встречи берёт ту же фабрику
 * (`recChaptersHtml`) и лишь СНИМАЕТ с `.rec-ch-list` собственную рамку — внутри
 * `.kn-meet-sec` коробка-в-коробке читалась бы как ещё один блок. Наводка и фокус —
 * на языке карточки (var(--hover) / var(--sel)), чтобы оглавление и расшифровка,
 * стоящие рядом, вели себя одинаково; оба токена определены в обеих темах. */
.kn-meet-chsec .rec-ch-list { border: 0; background: transparent; padding: 0; margin: 0 -3px; }
.kn-meet-chsec .rec-tr-seg { gap: 9px; padding: 7px 9px; border: 1px solid transparent; border-radius: 10px; }
.kn-meet-chsec .rec-tr-seg + .rec-tr-seg { margin-top: 2px; }
.kn-meet-chsec .rec-tr-seg:hover { background: var(--hover); }
.kn-meet-chsec .rec-tr-seg:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
/* Таймкод — тот же моноширинный столбик, что у реплики (.kn-meet-seg-tc): встык друг
   под другом две разные типографики читались бы как два разных списка. */
.kn-meet-chsec .rec-tr-t { min-width: 42px; padding-top: 2px;
  font: 500 11px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--text-dim); }

/* ── Связанная память + личный коуч ── */
.kn-meet-memgrid { padding: 0; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
.kn-meet-mem { padding: 12px 13px; gap: 6px; }
.kn-meet-mem .kn-scope { cursor: default; }
.kn-meet-mem .kn-scope:hover { background: var(--panel-2); color: var(--muted); border-color: var(--line); }
.kn-meet-mem .kn-ttl:hover, .kn-meet-mem .kn-txt:hover { background: transparent; }
.kn-meet-coach { border-color: color-mix(in srgb, var(--primary) 34%, var(--line));
  background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 6%, var(--panel)), var(--panel)); }
.kn-meet-coach .kn-meet-sec-h { color: var(--primary); }
.kn-meet-coach-b { display: flex; flex-direction: column; gap: 7px; }
.kn-meet-coach-l { position: relative; padding-left: 15px; font-size: 13.5px; line-height: 1.55; color: var(--text); }
.kn-meet-coach-l::before { content: ""; position: absolute; left: 3px; top: .62em; width: 5px; height: 5px;
  border-radius: 50%; background: var(--primary); opacity: .8; }
.kn-meet-priv { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--text-dim); }
.kn-meet-priv .ic { width: 12px; height: 12px; }

/* ── «Спросить»: микро-переключатель области (Везде ‖ Только встречи) + источник-реплика ── */
.kn-ask-only { margin: 0 auto 10px; width: max-content; max-width: 100%; background: var(--panel-2); }
.kn-ask-only button { padding: 5px 11px; font-size: 12px; color: var(--text-dim); }
.kn-ask-only button .ic { width: 13px; height: 13px; }
.kn-ask-only button:not(.active):hover { color: var(--muted); }
.kn-ask-meetsrc .kn-meet-tc { height: 18px; padding: 0 6px; font-size: 10.5px; }
.kn-ask-meetsrc .kn-meet-who { font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kn-ask-meet-ttl { font-size: 13px; }
.kn-meet-badge { color: var(--info); background: color-mix(in srgb, var(--info) 16%, transparent); }

@media (max-width: 720px) {
  .kn-meet-top, .kn-meet-dh { padding-left: 14px; padding-right: 14px; }
  .kn-mv { padding: 14px 14px 40px; }
  .kn-mv-hero { padding: 12px 12px 14px; }
  .kn-mv-ring { margin-left: 0; }
  .kn-mv-tiles { grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); }
  .kn-meet-hits { padding: 14px 14px 40px; }
  /* minmax(0,…): колонка `1fr` растёт до min-content карточки (замер --size mobile: карточки 815px
     при 328px раздела) — ноль снизу держит её в ширине раздела. */
  .kn-meet-grid { grid-template-columns: minmax(0, 1fr); }
  .kn-meet-memgrid { grid-template-columns: 1fr; }
  .kn-tt-row { grid-template-columns: minmax(64px, 96px) 1fr auto; gap: 8px; }
  .kn-meet-seg { grid-template-columns: auto minmax(0, 1fr); row-gap: 2px; }
  .kn-meet-seg-txt { grid-column: 1 / -1; }
}

/* ── «ИИ помнит»: проактивный рельс памяти на карточке задачи (реюз токенов «Базы знаний») ── */
.td-mem-rail[hidden], .tip-mem-card[hidden] { display: none !important; }
.tip-mem-card .td-mem-h { margin-bottom: 2px; }
.td-mem-h { display: flex; align-items: center; gap: 6px; color: var(--primary-2, var(--primary)); }
.td-mem-h svg { width: 15px; height: 15px; opacity: .9; }
/* «ИИ помнит» — сворачиваемый заголовок-тумблер (CLIE-315): весь заголовок кликабелен, шеврон
   поворачивается. Сброс стилей кнопки + наследуем типографику .td-section-h.
   Габариты строки (высота/поля/ховер) задаёт общий .tip-disc-h — см. «СТРОКА-РАСКРЫТИЕ». */
.td-mem-toggle { border: 0; background: none; font: inherit; cursor: pointer; text-align: left; }
.td-mem-toggle .td-mem-lbl { flex: 0 0 auto; }
.td-mem-toggle .td-mem-chev { margin-left: auto; display: inline-flex; align-items: center;
  transition: transform .16s ease; opacity: .7; }
.td-mem-toggle .td-mem-chev svg { width: 14px; height: 14px; }
.td-mem-toggle.collapsed .td-mem-chev { transform: rotate(-90deg); }
.td-mem-toggle:hover { color: var(--primary); }
.td-mem-toggle:hover .td-mem-chev { opacity: 1; }
.td-mem-toggle:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 2px; border-radius: 4px; }
/* шеврон замыкает строку справа (margin-left:auto) — отдельный ::after-хэйрлайн секции лишний */
.task-info-panel .td-section-h.td-mem-toggle::after,
.td-mem-toggle.td-section-h::after { content: none; }
.td-mem-list[hidden] { display: none !important; }
.td-mem-list { display: flex; flex-direction: column; gap: 7px; margin-top: 8px; }
/* Подзаголовок рельса — что тут показано (честный провенанс, а не догадка по важности). */
.td-mem-sub { font-size: 11.5px; line-height: 1.4; color: var(--muted); margin: -1px 0 3px; }
.td-mem-card { display: flex; flex-direction: column; align-items: stretch; gap: 7px; padding: 9px 11px; border-radius: 12px;
  border: 1px solid var(--line); background: color-mix(in srgb, var(--primary) 5%, var(--panel));
  cursor: pointer; transition: border-color .14s ease, background .14s ease, transform .14s ease; }
.td-mem-card:hover { border-color: color-mix(in srgb, var(--primary) 45%, var(--line));
  background: color-mix(in srgb, var(--primary) 9%, var(--panel)); transform: translateY(-1px); }
.td-mem-card:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 1px; }
.td-mem-top { display: flex; align-items: center; gap: 8px; }
.td-mem-card .kn-badge { flex: 0 0 auto; }
.td-mem-ttl { min-width: 0; font-size: 12.5px; line-height: 1.35; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
/* Провенанс-чипы (почему запись тут): «использовал» / «записал». Тонкие, спокойные, справа. */
.td-mem-provs { flex: 0 0 auto; margin-left: auto; display: inline-flex; align-items: center; gap: 6px; }
.td-mem-prov { display: inline-flex; align-items: center; gap: 3px; font-size: 10.5px; font-weight: 600;
  letter-spacing: .1px; padding: 2px 7px; border-radius: 999px; white-space: nowrap; }
.td-mem-prov svg { width: 11px; height: 11px; }
.td-mem-prov.used { color: color-mix(in srgb, var(--primary) 82%, var(--text));
  background: color-mix(in srgb, var(--primary) 13%, transparent); }
.td-mem-prov.rec { color: var(--muted); background: color-mix(in srgb, var(--muted) 15%, transparent); }
/* Мета-строка карточки: РЕАЛЬНЫЙ запрос ИИ («искал: «…»») + когда использовал. Прямой ответ на
   «откуда он знает, о чём речь» — показываем сам запрос, а не догадку. Пусто → строки нет. */
.td-mem-meta { display: flex; align-items: center; gap: 6px; flex-wrap: nowrap; min-width: 0;
  font-size: 11px; line-height: 1.3; color: var(--muted); }
/* Запрос забирает свободное место и при нехватке ellipsis'ится — «+N · время» всегда одной строкой. */
.td-mem-q { display: inline-flex; align-items: center; gap: 4px; flex: 1 1 auto; min-width: 0;
  color: color-mix(in srgb, var(--primary) 68%, var(--text)); }
.td-mem-q svg { width: 11px; height: 11px; flex: 0 0 auto; opacity: .85; }
.td-mem-qtxt { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-mem-qmore { flex: 0 0 auto; font-weight: 600; opacity: .85; padding: 0 5px; border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 12%, transparent); }
.td-mem-when { flex: 0 0 auto; color: var(--muted); font-variant-numeric: tabular-nums; }
.td-mem-dot { flex: 0 0 auto; opacity: .5; }
/* «Показать все (N)» — раскрытие сверх порога (по умолчанию видим топ-5). Спокойная строка-кнопка. */
.td-mem-more-wrap[hidden] { display: none !important; }
.td-mem-more-wrap { display: flex; flex-direction: column; gap: 7px; margin-top: 7px; }
.td-mem-more { width: 100%; display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  border: 1px solid var(--line); background: none; cursor: pointer; color: var(--muted); font: inherit;
  font-size: 11.5px; font-weight: 600; padding: 6px 10px; border-radius: 10px;
  transition: border-color .14s ease, color .14s ease, background .14s ease; }
.td-mem-more svg { width: 13px; height: 13px; opacity: .8; }
.td-mem-more:hover { color: var(--primary);
  border-color: color-mix(in srgb, var(--primary) 40%, var(--line));
  background: color-mix(in srgb, var(--primary) 6%, transparent); }
.td-mem-more:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 2px; }

/* ── Фильтр рельса по типу (Все · Правило · Факт · …) — сегмент-чипы. Рисуются только когда типов
   больше одного (иначе бесполезны). Клик мгновенно фильтрует. Apple-grade: pill, hairline, мягкие
   состояния, активный — в ИИ-тоне (--primary). ── */
.td-mem-filters { display: flex; flex-wrap: wrap; gap: 6px; margin: 3px 0 10px; }
.td-mem-fchip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--panel); color: var(--muted); font: inherit; font-size: 11.5px;
  font-weight: 600; cursor: pointer; white-space: nowrap;
  transition: border-color .14s ease, color .14s ease, background .14s ease; }
.td-mem-fchip:hover { color: var(--text); border-color: color-mix(in srgb, var(--primary) 35%, var(--line)); }
.td-mem-fchip .td-mem-fn { font-size: 10.5px; font-weight: 700; opacity: .65; font-variant-numeric: tabular-nums; }
.td-mem-fchip.on { color: color-mix(in srgb, var(--primary) 85%, var(--text));
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.td-mem-fchip.on .td-mem-fn { opacity: .95; }
.td-mem-fchip:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 1px; }
.td-mem-cards { display: flex; flex-direction: column; gap: 7px; }
.td-mem-empty { padding: 12px 2px; text-align: center; }

/* ── Большая модалка деталей знания (клик по карточке рельса). Широкий вариант cc-entmodal
   (2-классовая специфичность бьёт базовые 420px). Полный текст + запросы ИИ + мета + теги. ── */
.cc-entmodal.tm-modal { max-width: 640px; }
.tm-modal .tm-modal-b { max-height: 72vh; }
.tm-modal-h .kn-badge.tm-modal-kind { flex: 0 0 auto; }
.tm-modal-h .tm-modal-provs { margin-left: 2px; }
.tm-modal-h .x { margin-left: auto; }
.tm-modal-title { font-size: 17px; line-height: 1.35; font-weight: 700; color: var(--text); margin: 0 0 10px; overflow-wrap: anywhere; }
.cc-entmodal.tm-modal .tm-modal-body { font-size: 14px; line-height: 1.6; color: var(--text); }
.tm-modal-sec { margin-top: 16px; }
.tm-modal-sk { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 700; letter-spacing: .3px;
  text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
.tm-modal-sk svg { width: 13px; height: 13px; opacity: .8; }
.tm-modal-qs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.tm-modal-qs li { padding: 7px 11px; border-radius: 10px; font-size: 13px; line-height: 1.4; color: var(--text);
  background: color-mix(in srgb, var(--primary) 6%, var(--panel-2));
  border: 1px solid color-mix(in srgb, var(--primary) 14%, var(--line)); overflow-wrap: anywhere; }
.tm-modal-meta { margin-top: 16px; display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--line); padding-top: 12px; }
.tm-modal-mrow { display: flex; align-items: center; gap: 8px; font-size: 13px; padding: 5px 0; }
.tm-modal-mrow svg { width: 14px; height: 14px; color: var(--muted); flex: 0 0 auto; }
.tm-modal-mrow .k { color: var(--muted); flex: 0 0 auto; min-width: 108px; }
.tm-modal-mrow .v { color: var(--text); font-weight: 500; overflow-wrap: anywhere; }
.tm-modal-rel { color: var(--muted); font-weight: 400; }
.tm-modal-dots { display: inline-flex; align-items: center; gap: 3px; }
.tm-modal-dots i { width: 6px; height: 6px; border-radius: 50%; background: var(--line); }
.tm-modal-dots i.on { background: var(--primary); }
.tm-modal-tags { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 6px; }
.tm-modal-tag { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; color: var(--muted);
  padding: 3px 9px; border-radius: 999px; border: 1px solid var(--line); background: var(--panel-2); }
.tm-modal-tag svg { width: 11px; height: 11px; opacity: .7; }

/* ══════════════════════════════════════════════════════════════════════════════
   РЕЖИМ ВИДЖЕТА (/widget внутри админки клиента) — ТОТ ЖЕ чат, что /app, но чистый
   scoped-вид под клиентскую личность: без глобальной шапки, без внутренней навигации
   и пустых для клиента столбцов. Композер и ВСЕ функции сообщений (голосовые, кружки,
   файлы, эмодзи/стикеры, ответы) — как в основном чате (это и ЕСТЬ основной чат).
   Всё строго за html.cc-widget → /app не затрагивается.
   ══════════════════════════════════════════════════════════════════════════════ */
html.cc-widget, html.cc-widget body { height: 100%; }
html.cc-widget .topbar { display: none !important; }            /* нет глобальной шапки… */
html.cc-widget .screen { height: 100%; }                        /* …экран на всю высоту iframe */
html.cc-widget #chatRail,                                       /* внутренняя навигация — клиенту не нужна */
html.cc-widget .projects-col { display: none !important; }      /* столбик проектов (пуст у клиента) */
html.cc-widget #notifyBanner,                                   /* баннеры уведомлений/«Обновить» внутри */
html.cc-widget #cc-web-update-bar { display: none !important; } /* админки клиента не показываем */
html.cc-widget .thread-head { padding-right: 56px; }            /* место под крестик «Закрыть» */
/* «Пространство задач» (полноэкранная страница видов) теперь доступно и клиенту — кнопка ⛶ в шапке
   столбца открывает его (widgetOpenTasksWorkspace), заскоупленное на проект. Кнопку НЕ прячем. */
/* По умолчанию (узко/мобила) столбик задач в виджете скрыт — места мало (как основной чат) */
html.cc-widget .tasks-col { display: none !important; }

/* Экран виджета = CSS-grid. Рельс(96px) и проекты клиенту скрыты → выпадают из потока grid.
   Задачи проекта = НАСТОЯЩИЙ левый столбик #tasksCol (как «Мои задачи» в /app). Порог ≥1081px
   выбран РОВНО как в основном чате: именно там родная механика даёт --rw-tasks (250→42px при
   сворачивании→0 при скрытии) и прячет содержимое свёрнутого столбца. Показываем столбик там же —
   тогда И шов-ресайз (задачи↔чаты), И сворачивание работают. Сетка ТРИ колонки [задачи·чаты·тред].
   В УЗКОМ (640–1080px) места мало → столбик прячем (как основной чат на средних), [чаты · тред]. */
@media (min-width: 1081px) {
  html.cc-widget .tasks-col { display: flex !important; }
  html.cc-widget .chat,
  html.cc-widget .chat.show-thread {
    grid-template-columns: minmax(0, var(--rw-tasks)) minmax(0, var(--w-chats, 300px)) minmax(var(--thread-min, 380px), 1fr) !important;
  }
}
@media (min-width: 640px) and (max-width: 1080px) {
  html.cc-widget .chat,
  html.cc-widget .chat.show-thread {
    grid-template-columns: minmax(0, var(--w-chats, 300px)) minmax(var(--thread-min, 380px), 1fr) !important;
  }
}

/* ── ВИДЖЕТ · ПРОСТРАНСТВО ЗАДАЧ (отдельная страница видов) ────────────────────────────────
   Оверлей #tasksWorkspace в /app начинается за рельсом (inset:0 0 0 96px). В виджете рельса нет
   (скрыт), поэтому пространство занимает ВСЮ ширину iframe (inset:0). Место под крестик «Закрыть»
   виджета (#ccWidgetClose, top-right) даём отступом справа в шапке пространства.
   🔴 БЕЗ `!important` (CLIE-1006): специфичности (1,1,1) и так хватает над базовым
   `.tasks-workspace`, а «важность» делала правило НЕПЕРЕБИВАЕМЫМ для островной шкуры —
   раздел вылезал за холст и терял скругление. Шкура догоняет его своим правилом
   (island.css, блок «ВИДЖЕТ АДМИНКИ КЛИЕНТА»), и только когда шкура включена. */
html.cc-widget #tasksWorkspace { inset: 0; }
html.cc-widget #tasksWorkspace .tw-head { padding-right: 56px; }
/* Шапка «Задач» на телефоне — два ряда: название · счётчик · Шаблоны · ＋ · ✕ сверху, вкладки видов
   снизу во всю ширину (листаются пальцем). В один ряд вкладки (284 px) выдавливали «Шаблоны»,
   «＋ Задача» и «Закрыть» за правый край окна (316 px при экране 390), а название сжималось в ноль:
   раздел на телефоне было нечем закрыть (кадр «Штиля» 19.10). Подписи кнопок уходят — остаются
   значки с подсказкой. «Глубина» раскладывает так же своим правилом (depth.css §6, вес выше). */
@media (max-width: 640px) {
  #tasksWorkspace .tw-head { flex-wrap: wrap; gap: 8px; }
  #tasksWorkspace .tw-head > #twSeg { order: 10; flex: 1 1 100%; min-width: 0; max-width: 100%; }
  #tasksWorkspace .tw-head > .tw-title { flex: 1 1 0; min-width: 0; text-overflow: ellipsis; white-space: nowrap; }
  #tasksWorkspace .tw-head > :is(#twTpl, #twNew) > span { display: none; }
  #tasksWorkspace .tw-head > #twNew { min-width: 0; padding-inline: 10px; }
}
/* Клиенту не нужны служебные тумблеры пространства: «Выбрать» (массовые правки → 403), «Идёт»
   (мой таймер — у клиента нет), «Из встреч», «Повтор» (внутренние понятия). Остаются фильтры
   вида (исполнитель/метка/срок/статус/приоритет/поиск) + «Архив» и «ИИ». Меньше элементов — лучше. */
html.cc-widget #tasksWorkspace #twSelect,
html.cc-widget #tasksWorkspace #twRunBtn,
html.cc-widget #tasksWorkspace #twMeetBtn,
html.cc-widget #tasksWorkspace #twRecBtn { display: none !important; }
/* «＋ Пожелание» — инлайн-форма создания в теле пространства (прогрессивно). Apple-grade карточка. */
.ccw-ws-cform-host { padding: 10px 14px 2px; }
.ccw-ws-cform-host .ccw-cform {
  display: flex; flex-direction: column; gap: 8px;
  background: var(--panel, var(--cm-171a21, #171a21)); border: 1px solid var(--line, #2a2f3a);
  border-radius: 12px; padding: 12px; box-shadow: 0 6px 20px rgba(10,14,22,.14);
}
.ccw-ws-cform-host .ccw-cform-in {
  width: 100%; border: 1px solid var(--line, #2a2f3a); border-radius: 9px;
  background: var(--bg, #0f1115); color: var(--text, #e6e9ef);
  padding: 9px 11px; font-size: 14px; outline: none;
  transition: border-color .14s ease, box-shadow .14s ease;
}
.ccw-ws-cform-host .ccw-cform-in:focus {
  border-color: var(--accent, var(--cm-5b8cff, #5b8cff));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent, var(--cm-5b8cff, #5b8cff)) 22%, transparent);
}
.ccw-ws-cform-host .ccw-cform-row { display: flex; justify-content: flex-end; gap: 8px; }

#ccWidgetClose {
  position: fixed; top: 12px; right: 14px; z-index: 4000;
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--line, #2a2f3a); border-radius: 999px; cursor: pointer;
  background: var(--panel, var(--cm-171a21, #171a21)); color: var(--text, #e6e9ef);
  box-shadow: 0 6px 18px rgba(10,14,22,.28);
  transition: transform .14s cubic-bezier(.2,.8,.2,1), background .14s ease;
}
#ccWidgetClose:hover { transform: scale(1.07); }
html:not(.cc-widget) #ccWidgetClose { display: none !important; }

/* ── ВИДЖЕТ · ЭКРАН ВХОДА (реальный аккаунт ClientsChat) ───────────────────────────
   Клиент входит/регистрируется прямо в виджете (телефон+код) → авто-участник проекта под
   ролью «клиент». Экран входа = наш родной #loginScreen; в iframe центрируем карточку и даём
   воздух. Всё за html.cc-widget → /app не затрагивается. Светлая И тёмная — из общих токенов. */
html.cc-widget .screen.login { display: flex; align-items: center; justify-content: center; padding: 24px 18px; overflow: auto; }
html.cc-widget .screen.login .card { width: 100%; max-width: 380px; margin: auto; }

/* ══════════════════════════════════════════════════════════════════════════════
   ВИДЖЕТ · клиентские полировки + ЗАДАЧИ ПРОЕКТА (родной левый столбик #tasksCol)
   Всё за html.cc-widget → /app не затрагивается. Apple-grade, светлая И тёмная
   тянутся из общих токенов (--panel/--text/--line/--muted/--accent).
   ══════════════════════════════════════════════════════════════════════════════ */
/* Клиенту не нужны истории и служебные фильтры «Эфиры»/«ИИ»/«Тикеты» — убираем из режима
   виджета (владелец: клиенту они пустые/лишние). Остаются: Все · Чаты · Группы · Задачи · Новые. */
html.cc-widget #chatStories { display: none !important; }
html.cc-widget #convTabs [data-ctab="streams"],
html.cc-widget #convTabs [data-ctab="ai"],
html.cc-widget #convTabs [data-ctab="tickets"] { display: none !important; }

/* Чистый клиентский экран: убираем /app-ные плавающие/служебные контролы, у клиента мёртвые или
   неуместные. Всё строго html.cc-widget → /app не затрагивается (класс есть только на /widget). */
html.cc-widget #qcFab { display: none !important; }   /* плавающий «быстрый чат» /app — в виджете лишний пузырь */
/* Карточка задачи: у клиента нет доски, шаблонов/дублей/архива и /app-ссылки на задачу — прячем
   эти контролы шапки. Суть остаётся: описание, чек-листы, заметки, чат задачи, медиа, история,
   наблюдение (глаз) и «Закрыть» (возврат в чаты). */
html.cc-widget #tipShareBtn,
html.cc-widget #taskInfoPanel [data-tip="board"],
html.cc-widget #taskInfoPanel [data-tip="more"] { display: none !important; }

/* ── Пилюли статуса / приоритета (строка задачи в столбце) ── */
.ccw-prio { width: 8px; height: 8px; border-radius: 999px; flex: 0 0 auto; }
.ccw-pill {
  display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 650; line-height: 1.4; white-space: nowrap; color: var(--pc);
  background: color-mix(in srgb, var(--pc) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--pc) 32%, transparent);
}
.ccw-pbadge {
  display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 650; color: var(--pc);
  background: color-mix(in srgb, var(--pc) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--pc) 32%, transparent);
}

/* ── Строка задачи в столбце «Задачи проекта» (Apple-grade, тон как карточки /app) ── */
.ccw-col-row {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 9px 10px; border-radius: 11px; background: transparent; color: var(--text);
  cursor: pointer; transition: background .12s ease; outline: none;
}
.ccw-col-row + .ccw-col-row { margin-top: 2px; }
.ccw-col-row:hover { background: var(--panel-2); }
.ccw-col-row:focus-visible { box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 55%, transparent); }
.ccw-col-main { display: flex; align-items: center; gap: 7px; flex: 1; min-width: 0; }
.ccw-col-num { font-size: 11.5px; color: var(--text-dim, var(--muted)); font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.ccw-col-title { flex: 1; min-width: 0; font-size: 13.5px; line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ccw-col-row .ccw-pill { flex: 0 0 auto; }

/* ── Пустое состояние столбца ── */
.ccw-col-empty { padding: 18px 14px; text-align: center; list-style: none; }
.ccw-col-empty-t { font-size: 14px; font-weight: 650; color: var(--text); margin-bottom: 5px; }
.ccw-col-empty-s { font-size: 12px; line-height: 1.5; color: var(--muted); margin-bottom: 14px; }
.ccw-col-empty-cta,
.ccw-cform-ok {
  display: inline-flex; align-items: center; justify-content: center;
  height: 34px; padding: 0 15px; border: 0; border-radius: 10px;
  background: var(--acc-fill); color: #fff; cursor: pointer; font-size: 13px; font-weight: 620;
  transition: filter .14s ease, transform .12s ease;
}
.ccw-col-empty-cta:hover, .ccw-cform-ok:hover { filter: brightness(1.06); transform: translateY(-1px); }
.ccw-cform-ok:disabled { opacity: .6; cursor: default; transform: none; filter: none; }

/* ── Инлайн-форма создания пожелания (в столбце; прогрессивное раскрытие по «+») ── */
.ccw-cform {
  display: flex; flex-direction: column; gap: 8px; padding: 10px; list-style: none;
  margin: 0 0 4px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2);
}
.ccw-cform-in {
  width: 100%; box-sizing: border-box; padding: 9px 11px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--panel); color: var(--text); font: inherit; font-size: 13.5px; outline: none;
  transition: border-color .14s ease, box-shadow .14s ease;
}
.ccw-cform-in:focus { border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent); }
.ccw-cform-row { display: flex; gap: 8px; justify-content: flex-end; }
.ccw-cform-cancel {
  height: 34px; padding: 0 13px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel); color: var(--text); cursor: pointer; font-size: 13px; font-weight: 560;
  transition: background .14s ease;
}
.ccw-cform-cancel:hover { background: var(--panel-3, var(--panel-2)); }

/* ═══════════════════════════ CRM «Продажи» (Sales) ═══════════════════════════ */
/* Реюз каркаса .tasks-workspace + движка доски .tw-board/.tw-col/.tw-card (app.js buildSalesShell/
   renderSalesBoard). Ниже — надстройка карточки сделки и видов Список/Таймлайн/Прогноз + drawer.
   Обе темы автоматически: всё на дизайн-токенах (--panel/--line/--muted/--primary/--danger-soft). */

/* ── Шапка модуля «Продажи»: РАЗДЕЛЫ (одна строка) + контекстная строка ВИДОВ ─────────────
   Root cause прежней шапки: 15 вкладок в один ряд `.tw-seg` (flex:0 0 auto — не сжимается) →
   при окне 1600px строке нужно 1756px: «＋ Сделка» и «✕» уезжали ЗА экран, «Рассылки»/
   «Веб-форма» обрезались, а скролла нет. Лечение — не скролл, а иерархия: 6 разделов сверху,
   виды раздела — отдельной тонкой строкой (только там, где видов больше одного).
   Компоненты НЕ новые: разделы = единый таб-движок `.cc-tabs` (как #twSeg в «Задачах»),
   виды = `.cc-seg` (iOS-сегмент). Скоуп строго #salesWorkspace — доска задач НЕ затрагивается.
   База .primary = width:100% (мобильный CTA) — в шапке НЕ растягиваем. */
#salesWorkspace .tw-head { gap: 10px; padding: 0 14px 0 16px; height: 56px; min-height: 56px; }
/* Кнопки шапки — фиксированной высоты (иначе строка «прыгает» на 3px там, где «＋ Сделка»
   скрыта) и в одну строку: без white-space иконка+подпись переносились в два ряда. */
#salesWorkspace .tw-head .primary,
#salesWorkspace .tw-head .ghost {
  width: auto; flex: 0 0 auto; margin-top: 0;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: 34px; padding: 0 13px; white-space: nowrap; border-radius: 10px;
}
#salesWorkspace .tw-head #salesClose { width: 34px; padding: 0; font-size: 13px; color: var(--muted); }
#salesWorkspace .tw-head #salesClose:hover { color: var(--text); }
#salesWorkspace .tw-head .tw-title { flex: 0 0 auto; max-width: none; }
#salesWorkspace .tw-head .tw-count { flex: 0 0 auto; margin-left: -4px; }
/* Пустой счётчик (#salesCount = "" у Маркетинга, ИИ-ботов, Склада…) не держит места: gap шапки
   10 + margin -4 = 6 px сдвига ряда разделов вправо (замер: дорожка с x 189 против 181 у разделов,
   где ступень fit-1 счётчик прячет) — пункты прыгали под курсором (f_crm_a · marketing-tabstrip-shift-1). */
#salesWorkspace .tw-head .tw-count:empty { display: none; }
/* Ряд разделов: во всю высоту шапки, чернильная полоска активного садится на её нижнюю
   границу (собственный border-bottom гасим, чтобы не было двойного хэйрлайна). */
#salesSeg {
  flex: 0 1 auto; min-width: 0; align-self: stretch; align-items: center;
  margin-left: 4px; border-bottom: 0; gap: 0; overflow-x: auto; overflow-y: hidden;
}
#salesSeg button { padding: 0 11px; height: 100%; gap: 7px; }
#salesSeg button.active::after { left: 11px; right: 11px; bottom: 0; }
#salesSeg .tw-seg-badge { margin-left: 1px; }
/* Строка видов раздела (реюз .tw-toolbar): тонкая, левый край — по заголовку. */
#salesWorkspace .sales-subbar { padding: 6px 16px; gap: 8px; }
#salesWorkspace .sales-subbar .cc-seg { max-width: 100%; }
/* Адаптив НЕ по медиазапросам, а по ЗАМЕРУ (app.js salesFitHead): классы .fit-1…4 навешиваются,
   пока строка не влезет. Порядок жертв: счётчик → подпись «Сделка» → заголовок → подписи
   разделов (остаются иконки + тултип). Медиазапросы тут не годятся: у приложения свой масштаб
   интерфейса 80–200% (A−/A+) и подписи разделов разной длины. */
#salesWorkspace .tw-head.fit-1 .tw-count { display: none; }
#salesWorkspace .tw-head.fit-2 { gap: 8px; padding: 0 10px 0 12px; }
#salesWorkspace .tw-head.fit-2 #salesSeg button { padding: 0 9px; }
#salesWorkspace .tw-head.fit-2 #salesNew span { display: none; }
#salesWorkspace .tw-head.fit-2 #salesNew { padding-left: 10px; padding-right: 10px; }
#salesWorkspace .tw-head.fit-3 .tw-title { display: none; }
#salesWorkspace .tw-head.fit-4 #salesSeg .tw-seg-label { display: none; }
#salesWorkspace .tw-head.fit-4 #salesSeg button { padding: 0 12px; }
/* Последняя ступень: и иконками не влезли (телефон) — ряд листается пальцем (как весь канон
   .cc-tabs). Края подтаивают краской с обеих сторон (реестр ROW_FADE_SEL → .cc-rowfade), выбранный
   раздел выводит в видимую часть ccSegReveal — общие двери, своей маски у ряда нет (маска резала
   только правый край, слева бейдж раздела обрывался). Раньше тут был `overflow: hidden` — на
   телефоне видно 2 раздела из 11, остальные недостижимы. */
@media (max-width: 700px) { #salesWorkspace .sales-subbar .cc-seg .tw-seg-label { display: none; } }

/* Доска-воронка: карточка сделки */
.deal-card .deal-card-top { display: flex; align-items: flex-start; gap: 6px; justify-content: space-between; }
.deal-card .deal-card-top-r { display: flex; align-items: center; gap: 6px; flex: none; }
.deal-card .tw-card-title { font-weight: 600; font-size: 13.5px; line-height: 1.32; }
/* Ответственный маленьким аватаром на карточке доски (сделка и лид — одна реализация). */
.crm-card-owner { display: inline-flex; flex: none; }
.crm-card-owner .tw-av { width: 20px; height: 20px; font-size: 9px; margin: 0; }
.crm-card-owner.none { width: 20px; height: 20px; border-radius: 50%; border: 1.5px dashed var(--line); display: inline-flex; align-items: center; justify-content: center; color: var(--muted); }
.crm-card-owner.none .ic { width: 12px; height: 12px; }
.deal-amount { font-weight: 700; font-size: 14px; margin-top: 4px; letter-spacing: -.01em; color: var(--text); }
.deal-card .tw-card-foot { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; align-items: center; }
.deal-chip { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); padding: 1px 7px; border-radius: 999px; max-width: 152px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-chip .ic { width: 12px; height: 12px; opacity: .85; }
.deal-chip.deal-prob { color: var(--primary-2); font-weight: 600; }
.deal-chip.over { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, var(--line)); }
.deal-num { font-size: 11px; color: var(--text-dim); font-weight: 600; margin-left: auto; }
.deal-col-sum { font-size: 11px; font-weight: 600; color: var(--muted); }
.deal-card.rotting { box-shadow: inset 3px 0 0 #f5a623; }
/* значок «залежалась» — чернилами тревоги темы: #f5a623 на белой карточке давал 2.0 (значку нужно 3) */
.deal-rot { color: var(--warning-ink, var(--warning)); display: inline-flex; flex: none; }
.deal-rot .ic { width: 14px; height: 14px; }
/* зелёный «Выиграно» — токен семантики, а не число: #22a06b на тёмной колонке Штиля 4.34:1 */
.deal-col.cat-won .tw-col-name { color: var(--ok, #22a06b); }
.deal-col.cat-lost .tw-col-name { color: var(--danger); }

/* Пилюли лида (0167): грейд A–D + speed-to-lead SLA — одна реализация, доска и список */
.deal-grade { display: inline-flex; align-items: center; justify-content: center; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 5px; font-size: 10.5px; font-weight: 800; line-height: 1; letter-spacing: .02em; flex: none; border: 1px solid transparent; }
/* 🔴 Цвета — ТОЛЬКО через переменные темы. Было захардкожено (#1a8f5a / #b7791f): в тёмной теме
   грейд C и «ждём ответа» тонули в фоне, а лид-карточка показывает эти пилюли на каждой строке. */
.deal-grade.g-A { color: var(--ok); background: var(--ok-soft); border-color: color-mix(in srgb, var(--ok) 34%, transparent); }
.deal-grade.g-B { color: var(--primary-2); background: color-mix(in srgb, var(--primary) 14%, transparent); border-color: color-mix(in srgb, var(--primary) 30%, transparent); }
.deal-grade.g-C { color: var(--warning); background: var(--warning-soft); border-color: color-mix(in srgb, var(--warning) 34%, transparent); }
.deal-grade.g-D { color: var(--muted); background: var(--panel-2); border-color: var(--line); }
.deal-row-title .deal-grade { margin-right: 6px; vertical-align: middle; }
.deal-chip.deal-sla.breached { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 42%, var(--line)); background: var(--danger-soft); font-weight: 600; }
.deal-chip.deal-sla.pending { color: var(--warning); border-color: color-mix(in srgb, var(--warning) 34%, var(--line)); }

/* ══ Предиктивный скор выигрыша (0174): бейдж win_score 0..100 — доска и список ══ */
.deal-score { display: inline-flex; align-items: center; gap: 2px; height: 16px; padding: 0 5px 0 3px; border-radius: 5px; font-size: 10.5px; font-weight: 800; line-height: 1; flex: none; border: 1px solid transparent; }
.deal-score .ic { width: 11px; height: 11px; opacity: .9; }
.deal-score.s-hi { color: var(--ok-ink, var(--ok, #1a8f5a)); background: rgba(46, 204, 113, .15); border-color: color-mix(in srgb, #22a06b 32%, transparent); }
.deal-score.s-mid { color: var(--primary-2); background: color-mix(in srgb, var(--primary) 13%, transparent); border-color: color-mix(in srgb, var(--primary) 28%, transparent); }
.deal-score.s-lo { color: var(--muted); background: var(--panel-2); border-color: var(--line); }
html[data-theme="light"] .deal-score.s-hi { color: #15794b; }

/* ══ Вид «ИИ» (0174): AI-прогноз + next-best-action + AI-SDR. Одна реализация в «Продажах» ══ */
.sales-ai { max-width: 860px; margin: 0 auto; padding: 8px 4px 56px; display: flex; flex-direction: column; gap: 14px; }
.ai-card { border: 1px solid var(--line); background: var(--panel); border-radius: var(--radius); padding: 16px 18px; }
.ai-card-h { font-weight: 700; font-size: 15px; letter-spacing: -.01em; display: flex; align-items: baseline; gap: 8px; margin-bottom: 12px; }
.ai-sub { font-weight: 500; font-size: 12px; color: var(--muted); }
.ai-muted { color: var(--muted); font-size: 13px; padding: 4px 0; }
.ai-nums { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; }
.ai-num { border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px; background: var(--panel-2); }
/* «призрачная» цифра — без подложки, а не прозрачностью (.82 гасила подпись до 4.2) */
.ai-num.ghost { background: transparent; }
.ai-num-v { font-weight: 800; font-size: 18px; letter-spacing: -.02em; color: var(--text); }
/* зелёный «рост» — токен семантики: #1a8f5a на тёмной карточке 4.02:1 */
.ai-num-v.up { color: var(--ok, #1a8f5a); }
.ai-num-v.down { color: var(--danger); }
.ai-num-l { font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.ai-model { margin-top: 12px; font-size: 12.5px; color: var(--muted); }
.ai-model b { color: var(--text); }
.ai-cattbl { margin-top: 12px; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.ai-catrow { display: grid; grid-template-columns: 1.4fr .6fr 1fr 1fr; gap: 8px; padding: 8px 12px; font-size: 12.5px; align-items: center; }
.ai-catrow + .ai-catrow { border-top: 1px solid var(--line); }
.ai-cathead { background: var(--panel-2); color: var(--muted); font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; }
.ai-cat-name { font-weight: 700; }
.ai-cat-commit { color: #1a8f5a; } .ai-cat-best_case { color: var(--primary-2); } .ai-cat-pipeline { color: var(--muted); }
.ai-cat-cnt, .ai-cat-stage { color: var(--muted); }
.ai-cat-ai { font-weight: 700; color: var(--text); }
.ai-top { margin-top: 12px; }
.ai-top-h { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); margin-bottom: 6px; }
.ai-top-row { display: flex; align-items: center; gap: 8px; padding: 6px 4px; border-radius: 8px; cursor: pointer; transition: background .12s; }
.ai-top-row:hover { background: var(--hover); }
.ai-top-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.ai-top-amt { font-weight: 600; font-size: 12.5px; color: var(--muted); }
.ai-actions-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.ai-acts { display: flex; flex-direction: column; gap: 8px; }
.ai-act { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; cursor: pointer; transition: background .12s, border-color .12s; }
.ai-act:hover { background: var(--hover); border-color: color-mix(in srgb, var(--primary) 26%, var(--line)); }
.ai-act-pri { width: 4px; align-self: stretch; border-radius: 3px; flex: none; }
.ai-act-pri.p-hi { background: var(--danger); } .ai-act-pri.p-mid { background: #f5a623; } .ai-act-pri.p-lo { background: color-mix(in srgb, var(--primary) 55%, transparent); }
.ai-act-t { font-weight: 650; font-size: 13.5px; }
.ai-act-d { font-size: 12.5px; color: var(--muted); margin-top: 2px; }
.ai-act-deal { font-size: 11.5px; color: var(--text-dim); margin-top: 3px; }
.ai-agent { border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; }
.ai-agent-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ai-agent-name { font-weight: 700; font-size: 14px; margin-right: auto; }
.ai-tag { font-size: 10.5px; font-weight: 600; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); padding: 1px 6px; border-radius: 999px; }
.ai-tgl { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--muted); cursor: pointer; }
.ai-agent-meta { font-size: 11.5px; color: var(--muted); margin-top: 6px; }
/* `.ai-sdr-*` (песочница старой карточки агента) удалены: карточка бота уехала в раздел
   «ИИ-боты» (контракт §2.2), её песочница живёт в `.aib-sand*`. Мёртвые правила возвращать
   нельзя — они и есть приглашение завести вторую точку настройки одного бота. */
.ai-runs { margin-top: 10px; display: flex; flex-direction: column; gap: 4px; }
.ai-runs.hidden { display: none; }
.ai-run { display: flex; align-items: baseline; gap: 8px; font-size: 12px; padding: 5px 8px; border-radius: 7px; background: var(--panel-2); }
.ai-run-k { font-weight: 700; font-size: 10.5px; text-transform: uppercase; letter-spacing: .02em; flex: none; color: var(--muted); }
.ai-run-blocked .ai-run-k { color: #b7791f; } .ai-run-handoff .ai-run-k { color: var(--primary-2); } .ai-run-error .ai-run-k { color: var(--danger); } .ai-run-turn .ai-run-k { color: #1a8f5a; }
.ai-run-txt { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.ai-run-meta { flex: none; color: var(--muted); font-size: 11px; }
button.ghost.xsmall { font-size: 11.5px; padding: 3px 9px; }

/* Вид «Лиды» — движок скоринга/маршрутизации/SLA воронки (0167). Одна реализация в «Продажах» */
.sl-wrap { max-width: 720px; margin: 0 auto; padding: 6px 4px 48px; }
.sl-routes { display: flex; flex-wrap: wrap; gap: 8px; margin: 2px 0 4px; }
.sl-route { appearance: none; border: 1px solid var(--line); background: var(--panel); color: var(--muted); font: inherit; font-size: 12.5px; font-weight: 600; padding: 7px 14px; border-radius: 999px; cursor: pointer; transition: background .13s, color .13s, border-color .13s; }
.sl-route:hover { background: var(--hover); color: var(--text); }
.sl-route.on { background: color-mix(in srgb, var(--primary) 15%, transparent); color: var(--primary-2); border-color: color-mix(in srgb, var(--primary) 40%, transparent); }
.sl-owner-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 12px; }
.sl-owner-lbl { font-size: 13px; color: var(--text); }
.sl-owner { display: inline-flex; align-items: center; gap: 8px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 5px 9px 5px 5px; color: var(--text); font: inherit; font-size: 13px; cursor: pointer; transition: border-color .13s, background .13s; }
.sl-owner:hover { border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.sl-owner .ic { width: 15px; height: 15px; color: var(--muted); }
.sl-mems { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 12px; }
.sl-mem { display: flex; align-items: center; gap: 10px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 8px 10px; transition: opacity .13s; }
.sl-mem.off { opacity: .55; }
.sl-mem-main { flex: 1 1 auto; min-width: 0; }
.sl-mem-name { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sl-mem-skills { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.sl-skill { font-size: 11px; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: 999px; padding: 1px 8px; }
.sl-skill-in { width: 100%; box-sizing: border-box; margin-top: 4px; background: var(--panel); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 5px 8px; font-size: 12px; font-family: inherit; }
.sl-skill-in:focus { outline: none; border-color: var(--accent, var(--primary)); }
.sl-mem-x { background: transparent; border: 0; color: var(--muted); cursor: pointer; width: 28px; height: 28px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; flex: none; transition: background .12s, color .12s; }
.sl-mem-x:hover { background: var(--danger-soft); color: var(--danger); }
.sl-mem-x .ic { width: 15px; height: 15px; }
.sl-grades { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 6px 0 2px; }
.sl-rules { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 12px; }
.sl-rule { display: flex; align-items: center; gap: 8px; background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 8px 10px; flex-wrap: wrap; transition: opacity .13s; }
.sl-rule.off { opacity: .5; }
.sl-kind { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .03em; padding: 2px 6px; border-radius: 6px; flex: none; }
.sl-kind-fit { color: var(--primary-2); background: color-mix(in srgb, var(--primary) 13%, transparent); }
.sl-kind-behavior { color: #b7791f; background: rgba(245, 166, 35, .15); }
.sl-rule select, .sl-rule input { background-color: var(--panel); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 6px 8px; font-size: 12.5px; font-family: inherit; min-width: 0; }
/* bare-select-chevron-1 · у селектов правила (поле · условие · значение) сокращение `background:` выше стирало общий
   шеврон select; теперь только цвет, а здесь — место под шеврон, как у .lead-cfg-cat на том же экране. */
.sl-rule select { padding-right: 28px; background-position: right 9px center; }
.sl-rule select:focus, .sl-rule input:focus { outline: none; border-color: var(--accent, var(--primary)); }
.sl-r-fld { flex: 1 1 130px; }
.sl-r-op { flex: 0 0 100px; }
.sl-r-val { flex: 1 1 90px; }
.sl-r-dash { flex: 1 1 90px; color: var(--text-dim); text-align: center; }
.sl-r-pts { display: inline-flex; align-items: center; gap: 4px; flex: none; }
.sl-r-pts input { width: 58px; text-align: right; }
.sl-r-pts em { font-size: 11px; color: var(--muted); font-style: normal; }
.sl-r-del { background: transparent; border: 0; color: var(--muted); cursor: pointer; width: 28px; height: 28px; border-radius: 8px; display: inline-flex; align-items: center; justify-content: center; flex: none; transition: background .12s, color .12s; }
.sl-r-del:hover { background: var(--danger-soft); color: var(--danger); }
.sl-r-del .ic { width: 15px; height: 15px; }
@media (max-width: 560px) { .sl-grades { grid-template-columns: 1fr; } .sl-rule { gap: 6px; } .sl-r-fld, .sl-r-op, .sl-r-val { flex-basis: 100%; } }

/* Вид «Список» */
.deal-list { display: flex; flex-direction: column; gap: 1px; padding: 6px 12px 48px; }
.deal-list-head, .deal-row { display: grid; grid-template-columns: 130px minmax(0, 1.5fr) 130px 40px 108px 46px 86px 88px; gap: 10px; align-items: center; }
.deal-list-head { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-dim); padding: 8px 12px; position: sticky; top: 0; background: var(--bg); z-index: 1; }
.deal-row { padding: 11px 12px; border-radius: 10px; cursor: pointer; transition: background .12s; }
.deal-row:hover { background: var(--hover); }
.deal-row-stage { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-row-stage i { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.deal-row-title { font-weight: 600; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-row-num { color: var(--text-dim); font-weight: 500; margin-right: 4px; }
.deal-row-company { color: var(--text-dim); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-row-owner { display: flex; align-items: center; justify-content: center; }
.deal-row-amount { font-weight: 700; font-size: 13px; text-align: right; }
.deal-row-prob { color: var(--primary-2); font-size: 12px; text-align: right; }
.deal-row-close { font-size: 12px; color: var(--muted); }
.deal-row-close.over { color: var(--danger); }
.deal-row-status { font-size: 11px; font-weight: 600; padding: 2px 9px; border-radius: 999px; text-align: center; }
.deal-row-status.st-open { color: var(--primary-2); background: color-mix(in srgb, var(--primary) 12%, transparent); }
/* текст на своём тинте — ЧЕРНИЛА исхода (--ok-ink/--danger-ink): в тёмном «Штиле» --ok на тинте 4.2, --danger 4.0 */
.deal-row-status.st-won { color: var(--ok-ink, var(--ok, #22a06b)); background: color-mix(in srgb, var(--ok, #22a06b) 14%, transparent); }
.deal-row-status.st-lost { color: var(--danger-ink, var(--danger)); background: var(--danger-soft); }

/* Вид «Таймлайн» (по ожидаемой дате закрытия, по месяцам) */
.deal-timeline { display: flex; gap: 14px; padding: 14px; overflow-x: auto; height: 100%; align-items: flex-start; }
.deal-tl-col { flex: 0 0 232px; background: var(--panel); border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.deal-tl-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; padding: 10px 12px; font-weight: 600; font-size: 13px; border-bottom: 1px solid var(--line); text-transform: capitalize; }
.deal-tl-sum { font-size: 11px; color: var(--muted); font-weight: 600; text-transform: none; }
.deal-tl-body { padding: 8px; display: flex; flex-direction: column; gap: 6px; min-height: 64px; }
.deal-tl-card { background: var(--panel-2); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; cursor: pointer; display: flex; flex-direction: column; gap: 3px; transition: border-color .12s, transform .12s; }
.deal-tl-card:hover { border-color: var(--primary); transform: translateY(-1px); }
.deal-tl-card.st-won { border-left: 3px solid #2ecc71; }
/* проигранная — приглушена ЧЕРНИЛАМИ, а не прозрачностью (.68 гасила и сумму, и заголовок ниже нормы) */
.deal-tl-card.st-lost { border-left: 3px solid var(--danger); }
.deal-tl-card.st-lost .deal-tl-title { color: var(--muted); font-weight: 500; }
.deal-tl-title { font-size: 12.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-tl-amt { font-size: 12px; color: var(--muted); font-weight: 600; }
.deal-tl-empty { color: var(--text-dim); font-size: 12px; text-align: center; padding: 8px; }

/* Вид «Прогноз» */
.deal-forecast { padding: 22px; max-width: 920px; margin: 0 auto; }
/* Ряд карточек-цифр — flex с переносом, а не auto-fit сетка: в сетке 5 карточек на ширине под
   4 колонки оставляли пятую сиротой в ¼ ширины и пустые ¾ рядом; во flex последний ряд
   растягивается на всю ширину (f_crm_a · analytics-orphan-card-1). Мин. ширина та же — 178 px. */
.fc-cards { display: flex; flex-wrap: wrap; gap: 14px; }
.fc-cards > .fc-card { flex: 1 1 178px; min-width: 0; }
.fc-card { background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: 16px 18px; }
.fc-card.fc-primary { border-color: color-mix(in srgb, var(--primary) 50%, var(--line)); background: color-mix(in srgb, var(--primary) 7%, var(--panel)); }
.fc-card-lbl { font-size: 12px; color: var(--muted); }
.fc-card-val { font-size: 24px; font-weight: 750; letter-spacing: -.02em; margin-top: 6px; }
.fc-card-sub { font-size: 11.5px; color: var(--text-dim); margin-top: 4px; }
/* 🗣 0424 · Плитка NPS в ряду KPI аналитики: отрицательный индекс подсвечен, потому что это
   не «мало», а «нас ругают больше, чем хвалят» — тот же тревожный тон, что у просроченного. */
.fc-card.fc-bad { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); background: color-mix(in srgb, var(--danger) 7%, var(--panel)); }
.fc-card.fc-bad .fc-card-val { color: var(--danger); }
.fc-section-title { font-size: 13px; font-weight: 650; margin: 26px 0 12px; color: var(--text); }
.fc-bars { display: flex; flex-direction: column; gap: 11px; }
.fc-bar-row { display: grid; grid-template-columns: 168px minmax(0, 1fr) 156px; gap: 12px; align-items: center; }
.fc-bar-name { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fc-bar-name i { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.fc-bar-track { height: 8px; background: var(--panel-2); border-radius: 999px; overflow: hidden; }
.fc-bar-fill { height: 100%; border-radius: 999px; transition: width .3s ease; min-width: 2px; }
.fc-bar-val { font-size: 12.5px; font-weight: 650; text-align: right; }
.fc-bar-val em { color: var(--text-dim); font-style: normal; font-weight: 500; }

/* Вид «Дашборд» — аналитика продаж (воронка конверсии · velocity · лидерборд · план/факт · тренд) */
.deal-dashboard { padding: 22px; max-width: 980px; margin: 0 auto; }
/* 🔎 CRMC-697·3 · За что посчитано — СЛОВАМИ над цифрами (иначе смена периода читается как ошибка
   в данных), и отказ аналитики говорит причину с выходом «Повторить», а не «нет данных». */
.db-scope { margin: 0 0 14px; font-size: 12.5px; color: var(--muted); }
.db-scope b { color: var(--text); font-weight: 650; }
.db-fail { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; }
.db-fail-act { display: flex; gap: 8px; }
.deal-dashboard .fc-section-title { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.db-sub { font-size: 12px; font-weight: 500; color: var(--muted); }
/* воронка */
.db-funnel { display: flex; flex-direction: column; gap: 9px; }
.db-fn-row { display: grid; grid-template-columns: 190px minmax(0, 1fr) 128px; gap: 14px; align-items: center; }
.db-fn-name { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.db-fn-name i { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.db-fn-name em { color: var(--text-dim); font-style: normal; font-size: 11px; }
.db-fn-barwrap { display: flex; }
.db-fn-bar { height: 30px; border-radius: 8px; min-width: 8px; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .07); transition: width .34s cubic-bezier(.4, 0, .2, 1); }
.db-fn-meta { text-align: right; font-size: 12px; }
.db-fn-meta b { font-size: 15px; font-weight: 700; letter-spacing: -.01em; color: var(--text); }
.db-fn-meta em { display: block; color: var(--text-dim); font-style: normal; font-size: 11px; margin-top: 1px; }
.db-fn-drop { color: var(--danger); font-weight: 600; }
/* лидерборд */
.db-lb { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.db-lb-row { display: grid; grid-template-columns: minmax(0, 1.7fr) repeat(4, minmax(0, 1fr)); gap: 10px; align-items: center; padding: 11px 14px; border-top: 1px solid var(--line); }
.db-lb-row:first-child { border-top: none; }
.db-lb-head { background: var(--panel-2); padding: 8px 14px; }
.db-lb-head span { font-size: 10.5px !important; font-weight: 600 !important; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.db-lb-rep { display: inline-flex; align-items: center; gap: 9px; min-width: 0; }
.db-lb-rep b { font-weight: 600; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.db-rank { width: 18px; text-align: center; font-size: 12px; font-weight: 700; color: var(--text-dim); flex: none; }
.db-rank-1 { color: #d4af37; } .db-rank-2 { color: #9fb0c3; } .db-rank-3 { color: #cd7f32; }
/* светлая тема: «золото/серебро/бронза» тех же оттенков, но тёмнее — #d4af37 на белом 1.93:1 */
html[data-theme="light"] .db-rank-1 { color: #8a6a00; } html[data-theme="light"] .db-rank-2 { color: #5f6f80; } html[data-theme="light"] .db-rank-3 { color: #9a5a1c; }
.db-av { width: 26px; height: 26px; border-radius: 50%; flex: none; object-fit: cover; }
.db-av-i { display: inline-flex; align-items: center; justify-content: center; background: var(--acc-fill); color: #fff; font-size: 10.5px; font-weight: 700; }
.db-lb-num { text-align: right; font-size: 13.5px; font-weight: 650; color: var(--text); }
.db-lb-num em { display: block; font-style: normal; font-size: 10.5px; font-weight: 500; color: var(--text-dim); margin-top: 1px; }
.db-lb-won { color: var(--ok); }
/* тренд */
.db-trend { display: flex; align-items: flex-end; gap: 10px; height: 156px; padding: 6px 4px 0; }
.db-tr-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; justify-content: flex-end; }
.db-tr-val { font-size: 10px; color: var(--text-dim); min-height: 12px; }
.db-tr-barwrap { width: 100%; flex: 1; display: flex; align-items: flex-end; justify-content: center; }
.db-tr-bar { width: 58%; max-width: 46px; background: linear-gradient(180deg, var(--primary), color-mix(in srgb, var(--primary) 55%, transparent)); border-radius: 7px 7px 3px 3px; min-height: 4px; transition: height .3s ease; }
.db-tr-lbl { font-size: 11px; color: var(--muted); }
@media (max-width: 720px) {
  .db-fn-row { grid-template-columns: 120px minmax(0, 1fr) 96px; gap: 9px; }
  .db-lb-row { grid-template-columns: minmax(0, 1.4fr) repeat(4, minmax(0, 1fr)); gap: 6px; padding: 10px; }
  .db-lb-num { font-size: 12px; }
}

/* 💰 «Деньги компании» — виды «Прибыль» и «Расходы» раздела «Аналитика».
   🔴 Ни одного литерального цвета: только токены темы (`--panel/--panel-2/--line/--text/--muted/
   --text-dim/--primary/--danger/--ok`), поэтому светлая и тёмная получаются даром, а не вторым
   набором правил. Подложка убытка — `color-mix` от `--danger`, как у `.dinv-row.late`. */
.deal-profit { padding: 22px; max-width: 980px; margin: 0 auto; }
.deal-profit .prf-by-seg { margin: 0 0 14px; }
.deal-profit .fc-section-title { margin-top: 22px; }
/* 🔴 «Не знаю» выглядит КАК «не знаю», а не как ноль: без табличных цифр, приглушённо, курсивом. */
.prf-unknown { font-size: 15px; font-weight: 600; font-style: italic; color: var(--muted); }
.prf-neg { color: var(--danger); }
.fc-card.prf-loss { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); background: color-mix(in srgb, var(--danger) 10%, var(--panel)); }
/* Честность словами: «дохода нет» — объяснение, а не ошибка, поэтому нейтральная подложка. */
.prf-honest, .prf-warn { display: flex; align-items: center; gap: 9px; margin: 0 0 14px; padding: 10px 13px; border-radius: 12px; font-size: 12.5px; color: var(--text); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.prf-warn { margin: 14px 0 0; background: color-mix(in srgb, var(--danger) 8%, var(--panel-2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent); }
.prf-honest svg.ic, .prf-warn svg.ic { width: 15px; height: 15px; flex: none; color: var(--muted); }
.prf-warn svg.ic { color: var(--danger); }
/* Разновалютная выборка расходов: та же форма предупреждения, что у прибыли (.prf-warn) —
   одна реализация тревожной плашки, только адрес другой. */
.exp-mixed { display: flex; align-items: center; gap: 8px; margin: 10px 0 0; padding: 9px 12px; border-radius: 12px;
  font-size: 12.5px; color: var(--muted); background: color-mix(in srgb, var(--danger) 8%, var(--panel-2));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent); }
.exp-mixed svg.ic { width: 15px; height: 15px; flex: none; color: var(--danger); }
/* Итоги по ОСТАЛЬНЫМ валютам периода (ревью 20.09.2026, Б3): KPI считает главную валюту, а эти
   строки показывают остальные ЧИСЛАМИ — токены те же, что у таблицы разрезов, поэтому блок
   одинаково читается в светлой и тёмной теме. */
.prf-othercur { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 0; padding: 10px 13px; border-radius: 12px;
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); font-size: 12.5px; color: var(--muted); }
.prf-oc-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; font-variant-numeric: tabular-nums; }
.prf-oc-c { font-weight: 700; color: var(--text); }
.prf-oc-p { color: var(--text); font-weight: 640; }
/* Валюта строки разреза, если она не та, которой подписан итог. */
.prf-cur { margin-left: 6px; font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--muted);
  padding: 1px 5px; border-radius: 6px; background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
/* Список усечён — состояние ВИДНО и имеет выход (правило выхода; ревью Б2). */
.exp-more { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px;
  margin: 10px 0 0; padding: 9px 12px; border-radius: 12px; font-size: 12.5px; color: var(--muted);
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
/* Остальные валюты статьи затрат — рядом с её итогом, а не сложены в него. */
.exp-artmix { display: block; font-size: 10.5px; font-weight: 600; color: var(--muted); }
.prf-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.prf-unfiled { display: inline-flex; align-items: center; gap: 6px; }
.prf-unfiled svg.ic { width: 14px; height: 14px; }
/* Таблица разрезов: те же грид-правила, что у лидерборда дашборда (`.db-lb-row`). */
.prf-table { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.prf-row { display: grid; grid-template-columns: minmax(0, 1.8fr) repeat(5, minmax(0, 1fr)); gap: 10px; align-items: center; padding: 11px 14px; border-top: 1px solid var(--line); }
.prf-table.prf-noincome .prf-row { grid-template-columns: minmax(0, 1.8fr) repeat(2, minmax(0, 1fr)); }
.prf-row:first-child { border-top: none; }
.prf-head { background: var(--panel-2); padding: 8px 14px; }
.prf-head span { font-size: 10.5px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; }
.prf-t { font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.prf-v { text-align: right; font-size: 13px; font-weight: 640; color: var(--text); font-variant-numeric: tabular-nums; }
.prf-head .prf-v { text-align: right; }
.prf-row.loss { background: color-mix(in srgb, var(--danger) 7%, var(--panel)); }

/* 💸 Вид «Расходы»: реестр расходов + статьи затрат РАЗДЕЛОМ РЯДОМ (не отдельная страница). */
.deal-expenses { padding: 22px; max-width: 980px; margin: 0 auto; }
.exp-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 14px; }
.exp-bar .crm-row-sp { flex: 1 1 auto; }
.exp-f { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--muted); }
.exp-f.wide { flex: 1 1 220px; }
.exp-f > span { flex: none; }
.exp-f input, .exp-f select { flex: 1 1 auto; min-width: 0; font: inherit; font-size: 12.5px; color: var(--text); background-color: var(--panel); border: 1px solid var(--line); border-radius: 9px; padding: 6px 9px; } .exp-f select { padding-right: 34px; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.exp-f input:focus, .exp-f select:focus { outline: none; border-color: var(--primary); }
.exp-tot { display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; }
.exp-tot-v { font-size: 22px; font-weight: 750; letter-spacing: -.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.exp-tot-l { font-size: 12px; color: var(--muted); }
.exp-list { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.exp-row { display: grid; grid-template-columns: 74px 124px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 10px 14px; border-top: 1px solid var(--line); }
.exp-row:first-child { border-top: none; }
/* 🔴 «Без статьи» видно ГЛАЗОМ, а не только в подписи: такой расход не складывается в картину. */
.exp-row.noart { background: color-mix(in srgb, var(--danger) 6%, var(--panel)); }
.exp-d { font-size: 12px; color: var(--muted); white-space: nowrap; }
.exp-s { font-size: 13.5px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.exp-b { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.exp-t { font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.exp-m { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 11px; color: var(--text-dim); }
.exp-w { color: var(--muted); }
.exp-art, .exp-tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: 999px; font-size: 10.5px; font-weight: 600; color: var(--muted); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.exp-art { color: var(--text); background: color-mix(in srgb, var(--primary) 12%, transparent); box-shadow: none; }
.exp-art.noart { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); }
.exp-tag svg.ic { width: 11px; height: 11px; }
.exp-a { display: flex; align-items: center; gap: 6px; flex: none; }
/* Форма расхода — ИНЛАЙНОМ в списке (окно ради трёх полей экран не отбирает). */
.exp-form { margin-bottom: 14px; padding: 14px; border: 1px solid var(--line); border-radius: 14px; background: var(--panel); display: flex; flex-direction: column; gap: 10px; }
.exp-form-h { font-size: 13px; font-weight: 650; color: var(--text); }
.exp-fr { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.exp-form-a { display: flex; align-items: center; gap: 8px; }
.exp-note { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--muted); padding: 8px 10px; border-radius: 10px; background: var(--panel-2); }
.exp-note svg.ic { width: 14px; height: 14px; flex: none; }
/* Статьи затрат — раскрывающийся раздел РЯДОМ со списком, а не своя страница. */
.exp-arts { margin-top: 18px; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.exp-arts-h { display: flex; align-items: center; gap: 8px; width: 100%; padding: 11px 14px; font: inherit; font-size: 13px; font-weight: 650; color: var(--text); background: var(--panel-2); border: none; cursor: pointer; text-align: left; }
.exp-arts-h svg.ic { width: 15px; height: 15px; flex: none; color: var(--muted); }
.exp-arts-h em { margin-left: auto; font-style: normal; font-size: 11.5px; font-weight: 500; color: var(--muted); }
.exp-arts-b { display: flex; flex-direction: column; }
.exp-artrow { display: grid; grid-template-columns: minmax(0, 1fr) 132px 132px auto; gap: 10px; align-items: center; padding: 10px 14px; border-top: 1px solid var(--line); }
.exp-artrow.arch { opacity: .6; }
.exp-artt { font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.exp-artt em { font-style: normal; font-size: 11px; font-weight: 500; color: var(--muted); }
.exp-artk { font: inherit; font-size: 12px; color: var(--text); background-color: var(--panel); border: 1px solid var(--line); border-radius: 9px; padding: 5px 34px 5px 8px; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.exp-artv { text-align: right; font-size: 13px; font-weight: 640; color: var(--text); font-variant-numeric: tabular-nums; }
.exp-artv em { display: block; font-style: normal; font-size: 10.5px; font-weight: 500; color: var(--text-dim); }
.exp-arta { display: flex; align-items: center; gap: 6px; }
.exp-arts-a { padding: 11px 14px; border-top: 1px solid var(--line); }
@media (max-width: 720px) {
  .prf-row { grid-template-columns: minmax(0, 1.4fr) repeat(5, minmax(0, 1fr)); gap: 6px; padding: 10px; }
  .prf-v { font-size: 11.5px; }
  .exp-row { grid-template-columns: 62px 96px minmax(0, 1fr); gap: 8px; padding: 10px; }
  .exp-a, .exp-arta { grid-column: 1 / -1; }
  .exp-artrow { grid-template-columns: minmax(0, 1fr) 112px; }
}
/* 💼 Вид «Ведомость» (0479): список ведомостей → ведомость по людям. Токены темы, без реек. */
.pay-h { font-size: 14px; font-weight: 650; color: var(--text); }
.pay-row { cursor: pointer; transition: background .14s ease; }
.pay-row:hover, .pay-row:focus-visible { background: var(--panel-2); outline: none; }
.pay-row .exp-a svg.ic { width: 15px; height: 15px; color: var(--muted); }
.pay-st.pay-st-draft, .pay-st-draft .pay-st { color: var(--muted); }
.pay-st-approved .pay-st, .pay-st.pay-st-approved { color: var(--text); background: color-mix(in srgb, var(--primary) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.pay-st-partial .pay-st, .pay-st.pay-st-partial { color: var(--text); background: color-mix(in srgb, var(--warning) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 24%, transparent); }
.pay-st-paid .pay-st, .pay-st.pay-st-paid { color: var(--text); background: color-mix(in srgb, var(--ok) 13%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 22%, transparent); }
.pay-head { margin-bottom: 10px; display: flex; flex-direction: column; gap: 4px; }
.pay-title { font-size: 18px; font-weight: 700; letter-spacing: -.01em; color: var(--text); }
.pay-prob { margin-bottom: 8px; color: var(--text); background: color-mix(in srgb, var(--danger) 8%, var(--panel)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 18%, transparent); }
.pay-prob svg.ic { color: var(--danger); }
.pay-people { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
.pay-person { border: 1px solid var(--line); border-radius: 14px; background: var(--panel); padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }
.pay-ph { display: flex; align-items: baseline; gap: 12px; }
.pay-name { flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 650; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pay-name .pay-left { font-style: normal; font-weight: 500; font-size: 11px; color: var(--muted); margin-left: 6px; }
.pay-note { margin-bottom: 8px; }
.pay-amt:disabled { opacity: .6; cursor: progress; }
.pay-sum { display: flex; flex-direction: column; align-items: flex-end; flex: none; }
.pay-sum b { font-size: 15px; font-weight: 720; color: var(--text); font-variant-numeric: tabular-nums; }
.pay-sum em { font-style: normal; font-size: 11px; color: var(--muted); }
.pay-lines { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.pay-line { display: grid; grid-template-columns: 92px minmax(0, 1fr) 128px 28px; gap: 10px; align-items: center; padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.pay-k { font-size: 10.5px; font-weight: 650; color: var(--muted); text-transform: uppercase; letter-spacing: .04em; }
.pay-k-bonus { color: var(--primary); }
.pay-k-deduction, .pay-k-advance { color: var(--danger); }
.pay-w { min-width: 0; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pay-w em { font-style: normal; color: var(--muted); }
.pay-v { text-align: right; font-weight: 640; color: var(--text); font-variant-numeric: tabular-nums; }
.pay-v.minus { color: var(--danger); }
.pay-amt { width: 100%; box-sizing: border-box; text-align: right; font: inherit; font-size: 12.5px; font-variant-numeric: tabular-nums; color: var(--text); background: transparent; border: 1px solid transparent; border-radius: 8px; padding: 4px 7px; transition: border-color .14s ease, background .14s ease; }
.pay-amt:hover { border-color: var(--line); }
.pay-amt:focus { outline: none; border-color: var(--primary); background: var(--panel); }
.pay-x { padding: 2px; opacity: .55; transition: opacity .14s ease; }
.pay-line:hover .pay-x { opacity: 1; }
.pay-x svg.ic { width: 13px; height: 13px; }
.pay-wait, .pay-paid { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--muted); }
.pay-wait { padding: 7px 10px; border-radius: 10px; background: color-mix(in srgb, var(--primary) 8%, var(--panel)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 18%, transparent); color: var(--text); }
.pay-wait span { flex: 1 1 auto; }
.pay-wait svg.ic, .pay-paid svg.ic { width: 14px; height: 14px; flex: none; }
.pay-paid svg.ic { color: var(--ok); }
.pay-pa { display: flex; gap: 8px; flex-wrap: wrap; }
.pay-inl { margin: 0; }
@media (max-width: 720px) {
  .pay-line { grid-template-columns: 74px minmax(0, 1fr) 96px 24px; gap: 6px; }
}
/* 💰 Себестоимость часа и прибыль по часам в блоке «Часы и ставки» карточки сделки. */
.dpay-num.bad .dpay-num-v { color: var(--danger); }
.dhr-cost { color: var(--muted); }
/* 💸 Выписка банка: расход читается как расход — минусом и цветом; статья рядом. */
.cs-bank-op.out .cs-bank-op-m b { color: var(--danger); }
.cs-bank-art { display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 999px; font-size: 11px; font-weight: 600; color: var(--text); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.cs-bank-art.noart { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); }

/* ── CRM · Прогноз v2: панель, forecast-категории, квота-gauge, тренд, территории, свод команды ── */
.fc-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 18px; }
/* CLIE-505: два сегмента прогноза стояли в ОДНОЙ строке и отличались друг от друга
   (13px/12.5 против 11px/12) — эталон жалобы «дизайн везде разный». Своя геометрия
   удалена, оба берут канон .cc-seg + .cc-seg-md (размер строки тулбара). */

.fc-cat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; }
.fc-cat-cards .fc-card { position: relative; overflow: hidden; }
.fc-cat-cards .fc-card::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px; background: var(--line); }
.fc-card.fc-cat-closed::before { background: #2ecc71; }
.fc-card.fc-primary::before { background: var(--primary); }
.fc-card.fc-cat-best::before { background: var(--cm-a36bff, #a36bff); }
.fc-card.fc-cat-pipe::before { background: #8a8f98; }
.fc-card.fc-cat-weighted::before { background: #f5a623; }
.fc-cat-cards .fc-card-val { font-size: 21px; }

/* Стек-бар composition Closed→Commit→Best→Pipeline */
.fc-compo { display: flex; height: 15px; border-radius: 999px; overflow: hidden; margin: 16px 0 10px; background: var(--panel-2); }
.fc-compo-seg { height: 100%; transition: width .35s ease; }
.fc-compo-seg + .fc-compo-seg { box-shadow: inset 1px 0 0 rgba(255,255,255,.14); }
.fc-legend { display: flex; flex-wrap: wrap; gap: 14px; }
.fc-legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); }
.fc-legend-item i { width: 9px; height: 9px; border-radius: 3px; }

/* Gauge квоты + what-if */
.fc-quota { margin-top: 22px; border: 1px solid var(--line); border-radius: 16px; padding: 16px 18px; background: var(--panel); }
.fc-quota-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 13px; font-weight: 650; color: var(--text); margin-bottom: 12px; }
.fc-quota-target b { font-variant-numeric: tabular-nums; }
.fc-quota-input { width: 130px; padding: 7px 10px; border-radius: 9px; border: 1px solid var(--line); background: var(--panel-2); color: var(--text); font-size: 13px; font-weight: 650; text-align: right; outline: none; transition: box-shadow .12s, border-color .12s; }
.fc-quota-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.fc-quota-att { display: flex; align-items: baseline; gap: 9px; margin-bottom: 10px; }
.fc-quota-att-n { font-size: 30px; font-weight: 800; letter-spacing: -.02em; color: var(--text); font-variant-numeric: tabular-nums; }
.fc-quota-att-n em { font-size: 17px; font-weight: 700; font-style: normal; color: var(--muted); margin-left: 1px; }
.fc-quota-att-l { font-size: 12px; color: var(--muted); }
.fc-quota-bar { position: relative; height: 12px; border-radius: 999px; background: var(--panel-2); overflow: hidden; margin-bottom: 12px; }
.fc-quota-proj { position: absolute; left: 0; top: 0; bottom: 0; background: color-mix(in srgb, var(--primary) 32%, transparent); border-radius: 999px; transition: width .35s ease; }
.fc-quota-fill { position: absolute; left: 0; top: 0; bottom: 0; background: linear-gradient(90deg, #2ecc71, #27b463); border-radius: 999px; transition: width .35s ease; min-width: 2px; }
.fc-quota-meta { display: flex; flex-wrap: wrap; gap: 18px; font-size: 12.5px; color: var(--muted); }
.fc-quota-meta b { color: var(--text); font-variant-numeric: tabular-nums; }
.fc-quota-meta .fc-gap { color: #f5a623; }
.fc-quota-empty { font-size: 13px; color: var(--muted); }
.fc-quota-empty b { color: var(--text); }
.fc-muted { color: var(--muted); }
.fc-scenario { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--line); }
.fc-scenario-l { font-size: 12px; color: var(--muted); margin-right: 4px; }
.fc-scenario button { border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); font-size: 12px; font-weight: 600; padding: 5px 11px; border-radius: 8px; cursor: pointer; transition: all .13s; }
.fc-scenario button:hover { color: var(--text); }
.fc-scenario button.active { background: color-mix(in srgb, var(--primary) 14%, var(--panel)); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); color: var(--text); }

/* Тренд won по месяцам */
.fc-trend { display: flex; align-items: flex-end; gap: 10px; height: 92px; padding: 6px 4px 0; }
.fc-trend-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 6px; height: 100%; }
.fc-trend-bar { width: 100%; max-width: 46px; background: linear-gradient(180deg, color-mix(in srgb, var(--primary) 85%, #fff), var(--primary)); border-radius: 6px 6px 3px 3px; transition: height .35s ease; }
.fc-trend-x { font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* Территории */
.fc-terr { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.fc-terr-row { display: grid; grid-template-columns: minmax(0,1.4fr) 1fr 1fr 1fr; gap: 10px; padding: 10px 14px; align-items: center; font-size: 12.5px; }
.fc-terr-row + .fc-terr-row { border-top: 1px solid var(--line); }
.fc-terr-head { background: var(--panel-2); font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); font-weight: 600; }
.fc-terr-n { color: var(--text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fc-terr-v { text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }
.fc-terr-head .fc-terr-v, .fc-terr-head .fc-terr-n { text-align: left; }
.fc-terr-head .fc-terr-v { text-align: right; }
.fc-terr-won { color: #2ecc71; font-weight: 650; }

/* Свод по команде (manager-rollup) */
.fc-reps { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.fc-rep-row { display: grid; grid-template-columns: minmax(0,1.6fr) 1fr 1.3fr 1fr 1fr 1.2fr; gap: 10px; padding: 11px 14px; align-items: center; font-size: 12.5px; }
.fc-rep-row + .fc-rep-row { border-top: 1px solid var(--line); }
.fc-rep-head { background: var(--panel-2); font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--muted); font-weight: 600; }
.fc-rep-who { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.fc-rep-av { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; flex: none; }
.fc-rep-av-x { display: inline-flex; align-items: center; justify-content: center; background: var(--panel-2); color: var(--muted); font-size: 12px; font-weight: 700; text-transform: uppercase; }
.fc-rep-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); font-weight: 600; }
.fc-rep-num { text-align: right; color: var(--text); font-variant-numeric: tabular-nums; }
.fc-rep-head .fc-rep-num, .fc-rep-head .fc-rep-who, .fc-rep-head .fc-rep-quotacell { text-align: left; color: var(--muted); }
.fc-rep-head .fc-rep-num { text-align: right; }
.fc-rep-commit { position: relative; }
.fc-rep-bar { height: 4px; border-radius: 999px; background: var(--panel-2); overflow: hidden; margin-top: 4px; }
.fc-rep-bar-fill { height: 100%; background: var(--primary); border-radius: 999px; transition: width .35s ease; }
.fc-rep-quotacell { display: inline-flex; align-items: center; gap: 8px; justify-content: flex-end; }
.fc-rep-quota { width: 96px; padding: 5px 8px; font-size: 12px; }
.fc-rep-att { font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; flex: none; }
.fc-rep-att.ok { color: #2ecc71; } .fc-rep-att.mid { color: #f5a623; } .fc-rep-att.low { color: #e0533d; } .fc-rep-att.muted { color: var(--muted); }

/* Карточка сделки: две колонки полей (прогноз-категория + территория) */
.deal-field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

/* Карточка сделки — правый drawer (инлайн-правка + автосейв) */
.deal-backdrop { position: fixed; inset: 0; background: var(--cm-06080e-42, rgba(6, 8, 14, .42)); z-index: 120; transition: opacity .2s; }
.deal-backdrop.hidden { display: none; }
.deal-drawer { position: fixed; top: 0; right: 0; height: 100%; width: min(440px, 94vw); background: var(--panel); border-left: 1px solid var(--line); z-index: 121; box-shadow: -12px 0 44px rgba(0, 0, 0, .28); transform: translateX(100%); transition: transform .22s cubic-bezier(.2, .8, .2, 1); display: flex; flex-direction: column; }
.deal-drawer.open { transform: translateX(0); }
.deal-drawer.hidden { display: none; }
.deal-drawer-load { padding: 40px; color: var(--muted); text-align: center; }
.deal-drawer-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 13px 14px; border-bottom: 1px solid var(--line); flex: none; }
.deal-drawer-head-l { display: flex; align-items: center; gap: 8px; }
.deal-drawer-head-r { display: flex; align-items: center; gap: 6px; }
.deal-status-pill { font-size: 11px; font-weight: 650; padding: 3px 10px; border-radius: 999px; }
.deal-status-pill.st-open { color: var(--primary-2); background: color-mix(in srgb, var(--primary) 13%, transparent); }
.deal-status-pill.st-won { color: var(--ok-ink, var(--ok)); background: rgba(46, 204, 113, .15); }
.deal-status-pill.st-lost { color: var(--danger-ink, var(--danger)); background: var(--danger-soft); }
.deal-num-badge { font-size: 11px; font-weight: 600; color: var(--text-dim); }
/* Пилюля стадии в шапке карточки — тот же цветной дот, что на доске и в приложении
   (карточка сделки во Flutter показывает стадию цветной пилюлей). Нейтральный фон,
   цвет несёт дот — читается в обеих темах при любой палитре этапа. */
.deal-stage-pill { display: inline-flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 600; padding: 3px 10px; border-radius: 999px; background: var(--panel-2); border: 1px solid var(--line); color: var(--text); }
.deal-stage-pill > i { width: 7px; height: 7px; border-radius: 50%; background: var(--sc, #8a8f98); flex: 0 0 auto; }
/* Поле «Стадия»: цветной дот слева от списка — цвет этапа виден и в карточке, не только на доске. */
.deal-stage-row { display: flex; align-items: center; gap: 8px; }
.deal-stage-row > .deal-stage-dot { width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .1); }
.deal-stage-row > select.deal-stage { flex: 1 1 auto; min-width: 0; }
/* Выбор стадии — канон ccpp (select спрятан, его место заняла обёртка `.ccpp-wrap`,
   `ccEntSelectMount`): во всю ширину, как «Воронка» над ним, а не узкой кнопкой по тексту.
   Цвет стадии уже показывает точка слева — пустой кружок внутри кнопки лишний. */
.deal-stage-row > .ccpp-wrap { flex: 1 1 auto; min-width: 0; }
/* Пустой кружок «цвета нет» внутри подменённого списка читался как битый переключатель («○ Сайт — чат»):
   у пунктов без цвета точку не рисуем вовсе (кадр лида 14.09.2026). Тот же кружок у поля «Родительский
   проект» (projParentFieldHtml, без .ccpp-wrap) при «Без родителя» — контраст ≈1.2 и текст на 19 px правее
   соседних «Без компании»/«Без шаблона» (newproj-parent-marker-1). */
.ccpp-wrap .ccpp-field > .ccpp-dot-none, .ccpp-field[data-ccppfor] > .ccpp-dot-none { display: none; }
/* 🔴 ОТКРЫТЫЙ СПИСОК — ПОВЕРХ СОСЕДНИХ БЛОКОВ. Блок, стоящий в разметке ниже, рисовался поверх
   раскрытого списка стадий («Сроки и прогноз» закрывал варианты — кадр владельца 14.09.2026).
   Блок с открытым выбором поднимается над соседями и не клипает свой список. */
.crmw-blk:has(.ccpp-field.open) { position: relative; z-index: 40; }
.crmw-blk:has(.ccpp-field.open) > .di-sec, .di-sec:has(.ccpp-field.open) { overflow: visible; }
.deal-rot-badge { font-size: 10.5px; font-weight: 600; color: var(--warning-ink, var(--warning)); background: var(--warning-soft); padding: 2px 8px; border-radius: 999px; }
html[data-theme="light"] .deal-rot-badge { color: #a15c00; }
.deal-close-btn { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; padding: 5px 9px; border-radius: 9px; border: 1px solid var(--line); background: transparent; color: var(--muted); cursor: pointer; transition: color .12s, border-color .12s, background .12s; }
.deal-close-btn .ic { width: 14px; height: 14px; }
/* «Выиграна»/«Проиграна» — ЧЕРНИЛА смысла (--ok-ink/--danger-ink), рамка — сам цвет: #22a06b давал 3.03–3.85 в обеих темах */
.deal-won:hover, .deal-won.on { color: var(--ok-ink, var(--ok)); border-color: var(--ok); background: rgba(46, 204, 113, .12); }
.deal-lost:hover, .deal-lost.on { color: var(--danger-ink, var(--danger)); border-color: var(--danger); background: var(--danger-soft); }
.deal-drawer-x { border: none; background: transparent; color: var(--muted); cursor: pointer; font-size: 15px; padding: 4px 8px; border-radius: 8px; line-height: 1; }
.deal-drawer-x:hover { background: var(--hover); }
.deal-drawer-body { padding: 16px; overflow-y: auto; display: flex; flex-direction: column; gap: 14px; }
.deal-title-edit { font-size: 19px; font-weight: 700; letter-spacing: -.01em; line-height: 1.25; padding: 6px 8px; margin: -6px -8px; border-radius: 9px; outline: none; transition: background .12s, box-shadow .12s; }
.deal-title-edit:hover { background: var(--hover); }
.deal-title-edit:focus { background: var(--panel-2); box-shadow: inset 0 0 0 1.5px var(--primary); }
.deal-amount-row { display: flex; gap: 8px; align-items: center; }
/* min-width: 0 — поле суммы сжимается само, а не выталкивает валюту за край блока: у input
   min-width:auto = его «родная» ширина (~20 знаков), и в узкой колонке «Сумма / бюджет» лида
   (окно 390) срезала «RUB» на 32 px (замер 21.10). */
.deal-amount-in { flex: 1; min-width: 0; font-size: 16px; font-weight: 700; }
.deal-amount-row input, .deal-amount-row select { padding: 8px 10px; border-radius: 10px; border: 1px solid var(--line); background-color: var(--panel-2); color: var(--text); outline: none; transition: box-shadow .12s, border-color .12s; } .deal-amount-row select { padding-right: 28px; background-position: right 8px center; } /* select-shorthand-chevron-2: цвет, а не сокращение; валюта узкая (76 px) — шеврон ближе к краю */
.deal-amount-row input:focus, .deal-amount-row select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.deal-cur { width: 76px; font-weight: 600; }
.deal-prob-wrap { position: relative; display: inline-flex; align-items: center; }
.deal-prob-in { width: 68px; padding-right: 22px !important; text-align: right; }
.deal-prob-wrap > span { position: absolute; right: 9px; color: var(--muted); font-size: 12px; pointer-events: none; }
.deal-field { display: flex; flex-direction: column; gap: 5px; }
.deal-field > label { font-size: 11.5px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
.deal-field select, .deal-field input { padding: 9px 11px; border-radius: 10px; border: 1px solid var(--line); background-color: var(--panel-2); color: var(--text); outline: none; font-size: 13.5px; transition: box-shadow .12s, border-color .12s; } .deal-field select { padding-right: 34px; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.deal-field select:focus, .deal-field input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
/* 🏢 CLIE-1030·R2 · «Пространство» — читаемое значение, не поле ввода: высота как у соседей ряда,
   но без рамки поля (иначе контрол обещал бы правку, которой тут нет — мёртвых контролов не держим). */
.deal-space-val { display: inline-flex; align-items: center; gap: 7px; padding: 9px 0; font-size: 13.5px; color: var(--text); min-width: auto; }
.deal-space-val svg { width: 15px; height: 15px; color: var(--text-dim); flex: 0 0 auto; }
.deal-space-val span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ➕ ФОРМА НОВОЙ СДЕЛКИ (CRMC-647·4). Владелец: «Как вообще создавать сделки если выбора
   проекта нет?». Раньше кнопка «＋ Сделка» заводила запись вслепую; теперь окно спрашивает
   название, деньги, ПРОЕКТ, ответственного и клиента. Строки-связи — те же `.crmw-owner`,
   что в карточке сделки, поэтому своей вёрстки у них тут нет: только раскладка формы. */
.nd-form { display: flex; flex-direction: column; gap: 12px; }
.nd-form .deal-row2 { display: grid; grid-template-columns: 1fr 108px; gap: 10px; align-items: end; }
.nd-rows { display: flex; flex-direction: column; gap: 8px; }
.nd-rows .crmw-owner { width: 100%; box-sizing: border-box; }
.nd-form .pm-hint { font-size: 12px; line-height: 1.45; }
/* 🏢 CLIE-1030·R4 · «куда ляжет сделка» и «чьи это воронки» — подпись под строкой воронки и
   сноска в поповере выбора. Сужение обязано НАЗЫВАТЬ СЕБЯ: иначе исчезнувшие из списка воронки
   других компаний читаются как «пропали». Тон — подпись, не предупреждение. */
.nd-space-note { margin-top: 6px; font-size: 12px; line-height: 1.4; color: var(--text-dim); }
.tc-pop-note { margin: 6px 2px 2px; padding-top: 7px; border-top: 1px solid var(--line); font-size: 11.5px; line-height: 1.4; color: var(--text-dim); }
.deal-desc-edit { font-size: 13.5px; line-height: 1.5; min-height: 56px; padding: 10px 11px; border-radius: 10px; border: 1px solid var(--line); background: var(--panel-2); outline: none; transition: box-shadow .12s, border-color .12s; }
.deal-desc-edit:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.deal-desc-edit:empty:before { content: attr(data-ph); color: var(--text-dim); }
.deal-act-title { font-size: 12px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em; margin-top: 4px; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.deal-mail-btn { display: inline-flex; align-items: center; gap: 6px; text-transform: none; letter-spacing: 0; font-size: 12px; font-weight: 550; color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); border: 1px solid color-mix(in srgb, var(--primary) 26%, transparent); border-radius: 8px; padding: 5px 10px; cursor: pointer; transition: background .13s, border-color .13s; }
.deal-mail-btn:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); border-color: color-mix(in srgb, var(--primary) 44%, transparent); }
.deal-mail-btn svg { width: 13px; height: 13px; }
.deal-acts { display: flex; flex-direction: column; }
.deal-act { display: flex; gap: 10px; padding: 8px 0; }
.deal-act-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--primary); margin-top: 5px; flex: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent); }
.deal-act-k { font-size: 13px; font-weight: 550; overflow-wrap: anywhere; }
.deal-act-b { min-width: 0; }
.deal-act-m { font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.deal-acts-empty { color: var(--text-dim); font-size: 12.5px; padding: 6px 0; }
/* 🔴 CRMC-697·Р5 · «Активность» показывает 8 строк, остальное — за кнопкой с числом.
   Свёрнутая лента НЕ капится (это прогрессивное раскрытие, а не обрез). Раскрытая кап
   получает — потолок ДОЛЕЙ ЭКРАНА, не прибитыми пикселями (канон `scroll`), а видимость
   бегунка и тающий край приносит класс `.cc-scroll-in` из ЕДИНСТВЕННОГО реестра
   SCROLL_IN_SEL (app.js): своего overflow здесь нет намеренно. */
.deal-acts-list { display: flex; flex-direction: column; }
.deal-acts-list.is-capped { max-height: min(52vh, 468px); }
.deal-acts-foot { display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 6px; padding-top: 8px; border-top: 1px solid var(--line); }
.deal-acts-foot .di-link { display: inline-flex; align-items: center; gap: 5px; }
.deal-acts-foot .di-link svg { width: 13px; height: 13px; flex: none; transition: transform .14s ease; }
.deal-acts-foot .deal-acts-more[data-dacts="less"] svg { transform: rotate(180deg); }
.deal-acts-foot .deal-acts-win { margin-left: auto; color: var(--text-dim); font-weight: 500; }
.deal-acts-foot .deal-acts-win:hover { color: var(--primary); }
/* Вся лента отдельным окном: тело `.pm-card.pm-wide .pm-body` уже стоит в SCROLL_IN_SEL,
   поэтому бегунок виден и край тает — своего капа окну не нужно. */
.dacts-win .deal-act { padding: 9px 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent); }
.dacts-win .deal-act:last-child { border-bottom: 0; }
.deal-acts-cnt { margin-top: 10px; font-size: 12px; color: var(--text-dim); }
.deal-acts-cnt b { color: var(--text); font-weight: 650; }
@media (max-width: 560px) { .deal-list-head { display: none; } .deal-row { grid-template-columns: 1fr auto; gap: 3px 10px; } .deal-row-company, .deal-row-owner, .deal-row-prob, .deal-row-close { display: none; } }

/* ── 🎯 Conversation Intelligence сделки (бриф / deal-risk / next-steps / трекеры / ask) ── */
/* 🧱 CLIE-952·Ч13: обёртки .deal-intel больше нет — карточки интеллекта стали отдельными
   блоками реестра (.crmw-blk) и участвуют в сетке напрямую. */
.di-sec { border: 1px solid var(--line); border-radius: 13px; background: var(--panel-2); overflow: hidden; }
.di-sec-h { display: flex; align-items: center; justify-content: space-between; padding: 9px 12px; border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent); }
.di-sec-t { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
.di-sec-t .ic { width: 14px; height: 14px; opacity: .8; }
.di-sec-b { padding: 11px 12px; display: flex; flex-direction: column; gap: 9px; }
.di-empty { font-size: 12.5px; color: var(--text-dim); line-height: 1.5; }
/* 🔴 КЛАСС БАГА, а не частный случай: `.deal-drawer-body` — flex-колонка со скроллом, а у `.di-sec`
   стоит `overflow:hidden` → его `min-height:auto` = 0, и ЛЮБАЯ прямая секция схлопывается в 2px
   (в DOM есть, человек не видит НИЧЕГО — на этом уже горела секция «Переписка», ниже в файле).
   Правило общее для всех секций шторки, чтобы следующая новая не наступила на те же грабли. */
.deal-drawer-body > .di-sec { flex: none; }
/* 🔗 Секция «Чат сделки» (CRMC-30/1): привязанная беседа + действия. Правило «поле и его кнопка —
   не в один ряд»: имя беседы занимает строку целиком, действия — строкой ниже, слева. */
.di-chat-row { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
.di-chat-name { display: flex; align-items: center; gap: 7px; min-width: 0; font-size: 13px; color: var(--text); background: var(--panel); border: 1px solid var(--line); border-radius: 9px; padding: 7px 10px; }
.di-chat-name > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.di-chat-name svg.ic { width: 14px; height: 14px; flex: none; color: var(--muted); }
.di-chat-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* inline-flex + nowrap: у кнопок с иконкой (`svgIcon(...)<span>…`) иначе иконка и подпись
   вставали в ДВА ряда и кнопка выглядела кривой (CRMC-30/1). */
.di-btn { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; font-size: 12.5px; font-weight: 600; color: #fff; background: var(--acc-fill); border: none; border-radius: 9px; padding: 7px 13px; cursor: pointer; transition: filter .12s, transform .12s; }
.di-btn > svg.ic { width: 14px; height: 14px; flex: none; }
.di-btn:hover { filter: brightness(1.06); } .di-btn:active { transform: translateY(1px); } .di-btn:disabled { opacity: .6; cursor: default; }
.di-mini { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--text-dim); cursor: pointer; transition: color .12s, border-color .12s; }
.di-mini:hover { color: var(--primary); border-color: var(--primary); } .di-mini .ic { width: 14px; height: 14px; } .di-mini.busy { opacity: .6; }
/* Deal-risk */
.di-risk-main { display: flex; align-items: center; gap: 13px; }
.di-risk-score { display: flex; align-items: baseline; gap: 1px; font-weight: 750; line-height: 1; padding: 8px 12px; border-radius: 12px; }
.di-risk-num { font-size: 26px; } .di-risk-den { font-size: 13px; opacity: .6; }
.di-risk-score.band-low { color: #22a06b; background: rgba(46, 204, 113, .13); }
.di-risk-score.band-medium { color: #d99311; background: color-mix(in srgb, #f5a623 16%, transparent); }
.di-risk-score.band-high { color: var(--danger); background: var(--danger-soft); }
.di-risk-band { font-size: 13px; font-weight: 700; }
.di-risk-band.band-low { color: #22a06b; } .di-risk-band.band-medium { color: #d99311; } .di-risk-band.band-high { color: var(--danger); }
.di-risk-pct { display: block; font-size: 11.5px; color: var(--text-dim); margin-top: 2px; }
.di-risk-expl { font-size: 13px; line-height: 1.55; color: var(--text); }
.di-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.di-chip { font-size: 11px; font-weight: 550; color: var(--text-dim); background: var(--panel); border: 1px solid var(--line); border-radius: 7px; padding: 3px 8px; }
/* Бриф */
.di-brief-text { font-size: 13.5px; line-height: 1.58; color: var(--text); white-space: pre-wrap; }
.di-facts { display: grid; grid-template-columns: auto 1fr; gap: 4px 12px; margin-top: 3px; }
.di-fact { display: contents; }
.di-fact-k { font-size: 11.5px; font-weight: 600; color: var(--text-dim); }
.di-fact-v { font-size: 12.5px; color: var(--text); }
/* Next-steps checklist */
.di-steps-list { display: flex; flex-direction: column; gap: 2px; }
.di-step { display: flex; align-items: flex-start; gap: 9px; padding: 5px 2px; border-radius: 8px; transition: background .12s; }
.di-step:hover { background: color-mix(in srgb, var(--hover) 60%, transparent); }
.di-step:hover .di-step-del, .di-step:hover .di-step-plan { opacity: .55; }
.di-check { flex: none; width: 19px; height: 19px; margin-top: 1px; border-radius: 6px; border: 1.6px solid var(--line); background: transparent; color: #fff; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: background .12s, border-color .12s; }
.di-check .ic { width: 12px; height: 12px; stroke-width: 3; }
.di-step.done .di-check { background: var(--primary); border-color: var(--primary); }
.di-step-txt { flex: 1; font-size: 13px; line-height: 1.5; outline: none; padding: 1px 3px; border-radius: 5px; word-break: break-word; }
.di-step-txt:focus { background: var(--panel); box-shadow: 0 0 0 2px var(--glow); }
.di-step.done .di-step-txt { color: var(--text-dim); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--text-dim) 60%, transparent); }
.di-step-del { flex: none; opacity: 0; width: 20px; height: 20px; border: none; background: transparent; color: var(--text-dim); font-size: 13px; cursor: pointer; transition: opacity .12s, color .12s; }
.di-step-del:hover { color: var(--danger); opacity: 1 !important; }
/* 📅 Шаг ИИ → дело одним нажатием: та же деликатная кнопка-хвостик, что «удалить», но в акценте. */
.di-step-plan { flex: none; opacity: 0; width: 20px; height: 20px; margin-top: 1px; border: none; background: transparent; color: var(--text-dim); cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: opacity .12s, color .12s; }
.di-step-plan .ic { width: 14px; height: 14px; }
.di-step-plan:hover { color: var(--primary); opacity: 1 !important; }
.di-step-plan:disabled { opacity: .3 !important; cursor: default; }
.di-addstep { margin-top: 3px; }
.di-addstep-in { width: 100%; font-size: 12.5px; padding: 7px 9px; border-radius: 8px; border: 1px dashed var(--line); background: transparent; color: var(--text); outline: none; transition: border-color .12s; }
.di-addstep-in:focus { border-style: solid; border-color: var(--primary); }
.di-steps-empty { padding: 2px 0; }
/* Smart-Trackers */
.di-tr { display: flex; align-items: center; gap: 9px; padding: 7px 9px; border-radius: 9px; background: var(--panel); border: 1px solid var(--line); }
.di-tr + .di-tr { margin-top: 6px; }
.di-tr-cat { flex: none; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .02em; padding: 3px 7px; border-radius: 6px; }
.di-tr.cat-competitor .di-tr-cat { color: var(--cm-7c5cff, #7c5cff); background: color-mix(in srgb, var(--cm-7c5cff, #7c5cff) 15%, transparent); }
.di-tr.cat-price .di-tr-cat { color: #d99311; background: color-mix(in srgb, #f5a623 16%, transparent); }
.di-tr.cat-churn .di-tr-cat { color: var(--danger); background: var(--danger-soft); }
.di-tr-snip { flex: 1; font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.di-tr-time { flex: none; font-size: 11px; color: var(--text-dim); }
.di-tr-x { flex: none; border: none; background: transparent; color: var(--text-dim); font-size: 12px; cursor: pointer; opacity: .5; transition: opacity .12s, color .12s; }
.di-tr-x:hover { opacity: 1; color: var(--danger); }
/* Ask-anything + коучинг */
.di-ask-row { display: flex; gap: 7px; }
.di-ask-in { flex: 1; font-size: 13px; padding: 8px 11px; border-radius: 9px; border: 1px solid var(--line); background: var(--panel); color: var(--text); outline: none; transition: border-color .12s, box-shadow .12s; }
.di-ask-in:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.di-ask-send { flex: none; width: 36px; border-radius: 9px; border: none; background: var(--acc-fill); color: #fff; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; transition: filter .12s; }
.di-ask-send:hover { filter: brightness(1.06); } .di-ask-send .ic { width: 16px; height: 16px; }
.di-ask-tools { display: flex; }
.di-link { border: none; background: transparent; color: var(--primary); font-size: 12.5px; font-weight: 550; cursor: pointer; padding: 2px 0; }
.di-link:hover { text-decoration: underline; }
/* 🪄 Magic Fields (сделка) + Обогащение (контакт) — превью «до → после» / «пусто → значение» */
.dmagic-body, .crm-enrich-body { display: flex; flex-direction: column; gap: 9px; }
.dmagic-list { display: flex; flex-direction: column; gap: 6px; }
.dmagic-row { display: grid; grid-template-columns: 22px 1fr; gap: 9px; align-items: start; padding: 9px 10px; border: 1px solid var(--line); border-radius: 11px; background: var(--panel-2); cursor: pointer; transition: border-color .13s, background .13s; }
.dmagic-row:hover { border-color: color-mix(in srgb, var(--primary) 42%, var(--line)); background: color-mix(in srgb, var(--primary) 4%, var(--panel-2)); }
.dmagic-chk { display: flex; align-items: center; justify-content: center; padding-top: 1px; }
.dmagic-chk input { appearance: none; -webkit-appearance: none; margin: 0; width: 17px; height: 17px; border: 1.5px solid color-mix(in srgb, var(--text-dim) 55%, transparent); border-radius: 6px; background: var(--panel); cursor: pointer; position: relative; transition: background .12s, border-color .12s; }
.dmagic-chk input:hover { border-color: var(--primary); }
.dmagic-chk input:checked { background: var(--primary); border-color: var(--primary); }
.dmagic-chk input:checked::after { content: ""; position: absolute; left: 5px; top: 2px; width: 4px; height: 8px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.dmagic-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.dmagic-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dmagic-label { font-size: 12.5px; font-weight: 650; color: var(--text); }
.dmagic-diff { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; font-size: 12.5px; line-height: 1.4; }
.dmagic-before { color: var(--text-dim); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--text-dim) 55%, transparent); word-break: break-word; }
.dmagic-arrow { color: var(--text-dim); font-weight: 700; }
.dmagic-after { color: var(--text); font-weight: 600; background: color-mix(in srgb, var(--primary) 13%, transparent); border-radius: 6px; padding: 1px 7px; word-break: break-word; }
.dmagic-ev { font-size: 11.5px; color: var(--text-dim); line-height: 1.45; font-style: italic; }
.dmagic-foot { display: flex; align-items: center; gap: 12px; margin-top: 3px; }
.crm-enrich-src { font-size: 11px; font-weight: 550; color: var(--text-dim); background: var(--panel); border: 1px solid var(--line); border-radius: 6px; padding: 1px 7px; }
.crm-enrich-handle { display: inline-flex; align-items: center; gap: 4px; align-self: flex-start; font-size: 12px; font-weight: 600; color: var(--primary); }
.crm-enrich-btn { align-self: flex-start; }
.di-ask-ans:empty { display: none; }
.di-ask-load { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--text-dim); }
.di-ask-load .ic { width: 14px; height: 14px; animation: di-pulse 1.1s ease-in-out infinite; }
@keyframes di-pulse { 0%, 100% { opacity: .4; } 50% { opacity: 1; } }
.di-ask-a { font-size: 13px; line-height: 1.58; color: var(--text); background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px; white-space: pre-wrap; }
.di-ask-empty { color: var(--text-dim); }
.di-src { font-size: 12px; color: var(--text-dim); padding: 3px 0; }
.di-src + .di-src { border-top: 1px solid color-mix(in srgb, var(--line) 50%, transparent); }
.di-coach { font-size: 13px; line-height: 1.55; background: var(--panel); border: 1px solid var(--line); border-radius: 10px; padding: 11px 12px; display: flex; flex-direction: column; gap: 8px; }
.di-coach-s { white-space: pre-wrap; color: var(--text); }
.di-coach-n { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 3px; }
.di-coach-n li { font-size: 12px; color: var(--text-dim); }
.di-coach-copy { align-self: flex-start; }

/* ── Позиции сделки (line items) в drawer + «Сформировать КП» ── */
.di-lineitems .di-sec-h { gap: 10px; }
.di-quote-btn { display: inline-flex; align-items: center; gap: 6px; }
.di-quote-btn .ic { width: 14px; height: 14px; }
/* 🔴 CLIE-952·Ч15 · УЗКИЙ БЛОК: имя схлопывалось в НОЛЬ, и это было ДО правки. Замер стенда на
   телефоне (блок 300 px): пяти фиксированных столбиков + зазоров нужно 334 px, а `1fr` под имя
   получал остаток — то есть 0 px, и наименование позиции не было видно ВООБЩЕ. Даём таблице
   честный минимум и прокрутку: ничего не прячем и ничего не схлопываем (правило CLIE-620
   «список не капим, оставшийся скролл ПОКАЗЫВАЕМ» — поэтому бегунок тут виден всегда, а не
   только под курсором). Ширина считается от БЛОКА, а не от окна: блок бывает ½ и во всю
   ширину по настройке человека (CLIE-952·Ч13). */
.dli-table { display: flex; flex-direction: column; overflow-x: auto; scrollbar-width: thin; }
.dli-table::-webkit-scrollbar { height: 7px; }
.dli-table::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 7px; }
.dli-head, .dli-rows { min-width: 446px; }
/* 🔴🔴 CLIE-952·Ч15 · «Верстка кривая, текст не влезает в столбик» (владелец 10.09.2026, скрин
   шапки: «СКИДКА» и «%» на ДВУХ строках). Причина классовая, а не «этот экран»: ширины
   столбиков прибиты в px, а ширина ПОДПИСИ зависит от шрифта ОС — замер на живом проде дал у
   «Скидка %» столбик 58 px при подписи 58 px, то есть ЗАПАС РОВНО 0, и системный шрифт macOS
   (шире нашего) переносил её на вторую строку. Это канон `label-fit` (СРЕД-33) «контрол не
   сжимается ниже своей подписи»: у заголовка обязан быть ЗАПАС, а не совпадение до пикселя.
   🔴 Столбики остаются ФИКСИРОВАННЫМИ: шапка и строки — ДВА разных грида, и content-based
   треки (`auto`/`max-content`) считались бы у них независимо, то есть разъехались бы. */
.dli-head, .dli-row { display: grid; grid-template-columns: minmax(0, 1fr) 56px 74px 74px 78px 22px; align-items: center; gap: 6px; }
.dli-head { padding: 0 2px 6px; font-size: 10.5px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
/* Заголовок не переносится по слову. Обрезка тут ЗАЯВЛЕНА (СРЕД-33 разрешает `min-width: 0`
   ровно рядом с ней): на чужом шрифте лучше честное многоточие, чем молчаливая вторая строка,
   ломающая весь ряд. Полный текст остаётся в `title`. */
.dli-head > span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dli-head .dli-h-price, .dli-head .dli-h-sum { text-align: right; }
.dli-head .dli-h-qty, .dli-head .dli-h-disc { text-align: center; }
.dli-row { padding: 4px 2px; border-radius: 8px; transition: background .12s; }
.dli-row:hover { background: color-mix(in srgb, var(--hover) 60%, transparent); }
.dli-row:hover .dli-del { opacity: .55; }
.dli-name { min-width: 0; font-size: 13px; color: var(--text); outline: none; padding: 4px 6px; border-radius: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dli-name:focus { background: var(--panel); box-shadow: 0 0 0 2px var(--glow); white-space: normal; }
.dli-name:empty::before { content: "Наименование"; color: var(--text-dim); }
.dli-qty, .dli-price, .dli-disc { width: 100%; font-size: 12.5px; padding: 5px 6px; border-radius: 7px; border: 1px solid transparent; background: transparent; color: var(--text); outline: none; text-align: right; transition: border-color .12s, background .12s; }
.dli-qty { text-align: center; }
.dli-disc { text-align: center; }
.dli-qty:hover, .dli-price:hover, .dli-disc:hover { background: var(--panel); }
.dli-qty:focus, .dli-price:focus, .dli-disc:focus { border-color: var(--primary); background: var(--panel); box-shadow: 0 0 0 2px var(--glow); }
.dli-sum { font-size: 12.5px; font-weight: 600; color: var(--text); text-align: right; white-space: nowrap; }
.dli-del { opacity: 0; width: 20px; height: 20px; border: none; background: transparent; color: var(--text-dim); font-size: 12px; cursor: pointer; transition: opacity .12s, color .12s; }
.dli-del:hover { color: var(--danger); opacity: 1 !important; }
.dli-sum-total { margin-top: 4px; padding-top: 8px; border-top: 1px solid color-mix(in srgb, var(--line) 60%, transparent); font-size: 12.5px; color: var(--text-dim); display: flex; justify-content: flex-end; gap: 6px; }
.dli-sum-total b { color: var(--text); font-weight: 700; }

/* ══ CRM · Фаза 3 «Коммерция» в карточке сделки (0174): КП/e-sign/approval · заказы · счета · подписки · контракты ══ */
/* 🔴 Блок «КП и смета» (CLIE-943·Ч12) берёт геометрию «Коммерции» — своих чисел нет. */
.di-commerce .dc-body, .di-kp .dc-body { display: flex; flex-direction: column; gap: 14px; }
.dc-grp { display: flex; flex-direction: column; gap: 7px; }
.dc-grp-h { font-size: 11px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase; color: var(--text-dim); display: flex; align-items: center; justify-content: space-between; }
.dc-item { border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; background: var(--panel-2); display: flex; flex-direction: column; gap: 7px; transition: border-color .14s ease, background .14s ease; }
.dc-item:hover { border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.dc-item-h { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.dc-item-t { font-size: 13.5px; font-weight: 600; color: var(--text); }
.dc-item-sum { font-size: 13.5px; font-weight: 700; color: var(--text); white-space: nowrap; }
.dc-item-m { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.dc-chip { display: inline-flex; align-items: center; font-size: 11px; font-weight: 600; line-height: 1; padding: 4px 8px; border-radius: 999px; white-space: nowrap; }
.dc-chip.dc-ok { background: color-mix(in srgb, #34c759 18%, transparent); color: #248a3d; }
.dc-chip.dc-info { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary); }
.dc-chip.dc-warn { background: color-mix(in srgb, #ff9f0a 20%, transparent); color: #b25e00; }
.dc-chip.dc-bad { background: color-mix(in srgb, #ff3b30 16%, transparent); color: #c9251b; }
.dc-chip.dc-muted { background: var(--hover); color: var(--text-dim); }
html[data-theme="dark"] .dc-chip.dc-ok, :root:not([data-theme]) .dc-chip.dc-ok { color: #4cd964; }
html[data-theme="dark"] .dc-chip.dc-warn, :root:not([data-theme]) .dc-chip.dc-warn { color: #ffb340; }
html[data-theme="dark"] .dc-chip.dc-bad, :root:not([data-theme]) .dc-chip.dc-bad { color: #ff6961; }
/* ═══ 💬 ВОПРОСЫ КЛИЕНТА ПО СМЕТЕ (CLIE-943·Ч4; вёрстка — CLIE-943·Ч12) ═══════════════
   🔴 Класса `.eqa-*` в проекте НЕ БЫЛО НИ ОДНОГО: окно рисовалось голыми div'ами, поэтому
      «1.5Новый блок сметы8 ч · 8 ₽» слипалось в строку, поле ответа обрезалось собственной
      высотой по умолчанию, а кнопки стояли вплотную к нему. Это ровно та жалоба владельца
      09.09.2026 («вёрстка и дизайн ответа на вопросы кривая»).
   🔴 Своих цветов и своих размеров тут нет: карточка нити повторяет геометрию `.dc-item`,
      чипы — `.dc-chip`, кнопки — `.dc-a`, поэтому обе темы приезжают вместе с базой
      (CLIE-505). Ни одной левой рейки: акцент несут подложка и кольцо (CLIE-483).
   🔴 Поле ответа и его кнопки — ДВУМЯ строками (правило «поле + кнопка», CLIE-425). */
.eqa-box { width: min(760px, 94vw); }
.eqa-box .modal-body { display: flex; flex-direction: column; gap: 12px; }
.eqa-th { display: flex; flex-direction: column; gap: 12px; padding: 14px 16px 10px; border-radius: 16px; background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); transition: box-shadow .14s ease; }
.eqa-th.done .eqa-msgs { opacity: .86; }
.eqa-th.eqa-hl { box-shadow: inset 0 0 0 1.5px var(--primary), 0 0 0 4px var(--glow); }
/* Зона 1 — «о чём вопрос»: номер пункта · название · часы и деньги тихой подписью. */
.eqa-h { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.eqa-h-t { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; min-width: 0; flex: 1 1 auto; }
.eqa-num { flex: none; font-size: 11px; font-weight: 700; letter-spacing: .02em; line-height: 1; padding: 4px 7px; border-radius: 7px; background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary-2); }
.eqa-h-name { font-size: 14.5px; font-weight: 620; color: var(--text); line-height: 1.35; overflow-wrap: anywhere; }
.eqa-h-sub { font-size: 12.5px; color: var(--text-dim); white-space: nowrap; }
.eqa-h-m { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; flex: none; max-width: 52%; padding-top: 3px; }
.eqa-src { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; max-width: 220px; }
.eqa-src .ic { width: 14px; height: 14px; flex: none; }
.eqa-src span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Состояние нити — точка + слово (канон accent: «в строке — точка 6–7px, а не плашка»). */
.eqa-st { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; line-height: 1.2; color: var(--text-dim); white-space: nowrap; }
.eqa-st i { flex: none; width: 7px; height: 7px; border-radius: 50%; background: #ff9f0a; }
.eqa-st.done i { background: #34c759; }
.eqa-st.new i { background: var(--acc-fill, var(--primary)); }
/* Зона 2 — переписка: ПЛОСКИЕ строки «лицо · имя · время · текст» (CLIE-2020·4). Коробка в
   коробке на телефоне съедала ширину и читалась как форма, а не как разговор. */
.eqa-msgs { display: flex; flex-direction: column; gap: 12px; }
.eqa-m { display: flex; align-items: flex-start; gap: 10px; min-width: 0; }
.eqa-av { position: relative; flex: none; width: 28px; height: 28px; border-radius: 50%; overflow: hidden; margin-top: 1px; font-size: 11px; font-weight: 700; letter-spacing: .01em; background: var(--hover); }
.eqa-mb { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.eqa-who { display: flex; align-items: baseline; gap: 6px; min-width: 0; min-height: 18px; font-size: 12.5px; line-height: 1.3; color: var(--text-dim); }
.eqa-who b { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 650; color: var(--text); }
.eqa-when { flex: none; font-size: 11.5px; font-variant-numeric: tabular-nums; }
.eqa-m p { margin: 0; font-size: 14px; line-height: 1.45; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
.eqa-empty { font-size: 13px; line-height: 1.45; color: var(--text-dim); }
/* Зона 3 — ответ: поле-пилюля в ОДНУ строку (растёт по набору до ~6, `ccThreadCardGrow`) и
   круглая отправка внутри него — «доминирующее поле + компактная иконка» (CLIE-425). */
.eqa-f { display: flex; flex-direction: column; align-items: stretch; gap: 4px; padding-top: 12px; border-top: 1px solid color-mix(in srgb, var(--line) 65%, transparent); }
.eqa-cmp { display: flex; align-items: flex-end; gap: 6px; padding: 4px 4px 4px 14px; border-radius: 20px; background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); transition: box-shadow .14s ease; }
.eqa-cmp:focus-within { box-shadow: inset 0 0 0 1.5px var(--primary), 0 0 0 3px var(--glow); }
.eqa-t { flex: 1; min-width: 0; box-sizing: border-box; height: 32px; min-height: 32px; max-height: 148px; resize: none; overflow-y: auto; font: inherit; font-size: 14px; line-height: 20px; padding: 6px 0; border: 0; border-radius: 0; background: transparent; color: var(--text); }
.eqa-t::placeholder { color: var(--text-dim); }
/* Пустое поле — одна строка: длинная подсказка на узком экране переносилась во вторую, скрытую строку и резалась на полуслове. */
.eqa-t:not(.mthr-edit):placeholder-shown { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.eqa-t:not(.mthr-edit)::placeholder { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.eqa-t:focus { outline: none; }
.eqa-send { appearance: none; flex: none; width: 32px; height: 32px; padding: 0; border: 0; border-radius: 50%; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; background: var(--acc-fill, var(--primary)); color: #fff; transition: opacity .14s ease, transform .06s ease, filter .14s ease; }
.eqa-send svg.ic { width: 17px; height: 17px; stroke-width: 2.4; }
.eqa-send:hover { filter: brightness(1.08); }
.eqa-send:active { transform: scale(.93); }
.eqa-send:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 60%, transparent); outline-offset: 2px; }
/* Пустое поле — отправка приглушена (нажатие всё равно отвечает словами «Напишите…»). */
.eqa-cmp:has(.eqa-t:placeholder-shown) .eqa-send:not(.busy) { opacity: .42; }
.eqa-send.busy { cursor: progress; }
.eqa-send.busy svg { display: none; }
.eqa-send.busy::after { content: ""; width: 14px; height: 14px; box-sizing: border-box; border-radius: 50%; border: 2px solid rgba(255,255,255,.45); border-top-color: #fff; animation: ccSpin .7s linear infinite; }
.eqa-acts { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.eqa-done { appearance: none; font: inherit; display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 8px; margin-left: -6px; border: 0; border-radius: 8px; cursor: pointer; background: transparent; font-size: 12.5px; font-weight: 600; color: var(--text-dim); transition: background .12s ease, color .12s ease; }
.eqa-done svg.ic { width: 14px; height: 14px; flex: none; }
.eqa-done:hover, .eqa-done:focus-visible { background: var(--hover); color: var(--text); outline: none; }
/* 🔴 Базовый `.primary` — это КНОПКА ФОРМЫ: `width:100%` + `margin-top`. В ряду действий
   (`.dc-acts`) он растягивал «Открыть PDF» на всю строку и сбрасывал соседа на вторую —
   поймано СКРИНОМ, а не чтением CSS. Ряд возвращает кнопке её ширину. */
.dc-acts .dc-a.primary { width: auto; margin-top: 0; }
@media (max-width: 560px) { .eqa-h-sub { white-space: normal; } .eqa-th { padding: 13px 13px 8px; } }

/* ══ 📖💬 CLIE-2020 · ЧИТАЛКА СООБЩЕНИЯ И ОБСУЖДЕНИЕ ФРАГМЕНТОВ ═══════════════════════════════
   Владелец: «если сообщение большое — открыть его в большой модалке… писать комментарии на
   определённые части сообщения и вести диалог, как когда мы отправляем смету». Карточка нити —
   та же `ccThreadCardHtml` (`.eqa-*` выше), здесь только своё: строка под пузырём, рама окна,
   текст для чтения и подсветка обсуждаемых фрагментов. Акцент — подложка и кольцо, без реек. */
.msg-thr-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; max-width: 100%; }
.msg.mine .msg-thr-row { justify-content: flex-end; }
.msg-thr-open, .msg-thr-chip {
  appearance: none; font-family: inherit; display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 9px; border-radius: 999px; cursor: pointer;
  font-size: 12px; font-weight: 600; line-height: 1; white-space: nowrap;
  color: var(--text-dim); background: var(--panel-2); border: 1px solid var(--line);
  transition: background .13s ease, color .13s ease, border-color .13s ease, transform .06s ease;
}
.msg-thr-open:hover, .msg-thr-chip:hover { color: var(--text); background: var(--hover); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.msg-thr-open:active, .msg-thr-chip:active { transform: scale(.97); }
.msg-thr-open:focus-visible, .msg-thr-chip:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 1px; }
.msg-thr-open svg.ic, .msg-thr-chip svg.ic { width: 13px; height: 13px; flex: none; }
/* Есть нерешённое — чип говорит акцентом: подложка + кольцо, а не точка-загадка. */
.msg-thr-chip.open { color: var(--primary); background: color-mix(in srgb, var(--primary) 11%, transparent); border-color: color-mix(in srgb, var(--primary) 34%, transparent); }

/* Рама: широкое окно на две колонки — слева текст, справа обсуждения. Ширину тянет мышью
   `initWindowResize()` (data-ccwin), своего z-index нет — слой поднимает `ccLayerLift`. */
.mrd-box { width: min(1180px, 96vw); max-width: none; height: min(88vh, 980px); }
.mrd-head { gap: 12px; padding: 12px 14px 12px 20px; }
.mrd-who { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; flex: 1 1 auto; }
.mrd-who b { font-size: 15px; font-weight: 650; color: var(--text); }
.mrd-when { font-size: 12.5px; font-weight: 500; color: var(--text-dim); }
.mrd-tools { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.mrd-tools .dc-a { gap: 6px; }
.mrd-tools .dc-a svg.ic { width: 14px; height: 14px; flex: none; }
.mrd-rich.on { color: var(--primary); background: color-mix(in srgb, var(--primary) 9%, var(--panel)); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.mrd-cols { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 384px); }
.mrd-main { overflow-y: auto; overscroll-behavior: contain; padding: 30px clamp(18px, 4vw, 56px) 44px; }
.mrd-msg { max-width: 760px; margin: 0 auto; }
/* Текст для чтения, а не пузырь: без заливки, крупнее и с воздухом (как документ). Чернила —
   свои (`--bub-*`): `.mrd-msg` не `.msg`, наследовать нечего. */
.mrd-msg .bubble.mrd-doc {
  --bub-ink: var(--text); --bub-ink-dim: var(--text-dim);
  --bub-tint: color-mix(in srgb, var(--text) 6%, transparent);
  --bub-line: color-mix(in srgb, var(--text) 16%, transparent);
  background: transparent; border: 0; box-shadow: none; padding: 0; border-radius: 0;
  color: var(--text); font-size: 16px; line-height: 1.62; letter-spacing: -.005em;
  user-select: text; -webkit-user-select: text;
}
.mrd-doc .md-body h1 { font-size: 24px; margin: 22px 0 10px; }
.mrd-doc .md-body h2 { font-size: 20px; margin: 20px 0 8px; }
.mrd-doc .md-body h3 { font-size: 17px; margin: 16px 0 6px; }
.mrd-doc .md-body p, .mrd-doc .md-body ul, .mrd-doc .md-body ol { margin-bottom: 14px; }
.mrd-doc .md-body li { margin: 5px 0; }
.mrd-hint { display: flex; align-items: center; justify-content: center; gap: 6px; max-width: 760px; margin: 30px auto 0; font-size: 12.5px; color: var(--text-dim); }
.mrd-hint svg.ic { width: 14px; height: 14px; flex: none; }

/* Обсуждаемый фрагмент в тексте: тёплая подложка с подчёркиванием — видно и в тексте, и
   на кнопке-цитате нити (`.mthr-q`), одним цветом. Решённое гаснет до пунктира. */
mark.mrd-hl {
  color: inherit; cursor: pointer; border-radius: 3px; padding: 0 1px; margin: 0 -1px;
  background: color-mix(in srgb, #ffb800 24%, transparent);
  box-shadow: inset 0 -1.5px 0 color-mix(in srgb, #e09400 72%, transparent);
  transition: background .14s ease, box-shadow .14s ease;
}
mark.mrd-hl:hover { background: color-mix(in srgb, #ffb800 36%, transparent); }
mark.mrd-hl.cur { background: color-mix(in srgb, #ffb800 46%, transparent); box-shadow: 0 0 0 1.5px color-mix(in srgb, #e09400 85%, transparent); }
mark.mrd-hl.done { background: transparent; box-shadow: none; text-decoration: underline dotted color-mix(in srgb, var(--text-dim) 75%, transparent); text-underline-offset: 3px; }
mark.mrd-hl.done.cur { background: color-mix(in srgb, var(--text) 8%, transparent); }

.mrd-side { display: flex; flex-direction: column; min-height: 0; border-left: 1px solid var(--line); background: color-mix(in srgb, var(--panel-2) 40%, var(--panel)); }
/* Ограда выделения (CLIE-2020·3): пока мышь тянет выделение, начатое в тексте, всё вокруг
   текста невыделяемо — мышь, ушедшая в «Обсуждения», не забирает их заголовок, подсказку и
   кнопки. Начатое в «Обсуждениях» точно так же не тянет за собой текст. Атрибут ставит и
   снимает `setupMsgSelCopy` (нажатие → отпускание). */
.mrd-dim[data-mrd-sel], .mrd-dim[data-mrd-sel] * { -webkit-user-select: none; user-select: none; }
.mrd-dim[data-mrd-sel="doc"] .mrd-doc, .mrd-dim[data-mrd-sel="doc"] .mrd-doc *,
.mrd-dim[data-mrd-sel="side"] .mrd-list, .mrd-dim[data-mrd-sel="side"] .mrd-list *,
.mrd-dim[data-mrd-sel] :is(input, textarea, [contenteditable]) { -webkit-user-select: text; user-select: text; }
.mrd-side-h { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; padding: 16px 16px 10px; }
.mrd-side-h b { font-size: 14px; font-weight: 650; color: var(--text); }
.mrd-count { font-size: 12px; color: var(--text-dim); }
.mrd-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; display: flex; flex-direction: column; gap: 10px; padding: 2px 14px 14px; }
.mrd-whole { margin: 8px 14px 14px; justify-content: center; gap: 6px; padding: 8px 12px; font-size: 13px; }
.mrd-whole svg.ic { width: 14px; height: 14px; flex: none; }
.mrd-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 6px; padding: 40px 12px 28px; color: var(--text-dim); }
.mrd-empty svg.ic { width: 28px; height: 28px; opacity: .7; margin-bottom: 4px; }
.mrd-empty p { margin: 0; font-size: 14px; font-weight: 600; color: var(--text); }
.mrd-empty p.mrd-empty-sub { max-width: 270px; font-size: 12.5px; font-weight: 500; line-height: 1.45; color: var(--text-dim); }
.mrd-err { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 12px; border-radius: 12px; font-size: 13px; color: var(--text); background: color-mix(in srgb, #ff3b30 10%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #ff3b30 28%, transparent); }

/* Карточка нити в узкой колонке: та же `.eqa-th`, поплотнее. */
.mthr-th { padding: 12px 13px 8px; gap: 11px; }
.mthr-new { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--primary) 55%, transparent); }
.mthr-q {
  appearance: none; font: inherit; text-align: left; border: 0; cursor: pointer; max-width: 100%;
  padding: 6px 9px; border-radius: 9px; color: var(--text); font-size: 13px; line-height: 1.45;
  background: color-mix(in srgb, #ffb800 16%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #e09400 30%, transparent);
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; overflow-wrap: anywhere;
  transition: background .13s ease;
}
button.mthr-q:hover { background: color-mix(in srgb, #ffb800 26%, transparent); }
button.mthr-q:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: 1px; }
.mthr-th.done .mthr-q { background: color-mix(in srgb, var(--text) 6%, transparent); box-shadow: inset 0 0 0 1px var(--line); }
.mthr-ed { font-size: 11px; font-weight: 500; opacity: .8; }
/* Своё правится нажатием на сам текст (канон «нажал → изменил»): отклик — мягкая подложка. */
.mthr-txt { cursor: text; border-radius: 8px; margin: -3px -5px; padding: 3px 5px; transition: background .12s ease; }
.mthr-txt:hover, .mthr-txt:focus-visible { background: var(--hover); outline: none; }
.mthr-txt p { margin: 0; font-size: 13.5px; line-height: 1.45; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere; }
/* Правка своей реплики — обычное поле в рамке (у поля ответа рамку несёт пилюля `.eqa-cmp`). */
.eqa-t.mthr-edit { display: block; width: 100%; height: auto; min-height: 64px; padding: 8px 10px; line-height: 1.45; border: 1px solid var(--primary); border-radius: 10px; background: var(--panel); box-shadow: 0 0 0 3px var(--glow); }
.mthr-del {
  appearance: none; margin-left: auto; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 6px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-dim); opacity: .6;
  transition: opacity .12s ease, background .12s ease, color .12s ease;
}
.mthr-del svg.ic { width: 14px; height: 14px; }
/* Палец: 22 px — мимо. Поле промаха (канон tap-target) раскладку не двигает; снизу короче,
   чтобы не отнимать нажатие у своего текста (он правится по тапу). */
@media (pointer: coarse) {
  .mthr-del { position: relative; opacity: .85; }
  .mthr-del::after { content: ""; position: absolute; inset: -11px -11px -4px -11px; }
}
.eqa-m:hover .mthr-del { opacity: 1; }
.mthr-del:hover, .mthr-del:focus-visible { opacity: 1; color: #c9251b; background: color-mix(in srgb, #ff3b30 12%, transparent); outline: none; }
html[data-theme="dark"] .mthr-del:hover, :root:not([data-theme]) .mthr-del:hover { color: #ff6961; }

/* Части шапки шторки, которые живут только на узком экране (значок, подсказка, шеврон). */
.mrd-side-ic, .mrd-side-tip, .mrd-side-chev { display: none; }
/* 📱 Узко (CLIE-2020·4) — текст на весь экран, «Обсуждения» шторкой снизу ПОВЕРХ текста.
   Было: колонки вставали друг под другом, и до обсуждений листали всё сообщение. Опущенная
   шторка — одна полоска-кнопка «Обсуждения · 2 · открыто 1» (`data-mrd-sidetog`); поднятая
   (`.mrd-sheet-open` на `.mrd-dim`, `mrdSheet()` в app.js) — до 86 % высоты, текст над ней
   приглушён и по тапу опускает шторку. */
@media (max-width: 860px) {
  .mrd-cols { display: flex; flex-direction: column; position: relative; overflow: hidden; }
  .mrd-main { flex: 1; min-height: 0; overflow-y: auto; padding: 20px 18px calc(84px + env(safe-area-inset-bottom, 0px)); }
  .mrd-hint { display: none; }
  .mrd-cols::before { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: var(--scrim); opacity: 0; transition: opacity .2s ease; }
  .mrd-sheet-open .mrd-cols::before { opacity: .7; }   /* токен темы: в тёмной 0.28 чёрного не читалось */
  .mrd-side {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; max-height: 86%;
    border: 0; border-radius: 18px 18px 0 0; background: var(--panel);
    box-shadow: 0 -12px 32px -16px rgba(0,0,0,.4), 0 0 0 1px var(--line);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .mrd-side-h {
    position: relative; flex: none; align-items: center; flex-wrap: nowrap; gap: 8px; min-height: 58px; box-sizing: border-box;
    padding: 20px 14px 12px 16px; cursor: pointer; -webkit-tap-highlight-color: transparent; user-select: none; -webkit-user-select: none;
  }
  /* Ручка-«язычок»: шторку видно как шторку, а не как ещё одну панель. */
  .mrd-side-h::before { content: ""; position: absolute; top: 7px; left: 50%; width: 36px; height: 4px; margin-left: -18px; border-radius: 2px; background: color-mix(in srgb, var(--text) 22%, transparent); }
  .mrd-side-h:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent); outline-offset: -2px; border-radius: 18px 18px 0 0; }
  .mrd-side-h b { flex: none; font-size: 15px; }
  .mrd-side-ic { display: inline-flex; flex: none; color: var(--primary-2, var(--primary)); }
  .mrd-side-ic svg.ic { width: 18px; height: 18px; }
  .mrd-count, .mrd-side-tip { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; color: var(--text-dim); }
  .mrd-side-chev { display: inline-flex; flex: none; margin-left: auto; color: var(--text-dim); transition: transform .2s ease; }
  .mrd-side-chev svg.ic { width: 20px; height: 20px; }
  .mrd-sheet-open .mrd-side-chev { transform: rotate(180deg); }
  .mrd-dim:not(.mrd-sheet-open) .mrd-list, .mrd-dim:not(.mrd-sheet-open) .mrd-whole { display: none; }
  .mrd-sheet-open .mrd-list { animation: mrdSheetIn .2s ease-out; }
  .mrd-list { padding: 2px 12px 12px; }
  .mrd-whole { margin: 4px 12px 12px; }
  .mrd-empty { padding: 22px 12px 14px; }
}
@keyframes mrdSheetIn { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (max-width: 720px) {
  .mrd-box { width: 100%; height: 100dvh; }
  .mrd-head { gap: 6px; padding: 8px 6px 8px 16px; }
  .mrd-who { flex-direction: column; gap: 1px; min-width: 0; }
  .mrd-who b { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* «Показать оформленным» — значок (слово в aria-label), «Сохранить оформленным» — «Сохранить». */
  .mrd-tools { flex-wrap: nowrap; gap: 6px; }
  .mrd-rich { width: 36px; height: 36px; padding: 0; justify-content: center; border-radius: 10px; }
  .mrd-rich span, .mrd-saverich .mrd-lx { display: none; }
  .mrd-saverich { height: 36px; padding: 0 12px; white-space: nowrap; }
  .mrd-rich svg.ic { width: 17px; height: 17px; }
}

/* ══ 💬 CLIE-2020·2 · НЕПРОЧИТАННЫЕ КОММЕНТАРИИ К ФРАГМЕНТАМ ═══════════════════════════════
   Владелец: «когда кто-то пишет коммент этого никак не видно в списке… И внутри самого чата
   сделать блок где видно что есть непрочитанные комментарии». Строка списка — пилюля 💬N рядом
   с бейджем сообщений (акцент: подложка 12 % + кольцо 22 %, чернила --primary-2); блок под
   шапкой чата — ряд как у «Закреплённого»; список обсуждений — общая рама .cc-sheet. */
.conv-mark.conv-cmt {
  display: inline-flex; align-items: center; gap: 3px; flex: none;
  height: 18px; box-sizing: border-box; padding: 0 6px 0 5px; border-radius: 9px;
  color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
  font-size: 11.5px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
}
.conv-mark.conv-cmt svg.ic, .conv-mark.conv-cmt svg { width: 12px; height: 12px; flex: none; }

.mthr-bar {
  display: flex; align-items: center; gap: 8px; flex: none; min-height: 44px;
  padding: 5px 6px 5px 12px; cursor: pointer;
  background: color-mix(in srgb, var(--primary) 7%, var(--panel));
  border-bottom: 1px solid var(--line);
}
.mthr-bar.hidden { display: none; }
.mthr-bar:hover { background: color-mix(in srgb, var(--primary) 11%, var(--panel)); }
.mthr-bar-ic {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 28px; height: 28px; border-radius: 50%;
  color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}
.mthr-bar-ic svg.ic { width: 15px; height: 15px; }
.mthr-bar-body { flex: 1; min-width: 0; }
.mthr-bar-t { display: flex; align-items: baseline; gap: 6px; min-width: 0; font-size: 12px; line-height: 1.25; font-weight: 600; color: var(--primary-2, var(--primary)); }
.mthr-bar-t > span:first-child { flex: none; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mthr-bar-q { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; color: var(--muted); }
.mthr-bar-x { font-size: 13px; line-height: 1.3; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mthr-bar-x b { font-weight: 600; }
.mthr-bar-btn {
  appearance: none; flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0; border: 0; border-radius: 9px; cursor: pointer;
  background: transparent; color: var(--muted);
}
.mthr-bar-btn:hover { background: var(--panel-2); color: var(--text); }
.mthr-bar-btn svg.ic { width: 18px; height: 18px; }

.mthr-sheet-list { overflow-y: auto; overscroll-behavior: contain; padding: 6px; display: flex; flex-direction: column; gap: 2px; }
.mthr-si {
  appearance: none; font: inherit; text-align: left; width: 100%; cursor: pointer;
  display: flex; flex-direction: column; align-items: stretch; gap: 3px;
  padding: 9px 10px; border: 0; border-radius: 10px; background: transparent; color: var(--text);
}
.mthr-si:hover, .mthr-si:focus-visible { background: var(--panel-2); }
.mthr-si-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.mthr-si-q { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; font-weight: 600; color: var(--primary-2, var(--primary)); }
.mthr-si-n {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; box-sizing: border-box; padding: 0 5px; border-radius: 9px;
  font-size: 11px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums;
  color: #fff; background: var(--acc-fill, var(--primary));
}
.mthr-si-x { font-size: 13px; line-height: 1.35; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
.mthr-si-x b { font-weight: 600; }
.mthr-si-at { font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.mthr-sheet-more { padding: 8px 10px 4px; font-size: 12px; color: var(--muted); }
.mthr-sheet-empty { display: flex; align-items: center; gap: 8px; padding: 18px 12px; font-size: 13px; color: var(--muted); }
.mthr-sheet-empty svg.ic { width: 18px; height: 18px; color: var(--primary-2, var(--primary)); }
.mthr-sheet-foot { display: flex; justify-content: flex-end; padding: 8px 10px; border-top: 1px solid var(--line); }
.mthr-sheet-all {
  appearance: none; font: inherit; display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  height: 34px; padding: 0 12px; border-radius: 9px; border: 0;
  font-size: 13px; font-weight: 600; color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 12%, transparent);
}
.mthr-sheet-all:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); }
.mthr-sheet-all.hidden { display: none; }
.mthr-sheet-all svg.ic { width: 16px; height: 16px; }

/* Чип 💬N под пузырём: в обсуждении есть новое — чернила акцента и точка. */
.msg-thr-chip { position: relative; }
.msg-thr-chip.fresh { color: var(--primary-2, var(--primary)); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.msg-thr-dot {
  position: absolute; top: -3px; right: -3px; width: 9px; height: 9px; border-radius: 50%;
  background: var(--acc-fill, var(--primary)); box-shadow: 0 0 0 2px var(--bg);
}
@media (max-width: 720px) {
  .mthr-bar { padding-left: 10px; }
  .cc-sheet.mthr-sheet { width: 100%; max-height: 86vh; }
}
/* 📱 Телефон (CLIE-2020·4): обрезанная цитата во второй половине первой строки («…до п…»)
   не читалась — строка 1 говорит только «сколько нового», о чём и кто — строка 2. Цитата
   целиком — в списке («≡») и в самой читалке. */
@media (max-width: 480px) {
  .mthr-bar-q { display: none; }
}

/* ═══ 🌍 ЯЗЫКИ СМЕТЫ (CLIE-943 · Ч6) ══════════════════════════════════════════════════
   Панель «на каких языках работает смета». Своих чисел и своих размеров здесь нет: строка
   повторяет геометрию карточки сметы (.dc-item), кнопки — .dc-a, чипы — .dc-chip, поэтому
   светлая и тёмная темы приезжают вместе с базой. Шкала ОПРЕДЕЛЁННАЯ (есть настоящие N и M),
   акцент — цвет заливки и СЛОВО в чипе, а не полоса слева (правило CLIE-483). */
.el-src { font-size: 12.5px; color: var(--text-dim); line-height: 1.45; margin: 0 0 10px; }
/* ── 📣 МАСТЕР СОЗДАНИЯ СМЕТЫ: «какие блоки нужны и чем заполнить» (CLIE-984·Ч10) ──
   Ни одной левой рейки и ни одного своего цвета: подложка, хэйрлайн-кольцо и токены
   темы (CLIE-483 · CLIE-505). Ширину окна тянет общий механизм (data-ccwin). */
.enw-box { width: min(720px, 94vw); }
.enw-h { font-size: 11.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--text-dim); margin: 14px 0 8px; }
.enw-h:first-child { margin-top: 0; }
.enw-sets { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px; }
.enw-set { display: flex; flex-direction: column; gap: 3px; text-align: left; padding: 11px 12px; border-radius: 12px; background: var(--panel-2); border: 0; box-shadow: inset 0 0 0 1px var(--line); cursor: pointer; font: inherit; color: inherit; transition: box-shadow .14s, background .14s; }
.enw-set:hover { box-shadow: inset 0 0 0 1px var(--primary); }
.enw-set.on { background: color-mix(in srgb, var(--primary) 10%, transparent); box-shadow: inset 0 0 0 1.5px var(--primary); }
.enw-set b { font-size: 13.5px; font-weight: 620; color: var(--text); }
.enw-set span { font-size: 12px; color: var(--text-dim); line-height: 1.4; }
.enw-set i { font-style: normal; font-size: 11px; color: var(--text-dim); opacity: .8; }
/* ── 🧾 ОДНА ДВЕРЬ «СФОРМИРОВАТЬ КП»: простое КП или сайт-КП (CLIE-943·Ч11) ──
   Карточка выбора — ТОТ ЖЕ `.enw-set`, что у мастера блоков: своих цветов и своей
   геометрии не заводим (CLIE-505). Погашенный вариант НЕ исчезает — он объясняет
   причину (ЗВОН-604·3), поэтому подпись остаётся читаемой в обеих темах. */
.kpk-box { width: min(560px, 94vw); }
.kpk-sets { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.kpk-set { gap: 5px; padding: 14px 14px 13px; }
.kpk-ic { display: inline-flex; width: 30px; height: 30px; align-items: center; justify-content: center; margin: 0 0 4px; border-radius: 9px; background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary-2); }
.kpk-ic .ic { width: 17px; height: 17px; }
.kpk-set.off { cursor: not-allowed; }
.kpk-set.off:hover { box-shadow: inset 0 0 0 1px var(--line); }
.kpk-set.off .kpk-ic { background: color-mix(in srgb, var(--text-dim) 14%, transparent); color: var(--text-dim); }
/* Подпись-подсказка внутри блока настроек компании: куда едет то, что человек сейчас задал. */
.cs-note { grid-column: 1 / -1; margin: 8px 0 0; font-size: 11.5px; line-height: 1.45; color: var(--text-dim); }
/* ══ 📄 КОНСТРУКТОР КП-PDF (CLIE-943·Ч12) ═══════════════════════════════════════════════
   Рама — канон `.modal-box` (слой, тянущаяся ширина `data-ccwin`, самопрокрутка достаются
   даром). Размеры контролов — токены ряда `--ctl-*`, свою геометрию не заводим (CLIE-505).
   🔴 Акцент — иконка + слово + точка, НИКАКИХ левых полос-реек на всю высоту (CLIE-483). */
.kpd-box { width: min(1180px, 96vw); }
.kpd-body { padding: 0 !important; display: flex; flex-direction: column; min-height: 0; }
.kpd-top { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 14px; border-bottom: 1px solid var(--line); }
.kpd-acts { display: flex; align-items: center; gap: 6px; margin-left: auto; flex-wrap: wrap; }
.kpd-acts .ghost, .kpd-open { display: inline-flex; align-items: center; gap: 6px; height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs); padding: 0 10px; }
.kpd-open { text-decoration: none; color: var(--text); box-shadow: inset 0 0 0 1px var(--line); }
.kpd-open:hover { background: var(--panel-2); }
.kpd-cols { display: grid; grid-template-columns: minmax(320px, 42%) 1fr; gap: 0; min-height: 0; flex: 1; }
.kpd-left { padding: 12px 14px 16px; overflow: auto; min-height: 0; }
.kpd-right { display: flex; flex-direction: column; min-height: 0; border-left: 1px solid var(--line); background: var(--panel-2); }
.kpd-prev-h { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; font-size: 12px; color: var(--text-dim); border-bottom: 1px solid var(--line); }
.kpd-prev { flex: 1; width: 100%; border: 0; background: var(--panel-2); min-height: 420px; }
/* Телефон и узкое окно: сегмент «Блоки | Превью» вместо двух колонок. */
.kpd-seg { display: none; }
.kpd-brand { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-dim); margin: 0 0 10px; flex-wrap: wrap; }
.kpd-dot { width: 12px; height: 12px; border-radius: 50%; box-shadow: inset 0 0 0 1px rgba(0,0,0,.14); flex: none; }
.kpd-warn { display: flex; align-items: flex-start; gap: 7px; font-size: 12px; margin: -4px 0 10px; padding: 8px 10px; border-radius: 10px;
  background: color-mix(in srgb, var(--warn, #d98324) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn, #d98324) 24%, transparent); }
.kpd-warn .ic { width: 15px; height: 15px; flex: none; margin-top: 1px; }
.kpd-list { display: flex; flex-direction: column; gap: 8px; }
.kpd-b { border-radius: 12px; background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); overflow: hidden; transition: box-shadow .14s ease, opacity .14s ease; }
.kpd-b:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 26%, var(--line)); }
.kpd-b.off { opacity: .58; }
.kpd-bh { display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 10px; }
.kpd-bh b { font-size: 13px; font-weight: 600; }
.kpd-bh i { font-style: normal; font-size: 11.5px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.kpd-ba { display: flex; align-items: center; gap: 2px; margin-left: auto; flex: none; opacity: 0; transition: opacity .12s ease; }
.kpd-b:hover .kpd-ba, .kpd-b:focus-within .kpd-ba { opacity: 1; }
.kpd-ba .icon-btn { width: 26px; height: 26px; }
.kpd-ba .ic { width: 14px; height: 14px; }
.kpd-eye { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: 0; border-radius: 8px; background: transparent; color: var(--text-dim); cursor: pointer; flex: none; }
.kpd-eye:hover { background: var(--panel-2); color: var(--text); }
.kpd-eye .ic { width: 15px; height: 15px; }
.kpd-bf { display: flex; flex-direction: column; gap: 6px; padding: 0 10px 10px; }
.kpd-auto { font-size: 11.5px; color: var(--text-dim); padding-top: 0; }
.kpd-f { width: 100%; box-sizing: border-box; border-radius: 9px; border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  font: inherit; font-size: 12.5px; padding: 7px 9px; resize: vertical; }
.kpd-f:focus { outline: none; border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); background: var(--panel); }
.kpd-f-t { font-weight: 600; }
.kpd-add { display: inline-flex; align-items: center; gap: 6px; margin: 10px 0 0; height: var(--ctl-h); border-radius: var(--ctl-r); padding: 0 12px;
  border: 1px dashed var(--line); background: transparent; color: var(--text-dim); font-size: var(--ctl-fs); cursor: pointer; }
.kpd-add:hover { color: var(--text); border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); background: var(--panel-2); }
.kpd-add .ic { width: 15px; height: 15px; }
.kpd-pick { margin: 10px 0 0; }
.kpd-pop { position: fixed; z-index: 1200; width: 300px; max-width: calc(100vw - 16px); }
@media (max-width: 900px) {
  .kpd-seg { display: inline-flex; }
  .kpd-cols { grid-template-columns: 1fr; }
  .kpd-cols.kpd-v-b .kpd-right { display: none; }
  .kpd-cols.kpd-v-p .kpd-left { display: none; }
  .kpd-right { border-left: 0; border-top: 1px solid var(--line); }
}
.enw-grp { margin: 0 0 10px; }
.enw-grp h5 { margin: 0 0 6px; font-size: 12px; font-weight: 600; color: var(--text-dim); }
.enw-types { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 6px; }
.enw-t { display: flex; align-items: flex-start; gap: 8px; padding: 8px 10px; border-radius: 10px; background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); cursor: pointer; }
.enw-t.on { background: color-mix(in srgb, var(--primary) 8%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent); }
.enw-t input { margin: 2px 0 0; flex: none; }
.enw-tt { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.enw-tt b { font-size: 13px; font-weight: 600; color: var(--text); }
.enw-tt i { font-style: normal; font-size: 11.5px; color: var(--text-dim); line-height: 1.35; }
.enw-fill { border-radius: 12px; background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); padding: 10px 12px; margin: 0 0 8px; }
.enw-fill h5 { margin: 0 0 7px; font-size: 12.5px; font-weight: 620; color: var(--text); }
/* Поле-значение и его подпись — двумя строками (правило «поле + кнопка», CLIE-425). */
.enw-f { display: flex; flex-direction: column; gap: 4px; margin: 0 0 8px; }
.enw-f > span { font-size: 12px; color: var(--text-dim); }
.enw-f input, .enw-f textarea { width: 100%; box-sizing: border-box; font: inherit; font-size: 13px; padding: 7px 9px; border-radius: 9px; border: 1px solid var(--line); background: var(--panel); color: var(--text); resize: vertical; }
.enw-f input:focus, .enw-f textarea:focus { outline: none; border-color: var(--primary); }
/* ── 📎 РАЗБОР ДОКУМЕНТА В МАСТЕРЕ (CLIE-943·Ч12) ──────────────────────────────
   Три состояния одного блока и ни одного немого: «приложите» → ЧЕСТНАЯ шкала с
   именем файла и процентом → разбор словами и числами. Пустых состояний у долгой
   работы не бывает (правило №8). Своих цветов нет — токены темы. */
.enw-imp { display: flex; flex-direction: column; gap: 10px; padding: 13px 14px; border-radius: 12px; background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.enw-imp-say { font-size: 12.5px; line-height: 1.45; color: var(--text-dim); }
.enw-imp-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.enw-imp .enw-f { margin: 0; }
.enw-imp-bar { height: 4px; border-radius: 999px; background: var(--hover); overflow: hidden; }
.enw-imp-bar > i { display: block; height: 100%; width: 40%; border-radius: inherit; background: var(--primary); animation: enw-imp-run 1.1s ease-in-out infinite; }
@keyframes enw-imp-run { 0% { transform: translateX(-100%); } 100% { transform: translateX(320%); } }
.enw-imp-ok { background: color-mix(in srgb, var(--primary) 7%, var(--panel-2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 26%, transparent); }
.enw-imp-h { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.enw-imp-h .ic { width: 15px; height: 15px; color: var(--primary-2); align-self: center; }
.enw-imp-h b { font-size: 13.5px; font-weight: 640; color: var(--text); }
.enw-imp-h span { font-size: 12px; color: var(--text-dim); overflow-wrap: anywhere; }
.enw-imp-nums { display: flex; flex-wrap: wrap; gap: 6px 16px; }
.enw-imp-nums span { font-size: 12px; color: var(--text-dim); }
.enw-imp-nums b { font-size: 14px; font-weight: 700; color: var(--text); margin-right: 4px; }
.enw-imp-t { font-size: 11px; font-weight: 650; letter-spacing: .05em; text-transform: uppercase; color: var(--text-dim); margin-top: 2px; }
.enw-imp-list, .enw-imp-warn { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.enw-imp-list li { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12.5px; }
.enw-imp-list b { font-weight: 600; color: var(--text); overflow-wrap: anywhere; }
.enw-imp-list span { color: var(--text-dim); white-space: nowrap; }
.enw-imp-warn li { font-size: 12px; line-height: 1.45; color: var(--text-dim); padding-left: 14px; position: relative; }
.enw-imp-warn li::before { content: "•"; position: absolute; left: 2px; color: #b25e00; }
html[data-theme="dark"] .enw-imp-warn li::before, :root:not([data-theme]) .enw-imp-warn li::before { color: #ffb340; }
.enw-go { margin-top: 14px; }
@media (max-width: 560px) { .enw-types { grid-template-columns: 1fr; } }

.el-row { border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px; background: var(--panel-2); display: flex; flex-direction: column; gap: 8px; margin: 0 0 9px; }
.el-h { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; }
.el-h b { font-size: 13.5px; font-weight: 620; color: var(--text); }
.el-code { font-size: 11px; font-weight: 700; letter-spacing: .05em; color: var(--text-dim); border: 1px solid var(--line); border-radius: 7px; padding: 3px 6px; background: var(--panel); }
.el-bar { height: 6px; border-radius: 999px; background: var(--hover); overflow: hidden; }
.el-bar > i { display: block; height: 100%; border-radius: inherit; background: var(--primary); transition: width .18s ease; }
.el-say { font-size: 12px; color: var(--text-dim); }
.el-err { font-size: 12.5px; color: #c9251b; background: color-mix(in srgb, #ff3b30 10%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #ff3b30 22%, transparent); border-radius: 10px; padding: 8px 11px; margin: 0 0 9px; }
html[data-theme="dark"] .el-err, :root:not([data-theme]) .el-err { color: #ff6961; }
/* Правка машинного черновика — инлайн, без карандаша и без «Сохранить»: ушёл фокусом —
   сохранилось (правило продукта «нажал → изменил»). Правленная человеком строка помечена
   ТОЧКОЙ у подписи — не полосой слева (CLIE-483). Своего скролла у списка нет: он растёт, а
   скроллит панель (CLIE-620 — вложенный кап прячет остаток и заставляет искать второй бегунок). */
.el-words { display: flex; flex-direction: column; gap: 6px; margin: 2px 0 2px; }
.el-w { display: grid; grid-template-columns: minmax(120px, 1fr) minmax(140px, 1.2fr); gap: 8px; align-items: center; }
.el-w-src { font-size: 12px; color: var(--text-dim); line-height: 1.35; display: inline-flex; align-items: baseline; gap: 6px; overflow-wrap: anywhere; }
.el-w-src i { font-style: normal; font-size: 10px; font-weight: 650; letter-spacing: .03em; text-transform: uppercase; color: var(--text-dim); opacity: .75; border: 1px solid var(--line); border-radius: 6px; padding: 1px 4px; white-space: nowrap; }
.el-w-in { width: 100%; box-sizing: border-box; font-size: 12.5px; padding: 6px 9px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel); color: var(--text); outline: none; transition: border-color .12s, box-shadow .12s; }
.el-w-in:focus { border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); }
.el-w.ed .el-w-src::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--primary); flex: 0 0 auto; align-self: center; }
.el-add { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.el-add > .btn { align-self: flex-start; }
.el-pick { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--panel); }
.el-pick[hidden] { display: none; }

.dc-due { font-size: 11.5px; color: var(--text-dim); }
.dc-acts { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.dc-a { font-size: 12px; font-weight: 550; padding: 5px 10px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--text); cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; transition: background .12s ease, border-color .12s ease, transform .06s ease; }
.dc-a:hover { background: var(--hover); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.dc-a:active { transform: scale(.96); }
.dc-a.ok { color: #248a3d; border-color: color-mix(in srgb, #34c759 45%, var(--line)); }
.dc-a.bad { color: #c9251b; border-color: color-mix(in srgb, #ff3b30 40%, var(--line)); }

/* 🏠 CLIE-1397 · КАБИНЕТ ЗАКАЗЧИКА в карточке сделки. Токены — общие (var(--line)/--panel/
   --text): у блока нет своей палитры, поэтому он одинаково жив в светлой и тёмной теме.
   🔴 ПОЛЕ И КНОПКИ — НА ДВУХ СТРОКАХ, а не в один ряд: ссылка длинная, в ряду она отняла бы
   у кнопок всю ширину (то же правило, что у витрины проекта и у листа доступа). */
.dpor-head { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.dpor-url { width: 100%; margin-bottom: 8px; padding: 7px 10px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--panel-2, var(--panel)); color: var(--text);
  font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; text-overflow: ellipsis; }
.dpor-url:focus { outline: none; border-color: var(--primary); }

/* Предупреждение «эту беседу клиенту НЕ показываем» — акцент по канону `accent`:
   значок + СЛОВО (читается и в ч/б), подложка color-mix 12%, кольцо 22%, БЕЗ левой рейки.
   Токены обеих тем берутся из базы, своих цветов не заводим. */
.dpor-warn { display: flex; gap: 6px; margin-bottom: 8px; padding: 7px 10px; border-radius: 9px;
  font-size: 12.5px; line-height: 1.45; color: var(--text);
  background: color-mix(in srgb, var(--warn, #f5a623) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn, #f5a623) 22%, transparent); }

.dc-toggle { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-dim); cursor: pointer; user-select: none; }
.dc-toggle input { accent-color: var(--primary); width: 15px; height: 15px; }
.dc-subf { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 6px; }
.dc-subf input, .dc-subf select { padding: 7px 9px; font-size: 12.5px; border: 1px solid var(--line); border-radius: 8px; background-color: var(--panel-2); color: var(--text); } .dc-subf select { padding-right: 34px; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.dc-subf .dc-sf-name { flex: 1 1 130px; } .dc-subf .dc-sf-amt { width: 120px; }
.dli-add-toggle { align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; }
/* значок «плюс» вместо текстового «+» (deal-money-positions-hierarchy-1): 14 px, как у соседней «Сформировать КП» */
.dli-add-toggle > .ic { width: 14px; height: 14px; }
.dli-add-wrap:empty { display: none; }
.dli-add { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 8px; border: 1px dashed var(--line); border-radius: 10px; }
.dli-add input { font-size: 12.5px; padding: 7px 9px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--text); outline: none; transition: border-color .12s, box-shadow .12s; }
.dli-add input:focus { border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); }
.dli-add-name { flex: 1 1 140px; min-width: 120px; }
.dli-add-price, .dli-add-qty { width: 74px; }
.dli-cat:empty { display: none; }
.dli-cat { margin-top: 6px; }
.dli-cat-load, .dli-cat-empty { font-size: 12px; color: var(--text-dim); padding: 4px 2px; }
.dli-cat-list { display: flex; flex-direction: column; gap: 3px; max-height: 220px; overflow-y: auto; border: 1px solid var(--line); border-radius: 10px; padding: 4px; background: var(--panel); }
.dli-cat-item { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; padding: 7px 9px; border: none; border-radius: 8px; background: transparent; color: var(--text); font: inherit; font-size: 12.5px; cursor: pointer; transition: background .12s; }
.dli-cat-item:hover { background: var(--hover, rgba(127, 127, 127, .08)); }
.dli-cat-nm { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dli-cat-sku { flex: none; font-size: 11px; color: var(--muted); }
.dli-cat-pr { flex: none; font-weight: 600; color: var(--text); }

/* ── Вид «Продукты» модуля «Продажи»: каталог + прайс-листы ── */
.prod-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; overflow-y: auto; }
#salesProdPane { display: flex; flex-direction: column; gap: 18px; padding: 16px; max-width: 900px; width: 100%; margin: 0 auto; }
/* «Склад»: панель сама и есть .prod-wrap — полей и зазора #salesProdPane у неё не было, и секции
   стояли вплотную к краям рамы (кадр crm_stock: кромки секций x 104 и 1431, а заголовок «CRM» —
   чернила с x 122, сегмент вида — с x 124) и друг к другу (кромки y 249–250 подряд, зазор 0).
   Поле 16px ставит секции на ось заголовка. Верх не трогаем: 14px над секцией уже даёт рама. */
#salesStockPane { gap: 16px; padding: 0 16px 16px; }
.prod-sec { border: 1px solid var(--line); border-radius: 14px; background: var(--panel-2); overflow: hidden; }
.prod-sec-h { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 11px 14px; border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent); }
.prod-sec-t { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
.prod-sec-t .ic { width: 15px; height: 15px; opacity: .8; }
/* кнопка шапки секции — по своей ширине: .primary/.cli-btn тянули «＋ Товар» на всю строку (замер 20.10) */
.prod-add { display: inline-flex; align-items: center; gap: 5px; }
.prod-sec-h .prod-add { width: auto; flex: 0 0 auto; margin: 0; }
.prod-add .ic { width: 14px; height: 14px; }
.prod-table { padding: 6px 10px 12px; }
.prod-head, .prod-row { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1.2fr) 56px 92px 66px 54px 30px; align-items: center; gap: 8px; }
.pb-head, .pb-row { grid-template-columns: minmax(0, 1fr) 64px 100px 64px 30px; }
.prod-head { padding: 8px 8px 6px; font-size: 10.5px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
.prod-head .prod-h-price { text-align: right; }
.prod-head .prod-h-tax, .prod-head .prod-h-act { text-align: center; }
.prod-row { padding: 5px 8px; border-radius: 10px; transition: background .12s; }
.prod-row + .prod-row { margin-top: 1px; }
.prod-row:hover { background: color-mix(in srgb, var(--hover) 55%, transparent); }
.prod-row:hover .prod-del { opacity: .5; }
.prod-row.off { opacity: .55; }
.prod-cell { font-size: 13px; color: var(--text); outline: none; }
.prod-cell[contenteditable] { padding: 6px 8px; border-radius: 7px; border: 1px solid transparent; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: border-color .12s, background .12s; }
.prod-cell[contenteditable]:hover { background: var(--panel); }
.prod-cell[contenteditable]:focus { background: var(--panel); border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); white-space: normal; }
.prod-cell[contenteditable]:empty::before { content: attr(data-ph); color: var(--text-dim); }
input.prod-cell { width: 100%; padding: 6px 8px; border-radius: 7px; border: 1px solid transparent; background: transparent; color: var(--text); font-size: 12.5px; outline: none; text-align: right; transition: border-color .12s, background .12s; }
input.prod-c-tax { text-align: center; }
input.prod-cell:hover { background: var(--panel); }
input.prod-cell:focus { background: var(--panel); border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); }
.prod-c-act, .pb-c-def, .pb-c-act { justify-self: center; }
.pb-c-def { justify-self: start; gap: 6px; }
.pb-tog-lbl { font-size: 11.5px; color: var(--text-dim); font-weight: 600; }
.pb-c-cur { font-size: 12.5px; color: var(--muted); font-weight: 600; }
.prod-del { justify-self: center; opacity: 0; display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; border: none; background: transparent; color: var(--text-dim); cursor: pointer; border-radius: 7px; transition: opacity .12s, color .12s, background .12s; }
.prod-del .ic { width: 15px; height: 15px; }
.prod-del:hover { color: var(--danger); opacity: 1 !important; background: var(--danger-soft, color-mix(in srgb, var(--danger) 12%, transparent)); }
.pb-row:hover .prod-del { opacity: .5; }
@media (max-width: 620px) {
  .prod-head { display: none; }
  .prod-row, .pb-row { grid-template-columns: 1fr 1fr; grid-auto-rows: minmax(0, auto); row-gap: 4px; }
}

/* ═══════════ 📦 СКЛАД И ОСТАТКИ (CLIE-1796) ═══════════
   Остаток = СУММА ДВИЖЕНИЙ, поэтому экран — это таблица каталога с другими столбиками, а не
   новая вёрстка: строки и ячейки берут готовые `.prod-row`/`.prod-cell`/`.prod-head`, здесь
   лежит ТОЛЬКО то, чего у каталога нет (раскладка столбиков, знак прихода/расхода, форма
   движения). Цвета — токенами темы (`--danger`/`--warn`/`--ok`/`--text-dim`), чтобы обе темы
   читались без отдельного набора чисел. */
.stk-head, .stk-row { grid-template-columns: minmax(0, 2fr) minmax(0, 1.1fr) 92px 86px 86px 72px 96px; }
.stk-head-mv, .stk-row.stk-mv { grid-template-columns: 76px 104px minmax(0, 1.6fr) minmax(0, 1.1fr) 86px 86px minmax(0, 1.2fr); }
.stk-c-name, .stk-c-loc, .stk-c-who, .stk-c-when { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stk-c-num { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.stk-c-when { font-size: 12px; color: var(--muted); }
.stk-c-loc { color: var(--muted); }
/* Артикул и причина — вторая строка внутри ячейки: ряд остаётся одной строкой таблицы. */
.stk-sku, .stk-note { display: block; font-size: 11px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Свободно ≤ 0 — продавать нечего: цвет отказа, а не просто «серое число». */
.stk-free.bad { color: var(--danger); }
/* 🔴 CLIE-483: акцент — ПОДЛОЖКА и КОЛЬЦО, не левая рейка; «кончается» сверх этого
   названо СЛОВОМ в самой ячейке (`.stk-low-say`), чтобы цвет не был единственным носителем. */
.stk-row.stk-low { background: color-mix(in srgb, var(--warn) 9%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 24%, transparent); }
.stk-row.stk-low:hover { background: color-mix(in srgb, var(--warn) 14%, transparent); }
.stk-low-say { display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: 6px; font-size: 10.5px; font-weight: 700; color: var(--warn); background: color-mix(in srgb, var(--warn) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 30%, transparent); }
/* Вид движения: приход прибавляет, расход вычитает — знак виден цветом, а не только минусом. */
.stk-k { display: inline-flex; align-items: center; padding: 2px 7px; border-radius: 7px; font-size: 11.5px; font-weight: 650; white-space: nowrap; }
.stk-k.in { color: var(--ok); background: color-mix(in srgb, var(--ok) 13%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 28%, transparent); }
.stk-k.out { color: var(--warn); background: color-mix(in srgb, var(--warn) 13%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 28%, transparent); }
.stk-in { color: var(--ok); }
.stk-out { color: var(--warn); }
input.stk-c-min { max-width: 72px; }
.stk-mv-btn { justify-self: end; white-space: nowrap; font-size: 12px; }
.stk-q { width: 190px; max-width: 46vw; padding: 6px 10px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--text); font-size: 12.5px; outline: none; }
.stk-q:focus { border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); }
.stk-locpick { padding: 6px 9px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--text); font-size: 12.5px; outline: none; }
.stk-locpick:focus { border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); }
.stk-sec-form .prod-table { padding-top: 10px; }
/* Форма движения — ЕДИНСТВЕННЫЙ путь правки остатка; поля ложатся в ряд и переносятся сами. */
.stk-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.stk-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.stk-f > span { font-size: 10.5px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
.stk-f select, .stk-f input { padding: 7px 9px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--text); font-size: 13px; outline: none; max-width: 100%; }
.stk-f select:focus, .stk-f input:focus { border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); }
.stk-f-wide { flex: 1 1 210px; }
.stk-f-qty input { width: 110px; text-align: right; font-variant-numeric: tabular-nums; }
.stk-hint { flex: 1 1 100%; font-size: 12px; color: var(--text-dim); line-height: 1.5; }
/* Складов нет — говорим это словами и даём вход туда, где их заводят (правило выхода). */
.stk-form-off { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 12px 14px; border: 1px dashed var(--line-strong, var(--line)); border-radius: 12px; font-size: 13px; color: var(--text-dim); line-height: 1.5; }
.stk-more { padding: 10px 2px 2px; }
/* 📦 Подпись «на складе N, свободно M» — ОДНА сборка на строку сделки, строку КП и каталог. */
.cc-stock-row { padding: 0 2px 5px; margin-top: -2px; }
.cc-stock { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.cc-stock .ic { width: 13px; height: 13px; opacity: .75; }
.cc-stock.warn { color: var(--warn); }
.cc-stock.bad { color: var(--danger); }
@media (max-width: 760px) {
  .stk-head, .stk-head-mv { display: none; }
  .stk-row, .stk-row.stk-mv { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); grid-auto-rows: minmax(0, auto); row-gap: 4px; }
  .stk-mv-btn { justify-self: start; }
  .stk-q { width: 100%; max-width: none; }
}

/* ── CRM «Неразобранное» (инбокс входящих чат-сделок, Kommo, 0164) ── */
.tw-seg-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 17px; height: 17px; padding: 0 5px; margin-left: 3px; border-radius: 9px; background: var(--acc-fill); color: #fff; font-size: 11px; font-weight: 700; line-height: 1; }
/* 🔴 АТРИБУТ СОСТОЯНИЯ СИЛЬНЕЕ РАСКЛАДКИ. У бейджа свой `display: inline-flex`, и он бьёт
   `[hidden] { display: none }` из сброса: «спрятанный» нуль оставался на экране. Поймано
   дважды подряд на одном и том же контроле (вкладки переписки карточки CRM, кадры прода
   15–16.09.2026) — поэтому чиним у САМОГО компонента, а не у очередного его потребителя. */
.tw-seg-badge[hidden] { display: none !important; }
/* цифра на белой плашке — цветом ЗАЛИВКИ, а не чернил: в тёмном «Штиле» --primary светлый (по белому ~3:1) */
.tw-seg button.active .tw-seg-badge { background: rgba(255, 255, 255, .92); color: var(--acc-fill, var(--primary)); }
/* CLIE-505: тот же счётчик на КАНОНИЧЕСКОМ сегменте — иначе после перевода экрана
   на .cc-seg бейдж молча остаётся синим на подсвеченном thumb. */
.cc-seg > *.on .tw-seg-badge, .cc-seg > *.active .tw-seg-badge { background: rgba(255, 255, 255, .92); color: var(--acc-fill, var(--primary)); }
.deal-inbox { display: flex; flex-direction: column; gap: 8px; padding: 16px; max-width: 760px; }
.deal-inbox-hint { font-size: 12.5px; color: var(--text-dim); line-height: 1.5; margin-bottom: 4px; }
.deal-ibx-row { display: flex; align-items: center; gap: 12px; padding: 11px 13px; border: 1px solid var(--line); border-radius: 14px; background: var(--panel); cursor: pointer; transition: border-color .13s, box-shadow .13s; }
.deal-ibx-row:hover { border-color: var(--line-strong, var(--primary)); box-shadow: 0 2px 12px rgba(0, 0, 0, .06); }
.deal-ibx-av { flex: none; width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 14px; color: #fff; background: linear-gradient(135deg, var(--cm-7c8ff5, #7c8ff5), var(--cm-a36bff, #a36bff)); letter-spacing: .01em; }
.deal-ibx-main { flex: 1 1 auto; min-width: 0; }
.deal-ibx-top { display: flex; align-items: baseline; gap: 8px; justify-content: space-between; }
.deal-ibx-title { font-weight: 600; font-size: 14px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-ibx-amt { flex: none; font-weight: 700; font-size: 13.5px; color: var(--text); }
.deal-ibx-sub { display: flex; align-items: center; gap: 10px; margin-top: 3px; font-size: 12px; color: var(--text-dim); }
.deal-ibx-num { color: var(--muted); }
.deal-ibx-src { display: inline-flex; align-items: center; gap: 4px; }
.deal-ibx-src svg { width: 13px; height: 13px; }
.deal-ibx-when { margin-left: auto; }
.deal-ibx-act { flex: none; }
.deal-ibx-qual { white-space: nowrap; }
.deal-ibx-qual svg { width: 15px; height: 15px; }
.deal-ibx-dot { width: 9px; height: 9px; border-radius: 50%; flex: none; display: inline-block; margin-right: 2px; }
@media (max-width: 560px) { .deal-inbox { padding: 12px; } .deal-ibx-qual span { display: none; } .deal-ibx-when { display: none; } }

/* ═══════════════════════ CRM · Контакты и компании (сегмент «Контакты») ═══════════════════════ */
/* Аватар контакта: фото или цветной кружок с инициалами (contactColor/avatarInitials). */
.crm-av { --sz: 34px; width: var(--sz); height: var(--sz); flex: 0 0 var(--sz); border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 12.5px; font-weight: 650; color: #fff; background: var(--cc, var(--cm-6b8afd, #6b8afd)); overflow: hidden; letter-spacing: .2px; box-shadow: inset 0 0 0 1px rgba(255,255,255,.08); }
.crm-av img { width: 100%; height: 100%; object-fit: cover; display: block; }
.crm-av.sm { --sz: 28px; font-size: 11px; }
.crm-av.lg { --sz: 46px; font-size: 16px; }
/* contact-more-dup-avatar-1: кружок .crm-av от двери ccAvatarFace (CLIE-903) — буквы .cc-av-ini и фото .cc-av-img
   лежат position:absolute; inset:0, поэтому кружку нужна своя позиционирующая коробка (как у .inv-av / .v2-grp-ic). */
.crm-av { position: relative; }

/* Список контактов — тулбар */
.crm-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.crm-toolbar { display: flex; align-items: center; gap: 10px; padding: 12px 16px; flex-wrap: wrap; border-bottom: 1px solid var(--line); position: sticky; top: 0; background: var(--panel); z-index: 2; }
/* 🧭🧭 CLIE-1030·R3 · ШАПКА ДОСКИ НЕ УЕЗЖАЕТ ПРИ СКРОЛЛЕ (владелец 12.09.2026, кадр доски CRM:
   «Вёрстка ещё не верная, шапка при скролле не должна уезжать»).
   ПРИЧИНА: тулбар и плашка лежат ВНУТРИ прокручиваемого `.tw-body`, а доска `.tw-board` шире
   его — значит у `.tw-body` есть ГОРИЗОНТАЛЬНАЯ прокрутка, и `position: sticky; top: 0` от неё
   не спасает (sticky липнет по вертикали и ограничен своим контейнером: по горизонтали он
   уезжает вместе с содержимым).
   ЛЕЧЕНИЕ — не «число побольше», а РАЗДЕЛЕНИЕ ролей: тело раздела перестаёт прокручиваться само
   и становится колонкой, а горизонталь забирает САМА доска. Тогда шапка стоит, а ездят столбики.
   Класс вешает тот, кто нарисовал доску (`renderSalesBoard`/`renderLeadsBoard`), а не CSS по
   имени страницы — иначе следующая доска снова уедет. */
.tw-body.tw-body-board { display: flex; flex-direction: column; overflow: hidden; }
.tw-body.tw-body-board > .tw-board { flex: 1 1 auto; min-height: 0; height: auto; overflow: auto; }
.tw-body.tw-body-board > .crm-toolbar,
.tw-body.tw-body-board > .crm-space-note { flex: 0 0 auto; position: static; }
.crm-search { position: relative; display: inline-flex; align-items: center; flex: 1 1 220px; min-width: 180px; }
.crm-search-ic { position: absolute; left: 11px; display: inline-flex; color: var(--muted); pointer-events: none; }
.crm-search-ic svg { width: 15px; height: 15px; }
.crm-search input { width: 100%; box-sizing: border-box; padding: 8px 12px 8px 34px; border-radius: var(--r-full, 999px); border: 1px solid var(--line); background: var(--panel-2); color: var(--text); font: inherit; font-size: 13.5px; outline: none; transition: border-color .13s, box-shadow .13s; }
.crm-search input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.crm-search input::-webkit-search-cancel-button { -webkit-appearance: none; }
.crm-chips { display: inline-flex; gap: 5px; flex-wrap: wrap; }
.crm-chip { appearance: none; border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); font: inherit; font-size: 12.5px; font-weight: 600; padding: 6px 12px; border-radius: var(--r-full, 999px); cursor: pointer; transition: color .13s, border-color .13s, background .13s; }
.crm-chip:hover { color: var(--text); border-color: var(--line-strong, #555); }
.crm-chip.active { color: var(--primary-2, var(--primary)); background: color-mix(in srgb, var(--primary) 12%, transparent); border-color: transparent; }
.crm-add { margin-left: auto; }
/* crm-primary-placement-1 · «＋ Компания» и «＋ Контакт» на компьютере — главная кнопка шапки CRM
   (#salesNew, app.js salesNewSpec), на том же месте и того же размера, что «＋ Сделка» и «＋ Лид».
   Кнопка тела остаётся на телефоне: там шапка — круги 44 и свой ряд инструментов. Пустое
   состояние («＋ Компания клиента», «＋ Контакт») не трогаем. */
@media (min-width: 761px) {
  #salesBody > .crm-wrap > .crm-toolbar > .crm-add { display: none; }
}
@media (max-width: 760px) {
  #salesWorkspace .tw-head > #salesNew:is([data-new="contact"], [data-new="company"]) { display: none; }
}
/* Ряд «поиск · чипы · + Компания/Контакт» (Компании, Контакты) — один размерный класс (канон control-size).
   Поле росло от своих полей 8+8, «Мои» от 6+6, кнопка от .primary.small: замер «Глубины» — поиск 36 px
   (y 140–175), «Мои» и «+ Компания» 31 px (y 143–173), кнопки на 5 px ниже кромок поля. Высоту даёт --ctl-h. */
.crm-wrap > .crm-toolbar:has(> .crm-add) > .crm-search > input,
.crm-wrap > .crm-toolbar:has(> .crm-add) > .crm-chips > .crm-chip,
.crm-wrap > .crm-toolbar > .crm-add,
/* «Задачи CRM»: поиск · два сегмента · «Мои» — тот же ряд без «+»: замер «Глубины» — поиск и сегменты
   36 px (y 196–231), «Мои» 31 px (y 199–229). Чип стоит прямым ребёнком тулбара, а не в .crm-chips. */
.crm-wrap > .crm-toolbar:has(> #crmwMine) > .crm-search > input,
.crm-wrap > .crm-toolbar > #crmwMine { height: var(--ctl-h); padding-top: 0; padding-bottom: 0; }

/* 🏢 CLIE-1030·R2 · ПЛАШКА ПРОСТРАНСТВА. Вычитающий фильтр обязан назвать числом, что он спрятал,
   и дать выход в один клик. Акцент — подложка + кольцо (левые полоски-рейки запрещены).
   Чернила меряются к СВОЕЙ подложке: текст — var(--text) на 10% заливке, акцентное слово — var(--primary-2). */
.crm-space-note { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0; padding: 10px 16px;
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent), inset 0 -1px 0 0 var(--line);
  color: var(--text); font-size: 13px; line-height: 1.45; }
.crm-space-note .csn-ic { display: inline-flex; color: var(--primary-2, var(--primary)); flex: 0 0 auto; }
.crm-space-note .csn-ic svg { width: 16px; height: 16px; }
.crm-space-note .csn-t { flex: 1 1 240px; min-width: 180px; color: var(--text); }
.crm-space-note .csn-t b { font-weight: 650; color: var(--primary-2, var(--primary)); }
.crm-space-note .csn-acts { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; min-width: auto; }
.crm-space-note .csn-acts button { display: inline-flex; align-items: center; gap: 6px; min-width: auto; }
.crm-space-note .csn-acts button svg { width: 14px; height: 14px; }
/* ✕ плашки (CRMC-697·Р5, владелец: «Тут нужен крестик чтобы закрыть это уведомление»).
   Размерный класс ряда — как у соседних кнопок плашки; зона нажатия квадратная, не глиф. */
.crm-space-note .csn-x { display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: 8px; flex: 0 0 auto;
  background: transparent; color: var(--text-dim); cursor: pointer; transition: background .14s, color .14s; }
.crm-space-note .csn-x svg { width: 14px; height: 14px; }
.crm-space-note .csn-x:hover { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--text); }
.crm-space-note .csn-x:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--glow); }
/* След закрытой плашки — тихий чип В САМОМ тулбаре: ноль лишней высоты, вход в один клик. */
.crm-toolbar .csn-mini { display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto;
  height: var(--ctl-h); border-radius: var(--ctl-r); padding: 0 9px;
  color: var(--text-dim); font-variant-numeric: tabular-nums; }
.crm-toolbar .csn-mini svg { width: 14px; height: 14px; }
.crm-toolbar .csn-mini:hover { color: var(--text); }

/* Строки контактов */
.crm-list { padding: 6px 8px 20px; overflow-y: auto; }
.crm-list-tight { padding: 2px 0 0; }
.crm-row { display: flex; align-items: center; gap: 11px; padding: 9px 12px; border-radius: 12px; cursor: pointer; transition: background .12s; outline: none; }
.crm-row:hover { background: var(--hover, rgba(127,127,127,.07)); }
.crm-row:focus-visible { box-shadow: 0 0 0 2px var(--glow); }
.crm-row-main { flex: 1; min-width: 0; }
.crm-row-name { font-size: 14px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-row-sub { display: flex; align-items: center; gap: 6px; margin-top: 2px; font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; }
.crm-row-title { overflow: hidden; text-overflow: ellipsis; }
.crm-row-company { display: inline-flex; align-items: center; gap: 4px; overflow: hidden; text-overflow: ellipsis; }
.crm-row-company svg { width: 13px; height: 13px; opacity: .75; flex: 0 0 auto; }
/* разделитель «·» — чернилами строки, без прозрачности: opacity .5 давала 3.32:1 (CRM-свип 20.10) */
.crm-row-dot { color: var(--muted); }

/* ═══ 🗂 «ЗАДАЧИ CRM» (CLIE-1544) — сквозной список работы по клиентам ═══════════════════
   Каркас списка НЕ свой: строка стоит на `.crm-row` (те же отступы, радиус, hover, фокус),
   тулбар и чипы — на `.crm-toolbar`/`.crm-chip`. Здесь только то, чего у соседей нет:
   галочка «сделано», знак типа, срок и кнопка записи. Все цвета — токенами: у прибитого
   цвета нет второй темы (канон theme-contrast-runtime). */
.crmw-buckets { padding-top: 8px; padding-bottom: 8px; top: 56px; }
.crmw-cnt { display: inline-block; margin-left: 5px; font-size: 11px; font-weight: 700; }
.crmw-row { gap: 9px; }
.crmw-check { flex: 0 0 auto; width: 21px; height: 21px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; border: 1.6px solid var(--line-strong, #555); background: transparent; color: transparent; cursor: pointer; padding: 0;
  transition: border-color .12s, background .12s, color .12s; }
.crmw-check svg { width: 13px; height: 13px; }
.crmw-check:hover { border-color: var(--primary); color: color-mix(in srgb, var(--primary) 55%, transparent); }
.crmw-check.on { border-color: transparent; background: var(--ok, #22a06b); color: #fff; }
.crmw-kind { flex: 0 0 auto; display: inline-flex; color: var(--muted); }
.crmw-kind svg { width: 15px; height: 15px; }
.crmw-kind-warn { color: var(--urg-overdue-ink); }
.crmw-row.over .crmw-kind { color: var(--urg-overdue-ink); }
.crmw-num { color: var(--muted); font-weight: 600; margin-right: 6px; }
.crmw-done .crm-row-name { color: var(--muted); text-decoration: line-through; }
.crmw-ent { display: inline-flex; align-items: center; gap: 4px; max-width: 46%; border: none; background: transparent; padding: 0;
  font: inherit; font-size: 12px; color: var(--primary-2, var(--primary)); cursor: pointer; overflow: hidden; }
.crmw-ent span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmw-ent svg { width: 13px; height: 13px; flex: 0 0 auto; opacity: .85; }
/* crmwork-row-icon-size-1 · .crmw-ent — кнопка, и глобальное `button svg.ic` (22 px, вес 0,1,2) било
   13 px выше (0,1,1): мишень лида и воронка сделки стояли ≈20 px рядом с подписью 12 px. */
@media (min-width: 761px) {
  .crmw-ent svg.ic { width: 13px; height: 13px; }
}
.crmw-ent:hover span { text-decoration: underline; }
.crmw-entbits { overflow: hidden; text-overflow: ellipsis; }
/* Точки «·» между сущностями (сделка · лид · контакт) живут ВНУТРИ .crmw-entbits — обычном
   инлайне, где gap строки не действует: «Сделка·Лид» слипались. Поле = gap .crm-row-sub (6 px)
   (f_crm_a · crmwork-meta-glued-1). */
.crmw-entbits > .crm-row-dot { margin: 0 6px; }
.crmw-when { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; font-weight: 600; color: var(--muted);
  padding: 3px 9px; border-radius: var(--r-full, 999px); border: 1px solid var(--line); white-space: nowrap; }
.crmw-when svg { width: 12px; height: 12px; }
.crmw-when.today { color: var(--urg-today); background: var(--urg-today-soft); border-color: transparent; }
.crmw-when.over { color: var(--urg-overdue-ink); background: var(--urg-overdue-soft); border-color: transparent; }
.crmw-who { flex: 0 0 auto; display: inline-flex; }
/* 🔴 Размер аватара строки — ЧЕРЕЗ --sz, как у .crm-av.sm/.lg. База .crm-av держит flex: 0 0 var(--sz)
   (34px), а .crmw-who — флекс: прямые width/height ужимали только высоту, и фото исполнителя
   вставало эллипсом 34×24 (кадр CRM → Задачи, обе темы: x 1378–1411 · y 360–383). */
.crm-av.crmw-ava { --sz: 24px; font-size: 10px; }
/* crmwork-rows-1 · телефон (q_crm): глобальное `button svg.ic` 22 px било 13 px значка записи и в узкой
   строке «Работы» — правка выше стояла только ≥761, на телефоне мишень лида вставала ≈20 px. */
@media (max-width: 760px) {
  .crmw-ent svg.ic { width: 13px; height: 13px; }
}
/* crmwork-rows-1 · ≤560: в одну строку «галочка · знак · название · срок · аватар» название сжималось до
   8–10 знаков («Выявить пот…»), проект — до буквы («З…»). Название — до двух строк во всю ширину,
   под ним проект и номер, срок и исполнитель — третьей строкой (ничего не убрано). */
@media (max-width: 560px) {
  .crmw-row { display: grid; grid-template-columns: auto auto minmax(0, 1fr) auto; column-gap: 9px; row-gap: 3px; align-items: start;
    grid-template-areas: "ck kd nm nm" ". . sb sb" ". . wh wo"; }
  .crmw-row[data-gid] { grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "kd nm nm" ". sb sb" ". wh wo"; }
  .crmw-row > .crm-row-main { display: contents; }
  .crmw-row > .crmw-check { grid-area: ck; }
  .crmw-row > .crmw-kind { grid-area: kd; margin-top: 2px; }
  .crmw-row .crm-row-name { grid-area: nm; white-space: normal; display: -webkit-box; -webkit-box-orient: vertical;
    -webkit-line-clamp: 2; overflow-wrap: anywhere; }
  .crmw-row .crm-row-sub { grid-area: sb; min-width: 0; margin-top: 0; flex-wrap: wrap; row-gap: 2px; }
  /* crm-work-meta-trunc-1 · мета-строка «запись · #номер · стадия · сумма · компания» в одну строку не влезала
     (чернила x 151–352 на 390 px, кадр crm_crmwork, обе темы): ссылку держал потолок 62 %, хвост резался — стадия
     до «В ра…» / «В …» / «Разра…». Ссылка — своей строкой во всю ширину (длинная — с «…»), номер и стадия —
     строкой под ней, «·» между ними не нужна. Ничего не убрано, у хвоста (сумма, компания) многоточие прежнее. */
  .crmw-row .crmw-ent { max-width: 100%; }
  .crmw-row .crm-row-sub > .crm-row-dot { display: none; }
  .crmw-row .crmw-entbits { flex: 1 1 100%; min-width: 0; }
  .crmw-row > .crmw-when { grid-area: wh; justify-self: start; margin-top: 3px; }
  .crmw-row > .crmw-who { grid-area: wo; align-self: center; margin-top: 3px; }
}

/* 🚦 «Без следующего шага»: полоса-сигнал над списком и подпись во втором виде. */
.crmw-gapsbar { display: flex; align-items: center; gap: 8px; width: 100%; box-sizing: border-box; margin: 0; padding: 9px 16px;
  border: none; border-bottom: 1px solid var(--line); background: var(--urg-overdue-soft); color: var(--text);
  font: inherit; font-size: 12.5px; text-align: left; cursor: pointer; }
.crmw-gapsbar svg { width: 15px; height: 15px; color: var(--urg-overdue-ink); flex: 0 0 auto; }
.crmw-gapsbar:hover { background: color-mix(in srgb, var(--urg-overdue) 20%, transparent); }
.crmw-gapsgo { margin-left: auto; color: var(--primary-2, var(--primary)); font-weight: 650; }
.crmw-note { display: inline-flex; align-items: center; gap: 7px; flex: 1 1 260px; min-width: 200px; font-size: 12.5px; color: var(--muted); }
.crmw-note svg { width: 15px; height: 15px; color: var(--urg-overdue-ink); flex: 0 0 auto; }
/* Хвост «показаны первые N из M»: тот же язык, что у полосы-сигнала, но спокойным знаком —
   это не долг и не беда, а честная граница страницы. */
.crmw-more { display: flex; justify-content: center; padding: 10px 2px 2px; }
.crmw-more svg { color: var(--muted); }

/* Пилюля жизненного цикла (список + карточка компании) */
.crm-life { display: inline-flex; align-items: center; font-size: 11px; font-weight: 650; padding: 3px 9px; border-radius: var(--r-full, 999px); flex: 0 0 auto; --lc: #8b93a3; color: var(--lc); background: color-mix(in srgb, var(--lc) 14%, transparent); border: 1px solid color-mix(in srgb, var(--lc) 26%, transparent); }
.crm-life-lead { --lc: var(--cm-6b8afd, #6b8afd); }
.crm-life-mql { --lc: var(--cm-8b5cf6, #8b5cf6); }
.crm-life-sql { --lc: #e0913a; }
.crm-life-customer { --lc: #22a06b; }
/* светлая: стадия жизненного цикла читается на своём тинте 14 % — было 2.5–3.9 (замер 20.10) */
html[data-theme="light"] .crm-life { --lc: #555e6e; }
html[data-theme="light"] .crm-life-lead { --lc: var(--cm-3451c9, #3451c9); }
html[data-theme="light"] .crm-life-mql { --lc: var(--cm-6d3fd0, #6d3fd0); }
html[data-theme="light"] .crm-life-sql { --lc: #8a520a; }
html[data-theme="light"] .crm-life-customer { --lc: #0e6b40; }

/* Пустое состояние */
.crm-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; padding: 56px 24px; }
.crm-empty-ic { width: 44px; height: 44px; border-radius: 14px; display: inline-flex; align-items: center; justify-content: center; background: var(--panel-2); border: 1px solid var(--line); color: var(--muted); }
.crm-empty-ic svg { width: 22px; height: 22px; }
.crm-empty-t { font-size: 15px; font-weight: 650; color: var(--text); }
.crm-empty-s { font-size: 13px; color: var(--muted); max-width: 280px; line-height: 1.45; }
.crm-empty-add { margin-top: 6px; }

/* ══════════════════════════════════════════════════════════════════════════════════════
   🧱 CRMC-675·B · ПАНЕЛЬ «ВОРОНКИ» (конструктор воронок и стадий).
   Своих размеров и красок не изобретаем: рама — тот же `.crm-drawer` (значит тянется мышью
   и помнит ширину сама, CRMC-406), кирпичи внутри — `.cc-btn/.cc-in/.cc-sec-h/.cc-toggle`
   и `.sa-stg/.sa-req` (те же, что у дисциплины воронки). Здесь — только раскладка.
   🔴 Цвет воронки/стадии показываем ТОЧКОЙ, а не левой полоской-рейкой (CLIE-483).
   🔴 Список стадий НЕ капим вложенным max-height (CLIE-620): скроллит тело панели.
   ══════════════════════════════════════════════════════════════════════════════════════ */
/* 🔴 Двумя классами: `.crm-drawer { width: min(480px…) }` стоит НИЖЕ в файле и при равной
   специфичности побеждал — панель «Воронки» всю жизнь была 480px, а не задуманные 560. */
.pcf-drawer { container: pcf / inline-size; }
.pcf-drawer.crm-drawer { width: min(980px, 96vw); }
.pcf-head { align-items: center; }
.pcf-h-t { font-size: 17px; font-weight: 700; letter-spacing: -.01em; color: var(--text); }
.pcf-h-s { font-size: 12px; color: var(--muted); font-weight: 600; margin-left: 8px; }
.pcf-body { padding: 14px 16px 28px; gap: 0; }
/* 🧭 e9b06f9b · НАВИГАТОР ВОРОНОК: «список слева | воронка справа» (узор настроек почты).
   Список — канонический пикер `.ccpp`, смонтированный колонкой: здесь только раскладка и то, что
   колонке нужно иначе, чем поповеру — список тянется на всю высоту, а не капится 340px.
   Каждая колонка скроллит САМА: прокрутка сотни воронок не уводит настройку, и наоборот.
   Ширина списка — доля панели в пределах (не прибитое число): колонку НЕ регистрируем в WIN_PANES,
   потому что её инлайн-ширина (с !important) пережила бы переход шторки в узкий drill-down. */
.pcf-body.pcf-body-split { padding: 0; overflow: hidden; flex: 1 1 auto; min-height: 0; }
.pcf-split { flex: 1 1 auto; min-height: 0; display: flex; align-items: stretch; }
.pcf-nav { flex: 0 0 auto; width: clamp(240px, 34%, 340px); min-width: 0; display: flex; flex-direction: column; gap: 10px; padding: 14px 12px 12px 16px; border-right: 1px solid var(--line); overflow: hidden; }
.pcf-pipes { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.pcf-pipes > .ccpp { flex: 1 1 auto; min-height: 0; }
.pcf-pipes .ccpp-list { max-height: none; flex: 1 1 auto; min-height: 0; }
.pcf-pipes .bmp-sec-h { background: var(--panel); }
.pcf-nav > .pcf-arch { flex: 0 1 auto; max-height: 40%; overflow: auto; margin-top: 0; padding-top: 10px; }
.pcf-main { flex: 1 1 auto; min-width: 0; overflow-y: auto; padding: 14px 18px 28px; }
.pcf-back { display: none; appearance: none; align-items: center; gap: 6px; margin: 0 0 12px -4px; padding: 5px 9px 5px 4px; border: 0; border-radius: 8px; background: none; color: var(--primary); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; }
.pcf-back:hover { background: var(--hover); }
.pcf-back svg { width: 16px; height: 16px; }
/* Узкая панель (телефон, утянутая шторка) — drill-down: ЛИБО список, ЛИБО воронка с «← Все воронки». */
@container pcf (max-width: 719px) {
  .pcf-nav { flex: 1 1 auto; width: auto; border-right: 0; padding-right: 16px; }
  .pcf-split[data-view="nav"] > .pcf-main { display: none; }
  .pcf-split[data-view="one"] > .pcf-nav { display: none; }
  .pcf-back { display: inline-flex; }
}
.pcf-dot { appearance: none; flex: 0 0 auto; width: 10px; height: 10px; border-radius: 50%; border: 0; padding: 0; background: var(--muted); cursor: pointer; box-shadow: 0 0 0 1px color-mix(in srgb, var(--text) 14%, transparent) inset; }
.pcf-dot.big { width: 22px; height: 22px; border-radius: 7px; }
.pcf-dot:hover { box-shadow: 0 0 0 2px var(--primary); }
.pcf-row { display: flex; align-items: center; gap: 10px; }
.pcf-name { flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 650; color: var(--text); cursor: text; padding: 3px 7px; margin: 0 -7px; border-radius: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; transition: background .12s; }
.pcf-name:hover { background: var(--hover); }
.pcf-name-edit { flex: 1 1 auto; min-width: 0; width: 100%; box-sizing: border-box; font: inherit; font-size: 14px; font-weight: 650; color: var(--text); background: var(--panel-2); border: 0; box-shadow: inset 0 0 0 1.5px var(--primary); border-radius: 8px; padding: 4px 8px; outline: none; }
.pcf-sec { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 20px 0 10px; }
.pcf-stages { display: flex; flex-direction: column; }
.pcf-stg-h { gap: 8px; }
.pcf-grip { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 24px; color: var(--text-dim, var(--muted)); cursor: grab; touch-action: none; opacity: .55; transition: opacity .12s, color .12s; }
.pcf-stg:hover .pcf-grip { opacity: 1; color: var(--muted); }
.pcf-grip svg { width: 15px; height: 15px; }
.pcf-stg-badges { display: flex; flex-wrap: wrap; gap: 5px; padding: 0 12px 10px 42px; }
.pcf-stg-badges .cc-chip svg { width: 11px; height: 11px; }
.pcf-stg-b { padding: 4px 12px 12px; border-top: 1px solid var(--line); margin-top: 2px; }
.pcf-f { margin-bottom: 12px; }
.pcf-f > label { display: block; font-size: 11.5px; font-weight: 650; color: var(--muted); margin-bottom: 5px; text-transform: uppercase; letter-spacing: .03em; }
.pcf-f2 { display: flex; gap: 10px; }
.pcf-f2 > .pcf-f { flex: 1 1 0; min-width: 0; }
.pcf-stg-foot { display: flex; justify-content: flex-end; padding-top: 4px; }
.pcf-danger { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 22px; padding-top: 16px; border-top: 1px solid var(--line); }
.pcf-danger-h { flex: 1 1 160px; min-width: 0; font-size: 11.5px; color: var(--muted); line-height: 1.4; }
.pcf-drawer .cc-btn.busy { opacity: .6; }
.pcf-one.ro .pcf-name, .pcf-one.ro .cc-toggle { pointer-events: none; opacity: .55; }
/* Протяжка порядка стадий — ядро ccStartRowDrag: строка «приподнимается», соседи расступаются. */
.pcf-reordering { cursor: grabbing; }
.pcf-stg.pcf-dragging { position: relative; z-index: 3; box-shadow: var(--shadow-2, 0 10px 28px rgba(0,0,0,.28)); border-color: var(--primary); }
.pcf-stg.pcf-dragging .pcf-grip { cursor: grabbing; opacity: 1; }
.pcf-move-list { display: flex; flex-direction: column; gap: 2px; margin: 10px 0 8px; }
.pcf-move-list .tc-pop-row { display: flex; align-items: center; gap: 9px; }
.pcf-tpls { display: flex; flex-direction: column; gap: 2px; }
.pcf-tpls .tc-pop-sub { margin-left: auto; font-size: 11.5px; color: var(--muted); }
/* 🗄 Архив воронок — постоянный раздел РЯДОМ с активным списком (канон visa-trash), тихий:
   он не соревнуется за внимание с рабочими воронками, но всегда на месте. Никаких px-капов —
   раздел живёт внутри уже скроллящегося тела панели (CLIE-620). */
.pcf-arch { margin-top: 22px; padding-top: 14px; border-top: 1px solid var(--line); }
.pcf-arch-h { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 0 0 2px; cursor: pointer; color: var(--muted); }
.pcf-arch-h:hover { color: var(--text); }
.pcf-arch-row { display: flex; align-items: center; gap: 9px; padding: 7px 2px; border-bottom: 1px solid var(--line); }
.pcf-arch-row:last-child { border-bottom: 0; }
.pcf-arch-n { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; color: var(--text); }
.pcf-arch-m { flex: 0 0 auto; font-size: 11.5px; color: var(--muted); }

/* ── Карточка контакта/компании (правый drawer, тот же шелл, что у сделки) ── */
.crm-drawer { width: min(480px, 96vw); }
.crm-drawer-head { align-items: flex-start; padding: 15px 14px 14px 16px; }
.crm-head-id { display: flex; align-items: center; gap: 12px; min-width: 0; flex: 1; }
.crm-head-tx { min-width: 0; flex: 1; }
.crm-name-edit { font-size: 19px; font-weight: 700; letter-spacing: -.01em; line-height: 1.2; padding: 3px 7px; margin: -3px -7px 0; border-radius: 8px; outline: none; transition: background .12s, box-shadow .12s; }
.crm-name-edit:hover { background: var(--hover); }
.crm-name-edit:focus { background: var(--panel-2); box-shadow: inset 0 0 0 1.5px var(--primary); }
.crm-name-edit:empty:before, .crm-title-edit:empty:before { content: attr(data-ph); color: var(--text-dim); }
.crm-title-edit { font-size: 13px; color: var(--muted); font-weight: 500; padding: 2px 7px; margin: 2px -7px 0; border-radius: 7px; outline: none; transition: background .12s, box-shadow .12s; min-height: 1.2em; }
.crm-title-edit:hover { background: var(--hover); }
.crm-title-edit:focus { background: var(--panel-2); box-shadow: inset 0 0 0 1.5px var(--primary); color: var(--text); }
.crm-x { align-self: flex-start; }
.crm-drawer-body { padding: 14px 16px 24px; gap: 16px; }

/* Сегмент-пилюля жизненного цикла в карточке */
/* CLIE-505: стадия жизненного цикла = канон .cc-seg + .cc-seg-md (была pill-дорожка
   999px со сплошной brand-заливкой выбранного — третий вид сегмента в продукте). */
.crm-life-pill { align-self: flex-start; }

/* Компания-чип */
.crm-comp-row { margin-top: -4px; }
.crm-comp-chip { display: inline-flex; align-items: center; gap: 7px; max-width: 100%; padding: 7px 10px 7px 11px; border-radius: 11px; border: 1px solid var(--line); background: var(--panel-2); color: var(--text); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; transition: border-color .12s, background .12s; }
.crm-comp-chip:hover { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 8%, transparent); }
.crm-comp-chip > svg:first-child { width: 15px; height: 15px; color: var(--muted); flex: 0 0 auto; }
.crm-comp-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-comp-chip > svg:last-child { width: 15px; height: 15px; color: var(--muted); opacity: .7; flex: 0 0 auto; margin-left: auto; }

/* Поля (телефоны/email/заметки) — инлайн, автосейв на blur */
.crm-field { display: flex; flex-direction: column; gap: 6px; }
.crm-field > label { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
.crm-field > label svg { width: 13px; height: 13px; opacity: .8; }
.crm-multi { font-size: 13.5px; line-height: 1.55; min-height: 40px; padding: 9px 11px; border-radius: 10px; border: 1px solid var(--line); background: var(--panel-2); color: var(--text); outline: none; white-space: pre-wrap; word-break: break-word; transition: border-color .12s, box-shadow .12s; }
.crm-multi:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.crm-multi:empty:before { content: attr(data-ph); color: var(--text-dim); }
.crm-notes { min-height: 56px; }

/* Секции (дубли / история / компания) */
.crm-sec { display: flex; flex-direction: column; gap: 9px; }
.crm-sec-h { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 700; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em; }
.crm-sec-n { font-size: 11px; font-weight: 600; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--r-full, 999px); padding: 1px 8px; min-width: 18px; text-align: center; }
.crm-sec-empty { font-size: 12.5px; color: var(--text-dim); padding: 2px 0 4px; }
/* 🚪 Пустое состояние С ВЫХОДОМ (crmEmptyGoHtml): слова и под ними ОДНА кнопка. Общая геометрия —
   обоим шаблонам; стекло «Глубины» кладёт её фрагмент поверх. */
.crm-sec-empty.crm-empty-go { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.crm-empty-btn { display: inline-flex; align-items: center; gap: 6px; }
.crm-empty-btn svg { width: 14px; height: 14px; }
/* 🧾 Строка документа клиента: статус-чип и сумма справа (как строка сделки), значок беседы слева. */
.crm-doc-side { flex: none; display: inline-flex; align-items: center; gap: 10px; }
.crm-doc-amt { font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text); }
.crm-doc-ic { flex: none; width: 32px; height: 32px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; background: var(--hover); color: var(--text-dim); }
.crm-doc-ic svg { width: 16px; height: 16px; }
/* 👥 CRMC-705·6 · ЛЮДИ КЛИЕНТА: компании человека с должностью и ролями в каждой. Геометрия —
   та же карточка-строка, что у участников сделки (`.crmw-sub`): рамка `--line`, фон `--panel-2`,
   действия СЛОВАМИ. Роли — мягкие пилюли; приглушённые — роли в компании клиента, пока в сделке
   своих не назначено. Только токены темы — светлая и тёмная одинаково. */
.crm-sec-add { margin-left: auto; text-transform: none; letter-spacing: 0; display: inline-flex; align-items: center; gap: 4px; }
.crm-sec-add svg { width: 14px; height: 14px; }
.crm-title-ro { cursor: default; }
.crm-title-ro:hover { background: none; }
.crm-links { display: flex; flex-direction: column; gap: 8px; }
.crm-link { display: flex; flex-direction: column; gap: 6px; padding: 8px 10px; border-radius: 10px; border: 1px solid var(--line); background: var(--panel-2); min-width: 0; }
.crm-link-top { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0; }
.crm-link-name { flex: 1 1 140px; min-width: 0; display: inline-flex; align-items: center; gap: 8px; padding: 2px 4px 2px 0; border: 0; background: none; color: var(--text); font: inherit; font-size: 13px; font-weight: 600; text-align: left; cursor: pointer; }
.crm-link-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-link-name:hover span { color: var(--primary); }
.crm-link-prim { flex: none; font-size: 11px; font-weight: 600; color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); border-radius: var(--r-full, 999px); padding: 2px 8px; }
.crm-link-a { flex: none; min-width: max-content; padding: 3px 9px; border-radius: var(--r-full, 999px); border: 1px solid var(--line); background: none; color: var(--text-dim); font: inherit; font-size: 11.5px; font-weight: 600; white-space: nowrap; cursor: pointer; transition: background .14s ease, color .14s ease, border-color .14s ease; }
.crm-link-a:hover { background: var(--hover); color: var(--primary); border-color: var(--line-strong); }
.crm-link-pos { width: 100%; box-sizing: border-box; padding: 6px 8px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--text); font: inherit; font-size: 12.5px; outline: none; }
.crm-link-pos:focus { border-color: var(--primary); box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 18%, transparent); }
.crm-link-roles { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.crm-rchips { display: inline-flex; flex-wrap: wrap; gap: 4px; min-width: 0; }
.crm-rchip { font-size: 11px; font-weight: 600; color: var(--text); background: color-mix(in srgb, var(--primary) 10%, var(--panel)); border: 1px solid color-mix(in srgb, var(--primary) 22%, var(--line)); border-radius: var(--r-full, 999px); padding: 1px 8px; white-space: nowrap; }
.crm-rchip.muted { color: var(--muted); background: none; border-color: var(--line); font-weight: 500; }
.crmw-roles { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; padding: 2px 2px 2px 8px; min-width: 0; }
.crmw-roles .crmw-sub-a { border: 1px solid var(--line); border-radius: var(--r-full, 999px); padding: 2px 9px; margin-left: auto; }
.crmw-sub-txt .crm-rchips { margin-top: 3px; }

/* Возможные совпадения (дубли) */
.crm-dups { display: flex; flex-direction: column; gap: 6px; }
.crm-dup { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 11px; background: var(--panel-2); }
/* 🗣 0424 · Опросы на карточке контакта: оценка слева крупно, вопрос и «когда» — рядом.
   Одежда та же, что у «Возможных совпадений» выше: это список строк, а не новая поверхность. */
.crm-nps-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 11px; background: var(--panel-2); margin-bottom: 6px; }
.crm-nps-score { flex: 0 0 auto; min-width: 34px; text-align: center; font-size: 17px; font-weight: 750; letter-spacing: -.02em; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.crm-nps-row.good .crm-nps-score { color: var(--ok); }
.crm-nps-row.bad .crm-nps-score { color: var(--danger); }
.crm-nps-b { display: flex; flex-direction: column; min-width: 0; gap: 2px; }
.crm-nps-q { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-nps-s { font-size: 11.5px; color: var(--muted); }
.crm-dup-b { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.crm-dup-n { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-dup-s { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-dup-btn { appearance: none; border: 1px solid var(--line); background: var(--panel); color: var(--muted); font: inherit; font-size: 12px; font-weight: 600; padding: 5px 12px; border-radius: 9px; cursor: pointer; flex: 0 0 auto; transition: all .12s; }
.crm-dup-btn:hover { color: var(--text); border-color: var(--line-strong, #555); }
.crm-dup-btn.primary { color: #fff; background: var(--acc-fill); border-color: var(--acc-fill); }
.crm-dup-btn.primary:hover { filter: brightness(1.06); color: #fff; }
.crm-dup-btn[disabled] { opacity: .55; cursor: default; pointer-events: none; }
/* «Связать» носит общий `.primary` (width:100% + margin-top) — без сброса кнопка забирала весь ряд,
   имя совпадения сжималось в ноль, а в «Глубине» кнопка вылезала за карточку */
.crm-dup-btn.primary { width: auto; margin-top: 0; }

/* Композер активности — прогрессивное раскрытие (тулбар всплывает при фокусе/тексте) */
.crm-composer { border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); padding: 4px; transition: border-color .13s, box-shadow .13s; }
.crm-composer:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.crm-comp-in { font-size: 13.5px; line-height: 1.5; min-height: 20px; max-height: 160px; overflow-y: auto; padding: 8px 9px; outline: none; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.crm-comp-in:empty:before { content: attr(data-ph); color: var(--text-dim); }
.crm-comp-tools { display: none; align-items: center; gap: 8px; padding: 4px 4px 2px; margin-top: 2px; border-top: 1px solid var(--line); }
.crm-composer-open .crm-comp-tools { display: flex; }
.crm-comp-kind { display: inline-flex; gap: 3px; flex: 1; flex-wrap: wrap; }
.crm-kbtn { appearance: none; border: 1px solid transparent; background: transparent; color: var(--muted); font: inherit; font-size: 12px; font-weight: 600; padding: 5px 9px; border-radius: 8px; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; transition: all .12s; }
.crm-kbtn svg { width: 14px; height: 14px; }
.crm-kbtn:hover { color: var(--text); background: var(--hover); }
.crm-kbtn.active { color: var(--primary-2, var(--primary)); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.crm-comp-send { flex: 0 0 auto; }
.crm-comp-send svg { width: 14px; height: 14px; }
#crmTlHost { margin-top: 2px; }
.crm-tl-kind { font-size: 10.5px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; background: var(--panel-2); border: 1px solid var(--line); border-radius: 6px; padding: 1px 6px; }

/* Профиль компании */
.crm-co-head { align-items: flex-start; }
.crm-back { appearance: none; border: 1px solid var(--line); background: var(--panel-2); color: var(--muted); width: 30px; height: 30px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex: 0 0 auto; transition: color .12s, border-color .12s; }
.crm-back svg { width: 16px; height: 16px; }
.crm-back:hover { color: var(--text); border-color: var(--line-strong, #555); }
.crm-co-logo { width: 46px; height: 46px; flex: 0 0 46px; border-radius: 13px; display: inline-flex; align-items: center; justify-content: center; background: var(--cc, var(--panel-2)); color: #fff; overflow: hidden; }
.crm-co-logo img { width: 100%; height: 100%; object-fit: cover; }
.crm-co-logo svg { width: 22px; height: 22px; }
.crm-co-name { font-size: 18px; font-weight: 700; letter-spacing: -.01em; color: var(--text); line-height: 1.2; }
.crm-co-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 5px; }
.crm-co-chip { font-size: 11.5px; font-weight: 600; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line); border-radius: var(--r-full, 999px); padding: 2px 9px; }
.crm-co-site { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; font-weight: 600; color: var(--primary-2, var(--primary)); text-decoration: none; }
.crm-co-site svg { width: 13px; height: 13px; }
.crm-co-site:hover { text-decoration: underline; }
/* ✏️ CRMC-705·9 · шапка компании клиента правится на месте: поле выглядит значением, рамка —
   только на наведении и в правке; readonly (нет права) — значение без рамки. Токены темы. */
.crm-co-in { appearance: none; font: inherit; color: inherit; background: transparent; border: 1px solid transparent; border-radius: 7px; padding: 1px 5px; margin: 0 0 0 -6px; min-width: 4ch; max-width: 100%; box-sizing: border-box; field-sizing: content; transition: border-color .12s, background .12s; }
.crm-co-in:hover:not([readonly]) { border-color: var(--line); }
.crm-co-in:focus { outline: none; border-color: var(--primary); background: var(--input-bg); }
.crm-co-in[readonly] { cursor: default; }
.crm-co-in::placeholder { color: var(--text-dim); font-weight: 500; }
input.crm-co-name { display: block; width: calc(100% + 6px); field-sizing: fixed; }
.crm-co-in-meta { font-size: 12px; font-weight: 600; color: var(--muted); margin: 0; }
.crm-co-site-row { display: flex; align-items: center; gap: 4px; margin-top: 4px; min-width: 0; }
/* Вторая строка шапки компании: сайт + «Объединить с…». Кнопка — иконка и слово в ОДНУ строку и
   не сжимается; сайт уступает место многоточием. */
.crm-co-acts { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 4px; min-width: 0; }
.crm-co-acts .crm-co-site-row { margin-top: 0; flex: 0 1 auto; }
.crm-sec-n:empty { display: none; }
.crm-co-merge { flex: none; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; height: var(--ctl-h, 31px); font-size: var(--ctl-fs, 13px); }
.crm-co-merge svg { width: 14px; height: 14px; flex: none; }
.crm-co-site-go { display: inline-flex; flex: 0 0 auto; color: var(--primary-2, var(--primary)); }
.crm-co-site-go svg { width: 13px; height: 13px; }
.crm-co-in-site { font-size: 12px; font-weight: 600; color: var(--primary-2, var(--primary)); margin: 0; }
.crm-co-mgr-btn { max-width: 340px; }
.crm-co-mgr-btn[disabled] { cursor: default; }

/* Сделки компании */
.crm-deal-list { display: flex; flex-direction: column; gap: 3px; }
.crm-deal-row { display: flex; align-items: center; gap: 9px; padding: 8px 10px; border-radius: 10px; cursor: pointer; transition: background .12s; }
.crm-deal-row:hover { background: var(--hover, rgba(127,127,127,.07)); }
.crm-deal-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; background: var(--muted); }
.crm-deal-dot.st-open { background: var(--primary); }
.crm-deal-dot.st-won { background: #22a06b; }
.crm-deal-dot.st-lost { background: var(--danger); }
.crm-deal-title { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-deal-num { font-size: 11px; color: var(--text-dim); flex: 0 0 auto; }
.crm-deal-amt { font-size: 12.5px; font-weight: 600; color: var(--muted); flex: 0 0 auto; }

@media (max-width: 560px) { .crm-toolbar { padding: 10px 12px; } .crm-add { order: 3; margin-left: 0; } }

/* ── 🧩 Настраиваемые поля (custom fields) — реюзабельный блок карточек CRM (сделка/контакт/компания).
   Только токены темы → светлая и тёмная одинаково. Строка = имя слева + инлайн-контрол справа. ── */
.ccx-host { display: flex; flex-direction: column; gap: 8px; }
.ccx-label { font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--text-dim); }
/* в карточке блока «Дополнительные поля» заголовок уже есть — подпись «Поля» лишняя */
.crmw-blk[data-cb="custom"] > .crmw-card .ccx-label { display: none; }
.ccx-card { border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); overflow: hidden; }
.ccx-row { display: flex; align-items: center; gap: 12px; min-height: 44px; padding: 5px 12px; }
.ccx-row + .ccx-row { border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
.ccx-row-name { flex: 0 1 auto; max-width: 48%; font-size: 13.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ccx-row-val { flex: 1 1 auto; display: flex; justify-content: flex-end; align-items: center; min-width: 0; }
.ccx-in { width: 100%; text-align: right; border: none; background: transparent; color: var(--text); font-size: 13.5px; font-weight: 600; outline: none; padding: 4px 0; font-family: inherit; }
.ccx-in::placeholder { color: var(--text-dim); font-weight: 400; }
.ccx-sel { text-align: right; text-align-last: right; -webkit-appearance: none; appearance: none; cursor: pointer; }
.ccx-date { cursor: pointer; color-scheme: dark; }
html[data-theme="light"] .ccx-date { color-scheme: light; }
/* 👤 CRMC-639 · поле-СОТРУДНИК. Это `.ccpp-field` (канон пикера), только внутри строки поля:
   рамку и подложку снимаем — строка карточки уже разграфлена, вторая рамка внутри неё была бы
   лишним элементом (правило «меньше элементов — лучше»). Значение прижато вправо, как у
   соседних строк, аватар идёт перед именем. */
.ccx-user { width: auto; max-width: 100%; min-height: 30px; padding: 2px 0; border: none; background: transparent; justify-content: flex-end; gap: 7px; font-size: 13.5px; font-weight: 600; }
.ccx-user:hover { border: none; box-shadow: none; }
.ccx-user:hover .ccpp-fname { color: var(--primary); }
.ccx-user .ccpp-fname { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ccx-user .tw-av { flex: none; width: 20px; height: 20px; font-size: 9px; }
.ccx-user-none .ccpp-fname { color: var(--text-dim); font-weight: 400; }
/* Легаси-значение, набранное текстом до CRMC-639: видно, но видно и что оно «не человек». */
.ccx-user-legacy { font-style: italic; color: var(--text-dim); font-weight: 400; }
/* Список ВАРИАНТОВ поля (`select` c data-ccsel) в строке карточки: механизм CLIE-590 прячет
   родной селект и кладёт рядом `.ccpp-wrap` — даём ей ту же ширину, что было у селекта, а
   раскрытый список кладём под строку, не ломая её высоту. */
.ccx-row-val .ccpp-wrap { flex: 1 1 auto; min-width: 0; }
.ccx-row-val .ccpp-field { justify-content: flex-end; border: none; background: transparent; min-height: 30px; padding: 2px 0; font-weight: 600; font-size: 13.5px; }
.ccx-row-val .ccpp-field:hover { box-shadow: none; border: none; }
.ccx-row-val .ccpp-field:hover .ccpp-fname { color: var(--primary); }
.ccx-row { flex-wrap: wrap; }
.ccx-row-val .ccpp-inline { flex: 1 0 100%; }
/* Поле-ЧЕЛОВЕК: значение уходит на свою строку, подпись получает всю ширину. Иначе в узкой
   колонке карточки подпись обрубалась до «Ответственный м…», хотя место рядом простаивало. */
.ccx-row-user .ccx-row-name { max-width: 100%; }
.ccx-row-user .ccx-row-val { flex: 1 0 100%; }
.ccx-check { width: 22px; height: 22px; border-radius: 6px; border: 1.5px solid var(--line-strong); background: var(--panel); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: background .13s, border-color .13s; padding: 0; flex: 0 0 auto; }
.ccx-check .ic { width: 14px; height: 14px; color: #fff; opacity: 0; transition: opacity .12s; }
.ccx-check.on { background: var(--primary); border-color: var(--primary); }
.ccx-check.on .ic { opacity: 1; }
.ccx-addarea { display: flex; }
.ccx-add-btn { display: inline-flex; align-items: center; gap: 7px; border: none; background: transparent; color: var(--primary); font-size: 13.5px; font-weight: 600; cursor: pointer; padding: 6px 8px; border-radius: 8px; font-family: inherit; transition: background .12s; }
.ccx-add-btn:hover { background: color-mix(in srgb, var(--primary) 10%, transparent); }
.ccx-plus { font-size: 18px; line-height: 1; font-weight: 500; }
.ccx-form { width: 100%; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.ccx-form-name, .ccx-form-choices { width: 100%; border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--text); font-size: 13.5px; font-weight: 600; padding: 9px 11px; outline: none; font-family: inherit; box-sizing: border-box; transition: border-color .12s, box-shadow .12s; }
.ccx-form-name::placeholder, .ccx-form-choices::placeholder { color: var(--text-dim); font-weight: 400; }
.ccx-form-name:focus, .ccx-form-choices:focus { border-color: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 22%, transparent); }
.ccx-type-chips { display: flex; flex-wrap: wrap; gap: 7px; }
.ccx-type-chip { border: 1px solid var(--line); background: var(--panel); color: var(--muted); font-size: 12.5px; font-weight: 600; padding: 6px 11px; border-radius: 999px; cursor: pointer; font-family: inherit; transition: background .12s, border-color .12s, color .12s; }
.ccx-type-chip:hover { border-color: var(--line-strong); }
.ccx-type-chip.on { border-color: var(--primary); color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.ccx-form-acts { display: flex; justify-content: flex-end; gap: 8px; }
/* 🔴 CRMC-639 · У ПОЛЯ ПОЯВИЛСЯ ВЫХОД: переименовать · сменить тип · удалить.
   Раньше поле, заведённое один раз, оставалось таким НАВСЕГДА — поэтому «Ответственный
   менеджер» у владельца застрял типом `text`, и человека в нём писали словом «Вика».
   Имя = инлайн-редактор (клик → правка на месте, без карандаша и кнопок «Сохранить»),
   тип и удаление — за ОДНОЙ тихой «⋯», которая проявляется по наведению. Место под неё
   зарезервировано всегда: строка не должна прыгать под курсором. */
.ccx-row-name { padding: 3px 6px; margin-left: -6px; margin-right: -6px; border-radius: 7px; cursor: text; transition: background .12s, color .12s, box-shadow .12s; }
.ccx-row-name:hover { background: color-mix(in srgb, var(--primary) 9%, transparent); color: var(--text); }
.ccx-row-name:focus-visible { outline: none; background: color-mix(in srgb, var(--primary) 9%, transparent); color: var(--text); box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 45%, transparent); }
.ccx-row-name.editing { flex: 1 1 auto; max-width: none; background: var(--panel); color: var(--text); white-space: pre-wrap; overflow: visible; text-overflow: clip; outline: none; box-shadow: 0 0 0 1px var(--primary), 0 0 0 3px color-mix(in srgb, var(--primary) 20%, transparent); }
.ccx-row-name:empty::before { content: attr(data-ph); color: var(--text-dim); }
/* Размер — как у соседнего `.ccx-check` (22px): контролы одной строки = один размерный класс. */
.ccx-row-cfg { flex: 0 0 auto; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: none; background: transparent; color: var(--text-dim); border-radius: 7px; cursor: pointer; opacity: 0; transition: opacity .13s, background .12s, color .12s; }
.ccx-row-cfg .ic { width: 15px; height: 15px; }
.ccx-row:hover .ccx-row-cfg, .ccx-row-cfg:focus-visible, .ccx-row-cfg.on { opacity: 1; }
.ccx-row-cfg:hover, .ccx-row-cfg.on { background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--text); }
.ccx-row-cfg:focus-visible { outline: none; box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 45%, transparent); }
/* На тач-экране наведения не бывает — там «⋯» видна всегда, иначе выхода из состояния нет. */
@media (hover: none) { .ccx-row-cfg { opacity: 1; } }

/* ═══════════════════════════════════════════════════════════════════════════
   ОМНИКАНАЛ (0167): бейдж канала · переписка в дровере сделки · вид «Каналы».
   Apple-grade, светлая И тёмная (через тему-переменные). Кастомные иконки.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── бейдж канала (доска/список/инбокс/тред) ── */
.deal-ch-badge { display:inline-flex; align-items:center; gap:4px; padding:2px 8px 2px 6px; border-radius:999px; font-size:11px; font-weight:600; line-height:1.45; border:1px solid transparent; white-space:nowrap; }
.deal-ch-badge .ic { width:13px; height:13px; }
.tw-card-foot .deal-ch-badge, .deal-row-title .deal-ch-badge { padding:2px 6px; }
.deal-ch-badge.ch-telegram { color:#2AABEE; background:color-mix(in srgb,#2AABEE 14%,transparent); border-color:color-mix(in srgb,#2AABEE 26%,transparent); }
.deal-ch-badge.ch-whatsapp { color:#1FA855; background:color-mix(in srgb,#25D366 15%,transparent); border-color:color-mix(in srgb,#25D366 28%,transparent); }
.deal-ch-badge.ch-sms      { color:var(--cm-6c8bff, #6C8BFF); background:color-mix(in srgb,var(--cm-6c8bff, #6C8BFF) 15%,transparent); border-color:color-mix(in srgb,var(--cm-6c8bff, #6C8BFF) 30%,transparent); }
/* 📸 Instagram (и любой новый вид без своей строки): цвет — с сервера (`--ch-c` из `drivers[].color`),
   без него — акцент темы. Прибитого фирменного hex здесь нет (канон foreign-brand-own-mark).
   Чернила подмешаны к --text: цвет вида узнаётся, а слово читается в обеих темах. */
.deal-ch-badge.ch-instagram { color:color-mix(in srgb,var(--ch-c, var(--primary-2)) 72%,var(--text)); background:color-mix(in srgb,var(--ch-c, var(--primary)) 14%,transparent); border-color:color-mix(in srgb,var(--ch-c, var(--primary)) 26%,transparent); }
/* Знак-монограмма внутри бейджа — ростом со значок соседних видов, своей подложки не тянет. */
.deal-ch-badge .cc-bmark { width:13px; height:13px; border-radius:4px; font-size:8.5px; background:transparent; color:inherit; }
.deal-row-title .deal-ch-badge { vertical-align:middle; margin-right:2px; }

/* ── переписка в дровере сделки: строка «бот↔оператор» + ЖИВОЙ тред мессенджера.
   🔴 CRMC-33/1: CSS второй ленты (.dt-* пузыри, .deal-thread-msgs/-foot/-in/-ta/-send)
   удалён вместе с её кодом — переписку рисует ОДИН мессенджер. ── */
.deal-thread-sec .di-sec-b { gap:0; }
.deal-thread-load, .deal-thread-empty { color:var(--text-dim); font-size:12.5px; padding:8px 2px; }
.deal-thread-who { display:flex; align-items:center; gap:6px; font-size:12px; color:var(--text-dim); margin-bottom:9px; }
.deal-thread-who .ic { width:13px; height:13px; opacity:.8; }
.deal-thread-mode { display:inline-flex; align-self:flex-start; background:var(--panel); border:1px solid var(--line); border-radius:10px; padding:2px; gap:2px; }
.dtm-btn { display:inline-flex; align-items:center; gap:5px; padding:5px 11px; border-radius:8px; font-size:12px; font-weight:600; color:var(--text-dim); border:none; background:transparent; cursor:pointer; transition:background .14s,color .14s; }
.dtm-btn .ic { width:14px; height:14px; }
.dtm-btn:hover { color:var(--text); }
.dtm-btn.on { background:var(--acc-fill); color:#fff; }

/* ── вид «Каналы» ──
   🔴 Колонка выровнена по ЛЕВОМУ краю — по той же сетке, что шапка раздела и сегменты
   (.tw-head padding: 12px 16px). Раньше было `max-width:720px; margin:0 auto` — контент
   уезжал в центр, а шапка оставалась слева: «вёрстка не ровная» (жалоба владельца). */
.ch-wrap { max-width:960px; margin:0; padding:16px 16px 44px; display:flex; flex-direction:column; gap:14px; overflow-wrap:anywhere; }
.ch-hint { font-size:13px; line-height:1.55; color:var(--text-dim); background:var(--panel-2); border:1px solid var(--line); border-radius:12px; padding:12px 14px; }
.ch-hint b { color:var(--text); }
.ch-tiles { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:10px; }
.ch-tile { display:flex; flex-direction:column; align-items:flex-start; gap:9px; padding:14px; border:1px solid var(--line); border-radius:14px; background:var(--panel); cursor:pointer; transition:border-color .15s,box-shadow .15s,transform .15s; text-align:left; }
.ch-tile:hover { border-color:var(--primary); box-shadow:0 10px 26px -14px var(--glow); transform:translateY(-1px); }
.ch-tile-ic, .ch-row-ic { display:inline-flex; align-items:center; justify-content:center; border-radius:11px; }
.ch-tile-ic { width:36px; height:36px; } .ch-tile-ic .ic { width:20px; height:20px; }
.ch-row-ic  { width:36px; height:36px; min-width:36px; } .ch-row-ic .ic { width:19px; height:19px; }
.ch-tile-ic.ch-telegram, .ch-row-ic.ch-telegram { color:#2AABEE; background:color-mix(in srgb,#2AABEE 15%,transparent); }
.ch-tile-ic.ch-whatsapp, .ch-row-ic.ch-whatsapp { color:#1FA855; background:color-mix(in srgb,#25D366 16%,transparent); }
.ch-tile-ic.ch-sms, .ch-row-ic.ch-sms          { color:var(--cm-6c8bff, #6C8BFF); background:color-mix(in srgb,var(--cm-6c8bff, #6C8BFF) 16%,transparent); }
.ch-tile-ic.ch-instagram, .ch-row-ic.ch-instagram { color:color-mix(in srgb,var(--ch-c, var(--primary-2)) 72%,var(--text)); background:color-mix(in srgb,var(--ch-c, var(--primary)) 15%,transparent); }
.ch-tile-ic .cc-bmark, .ch-row-ic .cc-bmark { width:20px; height:20px; font-size:11.5px; background:transparent; color:inherit; }
.ch-tile-name { font-weight:650; font-size:14px; color:var(--text); }
.ch-tile-add { display:inline-flex; align-items:center; gap:4px; font-size:12px; font-weight:600; color:var(--primary); }
.ch-tile-add .ic { width:13px; height:13px; }
.ch-list-h { font-size:12px; font-weight:650; text-transform:uppercase; letter-spacing:.03em; color:var(--text-dim); margin-top:6px; }
.ch-row { display:flex; align-items:center; gap:12px; padding:12px 14px; border:1px solid var(--line); border-radius:14px; background:var(--panel); transition:opacity .15s; }
.ch-row.off { opacity:.55; }
.ch-row-main { flex:1; min-width:0; }
.ch-row-top { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.ch-row-name { font-weight:650; font-size:14px; color:var(--text); outline:none; border-radius:6px; padding:1px 4px; }
.ch-row-name:focus { background:var(--hover); box-shadow:0 0 0 2px color-mix(in srgb,var(--primary) 40%,transparent); }
.ch-cfg { font-size:11.5px; color:var(--text-dim); background:var(--panel-2); border-radius:6px; padding:2px 7px; }
/* @имя_бота рядом с названием — сразу видно, ЧЕЙ это канал (без открытия настроек). */
.ch-bot { font-size:11.5px; font-weight:600; color:var(--primary-2, var(--primary)); background:color-mix(in srgb,var(--primary) 12%,transparent);
  border-radius:6px; padding:2px 7px; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; overflow-wrap:anywhere; }
/* статус-пилюля: приём включён / выключен. Клик — живая проверка связи. */
.ch-pill { display:inline-flex; align-items:center; gap:4px; padding:2px 8px 2px 6px; border-radius:999px; font-size:11px; font-weight:600;
  border:1px solid transparent; background:transparent; cursor:pointer; transition:background 140ms ease, border-color 140ms ease, color 140ms ease; }
.ch-pill .ic { width:12px; height:12px; }
.ch-pill.on  { color:var(--ok-ink, var(--ok)); background:var(--ok-soft); border-color:color-mix(in srgb,var(--ok) 26%,transparent); }
.ch-pill.off { color:var(--muted); background:var(--panel-2); border-color:var(--line); }
.ch-pill:hover { border-color:currentColor; }
.ch-row-sub { display:flex; gap:12px; flex-wrap:wrap; margin-top:3px; font-size:11.5px; color:var(--text-dim); }
.ch-row-act { display:flex; align-items:center; gap:6px; }
.ch-mini { width:30px; height:30px; border-radius:9px; border:1px solid var(--line); background:var(--panel); color:var(--text-dim); display:inline-flex; align-items:center; justify-content:center; cursor:pointer; transition:color .14s,border-color .14s; }
.ch-mini:hover { color:var(--text); border-color:var(--primary); }
.ch-mini.danger:hover { color:var(--danger); border-color:var(--danger); }
.ch-mini .ic { width:15px; height:15px; }
.ch-empty { color:var(--text-dim); font-size:13px; padding:18px; text-align:center; border:1px dashed var(--line); border-radius:12px; }
.ch-switch { position:relative; display:inline-block; width:38px; height:22px; cursor:pointer; }
.ch-switch input { opacity:0; width:0; height:0; }
.ch-switch-sl { position:absolute; inset:0; background:var(--line); border-radius:999px; transition:background .16s; }
.ch-switch-sl:before { content:""; position:absolute; width:16px; height:16px; left:3px; top:3px; background:#fff; border-radius:50%; transition:transform .16s; box-shadow:0 1px 3px rgba(0,0,0,.25); }
.ch-switch input:checked + .ch-switch-sl { background:var(--primary); }
.ch-switch input:checked + .ch-switch-sl:before { transform:translateX(16px); }

/* ── модал каналов (подключение / настройка / URL / журнал / подтверждение) ── */
.ch-modal-bd { position:fixed; inset:0; background:var(--cm-0a0c14-5, rgba(10,12,20,.5)); backdrop-filter:blur(3px); display:flex; align-items:center; justify-content:center; z-index:9000; opacity:0; transition:opacity .18s; padding:20px; }
.ch-modal-bd.open { opacity:1; }
/* overflow-wrap:anywhere — длинные токены/URL/ошибки Telegram НЕ вылезают за модалку. */
.ch-modal { width:min(460px,100%); max-height:88vh; overflow:auto; background:var(--panel); border:1px solid var(--line); border-radius:18px; box-shadow:0 30px 80px -20px rgba(0,0,0,.5); transform:translateY(8px) scale(.985); transition:transform .18s; overflow-wrap:anywhere; }
.ch-modal-bd.open .ch-modal { transform:none; }
.ch-modal-head { display:flex; align-items:center; gap:9px; padding:15px 18px; border-bottom:1px solid var(--line); font-weight:650; font-size:15px; }
.ch-modal-head .ic { width:16px; height:16px; }
.ch-modal-head .ch-modal-x { margin-left:auto; }
.ch-modal-body { padding:16px 18px; display:flex; flex-direction:column; gap:12px; }
.ch-modal-foot { padding:14px 18px; border-top:1px solid var(--line); display:flex; justify-content:flex-end; gap:8px; }
/* 🔴 Кнопки подвала — по содержимому и в одну строку. Глобальный `.primary{width:100%}`
   (легаси-лейауты) в двухкнопочном подвале раздувал «Готово» на всю ширину и ВЫДАВЛИВАЛ
   «Проверить связь» за край — поэтому явные width:auto/margin-top:0. Одна кнопка в подвале
   (мастер) — наоборот, во всю ширину: крупная цель. */
.ch-modal-foot > button { flex:0 0 auto; width:auto; margin-top:0; white-space:nowrap;
  display:inline-flex; align-items:center; justify-content:center; gap:6px; }
.ch-modal-foot > button:only-child { width:100%; }
.ch-modal-foot > button .ic { width:14px; height:14px; }
.ch-f { display:flex; flex-direction:column; gap:5px; font-size:12.5px; color:var(--text-dim); }
.ch-f > span { font-weight:600; display:inline-flex; align-items:baseline; gap:6px; }
.ch-opt { font-style:normal; font-weight:500; font-size:11px; color:var(--muted); }
/* строка с флажком = кликабельная карточка в рамке (голый квадрат посреди текста — запрещён) */
.ch-f-row { flex-direction:row; align-items:center; gap:9px; color:var(--text); font-size:13px; font-weight:500;
  border:1px solid var(--line); border-radius:10px; padding:9px 11px; background:var(--panel-2); cursor:pointer;
  transition:border-color 140ms ease, background 140ms ease; }
.ch-f-row:hover { border-color:var(--line-strong); }
.ch-f-row:focus-within { border-color:var(--primary); }
.ch-in { width:100%; padding:9px 11px; border:1px solid var(--line); border-radius:10px; background-color:var(--input-bg); color:var(--text); font:inherit; font-size:13px; outline:none; transition:border-color .14s, box-shadow .14s; box-sizing:border-box; } select.ch-in { padding-right:34px; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.ch-in:focus { border-color:var(--primary); box-shadow:0 0 0 3px var(--glow); }
.ch-mono { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; letter-spacing:.01em; }
textarea.ch-in { resize:vertical; min-height:44px; }
/* Свой чек-бокс: рамка + галочка, одинаково в светлой и тёмной теме (accent-color в тёмной
   давал «голый квадрат» системного вида — запрещено правилом дизайна). */
.ch-cb { appearance:none; -webkit-appearance:none; flex:none; width:18px; height:18px; margin:0; border-radius:5px;
  border:1px solid var(--line-strong); background:var(--panel); cursor:pointer; position:relative;
  transition:background 140ms ease, border-color 140ms ease; }
.ch-cb:hover { border-color:var(--primary); }
.ch-cb:checked { background:var(--primary); border-color:var(--primary); }
.ch-cb:checked::after { content:""; position:absolute; left:5.5px; top:2px; width:4px; height:9px;
  border:solid #fff; border-width:0 2px 2px 0; transform:rotate(42deg); }
.ch-cb:focus-visible { outline:2px solid var(--primary); outline-offset:2px; }

/* ── мастер подключения: подводка, шаги «где взять токен», ошибка, экран «Готово» ── */
.ch-wz-lead { font-size:13px; line-height:1.55; color:var(--text-dim); }
.ch-help { border:1px solid var(--line); border-radius:10px; background:var(--panel-2); padding:0 12px; }
.ch-help > summary { display:flex; align-items:center; gap:7px; list-style:none; cursor:pointer; padding:9px 0;
  font-size:12.5px; font-weight:600; color:var(--text); }
.ch-help > summary::-webkit-details-marker { display:none; }
.ch-help > summary .ic { width:14px; height:14px; color:var(--muted); flex:none; }
.ch-help > summary::after { content:""; margin-left:auto; width:6px; height:6px; border:solid var(--muted);
  border-width:0 1.5px 1.5px 0; transform:rotate(45deg) translateY(-2px); transition:transform 140ms ease; }
.ch-help[open] > summary::after { transform:rotate(225deg) translateY(-1px); }
.ch-help[open] > summary { border-bottom:1px solid var(--line); }
.ch-steps { margin:0; padding:10px 0 12px 20px; display:flex; flex-direction:column; gap:6px;
  font-size:12.5px; line-height:1.5; color:var(--text-dim); }
.ch-steps b { color:var(--text); font-weight:650; }
.ch-steps code { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px; background:var(--panel);
  border:1px solid var(--line); border-radius:6px; padding:1px 5px; overflow-wrap:anywhere; }
.ch-help .ch-url-box { margin:10px 0 6px; }
.ch-help .ch-url-hint { padding-bottom:12px; }
.ch-err { display:flex; align-items:flex-start; gap:7px; font-size:12.5px; line-height:1.45; color:var(--danger);
  background:var(--danger-soft); border:1px solid color-mix(in srgb,var(--danger) 28%,transparent);
  border-radius:10px; padding:9px 11px; overflow-wrap:anywhere; }
.ch-err.hidden { display:none; }
.ch-err .ic { width:14px; height:14px; flex:none; margin-top:1px; }
.ch-ok-ic { display:inline-flex; align-items:center; justify-content:center; width:24px; height:24px; flex:none;
  border-radius:50%; background:var(--ok-soft); color:var(--ok); }
.ch-ok-ic.warn { background:var(--warning-soft); color:var(--warning); }
.ch-ok-ic .ic { width:14px; height:14px; }
.ch-ok-line { display:flex; align-items:center; gap:8px; font-size:13px; font-weight:600; border-radius:10px; padding:10px 12px; }
.ch-ok-line.ok { color:var(--ok); background:var(--ok-soft); }
.ch-ok-line.warn { color:var(--warning); background:var(--warning-soft); }
.ch-ok-line .ic { width:15px; height:15px; flex:none; }
.ch-ok-next { font-size:12.5px; line-height:1.55; color:var(--text-dim); }
.ch-ok-next b { color:var(--text); }
/* «Проверить связь» — строки живого статуса */
.ch-st { gap:6px; }
.ch-st-row { display:grid; grid-template-columns:16px 92px 1fr; align-items:baseline; gap:8px; font-size:12.5px;
  padding:8px 10px; border:1px solid var(--line); border-radius:10px; overflow-wrap:anywhere; }
.ch-st-row .ic { width:14px; height:14px; align-self:center; }
.ch-st-row.ok { color:var(--ok); border-color:color-mix(in srgb,var(--ok) 26%,var(--line)); }
.ch-st-row.err { color:var(--danger); border-color:color-mix(in srgb,var(--danger) 26%,var(--line)); }
.ch-st-row.info { color:var(--muted); }
.ch-st-k { color:var(--muted); font-weight:600; }
.ch-st-v { color:var(--text); font-weight:600; }
.ch-st-s { grid-column:3; color:var(--muted); font-size:11.5px; }
.ch-st-note { font-size:12.5px; line-height:1.5; color:var(--text-dim); background:var(--panel-2); border-radius:10px; padding:10px 12px; }
/* спиннер кнопки: «нажал → сразу видно, что пошёл процесс» */
.ch-sp, .crm-chat-sp { display:inline-block; width:13px; height:13px; flex:none; border-radius:50%;
  border:2px solid color-mix(in srgb,currentColor 30%,transparent); border-top-color:currentColor;
  animation:ch-spin .7s linear infinite; }
@keyframes ch-spin { to { transform:rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .ch-sp, .crm-chat-sp { animation-duration:2.4s; } }
.ch-setup { display:flex; gap:8px; font-size:12px; line-height:1.45; color:var(--text-dim); background:var(--panel-2); border-radius:10px; padding:10px 12px; }
.ch-setup .ic { width:15px; height:15px; flex:none; margin-top:1px; }
.ch-url-note { font-size:12.5px; color:var(--text-dim); line-height:1.5; }
.ch-url-box { display:flex; align-items:center; gap:8px; background:var(--panel-2); border:1px solid var(--primary); border-radius:12px; padding:10px 12px; }
.ch-url { flex:1; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; color:var(--text); word-break:break-all; user-select:all; }
.ch-url-copy { white-space:nowrap; }
.ch-url-copy .ic { width:14px; height:14px; }
.ch-url-copy.ok { background:#1FA855; border-color:#1FA855; }
.ch-url-hint { font-size:11.5px; color:var(--text-dim); line-height:1.5; }
.ch-url-hint code { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; word-break:break-all; }
.ch-confirm-txt { font-size:13.5px; line-height:1.5; color:var(--text); }
.ch-log { gap:6px; }
.ch-log-row { display:flex; gap:10px; align-items:baseline; font-size:12px; padding:8px 10px; border:1px solid var(--line); border-radius:9px; }
.ch-log-row.ok { border-left:3px solid #1FA855; }
.ch-log-row.err { border-left:3px solid var(--danger); }
.ch-log-st { font-weight:600; min-width:72px; color:var(--text); }
.ch-log-txt { flex:1; color:var(--text-dim); }
.ch-log-when { color:var(--text-dim); white-space:nowrap; font-size:11px; }
.primary.danger { background:var(--danger); border-color:var(--danger); color:#fff; }

/* ══════════════ 🤝 M7 · СОВМЕСТНАЯ РАБОТА В СОЗВОНЕ ══════════════
   Аннотации поверх показа экрана · доска · со-просмотр · подгруппы · пространство звука ·
   документ рядом со сценой · врезка/«вместе».
   Оверлей созвона ВСЕГДА тёмный → внутри него берём его же токены (--gc-hair/--gc-btn),
   как это делает M2. Всё, что живёт СНАРУЖИ оверлея (пристыкованный документ), работает
   на обычных токенах темы — светлая и тёмная одинаково. */

/* ── ХОЛСТ (аннотации + доска — один движок, один класс) ───────────────────────── */
/* 🔴 САМ ХОЛСТ, ПАНЕЛЬ ИНСТРУМЕНТОВ И ДОСКА ЖИВУТ В `/app/ccroom.css`.
   Сюда они не вернутся: штрихи пакует, разбирает и РИСУЕТ одна реализация
   (`CcRoom.packStroke/unpackStroke/paintStroke`), и её зовут ОБА бандла, а гостевая
   страница `style.css` не грузит вовсе (канон `guest-call-parity`). Переехали:
   `.cc-ink`, `.cc-ink.cc-ink-erase`, `.cc-ink-board`, `.cc-ink-text`, `.cc-inkbar`(+`-g`,
   `-sep`, `.on-board`), `@keyframes ccInkBarIn`, `.cc-ink-b`(все состояния), `.cc-ink-c`,
   `.cc-ink-w`, `.cc-ink-clr`, `.cc-ink-menu`, `.cc-board`.
   Здесь ОСТАЛОСЬ только то, что завязано на раму основного клиента: положение этих
   поверхностей в `.groupcall-overlay`/`.call-overlay` и их гашение в мини-режиме и в
   эфире (ниже по файлу) — такой разметки у гостя нет.
   🔴 `@keyframes ccPanelIn` остаётся ЗДЕСЬ (на нём живут со-просмотр, подгруппы и
   пристыкованный документ) и продублирован в `ccroom.css` для `.cc-board` — тело кадров
   одинаковое, правится в двух местах вместе. */
@keyframes ccPanelIn { from { opacity: 0; transform: scale(.985); } to { opacity: 1; transform: none; } }
.groupcall-overlay.cc-board-open .group-grid { opacity: .12; filter: saturate(.6); transition: opacity var(--dur-2) var(--ease); }

/* ── СО-ПРОСМОТР ──────────────────────────────────────────────────────────────── */
.cc-watch {
  position: absolute; right: 14px; top: 62px; z-index: 13;
  width: min(420px, 92vw); display: flex; flex-direction: column;
  background: var(--cm-12151c-94, rgba(18,21,28,.94)); border: 1px solid var(--gc-hair-2); border-radius: 16px;
  -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  box-shadow: 0 28px 70px -26px rgba(0,0,0,.75);
  overflow: hidden; animation: ccPanelIn var(--dur-2) var(--ease) both;
}
.cc-watch-head {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  padding: 9px 8px 9px 13px; border-bottom: 1px solid rgba(255,255,255,.08);
}
.cc-watch-title { flex: 1; min-width: 0; font-size: 13.5px; font-weight: 650; color: #e6e9ef; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-watch-head .gc-people-x { position: static; flex: 0 0 auto; }
.cc-watch-body { display: flex; flex-direction: column; }
.cc-watch-empty { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px 13px 13px; }
.cc-watch-empty.hidden { display: none; }
.cc-watch-url {
  flex: 1 1 210px; min-width: 0; padding: 9px 11px; font: inherit; font-size: 13px;
  color: #e6e9ef; background: rgba(255,255,255,.05);
  border: 1px solid var(--gc-hair-2); border-radius: 10px; outline: none;
  transition: border-color var(--dur-1) var(--ease);
}
.cc-watch-url::placeholder { color: #7d8698; }
.cc-watch-url:focus { border-color: var(--primary-2); }
.cc-watch-go {
  flex: 0 0 auto; padding: 9px 14px; border: 0; border-radius: 10px;
  background: var(--acc-grad); color: #fff; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: filter var(--dur-1) var(--ease);
}
.cc-watch-go:hover { filter: brightness(1.08); }
.cc-watch-hint { flex: 1 0 100%; font-size: 11.5px; line-height: 1.45; color: #8b93a3; }
.cc-watch-video { width: 100%; max-height: 46vh; display: block; background: #000; }
.cc-watch-video.hidden { display: none; }

/* ── ПОДГРУППЫ (breakout) ─────────────────────────────────────────────────────── */
.cc-bo {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 13;
  width: min(340px, 94vw); display: flex; flex-direction: column;
  background: var(--cm-12151c-94, rgba(18,21,28,.94));
  -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  border-left: 1px solid rgba(255,255,255,.10);
  box-shadow: -18px 0 46px rgba(0,0,0,.42);
  animation: ccSideIn var(--dur-2) var(--ease) both;
}
@keyframes ccSideIn { from { transform: translateX(18px); opacity: 0; } to { transform: none; opacity: 1; } }
.cc-bo-head, .cc-prox-head {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  padding: 11px 8px 11px 14px; border-bottom: 1px solid rgba(255,255,255,.08);
}
.cc-bo-title, .cc-prox-title { flex: 1; min-width: 0; font-size: 14px; font-weight: 650; color: #e6e9ef; }
.cc-bo-head .gc-people-x, .cc-prox-head .gc-people-x { position: static; flex: 0 0 auto; }
.cc-bo-body { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.cc-bo-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 13.5px; color: #cfd5e2; }
.cc-bo-step { display: inline-flex; align-items: center; gap: 2px; padding: 2px; background: rgba(255,255,255,.05); border: 1px solid var(--gc-hair-2); border-radius: 10px; }
.cc-bo-step button {
  width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 8px; background: transparent; color: #cfd5e2; cursor: pointer;
  transition: background var(--dur-1) var(--ease);
}
.cc-bo-step button:hover { background: var(--gc-btn-h); color: #fff; }
.cc-bo-step button svg.ic { width: 15px; height: 15px; }
.cc-bo-mins { display: inline-flex; align-items: center; gap: 6px; color: #8b93a3; font-size: 12.5px; }
.cc-bo-num {
  width: 54px; padding: 5px 6px; text-align: center; font: inherit; font-size: 13.5px;
  font-variant-numeric: tabular-nums; color: #e6e9ef; background: transparent;
  border: 0; outline: none; -moz-appearance: textfield;
}
.cc-bo-mins .cc-bo-num { background: rgba(255,255,255,.05); border: 1px solid var(--gc-hair-2); border-radius: 10px; }
.cc-bo-num::-webkit-outer-spin-button, .cc-bo-num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.cc-bo-hint { font-size: 11.5px; line-height: 1.45; color: #8b93a3; }
.cc-bo-preview { display: flex; flex-direction: column; gap: 6px; margin-top: 2px; }
.cc-bo-room {
  display: flex; flex-direction: column; gap: 2px; padding: 8px 10px;
  background: rgba(255,255,255,.04); border: 1px solid var(--gc-hair); border-radius: 10px;
}
.cc-bo-room b { font-size: 12.5px; font-weight: 650; color: #e6e9ef; }
.cc-bo-room span { font-size: 11.5px; line-height: 1.45; color: #9aa4b2; }
.cc-bo-room .cc-bo-empty { color: #6f7787; font-style: italic; }
.cc-bo-foot { flex: 0 0 auto; display: flex; gap: 8px; padding: 12px 14px calc(env(safe-area-inset-bottom) + 14px); border-top: 1px solid rgba(255,255,255,.08); }
.cc-bo-primary, .cc-bo-ghost {
  flex: 1; padding: 10px 12px; border-radius: 11px; font-size: 13.5px; font-weight: 600;
  cursor: pointer; transition: filter var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.cc-bo-primary { border: 0; background: var(--acc-grad); color: #fff; }
.cc-bo-primary:hover { filter: brightness(1.08); }
.cc-bo-ghost { border: 1px solid var(--gc-hair-2); background: transparent; color: #cfd5e2; }
.cc-bo-ghost:hover { background: var(--gc-btn-h); color: #fff; }
.cc-bo-primary.busy, .cc-bo-ghost.busy, .cc-bo-primary[disabled], .cc-bo-ghost[disabled] { opacity: .55; pointer-events: none; }

/* Баннер перехода: действие уже началось — человек это ВИДИТ (никаких «мёртвых» пауз). */
.cc-bo-banner {
  position: absolute; left: 50%; top: 74px; transform: translateX(-50%); z-index: 30;
  display: inline-flex; align-items: center; gap: 10px; padding: 10px 16px;
  background: var(--cm-161921-94, rgba(22,25,33,.94)); border: 1px solid var(--gc-hair-2); border-radius: 999px;
  color: #e6e9ef; font-size: 13px; font-weight: 600; white-space: nowrap;
  box-shadow: 0 22px 54px -22px rgba(0,0,0,.8);
  animation: ccPanelIn var(--dur-2) var(--ease) both;
}
.cc-bo-spin {
  width: 14px; height: 14px; flex: 0 0 auto; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.22); border-top-color: var(--primary-2);
  animation: ccSpin .8s linear infinite;
}
@keyframes ccSpin { to { transform: rotate(360deg); } }

/* Постоянный чип «Комната 2 · вернуться» — видно, что ты НЕ в общем зале. */
.cc-bo-chip {
  position: absolute; left: 16px; top: calc(env(safe-area-inset-top) + 14px); z-index: 26;
  display: inline-flex; align-items: center; gap: 8px; padding: 6px 6px 6px 11px;
  background: color-mix(in srgb, var(--primary) 20%, transparent); border: 1px solid var(--cm-8b9cf5-42, rgba(139,156,245,.42)); border-radius: 999px;
  color: var(--cm-dfe4ff, #dfe4ff); font-size: 12.5px; font-weight: 600;
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  box-shadow: 0 14px 34px -16px rgba(0,0,0,.7);
}
.cc-bo-chip svg.ic { width: 15px; height: 15px; opacity: .9; }
.cc-bo-chip-t { font-variant-numeric: tabular-nums; opacity: .78; }
.cc-bo-chip-b {
  border: 0; border-radius: 999px; padding: 5px 11px; cursor: pointer;
  background: rgba(255,255,255,.14); color: #fff; font-size: 12px; font-weight: 600;
  transition: background var(--dur-1) var(--ease);
}
.cc-bo-chip-b:hover { background: rgba(255,255,255,.26); }

/* ── ПРОСТРАНСТВО ЗВУКА ───────────────────────────────────────────────────────── */
/* 🔴 Ширина — СТАРТОВАЯ, а не прибитая: панель зарегистрирована в WIN_PANES и тянется
   мышью, ширина помнится (правило «ни одной прибитой ширины», CRMC-406). */
.cc-prox {
  position: absolute; right: 14px; top: 62px; z-index: 13;
  width: min(340px, 92vw); display: flex; flex-direction: column;
  background: var(--cm-12151c-94, rgba(18,21,28,.94)); border: 1px solid var(--gc-hair-2); border-radius: 16px;
  -webkit-backdrop-filter: blur(18px) saturate(1.3); backdrop-filter: blur(18px) saturate(1.3);
  box-shadow: 0 28px 70px -26px rgba(0,0,0,.75);
  overflow: hidden; animation: ccPanelIn var(--dur-2) var(--ease) both;
}
.cc-prox-map {
  position: relative; margin: 13px; aspect-ratio: 1 / 1; border-radius: 14px;
  background:
    radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--primary) 16%, transparent), transparent 62%),
    repeating-linear-gradient(0deg, rgba(255,255,255,.045) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, rgba(255,255,255,.045) 0 1px, transparent 1px 34px),
    var(--cm-12151c, #12151c);
  border: 1px solid var(--gc-hair-2); overflow: hidden; touch-action: none;
}
/* Круги слышимости вокруг СВОЕЙ точки: внутренний — полная громкость, внешний — граница
   тишины. Без них «почему меня не слышно» приходится угадывать (ЗВОН-608). Радиус задаётся
   инлайн в % от ширины карты, а карта квадратная — значит круг остаётся кругом на любой
   ширине окна (правило «размеры — доля от ширины, не px»). */
.cc-prox-ring {
  position: absolute; aspect-ratio: 1 / 1; border-radius: 50%;
  transform: translate(-50%, -50%); pointer-events: none;
  transition: left var(--dur-1) var(--ease), top var(--dur-1) var(--ease);
}
.cc-prox-ring.far { border: 1px dashed var(--cm-7892ff-34, rgba(120,146,255,.34)); background: color-mix(in srgb, var(--primary) 7%, transparent); }
.cc-prox-ring.near { border: 1px solid var(--cm-7892ff-5, rgba(120,146,255,.5)); background: color-mix(in srgb, var(--primary) 16%, transparent); }
.cc-prox-empty {
  position: absolute; inset: auto 14px 14px; text-align: center;
  font-size: 11.5px; line-height: 1.4; color: #7f8798; pointer-events: none; opacity: 0;
  transition: opacity var(--dur-1) var(--ease);
}
.cc-prox-map.alone .cc-prox-empty { opacity: 1; }
.cc-prox-dot {
  position: absolute; width: 38px; height: 38px; margin: -19px 0 0 -19px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 12.5px; font-weight: 700; letter-spacing: .2px;
  box-shadow: 0 6px 18px -6px rgba(0,0,0,.7), 0 0 0 1px rgba(255,255,255,.14) inset;
  transition: box-shadow var(--dur-1) var(--ease), opacity var(--dur-1) var(--ease),
              left var(--dur-1) var(--ease), top var(--dur-1) var(--ease);
  cursor: default; user-select: none;
}
/* 🖼 Лицо кружка рисует канон `CallUi.face` (фото поверх букв, видео-аватар) — слой во весь
   кружок, чтобы фото легло ровно по кругу, а подпись `.cc-prox-nm` осталась снаружи. */
.cc-prox-ini {
  position: absolute; inset: 0; border-radius: 50%; overflow: hidden;
  display: flex; align-items: center; justify-content: center; pointer-events: none;
}
.cc-prox-ini .gt-av-vid { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
/* Не слышно — это состояние ОБЪЕКТА, а не цвет подписи: кружок гаснет и теряет заливку. */
.cc-prox-dot.mute { background-image: none !important; background-color: rgba(255,255,255,.1) !important; }
/* …у букв гаснет и заливка слоя лица; фото не снимаем (без него кружок был бы пуст) — серим. */
.cc-prox-dot.mute .cc-prox-ini:not(.photo) { background-image: none !important; background-color: transparent !important; }
.cc-prox-dot.mute .cc-prox-ini.photo, .cc-prox-dot.mute .cc-prox-ini .gt-av-vid { filter: grayscale(1); }
.cc-prox-dot.me { cursor: grab; touch-action: none; box-shadow: 0 0 0 2px #fff, 0 8px 22px -6px rgba(0,0,0,.75); }
.cc-prox-dot.me:active { cursor: grabbing; }
.cc-prox-nm {
  position: absolute; top: 100%; left: 50%; transform: translateX(-50%); margin-top: 4px;
  padding: 1px 7px; border-radius: 999px; white-space: nowrap;
  background: rgba(8,10,14,.72); color: #cfd5e2; font-size: 10.5px; font-weight: 600;
}
/* У самой кромки карты центрированная пилюля имени уезжала за границу (карта режет по
   overflow) — и человек, ушедший в угол, читал у соседа «· не слышно» без имени. */
.cc-prox-dot.edge-l .cc-prox-nm { left: -4px; transform: none; }
.cc-prox-dot.edge-r .cc-prox-nm { left: auto; right: -4px; transform: none; }
.cc-prox-dot.edge-b .cc-prox-nm { top: auto; bottom: 100%; margin: 0 0 4px; }
.cc-prox-hint { padding: 0 14px 13px; font-size: 11.5px; line-height: 1.45; color: #8b93a3; }
/* 📞 Кружок в карточке «Приглашение в созвон» — дверь `ccAvatarFace` (CLIE-903): слои
   `.cc-av-ini`/`.cc-av-img` лежат `position:absolute; inset:0`, поэтому здесь —
   позиционирующий родитель с обрезкой. Цвет букв и заливки приходит от двери (ccMonoStyle). */
.inv-av {
  position: relative; overflow: hidden; flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; color: #fff;
}

/* ── ДОКУМЕНТ РЯДОМ СО СЦЕНОЙ ─────────────────────────────────────────────────── */
/* 🔴 Пристыковка — ТОЛЬКО геометрия: iframe жив, сессия соредактирования OnlyOffice
   (соавторы, курсоры, автосейв) продолжается — ровно как у .dv-min. */
#docViewer.dv-docked { background: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; padding: 0; justify-content: flex-end; pointer-events: none; }
#docViewer.dv-docked .docviewer-box {
  pointer-events: auto;
  width: min(56vw, 900px); height: calc(100dvh - 24px); margin: 12px 12px 12px 0;
  border-radius: 16px; border: 1px solid var(--line);
  box-shadow: var(--shadow-3);
}
@media (max-width: 900px) {
  #docViewer.dv-docked .docviewer-box { width: calc(100vw - 24px); height: 52dvh; margin: 12px; align-self: flex-end; }
}
.groupcall-overlay.cc-doc-docked .gc-stage { padding-right: min(56vw, 900px); transition: padding-right var(--dur-2) var(--ease); }
@media (max-width: 900px) { .groupcall-overlay.cc-doc-docked .gc-stage { padding-right: 22px; padding-bottom: 52dvh; } }

.cc-doc-chip {
  position: absolute; left: 50%; transform: translateX(-50%); top: calc(env(safe-area-inset-top) + 14px); z-index: 26;
  display: inline-flex; align-items: center; gap: 9px; padding: 6px 6px 6px 12px; max-width: min(560px, 92vw);
  background: var(--cm-161921-92, rgba(22,25,33,.92)); border: 1px solid var(--gc-hair-2); border-radius: 999px;
  color: #e6e9ef; font-size: 12.5px; font-weight: 600;
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  box-shadow: 0 18px 44px -20px rgba(0,0,0,.75);
  animation: ccPanelIn var(--dur-2) var(--ease) both;
}
.cc-doc-chip svg.ic { width: 16px; height: 16px; opacity: .82; flex: 0 0 auto; }
.cc-doc-chip-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-doc-chip-b {
  flex: 0 0 auto; border: 0; border-radius: 999px; padding: 5px 12px; cursor: pointer;
  background: var(--acc-grad); color: #fff; font-size: 12px; font-weight: 600;
  transition: filter var(--dur-1) var(--ease);
}
.cc-doc-chip-b:hover { filter: brightness(1.08); }
.cc-doc-chip-x {
  flex: 0 0 auto; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  border: 0; border-radius: 50%; background: transparent; color: #8b93a3; cursor: pointer;
  transition: background var(--dur-1) var(--ease), color var(--dur-1) var(--ease);
}
.cc-doc-chip-x:hover { background: var(--gc-btn-h); color: #fff; }
.cc-doc-chip-x svg.ic { width: 14px; height: 14px; }

/* ── ВРЕЗКА ДОКЛАДЧИКА и «ВМЕСТЕ» — режимы существующей сетки, не вторая сетка ─── */
.cc-cameo-vid {
  position: absolute; right: 12px; bottom: 12px; z-index: 6;
  width: clamp(120px, 21%, 240px); aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: 50%; background: var(--cm-0b0d12, #0b0d12);
  box-shadow: 0 0 0 2px rgba(255,255,255,.22), 0 16px 40px -14px rgba(0,0,0,.85);
  transform: scaleX(-1);   /* врезка — «зеркало», как привычное селфи-превью */
  pointer-events: none;
}
.gtile:not(.gtile-local) .cc-cameo-vid { transform: none; }
.group-grid.cc-cameo .gtile.main { position: relative; }

/* «Вместе»: участники на ОДНОМ фоне — мягкие вырезы в ряд у общей нижней линии. */
.group-grid.cc-together {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: center;
  gap: 0 clamp(-28px, -2vw, -8px); width: 100%; height: 100%; padding: 0 18px 6px;
  background:
    radial-gradient(120% 70% at 50% 108%, color-mix(in srgb, var(--primary) 20%, transparent), transparent 62%),
    linear-gradient(180deg, var(--cm-10131a, #10131a) 0%, var(--cm-0b0d12, #0b0d12) 72%);
  border-radius: 18px; overflow: hidden;
}
.group-grid.cc-together > .gtile {
  flex: 0 1 clamp(120px, 17vw, 220px); width: auto; height: clamp(150px, 34vh, 300px);
  background: transparent; border: 0; border-radius: 0; overflow: visible;
}
/* 🎞️ ЗВОН-34 · ТЕНЬ «ЧЕЛОВЕКА НА ОБЩЕМ ФОНЕ» — СТАТИЧЕСКИМ СЛОЕМ, А НЕ ФИЛЬТРОМ НА ВИДЕО.
   Было `filter: drop-shadow(...)` прямо на `<video>` — и это самый дорогой путь во всём
   созвоне: drop-shadow строит силуэт по АЛЬФЕ элемента и размывает его, а альфу здесь
   задаёт маска-градиент. Значит форма тени ОДНА И ТА ЖЕ на любом кадре, но браузер
   честно пересчитывал размытие 30-60 раз в секунду поверх живого видео.
   Тот же овал, нарисованный мягким радиальным градиентом на `::after`, композитор
   растрирует ОДИН раз. Вуали в «Вместе» нет (её и раньше гасили) — слот свободен.
   Слой лежит ПОД кадром: `::after` позиционирован, поэтому кадру даём `z-index: 1`
   (аватар z-index 1 идёт после него в DOM, подпись/эквалайзер 3-4 — порядок сохранён). */
.group-grid.cc-together > .gtile::after {
  display: block; inset: 0; z-index: 0; will-change: opacity;
  transform: translateY(12px);
  background: radial-gradient(58% 46% at 50% 38%, rgba(0,0,0,.5) 46%, rgba(0,0,0,0) 100%);
}
/* Камера выключена — видео скрыто, силуэту неоткуда взяться: раньше drop-shadow тоже
   ничего не рисовал (фильтр на display:none), у кружка своя тень ниже. */
.group-grid.cc-together > .gtile.cam-off::after { display: none; }
/* `> video` — кадр КАМЕРЫ (прямой ребёнок плитки); видео-аватар внутри `.gt-avatar` маску,
   `position: relative` и слой кадра не получает (жалоба №1, 16.10.2026). */
.group-grid.cc-together > .gtile > video {
  width: 100%; height: 100%; object-fit: cover; background: transparent;
  position: relative; z-index: 1;
  /* 🔴 МАСКА ОСТАЁТСЯ НА ВИДЕО ОСОЗНАННО, перенести её на плитку НЕЛЬЗЯ: маска родителя
     режет ВСЕХ потомков, а овал заканчивается на 84% высоты — подпись `.gname` внизу
     плитки исчезла бы целиком, эквалайзер и точка связи наверху выцвели бы наполовину.
     Обёртки только вокруг `<video>` в разметке нет и завести её здесь нельзя: плитку
     строит КАНОН (`CallUi.tile`, callui.js), один на все поверхности созвона, — своя
     вёрстка ради одного режима это ровно тот дубль, который канон и убирал.
     Поэтому стоимость ОГРАНИЧЕНА, а не убрана: `will-change` в `.gtile video`
     (callui.css) держит кадр отдельным слоем, и маска накладывается на этот слой, а не
     тянет за собой перерисовку всей плитки. Самое дорогое — drop-shadow — снято выше. */
  -webkit-mask-image: radial-gradient(58% 46% at 50% 38%, #000 62%, transparent 100%);
  mask-image: radial-gradient(58% 46% at 50% 38%, #000 62%, transparent 100%);
}
/* 🔴🔴 ПОКАЗ ЭКРАНА В «ВМЕСТЕ» — ЦЕЛИКОМ (ЗВОН-604·5, PTR-5). Правило выше (0,3,1) перебивало
   `.gtile.screen-share video { contain }` из callui.css (0,2,1): чужой экран обрезался `cover`,
   края уходили под овальную маску, и указка, нормированная к ЦЕЛОМУ кадру, ложилась мимо.
   Экран — не лицо: ни обрезки, ни маски. (Математика указки и сама теперь читает фактическую
   вписку через CcRoom.fitOf, но показывать человеку обрезанный экран нельзя в любом случае.) */
.group-grid.cc-together > .gtile.screen-share video {
  object-fit: contain; background: #000;
  -webkit-mask-image: none; mask-image: none;
}
.group-grid.cc-together > .gtile .gname {
  left: 50%; transform: translateX(-50%); bottom: 2px;
  background: rgba(8,10,14,.6); border-radius: 999px;
}
.group-grid.cc-together > .gtile .gt-avatar { box-shadow: 0 12px 26px -10px rgba(0,0,0,.7); }

/* ── Совместные поверхности не мешают мини-режиму и эфиру ─────────────────────── */
.groupcall-overlay.minimized #gcxInkBar,
.groupcall-overlay.minimized #gcxBoardPanel,
.groupcall-overlay.minimized #gcxCwPanel,
.groupcall-overlay.minimized #gcxBoPanel,
.groupcall-overlay.minimized #gcxProxPanel,
.groupcall-overlay.minimized #gcxBoBanner,
.groupcall-overlay.minimized #gcxDocChip,
.groupcall-overlay.minimized .cc-ink,
.groupcall-overlay.stream-mode #gcxCollabBtn,
.groupcall-overlay.stream-mode #gcxInkBar,
.groupcall-overlay.stream-mode #gcxBoardPanel,
.groupcall-overlay.stream-mode #gcxCwPanel,
.groupcall-overlay.stream-mode #gcxBoPanel,
.groupcall-overlay.stream-mode #gcxProxPanel { display: none !important; }
/* в мини чип комнаты остаётся (он и есть напоминание «ты в подгруппе»), но компактнее */
.groupcall-overlay.minimized .cc-bo-chip { left: 8px; top: 8px; padding: 3px 4px 3px 8px; font-size: 11px; }
.groupcall-overlay.minimized .cc-bo-chip svg.ic { width: 12px; height: 12px; }
.groupcall-overlay.minimized .cc-bo-chip-b { padding: 3px 8px; font-size: 11px; }

/* ══ ТЕ ЖЕ ПОВЕРХНОСТИ В ЗВОНКЕ 1-НА-1 (ЗВОН-24) ═══════════════════════════════════
   Второй разметки и второго движка нет: узлы создают ТЕ ЖЕ функции, а вешаются они в
   .call-box активного оверлея (gcxSurfaceBox — брат gcxMount). Здесь только «одежда»
   под другую раму: у звонка нет сетки плиток, зато есть нижний ряд .call-controls,
   превью-уголок и режим PiP. */
.call-overlay .cc-inkbar { bottom: calc(env(safe-area-inset-bottom) + 104px); }
.call-overlay .cc-board { top: calc(env(safe-area-inset-top) + 62px); bottom: calc(env(safe-area-inset-bottom) + 104px); }
.call-overlay.cc-board-open:not(.minimized) .videos { opacity: .12; filter: saturate(.6); transition: opacity var(--dur-2) var(--ease); }
.call-overlay .cc-watch { top: calc(env(safe-area-inset-top) + 62px); }
/* Документ пристыкован → кадр звонка ужимается ровно так же, как зал конференции. */
.call-overlay.cc-doc-docked:not(.minimized) .videos { right: min(56vw, 900px); transition: right var(--dur-2) var(--ease); }
@media (max-width: 900px) { .call-overlay.cc-doc-docked:not(.minimized) .videos { right: 0; bottom: 52dvh; } }
/* 🔴 Свёрнутый в плашку звонок (150px) поверхностей не показывает — тот же урок, что у
   .gcx-panel-open: класс со свёрнутого звонка не снимается, а рисовать в PiP нечего. */
.call-overlay.minimized #gcxInkBar,
.call-overlay.minimized #gcxBoardPanel,
.call-overlay.minimized #gcxCwPanel,
.call-overlay.minimized #gcxDocChip,
.call-overlay.minimized .cc-ink { display: none !important; }
/* Аннотации над СВОИМ показом экрана: превью-уголок 32%/150px — не холст. На время
   рисования сцена меняется местами: свой экран во всю коробку, собеседник — уголком.
   🔴 ЗВОН-693: ЭТОГО ПРАВИЛА ЗДЕСЬ БОЛЬШЕ НЕТ, и не потому, что фича ушла, а потому, что
   это была ВТОРАЯ копия геометрии врезки — причём МЁРТВАЯ. Она двигала `<video>`, а после
   CLIE-606·5 он лежит внутри плитки и занимает её целиком (`position: static`), то есть
   `top/right/width` ему ничего не делали: свой экран крупно НЕ разворачивался, собеседник
   уголком НЕ становился. Теперь обмен местами — ОДНА дверь `ccSelfViewSwap(on, "ink")`,
   та же, которой человек меняет кадры пальцем, и работает она через роли `.cc-stage` /
   `.cc-inset` выше. Класс `cc-ink-own` остаётся признаком «рисуем над своим экраном». */

@media (prefers-reduced-motion: reduce) {
  /* `.cc-inkbar`, `.cc-board`, `.cc-ink-b`, `.cc-ink-c` сняты отсюда вместе со своими
     правилами: их «без движения» живёт в `/app/ccroom.css`, чтобы доехало и до гостя. */
  .cc-watch, .cc-bo, .cc-prox, .cc-bo-banner, .cc-doc-chip { animation: none; }
  .cc-bo-step button, .cc-bo-primary, .cc-bo-ghost,
  .cc-watch-url, .cc-watch-go, .cc-doc-chip-b, .cc-doc-chip-x, .cc-bo-chip-b,
  .cc-prox-dot, .groupcall-overlay.cc-doc-docked .gc-stage { transition: none; }
  .cc-bo-spin { animation: none; border-top-color: rgba(255,255,255,.5); }
}


/* ══ ЕДИНЫЙ БЛОК «ИИ» (0396 «Отображение элементов») ═══════════════════════════════════════
   Владелец: «много полей связанных с ИИ — объединим в один блок, чтобы не загрязняли
   пространство; а если у человека нет своего ИИ / MCP / чужого разрешённого — не показывать
   вовсе». Карточка задачи: одна сворачиваемая секция вместо 5 строк вперемешку со «Сроком»
   и «Приоритетом» + «Чей ИИ выполнит» из «Участников». Реюз идиомы «Знаний по задаче»
   (.td-mem-toggle) — заголовок-кнопка + шеврон, состояние в localStorage. */
.tip-ai-toggle { border: 0; background: none; font: inherit; cursor: pointer; text-align: left;
  /* `font: inherit` сбрасывает и размер/жирность — возвращаем типографику .td-section-h,
     чтобы шапка «ИИ» была ОДИН-В-ОДИН как «Свойства»/«Напоминания», а не крупнее.
     Габариты строки (высота/поля/ховер) — общий .tip-disc-h ниже. */
  font-size: 12px; font-weight: 700; }
/* Превью дублирует то, что и так видно в раскрытых строках («Модель ИИ», «Полноценный подход»),
   поэтому в раскрытом виде его прячем — паритет с Flutter (`if (!open && preview != null)`)
   и durable-правило «не отбирать экран»: подпись нужна ровно тогда, когда содержимое скрыто. */
.tip-ai-toggle:not(.collapsed) .tip-ai-pv { display: none; }
.tip-ai-toggle .tip-ai-lbl { flex: 0 0 auto; }
/* Превью в шапке: свёрнутая секция обязана сама сказать, что внутри (модель или состояние
   прогона) — иначе «свернули» читается как «спрятали функционал». */
.tip-ai-toggle .tip-ai-pv { margin-left: 2px; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: 12.5px; font-weight: 500; letter-spacing: 0; text-transform: none;
  color: var(--muted); }
.tip-ai-toggle .tip-ai-chev { margin-left: auto; padding-left: 8px; display: inline-flex; align-items: center;
  transition: transform .16s ease; opacity: .7; }
.tip-ai-toggle .tip-ai-chev svg { width: 14px; height: 14px; }
.tip-ai-toggle.collapsed .tip-ai-chev { transform: rotate(-90deg); }
.tip-ai-toggle:hover { color: var(--primary); }
.tip-ai-toggle:hover .tip-ai-pv { opacity: .85; }
.tip-ai-toggle:hover .tip-ai-chev { opacity: 1; }
.tip-ai-toggle:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent);
  outline-offset: 2px; border-radius: 4px; }
/* шеврон замыкает строку справа — отдельный ::after-хэйрлайн секции лишний (как у .td-mem-toggle) */
.task-info-panel .td-section-h.tip-ai-toggle::after,
.tip-ai-toggle.td-section-h::after { content: none; }
.tip-ai-body[hidden] { display: none !important; }
.tip-ai-body { display: flex; flex-direction: column; gap: 10px; }

/* ══ СТРОКА-РАСКРЫТИЕ (.tip-disc-h) — ОДНА реализация для всех сворачиваемых шапок карточки ══
   Владелец по «ИИ»: «очень узкое по высоте пространство, сложно нажать». И правда: шапка была
   голым текстом — измерено на проде `getBoundingClientRect().height` = 14px у «ИИ» и 16px у
   «Знаний по задаче», кликать в такую полоску мышью больно, пальцем — невозможно (Apple HIG
   требует ≥44pt; у нас во Flutter та же строка давно 52px — веб просто отставал).
   Стало: настоящая строка-кнопка 44px (48 на тач-устройствах), кликается ВСЯ ширина карточки —
   заголовок выпускается за паддинг .tip-card наружу отрицательными полями, поэтому визуально
   карточка не «раздувается» (свёрнутая 40 → 44px), а мишень растёт втрое.
   Новую сворачиваемую секцию карточки вешать НА ЭТОТ класс, а не копировать габариты. */
.tip-disc-h { display: flex; align-items: center; gap: 8px; width: auto; box-sizing: border-box;
  min-height: 44px; margin: 0 -8px; padding: 0 8px; border-radius: 10px;
  transition: background-color .14s ease, color .14s ease; }
/* Внутри .tip-card шапка выходит на самые края карточки (паддинг 12/13) — вся плитка кликается.
   display/gap продублированы с той же специфичностью, что и `.tip-card .td-section-h`
   (inline-flex, gap 6) и `.task-info-panel .td-section-h` (gap 10) — иначе они перебивают базовый
   класс и строка снова «схлопывается» по ширине содержимого. */
.tip-card > .tip-disc-h { display: flex; gap: 8px; margin: -12px -13px 0; padding: 0 13px;
  border-radius: 13px 13px 0 0; }
/* Список «Знаний» уже отделён хэйрлайном шапки — двойной отступ (gap карточки + margin) не нужен. */
.tip-card > .tip-disc-h + .td-mem-list { margin-top: 0; }
/* Свёрнутая секция = ровно одна строка: съедаем и нижний паддинг, карточка становится кнопкой. */
.tip-card > .tip-disc-h.collapsed { margin-bottom: -12px; border-radius: 13px; }
/* Раскрытая — тонкий хэйрлайн, чтобы шапка читалась как заголовок группы, а не как первая строка. */
.tip-card > .tip-disc-h:not(.collapsed) { box-shadow: inset 0 -1px 0 var(--line); }
.tip-disc-h:hover { background: color-mix(in srgb, var(--primary) 8%, transparent); }
.tip-disc-h:active { background: color-mix(in srgb, var(--primary) 15%, transparent); }
@media (pointer: coarse) { .tip-disc-h { min-height: 48px; } }
@media (prefers-reduced-motion: reduce) { .tip-disc-h { transition: none; } }
/* «Чей ИИ выполнит» — значение-кнопка с аватаром: аватар в чипе меньше, чем в списке участников,
   иначе строка распухает выше соседних чипов («Модель ИИ», «Аккаунт ИИ» — 29px). */
.tip-aiexec-btn .tw-av { width: 18px; height: 18px; border-width: 1px; font-size: 9px; margin: 0; }
/* Инфо-«i» у подписи свойства — раньше был инлайн-стилем в разметке, теперь один класс. */
.tip-hint-i { display: inline-flex; align-items: center; margin-left: 3px; opacity: .45; cursor: help; }
.tip-hint-i svg.ic { width: 13px; height: 13px; }
.tip-hint-i:hover { opacity: .8; }

/* Обзор проекта: «Контекст для ИИ» + «Файлы для ИИ» + «Кто может отдавать в мой ИИ» были ТРЕМЯ
   отдельными карточками подряд — теперь один блок «ИИ» с тонкими подзаголовками-разделами. */
.v2ov-ai .v2ov-sub { font-size: 11px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); font-weight: 700; margin: 16px 0 10px; padding-top: 14px;
  border-top: 1px solid var(--line); }
.v2ov-ai .v2ov-sub:first-of-type, .v2ov-ai .v2ov-sub-first { margin-top: 0; padding-top: 0; border-top: 0; }

/* 🔴🔴 CLIE-659 · МЕТКА ОБЛАСТИ НАСТРОЙКИ («общее для проекта» / «только ваше»).
   В карточке «ИИ» рядом лежат ОБЩИЕ настройки проекта и ОДНА ЛИЧНАЯ («Кто может отдавать в
   мой ИИ» — у каждого участника свой список). Неподписанная строка читается как «наверное,
   такая же, как соседняя» — ровно отсюда вопрос владельца «у каждого свои настройки?».
   Тихая пилюля: капс подзаголовка снимаем (это ПОДПИСЬ, а не заголовок), личное — акцентом. */
.v2ov-scope { display: inline-block; vertical-align: 1px; margin-left: 6px; padding: 1px 7px;
  border-radius: 999px; font-size: 9.5px; font-weight: 600; letter-spacing: .02em;
  text-transform: none; line-height: 1.5; white-space: nowrap; cursor: help;
  color: var(--muted); background: color-mix(in srgb, var(--muted) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 20%, transparent); }
.v2ov-scope.mine { color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent); }

/* ══════════════════════════════════════════════════════════════════════════════════════
   🎯 ЛИДЫ — отдельная сущность (0177). Раздел «Лиды» в «Продажах»: доска своих столбиков,
   список, поток входящих, аналитика по источникам, карточка-шторка, настройки.
   Реюз каркаса .tasks-workspace / .tw-board / .tw-col / .tw-card / .deal-drawer / .crm-*.
   Токены — только переменные темы: одинаково вылизано в светлой и тёмной.
   ══════════════════════════════════════════════════════════════════════════════════════ */

/* — источник лида: чип с иконкой и цветом справочника — */
.lead-src { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; padding: 2px 7px 2px 5px;
  border-radius: var(--r-full); font-size: 11.5px; font-weight: 600; line-height: 1.5; flex: none;
  color: var(--lsrc, var(--muted));
  background: color-mix(in srgb, var(--lsrc, var(--muted)) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--lsrc, var(--muted)) 26%, transparent); }
.lead-src .ic { width: 12px; height: 12px; flex: none; }
.lead-src span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-src svg { width: 12px; height: 12px; flex: none; }
/* светлая: цвет канала затемнён до чернил (зелёный WhatsApp, голубой «Сайт — чат» по белому — 2.1–3.0).
   Было только в «Глубине» — это дефект базы, теперь одно правило на оба шаблона. */
html[data-theme="light"] .lead-src[style*="--lsrc"],
html[data-theme="light"] .crm-chip.lead-chip.active[style*="--lsrc"] { color: color-mix(in srgb, var(--lsrc) 55%, #000); }

/* — панель фильтров: минимум по умолчанию — */
.lead-toolbar { flex-wrap: wrap; }
.lead-chips { display: flex; gap: 6px; flex-wrap: wrap; min-width: 0; }
/* группа «Источник» (leadToolbarHtml): в базе прозрачна — чипы остаются пунктами ленты, как были */
.lead-src-seg { display: contents; }
.crm-chip.lead-chip { display: inline-flex; align-items: center; gap: 5px; }
.crm-chip.lead-chip .ic, .crm-chip.lead-chip svg { width: 12px; height: 12px; opacity: .85; }
/* счётчик в чипе — те же чернила, что у чипа: opacity:.6 гасила цифру до 2.3–2.8:1 (замер 20.10) */
.crm-chip.lead-chip i { font-style: normal; font-size: 10.5px; font-weight: 700; }
.crm-chip.lead-chip.active { color: var(--lsrc, var(--primary-2));
  background: color-mix(in srgb, var(--lsrc, var(--primary)) 12%, transparent);
  border-color: color-mix(in srgb, var(--lsrc, var(--primary)) 40%, var(--line)); }
.lead-filter { flex: none; }
.lead-filter.on { color: var(--primary-2); border-color: color-mix(in srgb, var(--primary) 42%, var(--line)); }
/* Счётчик найденного + сумма выборки в тулбаре сделок (CRMC-408). */
.crm-tb-sum { flex: none; font-size: 12.5px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.tc-pop-sep { height: 1px; margin: 6px 8px; background: var(--line); }
/* строка-подсказка справа в пункте поповера («Завтра утром → 13 авг, 10:00») и поле ввода */
.tc-pop-hint { margin-left: auto; padding-left: 10px; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.tc-pop-input { display: block; width: calc(100% - 16px); margin: 4px 8px 6px; padding: 7px 10px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); color: var(--text);
  font: inherit; font-size: 12.5px; box-sizing: border-box; transition: border-color 140ms ease; }
.tc-pop-input:focus { outline: none; border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); }
/* «Аналитика» применяет только источник — остальные фильтры там не рисуем, чипы во всю ширину */
.lead-toolbar.only-src .crm-chips { flex: 1 1 auto; }
.tc-pop-row.on { color: var(--primary-2); }
.tc-pop-row.on .ic { width: 14px; height: 14px; margin-left: auto; }

/* — доска лидов — */
.lead-board { padding-top: 10px; }
.lead-col .tw-col-head { gap: 8px; }
.lead-col.cat-qualified .tw-col-dot { box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 18%, transparent); }
.lead-card { display: flex; flex-direction: column; gap: 6px; }
.lead-card-top { display: flex; align-items: center; gap: 7px; min-width: 0; }
.lead-card-top .tw-card-title { flex: 1 1 auto; min-width: 0; }
.lead-card .lead-who { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-card .tw-card-foot { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lead-co { font-size: 11.5px; color: var(--text-dim); max-width: 130px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-amt { font-size: 11.5px; font-weight: 700; color: var(--text); }
.lead-amount-row { margin-top: 10px; }
.deal-reason-picked { font-size: 12.5px; font-weight: 600; color: var(--primary-2); margin-bottom: 4px; }
.lead-age { font-size: 11.5px; color: var(--muted); margin-left: auto; }
/* `.deal-num` тоже несёт `margin-left:auto` — второй «толкатель» в одной строке ломал ряд,
   когда пилюль много: номер уезжал на свою строку. В подвале карточки лида он просто последний. */
.lead-card .tw-card-foot .deal-num { margin-left: 0; }
.lead-card.rotting { border-color: color-mix(in srgb, var(--warning) 42%, var(--line)); }
/* лид требует человека (ждёт ответа / пора вернуться / ничей / молчит / завис) — тонкая метка
   слева, чтобы это читалось на доске одним взглядом, без чтения пилюль */
.lead-card.needs-me { border-left: 3px solid color-mix(in srgb, var(--warning) 75%, transparent); }
.lead-card.needs-me.has-unread { border-left-color: var(--danger); }

/* пустой столбик схлопнут в полосу: 4 из 6 столбиков «пусто» съедали весь экран.
   Тянем карточку → доска раскрывает их (цель для дропа обязана быть нормальной). */
/* 🔴🔴 «ВИЖУ СТОЛБИК» = «МОГУ СЮДА ПОЛОЖИТЬ» (CRMC-716). Замер на живом проде 16.09.2026
   (tools/crm_leads_prod.js, 1440×900): доска 666px, а цель для дропа у пустого столбика —
   44px (7%), у полного 42–55%. Человек целится в нарисованный прямоугольник и мажет — это
   и есть «не перетаскиваются по столбикам». Столбики досок CRM тянутся во всю высоту доски,
   а дроп слушает теперь весь .tw-col (crmBoardDnd в app.js): два конца одного лечения. */
/* `align-items: stretch` теперь у самой `.tw-board` (все доски), своё правило здесь не нужно. */
/* Столбик доски прямо в строке очереди: тот же силуэт «точка + имя», что в списке (CRMC-716). */
.lead-q-st { display: inline-flex; align-items: center; gap: 5px; flex: none; font-size: 11.5px; color: var(--muted); padding: 1px 7px 1px 5px; border-radius: 999px; background: var(--panel-2); border: 1px solid var(--line); max-width: 46%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-q-st i { width: 7px; height: 7px; border-radius: 50%; flex: none; }
/* Вход в карточку дела — видимая мишень в строке блока «Дела» (CRMC-716). Тот же силуэт и
   размер, что у соседей по строке (крестик), проявляется вместе с ними. */
.crm-act-go { flex: none; width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center; border: none; background: transparent; color: var(--muted); border-radius: 7px; cursor: pointer; transition: background .12s, color .12s; padding: 0; }
.crm-act-go:hover { background: var(--panel-2); color: var(--primary-2); }
.crm-act-go svg.ic { width: 16px; height: 16px; }
/* пустой столбец приглушён ЧЕРНИЛАМИ имени, а не прозрачностью: .7 гасила счётчик «0» до 3.9 (замер 20.10) */
.lead-col.is-empty { flex: 0 0 138px; min-width: 138px; }
.lead-col.is-empty .tw-col-head { padding-right: 10px; }
.lead-col.is-empty .tw-col-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; color: var(--muted); font-weight: 600; }
.lead-col.is-empty .tw-col-body { min-height: 44px; }
.lead-col.is-empty .tw-col-ph { display: none; }
.lead-board .tw-col { transition: flex-basis 160ms ease, min-width 160ms ease, opacity 160ms ease; }
.lead-board.dragging .lead-col.is-empty { flex: 1 1 0; min-width: 230px; opacity: 1; }
.lead-board.dragging .lead-col.is-empty .tw-col-ph { display: block; }

/* — список лидов (плотная таблица; сетка = head + rows) — */
.lead-list { padding: 8px 2px 40px; }
.lead-list-head, .lead-row { display: grid;
  grid-template-columns: 140px minmax(0, 1.5fr) 150px minmax(0, 1.1fr) minmax(0, .9fr) 130px 92px;
  gap: 12px; align-items: center; padding: 9px 12px; }
.lead-list-head { position: sticky; top: 0; z-index: 2; background: var(--bg); color: var(--muted);
  font-size: 11.5px; font-weight: 700; letter-spacing: .02em; border-bottom: 1px solid var(--line); }
.lead-row { border-bottom: 1px solid var(--line); cursor: pointer; transition: background 140ms ease; }
.lead-row:hover { background: var(--hover); }
.lead-row > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-row-st { display: inline-flex; align-items: center; gap: 7px; color: var(--text-dim); font-size: 12.5px; }
.lead-row-st i { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.lead-row-title { font-weight: 600; display: inline-flex; align-items: center; gap: 6px; }
.lead-row-contact, .lead-row-co, .lead-row-owner, .lead-row-when { color: var(--muted); font-size: 12.5px; }

/* ══ ОЧЕРЕДЬ ЛИДОВ — «кому ответить сейчас»: слева очередь с причиной, справа живая
   переписка и поле ответа. Заменила ленту «Поток», из которой ответ УВОДИЛ в чаты. ══ */
/* 🔴 Ширина колонки очереди ТЯНЕТСЯ мышью (WIN_PANES → `.lead-queue > .lead-q-list`), поэтому
   трек грида равен ширине самого списка (`auto`), а не прибитому числу: движок пишет ширину
   инлайном списку, и колонка следует за ним. Правило продукта «ни одной прибитой ширины». */
.lead-queue { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px;
  height: calc(100% - 6px); min-height: 420px; padding: 8px 2px 10px; }
/* 🔴🔴 CRMC-702 · ОЧЕРЕДЬ ВЛЕЗАЕТ В ОКНО (владелец 13.09.2026, кадр очереди лидов:
   «Верстка, не влезает» — у правой половины обрезано нижним краем экрана ПОЛЕ ОТВЕТА,
   видна только верхняя кромка рамки).
   ПРИЧИНА ТА ЖЕ, ЧТО У ДОСКИ (CLIE-1030·R3): тулбар с поиском и фильтрами лежит В ТОМ ЖЕ
   прокручиваемом теле раздела (`#salesBody.tw-body`), что и сама очередь. Значит
   `height: calc(100% - 6px)` у очереди читается как «весь экран ПЛЮС тулбар»: замер на
   проде 12.09 — тело 725px, содержимое 780px, лишние 55px = тулбар 61px минус те самые 6px;
   низ очереди уезжал на y=947 при окне 900. Композер физически оказывался под краем окна.
   ЛЕЧЕНИЕ — то же РАЗДЕЛЕНИЕ РОЛЕЙ, а не «число поменьше»: тело раздела на этом виде
   становится КОЛОНКОЙ, тулбар стоит своей высотой, очередь забирает ОСТАТОК. Класс вешает
   тот, кто нарисовал очередь (`renderLeadsFlow`), — как у доски, а не CSS по имени страницы.
   Ниже 1080px раскладка складывается в один столбик и прокручивается телом раздела, поэтому
   колоночный режим действует только на широком экране.
   🔴 ОКНО БЫВАЕТ НИЖЕ, ЧЕМ НУЖНО ПЕРЕПИСКЕ (замер под А+, окно 960×600): шапка лида 118 +
   шапка беседы 56 + композер 145 = 319px, и это МИНИМУМ, ниже которого поле ответа обрезает
   уже сама панель. Поэтому очередь не сжимается ниже `min-height` (наследуется 420px из
   правила выше) и тело раздела оставлено ПРОКРУЧИВАЕМЫМ (`overflow` базовый — `auto`):
   в низком окне человек честно доскроллит, а не увидит обрезанный композер. Тулбар при этом
   остаётся `sticky` (у очереди нет горизонтальной прокрутки, из-за которой доска CLIE-1030·R3
   вынуждена была делать его `static`). */
@media (min-width: 1081px) {
  .tw-body.tw-body-queue { display: flex; flex-direction: column; }
  .tw-body.tw-body-queue > .crm-toolbar { flex: 0 0 auto; }
  .tw-body.tw-body-queue > .lead-queue { flex: 1 1 auto; height: auto; }
}
.lead-queue > .lead-q-list { width: 380px; min-width: 240px; max-width: 620px; }
.lead-q-list { overflow: auto; display: flex; flex-direction: column; gap: 6px; padding-right: 2px; outline: none; }
.lead-q-list:focus-visible { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--primary) 34%, transparent); border-radius: 14px; }
.lead-q-h { display: flex; align-items: center; gap: 8px; padding: 10px 6px 2px; font-size: 11.5px;
  font-weight: 700; letter-spacing: .02em; color: var(--muted); text-transform: uppercase; }
.lead-q-h i { font-style: normal; font-weight: 700; font-variant-numeric: tabular-nums; }
.lead-q-h.hot { color: var(--danger); }
.lead-q-row { display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  transition: border-color 140ms ease, background 140ms ease, box-shadow 140ms ease; }
.lead-q-row:hover { border-color: var(--line-strong); background: var(--hover); }
.lead-q-row.hot { border-left: 3px solid var(--danger); padding-left: 10px; }
.lead-q-row.sel { border-color: color-mix(in srgb, var(--primary) 55%, var(--line));
  background: color-mix(in srgb, var(--primary) 7%, var(--panel)); box-shadow: var(--shadow-1); }
.lead-q-av { width: 30px; height: 30px; border-radius: 10px; flex: none; display: grid; place-items: center;
  background: var(--panel-2); color: var(--muted); border: 1px solid var(--line); }
.lead-q-av .ic, .lead-q-av svg { width: 15px; height: 15px; }
.lead-q-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.lead-q-t { display: flex; align-items: center; gap: 6px; min-width: 0; }
.lead-q-title { font-weight: 650; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-q-row.has-unread .lead-q-title { font-weight: 750; }
.lead-q-rs { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.lead-q-sub { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-q-when { flex: none; font-size: 11.5px; color: var(--muted); padding-top: 2px; }
.lead-q-none { padding-top: 8px; }

/* правая половина — карточка-шапка + ЖИВОЙ тред мессенджера */
.lead-q-panel { display: flex; flex-direction: column; min-width: 0; min-height: 0;
  background: var(--panel); border: 1px solid var(--line); border-radius: 18px; overflow: hidden; }
.lead-q-ph { padding: 12px 14px 10px; border-bottom: 1px solid var(--line); display: flex; flex-direction: column; gap: 8px; }
.lead-q-ph-t { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 15px; }
.lead-q-ph-t b { font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-q-ph-m { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; color: var(--muted); }
.lead-q-ow.none { color: var(--warning); }
.lead-q-acts { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.lead-q-acts > button { display: inline-flex; align-items: center; gap: 6px; flex: none; white-space: nowrap; }
.lead-q-sp { flex: 1 1 auto; min-width: 0; }
.lead-q-chat { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
/* Тот же контракт хоста, что у карточки лида/сделки/клиента: живой <main.thread> переезжает
   сюда как есть, поэтому и правила те же (одна реализация переписки на весь продукт). */
.lead-q-host { display: flex; flex: 1 1 auto; min-height: 0; flex-direction: column; overflow: hidden; }
/* Пустой хост не должен занимать пол-экрана: пока треда нет (открываю / беседы ещё нет /
   вас нет в беседе) — место отдаём объяснению, а не пустоте. */
.lead-q-host:empty { flex: none; height: 0; }
.lead-q-host > main.thread { display: flex; flex: 1 1 auto; min-height: 0; width: auto; }
.lead-q-host .thread-head { padding-left: 14px; }
.lead-q-host #backToList { display: none !important; }
.lead-q-slot:not(:empty) { padding: 14px; }
.lead-q-empty { flex: 1 1 auto; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 40px 24px; text-align: center; color: var(--muted); }
.lead-q-empty .ic, .lead-q-empty svg { width: 26px; height: 26px; color: var(--ok); }
.lead-q-empty b { font-size: 15px; color: var(--text); font-weight: 650; }
.lead-q-empty span { font-size: 12.5px; max-width: 360px; line-height: 1.5; }
/* 🔒 CLIE-1471 · ОТКАЗ В ПАНЕЛИ ОЧЕРЕДИ — тот же спокойный тон, что у `.tw-empty.denied`
   (CLIE-1454): это НЕ авария и НЕ «всё разобрано». Зелёная галочка «готово» тут была бы
   вторым враньём поверх первого, поэтому у замка нейтральные чернила. Цвета — ролями темы:
   светлая и тёмная получаются сами, второго набора прибитых значений нет. */
.lead-q-empty.denied .ic, .lead-q-empty.denied svg { color: var(--muted); }
/* 🔒 Все лиды очереди — из неоплаченных пространств: это не «разобрано», а «ждёт оплаты». */
.lead-q-empty.paylock svg { color: var(--danger); }
.lead-q-empty .se-acts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 4px; }
/* 🔒 CLIE-1471 · ОДНА ПЛАШКА НА ЭКРАН: под отказом список молчит (строк нет и не будет),
   говорит панель — и занимает всю ширину, чтобы рядом не стояла мёртвая пустая колонка. */
.lead-queue.solo { grid-template-columns: minmax(0, 1fr); }
.lead-queue.solo > .lead-q-list { display: none; }
@media (max-width: 1080px) {
  .lead-queue { grid-template-columns: minmax(0, 1fr); height: auto; }
  .lead-q-panel { min-height: 460px; }
}
/* leads-cards-overflow-1 · телефон: колонка очереди 380 px (min 240) шире плиты лидов — карточки
   уезжали за правую кромку, левый край стоял в 2 px от неё. Список — во всю ширину, поля — по тулбару. */
@media (max-width: 760px) {
  .lead-queue { padding: 8px 16px 10px; }
  .lead-queue > .lead-q-list { width: auto; min-width: 0; max-width: none; }
}
@media (max-width: 560px) { .lead-queue { padding-inline: 12px; } }

/* — аналитика лидов — */
.lead-an { padding-bottom: 48px; }
.lead-an-period button { min-width: 62px; }
.lead-an-table { background: var(--panel); border: 1px solid var(--line); border-radius: 16px; overflow: hidden; }
.lead-an-row { display: grid; grid-template-columns: minmax(140px, 1.1fr) minmax(80px, 1.6fr) 64px 64px 56px 92px;
  gap: 12px; align-items: center; padding: 10px 16px; border-top: 1px solid var(--line); cursor: pointer;
  transition: background 140ms ease; }
.lead-an-row:first-child { border-top: 0; }
.lead-an-row:hover:not(.head) { background: var(--hover); }
.lead-an-row.head { cursor: default; color: var(--muted); font-size: 11.5px; font-weight: 700; }
.lead-an-row.head:hover { background: transparent; }
.lead-an-name { display: inline-flex; align-items: center; gap: 8px; min-width: 0; font-size: 13px; }
.lead-an-name b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-an-name .ic, .lead-an-name svg { width: 14px; height: 14px; flex: none; opacity: .8; }
.lead-an-bar { display: block; height: 8px; border-radius: var(--r-full); background: var(--panel-2); overflow: hidden; }
.lead-an-bar i { display: block; height: 100%; border-radius: var(--r-full); transition: width 200ms ease; }
.lead-an-n, .lead-an-c, .lead-an-w, .lead-an-t { text-align: right; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.lead-an-n { font-weight: 700; }
.lead-an-c, .lead-an-w, .lead-an-t { color: var(--muted); }
.lead-an-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; }
.lead-an-minis { display: flex; flex-direction: column; gap: 6px; }
.lead-an-mini { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: var(--panel);
  border: 1px solid var(--line); border-radius: 12px; font-size: 12.5px; }
.lead-an-mini b { font-weight: 600; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-an-mini span { font-weight: 700; font-variant-numeric: tabular-nums; }
.lead-an-mini i { font-style: normal; color: var(--muted); font-size: 11.5px; }
.lead-an-none { color: var(--muted); font-size: 12.5px; }
.lead-an-warn { display: inline-flex; align-items: center; gap: 8px; margin-top: 16px; padding: 9px 14px;
  border-radius: 12px; background: var(--warning-soft); color: var(--warning); font-size: 12.5px; }
.lead-an-warn .ic { width: 14px; height: 14px; }
.fc-card.warn { border-color: color-mix(in srgb, var(--warning) 40%, var(--line)); }

/* — карточка лида (страница «рабочее место», см. блок `.crm-page`) — */
.lead-title { flex: 1 1 auto; min-width: 0; }
.lead-conv-note { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 12px;
  background: var(--ok-soft); color: var(--ok); font-size: 12.5px; margin-bottom: 14px; }
.lead-conv-note .ic { width: 14px; height: 14px; }
.lead-conv-note .link { background: none; border: 0; padding: 0; color: inherit; font: inherit;
  text-decoration: underline; cursor: pointer; }
.lead-dups { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 9px 12px; border-radius: 12px;
  background: var(--warning-soft); color: var(--warning); font-size: 12px; margin-bottom: 14px; }
.lead-dups .ic { width: 13px; height: 13px; }
/* «Объединить» — иконка и слово в строку, а не иконка над подписью (кадр лида 14.09.2026). */
.lead-dups button { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.lead-dup { background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-full);
  padding: 3px 10px; font-size: 11.5px; color: var(--text); cursor: pointer; transition: border-color 140ms ease; }
.lead-dup:hover { border-color: var(--line-strong); }
.lead-utm { display: flex; flex-direction: column; gap: 4px; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 12px; padding: 10px 14px; }
.lead-utm-row { display: flex; gap: 12px; font-size: 12px; }
.lead-utm-row span { color: var(--muted); min-width: 84px; flex: none; }
.lead-utm-row b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-owner-pick { background: var(--input-bg); border: 1px solid var(--line); border-radius: 10px;
  padding: 7px 11px; color: var(--text); font: inherit; font-size: 13px; text-align: left; cursor: pointer;
  transition: border-color 140ms ease; }
.deal-owner-pick:hover { border-color: var(--line-strong); }

/* — настройки: свои столбики и справочник источников — */
.lead-cfg { display: flex; flex-direction: column; gap: 6px; margin: 6px 0 10px; }
.lead-cfg-row { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--panel); }
.lead-cfg-row:hover { border-color: var(--line-strong); }
.lead-cfg-drag, .lead-cfg-ic { display: grid; place-items: center; width: 22px; color: var(--muted); flex: none; }
.lead-cfg-drag .ic, .lead-cfg-ic .ic, .lead-cfg-ic svg { width: 14px; height: 14px; }
.lead-cfg-color { width: 26px; height: 26px; padding: 0; border: 1px solid var(--line); border-radius: 8px;
  background: none; cursor: pointer; flex: none; }
.lead-cfg-name { flex: 1 1 auto; min-width: 0; background: transparent; border: 1px solid transparent;
  border-radius: 8px; padding: 5px 8px; color: var(--text); font: inherit; font-size: 13px; }
.lead-cfg-name:hover { border-color: var(--line); }
.lead-cfg-name:focus { border-color: color-mix(in srgb, var(--primary) 46%, var(--line)); background: var(--input-bg); outline: none; }
/* settings-select-nochevron-1 · шеврон берётся из общего списка селектов (рядом с #usersSort), а сокращение
   background его стирало. Здесь только цвет фона и место под шеврон: 138 − 2 − 7 − 28 = 101 ≥ «квалифицирован» 96 px. */
.lead-cfg-cat { flex: none; width: 138px; background-color: var(--input-bg); border: 1px solid var(--line);
  border-radius: 8px; padding: 5px 28px 5px 7px; background-position: right 9px center;
  color: var(--muted); font: inherit; font-size: 12px; }
/* settings-lead-cols-rot-unlabeled-1 · голое число «3» без единицы: смысл жил только в title (на касании не виден), а
   плейсхолдер «дн» пропадал у заполненного поля. Рамка — у обёртки (значок часов «залежался» + число + «дн»), поле
   внутри без своей рамки; кольцо фокуса ставит рамке общая дверь ccRingPlace. */
.lead-cfg-rotw { flex: none; display: inline-flex; align-items: center; gap: 4px; box-sizing: border-box; width: 84px;
  padding: 0 7px; background-color: var(--input-bg); border: 1px solid var(--line); border-radius: 8px;
  color: var(--muted); font-size: 12px; cursor: text; }
.lead-cfg-rotw > .ic { flex: none; width: 13px; height: 13px; }
.lead-cfg-rot { flex: 1 1 auto; align-self: stretch; width: 100%; min-width: 0; margin: 0; padding: 5px 0; border: 0;
  border-radius: 0; background-color: transparent; color: inherit; font: inherit; font-size: 12px; text-align: right;
  -moz-appearance: textfield; appearance: textfield; }
.lead-cfg-rot::-webkit-outer-spin-button, .lead-cfg-rot::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.lead-cfg-unit { flex: none; }
.lead-cfg-key { flex: none; font-size: 11px; color: var(--text-dim); font-family: ui-monospace, monospace; }
/* settings-lead-cols-rot-unlabeled-1 · счётчик был вторым голым числом рядом с замком: значок лидов (funnel — значок
   раздела «Лиды») и слово «лидов»; в узкой карточке слово уходит только с экрана (для чтения с экрана остаётся). */
.lead-cfg-n { flex: none; display: inline-flex; align-items: center; justify-content: flex-end; gap: 3px; min-width: 30px;
  text-align: right; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.lead-cfg-n > .ic { flex: none; width: 12px; height: 12px; }
.lead-cfg-sys { flex: none; display: grid; place-items: center; width: 26px; color: var(--text-dim); }
.lead-cfg-sys .ic { width: 13px; height: 13px; }
.lead-cfg-act { flex: none; display: inline-flex; align-items: center; cursor: pointer; }
.lead-cfg-act input { position: absolute; opacity: 0; pointer-events: none; }
.lead-cfg-act i { display: block; width: 30px; height: 18px; border-radius: var(--r-full); background: var(--seg-track);
  border: 1px solid var(--line); position: relative; transition: background 140ms ease, border-color 140ms ease; }
.lead-cfg-act i::after { content: ""; position: absolute; top: 1px; left: 1px; width: 14px; height: 14px;
  border-radius: 50%; background: var(--seg-thumb); box-shadow: var(--seg-thumb-sh); transition: transform 140ms ease; }
.lead-cfg-act input:checked + i { background: color-mix(in srgb, var(--primary) 62%, transparent);
  border-color: color-mix(in srgb, var(--primary) 62%, transparent); }
.lead-cfg-act input:checked + i::after { transform: translateX(12px); }
/* crm-settings-leadcols-overflow-1 · на узкой карточке ряд столбика не помещался: название сжималось в ноль,
   дни вылезали за край, счётчик и «Удалить» уходили за панель. Меряем сам список (@container), а не окно:
   ширину съедают рельс CRM и шторки; на десктопе (список 640–830 px) ряд остаётся одной строкой.
   settings-lead-cols-rot-unlabeled-1 · порог 520 → 600: в одной строке поле дней шире на 28 px (84 вместо 56), счётчик со
   словом шире на ≈ 32 — у названия на пороге остаётся прежний запас (≈ 150 px). */
.lead-cfg { container: leadcfg / inline-size; }
@container leadcfg (max-width: 600px) {
  /* Столбик: 1-я строка — ручка · цвет · название · счётчик · замок/корзина; 2-я — категория под ручкой,
     цветом и названием (так влезает «квалифицирован») · дни под счётчиком и корзиной. */
  .lead-cfg-row[data-lstid] { display: grid; grid-template-columns: 22px 26px minmax(0, 1fr) minmax(30px, auto) var(--ctl-h); gap: 6px 8px; }
  .lead-cfg-row[data-lstid] > .lead-cfg-name { grid-area: 1 / 3; }
  .lead-cfg-row[data-lstid] > .lead-cfg-n { grid-area: 1 / 4; }
  .lead-cfg-row[data-lstid] > :is(.lead-cfg-sys, .icon-btn) { grid-area: 1 / 5; justify-self: center; }
  .lead-cfg-row[data-lstid] > .lead-cfg-cat { grid-area: 2 / 1 / 3 / 4; }
  .lead-cfg-row[data-lstid] > .lead-cfg-rotw { grid-area: 2 / 4 / 3 / 6; min-width: 0; }
  /* Источник — тот же класс поломки: 1-я строка — значок · название · счётчик · замок/корзина;
     2-я — машинный ключ под названием · тумблер «предлагать» справа. */
  .lead-cfg-row[data-lsrcid] { display: grid; grid-template-columns: 22px minmax(0, 1fr) minmax(30px, auto) var(--ctl-h); gap: 6px 8px; }
  .lead-cfg-row[data-lsrcid] > .lead-cfg-name { grid-area: 1 / 2; }
  .lead-cfg-row[data-lsrcid] > .lead-cfg-n { grid-area: 1 / 3; }
  .lead-cfg-row[data-lsrcid] > :is(.lead-cfg-sys, .icon-btn) { grid-area: 1 / 4; justify-self: center; }
  .lead-cfg-row[data-lsrcid] > .lead-cfg-key { grid-area: 2 / 2; min-width: 0; padding-left: 9px; overflow-wrap: anywhere; }
  .lead-cfg-row[data-lsrcid] > .lead-cfg-act { grid-area: 2 / 3 / 3 / 5; justify-self: end; }
  .lead-cfg-row:is([data-lstid], [data-lsrcid]) > :is(.lead-cfg-name, .lead-cfg-cat, .lead-cfg-rotw) { width: 100%; }
  /* settings-lead-cols-rot-unlabeled-1 · в узкой карточке счётчик — значок и число (влезает в прежние 30 px при 1–2 цифрах,
     название «Квалифицирован» 105 px не теряет места); слово «лидов» остаётся для чтения с экрана и в title */
  .lead-cfg-n > .lead-cfg-nw { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  /* Поля ряда — высоты --ctl-h; корзина — квадрат --ctl-h без внутренних полей кнопки (видна и нажимается). */
  .lead-cfg-row > :is(.lead-cfg-name, .lead-cfg-cat, .lead-cfg-rotw) { height: var(--ctl-h); }
  .lead-cfg-row > .icon-btn { width: var(--ctl-h); height: var(--ctl-h); padding: 0; }
}
#leadEnginePane .sl-wrap { padding-top: 0; }

/* ══════════════════════════════════════════════════════════════════════════════════════
   ⏳ «ЧТО НАПИСАЛ ЧЕЛОВЕК» + «ЖДЁТ ОТВЕТА» (CRMC-29) — общий язык для карточки ЛИДА и
   СДЕЛКИ, списка и потока. Владелец: «как я узнаю, что он написал, а я не прочитал?».
   Визуальный язык — тот же, что в списке чатов: превью строкой, синий бейдж-счётчик,
   жирный заголовок у непрочитанного. Обе темы через токены (--primary/--danger/--warning).
   ══════════════════════════════════════════════════════════════════════════════════════ */
.cc-msg { display: flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%;
  padding: 5px 8px; border-radius: 10px; background: var(--panel-2); border: 1px solid var(--line);
  font-size: 12px; color: var(--text-dim); line-height: 1.35; }
.cc-msg .ic, .cc-msg svg { width: 13px; height: 13px; flex: none; color: var(--muted); }
.cc-msg-t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-msg-t b { font-weight: 650; color: var(--text); }
.cc-msg.unread { background: color-mix(in srgb, var(--primary) 9%, var(--panel-2));
  border-color: color-mix(in srgb, var(--primary) 26%, var(--line)); color: var(--text); }
.cc-msg.unread .ic, .cc-msg.unread svg { color: var(--primary-2); }
.cc-unread { flex: none; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--acc-fill); color: #fff; font-size: 11px; font-weight: 700; line-height: 18px;
  text-align: center; font-variant-numeric: tabular-nums; }
.cc-unread-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--primary); }
.tw-card.has-unread .tw-card-title, .lead-row.has-unread .lead-row-t1,
.lead-flow-row.has-unread .lead-flow-title { font-weight: 750; }

/* пилюля «ждёт 2 ч»: спокойная, пока в пределах порога, и красная — когда пора отвечать */
.cc-wait { display: inline-flex; align-items: center; gap: 4px; flex: none; padding: 1px 7px 1px 5px;
  border-radius: var(--r-full); border: 1px solid color-mix(in srgb, var(--warning) 32%, var(--line));
  background: var(--warning-soft); color: var(--warning-ink, var(--warning)); font-size: 11px; font-weight: 650;
  line-height: 1.55; white-space: nowrap; }
.cc-wait .ic, .cc-wait svg { width: 11px; height: 11px; }
/* 🔴 «Контрастность» 10.09.2026: цвет тревоги ЧЕРНИЛАМИ на её же тинте давал 4.02:1
   (тёмная) и 3.89:1 (светлая) при норме AA 4.5 — берём --danger-ink. */
.cc-wait.hot { border-color: color-mix(in srgb, var(--danger) 42%, var(--line));
  background: var(--danger-soft); color: var(--danger-ink, var(--danger)); }
/* CLIE-440: в списке чатов пилюля — КНОПКА «ответ не нужен» (кликом снимаем ожидание, не
   отвечая). Силуэт обязан остаться прежним: сбрасываем кнопочную геометрию и шрифт, добавляем
   только курсор и деликатный отклик — рядом с 📌/🔕/@ она не должна выглядеть кнопкой-кнопкой. */
button.cc-wait { font: inherit; font-size: 11px; font-weight: 650; margin: 0; cursor: pointer;
  -webkit-appearance: none; appearance: none; }
.conv-marks button.cc-wait { font-size: 10.5px; }
button.cc-wait:hover { border-color: color-mix(in srgb, var(--warning) 55%, var(--line)); }
button.cc-wait.hot:hover { border-color: color-mix(in srgb, var(--danger) 62%, var(--line)); }
button.cc-wait:active { transform: scale(.94); }
button.cc-wait:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.crm-chip.cc-chip-wait { color: var(--danger-ink, var(--danger)); border-color: color-mix(in srgb, var(--danger) 34%, var(--line)); }
.crm-chip.cc-chip-wait.active { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 52%, var(--line)); }
/* белая цифра — на ЗАЛИВКУ тревоги (--danger-fill), а не на её чернила: в тёмном Штиле было 3.06:1 */
.tw-seg-badge.hot { background: var(--danger-fill, var(--danger)); }
.tw-seg button.active .tw-seg-badge.hot { background: rgba(255, 255, 255, .92); color: var(--danger-fill, var(--danger)); }
/* тот же обмен цветами на вкладках разделов «Продажи» (`.cc-tabs`) — раньше правило висело
   только на `.tw-seg`, и на активной вкладке «Лиды» красный бейдж сливался с подсветкой */
.cc-tabs button.active .tw-seg-badge.hot { background: rgba(255, 255, 255, .92); color: var(--danger-fill, var(--danger)); }
.cc-seg > *.on .tw-seg-badge.hot, .cc-seg > *.active .tw-seg-badge.hot { background: rgba(255, 255, 255, .92); color: var(--danger-fill, var(--danger)); }

/* ⏰ ПРИЧИНЫ ОЧЕРЕДИ: тот же силуэт пилюли, свой тон. Ожидание — `.cc-wait` (жёлтый/красный),
   обещание «пора вернуться» — красное, «ничей» — жёлтое, «молчит»/«завис» — спокойные. */
.cc-wait.rz-followup { border-color: color-mix(in srgb, var(--danger) 42%, var(--line));
  background: var(--danger-soft); color: var(--danger-ink, var(--danger)); }
.cc-wait.rz-nobody { border-color: color-mix(in srgb, var(--warning) 40%, var(--line));
  background: var(--warning-soft); color: var(--warning-ink, var(--warning)); }
.cc-wait.rz-silent, .cc-wait.rz-stale { border-color: var(--line); background: var(--panel-2); color: var(--muted); }
/* спокойная пометка «напомню тогда-то» — обещание ещё впереди, тревожить не за что */
.lead-plan { display: inline-flex; align-items: center; gap: 4px; flex: none; padding: 1px 7px 1px 5px;
  border-radius: var(--r-full); border: 1px dashed var(--line-strong); color: var(--muted);
  font-size: 11px; font-weight: 600; line-height: 1.55; white-space: nowrap; }
.lead-plan .ic, .lead-plan svg { width: 11px; height: 11px; }

/* список: заголовок лида становится двухстрочным, когда есть сообщение клиента */
.lead-row-title { flex-direction: column; align-items: flex-start; gap: 4px; }
.lead-row-t1 { display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lead-row .cc-msg { max-width: 100%; }

/* настройки «Клиент ждёт ответа» */
.cc-set-row { display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 10px 0; border-top: 1px solid var(--line); }
.cc-set-row:first-of-type { border-top: 0; }
.cc-set-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.cc-set-txt b { font-size: 13.5px; font-weight: 600; color: var(--text); }
.cc-set-txt span { font-size: 12px; color: var(--muted); line-height: 1.35; }
.cc-set-num { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.cc-set-num input { width: 74px; text-align: right; }
.cc-set-num i { font-style: normal; font-size: 12px; color: var(--muted); }

/* «ждёт 2 ч» в СТРОКЕ ЧАТА: та же пилюля, но плотнее — рядом с @ и иконкой режима */
.conv-marks .cc-wait { padding: 0 6px 0 4px; font-size: 10.5px; line-height: 15px; height: 16px; }
.conv-marks .cc-wait .ic, .conv-marks .cc-wait svg { width: 10px; height: 10px; }

/* ═══════════════════════════════════════════════════════════════════════════
   💬 ЧАТ С КЛИЕНТОМ ВНУТРИ КАРТОЧКИ ЛИДА/СДЕЛКИ
   Сюда ФИЗИЧЕСКИ переезжает единый живой <main.thread> (та же реализация чата,
   что и на странице «Чаты» — не копия). Карточка лида в этот момент становится
   двухколонной: слева поля, справа полноценная переписка. Обе темы.
   ═══════════════════════════════════════════════════════════════════════════ */
/* 🔴 CRMC-36. Карточки ЛИДА и СДЕЛКИ больше не шторки: переписка у них — ОТДЕЛЬНАЯ КОЛОНКА
   полноэкранной страницы «рабочее место» (правила ниже, блок `.crm-page`). Здесь остались
   правила для карточки КЛИЕНТА/КОМПАНИИ — она по-прежнему шторка с секцией «Переписка». */
.crm-drawer.has-chat { width: min(700px, 96vw); }
.deal-drawer:not(.crm-page) .crm-chat-host { display: flex; flex-direction: column; min-height: 0; overflow: hidden;
  height: clamp(300px, 44vh, 520px); border: 1px solid var(--line); border-radius: 14px; background: var(--panel-2); }
/* Пустой хост не занимает места, но ОСТАЁТСЯ в потоке: скрытый через display:none хост «не на
   экране», и защита от гонки (crmChatStale) отменяла бы монтирование живого треда. */
.deal-drawer:not(.crm-page) .crm-chat-host:empty { height: 0; border-width: 0; }
.deal-drawer:not(.crm-page) .crm-chat-host > main.thread { display: flex; flex: 1 1 auto; min-height: 0; width: auto; }
.deal-drawer:not(.crm-page) .crm-chat-host .thread-head { padding-left: 12px; border-top-left-radius: 13px; border-top-right-radius: 13px; }
.deal-drawer:not(.crm-page) .crm-chat-host #backToList { display: none !important; }

/* ═══════════════════════════════════════════════════════════════════════════════════
   🗂 РАБОЧЕЕ МЕСТО КАРТОЧКИ (лид · сделка) — CRMC-36
   Владелец: «очень неудобно сейчас всё скроллить в узком окне, у нас ведь большой экран…
   чат сделай в отдельном столбике как было раньше». Было: шторка 440/700/1020px и ОДИН
   длинный скролл на 15 секций, переписка сделки — коробка clamp(300px,44vh,520px) внутри
   того же скролла. Стало: ПОЛНОЭКРАННАЯ страница (каркас `.tasks-workspace`, рельс слева
   виден) и ТРИ колонки, у каждой свой скролл:
        ДОСЬЕ (кто/сколько/откуда) · РАБОТА (что делаем) · ПЕРЕПИСКА (во всю высоту)
   🔴 Каркас ОДИН на лид и сделку (crmWsHtml в app.js): секции переиспользуются как есть
   (`.di-sec`, `.deal-field`, `.deal-acts`, `.deal-intel`…), вторых компонентов не заводим.
   🔴 Ни одной прибитой ширины: швы между колонками тянутся мышью и помнят ширину (WIN_PANES),
   двойной клик по шву — сброс. Ниже 900px колонки встают друг под друга, инлайн-ширина снимается.
   ═══════════════════════════════════════════════════════════════════════════════════ */
.deal-drawer.crm-page {
  position: absolute; inset: 0 0 0 var(--rail-track); width: auto; max-width: none; height: auto;
  z-index: 42; background: var(--bg); border-left: 0; box-shadow: none;
  display: flex; flex-direction: column; min-height: 0;
  opacity: 0; transform: translateY(5px);
  transition: opacity .16s ease, transform .16s cubic-bezier(.2, .8, .2, 1);
}
.deal-drawer.crm-page.open { opacity: 1; transform: none; }
/* 🔴 Специфичность 3 класса: общий `.deal-drawer.hidden{display:none}` объявлен ВЫШЕ и
   при равном весе проиграл бы позднему `display:flex` — закрытая карточка осталась бы на экране. */
.deal-drawer.crm-page.hidden { display: none; }
@media (max-width: 720px) { .deal-drawer.crm-page { inset: 0 0 0 62px; } }

/* — шапка страницы: назад · название+мета · действия — */
.crmw-head {
  flex: none; display: flex; align-items: center; gap: 12px; min-height: 58px;
  padding: 9px 16px; border-bottom: 1px solid var(--line); background: var(--panel);
}
.crmw-back {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0; border-radius: 10px; border: 1px solid var(--line);
  background: var(--panel-2); color: var(--muted); cursor: pointer;
  transition: background .12s, color .12s, border-color .12s;
}
.crmw-back:hover { background: var(--hover); color: var(--text); border-color: var(--line-strong); }
.crmw-back .ic { width: 17px; height: 17px; }
/* flex-basis 140px, а не auto: на узком экране шапка переносится по строкам, и «широкий по
   содержимому» блок с названием уезжал ПОД кнопку «назад» (замер на стенде, 402px). */
.crmw-head-t { flex: 1 1 140px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.crmw-head-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
.crmw-head-main .deal-title-edit { flex: 1 1 auto; min-width: 0; font-size: 18px; }
.crmw-head-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 11.5px; color: var(--muted); }
/* В списках эти подписи прижимались вправо (`margin-left:auto`) — в шапке страницы они идут
   ровным рядом сразу за номером, иначе «2 дн в работе» уезжает к кнопкам действий. */
.crmw-head-meta .deal-num, .crmw-head-meta .lead-age { margin-left: 0; }
.crmw-head-acts { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
/* `.primary` без `.small` — кнопка ФОРМЫ (width:100%): в строке действий её геометрию задаём тут. */
.crmw-head-acts .primary { width: auto; margin-top: 0; padding: 7px 14px; font-size: 12.5px; }
.crmw-head-acts .primary .ic, .crmw-head-acts .ghost .ic { width: 14px; height: 14px; }
.crmw-head-acts button { white-space: nowrap; }
/* Иконка и слово — в ОДНУ строку: `button svg.ic { display: block }` без флекса ставил галочку над
   «Конвертировать в сделку» (кадр лида 14.09.2026). */
.crmw-head-acts button { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.crmw-head-acts .ghost { padding: 7px 12px; font-size: 12.5px; }
.crmw-head-acts .ghost.icon-btn { padding: 7px; }

/* — тело: три колонки, у каждой свой скролл — */
.crmw-body { flex: 1 1 auto; min-height: 0; display: flex; position: relative; }
.crmw-col { min-width: 0; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.crmw-side {
  flex: 0 0 340px; display: flex; flex-direction: column; gap: 12px; padding: 14px;
  border-right: 1px solid var(--line); background: var(--panel);
}
.crmw-side > .di-sec { flex: none; }
.crmw-side .deal-field-grid { display: flex; flex-direction: column; gap: 10px; }
/* Сумма · валюта · вероятность: в колонке 288–340px три поля в один ряд не влезают —
   ряд переносится, а не выдавливает «%» за край карточки (замер на стенде, 1440px). */
.crmw-side .deal-amount-row { flex-wrap: wrap; row-gap: 8px; }
.crmw-side .deal-amount-in { flex: 1 1 130px; min-width: 0; }
.crmw-side .deal-field > span { font-size: 11.5px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
/* 🔴 Поле в карточке досье УТОПЛЕНО (`--input-bg`), а не `--panel-2`: фон карточки `.di-sec`
   — тоже `--panel-2`, и поля сливались с ней в сплошное полотно (видно на съёмке стенда:
   «Столбик/Источник/Имя» читались как простой текст, а не как то, что можно нажать и править). */
.crmw-side .deal-field input, .crmw-side .deal-field select, .crmw-side .deal-owner-pick,
.crmw-side .deal-amount-in, .crmw-side .deal-cur, .crmw-side .deal-prob-in,
.crmw-side .deal-stage, .crmw-side .deal-close-date, .crmw-side .deal-fcat, .crmw-side .deal-terr, .crmw-side .deal-reason {
  background-color: var(--input-bg); /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
}
.crmw-main { flex: 1 1 auto; padding: 14px; container-type: inline-size; }
/* Сетка «работы» — по ШИРИНЕ КОЛОНКИ, а не окна: колонку тянут мышью, и медиа-запрос по
   окну врал бы (узкая колонка на широком мониторе продолжала бы делиться надвое). */
.crmw-grid { display: grid; align-content: start; gap: 12px; grid-template-columns: minmax(0, 1fr); }
.crmw-grid > .di-sec { min-width: 0; }
/* 🧱 CLIE-952·Ч13 · БЛОК СТРАНИЦЫ — обёртка `.crmw-blk`: она и есть ячейка сетки, потому что
   тело блока (`crmBHost`, «Дела», «КП и смета») переписывается через innerHTML, а значки
   ширины/скрытия обязаны пережить это. Ширину решает НЕ класс блока, а личная настройка
   человека (`.full`), поэтому прежние точечные правила «.di-lineitems во всю ширину» сняты:
   у одного вопроса один ответ, и он живёт в `Clientschat.CrmCards`. */
.crmw-blk { min-width: 0; display: flex; flex-direction: column; }
.crmw-blk[data-cb="dossier"] { gap: 12px; } /* досье лида — две карточки (плитки «чьё это» и «Контакт и бюджет»): шаг 12, как у колонки .crmw-side */
.crmw-blk > .di-sec, .crmw-blk > .crmb, .crmw-blk > .crmacc, .crmw-blk > .crmauto { flex: 1 1 auto; }
/* 🔴 ПУСТОЙ БЛОК НЕ ЗАНИМАЕТ МЕСТО ВМЕСТЕ СО СВОЕЙ ОБЁРТКОЙ. Секции «Кто видит»,
   «Автоматизации» и блоки `crmBHost` прячут СЕБЯ через `:empty`, пока данные не доехали, —
   но обёртка при этом продолжала бы съедать зазор сетки (пустая дыра между блоками).
   Спрашиваем содержимое (`:has`), а не гадаем по классу. */
.crmw-blk:empty,
/* `.crmb-tags` — СОСЕД блока «Заметки» в той же обёртке: пока теги грузятся, он пуст, и без
   :not(.crmb-tags) прятался весь блок заметок вместе с ними (замер 11.10, отчёт «Заметки и ИИ»). */
.crmw-blk:has(> .crmb:not(.crmb-tags):empty), .crmw-blk:has(> .crmacc:empty), .crmw-blk:has(> .crmauto:empty) { display: none; }
/* Боковая колонка — обычный флекс-столбик, и ячейка в нём теперь обёртка, а не сама секция. */
.crmw-side > .crmw-blk { flex: none; }
@container (min-width: 720px) {
  .crmw-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .crmw-grid > .crmw-wide, .crmw-grid > .crmw-blk.full { grid-column: 1 / -1; }
}
/* Значки блока: ширина и «убрать». Появляются ПРИ НАВЕДЕНИИ (прогрессивное раскрытие) — в
   покое шапка блока чистая. */
.di-sec-h.has-cblk > .di-sec-t { margin-right: auto; }
.crmw-blk[data-cb="dossier"] > .di-sec + .di-sec > .di-sec-h { flex-wrap: wrap; row-gap: 8px; column-gap: 6px; } .crmw-blk[data-cb="dossier"] > .di-sec + .di-sec > .di-sec-h > .di-sec-t { margin-right: auto; } /* «Контакт и бюджет» без значков блока: заголовок слева, «Из документа»/визитка справа, тесно — переносом */
/* 🔴 ИМЯ КЛАССА — ЧАСТЬ МЕХАНИЗМА, И ОНО ОБЯЗАНО БЫТЬ СВОБОДНЫМ. Первая версия звалась
   `.cbx`, а такой класс в продукте УЖЕ ЕСТЬ (панель облачных боксов среды, ~21733) — и он
   объявлен НИЖЕ, то есть побеждал: значки блока вставали столбиком 28×60 и распирали шапку
   с 35 до 79 px. Поймано ЗАМЕРОМ на живом проде (getComputedStyle → flex-direction: column),
   а не чтением: свой код выглядел правильным. Тот же класс, что дубль имени `hdrAnchor`
   (CLIE-975) — тихая подмена поведения у ЧУЖИХ вызывающих. */
.cblk-acts { display: inline-flex; flex: none; align-items: center; gap: 2px; margin-left: 0; max-width: 0; overflow: hidden; opacity: 0; transition: opacity 140ms ease, max-width 140ms ease, margin-left 140ms ease; }
/* 🔴 Скрытые значки НЕ ДЕРЖАТ МЕСТО: при opacity: 0 они занимали ~90 px справа, и действия шапки
   («Звонок…», «Добавить · Из файлов», «Прикрепить · Задача») стояли посреди блока, а не у края
   (кадр владельца 14.09.2026). Ширина раскрывается вместе с появлением. */
.crmw-blk:hover .cblk-acts, .cblk-acts:focus-within { opacity: 1; max-width: 120px; margin-left: 6px; }
.cblk-b {
  display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px;
  border: 0; border-radius: 7px; background: transparent; color: var(--muted); cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.cblk-b:hover { background: var(--panel); color: var(--text); }
.cblk-b .ic { width: 14px; height: 14px; }
/* 🔴 ТАМ, ГДЕ НАВЕДЕНИЯ НЕ БЫВАЕТ, ЗНАЧКИ ВИДНЫ ВСЕГДА (CLIE-952·Ч16). Пальцем «навести»
   нельзя: на планшете значки блока (переставить · ширина · убрать) были недостижимы вовсе —
   то есть функции для этого человека не существовало. Тот же гейт `hover: hover`, которым
   прячется тихая кнопка вопроса на странице сметы. */
@media (hover: none) { .cblk-acts { opacity: 1; } }
/* …и держат своё место: раскрытие ширины — отдельно, чтобы строка выше оставалась ровно той,
   которую сторожит CRMCARDS_MECH. */
@media (hover: none) { .cblk-acts { max-width: none; margin-left: 6px; } }
/* 🧱 РУЧКА ПЕРЕТАСКИВАНИЯ БЛОКА (CLIE-952·Ч16) — переставляем ПРЯМО НА СТРАНИЦЕ. `touch-action`
   обязателен: браузер решает про прокрутку в момент pointerdown, и классом это уже не отменить. */
.cblk-grip { cursor: grab; touch-action: none; }
.cblk-grip:active { cursor: grabbing; }
/* 🔴 CRMC-1133 · РУЧКА ⠿ — ВСЕГДА В УГЛУ, У ВСЕХ БЛОКОВ НА ОДНОЙ X. Владелец: «элементы, за
   которые можно двигать, должны быть ровно, а не вразброс — в одном месте, в углу». Замер на
   живом проде (mobile, hover: none, `/tmp/t1133/grips.js`): ручка стояла ПЕРВОЙ в группе
   значков, а число значков ПОСЛЕ неё у блоков разное (боковой блок без «ширины») — отступ
   ручки от края блока 39 · 43 · 73 px. Порядок в разметке не трогаем (общий обработчик кликов
   и сторож CRMCARDS_MECH читают её как есть) — ручку в угол ставит `order`. */
.cblk-acts > .cblk-grip { order: 9; }
/* 🔴 CRMC-1133·2 · НА ТАЧЕ ЗНАЧКИ ВЫНЕСЕНЫ ИЗ ПОТОКА ШАПКИ. Замер на проде (mobile 402px,
   /tmp/t1133/gripdiag.js) после `order`: группа значков — обычный flex-ребёнок, и когда шапке
   тесно (заголовок в две строки, «Из документа», чипы «Звонок·Встреча…»), flex УЖИМАЕТ её
   («Дела»: 45 px под три значка по 24) — ручка уезжает за край группы и режется overflow'ом
   (отступ −30 · −1 · 1 · 9), а у шапок с переносом («Задачи», «Файлы») группа падает на вторую
   строку (отступ 193). Поэтому на таче группа стоит АБСОЛЮТНО в правом верхнем углу шапки, а
   шапка резервирует ей место справа: ручка у всех блоков на одной x, что бы ни делала шапка.
   `flex: none` (в корневом правиле выше) — группа не ужимается и на десктопе: отрезанная ручка =
   блок нельзя переставить. */
@media (hover: none) {
  .di-sec-h.has-cblk { position: relative; padding-right: 92px; flex-wrap: wrap; row-gap: 8px; }
  /* заголовок держит высоту значков — однострочная шапка остаётся 43 px, значки ей по центру */
  .di-sec-h.has-cblk > .di-sec-t { min-height: 24px; }
  .di-sec-h.has-cblk > .cblk-acts { position: absolute; top: 9px; right: 12px; margin-left: 0; }
  /* что не влезло рядом с заголовком — переносится и прижимается вправо, а не к левому краю */
  .di-sec-h.has-cblk > :not(.di-sec-t):not(.cblk-acts) { margin-left: auto; }
  /* широкие ряды действий («Звонок · Встреча…», «Прикрепить · Задача») — своей строкой под
     заголовком, во всю ширину блока: резерв справа нужен только строке заголовка */
  .di-sec-h.has-cblk > :is(.crm-act-add, .crmb-hacts) { flex: 0 0 calc(100% + 80px); margin-right: -80px; }
}
/* НА МЫШИ ШАПКА БЛОКА ТОЖЕ ПЕРЕНОСИТСЯ, когда ряд не помещается (узкое окно): без переноса
   «Из документа» в «Досье лида» уезжал за край блока на 10 px, а раскрытые наведением значки —
   за ним (замер 21.10, «Штиль», окно 390); в полублоке 311 px при окне 1440 заголовок сжимался в
   две строки, а значки вставали на 304–362 px — за краем. Первая строка как была — заголовок держит
   margin-right: auto; то, что не влезло, встаёт следующей строкой. У «Глубины» в узкой колонке
   своя раскладка (блок «УЗКАЯ КОЛОНКА НА УСТРОЙСТВЕ С МЫШЬЮ» ниже). */
@media (hover: hover) { .di-sec-h.has-cblk { flex-wrap: wrap; row-gap: 8px; } }
/* 🔴 НАВЕДЕНИЕ НЕ ДВИГАЕТ ШАПКУ («Штиль», мышь, 21.10). Значки раскрывались ШИРИНОЙ в потоке
   шапки (max-width 0 → 120): где свободного места в строке меньше их ширины, перенос уводил их
   отдельной строкой, и шапка прыгала при каждом заходе мыши — «Деньги и стадия» при окне 1440
   47 → 79 px, при 390 так прыгали 11 шапок; без переноса (до 21.10) вместо этого сжимался в две
   строки заголовок, а действия уезжали влево на ширину значков. Теперь коробка значков стоит в
   первой строке СРАЗУ за заголовком (`order`) и в покое, и при наведении шириной 0 — в расчёт
   строки она не входит, поэтому раскладка у покоя и наведения одна и та же. Свободное место
   строки — ей слева (margin-left: auto), действия шапки остаются у края; сами значки выходят из
   нулевой коробки ВЛЕВО (justify-content: flex-end) — в свободное место, а где его мало,
   поверх хвоста заголовка, на фоне блока. Скрытые значки по-прежнему не держат места (правило
   14.09 выше), а в покое не ловят клик (pointer-events). У «Глубины» место под значки
   зарезервировано (ревью 12.10, #69) — её не трогаем. */
@media (hover: hover) {
  .di-sec-h.has-cblk:not(.dz-pane *) > :not(.di-sec-t):not(.cblk-acts) { order: 1; }
  .di-sec-h.has-cblk:not(.dz-pane *) > .di-sec-t { margin-right: 0; }
  .crmw-blk .di-sec-h.has-cblk:not(.dz-pane *) > .cblk-acts,
  .crmw-blk:hover .di-sec-h.has-cblk:not(.dz-pane *) > .cblk-acts,
  .crmw-blk.cblk-lift .di-sec-h.has-cblk:not(.dz-pane *) > .cblk-acts {
    max-width: 0; margin-left: auto; overflow: visible; justify-content: flex-end;
  }
  /* фон блока под каждым значком, кольцо в 1 px закрывает зазор 2 px между ними, а слева от
     значков — затухание в 20 px: хвост заголовка плавно уходит ПОД значки, а не обрывается
     срезанной буквой и не просвечивает сквозь них (кадр 21.10: «ДЕНЬГИ И СТ/» при узкой тени) */
  .crmw-blk .di-sec-h.has-cblk:not(.dz-pane *) > .cblk-acts > .cblk-b { flex: none; background: var(--cblk-bg, var(--panel-2)); box-shadow: 0 0 0 1px var(--cblk-bg, var(--panel-2)); }
  .crmw-blk .di-sec-h.has-cblk:not(.dz-pane *) > .cblk-acts::before { content: ""; flex: none; align-self: stretch; width: 20px; margin-right: -2px; background: linear-gradient(90deg, transparent, var(--cblk-bg, var(--panel-2))); pointer-events: none; }
  .crmw-blk .di-sec-h.has-cblk:not(.dz-pane *) > .cblk-acts > .cblk-b:hover { background: var(--panel); }
  .crmw-blk:not(:hover):not(.cblk-lift) .di-sec-h.has-cblk:not(.dz-pane *) > .cblk-acts:not(:focus-within) { pointer-events: none; }
}
.crm-page .di-sec { --cblk-bg: var(--panel); }
/* Пока идёт перестановка: тянущийся блок приподнят и лежит ПОВЕРХ соседей, текст не выделяется. */
.cblk-reordering { user-select: none; -webkit-user-select: none; }
.cblk-reordering .crmw-blk { will-change: transform; }
.crmw-blk.cblk-lift {
  position: relative; z-index: 30; cursor: grabbing;
  box-shadow: 0 12px 28px rgba(0, 0, 0, .18), 0 2px 6px rgba(0, 0, 0, .10);
  border-radius: var(--r-lg, 14px);
}
.crmw-blk.cblk-lift .cblk-acts { opacity: 1; max-width: 120px; margin-left: 6px; }
/* Вход в настройку блоков — тихой строкой в подвале колонки «Работы»: он стоит У САМОЙ ВЕЩИ
   (канон CLIE-857·2), а не пунктом в общих настройках. */
.crmw-cfg { display: flex; justify-content: center; padding: 2px 0 6px; }
.crmw-grid > .crmw-cfg { grid-column: 1 / -1; }
.crmw-cfg-b {
  display: inline-flex; align-items: center; gap: 7px; height: var(--ctl-h, 30px);
  padding: 0 12px; border: 1px solid transparent; border-radius: var(--ctl-r, 10px);
  background: transparent; color: var(--muted); font-size: var(--ctl-fs, 13px); cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.crmw-cfg-b:hover { background: var(--panel-2); border-color: var(--line); color: var(--text); }
.crmw-cfg-b .ic { width: 15px; height: 15px; }
.crmw-cfg-n {
  font-style: normal; font-size: 11.5px; font-weight: 650; line-height: 1;
  padding: 3px 6px; border-radius: 999px; background: var(--panel-2); color: var(--text-dim);
}
/* Окно «Блоки»: строка-настройка в языке системных настроек (грип · имя · сегмент · тумблер). */
.cbrow {
  display: flex; align-items: center; gap: 10px; padding: 7px 10px;
  border: 1px solid var(--line); border-radius: var(--ctl-r, 10px); background: var(--panel);
  margin-bottom: 6px;
}
.cbrow.off { opacity: .55; }
.cbrow-grip { display: inline-flex; width: 16px; color: var(--muted); cursor: grab; flex: none; }
.cbrow-grip .ic { width: 16px; height: 16px; }
.cbrow-nm { flex: 1 1 auto; min-width: 0; font-size: var(--ctl-fs, 13px); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cbrow-sz { flex: none; }
.cbrow-add { flex: none; }
.cbrow-h { margin: 14px 0 8px; font-size: 12px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
.crm-cards-acts { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }

/* 🎨🎨 CRMC-698 · ТЕМА (ШАБЛОН) СДЕЛКИ ──────────────────────────────────────────────────
   Строка «убрано темой» ГОВОРИТ СЛОВАМИ, кто её убрал, и даёт «Вернуть»: человек сильнее
   темы, и он обязан это видеть, а не гадать, почему блок «сам пропал».
   🔴 Акцент — подложка + кольцо `inset 0 0 0 1px` и иконка СО СЛОВОМ. Левых полосок-реек
   (border-left ≥2px, абсолютная полоса у кромки) здесь нет и быть не должно (CLIE-483). */
.crmw-cfg-t {
  font-style: normal; font-size: 11.5px; font-weight: 600; line-height: 1;
  padding: 3px 7px; border-radius: 999px; max-width: 150px;
  background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary-2, var(--primary));
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cbrow-nm2 { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; white-space: normal; }
.cbrow-nm2 .cbrow-t { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cbrow-why { font-style: normal; font-size: 11.5px; line-height: 1.3; color: var(--muted); }
.cbrow.off.cbrow-bytpl {
  opacity: 1;
  background: color-mix(in srgb, var(--primary) 7%, var(--panel));
  border-color: color-mix(in srgb, var(--primary) 20%, var(--line));
}
/* 🔴 Имя блока — САМОЕ сильное в строке. `--text-dim` в СВЕТЛОЙ теме светлее `--muted`
   (замер: имя rgb(138,147,163) против подписи rgb(86,92,107) на светлом фоне), то есть
   пояснение перебивало название. Строку и так отличают подложка, кольцо и слова. */
.cbrow.off.cbrow-bytpl .cbrow-t { color: var(--text); }
/* Иконка и СЛОВО стоят в один ряд: у `.btn` строчная раскладка, и блочная `<svg class="ic">`
   сама сваливала подпись на вторую строку («↩» сверху, «Вернуть» снизу). */
.cbrow-add { display: inline-flex; align-items: center; justify-content: center; gap: 6px; white-space: nowrap; }
.cbrow-add .ic { width: 14px; height: 14px; flex: none; }

/* Полоса темы в шапке окна «Блоки»: чем сейчас решается состав страницы и вход в управление. */
.cbtpl {
  display: flex; align-items: center; gap: 10px; margin: 0 0 12px; padding: 9px 12px;
  border-radius: var(--ctl-r, 10px);
  background: color-mix(in srgb, var(--primary) 9%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}
.cbtpl-ic { flex: none; display: inline-flex; color: var(--primary-2, var(--primary)); }
.cbtpl-ic .ic { width: 17px; height: 17px; }
.cbtpl-t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cbtpl-t > i { font-style: normal; font-size: 10.5px; font-weight: 650; letter-spacing: .045em; text-transform: uppercase; color: var(--muted); }
.cbtpl-t > b { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cbtpl-go {
  flex: none; height: var(--ctl-h, 30px); padding: 0 11px; border: 1px solid transparent;
  border-radius: var(--ctl-r, 10px); background: transparent; color: var(--primary-2, var(--primary));
  font: inherit; font-size: var(--ctl-fs, 13px); font-weight: 600; cursor: pointer;
  transition: background 130ms ease, border-color 130ms ease;
}
.cbtpl-go:hover { background: color-mix(in srgb, var(--primary) 14%, transparent); border-color: color-mix(in srgb, var(--primary) 26%, transparent); }

/* Окно «Шаблоны сделок»: строка темы правится ПО КЛИКУ на само значение — ни карандаша,
   ни пары «Сохранить/Отмена» (канон «нажал → изменил»). */
.deal-tpl-box { width: min(720px, 94vw); }
.dtpl-list, .dtpl-pres { display: flex; flex-direction: column; gap: 8px; }
.dtpl-row, .dtpl-pre {
  display: flex; align-items: flex-start; flex-wrap: wrap; gap: 10px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--r-lg, 14px); background: var(--panel);
  transition: background 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
}
.dtpl-row:hover, .dtpl-pre:hover { border-color: var(--line-strong, #555); }
.dtpl-row.on {
  border-color: transparent;
  background: color-mix(in srgb, var(--primary) 8%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 24%, transparent);
}
.dtpl-dot {
  flex: none; width: 10px; height: 10px; margin-top: 6px; border-radius: 50%;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 14%, transparent);
}
.dtpl-main { flex: 1 1 220px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dtpl-nm, .dtpl-de {
  border-radius: 7px; padding: 1px 5px; margin-left: -5px; outline: none; overflow-wrap: anywhere;
  transition: background 120ms ease, box-shadow 120ms ease;
}
.dtpl-nm { font-size: 13.5px; font-weight: 600; color: var(--text); }
.dtpl-de { font-size: 12.5px; color: var(--muted); }
.dtpl-de:empty::before { content: attr(data-ph); color: var(--text-dim); }
.dtpl-nm[contenteditable]:hover, .dtpl-de[contenteditable]:hover { background: var(--hover); }
.dtpl-nm[contenteditable]:focus, .dtpl-de[contenteditable]:focus {
  background: var(--input-bg); color: var(--text); box-shadow: inset 0 0 0 1px var(--primary);
}
.dtpl-meta { margin-top: 2px; font-size: 11.5px; color: var(--text-dim); }
.dtpl-acts { flex: none; margin-left: auto; display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.dtpl-b, .dtpl-def {
  display: inline-flex; align-items: center; gap: 6px; height: var(--ctl-h, 30px); padding: 0 10px;
  border: 1px solid var(--line); border-radius: var(--ctl-r, 10px); background: var(--panel-2);
  color: var(--muted); font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer;
  transition: color 130ms ease, background 130ms ease, border-color 130ms ease;
}
.dtpl-b .ic, .dtpl-def .ic { width: 14px; height: 14px; flex: none; }
.dtpl-b:hover, .dtpl-def:hover { color: var(--text); border-color: var(--line-strong, #555); }
.dtpl-def.on {
  border-color: transparent; color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 12%, transparent);
}
.dtpl-del { padding: 0 9px; }
.dtpl-del:hover { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 46%, var(--line)); }
.dtpl-pre .dtpl-b { align-self: center; }
.dtpl-h { margin: 20px 0 8px; font-size: 12px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }

/* — колонка переписки: живой <main.thread> во всю высоту, со своим композером — */
.crmw-chat {
  flex: 0 0 400px; display: flex; flex-direction: column; overflow: hidden;
  border-left: 1px solid var(--line); background: var(--panel);
}
.crmw-chat-h {
  flex: none; display: flex; align-items: center; gap: 8px; height: 46px; padding: 0 14px;
  border-bottom: 1px solid var(--line); font-size: 12.5px; font-weight: 650; color: var(--text);
}
.crmw-chat-h .ic { width: 15px; height: 15px; color: var(--muted); flex: none; }
.crmw-chat-h .lead-src { margin-left: auto; }
/* 💬 0367 · ДВЕ СТОРОНЫ ПЕРЕПИСКИ («С клиентом» | «С коллегами») — КАНОН `.cc-seg` в
   компактном размере (`.cc-seg-sm` = «строка списка, шапка панели»). Своей дорожки с
   пилюлей здесь НЕ заводим (правило CLIE-505): вид сегмента один на весь продукт. Тут
   остаётся только место в шапке колонки и то, что подпись не должна ломать узкую колонку. */
.crmw-chat-seg { min-width: 0; }
.crmw-chat-seg > * { min-width: 0; }
.crmw-chat-seg > * > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Бейдж «сколько непрочитанных на ДРУГОЙ вкладке» — тот же `.tw-seg-badge`, что у остальных
   сегментов продукта; здесь только запрет расти и съедать подпись. */
.crmw-chat-seg .crm-side-n { flex: none; }
/* Гашение нуля живёт у САМОГО бейджа (`.tw-seg-badge[hidden]`), а не здесь: иначе каждый
   новый потребитель заводил бы это правило заново — и один раз уже завёл (0367·2). */
/* Канал сделки («Telegram») стоит справа, как чип источника у лида. */
.crmw-chat-chan { margin-left: auto; display: inline-flex; align-items: center; gap: 4px;
  color: var(--muted); font-size: 11.5px; font-weight: 600; white-space: nowrap; }
.crmw-chat-chan svg.ic { width: 13px; height: 13px; }
/* 🪟 ВХОД · ВЫХОД · ЗАТЕМНЕНИЕ шторки переписки (владелец 16.09.2026) — только на УЗКОМ
   экране. На широком колонка стоит третьей всегда, и эти три контрола там мёртвые: кнопка
   «Переписка», которая ничего не открывает, — ровно то, что правило продукта называет
   «нажал → ничего». Поэтому по умолчанию их НЕТ, а медиа-правило ниже их вносит. */
/* 🔴 Специфичность: рядом живёт `.crmw-head-acts button { display: inline-flex }` (0,1,1) —
   одноклассовое правило её НЕ перебивает, и вход «Переписка» вылезал на ШИРОКОМ экране, где
   колонка и так третья (поймано кадром 1440px). Спрашиваем ровно там же, где включаем. */
.crmw-head-acts .crmw-chat-btn { display: none; }
.crmw-chat-x, .crmw-chat-back { display: none; }
/* 👥 0370 · «Участники» переписки карточки — рядом с сегментом сторон. Тот же тон и размер,
   что у крестика шторки (`.crmw-chat-x`): это соседние системные кнопки одной шапки. */
.crmw-chat-ppl {
  flex: none; margin-left: auto; display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 6px; border: 0; border-radius: 8px; background: transparent;
  color: var(--muted); cursor: pointer; font: inherit; font-size: 11.5px; font-weight: 700;
}
.crmw-chat-ppl:hover { background: var(--panel-2); color: var(--text); }
.crmw-chat-ppl svg.ic { width: 16px; height: 16px; }
.crmw-ppl-n:empty { display: none; }
/* Шапка переписки в ОЧЕРЕДИ лидов — та же, что в карточке (одна разметка, один переключатель). */
.lead-q-chat-h { background: var(--panel); }
.crmw-chat-btn .crmw-chat-n { flex: none; }
.crmw-chat-b, .crmw-chat-box { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.crmw-chat .crm-chat-slot { flex: none; }
.crmw-chat .deal-chat-bar { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px; border-bottom: 1px solid var(--line); }
/* Хост: перебиваем глобальное `.tip-chat-host{display:none}` (тот же узел, другое место). */
.crmw-chat .crm-chat-host { display: flex; flex: 1 1 auto; min-height: 0; flex-direction: column; overflow: hidden; }
.crmw-chat .crm-chat-host > main.thread { display: flex; flex: 1 1 auto; min-height: 0; width: auto; }
.crmw-chat .crm-chat-host .thread-head { padding-left: 14px; }
.crmw-chat .crm-chat-host #backToList { display: none !important; } /* внутри карточки не нужна «назад к списку» */
.crmw-chat .crm-chat-note { margin: 12px; }

/* — мелочи «досье»: пара «подпись → значение», скор лида — */
.crmw-kv { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; font-size: 12.5px; }
.crmw-kv > span { color: var(--muted); flex: none; }
.crmw-kv > b { font-weight: 600; text-align: right; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmw-kv > b.bad { color: var(--danger); }
.crmw-score { display: flex; align-items: center; gap: 10px; }
.crmw-score > b { font-size: 26px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
/* Дорожка шкалы УТОПЛЕНА (`--input-bg`), а не `--panel`: карточка теперь ур.1 (белая), и
   дорожка цвета карточки была бы дорожкой из воздуха — замер после правки поверхностей дал
   #ffffff на #ffffff = 1.000. `--input-bg` даёт ступеньку в ОБЕИХ темах (светлая #f5f5f7 на
   белом, тёмная #171d25 на #1c222b) — в отличие от `--panel-2`, который в тёмной СВЕТЛЕЕ карточки. */
.crmw-score-bar { height: 6px; border-radius: var(--r-full); background: var(--input-bg); border: 1px solid var(--line); overflow: hidden; }
.crmw-score-bar > i { display: block; height: 100%; background: var(--grad); border-radius: var(--r-full); transition: width .2s ease; }
.crm-page .tw-empty, .crm-page .deal-drawer-load { margin: auto; padding: 40px; color: var(--muted); text-align: center; }

/* ── 🔐 «Кто видит» — доступ к ОДНОЙ записи (лид/сделка). Одна разметка на обе карточки ──
   Пока доступ не прочитан (или его не видно) — секция ПУСТА и её нет на экране: блок не
   «мигает» скелетом и не отбирает место. Список допущенных и «Добавить» появляются только
   в режиме «Только выбранные» — прогрессивное раскрытие, а не всё сразу. */
.crmacc:empty { display: none; }
/* ── ⚡ «Автоматизации» карточки (0212): что правила сделали с ЭТОЙ записью и почему НЕ
   сработали. Ничего не срабатывало — секции нет вовсе (не отбираем экран). Строки прогонов
   рисуются классами .cc-run* конструктора правил — одна разметка на журнал и на карточку. */
.crmauto:empty { display: none; }
.crmauto-cnt { flex: 0 0 auto; font-size: 11px; font-weight: 650; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-full); padding: 3px 9px; white-space: nowrap; }
.crmauto-list { display: flex; flex-direction: column; }
.crmauto-hint { color: var(--muted); font-size: 11.5px; line-height: 1.4; margin-top: 2px; }
.crmauto .cc-run { background: var(--panel); }
.crmauto .cc-run:last-child { margin-bottom: 0; }
.cc-run-nm { font-weight: 650; color: var(--text); margin-right: 6px; }
.crmacc-sw { display: flex; align-items: center; gap: 12px; cursor: pointer; }
.crmacc-sw.ro { cursor: default; }
.crmacc-sw-t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.crmacc-sw-t > b { font-size: 13px; font-weight: 600; color: var(--text); }
.crmacc-sw-t > i { font-style: normal; font-size: 11.5px; line-height: 1.35; color: var(--muted); }
.crmacc-ro { flex: 0 0 auto; font-size: 11px; font-weight: 650; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-full); padding: 3px 9px; white-space: nowrap; }
.crmacc-list { display: flex; flex-direction: column; gap: 2px; padding-top: 9px; border-top: 1px solid color-mix(in srgb, var(--line) 60%, transparent); }
.crmacc-it { display: flex; align-items: center; gap: 8px; min-width: 0; padding: 4px 4px 4px 0; border-radius: 9px; transition: background .14s ease; }
.crmacc-it:hover { background: var(--hover); }
.crmacc-it .tw-av { width: 22px; height: 22px; flex: none; font-size: 10px; }
.crmacc-dot { flex: none; width: 10px; height: 10px; margin: 0 6px; border-radius: 50%; background: var(--rb, var(--muted)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--rb, var(--muted)) 16%, transparent); }
.crmacc-nm { flex: 1 1 auto; min-width: 0; font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmacc-it.role .crmacc-nm { font-weight: 600; color: color-mix(in srgb, var(--rb, var(--text)) 62%, var(--text)); }
/* Крестик виден ВСЕГДА (приглушённо), а не только на hover: спрятанный контрол = «догадайся,
   как убрать» — и на тач-экране его не достать вовсе. На наведении просто набирает контраст. */
.crmacc-x { flex: none; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center; padding: 0; border: 0; border-radius: 7px; background: transparent; color: var(--muted); cursor: pointer; opacity: .5; transition: opacity .14s ease, background .14s ease, color .14s ease; }
.crmacc-x .ic { width: 13px; height: 13px; }
.crmacc-it:hover .crmacc-x, .crmacc-x:focus-visible { opacity: 1; }
.crmacc-x:hover { opacity: 1; background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.crmacc-add { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px 5px 9px; border-radius: 9px; border: 1px solid var(--line); background: var(--panel); color: var(--text-dim); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; transition: background .14s ease, color .14s ease, border-color .14s ease; }
.crmacc-add:hover { background: var(--hover); color: var(--text); border-color: var(--line-strong); }
.crmacc-add:disabled { opacity: .55; cursor: default; }
.crmacc-add .ic { width: 13px; height: 13px; }
.crmacc-empty { font-size: 11.5px; line-height: 1.4; color: var(--muted); }
/* 🔐 CLIE-1268: строка круга, которая в пространстве записи никого не пускает. Не прячем и не
   красим «ошибкой» — это законное состояние (запись переехала), но читаться как живой допуск
   она не имеет права: имя приглушено, причина стоит второй строкой словами сервера. */
.crmacc-it.stale .crmacc-nm { color: var(--muted); }
.crmacc-it.stale .crmacc-dot, .crmacc-it.stale .tw-av { opacity: .5; }
/* 🔴 CLIE-1268: причина ОБЯЗАНА ДОЧИТЫВАТЬСЯ. Многоточие тут не «аккуратность», а отказ
   без слов: обрезанное «не в пространстве записи — доступа не …» неотличимо от рабочей
   строки. Имя рядом по-прежнему в одну строку с многоточием — у него есть title. */
.crmacc-stale { display: block; margin-top: 1px; font-size: 11px; line-height: 1.35; font-weight: 500; color: var(--warning); font-style: normal; white-space: normal; overflow-wrap: anywhere; }
.crmacc-it.stale { align-items: flex-start; }
.crmacc-it.stale .tw-av, .crmacc-it.stale .crmacc-dot { margin-top: 2px; }
.crmacc-it.stale .crmacc-x { margin-top: 1px; }

/* ═══════════════════════════════════════════════════════════════════════════════════
   🧰 РАБОЧИЕ БЛОКИ КАРТОЧКИ CRM (CRMC-36, вторая волна). Владелец по первой версии
   страницы: «1. Куча всего не хватает из того, что было на макетах — нет функционала.
   2. Нет даже инфы кто ответственный за лида. 3. Дизайн не контрастный, плохо
   считывается». Здесь: ответственный, следующий шаг, теги, задачи, файлы + КОНТРАСТ.
   ═══════════════════════════════════════════════════════════════════════════════════ */

/* ── КОНТРАСТ: карточка, её заголовок и поля должны читаться, а не сливаться ──
   Было: рамки `--line` (в светлой #e7ebf3 — почти невидимы на белом), заголовки секций и
   подписи полей `--text-dim` (#8a93a3 ≈ 2.6:1 — ниже AA даже для крупного текста). Стало:
   рамка `--line-strong` + тень уровня 1, заголовок `--muted` (6:1) и жирнее, подписи полей
   тоже `--muted`. Меняем ТОЛЬКО на странице CRM — списки задач/проектов не трогаем. */
/* ── 🔴 ПОВЕРХНОСТИ СТРАНИЦЫ: ХОЛСТ → БЕЛАЯ КАРТОЧКА → УТОПЛЕННЫЙ ИНСЕТ ──
   Владелец 15.09.2026 (кадр карточки лида #1676): «Не красиво. серые блоки на сером фоне».
   ЗАМЕР на проде его собственной шкурой (светлая, concept-6 + острова, `crm-card-surface-probe`):
       --bg = --panel-2 = --input-bg = #f5f5f7, --panel = #ffffff
   то есть карточка `.di-sec` (фон `--panel-2`) и холст колонки — ОДИН И ТОТ ЖЕ ЦВЕТ:
   контраст 1.000 у всех 11 блоков «работы». Карточку рисует только хэйрлайн; поле досье
   (`--input-bg`) в такой карточке тоже 1.000 — ровно то, о чём говорит комментарий про
   «утоплено» ниже: он был верен для базовой палитры и перестал быть верным для этой.
   🔴 ПРАВИЛО, а не заплатка на один скин: карточка, стоящая НА ХОЛСТЕ, берёт ур.1 (`--panel`),
   а `--panel-2` остаётся тем, чем объявлен в токенах, — ИНСЕТОМ ВНУТРИ карточки. Поэтому
   колонка «досье» тоже становится холстом: иначе на одной странице жили бы два разных языка
   (белая колонка с серыми карточками слева и серый холст с белыми карточками справа). */
.crm-page .crmw-side { background: var(--bg); }
.crm-page .di-sec { background: var(--panel); border-color: var(--line-strong); box-shadow: var(--shadow-1); }
/* Поле «спросить/добавить» внутри карточки — УТОПЛЕНО: его базовый `--panel` совпал бы с
   карточкой ур.1 (замер после правки: #ffffff на #ffffff). Правим ТОЛЬКО на странице CRM —
   в панели задач `.di-ask-in` лежит на `--panel-2` и там `--panel` как раз и даёт ступеньку. */
.crm-page .di-ask-in { background: var(--input-bg); }
.crm-page .di-sec-h { border-bottom-color: var(--line); }
.crm-page .di-sec-t { color: var(--muted); font-weight: 700; font-size: 11.5px; letter-spacing: .045em; }
.crm-page .di-sec-t .ic { opacity: 1; color: var(--muted); }
.crm-page .crmw-side .deal-field > span,
.crm-page .crmw-side .deal-field > label { color: var(--muted); font-weight: 650; }
.crm-page .crmw-side .deal-field input,
.crm-page .crmw-side .deal-field select,
.crm-page .crmw-side .deal-amount-in, .crm-page .crmw-side .deal-cur, .crm-page .crmw-side .deal-prob-in,
.crm-page .crmw-side .deal-stage, .crm-page .crmw-side .deal-close-date, .crm-page .crmw-side .deal-fcat,
.crm-page .crmw-side .deal-terr, .crm-page .crmw-side .deal-reason {
  border-color: var(--line-strong); color: var(--text); font-weight: 500;
}
.crm-page .crmw-side .deal-field input::placeholder { color: var(--text-dim); }
.crm-page .deal-desc-edit, .crm-page .lead-utm-row > b, .crm-page .crmw-kv > b { color: var(--text); }
.crm-page .crmw-kv > span, .crm-page .lead-utm-row > span { color: var(--muted); }

/* ── Ответственный: аватар + имя, всегда на виду ── */
.crmw-owner {
  display: flex; align-items: center; gap: 10px; width: 100%; box-sizing: border-box;
  margin: -2px 0 2px; padding: 8px 10px; border-radius: 11px; cursor: pointer; text-align: left;
  border: 1px solid var(--line-strong); background: var(--input-bg); color: inherit; font: inherit;
  transition: background .14s ease, border-color .14s ease;
}
.crmw-owner:hover { background: var(--hover); border-color: var(--primary); }
.crmw-owner .tw-av { width: 30px; height: 30px; flex: none; font-size: 12px; }
.crmw-owner-av {
  flex: none; width: 30px; height: 30px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; background: var(--panel-2);
  border: 1px dashed var(--line-strong); color: var(--muted);
}
.crmw-owner-av .ic { width: 15px; height: 15px; }
.crmw-owner-t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
/* 🔴 CLIE-1030·R3: подпись строки ОДНОСТРОЧНАЯ. Замер 12.09: «ПРОСТРАНСТВО · ВЫБРАНО
   ВРУЧНУЮ» переносилось на вторую строку и распирало карточку клиента — строка-сосед
   («Компания», «Контакт») вставала выше/ниже своих братьев. Не влезло — отточие. */
.crmw-owner-t > i { font-style: normal; font-size: 10.5px; font-weight: 650; letter-spacing: .045em; text-transform: uppercase; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmw-owner-t > b { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmw-owner.none .crmw-owner-t > b { color: var(--primary-2); } /* акцентный ТЕКСТ — --primary-2: --primary на --panel-2 светлой давал 4.31 */
/* 🏢 CLIE-1030·R3 · «ПРОСТРАНСТВО» под «Проектом»: та же строка .crmw-owner (своей геометрии не
   заводим), а под ней — выбор компаний проекта РЯДОМ, чипами (владелец: «и рядом, а не в
   отдельном окне»). Чип канонический .crm-chip, здесь только раскладка ряда. */
.crmw-space-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 6px; padding: 0 2px; }
.crmw-space-chips .crm-chip { max-width: 100%; }
/* 🗂 CRMC-647 · строка «Проект» в карточке сделки: у выбранного проекта вместо иконки —
   его ЦВЕТ (тот же язык, что точка проекта в рельсе и в пикере), чтобы проект узнавался
   глазом, а не чтением. Своей рамки/размеров нет: геометрия общая с .crmw-owner-av. */
.crmw-owner-av.crmw-prdot { border-style: solid; border-color: color-mix(in srgb, var(--text) 12%, transparent); }
/* 🗂 CRMC-647 · чип проекта на карточке доски и в строке списка. */
.deal-chip.deal-proj { color: var(--muted); }
.deal-chip.deal-proj .deal-proj-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.deal-row-title .deal-chip.deal-proj { margin-left: 6px; vertical-align: middle; }
.crmw-owner-go { flex: none; display: inline-flex; color: var(--text-dim); }
.crmw-owner-go .ic { width: 15px; height: 15px; }
/* 👤 CRMC-647·3 · строка-СВЯЗЬ («Компания», «Контакт»), у которой клиент уже выбран: имя ведёт
   в КАРТОЧКУ клиента, «Сменить» — отдельным действием со СЛОВОМ. Рама и геометрия — те же
   .crmw-owner (второго вида строки не заводим), подсветку берут на себя дети, поэтому у самой
   рамы hover гасим: иначе подсвечивалась бы вся строка независимо от того, куда целится курсор. */
.crmw-owner.crmw-rel { padding: 0; gap: 0; overflow: hidden; }
.crmw-owner.crmw-rel:hover { background: var(--input-bg); border-color: var(--line-strong); }
.crmw-owner.crmw-rel:focus-within { border-color: var(--primary); }
.crmw-rel-main {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 10px;
  padding: 8px 6px 8px 10px; border: 0; background: none; color: inherit; font: inherit;
  text-align: left; cursor: pointer; transition: background .14s ease;
}
.crmw-rel-main:hover { background: var(--hover); }
.crmw-rel-main:hover .crmw-owner-go { color: var(--primary); }
/* Подпись действия НЕ сжимается ниже своей ширины (СРЕД-33): при нехватке места уступает имя
   клиента (у него ellipsis), а не кнопка — иначе «Сменить» напечаталось бы поверх соседа. */
.crmw-rel-swap {
  flex: none; align-self: stretch; min-width: max-content; display: inline-flex; align-items: center;
  padding: 0 11px; border: 0; border-left: 1px solid var(--line-strong); background: none;
  color: var(--text-dim); font: inherit; font-size: 12px; font-weight: 600; white-space: nowrap;
  cursor: pointer; transition: background .14s ease, color .14s ease;
}
.crmw-rel-swap:hover { background: var(--hover); color: var(--primary); }
/* 👥 CRMC-671 · ОСТАЛЬНЫЕ УЧАСТНИКИ сделки — компактным списком ПОД строкой «Контакты».
   Появляется, только когда людей больше одного (прогрессивное раскрытие: при единственном
   контакте на экране не прибавляется ни одного элемента). Строка ведёт в карточку человека,
   рядом два НАЗВАННЫХ СЛОВОМ действия — немой значок ищут глазами и не находят (ЗВОН-607).
   Геометрия наследует `.crmw-owner`: своей второй раскладки строк-связей у продукта нет. */
.crmw-subs { display: flex; flex-direction: column; gap: 4px; margin: -1px 0 6px; padding-left: 12px; }
/* 🔴 СРЕД-34: когда ширины не хватает, уступает ДЕЙСТВИЕ, а не ИМЯ ЧЕЛОВЕКА. Замер на боевом
   проде (колонка карточки сделки ~300px): имена печатались как «Але…» и «Пёт…», а обе кнопки
   стояли во всю ширину — то есть на экране оставалось украшение и пропадал ответ на вопрос
   «кто это». Поэтому строка ПЕРЕНОСИТСЯ, а у имени ОПРЕДЕЛЁННЫЙ базис (не `auto`): с `auto`
   доступная ширина ребёнка считается по содержимому, и перенос не срабатывает вовсе. */
.crmw-sub {
  display: flex; align-items: stretch; flex-wrap: wrap; min-width: 0; border-radius: 9px;
  overflow: hidden; border: 1px solid var(--line); background: var(--panel-2);
  transition: border-color .14s ease;
}
.crmw-sub:hover { border-color: var(--line-strong); }
.crmw-sub-main {
  flex: 1 1 150px; min-width: 0; display: flex; align-items: center; gap: 8px;
  padding: 6px 6px 6px 7px; border: 0; background: none; color: inherit; font: inherit;
  text-align: left; cursor: pointer; transition: background .14s ease;
}
.crmw-sub-main:hover { background: var(--hover); }
.crmw-sub .tw-av { width: 24px; height: 24px; flex: none; font-size: 10px; }
/* Имя и должность — в ДВЕ строки (та же вертикаль, что у `.crmw-owner-t`): в один ряд они
   не влезали в колонку карточки, и обрезалось ИМЯ. */
.crmw-sub-txt { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 0; }
.crmw-sub-n { font-size: 12.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmw-sub-t { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Действия — ОДНОЙ группой: если ширины не хватило, они уезжают на свою линию ЦЕЛИКОМ и
   прижаты вправо, а не рассыпаются по одной кнопке. */
.crmw-sub-acts { flex: 0 0 auto; margin-left: auto; display: flex; align-items: stretch; }
/* Подпись действия не сжимается ниже своей ширины (СРЕД-33): место уступает имя, у него ellipsis. */
.crmw-sub-a {
  flex: none; align-self: stretch; min-width: max-content; display: inline-flex; align-items: center;
  padding: 4px 9px; border: 0; border-left: 1px solid var(--line); background: none;
  color: var(--text-dim); font: inherit; font-size: 11.5px; font-weight: 600; white-space: nowrap;
  cursor: pointer; transition: background .14s ease, color .14s ease;
}
.crmw-sub-a:hover { background: var(--hover); color: var(--primary); }
/* 👥 CRMC-671 · чип «с кем работаем» на карточке доски и в строке списка. */
.deal-chip.deal-cts { color: var(--text-dim); }
.deal-chip.deal-cts .ic { width: 11px; height: 11px; }
/* Тот же ответственный чипом в шапке страницы. */
.crmw-ownchip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 190px; padding: 2px 9px 2px 2px;
  border-radius: var(--r-full); border: 1px solid var(--line-strong); background: var(--panel-2);
  color: var(--text); font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer;
  transition: background .14s ease, border-color .14s ease;
}
.crmw-ownchip:hover { background: var(--hover); border-color: var(--primary); }
.crmw-ownchip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmw-ownchip .tw-av { width: 19px; height: 19px; flex: none; font-size: 9px; }
.crmw-ownchip.none { padding-left: 8px; color: var(--muted); border-style: dashed; }
.crmw-ownchip.none .ic { width: 13px; height: 13px; }

/* ── Следующий шаг ── */
.crmb-step .di-sec-b { padding-top: 10px; }
.crmb-step.over { border-color: color-mix(in srgb, var(--urg-overdue) 46%, var(--line-strong)); }
.crmw-step { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.crmw-step-when {
  flex: none; display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px;
  border-radius: var(--r-full); border: 1px solid color-mix(in srgb, var(--urg-today) 34%, transparent);
  background: var(--urg-today-soft); color: var(--urg-today); font: inherit; font-size: 12px; font-weight: 650; cursor: pointer;
}
.crmw-step-when.over { border-color: color-mix(in srgb, var(--urg-overdue) 38%, transparent); background: var(--urg-overdue-soft); color: var(--urg-overdue-ink); }
.crmw-step-when .ic { width: 13px; height: 13px; }
.crmw-step-txt { flex: 1 1 200px; min-width: 0; font-size: 14px; line-height: 1.45; color: var(--text); outline: none; border-radius: 8px; padding: 3px 5px; margin: -3px -5px; }
.crmw-step-txt:hover { background: var(--hover); }
.crmw-step-txt:focus { background: var(--input-bg); box-shadow: 0 0 0 2px var(--glow); }
.crmw-step-txt:empty::before { content: attr(data-ph); color: var(--text-dim); }
.crmw-step-done { flex: none; }
.crmw-step-set {
  display: inline-flex; align-items: center; gap: 7px; padding: 7px 13px 7px 10px; border-radius: 10px;
  border: 1px dashed var(--line-strong); background: transparent; color: var(--muted);
  font: inherit; font-size: 13px; font-weight: 600; cursor: pointer; transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.crmw-step-set:hover { background: var(--hover); color: var(--text); border-color: var(--primary); }
.crmw-step-set .ic { width: 14px; height: 14px; }

/* ── «За что балл»: расшифровка оценки ── */
.crmw-why { display: flex; flex-direction: column; gap: 1px; margin-top: 4px; padding-top: 9px; border-top: 1px solid var(--line); }
.crmw-why-r { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text-dim); padding: 3px 0; }
.crmw-why-r > b { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 650; color: var(--text-dim); }
.crmw-why-d { flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--line-strong); }
.crmw-why-r.on { color: var(--text); }
.crmw-why-r.on > b { color: var(--ok); }
.crmw-why-r.on .crmw-why-d { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-soft); }

.crmw-why-none { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-top: 4px; padding-top: 9px; border-top: 1px solid var(--line); font-size: 12.5px; color: var(--muted); }
.crmw-why-none .ic { width: 14px; height: 14px; flex: none; }

/* ── Теги (метки) ── */
.crmb-tags { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 4px; }
.crmb-tags:empty { display: none; }
.crmb-tag {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--r-full);
  border: 1px solid color-mix(in srgb, var(--lc, var(--muted)) 40%, transparent);
  background: color-mix(in srgb, var(--lc, var(--muted)) 13%, transparent);
  color: color-mix(in srgb, var(--lc, var(--text)) 72%, var(--text));
  font: inherit; font-size: 11.5px; font-weight: 650; cursor: pointer; transition: background .14s ease;
}
.crmb-tag:hover { background: color-mix(in srgb, var(--lc, var(--muted)) 24%, transparent); }
.crmb-tag-add {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px 3px 8px; border-radius: var(--r-full);
  border: 1px dashed var(--line-strong); background: transparent; color: var(--muted);
  font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer; transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.crmb-tag-add:hover { background: var(--hover); color: var(--text); border-color: var(--primary); }
.crmb-tag-add .ic { width: 12px; height: 12px; }

/* ── Задачи и файлы карточки ── */
.crmb-cnt { margin-left: 6px; font-size: 11px; font-weight: 700; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-full); padding: 0 6px; }
/* Кнопка действия секции и «Готово» — ОДНОЙ строкой: базовая `button` в проекте блочная,
   и без inline-flex иконка вставала НАД подписью («+» / «Задача» в два этажа — поймано на
   съёмке прода, а не «по коду»). */
.crmb-act, .crmw-step-done {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  flex: none; width: auto; margin-top: 0; padding: 4px 10px 4px 8px; font-size: 12px;
}
.crmb-act .ic, .crmw-step-done .ic { width: 13px; height: 13px; }
.crmb-empty { font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.crmb-task { display: flex; align-items: center; gap: 9px; min-width: 0; padding: 4px 2px; border-radius: 9px; transition: background .14s ease; }
.crmb-task:hover { background: var(--hover); }
.crmb-task .tw-av { width: 21px; height: 21px; flex: none; font-size: 9px; }
.crmb-ck {
  flex: none; width: 18px; height: 18px; padding: 0; border-radius: 6px; cursor: pointer;
  border: 1.5px solid var(--line-strong); background: var(--input-bg); color: #fff;
  display: inline-flex; align-items: center; justify-content: center; transition: background .14s ease, border-color .14s ease;
}
.crmb-ck:hover { border-color: var(--primary); }
.crmb-ck.on { background: var(--ok); border-color: var(--ok); }
.crmb-ck .ic { width: 12px; height: 12px; }
.crmb-task-t { flex: 1 1 auto; min-width: 0; text-align: left; background: none; border: 0; padding: 0; cursor: pointer; font: inherit; font-size: 13.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmb-task-t:hover { color: var(--primary); }
.crmb-task.done .crmb-task-t { color: var(--muted); text-decoration: line-through; }
.crmb-due { flex: none; font-size: 11.5px; font-weight: 650; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-full); padding: 2px 8px; }
.crmb-due.today { color: var(--urg-today); background: var(--urg-today-soft); border-color: transparent; }
.crmb-due.over { color: var(--urg-overdue-ink); background: var(--urg-overdue-soft); border-color: transparent; }
.crmb-new { width: 100%; box-sizing: border-box; margin-top: 4px; background: var(--input-bg); color: var(--text); border: 1px solid var(--primary); border-radius: 9px; padding: 7px 10px; font: inherit; font-size: 13.5px; outline: none; box-shadow: 0 0 0 3px var(--glow); }
/* Номер задачи перед названием (CRMC-678): задачи в блоке — НАСТОЯЩИЕ, и узнают их по номеру.
   Приглушён намеренно — главное в строке имя, номер только адресует. */
.crmb-num { margin-right: 6px; font-size: 12.5px; font-weight: 650; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ══════════════════════════════════════════════════════════════════════════════════════
   ☑️ ЧЕК-ЛИСТ ПО СДЕЛКЕ/ЛИДУ (CRMC-678). Строка та же, что у задач, но текст правится ИНЛАЙН
   по клику (канон realtime-inline-edit-no-pencil): ни карандаша, ни «Сохранить/Отмена».
   Только токены темы (сырой hex запрещён) → светлая и тёмная выходят одинаково вылизанными.
   ══════════════════════════════════════════════════════════════════════════════════════ */
.crmb-cnt.ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 13%, transparent); border-color: color-mix(in srgb, var(--ok) 26%, transparent); }
.crmb-ckrow { display: flex; align-items: flex-start; gap: 9px; min-width: 0; padding: 4px 2px; border-radius: 9px; transition: background .14s ease; }
.crmb-ckrow:hover { background: var(--hover); }
.crmb-ckrow > .crmb-ck { margin-top: 1px; }
.crmb-ckrow.pending { opacity: .55; }                    /* пункт уехал на сервер и ещё не вернулся */
.crmb-ckt {
  flex: 1 1 auto; min-width: 0; margin: -1px -5px; padding: 1px 5px;
  font-size: 13.5px; line-height: 1.45; color: var(--text);
  border-radius: 7px; outline: none; cursor: text;
  white-space: pre-wrap; word-break: break-word;
  transition: background .14s ease, box-shadow .14s ease, color .14s ease;
}
.crmb-ckt:empty::before { content: attr(data-ph); color: var(--text-dim); }
.crmb-ckt:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }
.crmb-ckt:focus { background: var(--input-bg); box-shadow: 0 0 0 3px var(--glow), inset 0 0 0 1px var(--primary); }
.crmb-ckrow.done .crmb-ckt { color: var(--muted); text-decoration: line-through; }
/* Правим — читаем ЧТО правим: под курсором зачёркивание снимается. */
.crmb-ckrow.done .crmb-ckt:focus { color: var(--text); text-decoration: none; }
.crmb-ckby { flex: none; align-self: center; max-width: 34%; font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crmb-ckrow > .crmb-ckx { align-self: flex-start; }
/* Строки файлов приезжают из карточки задачи (`.tf-*`) — здесь только рама-подложка под
   тёмную/светлую тему: там фон задан жёстко белым по alpha, на светлой это «серый в сером». */
.crmb-files .tf-row { background: var(--input-bg); border: 1px solid var(--line); }
.crmb-files .tf-row:hover { background: var(--hover); }
.crmb-files .tf-name { color: var(--text); }
.crmb-files .tf-drop { margin: 0; }

/* ══════════════════════════════════════════════════════════════════════════════════════
   📅 ДЕЛА CRM (0211) — блок карточки, пилюля доски, «Мой день».
   Только токены темы (сырой hex запрещён) → светлая и тёмная получаются одинаково вылизанными.
   ══════════════════════════════════════════════════════════════════════════════════════ */
.crmb-acts .di-sec-h { align-items: flex-start; }
.crmb-cnt.hot { color: var(--urg-overdue-ink); background: var(--urg-overdue-soft); border-color: transparent; }
/* Четыре вида дела — компактным рядом; на узком переносятся, а не режутся. */
.crm-act-add { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; justify-content: flex-end; }
.crm-act-add .crmb-act { padding: 4px 9px 4px 7px; }
.crm-act-add .crmb-act.on { border-color: var(--primary); color: var(--primary); }

.crm-act-row {
  display: flex; align-items: center; gap: 8px; min-width: 0;
  padding: 5px 4px 5px 2px; border-radius: 9px;
  transition: background .14s ease;
}
.crm-act-row:hover { background: var(--hover); }
.crm-act-row + .crm-act-row { box-shadow: inset 0 1px 0 var(--line); }
.crm-act-ic { flex: none; display: inline-flex; color: var(--muted); }
.crm-act-ic .ic { width: 14px; height: 14px; }
.crm-act-row.over .crm-act-ic { color: var(--urg-overdue-ink); }
.crm-act-t {
  flex: 1 1 auto; min-width: 0; font-size: 13.5px; color: var(--text);
  outline: none; border-radius: 6px; padding: 2px 4px; margin: -2px -4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background .14s ease, box-shadow .14s ease;
}
.crm-act-t:focus { background: var(--input-bg); box-shadow: 0 0 0 2px var(--glow); white-space: normal; }
.crm-act-t:empty::before { content: attr(data-ph); color: var(--muted); }
.crm-act-row.done .crm-act-t { color: var(--muted); text-decoration: line-through; }
.crm-act-when {
  flex: none; display: inline-flex; align-items: center; gap: 4px; width: auto; margin: 0;
  font: inherit; font-size: 11.5px; font-weight: 650; cursor: pointer;
  color: var(--muted); background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-full); padding: 2px 9px 2px 7px;
  transition: color .14s ease, background .14s ease, border-color .14s ease;
}
.crm-act-when .ic { width: 12px; height: 12px; }
.crm-act-when:hover { border-color: var(--primary); color: var(--text); }
.crm-act-when.today { color: var(--urg-today); background: var(--urg-today-soft); border-color: transparent; }
.crm-act-when.over { color: var(--urg-overdue-ink); background: var(--urg-overdue-soft); border-color: transparent; }
.crm-act-when.none { border-style: dashed; }
.crm-act-who, .crm-act-x {
  flex: none; width: 24px; height: 24px; padding: 0; margin: 0; border: 0; background: none;
  color: var(--muted); border-radius: 7px; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .14s ease, color .14s ease, opacity .14s ease;
}
.crm-act-who .ic, .crm-act-x .ic { width: 13px; height: 13px; }
.crm-act-who .tw-av { width: 21px; height: 21px; font-size: 9px; }
/* Крестик не отбирает внимание: проявляется на наведении строки (на тач — всегда). */
.crm-act-x { opacity: 0; }
.crm-act-row:hover .crm-act-x, .crm-act-x:focus-visible { opacity: 1; }
.crm-act-x:hover { background: var(--danger-soft); color: var(--danger); }
.crm-act-res { flex: 0 1 auto; min-width: 0; font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-act-sep { display: flex; align-items: center; gap: 6px; margin: 10px 0 2px; font-size: 11px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase; color: var(--muted); }
.crm-act-sep i { font-style: normal; font-weight: 700; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-full); padding: 0 6px; }

/* ── 🪪 КАРТОЧКА ДЕЛА (CRMC-1133) — рама задачи (.task-info-panel.as-overlay), кирпичи .tip-* ──
   Входы: значок вида в строке блока «Дела» и название строки «Мой день» стали кнопками —
   сброс UA-вида, а не новый компонент (правило движка СРЕД-34). */
button.crm-act-ic { background: none; border: 0; padding: 0; margin: 0; cursor: pointer; border-radius: 6px; transition: color .14s ease; }
button.crm-act-ic:hover, button.crm-act-ic:focus-visible { color: var(--primary); }
.crm-act-row.done .crm-act-t[contenteditable="false"] { cursor: pointer; }
button.myday-t { font-family: inherit; text-align: left; background: none; border: 0; padding: 0; margin: 0; cursor: pointer; transition: color .14s ease; }
button.myday-t:hover, button.myday-t:focus-visible { color: var(--primary); }
.crmact-body { display: flex; flex-direction: column; gap: 10px; }
.crmact-body .td-section-h svg.ic { width: 13px; height: 13px; }
/* 🔴 Общие блоки (чек-лист · заметки · файлы · наблюдатели) в карточке дела — CRMC-716.
   Пустой блок НЕ рисует пустую рамку: в карточке лида это делает обёртка `.crmw-blk`, здесь
   обёртки нет — говорим то же самое напрямую. Зазор даёт `gap` самой колонки. */
.crmact-body .crmb:empty { display: none; }
.crmact-body .crmb { margin: 0; }
.crmact-hero { gap: 12px; }
.crmact-kinds { align-self: flex-start; }
.crmact-title {
  font-size: 19px; font-weight: 700; line-height: 1.3; color: var(--text); outline: none;
  border-radius: 8px; padding: 4px 8px; margin: -4px -8px; min-height: 1.3em; word-break: break-word;
  transition: background .12s ease, box-shadow .12s ease;
}
.crmact-title[contenteditable="true"] { cursor: text; }
.crmact-title[contenteditable="true"]:hover { background: var(--panel); }
.crmact-title[contenteditable="true"]:focus { background: var(--input-bg); box-shadow: 0 0 0 2px var(--glow); }
.crmact-title:empty::before { content: attr(data-ph); color: var(--muted); }
.crmact-title.closed { color: var(--muted); text-decoration: line-through; }
.crmact-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.crmact-chips .tip-chipbtn .tw-av { width: 20px; height: 20px; font-size: 9px; }
.crmact-status { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 650; padding: 5px 10px; border-radius: var(--r-full); color: var(--muted); background: var(--panel); }
.crmact-status i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.crmact-status.done { color: var(--ok); background: color-mix(in srgb, var(--ok) 13%, transparent); }
.crmact-status.over { color: var(--urg-overdue-ink); background: var(--urg-overdue-soft); }
.crmact-status.today { color: var(--urg-today); background: var(--urg-today-soft); }
.crmact-status.plan { color: var(--primary-2); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.crmact-links { gap: 0; padding-top: 4px; padding-bottom: 4px; }
.crmact-nav { width: 100%; background: none; border: 0; padding: 8px 0; margin: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; border-radius: 8px; }
.crmact-nav:disabled { cursor: default; }
.crmact-nav:not(:disabled):hover .tip-prop-ro { color: var(--text); }
.crmact-nav .tip-prop-k { color: var(--text); }
.crmact-nav .tip-prop-ro { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.crmact-nav .tip-prop-v > svg.ic { width: 14px; height: 14px; color: var(--muted); flex: none; }
.crmact-result {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 58px; display: block;
  font: inherit; font-size: 13.5px; line-height: 1.45; color: var(--text);
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 10px; padding: 8px 10px; outline: none;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.crmact-result:focus { border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); }
.crmact-actions { display: flex; align-items: center; gap: 8px; padding: 2px 0 6px; }
.crmact-btn { display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 40px; padding: 0 14px; border-radius: 11px; font: inherit; font-size: 13.5px; font-weight: 650; cursor: pointer; }
.crmact-btn svg.ic { width: 16px; height: 16px; }
/* «Выполнено» — зелёная, а не синяя: канон `.primary` в светлой теме объявлен как
   `html[data-theme="light"] .primary` (выше по специфичности), поэтому и здесь обе формы. */
.crmact-actions .crmact-btn.crmact-done, html[data-theme="light"] .crmact-actions .crmact-btn.crmact-done { flex: 1 1 auto; background: var(--ok); border-color: transparent; color: #fff; box-shadow: none; }
.crmact-actions .crmact-btn.crmact-done:hover, html[data-theme="light"] .crmact-actions .crmact-btn.crmact-done:hover { background: color-mix(in srgb, var(--ok) 88%, #000); box-shadow: 0 2px 8px color-mix(in srgb, var(--ok) 35%, transparent); }
.crmact-del { margin-left: auto; color: var(--muted); }
.crmact-del:hover { color: var(--danger); background: var(--danger-soft); }
.crmact-panel.busy .crmact-actions .crmact-btn { opacity: .6; pointer-events: none; }
.crm-act-sep::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--line); }
/* «Показать ещё N» — хвост длинного списка дел свёрнут, чтобы карточка не превращалась
   в стену на сотню строк (сверху и так самое срочное). */
.crm-act-more {
  display: block; width: 100%; margin-top: 6px; padding: 7px 10px; font: inherit; font-size: 12.5px;
  font-weight: 600; color: var(--muted); background: transparent; border: 1px dashed var(--line);
  border-radius: 9px; cursor: pointer; transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.crm-act-more:hover { background: var(--panel); color: var(--text); border-color: var(--line-strong, var(--line)); }
/* Строка ввода нового дела — появляется ТОЛЬКО после выбора вида (не отбираем экран заранее). */
.crm-act-new { display: flex; align-items: center; gap: 6px; margin-top: 8px; }
.crm-act-new.hidden { display: none; }
.crm-act-in {
  flex: 1 1 auto; min-width: 0; box-sizing: border-box; background: var(--input-bg); color: var(--text);
  border: 1px solid var(--primary); border-radius: 9px; padding: 7px 10px; font: inherit; font-size: 13.5px;
  outline: none; box-shadow: 0 0 0 3px var(--glow);
}
.crm-act-newdue { flex: none; }

/* Пилюля «ближайшее дело» и ЯВНОЕ «без дела» на карточке доски (модель amoCRM). */
.crm-act-pill, .crm-act-none {
  display: inline-flex; align-items: center; gap: 4px; flex: none;
  font-size: 11px; font-weight: 650; border-radius: var(--r-full); padding: 1px 7px 1px 5px;
  border: 1px solid var(--line); color: var(--muted); background: var(--panel);
}
.crm-act-pill .ic, .crm-act-none .ic { width: 11px; height: 11px; }
.crm-act-pill.today { color: var(--urg-today); background: var(--urg-today-soft); border-color: transparent; }
.crm-act-pill.over { color: var(--urg-overdue-ink); background: var(--urg-overdue-soft); border-color: transparent; }
.crm-act-none { color: var(--warning); background: var(--warning-soft); border-color: transparent; }
.crm-act-chip.hot.active { color: var(--urg-overdue-ink); border-color: var(--urg-overdue); }

/* Тулбар сделок появляется, только когда есть что фильтровать (см. renderSalesBoard). */
/* 🧭 CRMC-697·3 · ШАПКА СДЕЛОК = РОВНО ДВЕ СТРОКИ (владелец 13.09.2026: «Там 3 строки а должно
   быть 2. Канбан теперь занимает мало места»). Замер прода ДО правки: шапка 325px из трёх лент
   (метрики 116 + пространство 68 + «как отображать» 98) — доске оставалось 451px, ровно половина
   окна 900px. ЛЕЧЕНИЕ — не «сделать помельче», а СЛОЖИТЬ роли: лента 1 = метрики (B4, они
   вверху), лента 2 = пространство → как отображать → поиск/фильтры (B1+B3, одной строкой и в том
   порядке, который назвал владелец). Стиль поверхности прежний — это база, не остров (CLIE-975·3). */
/* 🔴 `flex-wrap: nowrap` ОБЯЗАТЕЛЕН: базовый `.crm-toolbar` — строка с переносом, а здесь мы
   развернули её в КОЛОНКУ. Колонка С ПЕРЕНОСОМ раскладывает детей по флекс-ЛИНИЯМ, и ширину
   им задаёт ЛИНИЯ (по содержимому), а не контейнер, — поэтому `align-items: stretch` ничего не
   стягивал: при окне 402px коробка шапки была 328px, а её полосы — 653px, и правый край
   (поиск · «Ещё фильтры» · «Воронки») уезжал под `overflow: hidden` тела раздела. */
.deal-toolbar { flex-direction: column; flex-wrap: nowrap; align-items: stretch; gap: 8px; padding: 10px 16px 9px; }

/* B4 · Плитки-метрики ОДНОЙ ЛЕНТОЙ: значение и подпись в ряд (было столбиком — 116px на ленту),
   акцент прежний (подложка + кольцо, канон accent, без левых реек). Активная = включённый фильтр.
   Не влезло по ширине — лента ЕДЕТ ВБОК (канон label-fit: подпись не сжимаем, честно прокручиваем),
   а НЕ переносится: перенос и был тем «третьим рядом», на который жаловался владелец. */
.crm-metrics { display: flex; gap: 8px; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.crm-metrics::-webkit-scrollbar { height: 0; }
.crm-metric {
  flex: 0 0 auto; min-width: auto; display: flex; align-items: center; gap: 8px;
  padding: 5px 12px; border-radius: var(--r-full, 999px); border: 1px solid var(--line);
  background: var(--panel-2); color: var(--text); cursor: pointer; text-align: left;
  min-height: var(--ctl-h, 31px); box-sizing: border-box;
  transition: border-color .13s, background .13s, box-shadow .13s;
}
.crm-metric:hover { border-color: var(--line-strong, #555); }
.crm-metric .cm-ic { display: inline-flex; color: var(--muted); flex: none; }
.crm-metric .cm-ic svg { width: 15px; height: 15px; }
.crm-metric .cm-body { display: flex; flex-direction: row; align-items: baseline; gap: 6px; line-height: 1.1; min-width: auto; }
.crm-metric .cm-v { font-size: 14.5px; font-weight: 700; color: var(--text); white-space: nowrap; }
.crm-metric .cm-l { font-size: 12px; font-weight: 600; color: var(--muted); white-space: nowrap; }
.crm-metric.on {
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  border-color: transparent; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}
.crm-metric.on .cm-ic, .crm-metric.on .cm-v { color: var(--primary-2, var(--primary)); }
.crm-metric.on .cm-l { color: var(--primary-2, var(--primary)); opacity: .85; }
.crm-metric.hot .cm-ic { color: var(--urg-overdue-ink); }
.crm-metric.hot.on {
  background: var(--urg-overdue-soft);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--urg-overdue) 30%, transparent);
}
.crm-metric.hot.on .cm-ic, .crm-metric.hot.on .cm-v, .crm-metric.hot.on .cm-l { color: var(--urg-overdue-ink); }

/* ВТОРАЯ ЛЕНТА: пространство → как отображать → поиск/фильтры. Один размерный класс ряда
   (канон control-size): все контролы берут --ctl-*. Строка НЕ переносится (nowrap) — иначе
   появляется третий ряд; уступает место дорожка чипов пространства (она едет вбок). */
/* 🔴 min-width:0 у полос шапки — иначе они НЕ СЖИМАЮТСЯ и вылезают за узкое окно.
   Замер (402px, стенд): коробка шапки 328px, а содержимое 669px, и `#salesBody` с
   `overflow-x: hidden` просто ОТРЕЗАЛ поиск, «Ещё фильтры» и «Воронки» — контролы были на
   экране, но недостижимы. У флекс-элемента `min-width: auto` = «не уже своего содержимого»,
   поэтому и перенос по `flex-wrap: wrap` не срабатывал: строке нечего было переносить. */
.deal-toolbar, .deal-toolbar .crm-metrics { min-width: 0; }
.deal-toolbar .crm-row { display: flex; align-items: center; gap: 8px; flex-wrap: nowrap; min-width: 0; min-height: var(--ctl-h); }
/* deals-toolbar-indent-1 · ряд вида — не строка списка: класс .crm-row приносил поле 9px 12px, курсор-руку
   и подсветку наведения. Выбор воронки стоял на x 132, а метрики и колонки доски — на x 120. */
@media (min-width: 761px) {
  .deal-toolbar > .crm-row.crm-view-row { padding-left: 0; padding-right: 0; cursor: auto; }
  .deal-toolbar > .crm-row.crm-view-row:hover { background: none; }
}
@media (max-width: 760px) {
  /* crm-deals-toolbar-inset-1 · то же на телефоне (390 px): поле 9px 12px от .crm-row утапливало ряд вида —
     выбор воронки с x 97, сегмент вида до x 354, а плитки KPI и колонки доски — x 85–366. Без поля края
     ряда совпадают с ними; курсор-рука и подсветка наведения строки списка ряду инструментов не нужны. */
  .deal-toolbar > .crm-row.crm-view-row { padding-left: 0; padding-right: 0; cursor: auto; }
  .deal-toolbar > .crm-row.crm-view-row:hover { background: none; }
  /* crm-deals-search-placeholder-1 · подсказка «Название, №, компания, контакт…» обрывалась посреди буквы
     («Название, №, комг»): у <input> обрыв по умолчанию — clip. Здесь обрыв многоточием, как у поиска
     Компаний; полный текст остаётся в широком окне. */
  .deal-toolbar .crm-view-row .crm-search > input,
  .deal-toolbar .crm-view-row .crm-search > input::placeholder { text-overflow: ellipsis; }
  /* crm-deals-empty-stages-1 · доска стопкой (≤860): пустая стадия занимала 93 px (y 370–463) ради слова «пусто»,
     под тулбаром в кадре — одни пустые стадии. Пустая стадия сворачивается в строку шапки «Новый 0»
     (как .lead-col.is-empty). Пока тянут карточку (.deal-board.dragging), стадия раскрывается как цель. */
  .deal-board:not(.dragging) > .deal-col:not(:has(.deal-card)) { flex: 0 0 auto; }
  .deal-board:not(.dragging) > .deal-col:not(:has(.deal-card)) > .tw-col-head { padding-bottom: 12px; }
  .deal-board:not(.dragging) > .deal-col:not(:has(.deal-card)) > .tw-col-body { min-height: 0; padding: 0; }
  .deal-board:not(.dragging) > .deal-col:not(:has(.deal-card)) > .tw-col-body > .tw-col-ph { display: none; }
}
.deal-toolbar .crm-row-lbl { font-size: 11px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase; color: var(--muted); flex: none; }
.deal-toolbar .crm-row-sp { flex: 1 1 auto; min-width: 0; }
.deal-toolbar .crm-row-div { width: 1px; align-self: stretch; margin: 2px 3px; background: var(--line); flex: none; }
.deal-toolbar .crm-row-val { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; }
/* Дорожка чипов пространства/воронки: одной строкой, не влезло — прокрутка (label-fit), а не перенос. */
.deal-toolbar .crm-space-cell { flex: 0 1 auto; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; align-items: center; }
.deal-toolbar .crm-space-cell::-webkit-scrollbar { height: 0; }
.deal-toolbar .crm-space-cell .crm-chip { flex: none; white-space: nowrap; }
.deal-toolbar .crm-pipe-chip { display: inline-flex; align-items: center; gap: 5px; }
.deal-toolbar .crm-pipe-chip svg, .deal-toolbar .crm-space-cell .crm-chip svg { width: 12px; height: 12px; opacity: .8; }
.deal-toolbar .crm-space-cell .crm-row-val { display: inline-flex; align-items: center; gap: 6px; }
.deal-toolbar .crm-space-cell .crm-row-val svg { width: 13px; height: 13px; opacity: .75; }
/* 🔻 CRMC-697·Р4 — ПИЛЮЛЯ ВЫБОРА ВОРОНКИ (макет B1): «<воронка> · <пространство> ▾».
   Главное имя — вес текста, пространство — приглушённая приписка: одна мысль «что я смотрю»,
   а не два соревнующихся контрола. Размер — общий --ctl-h (канон control-size), поэтому
   пилюля стоит в одну линию с сегментом видов и поиском и НЕ добавляет третью полосу. */
.deal-toolbar .crm-pipe-pick {
  /* 🔴 `flex: none` + потолок ширины: имя воронки сжиматься НЕ ДОЛЖНО. На 402px при `0 1 auto`
     пилюля схлопывалась до 24px — то есть ровно до состояния «не видно, какая воронка
     открыта», из-за которого весь этот раунд и случился. Не влезло — едет вбок вместе с рядом. */
  display: inline-flex; align-items: center; gap: 7px; flex: none; max-width: 260px; min-width: 0;
  appearance: none; cursor: pointer; font: inherit; font-size: 13px; font-weight: 700;
  color: var(--text); background: var(--panel-2); border: 1px solid var(--line);
  border-radius: var(--r-full, 999px); padding: 0 11px; min-height: var(--ctl-h, 31px);
  transition: border-color .13s, background .13s;
}
.deal-toolbar .crm-pipe-pick:hover { border-color: var(--line-strong, #555); }
.deal-toolbar .crm-pipe-pick svg { width: 13px; height: 13px; opacity: .8; flex: none; }
.deal-toolbar .crm-pipe-pick svg:last-child { opacity: .55; margin-left: -2px; }
.deal-toolbar .crm-pipe-pick .cpp-n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.deal-toolbar .crm-pipe-pick .cpp-sp {
  font-size: 11.5px; font-weight: 600; color: var(--muted); white-space: nowrap;
  padding-left: 7px; border-left: 1px solid var(--line); flex: none;
}
/* Поиск в ряду вида не тянется на весь экран — уступает место сегменту, но остаётся читаемым. */
.deal-toolbar .crm-view-row .crm-search { flex: 0 1 280px; min-width: 150px; }
/* 🗂🏢 Пилюли «Проекты» и «Клиенты» — канонический .tw-scope-btn, ужатый под ряд вида: подпись
   режется многоточием (overflow+ellipsis у .tw-scope-lbl), иконка и шеврон не сжимаются. */
.deal-toolbar .crm-view-row .deal-fpill { flex: 0 0 auto; min-width: 118px; max-width: 200px; }
.deal-toolbar .sales-view-seg, .deal-toolbar .dash-period-seg { flex: none; }
/* Кнопки правого края («Ещё фильтры», «Воронки») — ОДНОЙ линией и в рост ряда: без этого
   «Воронки» ставила слово ПОД иконку и вырастала до 50px при ряде в 31px — тот самый «криво
   косо», который видно на кадре, а не в коде (замер CRMC-697·Р4: 69×50 @1335,174). */
.deal-toolbar .crm-view-row > .ghost.small, .deal-toolbar .dash-owner-chip {
  flex: none; white-space: nowrap; display: inline-flex; align-items: center; gap: 6px;
  min-height: var(--ctl-h, 31px); align-self: center;
}
.deal-toolbar .dash-owner-chip { display: inline-flex; align-items: center; gap: 5px; min-height: var(--ctl-h); }
.deal-toolbar .dash-owner-chip svg { width: 13px; height: 13px; opacity: .85; }
/* Узкое окно — подписи видов гаснут (остаются иконки), «Воронки» теряет слово: строк по-прежнему две. */
@media (max-width: 1080px) {
  .deal-toolbar .sales-view-seg .tw-seg-label { display: none; }
  .deal-toolbar #salesPipeCfg span { display: none; }
  /* Пространство уходит из пилюли раньше имени воронки: имя отвечает «что я смотрю»,
     пространство — уточнение, и оно остаётся в подсказке кнопки и в самом пикере. */
  .deal-toolbar .crm-pipe-pick .cpp-sp { display: none; }
}
/* Узкое окно (телефон, узкая колонка ПК): рабочая строка ЕДЕТ ВБОК той же дорожкой, что и
   лента метрик выше, — не переносится третьей полосой и ничего не отрезает. Замер 402px ДО
   правки: поиск, «Ещё фильтры» и «Воронки» стояли за краем и были недостижимы (`#salesBody`
   с `overflow-x: hidden` их отрезал), потому что перенос во флексе тут не срабатывает вовсе. */
@media (max-width: 720px) {
  .deal-toolbar .crm-row {
    flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
  }
  .deal-toolbar .crm-row::-webkit-scrollbar { height: 0; }
  /* Распорка на узком экране не нужна: она раздувала дорожку пустотой. */
  .deal-toolbar .crm-row-sp { display: none; }
  .deal-toolbar .crm-view-row .crm-search { flex: none; width: 210px; }
  .deal-toolbar .crm-view-row .deal-fpill { flex: none; }
}

/* ── «Мой день» ── */
.myday-bar { padding-bottom: 10px; }
/* Ширину списка ограничиваем читаемой мерой: на 1440+ строка во весь экран растягивает
   взгляд на метр и читается как таблица, а это список дел. */
.myday { display: flex; flex-direction: column; gap: 18px; padding: 2px 2px 28px; max-width: 1080px; }
.myday-sec { display: flex; flex-direction: column; gap: 2px; }
.myday-h { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; font-size: 11.5px; font-weight: 700; letter-spacing: .3px; text-transform: uppercase; color: var(--muted); }
.myday-h i { font-style: normal; font-weight: 700; color: var(--muted); background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-full); padding: 0 6px; }
.myday-sec.hot .myday-h { color: var(--urg-overdue-ink); }
.myday-sec.hot .myday-h i { color: var(--urg-overdue-ink); background: var(--urg-overdue-soft); border-color: transparent; }
.myday-row {
  display: flex; align-items: center; gap: 10px; min-width: 0;
  padding: 8px 10px; border-radius: 11px;
  background: var(--panel); border: 1px solid var(--line);
  transition: background .14s ease, border-color .14s ease, transform .14s ease;
}
.myday-row + .myday-row { margin-top: 6px; }
.myday-row:hover { border-color: var(--line-strong); background: var(--hover); }
.myday-row.over { border-color: var(--urg-overdue-soft); }
.myday-t { flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.myday-ent {
  flex: 0 1 auto; min-width: 0; width: auto; margin: 0; padding: 2px 9px; border-radius: var(--r-full);
  font: inherit; font-size: 11.5px; font-weight: 600; cursor: pointer;
  color: var(--muted); background: transparent; border: 1px solid var(--line);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: color .14s ease, border-color .14s ease;
}
.myday-ent:hover { color: var(--primary); border-color: var(--primary); }
.myday-when { flex: none; font-size: 11.5px; font-weight: 650; color: var(--muted); }
.myday-when.today { color: var(--urg-today); }
.myday-when.over { color: var(--urg-overdue-ink); }
@media (max-width: 720px) {
  .myday-row { flex-wrap: wrap; row-gap: 6px; }
  .myday-t { flex-basis: 100%; order: 1; white-space: normal; }
  .myday-ent { order: 2; }
  .myday-when { order: 3; margin-left: auto; }
}

/* ── Заметки лентой (crmb-notes) ── */
.crmb-notes-list { display: flex; flex-direction: column; gap: 2px; }
.crmb-note { display: flex; align-items: flex-start; gap: 9px; padding: 7px 2px; border-radius: 9px; transition: background .14s ease; }
.crmb-note:hover { background: var(--hover); }
.crmb-note:hover .crmb-note-del { opacity: 1; }
.crmb-note .tw-av { width: 26px; height: 26px; flex: none; font-size: 10.5px; margin-top: 1px; }
.crmb-note-b { flex: 1 1 auto; min-width: 0; }
.crmb-note-h { display: flex; align-items: baseline; gap: 7px; }
.crmb-note-h > b { font-size: 12.5px; font-weight: 650; color: var(--text); }
.crmb-note-h > span { font-size: 11px; color: var(--muted); }
.crmb-note-t { margin-top: 2px; font-size: 13.5px; line-height: 1.45; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.crmb-note-del { flex: none; opacity: 0; width: 22px; height: 22px; padding: 0; border-radius: 7px; border: 0; background: transparent; color: var(--muted); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: opacity .14s ease, background .14s ease, color .14s ease; }
.crmb-note-del:hover { background: var(--danger-soft); color: var(--danger); }
.crmb-note-del .ic { width: 13px; height: 13px; }
.crmb-note-in {
  width: 100%; box-sizing: border-box; margin-top: 8px; resize: none; min-height: 34px; max-height: 140px;
  background: var(--input-bg); color: var(--text); border: 1px solid var(--line); border-radius: 9px;
  padding: 7px 10px; font: inherit; font-size: 13.5px; line-height: 1.4; outline: none; transition: border-color .14s ease, box-shadow .14s ease;
}
.crmb-note-in:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.crmb-note-in::placeholder { color: var(--muted); }

/* ── Наблюдатели (crmb-watchers) ── */
/* Ряд действий в шапке секции — общий: наблюдатели и «Задачи» (там их два: «Прикрепить»
   существующую и «Задача» — новая). На узкой колонке переносятся, а не режутся (СРЕД-33). */
.crmb-watch-acts, .crmb-hacts { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
/* Действия шапки — ОДНОЙ группой у правого края: по одной кнопке они не переносятся (столбик
   «Добавить / Из файлов» посреди шапки — кадр владельца 14.09.2026); не влезла группа — вся
   уходит строкой под заголовок и там тоже прижата вправо. */
.crmb-hacts { flex-wrap: nowrap; margin-left: auto; }
.crmb-hacts > button { white-space: nowrap; }
/* У «Задач» действий ДВА («Прикрепить» + «Задача»). На узкой колонке ряд переносится под
   заголовок, а не выдавливает его: подпись секции не имеет права ужаться под свою ширину
   (СРЕД-33), а `.di-sec` клипает (overflow: hidden) — то есть «не влезло» = «пропало». */
.di-sec-h:has(.crmb-hacts) { flex-wrap: wrap; row-gap: 8px; }
.crmb-watch-it { display: flex; align-items: center; gap: 9px; padding: 4px 2px; border-radius: 9px; transition: background .14s ease; }
.crmb-watch-it:hover { background: var(--hover); }
.crmb-watch-it:hover .crmb-watch-x { opacity: 1; }
.crmb-watch-it .tw-av { width: 24px; height: 24px; flex: none; font-size: 10px; }
.crmb-watch-nm { flex: 1 1 auto; min-width: 0; font-size: 13.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Крестик «убрать из строки» — ОДНА реализация на наблюдателя, пункт чек-листа и открепление
   задачи (CRMC-678): три копии одного контрола и есть «дизайн везде разный». */
.crmb-watch-x, .crmb-ckx, .crmb-taskx { flex: none; opacity: 0; width: 20px; height: 20px; padding: 0; border-radius: 6px; border: 0; background: transparent; color: var(--muted); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: opacity .14s ease, background .14s ease, color .14s ease; }
.crmb-watch-x:hover, .crmb-ckx:hover, .crmb-taskx:hover { background: var(--danger-soft); color: var(--danger); }
.crmb-watch-x .ic, .crmb-ckx .ic, .crmb-taskx .ic { width: 11px; height: 11px; }
.crmb-ckrow:hover .crmb-ckx, .crmb-ckx:focus-visible { opacity: 1; }
.crmb-task:hover .crmb-taskx, .crmb-taskx:focus-visible { opacity: 1; }
/* 🔴 Тач: «навести» нельзя → крестик, живущий только на :hover, там МЁРТВЫЙ контрол. Правило
   стоит ПОСЛЕ базового `opacity: 0` — иначе при равной специфичности выиграло бы оно. */
@media (hover: none) { .crmb-watch-x, .crmb-ckx, .crmb-taskx { opacity: .62; } }
.crmb-act.on { color: var(--primary); border-color: var(--primary); }

/* Узкий монитор — колонки ужимаются; ниже 900px встают друг под друга (страница скроллится
   целиком, переписка получает свой экран). Инлайн-ширину швов на этом пороге снимает winSync. */
@media (max-width: 1180px) {
  .crmw-side { flex-basis: 288px; }
  .crmw-chat { flex-basis: 344px; }
}
/* 🪟 ПОРОГ ШТОРКИ — 1100px, А НЕ 900 (владелец 16.09.2026: «уменьшил экран, ничего не
   изменилось»). 900 оказался мимо жизни: окно приложения на ноутбуке — это ~1000 CSS-px, и
   человек, сузив его, по-прежнему видел три сдавленные колонки. Порог взят НЕ с потолка: это
   тот же рубеж, на котором «рабочее место» карточки переключается в приложении
   (`_wsWide = 1100`, crm_leads_board_screen.dart) и на котором прячется докнутая карточка
   задачи (`.task-info-panel`, max-width 1080). Ниже 1100 переписка — страница поверх; ниже
   900 вдобавок стопкой встают досье и работа (их два столбца в 900px уже не живут). */
@media (max-width: 1100px) {
  .crmw-chat {
    position: fixed; z-index: 61; top: 0; right: 0; bottom: 0; left: auto;
    width: min(760px, 100vw); height: 100dvh; max-height: none; flex: none;
    border-left: 1px solid var(--line); border-top: 0; border-radius: 0;
    box-shadow: -18px 0 50px rgba(0, 0, 0, .5); overflow: hidden;
    transform: translateX(100%); visibility: hidden;
    transition: transform .22s ease, visibility 0s linear .22s;
  }
  .crm-page.chat-open .crmw-chat { transform: none; visibility: visible; transition: transform .22s ease; }
  .crmw-chat-back {
    display: block; position: fixed; inset: 0; z-index: 60; background: rgba(0, 0, 0, .55);
    opacity: 0; pointer-events: none; transition: opacity .22s ease;
  }
  .crm-page.chat-open .crmw-chat-back { opacity: 1; pointer-events: auto; }
  .crmw-chat-x {
    display: inline-flex; align-items: center; justify-content: center; flex: none;
    margin-left: 0; padding: 4px; border: 0; border-radius: 8px;
    background: transparent; color: var(--muted); cursor: pointer;
  }
  .crmw-chat-x:hover { background: var(--panel-2); color: var(--text); }
  .crmw-chat-x svg.ic { width: 16px; height: 16px; }
  .crmw-chat-h .lead-src, .crmw-chat-chan { margin-left: 0; }
  .crmw-chat-seg > * > span { display: none; }
  .crmw-head-acts .crmw-chat-btn { display: inline-flex; order: -1; }
}
@media (max-width: 900px) {
  .crmw-body { flex-direction: column; overflow-y: auto; }
  .crmw-col { overflow: visible; }
  .crmw-side { flex: none; border-right: 0; border-bottom: 1px solid var(--line); }
  .crmw-head { flex-wrap: wrap; row-gap: 8px; }
  .crmw-head-acts { order: 3; width: 100%; min-width: 0; flex-wrap: wrap; row-gap: 8px; }
  .crmw-head-acts .primary { flex: 1 1 auto; justify-content: center; min-width: 0; max-width: 100%; }
  .crmw-head-acts .primary > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
}
/* Карточка КЛИЕНТА (контакта): та же секция «Переписка» с живым чатом (одна реализация). */
.crm-drawer.has-chat, #crmDrawer.has-chat { width: min(700px, 96vw); }
#crmDrawer .crm-chat-sec { flex: none; }
#crmDrawer .crm-chat-host { display: flex; flex-direction: column; min-height: 0; overflow: hidden;
  height: clamp(300px, 44vh, 520px); border: 1px solid var(--line); border-radius: 14px; background: var(--panel-2); }
#crmDrawer .crm-chat-host:empty { height: 0; border-width: 0; }
#crmDrawer .crm-chat-host > main.thread { display: flex; flex: 1 1 auto; min-height: 0; width: auto; }
#crmDrawer .crm-chat-host .thread-head { padding-left: 12px; border-top-left-radius: 13px; border-top-right-radius: 13px; }
#crmDrawer .crm-chat-host #backToList { display: none !important; }
/* ✨ CLIE-1236 · Стороны переписки у клиента — отдельной строкой ПОД заголовком секции:
   заголовок `.crm-sec-h` набран капителью, и подписи сегмента он сделал бы заглавными. */
.crm-chat-sec-seg { display: flex; align-items: center; gap: 8px; min-width: 0; }
/* ✨ CLIE-1236 · СТОРОНА «АЯ» КОЛОНКИ «ПЕРЕПИСКА» (сделка · лид · очередь · клиент). Разговор
   тот же, что во вкладке «Ая» задачи (`ccTaskAi`), но стоит ВО ВСЮ колонку, как живая лента
   соседних сторон: рамку и подложку даёт хост (колонка или рамка шторки), своя рамка внутри
   была бы второй рамкой. Высоту держит хост — лента разговора прокручивается внутри. */
.crm-chat-host > .crm-tai { flex: 1 1 auto; min-height: 0; margin: 0; display: flex; flex-direction: column; }
.crm-chat-host > .crm-tai > .tai { flex: 1 1 auto; min-height: 0; border: 0; border-radius: 0; box-shadow: none; background: transparent; }
.crm-chat-host > .crm-tai .tai-head { padding: 11px 14px 7px; }
.crm-chat-host > .crm-tai .tai-thread { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 2px 14px 8px; }
.crm-chat-host > .crm-tai .tai-chips, .crm-chat-host > .crm-tai .tai-att { padding-left: 14px; padding-right: 14px; }
.crm-chat-host > .crm-tai .tai-in { margin: 0 12px 12px; }
/* Строки ЖИВОЙ переписки — «кто в беседе» и «клиент канала · бот↔оператор» — к разговору с Аей
   не относятся: на её стороне их нет, а не «нажал — „сначала откройте переписку“». Крестик
   шторки (узкий экран) прижимала вправо как раз кнопка участников — без неё прижимает себя сам. */
.crm-chat-ai .crmw-chat-ppl, .crm-chat-ai .deal-chat-bar { display: none; }
.crm-chat-ai .crmw-chat-x { margin-left: auto; }

.deal-chat-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 9px; }
.deal-chat-bar .deal-thread-mode { margin-left: auto; }
.deal-chat-bar .deal-thread-who { margin-bottom: 0; }
.deal-thread-who.muted { opacity: .7; }
/* Спокойные строки-состояния хоста (открываю / переписки пока нет / ошибка). */
.crm-chat-slot:empty { display: none; }
.crm-chat-note { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-radius: 12px;
  font-size: 12.5px; line-height: 1.45; color: var(--muted); background: var(--panel-2);
  border: 1px solid var(--line); overflow-wrap: anywhere; }
.crm-chat-note .ic { width: 14px; height: 14px; flex: none; opacity: .8; }
.crm-chat-note.err { color: var(--danger); background: var(--danger-soft);
  border-color: color-mix(in srgb, var(--danger) 26%, transparent); }
.crm-chat-retry { margin-left: auto; flex: none; border: 1px solid currentColor; background: transparent;
  color: inherit; font: inherit; font-size: 12px; font-weight: 600; border-radius: 8px; padding: 4px 10px;
  cursor: pointer; transition: background 140ms ease; }
.crm-chat-retry:hover { background: color-mix(in srgb, currentColor 12%, transparent); }
/* Пустое состояние = ОДНО действие «Написать клиенту» (не тупик и не второй экран).
   Кнопка — акцентная, но строка остаётся тихой: экран у пользователя не отбираем. */
.crm-chat-cta { flex-wrap: wrap; }
.crm-chat-start { margin-left: auto; flex: none; border: 1px solid transparent; background: var(--acc-fill);
  color: #fff; font: inherit; font-size: 12px; font-weight: 650; border-radius: 9px; padding: 6px 13px;
  cursor: pointer; transition: filter 140ms ease, opacity 140ms ease, transform 140ms ease; }
.crm-chat-start:hover { filter: brightness(1.06); }
.crm-chat-start:active { transform: scale(.98); }
.crm-chat-start:disabled { opacity: .55; cursor: default; transform: none; filter: none; }
/* «Позвать в ClientsChat» · «Привязать переписку» стоят в ТОЙ ЖЕ строке пустого состояния, что
   «Написать клиенту», но своих правил у них не было: брали глобальный `button` (14px, 10px 14px)
   и выходили 40px рядом с кнопкой 31px (кадр сделки 1440×900: 168–208 и 217–257 против 129–159).
   Размерный класс — тот же, что у `.crm-chat-start`; тон вторичный (обводка без заливки). */
.crm-chat-invite, .crm-chat-link { flex: none; border: 1px solid var(--line); background: transparent;
  color: var(--text); font: inherit; font-size: 12px; font-weight: 650; border-radius: 9px; padding: 6px 13px;
  cursor: pointer; transition: background 140ms ease, opacity 140ms ease; }
.crm-chat-invite:hover, .crm-chat-link:hover { background: color-mix(in srgb, currentColor 8%, transparent); }
.crm-chat-invite:disabled, .crm-chat-link:disabled { opacity: .55; cursor: default; }

/* Раздел «Продажи» не смог отрисоваться (см. renderSalesBody → try/catch): аккуратная карточка
   вместо ЧУЖОГО раздела на экране. */
.sales-fail { max-width: 420px; margin: 48px auto; display: flex; flex-direction: column; align-items: center;
  gap: 8px; text-align: center; padding: 24px 20px; border: 1px solid var(--line); border-radius: 16px;
  background: var(--panel); }
.sales-fail-ic { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
  border-radius: 50%; background: var(--warning-soft); color: var(--warning); }
.sales-fail-ic .ic { width: 17px; height: 17px; }
.sales-fail-t { font-size: 15px; font-weight: 650; color: var(--text); }
.sales-fail-s { font-size: 12.5px; color: var(--muted); }
.sales-fail .primary { width: auto; margin-top: 8px; display: inline-flex; align-items: center; gap: 6px; }
.sales-fail .primary .ic { width: 14px; height: 14px; }
.sales-fail-e { margin-top: 6px; font-size: 11px; line-height: 1.45; color: var(--text-dim);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; overflow-wrap: anywhere; }

@media (max-width: 900px) {
  .lead-list-head { display: none; }
  .lead-row { grid-template-columns: minmax(0, 1fr) 120px; grid-auto-rows: min-content; row-gap: 4px; }
  .lead-row-st, .lead-row-co, .lead-row-owner { display: none; }
  .lead-an-row { grid-template-columns: minmax(110px, 1fr) 56px 56px; }
  .lead-an-bar, .lead-an-w, .lead-an-t { display: none; }
  .lead-flow-act { flex-direction: column; }
}

/* ── Пространство разработки: вкладка «Превью» ───────────────────────────────────
   Живой сайт проекта с машины разработчика. Плоская сетка без «коробок в коробках»:
   тонкая панель состояния сверху, сайт занимает всё остальное. Тёмная тема — теми же
   токенами, что и остальной интерфейс. */
.v2prev { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.v2prev-bar {
  /* 🌍 i18n: английские подписи на 15–40% длиннее русских. Ряд переносится (а не режет
     кнопки и не уезжает за край) — вёрстка держит любой язык, включая немецкий. */
  display: flex; flex-wrap: wrap; row-gap: 6px; align-items: center; gap: 10px; padding: 8px 12px;
  border-bottom: 1px solid var(--line); flex: 0 0 auto;
}
.v2prev-grow { flex: 1 1 auto; }
.v2prev-status { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); min-width: 0; }
.v2prev-status > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2prev-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--muted); flex: 0 0 auto;
  transition: background 140ms ease;
}
.v2prev-dot.on { background: #34c759; box-shadow: 0 0 0 3px rgba(52, 199, 89, .16); }
.v2prev-dot.idle { background: #ff9f0a; box-shadow: 0 0 0 3px rgba(255, 159, 10, .16); }
.v2prev-dot.off { background: #8e8e93; }
.v2prev-acts { display: flex; align-items: center; gap: 6px; }
/* 🔴 [hidden] бессилен против display:flex — панель действий оставалась видимой,
   когда компьютер не подключён (кнопки, которые ничего не делают = мёртвый контрол). */
.v2prev-acts[hidden] { display: none; }
/* q_proj · project-preview-toolbar-1 · обёртка кнопок полосы «Превью» («Показать клиенту», «Доступ ИИ», действия
   машины). Здесь её как бы нет: кнопки остаются детьми .v2prev-bar, раскладка «Штиля» и компьютера прежняя.
   Обёртку раскрывает телефон «Глубины» (depth.css): одна листаемая строка под статусом. */
.v2prev-tools { display: contents; }
.v2prev-btn {
  display: inline-flex; align-items: center; gap: 6px; min-height: 28px; padding: 3px 10px;
  white-space: nowrap; flex: 0 0 auto;   /* 🌍 длинная подпись не сжимает кнопку в кашу */
  border: 1px solid var(--line); border-radius: 8px; background: transparent;
  color: var(--fg); font-size: 13px; cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease;
}
.v2prev-btn:hover { background: var(--hover); }
.v2prev-btn:active { transform: translateY(.5px); }
/* 🔴 `[hidden]` бессилен против `display:inline-flex` — та же грабля, что уже лечили у
   .v2prev-cmd и .v2prev-acts. Без этой строки скрытые кнопки тулбара среды (СРЕД-25:
   «Запустить/Отправить/Терминал», когда машины нет) остаются на экране мёртвыми. */
.v2prev-btn[hidden] { display: none; }
.v2prev-btn .ic { width: 15px; height: 15px; }
/* j_project · project-preview-row-overflow-1 (телефон 390, вкладка «Превью»): ряд действий машины
   (Запустить · Перезапустить · Остановить · Настройки · Логи · Открыть в окне) не переносился. Кнопки nowrap,
   поэтому минимальная ширина ряда = их сумме, и тело вкладки было шире экрана: третья пилюля обрезана на «О…».
   На узком экране ряд встаёт своей строкой и переносится, как сама полоса (.v2prev-bar). Кнопки делят строку, как
   .fsb-acts в файлах. */
@media (max-width: 760px) {
  .v2prev-acts { flex: 1 1 100%; flex-wrap: wrap; row-gap: 6px; min-width: 0; max-width: 100%; }
  .v2prev-acts > .v2prev-btn { flex: 1 0 auto; justify-content: center; }
}
/* «Показать клиенту» — витрина по коммиту. Кнопка видна ВСЕГДА (даже когда машина
   офлайн): ссылку и историю версий смотрят и без запущенного dev-сервера. Акцент лёгкий —
   заливка появляется на наведении, чтобы не спорить с «Запустить». */
.v2prev-show { border-color: color-mix(in srgb, var(--accent) 42%, var(--line)); color: var(--accent); }
.v2prev-show:hover { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.v2prev-show .ic { opacity: .9; }
.v2prev-stage { flex: 1 1 auto; min-height: 0; position: relative; background: var(--bg-soft, transparent); }
.v2prev-frame { width: 100%; height: 100%; border: 0; display: block; background: #fff; }
.v2prev-empty { height: 100%; display: grid; place-items: center; padding: 24px; }
.v2prev-empty-card { max-width: 420px; text-align: center; }
/* Карточка с командой шире: строка установки не должна обрезаться на середине. */
.v2prev-empty-card:has(.v2prev-cmd) { max-width: 640px; }
.v2prev-empty-card h3 { margin: 0 0 6px; font-size: 15px; font-weight: 600; }
.v2prev-empty-card p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--muted); }
/* Путь пропавшей папки (СРЕД-25): его читают ГЛАЗАМИ и сверяют посимвольно, поэтому
   моноширинный и целиком — длинный `/Users/…/projects/…` рвём по границам, а не троеточим. */
.dvs-nodir-path {
  /* Подложку и кромку считаем ОТ ТЕКСТА, а не от токена темы: `--bg-soft` в светлой палитре
     не задан, и плашка там пропадала — путь висел голой строкой, хотя в тёмной был в рамке. */
  margin: 8px 0 !important; padding: 6px 10px; border-radius: 8px;
  border: 1px solid color-mix(in oklab, var(--text) 14%, transparent);
  background: color-mix(in oklab, var(--text) 6%, transparent); color: var(--text) !important;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px !important;
  overflow-wrap: anywhere; text-align: left;
}
.dvs-empty .dvs-nodir-path { margin: 8px auto; max-width: 260px; }

/* ⛔️ СРЕД-26 · «ЗАПУСК УПАЛ» — состояние с ПРИЧИНОЙ, а не бодрое «Сайт не запущен».
   Акцент несут ЗНАЧОК + СЛОВО + мягкая подложка с хэйрлайн-кольцом (правило «никаких левых
   полосок-реек»): вертикальной кромки здесь нет и не будет. Карточка шире обычной — в ней
   живёт хвост лога, который читают глазами и сверяют посимвольно, поэтому и текст слева. */
.v2prev-empty-card.v2prev-fail { max-width: 620px; text-align: left; }
.v2prev-fail h3 { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.v2prev-fail h3 .ic, .v2prev-fail h3 svg { width: 17px; height: 17px; flex: 0 0 auto; color: var(--danger, #ef4444); }
.v2prev-fail-why {
  margin: 0 0 8px !important; padding: 9px 12px; border-radius: 10px;
  background: color-mix(in oklab, var(--danger, #ef4444) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--danger, #ef4444) 24%, transparent);
  color: var(--text) !important; font-size: 13.5px !important; font-weight: 500;
  overflow-wrap: anywhere;
}
.v2prev-fail-hint { margin: 0 !important; }
/* Хвост лога — read-only значение: во всю ширину, кнопки строкой ниже (правило CLIE-425). */
.v2prev-tail {
  margin: 10px 0 0; padding: 9px 11px; max-height: 168px; overflow: auto;
  border-radius: 10px; border: 1px solid var(--line, color-mix(in oklab, var(--text) 14%, transparent));
  background: color-mix(in oklab, var(--text) 5%, transparent);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; line-height: 1.5;
  color: var(--muted); white-space: pre-wrap; overflow-wrap: anywhere;
}
.v2prev-fail-cta { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; text-align: left; }
/* Рядом с залитой «главной» кнопкой второстепенные обязаны читаться КНОПКАМИ, а не ссылками.
   Кромку и подложку считаем ОТ ТЕКСТА, а не от `--line`: в светлой палитре среды он почти
   сливается с холстом (в тулбаре это незаметно из-за группировки, на карточке — заметно). */
.v2prev-fail-cta .v2prev-btn {
  min-height: 34px; padding-inline: 12px;
  border-color: color-mix(in oklab, var(--text) 18%, transparent);
  background: color-mix(in oklab, var(--text) 4%, transparent);
}
.v2prev-fail-cta .v2prev-btn:hover { background: color-mix(in oklab, var(--text) 9%, transparent); }
/* Кнопка-иконка (терминал: «Перезапустить»/«Остановить») подписи не имеет — «идёт» у неё
   показывает не текст, а состояние: гаснет и перестаёт отзываться на курсор. */
.v2prev-btn.is-busy, .v2prev-primary.is-busy { opacity: .6; cursor: progress; }
.v2prev-hint { margin-top: 10px !important; }
.v2prev-hint code {
  padding: 1px 5px; border: 1px solid var(--line); border-radius: 5px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
}
.v2prev-logs {
  flex: 0 0 auto; max-height: 34%; overflow: auto; margin: 0; padding: 10px 12px;
  border-top: 1px solid var(--line); background: var(--bg-soft, transparent);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.45;
  white-space: pre-wrap; color: var(--muted);
}

/* Превью: подключение машины и настройки — крупная типографика, одно действие на экране */
.v2prev-cta { margin-top: 16px; }
/* 0509 · Выходы облака на карточке превью — те же кнопки, что у полосы (`devCloudActsHtml`):
   до трёх в ряд, на узкой колонке переносятся, а не наезжают. */
.v2prev-cta.dvcl-cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
/* 🙋 0514 · «Проект вам не открыт»: просьба — состояние со словами (ждёт / отказ), а не тупик. */
.dvs-closed-note {
  margin: 12px auto 0 !important; padding: 8px 12px; border-radius: 10px; max-width: 360px;
  font-size: 12.5px !important; color: var(--fg) !important;
  background: color-mix(in srgb, var(--primary) 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 18%, transparent);
}
.dvs-closed-note.wait {
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 26%, transparent);
}
/* 560, а не 480: в строке две кнопки («Попросить доступ» и «Поставить задачу», 18.10.2026) — на
   компьютере строка остаётся одной, в узкой колонке кнопки уходят под имя (правило ниже). */
.v2prev-empty-card.dvs-noproj { max-width: 560px; }
.dvs-noproj .dvcp-rows { margin-top: 14px; text-align: left; }
/* 📱 Узкая колонка (телефон, узкое окно). Замер прода 18.10.2026 при 390 px: карточка — элемент
   сетки `.v2prev-empty`, её ширину распирал минимум строки (имя без переноса + «владелец — …» +
   кнопка) — 418 px в колонке 316, заголовок обрезан, «Попросить доступ» за кромкой экрана.
   Карточка занимает колонку (до своего max-width), а не «по содержимому»: у элемента сетки с
   центровкой ширина = max(минимум содержимого, колонка), и одного `min-width: 0` мало — минимум
   строки всё равно побеждал. Строка переносит кнопку под имя — у правого края; на широкой
   карточке строка остаётся одной. */
.v2prev-empty-card.dvs-closed { min-width: 0; width: 100%; }
.dvs-noproj .dvcp-row { flex-wrap: wrap; row-gap: 2px; }
.dvs-noproj .dvcp-row > :last-child { margin-left: auto; }
/* Закрытые проекты — в выборе проекта (под раскрытием) и в пустом состоянии среды. */
.dvcp { margin-top: 6px; border-top: 1px solid var(--line); }
.dvcp > summary {
  display: flex; align-items: center; gap: 8px; padding: 9px 10px; list-style: none; cursor: pointer;
  font-size: 12.5px; color: var(--muted); border-radius: 0 0 10px 10px;
}
.dvcp > summary::-webkit-details-marker { display: none; }
.dvcp > summary:hover { background: var(--hover); color: var(--fg); }
.dvcp > summary svg { width: 14px; height: 14px; flex: none; }
.dvcp-lead { margin: 0 10px 6px; font-size: 11.5px; line-height: 1.45; color: var(--muted); }
.dvcp-rows { display: flex; flex-direction: column; }   /* скроллит поповер/экран, не список */
.dvcp > .dvcp-rows { padding: 0 4px 6px; }
.dvcp-row { display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: 9px; }
.dvcp-row:hover { background: var(--hover); }
.dvcp-name {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 8px; padding: 4px 0;
  border: 0; background: transparent; color: var(--fg); font: inherit; text-align: left; cursor: pointer;
}
.dvcp-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; }
.dvcp-t { font-size: 13px; font-weight: 550; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvcp-o { flex: none; font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 45%; }
.dvcp-row .ghost.small { width: auto; margin: 0; flex: none; box-shadow: inset 0 0 0 1px var(--line); }
.dvcp-st { flex: none; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.dvcp-st.wait { color: var(--warn); font-weight: 600; }
.dvcp-acts { flex: none; display: flex; align-items: center; gap: 6px; }
/* Шапка среды: «Люди» и цифра просьб о доступе (только владельцу). */
.dvs-bar .dvs-people svg { width: 14px; height: 14px; }
.dvs-people-n {
  font-style: normal; min-width: 16px; height: 16px; padding: 0 4px; margin-left: 2px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: #fff; background: var(--acc-fill, var(--primary));
}
.dvs-people-n[hidden] { display: none; }
.v2prev-primary {
  /* 🌍 height→min-height: подпись в две строки (длинный перевод) не обрезается по высоте */
  min-height: 34px; padding: 5px 16px; border: 0; border-radius: 9px; cursor: pointer;
  white-space: nowrap;
  background: var(--acc-fill, var(--cm-5b5bd6, #5b5bd6)); color: #fff; font-size: 14px; font-weight: 500;
  transition: filter 140ms ease, transform 120ms ease;
}
/* Наведение держит СВОЙ фон: общее `button:hover { background: var(--active) }` специфичнее
   `.v2prev-primary` и красило главную кнопку в серый под белым текстом (кадр среды, 17.10). */
.v2prev-primary:hover { background: var(--accent, var(--cm-5b5bd6, #5b5bd6)); filter: brightness(1.06); }
.v2prev-primary:active { transform: translateY(.5px); }
.v2prev-primary:disabled { opacity: .6; cursor: default; }
/* Правило продукта (CLIE-425): read-only поле-значение и его кнопка — на РАЗНЫХ строках.
   Команда подключения длинная, кнопка «Скопировать» рядом с ней съедала её в узкую полоску
   с горизонтальной прокруткой. Эталон — тот же блок в окне «Машины» (.dvm-cmd ниже). */
.v2prev-cmd {
  display: flex; flex-direction: column; align-items: stretch; gap: 8px; margin-top: 16px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; text-align: left;
}
/* 🔴 `[hidden]` бессилен против `display:flex` — рамка пустой команды висела на экране ДО
   нажатия «Получить команду» (та же грабля, что уже лечили у .v2prev-acts и .dvm-cmd). */
.v2prev-cmd[hidden] { display: none; }
.v2prev-cmd code {
  display: block; width: 100%; box-sizing: border-box; word-break: break-all; white-space: normal;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.6;
}
.v2prev-cmd .v2prev-btn { align-self: flex-start; }
.v2prev-form { max-width: 460px; text-align: left; }
/* proj-preview-placeholder-cut-1 · «Что запускать» в «Превью»: при 460 px поле «Папка проекта» рядом с
   «Обзор…» ≈370 px, подсказка обрывалась на «/Users/me/pr…». Текст — общий ключ T() (en-словари), поэтому
   шире карточка, а не короче подсказка. Окно .dvs-setup (тот же класс) не трогаем. */
.v2prev-empty-card.v2prev-form { max-width: 560px; }
.v2prev-form h3, .v2prev-form > p { text-align: center; }
.v2prev-f { display: block; margin-top: 14px; }
.v2prev-f > span { display: block; margin-bottom: 5px; font-size: 12px; color: var(--muted); }
.v2prev-f input {
  width: 100%; height: 34px; padding: 0 10px; box-sizing: border-box;
  border: 1px solid var(--line); border-radius: 9px; background: transparent; color: var(--fg);
  font-size: 14px; transition: border-color 140ms ease;
}
.v2prev-f input:focus { outline: none; border-color: var(--accent, var(--cm-5b5bd6, #5b5bd6)); }
.v2prev-form .v2prev-cta { text-align: center; }
/* Поле «Папка проекта» с нативным выбором (десктоп-приложение) */
/* project-preview-browse-1: `.v2prev-f > span` (подпись поля: display:block, 12px, отступ 5px)
   специфичнее `.v2prev-pick` и ловил и сам ряд — поле 100% шириной, «Обзор…» уезжал строкой ниже
   вплотную (низ поля y=550, верх кнопки y=551). Ряд держит себя той же специфичностью + классом. */
.v2prev-pick, .v2prev-f > .v2prev-pick { display: flex; gap: 8px; align-items: center; margin-bottom: 0; font-size: inherit; color: inherit; }
.v2prev-pick input { flex: 1 1 auto; }
.v2prev-pick .v2prev-btn { flex: 0 0 auto; height: 34px; }

/* ── СБОРКИ: очередь публикации приложений ───────────────────────────────────────
   Токены те же, что у «Превью» (--line/--muted/--fg/--hover/--accent) — обе вкладки
   про одну и ту же подключённую машину и должны читаться как одно пространство.
   Радиусы и тайминги взяты из соседнего блока, а не придуманы заново. */
.v2bld { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.v2bld-bar {
  display: flex; align-items: flex-start; gap: 10px; padding: 8px 12px;
  border-bottom: 1px solid var(--line); flex: 0 0 auto;
}
.v2bld-runner { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: var(--muted); min-width: 0; flex: 1 1 auto; }
/* 🔴 Строка ОБЪЯСНЯЕТ, почему прогон стоит («собирается только на macOS, а такого
   компьютера среди подключённых нет») — обрезать её многоточием значит вернуть то самое
   немое «машина не подключена», на котором владелец потерял сутки. Пусть переносится:
   две строки текста дешевле часа догадок. Ограничиваем тремя — рамка не поедет. */
.v2bld-runner > span { min-width: 0; white-space: normal; overflow: hidden; line-height: 1.35;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; }
.v2bld-runner > .v2prev-dot { flex: 0 0 auto; margin-top: 4px; }
.v2bld-acts { display: flex; align-items: center; gap: 6px; }
.v2bld-acts[hidden] { display: none; }   /* [hidden] бессилен против display:flex */
.v2bld-run { border-color: transparent; background: var(--acc-fill, var(--cm-5b5bd6, #5b5bd6)); color: #fff; }
.v2bld-run:hover { background: var(--accent, var(--cm-5b5bd6, #5b5bd6)); filter: brightness(1.06); }

.v2bld-body { flex: 1 1 auto; min-height: 0; display: flex; align-items: stretch; }
.v2bld-main { flex: 1 1 auto; min-width: 0; min-height: 0; overflow: auto; }
.v2bld-side {
  flex: 0 0 clamp(340px, 46%, 720px); min-width: 0; min-height: 0;
  display: flex; flex-direction: column; border-left: 1px solid var(--line);
}
.v2bld-side[hidden] { display: none; }
@media (max-width: 900px) {
  .v2bld-body { flex-direction: column; }
  .v2bld-side { flex: 1 1 auto; border-left: 0; border-top: 1px solid var(--line); }
}

/* Список прогонов: строки-хэйрлайны, без карточек-«коробок в коробках» */
.v2bld-jobs { display: flex; flex-direction: column; }
.v2bld-job {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 10px 14px;
  border: 0; border-bottom: 1px solid var(--line); background: transparent; color: var(--fg);
  font-size: 13px; text-align: left; cursor: pointer;
  transition: background 120ms ease;
}
.v2bld-job:hover { background: var(--hover); }
.v2bld-job.on { background: var(--hover); box-shadow: inset 2px 0 0 var(--accent, var(--cm-5b5bd6, #5b5bd6)); }
.v2bld-num {
  flex: 0 0 auto; min-width: 34px; color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
}
.v2bld-jt { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2bld-meta { flex: 0 0 auto; color: var(--muted); font-size: 12px; }
.v2bld-hasart { flex: 0 0 auto; color: var(--muted); display: inline-flex; }
.v2bld-hasart .ic { width: 14px; height: 14px; }

.v2bld-chip {
  flex: 0 0 auto; padding: 2px 8px; border-radius: 999px; font-size: 11px; line-height: 16px;
  border: 1px solid var(--line); color: var(--muted);
}
.v2bld-chip.ok   { color: #34c759; border-color: rgba(52, 199, 89, .35); }
.v2bld-chip.err  { color: #ff3b30; border-color: rgba(255, 59, 48, .35); }
.v2bld-chip.wait { color: #ff9f0a; border-color: rgba(255, 159, 10, .35); }
.v2bld-chip.run  { color: var(--accent, var(--cm-5b5bd6, #5b5bd6)); border-color: color-mix(in srgb, var(--accent, var(--cm-5b5bd6, #5b5bd6)) 35%, transparent); }
.v2bld-chip.off  { color: #8e8e93; }

/* Живой лог */
.v2bld-side-head {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
  padding: 8px 12px; border-bottom: 1px solid var(--line); font-size: 13px;
}
.v2bld-log {
  flex: 1 1 auto; min-height: 0; overflow: auto; margin: 0; padding: 10px 12px;
  background: var(--bg-soft, transparent);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.45;
  white-space: pre-wrap; word-break: break-word; color: var(--fg);
}

/* Настройка целей: рецепты кнопками, поля правятся на месте */
.v2bld-setup { padding: 16px; max-width: 720px; margin: 0 auto; }
.v2bld-setup-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.v2bld-setup-head h3 { margin: 0; flex: 1 1 auto; font-size: 15px; font-weight: 600; }
.v2bld-targets { display: flex; flex-direction: column; gap: 10px; }
.v2bld-t { border: 1px solid var(--line); border-radius: 10px; padding: 12px; }
.v2bld-t-row { display: flex; align-items: center; gap: 8px; }
.v2bld-t-name {
  flex: 1 1 auto; min-width: 0; height: 30px; padding: 0 8px; box-sizing: border-box;
  border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--fg);
  font-size: 14px; font-weight: 500; transition: border-color 140ms ease, background 140ms ease;
}
.v2bld-t-name:hover { border-color: var(--line); }
.v2bld-t-name:focus { outline: none; border-color: var(--accent, var(--cm-5b5bd6, #5b5bd6)); }
.v2bld-t-pl {
  flex: 0 0 auto; height: 30px; padding: 0 8px; border: 1px solid var(--line); border-radius: 8px;
  background-color: transparent; color: var(--fg); font-size: 13px; padding-right: 34px; /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
}
.v2bld-t-del {
  flex: 0 0 auto; width: 28px; height: 28px; display: grid; place-items: center;
  border: 1px solid transparent; border-radius: 8px; background: transparent; color: var(--muted); cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.v2bld-t-del:hover { background: var(--hover); color: #ff3b30; }
.v2bld-t-del .ic { width: 14px; height: 14px; }
.v2bld-f { display: block; margin-top: 10px; }
.v2bld-f > span { display: block; margin-bottom: 4px; font-size: 12px; color: var(--muted); }
.v2bld-f input {
  width: 100%; height: 32px; padding: 0 10px; box-sizing: border-box;
  border: 1px solid var(--line); border-radius: 9px; background: transparent; color: var(--fg);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px;
  transition: border-color 140ms ease;
}
.v2bld-f input:focus { outline: none; border-color: var(--accent, var(--cm-5b5bd6, #5b5bd6)); }

.v2bld-addrow { display: flex; align-items: stretch; gap: 8px; flex-wrap: wrap; margin-top: 14px; font-size: 12px; color: var(--muted); }
.v2bld-addrow > span { align-self: center; }
.v2bld-addrow.center { justify-content: center; margin-top: 18px; }
.v2bld-preset {
  display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
  padding: 8px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: transparent; color: var(--fg); cursor: pointer; text-align: left;
  transition: background 120ms ease, border-color 120ms ease;
}
.v2bld-preset:hover { background: var(--hover); border-color: var(--accent, var(--cm-5b5bd6, #5b5bd6)); }
.v2bld-preset b { font-size: 13px; font-weight: 500; }
.v2bld-preset span {
  font-size: 11px; color: var(--muted);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.v2bld-preset.ghost { border-style: dashed; }
/* y1p-builds-mono-1 · «с нуля» под «Своя команда» — пояснение, а не команда: на кадре читалось как
   команда-заглушка рядом с `npm run build`. Шрифт интерфейса; моноширинный — только у строк команд. */
.v2bld-preset.ghost span { font-family: inherit; }
/* «Своя команда» — пресет с классом .ghost. Общее `html[data-theme="light"] .ghost` (вес 0,2,1) ставит
   border-color: transparent и перебивает `.v2bld-preset` (0,1,0): в светлой теме пунктир пропадал и
   оставался голый текст (на кадре контур совпадает с фоном 244,245,248), хотя в тёмной рамка есть.
   Возвращаем кромку и акцент наведения весом (0,3,1) и (0,4,1): обе темы рисуют одну и ту же кнопку. */
html[data-theme="light"] .v2bld-preset.ghost { border-color: var(--line); }
html[data-theme="light"] .v2bld-preset.ghost:hover { border-color: var(--accent); }

/* Обзор папок подключённой машины — лёгкий модальный список, без «коробок в коробках» */
.v2fb-overlay {
  position: fixed; inset: 0; z-index: 9000; display: grid; place-items: center;
  background: rgba(0, 0, 0, .28); backdrop-filter: blur(2px);
  animation: v2fbIn 140ms ease;
}
@keyframes v2fbIn { from { opacity: 0 } to { opacity: 1 } }
.v2fb {
  width: min(560px, 92vw); max-height: 72vh; display: flex; flex-direction: column;
  background: var(--bg, #fff); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 12px 48px rgba(0, 0, 0, .18); overflow: hidden;
}
.v2fb-head, .v2fb-foot {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px; flex: 0 0 auto;
}
.v2fb-head { border-bottom: 1px solid var(--line); }
.v2fb-foot { border-top: 1px solid var(--line); justify-content: flex-end; }
.v2fb-path {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  direction: rtl; text-align: left;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--muted);
}
.v2fb-list { flex: 1 1 auto; overflow: auto; padding: 6px; }
.v2fb-item {
  display: flex; align-items: center; gap: 10px; width: 100%; padding: 8px 10px;
  border: 0; border-radius: 9px; background: transparent; color: var(--fg);
  font-size: 14px; text-align: left; cursor: pointer; transition: background 120ms ease;
}
.v2fb-item:hover { background: var(--hover); }
.v2fb-item .ic { width: 17px; height: 17px; color: var(--muted); flex: 0 0 auto; }
.v2fb-empty { padding: 22px; text-align: center; font-size: 13px; color: var(--muted); }

/* ══ Среда разработчика: файлы · редактор · превью в одном пространстве ══════════ */
.dvs { display: flex; flex-direction: column; height: 100%; min-height: 0; }
.dvs-bar {
  /* 🔴 СРЕД-26/2 · ОДИН РЯД, БЕЗ ПЕРЕНОСА. Раньше тут стоял `flex-wrap: wrap`, и на экране
     владельца «Показать клиенту» с крестиком отваливались второй строкой — шапка росла в
     два этажа и читалась как сломанная вёрстка. Перенос для тулбара неверен в принципе:
     строка одна, а что не влезло — уезжает в «⋯» (devBarFit), как в системных панелях. */
  display: flex; flex-wrap: nowrap; align-items: center; gap: 8px; padding: 8px 12px; flex: 0 0 auto;
  min-width: 0; border-bottom: 1px solid var(--line);
  /* 🔴 16.10.2026 · «НЕ ВЛЕЗАЕТ И НЕ СКРОЛИТСЯ ВБОК» (владелец). Что не влезло и после «⋯» —
     прокручивается (колесо мыши крутит вбок, devBarWatch), а не обрезается вместе с крестиком.
     Полоса тонкая и появляется только при переполнении. */
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain; scrollbar-width: thin;
}
/* Крестик — выход из среды — ПРИБИТ к правому краю: при прокрутке шапки он не уезжает. Подложка
   того же цвета, что окно среды, иначе под ним просвечивали бы кнопки. */
.dvs-bar > [data-dv="close"],
.dvs-bar > .dvs-more {
  position: sticky; right: 0; z-index: 1; flex: 0 0 auto;
  background: var(--bg); box-shadow: -10px 0 8px -6px var(--bg);
}
/* «⋯» держит спрятанные кнопки — прибит рядом с крестиком (отступ ставит devBarFitNow). */
/* 🔴 ОДИН РЯД — ОДИН РАЗМЕРНЫЙ КЛАСС (durable-правило CLIE-505). В шапке среды соседствовали
   контролы 26 / 28 / 30px с радиусами 8 и 9 — на живом экране это и читается как «кривая
   вёрстка». Высоту, радиус и кегль ряда задают токены `--ctl-*`, а не собственные числа
   каждой кнопки. Правило СКОУПЛЕНО в `.dvs-bar`: те же классы живут во вкладке «Превью»
   проекта, где ряд другой, и трогать её мы не вправе. */
.dvs-bar .v2prev-btn,
.dvs-bar .dvs-proj,
.dvs-bar .dvs-branch,
.dvs-bar .dvs-tasklink,
.dvs-bar .dvs-cloud,
.dvs-bar .dvs-who {
  height: var(--ctl-h); min-height: var(--ctl-h);
  border-radius: var(--ctl-r); font-size: var(--ctl-fs);
}
.dvs-more .ic { width: 16px; height: 16px; }
/* 🙋 0514: «Люди» с ждущей просьбой уехала в «⋯» — цифру несёт сама «⋯» (devBarMoreBadge). */
.dvs-bar > .dvs-more[data-n]::after {
  content: attr(data-n); position: absolute; top: 0; right: 0;
  min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px; box-sizing: border-box;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: #fff; background: var(--acc-fill, var(--primary));
}
.dvs-grow { flex: 1 1 auto; }
.dvs-proj {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 9px; background: transparent; color: var(--fg);
  font-size: 14px; font-weight: 500; cursor: pointer; max-width: 260px;
}
.dvs-proj span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-proj:hover { background: var(--hover); }
/* Шеврон селекта машины — того же размера, что у селекта проекта: без своего правила .dvs-state .ic
   брал общее button svg.ic 22px (style.css:7196) — кадр: 12×8 px против 9×5 px у «ClientsChat». */
.dvs-proj .ic, .dvs-state .ic { width: 15px; height: 15px; color: var(--muted); flex: 0 0 auto; }
.dvs-branch {
  display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 8px;
  border: 1px solid transparent; border-radius: 8px; background: transparent;
  font-size: 12px; color: var(--muted); cursor: pointer; max-width: 220px;
  transition: background 120ms ease, border-color 120ms ease;
}
.dvs-branch:hover { background: var(--hover); border-color: var(--line); }
/* 🔴 Та же грабля `[hidden]` vs `display:inline-flex` (СРЕД-25): без этой строки пустая
   пилюля ветки и «пустая рамка задачи» висели в шапке среды, пока git ещё не ответил. */
.dvs-branch[hidden], .dvs-tasklink[hidden] { display: none; }
.dvs-branch > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-branch em { font-style: normal; font-size: 11px; color: var(--accent); }
.dvs-branch .ic { width: 14px; height: 14px; flex: 0 0 auto; }
/* 🙋 0514 · лицо «превью»: выход «Попросить доступ к коду» и состояние просьбы в шапке среды.
   Своя рамка — та же, что у пилюли ветки (высота 26, радиус 8), акцент — словом, без реек. */
.dvs-faceask { display: inline-flex; align-items: center; gap: 4px; flex: 0 0 auto; min-width: 0; }
.dvs-faceask[hidden] { display: none; }
.dvs-faceask-btn {
  display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 10px;
  border: 1px solid color-mix(in srgb, var(--primary) 32%, transparent); border-radius: 8px;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  font-size: 12px; font-weight: 600; color: var(--primary-2); cursor: pointer; white-space: nowrap;
  transition: background 120ms ease, border-color 120ms ease;
}
.dvs-faceask-btn:hover { background: color-mix(in srgb, var(--primary) 20%, transparent); }
.dvs-faceask-btn:disabled { opacity: .6; cursor: default; }
.dvs-faceask-wait {
  display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 8px; border-radius: 8px;
  font-size: 12px; color: var(--fg); white-space: nowrap;
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 26%, transparent);
}
.dvs-faceask .ic { width: 14px; height: 14px; flex: 0 0 auto; }
.dvs-faceask-link {
  height: 26px; padding: 0 6px; border: 0; background: transparent; border-radius: 8px;
  font-size: 12px; color: var(--muted); cursor: pointer; text-decoration: underline; text-underline-offset: 2px;
}
.dvs-faceask-link:hover { color: var(--fg); background: var(--hover); }
/* 🌍 min-width:0 + многоточие — тот же приём, что уже стоит на .v2prev-status (паритет).
   🔴 СРЕД-26/2: но СЖИМАТЬСЯ статусу нельзя. Пока строка была `wrap`, это не было видно; в
   одном ряду чип ужимался до «З…» — подпись, которая не значит ничего. Тесноту разбирает
   devBarFit (прячет кнопки в «⋯»), а не молчаливое схлопывание смысла. */
.dvs-state {
  display: inline-flex; align-items: center; gap: 7px; flex: 0 0 auto;
  min-width: 0; font-size: 12px; color: var(--muted);
}
.dvs-state > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Имя проекта — единственное, чему сжиматься не жалко: у него длинный текст и многоточие
   читается («Лого Созда…»), а нижний предел не даёт схлопнуть его в пыль. */
.dvs-proj { flex: 0 1 auto; min-width: 116px; }
/* 🔴 Раскладка ФЛЕКСОМ, а не гридом: ширину колонок тянут мышью (initWindowResize ставит
   колонке flex-базис). На гриде инлайн-ширина элемента не двигала бы дорожку — колонка
   осталась бы «прибитой», а это прямое нарушение правила продукта «ни одной прибитой ширины». */
.dvs-body { flex: 1 1 auto; min-height: 0; display: flex; align-items: stretch; }
.dvs-body.nopreview .dvs-prev { display: none; }
/* Левая колонка среды — ОДНА панель на два вида (файлы | изменения); тянется мышью
   (WIN_PANES → `#devOverlay .dvs-side`), прибитой ширины нет. */
.dvs-side {
  border-right: 1px solid var(--line); flex: 0 0 248px; min-width: 0;
  display: flex; flex-direction: column; min-height: 0; position: relative;
}
.dvs-files { overflow: auto; padding: 6px; flex: 1 1 auto; min-width: 0; min-height: 0; }
.dvs-files[hidden], .dvs-chg[hidden] { display: none; }

/* ── Э2: переключатель «Файлы | Изменения» и панель изменений ─────────────────── */
/* CLIE-505: вид = канон .cc-seg (+ .cc-seg-md в строке терминала, .cc-seg-sm в шапке
   «Работ ИИ»). Здесь остаются ТОЛЬКО раскладка и счётчик — свой вид сегмента удалён.
   Раньше этот же компонент носил три ad-hoc размера (.dvs-seg / .dvterm-seg / .dvai-seg). */
.dvs-seg { display: flex; margin: 8px 8px 6px; }
.dvs-seg > button { flex: 1 1 0; }
.dvs-seg em {
  font-style: normal; font-size: 10.5px; line-height: 15px; min-width: 16px; padding: 0 4px;
  border-radius: 8px; background: var(--acc-fill); color: #fff; font-weight: 600;
}
.dvs-seg em[hidden] { display: none; }
.dvs-chg { display: flex; flex-direction: column; min-height: 0; flex: 1 1 auto; }
.dvs-chghead {
  display: flex; align-items: center; gap: 8px; padding: 2px 10px 8px; flex: 0 0 auto;
  font-size: 12px; color: var(--muted);
}
.dvs-chgref {
  margin-left: auto; display: inline-flex; width: 24px; height: 24px; align-items: center;
  justify-content: center; border: 0; border-radius: 7px; background: transparent;
  color: var(--muted); cursor: pointer; transition: background 120ms ease;
}
.dvs-chgref:hover { background: var(--hover); color: var(--fg); }
.dvs-chgref .ic { width: 14px; height: 14px; }
/* Список занимает столько, сколько нужно (но не больше панели): коробка коммита идёт
   СРАЗУ под ним, а не улетает в самый низ пустой колонки. */
.dvs-chglist { overflow: auto; padding: 0 6px 6px; flex: 0 1 auto; min-height: 0; }
.dvs-chgrow {
  display: flex; align-items: center; gap: 7px; padding: 3px 6px; border-radius: 8px;
  transition: background 120ms ease;
}
.dvs-chgrow:hover, .dvs-chgrow.open { background: var(--hover); }
/* Чекбокс — тот же рисунок, что у списка доступов (.v2acc-row), только плотнее. */
.dvs-chk { display: inline-flex; align-items: center; flex: 0 0 auto; cursor: pointer; }
.dvs-chk input[type="checkbox"] {
  appearance: none; -webkit-appearance: none; margin: 0; width: 16px; height: 16px;
  border: 1.5px solid var(--line-strong); border-radius: 5px; background: var(--panel);
  cursor: pointer; position: relative; transition: background .13s ease, border-color .13s ease;
}
.dvs-chk:hover input[type="checkbox"] { border-color: var(--muted); }
.dvs-chk input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); }
.dvs-chk input[type="checkbox"]:checked::after {
  content: ""; position: absolute; left: 5px; top: 2px; width: 3px; height: 7px;
  border: solid #fff; border-width: 0 1.8px 1.8px 0; transform: rotate(45deg);
}
.dvs-chk input[type="checkbox"]:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--glow); }
.dvs-chgname {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: baseline; gap: 6px; padding: 3px 0;
  border: 0; background: transparent; color: var(--fg); font-size: 13px; text-align: left; cursor: pointer;
}
.dvs-chgfile { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-chgdir {
  flex: 0 1 auto; min-width: 0; font-size: 11px; color: var(--muted); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left;
}
.dvs-chgst {
  flex: 0 0 auto; width: 17px; height: 17px; display: inline-flex; align-items: center;
  justify-content: center; border-radius: 5px; font-style: normal; font-size: 10.5px;
  font-weight: 700; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--panel-2); color: var(--muted);
}
.dvs-chgst.s-M, .dvs-chgst.s-D { background: var(--danger-soft); color: var(--danger); }
.dvs-chgst.s-A, .dvs-chgst.s-N { background: var(--ok-soft); color: var(--ok); }
.dvs-chgst.s-R, .dvs-chgst.s-C { background: var(--glow); color: var(--accent); }

/* Коробка коммита: появляется, ТОЛЬКО когда что-то отмечено.
   Нижний отступ = место под сквозной пузырь быстрого чата (#qcFab: 56px + 20px снизу):
   иначе он ложится ровно на кнопку «Закоммитить». */
.dvs-commit { flex: 0 0 auto; border-top: 1px solid var(--line); padding: 10px 10px 84px; }
.dvs-commit[hidden] { display: none; }
.dvs-taskchip {
  display: inline-flex; align-items: center; gap: 5px; height: 24px; margin: 0 0 8px;
  padding: 0 8px; border: 1px solid var(--line); border-radius: 8px; background: transparent;
  color: var(--muted); font-size: 12px; cursor: pointer; max-width: 100%;
  transition: background 120ms ease, color 120ms ease;
}
.dvs-taskchip:hover { background: var(--hover); color: var(--fg); }
.dvs-taskchip .ic { width: 13px; height: 13px; flex: 0 0 auto; }
.dvs-taskchip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-msg {
  display: block; width: 100%; box-sizing: border-box; resize: vertical; min-height: 52px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--panel);
  color: var(--fg); font: inherit; font-size: 13px; line-height: 1.4;
  transition: border-color 130ms ease, box-shadow 130ms ease;
}
.dvs-msg:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--glow); }
/* Поле — на всю ширину, кнопки СТРОКОЙ НИЖЕ (правило продукта «поле + кнопка на 2 строки»). */
.dvs-cacts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.dvs-cacts button:disabled { opacity: .55; cursor: default; }
.dvs-cnote { margin: 8px 0 0; font-size: 11.5px; color: var(--muted); }
.dvs-cnote[hidden] { display: none; }
.dvs-cnote.bad { color: var(--danger); }
.dvs-newbr { border-top: 1px solid var(--line); margin-top: 6px; padding: 8px 4px 2px; }
.dvs-newbr .tc-mini { width: 100%; box-sizing: border-box; }
.dvs-newbr-acts { display: flex; gap: 8px; margin-top: 8px; }

/* СРЕД-31 · терминал: ЧЬЮ машину слушаем и почему на чужой нет строки ввода. */
.dvterm-mach { max-width: 190px; }
.dvterm-mach span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvterm-note {
  padding: 8px 12px; font-size: 12px; line-height: 1.45; color: var(--muted);
  border-top: 1px solid var(--line);
}

/* ══ 🔴🔴 СРЕД-32 · «МЫ ОТСТАЁМ» — ПЛАШКА, А НЕ КРОШЕЧНОЕ «↓48» В ЧИПЕ ВЕТКИ ══════════
   Владелец: «Нужен тогда явный интерфейс который показывает что мы отстаем… нужно показать
   что мы подтягиваем». Плашка живёт ПОД шапкой во всю ширину среды и появляется, только
   когда есть что сказать (прогрессивное раскрытие: копия совпала — её нет вовсе).
   🔴 Акцент — иконка + СЛОВО + мягкая подложка с хэйрлайн-кольцом. Никаких левых реек
   (durable-правило CLIE-483): уровень читается текстом, а не оттенком полоски.            */
.dvs-upd {
  display: flex; align-items: center; gap: 10px; flex: 0 0 auto; position: relative;
  margin: 8px 12px 0; padding: 9px 12px; border-radius: 12px;
  font-size: 13px; line-height: 1.35;
  background: color-mix(in srgb, var(--muted) 10%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 22%, transparent);
  animation: dvsUpdIn .16s ease-out both;
}
@keyframes dvsUpdIn { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .dvs-upd { animation: none; } }
/* 🔴 12.10.2026: [hidden] бессилен против display:flex — пустая плашка висела под шапкой всегда */
.dvs-upd[hidden] { display: none; }
/* 0508 · «Минуты облака закончились» — акцент предупреждения (подложка + кольцо, без реек), слова
   сервера в две строки: в них ЧЬИ минуты, сколько из скольких и цена тарифа выше. */
.dvs-upd.dvs-min {
  background: color-mix(in srgb, var(--warning) 12%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 22%, transparent);
}
.dvs-upd.dvs-min .dvs-upd-tx em { white-space: normal; }
/* 0509 · Полоса облака несёт до трёх кнопок («Купить минуты» · «Перейти на тариф…» · «Запустить на
   своём компьютере»): кнопкам не хватает места — они уходят СВОЕЙ строкой под слова, а не сжимают
   фразу сервера в столбик. «Мало минут» — ТИХАЯ полоса (нейтральная подложка, без цвета беды) с
   крестиком «скрыть на сутки»; беду скрыть нельзя, у неё крестика нет. */
.dvs-upd.dvs-min { flex-wrap: wrap; }
.dvs-upd.dvs-min .dvs-upd-tx { flex: 1 1 320px; }
@media (max-width: 900px) { .dvs-upd.dvs-min .dvs-upd-tx { flex-basis: 200px; } }
/* Ряд кнопок сжимается до ширины полосы и переносит кнопки внутри себя (иначе третья вылезала за край). */
.dvs-upd.dvs-min .dvs-upd-acts { flex: 0 1 auto; min-width: 0; max-width: 100%; flex-wrap: wrap; }
.dvs-upd.dvs-min.quiet {
  padding-right: 40px;   /* место крестику: он в углу, а не отдельной строкой на узком экране */
  background: color-mix(in srgb, var(--muted) 10%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 22%, transparent);
}
.dvs-upd-x { position: absolute; top: 7px; right: 7px; display: inline-grid; place-items: center; width: 26px; height: 26px; padding: 0;
  border: 0; border-radius: 8px; background: transparent; color: var(--text-dim); cursor: pointer; }
.dvs-upd-x:hover { background: var(--hover); color: var(--text); }
.dvs-upd-x .ic { width: 14px; height: 14px; }
.dvs-upd > .ic { width: 18px; height: 18px; flex: none; opacity: .85; }
.dvs-upd-tx { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.dvs-upd-tx b { font-weight: 650; }
.dvs-upd-tx em {
  font-style: normal; color: var(--text-dim); font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dvs-upd-acts { display: flex; align-items: center; gap: 8px; flex: none; }
/* 🔴 Размерный класс ряда (--ctl-*), но ВЫСОТОЙ-МИНИМУМОМ: `.v2prev-primary` не флекс сам по
   себе, и жёсткая `height` обрезала подпись «Подтянуть 3» пополам (поймано скриншотом, а не
   глазами по коду). Иконка + слово + счётчик выравниваются здесь, одной строкой на обе кнопки. */
.dvs-upd-acts .v2prev-btn,
.dvs-upd-acts .v2prev-primary {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  min-height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs);
  padding-block: 0; line-height: 1;
}
.dvs-upd-acts .ic { width: 16px; height: 16px; flex: none; }
.dvs-upd-acts em {
  font-style: normal; font-weight: 700; font-size: 11px; margin-left: 6px;
  padding: 1px 6px; border-radius: 999px;
  background: color-mix(in srgb, currentColor 18%, transparent);
}
/* Отстали / разошлись / слетели с ветки — это ПРОБЛЕМА, и она носит цвет предупреждения. */
.dvs-upd.loud {
  background: color-mix(in srgb, var(--warn, #d98324) 12%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn, #d98324) 30%, transparent);
}
.dvs-upd.loud > .ic { color: var(--warn, #d98324); opacity: 1; }
/* Идёт подтягивание: честная шкала «шаг N из 3», а не слепой бегунок. */
.dvs-upd.busy { padding-bottom: 12px; }
.dvs-upd-step { flex: none; color: var(--text-dim); font-size: 12px; font-variant-numeric: tabular-nums; }
.dvs-upd-bar {
  position: absolute; left: 12px; right: 12px; bottom: 6px; height: 3px;
  border-radius: 999px; background: color-mix(in srgb, var(--muted) 20%, transparent); overflow: hidden;
}
.dvs-upd-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--primary); transition: width .2s ease; }
/* Бейдж «есть обновления» на самой кнопке тулбара: плашку может увести в «⋯», кнопку — нет. */
.dvs-bar .v2prev-btn.has-upd { color: var(--primary); }
.dvs-bar .v2prev-btn .dvs-updn {
  font-style: normal; font-weight: 700; font-size: 10.5px; margin-left: 5px;
  padding: 1px 5px; border-radius: 999px; font-variant-numeric: tabular-nums;
  background: var(--acc-fill); color: #fff;
}
@media (max-width: 900px) { .dvs-upd { margin: 8px 8px 0; flex-wrap: wrap; } .dvs-upd-acts { width: 100%; } }

/* Ветки ВИДОМ панели, а не второй страницей (тот же список, что в поповере). */
.dvs-brpane { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 8px; }
.dvbr-inline .dvbr-body { max-height: none; }
/* 🔴 Панель ветки живёт в УЗКОЙ колонке (≈230px): поиск и сегмент в один ряд схлопывали поле
   в пустой квадрат, а имя ветки — в «origin/ta…». Внутри панели ряд переносится, поле идёт
   своей строкой, имя получает всю ширину. Поймано скриншотом, а не глазами по коду. */
.dvbr-inline .dvbr-tools { flex-wrap: wrap; gap: 6px; }
.dvbr-inline .dvbr-q { flex: 1 0 100%; }
.dvbr-inline .dvbr-seg { flex: 1 1 auto; }
.dvbr-inline .dvbr-main { padding-inline: 6px; }
.dvbr-inline .dvbr-name { min-width: 0; }
.dvbr-show {
  display: flex; align-items: center; gap: 8px; margin: 8px 0 4px; padding: 8px 10px;
  border-radius: 10px; font-size: 12px; color: var(--text-dim);
  background: color-mix(in srgb, var(--primary) 8%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 18%, transparent);
}
.dvbr-show span { flex: 1 1 auto; min-width: 0; }
.dvbr-show b { color: var(--text); font-weight: 650; }

/* 🔀 СРЕД-31 · ПАНЕЛЬ ВЕТОК: поиск + сортировка + ВСЯ информация в строке + слияние.
   Раньше здесь был столбик голых имён. Акцент несут ТОЧКА и СЛОВО (никаких левых реек):
   точка — где стоишь / чужая серверная ветка, слово — «здесь» / «на сервере».            */
.dvbr { display: flex; flex-direction: column; min-height: 0; }
.dvbr-tools { display: flex; align-items: center; gap: 8px; padding: 0 4px 8px; }
.dvbr-q { flex: 1 1 auto; min-width: 0; }
.dvbr-body { max-height: min(52vh, 430px); overflow: auto; margin: 0 -4px; padding: 0 4px; }
.dvbr-list { display: flex; flex-direction: column; gap: 2px; }
.dvbr-sec {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); padding: 12px 4px 6px;
}
/* 🔴🔴 СРЕД-32·3 · СТРОКА ВЕТКИ НЕ НАЛЕЗАЕТ САМА НА СЕБЯ.
   Владелец прислал скрин панели «Ветки»: «посмотри дизайн, ВСЁ НАЛЕЗАЕТ, как с этим
   работать?». Панель живёт в УЗКОЙ колонке среды (замер: ~363px), а строка ветки несла в
   один ряд имя, две пилюли, расхождение и ТРИ действия (👁 · 🗑 · «Влить») — из них два
   `flex:none`. Текстовой части оставалось меньше её собственного минимума, и вторая
   строка (автор · дата · сообщение коммита) уходила ПОД кнопки.
   Лестница та же, что у сегментов (СРЕД-33): сначала ужимаем текст, потом честно
   переносим действия на свою строку — но НЕ прячем их (кнопка, которой не видно, для
   человека не существует, это уже проходили с «Влить»). */
.dvbr-row {
  display: flex; align-items: center; gap: 6px; border-radius: 9px;
  flex-wrap: wrap; row-gap: 0;
}
.dvbr-row:hover { background: var(--panel-2); }
.dvbr-main {
  flex: 1 1 200px; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  padding: 7px 8px; border: 0; background: none; color: inherit; text-align: left;
  border-radius: 9px; cursor: pointer; font: inherit;
  /* Кнопка — не резиновый мешок: что не влезло, обрезается ЗДЕСЬ, а не рисуется поверх соседа. */
  overflow: hidden;
}
.dvbr-line1 { display: flex; align-items: center; gap: 7px; min-width: 0; max-width: 100%; }
.dvbr-line2 {
  max-width: 100%;
  color: var(--text-dim); font-size: 11.5px; line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-left: 13px;
}
/* Действия, уехавшие на свою строку, выравниваем ПО ТЕКСТУ (тот же отступ 13+8, что у
   второй строки), а не по кромке панели — иначе они читаются как чужие. */
.dvbr-row > .dvbr-ico:nth-of-type(2) { margin-left: 21px; }

.dvbr-dot {
  width: 6px; height: 6px; flex: none; border-radius: 50%;
  background: color-mix(in srgb, var(--muted) 55%, transparent);
}
.dvbr-dot.cur { background: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent); }
.dvbr-dot.rem { background: none; box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--muted) 70%, transparent); }
.dvbr-name {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 13px; font-weight: 500;
}
.dvbr-row.on .dvbr-name { font-weight: 650; }
.dvbr-tag {
  flex: none; font-size: 10.5px; line-height: 1; padding: 3px 6px; border-radius: 999px;
  color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}
.dvbr-tag.rem { color: var(--muted); background: color-mix(in srgb, var(--muted) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 20%, transparent); }
.dvbr-div { flex: none; margin-left: auto; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.dvbr-mg {
  flex: none; height: 26px; padding: 0 10px; border-radius: 8px; cursor: pointer;
  font: inherit; font-size: 12px; margin-right: 4px;
  color: var(--text); background: var(--panel-2); border: 1px solid var(--line);
  /* 🔴 НЕ ПРЯЧЕМ ДО НАВЕДЕНИЯ. Владелец пришёл ровно с «нет кнопки смержить» — кнопка,
     которая появляется только под курсором, для него не существует. Приглушена, но видна
     всегда; наведение лишь усиливает. */
  opacity: .62; transition: opacity .13s ease, background .13s ease, border-color .13s ease;
}
.dvbr-row:hover .dvbr-mg, .dvbr-mg:focus-visible, .dvbr-mg:hover { opacity: 1; }
.dvbr-mg:hover { background: color-mix(in srgb, var(--primary) 12%, var(--panel-2)); border-color: color-mix(in srgb, var(--primary) 34%, var(--line)); }
.dvbr-into {
  width: 100%; box-sizing: border-box; display: flex; align-items: center; gap: 8px;
  min-height: var(--ctl-h); padding: 0 10px; margin-bottom: 8px; cursor: pointer; font: inherit;
  font-size: var(--ctl-fs); font-weight: 600; border-radius: var(--ctl-r);
  color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 26%, transparent);
  transition: background .13s ease;
}
.dvbr-into:hover { background: color-mix(in srgb, var(--primary) 16%, transparent); }
.dvbr-into svg { width: 15px; height: 15px; flex: none; }
.dvbr-into span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvbr-busy { display: flex; align-items: center; gap: 9px; padding: 18px 8px; color: var(--muted); font-size: 12.5px; }
.dvbr-res { padding: 4px 4px 2px; }
.dvbr-res h4 { margin: 0 0 6px; font-size: 13.5px; font-weight: 650; }
.dvbr-res p { margin: 0 0 8px; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.dvbr-dim { color: var(--text-dim); font-size: 11.5px; }
.dvbr-files {
  margin: 0 0 10px; padding: 8px 10px; list-style: none; border-radius: 9px;
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line);
  max-height: 168px; overflow: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; line-height: 1.7;
}
.dvbr-acts { display: flex; flex-wrap: wrap; gap: 8px; }

/* Один инлайновый «идёт» на весь продукт (его уже просил инспектор превью — `.pvi-load`,
   и до сих пор рисовал ПУСТОТУ: класс был, правила не было). */
.cc-spin {
  width: 14px; height: 14px; flex: none; border-radius: 50%;
  border: 2px solid color-mix(in srgb, currentColor 24%, transparent);
  border-top-color: var(--primary); animation: ccSpin .7s linear infinite;
}
@keyframes ccSpin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .cc-spin { animation-duration: 2.4s; } }

.dvs-path {
  padding: 6px 8px 8px; font-size: 11px; color: var(--muted); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; text-align: left;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.dvs-row {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px; border: 0;
  border-radius: 8px; background: transparent; color: var(--fg); font-size: 13px; text-align: left;
  cursor: pointer; transition: background 120ms ease;
}
.dvs-row span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-row .ic { width: 15px; height: 15px; color: var(--muted); flex: 0 0 auto; }
.dvs-row:hover { background: var(--hover); }
.dvs-row.on { background: var(--hover); font-weight: 600; }
.dvs-row.up { color: var(--muted); }

/* ── СРЕД-26/2 · строка дерева = отметка «для ИИ» + сама строка ───────────────────
   Галочка не отбирает экран: место под неё есть всегда (иначе строки прыгали бы),
   но видна она на наведении, у выбранных и на фокусе с клавиатуры. */
.dvs-trow { display: flex; align-items: center; gap: 2px; border-radius: 8px; }
.dvs-trow > .dvs-chk { width: 22px; justify-content: center; opacity: 0; transition: opacity 130ms ease; }
.dvs-trow:hover > .dvs-chk,
.dvs-trow.on > .dvs-chk,
.dvs-trow > .dvs-chk:focus-within { opacity: 1; }
/* 🔴🔴 ВЫБОР НЕСКОЛЬКИХ ПАПОК И ФАЙЛОВ ВИДЕН (владелец 16.09.2026: «возможность сразу
   несколько папок выбрать — по факту нет таких возможностей»). Возможность была, но вход в
   неё жил только под мышью: `opacity: 0` до :hover. Замер на проде — `opacity=0` у чекбокса
   папки. Два лечения: явный тумблер «Выбрать» над деревом и hover, которого на тач-экране
   НЕ БЫВАЕТ вовсе — там чекбоксы показываем всегда. */
.dvs-files.pickon .dvs-trow > .dvs-chk { opacity: 1; }
@media (hover: none) { .dvs-trow > .dvs-chk { opacity: 1; } }
.dvs-pathrow {
  display: flex; align-items: center; gap: 6px;
  border-bottom: 1px solid var(--line); margin-bottom: 4px;
}
.dvs-pathrow > .dvs-path { flex: 1 1 auto; min-width: 0; border-bottom: 0; margin-bottom: 0; }
.dvs-pickmode {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; height: 22px;
  margin-right: 6px; padding: 0 7px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg); color: var(--muted); font-size: 11px; cursor: pointer; white-space: nowrap;
  transition: background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.dvs-pickmode:hover { background: var(--hover); color: var(--fg); border-color: var(--fg); }
.dvs-pickmode.on { background: var(--hover); border-color: var(--fg); color: var(--fg); font-weight: 600; }
.dvs-pickmode .ic { width: 12px; height: 12px; }
.dvs-trow > .dvs-chk input[type="checkbox"] { width: 14px; height: 14px; border-radius: 4px; }
.dvs-trow > .dvs-chk input[type="checkbox"]:checked::after { left: 4px; top: 1px; width: 3px; height: 6px; }
.dvs-trow.on { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.dvs-trow.on > .dvs-row { background: transparent; }
.dvs-trow.on > .dvs-row .ic { color: var(--accent); }
/* Строка-кнопка рядом с галочкой: `width:100%` + галочка 22 + зазор 2 > ширины ряда, а min-width:auto
   флекс-элемента не даёт ей ужаться ниже min-content (полное имя) — длинное имя уезжало за кромку
   карточки на ≤24 px и резалось ею, без «…». min-width:0 — и многоточие ставит сам span имени. */
.dvs-trow > .dvs-row { min-width: 0; }

/* ── СРЕД-40 · ДЕРЕВО КАК ФАЙЛОВЫЙ МЕНЕДЖЕР ───────────────────────────────────────
   Заказчик: «дизайн файловой структуры… как в нормальном файловом менеджере». Плоский
   список одного уровня стал деревом, поэтому строке нужны три вещи, которых у неё не
   было: ОТСТУП по глубине, МЕСТО под раскрывашку (одинаковое у папки и файла, иначе
   имена пляшут) и ЗНАЧОК, по которому вид файла читается, не читая расширение.
   Отступ — переменная `--dvd` (глубина), а не вложенные <ul>: дерево рисуется ОДНИМ
   плоским списком, и вложенный DOM на 10 тыс. строк нам не нужен.
   🔴 Чернила меряются к СВОЕЙ подложке (канон contrast-runtime-audit): строка лежит на
   var(--panel) боковой колонки, поэтому вторичное — var(--muted), третичное —
   var(--text-dim), и оба уже выверены в обеих темах. */
.dvs-row { padding-left: calc(8px + var(--dvd, 0) * 13px); }
.dvs-row > .dvs-tw {
  width: 14px; height: 14px; flex: 0 0 auto; margin-right: -2px;
  display: inline-flex; align-items: center; justify-content: center; color: var(--text-dim);
}
.dvs-row > .dvs-tw .ic { width: 12px; height: 12px; color: inherit; }
.dvs-row:hover > .dvs-tw { color: var(--muted); }

/* Вид файла — цветом ЗНАЧКА, не заливкой строки: цвет подсказывает, а не кричит.
   Оба набора заданы явно, потому что это семантические оттенки языка (js/css/md), а не
   состояния продукта; в светлой теме те же семьи, но темнее — пастель на белом не видна
   (contrast-runtime-audit: чернила иконки меряются к белой карточке, а не к тёмной). */
.dvs-row.dir .ic { color: var(--accent); }
.dvs-row.code .ic   { color: #e5c07b; }   /* js · ts · py · ex — «исполняемое» */
.dvs-row.vue .ic    { color: #42b883; }   /* vue · svelte */
.dvs-row.markup .ic { color: #e06c75; }   /* html · xml */
.dvs-row.style .ic  { color: #61afef; }   /* css · scss */
.dvs-row.data .ic   { color: #98c379; }   /* json · yaml · toml · env */
.dvs-row.text .ic   { color: #c8ccd4; }   /* md · txt */
.dvs-row.media .ic  { color: var(--cm-c678dd, #c678dd); }   /* png · svg · mp4 */
html[data-theme="light"] .dvs-row.code .ic   { color: #a1690a; }
html[data-theme="light"] .dvs-row.vue .ic    { color: #157f52; }
html[data-theme="light"] .dvs-row.markup .ic { color: #b93b46; }
html[data-theme="light"] .dvs-row.style .ic  { color: #1f6fb2; }
html[data-theme="light"] .dvs-row.data .ic   { color: #3d7a22; }
html[data-theme="light"] .dvs-row.text .ic   { color: #6b7280; }
html[data-theme="light"] .dvs-row.media .ic  { color: var(--cm-8a3fb0, #8a3fb0); }

/* Скрытый файл (`.env`, `.gitignore`) ВИДЕН — заказчик именно про это и писал, — но
   приглушён: он есть, он не главный. «Похоже на секрет» носит замок и тёплый оттенок:
   это подсказка «тут может лежать чувствительное», а не запрет (право решает сервер). */
.dvs-row.hid { color: var(--muted); }
.dvs-row.hid .ic { opacity: .72; }
.dvs-row.sec .ic { color: var(--warn); opacity: 1; }
.dvs-row.sec span { color: var(--muted); }

/* Крошки — НАВИГАЦИЯ, а не подпись: по каждому сегменту можно вернуться в его папку.
   Прежний `direction: rtl` (обрезал длинный путь с головы) здесь запрещён — он бы
   переставил кнопки задом наперёд; длинный путь уезжает прокруткой. */
.dvs-path {
  direction: ltr; display: flex; align-items: center; gap: 2px; flex-wrap: nowrap;
  overflow-x: auto; scrollbar-width: none; padding: 7px 8px 8px;
  border-bottom: 1px solid var(--line); margin-bottom: 4px;
}
.dvs-path::-webkit-scrollbar { height: 0; }
.dvs-path button {
  border: 0; background: transparent; color: var(--muted); cursor: pointer;
  font: inherit; font-size: 11px; padding: 2px 5px; border-radius: 6px; white-space: nowrap;
  transition: background 120ms ease, color 120ms ease;
}
.dvs-path button:hover { background: var(--hover); color: var(--fg); }
.dvs-path b { color: var(--fg); font-weight: 600; padding: 2px 3px; white-space: nowrap; }
/* Имя ОТКРЫТОГО файла — главное в крошках: сжимаются головные сегменты (корень, папки) с
   многоточием, а последний остаётся целым. Иначе длинный корень («wolf-autodoc») выталкивал
   имя файла за край ряда (16.10.2026). Полный путь — в title сегмента. */
.dvs-path button { flex: 0 1 auto; min-width: 2.5em; overflow: hidden; text-overflow: ellipsis; }
.dvs-path b { flex: 0 0 auto; }
.dvs-crsep { color: var(--text-dim); font-style: normal; flex: 0 0 auto; }

/* Плашка «файл разошёлся с машиной» — над деревом, со СЛОВАМИ и двумя выходами
   (правило выхода: состояние обязано быть видно там, где его встретят). */
.dvs-fsbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 4px 4px 8px; padding: 8px 10px; border-radius: 10px; font-size: 12px;
  color: var(--fg); background: color-mix(in srgb, var(--warn) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 30%, transparent);
}
.dvs-fsbar span { flex: 1 1 160px; min-width: 0; }
.dvs-fsbar button {
  border: 0; border-radius: 7px; padding: 4px 9px; font: inherit; font-size: 12px;
  cursor: pointer; background: var(--hover); color: var(--fg); white-space: nowrap;
  transition: background 120ms ease;
}
.dvs-fsbar button:hover { background: color-mix(in srgb, var(--warn) 22%, transparent); }
.dvs-fsbar button.primary { background: var(--acc-fill); color: #fff; }
.dvs-fsbar button.primary:hover { background: var(--acc-fill-hi); }

/* Коробка «выбрано для ИИ» — под деревом, ровно как коробка коммита в «Изменениях».
   Нижний отступ тот же (84px): сквозной пузырь быстрого чата (#qcFab) лежит в этом же
   углу и без него накрыл бы кнопку «Дать задачу ИИ». */
.dvs-picked {
  flex: 0 0 auto; border-top: 1px solid var(--line); padding: 10px 10px 84px;
  display: flex; flex-direction: column; gap: 8px; background: var(--panel);
}
.dvs-picked[hidden] { display: none; }
.dvs-picked-h { display: flex; align-items: center; gap: 8px; }
.dvs-picked-n { font-size: 12px; font-weight: 600; color: var(--fg); }
.dvs-picked-x {
  margin-left: auto; border: 0; background: transparent; color: var(--muted);
  font-size: 12px; cursor: pointer; padding: 2px 4px; border-radius: 6px;
  transition: background 120ms ease, color 120ms ease;
}
.dvs-picked-x:hover { background: var(--hover); color: var(--fg); }
.dvs-picked-list { display: flex; flex-wrap: wrap; gap: 5px; }
.dvs-picked-chip {
  display: inline-flex; align-items: center; gap: 4px; max-width: 100%; padding: 2px 7px;
  border: 1px solid var(--line); border-radius: 7px; background: var(--panel-2);
  font-size: 11.5px; color: var(--muted);
}
.dvs-picked-chip .ic { width: 12px; height: 12px; flex: 0 0 auto; }
.dvs-picked-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-picked-more { align-self: center; font-size: 11.5px; color: var(--muted); }
.dvs-picked-go { display: inline-flex; align-items: center; justify-content: center; gap: 6px; width: 100%; }
.dvs-picked-go .ic { width: 15px; height: 15px; }
/* Пропорции те же, что были на гриде (1fr | .85fr) — но флекс-базисом, чтобы колонку
   можно было утянуть мышью, а без превью колонка кода занимала всё сама. */
/* Код — РЕЗИНОВЫЙ и занимает всё, что осталось от правой панели. Нижние пределы обеих колонок
   живут в медиазапросе ниже: на узком окне (там ресайз выключен, WIN_MIN_VP = 721) жёсткий
   `min-width` вызвал бы горизонтальную прокрутку вместо честного сжатия. */
.dvs-edit { display: flex; flex-direction: column; min-width: 0; min-height: 0; flex: 1 1 0; border-right: 1px solid var(--line); }
@media (min-width: 721px) {
  /* Ни код, ни панель не имеют права схлопнуться в полоску: сжимается сперва правая
     панель (`flex-shrink:1`), а ниже 320/260 не идёт ни одна.
     🔴 18.10.2026 · Предел панели — с `.dvs-body >`: базовое `.dvs-prev { min-width: 0 }` стоит
     НИЖЕ в файле и молча его перебивало (замер прода при 768: колонка ИИ 88px, подсказка
     чата столбиком по слогу). Где три колонки не влезают вовсе — одна за раз (блок ≤959 ниже). */
  .dvs-edit { min-width: 320px; }
  .dvs-body > .dvs-prev { min-width: 260px; }
}

/* ── Вкладки открытых файлов ─────────────────────────────────────────────────────
   Несохранённое — точкой на месте крестика (крестик возвращается на наведение), как в
   системных редакторах: индикатор не отбирает место и не добавляет ещё одну кнопку. */
.dvs-tabbar {
  display: flex; align-items: stretch; flex: 0 0 auto; min-height: 36px;
  background: var(--panel); border-bottom: 1px solid var(--line);
}
.dvs-tabs { display: flex; align-items: stretch; flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.dvs-tabs::-webkit-scrollbar { height: 0; }
.dvs-tabi {
  position: relative; display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  max-width: 210px; height: 36px; padding: 0 8px 0 12px; border: 0; border-right: 1px solid var(--line);
  background: transparent; color: var(--muted); font-size: 12.5px; cursor: pointer;
  transition: background 130ms ease, color 130ms ease;
}
.dvs-tabi:hover { background: var(--hover); color: var(--text); }
.dvs-tabi.on { background: var(--panel-2); color: var(--text); font-weight: 590; }
.dvs-tabi.on::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px;
  background: var(--primary); border-radius: 2px 2px 0 0;
}
.dvs-tabn { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-tabd { display: none; width: 7px; height: 7px; border-radius: 50%; background: var(--primary); flex: 0 0 auto; }
.dvs-tabx {
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 18px; height: 18px; border-radius: 5px; color: var(--muted); opacity: 0;
  transition: opacity 130ms ease, background 130ms ease;
}
.dvs-tabx .ic { width: 11px; height: 11px; }
.dvs-tabi:hover .dvs-tabx, .dvs-tabi.on .dvs-tabx { opacity: .75; }
.dvs-tabx:hover { background: var(--active); opacity: 1; color: var(--text); }
.dvs-tabi.dirty .dvs-tabd { display: block; }
.dvs-tabi.dirty .dvs-tabx { display: none; }
.dvs-tabi.dirty:hover .dvs-tabd { display: none; }
.dvs-tabi.dirty:hover .dvs-tabx { display: flex; opacity: .9; }
/* 🌍 «Unsaved · Cmd+S» шире русского: ужимаем многоточием, а не выдавливаем соседей. */
.dvs-save { align-self: center; padding: 0 12px; min-width: 0; max-width: 45%; overflow: hidden;
  text-overflow: ellipsis; font-size: 11px; font-style: normal; color: var(--muted); white-space: nowrap; }

.dvs-edwrap { position: relative; flex: 1 1 auto; min-height: 0; }
.dvs-mon { position: absolute; inset: 0; }
.dvs-blank {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 6px; padding: 24px; text-align: center;
  background: var(--panel); color: var(--muted); font-size: 13px;
}
.dvs-blank[hidden] { display: none; }   /* 🔴 [hidden] бессилен против display:flex */
.dvs-blank p { margin: 0; }
/* Сравнение правок ИИ (Э3) — СВОЙ слой поверх редактора: вкладки, undo и позиции курсора
   остаются живы, «Закрыть сравнение» возвращает ровно то, что было открыто. */
.dvs-diff { position: absolute; inset: 0; display: flex; flex-direction: column; background: var(--panel); z-index: 3; }
.dvs-edwrap.has-diff .dvs-blank { display: none; }
.dvs-diff-bar {
  display: flex; align-items: center; gap: 10px; padding: 6px 8px 6px 12px; flex: 0 0 auto;
  border-bottom: 1px solid var(--line);
}
.dvs-diff-p {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl;
  text-align: left; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
}
.dvs-diff-m { flex: 0 0 auto; font-size: 11px; color: var(--muted); }
/* 🌍 Толкатель — только на ПЕРВОЙ кнопке: иначе каждая следующая уезжает вправо и
   при переносе ряда они расходятся по краям. Высота — min, подпись не режется. */
.dvs-diff-bar .v2prev-btn { min-height: 26px; white-space: nowrap; flex: 0 0 auto; }
.dvs-diff-bar .v2prev-btn:first-of-type { margin-left: auto; }
.dvs-diff-mon { flex: 1 1 auto; min-height: 0; }
.dvs-blank-k { font-size: 12px; color: var(--text-dim); }
.dvs-blank-k b { font-weight: 600; color: var(--muted); }

/* Подсветка результата перехода (⌘G и клик по совпадению): строка тонируется, само
   совпадение обведено — видно, КУДА попал, а не «просто проскроллилось». */
.dvs-hit { background: var(--sel); box-shadow: inset 2px 0 0 var(--primary); }
.dvs-hit-x { background: color-mix(in srgb, var(--primary) 34%, transparent); border-radius: 3px; }

/* ── Палитра: файл (⌘P) · текст по проекту (⌘⇧F) · строка (⌘G) ─────────────────── */
.dvs-pal-wrap {
  position: absolute; inset: 0; z-index: 40; display: flex; justify-content: center;
  align-items: flex-start; padding: min(13vh, 110px) 16px 16px;
  background: var(--cm-080a0f-34, rgba(8, 10, 15, .34)); animation: dvsPalIn 140ms ease-out;
}
html[data-theme="light"] .dvs-pal-wrap { background: var(--cm-141928-18, rgba(20, 25, 40, .18)); }
@keyframes dvsPalIn { from { opacity: 0 } to { opacity: 1 } }
.dvs-pal {
  width: min(720px, 100%); max-height: min(64vh, 560px); display: flex; flex-direction: column;
  background: var(--panel-3); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow-3); overflow: hidden;
}
.dvs-pal-top { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--line); }
.dvs-pal-ic { display: flex; color: var(--muted); flex: 0 0 auto; }
.dvs-pal-ic .ic { width: 16px; height: 16px; }
.dvs-pal-q {
  flex: 1 1 auto; min-width: 0; border: 0; background: transparent; color: var(--text);
  font-size: 15px; outline: none; padding: 4px 0;
}
.dvs-pal-q::placeholder { color: var(--text-dim); }
.dvs-pal-modes { display: flex; gap: 2px; flex: 0 0 auto; padding: 2px; border-radius: 9px; background: var(--seg-track); }
.dvs-pal-m {
  display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 8px; border: 1px solid transparent;
  border-radius: 7px; background: transparent; color: var(--muted); font-size: 11.5px; cursor: pointer;
  transition: background 130ms ease, color 130ms ease;
}
.dvs-pal-m em { font-style: normal; opacity: .65; font-size: 10.5px; }
.dvs-pal-m:hover { color: var(--text); }
.dvs-pal-m.on { background: var(--seg-thumb); border-color: var(--seg-thumb-bd); box-shadow: var(--seg-thumb-sh); color: var(--text); }
.dvs-pal-list { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 6px; }
.dvs-pal-list.busy { opacity: .55; }
.dvs-pal-h {
  padding: 9px 10px 4px; font-size: 11px; color: var(--muted); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.dvs-pal-r {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 10px; border: 0;
  border-radius: 8px; background: transparent; color: var(--text); font-size: 13px;
  text-align: left; cursor: pointer; min-width: 0;
}
.dvs-pal-r:hover { background: var(--hover); }
.dvs-pal-r.on { background: var(--sel); }
.dvs-pal-r mark { background: color-mix(in srgb, var(--primary) 28%, transparent); color: inherit; border-radius: 3px; padding: 0 1px; }
.dvs-pal-fi { display: flex; color: var(--muted); flex: 0 0 auto; }
.dvs-pal-fi .ic { width: 15px; height: 15px; }
.dvs-pal-n { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-pal-d { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left; font-size: 11.5px; color: var(--text-dim); }
.dvs-pal-open { flex: 0 0 auto; font-style: normal; font-size: 10.5px; color: var(--muted); border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px; }
.dvs-pal-ln { flex: 0 0 auto; min-width: 34px; text-align: right; font-size: 11.5px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.dvs-pal-code {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: pre;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
}
.dvs-pal-foot { flex: 0 0 auto; padding: 8px 14px; border-top: 1px solid var(--line); font-size: 11.5px; color: var(--muted); }

/* 🔴 ПРАВАЯ ПАНЕЛЬ СРЕДЫ (превью · сборки · ИИ) — СВОЯ ЧЕСТНАЯ ШИРИНА, А НЕ «ОСТАТОК».
   Было `flex: .85 1 0` — чистая доля роста без собственного размера и БЕЗ ПОТОЛКА. Как только
   колонка кода получала прибитую ширину (её запоминал WIN_PANES), панель оставалась
   единственным растяжимым элементом и забирала весь экран: у владельца редактор превращался в
   узкую полоску, а справа зияла почти пустая панель ИИ (СРЕД-26/4, замер: 503px из 1440 при
   двух строчках текста внутри). Теперь размер задаём мы: ~32% ширины тела, но не уже 320 и не
   шире 520 — дальше человек тянет мышью сам (шов на левой кромке, WIN_PANES → `.dvs-prev`). */
.dvs-prev { min-width: 0; display: flex; flex: 0 1 clamp(320px, 32%, 520px); }
.dvs-frame { flex: 1 1 auto; border: 0; background: #fff; }
.dvs-hint { padding: 20px; font-size: 13px; color: var(--muted); text-align: center; }
.v2prev-btn.on { background: var(--hover); border-color: var(--fg); }
.dvs-empty { padding: 26px 16px; text-align: center; }
.dvs-empty p { margin: 0 0 14px; font-size: 13px; line-height: 1.5; color: var(--muted); }
/* Выход отказа и запасной путь — столбиком одной ширины и высоты: панель файлов узкая
   (~230px), в ряд две кнопки не встают, а вплотную разной высоты они читаются как сбой. */
.dvs-empty-acts { display: flex; flex-direction: column; align-items: stretch; gap: 8px; max-width: 240px; margin: 0 auto; }
.dvs-empty-acts > .v2prev-btn { justify-content: center; min-height: 34px; }

/* ══════ 🪟 ПРЕВЬЮ КАК ОКНО + 🔎 ИНСПЕКТОР ЭЛЕМЕНТА (задача «Превью») ══════════════════
   Владелец: «превью открыть на весь экран и сделать отдельной модалкой как окно в
   виндоусе — свернуть вниз, настроить размер, перетаскивать по экрану».
   Одна разметка на оба режима: в колонке и в окне это ОДИН `.dvs-pv*` — меняется только
   рама. Второго набора правил «то же самое, но для окна» здесь нет намеренно.            */
.dvs-pv { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; min-height: 0; }
.dvs-pvmain { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; min-width: 0; }
.dvs-pvmain.wide { flex-direction: row; }
/* 🔴 Кадр превью: тёмная тема — ДЕФОЛТ (атрибута нет), светлая = html[data-theme="light"].
   Правило было написано наоборот (html[data-theme="dark"]) и не срабатывало НИКОГДА: в тёмном
   интерфейсе окно превью светилось белым прямоугольником, и состояния («папка не найдена»,
   «сайт не запущен»), которые рисуются прямо в кадре, читались как дыра. Те же грабли уже
   ловили на Monaco (СРЕД, Э2). */
.dvs-pvstage { position: relative; display: flex; flex: 1 1 auto; min-height: 0; min-width: 0; background: #0f1115; }
html[data-theme="light"] .dvs-pvstage { background: #fff; }

/* ══════ ⛑️🔴🔴 НАКЛАДКА СОСТОЯНИЯ ПОВЕРХ ЖИВОГО САЙТА (CLIE-1208) ══════════════════════
   Владелец: «при обычной работе с окном периодически что-то отваливается и приходится
   запускать или настраивать всё заново». Отваливался не проект — отваливался КАДР: любое
   состояние превью рисовалось в тот же узел, где живёт `<iframe>`.
   Теперь состояние — СЛОЙ: сайт под ним продолжает работать (форма заполнена, страница та
   же), а как только машина ответила — слой снимается и работа человека на месте.
   Подложка непрозрачная (сквозь неё сайт читался бы как «двоится»), но живёт ВНУТРИ сцены,
   поэтому шапка, полоса устройства и панель кода остаются на своих местах. */
.dvs-pvstage > .pvw-hold {
  position: absolute; inset: 0; z-index: 3;
  display: flex; flex-direction: column; overflow: auto;
  background: color-mix(in srgb, var(--panel) 94%, transparent);
  -webkit-backdrop-filter: saturate(140%) blur(2px); backdrop-filter: saturate(140%) blur(2px);
  animation: pvw-hold-in 140ms ease-out;
}
.dvs-pvstage > .pvw-hold > * { flex: 1 1 auto; min-height: 0; }
/* 🔴 НАКЛАДКА НЕ ЗАПИРАЕТ САЙТ (правило выходов, найдено ревью CLIE-1208). Она появляется и
   от МИГНУВШЕЙ связи, когда сайт под ней жив и человек в середине работы: отобрать у него
   клики, ввод и прокрутку до следующего удачного тика — это состояние без выхода. Поэтому
   подложка прозрачна для указателя, а ловят его только сами контролы («Повторить», ссылки). */
.dvs-pvstage > .pvw-hold,
.dvs-pvstage > .pvw-hold > * { pointer-events: none }
.dvs-pvstage > .pvw-hold button,
.dvs-pvstage > .pvw-hold a,
.dvs-pvstage > .pvw-hold input,
.dvs-pvstage > .pvw-hold select,
.dvs-pvstage > .pvw-hold textarea { pointer-events: auto }
@keyframes pvw-hold-in { from { opacity: 0 } to { opacity: 1 } }
@media (prefers-reduced-motion: reduce) { .dvs-pvstage > .pvw-hold { animation: none } }

/* ══════ 📱 DEVICE TOOLBAR — ПРЕВЬЮ ГЛАЗАМИ ЧУЖОГО УСТРОЙСТВА (CLIE-1122) ══════════════
   Полоса стоит ПОД шапкой превью и одинакова на всех трёх поверхностях (колонка · окно ·
   вкладка проекта) — разметку даёт `devPvMount`, поэтому новой поверхности писать нечего.
   Размерный класс тот же, что у шапки (`--ctl-*`, CLIE-505): ряд контролов обязан быть
   одной высоты. Не влезло — ПЕРЕНОС (UAFLEX_MECH), ужимается подпись режима, а не поля. */
.dvs-pvdev {
  flex: 0 0 auto; display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  padding: 5px 8px; border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--panel) 82%, var(--bg));
}
.pvd-open {
  display: inline-flex; align-items: center; gap: 7px;
  height: var(--ctl-h); padding: 0 11px; min-width: max-content;
  border: 1px solid var(--line); border-radius: var(--ctl-r);
  background: var(--panel); color: var(--muted); font-size: var(--ctl-fs); cursor: pointer;
  transition: background .14s ease, border-color .14s ease, color .14s ease;
}
.pvd-open:hover { background: var(--hover); color: var(--text); border-color: color-mix(in srgb, var(--accent) 35%, var(--line)); }
.pvd-open .ic { width: 15px; height: 15px; }
/* Поле выбора — канонический `.ccpp-field`, только не во всю ширину формы, а по содержимому. */
.dvs-pvdev .pvd-f { width: auto; flex: 0 1 auto; min-width: 96px; max-width: 200px; gap: 6px; padding: 0 8px; }
.dvs-pvdev .pvd-f .ic:first-child { flex: none; width: 15px; height: 15px; color: var(--muted); }
.dvs-pvdev .pvd-o { flex: 0 0 auto; }
.pvd-size { display: inline-flex; align-items: center; gap: 4px; flex: 0 0 auto; }
.pvd-num {
  width: 58px; height: var(--ctl-h); padding: 0 6px; box-sizing: border-box;
  border: 1px solid var(--line); border-radius: var(--ctl-r);
  background: var(--input-bg); color: var(--text); font-size: var(--ctl-fs); text-align: center;
  font-variant-numeric: tabular-nums; -moz-appearance: textfield;
}
.pvd-num::-webkit-outer-spin-button, .pvd-num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.pvd-num:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.pvd-x { color: var(--muted); font-size: 11.5px; }
/* Подпись активного режима: «iPhone 15 Pro · Safari iOS · 393 × 852 · DPR 3 · Портрет».
   Единственный элемент ряда, которому МОЖНО сжаться (у него есть многоточие) — правило
   подписи СРЕД-33: `min-width: 0` законен ТОЛЬКО рядом с `text-overflow: ellipsis`. */
.pvd-say {
  flex: 1 1 150px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding-left: 2px; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums;
}
.pvd-pop { position: absolute; }
.pvd-more { display: flex; flex-direction: column; gap: 10px; padding: 4px 2px; min-width: 262px; }
/* Подпись СВЕРХУ, сегмент во всю ширину: в ряд подпись и четыре чипа делили бы 262px и
   уступать пришлось бы подписи (СРЕД-33 — она nowrap и сжиматься не имеет права). */
.pvd-row { display: flex; flex-direction: column; align-items: stretch; gap: 5px; }
.pvd-row > span { padding-left: 2px; font-size: 11.5px; color: var(--muted); }
.pvd-row .cc-seg { width: 100%; }
/* Колонки равные; `min-width: 0` тут законен ровно потому, что подпись режется многоточием. */
.pvd-row .cc-seg > button { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pvd-chk { display: grid; grid-template-columns: auto 1fr; gap: 2px 9px; align-items: center; cursor: pointer; }
.pvd-chk input { grid-row: span 2; width: 16px; height: 16px; accent-color: var(--primary); cursor: pointer; }
.pvd-chk span { font-size: 12.5px; color: var(--text); }
.pvd-chk i { font-style: normal; font-size: 11px; line-height: 1.35; color: var(--muted); }
.pvd-note {
  margin-top: 2px; padding: 8px 10px; border-radius: 10px;
  background: color-mix(in srgb, var(--muted) 10%, transparent);
  font-size: 11px; line-height: 1.45; color: var(--muted);
}

/* ── Само устройство ───────────────────────────────────────────────────────────────
   ВЫКЛЮЧЕНО (нет `.on`): три узла ведут себя ровно как один прежний `<iframe>` —
   растягиваются на всю сцену. Это и есть «превью как было», без единого отличия.     */
.pvdev-wrap, .pvdev-box, .pvdev-scr { display: flex; flex: 1 1 auto; min-width: 0; min-height: 0; }
.pvdev-scr { flex-direction: column; }
.pvdev-bar, .pvdev-kb, .pvdev-cut, .pvdev-hi { display: none; }

/* ВКЛЮЧЕНО: сцена становится «столом», на котором лежит устройство. */
.pvdev-wrap.on {
  display: block; overflow: auto; padding: 14px;
  background:
    radial-gradient(circle at 1px 1px, color-mix(in srgb, var(--muted) 26%, transparent) 1px, transparent 0) 0 0 / 16px 16px;
}
.pvdev-wrap.on > .pvdev-box {
  display: block; margin: 0 auto;
  width: calc(var(--pvd-w) * var(--pvd-s)); height: calc(var(--pvd-h) * var(--pvd-s));
}
.pvdev-wrap.on .pvdev-scr {
  position: relative; display: flex; flex: none;
  width: var(--pvd-w); height: var(--pvd-h);
  transform: scale(var(--pvd-s)); transform-origin: top left;
  background: #fff; overflow: hidden;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .35), 0 0 0 1px color-mix(in srgb, var(--line) 90%, transparent);
}
.pvdev-wrap.on.pvd-round .pvdev-scr { border-radius: 22px; }
.pvdev-wrap.on .dvs-frame { flex: none; width: var(--pvd-w); height: var(--pvd-vh); }
/* Панели браузера — не декорация: ровно на их высоту короче область просмотра страницы.
   Поэтому они НАРИСОВАНЫ, а не «учтены где-то в числах». Нулевая высота = панели нет. */
.pvdev-wrap.on .pvdev-bar {
  display: flex; align-items: center; justify-content: center; flex: none;
  padding: 0 12px; overflow: hidden;
  background: #f2f2f7; color: #3c3c43;
}
.pvdev-wrap.on.pvd-topbar .pvdev-top { display: flex; height: var(--pvd-top); border-bottom: 1px solid rgba(0, 0, 0, .08); }
.pvdev-wrap.on.pvd-botbar .pvdev-bot { display: flex; height: var(--pvd-bot); border-top: 1px solid rgba(0, 0, 0, .08); }
.pvdev-wrap.on .pvdev-top, .pvdev-wrap.on .pvdev-bot { display: none; }
.pvdev-url {
  max-width: 82%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  padding: 3px 12px; border-radius: 999px; background: rgba(120, 120, 128, .16);
  font-size: 12px; line-height: 1.4; color: #3c3c43;
}
/* Клавиатура iOS НАКРЫВАЕТ страницу (разметку она не двигает — двигает только
   `visualViewport`); Android вместо этого отнимает высоту у самого кадра. */
.pvdev-wrap.on.pvd-kbon .pvdev-kb {
  display: block; position: absolute; left: 0; right: 0; bottom: var(--pvd-bot); height: var(--pvd-kb);
  background: linear-gradient(#d1d3d9, #c7c9cf); border-top: 1px solid rgba(0, 0, 0, .12);
}
/* Вырез и «домашняя» полоска — чтобы `safe-area-inset-*` было ВИДНО, а не только в CSS. */
.pvdev-wrap.on.pvd-notch .pvdev-cut {
  display: block; position: absolute; top: 9px; left: 50%; transform: translateX(-50%);
  width: 118px; height: 30px; border-radius: 999px; background: var(--cm-0b0d12, #0b0d12); pointer-events: none;
}
.pvdev-wrap.on.pvd-home .pvdev-hi {
  display: block; position: absolute; left: 50%; bottom: 7px; transform: translateX(-50%);
  width: 134px; height: 5px; border-radius: 999px; background: rgba(0, 0, 0, .32); pointer-events: none;
}

/* Шапка превью: тот же размерный класс, что у всей строки тулбара среды (--ctl-*). */
.dvs-pvbar {
  flex: 0 0 auto; display: flex; align-items: center; gap: 6px;
  padding: 4px 6px 4px 8px; min-height: 38px;
  border-bottom: 1px solid var(--line); background: var(--panel);
}
.pvw-grow { flex: 1 1 auto; }
.pvw-url {
  max-width: 44%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; color: var(--muted);
}
.pvw-b, .pvw-insp {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: var(--ctl-h); min-width: var(--ctl-h); padding: 0 8px;
  border: 1px solid transparent; border-radius: var(--ctl-r);
  background: transparent; color: var(--text); font-size: var(--ctl-fs); cursor: pointer;
  transition: background .14s ease, border-color .14s ease, color .14s ease;
}
.pvw-b .ic, .pvw-insp .ic { width: 15px; height: 15px; }
.pvw-b:hover, .pvw-insp:hover { background: var(--hover); }
/* 🔴🔴 СРЕД-32·3 · ГЛАВНОЕ ДЕЙСТВИЕ ПРЕВЬЮ ДЛЯ РАЗРАБОТЧИКА — И ОНО ВЫГЛЯДИТ ГЛАВНЫМ.
   Было: прозрачный фон + серый текст, то есть третьестепенный контрол рядом с адресом,
   при том что у КЛИЕНТА ровно тут стоит заливная «Оставить замечание» (`.cc-b.prim`
   в `priv/showcase/shell.css`). Владелец дважды говорил об этом одними и теми же словами.
   🔴 `min-width: max-content` ОБЯЗАТЕЛЕН (СРЕД-33): общее правило выше ставит явный
   `min-width: var(--ctl-h)`, а явный min-width отменяет автоматический минимум — контрол
   получал право сжаться ниже своей подписи. Замер ДО: окно 230px → коробка 53px против
   106px содержимого, значок за кромкой окна, слово наезжает на ⟳. Ужимается пусть АДРЕС. */
.pvw-insp {
  flex: 0 0 auto; min-width: max-content; padding: 0 12px; font-weight: 600;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border-color: color-mix(in srgb, var(--accent) 26%, transparent);
  color: var(--accent);
}
.pvw-insp:hover { background: color-mix(in srgb, var(--accent) 20%, transparent); }
.pvw-insp.on { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; }
.pvw-insp.on:hover { background: var(--acc-fill); filter: brightness(1.06); }
.pvw-insp.on .ic { color: #fff; }

/* 👋 Подсказка «правый клик по элементу» — пилюля у нижней кромки кадра (СРЕД-32·3).
   Стоит ПОВЕРХ сайта, но экран не отбирает: маленькая, по центру, гаснет сама через 14 с
   и не возвращается после первого же использования инспектора. */
.pv-tip {
  position: absolute; left: 50%; bottom: 14px; z-index: 4;
  display: flex; align-items: center; gap: 8px; max-width: calc(100% - 24px);
  padding: 7px 8px 7px 12px; border-radius: 999px;
  background: color-mix(in srgb, var(--cm-0b0d12, #0b0d12) 88%, transparent); color: #fff;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .3), 0 0 0 1px rgba(255, 255, 255, .1);
  font-size: 12.5px; line-height: 1.3; white-space: nowrap;
  opacity: 0; transform: translate(-50%, 8px);
  transition: opacity .22s ease, transform .22s cubic-bezier(.4, 0, .2, 1);
  pointer-events: auto;
}
.pv-tip.on { opacity: 1; transform: translate(-50%, 0); }
.pv-tip > span { overflow: hidden; text-overflow: ellipsis; }
.pv-tip .ic { flex: 0 0 auto; width: 15px; height: 15px; color: #6ab0ff; }
.pv-tip-x {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%;
  background: rgba(255, 255, 255, .12); color: #fff; cursor: pointer;
  transition: background .14s ease;
}
.pv-tip-x:hover { background: rgba(255, 255, 255, .22); }
.pv-tip-x .ic { width: 12px; height: 12px; color: #fff; }

/* Рама плавающего окна. Размер и место ставит `makeFloatingWindow` инлайном — здесь
   только вид и три состояния: окно · во весь экран · свёрнуто вниз. */
.dvs-pvwin {
  position: fixed; inset: 0; z-index: 64; display: flex; flex-direction: column;
  background: var(--panel);
  box-shadow: 0 24px 70px rgba(0, 0, 0, .28), 0 0 0 1px var(--line);
}
/* 🔴 Скругление режет СОДЕРЖИМОЕ, а не раму: `overflow:hidden` на самой раме обрезал бы и
   хваталки ресайза (они на 3–4px снаружи кромки) — за край окна было не взяться. */
/* 🔴 CLIE-1122·2: внутри окна лежит ТА ЖЕ оболочка `.dvs-pv`, что в колонке и во вкладке
   (вместе с полосой устройства). Своей разметки у окна больше нет — поэтому и скругление,
   и раскладка адресуются через неё, а не через прямых детей рамы. */
.dvs-pvwin > .dvs-pv { border-radius: inherit; min-height: 0; }
.dvs-pvwin > .dvs-pv > .dvs-pvbar { border-radius: inherit; border-bottom-left-radius: 0; border-bottom-right-radius: 0; }
.dvs-pvwin > .dvs-pv > .dvs-pvmain { overflow: hidden; border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; }
.dvs-pvwin.minimized {
  inset: auto; width: 720px; height: 560px; border-radius: 14px;
  transition: box-shadow .16s ease;
}
.dvs-pvwin.placed { left: 0; top: 0; }
.dvs-pvwin.resizing { user-select: none; }
.dvs-pvwin.resizing iframe, .dvs-pvwin.dragging iframe { pointer-events: none; }
/* ⬇️ Свёрнуто ВНИЗ: остаётся только шапка — окно видно, что живо, и одним кликом назад. */
.dvs-pvwin.docked { height: 38px !important; border-radius: 12px 12px 0 0; cursor: pointer; }
/* Прижатое окно — это РОВНО шапка (38px = PV_BAR_H): полоса устройства и кадр в неё не
   влезают, и оставленные видимыми они торчали бы обрезанной линией под шапкой. */
.dvs-pvwin.docked .dvs-pvmain, .dvs-pvwin.docked .dvs-pvdev { display: none; }
.dvs-pvwin.minimized .pvw-bar { cursor: grab; }
.dvs-pvwin.dragging .pvw-bar { cursor: grabbing; }

/* Хваталки растягивания — прозрачные полоски по кромке: экран не отбирают, курсор
   подсказывает сам. Общие для механизма, а не только для превью. */
.fw-rz { position: absolute; z-index: 3; }
.dvs-pvwin:not(.minimized) .fw-rz, .dvs-pvwin.docked .fw-rz { display: none; }
.fw-rz-n { left: 10px; right: 10px; top: -3px; height: 8px; cursor: ns-resize; }
.fw-rz-s { left: 10px; right: 10px; bottom: -3px; height: 8px; cursor: ns-resize; }
.fw-rz-w { top: 10px; bottom: 10px; left: -3px; width: 8px; cursor: ew-resize; }
.fw-rz-e { top: 10px; bottom: 10px; right: -3px; width: 8px; cursor: ew-resize; }
.fw-rz-nw { left: -4px; top: -4px; width: 16px; height: 16px; cursor: nwse-resize; }
.fw-rz-se { right: -4px; bottom: -4px; width: 16px; height: 16px; cursor: nwse-resize; }
.fw-rz-ne { right: -4px; top: -4px; width: 16px; height: 16px; cursor: nesw-resize; }
.fw-rz-sw { left: -4px; bottom: -4px; width: 16px; height: 16px; cursor: nesw-resize; }

/* ── Панель инспектора ────────────────────────────────────────────────────────────── */
.dvs-pvinsp {
  flex: 0 0 auto; display: flex; flex-direction: column; overflow: hidden;
  max-height: 46%; border-top: 1px solid var(--line); background: var(--panel-2);
}
/* 🔴 СРЕД-32·3: прокручивается ТЕЛО панели, а не панель целиком — иначе переключатель
   положения («слева · снизу · справа · во весь кадр · окно») уезжал бы вверх вместе с
   кодом, и его нельзя было бы нажать ровно тогда, когда он нужен: когда кода много. */
.pvi-body { flex: 1 1 auto; min-height: 0; overflow: auto; }
.dvs-pvmain.wide > .dvs-pvinsp {
  max-height: none; width: clamp(300px, 38%, 460px);
  border-top: 0; border-inline-start: 1px solid var(--line);
}
.dvs-pvinsp[hidden] { display: none; }

/* 🧰🔴🔴 СРЕД-32·3 · ГДЕ СТОИТ ПАНЕЛЬ КОДА — РЕШАЕТ ЧЕЛОВЕК (как в DevTools/VS Code).
   Владелец: «снизу части кода — очень неудобно… сделать вариант, чтобы либо сбоку, либо
   слева от превью, как в браузере». Пять положений — одно состояние `cc.dev.pv.dock`. */
.dvs-pvmain.dock-bottom { flex-direction: column; }
.dvs-pvmain.dock-bottom > .dvs-pvinsp {
  max-height: 46%; width: auto; border-top: 1px solid var(--line); border-inline-start: 0;
}
.dvs-pvmain.dock-right { flex-direction: row; }
.dvs-pvmain.dock-left { flex-direction: row-reverse; }
.dvs-pvmain.dock-right > .dvs-pvinsp, .dvs-pvmain.dock-left > .dvs-pvinsp {
  max-height: none; height: auto; width: clamp(280px, 40%, 520px); border-top: 0;
}
.dvs-pvmain.dock-right > .dvs-pvinsp { border-inline-start: 1px solid var(--line); border-inline-end: 0; }
.dvs-pvmain.dock-left > .dvs-pvinsp { border-inline-end: 1px solid var(--line); border-inline-start: 0; }
/* «Растянуть на весь кадр»: панель накрывает превью целиком, кадр остаётся живым под ней
   (сайт не перезагружается — это тот же урок, что переезд колонка↔окно у самого превью). */
.dvs-pvmain.dock-full { position: relative; }
.dvs-pvmain.dock-full > .dvs-pvinsp {
  position: absolute; inset: 0; z-index: 3; max-height: none; width: auto;
  border: 0; box-shadow: 0 -8px 30px rgba(0, 0, 0, .12);
}
/* 🔴 СРЕД-41: панель прячется на месте, ТОЛЬКО когда окно РЕАЛЬНО открыто (`body.pvpop-on`).
   Прежнее безусловное `display:none` вместе с настоящим окном браузера дало бы тупик: попап
   зарезан браузером или закрыт крестиком — и кода нет вообще нигде. Теперь панель остаётся
   на месте, а над ней стоит полоса «Открыть окно». */
body.pvpop-on .dvs-pvmain.dock-win > .dvs-pvinsp { display: none; }

/* 🪟 Полоса «панель открывается отдельным окном» — выход, а не объяснение. */
.pvi-popbar {
  flex: 0 0 auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 12px; border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  font-size: 12.5px; line-height: 1.45; color: var(--text);
}
.pvi-popbar > span { flex: 1 1 200px; min-width: 0; }
.pvi-popbar[hidden] { display: none; }

/* 🗣️ Строка, которой панель говорит сама за себя: тост живёт в главном окне, а панель
   бывает на другом мониторе (СРЕД-41). */
.pvi-say {
  flex: 0 0 auto; padding: 7px 12px; font-size: 12.5px; line-height: 1.45;
  color: var(--text); background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-bottom: 1px solid var(--line);
}
.pvi-say.bad {
  color: var(--danger, #ff453a);
  background: color-mix(in srgb, var(--danger, #ff453a) 12%, transparent);
}
.pvi-say[hidden] { display: none; }

/* 🎯 СРЕД-41 · тумблер «Выбрать элемент» в шапке панели — как указка в DevTools.
   🔴 Он НЕ СЖИМАЕТСЯ НИЖЕ СВОЕЙ ПОДПИСИ (СРЕД-33): у `.pvi-top` тугой ряд, и без
   `min-width: max-content` слово уехало бы под соседа при узкой панели. */
.pvi-arm {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 6px;
  min-width: max-content; height: 26px; padding: 0 10px 0 8px;
  border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel-2); color: var(--text);
  font-size: 12px; font-weight: 600; cursor: pointer;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.pvi-arm .ic { width: 15px; height: 15px; }
.pvi-arm:hover { background: var(--hover); }
.pvi-arm.on {
  background: var(--acc-fill); border-color: var(--acc-fill); color: #fff;
  box-shadow: 0 2px 10px color-mix(in srgb, var(--accent) 38%, transparent);
}
.pvi-arm.on .ic { color: #fff; }

/* Пока указка взята, кадр носит тонкое кольцо цвета акцента: человек видит, ПОЧЕМУ сайт
   сейчас отвечает инспектору, а не ему — и что это состояние временное. */
.dvs-pvstage.pv-arm { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 55%, transparent); }

/* Шапка панели: подпись + переключатель + закрыть. Она же — хваталка своего окна. */
.pvi-top {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  padding: 5px 6px 5px 12px; min-height: 34px;
  border-bottom: 1px solid var(--line); background: var(--panel);
}
.pvi-top-t {
  flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12px; font-weight: 600; letter-spacing: .01em; color: var(--muted);
  text-transform: uppercase;
}
.pvi-dock { flex: 0 0 auto; display: flex; align-items: center; gap: 2px; }
.pvi-dockb {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; border: 1px solid transparent; border-radius: 7px;
  background: transparent; color: var(--muted); cursor: pointer;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
.pvi-dockb .ic { width: 15px; height: 15px; }
.pvi-dockb:hover { background: var(--hover); color: var(--text); }
.pvi-dockb.on {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  border-color: color-mix(in srgb, var(--accent) 30%, transparent); color: var(--accent);
}

/* 🪟 СРЕД-41: «отдельным окном» — это НАСТОЯЩЕЕ окно браузера (`window.open`), поэтому
   внутристраничной рамы `.dvs-pviwin` больше нет: `div` за кромку вкладки не уедет, а
   владелец просил второй монитор. Разметку окна пишет `devPvPopPaint` и подключает ТЕ ЖЕ
   листы стилей, что у главного окна, — правила `.dvs-pvinsp`/`.pvi-*` выше действуют в нём
   как есть; собственную ширину и высоту ему задаёт система. */
.pvi-empty { padding: 22px 18px; text-align: center; color: var(--muted); }
.pvi-empty .ic { width: 22px; height: 22px; opacity: .5; }
.pvi-empty h4 { margin: 8px 0 4px; font-size: 13.5px; font-weight: 600; color: var(--text); }
.pvi-empty p { margin: 0 0 12px; font-size: 12.5px; line-height: 1.5; }
.pvi-head { display: flex; align-items: center; gap: 8px; padding: 8px 8px 8px 12px; border-bottom: 1px solid var(--line); }
.pvi-el { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.pvi-el b { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pvi-tx { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pvi-load { display: flex; align-items: center; gap: 8px; padding: 14px 14px; font-size: 12.5px; color: var(--muted); }
.pvi-src { padding: 8px 12px; font-size: 12px; color: var(--text); background: color-mix(in srgb, var(--accent) 8%, transparent); }
.pvi-src b { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 500; }
.pvi-files { display: flex; flex-direction: column; gap: 8px; padding: 8px; }
.pvi-file { border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: var(--panel); }
/* Самый правдоподобный файл выделяем КОЛЬЦОМ и подложкой, а не полоской слева. */
.pvi-file.top { background: color-mix(in srgb, var(--accent) 7%, var(--panel)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent); }
.pvi-fhead { display: flex; align-items: center; gap: 8px; padding: 7px 8px 7px 10px; }
.pvi-fname {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 7px;
  border: 0; background: transparent; padding: 0; cursor: pointer; color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; text-align: left;
}
.pvi-fname span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pvi-fname:hover span { text-decoration: underline; }
.pvi-kind { flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%; background: var(--muted); }
.pvi-kind.k-html { background: #ff9f0a; }
.pvi-kind.k-css { background: #0a84ff; }
.pvi-kind.k-code { background: #30d158; }
.pvi-why { flex: 0 0 auto; font-size: 11px; color: var(--muted); }
.pvi-line {
  display: flex; align-items: baseline; gap: 8px; width: 100%; padding: 3px 10px 3px 10px;
  border: 0; background: transparent; cursor: pointer; text-align: left;
  transition: background .12s ease;
}
.pvi-line:hover { background: var(--hover); }
.pvi-line em { flex: 0 0 auto; min-width: 30px; font-style: normal; font-size: 11px; color: var(--muted); text-align: right; }
.pvi-line code { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; color: var(--text); }
/* 🎯 СТРОКА, КОТОРАЯ И ЕСТЬ НАЖАТЫЙ ЭЛЕМЕНТ (СРЕД-36). Акцент — мягкая подложка и
   хэйрлайн-кольцо, а уровень назван СЛОВОМ на пилюле: левых полосок-реек не заводим
   (CLIE-483), и в ч/б это тоже читается. */
.pvi-line.self {
  background: color-mix(in srgb, var(--accent) 11%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 24%, transparent);
  border-radius: 8px;
}
.pvi-line.self:hover { background: color-mix(in srgb, var(--accent) 16%, transparent); }
.pvi-line.self em { color: var(--accent); font-weight: 600; }
.pvi-this {
  flex: 0 0 auto; font-size: 10px; font-weight: 600; letter-spacing: .02em; line-height: 1;
  padding: 3px 6px; border-radius: 999px; white-space: nowrap;
  color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent);
}
.pvi-snip {
  margin: 4px 8px 8px; padding: 8px 10px; border-radius: 8px; overflow: auto;
  background: var(--panel-2); border: 1px solid var(--line);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; line-height: 1.5;
  color: var(--text); white-space: pre; max-height: 150px;
}
.pvi-acts { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px 14px; }
.pvi-acts .v2prev-primary, .pvi-acts .pvi-wide { width: 100%; justify-content: center; }
.pvi-acts .pvi-wide { height: var(--ctl-h); border: 1px solid var(--line); }

/* ── СРЕД-32·2: превью во ВКЛАДКЕ проекта — тот же компонент ──────────────────────────
   `.v2prev-stage` уже `position:relative`, поэтому общий `.dvs-pv` просто ложится в неё
   целиком. Своего размерного класса вкладке не заводим: разметка и все состояния —
   ОДНИ (`devPvMount`), меняется только набор кнопок шапки. */
.v2prev-stage > .dvs-pv { position: absolute; inset: 0; }

/* 👆 Живая строка «под курсором»: что за элемент прямо сейчас под мышью. Стоит НАД
   разобранным элементом и не двигает его — она про «сейчас», а не про «выбрано». */
.pvi-hov {
  /* Липкая: человек водит мышью, а панель в этот момент прокручена к найденному коду —
     живая строка обязана оставаться на глазах, иначе «наведение ничего не показывает». */
  position: sticky; top: 0; z-index: 2;
  display: flex; align-items: baseline; gap: 8px; padding: 6px 12px;
  border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--accent) 8%, var(--panel-2));
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px;
  overflow: hidden; white-space: nowrap;
}
.pvi-hov[hidden] { display: none; }
.pvi-hov-l { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--accent); font-weight: 600; }
.pvi-hov-m { flex: 0 0 auto; color: var(--muted); }

/* 🧭 Хлебные крошки: путь к элементу. Мышь попадает в самый глубокий узел, а править надо
   блок вокруг него — клик по крошке поднимает выбор на уровень. */
.pvi-crumbs {
  display: flex; align-items: center; flex-wrap: wrap; gap: 2px; padding: 6px 12px 7px;
  border-bottom: 1px solid var(--line); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px;
}
.pvi-crumbs i { font-style: normal; color: var(--text-dim); opacity: .6; }
.pvi-crumb {
  border: 0; background: transparent; padding: 1px 5px; border-radius: 6px; cursor: pointer;
  color: var(--muted); font: inherit; max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.pvi-crumb:hover { background: var(--hover); color: var(--text); }
.pvi-crumb.cur { color: var(--text); font-weight: 600; cursor: default; }

/* Разделы «Разметка · Стили · Скрипт»: у элемента всегда несколько файлов, и они РАЗНЫЕ
   по смыслу. Роль считает сервер (DevLocate.role_of/1) — тут только подпись. */
.pvi-sec { display: flex; flex-direction: column; }
.pvi-sec > h5 {
  display: flex; align-items: center; gap: 7px; margin: 0; padding: 11px 12px 3px;
  font-size: 11px; font-weight: 700; letter-spacing: .055em; text-transform: uppercase; color: var(--text-dim);
}
.pvi-sec > h5 em {
  font-style: normal; font-size: 10.5px; font-weight: 600; letter-spacing: 0;
  padding: 0 5px; border-radius: 999px; background: var(--panel); color: var(--muted);
}
.pvi-rule { padding: 2px 10px 3px; }
.pvi-rule code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; color: var(--text); }
.pvi-fname.as-text { cursor: default; color: var(--muted); }

/* ══════════ 🧱 БЛОК КОДА ЭЛЕМЕНТА — И ЕГО ПРАВКА (СРЕД-36·2) ══════════
   Владелец: «Там должен быть в файле index БЛОК где эта кнопка и ВОЗМОЖНОСТЬ ПРАВИТЬ КОД».
   Раньше кусок кода лежал В САМОМ НИЗУ карточки файла и был только для чтения. Теперь это
   первый блок панели, он развёрнут, и в нём правят.
   🔴 Ширину не прибиваем НИГДЕ (CRMC-406): панель тянется мышью, код тянется вместе с ней.
   Строка кода НЕ переносится (`pre`) — перенос сбил бы нумерацию слева. */
.pvc { border-bottom: 1px solid var(--line); }
.pvc > h5 { padding-bottom: 6px; }
.pvc > h5 em { max-width: 55%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pvc-open {
  margin-inline-start: auto; display: inline-flex; align-items: center; gap: 5px;
  border: 0; background: transparent; cursor: pointer; padding: 2px 6px; border-radius: 7px;
  color: var(--muted); font-size: 10.5px; font-weight: 600; letter-spacing: 0; text-transform: none;
  /* Подпись не сжимается ниже себя самой (СРЕД-33): «строки 56–63» режется в кашу. */
  min-width: max-content; transition: background .12s ease, color .12s ease;
}
.pvc-open:hover { background: var(--hover); color: var(--accent); }
.pvc-open .ic { width: 13px; height: 13px; }

.pvc-box {
  margin: 0 8px 8px; border-radius: 10px; overflow: hidden;
  background: var(--panel-2); border: 1px solid var(--line);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; line-height: 1.55;
}
.pvc.dirty .pvc-box { border-color: color-mix(in srgb, var(--accent) 55%, transparent); }
/* Контекст — только для глаз: он говорит, ГДЕ человек правит. Приглушён, не правится. */
.pvc-ctx { padding: 5px 0; color: var(--text-dim); background: color-mix(in srgb, var(--text) 3%, transparent); }
.pvc-r { display: flex; gap: 8px; padding: 0 10px; white-space: pre; }
.pvc-r > i {
  flex: 0 0 auto; min-width: 2.2em; text-align: end; font-style: normal;
  color: var(--text-dim); opacity: .7; font-variant-numeric: tabular-nums; user-select: none;
}
.pvc-r > code { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

.pvc-main { display: flex; gap: 8px; padding: 6px 10px; align-items: stretch; }
.pvc-nums {
  flex: 0 0 auto; min-width: 2.2em; display: flex; flex-direction: column; text-align: end;
  color: var(--accent); opacity: .75; font-variant-numeric: tabular-nums; user-select: none;
}
.pvc-nums i { font-style: normal; line-height: 1.55; }
/* Само поле правки. Высоту растим числом строк из кода (`rows`), поэтому мёртвого скролла
   внутри не бывает: панель и так прокручивается телом (`.pvi-body`). */
.pvc-code {
  flex: 1 1 auto; min-width: 0; resize: none; border: 0; outline: none; padding: 0;
  background: transparent; color: var(--text);
  font: inherit; line-height: 1.55; white-space: pre; overflow-x: auto; overflow-y: hidden;
  caret-color: var(--accent); tab-size: 2;
}
.pvc-code:focus { outline: none; }
/* 🔴 ПОЛЕ КОДА НЕ СПЛЮЩИВАЕТСЯ (13.09, скрин владельца «код нельзя править»): длинная строка
   в поле из одной строки получала горизонтальную полосу прокрутки, и та съедала ВСЮ высоту —
   строка 302 превращалась в полоску в пару пикселей, по которой не попасть. Высоту подгоняет
   `devPvCodeFit` (текст + полоса); здесь — пол, если скрипт ещё не успел, и явный вид поля. */
.pvc-code {
  min-height: calc(1.55em + 14px); cursor: text; border-radius: 6px; padding: 0 6px;
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent);
}
.pvc-code:focus { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--accent) 60%, transparent); }
.pvc-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 0 8px 12px; }
.pvc-acts .v2prev-primary, .pvc-acts .pvw-b { min-width: max-content; }
.pvc-acts .pvw-b { height: var(--ctl-h); padding: 0 12px; border: 1px solid var(--line); }
.pvc-ok { font-size: 11.5px; color: #30d158; }
.pvc-hint { padding: 0 12px 10px; font-size: 11px; color: var(--muted); }
/* «Не прочиталось» — ЗАКОННЫЙ ответ и виден так же, как код: молчание тут и было багом. */
.pvc-fail {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 8px 10px; padding: 10px 12px;
  border-radius: 10px; font-size: 11.5px; color: var(--text);
  background: color-mix(in srgb, #ff9f0a 12%, var(--panel-2));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #ff9f0a 30%, transparent);
}
.pvc-fail .pvw-b { min-width: max-content; height: var(--ctl-h); padding: 0 10px; border: 1px solid var(--line); }

/* ══════════ ✏️ РЕДАКТОР СТИЛЯ В ИНСПЕКТОРЕ (СРЕД-35) ══════════
   Владелец: «тут вроде как с этим работать нельзя, бесполезная вещь». Блок «Правила,
   которые легли» показывал ОДИН селектор — теперь это редактор: объявления правила
   строками, значение правится кликом по нему, цвет — свотчем, число — протяжкой.
   Плотность как у системного инспектора: моноширинный кегль 11.5, шаг строки 4/8-grid. */
.pvi-rule.ed { padding: 2px 8px 4px; }
.pvi-rsel { display: flex; align-items: center; gap: 6px; padding: 3px 2px 2px; }
.pvi-rsel code { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--accent); }
.pvi-rsel em {
  flex: 0 0 auto; font-style: normal; font-size: 10px; font-weight: 600; letter-spacing: .03em;
  padding: 1px 5px; border-radius: 999px; color: var(--muted);
  background: color-mix(in srgb, var(--text) 7%, transparent);
}
.pvi-decls { display: flex; flex-direction: column; gap: 1px; }
.pvi-decl {
  display: flex; align-items: center; gap: 6px; min-height: 22px; padding: 1px 4px 1px 2px;
  border-radius: 6px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px;
  transition: background 130ms cubic-bezier(.4, 0, .2, 1);
}
.pvi-decl:hover { background: var(--hover); }
/* Правка видна ТОЧКОЙ у края строки, а не заливкой: заливка на всю строку — тот самый
   «дефолтный грубый» приём, который запрещён правилом дизайна (CLIE-483). */
.pvi-decl.dirty::before,
.pvi-decl.saved::before {
  content: ""; flex: 0 0 auto; width: 5px; height: 5px; margin-inline-start: 1px;
  border-radius: 50%; background: var(--accent);
}
.pvi-decl.saved::before { background: #30d158; }
.pvi-decl.dirty:not(:has(.pvi-sw))::before, .pvi-decl.saved:not(:has(.pvi-sw))::before { margin-inline-end: 4px; }
.pvi-p { flex: 0 0 auto; color: var(--muted); }
.pvi-p::after { content: ":"; opacity: .55; }
.pvi-v {
  flex: 1 1 auto; min-width: 32px; padding: 1px 5px; border-radius: 5px; color: var(--text);
  outline: none; cursor: text; white-space: pre-wrap; word-break: break-word;
  box-shadow: inset 0 0 0 1px transparent; transition: box-shadow 130ms cubic-bezier(.4, 0, .2, 1);
}
.pvi-v:hover { box-shadow: inset 0 0 0 1px var(--line); }
.pvi-v:focus { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 60%, transparent); background: var(--panel); }
/* Число тянется мышью — курсор обязан это обещать ДО нажатия (жест без подсказки = мёртвый). */
.pvi-v[data-kind="num"] { cursor: ew-resize; }
.pvi-v[data-kind="num"]:focus { cursor: text; }
.pvi-v.scrub { box-shadow: inset 0 0 0 1px var(--accent); }
body.pvi-scrubbing, body.pvi-scrubbing * { cursor: ew-resize !important; user-select: none; }
.pvi-sw {
  flex: 0 0 auto; width: 14px; height: 14px; padding: 0; border: 0; border-radius: 4px; cursor: pointer;
  background: repeating-conic-gradient(var(--line) 0 25%, transparent 0 50%) 0 0 / 8px 8px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 22%, transparent);
}
.pvi-sw i { display: block; width: 100%; height: 100%; border-radius: 4px; }
.pvi-sw:hover { box-shadow: inset 0 0 0 1px var(--accent), 0 0 0 3px color-mix(in srgb, var(--accent) 16%, transparent); }
.pvi-imp { flex: 0 0 auto; font-style: normal; font-weight: 700; color: #ff9f0a; }
.pvi-undo {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; padding: 0; border: 0; border-radius: 6px; background: transparent;
  color: var(--muted); cursor: pointer; opacity: 0; transition: opacity 130ms, background 130ms;
}
.pvi-decl:hover .pvi-undo, .pvi-undo:focus-visible, .pve-row .pvi-undo { opacity: 1; }
.pvi-undo:hover { background: var(--hover); color: var(--text); }
.pvi-undo .ic { width: 13px; height: 13px; }
.pvi-add {
  display: inline-flex; align-items: center; gap: 4px; align-self: flex-start; margin-top: 2px;
  height: 22px; padding: 0 8px 0 5px; border: 1px dashed var(--line); border-radius: 6px;
  background: transparent; color: var(--muted); font-size: 11.5px; cursor: pointer;
  transition: color 130ms, border-color 130ms, background 130ms;
}
.pvi-add:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: color-mix(in srgb, var(--accent) 7%, transparent); }
.pvi-add .ic { width: 12px; height: 12px; }
.pvi-nofix { padding: 3px 4px 2px; font-size: 11px; line-height: 1.45; color: var(--text-dim); }
.pvi-addpop { display: flex; flex-direction: column; gap: 8px; padding: 2px; }
.pvi-addpop label { display: flex; flex-direction: column; gap: 4px; font-size: 11px; color: var(--muted); }
.pvi-in {
  height: var(--ctl-h); padding: 0 9px; border: 1px solid var(--line); border-radius: var(--ctl-r);
  background: var(--panel); color: var(--text); font-size: var(--ctl-fs); font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.pvi-in:focus { outline: none; border-color: color-mix(in srgb, var(--accent) 60%, transparent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent); }

/* 💾 Полоса черновика: показ состояния + два выхода (правило выходов, СРЕД-31·2). Липкая —
   человек ушёл щёлкать следующий элемент, а несохранённая работа обязана остаться на виду. */
.pve-bar {
  position: sticky; top: 0; z-index: 3; display: flex; flex-direction: column; gap: 8px;
  padding: 8px 10px 10px; border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--accent) 9%, var(--card));
  backdrop-filter: saturate(180%) blur(12px);
}
.pve-bar.ok { background: color-mix(in srgb, #30d158 9%, var(--card)); }
.pve-sum {
  display: flex; align-items: center; gap: 7px; padding: 0; border: 0; background: transparent;
  color: var(--text); font-size: 12.5px; cursor: pointer; text-align: start;
}
.pve-sum b { font-weight: 650; }
.pve-sum span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: 11.5px; }
.pve-sum .ic { width: 13px; height: 13px; color: var(--muted); }
.pve-dot { flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); }
.pve-bar.ok .pve-dot { background: #30d158; }
.pve-acts { display: flex; align-items: center; gap: 8px; }
.pve-acts .v2prev-primary { flex: 1 1 auto; justify-content: center; }
.pve-undo-all { flex: 0 0 auto; height: var(--ctl-h); padding: 0 10px; border: 1px solid var(--line); gap: 5px; }
.pve-undo-all .ic { width: 14px; height: 14px; }
.pve-note { font-size: 11.5px; line-height: 1.45; color: var(--muted); }
.pve-note.bad { color: #ff453a; }
.pve-list { display: flex; flex-direction: column; gap: 2px; }
.pve-row { display: flex; align-items: center; gap: 8px; min-height: 24px; font-size: 11.5px; }
.pve-k { flex: 0 1 auto; min-width: 0; display: flex; align-items: baseline; gap: 5px; overflow: hidden; }
.pve-k b { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 600; color: var(--text); }
.pve-k i { font-style: normal; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pve-v { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--accent); text-align: end; }
.pve-row.saved .pve-v { color: #30d158; }

/* 🎨 Палитра с пипеткой — ОДНА на продукт (`ccColorPop`). */
.cc-pop {
  position: fixed; z-index: 2200; max-height: 70vh; overflow: auto;
  padding: 10px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--card); box-shadow: var(--shadow-2);
}
.cc-clr { display: flex; flex-direction: column; gap: 10px; }
.cc-clr-top { display: flex; align-items: center; gap: 6px; }
.cc-clr-now {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 8px; overflow: hidden;
  background: repeating-conic-gradient(var(--line) 0 25%, transparent 0 50%) 0 0 / 10px 10px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 20%, transparent);
}
.cc-clr-now i { display: block; width: 100%; height: 100%; }
.cc-clr-hex {
  flex: 1 1 auto; min-width: 0; height: 26px; padding: 0 8px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--panel); color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px;
}
.cc-clr-hex:focus { outline: none; border-color: color-mix(in srgb, var(--accent) 60%, transparent); }
.cc-clr-native, .cc-clr-eye {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel); color: var(--muted); cursor: pointer; overflow: hidden;
  transition: color 130ms, border-color 130ms;
}
.cc-clr-native:hover, .cc-clr-eye:hover { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.cc-clr-native input { width: 46px; height: 46px; margin: -10px; border: 0; padding: 0; background: transparent; cursor: pointer; }
.cc-clr-eye .ic { width: 15px; height: 15px; }
.cc-clr-sw { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
.cc-clr-s {
  height: 24px; padding: 0; border: 0; border-radius: 7px; cursor: pointer;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 16%, transparent);
  transition: transform 130ms cubic-bezier(.4, 0, .2, 1), box-shadow 130ms;
}
.cc-clr-s:hover { transform: scale(1.08); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 30%, transparent), 0 2px 8px rgba(0, 0, 0, .18); }
.cc-clr-a { display: flex; align-items: center; gap: 8px; font-size: 11px; color: var(--muted); }
.cc-clr-a input { flex: 1 1 auto; min-width: 0; accent-color: var(--accent); }
.cc-clr-a em { flex: 0 0 auto; min-width: 32px; font-style: normal; text-align: end; font-variant-numeric: tabular-nums; }

@media (max-width: 720px) {
  /* На телефоне окон нет — превью занимает экран целиком, а тянуть нечего. */
  .dvs-pvwin.minimized { inset: 0 !important; width: auto !important; height: auto !important; border-radius: 0; }
  .dvs-pvwin .fw-rz { display: none; }
  .dvs-pvmain.wide { flex-direction: column; }
  .dvs-pvmain.wide > .dvs-pvinsp { width: auto; max-height: 46%; border-inline-start: 0; border-top: 1px solid var(--line); }
}

/* ══ СРЕД-25: работать не с чем — ОДНО состояние на всю среду ════════════════════════
   Пустое дерево файлов + «Выберите файл слева» + тулбар из недействующих кнопок читаются
   как «совсем ничего не работает». Пока компьютер не подключён — ИЛИ пока не сказано, где
   на нём лежит код, — среда показывает ровно одну карточку, как вкладка «Превью».
   🔴 Класс ОДИН на оба состояния (`devSoloLayout` в app.js): «нет машины» и «нет папки» —
   один и тот же экран, и второй набор правил тут был бы дублем (правило «одна реализация»).
   Имя нейтральное (`-solo`, не `-noagent`) ровно поэтому. */
.dvs-body.dvs-solo > .dvs-side,
.dvs-body.dvs-solo > .dvs-edit { display: none; }
.dvs-body.dvs-solo > .dvs-prev { flex: 1 1 auto; border-left: 0; }
.dvs-body.dvs-solo .v2prev-empty { width: 100%; }

/* 🔴🔴 СРЕД-37 · ЛИЦО БЕЗ ДОСТУПА К ИСХОДНИКАМ (владелец 03.09.2026: «не должен видеть гит,
   и файлы, а только видеть превью и давать задачи в ИИ»). Колонка файлов и редактор уходят
   ТЕМ ЖЕ способом, что и в `dvs-solo` — второй механики скрытия колонок в среде не заводим.
   Класс отдельный, а не переиспользованный `dvs-solo`, ровно потому, что причины разные:
   `solo` — «машины нет прямо сейчас» (пройдёт), `face` — «вам это не открыто» (решение
   человека), и раскладка по состоянию не имеет права его отменить. */
.dvs-body.dvs-face > .dvs-side,
.dvs-body.dvs-face > .dvs-edit { display: none; }
.dvs-body.dvs-face > .dvs-prev { flex: 1 1 auto; border-left: 0; min-width: 0; }
.dvs-body.dvs-face .v2prev-empty { width: 100%; }

/* ══ 📱 СРЕДА НА ТЕЛЕФОНЕ (12.10.2026, проход по проду: дерево · код · панель рядом в 316px) ══════
   Колонка ОДНА за раз — по `data-ph` на .dvs-body (devPhPane), та же механика, что dvs-solo/-face.
   Выбор — канон-сегмент .dvs-phseg (на компьютере его нет). В solo/face показывается только
   панель (выбирать нечего), без панели (nopreview) — нет и третьего пункта.
   Шапка — ОДНА строка, прокручивается пальцем; крестик прибит к правому краю с подложкой, имя
   машины уходит (статус «● На связи» остаётся словом), цели — 44px под палец.
   🔴 18.10.2026 · Колонки по одной — до 959px, а не до 720. Три колонки требуют 248 + 320 + 260 =
   828px тела; на планшете и узком окне ПК (768: тело 656) панель ИИ сжималась в 88px. Порог тот
   же, что у `devPhCols()` и `vp: 960` у колонок среды в WIN_PANES. Шапка на 721–959 остаётся
   компьютерной («⋯» + прокрутка колесом) — пальцевая прокрутка и цели 44px только ≤720. */
.dvs .dvs-phseg { display: none; }
@media (max-width: 959px) {
  .dvs .dvs-phseg { display: flex; flex: 0 0 auto; margin: 8px 8px 0; }
  .dvs .dvs-phseg > button { flex: 1 1 0; }
  .dvs-body > :is(.dvs-side, .dvs-edit, .dvs-prev) { flex: 1 1 auto; min-width: 0; border-left: 0; border-right: 0; }
  .dvs-body:not([data-ph="side"]) > .dvs-side,
  .dvs-body:not([data-ph="edit"]) > .dvs-edit,
  .dvs-body:not([data-ph="prev"]) > .dvs-prev { display: none; }
  .dvs-body:is(.dvs-solo, .dvs-face):not(.nopreview) > .dvs-prev { display: flex; }
  .dvs .dvs-phseg:has(+ .dvs-body:is(.dvs-solo, .dvs-face)) { display: none; }
  .dvs .dvs-phseg:has(+ .dvs-body.nopreview) > [data-dvph="prev"] { display: none; }
}
@media (max-width: 720px) {
  .dvs .dvs-phseg { min-height: 44px; }
  .dvs .dvs-phseg > button { line-height: 36px; }

  .dvs-bar { overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
  .dvs-bar::-webkit-scrollbar { display: none; }
  .dvs-bar #dvsMach { display: none; }
  .dvs-bar .v2prev-btn,
  .dvs-bar .dvs-proj,
  .dvs-bar .dvs-branch,
  .dvs-bar .dvs-tasklink,
  .dvs-bar .dvs-cloud,
  .dvs-bar .dvs-who,
  .dvs-bar .dvs-state { height: 44px; min-height: 44px; flex-shrink: 0; }
  .dvs-bar > [data-dv="close"] {
    position: sticky; right: 0; z-index: 1; min-width: 44px; justify-content: center;
    background: var(--bg); box-shadow: -14px 0 12px -2px var(--bg);
  }
  /* devspace-header-overflow · «×» прилипает к краю прокрутки, а не к краю полосы: в правом поле 12 px за ним
     подглядывали уехавшие кнопки («бл» от «Облако», x372–383 на кадре 390). Поле прячет маска; нижний волосок
     полосы (1 px) маска оставляет целиком. Полоса по-прежнему листается вбок (СРЕД-26/2), ничего не убрано. */
  .dvs-bar {
    -webkit-mask-image: linear-gradient(#000, #000), linear-gradient(to left, transparent 12px, #000 12px);
    mask-image: linear-gradient(#000, #000), linear-gradient(to left, transparent 12px, #000 12px);
    -webkit-mask-size: 100% 1px, 100% 100%; mask-size: 100% 1px, 100% 100%;
    -webkit-mask-position: left bottom, 0 0; mask-position: left bottom, 0 0;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  }
}

/* 🔴 СРЕД-38: своей вёрстки у списка проектов среды БОЛЬШЕ НЕТ. Тут жили `.dvs-pop-set` и
   `.dvs-pop-path` — рукописная строка «имя + путь», нарисованная мимо канона списка
   сущностей (CLIE-590), и вместе с ней у списка не было ни поиска, ни сортировки, ни
   счётчика. Теперь пикер строит `ccppHtml`/`ccppMount`, а папка едет каноническим
   подзаголовком строки (`.bmp-sub`) — правится в ОДНОМ месте и одинаково выглядит везде.
   Вернуть сюда свою строку = вернуть список без поиска; это ловит `DEVPICK_MECH`. */

/* ══ СРЕД-25: «Что запускать» — форма, которую можно заполнить БЕЗ живой машины ══════
   Поле и его кнопка «Обзор…» — на РАЗНЫХ строках (правило продукта «поле + кнопка»):
   мелкое поле рядом с кнопкой схлопывается, а кнопка раздувается. Поле на всю ширину,
   действие — строкой ниже, естественной ширины, слева. */
.dvs-setup { max-width: 100%; }
.dvs-setup .dvs-setup-note { margin: 0 0 4px; font-size: 13px; line-height: 1.5; color: var(--muted); text-align: left; }
.dvs-setup .v2prev-f { display: flex; flex-direction: column; align-items: stretch; gap: 6px; }
.dvs-setup .v2prev-f > span { margin-bottom: 0; }
.dvs-setup .v2prev-f input { width: 100%; box-sizing: border-box; }
.dvs-setup .dvs-setup-acts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 2px; }
.dvs-setup .v2prev-cta { text-align: left; margin-top: 18px; }

/* ══ СРЕД-11 (0210): «чтение не разрешено» — объяснение + ОДНА кнопка ═════════════
   Кнопка восстановления не имеет права выглядеть как строка текста: `.ghost` по
   умолчанию без рамки и фона, и на пустой панели её просто не видно. Здесь она —
   аккуратный контрол (хэйрлайн, 8-grid, мягкий hover), как системные кнопки macOS. */
/* 🔴 Класс СВОЙ, а не `.ghost`: на светлой теме `html[data-theme="light"] .ghost`
   (специфичность выше) гасит рамку и фон — кнопка превращалась в строку текста ровно
   там, где она единственный выход. Увидел на снимке прода: в тёмной кнопка была, в
   светлой её не было. Правило: восстановительный CTA не наследует «призрачный» стиль. */
.dvs-accbtn {
  /* 🔴 Фон — `--panel-2` (как у базовой кнопки), а НЕ `--panel`: на светлой теме карточка
     отказа лежит на `--panel`, и кнопка того же цвета читалась как обычный текст (увидел
     на снимке прода — по коду этого не видно). Рамка чуть контрастнее хэйрлайна. */
  border: 1px solid color-mix(in srgb, var(--fg) 14%, var(--line));
  background: var(--panel-2); color: var(--fg);
  padding: 6px 12px; border-radius: 8px; font-size: 12.5px; font-weight: 500;
  transition: background .14s ease, border-color .14s ease, transform .14s ease;
}
.dvs-accbtn:hover {
  background: var(--hover); border-color: color-mix(in srgb, var(--fg) 22%, var(--line));
}
.dvs-accbtn:active { transform: translateY(.5px); }
/* Подвал палитры поиска и список папок — узкие места: там отказ рисуем строкой, а не
   карточкой в 20px отступов (иначе он съедает выдачу). */
#dvsPalFoot .dvs-hint, #v2fbList .dvs-hint {
  padding: 4px 0; text-align: left; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
#v2fbList .dvs-hint { padding: 14px 16px; }
/* Терминал: объяснение и кнопка ВМЕСТЕ, сразу под текстом, а не у нижнего края панели
   (кнопка в 300px от причины читается как чужой элемент). */
.dvterm.is-denied .dvterm-out { flex: 0 0 auto; min-height: 0; padding-bottom: 2px; }
.dvterm.is-denied .dvs-hint { padding: 4px 12px 12px; text-align: left; }

/* ══ Э3: доступ ИИ к машине + журнал действий ════════════════════════════════════
   Одна панель на оба экрана среды (вкладка «Превью» и полноэкранное пространство).
   Рама — та же геометрия, что у обзора папок (.v2fb): одно семейство окон среды.
   Цвета только токенами → тёмная тема наследуется без второго набора правил. */
.v2ai-overlay {
  position: fixed; inset: 0; z-index: 9000; display: grid; place-items: center;
  background: rgba(0, 0, 0, .28); backdrop-filter: blur(2px);
  animation: v2fbIn 140ms ease;
}
.v2ai {
  width: min(620px, 94vw); max-height: 78vh; display: flex; flex-direction: column;
  background: var(--bg, #fff); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 12px 48px rgba(0, 0, 0, .18); overflow: hidden;
}
.v2ai-head {
  display: flex; align-items: center; gap: 10px; padding: 12px 14px; flex: 0 0 auto;
  border-bottom: 1px solid var(--line);
}
.v2ai-head h3 { margin: 0; flex: 1 1 auto; font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.v2ai-sw {
  display: flex; align-items: flex-start; gap: 16px; padding: 14px;
  border-bottom: 1px solid var(--line);
}
.v2ai-sw-t { flex: 1 1 auto; min-width: 0; display: block; }
.v2ai-sw-t b { display: block; font-size: 14px; font-weight: 550; }
.v2ai-sw-t small { display: block; margin-top: 4px; font-size: 12px; line-height: 1.45; color: var(--muted); }
.v2ai-sw .cc-switch { flex: 0 0 auto; margin-top: 2px; }
.v2ai-jh {
  display: flex; align-items: baseline; gap: 8px; padding: 12px 14px 6px;
  font-size: 13px; font-weight: 600;
}
.v2ai-jh span { font-weight: 400; font-size: 12px; color: var(--muted); }
.v2ai-list { flex: 1 1 auto; overflow: auto; padding: 0 8px 10px; }
.v2ai-j {
  display: flex; align-items: flex-start; gap: 10px; padding: 8px 6px;
  border-radius: 10px; transition: background 120ms ease;
}
.v2ai-j:hover { background: var(--hover); }
.v2ai-j + .v2ai-j { box-shadow: 0 -1px 0 var(--line); }
.v2ai-j-ico {
  flex: 0 0 auto; width: 22px; height: 22px; margin-top: 1px; border-radius: 7px;
  display: grid; place-items: center; font-style: normal; font-size: 9px; font-weight: 700;
  letter-spacing: .02em; color: var(--muted); background: var(--panel-2, var(--hover));
  border: 1px solid var(--line);
}
.v2ai-j-ico.ai { color: #fff; background: var(--acc-fill, var(--cm-6c5ce7, #6c5ce7)); border-color: transparent; }
.v2ai-j-b { flex: 1 1 auto; min-width: 0; display: block; }
.v2ai-j-l { display: block; font-size: 13px; line-height: 1.45; }
.v2ai-j-l b { font-weight: 550; }
.v2ai-j-l code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  padding: 1px 5px; border-radius: 6px; background: var(--panel-2, var(--hover));
  word-break: break-all;
}
.v2ai-j-s { color: var(--muted); font-size: 12px; }
.v2ai-j-d { display: block; margin-top: 2px; font-size: 12px; line-height: 1.4; color: var(--muted); }
.v2ai-j.bad .v2ai-j-d { color: var(--danger, #e5484d); }
.v2ai-j-w { flex: 0 0 auto; font-size: 11px; color: var(--muted); white-space: nowrap; margin-top: 2px; }
/* СРЕД-11 «Доступ и журнал»: классы прав + отзыв. Тот же визуальный язык, что у тумблера
   доступа ИИ, — панель одна, второй в продукте нет. */
/* ОДНА полоса прокрутки на окно: вложенный скролл прятал нижние тумблеры и кнопки
   отзыва — человек их просто не видел (мёртвые контролы). */
.v2ai-body { flex: 1 1 auto; overflow: auto; min-height: 0; }
.v2ai-body .v2ai-list { flex: none; overflow: visible; }
.v2ai-gh {
  display: flex; align-items: baseline; gap: 8px; padding: 12px 14px 4px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase;
  color: var(--text-dim);
}
.v2ai-sw.compact { padding: 11px 14px; align-items: center; }
.v2ai-sw.compact .v2ai-sw-t b { font-size: 13.5px; }
.v2ai-sw.compact .cc-switch { margin-top: 0; }
.v2ai-sw.off .cc-switch { opacity: .45; cursor: default; }
/* 🌍 i18n: текст бейджа приходит из РАЗМЕТКИ (data-badge), а не прибит в content —
   из CSS перевести строку нельзя, и на английском тут навсегда осталось бы русское слово. */
.v2ai-sw.risk .v2ai-sw-t b[data-badge]::after {
  content: attr(data-badge); margin-left: 8px; padding: 1px 6px; border-radius: 999px;
  font-size: 10.5px; font-weight: 600; letter-spacing: .2px; text-transform: none;
  color: var(--warning, #e6a03c); background: var(--warning-soft, rgba(230, 160, 60, .16));
}
/* 🔴 СРЕД-11 · «НЕ ЗНАЮ» ≠ «ВЫКЛЮЧЕНО». Пока ответа сервера нет (панель только открыли или
   запрос упал), тумблер не имеет права изображать состояние: ползунок встаёт ПОСЕРЕДИНЕ,
   полоса гаснет до тонкого хэйрлайна, клик выключен. Иначе окно безопасности заявляет
   «на этой машине ничего не разрешено» о машине, про которую ему ничего не ответили.
   Признак — АТРИБУТ `data-unk`, а не класс: ключ запомненной ширины окна (winKeyOf) собран
   из classList, и класс-состояние развалил бы его на два ключа. */
.v2ai[data-unk] .v2ai-sw .cc-switch { cursor: default; }
.v2ai[data-unk] .v2ai-sw .cc-switch-tr { background: transparent; box-shadow: inset 0 0 0 1px var(--line); }
.v2ai[data-unk] .v2ai-sw .cc-switch-tr::before {
  transform: translateX(9px); background: var(--text-dim); box-shadow: none;
  transition: transform 140ms cubic-bezier(.3, .8, .4, 1), background 140ms ease;
}
.v2ai-gh span { font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--muted); }
/* 🔴 ЗВОН-604·3 · «ПРИШЁЛ ИЗ ОТКАЗА — ПОКАЖИ СТРОКУ». Панель доступа — шесть разделов;
   открыть её по кнопке «Включить доступ ИИ» и бросить человека у входа значит повторить
   ровно ту жалобу, с которой он пришёл («где это, не могу найти»). Мягкая подложка +
   хэйрлайн-кольцо (правило акцента CLIE-483: никаких левых полос), гаснет само за 2.6 с.
   Уважает «меньше движения»: при prefers-reduced-motion — без анимации, просто подложка. */
/* 🔗 CLIE-1022 — та же подсветка у блока «Сделка или лид», когда он ПЕРЕЕХАЛ (стоял внизу
   карточки пустым, со связью встал наверху): второго рецепта подсветки не заводим. */
.v2ai-gh.cc-hl, .v2ai-sw.cc-hl, .tip-crm-card.cc-hl {
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent, var(--cm-4a7dff, #4a7dff)) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent, var(--cm-4a7dff, #4a7dff)) 26%, transparent);
  animation: ccAccHl 2.6s ease-out 1;
}
@keyframes ccAccHl {
  0%   { background: color-mix(in srgb, var(--accent, var(--cm-4a7dff, #4a7dff)) 26%, transparent); }
  100% { background: color-mix(in srgb, var(--accent, var(--cm-4a7dff, #4a7dff)) 8%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .v2ai-gh.cc-hl, .v2ai-sw.cc-hl, .tip-crm-card.cc-hl { animation: none; } }
/* ══ 0224 · «КТО ВИДИТ ФАЙЛЫ ЭТОГО КОМПЬЮТЕРА» ══════════════════════════════════════
   Ответ на вопрос владельца («это только я вижу?») — поимённо, строкой на человека, и
   ручка владельца машины рядом. Акцент несут ИМЯ и СЛОВО роли, подложки-рейки нет: список
   людей — это типографика, а не цветная полоса.                                        */
.v2ai-who { display: flex; flex-direction: column; padding: 0 14px; }
.v2ai-who-row {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 7px 0; border-bottom: 1px solid var(--line);
}
.v2ai-who-row:last-of-type { border-bottom: 0; }
.v2ai-who-row b { font-size: 13.5px; font-weight: 600; color: var(--fg); }
.v2ai-who-row em {
  font-style: normal; font-size: 10.5px; font-weight: 600; letter-spacing: .2px;
  padding: 1px 6px; border-radius: 999px; color: var(--accent);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent);
}
.v2ai-who-row small { margin-left: auto; font-size: 11.5px; color: var(--muted); }
.v2ai-who-note { padding: 8px 0 2px; font-size: 11.5px; line-height: 1.45; color: var(--muted); }
/* Ручка владельца машины: подпись сверху, сегмент строкой ниже (правило «поле + кнопка —
   на двух строках»), сегмент — канонический .cc-seg, своей дорожки не заводим. */
.v2ai-share { display: flex; flex-direction: column; align-items: stretch; gap: 8px; padding: 10px 14px 2px; }
/* 🔴 `hidden` ОБЯЗАН ПРЯТАТЬ: UA-правило `[hidden]{display:none}` слабее класса с `display:flex`, и
   ручку «Мой компьютер доступен» видел каждый управляющий — без выбранного пункта и с нажатием
   в пустоту (ручка только у владельца машины, `i_am_host`). Перепись прода 17.10: единственный
   такой узел в среде и панели «Доступ». */
.v2ai-share[hidden] { display: none; }
.v2ai-share-t { font-size: 12.5px; color: var(--muted); }
.v2ai-share .cc-seg { align-self: flex-start; }
/* 0225 · «Кому доступен проект и исходники». Тот же язык, что у ручки владельца машины:
   подпись сверху, канонический сегмент строкой ниже, пояснение под ним. Список людей
   раскрывается ТОЛЬКО в режиме «Выбранным» — пустое состояние экран не отбирает. */
.v2ai-aud { display: flex; flex-direction: column; padding: 0 0 4px; }
.v2ai-aud > .v2ai-who-note { padding: 4px 14px 8px; }
.v2ai-aud-hint { font-size: 11.5px; line-height: 1.45; color: var(--muted); }
.v2ai-aud-people { display: flex; flex-direction: column; gap: 2px; padding: 6px 14px 2px; }
.v2ai-aud-people .v2ai-who-row { align-items: center; }
.v2ai-aud-x {
  margin-left: auto; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; border: 0; border-radius: 8px; cursor: pointer;
  background: transparent; color: var(--muted); transition: background 140ms ease, color 140ms ease;
}
.v2ai-aud-x:hover { background: var(--danger-soft); color: var(--danger); }
.v2ai-aud-x svg { width: 13px; height: 13px; }
.v2ai-aud-people > .ghost.small {
  align-self: flex-start; margin-top: 6px;
  box-shadow: inset 0 0 0 1px var(--line);   /* безрамочная кнопка в списке читается как текст */
}
.v2ai-aud-people > .ghost.small:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent); }
.v2ai-aud-pick { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.v2ai-aud-pick[hidden] { display: none; }
.v2ai-aud-cand {
  text-align: left; font-size: 13px; color: var(--fg); background: transparent;
  border: 0; border-radius: 8px; padding: 7px 8px; cursor: pointer;
  transition: background 140ms ease;
}
.v2ai-aud-cand:hover { background: var(--hover); }
.v2ai-aud-cand:disabled { opacity: .45; cursor: default; }
/* СРЕД-25 · «К КАКИМ ПРОЕКТАМ И КОМУ ДАВАТЬ ДОСТУП» — тот же вопрос про ВСЕ мои проекты.
   Свёрнутая строка-раскрывашка: пока не нажали, экран занимает ОДНА строка. Акцент несут
   имя проекта и слово «кому открыто» справа — левых полос-реек здесь нет. */
.v2ai-projs-b {
  display: flex; align-items: center; gap: 8px; width: calc(100% - 28px); margin: 2px 14px 0;
  padding: 8px 10px; border: 0; border-radius: 10px; cursor: pointer; text-align: left;
  font-size: 12.5px; font-weight: 600; color: var(--fg); background: var(--hover);
  transition: background 140ms ease;
}
.v2ai-projs-b[hidden] { display: none; }
.v2ai-projs-b:hover { background: color-mix(in srgb, var(--accent) 10%, var(--hover)); }
.v2ai-projs-b svg { width: 12px; height: 12px; color: var(--muted); transition: transform 140ms ease; }
.v2ai-projs-b.on svg { transform: rotate(90deg); }
.v2ai-projs { display: flex; flex-direction: column; padding: 6px 14px 2px; }
.v2ai-projs[hidden] { display: none; }
.v2ai-pr-q { margin-bottom: 6px; }
.v2ai-pr-list { display: flex; flex-direction: column; max-height: 42vh; overflow: auto; }
.v2ai-pr { display: flex; flex-direction: column; border-bottom: 1px solid var(--line); }
.v2ai-pr:last-child { border-bottom: 0; }
.v2ai-pr-h {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 4px;
  border: 0; background: transparent; cursor: pointer; text-align: left; border-radius: 8px;
  transition: background 140ms ease;
}
.v2ai-pr-h:hover { background: var(--hover); }
.v2ai-pr-h svg { width: 11px; height: 11px; flex: none; color: var(--muted); transition: transform 140ms ease; }
.v2ai-pr.on .v2ai-pr-h svg { transform: rotate(90deg); }
.v2ai-pr-n {
  font-size: 13.5px; font-weight: 600; color: var(--fg);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.v2ai-pr-cur {
  flex: none; font-style: normal; font-size: 10.5px; color: var(--muted);
  padding: 1px 6px; border-radius: 999px; box-shadow: inset 0 0 0 1px var(--line);
}
.v2ai-pr-m {
  margin-left: auto; flex: none; font-size: 11.5px; font-weight: 600; color: var(--accent);
  padding: 1px 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 22%, transparent);
}
/* «Только вы» — не событие, а норма: тише имени проекта и без цветной подложки. */
.v2ai-pr-m.solo { color: var(--muted); background: transparent; box-shadow: none; padding-right: 2px; }
/* Раскрытая настройка вложена ПОД имя проекта (отступ на ширину галочки-раскрывашки):
   иерархия читается без рамок и без левой полосы-рейки. */
.v2ai-pr-b { padding: 0 0 10px 19px; }
.v2ai-pr-b .v2ai-share { padding: 2px 0; }
.v2ai-pr-b .v2ai-aud-people { padding: 8px 0 0; }
.v2ai-pr-b .v2ai-who-row { padding: 5px 0; }
.v2ai-pr-b .v2ai-aud-lead, .v2ai-pr-b .v2ai-aud-legend, .v2ai-pr-b .v2ai-aud-st,
.v2ai-pr-b .v2ai-aud-list, .v2ai-pr-b .v2ai-aud-empty, .v2ai-pr-b .v2ai-aud-pause,
.v2ai-pr-b .v2ai-aud-pausebtn { margin-left: 0; margin-right: 0; padding-left: 0; padding-right: 0; }
.v2ai-pr-b .v2ai-aud-pause { padding: 8px 10px; }
.v2ai-pr-b .v2ai-aud-mgr { padding: 10px 0; border-bottom: 0; }
.v2ai-pr-b .v2ai-aud-lead { display: none; }   /* пояснение уже стоит у раздела выше — не дублируем */

/* 🙋 0514 · ДВА РАЗНЫХ ДОСТУПА — ДВЕ ВКЛАДКИ: «Люди» (кому открыт проект) · «ИИ и компьютер» ·
   «Журнал». Сегмент — канонический .cc-seg; цифра просьб — пилюлей-акцентом внутри «Люди». */
.v2ai-tabs { flex: 0 0 auto; padding: 10px 14px; border-bottom: 1px solid var(--line); }
.v2ai-tabseg { display: flex; width: 100%; }
.v2ai-tabseg > button { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.v2ai-tab-n {
  font-style: normal; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: #fff; background: var(--acc-fill, var(--primary));
}
.v2ai-tab-n[hidden], .v2ai-tab[hidden] { display: none; }
.v2ai-tab { display: flex; flex-direction: column; }

.v2ai-aud-lead { margin: 2px 14px 6px; font-size: 12px; line-height: 1.5; color: var(--muted); }
/* Пауза — состояние, у которого есть выход: слова слева, «Вернуть доступ» рядом. */
.v2ai-aud-pause {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px;
  margin: 6px 14px; padding: 10px 12px; border-radius: 12px; font-size: 12.5px; line-height: 1.45;
  color: var(--fg);
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 26%, transparent);
}
.v2ai-aud-pause > span { flex: 1 1 220px; min-width: 0; }
.v2ai-aud-pause .primary.small { width: auto; margin: 0; }
.v2ai-aud-st {
  display: flex; align-items: center; gap: 6px; padding: 12px 14px 4px;
  font-size: 12px; font-weight: 600; color: var(--text-dim);
}
.v2ai-aud-st b {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
  color: var(--text-dim); box-shadow: inset 0 0 0 1px var(--line);
}
.v2ai-aud-st em {
  font-style: normal; font-size: 10.5px; font-weight: 600; padding: 1px 6px; border-radius: 999px;
  color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, transparent);
}
.v2ai-aud-list { display: flex; flex-direction: column; padding: 0 14px; }
.v2ai-aud-list.paused .v2ai-aud-nm b { color: var(--muted); }
.v2ai-aud-row {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px;
  min-height: var(--ctl-h); padding: 6px 0; border-bottom: 1px solid var(--line);
}
.v2ai-aud-row:last-child { border-bottom: 0; }
.v2ai-aud-nm { flex: 1 1 150px; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.v2ai-aud-nm b { font-size: 13.5px; font-weight: 600; color: var(--fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.v2ai-aud-nm small { font-size: 11.5px; color: var(--muted); }
.v2ai-aud-lv { font-size: 12px; color: var(--muted); }
.v2ai-aud-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-left: auto; }
.v2ai-aud-acts .primary.small, .v2ai-aud-acts .ghost.small { width: auto; margin: 0; }
.v2ai-aud-acts .ghost.small { box-shadow: inset 0 0 0 1px var(--line); }
.v2ai-aud-acts .ghost.small:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent); }
.v2ai-aud-acts .v2ai-aud-no { color: var(--muted); }
.v2ai-aud-acts button.busy, .v2ai-aud-lvl button.busy { opacity: .55; cursor: default; }
/* Просьба — событие: имя в строке с мягким акцентом, кнопки решения рядом. */
.v2ai-aud-row.req .v2ai-aud-nm small { color: var(--primary-2, var(--primary)); }
.v2ai-aud-lvl { flex: none; margin-left: auto; }
.v2ai-aud-row .v2ai-aud-x { margin-left: 0; }
.v2ai-aud-empty { padding: 6px 14px 8px; font-size: 12px; line-height: 1.45; color: var(--muted); }
.v2ai-aud-more {
  align-self: flex-start; margin: 4px 0 2px; padding: 6px 0; border: 0; background: transparent;
  color: var(--primary); font: inherit; font-size: 12.5px; cursor: pointer;
}
.v2ai-aud-more:hover { text-decoration: underline; }
.v2ai-aud-legend {
  display: flex; flex-direction: column; gap: 3px; margin: 10px 14px 4px; padding-top: 8px;
  border-top: 1px solid var(--line); font-size: 11.5px; line-height: 1.45; color: var(--muted);
}
.v2ai-aud-legend b { font-weight: 600; color: var(--text-dim); }
.v2ai-aud-mgr { border-bottom: 0; }
.v2ai-aud-pausebtn {
  align-self: flex-start; margin: 0 14px 10px; padding: 6px 0; border: 0; background: transparent;
  color: var(--muted); font: inherit; font-size: 12px; cursor: pointer;
}
.v2ai-aud-pausebtn:hover { color: var(--danger); text-decoration: underline; }
/* Ошибка загрузки — над самими тумблерами, с явным «Повторить». Кнопка не жмётся в один ряд
   с текстом (правило «поле + кнопка — на двух строках»): причина сверху, действие ниже слева. */
.v2ai-err {
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  margin: 10px 14px 0; padding: 10px 12px; border-radius: 12px;
  background: var(--danger-soft); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 26%, transparent);
  animation: v2fbIn 140ms ease;
}
.v2ai-err[hidden] { display: none; }   /* [hidden] бессилен против display:flex — гасим явно */
.v2ai-err-t { font-size: 12.5px; line-height: 1.45; color: var(--danger); }
/* Кнопка та же `.ghost.small`, что у «Машины/Отозвать», но с тонким кольцом в цвете тревоги:
   на подложке ошибки безрамочная кнопка читается как обычный текст, а её ищут глазами. */
.v2ai .v2ai-err .ghost { color: var(--danger); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 32%, transparent); }
.v2ai .v2ai-err .ghost:hover { background: color-mix(in srgb, var(--danger) 10%, transparent); }
.v2ai .v2ai-err .ghost[disabled] { opacity: .55; cursor: default; }
.v2ai-meta { padding: 10px 14px 0; font-size: 12px; color: var(--muted); }
/* 🔒 СРЕД-11: «превью на этот порт не пустят» — это отказ, а не примечание: он обязан
   читаться так же тревожно, как строка `deny` в журнале ниже (тот же цвет, без заливки). */
.v2ai-meta.deny { color: var(--danger, #d64545); }
.v2ai-acts { display: flex; flex-wrap: wrap; gap: 8px; padding: 10px 14px 4px; }
.v2ai-j.deny .v2ai-j-ico { color: #fff; background: var(--danger, #e5484d); border-color: transparent; }
.v2ai-j.deny .v2ai-j-l b.v2ai-no { color: var(--danger, #e5484d); }

.v2ai-empty { padding: 26px 18px; text-align: center; font-size: 13px; line-height: 1.5; color: var(--muted); }
@media (max-width: 720px) {
  .v2ai { width: 100%; max-width: none; height: 100dvh; max-height: none; border-radius: 0; }
}

/* ══ Э3 · «Спросить ИИ» прямо из редактора ═══════════════════════════════════════
   Полоса под кодом. Пустого места НЕ занимает: её нет, пока разработчик не выбрал пункт
   в контекстном меню (прогрессивное раскрытие). 🔴 `[hidden]` бессилен против display:flex —
   гасим явным правилом (та же грабля, что у панели действий превью в Э1). */
.dvs-ask {
  flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px;
  padding: 10px 12px 12px; border-top: 1px solid var(--line); background: var(--panel);
  animation: dvsAskIn 140ms ease;
}
.dvs-ask[hidden] { display: none; }
@keyframes dvsAskIn { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.dvs-ask-head { display: flex; align-items: center; gap: 8px; }
.dvs-ask-grow { flex: 1 1 auto; }
.dvs-ask-place {
  display: inline-flex; align-items: center; gap: 6px; min-width: 0; font-size: 12px;
  color: var(--muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.dvs-ask-place span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-ask-place .ic { width: 14px; height: 14px; flex: 0 0 auto; }
.dvs-ask-x {
  display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px;
  border: 0; border-radius: 8px; background: transparent; color: var(--muted); cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.dvs-ask-x:hover { background: var(--hover); color: var(--text); }
.dvs-ask-x .ic { width: 15px; height: 15px; }
/* max-height — чтобы растянутое поле не съело редактор до нуля (ручка resize даёт тянуть
   бесконечно, а пола у высоты кода нет). */
.dvs-ask-q {
  width: 100%; box-sizing: border-box; min-height: 54px; max-height: 40vh; resize: vertical;
  padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel-2); color: var(--text); font: inherit; font-size: 13px; line-height: 1.45;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.dvs-ask-q::placeholder { color: var(--muted); }
.dvs-ask-q:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent);
}
.dvs-ask-foot { display: flex; align-items: center; gap: 10px; }
.dvs-ask-state { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--muted); }

/* Место в коде на КАРТОЧКЕ задачи: чип-возврат в редактор + снимок фрагмента. */
.tip-code-card .tip-code-chip {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px;
}
.tip-code-card .tip-code-chip .tip-chiplbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-code-card .tip-code-chip .ic { width: 15px; height: 15px; color: var(--muted); flex: 0 0 auto; }
.tip-code-pre {
  margin: 10px 0 0; padding: 10px 12px; max-height: 260px; overflow: auto;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2);
}
.tip-code-pre code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.5;
  color: var(--text); white-space: pre;
}

/* ══ 🌿 Э2 · ВЕТКА ЗАДАЧИ: чип в шапке среды + блок на карточке задачи ══════════════
   Всё на токенах (--line/--muted/--panel-2/--hover/--accent) → светлая и тёмная темы
   одинаковы без второго набора правил. В покое блок ничего не «кричит»: хэйрлайны,
   приглушённый текст, подсветка только на hover.                                    */
.dvs-tasklink {
  display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 8px;
  border: 1px solid var(--line); border-radius: 8px; background: transparent;
  font-size: 12px; font-weight: 600; color: var(--muted); cursor: pointer; max-width: 190px;
  transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.dvs-tasklink:hover { background: var(--hover); color: var(--text); border-color: var(--accent); }
.dvs-tasklink > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvs-tasklink .ic { width: 13px; height: 13px; flex: 0 0 auto; color: var(--accent); }

/* «Ветка задачи» — сворачиваемая секция в САМОМ НИЗУ карточки, по умолчанию свёрнута
   (владелец, СРЕД-21: «скрывать и раскрывать, по умолчанию скрыть, и в самый низ»).
   Габариты строки-раскрытия (44px, hover, вся ширина плитки) даёт общий `.tip-disc-h` —
   здесь только сброс кнопки и её содержимое, как у `.td-mem-toggle`/`.tip-ai-toggle`. */
.tdev-toggle { border: 0; background: none; font: inherit; cursor: pointer; text-align: left;
  font-size: 12px; font-weight: 700; }
.tdev-toggle .tdev-lbl { flex: 0 0 auto; }
/* Превью = имя ветки (или состояние, если ветки ещё нет): свёрнутая секция обязана сама
   сказать, что внутри, иначе «свернули» читается как «спрятали функционал». В раскрытом
   виде оно дублирует чип ветки — прячем (паритет с блоком «ИИ»). */
.tdev-toggle .tdev-pv { margin-left: 2px; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none; color: var(--muted); }
.tdev-toggle:not(.collapsed) .tdev-pv { display: none; }
.tdev-toggle .tdev-chev { margin-left: auto; padding-left: 8px; display: inline-flex; align-items: center;
  transition: transform .16s ease; opacity: .7; }
.tdev-toggle .tdev-chev svg { width: 14px; height: 14px; }
.tdev-toggle.collapsed .tdev-chev { transform: rotate(-90deg); }
.tdev-toggle:hover { color: var(--primary); }
.tdev-toggle:hover .tdev-pv { opacity: .85; }
.tdev-toggle:hover .tdev-chev { opacity: 1; }
.tdev-toggle:focus-visible { outline: 2px solid color-mix(in srgb, var(--primary) 55%, transparent);
  outline-offset: 2px; border-radius: 4px; }
/* шеврон замыкает строку справа — отдельный ::after-хэйрлайн секции лишний (как у соседей) */
.task-info-panel .td-section-h.tdev-toggle::after,
.tdev-toggle.td-section-h::after { content: none; }
.tdev-body[hidden] { display: none !important; }
/* Раскрытая шапка выпущена за паддинг карточки (см. `.tip-card > .tip-disc-h`) — телу нужен
   свой отступ, иначе ветка липнет к хэйрлайну. */
.tip-card > .tip-disc-h + .tdev-body { margin-top: 12px; }

.tip-dev-card .tdev-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tdev-branch {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0;
  height: 28px; padding: 0 10px; border: 1px dashed var(--line); border-radius: 9px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; color: var(--muted);
}
.tdev-branch.on { border-style: solid; color: var(--text); background: var(--panel-2); }
.tdev-branch > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tdev-branch .ic { width: 14px; height: 14px; flex: 0 0 auto; color: var(--accent); }
.tdev-state { font-size: 12px; color: var(--muted); }
/* Кнопка действия — вторичная, «как в системе»: хэйрлайн, 8-grid, тихий hover. Иконку и
   подпись держим в одной строке (у голого `.ghost` они вставали столбиком). */
.tdev-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.tip-dev-card .tdev-acts button {
  display: inline-flex; align-items: center; gap: 6px; height: 30px; padding: 0 12px;
  /* 🔴 `--line-strong`, а НЕ `--line`: карточка задачи сама нарисована на `--panel-2`, и
     хэйрлайн цвета разделителя на ней не виден — кнопка читалась как голый текст (поймано
     на снимке прода). Граница контрола = `--line-strong`, это её назначение. */
  border: 1px solid var(--line-strong); border-radius: 9px; background: var(--panel);
  font-size: 12.5px; font-weight: 600; color: var(--text); cursor: pointer;
  transition: background 130ms ease, border-color 130ms ease, opacity 130ms ease;
}
.tip-dev-card .tdev-acts button:hover:not(:disabled) { background: var(--hover); border-color: var(--accent); }
.tip-dev-card .tdev-acts button:disabled { opacity: 0.55; cursor: default; }
.tip-dev-card .tdev-acts button .ic { width: 14px; height: 14px; flex: 0 0 auto; color: var(--accent); }
.tdev-empty { margin: 10px 0 0; font-size: 12.5px; line-height: 1.5; color: var(--muted); }

.tdev-clist { margin-top: 12px; border-top: 1px solid var(--line); }
.tdev-c { border-bottom: 1px solid var(--line); }
.tdev-c:last-child { border-bottom: 0; }
.tdev-chead {
  display: flex; flex-direction: column; gap: 2px; width: 100%; padding: 8px 4px;
  border: 0; background: transparent; text-align: left; cursor: pointer; border-radius: 8px;
  transition: background 120ms ease;
}
.tdev-chead:hover { background: var(--hover); }
.tdev-csub {
  font-size: 12.5px; color: var(--text); line-height: 1.35;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tdev-cmeta { font-size: 11.5px; color: var(--muted); }
.tdev-cfiles { padding: 0 0 8px 4px; display: flex; flex-direction: column; gap: 1px; }
.tdev-f {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 4px 8px; border: 0;
  border-radius: 7px; background: transparent; color: var(--text); font-size: 12px; text-align: left;
  cursor: pointer; transition: background 120ms ease;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.tdev-f:hover { background: var(--hover); }
.tdev-f.as-plain { cursor: default; }
.tdev-f.as-plain:hover { background: transparent; }
.tdev-fst { width: 12px; text-align: center; font-weight: 700; flex: 0 0 auto; }
.tdev-fst.add { color: var(--ok); }
.tdev-fst.del { color: var(--danger); }
.tdev-fst.mod { color: var(--muted); }
.tdev-fp { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left; }
.tdev-rep { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 10px; }
.tdev-rep-h { font-size: 11.5px; color: var(--muted); margin-bottom: 4px; }

/* ══ ☁️ Э5 · облачный рантайм: чип в шапке среды + карточка бокса ═══════════════════
   Всё на токенах (--line/--muted/--panel/--hover) → светлая и тёмная темы одинаковы без
   второго набора правил. Чип в покое ничего не отбирает: тонкая рамка и приглушённый
   текст; «горит» только когда бокс реально поднят.                                   */
.dvs-cloud {
  display: inline-flex; align-items: center; gap: 6px; min-height: 26px; padding: 3px 9px;
  white-space: nowrap; flex: 0 0 auto; max-width: 180px; overflow: hidden; text-overflow: ellipsis;
  border: 1px solid var(--line); border-radius: 8px; background: transparent;
  color: var(--muted); font-size: 12px; cursor: pointer;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.dvs-cloud .ic { width: 14px; height: 14px; }
.dvs-cloud:hover { background: var(--hover); color: var(--fg); }
.dvs-cloud.on { color: var(--fg); border-color: var(--fg); }
.dvs-cloud[data-st="error"] { color: #d1495b; border-color: #d1495b55; }
.dvs-cloud .v2prev-dot { margin-left: 1px; }
/* 0224 · чип «кто видит файлы этого компьютера». Тот же размерный класс, что у соседей по
   шапке (--ctl-*, как .dvs-cloud), чтобы ряд не разъезжался. В покое — приглушённый: «видите
   только вы» не должно тревожить; как только глаз становится больше одного, чип берёт цвет
   акцента — это факт, о котором человек обязан узнать без клика. */
.dvs-who {
  display: inline-flex; align-items: center; gap: 6px; min-height: 26px; padding: 3px 9px;
  white-space: nowrap; flex: 0 0 auto; border: 1px solid var(--line); border-radius: 8px;
  background: transparent; color: var(--accent); font-size: 12px; cursor: pointer;
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
/* 🔴 [hidden] бессилен против display:inline-flex — без этой строки чип «Видят: N» и чип
   «Облако» НЕ гасли никогда: `who.hidden = true` в коде ничего не делал, и на закрытом
   проекте оставалась цифра от соседнего (тот же класс бага, что у .v2ai-err[hidden]). */
.dvs-who[hidden], .dvs-cloud[hidden] { display: none; }
.dvs-who .ic { width: 14px; height: 14px; }
.dvs-who:hover { background: var(--hover); }
.dvs-who:not(.solo) { border-color: color-mix(in srgb, var(--accent) 34%, transparent); }
.dvs-who.solo { color: var(--muted); }
/* Бокса нет вовсе — точка не нужна: пустой индикатор читался бы как «что-то сломалось». */
.dvs-cloud:not([data-st]) .v2prev-dot, .dvs-cloud[data-st=""] .v2prev-dot { display: none; }

.cbx { display: flex; flex-direction: column; gap: 12px; }
.cbx-load { padding: 24px; text-align: center; color: var(--muted); font-size: 13px; }
.cbx-head { display: flex; align-items: center; gap: 10px; }
.cbx-grow { flex: 1 1 auto; }
.cbx-st { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; }
.cbx-st b { font-weight: 600; }
.cbx-plan { font-size: 12px; color: var(--muted); }
.cbx-err {
  padding: 9px 11px; border-radius: 10px; font-size: 12.5px; line-height: 1.45;
  background: #d1495b14; border: 1px solid #d1495b40; color: var(--fg);
}
.cbx-f { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.cbx-f > span { font-size: 11.5px; color: var(--muted); }
.cbx-f input {
  width: 100%; box-sizing: border-box; height: 32px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--fg);
  font-size: 13px; transition: border-color 140ms ease, box-shadow 140ms ease;
}
.cbx-f input:focus { outline: 0; border-color: var(--fg); box-shadow: 0 0 0 3px color-mix(in srgb, var(--fg) 10%, transparent); }
.cbx-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.cbx-sec { border-top: 1px solid var(--line); padding-top: 12px; display: flex; flex-direction: column; gap: 9px; }
.cbx-sec-h { font-size: 12.5px; font-weight: 600; }
/* СРЕД-37·5 · подпись под полем: зачем оно и что будет, если оставить пустым. */
.cbx-hint { font-size: 11.5px; line-height: 1.45; color: var(--muted); margin: -4px 0 2px; }
/* 0508 · Минуты облака: кончились — акцент-блок (подложка + кольцо, без левых реек, канон
   `accent`) со словами сервера и главной кнопкой; остались — одна тихая кнопка «Увеличить время». */
.cbx-min { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.cbx-min.over {
  padding: 10px 12px; border-radius: 10px;
  background: color-mix(in srgb, var(--warning, #e0a020) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning, #e0a020) 22%, transparent);
}
.cbx-min-say { flex: 1 1 100%; font-size: 12.5px; line-height: 1.45; color: var(--fg); }
/* 0509 · Тариф выше — ВТОРОЙ ссылкой рядом с «Купить минуты» (спека §3.3): ссылка, а не вторая
   кнопка — главное действие здесь одно. Текстовый акцент — `--primary-2` (у заливки свой токен). */
.cbx-link { border: 0; background: none; padding: 2px; border-radius: 6px; cursor: pointer;
  color: var(--primary-2); font-size: 12.5px; text-decoration: underline; text-underline-offset: 2px;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent); }
.cbx-link:hover { text-decoration-color: currentColor; background: none; }
.cbx-sec-h em { font-style: normal; font-weight: 400; color: var(--muted); font-size: 11.5px; }
.cbx-keys { display: flex; flex-wrap: wrap; gap: 6px; }
.cbx-key {
  display: inline-flex; align-items: center; gap: 4px; padding: 3px 4px 3px 9px;
  border: 1px solid var(--line); border-radius: 7px; font-size: 12px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.cbx-key button { border: 0; background: transparent; color: var(--muted); cursor: pointer; padding: 2px; display: flex; border-radius: 5px; }
.cbx-key button:hover { background: var(--hover); color: var(--fg); }
.cbx-key .ic { width: 12px; height: 12px; }
.cbx-none { font-size: 12px; color: var(--muted); }
/* Правило продукта: поле-значение и его кнопка — на РАЗНЫХ строках, а не в один ряд. */
.cbx-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.cbx-log {
  margin: 0; max-height: 190px; overflow: auto; padding: 10px 12px; border-radius: 10px;
  background: var(--hover); border: 1px solid var(--line); font-size: 11.5px; line-height: 1.5;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; white-space: pre-wrap; color: var(--muted);
}
.cbx-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; border-top: 1px solid var(--line); padding-top: 12px; }
.cbx-saved { font-style: normal; font-size: 11.5px; color: var(--muted); }
.cbx-del span { color: #d1495b; }
@media (max-width: 620px) { .cbx-row2 { grid-template-columns: 1fr; } }

/* ── Э5: МАШИНЫ («ноутбук дома, рабочий компьютер, сервер») ───────────────────────
   Строка = один компьютер: точка состояния, иконка, ИМЯ (правится прямо тут, без
   карандаша и кнопки «Сохранить»), подпись «на связи / была час назад», действия —
   только на наведение, чтобы список читался, а не пестрел. Выделение выбранной машины —
   тонкая рамка и мягкая подложка, без заливки на всю строку. Обе темы. */
.dvm { display: flex; flex-direction: column; gap: 2px; }
.dvm-load { padding: 24px; text-align: center; color: var(--muted); font-size: 13px; }
.dvm-hd {
  font-size: 11.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); margin: 2px 0 6px;
}
.dvm-row {
  display: flex; align-items: center; gap: 10px; min-height: 52px; padding: 8px 10px;
  border: 1px solid transparent; border-radius: 11px; cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease;
}
.dvm-row:hover { background: var(--hover); }
.dvm-row:focus-visible { outline: 0; border-color: var(--fg); }
.dvm-row.sel {
  border-color: color-mix(in srgb, var(--fg) 22%, transparent);
  background: color-mix(in srgb, var(--fg) 5%, transparent);
}
.dvm-row.off .dvm-ico, .dvm-row.off .dvm-name { color: var(--muted); }
.dvm-ico { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; flex: 0 0 auto; border-radius: 9px; background: var(--hover); }
.dvm-ico .ic { width: 16px; height: 16px; }
.dvm-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dvm-name {
  font-size: 13.5px; font-weight: 600; color: var(--fg); border: 1px solid transparent;
  background: transparent; border-radius: 7px; padding: 2px 6px; margin: 0 -6px;
  width: 100%; box-sizing: border-box; font-family: inherit;
  transition: border-color 140ms ease, background 140ms ease;
}
.dvm-name.ro { padding: 2px 0; margin: 0; }
input.dvm-name:hover { border-color: var(--line); }
input.dvm-name:focus { outline: 0; border-color: var(--fg); background: var(--panel); cursor: text; }
.dvm-sub { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvm-badge {
  flex: 0 0 auto; font-size: 11px; font-weight: 600; padding: 3px 8px; border-radius: 999px;
  color: var(--ok); background: var(--ok-soft);
}
.dvm-acts { flex: 0 0 auto; display: flex; gap: 2px; opacity: 0; transition: opacity 140ms ease; }
.dvm-row:hover .dvm-acts, .dvm-row:focus-within .dvm-acts { opacity: 1; }
/* 🔴 ТАЧ: навести нельзя — значит «Отключить машину» и «Убрать из списка» на планшете просто
   НЕ СУЩЕСТВУЮТ (единственный способ наткнуться — случайно попасть в поле имени и получить
   focus-within). Тот же фолбэк, что у остальных наведением-действий продукта: .task-hover-acts,
   .tw-card-acts, .att-vid-dl. Пункт чек-листа «отключить машину» обязан работать и пальцем. */
@media (hover: none) { .dvm-acts { opacity: 1; } }
.dvm-x {
  border: 0; background: transparent; color: var(--muted); cursor: pointer;
  padding: 6px; display: flex; border-radius: 8px;
}
.dvm-x:hover { background: var(--hover); color: var(--fg); }
.dvm-x .ic { width: 15px; height: 15px; }
.dvm-empty { padding: 18px 10px; font-size: 12.5px; color: var(--muted); }
.dvm-warn {
  display: flex; gap: 8px; align-items: flex-start; margin-top: 8px; padding: 9px 11px;
  border-radius: 10px; font-size: 12.5px; line-height: 1.45;
  background: var(--warning-soft); border: 1px solid color-mix(in srgb, var(--warning) 38%, transparent);
}
.dvm-warn .ic { width: 15px; height: 15px; flex: 0 0 auto; margin-top: 1px; color: var(--warning); }
.dvm-add { border-top: 1px solid var(--line); margin-top: 10px; padding-top: 12px; }
/* Правило продукта: поле-значение и его кнопка — на РАЗНЫХ строках, не в один ряд. */
.dvm-cmd { display: flex; flex-direction: column; gap: 8px; }
/* 🔴 `[hidden]` бессилен против `display:flex` (та же грабля, что была с панелью действий
   в «Превью»): без этой строки пустая рамка команды висит на экране до первого нажатия. */
.dvm-cmd[hidden] { display: none; }
.dvm-cmd code {
  display: block; width: 100%; box-sizing: border-box; padding: 10px 12px; border-radius: 10px;
  background: var(--hover); border: 1px solid var(--line); font-size: 11.5px; line-height: 1.5;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; word-break: break-all; color: var(--fg);
}
.dvm-cmd-acts { display: flex; gap: 8px; flex-wrap: wrap; }
/* Команда подключения машины: у неё ДВЕ породы (macOS/Linux и Windows), и спрашиваем мы их
   КАНОНИЧЕСКИМ сегментом `.cc-seg` — своей дорожки с пилюлей здесь нет (CLIE-505). Блок один
   на оба места (карточка «подключите компьютер» и окно «Машины»), поэтому и стили одни. */
.dvcmd-os { align-self: flex-start; }
.dvcmd-acts { display: flex; gap: 8px; flex-wrap: wrap; }
/* Рамка карточки «Превью» центрирует содержимое — команду и подсказку читают слева. */
.v2prev-cmd .dvcmd-os, .v2prev-cmd .dvcmd-acts, .v2prev-cmd .dvm-hint { text-align: left; }
.dvm-hint { margin: 0; font-size: 11.5px; color: var(--muted); line-height: 1.45; }
.dvm-foot { margin: 10px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.45; }
/* «Подключить ещё компьютер» и «Подключить хостинг (SSH/FTP)» — одной строкой, слева. */
.dvm-add-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.dvm-add-acts[hidden], .dvm-add-acts > [hidden] { display: none; }

/* ══════ 🌐 ХОСТИНГ ПРОЕКТА (SSH/FTP) — форма devHostOpen ══════
   Поля — те же `.cbx-f`, что у облачного бокса (второй вёрстки формы нет). Здесь только
   своё: строка состояния, ключ моноширинным текстом, результат подключения, отпечатки.
   Цвета — только токенами: обе темы одинаковы. Акцент результата — подложка + кольцо,
   без левых реек (CLIE-483). */
.dvh { display: flex; flex-direction: column; gap: 12px; }
.dvh-st {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: 11px; background: var(--hover);
}
.dvh-st-t { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dvh-st-t b {
  font-size: 13px; font-weight: 600; color: var(--fg);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dvh-st-t span { font-size: 11.5px; color: var(--muted); }
.dvh-fp { font-size: 11.5px; color: var(--muted); margin-top: -6px; }
.dvh code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px;
  color: var(--fg); word-break: break-all;
}
.dvh-seg { align-self: flex-start; }
.dvh-row2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(84px, 7.5em); gap: 10px; }
.dvh .cbx-f textarea {
  width: 100%; box-sizing: border-box; min-height: 104px; resize: vertical; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--fg);
  font: 11.5px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.dvh .cbx-f textarea:focus {
  outline: 0; border-color: var(--fg);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--fg) 10%, transparent);
}
.dvh .cbx-f textarea.drop {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent);
}
.dvh .cbx-f input:disabled, .dvh .cbx-f textarea:disabled { opacity: .6; cursor: not-allowed; }
.dvh .cbx-f.bad input, .dvh .cbx-f.bad textarea {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 14%, transparent);
}
.dvh .cbx-f.bad > span { color: var(--danger); }
.dvh-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dvh-acts .v2prev-btn, .dvh-foot .v2prev-primary { display: inline-flex; align-items: center; gap: 7px; }
.dvh .v2prev-btn:disabled { opacity: .55; cursor: default; }
.dvh-sub { font-size: 11.5px; color: var(--muted); line-height: 1.4; }
.dvh-res {
  display: flex; align-items: flex-start; gap: 9px; padding: 10px 12px; border-radius: 10px;
  font-size: 12.5px; line-height: 1.45; color: var(--fg);
}
.dvh-res[hidden] { display: none; }
.dvh-res > .ic { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.dvh-res > .cc-spin { margin-top: 2px; }
.dvh-res.busy { background: var(--hover); color: var(--muted); }
.dvh-res.ok {
  background: var(--ok-soft);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 22%, transparent);
}
.dvh-res.ok > .ic { color: var(--ok); }
.dvh-res.err {
  background: var(--danger-soft);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent);
}
.dvh-res.err > .ic { color: var(--danger); }
.dvh-res-b { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.dvh-res-b b { font-weight: 600; }
.dvh-res-b > span { color: var(--muted); }
.dvh-fps { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 10px; align-items: baseline; }
.dvh-fps > span { color: var(--muted); font-size: 11.5px; }
.dvh-foot { display: flex; gap: 8px; flex-wrap: wrap; border-top: 1px solid var(--line); padding-top: 12px; }
.dvh-off span { color: var(--danger); }
.dvh-note { margin: 0; font-size: 11.5px; line-height: 1.45; color: var(--muted); }

/* 🔴 ЖУРНАЛ ВЛАДЕЛЬЦА МАШИНЫ прямо в окне «Машины»: «что делали на МОЁМ компьютере» —
   сквозь все проекты, в том числе те, которыми человек не управляет. Отделён хэйрлайном
   сверху (это другой вопрос, чем «где запускать»), строки рисует тот же `.v2ai-j`, что и
   журнал проекта, — второй вёрстки журнала в продукте нет. */
.dvm-hd + .dvm-audit, .dvm-audit { margin-top: 2px; max-height: 320px; overflow: auto; }
.dvm .dvm-hd:not(:first-child) {
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line);
  display: flex; align-items: baseline; gap: 8px;
}
.dvm-hd-s {
  font-size: 10.5px; font-weight: 500; letter-spacing: 0; text-transform: none; opacity: .8;
}

/* Чип состояния среды/превью стал КНОПКОЙ (вход в «Машины») — сбрасываем вид кнопки и
   показываем имя машины только когда машин несколько (правило «не отбирать экран»). */
.dvs-state, .v2prev-status {
  border: 1px solid transparent; background: transparent; font: inherit; cursor: pointer;
  border-radius: 8px; padding: 3px 7px; transition: background 140ms ease, border-color 140ms ease;
}
.dvs-state:hover, .v2prev-status:hover { background: var(--hover); }
.dvs-state em, .v2prev-status em {
  font-style: normal; color: var(--fg); font-weight: 600; max-width: 160px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dvs-state em::before, .v2prev-status em::before { content: "· "; color: var(--muted); font-weight: 400; }

.v2prev-or { margin: 14px 0 0; font-size: 12.5px; color: var(--muted); }
.v2prev-link {
  border: 0; background: transparent; padding: 0; font: inherit; color: var(--fg);
  text-decoration: underline; text-underline-offset: 2px; cursor: pointer;
}

/* ── Работы ИИ в среде (Э3): очередь работ и приёмка. Панель живёт в правой колонке ──
   рядом с превью и сборками. Никакой заливки на всю строку: тонкие хэйрлайны, точка
   состояния, спокойная типографика — как в системных списках macOS. */
.dvai { display: flex; flex-direction: column; min-width: 0; width: 100%; height: 100%; }

/* ── 🔴 СРЕД-26/3 · ПАНЕЛЬ ИИ = ЧАТ + ХОД РАБОТ (как VS Code/Cursor и Claude Code) ────────
   Владелец: «Чат с Ии есть справа как у vs code? … Есть список задач и ход их выполнения как
   в Клод и вс код? … Тут даже модель нельзя выбрать». Раскладка: тонкая шапка с сегментом,
   сама лента/список тянутся, композер прибит внизу — там же, где чип модели. Цвета — только
   токены темы: панель обязана быть одинаково вылизана в светлой и тёмной. */
.dvai-top {
  flex: 0 0 auto; display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; border-bottom: 1px solid var(--line);
}
.dvai-tabs { flex: 0 0 auto; }
.dvai-topacts { margin-left: auto; display: flex; align-items: center; gap: 4px; min-width: 0; }
.dvai-ico {
  display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
  border: 1px solid transparent; border-radius: 8px; background: transparent;
  color: var(--muted); font-size: 12px; cursor: pointer; white-space: nowrap;
  transition: background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.dvai-ico:hover { background: var(--hover); color: var(--fg); border-color: var(--line); }
.dvai-ico .ic { width: 13px; height: 13px; }
.dvai-pane { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.dvai-pane[hidden] { display: none; }

/* ── 🔴🔴 ЛЕНТА ЧАТОВ СРЕДЫ (владелец 16.09.2026: «вести сразу несколько чатов как в
   пространстве клода… и фильтровать их по проектам») ─────────────────────────────────────
   Фильтр закреплён СЛЕВА, вне горизонтального скролла: контрол, который сужает список,
   обязан быть виден всё время, пока сужение включено (иначе «куда всё пропало»). Чипы
   разговоров скроллятся, «＋» прибит справа — он не должен уезжать вместе с ними. */
.dvai-thbar {
  flex: 0 0 auto; display: flex; align-items: center; gap: 6px;
  padding: 6px 8px 6px 10px; border-bottom: 1px solid var(--line); min-width: 0;
}
.dvai-thf, .dvai-thnew {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 4px; height: 24px;
  padding: 0 7px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg);
  color: var(--muted); font-size: 11.5px; cursor: pointer; white-space: nowrap;
  transition: background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.dvai-thf { max-width: 44%; }
.dvai-thf > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-thf .ic, .dvai-thnew .ic { width: 12px; height: 12px; flex: 0 0 auto; }
.dvai-thf:hover, .dvai-thnew:hover { background: var(--hover); color: var(--fg); border-color: var(--fg); }
.dvai-thnew { width: 24px; padding: 0; justify-content: center; }
/* ── 🎞🎞 CLIE-1479 · ЛЕНТА — КАРУСЕЛЬ (колесо · протяжка · стрелки · гаснущий край) ───────
   Постановщик 22.09.2026: «когда нужный чат не помещается, приходится заходить в „Историю"».
   Рельс — коробка ленты со стрелками ПОВЕРХ краёв: они не занимают места в строке (иначе
   каждый чип платил бы за них шириной) и всплывают только туда, куда есть ход, — классы
   `more-l`/`more-r` ставит `devAiThEdges`. Край подтаивает маской: это ТОТ ЖЕ приём, что у
   `.conv-tabs` и лестницы `ccSegFit`, второй реализации не заводим. */
.dvai-thrail { position: relative; flex: 1 1 auto; min-width: 0; display: flex; align-items: center; }
.dvai-ths {
  flex: 1 1 auto; min-width: 0; display: flex; align-items: center; gap: 5px;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none;
  /* Полотно тянется рукой: курсор обещает жест ещё до нажатия, а `touch-action: pan-x`
     оставляет пальцу нативную горизонтальную прокрутку (ядро глушит только свой жест). */
  cursor: grab; touch-action: pan-x; overscroll-behavior-x: contain;
}
.dvai-ths.panning { cursor: grabbing; user-select: none; }
.dvai-ths::-webkit-scrollbar { display: none; }
/* Стрелка (20 px, сдвиг −2px) лежит НАД краем ленты и закрывает её крайние 18 px: прежняя маска
   в 26 px гасла почти вся под стрелкой, и чип резался посреди слова прямо под ней (кадр «Везд»).
   Под стрелкой край уже прозрачен (18 px), перед ней тает ещё 28 px. */
.dvai-thrail.more-l .dvai-ths {
  -webkit-mask-image: linear-gradient(to right, transparent 18px, #000 46px);
  mask-image: linear-gradient(to right, transparent 18px, #000 46px);
}
.dvai-thrail.more-r .dvai-ths {
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 46px), transparent calc(100% - 18px));
  mask-image: linear-gradient(to right, #000 calc(100% - 46px), transparent calc(100% - 18px));
}
.dvai-thrail.more-l.more-r .dvai-ths {
  -webkit-mask-image: linear-gradient(to right, transparent 18px, #000 46px, #000 calc(100% - 46px), transparent calc(100% - 18px));
  mask-image: linear-gradient(to right, transparent 18px, #000 46px, #000 calc(100% - 46px), transparent calc(100% - 18px));
}
.dvai-tharr {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  display: inline-flex; align-items: center; justify-content: center;
  width: 20px; height: 20px; padding: 0; border: 1px solid var(--line); border-radius: 50%;
  background: var(--panel); color: var(--muted); cursor: pointer;
  opacity: 0; pointer-events: none;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .14);
  transition: opacity 130ms ease, background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.dvai-tharr .ic { width: 12px; height: 12px; }
.dvai-tharr.l { left: -2px; }
.dvai-tharr.r { right: -2px; }
.dvai-tharr:hover { background: var(--hover); color: var(--fg); border-color: var(--fg); }
.dvai-thrail.more-l .dvai-tharr.l, .dvai-thrail.more-r .dvai-tharr.r { opacity: 1; pointer-events: auto; }
/* 🎞 Перетаскивание чипа: поднятый чип и расступающиеся соседи. Пока идёт жест — ни
   подсветки под мышью, ни всплывающего «в архив»: они спорят с тем, что держит палец. */
.dvai-ths.dvth-reordering { cursor: grabbing; user-select: none; }
.dvai-ths.dvth-reordering .dvai-tharx { opacity: 0; pointer-events: none; }
.dvai-thw.dvth-dragging { z-index: 3; }
.dvai-thw.dvth-dragging .dvai-th {
  border-color: var(--primary); color: var(--fg);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .22); background: var(--panel);
}
/* Место, выбранное рукой, читается и без цвета: у чипа появляется точка-засечка снизу
   (канон `accent`: в строке списка точка, а не полоса). */
.dvai-thw.hand > .dvai-th { position: relative; }
.dvai-thw.hand > .dvai-th::after {
  content: ""; position: absolute; left: 50%; bottom: 1px; width: 4px; height: 2px;
  border-radius: 1px; background: var(--primary); opacity: .75; transform: translateX(-50%);
}
.dvai-thund {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; padding: 0; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--muted); cursor: pointer;
  transition: background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.dvai-thund .ic { width: 12px; height: 12px; }
.dvai-thund:hover { background: var(--hover); color: var(--fg); border-color: var(--fg); }
/* Тач: hover не существует — стрелки там лишние, лента и так листается пальцем. */
@media (hover: none) { .dvai-tharr { display: none; } }
.dvai-th {
  flex: 0 0 auto; max-width: 190px; display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 8px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--muted); font-size: 11.5px; cursor: pointer; white-space: nowrap;
  transition: background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.dvai-th:hover { background: var(--hover); color: var(--fg); }
.dvai-th.on { background: var(--hover); border-color: var(--fg); color: var(--fg); font-weight: 600; }
/* ── 🔴🔴 СРЕД-44 · «В АРХИВ» НА ЧИПЕ РАЗГОВОРА (владелец: «чтобы не мозолили глаза») ──────
   Обёртка нужна ровно затем, чтобы кнопок было ДВЕ (открыть · убрать), а не кнопка внутри
   кнопки: у вложенного интерактива нет ни фокуса, ни честного click. Место под значок
   зарезервировано ВСЕГДА (padding-right у чипа), поэтому лента не дёргается при наведении —
   всплывает только сам значок (канон `progressive-disclosure`). На тач-экране hover не
   существует: там значок виден всегда, иначе действия нет вовсе. */
.dvai-thw { position: relative; flex: 0 0 auto; display: inline-flex; align-items: center; min-width: 0; }
.dvai-thw .dvai-th { padding-right: 21px; }
.dvai-tharx {
  position: absolute; right: 2px; top: 50%; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; padding: 0; border: 0; border-radius: 6px;
  background: transparent; color: var(--muted); cursor: pointer;
  opacity: 0; pointer-events: none; transition: opacity 120ms ease, background 120ms ease, color 120ms ease;
}
.dvai-tharx .ic { width: 12px; height: 12px; }
.dvai-thw:hover .dvai-tharx, .dvai-thw:focus-within .dvai-tharx { opacity: 1; pointer-events: auto; }
.dvai-tharx:hover { background: var(--panel-2); color: var(--fg); }
.dvai-tharx:focus-visible { opacity: 1; pointer-events: auto; outline: 2px solid var(--primary); outline-offset: 1px; }
@media (hover: none) { .dvai-tharx { opacity: 1; pointer-events: auto; } }
/* ── 🔴🔴 CLIE-1193 · ОКНО НАСТРОЕК ЗВУКА ГОТОВНОСТИ (выключатель · громкость · 10 голосов) ──
   Поповер тот же, что у «Истории» (`.td-userpick`), — второго пикера в продукте не заводим.
   Ширина фиксированная: список голосов с пояснениями не должен «дышать» при перерисовке. */
.dvai-cuemenu { width: 306px; padding: 10px 10px 8px; overflow: auto; }
.dvai-cuehead { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 0 2px 2px; }
.dvai-cuettl { font-size: 13px; font-weight: 650; color: var(--fg); }
.dvai-cuesay { padding: 0 2px 8px; font-size: 11.5px; line-height: 1.35; color: var(--muted); }
.dvai-cuevol { display: flex; align-items: center; gap: 8px; padding: 2px 2px 10px; font-size: 12px; color: var(--muted); }
.dvai-cuevol > span { flex: 0 0 auto; }
.dvai-cuevol input[type="range"] { flex: 1 1 auto; min-width: 0; padding: 0; }
.dvai-cuevol > b { flex: 0 0 auto; min-width: 34px; text-align: right; font-size: 11.5px; color: var(--fg); font-variant-numeric: tabular-nums; }
.dvai-cuelist { display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--line); padding-top: 6px; }
.dvai-cuev {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 6px 8px;
  border: 1px solid transparent; border-radius: 9px; background: transparent; color: var(--fg);
  font-size: 12.5px; text-align: left; cursor: pointer;
}
.dvai-cuev:hover { background: var(--hover); }
.dvai-cuev.on { background: var(--hover); border-color: color-mix(in srgb, var(--primary) 42%, var(--line)); }
.dvai-cuevm { flex: 0 0 auto; display: inline-flex; width: 16px; justify-content: center; color: var(--muted); }
.dvai-cuev.on .dvai-cuevm { color: var(--primary-2, var(--primary)); }
.dvai-cuevm .ic { width: 12px; height: 12px; }
.dvai-cuevn { flex: 0 0 auto; font-weight: 600; }
.dvai-cuevs { flex: 1 1 auto; min-width: 0; font-style: normal; font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: right; }
.dvai-cuev:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
/* Выключатель звука готовности: включён — акцентными чернилами, выключен — приглушён. Состояние
   читается и значком (динамик ↔ динамик с крестом), не только цветом. */
.dvai-cue.on { color: var(--primary); }
.dvai-cue:not(.on) { color: var(--muted); }
.dvai-th-n { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
/* 🔴 CLIE-1585: счётчик «0/19» у темы среды — акцентные чернила на инсете (4.31:1). */
.dvai-th-pl { flex: 0 0 auto; font-style: normal; font-size: 10.5px; color: var(--primary-2, var(--accent)); font-weight: 600; }
/* Точка проекта — 6px (канон акцента: в строке списка точка, а не полоса). */
.dvai-th-pdot { flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%; }
/* 🔴 Метка проекта в режиме «Все проекты»: канон `accent` — акцент читается и в ч/б, поэтому
   проект назван СЛОВОМ, а цвет лишь подложкой (color-mix, как у акцент-пилюли). Чернила
   меряются к СВОЕЙ подложке (канон contrast-runtime-audit): на var(--hover) это var(--muted),
   у выбранного и под мышью — var(--fg). */
.dvai-th-pn {
  flex: 0 0 auto; max-width: 62px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-style: normal; font-size: 9.5px; font-weight: 700; letter-spacing: .02em;
  line-height: 14px; padding: 0 5px; border-radius: 5px; color: var(--muted);
  background: var(--hover); box-shadow: inset 0 0 0 1px var(--line);
}
.dvai-th.on .dvai-th-pn, .dvai-th:hover .dvai-th-pn { color: var(--fg); }
/* «Здесь Claude отвечает прямо сейчас» — то, ради чего лента и нужна. */
.dvai-th-live {
  flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%; background: var(--primary);
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 55%, transparent);
  animation: dvaiThPulse 1.6s infinite ease-out;
}
.dvai-th.live { border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
@keyframes dvaiThPulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 55%, transparent); }
  70% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--primary) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--primary) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) { .dvai-th-live { animation: none; } }
/* 🔴🔴 CLIE-1193 · «ОТВЕТ ГОТОВ, ВЫ ЕГО НЕ ЧИТАЛИ». Синяя точка = «пишет прямо сейчас», жёлтая
   = «дописал и ждёт вас». Цвет берём из ГРАФИЧЕСКОГО токена `--fill-warn` (он одинаков в обеих
   темах), а НЕ из `--warning`: в светлой теме тот затемнён под контраст ТЕКСТА (#9a6a00) и как
   заливка шестипиксельной точки читается грязно-оливковым — ровно то, о чём предупреждает
   комментарий у самих токенов. Точка НЕ пульсирует: пульс означает «идёт процесс», а здесь
   процесс уже кончился — она просто ждёт, сколько нужно, и гаснет по прочтению. */
.dvai-th-new {
  flex: 0 0 auto; width: 7px; height: 7px; border-radius: 50%; background: var(--fill-warn);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--fill-warn) 26%, transparent);
}
.dvai-th.unread { border-color: color-mix(in srgb, var(--fill-warn) 52%, var(--line)); }
/* Имя непрочитанной ветки — плотнее: в ленте из 16 чипов цвет точки решает не всё. */
.dvai-th.unread .dvai-th-n { color: var(--fg); font-weight: 600; }
.dvai-th-say { font-size: 11.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dvai-th-act {
  flex: 0 0 auto; height: 22px; padding: 0 8px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); color: var(--fg); font-size: 11.5px; cursor: pointer; white-space: nowrap;
}
.dvai-th-act:hover { background: var(--hover); border-color: var(--fg); }
/* Проект строки в «Истории», когда список сквозной по всем проектам. */
.dvai-histp { display: inline-flex; align-items: center; gap: 4px; font-size: 10.5px; color: var(--muted); }

/* Лента разговора (владелец 14.09.2026: «там должен быть чат для разработки, оставь прежний»).
   Это ВИД на «Чат с ИИ» задачи, поэтому пузыри — спокойные, без «мессенджерных» хвостиков:
   панель узкая, и важнее читаемость кода в ответе, чем декор. */
.dvai-msgs { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 12px 12px 16px; }
.dvai-msg { max-width: 100%; margin: 0 0 10px; }
.dvai-msg .dvai-mb {
  padding: 8px 11px; border-radius: 12px; font-size: 13px; line-height: 1.5;
  border: 1px solid var(--line); background: var(--panel-2); color: var(--fg);
  overflow-wrap: anywhere;
}
.dvai-msg.me { padding-left: 24px; }
.dvai-msg.me .dvai-mb {
  background: color-mix(in srgb, var(--primary) 12%, var(--panel-2));
  border-color: color-mix(in srgb, var(--primary) 26%, var(--line));
}
.dvai-msg.ai { padding-right: 12px; }
.dvai-msg .dvai-mb > :first-child { margin-top: 0; }
.dvai-msg .dvai-mb > :last-child { margin-bottom: 0; }
.dvai-msg .dvai-mb pre {
  margin: 8px 0; padding: 8px 10px; border-radius: 9px; overflow: auto;
  background: var(--panel); border: 1px solid var(--line); font-size: 12px;
}
.dvai-msg .dvai-mb code { font-size: 12px; }
.dvai-mmeta { margin: 3px 0 0 4px; font-size: 10.5px; color: var(--muted); }
.dvai-mf { display: flex; flex-wrap: wrap; gap: 6px; margin: 5px 0 0 4px; }
.dvai-msg.me .dvai-mf, .dvai-msg.me .dvai-mimgs { justify-content: flex-end; }
.dvai-mf a {
  display: inline-flex; align-items: center; gap: 4px; max-width: 200px; padding: 2px 7px;
  border: 1px solid var(--line); border-radius: 7px; font-size: 11.5px; color: var(--muted);
  text-decoration: none; overflow: hidden;
}
.dvai-mf a:hover { color: var(--fg); background: var(--hover); }
.dvai-mf a span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-mf .ic { width: 12px; height: 12px; flex: 0 0 auto; }
/* Картинка в реплике — миниатюрой (клик открывает оригинал), а не строкой «image.png». */
.dvai-mimgs { display: flex; flex-wrap: wrap; gap: 6px; margin: 5px 0 0; }
.dvai-mimg {
  display: block; width: 112px; height: 84px; border-radius: 10px; overflow: hidden;
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line);
}
.dvai-mimg img { display: block; width: 100%; height: 100%; object-fit: cover; }
.dvai-msg.pending .dvai-mb { display: flex; align-items: center; gap: 8px; color: var(--muted); }
/* Живой прогон Claude на компьютере: текст течёт в пузыре, ниже — «что делает» и «Остановить».
   Акцент — мягкое кольцо цветом темы, без левых реек (CLIE-483). */
.dvai-msg.live .dvai-mb { box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 10%, transparent); }
.dvai-live-wait { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); }
.dvai-live-foot { display: flex; align-items: center; gap: 8px; margin: 6px 0 0 4px; min-width: 0; }
.dvai-live-act {
  flex: 1 1 auto; min-width: 0; display: inline-flex; align-items: center; gap: 7px;
  font-size: 11.5px; color: var(--muted);
}
.dvai-live-act > span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-stop {
  flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); color: var(--fg);
  font-size: 12px; cursor: pointer; transition: background 130ms ease, border-color 130ms ease, color 130ms ease;
}
.dvai-stop:hover { color: var(--danger); background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 35%, transparent); }
.dvai-stop:disabled { opacity: .6; cursor: default; }
.dvai-stop .ic { width: 11px; height: 11px; }
/* Claude на компьютере не вошёл / не установлен — слова и выход «Выбрать другой ИИ». */
.dvai-runerr {
  margin: 0 0 10px; padding: 10px 12px; border-radius: 12px; font-size: 12.5px; line-height: 1.45;
  background: color-mix(in srgb, #f0a020 9%, var(--panel-2));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, #f0a020 30%, var(--line)); color: var(--fg);
}
.dvai-runerr p { margin: 0 0 8px; overflow-wrap: anywhere; }
.dvai-runerr-acts { display: flex; align-items: center; gap: 6px; }
/* Разговор закрыт владельцем (СРЕД-37) — слово и выход, а не пустая рама. */
.dvai-away { margin: auto; max-width: 360px; padding: 22px 18px; text-align: center; }
.dvai-away p { margin: 0 0 12px; font-size: 13px; line-height: 1.5; color: var(--muted); }
/* «ИИ печатает» — три точки, а не спиннер: спиннер обещает конец, а тут думает модель. */
.dvai-typing { display: inline-flex; gap: 3px; }
.dvai-typing i { width: 5px; height: 5px; border-radius: 50%; background: var(--muted); animation: dvaiTyping 1.1s infinite ease-in-out; }
.dvai-typing i:nth-child(2) { animation-delay: .15s; }
.dvai-typing i:nth-child(3) { animation-delay: .3s; }
@keyframes dvaiTyping { 0%, 60%, 100% { opacity: .25; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-2px); } }
/* 🔴 ПУСТОЙ ЧАТ НЕ ОТБИРАЕТ ЭКРАН (durable-правило «прогрессивное раскрытие», СРЕД-26/4).
   Подсказка прижата к КОМПОЗЕРУ (о нём и рассказывает) и собрана в карточку с хэйрлайн-
   кольцом, а не абзац во всю ширину посреди пустоты. Класс ставит `devAiChatPaint` только
   для состояния «разговора ещё нет». */
.dvai-msgs.dvai-msgs-empty { display: flex; flex-direction: column; justify-content: flex-end; }
.dvai-pad { padding: 14px 4px; }
/* Файлы, перетаскиваемые на панель: вся панель — зона сброса, подсветка кольцом. */
.dvai.drop-hot { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--primary) 55%, transparent); background: color-mix(in srgb, var(--primary) 5%, transparent); }
.dvai-hello {
  margin: 0 auto; max-width: 420px; padding: 16px 18px 15px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2);
}

/* Ход выполнения ветки: план-чек-лист «🤖 План ИИ» + текущий шаг. Никаких левых полосок —
   акцент несут точка статуса и слово (durable-правило CLIE-483). */
.dvai-plan { flex: 0 0 auto; }
.dvai-plan[hidden] { display: none; }
.dvai-planbox {
  margin: 10px 12px 0; padding: 9px 11px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--panel-2);
}
.dvai-planh { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dvai-plantitle {
  display: flex; align-items: center; gap: 7px; min-width: 0; flex: 1 1 auto;
  padding: 0; border: 0; background: transparent; color: inherit; cursor: pointer; text-align: left;
}
.dvai-plantitle:hover .dvai-title { text-decoration: underline; text-underline-offset: 2px; }
.dvai-planN {
  flex: 0 0 auto; font-size: 11px; font-weight: 600; color: var(--primary);
  padding: 1px 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}
.dvai-planx {
  flex: 0 0 auto; width: 22px; height: 22px; display: inline-flex; align-items: center;
  justify-content: center; padding: 0; border: 0; border-radius: 6px; background: transparent;
  color: var(--muted); cursor: pointer;
}
.dvai-planx:hover { background: var(--hover); color: var(--fg); }
.dvai-planx .ic { width: 13px; height: 13px; }
.dvai-planact { margin: 6px 0 0; font-size: 11.5px; color: var(--muted); line-height: 1.4; }
.dvai-planmeta { display: flex; align-items: center; gap: 8px; margin: 7px 0 0; min-width: 0; }
.dvai-planmeta .dvai-planact { margin: 0; flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-planmeta .dvai-src { max-width: 62%; }
.dvai-planerr { display: flex; align-items: center; gap: 8px; margin: 7px 0 0; font-size: 11.5px; color: var(--danger); }
.dvai-planbox .dvai-prog { margin: 8px 0 0; }
/* 🔴 План на 15–29 пунктов НЕ должен съедать разговор: список прокручивается сам, а шапка
   («План 9/15», текущий шаг, шкала) остаётся на виду. Без потолка панель превращалась в
   чек-лист с одной строкой переписки внизу. */
.dvai-todo {
  list-style: none; margin: 8px 0 0; padding: 0 2px 0 0; display: flex; flex-direction: column;
  gap: 3px; max-height: 232px; overflow: auto; overscroll-behavior: contain;
}
.dvai-td { display: flex; align-items: flex-start; gap: 7px; font-size: 12px; line-height: 1.4; color: var(--fg); }
.dvai-tdm {
  flex: 0 0 auto; width: 14px; height: 14px; margin-top: 1px; border-radius: 4px;
  border: 1px solid var(--line-strong); display: inline-flex; align-items: center; justify-content: center;
  color: #fff;
}
.dvai-tdm .ic { width: 10px; height: 10px; }
.dvai-td.done .dvai-tdm { background: var(--primary); border-color: var(--primary); }
.dvai-td.done .dvai-tdt { color: var(--muted); text-decoration: line-through; text-decoration-color: var(--line-strong); }
.dvai-td.now .dvai-tdm { border-color: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 14%, transparent); }
.dvai-td.now .dvai-tdt { font-weight: 600; }
.dvai-tdt { min-width: 0; }

/* История разговоров — тот же поповер, что у пикеров карточки (.td-userpick), только строки шире.
   🔴 ФОРМА СТРОКИ ПИШЕТСЯ ЧЕРЕЗ `.td-userpick.dvai-hist`, А НЕ ГОЛЫМ КЛАССОМ (СРЕД, 17.09.2026):
   базовое `.td-userpick button` (0,1,1) СИЛЬНЕЕ голого `.dvai-histrow` (0,1,0) и навязывало
   двустрочной строке `align-items: center` + `gap: 9px`. В колонке это значит «ширина по
   содержимому и по центру»: замер на проде 17.09 дал `.dvai-histl` 587px внутри строки 306px —
   заголовок и подпись уезжали за ОБА края поповера (scrollW 565 при clientW 318), у каждой
   строки свой отступ слева, многоточие не срабатывало вовсе. Форма у соседнего меню источника
   (`.dvai-srcmenu`) ровно та же и написана так же — второй вёрстки одной строки не заводим. */
.td-userpick.dvai-hist { width: 360px; max-width: 92vw; padding: 6px; }
.td-userpick.dvai-hist .dvai-histrow {
  display: flex; flex-direction: column; align-items: stretch; gap: 2px;
  width: 100%; min-width: 0; padding: 7px 9px;
  border: 0; border-radius: 9px; background: transparent; color: var(--fg);
  font: inherit; cursor: pointer; text-align: left;
}
.td-userpick.dvai-hist .dvai-histrow:hover { background: var(--hover); }

/* 🔴 CLIE-1480·Р3 · ВЫХОД ИЗ ОКНА («Показать ещё» + «Показано N из M»). Форма ОБЩАЯ — та же
   `.tasks-more`, что у столбика задач и списка бесед, своей не заводим. Но здесь снова бьёт
   та же грабля специфичности, что у `.dvai-histrow` выше: базовое `.td-userpick button`
   (0,1,1) сильнее голого `.tasks-more-btn` (0,1,0) и навязывает `width: 100%`. Замер на проде
   22.09: кнопка растягивалась на все 630px, а подпись «Показано 30 из 2060» переносилась
   строкой ниже и уходила ЗА нижний край тела (y 885 при дне 875) — цена окна снова была не
   видна. Возвращаем кнопке её собственную ширину, всё остальное берём у общей формы. */
.td-userpick.dvai-hist .tasks-more { padding: 12px 8px 14px; }
.td-userpick.dvai-hist .tasks-more-btn {
  width: auto; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
}
.td-userpick.dvai-hist .dvai-histl { display: flex; align-items: center; gap: 7px; min-width: 0; max-width: 100%; }
/* Гибкий в строке ровно один — заголовок; ключ, метка проекта, статус и счётчики не сжимаются
   в кашу, а заголовок получает многоточие. */
.td-userpick.dvai-hist .dvai-title { flex: 1 1 auto; }
.td-userpick.dvai-hist .dvai-histp { flex: 0 1 auto; min-width: 0; max-width: 38%; overflow: hidden; white-space: nowrap; }
.td-userpick.dvai-hist .dvai-hists { max-width: 100%; }
.dvai-hists {
  font-size: 11.5px; color: var(--muted); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; padding-left: 14px;
}
.dvai-histempty { padding: 18px 14px; font-size: 12.5px; color: var(--muted); text-align: center; }
/* 👥 0512 · разговоры коллег в «Истории» (только смотреть) и замок композера: писать нельзя —
   вместо поля причина словами и выход «Начать свой разговор» (одна дверь devAiComposerLock). */
.dvai-peers-h { margin-top: 6px; }
.dvai-hrow-peer .dvai-gtag svg { width: 12px; height: 12px; margin-right: 3px; vertical-align: -1px; }
.dvai-new.dvai-locked > :not(.dvai-lock) { display: none !important; }
.dvai-lock { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 10px 12px; border-radius: 12px;
  background: color-mix(in srgb, var(--primary) 8%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 20%, transparent); }
.dvai-lock p { margin: 0; flex: 1 1 240px; font-size: 13px; line-height: 1.45; color: var(--text); }

/* ── 🔴🔴 СРЕД-44 · АРХИВ РАЗГОВОРОВ: ВИД «Разговоры | Архив N» В ТОМ ЖЕ ОКНЕ ─────────────
   Вид переключает КАНОНИЧЕСКИЙ сегмент (`.cc-seg .cc-seg-sm`, канон `segment`) — своей дорожки
   с пилюлей здесь нет. Форма строки архива пишется через `.td-userpick.dvai-hist`, а не голым
   классом: базовое `.td-userpick button` (0,1,1) сильнее голого класса и навязало бы свою
   раскладку (та же грабля, что у `.dvai-histrow` 17.09). */
.td-userpick.dvai-hist .dvai-histhead { padding: 2px 3px 6px; border-bottom: 1px solid var(--line); margin-bottom: 4px; }
.td-userpick.dvai-hist .dvai-histseg { display: inline-flex; width: 100%; }
/* 🔴 ВХОД В АРХИВ ОБЯЗАН БЫТЬ ВИДЕН (замер на проде 17.09.2026, скриншот обеих тем): базовое
   `.td-userpick button` (0,1,1) навязывает кнопке `width: 100%` и левый текст — первая кнопка
   сегмента съедала всю дорожку, а «Архив N» уезжала ЗА КРАЙ поповера. Скриптом она кликалась,
   то есть гейт «видно ⇔ вызываемо» прошёл бы на грепе: невидимый вход = отсутствующий вход
   (канон feature-entry-must-be-clickable). Та же грабля специфичности, что у `.dvai-histrow`.
   Обе кнопки ДЕЛЯТ дорожку пополам и подписаны по центру, как в каноническом сегменте. */
.td-userpick.dvai-hist .dvai-histseg button {
  flex: 1 1 0; width: auto; min-width: 0; justify-content: center; text-align: center;
}
.td-userpick.dvai-hist .dvai-histbody { display: block; min-width: 0; }
.td-userpick.dvai-hist .dvai-histsay { padding: 2px 9px 6px; font-size: 11.5px; color: var(--muted); }
/* Строка архива — ДВА действия рядом: открыть (читать как есть) и «Вернуть» (завершение
   состояния). Кнопки настоящие и обе доступны с клавиатуры — вложенного интерактива нет. */
.td-userpick.dvai-hist .dvai-archrow { flex-direction: row; align-items: center; gap: 6px; padding: 4px 6px; }
.td-userpick.dvai-hist .dvai-archgo {
  display: flex; flex-direction: column; align-items: stretch; gap: 2px; flex: 1 1 auto;
  min-width: 0; padding: 4px 3px; border: 0; border-radius: 8px; background: transparent;
  color: var(--fg); font: inherit; cursor: pointer; text-align: left;
}
.td-userpick.dvai-hist .dvai-archgo:hover { background: var(--hover); }
.td-userpick.dvai-hist .dvai-archback { flex: 0 0 auto; width: auto; }

/* ── 🗂🔴 CLIE-1480 · ШИРОКОЕ ОКНО «ИСТОРИИ»: МОИ ГРУППЫ СЛЕВА, СПИСОК СПРАВА ──────────
   Владелец 22.09.2026 выбрал вариант B: «широкое окно 880px: слева ваши группы, справа
   список». Замер ДО правки (прод, `tools/shots/clie1480-hist-width.js`): окно 360px, названию
   доставалось 236px из 346, обрезано 16 названий из 25, а СЛЕВА пустовал 1023px из 1440.
   🔴 Форма пишется через `.td-userpick.dvai-hist`, а НЕ голыми классами: базовое
   `.td-userpick button` (0,1,1) сильнее голого класса и навяжет кнопке рельса свою раскладку
   (`width:100%`, `align-items:center`, `gap:9px`) — ровно та грабля, что ловили 17.09.
   Прокрутка живёт у рельса и у списка ПОРОЗНЬ: иначе рельс уезжал бы вверх вместе со списком
   и цель переноса пропадала бы из-под курсора. */
.td-userpick.dvai-hist.dvai-hist-wide {
  width: 880px; max-width: 96vw; padding: 6px;
  display: flex; flex-direction: column; overflow: hidden;
}
.td-userpick.dvai-hist .dvai-histwide { display: flex; align-items: stretch; gap: 8px; flex: 1 1 auto; min-height: 0; }
.td-userpick.dvai-hist .dvai-grail {
  flex: 0 0 212px; display: flex; flex-direction: column; gap: 2px; min-height: 0;
  padding-right: 8px; border-right: 1px solid var(--line); overflow-y: auto;
}
/* В архиве рельса нет: убранный разговор в группе не лежит, и пустой рельс отобрал бы пол-окна. */
.td-userpick.dvai-hist .dvai-histwide-solo .dvai-grail { display: none; }
.td-userpick.dvai-hist.dvai-hist-wide .dvai-histbody { flex: 1 1 auto; min-width: 0; overflow-y: auto; }

/* Строка рельса: цветная плитка · имя · счётчик; у моей группы ещё хваталка и «⋯». */
.td-userpick.dvai-hist .dvai-grow {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 7px 9px; border: 0; border-radius: 8px; background: transparent;
  color: var(--text); font: inherit; font-size: 12.5px; text-align: left; cursor: pointer;
}
.td-userpick.dvai-hist .dvai-grow:hover { background: var(--hover); }
.td-userpick.dvai-hist .dvai-grow.on { background: color-mix(in srgb, var(--primary) 16%, transparent); font-weight: 600; }
.td-userpick.dvai-hist .dvai-gchip { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 3px; }
.td-userpick.dvai-hist .dvai-gnm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-userpick.dvai-hist .dvai-gct { flex: 0 0 auto; font-size: 11px; color: var(--muted); }
.td-userpick.dvai-hist .dvai-grow.on .dvai-gct { color: var(--text); }
.td-userpick.dvai-hist .dvai-ggrip,
.td-userpick.dvai-hist .dvai-hgrip {
  flex: 0 0 auto; opacity: .32; letter-spacing: -2px; font-size: 13px; line-height: 1;
  cursor: grab; touch-action: none; user-select: none;
}
.td-userpick.dvai-hist .dvai-grow:hover .dvai-ggrip,
.td-userpick.dvai-hist .dvai-hrow:hover .dvai-hgrip { opacity: .65; }
.td-userpick.dvai-hist .dvai-gmore { flex: 0 0 auto; opacity: 0; font-size: 13px; color: var(--muted); padding: 0 3px; border-radius: 5px; }
.td-userpick.dvai-hist .dvai-grow:hover .dvai-gmore,
.td-userpick.dvai-hist .dvai-grow.on .dvai-gmore { opacity: .75; }
.td-userpick.dvai-hist .dvai-gmore:hover { opacity: 1; background: var(--hover); }
.td-userpick.dvai-hist .dvai-gsec { padding: 11px 9px 4px; font-size: 10px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.td-userpick.dvai-hist .dvai-gnew {
  display: flex; align-items: center; gap: 7px; width: 100%; margin-top: 4px;
  padding: 7px 9px; border: 1px dashed var(--line-strong); border-radius: 8px;
  background: transparent; color: var(--muted); font: inherit; font-size: 12px; cursor: pointer;
}
.td-userpick.dvai-hist .dvai-gnew:hover { color: var(--text); border-color: var(--primary); background: transparent; }
/* 🔴 ЦЕЛЬ ПЕРЕНОСА ГОВОРИТ, ЧТО ПРИМЕТ: заливка И кольцо — одного цвета мало (ч/б, дальтонизм). */
.td-userpick.dvai-hist .dvai-grow.drop {
  background: color-mix(in srgb, var(--ok) 18%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 55%, transparent);
}
.td-userpick.dvai-hist .dvai-grow.drop .dvai-gct { color: var(--ok); font-weight: 700; }
.td-userpick.dvai-hist .dvai-greorder .dvai-grow { cursor: grabbing; }

/* Правка группы — ВНУТРИ рельса (вложенный поповер закрыл бы «Историю» первым же кликом). */
.td-userpick.dvai-hist .dvai-gedit {
  display: flex; flex-direction: column; gap: 7px; padding: 8px; margin: 2px 0;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel);
}
.td-userpick.dvai-hist .dvai-gin {
  width: 100%; padding: 6px 8px; border: 1px solid var(--line-strong); border-radius: 7px;
  background: var(--bg); color: var(--text); font: inherit; font-size: 12.5px;
}
.td-userpick.dvai-hist .dvai-gin:focus { outline: none; border-color: var(--primary); }
.td-userpick.dvai-hist .dvai-gpal { display: flex; flex-wrap: wrap; gap: 5px; }
.td-userpick.dvai-hist .dvai-gsw {
  width: 18px; height: 18px; min-width: 0; padding: 0; border-radius: 6px;
  border: 1px solid rgba(0,0,0,.12); cursor: pointer;
}
.td-userpick.dvai-hist .dvai-gsw.on { box-shadow: 0 0 0 2px var(--panel), 0 0 0 3.5px var(--primary); }
.td-userpick.dvai-hist .dvai-gacts { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.td-userpick.dvai-hist .dvai-gacts button { width: auto; flex: 0 0 auto; }
.td-userpick.dvai-hist .dvai-gsp { flex: 1 1 auto; }
.td-userpick.dvai-hist .dvai-gsay { flex: 1 1 100%; font-size: 11px; line-height: 1.35; color: var(--muted); }
.td-userpick.dvai-hist .dvai-gdel { color: var(--danger); }

/* ── СТРОКА СПИСКА НОВОГО ОБРАЗЦА ────────────────────────────────────────────────── */
.td-userpick.dvai-hist .dvai-hrow { display: flex; align-items: flex-start; gap: 3px; min-width: 0; border-radius: 9px; }
.td-userpick.dvai-hist .dvai-hrow .dvai-hgrip { margin-top: 11px; padding: 0 2px; }
.td-userpick.dvai-hist .dvai-hrow .dvai-histrow { flex: 1 1 auto; min-width: 0; }
.td-userpick.dvai-hist .dvai-htop { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
.td-userpick.dvai-hist .dvai-htop .dvai-dot { margin-top: 5px; }
/* 🔴 РАДИ ЭТОГО ВСЁ И ЗАТЕВАЛОСЬ: название занимает ВСЮ ширину строки и при нужде вторую
   строку, а не стоит в очереди за ключом и перед «Отвечает» со счётчиками. */
.td-userpick.dvai-hist .dvai-hrow .dvai-title {
  flex: 1 1 auto; min-width: 0; font-size: 13.5px; font-weight: 550; line-height: 1.32;
  white-space: normal; overflow: hidden; text-overflow: clip;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.td-userpick.dvai-hist .dvai-hmeta {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap; min-width: 0;
  padding-left: 15px; font-size: 11px; color: var(--muted);
}
.td-userpick.dvai-hist .dvai-hsep { flex: 0 0 auto; opacity: .5; }
.td-userpick.dvai-hist .dvai-gtag { display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto; }
.td-userpick.dvai-hist .dvai-hrow .dvai-hists { padding-left: 15px; }
.td-userpick.dvai-hist .dvai-hrow.dvai-hdrag { opacity: .45; }
.td-userpick.dvai-hist .dvai-hrow.dvai-hlift { background: var(--panel); box-shadow: 0 14px 32px rgba(0,0,0,.4); }

/* Строка композера: чип модели виден ВСЕГДА (его отсутствие и было жалобой), кнопки —
   по набору текста (прогрессивное раскрытие оставляем). */
.dvai-bar { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dvai-model, .dvai-src {
  display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto; max-width: 55%;
  padding: 3px 8px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--panel-2); color: var(--fg); font-size: 11.5px; cursor: pointer;
  transition: background 130ms ease, border-color 130ms ease;
}
.dvai-model:hover, .dvai-src:hover { background: var(--hover); border-color: var(--line-strong); }
.dvai-model > span, .dvai-src > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-model .ic, .dvai-src .ic { width: 12px; height: 12px; flex: 0 0 auto; color: var(--muted); }
.dvai-model .ic:last-child, .dvai-src .ic:last-child { margin-left: -1px; }
/* 📚 0515 · Чип-переключатель ряда («Знания ClientsChat») — тот же `.dvai-model`. Включено —
   акцентная подложка и кольцо (канон акцента: не рейка), чернила акцентные, а состояние
   читается ещё и галочкой — не только цветом. */
.dvai-model.on {
  color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 12%, var(--panel-2));
  border-color: color-mix(in srgb, var(--primary) 44%, var(--line));
}
.dvai-model.on:hover {
  background: color-mix(in srgb, var(--primary) 18%, var(--panel-2));
  border-color: color-mix(in srgb, var(--primary) 56%, var(--line));
}
.dvai-model.on .ic { color: currentColor; }
/* 📚 0515 · ТЕСНЫЙ РЯД КОМПОЗЕРА. Чип «Знания» добавил ряду ~90 px, а ряд и без него не влезал при
   набранном тексте (замер Chrome, панель 320–520 px: «Отправить ИИ» вылезала на 11–115 px).
   Кто уступает (канон label-fit: подпись не печатаем за край, уступает то, что умеет «…»):
   1) подпись «Чей ИИ» — единственная с многоточием — ужимается первой, до точки, «…» и стрелки;
   2) набран текст, а ряд всё ещё тесен — подпись «Знания» уходит в подсказку, на чипе остаются
      книга и галочка: состояние читается и без слова;
   3) совсем тесно — ряд переносится (как `Wrap` у приложения): чипы и «Отправить ИИ» строкой ниже.
   Пороги — ширина `.dvai-bar` с запасом ~8 px на разницу шрифтов платформ. Замер с лестницей:
   за край не выходит ничего ни в покое, ни при наборе, на всех ширинах панели (320–560). */
.dvai-bar { container: dvaibar / inline-size; }
/* Ряд композера — ОДИН размерный класс (канон control-size): микрофон и скрепка были 26 px
   (.dvai-clip), чипы «Чей ИИ» / модель / «Знания» — 23 px (padding 3px при кегле 11.5; кадр:
   y 854–879 против 856–878), «Отправить ИИ» — 30 px. Высоту задаёт токен ряда, 30 = самая
   высокая кнопка ряда; радиус и кегль — прежние 8 и 11.5. */
.dvai-bar { --ctl-h: 30px; --ctl-r: 8px; --ctl-fs: 11.5px; }
.dvai-bar .dvai-clip { width: var(--ctl-h); height: var(--ctl-h); border-radius: var(--ctl-r); }
.dvai-bar :is(.dvai-model, .dvai-src) { height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs); }
.dvai-bar .dvai-acts .v2prev-primary { min-height: var(--ctl-h); }
.dvai-barmain .dvai-src { flex-shrink: 1; min-width: 56px; }
/* Общее `.dvai-acts { margin-top: 10px }` — для действий карточки работы; в ряду композера оно
   опускало «Отправить ИИ» на 5 px ниже чипов, а в переносе раздвигало бы строки. */
.dvai-barmain > .dvai-acts { margin-top: 0; }
/* Пороги лестницы +8 px: квадраты микрофона и скрепки выросли 26 → 30 (2 × 4 px к ширине ряда). */
@container dvaibar (min-width: 409px) and (max-width: 456px) {
  .dvai-barmain:has(> .dvai-acts:not([hidden])) .dvai-kb > span { display: none; }
}
@container dvaibar (max-width: 408px) {
  .dvai-barmain:has(> .dvai-acts:not([hidden])) { flex-wrap: wrap; row-gap: 6px; }
  .dvai-barmain:has(> .dvai-acts:not([hidden])) > .dvai-acts { margin-left: auto; }
}
/* Панель у своего минимума (320 px; ряд 324 = 316 + 8 за квадраты 30 px): подпись «Знания» уходит в подсказку и в покое. */
@container dvaibar (max-width: 324px) { .dvai-kb > span { display: none; } }
/* 🤝 «Чей ИИ»: ИИ не выбран вовсе — чип просит внимания подложкой и кольцом (не рейкой). */
.dvai-src { max-width: 48%; }
.dvai-src.warn {
  color: #b86e00; background: color-mix(in srgb, #f0a020 12%, var(--panel-2));
  border-color: color-mix(in srgb, #f0a020 40%, var(--line));
}
:root:not([data-theme="light"]) .dvai-src.warn { color: #f3b04a; }
.dvai-srcdot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; background: var(--muted); }
.dvai-srcdot.on { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-soft); }
.dvai-srcdot.wait { background: #f0a020; }
/* Меню источника — тот же поповер, что у «Истории» (.td-userpick), свои только строки. */
.td-userpick.dvai-srcmenu { width: 300px; padding: 6px; }
.td-userpick.dvai-srcmenu .dvai-srow { display: flex; align-items: center; gap: 2px; border-radius: 9px; }
.td-userpick.dvai-srcmenu .dvai-srow:hover { background: var(--hover); }
.td-userpick.dvai-srcmenu .dvai-srowb {
  flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; align-items: stretch; gap: 2px;
  width: auto; padding: 7px 9px; border: 0; border-radius: 9px; background: transparent;
  color: var(--fg); font: inherit; text-align: left; cursor: pointer;
}
.td-userpick.dvai-srcmenu .dvai-srowb.static { cursor: default; }
/* Подсветку даёт СТРОКА целиком (кнопка + «подробнее» рядом) — у кнопки своя заливка не нужна. */
.td-userpick.dvai-srcmenu .dvai-srowb:hover { background: transparent; }
.dvai-srowt { display: flex; align-items: center; gap: 7px; min-width: 0; font-size: 13px; font-weight: 550; }
.dvai-srowt > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-srowt .ic { width: 13px; height: 13px; flex: 0 0 auto; margin-left: auto; color: var(--primary); }
.dvai-srows { padding-left: 14px; font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.td-userpick.dvai-srcmenu .dvai-srowx {
  flex: 0 0 auto; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: 7px; background: transparent; color: var(--muted); cursor: pointer;
}
.td-userpick.dvai-srcmenu .dvai-srowx:hover { background: var(--panel-2); color: var(--fg); }
.dvai-srowx .ic { width: 14px; height: 14px; }
.td-userpick.dvai-srcmenu .dvai-srowc {
  flex: 0 0 auto; width: auto; margin-right: 6px; padding: 3px 10px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--panel-2); color: var(--fg); font-size: 11.5px; cursor: pointer;
}
.td-userpick.dvai-srcmenu .dvai-srowc:hover { border-color: var(--line-strong); }
.dvai-ssep { height: 1px; margin: 5px 6px; background: var(--line); }
.td-userpick.dvai-srcmenu .dvai-sact {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 9px; border: 0; border-radius: 9px;
  background: transparent; color: var(--primary); font-size: 12.5px; font-weight: 550; text-align: left; cursor: pointer;
}
.td-userpick.dvai-srcmenu .dvai-sact:hover { background: var(--hover); }
.dvai-sact .ic { width: 14px; height: 14px; flex: 0 0 auto; }

/* ── 🔴 СРЕД-26/2 · КОМПОЗЕР «ЗАДАЧА ДЛЯ ИИ» ─────────────────────────────────────
   Ответ на «непонятно как работать с ИИ в этой среде, где интерфейс?»: поле стоит
   ПЕРВЫМ в панели, над списком работ. Кнопки всплывают только когда есть что
   отправлять — пустая панель остаётся спокойной (прогрессивное раскрытие). */
/* СРЕД-26/3: композер переехал ВНИЗ панели (там его ждут в любом чате) — значит и шов сверху. */
.dvai-new {
  flex: 0 0 auto; display: flex; flex-direction: column; gap: 8px;
  padding: 10px 14px 12px; border-top: 1px solid var(--line); background: var(--panel);
}
.dvai-newh { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.dvai-newhint {
  font-size: 11px; color: var(--muted); min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.dvai-ctx { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.dvai-chip {
  display: inline-flex; align-items: center; gap: 4px; max-width: 220px; padding: 2px 4px 2px 7px;
  border: 1px solid var(--line); border-radius: 7px; background: var(--panel-2);
  font-size: 11.5px; color: var(--fg);
}
.dvai-chip.auto { border-style: dashed; color: var(--muted); padding-right: 7px; }
.dvai-chip .ic { width: 12px; height: 12px; flex: 0 0 auto; color: var(--muted); }
.dvai-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-chip-x {
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  width: 16px; height: 16px; padding: 0; border: 0; border-radius: 5px;
  background: transparent; color: var(--muted); cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.dvai-chip-x:hover { background: var(--hover); color: var(--fg); }
.dvai-chip-x .ic { width: 11px; height: 11px; }
.dvai-add {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px;
  border: 1px dashed var(--line-strong); border-radius: 7px; background: transparent;
  color: var(--muted); font-size: 11.5px; cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.dvai-add:hover { background: var(--hover); color: var(--fg); border-color: var(--muted); }
.dvai-add .ic { width: 12px; height: 12px; }
.dvai-clr {
  margin-left: auto; border: 0; background: transparent; color: var(--muted);
  font-size: 11.5px; cursor: pointer; padding: 2px 4px; border-radius: 6px;
}
.dvai-clr:hover { background: var(--hover); color: var(--fg); }
/* 📎 Вложения композера: чип = миниатюра/значок · имя · доля загрузки · «×». Ошибка — словами
   и цветом токена, с «Повторить». */
.dvai-att { display: flex; flex-wrap: wrap; gap: 6px; }
.dvai-att[hidden] { display: none; }
.dvai-att-i {
  position: relative; display: inline-flex; align-items: center; gap: 6px; max-width: 240px;
  padding: 3px 4px 3px 4px; border: 1px solid var(--line); border-radius: 9px; background: var(--panel-2);
  font-size: 11.5px; color: var(--fg); overflow: hidden;
}
.dvai-att-i > .ic { width: 13px; height: 13px; flex: 0 0 auto; margin-left: 3px; color: var(--muted); }
.dvai-att-th { width: 26px; height: 26px; flex: 0 0 auto; border-radius: 6px; object-fit: cover; background: var(--panel); }
.dvai-att-n { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-att-pct { flex: 0 0 auto; font-size: 10.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.dvai-att-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 2px; background: transparent; }
.dvai-att-bar > b { display: block; height: 100%; background: var(--primary); transition: width 160ms ease; }
.dvai-att-i.err { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); background: color-mix(in srgb, var(--danger) 8%, var(--panel-2)); }
.dvai-att-i.err .dvai-att-n { color: var(--danger); }
.dvai-att-re {
  flex: 0 0 auto; padding: 1px 7px; border: 1px solid var(--line); border-radius: 6px;
  background: var(--panel); color: var(--fg); font-size: 11px; cursor: pointer;
}
.dvai-att-re:hover { border-color: var(--line-strong); }
/* 🖍 «Нарисовать» и «Вернуть оригинал» на чипе вложения: та же посадка, что у «×» рядом —
   один размерный класс на ряд действий чипа, иначе ряд читается как собранный не человеком. */
.dvai-att-ed {
  flex: 0 0 auto; width: 18px; height: 18px; display: inline-flex; align-items: center; justify-content: center;
  padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer;
  transition: background 130ms ease, color 130ms ease;
}
.dvai-att-ed:hover { background: var(--hover); color: var(--fg); }
.dvai-att-ed.busy { opacity: .55; cursor: default; }
.dvai-att-ed .ic { width: 11px; height: 11px; }
.dvai-clip {
  flex: 0 0 auto; width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  padding: 0; border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2); color: var(--muted);
  cursor: pointer; transition: background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.dvai-clip:hover { background: var(--hover); color: var(--fg); border-color: var(--line-strong); }
.dvai-clip .ic { width: 14px; height: 14px; }
/* Окно «Подключить компьютер» из отказа чата ИИ — та же карточка подключения, что в «Превью». */
.dvai-conn-say { margin: 0 0 10px; }
.dvai-conn .v2prev-empty { padding: 0; min-height: 0; }
/* 🔴 КРАЙ ПОЛЯ ВВОДА ИИ СРЕДЫ: потянуть — изменить высоту, двойной клик — автоподбор.
   Полоса-ручка широкая и с запасом по вертикали (канон `tap-target`: целиться в 2 px нельзя),
   а в раскладке места почти не занимает — отрицательные поля съедают свой же зазор. */
.dvai-qgrip {
  flex: 0 0 auto; height: 14px; margin: -5px 0 -7px; cursor: ns-resize; touch-action: none;
  display: flex; align-items: center; justify-content: center;
}
.dvai-qgrip::before {
  content: ""; width: 44px; height: 3px; border-radius: 3px; background: var(--line);
  transition: background 140ms ease, width 140ms ease;
}
.dvai-qgrip:hover::before { background: var(--muted); width: 56px; }
.dvai-qgrip.hot::before { background: var(--accent); width: 68px; }

.dvai-q {
  width: 100%; box-sizing: border-box; min-height: 76px; resize: none;
  padding: 9px 11px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel-2); color: var(--fg); font: inherit; font-size: 13px; line-height: 1.45;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.dvai-q:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--glow); }
.dvai-q::placeholder { color: var(--muted); }
.dvai-acts { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.dvai-acts[hidden] { display: none; }
.dvai-state { flex: 1 1 auto; min-width: 0; font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-acts .v2prev-primary { min-height: 30px; padding: 4px 14px; font-size: 13px; }
.dvai-acts .v2prev-btn:disabled, .dvai-acts .v2prev-primary:disabled { opacity: .55; cursor: default; }

/* ── 🎙️⌨ ЧАТ ИИ В СРЕДЕ: всё полезное из чата — ТЕМИ ЖЕ дверями (диктовка `dict` с целью,
   раскладка `convertLayout(поле)`, формат FMT_HOTKEYS, жест удержания голосового). Здесь только
   посадка в узкую панель: пустое поле = 🎤 · 📎 · поле, остальное — по делу. */
.dvai-barmain { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 0; }
.dvai-barmain.hidden { display: none; }
.dvai-mic { position: relative; touch-action: none; user-select: none; -webkit-user-select: none; }
.dvai-mic.on { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, var(--line)); }
.dvai-mic.recording { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, var(--panel-2)); }
.dvai-mic.busy::after { inset: 2px; }
/* Плашка раскладки — та же `.layout-suggest`, только островом внутри композера (не полосой). */
.dvai-new .dvai-lay {
  padding: 6px 10px; border: 1px solid color-mix(in srgb, var(--primary) 26%, var(--line));
  border-radius: 9px;
}
.dvai-new .dvai-lay .ls-preview { font-size: 13px; }
/* Строка «ИИ работает над текстом» и панель результата диктовки — те же классы, что у чата. */
.dvai-new .dict-proc, .dvai-new .dict-panel {
  padding: 6px 10px; border: 1px solid var(--line); border-radius: 9px;
}
/* Полоса записи встаёт В РЯД вместо инструментов композера (микрофон остаётся под пальцем). */
.dvai-dictbar {
  flex: 1 1 auto; min-width: 0; gap: 8px; padding: 0; border-top: 0;
  --rl-t: 0; --rc-t: 0;
}
.dvai-dictbar .rec-timer { font-size: 12px; font-variant-numeric: tabular-nums; }
.dvai-dictbar .rec-hint { font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-dictbar .l-voice { display: none; }
.dvai-dictbar.voice .l-voice { display: inline; }
.dvai-dictbar.voice .l-dict { display: none; }
.dvai-dictx {
  position: relative; overflow: hidden; flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 4px; height: 26px; padding: 0 9px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--panel-2);
  color: var(--fg); font-size: 12px; cursor: pointer;
  transition: background 130ms ease, color 130ms ease, border-color 130ms ease;
}
.dvai-dictx:hover { background: var(--hover); border-color: var(--line-strong); }
.dvai-dictx .ic { width: 13px; height: 13px; flex: 0 0 auto; }
/* Живая доля пути до ОТМЕНЫ (← влево): заливка «Удалить» растёт вместе с пальцем. */
.dvai-dictx::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: color-mix(in srgb, var(--danger) 22%, transparent);
  transform-origin: right center; transform: scaleX(var(--rc-t));
}
.dvai-dictbar.cancel .dvai-dictx { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); }
/* Живая доля пути до ЗАМКА (↑ вверх): видна только пока держат. */
.dvai-dictlock {
  display: none; position: relative; overflow: hidden; flex: 0 0 auto; align-items: center; gap: 3px;
  height: 22px; padding: 0 8px; border: 1px dashed var(--line-strong); border-radius: 11px;
  font-size: 11px; color: var(--muted);
}
.dvai-dictbar.voice:not(.locked) .dvai-dictlock { display: inline-flex; }
.dvai-dictlock::before {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; pointer-events: none;
  height: 100%; transform-origin: bottom center; transform: scaleY(var(--rl-t));
  background: color-mix(in srgb, var(--primary) 20%, transparent);
}
.dvai-dictlock > * { position: relative; }
.dvai-dictlock .ic { width: 11px; height: 11px; }
.dvai-dictbar.lock-hot .dvai-dictlock { color: var(--primary); border-style: solid; border-color: var(--primary); }
.dvai-dictok { flex: 0 0 auto; min-height: 26px; padding: 3px 12px; font-size: 12.5px; }
/* Голос ушёл — сырая речь рядом: «Как сказал» кладёт её в поле. */
.dvai-vnote { display: flex; align-items: center; gap: 8px; min-width: 0; font-size: 11.5px; color: var(--muted); }
.dvai-vnote[hidden] { display: none; }
.dvai-vnote > .ic { width: 13px; height: 13px; flex: 0 0 auto; }
.dvai-vnote-t { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-vnote [data-vn-raw] {
  flex: 0 0 auto; padding: 2px 9px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--panel-2); color: var(--fg); font-size: 11.5px; cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.dvai-vnote [data-vn-raw]:hover { background: var(--hover); border-color: var(--line-strong); }
/* Действия у реплики: плавающая пилюля над пузырём по наведению; на тач-экране — строкой. */
.dvai-msg { position: relative; }
.dvai-mact {
  position: absolute; top: -12px; right: 8px; z-index: 1;
  display: flex; align-items: center; gap: 1px; padding: 2px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel);
  box-shadow: 0 2px 10px rgba(0, 0, 0, .12);
  opacity: 0; visibility: hidden; transition: opacity 130ms ease, visibility 130ms ease;
}
.dvai-msg.ai .dvai-mact { right: 20px; }
.dvai-msg:hover > .dvai-mact, .dvai-mact:focus-within { opacity: 1; visibility: visible; }
.dvai-mact button {
  display: inline-flex; align-items: center; gap: 4px; height: 22px; padding: 0 7px;
  border: 0; border-radius: 7px; background: transparent; color: var(--muted);
  font-size: 11px; white-space: nowrap; cursor: pointer;
  transition: background 120ms ease, color 120ms ease;
}
.dvai-mact button:hover { background: var(--hover); color: var(--fg); }
.dvai-mact .ic { width: 12px; height: 12px; flex: 0 0 auto; }
@media (hover: none) {
  .dvai-mact { position: static; opacity: 1; visibility: visible; box-shadow: none; border: 0; background: transparent; padding: 0; margin: 0 0 3px; }
  .dvai-msg.me .dvai-mact { justify-content: flex-end; }
}
/* «Скопировать код» у блока кода в ответе — по наведению на блок. */
.dvai-msg .dvai-mb pre { position: relative; }
.dvai-codecp {
  position: absolute; top: 5px; right: 5px; width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center; padding: 0;
  border: 1px solid var(--line); border-radius: 6px; background: var(--panel-2); color: var(--muted);
  cursor: pointer; opacity: 0; transition: opacity 130ms ease, background 120ms ease, color 120ms ease;
}
.dvai-mb pre:hover .dvai-codecp, .dvai-codecp:focus-visible { opacity: 1; }
.dvai-codecp:hover { background: var(--hover); color: var(--fg); }
.dvai-codecp .ic { width: 13px; height: 13px; }
@media (hover: none) { .dvai-codecp { opacity: 1; } }

/* Строка палитры, уже взятая в задачу ИИ (⌘P в режиме набора файлов). */
.dvs-pal-r.picked { background: color-mix(in srgb, var(--accent) 10%, transparent); }
.dvs-pal-r.picked::after {
  content: ""; margin-left: auto; flex: 0 0 auto; width: 5px; height: 9px;
  border: solid var(--accent); border-width: 0 2px 2px 0; transform: rotate(45deg) translateY(-1px);
}

/* Шапка панели — ДВЕ строки: сверху название и охват, ниже сводка. Одной строкой её собирать
   нельзя: сводка выросла до «в работе 13 · на приёмке 87 · показаны первые 100 из 318», сжимала
   заголовок, и «Работы ИИ» переносилось посреди слова. */
.dvai-head {
  display: flex; flex-direction: column; gap: 3px; padding: 9px 14px 10px; flex: 0 0 auto;
  border-bottom: 1px solid var(--line);
}
.dvai-headrow { display: flex; align-items: center; gap: 10px; }
.dvai-h1 { font-size: 13px; font-weight: 650; letter-spacing: .2px; white-space: nowrap; }
.dvai-sub { font-size: 11px; color: var(--muted); line-height: 1.35; }
/* Охват «Этот проект | Все» — тот же сегмент, что «Файлы | Изменения» слева (.dvs-seg),
   второго вида переключателя в среде не заводим. Прижат вправо, ужат по содержимому. */
/* CLIE-505: размер даёт канон (.cc-seg-sm), здесь — только место в шапке. */
.dvai-seg { margin: 0 0 0 auto; }
.dvai-seg > button { flex: 0 0 auto; }
/* Проект строки — виден только в охвате «Все» (в «этом проекте» он и так один и тот же). */
.dvai-proj { color: var(--muted); flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* СРЕД-31 · ЧЬЯ это работа в общем списке проекта. Акцент — слово и мягкая подложка. */
.dvai-who {
  flex: none; padding: 2px 7px; border-radius: 999px; font-size: 11px;
  color: var(--primary); background: color-mix(in srgb, var(--primary) 11%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 20%, transparent);
  max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dvai-list { flex: 1 1 auto; overflow: auto; padding: 6px 8px 14px; }
.dvai-group {
  padding: 12px 6px 6px; font-size: 11px; font-weight: 600; letter-spacing: .5px;
  text-transform: uppercase; color: var(--muted);
}
.dvai-row {
  display: block; padding: 8px 10px; border-radius: 10px; cursor: pointer;
  border: 1px solid transparent; transition: background 130ms ease, border-color 130ms ease;
}
.dvai-row:hover { background: var(--hover); }
.dvai-row.open { background: var(--hover); border-color: var(--line); cursor: default; }
.dvai-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dvai-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); flex: 0 0 auto; }
.dvai-dot.on { background: var(--ok); box-shadow: 0 0 0 3px var(--ok-soft); }
.dvai-dot.ok { background: var(--primary); box-shadow: 0 0 0 3px var(--sel, var(--cm-667eea-16, rgba(102,126,234,.16))); }
.dvai-dot.wait { background: #f0a020; }
.dvai-dot.err { background: var(--danger); }
.dvai-key {
  font-size: 11px; font-weight: 600; color: var(--muted); flex: 0 0 auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.dvai-title {
  font-size: 13px; font-weight: 550; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.dvai-time { margin-left: auto; font-size: 11px; color: var(--muted); flex: 0 0 auto; }
.dvai-meta {
  display: flex; align-items: center; gap: 8px; margin-top: 4px; padding-left: 15px;
  font-size: 11px; color: var(--muted); min-width: 0;
}
.dvai-st { font-weight: 600; flex: 0 0 auto; }
.dvai-st.on { color: var(--ok); }
.dvai-st.ok { color: var(--primary); }
.dvai-st.wait { color: #d9880c; }
.dvai-st.err { color: var(--danger); }
.dvai-act { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvai-files { margin-left: auto; flex: 0 0 auto; }
.dvai-prog {
  height: 3px; width: 140px; margin: 7px 0 1px 15px; border-radius: 2px;
  background: var(--line); overflow: hidden;
}
.dvai-prog i { display: block; height: 100%; background: var(--primary); border-radius: 2px; transition: width 300ms ease; }
.dvai-body { margin: 8px 0 2px; padding-left: 15px; }
/* Подсказка внутри раскрытой строки — обычная строка текста, а не центрированная заглушка. */
.dvai-body .dvs-hint { padding: 6px 8px; text-align: left; font-size: 12px; }
.dvai-fl { display: flex; flex-direction: column; gap: 2px; }
.dvai-file {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 5px 8px; border: 0;
  border-radius: 7px; background: transparent; color: var(--fg); font-size: 12px; text-align: left;
  cursor: pointer; transition: background 120ms ease;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.dvai-file:hover { background: var(--hover); }
.dvai-fst { width: 12px; text-align: center; font-weight: 700; flex: 0 0 auto; }
.dvai-fst.add { color: var(--ok); }
.dvai-fst.del { color: var(--danger); }
.dvai-fst.mod { color: var(--muted); }
.dvai-fp { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; direction: rtl; text-align: left; }
.dvai-fc {
  margin-left: auto; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--muted); font-size: 11px; font-family: inherit;
}
.dvai-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.dvai-acts .v2prev-primary, .dvai-acts .v2prev-btn { min-height: 28px; padding-block: 4px; white-space: nowrap; }
.dvai-empty { padding: 30px 18px; text-align: center; }
/* Единственное действие в состоянии ошибки — значит оно и должно читаться как действие:
   хэйрлайн-кнопка на этом фоне была почти невидима (замерено на стенде: --line против --panel). */
.dvai-retry { margin-top: 6px; }
.dvai-retry[disabled] { opacity: .55; cursor: default; }
.dvai-empty p { margin: 0 0 10px; font-size: 13px; line-height: 1.5; }
.dvai-empty .dvai-dim { color: var(--muted); font-size: 12px; }
.dvai-askbox { width: min(520px, 92vw); }

/* 🤝 ОКНО ВЫДАЧИ ТОКЕНОВ ИИ (aiGrantOpen) и окно запроса (aiLendRequest). Рама — канон
   `ccFormModal` (.pm-scrim/.pm-card), здесь только тело: кто · «зачем» · аккаунты · срок.
   Акцент — подложкой и кольцом, без рельс (CLIE-483); обе темы — только токены. */
.aig-who { display: flex; align-items: center; gap: 11px; margin: 2px 0 12px; }
.aig-whot { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.aig-whot b { font-size: 14px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aig-whot span { font-size: 12px; color: var(--muted); }
.aig-quote {
  margin: 0 0 12px; padding: 9px 12px; border-radius: 10px; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line); font-size: 13px; line-height: 1.45; color: var(--text);
  white-space: pre-wrap; overflow-wrap: anywhere;
}
.aig-sec { margin: 14px 0 7px; font-size: 12px; font-weight: 600; color: var(--muted); }
.aig-accs { display: flex; flex-wrap: wrap; gap: 7px; }
.aig-acc {
  position: relative; display: inline-flex; align-items: center; gap: 7px; padding: 6px 11px 6px 8px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); cursor: pointer;
  transition: border-color 140ms ease, background 140ms ease;
}
.aig-acc:hover { border-color: var(--line-strong); }
.aig-acc.on { border-color: color-mix(in srgb, var(--primary) 50%, var(--line)); background: color-mix(in srgb, var(--primary) 10%, var(--panel-2)); }
.aig-acc input { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.aig-acc:focus-within { box-shadow: 0 0 0 3px var(--glow); }
.aig-box {
  display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px;
  border: 1.5px solid var(--line-strong); border-radius: 5px; color: #fff;
  transition: background 140ms ease, border-color 140ms ease;
}
.aig-box .ic { width: 11px; height: 11px; opacity: 0; transition: opacity 120ms ease; }
.aig-acc.on .aig-box { background: var(--primary); border-color: var(--primary); }
.aig-acc.on .aig-box .ic { opacity: 1; }
.aig-accn { font-size: 12.5px; font-weight: 500; color: var(--text); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
/* Вид аккаунта в окне выдачи: «воркер» / «для Среды» — словом на мягкой подложке. */
.aig-acck {
  font-size: 11px; color: var(--muted); padding: 1px 6px; border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 12%, transparent);
}
/* 🔴 ОСТАТОК ТОКЕНОВ АККАУНТА (CLIE-1165, владелец 15.09.2026: «Не видно токены, как понять
   какой аккаунт дать?»). Числа и слово считает сервер (`AiWorkers.usage_by_name` → `say`,
   `runway_say`), здесь — только вид. Слово рядом со значком: «стена»/«тесно» читаются и в ч/б
   (канон accent), цвет — лишь усиление. */
.aig-accu {
  display: inline-flex; align-items: center; gap: 4px; margin-left: auto; white-space: nowrap;
  font-size: 11px; font-weight: 500; color: var(--muted); padding: 1px 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 18%, transparent);
}
.aig-accu .ic { width: 12px; height: 12px; flex: none; }
.aig-accu.none { opacity: .75; }
.aig-accu.tight {
  color: var(--warning); background: color-mix(in srgb, var(--warning) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 24%, transparent);
}
.aig-accu.spent {
  color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 24%, transparent);
}
/* 🔴 Чернила акцента НА ЕГО ЖЕ подложке в СВЕТЛОЙ теме: сам токен на своей 12 %-заливке даёт
   4.06:1 («тесно») и 4.28:1 («стена») — ниже WCAG AA (замер сторожа контраста приложения,
   16.09.2026). Тот же цвет на 15 % темнее — 5.25:1 / 5.54:1; тёмной теме темнить нечего. */
html[data-theme="light"] .aig-accu.tight { color: color-mix(in srgb, var(--warning) 85%, #000); }
html[data-theme="light"] .aig-accu.spent { color: color-mix(in srgb, var(--danger) 85%, #000); }
/* Колонка вместо ряда чипов: имя слева, остаток справа — ряд чипов остаток не вмещал. */
.aig-accs-l { flex-direction: column; gap: 6px; }
.aig-accs-l .aig-acc { width: 100%; box-sizing: border-box; flex-wrap: wrap; }
.aig-accs-l .aig-accn { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.ai-lend-row .aig-accu { flex: none; }
.aig-in {
  width: 100%; height: var(--ctl-h); box-sizing: border-box; padding: 0 11px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); color: var(--text);
  font: inherit; font-size: 13px; outline: none; transition: border-color 140ms ease, box-shadow 140ms ease;
}
.aig-in:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--glow); }
.aig-in::placeholder { color: var(--muted); }
.ai-lacc-tok { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
.ai-lacc-top { margin-top: 0; }
.ai-lacc-top code { font-size: 12px; padding: 1px 5px; border-radius: 5px; background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.ai-lacc-err { color: var(--danger); }
.aig-dur { display: flex; width: 100%; }
.aig-dur > button { flex: 1 1 0; }
.aig-hint { margin: 12px 0 0; font-size: 12px; line-height: 1.45; color: var(--muted); }
/* 🔴 Заёмщик обязан узнать о видимости его запросов ДО, а не случайно (0382): подсказка
   поднимается до уровня внимания — подложка + кольцо предупреждения, цвет лишь усиление. */
.aig-hint.aig-warn {
  padding: 8px 11px; border-radius: 9px; color: var(--text);
  background: color-mix(in srgb, var(--warning) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 26%, transparent);
}
/* 🧠 CLIE-1246 «в прошлый раз вы разрешали…»: ТА ЖЕ форма подсказки, другой токен — подставленное
   из памяти обязано быть видно, но это не предупреждение. Подложка 10 % + кольцо 26 % (канон
   `accent`), чернила — var(--text) к СВОЕЙ подложке (канон `contrast-runtime-audit`): в обеих
   темах читается, а не тонет серым по серому. */
.aig-hint.aig-prev {
  padding: 8px 11px; border-radius: 9px; color: var(--text);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent);
}
.aig-lab { display: block; margin: 14px 0 6px; font-size: 12px; font-weight: 600; color: var(--muted); }
.aig-note {
  width: 100%; box-sizing: border-box; min-height: 72px; resize: vertical; padding: 9px 11px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--panel-2); color: var(--text);
  font: inherit; font-size: 13px; line-height: 1.45; outline: none;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.aig-note:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--glow); }
.aig-note::placeholder { color: var(--muted); }
.aig-status {
  padding: 10px 12px; border-radius: 10px; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line); font-size: 13px; line-height: 1.45; color: var(--text);
}
.aig-status.aig-st-active { background: color-mix(in srgb, var(--ok) 10%, var(--panel-2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 28%, var(--line)); }
.aig-status.aig-st-pending { background: color-mix(in srgb, #f0a020 10%, var(--panel-2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, #f0a020 30%, var(--line)); }
.aig-pick .up-hint { max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 💸 РАСХОД ОДОЛЖЕННЫХ ТОКЕНОВ И ИСТОРИЯ ЗАПРОСОВ (0381, владелец 16.09.2026: «добавь тут
   информацию по расходам ИИ на задачи того, с кем поделился. И отдельно историю его запросов»).
   Все числа и подписи приходят строками с сервера (`AiLendUsage`) — здесь только вид.
   🔴 Обе темы держатся НА ТОКЕНАХ (--panel-2/--line/--muted/--text): своих hex-цветов нет, иначе
   светлая тема получит тёмный блок (канон contrast-runtime-audit). */
.aiu { margin: 14px 0 2px; }
.aiu[hidden] { display: none; }
.aiu-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.aiu-ttl { margin: 0; flex: 1 1 auto; }
.aiu-head .aiu-per { flex: 0 0 auto; }
.aiu-load { opacity: .55; transition: opacity 120ms ease; }
.aiu-body { margin-top: 8px; }
/* Крупные цифры — четыре ответа на «сколько»: токены · запросы · ходы · задачи. Ходы стоят рядом
   с запросами НАМЕРЕННО: один вопрос человека — это десятки обращений к модели (0367). */
.aiu-tot {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 8px;
  padding: 10px 12px; border-radius: 10px; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
.aiu-big { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.aiu-big b { font-size: 17px; font-weight: 650; color: var(--text); font-variant-numeric: tabular-nums; }
.aiu-big span { font-size: 11px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.aiu-sub { margin-top: 6px; font-size: 12px; line-height: 1.45; color: var(--muted); }
.aiu-cost { font-variant-numeric: tabular-nums; }
.aiu-empty { margin-top: 8px; }
/* Столбики по дням — только форма расхода во времени, без осей и подписей (это не график, а
   намёк «когда жгли»). Значения — в title каждого столбика. */
.aiu-bars {
  display: flex; align-items: flex-end; gap: 2px; height: 34px; margin-top: 10px;
  padding: 0 2px; border-radius: 8px; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line);
}
/* 🔴 СТОЛБИК — ЭТО СТОЛБИК, А НЕ ПЛАШКА ВО ВСЮ ШИРИНУ. Замер кадра прода 17.09: за два дня
   замера блок рисовал ДВА прямоугольника на пол-окна каждый — глазами это читается как
   сломанный элемент, а не как «когда жгли». Ширина ограничена сверху, ряд прижат влево:
   два дня выглядят двумя столбиками, тридцать — плотной гребёнкой. */
.aiu-bars { justify-content: flex-start; }
.aiu-bars i {
  flex: 1 1 0; min-width: 2px; max-width: 14px; border-radius: 2px 2px 0 0;
  background: color-mix(in srgb, var(--primary) 55%, transparent);
}
.aiu-brk { margin-top: 10px; display: flex; flex-direction: column; gap: 6px; }
.aiu-brow { display: flex; align-items: flex-start; gap: 8px; }
.aiu-bk { flex: 0 0 76px; font-size: 11px; color: var(--muted); padding-top: 3px; }
.aiu-bv { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; flex: 1 1 auto; }
.aiu-bv-col { flex-direction: column; }
.aiu-chip {
  display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  padding: 3px 9px; border-radius: 999px; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line); font-size: 11.5px;
}
.aiu-chip b { font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aiu-chip em { font-style: normal; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.aiu-chip .aig-accu { margin-left: 0; }
.aiu-task { display: flex; align-items: baseline; gap: 8px; font-size: 12px; min-width: 0; }
.aiu-task b { font-weight: 500; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aiu-task em { font-style: normal; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; margin-left: auto; }
.aiu-foot { margin-top: 10px; }
/* 📜 Лист истории: фильтры сверху, строки — фактами прогона (без слов из работы коллеги). */
.aiu-hist { min-height: 120px; }
.aiu-flt { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.aiu-sels { display: flex; flex-wrap: wrap; gap: 6px; flex: 1 1 auto; }
.aiu-sel {
  height: var(--ctl-h); box-sizing: border-box; padding: 0 26px 0 9px; max-width: 170px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel-2); color: var(--text);
  font: inherit; font-size: 12px; outline: none; cursor: pointer;
  appearance: none; -webkit-appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 14px) calc(50% + 1px), calc(100% - 10px) calc(50% + 1px);
  background-size: 4px 4px, 4px 4px; background-repeat: no-repeat;
}
.aiu-sel:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--glow); }
.aiu-say { margin: 10px 0 4px; font-size: 12.5px; color: var(--text); }
.aiu-list { display: flex; flex-direction: column; }
.aiu-row { padding: 9px 2px; border-top: 1px solid var(--line); }
.aiu-row:first-child { border-top: 0; }
.aiu-r1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.aiu-when { font-size: 12.5px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.aiu-tag {
  font-size: 11px; color: var(--muted); padding: 1px 7px; border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 12%, transparent);
}
.aiu-tok { margin-left: auto; font-size: 12px; color: var(--text); font-variant-numeric: tabular-nums; }
/* 💬 Текст запроса коллеги (0382). Обрезаем ДВУМЯ строками: узнать запрос хватает, а полотно
   на пол-окна превращает историю в нечитаемую простыню. */
.aiu-ask {
  margin-top: 4px; padding: 6px 9px; border-radius: 8px; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line); font-size: 12.5px; line-height: 1.4; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere;
}
/* 📁 Проект (папка Среды) — чипом в первой строке, со значком папки. */
.aiu-tag.aiu-proj { display: inline-flex; align-items: center; gap: 4px; color: var(--text); }
.aiu-tag.aiu-proj .ic { width: 12px; height: 12px; opacity: .7; }
.aiu-r2 { margin-top: 3px; font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Задача, которой зритель не видит: название сервер не отдал — печатаем приглушённо, чтобы
   «Задача коллеги» не читалась как настоящее имя задачи. */
.aiu-r2.aiu-dim { color: var(--muted); font-style: italic; }
.aiu-r3 { margin-top: 2px; font-size: 11.5px; color: var(--muted); }
/* Исход — СЛОВОМ на своём токене (акцент читается и в ч/б, канон accent). */
.aiu-row.aiu-st-failed .aiu-status {
  color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent);
}
.aiu-row.aiu-st-running .aiu-status {
  color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, transparent);
}
.aiu-row.aiu-st-stopped .aiu-status {
  color: var(--warning); background: color-mix(in srgb, var(--warning) 14%, transparent);
}
/* Светлая тема: чернила акцента на СВОЕЙ заливке ниже AA — те же 15 % темнее, что у .aig-accu. */
html[data-theme="light"] .aiu-row.aiu-st-failed .aiu-status { color: color-mix(in srgb, var(--danger) 85%, #000); }
html[data-theme="light"] .aiu-row.aiu-st-running .aiu-status { color: color-mix(in srgb, var(--ok) 85%, #000); }
html[data-theme="light"] .aiu-row.aiu-st-stopped .aiu-status { color: color-mix(in srgb, var(--warning) 85%, #000); }
.aiu-none { padding: 18px 2px; font-size: 13px; color: var(--muted); }
.aiu-more { margin-top: 10px; }
@media (max-width: 640px) {
  .aiu-bk { flex-basis: 100%; padding-top: 0; }
  .aiu-brow { flex-wrap: wrap; }
  .aiu-sel { max-width: none; flex: 1 1 120px; }
}
/* 🕐 «Своё…» — свой срок выдачи (aiGrantDurHtml): число + единица (Часы | Дни), до 30 дней.
   Под сегментом всегда живой итог «до 17.09 18:00»; ошибка — цветом токена, без рельс. */
.aig-custom { display: flex; align-items: center; gap: 8px; margin-top: 8px; animation: aigIn 160ms ease; }
.aig-custom[hidden] { display: none; }
@keyframes aigIn { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
.aig-num {
  width: 76px; height: var(--ctl-h); box-sizing: border-box; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel-2); color: var(--text);
  font: inherit; font-size: 13px; font-variant-numeric: tabular-nums; outline: none;
  -moz-appearance: textfield; appearance: textfield;
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
.aig-num::-webkit-inner-spin-button, .aig-num::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.aig-num:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--glow); }
.aig-num.bad { border-color: var(--danger); box-shadow: 0 0 0 3px var(--danger-soft); }
.aig-unit { flex: none; }
.aig-max { font-size: 12px; color: var(--muted); }
.aig-max.bad { color: var(--danger); }
.aig-until { margin-top: 8px; min-height: 17px; font-size: 12.5px; color: var(--text); font-variant-numeric: tabular-nums; }
.aig-until.bad { color: var(--danger); }
/* «Отозвать» в подвале окна правки — разрушительное действие отнесено влево, цветом, без заливки. */
.pm-foot .aig-revoke { margin-right: auto; color: var(--danger); }
.pm-foot .aig-revoke:hover { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 35%, transparent); }

/* 🤝 «МОЙ ИИ У КОЛЛЕГ» — ОДИН блок (aiLendPaint) на все хосты [data-ai-lend]: вершина
   Настроек → ИИ и окно «Кому я одолжил свой ИИ…» из меню «Чей ИИ» среды. Строка =
   аватар · имя · «до 18:00 · аккаунты» · действия. Ожидание — тёплой подложкой, без рельс. */
.ai-lend { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; }
.ai-lend-h { margin: 12px 0 2px; font-size: 12px; font-weight: 600; color: var(--muted); }
.ai-lend-h:first-child { margin-top: 0; }
.ai-lend-row {
  display: flex; align-items: center; gap: 10px; min-height: 48px; padding: 7px 8px 7px 10px;
  border-radius: 12px; background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line);
  cursor: pointer; transition: box-shadow 140ms ease, background 140ms ease;
}
.ai-lend-row:hover { box-shadow: inset 0 0 0 1px var(--line-strong); }
.ai-lend-row.wait { background: color-mix(in srgb, #f0a020 8%, var(--panel-2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, #f0a020 28%, var(--line)); }
.ai-lend-av { flex: none; display: inline-flex; }
.ai-lend-av .tw-av { width: 30px; height: 30px; margin: 0; border: 0; font-size: 12px; }
.ai-lend-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.ai-lend-tx b { font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-lend-tx span { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-lend-acts { flex: none; display: flex; gap: 6px; }
.ai-lend-acts > button { height: var(--ctl-h); padding: 0 11px; border-radius: 9px; }
.ai-lend-acts > .ai-lend-go { color: var(--primary); }
.ai-lend-acts > .ai-lend-danger { color: var(--danger); }
.ai-lend-acts > .ai-lend-danger:hover { background: var(--danger-soft); border-color: color-mix(in srgb, var(--danger) 35%, transparent); }
.ai-lend-empty {
  display: flex; flex-direction: column; gap: 3px; padding: 12px; border-radius: 12px;
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); font-size: 13px; color: var(--text);
}
.ai-lend-empty span { font-size: 12px; line-height: 1.4; color: var(--muted); }
.ai-lend-empty button { align-self: flex-start; margin-top: 6px; }
.ai-lend-ask { align-self: flex-start; margin-top: 2px; }
/* 🔑 Аккаунты Claude для одалживания: строка не открывает окно (у неё одно действие — «Удалить»). */
.ai-lend-row.ai-lacc { cursor: default; }
.ai-lend-row.ai-lacc.on { background: color-mix(in srgb, var(--ok) 8%, var(--panel-2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 26%, var(--line)); }
.ai-lacc-ic {
  flex: none; width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--panel); color: var(--muted); box-shadow: inset 0 0 0 1px var(--line);
}
.ai-lacc-ic .ic { width: 14px; height: 14px; }
.ai-lend-win { margin-top: 0; }
@media (max-width: 520px) {
  .ai-lend-row { flex-wrap: wrap; }
  .ai-lend-acts { width: 100%; justify-content: flex-end; }
}
.dvai-askbody { padding: 14px 16px; }
.dvai-askbody textarea {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 84px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 10px; background: var(--bg); color: var(--fg);
  font: inherit; font-size: 13px; line-height: 1.45; outline: none;
  transition: border-color 130ms ease, box-shadow 130ms ease;
}
.dvai-askbody textarea:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.dvai-ask .v2fb-foot { justify-content: flex-end; gap: 8px; }
/* Заголовок диалога — обычный текст, а не путь к файлу: снимаем моношрифт и rtl-обрезку .v2fb-path. */
.dvai-ask .v2fb-path { direction: ltr; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--fg); }

/* ══ 🖥️ ТЕРМИНАЛ ПРОЕКТА (Э1): логи запуска · произвольная команда ══════════════
   Нижняя панель среды и она же — панель «Логи» во вкладке «Превью» (ОДНА реализация).
   Всё на токенах, поэтому светлая тема наследуется без второго набора правил.
   Высота НЕ прибита: её тянут мышью за верхнюю кромку (.dvterm-grip), значение помнится. */
.dvs-term {
  flex: 0 0 auto; height: 260px; min-height: 120px; max-height: 72vh;
  display: flex; flex-direction: column; min-width: 0;
  border-top: 1px solid var(--line); background: var(--panel);
  position: relative;
}
.dvs-term[hidden] { display: none; }               /* [hidden] бессилен против display:flex */
/* В среде панель живёт ПОД РЕДАКТОРОМ (в колонке кода): полноширинная легла бы левым
   нижним углом под сквозной пузырь быстрого чата. Кромка сверху — общая с редактором. */
.dvs-edit > .dvs-term { border-left: 0; }
/* Во вкладке «Превью» панель ниже сцены и достаёт до левого края рабочей области —
   там пузырь как раз рядом, поэтому строке ввода оставляем под него место (тот же приём,
   что у коробки коммита: `.dvs-commit { padding-bottom: 84px }`). */
#v2prevLogs .dvterm-in { padding-left: 64px; }
/* …и снизу у вывода — чтобы пузырь ложился на пустоту, а не на последнюю строку лога
   (отступ ВНУТРИ прокрутки: текст не сдвигается, автопрокрутка по-прежнему доводит до низа). */
#v2prevLogs .dvterm-out { padding-bottom: 62px; }
.dvterm { display: flex; flex-direction: column; height: 100%; min-height: 0; }
/* Хваталка высоты: тот же язык, что у всех швов продукта (.col-resizer), только по вертикали. */
.cc-hgrip {
  position: absolute; left: 0; right: 0; top: -4px; bottom: auto;
  width: auto; height: 9px; z-index: 20; cursor: row-resize;
}
.cc-hgrip::after {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  width: auto; height: 2px; transform: translateY(-50%);
  background: var(--primary); border-radius: 2px; box-shadow: 0 0 8px -1px var(--glow);
  opacity: 0; transition: opacity .15s ease;
}
.cc-hgrip:hover::after, .cc-hgrip.dragging::after { opacity: 1; }
.dvterm-bar {
  display: flex; align-items: center; gap: 8px; padding: 6px 10px; flex: 0 0 auto;
  border-bottom: 1px solid var(--line);
}
/* CLIE-505: размер даёт канон (.cc-seg-md — высота строки тулбара терминала). */
.dvterm-seg { margin: 0; }
.dvterm-seg > button { flex: 0 0 auto; }
.dvterm-state { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; color: var(--muted); min-width: 0; }
.dvterm-state > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 320px; }
.dvterm-bar .v2prev-btn[hidden] { display: none; }
.dvterm-bar .v2prev-btn.danger { border-color: color-mix(in srgb, var(--danger, #ff453a) 45%, var(--line)); color: var(--danger, #ff453a); }
.dvterm-out {
  flex: 1 1 auto; min-height: 0; overflow: auto; margin: 0; padding: 10px 12px;
  background: var(--bg-soft, transparent); color: var(--fg);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; line-height: 1.5;
  white-space: pre-wrap; word-break: break-word; outline: none;
}
/* Строка ввода = ОДНА чистая строка (доктрина «не отбирать экран»): приглашение, поле,
   история. Кнопка «Выполнить» всплывает только когда есть что выполнять. */
.dvterm-in {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto; padding: 8px 10px;
  border-top: 1px solid var(--line); background: var(--panel);
}
.dvterm-in[hidden] { display: none; }
.dvterm-prompt {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px;
  color: var(--accent); flex: 0 0 auto; opacity: .85;
}
.dvterm-input {
  flex: 1 1 auto; min-width: 0; height: 30px; padding: 0 10px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg); color: var(--fg);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; outline: none;
  transition: border-color 130ms ease, box-shadow 130ms ease;
}
.dvterm-input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.dvterm-input:disabled { opacity: .6; cursor: not-allowed; }
.dvterm-hist {
  flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border: 1px solid var(--line); border-radius: 8px;
  background: transparent; color: var(--muted); cursor: pointer;
  transition: background 140ms ease, color 140ms ease;
}
.dvterm-hist:hover { background: var(--hover); color: var(--fg); }
.dvterm-hist .ic { width: 15px; height: 15px; }
.dvterm-go {
  flex: 0 0 auto; height: 30px; padding: 0 14px; border: 0; border-radius: 8px;
  background: var(--acc-fill, var(--cm-5b5bd6, #5b5bd6)); color: #fff; font-size: 13px; font-weight: 500; cursor: pointer;
  animation: dvsAskIn 140ms ease;
}
.dvterm-go[hidden] { display: none; }
.dvterm-hist-pop { display: flex; flex-direction: column; padding: 4px; max-height: 320px; overflow: auto; }
.dvterm-hrow {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; text-align: left; padding: 7px 9px; border: 0; border-radius: 7px;
  background: transparent; color: var(--fg); cursor: pointer;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  overflow: hidden;
}
/* СРЕД-31: под командой — КТО её выполнил и когда (свои, коллеги и ИИ в одном списке). */
.dvterm-hrow > span { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvterm-hwho { font-size: 11px; color: var(--text-dim); font-family: inherit; }
.dvterm-hrow:hover { background: var(--hover); }
/* На узком экране терминал занимает больше высоты — иначе от вывода остаётся две строки. */
@media (max-width: 720px) {
  .dvs-term { height: 46vh; max-height: 60vh; }
  .cc-hgrip { display: none; }
}

/* ═══════════════════ 🗓 Расписание статусов (0183) ═══════════════════
   Строка-вход в поповере статуса + отдельный редактор интервалов. Обе темы держатся
   на токенах (--panel/--line/--muted), поэтому светлая наследуется без дублей правил;
   отдельно доопределяем только то, что цветом токена не выражается (нативный time-инпут). */
.st-sched-row {
  display: flex; align-items: center; gap: 9px; width: 100%;
  margin-top: 12px; padding: 9px 8px 9px 0;
  background: transparent; border: none; border-top: 1px solid var(--line);
  color: var(--text); text-align: left; cursor: pointer; border-radius: 0 0 8px 8px;
  transition: background 140ms ease;
}
.st-sched-row:hover { background: var(--hover); }
.st-sched-row .st-dnd-ic { padding-left: 2px; }
.st-sched-mid { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.st-sched-sub { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.st-sched-go { flex: none; display: inline-flex; color: var(--text-dim); }
.st-sched-go svg.ic { width: 15px; height: 15px; }

.sch-scrim {
  position: fixed; inset: 0; z-index: 1200; display: flex; align-items: center; justify-content: center;
  background: var(--scrim); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  padding: 20px; animation: schFade 140ms ease;
}
@keyframes schFade { from { opacity: 0; } to { opacity: 1; } }
.sch-modal {
  width: min(600px, 96vw); max-height: min(86vh, 760px); display: flex; flex-direction: column;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--shadow-3); overflow: hidden; animation: schPop 160ms cubic-bezier(.22,1,.36,1);
}
@keyframes schPop { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }
.sch-head { display: flex; align-items: center; gap: 10px; padding: 13px 14px 13px 16px; border-bottom: 1px solid var(--line); }
.sch-title { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; font-size: 15px; color: var(--text); }
.sch-title svg.ic { width: 17px; height: 17px; color: var(--primary); }
/* 💾 Подпись автосохранения — ОДНА форма на продукт (дверь ccSavedFlash, CLIE-1660):
   расписание статусов и поповер статуса берут её, а не рисуют каждый свою. */
.cc-savedflash { flex: none; font-size: 11.5px; transition: opacity 140ms ease; }
.cc-savedflash.bad { color: var(--danger); }
/* «Не сохранилось» — кликабельный повтор, а не мёртвая надпись (правка при этом цела). */
.cc-savedflash.retry { cursor: pointer; text-decoration: underline dotted; text-underline-offset: 2px; }
.cc-savedflash.retry:hover { opacity: .8; }
.sch-sw { flex: none; }
.sch-x { flex: none; background: transparent; border: none; color: var(--muted); cursor: pointer; padding: 5px; border-radius: 8px; display: inline-flex; }
.sch-x:hover { background: var(--hover); color: var(--text); }
.sch-x svg.ic { width: 16px; height: 16px; }
.sch-body { overflow: auto; padding: 14px 16px 18px; }
.sch-hint, .sch-note { font-size: 12px; line-height: 1.5; color: var(--muted); }
.sch-hint { margin-bottom: 12px; }
/* Оговорка про пересечения живёт ПОД рамой: у карточки уже есть своя граница,
   вторая линия над сноской делала «коробку в коробке». */
.sch-note { margin-top: 12px; padding: 0 2px; }
.sch-none { font-size: 12.5px; color: var(--text-dim); padding: 14px; }
.sch-none.sch-full { border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); color: var(--warning); }

/* ══ 🗓 CLIE-1081 · «НЕДЕЛЯ ОДНИМ ВЗГЛЯДОМ» ═══════════════════════════════════════════════
   Владелец: «Нужен нормальный дизайн расписания статусов». Прежний экран был формой-списком:
   четыре одинаковые строки полей, и главный вопрос фичи — «а не осталось ли часов, где я
   без статуса» — по ней не читался ВООБЩЕ (на этом фича уже обожглась: шаблон из апки
   оставлял ночь на понедельник пустой). Поэтому сверху — СОСТОЯНИЕ («Сейчас: …»), затем
   ПОЛОСА НЕДЕЛИ целиком, и только потом карточки-интервалы.
   🔴 Цвет вида интервала едет переменной `--sk` (её ставит app.js токеном темы), и один и тот
   же `--sk` красит блок недели, значок карточки и выбранные дни — связь «этот блок = эта
   карточка» видна без наведения и в ч/б. Никаких левых полосок-реек (канон accent). */
/* 🗂 CLIE-1081·2 «Тихий список»: ОДНА рама на весь экран, разделы внутри — волосяной
   линией (язык системных настроек). Коробка в коробке (карточка окна → карточка блока →
   карточка каждого интервала) была главной причиной «UI не понравился». */
.sch-card {
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
}
.sch-now {
  display: flex; align-items: center; gap: 10px; padding: 12px 14px;
  border-bottom: 1px solid var(--line);
}
.sch-now-dot {
  flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--sk, var(--primary));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--sk, var(--primary)) 22%, transparent);
}
.sch-now-t { flex: 1; min-width: 0; font-size: 13.5px; color: var(--text); }
.sch-now-t b { font-weight: 600; }
.sch-now-s { display: block; font-size: 11.5px; color: var(--muted); margin-top: 1px; }
/* Выход из паузы — рядом с самой паузой, а не отдельной плашкой сверху. */
.sch-now-act {
  flex: none; min-width: auto; height: 28px; padding: 0 11px; font-size: 12.5px; font-family: inherit;
  background: transparent; border: 1px solid var(--line-strong); border-radius: 9px;
  color: var(--text); cursor: pointer; white-space: nowrap; transition: all 130ms ease;
}
.sch-now-act:hover { border-color: var(--primary); background: var(--hover); }
.sch-now-act:disabled { opacity: .5; cursor: default; }

.sch-week { padding: 11px 14px 12px; border-bottom: 1px solid var(--line); }
.sch-week-h { display: flex; align-items: baseline; gap: 8px; margin-bottom: 8px; }
.sch-week-t { flex: 1; font-size: 11px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
/* Пропуск — это не ошибка ввода, а то, чего человек не заметил бы. Поэтому он назван числом
   и подсвечен цветом предупреждения, а не спрятан. */
.sch-week-gap { flex: none; font-size: 11.5px; color: var(--muted); }
.sch-week-gap.bad { color: var(--warning); }
/* Шкала — ПОД полосой и ровно по её ширине (flex-раскладка, а не абсолютные проценты):
   раньше подписи 0/6/12/18/24 считались от всей строки вместе с колонкой дней и стояли
   левее своих засечек. */
.sch-scale { display: flex; justify-content: space-between; margin: 8px 0 0 26px;
  font-size: 9.5px; color: var(--text-dim); letter-spacing: .02em; }
.sch-drow { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.sch-drow:first-of-type { margin-top: 0; }
.sch-dname { flex: none; width: 18px; font-size: 10.5px; color: var(--text-dim); text-align: right; }
.sch-track {
  position: relative; flex: 1; height: 10px; border-radius: 5px; overflow: hidden;
  background: color-mix(in srgb, var(--text) 6%, transparent);
}
/* Насечки каждые 6 часов — чтобы «с девяти» читалось глазом, без подписи у каждой строки. */
.sch-track::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(90deg, transparent 0, transparent calc(25% - 1px),
    color-mix(in srgb, var(--line) 70%, transparent) calc(25% - 1px), transparent 25%);
}
/* Сплошная заливка со скруглением: полупрозрачные блоки на тёмной подложке читались как
   «что-то бледное», и понять, где кончается интервал, было нельзя. */
.sch-blk { position: absolute; top: 0; bottom: 0; border-radius: 5px; background: var(--sk); opacity: .9; }

.sch-list { display: block; }
/* Интервал — СТРОКА списка, а не карточка: своей рамки и своего фона нет, соседей делит
   волосяная линия (канон accent: никаких левых реек, цвет вида живёт на значке). */
.sch-row {
  /* Локальный размерный класс ряда (канон control-size): значок, поле, оба времени и корзина
     обязаны совпасть по высоте — один токен, а не четыре числа. */
  --ctl-h: 30px; --ctl-r: 9px; --ctl-fs: 13px;
  border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
  padding: 9px 10px 9px 14px; transition: background 140ms ease;
}
.sch-row:first-child { border-top: none; }
.sch-row:hover { background: color-mix(in srgb, var(--text) 3%, transparent); }
.sch-line { display: flex; align-items: center; gap: 11px; cursor: pointer; }
.sch-emoji {
  flex: none; width: var(--ctl-h); height: var(--ctl-h); font-size: 16px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center; border: none;
  background: color-mix(in srgb, var(--sk) 16%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sk) 28%, transparent);
  border-radius: 9px; color: var(--text); cursor: pointer; transition: background 140ms ease;
}
.sch-emoji:hover { background: color-mix(in srgb, var(--sk) 26%, transparent); }
.sch-mid { flex: 1; min-width: 0; display: block; }
/* Название правится ПО КЛИКУ на само слово (канон inline-edit): рамка появляется на наведении,
   а не стоит вокруг каждой строки постоянно. */
.sch-text {
  display: block; width: 100%; box-sizing: border-box; height: 22px; padding: 0 5px; margin-left: -5px;
  font-size: 14px; font-weight: 550; font-family: inherit;
  background: transparent; border: 1px solid transparent; border-radius: 7px; color: var(--text);
  transition: border-color 140ms ease, box-shadow 140ms ease, background 140ms ease;
}
.sch-text:hover { border-color: var(--line); }
.sch-text:focus { outline: none; background: var(--input-bg); border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
/* Вторая строка — дни СЛОВАМИ и оговорка («через полночь»): читается без семи кнопок. */
.sch-sub { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; margin-top: 1px; }
.sch-dl { font-size: 11.5px; color: var(--muted); }
.sch-times { flex: none; display: inline-flex; align-items: center; gap: 4px; }
/* 🔴 Часы — СВОЯ кнопка, не `input[type=time]`: нативное поле в 12-часовой локали рисует
   «02:00 PM» с глифом часиков (замер на проде), тянет 122px на каждое поле и не слушает
   наши токены. Значение — та же строка «ЧЧ:ММ», меняет пикер `.sch-tp`. */
.sch-time {
  flex: none; min-width: auto; height: var(--ctl-h); padding: 0 9px; font-size: var(--ctl-fs);
  font-family: inherit; white-space: nowrap;
  background: color-mix(in srgb, var(--text) 6%, transparent); border: 1px solid transparent;
  border-radius: var(--ctl-r); color: var(--text);
  font-variant-numeric: tabular-nums; cursor: pointer; transition: all 130ms ease;
}
.sch-time:hover { background: color-mix(in srgb, var(--text) 10%, transparent); }
.sch-time:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--sel); }
.sch-dash { flex: none; color: var(--text-dim); font-size: 13px; }
/* 🔴 Корзина стоит ВСЕГДА (CLIE-1081·2). Прежняя пряталась за `opacity: 0` до наведения на
   строку — владелец просил «добавь возможность удалять», хотя кнопка в разметке была:
   контрол, которого не видно, для человека не существует. */
.sch-del {
  flex: none; width: var(--ctl-h); height: var(--ctl-h); border-radius: var(--ctl-r);
  background: transparent; border: none; color: var(--text-dim); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background 140ms ease, color 140ms ease;
}
.sch-del:hover { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.sch-del svg.ic { width: 15px; height: 15px; }
/* Раскрывающаяся часть строки: семь дней и палитра значков. Свёрнута по умолчанию —
   канон progressive-disclosure (пустое состояние = минимум). */
.sch-edit { margin: 9px 0 2px 41px; }
.sch-edit.hidden { display: none; }
/* Подпись под интервалом — появляется ТОЛЬКО когда есть что сказать («через полночь»,
   «круглые сутки», «не выбран ни один день»); пустая — не занимает места. */
.sch-span { font-size: 11.5px; line-height: 1.35; color: var(--muted); }
.sch-span:empty { display: none; }
.sch-span.warn { color: var(--warning); }
.sch-days { display: inline-flex; flex-wrap: wrap; gap: 3px; }
.sch-day {
  min-width: 30px; height: 26px; padding: 0 6px; font-size: 11.5px;
  background: transparent; border: 1px solid var(--line); border-radius: 8px;
  color: var(--text-dim); cursor: pointer; transition: all 130ms ease;
}
.sch-day:hover { border-color: var(--line-strong); color: var(--text); }
.sch-day.on {
  background: color-mix(in srgb, var(--sk) 16%, transparent); color: var(--text); font-weight: 600;
  border-color: color-mix(in srgb, var(--sk) 45%, transparent);
}
.sch-emoji-grid { display: grid; grid-template-columns: repeat(11, 1fr); gap: 2px; margin: 8px 0 0; }
.sch-emoji-grid.hidden { display: none; }
.sch-emoji-opt { background: transparent; border: none; border-radius: 7px; font-size: 16px; padding: 4px 0; cursor: pointer; }
.sch-emoji-opt:hover { background: var(--hover); }

/* Строка «Добавить интервал» — последняя строка того же списка, а не отдельная плашка.
   Набор видов появляется ПОД ней и только по нажатию (progressive-disclosure). */
.sch-addrow {
  display: flex; align-items: center; gap: 9px; width: 100%; box-sizing: border-box;
  padding: 11px 14px; font-size: 13px; font-family: inherit; text-align: left;
  background: transparent; border: none; border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent);
  color: var(--muted); cursor: pointer; transition: background 140ms ease, color 140ms ease;
}
.sch-addrow:hover:not(:disabled) { background: color-mix(in srgb, var(--text) 3%, transparent); color: var(--text); }
.sch-addrow:disabled { opacity: .45; cursor: default; }
.sch-addrow svg.ic { width: 14px; height: 14px; transition: transform 160ms ease; }
.sch-addrow.open svg.ic { transform: rotate(45deg); }
.sch-kinds {
  display: flex; flex-wrap: wrap; gap: 6px;
  padding: 0 14px 12px; border-top: none;
}
.sch-kinds.hidden { display: none; }
.sch-add {
  display: inline-flex; align-items: center; gap: 5px; min-width: auto;
  height: 30px; padding: 0 11px; font-size: 12.5px; font-family: inherit; white-space: nowrap;
  background: color-mix(in srgb, var(--text) 6%, transparent); border: 1px solid transparent; border-radius: 9px;
  color: var(--text); cursor: pointer; transition: all 130ms ease;
}
.sch-add:hover:not(:disabled) { background: color-mix(in srgb, var(--primary) 16%, transparent); border-color: color-mix(in srgb, var(--primary) 40%, transparent); }
.sch-add:disabled { opacity: .45; cursor: default; }
.sch-add svg.ic { width: 13px; height: 13px; }

/* 🕑 Свой пикер времени вместо нативного `input[type=time]`: две прокручиваемые
   колонки «часы» и «минуты», значение применяется сразу (канон inline-edit — без
   «Сохранить/Отмена»).
   🔴 СВОЕГО z-index ЗДЕСЬ НЕТ НАМЕРЕННО (канон слоёв CLIE-692): слой ставит дверь
   `ccLayerLift` по реестру `CC_LAYER_SEL` в app.js. Число «побольше» (было 1260 против
   1200 у `.sch-scrim`) не работало: шторку эта же дверь поднимает на CC_Z_BASE+N. */
.sch-tp {
  position: fixed; display: flex; gap: 2px; padding: 5px;
  background: var(--panel); border: 1px solid var(--line-strong); border-radius: 12px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, .34);
}
/* Кап кратен строке (28px × 7): обрез никогда не приходится на середину числа. Своего
   `overflow` тут намеренно нет — он приезжает каноном `.cc-scroll-in` (реестр `SCROLL_IN_SEL`
   в `app.js`), вместе с видимым бегунком и подтаявшим краем (CLIE-620). */
.sch-tp-col { width: 58px; max-height: 196px; }
.sch-tp-col + .sch-tp-col { border-left: 1px solid color-mix(in srgb, var(--line) 70%, transparent); padding-left: 2px; }
.sch-tp-o {
  display: block; width: 100%; height: 28px; padding: 0; font-size: 13px; font-family: inherit;
  background: transparent; border: none; border-radius: 7px; color: var(--text);
  font-variant-numeric: tabular-nums; cursor: pointer; transition: background 110ms ease;
}
.sch-tp-o:hover { background: var(--hover); }
.sch-tp-o.on { background: var(--acc-fill); color: #fff; font-weight: 600; }
.sch-tp-o:disabled { opacity: .3; cursor: default; }
.sch-tp-o:disabled:hover { background: transparent; }

.sch-empty { text-align: center; padding: 22px 18px 26px; }
.sch-empty-ic { display: inline-flex; padding: 12px; border-radius: 14px; background: var(--panel-2); color: var(--primary); margin-bottom: 12px; }
.sch-empty-ic svg.ic { width: 22px; height: 22px; }
.sch-empty p { margin: 0 auto 16px; max-width: 400px; font-size: 13px; line-height: 1.55; color: var(--muted); }
@media (max-width: 560px) {
  /* Узко — часы уезжают на свою строку, но корзина остаётся у имени: удаление
     не должно прятаться за переносом. */
  .sch-line { flex-wrap: wrap; }
  .sch-times { order: 3; margin: 7px 0 0 41px; }
  .sch-edit { margin-left: 0; }
  /* Чипы дней — под палец: 26px мышью нормально, пальцем мимо. */
  .sch-day { min-width: 38px; height: 32px; font-size: 12px; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   🔴🔴 ИЗОЛЯЦИЯ ОТРИСОВКИ ДЛИННОГО СПИСКА ЧАТОВ (перф, 2026-08-12)
   ------------------------------------------------------------------------------
   Жалоба владельца: «сильно тормозит, анимации с дерганьем».
   ЗАМЕРЕНО НА ЖИВОМ ПРОДЕ, аккаунт владельца (1794 беседы):
     #convList = 1693 <li> / 26 569 элементов / 2.66 МБ HTML;
     renderConvList() пересобирает его ЦЕЛИКОМ через innerHTML на каждое
     реалтайм-событие. Замер (медиана 7 прогонов, порядок обратный — прогрев исключён):
       без изоляции  = 336.8 мс   ← ~20 пропущенных кадров на КАЖДОЕ событие
       с изоляцией   =  31.6 мс   (контроль 43.7 мс)
     Частота (MutationObserver, 60 с в ПРОСТОЕ): 7 полных пересборок/мин
     → ≈2.4 с замороженного главного потока в минуту БЕЗ действий пользователя;
     за те же 60 с: 38 long-task (топ 1022/820/738/634/627 мс), максимум кадра 1135 мс.
   content-visibility даёт браузеру право не считать layout/paint строк за экраном.
   🔴 ЭТО МИТИГАЦИЯ (8-10×), НЕ ЛЕЧЕНИЕ: после неё остаются 32-44 мс на пересборку.
   Настоящее лечение — кэп/виртуализация #convList (пересобирать строку, а не список).
   🔴 НЕ РАСПРОСТРАНЯТЬ на .messages/.msg: пузырь — flex-элемент с shrink-to-fit
   шириной (max-width: min(70%, …)), intrinsic-плейсхолдер заставит его скакать по
   ширине при скролле. Эффект там НЕ замерен — не включать заодно.
   🔴 НЕ путать с осознанным отказом от content-visibility на схеме (style.css:11035):
   там панорамируемый canvas с transform — принципиально другой случай.
   ══════════════════════════════════════════════════════════════════════════════ */
#convList > li {
  /* auto — браузер ЗАПОМИНАЕТ реальную высоту отрисованной строки и дальше использует
     её вместо плейсхолдера (иначе scrollHeight уезжает сразу после innerHTML,
     а якорное восстановление позиции в renderConvList читает getBoundingClientRect). */
  content-visibility: auto;
  contain-intrinsic-size: auto 82px;
}

/* ══════════════════════════════════════════════════════════════════════════════
   🔴🔴 ИЗОЛЯЦИЯ ОТРИСОВКИ ДОСКИ И СПИСКА ЗАДАЧ (перф, 2026-08-12, CLIE-444)
   ------------------------------------------------------------------------------
   Владелец (десктоп-приложение, оно крутит этот же app.js): «Задачи → Все задачи →
   выбрать проекты → поскроллить минуту — сразу увидишь проблему». У него 944 задачи.
   ЗАМЕРЕНО на проде на 900 карточках (медиана 5 прогонов, порядок обратный):
     без изоляции = 1133 мс на пересборку   ← БОЛЬШЕ СЕКУНДЫ замороженного интерфейса
     с изоляцией  =  285 мс                 (контроль 581 мс)
   А пересобирается доска на КАЖДОЕ realtime-событие задачи (замер: 5 полных пересборок
   #tasksList за 60 с в ПРОСТОЕ, при живом ИИ-воркере — чаще).
   🔴 Раньше content-visibility поставили только на строки списка ЧАТОВ (#convList > li);
   доска задач — самое тяжёлое место продукта — осталась без изоляции. Это тот пропуск.

   🔴 `auto` в contain-intrinsic-size ОБЯЗАТЕЛЕН: браузер запоминает РЕАЛЬНУЮ высоту
   отрисованного элемента и дальше использует её вместо оценки — иначе scrollHeight
   уезжает и список дёргается при пересборке (проверено на #convList: с `auto` смещение 0 px).
   Числа — стартовая оценка для НИ РАЗУ не показанных элементов, не жёсткий размер.

   🔴 ИСКЛЮЧЕНИЕ .tw-lift: content-visibility влечёт `contain: paint`, а он ОБРЕЗАЕТ
   вылезающее за границы. У поднятой перетаскиванием карточки большая тень
   (`0 14px 34px`, style.css .tw-card-li.tw-lift .tw-card) — с изоляцией её бы срезало.
   Во время перетаскивания изоляцию снимаем.

   🔴 НЕ вешаем на .task-section-title (заголовки секций другой высоты) и на ленту
   сообщений (пузырь shrink-to-fit — плейсхолдер заставит его скакать по ширине).
   ══════════════════════════════════════════════════════════════════════════════ */
.tw-card-li {
  content-visibility: auto;
  contain-intrinsic-size: auto 190px;   /* карточка доски: заголовок + описание + чипы */
}
.tasks-list .task-row {
  content-visibility: auto;
  contain-intrinsic-size: auto 64px;    /* строка списка задач */
}
/* Перетаскиваемая карточка — без изоляции (иначе обрежется тень подъёма) */
.tw-card-li.tw-lift,
.tw-card-li.tw-lift .tw-card {
  content-visibility: visible;
  contain-intrinsic-size: auto;
}
/* ══════════════════════════════════════════════════════════════════════════════
   🔴🔴 ТА ЖЕ ИЗОЛЯЦИЯ — НА КАРТОЧКАХ САМОЙ ДОСКИ (CLIE-685·2, 31.08.2026)
   ------------------------------------------------------------------------------
   Правило CLIE-444 выше писалось РАДИ ДОСКИ (см. его комментарий: «доска задач — самое
   тяжёлое место продукта — осталась без изоляции. Это тот пропуск») и даже подписано
   «карточка доски». Но легло оно на `.tw-card-li` — а это `<li>` СТОЛБИКА «Мои задачи»
   (создаётся в renderMyTasksBody). Карточка НАСТОЯЩЕЙ доски — голый `.tw-card` внутри
   `.tw-col-body` (boardInnerHtml), и под оба селектора она не попадала НИ ОДНИМ УЗЛОМ.
   Фикс объявили сделанным, не спросив браузер, лёг ли он.

   🔴 ЗАМЕР НА БОЕВОМ ПРОДЕ (аккаунт владельца, живая карточка его доски, до правки):
     content-visibility = visible · contain-intrinsic-size = none · классы «tw-card prio-low»
   Цена (движок ПК-версии, Chromium 130 = Electron 33; tools/board_scroll_prod.js):
     1612 карточек · 89 441 узел · одна пересборка 3996 мс, из них РАСКЛАДКА 3105 мс.

   Число 220px — не на глаз: средняя высота карточки на доске владельца
   (228707+100434+25687)px / (899+531+132) карточек = 227px. `auto` обязателен — браузер
   запоминает РЕАЛЬНУЮ высоту показанной карточки и дальше берёт её вместо оценки, иначе
   scrollHeight столбца врёт и восстановление позиции клампится (проверено на #convList).

   🔴🔴 `flex: none` ЗДЕСЬ — ЧАСТЬ МЕХАНИЗМА, А НЕ УКРАШЕНИЕ. `.tw-col-body` — это flex-колонка,
   а у flex-элемента по умолчанию `flex-shrink: 1`. Обычную карточку от сжатия защищает её
   min-content (текст внутри) — но `content-visibility` включает и РАЗМЕРНУЮ изоляцию, и
   min-content пропущенной карточки становится НОЛЬ. Итог: контейнер сжимал каждую карточку до
   одних отступов, а `contain-intrinsic-size` не применялся вовсе. ЗАМЕР на доске владельца,
   столбик «На проверке» (900 карточек), одна и та же правка:
     без `flex:none` → высота столбца  31 566px (карточка 26px)  ← ВРАНЬЁ, реально 228 809px
     с   `flex:none` → высота столбца 227 586px (0.5% от настоящей) ✅
   Врущая высота — не косметика: бегунок показывает не ту долю, а прокрутка на замере давала
   31 откат назад и доносила до списка лишь 21% жеста.
   ══════════════════════════════════════════════════════════════════════════════ */
.tw-col-body > .tw-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 220px;
  flex: none;
}
/* Перетаскиваемая карточка — без изоляции (паритет с .tw-lift выше: contain:paint обрезал бы
   тень подъёма и предпросмотр переноса). */
.tw-col-body > .tw-card.dragging {
  content-visibility: visible;
  contain-intrinsic-size: auto;
}
/* ══════ ✉️ ПИСЬМО — КАНАЛ ЭТОЙ ЖЕ ПЕРЕПИСКИ (CRMC-33/2) ══════
   Полоса каналов живёт В САМОМ композере и появляется ТОЛЬКО в карточке CRM (сделка/лид/
   контакт) — в обычном чате её нет вовсе. Прогрессивное раскрытие: сегменты видно сразу,
   «Тема» — после выбора Email, «Копия» — ещё на шаг позже. Эталон вида — сегменты iOS. */
.crm-chan { display: flex; flex-direction: column; gap: 8px; padding: 0 0 9px; }
/* CLIE-505: вид = канон .cc-seg + .cc-seg-sm (дорожка и пилюля выбранного — его).
   🔗 25.10 · ТОЛЬКО ЗНАЧКИ (владелец: «переключение простейшее»): кнопка — квадрат с
   ЗНАЧКОМ мессенджера в его цвете (`--mc` из ccChanMeta), имя — в title/aria-label.
   Цвет ставится САМОМУ значку, а не кнопке: hover/.on канона красят подпись кнопки,
   а фирменный знак обязан оставаться фирменным в обеих темах. */
.crm-chan-seg { align-self: flex-start; }
.crm-chan-seg.cc-seg-sm > .crm-chan-b {
  width: 34px; min-width: 34px; height: 28px; padding: 0; gap: 0;
  display: inline-flex; align-items: center; justify-content: center; overflow: visible;
}
.crm-chan-seg .crm-chan-b > svg, .crm-chan-seg .crm-chan-b > svg.ic {
  width: 18px; height: 18px; flex: none; color: var(--mc, var(--primary));
}
/* Без префикса полосы: радиус значка — не «свой сегмент» (сторож CLIE-505 ищет радиус/фон у .…seg). */
.crm-chan-b > .cc-app-glyph {
  width: 18px; height: 18px; border-radius: 5px; display: block; flex: none; object-fit: cover;
}
/* Канал на паузе / без адреса — значок СЕРЕЕТ, но кнопка жива: нажатие объясняет причину и
   даёт выход (crmChanSet → fix/тост), «нажал — ничего» запрещено. */
.crm-chan-seg .crm-chan-b.off { opacity: .45; cursor: pointer; }
.crm-chan-seg .crm-chan-b.off > svg, .crm-chan-seg .crm-chan-b.off > .cc-app-glyph { filter: grayscale(1); }
.crm-chan-seg .crm-chan-b.off:hover { opacity: .7; }
.crm-chan-fields { display: flex; flex-direction: column; gap: 7px; }
.crm-chan-inp {
  width: 100%; box-sizing: border-box; background: var(--panel-2); color: var(--text);
  border: 1px solid var(--line); border-radius: 9px; padding: 8px 11px; font: inherit; font-size: 13.5px;
  outline: 0; transition: border-color .14s ease, box-shadow .14s ease;
}
.crm-chan-inp:focus { border-color: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent); }
.crm-chan-cc {
  align-self: flex-start; background: transparent; border: 0; color: var(--muted);
  font-size: 12px; cursor: pointer; padding: 2px 2px; border-radius: 6px; transition: color .13s ease;
}
.crm-chan-cc:hover { color: var(--primary); }
/* Честная плашка: транспорта нет → говорим ДО отправки, а не «отправлено» постфактум. */
.crm-chan-warn {
  display: flex; gap: 8px; align-items: flex-start; padding: 9px 11px; border-radius: 10px;
  font-size: 12px; line-height: 1.5; color: var(--text);
  background: color-mix(in srgb, #f0a63a 13%, transparent);
  border: 1px solid color-mix(in srgb, #f0a63a 32%, transparent);
}
.crm-chan-warn svg { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 1px; color: #f0a63a; }
.crm-chan-warn code {
  font-size: 11px; padding: 1px 4px; border-radius: 5px; background: var(--panel-2);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
/* 🕒 CRMC-715 (⑥) · ОКНО ОБСЛУЖИВАНИЯ 24 Ч — состояние беседы ПРЯМО В КОМПОЗЕРЕ, до набора
   текста. Канон `accent`: значок + СЛОВО (читается и в ч/б), подложка color-mix 10–14 % и
   ВНУТРЕННЯЯ рамка 22 % — левых реек нет. Три состояния = три семантики цвета, и обе темы
   берут их одним color-mix, а не двумя наборами hex.
   🔴 Чернила текста — var(--text) СВОЕЙ подложки (канон contrast-runtime-audit): цветным
   здесь только значок и слово-акцент, сам текст обязан читаться в обеих темах. */
.crm-chan-win {
  display: flex; gap: 8px; align-items: flex-start; padding: 8px 11px; border-radius: 10px;
  font-size: 12px; line-height: 1.5; color: var(--text);
  background: color-mix(in srgb, var(--wawin) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--wawin) 22%, transparent);
  --wawin: #4aa96c;
}
.crm-chan-win.st-closing { --wawin: #f0a63a; }
/* 📸 Instagram «ответ сотрудника» (клиент писал больше суток назад): отправка разрешена, но
   окно сужено — предупреждающий тон ТОКЕНОМ темы, не новым hex. */
.crm-chan-win.st-agent { --wawin: var(--warning); }
.crm-chan-win.st-closed, .crm-chan-win.st-never { --wawin: #e0654f; }
.crm-chan-win svg { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 2px; color: var(--wawin); }
.crm-chan-win b {
  font-weight: 700; letter-spacing: .02em; text-transform: uppercase; font-size: 10.5px;
  color: var(--wawin); margin-right: 5px;
}
.crm-chan-win .wawin-t { flex: 1 1 auto; min-width: 0; }
/* Кнопка выхода живёт В ПЛАШКЕ: отказ обязан привезти действие, а не только слова. */
.crm-chan-win .crm-chan-fix { flex: 0 0 auto; align-self: center; }

/* 📋 CRMC-715 · ВЫБОР ШАБЛОНА — лист поверх переписки. Своей рамы нет: `.modal-box`
   (ширину тянет `WIN_BOX_SEL`, слой поднимает `ccLayerLift`) — второй рамы не заводим. */
.wa-tpl-box { max-width: min(560px, 95vw); }
.wa-tpl-list { display: flex; flex-direction: column; gap: 8px; overflow: auto; }
.wa-tpl-row {
  text-align: left; padding: 10px 12px; border-radius: 11px; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  display: flex; flex-direction: column; gap: 4px; width: 100%;
}
.wa-tpl-row:hover { border-color: var(--primary); }
.wa-tpl-row[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }
.wa-tpl-row[aria-disabled="true"]:hover { border-color: var(--line); }
.wa-tpl-h { display: flex; align-items: center; gap: 7px; }
.wa-tpl-n { font-weight: 600; font-size: 13.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wa-tpl-b { font-size: 12.5px; color: var(--muted); line-height: 1.45; white-space: pre-wrap; }
/* Статус модерации — подложка + СЛОВО (канон accent): в ч/б «одобрен» и «отклонён» обязаны
   различаться не только цветом. */
.wa-tpl-st {
  font-size: 10.5px; font-weight: 700; letter-spacing: .02em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; flex: 0 0 auto;
  background: color-mix(in srgb, var(--tplc) 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tplc) 26%, transparent);
  color: var(--tplc); --tplc: var(--muted);
}
.wa-tpl-st.ok { --tplc: #4aa96c; }
.wa-tpl-st.wait { --tplc: #f0a63a; }
.wa-tpl-st.err { --tplc: #e0654f; }
.wa-tpl-cat { font-size: 10.5px; color: var(--muted); letter-spacing: .02em; }
.wa-tpl-vars { display: flex; flex-direction: column; gap: 7px; margin-top: 4px; }
.wa-tpl-vars label { font-size: 11.5px; color: var(--muted); }
.wa-tpl-prev {
  font-size: 12.5px; line-height: 1.5; padding: 9px 11px; border-radius: 10px; color: var(--text);
  background: color-mix(in srgb, var(--primary) 9%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 20%, transparent);
  white-space: pre-wrap; word-break: break-word;
}
.wa-tpl-empty { font-size: 13px; color: var(--muted); line-height: 1.55; padding: 6px 0 2px; }

/* В режиме письма вложения/голос неприменимы — гасим, но не убираем (не прыгает вёрстка). */
.composer .chan-off { opacity: .34; pointer-events: none; }
.composer.chan-sending #sendBtn { opacity: .6; }

/* Пузырь письма в ленте: канал + тема + ЧЕСТНЫЙ статус доставки. */
.msg-mail { margin: -1px 0 6px; }
.msg-mail-h { display: flex; align-items: center; gap: 6px; font-size: 11.5px; opacity: .78; }
.msg-mail-h svg { width: 13px; height: 13px; }
.msg-mail-ch { font-weight: 600; letter-spacing: .01em; }
.msg-mail-to { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; opacity: .8; }
.msg-mail-subj { font-weight: 600; font-size: 13.5px; margin: 3px 0 2px; }
.msg-mail-st { font-size: 11px; opacity: .85; }
.msg-mail-st.ok { color: #4aa96c; }
.msg-mail-st.wait { color: var(--muted); }
.msg-mail-st.err { color: #e0654f; }
/* На «своём» пузыре (акцентная заливка) обычные красный/зелёный тонут — берём светлые
   тона той же семантики, иначе честный статус физически не прочитать. */
.msg.mine .msg-mail-st.wait { color: rgba(255, 255, 255, .78); }
.msg.mine .msg-mail-st.err { color: #ffd6cb; font-weight: 600; }
.msg.mine .msg-mail-st.ok { color: #cdf3dc; font-weight: 600; }
.msg.mine .msg-mail-h,
.msg.mine .msg-mail-to { color: rgba(255, 255, 255, .82); }

/* 🔗 CRMC-713 → 25.10 · КАНАЛ СООБЩЕНИЯ В ОБЪЕДИНЁННОЙ ЛЕНТЕ — ЗНАЧОК У ВРЕМЕНИ.
   Владелец: плашки «ClientsChat · Ромашка» над текстом — грязь. Краткая форма шапки канала
   переехала в мета-строку: значок 13px слева от времени, только у первого сообщения после
   смены канала (msgChanMarkHtml). Имя канала и беседы — в title/aria-label.
   Цвет — токен `--mc` (его печатает сервер / реестр каналов); мета-строка лежит ПОД пузырём,
   на фоне ленты, поэтому «светлой пары» для своего пузыря не нужно. */
.meta .msg-chan-mark {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 13px; height: 13px; line-height: 0; color: var(--mc, var(--muted)); cursor: default;
}
.meta .msg-chan-mark svg, .meta .msg-chan-mark svg.ic { width: 13px; height: 13px; }
.meta .msg-chan-mark .cc-app-glyph { width: 13px; height: 13px; border-radius: 3.5px; display: block; object-fit: cover; }
/* Светлая тема: фирменный зелёный/голубой на белом читается ниже 3:1 — темним ТОТ ЖЕ цвет,
   а не подменяем его своим (знак остаётся узнаваемым). Та же поправка у значков полосы. */
html[data-theme="light"] .meta .msg-chan-mark,
html[data-theme="light"] .crm-chan-seg .crm-chan-b > svg {
  color: color-mix(in srgb, var(--mc, var(--primary)) 74%, #000);
}

/* Чип «Объединено · N» в шапке чата — он же вход в управление связкой. */
/* Длинный статус («был(а) в сети сегодня в …») сжимает соседей ряда — чип не сжимается и не
   переносит «N» на вторую строку: ужимается и режется многоточием статус, а не счётчик. */
.thread-link { display: inline-flex; align-items: center; flex: none; }
.conv-link-chip {
  display: inline-flex; align-items: center; gap: 5px; cursor: pointer; white-space: nowrap;
  padding: 1px 8px 1px 6px; border-radius: 999px; font-size: 11.5px; line-height: 18px;
  color: var(--primary-2, var(--primary)); border: 0;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
  transition: background .14s ease;
}
.conv-link-chip:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); }
.conv-link-chip svg { width: 13px; height: 13px; }
/* Метка в строке списка чатов: беседа входит в объединённую ленту — видно ДО открытия. */
.conv-link-mark {
  display: inline-flex; align-items: center; gap: 2px; margin-left: 5px; flex: none;
  font-size: 10.5px; line-height: 15px; padding: 0 5px 0 3px; border-radius: 999px;
  color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 20%, transparent);
}
.conv-link-mark svg { width: 11px; height: 11px; }

/* Окно «Это тот же клиент»: список бесед связки, подсказки, выход «Разъединить». */
.cl-head { font-size: 11.5px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); margin: 4px 0 -2px; }
.cl-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 10px;
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.cl-main { flex: 1 1 auto; min-width: 0; }
.cl-name { font-size: 13.5px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl-sub { display: flex; align-items: center; gap: 8px; margin-top: 3px; min-width: 0; }
.cl-ch { display: inline-flex; align-items: center; gap: 4px; flex: none; font-size: 11.5px;
  font-weight: 600; color: var(--text-dim, var(--muted)); }
/* 🔗 25.10: значок мессенджера СЛЕВА у каждой строки беседы (окно связки, «Мессенджеры · N»,
   окно «Привязать чат») — WhatsApp от Telegram отличается с первого взгляда. Акцент-плитка
   по канону accent: подложка 13% + кольцо 22% цвета канала, глиф — цветом канала. */
.cl-ic { --mc: var(--muted); width: 34px; height: 34px; flex: none; border-radius: 10px;
  display: inline-flex; align-items: center; justify-content: center; color: var(--mc);
  background: color-mix(in srgb, var(--mc) 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mc) 22%, transparent); }
.cl-ic svg { width: 18px; height: 18px; }
.cl-ch svg { width: 12px; height: 12px; }
.cl-why { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cl-here { font-size: 11.5px; color: var(--muted); flex: none; }
.cl-note { font-size: 12px; line-height: 1.45; color: var(--muted); }
/* Кнопки окна связки — один размерный класс ряда (--ctl-*, канон control-size).
   `.cl-pick` («Выбрать беседу вручную») носит ту же форму, что и `.cl-off`: это не главное
   действие, а спокойный выход из пустой подсказки. */
.cl-add, .cl-off, .cl-pick {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; cursor: pointer;
  height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs); font-weight: 600;
  padding: 0 12px; flex: none; border: 0; color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
  transition: background .14s ease;
}
.cl-add:hover, .cl-off:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); }
.cl-add[disabled], .cl-off[disabled], .cl-pick[disabled] { opacity: .55; cursor: default; }
.cl-off, .cl-pick { width: 100%; color: var(--text); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.cl-off:hover, .cl-pick:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.cl-off svg, .cl-pick svg { width: 15px; height: 15px; opacity: .8; }
/* 🔗 omni-person §3.2 · строка беседы — ВХОД в неё (окно связки, «Переписки · N» в профиле
   и карточке контакта). Одна строка `.cl-row` на все три места; кликабельность — атрибутом. */
.cl-row[data-clopen], .cl-row[data-cluser], .cl-row[data-clpick] { cursor: pointer; transition: background .14s ease; }
.cl-row[data-clopen]:hover, .cl-row[data-cluser]:hover, .cl-row[data-clpick]:hover { background: color-mix(in srgb, var(--text) 6%, var(--panel-2)); }
.cl-row[data-clopen]:focus-visible, .cl-row[data-cluser]:focus-visible, .cl-row[data-clpick]:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }
.cl-row.busy { opacity: .6; pointer-events: none; }
/* Окно «Привязать чат» (владелец 26.10: «куча Андреев, кто из них кто? дай посмотреть аватарку
   и что внутри»). Слева список: лицо со значком мессенджера, имя, время, ник или номер, последняя
   фраза. Справа — переписка выбранного чата и одна кнопка «Привязать». Телефон — одна колонка,
   `.cla-one` = открыта переписка. Поиск и кнопка — размерный класс ряда (--ctl-*). */
.cla-box { max-width: none; width: min(980px, 96vw); height: min(720px, 90vh); max-height: none; }
.cla-body { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(300px, 380px) minmax(0, 1fr); }
.cla-side { display: flex; flex-direction: column; min-height: 0; min-width: 0; border-right: 1px solid var(--line); }
.cla-top { display: flex; flex-direction: column; gap: 8px; padding: 12px 12px 8px; }
.cla-search { display: flex; align-items: center; gap: 8px; height: var(--ctl-h); padding: 0 10px;
  border-radius: var(--ctl-r); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); cursor: text; }
.cla-search svg { width: 15px; height: 15px; flex: none; color: var(--muted); }
.cla-search input { flex: 1; min-width: 0; border: 0; outline: 0; background: transparent; color: var(--text);
  font: inherit; font-size: var(--ctl-fs); height: 100%; padding: 0; }
.cla-search:focus-within { box-shadow: inset 0 0 0 1.5px var(--primary); }
.cla-top > .cla-filt { align-self: flex-start; }
.cla-filt[hidden] { display: none; }
.cla-fi { --mc: var(--muted); width: 16px; height: 16px; flex: none; display: inline-flex; align-items: center;
  justify-content: center; color: var(--mc); }
.cla-fi svg { width: 15px; height: 15px; }
.cla-fi .cc-app-glyph, .cla-badge .cc-app-glyph { width: 100%; height: 100%; border-radius: 4px; object-fit: cover; display: block; }
.cla-list { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; gap: 2px; padding: 0 8px 10px; }
.cla-sec { margin: 10px 6px 4px; }
.cla-sec:first-child { margin-top: 2px; }
.cla-row { display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: 10px; cursor: pointer;
  transition: background .14s ease; }
.cla-row:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }
.cla-row.on { background: color-mix(in srgb, var(--primary) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent); }
.cla-avw { position: relative; flex: none; width: 42px; height: 42px; }
.cla-av { position: relative; width: 42px; height: 42px; flex: none; border-radius: 50%; overflow: hidden;
  display: flex; align-items: center; justify-content: center; font-weight: 600; font-size: 15px;
  background: var(--acc-grad); color: #fff; }
.cla-av-lg { width: 44px; height: 44px; }
.cla-badge { --mc: var(--muted); position: absolute; right: -3px; bottom: -3px; width: 18px; height: 18px;
  border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; color: var(--mc);
  background: color-mix(in srgb, var(--mc) 16%, var(--panel)); box-shadow: 0 0 0 2px var(--panel); }
.cla-badge svg { width: 11px; height: 11px; }
.cla-badge.app { overflow: hidden; background: var(--panel); }
.cla-main { flex: 1; min-width: 0; }
.cla-r1 { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.cla-nm { min-width: 0; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cla-tag { flex: none; font-size: 11px; font-weight: 600; color: var(--muted); }
.cla-at { margin-left: auto; padding-left: 6px; flex: none; font-size: 11.5px; color: var(--muted); }
.cla-r2 { display: flex; gap: 6px; margin-top: 2px; min-width: 0; font-size: 12.5px; color: var(--muted); }
.cla-hd { flex: none; max-width: 55%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 500; color: var(--text-dim, var(--text)); }
.cla-sn { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cla-pane { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.cla-ph { display: flex; align-items: center; gap: 10px; padding: 10px 14px; border-bottom: 1px solid var(--line); }
.cla-ph > .cla-back { display: none; }
.cla-pch { display: flex; align-items: center; gap: 6px; margin-top: 2px; min-width: 0; font-size: 12.5px; color: var(--muted); }
.cla-pch > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cla-feedw { flex: 1; min-height: 0; overflow: auto; display: flex; flex-direction: column; padding: 12px 14px; }
.cla-feed { margin-top: 0; }
.cla-feed .tip-cm-bubble { flex: 0 1 auto; max-width: 78%; }
.cla-feed .tip-cm.mine { flex-direction: row-reverse; }
.cla-feed .tip-cm.mine .tip-cm-bubble { background: color-mix(in srgb, var(--primary) 10%, var(--panel-2)); }
.cla-pane-empty { margin: auto; padding: 24px; text-align: center; font-size: 13px; color: var(--muted); }
.cla-foot { display: flex; align-items: center; justify-content: flex-end; gap: 12px; padding: 10px 14px;
  border-top: 1px solid var(--line); }
.cla-fnote { flex: 1; min-width: 0; font-size: 12.5px; color: var(--muted); }
.cla-go { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--ctl-h);
  padding: 0 18px; border: 0; border-radius: var(--ctl-r); font: inherit; font-size: var(--ctl-fs); font-weight: 600;
  cursor: pointer; background: var(--acc-fill, var(--primary)); color: #fff; }
.cla-go svg { width: 15px; height: 15px; }
.cla-go:disabled { opacity: .55; cursor: default; }
@media (max-width: 720px) {
  .cla-box { width: 100%; height: 100dvh; }
  .cla-body { grid-template-columns: minmax(0, 1fr); }
  .cla-side { border-right: 0; }
  .cla-pane { display: none; }
  .cla-box.cla-one .cla-side { display: none; }
  .cla-box.cla-one .cla-pane { display: flex; }
  .cla-ph > .cla-back { display: inline-flex; }
  .cla-foot .cla-go { flex: 1; }
}
.pcv-empty { margin: 2px 2px 8px; }
.pcv-attach { margin-top: 8px; }
.cl-add.pcv-attach { width: 100%; }
.cl-add.pcv-attach svg { width: 15px; height: 15px; }
/* «Не он» рядом с «Объединить»: спокойная кнопка того же размерного класса (--ctl-*). */
.cl-acts { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.cl-no {
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs); font-weight: 600;
  padding: 0 12px; flex: none; border: 0; color: var(--muted); background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line); transition: background .14s ease, color .14s ease;
}
.cl-no:hover { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
.cl-no[disabled] { opacity: .55; cursor: default; }
/* Слабое совпадение (только имя) — имя приглушено: это вопрос, а не утверждение. */
.cl-weak .cl-name { color: var(--text-dim, var(--muted)); font-weight: 550; }
/* «Переписки · N» у человека: список строк, шеврон входа, одна кнопка «Объединить в одну ленту». */
.pcv-list { display: flex; flex-direction: column; gap: 6px; }
.pcv-chev { display: inline-flex; flex: none; color: var(--muted); }
.pcv-chev svg { width: 16px; height: 16px; }
.pcv-more { font-size: 12px; color: var(--muted); margin: 6px 2px 0; }
.cl-add.pcv-merge { width: 100%; margin-top: 8px; }
.cl-add.pcv-merge svg { width: 15px; height: 15px; }
.crm-convs .pcv-list { margin-top: 6px; }
/* 🔗 25.10 · раздел «Мессенджеры» профиля — КОРОТКИЕ строки той же .cl-row: без плашки, значок
   мессенджера кружком его цвета (наш чат — значок приложения) и слово мессенджера; тихая подпись
   (.cl-st) — только у одинаковых строк (пространство или имя чата); «Отвязать» проявляется по
   наведению (на касании — всегда). */
#userProfileConvs { max-width: 560px; }
.pcv-list.pcv-short { gap: 2px; margin-top: 4px; }
.cl-row.cl-short { flex-wrap: nowrap; min-height: 48px; padding: 7px 8px; gap: 12px; background: transparent; box-shadow: none; }
.cl-short .cl-ic { width: 34px; height: 34px; border-radius: 50%; }
.cl-short .cl-ic svg { width: 18px; height: 18px; }
.cl-short .cl-ic.cl-ic-app { background: transparent; box-shadow: none; }
.cl-short .cl-ic .cc-app-glyph { width: 34px; height: 34px; border-radius: 50%; display: block; object-fit: cover; }
.cl-short .cl-name { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.cl-short .cl-sw { flex: none; font-weight: 600; }
.cl-short .cl-st { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12.5px; font-weight: 400; color: var(--muted); }
.pcv-unlink { flex: none; height: 28px; padding: 0 10px; border: 0; border-radius: 8px; cursor: pointer;
  font: inherit; font-size: 12px; font-weight: 600; color: var(--text-dim, var(--muted)); background: transparent;
  opacity: 0; transition: opacity .12s ease, background .12s ease, color .12s ease; }
.cl-row:hover .pcv-unlink, .cl-row:focus-within .pcv-unlink, .pcv-unlink:focus-visible { opacity: 1; }
.pcv-unlink:hover { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
.pcv-unlink[disabled] { opacity: .5; cursor: default; }
@media (hover: none) { .pcv-unlink { opacity: 1; } }
/* Светлая тема: фирменный зелёный/голубой на белом — темним ТОТ ЖЕ цвет (как у значков полосы). */
html[data-theme="light"] .cl-short .cl-ic { color: color-mix(in srgb, var(--mc) 74%, #000); }
@media (max-width: 560px) {
  .cl-row { flex-wrap: wrap; }
  .cl-acts { margin-left: auto; }
}

/* ══════════════════════════════════════════════════════════════════════════════
   🔴🔴 БЕСКОНЕЧНЫЕ ПУЛЬСАЦИИ — ГЛАВНЫЙ ПОЖИРАТЕЛЬ CPU В ПРОСТОЕ (CLIE-444)
   ------------------------------------------------------------------------------
   Жалоба владельца: «когда комп нагружен, телеграм и ватсап не тормозят, а наше
   тормозит». ЗАМЕРЕНО на ЕГО аккаунте (944 задачи, доска открыта, НИЧЕГО не трогаем),
   CPU процессов рендерера, медиана 10 замеров:
       как есть ................................ 139.7 %
       выключить бесконечные анимации .......... 18.4 %   ← −121 п.п. (87% расхода!)
       + спрятать 2790 карточек из 2830 ........ 19.1 %   ← объём DOM НЕ виноват вовсе
   CPU-профиль движка: 92.1% «(program)» (стиль/раскладка/отрисовка), JS ≈ 0%,
   сборщик мусора 0.6%. То есть горит НЕ наш код, а покадровая перерисовка.
   Причина: 16 бесконечных анимаций анимируют `box-shadow` — его нельзя отдать
   видеокарте, каждый кадр перерисовывается заново, 60 раз в секунду, пока элемент
   виден. А висят они ПОКАДРОВО НА КАЖДОЙ ЗАДАЧЕ: точка «ИИ работает», пульс таймера,
   «ИИ ждёт ответа». У владельца таких элементов на экране десятки.

   ЛЕЧЕНИЕ: та же картинка, но композитными свойствами (transform/opacity на
   псевдоэлементе-кольце) — работа уходит на GPU. Проверено замером в одном прогоне:
       106.2 % → 54.9 %  (−51 п.п.)
   ══════════════════════════════════════════════════════════════════════════════ */
.ai-work-dot, .conv-mark.conv-ai-work .caw-dot, .ai-sub-dot.work, .ai-sub-dot.queued,
.ai-sub-dot.await, .ai-sub-dot.pending, .ai-await-dot, .tip-ai-dot, .cc-timer-pip,
.ai-sched-dot, .dash-live-dot, .ea-livedot, .dvai-th-live {
  animation: none !important;      /* больше НЕ анимируем box-shadow покадрово */
  position: relative;
}
/* 15.10.2026: четыре точки, забытые этой дверью, — те же 60 кадров/с главного потока. Замер на
   движке ПК (Electron 33), карточка задачи открыта: одна `.ai-sched-dot` («В очереди», «ИИ
   начнёт…») держала 60 кадров/с и 19 % потока, без неё — 1 кадр/с. Кольцо красится currentColor,
   поэтому у точки цвет кольца = цвет её заливки. */
.ai-sched-dot { color: #8196b2; }
.dash-live-dot, .ea-livedot { color: var(--ok); }
.dvai-th-live { color: var(--primary); }
/* 22.10.2026 · .cc-timer-pip: общий список выше стоит ПОЗЖЕ её правила (absolute в углу монеты) и
   ставил position: relative — точка выпадала в поток справа от монеты, а кольцо (currentColor)
   красило её чернилами: замер кадров «Проектов» (244,245,250) тёмной / (18,19,31) светлой.
   Угол монеты и цвет таймера (var(--info), как бейдж .tw-pill-timer) — обратно. */
.cc-timer-pip { position: absolute; color: var(--info); }
.ai-work-dot::after, .conv-mark.conv-ai-work .caw-dot::after, .ai-sub-dot.work::after,
.ai-sub-dot.queued::after, .ai-sub-dot.await::after, .ai-sub-dot.pending::after,
.ai-await-dot::after, .tip-ai-dot::after, .cc-timer-pip::after,
.ai-sched-dot::after, .dash-live-dot::after, .ea-livedot::after, .dvai-th-live::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: currentColor; pointer-events: none; z-index: -1;
  animation: ccPulseRing 1.8s ease-out infinite;
  will-change: transform, opacity;
}
@keyframes ccPulseRing {
  0%   { transform: scale(1);   opacity: .5; }
  70%  { transform: scale(2.6); opacity: 0; }
  100% { transform: scale(2.6); opacity: 0; }
}
/* 15.10.2026 · ЗВОНКОВЫЕ МЕТКИ — ТОЛЬКО ВИД (владелец: «логику не трогай, чтобы не ухудшить связь,
   UI можно трогать»). Те же точки с расходящейся тенью, что выше: «Созвон» в строке чата
   (.ccp-dot), баннер звонка в переписке (.tcb-dot), «Ая в созвоне» (.gc-agent-dot), запись
   (.gc-rec-blob), «эфир» перевода (.lt-live-dot), «В эфире» вебинара (.st-live-dot). Замер на
   движке ПК: одна видимая .ccp-dot — до 34 % окна и 11 % видеокарты; на кольце — композитор.
   Свой ритм каждой сохранён, «Ая думает» по-прежнему 1 с. z-index:0 — кольцо рисуется в слое
   самой точки: эти точки лежат на пилюлях со СВОЕЙ заливкой, и кольцо с z-index:-1 ушло бы под неё. */
.conv-call-pill .ccp-dot, .thread-call-banner .tcb-dot, .gc-agent-dot, .gc-rec-blob,
.lt-live-dot, .st-live-dot {
  animation: none !important;
  position: relative; z-index: 0;
}
/* Цвет кольца = цвет прежней тени (он не зависел от темы), а не цвет самой точки: в светлой теме
   --ok тёмно-зелёный, и кольцо им вышло бы серо-зелёным вместо мятного. */
.conv-call-pill .ccp-dot, .thread-call-banner .tcb-dot { color: rgb(93,202,165); }
.gc-agent-dot { color: var(--cm-8c9eff, rgb(140,158,255)); }
.gc-rec-blob, .st-live-dot { color: rgb(239,68,68); }
.lt-live-dot { color: rgb(224,72,61); }
.conv-call-pill .ccp-dot::after, .thread-call-banner .tcb-dot::after, .gc-agent-dot::after,
.gc-rec-blob::after, .lt-live-dot::after, .st-live-dot::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: currentColor; pointer-events: none; z-index: -1;
  animation: ccPulseRing 1.8s ease-out infinite;
  will-change: transform, opacity;
}
.gc-agent-dot::after { animation-duration: 2.6s; }
.gc-agent-pill.thinking .gc-agent-dot::after { animation-duration: 1s; }
.gc-rec-blob::after { animation-duration: 2s; }
.lt-live-dot::after { animation-duration: 1.6s; }
.st-live-dot::after { animation-duration: 2.4s; }
.lt-panel.paused .lt-live-dot::after { animation: none; opacity: 0; }
/* Точка свёрнутого звонка САМА псевдоэлемент (.call-status::before) — второго у неё нет, поэтому
   кольцо рисует .call-status::after ровно поверх неё: отступ пилюли слева 7 px, точка 7×7. */
.call-overlay.minimized.in-call .call-status::before { animation: none; }
.call-overlay.minimized.in-call .call-status::after {
  content: ""; position: absolute; left: 7px; top: calc(50% - 3.5px); width: 7px; height: 7px;
  border-radius: 50%; background: #34d399; pointer-events: none;
  animation: ccPulseRing 2.2s ease-out infinite;
  will-change: transform, opacity;
}
@media (prefers-reduced-motion: reduce) {
  .conv-call-pill .ccp-dot::after, .thread-call-banner .tcb-dot::after, .gc-agent-dot::after,
  .gc-rec-blob::after, .lt-live-dot::after, .st-live-dot::after,
  .call-overlay.minimized.in-call .call-status::after { animation: none; opacity: 0; }
}
/* wipPulse анимирует opacity (свойство композитное), но на svg.ic без собственного слоя
   браузер всё равно перерисовывает. will-change поднимает на слой — вид не меняется. */
.tasks-list .tst-running svg.ic, .tasks-list .task-chip.wip .ic, .tw-pill.tw-pill-timer .ic,
.tw-pill.tw-pill-worktime.running::after, .tw-run-btn.active svg.ic,
.task-chip.wip .ic, .tw-pill-ai .ic {
  will-change: opacity;
}

/* 🔴🔴 ГЛАВНОЕ: НЕ АНИМИРОВАТЬ, КОГДА НА НАС НЕ СМОТРЯТ.
   У десктопа НАМЕРЕННО выключен троттлинг фона (desktop/main.js: backgroundThrottling:false —
   иначе Chromium морозит таймеры свёрнутого окна и рвётся WS-keepalive → пропадают
   уведомления). Побочный эффект: пульсации крутятся на ПОЛНОЙ скорости, даже когда
   пользователь работает в другой программе — то есть мы жжём ядро процессора в фоне.
   Именно это владелец и описывает: «когда комп нагружен, тормозим только мы».
   Класс cc-idle ставит app.js по blur/visibilitychange. Таймеры и сокет НЕ затронуты —
   это чистая косметика, keepalive живёт своей жизнью.
   🔴 Справа — метка `.cc-anim`, а НЕ `*` (разбор торможений 22.10.2026): с `*` переключение класса
   на body пересчитывало стиль всего документа на каждый alt-tab (37 с за 48 ч). Метку ставит
   ccOffviewWatch каждому узлу с бесконечной анимацией (по `animationstart`), пересчёт — только им. */
body.cc-idle .cc-anim, body.cc-idle .cc-anim::before, body.cc-idle .cc-anim::after {
  animation-play-state: paused !important;
}
/* 🔴🔴 И НЕ АНИМИРОВАТЬ ТО, ЧТО ЗА КРАЕМ (15.10.2026). Класс cc-offview ставит ccOffviewWatch
   (app.js) на узел с БЕСКОНЕЧНОЙ анимацией, пока он вне видимой области: прокручен за край
   списка, за краем окна, в display:none. Такой узел движок не рисует и потому не может отдать
   его анимацию видеокарте — крутит её на главном потоке 60 раз в секунду с полной пересборкой
   слоёв (замер: значки «Идёт таймер» за краем «Моих задач» — 60 кадров/с, в виду — 2). На экране
   ничего не меняется: узел, который видно, класса не несёт. */
.cc-offview, .cc-offview::before, .cc-offview::after {
  animation-play-state: paused !important;
}
/* Уважение к системной настройке «уменьшить движение» — заодно снимает весь этот расход. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-iteration-count: 1 !important; }
}

/* ═══ 📦 CRMC-410 · Мультивыбор лидов и сделок (доска + список) ══════════════════════════════
   Ядро выбора общее с задачами (`.tw-card-sel`, `.tw-card.tsel`, `#boardBulkBar`) — здесь только
   то, чем CRM отличается: галка в строках списка и правило «не отбирать экран, пока выбор не
   начат». Все цвета — токены темы, поэтому светлая и тёмная выглядят одинаково выверенно. */

/* ДОСКА. Галка живёт в общем слоте быстрых действий (`.tw-card-acts`, opacity:0) и проявляется
   ПОД КУРСОРОМ. Начался выбор — показываем её на ВСЕХ карточках и отодвигаем содержимое, чтобы
   аватар ответственного не оказался под ней. Сама галка при этом НЕ двигается → курсор не
   промахивается (грабля каталога проектов, где галка встала в поток и строка уезжала вбок). */
body.cc-tsel-mode .lead-card .tw-card-acts,
body.cc-tsel-mode .deal-card .tw-card-acts { opacity: 1; }
body.cc-tsel-mode .lead-card,
body.cc-tsel-mode .deal-card { padding-right: 40px; }

/* СПИСОК. Слот галки абсолютный, а сдвиг делает ВСЯ таблица разом — и шапка, и строки, одним
   padding-left. Сетка колонок не пересобирается, поэтому столбцы не разъезжаются. */
.lead-row, .deal-row { position: relative; }
.crm-row-sel { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); display: none; }
body.cc-tsel-mode .crm-row-sel { display: inline-flex; }
body.cc-tsel-mode .lead-list-head, body.cc-tsel-mode .lead-row,
body.cc-tsel-mode .deal-list-head, body.cc-tsel-mode .deal-row { padding-left: 43px; }
body.cc-tsel-mode .lead-row, body.cc-tsel-mode .deal-row { cursor: pointer; }
.lead-row.tsel, .deal-row.tsel { background: color-mix(in srgb, var(--primary) 9%, transparent); }
.lead-row.tsel::after, .deal-row.tsel::after {
  content: ""; position: absolute; inset: 1px; border: 1.5px solid var(--primary);
  border-radius: 8px; pointer-events: none;
}

/* ↩️ Чип «Отменить» в шапке «Продаж»: отмена, которая переживает перезагрузку страницы.
   Спокойный контур, а не заливка — он висит до 15 минут и кричать ему нельзя; акцент даёт
   только цифра и подсветка при наведении. Оба состояния одинаково выверены в светлой и тёмной
   теме, потому что взяты из токенов (`--primary`, `--line`, `--panel-2`). */
#salesWorkspace .crm-undo-chip { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); }
#salesWorkspace .crm-undo-chip:hover:not([disabled]) { color: var(--primary); border-color: color-mix(in srgb, var(--primary) 42%, transparent); }
#salesWorkspace .crm-undo-chip .ic { width: 15px; height: 15px; }
#salesWorkspace .crm-undo-chip .cu-n {
  min-width: 18px; padding: 0 5px; border-radius: 999px; font-size: 11.5px; font-weight: 700;
  line-height: 17px; text-align: center; color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
}
#salesWorkspace .crm-undo-chip.busy, #salesWorkspace .crm-undo-chip[disabled] { opacity: .5; pointer-events: none; }
/* Узкая шапка: сначала прячем подпись (остаются стрелка + число + тултип), потом число. */
#salesWorkspace .tw-head.fit-2 .crm-undo-chip span:not(.cu-n) { display: none; }
#salesWorkspace .tw-head.fit-4 .crm-undo-chip .cu-n { display: none; }

/* Пачка едет — бар не принимает второй тап (двойной тап = ровно один эффект) и честно
   показывает прогресс вместо замершего счётчика. */
.board-bulk-bar.busy .sb-act, .board-bulk-bar.busy .sb-all { opacity: .45; pointer-events: none; }
.board-bulk-bar .sb-act[disabled], .board-bulk-bar .sb-all[disabled] { opacity: .45; pointer-events: none; }
.board-bulk-bar.busy .sb-count { color: var(--primary); }

/* ═══════════════════════════════════════════════════════════════════════════
   👁 CLIE-550 · «кто посмотрел и досмотрел ли» + подпись к медиа + одноразовый.
   Токены базы (--panel/--line/--muted/--primary) — значит обе темы и любой концепт
   получают это без второй палитры. Никаких левых полосок-реек: акцент несут иконка,
   слово и мягкая подложка (доктрина CLIE-483).
   ═══════════════════════════════════════════════════════════════════════════ */

/* Чип в мета-строке своего сообщения: глаз + сколько посмотрели (+ сколько досмотрели). */
.meta .msg-views {
  display: inline-flex; align-items: center; gap: 3px;
  margin-right: 6px; padding: 1px 6px 1px 5px;
  border: 1px solid transparent; border-radius: 999px;
  background: color-mix(in srgb, var(--fg) 6%, transparent);
  color: var(--muted); font: inherit; font-size: 11px; line-height: 16px;
  cursor: pointer; transition: background .14s var(--ease), color .14s var(--ease), border-color .14s var(--ease);
}
.meta .msg-views:hover {
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  border-color: color-mix(in srgb, var(--primary) 22%, transparent);
  color: var(--fg);
}
.meta .msg-views svg { width: 12px; height: 12px; opacity: .85; }
.meta .msg-views .mv-n { font-variant-numeric: tabular-nums; }
/* 🔴 CLIE-1585: «прочитали N» — акцентные чернила на подложке меты (3.84:1). */
.meta .msg-views .mv-done {
  display: inline-flex; align-items: center; gap: 1px;
  color: var(--primary-2, var(--primary)); font-variant-numeric: tabular-nums;
}
.meta .msg-views .mv-done svg { width: 11px; height: 11px; opacity: 1; }

/* Список зрителей — тот же язык, что у прочих диалогов (панель + хэйрлайн + мягкая тень). */
.mv-ov {
  position: fixed; inset: 0; z-index: 3000;
  display: flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .34); backdrop-filter: blur(2px);
  animation: mvIn .14s var(--ease);
}
@keyframes mvIn { from { opacity: 0 } to { opacity: 1 } }
.mv-box {
  width: min(380px, calc(100vw - 32px)); max-height: min(70vh, 560px);
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
  box-shadow: var(--shadow-3);
}
.mv-hd { display: flex; align-items: center; gap: 8px; padding: 14px 16px 10px; }
.mv-hd svg { width: 18px; height: 18px; color: var(--muted); }
.mv-hd h3 { margin: 0; font-size: 15px; font-weight: 650; letter-spacing: -.01em; }
.mv-list { overflow: auto; padding: 4px 8px 10px; }
.mv-empty { padding: 18px 8px 22px; text-align: center; color: var(--muted); font-size: 13px; }
.mv-row {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 8px; border-radius: 10px;
}
.mv-row + .mv-row { box-shadow: inset 0 1px 0 color-mix(in srgb, var(--line) 70%, transparent); }
.mv-av {
  flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--panel-2); color: var(--muted);
  font-size: 11px; font-weight: 600; background-size: cover; background-position: center;
}
.mv-av.has-img { color: transparent; }
.mv-txt { min-width: 0; flex: 1 1 auto; }
.mv-name { font-size: 13px; font-weight: 550; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mv-sub { font-size: 11.5px; color: var(--muted); }
.mv-sub.ok { color: var(--primary); }
.mv-at { flex: 0 0 auto; font-size: 11px; color: var(--muted); }

/* 🔥 Одноразовый: пометка на живом пузыре и плашка на месте сгоревшего.
   🔴 Это ТОТ САМЫЙ чип со скрина владельца (задача «Контрастность», 10.09.2026): он живёт
   ВНУТРИ пузыря, а красился токеном ХОЛСТА `--muted` — на залитом акцентом своём пузыре
   1.45:1 (светлая) и 1.40:1 (тёмная) при норме 4.5. Берём чернила и подложку У ПУЗЫРЯ:
   на чужом/медийном пузыре это прежний янтарь, на своём — читаемая пара. */
.once-hint {
  display: inline-flex; align-items: center; gap: 5px;
  margin-top: 6px; padding: 2px 8px 2px 6px; border-radius: 999px;
  background: var(--once-bg, color-mix(in srgb, var(--warn, #E5A23C) 12%, transparent));
  box-shadow: inset 0 0 0 1px var(--once-ring, color-mix(in srgb, var(--warn, #E5A23C) 24%, transparent));
  color: var(--bub-ink-dim, var(--muted)); font-size: 11.5px; line-height: 16px;
}
/* 🔴 кант чипа делает его границу видимой (WCAG 1.4.11): у --bub-line 42% белого это
   1.8:1 к заливке пузыря, поэтому у ЧИПА кант плотнее — он единственная его граница. */
.msg.mine .bubble:not(.has-media) .once-hint { --once-bg: var(--bub-tint); --once-ring: rgba(255,255,255,.72); }
.once-hint svg { width: 12px; height: 12px; }
.msg-burned { display: inline-flex; align-items: center; gap: 6px; color: var(--bub-ink-dim, var(--muted)); }
.msg-burned svg { width: 14px; height: 14px; opacity: .8; }
.msg-burned i { font-style: italic; }

/* Тумблер «Одноразовый» в рекордере кружка + подсказка о подписи из поля ввода. */
.circle-rec-controls .circle-once { display: inline-flex; align-items: center; gap: 6px; }
.circle-rec-controls .circle-once svg { width: 15px; height: 15px; }
.circle-rec-controls .circle-once.on {
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent);
}
.circle-cap-hint {
  max-width: min(420px, 86vw); margin: 6px auto 0; padding: 5px 10px;
  border-radius: 10px; background: rgba(255, 255, 255, .10); color: #fff;
  font-size: 12px; line-height: 1.35; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}


/* ══ СРЕД-31·2 · ВЫХОДЫ ИЗ СОСТОЯНИЙ СРЕДЫ ═══════════════════════════════════════════
   Отмена · история файла · ревью ветки · удаление веток · «кто где» · разбор конфликта.
   🔴 Акценты — иконка + СЛОВО + мягкая подложка с хэйрлайн-кольцом, в строке списка точка
   (левых полос-реек нет: CLIE-483). Ширины не прибиты: окна тянутся мышью (CRMC-406), а
   списки живут внутри `.modal-body`, который скроллит себя сам (CLIE-620).                */

/* ── плашка «Идёт слияние»: состояние видно ТАМ, где человек его встретит ────────────── */
.dvs-mgbanner {
  display: flex; align-items: flex-start; gap: 10px; margin: 8px 8px 4px; padding: 10px 12px;
  border-radius: 12px; background: color-mix(in srgb, var(--warning) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 26%, transparent);
}
.dvs-mgb-ic { flex: none; display: inline-flex; color: var(--warning); margin-top: 1px; }
.dvs-mgb-ic .ic { width: 17px; height: 17px; }
.dvs-mgb-tx { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dvs-mgb-tx b { font-size: 12.5px; font-weight: 650; color: var(--text); }
.dvs-mgb-tx span { font-size: 11.5px; line-height: 1.4; color: var(--text-dim); }
.dvs-mgb-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.dvs-mgbanner .dvs-mgb-tx { gap: 3px; }
.dvs-mgbanner .v2prev-primary, .dvs-mgbanner .v2prev-btn { height: 26px; font-size: 12px; }

/* ветка в шапке, пока слияние не доведено до конца */
.dvs-branch.cf {
  color: var(--warning);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  border-color: color-mix(in srgb, var(--warning) 30%, transparent);
}
.dvs-branch.cf:hover { background: color-mix(in srgb, var(--warning) 18%, transparent); }

/* ── строка изменений: конфликт · история · отмена ──────────────────────────────────── */
.dvs-chgrow.cf {
  background: color-mix(in srgb, var(--warning) 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 20%, transparent);
}
.dvs-chgcf { flex: none; display: inline-flex; align-items: center; color: var(--warning); padding-left: 6px; }
.dvs-chgcf .ic { width: 15px; height: 15px; }
.dvs-chgtag {
  flex: none; font-size: 10.5px; line-height: 1; padding: 3px 6px; border-radius: 999px;
  color: var(--warning); background: color-mix(in srgb, var(--warning) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 26%, transparent);
}
.dvs-chgact {
  flex: none; height: 24px; margin-right: 6px; padding: 0 9px; border-radius: 7px; cursor: pointer;
  font: inherit; font-size: 11.5px; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line);
  transition: background 120ms ease, border-color 120ms ease;
}
.dvs-chgact:hover { background: var(--hover); border-color: color-mix(in srgb, var(--warning) 40%, var(--line)); }
.dvs-chgico, .dvs-chgundo {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 7px; border: 1px solid transparent;
  background: transparent; color: var(--muted); cursor: pointer; opacity: 0;
  transition: opacity 120ms ease, background 120ms ease, color 120ms ease;
}
.dvs-chgico .ic, .dvs-chgundo .ic { width: 14px; height: 14px; }
/* Иконки строки не отбирают экран: всплывают на наведении/фокусе, но НИКОГДА не мёртвые —
   с клавиатуры доступны всегда (иначе это «догадайся, как включить»). */
.dvs-chgrow:hover .dvs-chgico, .dvs-chgico:focus-visible { opacity: 1; }
.dvs-chgico:hover { background: var(--hover); color: var(--text); }
.dvs-chgundo { opacity: .75; margin-left: 2px; }
.dvs-chgundo:hover { opacity: 1; background: var(--hover); color: var(--text); }
.dvs-chgst.s-U { color: var(--warning); background: color-mix(in srgb, var(--warning) 14%, transparent); }
.dvs-chghead .dvs-chgref em {
  font-style: normal; font-size: 10px; font-weight: 700; margin-left: 3px; color: var(--accent);
}
/* «История» в строке вкладок — появляется, только когда файл открыт */
.dvs-histbtn {
  display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 9px; flex: none;
  border: 1px solid var(--line); border-radius: 7px; background: transparent; color: var(--muted);
  font: inherit; font-size: 11.5px; cursor: pointer; transition: background 120ms ease, color 120ms ease;
}
.dvs-histbtn[hidden] { display: none; }
.dvs-histbtn:hover { background: var(--hover); color: var(--text); }
.dvs-histbtn .ic { width: 13px; height: 13px; }

/* ── ветки: третья строка «сейчас здесь» + иконки ревью/удаления ────────────────────── */
.dvbr-line3 {
  display: flex; align-items: center; gap: 5px; padding-left: 13px; max-width: 100%;
  font-size: 11.5px; line-height: 1.3; color: var(--accent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dvbr-line3 .ic { width: 12px; height: 12px; flex: none; }
.dvbr-ico {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 8px; cursor: pointer;
  border: 1px solid transparent; background: transparent; color: var(--muted);
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.dvbr-ico .ic { width: 14px; height: 14px; }
.dvbr-ico:hover { background: var(--hover); color: var(--text); border-color: var(--line); }
.dvbr-ico.del:hover { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, transparent); }

/* ── «кто на какой ветке прямо сейчас» ─────────────────────────────────────────────── */
.dvwho-row {
  display: flex; align-items: center; gap: 7px; padding: 6px 4px; border-radius: 8px;
  font-size: 12px; min-width: 0;
}
.dvwho-row:hover { background: var(--panel-2); }
.dvwho-dot {
  width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--ok);
}
.dvwho-dot.me { background: var(--accent); }
.dvwho-dot.off { background: color-mix(in srgb, var(--muted) 55%, transparent); }
.dvwho-who { flex: none; font-weight: 600; color: var(--text); }
.dvwho-mach { flex: 0 1 auto; min-width: 0; color: var(--text-dim); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvwho-br { flex: none; margin-left: auto; color: var(--muted); font-size: 11.5px; }
.dvwho-m { flex: none; color: var(--text-dim); font-size: 11px; }
.dvwho-row.off .dvwho-who, .dvwho-row.off .dvwho-br { color: var(--muted); }

/* ── отложенное ────────────────────────────────────────────────────────────────────── */
.dvst-row { display: flex; align-items: center; gap: 8px; padding: 7px 6px; border-radius: 9px; min-width: 0; }
.dvst-row:hover { background: var(--panel-2); }
.dvst-tx { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dvst-msg { font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvst-ago { font-size: 11px; color: var(--muted); }
.dvst-go {
  flex: none; height: 26px; padding: 0 10px; border-radius: 8px; cursor: pointer; font: inherit;
  font-size: 12px; color: var(--text); background: var(--panel-2); border: 1px solid var(--line);
}
.dvst-go:hover { background: var(--hover); }
.dvst-x {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: 8px; border: 1px solid transparent;
  background: transparent; color: var(--muted); cursor: pointer;
}
.dvst-x .ic { width: 14px; height: 14px; }
.dvst-x:hover { color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); }

/* ── общая подошва окон выходов ────────────────────────────────────────────────────── */
.dvcf-foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding-top: 12px; margin-top: 12px; border-top: 1px solid var(--line);
}

/* ── ⚔ разбор конфликта: три колонки, подписанные ИМЕНАМИ ВЕТОК ─────────────────────── */
/* 🔴 `.modal-box` капит себя `max-width:540px` — одной `width` его не перебить. Разбор
   конфликта — окно на ТРИ колонки кода: в 540px имена веток в подписях обрубались до
   «task…», а это ровно тот обрубок, который в продукте запрещён (CLIE-606). Ширину при
   этом НЕ прибиваем: окно тянется мышью, как любое другое (CRMC-406). */
.dvcf-box { width: min(1180px, 94vw); max-width: min(1180px, 94vw); }
.dvcf-files { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.dvcf-f {
  height: 26px; padding: 0 10px; border-radius: 999px; cursor: pointer; font: inherit; font-size: 12px;
  color: var(--text); background: var(--panel-2); border: 1px solid var(--line);
  transition: background 120ms ease, border-color 120ms ease;
}
.dvcf-f:hover { background: var(--hover); }
.dvcf-f.on {
  color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent);
  border-color: color-mix(in srgb, var(--primary) 30%, transparent);
}
.dvcf-cols { display: flex; align-items: stretch; gap: 10px; min-width: 0; }
.dvcf-col {
  flex: 1 1 0; min-width: 0; display: flex; flex-direction: column;
  border: 1px solid var(--line); border-radius: 12px; overflow: hidden; background: var(--panel);
}
.dvcf-col.mid { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.dvcf-t {
  display: flex; align-items: center; gap: 8px; padding: 7px 10px; min-width: 0;
  border-bottom: 1px solid var(--line); background: var(--panel-2);
}
.dvcf-t b {
  font-size: 12px; font-weight: 650; color: var(--text); min-width: 0; flex: 1 1 auto;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Кнопка ужимается раньше подписи: обрубленное ИМЯ ВЕТКИ хуже, чем короткая кнопка. */
.dvcf-take, .dvcf-hint { flex: 0 1 auto; min-width: 0; }
.dvcf-hint { font-size: 11px; color: var(--muted); }
.dvcf-take {
  margin-left: auto; flex: none; height: 22px; padding: 0 8px; border-radius: 6px; cursor: pointer;
  font: inherit; font-size: 11px; color: var(--text-dim); background: transparent; border: 1px solid var(--line);
  transition: background 120ms ease, color 120ms ease;
}
.dvcf-take:hover { background: var(--hover); color: var(--text); }
/* Высота колонок — доля ЭКРАНА, а не прибитые пиксели: окно тянется, и текст обязан тянуться с ним. */
.dvcf-code, .dvcf-ta {
  flex: 1 1 auto; margin: 0; min-height: 34vh; max-height: 52vh; overflow: auto;
  padding: 10px 12px; font-family: var(--mono, monospace); font-size: 12px; line-height: 1.55;
  color: var(--text); background: transparent; white-space: pre-wrap; word-break: break-word;
}
.dvcf-ta { border: 0; outline: none; resize: none; width: 100%; box-sizing: border-box; }
.dvcf-ta:focus { background: color-mix(in srgb, var(--primary) 4%, transparent); }
.dvcf-done { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 26px 12px; text-align: center; }
.dvcf-done .ic { width: 34px; height: 34px; color: var(--ok); }
.dvcf-done p { margin: 0; font-size: 13px; color: var(--text-dim); max-width: 42ch; line-height: 1.5; }

/* ── 👀 ревью ветки ────────────────────────────────────────────────────────────────── */
.dvrv-box { width: min(880px, 94vw); max-width: min(880px, 94vw); }
.dvrv-head { display: flex; flex-direction: column; gap: 5px; padding-bottom: 12px; border-bottom: 1px solid var(--line); }
.dvrv-nums { font-size: 13.5px; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.dvrv-state { font-size: 12.5px; }
.dvrv-state .ic { width: 14px; height: 14px; vertical-align: -2px; margin-right: 5px; }
.dvrv-ok { color: var(--ok); }
.dvrv-bad { color: var(--warning); }
.dvrv-dim { color: var(--muted); font-size: 12px; }
.dvrv-sec {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--muted); padding: 14px 2px 6px;
}
.dvrv-cms, .dvrv-fs { display: flex; flex-direction: column; gap: 1px; }
.dvrv-cm { display: flex; flex-direction: column; gap: 2px; padding: 7px 8px; border-radius: 9px; min-width: 0; }
.dvrv-cm:hover { background: var(--panel-2); }
.dvrv-cms1 { font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvrv-cms2 { font-size: 11.5px; color: var(--text-dim); }
.dvrv-f {
  display: flex; align-items: center; gap: 8px; padding: 7px 8px; border-radius: 9px; min-width: 0;
  border: 0; background: transparent; cursor: pointer; text-align: left; font: inherit; width: 100%;
}
.dvrv-f:hover { background: var(--panel-2); }
.dvrv-fn { flex: none; font-size: 12.5px; color: var(--text); }
.dvrv-fd { flex: 1 1 auto; min-width: 0; font-size: 11.5px; color: var(--text-dim);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvrv-fnum { flex: none; font-size: 11.5px; font-variant-numeric: tabular-nums; color: var(--muted); }
.dvrv-fnum em { font-style: normal; font-weight: 650; }
.dvrv-fnum em.a { color: var(--ok); }
.dvrv-fnum em.d { color: var(--danger); }
.dvrv-patch { margin-top: 12px; }

/* ── дифф построчно: одна отрисовка на все окна среды ──────────────────────────────── */
.dvp {
  border: 1px solid var(--line); border-radius: 10px; overflow: auto;
  max-height: 46vh; background: var(--panel); padding: 6px 0;
}
.dvp-l {
  font-family: var(--mono, monospace); font-size: 11.5px; line-height: 1.55;
  padding: 0 12px; white-space: pre-wrap; word-break: break-word; color: var(--text-dim);
}
.dvp-l.add { color: var(--ok); background: color-mix(in srgb, var(--ok) 9%, transparent); }
.dvp-l.del { color: var(--danger); background: color-mix(in srgb, var(--danger) 9%, transparent); }
.dvp-l.hunk { color: var(--muted); background: var(--panel-2); font-weight: 600; }

/* ── 🕘 история файла + «кто написал строку» ───────────────────────────────────────── */
.dvhs-box { width: min(860px, 94vw); max-width: min(860px, 94vw); }
.dvhs-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding-bottom: 12px; margin-bottom: 4px; border-bottom: 1px solid var(--line);
}
.dvhs-path { font-size: 11.5px; color: var(--muted); min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvhs-cs { display: flex; flex-direction: column; gap: 1px; }
.dvhs-c { display: flex; flex-direction: column; gap: 2px; padding: 8px; border-radius: 9px; min-width: 0; }
.dvhs-c:hover { background: var(--panel-2); }
.dvhs-c1 { font-size: 12.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dvhs-c2 { font-size: 11.5px; color: var(--text-dim); }
.dvhs-c3 { font-size: 11px; color: var(--muted); }
.dvbl { border: 1px solid var(--line); border-radius: 10px; overflow: auto; max-height: 60vh; background: var(--panel); padding: 4px 0; }
/* Имя автора печатается ОДИН раз на блок одинаковых строк: иначе оно повторяется двадцать
   раз подряд и перестаёт читаться как ответ на вопрос «кто это писал». */
.dvbl-who {
  font-size: 11px; color: var(--accent); padding: 7px 12px 2px; font-weight: 600;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dvbl-l { display: flex; gap: 8px; padding: 0 12px; min-width: 0; }
.dvbl-n {
  flex: none; width: 38px; text-align: right; color: var(--muted);
  font-family: var(--mono, monospace); font-size: 11px; line-height: 1.55;
  font-variant-numeric: tabular-nums; user-select: none;
}
.dvbl-tx {
  flex: 1 1 auto; min-width: 0; font-family: var(--mono, monospace); font-size: 12px;
  line-height: 1.55; color: var(--text); white-space: pre-wrap; word-break: break-word;
}

/* ── светлая тема: подложки на белом холсте берутся мягче, кольца — чуть плотнее ────── */
html[data-theme="light"] .dvs-mgbanner { background: color-mix(in srgb, var(--warning) 10%, #fff); }
html[data-theme="light"] .dvs-chgrow.cf { background: color-mix(in srgb, var(--warning) 7%, #fff); }
html[data-theme="light"] .dvp-l.add { background: color-mix(in srgb, var(--ok) 12%, #fff); }
html[data-theme="light"] .dvp-l.del { background: color-mix(in srgb, var(--danger) 12%, #fff); }
html[data-theme="light"] .dvcf-col.mid { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent); }

/* ═══ 📚 ВИКИ · ОЧЕРЕДЬ «НА ЧТО ИИ НЕ ОТВЕТИЛ» (часть 4) ═════════════════════════
   Секция «чего не хватает в вики»: мягкая подложка + хэйрлайн-кольцо, БЕЗ левой
   рейки-акцента (правило CLIE-483). Обе темы одинаково вылизаны. */
.kn-gap { margin: 0 0 14px; padding: 12px 14px; border-radius: 14px;
  background: color-mix(in srgb, var(--primary) 7%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 20%, transparent); }
.kn-gap-cap { display: flex; align-items: center; gap: 7px; font-weight: 600; font-size: 13px; letter-spacing: .01em; }
.kn-gap-cap svg.ic { width: 15px; height: 15px; opacity: .85; }
.kn-gap-sub { margin: 2px 0 9px 22px; font-size: 12px; color: var(--muted); }
.kn-gap-row { display: flex; align-items: center; gap: 8px; padding: 7px 0;
  border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
.kn-gap-row:first-of-type { border-top: none; }
/* Имя вопроса важнее украшений: оно и сжимается последним, и режется многоточием. */
.kn-gap-q { flex: 1 1 200px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
/* proj-wiki-gaps-trunc-1 · на компьютере вопрос читается ЦЕЛИКОМ: многоточие резало его на полуслове
   («…цена пу…»), а длину и так держит сервер (300 знаков, Faq). Телефон не трогаем — там строка своя. */
@media (min-width: 761px) {
  .kn-gap-q { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; line-height: 1.35; }
}
.kn-gap-n { flex: 0 0 auto; font-size: 12px; color: var(--muted); }
.kn-gap-add { flex: 0 0 auto; min-width: max-content; height: var(--ctl-h); padding: 0 12px; border-radius: var(--ctl-r);
  font-size: var(--ctl-fs); font-weight: 550; border: none; cursor: pointer;
  color: #fff; background: var(--acc-fill); transition: filter 140ms ease; }
.kn-gap-add:hover { filter: brightness(1.06); }
.kn-gap-hide { flex: 0 0 auto; width: 28px; height: 28px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: transparent; color: var(--muted); border-radius: 8px; cursor: pointer; transition: background 140ms ease; }
.kn-gap-hide:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.kn-gap-hide svg.ic { width: 14px; height: 14px; }
html[data-theme="light"] .kn-gap { background: color-mix(in srgb, var(--primary) 6%, #fff); }
/* q_proj · proj-wiki-gap-question-lost-1 · proj-wiki-gap-x-overflow-2 · телефон 390, вкладка «Вики» проекта: в одну
   строку вставали вопрос, «не ответили N раз» (≈99px), «Завести статью» (≈136px) и «×» — вопрос сжимался в ноль, а
   «×» (x 354–384) вылезал за карточку. Вопрос берёт свою строку (до трёх строк, целиком — в title), под ним счётчик,
   кнопка и «×»: 136 + 32 + зазоры влезают в карточку. «×» — цель 32px. */
@media (max-width: 760px) {
  .kn-gap-row { flex-wrap: wrap; row-gap: 6px; }
  .kn-gap-q { flex: 1 1 100%; white-space: normal; overflow-wrap: anywhere; line-height: 1.35;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; }
  .kn-gap-n { flex: 1 1 0; min-width: 0; }
  .kn-gap-hide { width: 32px; height: 32px; }
}

/* ─── 👋 ПЕРВОЕ КАСАНИЕ: карточка «С чего начать» (CLIE-873) ────────────────────
   Первая строка списка чатов у нового человека. Живёт ровно до того, как он начал
   разговаривать (`active` считает сервер) — и исчезает сама, не отбирая экран.
   🔴 Акцент несут ИКОНКА + СЛОВО + мягкая подложка и хэйрлайн-кольцо, а НЕ полоса
   слева (правило CLIE-483). Размеры контролов — из --ctl-*, своих чисел нет. */
.ft-card { display: block; margin: 6px 8px 10px; padding: 12px 12px 8px; list-style: none;
  border-radius: 14px; background: color-mix(in srgb, var(--primary) 8%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.ft-head { display: flex; align-items: baseline; gap: 8px; }
.ft-head b { font-size: 14px; letter-spacing: -0.01em; }
.ft-count { margin-left: auto; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.ft-note { margin-top: 3px; font-size: 12px; line-height: 1.35; color: var(--muted); }
.ft-steps { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
/* 🔴 НЕ ВЛЕЗЛО — ЛЕСТНИЦА, А НЕ МОЛЧАНИЕ (канон СРЕД-33). Колонка списка чатов тянется
   мышью и живёт от ~245px; втроём (галочка + подпись + кнопка) в такую ширину они не
   помещаются, и подпись начинала рваться на три строки («Написать / первому / человеку»).
   Ступень 1 — кнопка стоит В СТРОКЕ. Ступень 2 — она уезжает на СВОЮ строку вправо, а
   подпись получает всю ширину. Ширину меряет сам флекс по базису подписи, а не медиазапрос:
   колонку жмут мышью и масштабом А+, а `resize` при CSS-zoom не приходит (CLIE-459). */
.ft-step { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 8px; padding: 7px 2px; }
/* Хэйрлайн — обычной границей, а не inset-тенью: у тени скруглённые углы коробки съедали
   концы линии, и разделитель читался как обрывок дуги. */
.ft-step + .ft-step { border-top: 1px solid color-mix(in srgb, var(--line) 70%, transparent); }
.ft-tick { flex: 0 0 auto; align-self: flex-start; margin-top: 1px;
  width: 16px; height: 16px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; box-shadow: inset 0 0 0 1px var(--line-strong); color: var(--primary); }
.ft-step.done .ft-tick { background: color-mix(in srgb, var(--primary) 16%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 34%, transparent); }
.ft-tick svg.ic { width: 11px; height: 11px; }
/* Базис 148px — та ширина, ниже которой подпись шага начинает рваться на три строки;
   не влезли вместе с кнопкой → флекс переносит кнопку, а не режет слово. */
.ft-tx { display: flex; flex-direction: column; min-width: 0; flex: 1 1 148px; }
.ft-tx b { font-size: 13px; font-weight: 600; }
.ft-tx small { font-size: 11px; line-height: 1.3; color: var(--muted); }
.ft-step.done .ft-tx b { color: var(--muted); font-weight: 500; }
.ft-step.done .ft-tx small { display: none; }
/* 🔴 min-width:max-content — подпись кнопки не режется и не налезает на соседа при узкой
   колонке и под А+ (правило СРЕД-33: контрол не сжимается ниже своей подписи). */
.ft-go { flex: 0 0 auto; margin-left: auto; min-width: max-content; height: var(--ctl-h);
  padding: 0 10px; border-radius: var(--ctl-r); border: 1px solid transparent; cursor: pointer;
  font-size: var(--ctl-fs); font-weight: 600; color: #fff; background: var(--acc-fill);
  transition: filter 140ms ease; }
.ft-go:hover { filter: brightness(1.06); }
.ft-hide { display: block; margin: 6px auto 0; padding: 4px 8px; border: none; background: transparent;
  color: var(--muted); font-size: 12px; border-radius: 8px; cursor: pointer; transition: background 140ms ease; }
.ft-hide:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
/* Пустая ветка списка: строка + НАСТОЯЩЕЕ действие вместо мёртвого «выберите ниже». */
.ft-empty { display: flex; align-items: center; gap: 10px; padding: 12px 12px; list-style: none; }
.ft-empty-tx { font-size: 13px; color: var(--muted); }
html[data-theme="light"] .ft-card { background: color-mix(in srgb, var(--primary) 6%, #fff); }
/* Строка «что это за продукт» на экране входа (CLIE-873) — первое, что читает человек. */
.login-pitch { margin: 2px 0 6px; font-size: 14px; line-height: 1.35; color: var(--text); font-weight: 500; }
/* ═══ 🪙 ЭЛЕКТРОННЫЙ СЧЁТ (CLIE-882) ══════════════════════════════════════════════════════
   Раздел «Счёт»: баланс, мои рабочие пространства, история операций.
   🔴 Ни одной прибитой ширины и ни одной левой полосы-рейки (CLIE-483): состояние подписки
   несёт ТОЧКА 6px + СЛОВО, а не цветная кромка слева. Размеры контролов — из токенов
   (--ctl-h/--ctl-r/--ctl-fs), цвета — из палитры темы, поэтому светлая и тёмная одинаковы. */
/* 🔴 ЧИТАЕМАЯ МЕРА. На широком мониторе строка «ЛюблюЕду … 6 000 койнов в месяц» растянулась
   бы на 1400px, и глаз терял бы связь имени с ценой. Ограничиваем КОЛОНКУ КОНТЕНТА, а не окно:
   раздел по-прежнему тянется вместе с окном (правило CRMC-406), просто текст не разъезжается. */
.wal-wrap { max-width: 920px; margin: 0 auto; width: 100%; }
.wal-hero { padding: 22px 20px 18px; border-bottom: 1px solid var(--line); }
.wal-hero > .wal-wrap, .wal-sec > .wal-wrap { padding: 0; }
.wal-sum { font-size: 30px; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
.wal-rate { margin-top: 4px; color: var(--muted); font-size: 13px; }
.wal-acts { margin-top: 14px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.wal-pend { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; min-height: var(--ctl-h);
  box-sizing: border-box; line-height: 1.35;
  border-radius: var(--ctl-r); font-size: var(--ctl-fs); color: var(--muted);
  background: color-mix(in srgb, var(--text) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 10%, transparent); }

.wal-sec { padding: 16px 20px 6px; container: walsec / inline-size; }
.wal-sec-t { font-size: 12px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 8px; }

/* Строка рабочего пространства. Точка слева — это ЗНАК СОСТОЯНИЯ (оплачено / льгота /
   приостановлено), а не декоративная рейка: она круглая, 6px, и рядом всегда стоит СЛОВО —
   иначе смысл читался бы только цветом и пропадал в ч/б. */
.wal-ws { display: flex; align-items: center; gap: 10px; padding: 9px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent); font-size: 13px; }
.wal-ws:last-child { border-bottom: none; }
.wal-dot { flex: 0 0 auto; width: 6px; height: 6px; border-radius: 50%; background: var(--ok); }
.wal-ws-grace .wal-dot { background: var(--warn); }
.wal-ws-suspended .wal-dot { background: var(--danger); }
.wal-ws-free .wal-dot { background: var(--muted); }
.wal-ws-n { font-weight: 600; color: var(--text); min-width: max-content; }
.wal-ws-s { color: var(--muted); flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wal-ws-p { color: var(--muted); min-width: max-content; }
.wal-ws-suspended .wal-ws-s { color: var(--danger); }
/* 🔴 13.10.2026 (проход по проду, телефон 390): состояние подписки не режется многоточием до «« …» —
   на узкой колонке оно идёт второй строкой под имя пространства (сетка: точка · имя · цена / — · состояние). */
@container walsec (max-width: 560px) {
  .wal-ws { display: grid; grid-template-columns: 6px minmax(0, 1fr) auto;
    grid-template-areas: "dot name price" ". state state"; column-gap: 10px; row-gap: 2px; }
  .wal-ws > .wal-dot { grid-area: dot; }
  .wal-ws > .wal-ws-n { grid-area: name; min-width: 0; overflow-wrap: anywhere; }
  .wal-ws > .wal-ws-p { grid-area: price; text-align: right; }
  .wal-ws > .wal-ws-s { grid-area: state; white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.35; }
  .wal-ws > .wal-ws-s:empty { display: none; }
}

/* 🔒 ЗАМОК ПРОСТРАНСТВА (CLIE-882·2) — блок ПОД строкой пространства: «месяц не оплачен,
   данные скрыты» + единственный осмысленный выход «Пополнить счёт».
   🔴 Ни одной левой рейки (CLIE-483): акцент несут ЗНАК (замок), СЛОВО (готовая фраза
   сервера) и мягкая подложка с хэйрлайн-кольцом — то есть смысл читается и в ч/б, и у
   человека с нарушением цветовосприятия. Тон берём из --danger, а он у каждой темы свой,
   поэтому светлая и тёмная получаются одинаково выверенными без второй копии правил.
   🔴 Ни одной прибитой ширины (CRMC-406): текст переносится, кнопка уезжает на свою строку
   на узком окне (flex-wrap), высота/радиус/кегль кнопки — из токенов контрола. */
.wal-ws-locked { border-bottom: none; }
.wal-lock {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 10px; padding: 10px 12px; border-radius: 12px;
  font-size: 13px; line-height: 1.35; color: var(--text);
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 26%, transparent);
}
.wal-lock-ic { flex: 0 0 auto; display: flex; color: var(--danger); }
.wal-lock-ic svg { width: 16px; height: 16px; }
/* Фраза сервера ПЕРЕНОСИТСЯ, а не режется: у неё нет «неважного хвоста» — это причина и цена.
   min-width НЕ обнуляем (СРЕД-33: обнулять его законно только рядом с честным ellipsis). */
.wal-lock-t { flex: 1 1 auto; }
.wal-lock .primary { flex: 0 0 auto; }
html[data-theme="light"] .wal-lock {
  background: color-mix(in srgb, var(--danger) 8%, #fff);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent);
}

/* ═══ 💳 ТАРИФ ПРОСТРАНСТВА И ЛИМИТЫ (0423) ════════════════════════════════════════════════
   Карточка тарифа живёт РАЗДЕЛОМ экрана «Счёт» (одна реализация), поэтому и мера у неё та же
   `.wal-wrap`, и токены контролов те же. Ни одной прибитой ширины и ни одной левой рейки
   (CLIE-483 · CRMC-406): перебор лимита несут СЛОВО (строка «перебор на N») и тон полосы, а не
   цветная кромка слева. Цвета — из палитры темы, поэтому светлая и тёмная выходят одинаково
   выверенными БЕЗ второй копии правил. */
.wal-pl { padding: 12px 0 14px; border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent); }
.wal-pl:last-child { border-bottom: none; }
/* Пришёл из отказа по лимиту — карточка нужного пространства подсвечена, чтобы человек не
   искал её глазами среди восьми (правило «состояние видно там, где его встретят»). */
.wal-pl.hot { border-radius: 12px; padding: 12px; border-bottom: none;
  background: color-mix(in srgb, var(--accent) 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 24%, transparent); }
.wal-pl-h { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.wal-pl-n { font-weight: 600; color: var(--text); font-size: 14px; }
.wal-pl-b { display: inline-flex; align-items: center; padding: 1px 8px; border-radius: 999px;
  font-size: 12px; font-weight: 600; color: var(--text);
  background: color-mix(in srgb, var(--text) 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 12%, transparent); }
.wal-pl-p { color: var(--muted); font-size: 13px; margin-left: auto; min-width: max-content;
  font-variant-numeric: tabular-nums; }
.wal-pl-s { margin-top: 3px; color: var(--muted); font-size: 12.5px; }
.wal-pl-inc { margin-top: 6px; color: var(--muted); font-size: 12.5px; line-height: 1.4; }
.wal-us { margin-top: 8px; display: flex; flex-direction: column; gap: 6px; }
.wal-us-p { color: var(--muted); font-size: 11.5px; letter-spacing: .02em; }
.wal-us-r { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 12.5px; }
.wal-us-t { color: var(--text); min-width: 140px; }
.wal-us-s { color: var(--muted); flex: 1 1 auto; min-width: 0; }
/* Полоса — ПОКАЗ серверного процента, счёт словами стоит рядом: полоса без числа врёт. */
.wal-us-bar { flex: 0 0 120px; height: 6px; border-radius: 999px; overflow: hidden;
  background: color-mix(in srgb, var(--text) 10%, transparent); }
.wal-us-bar > i { display: block; height: 100%; background: var(--ok); border-radius: 999px; }
.wal-us-r.over .wal-us-s { color: var(--danger); }
.wal-us-r.over .wal-us-bar > i { background: var(--danger); }
.wal-pl-acts { margin-top: 10px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.wal-pl-acts .cc-seg { flex-wrap: wrap; }
.wal-pl-acts .cc-seg > * { min-width: max-content; }
.wal-pl-note { margin-top: 6px; color: var(--muted); font-size: 11.5px; line-height: 1.35; }
html[data-theme="light"] .wal-pl.hot {
  background: color-mix(in srgb, var(--accent) 6%, #fff);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 20%, transparent); }

.wal-row { display: flex; align-items: baseline; gap: 12px; padding: 8px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 60%, transparent); font-size: 13px; }
.wal-row:last-child { border-bottom: none; }
.wal-row-t { flex: 1 1 auto; min-width: 0; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wal-row-d { color: var(--muted); font-size: 12px; min-width: max-content; }
.wal-row-a { font-variant-numeric: tabular-nums; font-weight: 600; min-width: max-content; }
.wal-row-a.plus { color: var(--ok); }
.wal-row-a.minus { color: var(--text); }

.wal-empty { padding: 22px 20px; color: var(--muted); font-size: 13px;
  display: flex; align-items: center; gap: 10px; }
.wal-grant { width: 100px; height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs);
  padding: 0 8px; border: 1px solid var(--line); background: var(--panel); color: var(--text); }

/* ═══ ☁️ ОБЛАКО ПРОСТРАНСТВА В «СЧЁТЕ» (0509) ═══════════════════════════════════════════════
   Подраздел карточки тарифа: остаток словами сервера, полоса из трёх СЕРВЕРНЫХ долей, раскрытия
   «по проектам» и «история покупок», покупка, автодокупка, доп. запуски. Ни одной левой рейки
   (CLIE-483): «мало»/«кончились» несут СЛОВО сервера и тон полосы; от строк лимитов блок отделён
   хэйрлайном, как соседние строки карточки. Контролы одного ряда — из --ctl-* (канон
   `control-size`); цвета — из палитры темы, поэтому светлая и тёмная — без второй копии правил. */
.wal-cl { margin-top: 10px; padding-top: 10px; display: flex; flex-direction: column; gap: 7px;
  border-top: 1px solid color-mix(in srgb, var(--line) 60%, transparent); font-size: 12.5px; }
.wal-cl-h { display: flex; align-items: center; gap: 6px; color: var(--text); font-weight: 600; font-size: 13px; }
.wal-cl-h .ic { width: 15px; height: 15px; flex: none; color: var(--muted); }
.wal-cl-hr { margin-left: auto; color: var(--muted); font-weight: 400; font-size: 12px; min-width: max-content; }
.wal-cl-say { color: var(--text); line-height: 1.4; }
.wal-cl.low .wal-cl-say { color: var(--warning); }
.wal-cl.out .wal-cl-say { color: var(--danger); }
/* Полоса — ПОКАЗ серверных долей; оттенки разные, чтобы «тариф» и «пакеты» читались раздельно,
   а легенда ниже называет их словами (смысл не держится на одном цвете). */
.wal-cl-bar { display: flex; gap: 2px; height: 8px; border-radius: 999px; overflow: hidden;
  background: color-mix(in srgb, var(--text) 8%, transparent); }
.wal-cl-bar > i { display: block; height: 100%; min-width: 2px; }
.wal-cl-bar > i.u, .wal-cl-lg i.u { background: color-mix(in srgb, var(--text) 32%, transparent); }
.wal-cl-bar > i.l, .wal-cl-lg i.l { background: var(--ok); }
.wal-cl-bar > i.p, .wal-cl-lg i.p { background: var(--primary); }
.wal-cl.low .wal-cl-bar > i.l, .wal-cl.low .wal-cl-lg i.l { background: var(--warning); }
.wal-cl-lg { display: flex; flex-wrap: wrap; gap: 4px 14px; color: var(--muted); font-size: 11.5px; }
.wal-cl-lg span { display: inline-flex; align-items: center; gap: 5px; }
.wal-cl-lg i { width: 8px; height: 8px; border-radius: 50%; flex: none; }
/* Раскрытия — родной <details>: клавиатура и чтение экрана даром, своего «аккордеона» не пишем. */
.wal-cl-more > summary { display: inline-flex; align-items: center; gap: 6px; padding: 2px 0;
  color: var(--muted); font-size: 12px; cursor: pointer; list-style: none; }
.wal-cl-more > summary::-webkit-details-marker { display: none; }
.wal-cl-more > summary::before { content: ""; width: 5px; height: 5px; margin: 0 2px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(-45deg); transition: transform .15s ease; }
.wal-cl-more[open] > summary::before { transform: rotate(45deg); }
.wal-cl-more > summary:hover { color: var(--text); }
.wal-cl-row { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; padding: 5px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--line) 45%, transparent); }
.wal-cl-row:last-child { border-bottom: none; }
.wal-cl-rt { flex: 1 1 160px; min-width: 0; color: var(--text); overflow-wrap: anywhere; }
.wal-cl-rs, .wal-cl-rd { color: var(--muted); min-width: max-content; }
.wal-cl-rd { font-size: 12px; }
.wal-cl-ra { font-variant-numeric: tabular-nums; font-weight: 600; min-width: max-content; color: var(--text); }
.wal-cl-sub { margin-top: 4px; font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.wal-cl-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Ряд кнопок — один размерный класс: главная (`.primary.small`) и вторичная одной высоты. */
.wal-cl-acts .primary.small, .wal-cl-btn { min-height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs); }
/* Вторичная кнопка — КОНТРОЛ, а не подпись: `.ghost` без рамки на панели читается текстом (урок
   замера 13.09 у `.errfix-altbtn`), поэтому мягкая подложка акцента + рамка. */
.wal-cl-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; flex: 0 0 auto;
  padding: 0 12px; border: 1px solid color-mix(in srgb, var(--primary) 34%, var(--line));
  background: color-mix(in srgb, var(--primary) 10%, var(--panel-2)); color: var(--text); font-weight: 560; }
.wal-cl-btn:hover { background: color-mix(in srgb, var(--primary) 18%, var(--panel-2)); border-color: color-mix(in srgb, var(--primary) 52%, var(--line)); }
.wal-cl-auto { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; margin-top: 2px; }
.wal-cl-sw { display: inline-flex; align-items: center; gap: 8px; color: var(--text); font-size: 13px; cursor: pointer; }
.wal-cl-f { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px; color: var(--muted); font-size: 12.5px; }
.wal-cl-f[hidden] { display: none; }
/* Пакет и потолок — канон `.cc-seg .cc-seg-sm`; на узком окне сегмент переносится, а не режется. */
.wal-cl-f .cc-seg { flex-wrap: wrap; max-width: 100%; }
.wal-cl-f .cc-seg > * { min-width: max-content; }
.wal-cl-note { color: var(--muted); font-size: 11.5px; line-height: 1.4; }
.wal-cl-sl { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin-top: 2px; }
.wal-cl-slt { flex: 1 1 220px; min-width: 0; color: var(--text); }
.wal-cl-asked { align-self: flex-start; }
.wal-cl-asked .ic { width: 14px; height: 14px; flex: none; }
.wal-cl-me { display: flex; align-items: center; gap: 6px; padding: 10px 0 4px; color: var(--muted); font-size: 12.5px; }
.wal-cl-me .ic { width: 14px; height: 14px; flex: none; }

/* ☁️ Лист «Купить минуты» (`cloudBuySheet`) — рама `ccFormModal` с видом `clb-sheet`: механика окна
   (Escape, фокус, подложка) одна на продукт. Карточка пакета — сама кнопка покупки. */
.clb { display: flex; flex-direction: column; gap: 12px; }
.clb-say { font-size: 13px; line-height: 1.4; color: var(--text); }
.clb-packs { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
.clb-pack { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; padding: 12px 14px;
  text-align: left; border-radius: 12px; border: 1px solid var(--line); background: var(--panel-2); color: var(--text);
  cursor: pointer; transition: border-color .14s ease, background .14s ease, transform .12s ease; }
.clb-pack:hover { border-color: color-mix(in srgb, var(--primary) 55%, var(--line));
  background: color-mix(in srgb, var(--primary) 8%, var(--panel-2)); }
.clb-pack:active { transform: translateY(.5px); }
.clb-pack.is-busy { cursor: progress; }
.clb-q { font-size: 16px; font-weight: 700; letter-spacing: -.01em; }
.clb-p { font-size: 14px; font-weight: 600; color: var(--primary-2); }
.clb-h { font-size: 12px; color: var(--muted); }
.clb-m { font-size: 11px; color: var(--text-dim); }
.clb-note { font-size: 11.5px; line-height: 1.4; color: var(--muted); }
.clb-auto { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; }
.clb-bal { font-size: 12.5px; color: var(--muted); }
/* «Закрыть» в подвале листа — НЕ главное действие (главное здесь — карточка пакета), поэтому без
   заливки акцентом: две «главные» кнопки на одном окне — выбор без выбора. */
.clb-sheet .pm-foot [data-ccf="ok"] { background: transparent; color: var(--text); border: 1px solid var(--line); box-shadow: none; }
.clb-sheet .pm-foot [data-ccf="ok"]:hover { background: var(--hover); box-shadow: none; }

/* ══════════════════════════════════════════════════════════════════════════════════════
   👔🔴🔴 АНКЕТА СПЕЦИАЛИСТА (CLIE-897 · «Специалисты 1/5»)

   Раньше здесь жил булев тумблер «Я специалист» и плоская форма с нативными <select>.
   Теперь авторитет данных — СЕРВЕР (`Clientschat.Directory.Specialists`): он считает процент
   заполненности и КОНКРЕТНУЮ следующую подсказку, он же отдаёт реестры значений (видимость,
   статус поиска, формат, график, уровень языка, грейд, занятость, валюта). Клиент их ЧИТАЕТ и
   своих таблиц подписей не держит — иначе «Рассматриваю предложения» станет тремя разными
   фразами на трёх слоях (грабля CLIE-881: поле отдавали, никто не читал).

   🔴 Правка — ИНЛАЙН и БЕЗ кнопок «Сохранить/Отмена» (канон «нажал → изменил», CLIE-189):
   ввод дебаунсится, чип/сегмент/пикер сохраняются мгновенно, PATCH везёт ТОЛЬКО изменённые
   ключи. Ошибка не теряет черновик — она возвращает его в очередь и даёт «Повторить».

   🔴 Ни одного прибитого цвета: обе темы живут на токенах (--panel/--line/--primary/--ok).
   Ни одной прибитой ширины: сетки резиновые, потолков в px у списков нет (CLIE-620).
   ══════════════════════════════════════════════════════════════════════════════════════ */
.ank { display: grid; gap: 16px; margin-top: 4px; }
.ank-skel, .ank-fail { padding: 26px 18px; text-align: center; color: var(--muted); font-size: 13.5px;
  border: 1px dashed var(--line); border-radius: 14px; display: grid; gap: 12px; justify-items: center; }
.ank-fail { color: var(--text); }

/* ── ЗАПОЛНЕННОСТЬ: ЧИСЛО И ПОДСКАЗКА ПРИЕЗЖАЮТ ЦЕЛИКОМ С СЕРВЕРА ──────────────────────
   🔴 Клиент НИЧЕГО тут не считает: `percent`, `next.label`, `next.hint` и `next.weight` —
   поля ответа `/v3/me/anketa`. Вторая лестница «что считается заполненным» разъехалась бы
   с серверной молча, и человек видел бы 60 % на одном экране и 80 % на другом. */
.ank-prog { border: 1px solid var(--line); border-radius: 16px; padding: 15px 17px 16px;
  background: var(--panel-2); display: grid; gap: 11px; }
.ank-prog-top { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.ank-pct { font-size: 15.5px; font-weight: 650; letter-spacing: -.01em; color: var(--text); min-width: max-content; }
.ank-prog-sp { flex: 1 1 auto; }
.ank-state { display: inline-flex; align-items: center; gap: 6px; min-width: max-content;
  font-size: 11.5px; font-weight: 620; letter-spacing: .02em; padding: 3px 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--muted) 16%, transparent); color: var(--muted); }
.ank-state.on { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.ank-state svg { width: 13px; height: 13px; flex: none; }
.ank-bar { height: 7px; border-radius: 999px; overflow: hidden;
  background: color-mix(in srgb, var(--text) 10%, transparent); }
.ank-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--grad);
  transition: width .34s var(--ease-standard, cubic-bezier(.4,0,.2,1)); }
.ank-next { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; line-height: 1.45; color: var(--text); }
.ank-next-ic { flex: 0 0 auto; display: flex; color: var(--primary-2); margin-top: 1px; }
.ank-next-ic svg { width: 16px; height: 16px; }
.ank-next-tx { flex: 1 1 auto; min-width: 0; }
.ank-next-tx b { font-weight: 620; }
.ank-next-tx span { color: var(--muted); }
.ank-next-w { min-width: max-content; font-size: 11.5px; font-weight: 650; color: var(--primary-2);
  padding: 2px 8px; border-radius: 999px; background: color-mix(in srgb, var(--primary) 14%, transparent); }
.ank-next-go { min-width: max-content; border: 1px solid var(--line); background: var(--panel);
  color: var(--text); border-radius: 9px; padding: 5px 11px; font: inherit; font-size: 12.5px;
  font-weight: 600; cursor: pointer; transition: border-color .13s, background .13s; }
.ank-next-go:hover { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 9%, transparent); }
.ank-next.done .ank-next-ic { color: var(--ok); }

/* ── ПОДСТАНОВКА: ПРЕДЛОЖЕНИЕ, А НЕ ТИХАЯ ЗАПИСЬ ──────────────────────────────────────
   Значение УЖЕ стоит в поле (человек видит его как обычное и правит), а рядом тихая строка
   «подставлено: <откуда>». Записывается оно только его собственным сохранением. */
.ank-pfbar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  border: 1px solid color-mix(in srgb, var(--primary) 26%, transparent); border-radius: 14px;
  padding: 12px 15px; background: color-mix(in srgb, var(--primary) 8%, transparent); font-size: 13px; }
.ank-pfbar-ic { flex: 0 0 auto; display: flex; color: var(--primary-2); }
.ank-pfbar-ic svg { width: 17px; height: 17px; }
.ank-pfbar-t { flex: 1 1 220px; min-width: 0; line-height: 1.45; color: var(--text); }
.ank-pfbar-t span { display: block; color: var(--muted); font-size: 12px; }
.ank-pfbar-b { min-width: max-content; border: 0; border-radius: 10px; padding: 8px 15px;
  background: var(--acc-grad); color: #fff; font: inherit; font-size: 13px; font-weight: 620; cursor: pointer;
  transition: filter .13s, transform .13s; }
.ank-pfbar-b:hover { filter: brightness(1.07); transform: translateY(-1px); }
.ank-pf { display: inline-flex; align-items: center; gap: 5px; margin-left: 8px; text-transform: none;
  letter-spacing: 0; font-size: 11px; font-weight: 500; color: var(--primary-2); }
.ank-pf::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: .8; }

/* ── РАМА РАЗДЕЛОВ: НАВИГАЦИЯ СЛЕВА, АКТИВНЫЙ РАЗДЕЛ СПРАВА (CLIE-897·2, раунд 2) ──────
   Владелец: «страница заполнения данных очень слабая по дизайну, всё в куче, сложно смотреть
   разобраться». Разметку рамы (`ankNavHtml` + `.ank-pane`) завели, а СТИЛЕЙ у неё не было ни
   одной строки — навигация раскладывалась потоком как ряд коробок, счётчик прилипал к подписи
   («Кто вы5»), разделитель растягивался во всю ширину. Рама — ТА ЖЕ, что у настроек
   (`.set2-nav`/`.set2-navi`): второго языка «список разделов» в продукте не заводим.
   🔴 Ширина колонки — `clamp`, а не прибитое число (CRMC-406): модалку тянут мышью.
   🔴 Своего `max-height` у навигации НЕТ (CLIE-620): разделов одиннадцать, они помещаются,
   а вложенный кап спрятал бы «Приватность» под невидимый бегунок.
   🔴 `min-width: auto` у пункта (СРЕД-33): подпись не имеет права налезть на счётчик. */
.ank-wrap { display: grid; grid-template-columns: clamp(196px, 25%, 252px) minmax(0, 1fr);
  gap: 22px; align-items: start; }
.ank-nav { display: flex; flex-direction: column; gap: 1px; position: sticky; top: 0;
  padding: 4px; border: 1px solid var(--line); border-radius: 15px; background: var(--panel-2); }
.ank-navi { display: flex; align-items: center; gap: 10px; width: 100%; min-width: auto;
  border: 0; background: transparent; color: var(--text); font: inherit; font-size: 13.5px;
  font-weight: 500; text-align: left; padding: 8px 10px; border-radius: 10px; cursor: pointer;
  transition: background .13s ease, color .13s ease; }
.ank-navi > span { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.ank-navi:hover { background: var(--hover); }
.ank-navi.on { background: var(--sel); color: var(--primary-2); font-weight: 620; }
.ank-navi svg { width: 17px; height: 17px; flex: 0 0 auto; color: var(--muted);
  transition: color .13s ease; }
.ank-navi.on svg { color: var(--primary-2); }
.ank-navsep { height: 1px; border: 0; background: var(--line); margin: 7px 8px; }
/* Счётчик «сколько ещё осталось» и галочка «раздел заполнен» — СВОЯ коробка, а не текст
   впритык к подписи: слипшееся «Кто вы5» и есть то, что читается как «сделано на отвяжись». */
.ank-navn { flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  min-width: 19px; height: 19px; padding: 0 5px; border-radius: 999px; background: var(--panel);
  box-shadow: inset 0 0 0 1px var(--line); color: var(--muted);
  font-size: 11px; font-weight: 700; line-height: 1; }
.ank-navn:empty { display: none; }
.ank-navi.on .ank-navn { color: var(--primary-2); }
.ank-navok { flex: 0 0 auto; display: inline-flex; color: var(--ok); }
.ank-navok svg { width: 15px; height: 15px; color: var(--ok); }
.ank-pane { min-width: 0; display: grid; gap: 18px; }
/* Узко (телефон, зауженная мышью модалка) — навигация ложится ЛЕНТОЙ над разделом. */
@media (max-width: 860px) {
  .ank-wrap { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .ank-nav { position: static; flex-direction: row; gap: 6px; overflow-x: auto;
    scrollbar-width: thin; padding: 5px; }
  .ank-navi { width: auto; min-width: max-content; }
  .ank-navi > span { overflow: visible; }
  .ank-navsep { width: 1px; height: auto; align-self: stretch; margin: 4px 2px; }
}

/* ── ПОЛЕ ЖИВЁТ НЕ ЗДЕСЬ: РАЗДЕЛ ГОВОРИТ ЭТО И ДОВОДИТ ОДНОЙ КНОПКОЙ (ЗВОН-604·3) ────── */
.ank-away { display: flex; align-items: flex-start; gap: 11px; padding: 12px 14px;
  border: 1px solid var(--line); border-radius: 13px; background: var(--panel-2); }
.ank-away.done { border-color: color-mix(in srgb, var(--ok) 34%, transparent);
  background: color-mix(in srgb, var(--ok) 8%, transparent); }
.ank-away-ic { flex: 0 0 auto; display: flex; color: var(--primary-2); margin-top: 1px; }
.ank-away.done .ank-away-ic { color: var(--ok); }
.ank-away-ic svg { width: 17px; height: 17px; }
.ank-away-tx { flex: 1 1 auto; min-width: 0; display: grid; gap: 3px; }
.ank-away-tx b { font-size: 13.5px; font-weight: 620; }
.ank-away-tx span { font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.ank-away .ank-next-go { align-self: center; }

/* ── ПРЕДПРОСМОТР «КАК ВИДЯТ ДРУГИЕ» ─────────────────────────────────────────────────── */
.modal-box.ank-prev { max-width: min(760px, 96vw); }
.ank-prev .modal-body { display: grid; gap: 14px; }
.ank-prev-note { display: flex; align-items: flex-start; gap: 10px; padding: 11px 13px;
  border-radius: 12px; font-size: 12.5px; line-height: 1.45; color: var(--text);
  background: color-mix(in srgb, var(--primary) 9%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 24%, transparent); }
.ank-prev-note svg { width: 16px; height: 16px; flex: 0 0 auto; color: var(--primary-2); margin-top: 1px; }
.ank-prev-empty { display: grid; gap: 9px; justify-items: center; text-align: center;
  padding: 26px 18px; border: 1px dashed var(--line); border-radius: 15px; }
.ank-prev-empty b { font-size: 15px; font-weight: 650; }
.ank-prev-empty span { font-size: 13px; line-height: 1.5; color: var(--muted); max-width: 46ch; }

/* ── СЕКЦИИ ───────────────────────────────────────────────────────────────────────────── */
.ank-sec { display: grid; gap: 12px; }
.ank-sec-h { display: flex; align-items: center; gap: 10px; margin: 4px 0 0;
  font-size: 11.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--primary-2); }
.ank-sec-h::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--line); }
.ank-sec-hint { font-size: 12.5px; line-height: 1.45; color: var(--muted); margin: -4px 0 0; }

/* ── ПОЛЯ ─────────────────────────────────────────────────────────────────────────────── */
.ank-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.ank-grid.one { grid-template-columns: minmax(0, 1fr); }
.ank-f { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.ank-f.wide { grid-column: 1 / -1; }
.ank-lb { display: flex; align-items: center; flex-wrap: wrap; font-size: 11.5px; font-weight: 600;
  letter-spacing: .02em; text-transform: uppercase; color: var(--muted); }
/* 🔴 CLIE-505: контрол-кнопка стоит в ОДНОМ ряду с полями ввода модалки — значит и метрика
   у него та же, иначе ряд «рассыпается» (у канона `.ccpp-field` метрика ТУЛБАРНАЯ, 31px). */
#settingsModal .ank-f .ccpp-field { min-height: 42px; border-radius: 11px; padding: 0 14px;
  font-size: 14.5px; background: var(--panel-2); }
#settingsModal .ank-f .ccpp-field.open { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
/* 🔴 ПУТАНИЦА ОСЕЙ, УЖЕ ОПЛАЧЕННАЯ ОДИН РАЗ (CLIE-683·9). Канон пишет
   `.cc-seg-sm { align-self: center }` для сегмента В СТРОКЕ — там эта ось вертикальная
   («своя высота, по центру строки»). Поле анкеты — КОЛОНКА, и та же ось становится
   ГОРИЗОНТАЛЬНОЙ: замер стенда — сегмент «Уровень» стоял со сдвигом +65px, а «Валюта»
   +144px, то есть по центру, когда все соседние контролы идут от левой кромки.
   В колонке равняем по началу — ровно как это уже сделано для панели фона. */
.ank-f > .cc-seg-sm, .ank-sec > .cc-seg-sm { align-self: flex-start; }
.ank-f .ccpp-wrap { position: relative; }
.ank-pick { position: relative; margin-top: 6px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--panel); box-shadow: var(--shadow-2); overflow: hidden; }
.ank-free { display: flex; }
.ank-free[hidden] { display: none; }
.ank-free button { flex: 1 1 auto; display: flex; align-items: center; gap: 8px; border: 0;
  border-top: 1px solid var(--line); background: transparent; color: var(--text); font: inherit;
  font-size: 13px; padding: 10px 13px; cursor: pointer; text-align: left; }
.ank-free button:hover { background: var(--hover); }
.ank-free b { font-weight: 620; }

/* ── МНОГОВЫБОР-ПИЛЮЛИ (занятость · формат · график) ──────────────────────────────────── */
.ank-pills { display: flex; flex-wrap: wrap; gap: 8px; }
.ank-pill { border: 1px solid var(--line); border-radius: 10px; padding: 8px 14px; font: inherit;
  font-size: 13px; font-weight: 560; cursor: pointer; color: var(--muted); background: var(--panel-2);
  user-select: none; transition: border-color .14s, color .14s, background .14s, transform .14s; }
.ank-pill:hover { border-color: var(--primary); color: var(--text); }
.ank-pill.on { background: var(--acc-grad); border-color: transparent; color: #fff; }
.ank-pill:active { transform: scale(.97); }

/* ── НАВЫКИ: ЧИПЫ + ПОДСКАЗКИ СЕРВЕРА ─────────────────────────────────────────────────── */
.ank-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.ank-chips:empty { display: none; }
.ank-chip { display: inline-flex; align-items: center; gap: 8px; background: var(--panel-2);
  border: 1px solid var(--line); border-radius: 9px; padding: 7px 9px 7px 13px; font-size: 13px; }
.ank-chip b { cursor: pointer; color: var(--muted); font-weight: 700; line-height: 1; display: flex; }
.ank-chip b svg { width: 13px; height: 13px; }
.ank-chip b:hover { color: var(--danger); }
.ank-skwrap { position: relative; }
/* Выдача подсказок — тот самый «каталог», которому кап ОСТАВЛЕН осознанно (CLIE-620):
   без потолка двенадцать строк накрыли бы половину формы. Раз кап остаётся, скролл обязан
   быть ВИДЕН — и он приезжает каноном `.cc-scroll-in` (бегунок всегда виден, край тает,
   пока за ним есть строки). Класс вешает единственный реестр SCROLL_IN_SEL в app.js,
   поэтому своего `overflow` здесь нет намеренно: второй лестницы «как скроллить» не заводим. */
.ank-sug { position: absolute; left: 0; right: 0; top: calc(100% + 5px); z-index: 4;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel-3);
  box-shadow: var(--shadow-2); max-height: 260px; padding: 4px; }
.ank-sug[hidden] { display: none; }
.ank-sug-i { display: flex; align-items: center; gap: 9px; width: 100%; border: 0; background: transparent;
  color: var(--text); font: inherit; font-size: 13.5px; padding: 8px 10px; border-radius: 9px;
  cursor: pointer; text-align: left; }
.ank-sug-i:hover, .ank-sug-i.cur { background: var(--sel); }
.ank-sug-n { margin-left: auto; color: var(--muted); font-size: 11.5px; min-width: max-content; }

/* ── КТО ВИДИТ АНКЕТУ: ШЕСТЬ УРОВНЕЙ СЛОВАМИ (title + hint СЕРВЕРА) ────────────────────
   Это НЕ галочка: уровень решает, что физически попадёт в публичную таблицу, поэтому у
   каждого своя подпись и своё пояснение — оба приезжают реестром, а не пишутся в вёрстке. */
.ank-vis { display: grid; gap: 8px; }
.ank-vis-i { display: flex; align-items: flex-start; gap: 12px; width: 100%; text-align: left;
  border: 1px solid var(--line); border-radius: 13px; padding: 12px 14px; background: var(--panel-2);
  color: var(--text); font: inherit; cursor: pointer; transition: border-color .14s, background .14s; }
.ank-vis-i:hover { border-color: var(--line-strong); }
.ank-vis-i.on { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, transparent); }
.ank-vis-dot { flex: 0 0 auto; width: 16px; height: 16px; margin-top: 2px; border-radius: 50%;
  border: 1.5px solid var(--line-strong); position: relative; transition: border-color .14s; }
.ank-vis-i.on .ank-vis-dot { border-color: var(--primary); }
.ank-vis-i.on .ank-vis-dot::after { content: ""; position: absolute; inset: 3px; border-radius: 50%;
  background: var(--primary); }
.ank-vis-tx { flex: 1 1 auto; min-width: 0; display: grid; gap: 3px; }
.ank-vis-tx b { font-size: 13.5px; font-weight: 620; }
.ank-vis-tx span { font-size: 12.5px; line-height: 1.4; color: var(--muted); }

/* ── ДОВЕРИЕ КАРТОЧКИ: что скрыто + жалоба (CLIE-897 4/5) ───────────────────────────── */
.spec-trust { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; margin: 6px 0 2px; }
.spec-hid { font-size: 12px; color: var(--muted); }
.spec-rep { margin-left: auto; color: var(--muted); }
.spec-rep svg { width: 13px; height: 13px; }

/* ── ЧТО ПОКАЗЫВАТЬ: СКРЫТИЕ ОТДЕЛЬНЫХ ПОЛЕЙ (CLIE-897 4/5) ──────────────────────────
   Тот же контрол, что и уровень видимости, только флажок квадратный: это МНОЖЕСТВЕННЫЙ
   выбор, и круглая точка-радио врала бы про то, что можно выбрать одно. */
.ank-hide .ank-vis-dot { border-radius: 6px; }
.ank-hide .ank-vis-i.on .ank-vis-dot::after { border-radius: 3px; }

/* ── КТО СМОТРЕЛ МОЮ АНКЕТУ ─────────────────────────────────────────────────────────── */
.ank-views { display: grid; gap: 6px; }
.ank-view-i { display: flex; align-items: center; gap: 10px; padding: 9px 12px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); }
.ank-view-av { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 30%; object-fit: cover; }
.ank-view-av.ph { display: flex; align-items: center; justify-content: center;
  background: var(--panel); color: var(--muted); }
.ank-view-av.ph svg { width: 16px; height: 16px; }
.ank-view-tx { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
.ank-view-tx b { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 5px; }
.ank-view-tx b svg { width: 13px; height: 13px; color: var(--primary); }
.ank-view-tx span { font-size: 12px; color: var(--muted); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.ank-view-when { flex: 0 0 auto; font-size: 11.5px; color: var(--muted); }
.ank-views-e { font-size: 12.5px; line-height: 1.45; color: var(--muted); }

/* ── «КОМУ ПОРУЧИТЬ»: ПОДБОР ПОД ЗАДАЧУ (CLIE-897 4/5) ──────────────────────────────
   Рама — канонический поповер `.tc-pop` (свой z-index не заводим: слой считает
   ccLayerLift, CLIE-692). Левых полосок-реек нет (CLIE-483): причину совпадения несут
   СЛОВА, а не цветная кромка. */
.cand-pop { display: grid; gap: 8px; }
.cand-head { font-size: 12px; font-weight: 650; letter-spacing: .02em; color: var(--muted);
  text-transform: uppercase; padding: 2px 2px 0; }
.cand-body { display: grid; gap: 8px; max-height: 60vh; overflow-y: auto; }
.cand-load { font-size: 12.5px; color: var(--muted); padding: 8px 2px; }
.cand-terms { font-size: 12px; color: var(--muted); display: flex; flex-wrap: wrap;
  align-items: center; gap: 5px; }
.cand-term { display: inline-flex; padding: 2px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--text);
  font-size: 11.5px; font-weight: 560; }
.cand-list { display: grid; gap: 6px; }
.cand-row { display: flex; align-items: center; gap: 10px; padding: 9px 10px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); }
.cand-av { flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%; object-fit: cover; }
.cand-av.ph { display: flex; align-items: center; justify-content: center;
  background: var(--panel); color: var(--muted); }
.cand-av.ph svg { width: 16px; height: 16px; }
.cand-tx { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
.cand-tx b { font-size: 13px; font-weight: 620; display: flex; align-items: center; gap: 5px; }
.cand-ok svg { width: 13px; height: 13px; color: var(--primary); }
.cand-meta { font-size: 11.5px; color: var(--muted); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.cand-why { font-size: 11.5px; line-height: 1.35; color: var(--primary); }
.cand-acts { flex: 0 0 auto; display: flex; align-items: center; gap: 4px; }
.cand-empty { display: grid; gap: 6px; padding: 10px 4px 4px; }
.cand-empty b { font-size: 13px; font-weight: 620; }
.cand-empty span { font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.cand-empty-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.tip-cand-row { margin: 2px 0 6px; }

/* ── ПОВТОРЯЕМЫЕ СТРОКИ (работа · учёба · языки · портфолио · ссылки) ─────────────────── */
.ank-rows { display: grid; gap: 10px; }
.ank-row { position: relative; border: 1px solid var(--line); border-radius: 13px;
  padding: 15px 46px 15px 15px; background: var(--panel-2); display: grid; gap: 12px; }
#settingsModal .ank-row input, #settingsModal .ank-row select, #settingsModal .ank-row textarea { background-color: var(--panel); } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.ank-row-del { position: absolute; top: 10px; right: 10px; width: 28px; height: 28px; border: 0;
  border-radius: 8px; background: transparent; color: var(--muted); cursor: pointer;
  display: flex; align-items: center; justify-content: center; transition: background .14s, color .14s; }
.ank-row-del svg { width: 14px; height: 14px; }
.ank-row-del:hover { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.ank-add { width: 100%; background: transparent; border: 1.5px dashed var(--line); color: var(--muted);
  border-radius: 12px; padding: 12px; cursor: pointer; font: inherit; font-size: 13.5px; font-weight: 600;
  transition: border-color .14s, color .14s, background .14s; }
.ank-add:hover { border-color: var(--primary); color: var(--primary-2);
  background: color-mix(in srgb, var(--primary) 7%, transparent); }

/* Подсказка сервера довела до раздела — раздел обязан СКАЗАТЬ, что он и есть цель:
   шесть похожих блоков без метки человек читает сверху вниз и правит соседний. */
.ank-hl { border-radius: 16px; animation: ankHl 1.35s var(--ease-standard, ease); }
@keyframes ankHl {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  16%, 62% { box-shadow: 0 0 0 3px var(--glow); }
}
@media (prefers-reduced-motion: reduce) { .ank-hl { animation: none; box-shadow: 0 0 0 3px var(--glow); } }

/* Узкий экран — одна колонка (и это ЕДИНСТВЕННЫЙ медиазапрос: ширины везде резиновые). */
@media (max-width: 620px) { .ank-grid { grid-template-columns: minmax(0, 1fr); } }

/* ══════════════════════════════════════════════════════════════════════════════════════
   КАРТОЧКА СПЕЦИАЛИСТА — ОДНА ВЁРСТКА, ВИД «ВИТРИНА» (CLIE-897·4 → ·5, владелец 09.09.2026)
   ──────────────────────────────────────────────────────────────────────────────────────
   Владелец: «Не красиво… сделай 3-5 варианта» → показаны пять → «Давай витрина. Но если
   контент позволяет, то сделай блоки по 2 столбика где это возможно… если пользователь
   много информации о себе добавил, то пусть блок будет на всю ширину».
   🔴 Разметку рисует единственная `specCardHtml`; ширину блока решает ВЕС СОДЕРЖИМОГО
   (`specSecWeight` → `specSecLayout` → признак `data-w`), а не тип блока и не второй CSS.
   🔴 Витрина выбора жила ТОЛЬКО ДО РЕШЕНИЯ (CLIE-631): вариант назван — переключатель и
   ветки остальных четырёх удалены, остался один вид.
   🔴 Левых реек-акцентов здесь нет ни одной (CLIE-483): иерархию несут кегль, воздух,
   мягкая подложка (7–12 % акцента) и хэйрлайн-кольцо. Обе темы — на общих токенах.
   ══════════════════════════════════════════════════════════════════════════════════════ */
.spec-card { --sc-gap: 18px; color: var(--text); }
.spec-card * { min-width: 0; }

/* ── шапка ── */
.sc-hero { display: flex; align-items: center; gap: 16px; padding: 4px 0 2px; }
.sc-ava .cli-av, .sc-ava .cli-avs, .sc-ava .av, .sc-ava img, .sc-ava > span {
  width: 64px; height: 64px; min-width: 64px; border-radius: 50%; font-size: 22px;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
}
.sc-id { flex: 1 1 auto; display: flex; flex-direction: column; gap: 4px; }
.sc-name { font-size: 21px; font-weight: 650; letter-spacing: -.01em; line-height: 1.15;
  display: flex; align-items: center; gap: 7px; }
.sc-ok { display: inline-flex; width: 17px; height: 17px; border-radius: 50%; align-items: center;
  justify-content: center; background: color-mix(in srgb, var(--primary) 18%, transparent);
  color: var(--primary-2); }
.sc-ok svg { width: 11px; height: 11px; }
.sc-role { color: var(--muted); font-size: 13.5px; line-height: 1.35; }
.sc-open { align-self: flex-start; font-size: 11.5px; font-weight: 600; letter-spacing: .01em;
  padding: 2px 9px; border-radius: 999px; color: var(--mdc-green);
  background: color-mix(in srgb, var(--mdc-green) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--mdc-green) 26%, transparent); }
.sc-facts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.sc-fact { font-size: 12px; color: var(--text-dim); padding: 3px 10px; border-radius: 999px;
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); white-space: nowrap; }
.sc-fact[data-f="pay"] { color: var(--primary-2);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 24%, transparent); }
.sc-cta { margin-left: auto; }
.sc-cta .pr-host:empty { display: none; }

/* ── тело и разделы ── */
/* 🔴 CLIE-897·5 (владелец 09.09.2026): «блоки по 2 столбика где это возможно; если много
   информации — блок на всю ширину». Сколько места блоку — решает ВЕС ЕГО СОДЕРЖИМОГО
   (`specSecWeight`/`specSecLayout` в app.js, `specSecLayout` в приложении), а не тип блока:
   рисуем ровно то, что решил единый расчёт, признаком `data-w`. */
.spec-card { container-type: inline-size; }
.sc-body { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px; margin-top: 16px; align-items: start; }
.sc-sec { min-width: 0; }
.sc-sec[data-w="wide"] { grid-column: 1 / -1; }
/* Узкое место (телефон, узкая колонка, окно предпросмотра под руку) — одна колонка.
   Спрашиваем ширину САМОЙ карточки, а не окна: она живёт и в модалке, и на странице. */
@container (max-width: 560px) { .sc-body { grid-template-columns: minmax(0, 1fr); }
  .sc-sec[data-w] { grid-column: 1 / -1; } }
@media (max-width: 620px) { .sc-body { grid-template-columns: minmax(0, 1fr); }
  .sc-sec[data-w] { grid-column: 1 / -1; } }
.sc-h { display: flex; align-items: center; gap: 8px; font-size: 11px; font-weight: 640;
  text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin: 0 0 8px; }
.sc-cnt { font-size: 11px; font-weight: 600; color: var(--text-dim); padding: 1px 7px;
  border-radius: 999px; background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.sc-c { line-height: 1.5; }
.sc-links { display: flex; flex-wrap: wrap; gap: 10px 18px; }
.spec-card .dir-about { white-space: pre-wrap; line-height: 1.55; font-size: 14px; }
.spec-card .spec-trust { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 12px; font-size: 12px; color: var(--muted); }

/* ── ВИТРИНА — ЕДИНСТВЕННЫЙ ВИД КАРТОЧКИ (владелец 09.09.2026: «Давай витрина») ───────
   Из пяти показанных вариантов (CLIE-897·4) владелец назвал пятый — «Витрина». По канону
   CLIE-631 витрина выбора живёт ТОЛЬКО ДО РЕШЕНИЯ: переключатель `.sc-lab` и ветки
   `[data-speccard="a…d"]` удалены, остался один вид. Не возвращать. */
.spec-card .sc-hero { position: relative; padding: 20px 22px; border-radius: 18px;
  background:
    radial-gradient(120% 160% at 0% 0%, color-mix(in srgb, var(--primary) 16%, transparent), transparent 60%),
    var(--panel-2);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 16%, transparent),
              0 10px 30px -18px rgba(0,0,0,.55); }
.spec-card .sc-ava .cli-av, .spec-card .sc-ava > span,
.spec-card .sc-ava img { width: 72px; height: 72px; min-width: 72px; font-size: 25px;
  box-shadow: 0 0 0 2px var(--panel), 0 0 0 4px color-mix(in srgb, var(--primary) 34%, transparent); }
.spec-card .sc-name { font-size: 23px; }
.spec-card .sc-fact { background: color-mix(in srgb, var(--panel) 78%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 8%, transparent); }
.spec-card .sc-sec { padding: 16px 18px; border-radius: 16px; background: var(--panel-2);
  box-shadow: inset 0 0 0 1px var(--line); }
.spec-card .sc-sec[data-sec="portfolio"] { background: none; box-shadow: none; padding: 0; }
html[data-theme="light"] .spec-card .sc-hero { box-shadow:
  inset 0 0 0 1px color-mix(in srgb, var(--primary) 18%, transparent), 0 10px 26px -20px var(--cm-141e3c-35, rgba(20,30,60,.35)); }

/* 🔴 АВАТАР КАРТОЧКИ НЕ ЗАВИСИТ ОТ ИНЖЕКТА. `.cli-av` — это `<span>`, то есть по умолчанию
   INLINE: ширина и высота на нём не действуют вовсе, и в окне предпросмотра (оно открывается
   мимо `clientsEnsureStyles`) аватар меряется 18×28 по метрике буквы. Раскладку задаём здесь
   же, у самой карточки: класс CLIE-621, только в другом окне. */
.spec-card .sc-ava .cli-av, .spec-card .sc-ava > span {
  display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto;
  background-size: cover; background-position: center; font-weight: 640; overflow: hidden; }

/* ═══════════════════════════════════════════════════════════════════════════════
   РАЗДЕЛ «САЙТЫ» — СПИСОК · СТРАНИЦЫ · ВЕБ-РЕДАКТОР (Сайты · 3/7, CLIE-984)
   Механика — `/app/sites_edit.js` (window.CcSites). Здесь только вид.

   🔴 ЧТО ЗДЕСЬ ЗАПРЕЩЕНО И ПОЧЕМУ НЕТ:
     • левых реек-акцентов (`border-left`) — статус несёт ТОЧКА и СЛОВО (канон accent);
     • своего сегмента — переключатели берут канон `.cc-seg` (канон segment);
     • своих чисел у контролов ряда — высота/радиус/кегль из `--ctl-*` (канон control-size);
     • сырого `<select>` по сущностям — списки ищутся и сортируются (канон entity-list).
   Обе темы держатся на токенах базы: собственных hex в блоке нет.
   ═══════════════════════════════════════════════════════════════════════════════ */
.sed-crumbs { display: flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; }
.sed-crumb { border: 0; background: none; color: var(--muted); font: inherit; font-size: 13px;
  font-weight: 560; padding: 3px 6px; border-radius: 8px; cursor: pointer; white-space: nowrap;
  max-width: 220px; overflow: hidden; text-overflow: ellipsis; transition: color .14s, background .14s; }
.sed-crumb:hover { background: var(--hover); color: var(--text); }
.sed-crumb.on { color: var(--text); cursor: default; }
.sed-crumb-sep { display: inline-flex; color: var(--muted); opacity: .55; }
.sed-crumb-sep svg.ic { width: 13px; height: 13px; }
/* Узкий экран: шапка раздела в один ряд со значками, и все звенья сжимались поровну —
   замер 402 px: «🌐. С › Т… › П.», ни одно слово не читалось. Место — у ТЕКУЩЕГО звена (оно
   сжимается последним), звено сайта — ход назад, сжимается до многоточия, но не в букву. */
@media (max-width: 759px) {
  /* Значок раздела уступает место звеньям (первое звено и так «Сайты»), кнопки шапки — значками:
     вход «Правки клиента» в шапке страниц/редактора (СПЕК §7.2) добавил ряду 130 px, и на 402 px
     «Новая страница» и «×» уезжали за край. */
  /* 🔴 Шапка ПЕРЕНОСИТСЯ, а не сжимает крошки в букву (07.10): в редакторе действий много
     (состояние · «Смотреть сайт» · правки клиента · отменить · опубликовать), и на 375 px текущее
     звено исчезало целиком. Звенья держат свою ширину на первой строке, действия уходят ниже. */
  #sitesOverlay .tw-head { gap: 8px; flex-wrap: wrap; row-gap: 6px; }
  #sitesOverlay .tw-head > .tw-title, #sitesOverlay .tw-head > .tw-spacer { display: none; }
  #sitesOverlay .tw-head .sed-rv-entry > span:not(.tw-seg-badge),
  #sitesOverlay .tw-head [data-act="settings"] > span { display: none; }
  #sitesOverlay .sed-crumbs { flex: 1 1 auto; }
  #sitesOverlay .sed-crumbs > .sed-crumb:first-child:not(:last-child),
  #sitesOverlay .sed-crumbs > .sed-crumb:first-child:not(:last-child) + .sed-crumb-sep { display: none; }
  /* Сжимается сперва звено сайта (до «Т…»), и только потом — текущее, тоже с многоточием. */
  #sitesOverlay .sed-crumb { flex: 0 100 auto; min-width: 2.6em; }
  /* 🔴 ТЕКУЩЕЕ звено НЕ режется раньше звена сайта (07.10): «Наст…»/«Пра…» на 375 px не говорили,
     где человек. Ужимается сперва звено сайта (до «Т…»), а текущее берёт ВЕСЬ остаток строки —
     не «до 60 %» (ревью W9: при свободной строке название сайта всё равно резалось на 169 из 281 px). */
  #sitesOverlay .sed-crumb:last-child { flex: 0 1 auto; min-width: 0; max-width: none; }
  #sitesOverlay .sed-crumb-sep { flex: 0 0 auto; }
  #sitesOverlay .sed-crumb-x { display: none; }
  /* 🔴 «×» ДЕРЖИТ ПЕРВУЮ СТРОКУ (ревью W9, замер 375 px): при переносе шапки он уезжал ОДИН на
     третью строку (страницы — шапка 118 px, редактор — 164 px). Теперь он прибит к правому краю
     первой строки: звенья занимают первую строку до него, действия переносятся ниже на ВСЮ ширину.
     Список (одно звено «Сайты») остаётся одной строкой — звено, «Создать сайт» и «×»; место под
     «×» там — поле шапки справа. */
  #sitesOverlay .tw-head { position: relative; }
  #sitesOverlay .tw-head > #sitesClose { position: absolute; top: 12px; right: 14px; }
  #sitesOverlay .tw-head > .sed-crumbs { flex: 0 1 100%; margin-right: 42px; }
  #sitesOverlay .tw-head:has(> .sed-crumbs > .sed-crumb:only-child) { padding-right: 58px; }
  #sitesOverlay .tw-head:has(> .sed-crumbs > .sed-crumb:only-child) > .sed-crumbs { flex: 1 1 auto; margin-right: 0; }
}

.sed-sub { display: flex; align-items: center; gap: 8px; padding: 8px 12px; flex-wrap: wrap; }
/* 🔴 Сегмент сортировки — в рост поля поиска (канон control-size). `.cc-seg button` (ccroom.css,
   вес 0,1,1) с `padding: 6px 11px` перебивает размер `.cc-seg-md > *` (0,1,0), и дорожка вставала
   на 46 px рядом с полем 36 (кадр «Сайты», 21.10). Снимаем только вертикальные поля: высоту даёт
   line-height канона (--ctl-h − 8), ширина подписей прежняя. Тот же приём — `.ctp-segs .cc-seg-md`. */
.sed-sub .cc-seg-md > * { padding-top: 0; padding-bottom: 0; }
/* Одиночное звено крошек «Сайты» на компьютере повторяло заголовок шапки «Сайты» мелким серым
   словом рядом (кадр 21.10). Прячем его, пока звено одно; на узком экране (≤ 759) заголовок скрыт
   правилом выше, и звено остаётся единственной подписью — там его не трогаем. */
@media (min-width: 760px) {
  #sitesOverlay .tw-head > .sed-crumbs:has(> .sed-crumb:only-child) { display: none; }
}
/* 🔴 220px — это ШИРИНА в строке инструментов. В колонке (`.sed-lib` —
   flex-direction: column) та же строка означала бы ВЫСОТУ 220px и растяжение до
   низа: ровно это владелец увидел как «поиск высота большая» (CLIE-984·Р4).
   Размерный класс контрола задают `--ctl-h/--ctl-r/--ctl-fs`, а не flex-основа. */
.sed-lib .sed-q { flex: 0 0 auto; width: 100%; }
.sed-q { flex: 1 1 220px; min-width: 150px; height: var(--ctl-h); border-radius: var(--ctl-r);
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  padding: 0 10px; font-size: var(--ctl-fs); box-sizing: border-box; }
.sed-q:focus { outline: none; border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); }
/* Поиск в ряду инструментов «Сайтов» — с лупой слева, как `.tw-scope-search` и `.kn-wiki-find`:
   без знака поле читалось простым вводом (кадр 21.10: подсказка от x≈127, лупы нет). Место в ряду
   держит обёртка `.sed-qbox` (та же основа 220/150), поле — во всю её ширину, текст после лупы. */
.sed-qbox { position: relative; display: flex; align-items: center; flex: 1 1 220px; min-width: 150px; }
.sed-qbox > .ic { position: absolute; left: 10px; width: 15px; height: 15px; color: var(--muted); pointer-events: none; }
.sed-qbox > .sed-q { flex: 1 1 auto; min-width: 0; padding-left: 32px; }
.sed-tool { display: inline-flex; align-items: center; gap: 6px; height: var(--ctl-h);
  padding: 0 11px; border-radius: var(--ctl-r); border: 1px solid var(--line);
  background: var(--panel); color: var(--text); font: inherit; font-size: var(--ctl-fs);
  font-weight: 560; cursor: pointer; transition: background .14s, border-color .14s, color .14s; }
.sed-tool:hover { background: var(--hover); }
.sed-tool.on { background: var(--sel); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.sed-tool svg.ic { width: 15px; height: 15px; }
.sed-state { font-size: 12px; color: var(--muted); white-space: nowrap; max-width: 320px;
  overflow: hidden; text-overflow: ellipsis; }
.sed-state.warn { color: var(--warning); font-weight: 560; }

/* ── СПИСКИ: строка несёт ВСЕ данные, статус — точкой и словом ──────────────── */
.sed-list { display: flex; flex-direction: column; gap: 2px; padding: 8px 12px 24px; }
.sed-row { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  padding: 10px 12px; border: 0; border-radius: 12px; background: none; color: var(--text);
  font: inherit; cursor: pointer; transition: background .14s; }
.sed-row:hover { background: var(--hover); }
.sed-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; background: var(--muted); }
.sed-dot-published { background: var(--ok); }
.sed-dot-draft { background: var(--warning); }
.sed-dot-archived { background: var(--muted); opacity: .5; }
.sed-row-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.sed-row-t { font-size: 14px; font-weight: 580; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-row-sub { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-tag { font-size: 11px; font-weight: 620; color: var(--muted); padding: 3px 8px; border-radius: 999px;
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); white-space: nowrap; }
.sed-num, .sed-when { font-size: 12px; color: var(--muted); white-space: nowrap; }
.sed-when { min-width: 62px; text-align: right; }

.sed-empty { display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 56px 24px; text-align: center; color: var(--muted); }
.sed-empty svg.ic { width: 26px; height: 26px; opacity: .5; }
.sed-empty b { font-size: 15px; color: var(--text); font-weight: 600; }
.sed-empty p { margin: 0; max-width: 460px; font-size: 13px; line-height: 1.5; }

/* ── РЕДАКТОР: три колонки, обе боковые тянутся мышью (WIN_PANES) ───────────── */
.sed-wrap { display: flex; height: 100%; min-height: 0; align-items: stretch; }
.sed-left { width: 268px; flex: 0 0 auto; min-width: 0; display: flex; flex-direction: column;
  border-right: 1px solid var(--line); background: var(--panel); overflow: hidden; }
/* 🔴 ПРОКРУЧИВАЕТСЯ ТЕЛО, А НЕ РАМА (CLIE-1077·Р5): у рамы появилась шапка плавающего
   окна, и она обязана стоять на месте, когда список библиотеки уехал вниз. Липкие
   `.sed-lib-head`/`.sed-q` считают верх ОТ ЭТОГО скроллера — он у них и остался. */
.sed-pane-in { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; overflow: auto; }
.sed-lhead { padding: 12px 14px 6px; font-size: 11px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); }
.sed-outline { display: flex; flex-direction: column; gap: 1px; padding: 0 8px 8px; }
.sed-onode { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-radius: 10px;
  cursor: pointer; user-select: none; transition: background .12s; }
.sed-onode:hover { background: var(--hover); }
.sed-onode.on { background: var(--sel); }
.sed-onode.sed-lift { background: var(--panel-2); box-shadow: var(--shadow-2); }
.sed-reordering .sed-onode { transition: transform .16s ease; }
.sed-grip { display: inline-flex; color: var(--muted); opacity: .5; cursor: grab; }
.sed-grip svg.ic { width: 14px; height: 14px; }
.sed-onode-t { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 540;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-onode-k { font-size: 11px; color: var(--muted); white-space: nowrap; }
.sed-lfoot { padding: 4px 12px 14px; }
.sed-addbtn { display: inline-flex; align-items: center; gap: 6px; width: 100%; justify-content: center; }
.sed-hint { padding: 10px 14px; font-size: 12px; line-height: 1.5; color: var(--muted); }

/* Библиотека блоков — всплывает по действию, экран заранее не занимает */
.sed-lib { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px 18px;
  border-top: 1px solid var(--line); background: var(--panel-2); }
/* 🔴 Список НЕ капим и второй бегунок внутрь не ставим (канон scroll, CLIE-620):
   растёт внешняя колонка `.sed-left`. Чтобы при этом поиск не уезжал за верхний
   край на сотне карточек, шапка библиотеки и поле — липкие. */
.sed-lib-head { display: flex; align-items: center; gap: 8px;
  position: sticky; top: 0; z-index: 2; background: var(--panel-2); padding-top: 2px; }
.sed-lib .sed-q { position: sticky; top: 26px; z-index: 2; }
.sed-lib-head b { flex: 1 1 auto; font-size: 13px; font-weight: 640; }
.sed-cats { display: flex; flex-wrap: wrap; gap: 6px; }
.sed-cat, .sed-pill { border: 1px solid var(--line); background: var(--panel); color: var(--muted);
  font: inherit; font-size: 12px; font-weight: 560; padding: 4px 10px; border-radius: 999px;
  cursor: pointer; transition: background .14s, color .14s, border-color .14s; }
.sed-cat:hover, .sed-pill:hover { background: var(--hover); color: var(--text); }
.sed-cat.on, .sed-pill.on { background: var(--sel); color: var(--text);
  border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.sed-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sed-tile { display: flex; flex-direction: column; gap: 6px; padding: 8px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--panel); color: var(--text); font: inherit;
  text-align: left; cursor: pointer; transition: border-color .14s, box-shadow .14s, transform .14s; }
.sed-tile:hover { border-color: color-mix(in srgb, var(--primary) 40%, var(--line));
  box-shadow: var(--shadow-1); transform: translateY(-1px); }
.sed-tile.off { opacity: .45; cursor: not-allowed; }
.sed-tile.off:hover { transform: none; box-shadow: none; border-color: var(--line); }
/* 🔲 ПЛИТКУ МОЖНО ТАЩИТЬ — И ЭТО ВИДНО ДО ТОГО, КАК ЧЕЛОВЕК ПОПРОБУЕТ (CLIE-1077).
   Курсор-«ладонь» — единственная подсказка, которая работает без подписи. */
.sed-tile:not(.off) { cursor: grab; }
.sed-tile:not(.off):active { cursor: grabbing; }
/* Груз под курсором: он летит НАД рамкой страницы, поэтому fixed и без событий —
   иначе он сам стал бы целью попадания и сорвал жест. */
.sed-ghost { position: fixed; left: 0; top: 0; z-index: 100000; pointer-events: none;
  display: flex; flex-direction: column; gap: 2px; max-width: 260px;
  padding: 8px 10px; border-radius: 12px; border: 1px solid var(--line);
  background: var(--panel); color: var(--text); box-shadow: var(--shadow-2);
  font-size: 12px; font-weight: 600; }
.sed-ghost > b { font-size: 12.5px; font-weight: 650; }
.sed-ghost-say { font-weight: 500; color: var(--muted); font-size: 11.5px; }
/* Пока тащат — гасим выделение текста: жест не должен спорить с курсором. */
body.sed-dragging { user-select: none; cursor: grabbing; }
body.sed-dragging .sed-tile { cursor: grabbing; }
/* Доля блока в ряду — видна прямо в структуре страницы: «½» рядом с именем
   отвечает на «почему эти два блока стоят рядом» без открытия карточки. */
.sed-onode-col { flex: 0 0 auto; font-size: 11px; font-weight: 640; line-height: 1;
  padding: 3px 6px; border-radius: 999px; color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
/* ═══ 🧭 МАСТЕР «С ЧЕГО НАЧАТЬ САЙТ» (CLIE-1500·Р2·1) ═══════════════════════════════════
   Выбор пути — ДВЕ РАВНЫЕ плитки, а не «главная кнопка + мелкая ссылка рядом»: владелец
   не увидел выбора именно потому, что пути были неравны по весу. Токены общие с разделом
   (--line/--panel/--primary), своей палитры мастер не заводит — обе темы даром. */
.sed-start { padding: 14px 16px 28px; max-width: 900px; margin: 0 auto;
  display: flex; flex-direction: column; gap: 14px; }
.sed-start-h { display: flex; flex-direction: column; gap: 4px; }
.sed-start-h b { font-size: 17px; font-weight: 650; color: var(--text); }
.sed-start-h span { font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.sed-ways { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 12px; }
.sed-way { display: grid; grid-template-columns: 34px 1fr; grid-template-rows: auto auto;
  gap: 4px 10px; text-align: left; padding: 14px; border-radius: 14px; cursor: pointer;
  border: 1px solid var(--line); background: var(--panel); color: var(--text);
  transition: box-shadow .16s, transform .16s, border-color .16s, background .16s; }
.sed-way:hover { box-shadow: var(--shadow-1); transform: translateY(-1px); }
.sed-way.on { border-color: color-mix(in srgb, var(--primary) 55%, var(--line));
  background: color-mix(in srgb, var(--primary) 8%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 26%, transparent); }
.sed-way-i { grid-row: 1 / span 2; width: 34px; height: 34px; border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--primary-2, var(--primary)); }
.sed-way-i svg { width: 17px; height: 17px; }
.sed-way-t { display: flex; align-items: center; gap: 8px; min-width: 0; }
.sed-way-t b { font-size: 14.5px; font-weight: 640; }
.sed-way-b { font-style: normal; font-size: 10.5px; font-weight: 650; letter-spacing: .02em;
  padding: 2px 7px; border-radius: 999px; color: var(--primary-2, var(--primary));
  background: color-mix(in srgb, var(--primary) 14%, transparent); }
.sed-way-s { font-size: 12px; line-height: 1.5; color: var(--muted); }
.sed-start-body { display: flex; flex-direction: column; gap: 12px; }
.sed-howto { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 7px;
  font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.sed-howto b { color: var(--text); font-weight: 620; }
.sed-howto-tpl { padding-left: 0; }
.sed-howto-tpl p { margin: 0; }
.sed-brief { min-height: 118px; resize: vertical; line-height: 1.5; }
.sed-start-ex { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.sed-start-ex .sed-hint { padding: 0; }
.sed-files { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.sed-files .sed-hint { padding: 0; }
.sed-file { display: inline-flex; align-items: center; gap: 6px; max-width: 320px;
  padding: 5px 6px 5px 9px; border-radius: 999px; font-size: 12px; color: var(--text);
  border: 1px solid var(--line); background: var(--panel); }
.sed-file svg { width: 13px; height: 13px; color: var(--muted); flex: 0 0 auto; }
.sed-file b { font-weight: 560; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-file-s { color: var(--muted); flex: 0 0 auto; }
.sed-file-x { width: 20px; height: 20px; flex: 0 0 auto; padding: 0; border: 0; border-radius: 50%;
  background: transparent; color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; }
.sed-file-x:hover { background: var(--hover); color: var(--text); }
.sed-file-up { color: var(--muted); }
.sed-start-acts { display: flex; align-items: center; gap: 8px; }
/* 🔴 ОДИН РЯД — ОДИН РАЗМЕРНЫЙ КЛАСС (CLIE-505). Главное действие мастера крупнее строчных
   кнопок раздела, и вторичная кнопка растёт ВМЕСТЕ с ним, иначе в ряду ступенька высот.
   `nowrap` — потому что глобальное `button svg.ic { display: block }` роняет подпись со
   значком на вторую строку, как только ряду становится тесно (тот же класс, что СРЕД-33). */
.sed-start-acts .primary.small, .sed-start-acts .ghost.small {
  font-size: 13px; padding: 9px 16px; border-radius: 10px; white-space: nowrap; flex: 0 0 auto; }
.sed-start-wait { font-size: 12.5px; line-height: 1.5; color: var(--primary-2, var(--primary));
  padding: 9px 12px; border-radius: 10px;
  background: color-mix(in srgb, var(--primary) 9%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 20%, transparent); }

/* Каталог шаблонов сайтов (Сайты · 5/7): карточки с обложкой-скриншотом, а не список текста —
   человек выбирает глазами. Тот же язык, что .sed-tile (радиус, хэйрлайн, подъём на hover). */
.sed-tpl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px; padding: 8px 12px 24px; }
.sed-tpl-card { border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
  background: var(--panel); transition: box-shadow .16s, transform .16s; }
.sed-tpl-card:hover { box-shadow: var(--shadow-1); transform: translateY(-2px); }
.sed-tpl-cover { aspect-ratio: 4/3; background-size: cover; background-position: center;
  background-color: var(--bg-soft); }
.sed-tpl-body { padding: 10px 12px 12px; display: flex; flex-direction: column; gap: 6px; }
.sed-tpl-t { font-size: 13.5px; font-weight: 620; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-tpl-sub { font-size: 11.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-tpl-take { width: 100%; margin-top: 2px; }
.sed-tile-t { font-size: 12px; font-weight: 620; }
.sed-tile-w { font-size: 11px; color: var(--muted); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* 🔴 Превью блока — СХЕМА раскладки ИЗ САМОГО РЕЕСТРА (`pv` типа), а не одна
   форма на всех: у каждого куска свой рисунок, поэтому «Команда», «Галерея»,
   «Цены» и «Отзывы» видно и без подписи (CLIE-984·Р4). */
.sed-prev { display: flex; flex-direction: column; gap: 3px; height: 44px; padding: 6px;
  border-radius: 8px; background: var(--bg-soft); box-shadow: inset 0 0 0 1px var(--line);
  overflow: hidden; }
.sed-prev i { display: block; height: 4px; border-radius: 2px; background: var(--muted);
  opacity: .35; flex: 0 0 auto; }
/* Куски схемы: имена те же, что в реестре (`pv: ["h","tiles"]`). */
.sed-prev .pv-h { width: 58%; height: 6px; opacity: .55; }
.sed-prev .pv-p { width: 92%; }
.sed-prev .pv-li { width: 84%; }
.sed-prev .pv-li + .pv-li { width: 72%; }
.sed-prev .pv-row { width: 100%; height: 7px; border-radius: 3px; opacity: .28; }
.sed-prev .pv-note { width: 100%; flex: 1 1 auto; min-height: 10px; border-radius: 5px; opacity: .22; }
.sed-prev .pv-quote { width: 88%; flex: 1 1 auto; min-height: 12px; border-radius: 5px; opacity: .22;
  border-left: 3px solid color-mix(in srgb, var(--muted) 60%, transparent); background: none; }
.sed-prev .pv-img { width: 100%; flex: 1 1 auto; min-height: 12px; border-radius: 5px; opacity: .3;
  background: linear-gradient(135deg, var(--muted) 0%, transparent 70%); }
.sed-prev .pv-btn { width: 34%; height: 8px; border-radius: 4px; opacity: .5; }
.sed-prev .pv-foot { width: 100%; height: 9px; border-radius: 3px; opacity: .25; margin-top: auto; }
.sed-prev .pv-sum { width: 46%; height: 8px; opacity: .55; align-self: flex-end; }
.sed-prev .pv-tiles, .sed-prev .pv-cards, .sed-prev .pv-grid, .sed-prev .pv-tb,
.sed-prev .pv-mx, .sed-prev .pv-cal, .sed-prev .pv-pay {
  width: 100%; flex: 1 1 auto; min-height: 12px; height: auto; border-radius: 3px;
  background: none; opacity: 1;
  background-image: linear-gradient(color-mix(in srgb, var(--muted) 42%, transparent) 0 0);
  background-repeat: repeat; }
.sed-prev .pv-tiles { background-size: 30% 100%; background-position: 0 0;
  box-shadow: inset 0 0 0 0 transparent;
  background-image: repeating-linear-gradient(90deg,
    color-mix(in srgb, var(--muted) 42%, transparent) 0 30%, transparent 30% 35%); }
.sed-prev .pv-cards { background-image: repeating-linear-gradient(90deg,
    color-mix(in srgb, var(--muted) 42%, transparent) 0 46%, transparent 46% 54%); }
.sed-prev .pv-grid { background-image:
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--muted) 42%, transparent) 0 30%, transparent 30% 35%),
    repeating-linear-gradient(0deg, transparent 0 45%, transparent 45% 55%); }
.sed-prev .pv-tb { background-image: repeating-linear-gradient(0deg,
    color-mix(in srgb, var(--muted) 42%, transparent) 0 22%, transparent 22% 33%); }
.sed-prev .pv-mx { background-image:
    repeating-linear-gradient(90deg, color-mix(in srgb, var(--muted) 38%, transparent) 0 22%, transparent 22% 28%),
    repeating-linear-gradient(0deg, color-mix(in srgb, var(--muted) 26%, transparent) 0 40%, transparent 40% 50%); }
.sed-prev .pv-cal { background-image: repeating-linear-gradient(90deg,
    color-mix(in srgb, var(--muted) 34%, transparent) 0 12%, transparent 12% 20%); }
.sed-prev .pv-pay { background-image: repeating-linear-gradient(90deg,
    color-mix(in srgb, var(--muted) 46%, transparent) 0 18%, transparent 18% 33%); }
.sed-prev-rows i:first-child { width: 60%; }
.sed-prev-rows i:nth-child(2) { width: 92%; }
.sed-prev-rows i:last-child { width: 78%; }
.sed-prev-cover { justify-content: center; align-items: center; }
.sed-prev-cover i:first-child { width: 70%; height: 8px; opacity: .5; }
.sed-prev-cover i:nth-child(2) { width: 46%; }
.sed-prev-cover i:last-child { width: 26%; height: 7px; opacity: .5; }
.sed-prev-tiles { flex-direction: row; align-items: stretch; }
.sed-prev-tiles i { flex: 1 1 0; height: auto; }
.sed-prev-table i { width: 100%; }
.sed-prev-table i:first-child { opacity: .55; }
.sed-prev-menu { flex-direction: row; align-items: center; }
.sed-prev-menu i { flex: 0 0 auto; width: 18%; }
.sed-prev-menu i:first-child { width: 34%; opacity: .55; }
.sed-prev-sum { justify-content: flex-end; }
.sed-prev-sum i:last-child { width: 44%; height: 8px; opacity: .55; align-self: flex-end; }
.sed-prev-plan i:nth-child(2) { width: 70%; margin-left: 12%; }
.sed-prev-plan i:last-child { width: 44%; margin-left: 30%; }
.sed-prev-form i:last-child { width: 40%; height: 9px; opacity: .55; }
.sed-where { padding: 0; }

/* Сцена: рамка со САМОЙ страницей — правка идёт по рендеру публики */
.sed-stage { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column;
  align-items: center; background: var(--bg-soft); padding: 14px; overflow: auto; }
.sed-frame { width: 100%; max-width: 1280px; height: 100%; min-height: 420px; border: 0;
  border-radius: 14px; background: #fff; box-shadow: var(--shadow-2); }
.sed-stage[data-dev="mobile"] .sed-frame { width: 402px; max-width: 402px; border-radius: 26px; }
.sed-frame-say { display: none; margin-top: 12px; font-size: 13px; color: var(--muted);
  max-width: 520px; text-align: center; line-height: 1.5; }
.sed-frame-say.on { display: block; }

/* 🌐 КОЛОНКА АИ РЯДОМ С САЙТОМ (CLIE-1500, владелец: «слева сайт справа чат. Можно открыть
   сайт на весь экрна тогда чат поверх»).
   🔴 ВНУТРИ — КАНОНИЧЕСКАЯ рама встроенной Аи (`.cc-aya-fab`/`.cc-aya-pop`, CRMC-1136), та же,
      что в почте и CRM. Своей вёрстки чата у сайтов нет: колонка даёт раме МЕСТО, а оба
      обещания владельца («рядом» и «поверх») — это ДВЕ раскладки ОДНОЙ рамы, не два окна. */
.sed-aya { width: 380px; flex: 0 0 auto; min-width: 0; display: flex; flex-direction: column;
  border-left: 1px solid var(--line); background: var(--panel); overflow: hidden; }
.sed-aya[hidden] { display: none; }
/* Пузыря-кнопки у колонки нет: Аю здесь зовут кнопкой «Ая» в инструментах редактора, и два
   входа в одно окно спорили бы между собой состоянием. */
.sed-aya > .cc-aya-fab { display: none; }
/* «Рядом»: рама теряет оконную геометрию и занимает колонку целиком — это ТА ЖЕ рама. */
.sed-aya > .cc-aya-pop { position: static; width: 100%; max-width: none; height: 100%;
  border: 0; border-radius: 0; box-shadow: none; }
/* Адрес правки (сайт · страница · блок) живёт в подписи рамы и потому переезжает вместе с
   ней в режим «поверх»; 190 px почтовой темы для пути страницы мало. */
.sed-aya .cc-aya-head > span { min-width: 0; }
.sed-aya .cc-aya-sub { max-width: none; }
/* «ПОВЕРХ»: во весь экран колонка схлопывается, а рама всплывает окном над страницей. Колонку
   нельзя просто спрятать — внутри неё сам чат, и человек потерял бы открытый разговор. */
#sitesOverlay.sed-full .sed-aya { width: 0; border-left: 0; background: transparent;
  overflow: visible; }
#sitesOverlay.sed-full .sed-aya > .cc-aya-pop { position: fixed; right: 20px; bottom: 20px;
  width: min(440px, calc(100vw - 40px)); height: min(620px, calc(100vh - 110px));
  border: 1px solid var(--line); border-radius: 16px; box-shadow: 0 18px 48px rgba(0, 0, 0, .35); }

/* Карточка блока / дизайн-система — правая колонка ВСПЛЫВАЕТ по выбору */
.sed-right { width: 0; flex: 0 0 auto; overflow: hidden; border-left: 1px solid var(--line);
  background: var(--panel); display: flex; flex-direction: column; }
.sed-right.on { width: 320px; }
.sed-card-head { display: flex; align-items: center; gap: 8px; padding: 12px 12px 8px; }
.sed-card-head b { flex: 1 1 auto; min-width: 0; font-size: 14px; font-weight: 640;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-card-k { font-size: 11px; color: var(--muted); }
.sed-right .cc-seg { margin: 0 12px; }
.sed-card-body { display: flex; flex-direction: column; gap: 12px; padding: 12px; }
.sed-f { display: flex; flex-direction: column; gap: 6px; font-size: 12px; color: var(--muted); }
.sed-f > span { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-weight: 560; }
.sed-fv { color: var(--text); font-weight: 620; font-variant-numeric: tabular-nums; }
.sed-f-row { flex-direction: row; align-items: center; gap: 8px; }
.sed-in { width: 100%; box-sizing: border-box; min-height: var(--ctl-h);
  border-radius: var(--ctl-r); border: 1px solid var(--line); background: var(--bg-soft);
  color: var(--text); padding: 6px 10px; font: inherit; font-size: var(--ctl-fs); resize: vertical; }
.sed-in:focus { outline: none; border-color: color-mix(in srgb, var(--primary) 55%, var(--line));
  background: var(--panel); }
.sed-rng { width: 100%; accent-color: var(--primary); }
.sed-col { width: 100%; height: 30px; padding: 2px; border-radius: 9px;
  border: 1px solid var(--line); background: var(--panel); cursor: pointer; }
.sed-chk { accent-color: var(--primary); width: 15px; height: 15px; }
.sed-pills { display: flex; flex-wrap: wrap; gap: 6px; }
.sed-imgbtn { display: inline-flex; align-items: center; gap: 6px; justify-content: center; width: 100%; }
.sed-card-acts { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 12px 20px; }
/* 🔴 ОПАСНОЕ ДЕЙСТВИЕ КАРТОЧКИ — ЧЕРНИЛА, А НЕ ЗАЛИВКА. Замер прода 15.09.2026, тёмная
   тема: подложка rgb(210,100,122) И чернила rgb(210,100,122) — контраст 1.00, подписи
   «Удалить» не видно ВОВСЕ (кнопка есть, а прочитать её нельзя). Причина: в боевом
   концепте `--danger` это ЧЕРНИЛА на тёмном холсте (заливка живёт отдельным
   `--danger-fill`), а общий `.danger` красит фон именно чернилами — местное правило
   перекрашивало текст тем же цветом. Лечим по канону акцента: тинт-подложка + кольцо
   хэйрлайном + чернила своим токеном; заливкой опасное действие карточки не бывает. */
/* 🔴 Селектор с `#sitesOverlay`: общая пара правил базы кончается на
   `html[data-theme="light"] .danger` (0,2,1) — без id светлая тема продолжала бы красить
   ЗАЛИВКОЙ, и один и тот же контрол выглядел бы в двух темах по-разному. */
#sitesOverlay .sed-card-acts .danger, #sitesOverlay .sed-c2acts .danger,
#sitesOverlay .sed-rv-acts .danger, #sitesOverlay .sed-rv-bar .danger {
  color: var(--danger);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  border-color: transparent;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 26%, transparent);
}
#sitesOverlay .sed-card-acts .danger:hover, #sitesOverlay .sed-c2acts .danger:hover,
#sitesOverlay .sed-rv-acts .danger:hover, #sitesOverlay .sed-rv-bar .danger:hover {
  background: color-mix(in srgb, var(--danger) 20%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════════════
   🖥 РЕЖИМ «ВО ВЕСЬ ЭКРАН» — ХОЛСТ ЗАНИМАЕТ ОКНО, ПАНЕЛИ ПЛАВАЮТ ПОВЕРХ (CLIE-1077·Р5)

   Владелец 15.09.2026, с кадром редактора: «Нужна возможность раскрыть на весь экран,
   рабочие блоки тогда будут модалками поверх с возможностью скрыть и раскрыть».
   Замер ДО правки на проде (окно 1680×1050, библиотека открыта, блок выбран): шапка 53 +
   полоса инструментов 57 сверху, колонки 268 и 320 по бокам — СТРАНИЦЕ доставалось
   952×844, то есть 45,5 % окна.

   🔴 Вторая вёрстка редактора не заводится: это тот же `#sitesOverlay`, те же `.sed-left`,
      `.sed-right` и `.sed-frame`. Класс на раме меняет РАСКЛАДКУ, а не состав.
   🔴 Ширину и место плавающей панели считает ядро окон (инлайновые left/top/width/height):
      здесь только вид рамы — фон, тень, скругление, шапка, свёрнутое состояние.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Рама поднимается над рельсой продукта: «весь экран» — это весь экран, а не «всё, кроме
   левой полосы». `z-index` ниже пузыря быстрого чата (9100) намеренно: сквозной элемент
   продукта не имеет права пропасть на новой поверхности (канон cross-cutting). */
#sitesOverlay.sed-full { position: fixed; inset: 0; z-index: 8000; }
#sitesOverlay.sed-full .tw-head { display: none; }
#sitesOverlay.sed-full .tw-body { overflow: hidden; }

/* ПУЛЬТ — плавающая полоса: инструменты, устройство, состояние, «Опубликовать» и ВЫХОД.
   Она не накрывает страницу: сцена отдаёт ей верхнюю полосу (ниже `padding-top`), иначе
   верх сайта навсегда оставался бы под ней. */
#sitesOverlay.sed-full .sed-sub {
  position: fixed; top: 9px; left: 50%; transform: translateX(-50%); z-index: 16;
  width: max-content; max-width: calc(100vw - 24px); flex-wrap: nowrap;
  padding: 6px 8px; border-radius: 999px; gap: 6px;
  background: color-mix(in srgb, var(--panel) 90%, transparent);
  box-shadow: var(--shadow-2), inset 0 0 0 1px var(--line);
  -webkit-backdrop-filter: saturate(1.5) blur(12px); backdrop-filter: saturate(1.5) blur(12px);
}
#sitesOverlay.sed-full .sed-sub .tw-spacer { flex: 0 0 8px; }
#sitesOverlay.sed-full .sed-headacts { display: inline-flex; align-items: center; gap: 6px; }
#sitesOverlay.sed-full .sed-state { max-width: 200px; }

/* СЦЕНА: страница во всю ширину окна, поля и скругление рамки убраны — это холст. */
#sitesOverlay.sed-full .sed-stage { padding: 54px 0 0; }
#sitesOverlay.sed-full .sed-frame { max-width: none; border-radius: 0; box-shadow: none; }
#sitesOverlay.sed-full .sed-stage[data-dev="mobile"] .sed-frame {
  border-radius: 20px; box-shadow: var(--shadow-2); margin-top: 8px; height: calc(100% - 16px); }

/* ПАНЕЛИ — ОКНА ПОВЕРХ ХОЛСТА. Геометрию ставит ядро; здесь рама и её поведение. */
#sitesOverlay.sed-full .sed-left,
#sitesOverlay.sed-full .sed-right.on {
  position: fixed; z-index: 14; width: 320px; height: 560px; max-height: none;
  display: flex; flex-direction: column; overflow: visible;
  border: 0; border-radius: 14px; background: var(--panel);
  box-shadow: 0 24px 70px rgba(0, 0, 0, .28), 0 0 0 1px var(--line);
}
#sitesOverlay.sed-full .sed-left > .sed-pane-in,
#sitesOverlay.sed-full .sed-right > .sed-pane-in {
  border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; }
/* Закрытая панель не висит нулевой полоской поверх страницы — её нет. */
#sitesOverlay.sed-full .sed-right:not(.on) { display: none; }
#sitesOverlay.sed-full .sed-left.off { display: none; }
/* Пока тащат или тянут окно — кадр не перехватывает указатель (иначе жест «прилипает»). */
#sitesOverlay.sed-full .sed-left.resizing, #sitesOverlay.sed-full .sed-right.resizing { user-select: none; }
/* Тянут кромку окна — кадр перестаёт ловить указатель: иначе жест «прилипает» к чужому
   документу ровно в тот момент, когда окно переезжает границу рамки. Перетаскивание за
   шапку этим не лечится и не нуждается: его держит захват указателя в ядре окон. */
#sitesOverlay.sed-full .sed-wrap:has(.resizing) .sed-frame { pointer-events: none; }
/* Шапка карточки блока и дизайн-системы в окне не нужна: её имя и «×» несёт шапка ОКНА —
   два заголовка подряд читаются как «панель внутри панели». */
#sitesOverlay.sed-full .sed-right .sed-card-head { display: none; }
/* По той же причине уходит и заголовок колонки слева: «Структура страницы» уже написана
   на шапке окна, а два одинаковых заголовка подряд человек читает как сбой вёрстки. */
#sitesOverlay.sed-full .sed-left .sed-lhead { display: none; }
#sitesOverlay.sed-full .sed-left .sed-pane-in { padding-top: 6px; }

/* ШАПКА ПЛАВАЮЩЕГО ОКНА — в колонке её нет (таскать нечего). */
.sed-pane-bar { display: none; }
#sitesOverlay.sed-full .sed-pane-bar {
  display: flex; align-items: center; gap: 6px; flex: 0 0 auto; height: 40px;
  padding: 0 6px 0 10px; cursor: grab; background: var(--panel-2);
  border-bottom: 1px solid var(--line);
  border-top-left-radius: inherit; border-top-right-radius: inherit;
}
#sitesOverlay.sed-full .sed-left.dragging .sed-pane-bar,
#sitesOverlay.sed-full .sed-right.dragging .sed-pane-bar { cursor: grabbing; }
.sed-pane-grip { display: inline-flex; color: var(--muted); opacity: .55; }
.sed-pane-grip svg.ic { width: 14px; height: 14px; }
.sed-pane-t { flex: 1 1 auto; min-width: 0; font-size: 13px; font-weight: 640;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-pane-say { display: none; font-size: 12px; color: var(--muted); white-space: nowrap; }

/* СВЁРНУТО: от окна остаётся ШАПКА у нижней кромки — видно, что панель жива, и куда
   вернуться. Возврат — нажатием по этой же шапке (ядро окон), поэтому кнопки в свёрнутом
   виде убраны: у полоски одно значение, а не три. */
#sitesOverlay.sed-full .sed-left.docked,
#sitesOverlay.sed-full .sed-right.docked {
  height: 40px !important; border-radius: 12px 12px 0 0; cursor: pointer; }
#sitesOverlay.sed-full .docked .sed-pane-in,
#sitesOverlay.sed-full .docked .sed-pane-act,
#sitesOverlay.sed-full .docked .fw-rz { display: none; }
#sitesOverlay.sed-full .docked .sed-pane-say { display: inline; }
#sitesOverlay.sed-full .docked .sed-pane-bar { border-bottom: 0; cursor: pointer; }

/* Хваталки растягивания ядро вешает прямо в узел — в колоночном виде их быть не должно:
   там ширину тянет шов раздвижных колонок (WIN_PANES), и две хваталки спорили бы. */
#sitesOverlay:not(.sed-full) .fw-rz { display: none; }

/* Ниже планшета три колонки не помещаются: боковые ложатся полосами, а рамка
   со страницей остаётся главной — это её экран, а не панелей. */
@media (max-width: 900px) {
  .sed-wrap { flex-direction: column; }
  .sed-left { width: auto; border-right: 0; border-bottom: 1px solid var(--line); max-height: 40%; }
  .sed-right.on { width: auto; border-left: 0; border-top: 1px solid var(--line); max-height: 45%; }
  /* 🔴 Узкий экран и так «весь экран» — плавающие окна тут только мешают: три колонки в
     него не влезают, и панель поверх закрыла бы страницу целиком. Режим схлопывается в
     обычную раскладку. `!important` обязателен: ширину, высоту и место окну ставит ядро
     ИНЛАЙНОМ, а инлайн сильнее правила — без него панель осталась бы 320×660 полосой. */
  #sitesOverlay.sed-full .sed-left, #sitesOverlay.sed-full .sed-right.on,
  #sitesOverlay.sed-full .sed-left.docked, #sitesOverlay.sed-full .sed-right.docked {
    position: static !important; width: auto !important; height: auto !important;
    left: auto !important; top: auto !important; box-shadow: none; border-radius: 0; cursor: auto; }
  #sitesOverlay.sed-full .docked .sed-pane-in { display: flex; }
  #sitesOverlay.sed-full .sed-sub { position: static; transform: none; border-radius: 0; max-width: none;
    width: auto; flex-wrap: wrap; backdrop-filter: none; -webkit-backdrop-filter: none; box-shadow: none;
    background: none; }
  #sitesOverlay.sed-full .tw-head { display: flex; }
  #sitesOverlay.sed-full .sed-stage { padding: 8px; }
  #sitesOverlay.sed-full .sed-left .sed-lhead { display: block; }
  #sitesOverlay.sed-full .sed-right .sed-card-head { display: flex; }
  #sitesOverlay.sed-full .sed-pane-bar, #sitesOverlay.sed-full .fw-rz { display: none; }
  .sed-stage { padding: 8px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   САЙТЫ · Ч7 — НАСТРОЙКИ САЙТА (публикация · свой домен · аналитика) и ЯЩИК ИИ
   (CLIE-982, часть 7 из 7). Токены ряда те же (--ctl-h/--ctl-r/--ctl-fs), цвета —
   из палитры продукта, поэтому обе темы одинаковы без второго набора правил.
   🔴 Левых полос-реек здесь нет ни одной: состояние несёт ТОЧКА + СЛОВО (канон accent).
   ═══════════════════════════════════════════════════════════════════════════ */
.sed-set { display: flex; flex-direction: column; gap: 14px; padding: 16px;
  max-width: 760px; margin: 0 auto; width: 100%; box-sizing: border-box; }
.sed-card2 { border: 1px solid var(--line); border-radius: 16px; background: var(--panel);
  padding: 16px; display: flex; flex-direction: column; gap: 10px;
  box-shadow: 0 1px 2px rgba(0,0,0,.04); }
.sed-c2h { display: flex; align-items: center; gap: 8px; }
.sed-c2h b { font-size: 15px; font-weight: 640; letter-spacing: -.01em; }
.sed-c2h .cc-seg { margin-left: auto; }
.sed-c2p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--muted); }
/* ⏳ «Ждём ответа» просящего — на МЕСТЕ кнопки «Попросить доступ» (`my_ask` / `fix.asked` сервера):
   второй просьбы человеку не оставляем, состояние видно и после F5. */
.sed-ask-wait { display: flex; align-items: flex-start; gap: 8px; color: var(--text); }
.sed-ask-wait > svg.ic { width: 16px; height: 16px; flex: 0 0 auto; margin-top: 2px; color: var(--primary-2); }

/* Состояние — точка + слово (никаких полос слева). */
.sed-dot2 { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; background: var(--muted); }
.sed-dot2-live { background: var(--ok); }
.sed-dot2-dirty { background: var(--warning); }
.sed-dot2-draft { background: var(--muted); }
.sed-dot2-off { background: var(--danger); }
.sed-dot2-archived { background: var(--muted); opacity: .5; }
.sed-dot2-dns_wait, .sed-dot2-cert_wait { background: var(--warning); }
.sed-dot2-failed { background: var(--danger); }

/* 🔴 Поле-значение и его кнопки — на ДВУХ строках (правило владельца CLIE-425):
   мелкое поле рядом с крупной кнопкой схлопывается, а кнопка раздувается. */
.sed-linkrow { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
.sed-linkacts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
/* 🔗 Ссылка-кнопка: ОДИН рецепт на вкладку «Публикация» и на шапку редактора (CLIE-1500·Р4).
   Размеры — из --ctl-* (канон control-size): ссылка стоит в одном ряду с «Опубликовать» и
   обязана быть ей ростом вровень, иначе ряд «убогий». */
.sed-linkacts .btn, .sed-live { display: inline-flex; align-items: center; height: var(--ctl-h);
  padding: 0 12px; border-radius: var(--ctl-r); border: 1px solid var(--line);
  color: var(--text); text-decoration: none; font-size: var(--ctl-fs); }
.sed-live { gap: 6px; font-weight: 560; background: var(--panel); }
.sed-live:hover { background: var(--hover); }
.sed-live svg.ic { width: 15px; height: 15px; }
/* 🔴 `hidden` прячет ТОЛЬКО если авторский CSS не назначил классу свой display (канон
   progressive-disclosure): у .sed-live он назначен, поэтому гасим явно. */
.sed-live[hidden] { display: none; }
.sed-linkacts .sed-hint { padding: 0; }
.sed-c2acts { display: flex; flex-wrap: wrap; gap: 8px; }

/* 🚚 ГДЕ ЖИВЁТ САЙТ: у нас · мой GitHub · мой сервер · мой компьютер (CLIE-1500·Р5·④).
   🔴 Своих цветов здесь нет ни одного — всё из палитры продукта, поэтому светлая и тёмная
      темы получаются ОДНИМ набором правил, а не двумя расходящимися (канон
      theme-contrast-runtime: прибитый цвет темы не имеет).
   🔴 Ряд полей берёт --ctl-* через .sed-in (канон control-size): поле приёмника стоит в
      одном столбце с «Опубликовать» и обязано быть ему ростом вровень. */
.sed-tgtseg { display: flex; }
.sed-tgtseg .cc-seg { width: 100%; }
.sed-tgtsub { margin-top: -2px; }
/* Честный рассказ «что мы храним» — со значком замка: человек отдаёт нам чужой доступ и
   имеет право прочитать это раньше, чем нажмёт «Подключить». */
.sed-keeps { margin: 0; display: flex; align-items: flex-start; gap: 8px; font-size: 13px;
  line-height: 1.5; color: var(--text); border-radius: 12px; padding: 10px 12px;
  background: color-mix(in srgb, var(--ok) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 22%, transparent); }
.sed-keeps svg.ic { width: 15px; height: 15px; flex: 0 0 auto; margin-top: 2px; color: var(--ok); }
.sed-needs { font-size: 12px; }
.sed-tgtfields { display: flex; flex-direction: column; gap: 10px; }
.sed-tgtf { display: flex; flex-direction: column; gap: 4px; }
.sed-tgtf > span { font-size: 12px; font-weight: 560; color: var(--muted); }
/* Отказ приёмника — словами и цветом отказа, но БЕЗ левой рейки (канон accent). */
.sed-tgterr { color: var(--danger); border-radius: 12px; padding: 10px 12px;
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent); }
/* Поле во всю ширину: ключ и выбор протокола половинкой колонки не читаются. */
.sed-tgtkey { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  line-height: 1.45; resize: vertical; min-height: calc(var(--ctl-h) * 1.6); }
@media (min-width: 560px) {
  .sed-tgtfields { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
  .sed-tgtf:first-child { grid-column: 1 / -1; }
  .sed-tgtf-w { grid-column: 1 / -1; }
}

.sed-arec { display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--muted); }
.sed-arec code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px;
  padding: 4px 8px; border-radius: 8px; background: var(--bg-soft);
  box-shadow: inset 0 0 0 1px var(--line); color: var(--text); }

.sed-doms { display: flex; flex-direction: column; gap: 10px; }
.sed-dom { border-radius: 12px; padding: 12px; background: var(--bg-soft);
  box-shadow: inset 0 0 0 1px var(--line); display: flex; flex-direction: column; gap: 8px; }
.sed-dom-h { display: flex; align-items: center; gap: 8px; }
.sed-dom-h b { font-size: 13px; font-weight: 620; }
.sed-dom-st { margin-left: auto; font-size: 12px; color: var(--muted); }

/* Числа аналитики: сетка, а не таблица — на телефоне складывается сама. */
.sed-nums { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; }
.sed-num2 { display: flex; flex-direction: column; gap: 2px; padding: 12px; border-radius: 12px;
  background: var(--bg-soft); box-shadow: inset 0 0 0 1px var(--line); }
.sed-num2 b { font-size: 22px; font-weight: 660; letter-spacing: -.02em; }
.sed-num2 span { font-size: 12px; color: var(--muted); }
.sed-sub2 { font-size: 12px; font-weight: 620; color: var(--muted); margin-top: 4px; }
.sed-bars { display: flex; flex-direction: column; gap: 6px; }
.sed-bar { display: grid; grid-template-columns: minmax(80px, 1fr) 2fr auto; align-items: center; gap: 10px; }
.sed-bar-t { font-size: 12px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-bar-l { height: 6px; border-radius: 999px; background: var(--bg-soft);
  box-shadow: inset 0 0 0 1px var(--line); overflow: hidden; }
.sed-bar-l i { display: block; height: 100%; border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 70%, transparent); }
.sed-bar-n { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.sed-utm { display: flex; flex-direction: column; gap: 4px; }
.sed-utm-r { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  font-size: 12px; color: var(--muted); }
.sed-utm-r b { color: var(--text); font-variant-numeric: tabular-nums; }
.sed-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }

/* ── ЯЩИК ИИ У ТЕКСТОВОГО СЛОТА ─────────────────────────────────────────────
   Разбор ЧИТАЮТ (кнопки у него нет вовсе), вариант ПРИМЕНЯЮТ — и «Применить»
   стоит у КАЖДОГО варианта отдельно. */
.sed-aibtn { display: inline-flex; align-items: center; gap: 4px; border: 0; cursor: pointer;
  background: transparent; color: var(--primary); font-size: 11px; font-weight: 620;
  padding: 2px 6px; border-radius: 8px; }
.sed-aibtn:hover { background: color-mix(in srgb, var(--primary) 10%, transparent); }
.sed-aibtn svg { width: 13px; height: 13px; }
.sed-ai { border-top: 1px solid var(--line); padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.sed-ai-h { display: flex; align-items: center; gap: 8px; }
.sed-ai-h b { font-size: 13px; font-weight: 640; }
.sed-ai-k { font-size: 11px; color: var(--muted); margin-left: auto; }
/* Исходный текст показываем ЦЕЛИКОМ: свой скролл внутри уже скроллящейся колонки —
   это второй скролл на одном экране (храповик CLIE-620). Растёт он, скроллит колонка. */
.sed-ai-src { font-size: 12px; line-height: 1.5; color: var(--muted); padding: 10px;
  border-radius: 10px; background: var(--bg-soft); box-shadow: inset 0 0 0 1px var(--line);
  white-space: pre-wrap; }
.sed-ai-say { font-size: 12px; line-height: 1.6; color: var(--text); white-space: pre-wrap; }
.sed-ai-opt { border-radius: 12px; padding: 10px; background: var(--panel);
  box-shadow: inset 0 0 0 1px var(--line); display: flex; flex-direction: column; gap: 8px; }
.sed-ai-ot { font-size: 11px; font-weight: 640; color: var(--muted); text-transform: none; }
.sed-ai-ox { font-size: 13px; line-height: 1.5; white-space: pre-wrap; }
.sed-ai-warn { font-size: 11px; color: var(--warning); }
.sed-ai-err { font-size: 12px; color: var(--danger); }
.sed-ai-asks { display: flex; flex-wrap: wrap; gap: 6px; }

/* ── ГОТОВЫЕ ЦВЕТА (вид поля `swatch` общего ядра `block_editor.js`) ──────────────
   Выбор глазами одним касанием + «свой цвет» последней мишенью. Выбранный — кольцо,
   а не заливка строки (канон accent). Работает в обеих темах: кольцо — токены. */
.sed-sws { display: flex; flex-wrap: wrap; gap: 7px; }
.sed-sw { position: relative; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 8px;
  cursor: pointer; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 16%, transparent);
  transition: transform .12s, box-shadow .12s; }
.sed-sw:hover { transform: scale(1.08); }
.sed-sw.on { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 16%, transparent),
  0 0 0 2px var(--panel), 0 0 0 4px var(--primary); }
.sed-sw-none { background: linear-gradient(135deg, transparent 45%, var(--danger) 46% 54%, transparent 55%), var(--bg-soft); }
.sed-sw-own { display: inline-block; overflow: hidden;
  background: conic-gradient(from 90deg, #ef4444, #e5a23c, #16a34a, #0ea5a4, #4f46e5, #ef4444); }
.sed-sw-own input.sed-col { position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0;
  opacity: 0; cursor: pointer; }

/* ═══════════════════════════════════════════════════════════════════════════════
   ✍️ САЙТЫ · «ПРАВКИ КЛИЕНТА» (СПЕК site-review §7) — вид `S.view = "review"` в той же раме
   `#sitesOverlay`. Три колонки на весь экран продукта: список правок | сайт глазами клиента |
   карточка правки. Владелец: «не мельчи модалки — сразу крутое пространство».
   🔴 Левых реек нет ни одной: стадия правки — точка + слово в пилюле-тинте (канон accent:
      подложка color-mix 12% + кольцо 22%). Чекбокс — тот же квадрат продукта `.kn-mt-ck`,
      сегмент — `.cc-seg`, счётчик «Новых» — `.tw-seg-badge`, страница — `.sed-stage/.sed-frame`
      редактора: своей второй вёрстки у правок нет.
   🔴 Цвета — только токены базы, поэтому обе темы держит ОДИН набор правил.
   ═══════════════════════════════════════════════════════════════════════════════ */
/* «Нет в этом состоянии» — гасим явно: у кнопок и ссылок продукта свой display, и `hidden`
   его не перебивает (канон progressive-disclosure). */
#sitesOverlay .sed-rv-off { display: none !important; }
#sitesOverlay .sed-sub.sed-rv-nosub { display: none; }

/* Входы: кнопка в шапке страниц/редактора и пилюля в строке списка сайтов */
.sed-rv-entry .tw-seg-badge { margin-left: 2px; }
#sitesOverlay .sed-rv-entry, #sitesOverlay .sed-rv-hbtn { white-space: nowrap; }
.sed-rv-pill { display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto; padding: 3px 9px;
  border-radius: 999px; font-size: 11.5px; font-weight: 640; white-space: nowrap; cursor: pointer;
  color: var(--primary-2); background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); transition: background .14s; }
.sed-rv-pill:hover { background: color-mix(in srgb, var(--primary) 20%, transparent); }
.sed-rv-pill svg.ic { width: 13px; height: 13px; }

/* Полоса над колонками: ссылка клиента · фильтр со счётчиками · поиск */
.sed-rv-link { display: inline-flex; align-items: center; gap: 6px; flex: 0 1 auto; min-width: 0;
  max-width: min(460px, 42vw); height: var(--ctl-h); padding: 0 3px 0 10px; box-sizing: border-box;
  border-radius: var(--ctl-r); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); color: var(--muted); }
.sed-rv-link > svg.ic { width: 14px; height: 14px; flex: 0 0 auto; }
.sed-rv-url { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12.5px; color: var(--text); }
.sed-rv-chipbtn { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  height: calc(var(--ctl-h) - 6px); padding: 0 9px; border: 0; border-radius: calc(var(--ctl-r) - 2px);
  background: var(--panel); color: var(--text); font: inherit; font-size: 12px; font-weight: 600;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .1); cursor: pointer; transition: background .14s; }
.sed-rv-chipbtn:hover { background: var(--hover); }
.sed-rv-chipbtn svg.ic { width: 13px; height: 13px; }
.sed-rv-chipic { padding: 0 6px; background: transparent; box-shadow: none; color: var(--muted); }
.sed-rv-chipic:hover { color: var(--text); }
.sed-rv-segbox { display: inline-flex; flex: 0 0 auto; }
.sed-rv-segn { margin-left: 6px; font-size: 11.5px; font-weight: 600; color: var(--muted);
  font-variant-numeric: tabular-nums; }
.cc-seg > .on .sed-rv-segn { color: inherit; opacity: .72; }
.sed-q.sed-rv-q { flex: 1 1 200px; max-width: 320px; margin-left: auto; }

/* Рама вида: три колонки, середина резиновая (крайние тянутся мышью — WIN_PANES) */
.sed-rv { display: flex; height: 100%; min-height: 0; position: relative; align-items: stretch; }
.sed-rv kbd { display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px;
  padding: 0 5px; box-sizing: border-box; border-radius: 5px; font: 600 10.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--muted); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line), 0 1px 0 var(--line); }

/* ── Список правок ── */
.sed-rv-list { width: 400px; flex: 0 0 auto; min-width: 0; display: flex; flex-direction: column;
  border-right: 1px solid var(--line); background: var(--panel); }
.sed-rv-lhead { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; min-height: 48px;
  padding: 8px 14px 8px 10px; box-sizing: border-box; border-bottom: 1px solid var(--line); }
.sed-rv-lhead:empty { display: none; }
.sed-rv-all { display: inline-flex; flex: 0 0 auto; white-space: nowrap; align-items: center; gap: 9px; padding: 5px 9px 5px 6px; border: 0;
  border-radius: 9px; background: none; color: var(--text); font: inherit; font-size: 13px; font-weight: 580;
  cursor: pointer; transition: background .14s; }
.sed-rv-all:hover { background: var(--hover); }
.sed-rv-alln { font-size: 11.5px; font-weight: 650; color: var(--muted); font-variant-numeric: tabular-nums; }
.sed-rv-lsum { margin-left: auto; font-size: 12px; color: var(--muted); white-space: nowrap; }
.sed-rv .kn-mt-ck.mixed { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; }
/* 🔴 Нижний отступ 84px — место сквозного пузыря быстрого чата (#qcFab: 56px + 20px снизу, левый
   нижний угол — ровно над этой колонкой). Прятать пузырь нельзя (канон cross-cutting), поэтому
   расходится содержимое — тот же приём, что у «выбрано для ИИ» и коммита в среде (.dvs-picked). */
.sed-rv-rows { flex: 1 1 auto; min-height: 0; overflow: auto; padding: 0 8px 84px; outline: none; }
.sed-rv-group { position: sticky; top: 0; z-index: 1; display: flex; align-items: baseline; gap: 8px;
  padding: 14px 8px 6px; background: var(--panel); font-size: 11px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--muted); }
.sed-rv-gt { white-space: nowrap; }
.sed-rv-gp { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-transform: none; letter-spacing: 0; font-weight: 500; opacity: .75; }
.sed-rv-group > b { margin-left: auto; font-variant-numeric: tabular-nums; }
.sed-rv-row { display: grid; grid-template-columns: 20px 72px minmax(0, 1fr); gap: 12px; align-items: start;
  padding: 12px 10px; border-radius: 12px; cursor: pointer; transition: background .12s, box-shadow .12s; }
.sed-rv-row:hover { background: var(--hover); }
.sed-rv-row.picked { background: color-mix(in srgb, var(--primary) 6%, transparent); }
.sed-rv-row.on { background: var(--sel); }
/* Кольцо фокуса у СПИСКА не рисуем — его несёт выделенная строка: клавиатура ведёт по строкам,
   и рамка вокруг всей колонки только шумела бы (база кольца — :where(…[tabindex]):focus-visible). */
.sed-rv-rows:focus-visible { box-shadow: none; }
.sed-rv-rows:focus-visible .sed-rv-row.on { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--primary) 55%, transparent); }
.sed-rv-row .kn-mt-ck { margin-top: 2px; opacity: .7; }
.sed-rv-row:hover .kn-mt-ck, .sed-rv-row .kn-mt-ck.on { opacity: 1; }
.sed-rv-thumb { width: 72px; height: 54px; border-radius: 9px; overflow: hidden; display: flex;
  align-items: center; justify-content: center; background: var(--bg-soft); color: var(--muted);
  box-shadow: inset 0 0 0 1px var(--line); }
.sed-rv-thumb img { width: 100%; height: 100%; object-fit: cover; object-position: top center; display: block; }
.sed-rv-thumb svg.ic { width: 18px; height: 18px; opacity: .6; }
.sed-rv-main { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.sed-rv-t { font-size: 13.5px; line-height: 1.45; color: var(--text); overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; word-break: break-word; }
.sed-rv-no { margin-right: 6px; font-weight: 650; color: var(--muted); font-variant-numeric: tabular-nums; }
.sed-rv-row.done .sed-rv-t { color: var(--muted); }
.sed-rv-row.done .sed-rv-thumb { opacity: .7; }
.sed-rv-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 6px; font-size: 11.5px; color: var(--muted); }
.sed-rv-sep { opacity: .55; }
.sed-rv-blk { max-width: 140px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-rv-meta .sed-rv-st { margin-left: auto; }
.sed-rv-st { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px; border-radius: 999px;
  font-size: 11px; font-weight: 640; white-space: nowrap; line-height: 1.5;
  color: var(--primary-2); background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.sed-rv-st i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.sed-rv-st-ai { color: var(--warning); background: color-mix(in srgb, var(--warning) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 22%, transparent); }
.sed-rv-st-done { color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 22%, transparent); }
.sed-rv-warn { display: flex; align-items: flex-start; gap: 6px; font-size: 11.5px; line-height: 1.4; color: var(--warning); }
.sed-rv-warn svg.ic { width: 13px; height: 13px; flex: 0 0 auto; margin-top: 1px; }

/* Пустые состояния списка и ошибка — слова + выход, «нажал — ничего» не бывает */
.sed-rv-empty, .sed-rv-idle { display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 52px 24px; text-align: center; color: var(--muted); }
.sed-rv-empty b, .sed-rv-idle b { font-size: 15px; font-weight: 640; color: var(--text); }
.sed-rv-empty p, .sed-rv-idle p { margin: 0; max-width: 300px; font-size: 13px; line-height: 1.5; }
.sed-rv-empty-ic { width: 48px; height: 48px; margin-bottom: 4px; border-radius: 14px; display: flex;
  align-items: center; justify-content: center; background: var(--panel-2); color: var(--muted);
  box-shadow: inset 0 0 0 1px var(--line); }
.sed-rv-empty-ic svg.ic { width: 22px; height: 22px; }
.sed-rv-empty-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 8px; }
.sed-rv-keys { list-style: none; margin: 14px 0 0; padding: 0; display: inline-grid; gap: 8px; text-align: left; font-size: 12px; }
.sed-rv-keys li { display: flex; align-items: center; gap: 5px; }
.sed-rv-keys li span { margin-left: 4px; }
.sed-rv-err { margin: auto; }

/* Скелет загрузки — той же геометрии, что содержимое, чтобы экран не «прыгал» */
.sed-rv-sk { display: flex; flex-direction: column; gap: 10px; padding: 14px 4px; }
.sed-rv-sk i { display: block; height: 70px; border-radius: 12px; background: var(--panel-2); animation: glShimmer 1.2s ease-in-out infinite; }
.sed-rv-sk i:nth-child(2n) { animation-delay: .12s; }
.sed-rv-skpage { flex: 1 1 auto; display: flex; padding: 18px; }
.sed-rv-skpage i { flex: 1 1 auto; border-radius: 14px; background: var(--panel-2); animation: glShimmer 1.2s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .sed-rv-sk i, .sed-rv-skpage i { animation: none; } }

/* ИИ сделал правки в черновике — баннер-напоминание с ДЕЙСТВИЕМ «Опубликовать» */
.sed-rv-banner { margin: 12px 12px 0; padding: 12px 14px; border-radius: 14px; display: grid;
  grid-template-columns: 28px minmax(0, 1fr); gap: 4px 10px; align-items: start;
  background: color-mix(in srgb, var(--primary) 10%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.sed-rv-banner-ic { width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; color: var(--primary-2); background: color-mix(in srgb, var(--primary) 16%, transparent); }
.sed-rv-banner-ic svg.ic { width: 15px; height: 15px; }
.sed-rv-banner-t { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sed-rv-banner-t b { font-size: 13px; font-weight: 640; color: var(--text); }
.sed-rv-banner-t span { font-size: 12px; color: var(--muted); }
.sed-rv-banner-acts { grid-column: 2; display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }

/* ── Липкая полоса выбора внизу списка ── */
.sed-rv-bar { flex: 0 0 auto; display: flex; flex-direction: column; gap: 10px; padding: 12px 14px 84px;
  border-top: 1px solid var(--line); background: var(--panel);
  box-shadow: 0 -12px 24px -18px rgba(0, 0, 0, .45); }
.sed-rv-bar-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 13px; }
.sed-rv-bar-top b { font-weight: 650; color: var(--text); }
.sed-rv-bar-acts { display: flex; align-items: center; gap: 8px; }
/* Ряд кнопок — ОДИН размерный класс (канон control-size): высота и радиус из --ctl-*. */
#sitesOverlay .sed-rv-bar-acts > button { height: var(--ctl-h); border-radius: var(--ctl-r); }
#sitesOverlay .sed-rv-bar-acts > .icon-btn { width: var(--ctl-h); padding: 0; justify-content: center; }
.sed-rv-bar-ai { flex: 1 1 auto; }
.sed-rv-bar-ai .sed-rv-bar-n { margin-left: 2px; padding: 1px 7px; border-radius: 999px; font-size: 11px;
  font-weight: 700; background: rgba(255, 255, 255, .24); font-variant-numeric: tabular-nums; }
.sed-rv-textbtn { display: inline-flex; align-items: center; gap: 6px; padding: 3px 6px; margin: -3px -6px;
  border: 0; border-radius: 7px; background: none; color: var(--primary-2); font: inherit; font-size: 12.5px;
  font-weight: 580; cursor: pointer; transition: background .14s; }
.sed-rv-textbtn:hover { background: var(--hover); }
.sed-rv-textbtn svg.ic { width: 14px; height: 14px; }
.sed-rv-notetg { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px; max-width: 100%;
  padding: 2px 0; border: 0; background: none; color: var(--muted); font: inherit; font-size: 12.5px; cursor: pointer; }
.sed-rv-notetg span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-rv-notetg:hover, .sed-rv-notetg.has { color: var(--primary-2); }
.sed-rv-notetg svg.ic { width: 14px; height: 14px; flex: 0 0 auto; }
.sed-in.sed-rv-note { min-height: 76px; resize: vertical; font-size: 13px; line-height: 1.45; }

/* ── Середина: сайт глазами клиента ── */
.sed-rv-stage { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; background: var(--bg-soft); }
.sed-rv-ptop { flex: 0 0 auto; display: flex; align-items: center; gap: 10px; min-height: 52px;
  padding: 8px 14px 8px 16px; box-sizing: border-box; border-bottom: 1px solid var(--line); background: var(--panel); }
.sed-rv-pt { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.sed-rv-pt svg.ic { width: 15px; height: 15px; color: var(--muted); flex: 0 0 auto; }
.sed-rv-pt b { font-size: 13.5px; font-weight: 640; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sed-rv-pt span { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sed-rv-pin { display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto; padding: 3px 9px; border-radius: 999px;
  font-size: 12px; font-weight: 640; color: var(--primary-2); background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); font-variant-numeric: tabular-nums; }
.sed-rv-pin svg.ic { width: 13px; height: 13px; }
.sed-rv-ptop .cc-seg { flex: 0 0 auto; }
.sed-stage.sed-rv-pbox { flex: 1 1 auto; min-height: 0; padding: 18px; }
.sed-rv-pbox .sed-frame { flex: 1 1 auto; min-height: 0; }
/* «‹ Назад» живёт только в один столбец; `#sitesOverlay` — сильнее `.ghost.small { display: inline-flex }`. */
#sitesOverlay .sed-rv-back { display: none; }

/* Ссылки ещё нет — герой с тремя шагами и одной главной кнопкой */
#sitesOverlay .sed-rv[data-mode="hero"] .sed-rv-stage,
#sitesOverlay .sed-rv[data-mode="error"] .sed-rv-stage { overflow: auto; background: var(--bg); }
.sed-rv-hero { margin: auto; width: 100%; max-width: 780px; box-sizing: border-box; padding: 48px 28px 40px;
  display: flex; flex-direction: column; align-items: center; gap: 14px; text-align: center; }
.sed-rv-hero-ic { width: 64px; height: 64px; border-radius: 20px; display: flex; align-items: center;
  justify-content: center; color: var(--primary-2); background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.sed-rv-hero-ic svg.ic { width: 28px; height: 28px; }
.sed-rv-hero h2 { margin: 6px 0 0; font-size: 26px; line-height: 1.2; font-weight: 700; letter-spacing: -.02em; color: var(--text); }
.sed-rv-hero > p { margin: 0; max-width: 540px; font-size: 14.5px; line-height: 1.55; color: var(--muted); }
.sed-rv-steps { list-style: none; margin: 14px 0 4px; padding: 0; width: 100%; display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.sed-rv-step { display: flex; flex-direction: column; gap: 6px; padding: 18px; border-radius: 16px; text-align: left;
  background: var(--panel); box-shadow: inset 0 0 0 1px var(--line), var(--shadow-1); }
.sed-rv-step i { width: 28px; height: 28px; margin-bottom: 6px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; font-style: normal; font-size: 13px; font-weight: 700; color: var(--primary-2);
  background: color-mix(in srgb, var(--primary) 12%, transparent); }
.sed-rv-step b { font-size: 14px; font-weight: 640; color: var(--text); }
.sed-rv-step span { font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.sed-rv-hero-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 10px; }
#sitesOverlay .sed-rv-cta { display: inline-flex; align-items: center; justify-content: center; gap: 8px; width: auto;
  height: 44px; margin: 0; padding: 0 20px; border-radius: 12px; font-size: 14px; font-weight: 600; }
#sitesOverlay .ghost.sed-rv-cta { background: var(--panel); border: 1px solid var(--line); color: var(--text); }
#sitesOverlay .ghost.sed-rv-cta:hover { background: var(--hover); }
.sed-rv-cta svg.ic { width: 16px; height: 16px; }
.sed-rv-fine { margin: 4px 0 0; font-size: 12px; line-height: 1.5; color: var(--muted); max-width: 520px; }

/* ── Карточка правки ── */
.sed-rv-card { width: 440px; flex: 0 0 auto; min-width: 0; display: flex; flex-direction: column; overflow: auto;
  border-left: 1px solid var(--line); background: var(--panel); }
.sed-rv-chead { position: sticky; top: 0; z-index: 2; display: flex; align-items: center; gap: 10px;
  padding: 14px 14px 10px 18px; background: var(--panel); }
.sed-rv-cno { font-size: 15px; font-weight: 680; letter-spacing: -.01em; color: var(--text); white-space: nowrap; }
#sitesOverlay .sed-rv-cardx { display: none; }
/* scroll-cap-ok: снимок места — ПРЕВЬЮ, а не документ: целиком он открывается по клику общим
   просмотрщиком (зум, полёт кадра), поэтому обрезка по высоте здесь намеренная. */
.sed-rv-shot { display: block; flex: 0 0 auto; width: calc(100% - 36px); max-height: 320px; margin: 2px 18px 0;
  padding: 0; border: 0; border-radius: 14px; overflow: hidden; cursor: zoom-in; background: var(--bg-soft);
  box-shadow: inset 0 0 0 1px var(--line); transition: box-shadow .14s; }
.sed-rv-shot:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 45%, var(--line)), var(--shadow-1); }
.sed-rv-shot img { display: block; width: 100%; height: 100%; max-height: 320px; object-fit: cover; object-position: top center; }
.sed-rv-cbody { display: flex; flex-direction: column; gap: 16px; padding: 18px 18px 28px; }
.sed-rv-quote { margin: 0; padding: 14px 16px; border-radius: 14px; background: var(--panel-2);
  font-size: 15.5px; line-height: 1.55; color: var(--text); white-space: pre-wrap; word-break: break-word; }
.sed-rv-who { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted); }
.sed-rv-who svg.ic { width: 14px; height: 14px; flex: 0 0 auto; }
.sed-rv-who b { font-weight: 620; color: var(--text); }
.sed-rv-ainote { display: flex; align-items: flex-start; gap: 8px; padding: 10px 12px; border-radius: 12px;
  font-size: 12.5px; line-height: 1.45; color: var(--text);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 22%, transparent); }
.sed-rv-ainote svg.ic { width: 15px; height: 15px; flex: 0 0 auto; margin-top: 1px; color: var(--warning); }
.sed-rv-facts { margin: 0; display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: 10px 12px; font-size: 12.5px; }
.sed-rv-facts dt { color: var(--muted); }
.sed-rv-facts dd { margin: 0; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  color: var(--text); line-height: 1.45; }
.sed-rv-el { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 2px 7px;
  border-radius: 6px; font: 11.5px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--muted);
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.sed-rv-place { align-self: flex-start; margin: 0; }
.sed-rv-place kbd { margin-left: 4px; }
.sed-rv-acts { display: flex; flex-direction: column; gap: 10px; padding-top: 16px; border-top: 1px solid var(--line); }
#sitesOverlay .sed-rv-aibtn { display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 44px; margin: 0; padding: 0 18px; border-radius: 12px; font-size: 14px; }
.sed-rv-aibtn svg.ic { width: 16px; height: 16px; }
.sed-rv-withnote { margin: -2px 0 0; font-size: 12px; line-height: 1.45; color: var(--muted); }
.sed-rv-withnote:empty { display: none; }
.sed-rv-acts2 { display: flex; flex-wrap: wrap; gap: 8px; }
#sitesOverlay .sed-rv-acts2 > button { height: var(--ctl-h); border-radius: var(--ctl-r); }
.sed-rv-aistate { display: flex; align-items: center; gap: 8px; padding: 10px 12px; border-radius: 12px;
  font-size: 13px; color: var(--text); background: color-mix(in srgb, var(--warning) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 22%, transparent); }
.sed-rv-aistate svg.ic { width: 16px; height: 16px; flex: 0 0 auto; color: var(--warning); }

/* Состояния вида: без ссылки — только герой; ссылка без правок — список + сайт; ошибка —
   слова и выход посередине. Правила стоят ПОСЛЕ раскладок и сильнее их. */
#sitesOverlay .sed-rv[data-mode="hero"] .sed-rv-list, #sitesOverlay .sed-rv[data-mode="hero"] .sed-rv-card,
#sitesOverlay .sed-rv[data-mode="error"] .sed-rv-list, #sitesOverlay .sed-rv[data-mode="error"] .sed-rv-card,
#sitesOverlay .sed-rv[data-mode="empty"] .sed-rv-card, #sitesOverlay .sed-rv[data-mode="loading"] .sed-rv-card { display: none !important; }

/* Средний экран: карточка ВСПЛЫВАЕТ поверх страницы по выбору правки (у неё есть «×» и Esc) */
@media (max-width: 1099px) {
  .sed-rv-list { width: 340px; }
  /* Шапка не переносит подписи в две строки: «Открыть как клиент» и «Поделиться» остаются
     значками с подсказкой (то же действие, меньше места), сводка списка уступает место выбору. */
  #sitesOverlay .sed-rv-hbtn > span { display: none; }
  .sed-rv-lsum { display: none; }
  .sed-rv-link { max-width: 260px; }
  .sed-q.sed-rv-q { flex: 1 1 140px; max-width: 220px; }
  .sed-rv-card { position: absolute; top: 12px; right: 12px; bottom: 12px; z-index: 6; width: min(420px, calc(100% - 24px));
    display: none; border: 1px solid var(--line); border-radius: 18px; box-shadow: var(--shadow-2); }
  .sed-rv[data-card="1"] .sed-rv-card { display: flex; }
  #sitesOverlay .sed-rv-cardx { display: inline-flex; }
  .sed-rv-steps { grid-template-columns: 1fr; }
}
/* Узкий экран: один столбец — список → правка на весь экран («‹ Назад») → место на странице */
@media (max-width: 759px) {
  .sed-rv-list, .sed-rv-stage, .sed-rv-card { position: absolute; inset: 0; z-index: 1; display: none;
    width: auto !important; max-width: none !important; flex: none !important;
    border: 0; border-radius: 0; box-shadow: none; }
  .sed-rv[data-pane="list"] .sed-rv-list, .sed-rv[data-pane="card"] .sed-rv-card,
  .sed-rv[data-pane="page"] .sed-rv-stage { display: flex; }
  /* 🔴 В один столбец видимую колонку решает ТОЛЬКО `data-pane`. Правило среднего экрана
     `[data-card="1"] .sed-rv-card{display:flex}` (0,3,0) действует и здесь и клало карточку
     поверх места на странице: «Показать место» на телефоне не делало ничего видимого. Это
     правило той же силы и стоит позже — оно и решает (и при сужении окна с открытой карточкой). */
  .sed-rv:not([data-pane="card"]) .sed-rv-card { display: none; }
  #sitesOverlay .sed-rv[data-mode="hero"] .sed-rv-stage, #sitesOverlay .sed-rv[data-mode="error"] .sed-rv-stage { display: flex; }
  #sitesOverlay .sed-rv-back { display: inline-flex; }
  #sitesOverlay .sed-rv-cardx { display: none; }
  .sed-rv-link { max-width: 100%; }
  .sed-q.sed-rv-q { max-width: none; margin-left: 0; }
  /* Сегмент не вылезает за край: дорожка канона `.cc-seg` сама прокручивается с тающими
     краями (ccSegFit), ей нужно только знать свою ширину. */
  .sed-rv-segbox { flex: 1 1 100%; min-width: 0; }
  .sed-rv-segbox > .cc-seg { max-width: 100%; }
  /* «К страницам» дублирует крошку сайта, а в одну колонку шапке нужен каждый пиксель. */
  #sitesOverlay .sed-rv-hpages { display: none; }
  .sed-rv-facts { grid-template-columns: 96px minmax(0, 1fr); }
  .sed-rv-place kbd, .sed-rv-idle .sed-rv-keys { display: none; }
  .sed-stage.sed-rv-pbox { padding: 8px; }
  /* Шапка страницы в один столбец переносится, а не режется: «‹ Главная №8» — первой строкой,
     «Десктоп | Телефон» и ⟳ — второй. Замер 402 px: название страницы сжималось в ноль, а ⟳
     уезжал за край колонки. */
  .sed-rv-ptop { flex-wrap: wrap; row-gap: 8px; padding: 8px 12px; }
  .sed-rv-hero { padding: 28px 16px; }
  .sed-rv-hero h2 { font-size: 22px; }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   🌐 САЙТЫ · ДОСТУП, ПРИВЯЗКА, ФИЛЬТРЫ (СПЕК site-access §6.1/§6.2, клетки W1–W6 §8)
   Свои детали — только раскладка; кнопки, чипы фильтра, сегмент и пикер — каноны продукта
   (`.ghost.small`, `.lead-filter`, `.v2-fl-*`, `.cc-seg`, `.ccpp`), размеры ряда — `--ctl-*`.
   Акцент — точка/иконка + слово, подложка color-mix 10–14 % и кольцо 22 % (канон accent),
   левых реек нет. Цвета — токены базы: обе темы держатся сами, своих hex нет.
   ═══════════════════════════════════════════════════════════════════════════════ */
/* Состояние публикации строки — пять исходов сервера (`pub_state`), точкой. */
.sed-dot-live { background: var(--ok); }
.sed-dot-dirty { background: var(--warning); }
.sed-dot-off { background: var(--danger); }
/* ── Тулбар списка: «Фильтры» с бейджем числа (канон list-cfg: ползунки = фильтры ЭТОГО списка) ── */
.sed-fslot { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.sed-fbtn { display: inline-flex; align-items: center; gap: 6px; height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs); }
.sed-fbtn svg.ic { width: 15px; height: 15px; }
.sed-fbadge { min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; background: var(--acc-fill, var(--primary)); color: #fff;
  font-size: 11px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
.sed-fl .v2-fl-chip { max-width: 100%; }
.sed-fl-n { margin-left: 4px; font-weight: 700; opacity: .72; font-variant-numeric: tabular-nums; }
.sed-fl-none { font-size: 12.5px; color: var(--muted); line-height: 1.45; }
/* Применённые фильтры над списком: чип с крестиком; `stale` — серый, фильтр НЕ применён. */
.sed-fchips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 8px 12px 0; }
.sed-fchip { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; height: 26px; padding: 0 4px 0 10px; border-radius: 8px;
  font-size: 12px; font-weight: 600; color: var(--text); background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.sed-fchip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-fchip.stale { color: var(--muted); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); text-decoration: line-through;
  text-decoration-color: color-mix(in srgb, var(--muted) 60%, transparent); }
.sed-fchip-x { display: inline-flex; border: 0; background: none; color: inherit; padding: 3px; border-radius: 6px; cursor: pointer; opacity: .7; }
.sed-fchip-x:hover { opacity: 1; background: var(--hover); }
.sed-fchip-x svg.ic { width: 12px; height: 12px; }
.sed-fshown { font-size: 12px; color: var(--muted); }
.sed-linkbtn { border: 0; background: none; padding: 0; font: inherit; color: var(--primary-2); cursor: pointer; font-weight: 600; }
.sed-linkbtn:hover { text-decoration: underline; }
/* Плашка состояния над списком/страницами: замок за неуплату, архив, баннер админа. */
.sed-plate { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 8px 12px 0; padding: 10px 12px; border-radius: 12px;
  font-size: 13px; color: var(--text); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.sed-plate > svg.ic { width: 16px; height: 16px; color: var(--muted); flex: 0 0 auto; }
.sed-plate > span { flex: 1 1 200px; min-width: 0; line-height: 1.4; }
.sed-plate.warn, .sed-plate.sed-coa { background: color-mix(in srgb, var(--warning) 11%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 22%, transparent); }
.sed-plate.warn > svg.ic, .sed-plate.sed-coa > svg.ic { color: var(--warning); }
/* ── Строка сайта: чипы второй строкой, «⋯» — своё меню, а не открытие сайта ── */
.sed-row-chips { display: flex; flex-wrap: wrap; gap: 4px 6px; margin-top: 3px; min-width: 0; }
.sed-chip { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; height: 20px; padding: 0 7px; border-radius: 6px;
  font-size: 11.5px; font-weight: 560; color: var(--muted); background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.sed-chip > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-chip svg.ic { width: 12px; height: 12px; flex: 0 0 auto; }
.sed-chip-proj > i { width: 7px; height: 7px; border-radius: 50%; background: var(--lc, var(--muted)); flex: 0 0 auto; }
.sed-chip-ro { color: var(--text); background: color-mix(in srgb, var(--primary) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.sed-chip-act { color: var(--primary-2); cursor: pointer; }
.sed-chip-act:hover { background: var(--hover); }
.sed-more { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 30px; height: 30px; border-radius: 8px;
  color: var(--muted); cursor: pointer; }
.sed-more:hover, .sed-more:focus-visible { background: var(--hover); color: var(--text); outline: none; }
.sed-more svg.ic { width: 16px; height: 16px; }
.sed-tag { max-width: 220px; overflow: hidden; text-overflow: ellipsis; }
/* ── Шапка сайта: кнопка-состояние доступа ── */
.sed-accbtn { display: inline-flex; align-items: center; gap: 6px; max-width: 280px; min-width: 0; }
.sed-accbtn-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ── Редактор только для чтения: колонок правки нет, полоса словами + «Попросить доступ» ── */
.sed-ro { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px 8px; min-width: 0; font-size: 12.5px; color: var(--text);
  padding: 4px 6px 4px 10px; border-radius: var(--ctl-r); background: color-mix(in srgb, var(--primary) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.sed-ro.warn { background: color-mix(in srgb, var(--warning) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 22%, transparent); }
.sed-ro > svg.ic { width: 14px; height: 14px; flex: 0 0 auto; }
.sed-ro > span { min-width: 0; }
.sed-wrap-ro > .sed-left, .sed-wrap-ro > .sed-right, .sed-wrap-ro > .sed-aya { display: none; }
/* ── Мастер создания: необязательный «Проект» ── */
.sed-start-proj { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin: 2px 0 10px; }
.sed-pickbtn { display: inline-flex; align-items: center; gap: 6px; max-width: 100%; min-width: 0; }
.sed-pickbtn > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* ── Вкладка «Доступ» ── */
.sed-acc { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.sed-acc-part { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.sed-acc-part:empty { display: none; }
.sed-acc-sheet { min-width: 0; }
.sed-acc-skel { gap: 10px; }
.sed-acc-skel > i { display: block; height: 14px; border-radius: 7px; background: var(--panel-2); }
.sed-acc-skel > i:nth-child(2) { width: 70%; }
.sed-acc-skel > i:nth-child(3) { width: 45%; }
.sed-acc-sum .sed-c2h svg.ic, .sed-acc-coa .sed-c2h svg.ic { width: 16px; height: 16px; color: var(--muted); flex: 0 0 auto; }
.sed-acc-sum .sed-c2h b { min-width: 0; }
.sed-acc-reqs { gap: 8px; }
.sed-acc-req { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; padding: 8px 10px; border-radius: 12px;
  background: color-mix(in srgb, var(--primary) 10%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.sed-acc-req > svg.ic { width: 16px; height: 16px; color: var(--primary-2); flex: 0 0 auto; }
.sed-acc-req-t { flex: 1 1 180px; min-width: 0; font-size: 13px; }
.sed-bind-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 8px 0; border-top: 1px solid var(--line); }
.sed-bind-row:first-of-type { border-top: 0; }
.sed-bind-l { flex: 0 0 120px; font-size: 12.5px; color: var(--muted); }
.sed-bind-v { flex: 1 1 160px; min-width: 0; display: inline-flex; align-items: center; gap: 6px; font-size: 13.5px; font-weight: 560; }
.sed-bind-v > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sed-bind-v svg.ic { width: 14px; height: 14px; color: var(--muted); flex: 0 0 auto; }
.sed-bind-dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.sed-bind-grey { font-size: 12px; color: var(--muted); }
/* ── Правки клиента у того, кто только смотрит ── */
.sed-rv-ro { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted); }
.sed-rv-ro > svg.ic { width: 14px; height: 14px; flex: 0 0 auto; }
/* ── Лист доступа ВНУТРИ вкладки (`fsAccessSheet(…, {mount})`): та же модалка без рамы окна.
   Стили листа инжектит `filesEnsureStyles` ПОЗЖЕ этого файла — поэтому селекторы на ступень
   сильнее (`.fac-mount .fac.fac-embed`), а не `!important`. ── */
.fac-mount { min-width: 0; }
.fac-mount .fac.fac-embed { width: 100%; max-height: none; border-radius: 16px; box-shadow: none; transform: none; }
.fac-mount .fac.fac-embed .fac-main { min-height: 260px; max-height: 460px; }
.fac-mount .fac.fac-embed .fac-granted { max-height: 200px; }
.fac-site { display: flex; flex-direction: column; gap: 8px; padding: 4px 20px 0; }
.fac-site:empty { display: none; }
.fac-wide { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; font-size: 13px; color: var(--text); }
.fac-wide-t { font-weight: 600; }
.fac-wide-rc { flex: 1 1 220px; min-width: 0; font-size: 12px; color: var(--muted); line-height: 1.4; }
.fac-also, .fac-pinrow { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 12.5px; color: var(--muted); line-height: 1.4; }
.fac-also { flex-wrap: nowrap; align-items: flex-start; }
.fac-also > span { flex: 1 1 auto; min-width: 0; }
.fac-also b { color: var(--text); font-weight: 600; }
.fac-also > svg, .fac-pinrow > svg { width: 14px; height: 14px; flex: 0 0 auto; margin-top: 2px; }
.fac-pinrow { padding: 8px 10px; border-radius: 10px; background: color-mix(in srgb, var(--warning) 11%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warning) 22%, transparent); color: var(--text); }
.fac-linkbtn { border: 0; background: none; padding: 0; font: inherit; font-weight: 600; color: var(--primary-2); cursor: pointer; }
.fac-linkbtn:hover { text-decoration: underline; }
.fac-quick { display: flex; }
.fac-ro { padding: 14px 16px; border-radius: 14px; background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); font-size: 13px; line-height: 1.45; }
.fac-ro p { margin: 0; }
.fac-ro p.fac-ro-who { margin-top: 6px; color: var(--muted); }
.fac-out-h { font-size: 10.5px; font-weight: 720; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); padding: 12px 12px 4px; }
.fac-row.fac-out { cursor: default; flex-wrap: wrap; }
.fac-row.fac-out .fac-row-nm { flex: 1 1 140px; }
.fac-row.fac-out:hover { background: none; }
.fac-row.fac-out .ghost.small { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; }

/* ── Узкий экран (≤ 759 px, телефон 375): ни одной прокрутки вбок ── */
@media (max-width: 759px) {
  #sitesOverlay .sed-accbtn-t { display: none; }
  #sitesOverlay .sed-accbtn { max-width: none; }
  .sed-fbtn > span:not(.sed-fbadge) { display: none; }
  /* Строка в две линии: название и «⋯» — первой, пилюли, состояние и число страниц — второй,
     под названием (точка вынесена влево абсолютом, чтобы обе линии начинались ровно). */
  .sed-list .sed-row { flex-wrap: wrap; row-gap: 6px; column-gap: 8px; position: relative; padding-left: 31px; }
  .sed-list .sed-row > .sed-dot { position: absolute; left: 13px; top: 17px; }
  .sed-list .sed-row > .sed-row-main { flex: 1 1 calc(100% - 40px); order: 0; }
  .sed-list .sed-row > .sed-more { order: 0; }
  .sed-list .sed-row > .sed-rv-pill, .sed-list .sed-row > .sed-tag, .sed-list .sed-row > .sed-num { order: 1; }
  .sed-when { display: none; }
  .sed-tag { max-width: 150px; }
  #sitesOverlay .sed-sub > .cc-seg { max-width: 100%; }
  .sed-bind-l { flex: 0 0 100%; }
  .fac-site { padding: 4px 14px 0; }
  .fac-mount .fac.fac-embed .fac-main { max-height: none; }
  /* «×» плашки о праве правки переносился ОДИН на третью строку, слева под «Вернуть правку…». Он — в правом
     верхнем углу плашки, цель 32 px; содержимому плашки — поле справа под него. */
  .sed-plate.sed-coa { position: relative; padding-right: 44px; }
  .sed-plate.sed-coa > .icon-btn[data-coa="off"] {
    position: absolute; top: 4px; right: 6px; width: 32px; height: 32px; padding: 0;
    display: inline-flex; align-items: center; justify-content: center;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════════
   ✉️ КОНСТРУКТОР ПИСЬМА (`mailDesignOpen` в app.js) — рама окна, три колонки, холст.
   Письмо на холсте рисует СЕРВЕР (рамка с ответом `/v3/mail/design/preview`), а выбор,
   обводка, хваталка, «+» и панель блока — прозрачный слой пометок поверх неё. Плитки,
   поля и сегмент — те же `.sed-*`, что у конструктора сайтов (общее ядро). Колонки
   тянутся мышью (WIN_PANES), ширина окна — по раме `.modal-box`. Цвета — токены.
   ═══════════════════════════════════════════════════════════════════════════════ */
.mdz-box { width: min(1480px, 98vw); height: min(940px, 96vh); max-width: none; max-height: none;
  display: flex; flex-direction: column; padding: 0; overflow: hidden; }
.mdz-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 12px 10px 16px; border-bottom: 1px solid var(--line); }
.mdz-head .ghost.small:not(.icon-btn), .mdz-head .primary.small { display: inline-flex; align-items: center; gap: 6px; }
.mdz-title { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; white-space: nowrap; }
.mdz-title b { font-weight: 650; letter-spacing: -.01em; }
.mdz-title svg.ic, .mdz-aibtn svg.ic { width: 16px; height: 16px; color: var(--primary); }
.mdz-subj { font-size: 13px; color: var(--muted); max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mdz-st { font-size: 12px; color: var(--muted); max-width: 300px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mdz-st.warn { color: var(--warning); font-weight: 560; }
.mdz-sp { flex: 1 1 auto; }
.mdz-body { flex: 1 1 auto; min-height: 0; display: flex; align-items: stretch; }

/* Левая колонка: плитки блоков · готовые письма · мои шаблоны · «сохранить как шаблон» */
.mdz-left { width: 272px; flex: 0 0 auto; min-width: 0; overflow: auto; padding-bottom: 18px;
  border-right: 1px solid var(--line); background: var(--panel); }
.mdz-left .sed-tiles { padding: 0 12px 6px; }
.mdz-left .sed-hint { padding: 2px 14px 8px; }
.mdz-ready { grid-template-columns: 1fr; }
.mdz-ready .sed-tile { display: grid; grid-template-columns: 52px 1fr; column-gap: 10px; row-gap: 2px; align-items: center; }
.mdz-ready .sed-prev { grid-row: span 2; height: 38px; padding: 5px; }
.mdz-savebox { display: flex; flex-direction: column; align-items: stretch; gap: 8px; padding: 10px 12px 0; }
.mdz-savebox .ghost { align-self: flex-start; display: inline-flex; align-items: center; gap: 6px; }

/* Холст: письмо по центру, «Десктоп | Телефон» меняет ширину рамки — письмо перестраивается само */
.mdz-stage { position: relative; flex: 1 1 auto; min-width: 0; overflow: auto;
  padding: 28px 36px 72px; background: var(--bg-soft); }
.mdz-paper { position: relative; width: 624px; max-width: 100%; margin: 0 auto; transition: width .18s ease; }
.mdz-stage[data-dev="phone"] .mdz-paper { width: 375px; }
.mdz-frame { display: block; width: 100%; height: 420px; border: 0; border-radius: 16px;
  box-shadow: var(--shadow-2); background: transparent; }
.mdz-frame.nx { position: absolute; left: 0; top: 0; visibility: hidden; }
.mdz-marks { position: absolute; inset: 0; }
.mdz-mk { position: absolute; border-radius: 6px; cursor: pointer; outline: none; transition: box-shadow .12s; }
.mdz-mk:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 50%, transparent); }
.mdz-mk.sel { box-shadow: inset 0 0 0 2px var(--primary); }
.mdz-mk:focus-visible { box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--primary) 70%, transparent); }
.mdz-mk.flash { animation: mdzFlash .9s ease; }
@keyframes mdzFlash { from { background: color-mix(in srgb, var(--primary) 16%, transparent); } to { background: transparent; } }
.mdz-mk-k { position: absolute; left: 8px; top: -10px; display: none; padding: 1px 8px; border-radius: 999px;
  font-size: 10.5px; font-weight: 650; line-height: 17px; color: #fff; background: var(--acc-fill);
  pointer-events: none; white-space: nowrap; }
.mdz-mk:hover .mdz-mk-k, .mdz-mk.sel .mdz-mk-k, .mdz-mk.mdz-lift .mdz-mk-k { display: block; }
/* Хваталка — ЯВНАЯ мишень у левого края блока (канон ручного порядка), по наведению */
.mdz-grip { position: absolute; left: -30px; top: 50%; transform: translateY(-50%); display: none;
  place-items: center; width: 22px; height: 28px; padding: 0; border: 0; border-radius: 7px;
  background: var(--panel); color: var(--muted); box-shadow: var(--shadow-1); cursor: grab; touch-action: none; }
.mdz-grip:hover { color: var(--text); }
.mdz-grip:active { cursor: grabbing; }
.mdz-mk:hover .mdz-grip, .mdz-mk.sel .mdz-grip { display: grid; }
.mdz-grip svg.ic { width: 14px; height: 14px; }
.mdz-tb { position: absolute; right: 8px; top: -15px; z-index: 3; display: none; gap: 2px; padding: 2px;
  border-radius: 9px; background: var(--primary); box-shadow: var(--shadow-1); }
.mdz-mk.sel .mdz-tb { display: flex; }
.mdz-tb button { display: grid; place-items: center; width: 26px; height: 24px; padding: 0; border: 0;
  border-radius: 7px; background: none; color: #fff; cursor: pointer; transition: background .12s; }
.mdz-tb button:hover { background: rgba(255, 255, 255, .2); }
.mdz-tb svg.ic { width: 14px; height: 14px; }
/* «+» между блоками — всплывает, когда курсор над письмом */
.mdz-gap { position: absolute; left: 50%; z-index: 4; display: grid; place-items: center; width: 24px; height: 24px;
  margin: -12px 0 0 -12px; padding: 0; border: 0; border-radius: 50%; background: var(--acc-fill); color: #fff;
  box-shadow: var(--shadow-1); cursor: pointer; opacity: 0; transform: scale(.8); transition: opacity .14s, transform .14s; }
.mdz-paper:hover .mdz-gap { opacity: .85; transform: scale(1); }
.mdz-gap:hover, .mdz-gap:focus-visible { opacity: 1; transform: scale(1.08); }
.mdz-gap svg.ic { width: 14px; height: 14px; }
.mdz-reordering .mdz-mk { transition: transform .16s ease; background: color-mix(in srgb, var(--primary) 5%, transparent); }
.mdz-reordering .mdz-gap { display: none; }
.mdz-mk.mdz-lift { z-index: 5; background: color-mix(in srgb, var(--panel) 72%, transparent);
  box-shadow: 0 0 0 2px var(--primary), var(--shadow-2); }
.mdz-drop { position: absolute; left: 12px; right: 12px; z-index: 6; height: 3px; margin-top: -1.5px;
  border-radius: 3px; background: var(--primary); pointer-events: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 22%, transparent); }
.mdz-empty { position: absolute; left: 50%; top: 110px; transform: translateX(-50%); width: min(420px, 80%);
  display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 22px 24px; border-radius: 16px;
  background: var(--panel); box-shadow: var(--shadow-2); color: var(--muted); font-size: 13px; line-height: 1.5; text-align: center; }
.mdz-empty b { color: var(--text); font-size: 15px; font-weight: 640; }
.mdz-empty .ghost { display: inline-flex; align-items: center; gap: 6px; }
.mdz-empty[hidden], .mdz-drop[hidden], .mdz-rbody[hidden] { display: none; }

/* Правая колонка: «Настройки | Ая» → содержимое блока · стиль блока · тема письма */
.mdz-right { width: 324px; flex: 0 0 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column;
  border-left: 1px solid var(--line); background: var(--panel); }
.mdz-rtab { padding: 10px 12px; border-bottom: 1px solid var(--line); }
.mdz-rtab .cc-seg { display: flex; }
.mdz-rtab .cc-seg-b { flex: 1 1 0; }
.mdz-rbody { flex: 1 1 auto; min-height: 0; overflow: auto; }
.mdz-aihost { display: flex; flex-direction: column; padding: 10px 12px; }
.mdz-sec { border-bottom: 1px solid var(--line); }
.mdz-sec:last-child { border-bottom: 0; }
.mdz-sech { padding: 12px 12px 0; font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--muted); }
.mdz-sec .sed-card-body > .ghost.small, .mdz-coladd .ghost { display: inline-flex; align-items: center; gap: 6px; align-self: flex-start; }
.mdz-hintsec { display: flex; align-items: flex-start; gap: 10px; padding: 14px; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.mdz-hintsec svg.ic { flex: 0 0 auto; width: 18px; height: 18px; margin-top: 1px; color: var(--primary); }
.mdz-coladd { display: flex; flex-wrap: wrap; gap: 6px; }
/* «+» между блоками открывает короткий список блоков (поповер продукта `ccPop`) */
.mdz-pop-row { display: flex; align-items: center; gap: 10px; width: 100%; padding: 6px 8px; border: 0;
  border-radius: 10px; background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer; transition: background .12s; }
.mdz-pop-row:hover { background: var(--hover); }
.mdz-pop-row .sed-prev { flex: 0 0 auto; width: 44px; height: 30px; padding: 4px; }
.mdz-pop-t { display: flex; flex-direction: column; min-width: 0; }
.mdz-pop-t b { font-size: 13px; font-weight: 600; }
.mdz-pop-t i { font-style: normal; font-size: 11.5px; color: var(--muted); }

@media (max-width: 900px) {
  .mdz-body { flex-direction: column; overflow: auto; }
  .mdz-left { width: auto; max-height: 34%; border-right: 0; border-bottom: 1px solid var(--line); }
  .mdz-right { width: auto; max-height: 46%; border-left: 0; border-top: 1px solid var(--line); }
  .mdz-stage { padding: 16px 34px 40px; }
  .mdz-aibtn span, .mdz-subj { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   🖐 ОЧЕРЕДЬ ИИ — вид «Очередь» и блок карточки задачи (CLIE-1014)

   Размеры контролов — ТОЛЬКО общие токены ряда (--ctl-h/--ctl-r/--ctl-fs, канон control-size):
   своих чисел высоты/радиуса тут нет. Акцент — НОМЕР и СЛОВО, а не полоса слева (канон accent).
   Хваталка не отбирает экран: она проявляется под курсором (канон gesture-affordance).
   ═══════════════════════════════════════════════════════════════════════════════════════ */
.wsq-wrap { display: flex; flex-direction: column; height: 100%; min-height: 0; }

.wsq-head {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; border-bottom: 1px solid var(--line);
  font-size: 13px; color: var(--muted); flex: 0 0 auto;
}
.wsq-head b { color: var(--text); font-weight: 650; }
.wsq-now { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wsq-sub, .wsq-hint { font-size: 12px; color: var(--muted); }
.wsq-grow { flex: 1 1 auto; }
.wsq-spin {
  width: 12px; height: 12px; border-radius: 50%; flex: 0 0 12px;
  border: 2px solid color-mix(in srgb, var(--ok) 28%, transparent); border-top-color: var(--ok);
  animation: wsqspin 900ms linear infinite;
}
@keyframes wsqspin { to { transform: rotate(360deg); } }

.wsq-list { padding: 6px; overflow: auto; flex: 1 1 auto; min-height: 0; }

.wsq-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: 11px; cursor: pointer;
  transition: background 130ms ease;
}
.wsq-row + .wsq-row { margin-top: 1px; }
.wsq-row:hover { background: var(--panel-2); }

.wsq-grip {
  flex: 0 0 16px; width: 16px; height: 22px; display: grid; place-items: center;
  color: var(--line-strong); opacity: 0; cursor: grab; touch-action: none;
  transition: opacity 130ms ease, color 130ms ease;
}
.wsq-row:hover .wsq-grip, .wsq-row.wsq-lift .wsq-grip { opacity: 1; }
.wsq-grip:hover { color: var(--text); }
.wsq-grip .ic { width: 14px; height: 14px; }

.wsq-num {
  flex: 0 0 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 12px; font-weight: 700; color: var(--muted);
  background: var(--panel-2); border: 1px solid var(--line);
}
.wsq-row.first .wsq-num {
  color: #fff; background: var(--acc-fill); border-color: transparent;
  box-shadow: 0 1px 3px color-mix(in srgb, var(--accent) 45%, transparent);
}

.wsq-main { min-width: 0; flex: 1 1 auto; }
.wsq-t { font-size: 13.5px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wsq-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 4px; }
.wsq-hand { color: var(--warning);
  background: color-mix(in srgb, var(--warning) 12%, transparent);
  border-color: color-mix(in srgb, var(--warning) 26%, transparent); }

.wsq-act { display: flex; gap: 6px; opacity: 0; transition: opacity 130ms ease; flex: 0 0 auto; }
.wsq-row:hover .wsq-act { opacity: 1; }

/* ── 🔴 CLIE-1041 · «СЕЙЧАС В РАБОТЕ»: строки идущих прогонов над очередью ────────────────
   Та же строка, что у ждущих (чтобы взгляд не переучивался), но без хваталки и номера: работу
   не переставляют, у неё вместо места — ход. Отдельный класс `.wsq-wrow` ещё и физически
   уводит её от ядра протяжки, которое ищет `.wsq-row`. */
.wsq-wrow {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 10px; border-radius: 11px; cursor: pointer;
  transition: background 130ms ease;
}
.wsq-wrow + .wsq-wrow { margin-top: 1px; }
.wsq-wrow:hover { background: var(--panel-2); }
.wsq-sec {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 12px 5px; font-size: 11px; font-weight: 700;
  letter-spacing: .4px; text-transform: uppercase; color: var(--muted);
}
.wsq-runmark { background: color-mix(in srgb, var(--ok) 13%, transparent);
  border-color: color-mix(in srgb, var(--ok) 30%, transparent); }
.wsq-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ok); flex: 0 0 8px;
  animation: wipPulse 1.8s ease-in-out infinite; }
.wsq-live { color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent);
  border-color: color-mix(in srgb, var(--ok) 26%, transparent); font-weight: 600;
  max-width: 380px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wsq-live.quiet { color: var(--warning); background: color-mix(in srgb, var(--warning) 12%, transparent);
  border-color: color-mix(in srgb, var(--warning) 26%, transparent); }
.wsq-live.dead { color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent);
  border-color: color-mix(in srgb, var(--danger) 26%, transparent); }
/* 🔴 CLIE-1847 · «ЖДУТ СВОИ ЧАСТИ»: задача «В работе», которая сама ничего не выполняет. Тон —
   спокойный нейтральный (не зелёный «идёт» и не жёлтый «молчит»), метка — песочные часы, строка
   состояния ПЕРЕНОСИТСЯ целиком: в ней причина («ни одна не идёт: 7 ждут окна до 14:40»), а
   срезанная многоточием причина — та же немота, из-за которой и чинили. */
.wsq-parkmark { color: var(--muted); }
.wsq-parkmark .ic, .wsq-parkmark svg { width: 14px; height: 14px; }
.wsq-live.parked { color: var(--text); background: var(--panel-2);
  border-color: var(--line); font-weight: 500; max-width: 100%; white-space: normal;
  overflow: visible; text-overflow: clip; line-height: 1.35; }
.wsq-time { flex: 0 0 auto; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.wsq-prog { margin-top: 6px; height: 3px; border-radius: 2px; background: var(--panel-2); overflow: hidden; }
.wsq-prog > i { display: block; height: 100%; border-radius: 2px; background: var(--ok);
  transition: width 240ms ease; }
/* CLIE-1946 · светлая: --panel-2 = холст — дорожка прогресса и нейтральный «ждут свои части» сливались (1.00). */
html[data-theme="light"] .wsq-prog { background: var(--line); }
html[data-theme="light"] .wsq-live.parked { background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); }

/* Протяжка: поднятая строка и «расступившиеся» соседи — ядро ccStartRowDrag (rowdrag.js). */
.wsq-reordering .wsq-row { transition: transform 140ms cubic-bezier(.2,.7,.3,1); }
.wsq-row.wsq-lift {
  background: var(--panel); box-shadow: 0 10px 28px rgba(0,0,0,.18), 0 2px 6px rgba(0,0,0,.10);
  transform: scale(1.012); z-index: 3; cursor: grabbing;
}

/* ── блок «Очередь ИИ» в карточке задачи ── */
.tip-queue-card { padding: 12px 14px; }
.tip-q-h { display: flex; align-items: center; gap: 7px; font-size: 13px; font-weight: 700; color: var(--text); }
.tip-q-h .ic { width: 14px; height: 14px; color: var(--accent); }
.tip-q-c { margin-left: auto; font-size: 12px; font-weight: 700; color: var(--accent); }
.tip-q-empty { margin-top: 8px; font-size: 12px; color: var(--muted); }
.tip-q-list { margin-top: 9px; border: 1px solid var(--line); border-radius: 11px;
  overflow: hidden; background: var(--panel-2); }
.tip-q-row { display: flex; align-items: center; gap: 8px; padding: 6px 9px; font-size: 12.5px; }
.tip-q-row + .tip-q-row { border-top: 1px solid var(--line); }
.tip-q-row.me { background: var(--panel); font-weight: 650; }
.tip-q-grip { flex: 0 0 14px; color: var(--line-strong); opacity: 0; cursor: grab; touch-action: none;
  display: grid; place-items: center; transition: opacity 130ms ease; }
.tip-q-row:hover .tip-q-grip, .tip-q-row.tip-q-lift .tip-q-grip { opacity: 1; }
.tip-q-grip .ic { width: 12px; height: 12px; }
.tip-q-n { flex: 0 0 22px; height: 22px; border-radius: 50%; display: grid; place-items: center;
  font-size: 11px; font-weight: 700; color: var(--muted); background: var(--panel); border: 1px solid var(--line); }
.tip-q-row.me .tip-q-n { color: #fff; background: var(--acc-fill); border-color: transparent; }
.tip-q-t { min-width: 0; flex: 1 1 auto; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tip-q-row.me .tip-q-t { color: var(--text); }
.tip-q-this { flex: 0 0 auto; color: var(--accent);
  background: color-mix(in srgb, var(--accent) 11%, transparent);
  border-color: color-mix(in srgb, var(--accent) 24%, transparent); }
.tip-q-more { padding: 6px 9px 0; font-size: 11.5px; color: var(--muted); }
.tip-q-btns { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.tip-q-note { margin-top: 8px; font-size: 11.5px; color: var(--muted); }
.tip-q-reordering .tip-q-row { transition: transform 140ms cubic-bezier(.2,.7,.3,1); }
.tip-q-row.tip-q-lift { background: var(--panel);
  box-shadow: 0 8px 22px rgba(0,0,0,.16); z-index: 3; cursor: grabbing; }

/* ══════════════════════════════════════════════════════════════════════════════════════════
   🧩 ЭТАПЫ · ОПЛАТЫ · ЧАСЫ В КАРТОЧКЕ СДЕЛКИ (эпик «Продумать этапность сделки»)
   Акцент — ТОЧКА и СЛОВО, а не левая рейка (правило акцента). Ряды контролов берут --ctl-*.
   Цвета — только токены темы, поэтому светлая и тёмная одинаково вылизаны.
   ══════════════════════════════════════════════════════════════════════════════════════ */
.dph-top { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.dph-prog { display: inline-flex; align-items: center; gap: 8px; min-width: 168px; flex: 1 1 168px; }
.dph-prog-bar { flex: 1 1 auto; height: 6px; border-radius: 999px; background: var(--hover); overflow: hidden; }
.dph-prog-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--primary); transition: width .18s cubic-bezier(.2,.7,.3,1); }
.dph-prog-v { font-size: 13px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.dph-sum { font-size: 12px; color: var(--text-dim); }

.dph-list { display: flex; flex-direction: column; gap: 7px; }
.dph-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); transition: border-color .14s ease, background .14s ease; }
.dph-row:hover { border-color: color-mix(in srgb, var(--primary) 38%, var(--line)); }
.dph-row.is-done .dph-t { color: var(--text-dim); }
.dph-dot { flex: none; width: 7px; height: 7px; margin-top: 7px; border-radius: 999px; background: var(--pc, var(--muted)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--pc, var(--muted)) 16%, transparent); }
.dph-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.dph-h { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dph-t { flex: 1 1 auto; min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--text); border-radius: 7px; padding: 1px 4px; margin-left: -4px; outline: none; }
.dph-t:hover { background: var(--hover); }
.dph-t:focus { background: var(--panel); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 45%, transparent); }
.dph-w { flex: none; font-size: 11px; font-weight: 650; color: var(--text-dim); background: var(--hover); border-radius: 999px; padding: 3px 7px; font-variant-numeric: tabular-nums; }
.dph-st { flex: none; height: var(--ctl-h); border-radius: var(--ctl-r); font-size: 12px; font-weight: 600; color: var(--text); background-color: color-mix(in srgb, var(--pc, var(--muted)) 12%, var(--panel)); border: 1px solid color-mix(in srgb, var(--pc, var(--muted)) 32%, var(--line)); padding: 0 34px 0 8px; cursor: pointer; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.dph-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.dph-m { display: inline-flex; align-items: center; gap: 4px; font-size: 11.5px; color: var(--text-dim); white-space: nowrap; }
.dph-m.over { color: #c9251b; font-weight: 600; }
.dph-m svg.ic { width: 12px; height: 12px; opacity: .75; }
.dph-chip { display: inline-flex; align-items: center; gap: 4px; font-size: 11px; font-weight: 600; line-height: 1; padding: 4px 8px; border-radius: 999px; background: var(--hover); color: var(--text-dim); white-space: nowrap; }
.dph-chip svg.ic { width: 11px; height: 11px; }
.dph-chip.dph-par { background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.dph-chip.dph-block { background: color-mix(in srgb, #ff9f0a 18%, transparent); color: #b25e00; }
.dph-chip.dph-wait { padding-right: 3px; }
.dph-chip-x { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; margin-left: 2px; border: none; background: none; color: inherit; opacity: .55; border-radius: 999px; cursor: pointer; }
.dph-chip-x:hover { opacity: 1; background: var(--hover); }
.dph-chip-x svg.ic { width: 10px; height: 10px; }
.dph-line { height: 3px; border-radius: 999px; background: var(--hover); overflow: hidden; }
.dph-line > i { display: block; height: 100%; border-radius: 999px; transition: width .18s cubic-bezier(.2,.7,.3,1); }
.dph-acts { flex: none; display: flex; align-items: center; gap: 4px; opacity: 0; transition: opacity .12s ease; }
.dph-row:hover .dph-acts, .dph-row:focus-within .dph-acts, .dpay-row:hover .dph-acts, .dpay-row:focus-within .dph-acts, .dhr-row:hover .dph-acts, .dhr-row:focus-within .dph-acts { opacity: 1; }
.dph-a { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border-radius: 8px; border: 1px solid var(--line); background: var(--panel); color: var(--text-dim); cursor: pointer; transition: color .12s, border-color .12s; }
.dph-a:hover { color: var(--primary); border-color: var(--primary); }
.dph-a.bad:hover { color: #c9251b; border-color: #c9251b; }
.dph-a svg.ic { width: 13px; height: 13px; }
.dph-presets { display: flex; flex-wrap: wrap; gap: 8px; }
.dph-a.on { color: var(--primary); border-color: var(--primary); background: color-mix(in srgb, var(--primary) 10%, var(--panel)); }

/* 📈 ЗАДАЧИ ЭТАПА (владелец 20.10.2026: «этап должен быть привязан к задачам… прозрачность полная»).
   Строка задачи — общая `.crmb-task` блока «Задачи»; здесь только её место в этапе, шаги
   (пункты чек-листа + подзадачи) и статус. Акцент — точка и слово, без левых реек. */
.dph-tasks { display: flex; flex-direction: column; gap: 2px; }
.dph-tk-list { display: flex; flex-direction: column; gap: 1px; margin: 0 -2px; }
.dph-tk-list .crmb-task { padding: 3px 4px; }
.dph-tk-list .crmb-task-t { font-size: 13px; }
.dph-tk-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; padding-top: 2px; }
.dph-tk-a { display: inline-flex; align-items: center; gap: 4px; padding: 3px 0; border: 0; background: none; font: inherit; font-size: 12px; font-weight: 600; color: var(--text-dim); cursor: pointer; }
.dph-tk-a:hover, .dph-tk-a:focus-visible { color: var(--primary); }
.dph-tk-a svg.ic { width: 12px; height: 12px; }
.dph-tk-more { color: var(--primary); }
.dph-tk-to { flex: none; display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 9px; border-radius: var(--r-full); border: 1px solid var(--line); background: var(--panel); color: var(--text); font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap; }
.dph-tk-to:hover { border-color: var(--primary); color: var(--primary); }
.dph-tk-to svg.ic { width: 12px; height: 12px; }
.crmb-tmeta { flex: none; display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; }
.crmb-st { flex: none; display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; color: var(--text-dim); white-space: nowrap; }
.crmb-st > i { width: 6px; height: 6px; border-radius: 999px; background: var(--muted); }
.crmb-steps { flex: none; display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 650; color: var(--text-dim); font-variant-numeric: tabular-nums; white-space: nowrap; }
.crmb-steps > b { width: 11px; height: 11px; border-radius: 999px; background: conic-gradient(var(--primary) calc(var(--p, 0) * 1%), var(--line-strong, var(--line)) 0); }
.crmb-steps.full { color: var(--ok-ink, var(--ok)); }
.crmb-steps.full > b { background: var(--ok); }
.dph-m.dph-pcm { font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.dph-m.dph-unm { font-style: italic; white-space: normal; }
.dph-free { margin-top: 10px; padding: 9px 11px; border: 1px dashed var(--line-strong, var(--line)); border-radius: 12px; display: flex; flex-direction: column; gap: 4px; }
.dph-free-h { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 650; color: var(--text); }
.dph-free-h svg.ic { width: 13px; height: 13px; color: var(--text-dim); }
.dph-free-s { font-size: 12px; color: var(--text-dim); }
/* узкий блок «Этапы» в «Штиле» (телефон, блок-«половинка» на десктопе — 360 px) спрашивает ширину
   САМОГО блока (`dphblk`), а не окна и не колонки: название этапа — во всю ширину тела, вес и
   статус — строкой ниже, действия — столбиком справа (в одну строку с ними название рассыпалось по
   буквам); строка задачи — название целиком, статус, шаги и срок — второй строкой. «Глубина»
   раскладывает себя сама (`dzblk`). */
.crmw-blk[data-cb="phases"]:not(.dz-pane *) { container: dphblk / inline-size; }
@container dphblk (max-width: 560px) {
  .dph-row:not(.dz-pane *) .dph-h { flex-wrap: wrap; row-gap: 6px; }
  .dph-row:not(.dz-pane *) .dph-t { flex: 1 1 100%; }
  .dph-row:not(.dz-pane *) .dph-acts { flex-direction: column; }
  .dph-tk-list:not(.dz-pane *) .crmb-task { flex-wrap: wrap; row-gap: 3px; }
  .dph-tk-list:not(.dz-pane *) .crmb-task-t { flex-basis: calc(100% - 60px); }
  .dph-tk-list:not(.dz-pane *) .crmb-tmeta { flex: 1 1 0; margin-left: 28px; }
  .dph-tk-list:not(.dz-pane *) .crmb-task-t { white-space: normal; overflow-wrap: anywhere; text-overflow: clip; }
  /* шапка блока: заголовок и «Список · Потоки» — первой строкой, «Набор · Из сметы · + Этап» —
     следующей, а не сжатый в столбик сегмент и надписи в две строки */
  .di-phases:not(.dz-pane *) > .di-sec-h { flex-wrap: wrap; justify-content: flex-start; gap: 6px 12px; }
  .di-phases:not(.dz-pane *) > .di-sec-h > .cc-seg { flex: none; }
  .di-phases:not(.dz-pane *) > .di-sec-h > .di-link { white-space: nowrap; }
}

/* 📋 НАБОРЫ ЭТАПОВ · «СМЕТА → ЭТАПЫ» · ПРЕДЛОЖЕНИЕ ПЕРЕНОСА (CRMC-695) ─────────────────────
   Плотный список с галочками в раме `.pm-card`. Состояние строки называется СЛОВОМ в чипе —
   левых полосок-реек нет (правило акцента CLIE-483); выбранная карточка набора помечена
   подложкой и кольцом, а не заливкой во всю строку. Обе темы — на общих токенах. */
.pm-card.pm-wide { width: min(560px, 96vw); }
.pm-card.pm-wide .pm-body { max-height: min(64vh, 620px); }
.dph-tplbox { display: flex; flex-direction: column; gap: 12px; }
.dph-lbl { font-size: 11px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.dph-tpl-list { display: flex; flex-direction: column; gap: 6px; }
.dph-tpl { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; text-align: left;
  padding: 10px 12px; border-radius: 10px; border: 1px solid var(--line); background: var(--panel); cursor: pointer;
  transition: border-color .13s ease, background .13s ease, box-shadow .13s ease; }
.dph-tpl:hover { border-color: var(--muted); }
.dph-tpl.on { border-color: transparent; background: color-mix(in srgb, var(--primary) 11%, var(--panel));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 26%, transparent); }
.dph-tpl-t { font-size: 13.5px; font-weight: 600; color: var(--text); }
.dph-tpl-s { font-size: 12px; color: var(--text-dim); line-height: 1.35; }
.dph-tpl-m { font-size: 11.5px; color: var(--muted); }
.dph-tpl-when { display: flex; flex-direction: column; gap: 6px; }
.dph-date { height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs); padding: 0 10px;
  border: 1px solid var(--line); background: var(--panel); color: var(--text); }
.dph-date:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.dph-prev { display: flex; flex-direction: column; }
.dph-prev-h { font-size: 12.5px; color: var(--text-dim); line-height: 1.4; padding-bottom: 6px; }
.dph-prev-f { font-size: 12.5px; color: var(--text-dim); padding-top: 6px; border-top: 1px solid var(--line); }
.dph-prev-row { display: flex; align-items: center; gap: 10px; padding: 7px 2px; border-bottom: 1px solid var(--line); cursor: pointer; }
.dph-prev-row:last-child { border-bottom: none; }
.dph-prev-row:hover { background: var(--hover); border-radius: 8px; }
.dph-prev-row input[type="checkbox"] { appearance: none; -webkit-appearance: none; flex: none; margin: 0; padding: 0;
  width: 18px; height: 18px; min-width: 18px; box-sizing: border-box;
  border: 1.6px solid var(--line-strong); border-radius: 5px; background: var(--panel); cursor: pointer; position: relative;
  transition: background .13s ease, border-color .13s ease; }
.dph-prev-row:hover input[type="checkbox"] { border-color: var(--muted); }
.dph-prev-row input[type="checkbox"]:checked { background: var(--accent); border-color: var(--accent); }
.dph-prev-row input[type="checkbox"]:checked::after { content: ""; position: absolute; left: 6px; top: 2.5px; width: 3.5px; height: 8px;
  border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg); }
.dph-prev-row input[type="checkbox"]:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--glow); }
.dph-prev-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.dph-prev-t { font-size: 13px; font-weight: 500; color: var(--text); display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.dph-prev-s { font-size: 11.5px; color: var(--muted); }
.dph-prev-m { flex: none; font-size: 12.5px; font-variant-numeric: tabular-nums; color: var(--text-dim); }
.dph-prev-b { font-size: 10.5px; font-weight: 600; line-height: 1; padding: 3px 6px; border-radius: 999px; background: var(--hover); color: var(--text-dim); }
/* 🔴 БАЗА — ТЁМНАЯ тема (у неё атрибута нет вовсе, светлая = html[data-theme="light"]),
   поэтому янтарные чернила задаются здесь под тёмный фон, а светлая тема их углубляет. */
.dph-prev-b.warn { background: color-mix(in srgb, #ff9f0a 16%, transparent); color: #ffc766; }
.dtn-say { font-size: 13.5px; color: var(--text); line-height: 1.45; }
.dtn-note { font-size: 12.5px; color: var(--text-dim); line-height: 1.4; padding: 8px 10px; border-radius: 10px;
  background: color-mix(in srgb, var(--primary) 8%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 18%, transparent); }
.dtn-row { display: flex; flex-direction: column; gap: 6px; }
.dtn-pipe { width: 100%; justify-content: space-between; }
html[data-theme="light"] .dph-prev-b.warn { color: #a85f00; }

/* 🖐 Перетаскивание этапов (CRMC-685·3, п.2). Хваталка проявляется по наведению на строку —
   исходное состояние остаётся минимальным, а жест не спрятан: курсор и подсказка называют его. */
.dph-grip { flex: none; width: 18px; height: 24px; margin: 1px -3px 0 -3px; display: inline-flex; align-items: center; justify-content: center;
  border: none; background: none; padding: 0; color: var(--muted); opacity: 0; cursor: grab; transition: opacity .12s ease, color .12s ease; touch-action: none; }
.dph-row:hover .dph-grip, .dph-row:focus-within .dph-grip,
.dpay-row:hover .dph-grip, .dpay-row:focus-within .dph-grip { opacity: .5; }
.dph-grip:hover { opacity: 1; color: var(--text); }
.dph-grip:active { cursor: grabbing; }
.dph-grip svg.ic { width: 13px; height: 13px; }
.dph-reordering .dph-row, .dpay-reordering .dpay-row { transition: transform 140ms cubic-bezier(.2,.7,.3,1); }
.dph-row.dph-dragging, .dpay-row.dpay-dragging { background: var(--panel); border-color: color-mix(in srgb, var(--primary) 45%, var(--line));
  box-shadow: 0 8px 22px rgba(0,0,0,.16); z-index: 3; cursor: grabbing; }
/* 🖐 Строки графика платежей берут ТУ ЖЕ хваталку и те же состояния, что этапы (CRMC-685·4):
   у порядка в продукте одна рука, второго вида грипа и второй анимации переезда не заводим. */

/* 📝 План этапа: сроки · модель · сумма · часы · вес · ответственный. Поля берут те же токены
   ряда (`--ctl-*`), что и «Модель оплаты» — один размерный класс на весь продукт (CLIE-505). */
/* 🔴 СЕТКА, А НЕ `flex-wrap`. Кадр прода 12.09.2026 (обе темы) поймал рваную раскладку: поля
   переносились по СВОЕЙ ширине — «Начало|Срок» и «Оплата|Сумма» встали парами, а «План, ч» и
   «Вес в прогрессе» уехали каждый на свою строку. Родная ширина `input[type=date]` зависит от
   локали браузера, поэтому «подобрать min-width полю» — не лечение (канон `ua-defaults`).
   Колонки задаёт сетка: пары выровнены при ЛЮБОЙ ширине поля. Пол колонки (148px) держит
   подпись целиком — тот же смысл, что `min-width: auto` у флекса (канон `label-fit`), но
   выраженный сеткой. «Во всю строку» — осознанный `grid-column`, а не случайный перенос. */
.dph-plan { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  align-items: end; gap: 10px; margin-top: 2px; padding: 10px 11px;
  border-radius: 11px; background: var(--hover); }
.dph-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.dph-f-i { min-width: 0; width: 100%; box-sizing: border-box; }
.dph-f-i[type="date"] { font-variant-numeric: tabular-nums; }
.dph-plan-a { grid-column: 1 / -1; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dph-plan-a .di-btn { display: inline-flex; align-items: center; gap: 6px; }
.dph-plan-a .di-btn svg.ic { width: 13px; height: 13px; }
/* «Запланирован, а плана нет» — предложение действия, не пустота. */
.dph-plan-call { display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600; line-height: 1;
  padding: 4px 9px; border-radius: 999px; border: 1px dashed color-mix(in srgb, var(--primary) 42%, var(--line));
  background: none; color: var(--primary); cursor: pointer; transition: background .12s ease, border-color .12s ease; }
.dph-plan-call:hover { background: color-mix(in srgb, var(--primary) 10%, transparent); border-style: solid; }
.dph-plan-call svg.ic { width: 12px; height: 12px; }

/* 💰 Оплата этапа — тот же словарь состояний, что у строки графика (`.dc-*`). */
.dph-chip.dph-pay { border: none; cursor: pointer; }
.dph-chip.dph-pay:hover { filter: brightness(1.06); }
.dph-chip.dc-ok { background: color-mix(in srgb, #34c759 18%, transparent); color: #248a3d; }
.dph-chip.dc-info { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary); }
.dph-chip.dc-warn { background: color-mix(in srgb, #ff9f0a 20%, transparent); color: #b25e00; }
.dph-chip.dc-bad { background: color-mix(in srgb, #ff3b30 16%, transparent); color: #c9251b; }
.dph-chip.dc-muted { background: var(--hover); color: var(--text-dim); }
html[data-theme="dark"] .dph-chip.dc-ok, :root:not([data-theme]) .dph-chip.dc-ok { color: #4cd964; }
html[data-theme="dark"] .dph-chip.dc-warn, :root:not([data-theme]) .dph-chip.dc-warn { color: #ffb340; }
.dpay-phase-add { border: 1px dashed var(--line); background: none; color: var(--text-dim); cursor: pointer; }
.dpay-phase-add:hover { border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); color: var(--primary); }
.dpay-row .dph-chip.dph-pay { border: none; }

/* Вид «Потоки»: колонка = шаг графа; два этапа в одной колонке = параллельные. */
.dph-lanes { display: flex; align-items: stretch; gap: 8px; overflow-x: auto; padding-bottom: 4px; }
.dph-lane { flex: 0 0 min(300px, 78vw); display: flex; flex-direction: column; gap: 7px; }
.dph-lane-h { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase; color: var(--text-dim); }
.dph-lane-arr { flex: none; display: flex; align-items: center; color: var(--muted); opacity: .55; }
.dph-lane-arr svg.ic { width: 15px; height: 15px; }

/* ── Оплаты ── */
.dpay-nums { display: flex; flex-wrap: wrap; gap: 8px; }
.dpay-num { flex: 1 1 106px; min-width: 96px; padding: 8px 10px; border-radius: 11px; background: var(--hover); }
.dpay-num-v { font-size: 14.5px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.dpay-num-l { margin-top: 2px; font-size: 11px; color: var(--text-dim); }
.dpay-num.ok .dpay-num-v { color: #248a3d; }
.dpay-num.warn .dpay-num-v { color: #b25e00; }
.dpay-warn { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text); padding: 8px 10px; border-radius: 11px; background: color-mix(in srgb, #ff9f0a 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #ff9f0a 24%, transparent); }
.dpay-warn.hot { background: color-mix(in srgb, #ff3b30 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #ff3b30 26%, transparent); }
.dpay-warn svg.ic { width: 14px; height: 14px; flex: none; }
.dpay-list { display: flex; flex-direction: column; gap: 7px; }
.dpay-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); transition: border-color .14s ease; }
.dpay-row:hover { border-color: color-mix(in srgb, var(--primary) 38%, var(--line)); }
.dpay-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.dpay-pct { flex: none; font-size: 11px; font-weight: 650; color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); border-radius: 999px; padding: 3px 7px; font-variant-numeric: tabular-nums; }
.dpay-sum { flex: none; font-size: 13.5px; font-weight: 700; color: var(--text); white-space: nowrap; font-variant-numeric: tabular-nums; }
.dpay-presets { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
.dpay-presets-l { font-size: 11px; font-weight: 650; letter-spacing: .04em; text-transform: uppercase; color: var(--text-dim); }
.dpay-presets-b { display: flex; flex-wrap: wrap; gap: 8px; }
/* 💼 Модель оплаты и удержание (CRMC-685·2). Высоту контролов ряда задаёт размерный класс
   `--ctl-h` (канон control-size, CLIE-505) — своих чисел здесь нет, поэтому поле, пикер и
   кнопки-шаблоны стоят в одну линию. Подпись над полем: read-only-значение и его кнопку в
   один ряд не жмём (CLIE-425), а поясняющая фраза модели — отдельной строкой. */
.dpay-model { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; }
.dpay-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.dpay-f-l { font-size: 11px; font-weight: 650; letter-spacing: .02em; color: var(--text-dim); }
/* 🔴 Поле берёт поверхность ввода `--input-bg`, как канонический пикер `.ccpp-field`, а не
   `--panel-2`: замер на живом проде (tools/shots/crmc685r2-ret-contrast.js) показал, что в
   ТЁМНОЙ теме `--panel-2` совпадает с подложкой карточки (контраст заливки 1.00, рамка 1.06) —
   поле переставало читаться как поле. Кегль — тоже токен ряда (`--ctl-fs`), своих чисел нет. */
.dpay-f-i { height: var(--ctl-h); box-sizing: border-box; padding: 0 9px; font-size: var(--ctl-fs); color: var(--text); background: var(--input-bg); border: 1px solid var(--line); border-radius: var(--ctl-r); outline: none; transition: border-color .12s ease, box-shadow .12s ease; }
.dpay-f-i:hover { border-color: color-mix(in srgb, var(--primary) 38%, var(--line)); }
.dpay-f-i:focus { border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); }
.dpay-model-i { min-width: 196px; }
.dpay-ret-i { width: 92px; font-variant-numeric: tabular-nums; }
.dpay-model-say { flex: 1 1 180px; min-width: 0; font-size: 11.5px; color: var(--text-dim); padding-bottom: 4px; }
.dpay-warn .di-btn { margin-left: auto; flex: none; }

/* ── 💰 Деньги сделки (виджет-сводка, CRMC-694 · волна 3) ────────────────────────────────
   Плотная строка-сводка в голове карточки. Числа СЧИТАЕТ СЕРВЕР (`DealPayments.money_raw/2`),
   здесь только типографика: 4/8-grid, тонкие хэйрлайны, табличные цифры (колонки чисел не
   «пляшут» при пересчёте), никаких левых полос-реек — тревога это СЛОВО и точка. */
.dbg { display: flex; flex-direction: column; gap: 10px; }
.dbg-nums { display: flex; flex-wrap: wrap; gap: 8px; }
.dbg-n { flex: 1 1 116px; min-width: 104px; padding: 9px 11px; border-radius: 12px; background: var(--hover); }
.dbg-n-v { font-size: 16px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.01em; }
.dbg-n-l { margin-top: 3px; font-size: 11px; color: var(--text-dim); display: flex; align-items: center; gap: 5px; }
/* числа смысла — ЧЕРНИЛАМИ темы: прибитые #248a3d/#b25e00/#d1372b давали 3.03–4.14 */
.dbg-n.ok .dbg-n-v { color: var(--ok-ink, var(--ok)); }
.dbg-n.warn .dbg-n-v { color: var(--warning-ink, var(--warning)); }
/* Просрочка — подложка + кольцо акцента (канон accent), а не полоса слева. */
.dbg-n.bad { background: color-mix(in srgb, #ff3b30 11%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #ff3b30 22%, transparent); }
.dbg-n.bad .dbg-n-v { color: var(--danger-ink, var(--danger)); }
.dbg-n.bad .dbg-n-l b { font-weight: 650; color: #d1372b; }
/* Точка-акцент в подписи: 6px, как в строке списка. */
.dbg-dot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: currentColor; }

.dbg-rows { display: flex; flex-direction: column; gap: 8px; }
.dbg-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; color: var(--text); padding: 8px 11px; border-radius: 12px; background: var(--hover); }
.dbg-line svg.ic { width: 14px; height: 14px; flex: none; color: var(--text-dim); }
.dbg-line b { font-weight: 650; font-variant-numeric: tabular-nums; }
.dbg-line.alert { background: color-mix(in srgb, #ff9f0a 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #ff9f0a 24%, transparent); }
.dbg-line.alert svg.ic { color: #b25e00; }
.dbg-line.good { background: color-mix(in srgb, #34c759 11%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #34c759 22%, transparent); }
.dbg-line.good svg.ic { color: #248a3d; }

/* Сгорание бюджета: две шкалы одной длины — расход и готовность. Сравнивать два числа
   человеку трудно, сравнивать две линии — легко. */
.dbg-burn { display: flex; flex-direction: column; gap: 8px; padding: 10px 11px; border-radius: 12px; background: var(--hover); }
.dbg-burn.alert { background: color-mix(in srgb, #ff9f0a 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #ff9f0a 24%, transparent); }
.dbg-burn-g { display: flex; align-items: center; gap: 9px; }
.dbg-burn-l { flex: 0 0 88px; font-size: 11px; color: var(--text-dim); }
.dbg-burn-t { flex: 1 1 auto; height: 6px; border-radius: 999px; background: color-mix(in srgb, var(--text) 10%, transparent); overflow: hidden; }
.dbg-burn-f { display: block; height: 100%; border-radius: 999px; background: var(--primary); transition: width .16s ease; }
.dbg-burn-g.spent .dbg-burn-f { background: #ff9f0a; }
.dbg-burn-g.spent.hot .dbg-burn-f { background: #ff3b30; }
.dbg-burn-p { flex: 0 0 44px; text-align: right; font-size: 12px; font-weight: 650; color: var(--text); font-variant-numeric: tabular-nums; }
.dbg-burn-say { font-size: 11.5px; color: var(--text-dim); }
.dbg-burn.alert .dbg-burn-say { color: var(--text); }

/* Прогрессивное раскрытие: пока не нажали — только числа. Кнопка носит размерный класс ряда. */
.dbg-more { display: flex; align-items: center; gap: 6px; align-self: flex-start; height: var(--ctl-h); padding: 0 10px; font-size: var(--ctl-fs); color: var(--text-dim); background: transparent; border: 1px solid var(--line); border-radius: var(--ctl-r); cursor: pointer; transition: border-color .14s ease, color .14s ease; }
.dbg-more:hover { color: var(--text); border-color: color-mix(in srgb, var(--primary) 38%, var(--line)); }
.dbg-more svg.ic { width: 13px; height: 13px; transition: transform .16s ease; }
.dbg-more.on svg.ic { transform: rotate(180deg); }
.dbg-flat { font-size: 12.5px; color: var(--text-dim); }

/* ── 📋 Отчёт «Не выставлено» (CRMC-694) ─────────────────────────────────────────────── */
.deal-unbilled { padding: 22px; max-width: 920px; margin: 0 auto; }
.unb-tot { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.unb-tot-c { flex: 1 1 150px; min-width: 136px; padding: 11px 13px; border-radius: 13px; background: var(--panel-2); border: 1px solid var(--line); }
.unb-tot-v { font-size: 20px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; letter-spacing: -.015em; }
.unb-tot-l { margin-top: 3px; font-size: 11.5px; color: var(--text-dim); }
.unb-tot-c.bad .unb-tot-v { color: var(--danger-ink, var(--danger)); }
.unb-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 12px; }
.unb-q { flex: 1 1 220px; min-width: 180px; height: var(--ctl-h); box-sizing: border-box; padding: 0 11px; font-size: var(--ctl-fs); color: var(--text); background: var(--input-bg); border: 1px solid var(--line); border-radius: var(--ctl-r); outline: none; transition: border-color .12s ease, box-shadow .12s ease; }
.unb-q:hover { border-color: color-mix(in srgb, var(--primary) 38%, var(--line)); }
.unb-q:focus { border-color: var(--primary); box-shadow: 0 0 0 2px var(--glow); }
.unb-list { display: flex; flex-direction: column; gap: 8px; }
.unb-row { display: flex; align-items: center; gap: 12px; padding: 11px 13px; border: 1px solid var(--line); border-radius: 13px; background: var(--panel-2); cursor: pointer; transition: border-color .14s ease, background .14s ease; }
.unb-row:hover { border-color: color-mix(in srgb, var(--primary) 38%, var(--line)); background: var(--hover); }
.unb-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.unb-t { font-size: 13.5px; font-weight: 650; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.unb-t .unb-num { color: var(--text-dim); font-weight: 600; margin-right: 6px; font-variant-numeric: tabular-nums; }
.unb-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.unb-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: var(--muted); background: var(--hover); border-radius: 999px; padding: 3px 8px; font-variant-numeric: tabular-nums; }
.unb-chip.bad { color: var(--danger-ink, var(--danger)); background: color-mix(in srgb, #ff3b30 11%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, #ff3b30 22%, transparent); }
.unb-chip svg.ic { width: 12px; height: 12px; }
.unb-sum { flex: none; text-align: right; }
.unb-sum-v { font-size: 15px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; white-space: nowrap; }
.unb-sum-l { margin-top: 2px; font-size: 10.5px; color: var(--text-dim); }
.unb-acts { flex: none; display: flex; align-items: center; gap: 7px; }
.unb-note { margin-top: 12px; font-size: 11.5px; color: var(--text-dim); }

/* ── Часы ── */
.dhr-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.dhr-top-a { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dhr-list { display: flex; flex-direction: column; gap: 7px; }
.dhr-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 11px; border: 1px solid var(--line); border-radius: 12px; background: var(--panel-2); transition: border-color .14s ease; }
.dhr-row:hover { border-color: color-mix(in srgb, var(--primary) 38%, var(--line)); }
.dhr-b { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.dhr-t { flex: 1 1 auto; min-width: 0; font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dhr-min { flex: none; font-size: 12.5px; color: var(--text-dim); font-variant-numeric: tabular-nums; }
.dhr-amt { flex: none; font-size: 13.5px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.dhr-bill { flex: none; margin-top: 3px; display: inline-flex; align-items: center; cursor: pointer; }
.dhr-bill input { position: absolute; opacity: 0; width: 0; height: 0; }
.dhr-bill > span { display: inline-flex; align-items: center; justify-content: center; width: 17px; height: 17px; border-radius: 6px; border: 1.5px solid var(--line); background: var(--panel); transition: background .12s, border-color .12s; }
.dhr-bill input:checked + span { background: var(--primary); border-color: var(--primary); }
.dhr-bill input:checked + span::after { content: ""; width: 8px; height: 4.5px; border-left: 1.5px solid #fff; border-bottom: 1.5px solid #fff; transform: rotate(-45deg) translate(1px, -1px); }
.dhr-bill input:disabled + span { opacity: .45; }
.dhr-rate { display: flex; flex-direction: column; align-items: stretch; gap: 8px; padding: 9px 11px; border-radius: 11px; background: var(--hover); }
.dhr-rate-v { font-size: 12.5px; color: var(--text-dim); }
.dhr-rate-v b { color: var(--text); }
.dhr-rate-a { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.di-btn.primary-ghost { color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.di-btn.primary-ghost:hover { background: color-mix(in srgb, var(--primary) 18%, transparent); }
html[data-theme="dark"] .dpay-num.ok .dpay-num-v, :root:not([data-theme]) .dpay-num.ok .dpay-num-v { color: #4cd964; }
html[data-theme="dark"] .dpay-num.warn .dpay-num-v, :root:not([data-theme]) .dpay-num.warn .dpay-num-v { color: #ffb340; }
html[data-theme="dark"] .dph-m.over, :root:not([data-theme]) .dph-m.over { color: #ff6961; }
html[data-theme="dark"] .dph-chip.dph-block, :root:not([data-theme]) .dph-chip.dph-block { color: #ffb340; }
html[data-theme="dark"] .dpay-warn, :root:not([data-theme]) .dpay-warn { color: var(--text); }

/* ══════════════════════════════════════════════════════════════════════════════
   🔴🔴 CLIE-1055 · ДОК ПОВЕРХ ЖИВОГО КАДРА ОБЪЯВЛЯЕТ СВОИ СТЕКЛО И ЧЕРНИЛА
   («Элементы на странице звонков не заметные», владелец 12.09.2026)

   ЧТО БЫЛО. На скриншоте владельца весь ряд звонка 1-на-1 нарисован цветом
   rgb(35,37,43) по чёрному кадру — контраст 1.37:1 (порог «видно» 3:1), подложки
   нет ни у одной кнопки, кроме красной «Завершить». Замер живого прода
   (`tools/shots/zvon1055-row.js`) повторил снимок ДО СИМВОЛА:
       светлая тема · 17 кнопок из 18: фон rgba(0,0,0,0), иконка rgb(34,37,44),
                      ИКОНКА-vs-КАДР 1.37:1
       тёмная  тема · те же кнопки: фон rgba(255,255,255,.22), иконка rgb(232,235,241),
                      ИКОНКА-vs-КАДР 17.58:1  ← в тёмной дефекта НЕТ ВОВСЕ

   ПРИЧИНА (тот же класс, что CLIE-1010·R5 у поля чата созвона). Кнопки дока носят
   класс `.ghost`, а у §3 стоит
       `.ghost, html[data-theme="light"] .ghost { background: transparent; box-shadow: none }`
   Специфичность второго селектора (0,2,1) СИЛЬНЕЕ стиля компонента
   `.call-controls button` (0,1,1) — и в СВЕТЛОЙ теме стеклянная пилюля снималась
   вместе с тенью. Иконка при этом берёт `button { color: var(--text) }`, то есть
   ЧЕРНИЛА СТРАНИЦЫ — тёмные. Тёмный значок без подложки на живом кадре = ничего.
   Тем же ударом в светлой теме гасли и СОСТОЯНИЯ конференции (`.off` — «микрофон
   выключен», `.sharing` — «идёт показ экрана»): их правила тоже (0,2,0).

   ПРАВИЛО КЛАССА. Поверхность, которая лежит ПОВЕРХ ЧУЖОГО КАДРА, всегда тёмная и
   от темы страницы НЕ ЗАВИСИТ: она объявляет СВОИ стекло (`--ov-plate`), чернила
   (`--ov-ink`) и «выключено» (`--ov-off`), а её контролы берут ИХ. Токен темы внутрь
   дока не течёт — ни фоном, ни чернилами (канон `contrast-runtime-audit`:
   «поверхность, взявшая у темы заливку, обязана раздать и чернила», и обратная
   сторона — всегда-тёмная поверхность обязана НЕ брать чернила темы).

   ПОЧЕМУ СТЕКЛО ТЁМНОЕ, А НЕ БЕЛЁСОЕ. Прежняя пилюля rgba(255,255,255,.22) читалась
   только на тёмном кадре: на СВЕТЛОМ (окно, лампа, белая стена, показ экрана) белая
   пилюля с белой иконкой сливается. Тёмное стекло даёт ≥3:1 и на чёрном, и на белом,
   и на сером кадре — то же решение, что уже принято у окошка PiP (`.cm-btn`) и у дока
   конференции (`--gc-dock`). Блюр НЕ возвращаем (ЗВОН-34: `backdrop-filter` поверх
   живого видео читает кадр обратно из композитора на каждую кнопку).

   СТОРОЖ: `tools/contrast_audit.js` → проход `__calldocks__` (доки созвона в обеих
   темах, кадр чёрный/белый/серый) + храповик `tools/contrast_audit_baseline.json`;
   форма — `tools/design_lint.js` → блок `OVDOCK_MECH`.
   ────────────────────────────────────────────────────────────────────────────── */
.call-overlay, .groupcall-overlay {
  --ov-plate: var(--cm-10131a-72, rgba(16,19,26,.72));      /* стекло кнопки: ≥3:1 и на чёрном, и на белом кадре */
  --ov-plate-h: var(--cm-262a34-86, rgba(38,42,52,.86));
  --ov-ring: rgba(255,255,255,.22);    /* кромка: кнопку видно и на чёрном кадре */
  --ov-ink: #fff;                      /* чернила дока — НЕ var(--text) */
  --ov-off: rgba(255,59,48,.88);       /* «выключено» — тот же красный, что у PiP (.cm-btn.off) */
}
/* ── ряд звонка 1-на-1 ── */
/* 🔴 CLIE-1219: тень и кольцо у КАЖДОЙ кнопки сняты — с тех пор как ряд стал доком
   (общая стеклянная пилюля со своей тенью), они рисовали «кнопку в кнопке». Стекло и
   чернила остаются СВОИМИ (CLIE-1055): док звонка лежит поверх ЧУЖОГО кадра и от темы
   страницы не зависит; плотность `--ov-plate` выше `--gc-btn` осознанно — у ряда 1:1
   нет блюра (ЗВОН-34), и на светлом кадре кнопку держит именно она. */
.call-overlay .call-controls button.ghost {
  background: var(--ov-plate); color: var(--ov-ink); border-color: transparent;
}
.call-overlay .call-controls button.ghost:hover { background: var(--ov-plate-h); border-color: transparent; }
/* 🔴 «Выключено» — САМОЕ важное состояние ряда, и оно было нарисовано `opacity:.5` +
   зачёркиванием (зачёркивать у иконки нечего, а полупрозрачность делает её ЕЩЁ менее
   заметной — ровно жалоба владельца). Красный + белая иконка, как в PiP и конференции. */
.call-overlay .call-controls button.ghost.off {
  background: var(--ov-off); color: #fff; opacity: 1; text-decoration: none;
}
.call-overlay .call-controls button.ghost.sharing {
  background: var(--acc-grad); color: #fff; box-shadow: inset 0 0 0 2px rgba(255,255,255,.28);
}
/* ── док конференции: стекло у него своё (--gc-btn на тёмной пилюле дока), но в светлой
      теме `.ghost` снимал и его, и ОБА состояния. Возвращаем той же формой. ── */
.groupcall-overlay .groupcall-controls button.ghost {
  background: var(--gc-btn); color: var(--ov-ink); border-color: transparent;
}
.groupcall-overlay .groupcall-controls button.ghost:hover { background: var(--gc-btn-h); border-color: transparent; }
.groupcall-overlay .groupcall-controls button.ghost.off {
  background: rgba(239,68,68,.22); border-color: rgba(239,68,68,.42); color: #ffc2c2;
  opacity: 1; text-decoration: none;
}
.groupcall-overlay .groupcall-controls button.ghost.off:hover { background: rgba(239,68,68,.32); }
.groupcall-overlay .groupcall-controls button.ghost.sharing {
  background: var(--acc-grad); color: #fff; box-shadow: inset 0 0 0 2px rgba(255,255,255,.28);
}
/* 🔴 ВКЛЮЧЁННОЕ СОСТОЯНИЕ НА КАДРЕ — ЗАЛИВКА, А НЕ ТИНТ. `color-mix(--primary 16%)` поверх
   ЖИВОГО кадра не подложка, а почти ничего: на чёрном 1.2:1. На доке включённое = сплошной
   акцент + белая иконка (та же форма, что у #gcxHandBtn.on). Сюда же «формат кадра»
   (#videoFitBtn.on) — у него состояния НЕ БЫЛО вовсе: класс ставился, а рисовать его
   было нечем («нажал — ничего»). */
.call-overlay .call-controls #caCcBtn.active,
.call-overlay .call-controls #videoFitBtn.on,
.call-overlay .call-controls #callPipBtn.on,   /* окно поверх программ открыто (ЗВОН-604·6) */
.groupcall-overlay .groupcall-controls #gcCcBtn.active {
  background: var(--acc-grad); color: #fff; box-shadow: inset 0 0 0 2px rgba(255,255,255,.32);
}

/* ═══════════════════════════════════════════════════════════════════════════════
   🔴🔴 CLIE-1055·2 — ЗАХОД ПО ОСТАТКАМ ЗАМЕРА (светлая тема, живой прод 12.09.2026).
   Раунд 1 починил ряд кнопок звонка и намерил ЕЩЁ 27 нечитаемых мест в светлой теме
   (порог AA 4.5 для текста, 3:1 для заливки/канта контрола). Владелец: «делай заход» —
   значит закрываем их тем же приёмом: чернила меряются к СВОЕЙ подложке, а поверхность
   поверх ЧУЖОГО КАДРА объявляет своё стекло. Тёмную тему не трогаем (решение владельца).
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ── «Нет ответа» / «Пропущенный» в карточке звонка ────────────────────────────
   Было: инлайн #e5484d — 3.29:1 на тёплом пузыре. Инлайн не даёт теме углубить тон,
   поэтому цвет переехал в класс: тёмная получает ПРЕЖНИЙ оттенок, светлая — свой
   токен --danger (#b23e54 → 4.76:1 на пузыре). */
.call-msg-miss { color: #e5484d; }
html[data-theme="light"] .call-msg-miss { color: var(--danger); }

/* ── «в каталоге» у пользователя ───────────────────────────────────────────────
   Акцентный ТЕКСТ на акцентном тинте берёт --primary-2 (канон contrast-runtime-audit),
   а не --primary: замер прода 4.44:1 → 5.82:1. */
html[data-theme="light"] .au-pill.au-pill-pub { color: var(--primary-2); }

/* ── строка «длительность · вес · формат» на видео-карточке ────────────────────
   Было: белые чернила + text-shadow поверх ЧУЖОГО КАДРА. Пока постер не подъехал
   (спящее видео, медленная сеть, кадр не сгенерился), под строкой не кадр, а светлая
   карточка — замер прода 1.14:1. Тень кадром не является. Даём строке СВОЁ стекло —
   ту же тёмную пилюлю, что у соседней кнопки загрузки (.att-vid-get, rgba(0,0,0,.46)):
   белые чернила на ней читаются НА ЛЮБОМ кадре и без кадра вовсе. */
.att-vid-meta {
  /* .46 хватало на кадре, но пока постера нет — пилюля ложится на СВЕТЛУЮ карточку
     и белое на ней 3.85:1 (второй замер). .62 даёт 6.78:1 в этом худшем случае. */
  background: rgba(0,0,0,.62); border-radius: 9px; padding: 2px 8px;
  -webkit-backdrop-filter: saturate(140%) blur(6px); backdrop-filter: saturate(140%) blur(6px);
}

/* ── ВТОРОЙ ЗАМЕР ТОГО ЖЕ ЗАХОДА (CLIE-1055·2): что вылезло после первой правки ──────
   Прибор на живом проде: 27 → 9. Оставшиеся девять — те же два класса, просто на других
   поверхностях. Закрываем их здесь, чтобы не возвращаться. */

/* 1. ЧИП-МЕТКА. Цвет метки выбирает человек, формула `color-mix(--lc 74%, --text)` тон
      держит, а читаемость — нет: жёлтая метка 2.92:1. Чернила считает ЗАМЕР (--lci от
      ccReadableInk, см. app.js → lblInkVar); фолбэк — прежняя формула, тёмная не тронута. */
html[data-theme="light"] .v2-pc-lbl,
html[data-theme="light"] .v2ov-lchip,
html[data-theme="light"] .tip-label,
html[data-theme="light"] .tw-pill.lbl,
html[data-theme="light"] .task-chip.lbl,
html[data-theme="light"] .crmb-tag,
html[data-theme="light"] .v2-fl-chip.lbl.on {
  color: var(--lci, color-mix(in srgb, var(--lc, var(--muted)) 74%, var(--text)));
}

/* 2. АКЦЕНТНЫЙ ТЕКСТ НА АКЦЕНТНОМ ТИНТЕ берёт --primary-2 (канон contrast-runtime-audit).
      Замер прода: бейджи «Факт/Инсайт/Эпизод» 4.44:1, «Компания» в ленте 4.40:1,
      счётчик вида в «Пользователях» 4.28:1 → 5.6…5.8:1 тем же тоном. */
html[data-theme="light"] .kn-badge:where(:not(.kn-kind-decision, .kn-kind-lesson, .kn-kind-procedure, .kn-kind-preference)), /* CLIE-1946: виды памяти различимы — свои чернила на своём тинте */
html[data-theme="light"] .feed-hd .nm .badge-co,
html[data-theme="light"] .au-kinds button.on .au-kindn { color: var(--primary-2); }
/* …а СЕМАНТИЧЕСКИЕ виды знания держат свой оттенок: «Урок» — янтарь, «Процедура» — зелень, «Решение» —
   --info (style.css:19188). Общий --primary-2 перекрашивал «Урок» в синий. Янтарь --warning на своём тинте
   ~4.0:1 — поэтому тёмные чернила (--warning-ink «Глубины», в «Штиле» — смесь с --text, ~5.8:1). */
html[data-theme="light"] .kn-badge.kn-kind-lesson { color: var(--warning-ink, color-mix(in srgb, var(--warning) 72%, var(--text))); }
html[data-theme="light"] .kn-badge.kn-kind-procedure { color: var(--ok-ink, var(--ok)); }

/* 3. ЧИП ГРУППЫ/РОДИТЕЛЯ/КОМПАНИИ на плитке проекта — тот же класс, что чип-метка:
      формула 82% держала тон и теряла читаемость (синяя группа «Консалтинг» 3.67:1).
      Ink приезжает замером (--lci), фолбэк — прежняя формула. */
html[data-theme="light"] .v2-pc-fold {
  color: var(--lci, color-mix(in srgb, var(--fc, var(--muted)) 82%, var(--text)));
}

/* ══════════════════════════════════════════════════════════════════════════════════════════
   🤖 РАЗДЕЛ «ИИ-БОТЫ» В CRM (CLIE «AI-бот продаж», слой B) — `.aib-*`
   Контракт `docs/ai-bots-contract.md` §8. Всё на токенах базы, поэтому обе темы вылизаны
   одним кодом. Размерный класс ряда — `--ctl-h/--ctl-r/--ctl-fs` (канон control-size):
   поиск, кнопки и сегменты одного ряда обязаны совпасть по высоте.
   🔴 Статус бота — ТОЧКА и слово, левых полосок-реек здесь нет (канон accent).
   ══════════════════════════════════════════════════════════════════════════════════════════ */
.aib { display: flex; flex-direction: column; gap: 14px; padding: 4px 2px 24px; }
/* Тело раздела ИИ-боты в CRM — по сетке шапки: «CRM», подвкладки и тулбары соседних разделов стоят
   с полем 16 px, а у ботов было 2 px (замер: поиск с x 106 при раме на 104, «+ Бот» до 1429 при раме на 1431).
   Телефон не проверен — там прежние 2 px. */
@media (min-width: 761px) { #salesBody > .aib { padding-left: 16px; padding-right: 16px; } }
.aib-muted { color: var(--muted); font-size: 12.5px; line-height: 1.45; }
/* Пояснение под группой полей карточки бота («что бот знает всегда», «как писать слова вызова»).
   Отступ, и только он: цвет и размер берутся у .aib-muted, поэтому обе темы читаются сами. */
.aib-note { margin-top: 8px; }

/* Ряд управления: поиск + «Группа» + «Бот» — один размерный класс */
.aib-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.aib-search { position: relative; display: flex; align-items: center; gap: 7px; flex: 1 1 220px; min-width: 180px;
  height: var(--ctl-h); padding: 0 10px; border-radius: var(--ctl-r); border: 1px solid var(--line);
  background: var(--panel); transition: border-color .14s ease, box-shadow .14s ease; }
.aib-search:focus-within { border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); box-shadow: 0 0 0 3px var(--glow); }
.aib-search svg.ic { width: 14px; height: 14px; color: var(--muted); flex: none; }
.aib-q { flex: 1; min-width: 0; border: none; background: none; color: var(--text); font-size: var(--ctl-fs); outline: none; padding: 0; }
.aib-q::-webkit-search-cancel-button { display: none; }
/* Базовый `.primary` — кнопка ФОРМЫ: `width:100%` + `margin-top:6px` (см. блок про `.primary.small`
   выше). Кнопка ряда управления — ИНЛАЙН-контрол, поэтому ширину и отступ формы снимаем у себя,
   а базис задаём определённым (канон `ua-defaults`: `flex: 0 0 auto`, не «на усмотрение движка»). */
.aib-btn { display: inline-flex; align-items: center; gap: 6px; height: var(--ctl-h); padding: 0 12px;
  width: auto; margin-top: 0; flex: 0 0 auto;
  border-radius: var(--ctl-r); border: 1px solid var(--line); background: var(--panel); color: var(--text);
  font-size: var(--ctl-fs); font-weight: 500; cursor: pointer; white-space: nowrap;
  transition: background .13s ease, border-color .13s ease, transform .13s ease; }
.aib-btn:hover { background: var(--hover); border-color: color-mix(in srgb, var(--primary) 32%, var(--line)); }
.aib-btn:active { transform: translateY(.5px); }
.aib-btn.primary { background: var(--acc-fill); border-color: transparent; color: #fff; }
.aib-btn.primary:hover { background: color-mix(in srgb, var(--primary) 88%, #fff); }
.aib-btn svg.ic { width: 14px; height: 14px; }

/* Группы ботов */
.aib-groups { display: flex; flex-direction: column; gap: 12px; }
.aib-group { border: 1px solid var(--line); border-radius: 14px; background: var(--panel); overflow: hidden; }
.aib-ghead { display: flex; align-items: center; gap: 8px; padding: 9px 12px; min-height: 40px;
  border-bottom: 1px solid var(--line); background: var(--hover); }
.aib-gnogrip { width: 18px; flex: none; }
.aib-gdot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.aib-gname { font-size: 13.5px; font-weight: 600; color: var(--text); outline: none; border-radius: 6px;
  padding: 2px 5px; margin: -2px -5px; min-width: 40px; transition: background .12s ease, box-shadow .12s ease; }
.aib-gname:hover:not(.ro) { background: var(--hover); }
.aib-gname:focus { background: var(--bg); box-shadow: 0 0 0 2px var(--glow); }
.aib-gname.ro { color: var(--muted); font-weight: 500; }
.aib-gn { margin-left: auto; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums;
  min-width: 18px; text-align: right; }
.aib-gdel { opacity: 0; transition: opacity .13s ease; }
.aib-ghead:hover .aib-gdel, .aib-ghead:focus-within .aib-gdel { opacity: 1; }
.aib-empty { padding: 14px 16px; color: var(--muted); font-size: 12.5px; }
/* Поиск ничего не нашёл: слова + выход «Сбросить» в одной строке, а не пустая область. */
.aib-nf { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; border: 1px dashed var(--line); border-radius: 12px; }
.aib-nf > svg.ic { width: 14px; height: 14px; flex: none; }
.aib-nf .aib-a { margin: -4px 0; }

/* Строка бота: свёрнутая = имя + где работает + тумблер (прогрессивное раскрытие) */
.aib-bots { display: flex; flex-direction: column; }
.aib-bot + .aib-bot { border-top: 1px solid var(--line); }
.aib-brow { display: flex; align-items: center; gap: 10px; padding: 10px 14px; min-height: 54px; }
.aib-dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.aib-dot-on { background: var(--ok, #35c07f); }
.aib-dot-idle { background: var(--warn, #e2b04a); }
.aib-dot-off { background: var(--muted); opacity: .5; }
.aib-btog { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  border: none; background: none; padding: 2px 0; cursor: pointer; text-align: left; color: inherit; }
.aib-bname { font-size: 14.5px; font-weight: 600; color: var(--text); max-width: 100%; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.aib-bwhere { font-size: 12.5px; color: var(--muted); max-width: 100%; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.aib-bkind { font-size: 12.5px; font-weight: 550; color: var(--text); padding: 4px 11px; border-radius: 999px;
  background: color-mix(in srgb, var(--text) 8%, transparent); white-space: nowrap; flex: none; }
.aib-sw { flex: none; }

/* Раскрытая карточка бота — ВКЛАДКИ (владелец 11.10.2026: «сделай для каждой настройки свой таб…
   Сдлейа контрастнойсть… сделай элементы больше… Сделай пространство больше, все награмаждено»).
   Замер ДО (прод, обе темы): десять секций одной лентой, подпись поля 11.5px серым, заголовок
   секции 11px капсом, поле 31px/13px, подложка секции к карточке 1.13:1 — плита читалась пятном,
   а поле на ней терялось.
   ПОСЛЕ: тема настройки = вкладка (канон `.cc-tabs`, ряд не влез — лестница `ccSegFit`);
   полотно — фон страницы, секция — непрозрачная плита `--panel` с хэйрлайном (разницу держит
   ГРАНИЦА, а не 4 % подложки); подпись 13.5px цветом текста; поле 40px/14px с кромкой из цвета
   текста; воздух 16–22px. Размерный класс ряда переопределён СКОУПОМ (`--ctl-*` на `.aib-bbody`),
   поэтому поле, пикер `.ccpp-field`, сегмент `.cc-seg-md` и кнопка одного ряда по-прежнему
   совпадают по высоте (канон control-size), а остальной раздел живёт на токенах базы. */
.aib-bbody { --ctl-h: 40px; --ctl-r: 10px; --ctl-fs: 14px;
  --aib-field-bd: color-mix(in srgb, var(--text) 20%, transparent);
  display: flex; flex-direction: column; background: var(--bg); border-top: 1px solid var(--line); }
/* Ряд вкладок — шапка карточки (на её плите), содержимое вкладки — полотно под ним. */
.aib-tabs { padding: 0 14px; background: var(--panel); }
.aib-tabs > * { padding: 13px 13px 14px; font-size: 14px; }
.aib-tabs > *:focus-visible { box-shadow: inset 0 0 0 2px var(--glow); border-radius: 8px; }
.aib-pane { display: flex; flex-direction: column; gap: 16px; padding: 20px 20px 22px; }
.aib-pane[hidden], .aib-sec[hidden] { display: none; }
.aib-sec { display: flex; flex-direction: column; gap: 14px; padding: 20px 22px 22px; border-radius: 14px;
  background: var(--panel); border: 1px solid var(--line); }
.aib-sec-h { font-size: 15px; font-weight: 650; line-height: 1.3; color: var(--text); }
.aib-sec-h .aib-muted { font-size: 13px; font-weight: 400; margin-left: 8px; }
/* Подпись секции и пояснения — строкой, которую можно прочесть: 13px, ширина абзаца ≤ 72 знаков. */
.aib-sec-sub { margin-top: -8px; font-size: 13px; line-height: 1.55; color: var(--muted); max-width: 72ch; }
.aib-bbody .aib-muted { font-size: 13px; line-height: 1.55; }
.aib-sec > .aib-note { margin-top: -2px; max-width: 72ch; }
/* `auto-fill`, а не `auto-fit`: одно числовое поле («Потолок суммы») не растягивается на всю плиту —
   ширина поля говорит, сколько в него писать. Длинный текст — `.wide` во всю строку. */
.aib-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px 18px; align-items: end; }
.aib-f { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.aib-f.wide { grid-column: 1 / -1; }
.aib-f-l { font-size: 13.5px; font-weight: 550; line-height: 1.35; color: var(--text); }
.aib-f-i { width: 100%; box-sizing: border-box; min-height: var(--ctl-h); padding: 8px 12px;
  border-radius: var(--ctl-r); border: 1px solid var(--aib-field-bd, var(--line)); background: var(--input-bg);
  color: var(--text); font-size: var(--ctl-fs); line-height: 1.4; font-family: inherit; outline: none; resize: vertical;
  transition: border-color .14s ease, box-shadow .14s ease, background .14s ease; }
.aib-f-i::placeholder { color: var(--muted); opacity: .8; }
.aib-f-i:hover { border-color: color-mix(in srgb, var(--text) 32%, transparent); }
.aib-f-i:focus { background: var(--panel); border-color: color-mix(in srgb, var(--primary) 60%, var(--line));
  box-shadow: 0 0 0 3px var(--glow); }
/* Сервер отверг набранное (422/409/403): поле помечено до следующего удачного сохранения —
   слова отказа едут тостом, метка говорит, ГДЕ именно не сошлось. Тревожный тон — токеном. */
.aib-f-i.is-err, .aib-gname.is-err { border-color: color-mix(in srgb, var(--danger, #e5484d) 62%, var(--line));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger, #e5484d) 16%, transparent); }
textarea.aib-f-i { min-height: 88px; line-height: 1.5; padding-top: 10px; padding-bottom: 10px; }
/* Пикер в карточке (группа, модель, кого зовёт) — то же поле продукта, кромка — как у соседних полей. */
.aib-bbody .ccpp-field { border-color: var(--aib-field-bd); padding: 0 12px; }
.aib-bbody .ccpp-field:hover { border-color: color-mix(in srgb, var(--text) 32%, transparent); }
/* Сегмент прямо в секции — по ширине вариантов, а не во всю плашку: `.cc-seg-md { align-self: stretch }`
   канона (ccroom.css грузится позже) растягивал «Откуда берёт ответы» на всю секцию. Не влезает —
   ступени `ccSegFit` (`.cc-seg` уже в реестре дорожек): ужать воздух, затем прокрутка с краем. */
.aib-bbody .aib-seg { align-self: flex-start; }
/* 🔴 СЕГМЕНТ В СЕТКЕ КАРТОЧКИ БОТА ЗАНИМАЕТ ВСЮ СТРОКУ. Колонка сетки — 220px, а у сегмента
   ширина растёт с числом вариантов: «Всем сразу · По очереди · Равномерно» и «Без знаний ·
   Каталог + вики · Каталог + память · Каталог + всё» обрезались правым краем колонки, и
   последний вариант человек ПРОСТО НЕ ВИДЕЛ (замер скриншотом прода 16.09.2026, CRMC-1125).
   Обрезанный выбор — это отсутствующий выбор, поэтому правило общее, а не для одного поля. */
.aib-grid > .aib-f-seg { grid-column: 1 / -1; align-items: flex-start; }
.aib-grid > .aib-f-seg > .cc-seg { align-self: flex-start; }
/* Сегмент «в строку» карточки — ровно высота поля (40px) и его кегль: `.cc-seg button` канона (0,1,1)
   перебивает `.cc-seg-md > *`, и без этой строки сегмент вставал на 50px с подписью 12.5px. */
.aib-bbody .cc-seg-md > * { padding: 0 14px; font-size: var(--ctl-fs); line-height: calc(var(--ctl-h) - 8px); }
/* Строка-выключатель: название · что сейчас происходит словами · канон `.cc-switch` в полный рост.
   Вся строка — `<label>`: нажать можно по словам, а не только по рычажку. */
.aib-tgs { display: flex; flex-direction: column; }
.aib-tg { display: flex; align-items: center; gap: 18px; padding: 13px 0; cursor: pointer; }
.aib-tg:first-child { padding-top: 2px; }
.aib-tg:last-child { padding-bottom: 2px; }
.aib-tg + .aib-tg { border-top: 1px solid var(--line); }
.aib-tg-t { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.aib-tg-t b { font-size: 14px; font-weight: 600; line-height: 1.35; color: var(--text); }
.aib-tg-d { font-size: 13px; line-height: 1.5; color: var(--muted); }
.aib-tg .cc-switch { flex: none; }
/* Итог «что бот сделает сам» — одной фразой под выключателями продажи. Акцент — подложка и кольцо
   (канон accent), «не продаёт» — спокойная плашка без галочки: это ответ, а не тревога. */
.aib-sell-say { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: 12px;
  font-size: 14px; font-weight: 550; line-height: 1.4; color: var(--text);
  background: color-mix(in srgb, var(--primary) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.aib-sell-say svg.ic { width: 16px; height: 16px; flex: none; color: var(--primary); }
.aib-sell-say.off { font-weight: 500; color: var(--muted); background: var(--input-bg); box-shadow: inset 0 0 0 1px var(--line); }
.aib-sell-say.off svg.ic { display: none; }
/* Крупнее то, что нажимают: чипы, «＋», дни, отправка песочницы, подвал. */
.aib-bbody .aib-chips { gap: 10px; }
.aib-bbody .aib-chip { gap: 8px; padding: 7px 8px 7px 12px; font-size: 13.5px; }
.aib-bbody .aib-chip svg.ic { width: 15px; height: 15px; }
.aib-bbody .aib-chip .aib-chip-i { font-size: 12.5px; }
.aib-bbody .aib-chip-x { width: 24px; height: 24px; }
.aib-bbody .aib-chip-x svg.ic { width: 12px; height: 12px; }
.aib-bbody .aib-add { gap: 7px; min-height: 36px; padding: 0 14px; font-size: 13.5px; color: var(--text); }
.aib-bbody .aib-add svg.ic { width: 14px; height: 14px; color: var(--muted); }
.aib-bbody .aib-days { gap: 8px; }
.aib-bbody .aib-day { min-width: 46px; height: 38px; padding: 0 12px; border-radius: 10px; font-size: 14px;
  border-color: var(--aib-field-bd); background: var(--input-bg); }
.aib-bbody .aib-day.on { background: color-mix(in srgb, var(--primary) 14%, transparent);
  border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); font-weight: 600; }
.aib-bbody .aib-days .aib-muted { margin-left: 6px; }
.aib-bbody .aib-sand { gap: 10px; }
.aib-bbody .aib-go { padding: 0 16px; }
.aib-bbody .aib-sbub { font-size: 14px; padding: 9px 13px; }
.aib-bbody .aib-sbub.bot, .aib-bbody .aib-sempty, .aib-bbody .aib-why, .aib-bbody .aib-unq { background: var(--input-bg); }
.aib-bbody .aib-sempty b { font-size: 14px; }
.aib-bbody .aib-why-t { font-size: 12.5px; }
.aib-bbody .aib-why-r { font-size: 13px; }
.aib-bbody .aib-unans { gap: 8px; }
.aib-bbody .aib-unq { padding: 10px 14px; gap: 3px 12px; }
.aib-bbody .aib-unq-t { font-size: 14px; }
.aib-bbody .aib-unq-m { font-size: 12.5px; }
.aib-bbody .aib-a { font-size: 13.5px; }
.aib-bbody .aib-a svg.ic { width: 15px; height: 15px; }

/* Привязки — чипы «где работает» */
.aib-chips { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; }
.aib-chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 6px 4px 9px; border-radius: 999px;
  font-size: 12px; color: var(--text); background: color-mix(in srgb, var(--primary) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 24%, transparent); }
.aib-chip.off { background: var(--hover); box-shadow: inset 0 0 0 1px var(--line); color: var(--muted); }
.aib-chip svg.ic { width: 13px; height: 13px; opacity: .8; }
.aib-chip-x { border: none; background: none; padding: 0; width: 18px; height: 18px; border-radius: 50%;

/* 📚 Материалы бота: чип «файл/сайт» — та же форма, что у привязок, плюс СОСТОЯНИЕ словами
   и ссылка на сам источник (человек обязан мочь открыть то, на что сослался бот). */
.aib-chip .aib-chip-i { font-style: normal; font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.aib-chip .aib-chip-a { color: inherit; text-decoration: none; border-bottom: 1px solid color-mix(in srgb, currentColor 28%, transparent); }
.aib-chip .aib-chip-a:hover { border-bottom-color: currentColor; }
.aib-chip.bad { color: var(--danger); box-shadow: 0 0 0 1px color-mix(in srgb, var(--danger) 30%, transparent) inset; }
.aib-chip.bad .aib-chip-i { color: var(--danger); }
.aib-chip.busy .aib-chip-i { color: var(--accent); }
.aib-chip.busy svg.ic:first-child { animation: aib-know-pulse 1.2s ease-in-out infinite; }
@keyframes aib-know-pulse { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }
.aib-kgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 520px) { .aib-kgrid { grid-template-columns: 1fr; } }
  display: inline-flex; align-items: center; justify-content: center; color: var(--muted); cursor: pointer;
  transition: background .12s ease, color .12s ease; }
.aib-chip-x:hover { background: var(--line); color: var(--text); }
.aib-chip-x svg.ic { width: 11px; height: 11px; }
.aib-add { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 999px;
  border: 1px dashed var(--line); background: none; color: var(--muted); font-size: 12px; cursor: pointer;
  transition: color .13s ease, border-color .13s ease, background .13s ease; }
.aib-add:hover { color: var(--text); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); background: var(--hover); }
.aib-add svg.ic { width: 12px; height: 12px; }

/* Рабочие дни */
.aib-days { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.aib-day { min-width: 34px; height: 26px; padding: 0 8px; border-radius: 8px; border: 1px solid var(--line);
  background: var(--panel); color: var(--muted); font-size: 12px; cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease; }
.aib-day:hover { color: var(--text); }
.aib-day.on { background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--text);
  border-color: color-mix(in srgb, var(--primary) 38%, var(--line)); }
.aib-days .aib-muted { margin-left: 4px; }

/* Песочница «проверить ответ» */
.aib-sand { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.aib-sand-in { flex: 1 1 220px; min-width: 160px; }
.aib-go { display: inline-flex; align-items: center; gap: 6px; height: var(--ctl-h); padding: 0 13px;
  border-radius: var(--ctl-r); border: 1px solid transparent; background: var(--acc-fill); color: #fff;
  font-size: var(--ctl-fs); font-weight: 500; cursor: pointer; white-space: nowrap;
  transition: background .13s ease, opacity .13s ease; }
.aib-go:hover { background: color-mix(in srgb, var(--primary) 88%, #fff); }
.aib-go[disabled], .aib-go.busy { opacity: .6; cursor: default; }
.aib-go svg.ic { width: 14px; height: 14px; }

/* 🧪 CRMC-1127 · ПЕСОЧНИЦА — МИНИ-ЧАТ (пришла на место одноразового `.aib-sand-out`/`.aib-reply`).
   Лента пузырей: «я» справа, бот слева — тот же язык, что у переписки, только компактнее.
   Панель «почему» под ответом свёрнута по умолчанию — прогрессивное раскрытие, экран не
   отбираем до вопроса. Всё на токенах базы, поэтому обе темы держит один код. */
/* 🔴 СВОЕГО СКРОЛЛА У ЛЕНТЫ НЕТ (храповик CLIE-620): она растёт, а скроллит панель раздела,
   которая уже скроллится. Кап в px внутри скроллящейся панели прятал бы часть разговора за
   вторым ползунком — ровно то, что храповик и запрещает. */
.aib-sand-feed { display: flex; flex-direction: column; gap: 12px; padding: 2px; }
.aib-sand-feed:empty { display: none; }
.aib-sturn { display: flex; flex-direction: column; gap: 5px; }
.aib-sbub { max-width: 84%; padding: 8px 11px; border-radius: 12px; font-size: 13px; line-height: 1.45; }
.aib-sbub.me { align-self: flex-end; border-bottom-right-radius: 5px; color: var(--text);
  background: color-mix(in srgb, var(--primary) 17%, transparent); }
.aib-sbub.bot { align-self: flex-start; border-bottom-left-radius: 5px; color: var(--text);
  background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); }
.aib-sbub.mute .aib-sbub-t { color: var(--muted); }
.aib-sbub.pend { display: inline-flex; align-items: center; gap: 7px; }
.aib-sbub-t { white-space: pre-wrap; overflow-wrap: anywhere; }
.aib-sbub-t svg.ic { width: 13px; height: 13px; vertical-align: -2px; margin-right: 5px; }
/* Ряд быстрых ответов В ПЕСОЧНИЦЕ — подписи, а не кнопки: нажимать тут нечего, и вид обязан
   это говорить (иначе «видно, но не работает»). Класс кнопки тот же — гасим только поведение. */
.aib-sbtns { margin-top: 7px; }
.aib-sbtns .bot-btn[disabled] { cursor: default; pointer-events: none; opacity: .78; }
/* «Почему так» — подпись-раскрывашка, а не контрол-тяжеловес: она объясняет ход, а не действует. */
.aib-why-t { appearance: none; font-family: inherit; align-self: flex-start; display: inline-flex;
  align-items: center; gap: 6px; margin-left: -4px; padding: 2px 5px; border: 0; border-radius: 7px;
  background: none; color: var(--muted); font-size: 11.5px; cursor: pointer;
  transition: background .12s ease, color .12s ease; }
.aib-why-t:hover { background: var(--hover); color: var(--text); }
.aib-why-t svg.ic { width: 12px; height: 12px; flex: none; transition: transform .13s ease; }
.aib-why-t[aria-expanded="true"] svg.ic { transform: rotate(180deg); }
.aib-gate-chip { padding: 1px 7px; border-radius: 999px; font-size: 10.5px; font-weight: 600; }
.aib-gate-chip.ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 15%, transparent); }
.aib-gate-chip.bad { color: var(--danger); background: color-mix(in srgb, var(--danger) 15%, transparent); }
.aib-why { display: flex; flex-direction: column; gap: 5px; padding: 9px 11px; border-radius: 10px;
  background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); }
.aib-why[hidden] { display: none; }
.aib-why-r { display: flex; align-items: flex-start; gap: 6px; font-size: 12px; color: var(--text); line-height: 1.45; }
.aib-why-r svg.ic { width: 13px; height: 13px; flex: none; margin-top: 2px; color: var(--muted); }
.aib-why-r a { color: var(--accent); text-decoration: none; }
.aib-why-r a:hover { text-decoration: underline; }
/* Проверенный и НЕ сработавший гейт виден, но мелко и серым: он ответ, а не новость. */
.aib-why-r.dim, .aib-why-r.dim span { color: var(--muted); font-size: 11.5px; }
.aib-why-r.bad, .aib-why-r.bad svg.ic { color: var(--danger); }
.aib-why-r.good, .aib-why-r.good svg.ic { color: var(--ok); }
/* Пустая песочница — честное пустое состояние с подсказкой, а не мёртвый блок. */
.aib-sempty { display: flex; align-items: flex-start; gap: 11px; padding: 12px 14px; border-radius: 11px;
  background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); }
.aib-sempty svg.ic { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--muted); }
.aib-sempty b { font-size: 13px; color: var(--text); }
/* Мгновенная обратная связь у долгого хода (глоб. правило №8): один спиннер на песочницу. */
.aib-spin { display: inline-block; flex: none; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--muted) 42%, transparent); border-top-color: var(--primary);
  animation: aibSpin .7s linear infinite; }
.aib-go .aib-spin { border-color: rgba(255,255,255,.42); border-top-color: #fff; }
@keyframes aibSpin { to { transform: rotate(360deg); } }
/* Заголовок секции с действием справа («Очистить» песочницу) — модификатор, а не правка всех шапок. */
.aib-sec-h.row { display: flex; align-items: center; gap: 6px; }
.aib-sec-h.row .aib-muted { flex: 1 1 auto; min-width: 0; }
.aib-sec-h.row .aib-a { text-transform: none; letter-spacing: 0; flex: none; }

/* Подвал карточки бота */
.aib-foot { display: flex; flex-direction: row; align-items: center; flex-wrap: wrap; gap: 10px 16px;
  padding: 14px 22px 16px; border-top: 1px solid var(--line); }
.aib-a { display: inline-flex; align-items: center; gap: 5px; border: none; background: none; padding: 4px 6px;
  margin: -4px -6px; border-radius: 8px; color: var(--muted); font-size: 12.5px; cursor: pointer;
  transition: background .12s ease, color .12s ease; }
.aib-a:hover { background: var(--hover); color: var(--text); }
.aib-a.bad:hover { color: var(--danger, #e5484d); }
.aib-a svg.ic { width: 13px; height: 13px; }
.aib-foot .aib-a:first-of-type { margin-left: auto; }

/* Пустое состояние и честный отказ */
.aib-hello, .aib-fail { display: flex; align-items: center; gap: 14px; padding: 16px 18px;
  border: 1px solid var(--line); border-radius: 14px; background: var(--panel); flex-wrap: wrap; }
.aib-hello > svg.ic, .aib-fail > svg.ic { width: 26px; height: 26px; color: var(--muted); flex: none; }
.aib-hello > div, .aib-fail > div { flex: 1 1 260px; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.aib-hello b, .aib-fail b { font-size: 13.5px; color: var(--text); }
.aib-hello > .aib-btn, .aib-fail > .aib-btn { flex: none; }

/* Журнал ходов */
.aib-runs { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 14px;
  background: var(--panel); overflow: hidden; }
.aib-run { display: flex; gap: 10px; padding: 11px 14px; align-items: flex-start; }
.aib-run + .aib-run { border-top: 1px solid var(--line); }
.aib-run-dot { width: 7px; height: 7px; border-radius: 50%; margin-top: 6px; flex: none; background: var(--muted); opacity: .5; }
.aib-run-turn .aib-run-dot { background: var(--ok, #35c07f); opacity: 1; }
.aib-run-handoff .aib-run-dot { background: var(--primary); opacity: 1; }
.aib-run-error .aib-run-dot { background: var(--danger, #e5484d); opacity: 1; }
.aib-run-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.aib-run-h { font-size: 13px; color: var(--text); }
.aib-run-h span { color: var(--muted); }
.aib-run-why { color: var(--muted); }
/* 🏃 АКЦЕНТ «ДОГОНЯЮЩЕЕ КАСАНИЕ» (0376, CRMC-1129) — по канону `accent`: значок + СЛОВО
   (читается и в ч/б), подложка color-mix 12% и внутренняя рамка 22%, без левых реек.
   Слово привозит сервер (`followup_say`), здесь только форма. */
.aib-run-fup { display: inline-flex; align-items: center; gap: 4px; vertical-align: middle;
  padding: 1px 7px 1px 5px; border-radius: 999px; font-size: 11px; font-weight: 600; line-height: 1.5;
  color: var(--primary-2); background: color-mix(in srgb, var(--primary-2) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary-2) 22%, transparent); }
.aib-run-fup svg { width: 11px; height: 11px; opacity: .9; }
/* 🪜 АКЦЕНТ «ШАГ ПРОДАЖИ» (CLIE-1787) — тот же канон `accent`, что у касания: значок +
   СЛОВО, подложка 12 %, внутренняя рамка 22 %. Другой токен, чтобы два акцента в одной
   строке не слились в один; слово привозит сервер (`play_say`), здесь только форма. */
.aib-run-play { display: inline-flex; align-items: center; gap: 4px; vertical-align: middle;
  padding: 1px 7px 1px 5px; border-radius: 999px; font-size: 11px; font-weight: 600; line-height: 1.5;
  color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 22%, transparent); }
.aib-run-play svg { width: 11px; height: 11px; opacity: .9; }
.aib-run-t { font-size: 12.5px; color: var(--text); opacity: .88; line-height: 1.45;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; }
.aib-run-m { font-size: 11px; color: var(--muted); }
/* «Показать ещё» — страница журнала в прошлое (курсор `before`), кнопка того же ряда контролов. */
.aib-more { display: flex; justify-content: center; padding: 2px 0 0; }

/* 📊 ВИД «АНАЛИТИКА» ботов (CRMC-1124) — тот же словарь витрин, что у дашборда сделок и
   аналитики лидов: плитки `.fc-card`, полосы `.db-fn-*`. Своих плиток и своего графика
   раздел не рисует (канон one-implementation), здесь только рама внутри `.aib` и блок
   «как это посчитано». Цвета — токены, поэтому обе темы берутся даром. */
.aib .deal-dashboard.botan { padding: 4px 0 8px; max-width: none; }
.aib .deal-dashboard.botan .fc-section-title:first-child { margin-top: 6px; }
/* 🔴 ПОЯСНЯЛКА НЕ РЕЖЕТСЯ ПОСРЕДИ СЛОВА. `.db-fn-name` — инлайн-флекс, и `text-overflow:
   ellipsis` у него не срабатывает ВООБЩЕ: свойство применяется к собственному тексту блока, а
   не к детям-флексам. В колонке 190px подпись просто обрубалась («в доли не входят — м»), причём
   молча и в обеих темах. Колонку соседей (панель сделки) не трогаем — в НАШЕЙ витрине кладём
   пояснение ПОД название и даём ему перенос. */
.aib .deal-dashboard.botan .db-fn-row { grid-template-columns: 232px minmax(0, 1fr) 118px; }
/* Точка — СВОЯ колонка, а не флекс-сосед: на переносе длинного названия («Нет знаний для
   ответа — позван человек») она уезжала на строку выше и висела над текстом одна. */
.aib .deal-dashboard.botan .db-fn-name {
  display: grid; grid-template-columns: 9px minmax(0, 1fr); column-gap: 8px; row-gap: 1px;
  align-items: start; white-space: normal; overflow: visible;
}
.aib .deal-dashboard.botan .db-fn-name i { margin-top: 5px; }
.aib .deal-dashboard.botan .db-fn-name > span { min-width: 0; }
.aib .deal-dashboard.botan .db-fn-name em { grid-column: 2; line-height: 1.32; } /* без opacity: она гасила --text-dim до 4.42 */
@media (max-width: 900px) {
  .aib .deal-dashboard.botan .db-fn-row { grid-template-columns: 150px minmax(0, 1fr) 92px; }
}
/* 🔴 Определение «закрыл сам» и окно оценки — ВИДИМЫЙ блок, а не сноска и не подсказка при
   наведении: без него проценту не верят (у Fin/Lyro/Zendesk это отдельный раздел доки). */
.botan-how { border: 1px solid var(--line); border-radius: 14px; background: var(--panel); padding: 12px 16px; }
.botan-how ul { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; }
.botan-how li { font-size: 12.5px; line-height: 1.5; color: var(--text); opacity: .86; }

/* Протяжка: та же анимация переезда, что у этапов и платежей (одна рука у порядка) */
.aib-reordering .aib-bot, .aib-reordering .aib-group { transition: transform 140ms cubic-bezier(.2,.7,.3,1); }
.aib-bot.aib-dragging, .aib-group.aib-dragging { background: var(--panel);
  box-shadow: 0 8px 22px rgba(0,0,0,.16); z-index: 3; cursor: grabbing; position: relative; }
.aib-brow .dph-grip, .aib-ghead .dph-grip { margin: 0; }
.aib-brow:hover .dph-grip, .aib-brow:focus-within .dph-grip,
.aib-ghead:hover .dph-grip, .aib-ghead:focus-within .dph-grip { opacity: .5; }
/* Куда ляжет бот — видно ДО того, как отпустили: коробка группы под курсором зажигается.
   Бросок в «Без группы» — такой же переезд, поэтому подсветка общая для всех коробок. */
.aib-group.aib-drophot { border-color: color-mix(in srgb, var(--primary) 55%, var(--line));
  box-shadow: 0 0 0 3px var(--glow); }

/* Цвет группы правит ТА ЖЕ точка, которая его показывает (одна реализация, второй строки
   настроек у группы нет). Зона нажатия больше самой точки — в 8 px пальцем не попасть. */
.aib-gdotb { position: relative; border: none; padding: 0; cursor: pointer; -webkit-appearance: none; appearance: none; }
/* Зона нажатия расширена ровно в пределах `gap: 8px` шапки — чужие клики не перехватываем. */
.aib-gdotb::after { content: ""; position: absolute; inset: -7px; border-radius: 50%; }
.aib-gdotb:hover, .aib-gdotb:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--glow); }

/* «Дублировать» в строке бота — по наведению, как «удалить» у группы (тот же язык). */
.aib-bdup { opacity: 0; margin: -4px 0; padding: 4px; transition: opacity .13s ease; }
.aib-brow:hover .aib-bdup, .aib-brow:focus-within .aib-bdup { opacity: 1; }
/* bots-gutter-1 · bots-name-1 · телефон (q_crm): поле тела — как у ≥761 (правило `#salesBody > .aib` выше по
   файлу), иначе поиск, «+ Группа» и карточка группы стояли в 1 px от кромки панели. Копия-кнопка в строке бота
   видна только по наведению — на касании её не видно, а ≈36 px она отнимала у имени («Любл…»);
   «Дублировать» остаётся в подвале открытой карточки бота (.aib-foot). */
@media (max-width: 760px) {
  #salesBody > .aib { padding-left: 16px; padding-right: 16px; }
  .aib-brow > .aib-bdup { display: none; }
}
/* bots-gutter-1 · bots-name-1 · ≤560: поле 12 px, как у тулбаров CRM; шаг строки 8 px, как у шапки группы,
   — ещё 8 px имени; чип вида и переключатель свой размер держат (flex: none). */
@media (max-width: 560px) {
  #salesBody > .aib { padding-left: 12px; padding-right: 12px; }
  .aib-brow { gap: 8px; }
  /* bots-row-name-1 · в одном ряду с именем стояли чип вида («Продажи») и тумблер — имени оставалось ≈90 px («ЛюблюЕду …»,
     кадр crm_bots 390). Сетка на той же разметке: чип — второй строкой под именем и «где работает», тумблер справа на
     обе строки, имя берёт всю колонку и переносится до двух строк. Порядок кнопок для фокуса прежний. */
  .aib-brow { display: grid; grid-template-columns: auto auto minmax(0, 1fr) auto;
    grid-template-areas: "grip dot name sw" "grip . kind sw"; column-gap: 8px; row-gap: 4px; align-items: center; }
  .aib-brow > .dph-grip { grid-area: grip; }
  .aib-brow > .aib-dot { grid-area: dot; }
  .aib-brow > .aib-btog { grid-area: name; justify-self: stretch; }
  .aib-brow > .aib-bkind { grid-area: kind; justify-self: start; }
  .aib-brow > .aib-sw { grid-area: sw; }
  .aib-bname { white-space: normal; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
}

/* Поповер раздела: рама, тень и прокрутка — общий `.cc-pop`, здесь только внутренняя геометрия. */
.aib-pop { padding: 8px; }
.aib-pickpop { min-width: 0; }
/* Меню у якоря (с чего начать бота · «пусть помолчит здесь»): строка называет ДЕЙСТВИЕ, а
   вторая строка — его цену словами. Выбор из двух строк ≠ список сущностей, поэтому это не
   пикер с поиском, а короткое меню. */
.aib-menu { display: flex; flex-direction: column; gap: 2px; }
.aib-menu-h { font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); padding: 2px 8px 6px; }
.aib-menu-i { display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  width: 100%; box-sizing: border-box; padding: 8px 10px; border: none; border-radius: 10px;
  background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer;
  transition: background .12s ease; }
.aib-menu-i:hover { background: var(--hover); }
.aib-menu-i:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--glow); }
.aib-menu-t { font-size: 13.5px; font-weight: 500; }
.aib-menu-s { font-size: 11.5px; color: var(--muted); line-height: 1.35; }

/* 🤖 «ИИ-бот здесь» — строка карточки беседы (второй вход к той же двери) */
.gs-botrow { display: flex; align-items: center; gap: 10px; padding: 10px 12px; margin: 8px 0 2px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--panel); cursor: pointer;
  transition: border-color .13s ease, background .13s ease; }
.gs-botrow:hover { background: var(--hover); border-color: color-mix(in srgb, var(--primary) 30%, var(--line)); }
.gs-botrow-ic { width: 28px; height: 28px; border-radius: 9px; flex: none; display: inline-flex;
  align-items: center; justify-content: center; color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent); }
.gs-botrow-ic svg.ic { width: 16px; height: 16px; }
.gs-botrow-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.gs-botrow-t { font-size: 13.5px; font-weight: 500; color: var(--text); }
.gs-botrow-s { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gs-botrow .cc-switch { transform: scale(.8); transform-origin: right center; }
/* Действия живут В ТОЙ ЖЕ строке, о которой говорят: приглушить бота именно здесь и
   посмотреть, что он делал именно здесь. Отвязывать ради тишины в одной беседе не надо. */
.gs-botrow-acts { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; margin-top: 5px; }
.gs-botrow-acts .aib-a { margin: 0; padding: 3px 6px; font-size: 11.5px; }

/* Окно «кто отвечает в этой беседе» */
.cbp-say { padding: 2px 2px 0; }
.cbp-foot { display: flex; justify-content: flex-start; padding-top: 2px; }

/* 🙋 ПЛАШКА «КТО ЗДЕСЬ ОТВЕЧАЕТ» — состояние бота в ОТКРЫТОЙ беседе и кнопки передачи
   человеку (#ccHandoffBar). Стоит в подшапке треда соседом островка незнакомца
   (.dm-peer-bar) и плашки созвона — поэтому и язык у неё тот же: панель, поля 8/12,
   радиус 14, тонкий хэйрлайн, мягкая тень. Своих чисел нет.
   🔴 Акцент — значок и СЛОВО плюс подложка color-mix + кольцо (канон accent, CLIE-483):
      никаких левых полосок-реек.
   🔴 Контролы ряда — существующий .aib-btn, то есть общий размерный класс --ctl-h/--ctl-r/
      --ctl-fs (CLIE-505): вторых кнопок «как в чате» не заводим.
   🔴 Обе темы держатся на токенах (--panel/--line/--text/--muted/--primary/--ok), прибитых
      цветов нет; акцентные ЧЕРНИЛА — --primary-2 (contrast-runtime-audit), значок на своём
      тинте — --primary, как у соседней строки .gs-botrow-ic. */
.cc-hoff {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 8px 12px 0; padding: 7px 10px 7px 12px;
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .05);
  animation: ccHoffIn .18s cubic-bezier(.2, .7, .3, 1);
}
.cc-hoff-ic {
  width: 28px; height: 28px; border-radius: 9px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--muted); background: color-mix(in srgb, var(--muted) 14%, transparent);
}
.cc-hoff-ic svg.ic { width: 16px; height: 16px; }
.cc-hoff-b { flex: 1 1 180px; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.cc-hoff-t { font-size: 13px; font-weight: 500; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-hoff-s { font-size: 11.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Кнопка не сжимается ниже своей подписи (СРЕД-33): узкая колонка уводит ряд на вторую
   строку целиком, а не режет слово «Позвать человека» пополам. */
.cc-hoff-acts { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; flex-wrap: wrap; }
.cc-hoff-acts .aib-btn { white-space: nowrap; }
/* Кнопка стоит НА ПАНЕЛИ, а заливка .aib-btn — сама панель: на плашке она слилась бы с фоном
   и читалась одним хэйрлайном. Берём утопленный тон, которым на панели живут поля ввода
   (--input-bg): свой цвет не выдумываем, и обе темы получают его сразу. */
.cc-hoff-acts .aib-btn:not(.primary) { background: var(--input-bg); }
.cc-hoff-acts .aib-btn:not(.primary):hover { background: var(--hover); }
.cc-hoff-acts .aib-btn[disabled] { opacity: .55; cursor: default; }
/* «Позвали человека» — состояние, которого ЖДУТ: подложка и кольцо акцента, не рейка. */
.cc-hoff-called { background: color-mix(in srgb, var(--primary) 8%, var(--panel));
  border-color: color-mix(in srgb, var(--primary) 26%, var(--line)); }
.cc-hoff-called .cc-hoff-ic { color: var(--primary);
  background: color-mix(in srgb, var(--primary) 15%, transparent); }
/* «Диалог ведёт человек» — спокойное «всё под контролем»: зелёный язык статусов продукта. */
.cc-hoff-taken .cc-hoff-ic { color: var(--ok); background: var(--ok-soft); }
@keyframes ccHoffIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }

/* Журнал ходов: кого позвали, что бот сделал руками, и переход в саму беседу */
/* Кого позвали — акцентными чернилами (--primary-2, contrast-runtime-audit). «Звать было
   некого» — это НЕ адресат, а честное отсутствие: приглушённым, чтобы не читаться именем. */
.aib-run-to { color: var(--primary-2); }
.aib-run-to.none { color: var(--muted); }
.aib-run-act { display: inline-flex; align-items: center; gap: 5px; min-width: 0;

.aib-run-src { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.aib-run-src svg.ic { width: 13px; height: 13px; flex: none; }
.aib-run-src a { color: var(--accent); text-decoration: none; }
.aib-run-src a:hover { text-decoration: underline; }
  font-size: 12px; color: var(--text); }
.aib-run-act svg.ic { width: 12px; height: 12px; flex: none; color: var(--muted); }
.aib-run-act span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.aib-run[data-runconv] { cursor: pointer; transition: background .12s ease; }
.aib-run[data-runconv]:hover { background: var(--hover); }
.aib-run[data-runconv]:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--glow); }
/* 🎓 Обучение бота (11.10.2026): заметка — чип, имя которого ПРАВИТ заметку (кнопка, не ссылка);
   «Вопросы без ответа» — строки с вопросом, когда спрашивали и двумя выходами («Ответить», «В беседу»). */
.aib-chip .aib-chip-ed { appearance: none; border: 0; background: none; padding: 0; margin: 0; font: inherit;
  color: inherit; cursor: pointer; border-bottom: 1px solid color-mix(in srgb, currentColor 28%, transparent); }
.aib-chip .aib-chip-ed:hover { border-bottom-color: currentColor; }
.aib-unans { display: flex; flex-direction: column; gap: 6px; }
.aib-unans:empty { display: none; }
.aib-unq { display: grid; grid-template-columns: 1fr auto auto; gap: 2px 10px; align-items: center;
  padding: 7px 10px; border-radius: 10px; background: var(--panel); box-shadow: inset 0 0 0 1px var(--line); }
.aib-unq-t { grid-column: 1; grid-row: 1; font-size: 13px; color: var(--text); overflow-wrap: anywhere; }
.aib-unq-m { grid-column: 1; grid-row: 2; font-size: 11.5px; }
.aib-unq .aib-a { grid-row: 1 / span 2; margin: 0; white-space: nowrap; }
.aib-unq .aib-a[data-botteach] { grid-column: 2; color: var(--accent); }
.aib-unq .aib-a[data-botunqconv] { grid-column: 3; }
.aib-unq-more { margin-top: 2px; }
.aib-note-ta { width: 100%; min-height: 150px; resize: vertical; box-sizing: border-box; }
.aib-why-r .aib-a[data-botteach] { margin: -3px 0 -3px auto; color: var(--accent); white-space: nowrap; }

/* ═══ 🤝 РАЗДЕЛ «ПАРТНЁРЫ» (CLIE-1082 · 4/7) ═══════════════════════════════════
   Одна поверхность #partnersOverlay на каркасе .tasks-workspace; виды —
   каноническим .cc-seg поверх ОДНОГО компонента. Здесь только вид: сегмент,
   тумблер, чип, поиск и окно берутся из базы, своих копий у раздела нет.
   🔴 Акцент — точка + СЛОВО и мягкая подложка; левых реек-полос нет (CLIE-483).
   🔴 Контролы одного ряда — один размерный класс --ctl-h/--ctl-r/--ctl-fs (CLIE-505).
   🔴 Ширина карточки не прибита: шов даёт WIN_PANES (#partnersOverlay .pt-side). */
/* Значок раздела стоит РЯДОМ с названием, а не приклеен к букве: у общего .tw-title
   своей раскладки нет (он одна строка текста), поэтому её объявляет страница — как это
   уже сделано у «Компаний». */
#partnersOverlay .tw-title { display: inline-flex; align-items: center; gap: 9px; min-width: 0; overflow: hidden; }
#partnersOverlay .tw-title > span { overflow: hidden; text-overflow: ellipsis; }
#partnersOverlay .tw-title .ic { width: 19px; height: 19px; flex: 0 0 auto; color: var(--muted); }
#partnersOverlay .pt-sub { display: flex; gap: 8px; align-items: center; padding: 8px 12px; flex-wrap: wrap; }
#partnersOverlay .pt-tools { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; flex: 1 1 320px; min-width: 0; }
.pt-head-acts { display: flex; gap: 8px; align-items: center; }
.pt-q { flex: 1 1 200px; min-width: 140px; min-height: var(--ctl-h); }
.pt-chips { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.pt-date {
  min-height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs);
  background: var(--input-bg); border: 1px solid var(--line); color: var(--text); padding: 0 8px;
}
.pt-period { display: inline-flex; gap: 6px; align-items: center; font-size: 12px; color: var(--muted); }

/* 🧭 «Как это работает» — цепочка шагов прямо в разделе (CLIE-1082·Р2): владелец спросил
   «на что приводятся клиенты, какая логика», и ответ обязан жить на экране, а не в чате.
   Чернила на своей подложке (канон contrast-runtime-audit); левых реек нет (канон accent). */
.pt-how-rows { display: flex; flex-direction: column; gap: 10px; }
.pt-how-row {
  display: flex; gap: 10px; align-items: flex-start; padding: 10px 12px; border-radius: 12px;
  background: color-mix(in srgb, var(--text) 4%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 8%, transparent);
}
.pt-how-row > .ic { width: 18px; height: 18px; flex: 0 0 18px; margin-top: 2px; color: var(--muted); }
.pt-how-tx { min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.pt-how-t { font-weight: 600; font-size: 13px; color: var(--text); }
.pt-how-s { font-size: 12px; line-height: 1.45; color: var(--muted); }

/* 🏢 Пространство программы — подпись рядом с именем раздела (CLIE-1082·Р2): человек
   обязан видеть, в КАКОЙ компании он стоит, раз пространство теперь берётся из шапки.
   Чернила меряются к СВОЕЙ подложке (канон contrast-runtime-audit): подложка — тонкая
   заливка от var(--text), поэтому на ней берём var(--muted), а не акцент. */
.pt-space {
  display: inline-flex; align-items: center; max-width: 220px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: var(--muted);
  padding: 2px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--text) 6%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--text) 10%, transparent);
}
.pt-space.hidden { display: none; }

/* «Сохранено» — тихий ответ инлайн-правки: ни кнопки «Сохранить», ни модалки. */
.pt-saved {
  display: inline-flex; align-items: center; gap: 5px; font-size: 12px; color: var(--ok);
  opacity: 0; transform: translateY(-2px); transition: opacity .16s ease, transform .16s ease;
  pointer-events: none; white-space: nowrap;
}
.pt-saved.on { opacity: 1; transform: none; }
.pt-saved .ic { width: 14px; height: 14px; }
/* 🔴 13.10.2026 (ревью прода, телефон): прозрачная в покое подпись держала 84 px, и название
   резалось до «Партнё…» при видимой пустоте — подпись уступает место первой */
.pt-saved { flex: 0 1000 auto; min-width: 0; overflow: hidden; }
.pt-saved > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Тело: список | карточка. Скролл у колонок, а не у общего блока. */
.tw-body.pt-body { display: flex; min-height: 0; overflow: hidden; position: relative; }
#partnersOverlay .pt-main { flex: 1 1 auto; min-width: 0; overflow-y: auto; overscroll-behavior: contain; padding: 14px 16px 28px; }
#partnersOverlay .pt-side {
  flex: 0 0 380px; min-width: 0; display: flex; flex-direction: column;
  border-left: 1px solid var(--line); background: var(--panel); overflow: hidden;
}
#partnersOverlay .pt-side.hidden { display: none; }
.pt-side-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--line); }
.pt-side-t { flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 650; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pt-side-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 14px; display: flex; flex-direction: column; gap: 14px; }
/* В ящике карточки строка живёт в 380 px: подпись держим ОДНОЙ строкой с многоточием,
   иначе «ур. 2 · код · ставка · самозанятый · привёл …» разваливается на три этажа. */
#partnersOverlay .pt-side .pt-row-s { flex-wrap: nowrap; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: block; }
#partnersOverlay .pt-side .pt-row-s > * { display: inline; }
/* Кнопка рядом с полем — значок и подпись в строку (CLIE-425: поле и действие на разных строках,
   но сама кнопка не столбик). */
#partnersOverlay .pt-fld-acts .ghost { display: inline-flex; align-items: center; gap: 6px; }
.pt-side-danger { display: flex; gap: 8px; flex-wrap: wrap; padding-top: 4px; border-top: 1px solid var(--line); margin-top: 2px; }
.pt-bad, .pt-bad .ic { color: var(--danger); }

/* Карточка состояния программы */
.pt-card {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px 16px; box-shadow: var(--shadow-1);
}
.pt-prog-l { flex: 1 1 260px; min-width: 0; }
.pt-prog-t { font-size: 15px; font-weight: 650; color: var(--text); }
.pt-prog-h { margin-top: 4px; font-size: 12.5px; color: var(--muted); line-height: 1.45; }
.pt-prog-r { display: flex; align-items: center; gap: 12px; }

/* Плитки воронки. Ячейка без источника выглядит ЖДУЩЕЙ, а не пустой. */
.pt-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 10px; margin-top: 14px; }
.pt-tile { background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px; min-width: 0; }
.pt-tile-v { font-size: 21px; font-weight: 680; color: var(--text); letter-spacing: -.01em; }
.pt-tile-t { margin-top: 2px; font-size: 12.5px; color: var(--text-secondary); }
.pt-tile-s { margin-top: 2px; font-size: 11.5px; color: var(--muted); min-height: 14px; }
.pt-tile-wait .pt-tile-v { color: var(--muted); font-weight: 600; }

.pt-sec { margin-top: 18px; }
.pt-sec-h { font-size: 11.5px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 8px; }
.pt-sec2 { background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px; padding: 12px 14px; }
.pt-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 14px; align-items: start; }
.pt-col { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.pt-ver { font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--muted); }
.pt-mini { margin-top: 8px; font-size: 11.5px; color: var(--muted); line-height: 1.45; }
.pt-note { margin-top: 10px; font-size: 11.5px; color: var(--muted); }

/* Строка списка: все данные в строке, наведение мягкое, выбранная — подложкой. */
.pt-rows { display: flex; flex-direction: column; gap: 6px; }
.pt-rows-tight { gap: 4px; }
/* 🔴 СТРОКА С АДРЕСОМ (цель · приглашение · ссылка кабинета). Замер в живом браузере 15.09.2026:
   колонка настроек 423px, строка 393px, а заголовок цели ужат до 143px и обрезан многоточием —
   «ЧР3-Заявка с сайт…». Имя человек ЧИТАЕТ, значит оно переносится; адрес человек НЕ читает, он
   его КОПИРУЕТ кнопкой рядом — адрес живёт в одну строку с многоточием и не ломает карточку на
   три этажа. Модификатор на КОНТЕЙНЕРЕ: свойство у строки-с-адресом, а не у каждого списка. */
.pt-rows-addr .pt-row-t { white-space: normal; overflow: visible; text-overflow: clip; }
.pt-rows-addr .pt-row-s.pk-url { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.pt-row {
  display: flex; align-items: center; gap: 10px; min-width: 0; cursor: pointer;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 9px 12px; transition: border-color .13s ease, background .13s ease, transform .13s ease;
}
.pt-row:hover { border-color: var(--line-strong); background: var(--panel-3); }
.pt-row[data-on="1"] { border-color: color-mix(in srgb, var(--primary) 40%, transparent); background: var(--sel); }
.pt-row-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pt-row-t { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pt-row-s { font-size: 11.5px; color: var(--muted); display: flex; align-items: center; gap: 5px; flex-wrap: wrap; }
.pt-row-m { flex: 0 0 auto; display: flex; align-items: center; gap: 8px; }
.pt-row-go { flex: 0 0 auto; display: flex; align-items: center; gap: 6px; color: var(--muted); }
.pt-row-go .ic { width: 16px; height: 16px; }
.pt-sep { opacity: .45; }
.pt-code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; color: var(--primary-2); }
.pt-own { color: var(--primary-2); font-weight: 600; }
.pt-amt { font-size: 13.5px; font-weight: 650; color: var(--text); font-variant-numeric: tabular-nums; }
.pt-why { font-size: 11px; color: var(--text-dim); }
.pt-hit { border-color: color-mix(in srgb, var(--warn) 45%, transparent); }

/* Акцент статуса: точка + слово (читается и в ч/б), мягкая подложка и кольцо. */
.pt-tag {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600;
  padding: 3px 9px; border-radius: 999px; white-space: nowrap;
}
.pt-dot { width: 6px; height: 6px; border-radius: 50%; flex: 0 0 auto; }
.pt-tag-ok { background: color-mix(in srgb, var(--ok) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 24%, transparent); color: var(--ok); }
.pt-tag-wait { background: color-mix(in srgb, var(--warn) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 24%, transparent); color: var(--warn); }
.pt-tag-bad { background: color-mix(in srgb, var(--danger) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 24%, transparent); color: var(--danger); }
.pt-dot-ok { background: var(--ok); }
.pt-dot-wait { background: var(--warn); }
.pt-dot-bad { background: var(--danger); }

/* Хваталка — ЯВНАЯ мишень, проявляется по наведению на строку (CRMC-685·4). */
.pt-grip { flex: 0 0 auto; display: flex; align-items: center; color: var(--muted); cursor: grab; opacity: 0; transition: opacity .12s ease; }
.pt-grip .ic { width: 15px; height: 15px; }
.pt-row:hover .pt-grip, .pt-lvl:hover .pt-grip, .pt-grip:focus-visible { opacity: 1; }
.pt-reordering .pt-row, .pt-reordering .pt-lvl { transition: transform .16s cubic-bezier(.2,.8,.3,1); }
.pt-lift { box-shadow: var(--shadow-3); border-color: var(--line-strong); transform: scale(1.005); cursor: grabbing; }

/* Дерево «кто кого привёл»: раскрываемые уровни в ТОМ ЖЕ виде. Направляющая — хэйрлайн
   1px (не рейка-акцент): она рисует связь, а не важность. */
.pt-tree { display: flex; flex-direction: column; gap: 6px; }
.pt-node { display: flex; flex-direction: column; gap: 6px; }
.pt-kids { display: flex; flex-direction: column; gap: 6px; margin-left: 18px; padding-left: 12px; border-left: 1px solid var(--line); }
.pt-kids.hidden { display: none; }
.pt-exp {
  flex: 0 0 auto; width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: transparent; color: var(--muted); cursor: pointer; border-radius: 7px;
  transition: transform .16s cubic-bezier(.3,.8,.4,1), background .12s ease;
}
.pt-exp:hover { background: var(--panel-3); color: var(--text); }
.pt-exp.on { transform: rotate(90deg); }
.pt-exp-none { width: 22px; height: 22px; display: inline-block; }
.pt-exp .ic { width: 15px; height: 15px; }

/* Поля карточки и настроек — правка ИНЛАЙН по клику, без карандашей и «Сохранить». */
.pt-fld { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.pt-fld-t { font-size: 11.5px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; }
.pt-fld-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.pt-val { font-size: 13.5px; color: var(--text); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pt-val-mute { color: var(--muted); }
.pt-ro { width: 100%; box-sizing: border-box; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.pt-inp-wrap { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.pt-inp {
  min-height: var(--ctl-h); border-radius: var(--ctl-r); font-size: var(--ctl-fs);
  background: var(--input-bg); border: 1px solid var(--line); color: var(--text);
  padding: 0 8px; width: 104px; text-align: right; font-variant-numeric: tabular-nums;
}
.pt-inp-wide { width: 100%; box-sizing: border-box; text-align: left; }
.pt-inp:hover { border-color: var(--line-strong); }
.pt-inp:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 3px var(--sel); }
.pt-unit { font-size: 12px; color: var(--muted); }
.pt-area {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 120px;
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 11px;
  color: var(--text); font: inherit; font-size: 13px; line-height: 1.5; padding: 10px 12px;
}
.pt-area:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 3px var(--sel); }
.pt-rate { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.pt-rate-sw { display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--text); cursor: pointer; }
.pt-parent { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.pt-ck { flex: 0 0 auto; display: inline-flex; align-items: center; }
.pt-a { text-decoration: none; }
/* Обёртка канонического сегмента: только место, свою дорожку с пилюлей НЕ рисуем. */
.pt-choice { flex: 0 0 auto; max-width: 100%; }

.pt-set-row { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line); min-width: 0; }
.pt-set-row:last-child { border-bottom: 0; }
.pt-set-tx { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pt-set-t { font-size: 13px; color: var(--text); }
.pt-set-h { font-size: 11.5px; color: var(--muted); line-height: 1.4; }

/* Уровни и ставки: строка уровня с хваталкой, поля правятся на месте. */
.pt-levels { display: flex; flex-direction: column; gap: 8px; }
.pt-lvl {
  display: flex; align-items: flex-end; gap: 12px; flex-wrap: wrap;
  background: var(--panel-3); border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px;
}
.pt-lvl-n { flex: 0 0 auto; font-size: 12.5px; font-weight: 650; color: var(--text); align-self: center; }
.pt-lvl-f { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pt-lvl-base { flex: 1 1 100%; min-width: 0; }   /* «Сумма сделки · Факт оплаты · Вознаграждение ниже» —
   три длинные подписи: в карточке уровня им нужна СВОЯ строка, иначе последняя срезается
   (канон label-fit: подпись не режем; переполнение дальше разруливает ccSegFit — .cc-seg уже в SEG_FIT_SEL). */
.pt-lvl-base .cc-seg { max-width: 100%; }

/* Массовое действие: сумма НАЗВАНА до нажатия, а не после. */
.pt-bulk {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 9px 12px; font-size: 12.5px; color: var(--text);
}
.pt-bulk.on { border-color: color-mix(in srgb, var(--primary) 34%, transparent); background: var(--sel); }

/* Состояния: загрузка · ошибка с выходом · «часть ещё не приехала» · пусто. */
.pt-state { display: flex; align-items: center; gap: 10px; padding: 22px 4px; color: var(--muted); font-size: 13px; }
.pt-state-bad { align-items: flex-start; color: var(--text); }
.pt-state-bad .ic, .pt-refuse > .ic { width: 18px; height: 18px; color: var(--danger); flex: 0 0 auto; margin-top: 1px; }
.pt-state-t { margin-bottom: 8px; }
/* Отказ «Людей и времени» (.tw-empty.pt-refuse) — та же дверь, что у «Партнёров», но по центру пустого экрана. */
.pt-refuse .pt-fld-acts { justify-content: center; }
.pt-spin {
  width: 15px; height: 15px; flex: 0 0 auto; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--primary); animation: pt-spin .7s linear infinite;
}
@keyframes pt-spin { to { transform: rotate(360deg); } }
.pt-soon {
  display: flex; align-items: flex-start; gap: 10px;
  background: color-mix(in srgb, var(--warn) 8%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 22%, transparent);
  border-radius: 12px; padding: 12px 14px;
}
.pt-soon > .ic { width: 17px; height: 17px; color: var(--warn); flex: 0 0 auto; margin-top: 1px; }
.pt-soon-tx { min-width: 0; }
.pt-soon-t { font-size: 13px; font-weight: 600; color: var(--text); }
.pt-soon-h { margin: 4px 0 8px; font-size: 12px; color: var(--muted); line-height: 1.5; }
.pt-empty { max-width: 520px; margin: 48px auto; text-align: center; }
.pt-empty > .ic { width: 30px; height: 30px; color: var(--muted); opacity: .75; }
.pt-empty-t { margin-top: 10px; font-size: 16px; font-weight: 650; color: var(--text); }
.pt-empty-h { margin-top: 6px; font-size: 13px; color: var(--muted); line-height: 1.55; }
.pt-empty-a { margin-top: 14px; display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.pt-empty-a > * { flex: 0 0 auto; }   /* кнопка по своей подписи, а не во всю колонку */

/* ══════════════════════════════════════════════════════════════════════════════
   🏠 «МОЙ КАБИНЕТ» ПАРТНЁРА (CLIE-1082 · Ч5/7) — ВИД в том же #partnersOverlay.
   Своих плиток, тегов, состояний и кнопок здесь НЕТ: всё общее берётся у соседа
   (.pt-tile · .pt-tag · .pt-row · .pt-fld · .pt-state · .pt-empty). Ниже — только то,
   чего у него не было: карточка материала, баннер и первый экран «стать партнёром».
   Цвета — ТОЛЬКО токенами темы: у прибитого цвета нет тёмной темы.
   ══════════════════════════════════════════════════════════════════════════════ */
.pk-head { align-items: flex-start; }
.pk-spon { flex: 0 0 auto; font-size: 12px; color: var(--muted); }
.pk-spon b { color: var(--text); font-weight: 600; }

/* 🔴 ПОЛЕ + КНОПКИ НА ДВУХ СТРОКАХ (канон field-plus-button): поле во всю ширину,
   кнопки строкой ниже. Правило живёт КЛАССОМ, а не привычкой автора разметки. */
.pk-link { gap: 8px; margin-bottom: 4px; }
.pk-link .pt-ro { font-size: 12.5px; }
.pk-btn { display: inline-flex; align-items: center; gap: 6px; }
.pk-btn .ic, .pt-fld-acts .primary .ic { width: 15px; height: 15px; }

.pk-hint {
  font-size: 12.5px; color: var(--text-secondary); line-height: 1.5;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 10px 13px; margin-bottom: 12px;
}
.pk-hint-s { font-size: 11.5px; color: var(--muted); line-height: 1.45; }

/* Условия вознаграждения: фразы считает СЕРВЕР, здесь только их место. */
.pk-terms-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 10px; }
.pk-terms-grid-mid { max-width: 680px; margin: 16px auto 4px; text-align: left; }
.pk-term { background: var(--panel-2); border: 1px solid var(--line); border-radius: 12px; padding: 11px 13px; min-width: 0; }
.pk-term-t { font-size: 11.5px; color: var(--text-dim); text-transform: uppercase; letter-spacing: .03em; font-weight: 650; }
.pk-term-v { margin-top: 3px; font-size: 15px; font-weight: 650; color: var(--text); }
.pk-term-h { margin-top: 3px; font-size: 11.5px; color: var(--muted); line-height: 1.45; }

.pk-sec-h {
  display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px;
  font-size: 11.5px; font-weight: 650; color: var(--text-dim); text-transform: uppercase; letter-spacing: .04em;
}
.pk-terms { max-width: 760px; }
.pk-terms-text {
  margin: 14px 0; padding: 14px 16px; font-size: 13px; line-height: 1.6; color: var(--text);
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px;
  max-height: 46vh; overflow-y: auto; overscroll-behavior: contain;
}

/* Первый экран: ОДНА кнопка и две строки, а не сетка из нулей (канон progressive-disclosure). */
.pk-hero { max-width: 620px; margin: 40px auto; text-align: center; }
.pk-hero-ic .ic { width: 32px; height: 32px; color: var(--primary-2); }
.pk-hero-t { margin-top: 10px; font-size: 19px; font-weight: 680; color: var(--text); letter-spacing: -.01em; }
.pk-hero-h { margin-top: 8px; font-size: 13.5px; color: var(--muted); line-height: 1.55; }
.pk-hero-a { margin-top: 18px; display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
.pk-hero-a > * { flex: 0 0 auto; }

/* Генератор кодов. Форма приходит по действию и не отбирает экран заранее. */
.pk-new-row { margin-bottom: 10px; }
.pk-form {
  display: flex; flex-direction: column; gap: 12px; margin-bottom: 14px;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px; padding: 13px 15px;
}
.pk-form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 12px; }
.pk-spin { margin-right: 7px; vertical-align: -2px; }
.pk-off { opacity: .62; }
.pk-url { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px; color: var(--muted); }
.pk-row-acts { gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.pk-lock { display: inline-flex; vertical-align: -2px; margin-left: 5px; color: var(--muted); }
.pk-lock .ic { width: 13px; height: 13px; }

/* Материалы: карточка канала с готовым текстом. */
.pk-mats { display: grid; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); gap: 14px; align-items: start; }
.pk-mat { background: var(--panel-2); border: 1px solid var(--line); border-radius: 14px; padding: 13px 15px; min-width: 0; }
.pk-mat-h { display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; margin-bottom: 9px; }
.pk-mat-ch {
  flex: 0 0 auto; font-size: 11px; font-weight: 650; letter-spacing: .03em; text-transform: uppercase;
  color: var(--primary-2); background: color-mix(in srgb, var(--primary) 11%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent);
  border-radius: 999px; padding: 3px 9px;
}
.pk-mat-t { font-size: 13px; font-weight: 600; color: var(--text); min-width: 0; }
.pk-mat-subj { margin-bottom: 10px; }
.pk-mat-body {
  font-size: 13px; line-height: 1.55; color: var(--text); white-space: normal;
  background: var(--panel-3); border: 1px solid var(--line); border-radius: 11px;
  padding: 11px 13px; margin-bottom: 10px;
}
.pk-mat-banner { grid-column: 1 / -1; }
.pk-ban {
  margin: 10px 0; display: flex; justify-content: center;
  background: var(--panel-3); border: 1px solid var(--line); border-radius: 12px; padding: 12px;
}
.pk-ban svg { max-width: 100%; max-height: 340px; height: auto; border-radius: 8px; }

/* Узко — карточка партнёра становится полноэкранным слоем: колонок на 900px нет. */
@media (max-width: 900px) {
  #partnersOverlay .pt-side { position: absolute; inset: 0; flex: 1 1 auto; border-left: 0; z-index: 3; }
  .pt-grip { opacity: 1; }
  .pk-mats { grid-template-columns: 1fr; }
}
/* «Пригласить» звонка двоих живёт в доке (#caInviteBtn, как #gcInviteBtn конференции) — своей вёрстки у него нет. */
#ciNotice { color: var(--muted); font-size: 13px; line-height: 1.45; }

/* 🧩 SELFTASK_MECH (0380): бюджеты самопостановки в «Работах ИИ» — обе темы через токены */
.aiw-self { margin-top: 10px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface-2); }
.aiw-self-h { font-weight: 600; font-size: 13px; margin-bottom: 8px; }
.aiw-self-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 8px 12px; }
.aiw-self-f { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12.5px; color: var(--muted); }
.aiw-self-f .aiw-input { width: 64px; text-align: right; }
.aiw-self-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; flex-wrap: wrap; }

/* 🧭 STAGE_MECH (0382): фаза исполнения ИИ в шторке задачи — объяснение сверху, техника под ним */
.tip-stage .tip-prop-v { display: block; }
/* 🧾 Расход ИИ в карточке задачи (14.10.2026): строка-итог + раскрытие «На что ушли».
   Полосы — общие .dash-pf-*; своих цветов нет — только токены темы. */
.tip-spend { align-items: flex-start; }   /* подпись — у начала длинного раскрытия, а не посреди него */
.tip-spend .tip-prop-v { display: block; min-width: 0; }
.tip-spend-say { font-size: 12.5px; color: var(--text); line-height: 1.35; }
.tip-spend-more { margin-top: 6px; }
.tip-spend-more > summary { cursor: pointer; font-size: 12px; color: var(--primary-2, var(--primary)); list-style: none; user-select: none; }
.tip-spend-more > summary::-webkit-details-marker { display: none; }
.tip-spend-more > summary::before { content: "▸ "; }
.tip-spend-more[open] > summary::before { content: "▾ "; }
.tip-spend-more .dash-pf-row { margin: 0 0 8px; }
.tip-spend-more .dash-pf-lab { font-size: 11.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.tip-spend-more .dash-pf-num { font-size: 11.5px; }
.tip-spend-sec { font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 600; margin: 10px 0 6px; }
.tip-spend-li { font-size: 12px; color: var(--text); margin: 0 0 4px; overflow-wrap: anywhere; }
.tip-stage-say { font-weight: 600; margin-bottom: 6px; }
.tip-stage-t { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; color: var(--muted); padding: 1px 0; }
.tip-stage-t b { color: var(--fg); font-weight: 600; }
.tip-stage-more { margin-top: 6px; }
.tip-stage-more summary { cursor: pointer; font-size: 12.5px; color: var(--muted); }
.tip-stage-tech { margin-top: 4px; display: grid; gap: 2px; font-size: 12px; color: var(--muted); }
.tip-stage-tech > div { display: flex; justify-content: space-between; gap: 10px; }
.tip-stage-tech code { color: var(--fg); word-break: break-all; text-align: right; }

/* 🔴🔴 ДВЕРЬ: ПОДСКАЗКА ПУСТОГО ПОЛЯ НЕ ДВИГАЕТ КАРЕТКУ (CLIE-1181)
   Владелец 16.09.2026: «курсор начал не с начала быть» — в пустом композере каретка
   стояла ПОСЛЕ слова «Сообщение…» (замер прибором tools/shots/clie1181-caret.js на живом
   проде: смещение 90.2 px вместо 0).
   ПРИЧИНА КЛАССА, а не одного поля: у div-полей нет `::placeholder`, поэтому подсказка
   везде рисуется как `::before { content: attr(data-ph) }` — а это НАСТОЯЩЕЕ содержимое
   строки, и каретка честно встаёт ЗА ним. Так сделаны все 18 полей продукта (14 правил в
   этом файле + 4 в стилях, которые вклеивает app.js: .crmb-desc-edit, .cc-cv-edit,
   .brd-ed, .gm-name.editable).
   ЛЕЧЕНИЕ ОДНО НА ВСЕХ: подсказка выводится ИЗ ПОТОКА (`position: absolute`). Смещений
   нет — у абсолютного бокса с `auto` по всем сторонам место СТАТИЧЕСКОЕ, ровно там, где
   он стоял бы в потоке: подсказка не двигается ни на пиксель, а каретка встаёт в начало.
   `position: relative` у поля нужен, чтобы подсказка осталась ВНУТРИ него (обрезка
   `overflow` и `max-width` считались бы иначе от далёкого предка).
   🔴 Заводишь новое поле с подсказкой — бери `data-ph`, и дверь накроет его сама;
   НЕ пиши подсказку инлайновым ::before мимо этого атрибута. */
[data-ph] { position: relative; }
/* Показывают подсказку правила конкретных полей через content. Геометрия одинакова
   при любом содержимом: общий :empty здесь заставлял Chromium пересчитывать стили
   страницы на каждой букве, в том числе вместе с несвязанными :has(...:empty). */
[data-ph]::before { position: absolute; max-width: 100%; pointer-events: none; }
/* 🕐 F09: подпись «наблюдение устарело» рядом с фазой — фаза перестаёт выдаваться за «сейчас» */
.tip-stage-stale { font-weight: 400; font-size: 12px; color: var(--warn, var(--muted)); }

/* ═════════ 🖼 ЗАГЛУШКА «КАРТИНКИ БОЛЬШЕ НЕТ» (CLIE-1580) ═════════
   Одна коробка на весь продукт: ставит её единственный перехватчик `ccImgGone` (app.js).
   Обе темы берутся САМИ — цвета только токенами (--panel-2/--line/--muted), ни одного
   прибитого #hex: у прибитого цвета нет темы (канон `theme-contrast-runtime`). */
.cc-img-gone {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; box-sizing: border-box; padding: 8px 10px;
  min-width: 28px; min-height: 28px; max-width: 100%;
  background: var(--panel-2); color: var(--muted);
  border: 1px dashed var(--line-strong); border-radius: 10px;
  text-align: center; overflow: hidden; vertical-align: middle;
}
.cc-img-gone > svg { width: 22px; height: 22px; flex: 0 0 auto; opacity: .85; }
.cc-img-gone > b {
  font-weight: 500; font-size: 12px; line-height: 1.25; color: var(--muted);
  /* Длинные слова не рвут коробку: заглушка обязана быть аккуратной и в плитке 120px. */
  overflow-wrap: anywhere;
}
/* Нет сети — другое состояние и другой тон: это «попробуйте позже», а не «файла нет». */
.cc-img-gone.off { border-style: solid; }

/* Invoice composer: shared modal frame, theme tokens, scrollable body and pinned actions. */
.inv-compose { display:flex; flex-direction:column; gap:14px; color:var(--text); }
.inv-compose p { margin:0; }
.inv-context,.inv-totals { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:8px 16px; }
.inv-context { padding:12px 14px; border:1px solid var(--line); border-radius:12px; background:var(--panel); }
.inv-context span,.inv-note,.inv-seller,.inv-totals>span { font-size:12px; line-height:1.5; color:var(--muted); }
.inv-context strong,.inv-totals strong { font-size:16px; font-variant-numeric:tabular-nums; }
.inv-group { display:flex; flex-direction:column; gap:10px; padding-top:14px; border-top:1px solid var(--line); }
.inv-group h3 { font-size:14px; font-weight:650; margin:0 0 2px; }
.inv-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px 12px; }
.inv-field { display:flex; flex-direction:column; gap:5px; min-width:0; }
.inv-field>span { font-size:11px; color:var(--muted); }
.inv-field .pm-input { box-sizing:border-box; min-width:0; min-height:40px; font-size:13px; }
.inv-account { display:flex; align-items:center; justify-content:space-between; gap:12px; width:100%; padding:12px; border:1px solid var(--line); border-radius:10px; color:var(--text); background:var(--panel); text-align:left; cursor:pointer; }
.inv-account span { overflow-wrap:anywhere; }
.inv-account svg,.inv-remove svg { width:18px; height:18px; flex:none; }
.inv-actions { display:flex; flex-wrap:wrap; gap:8px; }
.inv-line { display:grid; grid-template-columns:minmax(120px,1fr) 68px 110px 104px 32px; align-items:end; gap:8px; margin-bottom:10px; }
.inv-remove { height:40px; padding:0; background:transparent; color:var(--muted); border:1px solid var(--line); border-radius:8px; cursor:pointer; }
.inv-remove:hover { color:var(--text); background:var(--panel); }
.inv-compose .dc-a { align-self:flex-start; }
.inv-totals { padding:12px 0 0; }
.inv-error { color:var(--danger,#d44f5e); font-size:12px; line-height:1.5; }
.inv-error:empty { display:none; }
.inv-totals p { flex-basis:100%; }
/* ✏️ CRMC-1237 · Жизнь выставленного счёта: путь исправления словами (`.inv-fixsay`), цепочка
   «взамен / заменён» ссылкой, кнопки жизни под чертой, оплаты счёта с отменой ошибочной. Токены
   общие — одинаково живо в светлой и тёмной теме; акцент — подложка и кольцо, без левых реек. */
.inv-fixsay { padding:10px 12px; border-radius:10px; font-size:12.5px; line-height:1.5; color:var(--text); background:color-mix(in srgb,var(--primary-2) 10%,var(--panel)); box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--primary-2) 22%,transparent); }
.inv-compose .dc-a { gap:6px; }
.inv-compose .dc-a svg { width:14px; height:14px; flex:none; }
.inv-life { padding-top:12px; border-top:1px solid var(--line); }
.inv-link { border:0; background:none; padding:0; font:inherit; color:var(--primary-2); cursor:pointer; text-decoration:underline; text-underline-offset:2px; }
.inv-link:hover { color:var(--text); }
.ipay-list { display:flex; flex-direction:column; gap:6px; }
.ipay-row { display:flex; align-items:center; gap:10px; padding:8px 10px; border:1px solid var(--line); border-radius:10px; background:var(--panel); }
.ipay-row.off { opacity:.62; }
.ipay-row.off .ipay-sum { text-decoration:line-through; }
.ipay-row.neg .ipay-sum { color:var(--danger,#d44f5e); }
.ipay-b { flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:2px; }
.ipay-sum { font-size:13.5px; font-weight:640; font-variant-numeric:tabular-nums; color:var(--text); }
.ipay-meta { font-size:11.5px; color:var(--muted); overflow-wrap:anywhere; }
.ipay-ext { font-size:11px; color:var(--muted); white-space:nowrap; }
.ipay-row .dc-a { flex:none; align-self:center; }
@media (max-width:600px) {
  .inv-grid { grid-template-columns:minmax(0,1fr); }
  .inv-line { grid-template-columns:minmax(50px,1fr) minmax(70px,1.3fr) minmax(90px,1.2fr) 32px; padding-bottom:12px; border-bottom:1px solid var(--line); }
  .inv-line .inv-field:first-child { grid-column:1 / -1; }
  .ipay-row { flex-wrap:wrap; }
  .ipay-ext { white-space:normal; }
}

/* 🖍 ЗВОН-604·7 · Холст пометок «только показать»: чужие пометки видны каждому, у кого на экране
   показ, без режима рисования. Он ничего не ловит — клик и указка проходят СКВОЗЬ него к показу
   (иначе в звонке 1:1 холст в .videos перехватил бы жест указки у <video>). */
.cc-ink.cc-ink-view { pointer-events: none; cursor: default; touch-action: auto; }

/* ═══════════════════════════════════════════════════════════════════════════════════════
   🗂 ДОСКИ-ВИДЫ ЗАДАЧ ПРОЕКТА (0447) — ТОЛЬКО НОВЫЕ УЗЛЫ, И ТОЛЬКО ТОКЕНАМИ.
   Сама доска, столбцы и карточки — те же `.tw-board` / `.tw-col` / `.tw-card`, что у
   остальных трёх адаптеров: своей вёрстки доски-вид не заводит. Здесь живут ровно четыре
   новых узла: переключатель вида (попап), лист шаблонов, подпись «ценности» на карточке и
   подсказка в меню вида. Никаких своих цветов — только переменные темы (канон токенов).
   ═════════════════════════════════════════════════════════════════════════════════════ */

/* Попап «Вид доски ▾» — тот же каркас, что `.tw-scope-pop`; добавляем только шапку,
   шестерёнку строки и подвал с «Новая доска». */
.tw-tb-pop .tw-tb-head { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); padding: 4px 8px 2px; }
.tw-tb-gear { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; flex: none;
  background: none; border: none; border-radius: 7px; color: var(--muted); cursor: pointer; opacity: 0; transition: opacity .12s ease; }
.tw-scope-row:hover .tw-tb-gear, .tw-tb-gear:focus-visible { opacity: 1; }
.tw-tb-gear:hover { background: var(--panel-2, var(--panel)); color: var(--text); }
.tw-tb-gear svg.ic { width: 14px; height: 14px; }
.tw-tb-new { display: flex; align-items: center; gap: 8px; width: 100%; padding: 8px 9px; border-radius: 8px; cursor: pointer;
  background: color-mix(in srgb, var(--primary) 10%, transparent); border: 1px solid color-mix(in srgb, var(--primary) 22%, var(--line));
  color: var(--text); font-size: 13px; }
.tw-tb-new:hover { background: color-mix(in srgb, var(--primary) 16%, transparent); }
.tw-tb-new svg.ic { width: 15px; height: 15px; flex: none; color: var(--primary); }
/* Срез списка досок и срез карточек — ТА ЖЕ форма `.tasks-more`, что везде в продукте;
   здесь только внешние отступы под место, где она стоит. */
.tw-tb-more { margin: 2px 0 0; }
.tw-tb-cards-more { margin: 10px 14px 16px; }

/* 🖐 ХВАТАЛКА ПОРЯДКА ВИДОВ (правило ручного порядка). Видна по наведению, курсор `grab`,
   отдельная мишень — выбор вида по клику с ней не спорит. Язык тот же, что у `.ccreq-grip`
   и `.dph-grip`: второй визуальной идиомы «тут можно тащить» в продукте нет. */
.tw-tb-grip { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 24px;
  flex: none; color: var(--muted); opacity: 0; cursor: grab; touch-action: none;
  transition: opacity 140ms ease, color 140ms ease; }
.tw-scope-row:hover .tw-tb-grip, .tw-tb-grip:focus-visible { opacity: .75; }
.tw-tb-grip:hover { color: var(--text); opacity: 1; }
.tw-tb-grip svg.ic { width: 13px; height: 13px; }
.tw-tb-reordering .tw-scope-row { transition: transform 120ms ease; }
.tw-tb-dragging { opacity: .9; box-shadow: 0 8px 22px rgba(0, 0, 0, .28); background: var(--panel-2, var(--panel)); }

/* Лист четырёх шаблонов: радио-карточки. Выбранная — акцентной подложкой и кольцом,
   как `.errfix-altbtn` (один язык акцента на весь продукт). */
.tb-tpl-list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.tb-tpl { display: flex; align-items: flex-start; gap: 10px; padding: 10px 12px; border: 1px solid var(--line);
  border-radius: 12px; cursor: pointer; background: var(--panel); }
.tb-tpl:hover { border-color: color-mix(in srgb, var(--primary) 40%, var(--line)); }
.tb-tpl.on { background: color-mix(in srgb, var(--primary) 10%, var(--panel)); border-color: color-mix(in srgb, var(--primary) 34%, var(--line));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 22%, transparent); }
.tb-tpl input { margin: 2px 0 0; accent-color: var(--primary); flex: none; }
.tb-tpl-ic { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; flex: none;
  border-radius: 8px; background: var(--panel-2, var(--bg)); color: var(--primary); }
.tb-tpl-ic svg.ic { width: 15px; height: 15px; }
.tb-tpl-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tb-tpl-txt b { font-size: 13.5px; color: var(--text); font-weight: 600; }
.tb-tpl-say { font-size: 12px; color: var(--muted); line-height: 1.35; }
.tb-priv { display: flex; align-items: center; gap: 8px; margin-top: 12px; font-size: 13px; color: var(--text); cursor: pointer; }
.tb-priv input { accent-color: var(--primary); }
/* Подсказка «доска общая — сделайте копию» в меню вида: это СЛОВА, а не контрол. */
.tb-menu-hint { padding: 8px 9px 2px; font-size: 12px; line-height: 1.4; color: var(--muted); max-width: 260px; }

/* 💰 Подпись «ценности» на карточке доски «по ценности» — вход правки, поэтому выглядит
   как остальные быстрые кнопки карточки, а не как текст. */
.tw-card-val { display: inline-flex; align-items: center; gap: 4px; max-width: 128px; padding: 2px 7px; border-radius: 7px;
  background: var(--panel-2, var(--panel)); border: 1px solid var(--line); color: var(--muted);
  font-size: 11.5px; font-variant-numeric: tabular-nums; cursor: pointer; white-space: nowrap; }
.tw-card-val:hover { color: var(--text); border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.tw-card-val svg.ic { width: 12px; height: 12px; flex: none; }
.tw-card-val span { overflow: hidden; text-overflow: ellipsis; }

/* Узкий экран: попап вида доски прижимается к краям, лист шаблонов не ужимает текст. */
@media (max-width: 640px) {
  .tw-tb-pop { left: 8px !important; right: 8px; width: auto !important; }
  .tb-tpl { padding: 9px 10px; }
  .tw-tb-cards-more { margin: 10px 10px 14px; }
}

/* ═══ 🤖🤖 AISELF_LOOK — ЗАДАЧА, КОТОРУЮ ИИ ПОСТАВИЛ СЕБЕ САМ (владелец 09.10.2026, вариант B) ═══
   «Они никак не выделяются нигде, и в итоге загрязняют пространство… Абсолютно везде».
   ОДНА декларация служебного вида на все поверхности: добавить поверхность = дописать селектор
   сюда, а не заводить свой блок. Тон — сланцевый «служебный», а НЕ фиолетовый ИИ: фиолетовый
   говорит «ИИ работает», сланцевый — «это не ваша задача». Акцент — значок + слово, подложка 13% +
   кольцо 28%, левых реек нет (канон accent). Предикат и разметка — дверь taskAiSelf/aiSelfMarkHtml/
   aiSelfFromHtml в app.js; близнец в приложении — client/lib/widgets/ai_self_look.dart. */
:root { --aiself: #8196b2; --aiself-ink: #b8c4d6; }
html[data-theme="light"] { --aiself: #475569; --aiself-ink: #475569; }
.ai-self-mark { display: inline-flex; align-items: center; gap: 5px; max-width: 100%; min-width: 0;
  font-size: 11.5px; font-weight: 500; line-height: 1.25; padding: 3px 8px; border-radius: 6px; white-space: nowrap;
  color: var(--aiself-ink); background: color-mix(in srgb, var(--aiself) 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--aiself) 28%, transparent); }
.ai-self-mark > span { overflow: hidden; text-overflow: ellipsis; }
.ai-self-mark svg.ic, .ai-self-from svg.ic, .ai-self-cnt svg.ic, .ai-self-ic svg.ic { width: 13px; height: 13px; flex: none; }
.ai-self-from { display: inline-flex; align-items: center; gap: 5px; min-width: 0; max-width: 100%; font-size: 12px; color: var(--muted); }
.ai-self-from > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.ai-self-from a { color: var(--primary-2); text-decoration: none; }
.ai-self-from a:hover { text-decoration: underline; }
.ai-self-from-row { display: flex; margin-top: 8px; min-width: 0; }
.ai-self-cnt { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px; padding: 1px 6px; border-radius: 6px;
  font-size: 11.5px; font-weight: 500; font-variant-numeric: tabular-nums;
  color: var(--aiself-ink); background: color-mix(in srgb, var(--aiself) 12%, transparent); }
.ai-self-ic { display: inline-flex; color: var(--aiself-ink); margin-right: 5px; vertical-align: -2px; }

/* служебная карточка / строка: без заливки, пунктир, серый заголовок.
   Светлые селекторы карточки — не второй вид, а вес: html[data-theme="light"] .tw-card (вес 0,2,1) перебивал
   пунктир (0,2,0) сплошной рамкой и белой заливкой — кадр 21.10: «CLIE-1847·H4·⑥» в тёмной пунктирная,
   в светлой сплошная 227,227,229. Подсветку перехода (.rel-hl) светлая не теряет. */
.tw-card.ai-self, .tw-row.ai-self, .task-row.ai-self, .wsq-row.ai-self, .wsq-wrow.ai-self,
.tdy-row.ai-self, .cc-node.ai-self, .tl-urow.ai-self,
html[data-theme="light"] .tw-card.ai-self:where(:not(.rel-hl)), html[data-theme="light"] .tasks-list .tw-card.ai-self:where(:not(.rel-hl)) {
  /* пунктир сланцевым тоном, а не хэйрлайном: замер кадра 09.10 — хэйрлайн на тёмном холсте почти не виден */
  background: transparent; border: 1px dashed color-mix(in srgb, var(--aiself) 55%, transparent); box-shadow: none; }
.tw-card.ai-self .tw-card-title, .tw-row.ai-self .tw-row-title, .task-row.ai-self .task-title,
.wsq-row.ai-self .wsq-t, .wsq-wrow.ai-self .wsq-t, .tdy-row.ai-self .tdy-t, .cc-node.ai-self .cc-node-title,
.tl-row.ai-self .tl-name, .tip-sub.ai-self .tip-rel-t, .conv-item.ai-self .conv-name, .search-task.ai-self .conv-name,
.notif-item.ai-self .notif-title {
  color: var(--muted); font-weight: 500; }
.tw-card.ai-self:hover, .cc-node.ai-self:hover, .tw-row.ai-self:hover { border-color: var(--aiself); }
/* светлая: наведение без «подъёма» html[data-theme="light"] .tw-card:hover — как в тёмной */
html[data-theme="light"] .tw-card.ai-self:hover:where(:not(.rel-hl)),
html[data-theme="light"] .tasks-list .tw-card.ai-self:hover:where(:not(.rel-hl)) { border-color: var(--aiself); box-shadow: none; }
/* 🔴 i_hubs · tasks-board-changes-label-parity-1 — у служебной карточки ИИ в ТЁМНОЙ не было ни одного
   признака «есть изменения». Тёмная говорит его подкраской 10 % и inset-кольцом `.tw-card.has-unseen`
   (style.css выше), а правило `.tw-card.ai-self` той же специфичности ниже по файлу обнуляет обе
   (background: transparent; box-shadow: none); жирность заголовка гасит `.tw-card.ai-self .tw-card-title`
   (500), точку прячет `.tw-card-title .task-changed-dot`. Кадр v1desk k_tasks: в светлой «Есть изменения»
   стоит над пунктирными карточками, в тёмной у тех же карточек — ничего, заливка = фону колонки.
   Причина — CSS, а не данные: подпись (app.js boardCardHtml, `changeCaption`) рисуется в обеих темах.
   Пунктир служебной карточки оставляем — в тёмной ей подпись светлой темы, с тем же удержанием места. */
html:not([data-theme="light"]) .tw-card.ai-self .task-change-caption {
  display: block; margin: 0 0 9px;
  font-size: 11px; line-height: 15px; font-weight: 500; letter-spacing: .1px;
  color: var(--muted); opacity: 1; transition: opacity .14s ease;
}
html:not([data-theme="light"]) .tw-card.ai-self:not(.has-unseen) .task-change-caption { opacity: 0; visibility: hidden; }
/* Нейтральные чипы служебной карточки — с кольцом, как нейтральные чипы светлой темы. Карточка прозрачна,
   под ней фон колонки --panel-2 — тот же тон, что у подложки чипа: кадр 21.10 (тёмная), ряд y=605 по
   x 380–530 однородный 34,34,40 — «5ч1м», «↳ подзадача», «Без проекта» висели голым текстом. */
.tw-card.ai-self :is(.tw-pill.tw-pill-area, .tw-pill.sub, .tw-pill.link, .tw-pill.parent, .tw-pill.chat:not(.unread), .tw-pill.tw-pill-worktime) {
  box-shadow: inset 0 0 0 1px var(--line); }
/* полоса таймлайна куска ИИ — штриховка «работа машины», а не срок человека */
.tl-bar.ai-self { background: repeating-linear-gradient(135deg,
    color-mix(in srgb, var(--aiself) 34%, var(--panel)) 0 6px, color-mix(in srgb, var(--aiself) 16%, var(--panel)) 6px 12px);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--aiself) 50%, transparent); }
.tl-bar.ai-self .tl-lbl { color: var(--aiself-ink); text-shadow: none; font-weight: 500; }
.tl-bar.ai-self .tl-fill { background: color-mix(in srgb, var(--aiself) 22%, transparent); }
/* чат куска: пунктирный кружок со значком bot вместо кольца статуса задачи */
.conv-av.ai-self-av, .thread-av.ai-self-av { box-sizing: border-box; background: transparent !important; color: var(--aiself-ink);
  border: 2px dashed color-mix(in srgb, var(--aiself) 60%, transparent); }
.conv-item.tkc-conv.ai-self .conv-av:not(.has-story)::before { display: none; }
.search-task-av.ai-self-av { border: 0; background: color-mix(in srgb, var(--aiself) 13%, var(--panel-2)) !important; }
/* уведомление о куске — тише остальных (сервер пишет его прочитанным) */
.notif-item.ai-self .notif-reason { color: var(--aiself-ink); font-weight: 500; }
/* карточка задачи: плашка «ИИ поставил эту задачу себе сам» и группа «Части ИИ» */
.tip-card.ai-self-ban { display: flex; align-items: flex-start; gap: 8px; font-size: 13px; color: var(--aiself-ink);
  background: color-mix(in srgb, var(--aiself) 10%, transparent); border: 0;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--aiself) 24%, transparent); }
.tip-card.ai-self-ban svg.ic { width: 15px; height: 15px; flex: none; margin-top: 1px; }
.tip-card.ai-self-ban a { color: var(--primary-2); font-weight: 600; text-decoration: none; }
/* «Продолжает работу части #…»: id источника — ссылка на ту часть (data-tiprel) */
.tip-card.ai-self-ban .tip-carry-src { background: none; border: 0; padding: 0; font: inherit; color: var(--primary-2); font-weight: 600; cursor: pointer; }
.td-section-h.ai-self-grp { color: var(--aiself-ink); margin-top: 12px; }
/* чип-ссылка на кусок ИИ в тексте сообщения */
.msg-ref.ai-self { color: var(--aiself-ink); background: color-mix(in srgb, var(--aiself) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--aiself) 26%, transparent); }
.tw-trash-sub .ai-self-mark, .crmb-task .ai-self-mark, .tip-sub .ai-self-mark, .tip-link .ai-self-mark,
.tip-parent .ai-self-mark, .dvai-line .ai-self-mark, .tl-urow .ai-self-mark { margin-left: 6px; flex: none; }
.tw-trash-sub .ai-self-mark { margin: 0 6px 0 0; }
.crmb-task.ai-self .crmb-task-t { color: var(--muted); }
.ea-task.ai-self { background: transparent; border: 1px dashed color-mix(in srgb, var(--aiself) 55%, transparent); box-shadow: none; }
.ea-task.ai-self .ea-task-title { color: var(--muted); font-weight: 500; }
.ea-task .ai-self-mark, .dash-at-row .ai-self-mark { margin-top: 4px; width: fit-content; }
/* строка чата куска ИИ: метка целиком, «из задачи …» уступает место и режется многоточием */
#convList .conv-item.ai-self .conv-row-proj { gap: 6px; align-items: center; }
#convList .conv-item.ai-self .conv-row-proj .ai-self-mark { flex: none; }
#convList .conv-item.ai-self .conv-row-proj .ai-self-from { flex: 1 1 auto; min-width: 0; }

/* ═══ 🖥 ПЕРЕПИСЬ ЭКРАНОВ в карточке задачи (ЛЮБЛ-1260) ═══
   Служебный чек-лист «🖥 Перепись экранов» рисуется ТАБЛИЦЕЙ: № · путь кликов · экран · кнопка · кадр.
   Человек видит ДО кода, какие экраны ИИ собрался проверить, и по колонке «кадр» — что закрыто
   кадром, что исключено с причиной, что ещё без кадра. Цвета — токенами, обе темы. */
.tip-census { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; line-height: 1.4;
  color: var(--text); table-layout: fixed; }
.tip-census th { text-align: left; font-size: 11px; font-weight: 650; letter-spacing: .02em; text-transform: uppercase;
  color: var(--muted); padding: 4px 8px 6px; border-bottom: 1px solid var(--line); white-space: nowrap; }
.tip-census td { padding: 7px 8px; vertical-align: top; border-bottom: 1px solid var(--line); word-break: break-word; }
.tip-census tr:last-child td { border-bottom: 0; }
.tip-census .tip-census-n { width: 28px; color: var(--muted); font-variant-numeric: tabular-nums; }
.tip-census .tip-census-path { width: 34%; color: var(--muted); }
.tip-census .tip-census-screen { font-weight: 600; }
.tip-census .tip-census-ctl { width: 22%; }
.tip-census .tip-census-st { width: 108px; white-space: nowrap; }
.tip-census-pill { display: inline-flex; align-items: center; gap: 4px; width: fit-content; padding: 2px 8px;
  border-radius: 999px; font-size: 11.5px; font-weight: 600; line-height: 1.4; }
.tip-census-pill svg.ic { width: 11px; height: 11px; }
.tip-census-pill.ok { color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ok) 22%, transparent); }
.tip-census-pill.skip { color: var(--muted); background: color-mix(in srgb, var(--muted) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 22%, transparent); }
.tip-census-pill.wait { color: var(--warn, #c77d00); background: color-mix(in srgb, var(--warn, #c77d00) 12%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn, #c77d00) 22%, transparent); }
.tip-census-exc { display: block; margin-top: 3px; font-size: 11.5px; color: var(--muted); white-space: normal; }
.tip-census-wrap { overflow-x: auto; }
/* подстрока «путь · кнопка» под экраном — ТОЛЬКО на узком экране, где эти колонки спрятаны (кадр CLIE-1845: на десктопе она дублировала текст) */
.tip-census-sub { display: none; }
@media (max-width: 560px) {
  .tip-census .tip-census-path, .tip-census .tip-census-ctl { display: none; }
  .tip-census-sub { display: block; margin-top: 2px; font-size: 11.5px; color: var(--muted); font-weight: 400; }
}

/* ═══ 🗂 CLIE-1842·2 — БОЛЬШАЯ ПАНЕЛЬ «ПРОЕКТЫ» ИЗ ПИЛЮЛИ ШАПКИ (#projScopePanel) ═════════════
   Возврат владельца 10.10.2026: «больше окно, заебал мельчить! Экран же большой!». Панель — это
   столбик «Проекты» во весь экран: те же данные, те же настройки (cc_projrail), крупные строки
   с монетой, счётчиками и действиями, фильтры в правой колонке. z-index 9400 — НИЖЕ .tc-pop (9600),
   чтобы меню группировки / ⚙ / «Новый проект» открывались поверх панели. */
.pp-root { position: fixed; inset: 0; z-index: 9400; display: none; }
.pp-root.open { display: block; }
.pp-backdrop { position: absolute; inset: 0; background: var(--scrim, rgba(0,0,0,.5)); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); animation: ppFade .16s ease-out; }
.pp-win {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(1320px, calc(100vw - 48px)); height: min(920px, calc(100dvh - 48px));
  display: flex; flex-direction: column; box-sizing: border-box; outline: none;
  background: var(--panel); color: var(--text); border: 1px solid var(--line);
  border-radius: 20px; box-shadow: var(--shadow-3), 0 0 0 1px rgba(0,0,0,.08);
  animation: ppPop .18s cubic-bezier(.2,.8,.2,1);
  overflow: hidden;
}
@keyframes ppFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes ppPop { from { opacity: 0; transform: translate(-50%, -50%) scale(.985); } to { opacity: 1; transform: translate(-50%, -50%) scale(1); } }
@media (prefers-reduced-motion: reduce) { .pp-backdrop, .pp-win { animation: none; } }
body.pp-open { overflow: hidden; }

/* ── шапка ── */
.pp-head { display: flex; align-items: center; gap: 14px; padding: 16px 20px 12px; border-bottom: 1px solid var(--line); flex: none; }
.pp-title { display: inline-flex; align-items: center; gap: 9px; font-size: 20px; font-weight: 700; letter-spacing: -.01em; flex: none; }
.pp-title svg.ic { width: 22px; height: 22px; color: var(--primary); }
.pp-total { font-size: 13px; font-weight: 600; color: var(--muted); background: var(--panel-2); border-radius: 999px; padding: 2px 9px; font-variant-numeric: tabular-nums; }
.pp-search { position: relative; flex: 1 1 320px; min-width: 200px; display: flex; align-items: center; }
.pp-search > svg.ic { position: absolute; left: 13px; width: 17px; height: 17px; color: var(--muted); pointer-events: none; }
.pp-search input {
  width: 100%; box-sizing: border-box; height: 42px; padding: 0 40px 0 40px; font-size: 15px;
  background: var(--input-bg); border: 1px solid var(--line); border-radius: 12px; color: var(--text); outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.pp-search input:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--glow); }
.pp-search .pp-x { position: absolute; right: 8px; width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--muted); padding: 0; }
.pp-search .pp-x:hover { background: var(--hover); color: var(--text); }
.pp-search .pp-x svg.ic { width: 14px; height: 14px; }
.pp-tools { display: flex; align-items: center; gap: 8px; flex: none; }
.pp-tool {
  display: inline-flex; align-items: center; gap: 7px; height: 38px; padding: 0 13px; font-size: 13.5px; font-weight: 600;
  background: var(--panel-2); border: 1px solid var(--line); border-radius: 11px; color: var(--text); cursor: pointer;
  transition: border-color .12s, background .12s;
}
.pp-tool:hover { border-color: var(--primary); }
.pp-tool.on { border-color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.pp-tool svg.ic { width: 16px; height: 16px; opacity: .85; }
.pp-tool.primary-ish { background: var(--acc-grad); color: #fff; border-color: transparent; box-shadow: 0 6px 16px -6px var(--glow); }
.pp-tool.primary-ish svg.ic { opacity: 1; }
.pp-close { width: 38px; height: 38px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 1px solid transparent; color: var(--muted); padding: 0; margin-left: 4px; }
.pp-close:hover { background: var(--hover); color: var(--text); border-color: transparent; }
.pp-close svg.ic { width: 18px; height: 18px; }

/* ── тело: список + правая колонка ── */
.pp-body { display: flex; flex: 1 1 auto; min-height: 0; }
.pp-list { flex: 1 1 auto; min-width: 0; overflow-y: auto; padding: 10px 14px 18px 18px; scroll-padding: 60px; }
.pp-side { flex: 0 0 300px; border-left: 1px solid var(--line); overflow-y: auto; padding: 8px 14px 18px; background: color-mix(in srgb, var(--panel-2) 55%, var(--panel)); }
.pp-side.hidden { display: none; }
.pp-side-h { display: flex; align-items: center; justify-content: space-between; font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); padding: 14px 4px 7px; }
.pp-side-h .v2-fl-clear { font-size: 11.5px; text-transform: none; letter-spacing: 0; }
.pp-radios { display: flex; flex-direction: column; gap: 2px; }
.pp-radio { display: flex; align-items: center; gap: 9px; width: 100%; background: none; border: 0; color: var(--text); text-align: left; padding: 8px 9px; border-radius: 9px; cursor: pointer; font-size: 13.5px; }
.pp-radio:hover { background: var(--hover); }
.pp-radio.on { background: color-mix(in srgb, var(--primary) 12%, transparent); font-weight: 600; }
.pp-radio svg.ic { width: 15px; height: 15px; color: var(--muted); flex: none; }
.pp-radio.on svg.ic { color: var(--primary); }
.pp-radio i { width: 15px; height: 15px; border-radius: 50%; border: 1.5px solid var(--line-strong); flex: none; box-sizing: border-box; position: relative; }
.pp-radio.on i { border-color: var(--primary); }
.pp-radio.on i::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--primary); }
.pp-side-link { display: flex; align-items: center; gap: 8px; width: 100%; background: none; border: 1px dashed var(--line); color: var(--muted); text-align: left; padding: 8px 10px; border-radius: 9px; cursor: pointer; font-size: 12.5px; margin-top: 6px; }
.pp-side-link:hover { color: var(--text); border-color: var(--primary); }
.pp-side-link svg.ic { width: 14px; height: 14px; }
.pp-filters .v2-fl-sec { border-top: 0; padding: 4px 4px 10px; }
.pp-filters .v2-fl-lbl { margin-bottom: 6px; }

/* ── секции ── */
.pp-sec {
  display: flex; align-items: center; gap: 8px; margin: 14px 4px 6px; padding: 4px 6px; border-radius: 8px;
  font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); cursor: pointer; user-select: none;
}
.pp-sec:hover { background: var(--hover); }
.pp-sec .psec-caret { display: inline-flex; transition: transform .14s; }
.pp-sec .psec-caret svg.ic { width: 14px; height: 14px; }
.pp-sec.collapsed .psec-caret { transform: rotate(-90deg); }
.pp-sec .psec-swatch { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.pp-sec-ic { display: inline-flex; color: var(--warning); }
.pp-sec-ic svg.ic { width: 14px; height: 14px; }
.pp-sec-n { font-weight: 600; font-variant-numeric: tabular-nums; opacity: .8; }
.pp-sec-hint { margin-left: 6px; font-weight: 500; text-transform: none; letter-spacing: 0; opacity: .75; }
.pp-sec.freq { color: var(--text); }

/* ── строки ── */
.pp-row {
  position: relative; display: flex; align-items: center; gap: 12px;
  min-height: 56px; padding: 8px 10px 8px 10px; margin: 2px 0; border-radius: 13px;
  border: 1px solid transparent; cursor: pointer; color: var(--text);
  transition: background .12s, border-color .12s, box-shadow .12s;
}
.pp-row.sub { margin-left: calc(var(--pdepth, 1) * 26px); }
.pp-row:hover, .pp-row.kb { background: var(--panel-2); }
.pp-row.kb { box-shadow: inset 0 0 0 1.5px var(--primary); }
.pp-row.on { background: color-mix(in srgb, var(--primary) 11%, transparent); border-color: color-mix(in srgb, var(--primary) 32%, transparent); }
.pp-row.on:hover { background: color-mix(in srgb, var(--primary) 16%, transparent); }
.pp-row.archived { opacity: .55; }
.pp-row.archived:hover, .pp-row.archived.on { opacity: .9; }
.pp-row.notwork { opacity: .72; }
.pp-row.notwork:hover, .pp-row.notwork.on { opacity: 1; }
.pp-chk {
  width: 22px; height: 22px; border-radius: 7px; flex: none; box-sizing: border-box;
  border: 1.5px solid var(--line-strong); background: var(--input-bg);
  display: inline-flex; align-items: center; justify-content: center; color: transparent;
  transition: background .12s, border-color .12s, color .12s;
}
.pp-chk svg.ic { width: 14px; height: 14px; stroke-width: 3; }
.pp-row:hover .pp-chk { border-color: var(--primary); }
.pp-row.on .pp-chk { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; }
.pp-coin {
  position: relative; width: 38px; height: 38px; border-radius: 11px; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 15px; font-weight: 700; line-height: 1; background: var(--acc-grad); color: #fff;
  box-shadow: 0 4px 12px -6px var(--glow);
}
.pp-coin svg.ic { width: 18px; height: 18px; }
.pp-coin.grad { background: linear-gradient(135deg, #5b8def, var(--cm-7c74dc, #7c74dc)); }
.pp-coin.dash { background: transparent; color: var(--muted); box-shadow: none; border: 1.5px dashed var(--line-strong); }
.pp-coin .cc-timer-pip { right: -4px; bottom: -4px; border-color: var(--panel); }
.pp-branch { width: 24px; height: 24px; flex: none; display: inline-flex; align-items: center; justify-content: center; background: transparent; border: 0; color: var(--muted); border-radius: 6px; padding: 0; margin-left: -6px; transition: transform .14s; }
.pp-branch:hover { background: var(--hover); color: var(--text); }
.pp-branch.collapsed { transform: rotate(-90deg); }
.pp-branch svg.ic { width: 14px; height: 14px; }
.pp-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pp-name { font-size: 15px; font-weight: 600; line-height: 1.25; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pp-note { color: var(--muted); font-weight: 500; }
.pp-sub { font-size: 12.5px; color: var(--muted); line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: flex; align-items: center; gap: 4px; }
.pp-lbl { width: 8px; height: 8px; border-radius: 50%; background: var(--lc, var(--muted)); display: inline-block; margin-left: 2px; }
.pp-stats { display: inline-flex; align-items: center; gap: 6px; flex: none; margin-left: auto; }
.pp-stat {
  display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 9px; border-radius: 8px;
  font-size: 12.5px; font-weight: 600; color: var(--muted); background: var(--panel-2); border: 1px solid var(--line);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.pp-stat svg.ic { width: 13px; height: 13px; }
.pp-stat b { font-weight: 700; color: var(--text); }
.pp-stat.zero { opacity: .55; }
.pp-stat.zero b { color: var(--muted); }
.pp-stat.wait { color: var(--warning); background: var(--warning-soft); border-color: color-mix(in srgb, var(--warning) 35%, transparent); }
.pp-stat.wait b { color: var(--warning); }
.pp-stat.chats.unread { color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); border-color: color-mix(in srgb, var(--primary) 35%, transparent); }
.pp-stat.chats.unread b { color: var(--primary); }
.pp-row.on .pp-stat { background: var(--panel); }
.pp-acts { display: inline-flex; align-items: center; gap: 4px; flex: none; opacity: 0; transition: opacity .12s; }
.pp-row:hover .pp-acts, .pp-row.kb .pp-acts, .pp-row:focus-within .pp-acts { opacity: 1; }
.pp-act {
  display: inline-flex; align-items: center; gap: 5px; height: 30px; padding: 0 10px; border-radius: 9px;
  font-size: 12.5px; font-weight: 600; color: var(--text); background: var(--panel); border: 1px solid var(--line); cursor: pointer;
}
.pp-act:hover { border-color: var(--primary); color: var(--primary); }
.pp-act svg.ic { width: 14px; height: 14px; }
/* якорь ветки: имя родителя из другого блока — тихая строка без галочки/счётчиков/действий (CLIE-627) */
.pp-row.ghost { cursor: default; min-height: 44px; opacity: .8; }
/* 🗂 CLIE-1842·3: сортировка мышью в панели — та же механика и тот же вид, что у столбика
   (.proj-item.dragging · .proj-section-title.drop-target · .co-reordering): курсор-«захват»,
   приподнятая полупрозрачная строка под курсором, секция-цель переноса тонким акцентом. */
.pp-row[draggable="true"] { cursor: grab; }
.pp-row[draggable="true"]:active { cursor: grabbing; }
.pp-list.reordering .pp-row[draggable="true"] { transition: transform .14s cubic-bezier(.2,.7,.3,1), background .12s, border-color .12s, box-shadow .12s; }
.pp-row.dragging, .pp-row.dragging:hover {
  opacity: .6; cursor: grabbing;
  background: var(--panel-2);
  border-color: color-mix(in srgb, var(--primary) 35%, transparent);
  box-shadow: 0 10px 24px -10px var(--glow);
}
.pp-sec.drop-target {
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 42%, transparent);
}
.pp-sec[draggable="true"] { cursor: grab; }
.pp-sec[draggable="true"]:active { cursor: grabbing; }
.pp-sec.dragging { opacity: .6; cursor: grabbing; background: var(--panel-2); }
/* Пока тащим компанию — соседние заголовки не «мигают» ховером под курсором (строки pointer-events
   не гасим: dragover целится в заголовок ЧЕРЕЗ строку под курсором). */
.pp-list.co-reordering .pp-sec:not(.dragging) { background: transparent; }
.pp-row.ghost:hover { background: transparent; }
.pp-row.ghost .pp-coin { width: 30px; height: 30px; font-size: 12px; border-radius: 9px; opacity: .8; }
.pp-row.ghost .pp-name { font-size: 13.5px; }
.pp-empty { padding: 36px 16px; text-align: center; color: var(--muted); font-size: 14px; display: flex; flex-direction: column; align-items: center; gap: 12px; }

/* ── подвал ── */
/* слева в подвале — место под сквозной пузырь чатов (#qcFab стоит в углу экрана поверх панели по
   реестру плавающей мебели CC_FLOAT_SEL): текст области не прячется под ним */
.pp-foot { display: flex; align-items: center; gap: 14px; padding: 12px 20px 12px 112px; border-top: 1px solid var(--line); flex: none; background: color-mix(in srgb, var(--panel-2) 55%, var(--panel)); }
.pp-foot-sel { font-size: 13.5px; color: var(--muted); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1 1 auto; }
.pp-foot-sel.on { color: var(--text); font-weight: 600; }
.pp-foot-hint { font-size: 12px; color: var(--text-dim); flex: none; }
.pp-foot-acts { display: inline-flex; gap: 8px; flex: none; }
.pp-foot-acts .primary.small { width: auto; margin: 0; }

/* ── узкий экран: панель во весь экран, колонка настроек прячется (⚙ через ту же кнопку) ── */
@media (max-width: 1100px) { .pp-side { flex-basis: 260px; } .pp-foot-hint { display: none; } }
@media (max-width: 900px) { .pp-foot { padding-left: 16px; } }
@media (max-width: 900px) {
  .pp-win { width: 100vw; height: 100dvh; border-radius: 0; border: 0; }
  .pp-side { display: none; }
  .pp-tool span { display: none; }
  .pp-tool { padding: 0 10px; }
  .pp-tool.primary-ish span { display: inline; }
  .pp-head { flex-wrap: wrap; gap: 10px; padding: 12px 14px 10px; }
  .pp-search { flex-basis: 100%; order: 3; }
  .pp-acts { opacity: 1; }
  .pp-act span { display: none; }
  .pp-act { padding: 0 8px; }
  .pp-stat.tasks { display: none; }
}
/* светлая тема: подложки тех же токенов, тени мягче */
html[data-theme="light"] .pp-win { box-shadow: var(--shadow-3); }
html[data-theme="light"] .pp-row:hover, html[data-theme="light"] .pp-row.kb { background: var(--hover); }
html[data-theme="light"] .pp-stat:where(:not(.wait)) { background: #fff; } /* CLIE-1946: «ждут» держит янтарный тинт */


/* ══════════ 🔒 НЕОПЛАЧЕННЫЕ ПРОСТРАНСТВА — ПЛАШКА ПОД ШАПКОЙ И ОКНО ОПЛАТЫ (11.10.2026) ══════════
   Владелец: «модалку большую, где всё видно и доступно объяснено… в шапке постоянно висящее
   уведомление… сделай как делает Apple». Акцент — канон `accent`: ЗНАК + СЛОВО на мягкой
   подложке (color-mix 10–15 %) с хэйрлайн-кольцом, без левых реек. Тон — один `--acc` на блок:
   замок → --danger, льгота и скорое продление → --warning; обе темы выверяют сами токены. */
.pay-bar {
  --acc: var(--danger);
  display: flex; align-items: center; gap: 10px;
  padding: 7px 16px; box-sizing: border-box;
  background: color-mix(in srgb, var(--acc) 11%, var(--panel));
  box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--acc) 26%, var(--line));
  color: var(--text); cursor: pointer; position: relative; z-index: 2;
  font-size: 13px; line-height: 1.35;
}
.pay-bar.lv-grace, .pay-bar.lv-soon { --acc: var(--warning); }
.pay-bar .pb-ico {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--acc); background: color-mix(in srgb, var(--acc) 18%, transparent);
}
.pay-bar .pb-ico svg { width: 14px; height: 14px; }
.pay-bar .pb-tx {
  flex: 1 1 auto; min-width: 0; font-weight: 560;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.pay-bar .pb-go {
  flex: none; height: var(--ctl-h, 31px); padding: 0 14px; border: 0; border-radius: var(--ctl-r, 9px);
  background: var(--acc-fill, var(--primary)); color: #fff; font-weight: 600; font-size: var(--ctl-fs, 13px);
  cursor: pointer; white-space: nowrap;
}
.pay-bar .pb-go:hover { filter: brightness(1.08); }
.pay-bar .pb-x {
  flex: none; width: 28px; height: 28px; border: 0; padding: 0; border-radius: 8px;
  background: transparent; color: var(--muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.pay-bar .pb-x:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.pay-bar .pb-x svg { width: 14px; height: 14px; }
@media (max-width: 720px) {
  .pay-bar { padding: 7px 10px; gap: 8px; font-size: 12.5px; }
  .pay-bar .pb-go { padding: 0 11px; }
}

/* Окно оплаты — ТА ЖЕ рама ccFormModal (механика окна одна на продукт), свой вид: герой по
   центру, факты списком, карточки пространств, внизу одна большая главная кнопка и «Не сейчас». */
.pm-card.paylock { width: min(520px, 96vw); border-radius: 18px; }
.pm-card.paylock .pm-body { padding: 26px 22px 6px; gap: 14px; }
.pm-card.paylock .pm-foot {
  flex-direction: column-reverse; align-items: stretch; gap: 4px;
  padding: 12px 22px 16px; border-top: 0;
}
.pm-card.paylock .pm-foot .primary {
  width: 100%; min-height: 46px; font-size: 15px; font-weight: 650; border-radius: 12px;
}
.pm-card.paylock .pm-foot .ghost {
  width: 100%; min-height: 38px; background: transparent; border: 0; box-shadow: none;
  color: var(--primary-2, var(--primary)); font-weight: 560; font-size: 14px;
}

/* 🎥 ОКНО ПЕРЕД ВХОДОМ В СОЗВОН (жалоба №5, `ccJoinCheck` в app.js) — ТА ЖЕ рама ccFormModal,
   свой вид. Сцена — видеополотно: тёмная В ОБЕИХ темах (как плитка созвона, `--gc-*` канона
   callui.css), всё остальное — токены темы. Кнопки мик/камеры — один размерный класс ряда
   (`--ctl-*`, канон control-size), круглые; «выключено» — заливка `--danger` + перечёркнутая
   иконка + СЛОВО под кнопкой (читается и в ч/б, канон акцента). */
.pm-card.cc-joincheck { border-radius: 18px; }
.pm-card.cc-joincheck .pm-body { padding: 14px 18px 8px; gap: 12px; }
.cc-joincheck .jc-stage {
  position: relative; width: 100%; aspect-ratio: 16 / 9; flex: 0 0 auto;
  border-radius: 14px; overflow: hidden; background: var(--gc-tile-off, var(--cm-14161f, #14161f));
}
.cc-joincheck .jc-stage > .gtile {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border: 0; border-radius: inherit; cursor: default;
}
.cc-joincheck .jc-bar {
  --ctl-h: 48px; --ctl-r: 50%; --ctl-fs: 12px;
  display: flex; justify-content: center; gap: 28px;
}
.cc-joincheck .jc-ctl { display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 0; }
.cc-joincheck .jc-btn {
  width: var(--ctl-h); height: var(--ctl-h); min-width: var(--ctl-h); margin: 0; padding: 0;
  border-radius: var(--ctl-r); border: 1px solid var(--line);
  background: var(--panel-2, var(--panel)); color: var(--text);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  transition: background .14s, color .14s, border-color .14s, transform .1s, opacity .14s;
}
.cc-joincheck .jc-btn:hover { background: color-mix(in srgb, var(--text) 10%, var(--panel-2, var(--panel))); }
.cc-joincheck .jc-btn:active { transform: scale(.94); }
.cc-joincheck .jc-btn:focus-visible { outline: 2px solid var(--primary-2, var(--primary)); outline-offset: 2px; }
.cc-joincheck .jc-btn svg.ic { width: 21px; height: 21px; }
.cc-joincheck .jc-btn.off { background: var(--danger); border-color: transparent; color: #fff; }
.cc-joincheck .jc-btn.off:hover { background: color-mix(in srgb, var(--danger) 86%, #000); }
/* Захват идёт (браузер спрашивает разрешение) — кнопка ЖИВАЯ, просто тише: второе нажатие
   честно передумывает (поколение в `ccJoinCheckCtl`), а не упирается в disabled. */
.cc-joincheck .jc-btn.busy { opacity: .62; }
.cc-joincheck .jc-cap { font-size: var(--ctl-fs); line-height: 1.25; color: var(--muted); text-align: center; white-space: nowrap; }
.cc-joincheck .jc-note {
  margin: 0; padding: 9px 12px; border-radius: 10px; font-size: 13px; line-height: 1.4; text-align: center;
  color: var(--text); background: color-mix(in srgb, var(--danger) 10%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 22%, transparent);
}
/* Строка «что с созвоном сейчас» (`ccJoinCheckLive`) и подсказка про эффекты (`ccJoinCheckHint`) —
   тихие подписи, не тревога: токены текста темы. Созвон закончился — это уже новость: точка-акцент
   `--warning` + слово (читается и в ч/б), без рамок и реек. */
.cc-joincheck .jc-live, .cc-joincheck .jc-hint {
  margin: 0; font-size: 13px; line-height: 1.4; text-align: center; color: var(--muted);
}
.cc-joincheck .jc-live.ended { color: var(--text); }
.cc-joincheck .jc-live.ended::before {
  content: ""; display: inline-block; width: 7px; height: 7px; margin-right: 7px; vertical-align: 1px;
  border-radius: 50%; background: var(--warning);
}
.pm-card.cc-joincheck .pm-foot { border-top: 0; padding: 8px 18px 16px; }
.pm-card.cc-joincheck .pm-foot .primary { min-height: 40px; padding: 0 20px; font-size: 14px; font-weight: 650; border-radius: 11px; }
/* 📱 Узкий экран — окно на весь экран: кадр берёт всю свободную высоту, «Присоединиться» —
   крупная кнопка внизу над полосой «домой» (safe-area), «Отмена» — под ней строкой. */
@media (max-width: 600px) {
  .pm-scrim:has(> .cc-joincheck) { padding: 0; }
  .pm-card.cc-joincheck {
    width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh;
    border-radius: 0; border: 0; box-shadow: none;
  }
  .pm-card.cc-joincheck .pm-head { padding-top: calc(15px + env(safe-area-inset-top, 0px)); }
  /* `max-height` широкой рамы (`.pm-wide .pm-body` — 64vh) здесь снят: кадр берёт ВСЮ свободную
     высоту, иначе «Присоединиться» висела бы посреди экрана, а не у большого пальца. */
  .pm-card.cc-joincheck .pm-body { flex: 1 1 auto; max-height: none; padding: 12px 16px 6px; }
  .cc-joincheck .jc-stage { flex: 1 1 auto; aspect-ratio: auto; min-height: 180px; }
  .pm-card.cc-joincheck .pm-foot {
    flex-direction: column-reverse; align-items: stretch; gap: 4px;
    padding: 8px 16px calc(14px + env(safe-area-inset-bottom, 0px));
  }
  .pm-card.cc-joincheck .pm-foot .primary { width: 100%; min-height: 48px; font-size: 16px; border-radius: 13px; }
  .pm-card.cc-joincheck .pm-foot .ghost {
    width: 100%; min-height: 40px; background: transparent; border: 0; box-shadow: none;
    color: var(--primary-2, var(--primary)); font-weight: 560; font-size: 15px;
  }
}
@media (prefers-reduced-motion: reduce) { .cc-joincheck .jc-btn { transition: none; } }
.pl-hero { --acc: var(--danger); display: flex; flex-direction: column; align-items: center; text-align: center; gap: 8px; }
.pl-hero.lv-grace, .pl-hero.lv-soon { --acc: var(--warning); }
.pl-ico {
  width: 56px; height: 56px; border-radius: 50%; margin-bottom: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--acc); background: color-mix(in srgb, var(--acc) 15%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--acc) 24%, transparent);
}
.pl-ico svg { width: 26px; height: 26px; }
.pl-title { font-size: 21px; font-weight: 700; line-height: 1.25; letter-spacing: -.01em; color: var(--text); }
.pl-what { font-size: 13px; font-weight: 560; color: var(--muted); }
.pl-lead { font-size: 14.5px; line-height: 1.45; color: var(--text); opacity: .86; max-width: 450px; }
.pl-facts {
  list-style: none; margin: 2px 0 0; padding: 12px 14px; display: flex; flex-direction: column; gap: 9px;
  border-radius: 14px; background: var(--panel-2, var(--panel));
}
.pl-facts li { display: flex; align-items: flex-start; gap: 10px; font-size: 13.5px; line-height: 1.4; color: var(--text); }
.pl-facts li svg { flex: none; width: 17px; height: 17px; margin-top: 1px; color: var(--ok); }
.pl-list { display: flex; flex-direction: column; gap: 10px; }
.pl-ws {
  --acc: var(--danger);
  display: flex; flex-direction: column; gap: 6px; padding: 12px 14px; border-radius: 14px;
  background: var(--panel); box-shadow: inset 0 0 0 1px var(--line);
}
.pl-ws.lv-grace, .pl-ws.lv-soon { --acc: var(--warning); }
.pl-ws-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.pl-ws-name { flex: 1 1 auto; min-width: 0; font-size: 15px; font-weight: 650; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-pill {
  flex: none; padding: 2px 8px; border-radius: 999px; white-space: nowrap;
  font-size: 11.5px; font-weight: 650; color: var(--acc);
  background: color-mix(in srgb, var(--acc) 13%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--acc) 26%, transparent);
}
.pl-ws-say { font-size: 13px; line-height: 1.4; color: var(--muted); }
.pl-ws-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 2px; }
.pl-btn {
  height: var(--ctl-h, 31px); padding: 0 12px; border: 0; border-radius: var(--ctl-r, 9px);
  font-size: var(--ctl-fs, 13px); font-weight: 600; cursor: pointer;
}
.pl-pay { background: var(--acc-fill, var(--primary)); color: #fff; }
.pl-more {
  background: color-mix(in srgb, var(--primary) 10%, var(--panel-2, var(--panel))); color: var(--text);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 24%, var(--line));
}
.pl-ws-more { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; padding-top: 6px; border-top: 1px solid var(--line); }
.pl-link {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  padding: 8px 6px; border: 0; border-radius: 9px; background: transparent;
  color: var(--text); font-size: 13.5px; cursor: pointer;
}
.pl-link:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }
.pl-link svg { flex: none; width: 16px; height: 16px; color: var(--muted); }
.pl-link.pl-danger, .pl-link.pl-danger svg { color: var(--danger); }
.pl-bal { text-align: center; font-size: 12.5px; color: var(--muted); }
/* Пометка «не оплачено» в строках списков (чаты, проекты, лиды, сделки, задачи) — та же пилюля `.co-lock`, что в
   переключателе компаний; здесь только посадка в строку. */
.pl-mark { margin-left: 6px; vertical-align: middle; cursor: pointer; }
.conv-item .pl-mark { margin-left: 0; }
.pp-main .pl-mark { margin: 2px 0 0; align-self: flex-start; }
/* 🔒 «НЕАКТИВНАЯ» ВЕЩЬ НЕОПЛАЧЕННОГО ПРОСТРАНСТВА (владелец 11.10.2026: «должны отображаться
   проекты как и раньше, но типа неактивными, пунктиром например и с пометкой оплатить»).
   Класс `.pl-locked` ставит сама строка (`ccPaylockCls`) — классом, а не `:has()`: на списках
   с живыми тикерами `:has` дорог (замер CLIE-444). Пунктир — `outline` (раскладка не двигается
   ни на пиксель), приглушено всё, КРОМЕ имени и пилюли: что это и что делать — читается сразу. */
.pl-locked {
  outline: 1.5px dashed color-mix(in srgb, var(--danger) 55%, var(--line));
  outline-offset: -2px;
  background: color-mix(in srgb, var(--danger) 4%, transparent);
}
.v2-pc-card.pl-locked > :not(.v2-pc-name),
.v2-pc-row.pl-locked > :not(.v2-pc-rname),
.pp-row.pl-locked .pp-coin, .pp-row.pl-locked .pp-sub, .pp-row.pl-locked .pp-stats,
.conv-item.pl-locked > :first-child, .conv-item.pl-locked .conv-meta, .conv-item.pl-locked .conv-time,
.conv-item.pl-locked .search-snippet, .conv-item.pl-locked .search-when,
.lead-card.pl-locked > :not(.tw-card-foot):not(.lead-card-top), .lead-card.pl-locked .lead-card-top > :not(.tw-card-title),
.deal-card.pl-locked > :not(.tw-card-foot):not(.deal-card-top), .deal-card.pl-locked .deal-card-top > :not(.tw-card-title),
.lead-card.pl-locked .tw-card-foot > :not(.pl-mark), .deal-card.pl-locked .tw-card-foot > :not(.pl-mark),
.lead-q-row.pl-locked > :not(.lead-q-main), .lead-q-row.pl-locked .lead-q-main > :not(.lead-q-t):not(.lead-q-rs),
.lead-q-row.pl-locked .lead-q-rs > :not(.pl-mark), .lead-q-row.pl-locked .lead-q-t > :not(.lead-q-title),
.lead-row.pl-locked > :not(.lead-row-title), .deal-row.pl-locked > :not(.deal-row-title),
.task-row.pl-locked .task-check, .task-row.pl-locked > :not(.tr-top),
.tw-row.pl-locked .tw-check, .tw-row.pl-locked .tw-row-meta > :not(.pl-mark),
.tw-card.pl-locked:not(.lead-card):not(.deal-card) > :not(.tw-card-head):not(.tw-card-title) {
  opacity: .5; filter: grayscale(.6);
}
.v2-pc-card.pl-locked .v2-pc-name, .v2-pc-row.pl-locked .v2-pc-rname,
.pp-row.pl-locked .pp-name, .task-row.pl-locked .task-title, .tw-card.pl-locked .tw-card-title,
.lead-q-row.pl-locked .lead-q-title, .lead-row.pl-locked .lead-row-t1, .deal-row.pl-locked .deal-row-title,
.tw-row.pl-locked .tw-row-title { color: var(--muted); }
.tw-row-meta .pl-mark, .lead-q-rs .pl-mark { margin-left: 0; }
.conv-item-body > .pl-mark { margin: 4px 0 0; } /* строка выдачи поиска: пометка своей строкой под подписью */

/* 💵 Вид «Касса» (ИДЕИ-1854): платёжный календарь вперёд по неделям — ВИД раздела «Аналитика»
   рядом с «Прибылью». Только токены темы (как у .prf-*): приход — `--ok`, уход — `--text`,
   разрыв и просрочка — `color-mix` от `--danger`; светлая и тёмная получаются даром. */
.deal-cashflow { padding: 22px; max-width: 980px; margin: 0 auto; }
.deal-cashflow .cf-weeks-seg { margin: 0 0 14px; }
.deal-cashflow .fc-section-title { margin-top: 22px; }
.cf-ok { color: var(--ok); }
.cf-weeks { display: flex; flex-direction: column; gap: 10px; }
.cf-week { border: 1px solid var(--line); border-radius: 14px; background: var(--panel); overflow: hidden; }
.cf-week.current { border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); }
.cf-week.gap { border-color: color-mix(in srgb, var(--danger) 45%, var(--line)); }
.cf-week.overdue { border-color: color-mix(in srgb, var(--danger) 35%, var(--line)); background: color-mix(in srgb, var(--danger) 5%, var(--panel)); }
.cf-week-h { display: grid; grid-template-columns: minmax(0, 1fr) auto 18px; gap: 12px; align-items: center; width: 100%;
  padding: 11px 14px; border: 0; background: transparent; color: var(--text); font: inherit; text-align: left; cursor: pointer; }
.cf-week-h:hover { background: var(--panel-2); }
.cf-week-t { font-size: 13.5px; font-weight: 650; display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.cf-week-t em { font-style: normal; font-size: 10.5px; font-weight: 700; color: var(--muted); padding: 1px 6px; border-radius: 6px;
  background: var(--panel-2); box-shadow: inset 0 0 0 1px var(--line); }
.cf-week.current .cf-week-t em { color: var(--primary-2); }
.cf-week.overdue .cf-week-t em { color: var(--danger-ink, var(--danger)); }
.cf-week-n { display: inline-flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px 14px; font-size: 12.5px; font-weight: 640; font-variant-numeric: tabular-nums; }
.cf-in { color: var(--ok); }
.cf-out { color: var(--text); }
.cf-bal { color: var(--muted); display: inline-flex; align-items: center; gap: 5px; }
.cf-bal.gap { color: var(--danger); font-weight: 700; }
.cf-bal svg.ic { width: 13px; height: 13px; }
.cf-bal-na { font-weight: 500; font-style: italic; }
.cf-chev svg.ic { width: 16px; height: 16px; color: var(--muted); transition: transform .18s ease; }
.cf-week.open .cf-chev svg.ic { transform: rotate(180deg); }
.cf-week-b { display: none; border-top: 1px solid var(--line); }
.cf-week.open .cf-week-b { display: block; }
.cf-empty { padding: 12px 14px; font-size: 12.5px; color: var(--muted); }
.cf-row { display: grid; grid-template-columns: 58px minmax(0, 1fr) auto; gap: 12px; align-items: center; padding: 9px 14px; border-top: 1px solid var(--line); }
.cf-row:first-child { border-top: 0; }
.cf-row.cf-open { cursor: pointer; }
.cf-row.cf-open:hover, .cf-row.cf-open:focus-visible { background: var(--panel-2); outline: none; }
.cf-row.late { background: color-mix(in srgb, var(--danger) 7%, var(--panel)); }
.cf-date { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.cf-title { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cf-title b { font-size: 13px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cf-title em { font-style: normal; font-size: 11px; color: var(--text-dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cf-amt { font-size: 13px; font-weight: 650; font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
.cf-row.in .cf-amt { color: var(--ok); }
.cf-row.out .cf-amt { color: var(--text); }
.cf-acts { grid-column: 2 / -1; display: flex; flex-wrap: wrap; gap: 6px; }
.cf-more { margin: 6px 14px 10px; }
@media (max-width: 720px) {
  .deal-cashflow { padding: 14px; }
  .cf-week-h { grid-template-columns: minmax(0, 1fr) 18px; }
  .cf-week-n { grid-column: 1 / -1; justify-content: flex-start; }
  .cf-row { grid-template-columns: 50px minmax(0, 1fr); }
  .cf-amt { grid-column: 2; text-align: left; }
}
/* ═════ 📊 ПОДПИСКА НА СВОДКУ (0477): окно «Подписка» у дашбордов + карточка в «Избранном» ═════
   Окно — канон `ccFormModal` (.pm-card), сегменты — `.cc-seg .cc-seg-sm`, тумблеры — `.v2ai-sw`.
   Карточка — числа строками «подпись · значение · дельта»; тон (good/bad) красит ТОЛЬКО число
   и дельту, без цветных реек сбоку. Обе темы — на токенах. */
.adg-form { display: flex; flex-direction: column; gap: 10px; }
.adg-lbl { font-size: 12px; font-weight: 600; color: var(--muted); text-transform: none; margin-top: 2px; }
.adg-seg { align-self: flex-start; }
.adg-seg > .adg-off { opacity: .45; }
.adg-busy .adg-form { opacity: .6; pointer-events: none; transition: opacity .14s ease; }
.adg-note, .adg-space { display: flex; align-items: center; gap: 6px; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.adg-note { color: var(--warn, #b7791f); }
.adg-space .ic, .adg-space svg { width: 14px; height: 14px; flex: 0 0 auto; }
.adg-when { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.adg-sel { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--muted); }
.adg-sel select { background-color: var(--input-bg, var(--panel-2)); color: var(--text); border: 1px solid var(--line); border-radius: 8px; padding: 5px 34px 5px 8px; font: inherit; } /* select-shorthand-chevron-2: цвет, а не сокращение background — общий шеврон select цел */
.adg-hint { font-size: 12px; color: var(--muted); line-height: 1.45; }
.adg-hide { display: none !important; }
.adg-sws { display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: 12px; overflow: hidden; }
.adg-sws .v2ai-sw { padding: 10px 12px; }
.adg-sws .v2ai-sw:last-child { border-bottom: 0; }
.adg-sw.adg-dis { opacity: .6; }
.adg-status { font-size: 13px; font-weight: 550; color: var(--text); padding: 8px 10px; border-radius: 10px; background: var(--panel-2); }
.adg-foot-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

.adg-card { min-width: 260px; max-width: 420px; padding: 12px 14px; border-radius: 16px; background: var(--panel); border: 1px solid var(--line); color: var(--text); display: flex; flex-direction: column; gap: 10px; }
.adg-head { display: flex; align-items: center; gap: 10px; }
.adg-ic { width: 32px; height: 32px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; background: color-mix(in srgb, var(--primary) 14%, transparent); color: var(--primary); }
.adg-alert .adg-ic { background: var(--danger-soft, color-mix(in srgb, var(--danger, #e5484d) 14%, transparent)); color: var(--danger, #e5484d); }
.adg-ic svg, .adg-ic .ic { width: 18px; height: 18px; }
.adg-ht { display: flex; flex-direction: column; min-width: 0; }
.adg-ht b { font-size: 14px; font-weight: 600; line-height: 1.3; }
.adg-ht small { font-size: 12px; color: var(--muted); }
.adg-sec { display: flex; flex-direction: column; gap: 4px; }
.adg-sec-h { font-size: 11.5px; font-weight: 600; letter-spacing: .02em; color: var(--muted); }
.adg-row { display: flex; align-items: baseline; gap: 10px; font-size: 13.5px; line-height: 1.4; }
.adg-row-l { flex: 1 1 auto; min-width: 0; color: var(--text-secondary, var(--muted)); }
.adg-row-v { flex: 0 0 auto; font-weight: 600; font-variant-numeric: tabular-nums; text-align: right; }
.adg-d { margin-left: 6px; font-size: 11.5px; font-weight: 500; color: var(--muted); }
.adg-row-v.adg-good, .adg-d.adg-good { color: var(--ok, #2f9e66); }
.adg-row-v.adg-bad, .adg-d.adg-bad { color: var(--danger, #e5484d); }
.adg-cnote { font-size: 12px; color: var(--muted); line-height: 1.45; white-space: pre-line; }
.adg-open { align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; border: 0; background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary-2, var(--primary)); font: inherit; font-size: 13px; font-weight: 550; padding: 6px 12px 6px 10px; border-radius: 10px; cursor: pointer; }
.adg-open:hover { background: color-mix(in srgb, var(--primary) 20%, transparent); }
.adg-open svg, .adg-open .ic { width: 15px; height: 15px; }

/* ═══════════════════════════════════════════════════════════════════════════
   🌌 «ГЛУБИНА» — НОВЫЙ ВИД СТРАНИЦЫ СДЕЛКИ (владелец 11.10.2026, вариант 5 из 10)
   Тёмное небо, мягкое сияние только за главным блоком, матовое стекло карточек, Manrope.
   Включается классом `:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page` (ссылка `/dl/<id>?look=depth`). Токены вида —
   `--dz-*`; базовые токены продукта (`--panel`, `--text`, `--line`…) ПЕРЕОПРЕДЕЛЕНЫ внутри
   колонки вида целиком — иначе блоки реестра взяли бы чужую палитру (канон control-size:
   локальный скоуп обязан накрыть ВСЕ токены базы). Колонка переписки остаётся в теме продукта.
   ═══════════════════════════════════════════════════════════════════════════ */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page, .tc-pop.dz-menu, .dz-modal {
  --dz-bg: #0B0C12; --dz-pop: #1E1F2B; --dz-glass: rgba(255,255,255,.06); --dz-glass2: rgba(255,255,255,.09);
  --dz-edge: rgba(255,255,255,.12); --dz-edge2: rgba(255,255,255,.18);
  --dz-text: #F4F5FA; --dz-text2: #BBBDC9; --dz-text3: #A1A3B4;
  --dz-link: #9aa6f4; --dz-bad: #FF6B6B; --dz-warn: #FFB547; --dz-ok: #4BE3C8; --dz-inv: #7c92e6;
  --dz-grad: linear-gradient(135deg, #5b68cf, #4e5ac2);
  --dz-glow: 0 10px 34px rgba(91,104,207,.45);
  --dz-shadow: 0 24px 60px rgba(0,0,0,.35);
  --dz-a1: #5d6ee7; --dz-a2: #596ae6; --dz-a3: #19C2B0; --dz-aura-o: .55;
  --dz-track: rgba(255,255,255,.10);
  /* сплошной акцент вида (заливка кнопок блоков, кольца, ссылки-плашки) и заливка «опасного»
     действия — белый текст на них читается (замер контраста ≥4.5) */
  --dz-pri: #5b68cf; --dz-pri-hi: #606dd2; --dz-bad-fill: #D93D42;
  background: var(--dz-bg);
}
html[data-theme="light"] :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page, html[data-theme="light"] .tc-pop.dz-menu, html[data-theme="light"] .dz-modal {
  --dz-bg: #F4F5F8; --dz-pop: #FFFFFF; --dz-glass: rgba(255,255,255,.72); --dz-glass2: rgba(255,255,255,.88);
  --dz-edge: rgba(24,24,39,.09); --dz-edge2: rgba(24,24,39,.16);
  --dz-text: #12131F; --dz-text2: #444655; --dz-text3: #595B6B;
  --dz-link: #005bb8; --dz-bad: #C42540; --dz-warn: #8A4D00; --dz-ok: #03695D; --dz-inv: #2f5bd0;
  --dz-grad: linear-gradient(135deg, #0071e3, #0066cc);
  --dz-glow: 0 10px 30px rgba(0,113,227,.25);
  --dz-shadow: 0 18px 50px rgba(36,36,59,.10);
  --dz-a1: #7fb7f4; --dz-a2: #8cc3ff; --dz-a3: #9FE8DA; --dz-aura-o: .55;
  --dz-track: rgba(24,24,39,.10);
  --dz-pri: #0071e3; --dz-pri-hi: #0066cc; --dz-bad-fill: #C42540;
}
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-col, .dz-modal, .v2pt-top.dz, .v2ov.dz,
:root[data-design="depth"] .task-info-panel > :is(.tip-head, .tip-tabs, .tip-scroll, .tip-history-host, .tip-media-host) {
  /* базовые токены продукта → палитра вида (блоки реестра, поля, кнопки внутри вкладок);
     .v2pt-top.dz / .v2ov.dz — шапка и «Обзор» страницы проекта в «Глубине» (та же палитра, не вторая);
     .task-info-panel > … — сторона КАРТОЧКИ у рамы задачи/тикета/доски/идеи (переписка — в теме продукта) */
  --bg: var(--dz-bg); --panel: var(--dz-glass); --panel-2: var(--dz-glass2); --panel-3: var(--dz-glass2);
  --card: var(--dz-glass); --surface: var(--dz-glass); --surface2: var(--dz-glass2); --surface-2: var(--dz-glass2);
  --line: var(--dz-edge); --line-strong: var(--dz-edge2); --border: var(--dz-edge); --hairline: var(--dz-edge);
  --text: var(--dz-text); --text-2: var(--dz-text); --fg: var(--dz-text); --muted: var(--dz-text2); --muted-2: var(--dz-text2);
  --text-dim: var(--dz-text3); --text-secondary: var(--dz-text2);
  --input-bg: color-mix(in srgb, var(--dz-bg) 55%, transparent); --bg-soft: var(--input-bg);
  --hover: color-mix(in srgb, var(--dz-text) 6%, transparent);
  --primary-2: var(--dz-link); --danger: var(--dz-bad); --ok: var(--dz-ok);
  --shadow-1: none;
  /* ВСЕ остальные токены базы, которые читают блоки реестра (замер 11.10: --primary 209 мест,
     --urg-* 48, --glow 33, --ctl-* 40, --warn 15…). `--warn` у базы = var(--warning), но
     ссылка разрешается там, где объявлена (:root), — поэтому переопределяем ОБА. */
  --primary: var(--dz-pri); --primary-hi: var(--dz-pri-hi); --accent: var(--dz-pri); --acc-fill: var(--dz-pri);
  --grad: var(--dz-grad); --glow: color-mix(in srgb, var(--dz-pri) 40%, transparent);
  --warning: var(--dz-warn); --warn: var(--dz-warn); --warning-soft: color-mix(in srgb, var(--dz-warn) 15%, transparent);
  --danger-soft: color-mix(in srgb, var(--dz-bad) 15%, transparent); --danger-fill: var(--dz-bad-fill); --danger-ink: var(--dz-bad);
  --ok-soft: color-mix(in srgb, var(--dz-ok) 14%, transparent);
  --urg-overdue: var(--dz-bad); --urg-overdue-soft: color-mix(in srgb, var(--dz-bad) 15%, transparent);
  --urg-today: var(--dz-warn); --urg-today-soft: color-mix(in srgb, var(--dz-warn) 15%, transparent);
  --urg-done: var(--dz-ok); --urg-done-soft: color-mix(in srgb, var(--dz-ok) 14%, transparent);
  --shadow-2: var(--dz-shadow);
  /* размерный класс ряда в «Глубине» крупнее (канон control-size: соседи в ряду берут --ctl-*) */
  --ctl-h: 40px; --ctl-r: 12px; --ctl-fs: 14px;
  --seg-track: var(--dz-glass); --seg-thumb: var(--dz-glass2); --seg-thumb-bd: var(--dz-edge2);
  --seg-thumb-sh: 0 6px 18px rgba(0,0,0,.18); --seg-div: var(--dz-edge);
}
/* раскладка колонки вида — отдельно от токенов (токены делит и окно .dz-modal) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-col {
  flex: 1 1 auto; position: relative; background: var(--dz-bg); color: var(--dz-text);
  container-type: inline-size; container-name: dz;
  /* сияние шире колонки по замыслу — горизонтальной прокрутки из-за него быть не должно */
  overflow-x: clip;
}
/* 🌊 CC-DZ-CRM · карточка КЛИЕНТА (компания, контакт) в «Глубине» — та же рама, что у сделки:
   широкий лист справа, колонка вида `.dz-col` (контейнер dz: герой, вкладки, плитки, карточки),
   у контакта — живая переписка своей колонкой, как `.crmw-chat` у сделки. Секции внутри — те же
   узлы, что рисует «Штиль» (одна реализация), им «Глубина» даёт только стекло и крупный шрифт. */
#crmDrawer.dz-page, #crmDrawer.dz-page.has-chat { width: min(1240px, calc(100vw - 64px)); background: var(--dz-bg); }
#crmDrawer.dz-page:has(> .crm-dz-body > .dz-chatcol) { width: min(1440px, calc(100vw - 64px)); }
#crmDrawer.dz-page > .crm-dz-body { flex: 1 1 auto; min-height: 0; display: flex; position: relative; }
#crmDrawer.dz-page > .crm-dz-body > .dz-col { overflow-y: auto; overscroll-behavior: contain; min-width: 0; min-height: 0; }
#crmDrawer.dz-page > .crm-dz-body.dz-skel { background: var(--dz-bg); }
#crmDrawer.dz-page > .crm-dz-body.dz-skel > .dz-col { overflow: hidden; }
/* переписка контакта — колонкой справа во всю высоту, со своим композером (как у сделки) */
#crmDrawer.dz-page .dz-chatcol { flex: 0 0 400px; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden;
  border-left: 1px solid var(--line); background: var(--panel); }
#crmDrawer.dz-page .dz-chatcol > .cws-chat-h { flex: none; display: flex; align-items: center; gap: 8px; height: 46px; padding: 0 14px; border-bottom: 1px solid var(--line); }
#crmDrawer.dz-page .dz-chatcol > .crm-chat-sec { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 10px; padding: 14px 14px 12px; }
#crmDrawer.dz-page .dz-chatcol .crm-chat-sec > .crm-sec-h { font-size: 16px; font-weight: 800; letter-spacing: -.01em; text-transform: none; color: var(--text); }
#crmDrawer.dz-page .dz-chatcol .crm-chat-host { flex: 1 1 auto; height: auto; min-height: 320px; }
#crmDrawer.dz-page .dz-chatcol .crm-chat-host:empty { flex: 0 0 0; min-height: 0; }
#crmDrawer.dz-page .dz-chatcol.dz-flash { animation: dzFlashIn 1.4s ease-out 1; border-radius: 0; }
html[data-theme="light"] #crmDrawer.dz-page .dz-chatcol { border-left-color: rgba(18,26,35,.09); }
/* окно уже листа с перепиской (ноутбук, планшет) — переписка встаёт ПОД карточкой, лист листается целиком;
   «Написать» в герое доводит до неё (dzWrite) */
@media (max-width: 1100px) {
  #crmDrawer.dz-page > .crm-dz-body:has(> .dz-chatcol) { flex-direction: column; overflow-y: auto; overscroll-behavior: contain; }
  #crmDrawer.dz-page > .crm-dz-body:has(> .dz-chatcol) > .dz-col { flex: none; overflow: visible; }
  #crmDrawer.dz-page .dz-chatcol { flex: none; height: clamp(440px, 82vh, 760px); border-left: 0; border-top: 1px solid var(--line); }
  #crmDrawer.dz-page .crm-dz-body.dz-skel .dz-chatcol { display: none; }
}
@media (max-width: 720px) {
  #crmDrawer.dz-page, #crmDrawer.dz-page.has-chat, #crmDrawer.dz-page:has(> .crm-dz-body > .dz-chatcol) { width: 100vw; border-left: 0; }
}
/* секции «Штиля» внутри вида — стеклянные карточки языка `.dz-card` */
/* язык блока — ровно как у блоков реестра сделки (.dz-pane .di-sec): стекло без тени, шапка 13/750 капсом */
.crm-dz-body .dz .crm-sec { background: var(--dz-glass); border: 1px solid var(--dz-edge); border-radius: 22px; padding: 14px 20px 20px;
  gap: 10px; box-shadow: none; -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px); min-width: 0; }
.crm-dz-body .dz .crm-sec .crm-sec { background: none; border: 0; border-radius: 0; padding: 0; box-shadow: none; }
.crm-dz-body .dz .crm-sec-h { font-size: 13px; font-weight: 750; letter-spacing: .06em; text-transform: uppercase; color: var(--dz-text2); min-height: var(--ctl-h); gap: 9px; }
.crm-dz-body .dz .crm-sec-h > svg.ic { width: 17px; height: 17px; color: var(--dz-link); }
.crm-dz-body .dz .crm-sec-n { flex: none; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  min-width: 26px; height: 24px; margin-left: -2px; padding: 0 8px; border: 0; border-radius: 12px;
  font-size: 13px; font-weight: 700; letter-spacing: 0; color: var(--dz-text2); background: var(--dz-glass2); }
.crm-dz-body .crm-sec-n:empty { display: none; }
.crm-dz-body .dz .crm-sec-add { box-sizing: border-box; min-height: var(--ctl-h); margin-right: -10px; padding: 0 10px; border: 0; border-radius: var(--ctl-r);
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; white-space: nowrap; color: var(--dz-link); background: transparent; box-shadow: none; gap: 7px; }
.crm-dz-body .dz .crm-sec-add:hover { background: color-mix(in srgb, var(--dz-link) 12%, transparent); color: var(--dz-link); }
.crm-dz-body .dz .crm-sec-add svg { width: 16px; height: 16px; }
.crm-dz-body .dz .crm-sec-empty { font-size: 15px; color: var(--dz-text2); }
.crm-dz-body .dz .crm-row, .crm-dz-body .dz .crm-deal-row { padding: 11px 12px; border-radius: 14px; margin: 0 -12px; }
.crm-dz-body .dz .crm-row-name { font-size: 16px; }
.crm-dz-body .dz .crm-row-sub { font-size: 13.5px; color: var(--dz-text2); }
/* у .crm-list overflow-y:auto → по x тоже auto: строки с полем -12px давали прокрутку вбок на 12 px */
.crm-dz-body .dz .crm-list-tight { padding: 0; overflow: visible; }
.crm-dz-body .dz .crm-field > label { font-size: 13px; color: var(--dz-text2); text-transform: none; letter-spacing: 0; font-weight: 700; }
.crm-dz-body .dz .crm-multi { font-size: 15px; padding: 11px 14px; border-radius: 14px; min-height: 46px; }
.crm-dz-body .dz .crm-notes { min-height: 120px; }
.crm-dz-body .dz .crm-link { padding: 12px 14px; border-radius: 16px; }
.crm-dz-body .dz .crm-link-name { font-size: 16px; }
.crm-dz-body .dz .crm-dup { gap: 12px; padding: 10px 12px; border-radius: 16px; background: var(--dz-glass2); border-color: var(--dz-edge); }
.crm-dz-body .dz .crm-dup-n { font-size: 15px; font-weight: 700; color: var(--dz-text); }
.crm-dz-body .dz .crm-dup-s { font-size: 13px; color: var(--dz-text2); }
.crm-dz-body .dz .crm-dup-btn { min-height: 36px; padding: 0 14px; border-radius: 12px; font-size: 14px; font-weight: 700; }
.crm-dz-body .dz .crm-dup-btn:not(.primary) { background: transparent; border-color: var(--dz-edge); color: var(--dz-text); }
.crm-dz-body .dz-pane > .di-sec, .crm-dz-body .crm-dz-stack > .di-sec { margin: 0; }
.crm-dz-stack { display: flex; flex-direction: column; gap: 14px; min-width: 0; }
.crm-dz-ccx .ccx-label { display: none; }
.crm-dz-body .dz-two > .crm-sec { align-self: stretch; }
/* герой: логотип / лицо + название, правится на месте (те же поля, та же дверь записи) */
.dz-coid { display: flex; align-items: center; gap: 16px; min-width: 0; }
.dz-coid > .crm-co-logo { width: 60px; height: 60px; flex: 0 0 60px; border-radius: 18px; }
.dz-coid > .crm-co-logo svg { width: 28px; height: 28px; }
.dz-coid > .crm-av { --sz: 64px; font-size: 22px; }
.dz-coid > .crm-head-tx { display: flex; flex-direction: column; gap: 6px; min-width: 0; flex: 1 1 auto; }
.crm-dz-body .dz-coid > :is(input, textarea).dz-title { flex: 1 1 auto; min-width: 0; width: auto; display: block; field-sizing: fixed;
  border: 0; background: transparent; color: var(--dz-text); }
/* название — многострочное поле: длинное имя переносится, а не режется краем (390: «АртРест - Вкусная до») */
.crm-dz-body .dz-coid > textarea.dz-title { flex: 1 1 0; field-sizing: content; resize: none; overflow: hidden;
  font-family: inherit; min-height: 0; max-height: none; outline: none; overflow-wrap: anywhere; }
.crm-dz-body .dz-coid > :is(input, textarea).dz-title:hover:not([readonly]) { background: var(--dz-glass); }
.crm-dz-body .dz-coid > :is(input, textarea).dz-title:focus { background: var(--dz-glass2); box-shadow: 0 0 0 2px var(--dz-link); }
.crm-dz-body .dz-coid > :is(input, textarea).dz-title[readonly]:hover { background: transparent; }
.crm-dz-body .crm-head-tx > .crm-name-edit.dz-title { margin: -4px -8px; padding: 4px 8px; }
.crm-dz-body .crm-head-tx > .crm-name-edit.dz-title:empty:before { color: var(--dz-text3); }
.crm-dz-body .crm-head-tx > .crm-title-edit { font-size: 16px; color: var(--dz-text2); margin: 0 -7px; }
.crm-dz-body .dz-coid > .dz-title { flex: 1 1 auto; min-width: 0; }
.dz .dz-hero.dz-hero-solo { grid-template-columns: minmax(0, 1fr); }
.dz-hero-l > .crm-life-pill { align-self: flex-start; max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.dz-hero-l > .crm-life-pill::-webkit-scrollbar { display: none; }
/* пилюли шапки, которые правятся на месте: отрасль, город, сайт */
.dz-mi.dz-mi-in { cursor: text; }
.dz-mi.dz-mi-in input.crm-co-in { all: unset; box-sizing: border-box; font: inherit; font-size: 15px; font-weight: 700; color: var(--dz-text);
  field-sizing: content; min-width: 6ch; max-width: 240px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: text; }
.dz-mi.dz-mi-in input.crm-co-in[readonly] { cursor: default; }
.dz-mi.dz-mi-in input.crm-co-in::placeholder { color: var(--dz-link); font-weight: 700; opacity: 1; }
.dz-mi.dz-mi-in:focus-within { border-color: var(--dz-link); box-shadow: 0 0 0 1px var(--dz-link); }
.dz-mi .crm-co-site-go { color: var(--dz-link); text-decoration: none; }
.dz-mi.crm-co-mgr-btn[disabled] { cursor: default; }
.dz-mi.crm-co-mgr-btn[disabled]:hover { border-color: var(--dz-edge); }
/* «Объединена с …» — слитый дубль по старой ссылке */
.dz-co-say { display: flex; flex-direction: column; gap: 4px; }
.dz-co-say b { font-size: 17px; font-weight: 700; color: var(--dz-text); }
.dz-co-say span { font-size: 15px; color: var(--dz-text2); }
.crm-dz-body .dz-mc-v small { font-size: 17px; font-weight: 700; color: var(--dz-text2); letter-spacing: 0; }
@container dz (max-width: 640px) {
  .dz-coid { gap: 12px; }
  .dz-coid > .crm-co-logo { width: 48px; height: 48px; flex-basis: 48px; border-radius: 14px; }
  .dz-coid > .crm-av { --sz: 52px; font-size: 18px; }
  .dz-mi.dz-mi-in input.crm-co-in { max-width: none; flex: 1 1 auto; }
  .dz-mi.dz-mi-in > span:last-child { flex: 1 1 auto; }
  .crm-dz-body .dz .crm-sec { padding: 12px 16px 16px; border-radius: 20px; }
  .crm-dz-body .dz .crm-sec-h { font-size: 12.5px; }
}
.dz {
  position: relative; max-width: 1180px; margin: 0 auto; padding: 18px 28px 72px;
  display: flex; flex-direction: column; gap: 18px;
  font-family: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-size: 16px; line-height: 1.4; color: var(--dz-text); -webkit-font-smoothing: antialiased;
}
.dz > * { position: relative; z-index: 1; }
/* сияние шире самого .dz, но НЕ шире колонки: колонка — прокручиваемый контейнер, и всё, что
   вылезало вправо, становилось её горизонтальной прокруткой (замер 12.10: +120 px на 1600,
   +235 px на телефоне). Поле наружу = зазор до края колонки (cqw — ширина колонки), ≤120 px;
   пятна внутри обрезаются самим сиянием (`overflow: clip` не создаёт прокрутки). */
.dz .dz-aura { position: absolute; z-index: 0; top: -160px; height: 720px; pointer-events: none; opacity: var(--dz-aura-o); overflow: clip;
  --dz-aura-x: calc(-1 * min(120px, max(0px, (100cqw - 100%) / 2))); left: var(--dz-aura-x); right: var(--dz-aura-x); }
.dz .dz-aura i { position: absolute; border-radius: 50%; filter: blur(70px); }
.dz .dz-aura i:nth-child(1) { width: 520px; height: 420px; left: 4%; top: 60px; background: var(--dz-a1); }
.dz .dz-aura i:nth-child(2) { width: 460px; height: 380px; left: 38%; top: 0; background: var(--dz-a2); opacity: .8; }
.dz .dz-aura i:nth-child(3) { width: 380px; height: 320px; right: 2%; top: 140px; background: var(--dz-a3); opacity: .6; }
.dz .dz-sp { flex: 1 1 auto; }
.dz .dz-glass {
  background: var(--dz-glass); border: 1px solid var(--dz-edge); border-radius: 26px;
  -webkit-backdrop-filter: blur(24px) saturate(140%); backdrop-filter: blur(24px) saturate(140%);
  box-shadow: var(--dz-shadow);
}
.dz .dz-glass2 { background: var(--dz-glass2); border: 1px solid var(--dz-edge); border-radius: 22px; }
.dz button { font-family: inherit; }
.dz .dz-lnk { all: unset; cursor: pointer; color: var(--dz-link); font-size: 15px; font-weight: 700; white-space: nowrap; padding: 6px 2px;
  /* зона нажатия ≥44px без сдвига раскладки (канон tap-target) */
  position: relative; }
.dz .dz-lnk::after { content: ""; position: absolute; inset: -9px -6px; }
.dz .dz-lnk:hover { text-decoration: underline; }
.dz .dz-cap { font-size: 13px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--dz-text2); }

/* шапка: путь + звезда + поделиться */
.dz-crumbs { display: flex; align-items: center; gap: 10px; min-height: 44px; font-size: 15px; color: var(--dz-text2); }
.dz-crumbs .dz-crumb-sep { opacity: .6; }
.dz-crumbs .dz-crumb { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-crumbs .dz-crumb-sep, .dz-crumbs .dz-back, .dz-crumbs .dz-ib, .dz-crumbs .dz-crumb:first-of-type { flex: none; }
.dz .dz-crumbs .dz-back, .dz .dz-crumbs .dz-ib {
  width: 44px; height: 44px; padding: 0; border-radius: 22px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--dz-glass); border: 1px solid var(--dz-edge); color: var(--dz-text); cursor: pointer;
}
.dz-crumbs .dz-back svg.ic, .dz-crumbs .dz-ib svg.ic { width: 18px; height: 18px; }
.dz .dz-crumbs .dz-back:hover, .dz .dz-crumbs .dz-ib:hover { background: var(--dz-glass2); border-color: var(--dz-edge2); }

/* герой: название · люди · действия | деньги */
.dz-hero { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 28px; padding: 28px; align-items: start; }
.dz-hero-l { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.dz-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.dz-chip { display: inline-flex; align-items: center; gap: 7px; height: 30px; padding: 0 12px; border-radius: 15px;
  background: var(--dz-glass2); border: 1px solid var(--dz-edge); font-size: 14px; font-weight: 700; color: var(--dz-text2); }
/* lead-hero-status-color-1 — точка статуса героя: открыт — акцент вида --dz-pri (как текущий шаг
   статуса .dz-step.cur), выиграна — --dz-ok, проиграна — --dz-bad. Раньше бирюзой «выиграна» горел
   любой открытый лид и сделка. Неизвестный статус получает акцент, а не «успех». */
.dz-chip.dz-st i { width: 8px; height: 8px; border-radius: 4px; background: var(--dz-pri); box-shadow: 0 0 10px var(--dz-pri); }
.dz-chip.dz-st { color: var(--dz-text); }
.dz-chip.st-won i { background: var(--dz-ok); box-shadow: 0 0 10px var(--dz-ok); }
.dz-chip.st-lost i { background: var(--dz-bad); box-shadow: 0 0 10px var(--dz-bad); }
.dz-title { font-size: 34px; line-height: 1.16; font-weight: 800; letter-spacing: -.02em; color: var(--dz-text);
  outline: none; border-radius: 10px; margin: -4px -8px; padding: 4px 8px; overflow-wrap: anywhere; }
.dz-title:hover { background: var(--dz-glass); }
.dz-title.dz-title-long { font-size: 28px; }
.dz-title.dz-title-long:not(:focus) { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; overflow: hidden; }
.dz-title:focus { background: var(--dz-glass2); box-shadow: 0 0 0 2px var(--dz-link); }
.dz-meta { display: flex; flex-wrap: wrap; gap: 10px; }
.dz-mi { all: unset; box-sizing: border-box; cursor: pointer; display: inline-flex; align-items: center; gap: 10px;
  min-height: 52px; max-width: 100%; padding: 6px 16px 6px 6px; border-radius: 26px; background: var(--dz-glass2); border: 1px solid var(--dz-edge); }
.dz-mi:hover { border-color: var(--dz-edge2); }
.dz-mi > span:last-child { display: flex; flex-direction: column; line-height: 1.2; min-width: 0; }
.dz-mi small, .dz-mi b { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-mi small { font-size: 13px; color: var(--dz-text3); }
.dz-mi b { font-size: 15px; font-weight: 700; color: var(--dz-text); }
.dz-mi b.dz-link { color: var(--dz-link); }
/* короткая форма значения (`.dz-mi-s`, «8 окт · 14 дн») по умолчанию скрыта: её включает узкая
   раскладка героя, широкая показывает полную (`.dz-mi-l`) — lead-hero-chip-wrap-1 */
.dz-mi .dz-mi-s { display: none; }
.dz-av { width: 40px; height: 40px; border-radius: 20px; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: var(--dz-grad); color: #fff; font-size: 15px; font-weight: 800; }
.dz-av.dz-av-sq { border-radius: 12px; background: #C2410C; font-size: 13px; }
.dz-av.dz-av-ic { background: var(--dz-glass); color: var(--dz-text2); border: 1px solid var(--dz-edge); }
.dz-av svg.ic { width: 18px; height: 18px; }
.dz-acts { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 4px; }
.dz .dz-btn { all: unset; box-sizing: border-box; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  height: 52px; padding: 0 22px; border-radius: 26px; font-size: 16px; font-weight: 700; white-space: nowrap;
  background: var(--dz-glass2); border: 1px solid var(--dz-edge); color: var(--dz-text); }
.dz .dz-btn:hover { border-color: var(--dz-edge2); }
.dz .dz-btn svg.ic { width: 18px; height: 18px; flex: none; }
.dz .dz-btn.dz-primary { background: var(--dz-grad); color: #fff; border-color: transparent; box-shadow: var(--dz-glow); }
.dz .dz-btn.dz-primary:hover { filter: brightness(1.08); }
.dz .dz-btn.dz-icon { width: 52px; padding: 0; }
/* общая кнопка, рождённая `.ghost` («В телефон» — ccVcfBtn): тематический `html[data-theme="light"] .ghost`
   (0,2,1) гасил стекло и рамку — в светлой «Глубине» кнопка оставалась голой подписью */
.dz .dz-btn.ghost, html[data-theme="light"] .dz .dz-btn.ghost { background: var(--dz-glass2); border: 1px solid var(--dz-edge); box-shadow: none; }
.dz .dz-btn.ghost:hover, html[data-theme="light"] .dz .dz-btn.ghost:hover { background: var(--dz-glass2); border-color: var(--dz-edge2); }
.dz .dz-btn .tw-seg-badge { margin-left: 2px; }
.dz .dz-btn.dz-soft-bad { background: color-mix(in srgb, var(--dz-bad) 16%, transparent); border-color: color-mix(in srgb, var(--dz-bad) 34%, transparent); }
.dz .dz-btn:focus-visible, .dz .dz-mi:focus-visible, .dz .dz-metric:focus-visible, .dz .dz-money:focus-visible, .dz .dz-pay:focus-visible,
.dz .dz-out:focus-visible, .dz .dz-burn:focus-visible, .dz .dz-person:focus-visible, .dz .dz-lnk:focus-visible, .dz .dz-chatcta:focus-visible,
.dz .dz-crumbs .dz-back:focus-visible, .dz .dz-crumbs .dz-ib:focus-visible { outline: 2px solid var(--dz-link); outline-offset: 2px; }
.dz .dz-step:focus-visible .dz-step-dot { outline: 2px solid var(--dz-link); outline-offset: 3px; }

/* карточка денег в шапке */
.dz-money { all: unset; box-sizing: border-box; cursor: pointer; display: flex; flex-direction: column; gap: 12px; padding: 22px;
  background: var(--dz-glass2); border: 1px solid var(--dz-edge); border-radius: 22px; min-width: 0; }
.dz-money:hover { border-color: var(--dz-edge2); }
.dz-mc-h { display: flex; align-items: center; justify-content: space-between; }
.dz-mc-h small { font-size: 14px; color: var(--dz-text2); font-weight: 600; }
.dz-mc-h svg.ic { width: 16px; height: 16px; color: var(--dz-text2); }
.dz-mc-v { font-size: 40px; line-height: 1.1; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.dz-bar { display: flex; height: 10px; border-radius: 5px; overflow: hidden; background: var(--dz-track); }
.dz-bar i { display: block; height: 100%; }
.dz-bar i.ok { background: var(--dz-ok); }
.dz-bar i.bad { background: repeating-linear-gradient(135deg, var(--dz-bad) 0 6px, color-mix(in srgb, var(--dz-bad) 55%, transparent) 6px 12px); }
.dz-bar i.inv { background: var(--dz-inv); }
.dz-mc-rows { display: flex; flex-direction: column; gap: 6px; font-size: 15px; color: var(--dz-text2); }
.dz-mc-rows > span { display: flex; align-items: center; gap: 8px; }
.dz-mc-rows > span > i { width: 8px; height: 8px; border-radius: 4px; background: var(--dz-track); flex: none; }
/* deal-sum-legend-dot-light-1: точка «Осталось получить» — цвет пустой дорожки (связь «серый = остаток»), но на белой карточке
   заливка --dz-track даёт контраст 1.24 (невидима). Кольцо средней силы делает точку видимой в обеих темах, заливка остаётся цветом дорожки. */
.dz-mc-rows > span > i:not(.ok):not(.inv):not(.bad) { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--dz-text3) 75%, transparent); }
.dz-mc-rows > span > i.ok { background: var(--dz-ok); }
.dz-mc-rows > span > i.inv { background: var(--dz-inv); }
.dz-mc-rows b { margin-left: auto; color: var(--dz-text); font-weight: 700; font-variant-numeric: tabular-nums; }
.dz-mc-say, .dz-mc-wait { font-size: 13px; color: var(--dz-text3); }
.dz-mc-v.dz-mc-none { font-size: 30px; color: var(--dz-link); }
.dz-mc-wait.dz-fail { color: var(--dz-bad); font-weight: 600; }
.dz-fail-box > span { color: var(--dz-text); }

/* лестница стадий */
.dz-stages { padding: 20px 24px 22px; display: flex; flex-direction: column; gap: 18px; }
.dz-stages-h { display: flex; align-items: center; gap: 10px 16px; flex-wrap: wrap; }
.dz-stages-h > .dz-cap { flex: 1 1 240px; min-width: 0; }
/* исход сделки — ОДНА группа: «Итог:» и обе кнопки переносятся вместе, а не по одной */
.dz-outs { flex: none; max-width: 100%; display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.dz-stages-none { font-size: 14px; }
.dz .dz-out { all: unset; box-sizing: border-box; cursor: pointer; display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 14px;
  border-radius: 20px; border: 1px solid var(--dz-edge); background: var(--dz-glass); font-size: 14px; font-weight: 700; color: var(--dz-text); }
.dz .dz-out svg.ic { width: 15px; height: 15px; }
.dz .dz-out { position: relative; }
.dz .dz-out::after { content: ""; position: absolute; inset: -2px 0; }
.dz .dz-out.deal-won svg.ic { color: var(--dz-ok); }
.dz .dz-out.deal-lost svg.ic { color: var(--dz-bad); }
.dz .dz-out.deal-won.on { background: color-mix(in srgb, var(--dz-ok) 18%, transparent); border-color: var(--dz-ok); }
.dz .dz-out.deal-lost.on { background: color-mix(in srgb, var(--dz-bad) 18%, transparent); border-color: var(--dz-bad); }
.dz-track { position: relative; display: grid; grid-template-columns: repeat(var(--n), minmax(0, 1fr)); }
.dz-step { all: unset; box-sizing: border-box; cursor: pointer; position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 0 4px; min-width: 0; text-align: center; }
/* соединительная линия — у КАЖДОЙ стадии своя, до соседа справа (колонки равные: центр соседа
   ровно через 100 %). Общая полоса на всю дорожку рвалась бы в прокрутке узкой колонки. */
.dz-step:not(:last-child)::before { content: ""; position: absolute; z-index: -1; top: 14px; left: calc(50% + 15px); width: calc(100% - 30px); height: 3px; border-radius: 2px; background: var(--dz-track); }
.dz-step.done:not(:last-child)::before { background: var(--dz-grad); box-shadow: 0 0 12px rgba(91,104,207,.6); }
.dz .dz-track > .dz-step { padding: 0 4px; gap: 8px; }
.dz-step-dot { width: 30px; height: 30px; border-radius: 15px; display: inline-flex; align-items: center; justify-content: center;
  background: var(--dz-bg); border: 2px solid var(--dz-edge2); color: #fff; }
.dz-step-dot svg.ic { width: 15px; height: 15px; }
.dz-step.done .dz-step-dot { background: var(--dz-grad); border-color: transparent; }
.dz-step.cur .dz-step-dot { border: 3px solid #5b68cf; box-shadow: 0 0 0 6px color-mix(in srgb, #5b68cf 25%, transparent), 0 0 18px rgba(91,104,207,.7); }
.dz-step.cur .dz-step-dot::after { content: ""; width: 10px; height: 10px; border-radius: 5px; background: #5b68cf; }
/* подпись стадии рвётся ТОЛЬКО между словами (12.10: «Разрабо/тка», «Тестиро/вание» на телефоне);
   слово длиннее колонки — многоточием, полное имя — в подсказке кнопки (title) */
.dz-step-n { max-width: 100%; font-size: 15px; font-weight: 600; line-height: 1.3; color: var(--dz-text2);
  overflow-wrap: normal; word-break: normal; hyphens: manual;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; text-overflow: ellipsis; }
.dz-step.cur .dz-step-n { color: var(--dz-text); font-weight: 800; }
.dz-step:hover .dz-step-n { color: var(--dz-text); }
.dz-track.dz-many .dz-step-n { font-size: 13.5px; }
.dz .dz-track.dz-many > .dz-step { padding: 0 2px; }
.dz-warnchip { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 12px; font-size: 13px; font-weight: 700; white-space: nowrap;
  color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 14%, transparent); border: 1px solid color-mix(in srgb, var(--dz-warn) 30%, transparent); }
.dz-warnchip svg.ic { width: 13px; height: 13px; }

/* просрочка */
.dz-alert { display: grid; grid-template-columns: 46px minmax(0, 1fr) auto; align-items: center; gap: 12px 16px; padding: 18px 22px; border-radius: 22px;
  background: color-mix(in srgb, var(--dz-bad) 12%, var(--dz-glass)); border: 1px solid color-mix(in srgb, var(--dz-bad) 38%, transparent);
  -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px); }
.dz-alert-ic { width: 46px; height: 46px; border-radius: 23px; flex: none; display: inline-flex; align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--dz-bad) 20%, transparent); color: var(--dz-bad); }
.dz-alert-ic svg.ic { width: 22px; height: 22px; }
.dz-alert-t { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.dz-alert-t b { font-size: 20px; font-weight: 800; color: var(--dz-bad); }
.dz-alert-t small { font-size: 15px; color: var(--dz-text2); }
.dz-alert-t .dz-alert-why { font-size: 14px; color: var(--dz-text2); }
.dz-alert-acts { display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 10px 20px; }

/* вкладки — канон `.cc-seg` (крупный, страничный), палитра стекла */
.dz-tabsrow { position: sticky; top: 0; z-index: 3; padding: 6px 0; margin: -6px 0; }
.dz .dz-tabs { -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px); border-radius: 16px; padding: 4px; border-color: var(--dz-edge); }
.dz .dz-tabs > * { font-size: 16px; font-weight: 650; padding: 11px 20px; border-radius: 12px; color: var(--dz-text2); }
.dz .dz-tabs > *.on { color: var(--dz-text); font-weight: 800; }
.dz-pane[hidden] { display: none !important; }
.dz-pane { display: flex; flex-direction: column; gap: 18px; }

/* обзор: расход, метрики, этапы, платежи, клиент, последнее */
.dz-burn { all: unset; box-sizing: border-box; cursor: pointer; width: 100%; display: grid; grid-template-columns: 42px minmax(0, 1fr) auto; align-items: center; gap: 12px 16px; padding: 16px 22px; }
.dz-burn-ic { width: 42px; height: 42px; border-radius: 21px; flex: none; display: inline-flex; align-items: center; justify-content: center;
  color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 16%, transparent); }
.dz-burn-ic svg.ic { width: 20px; height: 20px; }
.dz-burn-t { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dz-burn-t b { font-size: 17px; font-weight: 800; }
.dz-burn-t em { font-style: normal; color: var(--dz-warn); }
.dz-burn-t small { font-size: 14px; color: var(--dz-text2); }
.dz-burn-g { display: flex; flex-direction: column; gap: 6px; width: 260px; max-width: 100%; }
.dz-burn-g > span { display: grid; grid-template-columns: 96px 1fr 44px; align-items: center; gap: 10px; font-size: 14px; color: var(--dz-text2); }
.dz-burn-g small { font-size: 13px; }
.dz-burn-g > span::before { content: ""; grid-column: 2; grid-row: 1; height: 6px; border-radius: 3px; background: var(--dz-track); }
.dz-burn-g i { grid-column: 2; grid-row: 1; height: 6px; border-radius: 3px; background: var(--dz-inv); }
.dz-burn-g i.warn { background: var(--dz-warn); }
.dz-burn-g b { text-align: right; color: var(--dz-text); font-variant-numeric: tabular-nums; }
.dz-metrics { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.dz-metric { all: unset; box-sizing: border-box; cursor: pointer; display: flex; flex-direction: column; gap: 6px; padding: 20px; min-height: 150px; }
.dz-metric:hover { border-color: var(--dz-edge2); }
.dz-metric-h { display: flex; align-items: center; justify-content: space-between; }
.dz-metric-h small { font-size: 14px; color: var(--dz-text2); font-weight: 600; }
.dz-metric-h svg.ic { width: 16px; height: 16px; color: var(--dz-text2); }
.dz-metric-v { display: flex; align-items: center; gap: 10px; font-size: 32px; line-height: 1.1; font-weight: 800; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.dz-metric-v small { font-size: 18px; font-weight: 700; color: var(--dz-text2); margin-left: 2px; }
.dz-metric-s { font-size: 14px; color: var(--dz-text2); line-height: 1.35; }
.dz-metric-s b { color: var(--dz-text); }
.dz-ring { --p: 0; width: 30px; height: 30px; border-radius: 50%; flex: none;
  background: conic-gradient(var(--dz-pri, #5b68cf) calc(var(--p) * 1%), var(--dz-track) 0); -webkit-mask: radial-gradient(circle 10px, transparent 98%, #000 100%); mask: radial-gradient(circle 10px, transparent 98%, #000 100%); }
.dz-card { padding: 22px 24px; display: flex; flex-direction: column; gap: 14px; }
.dz-card-h { display: flex; align-items: baseline; gap: 4px 12px; flex-wrap: wrap; }
.dz-card-h h3 { margin: 0; font-size: 22px; font-weight: 800; letter-spacing: -.01em; }
.dz-card-h small { font-size: 14px; color: var(--dz-text2); }
.dz-empty { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; font-size: 15px; color: var(--dz-text2); }
.dz-two { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); gap: 14px; align-items: start; }
/* сетка плиток под 2/3/5 плиток (сводки вкладок) — модификатор, а не вторая сетка */
.dz-metrics.dz-n2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.dz-metrics.dz-n3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.dz-metrics.dz-n5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
/* сводка вкладки: нечего сказать — хоста нет */
.dz-sum { display: flex; flex-direction: column; gap: 14px; }
.dz-sum:empty { display: none; }
/* вкладка без блоков — слова и выход */
.dz-tabempty { padding: 36px 28px; align-items: center; text-align: center; gap: 10px; }
.dz-tabempty small { font-size: 15px; color: var(--dz-text2); max-width: 420px; }
.dz-tabempty .dz-btn { margin-top: 6px; }
.dz-tabempty > svg.ic { width: 26px; height: 26px; color: var(--dz-link); }
.dz-tabempty b { font-size: 19px; font-weight: 800; color: var(--dz-text); }

.dz-tl { display: flex; flex-direction: column; gap: 4px; }
.dz-tl-axis { display: grid; grid-template-columns: minmax(180px, 34%) 1fr; height: 22px; }
.dz-tl-axis > div { position: relative; }
.dz-tl-axis i { position: absolute; top: 0; transform: translateX(-50%); font-style: normal; font-size: 13px; color: var(--dz-text3); white-space: nowrap; }
.dz-tl-axis i.today span { color: var(--dz-link); font-weight: 800; }
.dz-tl-axis i.end { transform: translateX(-100%); }
.dz-tl-axis i.start { transform: none; }
.dz-tl-rows { position: relative; display: flex; flex-direction: column; }
.dz-ph { display: grid; grid-template-columns: minmax(180px, 34%) 1fr; align-items: center; gap: 0; min-height: 66px; border-top: 1px solid var(--dz-edge); }
.dz-ph.par { background: color-mix(in srgb, var(--dz-link) 7%, transparent); }
.dz-ph-t { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px 10px 0; min-width: 0; }
.dz-ph-t b { font-size: 16px; font-weight: 700; }
.dz-ph-t small { font-size: 13px; color: var(--dz-text2); }
.dz-ph-sts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.dz-ph-st { align-self: flex-start; font-size: 13px; font-weight: 700; line-height: 1.35; padding: 3px 10px; border-radius: 10px; color: var(--dz-text2); background: var(--dz-glass2); }
.dz-ph-st.done { color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 14%, transparent); }
.dz-ph-st.live { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent); }
.dz-ph-st.late { color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 14%, transparent); }
/* линия «сегодня» — фон дорожки на отметке `--today` (это шкала времени, а не акцент-рейка) */
.dz-ph-lane { position: relative; height: 100%; min-height: 56px;
  background: linear-gradient(color-mix(in srgb, var(--dz-link) 75%, transparent), color-mix(in srgb, var(--dz-link) 75%, transparent)) no-repeat;
  background-size: 2px 100%; background-position: var(--today) 0; }
.dz-ph-d { position: absolute; z-index: 1; top: 6px; left: calc(var(--s, 0) * 1%); font-size: 13px; color: var(--dz-text3); white-space: nowrap; text-shadow: 0 0 3px var(--dz-bg), 0 0 3px var(--dz-bg); }
.dz-ph-d.end { left: auto; right: calc((100 - var(--e, 100)) * 1%); }
.dz-ph-bar { position: absolute; top: 30px; height: 10px; border-radius: 5px; }
.dz-ph-bar.done { background: var(--dz-ok); }
.dz-ph-bar.live { background: var(--dz-grad); box-shadow: 0 0 12px rgba(91,104,207,.55); }
.dz-ph-bar.wait { background: transparent; border: 1.5px dashed var(--dz-edge2); box-sizing: border-box; }
.dz-ph-bar.late { border-radius: 0 5px 5px 0; background: repeating-linear-gradient(135deg, var(--dz-warn) 0 5px, color-mix(in srgb, var(--dz-warn) 35%, transparent) 5px 10px); }

.dz-pays { display: flex; flex-direction: column; }
.dz-pay { all: unset; box-sizing: border-box; cursor: pointer; display: grid; grid-template-columns: 42px minmax(0, 1fr) auto; align-items: center; gap: 14px; padding: 14px 0; border-top: 1px solid var(--dz-edge); }
.dz-pay:first-child { border-top: 0; }
.dz-pay-ic { width: 42px; height: 42px; border-radius: 21px; display: inline-flex; align-items: center; justify-content: center; background: var(--dz-glass2); color: var(--dz-text2); }
.dz-pay-ic svg.ic { width: 18px; height: 18px; }
.dz-pay-ic.bad { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 16%, transparent); }
.dz-pay-ic.ok { color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 16%, transparent); }
.dz-pay-ic.warn { color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 16%, transparent); }
.dz-pay-t { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.dz-pay-t b { font-size: 16px; font-weight: 700; }
.dz-pay-t small { font-size: 14px; color: var(--dz-text2); }
.dz-pay-t small b.warn { font-size: 14px; color: var(--dz-warn); }
.dz-pay-bar { height: 5px; border-radius: 3px; background: var(--dz-track); overflow: hidden; max-width: 220px; margin-top: 4px; }
.dz-pay-bar i { display: block; height: 100%; background: var(--dz-ok); }
.dz-pay-r { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.dz-pay-r b { font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; white-space: nowrap; }
.dz-tag { font-style: normal; font-size: 13px; font-weight: 700; padding: 2px 9px; border-radius: 10px; color: var(--dz-text2); background: var(--dz-glass2); white-space: nowrap; }
.dz-tag.bad { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); }
.dz-tag.ok { color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 14%, transparent); }
.dz-tag.warn { color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 14%, transparent); }
.dz-tag.inv { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent); }
.dz-tag, .dz-ph-st { box-shadow: inset 0 0 0 1px var(--dz-edge2); }
.dz-tag.ok, .dz-ph-st.done { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-ok) 26%, transparent); }
.dz-tag.bad { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent); }
.dz-tag.warn, .dz-ph-st.late { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 26%, transparent); }
.dz-tag.inv, .dz-ph-st.live { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-link) 26%, transparent); }

.dz-client-empty { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; padding: 10px 6px; }
.dz-client-ic { width: 56px; height: 56px; border-radius: 28px; display: inline-flex; align-items: center; justify-content: center; background: var(--dz-grad); color: #fff; box-shadow: var(--dz-glow); }
.dz-client-ic svg.ic { width: 24px; height: 24px; }
.dz-client-empty b { font-size: 19px; font-weight: 800; }
.dz-client-empty small { font-size: 15px; color: var(--dz-text2); max-width: 300px; }
.dz-company { display: flex; align-items: center; gap: 10px; font-size: 16px; }
.dz-company svg.ic { width: 18px; height: 18px; color: var(--dz-text2); }
.dz-people { display: flex; flex-direction: column; gap: 6px; }
.dz-person { all: unset; cursor: pointer; display: flex; align-items: center; gap: 12px; padding: 6px 0; }
.dz-person > span:last-child { display: flex; flex-direction: column; }
.dz-person b { font-size: 16px; font-weight: 700; }
.dz-person small { font-size: 14px; color: var(--dz-text2); }
.dz .dz-lnk.dz-more { align-self: flex-start; font-size: 14px; }
.dz-recent .deal-act { padding: 12px 0; gap: 14px; border-top: 1px solid var(--dz-edge); }
.dz-recent .deal-act-dot { margin-top: 8px; background: var(--dz-pri); box-shadow: 0 0 0 4px color-mix(in srgb, var(--dz-pri) 22%, transparent); }
.dz-recent .deal-act-b { flex: 1 1 auto; min-width: 0; display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 2px 16px; }
.dz-recent .deal-act:first-child { border-top: 0; }
.dz-recent .deal-act-k { font-size: 16px; color: var(--dz-text); }
.dz-recent .deal-act-m { margin-top: 0; font-size: 14px; color: var(--dz-text2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.dz-chatcta { all: unset; box-sizing: border-box; cursor: pointer; display: flex; align-items: center; gap: 14px; padding: 18px 22px; }
.dz-chatcta > svg.ic:first-child { width: 22px; height: 22px; color: var(--dz-link); }
.dz-chatcta > span { flex: 1 1 auto; display: flex; flex-direction: column; }
.dz-chatcta b { font-size: 17px; font-weight: 800; }
.dz-chatcta small { font-size: 14px; color: var(--dz-text2); }
.dz-chatcta > svg.ic:last-child { width: 18px; height: 18px; color: var(--dz-text2); }

/* блоки реестра внутри вкладок — стекло вида, тот же провод */
.dz-pane .crmw-grid { gap: 14px; }
.dz-pane .di-sec, .dz-pane .crmb, .dz-pane .crmacc, .dz-pane .crmauto {
  background: var(--dz-glass); border: 1px solid var(--dz-edge); border-radius: 22px; box-shadow: none;
  -webkit-backdrop-filter: blur(24px); backdrop-filter: blur(24px);
}
/* общий язык блоков во всех вкладках: воздух, крупнее кегль, заголовок без черты */
.dz-pane .di-sec-h { padding: 16px 20px 8px; border-bottom: 0; min-height: 52px; box-sizing: border-box; }
.dz-pane .di-sec-t { font-size: 13px; font-weight: 750; letter-spacing: .06em; color: var(--dz-text2); gap: 9px; }
.dz-pane .di-sec-t .ic { width: 17px; height: 17px; opacity: 1; color: var(--dz-link); }
.dz-pane .di-sec-b { padding: 6px 20px 20px; gap: 12px; font-size: 15px; }
.dz-pane .crmw-cfg { margin-top: 4px; }
/* «Доп. поля» до загрузки — пустой хост не занимает ячейку сетки */
.dz-pane .crmw-blk:has(> .ccx-host:empty) { display: none; }
/* скелетон «Глубины»: её геометрия на её небе; переписка справа — как у «Штиля» */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .crmw-skel.dz-skel { background: var(--dz-bg); }
.dz-skel .dz-skel-main { flex: 1 1 auto; overflow: hidden; --line: var(--dz-edge); --line-strong: var(--dz-edge2); background: var(--dz-bg);
  container-type: inline-size; container-name: dz; }
.dz-skel .dz { pointer-events: none; }
.dz-skel .dz-skel-title { display: flex; flex-direction: column; gap: 10px; }
.dz-skel .dz-mi > span:last-child { gap: 7px; }
.dz-skel .dz-skel-btn { flex: none; width: 164px; height: 52px; border-radius: 26px; }
.dz-skel .dz-skel-btn.dz-skel-main-btn { width: 150px; }
.dz-skel .dz-skel-btn.dz-skel-ic-btn { width: 52px; }
.dz-skel .dz-step > .cc-skel:last-child { max-width: 100%; }
.dz-skel .dz-metric { min-height: 0; gap: 12px; }
.dz-skel .dz-card { gap: 16px; }
/* ⟦DZ-TAB-FRAGMENTS⟧ — оформление блоков по вкладкам (Деньги · Работа · Заметки и ИИ · История · Детали) */
/* ── common ── */
/* ═══════════════════════════════════════════════════════════════════════════
   🧩 «ГЛУБИНА» · ОБЩИЙ СЛОВАРЬ КОНТРОЛОВ БЛОКОВ (все вкладки: Деньги · Работа · Заметки и ИИ ·
   История · Детали). Едет ПЕРВЫМ, вкладочные фрагменты его уточняют — поэтому специфичность здесь
   НАРОЧНО низкая: `.dz-pane .x` (0,2,0), класс-модификатор — (0,3,0). Вкладка, которой нужен
   свой вид контрола, пишет `.dz-pane .<корень блока> .x` и выигрывает без `!important`.
   Раскладку КОНКРЕТНЫХ блоков (сетки, колонки, порядок) здесь не трогаем — только сами контролы:
   кнопки · ссылки · поля · чипы статусов · счётчики · пустые/скелетон/отказ · значки шапки ·
   иконки-действия строк · строки списков. Цвета — только токены вида `--dz-*`.
   ═══════════════════════════════════════════════════════════════════════════ */

/* токены, которых блоки читают, а колонка вида не перекрыла (замер var() по правилам, задевающим
   узлы вкладок, 12.10: `.primary` брал `--acc-grad` продукта — чужой градиент на небе «Глубины») */
.dz-pane {
  --acc-grad: var(--dz-grad);
  --sel: color-mix(in srgb, var(--dz-link) 24%, transparent);
  /* размер иконки-действия строки и её поле промаха на сенсоре */
  --dz-ib: 32px;
  /* фокус-кольцо полей и кнопок — ссылочным цветом вида, видно в обеих темах */
  --dz-ring: 0 0 0 3px color-mix(in srgb, var(--dz-link) 30%, transparent);
}

/* ── 1 · КНОПКИ ─────────────────────────────────────────────────────────────
   Главная кнопка блока — сплошной акцент вида, белый текст (градиент со свечением остаётся у ОДНОЙ
   кнопки экрана — героя шапки, правило V5 «одна светящаяся кнопка»). Вторичная — стекло с кромкой.
   Размер — размерный класс ряда `--ctl-*` (40 / 12 / 14). Подпись не уже себя: длинная переносится,
   а не вылезает за край узкой колонки телефона. */
.dz-pane .di-btn, .dz-pane .primary, .dz-pane .di-ask-send {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  box-sizing: border-box; min-height: var(--ctl-h); max-width: 100%; margin-top: 0;
  padding: 6px 18px; border: 0; border-radius: var(--ctl-r);
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; line-height: 1.25;
  white-space: normal; text-align: center; overflow-wrap: normal;
  color: #fff; background: var(--dz-pri); box-shadow: none; filter: none;
}
.dz-pane .di-btn:hover, .dz-pane .primary:hover, .dz-pane .di-ask-send:hover {
  background: var(--dz-pri-hi); box-shadow: 0 6px 18px color-mix(in srgb, var(--dz-pri) 32%, transparent); filter: none;
}
.dz-pane .di-btn > svg.ic, .dz-pane .primary svg.ic, .dz-pane .di-ask-send svg.ic { width: 16px; height: 16px; flex: none; }
.dz-pane .primary.small { width: auto; padding: 6px 16px; }
/* квадратная «отправить» рядом с полем — вровень с полем */
.dz-pane .di-ask-send, .dz-pane .primary.icon-btn { width: var(--ctl-h); padding: 0; flex: none; }

/* несколько главных кнопок рядом (шаблоны графика, «Акт по счёту · Акт по часам») — это выбор,
   а не одно главное действие: стекло, как у вторичной (V5: светится одна). `:where` держит вес
   одиночной кнопки, чтобы вкладка могла вернуть акцент своему действию. */
.dz-pane .di-btn:where(:has(+ .di-btn), .di-btn + .di-btn) {
  color: var(--dz-text); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge2);
}
.dz-pane .di-btn:where(:has(+ .di-btn), .di-btn + .di-btn):hover {
  background: color-mix(in srgb, var(--dz-text) 10%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2));
}

/* вторичная: стекло + кромка (кнопки тела блока) */
.dz-pane .dc-a, .dz-pane .dbg-more, .dz-pane .di-btn.primary-ghost, .dz-pane .cc-btn,
.dz-pane .crm-act-more, .dz-pane .crmw-cfg-b, .dz-pane .di-sec-b .ghost.small:not(.icon-btn) {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  box-sizing: border-box; min-height: var(--ctl-h); max-width: 100%; margin-top: 0;
  padding: 6px 16px; border: 1px solid var(--dz-edge2); border-radius: var(--ctl-r);
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; line-height: 1.25;
  white-space: normal; text-align: center; overflow-wrap: normal; text-decoration: none;
  color: var(--dz-text); background: var(--dz-glass2); box-shadow: none; filter: none;
}
.dz-pane .dc-a:hover, .dz-pane .dbg-more:hover, .dz-pane .di-btn.primary-ghost:hover, .dz-pane .cc-btn:hover,
.dz-pane .crm-act-more:hover, .dz-pane .crmw-cfg-b:hover, .dz-pane .di-sec-b .ghost.small:not(.icon-btn):hover {
  color: var(--dz-text); border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2));
  background: color-mix(in srgb, var(--dz-text) 10%, transparent);
}
.dz-pane .dc-a svg.ic, .dz-pane .dbg-more svg.ic, .dz-pane .cc-btn svg.ic, .dz-pane .crmw-cfg-b .ic,
.dz-pane .di-sec-b .ghost.small svg.ic { width: 16px; height: 16px; flex: none; }
/* смысловые вторичные: приход и беда — цвет словом и кромкой, подложка стекло (канон accent) */
.dz-pane .dc-a.ok { color: var(--dz-ok); border-color: color-mix(in srgb, var(--dz-ok) 40%, transparent); }
/* действие беды (удалить · отозвать · «primary danger» подтверждения) — коралловая кромка (V5) */
.dz-pane .dc-a.bad, .dz-pane .danger, .dz-pane .cc-btn.danger, .dz-pane .di-sec-b .ghost.small.danger:not(.icon-btn) {
  color: var(--dz-bad); border: 1px solid color-mix(in srgb, var(--dz-bad) 40%, transparent); background: color-mix(in srgb, var(--dz-bad) 10%, transparent);
}

/* действия ШАПКИ блока (+ Пункт · Прикрепить · Звонок…): ссылкой, без плашки — шапка остаётся
   лёгкой (V5: «вторая — стекло, остальное — ссылкой»); высота ряда та же, что у соседей */
.dz-pane .di-sec-h .crmb-act, .dz-pane .di-sec-h .di-link, .dz-pane .di-sec-h .ghost.small {
  display: inline-flex; align-items: center; gap: 7px; box-sizing: border-box;
  min-height: var(--ctl-h); margin-top: 0; padding: 0 10px; border: 0; border-radius: var(--ctl-r);
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; line-height: 1.2; white-space: nowrap;
  color: var(--dz-link); background: transparent; box-shadow: none; text-decoration: none;
}
.dz-pane .di-sec-h .crmb-act:hover, .dz-pane .di-sec-h .di-link:hover, .dz-pane .di-sec-h .ghost.small:hover {
  background: color-mix(in srgb, var(--dz-link) 12%, transparent); color: var(--dz-link); border-color: transparent; text-decoration: none;
}
.dz-pane .di-sec-h .crmb-act svg.ic, .dz-pane .di-sec-h .ghost.small svg.ic { width: 16px; height: 16px; flex: none; }
/* включённое действие шапки (поле «+ Пункт» открыто, «Следить» включено) — подпись зависит от состояния */
.dz-pane .di-sec-h .crmb-act.on { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-link) 30%, transparent); }
.dz-pane .di-sec-h .ghost.small.icon-btn { width: var(--ctl-h); padding: 0; justify-content: center; }
.dz-pane .crm-act-add, .dz-pane .crmb-hacts, .dz-pane .crmb-watch-acts { gap: 2px; }
/* заголовок держит высоту ряда действий — подпись по центру первой строки, даже когда действия
   переносятся (у «Дел» шапка выровнена по верху) */
.dz-pane .di-sec-h > .di-sec-t { min-height: var(--ctl-h); }

/* ссылка-действие в теле блока («+ Добавить позицию», «Повторить», «Показать») */
.dz-pane .di-link {
  position: relative; display: inline-flex; align-items: center; gap: 6px; padding: 2px 0;
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; color: var(--dz-link); background: transparent; border: 0;
}
.dz-pane .di-link:hover { color: var(--dz-link); text-decoration: underline; text-underline-offset: 3px; }
/* зона нажатия ≥44 px без сдвига раскладки (канон tap-target, как `.dz-lnk`) */
.dz-pane .di-link::after { content: ""; position: absolute; inset: -12px -6px; }
.dz-pane .di-sec-h .di-link::after { inset: -2px 0; }

/* фокус с клавиатуры — одно кольцо у всех кнопок блоков */
.dz-pane :is(.di-btn, .primary, .di-ask-send, .dc-a, .dbg-more, .cc-btn, .crm-act-more, .crmw-cfg-b, .crmb-act, .ghost, .di-link):focus-visible {
  outline: 2px solid var(--dz-link); outline-offset: 2px;
}
.dz-pane :is(.di-btn, .primary, .dc-a, .crmb-act, .ghost, .cc-btn):disabled { opacity: .5; cursor: default; box-shadow: none; }

/* ── 2 · ПОЛЯ, СЕЛЕКТЫ, TEXTAREA ─────────────────────────────────────────────
   Одна дверь на все поля блоков: утопленная подложка `--input-bg`, кромка, шрифт вида (у полей
   браузер отдавал Arial), фокус-кольцо. Инлайн-правки, у которых своя форма (строка доп. поля,
   «+ добавить шаг», статус этапа цветом), — исключены по классу. Галочки/радио — не поля. */
.dz-pane :where(input:not([type="checkbox"], [type="radio"], [type="file"], [type="range"], [type="color"], [type="hidden"], [type="button"], [type="submit"]), select, textarea):not(.ccx-in, .di-addstep-in, .dph-st, .hidden) {
  box-sizing: border-box; min-height: var(--ctl-h); max-width: 100%;
  padding: 8px 14px; border: 1px solid var(--dz-edge2); border-radius: var(--ctl-r);
  font-family: inherit; font-size: 15px; font-weight: 500; line-height: 1.35;
  color: var(--dz-text); background-color: var(--input-bg); box-shadow: none;
}
.dz-pane :where(textarea):not(.ccx-in) { min-height: 88px; line-height: 1.5; }
.dz-pane :where(select):not(.dph-st) { padding-right: 38px; background-position: right 12px center; }
/* шрифт вида — у ВСЕХ полей, и у инлайн-правок со своей формой (браузер отдаёт полям Arial) */
.dz-pane :where(input, select, textarea) { font-family: inherit; }
/* ряд «сумма · валюта · %»: одна высота ряда у трёх соседей (канон control-size); сумма — крупно и
   жирно, валюта узкая по замыслу — отступ под шеврон меньше, чтобы «RUB» не резался */
.dz-pane .deal-amount-in { font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; }
.dz-pane .deal-cur { padding-left: 10px; padding-right: 26px; background-position: right 7px center; font-weight: 700; }
.dz-pane :where(input, textarea)::placeholder { color: var(--dz-text3); opacity: 1; }
.dz-pane :where(input:not([type="checkbox"], [type="radio"]), select, textarea):not(.ccx-in, .di-addstep-in, .dph-st):hover { border-color: color-mix(in srgb, var(--dz-link) 40%, var(--dz-edge2)); }
.dz-pane :where(input:not([type="checkbox"], [type="radio"]), select, textarea):not(.ccx-in, .di-addstep-in, .dph-st):focus {
  outline: none; border-color: var(--dz-link); box-shadow: var(--dz-ring);
}
/* поле-кнопка выбора (ответственный, модель оплаты, шаблон) — та же форма, что у поля */
.dz-pane .ccpp-field:not(.ccx-user) {
  min-height: var(--ctl-h); padding: 0 12px; border: 1px solid var(--dz-edge2); border-radius: var(--ctl-r);
  font-family: inherit; font-size: 15px; color: var(--dz-text); background: var(--input-bg);
}
.dz-pane .ccpp-field:not(.ccx-user):hover { border-color: color-mix(in srgb, var(--dz-link) 40%, var(--dz-edge2)); }
.dz-pane .ccpp-field.open { border-color: var(--dz-link); box-shadow: var(--dz-ring); }
.dz-pane .ccpp-field > svg { color: var(--dz-text2); }
/* открытое поле добавления (пункт · задача · дело): кольцо — признак фокуса, а не вечный ореол */
.dz-pane .crmb-new { margin-top: 6px; border-color: var(--dz-edge2); box-shadow: none; }
.dz-pane .crmb-new:focus { border-color: var(--dz-link); box-shadow: var(--dz-ring); }

/* галочка строки (дела · задачи · чек-лист) — крупнее, кромка видна в обеих темах */
.dz-pane .crmb-ck {
  position: relative; width: 22px; height: 22px; border-radius: 7px;
  border: 1.5px solid color-mix(in srgb, var(--dz-text) 34%, transparent); background: var(--input-bg); color: #fff;
}
.dz-pane .crmb-ck:hover { border-color: var(--dz-link); }
.dz-pane .crmb-ck.on { background: var(--dz-ok); border-color: var(--dz-ok); color: var(--dz-bg); }
.dz-pane .crmb-ck .ic { width: 14px; height: 14px; }
.dz-pane .crmb-ck::after { content: ""; position: absolute; inset: -11px; }

/* ── 3 · ЧИПЫ СТАТУСОВ ───────────────────────────────────────────────────────
   Язык «Обзора» (`.dz-tag`): 13 px / 700, текст токеном, подложка 14 %, кольцо inset 1px 26 %.
   ok · bad · warn · inv(ссылка) · нейтральный. Цвет всегда вместе со словом (канон accent). */
.dz-pane :is(.dc-chip, .dph-chip, .dpay-pct, .crmb-due, .crm-act-pill, .crm-act-none) {
  display: inline-flex; align-items: center; gap: 5px; box-sizing: border-box; min-height: 24px;
  padding: 2px 10px; border: 0; border-radius: 10px;
  font-size: 13px; font-weight: 700; line-height: 1.35; letter-spacing: 0; white-space: nowrap;
  color: var(--dz-text2); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane :is(.dc-chip, .dph-chip, .crmb-due, .crm-act-pill, .crm-act-none) svg.ic { width: 13px; height: 13px; flex: none; }
/* `.dz-pane.dz-pane`: базовые тёмные правила `html[data-theme="dark"] .dc-chip.dc-ok` весят (0,3,1) —
   повтор класса вкладки поднимает до (0,4,0) без `!important` */
.dz-pane.dz-pane :is(.dc-chip, .dph-chip).dc-ok, .dz-pane .crmb-cnt.ok {
  color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-ok) 26%, transparent);
}
.dz-pane.dz-pane :is(.dc-chip, .dph-chip).dc-bad, .dz-pane .crmb-due.over, .dz-pane .crm-act-pill.over {
  color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent);
}
.dz-pane.dz-pane :is(.dc-chip, .dph-chip).dc-warn, .dz-pane.dz-pane .dph-chip.dph-block, .dz-pane .crmb-due.today, .dz-pane .crm-act-pill.today, .dz-pane .crm-act-none {
  color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 26%, transparent);
}
.dz-pane.dz-pane :is(.dc-chip, .dph-chip).dc-info, .dz-pane.dz-pane .dph-chip.dph-par, .dz-pane .dpay-pct {
  color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-link) 26%, transparent);
}
.dz-pane.dz-pane :is(.dc-chip, .dph-chip).dc-muted { color: var(--dz-text2); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge); }
.dz-pane .dpay-pct { font-variant-numeric: tabular-nums; }
/* «за этап…» — чип-КНОПКА привязки: пунктир говорит «нажми, чтобы выбрать» (как в базе) */
.dz-pane .dpay-phase-add { cursor: pointer; background: transparent; box-shadow: inset 0 0 0 1px transparent; outline: 1px dashed var(--dz-edge2); outline-offset: -1px; }
.dz-pane .dpay-phase-add:hover { color: var(--dz-link); outline-color: var(--dz-link); }
/* крестик внутри чипа (снять зависимость) — цель на сенсоре без сдвига строки */
.dz-pane .dph-chip-x { position: relative; width: 18px; height: 18px; opacity: .8; color: inherit; }
.dz-pane .dph-chip-x::after { content: ""; position: absolute; inset: -13px -6px; }   /* 18 + 26 = 44 по вертикали */
/* метки сделки (цвет задаёт сама метка через --lc) — только размер языка вида */
.dz-pane .crmb-tag, .dz-pane .crmb-tag-add { min-height: 28px; padding: 3px 12px; font-size: 13px; font-weight: 700; border-radius: 14px; }
.dz-pane .crmb-tag-add { color: var(--dz-text2); border-color: var(--dz-edge2); }
.dz-pane .crmb-tag-add:hover { color: var(--dz-text); border-color: var(--dz-link); background: var(--hover); }
.dz-pane .crmb-tag-add .ic { width: 14px; height: 14px; }

/* ── 4 · СЧЁТЧИКИ ────────────────────────────────────────────────────────────
   Число рядом с заголовком блока и у разделителя «Закрытые»: плотная таблетка, цифры одной ширины. */
.dz-pane .crmb-cnt, .dz-pane .crm-act-sep i, .dz-pane .di-sec-t .tw-seg-badge {
  /* ревью 12.10 (#37): счётчик не сжимается длинным заголовком («5/10» выходил за таблетку) */
  flex: none;
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  min-width: 26px; height: 24px; margin-left: 4px; padding: 0 8px; border: 0; border-radius: 12px;
  font-size: 13px; font-weight: 800; letter-spacing: 0; text-transform: none; font-variant-numeric: tabular-nums;
  color: var(--dz-text); background: var(--dz-track); box-shadow: none;
}
.dz-pane .crmb-cnt.hot { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent); }
/* разделитель «Закрытые N» — подпись капсом, как заголовки блоков */
.dz-pane .crm-act-sep { margin: 14px 0 4px; font-size: 13px; font-weight: 700; letter-spacing: .06em; color: var(--dz-text2); }

/* ── 5 · ПУСТО · ЗАГРУЗКА · ОТКАЗ ────────────────────────────────────────────
   Пустое состояние — обычный текст вида (15 px, вторичный), не мелкая серая сноска. */
.dz-pane :is(.di-empty, .crmb-empty, .dli-cat-empty, .di-ask-empty, .deal-acts-empty, .crmacc-empty) {
  font-size: 15px; line-height: 1.5; color: var(--dz-text2);
}
.dz-pane .di-empty b, .dz-pane .crmb-empty b { color: var(--dz-text); }
/* «Повторить» внутри отказа — ссылкой, на своей строке не нужна */
.dz-pane .di-empty .di-link { font-size: 15px; vertical-align: baseline; }
/* скелетон строк — кости в размер строки вида (14 px), на стекле видны в обеих темах */
.dz-pane .cc-skel-b { gap: 12px; padding: 4px 0; }
.dz-pane .cc-skel {
  border-radius: 7px; background-color: color-mix(in srgb, var(--dz-text) 9%, transparent);
  background-image: linear-gradient(100deg, transparent 30%, color-mix(in srgb, var(--dz-text) 16%, transparent) 50%, transparent 70%);
}
.dz-pane .cc-skel-line { height: 14px; }
/* отказ загрузки одной дверью (`ccLoadFail`): причина + «Повторить» — внутри блока слева, без
   страничных отступов 48 px */
.dz-pane .cc-cv-empty.cc-lf { align-items: flex-start; gap: 10px; padding: 4px 0; text-align: left; font-size: 15px; color: var(--dz-text2); }
.dz-pane .cc-lf-why { font-size: 14px; opacity: 1; color: var(--dz-text3); }

/* ── 6 · ЗНАЧКИ ШАПКИ БЛОКА (ширина · скрыть · перетащить) ───────────────────
   На мыши — по наведению (прогрессивное раскрытие, как в базе). На сенсоре видны всегда и крупнее;
   шапка резервирует под них место справа (в базе резерв 92 px перебивался отступом вида 20 px —
   ряд «Звонок · Встреча…» на телефоне уезжал за край на 45 px). */
.dz-pane .cblk-b { width: 30px; height: 30px; border-radius: 9px; color: var(--dz-text2); }
.dz-pane .cblk-b:hover { color: var(--dz-text); background: var(--dz-glass2); }
.dz-pane .cblk-b .ic { width: 16px; height: 16px; }
.dz-pane .crmw-blk:hover .cblk-acts, .dz-pane .cblk-acts:focus-within { max-width: 140px; }
/* ревью 12.10 (#69): на мыши место под значки шапки ЗАРЕЗЕРВИРОВАНО — появляются они
   прозрачностью, и действия шапки («+ Пункт», «Набор · Из сметы») при наведении не прыгают */
@media (hover: hover) { .dz-pane .cblk-acts { max-width: 140px; margin-left: 6px; } }
@media (hover: none) {
  /* Первая строка шапки — ТОЛЬКО заголовок: он занимает строку целиком и держит справа место под
     значки (30 × n + 2 × (n−1) + 8 до подписи; у боковых блоков значка два). Действия шапки
     («Звонок · Встреча…», «+ Пункт», «Набор · Из сметы», «Сформировать КП») встают следующими
     строками ВО ВСЮ ширину и по левому краю — а не в узкую щель слева от значков (там «+ Пункт»
     висел посередине, а «Сформировать КП» ломался в две строки). */
  .dz-pane .di-sec-h.has-cblk { padding-right: 20px; flex-wrap: wrap; justify-content: flex-start; align-items: center; column-gap: 4px; row-gap: 4px; }
  .dz-pane .di-sec-h.has-cblk > .di-sec-t { flex: 1 0 100%; box-sizing: border-box; margin-right: 0; padding-right: 96px; }
  .dz-pane .di-sec-h.has-cblk:not(:has(> .cblk-acts > :nth-child(3))) > .di-sec-t { padding-right: 64px; }
  .dz-pane .di-sec-h.has-cblk > :not(.di-sec-t):not(.cblk-acts) { margin-left: 0; }
  /* ряд ссылок-действий — по краю подписи: подсветка наведения выходит в поле на 10 px */
  .dz-pane .di-sec-h.has-cblk > :is(.crm-act-add, .crmb-hacts, .crmb-watch-acts):not(.di-sec-t) { flex: 1 1 100%; margin: 0 0 0 -10px; justify-content: flex-start; flex-wrap: wrap; }
  .dz-pane .di-sec-h.has-cblk > :is(.crmb-act, .di-link):first-of-type { margin-left: -10px; }
  /* …но не та ссылка, что стоит в строке ПОСЛЕ сегмента («Список | Потоки · Набор»): ей
     отрицательный отступ наезжал на сегмент на 6 px (ревью 12.10, #38) */
  .dz-pane .di-sec-h.has-cblk > .cc-seg ~ :is(.crmb-act, .di-link) { margin-left: 0; }
  .dz-pane .di-sec-h.has-cblk > .cblk-acts { top: 21px; right: 14px; gap: 2px; }
  .dz-pane .cblk-b { width: 30px; height: 30px; position: relative; }
  /* поле промаха — по вертикали до 44 и по 1 px в зазор соседа (канон tap-target: только туда, где пусто;
     шире не даёт сосед — три значка стоят вплотную, а место отнято у заголовка) */
  .dz-pane .cblk-b::after { content: ""; position: absolute; inset: -7px -1px; }
}
/* УЗКАЯ КОЛОНКА НА УСТРОЙСТВЕ С МЫШЬЮ — та же раскладка шапки, что на сенсоре выше. В строку
   «заголовок · действия · значки» колонка уже ~500 px не помещается, а переноса на мыши не было:
   «Сформировать КП» и значки уезжали за край и резались overflow'ом блока (замер 21.10 на проде,
   окно 390: «Позиции сделки» — значки 392–454 при крае карточки 370, «Досье лида» — на 126 px за
   краем). Порог — общий порог узкой колонки `dz` (640). Значки на мыши по-прежнему появляются
   наведением (opacity из корневого правила), место под ними держит строка заголовка — 64 px, под
   ДВА значка: «ширины» в колонке уже 720 нет (правило ниже).
   Пара с блоком `@media (hover: none)` выше: правишь геометрию там — правь и здесь. */
@container dz (max-width: 640px) {
  @media (hover: hover) {
    .dz-pane .di-sec-h.has-cblk { position: relative; padding-right: 20px; flex-wrap: wrap; justify-content: flex-start; align-items: center; column-gap: 4px; row-gap: 4px; }
    .dz-pane .di-sec-h.has-cblk > .di-sec-t { flex: 1 0 100%; box-sizing: border-box; margin-right: 0; padding-right: 64px; }
    .dz-pane .di-sec-h.has-cblk > :not(.di-sec-t):not(.cblk-acts) { margin-left: 0; }
    .dz-pane .di-sec-h.has-cblk > :is(.crm-act-add, .crmb-hacts, .crmb-watch-acts):not(.di-sec-t) { flex: 1 1 100%; margin: 0 0 0 -10px; justify-content: flex-start; flex-wrap: wrap; }
    .dz-pane .di-sec-h.has-cblk > :is(.crmb-act, .di-link):first-of-type { margin-left: -10px; }
    .dz-pane .di-sec-h.has-cblk > .cc-seg ~ :is(.crmb-act, .di-link) { margin-left: 0; }
    .dz-pane .di-sec-h.has-cblk > .cblk-acts { position: absolute; top: 21px; right: 14px; gap: 2px; margin-left: 0; }
  }
}
/* В колонке `dz` уже 720 значка «ширина» нет (`[data-cbact="size"]` скрыт порогом 719.98 ниже) —
   видны ДВА значка, и заголовок держит место под два (64), а не под три (96) по числу кнопок в
   разметке: иначе «Позиции сделки» ломалось в две строки при свободных 32 px (замер 21.10,
   окно 390). Пара к сенсорному блоку выше — на мыши то же стоит в узком блоке над этим. */
@container dz (max-width: 719.98px) {
  @media (hover: none) { .dz-pane .di-sec-h.has-cblk > .di-sec-t { padding-right: 64px; } }
}

/* ── 7 · ИКОНКИ-ДЕЙСТВИЯ СТРОК (удалить · открыть · переставить · скачать) ─────
   Одна форма: прозрачная клетка `--dz-ib`, радиус 10, значок вторичным цветом; удаление краснеет
   токеном беды. Живут по наведению — на сенсоре видны всегда (наводить нечем). */
.dz-pane :is(.dph-a, .dinv-ib, .crmb-ckx, .crmb-taskx, .crmb-watch-x, .crmb-note-del, .crm-act-x, .crm-act-go, .ccx-row-cfg, .tf-dl, .tf-del, .dli-del, .di-step-del, .di-step-plan) {
  position: relative; display: inline-flex; align-items: center; justify-content: center; flex: none;
  box-sizing: border-box; width: var(--dz-ib); height: var(--dz-ib); padding: 0;
  border: 0; border-radius: 10px; background: transparent; color: var(--dz-text2); box-shadow: none;
}
.dz-pane :is(.dph-a, .dinv-ib, .crmb-ckx, .crmb-taskx, .crmb-watch-x, .crmb-note-del, .crm-act-x, .crm-act-go, .ccx-row-cfg, .tf-dl, .tf-del, .dli-del, .di-step-del, .di-step-plan):hover {
  color: var(--dz-text); background: var(--dz-glass2); border-color: transparent;
}
.dz-pane :is(.dph-a, .dinv-ib, .crmb-ckx, .crmb-taskx, .crmb-watch-x, .crmb-note-del, .crm-act-x, .crm-act-go, .ccx-row-cfg, .tf-dl, .tf-del, .dli-del, .di-step-del, .di-step-plan) svg.ic { width: 16px; height: 16px; }
.dz-pane :is(.dph-a.bad, .crmb-ckx, .crmb-taskx, .crmb-watch-x, .crmb-note-del, .crm-act-x, .tf-del, .dli-del, .di-step-del):hover {
  color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent);
}
.dz-pane .dph-a.on { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent); }
.dz-pane .dinv-ib.ok { color: var(--dz-ok); }
.dz-pane .dph-grip { color: var(--dz-text2); }
/* ревью 12.10 (#81): фокус с клавиатуры на значке строки виден — кольцо и сам значок */
.dz-pane :is(.dph-a, .dinv-ib, .crmb-ckx, .crmb-taskx, .crmb-watch-x, .crmb-note-del, .crm-act-x, .crm-act-go, .ccx-row-cfg, .tf-dl, .tf-del, .dli-del, .di-step-del, .di-step-plan):focus-visible {
  opacity: 1; outline: 2px solid var(--dz-link); outline-offset: 1px;
}
.dz-pane :is(.dph-acts, .crm-act-x, .crmb-note-del, .ccx-row-cfg, .dli-del, .di-step-del, .di-step-plan, .crmb-ckx, .crmb-taskx, .crmb-watch-x):focus-within { opacity: 1; }
@media (hover: none) {
  .dz-pane :is(.dph-acts, .crm-act-x, .crmb-note-del, .ccx-row-cfg, .dli-del, .di-step-del, .di-step-plan, .dph-grip, .crmb-ckx, .crmb-taskx, .crmb-watch-x) { opacity: 1; }
  .dz-pane :is(.dph-a, .dinv-ib, .crmb-ckx, .crmb-taskx, .crmb-watch-x, .crmb-note-del, .crm-act-x, .crm-act-go, .ccx-row-cfg, .tf-dl, .tf-del, .dli-del, .di-step-del, .di-step-plan)::after { content: ""; position: absolute; inset: -6px 0; }   /* 32 + 12 = 44 */
}

/* ── 8 · СТРОКИ СПИСКОВ ──────────────────────────────────────────────────────
   Строка — 44 px и выше, подсветка наведения `--hover` с радиусом 12; текст строки 15 px. Подсветка
   выходит на 10 px за поле текста, чтобы подпись стояла ровно по краю заголовка блока. */
.dz-pane :is(.crmb-task, .crmb-ckrow, .crm-act-row, .crmb-watch-it, .crmb-note) {
  min-height: 44px; box-sizing: border-box; gap: 12px; margin: 0 -10px; padding: 6px 10px; border-radius: 12px;
}
.dz-pane :is(.crmb-task, .crmb-ckrow, .crm-act-row, .crmb-watch-it, .crmb-note):hover { background: var(--hover); }
.dz-pane .crmb-ckrow { align-items: center; }
.dz-pane .crm-act-row + .crm-act-row { box-shadow: none; }
.dz-pane :is(.crmb-task-t, .crmb-ckt, .crm-act-t, .crmb-watch-nm) { font-size: 15px; line-height: 1.4; color: var(--dz-text); }
/* название задачи — кнопка-текст: глобальное `button:hover { background: var(--active) }` рисовало
   под ним серую плашку поверх подсветки строки — у текста-ссылки плашки нет, только цвет */
.dz-pane .crmb-task-t:hover { color: var(--dz-link); background: none; }
.dz-pane :is(.crmb-task.done .crmb-task-t, .crmb-ckrow.done .crmb-ckt, .crm-act-row.done .crm-act-t) { color: var(--dz-text2); }
.dz-pane :is(.crmb-ckby, .crm-act-res, .crmb-num) { font-size: 13px; color: var(--dz-text2); }
.dz-pane .crmb-num { font-weight: 700; }
.dz-pane :is(.crmb-task, .crmb-watch-it, .crm-act-row) .tw-av { width: 28px; height: 28px; font-size: 12px; }
/* срок дела — кнопка-чип: та же форма, что у чипов статуса */
.dz-pane .crm-act-when {
  display: inline-flex; align-items: center; gap: 5px; min-height: 28px; padding: 2px 10px; border-radius: 10px;
  font-size: 13px; font-weight: 700; color: var(--dz-text2); background: var(--dz-glass2); border: 0; box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .crm-act-when:hover { color: var(--dz-text); box-shadow: inset 0 0 0 1px var(--dz-link); }
.dz-pane .crm-act-when.none { box-shadow: inset 0 0 0 1px var(--dz-edge2); background: transparent; }
.dz-pane .crm-act-when.over { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent); }
.dz-pane .crm-act-when.today { color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 26%, transparent); }
.dz-pane .crm-act-when .ic { width: 13px; height: 13px; }
.dz-pane .crm-act-ic { color: var(--dz-text2); }
.dz-pane .crm-act-row.over .crm-act-ic { color: var(--dz-bad); }
.dz-pane .crm-act-who { width: 32px; height: 32px; border-radius: 10px; color: var(--dz-text2); }

/* ── 9 · СЕГМЕНТ ВНУТРИ БЛОКА (канон `.cc-seg`, только размер языка вида) ───── */
.dz-pane .cc-seg > * { font-size: 14px; font-weight: 650; color: var(--dz-text2); }
.dz-pane .cc-seg > *.on, .dz-pane .cc-seg > *.active { color: var(--dz-text); font-weight: 800; }
/* компактный сегмент в шапке блока стоит в ряду с действиями — та же высота ряда `--ctl-h` */
.dz-pane .cc-seg-sm { min-height: var(--ctl-h); padding: 3px; border-radius: var(--ctl-r); }
.dz-pane .cc-seg-sm > * { padding: 0 12px; line-height: calc(var(--ctl-h) - 8px); border-radius: calc(var(--ctl-r) - 3px); }
/* ── money-a ── */
/* ═══════════════════════════════════════════════════════════════════════════
   💰 «ГЛУБИНА» · ВКЛАДКА «ДЕНЬГИ» (money-a): сводка вкладки + блоки
   «Деньги сделки» (.di-budget) · «Оплаты» (.di-payments) · «Часы и ставки» (.di-hours) ·
   «Счета» (.di-invoices). Общие контролы (кнопки, чипы, поля, иконки строк) — из lab/common;
   здесь только раскладка и типографика СВОИХ блоков, каждый селектор под своим корнем: классы
   `.dph-*` общие с «Этапами», `.dpay-num(s)/.dpay-warn` — у «Оплат» и «Часов», `.dinv-*` — у
   «Счетов» и «Актов». Язык «Обзора»: текст 15–16, подписи 13–14, цифры 18–32 / 800 tabular-nums,
   внутренние плитки — `--dz-glass2` радиус 16–18 с кромкой inset, статусы — токены `--dz-*`.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 0 · СВОДКА ВКЛАДКИ (DZ_SUM.money → .dz-metrics.dz-msum) ──────────────────────────────
   Плитки — разметка «Обзора» (.dz-metric); здесь только тон подписи и кольца словами-токенами. */
.dz-pane .dz-msum .dz-metric-s { overflow-wrap: break-word; }
.dz-pane .dz-msum .dz-metric-s b { font-weight: 700; }
.dz-pane .dz-msum .dz-metric-s b.warn { color: var(--dz-warn); }
.dz-pane .dz-msum .dz-metric-s b.bad { color: var(--dz-bad); }
.dz-pane .dz-msum .dz-metric-s b.ok { color: var(--dz-ok); }
/* кольцо «Обзора» прибито акцентом вида — у расхода бюджета оно говорит тоном (вместе со словом) */
.dz-pane .dz-msum .dz-ring.warn { background: conic-gradient(var(--dz-warn) calc(var(--p) * 1%), var(--dz-track) 0); }
.dz-pane .dz-msum .dz-ring.ok { background: conic-gradient(var(--dz-ok) calc(var(--p) * 1%), var(--dz-track) 0); }

/* ── 1 · ОБЩАЯ ПОЛОСА ЦИФР (числа «Деньги сделки» и «Часов») ──────────────────────────────
   Одна стеклянная плитка, ячейки без своих подложек: сколько бы чисел ни пришло (5 или 7 —
   у кого есть право на себестоимость), рядом нет дыр и «осиротевших» плиток. Подпись сверху
   (как у плиток «Обзора»), число под ней — крупно. */
.dz-pane .di-budget .dbg-nums, .dz-pane .di-hours .dpay-nums {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); gap: 16px 22px;
  padding: 16px 20px; border-radius: 18px; background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .di-budget .dbg-n, .dz-pane .di-hours .dpay-num {
  /* column-reverse: подпись сверху; flex-start = низ ячейки — числа ряда стоят на одной линии,
     даже когда соседняя подпись («Ждёт одобрения») переносится в две строки */
  display: flex; flex-direction: column-reverse; justify-content: flex-start; gap: 4px;
  min-width: 0; padding: 0; border-radius: 0; background: none; box-shadow: none;
}
.dz-pane .di-budget .dbg-n-v, .dz-pane .di-hours .dpay-num-v {
  font-size: 22px; line-height: 1.15; font-weight: 800; letter-spacing: -.01em; font-variant-numeric: tabular-nums;
  color: var(--dz-text); overflow-wrap: anywhere;
}
.dz-pane .di-budget .dbg-n-l, .dz-pane .di-hours .dpay-num-l { margin: 0; font-size: 13px; line-height: 1.3; font-weight: 600; color: var(--dz-text2); }
/* тон — словом-токеном (база прибивала #hex: 3.0–4.3 на стекле) */
.dz-pane .di-budget .dbg-n.ok .dbg-n-v, .dz-pane .di-hours .dpay-num.ok .dpay-num-v { color: var(--dz-ok); }
.dz-pane .di-budget .dbg-n.warn .dbg-n-v, .dz-pane .di-hours .dpay-num.warn .dpay-num-v { color: var(--dz-warn); }
.dz-pane .di-budget .dbg-n.bad .dbg-n-v, .dz-pane .di-hours .dpay-num.bad .dpay-num-v { color: var(--dz-bad); }
.dz-pane .di-budget .dbg-n.bad { background: none; box-shadow: none; }
.dz-pane .di-budget .dbg-n.bad .dbg-n-l b { color: var(--dz-bad); font-weight: 700; }
.dz-pane .di-budget .dbg-dot { width: 7px; height: 7px; background: var(--dz-bad); }

/* ── 2 · ПЛАШКИ-ПРЕДУПРЕЖДЕНИЯ (канон accent: значок + слово, подложка 12 % + кромка 26 %) ──
   Текст плашки — голые текстовые узлы вперемешку с <b> (разметка блока): во флексе каждый узел
   стал бы отдельной колонкой, и на телефоне значок уезжал на свою строку. Поэтому плашка —
   обычный абзац, значок висит в левом поле, кнопка выхода — своей строкой под текстом. */
.dz-pane :is(.di-payments, .di-hours) .dpay-warn, .dz-pane .di-budget .dbg-line {
  display: block; position: relative; box-sizing: border-box;
  padding: 14px 18px 14px 50px; border-radius: 16px; font-size: 15px; line-height: 1.45; color: var(--dz-text);
  background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane :is(.di-payments, .di-hours) .dpay-warn { background: color-mix(in srgb, var(--dz-warn) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 26%, transparent); }
.dz-pane :is(.di-payments, .di-hours) .dpay-warn.hot { background: color-mix(in srgb, var(--dz-bad) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent); }
.dz-pane :is(.di-payments, .di-hours) .dpay-warn > svg.ic, .dz-pane .di-budget .dbg-line > svg.ic { position: absolute; left: 18px; top: 16px; width: 18px; height: 18px; }
.dz-pane :is(.di-payments, .di-hours) .dpay-warn > svg.ic { color: var(--dz-warn); }
.dz-pane :is(.di-payments, .di-hours) .dpay-warn.hot > svg.ic { color: var(--dz-bad); }
.dz-pane :is(.di-payments, .di-hours) .dpay-warn b { font-weight: 800; font-variant-numeric: tabular-nums; }
.dz-pane .di-payments .dpay-warn .di-btn { display: flex; width: fit-content; margin: 10px 0 0; }

/* ── 3 · «ДЕНЬГИ СДЕЛКИ» ─────────────────────────────────────────────────────────────────
   В «Глубине» сумма · выставлено · оплачено · осталось стоят в карточке денег героя, просрочка —
   в «Просрочено» над вкладками. Блок здесь — ПОДРОБНОСТИ (сгорание, часы, удержание, модель):
   они раскрыты сразу (patch.py, только при `dzOn()`), повтор цифр шапки и строки просрочки
   спрятан. Нет подробностей (денег почти нет) — числа остаются: пустым блок не бывает. */
.dz-pane .di-budget .dbg { gap: 12px; }
.dz-pane .di-budget .dbg:has(> .dbg-rows) > .dbg-nums,
.dz-pane .di-budget .dbg > .dbg-line.alert,
.dz-pane .di-budget .dbg-more,
.dz-pane .di-budget .dbg-line.dbg-model { display: none; }
.dz-pane .di-budget .dbg-rows { display: flex; flex-direction: column; gap: 12px; }
.dz-pane .di-budget .dbg-line > svg.ic { color: var(--dz-link); }
.dz-pane .di-budget .dbg-line > span { color: var(--dz-text2); }
.dz-pane .di-budget .dbg-line b { color: var(--dz-text); font-weight: 800; font-variant-numeric: tabular-nums; }
.dz-pane .di-budget .dbg-line.alert { background: color-mix(in srgb, var(--dz-warn) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 26%, transparent); }
.dz-pane .di-budget .dbg-line.alert > svg.ic { color: var(--dz-warn); }
.dz-pane .di-budget .dbg-line.alert > span { color: var(--dz-text); }
/* сгорание — первым: две полосы одной длины, проценты крупно, фраза сервера словами */
.dz-pane .di-budget .dbg-burn {
  order: -1; display: flex; flex-direction: column; gap: 12px; padding: 18px 20px; border-radius: 18px;
  background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .di-budget .dbg-burn.alert { background: color-mix(in srgb, var(--dz-warn) 10%, var(--dz-glass2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 26%, transparent); }
.dz-pane .di-budget .dbg-burn-g { display: grid; grid-template-columns: 112px minmax(0, 1fr) 64px; align-items: center; gap: 14px; }
.dz-pane .di-budget .dbg-burn-l { flex: none; font-size: 14px; font-weight: 600; color: var(--dz-text2); }
.dz-pane .di-budget .dbg-burn-t { display: block; height: 10px; border-radius: 5px; background: var(--dz-track); }
/* заливка — строчный <span>: без display:block ширина ему не задаётся и полоса пустая (баг базы,
   чинится и в «Штиле» — patch.py) */
.dz-pane .di-budget .dbg-burn-f { display: block; height: 100%; border-radius: 5px; background: var(--dz-inv); }
.dz-pane .di-budget .dbg-burn-g.spent .dbg-burn-f { background: var(--dz-warn); }
.dz-pane .di-budget .dbg-burn-g.spent.hot .dbg-burn-f { background: var(--dz-bad); }
.dz-pane .di-budget .dbg-burn-p { flex: none; font-size: 18px; font-weight: 800; color: var(--dz-text); text-align: right; }
.dz-pane .di-budget .dbg-burn-say { font-size: 15px; line-height: 1.45; color: var(--dz-text2); }
.dz-pane .di-budget .dbg-burn.alert .dbg-burn-say { color: var(--dz-text); }
.dz-pane .di-budget .dbg-flat { font-size: 15px; line-height: 1.5; color: var(--dz-text2); }
/* во вкладке «Деньги» над блоком стоят плитки сводки: вывод сгорания («Выставлено … обгоняет
   работу …») — это плитка «Расход бюджета», «не выставлено … · ждут одобрения …» (метка `dbg-dup`,
   patch.py п.13) — плитка «Часы без счёта». Слово в слово второй раз не говорим: остаются шкалы
   и план/факт часов. Строка часов без «не выставлено» — уже не тревога: нейтральное стекло. */
.dz-pane[data-dzpane="money"] .di-budget .dbg-burn-say,
.dz-pane[data-dzpane="money"] .di-budget .dbg-dup { display: none; }
.dz-pane[data-dzpane="money"] .di-budget .dbg-line.dbg-hours.alert { background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge); }
.dz-pane[data-dzpane="money"] .di-budget .dbg-line.dbg-hours.alert > svg.ic { color: var(--dz-link); }
.dz-pane[data-dzpane="money"] .di-budget .dbg-line.dbg-hours.alert > span { color: var(--dz-text2); }

/* ── 4 · «ОПЛАТЫ» ────────────────────────────────────────────────────────────────────────
   Пять чисел над графиком (сумма · в графике · выставлено · оплачено · остаток) — это карточка
   денег героя слово в слово; «в графике ≠ сумма» и так говорит плашка расхождения. Прячем. */
.dz-pane .di-payments .dpay-nums { display: none; }
.dz-pane .di-payments .di-sec-b { gap: 14px; }
/* модель оплаты · удержание · фраза модели — одна строка полей ряда (--ctl-*) */
.dz-pane .di-payments .dpay-model { align-items: flex-end; gap: 10px 14px; }
.dz-pane .di-payments .dpay-f { gap: 6px; }
.dz-pane .di-payments .dpay-f-l { font-size: 13px; font-weight: 600; letter-spacing: 0; color: var(--dz-text2); }
.dz-pane .di-payments .dpay-model-i { min-width: 220px; }
.dz-pane .di-payments .dpay-model .ccpp-field { min-width: 220px; }
.dz-pane .di-payments .dpay-ret-i { width: 110px; font-variant-numeric: tabular-nums; }
.dz-pane .di-payments .dpay-model-say { flex: 1 1 220px; padding-bottom: 10px; font-size: 14px; line-height: 1.4; color: var(--dz-text2); }
/* строка графика: [ручка] название ··· % сумма / статус · срок · этап ··· действия */
.dz-pane .di-payments .dpay-list { gap: 10px; }
.dz-pane .di-payments .dpay-row {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; column-gap: 14px; row-gap: 10px;
  padding: 14px 18px 14px 26px; border: 0; border-radius: 18px;
  background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .di-payments .dpay-row:hover { box-shadow: inset 0 0 0 1px var(--dz-edge2); }
.dz-pane .di-payments .dpay-b { display: contents; }
/* ручка порядка живёт в левом поле строки (появляется по наведению, как в базе) — название стоит
   ровно по краю, без пустой колонки под невидимой ручкой */
.dz-pane .di-payments .dpay-row > .dph-grip { position: absolute; left: 3px; top: 50%; margin: -16px 0 0; width: 22px; height: 32px; }
.dz-pane .di-payments .dpay-row > .dph-grip svg.ic { width: 16px; height: 16px; }
.dz-pane .di-payments .dpay-row .dph-h { grid-column: 1 / -1; grid-row: 1; gap: 10px; align-items: center; }
.dz-pane .di-payments .dpay-row .dph-meta { grid-column: 1; grid-row: 2; gap: 8px 10px; }
.dz-pane .di-payments .dpay-row .dph-acts { grid-column: 2; grid-row: 2; justify-self: end; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
/* строка с прошедшим сроком — её действие («Оплата · остаток», «Выставить счёт») видно без
   наведения: это и есть следующий шаг человека во вкладке; остальные — по наведению (база) */
.dz-pane .di-payments .dpay-row.late .dph-acts { opacity: 1; }
.dz-pane .di-payments .dph-t {
  font-size: 16px; line-height: 1.35; font-weight: 700; color: var(--dz-text);
  padding: 2px 6px; margin-left: -6px; border-radius: 8px; overflow-wrap: break-word;
}
.dz-pane .di-payments .dph-t:hover { background: var(--hover); }
.dz-pane .di-payments .dph-t:focus { background: var(--input-bg); box-shadow: inset 0 0 0 1px var(--dz-link); }
.dz-pane .di-payments .dpay-sum { font-size: 18px; font-weight: 800; letter-spacing: -.01em; color: var(--dz-text); }
.dz-pane .di-payments .dph-m { font-size: 14px; color: var(--dz-text2); gap: 6px; white-space: normal; }
.dz-pane .di-payments .dph-m svg.ic { width: 15px; height: 15px; opacity: 1; color: var(--dz-text3); }
.dz-pane .di-payments .dph-m.over { color: var(--dz-bad); font-weight: 700; }
.dz-pane .di-payments .dph-m.over svg.ic { color: var(--dz-bad); }
.dz-pane .di-payments .dph-chip.dph-pay { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-link) 26%, transparent); }
.dz-pane .di-payments .dph-chip.dph-pay:hover { filter: none; background: color-mix(in srgb, var(--dz-link) 18%, transparent); }
/* оплаченная строка — спокойный зелёный, строка с прошедшим сроком — красный (слово — в чипе):
   ОДИН тон с соседними строками «Счетов» — правило общее (раздел 6, «одна суть — один вид») */
/* перетаскиваемая строка — плотное стекло, иначе соседи просвечивают сквозь неё (вес — выше тона
   просрочки: перетаскивают и просроченную) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-payments .dpay-row.dpay-dragging { background: color-mix(in srgb, var(--dz-text) 8%, var(--dz-bg)); box-shadow: inset 0 0 0 1px var(--dz-link), var(--dz-shadow); }
/* шаблоны графика — подпись блока капсом, кнопки-выбор стеклом (common) */
.dz-pane .di-payments .dpay-presets { gap: 10px; padding-top: 4px; }
.dz-pane .di-payments .dpay-presets-l { font-size: 13px; font-weight: 700; letter-spacing: .06em; color: var(--dz-text2); }
.dz-pane .di-payments .dpay-presets-b { gap: 8px; }

/* ── 5 · «ЧАСЫ И СТАВКИ» ─────────────────────────────────────────────────────────────── */
.dz-pane .di-hours .di-sec-b { gap: 14px; }
.dz-pane .di-hours .dhr-top { gap: 10px 14px; }
.dz-pane .di-hours .dhr-top-a { gap: 8px; }
/* ставки: подпись · значение крупно, кнопка справа */
.dz-pane .di-hours .dhr-rate {
  flex-direction: row; flex-wrap: wrap; align-items: center; gap: 8px 24px;
  padding: 14px 18px; border-radius: 16px; background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .di-hours .dhr-rate-v { font-size: 15px; line-height: 1.4; color: var(--dz-text2); }
.dz-pane .di-hours .dhr-rate-v b { font-weight: 800; color: var(--dz-text); font-variant-numeric: tabular-nums; }
.dz-pane .di-hours .dhr-rate-a { margin-left: auto; }
/* строка часа: [галочка] что сделано ··· время  сумма / статус · кто · ставка ··· действие */
.dz-pane .di-hours .dhr-list { gap: 10px; }
.dz-pane .di-hours .dhr-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; column-gap: 14px; row-gap: 10px;
  padding: 14px 18px 14px 16px; border: 0; border-radius: 18px;
  background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .di-hours .dhr-row:hover { box-shadow: inset 0 0 0 1px var(--dz-edge2); }
.dz-pane .di-hours .dhr-b { display: contents; }
.dz-pane .di-hours .dhr-row > .dhr-bill { grid-column: 1; grid-row: 1 / span 2; align-self: center; margin: 0; position: relative; }
.dz-pane .di-hours .dhr-row .dph-h { grid-column: 2 / -1; grid-row: 1; gap: 12px; align-items: baseline; }
.dz-pane .di-hours .dhr-row .dph-meta { grid-column: 2; grid-row: 2; gap: 8px 10px; }
.dz-pane .di-hours .dhr-row .dph-acts { grid-column: 3; grid-row: 2; justify-self: end; gap: 8px; }
.dz-pane .di-hours .dhr-t { font-size: 16px; line-height: 1.35; font-weight: 700; color: var(--dz-text); white-space: normal; overflow-wrap: break-word; }
.dz-pane .di-hours .dhr-min { font-size: 14px; font-weight: 600; color: var(--dz-text2); white-space: nowrap; }
.dz-pane .di-hours .dhr-amt { font-size: 18px; font-weight: 800; letter-spacing: -.01em; color: var(--dz-text); white-space: nowrap; }
.dz-pane .di-hours .dph-m { font-size: 14px; color: var(--dz-text2); white-space: normal; }
.dz-pane .di-hours .dph-m.dhr-cost { color: var(--dz-text3); }
/* галочка «оплачиваемый час» — та же форма, что у галочек строк вида (common .crmb-ck), поле промаха 44 */
.dz-pane .di-hours .dhr-bill > span {
  width: 22px; height: 22px; border-radius: 7px; box-sizing: border-box;
  border: 1.5px solid color-mix(in srgb, var(--dz-text) 34%, transparent); background: var(--input-bg);
}
.dz-pane .di-hours .dhr-bill:hover > span { border-color: var(--dz-link); }
.dz-pane .di-hours .dhr-bill input:checked + span { background: var(--dz-pri); border-color: var(--dz-pri); }
/* галочка внутри — штрихи глифа (повёрнутый уголок), а не рейка */
.dz-pane .di-hours .dhr-bill input:checked + span::after { width: 9px; height: 5px; border-left-width: 1.75px; border-bottom-width: 1.75px; }
.dz-pane .di-hours .dhr-bill input:focus-visible + span { outline: 2px solid var(--dz-link); outline-offset: 2px; }
.dz-pane .di-hours .dhr-bill::after { content: ""; position: absolute; inset: -11px; }

/* ── 6 · «СЧЕТА» (стили блока вставляет JS `dinvEnsureStyles` ПОСЛЕ style.css — перебиваем
   весом `:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane`, а не `!important`) ─────────────────────────────── */
/* итог в шапке — рядом с заголовком, а не посередине шапки (у заголовка уже margin-right:auto) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .di-sec-h .dinv-sum { margin-left: 0; font-size: 14px; font-weight: 600; color: var(--dz-text2); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-list { gap: 10px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; column-gap: 14px; row-gap: 10px;
  padding: 14px 16px 14px 18px; border: 0; border-radius: 18px;
  background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-row:hover { border: 0; box-shadow: inset 0 0 0 1px var(--dz-edge2); }
/* тон строки — ОДИН у «Счетов» и «Оплат»: оплачено — зелёный, срок прошёл — красный (до правки
   просроченная строка «Оплат» оставалась нейтральным стеклом рядом с красным счётом) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-row.paid,
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-payments .dpay-row:has(.dph-meta > .dc-chip.dc-ok:first-child) { background: color-mix(in srgb, var(--dz-ok) 8%, var(--dz-glass2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-ok) 24%, transparent); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-row.late,
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-payments .dpay-row.late { background: color-mix(in srgb, var(--dz-bad) 8%, var(--dz-glass2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent); }
/* точка-акцент строки 7 px (канон accent: в строке списка — точка, а не полоса) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-dot { grid-column: 1; grid-row: 1; width: 7px; height: 7px; background: var(--dz-text3); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-row.paid .dinv-dot { background: var(--dz-ok); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-row.late .dinv-dot { background: var(--dz-bad); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-main { grid-column: 2; grid-row: 1; gap: 4px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-t { gap: 8px 10px; font-size: 16px; line-height: 1.35; font-weight: 700; color: var(--dz-text); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-m { gap: 4px 14px; font-size: 14px; line-height: 1.4; color: var(--dz-text2); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-money { grid-column: 3; grid-row: 1; max-width: 220px; font-size: 18px; font-weight: 800; letter-spacing: -.01em; color: var(--dz-text); white-space: nowrap; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-money small { margin-top: 2px; font-size: 13px; font-weight: 600; letter-spacing: 0; color: var(--dz-text2); white-space: normal; }
/* колонка значков одной ширины у всех строк: суммы стоят в одну линию, а постоянные «на подпись ·
   акт» — на одном месте у правого края. 🔴 88c22e06 (21.10.2026, «элементы налезают друг на друга,
   хотя места достаточно»): ширина была ЖЁСТКОЙ на 6 значков, а у выставленного счёта с PDF их 8
   (открыть · скачать · исправить · отправить · оплата · ссылка · подпись · акт) — лишние два
   вылезали влево ПОВЕРХ суммы. Теперь 8 — нижняя граница (выравнивание), а коробка растёт по
   содержимому (max-content): новый значок раздвинет колонку, а не ляжет на сумму. */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-acts { grid-column: 4; grid-row: 1; gap: 2px; width: max-content; min-width: calc(8 * var(--dz-ib) + 14px); justify-content: flex-end; }
/* иконки строки — клетка `--dz-ib` из common; у вставленного стиля была кромка на наведении */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-ib { border: 0; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-ib svg { width: 17px; height: 17px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-ib.ok:hover { color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 14%, transparent); }
/* слово главного действия и «⋯» с подписями (patch.py п.14) — только там, где наводить нечем
   (сенсор) или тесно (узкая колонка): правила ниже, в @media (hover: none) и @container */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices :is(.dinv-more, .dinv-ib-l) { display: none; }

/* ── 7 · ВЫПАДАЮЩИЙ СПИСОК МОДЕЛИ ОПЛАТЫ — плотное стекло (`--panel` вида = 0.06 просвечивал) ── */
.dz-pane .di-payments .ccpp-inline { background: linear-gradient(var(--dz-glass2), var(--dz-glass2)), var(--dz-bg); border-color: var(--dz-edge2); box-shadow: var(--dz-shadow); }

/* ── 8 · СЕНСОР: действия строк видны всегда (наводить нечем) — common уже снял прозрачность;
   ручка порядка — тоже (common), здесь только её поле промаха без сдвига строки ────────── */
@media (hover: none) {
  .dz-pane .di-payments .dpay-row > .dph-grip::after { content: ""; position: absolute; inset: -6px -3px; }
}

/* ── 9 · УЗКАЯ КОЛОНКА (ноутбук с перепиской, телефон) ───────────────────────────────── */
/* ноутбук 1280 с открытой перепиской: колонка ~770 px — четыре плитки по 167 px резали «135 000 ₽»
   о край плитки; сводка денег встаёт 2 × 2 раньше общей сетки «Обзора» (у неё подписи длиннее) */
@container dz (max-width: 900px) {
  .dz-pane .dz-metrics.dz-msum { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dz-pane .dz-metrics.dz-msum > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  /* счета: колонка из 6 значков и «оплачено … · осталось …» съедали номер счёта до «INV-» на
     строке — значки уходят второй строкой под номер, итог шапки — своей строкой под заголовком */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-row { grid-template-columns: auto minmax(0, 1fr) auto; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-money { max-width: 230px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-acts { grid-column: 2 / -1; grid-row: 2; width: auto; min-width: 0; flex-wrap: wrap; justify-content: flex-start; margin-left: -6px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .di-sec-h { flex-wrap: wrap; row-gap: 2px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .di-sec-h .dinv-sum { order: 5; flex: 1 1 100%; }
}
@container dz (max-width: 640px) {
  /* телефон: плитка ~110 px внутри не вмещала крупную сумму — сводка становится списком из
     четырёх строк «подпись · пояснение | число» во всю ширину (высота та же, что у 2 × 2) */
  .dz-pane .dz-metrics.dz-msum { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .dz-pane .dz-msum .dz-metric {
    display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "h v" "s v";
    align-items: center; column-gap: 12px; row-gap: 2px; min-height: 0; padding: 14px 16px; border-radius: 20px;
  }
  .dz-pane .dz-msum .dz-metric-h { grid-area: h; }
  .dz-pane .dz-msum .dz-metric-h small { font-size: 14px; font-weight: 700; color: var(--dz-text); }
  .dz-pane .dz-msum .dz-metric-h svg.ic { display: none; }
  .dz-pane .dz-msum .dz-metric-v { grid-area: v; justify-self: end; gap: 8px; font-size: 22px; white-space: nowrap; }
  .dz-pane .dz-msum .dz-metric-v small { font-size: 15px; }
  .dz-pane .dz-msum .dz-metric-s { grid-area: s; font-size: 13.5px; }
  .dz-pane .dz-msum .dz-ring { width: 24px; height: 24px; -webkit-mask: radial-gradient(circle 8px, transparent 98%, #000 100%); mask: radial-gradient(circle 8px, transparent 98%, #000 100%); }
  .dz-pane :is(.di-budget, .di-hours) :is(.dbg-nums, .dpay-nums) { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 14px 16px; gap: 14px 16px; }
  .dz-pane .di-budget .dbg-n-v, .dz-pane .di-hours .dpay-num-v { font-size: 20px; }
  .dz-pane :is(.di-payments, .di-hours) .dpay-warn, .dz-pane .di-budget .dbg-line { padding: 12px 14px 12px 42px; }
  .dz-pane :is(.di-payments, .di-hours) .dpay-warn > svg.ic, .dz-pane .di-budget .dbg-line > svg.ic { left: 14px; top: 14px; }
  .dz-pane .di-budget .dbg-burn { padding: 14px 16px; }
  .dz-pane .di-budget .dbg-burn-g { grid-template-columns: minmax(0, 1fr) auto; row-gap: 6px; }
  .dz-pane .di-budget .dbg-burn-l { grid-column: 1; grid-row: 1; }
  .dz-pane .di-budget .dbg-burn-p { grid-column: 2; grid-row: 1; }
  .dz-pane .di-budget .dbg-burn-t { grid-column: 1 / -1; grid-row: 2; }
  /* оплаты: название на всю строку, сумма под ним, действия — своей строкой во всю ширину */
  .dz-pane .di-payments .dpay-model > .dpay-f:first-child { flex: 1 1 100%; }
  .dz-pane .di-payments .dpay-model-i, .dz-pane .di-payments .dpay-model .ccpp-field { min-width: 0; width: 100%; }
  .dz-pane .di-payments .dpay-model-say { flex-basis: 100%; padding-bottom: 0; }
  .dz-pane .di-payments .dpay-row { grid-template-columns: minmax(0, 1fr); padding: 14px 14px 14px 30px; }
  .dz-pane .di-payments .dpay-row > .dph-grip { top: 12px; margin: 0; left: 4px; }
  .dz-pane .di-payments .dpay-row .dph-h { grid-column: 1; flex-wrap: wrap; row-gap: 6px; }
  .dz-pane .di-payments .dpay-row .dph-t { flex: 1 1 100%; }
  .dz-pane .di-payments .dpay-row .dph-meta { grid-column: 1; }
  .dz-pane .di-payments .dpay-row .dph-acts { grid-column: 1; grid-row: 3; justify-self: stretch; justify-content: flex-start; }
  .dz-pane .di-payments .dpay-row .dph-acts .dph-a { margin-left: auto; }
  /* часы */
  .dz-pane .di-hours .dhr-top { flex-direction: column; align-items: stretch; }
  .dz-pane .di-hours .dhr-top .cc-seg { align-self: flex-start; }
  .dz-pane .di-hours .dhr-top-a .di-btn { flex: 1 1 auto; padding: 6px 14px; }
  /* сводка-список: число и тревожное слово; пояснение (название платежа, «при готовности…») — в блоке */
  .dz-pane .dz-msum .dz-msum-x { display: none; }
  .dz-pane .di-hours .dhr-rate-a { margin-left: 0; }
  .dz-pane .di-hours .dhr-row { grid-template-columns: auto minmax(0, 1fr); padding: 14px; column-gap: 12px; }
  .dz-pane .di-hours .dhr-row > .dhr-bill { grid-row: 1 / span 3; align-self: start; margin-top: 2px; }
  .dz-pane .di-hours .dhr-row .dph-h { grid-column: 2; flex-wrap: wrap; row-gap: 4px; }
  .dz-pane .di-hours .dhr-t { flex: 1 1 100%; }
  .dz-pane .di-hours .dhr-row .dph-acts:not(:empty) { grid-column: 2; grid-row: 3; justify-self: start; }
  /* счета: номер и статус, под ними сумма, ниже значки действий */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-row { grid-template-columns: auto minmax(0, 1fr); padding: 14px; column-gap: 12px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-dot { align-self: start; margin-top: 9px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-money { grid-column: 2; grid-row: 2; max-width: none; text-align: left; white-space: normal; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-acts { grid-column: 2; grid-row: 3; width: auto; min-width: 0; justify-content: flex-start; flex-wrap: wrap; gap: 8px; margin-left: 0; }
  /* узко — то же, что на сенсоре: главное действие словом, остальные — «⋯» с подписями */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-acts > :is(a, button[data-docpdf], [data-dinv-act="link"], [data-dinv-act="sign"], [data-dinv-act="act"]) { display: none; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices :is(.dinv-ib.ok, .dinv-more) {
    display: inline-flex; width: auto; height: var(--ctl-h); padding: 0 14px; gap: 8px; border-radius: var(--ctl-r);
    font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; white-space: nowrap;
  }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-ib-l { display: inline; }
  /* «Оплата · 85 000 ₽» — словом, как та же кнопка в строке «Оплат»; «⋯» рядом с ней — квадрат
     (одна строка на телефоне), один — со словом «Документ» */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-ib.ok svg.ic { display: none; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-more:not(:has(.dinv-ib-l)) { width: var(--ctl-h); padding: 0; justify-content: center; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-ib.ok { color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-ok) 26%, transparent); }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-more { color: var(--dz-text); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge); }
}

/* ── 10 · СЕНСОР · «СЧЕТА»: шесть немых значков → главное действие словом + «⋯» с подписями ──
   (patch.py п.14). Наводить нечем — подсказку `title` не прочесть, «ярлык» и «щит» не угадать.
   Стоит ПОСЛЕ @container: на планшете (сенсор и колонка уже 900) слово и отступ берутся отсюда. */
@media (hover: none) {
  /* счёт: шесть немых значков → «Оплата · 85 000 ₽» словом + «⋯ Ещё» с подписями (меню) */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-acts > :is(a, button[data-docpdf], [data-dinv-act="link"], [data-dinv-act="sign"], [data-dinv-act="act"]) { display: none; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-acts { width: auto; min-width: 0; gap: 8px; margin-left: 0; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices :is(.dinv-ib.ok, .dinv-more) {
    display: inline-flex; width: auto; height: var(--ctl-h); padding: 0 14px; gap: 8px; border-radius: var(--ctl-r);
    font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; white-space: nowrap;
  }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-ib-l { display: inline; }
  /* «Оплата · 85 000 ₽» — словом, как та же кнопка в строке «Оплат»; «⋯» рядом с ней — квадрат
     (одна строка на телефоне), один — со словом «Документ» */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-ib.ok svg.ic { display: none; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-more:not(:has(.dinv-ib-l)) { width: var(--ctl-h); padding: 0; justify-content: center; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-ib.ok { color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-ok) 26%, transparent); }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-invoices .dinv-more { color: var(--dz-text); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge); }
}
/* ── money-b ── */
/* ═══════════════════════════════════════════════════════════════════════════
   💰 «ГЛУБИНА» · ВКЛАДКА «ДЕНЬГИ» (часть B): Позиции сделки · КП и смета ·
   Закрывающие документы · Коммерция. Только вид — разметка блоков та же, что в «Штиле»
   (`dealLineItemsHtml` · `dealKpBodyHtml`/`dcQuoteRowsHtml`/`estimateGroupHtml` ·
   `dealWorkActsBodyHtml` · `dealCommerceBodyHtml`). Скоуп — корень блока внутри `.dz-pane`:
   классы `.dc-*` и `.dinv-*` общие со «Счетами», окном вопросов по смете и лидом — их не задеваем.
   Язык строки документа — тот же, что у соседей по вкладке («Оплаты», «Часы», «Счета» — часть A):
   плитка стекла 18 px · название 16/700 · сумма 18/800 справа · чипы статуса строкой ниже.
   «Закрывающие документы» — та же разметка, что «Счета», и тот же вид (значения 1:1 с частью A).
   Действия строки — по V5: первое стеклом, решение (согласовать · отклонить · отгрузить) — цветом
   смысла, остальные ссылкой: 4 КП × 6 рамок превращались в стену кнопок.
   ═══════════════════════════════════════════════════════════════════════════ */

/* значок пустого состояния — маска (форма из ICONS продукта), цвет даёт токен темы */
.dz-pane :is(.di-kp, .di-workacts) {
  --dzm-ic-file: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z'/%3E%3Cpath d='M14 2v4a2 2 0 0 0 2 2h4'/%3E%3Cpath d='M10 9H8'/%3E%3Cpath d='M16 13H8'/%3E%3Cpath d='M16 17H8'/%3E%3C/svg%3E");
  --dzm-ic-shield: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z'/%3E%3C/svg%3E");
  /* нейтральный кружок: 7 % чернил видно на стекле обеих тем (glass2 в светлой — белое на белом) */
  --dzm-circle: color-mix(in srgb, var(--dz-text) 7%, transparent);
}
/* тело каждого блока — контейнер: раскладка строки решается шириной БЛОКА (½ или во всю
   ширину по настройке человека, телефон), а не шириной окна */
.dz-pane :is(.di-lineitems, .di-kp, .di-commerce) > .di-sec-b { container: dzmb / inline-size; }

/* ── ПОЗИЦИИ СДЕЛКИ ─────────────────────────────────────────────────────────
   Таблица без горизонтальной прокрутки: на широком блоке — колонки, на узком — строка в два
   этажа (название · сумма / кол-во · цена · скидка). Поля — тихие «пилюли» правки: видно, что
   число можно поменять, но 22 строки × 3 рамки не превращаются в сетку из коробок. */
.dz-pane .di-lineitems .dli-table { overflow: visible; }
.dz-pane .di-lineitems :is(.dli-head, .dli-rows) { min-width: 0; }
.dz-pane .di-lineitems :is(.dli-head, .dli-row) {
  grid-template-columns: minmax(0, 1fr) 76px 132px 92px 140px var(--dz-ib);
  column-gap: 12px;
}
.dz-pane .di-lineitems .dli-head {
  padding: 0 0 8px; font-size: 13px; font-weight: 750; letter-spacing: .06em; color: var(--dz-text2);
  border-bottom: 1px solid var(--dz-edge);
}
.dz-pane .di-lineitems .dli-head .dli-h-price { padding-right: 12px; }
.dz-pane .di-lineitems .dli-rows { display: flex; flex-direction: column; }
.dz-pane .di-lineitems .dli-row {
  position: relative; min-height: 60px; box-sizing: border-box; padding: 10px 0; border-radius: 0;
  background: transparent; transition: background .12s;
}
.dz-pane .di-lineitems .dli-rows > .dli-row:not(:first-child) { border-top: 1px solid var(--dz-edge); }
.dz-pane .di-lineitems .dli-row:hover { background: transparent; }
.dz-pane .di-lineitems .dli-name {
  margin-left: -8px; padding: 7px 8px; border-radius: 10px;
  font-size: 16px; font-weight: 650; line-height: 1.35; color: var(--dz-text);
  white-space: normal; overflow: visible; overflow-wrap: anywhere; text-overflow: clip;
}
.dz-pane .di-lineitems .dli-name:hover { background: var(--hover); }
.dz-pane .di-lineitems .dli-name:focus { background: var(--input-bg); box-shadow: inset 0 0 0 1px var(--dz-link), var(--dz-ring); }
.dz-pane .di-lineitems .dli-name:empty::before { color: var(--dz-text3); }
/* поля строки: тихая пилюля 5 % чернил; рамка — по наведению, кольцо — по фокусу */
.dz-pane .di-lineitems :is(.dli-qty, .dli-price, .dli-disc) {
  box-sizing: border-box; width: 100%; min-height: var(--ctl-h); height: var(--ctl-h); padding: 0 10px;
  border: 1px solid transparent; border-radius: var(--ctl-r);
  font-size: 15px; font-weight: 650; font-variant-numeric: tabular-nums; color: var(--dz-text);
  background: color-mix(in srgb, var(--dz-text) 5%, transparent); box-shadow: none;
}
.dz-pane .di-lineitems .dli-qty { padding: 0 8px; }
.dz-pane .di-lineitems :is(.dli-qty, .dli-price, .dli-disc):hover { border-color: var(--dz-edge2); background: color-mix(in srgb, var(--dz-text) 7%, transparent); }
.dz-pane .di-lineitems :is(.dli-qty, .dli-price, .dli-disc):focus { border-color: var(--dz-link); background: var(--input-bg); box-shadow: var(--dz-ring); }
.dz-pane .di-lineitems .dli-sum { font-size: 16px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--dz-text); }
/* удалить: на мыши — по наведению на строку или фокусу в ней (прогрессивное раскрытие);
   на сенсоре видно всегда (общий слой, `@media (hover: none)`) */
.dz-pane .di-lineitems .dli-del { justify-self: end; font-size: 15px; line-height: 1; }
.dz-pane .di-lineitems .dli-row:is(:hover, :focus-within) .dli-del { opacity: .7; }
.dz-pane .di-lineitems .dli-del:focus-visible { opacity: 1; outline: 2px solid var(--dz-link); outline-offset: 1px; }
/* склад под строкой: подпись 13 px, цвет состояния — токенами вида; длинная — переносится */
.dz-pane .di-lineitems .cc-stock-row { margin-top: -6px; padding: 0 0 12px; }
.dz-pane :is(.di-lineitems, .di-commerce) .cc-stock { gap: 6px; font-size: 13px; font-weight: 650; color: var(--dz-text2); white-space: normal; }
.dz-pane :is(.di-lineitems, .di-commerce) .cc-stock .ic { width: 14px; height: 14px; opacity: 1; flex: none; }
.dz-pane :is(.di-lineitems, .di-commerce) .cc-stock.warn { color: var(--dz-warn); }
.dz-pane :is(.di-lineitems, .di-commerce) .cc-stock.bad { color: var(--dz-bad); }
/* итог — крупной цифрой, как плитки «Обзора» */
.dz-pane .di-lineitems .dli-sum-total {
  align-items: baseline; gap: 10px; margin-top: 2px; padding-top: 16px; border-top: 1px solid var(--dz-edge);
  font-size: 14px; font-weight: 600; color: var(--dz-text2);
}
.dz-pane .di-lineitems .dli-sum-total b { font-size: 24px; font-weight: 800; letter-spacing: -.01em; font-variant-numeric: tabular-nums; color: var(--dz-text); }
.dz-pane .di-lineitems .dli-add-toggle { font-size: 15px; min-height: 32px; }
/* форма добавления: плитка стекла, а не пунктир; поля и кнопка — одна высота ряда */
.dz-pane .di-lineitems .dli-add {
  gap: 10px; padding: 14px; border: 1px solid var(--dz-edge); border-radius: 16px; background: var(--dz-glass2);
}
.dz-pane .di-lineitems .dli-add input { min-height: var(--ctl-h); padding: 0 14px; border: 1px solid var(--dz-edge2); border-radius: var(--ctl-r); font-size: 15px; background: var(--input-bg); }
.dz-pane .di-lineitems .dli-add input:focus { border-color: var(--dz-link); box-shadow: var(--dz-ring); }
.dz-pane .di-lineitems .dli-add-name { flex: 1 1 160px; min-width: 0; }
.dz-pane .di-lineitems .dli-add-price { width: 132px; }
.dz-pane .di-lineitems .dli-add-qty { width: 88px; }
.dz-pane .di-lineitems .dli-add .dli-add-cat { padding: 0 6px; }
/* каталог: строки 48 px, название 15, артикул и склад — подписью, цена жирно */
.dz-pane .di-lineitems .dli-cat { margin-top: 10px; }
.dz-pane .di-lineitems .dli-cat-list { max-height: 400px; gap: 2px; padding: 6px; border: 1px solid var(--dz-edge); border-radius: 16px; background: var(--dz-glass2); }
.dz-pane .di-lineitems .dli-cat-item {
  flex: none; flex-wrap: wrap; column-gap: 12px; row-gap: 2px; min-height: 48px; padding: 8px 12px; border-radius: 12px;
  font-family: inherit; font-size: 15px; color: var(--dz-text);
}
.dz-pane .di-lineitems .dli-cat-item:hover { background: var(--hover); }
/* название товара не режется многоточием (у пункта нет title) — переносится */
.dz-pane .di-lineitems .dli-cat-nm { flex: 1 1 200px; font-weight: 650; white-space: normal; overflow-wrap: anywhere; }
.dz-pane .di-lineitems .dli-cat-sku { font-size: 13px; font-weight: 600; color: var(--dz-text2); }
.dz-pane .di-lineitems .dli-cat-pr { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; }
.dz-pane .di-lineitems .dli-cat-empty { font-size: 15px; color: var(--dz-text2); padding: 6px 0; }
.dz-pane .di-lineitems .dli-cat > :is(.cc-lf, .cc-skel-b) { padding: 6px 0; }

/* ── КП И СМЕТА · КОММЕРЦИЯ: группы и плитки ─────────────────────────────── */
.dz-pane :is(.di-kp, .di-commerce) .dc-body { gap: 22px; }
.dz-pane :is(.di-kp, .di-commerce) :is(.dc-grp, .dc-est-body) { display: flex; flex-direction: column; gap: 10px; }
.dz-pane :is(.di-kp, .di-commerce) .dc-grp-h {
  gap: 10px; min-height: 32px;
  font-size: 13px; font-weight: 750; letter-spacing: .06em; color: var(--dz-text2);
}
.dz-pane :is(.di-kp, .di-commerce) .dc-grp-h .di-link { text-transform: none; letter-spacing: 0; }
.dz-pane :is(.di-kp, .di-commerce) .dc-grp > .di-empty { padding: 0 0 4px; }
.dz-pane :is(.di-kp, .di-commerce) .dc-item {
  gap: 10px; padding: 14px 16px 14px 18px; border: 0; border-radius: 18px;
  background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane :is(.di-kp, .di-commerce) .dc-item:hover { box-shadow: inset 0 0 0 1px var(--dz-edge2); }
/* название · сумма — строка «Обзора»: не влезают рядом — сумма уходит строкой ниже вправо */
.dz-pane :is(.di-kp, .di-commerce) .dc-item-h { flex-wrap: wrap; align-items: baseline; column-gap: 14px; row-gap: 2px; }
.dz-pane :is(.di-kp, .di-commerce) .dc-item-t { flex: 1 1 auto; min-width: 0; font-size: 16px; font-weight: 700; line-height: 1.35; overflow-wrap: anywhere; color: var(--dz-text); }
.dz-pane :is(.di-kp, .di-commerce) .dc-item-sum { margin-left: auto; font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--dz-text); }
.dz-pane :is(.di-kp, .di-commerce) .dc-item-h > .dc-chip { margin-left: auto; align-self: center; }
.dz-pane :is(.di-kp, .di-commerce) .dc-item-m { gap: 6px 10px; }
.dz-pane :is(.di-kp, .di-commerce) .dc-item-m:empty { display: none; }
.dz-pane :is(.di-kp, .di-commerce) .dc-due { font-size: 14px; color: var(--dz-text2); font-variant-numeric: tabular-nums; }
/* действия строки: первое — стекло, решение — цветом смысла, остальные — ссылкой (V5) */
/* ряд уходит влево на поле ссылки (10 px): перенесённая ссылка встаёт текстом ровно под
   названием, а кнопки с рамкой возвращают себе это поле отступом слева */
.dz-pane :is(.di-kp, .di-commerce) .dc-item .dc-acts { gap: 4px 0; margin: 2px 0 0 -10px; }
.dz-pane :is(.di-kp, .di-commerce) .dc-item .dc-acts:empty { display: none; }
.dz-pane :is(.di-kp, .di-commerce) .dc-item .dc-acts > :is(.dc-a:first-child, .dc-a.ok, .dc-a.bad) { margin: 0 4px 0 10px; }
/* PDF КП — `a.dc-a.primary`: светлая тема базы (`html[data-theme="light"] .primary`, вес 0,2,1)
   заливала его акцентом, а тёмная оставляла стеклом — одна кнопка, две разные роли по темам */
.dz-pane :is(.di-kp, .di-commerce) .dc-acts > .dc-a.primary {
  color: var(--dz-text); background: var(--dz-glass2); border-color: var(--dz-edge2); box-shadow: none;
}
.dz-pane :is(.di-kp, .di-commerce) .dc-acts > .dc-a.primary:hover {
  color: var(--dz-text); background: color-mix(in srgb, var(--dz-text) 10%, transparent);
  border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); box-shadow: none;
}
.dz-pane :is(.di-kp, .di-commerce) .dc-item .dc-acts > .dc-a:not(:first-child):not(.ok):not(.bad) {
  position: relative; padding: 0 10px; border-color: transparent; background: transparent; color: var(--dz-link);
}
.dz-pane :is(.di-kp, .di-commerce) .dc-item .dc-acts > .dc-a:not(:first-child):not(.ok):not(.bad):hover {
  border-color: transparent; background: color-mix(in srgb, var(--dz-link) 12%, transparent); color: var(--dz-link);
}
.dz-pane :is(.di-kp, .di-commerce) .dc-item .dc-acts > .dc-a.ok { background: color-mix(in srgb, var(--dz-ok) 12%, transparent); }
.dz-pane :is(.di-kp, .di-commerce) .dc-item .dc-acts > .dc-a.ok:hover { color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 20%, transparent); border-color: color-mix(in srgb, var(--dz-ok) 55%, transparent); }
.dz-pane :is(.di-kp, .di-commerce) .dc-item .dc-acts > .dc-a.bad:hover { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 18%, transparent); border-color: color-mix(in srgb, var(--dz-bad) 55%, transparent); }
/* сенсор: действия строки 40 px → поле промаха до 44 без сдвига раскладки (канон tap-target) */
.dz-pane :is(.di-kp, .di-commerce) .dc-acts > :is(.dc-a, .dc-toggle) { position: relative; }
@media (hover: none) {
  .dz-pane :is(.di-kp, .di-commerce) .dc-acts > :is(.dc-a, .dc-toggle)::after { content: ""; position: absolute; inset: -2px 0; }
}
/* счётчик внутри действия («Вопросы клиента 2») — чип вплотную к слову */
.dz-pane :is(.di-kp, .di-commerce) .dc-a .dc-chip { min-height: 22px; margin-left: 2px; padding: 0 8px; }
/* состояние вместо кнопки («отгружен 06.10») и переключатель автопродления — в ряд действий */
.dz-pane .di-commerce .dc-acts > .dc-due { display: inline-flex; align-items: center; min-height: var(--ctl-h); padding: 0 10px; }
.dz-pane .di-commerce .dc-toggle {
  position: relative; gap: 8px; min-height: var(--ctl-h); padding: 0 10px; border-radius: var(--ctl-r);
  font-size: 14px; font-weight: 650; color: var(--dz-text);
}
.dz-pane .di-commerce .dc-toggle:hover { background: var(--hover); }
.dz-pane .di-commerce .dc-toggle input { width: 18px; height: 18px; margin: 0; accent-color: var(--dz-pri); }
/* форма подписки: поля и кнопка — одна высота ряда, на узком — по строкам */
.dz-pane .di-commerce .dc-sub-form:not([hidden]) { margin-top: 6px; }
.dz-pane .di-commerce .dc-subf { gap: 10px; margin-top: 0; padding: 14px; border: 1px solid var(--dz-edge); border-radius: 16px; background: var(--dz-glass2); }
.dz-pane .di-commerce .dc-subf :is(input, select) { min-height: var(--ctl-h); font-size: 15px; border-color: var(--dz-edge2); background-color: var(--input-bg); }
.dz-pane .di-commerce .dc-subf .dc-sf-name { flex: 1 1 220px; min-width: 0; }
.dz-pane .di-commerce .dc-subf .dc-sf-amt { width: 150px; }
/* свёрнутая «Коммерция» — шапка без хвоста пустоты снизу: `[hidden]` у тела перебивался
   базовым `.di-sec-b { display: flex }` (UA-правило слабее), и пустое тело держало 26 px + зазор */
.dz-pane .di-commerce > .dc-body[hidden] { display: none; }
.dz-pane .di-commerce:has(> .dc-body[hidden]) > .di-sec-h { padding-bottom: 16px; }

/* пусто «КП и смета» / «Актов пока нет» — кружок-значок слева от слов (как пустой «Клиент» в «Обзоре») */
.dz-pane .di-kp > .dc-body > .di-empty:only-child,
.dz-pane .di-workacts > .di-sec-b > .dc-acts + .di-empty:last-child {
  /* блок, а не флекс: внутри текст с <b> — флекс разнёс бы его на колонки */
  position: relative; display: block; box-sizing: border-box; min-height: 42px; padding: 9px 0 9px 56px;
}
.dz-pane .di-kp > .dc-body > .di-empty:only-child::before,
.dz-pane .di-workacts > .di-sec-b > .dc-acts + .di-empty:last-child::before {
  content: ""; position: absolute; left: 0; top: 50%; width: 42px; height: 42px; margin-top: -21px; border-radius: 21px; background: var(--dzm-circle);
}
.dz-pane .di-kp > .dc-body > .di-empty:only-child::after,
.dz-pane .di-workacts > .di-sec-b > .dc-acts + .di-empty:last-child::after {
  content: ""; position: absolute; left: 12px; top: 50%; width: 18px; height: 18px; margin-top: -9px; background-color: var(--dz-text2);
  -webkit-mask: var(--dzm-ic-file) center / 18px 18px no-repeat; mask: var(--dzm-ic-file) center / 18px 18px no-repeat;
}
.dz-pane .di-workacts > .di-sec-b > .dc-acts + .di-empty:last-child::after { -webkit-mask-image: var(--dzm-ic-shield); mask-image: var(--dzm-ic-shield); }

/* ── ЗАКРЫВАЮЩИЕ ДОКУМЕНТЫ ─────────────────────────────────────────────────
   Та же разметка, что у «Счетов» (`.dinv-*`), и ТОТ ЖЕ вид, что у них в части A (значения 1:1):
   две соседние ленты документов не должны выглядеть по-разному. Правила `dinvCss` вставляет JS
   ПОСЛЕ style.css — перебиваем весом `:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane`, а не `!important`.
   При сведении частей — один селектор `:is(.di-invoices, .di-workacts)`. */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .di-sec-h .dinv-sum { margin-left: 0; font-size: 14px; font-weight: 600; color: var(--dz-text2); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .di-sec-h:not(.has-cblk) .dinv-sum { margin-left: auto; }
.dz-pane .di-workacts .di-sec-b > .dc-acts { gap: 8px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-list { gap: 10px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-row {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; column-gap: 14px; row-gap: 10px;
  padding: 14px 16px 14px 18px; border: 0; border-radius: 18px;
  background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-row:hover { border: 0; box-shadow: inset 0 0 0 1px var(--dz-edge2); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-row.paid { background: color-mix(in srgb, var(--dz-ok) 8%, var(--dz-glass2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-ok) 24%, transparent); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-row.late { background: color-mix(in srgb, var(--dz-bad) 8%, var(--dz-glass2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent); }
/* точка-акцент строки 7 px (канон accent: в строке списка — точка, а не полоса) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-dot { grid-column: 1; grid-row: 1; width: 7px; height: 7px; background: var(--dz-text3); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-row.paid .dinv-dot { background: var(--dz-ok); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-row.late .dinv-dot { background: var(--dz-bad); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-main { grid-column: 2; grid-row: 1; gap: 4px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-t { gap: 8px 10px; font-size: 16px; line-height: 1.35; font-weight: 700; color: var(--dz-text); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-m { gap: 4px 14px; font-size: 14px; line-height: 1.4; color: var(--dz-text2); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-money { grid-column: 3; grid-row: 1; font-size: 18px; font-weight: 800; letter-spacing: -.01em; color: var(--dz-text); white-space: nowrap; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-money small { margin-top: 2px; font-size: 13px; font-weight: 600; letter-spacing: 0; color: var(--dz-text2); white-space: normal; }
/* колонка значков одной ширины у всех строк (у акта до 4 значков: открыть · скачать · подпись ·
   аннулировать): суммы стоят в одну линию; коробка растёт по содержимому, а не ложится на сумму
   (88c22e06 — была жёсткой на 3 значка) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-acts { grid-column: 4; grid-row: 1; gap: 2px; width: max-content; min-width: calc(4 * var(--dz-ib) + 6px); justify-content: flex-end; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-ib { border: 0; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-ib svg { width: 17px; height: 17px; }

/* ── СРЕДНИЙ БЛОК (компьютер 1280 с перепиской справа · блок ½ ширины) ────────
   Таблица та же, столбики плотнее; «Скидка %» держит запас к своей подписи (канон label-fit: 86 px
   при подписи ~74). Цена — 112 px: 10 знаков («1234567.89») целиком (104 резали её на 2 px), сумма —
   140 px: «12 345 678,90 ₽» не залезает на крестик (116 px — залезала). Кол-во — 72 px: 6 знаков
   («250000») целиком (60 резали уже «12000»). Имени остаётся ~190 px. */
@container dzmb (max-width: 720px) {
  .dz-pane .di-lineitems :is(.dli-head, .dli-row) { grid-template-columns: minmax(0, 1fr) 72px 112px 86px 140px var(--dz-ib); column-gap: 8px; }
  .dz-pane .di-lineitems .dli-head { letter-spacing: .03em; }
  .dz-pane .di-lineitems .dli-head .dli-h-price { padding-right: 10px; }
  .dz-pane .di-lineitems .dli-price { padding: 0 8px; }
  .dz-pane .di-lineitems .dli-qty { padding: 0 6px; }
}

/* ── УЗКИЙ БЛОК (телефон) ───────────────────────────────────────────────────── */
@container dzmb (max-width: 520px) {
  /* позиции: название во всю строку (крестик — в углу), под ним кол-во · цена · скидка · сумма */
  .dz-pane .di-lineitems .dli-head { display: flex; flex-wrap: wrap; column-gap: 0; row-gap: 2px; padding-bottom: 8px; }
  /* подпись столбиков — одной строкой-легендой порядка полей (сумма в ряду говорит сама) */
  .dz-pane .di-lineitems .dli-head > :is(.dli-h-name, .dli-h-x, .dli-h-sum) { display: none; }
  .dz-pane .di-lineitems .dli-head > span:is(.dli-h-qty, .dli-h-price, .dli-h-disc) { overflow: visible; padding: 0; }
  .dz-pane .di-lineitems .dli-head > span:is(.dli-h-price, .dli-h-disc)::before { content: "·"; margin: 0 8px; }
  /* 🔴 СТОЛБИКИ ПОЛЕЙ — ПОСТОЯННОЙ ШИРИНЫ. У каждой строки своя сетка, и прежний столбик суммы
     `minmax(auto, 1fr)` мерился ПО СВОЕЙ строке: цена выходила 46 / 61 / 71 px и резала число
     («145000» читалось «14500», «6658.33» — «665»). Теперь кол-во · цена · скидка одной ширины во
     всех строках (цена — 112 px, 10 знаков; кол-во — 66 px, 6 знаков: «12000» в 52 px резалось),
     сумма — остаток справа. */
  .dz-pane .di-lineitems .dli-row {
    grid-template-columns: 66px 112px 52px minmax(0, 1fr); column-gap: 6px; row-gap: 6px; padding: 12px 0;
  }
  .dz-pane .di-lineitems .dli-name { grid-column: 1 / -1; grid-row: 1; margin-right: 32px; }
  .dz-pane .di-lineitems .dli-qty { grid-column: 1; grid-row: 2; padding: 0 4px; }
  .dz-pane .di-lineitems .dli-price { grid-column: 2; grid-row: 2; padding: 0 10px; }
  .dz-pane .di-lineitems .dli-disc { grid-column: 3; grid-row: 2; padding: 0 4px; }
  .dz-pane .di-lineitems .dli-sum { grid-column: 4; grid-row: 2; padding-left: 4px; }
  .dz-pane .di-lineitems .dli-del { position: absolute; top: 14px; right: -4px; }
  .dz-pane .di-lineitems .cc-stock-row { margin-top: -4px; }
  .dz-pane .di-lineitems .dli-sum-total { flex-wrap: wrap; row-gap: 2px; }
  .dz-pane .di-lineitems .dli-add-name { flex-basis: 100%; }
  .dz-pane .di-lineitems .dli-add :is(.dli-add-price, .dli-add-qty) { flex: 1 1 90px; width: auto; min-width: 0; }
  .dz-pane .di-lineitems .dli-add .dli-add-ok { flex: 1 1 auto; }
  .dz-pane .di-lineitems .dli-cat-nm { flex-basis: 100%; }
  .dz-pane .di-lineitems .dli-cat-pr { margin-left: auto; }

  /* плитки документов: поле внутри уже, чем на компьютере */
  .dz-pane :is(.di-kp, .di-commerce) .dc-item { padding: 14px; }
  .dz-pane .di-commerce .dc-subf .dc-sf-name { flex-basis: 100%; }
  .dz-pane .di-commerce .dc-subf :is(.dc-sf-amt, .dc-sf-int) { flex: 1 1 110px; width: auto; min-width: 0; }
  .dz-pane .di-commerce .dc-subf .dc-sf-ok { flex: 1 1 100%; }
}
/* ── ТЕЛЕФОН (блок ≤ 400: на 390 у позиций ~246 px) ──────────────────────────────
   Кол-во · цена · скидка · сумма в одну строку не помещаются: сумме «79 899,96 ₽» нужно ~95 px, и
   отдавала их цена. Поля занимают всю строку (цена — всё, что между кол-вом и скидкой, ~116 px:
   «12345678.9» целиком), сумма — своим этажом под ними, справа, как итог расчёта строки. */
@container dzmb (max-width: 400px) {
  .dz-pane .di-lineitems .dli-row { grid-template-columns: 66px minmax(0, 1fr) 52px; row-gap: 6px; }
  .dz-pane .di-lineitems .dli-sum { grid-column: 1 / -1; grid-row: 3; justify-self: end; padding: 0 2px 0 0; }
}
/* акты — порог тот же, что у «Счетов» части A (колонка вида ≤ 640), чтобы две ленты документов
   перестраивались на одной ширине: номер и статус, под ними сумма, ниже значки действий */
@container dz (max-width: 640px) {
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-row { grid-template-columns: auto minmax(0, 1fr); padding: 14px; column-gap: 12px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-dot { align-self: start; margin-top: 9px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-money { grid-column: 2; grid-row: 2; text-align: left; white-space: normal; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .di-workacts .dinv-acts { grid-column: 2; grid-row: 3; width: auto; min-width: 0; justify-content: flex-start; flex-wrap: wrap; margin-left: -6px; }
}
/* ── work ── */
/* ═══════════════════════════════════════════════════════════════════════════
   🛠 «ГЛУБИНА» · ВКЛАДКА «РАБОТА» — сводка · Этапы · Дела · Чек-лист · Задачи · Файлы · Шаги.
   Опирается на общий словарь (lab/common: кнопки, поля, чипы, счётчики, строки 44 px, значки
   строк по наведению). Здесь — только РАСКЛАДКА строк своих блоков и то, чего словарю не хватило.
   Узкая раскладка строки спрашивает ширину САМОГО блока (контейнер `dzblk`), а не окна: блок
   «половинка» узок и на ноутбуке с перепиской (≈345 px), и на телефоне (≈280 px); колонка «Потоков»
   — тоже `dzblk`, поэтому этап в потоке берёт ту же узкую раскладку без второго набора правил.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 0 · контейнеры ширины блоков вкладки ──────────────────────────────────────
   Только свои блоки: безымянные @container базы (сетка `.crmw-grid`) спрашивают колонку, а не
   ячейку — у ячейки имя своё. Ширина ячейки задана дорожкой сетки, от содержимого не зависит. */
.dz-pane .crmw-blk:is([data-cb="phases"], [data-cb="acts"], [data-cb="tasks"], [data-cb="checklist"], [data-cb="files"], [data-cb="steps"]) {
  container: dzblk / inline-size;
}

/* ── 1 · СВОДКА ВКЛАДКИ (плитки «Обзора») ──────────────────────────────────── */
.dz-pane .dz-sum .dz-wsum-t {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  margin-top: 2px; font-weight: 600; color: var(--dz-text); overflow-wrap: anywhere;
}
.dz-pane .dz-sum:where([data-dzsum="work"]) .dz-metric-s .dz-tag { display: inline-flex; max-width: 100%; margin-top: 6px; white-space: normal; }
.dz-pane .dz-sum .dz-metric-s .dz-wsum-ok { color: var(--dz-ok); font-weight: 700; }
.dz-pane .dz-sum .dz-metric-s .dz-wsum-warn { color: var(--dz-warn); font-weight: 700; }
.dz-pane .dz-sum .dz-metric-v .dz-wsum-wait { color: var(--dz-text2); }
/* плитка убранного блока — действие словом цвета ссылки: «вернуть на страницу» (ревью #43) */
.dz-pane .dz-sum .dz-metric-s .dz-wsum-act { color: var(--dz-link); font-weight: 700; }

/* ── 2 · ЭТАПЫ ─────────────────────────────────────────────────────────────────
   Строка — плитка стекла второго уровня. Цвет статуса — токен вида по ВЫБРАННОМУ статусу (сам
   `<select>` знает его вживую: `option:checked`), а не прибитый #hex из разметки (`DPH_ST`). */
.dz-pane :where(.di-phases) .dph-row { --dph-c: var(--dz-text2); }
.dz-pane :where(.di-phases) .dph-row:has(.dph-st option[value="active"]:checked) { --dph-c: var(--dz-link); }
.dz-pane :where(.di-phases) .dph-row:has(.dph-st option[value="review"]:checked) { --dph-c: var(--dz-warn); }
.dz-pane :where(.di-phases) .dph-row:has(.dph-st option[value="done"]:checked) { --dph-c: var(--dz-ok); }
.dz-pane :where(.di-phases) .dph-row:has(.dph-st option[value="canceled"]:checked) { --dph-c: var(--dz-text3); }

/* итог блока: крупная готовность + полоса + одна строка «сколько чего» */
.dz-pane :where(.di-phases) .dph-top { display: flex; flex-direction: column; align-items: stretch; gap: 8px; margin-bottom: 6px; }
.dz-pane :where(.di-phases) .dph-prog { display: flex; align-items: center; gap: 16px; min-width: 0; flex: none; }
.dz-pane :where(.di-phases) .dph-prog-v {
  order: -1; flex: none; font-size: 30px; line-height: 1.1; font-weight: 800; letter-spacing: -.02em;
  font-variant-numeric: tabular-nums; color: var(--dz-text);
}
.dz-pane :where(.di-phases) .dph-prog-bar { height: 8px; border-radius: 4px; background: var(--dz-track); }
.dz-pane :where(.di-phases) .dph-prog-bar > i { border-radius: 4px; background: var(--dz-grad); box-shadow: 0 0 12px color-mix(in srgb, var(--dz-pri) 45%, transparent); }
.dz-pane :where(.di-phases) .dph-sum { font-size: 14px; line-height: 1.45; color: var(--dz-text2); }

.dz-pane :where(.di-phases) .dph-list { gap: 10px; margin-top: 4px; }
.dz-pane :where(.di-phases) .dph-row {
  display: grid; grid-template-columns: auto auto minmax(0, 1fr) auto auto auto;
  grid-template-areas: "grip dot t w st acts" ". . meta meta meta meta" ". . line line line line" ". . tasks tasks tasks tasks" ". . plan plan plan plan";
  align-items: center; gap: 0; padding: 14px 14px 16px 12px; border-radius: 18px;
  background: var(--dz-glass2); border: 1px solid var(--dz-edge);
}
.dz-pane :where(.di-phases) .dph-row:hover { border-color: color-mix(in srgb, var(--dz-link) 34%, var(--dz-edge)); }
.dz-pane :where(.di-phases) .dph-row.plan-open { border-color: color-mix(in srgb, var(--dz-link) 40%, var(--dz-edge)); }
/* тянущийся этап — НЕпрозрачное стекло поверх неба: база красит его `--panel` (= стекло 6 %), и текст
   соседа просвечивал сквозь поднятую строку (кадр st-drag) */
.dz-pane :where(.di-phases) .dph-row.dph-dragging {
  background: linear-gradient(var(--dz-glass2), var(--dz-glass2)), var(--dz-bg);
  border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge)); box-shadow: var(--dz-shadow);
}
/* тело строки отдаёт детей в сетку строки: на узкой ширине статус встаёт под название, а не
   отнимает у него место (на телефоне название рассыпалось по буквам) */
.dz-pane :where(.di-phases) .dph-row > .dph-b, .dz-pane :where(.di-phases) .dph-row .dph-h { display: contents; }
.dz-pane :where(.di-phases) .dph-grip { grid-area: grip; margin: 0 2px 0 -4px; width: 22px; height: 32px; color: var(--dz-text2); }
.dz-pane :where(.di-phases) .dph-grip svg.ic { width: 15px; height: 15px; }
.dz-pane :where(.di-phases) .dph-dot {
  grid-area: dot; align-self: center; width: 10px; height: 10px; margin: 0 12px 0 4px; border-radius: 5px;
  background: var(--dph-c); box-shadow: 0 0 0 4px color-mix(in srgb, var(--dph-c) 20%, transparent);
}
.dz-pane :where(.di-phases) .dph-t {
  grid-area: t; min-width: 0; margin: -3px 0 -3px -6px; padding: 3px 6px; border-radius: 8px;
  font-size: 16px; line-height: 1.35; font-weight: 700; color: var(--dz-text); overflow-wrap: anywhere;
}
.dz-pane :where(.di-phases) .dph-t:hover { background: var(--hover); }
.dz-pane :where(.di-phases) .dph-t:focus { background: var(--input-bg); box-shadow: var(--dz-ring); }
.dz-pane :where(.di-phases) .dph-row.is-done .dph-t { color: var(--dz-text2); }
.dz-pane :where(.di-phases) .dph-row:has(.dph-st option[value="canceled"]:checked) .dph-t { color: var(--dz-text3); text-decoration: line-through; }
/* вес этапа — число со словом, а не немая цифра */
.dz-pane :where(.di-phases) .dph-w {
  grid-area: w; margin: 0 10px 0 12px; padding: 3px 10px; border-radius: 10px;
  font-size: 13px; font-weight: 700; line-height: 1.35; color: var(--dz-text2); background: var(--dz-track);
}
.dz-pane :where(.di-phases) .dph-w::before { content: "вес "; font-weight: 600; }
/* статус — пилюля цветом статуса (слово + цвет, канон accent); высота ряда — --ctl-h */
.dz-pane :where(.di-phases) .dph-row .dph-st {
  grid-area: st; justify-self: start; height: var(--ctl-h); min-width: 0; max-width: 100%;
  padding: 0 34px 0 14px; border-radius: var(--ctl-r);
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; color: var(--dph-c);
  background-color: color-mix(in srgb, var(--dph-c) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--dph-c) 34%, transparent); box-shadow: none;
  /* стрелка раскрытия: базовое `.dph-st { background: … }` сокращённой записью стирает картинку
     общей стрелки `select` — статус читался неизменяемым бейджем, а справа зиял пустой отступ.
     Шеврон — два градиента цветом подписи (currentColor = токен статуса в обеих темах), а не
     SVG с прибитым #hex; отдельными свойствами, чтобы ничья сокращённая запись его не стёрла. */
  background-image:
    linear-gradient(to bottom left, transparent calc(50% - 1.5px), currentColor calc(50% - .7px), currentColor calc(50% + .7px), transparent calc(50% + 1.5px)),
    linear-gradient(to bottom right, transparent calc(50% - 1.5px), currentColor calc(50% - .7px), currentColor calc(50% + .7px), transparent calc(50% + 1.5px));
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat;
  background-position: right 20px center, right 14px center;
}
.dz-pane :where(.di-phases) .dph-row:has(.dph-st option[value="planned"]:checked) .dph-st,
.dz-pane :where(.di-phases) .dph-row:has(.dph-st option[value="canceled"]:checked) .dph-st { color: var(--dz-text); background-color: var(--dz-glass); border-color: var(--dz-edge2); }
.dz-pane :where(.di-phases) .dph-row .dph-st:hover { border-color: var(--dph-c); }
.dz-pane :where(.di-phases) .dph-row .dph-st:focus { outline: none; box-shadow: var(--dz-ring); }
.dz-pane :where(.di-phases) .dph-row .dph-st option { color: var(--dz-text); background: var(--dz-bg); }
.dz-pane :where(.di-phases) .dph-acts { grid-area: acts; margin-left: 8px; gap: 2px; }
.dz-pane :where(.di-phases) .dph-meta { grid-area: meta; margin-top: 10px; gap: 8px; row-gap: 8px; }
.dz-pane :where(.di-phases) .dph-meta:empty { display: none; }
.dz-pane :where(.di-phases) .dph-m { gap: 6px; font-size: 14px; line-height: 1.35; color: var(--dz-text2); }
.dz-pane :where(.di-phases) .dph-m svg.ic { width: 14px; height: 14px; opacity: 1; }
/* `.dz-pane.dz-pane`: тёмное `html[data-theme="dark"] .dph-m.over` базы весит (0,3,1) */
.dz-pane.dz-pane :where(.di-phases) .dph-m.over { color: var(--dz-bad); font-weight: 700; }
.dz-pane :where(.di-phases) .dph-chip.dph-wait { padding-right: 4px; }
/* чип этапа (оплата «112 500 ₽ · оплачено 50 000 ₽», «ждёт <длинное имя>») не шире строки:
   переносит слова, а не уезжает за край */
.dz-pane :where(.di-phases) .dph-meta .dph-chip { white-space: normal; max-width: 100%; overflow-wrap: anywhere; }
/* «Указать план» — чип-кнопка: пунктир говорит «нажми» (было 11.5 px и контраст 3.0) */
.dz-pane :where(.di-phases) .dph-plan-call {
  position: relative; display: inline-flex; align-items: center; gap: 6px; min-height: 26px; padding: 2px 11px;
  border: 1px dashed color-mix(in srgb, var(--dz-link) 55%, transparent); border-radius: 10px; background: transparent;
  font-family: inherit; font-size: 13px; font-weight: 700; line-height: 1.35; color: var(--dz-link); cursor: pointer;
}
.dz-pane :where(.di-phases) .dph-plan-call:hover { border-style: solid; background: color-mix(in srgb, var(--dz-link) 12%, transparent); }
.dz-pane :where(.di-phases) .dph-plan-call svg.ic { width: 14px; height: 14px; }
.dz-pane :where(.di-phases) .dph-plan-call::after { content: ""; position: absolute; inset: -9px -2px; }
.dz-pane :where(.di-phases) .dph-line { grid-area: line; height: 4px; margin-top: 12px; border-radius: 2px; background: var(--dz-track); }
/* заливка полосы приходит ИНЛАЙНОМ (`background:#hex` в `dphRowHtml`) — перебить её можно только
   !important; цвет берём токеном статуса вида, чтобы полоса читалась в обеих темах */
.dz-pane :where(.di-phases) .dph-line > i { border-radius: 2px; background: var(--dph-c) !important; }
/* 📈 задачи этапа — своя область сетки строки (`tasks`), строка задачи — та же, что в блоке «Задачи»
   (правила раздела «4 · ЗАДАЧИ» берут и `.dph-tasks`, и `.dph-free`) */
.dz-pane :where(.di-phases) .dph-tasks { grid-area: tasks; min-width: 0; margin-top: 10px; gap: 4px; }
.dz-pane :where(.di-phases) .dph-tk-list { margin: 0 -8px; gap: 0; }
.dz-pane :where(.di-phases) .dph-tk-a { font-size: 14px; font-weight: 700; color: var(--dz-text2); padding: 6px 0; }
.dz-pane :where(.di-phases) .dph-tk-a:hover, .dz-pane :where(.di-phases) .dph-tk-a:focus-visible { color: var(--dz-link); }
.dz-pane :where(.di-phases) .dph-tk-a svg.ic { width: 15px; height: 15px; }
.dz-pane :where(.di-phases) .dph-tk-more { color: var(--dz-link); }
.dz-pane :where(.di-phases) .dph-tk-acts { gap: 2px 18px; padding: 2px 0 0; }
.dz-pane :where(.di-phases) .crmb-st { font-size: 13px; color: var(--dz-text2); }
.dz-pane :where(.di-phases) .crmb-steps { font-size: 13px; color: var(--dz-text2); }
.dz-pane :where(.di-phases) .crmb-steps > b { width: 13px; height: 13px; background: conic-gradient(var(--dz-link) calc(var(--p, 0) * 1%), var(--dz-track) 0); }
.dz-pane :where(.di-phases) .crmb-steps.full { color: var(--dz-ok); }
.dz-pane :where(.di-phases) .crmb-steps.full > b { background: var(--dz-ok); }
.dz-pane :where(.di-phases) .dph-free { margin-top: 12px; padding: 14px 14px 10px; gap: 6px; border-radius: 18px; border: 1px dashed var(--dz-edge2); background: color-mix(in srgb, var(--dz-bg) 25%, transparent); }
.dz-pane :where(.di-phases) .dph-free-h { font-size: 15px; font-weight: 750; color: var(--dz-text); }
.dz-pane :where(.di-phases) .dph-free-h svg.ic { width: 16px; height: 16px; color: var(--dz-text2); }
.dz-pane :where(.di-phases) .dph-free-s { font-size: 13px; color: var(--dz-text2); }
.dz-pane :where(.di-phases) .dph-tk-to { height: 32px; padding: 0 12px; font-size: 13px; font-weight: 700; color: var(--dz-text); background: var(--dz-glass2); border-color: var(--dz-edge2); }
.dz-pane :where(.di-phases) .dph-tk-to:hover { color: var(--dz-link); border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); }
.dz-pane :where(.di-phases) .dph-plan {
  grid-area: plan; margin-top: 14px; padding: 16px; gap: 14px; border-radius: 16px;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  background: color-mix(in srgb, var(--dz-bg) 35%, transparent); border: 1px solid var(--dz-edge);
}
.dz-pane :where(.di-phases) .dph-plan .dph-f { gap: 6px; }
.dz-pane :where(.di-phases) .dph-plan .dpay-f-l { font-size: 13px; font-weight: 600; letter-spacing: 0; color: var(--dz-text2); }
.dz-pane :where(.di-phases) .dph-plan .dph-f-i { width: 100%; }
.dz-pane :where(.di-phases) .dph-plan-a { gap: 10px; }
/* «Ответственный · Платёж за этап» — выбор и переход, а не главное действие экрана: стекло */
.dz-pane :where(.di-phases) .dph-plan-a .di-btn { color: var(--dz-text); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge2); }
.dz-pane :where(.di-phases) .dph-plan-a .di-btn:hover { background: color-mix(in srgb, var(--dz-text) 10%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); }
.dz-pane :where(.di-phases) .dph-plan-a .di-btn svg.ic { width: 16px; height: 16px; }
.dz-pane :where(.di-phases) .dph-presets { gap: 10px; margin-top: 4px; }
.dz-pane .di-phases .di-empty b { color: var(--dz-text); }

/* «Потоки»: шаги графа — карточки сеткой (а не лента за край): шаг под шагом на телефоне, по три
   в ряд на компьютере; параллельные этапы — внутри одного шага */
.dz-pane :where(.di-phases) .dph-lanes { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr)); align-items: start; gap: 12px; overflow: visible; padding: 0; margin-top: 4px; }
.dz-pane :where(.di-phases) .dph-lane { container: dzblk / inline-size; flex: none; min-width: 0; gap: 10px; padding: 12px; border-radius: 18px; background: color-mix(in srgb, var(--dz-bg) 30%, transparent); border: 1px solid var(--dz-edge); }
.dz-pane :where(.di-phases) .dph-lane-arr { display: none; }
.dz-pane :where(.di-phases) .dph-lane-h { gap: 8px; min-height: 26px; padding: 0 4px; font-size: 13px; font-weight: 750; letter-spacing: .06em; color: var(--dz-text2); }
.dz-pane :where(.di-phases) .dph-lane-h .dph-chip { text-transform: none; letter-spacing: 0; }
.dz-pane :where(.di-phases) .dph-lane .dph-row { padding: 12px 12px 14px 10px; }

/* узкая строка этапа (телефон, колонка «Потоков»): верхняя строка — служебная (ручка · точка
   статуса · вес … действия справа), ниже название ЦЕЛИКОМ, чипы, статус, полоса. В одну строку
   с названием на ~220 px не влезает ничего: название рассыпалось по буквам, статус сжимался в шеврон. */
@container dzblk (max-width: 600px) {
  .dz-pane :where(.di-phases) .dph-row {
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    grid-template-areas: "grip dot w acts" "t t t t" "meta meta meta meta" "st st st st" "line line line line" "tasks tasks tasks tasks" "plan plan plan plan";
    padding: 10px 12px 14px;
  }
  .dz-pane :where(.di-phases) .dph-w { justify-self: start; margin: 0; }
  .dz-pane :where(.di-phases) .dph-acts { margin: 0 -6px 0 6px; }
  .dz-pane :where(.di-phases) .dph-t { margin: 8px 0 -3px -6px; }
  .dz-pane :where(.di-phases) .dph-row .dph-st { margin-top: 12px; }
  .dz-pane :where(.di-phases) .dph-plan { padding: 12px; grid-template-columns: minmax(0, 1fr); }
  .dz-pane :where(.di-phases) .dph-top .dph-prog-v { font-size: 26px; }
}

/* ── 3 · ДЕЛА ──────────────────────────────────────────────────────────────────
   Строка — две строки текста: название целиком (до двух строк) · ниже срок и итог. Кто / открыть /
   удалить — справа от названия; на узком блоке — справа от срока. Порядок раскладки — `order`,
   разрыв строки — пустой `::after` во всю ширину (DOM строки не трогаем). */
.dz-pane :where(.crmb-acts) .crm-act-row { flex-wrap: wrap; align-items: flex-start; column-gap: 10px; row-gap: 0; padding-top: 8px; padding-bottom: 8px; }
/* длинное название переносится — галочка, вид и значки держатся ПЕРВОЙ строки (строка текста 21 px:
   галочка 22 — вровень, значок 16 — +2.5, кнопки 32 — −5.5), а не середины абзаца */
.dz-pane :where(.crmb-acts) .crm-act-row > .crmb-ck { margin-top: 0; }
.dz-pane :where(.crmb-acts) .crm-act-row > .crm-act-ic { margin-top: 3px; }
.dz-pane :where(.crmb-acts) .crm-act-row > :is(.crm-act-who, .crm-act-go, .crm-act-x) { margin-top: -5px; }
/* разрыв строки: пустая строка нулевой высоты, поэтому row-gap 0 и отступ сверху у второй строки */
.dz-pane :where(.crmb-acts) .crm-act-row::after { content: ""; order: 1; flex: 0 0 100%; height: 0; }
.dz-pane :where(.crmb-acts) .crm-act-row > .crm-act-when, .dz-pane :where(.crmb-acts) .crm-act-row > .crm-act-res { order: 2; margin-top: 6px; }
.dz-pane :where(.crmb-acts) .crm-act-row > .crm-act-when { margin-left: 58px; }
.dz-pane :where(.crmb-acts) .crm-act-ic { width: 16px; height: 16px; padding: 0; border: 0; background: none; }
.dz-pane :where(.crmb-acts) .crm-act-ic .ic { width: 16px; height: 16px; }
.dz-pane :where(.crmb-acts) .crm-act-t { flex: 1 1 0; white-space: normal; overflow-wrap: anywhere; font-weight: 600; }
.dz-pane :where(.crmb-acts) .crm-act-t:focus { background: var(--input-bg); box-shadow: var(--dz-ring); }
.dz-pane :where(.crmb-acts) .crm-act-row.done .crm-act-t { font-weight: 500; }
.dz-pane :where(.crmb-acts) .crm-act-res { flex: 1 1 0; min-width: 0; font-size: 13px; color: var(--dz-text2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dz-pane :where(.crmb-acts) .crm-act-who .tw-av { margin-left: 0; border: 0; }
.dz-pane :where(.crmb-acts) .crm-act-who .ic { width: 16px; height: 16px; }
.dz-pane :where(.crmb-acts) .crm-act-go .ic { width: 18px; height: 18px; }
.dz-pane :where(.crmb-acts) .crm-act-more { width: 100%; margin-top: 8px; }
.dz-pane :where(.crmb-acts) .crm-act-new { gap: 8px; margin-top: 10px; }
.dz-pane :where(.crmb-acts) .crm-act-new .crm-act-in { flex: 1 1 auto; min-width: 0; }

@container dzblk (max-width: 440px) {
  /* кто · открыть · удалить уходят к сроку, название получает всю ширину */
  .dz-pane :where(.crmb-acts) .crm-act-row { column-gap: 6px; }
  .dz-pane :where(.crmb-acts) .crm-act-row > .crmb-ck { margin-right: 4px; }
  .dz-pane :where(.crmb-acts) .crm-act-row > :is(.crm-act-who, .crm-act-go, .crm-act-x) { order: 2; margin-top: 4px; }
  .dz-pane :where(.crmb-acts) .crm-act-row > .crm-act-when { margin-top: 6px; }
  .dz-pane :where(.crmb-acts) .crm-act-row > .crm-act-when { margin-left: 54px; }
  .dz-pane :where(.crmb-acts) .crm-act-row > .crm-act-who { margin-left: auto; }
  .dz-pane :where(.crmb-acts) .crm-act-row > .crm-act-res { order: 3; flex: 1 1 100%; margin-left: 54px; white-space: normal; overflow-wrap: anywhere; }
  /* четыре вида дела — два на два, а не «Задача» одна на третьей строке */
  .dz-pane .crmb-acts .di-sec-h > .crm-act-add { display: grid; grid-template-columns: repeat(2, max-content); }
}
@container dzblk (max-width: 340px) {
  /* телефон: срок — от края строки (под галочкой): срок + три значка = 244 px из 247 */
  .dz-pane :where(.crmb-acts) .crm-act-row > :is(.crm-act-when, .crm-act-res) { margin-left: 0; }
}

/* ── 4 · ЗАДАЧИ ────────────────────────────────────────────────────────────── */
.dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task { flex-wrap: wrap; align-items: flex-start; column-gap: 10px; row-gap: 0; padding-top: 8px; padding-bottom: 8px; }
/* то же правило первой строки: чип 24 — −1.5, аватар 28 — −3.5, крестик 32 — −5.5 */
.dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > .crmb-due { margin-top: -1px; }
.dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > .tw-av { margin-top: -3px; }
.dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > .crmb-taskx { margin-top: -5px; }
.dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > .ai-self-mark { margin-top: 1px; }
.dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task-t { flex: 1 1 0; white-space: normal; overflow-wrap: anywhere; font-weight: 600; }
.dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task.done .crmb-task-t { font-weight: 500; }
.dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task .crmb-num { margin-right: 4px; }
.dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task .tw-av { margin-left: 0; border: 0; }
.dz-pane :where(.dph-free) .crmb-task > .dph-tk-to { margin-top: -5px; }
.dz-pane :where(.dph-tasks, .dph-free) .crmb-task > .crmb-tmeta { gap: 6px 10px; }
.dz-pane :where(.dph-tasks, .dph-free) .crmb-tmeta > .crmb-due { margin-top: -1px; }
@container dzblk (max-width: 440px) {
  .dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task::after { content: ""; order: 1; flex: 0 0 100%; height: 0; }
  .dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > :not(.crmb-ck):not(.crmb-task-t) { order: 2; margin-top: 6px; align-self: center; }
  .dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > :is(.crmb-due, .ai-self-mark) { margin-left: 32px; }
  .dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > .ai-self-mark + .crmb-due { margin-left: 0; }
  .dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > .tw-av, .dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > .crmb-taskx { margin-left: auto; }
  .dz-pane :where(.crmb-tasks, .dph-tasks, .dph-free) .crmb-task > .tw-av + .crmb-taskx { margin-left: 0; }
  .dz-pane :where(.dph-tasks, .dph-free) .crmb-task > .crmb-tmeta { flex: 1 1 0; margin-left: 32px; row-gap: 6px; }
  .dz-pane :where(.dph-tasks, .dph-free) .crmb-task > .dph-tk-to { margin-left: auto; }
  .dz-pane :where(.dph-tasks, .dph-free) .crmb-task > .tw-av + .dph-tk-to { margin-left: 0; }
}

/* ── 5 · ЧЕК-ЛИСТ ──────────────────────────────────────────────────────────── */
.dz-pane :where(.crmb-checklist) .crmb-ckrow { flex-wrap: wrap; align-items: flex-start; column-gap: 10px; row-gap: 0; padding-top: 8px; padding-bottom: 8px; }
.dz-pane :where(.crmb-checklist) .crmb-ckrow > .crmb-ckby { align-self: flex-start; margin-top: 2px; }
.dz-pane :where(.crmb-checklist) .crmb-ckrow > .crmb-ckx { margin-top: -5px; }
.dz-pane :where(.crmb-checklist) .crmb-ckt { flex: 1 1 0; overflow-wrap: anywhere; }
.dz-pane :where(.crmb-checklist) .crmb-ckby { max-width: 40%; }
@container dzblk (max-width: 440px) {
  /* «кто отметил» — под пунктом, а не отнимая у него треть строки */
  .dz-pane :where(.crmb-checklist) .crmb-ckrow::after { content: ""; order: 1; flex: 0 0 100%; height: 0; }
  .dz-pane :where(.crmb-checklist) .crmb-ckrow > .crmb-ckby { order: 2; max-width: none; margin: 2px 0 0 32px; }
}

/* ── 6 · ФАЙЛЫ ─────────────────────────────────────────────────────────────────
   Стили строк вставляет JS (`injectTaskFilesStyles`, `.tip-files-card .tf-*` = 0,2,0, позже
   style.css) — здесь вес (0,3,0) и выше; у светлой темы базы свои `html[data-theme="light"]
   .tip-files-card .tf-row/.tf-thumb/.tf-dl:hover` (0,3,1) — там `.dz-pane.dz-pane` (0,4,0).
   Белые rgba базы в светлой теме не видны — токены вида. */
.dz-pane .crmb-files .tf-drop { gap: 6px; margin: 0; padding: 0; border: 0; border-radius: 16px; }
.dz-pane .crmb-files .tf-drop.dragover { outline: 2px dashed var(--dz-link); outline-offset: 4px; background: color-mix(in srgb, var(--dz-link) 8%, transparent); }
/* пусто — сама зона броска: пунктир и воздух, слово по центру */
.dz-pane .crmb-files .tf-drop:has(> .crmb-empty) { padding: 22px 16px; border: 1.5px dashed var(--dz-edge2); text-align: center; }
.dz-pane .crmb-files .tf-list { gap: 2px; }
.dz-pane.dz-pane .crmb-files .tf-row {
  gap: 12px; min-height: 64px; box-sizing: border-box; margin: 0 -10px; padding: 8px 10px;
  border: 0; border-radius: 14px; background: transparent;
}
.dz-pane.dz-pane .crmb-files .tf-row:hover { background: var(--hover); }
.dz-pane.dz-pane .crmb-files .tf-thumb {
  width: 48px; height: 48px; border-radius: 12px; color: var(--dz-link);
  background: var(--dz-glass2); border: 0; box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .crmb-files .tf-thumb .tf-ic svg.ic { width: 22px; height: 22px; }
.dz-pane .crmb-files .tf-meta { gap: 3px; }
.dz-pane .crmb-files .tf-name { font-size: 15px; font-weight: 600; line-height: 1.35; color: var(--dz-text); }
.dz-pane .crmb-files .tf-sub { font-size: 13px; line-height: 1.35; color: var(--dz-text2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dz-pane .crmb-files .tf-meta:hover .tf-name { color: var(--dz-link); }
.dz-pane .crmb-files :is(.tf-dl, .tf-del) { opacity: 1; width: var(--dz-ib); height: var(--dz-ib); border-radius: 10px; color: var(--dz-text2); }
.dz-pane.dz-pane .crmb-files .tf-dl:hover { color: var(--dz-text); background: var(--dz-glass2); }
.dz-pane .crmb-files .tf-del:hover { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); }
.dz-pane .crmb-files .crmb-act.busy { opacity: .6; }
@container dzblk (max-width: 420px) {
  /* превью слева на две строки: имя и тип — первой, действия — второй, справа */
  .dz-pane .crmb-files .tf-row {
    display: grid; grid-template-columns: 48px minmax(0, 1fr) auto auto auto; column-gap: 12px; row-gap: 2px;
    grid-template-areas: "th meta meta meta meta" "th . b1 b2 b3";
  }
  .dz-pane .crmb-files .tf-thumb { grid-area: th; align-self: center; }
  .dz-pane .crmb-files .tf-meta { grid-area: meta; }
  .dz-pane .crmb-files .tf-row > button.tf-dl { grid-area: b1; }
  .dz-pane .crmb-files .tf-row > a.tf-dl { grid-area: b2; }
  .dz-pane .crmb-files .tf-row > .tf-del { grid-area: b3; }
}

/* ── 7 · СЛЕДУЮЩИЕ ШАГИ ────────────────────────────────────────────────────── */
.dz-pane :where(.di-steps) .di-steps-list { gap: 2px; }
.dz-pane :where(.di-steps) .di-step {
  align-items: flex-start; gap: 12px; min-height: 44px; box-sizing: border-box;
  margin: 0 -10px; padding: 8px 10px; border-radius: 12px;
}
.dz-pane :where(.di-steps) .di-step:hover { background: var(--hover); }
.dz-pane :where(.di-steps) .di-check {
  position: relative; width: 22px; height: 22px; margin-top: 0; border-radius: 7px; padding: 0;
  border: 1.5px solid color-mix(in srgb, var(--dz-text) 34%, transparent); background: var(--input-bg); color: var(--dz-bg);
}
.dz-pane :where(.di-steps) .di-check:hover { border-color: var(--dz-link); }
.dz-pane :where(.di-steps) .di-step.done .di-check { background: var(--dz-ok); border-color: var(--dz-ok); }
.dz-pane :where(.di-steps) .di-check .ic { width: 14px; height: 14px; }
.dz-pane :where(.di-steps) .di-check::after { content: ""; position: absolute; inset: -11px; }
.dz-pane :where(.di-steps) .di-step-txt { margin: 0 -4px; padding: 0 4px; font-size: 15px; line-height: 22px; color: var(--dz-text); overflow-wrap: anywhere; }
.dz-pane :where(.di-steps) .di-step-txt:focus { background: var(--input-bg); box-shadow: var(--dz-ring); }
.dz-pane :where(.di-steps) .di-step.done .di-step-txt { color: var(--dz-text2); text-decoration-color: color-mix(in srgb, var(--dz-text2) 60%, transparent); }
.dz-pane :where(.di-steps) :is(.di-step-plan, .di-step-del) { margin-top: -5px; font-size: 15px; line-height: 1; }
.dz-pane :where(.di-steps) .di-step:hover :is(.di-step-plan, .di-step-del) { opacity: 1; }
.dz-pane :where(.di-steps) .di-addstep { margin-top: 8px; }
/* узкий блок на сенсоре (телефон): «запланировать · удалить» видны всегда — второй строкой справа,
   текст шага — во всю строку. Было (ревью #36): 132 px из 266, фраза из шести слов — в четыре строки.
   Справа их прижимает `justify-content`: первая строка заполнена текстом, свободное место — только
   у второй. Разрыв — пустой `::after` во всю ширину, как у дел и задач (DOM строки не трогаем).
   На мыши значки проявляются по наведению — вторая строка дала бы пустую полосу под каждым шагом
   (кадр 1280 с перепиской), поэтому там они остаются справа в строке. */
@media (hover: none) {
  @container dzblk (max-width: 440px) {
    .dz-pane :where(.di-steps) .di-step { flex-wrap: wrap; justify-content: flex-end; row-gap: 0; }
    .dz-pane :where(.di-steps) .di-step::after { content: ""; order: 1; flex: 0 0 100%; height: 0; }
    .dz-pane :where(.di-steps) .di-step > .di-step-txt { flex: 1 1 0; min-width: 0; }
    .dz-pane :where(.di-steps) .di-step > :is(.di-step-plan, .di-step-del) { order: 2; margin-top: 2px; }
  }
}
.dz-pane :where(.di-steps) .di-addstep-in {
  box-sizing: border-box; width: 100%; height: var(--ctl-h); padding: 0 14px; border-radius: var(--ctl-r);
  border: 1px dashed var(--dz-edge2); background: transparent; box-shadow: none;
  font-family: inherit; font-size: 15px; color: var(--dz-text);
}
.dz-pane :where(.di-steps) .di-addstep-in:hover { border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); }
.dz-pane :where(.di-steps) .di-addstep-in:focus { border-style: solid; border-color: var(--dz-link); box-shadow: var(--dz-ring); }

/* ── 9 · ЦЕЛИ НАЖАТИЯ НА СЕНСОРЕ (ревью #41) ─────────────────────────────────────
   Мелкие цели строк получают поле промаха `::after` БЕЗ сдвига раскладки (как `.dz-lnk`): по высоте —
   до 44, вбок — только в свой зазор (канон tap-target: туда, где пусто; центр соседа остаётся соседу —
   замер `evals/fx.js`, «кражи» нет). Значок вида дела зажат галочкой и названием — вбок ему 1 px;
   тот же вход в карточку дела есть кнопкой «открыть» рядом. */
@media (hover: none) {
  .dz-pane :where(.crmb-acts) .crm-act-row > :is(.crm-act-ic, .crm-act-who, .crm-act-when) { position: relative; }
  .dz-pane :where(.crmb-acts) .crm-act-ic::after { content: ""; position: absolute; inset: -14px -1px; }     /* 16 → 18×44 */
  .dz-pane :where(.crmb-acts) .crm-act-who::after { content: ""; position: absolute; inset: -6px -3px; }     /* 32 → 38×44, 3 px — половина зазора до «открыть» */
  .dz-pane :where(.crmb-acts) .crm-act-when::after { content: ""; position: absolute; inset: -8px -6px; }    /* высота 28 → 44 */
  .dz-pane :where(.di-phases) .dph-grip { position: relative; }
  .dz-pane :where(.di-phases) .dph-grip::after { content: ""; position: absolute; inset: -6px -8px; }        /* 22×32 → 38×44 */
  .dz-pane :where(.di-phases) .dph-pay[role="button"] { position: relative; }
  /* чип оплаты: сверху 9 (над ним название этапа), снизу 11 (под ним статус с отступом 12) */
  .dz-pane :where(.di-phases) .dph-pay[role="button"]::after { content: ""; position: absolute; inset: -9px -4px -11px; }   /* высота 24 → 44 */
}

/* ── 8 · ШАПКИ блоков-половинок: на узком блоке ряд действий — своей строкой под заголовком
   (по краю подписи), а не «Задача» одна на второй строке справа. Значки шапки (ширина · убрать ·
   ручка) остаются В СТРОКЕ ЗАГОЛОВКА: ряд действий уходит после них (`order: 1`). Иначе на мыши,
   где под значки место зарезервировано всегда (общий словарь, ревью #69), они вставали третьей
   строкой — пустая полоса 38 px между «Звонок · Встреча…» и первым делом. ─────────────────── */
@container dzblk (max-width: 560px) {
  .dz-pane .crmb-acts .di-sec-h { flex-wrap: wrap; row-gap: 2px; }
  .dz-pane .crmb-acts .di-sec-h > .crm-act-add { order: 1; flex: 1 1 100%; justify-content: flex-start; margin-left: -10px; }
}
@container dzblk (max-width: 420px) {
  .dz-pane :where(.crmb-tasks, .crmb-checklist, .crmb-files) .di-sec-h:has(> .crmb-hacts) > .crmb-hacts { order: 2; flex: 1 1 100%; justify-content: flex-start; margin-left: -10px; flex-wrap: wrap; }
}
/* мышь, узкий блок (ноутбук 1280 с перепиской): заголовок «Чек-лист по сделке» со счётчиком, «+ Пункт» и
   зарезервированное место под значки шапки в одну строку не помещались — заголовок ломался в четыре
   строки «ЧЕК- / ЛИСТ / ПО / СДЕЛКЕ». Строка 1 — заголовок во всю ширину, разрыв `::after`, строка 2 —
   «+ Пункт» слева и значки шапки справа (рядом с длинным заголовком им места нет: встав отдельной
   строкой, невидимые до наведения значки давали пустую полосу 30 px). У «Задач» и «Файлов» заголовок
   короткий — значки остаются в его строке, ряд действий уходит ниже (правило выше).
   На сенсоре это делает общий словарь (значки там стоят абсолютно, заголовок — во всю строку). */
@media (hover: hover) {
  @container dzblk (max-width: 420px) {
    .dz-pane :where(.crmb-checklist) .di-sec-h { flex-wrap: wrap; row-gap: 2px; }
    .dz-pane :where(.crmb-checklist) .di-sec-h::after { content: ""; order: 1; flex: 0 0 100%; height: 0; }
    .dz-pane :where(.crmb-checklist) .di-sec-h > .crmb-act { order: 2; margin-left: -10px; }
    .dz-pane :where(.crmb-checklist) .di-sec-h > .cblk-acts { order: 3; }
  }
}
/* ── notes ── */
/* ═══════════════════════════════════════════════════════════════════════════
   📝 «ГЛУБИНА» · ВКЛАДКА «ЗАМЕТКИ И ИИ»: заметки (+ теги) · риск · бриф · магия полей ·
   сигналы трекеров · «Спросить по сделке» · переход «Переписка по сделке» · сводка вкладки.
   Только вид: разметка блоков та же, что в «Штиле» (одна реализация), «Штиль» не тронут —
   каждый селектор начинается с `.dz-pane`.
   🔴 Заметки и композер красит `tipNotesCss()` — его <style> вклеивается в <head> ПОСЛЕ
   style.css и при равной специфичности побеждает. Поэтому правила заметок идут с префиксом
   `:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane` (1,2,0+), а не голым `.dz-pane`.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 0 · СВОДКА ВКЛАДКИ (DZ_SUM.notes) — плитки «Обзора», свои только мелочи ───── */
/* плитка без перехода (сигналов нет — вести некуда): не притворяется кнопкой */
.dz-pane .dz-metric.dz-nt-static { cursor: default; }
.dz-pane .dz-metric.dz-nt-static:hover { border-color: var(--dz-edge); }
/* кольцо риска — цветом полосы риска (у «Обзора» кольцо всегда акцентное) */
.dz-pane .dz-ring.dz-nt-low { background: conic-gradient(var(--dz-ok) calc(var(--p) * 1%), var(--dz-track) 0); }
.dz-pane .dz-ring.dz-nt-medium { background: conic-gradient(var(--dz-warn) calc(var(--p) * 1%), var(--dz-track) 0); }
.dz-pane .dz-ring.dz-nt-high { background: conic-gradient(var(--dz-bad) calc(var(--p) * 1%), var(--dz-track) 0); }
/* слово полосы — цветом и словом (канон accent: читается и в ч/б) */
.dz-pane .dz-metric-s b.dz-nt-low { color: var(--dz-ok); }
.dz-pane .dz-metric-s b.dz-nt-medium { color: var(--dz-warn); }
.dz-pane .dz-metric-s b.dz-nt-high { color: var(--dz-bad); }
.dz-pane .dz-metric-s .dz-nt-who { color: var(--dz-text); font-weight: 700; }

/* ── 1 · ПЕРЕХОД «ПЕРЕПИСКА ПО СДЕЛКЕ» ──────────────────────────────────────── */
.dz-pane .dz-chatcta { gap: 16px; padding: 16px 20px; min-height: 76px; }
.dz-pane .dz-chatcta:hover { border-color: var(--dz-edge2); }
.dz-pane .dz-chatcta:focus-visible { outline: 2px solid var(--dz-link); outline-offset: 2px; }
/* значок — в круглой подложке акцента, как значок «Просрочено» (язык шапки) */
.dz-pane .dz-chatcta > svg.ic:first-child {
  width: 44px; height: 44px; padding: 11px; box-sizing: border-box; flex: none; border-radius: 22px;
  color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent);
}
.dz-pane .dz-chatcta > span { min-width: 0; gap: 2px; }
.dz-pane .dz-chatcta > svg.ic:last-child { flex: none; }
/* «— в колонке справа»: колонка переписки стоит справа только шире 1100 (CRMW_PANE_VP в app.js,
   @media в style.css); уже — переписка открывается шторкой, и слова про колонку были неправдой */
@media (max-width: 1100px) { .dz-pane .dz-chatcta .dz-nt-where { display: none; } }

/* ── 2 · ЗАМЕТКИ ─────────────────────────────────────────────────────────────── */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .crmb-notes-list { gap: 10px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note {
  gap: 12px; padding: 14px 16px 16px 12px; border-radius: 16px;
  border: 1px solid var(--dz-edge); background: var(--dz-glass2);
}
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note:hover { border-color: var(--dz-edge2); }
/* закреплённая — тинт и кольцо акцента «внимание» (канон accent: 8–14 % + inset 1px ~26 %) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-pinned {
  border-color: transparent; background: color-mix(in srgb, var(--dz-warn) 8%, var(--dz-glass2));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 30%, transparent);
}
/* «Описание» — поле самой сделки: пунктир говорит «сюда пишут», а не «ещё одна заметка» */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-desc { background: transparent; border: 1px dashed var(--dz-edge2); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-desc:focus-within { border-style: solid; border-color: var(--dz-link); box-shadow: var(--dz-ring); }
/* правка (#55): ОДНА рамка — сама карточка (кромка акцента, кольцо при фокусе); композер внутри
   неё без своей коробки и своего кольца — раньше две фиолетовые рамки стояли в 12 px друг от
   друга. Колонка булавки держится пустым местом 32 px: аватар и имя не прыгают на 44 px влево
   относительно соседних карточек. */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-editing { border-color: var(--dz-link); box-shadow: none; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-editing:focus-within { box-shadow: var(--dz-ring); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-editing::before { content: ""; flex: 0 0 32px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-editing .cc-note-compose,
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-editing .cc-note-compose:focus-within {
  padding: 0; border: 0; border-radius: 0; background: transparent; box-shadow: none;
}
/* булавка: цель 32 px, на сенсоре видна (наводить нечем) — подложка только у включённой */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-chk.pin {
  position: relative; width: 32px; height: 32px; margin: -3px 0 0; border: 0; border-radius: 10px;
  opacity: 1; color: var(--dz-text3); background: transparent;
}
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-chk.pin .ic { width: 16px; height: 16px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes button.tip-note-chk.pin:hover { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 12%, transparent); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes button.tip-note-chk.pin.on { color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 16%, transparent); }
/* булавка «Описания» — не кнопка (оно закреплено всегда, это поле сделки): только значок тихими
   чернилами, без плашки включённого переключателя — иначе читалась как живая и «нажал — ничего» (#53) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-desc .tip-note-chk.pin { color: var(--dz-text3); background: transparent; cursor: default; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes button.tip-note-chk.pin::after { content: ""; position: absolute; inset: -6px; }
/* шапка заметки: аватар · имя · когда · «изменено» */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-top { gap: 4px 8px; min-height: 26px; margin-bottom: 6px; }
/* аватар автора (`.tw-av` из taskAvatarHtml: 22 px с кольцом цвета панели — на стекле кольцо читалось грязной каймой) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-top .tw-av { width: 28px; height: 28px; margin: 0 2px 0 0; border: 0; font-size: 12px; font-weight: 800; }
/* буква на цвете имени (hsl(h 52% 46%) + ccInkOn) на части оттенков давала 4.35:1 — подложку
   сдвигаем на шаг ОТ чернил: под белой буквой темнее, под тёмной светлее. Фон приходит
   ИНЛАЙН-стилем taskAvatarHtml (`background:` гасит background-image), перебить можно только
   !important; фото-аватар (`background-image:url`) этим не задет — у него нет `color:` */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-top .tw-av[style*="color:#fff"] { background-image: linear-gradient(rgba(0,0,0,.14), rgba(0,0,0,.14)) !important; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-top .tw-av[style*="color:#141821"] { background-image: linear-gradient(rgba(255,255,255,.18), rgba(255,255,255,.18)) !important; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-name { font-size: 15px; font-weight: 700; color: var(--dz-text); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-time { font-size: 13px; font-weight: 500; color: var(--dz-text3); }
/* «· изменено» / «· правка» — та же подпись времени. Прозрачность .55 приходит ИНЛАЙН-стилем из
   разметки ccNoteCardHtml (общей с задачами — её не трогаем); перебить инлайн можно только
   !important, иначе подпись в светлой теме падает ниже 4.5:1 */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-time ~ .tip-note-name { opacity: 1 !important; font-size: 13px; font-weight: 500; color: var(--dz-text3); }
/* текст заметки — основной кегль вида */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-body { font-size: 16px; line-height: 1.55; color: var(--dz-text); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-body[data-crmnedit] { cursor: text; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .crmb-desc-edit { min-height: 24px; border-radius: 8px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .crmb-desc-edit:empty::before { color: var(--dz-text3); opacity: 1; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-body.md-note p { margin: 0 0 8px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-body.md-note ul,
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-body.md-note ol { margin: 2px 0 8px; padding-left: 22px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-body.md-note li { margin: 3px 0; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-body.md-note > :last-child { margin-bottom: 0; }
/* файлы заметки — крупнее, радиус внутренних плиток */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-files { gap: 8px; margin-top: 12px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-files .tnf { height: 64px; border-radius: 12px; border-color: var(--dz-edge); background: var(--dz-glass); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-files .tnf.img,
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-files .tnf.vid { width: 88px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-files .tnf.doc {
  gap: 8px; max-width: 100%; box-sizing: border-box; padding: 0 14px; font-size: 14px; font-weight: 600; color: var(--dz-text); text-decoration: none;
}
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-files .tnf.doc .ic { width: 16px; height: 16px; color: var(--dz-text2); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-files .tnf:hover { border-color: var(--dz-edge2); }
/* удалить: на мыши — по наведению (как в базе), на сенсоре — всегда; цель 32 + поле промаха */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-acts { top: 10px; right: 10px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note:focus-within .tip-note-acts { opacity: 1; transform: none; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-ic { position: relative; width: 32px; height: 32px; border-radius: 10px; color: var(--dz-text2); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-ic .ic { width: 16px; height: 16px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-ic:hover { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note:has(> .tip-note-acts) .tip-note-top { padding-right: 36px; }

/* «Показать все (N)» / «Свернуть» (#49) — ссылка-действие словаря (`.di-link`) на месте скрытых
   заметок: между закреплёнными и последними пятью */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .crmb-notes-more { align-self: flex-start; min-height: 32px; margin: 0 0 0 4px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .crmb-notes-more svg.ic { width: 16px; height: 16px; transition: transform .15s; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .crmb-notes-more.is-open svg.ic { transform: rotate(180deg); }
/* отказ загрузки ленты (#48): дверь `ccLoadFail` — та же вёрстка, что у соседних блоков (common) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .crmb-notes-lf .cc-lf { padding: 4px 2px 8px; }

/* композер — поле вида: утопленная подложка, кромка, кольцо фокуса */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose {
  gap: 10px; padding: 12px 14px; border-radius: 16px; border: 1px solid var(--dz-edge2); background: var(--input-bg);
}
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .crmb-note-compose { margin-top: 2px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose:focus-within { border-color: var(--dz-link); box-shadow: var(--dz-ring); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose .rd-box { display: flex; flex-direction: column; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose .rd-box .rd-ce {
  min-height: 52px; padding: 2px; font-size: 16px; line-height: 1.55; color: var(--dz-text); caret-color: var(--dz-link);
}
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose .rd-ce.is-empty::before { color: var(--dz-text3); }
/* значки разметки (`**`, `- `) в поле — тише текста, но читаемы (в базе .55 от --muted = 2.8:1) */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose .rd-ce .rd-mk { color: var(--dz-text3); opacity: 1; }
/* панель форматирования — ПОД текстом и только когда пишут (прогрессивное раскрытие): пустой
   композер в покое — поле и «Файл», а не полка из 13 значков. Под текстом — чтобы её появление
   не сдвигало поле, по которому только что нажали. */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose .rd-box .rd-tb {
  order: 2; gap: 2px; margin: 8px 0 0; padding: 8px 0 0; border-bottom: 0; border-top: 1px solid var(--dz-edge); background: none;
}
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose:not(:focus-within):has(.rd-ce.is-empty) .rd-tb { display: none; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose .rd-box .rd-tb button { width: 34px; height: 34px; border-radius: 10px; color: var(--dz-text2); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose .rd-box .rd-tb button:hover { color: var(--dz-text); background: color-mix(in srgb, var(--dz-text) 8%, transparent); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose .rd-box .rd-tb button.active { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose .rd-tb .rd-sep { background: var(--dz-edge); }
/* ряд «Файл · подсказка · Отмена · Сохранить»: на узкой правке не влезал в строку (вылет 88 px) —
   переносится, действия уходят вправо следующей строкой */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-crow { flex-wrap: wrap; gap: 8px 10px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .ccnc-acts.on { flex-wrap: wrap; justify-content: flex-end; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-hint { font-size: 13px; color: var(--dz-text3); opacity: 1; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-tray { gap: 8px; }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-tray .tnt { width: 64px; height: 64px; border-radius: 12px; border-color: var(--dz-edge); background: var(--dz-glass); }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .ccnc-acts { gap: 8px; }
/* перетаскивание файла на заметку/композер — подсветка ссылочным цветом вида */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes :is(.tip-note, .tip-note-compose).drop-hot {
  outline-color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 10%, var(--dz-glass2));
}

/* теги — сосед заметок в той же обёртке: строка пилюль под карточкой, а НЕ вторая стеклянная
   карточка (общее `.dz-pane .crmb` давало ей рамку, радиус 22 и размытие при нулевом отступе) */
.dz-pane .crmw-blk > .crmb-tags {
  flex: none; gap: 8px; margin: 0; padding: 10px 4px 2px;
  background: none; border: 0; border-radius: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none;
}
.dz-pane .crmb-tags .crmb-tag, .dz-pane .crmb-tags .crmb-tag-add { position: relative; max-width: 100%; }
.dz-pane .crmb-tags .crmb-tag { overflow-wrap: anywhere; text-align: left; }
.dz-pane .crmb-tags :is(.crmb-tag, .crmb-tag-add)::after { content: ""; position: absolute; inset: -8px 0; }
/* теги не загрузились (#48): «Не удалось загрузить теги.» + причина + «Повторить» — строкой ряда */
.dz-pane .crmb-tags > .cc-lf { flex: 1 1 100%; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 4px 12px; padding: 2px 0; font-size: 14px; }
.dz-pane .crmb-tags > .cc-lf .cc-lf-why { font-size: 13px; }

/* блок под липким рядом вкладок: переход сводки (`dzGo`) подводит к блоку, а не под вкладки
   (замер: без отступа «Чат сделки» вставал верхом на 62 px ПОД ряд вкладок). Плитка «Переписка»
   ведёт во «Детали» к «Чату сделки» — ему тот же отступ; вид блока это не меняет. Общее правило
   на все блоки вида (`.dz-pane .crmw-blk`) — дело общего слоя, см. отчёт. */
.dz-pane[data-dzpane="notes"] .crmw-blk, .dz-pane .crmw-blk[data-cb="chatlink"] { scroll-margin-top: 80px; }

/* ── 3 · КНОПКА «ПЕРЕСЧИТАТЬ / ПЕРЕСОБРАТЬ» В ШАПКЕ (риск · бриф) ─────────────── */
.dz-pane :is(.di-risk, .di-brief) .di-mini {
  position: relative; width: var(--ctl-h); height: var(--ctl-h); flex: none; padding: 0;
  border: 0; border-radius: var(--ctl-r); background: transparent; color: var(--dz-text2);
}
.dz-pane :is(.di-risk, .di-brief) .di-mini .ic { width: 18px; height: 18px; }
.dz-pane :is(.di-risk, .di-brief) .di-mini:hover { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 12%, transparent); border-color: transparent; }
.dz-pane :is(.di-risk, .di-brief) .di-mini:focus-visible { outline: 2px solid var(--dz-link); outline-offset: 2px; }
/* занят: `diBusy` пишет В САМУ кнопку «Считаю риск…» — квадрат 40 px становится пилюлей,
   а не ломает подпись по буквам */
.dz-pane :is(.di-risk, .di-brief) .di-mini.busy {
  width: auto; padding: 0 12px; opacity: 1; font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; white-space: nowrap;
  color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 12%, transparent);
}

/* ── 4 · РИСК СДЕЛКИ ─────────────────────────────────────────────────────────── */
.dz-pane .di-risk .di-risk-main { flex-wrap: wrap; gap: 12px 16px; }
.dz-pane .di-risk .di-risk-score {
  align-items: baseline; gap: 2px; padding: 10px 16px 12px; border-radius: 16px; font-weight: 800; font-variant-numeric: tabular-nums;
}
.dz-pane .di-risk .di-risk-num { font-size: 40px; line-height: 1; letter-spacing: -.02em; }
.dz-pane .di-risk .di-risk-den { font-size: 16px; font-weight: 700; opacity: 1; color: var(--dz-text2); }
.dz-pane .di-risk .di-risk-score.band-low { color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-ok) 26%, transparent); }
.dz-pane .di-risk .di-risk-score.band-medium { color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 26%, transparent); }
.dz-pane .di-risk .di-risk-score.band-high { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent); }
.dz-pane .di-risk .di-risk-side { min-width: 0; flex: 1 1 160px; }
.dz-pane .di-risk .di-risk-band { font-size: 18px; font-weight: 800; line-height: 1.3; }
.dz-pane .di-risk .di-risk-band.band-low { color: var(--dz-ok); }
.dz-pane .di-risk .di-risk-band.band-medium { color: var(--dz-warn); }
.dz-pane .di-risk .di-risk-band.band-high { color: var(--dz-bad); }
.dz-pane .di-risk .di-risk-pct { margin-top: 4px; font-size: 14px; line-height: 1.4; color: var(--dz-text2); }
.dz-pane .di-risk .di-risk-expl { font-size: 16px; line-height: 1.55; color: var(--dz-text); }
.dz-pane .di-risk .di-chips { gap: 8px; }
.dz-pane .di-risk .di-chip {
  display: inline-flex; align-items: center; min-height: 28px; box-sizing: border-box; padding: 3px 12px; border: 0; border-radius: 12px;
  font-size: 13px; font-weight: 700; line-height: 1.35; color: var(--dz-text2); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}

/* ── 5 · БРИФ ────────────────────────────────────────────────────────────────── */
.dz-pane .di-brief .di-brief-text { font-size: 16px; line-height: 1.6; color: var(--dz-text); overflow-wrap: anywhere; }
/* факты — внутренние плитки (подпись над значением), а не мелкая таблица «ключ · значение» */
.dz-pane .di-brief .di-facts { grid-template-columns: repeat(auto-fill, minmax(min(100%, 190px), 1fr)); gap: 10px; margin-top: 2px; }
.dz-pane .di-brief .di-fact {
  display: flex; flex-direction: column; gap: 4px; min-width: 0; padding: 12px 14px; border-radius: 14px;
  background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .di-brief .di-fact-k { font-size: 13px; font-weight: 700; letter-spacing: .02em; color: var(--dz-text2); }
.dz-pane .di-brief .di-fact-v { font-size: 15px; font-weight: 600; line-height: 1.45; color: var(--dz-text); overflow-wrap: anywhere; }

/* ── 6 · МАГИЯ ПОЛЕЙ (предложения «было → станет») ──────────────────────────── */
.dz-pane .di-magic .dmagic-body { gap: 12px; }
.dz-pane .di-magic .dmagic-list { gap: 10px; }
.dz-pane .di-magic .dmagic-row {
  grid-template-columns: 24px minmax(0, 1fr); gap: 12px; padding: 14px 16px; border-radius: 16px;
  border: 1px solid var(--dz-edge); background: var(--dz-glass2);
}
.dz-pane .di-magic .dmagic-row:hover { border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); background: color-mix(in srgb, var(--dz-link) 6%, var(--dz-glass2)); }
/* отмеченное поле — кромка акцента (подпись строки от состояния не зависит, меняется рамка) */
.dz-pane .di-magic .dmagic-row:has(input:checked) { border-color: color-mix(in srgb, var(--dz-link) 40%, var(--dz-edge)); }
.dz-pane .di-magic .dmagic-chk { padding-top: 1px; }
.dz-pane .di-magic .dmagic-chk input {
  width: 22px; height: 22px; border-radius: 7px; border: 1.5px solid color-mix(in srgb, var(--dz-text) 34%, transparent); background: var(--input-bg);
}
.dz-pane .di-magic .dmagic-chk input:hover { border-color: var(--dz-link); }
.dz-pane .di-magic .dmagic-chk input:focus-visible { outline: 2px solid var(--dz-link); outline-offset: 2px; }
.dz-pane .di-magic .dmagic-chk input:checked { background: var(--dz-pri); border-color: var(--dz-pri); }
.dz-pane .di-magic .dmagic-chk input:checked::after { left: 6.5px; top: 2.5px; width: 5px; height: 10px; }
.dz-pane .di-magic .dmagic-main { gap: 6px; }
.dz-pane .di-magic .dmagic-label { font-size: 15px; font-weight: 700; color: var(--dz-text); }
.dz-pane .di-magic .dmagic-diff { gap: 6px 8px; font-size: 15px; line-height: 1.45; }
.dz-pane .di-magic .dmagic-before { color: var(--dz-text3); text-decoration-color: color-mix(in srgb, var(--dz-text3) 70%, transparent); overflow-wrap: anywhere; }
.dz-pane .di-magic .dmagic-arrow { color: var(--dz-text3); }
.dz-pane .di-magic .dmagic-after {
  padding: 2px 9px; border-radius: 8px; font-weight: 700; color: var(--dz-text); overflow-wrap: anywhere;
  background: color-mix(in srgb, var(--dz-link) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-link) 26%, transparent);
}
.dz-pane .di-magic .dmagic-ev { font-size: 14px; line-height: 1.5; color: var(--dz-text2); overflow-wrap: anywhere; }
.dz-pane .di-magic .dmagic-foot { flex-wrap: wrap; gap: 10px 14px; margin-top: 2px; }

/* ── 7 · СИГНАЛЫ ТРЕКЕРОВ ────────────────────────────────────────────────────── */
.dz-pane .di-trackers .di-sec-b { gap: 10px; }
/* строка: категория · когда · скрыть — сверху, цитата — во всю ширину под ними (на узком
   цитата больше не режется многоточием на полуслове) */
.dz-pane .di-trackers .di-tr {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "cat time x" "snip snip snip";
  align-items: center; gap: 6px 10px; padding: 10px 8px 14px 16px; border-radius: 16px;
  border: 1px solid var(--dz-edge); background: var(--dz-glass2);
}
.dz-pane .di-trackers .di-tr + .di-tr { margin-top: 0; }
.dz-pane .di-trackers .di-tr-cat {
  grid-area: cat; justify-self: start; padding: 3px 10px; border-radius: 10px;
  font-size: 13px; font-weight: 800; letter-spacing: .05em; line-height: 1.35;
  color: var(--dz-text2); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .di-trackers .di-tr.cat-competitor .di-tr-cat { color: var(--dz-inv); background: color-mix(in srgb, var(--dz-inv) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-inv) 26%, transparent); }
.dz-pane .di-trackers .di-tr.cat-price .di-tr-cat { color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 26%, transparent); }
.dz-pane .di-trackers .di-tr.cat-churn .di-tr-cat { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent); }
.dz-pane .di-trackers .di-tr-time { grid-area: time; min-width: 0; font-size: 13px; color: var(--dz-text3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz-pane .di-trackers .di-tr-snip { grid-area: snip; padding-right: 8px; font-size: 15px; line-height: 1.5; color: var(--dz-text); white-space: normal; overflow: visible; overflow-wrap: anywhere; }
.dz-pane .di-trackers .di-tr-x {
  grid-area: x; position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0; border-radius: 10px; opacity: 1; font-size: 14px; color: var(--dz-text2); background: transparent;
}
.dz-pane .di-trackers .di-tr-x:hover { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); }
.dz-pane .di-trackers .di-tr-x:focus-visible { outline: 2px solid var(--dz-link); outline-offset: 2px; }
.dz-pane .di-trackers .di-tr-x::after { content: ""; position: absolute; inset: -6px; }

/* ── 8 · СПРОСИТЬ ПО СДЕЛКЕ ──────────────────────────────────────────────────── */
.dz-pane .di-ask .di-ask-row { gap: 8px; }
.dz-pane .di-ask .di-ask-in { flex: 1 1 auto; min-width: 0; }
.dz-pane .di-ask .di-ask-ans:not(:empty) { display: flex; flex-direction: column; gap: 10px; }
.dz-pane .di-ask .di-ask-load { gap: 8px; font-size: 15px; color: var(--dz-text2); }
.dz-pane .di-ask .di-ask-load .ic { width: 16px; height: 16px; color: var(--dz-link); }
/* ответ ИИ — плитка с тинтом акцента (канон accent), текст основным кеглем */
.dz-pane .di-ask :is(.di-ask-a, .di-coach) {
  padding: 14px 16px; border: 0; border-radius: 16px; font-size: 16px; line-height: 1.6; color: var(--dz-text);
  background: color-mix(in srgb, var(--dz-link) 8%, var(--dz-glass2)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-link) 22%, transparent);
  overflow-wrap: anywhere;
}
/* «ответа не нашлось» / отказ — нейтральная плитка, не акцент */
.dz-pane .di-ask .di-ask-a.di-ask-empty { font-size: 15px; color: var(--dz-text2); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge); }
.dz-pane .di-ask .di-ask-a.di-ask-src { display: flex; flex-direction: column; padding: 4px 16px; }
.dz-pane .di-ask .di-src { padding: 10px 0; font-size: 15px; line-height: 1.5; color: var(--dz-text); }
.dz-pane .di-ask .di-src + .di-src { border-top-color: var(--dz-edge); }
.dz-pane .di-ask .di-coach { gap: 10px; }
.dz-pane .di-ask .di-coach-s { color: var(--dz-text); }
.dz-pane .di-ask .di-coach-n { gap: 6px; padding-left: 20px; }
.dz-pane .di-ask .di-coach-n li { font-size: 14px; line-height: 1.5; color: var(--dz-text2); }

/* ── 9 · ПЛАШКА «ПРИВЯЗАТЬ ЧАТ» (отказ ИИ no_conversation внутри риска/брифа/магии) ── */
.dz-pane :is(.di-risk, .di-brief, .di-magic) .di-chat-acts { gap: 10px; }

/* ── 10 · СЕНСОР: наводить нечем — действия видны всегда ───────────────────────── */
@media (hover: none) {
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-acts { opacity: 1; transform: none; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-ic::after { content: ""; position: absolute; inset: -6px; }
  /* «⌘V · ⌘↵ · бросьте файл» — подсказки клавиатуры и мыши, на телефоне не к чему */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-hint { display: none; }
}

/* ── 11 · УЗКАЯ КОЛОНКА (телефон, ~300 px полезной ширины) ─────────────────────── */
@container dz (max-width: 640px) {
  /* плитка риска: кольцо + «72» + «/100» не помещались в половину строки (вылет 19 px за плитку) —
     на узком цвет полосы несёт слово под числом, кольцо уходит */
  .dz-pane .dz-nt-sum .dz-ring { display: none; }
  /* заметка во всю ширину: булавка уезжает в правый верхний угол к «удалить», текст не теряет
     колонку слева (на 300 px это 40 px из 230) */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note { padding: 12px 12px 14px 12px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-chk.pin { position: absolute; top: 9px; right: 10px; margin: 0; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note:has(> .tip-note-acts) .tip-note-chk.pin { right: 44px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note .tip-note-top { padding-right: 36px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note:has(> .tip-note-acts) .tip-note-top { padding-right: 68px; }
  /* шапка заметки (#51): аватар · имя — одна строка (имя многоточием), время и «изменено» —
     второй строкой ПОД именем; точка-разделитель в начале строки не стоит. Раньше длинное имя
     раскладывало шапку на три строки: аватар один, имя, «· 11.10». Все карточки — одной формы.
     Первая строка высотой с булавку/корзину (они в углу, 9…41 px) и только ОНА уступает им место
     (отступ справа у имени, а не у всей шапки) — вторая строка ниже кнопок и идёт во всю ширину:
     «5 ч назад · изменено» не режется многоточием. */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note .tip-note-top:has(> .tw-av) {
    display: grid; grid-template-columns: auto auto minmax(0, 1fr); grid-template-rows: minmax(30px, auto) auto;
    align-items: center; gap: 0 8px; min-height: 0; padding-right: 0;
  }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note .tip-note-top:has(> .tw-av) > .tw-av { grid-column: 1; grid-row: 1 / span 2; margin: 0; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note .tip-note-top:has(> .tw-av) > .tw-av + .tip-note-name {
    grid-column: 2 / span 2; grid-row: 1; min-width: 0; margin-right: 36px; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note:has(> .tip-note-acts) .tip-note-top:has(> .tw-av) > .tw-av + .tip-note-name { margin-right: 68px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note .tip-note-top:has(> .tw-av) > .tip-note-time { grid-column: 2; grid-row: 2; line-height: 1.35; white-space: nowrap; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note .tip-note-top:has(> .tw-av) > .tip-note-time ~ .tip-note-name {
    grid-column: 3; grid-row: 2; min-width: 0; margin-left: -4px; line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note .tip-note-top:has(> .tw-av) > .tip-note-time .tip-note-sep { display: none; }
  /* «Описание»: подпись поля — второй строкой без ведущей точки */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-desc .tip-note-time { flex: 1 1 100%; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-desc .tip-note-sep { display: none; }
  /* правка: колонки булавки на узком нет (булавка в углу) — и места под неё не держим */
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note.is-editing::before { content: none; }
  .dz-pane .di-trackers .di-tr { gap: 6px 8px; padding: 10px 6px 12px 12px; }
  .dz-pane .di-trackers .di-tr-cat { letter-spacing: .03em; padding: 3px 8px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .cc-note-compose { padding: 10px 12px; }
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-files .tnf.img,
  :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane .crmb-notes .tip-note-files .tnf.vid { width: 76px; }
  .dz-pane .dz-chatcta { gap: 12px; padding: 14px 16px; }
  .dz-pane .di-risk .di-risk-num { font-size: 34px; }
  .dz-pane .di-magic .dmagic-row { padding: 12px 14px; gap: 10px; }
}
/* ── hist ── */
/* ═══════════════════════════════════════════════════════════════════════════
   🕰 «ГЛУБИНА» · ВКЛАДКА «ИСТОРИЯ» — лента событий (`activity`) и «Автоматизации» (`auto`)
   + сводка `[data-dzsum="hist"]`. Лента читается как таймлайн: группы по дням (подпись дня —
   атрибут `data-day` у первой строки дня, его ставит та же `dealActRowHtml`), строка 16 px,
   значок вида события в кольце (`data-k` → маска значка из ICONS продукта), время справа.
   Рейки слева нет: точка/кольцо, между строками — волосок от колонки текста.
   Узел `.deal-acts` не оборачивается и не пересоздаётся (на нём единственный слушатель) —
   здесь только вид его детей.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 0 · раскладка вкладки ─────────────────────────────────────────────────
   Раскладку задаёт ВКЛАДКА, а не личная ширина блока: лента — главное (первой и шире), журнал
   автоматизаций — рядом. Одна колонка (1280 с перепиской, телефон) — лента ПЕРВОЙ, как и в
   две колонки; широкая колонка вида и видны ОБА блока — лента слева, журнал справа. Значки
   «ширина» и «переставить» на этой вкладке врали бы (нажал — раскладка та же или наоборот),
   поэтому их здесь нет; «Убрать блок» остаётся (сводка это слышит). В «Штиле» оба живы. */
.dz-pane[data-dzpane="hist"] .crmw-grid { grid-template-columns: minmax(0, 1fr); align-items: start; }
.dz-pane[data-dzpane="hist"] .crmw-grid > .crmw-blk { grid-column: 1 / -1; }
.dz-pane[data-dzpane="hist"] .crmw-grid > .crmw-blk[data-cb="activity"] { order: -1; }
.dz-pane[data-dzpane="hist"] .cblk-acts > :is([data-cbact="size"], .cblk-grip) { display: none; }
@media (hover: none) {
  /* на сенсоре шапка держит место под значки — здесь значок один («убрать»): 30 + 8 */
  .dz-pane[data-dzpane="hist"] .di-sec-h.has-cblk > .di-sec-t { padding-right: 40px; }
}
/* строки обоих блоков раскладываются по ширине САМОГО блока, а не колонки: тот же журнал в
   боковой колонке (≈380 px) и на телефоне — узкая раскладка, во всю ширину — широкая */
.dz-pane[data-dzpane="hist"] .crmw-grid > .crmw-blk > .di-sec {
  container: dzhist / inline-size;
  /* обрезка по радиусу без своей прокрутки: `hidden` карточки делал её ловушкой для липкого
     подвала раскрытой ленты (sticky прилипал к карточке, а не к прокрутке страницы) */
  overflow: clip;
}
/* `:has` не вкладывается в `:has` — видимость журнала спрашиваем ребёнком: пустой `.crmauto`
   (прогонов нет) скрыт базой. Колонки — по КЛЮЧУ блока, а не по личной ширине `.full`. */
@container dz (min-width: 980px) {
  .dz-pane[data-dzpane="hist"] .crmw-grid:has(> .crmw-blk[data-cb="activity"]):has(> .crmw-blk[data-cb="auto"] > .di-sec:not(:empty)) {
    grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); grid-auto-flow: row dense;
  }
  .dz-pane[data-dzpane="hist"] .crmw-grid:has(> .crmw-blk[data-cb="activity"]):has(> .crmw-blk[data-cb="auto"] > .di-sec:not(:empty)) > .crmw-blk[data-cb="activity"] { grid-column: 1; }
  .dz-pane[data-dzpane="hist"] .crmw-grid:has(> .crmw-blk[data-cb="activity"]):has(> .crmw-blk[data-cb="auto"] > .di-sec:not(:empty)) > .crmw-blk:not([data-cb="activity"]) { grid-column: 2; }
}

/* ── 1 · СВОДКА «ИСТОРИИ» ──────────────────────────────────────────────────
   Плитки «Обзора» (одна реализация, высота — её же); здесь — только тон значения и подпись
   не длиннее двух строк (тема письма бывает в абзац). */
.dz-pane[data-dzpane="hist"] .dz-metrics.dz-n1 { grid-template-columns: minmax(0, 1fr); }
.dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-v { flex-wrap: wrap; row-gap: 0; }
.dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-v small { white-space: nowrap; }
.dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-v.dz-hv-warn { color: var(--dz-warn); }
.dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-s {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere;
}
.dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-s b.dz-hv-bad { color: var(--dz-bad); font-weight: 700; }
.dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-s b.dz-hv-part { color: var(--dz-warn); font-weight: 700; }

/* ── 2 · ЛЕНТА СОБЫТИЙ ─────────────────────────────────────────────────────
   Значки — маски из словаря ICONS продукта (тот же рисунок, что у `svgIcon`), цвет — токен
   вида события. Неизвестный вид — ровная точка в кольце (новый вид события не ломает ленту). */
/* маски значков — на вкладке: их читают оба блока (лента — виды событий, журнал — шеврон) */
.dz-pane[data-dzpane="hist"], .dz-modal {
  --dz-hi-timer: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cline%20x1%3D%2710%27%20x2%3D%2714%27%20y1%3D%272%27%20y2%3D%272%27%2F%3E%3Cline%20x1%3D%2712%27%20x2%3D%2712%27%20y1%3D%2714%27%20y2%3D%279%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2714%27%20r%3D%278%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-layers: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27m12%202%209%205-9%205-9-5%209-5Z%27%2F%3E%3Cpath%20d%3D%27m3%2012%209%205%209-5%27%2F%3E%3Cpath%20d%3D%27m3%2017%209%205%209-5%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-flag: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M4%2015s1-1%204-1%205%202%208%202%204-1%204-1V3s-1%201-4%201-5-2-8-2-4%201-4%201z%27%2F%3E%3Cline%20x1%3D%274%27%20x2%3D%274%27%20y1%3D%2722%27%20y2%3D%2715%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-funnel: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpolygon%20points%3D%2722%203%202%203%2010%2012.46%2010%2019%2014%2021%2014%2012.46%2022%203%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-envelope: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Crect%20x%3D%272%27%20y%3D%274%27%20width%3D%2720%27%20height%3D%2716%27%20rx%3D%272%27%2F%3E%3Cpath%20d%3D%27m22%207-8.97%205.7a1.94%201.94%200%200%201-2.06%200L2%207%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-phone: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M22%2016.92v3a2%202%200%200%201-2.18%202%2019.79%2019.79%200%200%201-8.63-3.07%2019.5%2019.5%200%200%201-6-6%2019.79%2019.79%200%200%201-3.07-8.67A2%202%200%200%201%204.11%202h3a2%202%200%200%201%202%201.72c.13.96.36%201.9.7%202.81a2%202%200%200%201-.45%202.11L8.09%209.91a16%2016%200%200%200%206%206l1.27-1.27a2%202%200%200%201%202.11-.45c.91.34%201.85.57%202.81.7A2%202%200%200%201%2022%2016.92z%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-usersGroup: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M17%2021v-2a4%204%200%200%200-4-4H5a4%204%200%200%200-4%204v2%27%2F%3E%3Ccircle%20cx%3D%279%27%20cy%3D%277%27%20r%3D%274%27%2F%3E%3Cpath%20d%3D%27M23%2021v-2a4%204%200%200%200-3-3.87%27%2F%3E%3Cpath%20d%3D%27M16%203.13a4%204%200%200%201%200%207.75%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-chatDots: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M21%2011.5a8.38%208.38%200%200%201-.9%203.8%208.5%208.5%200%200%201-7.6%204.7%208.38%208.38%200%200%201-3.8-.9L3%2021l1.9-5.7a8.38%208.38%200%200%201-.9-3.8%208.5%208.5%200%200%201%204.7-7.6%208.38%208.38%200%200%201%203.8-.9h.5a8.48%208.48%200%200%201%208%208v.5z%27%2F%3E%3Ccircle%20cx%3D%278.5%27%20cy%3D%2711.5%27%20r%3D%27.6%27%20fill%3D%27currentColor%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2711.5%27%20r%3D%27.6%27%20fill%3D%27currentColor%27%2F%3E%3Ccircle%20cx%3D%2715.5%27%20cy%3D%2711.5%27%20r%3D%27.6%27%20fill%3D%27currentColor%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-pencil: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M12%2020h9%27%2F%3E%3Cpath%20d%3D%27M16.5%203.5a2.12%202.12%200%200%201%203%203L7%2019l-4%201%201-4Z%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-plus: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M12%205v14%27%2F%3E%3Cpath%20d%3D%27M5%2012h14%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-sparkles: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M9.94%2015.5A2%202%200%200%200%208.5%2014.06l-6.14-1.58a.5.5%200%200%201%200-.96L8.5%209.94A2%202%200%200%200%209.94%208.5l1.58-6.14a.5.5%200%200%201%20.96%200L14.06%208.5A2%202%200%200%200%2015.5%209.94l6.14%201.58a.5.5%200%200%201%200%20.96L15.5%2014.06a2%202%200%200%200-1.44%201.44l-1.58%206.14a.5.5%200%200%201-.96%200z%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-checkCircle: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M22%2011.08V12a10%2010%200%201%201-5.93-9.14%27%2F%3E%3Cpath%20d%3D%27m9%2011%203%203L22%204%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-x: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M18%206%206%2018%27%2F%3E%3Cpath%20d%3D%27m6%206%2012%2012%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-paperclip: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27m21.44%2011.05-9.19%209.19a6%206%200%200%201-8.49-8.49l9.19-9.19a4%204%200%200%201%205.66%205.66l-9.2%209.19a2%202%200%200%201-2.83-2.83l8.49-8.48%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-fileText: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M15%202H6a2%202%200%200%200-2%202v16a2%202%200%200%200%202%202h12a2%202%200%200%200%202-2V7Z%27%2F%3E%3Cpath%20d%3D%27M14%202v4a2%202%200%200%200%202%202h4%27%2F%3E%3Cpath%20d%3D%27M10%209H8%27%2F%3E%3Cpath%20d%3D%27M16%2013H8%27%2F%3E%3Cpath%20d%3D%27M16%2017H8%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-calendar: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Crect%20width%3D%2718%27%20height%3D%2718%27%20x%3D%273%27%20y%3D%274%27%20rx%3D%272%27%2F%3E%3Cpath%20d%3D%27M3%2010h18%27%2F%3E%3Cpath%20d%3D%27M8%202v4%27%2F%3E%3Cpath%20d%3D%27M16%202v4%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-checkSquare: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27m9%2011%203%203L22%204%27%2F%3E%3Cpath%20d%3D%27M21%2012v7a2%202%200%200%201-2%202H5a2%202%200%200%201-2-2V5a2%202%200%200%201%202-2h11%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-user: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M19%2021v-2a4%204%200%200%200-4-4H9a4%204%200%200%200-4%204v2%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%277%27%20r%3D%274%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-userPlus: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M16%2021v-2a4%204%200%200%200-4-4H6a4%204%200%200%200-4%204v2%27%2F%3E%3Ccircle%20cx%3D%279%27%20cy%3D%277%27%20r%3D%274%27%2F%3E%3Cline%20x1%3D%2719%27%20x2%3D%2719%27%20y1%3D%278%27%20y2%3D%2714%27%2F%3E%3Cline%20x1%3D%2722%27%20x2%3D%2716%27%20y1%3D%2711%27%20y2%3D%2711%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-archive: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Crect%20width%3D%2720%27%20height%3D%275%27%20x%3D%272%27%20y%3D%273%27%20rx%3D%271%27%2F%3E%3Cpath%20d%3D%27M4%208v11a1%201%200%200%200%201%201h14a1%201%200%200%200%201-1V8%27%2F%3E%3Cpath%20d%3D%27M10%2012h4%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-alert: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27m21.73%2018-8-14a2%202%200%200%200-3.48%200l-8%2014A2%202%200%200%200%204%2021h16a2%202%200%200%200%201.73-3Z%27%2F%3E%3Cpath%20d%3D%27M12%209v4%27%2F%3E%3Cpath%20d%3D%27M12%2017h.01%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-target: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%2710%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%276%27%2F%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%272%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-coins: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Ccircle%20cx%3D%278%27%20cy%3D%278%27%20r%3D%276%27%2F%3E%3Cpath%20d%3D%27M18.09%2010.37A6%206%200%201%201%2010.34%2018%27%2F%3E%3Cpath%20d%3D%27M7%206h1v4%27%2F%3E%3Cpath%20d%3D%27m16.71%2013.88.7.71-2.82%202.82%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-refresh: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27M3%2012a9%209%200%200%201%209-9%209.75%209.75%200%200%201%206.74%202.74L21%208%27%2F%3E%3Cpath%20d%3D%27M21%203v5h-5%27%2F%3E%3Cpath%20d%3D%27M21%2012a9%209%200%200%201-9%209%209.75%209.75%200%200%201-6.74-2.74L3%2016%27%2F%3E%3Cpath%20d%3D%27M8%2016H3v5%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-clock: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Ccircle%20cx%3D%2712%27%20cy%3D%2712%27%20r%3D%279%27%2F%3E%3Cpath%20d%3D%27M12%207v5l3%202%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-chevronDown: url("data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%272%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27m6%209%206%206%206-6%27%2F%3E%3C%2Fsvg%3E");
  --dz-hi-dot: radial-gradient(circle, currentColor 0 4px, transparent 4.6px);
}
:is(.dz-pane, .dz-modal) .deal-acts .deal-acts-list { display: flex; flex-direction: column; }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act {
  --dz-ht: var(--dz-text2); --dz-hi: var(--dz-hi-dot);
  display: grid; grid-template-columns: 40px minmax(0, 1fr); column-gap: 14px; align-items: start; padding: 0;
}
/* подпись дня — заголовок группы во всю ширину: жирнее строки, но не капсом (капс — у заголовка
   блока, двумя одинаковыми строками подряд они читались бы как один заголовок) */
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-day]::before {
  content: attr(data-day); grid-column: 1 / -1; display: block; padding: 22px 0 4px;
  font-size: 15px; font-weight: 800; line-height: 1.3; letter-spacing: -.005em; color: var(--dz-text);
}
:is(.dz-pane, .dz-modal) .deal-acts .deal-acts-list > .deal-act:first-child[data-day]::before { padding-top: 2px; }
/* кольцо со значком вида события — тон токеном вида (подложка 14 %, кромка 28 %) */
:is(.dz-pane, .dz-modal) .deal-acts .deal-act-dot {
  /* кольцо — вровень с ПЕРВОЙ строкой подписи (у заметки в пять строк оно не уплывает в середину):
     отступ = поле строки 14 − (40 − 22) / 2 */
  position: relative; box-sizing: border-box; width: 40px; height: 40px; margin: 5px 0 0; border-radius: 50%; flex: none;
  color: var(--dz-ht); background: color-mix(in srgb, var(--dz-ht) 14%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-ht) 28%, transparent);
}
:is(.dz-pane, .dz-modal) .deal-acts .deal-act-dot::after {
  content: ""; position: absolute; inset: 0; margin: auto; width: 18px; height: 18px; background: currentColor;
  -webkit-mask: var(--dz-hi) center / contain no-repeat; mask: var(--dz-hi) center / contain no-repeat;
}
/* текст строки: подпись 16 px слева, время справа; волосок между строками дня — от колонки текста */
:is(.dz-pane, .dz-modal) .deal-acts .deal-act-b {
  display: flex; align-items: baseline; gap: 4px 16px; min-width: 0; padding: 14px 0;
  border-top: 1px solid var(--dz-edge);
}
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-day] .deal-act-b { border-top-color: transparent; }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act-k {
  flex: 1 1 auto; min-width: 0; font-size: 16px; font-weight: 600; line-height: 1.4; color: var(--dz-text); overflow-wrap: anywhere;
}
:is(.dz-pane, .dz-modal) .deal-acts .deal-act-m {
  flex: none; margin: 0; font-size: 14px; font-weight: 600; line-height: 1.4; color: var(--dz-text2);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
/* дата уже в подписи группы — у строки остаётся время */
:is(.dz-pane, .dz-modal) .deal-acts .deal-act-md { display: none; }

/* виды событий → значок и тон */
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="stage_changed"], [data-k="stage"], [data-k="status_changed"]) { --dz-hi: var(--dz-hi-flag); --dz-ht: var(--dz-link); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="pipeline_changed"], [data-k="pipeline_tunnel"]) { --dz-hi: var(--dz-hi-funnel); --dz-ht: var(--dz-link); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="phase"], [data-k="template"], [data-k="projects"], [data-k="project"]) { --dz-hi: var(--dz-hi-layers); --dz-ht: var(--dz-link); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="created"], [data-k="deal_created"], [data-k="unarchived"]) { --dz-hi: var(--dz-hi-plus); --dz-ht: var(--dz-link); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="quote"], [data-k="estimate"], [data-k="line_item"], [data-k="esign"]) { --dz-hi: var(--dz-hi-fileText); --dz-ht: var(--dz-link); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k^="ai_"] { --dz-hi: var(--dz-hi-sparkles); --dz-ht: var(--dz-link); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="email"], [data-k="mail_message"], [data-k="mail_thread"]) { --dz-hi: var(--dz-hi-envelope); --dz-ht: var(--dz-inv); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k="call"] { --dz-hi: var(--dz-hi-phone); --dz-ht: var(--dz-inv); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k="meeting"] { --dz-hi: var(--dz-hi-usersGroup); --dz-ht: var(--dz-inv); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="message"], [data-k="chat"], [data-k="conversation"]) { --dz-hi: var(--dz-hi-chatDots); --dz-ht: var(--dz-inv); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="note"], [data-k="comment"], [data-k="commented"]) { --dz-hi: var(--dz-hi-pencil); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="time_logged"], [data-k="time_started"]) { --dz-hi: var(--dz-hi-timer); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="file"], [data-k="attached"], [data-k="attachment"]) { --dz-hi: var(--dz-hi-paperclip); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k="checklist"] { --dz-hi: var(--dz-hi-checkSquare); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k="activity_added"] { --dz-hi: var(--dz-hi-calendar); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k="activity_reopened"] { --dz-hi: var(--dz-hi-refresh); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k="activity_canceled"] { --dz-hi: var(--dz-hi-x); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="owner_changed"], [data-k="routed"], [data-k="user"]) { --dz-hi: var(--dz-hi-user); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="contact_added"], [data-k="contacts"]) { --dz-hi: var(--dz-hi-userPlus); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k="lead_scored"] { --dz-hi: var(--dz-hi-target); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k="archived"] { --dz-hi: var(--dz-hi-archive); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="won"], [data-k="activity_done"]) { --dz-hi: var(--dz-hi-checkCircle); --dz-ht: var(--dz-ok); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k*="pay"], [data-k*="invoice"]) { --dz-hi: var(--dz-hi-coins); --dz-ht: var(--dz-ok); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-k="lost"] { --dz-hi: var(--dz-hi-x); --dz-ht: var(--dz-bad); }
:is(.dz-pane, .dz-modal) .deal-acts .deal-act:is([data-k="rotting"], [data-k="speed_to_lead_breach"]) { --dz-hi: var(--dz-hi-alert); --dz-ht: var(--dz-warn); }

/* пусто — кольцо с часами и слова (текст блока прежний: «Пока нет событий.») */
.dz-pane .deal-acts .deal-acts-empty {
  position: relative; display: flex; align-items: center; box-sizing: border-box; min-height: 40px; padding: 2px 0 2px 54px;
  font-size: 15px; line-height: 1.5; color: var(--dz-text2);
}
.dz-pane .deal-acts .deal-acts-empty::before {
  content: ""; position: absolute; left: 0; top: 50%; width: 40px; height: 40px; margin-top: -20px; border-radius: 50%;
  background: color-mix(in srgb, var(--dz-text2) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-text2) 24%, transparent);
}
.dz-pane .deal-acts .deal-acts-empty::after {
  content: ""; position: absolute; left: 11px; top: 50%; width: 18px; height: 18px; margin-top: -9px; background: var(--dz-text2);
  -webkit-mask: var(--dz-hi-clock) center / contain no-repeat; mask: var(--dz-hi-clock) center / contain no-repeat;
}

/* подвал: «Смотреть все (N)» — вторичная кнопка вида, «Окном» — ссылка справа */
.dz-pane .deal-acts .deal-acts-foot {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 10px; padding-top: 16px;
  border-top: 1px solid var(--dz-edge);
}
.dz-pane .deal-acts .deal-acts-foot .deal-acts-more {
  display: inline-flex; align-items: center; gap: 8px; box-sizing: border-box; min-height: var(--ctl-h); padding: 0 16px;
  border: 1px solid var(--dz-edge2); border-radius: var(--ctl-r); background: var(--dz-glass2);
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; color: var(--dz-text); text-decoration: none;
}
.dz-pane .deal-acts .deal-acts-foot .deal-acts-more:hover {
  color: var(--dz-text); text-decoration: none; border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2));
  background: color-mix(in srgb, var(--dz-text) 10%, transparent);
}
.dz-pane .deal-acts .deal-acts-foot .deal-acts-more::after { inset: -2px 0; }
.dz-pane .deal-acts .deal-acts-foot .di-link svg { width: 16px; height: 16px; }
.dz-pane .deal-acts .deal-acts-foot .deal-acts-win { margin-left: auto; font-size: var(--ctl-fs); font-weight: 700; color: var(--dz-link); }
.dz-pane .deal-acts .deal-acts-foot .deal-acts-win:hover { color: var(--dz-link); }
/* раскрытая лента: в «Глубине» у «Истории» своя вкладка — вложенного окна прокрутки нет (в
   «Штиле» кап держит соседей-блоки на месте, здесь соседей сбоку нет). Подвал «Свернуть»
   прилипает к низу колонки — выход из раскрытого состояния всегда под рукой. */
.dz-pane .deal-acts .deal-acts-list.is-capped { max-height: none; overflow: visible; overscroll-behavior: auto; }
.dz-pane .deal-acts .deal-acts-list.cc-scroll-in::before, .dz-pane .deal-acts .deal-acts-list.cc-scroll-in::after { content: none; }
/* Подвал НЕПРОЗРАЧНЫЙ: размытие под ним не работало (у карточки `.di-sec` своё
   `backdrop-filter`, вложенное размытие браузер не рисует), и строки ленты читались сквозь
   «Свернуть». Подложка — сплошная поверхность вида `--dz-pop` (та же, что у меню «⋯»), над
   подвалом — мягкое затухание ленты вверх. */
.dz-pane .deal-acts:has(> .deal-acts-list.is-capped) > .deal-acts-foot {
  position: sticky; bottom: 0; z-index: 2; margin: 10px -12px 0; padding: 12px; border-top: 0; border-radius: 16px;
  background: var(--dz-pop);
  box-shadow: inset 0 0 0 1px var(--dz-edge), 0 -14px 18px -4px color-mix(in srgb, var(--dz-pop) 88%, transparent);
}
/* на компьютере в левом нижнем углу экрана живёт сквозной пузырь чатов (#qcFab, 56 px), и он
   ложился на край подвала в 5 px от «Свернуть» — подвал отдаёт ему место слева (тот же приём,
   что у подвала окна людей `.pp-foot`). На телефоне пузырь стоит над рельсом, не над лентой. */
@media (min-width: 761px) {
  .dz-pane .deal-acts:has(> .deal-acts-list.is-capped) > .deal-acts-foot { padding-left: 40px; }
}

/* ── 2б · ОКНО «ОКНОМ» В «ГЛУБИНЕ» ─────────────────────────────────────────
   Рама — общая (`ccFormModal`: Escape, фокус, прокрутка тела, «Закрыть»); кожа — вида: небо
   `--dz-bg` с мягким сиянием, Manrope, строки — те же правила ленты, что во вкладке (группы
   дней, кольца со значками, время справа). Окно шире `.pm-wide` (560): на 680 строка
   «подпись — время справа» умещается так же, как во вкладке; на телефоне — узкая раскладка. */
.dz-modal:has(> .pm-body > .dacts-win) {
  width: min(680px, 96vw); border: 1px solid var(--dz-edge2); border-radius: 24px; color: var(--dz-text);
  background:
    radial-gradient(90% 60% at 0% 0%, color-mix(in srgb, var(--dz-a1) 18%, transparent), transparent 70%),
    radial-gradient(70% 50% at 100% 0%, color-mix(in srgb, var(--dz-a2) 14%, transparent), transparent 70%),
    var(--dz-bg);
  box-shadow: var(--dz-shadow);
  font-family: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.dz-modal:has(> .pm-body > .dacts-win) > .pm-head {
  padding: 20px 24px 16px; border-bottom: 1px solid var(--dz-edge);
  font-size: 18px; font-weight: 800; line-height: 1.3; letter-spacing: -.01em; color: var(--dz-text);
}
.dz-modal:has(> .pm-body > .dacts-win) > .pm-body { padding: 6px 24px 18px; max-height: min(70vh, 720px); }
.dz-modal:has(> .pm-body > .dacts-win) > .pm-foot { padding: 14px 24px; border-top: 1px solid var(--dz-edge); }
.dz-modal:has(> .pm-body > .dacts-win) > .pm-foot .primary {
  min-height: var(--ctl-h); padding: 0 22px; border: 0; border-radius: var(--ctl-r);
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; color: #fff; background: var(--dz-grad); box-shadow: var(--dz-glow);
}
.dz-modal:has(> .pm-body > .dacts-win) > .pm-foot .primary:hover { filter: brightness(1.08); }
/* строки окна раскладываются по ширине окна (тот же контейнер, что у блока во вкладке) */
.dz-modal .dacts-win { container: dzhist / inline-size; }
.dz-modal .dacts-win .deal-act { border-bottom: 0; }
.dz-modal .dacts-win .deal-acts-cnt {
  margin-top: 10px; padding-top: 14px; border-top: 1px solid var(--dz-edge); font-size: 14px; line-height: 1.4; color: var(--dz-text2);
}
.dz-modal .dacts-win .deal-acts-cnt b { color: var(--dz-text); font-weight: 800; }
@media (max-width: 560px) {
  .dz-modal:has(> .pm-body > .dacts-win) { border-radius: 20px; }
  .dz-modal:has(> .pm-body > .dacts-win) > :is(.pm-head, .pm-body, .pm-foot) { padding-left: 18px; padding-right: 18px; }
  .dz-modal:has(> .pm-body > .dacts-win) > .pm-head { font-size: 17px; }
}

/* ── 3 · «АВТОМАТИЗАЦИИ» ───────────────────────────────────────────────────
   Стили `.cc-run*`/`.cc-chip` вставляет JS (`#ccChanCss`, `#salesAutoCss`) ПОСЛЕ style.css —
   поэтому селекторы здесь на класс длиннее. Прогон — плитка: слева имя правила и «триггер ·
   время», справа статус словом и цветом и «условия совпали/нет»; шеврон говорит «разверни». */
.dz-pane .crmauto .di-sec-h { align-items: center; gap: 10px; }
.dz-pane .crmauto .di-sec-h .crmauto-cnt {
  display: inline-flex; align-items: center; box-sizing: border-box; min-height: 26px; padding: 2px 10px; border: 0; border-radius: 10px;
  font-size: 13px; font-weight: 700; line-height: 1.35; color: var(--dz-text2); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .crmauto .crmauto-list { display: flex; flex-direction: column; gap: 10px; }
.dz-pane .crmauto .crmauto-list .cc-run {
  margin: 0; padding: 0; border: 1px solid var(--dz-edge); border-radius: 16px; background: var(--dz-glass2);
}
.dz-pane .crmauto .crmauto-list .cc-run:has(.cc-chip.st-error) {
  border-color: color-mix(in srgb, var(--dz-bad) 34%, transparent); background: color-mix(in srgb, var(--dz-bad) 6%, var(--dz-glass2));
}
.dz-pane .crmauto .cc-run .cc-run-head {
  display: grid; grid-template-columns: minmax(0, 1fr) auto 18px; grid-template-areas: "tt chip chev" "tt m chev";
  column-gap: 14px; row-gap: 4px; align-items: center; box-sizing: border-box; min-height: 56px; padding: 14px 16px; border-radius: 15px; cursor: pointer;
}
@media (hover: hover) { .dz-pane .crmauto .cc-run .cc-run-head:hover { background: var(--hover); } }
.dz-pane .crmauto .cc-run .cc-run-head::after {
  content: ""; grid-area: chev; width: 18px; height: 18px; background: var(--dz-text2); transition: transform .16s ease;
  -webkit-mask: var(--dz-hi-chevronDown) center / contain no-repeat; mask: var(--dz-hi-chevronDown) center / contain no-repeat;
}
.dz-pane .crmauto .cc-run.open .cc-run-head::after { transform: rotate(180deg); }
.dz-pane .crmauto .cc-run .cc-run-head .cc-run-tt { grid-area: tt; min-width: 0; font-size: 14px; line-height: 1.45; color: var(--dz-text2); overflow-wrap: anywhere; }
.dz-pane .crmauto .cc-run .cc-run-head .cc-run-nm { display: block; margin: 0 0 2px; font-size: 16px; font-weight: 700; line-height: 1.35; color: var(--dz-text); }
.dz-pane .crmauto .cc-run .cc-run-head .sa-run-matched { grid-area: m; justify-self: end; margin: 0; font-size: 13px; font-weight: 600; line-height: 1.3; color: var(--dz-text2); white-space: nowrap; }
/* статус прогона — чип языка вида: слово + тон токеном (ok · warn · bad · нейтральный) */
.dz-pane .crmauto .cc-run .cc-run-head .cc-chip {
  grid-area: chip; justify-self: end; display: inline-flex; align-items: center; box-sizing: border-box; min-height: 26px; padding: 2px 10px;
  border: 0; border-radius: 10px; font-size: 13px; font-weight: 700; line-height: 1.35; white-space: nowrap;
  color: var(--dz-text2); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge);
}
.dz-pane .crmauto .cc-run .cc-run-head .cc-chip.st-ok { color: var(--dz-ok); background: color-mix(in srgb, var(--dz-ok) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-ok) 26%, transparent); }
.dz-pane .crmauto .cc-run .cc-run-head .cc-chip.st-partial { color: var(--dz-warn); background: color-mix(in srgb, var(--dz-warn) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-warn) 26%, transparent); }
.dz-pane .crmauto .cc-run .cc-run-head .cc-chip.st-error { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 26%, transparent); }
/* шаги прогона (раскрыт): точка-статус · что за шаг · что вышло */
.dz-pane .crmauto .cc-run .cc-run-log { margin: 0 16px; padding: 10px 0 14px; border-top: 1px solid var(--dz-edge); }
.dz-pane .crmauto .cc-run .cc-run-log .cc-run-step {
  display: grid; grid-template-columns: 8px 210px minmax(0, 1fr); column-gap: 12px; align-items: start;
  padding: 6px 0; font-size: 14px; line-height: 1.45; color: var(--dz-text);
}
.dz-pane .crmauto .cc-run .cc-run-log .cc-run-step .dot { width: 8px; height: 8px; margin: 6px 0 0; border-radius: 50%; background: var(--dz-ok); }
.dz-pane .crmauto .cc-run .cc-run-log .cc-run-step.bad .dot { background: var(--dz-bad); }
.dz-pane .crmauto .cc-run .cc-run-log .cc-run-step.waiting .dot { background: var(--dz-link); }
.dz-pane .crmauto .cc-run .cc-run-log .cc-run-step .act { min-width: 0; font-weight: 700; color: var(--dz-text2); overflow-wrap: anywhere; }
.dz-pane .crmauto .cc-run .cc-run-log .cc-run-step > span:last-child { min-width: 0; overflow-wrap: anywhere; }
.dz-pane .crmauto .cc-run .cc-run-log .cc-run-step.bad > span:last-child { color: var(--dz-bad); }
.dz-pane .crmauto .cc-run .cc-run-log .saf-run-out:is(.ok, .yes) { color: var(--dz-ok); }
.dz-pane .crmauto .cc-run .cc-run-log .saf-run-out:is(.fail, .no) { color: var(--dz-warn); }
.dz-pane .crmauto .cc-run .cc-run-log > .muted { font-size: 14px; color: var(--dz-text2); }
/* подсказка про «условия не совпали» — только когда такая строка есть */
.dz-pane .crmauto .crmauto-hint { margin: 2px 0 0; font-size: 14px; line-height: 1.5; color: var(--dz-text3); }
.dz-pane .crmauto:not(:has(.sa-run-nomatch)) .crmauto-hint { display: none; }

/* ── 4 · узкий блок (телефон, боковая колонка) и узкая колонка вида ──────── */
@container dzhist (max-width: 540px) {
  :is(.dz-pane, .dz-modal) .deal-acts .deal-act { grid-template-columns: 36px minmax(0, 1fr); column-gap: 12px; }
  :is(.dz-pane, .dz-modal) .deal-acts .deal-act-dot { width: 36px; height: 36px; margin-top: 4px; }
  :is(.dz-pane, .dz-modal) .deal-acts .deal-act-dot::after { width: 17px; height: 17px; }
  /* время — под подписью: подписи нужна вся ширина (иначе «Программирование» рвался по буквам) */
  :is(.dz-pane, .dz-modal) .deal-acts .deal-act-b { flex-direction: column; align-items: flex-start; gap: 2px; padding: 11px 0; }
  :is(.dz-pane, .dz-modal) .deal-acts .deal-act-k { flex: none; width: 100%; font-size: 15px; overflow-wrap: break-word; }
  :is(.dz-pane, .dz-modal) .deal-acts .deal-act-m { font-size: 13px; }
  :is(.dz-pane, .dz-modal) .deal-acts .deal-act[data-day]::before { padding-top: 20px; }
  /* подвал в одну строку и на 300 px: «Смотреть все (100)» · «Окном» */
  .dz-pane .deal-acts .deal-acts-foot { gap: 8px; }
  .dz-pane .deal-acts .deal-acts-foot .deal-acts-more { gap: 6px; padding: 0 12px; }
  /* прогон: первая строка — статус и «условия…», под ней имя правила во всю ширину */
  .dz-pane .crmauto .cc-run .cc-run-head { grid-template-columns: auto minmax(0, 1fr) 18px; grid-template-areas: "chip m chev" "tt tt tt"; row-gap: 8px; padding: 12px 14px; }
  .dz-pane .crmauto .cc-run .cc-run-head .cc-chip, .dz-pane .crmauto .cc-run .cc-run-head .sa-run-matched { justify-self: start; }
  .dz-pane .crmauto .cc-run .cc-run-head .sa-run-matched { white-space: normal; }
  .dz-pane .crmauto .cc-run .cc-run-log { margin: 0 14px; }
  .dz-pane .crmauto .cc-run .cc-run-log .cc-run-step { grid-template-columns: 8px minmax(0, 1fr); row-gap: 2px; }
  .dz-pane .crmauto .cc-run .cc-run-log .cc-run-step > span:last-child { grid-column: 2; }
}
@container dz (max-width: 640px) {
  .dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-v.dz-hv-word { font-size: 22px; }
  .dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-v { column-gap: 6px; }
  .dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-v small { font-size: 14px; }
  .dz-pane[data-dzpane="hist"] [data-dzhist] .dz-metric-s { -webkit-line-clamp: 3; font-size: 13.5px; }
}
/* ── more ── */
/* ═══════════════════════════════════════════════════════════════════════════
   🗂 «ГЛУБИНА» · ВКЛАДКА «ДЕТАЛИ» — паспорт сделки: Клиент · Деньги и стадия · Сроки и прогноз ·
   Чат сделки · Кабинет заказчика · Дополнительные поля · Кто видит · Наблюдатели.
   Блоки — те же, что в «Штиле» (одна реализация); здесь только их вид в небе «Глубины».
   Правила боковой колонки `.crmw-side …` в этом виде не действуют — поля оформлены заново:
   подпись 13 px над полем, поле во всю ширину, высота `--ctl-h`, сетка полей 2 колонки на
   компьютере и 1 на телефоне. Скоуп — ключ блока реестра `[data-cb=…]` внутри `.dz-pane`.
   ═══════════════════════════════════════════════════════════════════════════ */

/* нативные поля (дата, короткий select) — в схеме цвета темы: значок календаря и раскрытый
   список читаются на тёмном стекле (база: значок даты на тёмном почти не виден) */
.dz-pane[data-dzpane="more"] { color-scheme: dark; }
html[data-theme="light"] :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .dz-pane[data-dzpane="more"] { color-scheme: light; }

/* ── 0 · РАСКЛАДКА ВКЛАДКИ ────────────────────────────────────────────────────
   Блок «Деталей» нужен шириной от ~460 px, иначе поля снова встают в узкий столбик «Штиля».
   Две колонки блоков — только на широкой колонке вида; уже — одна колонка, и внутри блока
   поля ложатся в две. Карточки не тянутся до высоты соседа (пустое стекло под коротким блоком —
   хуже неба между карточками, как на «Обзоре»). */
.dz-pane[data-dzpane="more"] > .crmw-grid { gap: 16px; align-items: start; }
.dz-pane[data-dzpane="more"] > .crmw-grid > .crmw-blk > :is(.di-sec, .crmb, .crmacc) { flex: none; }
@container dz (min-width: 720px) and (max-width: 999px) {
  .dz-pane[data-dzpane="more"] > .crmw-grid { grid-template-columns: minmax(0, 1fr); }
}
/* широкая колонка: «Клиент» и «Доп. поля» (когда поля заведены) — во всю ширину, их строки в
   две колонки. Половиной ширины они вытягивались вдвое-втрое выше соседа, и под «Деньгами»
   зияло пустое небо (замер на «много»: клиент 815 px против 242). Остальные блоки встают
   парами близкой высоты: Деньги | Сроки, Чат | Кабинет, Кто видит | Наблюдатели. Порядок блоков
   по-прежнему решает реестр (перетаскивание не тронуто). */
@container dz (min-width: 1000px) {
  .dz-pane[data-dzpane="more"] > .crmw-grid > .crmw-blk[data-cb="client"] { grid-column: 1 / -1; }
  .dz-pane[data-dzpane="more"] > .crmw-grid > .crmw-blk[data-cb="custom"]:has(.ccx-row) { grid-column: 1 / -1; }
  .dz-pane [data-cb="custom"] .ccx-card { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 36px; }
  .dz-pane [data-cb="custom"] .ccx-card > .ccx-row:nth-child(2) { border-top: 0; }
}

/* ── 1 · ПОЛЯ ФОРМЫ (Деньги и стадия · Сроки и прогноз) ──────────────────────
   Подпись 13 px над полем (обычным регистром — капсом говорит только заголовок блока), поле во
   всю ширину ячейки, высота ряда `--ctl-h`. */
.dz-pane :is([data-cb="money"], [data-cb="dates"]) .di-sec-b {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start;
}
.dz-pane :is([data-cb="money"], [data-cb="dates"]) .deal-field { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.dz-pane :is([data-cb="money"], [data-cb="dates"]) .deal-field > label,
.dz-pane [data-cb="money"] .deal-amount-row::before,
.dz-pane [data-cb="money"] .deal-amount-row::after {
  font-size: 13px; font-weight: 650; line-height: 1.3; letter-spacing: 0; text-transform: none; color: var(--dz-text2);
}
.dz-pane :is([data-cb="money"], [data-cb="dates"]) .deal-field :is(input, select),
.dz-pane :is([data-cb="money"], [data-cb="dates"]) .deal-field .ccpp-field {
  width: 100%; min-height: var(--ctl-h); font-size: 15px;
}
/* сумма · валюта · вероятность: у ряда своих подписей в разметке нет — подписи рисует вид
   (разметку «Штиля» не трогаем), поля стоят ровно под ними */
.dz-pane [data-cb="money"] .deal-amount-row {
  display: grid; align-items: end; column-gap: 10px; row-gap: 8px;
  grid-template-columns: minmax(0, 1fr) 104px 116px;
  grid-template-areas: "la la lp" "amt cur prob";
}
.dz-pane [data-cb="money"] .deal-amount-row::before { content: "Сумма и валюта"; grid-area: la; }
.dz-pane [data-cb="money"] .deal-amount-row::after { content: "Вероятность"; grid-area: lp; }
/* сумма — ровно `--ctl-h`, как соседи по ряду (кегль 18 с полями давал 42 против 40, верх
   уезжал на 2 px; канон control-size). Крупнее и жирнее остальных — только она. */
.dz-pane [data-cb="money"] .deal-amount-in {
  grid-area: amt; box-sizing: border-box; width: 100%; min-width: 0; height: var(--ctl-h); min-height: 0; padding-block: 0; line-height: 1;
  font-size: 18px; font-weight: 800; letter-spacing: -.01em; font-variant-numeric: tabular-nums;
}
.dz-pane [data-cb="money"] .deal-cur { grid-area: cur; width: 100%; min-height: var(--ctl-h); font-size: 15px; }
.dz-pane [data-cb="money"] .deal-prob-wrap { grid-area: prob; display: flex; position: relative; min-width: 0; }
.dz-pane [data-cb="money"] .deal-prob-in {
  width: 100%; min-height: var(--ctl-h); font-size: 15px; font-variant-numeric: tabular-nums;
  -moz-appearance: textfield; appearance: textfield;
}
/* значения полей формы — одним весом 600 (было 400/500/700 вперемешку у соседей одной формы);
   плейсхолдер — тише значения, чтобы пустое не читалось введённым */
.dz-pane :is([data-cb="money"], [data-cb="dates"]) :is(.deal-cur, .deal-prob-in, .deal-close-date, .deal-fcat, .deal-terr, .deal-reason, .ccpp-field, .ccpp-fname, .deal-space-val) { font-weight: 600; }
.dz-pane :is([data-cb="money"], [data-cb="dates"]) :is(input, select)::placeholder { font-weight: 500; color: var(--dz-text3); }
/* стрелки числа поверх «%» мешали прочесть подпись — число правят клавишами и набором */
.dz-pane [data-cb="money"] .deal-prob-in::-webkit-inner-spin-button,
.dz-pane [data-cb="money"] .deal-prob-in::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.dz-pane [data-cb="money"] .deal-prob-wrap > span { right: 11px; font-size: 14px; font-weight: 700; color: var(--dz-text2); }
/* воронка одна — значение не выбирают, оно просто названо: та же высота ряда, рамка тише поля */
.dz-pane [data-cb="money"] .deal-space-val {
  box-sizing: border-box; display: flex; align-items: center; min-height: var(--ctl-h); padding: 0 14px;
  border: 1px solid var(--dz-edge); border-radius: var(--ctl-r); font-size: 15px; font-weight: 600; color: var(--dz-text);
}
.dz-pane [data-cb="money"] .deal-space-val span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* стадия: цветная точка внутри поля, слева от названия */
.dz-pane [data-cb="money"] .deal-stage-row { position: relative; display: block; }
.dz-pane [data-cb="money"] .deal-stage-row > .deal-stage-dot {
  position: absolute; z-index: 1; left: 15px; top: calc(var(--ctl-h) / 2 - 5px); width: 10px; height: 10px; pointer-events: none;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--dz-text) 10%, transparent);
}
.dz-pane [data-cb="money"] .deal-stage-row > select.deal-stage,
.dz-pane [data-cb="money"] .deal-stage-row .ccpp-field { width: 100%; padding-left: 36px; }
.dz-pane [data-cb="money"] .deal-stage-row > .ccpp-wrap { display: block; }
/* поле даты — шрифт и цвет вида (браузер рисовал «дд.мм.гггг» засечками) */
.dz-pane [data-cb="dates"] .deal-close-date { font-variant-numeric: tabular-nums; }
.dz-pane [data-cb="dates"] .deal-close-date::-webkit-calendar-picker-indicator { cursor: pointer; opacity: .75; }
.dz-pane [data-cb="dates"] .deal-close-date::-webkit-calendar-picker-indicator:hover { opacity: 1; }
/* «Причина проигрыша»: выбранная причина — чипом беды в строке подписи, под ними — поле
   комментария. Жирной строкой между подписью и полем она поднимала поле на 29 px выше соседа
   и читалась как второй заголовок. */
.dz-pane [data-cb="dates"] .deal-field:has(> .deal-reason-picked) {
  display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: 10px; row-gap: 8px;
}
.dz-pane [data-cb="dates"] .deal-field:has(> .deal-reason-picked) > :is(input, select) { grid-column: 1 / -1; }
.dz-pane [data-cb="dates"] .deal-reason-picked {
  justify-self: start; box-sizing: border-box; max-width: 100%; min-width: 0; margin: 0; padding: 4px 10px; border-radius: 10px;
  font-size: 13px; font-weight: 700; line-height: 1.35; overflow-wrap: anywhere; color: var(--dz-bad);
  background: color-mix(in srgb, var(--dz-bad) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-bad) 28%, transparent);
}

/* две колонки полей: на компьютере (колонка вида шире телефона) */
@container dz (min-width: 641px) {
  .dz-pane [data-cb="money"] .di-sec-b, .dz-pane [data-cb="dates"] .di-sec-b { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 14px; row-gap: 18px; }
  /* название воронки длиннее названия стадии («Разработка · ЛюблюЕду») — ей больше места */
  .dz-pane [data-cb="money"] .di-sec-b { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); }
  .dz-pane [data-cb="money"] .deal-amount-row { grid-column: 1 / -1; }
  /* «Территория» и «Причина проигрыша» — каждая своей строкой во всю ширину: рядом они
     расходились по высоте (чип причины), одна «Территория» оставляла дыру справа */
  .dz-pane [data-cb="dates"] .di-sec-b > .deal-field:nth-child(n+3) { grid-column: 1 / -1; }
  /* одна воронка (значение не выбирают) и стадия — в ряд; нет воронки — стадия во всю ширину */
  .dz-pane [data-cb="money"] .deal-amount-row + .deal-field:last-child { grid-column: 1 / -1; }
}
/* телефон: сумма — во всю ширину ряда (рядом с валютой 11-значная сумма упиралась в край поля и
   последняя цифра срезалась), валюта — под ней в той же группе «Сумма и валюта»; вероятность —
   своей группой ниже */
@container dz (max-width: 640px) {
  .dz-pane [data-cb="money"] .deal-amount-row {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "la" "amt" "cur" "lp" "prob";
  }
  .dz-pane [data-cb="money"] .deal-cur { width: 120px; justify-self: start; }
  /* причина проигрыша: в ~270 px чип рядом с подписью ломался на две строки — он своей строкой */
  .dz-pane [data-cb="dates"] .deal-field:has(> .deal-reason-picked) { grid-template-columns: minmax(0, 1fr); }
  .dz-pane [data-cb="money"] .deal-amount-row::after { margin-top: 8px; }
  .dz-pane [data-cb="money"] .deal-prob-wrap { width: 132px; }
}

/* ── 2 · КЛИЕНТ ───────────────────────────────────────────────────────────────
   Строки «чьё это» — плитками языка шапки (`.dz-mi`): кружок 40, подпись 13 над значением 16.
   Пустое значение («Не выбран») — ссылочным цветом: это приглашение выбрать. */
.dz-pane [data-cb="client"] .di-sec-b { display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; align-items: start; }
.dz-pane [data-cb="client"] .crmw-owner {
  box-sizing: border-box; width: 100%; min-height: 60px; margin: 0; padding: 10px 14px 10px 11px; gap: 14px;
  border: 1px solid var(--dz-edge); border-radius: 20px; background: var(--dz-glass2); color: var(--dz-text);
  font-family: inherit; text-align: left;
}
.dz-pane [data-cb="client"] .crmw-owner:not(.crmw-rel):hover { background: var(--dz-glass2); border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); }
.dz-pane [data-cb="client"] .crmw-owner:not(.crmw-rel):focus-visible { outline: 2px solid var(--dz-link); outline-offset: 2px; }
.dz-pane [data-cb="client"] .crmw-owner .tw-av { width: 40px; height: 40px; margin: 0; border: 0; font-size: 15px; font-weight: 800; }
.dz-pane [data-cb="client"] .crmw-owner-av {
  width: 40px; height: 40px; box-sizing: border-box; color: var(--dz-text2);
  background: var(--dz-glass); border: 1px solid var(--dz-edge2);
}
.dz-pane [data-cb="client"] .crmw-owner.none > .crmw-owner-av,
.dz-pane [data-cb="client"] .crmw-owner.none .crmw-rel-main > .crmw-owner-av { border-style: dashed; }
.dz-pane [data-cb="client"] .crmw-owner-av .ic { width: 18px; height: 18px; }
/* цвет проекта/темы — точкой в том же кружке 40 (заливать кружок целиком — слишком громко) */
.dz-pane [data-cb="client"] .crmw-owner-av.crmw-prdot { width: 16px; height: 16px; margin: 12px; border: 0; box-shadow: 0 0 0 5px color-mix(in srgb, var(--dz-text) 8%, transparent); }
.dz-pane [data-cb="client"] .crmw-owner-t { gap: 3px; }
.dz-pane [data-cb="client"] .crmw-owner-t > i {
  font-size: 13px; font-weight: 600; line-height: 1.3; letter-spacing: 0; text-transform: none; color: var(--dz-text3);
}
/* значение — до двух строк (длинное имя компании или клиента читается, а не режется на
   первом слове), дальше — отточие; полное значение остаётся в подсказке строки */
.dz-pane [data-cb="client"] .crmw-owner-t > b {
  font-size: 16px; font-weight: 700; line-height: 1.3; color: var(--dz-text);
  white-space: normal; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}
.dz-pane [data-cb="client"] .crmw-owner.none .crmw-owner-t > b { color: var(--dz-link); }
.dz-pane [data-cb="client"] .crmw-owner-go { color: var(--dz-text3); }
.dz-pane [data-cb="client"] .crmw-owner-go .ic { width: 18px; height: 18px; }
/* выбранный клиент: строка → его карточка, «Сменить» — отдельным словом справа */
.dz-pane [data-cb="client"] .crmw-owner.crmw-rel { padding: 0; gap: 0; overflow: hidden; }
.dz-pane [data-cb="client"] .crmw-owner.crmw-rel:hover { background: var(--dz-glass2); border-color: var(--dz-edge2); }
.dz-pane [data-cb="client"] .crmw-owner.crmw-rel:focus-within { border-color: var(--dz-link); }
.dz-pane [data-cb="client"] .crmw-rel-main { gap: 14px; min-height: 58px; padding: 10px 10px 10px 11px; color: var(--dz-text); font-family: inherit; }
.dz-pane [data-cb="client"] .crmw-rel-main:hover { background: var(--hover); }
.dz-pane [data-cb="client"] .crmw-rel-main:hover .crmw-owner-go { color: var(--dz-link); }
.dz-pane [data-cb="client"] .crmw-rel-swap {
  padding: 0 16px; border-left: 1px solid var(--dz-edge); font-family: inherit; font-size: 14px; font-weight: 700; color: var(--dz-link);
}
.dz-pane [data-cb="client"] .crmw-rel-swap:hover { background: color-mix(in srgb, var(--dz-link) 12%, transparent); color: var(--dz-link); }
/* компании проектов сделки — выбор рядом, чипами (подпись выбранного зависит от состояния) */
.dz-pane [data-cb="client"] .crmw-space-chips { gap: 8px; margin: -2px 0 2px; padding: 0 2px; }
.dz-pane [data-cb="client"] .crmw-space-chips .crm-chip {
  min-height: 34px; padding: 0 14px; border-radius: 12px; font-family: inherit; font-size: 14px; font-weight: 700;
  color: var(--dz-text2); background: transparent; border: 1px solid var(--dz-edge2);
}
.dz-pane [data-cb="client"] .crmw-space-chips .crm-chip:hover { color: var(--dz-text); border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); }
.dz-pane [data-cb="client"] .crmw-space-chips .crm-chip.active {
  color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent); border-color: color-mix(in srgb, var(--dz-link) 34%, transparent);
}
/* телефон основного контакта — под его строкой: номер крупно, «Позвонить» — вторичной кнопкой
   (`.dz-pane .cc-phone-row …` сильнее стилей, которые телефония вставляет из JS) */
.dz-pane [data-cb="client"] .cc-phone-row { gap: 10px; margin: 0; padding: 0 2px 0 4px; }
.dz-pane [data-cb="client"] .cc-phone-row .ccp-num { font-size: 16px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--dz-text); }
.dz-pane [data-cb="client"] .cc-phone-row .cc-phone-btn {
  min-height: var(--ctl-h); padding: 0 16px; border-radius: var(--ctl-r); gap: 8px;
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; color: var(--dz-text);
  background: var(--dz-glass2); border: 1px solid var(--dz-edge2);
}
.dz-pane [data-cb="client"] .cc-phone-row .cc-phone-btn:hover { border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); background: color-mix(in srgb, var(--dz-text) 10%, transparent); }
/* роли основного контакта и остальные люди клиента — под строкой «Контакты» */
.dz-pane [data-cb="client"] .crmw-subs { gap: 8px; margin: 0; padding: 0; }
.dz-pane [data-cb="client"] .crmw-roles { gap: 8px; padding: 2px 2px 2px 4px; }
.dz-pane [data-cb="client"] .crmw-roles .crmw-sub-t { font-size: 14px; color: var(--dz-text2); }
.dz-pane [data-cb="client"] .crm-rchips { gap: 6px; }
.dz-pane [data-cb="client"] .crm-rchip {
  display: inline-flex; align-items: center; min-height: 24px; padding: 0 10px; border: 0; border-radius: 10px;
  font-size: 13px; font-weight: 700; color: var(--dz-link);
  background: color-mix(in srgb, var(--dz-link) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--dz-link) 26%, transparent);
}
.dz-pane [data-cb="client"] .crm-rchip.muted { color: var(--dz-text2); background: var(--dz-glass2); box-shadow: inset 0 0 0 1px var(--dz-edge); font-weight: 600; }
.dz-pane [data-cb="client"] .crmw-sub {
  align-items: stretch; border: 1px solid var(--dz-edge); border-radius: 18px; background: var(--dz-glass2);
}
.dz-pane [data-cb="client"] .crmw-sub:hover { border-color: var(--dz-edge2); }
.dz-pane [data-cb="client"] .crmw-sub-main { flex-basis: 180px; gap: 12px; min-height: 56px; padding: 8px 10px 8px 11px; color: var(--dz-text); font-family: inherit; }
.dz-pane [data-cb="client"] .crmw-sub .tw-av { width: 34px; height: 34px; margin: 0; border: 0; font-size: 13px; font-weight: 800; }
.dz-pane [data-cb="client"] .crmw-sub-txt { gap: 3px; }
/* имя — до двух строк, как у основного контакта (в одну строку резалось «Александр Владимир…») */
.dz-pane [data-cb="client"] .crmw-sub-n {
  font-size: 15px; font-weight: 700; line-height: 1.3; color: var(--dz-text);
  white-space: normal; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
}
.dz-pane [data-cb="client"] .crmw-sub-t { font-size: 13px; color: var(--dz-text2); }
.dz-pane [data-cb="client"] .crmw-sub-txt .crm-rchips { margin-top: 3px; }
.dz-pane [data-cb="client"] .crmw-sub-acts { align-items: stretch; }
.dz-pane [data-cb="client"] .crmw-sub-a {
  min-height: 44px; padding: 0 12px; border-left: 1px solid var(--dz-edge); font-family: inherit;
  font-size: 14px; font-weight: 700; color: var(--dz-link); background: transparent;
}
.dz-pane [data-cb="client"] .crmw-sub-a[data-ccdrop] { color: var(--dz-text2); }
.dz-pane [data-cb="client"] .crmw-sub-a:hover { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 12%, transparent); }
.dz-pane [data-cb="client"] .crmw-sub-a[data-ccdrop]:hover { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 12%, transparent); }
/* кнопка «＋ Роль» у основного — ссылкой-пилюлей справа */
.dz-pane [data-cb="client"] .crmw-roles .crmw-sub-a { min-height: 32px; border: 1px solid var(--dz-edge2); border-radius: 12px; padding: 0 12px; }

/* плитка остального человека клиента не шире ~490 px ни на одном экране (компьютер — полколонки,
   телефон — вся колонка): действия — своей строкой плитки, поровну, с разделителем сверху, имя
   получает всю ширину. В ряд с именем три слова «＋ Роль · Основной · Убрать» съедали ~245 px, и
   имя резалось на 180 px. В ряду из двух плиток разной высоты действия прижаты к низу. */
.dz-pane [data-cb="client"] .crmw-sub { align-content: space-between; }
.dz-pane [data-cb="client"] .crmw-sub-acts { flex: 1 0 100%; border-top: 1px solid var(--dz-edge); }
.dz-pane [data-cb="client"] .crmw-sub-acts > .crmw-sub-a { flex: 1 1 0; justify-content: center; }
.dz-pane [data-cb="client"] .crmw-sub-acts > .crmw-sub-a:first-child { border-left: 0; }
/* карточка клиента шире телефона: строки — в две колонки. Чипы пространства — строкой под
   «Пространством». «Контакты» встают СЛЕВА, «Компания клиента» — справа: тогда телефон и роли
   основного контакта ложатся полосой прямо под его плиткой, а остальные люди клиента — сеткой
   2 колонки во всю ширину. Раньше всё это жило только в правой колонке, и под «Компанией»
   зияла пустота до ~560 px стекла (замер на шести контактах). */
@container dz (min-width: 641px) {
  .dz-pane [data-cb="client"] .di-sec-b, .dz-pane [data-cb="dossier"] > .di-sec:first-child:not(:last-child) > .di-sec-b { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-auto-flow: row dense; column-gap: 12px; }
  .dz-pane [data-cb="client"] .di-sec-b > .crmw-space-chips, .dz-pane [data-cb="dossier"] > .di-sec:first-child:not(:last-child) > .di-sec-b > .crmw-space-chips { grid-column: 1 / -1; }
  .dz-pane [data-cb="client"] .di-sec-b > :is(.crmw-owner[data-crmcontact], .crmw-owner:has(> [data-crmcontact])) { grid-column: 1; }
  .dz-pane [data-cb="client"] .di-sec-b > :is(.crmw-owner[data-crmcompany], .crmw-owner:has(> [data-crmcompany])) { grid-column: 2; }
  .dz-pane [data-cb="client"] .di-sec-b > :is(.cc-phone-row, .crmw-subs) { grid-column: 1 / -1; }
  .dz-pane [data-cb="client"] .crmw-subs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 12px; }
  .dz-pane [data-cb="client"] .crmw-subs > .crmw-roles { grid-column: 1 / -1; }
  /* «＋ Роль» основного — сразу за его чипами, а не на дальнем краю под чужой плиткой */
  .dz-pane [data-cb="client"] .crmw-roles .crmw-sub-a { margin-left: 4px; }
}

/* ── 3 · ЧАТ СДЕЛКИ ───────────────────────────────────────────────────────── */
.dz-pane [data-cb="chatlink"] .di-sec-b { gap: 16px; }
.dz-pane [data-cb="chatlink"] .di-empty { max-width: 46ch; }
.dz-pane [data-cb="chatlink"] .di-chat-row { gap: 14px; }
.dz-pane [data-cb="chatlink"] .di-chat-name {
  gap: 12px; min-height: 56px; padding: 8px 16px 8px 10px; border: 1px solid var(--dz-edge); border-radius: 18px;
  background: var(--dz-glass2); font-size: 16px; font-weight: 700; color: var(--dz-text);
}
.dz-pane [data-cb="chatlink"] .di-chat-name svg.ic {
  box-sizing: border-box; width: 38px; height: 38px; padding: 10px; border-radius: 19px;
  color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent);
}
.dz-pane [data-cb="chatlink"] .di-chat-acts { gap: 6px 14px; }

/* ── 4 · КАБИНЕТ ЗАКАЗЧИКА ─────────────────────────────────────────────────
   Статус чипами · ссылка · действия. Главное действие блока — «Скопировать» (ссылку отправляют
   клиенту) и «Создать ссылку» — сплошным акцентом; «Отозвать» — коралловой кромкой беды. */
.dz-pane [data-cb="portal"] .dpor { display: flex; flex-direction: column; gap: 14px; }
.dz-pane [data-cb="portal"] .dpor-head { gap: 8px; margin: 0; }
.dz-pane [data-cb="portal"] .dpor-warn {
  gap: 8px; margin: 0; padding: 10px 14px; border-radius: 14px; font-size: 14px; line-height: 1.45; color: var(--dz-text);
}
.dz-pane [data-cb="portal"] .dpor-url {
  width: 100%; margin: 0; padding: 0 14px; text-overflow: ellipsis;
  font-size: 14px; font-weight: 600; color: var(--dz-text2); cursor: text;
}
.dz-pane [data-cb="portal"] .dc-acts { gap: 8px; }
.dz-pane [data-cb="portal"] .dc-a:is([data-dpor-act="copy"], [data-dpor-act="make"]) {
  color: #fff; background: var(--dz-pri); border-color: transparent;
}
.dz-pane [data-cb="portal"] .dc-a:is([data-dpor-act="copy"], [data-dpor-act="make"]):hover {
  color: #fff; background: var(--dz-pri-hi); border-color: transparent; box-shadow: 0 6px 18px color-mix(in srgb, var(--dz-pri) 32%, transparent);
}
.dz-pane [data-cb="portal"] .dc-a[data-dpor-act="revoke"] { color: var(--dz-bad); border-color: color-mix(in srgb, var(--dz-bad) 40%, transparent); }
.dz-pane [data-cb="portal"] .dc-a[data-dpor-act="revoke"]:hover { color: var(--dz-bad); border-color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 10%, transparent); }

/* ── 5 · ДОПОЛНИТЕЛЬНЫЕ ПОЛЯ ─────────────────────────────────────────────────
   Блок — карточка реестра `crmWsCard` (patch.py п.7): стекло, заголовок с иконкой и действия
   шапки «скрыть / перетащить» — общим языком `.dz-pane .di-sec`, как у соседей. Здесь — строки. */
.dz-pane [data-cb="custom"] .ccx-host { gap: 14px; }
/* заголовок теперь у карточки — подпись «Поля» над списком лишняя */
.dz-pane [data-cb="custom"] .ccx-label { display: none; }
.dz-pane [data-cb="custom"] .ccx-card { border: 0; border-radius: 0; background: transparent; overflow: visible; }
.dz-pane [data-cb="custom"] .ccx-row { gap: 10px; min-height: 54px; padding: 6px 0; }
.dz-pane [data-cb="custom"] .ccx-row + .ccx-row { border-top: 1px solid var(--dz-edge); }
.dz-pane [data-cb="custom"] .ccx-row-name { max-width: 46%; font-size: 15px; font-weight: 500; color: var(--dz-text2); }
.dz-pane [data-cb="custom"] .ccx-row-name:hover,
.dz-pane [data-cb="custom"] .ccx-row-name:focus-visible { color: var(--dz-text); background: color-mix(in srgb, var(--dz-link) 10%, transparent); }
.dz-pane [data-cb="custom"] .ccx-row-name.editing { color: var(--dz-text); background: var(--input-bg); box-shadow: var(--dz-ring); }
.dz-pane [data-cb="custom"] .ccx-row-name:empty::before { color: var(--dz-text3); }
/* значение справа: без рамки в покое, подсветка — по наведению и фокусу */
.dz-pane [data-cb="custom"] .ccx-in {
  box-sizing: border-box; min-height: var(--ctl-h); padding: 4px 10px; border-radius: 10px; text-overflow: ellipsis;
  font-size: 15px; font-weight: 700; color: var(--dz-text);
}
.dz-pane [data-cb="custom"] .ccx-in:hover { background: var(--hover); }
.dz-pane [data-cb="custom"] .ccx-in:focus { background: var(--input-bg); box-shadow: var(--dz-ring); }
.dz-pane [data-cb="custom"] .ccx-in::placeholder { color: var(--dz-text3); font-weight: 500; }
.dz-pane [data-cb="custom"] .ccx-date { width: auto; color-scheme: inherit; font-variant-numeric: tabular-nums; }
.dz-pane [data-cb="custom"] .ccx-row-val .ccpp-field,
.dz-pane [data-cb="custom"] .ccx-user {
  width: auto; max-width: 100%; min-height: 36px; padding: 0 10px; margin-right: -2px; gap: 8px;
  border: 0; border-radius: 10px; background: transparent; box-shadow: none; justify-content: flex-end;
  font-family: inherit; font-size: 15px; font-weight: 700; color: var(--dz-text);
}
.dz-pane [data-cb="custom"] .ccx-row-val .ccpp-wrap { display: flex; justify-content: flex-end; }
.dz-pane [data-cb="custom"] .ccx-row-val .ccpp-field:hover,
.dz-pane [data-cb="custom"] .ccx-user:hover { border: 0; background: var(--hover); box-shadow: none; }
.dz-pane [data-cb="custom"] .ccx-row-val .ccpp-field.open { background: var(--input-bg); box-shadow: var(--dz-ring); }
/* фокус с клавиатуры виден так же, как у текстовых значений (кольцо вида), а не пропадает */
.dz-pane [data-cb="custom"] :is(.ccx-row-val .ccpp-field, .ccx-user):focus-visible { outline: none; background: var(--input-bg); box-shadow: var(--dz-ring); }
.dz-pane [data-cb="custom"] .ccx-check:focus-visible { outline: none; box-shadow: var(--dz-ring); }
.dz-pane [data-cb="custom"] .ccx-row-val .ccpp-field:hover .ccpp-fname,
.dz-pane [data-cb="custom"] .ccx-user:hover .ccpp-fname { color: var(--dz-link); }
/* пустое значение — ОДНИМ видом у всех типов: тихое «Не задано» (как плейсхолдер числа и
   текста). Было четыре вида: жирное «— не задано —» у списка, «○ Не задано» у сотрудника,
   жирное «дд.мм.гггг» у даты — пустые список и дата читались введёнными значениями. */
.dz-pane [data-cb="custom"] .ccx-user-none .ccpp-fname,
.dz-pane [data-cb="custom"] .ccx-user-legacy,
.dz-pane [data-cb="custom"] .ccx-row-val:has(> select.ccx-sel option[value=""]:checked) .ccpp-fname { color: var(--dz-text3); font-weight: 500; }
.dz-pane [data-cb="custom"] .ccx-user-none > .ccpp-dot-none { display: none; }
.dz-pane [data-cb="custom"] .ccx-date.ccx-empty:not(:focus) { color: var(--dz-text3); font-weight: 500; }
.dz-pane [data-cb="custom"] .ccx-user .tw-av { width: 26px; height: 26px; margin: 0; border: 0; font-size: 11px; }
.dz-pane [data-cb="custom"] .ccx-check {
  position: relative; width: 24px; height: 24px; margin-right: 8px; border-radius: 7px;
  border: 1.5px solid color-mix(in srgb, var(--dz-text) 34%, transparent); background: var(--input-bg);
}
.dz-pane [data-cb="custom"] .ccx-check:hover { border-color: var(--dz-link); }
.dz-pane [data-cb="custom"] .ccx-check.on { background: var(--dz-pri); border-color: var(--dz-pri); }
.dz-pane [data-cb="custom"] .ccx-check .ic { width: 15px; height: 15px; }
/* поле промаха 44: коробка 24 с рамкой 1.5 → от padding-box 21 нужно по 11.5 с каждой стороны */
.dz-pane [data-cb="custom"] .ccx-check::after { content: ""; position: absolute; inset: -11.5px; }
.dz-pane [data-cb="custom"] .ccx-row-val { flex: 1 1 0; min-width: 0; }
.dz-pane [data-cb="custom"] .ccx-row-val .ccpp-field, .dz-pane [data-cb="custom"] .ccx-user { min-width: 0; }
/* человек в поле — значение на своей строке только там, где рядом с подписью ему тесно */
.dz-pane [data-cb="custom"] .ccx-row-user .ccx-row-name { max-width: 46%; }
.dz-pane [data-cb="custom"] .ccx-row-user .ccx-row-val { flex: 1 1 auto; }
/* телефон: подпись поля НАД значением, как у полей формы (рядом им тесно: «Бюджет про…»);
   значение — слева под своей подписью, «⋯» — справа в строке подписи */
@container dz (max-width: 640px) {
  .dz-pane [data-cb="custom"] .ccx-row { flex-wrap: wrap; align-items: center; row-gap: 2px; padding: 8px 0 10px; }
  .dz-pane [data-cb="custom"] .ccx-row .ccx-row-name { flex: 1 1 0; min-width: 0; max-width: none; font-size: 14px; }
  .dz-pane [data-cb="custom"] .ccx-row .ccx-row-val { flex: 1 0 100%; justify-content: flex-start; margin-left: -10px; }
  .dz-pane [data-cb="custom"] .ccx-row .ccx-in { text-align: left; }
  .dz-pane [data-cb="custom"] .ccx-row-val .ccpp-wrap { justify-content: flex-start; }
  .dz-pane [data-cb="custom"] .ccx-row-val .ccpp-field, .dz-pane [data-cb="custom"] .ccx-user { justify-content: flex-start; }
  .dz-pane [data-cb="custom"] .ccx-check { margin: 6px 0 4px 10px; }
}
/* «+ Добавить поле» — ссылка-действие вида (база красила `--primary`: 4.36 на тёмном стекле) */
.dz-pane [data-cb="custom"] .ccx-add-btn {
  position: relative; min-height: var(--ctl-h); margin-left: -10px; padding: 0 10px; gap: 8px; border-radius: var(--ctl-r);
  font-size: 15px; font-weight: 700; color: var(--dz-link);
}
.dz-pane [data-cb="custom"] .ccx-add-btn:hover { background: color-mix(in srgb, var(--dz-link) 12%, transparent); }
.dz-pane [data-cb="custom"] .ccx-plus { font-size: 20px; font-weight: 600; }
/* форма нового поля — плитка внутри карточки */
.dz-pane [data-cb="custom"] .ccx-form { gap: 12px; padding: 16px; border: 1px solid var(--dz-edge); border-radius: 18px; background: var(--dz-glass2); }
.dz-pane [data-cb="custom"] .ccx-type-chips { gap: 8px; }
.dz-pane [data-cb="custom"] .ccx-type-chip {
  min-height: 34px; padding: 0 14px; border-radius: 12px; font-size: 14px; font-weight: 700;
  color: var(--dz-text2); background: transparent; border: 1px solid var(--dz-edge2);
}
.dz-pane [data-cb="custom"] .ccx-type-chip:hover { color: var(--dz-text); border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); }
.dz-pane [data-cb="custom"] .ccx-type-chip.on { color: var(--dz-link); background: color-mix(in srgb, var(--dz-link) 14%, transparent); border-color: color-mix(in srgb, var(--dz-link) 34%, transparent); }
.dz-pane [data-cb="custom"] .ccx-form-acts { gap: 8px; }
.dz-pane [data-cb="custom"] .ccx-form-acts .ghost.small {
  display: inline-flex; align-items: center; justify-content: center; min-height: var(--ctl-h); padding: 0 16px;
  border: 1px solid var(--dz-edge2); border-radius: var(--ctl-r); font-family: inherit; font-size: var(--ctl-fs); font-weight: 700;
  color: var(--dz-text); background: var(--dz-glass2);
}
.dz-pane [data-cb="custom"] .ccx-form-acts .ghost.small:hover { border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); background: color-mix(in srgb, var(--dz-text) 10%, transparent); }
/* отказ загрузки полей — внутри карточки, без страничных отступов */
.dz-pane [data-cb="custom"] .cc-cv-empty.cc-lf { padding: 0; }

/* ── 6 · КТО ВИДИТ ─────────────────────────────────────────────────────────── */
.dz-pane [data-cb="access"] .crmacc-sw { gap: 16px; padding: 2px 0; }
.dz-pane [data-cb="access"] .crmacc-sw-t { gap: 4px; }
.dz-pane [data-cb="access"] .crmacc-sw-t > b { font-size: 16px; font-weight: 700; color: var(--dz-text); }
.dz-pane [data-cb="access"] .crmacc-sw-t > i { font-size: 14px; line-height: 1.45; color: var(--dz-text2); }
/* тумблер: выключенная дорожка видна на стекле обеих тем (база: `--line` = 12 % белого) */
.dz-pane [data-cb="access"] .cc-switch { width: 50px; height: 30px; }
.dz-pane [data-cb="access"] .cc-switch-tr { background: color-mix(in srgb, var(--dz-text) 24%, transparent); }
.dz-pane [data-cb="access"] .cc-switch-tr::before { width: 24px; height: 24px; }
.dz-pane [data-cb="access"] .cc-switch input:checked + .cc-switch-tr { background: var(--dz-pri); }
.dz-pane [data-cb="access"] .cc-switch input:checked + .cc-switch-tr::before { transform: translateX(20px); }
.dz-pane [data-cb="access"] .cc-switch input:focus-visible + .cc-switch-tr { box-shadow: var(--dz-ring); }
.dz-pane [data-cb="access"] .crmacc-list { gap: 2px; margin-top: 4px; padding-top: 10px; border-top: 1px solid var(--dz-edge); }
.dz-pane [data-cb="access"] .crmacc-it { min-height: 46px; gap: 12px; margin: 0 -10px; padding: 6px 10px; border-radius: 12px; }
.dz-pane [data-cb="access"] .crmacc-it .tw-av { width: 30px; height: 30px; margin: 0; border: 0; font-size: 12px; font-weight: 800; }
.dz-pane [data-cb="access"] .crmacc-dot { width: 12px; height: 12px; margin: 0 9px; }
.dz-pane [data-cb="access"] .crmacc-nm { font-size: 15px; color: var(--dz-text); }
.dz-pane [data-cb="access"] .crmacc-it.stale .crmacc-nm { color: var(--dz-text2); }
.dz-pane [data-cb="access"] .crmacc-stale { margin-top: 3px; font-size: 13px; font-weight: 600; color: var(--dz-warn); }
.dz-pane [data-cb="access"] .crmacc-x {
  position: relative; width: 32px; height: 32px; border-radius: 10px; color: var(--dz-text2); opacity: 0;
}
.dz-pane [data-cb="access"] .crmacc-x .ic { width: 16px; height: 16px; }
.dz-pane [data-cb="access"] .crmacc-it:hover .crmacc-x, .dz-pane [data-cb="access"] .crmacc-x:focus-visible { opacity: 1; }
.dz-pane [data-cb="access"] .crmacc-x:hover { color: var(--dz-bad); background: color-mix(in srgb, var(--dz-bad) 14%, transparent); }
@media (hover: none) {
  .dz-pane [data-cb="access"] .crmacc-x { opacity: 1; }
  .dz-pane [data-cb="access"] .crmacc-x::after { content: ""; position: absolute; inset: -6px 0; }
}
.dz-pane [data-cb="access"] .crmacc-add {
  min-height: var(--ctl-h); margin-top: 6px; padding: 0 16px 0 12px; gap: 8px; border: 1px solid var(--dz-edge2); border-radius: var(--ctl-r);
  font-family: inherit; font-size: var(--ctl-fs); font-weight: 700; color: var(--dz-text); background: var(--dz-glass2);
}
.dz-pane [data-cb="access"] .crmacc-add:hover { color: var(--dz-text); border-color: color-mix(in srgb, var(--dz-link) 45%, var(--dz-edge2)); background: color-mix(in srgb, var(--dz-text) 10%, transparent); }
.dz-pane [data-cb="access"] .crmacc-add .ic { width: 16px; height: 16px; }

/* ── 7 · НАБЛЮДАТЕЛИ ─────────────────────────────────────────────────────────
   Строки, пустое и действия шапки — общий словарь (lab/common); здесь только аватар крупнее. */
.dz-pane [data-cb="watchers"] .crmb-watch-it .tw-av { width: 32px; height: 32px; margin: 0; border: 0; font-size: 13px; font-weight: 800; }
.dz-pane [data-cb="watchers"] .crmb-watch-nm { font-weight: 600; }

/* ── 8 · ОБЩЕЕ ДЛЯ БЛОКОВ ВКЛАДКИ ──────────────────────────────────────────── */
/* зона нажатия ≥44 px у контролов ниже 44 — полем промаха, без сдвига раскладки (канон
   tap-target). Поле промаха считается от padding-box: чип 34 с рамкой 1 → 32 + 2×6; «＋ Роль»
   основного 32 с рамкой 1 → 30 + 2×7; «+ Добавить поле» 40 без рамки → 40 + 2×2. */
.dz-pane [data-cb="client"] .crmw-space-chips .crm-chip,
.dz-pane [data-cb="client"] .crmw-roles .crmw-sub-a,
.dz-pane [data-cb="custom"] .ccx-type-chip { position: relative; }
.dz-pane [data-cb="client"] .crmw-space-chips .crm-chip::after,
.dz-pane [data-cb="custom"] .ccx-type-chip::after { content: ""; position: absolute; inset: -6px -2px; }
.dz-pane [data-cb="client"] .crmw-roles .crmw-sub-a::after { content: ""; position: absolute; inset: -7px -2px; }
.dz-pane [data-cb="custom"] .ccx-add-btn::after { content: ""; position: absolute; inset: -2px 0; }
/* текст пустых состояний — по ширине строки чтения, а не во всю карточку */
.dz-pane[data-dzpane="more"] :is(.di-empty, .crmb-empty) { max-width: 52ch; }

/* ── 10 · СВОДКА ВКЛАДКИ (`DZ_SUM.more`: взвешенная сумма · отсчёт до даты закрытия) ──
   Плитки «Обзора» (`.dz-metrics.dz-n2`), ниже ростом — под ними сразу форма. Слово вместо
   числа («не задан», «сегодня», «закрыта») — тише цифры; просрочка — цветом беды и словом. */
.dz-pane[data-dzpane="more"] .dz-more-sum .dz-metric { min-height: 0; gap: 8px; }
.dz-pane[data-dzpane="more"] .dz-more-sum .dz-more-word { font-size: 24px; font-weight: 800; letter-spacing: -.01em; }
.dz-pane[data-dzpane="more"] .dz-more-sum .dz-more-link { color: var(--dz-link); }
.dz-pane[data-dzpane="more"] .dz-more-sum .dz-more-bad .dz-metric-v { color: var(--dz-bad); }
.dz-pane[data-dzpane="more"] .dz-more-sum .dz-more-warn .dz-metric-v { color: var(--dz-warn); }

/* ── 9 · ТЕЛЕФОН ─────────────────────────────────────────────────────────────
   Полезная ширина ~300 px: поля карточки ближе к краю (20 → 16), плитки клиента ниже. */
@container dz (max-width: 640px) {
  .dz-pane[data-dzpane="more"] > .crmw-grid { gap: 14px; }
  .dz-pane[data-dzpane="more"] .di-sec-h { padding-left: 16px; padding-right: 16px; }
  .dz-pane[data-dzpane="more"] .di-sec-b { padding-left: 16px; padding-right: 16px; }
  .dz-pane [data-cb="client"] .crmw-owner { min-height: 60px; padding: 9px 12px 9px 9px; gap: 12px; }
  .dz-pane [data-cb="client"] .crmw-rel-main { min-height: 58px; padding: 9px 8px 9px 9px; gap: 12px; }
  .dz-pane [data-cb="client"] .crmw-rel-swap { padding: 0 12px; }
  .dz-pane [data-cb="client"] .crmw-owner-t > b { font-size: 15px; }
  /* подпись строки на телефоне переносится («Пространство · из проекта»), а не режется */
  .dz-pane [data-cb="client"] .crmw-owner-t > i { white-space: normal; }
  /* выбранный клиент на телефоне: «Сменить» — второй строкой плитки во всю ширину, иначе
     слово съедало половину строки и от имени клиента оставалось «ООО «Т…» */
  .dz-pane [data-cb="client"] .crmw-owner.crmw-rel { flex-wrap: wrap; }
  .dz-pane [data-cb="client"] .crmw-rel-main { flex: 1 0 100%; }
  .dz-pane [data-cb="client"] .crmw-rel-swap {
    flex: 1 0 100%; justify-content: center; min-height: 40px; padding: 0 12px;
    border-left: 0; border-top: 1px solid var(--dz-edge);
  }
  /* телефон клиента: номер строкой, «Позвонить» — во всю ширину под ним (как кнопки блоков) */
  .dz-pane [data-cb="client"] .cc-phone-row { row-gap: 8px; padding: 0; }
  .dz-pane [data-cb="client"] .cc-phone-row .ccp-num { flex: 1 0 100%; padding-left: 4px; }
  .dz-pane [data-cb="client"] .cc-phone-row .cc-phone-btn { flex: 1 1 auto; justify-content: center; }

  .dz-pane [data-cb="chatlink"] .di-chat-acts > * { flex: 1 1 auto; }
  /* действия кабинета — столбиком во всю ширину, а не рваной лесенкой разной длины */
  .dz-pane [data-cb="portal"] .dc-acts > .dc-a { flex: 1 1 auto; }
  /* сводка из двух плиток — одной колонкой: в 137 px «не задан» и подпись ломались по слову */
  .dz-pane[data-dzpane="more"] .dz-more-sum { grid-template-columns: minmax(0, 1fr); }
  /* плитка сводки — сверху вниз: подпись → значение → пояснение. Строкой «подпись и пояснение
     слева, цифра справа» (раскладка плиток «Обзора» на телефоне) крупное значение забирало
     ширину: пояснению оставалось 38–90 px, слова вставали по одному, «сделка закрыта»
     наезжало на «Реализована · 10 октября». */
  .dz-pane[data-dzpane="more"] .dz-more-sum .dz-metric { grid-template-columns: minmax(0, 1fr); grid-template-areas: "h" "v" "s"; row-gap: 6px; }
  .dz-pane[data-dzpane="more"] .dz-more-sum .dz-metric-v { justify-self: start; min-width: 0; flex-wrap: wrap; }
}
/* ── integ ── */
/* ── интеграция ── число и его единица/слово в плитке («30 %», «0 событий», «2 ч 15 мин»):
   зазор плитки 10 px — только между кольцом и числом; у подписи-единицы — свой отступ слова */
.dz .dz-metric-v { gap: 0; }
.dz .dz-metric-v > .dz-ring { margin-right: 10px; }
.dz .dz-metric-v small { margin-left: .22em; }
.dz .dz-metric-v small:not(:last-child) { margin-right: .3em; }
.dz-pane .dz-msum .dz-metric-v { gap: 0; }
.dz-pane .dz-msum .dz-metric-v > .dz-ring { margin-right: 8px; }

/* ── интеграция · ревью 12.10 ─────────────────────────────────────────────────────────── */
/* #0 #34 #65: переход к блоку (dzGo, dzReveal) — заголовок блока НЕ уходит под липкий ряд
   вкладок (высота ряда ≈ 62 px). Один отступ на все вкладки вместо правила одной вкладки. */
.dz-pane .crmw-blk, .dz-pane .crmw-blk[data-cb] { scroll-margin-top: 84px; }
.dz-pane :is(.dpay-row, .dinv-row, .dph-row) { scroll-margin-top: 96px; }
/* #39 #52: блок — по своей высоте, без пустого стекла до высоты соседа по ряду */
.dz-pane .crmw-grid { align-items: start; }
/* #62: в одну колонку «½ / во всю ширину» ничего не меняет — значка нет (две колонки сетки
   начинаются с 720 px колонки вида — @container базы `.crmw-grid`) */
@container dz (max-width: 719.98px) { .dz-pane .cblk-b[data-cbact="size"] { display: none; } }
/* #5: линия «сегодня» идёт по дорожке полос, а не через подписи дат над ними */
.dz-ph-lane { background-size: 2px calc(100% - 26px); background-position: var(--today) 26px; }
@container dz (max-width: 640px) { .dz-ph-lane { background-size: 2px calc(100% - 22px); background-position: var(--today) 22px; } }
/* #6: пунктир ожидающего этапа — графический знак, контраст ≥ 3:1 в обеих темах */
.dz-ph-bar.wait { border-color: color-mix(in srgb, var(--dz-text3) 75%, transparent); }
/* #14: имя ТЕКУЩЕЙ стадии видно целиком (до трёх строк) — на сенсоре подсказки нет */
.dz-step.cur .dz-step-n { -webkit-line-clamp: 3; }
/* #11: в «Последнем» на узкой колонке дата — всегда второй строкой (колонка дат не прыгает) */
@container dz (max-width: 640px) { .dz-recent .deal-act-b { flex-direction: column; align-items: flex-start; gap: 2px; } }
/* #7: цели нажатия на сенсоре ≥ 44 px — вкладки и исход сделки */
@media (hover: none) {
  .dz .dz-tabs > .cc-seg-btn { min-height: 44px; }
  .dz .dz-out { height: 44px; }
}
/* #13: фото ответственного в шапке — то же лицо, что в «Деталях» */
.dz-av.dz-av-img { background-size: cover; background-position: center; background-color: var(--dz-glass2); }
/* #17 #32 #44 #57 (правый край на телефоне) — в island.css: это поле шкуры, его токены живут там */

/* ── владелец 12.10: «Тут ховеры не нравятся» (лестница стадий) ─────────────────────────
   Было: общее `button:hover { background: var(--active) }` перебивало `all: unset` стадии —
   прямоугольник без радиуса во всю колонку, плюс плашка «… — перенести сюда».
   Стало: подложки нет; кружок отвечает кольцом акцента и показывает действие («перенести сюда»
   текущей» стрелкой действия), подпись светлеет. Плашки нет (title только у обрезанного имени). */
.dz .dz-step:hover, .dz .dz-step:active { background: transparent; }
.dz-step-dot { transition: border-color .15s ease, box-shadow .15s ease; }
.dz .dz-step:not(.cur):hover .dz-step-dot {
  border-color: var(--dz-link);
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--dz-pri) 16%, transparent);
}
/* внутри — СТРЕЛКА действия (вперёд к будущей, назад к пройденной), а не точка: точка внутри —
   знак ТЕКУЩЕЙ стадии, и наведённая стадия не должна выглядеть второй текущей */
.dz .dz-step:not(.cur):hover .dz-step-dot::after {
  content: ""; width: 15px; height: 15px; background: var(--dz-link);
  -webkit-mask: var(--dz-step-go) center / contain no-repeat; mask: var(--dz-step-go) center / contain no-repeat;
}
.dz .dz-step.next { --dz-step-go: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14M13 6l6 6-6 6'/%3E%3C/svg%3E"); }
.dz .dz-step.done { --dz-step-go: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 12H5M11 6l-6 6 6 6'/%3E%3C/svg%3E"); }
/* у пройденной на наведении галочка уступает место стрелке «вернуть сюда»; заливка — стекло */
.dz .dz-step.done:hover .dz-step-dot { background: var(--dz-bg); }
.dz .dz-step.done:hover .dz-step-dot svg.ic { display: none; }
.dz .dz-step:not(.cur):hover .dz-step-n { color: var(--dz-text); }
@media (prefers-reduced-motion: reduce) { .dz-step-dot { transition: none; } }

/* меню «⋯» шапки: стекло вида, Manrope, строки 44 px (цель нажатия) */
.tc-pop.dz-menu { padding: 6px; border-radius: 18px; border: 1px solid var(--dz-edge2); background: var(--dz-pop); color: var(--dz-text);
  box-shadow: var(--dz-shadow); font-family: "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
.tc-pop.dz-menu .tc-pop-row { min-height: 44px; padding: 0 12px; gap: 12px; border-radius: 12px; font-family: inherit; font-size: 15px; font-weight: 600; color: var(--dz-text); }
.tc-pop.dz-menu .tc-pop-row:hover, .tc-pop.dz-menu .tc-pop-row:focus-visible { background: color-mix(in srgb, var(--dz-text) 8%, transparent); outline: none; }
.tc-pop.dz-menu .tc-pop-row .ic { width: 18px; height: 18px; color: var(--dz-text2); }
.tc-pop.dz-menu .tc-pop-sep { margin: 6px 10px; background: var(--dz-edge); }

@keyframes dzFlash { 0% { box-shadow: 0 0 0 0 rgba(91,104,207,.0); } 25% { box-shadow: 0 0 0 4px rgba(91,104,207,.55); } 100% { box-shadow: 0 0 0 0 rgba(91,104,207,0); } }
.dz-flash { animation: dzFlash 1.4s ease-out 1; border-radius: 22px; }

/* колонка переписки в этом виде — та же, только сливается с небом по краю */
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .crmw-chat { border-left-color: rgba(255,255,255,.08); }
html[data-theme="light"] :is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .crmw-chat { border-left-color: rgba(18,26,35,.09); }
/* Рама страницы обрезает детей по своему радиусу (island.css → .deal-drawer.crm-page), поэтому
   наружное кольцо подсветки срезалось бы с трёх сторон — у колонки переписки кольцо ВНУТРЕННЕЕ. */
@keyframes dzFlashIn { 0% { box-shadow: inset 0 0 0 0 rgba(91,104,207,0); } 25% { box-shadow: inset 0 0 0 3px rgba(91,104,207,.6); } 100% { box-shadow: inset 0 0 0 0 rgba(91,104,207,0); } }
:is(#dealDrawer, #leadDrawer, #crmDrawer).dz-page .crmw-chat.dz-flash { animation: dzFlashIn 1.4s ease-out 1; border-radius: 0; }

/* узкая колонка (ноутбук с открытой перепиской, планшет, телефон) — ширина КОЛОНКИ, а не окна */
@container dz (max-width: 1060px) {
  .dz-hero { grid-template-columns: minmax(0, 1fr) 300px; gap: 22px; }
  .dz-title { font-size: 30px; }
  /* пять плиток: 3 + 2 без дыры (шестиколоночная сетка, верхние по 2, нижние по 3) */
  .dz-metrics.dz-n5 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .dz-metrics.dz-n5 > * { grid-column: span 2; }
  .dz-metrics.dz-n5 > :nth-child(n+4) { grid-column: span 3; }
}
@container dz (max-width: 940px) {
  /* герой в одну колонку: название не ломается в три строки, люди и кнопки — в один ряд;
     карточка денег — на всю ширину, сумма слева, разбивка справа */
  .dz-hero { grid-template-columns: minmax(0, 1fr); }
  /* подписи стадий — на ступень мельче: «Тестирование» и «Пусконаладка» целиком в ~110 px */
  .dz-step-n { font-size: 14px; }
  .dz .dz-track > .dz-step { padding: 0 2px; }
  /* 7+ стадий в узкой колонке — дорожка прокручивается (как на телефоне), стадии по 112 px */
  .dz-track.dz-many { display: flex; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; padding-bottom: 2px; }
  .dz-track.dz-many::-webkit-scrollbar { display: none; }
  .dz .dz-track.dz-many > .dz-step { flex: 0 0 112px; }
  /* четыре плитки «Обзора» — две в ряд: «135 000 ₽» не упирается в край плитки (:where — вес
     одного класса, чтобы ступени уже перебивали) */
  .dz-metrics:where(:not(.dz-n2, .dz-n3, .dz-n5)) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dz-alert { grid-template-columns: 46px minmax(0, 1fr); }
  .dz-alert-acts { grid-column: 2; justify-content: flex-start; }
}
@container dz (min-width: 641px) and (max-width: 940px) {
  .dz-money:has(.dz-mc-rows) { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 28px; row-gap: 10px;
    grid-template-areas: "h h" "v rows" "bar rows" "say say"; align-items: center; }
  .dz-money:has(.dz-mc-rows) > .dz-mc-h { grid-area: h; }
  .dz-money:has(.dz-mc-rows) > .dz-mc-v { grid-area: v; }
  .dz-money:has(.dz-mc-rows) > .dz-bar { grid-area: bar; }
  .dz-money:has(.dz-mc-rows) > .dz-mc-rows { grid-area: rows; }
  .dz-money:has(.dz-mc-rows) > .dz-mc-say { grid-area: say; }
}
@container dz (max-width: 860px) {
  .dz-two { grid-template-columns: minmax(0, 1fr); }
}
@container dz (max-width: 760px) {
  .dz-metrics, .dz-metrics.dz-n3, .dz-metrics.dz-n5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dz-metrics.dz-n5 > *, .dz-metrics.dz-n5 > :nth-child(n+4) { grid-column: auto; }
  /* нечётная последняя плитка — на всю строку, без дыры справа */
  .dz-metrics > :last-child:nth-child(odd) { grid-column: 1 / -1; }
  .dz-burn { grid-template-columns: 42px minmax(0, 1fr); }
  .dz-burn-g { grid-column: 2; width: auto; max-width: 340px; }
}
@container dz (max-width: 640px) {
  .dz { padding: 12px 14px 56px; gap: 14px; }
  .dz-hero { padding: 16px; gap: 18px; }
  .dz-title { font-size: 26px; }
  .dz-title.dz-title-long { font-size: 22px; }
  .dz-title.dz-title-long:not(:focus) { -webkit-line-clamp: 5; }
  /* люди и срок — столбиком равной ширины, а не лесенкой из пилюль разной длины */
  .dz-meta { flex-direction: column; gap: 8px; }
  .dz-mi { min-height: 48px; }
  .dz-mi .dz-av { width: 36px; height: 36px; }
  .dz-acts { flex-wrap: nowrap; gap: 8px; }
  .dz .dz-acts .dz-btn { height: 48px; }
  .dz .dz-acts .dz-btn.dz-primary { flex: 1 1 auto; min-width: 0; padding: 0 14px; }
  /* подпись не уже себя (СРЕД-33): сжатая кнопка режет подпись многоточием, а не за краем */
  .dz .dz-acts .dz-btn.dz-primary > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .dz .dz-acts .dz-btn:not(.dz-primary) span { display: none; }
  .dz .dz-acts .dz-btn:not(.dz-primary) { width: 48px; padding: 0; flex: none; }
  .dz-money { padding: 16px; gap: 10px; }
  .dz-mc-v { font-size: 32px; }
  /* «Осталось получить 400 000 ₽» — одной строкой в ~220 px карточки */
  .dz-mc-rows { font-size: 13.5px; }
  .dz-mc-rows > span { gap: 6px; }
  .dz-mc-rows b { padding-left: 8px; }
  /* лестница: заголовок · дорожка с прокруткой (ccSegFit: подтаявший край, текущая на виду) ·
     исход ПОД дорожкой, кнопки во всю ширину */
  .dz-stages { padding: 16px; gap: 14px; }
  .dz-stages-h { display: contents; }
  .dz-stages-h > .dz-cap { flex: none; }
  .dz-outs { order: 3; display: flex; width: 100%; gap: 8px; }
  .dz-outs > .dz-cap { display: none; }
  .dz .dz-outs .dz-out { flex: 1 1 auto; justify-content: center; }
  .dz-track { display: flex; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; padding-bottom: 2px; }
  .dz-track::-webkit-scrollbar { display: none; }
  .dz .dz-track > .dz-step { flex: 0 0 104px; }
  .dz-step-n { font-size: 13.5px; }
  .dz-warnchip { font-size: 12.5px; padding: 3px 8px; }
  .dz-alert { grid-template-columns: 40px minmax(0, 1fr); padding: 16px; gap: 12px; }
  .dz-alert-ic { width: 40px; height: 40px; }
  .dz-alert-t b { font-size: 18px; }
  .dz-alert-t small { font-size: 14px; }
  .dz-alert-acts { grid-column: 1 / -1; gap: 4px 12px; }
  .dz-alert-acts > .dz-btn { flex: 1 1 auto; height: 48px; }
  .dz-alert-acts > .dz-lnk { flex: 1 1 auto; text-align: center; }
  .dz-burn { padding: 16px; }
  .dz-burn-g { grid-column: 1 / -1; max-width: none; }
  .dz-burn-t b { font-size: 16px; }
  .dz .dz-tabs > * { padding: 10px 14px; font-size: 15px; }
  .dz-card { padding: 18px 16px; }
  .dz-card-h h3 { font-size: 20px; }
  .dz-card-h > small { order: 3; flex-basis: 100%; }
  /* этапы на телефоне — список (V5 mobile): название и статус, под ними своя мини-дорожка */
  .dz-tl-axis { display: none; }
  .dz-ph { grid-template-columns: minmax(0, 1fr); min-height: 0; }
  .dz-ph-t { padding: 12px 0 2px; }
  .dz-ph-lane { min-height: 40px; }
  .dz-ph-d { top: 2px; }
  .dz-ph-bar { top: 24px; height: 8px; }
  /* платёж: значок · название; сумма и статус — строкой под названием */
  .dz-pay { grid-template-columns: 40px minmax(0, 1fr); grid-template-areas: "ic t" "ic r"; align-items: start; row-gap: 8px; column-gap: 12px; }
  .dz-pay-ic { grid-area: ic; width: 40px; height: 40px; }
  .dz-pay-t { grid-area: t; }
  .dz-pay-r { grid-area: r; flex-direction: row; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 6px 10px; }
  .dz-crumbs .dz-crumb:not(:last-of-type), .dz-crumbs .dz-crumb-sep { display: none; }
  .dz-tabempty { padding: 28px 18px; }
  /* скелетон телефона — кнопки как у героя: главная тянется, остальные — значки 48 */
  .dz-skel .dz-acts .dz-skel-btn { width: 48px; height: 48px; }
  .dz-skel .dz-acts .dz-skel-btn.dz-skel-main-btn { flex: 1 1 auto; width: auto; }
}
@container dz (max-width: 520px) {
  /* плитки — строкой во всю ширину: подпись и пояснение слева, крупная цифра справа
     (в две колонки по ~137 px «135 000 ₽» не помещалась, «мин» упиралось в край) */
  .dz-metrics, .dz-metrics.dz-n2, .dz-metrics.dz-n3, .dz-metrics.dz-n5 { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .dz-metric { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "h v" "s v"; align-items: center;
    column-gap: 14px; row-gap: 3px; min-height: 0; padding: 14px 16px; }
  .dz-metric-h { grid-area: h; }
  .dz-metric-h svg.ic { display: none; }
  .dz-metric-v { grid-area: v; justify-self: end; font-size: 26px; gap: 8px; }
  .dz-metric-v small { font-size: 15px; }
  .dz-metric-s { grid-area: s; font-size: 13.5px; }
  .dz-ring { width: 26px; height: 26px; -webkit-mask: radial-gradient(circle 8.5px, transparent 98%, #000 100%); mask: radial-gradient(circle 8.5px, transparent 98%, #000 100%); }
}/* Касса: просрочка чужой валюты рядом с её горизонтом — тем же тоном, что плашка «Просрочено». */
.deal-cashflow .cf-oc-late { color: var(--danger); font-weight: 600; }

/* 🔴 13.10.2026 (ревью кадров, телефон, оба шаблона): открыт разговор — сквозной пузырь чатов (left 16 ·
   bottom 16) ложился РОВНО на скрепку композера. Поднимаем его над композером (с рядом инструментов
   ≈107 px), ленте — такой же запас снизу, чтобы последний пузырь не прятался под ним. Высота низа
   меняется (ряд инструментов, «ответ на…», лоток вложений) — где браузер умеет якоря (Chromium 125+,
   Safari 26), пузырь стоит над НИЖНЕЙ КРОМКОЙ ЛЕНТЫ; 120 — запас для остальных.
   idea-discuss-minichat-over-hero-1 · taskcard-chat-bubble-pos-1 · ticket-chat-fab-overlap-1 (22.10.2026):
   тред переезжает в карточку (ccThreadTake: задача, тикет, идея, сделка…), и `#chatScreen > .thread` там не
   находился. Якоря не было, anchor() без запасного значения делал bottom недействительным, и пузырь вставал
   на статичное место (y 56–108) поверх героя, вкладки «Карточка» и селекта статуса. Якорь и запас под
   пузырём теперь у самой ленты, где бы она ни жила; у anchor() есть запасные 108 (= bottom 120), если якорь
   недоступен. Списка экранов нет. */
@media (max-width: 720px) {
  #chatScreen.show-thread > #qcFab { bottom: 120px; }
  :root.cc-qc-thread main.thread > .messages { padding-bottom: 72px; }
  main.thread > .messages { anchor-name: --cc-feed; }
  @supports (anchor-name: --a) {
    #chatScreen.show-thread > #qcFab { position-anchor: --cc-feed; bottom: calc(anchor(bottom, 108px) + 12px); }
  }
}

/* 🔴 13.10.2026: окно настроек — «место» сквозного пузыря чатов, и пузырь (56 px, 20 от низа) садился на
   подпись версии внизу левой колонки (оба шаблона). Пока пузырь на экране, подвал колонки стоит над ним. */
@media (min-width: 721px) {
  :root.cc-qc-shown #settingsModal .set2-sidefoot { padding-bottom: 76px; }
}

/* 📅 ОКНО СРОКА ЗАДАЧИ — ОДНО на продукт (`ccDuePop`: форма «Новая задача», разбор встречи, отчёт
   записи). Готовые дни · месяц сеткой · время чипами · «Убрать» / «Готово». Выбранный день —
   белое по `--acc-fill` (заливка), сегодня — кольцо `--primary-2` (чернила): разные токены. */
.cc-due-pop { padding: 10px; }
.cc-due-pop input[type="time"] { color-scheme: dark; }
html[data-theme="light"] .cc-due-pop input[type="time"] { color-scheme: light; }
.ccd { display: flex; flex-direction: column; gap: 10px; }
.ccd-pre { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.ccd-p { display: flex; flex-direction: column; align-items: flex-start; gap: 1px; min-width: 0; padding: 6px 9px;
  border: 1px solid var(--line); border-radius: 9px; background: var(--panel); color: var(--text); font: inherit;
  font-size: 12.5px; font-weight: 600; cursor: pointer; text-align: left; transition: border-color .12s ease, background .12s ease; }
.ccd-p em { font-style: normal; font-weight: 500; font-size: 11px; color: var(--muted); font-variant-numeric: tabular-nums; }
.ccd-p:hover { border-color: color-mix(in srgb, var(--primary) 55%, var(--line)); background: var(--hover); }
.ccd-cal { border-top: 1px solid var(--line); padding-top: 8px; }
.ccd-mh { display: flex; align-items: center; justify-content: space-between; gap: 6px; margin-bottom: 4px; }
.ccd-mh b { font-size: 13px; font-weight: 650; color: var(--text); }
.ccd-nav { width: 28px; height: 28px; padding: 0; display: inline-grid; place-items: center; border: 0; border-radius: 8px;
  background: transparent; color: var(--muted); cursor: pointer; }
.ccd-nav:hover { background: var(--hover); color: var(--text); }
.ccd-nav .ic { width: 15px; height: 15px; }
/* 🔴 `minmax(0, 1fr)` и свой `padding: 0` у кнопки дня: общий `button { padding: 10px 14px }`
   раздувал день до 44px при столбце 40px, и воскресенье уезжало за край окна (замер 14.10). */
.ccd-wd, .ccd-days { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.ccd-wd span { text-align: center; font-size: 10.5px; font-weight: 600; color: var(--muted); padding: 3px 0; text-transform: uppercase; letter-spacing: .03em; }
.ccd-d { height: 32px; min-width: 0; padding: 0; border: 0; border-radius: 8px; background: transparent; color: var(--text); font: inherit;
  font-size: 13px; font-variant-numeric: tabular-nums; cursor: pointer; transition: background .1s ease; }
.ccd-d:hover { background: var(--hover); }
/* Выходные — обычными чернилами: серым на кадре 14.10 они читались как «нельзя выбрать», вровень
   с бледными днями соседнего месяца. Бледным остаётся только чужой месяц. */
.ccd-d.is-out { color: var(--muted); opacity: .45; }
.ccd-d.is-today { box-shadow: inset 0 0 0 1.5px var(--primary-2); color: var(--primary-2); font-weight: 650; }
.ccd-d.on, .ccd-d.on:hover { background: var(--acc-fill); color: #fff; box-shadow: none; font-weight: 650; opacity: 1; }
.ccd-d:focus-visible, .ccd-t:focus-visible, .ccd-p:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.ccd-time { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; border-top: 1px solid var(--line); padding-top: 9px; }
.ccd-lbl { width: 100%; font-size: 11.5px; font-weight: 600; color: var(--muted); }
.ccd-ts { display: contents; }
.ccd-t { height: 28px; padding: 0 9px; border: 1px solid var(--line); border-radius: 8px; background: var(--panel);
  color: var(--text); font: inherit; font-size: 12.5px; font-variant-numeric: tabular-nums; cursor: pointer; }
.ccd-t:hover { border-color: var(--line-strong); }
.ccd-t.on { background: var(--acc-fill); border-color: var(--acc-fill); color: #fff; font-weight: 600; }
.ccd-tin { height: 28px; width: 92px; padding: 0 8px; border: 1px solid var(--line); border-radius: 8px; background: var(--input-bg, var(--panel));
  color: var(--text); font: inherit; font-size: 12.5px; font-variant-numeric: tabular-nums; box-sizing: border-box; }
.ccd-tin:focus { outline: none; border-color: var(--primary); }
.ccd-foot { display: flex; align-items: center; gap: 8px; border-top: 1px solid var(--line); padding-top: 9px; }
.ccd-sum { flex: 1 1 auto; min-width: 0; font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ccd-clear { display: inline-flex; align-items: center; gap: 4px; color: var(--danger); }
.ccd-clear .ic { width: 13px; height: 13px; }
.ccd-foot .primary[disabled] { opacity: .45; cursor: default; }

/* ══ 🔎 ОКНО ВЫБОРА ЗАДАЧИ `ccTaskPick` (владелец 21.10.2026, сделка #1312: «Неудобно искать
   задачу, нужно больше окно сделать, и больше данных по задачам показать»). Одна рама на весь
   веб: этап сделки, карточка CRM, связи задачи, «Старт после», файл → в задачу, напоминание.
   Окно высокое и ФИКСИРОВАННОЙ высоты: поиск, фильтры и подвал не прыгают, пока список меняется.
   Цвета — только токены темы (обе темы); точка важности и люди — общие списки селекторов выше. */
.ctp-overlay .ctp-box { max-width: min(940px, 96vw); height: min(860px, 92vh); max-height: 92vh; }
.ctp-head { align-items: flex-start; gap: 12px; padding: 14px 16px 10px; border-bottom: none; }
.ctp-hd { min-width: 0; flex: 1; }
.ctp-hd h3 { margin: 0; font-size: 16px; line-height: 1.3; }
/* Подсказка — до двух строк: на телефоне «снимите галочку — открепятся» не должна обрезаться на полуслове. */
.ctp-sub { margin-top: 2px; font-size: 12.5px; font-weight: 500; color: var(--muted); overflow: hidden; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow-wrap: anywhere; }
.ctp-headx { padding: 0 16px 10px; }
.ctp-rel { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.ctp-rel-l { font-size: 12px; color: var(--muted); }
.ctp-tools { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 10px; padding: 0 16px 12px; border-bottom: 1px solid var(--line); }
.ctp-search { flex: 1 1 300px; min-width: 0; display: flex; align-items: center; gap: 8px; height: var(--ctl-h); box-sizing: border-box; padding: 0 6px 0 10px; border: 1px solid var(--line); border-radius: var(--ctl-r); background: var(--panel-2); }
.ctp-search:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent); }
.ctp-search > .ic { width: 15px; height: 15px; flex: none; color: var(--muted); }
.ctp-search input { flex: 1; min-width: 0; height: 100%; padding: 0; border: 0; outline: none; background: transparent; color: var(--text); font-size: var(--ctl-fs); }
.ctp-clr[hidden] { display: none; }
.ctp-clr { flex: none; display: inline-flex; padding: 4px; border: 0; border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer; }
.ctp-clr:hover { color: var(--text); background: var(--panel); }
.ctp-clr .ic { width: 14px; height: 14px; }
.ctp-segs { display: flex; flex-wrap: wrap; gap: 8px; }
/* `.cc-seg button` (ccroom.css, 0,1,1) перебивает размер канона `.cc-seg-md > *` (0,1,0): без этой
   строки дорожка вставала на 46px рядом с поиском 36 (замер 21.10, канон control-size). */
.ctp-segs .cc-seg-md > * { padding: 0 12px; font-size: var(--ctl-fs); line-height: calc(var(--ctl-h) - 8px); }
.ctp-rel .cc-seg-sm > * { padding: 0 9px; font-size: 12px; line-height: 18px; }
.ctp-n { margin-left: 4px; font-size: 11px; font-weight: 600; opacity: .7; font-variant-numeric: tabular-nums; }
.ctp-state { display: flex; align-items: center; gap: 8px; padding: 8px 16px; font-size: 12.5px; color: var(--muted); background: var(--panel-2); border-bottom: 1px solid var(--line); }
.ctp-state[hidden] { display: none; }
.ctp-state > .ic { width: 14px; height: 14px; flex: none; color: var(--warning); }
.ctp-lnk { padding: 0; border: 0; background: transparent; color: var(--primary-2); font: inherit; font-weight: 600; cursor: pointer; }
.ctp-lnk:hover { text-decoration: underline; }
.ctp-spin { flex: none; width: 12px; height: 12px; border-radius: 50%; border: 2px solid color-mix(in srgb, var(--muted) 35%, transparent); border-top-color: var(--primary); animation: ctpSpin .8s linear infinite; }
@keyframes ctpSpin { to { transform: rotate(360deg); } }
.ctp-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 8px 10px; }
.ctp-sec { position: sticky; top: 0; z-index: 1; display: flex; align-items: center; gap: 6px; margin: 0 -8px; padding: 12px 18px 6px; background: var(--panel); font-size: 11.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--muted); }
.ctp-sec.pin { color: var(--primary-2); }
.ctp-sec .ctp-n { text-transform: none; letter-spacing: 0; }
.ctp-row { position: relative; display: grid; grid-template-columns: 22px minmax(0, 1fr) auto 30px; align-items: start; gap: 4px 12px; padding: 10px; border: 1px solid transparent; border-radius: 10px; cursor: pointer; }
.ctp-row + .ctp-row { margin-top: 2px; }
.ctp-row:hover, .ctp-row.cur { background: var(--panel-2); }
.ctp-row.cur { border-color: color-mix(in srgb, var(--primary) 35%, transparent); }
.ctp-row.on { background: color-mix(in srgb, var(--primary) 9%, transparent); }
.ctp-row.on:hover, .ctp-row.on.cur { background: color-mix(in srgb, var(--primary) 14%, transparent); }
.ctp-row.busy { opacity: .6; pointer-events: none; }
.ctp-row .tp-noone { pointer-events: none; }
.ctp-list:not([aria-multiselectable]) .ctp-row { grid-template-columns: minmax(0, 1fr) auto 30px; }
.ctp-list:not([aria-multiselectable]) .ctp-mark { display: none; }
.ctp-mark { width: 20px; height: 20px; margin-top: 1px; box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; border: 1.5px solid color-mix(in srgb, var(--muted) 55%, transparent); border-radius: 6px; color: #fff; }
.ctp-row.on .ctp-mark { background: var(--acc-fill); border-color: var(--acc-fill); }
.ctp-mark .ic { width: 14px; height: 14px; }
.ctp-main { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.ctp-t { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.ctp-code { flex: none; font-size: 11.5px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.ctp-tt { min-width: 0; font-size: 14.5px; font-weight: 600; line-height: 1.32; color: var(--text); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
.ctp-row.done .ctp-tt, .ctp-row.cancelled .ctp-tt { color: var(--muted); text-decoration: line-through; text-decoration-color: color-mix(in srgb, var(--muted) 60%, transparent); }
.ctp-snip { font-size: 12.5px; line-height: 1.4; color: var(--muted); overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow-wrap: anywhere; }
.ctp-snip b { font-weight: 600; color: var(--text); }
.ctp-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 5px 6px; margin-top: 2px; min-width: 0; }
.ctp-where { display: inline-flex; align-items: center; gap: 4px; min-width: 0; max-width: 100%; font-size: 12px; color: var(--muted); }
.ctp-where > .ic { width: 13px; height: 13px; flex: none; }
.ctp-where > span { max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctp-where > span + .ic { margin-left: 6px; }
.ctp-note { display: inline-flex; align-items: center; gap: 4px; padding: 2px 7px; border-radius: 6px; font-size: 11.5px; font-weight: 600; background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary-2); }
.ctp-note .ic { width: 12px; height: 12px; }
.ctp-note.arch { background: color-mix(in srgb, var(--muted) 14%, transparent); color: var(--muted); }
.ctp-side { min-width: 0; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.ctp-row .ctp-side .tr-ppl { margin-top: 0; }
.ctp-upd { font-size: 11.5px; color: var(--muted); white-space: nowrap; }
.ctp-open { width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center; border: 0; border-radius: 8px; background: transparent; color: var(--muted); cursor: pointer; opacity: 0; transition: opacity .12s, background-color .12s; }
.ctp-row:hover .ctp-open, .ctp-row.cur .ctp-open, .ctp-open:focus-visible { opacity: 1; }
.ctp-open:hover { background: var(--panel); color: var(--text); }
.ctp-open .ic { width: 16px; height: 16px; }
@media (hover: none) { .ctp-open { opacity: 1; } }
.ctp-create { display: flex; align-items: center; gap: 10px; width: 100%; margin: 10px 0 2px; padding: 10px 12px; border: 1px dashed color-mix(in srgb, var(--primary) 45%, transparent); border-radius: 10px; background: color-mix(in srgb, var(--primary) 6%, transparent); color: var(--primary-2); font: inherit; font-size: 13.5px; font-weight: 600; text-align: left; cursor: pointer; }
.ctp-create:hover { background: color-mix(in srgb, var(--primary) 12%, transparent); }
.ctp-create.busy { opacity: .6; pointer-events: none; }
.ctp-create > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctp-create > .ic { width: 16px; height: 16px; flex: none; }
.ctp-create kbd { padding: 3px 6px; border: 1px solid var(--line); border-radius: 5px; background: var(--panel); color: var(--muted); font: 600 11px/1 inherit; }
.ctp-more { display: block; width: 100%; margin: 4px 0 6px; padding: 8px 12px; border: 0; border-radius: 8px; background: transparent; color: var(--primary-2); font: inherit; font-size: 13px; font-weight: 600; text-align: left; cursor: pointer; }
.ctp-more:hover { background: var(--panel-2); }
.ctp-empty { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 56px 20px; text-align: center; font-size: 13.5px; color: var(--muted); }
.ctp-empty > .ic { width: 28px; height: 28px; opacity: .6; }
.ctp-foot { display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-top: 1px solid var(--line); background: var(--panel); }
.ctp-foot-t { font-size: 13px; font-weight: 600; color: var(--text); }
.ctp-keys { margin-left: auto; font-size: 12px; color: var(--muted); }
.ctp-btn.pri { height: var(--ctl-h); padding: 0 18px; border: 0; border-radius: var(--ctl-r); background: var(--acc-fill); color: #fff; font-size: var(--ctl-fs); font-weight: 600; cursor: pointer; }
.ctp-btn.pri:hover { filter: brightness(1.08); }
/* Телефон: рама уже во весь экран (`.modal-box` ≤720px). Строка складывается в две —
   название с пометками сверху, люди и «когда менялась» под ним; ↗ всегда видна. */
@media (max-width: 720px) {
  .ctp-overlay .ctp-box { height: 100dvh; max-height: none; }
  .ctp-search { flex-basis: 100%; }
  /* Фильтр и порядок — каждый своей строкой во всю ширину, пункты делят её поровну: шесть
     пунктов в одну строку телефона 390 не влезают (замер 21.10: «Срок» срезался краем). */
  .ctp-segs { flex: 1 1 100%; }
  .ctp-segs .cc-seg-md { display: flex; flex: 1 1 100%; min-width: 0; }
  .ctp-segs .cc-seg-md > * { flex: 1 1 0; min-width: 0; padding: 0 6px; }
  .ctp-row { grid-template-columns: 22px minmax(0, 1fr) 30px; }
  .ctp-list:not([aria-multiselectable]) .ctp-row { grid-template-columns: minmax(0, 1fr) 30px; }
  .ctp-row .ctp-side { grid-column: 2; grid-row: 2; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: flex-start; }
  .ctp-list:not([aria-multiselectable]) .ctp-row .ctp-side { grid-column: 1; }
  .ctp-row .ctp-open { grid-column: -2; grid-row: 1; opacity: 1; }
  .ctp-keys { display: none; }
  .ctp-btn.pri { margin-left: auto; }
}
/* 🌊 «Глубина» лида — вариант А (21.10.2026): строки «горит» в карточке оценки, замок лестницы,
   карточки «Обзора» (Откуда пришёл · Контакт), чип статуса с многоточием, цитата тревоги в две
   строки, норма у плашки «без движения». Цвета — только токены «Глубины» (--dz-*), обе темы. */
.dz-mc-rows > span > i.bad { background: var(--dz-bad); }
.dz-mc-rows .dz-tag { vertical-align: middle; }
.dz .dz-step.dz-busy { opacity: .6; pointer-events: none; }
.dz .dz-src-line svg { width: 16px; height: 16px; flex: none; }
.dz-facts { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.dz-facts > span { display: flex; align-items: baseline; gap: 12px; min-width: 0; font-size: 15px; }
.dz-facts small { flex: none; width: 120px; color: var(--dz-text3); font-size: 13px; }
.dz-facts b { min-width: 0; font-weight: 600; color: var(--dz-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.dz[data-dzkind="lead"] .dz-chip { max-width: 100%; min-width: 0; }
.dz-chip-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dz-alert-t small.dz-alert-q { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.dz[data-dzkind="lead"] .dz-person > span:last-child { min-width: 0; }
.dz[data-dzkind="lead"] .dz-person b, .dz[data-dzkind="lead"] .dz-person small { overflow-wrap: anywhere; }
/* плашка «без движения» не переносится (nowrap) и стоит по центру своего столбика: с нормой она
   ≈280px. Норма видна, только когда столбик её вмещает (столбик ≈ (ширина − 104px) / число шагов),
   иначе плашка вылезала за край карточки и наезжала на подпись соседа; норма остаётся в подсказке. */
.dz-warn-norm { display: none; }
@container dz (min-width: 680px) { .dz-track.dz-n1 .dz-warn-norm, .dz-track.dz-n2 .dz-warn-norm { display: inline; } }
@container dz (min-width: 960px) { .dz-track.dz-n3 .dz-warn-norm { display: inline; } }
@container dz (min-width: 1240px) { .dz-track.dz-n4 .dz-warn-norm { display: inline; } }
@container dz (max-width: 640px) {
  .dz-facts small { width: 96px; }
}
/* точка статуса — круг 8×8 и тогда, когда длинная причина отказа сжимает чип до многоточия */
.dz[data-dzkind="lead"] .dz-chip.dz-st i { flex: none; }
/* 🔴🔴 CLIE-1946 · ЧЕРНИЛА СТАТУСА ВЫБИРАЕТ ТЕМА, А НЕ МОМЕНТ ОТРИСОВКИ.
   Пилюля статуса (statusPillTint) и подпись секции (taskGroupHeadHtml) везут ОБА цвета
   инлайн-переменными: --spt-d (тёмная — прежний алгоритм) и --spt-l (светлая — замер к
   LBL_LIGHT_SURFACE под тинтом), а `color: var(--spt-ink, var(--spt-d))`. Светлая тема
   подставляет свои чернила — смена темы без перезагрузки (setTheme ничего не перерисовывает)
   больше не оставляет 1.8:1 «В работе» в светлой и затемнённый тон в тёмной.
   Тёмной теме правило не достаётся: там --spt-ink не задан, работает фолбэк --spt-d. */
html[data-theme="light"] .tw-pill[style*="--spt-l"],
html[data-theme="light"] .task-section-title[style*="--spt-l"] { --spt-ink: var(--spt-l); }

/* 🔴 CLIE-1946: светлый «html[data-theme=light] .ghost» (вес 0,2,1) снимал рамку
   контурной кнопки приглашения «Поделиться» / «Обновить ссылку» (.v2inv-lbtn.ghost, 0,2,0) —
   кнопка терялась на панели. Возвращаем задуманную рамку, и на наведении тоже. */
html[data-theme="light"] .v2inv-lbtn.ghost,
html[data-theme="light"] .v2inv-lbtn.ghost:hover { border-color: var(--line-strong); }
