:root{--navy:#05152e;--card:#0b2852;--line:#225185;--blue:#0d82f7;--cyan:#45bbff;--green:#31d889;--white:#f5f8ff;--muted:#9cb1ce;--max:1240px}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:var(--navy);color:var(--white);font-family:Inter,Arial,sans-serif;line-height:1.5;overflow-x:hidden}a{color:inherit;text-decoration:none}button,input{font:inherit}img{display:block;max-width:100%;height:auto}.grid-bg{background-image:linear-gradient(rgba(66,184,255,.045) 1px,transparent 1px),linear-gradient(90deg,rgba(66,184,255,.045) 1px,transparent 1px);background-size:52px 52px}.section{width:min(var(--max),calc(100% - 56px));margin:auto;padding:105px 0}.header{height:82px;padding:0 max(28px,calc((100vw - var(--max))/2 + 28px));display:flex;align-items:center;gap:34px;border-bottom:1px solid rgba(112,166,226,.16);position:sticky;top:0;z-index:50;background:rgba(5,21,46,.88);backdrop-filter:blur(20px)}.brand img{width:145px;height:48px;object-fit:contain}.phone{font-weight:900}.menu-button{display:none}.eyebrow{display:block;color:var(--cyan);font-size:11px;font-weight:900;letter-spacing:.18em;text-transform:uppercase}
.hero-punch{margin:14px 0 0;max-width:600px;font-size:clamp(17px,2vw,22px);font-weight:800;line-height:1.32;letter-spacing:-.01em;color:#eaf2ff}
.hero-punch b{color:#fff}
.hero-punch em{font-style:normal;color:var(--cyan)}.button{display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--line);border-radius:999px;padding:15px 22px;color:#fff;background:transparent;font-weight:800;cursor:pointer;transition:.25s}.button:hover{transform:translateY(-2px)}.button.primary{border-color:transparent;background:linear-gradient(110deg,#087cff,#31a9ff);box-shadow:0 15px 40px rgba(7,124,255,.25)}.chem-hero{min-height:min(calc(100vh - 82px),760px);padding:70px max(28px,calc((100vw - var(--max))/2 + 28px));display:grid;grid-template-columns:1fr 1fr;align-items:center;gap:35px}
/* Между чипами и плашкой статистики было ~117px пустоты — большую часть
   даёт нижний паддинг героя, унаследованный от версии с более длинным
   абзацем. Отдельное правило той же специфичности и позже по файлу почему-то
   не перебивало исходное (воспроизводимо, не нашёл причины) — !important
   не по любви к нему, а потому что каскад here вёл себя не по спеке. */
.chem-hero{padding-bottom:24px!important}.hero-copy h1{font-size:clamp(52px,6.3vw,91px);line-height:.93;letter-spacing:-.06em;margin:21px 0}.hero-copy h1 em{color:rgba(111,196,255,.6);font-style:normal}.hero-copy>p{max-width:620px;color:var(--muted);font-size:19px}.hero-actions{display:flex;gap:12px;margin:33px 0}.hero-trust{display:flex;gap:8px;flex-wrap:wrap}.hero-trust span{padding:7px 10px;border:1px solid #285587;border-radius:999px;color:#9eb3cf;font-size:10px}.hero-visual{position:relative;min-height:620px;display:grid;place-items:center}.hero-visual>img{position:absolute;z-index:1;right:-8%;bottom:0;width:90%;height:74%;object-fit:contain;filter:drop-shadow(0 35px 50px rgba(0,0,0,.45))}.hero-ring{position:absolute;width:480px;height:480px;border:1px solid rgba(69,187,255,.25);border-radius:50%;box-shadow:inset 0 0 100px rgba(0,122,255,.08),0 0 120px rgba(0,122,255,.08)}.hero-ring:before,.hero-ring:after{content:"";position:absolute;inset:15%;border:inherit;border-radius:inherit}.hero-ring:after{inset:31%}.hero-pack,.packshot{position:absolute;z-index:2;width:145px;height:205px;padding:35px 15px 15px;border-radius:18px 18px 22px 22px;color:#fff;box-shadow:0 28px 45px rgba(0,0,0,.34);transform:rotate(-5deg);overflow:hidden}.hero-pack:before,.packshot:before{content:"";position:absolute;left:29px;top:-4px;width:72px;height:28px;border:9px solid rgba(255,255,255,.24);border-bottom:0;border-radius:13px 13px 0 0}.hero-pack:after,.packshot:after{content:"";position:absolute;inset:66px 12px 15px;border-radius:12px;background:rgba(245,249,255,.92);box-shadow:inset 0 0 0 1px rgba(10,51,99,.12)}.hero-pack span,.hero-pack b,.hero-pack small{position:relative;z-index:1;display:block}.hero-pack span{font-size:10px;font-weight:900;letter-spacing:.12em}.hero-pack b{margin-top:39px;color:#09234a;font-size:19px;line-height:1}.hero-pack small{margin-top:26px;color:#2587df;font-weight:900}.pack-blue{left:7%;bottom:18%;background:linear-gradient(150deg,#073c80,#087df2)}.pack-cyan{right:2%;top:14%;background:linear-gradient(150deg,#06678a,#25c9e9);transform:rotate(7deg) scale(.83)}.bubble{position:absolute;z-index:3;border-radius:50%;background:radial-gradient(circle at 30% 25%,#9beaff,#1da9f5 45%,#0566d3);box-shadow:inset -10px -12px 20px rgba(0,42,117,.25),0 18px 35px rgba(0,85,190,.22);animation:bubble 5s ease-in-out infinite}.bubble-a{width:70px;height:70px;left:3%;top:22%}.bubble-b{width:34px;height:34px;right:12%;bottom:15%;animation-delay:-2s}.bubble-c{width:18px;height:18px;left:34%;top:11%;animation-delay:-3s}.chem-stats{padding:28px 0;display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--line);border-radius:22px;background:#09234a}.chem-stats article{display:flex;gap:16px;align-items:center;padding:18px 25px;border-right:1px solid var(--line)}.chem-stats article:last-child{border:0}.chem-stats strong{font-size:44px;line-height:1}.chem-stats strong small{font-size:18px;color:var(--cyan)}.chem-stats span{color:#9cb1ce;font-size:12px}.section-heading{display:flex;align-items:end;justify-content:space-between;gap:40px;margin-bottom:35px}.section-heading h2,.usage h2,.quality h2{margin:11px 0 0;font-size:clamp(42px,5vw,67px);line-height:.98;letter-spacing:-.05em}.section-heading>p{max-width:420px;color:var(--muted)}.filter-row{display:flex;gap:8px;overflow:auto;margin-bottom:22px;padding-bottom:5px;scrollbar-width:none}.filter{white-space:nowrap;border:1px solid var(--line);border-radius:999px;padding:10px 16px;background:#081f43;color:#a8bdd9;font-weight:800;cursor:pointer}.filter span{margin-left:6px;color:var(--cyan)}.filter.active{background:#f4f8ff;color:#09234a;border-color:#f4f8ff}.filter.active span{color:#087ff2}.product-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}.product-card{display:flex;min-width:0;flex-direction:column;border:1px solid var(--line);border-radius:22px;background:linear-gradient(160deg,#0c2a56,#071c3c);overflow:hidden;transition:.35s}.product-card:hover{transform:translateY(-5px);border-color:#3b8bdd;box-shadow:0 25px 55px rgba(0,0,0,.28)}.product-card.selected{border-color:#2ccf8a;box-shadow:0 0 0 1px #2ccf8a}.product-card[hidden]{display:none}.product-media{position:relative;height:275px;display:grid;place-items:center;background:radial-gradient(circle at 50% 35%,#eaf7ff,#b9d6ed 62%,#91b6d5);overflow:hidden}.product-media:after{content:"";position:absolute;left:8%;right:8%;bottom:-34%;height:62%;border:1px solid rgba(0,109,215,.35);border-radius:50%}.packshot{position:relative;width:148px;height:210px;transform:rotate(-3deg);background:linear-gradient(145deg,var(--pack-dark),var(--pack-color));transition:.45s}.product-card:hover .packshot{transform:rotate(2deg) scale(1.04)}.pack-label{position:absolute;z-index:2;inset:70px 13px 15px;padding:13px;color:#09234a}.pack-label span,.pack-label b,.pack-label small{display:block}.pack-label span{font-size:9px;font-weight:900;letter-spacing:.12em}.pack-label b{margin-top:8px;font-size:16px;line-height:1}.pack-label small{position:absolute;bottom:10px;color:var(--pack-color);font-weight:900}.product-chip{position:absolute;z-index:3;left:14px;top:14px;padding:7px 9px;border-radius:999px;background:rgba(5,24,52,.88);color:#fff;font-size:9px;font-weight:800;text-transform:uppercase;letter-spacing:.1em}.details-button{position:absolute;z-index:3;right:14px;top:14px;width:38px;height:38px;border:0;border-radius:50%;background:#fff;color:#09234a;font-size:22px;cursor:pointer;transition:.25s}.details-button:hover{transform:rotate(90deg)}.product-body{display:flex;flex:1;flex-direction:column;padding:21px}.product-category{color:var(--cyan);font-size:9px;font-weight:900;text-transform:uppercase;letter-spacing:.15em}.product-body h3{font-size:24px;line-height:1.05;margin:7px 0}.product-body p{min-height:43px;margin:0;color:#9bb0cc;font-size:12px}.product-meta{display:flex;gap:7px;margin:17px 0}.product-meta span{padding:5px 8px;border:1px solid #285789;border-radius:999px;color:#b3c5dc;font-size:9px}.product-buy{display:flex;align-items:end;justify-content:space-between;gap:12px;margin-top:auto;padding-top:16px;border-top:1px solid #244c7a}.product-buy small,.product-buy strong{display:block}.product-buy small{color:#7892b3;font-size:9px}.product-buy strong{font-size:17px}.add-product{border:0;border-radius:999px;padding:10px 13px;background:#0c80f5;color:#fff;font-weight:800;cursor:pointer}.product-card.selected .add-product{background:#26c987}.usage{display:grid;grid-template-columns:1fr 1fr;gap:75px;align-items:center}.usage-copy>p{color:var(--muted);font-size:17px}.usage-copy ul{padding:0;list-style:none}.usage-copy li{margin:13px 0;color:#b4c5da}.usage-copy li:before{content:"✓";display:inline-grid;place-items:center;width:22px;height:22px;margin-right:12px;border:1px solid var(--green);border-radius:50%;color:var(--green)}.usage-calculator{padding:30px;border:1px solid #2b5d93;border-radius:24px;background:linear-gradient(150deg,#0e3061,#081f43)}.usage-calculator label{display:grid;grid-template-columns:1fr auto;gap:14px;margin-bottom:26px;color:#b5c6db}.usage-calculator output{color:var(--cyan);font-size:24px;font-weight:900}.usage-calculator input{grid-column:1/-1;width:100%;accent-color:#168af8}.usage-result{padding:24px;margin:4px 0 20px;border-radius:18px;background:#061a38}.usage-result span,.usage-result small{display:block;color:#89a1c0;font-size:11px}.usage-result strong{display:block;margin:4px 0;font-size:46px;letter-spacing:-.05em}.usage-calculator .button{width:100%}.quality{display:grid;grid-template-columns:1fr 1fr;gap:65px;align-items:center}.quality-photo{position:relative;min-height:530px;border:1px solid var(--line);border-radius:28px;overflow:hidden}.quality-photo img{width:100%;height:530px;object-fit:cover}.quality-photo:after{content:"";position:absolute;inset:0;background:linear-gradient(0deg,rgba(3,15,34,.75),transparent 55%)}.quality-photo span{position:absolute;z-index:2;left:22px;bottom:20px;font-weight:800}.quality>div>p{color:var(--muted);font-size:17px}.quality-points{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:25px 0}.quality-points article{padding:15px;border:1px solid var(--line);border-radius:14px}.quality-points b,.quality-points span{display:block}.quality-points b{color:var(--cyan)}.quality-points span{font-size:10px}.selection-bar{position:fixed;z-index:90;left:50%;bottom:18px;transform:translateX(-50%);width:min(780px,calc(100% - 28px));display:grid;grid-template-columns:auto 1fr auto auto;gap:20px;align-items:center;padding:12px 14px 12px 20px;border:1px solid #3486d4;border-radius:18px;background:rgba(6,29,62,.95);box-shadow:0 25px 80px rgba(0,0,0,.5);backdrop-filter:blur(18px)}.selection-bar[hidden]{display:none}.selection-bar span{display:block;color:#87a0c0;font-size:9px}.selection-names{overflow:hidden;color:#b7c8de;font-size:11px;white-space:nowrap;text-overflow:ellipsis}.selection-bar .button{padding:11px 16px;font-size:11px}.selection-clear{border:0;background:transparent;color:#9fb3cf;font-size:24px;cursor:pointer}dialog{width:min(850px,calc(100% - 32px));max-width:none;padding:32px;border:1px solid #32659b;border-radius:24px;background:#0a2853;color:#fff;box-shadow:0 35px 110px #000}dialog::backdrop{background:rgba(0,8,20,.8);backdrop-filter:blur(7px)}.dialog-close{position:absolute;z-index:3;right:17px;top:14px;border:0;background:transparent;color:#fff;font-size:28px;cursor:pointer}.product-dialog{display:none;grid-template-columns:.8fr 1.2fr;gap:35px;align-items:center}.product-dialog[open]{display:grid}.dialog-pack{min-height:410px;display:grid;place-items:center;border-radius:18px;background:radial-gradient(circle,#eaf7ff,#a9cbe4)}.dialog-pack .packshot{position:relative}.product-dialog h2,.order-dialog h2{font-size:43px;line-height:1;margin:12px 0}.product-dialog p,.order-dialog>p{color:var(--muted)}.product-dialog dl{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:24px 0}.product-dialog dl div{padding:12px;border:1px solid #315d91;border-radius:12px}.product-dialog dt{color:#7993b4;font-size:9px}.product-dialog dd{margin:3px 0 0;font-weight:800}.order-dialog{width:min(560px,calc(100% - 32px))}.order-list{margin:18px 0;padding:10px 14px;border:1px solid #315d91;border-radius:12px;color:#b6c8de;font-size:11px}.order-list:empty{display:none}form{display:grid;gap:12px}form label{color:#a9bdd6;font-size:11px}form input:not([type=checkbox]){display:block;width:100%;margin-top:5px;padding:13px;border:1px solid #315d91;border-radius:11px;background:#061a38;color:#fff;outline:none}form input:focus{border-color:#168cf8}.consent{display:flex;gap:8px;align-items:center}.success{text-align:center;padding:35px 0}.success strong{color:var(--green);font-size:26px}.reveal{opacity:0;transform:translateY(24px);transition:.7s ease}.reveal.visible{opacity:1;transform:none}.delay-1{transition-delay:.12s}@keyframes bubble{50%{transform:translateY(-16px) scale(.94)}}@media(max-width:980px){.chem-hero{grid-template-columns:1fr;padding-top:110px}.hero-visual{min-height:520px}.chem-stats{grid-template-columns:1fr 1fr}.chem-stats article:nth-child(2){border-right:0}.chem-stats article:nth-child(-n+2){border-bottom:1px solid var(--line)}.product-grid{grid-template-columns:1fr 1fr}.usage,.quality{grid-template-columns:1fr;gap:35px}.global-footer{} }.menu-button{background:transparent;border:0;width:40px;height:40px}.menu-button span{display:block;height:2px;background:#fff;margin:7px}@media(max-width:720px){.section{width:min(100% - 36px,var(--max));padding:75px 0}.chem-hero{padding:70px 18px 30px;min-height:auto}.hero-copy h1{font-size:48px}.hero-copy>p{font-size:16px}.hero-actions{flex-direction:column}.hero-visual{min-height:450px}.hero-visual>img{width:110%;right:-12%}.hero-ring{width:330px;height:330px}.hero-pack{transform:scale(.72) rotate(-5deg)}.pack-blue{left:-5%;bottom:12%}.pack-cyan{right:-10%;top:7%;transform:scale(.62) rotate(7deg)}.chem-stats{width:calc(100% - 28px);padding:8px}.chem-stats article{padding:16px 11px}.chem-stats strong{font-size:34px}.chem-stats span{font-size:9px}.section-heading{display:block}.product-grid{grid-template-columns:1fr}.product-body p{min-height:0}.quality-photo,.quality-photo img{height:390px;min-height:390px}.quality-points{grid-template-columns:1fr}.selection-bar{grid-template-columns:1fr auto}.selection-names{display:none}.selection-bar .button{grid-column:1/-1}.selection-clear{position:absolute;right:8px;top:4px}.product-dialog[open]{display:block}.dialog-pack{min-height:270px;margin-bottom:25px}.product-dialog dl{grid-template-columns:1fr}.product-dialog h2,.order-dialog h2{font-size:35px}.header{height:70px;padding:0 18px}.header .phone{display:none}.brand img{width:125px}}

/* ============================================================
   chem-shop · КАТАЛОГ КАК В МАГАЗИНЕ (86 позиций Shine Systems)
   Дописано в конец файла: правила ниже перебивают старые блоки
   .product-card / .product-media / .dialog-pack просто порядком
   следования. Переменные — из :root страницы, локальные токены
   живут на самой секции.
   ============================================================ */
.catalog-section{
  /* Светлая плашка под снимок. Прайсовые PNG — вырезы на прозрачном фоне,
     и объекты в них разные: белые канистры и чёрные курки-распылители.
     Прямо на navy первые светятся ореолом, вторые пропадают. Плашка
     возвращает студийный фон, на котором их снимали, — края видно всегда. */
  --plate:#e8f0f9;
  --plate-edge:#c7dbef;
  --plate-ink:#0a2547;     /* 13:1 к --plate: артикул на плашке читаем */
  --plate-soft:#4a688c;    /* 5:1 к --plate: вторичные подписи */
  --plate-grid:rgba(10,60,120,.10);
  --plate-size:104px;      /* сторона плашки; снимок внутри всегда ровно 80×80 */
}
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ---------- Поиск и счётчик ---------- */
.catalog-tools{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;margin-bottom:18px}
.catalog-search{position:relative;flex:1 1 320px;max-width:440px;display:flex;align-items:center}
.catalog-search-ic{position:absolute;left:15px;width:18px;height:18px;fill:none;stroke:#7f9bc0;stroke-width:1.8;stroke-linecap:round;pointer-events:none}
#catalog-q{width:100%;padding:14px 44px;border:1px solid var(--line);border-radius:14px;background:#081f43;color:#fff;font-size:15px;outline:none}
#catalog-q::placeholder{color:#7f97b8}
#catalog-q:focus{border-color:var(--cyan);box-shadow:0 0 0 3px rgba(69,187,255,.18)}
#catalog-q::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}
.catalog-search-clear{position:absolute;right:9px;width:30px;height:30px;border:0;border-radius:50%;background:transparent;color:#a7bcd8;font-size:20px;line-height:1;cursor:pointer}
.catalog-search-clear:hover{background:#123a6d;color:#fff}
.catalog-search-clear[hidden]{display:none}
.catalog-count{margin:0;color:#93aac9;font-size:12.5px}

/* Ряды чипов над сеткой заменены панелью слева — её правила в конце файла,
   в блоке chem22. */

/* ---------- Сетка ----------
   auto-fill вместо жёстких трёх колонок: 3 на 1440, 2 на 768, 1 на 390 —
   без отдельных медиазапросов. min(340px,100%) страхует экраны уже 340 px. */
#product-grid{grid-template-columns:repeat(auto-fill,minmax(min(340px,100%),1fr));gap:14px}

/* ---------- Карточка ---------- */
.pc{
  display:grid;grid-template-columns:var(--plate-size) minmax(0,1fr);
  grid-template-areas:"plate body" "acts acts";
  gap:12px 16px;padding:16px;border-radius:18px;align-content:start;
  background:linear-gradient(160deg,#0c2a56,#081f42);
  border:1px solid var(--line);
  /* Ровная высота: 86 карточек с «пляшущим» низом читаются как каша.
     Она же нужна content-visibility ниже, чтобы прокрутку не дёргало. */
  min-height:198px;
  /* Главная экономия на телефоне: браузер не считает раскладку и не красит
     карточки за экраном. 86 штук — как раз тот случай, когда это заметно. */
  content-visibility:auto;contain-intrinsic-size:auto 198px;
  transition:border-color .25s,box-shadow .25s,transform .25s;
  /* Вся карточка теперь тоже ведёт на товар (script.js, onGridClick) —
     курсор должен обещать это до клика, а не только над «Подробнее». */
  cursor:pointer
}
/* .pc задаёт display:grid и перебивает старое .product-card[hidden] —
   возвращаем скрытие явно, иначе фильтр перестанет прятать карточки. */
.pc[hidden]{display:none}
.pc:hover{transform:translateY(-2px);border-color:#3b8bdd;box-shadow:0 14px 32px -12px rgba(0,0,0,.55)}

/* ---------- Плашка со снимком 80×80 ---------- */
.pc-plate{
  grid-area:plate;position:relative;width:var(--plate-size);height:var(--plate-size);
  display:grid;place-items:center;border-radius:14px;overflow:hidden;
  /* Сетка 8 px — та же графика, что у .grid-bg страницы. Она задаёт масштаб:
     рядом с ней снимок 80 px читается как «столько и есть», а не как
     уменьшенная большая картинка. */
  background:
    linear-gradient(var(--plate-grid) 1px,transparent 1px) 0 0/8px 8px,
    linear-gradient(90deg,var(--plate-grid) 1px,transparent 1px) 0 0/8px 8px,
    radial-gradient(circle at 50% 28%,#fff,var(--plate) 68%,var(--plate-edge));
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.55),0 6px 16px -9px rgba(0,0,0,.6)
}
.pc-plate img{
  /* Ровно 80×80 и ни пикселем больше: источник — растр 80×80 из прайса,
     любое увеличение даёт мыло. 12 px воздуха до края плашки — это поле
     кадра, из-за него снимок выглядит поставленным, а не обрезанным. */
  width:80px;height:80px;object-fit:contain;
  filter:drop-shadow(0 3px 5px rgba(10,40,80,.22))
}
/* Нет фото — вместо битой картинки индексная плашка: артикул читаемо,
   буква назначения фоном. Геометрия та же, ряд не рвётся. */
.pc-plate.is-blank{background:
  linear-gradient(var(--plate-grid) 1px,transparent 1px) 0 0/8px 8px,
  linear-gradient(90deg,var(--plate-grid) 1px,transparent 1px) 0 0/8px 8px,
  linear-gradient(155deg,#eff5fc,#d5e4f2)}
.pc-blank-letter{position:absolute;font-size:62px;font-weight:900;line-height:1;letter-spacing:-.06em;color:rgba(10,60,120,.14);user-select:none}
.pc-blank-sku{position:relative;padding:3px 7px;border-radius:7px;background:rgba(255,255,255,.75);color:var(--plate-ink);font-size:12px;font-weight:900}

/* ---------- Текст карточки ---------- */
.pc-body{grid-area:body;min-width:0}
.pc-head{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.pc-kind{color:var(--cyan);font-size:10px;font-weight:900;letter-spacing:.14em;text-transform:uppercase}
/* Новинка помечена, потому что у неё в прайсе ещё не заведена цена: менеджер
   должен видеть, что по ней нужен отдельный расчёт. */
.pc-new{padding:2px 7px;border-radius:6px;background:rgba(255,216,115,.16);color:#ffd873;font-size:9.5px;font-weight:900;letter-spacing:.08em;text-transform:uppercase}
.pc-brand{margin-left:auto;flex:0 0 auto;color:#8ba2c2;font-size:10px;font-weight:800;letter-spacing:.05em}
.pc-title{margin:7px 0 5px;font-size:17px;line-height:1.2;letter-spacing:-.01em}
.pc-lead{margin:0;color:#a8bcd8;font-size:12.5px;line-height:1.45;
  /* Описания приходят разной длины. Обрезаем до двух строк, чтобы ряд стоял
     ровно; полный текст живёт в карточке товара, ничего не теряется. */
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden}
/* У «бедных» позиций (микрофибра, инструмент) нет ни pH, ни разбавления —
   ряд чипов почти пустой. Отдаём освободившуюся строку описанию. */
.pc.is-lean .pc-lead{-webkit-line-clamp:3}
.pc-specs{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.pc-specs span{padding:4px 8px;border:1px solid #2a5b8f;border-radius:8px;color:#bacbe0;font-size:11px;white-space:nowrap}
/* Артикул — единственный чип, который есть у всех: по нему заказывают,
   по нему же ищут. Поэтому он выделен и стоит первым. */
.pc-specs .is-sku{border-color:rgba(69,187,255,.35);background:rgba(69,187,255,.12);color:#c7e6ff;font-weight:800}
/* Цена в карточке. Оптовая крупно, розничная зачёркнутой рядом — та же
   логика, что на странице товара. Цифры табличные: в сетке из трёх колонок
   разнобой по ширине цифр заметен сразу. */
.pc-price{display:flex;align-items:baseline;gap:9px;margin-top:11px;font-variant-numeric:tabular-nums}
/* nowrap: у позиций дороже ста тысяч знак рубля срывался на вторую строку,
   и цена читалась как «237 578» отдельно и «₽» отдельно. */
.pc-price b{font-size:19px;font-weight:900;letter-spacing:-.02em;color:#fff;white-space:nowrap}
.pc-price s{color:#8ba2c2;font-size:13px;white-space:nowrap}

/* ---------- Действия ---------- */
.pc-acts{grid-area:acts;display:flex;gap:8px;margin-top:auto;padding-top:12px;border-top:1px solid #23497a}
/* «Подробнее» теперь ссылка на страницу товара, а не кнопка модалки —
   поэтому нужны inline-flex и выравнивание: у <a> нет своей высоты. */
.pc-more{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;padding:10px 14px;border:1px solid var(--line);border-radius:10px;background:#0a2450;color:#dce7f7;font-size:12px;font-weight:800;cursor:pointer}
.pc-more:hover{border-color:var(--cyan);color:#fff}
.pc-add{flex:1 1 auto;padding:10px 14px;border:0;border-radius:10px;background:#0c80f5;color:#fff;font-size:12px;font-weight:800;cursor:pointer}
.pc-add:hover{background:#2b95ff}
/* «В запросе» — тёмный текст на зелёном: белый на #31d98a даёт 2:1 и
   не проходит по контрасту, хотя выглядит бодро. */
.pc.selected .pc-add{background:var(--green);color:#04281a}

/* ---------- Пустой результат и «показать ещё» ---------- */
.catalog-empty{margin:26px 0 0;padding:24px;border:1px dashed #2c5c92;border-radius:16px;color:#b6c8de;font-size:14px;text-align:center;line-height:1.6}
.catalog-empty[hidden]{display:none}
.catalog-empty b{color:#fff}
.linkish{padding:0;border:0;background:none;color:var(--cyan);font:inherit;font-weight:800;text-decoration:underline;cursor:pointer}
.catalog-more{display:flex;justify-content:center;margin-top:24px}
.catalog-more[hidden]{display:none}
#catalog-more-btn{min-width:240px}

/* ---------- пагинация каталога ----------
   Пришла на смену «Показать ещё»: страницы вместо накопительной подгрузки —
   к конкретной позиции можно вернуться по прямой ссылке на страницу выдачи,
   а не долистывать всё заново. Рисует script.js (renderPagination), сама
   разметка — только контейнер с id, чтобы работать без разметки под каждый
   язык отдельно. */
.catalog-pages{display:flex;align-items:center;justify-content:center;gap:8px;margin-top:28px}
.catalog-pages[hidden]{display:none}
.cp-numbers{display:flex;align-items:center;gap:6px;flex-wrap:wrap;justify-content:center}
.cp-nav,.cp-page{
  min-width:40px;height:40px;padding:0 6px;border-radius:999px;
  border:1px solid var(--line);background:rgba(11,40,82,.4);color:#cfe0f7;
  font-weight:800;font-size:15px;cursor:pointer;transition:.18s;
  display:inline-flex;align-items:center;justify-content:center
}
.cp-nav{font-size:20px}
.cp-nav:hover,.cp-page:hover{border-color:var(--cyan);color:#fff}
.cp-page.is-on{border-color:transparent;background:linear-gradient(110deg,#087cff,#31a9ff);color:#fff}
.cp-nav:disabled{opacity:.35;cursor:default;pointer-events:none}
@media (max-width:560px){.cp-nav,.cp-page{min-width:36px;height:36px;font-size:14px}.cp-nav{font-size:18px}}

/* ---------- Карточка товара в модалке ----------
   Старая .dialog-pack была высотой 410 px под нарисованную канистру.
   Реального снимка там 80 px, поэтому столько места не нужно. */
.product-dialog{grid-template-columns:190px minmax(0,1fr);gap:30px;align-items:start;max-height:min(88vh,860px);overflow:auto;overscroll-behavior:contain}
.dialog-side{display:grid;justify-items:center;gap:10px}
.dialog-pack{min-height:0;padding:0;background:none}
.pc-plate.is-big{--plate-size:150px;border-radius:18px}
.pc-plate.is-big .pc-blank-letter{font-size:84px}
.dialog-status{padding:5px 10px;border:1px solid #2f6ba4;border-radius:999px;color:#a9c3e2;font-size:10px;font-weight:800;text-transform:uppercase;letter-spacing:.1em}
.dialog-status[hidden]{display:none}
#dialog-description[hidden]{display:none}
#dialog-specs{display:grid;grid-template-columns:repeat(auto-fit,minmax(128px,1fr));gap:8px;margin:22px 0 0}
#dialog-specs:empty{display:none}
#dialog-specs div{padding:11px 13px;border:1px solid #315d91;border-radius:12px}
#dialog-specs dt{color:#93aac9;font-size:9px;font-weight:800;letter-spacing:.1em;text-transform:uppercase}
#dialog-specs dd{margin:4px 0 0;font-weight:800;font-size:14px}
.pd-note{margin-top:12px;padding:13px 16px;border-left:2px solid rgba(69,187,255,.55);border-radius:0 12px 12px 0;background:rgba(8,32,68,.7)}
.pd-note b{display:block;margin-bottom:5px;color:var(--cyan);font-size:10px;font-weight:900;letter-spacing:.13em;text-transform:uppercase}
.pd-note p{margin:0;color:#c2d3e8;font-size:13px;line-height:1.55}
.pd-note.is-warn{border-left-color:#f0a33a}
.pd-note.is-warn b{color:#ffbf63}
.product-dialog .dialog-add{margin-top:22px}

/* ---------- Панель выбора ----------
   В разметке этот блок без класса (.selection-names в CSS ни к чему не
   крепился). С шестью товарами это не мешало, а с двадцатью строка
   растягивает панель на пол-экрана. Правим по id. */
#selection-names{min-width:0;overflow:hidden;color:#b7c8de;font-size:11px;white-space:nowrap;text-overflow:ellipsis}
.order-list{max-height:120px;overflow:auto}

/* ---------- Клавиатура ----------
   Видимого фокуса на странице не было вовсе: по 86 карточкам, поиску и
   фильтрам без него не пройти. */
.catalog-section :focus-visible,.selection-bar :focus-visible,dialog :focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.facet>summary:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}

/* ---------- Адаптив ---------- */
@media(max-width:980px){
  .product-dialog[open]{grid-template-columns:1fr}
  .dialog-side{justify-items:start}
}
@media(max-width:720px){
  .catalog-tools{gap:10px}
  .catalog-search{max-width:none;flex:1 1 100%}
  #selection-names{display:none}
  .product-dialog[open]{display:block}
  .dialog-side{grid-auto-flow:column;justify-content:start;align-items:center;margin-bottom:20px}
}
@media(max-width:430px){
  .catalog-section{--plate-size:96px}
  .pc{padding:14px;gap:12px}
  .pc-title{font-size:16px}
  .pc-acts{flex-wrap:wrap}
  .pc-more,.pc-add{flex:1 1 130px}
}
@media(prefers-reduced-motion:reduce){
  .pc,.pc-more,.pc-add,#catalog-q{transition:none}
  .pc:hover{transform:none}
}
/* chem-shop · горизонтальная прокрутка на телефоне.
   Замер на 390 px: страница 398 px, лишние 8 даёт снимок в первом экране —
   у него нет ограничения по ширине контейнера. Правило общее для картинок
   страницы: ни одна не должна вылезать за свою колонку. */
.chem-hero img,.hero-visual img{max-width:100%;height:auto}
/* chem7 · Фотография в первом экране съезжала на дно блока.
   Правило выше — общая защита от горизонтальной прокрутки на телефоне —
   имеет ту же специфичность (0,1,1), что и .hero-visual>img из основного
   блока, но идёт ниже по файлу, поэтому перебивало height:74% на height:auto.
   Снимок схлопывался с 459 px до 212 px и, оставаясь прижатым к bottom:0,
   падал вниз и налезал на канистру.
   Возвращаем заданную высоту через повышенную специфичность (0,2,1).
   max-width:100% выше НЕ трогаем — на нём держится защита от прокрутки. */
.chem-hero .hero-visual>img{height:74%}
/* chem7 · На 375 px «самообслуживания» не влезало в строку и рвалось
   посреди слова: «самообслужив / ания». Слово длинное, переносов нет,
   поэтому кегль привязан к ширине экрана. Замер на 375 px: доступно 339 px,
   слово при 36 px занимает 324 px, при 38 px — уже 344 и рвётся. 9.2vw даёт
   34,5 px на 375 px и 38,6 px на 420 px — влезает на всей вилке. */
@media(max-width:420px){.chem-hero .hero-copy h1{font-size:min(48px,9.2vw)}}

/* ============================================================
   chem-shop · снимки без плашки и без сетки (решение владельца)
   У 18 снимков фон был вклеен светло-серым градиентом — вырезан
   скриптом tools/chemistry-06-cutout.ps1, оригиналы лежат в
   assets/products-src. Теперь все 65 — вырезы с прозрачностью,
   поэтому подложка не нужна: вместо неё мягкое свечение, у него
   нет краёв, и оно не читается как рамка.
   ============================================================ */
.pc-plate{
  background:radial-gradient(circle at 50% 56%,rgba(190,225,255,.16),rgba(190,225,255,.05) 55%,transparent 72%);
  box-shadow:none;border-radius:0
}
/* Тень под самим предметом, а не под плашкой: она сажает вырез на карточку
   и удерживает белые канистры, которые иначе висят в воздухе. */
.pc-plate img{filter:drop-shadow(0 6px 10px rgba(0,10,28,.55))}

/* Позиции без фото — единственный случай, где рамка нужна: показывать нечего,
   и без неё артикул висит в пустоте. Сетки здесь тоже нет. */
.pc-plate.is-blank{
  background:linear-gradient(160deg,rgba(120,180,255,.10),rgba(120,180,255,.03));
  border:1px solid rgba(120,180,255,.22);border-radius:14px}
.pc-plate.is-blank .pc-blank-letter{color:rgba(150,200,255,.16)}
.pc-plate.is-blank .pc-blank-sku{background:rgba(8,32,68,.85);color:#cfe3fb}

/* ============================================================
   chem-shop · настоящие снимки производителя (chem6)

   Прайсовые картинки были 80×80 — для карточки магазина этого мало.
   Снимки взяты из каталога Shine Systems скриптом
   tools/chemistry-07-shine-photos.py: 51 позиция, кадр 1:1.

   Фон у них не вырезан, а доведён до чистого белого — и это не
   упрощение. Товар и фон здесь одного цвета: заливка, настроенная
   так, чтобы убрать серый градиент по краю кадра, прорывается через
   контур и выедает бок белой канистры (проверено на ActiveBase и
   PreWash). Добеливание тем же путём безопасно. Поэтому плитка под
   снимком светлая: это тот самый студийный фон, на котором снимали.
   ============================================================ */
.catalog-section{--plate-size:132px}
/* Между плашкой статистики и каталогом было ~105px пустоты — общий
   .section{padding:105px 0} рассчитан на крупные секции лендинга, а тут
   между двумя уже насыщенными блоками смотрелся как дыра в вёрстке. */
.catalog-section{padding-top:40px}
.pc-plate{
  background:#fff;border-radius:14px;padding:0;
  box-shadow:0 1px 0 rgba(255,255,255,.4),0 12px 24px -16px rgba(0,8,24,.8)
}
/* Снимок отдаём в его настоящем размере и только ограничиваем сверху.
   У 20 позиций в прайсе есть лишь 80×80, а у части снимков поставщика —
   265 px: растянуть их до плитки значит показать мыло. Маленький, но
   резкий кадр честнее. Поле 4% уже заложено в файл, отступ не нужен. */
.pc-plate img{width:auto;height:auto;max-width:100%;max-height:100%;filter:none}
/* Тень под предметом больше не нужна: она сажала вырез на тёмную карточку,
   а на белой плитке читается как грязь по контуру. */

.pc-plate.is-blank{
  background:linear-gradient(158deg,#eef4fb,#dae7f4);border:0;
  box-shadow:inset 0 0 0 1px rgba(10,60,120,.1),0 12px 24px -16px rgba(0,8,24,.7)}
.pc-plate.is-blank .pc-blank-letter{color:rgba(10,60,120,.13)}
.pc-plate.is-blank .pc-blank-sku{background:rgba(255,255,255,.82);color:#0a2547}

/* ---------- Карточка товара ----------
   Было: две колонки во всю высоту модалки. Снимок 80 px стоял в колонке
   190 px, под ним оставалось 700 px пустоты, а кнопка «Запросить цену»
   уезжала за нижний край — до главного действия надо было прокрутить.
   Ещё характеристики шли сеткой одинаковых боксов, и «Разбавление»
   фразой в 60 знаков растягивало ряд: рядом стояли три почти пустых
   бокса по 210 px в высоту.

   Стало: снимок, название и кнопка стоят наверху и не двигаются,
   длинные тексты листаются под ними. */
.product-dialog[open]{
  display:grid;grid-template-columns:none;grid-template-rows:auto minmax(0,1fr);
  gap:0;align-items:stretch;padding:26px 28px 24px;
  max-height:min(88vh,880px);overflow:hidden
}
.pd-top{display:grid;grid-template-columns:auto minmax(0,1fr);gap:28px;align-items:start}
.pd-intro{min-width:0}
.dialog-side{display:grid;justify-items:center;gap:10px}
/* Сторону плитки ставит скрипт в --plate-size: она равна настоящему
   размеру снимка, но не больше 300 px. Так у позиции с кадром 265 px
   не остаётся белого поля вокруг предмета. */
.pc-plate.is-big{border-radius:18px;box-shadow:0 18px 38px -22px rgba(0,8,24,.95)}
.product-dialog h2{margin:10px 0 0;font-size:clamp(30px,3.4vw,40px);line-height:1.04;letter-spacing:-.03em;text-wrap:balance}
/* Фокус при открытии уводим на заголовок — скринридер читает название
   товара. Рамку вокруг него не рисуем: это не кнопка, и обводка на
   полэкрана читается как брак вёрстки. */
#dialog-name:focus,#dialog-name:focus-visible{outline:none}
#dialog-description{margin:12px 0 0;color:#adc1dc;font-size:14.5px;line-height:1.55;max-width:60ch}
/* Чипы вместо сетки боксов: flex тянет каждый по содержимому и не
   выравнивает высоту по самому длинному. */
#dialog-specs{display:flex;flex-wrap:wrap;gap:8px;margin:18px 0 0;grid-template-columns:none}
#dialog-specs div{padding:9px 13px;border:1px solid #2f5c8f;border-radius:11px;background:rgba(8,30,64,.55)}
#dialog-specs dd{white-space:nowrap}
.product-dialog .dialog-add{margin-top:20px}

.pd-body{
  margin-top:22px;padding:20px 4px 0 0;border-top:1px solid #23497a;
  overflow:auto;overscroll-behavior:contain;
  scrollbar-width:thin;scrollbar-color:#2a5b8f transparent
}
.pd-body:empty{display:none}
.pd-body .pd-note:first-child{margin-top:0}

/* Экран низкий (ноутбук 768 px, телефон лежа) — внутренняя прокрутка
   съедает верх карточки. Тогда листаем модалку целиком. */
@media(max-height:760px){
  .product-dialog[open]{grid-template-rows:auto auto;overflow:auto}
  .pd-body{overflow:visible}
}
@media(max-width:760px){
  .product-dialog[open]{display:grid;grid-template-rows:auto auto;overflow:auto;padding:22px 18px}
  .pd-top{grid-template-columns:1fr;gap:18px}
  /* Снимок и метка «новинка» встают в строку: вертикаль на телефоне дороже. */
  .dialog-side{grid-auto-flow:column;justify-content:start;justify-items:start;align-items:center;gap:14px;margin:0}
  .pd-body{overflow:visible}
}

/* ============================================================
   chem-shop · канистры в первом экране (chem6)
   Прежние .hero-pack были нарисованы на CSS: прямоугольник с
   псевдоэлементами вместо горлышка и этикетки. Рядом с фотографией
   машины это читалось как заглушка. Теперь это снимки вектора
   (tools/canister-builder.html) с прозрачным фоном, поэтому нужны
   только положение, размер и тень.
   ============================================================ */
.hero-can{position:absolute;z-index:2;display:block;line-height:0;
  filter:drop-shadow(0 26px 34px rgba(0,10,30,.5))}
.hero-can img{width:auto;height:clamp(206px,23vw,290px)}
.hero-can.can-blue{left:4%;bottom:15%;transform:rotate(-5deg)}
.hero-can.can-cyan{right:1%;top:11%;transform:rotate(7deg)}
.hero-can.can-cyan img{height:clamp(168px,18.5vw,232px)}
@media(max-width:720px){
  .hero-can.can-blue{left:-2%;bottom:11%}
  .hero-can.can-cyan{right:-4%;top:6%}
  .hero-can img{height:clamp(150px,36vw,206px)}
  .hero-can.can-cyan img{height:clamp(120px,29vw,168px)}
}

/* ============================================================
   chem-shop · линейки (chem6)
   Знаки — файлы производителя, собраны скриптом
   tools/chemistry-08-brand-logos.py. Оба белые на прозрачном,
   поэтому лежат прямо на тёмной карточке без подложки.
   ============================================================ */
.pc-brand-mark{
  margin-left:auto;flex:0 0 auto;width:auto;height:16px;
  /* Леттеринг белый и на navy бьёт ярче названия товара, которое здесь
     главное. Приглушаем до уровня вторичной подписи. */
  opacity:.72
}
.pc:hover .pc-brand-mark{opacity:.95}

/* Знак в карточке товара: рядом с назначением, чипа «Бренд» ниже больше нет.
   Отступ справа — под кнопку закрытия: она висит абсолютом в том же углу и
   наезжала на знак. */
.pd-eyebrow{display:flex;align-items:center;justify-content:space-between;gap:16px;padding-right:46px}
.pd-brand{display:flex;flex:0 0 auto}
.pd-brand img{width:auto;height:22px;opacity:.85}

/* ===== Страницу таскало вбок на телефоне =====
   Замер на экране 375 px: страница была шириной 508 px, то есть уезжала
   на 133 px вправо. Причина — первый экран. Он грид, и на телефоне колонка
   задана как 1fr. А «1fr» на самом деле означает minmax(auto,1fr): колонка
   не имеет права стать уже своего содержимого. Содержимое оказалось шире
   экрана, колонка растянулась до 437 px и вытолкнула всё за край.
   minmax(0,1fr) снимает этот нижний предел — колонка садится в 339 px.

   Остаток в 23 px давали декоративные картинки первого экрана: они лежат
   абсолютом и по задумке чуть выходят за рамку. На широком экране это
   красиво, на телефоне — лишняя прокрутка. Подрезаем по горизонтали:
   clip, а не hidden, чтобы не создавать лишний контейнер прокрутки. */
@media(max-width:1200px){
  .chem-hero{overflow-x:clip}
}
@media(max-width:980px){
  .chem-hero{grid-template-columns:minmax(0,1fr)}
}
/* ============================================================
   chem-hero · один широкоформатный кадр (21.08.2026)
   Раньше первый экран собирался из фотографии машины, двух векторных
   канистр, декоративного кольца и трёх «пузырей» — четыре запроса и
   абсолютное позиционирование, которое приходилось чинить на каждой
   ширине. Теперь это одна картинка с прозрачным фоном, пропорция 1,78.
   Кадр широкий, поэтому он стоит НЕ в правой колонке, а во всю ширину
   экрана под текстом: в колонке шириной в половину экрана широкий кадр
   получался низким и мелким. Отрицательные поля вытягивают его за
   боковые отступы секции — до самых краёв окна.
   Старые правила .hero-can / .hero-ring / .bubble остались выше по файлу,
   но элементов с такими классами на странице больше нет.
   ============================================================ */
/* place-items:center у .hero-visual (базовое правило выше) центрирует кадр
   внутри колонки. Кадр шире колонки, поэтому «лишнее» уходило поровну влево и
   вправо — влево прямо на текст: на 1920 наезд был 126 px. Прижимаем к левому
   краю колонки, тогда весь избыток уходит вправо, к краю окна. */
.chem-hero .hero-visual{min-height:0;display:block;place-items:start}
.chem-hero .hero-visual>img.chem-hero-pack{
  position:static;display:block;justify-self:start;width:100%;max-width:none;height:auto;
  filter:drop-shadow(0 26px 44px rgba(0,10,30,.5));
}
/* Широкий экран: текст и кадр стоят рядом, на одном уровне. Кадр шире своей
   колонки — вытянут до правого края окна за боковой отступ секции, иначе
   при пропорции 1,78 он получается низким. Заголовок ужат ровно настолько,
   чтобы «самообслуживания» помещалось в колонку одной строкой. */
@media(min-width:981px){
  .chem-hero{
    grid-template-columns:minmax(0,48%) minmax(0,52%);
    align-items:center;gap:40px;
    padding-top:70px;padding-bottom:70px;
  }
  .chem-hero .hero-copy h1{font-size:clamp(36px,3.4vw,48px);letter-spacing:-.045em}
  .chem-hero .hero-copy>p,.chem-hero .hero-punch{max-width:100%}
  /* Кадр НЕ вылезает за колонку. Вылет к краю окна давал две беды: на широких
     мониторах правая канистра уезжала за границу экрана и обрезалась, а сам
     кадр начинал спорить с заголовком по весу. Теперь правый край картинки
     совпадает с правым краем текстового блока. */
  .chem-hero .hero-visual>img.chem-hero-pack{
    /* Небольшой, ЖЁСТКО ОГРАНИЧЕННЫЙ вылет вправо: кадр становится крупнее,
       но не уходит за край окна и не обрезается, как было при вылете на всю
       ширину бокового отступа. */
    --bleed:clamp(0px, (100vw - var(--max))/2 - 24px, 64px);
    width:calc(100% + var(--bleed));
  }
}
@media(max-width:980px){ .chem-hero{padding-top:96px} .chem-hero .hero-visual{margin-top:14px} }
@media(max-width:720px){
  .chem-hero{padding-top:104px;padding-bottom:14px}
  .chem-hero .hero-actions{margin:20px 0}
  .chem-hero .hero-visual{margin-top:4px}
  .chem-hero .hero-visual>img.chem-hero-pack{width:88%;margin-inline:auto}
}

/* ============================================================
   АКТИВНАЯ ПЕНА · текстовый раздел под главный запрос страницы.
   Своих цветов не заводит — всё из :root страницы, поэтому блок
   не разъедется, если поменяется тема.
   ============================================================ */
.foam-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.foam-grid article{padding:26px;border:1px solid var(--line);border-radius:22px;background:linear-gradient(160deg,#0c2a56,#071c3c)}
.foam-grid b{display:block;margin-bottom:11px;color:var(--cyan);font-size:11px;font-weight:900;letter-spacing:.15em;text-transform:uppercase}
.foam-grid p{margin:0;color:#b4c5da;font-size:15px}
.foam a{color:var(--cyan);text-decoration:underline;text-underline-offset:3px}
.foam a:hover{color:#8fd6ff}
.foam-foot{max-width:820px;margin:26px 0 0;color:var(--muted);font-size:15px}
@media(max-width:980px){.foam-grid{grid-template-columns:1fr 1fr}}
@media(max-width:720px){.foam-grid{grid-template-columns:1fr}.foam-grid article{padding:20px}}
/* ============================================================
   ИНДЕКС КАТАЛОГА · статический список страниц товаров.
   Сетку каталога рисует JS, и в исходном HTML хаба не было ни одной
   ссылки на 40 страниц товаров — краулер, не исполняющий JS, их не
   обходил, и весь каталог висел на одном sitemap.xml. Блок нарочно
   неброский: это указатель в конце каталога, а не вторая витрина.
   Собирает tools/chemistry-12-static-index.py — руками не правят.
   ============================================================ */
.catalog-index{margin-top:34px;padding-top:26px;border-top:1px solid var(--line)}
.catalog-index h2{margin:0;font-size:22px;letter-spacing:-.02em}
.catalog-index>p{max-width:640px;margin:8px 0 18px;color:var(--muted);font-size:14px}
.catalog-index ul{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:7px 26px;margin:0;padding:0;list-style:none}
.catalog-index li{font-size:13.5px;line-height:1.45}
.catalog-index a{color:#cfe0f4;border-bottom:1px solid transparent}
.catalog-index a:hover{color:#fff;border-bottom-color:var(--cyan)}
.catalog-index a span{color:#7f97b8}
@media(max-width:980px){.catalog-index ul{grid-template-columns:1fr 1fr}}
@media(max-width:720px){.catalog-index ul{grid-template-columns:1fr;gap:10px}}
/* ============================================================
   chem-shop · ПАНЕЛЬ ФИЛЬТРОВ СЛЕВА (chem22 · 26.08.2026)

   Было: два ряда чипов над сеткой — пятнадцать назначений и
   четыре «линейки». На десктопе это четыре строки кнопок до
   первого товара, и выбрать можно ровно одно значение в ряду.
   Стало: панель слева, как в любом каталоге, где товаров больше
   полусотни, с множественным выбором и сортировкой.

   Ширина панели 260 px. Сетке остаётся ~940 px, то есть две
   карточки в ряд вместо трёх. Это не потеря: карточка здесь
   горизонтальная (снимок слева, текст справа), и в трети от
   940 px текстовой колонке остаётся 133 px — там не помещается
   ни название, ни строка характеристик.
   ============================================================ */
.cat-layout{display:grid;grid-template-columns:260px minmax(0,1fr);gap:26px;align-items:start}
.cat-main{min-width:0}
.cat-main .catalog-count{margin:0 0 14px}

/* Панель липкая: список фильтров должен оставаться под рукой на любой
   странице каталога, иначе за ним нужно возвращаться наверх. Отступ сверху —
   под высоту шапки (82 px), она тоже липкая и перекрыла бы заголовок панели. */
.cat-side{position:sticky;top:96px;border:1px solid var(--line);border-radius:18px;
  background:rgba(9,35,74,.55)}
.cat-side-head{display:flex;align-items:center;gap:10px;padding:14px 16px;border-bottom:1px solid #1d4576}
.cat-side-head b{font-size:14px;letter-spacing:-.01em}
.cat-reset{margin-left:auto;padding:4px 2px;border:0;background:transparent;color:var(--cyan);font-size:12px;font-weight:800;cursor:pointer}
.cat-reset:hover{text-decoration:underline}
.cat-reset[hidden]{display:none}
.cat-side-close{display:none}
/* Своя прокрутка внутри панели: граней шесть, на невысоком ноутбуке они не
   помещаются в экран, а липкий блок выше экрана не прокручивается. */
/* Высота: экран минус липкая шапка (96), минус заголовок панели (52) и
   небольшой воздух снизу. На ноутбуке 900 px в панель помещаются бренды,
   назначения и фасовка целиком, цена уезжает под прокрутку. */
.cat-side-scroll{max-height:calc(100vh - 168px);overflow:auto;padding:2px 16px 10px;
  scrollbar-width:thin;scrollbar-color:#2a5b8f transparent}
/* Системная полоса прокрутки в Chrome на Windows рисуется светло-серой и на
   тёмной панели выглядит как случайная деталь. Свой вариант — той же линией,
   что и рамки вокруг. */
.cat-side-scroll::-webkit-scrollbar{width:6px}
.cat-side-scroll::-webkit-scrollbar-track{background:transparent}
.cat-side-scroll::-webkit-scrollbar-thumb{background:#2a5b8f;border-radius:999px}
.cat-side-scroll::-webkit-scrollbar-thumb:hover{background:#3a7ec0}
.cat-side-foot{display:none}

/* ---------- Грань ---------- */
.facet{padding:12px 0;border-bottom:1px solid #17396a}
.facet:last-child{border-bottom:0}
.facet>summary{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 0;
  list-style:none;cursor:pointer;color:#cfe0f4;font-size:11px;font-weight:900;letter-spacing:.13em;text-transform:uppercase}
.facet>summary::-webkit-details-marker{display:none}
.facet>summary:after{content:"";flex:0 0 auto;width:7px;height:7px;margin-bottom:3px;
  border-right:2px solid #6d8db3;border-bottom:2px solid #6d8db3;transform:rotate(45deg);transition:transform .2s}
.facet[open]>summary:after{transform:rotate(-135deg);margin-bottom:-2px}
.facet-body{padding-top:10px}

/* ---------- Бренд ----------
   Знаком, а не строкой: производителя узнают по знаку быстрее, чем читают
   имя. Знаки белые на прозрачном, поэтому лежат прямо на тёмной плитке.
   Погашенный вариант (в текущей выдаче таких товаров нет) не прячем — иначе
   список скачет под курсором и кажется, что бренд из каталога исчез. */
.brand-tiles{display:grid;gap:8px}
.btile{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:48px;
  padding:10px 12px;border:1px solid #2a5b8f;border-radius:12px;background:#081f43;cursor:pointer;transition:.2s}
.btile img{width:auto;height:20px;opacity:.78}
.btile-n{color:#7f97b8;font-size:11px;font-weight:800;font-variant-numeric:tabular-nums}
.btile:hover{border-color:var(--cyan)}
.btile:hover img{opacity:1}
.btile.is-on{border-color:var(--cyan);background:rgba(69,187,255,.13);box-shadow:inset 0 0 0 1px rgba(69,187,255,.3)}
.btile.is-on img{opacity:1}
.btile.is-on .btile-n{color:var(--cyan)}
.btile.is-off{opacity:.35;pointer-events:none}

/* ---------- Чекбокс ----------
   Родной квадратик в тёмной теме на Windows рисуется белым и выбивается из
   палитры, поэтому прячем его и рисуем свой. input остаётся в разметке и
   держит на себе фокус и клавиатуру. */
.fchk{display:flex;align-items:center;gap:9px;padding:6px 2px;color:#c2d4ea;font-size:13px;line-height:1.3;cursor:pointer}
.fchk input{position:absolute;width:1px;height:1px;opacity:0}
.fchk-box{position:relative;flex:0 0 auto;width:17px;height:17px;border:1px solid #35679e;border-radius:5px;background:#081f43;transition:.15s}
.fchk input:checked+.fchk-box{border-color:var(--cyan);background:var(--cyan)}
.fchk input:checked+.fchk-box:after{content:"";position:absolute;left:5px;top:1px;width:5px;height:10px;
  border:solid #05152e;border-width:0 2px 2px 0;transform:rotate(45deg)}
.fchk input:focus-visible+.fchk-box{outline:2px solid var(--cyan);outline-offset:2px}
.fchk-t{flex:1 1 auto;min-width:0}
.fchk-n{flex:0 0 auto;color:#7f97b8;font-size:11px;font-weight:800;font-variant-numeric:tabular-nums}
.fchk:hover{color:#fff}
.fchk.is-off{opacity:.4;pointer-events:none}
.facet-flags{padding-top:14px}

/* ---------- Цена ---------- */
.facet-price{display:flex;align-items:center;gap:8px}
.facet-price label{flex:1 1 0;min-width:0}
.facet-price i{flex:0 0 auto;color:#6d8db3;font-style:normal}
.facet-price input{width:100%;padding:9px 10px;border:1px solid #2a5b8f;border-radius:10px;background:#081f43;
  color:#fff;font-size:13px;outline:none;font-variant-numeric:tabular-nums;-moz-appearance:textfield;appearance:textfield}
.facet-price input::-webkit-outer-spin-button,.facet-price input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.facet-price input:focus{border-color:var(--cyan)}
.facet-price input::placeholder{color:#6a86a8;font-size:12.5px}

/* ---------- Сортировка ----------
   Родная стрелка у select в тёмной теме почти не видна, рисуем свою.
   option оставляем со своим фоном: на Windows системный список иначе
   открывается белым по белому. */
.catalog-sort{position:relative;flex:0 0 auto}
.catalog-sort select{appearance:none;-webkit-appearance:none;padding:13px 40px 13px 15px;border:1px solid var(--line);
  border-radius:14px;background:#081f43;color:#dbe8fa;font-size:13px;font-weight:700;cursor:pointer;outline:none}
.catalog-sort select:focus{border-color:var(--cyan);box-shadow:0 0 0 3px rgba(69,187,255,.18)}
.catalog-sort option{background:#0b2852;color:#fff}
.catalog-sort:after{content:"";position:absolute;right:16px;top:calc(50% - 6px);width:7px;height:7px;
  border-right:2px solid #7f9bc0;border-bottom:2px solid #7f9bc0;transform:rotate(45deg);pointer-events:none}

/* ---------- Выбранное плашками ----------
   Нужны прежде всего на телефоне: панель там закрыта, и без плашек человек
   не видит, чем сузил выдачу, — короткий список читается как пустой каталог. */
.cat-chips{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:12px}
.cat-chips[hidden]{display:none}
.cchip{display:inline-flex;align-items:center;gap:7px;padding:7px 10px 7px 12px;border:1px solid #2f6aa5;
  border-radius:999px;background:rgba(69,187,255,.12);color:#dbe8fa;font-size:12px;font-weight:700;cursor:pointer}
.cchip i{font-style:normal;font-size:15px;line-height:1;color:#9fc3e6}
.cchip:hover{border-color:var(--cyan);color:#fff}

/* ---------- Кнопка «Фильтры» ---------- */
.cat-side-open{display:none;align-items:center;gap:9px;padding:13px 16px;border:1px solid var(--line);
  border-radius:14px;background:#081f43;color:#dbe8fa;font-size:13px;font-weight:800;cursor:pointer}
.cat-side-open svg{width:18px;height:18px;fill:none;stroke:#7f9bc0;stroke-width:1.9;stroke-linecap:round}
.cat-side-open-n{min-width:19px;height:19px;display:grid;place-items:center;padding:0 5px;border-radius:999px;
  background:var(--cyan);color:#05152e;font-size:11px;font-weight:900}
.cat-side-open-n[hidden]{display:none}

/* ---------- Телефон и планшет ----------
   Панель уезжает в выдвижной лист. Разметка та же: вторая копия фильтров
   означала бы два состояния, которые обязательно разойдутся. */
@media(max-width:980px){
  .cat-layout{grid-template-columns:minmax(0,1fr)}
  .cat-side-open{display:inline-flex}
  .cat-side{position:fixed;z-index:120;left:0;top:0;bottom:0;width:min(340px,88vw);display:flex;flex-direction:column;
    border-width:0 1px 0 0;border-radius:0 18px 18px 0;background:#08234b;transform:translateX(-102%);transition:transform .28s ease}
  .cat-side.is-open{transform:none;box-shadow:0 0 90px rgba(0,0,0,.6)}
  .cat-side-close{display:inline-grid;place-items:center;width:32px;height:32px;border:0;border-radius:50%;
    background:transparent;color:#cfe0f4;font-size:26px;line-height:1;cursor:pointer}
  .cat-side-scroll{flex:1 1 auto;max-height:none}
  .cat-side-foot{display:block;padding:12px 16px;border-top:1px solid #1d4576}
  .cat-side-foot .button{width:100%;padding:14px 18px}
  body.side-open{overflow:hidden}
  .cat-side-veil{position:fixed;z-index:110;inset:0;border:0;padding:0;background:rgba(2,10,24,.62)}
}
@media(max-width:720px){
  .catalog-tools{gap:8px}
  .cat-side-open{flex:0 0 auto;padding:12px 14px}
  .catalog-sort{flex:1 1 100%;order:3}
  .catalog-sort select{width:100%}
}
@media(prefers-reduced-motion:reduce){
  .cat-side{transition:none}
  .btile,.fchk-box,.facet>summary:after{transition:none}
}
/* ---------- Переключатель фасовки в карточке (chem23) ----------
   Карточка теперь одна на товар, а фасовки лежат в ней пилюлями. Раньше
   ActiveBase занимал четыре карточки подряд с одинаковым описанием.
   Ряд с переносом, а не с прокруткой: фасовок самое большее четыре, и
   горизонтальная прокрутка внутри карточки — это ловушка для пальца. */
.pc-vars{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.pc-var{padding:5px 10px;border:1px solid #2a5b8f;border-radius:8px;background:#081f43;
  color:#bacbe0;font-size:11.5px;font-weight:700;line-height:1.25;cursor:pointer;
  white-space:nowrap;font-variant-numeric:tabular-nums;transition:.18s}
.pc-var:hover{border-color:var(--cyan);color:#fff}
.pc-var.is-on{border-color:transparent;background:#f4f8ff;color:#09234a}
@media(prefers-reduced-motion:reduce){.pc-var{transition:none}}

/* Приписка под ценовым фильтром: часть каталога без цены в прайсе, и под
   любым диапазоном эти позиции выпадают. Молча — значит человек решит, что
   их нет вовсе. */
.facet-nprice{margin:9px 0 0;color:#7f96b6;font-size:11.5px;line-height:1.35}
.facet-nprice[hidden]{display:none}
/* ============================================================
   chem-brands + chem-faq (chem24 · 26.08.2026)

   Бренды: марок в каталоге три, а видно их было только внутри
   фильтра. Карточка — знак производителя, число позиций и одна
   честная строка о том, что именно у него берут. Кнопка не
   ссылка: она включает грань «Бренд» и прокручивает к сетке.
   Отдельного адреса у фильтра нет намеренно — три копии одного
   каталога в индексе не нужны.

   Вопросы: нативный <details>. Свой аккордеон здесь незачем —
   этот работает с клавиатуры и без JS, а поисковый робот видит
   текст ответа в разметке независимо от того, раскрыт он или нет.
   ============================================================ */
.chem-brands .section-heading{margin-bottom:28px}
.cb-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:16px}
.cb-card{display:flex;flex-direction:column;gap:12px;padding:24px;border:1px solid var(--line);
  border-radius:20px;background:linear-gradient(160deg,#0c2a56,#081f42)}
/* Знаки белые на прозрачном и разной ширины — выравниваем по левому краю,
   высота одна: ряд из трёх логотипов разного кегля читается как небрежность. */
.cb-mark{width:auto;height:22px;opacity:.85;align-self:flex-start}
.cb-n{margin:0;color:var(--cyan);font-size:12px;font-weight:900;letter-spacing:.08em;
  text-transform:uppercase;font-variant-numeric:tabular-nums}
.cb-card p:not(.cb-n){margin:0;color:#a8bcd8;font-size:14px;line-height:1.55}
.cb-go{margin-top:auto;align-self:flex-start;padding:10px 0;border:0;background:transparent;
  color:#dbe8fa;font-size:13px;font-weight:800;cursor:pointer;border-bottom:1px solid #2f6aa5}
.cb-go:hover{color:#fff;border-bottom-color:var(--cyan)}
.cb-go span{color:var(--cyan)}

.chem-faq .section-heading{margin-bottom:26px}
.cf-list{display:grid;gap:10px}
.cf-item{border:1px solid var(--line);border-radius:16px;background:rgba(9,35,74,.55);overflow:hidden}
.cf-item summary{display:flex;align-items:baseline;gap:14px;padding:18px 22px;list-style:none;cursor:pointer;
  font-size:16px;font-weight:800;line-height:1.35}
.cf-item summary::-webkit-details-marker{display:none}
/* Свой маркер: нативный треугольник на тёмном почти не виден, а плюс-минус
   сразу говорит, что блок раскрывается. */
.cf-item summary:before{content:"+";flex:0 0 auto;width:26px;height:26px;display:grid;place-items:center;
  border:1px solid var(--line);border-radius:8px;color:var(--cyan);font-size:15px;font-weight:900;line-height:1}
.cf-item[open] summary:before{content:"–"}
.cf-item summary span{flex:1 1 auto;min-width:0}
.cf-item summary:hover{color:#fff}
.cf-item summary:focus-visible{outline:2px solid var(--cyan);outline-offset:-2px}
.cf-item p{margin:0;padding:0 22px 20px 62px;color:#a8bcd8;font-size:14.5px;line-height:1.6;max-width:78ch}

@media(max-width:980px){
  .cb-grid{grid-template-columns:1fr 1fr}
}
@media(max-width:720px){
  .cb-grid{grid-template-columns:1fr}
  .cb-card{padding:20px}
  .cf-item summary{padding:16px;font-size:15px;gap:11px}
  /* На телефоне отступ под маркер съедает треть строки — ответ выравниваем
     по краю карточки, а не под текст вопроса. */
  .cf-item p{padding:0 16px 18px;font-size:14px}
}