

/* ==========================================================================
   css/pages/catalog.css
   страничные стили
   ========================================================================== */
/* ===========================================================================
   Страница каталога /catalog/. Владелец файла — tools/gen_catalog.py и
   js/modules/catalog.js.

   Всё оформление — через токены css/tokens.css.
   =========================================================================== */


/* Блоки, которые без JavaScript бессмысленны, прячет <noscript> в <head>.
   Пояснение под тулбаром, наоборот, появляется только без JS. */
.noscript-note { display: none; margin-bottom: var(--s-5); }

/* ============================ шапка раздела ============================ */
/* В макете крошки, H1 и вкладки стоят плотной колонкой: от низа шапки до
   первой карточки 250 px. Поэтому воздух над H1 срезан до крошек, а вводный
   текст ушёл под выдачу (.catalog__outro). */
[data-page="catalog"] .crumbs { padding-bottom: var(--s-1); }
[data-page="catalog"] .section--tight { padding-top: 0; }
.catalog__head { margin-bottom: var(--s-4); }

.catalog__outro {
  margin-top: var(--s-6); max-width: 72ch;
  font-size: var(--fs-sm); color: var(--muted);
}

/* Вкладки: сплошная плашка без внутренних полей — активная заливка в макете
   доходит до самой рамки, а разделы отбиты тонкими линиями. */
/* overflow-x:auto, а не hidden: на телефоне четыре вкладки не влезают в экран
   и должны прокручиваться. Скругление держим на крайних кнопках — обрезка
   контейнером убила бы прокрутку. */
.catalog__tabs { margin-bottom: var(--s-5); max-width: 100%; overflow-x: auto; padding: 0; gap: 0; }
.segmented__btn:first-child { border-radius: 8px 0 0 8px; }
.segmented__btn:last-child { border-radius: 0 8px 8px 0; }
.segmented__btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 20px; line-height: 1.25;
  font-weight: 700; font-size: var(--fs-sm); color: var(--ink-2); white-space: nowrap;
  transition: background var(--dur), color var(--dur);
}
.segmented__btn + .segmented__btn { border-left: 1px solid var(--line); }
.segmented__btn:hover { color: var(--navy); background: var(--bg-2); }
.segmented__btn[aria-current] { background: var(--navy); color: var(--white); }
.segmented__btn[aria-current]:hover { background: var(--navy-700); }
.segmented__n { font-size: var(--fs-xs); font-weight: 700; opacity: .6; }

/* ============================ раскладка ============================ */
.catalog__layout {
  display: grid; grid-template-columns: 244px minmax(0, 1fr); gap: 28px; align-items: start;
}
.catalog__aside { position: sticky; top: calc(var(--header-h) + 12px); }
.catalog__filters-toggle { display: none; width: 100%; }
.catalog__filters-n { color: var(--muted); font-weight: 400; }
.catalog__filters-n:not(:empty)::before { content: " · "; }
/* На широком экране панель и список стоят рядом — уходить из фильтров некуда. */
.catalog__filters-apply { display: none; }
.catalog__main { min-width: 0; }

/* ============================ панель фильтров ============================ */
.filters { display: flex; flex-direction: column; gap: var(--s-2); }
.filters__card { padding: 0 14px; }
.filters__reset {
  justify-content: center; padding: 10px 14px; font-size: var(--fs-sm);
  border-color: var(--line);
}
/* Иконки панели в макете тёмные, а не золотые: золото на странице каталога
   оставлено рамке «Настроить в 3D» и ползункам — иначе акцент размывается. */
.filters__reset svg { width: 17px; height: 17px; color: var(--navy); }

/* Заголовки групп фильтров — то же правило: 19 px высоты при 18 px между
   центрами. Поля по 13 дают 32 и снимают нарушение. */
.filters__group { border-top: 1px solid var(--line); padding: 13px 0; }
.filters__group:first-of-type { border-top: 0; }
.filters__group--static { border-top: 1px solid var(--line); }

.filters__sum { list-style: none; cursor: pointer; display: block; }
.filters__sum::-webkit-details-marker { display: none; }
.filters__row { display: flex; align-items: center; gap: 9px; }
.filters__ic { width: 19px; height: 19px; flex: none; color: var(--ink-2); }
.filters__title { font-weight: 700; font-size: var(--fs-sm); line-height: 1.3; flex: 1; min-width: 0; }
.filters__chev {
  width: 17px; height: 17px; flex: none; color: var(--muted-2);
  transition: transform var(--dur) var(--ease);
}
.filters__group[open] > .filters__sum .filters__chev { transform: rotate(180deg); }
.filters__note { font-size: var(--fs-xs); line-height: 1.3; color: var(--muted); margin: 3px 0 0 28px; }
/* Интервал между строками фильтра — не оформление, а требование.
   WCAG 2.2 (2.5.8, уровень AA) разрешает цель меньше 24×24, только если
   вокруг неё есть место: круг диаметром 24 не должен задевать соседнюю цель.
   Строка флажка высотой 21 px при зазоре 9 давала расстояние между центрами
   15 px — попасть пальцем мимо было легче, чем попасть. 12 px зазора дают 33
   и укладывают строку в норму, не растягивая колонку заметно. */
.filters__body { padding: 10px 0 2px 28px; display: flex; flex-direction: column; gap: 12px; }
/* «Тип изделия» на вкладке заборов вырождается и прячется из JS. Скрытая
   группа остаётся :first-of-type, поэтому линию снимаем и со следующей —
   иначе панель открывается лишней чертой под самой рамкой карточки. */
.filters__group[hidden] + .filters__group { border-top: 0; }
.filters__group[open] > .filters__sum .filters__note { display: none; }

.filters__opt {
  display: flex; align-items: center; gap: 9px; cursor: pointer;
  font-size: var(--fs-sm); font-weight: 600; color: var(--ink-2);
}
.filters__opt input { width: 17px; height: 17px; accent-color: var(--gold); flex: none; }
.filters__opt-title { flex: 1; min-width: 0; }
.filters__opt:hover .filters__opt-title { color: var(--ink); }
/* Счётчик товаров у варианта фильтра — это ТЕКСТ, который читают: «Профнастил
   6». --muted-2 задуман для иконок и рамок и на 12 px даёт 3,64:1 при норме
   4,5:1; про эту ловушку прямо написано в css/tokens.css. */
.filters__count { font-size: var(--fs-xs); color: var(--muted); font-weight: 700; }
/* Вариант, которого в текущей выдаче нет: не прячем, а гасим — так видно,
   что фильтр существует, и не «прыгает» высота панели. */
.filters__opt.is-empty { opacity: .45; }
.filters__opt--solo {
  border-top: 1px solid var(--line); padding-top: var(--s-4); margin-top: var(--s-3);
  font-weight: 700; color: var(--ink);
}

/* подсказка «ⓘ» */
.hint {
  background: none; border: 0; padding: 0; cursor: help; color: var(--muted-2);
  display: inline-flex; flex: none;
}
.hint:hover { color: var(--gold-600); }
.hint__ic { width: 15px; height: 15px; }

/* диапазоны «от … до …» */
.filters__range { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-2); }
.filters__mini { display: flex; align-items: center; gap: 7px; min-width: 0; }
.filters__mini-lab { font-size: var(--fs-xs); color: var(--muted); flex: none; }
/* Поля «от» и «до» в фильтрах: тоже 16 px, иначе iPhone зумит каталог при
   попытке уточнить цену. */
.input--mini { padding: 6px 8px; text-align: center; }

.range { position: relative; height: 26px; margin-top: var(--s-2); }
.range__track {
  position: absolute; left: 0; right: 0; top: 11px; height: 4px;
  background: var(--line); border-radius: var(--radius-pill); display: block;
}
.range__fill {
  position: absolute; top: 0; bottom: 0; left: 0; right: 0;
  background: var(--gold); border-radius: var(--radius-pill); display: block;
}
/* Два ползунка лежат друг на друге: события ловит только сам «бегунок»,
   иначе верхний input перехватывал бы клики по нижнему на всей длине. */
.range__thumb {
  position: absolute; left: 0; top: 0; width: 100%; height: 26px; margin: 0;
  -webkit-appearance: none; appearance: none; background: none; pointer-events: none;
}
.range__thumb::-webkit-slider-thumb {
  -webkit-appearance: none; pointer-events: auto;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--white); border: 2px solid var(--gold); box-shadow: var(--shadow-xs); cursor: grab;
}
.range__thumb::-moz-range-thumb {
  pointer-events: auto; width: 16px; height: 16px; border-radius: 50%;
  background: var(--white); border: 2px solid var(--gold); box-shadow: var(--shadow-xs); cursor: grab;
}
.range__thumb:focus-visible::-webkit-slider-thumb { border-color: var(--navy); }
.range__thumb:focus-visible::-moz-range-thumb { border-color: var(--navy); }

/* образцы RAL. В макете шесть квадратов и «ещё» стоят одной строкой и
   выровнены по заголовку группы, поэтому в узкой колонке фильтров образец
   мельче базовых 34 px из components.css. */
.filters__group--static .swatches { margin: 10px 0 0 28px; gap: 8px 7px; }
.filters__group--static .filters__note { margin-top: 8px; }
.filters__group--static .swatch { width: 20px; height: 20px; border-width: 1px; }

/* ============================ панель результатов ============================ */
.catalog__toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); flex-wrap: wrap; margin-bottom: var(--s-3);
}
.catalog__found { font-weight: 700; font-size: var(--fs-base); }
.catalog__tools { display: flex; align-items: center; gap: var(--s-3); flex-wrap: wrap; }
.catalog__sort { min-width: 254px; }
/* Кегль не опускаем: 13,5 заставлял iPhone увеличивать каталог при попытке
   сменить сортировку (см. --fs-field в css/tokens.css). Компактность —
   отступами. */
.catalog__sort .select {
  font-weight: 600; line-height: 1.3;
  padding: 6px 34px 6px 12px; border-color: var(--line);
}
/* Переключатель вида в макете — одна светлая плашка из двух половин с тонкой
   перегородкой, без тёмной заливки. Активное состояние показываем мягкой
   подложкой и насыщенностью иконки: тёмный прямоугольник спорил бы с
   единственной тёмной кнопкой страницы — «в корзину». */
.catalog__view { padding: 0; gap: 0; overflow: hidden; border-color: var(--line); }
.catalog__view button {
  padding: 6px 12px; display: inline-flex; min-width: 42px; min-height: 33px;
  align-items: center; justify-content: center; border-radius: 0; color: var(--muted-2);
}
.catalog__view button + button { border-left: 1px solid var(--line); }
.catalog__view button svg { width: 18px; height: 18px; }
.catalog__view button[aria-pressed="true"] { background: var(--bg-2); color: var(--navy); }
/* На тач-экране кнопка без подписи обязана оставаться крупной целью. */
@media (pointer: coarse) {
  .catalog__view button { min-height: 44px; min-width: 46px; }
}

.catalog__chips { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-bottom: var(--s-4); }
.catalog__chips .chip { padding: 6px 12px; font-size: var(--fs-xs); }
.catalog__chips .chip button { font-size: 16px; line-height: 1; padding: 0 0 2px; }

/* ============================ сетка карточек ============================ */
.catalog__grid { display: grid; gap: var(--s-3); grid-template-columns: repeat(3, minmax(0, 1fr)); }
.catalog__grid[data-view="list"] { grid-template-columns: 1fr; }

/* Карточка макета: превью — широкая полоса 9:4 в рамке из 8 px поля, текст и
   кнопки выровнены по её краю. Правила скоупим сеткой каталога: те же
   .product-card живут на посадочных и на карточке товара, у них своя ширина. */
.catalog__grid .product-card { padding: 8px; }
/* Рамка под фотографию: 3:2 — ровно пропорция нарезки (960×640 из
   tools/gen_photos.py), поэтому при object-fit: cover снимок не теряет ни
   неба, ни земли. Полоса 9:4 из макета была рассчитана на векторную схему;
   с фотографии она срезала бы больше половины кадра. Пропорция задана здесь
   для ВСЕХ карточек сетки, и с фото, и с артом, — иначе карточки в ряду
   получились бы разной высоты. */
.catalog__grid .product-card__media { aspect-ratio: 3 / 2; border-radius: var(--radius-xs); }
.catalog__grid .product-card__flags { top: 8px; left: 8px; flex-wrap: wrap; max-width: calc(100% - 16px); }
.catalog__grid .product-card__body { padding: 12px 2px 2px; gap: 9px; }
.catalog__grid .product-card__title { font-size: var(--fs-base); line-height: 1.3; }
.catalog__grid .product-card__tags { gap: 5px; }
.catalog__grid .tag { padding: 4px 8px; font-size: 11.5px; line-height: 1.35; }
.catalog__grid .product-card__price { font-size: 18px; text-align: right; }
.catalog__grid .product-card__actions { grid-template-columns: 1fr 30%; gap: 9px; }

/* Строка «что посчитано». Стоит под ценой во всю ширину карточки, а не в
   колонке цены: в узкую правую колонку она встала бы лесенкой из четырёх
   строк. Отрицательный отступ съедает половину gap колонки тела — подпись
   должна читаться как продолжение цены, а не как отдельный блок. */
.catalog__grid .product-card__basis {
  margin: -5px 0 0; font-size: var(--fs-xs); line-height: 1.35; color: var(--muted);
}


/* --- фотография объекта вместо векторного превью ---
   Размеры и object-fit для самой картинки задаёт .product-card__media img в
   css/components.css. Здесь только <picture>: он инлайновый, и без display
   картинка внутри меряет высоту от строки текста, а не от рамки. */
.catalog__grid .product-card__media picture { display: block; width: 100%; height: 100%; }
/* Плашки лежат на фотографии, а не на ровной подложке: тень отделяет их от
   пёстрого фона — на светлом небе белая «Предварительно» иначе теряется. */
.catalog__grid .product-card__flags .badge { box-shadow: var(--shadow-sm); }

/* В макете подпись «Настроить в 3D» набрана золотом. Берём тёмный оттенок
   золота (--gold-ink): чистый --gold на белом даёт 2,9:1 и не проходит AA. */
.catalog__grid .product-card__actions .btn--outline { color: var(--gold-ink); }
.catalog__grid .product-card__actions .btn--icon { padding: 9px; }

/* Списковый вид: превью слева, характеристики в строку. */
.catalog__grid[data-view="list"] .product-card { flex-direction: row; }
.catalog__grid[data-view="list"] .product-card__media { flex: 0 0 300px; aspect-ratio: auto; }
.catalog__grid[data-view="list"] .product-card__body { padding: 4px var(--s-4); }
.catalog__grid[data-view="list"] .product-card__actions {
  grid-template-columns: auto auto; justify-content: start;
}

/* ============================ панель сравнения ============================ */
.compare {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-drawer);
  background: var(--white); border-top: 1px solid var(--line); box-shadow: var(--shadow-lg);
}
.compare__inner {
  display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap;
  padding-top: var(--s-3); padding-bottom: var(--s-3);
}
.compare__title { font-weight: 700; font-size: var(--fs-sm); }
.compare__items { display: flex; gap: var(--s-2); flex: 1; flex-wrap: wrap; min-width: 0; }
.compare__item {
  display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px;
  border: 1px solid var(--line); border-radius: var(--radius-pill);
  font-size: var(--fs-xs); font-weight: 600; color: var(--ink-2); max-width: 260px;
}
.compare__item span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.compare__item button { background: none; border: 0; cursor: pointer; color: var(--muted); line-height: 1; }
.compare__item button:hover { color: var(--danger); }
.compare__acts { display: flex; gap: var(--s-2); align-items: center; }

/* Условие, которого не выполняет выключенная кнопка «Сравнить». Обычным весом:
   это пояснение к счётчику, а не второй заголовок. */
.compare__need { font-weight: 400; color: var(--muted); }

/* «Свернуть» — 44×44 по цели нажатия: панель липнет к низу экрана, и на
   телефоне промах уводит в карточку под ней. */
.compare__hide {
  width: 44px; height: 44px; flex: none;
  display: grid; place-items: center;
  border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--muted);
  font-size: 22px; line-height: 1; cursor: pointer;
}
.compare__hide:hover { background: var(--bg-2); color: var(--ink); }
.compare__sheet {
  max-height: 52vh; overflow: auto; border-top: 1px solid var(--line);
  padding: var(--s-4) var(--gutter);
}
.compare__sheet table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.compare__sheet th, .compare__sheet td {
  border: 1px solid var(--line); padding: 9px 12px; text-align: left; vertical-align: top;
}
.compare__sheet th { background: var(--bg-2); font-weight: 700; white-space: nowrap; }
.compare__sheet td.is-diff { background: var(--gold-100); }

/* Панель сравнения перекрывает низ страницы — добавляем воздух под контентом. */
.catalog.has-compare { padding-bottom: 88px; }


/* ============================ адаптив ============================ */
@media (max-width: 1120px) {
  .catalog__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .catalog__layout { grid-template-columns: 228px minmax(0, 1fr); gap: var(--s-5); }
}
@media (max-width: 900px) {
  .catalog__layout { grid-template-columns: 1fr; }
  .catalog__aside { position: static; }
  .catalog__filters-toggle { display: inline-flex; margin-bottom: var(--s-3); }
  /* На узком экране панель фильтров раскрывается кнопкой: иначе до карточек
     нужно пролистать экран фильтров. */
  .catalog__filters { display: none; }
  .catalog__aside.is-open .catalog__filters { display: block; }
  .catalog__filters-apply { display: block; width: 100%; margin-top: var(--s-4); }
  .catalog__sort { min-width: 0; flex: 1; }
  .catalog__grid[data-view="list"] .product-card { flex-direction: column; }
  .catalog__grid[data-view="list"] .product-card__media { flex: none; aspect-ratio: 16 / 10; }
}
@media (max-width: 620px) {
  .catalog__grid, .catalog__grid[data-view="list"] { grid-template-columns: 1fr; }
  .catalog__toolbar { align-items: flex-start; }
  .compare__items { display: none; }
}

/* Чипы характеристик. В макете их три и они умещаются в одну строку; у нас
   часть характеристик длиннее («Горизонтальный монтаж»), поэтому чип чуть
   мельче и плотнее — так три штуки садятся в строку почти у всех товаров,
   а карточки в ряду не разъезжаются по высоте. */

/* Образцы RAL в фильтре: в макете это скруглённые квадраты, а не кружки. */
.filters__group--static .swatch { width: 22px; height: 22px; border-radius: 6px; }
