/* ============================================================
   VisArtis — каталог: дерево разделов слева (280px), выдача
   справа. Название раздела и подбор (сортировка, цена, способ
   покупки, местонахождение) стоят одной строкой над лотами.
   На узких экранах дерево превращается в шторку по кнопке
   «Разделы». Всё поверх base.css, только страничное.

   Канон — главная (ЗАКОН v1.0): белое плоское полотно,
   карточка .mcard, кегли из девяти ступеней, скругления
   2 / 6 / 8 / 10 / 17 / 50%.
   ============================================================ */

/* Полотно, карточка выдачи, кнопки, бейджи и высота шапки живут
   в base.css: здесь только то, чего нет больше нигде. */

.catalog { padding-top: var(--s3); }

/* --- Хлебная крошка --- */
.crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  min-height: 24px;
  font-size: 13.5px; color: var(--ink-2);
}
.crumbs a:hover { color: var(--accent); }
.crumbs .sep { color: var(--ink-3); }
.crumbs .here { color: var(--ink-black); }

/* --- Двухколоночная раскладка --- */
.catalog-layout {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  gap: var(--s6);
  align-items: start;
  margin-top: var(--s3);
}

/* --- Панель разделов --- */
.facets {
  position: sticky; top: calc(var(--header-h) + var(--s3));
  max-height: calc(100vh - var(--header-h) - var(--s5));
  overflow-y: auto;
  scrollbar-width: thin;
  padding-right: 6px;
}
/* Шапка панели нужна только шторке: на широком экране в ней нечему быть —
   надписи «Фильтры» больше нет, а крестик закрывает только шторку. */
.facets__head { display: none; }
.facets__close {
  border: 0; background: none; padding: 8px;
  font-size: 16px; line-height: 1; color: var(--ink-2);
}
.facets__close:hover { color: var(--accent); }
.facets__apply { display: none; }

.facet { border-top: 1px solid var(--line); padding: var(--s2) 0; }
.facet__title {
  margin: 0 0 10px;
  font-family: var(--sans); font-weight: 500;
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--ink-2);
}
.facet ul { list-style: none; margin: 0; padding: 0; }

.facet-row {
  display: flex; width: 100%; align-items: baseline;
  gap: 10px;
  border: 0; background: none; text-align: left;
  padding: 6px 0;
  font-size: 15px; line-height: 1.4; color: var(--ink-2);
  transition: color .2s var(--ease);
}
.facet-row:hover { color: var(--accent); }
.facet-row.is-active { color: var(--ink-black); font-weight: 600; }

/* ---------- Уровни дерева каталога ----------
   Уровень читается тремя признаками сразу: кеглем, насыщенностью и
   отступом. Одного мало — на скриншоте заказчика отступ был, а список
   всё равно выглядел плоским.

   Вертикальной направляющей у подуровней больше нет: заказчица пишет,
   что линия режет глаз. Отступ её заменяет — и он же теперь разный на
   втором и третьем уровнях, иначе полки стояли с отделами в одну линию. */

/* Уровень 1 — раздел каталога: крупнее, темнее, с воздухом между строками. */
.facet-tree > li > .facet-row {
  font-size: 15px; font-weight: 500; color: var(--ink-black);
  padding: 8px 0;
}
.facet-tree > li + li > .facet-row { border-top: 1px solid var(--line); }

/* Уровень 2 — отдел: мельче и тише.
   Селектор нарочно начинается с .facet: сброс `.facet ul { padding: 0 }`
   выше по файлу весит (0,1,1) и до сих пор съедал отступ подуровней —
   держался один лишь бордюр. Из-за этого полки и стояли с отделами в
   одну линию. Два класса весят (0,2,0) и перебивают сброс. */
.facet .facet-tree__sub {
  margin: 2px 0 10px;
  padding-left: 14px;
}
.facet-tree__sub > li > .facet-row {
  font-size: 14px; font-weight: 400; color: var(--ink-2);
  padding: 5px 0;
}

/* Уровень 3 — полка: ещё мельче и с собственным отступом поверх
   отступа второго уровня (14 + 20 = 34px от края панели). */
.facet .facet-tree__sub .facet-tree__sub {
  margin: 2px 0 6px;
  padding-left: 20px;
}
.facet-tree__sub .facet-tree__sub > li > .facet-row {
  font-size: 13px; color: var(--ink-3); padding: 4px 0;
}

/* Выбранная строка чернеет на любом уровне: это её единственная роль,
   и она не должна спорить с иерархией. */
.facet-row.is-active { color: var(--ink-black); font-weight: 600; }

/* ---------- Строка над выдачей: название раздела + подбор ----------
   Сетка, а не гибкая строка с переносом. Прошлая раскладка роняла подбор
   вниз на ЛЮБОМ экране: колонке выдачи достаётся максимум 992px, подбор
   просил 675px, а левая половина вместе со строкой подписки набирала
   577–857px — сумма не влезала никогда.
   Теперь колонок ровно две: слева название, справа подбор своей
   естественной ширины. Тесно — название переносится по словам, а подбор
   отдаёт лишние пиксели. Подписка ушла отдельным рядом под названием. */
/* Раскладка по эскизу заказчицы:

       Живопись, графика            + Подписаться на новые лоты
       Разделы                      Выбор кураторов   от – до

   Первая строка — имя раздела и подписка, вторая — подбор. Прежде подписка
   стояла отдельной строкой ПОД заголовком: длинная подпись («…в разделе
   «Драгоценности, камни и украшения»») раздувала левую колонку, и подбор не
   помещался рядом. Подпись сокращена до «Подписаться на новые лоты» —
   название раздела стоит рядом в заголовке, повторять его незачем, — и
   строка снова умещается справа от имени. */
.results__head {
  display: grid;
  /* Левая колонка никогда не уже самого длинного слова названия
     (min-content). Без этого пола «Драгоценности, камни и украшения»
     ломались посреди слова: колонке доставалось 143px при слове в 212px.
     Не хватает места — уступает подписка, а не заголовок. */
  grid-template-columns: minmax(min-content, 1fr) auto;
  grid-template-areas:
    "title   sub"
    "filters filters";
  /* start, а не center: так верх названия и верх подписки стоят на одной
     координате ровно, без разъезда в пару пикселей. */
  align-items: start;
  gap: 10px var(--s3);
  margin-bottom: var(--s3);
}
.results__head h1 {
  grid-area: title;
  margin: 0;
  /* Кегль пружинит: на 1280px колонка уже, и постоянные 34px гнали
     длинные названия («Ювелирные украшения») в три строки. */
  font-size: clamp(27px, 2.2vw, 34px); line-height: 1.15;
  overflow-wrap: break-word;
}
/* Подбор занимает всю ширину: слева «Разделы», справа — сортировка, цена,
   способ покупки и город, как на эскизе. */
.results__head .filters { grid-area: filters; width: 100%; }
.results__head .filters .btn--tree { margin-right: auto; }

/* Подписка на новые лоты раздела: тихая строка под названием, а не
   кнопка-акцент — она не должна спорить с заголовком. justify-self
   обязателен: иначе кнопка растянулась бы на обе колонки сетки и
   ловила бы нажатия там, где для человека пусто. */
.cat-sub {
  grid-area: sub; justify-self: end; max-width: 100%;
  border: 0; background: none; padding: 2px 0;
  text-align: right; white-space: nowrap;
  font-size: 13.5px; line-height: 1.45; color: var(--ink-2);
  transition: color .2s var(--ease);
}
.cat-sub[hidden] { display: none; }
.cat-sub:hover { color: var(--accent); }
.cat-sub__plus { margin-right: 5px; }
.cat-sub.is-on { color: var(--ink-black); }
.cat-sub.is-on:hover { color: var(--ink-black); }
.cat-sub__off {
  margin-left: 8px; color: var(--ink-3);
  border-bottom: 1px dashed var(--line-strong);
}
.cat-sub.is-on:hover .cat-sub__off {
  color: var(--warn); border-bottom-color: currentColor;
}

/* Подбор: контролы стоят в одну строку и НЕ переносятся — перенос внутри
   подбора немедленно уводит весь блок под название. Ширины заданы явно и
   считаны под самый длинный пункт каждого списка. */
.filters {
  display: flex; flex-wrap: nowrap; align-items: center;
  gap: 12px;
  min-width: 0;
}
.filters__f { display: flex; align-items: center; min-width: 0; flex: 0 1 auto; }
.filters__f[hidden] { display: none; }
/* Фон задаём ТОЛЬКО background-color: сокращение background стирает
   шеврон, который base.css рисует фоновой картинкой. Раньше из-за этого
   в файле жил самодельный шеврон на ::after — он больше не нужен. */
.filters select,
.price-range input {
  background-color: var(--page-white);
  max-width: 100%;
  font-size: 14px;
}
/* Ширины считаны под самый длинный пункт каждого списка при 14px Inter:
   «Скоро завершатся» 128px, «Купить сейчас» 100px, «Санкт-Петербург»
   119px — плюс 14px поля слева и 34px под шеврон.
   Селекторы по классу, а не по id: на узком экране ширину контролов
   перебивает медиазапрос, а id он бы не перевесил. */
.filters__f select { width: 100%; min-width: 0; }
/* Сортировка не сжимается вовсе: её собственная надпись самая длинная в
   строке, и при сжатии обрезалась бы первой. */
.filters__f--sort { width: 180px; flex-shrink: 0; }
.filters__f--sale { width: 152px; }
.filters__f--loc { width: 172px; }

/* Цена уступает место первой (сжимается вчетверо охотнее селектов): у неё
   внутри числа, они не пропадают и доскроллятся, а у селекта обрезалось бы
   имя фильтра — единственная надпись, по которой его узнают. */
.price-range { display: flex; align-items: center; gap: 6px; min-width: 0; flex-shrink: 4; }
.price-range input { width: 72px; min-width: 40px; padding: 0 10px; }
.price-range__dash { color: var(--ink-3); }
/* Знак рубля вместо подписи «Цена, ₽» над полями: два поля с «от» и «до»
   сами по себе не говорят, что в них деньги. */
.price-range__cur { color: var(--ink-2); font-size: 14px; }

.btn--tree { display: none; }

/* --- Чипы применённых условий: отдельной строкой под подбором --- */
.chips {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  margin-bottom: var(--s3);
}
.chips:empty { display: none; }
.chip {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--line-strong); border-radius: var(--r-control);
  background: var(--page-white); color: var(--ink-black);
  padding: 6px 12px;
  font-size: 13.5px; line-height: 1.3;
  transition: border-color .2s var(--ease), color .2s;
}
.chip:hover { border-color: var(--accent); color: var(--accent); }
.chip__x { color: var(--ink-3); font-size: 13.5px; line-height: 1; }
.chip:hover .chip__x { color: var(--warn); }
.chips__clear {
  border: 0; background: none; padding: 6px 4px;
  font-size: 13.5px; color: var(--ink-2);
}
.chips__clear:hover { color: var(--accent); }

/* Карточка выдачи — канон .mcard из base.css, страница её не
   переопределяет: одна карточка на весь сайт. */

/* --- «Показать ещё» --- */
.results__more { margin-top: var(--s4); text-align: center; }
.results__more p { margin: 0 0 12px; font-size: 13.5px; color: var(--ink-2); }

/* --- Пустая выдача и ошибки --- */
.empty {
  grid-column: 1 / -1;
  border: 1px solid var(--line); border-radius: var(--r-panel);
  background: var(--surface-1);
  padding: var(--s8) var(--s3);
  text-align: center;
}
.empty__title {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(22px, 2.4vw, 27px); line-height: 1.2;
  margin: 0 0 8px; text-wrap: balance;
}
.empty > .muted { margin: 0 auto; max-width: 46ch; font-size: 16px; }
.empty__actions {
  display: flex; flex-wrap: wrap; gap: 12px; justify-content: center;
  margin-top: var(--s3);
}
.empty__soon { margin: var(--s2) auto 0; max-width: 46ch; font-size: 13.5px; }

/* --- Скелетоны выдачи --- */
.sk-card .sk-photo { aspect-ratio: 4 / 5; margin-bottom: 12px; border-radius: var(--r-photo); }
.sk-card .sk-line { height: 13px; margin-bottom: 8px; }
.sk-card .sk-line--short { width: 55%; }

/* --- Подбор уезжает под название --- */
/* Ниже 1200px колонке выдачи остаётся меньше 800px: подбор рядом с
   названием пришлось бы обрезать по буквам. Уводим его под название
   целиком — отдельной строкой во всю ширину. */
@media (max-width: 1200px) {
  .results__head {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "title" "sub" "filters";
  }
  /* В одну колонку подписка снова становится строкой под названием и
     выравнивается по левому краю — прижимать её вправо, когда над ней
     заголовок во всю ширину, значит оставить посреди строки пустоту. */
  .results__head .cat-sub {
    justify-self: start; text-align: left; white-space: normal;
  }
  .results__head .filters { margin-top: 10px; }
}

/* --- Мобильная шторка с деревом разделов --- */
@media (max-width: 1000px) {
  .catalog-layout { display: block; margin-top: var(--s3); }
  .btn--tree { display: inline-flex; min-height: 44px; padding: 0 16px; font-size: 15px; }

  /* В строку подбора встаёт пятый элемент — кнопка «Разделы»; на планшете
     ей уже тесно, поэтому строке разрешён перенос. */
  .results__head .filters { flex-wrap: wrap; }

  .facets {
    position: fixed; z-index: 120; top: 0; left: 0; bottom: 0;
    width: min(340px, 88vw); max-height: none;
    display: flex; flex-direction: column;
    background: var(--page-white);
    border-right: 1px solid var(--line);
    padding: var(--s2) var(--s3);
    transform: translateX(-103%);
    transition: transform .3s var(--ease), visibility .3s;
    visibility: hidden;
  }
  .facets.is-open { transform: none; visibility: visible; box-shadow: var(--shadow-pop); }
  /* В шторке шапка появляется ради крестика и прижимает его вправо. */
  .facets__head {
    display: flex; align-items: center; justify-content: flex-end;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--line);
  }
  #facetsBody { flex: 1 1 auto; overflow-y: auto; }
  .facets__apply {
    display: block;
    padding-top: var(--s2);
    border-top: 1px solid var(--line);
  }
  .facets__apply .btn { width: 100%; }

  .facets-backdrop {
    position: fixed; inset: 0; z-index: 110;
    background: rgba(20, 20, 20, .38);
  }
}

/* Узкий экран: строка подбора сворачивается в аккуратный блок из двух
   колонок. min-width: 0 и width: 100% обязательны — у body стоит
   overflow-x: clip, и вылезший селект не дал бы прокрутки, а просто
   обрезался бы по краю: выглядело бы как пропавший фильтр. */
@media (max-width: 620px) {
  .filters { display: grid; grid-template-columns: 1fr 1fr; gap: 12px var(--s2); }
  /* Сортировка и цена занимают всю ширину блока: у сортировки длинные
     подписи опций, а у цены два поля — в половине строки их обрезало бы. */
  .filters .btn--tree,
  .filters__f--sort,
  .filters__f--price { grid-column: 1 / -1; }
  .filters .btn--tree { justify-content: center; }
  /* Настольные ширины контролов снимаем целиком: в сетке колонку задаёт
     она сама. Правило стоит ПОСЛЕ них в файле и потому перевешивает при
     равной значимости. */
  .filters__f { width: auto; }
  .filters select { width: 100%; min-width: 0; }
  .price-range input { flex: 1 1 0; width: auto; min-width: 0; }
}

/* Совсем узкий экран: две колонки уже не дают контролу показать текст. */
@media (max-width: 430px) {
  .filters { grid-template-columns: 1fr; }
}

body.no-scroll { overflow: hidden; }

/* ---------- Вводный текст зала ----------
   Под сеткой предметов: сначала товар, потом объяснение. Ширина строки
   ограничена — длинный абзац в полную ширину каталога не читается. */
.hall-intro {
  margin-top: var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
  max-width: 68ch;
}
.hall-intro h2 {
  margin: 0 0 var(--s2);
  font-family: var(--serif);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.hall-intro p { margin: 0; color: var(--ink-2); line-height: 1.65; }

@media (max-width: 720px) {
  .hall-intro { margin-top: var(--s4); }
  .hall-intro h2 { font-size: 18px; }
}
