/* Стили только для страницы каталога: активные фильтры, фильтры внутри
   заголовков таблицы (col-filter + filter-menu), таблица, бейджи статуса,
   плейсхолдер-аватар. */

/* Скрытая форма с hidden inputs не должна занимать gap в col-main flex —
   её существование чисто для HTMX-запроса, в layout не участвует. */
#filterForm { display: contents; }

/* ───── Шапка прайса .pb (2026-06-12) ─────
   Одна компактная полоса: лого + заголовок/табы/контакты + действия.
   --pb-* замаплены на токены проекта, поэтому per-brand цвета
   (.catalog-theme переопределяет --accent) текут сами. */
/* Полноширинный слот шапки прайса: занимает первую строку грида .body-wrap
   на всю ширину (обе колонки), поэтому операторская чат-панель (.col-rail)
   и таблица идут СТРОГО ПОД ней (2026-06-20). */
.catalog-pb-row { grid-column: 1 / -1; }
/* .body-wrap — grid с flex:1 (тянется на всю высоту окна). Дефолтный
   align-content:stretch на коротком прайсе раздувал строку шапки → пустота
   между .pb и таблицей. Прижимаем строки грида к верху (только на каталоге —
   там есть .catalog-pb-row), чтобы верх таблицы стремился к верху экрана. */
.body-wrap:has(.catalog-pb-row) { align-content: start; }
.pb {
  --pb-accent: var(--accent);
  --pb-accent-soft: var(--accent-soft);
  --pb-accent-line: var(--border-strong);
  --pb-ink: var(--ink); --pb-soft: var(--ink-soft);
  --pb-mute: var(--mute); --pb-mute-soft: var(--mute-soft);
  --pb-border: var(--border); --pb-card: var(--bg-card); --pb-alt: var(--bg-alt);
  display: flex; align-items: center; gap: 16px;
  padding: 6px 24px; background: var(--pb-card);
  border-bottom: 1px solid var(--pb-border);
  color: var(--pb-ink);
  /* Полоса прайса во всю ширину, прижата к верхнему меню (редизайн 2026-06-17):
     отрицательные поля гасят padding .body-wrap (16px верт. / 24px гориз.).
     Нижний отступ = 0: расстояние до таблицы/чата даёт grid gap (16px). */
  margin: -16px -24px 0;
}
/* Лого-слот: фикс. высота, авто-ширина — любая пропорция логотипа впишется */
.pb__logo {
  height: 66px; display: flex; align-items: center;
  padding: 0 12px; border-radius: 8px; flex-shrink: 0;
  border: 1px solid var(--pb-border); background: var(--bg-subtle);
}
/* Лого-баннер на всю высоту слота (каретка ⌄ встроена в сам ассет). */
.pb__logo img { height: 100%; width: auto; object-fit: contain; display: block; }
/* С загруженным лого область не заливаем: логотип сидит на родной подложке страницы (прозрачный PNG → на белом фоне). Текстовый fallback оставляем в подложке-чипе. */
.pb__logo:has(img) { background: transparent; border-color: transparent; padding: 0; }
/* Hover-логотип бренда (Brand.logo_hover): обе картинки в обёртке, hover-вариант лежит поверх и плавно проявляется при наведении на лого-слот. */
.pb__logo-imgwrap { position: relative; display: inline-flex; line-height: 0; height: 100%; }
/* Главная картинка лого задаёт ширину обёртки по высоте слота (иначе при
   logo_hover у обёртки нет высоты → height:100% картинки → натуральный размер). */
.pb__logo-imgwrap .pb__logo-img { height: 100%; width: auto; }
.pb__logo-img--hover {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: 0; transition: opacity .18s ease; pointer-events: none;
}
.pb__logo:hover .pb__logo-img--hover { opacity: 1; }
@media (hover: none) { .pb__logo-img--hover { display: none; } }
.pb__logo-name {
  font-size: 15px; font-weight: 700; letter-spacing: -.3px;
  color: var(--pb-ink); white-space: nowrap;
}

/* ── Переключатель фирм (ТЗ §3.1): лого-блок раскрывает список фирм ── */
.pb__firm-switch { position: relative; flex-shrink: 0; }
.pb__logo--switch { cursor: pointer; gap: 10px; list-style: none; user-select: none; }
.pb__logo--switch::-webkit-details-marker { display: none; }
.pb__logo--switch:hover { border-color: var(--pb-accent-line); }
.pb__firm-switch[open] .pb__logo--switch { border-color: var(--pb-accent); background: var(--pb-accent-soft); }
/* Лого-баннер бренда самодостаточен (стрелка встроена) — при наведении/
   открытии выпадашки чип НЕ заливаем индиго и не рисуем рамку. */
.pb__logo--switch-logo:hover,
.pb__firm-switch[open] .pb__logo--switch-logo { border-color: transparent; background: transparent; }
.pb__firm-caret { color: var(--pb-mute); transition: transform .15s; flex-shrink: 0; }
.pb__firm-switch[open] .pb__firm-caret { transform: rotate(180deg); }
.pb__firm-menu {
  position: absolute; top: calc(100% + 6px); left: 0; width: 340px; max-width: 92vw;
  background: var(--pb-card); border: 1px solid var(--pb-border); border-radius: 12px;
  box-shadow: 0 18px 44px rgba(10,14,26,.20); padding: 6px 0; z-index: 60;
  max-height: 466px; overflow-y: auto;
}
.pb__firm-group-label {
  font-size: 10px; font-family: var(--font-mono); letter-spacing: 1px; text-transform: uppercase;
  color: var(--pb-mute); font-weight: 600; padding: 6px 10px 4px;
}
.pb__firm-group-label--fav { color: #caa024; }
.pb__firm-row { display: flex; align-items: center; border-radius: 8px; }
.pb__firm-row.is-current { background: var(--pb-accent-soft); }
/* В выпадашке (.pb__firm-menu) заливка строки — во всю ширину меню, без боковых
   зазоров: убираем боковой padding меню (выше) и скругление/инсет строки, а
   отступы содержимого даём изнутри (padding-left у ссылки, margin у звезды). */
.pb__firm-menu .pb__firm-row { border-radius: 0; }
.pb__firm-menu .pb__firm-row:hover { background: var(--pb-alt); }
.pb__firm-menu .pb__firm-row.is-current,
.pb__firm-menu .pb__firm-row.is-current:hover { background: var(--pb-accent-soft); }
.pb__firm-menu .pb__firm-link { padding-left: 14px; border-radius: 0; }
.pb__firm-menu .pb__firm-link:hover { background: transparent; }
.pb__firm-menu .pb__firm-row .pi-firm-star { margin-right: 10px; }
.pb__firm-menu .pb__firm-group-label { padding-left: 14px; }
.pb__firm-link {
  flex: 1; min-width: 0; display: flex; align-items: center; gap: 11px;
  padding: 7px 4px 7px 8px; text-decoration: none; color: var(--pb-ink); border-radius: 8px;
}
.pb__firm-link:hover { background: var(--pb-alt); }
.pb__firm-mono {
  width: 32px; height: 32px; border-radius: 7px; flex-shrink: 0;
  display: grid; place-items: center; color: #fff; font-size: 12px; font-weight: 700;
  background: hsl(var(--firm-hue, 200) 55% 42%);
}
.pb__firm-text { flex: 1; min-width: 0; }
.pb__firm-name {
  display: flex; align-items: center; gap: 6px; font-size: 13.5px; font-weight: 600;
  color: var(--pb-ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pb__firm-partner { color: var(--pb-mute); flex-shrink: 0; }
.pb__firm-sub { font-size: 11px; color: var(--pb-mute); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pb__firm-check { color: var(--pb-accent); flex-shrink: 0; margin-right: 4px; }
.pb__firm-row .pi-firm-star { margin-right: 4px; }
/* Поиск-строка (открывает модалку) + «показать все» */
.pb__firm-searchrow {
  width: calc(100% - 16px); margin: 2px 8px 6px; display: flex; align-items: center; gap: 8px;
  height: 32px; padding: 0 10px; border-radius: 8px; background: var(--pb-alt);
  border: 1px solid var(--pb-border); color: var(--pb-mute); font: inherit; font-size: 12.5px;
  cursor: pointer; text-align: left;
}
.pb__firm-searchrow:hover { border-color: var(--pb-accent-line); }
.pb__firm-showall {
  width: 100%; display: flex; align-items: center; justify-content: center; gap: 5px;
  height: 30px; border: 0; background: transparent; cursor: pointer;
  color: var(--pb-accent); font: inherit; font-size: 12px; font-weight: 600;
}
.pb__firm-showall:hover { text-decoration: underline; }
/* Низ выпадашки: «Все прайсы →» + «＋ Добавить фирму» */
.pb__firm-foot {
  display: flex; gap: 4px; margin-top: 4px; padding: 4px 8px 0;
  border-top: 1px solid var(--pb-border);
}
.pb__firm-all, .pb__firm-add {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 4px;
  padding: 8px 8px; text-align: center; font-size: 12.5px; font-weight: 600;
  color: var(--pb-accent); text-decoration: none; border-radius: 8px; white-space: nowrap;
}
.pb__firm-all:hover, .pb__firm-add:hover { background: var(--pb-alt); }

/* ── Модалка «Выбор фирмы» (ТЗ §3.2) ── */
.firm-modal[hidden] { display: none; }
.firm-modal {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: flex-start; justify-content: center; padding-top: 80px;
}
.firm-modal__backdrop { position: absolute; inset: 0; background: rgba(10,14,26,.45); }
.firm-modal__dialog {
  position: relative; width: 640px; max-width: 94vw; max-height: 78vh;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--bg-card); border-radius: 14px;
  box-shadow: 0 24px 60px rgba(10,14,26,.35);
}
.firm-modal__head {
  display: flex; align-items: center; gap: 8px;
  padding: 16px 18px; border-bottom: 1px solid var(--border);
}
.firm-modal__title { font-size: 17px; font-weight: 700; color: var(--ink); letter-spacing: -.3px; }
.firm-modal__count { font-size: 12.5px; color: var(--mute); }
.firm-modal__spacer { flex: 1; }
.firm-modal__close {
  width: 30px; height: 30px; display: grid; place-items: center; padding: 0;
  border: 1px solid var(--border); background: var(--bg-card); border-radius: 8px;
  color: var(--mute); cursor: pointer;
}
.firm-modal__close:hover { background: var(--bg-alt); }
.firm-modal__search {
  margin: 12px 18px 4px; display: flex; align-items: center; gap: 8px;
  height: 38px; padding: 0 12px; border-radius: 9px; background: var(--bg-alt);
  border: 1px solid var(--border); color: var(--mute);
}
.firm-modal__search input {
  flex: 1; border: 0; background: transparent; outline: none; font: inherit;
  font-size: 13px; color: var(--ink);
}
.firm-modal__body { flex: 1; overflow-y: auto; padding: 8px 12px 14px; }
.firm-modal__empty { padding: 24px 10px; text-align: center; color: var(--mute); font-size: 13px; }

.pb__divider { width: 1px; height: 40px; background: var(--pb-border); flex-shrink: 0; }
.pb__main { min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.pb__row { display: flex; align-items: center; gap: 9px; }

/* Звезда «избранная фирма» (ТЗ 2026-06-12) — партиал _firm_star.html.
   prices_index.css на каталоге не подключён, поэтому стиль дублируем здесь. */
.pb .pi-firm-star-form { margin: 0; display: inline-flex; flex-shrink: 0; }
.pb .pi-firm-star {
  width: 26px; height: 26px; display: grid; place-items: center; padding: 0;
  border: 0; background: transparent; cursor: pointer; border-radius: 6px; flex-shrink: 0;
}
.pb .pi-firm-star:hover { background: var(--pb-bg-alt, #f4f5f7); }
.pb .pi-firm-star svg { display: block; }
.pb h1 { margin: 0; font-size: 19px; font-weight: 700; letter-spacing: -.4px; white-space: nowrap; }
.pb__sep { width: 1px; height: 18px; background: var(--pb-border); margin: 0 2px; flex-shrink: 0; }

.pb__tabs { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
/* Вкладка прайса (свой и партнёрский — один стиль, без янтаря) */
.pb__tab {
  display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px;
  border-radius: 7px; font-size: 12.5px; font-weight: 500; color: var(--pb-mute);
  text-decoration: none; border: 1px solid transparent; white-space: nowrap;
  transition: background 0.15s, color 0.15s;
}
.pb__tab:hover { background: var(--pb-alt); color: var(--pb-soft); }
.pb__tab svg { opacity: .85; flex-shrink: 0; }
.pb__tab.is-active { color: var(--pb-accent); background: var(--pb-accent-soft); }

.pb__contacts {
  margin-top: 2px; font-size: 12px; color: var(--pb-mute);
  font-family: var(--font-mono);
  display: flex; flex-wrap: wrap; align-items: center; gap: 2px 14px;
}
.pb__contacts a { color: var(--pb-mute); text-decoration: none; }
.pb__contacts a:hover { color: var(--pb-accent); text-decoration: underline; }
.pb__contacts .pb__dot { color: var(--pb-mute-soft); }

.pb__spacer { flex: 1; }

.pb__actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.pb__btn {
  display: inline-flex; align-items: center; gap: 7px; height: 34px; padding: 0 12px;
  border: 1px solid var(--pb-border); background: var(--pb-card); border-radius: 8px;
  font-size: 13px; font-weight: 500; color: var(--pb-soft); cursor: pointer;
  text-decoration: none; white-space: nowrap;
  transition: background 0.15s;
}
.pb__btn:hover { background: var(--bg-subtle); }

/* Узкая ширина: действия переносятся под заголовок, чтобы не наезжать на табы. */
@media (max-width: 900px) {
  .pb { flex-wrap: wrap; }
  .pb__spacer { display: none; }
  .pb__actions { width: 100%; margin-top: 4px; }
}

/* Прокручиваемый блок внутри дропдаунов колонок (используется в шапке
   «Категория» — список групп бывает длинным). */
.pop-scroll { max-height: 320px; overflow-y: auto; padding: 6px 0; }

/* ───── Полоса активных фильтров ─────
   Чипы применённых фильтров + счётчик «N / total». Полоса видна всегда —
   без активных фильтров фон становится прозрачным. */
.filter-active-bar {
  display: flex; align-items: center; gap: 8px;
  /* nowrap: переносятся чипы ВНУТРИ .fab-chips, а подпись и кнопки всегда
     остаются в одной строке с ними (иначе flex уносил их на свои строки). */
  flex-wrap: nowrap;
  padding: 10px 16px;
  background: transparent;
  position: relative;
}
.filter-active-bar.is-empty {
  background: transparent;
  border-bottom-color: transparent;
  padding: 8px 16px;
}
.filter-active-bar.is-empty .lbl { display: none; }
.filter-active-bar .lbl {
  font-size: 11px; color: var(--mute);
  text-transform: uppercase; letter-spacing: 0.4px;
  font-weight: 600;
  flex: 0 0 auto; white-space: nowrap;
}
.filter-active-bar .filter-count {
  font-size: 12px; color: var(--mute);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  margin-left: auto;
}
.filter-active-bar .chip-active {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px;
  padding: 0 8px 0 12px;
  background: var(--accent-soft);
  color: var(--accent);
  border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
  border-radius: 999px;
  font-size: 12.5px; font-weight: 500;
}
.filter-active-bar .chip-active b { font-weight: 600; margin-right: 2px; }
.filter-active-bar .chip-active .x {
  width: 16px; height: 16px;
  border-radius: 8px;
  display: grid; place-items: center;
  cursor: pointer;
  font-size: 13px;
  color: var(--accent);
  transition: background 0.15s;
}
.filter-active-bar .chip-active .x:hover { background: rgba(67,56,202,0.18); }
.filter-active-bar .reset-all {
  background: transparent; border: 0;
  font: inherit; font-size: 12px; font-weight: 500;
  color: var(--mute);
  cursor: pointer;
  border-bottom: 1px dashed var(--mute-soft);
  padding: 0 0 1px;
  flex: 0 0 auto; white-space: nowrap;
}
.filter-active-bar .reset-all:hover {
  color: var(--bad);
  border-bottom-color: var(--bad);
}

/* Полоса — ровно ОДНА строка чипов, остальные в окне-списке по кнопке
   «Ещё N» (у питомника с сотнями родов чипов бывает на 20+ строк).
   Классы is-collapsed / is-open ставит filterbar.js — без JS полоса
   разворачивается как раньше. */
.filter-active-bar .fab-chips {
  display: flex; flex-wrap: wrap; gap: 8px;
  flex: 1 1 auto; min-width: 0;
}
.filter-active-bar.is-collapsed .fab-chips {
  max-height: 30px; overflow: hidden;
}
.filter-active-bar.is-open .fab-chips {
  position: absolute; top: calc(100% - 4px); left: 16px; right: 16px;
  z-index: 40;
  align-content: flex-start;
  max-height: min(60vh, 420px); overflow-y: auto;
  padding: 12px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(10,14,26,0.12);
}
.filter-active-bar .fab-more {
  flex: 0 0 auto;
  height: 28px; min-width: 96px; padding: 0 12px;
  background: transparent;
  border: 1px dashed color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 999px;
  font: inherit; font-size: 12.5px; font-weight: 500;
  color: var(--accent);
  cursor: pointer;
  white-space: nowrap;
}
.filter-active-bar .fab-more:hover {
  background: var(--accent-soft);
  border-style: solid;
}
.filter-active-bar .fab-more-close { display: none; }
.filter-active-bar.is-open .fab-more-open { display: none; }
.filter-active-bar.is-open .fab-more-close { display: inline; }

/* ───── «Условия заказа в питомнике» — ссылка в строке контактов + поповер
   (ТЗ дизайнера 2026-06-13, заменяет прежнюю полосу .pricelist-conditions) ───── */
.pb__contacts .pb__sep {
  display: inline-block; height: 13px; vertical-align: -2px; margin: 0 8px;
}
.pb-terms { display: inline-block; position: relative; font-family: var(--font-sans); }
.pb-terms > summary { list-style: none; }
.pb-terms > summary::-webkit-details-marker { display: none; }
.pb-terms__link {
  display: inline-flex; align-items: center; gap: 5px;
  min-height: 24px;
  font-size: 12px; font-weight: 600; color: var(--pb-accent, var(--accent));
  border-bottom: 1px dashed color-mix(in srgb, var(--pb-accent, var(--accent)) 38%, #fff);
  cursor: pointer; user-select: none;
}
.pb-terms__ico { flex-shrink: 0; }
.pb-terms__pop {
  position: absolute; top: calc(100% + 6px); left: 0;
  width: 320px; max-width: min(320px, calc(100vw - 24px));
  background: var(--bg-card); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 18px 44px rgba(10,14,26,.20);
  padding: 12px 14px; z-index: 60; text-align: left;
}
.pb-terms__caps {
  font-family: var(--font-mono); font-size: 11px; font-weight: 600;
  letter-spacing: 1px; text-transform: uppercase; color: var(--mute);
  padding: 2px 0 4px;
}
.pb-terms__row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 7px 0; font-size: 13px;
}
.pb-terms__row span { color: var(--mute); flex: 0 0 auto; }
/* Значение переносится: длинная оплата/доставка не распирает поповер (320px).
   Короткие значения (−3%, «кратно 24 шт») и так не переносятся. text-align:right
   держит перенесённые строки в колонке значения. */
.pb-terms__row b {
  color: var(--ink); font-weight: 600;
  min-width: 0; text-align: right; overflow-wrap: anywhere;
}
.pb-terms__row--accent b { color: var(--pb-accent, var(--accent)); }
.pb-terms__hr { height: 1px; background: var(--border); margin: 8px 0; }
.pb-terms__text { font-size: 12.5px; line-height: 1.5; color: var(--ink-soft); padding: 4px 0 2px; }

/* ───── Таблица каталога ───── */
.tbl-card {
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 1px 2px rgba(10,14,26,0.04);
  overflow: visible;  /* критично — иначе filter-menu отрежется */
  position: relative;
  /* content-box: col-resize.js (applyTotal) ставит card.width == table.width;
     при border-box content-зона карточки на 2px уже рамки → таблица перекрывала
     правую границу (она «не прорисовывалась»). content-box → width = content =
     ширине таблицы, рамка 1px снаружи и всегда видна. Падингов у карточки нет. */
  box-sizing: content-box;
  /* Компактная таблица (редизайн 2026-06-17): ширина по содержимому,
     не на весь экран. Колонки в px (.col-*) + ручной ресайз (col-resize.js). */
  width: fit-content;
  max-width: 100%;
}

/* Таблица + операторская чат-панель в одной флекс-строке: панель приклеена
   к правому краю таблицы и двигается при ресайзе столбцов (2026-06-20).
   .tbl-card flex:0 0 auto — сохраняет свою content-ширину; чат фикс. 320px,
   sticky по вертикали (как раньше в .col-rail). */
.cat-table-row { display: flex; align-items: flex-start; gap: 16px; }
.cat-table-row > .tbl-card { flex: 0 0 auto; }
.cat-table-row > .chat-card {
  flex: 0 0 var(--rail-w, 320px);
  align-self: flex-start;
  position: sticky; top: 72px;
  height: calc(100vh - 56px - 32px);
  max-height: calc(100vh - 56px - 32px);
}

/* Сообщение «комбинация фильтров не даёт строк». Рендерится в _rows.html
   как tr.catalog-empty-row при `not groups and selected.has_any`. */
.catalog-empty-row td {
  background: var(--bg-card);
  padding: 32px 24px;
  text-align: center;
}
.catalog-empty-msg {
  color: var(--mute);
  font-size: 15px;
  line-height: 1.5;
  max-width: 560px;
  margin: 0 auto;
}
/* Подсказка «какой фильтр обнулил выдачу» (Алексей 2026-06-21). */
.catalog-empty-title {
  color: var(--ink);
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 6px;
}
.catalog-empty-hint {
  color: var(--mute);
  font-size: 14px;
  margin-bottom: 14px;
}
.catalog-empty-fixes {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}
.catalog-empty-fix {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  border: 1px solid var(--accent);
  border-radius: 8px;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 14px;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.catalog-empty-fix:hover {
  background: var(--accent);
  color: #fff;
}
.catalog-empty-fix-n {
  min-width: 22px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  font-family: var(--font-mono);
  text-align: center;
}
.catalog-empty-fix:hover .catalog-empty-fix-n {
  background: #fff;
  color: var(--accent);
}
.tbl-card table { width: max-content; border-collapse: collapse; table-layout: fixed; }

.tbl-card thead tr {
  border-bottom: 1px solid var(--border);
  height: 40px;
}
/* Background перенесён с tr на th — иначе border-radius на угловых
   th не покроется фоном (background tr не наследуется на th-уровне
   при скругленных углах). Нужно для замазки белых уголков
   .tbl-card в правом-верхнем / левом-верхнем углу скругления. */
.tbl-card th {
  position: relative;     /* для абсолютного filter-menu */
  padding: 0;
  background: var(--bg-subtle);
  font-size: 11.5px; font-weight: 600;
  color: var(--mute);
  text-transform: uppercase; letter-spacing: 0.4px;
  user-select: none;
  text-align: left;
}
.tbl-card thead tr:first-child th:first-child { border-top-left-radius: 12px; }
.tbl-card thead tr:first-child th:last-child  { border-top-right-radius: 12px; }

/* Первая строка tbody — обычно group-header-row (серая полоса «Σ группы»).
   Без скругления её прямой угол вылезает за округлые углы .tbl-card
   (overflow:visible) — в правом-верхнем углу видно белый «уголок» поверх
   серой заливки. Скругляем td так же, как у thead на 145-146 строках. */
.tbl-card tbody tr:first-child td:first-child { border-top-left-radius: 12px; }
.tbl-card tbody tr:first-child td:last-child  { border-top-right-radius: 12px; }

/* Кнопка-заголовок: на всю ширину <th>, открывает выпадайку. */
.col-filter {
  display: flex; align-items: center; gap: 4px;
  width: 100%; height: 40px;
  padding: 0 12px;
  background: transparent; border: 0;
  font: inherit;
  font-size: 11.5px; font-weight: 600;
  color: var(--mute);
  text-transform: uppercase; letter-spacing: 0.4px;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.col-filter:hover { background: var(--bg-alt); color: var(--ink); }
/* Активная сортировка — без своего фона (иначе столбец «Наименование» по
   умолчанию отличается заливкой от остальной шапки); индикация — цветом
   текста + стрелкой сортировки. */
.col-filter.active-sort { color: var(--ink); }
/* Активный фильтр — без заливки столбца; индикация — бейджем «·N» и цветом текста. */
.col-filter.active-filter { color: var(--accent); }
.col-filter.menu-open { background: var(--bg-alt); }

/* Маркер интерактивности: пунктир под текстом заголовка. Длина
   подчёркивания = длина текста (text-decoration); цвет наследуется
   от .col-filter (серый в норме, индиго при active-filter). */
.col-filter-label {
  flex: 0 0 auto;
  text-decoration: underline dashed;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  white-space: nowrap;
}

/* C2.3e UX (2026-05-08): cart-шапка отцентрирована — степпер +/- в
   ячейках тоже центрирован через .stepper-wrap, текст «В корзину»
   садится ровно над кнопками. Только cart-th.
   ::before — симметричный invisible spacer слева, шириной gap(4)+caret(8)=12px.
   Без него блок [text + gap + caret] асимметричен, центр текста на 6px
   левее центра кнопки. */
.th-cart-right .col-filter { justify-content: center; }
.th-cart-right .col-filter::before {
  content: '';
  width: 12px;
  flex-shrink: 0;
}

/* Кнопка «Очистить корзину» в шапке столбца «В корзину» — рендерится
   только когда `is_b2b_approved and cart_qtys` (есть что чистить). Лежит
   слева внутри <th class="th-cart-right">, абсолютно позиционирована —
   не вмешивается в flex-layout col-filter, текст «В корзину» остаётся
   центрированным. z-index:2 над col-filter, чтобы клик ловился кнопкой,
   а не уходил popup'у. По клику — HTMX-POST на /cart/clear/ с confirm,
   view возвращает HX-Refresh → страница перезагружается со свежим
   состоянием (степперы → «+ В корзину», бейдж в шапке = 0). */
.th-cart-clear {
  position: absolute;
  top: 50%;
  left: 6px;
  transform: translateY(-50%);
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--mute);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  z-index: 2;
  transition: background 0.15s, color 0.15s;
}
.th-cart-clear:hover {
  background: var(--bad-soft, #fee2e2);
  color: var(--bad, #dc2626);
}
.th-cart-clear svg { width: 14px; height: 14px; display: block; }

.col-filter .col-count {
  color: var(--accent);
  font-family: var(--font-mono);
  font-weight: 700;
  margin-left: 2px;
}
.col-filter .sort-arrow {
  font-size: 12px; color: var(--accent); margin-left: 2px;
}
.col-filter .caret {
  width: 8px; height: 8px;
  flex-shrink: 0;
  margin-left: 2px;
  opacity: 0.5;
  transition: transform 0.15s, opacity 0.15s;
}
.col-filter:hover .caret,
.col-filter.menu-open .caret,
.col-filter.active-sort .caret,
.col-filter.active-filter .caret { opacity: 1; }
.col-filter.menu-open .caret { transform: rotate(180deg); }

/* Статичный заголовок без дропдауна (колонка «В корзину» — пока без фильтра) */
.th-static {
  display: flex; align-items: center;
  height: 40px; padding: 0 16px;
}

/* Дропдаун фильтра колонки */
.filter-menu {
  position: absolute;
  top: calc(100% + 1px); left: 0;
  min-width: 240px; max-width: 320px;
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(10,14,26,0.12);
  z-index: 25;
  overflow: hidden;
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  color: var(--ink);
  display: none;
}
.filter-menu.open { display: block; }
.filter-menu.right-aligned { left: auto; right: 0; }

/* Меню «Параметры»: горизонтальный layout с 540-720px только когда секций ≥2
   (Растение + Услуга/Расходник). Если в прайсе только одна секция (например
   p9 — все товары растения), popup не должен раздуваться — берёт обычные
   240-320px. По умолчанию params-cols = block, flex включается через :has(). */
.filter-menu.params-menu:has(.filter-section + .filter-section) {
  min-width: 540px;
  max-width: 720px;
}
.filter-menu.params-menu:has(.filter-section + .filter-section) .params-cols {
  display: flex;
  align-items: stretch;
}
.params-cols > .filter-section {
  flex: 1; min-width: 160px;
  border-right: 1px solid var(--border);
  border-bottom: 0;
}
.params-cols > .filter-section:last-child { border-right: 0; }
/* Сброс max-height/overflow от глобального .filter-section:has(input[type=checkbox])
   (специфичность 0,2,1 — нужна более высокая в нашем сбросе). Двойной скролл
   возникал когда оба правила накладывались: внешний на .filter-section (280px)
   и внутренний на .pop-scroll (320px). Скролл оставляем только на .pop-scroll. */
.filter-menu.params-menu .params-cols > .filter-section {
  max-height: none;
  overflow: visible;
}

/* Аккордеон-группа в дропдауне «Категория»: <details>/<summary> с
   кастомным маркером. Дочерние категории идут с отступом внутри. */
.filter-group { padding: 0; }
.filter-group > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  padding: 8px 14px 4px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--mute-soft);
  text-transform: uppercase;
  letter-spacing: 0.4px;
  font-family: var(--font-mono);
  display: flex;
  align-items: center;
  gap: 8px;
  transition: color 0.15s, background 0.15s;
}
.filter-group > summary:hover {
  color: var(--accent);
  background: var(--bg-alt);
}
.filter-group > summary::-webkit-details-marker { display: none; }
.filter-group > summary::before {
  content: "▶";
  font-size: 12px;
  color: var(--accent);
  transition: transform 0.15s;
  flex-shrink: 0;
}
.filter-group[open] > summary::before { transform: rotate(90deg); }
.filter-item--indent { padding-left: 28px; }
/* Категория «нет в наличии» — серым, но всё ещё кликабельной (продавец
   может специально выбрать). См. apps/catalog/views.py::_category_tree
   is_empty (n_total>0 && n_available=0). */
.filter-item--empty { opacity: 0.55; }
.filter-item--empty .label { color: var(--mute); }
.filter-group--empty > summary { color: var(--mute); font-style: italic; }
.filter-group--nested { margin-left: 16px; }

.filter-section {
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.filter-section:last-child { border-bottom: 0; }
/* Длинные списки чекбоксов скроллятся, чтобы кнопка «Применить» в
   foot'е меню не уезжала за viewport. Sort-секции (без чекбоксов)
   остаются как есть — там 2-3 пункта. */
.filter-section:has(input[type="checkbox"]) {
  max-height: 280px;
  overflow-y: auto;
}
/* Если внутри секции уже есть .pop-scroll — он сам скроллится (320px).
   Без этого сброса было бы два скроллбара рядом: внешний у .filter-section
   и внутренний у .pop-scroll. Скролл оставляем ровно один — на .pop-scroll. */
.filter-menu .filter-section:has(.pop-scroll) {
  max-height: none;
  overflow: visible;
}

.filter-item {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px;
  font-size: 13px;
  color: var(--ink-soft);
  cursor: pointer;
  user-select: none;
  transition: background 0.15s;
}
.filter-item:hover { background: var(--bg-alt); color: var(--ink); }
.filter-item input[type="checkbox"] {
  margin: 0; accent-color: var(--accent); cursor: pointer;
}
.filter-item .label { flex: 1; }
.filter-item.sort-row.active {
  background: var(--accent-soft); color: var(--accent); font-weight: 500;
}
/* Серое неактивное значение фасета: под текущим выбором даёт 0 товаров —
   видно (с числом 0), но не кликается. */
.filter-item.is-disabled { opacity: 0.45; cursor: default; }
.filter-item.is-disabled:hover { background: none; color: var(--ink-soft); }
.filter-item.is-disabled input[type="checkbox"] { cursor: default; }
.filter-count {
  font-size: 11px; color: var(--mute); font-variant-numeric: tabular-nums;
  margin-left: auto; padding-left: 8px;
}

.filter-group-title {
  padding: 8px 14px 4px;
  font-size: 10.5px; font-weight: 600;
  color: var(--mute-soft);
  text-transform: uppercase; letter-spacing: 0.4px;
  font-family: var(--font-mono);
}

/* Заголовок multi-select блока: подпись слева + иконки select-all/none справа. */
.filter-group-title-row {
  display: flex; align-items: center; justify-content: space-between;
  padding-right: 8px;
}
.filter-group-title-row .filter-group-title { padding-right: 6px; }
.filter-group-actions { display: flex; gap: 2px; }
.filter-icon-btn {
  width: 24px; height: 24px;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 5px;
  color: var(--mute-soft);
  cursor: pointer;
  transition: color 0.15s, background-color 0.15s, border-color 0.15s;
}
.filter-icon-btn:hover, .filter-icon-btn:focus-visible {
  color: var(--accent);
  background: var(--accent-soft);
  border-color: var(--accent-soft);
  outline: none;
}
.filter-icon-btn svg { width: 14px; height: 14px; display: block; }

.filter-input {
  width: 100%; height: 32px;
  padding: 0 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font: inherit; font-size: 12.5px;
  background: var(--bg-card); color: var(--ink);
  outline: none;
  transition: border-color 0.15s;
}
.filter-input:focus { border-color: var(--accent); }
.filter-search-wrap { padding: 8px 12px; }
.filter-range {
  display: flex; align-items: center; gap: 6px;
  padding: 8px 12px;
}
.filter-range .filter-input { flex: 1; min-width: 0; }
.filter-range .sep { color: var(--mute-soft); font-size: 12px; }

.filter-foot {
  display: flex; gap: 8px;
  padding: 10px 12px;
  background: var(--bg-subtle);
  border-top: 1px solid var(--border);
}
.filter-foot button {
  flex: 1; height: 32px;
  border-radius: 6px;
  border: 1px solid var(--border-strong);
  background: var(--bg-card);
  color: var(--ink-soft);
  font: inherit; font-size: 12px; font-weight: 500;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.filter-foot button:hover {
  background: var(--bg-alt); border-color: var(--accent); color: var(--accent);
}
.filter-foot button.primary {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.filter-foot button.primary:hover {
  background: var(--accent-hover); border-color: var(--accent-hover);
}

/* ───── Строки таблицы ───── */
.tbl-card tbody tr.data-row { height: 52px; }
/* Если у сорта несколько модификаций (rowspan>1 на cell-name) —
   первая строка чуть выше, чтобы аватар + 2 строки имени влезли
   без перетягивания. Эталон base-2.html:254. */
.tbl-card tbody tr.data-row.row-base.multi { height: 60px; }
/* Белый фон только на data-row td. Раньше был на `.tbl-card tbody td`,
   что специфичностью (0,1,2) перекрывало `.group-header-row td` (0,1,1)
   — заливка категорий теряла свой bg-subtle. */
.tbl-card tbody tr.data-row td { background: var(--bg-card); }

.row-base td { border-top: 1px solid var(--border); }
.row-cont td:not(.cell-name) { border-top: 1px dashed var(--border); }

.tbl-card td.cell-name {
  vertical-align: middle; padding: 0 14px;
  border-right: 1px solid var(--border);
}
.name-flex {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0;
}
.name-text { min-width: 0; flex: 1; }
.sort-name {
  font-size: 13.5px; font-weight: 600; color: var(--ink); line-height: 1.25;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Ширина колонок каталога — на <colgroup><col>, в px (редизайн 2026-06-17).
   Прежняя %-схема + spacer-хак заменены: таблица компактная (width:fit-content),
   ширины в px и регулируются вручную (col-resize.js → SSR <col style> / localStorage).
   table-layout:fixed читает colgroup; SSR-ширины из аккаунта переопределяют эти
   дефолты inline-стилем на <col>. min-width оставлен как нижний предел содержимого. */
.col-name { width: 260px; min-width: 160px; }
.col-category { width: 130px; min-width: 90px; }
.col-supplier { width: 150px; min-width: 100px; }
.col-code { width: 110px; min-width: 80px; }
.col-attr { width: 150px; min-width: 90px; }
.col-price { width: 120px; min-width: 90px; }
.col-state { width: 180px; min-width: 120px; }
.col-warehouse { width: 150px; min-width: 100px; }
.col-stock { width: 110px; min-width: 80px; }
.col-cart { width: 170px; min-width: 120px; }

td.cell-category { padding: 0 14px; font-size: 13px; }
td.cell-supplier { padding: 0 14px; font-size: 13px; }
td.cell-attr {
  padding: 0 14px; font-size: 12.5px; font-family: var(--font-mono); color: var(--ink-soft);
}
td.cell-code { padding: 0 14px; }
td.cell-code code { font-family: var(--font-mono); font-size: 12px; color: var(--mute); }

td.cell-params {
  padding: 0 14px;
  font-size: 12.5px; color: var(--ink-soft);
  font-family: var(--font-mono);
}
td.cell-state {
  padding: 6px 14px;
  width: 14%;
  /* C2.3e hotfix: длинные warehouse-label'ы («Бронь для СЦ - для продажи»)
     раньше вылазили за пределы ячейки. Принудительный wrap в 2 строки. */
  white-space: normal;
  word-break: break-word;
  line-height: 1.25;
  vertical-align: middle;
}
td.cell-warehouse {
  padding: 6px 14px;
  font-size: 12.5px;
  color: var(--ink-soft);
  white-space: normal;
  word-break: break-word;
  line-height: 1.25;
  vertical-align: middle;
}
td.cell-stock {
  padding: 0 14px;
  font-family: var(--font-mono);
  font-size: 12.5px; color: var(--ink);
  /* CLAUDE.md «Каталог: ширина колонок» — % схема как в base-2 prototype. */
  width: 12%;
}
td.cell-stock.zero { color: var(--mute); }
td.cell-price {
  padding: 0 14px;
  font-size: 14px; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums;
  /* CLAUDE.md «Каталог: ширина колонок» — % схема как в base-2 prototype. */
  width: 12%;
}
td.cell-price .vat-note {
  display: block;
  color: var(--mute); font-weight: 400; font-size: 11px;
  margin-top: 1px;
}
td.cell-price .price-pair {
  font-size: 12.5px; font-weight: 500;
  color: var(--ink-soft);
  display: block;
}
/* Аноним: реальная оптовая цена остаётся в HTML, но визуально размыта —
 * читаемую цену видит только зарегистрированный покупатель. */
.price-blur {
  filter: blur(5px);
  user-select: none;
  pointer-events: none;
}
td.cell-cart {
  text-align: center;
  padding: 0 14px;
  /* width согласован с <col class="col-cart"> в colgroup (14%) — раньше
   * был 16% и создавал рассогласование при table-layout:fixed. */
  width: 14%;
}

/* ───── Ячейка «В корзину» для не-оптовых посетителей ───── */
/* Аноним: ссылка на регистрацию (badge с accent-цветом, кликабельная). */
.cart-cell-register {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--accent-soft, #eef2ff);
  color: var(--accent, #4338ca);
  font-size: 12px;
  font-weight: 600;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background .12s, border-color .12s;
}
.cart-cell-register:hover {
  background: var(--accent, #4338ca);
  color: #fff;
  border-color: var(--accent, #4338ca);
}
/* Individual+pending: ghost-badge «Ожидайте» (некликабельный). */
.cart-cell-wait {
  display: inline-block;
  padding: 4px 10px;
  border-radius: 999px;
  background: #fef3c7;
  color: #92400e;
  font-size: 12px;
  font-weight: 500;
  border: 1px solid transparent;
  cursor: default;
}

/* Мобильный аналог в .m-variant-row */
.m-cart-wait {
  align-self: center;
  padding: 6px 12px;
  border-radius: 7px;
  background: #fef3c7;
  color: #92400e;
  font-size: 12px;
  font-weight: 500;
}

/* ───── Степпер +/− в ячейке «В корзину» ───── */
.stepper-wrap { display: flex; justify-content: center; }
/* Во время запроса к /cart/update/ (~0.5с): hx-indicator вешает htmx-request →
   гасим степпер и блокируем клики, чтобы повторный тап не слал устаревший qty
   («второй клик не срабатывал») и был визуальный отклик. */
.stepper-wrap.htmx-request { opacity: 0.5; pointer-events: none; }
.stepper {
  display: inline-flex; align-items: center; gap: 0;
  height: 32px; border: 1px solid var(--border); border-radius: 7px;
  background: var(--bg-card); overflow: hidden;
}
.step-btn {
  width: 32px; height: 100%;
  border: 0; background: transparent; color: var(--ink);
  font: inherit; font-size: 16px; font-weight: 500; line-height: 1;
  cursor: pointer; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.step-btn:hover:not(:disabled) { background: var(--bg-alt); color: var(--accent); }
.step-btn:disabled { color: var(--mute); cursor: not-allowed; }
.step-qty {
  /* CLAUDE.md «Каталог: ширина числовых колонок» — под qty=99999
   * (5 цифр JetBrains Mono 12.5px + padding 6×2 + борды 1×2). */
  min-width: 52px; padding: 0 6px;
  font-family: var(--font-mono); font-size: 12.5px; font-weight: 600;
  color: var(--ink); text-align: center;
  border-left: 1px solid var(--border); border-right: 1px solid var(--border);
  height: 100%; display: inline-flex; align-items: center; justify-content: center;
}
/* Поле ввода количества с клавиатуры — выглядит как .step-qty-плашка. */
input.step-qty {
  display: inline-block; box-sizing: border-box; width: 52px;
  border-top: 0; border-bottom: 0; border-radius: 0;
  background: var(--bg-card); outline: none; -moz-appearance: textfield;
}
input.step-qty:focus { background: var(--bg-alt); }
input.step-qty::-webkit-outer-spin-button,
input.step-qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.step-add {
  height: 32px;
  min-width: 110px; padding: 0 14px;
  border: 1px solid var(--accent); border-radius: 7px;
  background: var(--bg-card); color: var(--accent);
  font: inherit; font-size: 12.5px; font-weight: 600; line-height: 1;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  /* убрали margin-left: auto; */
  transition: background 0.15s, color 0.15s;
}
.step-add:hover { background: var(--accent); color: var(--color-on-primary, #fff); }
.step-add-plus { font-size: 16px; font-weight: 500; line-height: 1; margin-top: -1px; }
.step-add-label { white-space: nowrap; }
tr.row-soon .step-add,
tr.row-soon .stepper { opacity: 0.5; }

/* «Скоро будет» (stock=0) — приглушённая строка */
tr.row-soon td.cell-name .sort-name,
tr.row-soon td.cell-params,
tr.row-soon td.cell-price { color: var(--mute); }

/* ───── Бейдж статуса ───── */
.badge {
  display: inline-flex; align-items: center; gap: 5px;
  height: 22px; padding: 0 8px; border-radius: 4px;
  font-size: 11.5px; font-weight: 500;
}
.badge .dot { width: 5px; height: 5px; border-radius: 3px; background: currentColor; }
.badge.ok { background: var(--ok-soft); color: var(--ok); }
.badge.warn { background: var(--warn-soft); color: var(--warn); }
.badge.bad { background: var(--bad-soft); color: var(--bad); }

/* ───── Аватар товара 56×56 ─────
   Базовая плашка-плейсхолдер — градиент по Product.photo_hue + инициалы.
   Если в МС загружено фото и cron `sync_moysklad --with-images` его
   подтянул — `product_avatar` templatetag отдаёт `<img class="ph-avatar
   ph-avatar--photo">` вместо `<div>`. Геометрия общая, фоновый градиент
   у `<img>` виден как «skeleton» пока картинка догружается. */
.ph-avatar {
  width: 56px; height: 56px; border-radius: 8px;
  flex-shrink: 0;
  background:
    linear-gradient(160deg,
      hsl(var(--hue, 220) 70% 92%) 0%,
      hsl(var(--hue, 220) 65% 80%) 100%);
  color: hsl(var(--hue, 220) 55% 28%);
  display: grid; place-items: center;
  font-weight: 700; font-size: 19px; letter-spacing: -0.5px;
  font-family: var(--font-sans);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,0.5),
    0 1px 2px rgba(10,14,26,0.06);
  user-select: none;
}

/* Реальное фото из МС: 112×112 ужатое в 56×56 (retina-ready).
   `object-fit: cover` обрезает до квадрата. Background оставляем как
   skeleton — пока картинка не загрузилась (lazy) или сломан src. */
.ph-avatar--photo {
  background: var(--surface, #f3f4f8);
  object-fit: cover;
  display: block;
}

/* ───── Шапки групп товаров (▼ Голубика · 5 сортов) ─────
   Структура: <tr class="group-header-row"><td colspan=20><div class="group-header-inner">...
   `display: flex` стоит на ВНУТРЕННЕМ div, не на td: flex на самом
   <td> ломает table-cell механику (td теряет растяжение по colspan,
   полоса не покрывает всю ширину строки). Эталон base-2 делает так
   же — `<td><div class="gh-inner">…</div></td>` (строка 1214).

   Параметры (height/padding/cursor/hover/border) выравнены под
   эталон base-2.html:216-238. */
.group-header-row td {
  padding: 0 16px; height: 40px;
  background: var(--bg-subtle);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  cursor: pointer; user-select: none;
  transition: background 0.12s;
}
.group-header-row td:hover { background: var(--bg-alt); }
.group-header-row:first-child td { border-top: 0; }
.group-header-inner {
  display: flex; align-items: center; gap: 10px;
  height: 100%;
}
.group-toggle {
  display: inline-grid; place-items: center;
  width: 20px; height: 20px;
  background: none; border: none; cursor: pointer; padding: 0;
  font-size: 10px; color: var(--ink-soft);
  transition: transform 0.18s;
  flex-shrink: 0;
}
.group-toggle.collapsed { transform: rotate(-90deg); }
.group-name { font-size: 13px; font-weight: 600; color: var(--ink); }
.group-meta { font-size: 12px; color: var(--mute); }
.group-total {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 11.5px; font-weight: 500; color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ───── Пагинация / «Показать ещё» ───── */
.pagination {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 8px; margin: 14px 0 24px; padding: 0 2px;
  font-size: 13px;
}
.pagination:empty { display: none; }
.load-more-btn {
  padding: 8px 20px;
  font-size: 13px; font-weight: 500;
  background: white; color: var(--accent);
  border: 1.5px solid var(--accent);
  border-radius: 8px; cursor: pointer;
  transition: background .12s, color .12s;
}
.load-more-btn:hover { background: var(--accent-soft, #eef2ff); }
.load-more-btn:disabled { opacity: .55; cursor: default; }
.pgn-done { color: var(--mute); font-size: 13px; }
.pagination .pgn-btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 30px; height: 30px; padding: 0 8px;
  border: 1px solid var(--border); border-radius: 6px;
  background: #fff; color: inherit; text-decoration: none;
  font-variant-numeric: tabular-nums;
  transition: background .12s, border-color .12s;
}
.pagination a.pgn-btn:hover {
  background: var(--accent-soft);
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
}
.pagination .pgn-current {
  background: var(--accent); color: #fff;
  border-color: var(--accent); font-weight: 600; cursor: default;
}
.pagination .pgn-disabled {
  color: color-mix(in srgb, currentColor 35%, transparent);
  background: #fafafa; cursor: default;
}
.pagination .pgn-ellipsis {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 22px; height: 30px; color: color-mix(in srgb, currentColor 50%, transparent);
}
.pagination .pgn-info {
  margin-left: auto; color: color-mix(in srgb, currentColor 60%, transparent);
}

/* ═════ Редизайн каталога 2026-06-17 (handoff PP.zip) ═════ */

/* ───── Шкала готовности .rd (Блок 4) — цвет тира + мини-метр из 3 делений ───── */
.rd {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 23px; padding: 3px 11px 3px 9px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; white-space: normal; line-height: 1.25;
}
/* Иконка-корзина в строке на странице /cart/ (рядом со степпером). */
.cart-row-del {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; margin-left: 8px; vertical-align: middle;
  border: 1px solid var(--border); border-radius: 8px;
  background: var(--bg-card); color: var(--mute); cursor: pointer;
}
.cart-row-del:hover {
  color: var(--bad, #dc2626); border-color: var(--bad, #dc2626);
  background: var(--bad-soft, #fef2f2);
}
.rd-meter { display: inline-flex; align-items: flex-end; gap: 2px; }
.rd-meter i { width: 3.5px; border-radius: 2px; background: currentColor; opacity: .24; }
.rd-meter i:nth-child(1) { height: 6px; }
.rd-meter i:nth-child(2) { height: 8px; }
.rd-meter i:nth-child(3) { height: 10px; }
.rd--ready    { background: var(--ok-soft);   color: var(--ok); }
.rd--soon     { background: var(--warn-soft); color: var(--warn); }
.rd--growing  { background: var(--bg-alt);    color: var(--ink-soft); }
.rd--incoming { background: var(--info-soft); color: var(--info); }
.rd--scheduled { background: var(--info-soft); color: var(--info); }
.rd--ready   .rd-meter i { opacity: 1; }
.rd--soon    .rd-meter i:nth-child(-n+2) { opacity: 1; }
.rd--growing .rd-meter i:nth-child(1) { opacity: 1; }
.rd--scheduled .rd-meter i { opacity: .28; }
.rd--scheduled .rd-meter i:nth-child(1) { opacity: 1; }

/* ───── Шапка .pb: средняя зона (Отправить прайс | Контакты) + зона заказа (Блок 3) ───── */
.pb__send { flex-shrink: 0; }

/* Попап «Отправить прайс»: обычная ссылка / ссылка-вход для клиента (2026-06-24) */
.pb__share { position: relative; display: inline-flex; flex-shrink: 0; }
.share-pop {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 60;
  min-width: 280px; background: #fff; border: 1px solid var(--border);
  border-radius: 10px; box-shadow: 0 10px 30px rgba(15, 23, 42, .16); padding: 6px;
}
.share-pop-item {
  display: block; width: 100%; text-align: left; padding: 9px 11px; border: 0;
  background: none; border-radius: 7px; cursor: pointer; font-size: 13px;
  color: #1f2937; line-height: 1.3;
}
.share-pop-item:hover { background: var(--bg-subtle); }

/* Код встройки прайса на чужой сайт (embed-виджет). */
.share-embed { padding: 8px 10px 10px; border-top: 1px solid var(--border); }
.share-embed-hint { font-size: 12px; color: var(--mute); margin-bottom: 6px; }
.share-embed-code {
  width: 100%; font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11.5px; line-height: 1.45; color: var(--ink);
  border: 1px solid var(--border); border-radius: 6px; padding: 7px 9px;
  background: var(--bg-subtle); resize: vertical;
}
.share-embed-copy { width: 100%; margin-top: 6px; }
.share-embed-doc { display: inline-block; margin-top: 6px; font-size: 12px; color: var(--accent); }
.share-client { border-top: 1px solid var(--border); margin-top: 4px; padding-top: 8px; }
.share-client-q {
  width: 100%; box-sizing: border-box; padding: 8px 10px; border: 1px solid var(--border);
  border-radius: 7px; font-size: 13px; margin-bottom: 6px; outline: none;
}
.share-client-q:focus { border-color: var(--accent, #4338ca); }
.share-client-list { max-height: 230px; overflow-y: auto; color: #6b7280; font-size: 12px; }
.share-client-item {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px;
  width: 100%; text-align: left; padding: 7px 9px; border: 0; background: none;
  border-radius: 7px; cursor: pointer;
}
.share-client-item:hover { background: var(--accent-soft, var(--bg-subtle)); }
.share-client-name { font-size: 13px; color: #1f2937; font-weight: 600; }
.share-client-email { font-size: 11px; color: #6b7280; }
.share-active { margin-top: 6px; border-top: 1px solid var(--border); padding-top: 6px; }
.share-active-list { max-height: 230px; overflow-y: auto; font-size: 12px; }
.share-active-row { display: flex; align-items: center; gap: 8px; padding: 5px 7px; border-radius: 7px; }
.share-active-row:hover { background: var(--bg-subtle); }
.share-active-meta { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.share-active-email { font-size: 12px; color: #1f2937; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.share-active-sub { font-size: 10px; color: #6b7280; }
.share-active-revoke { flex-shrink: 0; font-size: 11px; padding: 3px 9px; border: 1px solid #fca5a5; border-radius: 6px; background: #fff; color: #b91c1c; cursor: pointer; }
.share-active-revoke:hover { background: #fef2f2; }
.share-active-revoke:disabled { opacity: .5; cursor: default; }
.share-client-result { margin-top: 8px; border-top: 1px solid var(--border); padding-top: 8px; }
.share-client-link {
  font-size: 12px; word-break: break-all; background: var(--bg-subtle);
  border-radius: 6px; padding: 8px 10px; margin-bottom: 6px;
  font-family: ui-monospace, "JetBrains Mono", monospace; color: #1f2937;
}
.share-client-hint { font-size: 11px; color: #6b7280; padding: 2px 4px 0; }
.share-client-newms { border-top: 1px solid var(--border); margin-top: 6px; padding-top: 8px; }
.share-client-newms-hint { font-size: 11px; color: #6b7280; margin-bottom: 6px; }
.share-client-inn,
.share-client-ms-q,
.share-client-ms-email-input {
  width: 100%; box-sizing: border-box; padding: 8px 10px; border: 1px solid var(--border);
  border-radius: 7px; font-size: 13px; margin-bottom: 6px; outline: none;
}
.share-client-inn:focus,
.share-client-ms-q:focus,
.share-client-ms-email-input:focus { border-color: var(--accent, #4338ca); }
.share-client-ms-list { max-height: 200px; overflow-y: auto; }
.share-client-ms-email { border-top: 1px dashed var(--border); margin-top: 6px; padding-top: 8px; }
.share-client-reg { color: var(--accent, #4338ca); font-weight: 600; }
.share-result-line { font-size: 12px; color: #1f2937; padding: 2px 4px; }
.share-result-line b { color: #6b7280; font-weight: 600; }
.share-result-copy { color: var(--accent, #4338ca); font-weight: 600; }
.share-client-err { font-size: 12px; color: #b42318; padding: 6px 4px; }
/* Свободное пространство между табами и корзиной — две равные колонки,
   контент каждой отцентрирован. */
.pb__mid { flex: 1 1 auto; display: flex; align-items: center; min-width: 0; }
.pb__midcol { flex: 1 1 0; display: flex; justify-content: flex-start; align-items: center; gap: 8px; min-width: 0; }
/* Контакты — телефон над почтой, по центру, без заливки. */
.pb__mid .pb__contacts {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  font-family: var(--font-sans); font-size: 12.5px; text-align: center;
}
.pb__mid .pb__contacts a {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--pb-soft); text-decoration: none; font-weight: 500;
}
.pb__mid .pb__contacts a:hover { color: var(--pb-accent); }
.pb__mid .pb__contacts a svg { flex-shrink: 0; opacity: .6; }
.pb__mid .pb__contacts .pb__dot { display: none; }
/* Условия заказа + Корзина — одной строкой справа. */
.pb__order { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
/* Корзина в шапке прайса (перенесена из тёмного меню) — зелёный блок:
   счётчик + сумма + прогресс до следующей скидки (как на скрине). */
.pb__cart {
  display: inline-flex; flex-direction: column; gap: 1px; flex-shrink: 0;
  padding: 6px 14px; border-radius: 10px; text-decoration: none; line-height: 1.25;
  background: #e8f6ec; border: 1px solid #cdebd6;
}
.pb__cart:hover { background: #ddf0e3; border-color: #b6e0c4; }
.pb__cart-top {
  display: flex; align-items: center; gap: 8px;
  color: #15803d; font-weight: 700; font-size: 14px; white-space: nowrap;
}
.pb__cart-num {
  display: inline-grid; place-items: center; min-width: 20px; height: 20px;
  padding: 0 6px; border-radius: 10px; background: #16a34a; color: #fff;
  font-size: 12px; font-weight: 700;
}
.pb__cart-sum { color: var(--ink); font-weight: 800; font-size: 15px; }
.pb__cart-tier { font-size: 11px; color: var(--mute); white-space: nowrap; }
/* Корзина переехала в белую шапку каталога → прячем её в тёмном верхнем меню. */
body:has(.catalog-theme) .topbar .cart-btn { display: none; }
/* Узкий экран: средняя зона и зона заказа переносятся под табы. */
@media (max-width: 1080px) {
  .pb__mid { flex: 1 1 100%; order: 3; justify-content: space-between; margin-top: 6px; }
  .pb__order { order: 4; margin-top: 6px; }
}

/* ───── Ручной ресайз колонок (Блок 5) — хват на правом крае <th> ───── */
.col-resizer {
  position: absolute; top: 0; right: -3px; width: 8px; height: 100%;
  z-index: 6; cursor: col-resize; touch-action: none;
}
.col-resizer::after {
  content: ''; position: absolute; left: 3px; top: 7px; bottom: 7px; width: 2px;
  border-radius: 2px; background: transparent; transition: background .12s;
}
.col-resizer:hover::after,
.tbl-card th.col-resizing .col-resizer::after { background: var(--accent); }
body.col-resizing-active { cursor: col-resize !important; user-select: none; }
body.col-resizing-active .col-filter { pointer-events: none; }
