/* Модуль «Поставщики»: справочник бюро.

   Перенесено из public/styles.css как было (24 сентября 2026). Подключается
   отдельным <link> только у включённого модуля — renderIndex() в server.js.
   Токены облика те же, из :root общего styles.css: кегль, отступы и
   радиусы — только ими, числами не писать (docs/ОБЛИК-И-ШКАЛЫ.md).

   В общем styles.css остались то, чем пользуются и другие экраны:
   полоса загрузки (.progress), выбор строкой (.pickbox), .pageicon. */

.suptbl { background: var(--surface); border-radius: var(--radius); overflow: hidden; }
.suptbl td { padding: var(--s-1) var(--s-2); vertical-align: top; }
.suptbl th { cursor: default; }
/* Заголовок — кнопка порядка. Нажатая помечена стрелкой, а не только цветом:
   по цвету не видно, вверх сортировка или вниз. */
.suptbl__th { cursor: pointer; user-select: none; white-space: nowrap; }
.suptbl__th:hover:where([data-hover="mouse"] *) { color: var(--text); }
.suptbl__th.is-sorted { color: var(--text); }
.suptbl__ord { margin-left: 3px; font-size: var(--t-2xs); }

/* Ячейка — текст, пока в неё не встали. Рамка у каждой из сотни ячеек
   превратила бы таблицу в анкету: не видно, где данные, а где пустота. */
.supcell {
  display: flex; align-items: flex-start; gap: var(--s-1); min-height: 30px;
  flex-wrap: wrap;
  border-radius: var(--radius-sm); padding: 0 var(--s-1); cursor: text;
  transition: background var(--fast), box-shadow var(--fast);
}
.supcell:hover:where([data-hover="mouse"] *) { background: var(--hover); box-shadow: inset 0 0 0 1px var(--border); }
/* Текст переносится, а не тянет столбец. Раньше ячейка была в одну строку,
   и «Что продаёт» с описанием на полтораста знаков растягивало столбец на
   пол-экрана, а таблицу — на четыре ширины монитора. Перенос по любому месту
   нужен ради ссылок и почты: пробелов в них нет, и без него строка всё равно
   распирала бы столбец. */
.supcell__text {
  flex: 1; min-width: 0; font-size: var(--t-sm);
  white-space: normal; overflow-wrap: anywhere;
}
/* В таблице текст в покое обрезан до двух строк.
   Обрезка появилась не ради красоты. На мониторе видны первые семь столбцов
   с короткими значениями, а высоту строки задавали «Отзывы» и «Разбор
   аудита» далеко справа: из шестисот строк четыре сотни выходили выше
   восьмидесяти точек, и таблица читалась пустыми провалами между строками.
   Данные при этом не теряются — под срезом стоит «ещё», и в правке текст
   по-прежнему весь. На странице поставщика обрезки нет: там поле и открывают
   затем, чтобы прочитать целиком. */
.supcell__text.is-cut {
  display: -webkit-box; -webkit-box-orient: vertical;
  -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
}
/* «ещё» — своей строкой под текстом и тише текста: это не орган управления
   строкой, а признак того, что под срезом что-то осталось. */
.supcell__more {
  flex: 0 0 100%; margin: 0; padding: 0; border: none; background: none;
  font: inherit; font-size: var(--t-2xs); color: var(--text-faint);
  text-align: left; cursor: pointer;
}
.supcell__more:hover:where([data-hover="mouse"] *) { color: var(--accent-fg); }
.supcell__empty { flex: 1; color: var(--text-faint); font-size: var(--t-sm); }
.supcell__input {
  width: 100%; height: 28px; padding: 0 var(--s-1); font-size: var(--t-sm);
}
/* Ссылка отдельным знаком: нажатие ради правки не должно уводить со страницы */
.supcell__go {
  flex: none; display: inline-flex; color: var(--text-faint); text-decoration: none; padding: 0 var(--s-05);
  font-size: var(--t-xs);
}
.supcell__go:hover:where([data-hover="mouse"] *) { color: var(--accent-fg); text-decoration: none; }
/* Источник — словом в цвете, а не фишкой: столбец читают колонкой сверху
   вниз, и «работали» должно выделяться среди непроверенного, не крича. */
.suporigin { font-size: var(--t-sm); text-align: left; }
.suporigin.is-worked { color: var(--ok-fg); font-weight: 500; }
.suporigin.is-viki { color: var(--text); }
.suporigin.is-bought { color: var(--text-faint); }
/* Две кнопки в строке — чёрный список и удаление — в один ряд, без переноса */
.suptbl__act { white-space: nowrap; }
.supcell__pick {
  background: none; border: none; padding: 0; cursor: pointer; font: inherit;
  display: flex; align-items: center; min-width: 0;
}

/* Перебранная руками строка — светло-зелёная. Отметка не про поставщика,
   а про разбор базы: две трети строк пришли пачкой из купленной таблицы,
   и без цвета не видно, докуда дошли. Цвет бледный намеренно — это фон под
   двадцатью столбцами, а не сообщение. */
.suptbl tr.is-checked td { background: color-mix(in srgb, var(--ok) 9%, transparent); }
/* Категорий у поставщика бывает пять — метки переносятся, а не режутся */
.supcell--tags .supcell__pick { flex: 1; }
.supcell__tags { display: flex; flex-wrap: wrap; gap: 3px; }

/* ── Страница поставщика — профиль, а не форма (разбор, П2) ─────────────

   Две колонки с пределом ширины: на 2560 строки «Что продаёт» и «Условий»
   не растягиваются на две тысячи точек, а колонки не расходятся по краям
   экрана. Слева — о поставщике, справа — аудит. На телефоне — одной
   колонкой, аудит под контактами. */
.supprof { --prof-max: 1680px; }
.supprof__head, .supprof__sub, .supprof__grid { max-width: var(--prof-max); }
.supprof__head {
  display: flex; align-items: center; gap: var(--s-2) var(--s-3); flex-wrap: wrap;
}
.supprof__name {
  display: inline-flex; align-items: center; gap: var(--s-2);
  min-width: 0; overflow-wrap: anywhere;
}
.supprof__cats { min-width: 0; }
.supprof__cats .supcell { min-height: 0; padding: var(--s-05) var(--s-1); }
.supprof__cats .supcell__empty { color: var(--text-faint); font-size: var(--t-sm); white-space: nowrap; }
.supprof__sp { flex: 1 1 0; }
.supprof__acts { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.supprof__acts .btn .ic { color: var(--text-faint); }
/* Строка под именем: что продаёт · сегмент · город */
.supprof__sub {
  display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap;
  margin: var(--s-2) 0 var(--s-4); color: var(--text-dim); font-size: var(--t-base);
}
.supprof__line { display: flex; min-width: 0; max-width: 100%; white-space: pre; }
.supprof__what { min-width: 0; max-width: 72ch; overflow: hidden; text-overflow: ellipsis; }
.supprof__where { flex: none; }
/* Контакты — тем же кеглем, что значения рядом */
.supdl .supkon__name { font-size: var(--t-base); }
.supdl .supkon__val { font-size: var(--t-sm); }

.supprof__grid {
  display: grid; gap: var(--s-4); align-items: start;
  grid-template-columns: minmax(0, 1.5fr) minmax(320px, 1fr);
}
.supprof__panel {
  background: var(--solid); border-radius: var(--radius-lg); box-shadow: var(--sh-1);
  padding: var(--s-5); display: flex; flex-direction: column; gap: var(--s-4); min-width: 0;
}
.supprof__cap { font-size: var(--t-xs); font-weight: 600; color: var(--text-faint); }

/* Подпись — значение. Значение — текст, пока в него не встали: правка
   щелчком, под мышью подложка, как у ячейки таблицы. */
.supdl {
  display: grid; grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--s-2) var(--s-5); margin: 0; align-items: start;
}
.supdl dt { color: var(--text-faint); font-size: var(--t-sm); padding-top: var(--s-1); }
.supdl dd { margin: 0; min-width: 0; }
.supdl .supcell { padding: var(--s-1) var(--s-2); margin-left: calc(-1 * var(--s-2)); }
.supdl .supcell__text, .supprof__note .supcell__text { font-size: var(--t-base); }
.supdl .supcell__empty, .supprof__note .supcell__empty { font-size: var(--t-base); }
.supdl .supcell--kon { cursor: pointer; }
.supprof .supcell:hover:where([data-hover="mouse"] *) { box-shadow: none; }
.supprof__note { display: flex; flex-direction: column; gap: var(--s-1); }
.supprof__note .supcell { padding: var(--s-1) var(--s-2); margin-left: calc(-1 * var(--s-2)); }

/* Пустое — не полями с прочерком, а одной строкой: «Не заполнено: адрес,
   юрлицо — добавить поле». Имя поля нажимается и открывает его правку. */
.supprof__empty {
  color: var(--text-faint); font-size: var(--t-sm); line-height: 1.7;
  border-top: 1px solid var(--border); padding-top: var(--s-3);
}
.supprof__fill, .supprof__add {
  display: inline; padding: 0; border: none; background: none; cursor: pointer;
  font: inherit; color: var(--text-dim); border-radius: var(--radius-sm);
  transition: color var(--fast), background var(--fast);
}
.supprof__fill:hover:where([data-hover="mouse"] *), .supprof__add:hover:where([data-hover="mouse"] *) { color: var(--accent-fg); }
.supprof__fill--menu, .supprof__add { color: var(--accent-fg); }
.supprof__add { font-size: var(--t-base); padding: var(--s-1) 0; }

/* Аудит: оценка крупно и цветом, флаги плашками */
.supprof__grade { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.supprof__site { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.supprof__pick {
  display: inline-flex; align-items: center; gap: var(--s-1);
  padding: 0 var(--s-2); border: none; background: none; cursor: pointer;
  border-radius: var(--radius-sm); font: inherit; font-size: var(--t-base); color: var(--text);
  transition: background var(--fast);
}
.supprof__pick:hover:where([data-hover="mouse"] *), .supprof__pick.is-open { background: var(--hover); }
.supprof__letter { font-size: var(--t-xl); font-weight: 700; line-height: 1.3; }
.supprof__letter.is-A { color: var(--ok-fg); }
.supprof__letter.is-C { color: var(--warn-fg); }
.supprof__letter.is-D { color: var(--late-fg); }
.supprof__letter.is-none { color: var(--text-faint); font-weight: 400; }
.supprof__flags { display: flex; flex-direction: column; gap: var(--s-2); }
.supprof__flags .supcell { padding: 0; }
.supprof__flags .supcell:hover:where([data-hover="mouse"] *) { background: none; }
.supflags { display: flex; flex-direction: column; gap: var(--s-1); width: 100%; }
.supflag {
  display: flex; gap: var(--s-2); align-items: flex-start;
  padding: var(--s-2) var(--s-3); border-radius: var(--radius);
  background: var(--late-soft); color: var(--text); font-size: var(--t-base);
  transition: box-shadow var(--fast);
}
.supprof__flags .supcell:hover:where([data-hover="mouse"] *) .supflag { box-shadow: inset 0 0 0 1px var(--late); }
.supflag b { color: var(--late-fg); font-weight: 700; }
/* Разбор, отзывы, источники — свёрнуты одной строкой */
.supprof__more { border-top: 1px solid var(--border); padding-top: var(--s-3); }
.supprof__more > summary {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-2);
  cursor: pointer; list-style: none; color: var(--text-dim); font-size: var(--t-base); font-weight: 500;
  border-radius: var(--radius-sm);
}
.supprof__more > summary::-webkit-details-marker { display: none; }
.supprof__more > summary::after { content: '▾'; color: var(--text-faint); font-size: var(--t-xs); }
.supprof__more[open] > summary::after { content: '▴'; }
.supprof__more > summary:hover:where([data-hover="mouse"] *) { color: var(--text); }
.supdl--more { margin-top: var(--s-3); }

@media (max-width: 900px) {
  .supprof__grid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
  .supprof__sp { display: none; }
  .supprof__panel { padding: var(--s-4); }
  /* Подпись над значением: в две колонки на 375 точках значению оставалось
     двести точек, и «Что продаёт» шло столбиком по два слова */
  .supdl { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .supdl dt { padding-top: var(--s-2); }
  .supprof__acts .btn { max-width: 100%; }
  .supprof__line { flex-wrap: wrap; white-space: normal; }
  .supprof__what { white-space: nowrap; max-width: 100%; }
}

/* Окно заведения поставщика: два поля в ряд */
.newsup__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-3); }
/* Категории в окне: выбранные метками, под ними поле поиска и список.
   Список короткий и листается: высоты окна на полсотни строк не хватит. */
.newsup__chips { display: flex; flex-wrap: wrap; gap: var(--s-1); margin-bottom: var(--s-2); }
.newsup__chips[hidden] { display: none; }
.newsup__find { width: 100%; }
.newsup__found {
  display: flex; flex-direction: column; margin-top: var(--s-1);
  max-height: 168px; overflow-y: auto; overscroll-behavior: contain;
  border-radius: var(--radius-sm); box-shadow: inset 0 0 0 1px var(--border);
  padding: var(--s-1);
}
.newsup__opt {
  text-align: left; padding: var(--s-1) var(--s-2); border: none; background: none;
  border-radius: var(--radius-sm); cursor: pointer;
  font: inherit; font-size: var(--t-base); color: var(--text);
}
.newsup__opt:hover:where([data-hover="mouse"] *), .newsup__opt:focus-visible { background: var(--hover); }
.newsup__none { padding: var(--s-1) var(--s-2); }

/* ── Шапка и строка отборов (разбор «Ресурсов», 1 октября 2026, П1) ──────

   Две строки над списком вместо пяти. Шапка: заголовок, поиск, «+ Поставщик»,
   «⋯». Строка отборов: категория, «Фильтры», включённые метками, справа
   порядок и вид. Все органы обеих строк одной средней линии.

   Шапка разложена сеткой, а не флексом. Флексом название, поле и кнопки
   вставали подряд от левого края, и на широком экране треть строки
   оставалась пустой справа. Боковые колонки равны — поле стоит по центру
   страницы, а не по центру остатка, — а кнопки уходят к правому краю. */
.suphead {
  display: grid; align-items: center;
  grid-template-columns: 1fr minmax(200px, 640px) 1fr;
  gap: var(--s-3); margin-bottom: var(--s-2);
}
/* Своя нижняя граница ширины: общее правило шапок разделов ставит
   заголовку min-width: 0, и в сетке его колонка сжималась ниже самого
   слова — «Поставщики» вылезало из своей клетки и уезжало под поле поиска
   на экранах от 760 до 1100 точек. */
.suphead__title { display: flex; align-items: center; gap: var(--s-3); justify-self: start; min-width: max-content; }
.suphead h1 { min-width: max-content; }
.supsearch { width: 100%; height: 36px; font-size: var(--t-base); }
.suphead .supsearch { min-width: 0; max-width: none; margin: 0; }
.suphead .page__head-right { justify-self: end; gap: var(--s-2); }
/* «⋯» — той же высоты, что «+ Поставщик» рядом; под пальцем кнопки
   выше (38, общее правило pointer: coarse) — и «⋯» вслед за ними */
.supmore { width: 36px; height: 36px; }
@media (pointer: coarse) { .supmore { width: 38px; height: 38px; } }

/* Выбранный служебный список — меткой у заголовка, крестик возвращает
   к общему. Вкладок над лентой больше нет: чёрный список и кандидатов
   открывают из «⋯». */
.suplist {
  display: inline-flex; align-items: center; gap: var(--s-2);
  height: 30px; padding: 0 var(--s-1) 0 var(--s-3); border-radius: var(--radius-full);
  background: var(--well); font-size: var(--t-sm); font-weight: 600; color: var(--text);
  white-space: nowrap;
}
.suplist__n { font-weight: 400; color: var(--text-faint); font-variant-numeric: tabular-nums; }
.suplist__x {
  width: 24px; height: 24px; display: grid; place-items: center; padding: 0;
  border: none; border-radius: var(--radius-full); background: none; cursor: pointer;
  color: var(--text-dim); transition: background var(--fast);
}
.suplist__x:hover:where([data-hover="mouse"] *) { background: var(--hover); color: var(--text); }

.supbar {
  display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap;
  margin-bottom: var(--s-4);
}
.supbar__sp { flex: 1 1 0; min-width: 0; }
.supbar__n { white-space: nowrap; font-variant-numeric: tabular-nums; }
.supbar__cat { max-width: 360px; }
.supbar__cat .menulabel { min-width: 0; }
.supbar__catname { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.supbar__catn { color: var(--text-faint); font-weight: 400; font-variant-numeric: tabular-nums; }
/* Включённый отбор — кнопка в своём цвете */
.supbar__cat.is-set, .supbar__f.is-set {
  background: var(--accent-soft); border-color: transparent; color: var(--text);
  --btn-hover-bg: color-mix(in oklab, var(--accent-soft), var(--ink) 6%);
  --btn-hover-line: transparent;
}
.supbar__badge {
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: var(--radius-full);
  display: inline-grid; place-items: center;
  background: var(--accent); color: var(--accent-ink);
  font-size: var(--t-xs); font-weight: 600; font-variant-numeric: tabular-nums;
}
.supbar__badge[hidden] { display: none; }
.supbar__chips { display: contents; }
/* Метка включённого отбора: нажатие снимает её целиком */
.supchip {
  display: inline-flex; align-items: center; gap: var(--s-1);
  height: 26px; padding: 0 var(--s-2) 0 var(--s-3); border-radius: var(--radius-full);
  border: none; background: var(--well); cursor: pointer;
  font: inherit; font-size: var(--t-sm); font-weight: 500; color: var(--text); white-space: nowrap;
  transition: background var(--fast);
}
.supchip:hover:where([data-hover="mouse"] *) { background: var(--hover-solid); }
.supchip .ic { color: var(--text-faint); }
.supchip--all { background: none; color: var(--text-dim); padding: 0 var(--s-2); }
.supchip--all:hover:where([data-hover="mouse"] *) { background: var(--hover); }
/* Порядок — словами и направлением: «По названию А–Я» */
.supsort__dir { color: var(--text-faint); font-weight: 400; }
.supbar .viewseg { flex: none; }

/* Окошко у кнопки: выбор категории и фильтры. Строится на .menupop —
   рамка, тень и радиус те же, что у меню. */
.suppop { display: flex; flex-direction: column; overflow: hidden; }
.suppop--cat { width: 320px; max-width: 320px; }
.suppop--f { width: 420px; max-width: 420px; }
.suppop__search { flex: none; height: 32px; margin: var(--s-1) var(--s-1) var(--s-2); width: auto; }
.suppop__list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.suppop__row { padding: var(--s-2); font-size: var(--t-base); border-bottom: none; border-radius: var(--radius-sm); }
.suppop__row:hover:where([data-hover="mouse"] *) { background: var(--hover); }
.suppop__row.is-active { font-weight: 600; background: var(--hover); }
.suppop__name { flex: 1; min-width: 0; text-align: left; }
.suppop__none { padding: var(--s-2); }
.suppop__add {
  flex: none; gap: var(--s-2); padding: var(--s-2); margin-top: var(--s-1);
  border-top: 1px solid var(--border); border-bottom: none; border-radius: 0;
  font-size: var(--t-base); color: var(--text-dim);
}
.suppop__add:hover:where([data-hover="mouse"] *) { color: var(--text); background: var(--hover); }
.suppop__body { overflow-y: auto; padding: var(--s-2); display: flex; flex-direction: column; gap: var(--s-3); }
.supf__cap { font-size: var(--t-xs); font-weight: 600; color: var(--text-faint); margin-bottom: var(--s-1); }
.supf__row { display: flex; flex-wrap: wrap; gap: var(--s-1); }
.supf__pill {
  height: 28px; padding: 0 var(--s-3); border-radius: var(--radius-full);
  border: 1px solid var(--border); background: none; cursor: pointer;
  font: inherit; font-size: var(--t-sm); font-weight: 500; color: var(--text-dim); white-space: nowrap;
  transition: background var(--fast), border-color var(--fast);
}
.supf__pill:hover:where([data-hover="mouse"] *) { background: var(--hover); }
.supf__pill.is-on { background: var(--accent-soft); border-color: transparent; color: var(--text); font-weight: 600; }

/* На телефоне поиск уходит на свою строку.

   В одну строку с названием раздела и двумя кнопками он не помещался
   и распирал страницу: сама страница уезжала вбок, и заголовок с фишками
   уходили за левый край. Поиск при этом главный орган раздела — прятать
   или ужимать его нельзя, значит место ему нужно своё. */
@media (max-width: 760px) {
  /* Сетка в три колонки на узком экране не нужна: колонок нет, всё
     переносится. */
  .suphead { display: flex; flex-wrap: wrap; }
  .suphead .supsearch { flex: 1 0 100%; order: 3; max-width: none; }
  /* Метка «Чёрный список» уходит под заголовок, а не сталкивает «+» и «⋯»
     на свою строку */
  .suphead__title { flex: 1 1 0; min-width: 0; flex-wrap: wrap; row-gap: var(--s-1); }
  .suphead .page__head-right { margin-left: auto; }
  /* «+ Поставщик» — круглой, как «+ Задача» на телефоне */
  .supadd { width: auto; aspect-ratio: 1; padding: 0; }
  .supadd__t { display: none; }
  /* Счёт — за столом, где базу разбирают; на телефоне строка нужна отборам */
  .supbar__n { display: none; }
  .supbar { gap: var(--s-1) var(--s-2); }
  .supbar__cat { max-width: 200px; }
  /* Порядок — одним направлением: «По названию» не помещалось в строку
     с категорией и фильтрами, и кнопка сваливалась на свою */
  .supsort__label { display: none; }
  .supsort { padding: 0 var(--s-2); }
}

/* Отметка «перебрано» — галочкой, и только у перебранных (разбор, П4).
   Не системный флажок: тот читался бы как «выбрать строку». */
.suptick {
  width: 20px; height: 20px; flex: none; padding: 0;
  display: inline-grid; place-items: center; border-radius: var(--radius-full);
  border: 1px solid transparent; background: none; cursor: pointer; color: transparent;
  transition: background var(--fast), border-color var(--fast), color var(--fast);
}
.suptick svg { display: block; }
.suptick.is-on { background: var(--ok-soft); color: var(--ok-fg); }
.suptick.is-static { cursor: default; }
/* Неперебранная строка — пустое место, кружок проявляется под мышью:
   нажать есть куда, а смотреть не на что */
.suptbl tr:hover:where([data-hover="mouse"] *) .suptick:not(.is-on) { border-color: var(--border-strong); }
.suptick:not(.is-on):hover:where([data-hover="mouse"] *), .suptick:not(.is-on):focus-visible { color: var(--text-faint); background: var(--hover); }
.suptick.is-on:not(.is-static):hover:where([data-hover="mouse"] *) { background: color-mix(in srgb, var(--ok) 24%, transparent); }
.supcell--check { justify-content: center; align-items: center; }
.supcell--check { cursor: default; }
.supcell--check:hover:where([data-hover="mouse"] *) { background: none; box-shadow: none; }

/* Выбор пачкой: своя колонка, своя галочка, свой цвет строки */
.suptbl__pick { text-align: center; vertical-align: middle; }
.suptbl__pick input { margin: 0; cursor: pointer; }
/* Переход на страницу поставщика — свой столбец сразу за выбором пачкой.
   Кнопка тихая: строк шестьсот, и шестьсот заметных кнопок легли бы решёткой
   поверх данных. Она проясняется на строке под курсором и загорается под
   самим курсором — то есть находится ровно тогда, когда её ищут. */
.suptbl__open { text-align: center; vertical-align: middle; }
.supopen {
  display: inline-grid; place-items: center;
  width: 28px; height: 28px; padding: 0;
  border: none; border-radius: var(--radius-sm);
  background: none; cursor: pointer; color: var(--text-faint);
  transition: color var(--fast), background var(--fast);
}
.suptbl tr:hover:where([data-hover="mouse"] *) .supopen { color: var(--text-dim); }
.supopen:hover:where([data-hover="mouse"] *) { color: var(--accent-fg); background: var(--hover); }
.supopen:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.suptbl tr.is-picked td { background: color-mix(in srgb, var(--accent) 10%, transparent); }

/* Что можно сделать с выбранными. Появляется, когда есть кого. */
.suppick {
  display: none; align-items: center; gap: var(--s-2); flex-wrap: wrap;
  margin-bottom: var(--s-3); padding: var(--s-2) var(--s-3);
  border: 1px solid var(--accent); border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent) 7%, transparent);
}
.suppick.is-on { display: flex; }
.suppick__n { font-size: var(--t-sm); font-weight: 500; white-space: nowrap; }

/* Технический номер строки: моноширинный, тусклый, копируется нажатием */
.supcell--id { cursor: copy; }
.supid {
  font-family: var(--mono);
  font-size: var(--t-2xs); color: var(--text-faint); overflow-wrap: anywhere;
}

/* Контакты в ячейке: у поставщика их бывает пять, и каждый — своя строка */
.supkon { display: flex; flex-direction: column; gap: 3px; width: 100%; }
.supkon__row { display: flex; flex-wrap: wrap; gap: var(--s-1); align-items: baseline; }
.supkon__name { font-size: var(--t-sm); font-weight: 500; }
.supkon__val {
  font-size: var(--t-xs); color: var(--text-dim); text-decoration: none;
  overflow-wrap: anywhere;
}
a.supkon__val:hover:where([data-hover="mouse"] *) { color: var(--accent-fg); }

/* Правка контакта: четыре поля в ряд, заметка под ними, крестик справа */
.konedit {
  position: relative; border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--s-3); padding-right: 40px; margin-bottom: var(--s-2);
  display: flex; flex-direction: column; gap: var(--s-2);
}
.konedit__grid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-2);
}
.konedit__del { position: absolute; top: var(--s-2); right: var(--s-2); }

/* Справочник на телефоне — карточками.

   Двадцать пять столбцов на экране в 375 точек — лента шириной в пятнадцать
   экранов. С телефона в справочник заходят найти поставщика и позвонить ему;
   разбирают базу за столом. */
/* Сеткой, а не столбцом: на телефоне столбец выходит сам собой — там
   помещается один, — а за столом карточка во всю ширину монитора это строка
   таблицы, только высокая. 300 точек — ширина, на которой имя поставщика
   и строчка «что продаёт» читаются без переносов посреди слова. */
/* Карточки одного ряда — одной высоты, подвал прижат к низу (разбор, П6):
   при `align-items: start` ряд стоял лесенкой 120 / 140 / 120, и «сайт ↗»
   гулял по высоте. Так же сделаны карточки задач (30 сентября 2026). */
.supcards {
  display: grid; gap: var(--s-2);
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  align-items: stretch;
}
/* Невидимая черта под лентой: до неё доезжает наблюдатель и дописывает
   следующую пачку карточек. */
.supcards__end { height: 1px; }
.supcard {
  /* Обводка, а не одна заливка. На светлой теме карточку от полотна отделяла
     разница в светлоте, и её хватало; на тёмной обе плоскости тёмные, разница
     сходит на нет, и сетка карточек превращалась в одно поле с текстом.
     Граница держит карточку карточкой в любой теме. */
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--s-3); display: flex; flex-direction: column; gap: var(--s-1);
  transition: border-color var(--fast), box-shadow var(--fast);
}
.supcard:hover:where([data-hover="mouse"] *) { border-color: var(--border-strong); box-shadow: var(--shadow-xs); }
.supcard.is-checked { box-shadow: inset 3px 0 0 var(--ok); }
.supcard__name {
  border: none; background: none; padding: 0; text-align: left; cursor: pointer;
  font: inherit; font-size: var(--t-md); font-weight: 600; color: var(--text);
}
.supcard__cats { display: flex; flex-wrap: wrap; gap: 3px; }
.supcard__what {
  font-size: var(--t-sm); color: var(--text-dim);
  /* Две строки: описание бывает в полтораста слов, и карточка вырастала
     на пол-экрана — до следующего поставщика приходилось листать. */
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
}
.supcard__kon { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s-2); }
.supcard__who { font-size: var(--t-sm); font-weight: 500; }
.supcard__link { font-size: var(--t-sm); text-decoration: none; }
.supcard__foot {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s-2); margin-top: auto; padding-top: var(--s-1);
}
.supcard__go { font-size: var(--t-sm); text-decoration: none; flex: none; }
.supcard__head { display: flex; align-items: center; gap: var(--s-2); min-width: 0; }
.supcard__head .supcard__name { min-width: 0; overflow-wrap: anywhere; }

.konedit__move { position: absolute; top: var(--s-2); right: 40px; }

/* Разбор повторов. Куча — это строки об одном поставщике; отмеченная
   останется, остальные подошьются к ней. */
.dupgroup {
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: var(--s-3); margin-bottom: var(--s-3);
}
.dupgroup__why { margin-bottom: var(--s-2); }
.dupgroup__foot { margin-top: var(--s-2); display: flex; justify-content: flex-end; }
.duprow {
  display: flex; align-items: baseline; gap: var(--s-2); cursor: pointer;
  padding: var(--s-1) 0;
}
.duprow input { margin: 0; flex: none; }
.duprow__name { font-weight: 500; flex: none; }
.duprow__meta { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Оценка аудита — буквой в цвете. Читать её приходится колонкой сверху вниз,
   и цвет отвечает на «где тут плохо» быстрее, чем чтение букв. */
.suptbl__grade .supcell__text { font-weight: 600; }
.suptbl__grade.is-A .supcell__text { color: var(--ok-fg); }
.suptbl__grade.is-B .supcell__text { color: var(--text); }
.suptbl__grade.is-C .supcell__text { color: var(--warn-fg); }
.suptbl__grade.is-D .supcell__text { color: var(--late-fg); }
/* Таблица шире экрана и листается вбок: столбцов пятнадцать, и ужимать их
   до нечитаемости хуже, чем листать. Ширины заданы в точках, а не в долях:
   в долях «Сегмент» получал столько же, сколько «Что продаёт». */
/* Ширины столбцов — предел, а не запрос: fixed держит их ровно такими,
   какие заданы, и содержимое переносится внутри. min-width таблице ставит
   сама страница, суммой видимых столбцов: столбцы включаются и выключаются,
   и зашитое сюда число врало бы при каждом переключении. */
.suptbl { table-layout: fixed; }
/* Поле правки на несколько строк — для тех полей, где лежит абзац */
.supcell__input--long {
  height: auto; min-height: 120px; resize: vertical; line-height: 1.4;
  padding: var(--s-1);
}
/* Таблица шире экрана листается в своей рамке, а не вместе со страницей.
   Пока вбок ехала страница, уезжало всё разом — шапка раздела, поиск,
   фишки категорий, — и слева оставалось пустое поле шириной в монитор. */
.tblscroll {
  overflow: auto; max-width: 100%;
  border-radius: var(--radius);
  /* Высоту ставит разметка: над таблицей то одна строка отборов, то три,
     и зашитое сюда число врало бы через раз. */
}
/* Край растворяется, пока вбок есть что листать (разбор, П7). Прежняя тень
   подложкой рамки не была видна вовсе: её закрывал фон самой таблицы.
   Маской — как у полосы вкладок; полоса прокрутки справа (--sbw, ширину
   меряет разметка) в растворение не попадает. */
.tblscroll.есть-справа {
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - var(--sbw, 0px) - 48px),
    transparent calc(100% - var(--sbw, 0px)), #000 calc(100% - var(--sbw, 0px)));
  mask-image: linear-gradient(90deg, #000 calc(100% - var(--sbw, 0px) - 48px),
    transparent calc(100% - var(--sbw, 0px)), #000 calc(100% - var(--sbw, 0px)));
}
/* Шапка таблицы стоит на месте, пока едет всё остальное. Без неё на шестой
   сотне строк уже не помнишь, какой столбец что значит, а столбцов двадцать. */
.suptbl thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface);
  box-shadow: inset 0 -1px 0 var(--border);
}

/* Карточка — сплошной, без обводки (сверка облика, 27 сентября 2026): на
   тёмной стороне новых токенов --solid светлее фона, и карточку держит тон
   с тенью — ради этого обводка и заводилась */
.supcard { border-color: transparent; background: var(--solid); box-shadow: var(--sh-1); }

/* Procurement fields of the supplier card (stage 8): lead time and template */
.supprof__procrow { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.supprof__lead { width: 72px; }
.supprof__hint { color: var(--text-faint); font-size: var(--t-sm); }
