/* woff2 вместо ttf — тот же шрифт, ~35% исходного веса (в сумме 4 файла
   раньше весили ~1.7 МБ, теперь ~570 КБ), конвертация fontTools, символы не
   резались (риск случайно обрезать турецкие буквы или символ ₽ в ценах не
   стоил выигрыша ещё в пару раз). font-display: swap — текст сразу
   показывается системным шрифтом, Inter подменяет его без брака "невидимого
   текста" на медленной сети (частая жалоба на встроенный браузер WhatsApp). */
@font-face { font-family: "Inter"; src: url("/assets/fonts/Inter-Regular.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Inter"; src: url("/assets/fonts/Inter-Medium.woff2") format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Inter"; src: url("/assets/fonts/Inter-SemiBold.woff2") format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Inter"; src: url("/assets/fonts/Inter-Bold.woff2") format("woff2"); font-weight: 700; font-display: swap; }

:root {
  --green: #1aa260;
  --green-dark: #148a51;
  --green-bg: #eaf7f0;
  --green-border: #b7e3c8;
  --logo-green: #00623c;
  --ink: #141414;
  --gray: #86868b;
  --lgray: #b4b4ba;
  --border: #e8e8ed;
  --bg: #fafafa;
  --photobg: #f2f2f4;
  --white: #ffffff;
  --danger: #c0392b;
  --warning: #d99a1e;
  --warning-bg: #fdf3e3;
  --link-blue: #2f6fed;
  /* Убыточный товар (ABC по марже = 'D', см. src/abc_xyz.py) — отдельный,
     более тёмный оттенок красного: визуально отличим от --danger (мало
     вклада/затоварено), т.к. это качественно другая проблема — товар
     теряет деньги при продаже, не просто "низкий приоритет". */
  --loss: #7a1f1f;
  --loss-bg: #fbebeb;

  --r-card: 20px;
  --r-control: 12px;
  --r-btn-lg: 18px;
  --r-pill: 999px;
  --r-sm: 10px;

  --header-h: 168px;
  --z-header: 30;
  --z-overlay-backdrop: 40;
  --z-overlay-panel: 41;
}

* { box-sizing: border-box; }

/* [hidden] должен побеждать любой display:flex/grid, заданный тем же
   классом ниже (иначе, при равной специфичности, побеждает правило,
   объявленное позже в файле — то есть наше, а не браузерное). */
[hidden] { display: none !important; }

/* overflow-x:hidden + overscroll-behavior:none — по прямому репорту
   пользователя (2026-08-18): на iOS при потягивании экрана открывалась
   пустая область за краем страницы (стандартный "резиновый" бounce
   Safari). overflow-x:hidden на html/body не мешает внутренним элементам
   со своим overflow-x:auto (графики/таблицы) скроллиться горизонтально —
   он только не даёт САМОЙ СТРАНИЦЕ становиться шире экрана. background на
   html — на случай, если bounce всё равно секунду виден при вертикальной
   прокрутке, чтобы это был цвет фона приложения, а не белый/серый по
   умолчанию.

   scroll-behavior:smooth здесь СТОЯЛО, убрано по репорту пользователя
   (2026-08-19, "скролл не работает, любая попытка спуска возвращает
   наверх"): это CSS-свойство делает ГЛАДКИМ вообще ЛЮБОЙ скролл страницы,
   включая нативный (колесо мыши/трекпад/скроллбар), не только
   программные scrollIntoView/scrollTo из site.js — а тем уже явно
   передан behavior:"smooth" ПРЯМО В ВЫЗОВЕ (см. флудом по файлу), они в
   этом свойстве не нуждаются вовсе. Быстрые тики колеса мыши на такой
   длинной странице (5 блоков аналитики + полный каталог) запускают
   каскад перекрывающихся smooth-анимаций, и по задокументированному
   поведению части браузеров такая гонка анимаций может "сбрасывать"
   скролл, а не просто быть медленной — это ближе всего к описанному
   симптому, чем что-либо ещё, что мы уже пробовали (content-visibility,
   overflow-anchor). Нативный скролл теперь мгновенный (браузер по
   умолчанию) — визуально грубее, зато предсказуемый и не воюет сам с
   собой. */
html {
  /* Зум по двойному тапу — та же правка, что в site/static/style.css
     (см. site/templates/_viewport.html): клиент случайно приближает и не
     может вернуть. */
  touch-action: manipulation;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  overflow-x: hidden;
  overscroll-behavior: none;
  background: var(--bg);
}

/* overflow-x/overscroll-behavior были и здесь, и на html — по прямому
   репорту пользователя (2026-08-19: колесо мыши и Page Down не скроллят
   страницу вообще, работает только перетаскивание самого скроллбара, и в
   DevTools на дереве предков нет ни одного "wheel"-слушателя). Когда
   overflow задан ОДНОВРЕМЕННО и на html, и на body, браузер должен выбрать
   ОДИН из них "корневым скролл-элементом" (document.scrollingElement) — и
   при таком дублировании это может развалиться на ДВА независимых скролл-
   контекста: видимый скроллбар управляет одним (настоящим, viewport), а
   колесо мыши/клавиатура целятся в другой (body как отдельный бокс,
   который может быть уже "выбран до упора" или вообще не тем, что видно
   на экране) — это задокументированная, известная категория багов именно
   от дублирования overflow на html И body одновременно. Оставлено только
   на html — тут не нужно повторять.*/
body {
  margin: 0;
  font-family: "Inter", system-ui, sans-serif;
  color: var(--ink);
  background: var(--bg);
  padding-bottom: 40px;
  max-width: 100vw;
}

a { color: inherit; }

/* ---------- шапка ---------- */
/* Вся шапка целиком — один неподвижный sticky-блок, всегда полностью
   видимый, без сворачивания при скролле. Несколько попыток заставить
   верхнюю часть (лого/поиск) прятаться при скролле вниз и появляться при
   скролле вверх — сперва через JS-анимацию высоты, потом через
   независимый sticky у одной только .categories-wrap — каждый раз ломали
   что-то более важное на iPhone/Safari (то дёргалась, то переставала
   возвращаться, то меню вообще переставало быть закреплённым и переставала
   работать навигация по разделам). Рабочая надёжная навигация важнее
   лишних пикселей экрана при скролле — возвращена простая схема без
   всякого скролл-зависимого JS. */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--white);
  border-bottom: 1px solid var(--border);
}

.header-top {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 16px 20px 10px;
}
.logo { height: 52px; width: auto; flex-shrink: 0; }
.header-info { flex: 1; min-width: 0; }
.tagline { font-weight: 600; font-size: 14px; color: var(--logo-green); line-height: 1.3; }
.orders-link { font-size: 12.5px; font-weight: 600; color: var(--green); text-decoration: none; margin-top: 4px; display: inline-block; }
.orders-link:hover { text-decoration: underline; }

/* Шапка на десктопе — по прямому запросу пользователя (2026-08-19,
   "заголовок выглядит очень плохо"): раньше здесь не было НИКАКОГО
   отдельного десктопного вида — те же мобильные пропорции (лого+тэглайн
   одной колонкой, поисковая строка на всю ширину под ними, чипы разделов
   отдельной строкой) просто растягивались на весь широкий экран, отчего
   шапка читалась как плоская мобильная страница, а не как приложение.
   Тот же язык, что и у .analytics-section ниже (общий max-width, карточки
   с тенью) — лого и поиск в один ряд, сам поиск не на всю ширину, а
   разумного размера рядом с лого, чипы разделов в той же по ширине
   колонке, что и остальной контент страницы. */
@media (min-width: 900px) {
  /* Без max-width — по прямому запросу пользователя (2026-08-19):
     карточки товаров растянуты на весь экран без ограничения ширины
     (см. .catalog/.grid ниже), а шапка/аналитика были искусственно сжаты
     в узкую колонку по центру — несогласованно. Просто отступы по краям,
     ширина — вся доступная, как и у каталога. */
  .header-collapsible-inner {
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 20px 28px 14px;
  }
  .header-top { padding: 0; flex-shrink: 0; }
  .logo { height: 40px; }
  .tagline { font-size: 15px; }
  .orders-link { margin-top: 3px; }
  .searchbar { flex: 1; max-width: 420px; margin-left: auto; padding: 0; }
  .categories-wrap { padding: 0 28px 16px; }
  .category-chip { padding: 9px 18px; font-size: 14px; }
}
/* Мобильный — логотип меньше, а тэглайн ("Оптовый склад с доставкой до
   двери") в одну строку, не в две (по прямому запросу пользователя). Первая
   попытка (40px/13px) на узких экранах текст всё ещё не помещался и
   обрезался многоточием (фидбэк пользователя, скриншот) — логотип и отступы
   уменьшены сильнее, шрифт мельче. overflow/ellipsis остаётся подстраховкой
   на случай совсем узких экранов, не основным приёмом. */
@media (max-width: 899px) {
  .header-top { gap: 10px; padding: 14px 16px 8px; }
  .logo { height: 36px; }
  .tagline { font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
}

/* Кабинет аналитики закупок не инструмент заказа — из .fab-stack убрана
   корзина (по прямому запросу пользователя 2026-08-17), остался только
   "наверх раздела". */
.fab-stack {
  position: fixed;
  right: 16px;
  bottom: 16px;
  z-index: var(--z-header);
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-end;
  gap: 10px;
}
@media (min-width: 900px) {
  .fab-stack { position: static; display: contents; }
  .scroll-top-toggle { position: fixed; bottom: 16px; right: 24px; z-index: var(--z-header); }
}
.scroll-top-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: 50%;
  background: var(--white);
  color: var(--ink);
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(20,20,20,0.2);
  transition: background 0.15s ease;
}
.scroll-top-toggle:hover { background: var(--photobg); }

.searchbar { padding: 4px 20px 12px; }
.search-wrap { position: relative; }
#search {
  width: 100%;
  padding: 12px 40px 12px 16px;
  border: 1px solid var(--border);
  background: var(--photobg);
  /* var(--r-btn-lg), не --r-control — по фидбэку пользователя выглядело
     мельче остальных скруглений на сайте (та же правка уже делалась для
     поля PIN на странице входа в кабинет). */
  border-radius: var(--r-btn-lg);
  font-size: 16px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}
#search:focus { border-color: var(--green); background: var(--white); }
/* Свой крестик очистки (#search-clear, см. site.js) вместо нативного
   ::-webkit-search-cancel-button — по прямому репорту пользователя
   (2026-08-27, мобильный скриншот): нативная кнопка у type="search"
   ненадёжно/еле заметно появляется на телефоне, один явный тап должен
   гарантированно чистить поле на любом мобильном браузере. Прячем
   нативную, чтобы не было двух крестиков разом. */
#search::-webkit-search-cancel-button { display: none; -webkit-appearance: none; }
.search-clear-btn {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  border: none; background: none; color: var(--gray); font-size: 22px; line-height: 1;
  cursor: pointer; padding: 8px; display: flex; align-items: center; justify-content: center;
}
.search-clear-btn:hover { color: var(--ink); }

/* ---------- карусель категорий ---------- */
.categories-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px 12px 20px;
}
.categories {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scroll-behavior: smooth;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.categories::-webkit-scrollbar { display: none; }
.category-chip {
  border: 1px solid var(--border);
  background: var(--white);
  color: var(--ink);
  border-radius: var(--r-pill);
  padding: 8px 16px;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
  flex-shrink: 0;
  white-space: nowrap;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.category-chip.active {
  background: var(--green);
  border-color: var(--green);
  color: var(--white);
}
.category-chip.promo-chip:not(.active) { border-color: var(--green-border); color: var(--green-dark); }
.category-chip.reset { background: var(--danger); border-color: var(--danger); color: var(--white); }
.category-chip.reset:hover { background: #a5311f; border-color: #a5311f; }
/* Невыбранные чипы бренда/подраздела, пока в разделе стоит фильтр — по
   прямому запросу пользователя: видно, что раздел сейчас сужен и эти чипы
   сейчас скрывают часть товаров, но сами чипы остаются кликабельными
   (просто приглушены, не задизейблены). */
.category-chip.muted { opacity: 0.4; }

.categories-expand-btn {
  flex-shrink: 0;
  width: 38px;
  height: 38px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--white);
  color: var(--ink);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.categories-expand-btn:hover { background: var(--photobg); }

/* ---------- каталог: секции ---------- */
/* overflow-anchor:none — по репорту пользователя (2026-08-18, "скролл не
   работает, любая попытка спуска возвращает наверх"): каталог теперь
   строится порциями по кадру (см. site.js: processRenderQueue), новые
   разделы дописываются в конец, пока пользователь может уже листать —
   браузерная "scroll anchoring" (эвристика "не дай контенту вверху экрана
   сдвинуть текущий взгляд") в некоторых движках плохо ладит с контейнером,
   который часто меняет высоту, и может компенсировать резче, чем нужно.
   Отключаем эвристику для контейнера каталога — сами разделы не прыгают
   (id/высота готовых секций не меняются задним числом), терять там нечего. */
/* scroll-margin-top — по прямому запросу пользователя (2026-08-19):
   "когда что-то в поиске начинают вводить, страница сразу попадала в
   раздел с этими товарами" (см. site.js: searchInput input-обработчик,
   scrollIntoView на #catalog) — без этого прыжок к результатам заводил
   верх #catalog ПОД липкую шапку (тот же приём, что и у .category-section
   выше, var(--header-h) — реальная высота шапки). */
/* margin-top — по прямому запросу пользователя (2026-08-19): "раздел
   Неликвиды с остальными разделами тоже разедини визуально тем же
   отступом" — тот же 80px, что и у #zakup-section/#nelikvidy-section (см.
   .warehouse-section > h2:first-child выше), только здесь применён к
   ВСЕМУ #catalog (а не к одному id), потому что первый раздел внутри
   каталога (ABC/XYZ, Дерево или 1С — зависит от режима сортировки)
   рендерится динамически через JS, у него нет своего фиксированного id
   для точечного таргетинга. Итоговый зазор — те же 28 (margin-bottom
   .nelikvidy-section) + 80 (это) + 22 (padding-top первого
   .category-section внутри) = 130px, что и между остальными разделами. */
.catalog { padding: 4px 14px 20px; margin-top: 80px; overflow-anchor: none; scroll-margin-top: var(--header-h); }


/* Самокритика от 2026-08-25 (по прямому репорту пользователя — заголовок
   "Цель — 10 млн" стоял впритык к шапке): padding-top здесь МОЛЧА
   проигрывал .analytics-section { padding: 0 16px; ... } ниже по файлу —
   тот же класс-специфичность (0,0,1,0), а .analytics-section объявлен
   позже, поэтому его padding-top:0 побеждал у ЛЮБОЙ секции с обоими
   классами разом (то есть у всех .analytics-section .category-section на
   странице) — просто это было незаметно у всех секций, кроме самой первой
   на странице, потому что у остальных 28px margin-bottom ПРЕДЫДУЩЕЙ
   секции визуально давал зазор вместо этого padding. section. — не
   косметика, реальный битый специфичность-tie-break, побеждает
   .analytics-section независимо от порядка объявления в файле. */
section.category-section { scroll-margin-top: var(--header-h); padding-top: 22px; }
.category-title {
  font-size: 18px;
  font-weight: 700;
  margin: 0;
  color: var(--ink);
}

.category-title-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 12px;
}

.promo-name-group {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* Кнопка "Анализ" (см. site.js: createAnalysisButton) — заменяет прежнюю
   🔗-ссылку на раздел, по прямому запросу пользователя (2026-08-24): та
   тут не нужна была вовсе. Текстовая пилюля, не иконка — сама функция
   (построить рекомендации по закупке) не считывается одним символом так
   же однозначно, как "скопировать ссылку". */
.category-analysis-btn {
  background: none;
  border: 1px solid var(--border);
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  padding: 5px 10px;
  border-radius: var(--r-pill);
  color: var(--green-dark);
  flex-shrink: 0;
}
.category-analysis-btn:hover { background: var(--green-bg); }
.category-analysis-btn.active { background: var(--green); border-color: var(--green); color: var(--white); }
.promo-banner .category-analysis-btn { border-color: var(--green-dark); }

/* Панель результатов "Анализ" — вставляется сразу под заголовком/шапкой
   раздела (см. site.js: toggleAnalysisPanel). Зелёная полоса слева убрана
   по прямому запросу пользователя (2026-08-26, "не нравится это зелёное
   выделение слева… на всём сайте это выделение уберём") — обычная рамка
   карточки, как у .warehouse-panel/.abc-card, без акцентной полосы. */
.analysis-panel {
  margin: 10px 0 18px;
  padding: 14px 16px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  box-shadow: 0 1px 2px rgba(20, 20, 20, 0.05);
}
.analysis-panel-title { font-weight: 700; font-size: 14px; margin-bottom: 10px; }
.analysis-mode-toggle { max-width: 280px; }
/* Переключатель "По дате"/"По количеству" у "кто купил в этом месяце"
   (2026-08-27) — тот же .seg-toggle-row, что и везде, просто с отступом
   снизу перед таблицей. */
.demand-drilldown-sort { margin-bottom: 10px; }
/* Шире на телефоне — по прямому запросу пользователя (2026-08-27):
   .analysis-panel (padding 16px) внутри .product-modal-body (padding
   20px) в сумме отъедали 36px с каждой стороны у и без того тесной
   4-колоночной таблицы (Клиент/Дата/Кол-во/Цена). Отрицательный
   margin возвращает часть этой ширины именно этой панели (не всем
   .analysis-panel — там, где такая ширина нужна) — "совсем капелька",
   не полный edge-to-edge, чтобы не выглядеть как отдельный слой поверх
   остального модального окна. Освободившееся место уходит на padding
   ячеек таблицы (col ниже), а не просто в пустоту. */
@media (max-width: 639px) {
  .demand-drilldown-panel { margin-left: -10px; margin-right: -10px; padding-left: 10px; padding-right: 10px; }
  .demand-drilldown-panel .purchase-table th,
  .demand-drilldown-panel .purchase-table td { padding-right: 12px; }
}
.analysis-bucket { margin-bottom: 16px; }
.analysis-bucket:last-child { margin-bottom: 0; }
.analysis-bucket h4 { font-size: 13px; font-weight: 600; margin: 0 0 6px; color: var(--gray); }
/* Сноска-объяснение под заголовком корзины ("товара нет — теряем выручку" и
   т.п.) — generic .hint нигде до этого не был стилизован (см. .analytics-
   section p.hint выше, оно уже точнее для своего места), только здесь
   получает собственный отступ. */
.analysis-bucket-hint { margin: 0 0 8px; }
.hint { font-size: 12px; color: var(--gray); }

.category-section.promo .promo-banner {
  background: var(--green-bg);
  border: 1px solid var(--green-border);
  border-radius: var(--r-control);
  padding: 12px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
  font-weight: 700;
  font-size: 15px;
  color: var(--green-dark);
}
.category-section.promo .promo-banner .promo-tag {
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  background: var(--green);
  color: var(--white);
  padding: 4px 10px;
  border-radius: var(--r-pill);
}

/* Вложенный список брендов внутри раздела дерева (см. site.js:
   buildParentSection) — свёрнут по умолчанию, разворачивается по клику на
   "Бренды". Сами кнопки — те же .category-chip/.category-chip.active, что
   и в верхней карусели разделов (по фидбэку пользователя: раньше были
   зеленоватыми даже невыбранные, должно быть бело/зелено один-в-один с
   основной линией разделов). */
.brand-label {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12.5px; font-weight: 600; color: var(--green-dark);
  margin: 0 0 10px; user-select: none;
}
.brand-row { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 16px; }
.brand-row .category-chip .n { opacity: .65; font-size: 11.5px; }
.brand-row .category-chip.active .n { opacity: .85; }

/* Заголовок подраздела внутри раздела дерева — мельче .category-title,
   несколько подряд в одной секции (см. buildParentSection). Строка (текст +
   кнопка "скопировать ссылку", см. createCategoryLinkButton), не просто
   текст — та же ссылка на подраздел, что уже есть у основного раздела. */
.child-title {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 13px; font-weight: 700; color: var(--gray);
  margin: 18px 0 10px;
  /* Прямой переход из "Все разделы" в конкретный подраздел (см. site.js:
     rebuildCategoriesOverlay) скроллит сюда напрямую — без этого заголовок
     подраздела оказывался под "прилипшей" шапкой. */
  scroll-margin-top: var(--header-h);
}
.child-title span { text-transform: uppercase; letter-spacing: 0.02em; }
.child-title:first-of-type { margin-top: 0; }

.grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}
@media (min-width: 480px) {
  .grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 620px) {
  .grid { grid-template-columns: repeat(4, 1fr); gap: 16px; }
}
@media (min-width: 900px) {
  .grid { grid-template-columns: repeat(5, 1fr); gap: 20px; }
}

.card {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 1px 2px rgba(20,20,20,0.03);
}
/* content-visibility: auto здесь стояло раньше (2026-08-18, попытка не
   лейаутить/красить карточки за экраном) — откачено в тот же день по
   репорту пользователя: "скролл не работает, любая попытка спуска
   возвращает наверх". Первая версия отката не помогла — репорт повторился
   и на следующий день (2026-08-19); настоящей причиной, судя по всему,
   было global scroll-behavior:smooth на html (убрано отдельно, см. начало
   файла) — оно делает гладким ЛЮБОЙ скролл, включая нативное колесо мыши,
   и на длинной странице быстрые тики колеса запускают гонку
   перекрывающихся smooth-анимаций, которая в части браузеров может
   сбрасывать скролл, а не просто быть медленной. content-visibility могло
   усугублять ту же гонку (плывущая интринсик-высота карточек во время
   активной анимации), поэтому обе правки оставлены рядом — но именно
   scroll-behavior видится основной причиной. Нагрузка на рендер и так
   снята на уровне JS (см. site.js: processRenderQueue/flushPendingRender —
   каталог строится порциями по кадру, а не одним блокирующим проходом). */
/* Карточка не в наличии — визуально задизейблена целиком, но остаётся
   кликабельной (раскрывает карточку товара, см. renderCard). Приглушаем
   фото (img/.no-photo) и весь .card-body (название/цену/задизейбленную
   кнопку "В корзину") по отдельности, не общим родителем. */
.card.out-of-stock .card-photo img,
.card.out-of-stock .card-photo .no-photo,
.card.out-of-stock .card-body { opacity: 0.55; }
.card.promo-card { background: var(--green-bg); border-color: var(--green-border); }
.card { cursor: pointer; }

.card-photo {
  background: var(--photobg);
  aspect-ratio: 5 / 4;
  overflow: hidden;
  position: relative;
}
.card.promo-card .card-photo { background: #ddf0e4; }
.card-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card-photo img.photo-contain { object-fit: contain; padding: 8px; }
/* Стек бейджей в правом верхнем углу фото — "Акция"/"Срок до .../"Истёк
   срок" (для товара из папки истекающих/истёкших сроков 1С, см.
   product_taxonomy.expiry_badge) — общий flex-контейнер вместо каждого
   бейджа со своим absolute-позиционированием. */
.card-badges {
  position: absolute; top: 8px; right: 8px; z-index: 1;
  display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
}
/* Размер — как у остальных бейджей кабинета (.card-badge-stock/-cost ниже),
   не как на клиентском сайте (site/static/style.css держит их крупнее
   специально для клиента) — по прямому запросу пользователя (2026-08-22):
   "только в сервисе аналитики [сделай] меньше, таких же размеров как и
   остальные бейджи". */
.card-badge {
  background: var(--green); color: var(--white);
  border: none; border-radius: var(--r-pill);
  font-size: 10px; font-weight: 600;
  padding: 3px 7px;
  box-shadow: 0 1px 4px rgba(20,20,20,0.2);
}
.card-badge.expired { background: var(--danger); }
/* Общий остаток на складах + стоимость остатка в себестоимости — верхний
   левый угол фото (в отличие от .card-badges справа), по прямому запросу
   пользователя: видно сразу в сетке, симметрично основным бейджам.
   Уменьшено до размера остальных плашек (маржа/ABC-XYZ) — по прямому
   запросу пользователя (2026-08-18), раньше .card-badge-stock была
   заметно крупнее их. */
.card-badges-left { position: absolute; top: 8px; left: 8px; z-index: 1; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.card-badge-stock, .card-badge-cost {
  background: rgba(20,20,20,0.72); color: var(--white);
  border-radius: var(--r-pill);
  font-size: 10px; font-weight: 600;
  padding: 3px 7px;
  box-shadow: 0 1px 4px rgba(20,20,20,0.2);
}
.no-photo {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: var(--lgray); font-size: 11px; line-height: 1.35;
  text-align: center; padding: 10px;
}
.product-modal-photo .no-photo { font-size: 13px; padding: 24px; }

.card-body { padding: 10px 10px 12px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.card-name { font-size: 13px; font-weight: 500; line-height: 1.35; min-height: 35px; }
.card-article { font-size: 11px; color: var(--gray); }
/* Сноска "почему может подойти" (рельса допродажи в личном кабинете, см.
   site/cabinet.py: cross_sell_items, поле "причина") — коротко и не должно
   раздувать карточку сильнее обычной: до 3 строк, дальше — многоточие. */
.card-reason {
  font-size: 11.5px; line-height: 1.4; color: var(--gray);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
/* В модалке места достаточно — сноска показывается целиком, без обрезки
   (в отличие от .card-reason на карточке в сетке). */
.pm-reason { font-size: 13px; line-height: 1.5; color: var(--gray); margin: 2px 0; }
.stock-badge { font-size: 11px; color: var(--danger); font-weight: 600; }
.card-price { font-size: 16px; font-weight: 700; color: var(--green); margin-top: auto; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.price-old { font-size: 13px; font-weight: 400; color: var(--gray); text-decoration: line-through; }
.price-current { font-size: inherit; font-weight: inherit; color: inherit; }
/* Себестоимость + средний % маржи — отдельная строка ПОД отпускными ценами
   (flex-basis: 100% всегда переносит её на новую строку, даже если сами
   цены короткие и формально есть место рядом), с/с слева, % маржи справа
   на том же уровне, по прямому запросу пользователя (см.
   fillManagementPriceRow). */
.price-cost-row { flex-basis: 100%; display: flex; align-items: center; justify-content: space-between; }
.price-cost { font-size: inherit; font-weight: inherit; color: var(--danger); }
/* Плашка среднего % маржи — тот же шрифт, что у с/с слева (inherit от
   .card-price), заливка цветом по порогу (см. fillManagementPriceRow):
   >=20% зелёная, 15-19% жёлтая, <=14% красная. */
/* inline-block + text-align:center, НЕ inline-flex — по прямому репорту
   пользователя (2026-08-18, дважды): текст съезжал то по вертикали, то по
   горизонтали. flexbox плохо центрирует одинокий анонимный текстовый узел
   в некоторых версиях iOS Safari (именно та платформа, на которой смотрят
   Заур/Ильяс) — text-align на обычном inline-block не имеет этой проблемы. */
.price-margin {
  font-size: 12px; font-weight: 700; color: var(--white);
  border-radius: var(--r-pill); padding: 4px 9px 3px;
  display: inline-block; text-align: center;
  min-width: 34px; line-height: 1;
}
.price-margin.margin-good { background: var(--green); }
.price-margin.margin-mid { background: var(--warning); }
.price-margin.margin-bad { background: var(--danger); }

/* Двойная плашка ABC(по марже)/XYZ в правом верхнем углу фото (тот же
   угол, что и "Акция"/"Срок до", см. card-badges) — по прямому запросу
   пользователя (2026-08-18): видно классификацию товара сразу в сетке, без
   раскрытия карточки. Каждая плашка закрашена цветом своей буквы (A/X —
   зелёный, B/Y — жёлтый, C/Z — красный, те же уровни, что и у %маржи выше),
   остальные буквы алфавита показаны тут же, приглушённо, для контекста. */
.card-badge-classify { display: flex; gap: 3px; }
.classify-pill {
  display: flex; gap: 3px; align-items: center;
  border-radius: var(--r-pill); padding: 3px 6px;
  box-shadow: 0 1px 4px rgba(20,20,20,0.2);
}
.classify-pill.margin-good { background: var(--green); }
.classify-pill.margin-mid { background: var(--warning); }
.classify-pill.margin-bad { background: var(--danger); }
.classify-pill.margin-loss { background: var(--loss); }
.classify-letter { font-size: 10px; font-weight: 600; color: rgba(255,255,255,0.55); line-height: 1; }
.classify-letter.active { color: var(--white); font-weight: 800; }
/* Крупное число + подпись — по прямому запросу пользователя (2026-08-19,
   "сделай информацию о количестве на складах более заметной, но с
   соблюдением правил UX/UI"): раньше вся строка ("На складах: X шт ·
   Центральный Y, Хасавюрт Z · В себестоимости: N ₽") шла одним мелким
   серым текстом (12.5px) — терялась рядом с ценой (16px, жирная, зелёная).
   Само число теперь того же масштаба, что и .stock-big в "Аналитике
   склада" (тот же визуальный язык на карточке), детали — мельче, чтобы не
   спорить с ним за внимание. Нейтральный цвет (--ink, не зелёный/красный)
   — это не "хорошо" и не "плохо", просто важная цифра. */
.pm-stock-total { margin: 2px 0 10px; }

/* На карточке в сетке кнопка "В корзину" и степпер количества никогда не
   показываются одновременно: до добавления — только кнопка на всю ширину,
   после клика она заменяется степпером (тоже на всю ширину, по центру) —
   поэтому теснота больше не проблема и степпер может быть крупным. */
.card-controls { display: flex; align-items: center; justify-content: center; gap: 4px; margin-top: 4px; }

/* ---------- лестница цен по объёму (опт от коробки, только у товаров с
   item.лестница_цен — см. src/tier_pricing.py) ----------
   По фидбэку пользователя первая версия (рамка на каждой строке) выглядела
   тяжело и спорила сама с собой за внимание — теперь рамка/цвет только у
   ОДНОЙ активной строки, остальные различаются едва заметным разделителем
   внутри общей карточки, как в обычных списках выбора (тарифы, доставка),
   а не набором одинаковых кнопок. */
.pm-tiers-label {
  font-size: 12px; font-weight: 600; color: var(--gray);
  margin: 2px 0 8px; text-transform: uppercase; letter-spacing: 0.03em;
}
.pm-tiers-wrap { margin: 4px 0 10px; }
.pm-tiers {
  display: flex; flex-direction: column;
  /* --r-card (20px), не --r-control (12px) — та же логика, что и у самих
     карточек товара: широкому контейнеру нужен радиус покрупнее, иначе на
     ширине во всю модалку 12px читается почти незаметной вмятиной, а не
     тем же скруглением, что у компактных кнопок под ним (фидбэк
     пользователя, скриншот — рамка лестницы выглядела "более квадратной",
     хотя абсолютное значение совпадало с кнопками степпера). */
  border-radius: var(--r-card); overflow: hidden;
  background: var(--photobg);
}
.pm-tier-row {
  display: flex; align-items: center; gap: 12px;
  width: 100%; text-align: left; cursor: pointer;
  border: none; border-bottom: 1px solid rgba(20, 20, 20, 0.07);
  background: transparent; padding: 12px 14px;
  font-family: inherit; transition: background 0.15s ease;
}
.pm-tier-row:last-child { border-bottom: none; }
.pm-tier-row:hover { background: rgba(26, 162, 96, 0.07); }
.pm-tier-row.active { background: var(--white); box-shadow: inset 0 0 0 1.5px var(--green); }
/* Инсет-тень активной строки рисуется по СОБСТВЕННЫМ скруглениям строки —
   у обычной строки их нет (0), поэтому первая/последняя строка (там, где
   видна и рамка контейнера .pm-tiers) должны сами повторить его радиус,
   иначе подсветка активной строки там выглядит квадратной на фоне
   скруглённой карточки вокруг (фидбэк пользователя, скриншот). */
.pm-tier-row:first-child { border-top-left-radius: var(--r-card); border-top-right-radius: var(--r-card); }
.pm-tier-row:last-child { border-bottom-left-radius: var(--r-card); border-bottom-right-radius: var(--r-card); }

.pm-tier-radio {
  position: relative;
  width: 18px; height: 18px; border-radius: 50%; flex-shrink: 0; box-sizing: border-box;
  border: 2px solid var(--lgray);
  transition: border-color 0.15s ease;
}
.pm-tier-row.active .pm-tier-radio { border-color: var(--green); }
/* Точка — абсолютным позиционированием от центра родителя (top/left 50% +
   translate(-50%,-50%)), а не flex-центрированием — так её позиция не
   зависит от округления при делении контейнера на нечётные значения,
   гарантированно ровно посередине независимо от размера точки. */
.pm-tier-radio-dot {
  position: absolute; top: 50%; left: 50%;
  width: 9px; height: 9px; border-radius: 50%; background: var(--green);
  transform: translate(-50%, -50%) scale(0);
  transition: transform 0.15s ease;
}
.pm-tier-row.active .pm-tier-radio-dot { transform: translate(-50%, -50%) scale(1); }

.pm-tier-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pm-tier-label { font-size: 13.5px; color: var(--ink); line-height: 1.3; }
.pm-tier-row.active .pm-tier-label { font-weight: 600; }

.pm-tier-price { font-size: 15px; font-weight: 700; color: var(--ink); white-space: nowrap; flex-shrink: 0; }
.pm-tier-row.active .pm-tier-price { color: var(--green-dark); }

/* ---------- степпер количества (- / число / +) ---------- */
.qty-stepper {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}
.qty-btn {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-control);
  background: var(--white);
  color: var(--ink);
  font-size: 18px;
  line-height: 1;
  font-weight: 600;
  cursor: pointer;
  padding: 0;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.qty-btn:hover { background: var(--green); border-color: var(--green); color: var(--white); }
.qty-btn:disabled { color: var(--lgray); cursor: not-allowed; background: var(--white); border-color: var(--border); }
.qty-input {
  /* Оптовые количества — хватает места на 4 цифры (до "9999"), не обрезается. */
  width: 46px;
  border: none;
  background: none;
  text-align: center;
  font-family: inherit;
  font-size: 16px;
  font-weight: 600;
  padding: 0;
  -moz-appearance: textfield;
}
.qty-input::-webkit-outer-spin-button,
.qty-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.add-btn {
  flex: 1;
  border: none;
  background: var(--photobg);
  color: var(--ink);
  /* Крупнее, чем общий --r-control (12px) — по фидбэку пользователя кнопки
     "В корзину"/"Показать альтернативы" должны скругляться заметнее, ближе
     к тому, как выглядят кнопки в iOS. Меняем радиус только у этого класса,
     не сам --r-control — та же переменная используется у степпера
     количества, поиска, промо-баннера, и трогать их не просили. Настоящий
     "сквирк" (непрерывная iOS-кривая, не дуга окружности) в CSS
     border-radius нельзя — свойство corner-shape для него пока не
     поддерживается браузерами достаточно широко; увеличенный радиус —
     обычная веб-аппроксимация того же ощущения. */
  border-radius: 16px;
  padding: 9px 8px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.add-btn:hover, .add-btn:active, .add-btn.in-cart { background: var(--green); color: var(--white); }
.add-btn:disabled { background: var(--photobg); color: var(--lgray); cursor: not-allowed; }
/* На акционном (зелёном) фоне серая кнопка теряется — делаем её белой. */
.promo-card .add-btn { background: var(--white); }
.promo-card .add-btn:hover, .promo-card .add-btn:active, .promo-card .add-btn.in-cart { background: var(--green); color: var(--white); }

.promo-card .add-btn:disabled { background: var(--white); color: var(--lgray); }

/* ---------- нет в наличии: сворачивание ---------- */
.oos-wrap { margin-top: 16px; }
.oos-label { font-size: 12px; font-weight: 600; color: var(--gray); margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.03em; }
/* "Нет в наличии" (хорошо продающиеся товары, дозаказ >= 100 шт) — первым
   подразделом, ВСЕГДА видимым, без сворачивания (см. site.js:
   buildItemsBlock). По прямому репорту пользователя (2026-08-22,
   скриншот: секция визуально "перетекала" в обычную сетку без границы) —
   явный отступ и разделительная линия снизу, чтобы граница с товарами в
   наличии была однозначной, не угадывалась по одному только заголовку. */
.oos-wrap-visible { margin-top: 0; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 1px solid var(--lgray); }
/* 90px — то же самое, что и FADE_HEIGHT в site.js (buildItemsBlock):
   запасное значение на случай, если JS ещё не успел проверить, есть ли
   вторая строка (там же переопределяет max-height инлайн-стилем — или
   этим же 90px, или "none", если строка всего одна).
   margin-top — по прямому репорту пользователя (2026-08-25, скриншот):
   первая (всегда видимая) строка "нет в наличии" примыкала вплотную к
   этому свёрнутому блоку без отступа — site.js просто добавляет два
   .grid один за другим в один wrap (buildItemsBlock), между гридами нет
   зазора, только gap ВНУТРИ каждого. Особенно заметно у товара без фото
   (длинный текст-заглушка "Упс! Фотограф не поспевает…" в .no-photo
   визуально "прилипал" прямо к следующей строке). Значения — те же, что
   и у .grid gap на тех же брейкпоинтах, чтобы вертикальный ритм совпадал
   с горизонтальным зазором внутри самой сетки. */
.oos-collapse { position: relative; overflow: hidden; max-height: 90px; margin-top: 12px; }
@media (min-width: 620px) {
  .oos-collapse { margin-top: 16px; }
}
@media (min-width: 900px) {
  .oos-collapse { margin-top: 20px; }
}
.oos-collapse.expanded { max-height: none; }
.oos-fade {
  position: absolute; left: 0; right: 0; bottom: 0; height: 90px;
  background: linear-gradient(to bottom, rgba(250,250,250,0), var(--bg));
  pointer-events: none;
}
.oos-collapse.expanded .oos-fade { display: none; }
.oos-toggle {
  margin-top: 10px;
  background: none;
  border: none;
  color: var(--green);
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  padding: 0;
}

.empty-state { text-align: center; color: var(--gray); padding: 60px 20px; }

/* Подпись над ослабленной выдачей поиска: точных совпадений не нашлось,
   показываем ближайшее, но честно предупреждаем. */
.search-partial-note {
  margin: 4px 2px 10px;
  color: var(--gray);
  font-size: 14px;
}

/* ---------- оверлей "все разделы" ---------- */
.categories-overlay {
  position: fixed; inset: 0; z-index: var(--z-overlay-backdrop);
  background: rgba(0,0,0,0.4);
  display: flex; align-items: flex-end;
}
.categories-overlay-panel {
  background: var(--white);
  width: 100%;
  max-height: 75vh;
  border-radius: 20px 20px 0 0;
  padding: 16px 20px 24px;
  display: flex;
  flex-direction: column;
  margin: 0 auto;
}
@media (min-width: 640px) {
  .categories-overlay { align-items: center; justify-content: center; }
  .categories-overlay-panel { max-width: 420px; border-radius: 20px; max-height: 70vh; }
}
.categories-overlay-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.categories-overlay-header h2 { font-size: 16px; margin: 0; }

/* Переключатель "старая/расширенная сортировка" — только в личном кабинете
   клиента (см. site.js: setupSortModeToggle). */
.seg-toggle-row { display: flex; background: var(--photobg); border-radius: var(--r-pill); padding: 3px; gap: 2px; margin-bottom: 14px; }
.seg-toggle-btn {
  flex: 1; border: none; background: none; color: var(--gray); padding: 8px 10px;
  border-radius: var(--r-pill); font-size: 12.5px; font-weight: 600; cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.seg-toggle-btn.active { background: var(--green); color: var(--white); }

.categories-overlay-list { overflow-y: auto; display: flex; flex-direction: column; }

/* Аккордеон дерева разделов внутри оверлея "Все разделы": раздел ->
   подразделы (+ вложенный список брендов). Раскрытие — справа в каждой
   строке (по фидбэку пользователя: на телефоне удобнее нажимать правой
   частью экрана), разделы раскрыты сразу, свёрнуты только "Бренды". */
.overlay-parent-head {
  width: 100%; border: none; background: none; text-align: left; cursor: pointer;
  display: flex; align-items: center; gap: 9px;
  padding: 12px 4px; font-size: 14.5px; font-weight: 700; color: var(--ink);
  border-bottom: 1px solid var(--border);
}
.overlay-parent-head .pname { flex: 1; }
.overlay-parent-head .right { display: flex; align-items: center; gap: 9px; flex-shrink: 0; }
.overlay-parent-head .cnt { font-size: 12px; color: var(--gray); font-weight: 500; }
.overlay-parent-head .chev { font-size: 11px; color: var(--gray); width: 12px; text-align: center; flex-shrink: 0; }
/* "Все бренды" — заголовок группы там div, не button (нечего сворачивать). */
.overlay-parent-head:not(button) { cursor: default; }
.overlay-children { padding: 2px 4px 8px 14px; display: flex; flex-direction: column; }
.overlay-child {
  width: 100%; border: none; background: none; text-align: left; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
  padding: 9px 8px; font-size: 13.5px; color: var(--ink); border-radius: var(--r-control);
}
.overlay-child:hover { background: var(--photobg); }
.overlay-child .cnt { color: var(--gray); font-size: 12px; }
.overlay-brand-block { margin-bottom: 4px; padding-bottom: 6px; border-bottom: 1px dashed var(--border); }
.overlay-brand-toggle {
  width: 100%; border: none; background: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between;
  padding: 6px 8px 4px;
  font-size: 12.5px; font-weight: 700; color: var(--green-dark);
}
.overlay-brand-toggle .chev { font-size: 10px; }
.overlay-brand-list { display: flex; flex-direction: column; padding-left: 6px; border-left: 2px solid var(--green-border); margin-left: 2px; }
.overlay-brand .cnt { color: var(--green-dark); }

/* ---------- товар: полная карточка ---------- */
.product-modal {
  position: fixed; inset: 0; z-index: var(--z-overlay-panel);
  background: rgba(0,0,0,0.4);
  display: flex; align-items: flex-end;
}
.product-modal-panel {
  background: var(--white);
  width: 100%;
  /* vh в мобильном Safari считается от МАКСИМАЛЬНОЙ высоты экрана (когда
     адресная строка скрыта) — если она видна (как обычно сразу после
     перехода по ссылке), реальная видимая область меньше, и панель на
     90vh вылезала выше неё, утаскивая крестик, который сидел в её верхней
     части, за пределы экрана (фидбэк пользователя — "крестик где-то там
     под доменом"). svh — высота именно видимой (small) области, без этого
     рассинхрона; там, где svh не поддерживается, используется vh (строка
     выше, обычный CSS-фоллбек — на новых экран не хуже, на старых работает
     как раньше). Сам крестик теперь всё равно не зависит от высоты панели
     (см. ниже, position: fixed), но и остальной контент не должен вылезать
     за реально видимую область. */
  max-height: 90vh;
  max-height: 90svh;
  border-radius: 20px 20px 0 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
}
/* Прокручивается ТОЛЬКО эта внутренняя обёртка, не вся панель — крестик
   (product-modal-close) сидит вне неё, в самой панели, поэтому при скролле
   длинного списка альтернатив остаётся на месте, а не уезжает с контентом
   и не пропадает из виду (было — см. историю правки). min-height: 0
   обязателен: без него flex-элемент не сжимается до max-height родителя и
   вместо внутреннего скролла просто раздувает панель на весь контент. */
.product-modal-scroll { overflow-y: auto; flex: 1; min-height: 0; padding: 0 0 20px; }
@media (min-width: 640px) {
  .product-modal { align-items: center; justify-content: center; }
  .product-modal-panel { max-width: 480px; border-radius: 20px; max-height: 85vh; max-height: 85svh; }
}
/* На настоящем десктопе (не просто "шире телефона") — по прямому запросу
   пользователя (2026-08-27): "удобство десктопной версии в том, что мы на
   одном экране видим сразу много... сейчас карточки открываются в
   размере смартфона" — карточка товара/клиента должна использовать
   реальную ширину экрана, "как большой планшет повёрнутый горизонтально",
   не оставаться зауженной до 480px. 900px — тот же desktop-порог, что уже
   используется по всему сайту (.fab-stack/.analytics-section h2 и т.д.),
   не новое произвольное число. min(1100px, 92vw) — не упирается в самый
   край окна на очень широких мониторах, но и не вылезает за реальную
   ширину на более скромном десктопном разрешении. */
@media (min-width: 900px) {
  .product-modal-panel { max-width: min(1100px, 92vw); }
  /* Фото — по прямому репорту пользователя (2026-08-27, "сейчас плохо
     выглядит" — было edge-to-edge на всю ширину 480px, затем просто
     отцентрировано на всю ширину 1100px): теперь заметно меньше, с
     отступами от краёв, скруглёнными углами, прижато к левому краю
     (не растянуто и не по центру) — верхний левый угол карточки, как и
     просили. Не float — .product-modal-body ниже сам flex-контейнер
     (flex-direction:column), CSS-float с ним не сработал бы как
     "обтекание текстом" (flex-контейнер как единый BFC-блок целиком
     уезжает в сторону от float на всю свою высоту, а не только заголовок
     — попробовано, отклонено): проще и надёжнее остаться в обычном
     блочном потоке, просто уменьшить и подвинуть само фото. */
  .product-modal-photo {
    width: 320px; max-width: 320px;
    margin: 20px 0 4px 20px;
    border-radius: 16px;
    overflow: hidden;
  }
}
/* .icon-btn.product-modal-close (два класса), не просто .product-modal-close
   (один класс) — общий .icon-btn (используется ещё у крестиков корзины и
   списка категорий) задаёт background: none той же специфичностью, что и
   один класс, и, стоя ниже в файле, побеждал бы: кнопка была фактически
   прозрачной (репорт пользователя — "не прозрачной, а полностью белой"). */
.icon-btn.product-modal-close {
  /* absolute внутри .product-modal-panel (у неё уже position: relative), не
     fixed относительно экрана — раньше было fixed именно потому, что
     панель на 90vh могла вылезать выше реально видимой области (мобильный
     Safari с показанной адресной строкой) и утаскивала кнопку-соседа за
     собой; тот баг закрыт переходом на svh у max-height панели (см. ниже),
     после чего fixed стал не нужен и создал НОВУЮ проблему — панель снизу
     (align-items: flex-end) может начинаться намного ниже верха экрана
     (когда под карточкой не видно строки браузера, свободного места
     сверху больше), а кнопка, зафиксированная у самого верха экрана,
     оказывалась далеко от самой карточки (фидбэк пользователя). Кнопка —
     сосед .product-modal-scroll, не её потомок, поэтому при скролле
     длинного списка альтернатив всё равно остаётся на месте, а не уезжает
     с контентом. */
  position: absolute;
  top: 12px;
  left: 12px;
  z-index: calc(var(--z-overlay-panel) + 1);
  background: var(--white); color: var(--ink); border-radius: 50%; width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 6px rgba(0,0,0,0.15);
  font-size: 18px;
}
.pm-close-glyph-desktop { display: none; }
/* Кнопка "наверх карточки клиента" — тот же absolute-приём, что и
   .icon-btn.product-modal-close (сосед .product-modal-scroll, не потомок:
   остаётся на месте при скролле длинной карточки), нижний правый угол
   панели, появляется только после прокрутки вниз (см. site.js). Визуально —
   ровно тот же дизайн, что и #scroll-top-toggle на основной странице (44px
   круг/белый фон/тень/SVG-стрелка) — по прямому запросу пользователя
   (2026-08-26, "в том же дизайне, что и на основной странице, а не в новом
   дизайне") — не общий класс (у .scroll-top-toggle своя логика позиции
   через .fab-stack/position:fixed, конфликтующая с position:absolute
   внутри модалки), просто те же самые декларации. */
.client-modal-scroll-top {
  position: absolute;
  bottom: 16px; right: 16px;
  z-index: calc(var(--z-overlay-panel) + 1);
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border: none; border-radius: 50%;
  background: var(--white); color: var(--ink);
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(20,20,20,0.2);
  transition: background 0.15s ease;
}
.client-modal-scroll-top:hover { background: var(--photobg); }
@media (min-width: 640px) {
  /* На десктопе панель — центрированный диалог, а не полноэкранный лист;
     крестик вместо стрелочки — на десктопе слева уже нет смысла в "назад",
     это обычный диалог, который принято закрывать крестиком в правом
     верхнем углу. */
  .icon-btn.product-modal-close {
    left: auto;
    right: 12px;
  }
  .pm-close-glyph-mobile { display: none; }
  .pm-close-glyph-desktop { display: block; }
}
.product-modal-photo { background: var(--photobg); aspect-ratio: 4 / 3; overflow: hidden; position: relative; }
.product-modal-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.product-modal-photo img.photo-contain { object-fit: contain; padding: 16px; }
.product-modal-body { padding: 18px 20px 4px; display: flex; flex-direction: column; gap: 8px; }
.product-modal-body h2 { font-size: 18px; margin: 0; line-height: 1.3; }
/* ---------- описание товара в модалке (только сокращённый кабинет) ----------
   Копия .product-modal-desc из site/static/style.css. Разделы (абзац /
   характеристики / состав / дисклеймер) рисуются только при наличии данных
   — см. site.js:renderProductDesc. */
.product-modal-desc {
  font-size: 13.5px; color: var(--gray); line-height: 1.55;
  margin: 6px 0 0; padding-top: 16px; border-top: 1px solid var(--border);
  display: flex; flex-direction: column; gap: 14px;
}
.product-modal-desc .pm-desc-lead { margin: 0; }
.product-modal-desc .pm-desc-specs {
  margin: 0; padding-top: 14px; border-top: 1px solid var(--border);
  /* Не max-content: длинный ключ не переносился и сетка вылезала за экран
     (скриншот 2026-09-14, синхронно с site/). */
  display: grid; grid-template-columns: fit-content(45%) minmax(0, 1fr); gap: 8px 16px;
}
.product-modal-desc .pm-desc-specs dt,
.product-modal-desc .pm-desc-specs dd { min-width: 0; overflow-wrap: break-word; word-break: break-word; }
.product-modal-desc .pm-desc-specs dt { color: var(--ink); font-weight: 400; }
.product-modal-desc .pm-desc-specs dt::after { content: ":"; }
.product-modal-desc .pm-desc-specs dd { margin: 0; }
.product-modal-desc .pm-desc-sostav {
  margin: 0; padding-top: 14px; border-top: 1px solid var(--border);
}
.product-modal-desc .pm-desc-sostav b { color: var(--ink); font-weight: 400; }
.product-modal-desc .pm-desc-notes {
  margin: 0; padding: 14px 16px;
  display: flex; align-items: center; gap: 13px;
  background: #faf4ea; border-radius: 14px;
}
.product-modal-desc .pm-desc-notes-ic {
  flex: none; width: 20px; height: 20px; border-radius: 50%;
  border: 1.5px solid #cfa16f; color: #b47636;
  font-size: 12px; font-weight: 600; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.product-modal-desc .pm-desc-notes-list { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.product-modal-desc .pm-desc-notes-list p { margin: 0; font-size: 12px; color: #7a5326; line-height: 1.5; }
.product-modal-desc .pm-desc-disc { margin: 2px 0 0; font-size: 11.5px; color: var(--lgray); line-height: 1.45; }
/* ---------- товар с характеристиками (например, диффузоры разных
   ароматов) — лента вариантов под главным фото ---------- */
.pm-variants {
  display: flex; gap: 8px; overflow-x: auto; padding: 10px 20px;
  -webkit-overflow-scrolling: touch; background: var(--white);
}
.pm-variant-chip {
  flex: 0 0 auto; width: 60px; display: flex; flex-direction: column; align-items: center; gap: 4px;
  cursor: pointer; border: none; background: none; padding: 0;
}
.pm-variant-thumb {
  width: 52px; height: 52px; border-radius: var(--r-control); overflow: hidden;
  border: 2px solid transparent; box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  background: var(--photobg); color: var(--lgray); font-size: 18px;
}
.pm-variant-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pm-variant-chip.active .pm-variant-thumb { border-color: var(--green); }
.pm-variant-chip.out-of-stock .pm-variant-thumb { opacity: 0.45; }
.pm-variant-name {
  font-size: 10px; text-align: center; line-height: 1.2; color: var(--gray);
  max-width: 60px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pm-variant-chip.active .pm-variant-name { color: var(--green-dark); font-weight: 600; }
/* Чип "Все варианты" (агрегат по товару в целом) — эмодзи вместо фото,
   лёгкий акцентный фон, чтобы визуально не путался с ароматами (по
   прямому запросу пользователя 2026-08-20). */
.pm-variant-chip-all .pm-variant-thumb { background: var(--green-bg); font-size: 22px; }
.pm-variant-chip-all.active .pm-variant-thumb { border-color: var(--green); }

.icon-btn { border: none; background: none; font-size: 22px; cursor: pointer; color: var(--gray); }
/* .btn — общая кнопка, используется и на <button> (страницы "Закупки"/
   "Устройства"), и на <a> (страница "Логин"), где по умолчанию у ссылки был
   бы inline-текст без фона на всю ширину. */
.btn { box-sizing: border-box; display: block; text-align: center; text-decoration: none; border: none; border-radius: var(--r-btn-lg); padding: 13px; font-size: 14px; font-weight: 600; cursor: pointer; transition: background 0.15s ease; }
.btn-primary { background: var(--green); color: var(--white); }
.btn-primary:hover { background: var(--green-dark); }
.btn-secondary { background: var(--photobg); color: var(--ink); border: 1px solid var(--border); }
.btn:disabled { background: var(--photobg); color: var(--lgray); cursor: not-allowed; }
.retry-btn { margin-left: 6px; text-decoration: underline; background: none; border: none; color: inherit; font: inherit; cursor: pointer; padding: 0; }

/* ---------- каталог: загрузка/ошибка ---------- */
.catalog-loading { text-align: center; color: var(--gray); padding: 60px 16px; font-size: 14px; }
.catalog-error { text-align: center; color: var(--danger); padding: 60px 16px; font-size: 14px; }

/* ---------- личный кабинет: вход по PIN ---------- */
.cabinet-login-body { background: var(--bg); margin: 0; font-family: "Inter", system-ui, sans-serif; }
.cabinet-login-page {
  max-width: 360px; margin: 0 auto; min-height: 100vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 24px; text-align: center;
}
.cabinet-login-logo { height: 48px; width: auto; margin-bottom: 20px; }
.cabinet-login-title { font-size: 20px; margin: 0 0 6px; color: var(--ink); }
.cabinet-login-sub { font-size: 14px; color: var(--gray); margin: 0 0 24px; }
.cabinet-login-form { width: 100%; display: flex; flex-direction: column; gap: 14px; }
.cabinet-login-input {
  width: 100%; border: 1px solid var(--border); background: var(--photobg);
  /* var(--r-btn-lg), не --r-control — консистентно со скруглением кнопки
     "Войти" сразу под полем (по фидбэку пользователя, было заметно мельче). */
  border-radius: var(--r-btn-lg); padding: 16px; text-align: center;
  font-family: inherit; font-size: 24px; font-weight: 700; letter-spacing: 0.3em;
}
.cabinet-login-input:focus { outline: none; border-color: var(--green); background: var(--white); }
/* Поле, заполненное менеджером паролей, браузер красит своим жёлтым — он
   выбивается из зелёной вёрстки (запрос пользователя 2026-09-17). Цвет
   фона у autofill нельзя переопределить обычным background: WebKit рисует
   его поверх, поэтому подменяем ОГРОМНОЙ внутренней тенью, а текст —
   -webkit-text-fill-color. transition на 5 минут — старый приём против
   того, что Chrome возвращает свой фон сразу после отрисовки. */
.cabinet-login-input:-webkit-autofill,
.cabinet-login-input:-webkit-autofill:hover,
.cabinet-login-input:-webkit-autofill:focus,
.cabinet-login-input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px var(--green-bg, #e9f7ef) inset !important;
  box-shadow: 0 0 0 1000px var(--green-bg, #e9f7ef) inset !important;
  -webkit-text-fill-color: var(--ink);
  caret-color: var(--ink);
  border-color: var(--green);
  transition: background-color 600000s 0s, color 600000s 0s;
}
/* Firefox рисует своё выделение автозаполнения отдельным правилом. */
.cabinet-login-input:autofill { background: var(--green-bg, #e9f7ef); border-color: var(--green); }
.cabinet-login-error { color: var(--danger); font-size: 13.5px; }
.cabinet-login-trust { display: flex; align-items: center; gap: 8px; font-size: 14px; color: var(--gray); cursor: pointer; text-align: left; }
.cabinet-login-trust input { width: 18px; height: 18px; accent-color: var(--green); flex: none; }
.cabinet-login-submit { width: 100%; }
/* «Кто входит» — у подключивших приложение на телефон (mgmt_accounts, 23.09).
   Своя стрелка: системную на iOS не видно на светлой подложке. */
.cabinet-login-who { appearance: none; -webkit-appearance: none; cursor: pointer; padding-right: 36px;
  letter-spacing: normal; font-size: 16px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%237a8a80' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; }

/* ---------- страница подключения приложения на телефон ---------- */
.mgmt-setup { max-width: 420px; }
/* Поля входа набраны в разрядку (это про звёздочки пароля), а здесь в них
   пишут словами — подсказка обрезалась на «Новый пароль, от». */
.mgmt-setup .cabinet-login-input { letter-spacing: normal; font-size: 16px; }
.mgmt-setup-btn { display: block; width: 100%; padding: 14px; border-radius: var(--r-btn-lg);
  border: 1px solid var(--green); color: var(--green-dark, var(--green)); background: var(--green-bg, #e9f7ef);
  font-weight: 600; text-align: center; text-decoration: none; }
.mgmt-setup-h { font-size: 15px; font-weight: 600; margin: 18px 0 2px; text-align: left; }
.mgmt-setup-note { font-size: 13.5px; color: var(--gray); margin: 0 0 6px; text-align: left; }
.mgmt-setup-qr { display: flex; justify-content: center; margin: 4px 0 2px; }
.mgmt-setup-qr svg { width: 180px; height: 180px; }
.mgmt-setup-steps { text-align: left; font-size: 14px; color: var(--gray); margin: 0 0 20px; padding-left: 20px; }
.mgmt-setup-steps li { margin: 6px 0; }
/* Придуманный нами пароль показываем открыто — иначе его не переписать. */
.mgmt-setup-gen { text-align: left; background: var(--green-bg, #e9f7ef); border-radius: var(--r-btn-lg); padding: 12px 14px; }
.mgmt-setup-gen b { display: block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 18px;
  letter-spacing: 0.02em; word-break: break-all; margin-bottom: 4px; }
.mgmt-setup-gen span { font-size: 13px; color: var(--gray); }
.mgmt-setup-label { display: block; font-size: 13px; color: var(--gray); text-align: left; margin: 0 0 -4px; }
.mgmt-setup-login { font-weight: 600; }
.mgmt-setup-btn-2 { border-color: var(--border, #e3e6e8); color: inherit; background: #fff; font-weight: 500; }
button.mgmt-setup-btn { font: inherit; cursor: pointer; }
.mgmt-setup-help { text-align: left; font-size: 14px; }
.mgmt-setup-help summary { cursor: pointer; color: var(--green-dark, var(--green)); font-weight: 600; padding: 4px 0; }
.mgmt-setup-help[open] summary { margin-bottom: 8px; }
.mgmt-setup-help .mgmt-setup-btn { margin: 0 0 12px; }
.mgmt-setup-key b { display: block; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 15px;
  word-break: break-all; background: var(--green-bg, #e9f7ef); border-radius: var(--r-btn-lg); padding: 10px 12px; margin-bottom: 8px;
  user-select: all; -webkit-user-select: all; }

/* ---------- страница "Личный кабинет" в шапке основного сайта
   (cabinet_info.html) — не путать с cabinet-login выше: это не форма
   входа, а объяснение + кнопки написать менеджеру. Переиспользует только
   .cabinet-login-body/-logo (логотип по центру — этого по прямому запросу
   пользователя достаточно, остальное — заголовок и текст — слева, не по
   центру). */
.cabinet-info-back {
  /* fixed, не в потоке страницы — здесь нет общего "шапка+назад" ряда, как
     в cabinet_orders.html, страница начинается сразу с логотипа. Тот же
     визуальный стиль, что и .orders-back, но своим классом — .orders-back
     завязан на позиционирование внутри .orders-header, здесь его нет. */
  position: fixed;
  top: calc(12px + env(safe-area-inset-top));
  left: calc(12px + env(safe-area-inset-left));
  z-index: 1;
  background: var(--white); color: var(--ink); border-radius: 50%; width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 1px 6px rgba(0,0,0,0.1);
  font-size: 18px;
}
.cabinet-info-page {
  max-width: 420px; margin: 0 auto; min-height: 100vh;
  display: flex; flex-direction: column; align-items: center;
  padding: 32px 24px; text-align: center;
}
.cabinet-info-title { font-size: 28px; color: var(--logo-green); text-align: left; width: 100%; margin: 4px 0 20px; }
.cabinet-info-text { font-size: 14.5px; color: var(--logo-green); line-height: 1.6; text-align: left; margin: 0 0 16px; }
.cabinet-info-actions { width: 100%; margin-top: 8px; }

/* ---------- личный кабинет: история заказов (cabinet_orders.html) ----------
   Отдельная лёгкая страница, без site.js — список заказов не участвует ни
   в поиске, ни в категориях, ни в корзине. */
.orders-body { background: var(--bg); margin: 0; font-family: "Inter", system-ui, sans-serif; color: var(--ink); }
.orders-page { max-width: 640px; margin: 0 auto; padding: 16px 16px 40px; }
/* sticky, не просто в потоке — чтобы выйти из истории заказов, не нужно
   прокручивать список вверх до конца (по фидбэку пользователя). Фон и
   отступы по бокам — чтобы карточки заказов не просвечивали под шапкой
   при скролле. */
.orders-header {
  display: flex; align-items: center; gap: 12px;
  position: sticky; top: 0; z-index: 5;
  background: var(--bg); margin: 0 -16px 18px; padding: 16px 16px 10px;
}
.orders-back {
  background: var(--white); border-radius: 50%; width: 34px; height: 34px;
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  box-shadow: 0 1px 6px rgba(0,0,0,0.1); text-decoration: none;
}
.orders-title { font-size: 19px; margin: 0; }
.orders-empty { color: var(--gray); font-size: 14px; }
.orders-note { color: var(--gray); font-size: 12.5px; text-align: center; margin: 14px 0 0; }

.orders-list { display: flex; flex-direction: column; gap: 14px; }
.order-card { background: var(--white); border-radius: var(--r-card); padding: 16px; border: 1px solid var(--border); }
.order-card-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; gap: 10px; }
.order-date { font-weight: 700; font-size: 14px; }
.order-number { color: var(--gray); font-size: 12.5px; }
.order-lines { display: flex; flex-direction: column; gap: 6px; }
.order-line { display: flex; align-items: baseline; gap: 6px; font-size: 13.5px; }
.order-line-name { flex-shrink: 1; min-width: 0; }
.order-line-dots { flex: 1 1 12px; min-width: 12px; border-bottom: 1px dotted var(--lgray); margin-bottom: 4px; }
.order-line-qty { flex-shrink: 0; color: var(--gray); font-size: 12.5px; }

/* ---------- страница "Устройства" (devices.html) — редизайн (2026-08-19) ----------
   Раньше .purchases-page/.purchases-note (обёртка страницы и вводный
   абзац) вообще не имели стилей — .purchases-page задавался только в
   локальном <style> самого devices.html, а .purchases-note не был
   определён нигде, даже там (страница на деле рендерилась почти без
   оформления). Теперь — переиспользует .orders-page/.orders-header
   (уже стилизованы для этой же группы страниц выше), плюс новые
   .device-* классы здесь, единым языком с .abc-card/.pm-mgmt-badge —
   по прямому запросу пользователя: "легко пропустить мошеннический вход
   среди своих же... пересобери с точки зрения качественного UX/UI". */
.devices-intro { font-size: 12.5px; color: var(--gray); line-height: 1.55; margin: 0 0 18px; }
.devices-list { display: flex; flex-direction: column; gap: 12px; }
.device-card {
  background: var(--white); border: 1px solid var(--border); border-radius: var(--r-card);
  padding: 16px 18px; box-shadow: 0 1px 2px rgba(20, 20, 20, 0.05);
}
/* Незаблокированное и ещё НЕ подписанное — единственное состояние, где
   реально нужно решение владельца ("это я или нет?") — по прямому
   запросу пользователя выделено сильнее остальных (левая цветная полоса
   + лёгкий тёплый фон), чтобы не потеряться среди спокойных известных
   карточек. Заблокированное — тревожный красный, но это уже РЕШЁННЫЙ
   случай (не требует внимания прямо сейчас), поэтому чуть спокойнее
   незаблокированного-неподписанного по иерархии (см. сортировку в
   management/app.py:devices_page — неподписанные всегда выше). */
.device-card.unlabeled { border-left: 3px solid var(--warning); background: var(--warning-bg); }
.device-card.blocked { border-left: 3px solid var(--danger); background: rgba(220, 53, 69, 0.05); }
.device-card.current { border-color: var(--green); }
.device-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; flex-wrap: wrap; }
.device-label { font-size: 15px; font-weight: 700; }
.device-badges { display: flex; gap: 6px; flex-wrap: wrap; justify-content: flex-end; }
.device-badge {
  font-size: 11px; font-weight: 600; white-space: nowrap;
  background: var(--bg-alt, #f2f2f4); color: var(--gray); border-radius: var(--r-control, 12px); padding: 4px 9px;
}
.device-badge.current-badge { background: var(--green); color: var(--white); }
.device-badge.blocked-badge { background: var(--danger); color: var(--white); }
.device-badge.unlabeled-badge { background: var(--warning); color: var(--white); }
.device-meta { font-size: 12px; color: var(--gray); margin: 8px 0 12px; line-height: 1.6; }
.device-rename { display: flex; gap: 8px; margin-bottom: 10px; }
.device-rename input {
  flex: 1; min-width: 0; padding: 9px 12px; border: 1px solid var(--border); border-radius: var(--r-control);
  background: var(--photobg); font-family: inherit; font-size: 16px; color: var(--ink);
  outline: none; transition: border-color 0.15s ease, background 0.15s ease;
}
.device-rename input:focus { border-color: var(--green); background: var(--white); }
.device-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.device-actions form { display: inline; }

/* Кабинет аналитики закупок (management/, Шаг 3 плана) — расширенный блок
   в карточке товара. Переработано 2026-08-18 по прямому запросу
   пользователя ("максимально дотошно... акцент только на необходимых
   данных, другие вторичны и третичны") — единая система отступов
   (.pm-section) и подписей разделов (.pm-section-label, приглушённая
   капитель вместо жирного текста наравне с данными), чтобы разделы не
   соревновались друг с другом за внимание. */
.pm-management { margin: 10px 0; padding-top: 10px; border-top: 1px solid var(--lgray); }
.pm-section { margin-bottom: 18px; }
.pm-section:last-child { margin-bottom: 0; }
.pm-section-label {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--lgray); margin-bottom: 7px;
}
.pm-mgmt-badges { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 6px; }
.pm-mgmt-badge { font-size: 12px; color: var(--gray); background: var(--bg-alt, #f2f2f4); border-radius: var(--r-control, 12px); padding: 4px 10px; }
.pm-mgmt-badge b { color: var(--ink, #1a1a1a); }
/* Цвет по букве — тот же зелёный/жёлтый/красный, что и у двойной плашки
   ABC/XYZ на карточке в сетке (см. classifyLevel в site.js), по прямому
   запросу пользователя (2026-08-18): классификация должна читаться
   одинаково визуально, а не только текстом снаружи и текстом внутри. */
.pm-mgmt-badge.margin-good { background: var(--green); color: var(--white); }
.pm-mgmt-badge.margin-mid { background: var(--warning); color: var(--white); }
.pm-mgmt-badge.margin-bad { background: var(--danger); color: var(--white); }
.pm-mgmt-badge.margin-loss { background: var(--loss); color: var(--white); }
.pm-mgmt-badge.margin-good b, .pm-mgmt-badge.margin-mid b, .pm-mgmt-badge.margin-bad b, .pm-mgmt-badge.margin-loss b { color: var(--white); }
/* "мало данных" рядом с буквой XYZ — надёжность_xyz=False, см. src/abc_xyz.py
   (CV посчитан по короткому, статистически шумному ряду). */
.pm-mgmt-badge .xyz-low-data { font-weight: 400; opacity: 0.85; }
.pm-mgmt-totals { font-size: 12px; color: var(--gray); }
/* Пометка "общая аналитика / по варианту" у товаров с характеристиками
   (диффузоры, чай Koza) — по прямому запросу пользователя (2026-08-19). */
.pm-scope-note {
  font-size: 12px; color: var(--gray); background: var(--bg-alt, #f2f2f4);
  border-radius: var(--r-control, 8px); padding: 6px 10px; margin-bottom: 10px;
}
.pm-mgmt-loading { font-size: 13px; color: var(--gray); padding: 4px 0; }
.pm-mgmt-history { width: 100%; border-collapse: collapse; font-size: 12px; }
.pm-mgmt-history th { text-align: left; color: var(--gray); font-weight: 500; padding: 3px 6px 3px 0; border-bottom: 1px solid var(--lgray); }
.pm-mgmt-history td { padding: 4px 6px 4px 0; border-bottom: 1px solid var(--lgray); color: var(--gray); }
.pm-mgmt-history td:first-child { color: var(--ink); font-variant-numeric: tabular-nums; }

/* График спроса по месяцам (renderDemandChart) — простые CSS-столбики, без
   библиотек: высота .pm-demand-bar в % от максимума за окно (12 мес., см.
   SALES_HISTORY_MONTHS). 12 колонок в узкий экран телефона уже не
   утрамбовать без потери читаемости подписей — скролл вбок вместо сжатия
   (тот же приём, что и у .table-scroll в "Аналитике склада"), колонка
   фиксированной ширины, а не резиновая. */
.pm-demand-chart { display: flex; gap: 8px; align-items: flex-end; margin-bottom: 8px; overflow-x: auto; padding-bottom: 2px; }
.pm-demand-col { flex: 0 0 34px; display: flex; flex-direction: column; align-items: center; gap: 2px; }
/* Высота фиксирована на одну строку — по прямому репорту пользователя
   (2026-08-18): более длинная подпись у месяцев "не в наличии" раньше
   переносилась на 2 строки и делала эти колонки выше соседних (казалось,
   что часть столбиков "лезет вверх"); теперь у всех подписей одна строка
   (см. valueText в site.js — "нет" вместо "нет в наличии"), но высота
   всё равно зафиксирована на случай будущих длинных значений.
   white-space:nowrap + overflow:visible — по прямому репорту пользователя
   (2026-08-18, "опять вёрстка сломалась"): "5 064"/"1 306" и т.п. шире
   34px-колонки и без nowrap переносились на 2 строки, вылезая из
   зафиксированной высоты и ломая выравнивание с баром под ними. Теперь
   число не переносится, а слегка нависает над соседней колонкой при
   необходимости (за счёт gap между колонками) — это менее заметно, чем
   разъехавшаяся вёрстка. */
.pm-demand-value { font-size: 10.5px; color: var(--gray); font-variant-numeric: tabular-nums; height: 13px; line-height: 13px; white-space: nowrap; overflow: visible; }
/* Подпись "N зак." под суммой выручки — панель "Заказы по месяцам" в
   карточке клиента (2026-08-27, по прямому запросу пользователя), тот же
   .pm-demand-col/.pm-demand-chart, что и у "Спрос по месяцам" на карточке
   товара, просто с дополнительной строкой числа заказов. */
.client-month-orders { font-size: 9px; color: var(--lgray); line-height: 11px; white-space: nowrap; }
.pm-demand-value.no-stock { font-size: 9px; }
.pm-demand-track { width: 100%; height: 56px; display: flex; align-items: flex-end; background: var(--photobg); border-radius: 4px; overflow: hidden; }
/* Месяц без остатка на складе (см. src/stock_availability.py) — штриховка
   вместо обычного пустого трека, чтобы не путать с "остаток был, просто не
   продавали". */
.pm-demand-track.no-stock {
  background: repeating-linear-gradient(45deg, var(--photobg), var(--photobg) 4px, var(--lgray) 4px, var(--lgray) 5px);
}
.pm-demand-bar { width: 100%; background: var(--green); border-radius: 4px 4px 0 0; }
/* Текущий (ещё не закрытый в 1С) месяц — по прямому запросу пользователя
   (2026-08-20): показываем количество продаж, но визуально иначе, чтобы не
   приняли за такой же полноценный месяц, как остальные (данные
   предварительные, себестоимость 1С досчитает только на закрытии месяца,
   см. renderDemandChart/demand_trend.build_summary). Самокритика: сначала
   пунктир/бледная заливка стояли прямо на самом бары (.pm-demand-bar) —
   при небольшой высоте бар почти пропадал (бледный цвет на бледном фоне),
   выглядело как пустая колонка. Теперь пунктир — на ВСЁМ треке (полная
   высота 56px, видно всегда), а сам бар внутри остаётся обычным сплошным
   зелёным — заполненность колонки читается так же ясно, как у обычных
   месяцев. */
.pm-demand-track.current-month { border: 1.5px dashed var(--green); background: var(--green-bg); }
.pm-demand-col.current-month .pm-demand-label { color: var(--green-dark); font-weight: 600; }
/* Тот же nowrap-фикс, что и у .pm-demand-value выше, по прямому репорту
   пользователя (2026-08-18, "опять улетает вверх") — на этот раз перенос
   на 2 строки ловился у подписи МЕСЯЦА снизу (например "фев 26"), не у
   числа сверху: колонка с 2-строчной подписью становилась выше соседних,
   и align-items:flex-end у .pm-demand-chart поднимал её содержимое вверх
   относительно однострочных соседей. Высота тоже зафиксирована, как у
   .pm-demand-value — теперь обе подписи в колонке гарантированно занимают
   одинаковую высоту у всех месяцев, выравнивание больше не может разъехаться. */
.pm-demand-label { font-size: 10.5px; color: var(--gray); height: 13px; line-height: 13px; white-space: nowrap; overflow: visible; }
/* Средняя уходимость — заголовок графика, а не отдельный факт, поэтому
   без жирного выделения самого числа: подпись раздела уже сказала, что мы
   на графике спроса, эта строка — итог под ним, вторична. */
.pm-demand-avg { font-size: 12.5px; color: var(--gray); margin-top: 6px; }
.pm-demand-excluded { font-size: 11px; }
.pm-demand-yoy { font-size: 12px; margin-top: 2px; }
.pm-demand-yoy.up { color: var(--green-dark); }
.pm-demand-yoy.down { color: var(--danger); }

/* Рекомендация к закупке — главный вывод карточки для закупщика, поэтому
   вынесена в отдельную акцентную плашку и стоит ПЕРВОЙ в блоке аналитики
   (см. renderManagementBlock в site.js), а не наравне с остальными
   фактами. Большое число — единственное, что нужно прочитать за секунду;
   всё остальное — обоснование под ним, мельче и приглушённее. */
.pm-rec-card { background: var(--green-bg); border: 1px solid var(--green-border); border-radius: var(--r-control, 12px); padding: 12px 14px; }
.pm-rec-card.pm-rec-none { background: var(--bg); border-color: var(--lgray); }
.pm-rec-label { font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--green-dark); }
.pm-rec-card.pm-rec-none .pm-rec-label { color: var(--gray); }
.pm-rec-big { font-size: 25px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ink); line-height: 1.25; margin-top: 1px; }
.pm-rec-detail { font-size: 12px; color: var(--gray); margin-top: 5px; }
.pm-rec-detail b { color: var(--ink); font-weight: 600; }
.pm-rec-note { font-size: 11.5px; color: var(--gray); line-height: 1.5; margin-top: 6px; }
.pm-rec-note.warn b { color: var(--warning); }
.pm-rec-note.unknown { font-style: italic; }

/* Переключатель "Учесть тренд" (2026-08-22) — один общий контрол, виден и
   на карточке товара (см. .pm-rec-top-row), и в блоке "Закуп" (см.
   .zakup-trend-toggle-slot) — переключение в любом месте сразу пересчитывает
   отображаемое число дозаказа везде без нового запроса к серверу. */
.pm-rec-top-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.trend-toggle { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 600; color: var(--gray); cursor: pointer; user-select: none; white-space: nowrap; }
.trend-toggle input { cursor: pointer; }
.zakup-trend-toggle-slot { margin: 8px 0 2px; }
.zakup-trend-toggle-slot .trend-toggle { font-size: 12px; }

/* ---------- "Аналитика склада" / "Закупки" / остаток "Аналитики" — блоки
   на главной странице кабинета (management/templates/catalog.html), по
   прямому запросу пользователя (2026-08-18): раньше были отдельными
   страницами (purchases.html/analytics.html, теперь удалены). ---------- */
/* Аналитика склада + соседние разделы (Закупки/ABC-XYZ счётчики/Неликвиды/
   Падения выручки) — общий контейнер. По прямому запросу пользователя
   (2026-08-18, "на десктопе выглядит стрёмно"): 900px на широком экране
   давал узкую колонку карточек с рыхлыми пропорциями — под десктоп
   отдельный, более широкий контейнер (media query ниже), мобильный вид не
   трогаем (там 900px и так уже равен фактической ширине экрана). */
.analytics-section { max-width: 900px; margin: 0 auto 28px; padding: 0 16px; }
/* 16px читался как подзаголовок, не как заголовок раздела — по прямому
   репорту пользователя (2026-08-19, "заголовки в мобильной версии очень
   маленькие, нужно сделать нормальные"): это те же по смыслу заголовки,
   что и пункты в карусели чипов сверху ("Аналитика", "Закуп",
   "Неликвиды") — должны выглядеть весомо, не мельче текста под ними. */
.analytics-section h2 { font-size: 21px; margin: 0 0 10px; }
/* Заголовок раздела сразу под шапкой смотрелся приплюснутым — по прямому
   репорту пользователя (2026-08-19): нужен зазор сверху (не 0) и явно
   более крупный, уверенный размер на десктопе — на мобильном уже было
   нормально (там своя, более тесная плотность экрана), трогаем только
   десктопную ширину ниже. */
.warehouse-section > h2:first-child { margin-top: 24px; }
/* Отступ у "Закупа" — по прямому запросу пользователя (2026-08-30):
   должен совпадать с отступом у "Клиенты" (у той — только стандартный
   зазор .category-section/.analytics-section, без добавки). Раньше здесь
   был дополнительный margin-top:80px (2026-08-19, когда "Закуп" шёл сразу
   после "Аналитики", а следом — "Неликвиды") — с тех пор "Неликвиды"
   убраны, а этот раздел стал визуально не в ряд с соседями. */
.analytics-section p.hint { font-size: 12.5px; color: var(--gray); margin: 0 0 12px; line-height: 1.5; }
.warehouse-subtitle { font-size: 13px; margin: 22px 0 6px; }
/* overflow-x:auto в одиночку — по прямому репорту пользователя (2026-08-19,
   "фиксированная строка... не заработала, зафиксирована криво внутри
   самой таблицы"): в CSS если overflow-x задан (не visible), а overflow-y
   не задан явно, браузер сам ВЫЧИСЛЯЕТ overflow-y как auto (спека Overflow
   Module, п. про "computed value" для взаимоисключающих visible/иное) —
   .table-scroll незаметно становился собственным скролл-контейнером СРАЗУ
   по обеим осям, и position:sticky у th прилипал К НЕМУ, а не к экрану,
   отсюда и кривое поведение (щель ползла вместе со страницей). Явный
   max-height — вместо борьбы со скрытым автовычислением, делаем ровно то,
   чего и добивались: .table-scroll сам становится маленьким скролл-окном
   с прилипающей к ЕГО верху шапкой (top:0 у th ниже) — для коротких
   таблиц это ничего не меняет (высоты не хватает, скролла нет вообще), для
   длинных — ровно то поведение, которое просили. */
.table-scroll { overflow: auto; max-height: 65vh; }
/* Тепловая таблица и график динамики раньше висели прямо на фоне
   страницы, без своей рамки — на широком экране это читалось как
   недособранный элемент среди аккуратных карточек рядом. Тот же язык
   карточки (граница + тень + скругление), что и .abc-card. */
.warehouse-panel {
  border: 1px solid var(--border); border-radius: var(--r-card);
  padding: 16px 18px; background: var(--white);
  box-shadow: 0 1px 2px rgba(20, 20, 20, 0.05);
}

/* Карточки — тонкая тень + мягкая граница вместо плоского 1px-контура (по
   тому же репорту, "стрёмно выглядят"): чуть больше глубины, не претендуя
   на что-то вычурное — тот же приём для .abc-card/.target-card/
   .supplier-block/.value-chart и т.п. одинаково. */
.abc-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; }
/* Отступ между последовательными .abc-grid/.abc-card блоками — по прямому
   репорту пользователя (2026-08-29): карточка клиента с 2026-08-29
   собирается из ЧЕРЕДУЮЩИХСЯ сетки/одиночной карточки ("Выручка всего" в
   сетке → "Заказов всего" отдельным блоком → "Последний заказ"/
   "Задолженность" снова в сетке, см. site.js: renderClientModalBody) —
   .abc-grid даёт gap ТОЛЬКО между карточками ВНУТРИ одной сетки, у двух
   соседних отдельных блоков между собой отступа не было, они слипались. */
.abc-grid + .abc-card, .abc-card + .abc-grid, .abc-grid + .abc-grid { margin-top: 14px; }
.abc-card {
  border: 1px solid var(--border); border-radius: var(--r-card);
  padding: 16px 18px; background: var(--white);
  box-shadow: 0 1px 2px rgba(20, 20, 20, 0.05);
  /* flex-колонка — по прямому репорту пользователя (2026-08-19,
     "почему данные на карточках с разными отступами?"): .abc-card в
     .abc-grid уже растягивается на всю высоту строки (grid stretch по
     умолчанию), но кнопка внутри (см. .nelikvid-reveal-btn) раньше просто
     шла следом за текстом обычным потоком — у карточки с более длинным
     подзаголовком кнопка оказывалась ниже, чем у соседней с коротким.
     Сама по себе flex-колонка ничего не меняет для карточек без кнопки
     (текстовые блоки внутри — блочные, растяжение по ширине для них не
     заметно) — эффект только у .nelikvid-reveal-btn ниже. */
  display: flex; flex-direction: column;
}
.abc-card h3 { font-size: 13px; font-weight: 600; margin: 0 0 9px; color: var(--gray); }
.abc-row { display: flex; justify-content: space-between; font-size: 14px; padding: 3px 0; }
.abc-row b { font-variant-numeric: tabular-nums; }

/* Общая стоимость остатка — единственная настоящая "шапка" раздела (все
   остальные цифры — детали относительно неё), поэтому отдельная широкая
   карточка над сеткой, крупнее шрифтом, а не один из равных квадратов. */
.abc-hero { margin-bottom: 14px; padding: 18px 22px; }
.stock-hero { font-size: 32px; }

.stock-big { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }
.stock-big.gmroi-good { color: var(--green-dark); }
.stock-big.gmroi-mid { color: var(--warning); }
.stock-big.gmroi-bad { color: var(--danger); }
/* Валовая прибыль клиента — второй, чуть меньший заголовок сразу под
   выручкой (по прямому запросу пользователя, 2026-08-26: "тоже заглавно"),
   не мелкая подпись — но всё же меньше самой выручки, чтобы не спорить
   с ней за внимание. */
.stock-big-secondary { font-size: 17px; margin-top: 2px; }
/* Отступ между крупной цифрой "Заказов всего" и графиком по месяцам под
   ней — по прямому запросу пользователя (2026-08-29), без него цифра и
   первая строка графика визуально слипались. */
.client-orders-total-value { margin-bottom: 14px; }

/* Прогресс к цели "10 млн ₽/мес чистой прибыли" (2026-08-24) — простая
   полоска под заголовком abc-hero, тот же принцип, что и bar-высоты
   графиков (готовый % от сервера, div просто рисует). */
.profit-progress-track { width: 100%; height: 8px; border-radius: var(--r-sm); background: var(--photobg); margin-top: 10px; overflow: hidden; }
.profit-progress-fill { height: 100%; background: var(--green); border-radius: var(--r-sm); transition: width 0.3s ease; }
.expiry-loss { color: var(--danger); }
.concentration-link { color: var(--link-blue); font-weight: 600; cursor: pointer; text-decoration: underline; }
.stock-sub { font-size: 12px; color: var(--gray); margin-top: 4px; line-height: 1.5; }
.stock-split-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-size: 13.5px; padding: 4px 0; }
/* Разбивка "Продажи" по менеджерам (2026-08-25) — та же .stock-split-row,
   просто отделена от крупной суммы над ней тонкой линией. */
.sales-manager-split { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--lgray); }
/* Клик по столбику "По дням"/"По месяцам" — по прямому запросу пользователя
   (2026-08-26): карточки "Сегодня"/"С начала месяца" подменяются данными
   за выбранный день/месяц, см. site.js. Подсветка — ТОЛЬКО во время
   самого нажатия (:active), не сохраняется после отпускания — по прямому
   репорту пользователя (2026-08-29): "выделение должно отображаться
   только при нажатии", постоянная заливка выбранного столбика (класс
   .selected, убран из JS) выглядела как зависший баг, особенно после
   прокрутки страницы далеко от карточек "Сегодня"/"С начала месяца" —
   те и так корректно обновляются данными без подсветки самого столбика. */
.sales-day-col, .sales-month-col {
  cursor: pointer;
  border-radius: var(--r-sm);
  transition: background 0.1s ease;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
}
.sales-day-col:active, .sales-month-col:active { background: var(--photobg); }
.sales-month-profit-lines { margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--lgray); }
/* Расходы выбранного месяца — компактный текстовый разворот прямо в
   карточке "С начала месяца" (2026-09-03, взамен убранного отдельного
   блока "Операционные расходы" ниже по странице — тот же .stock-split-row
   визуальный язык, что и разбивка по менеджерам, просто в другом месте).
   Кнопка — тот же зелёный "reveal"-стиль, что и .reactivation-hero-reveal,
   но настоящий <button> (сброс браузерных стилей), не <div>. */
.expenses-toggle-btn {
  display: block;
  margin-top: 8px;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--green-dark);
  cursor: pointer;
}
.expenses-toggle-btn:active { opacity: 0.7; }
.sales-month-expenses { margin-top: 4px; }
.sales-month-expenses-excluded-title { font-size: 11.5px; color: var(--gray); margin-top: 8px; margin-bottom: 2px; }
.sales-month-expenses-excluded { opacity: 0.7; }
.sales-month-expenses-excluded span { font-size: 12.5px; }
/* Валовая прибыль менеджера — вторая, менее заметная строка сразу под его
   выручкой (не отдельная колонка/таблица — тесно на мобильном). */
.sales-manager-margin-row { padding-top: 0; font-size: 12px; opacity: 0.75; }
.stock-split-row span { color: var(--gray); }
/* nowrap у суммы — по наблюдению на телефоне (2026-09-12, карточка
   "Приближающиеся сроки"): у строки с длинной подписью ("Реально можно
   выручить (по сниженной цене)") на вторую строку переносился один знак
   "₽", отрываясь от своего числа. Переносить должна подпись слева, число
   — никогда. */
.stock-split-row b { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Десктоп — шире контейнер, крупнее шаг сетки и герой-цифра, чтобы не
   гулять пустым местом по краям и не тянуть тонкие карточки в редкую
   решётку на широком экране. */
@media (min-width: 860px) {
  /* Без max-width — та же правка, что и у шапки выше: аналитика теперь
     занимает всю доступную ширину, как и карточки товаров, а не сжата в
     узкую колонку с пустыми полями по бокам. auto-fit в сетках ниже сам
     добавляет колонки на свободном месте, а не растягивает то же число
     карточек шире. */
  .analytics-section { padding: 0 28px; }
  .abc-grid { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; }
  .stock-hero { font-size: 38px; }
  /* Заголовок раздела — по прямому репорту пользователя (2026-08-19,
     "приплюснут к шапке, маленький на десктопе") — заметно крупнее и с
     нормальным зазором сверху на широком экране; на телефоне не трогаем,
     там уже было хорошо. */
  .analytics-section h2 { font-size: 24px; margin: 0 0 14px; }
  .warehouse-subtitle { font-size: 16px; margin: 30px 0 10px; }
}

/* border-collapse: separate + border-spacing (не collapse) — по прямому
   запросу пользователя (2026-08-18, "скругления не консистентны"):
   border-radius на <td> в collapse-таблице визуально ничего не даёт,
   соседние цветные ячейки просто стыкуются углами — с separate между ними
   появляется зазор, и скругление каждой ячейки читается как отдельный
   "чип", тем же радиусом (--r-sm), что и остальные некрупные элементы. */
.heat-table { width: 100%; border-collapse: separate; border-spacing: 3px; margin: -3px 0 4px -3px; font-size: 12.5px; min-width: 480px; }
.heat-table th { font-weight: 500; color: var(--gray); padding: 5px 6px; text-align: center; }
.heat-table th:first-child { text-align: left; }
.heat-table td { padding: 8px 6px; text-align: center; border-radius: var(--r-sm); font-variant-numeric: tabular-nums; }
.heat-table td.heat-label { text-align: left; font-weight: 600; color: var(--gray); border-radius: 0; }
/* Кликабельная ячейка (см. site.js: scrollToAbcXyzCell) — button внутри td,
   растянутая на всю ячейку, без штатного вида кнопки: цвет/фон/выравнивание
   наследуются от td (сам фон-градиент интенсивности стоит на td, не тут). */
.heat-cell-btn {
  all: unset; display: block; width: 100%; cursor: pointer; color: inherit; text-align: inherit;
}
.heat-cell-btn:hover { opacity: 0.85; }
/* Строка D (убыточные товары, см. src/abc_xyz.py) — визуально отделена от
   A/B/C сверху, буква окрашена в --loss, а не нейтральный --gray. */
.heat-table tr.heat-row-loss td.heat-label { color: var(--loss); }
.heat-table tr.heat-row-loss td:first-child { border-top: 1px solid var(--border); }
.heat-table .heat-value { font-weight: 700; }
.heat-table .heat-pct { display: block; font-size: 11px; font-weight: 400; opacity: 0.75; }
.heat-table .heat-empty { color: var(--lgray); }
.heat-table .heat-turnover { display: flex; align-items: center; justify-content: center; gap: 4px; font-size: 10.5px; font-weight: 400; opacity: 0.85; margin-top: 3px; }
.heat-status-legend { display: inline-flex; align-items: center; gap: 4px; margin-left: 4px; }
.heat-status-dot { width: 7px; height: 7px; border-radius: 50%; display: inline-block; margin-left: 8px; }
.heat-status-legend .heat-status-dot:first-child { margin-left: 0; }
.heat-status-dot.over { background: var(--danger); }
.heat-status-dot.ok { background: var(--green); }
.heat-status-dot.under { background: var(--warning); }

/* Прогресс к целевым показателям (GMROI/оборачиваемость/доля неликвида vs
   бенчмарки, см. src/warehouse_analytics.py: TARGETS). Переработано
   2026-08-18 по прямому запросу пользователя ("на десктопе выглядит
   стрёмно") — раньше это были тонкие полоски на всю ширину: на телефоне
   ещё нормально, на широком экране превращались в разрежённые ниточки с
   текстом по краям и пустотой между ними. Теперь — те же самодостаточные
   карточки, что и .abc-card выше (единый визуальный язык), с полоской
   прогресса ВНУТРИ карточки, а не во всю ширину страницы. */
.target-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 14px; }
.target-card-top { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
.target-label { font-size: 13px; font-weight: 600; color: var(--gray); }
.target-value { font-size: 20px; font-variant-numeric: tabular-nums; font-weight: 800; }
.target-value.target-met { color: var(--green-dark); }
.target-value.target-missed { color: var(--danger); }
.target-bar-track { height: 6px; border-radius: var(--r-pill); background: var(--photobg); overflow: hidden; margin-bottom: 7px; }
.target-bar-fill { height: 100%; border-radius: var(--r-pill); }
.target-bar-fill.target-met { background: var(--green); }
.target-bar-fill.target-missed { background: var(--danger); }
.target-goal { font-size: 11.5px; color: var(--gray); }
/* Месяц, за который показан показатель — с 2026-09-12 карточки показывают
   не одно число по 12-месячному окну, а последний месяц (см.
   warehouse_analytics.target_scorecard). Приписка мелкая и приглушённая:
   это уточнение к названию показателя, а не второй заголовок. */
.target-period { font-size: 11px; font-weight: 500; color: var(--lgray); }

/* Помесячные столбики ВНУТРИ карточки показателя (2026-09-12, по прямому
   запросу пользователя: "данные по месяцам должны быть в самих карточках
   GMROI, оборачиваемость и доля неликвида... в виде таблицы это выводить не
   нужно"). Та же разметка .value-chart, что и у графика продаж по месяцам,
   только компактнее: карточка в .target-grid — колонка от 230px, а месяцев
   11-12, поэтому столбик 44px (в него влезает "08.2026" десятым кеглем) и
   трек ниже обычных 96px. Что не влезло — уходит в горизонтальную прокрутку
   самого .value-chart (overflow-x у него уже есть), а site.js открывает
   график на самых свежих месяцах. Прежняя помесячная ТАБЛИЦА
   (.warehouse-monthly-table) убрана тем же запросом. */
.target-chart { margin-top: 14px; }
.target-chart .value-chart-col { flex: 0 0 44px; min-width: 44px; }
.target-chart .value-chart-track { height: 64px; }
.target-chart .value-chart-value { font-size: 10px; }
.target-chart .value-chart-date { font-size: 10px; }
/* Цвет — по достижению цели В ТОМ месяце (а не по метрике, как в графике
   продаж): зелёный столбик = цель выполнена, красный = нет. */
.value-chart-value.target-met { color: var(--green-dark); }
.value-chart-value.target-missed { color: var(--danger); }
.value-chart-bar.target-met { background: var(--green); }
.value-chart-bar.target-missed { background: var(--danger); }

/* Второстепенная группа внутри карточки (просрочка под приближающимися
   сроками, 2026-09-12) — отделена линией и подписана мелким заголовком:
   главное в карточке остаётся одно, крупное число сверху. */
.card-subgroup { margin-top: 14px; padding-top: 10px; border-top: 1px solid var(--border); }
.card-subgroup-title { font-size: 11.5px; font-weight: 600; color: var(--lgray); margin-bottom: 2px; }

.purchase-table { width: 100%; border-collapse: collapse; font-size: 12.5px; min-width: 560px; }
/* Таблицы ВНУТРИ модалок (карточка товара/клиента — "кто купил в этом
   месяце", "в каких чеках был этот товар" и т.п.) — по прямому репорту
   пользователя (2026-08-27, скриншот с телефона): 560px принудительной
   ширины на компактную табличку в 4 узких колонки (Клиент/Дата/Кол-во/
   Цена) растягивало её далеко за пределы экрана телефона, колонки
   выглядели неестественно разреженными. Обычные страничные таблицы
   (Закуп/Проверить заказ/Клиенты) сохраняют 560px как было — там колонок
   больше и такая ширина оправдана. min-width:0 — не считаем это заново
   для каждой отдельной таблицы модалки, просто убираем принуждение,
   таблица сама сжимается под содержимое / растягивается на ширину модалки. */
.product-modal-scroll .purchase-table { min-width: 0; }
/* Заголовок таблицы прилипает к верху ЕЁ СОБСТВЕННОГО скролл-окна
   (.table-scroll, см. выше) при прокрутке — по прямому репорту
   пользователя (2026-08-19, скриншоты "Проверить заказ"/"Закуп" на
   телефоне): длинную таблицу листаешь вниз, подписи колонок ("Заказать/
   Остаток/Цена/Сумма/Причина") уезжают вверх и через пару экранов уже не
   помнишь, что за цифра в каком столбце — легко потеряться. top:0, не
   var(--header-h) — липнет теперь не к шапке САЙТА, а к верхней границе
   .table-scroll (см. комментарий там). background — обязателен для
   sticky-строки, иначе сквозь неё видно уезжающие вверх строки таблицы. */
.purchase-table th {
  text-align: left; color: var(--gray); font-weight: 500; padding: 4px 8px 4px 0;
  border-bottom: 1px solid var(--lgray);
  position: sticky; top: 0; background: var(--white); z-index: 2;
}
.purchase-table td { padding: 5px 8px 5px 0; border-bottom: 1px solid var(--lgray); }
.purchase-table td.num, .purchase-table th.num { text-align: right; }
/* Оговорки у "Падения выручки" (стокаут / год-к-году) — см.
   catalog.html:nelikvid-list-revenue-drop, по прямому запросу
   пользователя (2026-08-19, самокритика сервиса). */
.pd-notes { display: flex; flex-wrap: wrap; gap: 4px; }
.pd-note { font-size: 10.5px; font-weight: 600; border-radius: var(--r-pill); padding: 2px 7px; white-space: nowrap; }
.pd-note-stockout { background: var(--warning-bg); color: var(--warning); }
.pd-note-yoy { background: var(--bg-alt, #f2f2f4); color: var(--gray); }
/* Кликабельное название товара — по прямому запросу пользователя
   (2026-08-19, "сделай сами товары во всех таблицах кликабельными... при
   клике раскрывалась бы карточка"): открывает ту же карточку, что и клик
   по товару в обычной сетке (см. site.js — делегированный обработчик
   .product-link-cell). display:block + собственный padding — не просто
   подчёркнутый текст, а полноценная зона нажатия НА ВСЮ ширину и высоту
   ячейки, чтобы на телефоне палец наверняка попадал по нужной строке, а
   не по соседней (по прямому запросу пользователя, "сохрани зону нажатия
   на мобильной версии"). */
.product-link-cell, .client-link-cell {
  display: block; width: 100%; text-align: left; background: none; border: none;
  font: inherit; color: inherit; cursor: pointer; padding: 6px 4px; margin: -6px -4px;
  text-decoration: underline; text-decoration-color: var(--lgray); text-underline-offset: 2px;
}
.product-link-cell:hover, .product-link-cell:focus-visible,
.client-link-cell:hover, .client-link-cell:focus-visible { color: var(--green-dark); text-decoration-color: var(--green); }

/* Раздел «Клиенты» (2026-08-26) — минимум нового: RFM-таблица переиспользует
   .heat-table/.heat-cell-btn, панели — .analysis-panel/.purchase-table,
   карточки заказов — .order-card/.order-line (все уже есть выше в файле). */
/* Поиск/сортировка клиентов раньше стояли голыми браузерными контролами
   (тонкая системная рамка, никакого фокуса) — по прямому запросу
   пользователя (2026-08-26, "слишком тонкий поиск и фильтр"): тот же
   визуальный язык, что и у #search в шапке каталога (фон --photobg,
   крупный радиус --r-btn-lg, явный фокус зелёным) — сайт больше нигде не
   использует голый <select>, только .seg-toggle-row, но вариантов
   сортировки тут больше трёх (см. #clients-sort ниже) — крашеный select
   ближе по духу, чем ряд из 5-6 пилюль, которые не влезут в одну строку
   на телефоне. */
/* Поиск по товарам клиента + переключатель бейджей (2026-08-31) —
   переиспользуют .clients-search-row как есть (та же строка ввода), плюс
   .trend-toggle (готовый компактный чекбокс-пилюля, см. выше "Учесть
   тренд"). .client-badges-hidden скрывает бейджи ТОЛЬКО внутри карточки
   клиента (#client-modal) — .card-badges/.card-badges-left те же классы,
   что и у обычных карточек каталога позади модалки, скрывать их везде
   было бы регрессией. */
#client-modal.client-badges-hidden .client-product-card .card-badges,
#client-modal.client-badges-hidden .client-product-card .card-badges-left { display: none; }
.client-products-toolbar { align-items: center; }
.clients-search-row { display: flex; gap: 10px; margin: 10px 0 14px; flex-wrap: wrap; }
.clients-search-row input[type="search"],
.clients-search-row select {
  padding: 12px 16px;
  border: 1px solid var(--border);
  background: var(--photobg);
  border-radius: var(--r-btn-lg);
  font-size: 16px;
  font-family: inherit;
  color: var(--ink);
  outline: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.clients-search-row input[type="search"]:focus,
.clients-search-row select:focus { border-color: var(--green); background: var(--white); }
.clients-search-row input[type="search"] { flex: 1 1 220px; accent-color: var(--gray); }
.clients-search-row select { flex: 1 1 200px; }
.client-orders { display: flex; flex-direction: column; gap: 10px; }
.order-card-total { margin-top: 8px; font-weight: 600; font-size: 13.5px; text-align: right; }
.client-modal-panel .product-modal-body { padding-top: 8px; }
/* Карточка клиента и карточка товара МОГУТ открываться друг НАД другом в
   любом порядке (клиент из drill-down "кто купил в этом месяце" ПОВЕРХ
   товара, и наоборот — товар из карточки клиента ПОВЕРХ клиента). Оба
   модальных окна используют один класс .product-modal (тот же z-index) —
   раньше здесь было СТАТИЧЕСКОЕ #client-modal{z-index:+1}, чинившее только
   первый сценарий (репорт 2026-08-26), но по репорту 2026-08-29 оно же
   ломало второй (товар из карточки клиента открывался, но визуально ПОД
   клиентом). Теперь z-index поднимает ДИНАМИЧЕСКИ site.js в момент показа
   каждого модального окна — какое открылось последним, то и сверху (см.
   bringModalToFront в site.js). */
/* Крестик/стрелка "назад" (.icon-btn.product-modal-close) сидит поверх
   .product-modal-body — у обычной карточки товара над ним всегда есть
   .product-modal-photo, у карточки клиента фото нет, и заголовок (h2) с
   первого же пикселя оказывался под кнопкой (репорт пользователя,
   скриншот). Кнопка — круг 34px на отступе 12px от края (см. .icon-btn.
   product-modal-close выше) — с запасом до 54px. */
.client-modal-panel .product-modal-body { padding-top: 54px; }

/* Карточки товаров клиента — по прямому запросу пользователя (2026-08-26):
   "также, как и в каталоге, в виде картинок", с количеством/выручкой/
   маржой бейджами поверх фото. Переиспользует .card/.card-photo/.card-body/
   .card-name/.card-article (та же карточка, что и в обычной сетке
   каталога) — НЕ через renderCard() (тот заточен под живую карточку
   каталога — остаток/ABC-XYZ/срок годности, здесь неприменимо и было бы
   неверно показывать актуальные складские данные рядом с историческими
   продажами), см. site.js: renderClientProductCard. */
/* Выручка — серым (нейтральный факт) — по прямому репорту пользователя
   (2026-08-26): было наоборот. .card-badge-revenue переиспользует тот же
   тёмный полупрозрачный стиль, что и .card-badge-stock/-cost выше. */
.card-badge-revenue {
  background: rgba(20,20,20,0.72); color: var(--white);
  border: none; border-radius: var(--r-pill);
  font-size: 10px; font-weight: 600;
  padding: 3px 7px;
  box-shadow: 0 1px 4px rgba(20,20,20,0.2);
}
/* Маржа — 3 уровня по % (не по знаку), по прямому запросу пользователя
   (2026-08-26): >=20% — зелёный (.card-badge, цвет уже зелёный по
   умолчанию), 5-20% — жёлтый (.mid), <5% (включая убыток) — красный
   (.bad) — тот же смысл, что var(--warning)/var(--danger) используются
   везде на сайте для "средне"/"плохо". */
.card-badge.margin-badge.mid { background: var(--warning); }
.card-badge.margin-badge.bad { background: var(--danger); }
/* Карточка товара клиента подсвечивается, пока под ней открыта панель
   "в каких чеках был этот товар" (toggleProductOrdersPanel). Кольцо — на
   ::after поверх ВСЕГО содержимого карточки, не box-shadow/outline на
   самой .card: и inset box-shadow, и инсетный outline на карточке с
   overflow:hidden рисуются ПОД дочерними элементами (обычный порядок
   отрисовки CSS) — фото (.card-photo, непрозрачная картинка почти
   вплотную к краю) перекрывало кольцо сверху, а текстовая нижняя часть
   (.card-body, с отступами) — нет, отсюда "тоньше сверху, толще снизу"
   (повторный репорт пользователя 2026-08-26 — первая попытка через
   box-shadow не решила проблему по той же причине). ::after генерируется
   ПОСЛЕДНИМ и красится поверх всех братьев/детей независимо от их фона. */
.client-product-card.active { position: relative; }
.client-product-card.active::after {
  content: "";
  /* -1px, не 0 — absolute-потомок позиционируется от PADDING-края родителя
     (.card имеет border: 1px), inset:0 садился на 1px внутрь настоящей
     скруглённой кромки карточки, и с тем же border-radius давал заметно
     более тугую кривизну по углам, чем у самой карточки (повторный репорт
     пользователя 2026-08-26, "обводка в скруглениях не попадает ровно").
     -1px компенсирует эту разницу — внешний край ::after теперь совпадает
     с внешним краем border самой .card. */
  position: absolute; inset: -1px;
  border-radius: inherit;
  box-shadow: inset 0 0 0 2px var(--green-border);
  pointer-events: none;
}
.product-orders-panel { grid-column: 1 / -1; }
.product-orders-panel h4 { font-size: 14px; font-weight: 700; margin: 4px 0 10px; }

/* KPI-карточки "Заказов всего"/"Последний заказ"/"Задолженность" в обзоре
   клиента кликабельны (скролл к заказам/раскрытие долга по чекам) — по
   прямому запросу пользователя (2026-08-26). Тень на :hover "залипала" на
   сенсорных экранах (мобильный Safari применяет :hover по тапу и не всегда
   снимает его — повторный репорт пользователя, "тень не пропадает после
   снятия выделения"): :hover теперь только для устройств с реальным
   курсором (@media hover:hover — мышь, десктоп), а :active даёт тот же
   эффект именно ПОКА палец касается карточки и гаснет сразу по отпусканию
   — на тач-экранах это и есть "нравится свечение, но чтобы пропадала". */
.abc-card.clickable { cursor: pointer; transition: box-shadow .15s; }
@media (hover: hover) {
  .abc-card.clickable:hover { box-shadow: 0 2px 10px rgba(20,20,20,0.12); }
}
.abc-card.clickable:active { box-shadow: 0 2px 10px rgba(20,20,20,0.12); }
/* ABC-бейджи клиента + подсказка-оговорка — намеренно нейтрально-серые,
   не цветные .pm-mgmt-badge/classifyLevel: пользователь прямо спросил,
   почему ABC="A" по марже при 13% (2026-08-26) — ABC тут про СУММУ вклада
   в прибыль компании, не про качество этого конкретного клиента, цветные
   пилюли вводили в заблуждение, что это тот же "хорошо/плохо" сигнал, что
   и % маржи (тот теперь и есть единственный цветной сигнал, см. .stock-big-
   secondary.gmroi-*). */
.client-abc-badge { font-size: 12px; color: var(--gray); background: var(--bg-alt, #f2f2f4); border-radius: var(--r-control, 12px); padding: 4px 10px; cursor: help; }
.client-abc-badge b { color: var(--ink, #1a1a1a); font-weight: 600; }
.client-abc-hint { margin-top: 2px; }
.client-debt-detail-panel { grid-column: 1 / -1; margin-top: -4px; }
/* Клик по "Последний заказ" временно подсвечивает нужную .order-card —
   зелёный акцент, гаснет через 1.5с. */
@keyframes order-card-flash-anim { from { box-shadow: 0 0 0 3px var(--green); } to { box-shadow: 0 1px 4px rgba(20,20,20,0.08); } }
.order-card-flash { animation: order-card-flash-anim 1.5s ease-out; }

/* Заказ клиента как строки корзины (миниатюра + название + кол-во×цена) —
   по прямому запросу пользователя (2026-08-26: "так же, как показывается
   корзина клиента"), переиспользует .zakup-row-photo/.zakup-row-thumb
   (уже есть выше) для миниатюры+названия, добавляет только правую часть
   строки (количество/цена) и итоговую строку с валовой прибылью заказа. */
.order-item-row { display: flex; align-items: center; gap: 8px; padding: 5px 0; }
.order-item-row .zakup-row-photo { flex: 1 1 auto; min-width: 0; }
.order-item-right { flex: 0 0 auto; text-align: right; font-size: 12px; color: var(--gray); white-space: nowrap; padding-left: 6px; }
.order-item-right b { display: block; color: var(--ink); font-size: 13px; font-weight: 600; }
.order-card-margin { font-size: 12.5px; color: var(--green-dark); text-align: right; margin-top: 2px; font-weight: 600; }
.order-card-margin.mid { color: var(--warning); }
.order-card-margin.bad { color: var(--danger); }

/* ---------- Реактивация клиентов (2026-08-26) ---------- */
/* Баннер "рыночный/сезонный эффект" — тонированный фон (var(--warning-bg),
   тот же, что и у .device-card.unlabeled), БЕЗ цветной полосы слева — по
   прямому запросу пользователя в этой же сессии убрать левый акцент у
   .analysis-panel, тот же принцип держим и здесь: не возвращаем его нигде
   в новых панелях. Это честное предупреждение, не тревога — не тот же
   красный, что у задолженности/убытка. */
.reactivation-banner {
  background: var(--warning-bg);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: 12px 16px;
  font-size: 13.5px;
  line-height: 1.5;
  margin: 10px 0 16px;
}
/* Карточки-счётчики "Замолчали"/"Просели" — теперь сами кнопки-раскрывашки
   (см. .reactivation-hero-toggle в catalog.html), не просто div — по
   прямому запросу пользователя (2026-08-26, скриншот: список сразу
   разворачивался огромной стеной карточек, лучше кнопка "Раскрыть").
   Сброс браузерных стилей <button> поверх уже готового .abc-card.abc-hero
   (та же рамка/тень/паддинг, что и раньше, просто теперь кликабельно). */
button.reactivation-hero-toggle {
  width: 100%; text-align: left; cursor: pointer; font-family: inherit;
  display: block; color: inherit; appearance: none;
}
/* Числа счётчиков — обычный чёрный (--ink), не зелёный/красный: по
   прямому вопросу пользователя (2026-08-26, "стоит ли сделать зелёными
   или чёрными?") — цвет на этом сайте зарезервирован за ОЦЕНКОЙ качества
   числа (маржа хорошая/плохая, gmroi-good/-bad), а не просто фактом-
   счётчиком — те же "Всего клиентов"/"Заказов всего" тоже чёрные. Синий
   до этой правки был не осознанным выбором, а браузерным дефолтом цвета
   текста внутри <button> (iOS Safari подкрашивает необработанный <button>
   системным синим) — button.reactivation-hero-toggle{color:inherit} выше
   это чинит; это правило — просто явная подстраховка. */
button.reactivation-hero-toggle .stock-big { color: var(--ink); }
.reactivation-hero-reveal { margin-top: 8px; font-size: 12.5px; color: var(--green-dark); font-weight: 600; }
/* Карточка "Замолчали"/"Просели" + её раскрывающийся список — одна
   вертикальная группа (см. _clients_section.html), явный отступ между
   двумя такими группами, не полагаемся на схлопывание margin-ов через
   обёртку. */
.reactivation-hero-block + .reactivation-hero-block { margin-top: 14px; }
.reactivation-panel { margin-bottom: 14px; }
/* "Скрыть журнал"/таблица журнала контактов — по прямому репорту
   пользователя (2026-08-26, скриншот: "кнопка прилипла к таблице"):
   .nelikvid-reveal-btn обычно сидит ВНУТРИ .abc-card (там разделение даёт
   паддинг самой карточки, margin-top:auto просто прижимает кнопку к её
   низу) — здесь кнопка стоит одна, в потоке страницы, без карточки
   вокруг, так что нужен явный отступ снизу. */
#contact-log-reveal { margin-bottom: 12px; }
.contact-log-delete-btn { font-size: 12px; padding: 5px 10px; white-space: nowrap; }
.reactivation-list { display: flex; flex-direction: column; gap: 10px; margin-top: 12px; }
/* Карточка строки — тот же визуальный язык, что и .abc-card/.order-card
   (граница+тень+скругление) — раньше не хватало тени, из-за чего на
   светлом фоне граница читалась слабо/"вёрстка как будто сломана"
   (репорт пользователя 2026-08-26). */
.reactivation-row { background: var(--white); border-radius: var(--r-card); padding: 14px 16px; border: 1px solid var(--border); box-shadow: 0 1px 2px rgba(20, 20, 20, 0.05); }
.reactivation-row-header { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; }
.reactivation-row-header .client-link-cell { font-weight: 600; font-size: 14.5px; }
.reactivation-risk { font-weight: 700; font-size: 14.5px; color: var(--ink); white-space: nowrap; font-variant-numeric: tabular-nums; }
.reactivation-row-reason { font-size: 12.5px; color: var(--gray); margin-top: 4px; }
.reactivation-row-products { font-size: 12.5px; color: var(--gray); margin-top: 2px; }
/* Повторное появление после несостоявшегося контакта — то же тонирование,
   что и у баннера, но без своей рамки (внутри карточки строки уже есть
   рамка) — по прямому запросу пользователя: "чтобы менеджер не начинал
   разговор с нуля". */
.reactivation-row-prev { background: var(--warning-bg); border-radius: var(--r-sm); padding: 6px 8px; font-size: 12px; color: var(--ink); margin-top: 8px; }
.reactivation-row-actions { margin-top: 10px; }
.reactivation-contact-btn { font-size: 13px; padding: 7px 12px; }
.reactivation-contact-form { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.reactivation-contact-form textarea {
  width: 100%; min-height: 54px; padding: 8px 10px; border: 1px solid var(--border);
  border-radius: var(--r-sm); font-family: inherit; font-size: 16px; resize: vertical;
}
.reactivation-contact-form label { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--gray); }
/* Менеджер — предзаполненное, но редактируемое поле (по прямому запросу
   пользователя, 2026-08-26: "не факт, что обзвоном занимается именно этот
   менеджер... нужно, чтобы данные можно было изменить на другое имя,
   вписанное вручную") — обычный текстовый инпут, не select/чтение. */
.reactivation-manager-label { flex-wrap: wrap; }
.reactivation-contact-manager {
  flex: 1 1 120px; min-width: 100px; padding: 6px 8px; border: 1px solid var(--border);
  border-radius: var(--r-sm); font-family: inherit; font-size: 16px; color: var(--ink);
}
.reactivation-contact-form .reactivation-form-buttons { display: flex; gap: 8px; }

/* Миниатюра фото слева от названия в таблицах "Закуп"/"Проверить заказ" —
   по прямому запросу пользователя (2026-08-20, "как у нас было
   реализованно в корзине"), см. site.js: productPhotoLinkCell. Тот же
   .product-link-cell (display:block по умолчанию) переключается на flex,
   только когда есть фото — text-decoration остаётся только на названии,
   не на всей строке. */
.product-link-cell.zakup-row-photo { display: flex; align-items: center; gap: 8px; text-decoration: none; }
.zakup-row-photo .zakup-row-name { text-decoration: underline; text-decoration-color: var(--lgray); text-underline-offset: 2px; }
.zakup-row-photo:hover .zakup-row-name, .zakup-row-photo:focus-visible .zakup-row-name { text-decoration-color: var(--green); }
.zakup-row-thumb {
  flex: 0 0 auto; width: 32px; height: 32px; border-radius: var(--r-sm); overflow: hidden;
  background: var(--photobg); display: flex; align-items: center; justify-content: center;
  font-size: 14px; color: var(--lgray);
}
.zakup-row-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
div.zakup-row-photo { display: flex; align-items: center; gap: 8px; }
details.analytics-more summary { cursor: pointer; color: var(--green); font-size: 13px; padding: 6px 0; }

.supplier-block { border: 1px solid var(--border); border-radius: var(--r-card); margin-bottom: 12px; overflow: hidden; background: var(--white); box-shadow: 0 1px 2px rgba(20, 20, 20, 0.05); }
.supplier-summary { list-style: none; cursor: pointer; padding: 14px 16px; display: flex; justify-content: space-between; align-items: baseline; gap: 12px; font-weight: 600; }
.supplier-summary::-webkit-details-marker { display: none; }
.supplier-summary .supplier-sum { font-weight: 400; color: var(--gray); font-size: 13px; }
.supplier-body { padding: 0 16px 16px; }
.copy-tab-btn, .zakup-copy-btn { margin-top: 10px; }
.copy-tab-status { font-size: 12px; color: var(--green); margin-left: 8px; visibility: hidden; }

/* ---------- блок "Закуп" — поиск вместо 4 вкладок (2026-08-19) ---------- */
/* По прямому запросу пользователя: одно поле поиска вместо 4 отдельных
   вкладок-группировок, подсказки приходят с /api/zakup-search по мере
   ввода, разделены на 3 категории (см. management/static/site.js). */
.zakup-search-wrap { position: relative; margin-bottom: 12px; }
.zakup-search-input {
  width: 100%; padding: 13px 14px; border: 1px solid var(--border);
  /* var(--r-btn-lg), не --r-control — по прямому репорту пользователя
     (2026-08-29): скругление этого поля и текстового поля проверки заказа
     ниже (.zakup-check-input) не совпадало с #search в шапке и с кнопкой
     "Проверить" (.btn, уже на --r-btn-lg) — та же правка, что уже
     сделана раньше для #search и .clients-search-row. */
  border-radius: var(--r-btn-lg); background: var(--photobg);
  font-family: inherit; font-size: 16px; color: var(--ink); outline: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.zakup-search-input:focus { border-color: var(--green); background: var(--white); }
/* Подсказки — плавающая панель под полем, не толкает остальной контент
   вниз (position:absolute), с собственной тенью/скруглением как у карточек. */
.zakup-suggestions {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: 5;
  background: var(--white); border: 1px solid var(--border); border-radius: var(--r-card);
  box-shadow: 0 6px 20px rgba(20, 20, 20, 0.12); max-height: 360px; overflow-y: auto;
  padding: 6px 0;
}
.zakup-suggestion-group + .zakup-suggestion-group { border-top: 1px solid var(--photobg); margin-top: 4px; padding-top: 4px; }
.zakup-suggestion-heading {
  font-size: 10.5px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase;
  color: var(--lgray); padding: 6px 14px 4px;
}
.zakup-suggestion-item {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  width: 100%; padding: 9px 14px; border: none; background: none; text-align: left;
  font-family: inherit; font-size: 13.5px; color: var(--ink); cursor: pointer;
}
.zakup-suggestion-item:hover, .zakup-suggestion-item:focus-visible { background: var(--photobg); }
.zakup-suggestion-meta { font-size: 11.5px; color: var(--gray); white-space: nowrap; flex-shrink: 0; }
.zakup-selected { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.zakup-selected-label { font-size: 16px; font-weight: 600; color: var(--gray); }
.zakup-result { margin-top: 4px; }
.zakup-result-total { font-size: 13px; color: var(--gray); margin: 10px 0; font-variant-numeric: tabular-nums; }
/* Ближе к поиску над ним — по прямому репорту пользователя (2026-08-19):
   "блок Проверить заказ к поиску должен быть гораздо ближе" — это
   продолжение того же раздела "Закуп" (альтернативный сценарий: не искать
   и собирать, а сразу вставить готовый заказ), не отдельная тема, поэтому
   зазор здесь минимальный, в отличие от зазоров МЕЖДУ разделами ниже.

   Короткая центрированная черта (::before) не понравилась — по прямому
   репорту пользователя (2026-08-19, повторно) вернул обычный полноширинный
   border-top, просто выровнял отступы симметрично вокруг неё: сверху —
   margin-bottom у .zakup-search-wrap (12px) + margin-top здесь (4px) =
   16px; снизу — padding-top здесь (16px), а свой немаленький margin-top у
   .warehouse-subtitle (22px/30px на десктопе, см. ниже) для ЭТОГО
   конкретного заголовка обнулён (см. .zakup-checker .warehouse-subtitle) —
   иначе он суммировался бы с padding-top, и черта опять оказалась бы не
   по центру зазора, а ближе к верху (что и было до этой правки). */
.zakup-checker { margin-top: 4px; padding-top: 16px; border-top: 1px solid var(--photobg); }
.zakup-checker .warehouse-subtitle { margin-top: 0; }
.zakup-check-input {
  width: 100%; min-height: 140px; padding: 12px 14px; margin-bottom: 10px;
  /* var(--r-btn-lg) — см. комментарий у .zakup-search-input выше, та же
     причина/тот же фикс. */
  border: 1px solid var(--border); border-radius: var(--r-btn-lg);
  background: var(--photobg); font-family: inherit; font-size: 16px;
  color: var(--ink); resize: vertical; outline: none;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.zakup-check-input:focus { border-color: var(--green); background: var(--white); }
.zakup-check-result { margin-top: 16px; }
/* Отступ от списка сверки до кнопки копирования — по прямому репорту
   пользователя (2026-08-19, "кнопку скопировать нужно отлепить от самого
   списка, дать консистентный отступ"): раньше таблица и кнопка шли впритык
   без зазора (.table-scroll не имел своего margin-bottom). Тот же зазор,
   что и у .copy-tab-btn/.zakup-copy-btn выше — консистентно с остальными
   кнопками копирования в этом разделе. */
#zakup-check-copy-btn { margin-top: 10px; }
/* Строка результата — подсвечена, только если рекомендация РАСХОДИТСЯ с
   присланным количеством (см. site.js: renderZakupCheckResult) — совпавшие
   строки не должны отвлекать внимание, расхождения должны бросаться в глаза
   сразу, без чтения каждой строки подряд. */
.zakup-check-row-diff td { background: var(--warning-bg); }
.zakup-check-row-missing td { color: var(--lgray); }
.zakup-check-reason { font-size: 12px; color: var(--gray); }

/* ---------- "Неликвиды" — редизайн (2026-08-19) ---------- */
/* Список скрыт за кнопкой по умолчанию (см. site.js) — по прямому запросу
   пользователя: "не нужно выводить эти некрасивые списки, должна быть
   лаконичная кнопка". .abc-card/.abc-grid переиспользованы как есть —
   тот же визуальный язык, что и у карточек "Аналитики склада" рядом. */
/* margin-top:auto внутри flex-колонки .abc-card — прижимает кнопку к
   низу карточки независимо от длины текста над ней (оба соседних
   .abc-card в .abc-grid растянуты на одну высоту, см. комментарий там);
   align-self — иначе кнопка растянулась бы на всю ширину карточки
   (align-items:stretch по умолчанию для flex-колонки). */
.nelikvid-reveal-btn { margin-top: auto; align-self: flex-start; }
/* Гарантированный минимум пространства между текстом и кнопкой — по
   прямому репорту пользователя (2026-08-19, "сделай отступ кнопки от
   текста больше"): margin-top:auto на самой кнопке сам по себе не
   гарантирует МИНИМУМ (если бы текст почти заполнял карточку, отступ мог
   бы стать совсем маленьким) — здесь фиксированный запас снизу под
   текстом, auto на кнопке просто добавляет к нему остаток до низа карточки. */
.nelikvid-count-sub { margin-bottom: 16px; }
.nelikvid-list { margin-top: 20px; }
/* Карточка тренда неликвида стоит ОТДЕЛЬНО от .abc-grid ниже (сама не
   часть сетки — на всю ширину, не в клетке) и не наследует её gap — по
   прямому репорту пользователя (2026-08-19, "нужно отлипить блоки друг от
   друга"), без этого карточки визуально сливались в одну. */
.nelikvid-summary-card { margin-bottom: 14px; }

/* Динамика стоимости остатка (data/warehouse_value_history.json) — по
   прямому запросу пользователя (2026-08-18, разбивка) и (2026-08-19,
   передел): раньше был столбик на КАЖДЫЙ день — на глубину истории
   получалось нечитаемо тесно. Теперь последние 4 недели сведены в 4
   недельные точки, всё старше — уже помесячно (см. management/app.py:
   _bucket_value_history) — сильно меньше столбиков, каждый шире и
   разборчивее. Стек снизу вверх: ликвидная часть, поверх неё —
   неликвидная, обе высоты уже посчитаны в management/app.py относительно
   максимума окна. */
.trend-up { color: var(--green-dark); font-weight: 600; }
.trend-down { color: var(--danger); font-weight: 600; }
/* Подпись суммы над столбиком + дата под ним — по прямому запросу
   пользователя (2026-08-18): видно сразу, без наведения курсора (на
   телефоне его и нет). Колонка фиксированной ширины + скролл вбок, та же
   логика, что и у .pm-demand-chart. Ширина/зазор увеличены (2026-08-19) —
   столбиков стало меньше после сведения по неделям/месяцам, есть куда
   расти каждому в ширину. */
.value-chart { display: flex; align-items: flex-end; gap: 6px; margin-top: 16px; overflow-x: auto; padding-bottom: 4px; }
/* Столбики растягиваются на всю ширину блока — по прямому репорту
   пользователя (2026-08-19, "эти столбики нужно расширить на всю часть
   блока"): раньше была фиксированная узкая ширина (36px) — на широком
   экране справа оставалось много пустого места. flex:1 делит доступную
   ширину поровну между всеми колонками — но только на десктопе (media
   ниже): на телефоне тот же приём на ~10 колонках сжимал каждую до ~26px,
   подписи ("39.6M") сливались в нечитаемую кашу (по прямому репорту
   пользователя 2026-08-19, скриншот). На мобильном — снова фиксированная
   ширина, достаточная для подписи, а лишние колонки уезжают за край
   (overflow-x на .value-chart выше уже даёт скролл вбок, тем и
   пользуемся, как и попросили: "можно просто скролл вправо добавить"). */
.value-chart-col { flex: 0 0 52px; min-width: 52px; display: flex; flex-direction: column; align-items: center; gap: 5px; }
@media (min-width: 900px) {
  .value-chart-col { flex: 1 1 0; min-width: 26px; }
  /* График "По месяцам" (2026-08-25, после слияния со старой базой —
     ~25 столбиков) — колонка НЕ растягивается даже на десктопе, остаётся
     той же ширины, что и на мобильном (52px), иначе 3 строки цифр
     (выручка/маржа/прибыль) не помещаются в узкую растянутую колонку и
     наезжают друг на друга (репорт пользователя, скриншот десктопа).
     Переполнение уходит в горизонтальный скролл — .value-chart уже умеет
     это (overflow-x), просто раньше десктопу было незачем скроллить, все
     столбики влезали растянутыми. */
  .value-chart-fixed-width .value-chart-col { flex: 0 0 52px; min-width: 52px; max-width: 52px; }
}
/* Общая сумма за период НАД столбиком — по прямому повторному запросу
   пользователя (2026-08-19), возвращена поверх подписей внутри сегментов
   (не замена им — те показывают ликвид/неликвид, эта показывает сумму
   периода целиком, тем же приёмом, что и раньше). */
.value-chart-value { font-size: 11.5px; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Тот же перенос вместо nowrap, что и у .value-chart-value-stack ниже — и
   для одиночной (не тройной) цифры графика "По дням", раз колонка теперь
   тоже фиксированной 52px-ширины (.value-chart-fixed-width, см. выше). */
.value-chart-fixed-width .value-chart-value { white-space: normal; overflow-wrap: break-word; max-width: 100%; }
/* Стопка из 3 цифр (выручка/маржа/чистая прибыль) над столбиком графика
   "по месяцам" — по прямому запросу пользователя (2026-08-25): зелёный
   сегмент столбика обычно слишком тонкий для подписи внутри, поэтому все
   3 цифры теперь здесь, каждая покрашена в цвет СВОЕЙ метрики (не
   сегмента, который она отмечает). Шрифт чуть мельче обычного
   .value-chart-value — тут теперь до 3 строк, а не одна. */
.value-chart-value-stack { display: flex; flex-direction: column; align-items: center; gap: 1px; width: 100%; }
/* Самокритика от 2026-08-25 (по прямому репорту пользователя, скриншот:
   "толщина верхних столбиков" — то есть блока с цифрами — визуально шире
   узких столбиков диаграммы под ним): .value-chart-value наследует
   white-space:nowrap — при длинных числах ("25.4М" и т.п.) это позволяло
   тексту (а с ним и родительской .value-chart-col, у которой flex-basis
   52px не является жёсткой границей без min-width:0) раздуваться шире
   узкой 52px-колонки, хотя сам цветной столбик снизу остаётся честные
   52px. Перенос вместо nowrap + min-width:0 — держит цифры строго в
   границах колонки, тем же 52px. */
.value-chart-value-stack .value-chart-value { font-size: 10px; white-space: normal; overflow-wrap: break-word; line-height: 1.15; min-width: 0; max-width: 100%; }
/* Процент от выручки под суммой маржи/чистой прибыли (2026-09-12) — своя
   строка внутри той же цветной цифры (цвет наследуется), помельче и чуть
   прозрачнее: это уточнение к сумме, а не четвёртая метрика. */
.value-chart-pct { display: block; font-size: 9px; font-weight: 600; opacity: 0.75; }
.value-chart-value.metric-revenue { color: var(--danger); }
.value-chart-value.metric-margin { color: var(--warning); }
.value-chart-value.metric-net { color: var(--green-dark); }
/* Трек без своей рамки/фона — по прямому репорту пользователя (2026-08-19,
   "не нужен этот максимум окна, окно должно быть той же высоты что и
   штриховка"): предыдущая правка добавила рамку+фон на весь трек, отчего
   даже короткие столбики читались как "коробка" на всю высоту колонки —
   откачено. Видна должна быть ТОЛЬКО сама заполненная область (сам
   столбик), высота колонки — просто невидимый ориентир масштаба, не
   отдельный визуальный элемент. */
.value-chart-track {
  width: 100%; height: 96px; display: flex; flex-direction: column-reverse;
}
/* День недели НАД датой, не в одну строку — по прямому запросу пользователя
   (2026-08-25): "дни недели идут перед датой", тот же шрифт, что и у самой
   даты (никакой разницы в размере/насыщенности — тоже прямой запрос,
   первая версия со .value-chart-weekday помельче/посветлее была
   отклонена). Отдельная строка вместо "Пн 01.08" в одну — на десктопе
   (много узких колонок, flex:1 делит место поровну, см. .value-chart-col
   ниже) сама строка не помещалась и white-space:nowrap выталкивал текст
   за пределы колонки (репорт пользователя, скриншот). */
.value-chart-date { display: flex; flex-direction: column; align-items: center; font-size: 11px; color: var(--gray); font-weight: 500; white-space: nowrap; }

/* ===================== CRM (план crm-tidy-sparrow.md, 2026-09-13) =====================
   Страница /crm — та же главная, body.crm-page прячет остальные разделы и
   поиск по товарам: карточка клиента при этом остаётся той же (site.js). */
.header-links { display: flex; gap: 14px; flex-wrap: wrap; align-items: baseline; }
.crm-nav-link { font-weight: 700; }
body.crm-page .analytics-section:not(.crm-section),
body.crm-page:not(.crm-catalog-on) .searchbar,
body.crm-page:not(.crm-catalog-on) .categories-wrap,
body.crm-page:not(.crm-catalog-on) #catalog,
body.crm-page #empty-state { display: none !important; }
/* «Товары → Каталог» (v3, 25.09): каталог Аналитики под разделом CRM, свой
   поиск по товарам — в шапке, общий поиск CRM на это время прячем. */
body.crm-catalog-on .crm-search-trigger { display: none !important; }
/* Высоту шапки с поиском и разделами меряет site.js (на <html>). */
body.crm-page.crm-catalog-on { --header-h: inherit; }
/* На компьютере панель разделов «липкая» ВНУТРИ блока CRM, а каталог лежит
   ниже блока — при прокрутке она уезжала вместе с ним (репорт 25.09). На время
   «Каталога» она парит снизу, как на телефоне. */
@media (min-width: 701px) {
  body.crm-catalog-on .crm-tabbar {
    position: fixed; top: auto; bottom: 16px; z-index: 30; margin: 0;
    left: max(16px, calc(50% - 550px)); right: max(16px, calc(50% - 550px));
    background: rgba(255, 255, 255, 0.82);
    box-shadow: 0 10px 34px rgba(20, 20, 20, 0.16), 0 0 0 0.5px rgba(20, 20, 20, 0.06);
  }
}
/* Каталог — на всю ширину с полями 14px, блок CRM (заголовок «Каталог») —
   в той же сетке, а не по центру 1100px (репорт 26.09). */
body.crm-catalog-on .crm-section { padding-bottom: 0; margin-bottom: 0; max-width: none; padding-left: 14px; padding-right: 14px; }
body.crm-catalog-on #catalog { margin-top: 0; padding-bottom: 120px; }
body.crm-page { --header-h: 76px; }

.crm-section { max-width: 1100px; padding-top: 12px; }
/* Длинные ссылки и слова без пробелов (catalog.lideropt.store/...?category=%D0…)
   в превью и переписке растягивали страницу на телефоне до 817px (2026-09-14). */
.crm-section, #client-modal-crm { overflow-wrap: anywhere; }
.crm-card > *, .crm-preview, .crm-preview-line, .crm-block, .crm-card-left, .crm-card-right { min-width: 0; max-width: 100%; }
body.crm-page { overflow-x: hidden; }

/* --- Меню CRM (2026-09-20): разделы по роли, «Ещё», поиск одним полем.
   Цвета — фирменные зелёные (--green/--logo-green), как на сайте и в
   Кабинете. --- */

/* Таб-бар: иконка + подпись, цель нажатия не меньше 44px, счётчик — кружком
   на углу иконки, как в системных приложениях. На телефоне — закреплён
   снизу с учётом safe-area, полупрозрачный с размытием. */
.crm-tabbar {
  display: flex; gap: 2px; margin: 0 0 14px; padding: 5px;
  background: rgba(242, 242, 244, 0.82); border-radius: var(--r-pill);
  -webkit-backdrop-filter: saturate(180%) blur(18px); backdrop-filter: saturate(180%) blur(18px);
  position: sticky; top: 8px; z-index: 5;
}
.crm-tabbar-btn {
  flex: 1 1 0; min-width: 0; min-height: 44px; border: 0; background: transparent; cursor: pointer;
  font-family: inherit; color: var(--gray); border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center; gap: 8px; padding: 8px 6px;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.22s cubic-bezier(0.32, 0.72, 0, 1), color 0.18s, transform 0.14s;
}
.crm-tab-ico { transition: transform 0.24s cubic-bezier(0.34, 1.56, 0.64, 1); }
.crm-tabbar-btn .crm-tab-label { font-size: 13px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-tabbar-btn:active { transform: scale(0.96); }
.crm-tabbar-btn.active { background: var(--white); color: var(--green-dark); box-shadow: 0 1px 3px rgba(20, 20, 20, 0.08); }
.crm-tab-ico-wrap { position: relative; display: inline-flex; flex: none; }
.crm-tab-ico { display: block; }
.crm-tabbar .crm-tab-count, .crm-more-item .crm-tab-count {
  position: absolute; top: -6px; left: 14px; min-width: 17px; height: 17px; box-sizing: border-box;
  padding: 0 5px; border-radius: 999px; background: var(--danger); color: var(--white);
  font-size: 10.5px; font-weight: 700; line-height: 17px; text-align: center;
  border: 2px solid var(--photobg); pointer-events: none;
  /* Без nowrap ширина абсолютного бейджа считается по остатку иконки (11px),
     и «223» обрезалось до «2» (поймано на проде 2026-09-20). */
  white-space: nowrap;
}
.crm-tabbar-btn.active .crm-tab-count { border-color: var(--white); }
.crm-tabbar .crm-tab-count:empty, .crm-more-item .crm-tab-count:empty { display: none; }
.crm-tabbar .crm-tab-count-alert { background: var(--danger); }

/* Заголовок раздела — крупно, чтобы всегда было видно, где ты. */
.crm-page-title { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; margin: 2px 0 10px; }
/* Переход между разделами: содержимое всплывает, а не прыгает. */
@keyframes crmPanelIn {
  from { opacity: 0; transform: translateY(8px) scale(0.995); }
  to { opacity: 1; transform: none; }
}
/* backwards, а НЕ both: с both после анимации на разделе оставался
   transform (единичная матрица), и всё position: fixed внутри раздела
   (кнопка «Опубликовать» в «Промо», панели итога) держалось не за экран, а
   за раздел — уезжало в самый низ длинной страницы (24.09, Саида). */
.crm-v2 .crm-panel:not([hidden]) { animation: crmPanelIn 0.26s cubic-bezier(0.32, 0.72, 0, 1) backwards; }
.crm-v2 .crm-page-title { animation: crmPanelIn 0.22s cubic-bezier(0.32, 0.72, 0, 1) both; }
@media (prefers-reduced-motion: reduce) {
  .crm-v2 .crm-panel:not([hidden]), .crm-v2 .crm-page-title, .crm-more-sheet, .crm-find-panel { animation: none; transition: none; }
}
/* Деньги в строке дела: сколько принесёт перезаказ или возврат клиента. */
.crm-money-chip { font-size: 12.5px; font-weight: 700; color: var(--green-dark); background: var(--green-bg); border-radius: var(--r-pill); padding: 2px 8px; white-space: nowrap; }
/* «Долги»: деньги на улице. */
.crm-debt-top { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-bottom: 12px; }
.crm-debt-card { background: var(--white); border: 1px solid var(--border); border-radius: var(--r-control); padding: 12px 14px; display: flex; flex-direction: column; gap: 4px; }
.crm-debt-card span { font-size: 12.5px; color: var(--gray); }
.crm-debt-card b { font-size: 22px; font-weight: 700; letter-spacing: -0.01em; }
.crm-debt-card-late b { color: var(--danger); }
.crm-debt-bar-row { display: flex; align-items: center; gap: 10px; padding: 5px 0; }
.crm-debt-bar-name { width: 68px; font-size: 13px; flex: none; }
.crm-debt-bar { flex: 1 1 auto; height: 14px; background: var(--photobg); border-radius: 4px; overflow: hidden; }
.crm-debt-bar i { display: block; height: 100%; background: var(--green-border); border-radius: 4px; }
.crm-debt-bar i b { display: block; height: 100%; background: var(--danger); border-radius: 4px; }
.crm-debt-bar-sum { width: 96px; text-align: right; font-size: 13px; font-weight: 600; flex: none; }
.crm-debt-sum { margin-left: auto; font-size: 15px; font-weight: 700; }
.crm-debt-hint { margin: -4px 0 10px; }
/* Матрица наличия. */
.crm-mx-abc { background: var(--photobg); color: var(--gray); font-weight: 700; letter-spacing: 0.04em; }
.crm-mx-alert { background: var(--green-bg); border: 1px solid var(--green-border); color: var(--green-dark); border-radius: var(--r-control); padding: 10px 12px; font-size: 13.5px; margin: 0 0 12px; }
.crm-mx-cat { width: 128px; font-size: 12.5px; flex: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-matrix-item .crm-item-title { font-weight: 600; }
.crm-link-strong { font-weight: 700; color: var(--green-dark); }

/* «Ещё» — лист снизу с ручкой, как системная шторка. */
.crm-sheet-backdrop { position: fixed; inset: 0; z-index: 39; background: rgba(20, 20, 20, 0.34); opacity: 0; transition: opacity 0.24s; }
.crm-sheet-backdrop.open { opacity: 1; }
.crm-more-sheet {
  position: fixed; z-index: 40; left: 0; right: 0; bottom: 0; background: var(--white);
  border-radius: 18px 18px 0 0; padding: 6px 8px calc(10px + env(safe-area-inset-bottom, 0px));
  box-shadow: 0 -10px 40px rgba(20, 20, 20, 0.18); display: flex; flex-direction: column;
  transform: translateY(102%); transition: transform 0.28s cubic-bezier(0.32, 0.72, 0, 1);
  max-height: 72vh; overflow-y: auto;
}
.crm-more-sheet.open { transform: none; }
.crm-sheet-grabber { width: 38px; height: 5px; border-radius: 3px; background: #d9d9de; margin: 6px auto 4px; flex: none; }
.crm-sheet-title { font-size: 17px; font-weight: 700; text-align: center; padding: 2px 0 10px; }
.crm-more-item {
  display: flex; align-items: center; gap: 12px; width: 100%; min-height: 52px; text-align: left;
  border: 0; background: transparent; font-family: inherit; font-size: 16px; color: var(--ink);
  padding: 8px 10px; border-radius: 12px; cursor: pointer; -webkit-tap-highlight-color: transparent;
}
.crm-more-item + .crm-more-item { box-shadow: inset 0 1px 0 var(--border); }
.crm-more-item:active { background: var(--photobg); }
.crm-more-item.active { color: var(--green-dark); }
.crm-more-ico { position: relative; display: inline-flex; color: var(--gray); flex: none; }
.crm-more-item.active .crm-more-ico { color: var(--green); }
.crm-more-label { flex: 1 1 auto; }
.crm-more-item .crm-tab-count { position: static; border: 0; background: var(--photobg); color: var(--gray); font-size: 12px; height: 20px; line-height: 20px; }
.crm-more-chev { color: var(--lgray); flex: none; }

/* Поиск одним полем: поле-кнопка в шапке (только в новом виде на /crm).
   Отступы и высота — как у поля поиска каталога (.searchbar), иначе оно
   липло к краям экрана и выглядело тонкой полоской. */
.crm-search-trigger { display: none; }
body.crm-page.crm-ui-v2 .crm-search-trigger {
  display: flex; align-items: center; gap: 10px; width: calc(100% - 40px); box-sizing: border-box;
  border: 0; background: var(--crm-field, #eceef1); border-radius: 16px;
  padding: 13px 16px; margin: 4px 20px 12px; color: var(--gray); font-family: inherit; font-size: 15px;
  cursor: pointer; text-align: left; -webkit-tap-highlight-color: transparent;
  transition: background 0.15s, box-shadow 0.15s;
}
body.crm-page.crm-ui-v2 .crm-search-trigger:hover,
body.crm-page.crm-ui-v2 .crm-search-trigger:focus-visible { background: #e4e7eb; box-shadow: 0 0 0 3px rgba(26, 162, 96, 0.12); }
body.crm-page.crm-ui-v2 .crm-search-trigger:active { transform: scale(0.995); }
.crm-search-trigger svg { color: var(--gray); flex: none; }
.crm-search-trigger span { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-search-trigger kbd {
  font-family: inherit; font-size: 12px; font-weight: 600; color: var(--lgray);
  background: rgba(255, 255, 255, 0.75); border-radius: 7px; padding: 3px 7px; flex: none;
}
.crm-ui-toggle { border: 0; background: transparent; font-family: inherit; cursor: pointer; padding: 0; }

.crm-sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.crm-find-overlay {
  position: fixed; inset: 0; z-index: 90; background: rgba(20, 20, 20, 0.42);
  display: flex; align-items: flex-start; justify-content: center; padding: 8vh 16px 16px;
}
.crm-find-panel {
  width: min(720px, 100%); background: rgba(255, 255, 255, 0.92); border-radius: 22px; overflow: hidden;
  -webkit-backdrop-filter: saturate(180%) blur(24px); backdrop-filter: saturate(180%) blur(24px);
  box-shadow: 0 30px 70px rgba(20, 20, 20, 0.3), inset 0 1px 0 rgba(255, 255, 255, 0.9);
  display: flex; flex-direction: column; max-height: 78vh;
  animation: crmFindIn 0.24s cubic-bezier(0.32, 0.72, 0, 1) both;
}
@keyframes crmFindIn {
  from { opacity: 0; transform: translateY(-12px) scale(0.98); }
  to { opacity: 1; transform: none; }
}
.crm-find-head { display: flex; align-items: center; gap: 12px; padding: 16px 18px; border-bottom: 1px solid rgba(20, 20, 20, 0.07); }
.crm-find-head svg { color: var(--gray); flex: none; }
.crm-find-head input {
  flex: 1 1 auto; border: 0; outline: none; font-family: inherit; font-size: 17px; color: var(--ink); background: transparent; min-width: 0;
}
.crm-find-esc { border: 1px solid var(--border); background: var(--white); border-radius: 6px; color: var(--gray); font-family: inherit; font-size: 11.5px; padding: 3px 7px; cursor: pointer; flex: none; }
.crm-find-body { overflow-y: auto; padding: 8px 8px 12px; }
.crm-find-group { padding: 6px 0; }
.crm-find-group-h { font-size: 11px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--gray); padding: 6px 10px; }
.crm-find-row {
  display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left; border: 0; background: transparent;
  font-family: inherit; padding: 9px 10px; border-radius: 10px; cursor: pointer;
}
.crm-find-row:hover, .crm-find-row.sel { background: var(--green-bg); }
.crm-find-main { font-size: 14.5px; font-weight: 600; color: var(--ink); }
.crm-find-sub { font-size: 12.5px; color: var(--gray); overflow: hidden; text-overflow: ellipsis; }
.crm-find-row.sel .crm-find-main { color: var(--green-dark); }
.crm-find-empty { color: var(--gray); font-size: 13.5px; padding: 18px 12px; margin: 0; line-height: 1.5; }
.crm-find-foot { display: flex; gap: 14px; padding: 9px 16px; border-top: 1px solid var(--border); font-size: 11.5px; color: var(--gray); }
.crm-find-hint { margin-left: auto; }

@media (max-width: 700px) {
  /* Меню на телефоне — ПАРЯЩАЯ панель со стеклом: отделена от края, сквозь
     неё просвечивает содержимое (как в современных приложениях). В ленту из
     11 вкладок помещалось три, остальное листали вслепую (замер 2026-09-20). */
  .crm-tabbar {
    position: fixed; left: 12px; right: 12px; top: auto; z-index: 30; margin: 0;
    bottom: calc(10px + env(safe-area-inset-bottom, 0px));
    border-radius: 26px; gap: 2px; padding: 6px;
    background: rgba(255, 255, 255, 0.72);
    -webkit-backdrop-filter: saturate(180%) blur(22px);
    backdrop-filter: saturate(180%) blur(22px);
    box-shadow: 0 10px 34px rgba(20, 20, 20, 0.16), 0 0 0 0.5px rgba(20, 20, 20, 0.06),
                inset 0 1px 0 rgba(255, 255, 255, 0.85);
  }
  .crm-tabbar-btn { flex-direction: column; gap: 3px; padding: 7px 2px 6px; border-radius: 20px; min-height: 50px; }
  .crm-tabbar-btn .crm-tab-label { font-size: 10.5px; font-weight: 500; letter-spacing: -0.01em; }
  .crm-tabbar-btn.active { background: rgba(26, 162, 96, 0.13); box-shadow: none; color: var(--green-dark); }
  .crm-tabbar-btn.active .crm-tab-ico { transform: translateY(-1px) scale(1.04); }
  .crm-tabbar .crm-tab-count { border-color: rgba(255, 255, 255, 0.9); }
  .crm-v2 { padding-bottom: 92px; }
  .crm-page-title { font-size: 28px; margin: 4px 0 12px; }
  .crm-find-overlay { padding: 0; align-items: stretch; }
  .crm-find-panel { width: 100%; max-height: 100%; border-radius: 0; }
  .crm-find-hint { display: none; }
}
@media (min-width: 701px) {
  /* На компьютере пункт меню — строка «иконка + подпись», поэтому счётчик
     встаёт в строку, а не кружком поверх иконки. */
  .crm-tabbar .crm-tab-count {
    position: static; border: 0; margin-left: 4px; height: 18px; line-height: 18px; font-size: 11px;
  }
  .crm-tab-ico-wrap { display: inline-flex; align-items: center; }
  /* Пять этапов заказа помещаются в один ряд — без «Отправл…» и «Закрыт …». */
  .crm-steps { grid-template-columns: repeat(5, minmax(0, 1fr)); max-width: 520px; }
  /* На компьютере «Ещё» — обычное выпадающее меню у кнопки, а не шторка.
     Место считает crm.js (placeMore) по самой кнопке: с absolute/right:0
     меню прижималось к краю экрана, далеко от «Ещё» (репорт 24.09).
     top/right здесь — только запасной вариант, если скрипт не сработал. */
  .crm-more-sheet {
    position: fixed; left: auto; right: 24px; bottom: auto; top: 64px; width: 264px;
    border-radius: var(--r-control); transform: translateY(-6px); opacity: 0; pointer-events: none;
    padding: 6px; box-shadow: 0 14px 34px rgba(20, 20, 20, 0.16); border: 1px solid var(--border);
    transition: opacity 0.16s, transform 0.16s;
  }
  .crm-more-sheet.open { transform: none; opacity: 1; pointer-events: auto; }
  /* Меню справа от кнопки выезжает вбок, а не сверху. */
  .crm-more-sheet.crm-more-side { transform: translateX(-6px); }
  .crm-more-sheet.crm-more-side.open { transform: none; }
  .crm-sheet-grabber, .crm-sheet-title { display: none; }
  .crm-more-item { min-height: 44px; font-size: 14.5px; }
  .crm-sheet-backdrop { background: transparent; }
}
.crm-badge.crm-stale { background: var(--photobg); color: var(--gray); }
.crm-chat-rebind { flex-basis: 100%; }
.crm-tab-count { font-weight: 700; opacity: 0.85; }
.crm-chips { display: flex; gap: 6px; overflow-x: auto; padding: 2px 0 10px; scrollbar-width: none; }
.crm-chips::-webkit-scrollbar { display: none; }
.crm-chip { flex: none; border: 1px solid var(--border); background: var(--white); color: var(--ink); border-radius: var(--r-pill); padding: 6px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; }
.crm-chip.active { background: var(--ink); border-color: var(--ink); color: var(--white); }
.crm-chip-n { color: var(--gray); font-weight: 500; }
.crm-chip.active .crm-chip-n { color: var(--lgray); }
.crm-loading, .crm-empty { text-align: center; color: var(--gray); padding: 36px 12px; font-size: 14px; line-height: 1.6; }
.crm-empty { color: var(--ink); font-weight: 600; }
.crm-intro { margin: 0 0 12px; line-height: 1.5; }
.crm-search { width: 100%; box-sizing: border-box; border: 1px solid var(--border); border-radius: var(--r-control); padding: 10px 12px; font-size: 15px; background: var(--white); margin-bottom: 10px; font-family: inherit; }

.crm-group { margin-bottom: 18px; }
.crm-group h3 { font-size: 15px; margin: 0 0 8px; }
.crm-group-n { color: var(--gray); font-weight: 600; }
.crm-row, .crm-card { display: flex; gap: 10px; align-items: flex-start; background: var(--white); border: 1px solid var(--border); border-radius: 16px; padding: 12px; margin-bottom: 8px; cursor: pointer; }
.crm-card { flex-direction: column; cursor: default; gap: 8px; }
.crm-row:hover { border-color: var(--lgray); }
.crm-row-main { flex: 1; min-width: 0; }
.crm-row-top { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.crm-client { font-size: 14.5px; }
.crm-who { font-size: 11.5px; color: var(--gray); background: var(--photobg); border-radius: var(--r-pill); padding: 2px 8px; }
.crm-row-text { font-size: 13.5px; color: var(--ink); margin-top: 4px; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.crm-row-reason { font-size: 12px; color: var(--gray); margin-top: 3px; }
.crm-row-actions { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.crm-row > .crm-row-actions { flex-direction: column; align-items: stretch; }
.crm-btn { border: 1px solid var(--border); background: var(--white); color: var(--ink); border-radius: var(--r-pill); padding: 7px 12px; font-size: 12.5px; font-weight: 600; cursor: pointer; text-decoration: none; white-space: nowrap; text-align: center; font-family: inherit; }
.crm-btn:disabled { opacity: 0.5; cursor: default; }
.crm-btn-primary { background: var(--green); border-color: var(--green); color: var(--white); }
.crm-btn-wa { background: var(--green-bg); border-color: var(--green-border); color: var(--green-dark); }
.crm-btn-ghost { background: var(--white); }
.crm-badge { font-size: 11.5px; font-weight: 700; border-radius: var(--r-pill); padding: 2px 8px; white-space: nowrap; }
/* «Клиенты → Номера» (03.10): к кому привязан номер — строкой под именем,
   статус меткой цвета (клиент — зелёный, свободный — жёлтый, «не клиент» —
   серый, поставщик — синий). */
.crm-num-bind { margin: 8px 0 2px; font-size: 14px; line-height: 1.45; overflow-wrap: anywhere; }
.crm-num-bind .crm-link-btn { font-size: 14px; }
.crm-num-tag { display: inline-block; font-size: 11.5px; font-weight: 700; border-radius: var(--r-pill); padding: 2px 8px; margin-right: 6px; white-space: nowrap; }
.crm-num-client, .crm-num-lead { background: var(--green-bg); color: var(--green-dark); }
.crm-num-free { background: var(--warning-bg); color: #9a6a0c; }
.crm-num-not_client { background: var(--photobg); color: var(--gray); }
.crm-num-supplier { background: #eef1fb; color: #3a4f9a; }
.crm-num-filter { margin: 10px 0 4px; }
.crm-num-busy { opacity: 0.45; pointer-events: none; transition: opacity 0.15s; }
.crm-wait { background: var(--photobg); color: var(--gray); }
.crm-warn { background: var(--warning-bg); color: #9a6a0c; }
.crm-late { background: var(--loss-bg); color: var(--danger); }
.crm-late-text { color: var(--danger); font-weight: 600; }
.crm-cell-bad { color: var(--danger); }
.crm-team-grid { display: grid; grid-template-columns: 1fr; gap: 8px; margin-bottom: 18px; }
.crm-team-card { background: var(--white); border: 1px solid var(--border); border-radius: 16px; padding: 12px; }
.crm-metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); gap: 8px; margin-top: 10px; }
.crm-metric-v { font-size: 17px; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums; }
.crm-metric-l { font-size: 11px; color: var(--gray); line-height: 1.3; }
.crm-dot { flex: none; width: 10px; height: 10px; border-radius: 50%; margin-top: 5px; background: var(--border); }
.crm-dot-green { background: var(--green); }
.crm-dot-yellow { background: var(--warning); }
.crm-dot-red { background: var(--danger); }
.crm-stage-pill { display: inline-block; font-size: 11px; font-weight: 700; color: var(--green-dark); background: var(--green-bg); border-radius: var(--r-pill); padding: 1px 7px; }

.crm-preview { background: var(--bg); border-radius: var(--r-sm); padding: 8px 10px; font-size: 13px; line-height: 1.45; }
.crm-preview-line { color: var(--ink); }
.crm-preview-line.me { color: var(--gray); }
.crm-suggest { font-size: 13.5px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.crm-bind-results { display: flex; flex-direction: column; gap: 4px; }
.crm-result { text-align: left; border: 1px solid var(--border); background: var(--white); border-radius: var(--r-sm); padding: 9px 10px; font-size: 13.5px; cursor: pointer; font-family: inherit; }
.crm-result:hover { border-color: var(--green); }

.crm-team-table th { white-space: nowrap; }
.crm-conn-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; background: var(--white); border: 1px solid var(--border); border-radius: 14px; padding: 10px 12px; margin-bottom: 6px; font-size: 14px; }
.crm-conn-row .crm-dot { margin-top: 0; }
.crm-conn-status { color: var(--gray); font-size: 12.5px; flex: 1; }
.crm-pair-panel { max-width: 460px; }
.crm-pair-steps { padding-left: 18px; font-size: 14px; line-height: 1.5; }
.crm-pair-qr { display: flex; justify-content: center; margin: 12px 0; }
.crm-pair-qr img { width: 280px; max-width: 100%; image-rendering: pixelated; border: 10px solid var(--white); border-radius: 12px; box-shadow: 0 0 0 1px var(--border); }
.crm-pair-phone summary { cursor: pointer; font-weight: 600; font-size: 13.5px; margin: 8px 0; }
.crm-pair-code { font-size: 30px; font-weight: 800; letter-spacing: 4px; text-align: center; margin: 12px 0; font-variant-numeric: tabular-nums; }

/* --- CRM-вкладка в карточке клиента --- */
#client-modal-crm { margin-bottom: 12px; }
.crm-card-tabs { background: var(--photobg); border-radius: var(--r-pill); padding: 4px; display: flex; gap: 2px; margin: 4px 0 12px; max-width: 320px; }
.crm-stagebar { display: flex; gap: 3px; overflow-x: auto; scrollbar-width: none; margin-bottom: 8px; }
.crm-stagebar::-webkit-scrollbar { display: none; }
.crm-step { flex: 1 1 0; min-width: 0; text-align: center; font-size: 10.5px; font-weight: 600; color: var(--gray); background: var(--photobg); padding: 7px 2px; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-step:first-child { border-radius: 10px 0 0 10px; }
.crm-step:last-child { border-radius: 0 10px 10px 0; }
.crm-step.past { background: var(--green-bg); color: var(--green-dark); }
.crm-step.current { background: var(--green); color: var(--white); }
.crm-step small { display: block; font-weight: 500; opacity: 0.9; }
.crm-card-badges { margin-bottom: 8px; }
.crm-card-head .crm-row-actions { margin-bottom: 10px; }
.crm-card-cols { display: flex; flex-direction: column; gap: 10px; }
.crm-block { background: var(--white); border: 1px solid var(--border); border-radius: 16px; padding: 12px 14px; margin-bottom: 10px; }
.crm-block h4 { margin: 0 0 6px; font-size: 14px; }
.crm-block ul { margin: 0; padding-left: 18px; font-size: 13.5px; line-height: 1.5; }
.crm-block li { margin-bottom: 4px; }
.crm-next { font-size: 13.5px; margin: 8px 0; padding: 8px 10px; background: var(--green-bg); border-radius: var(--r-sm); }
.crm-risks { font-size: 13.5px; margin-top: 6px; }
.crm-goodbad { display: grid; grid-template-columns: 1fr; gap: 0 10px; }
.crm-good h4 { color: var(--green-dark); }
.crm-bad h4 { color: var(--danger); }
.crm-quote-link { border: none; background: none; color: var(--link-blue); cursor: pointer; font-size: 13px; padding: 0 2px; }
.crm-fb { display: inline-flex; gap: 2px; margin-left: 4px; vertical-align: middle; }
.crm-fb button { border: 1px solid var(--border); background: var(--white); border-radius: 50%; width: 22px; height: 22px; font-size: 11px; line-height: 1; cursor: pointer; color: var(--gray); padding: 0; }
.crm-fb button.chosen { background: var(--ink); color: var(--white); border-color: var(--ink); }
.crm-chats { margin-bottom: 8px; }
.crm-feed { max-height: 60vh; overflow-y: auto; display: flex; flex-direction: column; gap: 4px; padding: 4px 2px; background: var(--bg); border-radius: 12px; }
.crm-day { align-self: center; font-size: 11.5px; color: var(--gray); background: var(--white); border: 1px solid var(--border); border-radius: var(--r-pill); padding: 2px 10px; margin: 8px 0 4px; }
.crm-msg { display: flex; }
.crm-msg.me { justify-content: flex-end; }
.crm-bubble { max-width: 82%; background: var(--white); border: 1px solid var(--border); border-radius: 14px 14px 14px 4px; padding: 7px 10px; font-size: 13.5px; line-height: 1.45; white-space: pre-wrap; word-break: break-word; }
.crm-msg.me .crm-bubble { background: #dcf5e6; border-color: var(--green-border); border-radius: 14px 14px 4px 14px; }
.crm-msg.flagged .crm-bubble { box-shadow: inset 3px 0 0 var(--warning); }
.crm-msg.crm-highlight .crm-bubble { outline: 2px solid var(--link-blue); outline-offset: 1px; }
.crm-meta { font-size: 10.5px; color: var(--gray); text-align: right; margin-top: 2px; white-space: nowrap; }
.crm-reactions { font-size: 13px; margin-top: 2px; }
.crm-transcript { margin-top: 4px; font-size: 13px; color: var(--ink); font-style: italic; }
.crm-bubble audio { width: 230px; max-width: 100%; height: 36px; }
.crm-img { max-width: 220px; max-height: 260px; border-radius: 10px; display: block; }
.crm-more { align-self: center; margin: 6px 0; }
.crm-feed-tools .crm-search { margin-bottom: 6px; font-size: 14px; padding: 8px 10px; }
.crm-ask textarea.crm-search { resize: vertical; min-height: 56px; margin-bottom: 8px; font-size: 14px; }
.crm-ask-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.crm-ask-row .hint { font-size: 12px; }
/* Примеры вопросов — отдельной строкой под полем: в placeholder длинная
   подсказка обрезалась (репорт пользователя 2026-09-17). */
.crm-ask-examples { margin: 6px 0 10px; font-size: 12.5px; line-height: 1.45; }
/* Заданный вопрос и ответ — отдельной карточкой-подложкой, а не строчками
   через разделитель: так видно, где кончается один вопрос и начинается
   следующий («вёрстка после заданного вопроса хромает»). */
.crm-qa { margin-top: 10px; padding: 10px 12px; background: var(--crm-field); }
.crm-q { display: flex; align-items: baseline; gap: 8px; }
.crm-q-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.crm-q-when { flex: 0 0 auto; font-size: 11.5px; color: var(--gray); white-space: nowrap; }
.crm-qa-points { margin: 6px 0 0; padding-left: 18px; font-size: 13.5px; line-height: 1.5; }
.crm-qa-points li + li { margin-top: 4px; }

.crm-exact { margin-bottom: 14px; }
.crm-exact-row { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-top: 1px solid var(--border); font-size: 13.5px; line-height: 1.4; cursor: pointer; }
.crm-exact-row input { width: 18px; height: 18px; margin: 1px 0 0; flex: 0 0 auto; accent-color: var(--green); }
.crm-exact .crm-row-actions { margin-top: 8px; }
.crm-cand-list { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 4px; }
.crm-chats { margin-bottom: 8px; }
.crm-chats-head { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.crm-link-btn { border: 0; background: none; padding: 0; color: var(--link-blue); font-size: 13px; cursor: pointer; font-family: inherit; }
.crm-chat-row { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 13px; padding: 2px 0; }
.crm-chat-actions { display: none; gap: 6px; }
.crm-chats.editing .crm-chat-actions { display: inline-flex; }
.crm-lead-form { margin-top: 10px; }
.crm-lead-form .hint { margin-bottom: 6px; }
.crm-lead-block { border-color: var(--green-border); background: var(--green-bg); }
.crm-lead-block .crm-search { margin: 8px 0 4px; }
.crm-lead-badge { background: var(--green-bg); color: var(--green-dark); }
.crm-cand-list .crm-btn { white-space: normal; text-align: left; }
.crm-q { font-size: 13.5px; margin-bottom: 4px; }

@media (min-width: 900px) {
  .crm-team-grid { grid-template-columns: 1fr 1fr; }
  .crm-step { font-size: 12px; padding: 8px 4px; }
  .crm-row > .crm-row-actions { flex-direction: row; }
  .crm-card-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 12px; align-items: start; }
  .crm-goodbad { grid-template-columns: 1fr 1fr; }
  .crm-feed { max-height: 70vh; }
}

/* --- CRM 2026-09-14: заказы и пересборка интерфейса ---
   Главное — крупно и первым (имя клиента, номер заказа, «ждёт», проблема),
   второстепенное — мелким серым в одной строке. На телефоне строка не
   делится на колонку кнопок: WhatsApp — круглая иконка справа, остальные
   действия — текстовые ссылки под текстом. */
.crm-tab-count-alert { color: var(--danger); }
.seg-toggle-btn.active .crm-tab-count-alert { color: inherit; }
.crm-manager-filter { padding-bottom: 6px; }
.crm-tone { flex: none; display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--lgray); }
.crm-tone-red { background: var(--danger); }
.crm-tone-orange { background: #e67e22; }
.crm-tone-yellow { background: var(--warning); }
.crm-tone-green { background: var(--green); }
.crm-tone-gray { background: var(--lgray); }

.crm-sum-strip { display: flex; flex-wrap: wrap; gap: 6px; margin: 2px 0 14px; }
.crm-sum-chip { display: inline-flex; align-items: center; gap: 6px; border: 1px solid var(--border); background: var(--white); border-radius: var(--r-pill); padding: 6px 11px; font: inherit; font-size: 13px; color: var(--ink); cursor: pointer; }
.crm-sum-chip b { font-variant-numeric: tabular-nums; }
.crm-sum-chip:hover { border-color: var(--lgray); }
.crm-allgood { margin: 0 0 12px; font-size: 13px; color: var(--green-dark); font-weight: 600; }
.crm-group { margin-bottom: 20px; scroll-margin-top: 70px; }
.crm-group-h { display: flex; align-items: center; gap: 8px; font-size: 15px; margin: 0 0 8px; }
.crm-more-btn { width: 100%; border: 1px dashed var(--border); background: transparent; border-radius: 12px; padding: 9px; font: inherit; font-size: 13px; font-weight: 600; color: var(--gray); cursor: pointer; }
.crm-more-btn:hover { color: var(--ink); border-color: var(--lgray); }

.crm-item { display: flex; gap: 10px; align-items: flex-start; background: var(--white); border: 1px solid var(--border); border-radius: 14px; padding: 11px 12px; margin-bottom: 6px; cursor: pointer; }
.crm-item:hover { border-color: var(--lgray); }
.crm-item:focus-visible, .crm-order:focus-visible { outline: 2px solid var(--link-blue); outline-offset: 1px; }
.crm-item-body { flex: 1; min-width: 0; }
.crm-item-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.crm-item-title { font-size: 15px; font-weight: 700; line-height: 1.3; }
.crm-item-text { font-size: 13.5px; color: #3a3a3c; margin-top: 3px; line-height: 1.4; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.crm-item-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 14px; margin-top: 5px; }
.crm-item-sub { font-size: 12px; color: var(--gray); flex: 1 1 auto; min-width: 0; }
.crm-item-foot .crm-link-btn { font-size: 12.5px; font-weight: 600; }
.crm-item .crm-dot { margin-top: 6px; }
.crm-wa { flex: none; width: 38px; height: 38px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: var(--green-bg); color: var(--green-dark); border: 1px solid var(--green-border); text-decoration: none; }
.crm-wa:hover { background: var(--green); color: var(--white); }
.crm-card .crm-item-head .crm-wa { margin-left: auto; width: 34px; height: 34px; }
.crm-btn-wa svg { width: 15px; height: 15px; vertical-align: -3px; }
.crm-link-btn:disabled { opacity: 0.5; }
.crm-chip-sm { padding: 4px 10px; font-size: 12px; }
.crm-chips-sub { margin-top: -4px; }
.crm-chip-alert:not(.active) { border-color: #f1c4bf; color: var(--danger); }
.crm-foot-hint { margin-top: 10px; font-size: 12px; }

/* Строка заказа: номер слева крупно, клиент и этапы по центру, сумма и оплата справа. */
.crm-order { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; gap: 4px 12px; align-items: start; background: var(--white); border: 1px solid var(--border); border-radius: 14px; padding: 10px 12px; margin-bottom: 6px; cursor: pointer; }
.crm-order:hover { border-color: var(--lgray); }
.crm-order.has-problem { border-color: #f1c4bf; box-shadow: inset 3px 0 0 var(--danger); }
.crm-order-id { display: flex; flex-direction: column; align-items: flex-start; min-width: 44px; }
.crm-order-id b { font-size: 17px; font-variant-numeric: tabular-nums; letter-spacing: -0.2px; line-height: 1.2; }
.crm-order-id span { font-size: 11.5px; color: var(--gray); white-space: nowrap; }
.crm-order-main { min-width: 0; }
.crm-order-head { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; margin-bottom: 6px; }
.crm-order-client { font-size: 14.5px; font-weight: 700; line-height: 1.3; }
.crm-order-side { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; text-align: right; }
.crm-order-sum { font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.crm-order-sub { font-size: 12px; color: var(--gray); margin-top: 5px; line-height: 1.35; }
.crm-order-problem { font-size: 12.5px; color: var(--danger); font-weight: 600; margin-top: 5px; line-height: 1.35; }
.crm-order.compact { padding: 8px 10px; border-radius: 12px; }
.crm-order.compact .crm-order-id b { font-size: 15px; }
.crm-steps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 3px; max-width: 360px; }
.crm-steps-now { display: none; }
@media (max-width: 700px) {
  /* Пять подписей в 390px превращались в «Отпр… Собр… Отгр…» и вторую строку
     с «Закр…» — на телефоне это полоса прогресса плюс текущий этап словами. */
  .crm-steps { display: flex; align-items: center; gap: 3px; max-width: none; }
  .crm-steps .crm-seg { flex: 1 1 0; font-size: 0; padding: 0; height: 4px; border-radius: 2px; }
  .crm-steps-now { display: inline-block; flex: none; margin-left: 7px; font-size: 12px; font-weight: 600; color: var(--gray); white-space: nowrap; }
}
.crm-seg { font-size: 10.5px; font-weight: 600; color: var(--gray); text-align: center; padding: 3px 2px 4px; border-radius: 6px; background: var(--photobg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-seg.done { background: var(--green-bg); color: var(--green-dark); }
.crm-pay { font-size: 11.5px; font-weight: 700; border-radius: var(--r-pill); padding: 2px 8px; white-space: nowrap; background: var(--photobg); color: var(--gray); }
.crm-pay-ok { background: var(--green-bg); color: var(--green-dark); }
.crm-pay-warn { background: var(--warning-bg); color: #9a6a0c; }
.crm-pay-bad { background: var(--loss-bg); color: var(--danger); }
@media (max-width: 520px) {
  /* Узкий экран: сумма и оплата уходят под этапы, номер остаётся слева. */
  .crm-order { grid-template-columns: auto minmax(0, 1fr); }
  .crm-order-side { grid-column: 2; flex-direction: row; flex-wrap: wrap; align-items: center; justify-content: flex-start; text-align: left; gap: 4px 8px; }
}

/* Окно заказа. Кнопка «назад» сидит поверх тела окна — отступ, как у карточки клиента. */
.crm-order-panel { max-width: 640px; }
.crm-order-panel .product-modal-body { padding-top: 54px; }
.crm-order-title { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; }
.crm-order-title h2 { font-size: 22px; }
.crm-order-clientlink { align-self: flex-start; border: 0; background: none; padding: 2px 0; font: inherit; font-size: 16px; font-weight: 700; color: var(--link-blue); cursor: pointer; text-align: left; }
.crm-osteps { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin: 6px 0 2px; }
.crm-ostep { position: relative; display: flex; flex-direction: column; gap: 2px; padding-top: 14px; font-size: 12.5px; color: var(--gray); min-width: 0; }
.crm-ostep::before { content: ""; position: absolute; top: 4px; left: 0; right: 0; height: 3px; border-radius: 2px; background: var(--border); }
.crm-ostep.done::before { background: var(--green); }
.crm-ostep-dot { display: none; }
.crm-ostep b { color: var(--gray); font-weight: 600; }
.crm-ostep.done b { color: var(--ink); }
.crm-ostep small { font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-alert { background: var(--loss-bg); color: var(--danger); border-radius: 12px; padding: 9px 12px; font-size: 13.5px; font-weight: 600; line-height: 1.45; }
.crm-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 5px 14px; margin: 6px 0 0; font-size: 13.5px; }
.crm-facts dt { color: var(--gray); }
.crm-facts dd { margin: 0; overflow-wrap: anywhere; }
.crm-h4 { font-size: 14px; margin: 12px 0 2px; display: flex; align-items: center; gap: 6px; }
.crm-ophotos { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }
.crm-ophoto { position: relative; display: block; border-radius: 10px; overflow: hidden; background: var(--photobg); aspect-ratio: 1; max-width: 100%; }
.crm-ophoto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.crm-ophoto span { position: absolute; left: 0; right: 0; bottom: 0; font-size: 10px; color: var(--white); background: linear-gradient(transparent, rgba(0,0,0,.6)); padding: 10px 5px 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-ophoto-groups { display: flex; flex-direction: column; gap: 10px; }
.crm-ophoto-label { font-size: 12.5px; font-weight: 700; color: var(--gray); margin-bottom: 4px; display: flex; align-items: center; gap: 4px; }
.crm-ophoto-doc, .crm-ophoto-missing { display: flex; align-items: center; justify-content: center; text-decoration: none; }
.crm-ophoto-doc b { font-size: 16px; color: var(--danger); }
.crm-ophoto-missing b { font-size: 11px; color: var(--gray); font-weight: 600; }
.crm-ophoto-missing span { color: var(--gray); background: none; }

/* Просмотр фото поверх страницы: чёрный фон, фото по центру, «Назад». */
html.crm-viewer-open, html.crm-viewer-open body { overflow: hidden; }
.crm-viewer { position: fixed; inset: 0; background: #000; display: flex; flex-direction: column; color: #fff; overscroll-behavior: contain; }
.crm-viewer[hidden] { display: none; }
.crm-viewer-top { display: flex; align-items: center; gap: 10px; padding: calc(env(safe-area-inset-top, 0px) + 8px) 12px 8px; background: rgba(0,0,0,.6); z-index: 2; }
.crm-viewer-back { border: 0; background: rgba(255,255,255,.16); color: #fff; font: inherit; font-size: 15px; font-weight: 600; border-radius: var(--r-pill); padding: 8px 14px; cursor: pointer; flex: none; }
.crm-viewer-cap { flex: 1; min-width: 0; font-size: 13px; opacity: .85; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.crm-viewer-n { font-size: 13px; opacity: .7; flex: none; font-variant-numeric: tabular-nums; }
.crm-viewer-stage { position: relative; flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; overflow: hidden; touch-action: none; }
.crm-viewer-stage img { max-width: 100%; max-height: 100%; object-fit: contain; user-select: none; -webkit-user-select: none; transform-origin: center center; will-change: transform; }
.crm-viewer-doc { width: 100%; height: 100%; border: 0; background: #fff; }
.crm-viewer-file { position: absolute; bottom: calc(env(safe-area-inset-bottom, 0px) + 12px); left: 50%; transform: translateX(-50%); color: #fff; background: rgba(0,0,0,.7); padding: 8px 14px; border-radius: var(--r-pill); text-decoration: none; font-size: 14px; }
.crm-viewer-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 44px; height: 64px; border: 0; background: rgba(255,255,255,.12); color: #fff; font-size: 34px; line-height: 1; cursor: pointer; z-index: 2; }
.crm-viewer-prev { left: 6px; border-radius: 0 12px 12px 0; }
.crm-viewer-next { right: 6px; border-radius: 12px 0 0 12px; }
@media (hover: none) { .crm-viewer-nav { display: none; } }

.crm-team-card { cursor: pointer; }
.crm-team-card:hover { border-color: var(--lgray); }
/* «Закуп»: строка спроса раскрывается в список клиентов, которые спрашивали. */
.crm-demand { display: block; padding: 0; }
.crm-demand > summary { list-style: none; cursor: pointer; padding: 11px 12px; display: flex; }
.crm-demand > summary::-webkit-details-marker { display: none; }
.crm-demand[open] > summary { border-bottom: 1px solid var(--border); }
.crm-demand-clients { padding: 4px 12px 10px; }
/* «Промо»: подборка товаров для статусов WhatsApp. */
.crm-promo-item { background: var(--white); border: 1px solid var(--border); border-radius: 14px; margin-bottom: 6px; overflow: hidden; }
.crm-promo-item.open { border-color: var(--green); }
.crm-promo-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 10px 12px; cursor: pointer; font-size: 14px; }
.crm-promo-head .crm-item-title { flex: 1 1 200px; min-width: 0; }
.crm-promo-check { flex: none; width: 22px; height: 22px; border: 2px solid var(--border); border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; font-size: 14px; color: var(--white); }
.crm-promo-item.open .crm-promo-check { background: var(--green); border-color: var(--green); }
.crm-promo-body { padding: 0 12px 12px; display: flex; flex-direction: column; gap: 8px; }
.crm-promo-img { width: 190px; max-width: 60%; border-radius: 10px; border: 1px solid var(--border); }
.crm-promo-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.crm-promo-text { white-space: pre-wrap; background: var(--bg); border-radius: 8px; padding: 8px 10px; font: inherit; font-size: 13px; margin: 0; }

/* Задача без клиента: товар со сроком — фото и шаги. */
.crm-task-plain { cursor: default; }
.crm-task-photos { display: flex; gap: 6px; flex-wrap: wrap; margin: 6px 0; }
.crm-task-photo { display: block; width: 78px; height: 78px; border-radius: 10px; overflow: hidden; background: var(--photobg); }
.crm-task-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.crm-task-steps { margin: 4px 0 2px; padding-left: 20px; font-size: 13px; color: #3a3a3c; line-height: 1.45; }
.crm-demand-fix { border-top: 1px dashed var(--border); margin-top: 6px; padding-top: 8px; display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.crm-demand-fix .crm-search { width: 100%; font-size: 14px; padding: 8px 10px; }
.crm-demand-fix .crm-bind-results { width: 100%; }
button.crm-sum-chip.active { background: var(--ink); color: var(--white); border-color: var(--ink); }
.crm-demand-client + .crm-demand-client { border-top: 1px solid var(--border); }
.crm-demand .crm-ev-link { padding: 7px 0; }
.crm-badge.crm-warn { background: var(--warning-bg); color: #9a6a0c; }
.crm-plan { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 8px; }
.crm-plan-head { font-size: 13.5px; display: flex; flex-wrap: wrap; gap: 6px; align-items: baseline; }
.crm-plan-bar { height: 8px; border-radius: 4px; background: var(--photobg); overflow: hidden; margin: 6px 0 4px; }
.crm-plan-bar span { display: block; height: 100%; background: var(--green); }
.crm-team-more { margin-top: 10px; font-size: 13px; font-weight: 600; color: var(--link-blue); }
.crm-review p { margin: 0 0 6px; font-size: 14px; line-height: 1.5; }
.crm-review li { margin-bottom: 8px; }
.crm-good-h { color: var(--green-dark); font-size: 13px; margin: 10px 0 4px; }
.crm-bad-h { color: var(--danger); font-size: 13px; margin: 10px 0 4px; }
.crm-days { border-collapse: collapse; font-size: 13px; width: 100%; white-space: nowrap; }
.crm-days th, .crm-days td { padding: 6px 8px; border-bottom: 1px solid var(--border); text-align: right; font-variant-numeric: tabular-nums; }
.crm-days th:first-child, .crm-days td:first-child { text-align: left; }
.crm-days th { color: var(--gray); font-weight: 600; font-size: 12px; }
.crm-days tr.crm-off td { color: var(--lgray); }
.crm-evidence ul { list-style: none; padding: 0; }
.crm-evidence li { border-top: 1px solid var(--border); margin: 0; }
.crm-ev-link { display: block; width: 100%; text-align: left; border: 0; background: none; padding: 8px 0; font: inherit; font-size: 13.5px; line-height: 1.4; color: var(--ink); cursor: pointer; }
.crm-ev-link:hover b { color: var(--link-blue); }
.crm-feed-modal { max-height: 62vh; margin-top: 6px; }
.crm-cash-unmatched { border-color: #f3d9a4; }
.crm-cash-row { border-top: 1px solid var(--border); padding: 8px 0; font-size: 13.5px; }
.crm-cash-row .crm-search { margin: 6px 0 4px; font-size: 14px; padding: 8px 10px; }
.crm-supplier-search { width: 100%; }
.crm-product-suppliers .crm-row-actions { margin-top: 6px; }

.crm-timeline { list-style: none; margin: 0; padding: 0; }
.crm-ev { display: flex; gap: 10px; padding: 8px 0; border-top: 1px solid var(--border); }
.crm-ev:first-child { border-top: 0; }
.crm-ev .crm-tone { margin-top: 6px; }
.crm-ev-body { flex: 1; min-width: 0; font-size: 13.5px; line-height: 1.4; }
.crm-ev-head { display: flex; flex-wrap: wrap; gap: 2px 6px; align-items: baseline; }
.crm-ev-time { margin-left: auto; font-size: 12px; color: var(--gray); white-space: nowrap; }
.crm-ev-text { white-space: pre-wrap; background: var(--bg); border-radius: 8px; padding: 6px 8px; margin-top: 4px; font-size: 13px; }
.crm-details { margin-top: 8px; font-size: 13.5px; }
.crm-details summary { cursor: pointer; color: var(--link-blue); }

/* Карточка клиента. */
.crm-card-head { margin-bottom: 4px; }
.crm-card-line { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 10px; }
.crm-card-phones { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }
.crm-todo ul { list-style: none; padding: 0; }
.crm-todo li { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px; padding: 6px 0; border-top: 1px solid var(--border); margin: 0; }
.crm-todo li:first-child { border-top: 0; padding-top: 0; }
.crm-todo li > span:first-child { flex: 1 1 220px; min-width: 0; }
.crm-todo-actions { display: inline-flex; gap: 12px; }
.crm-todo .crm-link-btn { font-weight: 600; font-size: 12.5px; }
.crm-todo { border-color: #f3d9a4; }
/* Обещания клиента — отдельная зона, не «Что сделать» менеджера (2026-09-20). */
.crm-cpromises ul { list-style: none; padding: 0; margin: 0; }
.crm-cpromises li { padding: 6px 0; border-top: 1px solid var(--border); margin: 0; }
.crm-cpromises li:first-child { border-top: 0; padding-top: 0; }
.crm-cpromises .crm-badge { margin-left: 4px; }
.crm-orders-block .crm-order { background: var(--bg); }
.crm-orders-block h4 { display: flex; align-items: center; gap: 6px; }
.crm-summary h5 { font-size: 13px; margin: 10px 0 4px; }
.crm-summary .crm-goodbad { margin-top: 4px; }
.crm-summary-foot { margin-top: 8px; font-size: 11.5px; }
details.crm-block > summary { cursor: pointer; list-style: none; display: flex; align-items: center; gap: 6px; }
details.crm-block > summary::-webkit-details-marker { display: none; }
details.crm-block > summary h4 { margin: 0; }
details.crm-block[open] > summary { margin-bottom: 8px; }
.crm-chats { margin: 10px 0 0; font-size: 12.5px; }
.crm-chats > summary { cursor: pointer; color: var(--gray); list-style: none; }
.crm-chats > summary::-webkit-details-marker { display: none; }
.crm-chats[open] .crm-chat-actions { display: flex; flex-wrap: wrap; }
/* 2026-09-15: четыре кнопки чата в одну строку распирали карточку вбок, и
   переписка уезжала за левый край (скриншот пользователя). Колонки карточки
   не шире экрана, кнопки переносятся. */
.crm-card-left, .crm-card-right { min-width: 0; }
.crm-chat-row > .hint { min-width: 0; overflow-wrap: anywhere; }
.crm-chat-actions { gap: 6px; width: 100%; }
.crm-chat-actions .crm-btn { padding: 6px 10px; font-size: 12.5px; white-space: nowrap; }
.crm-chats > summary { overflow-wrap: anywhere; }
.crm-bubble { overflow-wrap: anywhere; tab-size: 2; }
/* Ценность клиента: A — крупный, B — средний, C — небольшой (по выручке за 3 мес.). */
.crm-val { flex: none; display: inline-flex; align-items: center; font-size: 11.5px; font-weight: 700; border-radius: var(--r-pill); padding: 2px 8px; white-space: nowrap; font-variant-numeric: tabular-nums; }
.crm-val-A { background: #1f7a4d; color: #fff; }
.crm-val-B { background: var(--green-bg); color: var(--green-dark); }
.crm-val-C { background: var(--photobg); color: var(--gray); }
.crm-value-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font-size: 13px; color: #3a3a3c; margin: 2px 0 8px; line-height: 1.4; }
.crm-sort-toggle { display: inline-flex; gap: 4px; margin-left: auto; }
/* Личный кабинет и витрина в карточке CRM (из РОП). */
.crm-site-row { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 8px 12px; padding: 8px 0; border-top: 1px solid var(--border); font-size: 13.5px; }
.crm-site-row:first-of-type { border-top: 0; padding-top: 2px; }
.crm-site-row > div:first-child { flex: 1 1 220px; min-width: 0; overflow-wrap: anywhere; }
.crm-site-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
.crm-site-actions .crm-link-btn { font-weight: 600; font-size: 13px; }
.crm-site-warn { font-size: 12.5px; margin-top: 2px; }
.crm-site-status:empty { display: none; }
/* Оплата витрины (10.10.2026): карточка клиента и карточка во «Витринах». */
.crm-bill { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px; margin: 4px 0 10px; border: 1px solid var(--border); border-radius: 12px; font-size: 13.5px; }
.crm-bill-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.crm-bill-due .hint { margin-top: 2px; }
.crm-bill-form { display: flex; flex-direction: column; gap: 10px; padding-top: 4px; }
.crm-bill [hidden] { display: none !important; }
.crm-bill-field { display: flex; flex-direction: column; gap: 4px; }
.crm-bill-field .crm-input, .crm-bill-field .crm-select { font-size: 16px; width: 100%; box-sizing: border-box; }
.crm-bill-hist summary { cursor: pointer; font-size: 13px; color: var(--gray); }
.crm-bill-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; padding: 6px 0; border-top: 1px solid var(--border); }
.crm-bill-row:first-of-type { border-top: 0; }
.crm-bill-cancelled b { text-decoration: line-through; color: var(--gray); }
.crm-select { font: inherit; font-size: 14px; padding: 8px 10px; border: 1px solid var(--border); border-radius: 10px; background: var(--white); max-width: 100%; }
.crm-badge.crm-ok { background: var(--green-bg); color: var(--green-dark); }
.crm-result-new { border-style: dashed; }
.crm-thinking { animation: crm-pulse 1.4s ease-in-out infinite; }
@keyframes crm-pulse { 50% { opacity: 0.45; } }
.crm-feed-chips { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; margin: 0 0 8px; padding-bottom: 2px; }
.crm-feed-chips::-webkit-scrollbar { display: none; }
.crm-feed-chips .crm-chip { flex: none; }
.crm-feed-switch { align-self: stretch; text-align: center; font-size: 11.5px; font-weight: 700; color: var(--green-dark); margin: 6px 0 2px; display: flex; align-items: center; gap: 8px; }
.crm-feed-switch::before, .crm-feed-switch::after { content: ""; flex: 1; height: 1px; background: var(--green-border); }
.crm-chats[open] > summary { margin-bottom: 6px; }
.crm-chat-row { border-top: 1px solid var(--border); padding: 6px 0; }
/* Суммы прямо в столбике (см. catalog.html) — по прямому репорту
   пользователя (2026-08-19), заменяет прежнюю подпись под графиком.
   Сегмент — flex-контейнер, чтобы подпись центрировалась и по высоте, и
   по ширине СВОЕГО цветного участка, а не всей колонки целиком. */
.value-chart-bar { display: flex; align-items: center; justify-content: center; overflow: hidden; }
.value-chart-bar-label {
  font-size: 8.5px; font-weight: 700; color: var(--white);
  font-variant-numeric: tabular-nums; white-space: nowrap; letter-spacing: -0.1px;
}
/* Откачено обратно на общие var(--green)/var(--danger) — по прямому
   репорту пользователя (2026-08-19): предыдущая более яркая, "своя" пара
   цветов оказалась ярче, чем нужно — попросил сделать зелёный таким же,
   как у выделенного элемента на скриншоте (переключатель "По поставщику",
   .seg-toggle-btn.active — который и есть var(--green)), и подобрать
   красный в пару по яркости. var(--danger) — тот же самый приглушённый
   красный, уже используемый рядом (цена закупки на карточке, бейджи
   минус-маржи) — та же логика "не одна яркая деталь среди приглушённого
   интерфейса", просто теперь тем же токеном, что и everywhere else. */
.value-chart-bar.liquid { background: var(--green); }
.value-chart-bar.illiquid { background: var(--danger); }
/* Скругление у КАЖДОГО столбика сверху, независимо от высоты — по
   прямому запросу пользователя (2026-08-19, "пусть они все будут с
   закруглёнными углами"). Раньше скругление было только на самом
   track (overflow:hidden) — реально доставалось только самому высокому
   столбику окна, у всех остальных верх был плоским. :last-child — в
   column-reverse это визуально ВЕРХНИЙ сегмент стека (или единственный
   столбик, если разбивка неизвестна). */
.value-chart-bar:last-child { border-radius: var(--r-sm) var(--r-sm) 0 0; }
/* Исходные, более светлые цвета штриховки — по прямому репорту
   пользователя (2026-08-19, "верни изначальные цвета штриховки, эти
   слишком тёмные"). */
.value-chart-bar.unknown-split {
  background: repeating-linear-gradient(135deg, var(--lgray) 0 6px, var(--photobg) 6px 12px);
}
/* График "Продажи" по дням (дашборд продаж + цель 10 млн, 2026-08-24) —
   тот же .value-chart-bar, сплошной зелёный (не заштрихован — сама
   выручка ДОСТОВЕРНА даже за текущий месяц, см. src/sales_totals.py). */
.value-chart-bar.revenue { background: var(--green); }
/* График "Продажи" по месяцам — ТРИ вложенных (не аддитивных) сегмента на
   столбик, перекрашено по прямому запросу пользователя (2026-08-25):
   красный — общая выручка, жёлтый — валовая маржа, зелёный — чистая
   прибыль (см. management/app.py:_build_monthly_sales_chart — сегменты
   считаются как разница уровней, поэтому визуально складываются в стек,
   хотя по смыслу каждый цвет отмечает СВОЙ уровень, не долю выручки). */
.value-chart-bar.total-revenue { background: var(--danger); }
.value-chart-bar.gross-profit { background: var(--warning); }
.value-chart-bar.net-profit { background: var(--green); }
.value-chart-legend { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 14px; font-size: 11.5px; color: var(--gray); margin-top: 10px; }
/* Самокритика от 2026-08-25 (по прямому репорту пользователя, скриншот:
   при переносе на новую строку точка цвета оставалась на прежней строке, а
   подпись, которую она объясняет, "уезжала" отдельно вниз) — точка и текст
   теперь ОДИН inline-flex элемент (.legend-item), перенос переносит пару
   целиком, не рвёт её. gap на .value-chart-legend (было margin-left на
   каждой .dot) — раньше это разваливалось бы: margin-left между .dot и
   ТЕКСТОМ внутри одного .legend-item создавал бы лишний отступ там, где он
   не нужен, gap между .legend-item-ами решает то же самое чище. */
.legend-item { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.value-chart-legend .dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; flex: 0 0 auto; }
.value-chart-legend .dot.liquid { background: var(--green); }
.value-chart-legend .dot.illiquid { background: var(--danger); }
.value-chart-legend .dot.unknown-split { background: repeating-linear-gradient(135deg, var(--lgray) 0 3px, var(--photobg) 3px 6px); }
.value-chart-legend .dot.total-revenue { background: var(--danger); }
.value-chart-legend .dot.gross-profit { background: var(--warning); }
.value-chart-legend .dot.net-profit { background: var(--green); }
/* График "По месяцам" урезанной роли — по прямому запросу пользователя
   (2026-08-27): цвет столбика по абсолютному порогу выручки, не маржа/
   прибыль (тех данных в урезанном снимке нет вообще). */
.value-chart-bar.sales-bar-green { background: var(--green); }
.value-chart-bar.sales-bar-yellow { background: var(--warning); }
.value-chart-bar.sales-bar-red { background: var(--danger); }
.value-chart-legend .dot.sales-bar-green { background: var(--green); }
.value-chart-legend .dot.sales-bar-yellow { background: var(--warning); }
.value-chart-legend .dot.sales-bar-red { background: var(--danger); }
/* Почему часть столбиков вообще без деления на ликвид/неликвид — раньше
   это объяснялось только всплывающей подсказкой при наведении (title),
   которая на телефоне недоступна и легко остаётся незамеченной — по
   прямому репорту пользователя (2026-08-19, "почему все остальные месяцы
   серые?"). Отдельной строкой, всегда видно, без наведения. */
.value-chart-legend-note { display: block; width: 100%; margin-top: 4px; font-size: 11px; color: var(--lgray); line-height: 1.5; }


/* ===== CRM: единая стилистика, как в админке витрины (2026-09-16) ===========
   Пользователю понравилось, как сделаны настройки витрины для клиентов:
   одно скругление на всё, поля-«подложки» без рамок, системные галочки,
   сгруппированные строки со светлыми разделителями — то, что на iOS называют
   inset grouped list. Здесь тот же набор, но только для CRM: каталог и
   аналитика Кабинета не трогаются. */
:root {
  --r-crm: 18px;          /* карточка, поле, кнопка-«мини» — одно скругление */
  --r-crm-in: 12px;       /* вложенное: картинка, превью, лента */
  --crm-field: #eceef1;   /* подложка всего, куда можно вводить или нажимать */
  --crm-field-focus: #ffffff;
  --crm-sep: #e6e8ec;     /* разделитель строк внутри группы */
}
.crm-item, .crm-order, .crm-block, .crm-team-card, .crm-card, .crm-conn-row,
.crm-qa, .crm-demand, .crm-card-group, .crm-tree { border-radius: var(--r-crm); }
.crm-feed, .crm-ophoto, .crm-img, .crm-promo-img, .crm-task-photo, .crm-result,
.crm-preview, .crm-next, .crm-ev-text, .crm-promo-text, .crm-viewer-doc,
.crm-plan-bar { border-radius: var(--r-crm-in); }
/* У пузыря переписки «хвост» остаётся мелким — иначе он перестаёт читаться
   как указатель на говорящего. */
.crm-bubble { border-radius: var(--r-crm) var(--r-crm) var(--r-crm) 5px; }
.crm-msg.me .crm-bubble { border-radius: var(--r-crm) var(--r-crm) 5px var(--r-crm); }

/* Поля ввода: подложка вместо рамки, фокус поднимает на белый (как в витрине). */
.crm-search, .crm-select, .crm-input, .crm-section input[type="search"],
.crm-section input[type="text"] {
  border-radius: var(--r-crm); border: 1px solid transparent; background: var(--crm-field);
  padding: 12px 14px; font-size: 16px; font-family: inherit; width: 100%; box-sizing: border-box;
  -webkit-appearance: none; appearance: none; transition: background .12s, border-color .12s;
}
.crm-search:focus, .crm-select:focus, .crm-input:focus,
.crm-section input[type="search"]:focus, .crm-section input[type="text"]:focus {
  outline: none; background: var(--crm-field-focus); border-color: var(--green);
}

/* Сегмент-контрол: капсула с подвижной активной кнопкой — как переключатель
   «Товары / Разделы» в витрине. */
.crm-seg-row { display: flex; background: var(--crm-field); border-radius: var(--r-pill); padding: 3px; gap: 2px; margin: 0 0 12px; }
.crm-seg { flex: 1; border: none; background: none; color: var(--gray); padding: 8px 10px; border-radius: var(--r-pill);
  font-size: 13px; font-weight: 600; font-family: inherit; cursor: pointer; transition: background .15s, color .15s; }
.crm-seg.active { background: var(--white); color: var(--ink, #1d1d1f); box-shadow: 0 1px 3px rgba(0,0,0,.12); }

/* Второстепенное действие в шапке группы. */
.crm-mini { background: var(--crm-field); border: none; border-radius: var(--r-crm); color: var(--green-dark);
  font-size: 12.5px; font-weight: 600; font-family: inherit; padding: 7px 11px; cursor: pointer; flex: none; }
.crm-mini:disabled { opacity: .5; }

/* Группа строк: одна карточка, внутри строки со светлыми разделителями. */
.crm-card-group { background: var(--white); border: 1px solid var(--border); overflow: hidden; margin-bottom: 12px; }
.crm-li { display: flex; align-items: center; gap: 10px; padding: 11px 12px; font-size: 14px; }
.crm-li + .crm-li, .crm-tree-node + .crm-tree-node > .crm-li,
.crm-tree-kids > .crm-li:first-child, .crm-tree-kids > .crm-tree-node:first-child > .crm-li { border-top: 1px solid var(--crm-sep); }
.crm-li-head { font-weight: 600; background: var(--white); }
.crm-li-title { flex: 1; min-width: 0; font-size: 14px; font-weight: 700; }
.crm-li-hint { color: var(--gray); font-size: 12.5px; line-height: 1.45; display: block; }
.crm-li-tap { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; cursor: pointer; }
.crm-li-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.crm-li-name { overflow-wrap: anywhere; }
.crm-li-sub { color: var(--gray); font-size: 12px; }
.crm-li-price, .crm-li-n { color: var(--gray); font-size: 12.5px; font-variant-numeric: tabular-nums; flex: none; }
.crm-li-price { color: var(--ink, #1d1d1f); font-weight: 600; }
/* «от 5 кор.» под ценой — самая низкая ступень крупного опта (2026-09-19). */
.crm-li-price-note { display: block; font-size: 11px; font-weight: 500; color: var(--gray); text-align: right; white-space: nowrap; }
.crm-li-on { background: var(--green-bg, #f2fbf6); }
.crm-li-done .crm-li-name { color: var(--gray); }
.crm-li-eye { flex: none; width: 34px; height: 34px; border-radius: 50%; background: var(--crm-field);
  display: inline-flex; align-items: center; justify-content: center; text-decoration: none; color: var(--gray); }
.crm-li-link { width: 100%; background: none; border: 0; font: inherit; text-align: left; cursor: pointer; }
.crm-li-chev { flex: none; width: 32px; height: 32px; border: 0; background: none; color: var(--gray);
  font-size: 20px; line-height: 1; cursor: pointer; transition: transform .15s; }
.crm-li-chev.open { transform: rotate(90deg); color: var(--green-dark); }
/* Раскрытие узла дерева (26.09): количество и стрелка — одна широкая зона
   на всю высоту строки, а не маленькая стрелка. */
.crm-li-open { flex: none; align-self: stretch; display: inline-flex; align-items: center; justify-content: flex-end; gap: 4px;
  min-width: 76px; margin: -10px -12px -10px 0; padding: 0 12px 0 10px; border: 0; background: none; font: inherit; cursor: pointer; }
.crm-li-open .crm-li-chev { display: inline-flex; align-items: center; justify-content: center; }
.crm-li-group .crm-li-grouptap { border: 0; background: none; font: inherit; text-align: left; padding: 0; color: var(--gray); }
.crm-li-group .crm-li-name { font-weight: 600; color: var(--gray); }

/* Галочки — системные, зелёные: ровно как в витрине (input, а не рисунок). */
.crm-box { flex: none; width: 23px; height: 23px; margin: 0; accent-color: var(--green); cursor: pointer; }
.crm-box.some { opacity: .55; }
.crm-box:disabled { cursor: default; opacity: .45; }

/* Дерево разделов промо */
.crm-tree { background: var(--white); border: 1px solid var(--border); overflow: hidden; }
.crm-tree-kids { background: #fbfbfd; }
.crm-tree-kids .crm-tree-kids { background: var(--white); }

/* Кнопка публикации встаёт НА МЕСТО кнопки «Наверх» (запрос пользователя
   2026-09-16), а «Наверх» на это время поднимается над ней. */
.crm-fab-bar { position: fixed; right: 16px; bottom: 16px; z-index: var(--z-header); display: flex; align-items: center; gap: 8px; }
.crm-fab { display: inline-flex; align-items: center; gap: 8px; border: 0; border-radius: var(--r-pill);
  background: var(--green); color: var(--white); font: inherit; font-size: 14px; font-weight: 600;
  padding: 12px 18px; cursor: pointer; box-shadow: 0 6px 20px rgba(26,162,96,.35); }
.crm-fab:disabled { opacity: .6; }
.crm-fab-clear { width: 40px; height: 40px; border: 0; border-radius: 50%; background: var(--white); color: var(--gray);
  font-size: 20px; line-height: 1; cursor: pointer; box-shadow: 0 4px 16px rgba(20,20,20,.2); }
body.crm-fab-on .fab-stack { bottom: 74px; }
@media (min-width: 900px) {
  body.crm-fab-on .scroll-top-toggle { bottom: 74px; }
}
/* «+ Каждый день» (29.09): второй кнопкой НАД строкой публикации — в одну
   строку на телефоне не помещается. Панель выше — «Наверх» поднимается выше. */
.crm-fab-bar.crm-fab-2 { flex-direction: column; align-items: flex-end; }
.crm-fab-row { display: flex; align-items: center; gap: 8px; }
.crm-fab.crm-fab-alt { background: var(--white); color: var(--green-dark); border: 1.5px solid var(--green);
  font-size: 13.5px; padding: 9px 16px; box-shadow: 0 4px 16px rgba(20,20,20,.16); }
body.crm-fab-on.crm-fab-tall .fab-stack { bottom: 122px; }
@media (min-width: 900px) {
  body.crm-fab-on.crm-fab-tall .scroll-top-toggle { bottom: 122px; }
}
/* Переключатель «Каждый день» в «Опубликовано» (29.09) — как в iOS. */
.crm-switch { display: inline-flex; align-items: center; gap: 8px; margin-top: 6px; font-size: 13px;
  color: var(--ink); cursor: pointer; user-select: none; align-self: flex-start; }
.crm-switch input { -webkit-appearance: none; appearance: none; flex: none; width: 40px; height: 24px; margin: 0;
  border-radius: 12px; background: #d9d9de; position: relative; cursor: pointer; transition: background .2s; }
.crm-switch input::after { content: ""; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px;
  border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.28); transition: transform .2s; }
.crm-switch input:checked { background: var(--green); }
.crm-switch input:checked::after { transform: translateX(16px); }
.crm-switch input:disabled { opacity: .6; }
/* «Каждый день»: пауза и предупреждения — заметнее обычной подсказки. */
.crm-li-hint.crm-daily-paused { color: #9a6a0c; background: var(--warning-bg, #fff6e0); }
/* «Статусы → Реклама» (29.09, crm_ads.py). */
.crm-ads-form-body { display: grid; gap: 10px; padding: 12px; }
.crm-ads-pick { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.crm-ads-preview { width: 96px; height: 96px; object-fit: cover; border-radius: 10px; border: 1px solid var(--border); }
.crm-ads-text { width: 100%; box-sizing: border-box; border: 1px solid var(--border); border-radius: var(--r-control);
  padding: 10px 12px; font: inherit; font-size: 16px; line-height: 1.4; resize: vertical; background: var(--white); }
.crm-ads-add { justify-self: start; box-shadow: none; }
.crm-ads-item { align-items: flex-start; }
.crm-ads-thumb { flex: none; width: 72px; height: 72px; border-radius: 10px; overflow: hidden; border: 1px solid var(--border);
  background: var(--crm-field); display: flex; align-items: center; justify-content: center; font-size: 12px; color: var(--gray); }
.crm-ads-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.crm-ads-textview { white-space: pre-wrap; overflow-wrap: anywhere; font-size: 13px; line-height: 1.4; color: var(--ink);
  display: -webkit-box; -webkit-line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden; }
.crm-ads-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.crm-promo-queue { border-color: var(--green-border); }
/* Папка внутри пачки поступления (бренд или раздел 1С): не вторая карточка,
   а подзаголовок со своей кнопкой «Выбрать» (2026-09-20). */
.crm-promo-folder { border: 0; border-radius: 0; margin: 0; background: none; box-shadow: none; }
.crm-li-sub-head { background: var(--crm-field); border-top: 1px solid var(--crm-sep); }
.crm-li-sub-head .crm-li-title { display: flex; flex-direction: column; gap: 1px; font-size: 13.5px; }
.crm-li-sub-head .crm-li-sub { font-size: 11.5px; color: var(--gray); font-weight: 500; }

/* Свёрнутые блоки («Выбрать из каталога», «Опубликованные статусы»): нативный
   details, чтобы работало и без JS. */
.crm-fold > summary { list-style: none; cursor: pointer; }
.crm-fold > summary::-webkit-details-marker { display: none; }
.crm-fold-head::after { content: "›"; color: var(--gray); font-size: 20px; line-height: 1; transition: transform .15s; }
.crm-fold[open] > .crm-fold-head::after { transform: rotate(90deg); }
.crm-fold[open] > .crm-fold-head { border-bottom: 1px solid var(--crm-sep); }
.crm-fold-body > .crm-seg-row { margin: 10px 12px; }
.crm-fold-body > .crm-tree { border: 0; border-radius: 0; }

/* Состояние публикации: зелёная точка — статус висит, красная — снят. */
.crm-state-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--gray); align-self: flex-start; margin-top: 6px; }
.crm-state-dot.live { background: var(--green); }
.crm-state-dot.gone { background: #d93025; }
.crm-state-dot.err { background: var(--warning, #f0a000); }
.crm-stat-link { border: 0; background: none; padding: 0; font: inherit; font-size: 12px; color: var(--link-blue); cursor: pointer; }
.crm-li-stat { color: var(--gray); }
.crm-mini-danger { color: #d93025; }
.crm-stat-box { padding: 4px 12px 12px; border-top: 1px solid var(--crm-sep); }
.crm-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(92px, 1fr)); gap: 8px; margin: 8px 0; }
.crm-stat-cell { background: var(--crm-field); border-radius: var(--r-crm-in); padding: 8px 10px; }
.crm-stat-v { display: block; font-size: 17px; font-weight: 700; font-variant-numeric: tabular-nums; }
.crm-stat-l { display: block; font-size: 11px; color: var(--gray); line-height: 1.3; }
.crm-stat-clients { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }

/* «Выбрать всё» — нейтральная, а не зелёная: зелёный в CRM значит «сделано». */
.crm-mini { color: #4a4f57; }

/* «Команда»: цифра, за которой стоят сообщения, — кнопка. Синей ссылки
   «подробный разбор» больше нет (2026-09-16), вместо неё обычная строка. */
.crm-metric-tap { border: 0; background: none; padding: 0; font: inherit; text-align: left; cursor: pointer; }
.crm-metric-tap:active { opacity: .6; }
.crm-metric-tap .crm-metric-v { text-decoration: underline; text-decoration-color: var(--border); text-underline-offset: 3px; }
.crm-team-more { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%;
  margin-top: 10px; padding: 10px 0 0; border: 0; border-top: 1px solid var(--crm-sep); background: none;
  font: inherit; font-size: 13px; color: var(--gray); text-align: left; cursor: pointer; }
.crm-tap { cursor: pointer; }
/* На выбранной (зелёной) строке кнопка картинки белая — как на iOS. */
.crm-li-on .crm-li-eye { background: var(--white); color: var(--green-dark); box-shadow: 0 1px 4px rgba(20,20,20,.18); }

/* ===== Переписка как в WhatsApp на iOS (2026-09-16) =========================
   Просьба пользователя: «в идеале UX/UI полностью идентичный WhatsApp iOS».
   Обои, белый пузырь клиента слева с хвостиком, зелёный наш справа, время
   внутри пузыря, дата «пилюлей». Цветные подсветки «упомянуто в разборе»
   убраны: они мешали читать диалог. */
.crm-feed {
  /* Ровные обои без «крапинок»: две radial-gradient-точки, которыми я
     изображал узор WhatsApp, читались как белый мусор на фоне (репорт
     пользователя 2026-09-17). Настоящие обои — картинка; подделка точками
     хуже, чем чистый цвет. */
  background: #efe7de;
  gap: 2px; padding: 10px 8px; max-height: 66vh;
}
.crm-day { background: rgba(255,255,255,.92); border: 0; color: #54656f; font-size: 12px; font-weight: 500;
  border-radius: var(--r-pill); padding: 4px 12px; margin: 10px auto 8px; box-shadow: 0 1px 1px rgba(0,0,0,.08); }
.crm-msg { margin: 1px 0; }
.crm-bubble { position: relative; max-width: 80%; background: var(--white); border: 0;
  border-radius: 9px; padding: 6px 9px 5px; font-size: 14.5px; line-height: 1.38; color: #111b21;
  box-shadow: 0 1px 1px rgba(11,20,26,.13); }
.crm-msg.me .crm-bubble { background: #d9fdd3; border: 0; }
/* Хвостик рисуем сами — как в WhatsApp у ПЕРВОГО сообщения серии. */
.crm-msg:not(.me) + .crm-msg:not(.me) .crm-bubble, .crm-msg.me + .crm-msg.me .crm-bubble { border-radius: 9px; }
.crm-msg:not(.me) .crm-bubble { border-top-left-radius: 2px; }
.crm-msg.me .crm-bubble { border-top-right-radius: 2px; }
.crm-bubble-body { display: inline; }
/* Время внутри пузыря справа, текст его обтекает — приём самого WhatsApp. */
.crm-meta { float: right; margin: 6px -2px -2px 8px; font-size: 11px; color: #667781; white-space: nowrap; }
.crm-msg.me .crm-meta { color: #4a7a52; }
.crm-bubble::after { content: ""; display: block; clear: both; }
.crm-flash .crm-bubble { animation: crm-flash 1.6s ease-out; }
@keyframes crm-flash {
  0% { box-shadow: 0 0 0 3px rgba(26,162,96,.55); background: #fff6cc; }
  60% { box-shadow: 0 0 0 3px rgba(26,162,96,.25); }
  100% { box-shadow: 0 1px 1px rgba(11,20,26,.13); }
}
.crm-msg.me.crm-flash .crm-bubble { animation: crm-flash-me 1.6s ease-out; }
@keyframes crm-flash-me {
  0% { box-shadow: 0 0 0 3px rgba(26,162,96,.55); background: #eaffd8; }
  100% { box-shadow: 0 1px 1px rgba(11,20,26,.13); background: #d9fdd3; }
}
/* Цитата: на что отвечают. Полоска, автор, начало текста — как в WhatsApp. */
.crm-quote { display: block; width: 100%; text-align: left; border: 0; border-left: 4px solid var(--green);
  background: rgba(0,0,0,.05); border-radius: 6px; padding: 5px 8px; margin: 0 0 4px; cursor: pointer; font: inherit; }
.crm-quote.me { border-left-color: #53bdeb; }
.crm-quote-who { display: block; font-size: 12.5px; font-weight: 600; color: var(--green-dark); }
.crm-quote.me .crm-quote-who { color: #1f7d9e; }
.crm-quote-text { display: block; font-size: 13px; color: #54656f; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-transcript { margin-top: 4px; font-size: 13.5px; color: #3b4a54; font-style: normal; }
.crm-reactions { position: absolute; bottom: -10px; left: 8px; background: var(--white); border-radius: var(--r-pill);
  padding: 1px 6px; font-size: 12px; box-shadow: 0 1px 2px rgba(11,20,26,.2); margin: 0; }
.crm-msg.me .crm-reactions { left: auto; right: 8px; }
.crm-msg-sys { justify-content: center; }
.crm-msg-sys .crm-bubble { background: rgba(255,255,255,.9); font-size: 13px; color: #54656f; max-width: 90%; border-radius: var(--r-crm-in); }
.crm-feed-switch { color: #54656f; margin: 12px 0 6px; }
.crm-feed-switch::before, .crm-feed-switch::after { background: rgba(0,0,0,.12); }
.crm-img { border-radius: 6px; }

/* Карточка заказа: реализация под номером и заявка прямо в этапе сборки
   (запросы пользователя 2026-09-16). */
.crm-order-ship { font-size: 13px; color: var(--ink); margin-top: 2px; }
.crm-order-ship b { font-variant-numeric: tabular-nums; }
.crm-order-ship-none { color: var(--gray); }
.crm-ostep-note { background: var(--crm-field); border-radius: var(--r-crm-in); padding: 10px 12px; margin: 0 0 12px; }
.crm-ostep-note-h { font-size: 12px; font-weight: 600; color: var(--gray); margin-bottom: 4px; }
.crm-ostep-note .crm-ev-text { background: none; padding: 0; margin: 0; font-size: 13.5px; white-space: pre-wrap; }

/* ---------- Раздел «Сайт» в Аналитике (пересобран 2026-09-19) ----------
   Язык — карточки Аналитики (.warehouse-panel), один зелёный для всех меток
   данных, цифры табличным шрифтом. overflow-wrap: break-word, а не
   anywhere, как у .crm-section: «anywhere» урезает минимальную ширину
   колонок, и слова рвались посреди буквы — это и была «сломанная вёрстка
   по текстам». */
.site-an { overflow-wrap: break-word; padding-top: 0; transition: opacity .15s; }
.site-an.sa-busy { opacity: .55; pointer-events: none; }
.sa-period { max-width: 360px; }
.sa-note { margin: -4px 0 14px !important; }
.sa-card { background: var(--white); border: 1px solid var(--border); border-radius: var(--r-card);
  box-shadow: 0 1px 2px rgba(20, 20, 20, .05); padding: 16px 16px 14px; margin: 0 0 12px; min-width: 0; }
.sa-h { font-size: 15px; font-weight: 700; margin: 0 0 10px; display: flex; align-items: baseline; gap: 8px; }
.sa-h-n { font-size: 13px; font-weight: 600; color: var(--gray); }
.sa-card p.hint { margin: -4px 0 12px; }
.sa-cols { display: grid; grid-template-columns: 1fr; gap: 0 12px; }
@media (min-width: 720px) { .sa-cols { grid-template-columns: 1fr 1fr; } }

.sa-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 0 0 12px; }
@media (min-width: 720px) { .sa-tiles { grid-template-columns: repeat(4, 1fr); gap: 12px; } }
.sa-tile { background: var(--white); border: 1px solid var(--border); border-radius: var(--r-card);
  box-shadow: 0 1px 2px rgba(20, 20, 20, .05); padding: 12px 14px; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sa-tile-l { font-size: 12.5px; color: var(--gray); font-weight: 500; }
.sa-tile-v { font-size: 24px; font-weight: 700; line-height: 1.15; font-variant-numeric: tabular-nums;
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; }
.sa-tile-of { font-size: 14px; font-weight: 600; color: var(--gray); }
.sa-tile-s { font-size: 12px; color: var(--gray); line-height: 1.35; }
.sa-delta { font-size: 12px; font-weight: 600; color: var(--gray); white-space: nowrap; }
.sa-delta.sa-up { color: var(--green-dark); }
.sa-delta.sa-down { color: var(--danger); }

.sa-chart { position: relative; padding-left: 36px; }
.sa-plot { position: relative; }
.sa-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.sa-grid { stroke: var(--border); stroke-width: 1; vector-effect: non-scaling-stroke; }
.sa-grid.sa-base { stroke: var(--lgray); }
.sa-bar { fill: var(--green); transition: fill .1s; }
.sa-bar.sa-bar-on { fill: var(--logo-green); }
.sa-ylab span { position: absolute; right: calc(100% + 6px); transform: translateY(-50%); font-size: 10.5px; color: var(--gray);
  font-variant-numeric: tabular-nums; line-height: 1; white-space: nowrap; }
.sa-xlab, .sa-marks { position: relative; height: 16px; }
.sa-xlab span, .sa-marks span { position: absolute; transform: translateX(-50%); font-size: 10.5px; color: var(--gray);
  white-space: nowrap; font-variant-numeric: tabular-nums; top: 2px; }
.sa-marks span { font-weight: 700; color: var(--green-dark); }
.sa-tip { position: absolute; top: 0; z-index: 3; background: var(--ink); color: #fff; border-radius: 10px;
  padding: 7px 10px; font-size: 12px; line-height: 1.4; pointer-events: none; display: flex; flex-direction: column;
  white-space: nowrap; box-shadow: 0 4px 14px rgba(0, 0, 0, .18); }
.sa-tip[hidden] { display: none; }
.sa-tip b { font-weight: 700; }
.sa-legend { display: flex; align-items: center; gap: 6px; margin: 6px 0 0 !important; }
.sa-key { width: 10px; height: 10px; border-radius: 3px; background: var(--green); flex: none; }

.sa-hbars, .sa-funnel { display: flex; flex-direction: column; gap: 10px; }
.sa-hbar-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: 13.5px; }
.sa-hbar-l { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sa-hbar-head b { font-variant-numeric: tabular-nums; flex: none; }
.sa-hbar-track { display: block; height: 6px; background: var(--crm-field); border-radius: 3px; margin-top: 4px; overflow: hidden; }
.sa-hbar-track i { display: block; height: 100%; background: var(--green); border-radius: 3px; }
.sa-hbar-sub { font-size: 12px; color: var(--gray); margin-top: 3px; }
.sa-funnel .sa-hbar-track { height: 10px; border-radius: 5px; }
.sa-funnel .sa-hbar-track i { border-radius: 5px; }

.sa-search { margin: 0 0 8px; }
.sa-list { display: flex; flex-direction: column; }
.sa-row { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; background: none; border: 0;
  border-top: 1px solid var(--crm-sep); padding: 11px 0; font: inherit; color: inherit; cursor: pointer; }
.sa-row:first-child { border-top: 0; }
.sa-row:hover .sa-row-title b { color: var(--green-dark); }
.sa-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sa-row-title { display: flex; align-items: center; gap: 6px; font-size: 14.5px; min-width: 0; }
.sa-row-title b { font-weight: 600; min-width: 0; }
.sa-row-sub { font-size: 12.5px; color: var(--gray); line-height: 1.4; }
.sa-row .crm-li-chev { width: 20px; height: auto; }
.sa-abc { flex: none; font-size: 10.5px; font-weight: 700; border-radius: 5px; padding: 1px 5px; background: var(--crm-field); color: var(--gray); }
.sa-abc-a { background: var(--green-bg); color: var(--green-dark); }
.sa-pills { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 2px; }
.sa-pill { font-size: 11.5px; font-weight: 600; border-radius: var(--r-pill); padding: 3px 9px; background: var(--crm-field); color: var(--ink); }
.sa-pill-ok { background: var(--green-bg); color: var(--green-dark); }
.sa-pill-warn { background: var(--warning-bg); color: #8a5a00; }
.sa-more { display: block; width: 100%; margin-top: 6px; border: 0; background: var(--crm-field); border-radius: var(--r-crm);
  padding: 11px; font: inherit; font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; }

.sa-prods { display: flex; flex-direction: column; gap: 10px; }
.sa-prod { display: flex; align-items: center; gap: 10px; min-width: 0; }
.sa-thumb { flex: none; width: 46px; height: 46px; border-radius: 10px; background: var(--photobg); overflow: hidden; }
.sa-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.sa-prod-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.sa-prod-name { font-size: 13.5px; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.sa-prod-sub { font-size: 11.5px; color: var(--gray); }
.sa-oos { color: var(--danger); }
.sa-prod-n { flex: none; font-size: 14px; font-variant-numeric: tabular-nums; min-width: 24px; text-align: right; }

/* ---------- Главная CRM: «Пульс месяца» / «Мой месяц» (2026-09-19) ----------
   Над «Главным сегодня»: сначала «успеваем ли к цели», потом дела. */
.crm-pulse { margin: 0 0 16px; }
.crm-pulse-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 2px 0 10px; }
.crm-pulse-head h3 { margin: 0; font-size: 17px; }
.crm-ptiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 10px; }
@media (min-width: 760px) { .crm-ptiles { grid-template-columns: repeat(3, 1fr); } }
.crm-ptile { background: var(--white); border: 1px solid var(--border); border-radius: var(--r-crm); padding: 11px 13px;
  min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.crm-ptile[role="button"] { cursor: pointer; }
.crm-ptile[data-mm].on { border-color: var(--green); background: var(--green-bg); }
.crm-mm-detail { margin-top: 10px; }
.crm-ptile[role="button"]:hover { border-color: var(--green-border); }
.crm-ptile-l { font-size: 12.5px; color: var(--gray); font-weight: 500; }
.crm-ptile-v { font-size: 21px; font-weight: 700; line-height: 1.15; font-variant-numeric: tabular-nums; }
.crm-ptile-s { font-size: 12px; color: var(--gray); line-height: 1.35; }
.crm-up { color: var(--green-dark); font-weight: 600; }
.crm-down { color: var(--danger); font-weight: 600; }
.crm-pbar { height: 5px; background: var(--crm-field); border-radius: 3px; overflow: hidden; margin-top: 5px; }
.crm-pbar i { display: block; height: 100%; background: var(--green); border-radius: 3px; }
.crm-pulse-risk { margin-bottom: 10px; }
.crm-prow { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; background: none; border: 0;
  border-top: 1px solid var(--crm-sep); padding: 11px 14px; font: inherit; color: inherit; cursor: pointer; }
.crm-prow-name { flex: 0 0 34%; min-width: 0; display: flex; flex-direction: column; gap: 1px; font-size: 14px; }
.crm-prow-name .hint { font-size: 12px; }
.crm-prow-cells { flex: 1; min-width: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(62px, 1fr)); gap: 4px 8px; }
.crm-prow-cells span { display: flex; flex-direction: column; font-size: 13px; }
.crm-prow-cells b { font-variant-numeric: tabular-nums; }
.crm-prow-cells i { font-style: normal; font-size: 11px; color: var(--gray); }
.crm-prow .crm-li-chev { width: 18px; height: auto; flex: none; }
@media (max-width: 560px) {
  .crm-prow { flex-wrap: wrap; }
  .crm-prow-name { flex: 1 1 0; }
  .crm-prow .crm-li-chev { order: 2; }
  .crm-prow-cells { flex-basis: 100%; order: 3; grid-template-columns: repeat(3, 1fr); }
}
.crm-bonus-tag { flex: none; font-size: 12px; font-weight: 700; color: var(--green-dark); background: var(--green-bg);
  border-radius: var(--r-pill); padding: 3px 9px; align-self: center; white-space: nowrap; }
.crm-item-head .crm-bonus-tag { padding: 2px 8px; }
/* Плашка «+500 ₽» в карточке клиента (27.09). */
.crm-bonus-bar { display: flex; gap: 10px; align-items: flex-start; margin: 8px 0 0; padding: 9px 12px;
  background: var(--green-bg); border-radius: var(--r-crm-in); font-size: 13px; line-height: 1.4; }
.crm-bonus-bar .crm-bonus-tag { background: var(--surface, #fff); }
.crm-bonus-bar > span:not(.crm-bonus-tag) { flex: 1; min-width: 0; }
.crm-bonus-bar .crm-btn { flex: none; }
.crm-bonus-tag-pool { color: var(--cr-amber, #9a6a0c); background: var(--cr-amber-bg, #fdf3e3); }

/* «Клиенты → +500 ₽» (27.09): пул / в работе. */
.crm-b5-head { padding-bottom: 12px; }
.crm-b5-title { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.crm-b5-title h3 { margin: 0; }
.crm-b5-month { font-size: 15px; margin-bottom: 6px; }
.crm-b5-month > summary { cursor: pointer; list-style: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.crm-b5-month > summary::-webkit-details-marker { display: none; }
.crm-b5-month > summary::after { content: "›"; color: var(--cr-gray, #86868b); font-size: 20px; transition: transform 0.2s; }
.crm-b5-month[open] > summary::after { transform: rotate(90deg); }
.crm-b5-month-t { display: flex; flex-direction: column; gap: 2px; }
.crm-b5-month .hint { font-size: 13px; }
.crm-b5-segs { margin: 10px 0 6px; }
.crm-b5-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.crm-b5-table th { text-align: left; font-size: 12px; font-weight: 600; color: var(--cr-gray, #86868b); padding: 6px 6px 6px 0; border-bottom: 1px solid var(--border); }
.crm-b5-table td { padding: 8px 6px 8px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.crm-b5-table tr[data-open-client] { cursor: pointer; }
.crm-b5-table tr[data-open-client]:hover td { background: var(--cr-line, rgba(20, 20, 20, 0.04)); }
.crm-b5-table .num { text-align: right; white-space: nowrap; }
.crm-b5-table .hint { font-size: 12px; }
.crm-b5-kind { white-space: nowrap; }

/* «Клиенты → По регионам» (27.09). */
.crm-rg-head h3 { margin: 0 0 4px; }
.crm-rg-trip { margin: 2px 0 6px; font-size: 14px; }
.crm-rg-sum { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 14px; margin-top: 6px; }
.crm-rg-chips { margin: 12px 0; flex-wrap: nowrap; overflow-x: auto; }
.crm-rg-region { margin-bottom: 14px; }
.crm-rg-region > .crm-li-head { flex-wrap: wrap; gap: 4px 10px; }
.crm-rg-seg > summary { cursor: pointer; padding: 10px 16px; border-top: 1px solid var(--border); list-style: none; }
.crm-rg-seg > summary::-webkit-details-marker { display: none; }
.crm-rg-seg-ordered > summary b { color: var(--green-dark); }
.crm-rg-seg-hot > summary b { color: var(--cr-amber, #9a6a0c); }
.crm-rg-row { align-items: flex-start; }
.crm-rg-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; align-items: center; }
.crm-rg-acts .crm-btn-wa { padding: 5px 9px; }
.crm-rg-abc { font-size: 11px; font-weight: 700; color: var(--cr-gray, #86868b); border: 1px solid var(--border);
  border-radius: var(--r-pill); padding: 0 6px; vertical-align: 2px; }
.crm-rg-mark { font-size: 11px; font-weight: 700; border-radius: var(--r-pill); padding: 1px 7px; background: var(--cr-line, #eee); }
.crm-rg-mark-yes { background: var(--green-bg); color: var(--green-dark); }
.crm-rg-mark-later { background: var(--cr-amber-bg, #fdf3e3); color: var(--cr-amber, #9a6a0c); }
.crm-rg-offer { margin-top: 8px; padding: 8px 10px; background: var(--cr-line, rgba(20, 20, 20, 0.04)); border-radius: var(--r-crm-in); font-size: 13px; }
.crm-rg-offer ul { margin: 2px 0 8px; padding: 0; list-style: none; }
.crm-rg-offer li { margin: 3px 0; }
.crm-rg-offer label { display: flex; gap: 8px; align-items: flex-start; cursor: pointer; }
.crm-rg-offer input[type="checkbox"] { margin-top: 2px; flex: none; accent-color: var(--green); }
.crm-rg-sent { font-size: 13px; font-weight: 600; color: var(--green-dark); }
.crm-b5-no { font-size: 12px; color: var(--cr-gray, #86868b); }
.crm-b5-tools .crm-sort-toggle { margin-left: 0; overflow-x: auto; max-width: 100%; }
.crm-b5-how { display: flex; width: 100%; justify-content: space-between; align-items: center; border: 0; background: none;
  padding: 6px 0 0; font: inherit; font-weight: 600; font-size: 15px; color: var(--green-dark); cursor: pointer; text-align: left; }
#crm-rules-bonus { scroll-margin-top: 64px; }
.crm-rules-steps { margin: 4px 0 10px 18px; padding: 0; }
.crm-rules-steps li { margin-bottom: 4px; }
.crm-b5-tabs { display: flex; gap: 4px; padding: 4px; margin: 12px 0; background: var(--cr-line, rgba(20, 20, 20, 0.06));
  border-radius: var(--r-control); }
.crm-b5-tab { flex: 1; border: 0; background: transparent; border-radius: calc(var(--r-control) - 3px); padding: 9px 10px;
  font: inherit; font-size: 15px; font-weight: 600; color: var(--cr-gray, #86868b); cursor: pointer; }
.crm-b5-tab.active { background: var(--cr-surface, #fff); color: var(--cr-ink, #141414); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); }
.crm-b5-tools { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-bottom: 10px; }
.crm-b5-tools .crm-search { flex: 1 1 220px; min-width: 0; }
.crm-b5-limit { margin: 0 0 8px; }
.crm-b5-row { align-items: center; gap: 10px; }
.crm-b5-row > .crm-btn { flex: none; }
.crm-b5-acts { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex: none; }
.crm-b5-hold { background: var(--cr-amber-bg, #fdf3e3); }
.crm-b5-flash { margin: 10px 0 0; padding: 10px 12px; border-radius: var(--r-crm-in); background: var(--green-bg);
  font-size: 14px; line-height: 1.4; }
.crm-b5-row > .crm-btn.crm-btn-sm { padding: 7px 12px; font-size: 13px; white-space: nowrap; }
@media (max-width: 520px) {
  .crm-b5-row:has(.crm-b5-acts) { flex-wrap: wrap; }
  .crm-b5-acts { width: 100%; flex-direction: row; justify-content: space-between; align-items: center; }
  .crm-b5-row > .crm-btn.crm-btn-sm { width: auto; }
}

/* Окно «Зарплата и бонусы» */
.crm-test-note { background: var(--warning-bg); color: #7a5200; border-radius: var(--r-crm-in); padding: 10px 12px; font-size: 13px; line-height: 1.45; margin: 0 0 12px; }
.crm-sal { background: var(--white); border: 1px solid var(--border); border-radius: var(--r-crm); padding: 6px 14px; margin: 0 0 16px; }
.crm-sal-row { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-top: 1px solid var(--crm-sep); font-size: 14px; }
.crm-sal-row:first-child { border-top: 0; }
.crm-sal-row b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.crm-sal-sub { font-size: 12.5px; color: var(--gray); padding: 4px 0 4px 12px; border-top: 0; }
.crm-sal-total { font-size: 16px; font-weight: 700; }
.crm-bonus { border-top: 1px solid var(--crm-sep); padding: 11px 0; }
.crm-bonus-head { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.crm-bonus-head .crm-link-btn { font-size: 14.5px; font-weight: 600; color: var(--ink); text-align: left; }
.crm-bonus-proof { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.crm-bonus-start { text-align: left; border: 0; background: var(--crm-field); border-radius: var(--r-crm-in); padding: 7px 10px;
  font: inherit; font-size: 12.5px; color: var(--ink); cursor: pointer; line-height: 1.4; }
.crm-bonus-who { font-weight: 700; }
.crm-bonus-who-manager, .crm-bonus-who-call { color: var(--green-dark); }
.crm-bonus-who-client { color: #8a5a00; }
.crm-link-danger { color: var(--danger); }
.crm-rules { margin: 4px 0 0; padding-left: 18px; font-size: 13px; line-height: 1.5; }
/* Склад в CRM (приложение склада, 2026-09-22). */
.crm-wh form { display: flex; flex-direction: column; gap: 10px; margin-top: 8px; }
.crm-wh-check { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; margin-right: 12px; }
.crm-wh-check input { width: 20px; height: 20px; accent-color: var(--cr-green-dark, #148a51); }
.crm-wh-new, [data-staff-expenses] { display: flex; flex-direction: column; gap: 8px; margin-top: 14px; }
.crm-wh-link { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.crm-wh-link input { flex: 1 1 220px; }
.crm-table-wrap { overflow-x: auto; margin-top: 8px; }
.crm-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.crm-table th, .crm-table td { text-align: left; padding: 6px 8px; border-top: 1px solid var(--border, #e6e8eb); white-space: nowrap; }
.crm-table th { color: var(--cr-gray, #86868b); font-weight: 600; }
/* «Как получить бонус» и подсказка «кому написать» (2026-09-22). */
.crm-bonus-rules h5 { margin: 12px 0 2px; font-size: 14px; }
.crm-bonus-rules .crm-rules li + li { margin-top: 4px; }
.crm-hint { display: block; margin-top: 2px; font-size: 12px; font-weight: 600; }
.crm-hint-ok { color: var(--cr-green-dark, #148a51); }
.crm-hint-todo { color: var(--cr-amber, #9a6a0c); }
.crm-hint-wait { color: var(--cr-gray, #86868b); }

/* Компактный рейтинг (поиск, источники): полоса — подложкой самой строки. */
.sa-rank { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 3px; }
.sa-rank li { display: flex; justify-content: space-between; gap: 10px; align-items: center; font-size: 13.5px;
  padding: 5px 9px; border-radius: 8px;
  background: linear-gradient(to right, var(--green-bg) var(--w, 0%), transparent var(--w, 0%)); }
.sa-rank li span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sa-rank li b { flex: none; font-variant-numeric: tabular-nums; }
.sa-fpct { font-weight: 500; color: var(--gray); font-size: 12px; margin-left: 4px; }
.sa-fnote { margin: 8px 0 0 !important; }

/* Внутри карточки клиента: подблоки без своих рамок, заголовок поменьше. */
.sa-sub { margin: 14px 0 0; min-width: 0; }
.sa-h5 { margin: 0 0 8px; font-size: 13px; font-weight: 700; color: var(--ink); }
.sa-cols-tight { gap: 0 16px; }
.sa-tiles-card { margin: 4px 0 0; }
.sa-tiles-card .sa-tile { box-shadow: none; background: var(--crm-field); border-color: transparent; padding: 10px 12px; }
.sa-tiles-card .sa-tile-v { font-size: 20px; }
.sa-card-dash { margin-top: 12px; }
.sa-card-dash > summary h4 { margin: 0; }

/* ---------- Вкладка «Витрины»: админка магазинов клиентов (2026-09-20) ----
   Витрины и свои товары открыли всем клиентам, и нужен экран, где видно все
   магазины разом и очередь на проверку товаров. Стилистика — общая с CRM
   (та же подложка, то же скругление), своих цветов и размеров не вводим. */
.crm-shops-nav { margin-bottom: 12px; }
.crm-chip-n-alert { color: var(--danger, #c0392b); font-weight: 700; }
.crm-shops-tools { margin-bottom: 10px; }
.crm-shops-tools .crm-chips { margin-top: 8px; }

/* Строка магазина в списке: слева вывеска и хозяин, справа деньги. */
.crm-shop-row {
  display: flex; align-items: flex-start; gap: 12px; padding: 12px 14px; cursor: pointer;
  background: var(--white); border: 1px solid var(--border); border-radius: var(--r-crm);
  margin-bottom: 8px;
}
.crm-shop-row:active { background: var(--crm-field); }
.crm-shop-main { flex: 1; min-width: 0; }
.crm-shop-main b { font-size: 14.5px; }
.crm-shop-main .hint { overflow-wrap: anywhere; }
.crm-shop-nums { flex: none; text-align: right; display: flex; flex-direction: column; gap: 2px; }
.crm-shop-nums b { font-size: 14.5px; font-variant-numeric: tabular-nums; }
.crm-shop-nums .hint { font-size: 12px; white-space: nowrap; }
/* «Клиенты → Витрины» менеджера (15.10.2026): строка не открывается целиком —
   внутри ссылка на витрину и имя клиента (карточка клиента). */
.crm-shop-row.crm-shop-static { cursor: default; }
.crm-shop-row.crm-shop-static:active { background: var(--white); }

/* «Требует внимания» на обзоре. */
.crm-att-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0; border-top: 1px solid var(--crm-sep); }
.crm-att-row:first-of-type { border-top: none; }
.crm-att-text { flex: 1; min-width: 0; font-size: 14px; }
.crm-att-hot .crm-att-text b { color: var(--danger, #c0392b); }
.crm-att-shops { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

/* Карточка витрины поверх списка. */
.crm-shop-title { font-size: 19px; margin: 0 0 4px; }
.crm-shop-sub { margin-bottom: 10px; overflow-wrap: anywhere; }
.crm-shop-owner { margin-bottom: 12px; font-size: 13.5px; }
.crm-shop-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 14px; }
/* Пауза клиента и «Удалить витрину» (12.10.2026): удаление — последним, за
   чертой, красной ссылкой; окно подтверждения — лист «Документов 1С». */
.crm-shop-paused { margin: -6px 0 12px; color: #7a5200; }
.crm-shop-danger { margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--crm-sep, rgba(20,20,20,.08)); }
.crm-danger-link, .crm-v2 .crm-danger-link, body.crm-ui-v2 .crm-danger-link { color: var(--cr-danger, #c0392b) !important; }
.crm-shop-facts { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 12.5px; color: var(--gray); margin-bottom: 4px; }

/* Очередь модерации: карточки товаров клиентов. Фото крупное — по нему и
   видно, годится карточка на нашем домене или нет. */
.crm-review-head { display: flex; justify-content: flex-end; margin: 10px 0; }
/* По витринам (15.10.2026): шапка витрины с «Выбрать все» только её товаров. */
.crm-review-group { margin-top: 16px; }
.crm-review-group-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 0 2px 8px; }
.crm-review-group-title { min-width: 0; }
.crm-review-group-title b { font-size: 15.5px; overflow-wrap: anywhere; }
.crm-review-group-head > .crm-btn { flex: none; white-space: nowrap; }
.crm-review-grid { display: grid; grid-template-columns: 1fr; gap: 8px; }
@media (min-width: 720px) { .crm-review-grid { grid-template-columns: 1fr 1fr; } }
.crm-own-card {
  position: relative; display: flex; gap: 12px; padding: 12px; cursor: pointer;
  background: var(--white); border: 1px solid var(--border); border-radius: var(--r-crm);
}
.crm-own-card.picked { border-color: var(--green); box-shadow: inset 0 0 0 1px var(--green); }
/* Снял другой человек — менеджеру только посмотреть (15.10.2026). */
.crm-own-card.crm-own-locked { cursor: default; opacity: .75; }
/* Похоже на лекарство / похудение (15.10.2026): красная рамка и плашка с
   рекомендацией снять; выделенная (зелёная) рамка важнее — она ниже. */
.crm-own-card.crm-own-flagged { border-color: #f0c3bd; box-shadow: inset 0 0 0 1px #f0c3bd; }
.crm-own-card.crm-own-flagged.picked { border-color: var(--green); box-shadow: inset 0 0 0 1px var(--green); }
.crm-own-flag { background: #fdecea; color: #8a1c13; border-radius: var(--r-crm-in, 10px); padding: 8px 10px; margin: 2px 0 8px;
  font-size: 12.5px; line-height: 1.45; overflow-wrap: anywhere; }
.crm-own-flag-why { margin-top: 4px; opacity: .85; }
.crm-own-flag .crm-flag-take { margin-top: 8px; min-height: 34px; padding: 7px 14px; font-size: 13px; }
/* Почему сняли (15.10.2026): пункт договора и пояснение — красным под ценой. */
.crm-own-taken { font-size: 12.5px; line-height: 1.4; color: var(--cr-danger, #c0392b); margin: 0 0 4px; overflow-wrap: anywhere; }
/* «Почему снимаете?»: пункты договора строками под палец, пояснение ниже. */
.crm-take-rules { display: flex; flex-direction: column; margin: 2px 0; }
.crm-take-rule { display: flex; align-items: flex-start; gap: 10px; padding: 9px 2px; cursor: pointer;
  border-top: 1px solid var(--cr-line, rgba(20, 20, 20, .07)); font-size: 14px; line-height: 1.35; }
.crm-take-rule:first-child { border-top: 0; }
.crm-take-rule input { flex: none; width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--cr-danger, #c0392b); }
.crm-take-rule > span { display: flex; flex-direction: column; gap: 2px; }
.crm-take-note { display: flex; flex-direction: column; gap: 4px; }
/* 16px — иначе iPhone приближает страницу при вводе. */
.crm-take-note textarea { width: 100%; box-sizing: border-box; font: inherit; font-size: 16px; resize: vertical; }
/* Журнал нарушений в карточке витрины. */
.crm-viol-row { padding: 7px 0; border-top: 1px solid var(--crm-sep, rgba(20, 20, 20, .08)); font-size: 13.5px; line-height: 1.4; overflow-wrap: anywhere; }
.crm-viol-row:first-of-type { border-top: 0; }
/* Чекбокс только рисуется: клик ловит карточка (см. crm.js, reviewCard). */
.crm-own-check { position: absolute; top: 10px; right: 10px; pointer-events: none; }
.crm-own-check input { pointer-events: none; width: 20px; height: 20px; accent-color: var(--green); }
.crm-own-photo {
  flex: none; width: 92px; height: 74px; border-radius: var(--r-crm-in); background: var(--photobg) center/cover no-repeat;
  display: flex; align-items: center; justify-content: center; color: var(--gray); font-size: 11px; text-decoration: none;
}
.crm-own-nophoto { border: 1px dashed var(--border); }
.crm-own-text { flex: 1; min-width: 0; padding-right: 26px; }
.crm-own-text b { font-size: 14px; overflow-wrap: anywhere; }
.crm-own-price { font-weight: 700; font-size: 14px; margin: 2px 0 4px; }
.crm-own-desc { overflow-wrap: anywhere; }
.crm-own-links { display: flex; gap: 12px; margin-top: 6px; font-size: 12.5px; }

/* Панель массового действия — закреплена снизу, как корзина в витрине. */
.crm-review-bar {
  position: sticky; bottom: 0; z-index: 2; display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  margin-top: 12px; padding: 10px 12px; background: var(--white);
  border: 1px solid var(--border); border-radius: var(--r-crm); box-shadow: 0 -2px 12px rgba(0,0,0,.08);
}
.crm-review-bar.hidden { display: none; }
.crm-review-bar > span { font-weight: 700; font-size: 13.5px; margin-right: auto; }
/* В разделах панель — парящая, как кнопка публикации в «Статусах»
   (15.10.2026, поймано проверкой «Клиенты → Витрины»): sticky в CRM не
   работает — overflow-x: hidden у html/body (защита от «резинки» iOS) делает
   body контейнером прокрутки, и панель всегда стояла в самом конце ленты.
   На телефоне — над парящим меню; «наверх», пока что-то выделено, прячем:
   иначе ложится на панель. Внизу ленты — запас, чтобы панель не закрывала
   последние карточки. В карточке магазина (окно) — как было. */
[data-crm-panel] .crm-review-bar {
  position: fixed; left: auto; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: var(--z-header); max-width: calc(100% - 32px); margin: 0;
}
[data-crm-panel] .crm-shops-body:has(.crm-review-bar:not(.hidden)) { padding-bottom: 120px; }
body.crm-page:has([data-crm-panel]:not([hidden]) .crm-review-bar:not(.hidden)) .fab-stack,
body.crm-page:has([data-crm-panel]:not([hidden]) .crm-review-bar:not(.hidden)) .scroll-top-toggle { display: none !important; }
@media (max-width: 700px) {
  body.crm-page.crm-ui-v2 [data-crm-panel] .crm-review-bar {
    left: 12px; right: 12px; max-width: none; bottom: calc(92px + env(safe-area-inset-bottom, 0px));
  }
}
.crm-btn-danger { background: var(--danger, #c0392b); color: #fff; border-color: transparent; }
.sa-orders { display: flex; flex-direction: column; }
.sa-order { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-top: 1px solid var(--crm-sep); font-size: 13.5px; }
.sa-order:first-child { border-top: 0; }
.sa-order-d { flex: none; width: 58px; color: var(--gray); font-variant-numeric: tabular-nums; }
.sa-order .sa-pill { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sa-order-s { margin-left: auto; flex: none; font-variant-numeric: tabular-nums; }

/* Поиск по переписке как в WhatsApp: подсветка + переход по совпадениям. */
/* Отступа слева здесь НЕТ (убран 2026-09-17: «заголовок Переписка съехал
   вправо»). Он стоял под плавающую кнопку «назад», но она перекрывает
   заголовок только когда блок прижат к самому верху, а переход по ссылке и
   так оставляет запас 64px (scrollBlockIntoView). Всё остальное время это
   выглядело как перекос. */
.crm-feed-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
.crm-feed-head h4 { margin: 0; }
.crm-feed-wa { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; color: var(--green-dark);
  background: var(--green-bg); border-radius: var(--r-pill); padding: 6px 12px; font-size: 13px; font-weight: 600; }
/* «+ Товары» — фото товаров с ценой клиента в его чат (26.09). */
.crm-feed-head h4 { margin-right: auto; }
.crm-feed-cards { border: 0; cursor: pointer; font: inherit; color: var(--green-dark); background: var(--green-bg);
  border-radius: var(--r-pill); padding: 6px 12px; font-size: 13px; font-weight: 600; }
.crm-cards-status { margin: 0 0 8px; padding: 8px 12px; border-radius: 12px; background: var(--green-bg); color: var(--green-dark); font-size: 13.5px; }
.crm-cards-status .crm-link-btn { margin-left: 8px; }
/* Три кнопки над перепиской («+ Товары», «Прайс», WhatsApp — 28.09): на
   телефоне заголовок отдельной строкой, кнопки не ломаются посреди слова. */
.crm-feed-head { flex-wrap: wrap; row-gap: 8px; }
/* «Заказывает вместе с» в карточке клиента (28.09). */
.crm-partner-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px 0;
  border-bottom: 1px solid var(--line, rgba(0,0,0,.06)); }
.crm-partner-body { display: flex; flex-direction: column; align-items: flex-start; min-width: 0; }
.crm-partner-body .crm-link-btn { padding: 0; text-align: left; }
.crm-partner-search { margin-top: 8px; }
/* Номер WhatsApp в карточке клиента без телефона и «Старые и из контактов» (29.09). */
.crm-num-row .crm-partner-body b { font-weight: 600; overflow-wrap: anywhere; }
.crm-num-row > .crm-btn { flex: none; }
.crm-wa-numbers .crm-search { width: 100%; margin: 10px 0 2px; }
.crm-wa-numbers > .hint:last-child { margin: 8px 0 0; font-size: 12.5px; }
.crm-unb-h { margin: 16px 0 8px; font-size: 15px; }
.crm-unb-rest .crm-search { width: 100%; margin: 8px 0 10px; }
.crm-feed-cards, .crm-feed-wa { white-space: nowrap; }
@media (max-width: 600px) { .crm-feed-head h4 { flex: 1 0 100%; } }
.crm-cards-results { margin: 10px 0; max-height: 45vh; overflow: auto; }
#crm-cards-sheet .crm-seg-row { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 2px; }
#crm-cards-sheet .crm-seg-row.is-dim { opacity: .45; }
#crm-cards-sheet [hidden] { display: none !important; }
/* Поиск и переключатель — всегда видны, прилипают к верху окна. */
.crm-cards-top { position: sticky; top: 0; z-index: 2; background: #fff; padding: 6px 0 8px; }
.crm-cards-foot { padding-bottom: 80px; }
/* Кнопка «Отправить клиенту» — поверх окна (оно само выше панели CRM). */
.crm-fab-bar.crm-cards-fab { z-index: calc(var(--z-overlay-panel) + 6); bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
body.crm-page.crm-ui-v2 .crm-fab-bar.crm-cards-fab { bottom: calc(16px + env(safe-area-inset-bottom, 0px)); }
.crm-cards-head { margin: 12px 0 6px; }
.crm-cards-row { align-items: flex-start; gap: 10px; }
.crm-cards-thumb { width: 44px; height: 58px; object-fit: cover; object-position: top; border-radius: 6px; flex: none; border: 1px solid rgba(0,0,0,.08); }
.crm-cards-cap { white-space: normal; overflow-wrap: anywhere; line-height: 1.35; }
.crm-feed-tools { display: flex; flex-direction: column; gap: 6px; margin-bottom: 8px; }
.crm-find { display: flex; align-items: center; gap: 6px; }
.crm-find-n { flex: 1; font-size: 12.5px; color: var(--gray); }
.crm-find-btn { width: 32px; height: 32px; border: 0; border-radius: 50%; background: var(--crm-field);
  color: var(--ink); font-size: 16px; line-height: 1; cursor: pointer; }
mark.crm-mark { background: #ffe680; color: inherit; border-radius: 3px; padding: 0 1px; }
.crm-msg.crm-hit-current .crm-bubble { box-shadow: 0 0 0 2px var(--green); }

/* «Команда»: произвольный период */
.crm-daterange { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 12px; font-size: 13px; color: var(--gray); }
.crm-daterange label { display: inline-flex; align-items: center; gap: 6px; }
.crm-date { border: 1px solid transparent; background: var(--crm-field); border-radius: var(--r-crm);
  padding: 8px 10px; font: inherit; font-size: 15px; color: var(--ink); }
.crm-date:focus { outline: none; background: var(--white); border-color: var(--green); }

/* «Деньги на счетах»: карточка счёта раскрывается в свои операции
   (запрос пользователя 2026-09-17 — «каждую карту можно раскрыть и увидеть
   все операции с квитанциями»), поэтому это <details>, а не плитка. */
.crm-money-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; margin-bottom: 14px; }
.crm-money-card { background: var(--white); border: 1px solid var(--border); border-radius: var(--r-crm);
  padding: 14px; margin-bottom: 10px; }
.crm-money-main { flex: 1; min-width: 0; }
.crm-money-unknown { border-style: dashed; }
.crm-money-head { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.crm-money-sum { font-size: 24px; font-weight: 700; margin: 6px 0 2px; font-variant-numeric: tabular-nums; }
.crm-money-line { font-size: 12.5px; color: var(--gray); }
.crm-money-card .crm-row-actions { margin-top: 10px; gap: 8px; }
.crm-money-card > .crm-card-group { margin-top: 10px; }

/* «Главное сегодня» — 10 дел по деньгам вместо стены задач. */
.crm-focus { border-color: var(--green-border); }
.crm-focus-row { cursor: pointer; }
.crm-focus-tag { display: inline-block; font-size: 11px; font-weight: 700; color: var(--white);
  background: var(--gray); border-radius: 6px; padding: 1px 6px; margin-right: 6px; vertical-align: 1px; }
.crm-focus-order { background: #d93025; }
.crm-focus-waiting { background: #e8710a; }
.crm-focus-promise { background: #b8860b; }
.crm-focus-lead { background: var(--green); }
.crm-focus-followup, .crm-focus-reorder, .crm-focus-reactivation { background: #6b7280; }

/* Фидбек на выводах ИИ: галочки исчезают, остаётся подтверждение. */
.crm-fb { transition: opacity .2s ease; }
.crm-fb.crm-fb-sent { opacity: 0; }
.crm-fb-done { display: inline-block; font-size: 12px; color: var(--green-dark); animation: crm-fb-in .25s ease; }
@keyframes crm-fb-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

/* Вкладка «ИИ»: чат-советник */
.crm-ai { display: flex; flex-direction: column; gap: 12px; }
.crm-ai-feed { display: flex; flex-direction: column; gap: 14px; max-height: 60vh; overflow-y: auto; padding-right: 2px; }
.crm-ai-turn { display: flex; flex-direction: column; gap: 6px; }
.crm-ai-q { align-self: flex-end; max-width: 85%; background: var(--green); color: var(--white);
  border-radius: var(--r-crm) var(--r-crm) 6px var(--r-crm); padding: 10px 13px; font-size: 14.5px; }
.crm-ai-a { background: var(--white); border: 1px solid var(--border); border-radius: var(--r-crm);
  padding: 12px 14px; font-size: 14.5px; line-height: 1.5; overflow-wrap: anywhere; }
.crm-ai-wait { color: var(--gray); }
.crm-ai-err { color: #d93025; }
.crm-ai-cost { font-size: 11.5px; color: var(--gray); }
.crm-ai-empty { background: var(--white); border: 1px solid var(--border); border-radius: var(--r-crm); padding: 16px; }
.crm-ai-empty h3 { margin: 0 0 6px; font-size: 16px; }
.crm-ai-hints { display: flex; flex-wrap: wrap; gap: 8px; }
.crm-ai-hints .crm-chip { white-space: normal; text-align: left; font-size: 12.5px; line-height: 1.35; }
.crm-ai-bar { display: flex; gap: 8px; align-items: flex-end; }
.crm-ai-input { flex: 1; border: 1px solid transparent; background: var(--crm-field); border-radius: var(--r-crm);
  padding: 12px 14px; font: inherit; font-size: 16px; resize: vertical; min-height: 48px; }
.crm-ai-input:focus { outline: none; background: var(--white); border-color: var(--green); }
.crm-ai-bar .crm-fab { box-shadow: none; }
/* Диалоги и фото к вопросу (25.09). */
.crm-ai-threads { display: flex; gap: 8px; overflow-x: auto; padding-bottom: 2px; scrollbar-width: none; }
.crm-ai-threads::-webkit-scrollbar { display: none; }
.crm-ai-threads .crm-chip { flex: 0 0 auto; }
.crm-ai-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; min-width: 0; }
.crm-ai-title { font-weight: 600; font-size: 15px; min-width: 0; overflow-wrap: anywhere; }
.crm-ai-del { color: var(--cr-danger, #c0392b); }
.crm-ai-qimgs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 6px; }
.crm-ai-qimgs img { width: 72px; height: 72px; object-fit: cover; border-radius: 10px; display: block; background: rgba(255,255,255,.2); }
.crm-ai-files { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.crm-ai-file { position: relative; }
.crm-ai-file img { width: 64px; height: 64px; object-fit: cover; border-radius: 10px; display: block; }
.crm-ai-file button { position: absolute; top: -6px; right: -6px; width: 22px; height: 22px; border-radius: 50%; border: 0;
  background: #141414; color: #fff; font-size: 15px; line-height: 22px; padding: 0; cursor: pointer; }
.crm-ai-clip { flex: 0 0 auto; width: 48px; height: 48px; border: 0; border-radius: var(--r-crm); background: var(--crm-field);
  color: var(--cr-ink-2, #4a4a50); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; }
.crm-ai-clip:active { transform: scale(.95); }

/* Чей статус — когда владелец смотрит всех сразу. */
.crm-who { display: inline-block; font-size: 11px; font-weight: 700; color: var(--white);
  background: var(--green-dark); border-radius: 6px; padding: 1px 6px; margin-right: 6px; vertical-align: 1px; }
.crm-whose { margin-bottom: 8px; }

/* «Непривязанные»: название — первой строкой, номер и менеджер — всегда
   второй, круглая иконка WhatsApp — всегда на одном месте справа (запрос
   пользователя 2026-09-17). Раньше всё лежало одной строкой с переносом,
   и иконка ездила по карточке в зависимости от длины имени. */
/* Иконка WhatsApp — в правом ВЕРХНЕМ углу карточки, на уровне названия
   (запрос пользователя 2026-09-17), а не по центру двух строк. */
.crm-unb-head { display: flex; align-items: flex-start; gap: 10px; }
.crm-unb-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.crm-unb-main .crm-item-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.crm-unb-head .crm-wa { flex: 0 0 auto; }
/* Чата без номера (скрытый @lid) — место под иконку всё равно держим. */
.crm-wa-gap { flex: 0 0 auto; width: 36px; height: 36px; }

/* ОДНА стрелка раскрытия на всю CRM — такая же, как в «Промо» (запрос
   пользователя 2026-09-17: «везде, где есть такие стрелочки, сделай их
   такими же, как в Промо»). Системный треугольник <details> убираем везде:
   он свой в каждом браузере и выбивается из стилистики. Правило общее, но
   не трогает «Промо» — там шеврон уже нарисован своим элементом
   (.crm-fold-head, .crm-li-chev). Перечисляем классы, а не «все details
   внутри секции»: разбор менеджера и окно заказа живут в своих модалках
   прямо в body, вне .crm-section. */
.crm-block > summary, .crm-evidence > summary, .crm-demand > summary, .crm-chats > summary,
.crm-details > summary, .crm-ask > summary, .crm-pair-phone > summary,
.crm-cash-unmatched > summary, details.analytics-more > summary {
  list-style: none; display: flex; align-items: center; gap: 6px; cursor: pointer; }
.crm-block > summary::-webkit-details-marker, .crm-evidence > summary::-webkit-details-marker,
.crm-demand > summary::-webkit-details-marker, .crm-chats > summary::-webkit-details-marker,
.crm-details > summary::-webkit-details-marker, .crm-ask > summary::-webkit-details-marker,
.crm-pair-phone > summary::-webkit-details-marker, .crm-cash-unmatched > summary::-webkit-details-marker,
details.analytics-more > summary::-webkit-details-marker { display: none; }
.crm-block > summary::after, .crm-evidence > summary::after, .crm-demand > summary::after,
.crm-chats > summary::after, .crm-details > summary::after, .crm-ask > summary::after,
.crm-pair-phone > summary::after, .crm-cash-unmatched > summary::after,
details.analytics-more > summary::after {
  content: "›"; margin-left: auto; color: var(--gray); font-size: 20px; line-height: 1; transition: transform .15s; }
.crm-block[open] > summary::after, .crm-evidence[open] > summary::after, .crm-demand[open] > summary::after,
.crm-chats[open] > summary::after, .crm-details[open] > summary::after, .crm-ask[open] > summary::after,
.crm-pair-phone[open] > summary::after, .crm-cash-unmatched[open] > summary::after,
details.analytics-more[open] > summary::after { transform: rotate(90deg); color: var(--green-dark); }

/* =====================================================================
   CRM v2 — единая система (2026-09-21, запрос пользователя: «все цвета,
   скругления, выделения, нажатия, шрифты, кнопки и стрелочки — в одной
   понятной системе»). Всё ниже действует ТОЛЬКО в новом виде (.crm-v2 /
   body.crm-ui-v2): «Старый вид» тумблером остаётся нетронутым.

   Система в трёх строках:
   • Цвет: один акцент — фирменный зелёный. Им отмечено «выбрано», «активно»,
     «главное действие», «выполнено». Красный — только проблема. Янтарный —
     только «ждём / обещали». Всё остальное — чернила и три серых.
   • Форма: радиусы 22 (панели и шторки) → 16 (карточки) → 12 (поля и
     кнопки) → пилюля (чипы, значки, таб-бар). Рамок почти нет — карточки
     отделяет полупрозрачная волосяная линия и фон страницы.
   • Движение: нажатие — лёгкое сжатие, выбор — пружина, появление —
     всплытие. Одна кривая cubic-bezier(.32,.72,0,1), одна длительность.
   ===================================================================== */
.crm-v2, body.crm-ui-v2 {
  --cr-ink: #141414;
  --cr-ink-2: #4a4a50;
  --cr-gray: #86868b;
  --cr-lgray: #b4b4ba;
  --cr-surface: #ffffff;
  --cr-surface-2: #f2f3f5;
  --cr-line: rgba(20, 20, 20, 0.07);
  --cr-green: #1aa260;
  --cr-green-dark: #148a51;
  --cr-green-bg: #eaf7f0;
  --cr-danger: #c0392b;
  --cr-danger-bg: #fdecea;
  --cr-amber: #9a6a0c;
  --cr-amber-bg: #fdf3e3;
  --cr-r-xl: 22px;
  --cr-r-lg: 16px;
  --cr-r-md: 12px;
  --cr-ease: cubic-bezier(0.32, 0.72, 0, 1);
  --cr-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
}

/* --- Текст --- */
.crm-v2 { color: var(--cr-ink); font-size: 14.5px; line-height: 1.4; }
.crm-v2 .crm-page-title { font-size: 28px; font-weight: 700; letter-spacing: -0.02em; margin: 4px 0 12px; }
.crm-v2 .crm-block h4, .crm-v2 .crm-group-h, .crm-v2 .crm-h4 { font-size: 15px; font-weight: 700; letter-spacing: -0.01em; color: var(--cr-ink); }
.crm-v2 .crm-item-title { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.crm-v2 .crm-item-text { font-size: 13.5px; color: var(--cr-ink-2); }
.crm-v2 .crm-item-sub, .crm-v2 .hint, .crm-v2 .crm-order-sub, .crm-v2 .crm-group-n { font-size: 12.5px; color: var(--cr-gray); }
.crm-v2 .crm-group-n { font-weight: 600; }

/* --- Поверхности: карточки без тяжёлых рамок --- */
.crm-v2 .crm-block, .crm-v2 .crm-item, .crm-v2 .crm-order, .crm-v2 .crm-debt-card, .crm-v2 .crm-sal,
.crm-v2 .crm-own-card, .crm-v2 .crm-matrix-item, .crm-v2 .crm-demand {
  background: var(--cr-surface); border: 1px solid var(--cr-line); border-radius: var(--cr-r-lg);
  box-shadow: none; transition: transform 0.14s var(--cr-ease), background 0.14s;
}
/* ОДИН внутренний отступ у всех карточек приложения — 12 px сверху/снизу и
   14 px по бокам (репорт пользователя 2026-09-21: «в Закупе карточки
   слишком воздушные, отступы контента от карточки должны быть одинаковыми
   везде»). В «Закупе» отступ складывался дважды: у карточки (.crm-item) и
   у её заголовка-раскрывашки — содержимое стояло в 29×25 px от края
   против 15×13 в остальных разделах. */
.crm-v2, body.crm-ui-v2 { --cr-pad-y: 12px; --cr-pad-x: 14px; }
.crm-v2 .crm-item, .crm-v2 .crm-order, .crm-v2 .crm-block, .crm-v2 .crm-debt-card, .crm-v2 .crm-sal,
.crm-v2 .crm-own-card, .crm-v2 .crm-matrix-item { padding: var(--cr-pad-y) var(--cr-pad-x); }
.crm-v2 .crm-item, .crm-v2 .crm-order { margin-bottom: 8px; }
.crm-v2 .crm-block { margin-bottom: 10px; }
.crm-v2 .crm-item.crm-demand { padding: 0; }
.crm-v2 .crm-demand-clients { padding: 4px var(--cr-pad-x) var(--cr-pad-y); }
.crm-v2 .crm-li, .crm-v2 .crm-promo-head { padding: var(--cr-pad-y) var(--cr-pad-x); }
.crm-v2 .crm-promo-body { padding: 0 var(--cr-pad-x) var(--cr-pad-y); }
.crm-v2 .crm-card-group, .crm-v2 .crm-promo-item { border-radius: var(--cr-r-lg); border-color: var(--cr-line); }
.crm-v2 .crm-item:active, .crm-v2 .crm-order:active, .crm-v2 .crm-focus-row:active { transform: scale(0.985); background: #fbfbfc; }
.crm-v2 .crm-order.compact { border-radius: var(--cr-r-md); }
.crm-v2 .crm-todo, .crm-v2 .crm-focus { border-color: var(--cr-line); }
/* Блок «Сегодня» — обычная белая карточка: зелёная заливка на ВСЕХ делах
   сразу ничего не выделяла, только шумела (репорт пользователя 2026-09-21). */
.crm-v2 .crm-focus { background: var(--cr-surface); border-color: var(--cr-line); }
/* Проблемный заказ: не толстая красная полоса слева, а тонкая красноватая
   рамка — сама проблема уже написана красным текстом. */
.crm-v2 .crm-order.has-problem { border-color: rgba(192, 57, 43, 0.28); box-shadow: none; }
.crm-v2 .crm-order-problem { color: var(--cr-danger); font-weight: 600; }
.crm-v2 .crm-empty, .crm-v2 .crm-loading { color: var(--cr-gray); font-weight: 500; }
.crm-v2 .crm-empty { color: var(--cr-ink-2); }

/* --- Этапы заказа: серые, выполненные — зелёные, без заливки текста --- */
/* Только этапы (.crm-steps): тем же классом .crm-seg сделаны переключатели
   (промо, зарплата, «Команда», уровень цен в подборке) — их не трогаем,
   они остаются в прежнем виде (репорт пользователя 2026-09-21). */
.crm-v2 .crm-steps .crm-seg { background: var(--cr-surface-2); color: var(--cr-gray); font-weight: 600; border-radius: 8px; }
.crm-v2 .crm-steps .crm-seg.done { background: var(--cr-green-bg); color: var(--cr-green-dark); }
.crm-v2 .crm-ostep-dot { background: var(--cr-surface-2); border-color: var(--cr-surface-2); }
.crm-v2 .crm-ostep.done .crm-ostep-dot { background: var(--cr-green); border-color: var(--cr-green); }
@media (max-width: 700px) {
  .crm-v2 .crm-steps .crm-seg { background: #e6e8ec; height: 4px; }
  .crm-v2 .crm-steps .crm-seg.done { background: var(--cr-green); }
  .crm-v2 .crm-steps-now { color: var(--cr-gray); }
}

/* --- Чипы: без рамок; выбранный — зелёный --- */
.crm-v2 .crm-chip, .crm-v2 .crm-sum-chip {
  border: 0; background: var(--cr-surface-2); color: var(--cr-ink); border-radius: 999px;
  padding: 8px 13px; font-size: 13px; font-weight: 600; min-height: 34px;
  transition: background 0.14s, color 0.14s, transform 0.12s;
}
.crm-v2 .crm-chip:active, .crm-v2 .crm-sum-chip:active { transform: scale(0.96); }
.crm-v2 .crm-chip.active { background: var(--cr-green-dark); color: #fff; }
.crm-v2 .crm-chip.active .crm-chip-n { color: rgba(255, 255, 255, 0.75); }
.crm-v2 .crm-chip-n { color: var(--cr-gray); font-weight: 500; }
.crm-v2 .crm-chip-alert { color: var(--cr-danger); background: var(--cr-danger-bg); }
.crm-v2 .crm-chip-alert.active { background: var(--cr-danger); color: #fff; }
.crm-v2 .crm-sum-chip:hover { background: #e9ebef; }

/* --- Кнопки: главная — зелёная, обычная — серая подложка, ссылка — зелёный текст --- */
.crm-v2 .crm-btn, body.crm-ui-v2 .crm-btn {
  border: 0; background: var(--cr-surface-2); color: var(--cr-ink); border-radius: 999px;
  padding: 9px 15px; font-size: 13.5px; font-weight: 600; min-height: 38px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  transition: background 0.14s, transform 0.12s, opacity 0.14s;
}
.crm-v2 .crm-btn:active, body.crm-ui-v2 .crm-btn:active { transform: scale(0.97); }
.crm-v2 .crm-btn:disabled, body.crm-ui-v2 .crm-btn:disabled { opacity: 0.45; cursor: default; }
.crm-v2 .crm-btn-primary, body.crm-ui-v2 .crm-btn-primary { background: var(--cr-green-dark); color: #fff; }
.crm-v2 .crm-btn-primary:hover, body.crm-ui-v2 .crm-btn-primary:hover { background: #117745; }
.crm-v2 .crm-btn-ghost, body.crm-ui-v2 .crm-btn-ghost { background: var(--cr-surface-2); }
.crm-v2 .crm-btn-wa, body.crm-ui-v2 .crm-btn-wa { background: var(--cr-green-bg); color: var(--cr-green-dark); }
/* Красная кнопка опасного действия (12.10): серый фон `.crm-btn` нового вида
   перебивал .docs-danger-btn и .crm-btn-danger — «Удалить заказ»,
   «Распровести» в «Документах 1С» и «Удалить витрину» были серыми. */
.crm-v2 .crm-btn.docs-danger-btn, body.crm-ui-v2 .crm-btn.docs-danger-btn,
.crm-v2 .crm-btn.crm-btn-danger, body.crm-ui-v2 .crm-btn.crm-btn-danger { background: var(--cr-danger, #c0392b); color: #fff; }
.crm-v2 .crm-btn.docs-danger-btn:hover, body.crm-ui-v2 .crm-btn.docs-danger-btn:hover,
.crm-v2 .crm-btn.crm-btn-danger:hover, body.crm-ui-v2 .crm-btn.crm-btn-danger:hover { background: #a5311f; }
.crm-v2 .crm-link-btn, body.crm-ui-v2 .crm-link-btn, .crm-v2 .crm-quote-link, body.crm-ui-v2 .crm-quote-link,
.crm-v2 .crm-ev-link, .crm-v2 a { color: var(--cr-green-dark); font-weight: 600; }
.crm-v2 .crm-link-strong { color: var(--cr-green-dark); }
.crm-v2 .crm-more-btn { border: 0; background: var(--cr-surface-2); color: var(--cr-ink-2); border-radius: var(--cr-r-md); }
.crm-v2 .crm-more-btn:hover { background: #e9ebef; }
.crm-v2 .crm-search, body.crm-ui-v2 .crm-search {
  border: 0; background: var(--cr-surface-2); border-radius: var(--cr-r-md); padding: 12px 14px; font-size: 15px;
  transition: box-shadow 0.14s, background 0.14s;
}
.crm-v2 .crm-search:focus, body.crm-ui-v2 .crm-search:focus { outline: none; background: #fff; box-shadow: 0 0 0 2px var(--cr-green); }
.crm-v2 .crm-fb button { border: 0; background: var(--cr-surface-2); color: var(--cr-gray); }
.crm-v2 .crm-fb button.chosen { background: var(--cr-green-dark); color: #fff; }
.crm-v2 .crm-wa { background: var(--cr-green-bg); color: var(--cr-green-dark); }

/* --- Значки состояния: тот же зелёный / красный / янтарный, мягкие подложки --- */
.crm-v2 .crm-badge, .crm-v2 .crm-pay, .crm-v2 .crm-val, .crm-v2 .crm-who { border-radius: 999px; font-weight: 600; }
.crm-v2 .crm-badge.crm-ok, .crm-v2 .crm-pay-ok, .crm-v2 .crm-stage-pill { background: var(--cr-green-bg); color: var(--cr-green-dark); }
.crm-v2 .crm-badge.crm-late, .crm-v2 .crm-late, .crm-v2 .crm-pay-bad { background: var(--cr-danger-bg); color: var(--cr-danger); }
.crm-v2 .crm-badge.crm-warn, .crm-v2 .crm-pay-warn, .crm-v2 .crm-wait { background: var(--cr-amber-bg); color: var(--cr-amber); }
.crm-v2 .crm-badge.crm-stale, .crm-v2 .crm-stale, .crm-v2 .crm-pay { background: var(--cr-surface-2); color: var(--cr-gray); }
.crm-v2 .crm-val-A { background: var(--cr-green-dark); color: #fff; }
.crm-v2 .crm-val-B { background: var(--cr-green-bg); color: var(--cr-green-dark); }
.crm-v2 .crm-val-C { background: var(--cr-surface-2); color: var(--cr-gray); }
.crm-v2 .crm-money-chip { background: var(--cr-green-bg); color: var(--cr-green-dark); }
.crm-v2 .crm-tone-orange, .crm-v2 .crm-tone-yellow { background: #d99a1e; }
.crm-v2 .crm-tone-red { background: var(--cr-danger); }
.crm-v2 .crm-tone-green { background: var(--cr-green); }
.crm-v2 .crm-tone-gray { background: var(--cr-lgray); }
.crm-v2 .crm-focus-tag { border-radius: 6px; font-weight: 700; }
.crm-v2 .crm-focus-order { background: var(--cr-danger); }
.crm-v2 .crm-focus-waiting, .crm-v2 .crm-focus-promise { background: #d99a1e; }
.crm-v2 .crm-focus-lead { background: var(--cr-green-dark); }
.crm-v2 .crm-focus-followup, .crm-v2 .crm-focus-reorder, .crm-v2 .crm-focus-reactivation,
.crm-v2 .crm-focus-pool, .crm-v2 .crm-focus-client_promise, .crm-v2 .crm-focus-reserve { background: var(--cr-gray); }
.crm-v2 .crm-debt-card-late b { color: var(--cr-danger); }

/* --- Раскрытия: единый шеврон, поворачивается при открытии --- */
.crm-v2 details > summary { list-style: none; cursor: pointer; position: relative; padding-right: 26px; }
.crm-v2 details > summary::-webkit-details-marker { display: none; }
.crm-v2 details > summary::after {
  content: ""; position: absolute; right: 4px; top: 50%; width: 18px; height: 18px; margin-top: -9px;
  background: no-repeat center / 18px url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='none' stroke='%23b4b4ba' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m9 6l6 6l-6 6'/></svg>");
  transition: transform 0.24s var(--cr-ease);
}
.crm-v2 details[open] > summary::after { transform: rotate(90deg); }
.crm-v2 .crm-demand > summary { padding: var(--cr-pad-y) 38px var(--cr-pad-y) var(--cr-pad-x); }
.crm-v2 .crm-demand > summary::after { right: 12px; }
.crm-v2 .crm-demand[open] > summary { border-bottom-color: var(--cr-line); }

/* --- Таб-бар: иконки и микроанимация выбора (как в мессенджерах) --- */
.crm-v2 .crm-tab-ico { display: block; will-change: transform; }
@keyframes crmIconPop {
  0% { transform: scale(1); }
  30% { transform: scale(0.8) translateY(2px); }
  62% { transform: scale(1.16) translateY(-2px); }
  82% { transform: scale(0.96); }
  100% { transform: scale(1); }
}
.crm-v2 .crm-tab-ico.pop { animation: crmIconPop 0.48s var(--cr-spring); }
.crm-v2 .crm-tabbar-btn { color: var(--cr-gray); }
.crm-v2 .crm-tabbar-btn.active { color: var(--cr-green-dark); }
.crm-v2 .crm-tabbar .crm-tab-count { background: var(--cr-danger); }

/* --- Кнопка «наверх» — над парящей панелью ---
   На телефоне кнопка лежит в .fab-stack (position: fixed), и двигать надо
   КОНТЕЙНЕР: bottom у самой кнопки там ни на что не влиял — поэтому
   первая правка «не взяла» и кнопка снова легла на таб-бар (репорт
   пользователя 2026-09-21). Панель: 10 px от края + ~62 px высоты. */
@media (max-width: 700px) {
  body.crm-page.crm-ui-v2 .fab-stack { bottom: calc(92px + env(safe-area-inset-bottom, 0px)); right: 16px; }
  body.crm-page.crm-ui-v2 .crm-fab-bar { bottom: calc(92px + env(safe-area-inset-bottom, 0px)); }
  body.crm-page.crm-ui-v2.crm-fab-on .fab-stack { bottom: calc(152px + env(safe-area-inset-bottom, 0px)); }
  body.crm-page.crm-ui-v2.crm-fab-on.crm-fab-tall .fab-stack { bottom: calc(200px + env(safe-area-inset-bottom, 0px)); }
}
body.crm-page.crm-ui-v2 .scroll-top-toggle {
  border: 0; background: rgba(255, 255, 255, 0.86); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
  box-shadow: 0 8px 24px rgba(20, 20, 20, 0.14), 0 0 0 0.5px rgba(20, 20, 20, 0.06); color: var(--cr-ink);
}
/* «Каталог» на компьютере: панель парит снизу — кнопка «наверх» над ней
   (в узком окне панель доходит до правого края и закрыла бы кнопку). */
@media (min-width: 701px) and (max-width: 899px) {
  body.crm-page.crm-catalog-on .fab-stack { bottom: 86px; }
}
@media (min-width: 900px) {
  body.crm-page.crm-ui-v2.crm-catalog-on .scroll-top-toggle { bottom: 86px; }
}

/* --- Шторка «Ещё» и поиск: единые радиусы и подложки --- */
.crm-v2 .crm-more-sheet { border-radius: var(--cr-r-xl) var(--cr-r-xl) 0 0; }
/* Без «ручки»: шторку не смахивают вниз, значит и полоска-подсказка ни к чему. */
.crm-v2 .crm-sheet-grabber { display: none; }
.crm-v2 .crm-sheet-title { padding: 14px 0 10px; }
.crm-v2 .crm-more-item { border-radius: var(--cr-r-md); }
.crm-v2 .crm-more-item.active .crm-more-ico { color: var(--cr-green-dark); }
.crm-v2 .crm-more-item .crm-tab-count { background: var(--cr-surface-2); color: var(--cr-gray); }
body.crm-ui-v2 .crm-find-panel { border-radius: var(--cr-r-xl); }
body.crm-ui-v2 .crm-find-row { border-radius: var(--cr-r-md); }
body.crm-ui-v2 .crm-find-esc { border: 0; background: var(--cr-surface-2); }
@media (min-width: 701px) {
  .crm-v2 .crm-more-sheet { border-radius: var(--cr-r-lg); }
}

/* --- Модалка подборки замен --- */
body.crm-ui-v2 .crm-alt-panel .product-modal-body { padding-bottom: 24px; }
.crm-alt-label { display: block; font-size: 12.5px; color: var(--cr-gray, #86868b); margin: 12px 0 6px; }
.crm-alt-label b { color: var(--cr-ink, #141414); font-weight: 600; }
.crm-alt-select { margin: 4px 0 0; }
.crm-alt-tiers { max-width: 340px; }
.crm-alt-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin: 6px 0 8px; }
@media (min-width: 701px) { .crm-alt-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.crm-alt-item {
  position: relative; display: flex; flex-direction: column; gap: 6px; text-align: left; padding: 0 0 10px;
  border: 2px solid transparent; background: var(--cr-surface-2, #f2f3f5); border-radius: var(--cr-r-lg, 16px);
  overflow: hidden; cursor: pointer; font-family: inherit; color: var(--cr-ink, #141414);
  transition: border-color 0.14s, transform 0.12s;
}
.crm-alt-item:active { transform: scale(0.97); }
.crm-alt-item.on { border-color: var(--cr-green, #1aa260); background: #fff; }
.crm-alt-item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; background: #eceef1; }
.crm-alt-nophoto { display: flex; align-items: center; justify-content: center; aspect-ratio: 4 / 3; font-size: 12px; color: var(--cr-gray, #86868b); }
.crm-alt-name { font-size: 12.5px; font-weight: 600; line-height: 1.3; padding: 0 10px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.crm-alt-price { font-size: 14px; font-weight: 700; color: var(--cr-ink, #141414); padding: 0 10px; margin-top: auto; }
/* «Чем похоже» — те же строки, что увидит клиент на картинке. */
.crm-alt-why { display: flex; flex-direction: column; gap: 3px; padding: 0 10px; }
.crm-alt-why span {
  position: relative; padding-left: 18px; font-size: 12px; line-height: 1.3; font-weight: 600;
  color: var(--cr-green-dark, #148a51);
}
.crm-alt-why span::before {
  content: ""; position: absolute; left: 0; top: 1px; width: 13px; height: 13px; border-radius: 50%;
  background: var(--cr-green, #1aa260) no-repeat center / 9px
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='none' stroke='white' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round' d='m5 12.5l4.5 4.5L19 7.5'/></svg>");
}
.crm-alt-check {
  position: absolute; top: 8px; right: 8px; width: 24px; height: 24px; border-radius: 50%;
  background: rgba(255, 255, 255, 0.92); color: var(--cr-green-dark, #148a51); font-size: 14px; font-weight: 700;
  display: flex; align-items: center; justify-content: center; box-shadow: 0 1px 3px rgba(20, 20, 20, 0.16);
}
.crm-alt-item.on .crm-alt-check { background: var(--cr-green-dark, #148a51); color: #fff; }
.crm-alt-preview { width: 100%; max-width: 420px; display: block; border-radius: var(--cr-r-lg, 16px); box-shadow: 0 8px 28px rgba(20, 20, 20, 0.14); margin: 6px 0 4px; }
.crm-alt-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.crm-alt-actions .crm-btn { min-height: 44px; padding: 10px 18px; font-size: 14.5px; }

/* --- Уведомление снизу --- */
.crm-toast {
  position: fixed; left: 50%; bottom: calc(100px + env(safe-area-inset-bottom, 0px)); transform: translate(-50%, 12px);
  z-index: 95; background: rgba(20, 20, 20, 0.92); color: #fff; font-size: 14px; font-weight: 500;
  padding: 12px 18px; border-radius: 999px; box-shadow: 0 10px 30px rgba(20, 20, 20, 0.25);
  opacity: 0; transition: opacity 0.24s, transform 0.28s cubic-bezier(0.32, 0.72, 0, 1); max-width: calc(100% - 32px); text-align: center;
}
.crm-toast.on { opacity: 1; transform: translate(-50%, 0); }
@media (min-width: 701px) { .crm-toast { bottom: 28px; } }

/* =====================================================================
   Разбор CRM 2026-09-21 (static/crm-plus.js): итог дела, голосовая поправка
   ИИ, цепочка касаний, «Позже», «Пульт», «Закупка», допродажа, подключения.
   Те же токены --cr-*: зелёный — действие и «сделано», красный — проблема.
   ===================================================================== */
/* «Главное»: шаг цепочки и действие прямо в строке */
.crm-focus-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; margin-top: 6px; }
.crm-focus-actions .crm-link-btn { padding: 2px 0; font-size: 13.5px; }
.crm-step-chip {
  display: inline-flex; align-items: center; font-size: 11.5px; font-weight: 600; color: var(--cr-green-dark, #148a51);
  background: var(--cr-green-bg, #eaf7f0); border-radius: 999px; padding: 2px 9px;
}
/* «Позже» — всё, что не вошло в «Главное», свёрнуто */
.crm-later { margin: 12px 0; }
.crm-later > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 8px; padding: 12px 38px 12px 14px;
  background: var(--cr-surface, #fff); border: 1px solid var(--cr-line, rgba(20,20,20,.07)); border-radius: var(--cr-r-lg, 16px);
  font-weight: 600; font-size: 15px; position: relative;
}
.crm-later > summary::-webkit-details-marker { display: none; }
.crm-v2 .crm-later > summary::after { right: 12px; }
.crm-later-n { color: var(--cr-gray, #86868b); font-weight: 600; font-size: 13px; background: var(--cr-surface-2, #f2f3f5); border-radius: 999px; padding: 1px 8px; }
.crm-later[open] > summary { margin-bottom: 10px; }
.crm-month-fold { margin-top: 12px; }
.crm-month-top { margin: 0 0 10px; }
.crm-month-top > summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.crm-month-top > summary .hint { font-size: 13px; }
.crm-today-link + .crm-today-link { margin-top: -4px; }
.crm-subtab-here { pointer-events: none; }
/* Длинная вводная — одной строкой, «?» раскрывает (v3, этап 4). */
.crm-intro-fold { position: relative; padding-right: 40px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.crm-intro-fold.open { display: block; -webkit-line-clamp: unset; overflow: visible; }
.crm-intro-q { position: absolute; right: 0; top: -4px; width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--border, #e3e3e8);
  background: var(--white, #fff); color: var(--green-dark, #148a51); font: inherit; font-weight: 700; font-size: 14px; cursor: pointer; padding: 0; }
.crm-intro-q::after { content: ""; position: absolute; inset: -6px; }
/* Полоса вкладок/чипов, уходящая за край, — затухание справа. */
.crm-scroll-more { -webkit-mask-image: linear-gradient(to right, #000 85%, transparent); mask-image: linear-gradient(to right, #000 85%, transparent); }
a.crm-today-link { text-decoration: none; color: inherit; }
a.crm-today-link b { color: var(--green-dark, #148a51); }
label.crm-wh-check:has(select) { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; white-space: nowrap; }
label.crm-wh-check select { flex: 1 1 160px; min-width: 0; min-height: 40px; font-size: 16px; }
.crm-task-meta { display: block; font-size: 13px; font-weight: 500; color: var(--cr-gray, #66666b); margin-top: 2px; }
.crm-task-steps { display: flex; flex-direction: column; gap: 2px; margin: 8px 0; }
.crm-task-step { display: flex; align-items: center; gap: 8px; min-height: 40px; font-size: 14px; }
.crm-task-step input { width: 22px; height: 22px; accent-color: var(--green, #1aa260); flex: none; }
/* «Клиенты → Карта клиентов» (RFM, 26.09). */
.crm-rfm > summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.crm-rfm-grid { display: grid; grid-template-columns: 58px repeat(3, minmax(0, 1fr)); gap: 4px; margin-top: 8px; }
.crm-rfm-col { font-size: 12px; color: var(--cr-gray, #66666b); text-align: center; font-weight: 600; }
.crm-rfm-row { font-size: 12px; color: var(--cr-gray, #66666b); display: flex; align-items: center; font-weight: 600; }
.crm-rfm-cell { min-height: 64px; border: 1px solid var(--cr-line, rgba(20,20,20,.08)); border-radius: 12px; background: var(--white, #fff);
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px; padding: 6px; font: inherit; text-align: left; cursor: pointer; min-width: 0; }
.crm-rfm-cell:disabled { opacity: .45; cursor: default; }
.crm-rfm-r1 { background: #eef8f2; }
.crm-rfm-r2 { background: #fdf6e8; }
.crm-rfm-r3 { background: #f6f6f7; }
.crm-rfm-cell.active { outline: 2px solid var(--green-dark, #148a51); outline-offset: 1px; }
.crm-rfm-l { font-size: 11px; line-height: 1.25; color: var(--cr-ink-2, #4a4a50); overflow-wrap: anywhere; }
.crm-rfm-n { font-size: 16px; font-weight: 700; }
.crm-rfm-v { font-size: 11px; color: var(--cr-gray, #66666b); }
.crm-map-note { margin: 4px 0 8px; }
.crm-stale-bar { margin: 0 0 10px; padding: 10px 14px; border-radius: 12px; background: var(--cr-amber-bg, #fdf3e3);
  color: var(--cr-amber, #8a5d08); font-size: 14px; line-height: 1.4; }
.rp-stale, .sales-asof-stale { color: var(--cr-amber, #8a5d08); }
.crm-tg-quiet { display: block; margin: 0 0 8px; }
.crm-tg-ask { width: 100%; min-height: 44px; margin-top: 8px; font-size: 15px; }
.uprav-moved { display: block; margin: 12px 16px; padding: 14px 16px; border-radius: 16px; background: var(--green-bg, #eaf7f0);
  color: var(--green-dark, #148a51); text-decoration: none; font-size: 15px; line-height: 1.4; }
.crm-buy-check textarea { width: 100%; margin: 6px 0; font-size: 16px; }
.crm-buy-check .crm-btn { min-height: 44px; margin: 4px 0 8px; }
.crm-buy-check .product-link-cell.crm-buy-check-name { width: auto; text-align: left; background: none; border: 0; padding: 0; font: inherit; font-weight: 600; cursor: pointer; }
.crm-li-warn { background: var(--cr-amber-bg, #fdf3e3); }
.crm-li-bad { background: #fdecea; }
#crm-welcome .crm-welcome-ok { width: 100%; min-height: 44px; margin-top: 12px; font-size: 15px; }
/* Подключить Telegram / уведомления */
.crm-connect-row { display: grid; grid-template-columns: 1fr; gap: 8px; margin: 0 0 12px; }
@media (min-width: 701px) { .crm-connect-row { grid-template-columns: 1fr 1fr; } }
.crm-connect {
  display: flex; flex-direction: column; gap: 2px; text-align: left; border: 0; cursor: pointer; font-family: inherit;
  background: var(--cr-green-bg, #eaf7f0); color: var(--cr-green-dark, #148a51); border-radius: var(--cr-r-lg, 16px); padding: 12px 14px;
  transition: transform .12s;
}
.crm-connect:active { transform: scale(.98); }
.crm-connect b { font-size: 14.5px; }
.crm-connect span { font-size: 12.5px; color: var(--cr-ink-2, #4a4a50); }
/* Итог дела */
.crm-outcome-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin: 8px 0 12px; }
.crm-outcome {
  border: 0; background: var(--cr-surface-2, #f2f3f5); color: var(--cr-ink, #141414); border-radius: var(--cr-r-md, 12px);
  padding: 13px 12px; font-family: inherit; font-size: 14px; font-weight: 600; cursor: pointer; text-align: left; transition: transform .12s, background .12s;
}
.crm-outcome:active { transform: scale(.97); }
.crm-outcome-main { background: var(--cr-green-dark, #148a51); color: #fff; }
/* Оценка разбора словами */
.crm-fb-words button { width: auto !important; padding: 2px 9px !important; border-radius: 999px !important; font-size: 12px !important; font-weight: 600; }
/* На всю ширину и с переносом: одной строкой (nowrap у .crm-btn) на
   телефоне 360px кнопка вылезала за карточку (репорт 2026-09-22). */
.crm-btn.crm-aifb-btn, .crm-v2 .crm-btn.crm-aifb-btn { margin-top: 10px; display: flex; width: 100%; align-items: center;
  justify-content: center; gap: 8px; white-space: normal; text-align: center; line-height: 1.3; }
.crm-aifb-btn svg { flex: none; }
.crm-aifb-quote { background: var(--cr-surface-2, #f2f3f5); border-radius: var(--cr-r-md, 12px); padding: 10px 12px; font-size: 13.5px; margin-bottom: 10px; }
.crm-aifb-lead { font-size: 14px; line-height: 1.45; margin: 0 0 12px; }
.crm-rec { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 8px 0 4px; }
.crm-rec-btn {
  width: 76px; height: 76px; border-radius: 50%; border: 0; cursor: pointer; background: var(--cr-green-dark, #148a51);
  display: flex; align-items: center; justify-content: center; box-shadow: 0 8px 22px rgba(20,138,81,.35); transition: transform .15s, background .15s;
}
.crm-rec-btn:active { transform: scale(.94); }
.crm-rec-dot { width: 26px; height: 26px; border-radius: 50%; background: #fff; transition: border-radius .2s, width .2s, height .2s; }
.crm-rec-btn.on { background: var(--cr-danger, #c0392b); animation: crmRecPulse 1.4s ease-in-out infinite; box-shadow: 0 8px 22px rgba(192,57,43,.35); }
.crm-rec-btn.on .crm-rec-dot { border-radius: 6px; width: 22px; height: 22px; }
@keyframes crmRecPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }
.crm-rec-state { font-size: 13px; color: var(--cr-gray, #86868b); text-align: center; }
.crm-rec-audio { width: 100%; max-width: 360px; }
/* Допродажа в карточке */
.crm-xsell h4 { margin-bottom: 4px; }
.crm-xsell-list { list-style: none; margin: 8px 0 10px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.crm-xsell-list li { display: flex; align-items: center; gap: 10px; }
.crm-xsell-list img, .crm-xsell-nophoto { width: 48px; height: 48px; border-radius: 10px; object-fit: cover; background: var(--cr-surface-2, #f2f3f5); flex: none; }
.crm-xsell-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; font-size: 13.5px; }
.crm-xsell-body .crm-alt-why { padding: 0; }
.crm-xsell-price { font-weight: 700; font-size: 13.5px; flex: none; }
/* «Допродажа» из РОП (24.09, static/crm-upsell.js): карточка клиента и
   «Что ещё предложить» в «Новом заказе». */
.crm-up-h { margin: 12px 0 0; font-size: 13px; font-weight: 600; color: var(--cr-muted, #6b7280); }
.crm-xsell .crm-up-h:first-of-type { margin-top: 8px; }
.crm-xsell-list .crm-up-li { align-items: flex-start; }
.crm-xsell-list .crm-up-li[hidden] { display: none; }
.crm-up-foot { display: flex; align-items: center; gap: 10px; margin-top: 4px; }
.crm-up-more { margin: -4px 0 4px; }
.crm-xsell-list .crm-mini { flex: none; }
.crm-xsell-list .crm-mini:disabled { opacity: .55; }
.crm-up-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.crm-up-textbox { margin-top: 10px; }
.crm-up-text { width: 100%; box-sizing: border-box; min-height: 120px; font-size: 16px; line-height: 1.45; resize: vertical; }
.crm-up-order { margin: 10px 0 4px; }
.crm-up-head { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; }
.crm-up-head .crm-link-btn { margin-left: auto; }
/* «Пульт» */
.crm-cockpit-tiles { grid-template-columns: 1fr 1fr; }
@media (min-width: 701px) { .crm-cockpit-tiles { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.crm-ptile-bad .crm-ptile-v { color: var(--cr-danger, #c0392b); }
.crm-section-h { font-size: 17px; font-weight: 700; margin: 18px 0 8px; }
.crm-week-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 10px; margin-bottom: 8px; }
.crm-week-head b { font-size: 15.5px; }
.crm-week-head span { font-size: 13px; color: var(--cr-gray, #86868b); }
.crm-week-cells { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 6px; margin-bottom: 6px; }
.crm-week-cells span, .crm-wcell { display: flex; flex-direction: column; align-items: flex-start; background: var(--cr-surface-2, #f2f3f5);
  border: 0; border-radius: var(--cr-r-md, 12px); padding: 8px 10px; font-family: inherit; text-align: left; cursor: pointer; }
/* Цифры «Пульта» раскрываются списком (23.09): нажатая ячейка — зелёная. */
.crm-wcell.on, .crm-ptile-btn.on { background: var(--cr-green-bg, #eaf7f0); border-color: var(--cr-green, #1aa260); }
.crm-ptile-btn { width: 100%; text-align: left; font-family: inherit; cursor: pointer; }
.crm-ptile-btn:hover, .crm-wcell:hover { border-color: var(--cr-green, #1aa260); }
.crm-cock-detail { margin: 2px 0 12px; }
.crm-cock-detail .crm-card-group { max-height: 60vh; overflow-y: auto; }
.crm-week-cells b { font-size: 17px; font-variant-numeric: tabular-nums; }
.crm-week-cells i { font-style: normal; font-size: 11.5px; color: var(--cr-gray, #86868b); }
.crm-week-review { display: flex; flex-direction: column; gap: 4px; margin-top: 8px; }
.crm-review-link { text-align: left; border: 0; background: none; padding: 2px 0; font-family: inherit; font-size: 13px; color: var(--cr-green-dark, #148a51); cursor: pointer; }
.crm-loss { display: flex; flex-direction: column; gap: 6px; }
.crm-loss-row { display: grid; grid-template-columns: 150px 1fr 36px; align-items: center; gap: 8px; font-size: 13.5px; }
.crm-loss-row i { display: block; height: 8px; border-radius: 4px; background: var(--cr-danger, #c0392b); opacity: .75; }
.crm-loss-row b { text-align: right; font-variant-numeric: tabular-nums; }
.crm-plan-line { display: grid; grid-template-columns: 80px 1fr auto; align-items: center; gap: 10px; font-size: 13.5px; padding: 4px 0; }
.crm-plan-line .crm-pbar { margin: 0; }
/* «Закупка» (вторая итерация 2026-09-21: без красной заливки строк; выбранная
   строка — зелёная подложка, поле количества — как в «Промо»: серое на белом,
   белое на подкрашенном) */
.crm-buy-summary { font-size: 14.5px; margin: 0 0 8px; }
.crm-buy-chips { margin: 0 0 10px; }
.crm-buy-how { margin: 0 0 10px; font-size: 13.5px; }
.crm-buy-how > summary { list-style: none; cursor: pointer; color: var(--cr-green-dark, #148a51); font-weight: 600; position: relative; padding-right: 22px; display: inline-block; }
.crm-buy-how > summary::-webkit-details-marker { display: none; }
.crm-buy-how p { margin: 6px 0 0; }
.crm-buy-group > summary { list-style: none; cursor: pointer; }
.crm-buy-group > summary::-webkit-details-marker { display: none; }
.crm-buy-summary-row { position: relative; padding-right: 40px !important; gap: 8px; }
.crm-buy-summary-end { display: flex; align-items: center; gap: 6px; margin-left: auto; flex: none; }
.crm-v2 .crm-buy-group > summary::after { right: 12px; }
.crm-buy-sup { padding: 8px var(--cr-pad-x, 14px) 10px; font-size: 13px; color: var(--cr-ink-2, #4a4a50); display: flex; flex-direction: column; gap: 4px;
  border-top: 1px solid var(--cr-line, rgba(20,20,20,.07)); }
.crm-buy-sup-line b { color: var(--cr-ink, #141414); }
.crm-buy-debt { color: var(--cr-amber, #9a6a0c); }
.crm-buy-sup-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px; }
.crm-buy-sup-form label { display: flex; flex-direction: column; gap: 2px; font-size: 12px; color: var(--cr-gray, #86868b); }
.crm-buy-sup-form input { width: 96px; border: 0; background: var(--crm-field, #eceef1); border-radius: var(--cr-r-md, 12px); padding: 8px 10px; font: inherit; font-size: 16px; }
.crm-buy-item { display: flex; align-items: flex-start; gap: 10px; padding: var(--cr-pad-y, 12px) var(--cr-pad-x, 14px);
  border-top: 1px solid var(--cr-line, rgba(20,20,20,.07)); transition: background-color .18s ease; }
.crm-buy-item.is-picked { background: var(--cr-green-bg, #eaf7f0); }
.crm-buy-check { padding-top: 12px; }
.crm-buy-check input { width: 20px; height: 20px; margin: 0; accent-color: var(--cr-green, #1aa260); }
/* .product-link-cell из «Закупа» Аналитики даёт width:100% и отрицательные поля —
   в строке «Закупки» это сжимало текст до нуля ширины (поймано на проде). */
.crm-buy-item .product-link-cell.crm-buy-photo-btn { display: block; width: auto; margin: 0; padding: 0; border: 0; background: none; cursor: pointer; flex: none; text-decoration: none; }
.crm-buy-photo { display: block; width: 44px; height: 44px; border-radius: 10px; object-fit: contain; background: #fff; border: 1px solid var(--cr-line, rgba(20,20,20,.07)); flex: none; }
.crm-buy-nophoto { background: var(--cr-surface-2, #f2f3f5); }
.crm-buy-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.crm-buy-item .product-link-cell.crm-buy-name { display: block; width: auto; margin: 0; padding: 0; border: 0; background: none; text-align: left; cursor: pointer;
  font: inherit; font-size: 14px; font-weight: 600; line-height: 1.3; color: var(--cr-ink, #141414); overflow-wrap: anywhere; text-decoration: none; }
.crm-buy-item .crm-buy-name:hover, .crm-buy-item .crm-buy-name:focus-visible { color: var(--cr-green-dark, #148a51); text-decoration: underline; }
.crm-buy-stock { font-size: 13px; color: var(--cr-ink-2, #4a4a50); }
.crm-buy-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
.crm-buy-line { font-size: 12.5px; color: var(--cr-ink-2, #4a4a50); }
.crm-buy-why { font-size: 12px; color: var(--cr-gray, #86868b); line-height: 1.35; }
.crm-buy-alts { font-size: 12.5px; color: var(--cr-ink-2, #4a4a50); }
.crm-buy-ask > summary { list-style: none; cursor: pointer; display: inline-flex; padding: 0 !important; border: 0 !important; }
.crm-buy-ask > summary::-webkit-details-marker { display: none; }
.crm-v2 .crm-buy-ask > summary::after, .crm-buy-ask > summary::after { content: none !important; display: none; }
.crm-buy-ask > summary .crm-badge::after { content: "›"; display: inline-block; margin-left: 4px; transition: transform .18s ease; }
.crm-buy-ask[open] > summary .crm-badge::after { transform: rotate(90deg); }
.crm-buy-ask-list { display: flex; flex-direction: column; gap: 4px; margin: 6px 0 2px; }
.crm-buy-ask-row { all: unset; cursor: pointer; display: flex; flex-direction: column; gap: 1px; padding: 8px 10px; border-radius: var(--cr-r-md, 12px);
  background: #fff; border: 1px solid var(--cr-line, rgba(20,20,20,.07)); font-size: 13px; }
.crm-buy-ask-row span { color: var(--cr-ink-2, #4a4a50); }
.crm-buy-ask-row i { font-style: normal; font-size: 12px; color: var(--cr-green-dark, #148a51); }
.crm-buy-qty { display: flex; align-items: center; gap: 4px; flex: none; padding-top: 4px; }
.crm-buy-qty input {
  width: 68px; border: 0; background: var(--crm-field, #eceef1); border-radius: var(--cr-r-md, 12px); padding: 9px 6px; font: inherit;
  font-size: 16px; font-weight: 700; text-align: center; color: var(--cr-ink, #141414);
}
.crm-buy-item.is-picked .crm-buy-qty input { background: #fff; }
.crm-buy-qty input:focus { outline: none; background: #fff; box-shadow: 0 0 0 2px var(--cr-green, #1aa260); }
.crm-buy-qty span { font-size: 12px; color: var(--cr-gray, #86868b); }
.crm-buy-actions { display: flex; gap: 8px; flex-wrap: wrap; padding: var(--cr-pad-y, 12px) var(--cr-pad-x, 14px); border-top: 1px solid var(--cr-line, rgba(20,20,20,.07)); }
.crm-buy-marked { display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 6px 0; font-size: 13.5px; }
.crm-buy-never { display: flex; flex-direction: column; gap: 5px; font-size: 13.5px; }
.crm-buy-never-head b { font-size: 14px; }
.crm-buy-never-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 2px; }
.crm-buy-never-find { display: flex; flex-direction: column; gap: 6px; }
.crm-buy-never-res { display: flex; flex-direction: column; gap: 4px; }
.crm-buy-never-opt { all: unset; cursor: pointer; padding: 8px 10px; border-radius: var(--cr-r-md, 12px); background: var(--crm-field, #eceef1); font-size: 13px; }
.crm-buy-never-opt:hover { background: var(--cr-green-bg, #eaf7f0); }
.crm-buy-doc .crm-li-sub b { color: var(--cr-ink, #141414); }
.crm-buy-stale { color: var(--cr-amber, #9a6a0c); }

/* Печатные формы 1С (2026-09-21) */
.crm-print-row { margin: 8px 0 4px; }
.crm-print-forms { margin: 4px 0 10px; }
.crm-print-forms .crm-chip.active { background: var(--cr-green, #1aa260); border-color: transparent; color: #fff; }
.crm-print-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
.crm-print-actions .crm-btn { text-decoration: none; flex: 1 1 0; justify-content: center; text-align: center; }
.crm-print-sent { color: var(--cr-green-dark, #148a51); font-weight: 600; margin: -4px 0 12px; }
.crm-print-pages { display: flex; flex-direction: column; gap: 10px; }
.crm-print-page { display: block; width: 100%; height: auto; background: #fff; border: 1px solid var(--cr-line, rgba(20,20,20,.07));
  border-radius: var(--cr-r-md, 12px); box-shadow: 0 2px 10px rgba(20, 40, 30, 0.06); }
.crm-print-btn { margin-top: 4px; align-self: flex-start; }
.crm-print-pagelink { display: block; cursor: zoom-in; }
.crm-buy-doc .crm-li-body { display: flex; flex-direction: column; align-items: flex-start; }

/* ===== «Анализ» — продажи выбранных товаров по клиентам (crm-sales.js,
   2026-09-23). Выбор товаров — те же строки дерева, что в «Промо»; плитки,
   воронка и столбики — набор .sa-* из раздела «Сайт». Цвета графика — две
   ступени зелёного (проверены валидатором палитры: светлая 2,09:1 к белому):
   тёмная — повторные покупки, светлая — первые. ===== */
.sl-pick { margin-bottom: 12px; }
.sl-pick > summary .crm-li-n { margin-right: 10px; }
.sl-modes .crm-seg, .sl-periods .crm-seg { padding-left: 4px; padding-right: 4px; }
.sl-selrow { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin: -2px 12px 10px; font-size: 13.5px; color: var(--cr-ink-2, #4a4a50); }
.sl-selrow[hidden] { display: none; }
.sl-selrow > span { margin-right: auto; }
.sl-search { padding: 10px 12px 0; }
.sl-search .crm-search { margin: 0; }
.sl-intro { margin-top: 4px; }
.sl-head .sl-title { font-size: 17px; font-weight: 700; letter-spacing: -0.01em; }
.sl-head .hint { margin-top: 2px; }
.sl-periods { margin: 10px 0 0; }
.sl-excl { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 10px; margin-top: 10px; font-size: 13.5px; color: var(--cr-ink-2, #4a4a50); }
.sl-stale { margin: 8px 0 0; color: var(--cr-amber, #9a6a0c); }
.sl-verdict ul { list-style: none; margin: 8px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.sl-v { position: relative; padding-left: 14px; font-size: 14px; line-height: 1.45; }
.sl-v::before { content: ""; position: absolute; left: 0; top: 0.55em; width: 6px; height: 6px; border-radius: 50%; background: var(--cr-lgray, #b4b4ba); }
.sl-v-good::before { background: var(--cr-green, #1aa260); }
.sl-v-warn::before { background: var(--cr-amber, #9a6a0c); }
.sl-v-bad::before { background: var(--cr-danger, #c0392b); }
.sl-v-tag { font-weight: 700; }
.sl-v-good .sl-v-tag { color: var(--cr-green-dark, #148a51); }
.sl-v-warn .sl-v-tag { color: var(--cr-amber, #9a6a0c); }
.sl-v-bad .sl-v-tag { color: var(--cr-danger, #c0392b); }
.sl-tiles { margin: 0 0 10px; }
.sl-chart { padding-left: 46px; }
.sl-chart .sa-bar.sl-rep { fill: #148a51; }
.sl-chart .sa-bar.sl-trial { fill: #6cc596; }
.sl-chart .sa-bar.sa-bar-on { opacity: 0.8; }
.sl-chart .sa-bar.sl-partial { opacity: 0.5; }
.sl-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 6px 0 8px; font-size: 12.5px; color: var(--cr-ink-2, #4a4a50); }
.sl-legend span { display: inline-flex; align-items: center; gap: 6px; }
.sl-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; }
.sl-legend i.sl-rep { background: #148a51; }
.sl-legend i.sl-trial { background: #6cc596; }
.sl-h4-gap { margin-top: 18px; }
.sl-two { display: grid; grid-template-columns: 1fr; gap: 18px; }
@media (min-width: 720px) { .sl-two { grid-template-columns: 1fr 1fr; } }
.sl-two h4 { margin: 0 0 8px; }
.sl-table-wrap { overflow-x: auto; margin: 6px 0 0; }
.sl-table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
.sl-table th { text-align: right; font-weight: 600; color: var(--cr-gray, #86868b); font-size: 12px; padding: 6px 5px; white-space: nowrap; border-bottom: 1px solid var(--cr-line, rgba(20,20,20,.07)); }
.sl-table td { text-align: right; padding: 8px 5px; white-space: nowrap; border-bottom: 1px solid var(--cr-line, rgba(20,20,20,.07)); }
.sl-table th:first-child, .sl-table td:first-child { text-align: left; padding-left: 0; }
.sl-table tr:last-child td { border-bottom: 0; }
.sl-link { border: 0; background: none; padding: 0; font: inherit; color: var(--cr-green-dark, #148a51); cursor: pointer; text-align: left; }
.sl-chips { margin: 6px 0 8px; }
.sl-skus { display: flex; flex-direction: column; }
.sl-sku { padding: 10px 0; border-top: 1px solid var(--cr-line, rgba(20,20,20,.07)); min-width: 0; }
.sl-sku:first-child { border-top: 0; }
/* .product-link-cell из «Закупа» Аналитики даёт width:100% и отрицательные
   поля — в строке товара переопределяем, как у «Закупки». */
.sl-sku .product-link-cell.sl-sku-name { display: block; width: auto; margin: 0; padding: 0; border: 0; background: none; text-align: left;
  cursor: pointer; font: inherit; font-size: 14.5px; font-weight: 600; color: var(--cr-ink, #141414); }
.sl-sku .sl-sku-name:hover, .sl-sku .sl-sku-name:focus-visible { color: var(--cr-green-dark, #148a51); text-decoration: underline; }
.sl-sku-facts { display: flex; flex-wrap: wrap; gap: 2px 10px; margin-top: 3px; font-size: 12.5px; color: var(--cr-gray, #86868b); }
.sl-sku-facts b { color: var(--cr-ink, #141414); font-weight: 600; }
.sl-bad { color: var(--cr-danger, #c0392b); font-weight: 600; }
.sl-warn { color: var(--cr-amber, #9a6a0c); font-weight: 600; }
.sl-never { margin: 10px 0 0; }
.sl-never-list { margin: 6px 0 0; padding-left: 18px; font-size: 13px; }
.sl-clients { display: flex; flex-direction: column; }
.sl-client { display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left; border: 0; border-top: 1px solid var(--cr-line, rgba(20,20,20,.07));
  background: none; padding: 10px 0; font: inherit; color: inherit; cursor: pointer; }
.sl-client:first-child { border-top: 0; }
.sl-client-name { display: flex; align-items: center; gap: 6px; font-size: 14.5px; font-weight: 600; min-width: 0; }
.sl-client:hover .sl-client-name { color: var(--cr-green-dark, #148a51); }
.sl-client-sub { font-size: 12.5px; color: var(--cr-gray, #86868b); line-height: 1.4; }
.sl-client-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
/* «Анализ»: бренды и «Что заказать и что вывести» (2026-09-24). Строки заказа —
   те же .crm-buy-*, что в «Закупке», чтобы закупщик видел один и тот же вид. */
.sl-only { flex: none; margin-right: 6px; }
.sl-plan h4 { margin: 0 0 4px; }
.sl-plan-summary { margin: 0 0 8px; font-size: 14px; line-height: 1.45; color: var(--cr-ink-2, #4a4a50); }
.sl-plan-summary b { color: var(--cr-ink, #141414); }
.sl-plan-group { margin: 0 0 12px; }
/* «повторили 4 из 22 (18%) — повтор низкий» на телефоне обрезалось справа. */
.sl-plan .crm-buy-meta .crm-badge { white-space: normal; text-align: left; line-height: 1.3; }
/* Контраст на зелёной подложке выбранной строки (правило пользователя: на
   цветном фоне всё белое). Плашки «горит» и «повтор низкий» на зелёном
   смотрелись грязно — белая подложка, цвет остаётся в тексте; кнопки −/+ и
   пустое фото — тоже белые, с тонкой обводкой. Действует и в «Закупке». */
.crm-buy-item.is-picked .crm-buy-meta .crm-badge,
.crm-buy-item.is-picked .crm-buy-ask .crm-badge { background: #fff; box-shadow: inset 0 0 0 1px rgba(20, 20, 20, 0.06); }
.crm-buy-item.is-picked .crm-buy-nophoto { background: #fff; }
.crm-buy-item.is-picked .sl-step, .crm-buy-item.is-picked .sl-qty input { background: #fff; box-shadow: inset 0 0 0 1px rgba(20, 20, 20, 0.08); }
.crm-buy-item.is-picked .sl-qty input:focus { box-shadow: 0 0 0 2px var(--cr-green, #1aa260); }
.sl-qty { display: flex; align-items: center; gap: 6px; margin-top: 6px; }
.sl-qty input {
  width: 64px; border: 0; background: var(--crm-field, #eceef1); border-radius: var(--cr-r-md, 12px); padding: 8px 4px; font: inherit;
  font-size: 16px; font-weight: 700; text-align: center; color: var(--cr-ink, #141414); -moz-appearance: textfield;
}
.sl-qty input::-webkit-outer-spin-button, .sl-qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.crm-buy-item.is-picked .sl-qty input { background: #fff; }
.sl-qty input:focus { outline: none; background: #fff; box-shadow: 0 0 0 2px var(--cr-green, #1aa260); }
.sl-step { width: 36px; height: 36px; flex: none; border: 0; border-radius: 50%; background: var(--cr-surface-2, #f2f3f5); color: var(--cr-ink, #141414);
  font: inherit; font-size: 20px; line-height: 1; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.crm-buy-item.is-picked .sl-step { background: #fff; }
.sl-step:active { transform: scale(0.94); }
.sl-qty span { font-size: 12px; color: var(--cr-gray, #86868b); }
.sl-plan-actions { align-items: center; }
.sl-plan-sum { flex: 1 1 100%; font-size: 13.5px; font-weight: 600; color: var(--cr-ink, #141414); }
.sl-wa { display: inline-flex; align-items: center; gap: 6px; }
.sl-phone-form input { width: 200px; }
.sl-plan-why { margin-top: 3px; font-size: 13px; line-height: 1.4; color: var(--cr-ink-2, #4a4a50); }
.sl-plan-why-drop { color: var(--cr-danger, #c0392b); }
.sl-plan-why-stop { color: var(--cr-amber, #9a6a0c); }
.sl-plan-how { margin: 10px 0 0; }
.sl-how { margin: 4px 0 96px; }
.sl-how p { color: var(--cr-ink-2, #4a4a50); }
.sl-good { color: var(--cr-green-dark, #148a51); font-weight: 600; }
/* Черновик заказа поставщику в 1С (2026-09-24) — строка под кнопками группы. */
.sl-draft-state { padding: 0 var(--cr-pad-x, 14px) var(--cr-pad-y, 12px); font-size: 13px; line-height: 1.45; color: var(--cr-ink-2, #4a4a50); }
/* «Ассортимент»: решение закупщицы «Выводим / Оставляем» (v3, 25.09). */
.crm-mx-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.crm-mx-actions .crm-btn { min-height: 38px; padding: 8px 14px; font-size: 14px; }
.crm-mx-decided { margin-top: 8px; font-size: 13px; line-height: 1.5; color: var(--cr-ink-2, #4a4a50); }
/* «Товары → Поставщики» (v3, 25.09): документы 1С внутри карточки поставщика. */
.crm-sup-docs { border-top: 1px solid var(--cr-line, #ececef); }
.crm-sup-docs-title { padding: 10px var(--cr-pad-x, 14px) 2px; font-size: 12px; font-weight: 600; letter-spacing: .02em;
  text-transform: uppercase; color: var(--cr-gray, #86868b); }
.crm-sup-card .crm-buy-actions { border-top: 1px solid var(--cr-line, #ececef); }

/* ===== «Новый заказ» — пробить заказ клиента в 1С (crm-order.js, 2026-09-24,
   вторая редакция тем же днём). Три шага карточками, закреплённая панель
   итога над меню, сводка перед пробитием. Строки — те же .crm-buy-*, что в
   «Закупке» и «Анализе». ===== */
.no-wrap { padding-bottom: 24px; }
.no-h4 { margin: 18px 0 8px; }
.no-step { background: var(--white, #fff); border: 1px solid var(--cr-line, rgba(20,20,20,.07)); border-radius: var(--cr-r-lg, 16px);
  padding: var(--cr-pad-y, 12px) var(--cr-pad-x, 14px); margin: 0 0 12px; display: flex; flex-direction: column; gap: 10px; transition: opacity .2s; }
.no-step.no-dim { opacity: .45; pointer-events: none; }
.no-step-h { display: flex; align-items: center; gap: 8px; font-size: 16px; font-weight: 700; }
.no-num { width: 24px; height: 24px; border-radius: 50%; background: var(--cr-green-dark, #148a51); color: #fff; font-size: 13px;
  display: inline-flex; align-items: center; justify-content: center; flex: none; }
.no-step-n { min-width: 22px; padding: 1px 7px; border-radius: 999px; background: var(--cr-green-bg, #eaf7f0); color: var(--cr-green-dark, #148a51);
  font-size: 12.5px; text-align: center; }
.no-step-n:empty { display: none; }
.no-clear { margin-left: auto; font-size: 13px; }
.no-sub-h { font-size: 12px; font-weight: 600; color: var(--cr-gray, #86868b); margin: 2px 0 6px; }
.no-field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.no-field .crm-seg-row { margin: 0; }
.no-label { font-size: 12px; font-weight: 600; color: var(--cr-gray, #86868b); }
.no-label-hint { font-weight: 500; }
.no-opts { display: flex; flex-direction: column; gap: 12px; }
.no-client { display: flex; align-items: flex-start; gap: 10px; }
.no-client-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.no-client-name, .no-client-link { border: 0; background: none; padding: 0; font: inherit; text-align: left; cursor: pointer; color: var(--cr-ink, #141414); overflow-wrap: anywhere; }
.no-client-name { font-size: 17px; font-weight: 700; }
.no-client-link { font-weight: 600; }
.no-client-name:hover, .no-client-link:hover { color: var(--cr-green-dark, #148a51); }
.no-client-list { margin: 0; }
.no-pick { width: 100%; border: 0; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.no-pick:hover { background: var(--cr-green-bg, #eaf7f0); }
.no-find { position: relative; }
.no-find .crm-search { padding-right: 40px; }
.no-find-clear { position: absolute; right: 6px; top: 50%; transform: translateY(-50%); width: 32px; height: 32px; border: 0; border-radius: 50%;
  background: none; color: var(--cr-gray, #86868b); font-size: 22px; line-height: 1; cursor: pointer; }
.no-results, .no-lines { margin: 0; }
.no-results .crm-buy-item:first-child, .no-lines .crm-buy-item:first-child { border-top: 0; }
.no-res { align-items: center; }
.no-res-tap { cursor: pointer; }
.no-res-tap:hover { background: var(--cr-green-bg, #eaf7f0); }
.no-res.is-in { background: var(--cr-green-bg, #eaf7f0); }
.no-res.is-in .crm-buy-nophoto { background: #fff; }
.no-res-name { font-size: 14px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.no-res .crm-buy-why b { color: var(--cr-ink, #141414); }
.no-add-btn { flex: none; min-width: 36px; height: 36px; padding: 0 8px; border-radius: 999px; background: var(--cr-green-dark, #148a51); color: #fff;
  font-size: 18px; font-weight: 700; display: inline-flex; align-items: center; justify-content: center; }
.no-res.is-in .no-add-btn { font-size: 14px; }
.no-vars { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.no-vars .crm-chip.active { background: var(--cr-green-dark, #148a51); border-color: transparent; color: #fff; }
.no-line { position: relative; padding-right: 40px; }
.no-line .crm-buy-meta .crm-badge { white-space: normal; text-align: left; line-height: 1.3; }
.no-del { position: absolute; top: 8px; right: 6px; width: 32px; height: 32px; border: 0; border-radius: 50%; background: none;
  color: var(--cr-gray, #86868b); font-size: 22px; line-height: 1; cursor: pointer; }
.no-del:hover { background: var(--cr-surface-2, #f2f3f5); color: var(--cr-danger, #c0392b); }
.no-ctrl { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin-top: 2px; }
.no-ctrl .sl-qty { margin-top: 4px; }
.no-price { display: flex; align-items: center; gap: 6px; margin-top: 4px; font-size: 12px; color: var(--cr-gray, #86868b); }
/* Общее .crm-section input[type="text"] (ширина 100%, свои поля) растягивало
   количество и цену на всю строку — «шт» и «Цена» ломались по буквам. */
.crm-section .no-line .sl-qty input, .crm-section .no-line .no-price input { flex: none; border: 0; border-radius: var(--cr-r-md, 12px);
  padding: 8px 6px; font-size: 16px; font-weight: 700; color: var(--cr-ink, #141414); background: var(--crm-field, #eceef1); }
.crm-section .no-line .sl-qty input { width: 64px; text-align: center; }
.crm-section .no-line .no-price input { width: 104px; text-align: right; }
.crm-section .no-line .sl-qty input:focus, .crm-section .no-line .no-price input:focus { background: #fff; box-shadow: 0 0 0 2px var(--cr-green, #1aa260); border: 0; }
.no-line .sl-qty span, .no-price span { white-space: nowrap; }
.no-prices { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 2px; font-size: 12.5px; }
.no-cost { color: var(--cr-ink-2, #4a4a50); margin-right: 2px; }
.no-cost b { color: var(--cr-ink, #141414); }
.no-p { border: 1px solid var(--cr-line, rgba(20,20,20,.1)); background: #fff; color: var(--cr-ink, #141414); border-radius: 999px; padding: 4px 10px;
  font: inherit; font-size: 12.5px; cursor: pointer; }
.no-p.active { background: var(--cr-green-dark, #148a51); border-color: transparent; color: #fff; }
/* Склад позиции (24.09, вёрстка ломалась на узком телефоне): подпись над
   переключателем, кнопки делят ширину поровну, в каждой — склад и доступно. */
.no-whrow { display: flex; flex-direction: column; gap: 4px; margin-top: 2px; }
.no-wh-label { font-size: 11.5px; color: var(--cr-gray, #86868b); }
.no-whseg { display: flex; width: 100%; max-width: 320px; background: var(--crm-field, #eceef1); border-radius: 999px; padding: 2px; gap: 2px; box-sizing: border-box; }
.no-whseg button { flex: 1 1 0; min-width: 0; display: inline-flex; align-items: baseline; justify-content: center; gap: 5px; border: 0; background: none;
  border-radius: 999px; padding: 6px 8px; font: inherit; font-size: 12.5px; color: var(--cr-ink-2, #4a4a50); cursor: pointer; white-space: nowrap; }
.no-whseg button b { font-weight: 600; font-variant-numeric: tabular-nums; }
.no-whseg button.active { background: #fff; color: var(--cr-ink, #141414); font-weight: 600; box-shadow: 0 1px 3px rgba(0,0,0,.12); }
.no-avail span { white-space: nowrap; }
.no-tools { display: flex; flex-wrap: wrap; gap: 8px; }
.no-tools .crm-btn { flex: 1 1 auto; }
.no-price-rule { font-size: 14px; font-weight: 600; padding: 2px 0; }
.no-price-fixed { display: flex; align-items: baseline; gap: 3px; margin-top: 4px; font-size: 16px; }
.no-price-fixed span { font-size: 12px; color: var(--cr-gray, #86868b); }
.no-var { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px 3px 3px; max-width: 100%; }
.no-var img { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; flex: none; background: #fff; }
.no-var span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.no-var:not(:has(img)) { padding-left: 10px; }
.no-need { background: #fff8eb; }
.no-need .crm-buy-nophoto { background: #fff; }
.no-need-h { font-size: 12.5px; font-weight: 600; color: var(--cr-amber, #9a6a0c); }
.no-quote { font-size: 12px; color: var(--cr-ink-2, #4a4a50); font-style: italic; overflow-wrap: anywhere; }
.no-site { font-size: 12.5px; line-height: 1.4; padding: 6px 8px; border-radius: 10px; background: #fff7e6; color: #6b4b06; }
.no-site.ok { background: var(--cr-green-bg, #eaf7f0); color: var(--cr-green-dark, #148a51); }
.no-site-box:empty { display: none; }
.no-tag { display: inline-block; font-size: 11px; font-weight: 700; border-radius: 999px; padding: 1px 7px; font-style: normal; }
.no-tag.ok { background: var(--cr-green-bg, #eaf7f0); color: var(--cr-green-dark, #148a51); }
.no-tag.warn { background: #fff4de; color: var(--cr-amber, #9a6a0c); }
.no-tag.bad { background: #fdecea; color: var(--cr-danger, #c0392b); }
.no-paste-ta { font-size: 13px; font-family: ui-monospace, Menlo, Consolas, monospace; }
.no-paste-sum { font-size: 13.5px; font-weight: 600; margin-top: 4px; }
.no-paste-keep-h { margin: 12px 0 6px; }
.no-chat-list { display: flex; flex-direction: column; max-height: 55vh; overflow-y: auto; }
.no-chat-row { display: flex; align-items: flex-start; gap: 10px; padding: 9px 0; border-top: 1px solid var(--cr-line, rgba(20,20,20,.07)); cursor: pointer; }
.no-chat-row:first-child { border-top: 0; }
.no-chat-row .crm-box { margin-top: 12px; width: 20px; height: 20px; flex: none; accent-color: var(--cr-green, #1aa260); }
.no-chat-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; font-size: 14px; }
.no-draft-done { color: var(--cr-amber, #9a6a0c); font-weight: 600; }
.no-ai-note { font-size: 12px; color: var(--cr-amber, #9a6a0c); }
/* Отметка оплаты менеджером в карточке заказа (24.09). */
.crm-pm { margin: 12px 0; }
.crm-pm-kinds { flex-wrap: wrap; margin: 6px 0; }
.crm-pm-form { display: flex; flex-direction: column; gap: 8px; margin: 8px 0; padding: var(--cr-pad-y, 12px) var(--cr-pad-x, 14px);
  background: var(--surface-2, #f4f5f6); border-radius: 12px; }
.crm-pm-field { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--gray); }
.crm-pm-field .crm-input { font-size: 16px; }
.crm-pm-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.crm-pm-list { list-style: none; padding: 0; margin: 8px 0 0; display: flex; flex-direction: column; gap: 6px; font-size: 14px; }
/* «Документы 1С» (24.09): списки заказов и реализаций с действиями. */
.docs-wrap { display: flex; flex-direction: column; gap: 10px; }
.docs-tabs { align-self: stretch; margin: 0; }
.docs-tools { display: flex; gap: 8px; align-items: center; }
.docs-tools .crm-search { flex: 1; min-width: 0; }
.docs-sort { flex: none; width: auto; max-width: 46%; }
.docs-chips { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0; }
.docs-chips::-webkit-scrollbar { display: none; }
.docs-count { margin: 0; }
.docs-row { flex-direction: column; align-items: stretch; padding: 0; }
.docs-head { display: grid; grid-template-columns: 1fr auto; grid-template-areas: "main sum" "client client" "sub sub";
  gap: 2px 10px; width: 100%; text-align: left; background: none; border: 0; padding: var(--cr-pad-y, 12px) var(--cr-pad-x, 14px);
  font: inherit; color: inherit; cursor: pointer; }
.docs-main { grid-area: main; font-size: 14px; display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center; }
.docs-client { grid-area: client; font-weight: 600; font-size: 15px; overflow-wrap: anywhere; }
.docs-head .crm-li-sub { grid-area: sub; }
.docs-sum { grid-area: sum; font-weight: 700; white-space: nowrap; }
.docs-acts { display: flex; flex-wrap: wrap; gap: 8px; padding: 0 var(--cr-pad-x, 14px) var(--cr-pad-y, 12px); }
.docs-acts .crm-btn { flex: 0 1 auto; }
.docs-row.is-open { background: var(--cr-green-bg, #eaf7f0); }
.docs-danger { color: var(--cr-danger, #c0392b) !important; }
/* Прослойки каркаса «Документов 1С»: дети встают прямо в колонку .docs-wrap. */
.docs-slot { display: contents; }
/* .crm-v2 .crm-li перебивал .docs-row { padding: 0 } — отступ строки
   складывался с отступом .docs-head. */
.crm-v2 .docs-row { padding: 0; }
/* Только что появившийся документ — тонкая зелёная полоска слева. */
.docs-row.docs-new { box-shadow: inset 3px 0 0 var(--cr-green, #1aa260); }
/* На зелёной (и любой цветной) подложке кнопки и чипы — белые с волосяной
   обводкой (просьба пользователя 24.09: «на зелёном фоне кнопки белые»;
   в раскрытой реализации «Документов 1С» они были серыми). Главная
   зелёная, красная и WhatsApp не трогаются. Цепочка :not() нужна для
   веса: иначе побеждает .crm-v2 / body.crm-ui-v2 .crm-btn-ghost. */
.docs-row.is-open .crm-btn:not(.crm-btn-primary):not(.crm-btn-danger):not(.docs-danger-btn):not(.crm-btn-wa),
.no-job .crm-btn:not(.crm-btn-primary):not(.crm-btn-danger):not(.docs-danger-btn):not(.crm-btn-wa),
.crm-lead-block .crm-btn:not(.crm-btn-primary):not(.crm-btn-danger):not(.docs-danger-btn):not(.crm-btn-wa),
.no-res.is-in .crm-chip:not(.active),
.crm-li-on .crm-mini {
  background: #fff;
  box-shadow: inset 0 0 0 1px rgba(20, 20, 20, 0.08);
}
.docs-row.is-open .crm-btn:disabled { opacity: .55; }
/* Плашка «Проведён / Реализация» — зелёная на зелёном, сливалась с фоном. */
.docs-row.is-open .no-tag.ok { background: #fff; }
/* Поле поиска клиента в блоке «Новый клиент» (карточка клиента) — белое. */
.crm-block.crm-lead-block .crm-search { background: #fff; box-shadow: inset 0 0 0 1px rgba(20, 20, 20, 0.08); }
.docs-danger-btn { background: var(--cr-danger, #c0392b); color: #fff; border: 0; }
.docs-stage { margin: 6px 0; }
/* Меню «⋯ Действия» (26.09): список снизу, у пункта — что он сделает;
   безопасное сверху, распровести/удалить — отдельной группой, красным. */
.docs-more-btn span { font-weight: 800; letter-spacing: 1px; margin-right: 2px; }
.docs-menu { display: flex; flex-direction: column; margin: 12px 0 0; border-radius: 14px; overflow: hidden;
  box-shadow: inset 0 0 0 1px rgba(20, 20, 20, 0.08); }
.docs-menu + .docs-menu { margin-top: 10px; }
.docs-menu-item { all: unset; box-sizing: border-box; display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; cursor: pointer;
  background: #fff; border-top: 1px solid rgba(20, 20, 20, 0.06); }
.docs-menu-item:first-child { border-top: 0; }
.docs-menu-item:hover, .docs-menu-item:focus-visible { background: var(--cr-surface-2, #f4f5f7); }
.docs-menu-item b { font-size: 15px; font-weight: 600; color: var(--cr-ink, #141414); }
.docs-menu-item span { font-size: 12.5px; color: var(--cr-gray, #86868b); line-height: 1.35; }
.docs-menu-item.is-warn b { color: #9a6a0c; }
.docs-menu-item.is-danger b { color: var(--cr-danger, #c0392b); }
.docs-row.docs-deleted .docs-client, .docs-row.docs-deleted .docs-sum { color: var(--cr-gray, #86868b); text-decoration: line-through; }
.crm-odoc .docs-acts { padding: 0; margin-top: 10px; }
.crm-odoc-sale { margin-top: 6px; }
.no-edit-status { margin-top: 8px; font-size: 13.5px; }
.docs-more { align-self: center; }
/* «Корзина уже пробита в 1С» — сведение, не ошибка: зелёным, как «выполнено»;
   «после корзины пробили другой заказ» — янтарным, это «проверьте». */
.no-chat-info { background: var(--cr-green-bg, #eaf7f0); color: var(--cr-green-dark, #148a51); border-radius: 12px;
  padding: 9px 12px; font-size: 13.5px; font-weight: 600; line-height: 1.45; margin: 0 0 8px; }
.no-chat-info.warn { background: #fff4de; color: var(--cr-amber, #9a6a0c); }
.no-ai-summary { margin: 0; font-size: 14.5px; font-weight: 600; }
.no-sheet-actions { flex-wrap: wrap; }
.no-bar-btns { display: flex; gap: 8px; flex: none; }
.no-bar .no-draft { padding: 12px 14px; font-size: 14px; }
.no-add-btn.is-in { background: #fff; color: var(--cr-green-dark, #148a51); box-shadow: inset 0 0 0 2px var(--cr-green-dark, #148a51); }
@media (max-width: 480px) {
  .no-bar { flex-wrap: wrap; }
  .no-bar-info { flex: 1 1 100%; }
  .no-bar-btns { flex: 1 1 100%; }
  .no-bar-btns .crm-btn { flex: 1; }
}
.no-line-note { font-size: 12.5px; color: var(--cr-ink-2, #4a4a50); line-height: 1.4; }
.no-note-warn { padding: 8px 10px; border-radius: var(--cr-r-md, 12px); background: #fff7e6; color: var(--cr-amber, #9a6a0c); font-size: 13px; line-height: 1.4; }
.no-empty { margin: 0; }
/* Панель итога — закреплена внизу, над парящим меню телефона. */
.no-bar { position: sticky; bottom: 12px; z-index: 5; display: flex; align-items: center; gap: 12px; margin: 4px 0 0;
  padding: 10px 12px 10px 16px; background: rgba(255, 255, 255, 0.92); -webkit-backdrop-filter: saturate(180%) blur(18px); backdrop-filter: saturate(180%) blur(18px);
  border: 1px solid var(--cr-line, rgba(20,20,20,.08)); border-radius: 20px; box-shadow: 0 8px 28px rgba(20, 20, 20, 0.14); }
.no-bar[hidden] { display: none; }
.no-bar-info { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.no-bar-sum { font-size: 19px; font-weight: 700; font-variant-numeric: tabular-nums; }
.no-bar-sub { font-size: 12px; color: var(--cr-ink-2, #4a4a50); }
.no-bar .no-send { flex: none; padding: 12px 18px; font-size: 15px; }
@media (max-width: 700px) {
  .no-bar { bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }
}
.no-job { margin: 14px 0 0; padding: var(--cr-pad-y, 12px) var(--cr-pad-x, 14px); border-radius: var(--cr-r-lg, 16px);
  background: var(--cr-surface-2, #f2f3f5); font-size: 14px; line-height: 1.45; }
.no-job.is-done { background: var(--cr-green-bg, #eaf7f0); }
.no-job.is-error { background: #fdecea; }
/* На цветной подложке кнопки белые (правило контраста пользователя). */
.no-job .crm-btn-ghost, .no-job.is-done .crm-btn-ghost { background: #fff; box-shadow: inset 0 0 0 1px rgba(20, 20, 20, 0.08); }
.no-job-title { font-weight: 700; margin-bottom: 2px; }
.no-job-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.no-job-next { margin-top: 8px; font-size: 13px; }
.no-wait { color: var(--cr-amber, #9a6a0c); font-weight: 600; }
.no-row .crm-li-body { gap: 3px; }
.no-row-status { font-size: 13px; line-height: 1.45; }
.no-row-status .no-job-actions { margin-top: 4px; }
/* Сводка перед пробитием и перед реализацией. */
.no-sheet-back { position: fixed; inset: 0; z-index: 1000; background: rgba(20, 20, 20, 0.38); display: flex; align-items: flex-end; justify-content: center; }
.no-sheet { width: 100%; max-width: 520px; max-height: 88vh; overflow-y: auto; background: #fff; border-radius: 22px 22px 0 0;
  padding: 18px 18px calc(18px + env(safe-area-inset-bottom, 0px)); display: flex; flex-direction: column; gap: 8px; }
@media (min-width: 701px) {
  .no-sheet-back { align-items: center; }
  .no-sheet { border-radius: 22px; }
}
.no-sheet h3 { margin: 0; font-size: 19px; }
.no-sum-client { font-size: 16px; font-weight: 700; }
.no-sum-lines { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; }
.no-sum-lines li { display: flex; justify-content: space-between; gap: 10px; padding: 8px 0; border-top: 1px solid var(--cr-line, rgba(20,20,20,.07)); font-size: 14px; }
.no-sum-lines li span { min-width: 0; overflow-wrap: anywhere; }
.no-sum-lines li i { font-style: normal; color: var(--cr-ink-2, #4a4a50); white-space: nowrap; }
.no-sum-lines li em { display: block; font-style: normal; font-size: 12px; color: var(--cr-amber, #9a6a0c); }
.no-sum-lines li b { white-space: nowrap; font-variant-numeric: tabular-nums; }
.no-sum-total { display: flex; justify-content: space-between; padding-top: 8px; border-top: 1px solid var(--cr-line, rgba(20,20,20,.12)); font-size: 16px; }
.no-sum-total b { font-size: 20px; }

/* Новая версия по курсу «Реальный отдел продаж» (13.10, static/crm-reop.js):
   переключатель «Новая / Старая версия» в шапке и блоки новой версии. */
.crm-reop-toggle { display: inline-flex; align-items: center; gap: 6px; margin-left: 8px; padding: 3px 10px; border-radius: 999px;
  border: 1px solid var(--green-border, #b7e3c8); background: #fff; color: #3a3f45; font: inherit; font-size: 12px; font-weight: 600;
  cursor: pointer; white-space: nowrap; }
.crm-reop-toggle.on { background: var(--green-bg, #eaf7f0); color: var(--green-dark, #148a51); }
.crm-reop-toggle:disabled { opacity: .6; cursor: wait; }
.crm-reop-toggle .crm-reop-dot { width: 8px; height: 8px; border-radius: 50%; background: #9aa3ab; }
.crm-reop-toggle.on .crm-reop-dot { background: var(--green, #1aa260); }
.crm-reop-tag { display: inline-block; font-size: 11px; font-weight: 600; line-height: 1.5; padding: 0 7px; border-radius: 999px;
  background: #eef2ef; color: #55606a; vertical-align: 1px; white-space: nowrap; }
.crm-reop-tag-risk { background: #fcebec; color: #b0262e; }
.crm-reop-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.crm-reop-key.is-dormant .crm-li-name { color: #8a1f26; }
.crm-reop-note { margin: 8px 2px 0; }
.crm-reop-callbtn { margin-right: 6px; }
/* «Моя неделя», «Планёрка», игра «Вернём крупных» (13.10). */
.crm-reop-week, .crm-reop-person, .crm-reop-game, .crm-reop-notes, .crm-reop-switch { display: flex; flex-direction: column; gap: 8px; }
.crm-reop-week .crm-week-head, .crm-reop-person .crm-week-head, .crm-reop-game .crm-week-head,
.crm-reop-notes .crm-week-head, .crm-reop-switch .crm-week-head { margin-bottom: 0; }
.crm-reop-main { display: flex; flex-direction: column; gap: 2px; }
.crm-reop-big { font-size: 26px; font-weight: 700; line-height: 1.15; font-variant-numeric: tabular-nums; }
.crm-reop-delta { font-weight: 700; white-space: nowrap; color: var(--gray); }
.crm-reop-delta.up { color: var(--green-dark); }
.crm-reop-delta.down { color: var(--danger); }
.crm-reop-goal { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.crm-reop-goalbar { width: 100%; box-sizing: border-box; grid-template-columns: auto minmax(0, 1fr) auto; }
.crm-reop-plan { margin: 0; font-size: 14px; line-height: 1.45; white-space: pre-wrap; overflow-wrap: anywhere; }
.crm-reop-next, .crm-reop-nogoal { margin: 0; }
.crm-reop-sub { margin: 0; font-size: 13.5px; color: var(--cr-ink-2, #4a4a50); line-height: 1.45; }
.crm-reop-form { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.crm-reop-fld { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--gray); min-width: 0; }
.crm-reop-form .crm-search, .crm-reop-form .crm-select { margin: 0; font-size: 16px; }
.crm-reop-form textarea.crm-search { resize: vertical; min-height: 64px; line-height: 1.4; }
.crm-reop-form-acts { display: flex; flex-wrap: wrap; gap: 8px; }
.crm-reop-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
@media (max-width: 480px) { .crm-reop-grid { grid-template-columns: 1fr; } }
.crm-reop-cells { grid-template-columns: repeat(4, minmax(0, 1fr)); margin-bottom: 0; }
@media (max-width: 560px) { .crm-reop-cells { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.crm-reop-cells .crm-reop-cell { cursor: default; min-width: 0; }
.crm-reop-cells .crm-reop-cell i { overflow-wrap: anywhere; }
.crm-reop-gamemini, .crm-reop-rows { border-top: 1px solid var(--crm-sep, #e6e8ec); padding-top: 8px; }
.crm-reop-gamemini > summary, .crm-reop-rows > summary { list-style: none; cursor: pointer; display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 10px; }
.crm-reop-gamemini > summary::-webkit-details-marker, .crm-reop-rows > summary::-webkit-details-marker { display: none; }
.crm-reop-gamemini > summary::after, .crm-reop-rows > summary::after { content: "›"; color: var(--gray); font-size: 18px; line-height: 1; margin-left: auto; transition: transform .15s; }
.crm-reop-gamemini[open] > summary::after, .crm-reop-rows[open] > summary::after { transform: rotate(90deg); }
.crm-reop-rows > summary { font-size: 13.5px; font-weight: 600; }
.crm-reop-gamemini[open] > summary, .crm-reop-rows[open] > summary { margin-bottom: 8px; }
.crm-reop-board { margin: 0; }
.crm-reop-score { font-size: 20px; font-variant-numeric: tabular-nums; min-width: 28px; text-align: right; flex: none; align-self: center; }
.crm-reop-me { background: var(--green-bg); }
.crm-reop-qs { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; width: 100%; }
.crm-reop-qs .hint { margin: 0; }
.crm-reop-q { display: flex; gap: 10px; align-items: baseline; justify-content: space-between; width: 100%; font-size: 14px; }
.crm-reop-q span { min-width: 0; overflow-wrap: anywhere; }
.crm-reop-to-pl { align-self: flex-start; font-size: 14px; }
.crm-reop-weeks { margin-bottom: 2px; }
.crm-reop-tiles .crm-ptile-v { font-size: 20px; }
@media (max-width: 759px) { .crm-reop-tiles .crm-ptile:nth-child(3):last-child, .crm-reop-tiles .crm-ptile:only-child { grid-column: 1 / -1; } }
@media (min-width: 760px) { .crm-reop-tiles:has(> .crm-ptile:nth-child(4)) { grid-template-columns: repeat(4, 1fr); } }
.crm-reop-rows > summary .hint { font-weight: 400; font-size: 12.5px; }
.crm-reop-switch { border: 1px solid var(--warning, #d99a1e); background: var(--warning-bg, #fdf3e3); }
.crm-reop-switch.is-on { border-color: var(--green-border); background: var(--green-bg); }
.crm-reop-switch .hint { margin: 0; color: var(--cr-ink-2, #4a4a50); }
.crm-reop-switch .crm-btn { align-self: flex-start; }
.crm-reop-switch .crm-btn-ghost { background: #fff; }
.crm-reop-noteline { display: flex; gap: 8px; flex-wrap: wrap; }
.crm-reop-noteline .crm-select { flex: 0 0 auto; max-width: 100%; }
.crm-reop-noteline .crm-search { flex: 1 1 220px; min-width: 0; }
.crm-reop-noterow.is-done .crm-li-name { text-decoration: line-through; color: var(--gray); }
.crm-reop-pnotes { margin: 0; }
.crm-reop-person > .crm-link-btn, .crm-reop-notes > .crm-link-btn { align-self: flex-start; font-size: 13.5px; }
.crm-badge.crm-reop-badge { background: #eef2ef; color: #3c5a48; }
/* Порция 3 (13.10): причины, напоминания, шаблоны, «Правила», «Воронки», калькулятор. */
.crm-reop-sheet { display: flex; flex-direction: column; gap: 10px; }
.crm-reop-sheet > .hint { margin: -4px 0 0; overflow-wrap: anywhere; }
.crm-reop-reasons { display: flex; flex-direction: column; gap: 2px; }
.crm-reop-reason { display: flex; align-items: center; gap: 10px; padding: 9px 4px; border-bottom: 1px solid var(--crm-sep, #e6e8ec); font-size: 15px; cursor: pointer; }
.crm-reop-reason:last-child { border-bottom: 0; }
.crm-reop-reason input { width: 18px; height: 18px; margin: 0; flex: none; accent-color: var(--green); }
.crm-reop-reason.is-good span { color: var(--green-dark); font-weight: 600; }
.crm-reop-chips { padding-bottom: 0; flex-wrap: wrap; overflow: visible; }
.crm-reop-cardrem { display: flex; flex-direction: column; gap: 4px; margin: 8px 0; padding: 10px 12px; border-radius: 12px;
  background: var(--warning-bg, #fdf3e3); font-size: 14px; }
.crm-reop-grp { margin: 6px 0 0; font-size: 12px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--gray); }
.crm-reop-tpl { display: flex; flex-direction: column; gap: 6px; padding: 10px 0; border-bottom: 1px solid var(--crm-sep, #e6e8ec); }
.crm-block.crm-reop-tpl { padding: 12px 14px; border-bottom: 1px solid var(--border); }
.crm-reop-rule { display: flex; flex-direction: column; gap: 8px; }
.crm-reop-rule.is-draft { border-style: dashed; }
.crm-reop-rule.is-new { border-color: var(--green-border); box-shadow: inset 3px 0 0 var(--green); }
.crm-reop-rule .crm-btn { align-self: flex-start; }
.crm-reop-unread { color: var(--danger); }
.crm-reop-tablewrap { overflow-x: auto; margin: 0 0 12px; border: 1px solid var(--border); border-radius: var(--r-crm, 18px); background: var(--white); }
.crm-reop-ftable { width: 100%; border-collapse: collapse; font-size: 13.5px; font-variant-numeric: tabular-nums; }
.crm-reop-ftable.is-wide { min-width: 560px; }
.crm-reop-ftable th, .crm-reop-ftable td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--crm-sep, #e6e8ec); vertical-align: top; white-space: nowrap; }
.crm-reop-ftable thead th { font-size: 12px; color: var(--gray); font-weight: 600; }
.crm-reop-ftable tbody tr:last-child th, .crm-reop-ftable tbody tr:last-child td { border-bottom: 0; }
.crm-reop-ftable tbody th { font-weight: 600; }
.crm-reop-fpct { display: block; font-weight: 700; }
.crm-reop-fpct.is-good { color: var(--green-dark); }
.crm-reop-fpct.is-bad { color: var(--danger); }
.crm-reop-fsub { display: block; font-size: 11.5px; color: var(--gray); }
.crm-ptile-v.crm-reop-bad { color: var(--danger); }
.crm-reop-calc-res { margin: 0; font-size: 14px; line-height: 1.5; }
.crm-reop-money .crm-reop-sub { margin-bottom: 8px; }
.crm-reop-rem .crm-card-group { margin: 0; }
.crm-reop-reasons-card .crm-loss { margin: 0; }
/* Порция 4 (13.10): статусы, лента дня, лояльные на 1-е и 15-е, «Новые точки». */
.crm-badge.crm-reop-rfm.is-loyal { background: var(--green-bg); color: var(--green-dark); }
.crm-badge.crm-reop-rfm.is-lost { background: #fcebec; color: #b0262e; }
.crm-badge.crm-reop-rfm.is-novice { background: #e9f1fd; color: #2a5bb8; }
.crm-badge.crm-reop-rfm.is-stale { background: #f1eefa; color: #5b3fa8; }
.crm-reop-cardinfo { display: flex; flex-direction: column; gap: 4px; margin: 8px 0 0; font-size: 14px; }
.crm-reop-cardinfo .crm-badge { margin-right: 4px; }
.crm-reop-sugg { display: flex; flex-wrap: wrap; gap: 6px; }
.crm-reop-sugg:empty { display: none; }
.crm-reop-sugg .crm-chip { white-space: normal; text-align: left; }
.crm-reop-loyal b { color: var(--ink); }
.crm-reop-hours { display: grid; grid-template-columns: repeat(13, minmax(0, 1fr)); gap: 3px; align-items: end; margin: 8px 0 4px; }
.crm-reop-hour { display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 0; }
.crm-reop-hour span { font-size: 11px; color: var(--gray); font-variant-numeric: tabular-nums; }
.crm-reop-hbar { width: 100%; height: 64px; display: flex; flex-direction: column-reverse; gap: 1px; background: var(--crm-field, #eceef1); border-radius: 4px; overflow: hidden; }
.crm-reop-hour.is-quiet .crm-reop-hbar { background: #fbe9e9; }
.crm-reop-hbar i, .crm-reop-legend i { display: block; width: 100%; }
.crm-reop-hbar i.s, .crm-reop-legend i.s { background: var(--green); }
.crm-reop-hbar i.g, .crm-reop-legend i.g { background: #9ccfb3; }
.crm-reop-hbar i.c, .crm-reop-legend i.c { background: #2f6fed; }
.crm-reop-hbar i.m, .crm-reop-legend i.m { background: #d99a1e; }
.crm-reop-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin: 0 3px 0 8px; vertical-align: 0; }
.crm-reop-legend i:first-child { margin-left: 0; }
.crm-reop-series { display: flex; gap: 6px; align-items: flex-end; overflow-x: auto; padding: 6px 0 2px; scrollbar-width: thin; }
.crm-reop-sbar { flex: 0 0 38px; display: flex; flex-direction: column; align-items: center; gap: 3px; }
.crm-reop-sbar b { font-size: 12px; font-variant-numeric: tabular-nums; }
.crm-reop-sbar span { font-size: 10.5px; color: var(--gray); white-space: nowrap; }
.crm-reop-scol { width: 100%; height: 90px; display: flex; align-items: flex-end; background: var(--crm-field, #eceef1); border-radius: 6px; overflow: hidden; }
.crm-reop-scol i { display: block; width: 100%; background: var(--green); border-radius: 6px 6px 0 0; }
.crm-reop-ps.is-open { background: var(--green-bg); }
.crm-reop-psopen { border-bottom: 1px solid var(--crm-sep, #e6e8ec); }
.crm-reop-psbody { display: flex; flex-direction: column; gap: 10px; padding: 10px 14px 14px; }
.crm-reop-qual { display: flex; flex-direction: column; gap: 0; }
.crm-reop-qual .hint { margin: 4px 0 0; }
.crm-reop-grade { font-weight: 700; }
.crm-reop-grade.gA { background: var(--green-bg); color: var(--green-dark); }
.crm-reop-grade.gB { background: #e9f1fd; color: #2a5bb8; }
.crm-reop-grade.gD { background: #fcebec; color: #b0262e; }
.crm-reop-psform .crm-reop-fld span { color: var(--cr-ink-2, #4a4a50); }
.no-sheet-actions { display: flex; gap: 8px; margin-top: 6px; }
.no-sheet-actions .crm-btn { flex: 1; padding: 13px 16px; font-size: 15px; }

/* Округление потребности в «Закупке» и «Анализе» (2026-09-24). */
.crm-round { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 10px var(--cr-pad-x, 14px) 0;
  border-top: 1px solid var(--cr-line, rgba(20,20,20,.07)); font-size: 12.5px; color: var(--cr-ink-2, #4a4a50); }
.crm-round > span { margin-right: 2px; font-weight: 600; }
.crm-round .crm-chip { padding: 5px 11px; }
.crm-round .crm-chip.active { background: var(--cr-green-dark, #148a51); border-color: transparent; color: #fff; }
.crm-round + .crm-buy-actions { border-top: 0; }

/* «Отправка на сборку» в карточке заказа (2026-09-24). */
.crm-wh-form form { display: flex; flex-direction: column; gap: 12px; }
.crm-wh-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.crm-wh-field[hidden] { display: none; }
.crm-wh-field .crm-seg-row { margin: 0; }
.crm-wh-label { font-size: 12px; font-weight: 600; color: var(--cr-gray, #86868b); }
.crm-wh-addr-note { font-size: 12.5px; line-height: 1.5; color: var(--cr-ink-2, #4a4a50); }
.crm-wh-addr-alts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.crm-wh-addr-alts .crm-chip { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.crm-wh-groups { flex-wrap: wrap; gap: 6px; }
.crm-wh-groups .crm-chip.active { background: var(--cr-green-dark, #148a51); border-color: transparent; color: #fff; }
.crm-wh-auto { font-size: 11px; font-weight: 500; opacity: .75; }
.crm-wh-text { font-size: 14px; line-height: 1.45; white-space: pre-wrap; }
.crm-wh-form [hidden] { display: none !important; }
.crm-wh-direct { padding: 8px 10px; border-radius: 10px; background: var(--cr-green-bg, #eaf7f0); color: var(--cr-green-dark, #148a51); font-size: 13.5px; font-weight: 600; }
/* Предпросмотр заявки — как сообщение в WhatsApp (фон чата, зелёный пузырь). */
.crm-wa-preview { background: #efeae2; border-radius: var(--cr-r-md, 12px); padding: 10px 10px 12px; display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.crm-wa-preview[hidden] { display: none !important; }
.crm-wa-head { align-self: stretch; text-align: center; font-size: 11.5px; color: #54656f; }
.crm-wa-head span { color: inherit; }
.crm-wa-bubble { position: relative; max-width: 92%; background: #d9fdd3; color: #111b21; border-radius: 10px 0 10px 10px; padding: 7px 9px 18px;
  font-size: 14.5px; line-height: 1.38; white-space: pre-wrap; overflow-wrap: anywhere; box-shadow: 0 1px 0.5px rgba(11, 20, 26, 0.13); text-align: left; min-width: 90px; }
.crm-wa-time { position: absolute; right: 8px; bottom: 3px; font-size: 11px; color: #667781; white-space: nowrap; }
.no-sheet .crm-wa-preview { margin: 4px 0; }
.crm-wh-go { padding: 12px 16px; font-size: 15px; }
.crm-wh .crm-alert .crm-btn { margin-left: 6px; background: #fff; }

/* Вёрстка на iPhone (25.09, «кнопки −/+ не посередине, значки-счётчики
   полетели»). (1) Счётчик: высота 17px с рамкой 2px (border-box), а
   line-height 17px — цифре оставалось 13px, и она съезжала вниз. Теперь
   центрируем флексом, высота строки не участвует. (2) −/+ рисуем полосками:
   текстовые «−» и «+» стоят по-разному в Safari и Chrome (свои отступы
   кнопки по умолчанию, математическая ось шрифта). (3) Разделитель в «Ещё»
   шёл по скруглению строки — концы линии загибались. */
.crm-tabbar .crm-tab-count, .crm-more-item .crm-tab-count {
  display: inline-flex; align-items: center; justify-content: center; line-height: 1; opacity: 1;
  font-variant-numeric: tabular-nums;
}
.crm-tabbar .crm-tab-count:empty, .crm-more-item .crm-tab-count:empty { display: none; }
.sl-step { position: relative; display: inline-flex; align-items: center; justify-content: center; padding: 0; font-size: 0; }
.sl-step::before, .sl-step[aria-label="Больше"]::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 13px; height: 2px; border-radius: 1px;
  background: currentColor; transform: translate(-50%, -50%);
}
.sl-step[aria-label="Больше"]::after { width: 2px; height: 13px; }
.crm-more-item + .crm-more-item { box-shadow: none; position: relative; }
.crm-more-item + .crm-more-item::before {
  content: ""; position: absolute; top: 0; left: 10px; right: 10px; height: 1px; background: var(--border); pointer-events: none;
}
/* CRM v3 (24.09): вкладки раздела — текст с чертой под активной, а не
   «пилюли»: пилюлями внутри разделов нарисованы фильтры («Горит / Все»), и
   два одинаковых ряда путались ([data-crm-subtabs], crm.js: renderSubtabs). */
.crm-subtabs {
  display: flex; gap: 22px; overflow-x: auto; scrollbar-width: none; margin: -6px 0 14px; padding: 0 2px;
  -webkit-overflow-scrolling: touch; box-shadow: inset 0 -1px 0 var(--border, #e6e6ea);
}
.crm-subtabs::-webkit-scrollbar { display: none; }
.crm-subtabs[hidden] { display: none; }
.crm-subtab {
  flex: none; position: relative; display: inline-flex; align-items: center; gap: 6px; border: 0; background: transparent;
  padding: 10px 0 11px; font: inherit; font-size: 15px; font-weight: 600; color: var(--cr-gray, #86868b);
  cursor: pointer; -webkit-tap-highlight-color: transparent; white-space: nowrap;
}
.crm-subtab.active { color: var(--cr-ink, #141414); }
.crm-subtab.active::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; border-radius: 3px 3px 0 0; background: var(--cr-green, #1aa260);
}
.crm-subtab .crm-tab-count {
  display: inline-flex; align-items: center; justify-content: center; min-width: 18px; height: 18px; padding: 0 5px; box-sizing: border-box;
  border-radius: 999px; font-size: 11px; font-weight: 700; line-height: 1; background: var(--cr-surface-2, #f2f3f5); color: var(--cr-gray, #86868b);
  position: static; border: 0; opacity: 1; font-variant-numeric: tabular-nums;
}
.crm-subtab.active .crm-tab-count { background: var(--cr-green-bg, #eaf7f0); color: var(--cr-green-dark, #148a51); }
.crm-subtab .crm-tab-count:empty { display: none; }
/* CRM v3, этап 2 (24.09): «Документ в 1С» в карточке заказа, «+ Заказ». */
.crm-odoc { margin: 10px 0; }
.crm-odoc .crm-row-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.crm-odoc-sale { padding: 10px 0 2px; border-top: 1px solid var(--border, #e6e6ea); margin-top: 10px; }
.crm-odoc-busy { color: var(--cr-amber, #b7791f); }
.crm-new-order-btn { width: 100%; margin: 0 0 10px; }
/* «+ Заказ» слева, номер WhatsApp справа, одной строкой; до блоков карточки —
   отступ (26.09: кнопка была прибита к «Что сделать»). */
.crm-card-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 10px; } /* снизу = сверху (10 px) */
.crm-card-actions .crm-card-neworder { margin: 0; flex: none; }
/* CRM v3, этап 3 (24.09): строка-ссылка «Провести оплату в 1С» в «Сегодня». */
.crm-today-link { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; text-align: left; border: 0; font: inherit; cursor: pointer; }
/* «Клиенты → + Клиент» (26.09): новый клиент в 1С (static/crm-client-new.js). */
.crm-clients-top { display: flex; gap: 8px; align-items: stretch; margin: 0 0 10px; }
.crm-clients-top .crm-search { flex: 1 1 auto; min-width: 0; margin: 0; }
.crm-clients-top .crm-btn { flex: none; margin: 0; min-height: 44px; height: auto; padding: 0 16px; font-size: 15px;
  display: inline-flex; align-items: center; justify-content: center; border-radius: var(--r-crm, 18px); }
.crm-rfm-mgr { margin: 8px 0 4px; }
/* Ответ клиента на статус (26.09): миниатюра + товар прямо в пузыре. */
.crm-quote-status { display: flex; gap: 8px; align-items: flex-start; cursor: default; }
.crm-quote-lost { cursor: default; border-left-style: dashed; }
.crm-li-price-old { color: var(--gray, #8a8a8a); font-weight: 400; text-decoration: line-through; }
/* «Заказать → Горит»: ссылка на поставщиков без горящих позиций (26.09) */
.crm-link-row { display: block; width: 100%; margin: 10px 0; padding: 12px 14px; border: 1px dashed var(--line, #d9d9d9);
  border-radius: 12px; background: none; font: inherit; color: var(--green-dark, #148a51); text-align: left; cursor: pointer; }
/* Окно «Правила» (26.09) */
.crm-rules-btn { margin: 0 0 10px; }
.crm-rules-doc h3 { margin: 18px 0 6px; font-size: 16px; }
.crm-rules-doc p, .crm-rules-doc li { line-height: 1.45; }
.crm-rules-doc ul, .crm-rules-doc ol { padding-left: 20px; margin: 6px 0; }
.crm-rules-ex { color: var(--gray, #6b6b6b); }
.crm-rules-ex-list li { margin-bottom: 4px; }
.crm-rules-yes { color: var(--green-dark, #148a51); }
.crm-rules-no { color: #c0392b; }
/* «Товары → Перемещение» (26.09) */
.crm-transfer-row { display: flex; gap: 10px; align-items: center; }
.crm-transfer-row .crm-li-main { flex: 1 1 auto; min-width: 0; }
.crm-transfer-name.product-link-cell { display: block; width: auto; margin: 0; padding: 0; background: none; border: 0; font: inherit;
  font-weight: 600; text-align: left; color: inherit; cursor: pointer; overflow-wrap: anywhere; }
.crm-transfer-qty { flex: none; font-weight: 700; white-space: nowrap; }
.crm-transfer-qty.urgent { color: #c0392b; }
.crm-quote-thumb { width: 56px; height: 72px; object-fit: cover; border-radius: 6px; flex: none; }
.crm-quote-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* «Глазами другого» (26.09): шапка «CRM · Ильяс ▾» — невидимый select поверх,
   на телефоне открывается родной список. Плашка режима — жёлтая, кнопка на
   ней белая с обводкой (правило пользователя про кнопки на цветном фоне). */
.crm-viewas-tag { position: relative; cursor: pointer; }
.crm-viewas-select { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; font-size: 16px; }
.crm-viewas-bar { position: sticky; top: 0; z-index: 60; display: flex; align-items: center; justify-content: space-between; gap: 10px;
  flex-wrap: wrap; padding: 8px 16px; background: #fff3cd; color: #7a5200; font-size: 14px; border-bottom: 1px solid rgba(122, 82, 0, 0.15); }
.crm-viewas-bar .crm-btn.crm-btn-ghost { flex: none; padding: 6px 12px; font-size: 13.5px; background: #fff; color: #7a5200;
  box-shadow: inset 0 0 0 1px rgba(122, 82, 0, 0.18); }
/* «Ответ не нужен» прямо под перепиской (26.09). */
.crm-noreply-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
  margin: 8px 0 4px; padding: 8px 12px; border-radius: 12px; background: #fff6e0; color: #7a5200; font-size: 13.5px; }
/* Правило пользователя: на цветном фоне кнопка не серая, а белая с тонкой
   обводкой (как в «Заказать» у выбранной строки). */
.crm-noreply-bar .crm-btn.crm-btn-ghost { flex: none; padding: 6px 12px; font-size: 13.5px; background: #fff; color: #7a5200;
  box-shadow: inset 0 0 0 1px rgba(122, 82, 0, 0.18); }
.crm-noreply-bar .crm-btn.crm-btn-ghost:hover { background: #fffdf7; box-shadow: inset 0 0 0 1px rgba(122, 82, 0, 0.32); }
/* «Статусы»: бейдж срока как на сайте и свёрнутое «Нет в наличии» (26.09). */
.crm-expiry-badge { align-self: flex-start; font-size: 11.5px; font-weight: 600; line-height: 1.3; padding: 1px 7px;
  border-radius: 999px; background: #1aa260; color: #fff; }
.crm-expiry-badge.is-out { background: #c0392b; }
.crm-promo-out > summary { padding: 10px 38px 10px 14px; font-size: 13px; font-weight: 600; color: var(--gray);
  border-top: 1px solid var(--crm-sep, rgba(20,20,20,.07)); }
.crm-quote-status .product-link-cell.crm-quote-prod { display: block; width: auto; margin: 0; background: none; border: 0; padding: 0; font: inherit; font-size: 13.5px; line-height: 1.3; font-weight: 600;
  color: var(--ink, #1d1d1f); text-decoration: none; text-align: left; cursor: pointer; overflow-wrap: anywhere; }
.crm-quote-status .product-link-cell.crm-quote-prod:hover { color: var(--green-dark, #148a51); }
.crm-quote-status .crm-quote-who, .crm-quote-status .crm-quote-text { margin: 0; padding: 0; line-height: 1.3; }
.crm-quote-status .crm-quote-thumb { width: 48px; height: 64px; object-fit: cover; object-position: top; border: 1px solid rgba(0,0,0,.08); }
.crm-matrix-item .product-link-cell.crm-mx-name { width: auto; flex: 1 1 auto; min-width: 0; text-align: left; background: none; border: 0;
  padding: 0; font: inherit; font-weight: 600; color: inherit; cursor: pointer; overflow-wrap: anywhere; }
.crm-rfm-list { margin-top: 10px; }
#crm-cnew-modal .crm-btn { min-height: 44px; width: 100%; margin-top: 10px; font-size: 15px; }
#crm-cnew-modal .crm-search { width: 100%; margin-top: 4px; }
#crm-cnew-modal .crm-cnew-err { color: var(--cr-danger, #c0392b); }
/* Название товара как ссылка на карточку внутри строки текста (аудит 27.09:
   «Спрос», «Уже заказано», «Опубликовано», «Распродать»). */
.product-link-cell.crm-prod-link { display: inline; width: auto; margin: 0; padding: 0; border: 0; background: none; font: inherit;
  color: inherit; font-weight: 600; text-align: left; cursor: pointer; text-decoration: underline; text-decoration-color: rgba(0,0,0,.25);
  text-underline-offset: 3px; }
.product-link-cell.crm-prod-link:hover { color: var(--green-dark, #148a51); }