/* es2-cat — раздел каталога (v2.category): layout прототипа (.crumbs .subs .lst .flt .fg .cb .rng
   .tg .tbl .stock .sheet) + перекраска реальной разметки живых сниппетов (esFacets/esQuickLinks/
   esSiblingCats/esCrossSell/es.product-card/esFaqSchema-контент) под токены es2.css.
   Ядро (es2.css) не трогаем — только этот файл, грузится параметром css=cat у es2.head. */

/* ---------- шапка раздела ---------- */
.pg--cat{padding:20px 0 64px}
.cat-h{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap}
.cat-h h1{font-size:34px;line-height:1.15;margin:0}
.cat-h .num{color:var(--muted);font-size:15px;white-space:nowrap}
.cat-intro{color:var(--muted);font-size:15.5px;margin:8px 0 0;max-width:760px}
.es-often__pickup{color:var(--muted);font-size:13.5px;margin:6px 0 0}

/* ---------- подразделы: чипы и плитки ---------- */
.subs{display:flex;flex-wrap:wrap;gap:8px;margin:20px 0 0}
.subs .chip{font-size:14px}
.cat-tiles{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin:20px 0 0}
.cat-tiles .es-tile{padding:10px;gap:6px}
.cat-tiles .es-tile__img,.cat-tiles .es-tile__icon{aspect-ratio:auto;height:96px}
.cat-tiles .es-tile__name{font-size:13px;line-height:1.2}
.cat-tiles .es-tile__meta{font-size:11.5px}
/* 27.09.26 (ревью, /truboprovodnaya-armatura/): 22 крупные плитки растягивали L1 на 2 экрана —
   компактная сетка 6/3/2 + показ первых 12, остальные раскрывает JS (без JS видны все ссылки). */
.cat-tiles--capped>div:nth-child(n+13){display:none}
.cat-tiles__more{display:inline-flex;align-items:center;justify-content:center;min-height:38px;padding:0 18px;margin-top:14px;border-radius:var(--r-pill);background:var(--mist);color:var(--ink);font-size:14px;font-weight:600;border:0;cursor:pointer}
.cat-tiles__more:hover{background:var(--blue-50);color:var(--navy)}
@media (max-width:959px){.cat-tiles{grid-template-columns:repeat(4,1fr)}}
@media (max-width:760px){.cat-tiles{grid-template-columns:repeat(3,1fr)}}
/* 27.09.26 (ревью, 390): 2 плитки в ряд × 12 шт — почти 2 экрана до товаров на мобиле.
   Горизонтальная лента со скроллом (scroll-snap) — компактно по высоте, все 22 ссылки в DOM
   и доступны свайпом; кэп/кнопка "Все подразделы" от JS (1в) на этой ширине снимается. */
@media (max-width:639px){
  .cat-tiles{display:flex;flex-wrap:nowrap;overflow-x:auto;scroll-snap-type:x mandatory;gap:10px;padding-bottom:4px;-webkit-overflow-scrolling:touch}
  .cat-tiles>div{flex:0 0 120px;scroll-snap-align:start}
  .cat-tiles .es-tile{padding:8px;gap:6px}
  .cat-tiles .es-tile__img,.cat-tiles .es-tile__icon{height:72px}
  .cat-tiles .es-tile__name{font-size:12px}
  .cat-tiles .es-tile__meta{font-size:11px}
  .cat-tiles--capped>div:nth-child(n+13){display:block}
  .cat-tiles__more{display:none}
}

/* ---------- каталог: 3×2 сетка разделов (v2.catalog) ---------- */
.cats-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:20px}
@media (max-width:959px){.cats-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:639px){.cats-grid{grid-template-columns:1fr;gap:10px}}
.cats-grid>[data-tilt]{border-radius:var(--r-card)}
.cats-grid .es-tile{height:100%}

/* ---------- раскладка листинга ---------- */
.lst{display:grid;grid-template-columns:260px 1fr;gap:28px;margin-top:28px;align-items:start}
/* 27.09.26 (ревью, 390): грид-трек "1fr" без min-width:0 не сжимается ниже intrinsic-ширины
   содержимого (длинный текст в SELECT сортировки, пагинация и т.п.) — колонка листинга
   растягивалась до ~444px при вьюпорте 390 и обрезалась по правому краю .wrap (html/body
   не скроллились горизонтально благодаря overflow-x:hidden в ядре, поэтому баг был не виден
   через scrollWidth, но контент реально вылезал и обрезался). min-width:0 — стандартный фикс
   переполнения грид-колонки контентом. */
.lst>*{min-width:0}
.flt{display:flex;flex-direction:column;gap:16px;position:sticky;top:96px}
.fg{background:#fff;border-radius:var(--r-card);padding:18px 20px}
.fg h4,.fg .fg-h{font-size:13px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:0 0 12px;font-weight:600}
.fg .fg-h{line-height:1.4}
.fg--sort-m{display:none}
.fg--note a{margin-top:10px}
/* мобиль/планшет: фильтр уходит в шторку (#sheet), сюда его переносит es2-cat.js по клику "Фильтры" —
   правило ниже должно идти ПОСЛЕ базовых .lst/.flt/.fg--sort-m, иначе перебивает их (была живая ошибка
   27.09: .flt показывался поверх ленты на 390 — исправлено переносом media-блока в конец каскада). */
@media (max-width:959px){.lst{grid-template-columns:1fr}.flt{display:none}.fg--sort-m{display:block}}
/* внутри открытой шторки (#sheet-slot) фильтр всегда виден — es2-cat.js переносит #flt туда по клику */
#sheet-slot .flt{display:flex !important;position:static;top:auto}

/* ---------- панель "Фильтры / сортировка" над таблицей ---------- */
.bar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:14px}
.bar .sp{flex:1}
.fbtn{display:none}
@media (max-width:959px){.fbtn{display:none !important}} /* на мобиле открывает липкая нижняя кнопка */
.sel-chips{display:flex;flex-wrap:wrap;gap:8px}
.sel-chips .chip{min-height:30px;padding:0 10px;font-size:13px}
.es-sortbar__links{display:inline-flex;gap:10px;font-size:13.5px}
.es-sortbar__links a{color:var(--muted)}

/* ---------- таблица позиций ---------- */
.tbl{background:#fff;border-radius:var(--r-card);overflow:hidden}
.tbl table{width:100%;border-collapse:collapse}
.tbl th{text-align:left;font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:600;padding:14px 16px;border-bottom:1px solid var(--mist)}
.tbl th.r,.tbl td.num{text-align:right}
.es-td--wide{min-width:260px}
.es-prow{display:flex;align-items:center;gap:12px}
.es-prow__img{flex:none;width:52px;height:40px;border-radius:8px;overflow:hidden;display:block}
.es-prow__img img{width:100%;height:100%;object-fit:cover}
.tbl td{padding:14px 16px;border-bottom:1px solid var(--mist);font-size:15px;vertical-align:middle}
.tbl tbody tr:last-child td{border-bottom:0}
.tbl tbody tr:hover{background:#FAFBFD}
@media (max-width:639px){
  /* 27.09.26 (ревью, 390): было `.tbl table,.tbl thead{display:none}` — display:none на самом
     <table> убирал ВСЮ таблицу из рендера вместе с tbody/tr/td, поэтому карточные display:block/flex
     на потомках ничего не давали — листинг товаров пропадал целиком. Прячем только thead, а table/
     tbody переводим в display:block, чтобы card-layout на tr/td реально показывался. */
  .tbl table{display:block}
  .tbl thead{display:none}
  .tbl tbody{display:block}
  /* 27.09.26 (ревью #2, 390): было ~275px/карточку (подписи "Цена, ₽/шт"/"Наличие" отдельными
     строками + полноразмерная .mb 40×136). Раскладка через grid на <tr>: фото+название/арт (сам
     td.es-td--wide, внутри свой flex) на всю ширину сверху, вторая строка — цена+наличие слева
     (данные из отдельных <td>, кладём рядом через grid-column) и компактная кнопка «В заявку»
     справа (justify-self:end). Подписи data-label для цены/наличия скрываем — цена жирная и
     зелёная точка у наличия сами по себе читаемы без подписи (методика Леманы: карточка
     компактнее нужнее подписи на мобиле). Цель ≤150px/карточку. */
  .tbl tbody tr{
    display:grid;grid-template-columns:auto auto 1fr auto;align-items:center;
    column-gap:8px;row-gap:6px;padding:12px 16px;border-bottom:1px solid var(--mist)
  }
  .tbl tbody tr td{display:block;padding:0;border:0}
  .tbl tbody tr td.es-td--wide{grid-column:1/-1}
  .tbl tbody tr td[data-label="Цена, ₽/шт"]{grid-row:2;grid-column:1;font-size:15px}
  .tbl tbody tr td[data-label="Наличие"]{grid-row:2;grid-column:2;font-size:12.5px}
  .tbl tbody tr td[data-label=""]{grid-row:2;grid-column:4;justify-self:end}
  /* без подписей "Цена, ₽/шт" / "Наличие" — жирная цена и точка-индикатор наличия достаточны */
  .tbl tbody tr td[data-label]::before{content:none}
  .tbl .es-prow{align-items:flex-start}
  .tbl .es-prow__img{width:64px;height:48px}
  .tbl .es-table__name{display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;font-size:14px;line-height:1.3}
  .tbl .es-table__sub{font-size:12px;margin-top:2px}
  /* «Подробнее» и так скрыта на мобиле классом uk-visible@m (живой es.product-card.tpl) —
     компактная .mb справа вместо полноразмерной 40×136. */
  .tbl tbody tr .mb{height:32px;width:auto;min-width:96px;padding:0 14px;font-size:13px;border-radius:16px}
}

/* ---------- M1 (этап 10, 28.09.2026): нишевые колонки таблицы (характеристики/бренд) ---------- */
.es-td--spec,.es-td--brand,.es-th--spec,.es-th--brand{white-space:nowrap}
.tbl.is-hide-spec .es-td--spec,.tbl.is-hide-spec .es-th--spec,
.tbl.is-hide-brand .es-td--brand,.tbl.is-hide-brand .es-th--brand{display:none}
@media (max-width:639px){.es-td--spec,.es-td--brand,.es-th--spec,.es-th--brand{display:none}}

/* ---------- M1: тумблер "Только в наличии" в панели фильтров ---------- */
.bar .tg{margin-left:2px}
@media (max-width:639px){.bar .tg{order:3;width:100%}}
.tbl tbody tr.is-hidden-instock{display:none}

/* ---------- M1: «Показать ещё N из M» (AJAX) ---------- */
#cat-pagewrap.is-ajax{display:none}
.more-b{display:flex;justify-content:center;margin-top:20px}
.more-b .btn{min-width:220px}
.more-b.is-loading .btn{opacity:.6;pointer-events:none}
/* строки, дописанные AJAX-подгрузкой — появление снизу, только transform/opacity */
.tbl tbody tr.es-row-in{opacity:0;transform:translateY(10px)}
.tbl tbody tr.es-row-in.es-row-go{opacity:1;transform:translateY(0);transition:opacity .38s var(--ease),transform .38s var(--ease)}
html.rm .tbl tbody tr.es-row-in{opacity:1;transform:none;transition:none}

/* ---------- M1: пустое состояние листинга ---------- */
.empty{background:#fff;border-radius:var(--r-card);padding:32px 24px;text-align:center;color:var(--muted);font-size:15px;line-height:1.5}
.empty a{color:var(--blue);font-weight:600}
.empty a:hover{color:var(--blue-hi)}

/* ---------- M1: визуальный двухползунковый слайдер поверх первого числового es-range (esFacets.php
   отдельного ценового фасета не отдаёт — есть только сортировка по цене; слайдер enhance'ит реальный
   числовой фильтр раздела, какой есть в разметке). esFacets.php не трогаем — просто вставляем
   трек+ручки перед его инпутами и синхронизируем. ---------- */
.es-range{position:relative;display:flex;flex-wrap:wrap;gap:8px;align-items:center}
.rng-v{display:flex;justify-content:space-between;width:100%;font-size:14px;font-weight:600;margin-bottom:2px;color:var(--ink)}
.rng{position:relative;width:100%;height:28px;touch-action:none;cursor:pointer;margin-bottom:4px}
.rng .tr{position:absolute;left:0;right:0;top:12px;height:4px;border-radius:2px;background:var(--mist)}
.rng .fi{position:absolute;top:12px;height:4px;border-radius:2px;background:var(--navy)}
.rng .kn{position:absolute;top:4px;width:20px;height:20px;margin-left:-10px;border-radius:10px;background:#fff;
  box-shadow:0 0 0 1.5px var(--navy),0 2px 6px rgba(11,37,64,.2);cursor:grab}
.rng .kn:active{cursor:grabbing}
.rng .kn:focus-visible{outline:3px solid var(--light);outline-offset:2px}
/* быстрые чипы диапазонов цены — вычисляются из реальных min/max (placeholder полей es-range) */
.pr-chips{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 2px}
.pr-chips .chip{font-size:12.5px;min-height:26px;padding:0 10px}

/* ---------- пагинация ---------- */
.pg-nav{display:flex;justify-content:center;flex-wrap:wrap;gap:6px;margin-top:24px;list-style:none;padding:0}
.pg-nav li a,.pg-nav li span{display:flex;align-items:center;justify-content:center;min-width:36px;height:36px;padding:0 8px;border-radius:var(--r-pill);color:var(--ink);box-shadow:inset 0 0 0 1px var(--line);font-size:14px}
.pg-nav li.on span{background:var(--navy);color:#fff;box-shadow:none}
.pg-nav li.skip span{box-shadow:none;color:var(--muted)}
@media (max-width:639px){.pg-nav{gap:4px}.pg-nav li a,.pg-nav li span{min-width:30px;height:30px;padding:0 6px;font-size:13px}}

/* ---------- фасеты esFacets.php (перекраска реальной разметки сниппета) ---------- */
.flt .es-filter{background:none;padding:0;margin:0}
.es-filter__title{font-size:13px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);font-weight:600;margin:0 0 12px}
.es-filter--head .es-filter__title{margin-bottom:6px}
.es-filter__found{color:var(--muted);font-size:13.5px;margin:0 0 12px}
.es-chips{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 14px}
.es-chip{font-size:13px;min-height:30px;padding:0 10px 0 12px}
.es-chip--reset{background:none;box-shadow:inset 0 0 0 1px var(--line);color:var(--muted)}
.es-chip--reset:hover{box-shadow:inset 0 0 0 1px var(--navy);color:var(--ink)}
.es-input{width:100%;height:38px;border-radius:var(--r-pill);border:0;box-shadow:inset 0 0 0 1px var(--line);padding:0 14px;font-size:14px;background:#fff}
.es-input:focus{outline:2px solid var(--blue-50);outline-offset:1px}
.es-filter__search{margin-bottom:10px}
.es-range{display:flex;align-items:center;gap:8px;margin-top:4px}
.es-range .es-input{height:36px;font-size:13.5px;text-align:center}
.es-range__ok{flex:none;height:36px;padding:0 14px;border-radius:var(--r-pill);background:var(--navy);color:#fff;font-size:13.5px;font-weight:600;border:0}
.es-facet-list{margin-bottom:16px}
.es-facet-list:last-child{margin-bottom:0}
.es-facet-more summary{cursor:pointer;color:var(--blue);font-size:13.5px;padding:4px 0;list-style:none}
.es-facet-more summary::-webkit-details-marker{display:none}

/* ---------- часто ищут (этап 5.4) ---------- */
.es-often{background:#fff;border-radius:var(--r-card);padding:20px;margin:24px 0}
/* 27.09.26 (ревью, 390): убрали <details>/<summary> (es2.oftensearch.php) — «Часто ищут» теперь
   всегда видимая строка чипов, не аккордеон, ни на 1440, ни на 390. */
.es-often__title{margin:0 0 14px;font-weight:600;color:var(--navy);display:flex;align-items:center;gap:8px}
.es-often__cnt{color:var(--muted);font-weight:500;font-size:13.5px}
.es-often__list{display:flex;flex-wrap:wrap;gap:8px;list-style:none;margin:0;padding:0}
.es-often__link{display:inline-flex;align-items:center;min-height:34px;padding:0 14px;border-radius:var(--r-pill);background:var(--mist);color:var(--ink);font-size:14px;white-space:nowrap}
.es-often__link:hover{background:var(--blue-50);color:var(--navy)}
.es-often__stats{font-size:13.5px;margin:16px 0 0}
.es-often__where h4,.es-often__where .fg-h{font-size:15px;margin:0 0 10px;color:var(--navy)}
.es-often__where p{margin:4px 0}
@media (max-width:639px){
  /* лента чипов со скроллом вместо переноса — короче по высоте, все ссылки в DOM */
  .es-often__list{flex-wrap:nowrap;overflow-x:auto;padding-bottom:4px;-webkit-overflow-scrolling:touch}
  .es-often__link{flex:0 0 auto}
}

/* ---------- SEO-текст / esQuickLinks / esSiblingCats / esCrossSell ---------- */
.es-seo{color:var(--ink);font-size:15px;line-height:1.65}
.es-seo h2,.es-quicklinks__title{font-size:22px;margin:32px 0 14px}
.es-quicklinks{margin:28px 0}
/* 27.09.26 (ревью, /truboprovodnaya-armatura/): 3 колонки auto-fill растягивали блок чипов-фасетов
   до ~1600px по высоте (до 12 ссылок в группе). esQuickLinks.php уже умеет maxPerGroup (передаём 8
   из category.tpl, логику сниппета не трогаем) — здесь просто плотнее сетка на 1440. */
.es-quicklinks__groups{display:grid;grid-template-columns:repeat(4,1fr);gap:20px}
@media (max-width:959px){.es-quicklinks__groups{grid-template-columns:repeat(2,1fr)}}
@media (max-width:639px){.es-quicklinks__groups{grid-template-columns:1fr;gap:14px}}
.es-quicklinks__label{font-size:13px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);font-weight:600;margin:0 0 8px}
/* 27.09.26 (ревью, 390): было flex-direction:column — каждая группа превращалась в длинный
   вертикальный столбик (до 8 строк × ~11 групп), на мобиле с 1 колонкой это огромный блок.
   Чипы с переносом строк — короче в разы, при этом свои ссылки/счётчики не теряются (SEO). */
.es-quicklinks__list{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:8px}
.es-quicklinks__link{display:inline-flex;align-items:center;gap:5px;padding:6px 12px;border-radius:var(--r-pill);background:var(--mist);color:var(--ink);font-size:13.5px}
.es-quicklinks__link:hover{background:var(--blue-50);color:var(--navy)}
.es-quicklinks__link.is-current{color:var(--muted);font-weight:600}
.es-quicklinks__count,.es-quicklinks__cnt{color:var(--muted);font-size:12px}
.es-quicklinks__more summary{cursor:pointer;color:var(--blue);font-size:13.5px;list-style:none;margin-top:6px}
.es-quicklinks__more summary::-webkit-details-marker{display:none}
/* сворачивание группы в <details> на ≤640 — добавляет es2-cat.js (класс es-quicklinks__fold),
   без JS группа остаётся открытым чип-списком (ссылки доступны). */
.es-quicklinks__fold>summary{cursor:pointer;list-style:none;font-size:13px;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);font-weight:600;margin:0 0 8px;display:flex;align-items:center;gap:6px}
.es-quicklinks__fold>summary::-webkit-details-marker{display:none}
.es-quicklinks__fold>summary::after{content:'';width:7px;height:7px;border-right:2px solid var(--muted);border-bottom:2px solid var(--muted);transform:rotate(-45deg);margin-left:auto}
.es-quicklinks__fold[open]>summary::after{transform:rotate(45deg)}
.es-crosssell .es-quicklinks__list{flex-direction:row;flex-wrap:wrap;gap:8px}
.es-crosssell .es-quicklinks__link{background:var(--mist);border-radius:var(--r-pill);padding:6px 14px}

/* ---------- FAQ (контент резюме + esFaqSchema) ---------- */
.es-faq__item{background:#fff;border-radius:var(--r-card);margin:0 0 8px;overflow:hidden}
.es-faq__item>summary{padding:18px 22px;font-weight:600;color:var(--navy);cursor:pointer;list-style:none}
.es-faq__item>summary::-webkit-details-marker{display:none}
.es-faq__a{padding:0 22px 20px;color:var(--muted);font-size:14.5px}

/* ---------- плавающая кнопка "Показать N" от app.js (GAP3) — токены v2 поверх theme.css ----------
   27.09.26 (ревью, /truboprovodnaya-armatura/ 1440): координатор увидел плашку «Показать ×» без
   числа между плитками подразделов, хотя фильтр не трогали. Проверка через Playwright bounding-box
   в реальном вьюпорте показала, что .es-apply на самом деле корректно смещена за экран
   (transform: translate(-50%,140%) из live theme.css, is-open добавляет app.js только при dirty-
   фасете) — это, вероятнее всего, артефакт составного full-page-скрина Chromium с fixed-элементами
   (компонуется один раз в начальной позиции вьюпорта, а не переклипается по всей склеенной высоте).
   На случай если это не только артефакт скрина, жёстко скрываем плашку по умолчанию своим CSS —
   app.js (не трогаем) всё равно переключает .is-open по факту изменения фасета. */
.es-apply{display:none}
.es-apply.is-open{display:flex}
.es-apply__btn{border-radius:var(--r-pill) !important;background:var(--blue) !important;box-shadow:0 10px 24px -10px rgba(11,37,64,.5) !important}
.es-apply__reset{box-shadow:0 4px 14px rgba(11,37,64,.18) !important}

/* ---------- липкая нижняя панель фильтра (мобиле) ---------- */
.mobile-filterbar{display:none;position:fixed;left:0;right:0;bottom:0;z-index:70;padding:10px 16px calc(10px + env(safe-area-inset-bottom));background:linear-gradient(180deg,rgba(255,255,255,0),#fff 30%)}
@media (max-width:959px){.mobile-filterbar{display:block}}
