/* =========================================================================
   Ceresit Shop v2 — дизайн-система из макета Claude Design «Ceresit Shop v2.dc.html».
   Пропущены: App shell (обвязка превью) и страница дизайн-системы (.ds*).
   ВАЖНО: адаптив на container queries и лежит В КОНЦЕ, после секции дизайн-системы —
   блок resp ниже это учитывает. Весь контент страницы обязан быть внутри .v2root.
   Обновлено: главная догнана до макета (hero-лента, колеровка, форма, FAQ, работы).
   ========================================================================= */

.v2root{ container-type:inline-size; }
  * { margin:0; padding:0; box-sizing:border-box; }
  :root{
    --teal:#17191c; --teal-d:#000000; --teal-l:#eef0f1;
    --red:#e4002b; --red-d:#c30026;
    --ink:#141a1c; --muted:#6b7679; --faint:#98a2a5;
    --line:#e7ebeb; --bg:#f2f5f5; --gold:#ffb400; --green:#1fa463;
    /* Шрифт сайта — Inter (подключение в чанке v2_head, Google Fonts).
       Фолбэки лежат ВНУТРИ переменной, а не рядом с ней: имя семейства подставляется
       и в сокращённую запись `font:700 11px/1 var(--font-body)` в двух десятках мест,
       где дописать запасные шрифты негде. Без них при недоступном Google Fonts
       эти подписи уехали бы в Times.
       ⚠️ Меняешь шрифт — меняй ОБА места: эти переменные и ссылку на Google Fonts
       в чанке v2_head (id 88). Поменяешь только переменную — браузер не найдёт
       семейство и молча возьмёт system-ui, а выглядеть будет «почти похоже».
       ⚠️ --fw-head=700 остался с IBM Plex Sans, у которого не было начертания 800.
       У Inter 800 есть, и по макету заголовки были 800. Вернуть жир — поднять
       --fw-head до 800 и добавить 800 в список весов в ссылке на Google Fonts. */
    --font-body:'Inter',system-ui,sans-serif;
    --font-head:'Inter',system-ui,sans-serif;
    --fs-h1:24px; --fs-h2:28px; --fs-h3:18px; --fs-body:15px;
    --fw-head:700; --ls-head:-.01em;
    /* ---- Сетка страницы: шесть значений, из которых собран весь сайт ----
       Раньше каждый блок носил свои числа: поля 12/16/24, зазоры 24/26/28/34/38,
       промежутки в сетках 8/9/10/12/14/20, скругления 7/9/10/11/12/14/16/18/20.
       Страница читалась как склейка нескольких макетов. Теперь — шесть рычагов,
       одинаковых на десктопе и на телефоне. */
    --pad-x:16px;      /* поля страницы слева и справа */
    --sec-gap:48px;    /* между блоками */
    --head-gap:20px;   /* от заголовка до его собственного блока */
    --gap-card:12px;   /* между карточками внутри блока */
    --r-card:12px;     /* скругление карточки */
    --r-block:16px;    /* скругление крупного блока-контейнера */
  }
  /* ⚠️ ФОН СТРАНИЦЫ БЕЛЫЙ — не менять на #e9edee при повторном переносе макета.
     #e9edee в .dc.html — это фон холста ВОКРУГ масштабируемой рамки превью, а сама
     страница внутри рамки белая (.frame{background:#fff}). Один раз уже утащили
     вместе с обвязкой, из-за чего весь сайт стоял серым. См. LESSONS.md, п. 21. */
  html{ background:#fff; }
  /* Страховка от «съехавшей» сетки: если какой-то блок случайно окажется шире экрана,
     страница не начнёт ездить вбок (а вместе с ней — все отступы). `clip` вместо
     `hidden` специально: он не создаёт контейнер прокрутки и не ломает sticky. */
  body{ overflow-x:clip; }
  body{ font-family:var(--font-body),system-ui,sans-serif; font-size:var(--fs-body); color:var(--ink); background:#fff; -webkit-font-smoothing:antialiased; font-variant-numeric:tabular-nums; }
  a{ color:var(--ink); text-decoration:none; }
  a:hover{ color:var(--red); }
  button{ font-family:inherit; cursor:pointer; border:none; background:none; }
  input,textarea{ font-family:inherit; }
  .ph{ background-color:#eef1f1; background-image:repeating-linear-gradient(135deg,#e6eaea 0 10px,#eef1f1 10px 20px); display:flex; align-items:center; justify-content:center; color:#9aa4a6; font:500 11px/1.3 ui-monospace,monospace; text-align:center; letter-spacing:.02em; }

  /* ---- Header ---- */
  .util{ display:none; background:var(--ink); color:#cfd6d6; font-size:13px; }
  .utilIn{ max-width:1244px; margin:0 auto; padding:8px 16px 8px 12px; display:flex; align-items:center; gap:20px; }
  .util a{ color:#cfd6d6; } .util a:hover{ color:#fff; }
  .utilSpacer{ flex:1; }
  /* Город — такой же пункт, как соседние: тот же кегль и вес, отличается только
     иконкой и белым цветом (это переключатель, а не ссылка раздела). */
  .cityBtn{ color:#fff; display:flex; align-items:center; gap:6px; font-size:13px; font-weight:400; margin-left:-2px; }
  /* Иконки взяты из пака Bowcaster (Figma): контур в нём ЗАЛИТ (fill-rule=evenodd),
     а не нарисован обводкой. Поэтому здесь fill:currentColor + stroke:none.
     Вернёте fill:none/stroke — иконки исчезнут или станут двойным контуром. */
  .cityBtn svg{ width:15px; height:15px; fill:currentColor; stroke:none; }

  .hdr{ border-bottom:1px solid var(--line); }
  .hdrIn{ max-width:1244px; margin:0 auto; padding:12px 16px; display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
  .burger{ display:inline-flex; flex-direction:column; gap:4px; padding:8px; border-radius:8px; }
  .burger span{ width:22px; height:2.5px; background:var(--ink); border-radius:2px; display:block; }
  .logo{ display:flex; align-items:baseline; gap:2px; font-weight:700; font-size:24px; letter-spacing:-.02em; color:var(--ink); }
  .logo b{ color:var(--ink); } .logo i{ color:var(--red); font-style:normal; }
  .logoTag{ display:none; font:600 11px/1.2 var(--font-body); color:var(--muted); border-left:1px solid var(--line); padding-left:12px; margin-left:4px; max-width:150px; }
  .catBtn{ display:none; align-items:center; gap:8px; background:var(--ink); color:#fff; font-weight:700; font-size:15px; padding:12px 20px; border-radius:10px; }
  .catBtn:hover{ background:#000; color:#fff; }
  .catBtn .bl{ display:flex; flex-direction:column; gap:4px; }
  .catBtn .bl span{ width:16px; height:2px; background:#fff; border-radius:2px; }
  .searchWrap{ order:3; flex-basis:100%; display:flex; }
  .search{ flex:1; display:flex; align-items:center; background:#fff; border:1.5px solid var(--line); border-radius:10px; overflow:hidden; }
  .searchInp{ flex:1; border:none; outline:none; padding:12px 16px 12px 0; font-size:15px; background:transparent; }
  .search:focus-within{ border-color:var(--muted); }
  .searchIco{ display:flex; align-items:center; padding:0 12px 0 16px; color:var(--faint); }
  .searchIco svg{ width:19px; height:19px; fill:currentColor; stroke:none; }
  .searchBtn{ background:var(--ink); color:#fff; padding:0 20px; align-self:stretch; display:flex; align-items:center; font-weight:700; }
  .searchBtn:hover{ background:#000; }
  .hdrActions{ margin-left:auto; display:flex; align-items:center; gap:6px; }
  .act{ display:none; flex-direction:column; align-items:center; gap:4px; padding:6px 8px; border-radius:10px; color:var(--muted); font:600 11px/1 var(--font-body); }
  .act:hover{ color:var(--ink); background:#f2f5f5; }
  .act .ico{ display:flex; align-items:center; justify-content:center; height:23px; }
  .act .ico svg, .cartBtn .ico svg{ width:23px; height:23px; fill:currentColor; stroke:none; }
  .cartBtn{ display:flex; flex-direction:column; align-items:center; gap:4px; padding:6px 8px; border-radius:10px; color:var(--muted); font:600 11px/1 var(--font-body); position:relative; }
  .cartBtn:hover{ color:var(--red); background:#fdeef1; }
  .cartBtn .ico{ display:flex; align-items:center; justify-content:center; height:23px; }
  .cartCount{ position:absolute; top:0; right:2px; background:var(--red); color:#fff; font:700 10px/1 sans-serif; min-width:16px; height:16px; padding:0 4px; border-radius:8px; display:flex; align-items:center; justify-content:center; }

  /* Строка категорий: не серая плашка, а просто линия-разделитель под меню.
     Плашка визуально спорила с шапкой и утяжеляла верх страницы. */
  .catbar{ display:none; background:transparent; border-bottom:1px solid var(--line); position:relative; }
  .catbarIn{ max-width:1244px; margin:0 auto; padding:0 16px; display:flex; gap:28px; overflow-x:auto; }
  /* padding 8/9 вместо 12/12 — пункты сидят выше, строка стала компактнее (46 → ~39px).
     Нижние 9px чуть больше верхних: под текстом проходит подчёркивание активного пункта. */
  .catlink{ color:var(--ink); font-weight:600; font-size:14px; padding:8px 0 8px; white-space:nowrap; border-bottom:3px solid transparent; }
  @container (max-width:699px){
    .hdrIn{ display:grid; grid-template-columns:auto 1fr auto; grid-template-areas:"burger logo cart"; align-items:center; column-gap:8px; }
    .burger{ grid-area:burger; margin-left:-8px; }
    .logo{ grid-area:logo; justify-self:center; font-size:21px; }
    .hdrActions{ grid-area:cart; margin-left:0; }
    .searchWrap{ display:none; }
    .cartBtn{ flex-direction:row; gap:8px; padding:4px 2px; }
    .cartLbl{ display:none; }
    .cartBtn .ico{ height:auto; }
    /* Иконка корзины остаётся одна, без подписи, — значит она должна читаться
       наравне с бургером слева: та же ширина (полоски бургера 22px) и близкая
       толщина линии, иначе правый край шапки выглядит легче левого. */
    .cartBtn .ico svg{ width:24px; height:24px; }
    .cartBtn{ padding:8px 4px; }
  }
  .mmOverlay{ position:fixed; inset:0; background:rgba(15,20,22,.5); z-index:60; display:flex; }
  .mmPanel{ background:#fff; width:min(340px,86vw); height:100%; display:flex; flex-direction:column; padding:20px; gap:16px; box-shadow:2px 0 40px rgba(0,0,0,.3); overflow-y:auto; }
  .mmTop{ display:flex; align-items:center; justify-content:space-between; }
  .mmTop .logo{ font-size:20px; }
  .mmClose{ width:38px; height:38px; border-radius:10px; font-size:17px; color:var(--muted); }
  .mmClose:hover{ background:#f2f5f5; color:var(--ink); }
  .mmSearch{ display:flex; align-items:center; background:#fff; border:1.5px solid var(--line); border-radius:10px; overflow:hidden; }
  .mmSearch:focus-within{ border-color:var(--muted); }
  .mmNav{ display:flex; flex-direction:column; border-top:1px solid var(--line); }
  .mmLink{ padding:16px 4px; font-weight:700; font-size:15px; color:var(--ink); border-bottom:1px solid var(--line); }
  .mmLink:hover{ color:var(--red); }
  .mmUtil{ display:flex; flex-direction:column; gap:12px; margin-top:auto; padding-top:8px; }
  .mmUtil a{ font-size:15px; color:var(--muted); font-weight:600; }
  .mmUtil a:hover{ color:var(--ink); }
  .mmPhone{ color:var(--ink) !important; font-size:17px; font-weight:700 !important; }
  .catlink:hover{ color:var(--red); border-color:var(--red); }

  /* «Скидки %» — единственный акцент в строке категорий: красный и прижат
     к правому краю. margin-left:auto съедает весь свободный остаток флекса,
     поэтому пункт уезжает в угол, а разделы остаются слева на своих местах;
     раскладку остальных ссылок это не трогает.
     Строка категорий скроллится по горизонтали (.catbarIn overflow-x:auto) —
     на узком окне свободного остатка нет, auto превращается в ноль, и «Скидки»
     просто встают последними в ленте прокрутки. Ломаться там нечему. */
  .catlink--sale{ margin-left:auto; color:var(--red); }
  .catlink--sale:hover{ color:var(--red-d); border-color:var(--red-d); }
  /* Тот же пункт в мобильном меню: там колонка, прижимать вправо нечем и незачем —
     от остальных его отличает только цвет. */
  .mmLink--sale{ color:var(--red); }

  /* ---- Generic ---- */
  .wrap{ max-width:1244px; margin:0 auto; padding:0 var(--pad-x); }
  @container (max-width:699px){ .wrap.page{ padding:16px var(--pad-x) 34px; } }
  .page{ padding:16px 0 40px; }
  .crumbs{ display:flex; flex-wrap:wrap; gap:6px; align-items:center; font-size:13px; color:var(--faint); padding:12px 0; }
  .crumbs a{ color:var(--muted); } .crumbs .sep{ color:#c8cfcf; }
  /* На телефоне крошки — одна строка с прокруткой, а не два этажа текста.
     Полосу прокрутки прячем: подсказка тут не нужна, палец и так листает.
     Стартовую позицию (конец строки, ближайший родитель) ставит v2.js —
     CSS этого не умеет. */
  @container (max-width:699px){
    .crumbs{ flex-wrap:nowrap; overflow-x:auto; scrollbar-width:none; -webkit-overflow-scrolling:touch; }
    .crumbs::-webkit-scrollbar{ display:none; }
    .crumbs > *{ flex:none; white-space:nowrap; }
  }
  .secHead{ display:flex; align-items:flex-end; justify-content:space-between; gap:16px; margin:var(--sec-gap) 0 var(--head-gap); }
  /* ЕДИНЫЙ вид заголовка блока — одно правило на всю страницу.
     Было четыре разных: .secHead h2 — 21px, дилер и преимущества — 34px
     (в широком контейнере), блок ролей — 36px по центру. Страница читалась как
     склейка из четырёх макетов. Теперь все берут одни и те же токены, и размер
     всех заголовков меняется в одном месте — --fs-h2.
     ⚠️ Правило стоит РАНЬШЕ описаний .distrib/.advBlock/.roles, поэтому там свои
     font-size/font-weight убраны совсем: иначе они перебьют это по правилу
     «при равной специфичности выигрывает тот, что ниже». */
  .secHead h2,
  .distrib h3,
  .advBlock__text h2,
  .roles__title{
    font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head);
    letter-spacing:var(--ls-head); line-height:1.25; text-align:left;
  }
  /* заголовок-ссылка: наследует вид h2 (тёмный, крупный), краснеет на наведении */
  .secHead h2 a{ color:inherit; }
  .secHead h2 a:hover{ color:var(--red); }
  /* правый CTA — единый стиль у всех разделов */
  .secHead .secMore{ font-size:13px; font-weight:600; color:var(--red); white-space:nowrap; flex:none; }
  h1.pTitle{ font-family:var(--font-head); font-size:var(--fs-h1); font-weight:var(--fw-head); letter-spacing:var(--ls-head); line-height:1.2; }

  /* ---- Home hero ---- */
  .heroGrid{ display:grid; grid-template-columns:1fr; gap:12px; margin-bottom:12px; margin-top:8px; align-items:stretch; }
  /* Фото баннера — локальное (img/hero-bg.jpg), не с боевого домена: сайт не зависит от внешней загрузки.
     Затемнение подняли (.80→.52 вместо .74→.40) — снимок светлый, на прежней вуали белый текст терялся. */
  .heroMain{ position:relative; border-radius:var(--r-block); overflow:hidden; height:340px; background:linear-gradient(120deg,rgba(18,20,24,.80),rgba(4,6,8,.52)), url('/img/hero-bg.jpg') center/cover; color:#fff; padding:28px; display:flex; flex-direction:column; justify-content:flex-start; }
  /* кегль/трекинг уменьшены и nowrap — надпись «официальный дилер … с 2007 года» держится в одну строку и на узком hero */
  .heroMain .eyebrow{ font:700 10px/1.2 var(--font-body); letter-spacing:.08em; text-transform:uppercase; color:#fff; opacity:.7; white-space:nowrap; }
  /* Страховка от nowrap. Внутренняя ширина баннера = экран − 32 (поля страницы) − 56
     (padding героя): на 375 это 287px, и надстрочник занимал ровно 287 — впритык.
     На узких экранах (320—360, SE и старые Android) он выезжал за карточку и тащил
     горизонтальную прокрутку ВСЕЙ страницы. Там разрешаем перенос: две строки мелкой
     подписи лучше, чем съехавший вбок сайт. */
  @container (max-width:369px){ .heroMain .eyebrow{ white-space:normal; } }
  .heroMain h1, .heroMain h2{ font-size:20px; font-weight:700; line-height:1.1; margin:12px 0; max-width:20ch; letter-spacing:-.01em; }
  .heroMain p{ opacity:.85; max-width:40ch; font-size:13px; }
  .heroBottom{ margin-top:auto; padding-top:16px; display:flex; align-items:flex-end; justify-content:space-between; gap:12px; }
  .heroBtn{ align-self:flex-start; background:var(--red); color:#fff; font-weight:700; padding:12px 24px; border-radius:10px; font-size:15px; }
  /* Наведение на ЛЮБУЮ красную кнопку сайта: фон становится чёрным, текст остаётся
     белым. Ни теней, ни подъёма. Так же ведут себя .addBtn, .bbAdd, .submitBtn,
     .navBtn, .rvSend, .rvSideBtn, .authBtn, .rolesCta, .kBtn.red и кнопки в блоках
     колеровки и новости — правило одно и то же, менять их надо все разом.
     `--red-d` больше не участвует в наведении, он остался цветом ТЕКСТА на розовых
     плашках (.save, .saveTag, .coError, .rvMsg--err) — там его не трогать. */
  .heroBtn:hover{ background:var(--ink); color:#fff; }
  @container (max-width:699px){ .heroBtn{ padding:10px 16px; font-size:12px; border-radius:9px; } }
  .heroLeft{ display:flex; flex-direction:column; position:relative; }
  .heroDots{ display:flex; gap:8px; justify-content:center; padding:12px 0 2px; }
  .heroDots i{ width:8px; height:8px; border-radius:50%; background:rgba(255,255,255,.45); cursor:pointer; transition:all .2s ease; }
  .heroDots i[data-on="true"]{ background:#fff; width:22px; border-radius:4px; }
  @container (max-width:699px){
    .heroDots i{ background:#c3cbcb; }
    .heroDots i[data-on="true"]{ background:var(--ink); }
  }
  /* ---- Hero 3D: пирог утепления фасада ---- */
  /* Класс .is3d ставит САМ виджет, когда сцена собралась. До этого (и навсегда, если
     нет WebGL2 или модуль упал) баннер остаётся прежней фотографией. Так «не завелось»
     выглядит как обычный баннер, а не как чёрная дыра на первом экране. */
  /* Фон .heroMain НЕ переопределяем: под холстом остаётся фотография — она фолбэк
     на случай, когда WebGL2 недоступен и класс .is3d так и не появится.
     Проявления у холста нет намеренно: сцена собирается СИНХРОННО, до первой
     отрисовки страницы, поэтому подменять на экране нечего — 3D там с самого начала. */
  .hero3dCanvas{ position:absolute; inset:0; width:100%; height:100%; display:block; z-index:0;
    /* Холст НЕ ловит касания. Баннер занимает пол-экрана телефона, и если отдать
       ему жесты — палец по нему не пролистает страницу (LESSONS.md, п. 24). */
    pointer-events:none; touch-action:pan-y; }

  /* Вуаль под текстом + виньетка по углам.
     Вуаль: короед светлый, белый заголовок на нём без затемнения не читается.
     На десктопе она горизонтальная (текст слева), на мобильной — вертикальная (текст сверху).
     Виньетка: тот самый «снято на макет» с референсов — кадр гаснет к краям, взгляд
     остаётся на предмете. Дешевле любого постпроцессинга и не стоит ни одного кадра. */
  .heroMain.is3d::before{ content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
    background:
      radial-gradient(120% 92% at 62% 44%, rgba(5,7,11,0) 34%, rgba(5,7,11,.34) 74%, rgba(4,5,9,.72) 100%),
      linear-gradient(180deg,rgba(5,7,11,.92) 0%,rgba(5,7,11,.80) 34%,rgba(5,7,11,.26) 56%,rgba(5,7,11,0) 74%); }
  .heroMain.is3d > *:not(.hero3dCanvas){ position:relative; z-index:3; }
  .heroMain.is3d .heroBottom{ margin-top:16px; }

  @container (max-width:699px){
    .heroMain.is3d{ height:470px; }
    /* Кнопка прижата к НИЗУ карточки. Два следствия, оба заказаны:
       1) отступ под кнопкой равен отступу над надстрочником — это padding:28px
          самого .heroMain, никаких добавок;
       2) между абзацем и кнопкой освобождается полоса, в неё и встаёт 3D-пирог
          (его вертикаль задаётся в assets/hero3d/src/app.js, VIEW.mobile.shift[1]).
       Правило намеренно перебивает `.heroMain.is3d .heroBottom{margin-top:16px}`
       выше по файлу — то значение оставлено для планшета. */
    .heroMain.is3d .heroBottom{ margin-top:auto; padding-top:0; }
  }

  .promoBox{ display:flex; flex-direction:column; min-width:0; }
  .promoBox > .promoCol{ flex:1; }
  .promoCol{ display:grid; grid-template-columns:1fr 1fr; gap:var(--gap-card); }
  .promoTile{ scroll-snap-align:start; }
  @container (max-width:699px){
    .promoCol{ display:flex; overflow-x:auto; gap:var(--gap-card); scroll-snap-type:x proximity; padding-bottom:6px; }
    .promoCol .promoTile{ flex:0 0 calc((100% - 10px) / 2); padding:16px; gap:8px; }
    .promoCol .promoIco{ width:34px; height:34px; }
    .promoCol .promoTile b{ font-size:14px; } .promoCol .promoTile span{ font-size:12px; }
  }
  /* Содержимое прижато к ВЕРХУ. Центрирование пробовали — при разной длине
     описаний иконки в соседних плитках оказывались на разной высоте и строчки
     не выравнивались между собой. Верхний край важнее, чем пустота снизу. */
  .promoTile{ border-radius:var(--r-card); padding:20px; display:flex; flex-direction:column; align-items:flex-start; justify-content:flex-start; gap:12px; border:1px solid var(--line); background:#fff; transition:all .15s ease; }
  /* Наведение — как у всех карточек сайта: рамка чернеет, снизу появляется тень. */
  .promoTile:hover{ border-color:var(--ink); box-shadow:0 10px 24px -8px rgba(20,26,28,.35); }
  /* Серая подложка под иконкой — та же, что у остальных плашек-заглушек. */
  .promoIco{ height:44px; width:44px; border-radius:10px; flex:none;
    background:var(--teal-l); display:flex; align-items:center; justify-content:center; }
  .promoIco img{ width:24px; height:24px; display:block; }
  .promoTile b{ font-size:17px; font-weight:700; }
  .promoTile span{ font-size:13px; color:var(--muted); }
  .promoTile .tag{ align-self:flex-start; font:700 11px/1 var(--font-body); padding:6px 8px; border-radius:6px; background:var(--red); color:#fff; }

  /* ---- News ---- */
  .newsStrip{ display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:12px; margin-top:20px; }
  .newsItem{ display:flex; gap:12px; align-items:flex-start; background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:16px 16px; }
  .newsItem .nb{ flex:1; }
  .newsItem .nd{ font:700 11px/1.4 var(--font-body); color:var(--faint); flex:none; white-space:nowrap; }
  .newsItem p{ font-size:13px; line-height:1.5; margin-top:4px; }
  .newsTag{ font:700 10px/1 sans-serif; letter-spacing:.1em; text-transform:uppercase; color:var(--red); }

  /* ---- Fasad intro ---- */
  .fasadIntro{ background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:24px; margin-top:24px; font-size:15px; line-height:1.7; color:#37413f; }
  .fasadIntro b{ color:var(--ink); }

  /* ---- Kolerovka picker ---- */
  .kolerovka{ display:grid; grid-template-columns:1fr; gap:24px; margin-top:16px; align-items:start; }
  .kPreview{ border:1px solid var(--line); border-radius:var(--r-block); overflow:hidden; background:#fff; }
  .kRoof{ height:30px; background:#1c1f22; }
  .kWall{ height:220px; padding:16px; display:flex; align-items:flex-start; transition:background .2s ease; }
  .kBase{ height:64px; transition:background .2s ease; }
  .kTag{ background:rgba(0,0,0,.55); color:#fff; font:600 11px/1 var(--font-body); padding:6px 12px; border-radius:6px; }
  .kControls{ display:flex; flex-direction:column; gap:6px; }
  .kLabel{ font-size:15px; font-weight:700; margin-top:6px; }
  .swatchRow{ display:flex; flex-wrap:wrap; gap:12px; align-items:flex-start; }
  @container (max-width:699px){
    .swatchRow{ flex-wrap:nowrap; overflow-x:auto; scroll-snap-type:x proximity; gap:10px; padding-bottom:8px; }
    .swatchRow > .swatch{ flex:none; scroll-snap-align:start; }
    .swatchRow > .swMore{ flex:none; align-self:center; white-space:nowrap; }
  }
  .swatch{ display:flex; flex-direction:column; align-items:center; gap:6px; cursor:pointer; }
  .swatch .sw{ width:52px; height:52px; border-radius:10px; border:2px solid var(--line); display:flex; align-items:center; justify-content:center; }
  .swatch[data-on="true"] .sw{ border-color:var(--ink); }
  .swatch .dot{ display:none; width:14px; height:14px; border-radius:50%; background:#fff; box-shadow:0 0 0 2px rgba(0,0,0,.5); }
  .swatch[data-on="true"] .dot{ display:block; }
  .swatch span{ font-size:11px; color:var(--muted); }
  .swMore{ align-self:center; font-size:13px; font-weight:700; color:var(--red); padding-top:16px; }
  .kActions{ display:flex; flex-wrap:wrap; gap:12px; margin-top:8px; }
  .kBtn{ font-weight:700; font-size:15px; padding:16px 24px; border-radius:10px; color:#fff; }
  .kBtn.dark{ background:var(--ink); } .kBtn.dark:hover{ background:#000; }
  .kBtn.red{ background:var(--red); } .kBtn.red:hover{ background:var(--ink); color:#fff; }
  .helpBox{ margin-top:6px; }
  .helpBox h4{ font-size:15px; } .helpBox p{ font-size:13px; color:var(--muted); line-height:1.6; margin-top:6px; }
  .helpBox .disc{ margin-top:12px; font-weight:700; color:var(--ink); } .helpBox .disc b{ color:var(--red); }
  .author{ display:flex; gap:16px; align-items:flex-start; background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:20px; margin-top:16px; }
  .author .av{ width:72px; height:72px; border-radius:50%; flex:none; }
  .author b{ font-size:15px; } .author .role{ font-size:13px; color:var(--faint); }
  .author p{ font-size:13px; color:#37413f; line-height:1.6; margin-top:8px; }

  /* ---- Categories ---- */
  .catsGrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); gap:var(--gap-card); }
  .catCard{ background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:16px; display:flex; gap:16px; align-items:flex-start; transition:all .15s ease; }
  .catCard:hover{ border-color:var(--ink); box-shadow:0 8px 22px -14px rgba(20,26,28,.4); transform:translateY(-2px); }
  .catIco{ width:72px; height:72px; border-radius:10px; flex:none; }
  .catCard .ct{ flex:1; }
  .catCard b{ font-size:15px; font-weight:700; display:block; margin-bottom:4px; }
  .catCard span{ font-size:13px; color:var(--faint); line-height:1.45; }
  .catCard .arr{ color:var(--red); font-size:17px; }

  /* ---- Product cards ---- */
  .prodRow{ display:flex; gap:12px; overflow-x:auto; scroll-snap-type:x proximity; padding-bottom:6px; }
  .prodRow > .card{ flex:0 0 210px; scroll-snap-align:start; }
  .scrollBox{ position:relative; }
  .scrollArrow{ position:absolute; top:calc(50% - 30px); width:40px; height:40px; border-radius:50%; background:#fff; border:1px solid var(--line); box-shadow:0 3px 12px rgba(20,25,27,.14); color:var(--ink); display:none; align-items:center; justify-content:center; z-index:3; }
  .scrollArrow svg{ width:20px; height:20px; fill:currentColor; stroke:none; }
  .scrollArrow:hover{ border-color:var(--ink); background:var(--ink); color:#fff; }
  .scrollArrow.prev{ left:-14px; } .scrollArrow.next{ right:-14px; }
  .scrollBox[data-prev="true"] > .scrollArrow.prev{ display:flex; }
  .scrollBox[data-next="true"] > .scrollArrow.next{ display:flex; }
  @container (max-width:699px){ .scrollArrow{ width:34px; height:34px; top:calc(50% - 40px); } .scrollArrow.prev{ left:-4px; } .scrollArrow.next{ right:-4px; } }
  /* Карточка товара БЕЗ обводки (убрана по просьбе). Границу теперь держат воздух
     между карточками и фото; на наведении остаётся тень с подъёмом. Рамку не
     заменяем прозрачной: padding 12px и так даёт нужный отступ, а лишний 1px по
     кругу забирал ширину у строки цен (см. расчёт ниже). */
  /* Контур у карточки товара — такой же, как у карточки раздела (.catCard выше):
     обычная линия --line, на наведении она чернеет до --ink и добавляется тень
     с подъёмом. Значения намеренно совпадают с .catCard один в один: карточки
     разделов и товаров стоят на одной странице и не должны вести себя по-разному. */
  .card{ background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:12px; display:flex; flex-direction:column; gap:var(--gap-card); position:relative; transition:all .15s ease; }
  /* ⚠️ Карточку товара на наведении НЕ поднимаем, в отличие от .catCard.
     Причина: ленты товаров (.prodRow) прокручиваются по горизонтали, а
     `overflow-x:auto` заставляет браузер обрезать и по вертикали тоже. Подъём
     на 2px срезал карточке верхнюю кромку — контур переставал читаться целиком.
     Вместо подъёма — тень, уходящая ВНИЗ: смещение 10px больше половины размытия,
     поэтому вверх она не выступает и обрезать там нечего. */
  .card:hover{ border-color:var(--ink); box-shadow:0 10px 24px -8px rgba(20,26,28,.35); }
  .cardImg{ width:100%; aspect-ratio:1/1; border-radius:10px; object-fit:cover; display:block; }
  .badge{ position:absolute; top:16px; left:16px; font:700 10.5px/1 var(--font-body); letter-spacing:.03em; padding:6px 8px; border-radius:6px; color:#fff; }
  .badge.hit{ background:var(--red); } .badge.new{ background:var(--ink); } .badge.sale{ background:var(--red); }
  .fav{ display:none; }  /* избранное убрано по просьбе — сердечко скрыто на всех экранах */
  .fav:hover{ color:var(--red); background:#fdeef1; }
  .cardName{ font-size:13px; font-weight:600; line-height:1.35; color:var(--ink); }
  .cardName:hover{ color:var(--red); }
  .cardMeta{ display:flex; align-items:center; gap:8px; font-size:13px; color:var(--faint); }
  .stars{ color:var(--red); letter-spacing:1px; font-size:13px; }
  /* Цена и старая цена — ВСЕГДА в одну строку. Кегли подобраны под худший случай
     «88 888 ₽ + 88 888 ₽» фолбэк-шрифтом (он шире IBM Plex) в самой узкой карточке.
     Десктоп/каталог: карточка min 200px → 174px внутри; 86 + 8 + 56.4 = 150.4 ✓ */
  .priceRow{ display:flex; align-items:baseline; gap:8px; flex-wrap:nowrap; min-width:0; }
  .price{ font-size:20px; font-weight:700; color:var(--ink); white-space:nowrap; }
  .price i{ font-style:normal; font-size:13px; color:var(--muted); font-weight:600; }
  .oldPrice{ font-size:13px; color:var(--faint); text-decoration:line-through; white-space:nowrap; }
  /* кнопка занимает всю ширину карточки (внутри её отступов) */
  .buyRow{ display:flex; gap:8px; }
  .buyRow .ms2_form{ flex:1; min-width:0; }
  .buyRow .addBtn{ width:100%; }
  .addBtn{ flex:1; background:var(--red); color:#fff; font-weight:700; font-size:13px; padding:12px; border-radius:10px; display:flex; align-items:center; justify-content:center; gap:8px; transition:background .15s ease; }
  .addBtn:hover{ background:var(--ink); color:#fff; }
  .addBtn:active{ transform:translateY(1px); }
  .card > .cardThumb{ order:1; }
  /* Оценка слева, наличие справа — одной строкой прямо над кнопкой */
  .cardFoot{ display:flex; align-items:center; justify-content:space-between; gap:8px; }
  .cardFoot .cardMeta{ display:inline-flex; align-items:center; gap:6px; }
  .cardFoot .cardStock{ margin-left:auto; }
  .card > .cardMeta{ order:2; }
  .card > .priceRow{ order:3; }
  .card > .perLine{ order:4; }
  .card > .cardName{ order:5; }
  .card > .cardFoot{ order:6; margin-top:auto; padding-top:4px; }
  .card > .buyRow{ order:7; }
  @container (max-width:699px){
    .prodRow > .card{ flex:0 0 58%; min-width:0; padding:12px; gap:10px; }  /* ~1.7 карточки в кадре — видно, что можно листать */
    .card > .cardThumb{ order:1; }
    /* было: flex-wrap:wrap + price на всю ширину — старая цена уезжала на 2-ю строку */
    .card > .priceRow{ order:2; flex-wrap:nowrap; gap:6px; }
    .card > .cardName{ order:3; }
    .card > .perLine{ display:none; }
    .cardFoot{ font-size:12px; }
    .card > .cardMeta .stars{ letter-spacing:-1px; }
    .card > .cardMeta .revCnt{ display:none; }
    .card > .cardFoot{ order:5; margin-top:auto; font-size:12px; }  /* строка «оценка — наличие» прижата к низу */
    .card > .buyRow{ order:6; gap:10px; }
    /* Замеры в браузере (не на глаз): внутренняя ширина карточки 147px при экране
       375px и 119px при 320px. Пятизначная пара «20 000 ₽» + «17 000 ₽» на 17/11.5px
       просит 125px — с 375px влезает с запасом, на 320px нет. Поэтому ниже 360px
       отдельный шаг, см. следующий блок. */
    .card .price{ font-size:17px; }
    .card .oldPrice{ font-size:12px; }
    /* «В наличии» рвалось на две строки: строке нужно было 118px при доступных 119px.
       nowrap запрещает перенос, а точка и зазоры ужаты — так появляется реальный запас. */
    .card .cardFoot{ gap:6px; }
    .card .cardStock{ white-space:nowrap; font-size:12px; gap:6px; }
    .card .cardStock::before{ width:6px; height:6px; }
    .card .cardMeta .rvAvg{ font-size:12px; }
    /* мини-карточка: название ровно 2 строки с многоточием — высота предсказуема */
    .card .cardName{ font-size:14px; min-height:2.7em; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
    .card .cardMeta .stars{ font-size:14px; }
    .card .addBtn{ padding:12px 8px; font-size:14px; border-radius:10px; }
    .card .fav{ display:none; }
    .card > .buyRow{ flex-direction:column; gap:8px; }
    .card .fav:hover{ color:var(--red); border-color:var(--red); background:#fff; }
  }
  /* Узкие экраны (320–359px): в карточку шириной 119px пятизначная пара цен
     на прежнем кегле не помещается физически. Шаг вниз по кеглю — единственное,
     что оставляет обе цены в одной строке. С 360px работает основной размер. */
  @container (max-width:359px){
    .card .price{ font-size:15px; }
    .card .oldPrice{ font-size:11px; }
    .card .cardStock{ font-size:11px; }
    .card .cardMeta .rvAvg{ font-size:11px; }
    .card .cardMeta .stars,
    .card .cardMeta .rvStar{ font-size:13px; }
  }
  .cmpBtn{ width:42px; border:1px solid var(--line); border-radius:10px; color:var(--faint); display:flex; align-items:center; justify-content:center; font-size:17px; }
  .cmpBtn:hover{ border-color:var(--ink); color:var(--ink); }

  /* ---- Advantages ---- */
  .advStrip{ display:grid; grid-template-columns:repeat(auto-fill,minmax(150px,1fr)); gap:12px; margin-top:16px; }
  .advItem{ background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:16px; display:flex; gap:12px; align-items:center; }
  .advItem .ai{ width:44px; height:44px; border-radius:10px; background:var(--teal-l); color:var(--ink); display:flex; align-items:center; justify-content:center; font-size:20px; flex:none; }
  .advItem b{ font-size:13px; display:block; line-height:1.35; }

  /* ---- Help form ---- */
  .helpMain{ background:var(--ink); color:#cfd6d6; border-radius:var(--r-block); padding:28px; margin-top:24px; display:grid; grid-template-columns:1fr; gap:var(--gap-card); align-items:start; }
  .helpMain h2{ color:#fff; font-size:20px; line-height:1.2; }
  .helpMain .lead{ color:#fff; font-weight:700; margin-top:12px; }
  .helpMain p{ font-size:13px; line-height:1.7; margin-top:12px; }
  .formCard{ background:#0f1214; border:1px solid #2a3335; border-radius:var(--r-card); padding:20px; }
  @container (max-width:699px){ .formCard{ margin-left:-8px; margin-right:-8px; } }
  .formGrid{ display:grid; grid-template-columns:1fr; gap:12px; }
  .field{ display:flex; flex-direction:column; gap:6px; }
  .field label{ font-size:13px; color:#aeb8b8; }
  .field input,.field textarea{ background:#191d20; border:1px solid #2a3335; border-radius:10px; padding:12px 12px; color:#fff; font-size:15px; outline:none; }
  .field input:focus,.field textarea:focus{ border-color:#fff; }
  .field textarea{ min-height:74px; resize:vertical; }
  .checkRow{ display:flex; gap:8px; align-items:center; font-size:13px; color:#aeb8b8; }
  .checkRow input{ accent-color:var(--red); width:16px; height:16px; }
  .submitBtn{ margin-top:16px; width:100%; background:var(--red); color:#fff; font-weight:700; padding:12px; border-radius:10px; font-size:15px; }
  .submitBtn:hover{ background:var(--ink); color:#fff; }

  /* Шаг между пунктами формы — одинаковый во ВСЕХ формах заявки.
     Раньше его задавал только .formGrid, то есть форма на странице. В модалках
     (.rolForm > .v2form) сетки нет, и поля стояли вплотную: замер между «Имя» и
     «Телефон» давал 0px, до галочки согласия 2px, а кнопка липла к ней вплотную.
     Задаём шаг на самой форме, тогда он работает в любой обвязке. */
  .v2form{ display:grid; gap:14px; }
  .v2form .formGrid{ gap:14px; }
  .v2form > .checkRow{ margin-top:2px; }
  .v2form .submitBtn{ margin-top:10px; }   /* + шаг сетки = 24px от согласия */

  /* ---- Distributor ---- */
  /* Блок дилера: широкое фото стенда с образцами, под ним крупный заголовок
     слева и текст со списком справа. Была карточка в рамке с мелким заголовком —
     она читалась как сноска, хотя это главный блок про магазин. */
  .distrib{ margin-top:var(--sec-gap); }
  .distribPhoto{ width:100%; aspect-ratio:16/8; object-fit:cover; display:block; border-radius:var(--r-block); background:var(--teal-l); }
  .distribGrid{ display:grid; grid-template-columns:1fr; gap:var(--gap-card); margin-top:24px; }
  .distrib h4{ font-size:15px; font-weight:700; margin:16px 0 12px; }
  .distrib p{ color:var(--muted); font-size:13px; line-height:1.7; }
  /* список — обычными маркерами и в одну колонку: это перечисление, а не преимущества */
  .distribList{ padding-left:20px; display:grid; gap:8px; }
  .distribList li{ font-size:13px; line-height:1.55; color:#37413f; }
  .studioList{ list-style:none; display:grid; grid-template-columns:1fr; gap:8px; margin-top:6px; }
  .studioList li{ display:flex; gap:12px; font-size:13px; color:#37413f; line-height:1.5; }
  .studioList li::before{ content:'✓'; color:var(--red); font-weight:700; flex:none; }

  /* ---- FAQ ---- */
  .faqWrap{ display:grid; grid-template-columns:1fr; gap:24px; margin-top:16px; align-items:start; }
  .faqList{ display:flex; flex-direction:column; background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:4px 20px; }
  .faqItem{ border-bottom:1px solid var(--line); }
  .faqItem:last-child{ border-bottom:none; }
  .faqQ{ width:100%; display:flex; gap:16px; align-items:center; justify-content:space-between; text-align:left; padding:16px 2px; font-weight:700; font-size:15px; color:var(--ink); }
  /* Кружок «+» чёрный, а не красный: красный на сайте — цвет действия (кнопки
     «В корзину», «Заказать»), а раскрытие вопроса действием не является. */
  .faqQ .pm{ width:26px; height:26px; border-radius:50%; background:var(--ink); color:#fff; flex:none; display:flex; align-items:center; justify-content:center; font-size:17px; line-height:1; }
  .faqA{ padding:0 2px 16px; font-size:13px; color:var(--muted); line-height:1.7; }
  .calcTile{ position:relative; border-radius:var(--r-block); overflow:hidden; min-height:300px; }
  .calcTile .ph{ position:absolute; inset:0; }
  .calcTile .calcImg{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }
  .calcTile .cap{ position:absolute; left:0; right:0; bottom:0; padding:20px; background:linear-gradient(transparent,rgba(0,0,0,.75)); color:#fff; display:flex; align-items:center; justify-content:space-between; }
  .calcTile .cap span{ font-size:13px; opacity:.85; display:block; } .calcTile .cap b{ font-size:17px; }
  .calcTile .cap .arr{ font-size:20px; }

  /* ---- Works ---- */
  .worksHead{ display:flex; align-items:center; gap:16px; }
  .worksHead .div{ width:1px; height:22px; background:var(--line); }
  .worksGrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(180px,1fr)); gap:var(--gap-card); }
  .workCard{ position:relative; border-radius:var(--r-card); overflow:hidden; }
  .workCard .ph{ aspect-ratio:4/3; }
  .workCard img{ width:100%; aspect-ratio:4/3; object-fit:cover; display:block; }
  .workCard .wc{ position:absolute; left:0; right:0; bottom:0; padding:12px 16px; background:linear-gradient(transparent,rgba(0,0,0,.7)); color:#fff; font-size:13px; font-weight:600; }

  .seo{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block); padding:24px; margin-top:var(--sec-gap); color:var(--muted); font-size:13px; line-height:1.7; }
  .seo h3{ font-family:var(--font-head); font-size:var(--fs-h3); color:var(--ink); font-size:17px; margin-bottom:12px; }
  .seo p{ margin-bottom:12px; }

  /* ---- Catalog ---- */
  .catTop{ display:flex; flex-direction:column; gap:12px; margin-bottom:16px; }
  /* line-height обязателен: без него h1 берёт `normal` и стоит выше, чем h1.pTitle
     на карточке товара. Оба заголовка должны читаться одинаково — см. п.179. */
  .catTop h1{ font-family:var(--font-head); font-size:var(--fs-h1); font-weight:var(--fw-head); letter-spacing:var(--ls-head); line-height:1.2; }
  /* 4px отступа от заголовка: без него строка «Найдено N товаров» вплотную
     подпирает h1 — h1 внутри .catTop лежит в общем div, и gap флекса между
     ними не работает (правка 13.08.2026). */
  .catTop .cnt{ font-size:13px; color:var(--faint); margin-top:4px; }

  /* Подпись ошибки под полем оформления заказа (13.08.2026). Раньше причина
     писалась одной строкой у кнопки: на телефоне она оставалась за экраном,
     человек видел только красную рамку и не понимал, что править. */
  .coErrMsg{ display:block; margin-top:6px; font-style:normal; font-size:12.5px;
    line-height:1.4; color:var(--red); font-weight:600; }
  .optCard .coErrMsg, .agree .coErrMsg{ margin-top:8px; }
  /* Мобильная панель управления выдачей: две кнопки в одну строку —
     слева «Сортировка», справа «Фильтр». Ниже сразу товары.
     На планшете/десктопе не нужна: там слева живёт сайдбар фильтров,
     а сортировка стоит строкой чипов над сеткой (см. блок >=700). */
  .catTools{ display:grid; grid-template-columns:1fr 1fr; gap:12px; }
  .catTool{ display:flex; align-items:center; justify-content:center; gap:8px; border:1px solid var(--ink); background:#fff; color:var(--ink); font-weight:700; padding:12px; border-radius:10px; font-size:15px; }
  .catTool[aria-expanded="true"]{ background:var(--ink); color:#fff; }
  .catLayout{ display:grid; grid-template-columns:1fr; gap:20px; align-items:start; }
  .sidebar{ display:none; background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:4px 16px 16px; }
  .catLayout[data-open="true"] .sidebar{ display:block; }
  .fGroup{ border-bottom:1px solid var(--line); padding:16px 0; }
  .fGroup:last-child{ border-bottom:none; }
  /* Последний блок фильтров стоит НЕ последним ребёнком — за ним идёт .fFoot со
     «Сбросить фильтры». Поэтому :last-child его не ловил, и над кнопкой рисовались
     ДВЕ линии в 4px друг от друга: своя у блока и border-top у .fFoot. Линию оставляем
     одну — ту, что у .fFoot, и только когда «Сбросить» показана. */
  .fGroup:has(+ .fFoot){ border-bottom:none; }
  .fTitle{ font-size:15px; font-weight:700; margin-bottom:12px; display:flex; justify-content:space-between; align-items:center; }
  .fTitle span{ color:var(--faint); font-size:17px; }
  .fOpt{ display:flex; align-items:center; gap:8px; padding:6px 0; font-size:13px; color:#37413f; cursor:pointer; }
  .fOpt input{ width:17px; height:17px; accent-color:var(--ink); }
  .fOpt .fc{ margin-left:auto; color:var(--faint); font-size:13px; }
  .priceInputs{ display:flex; align-items:center; gap:8px; }
  .priceInputs input{ width:100%; border:1px solid var(--line); border-radius:8px; padding:8px 12px; font-size:13px; outline:none; }
  .priceInputs input:focus{ border-color:var(--ink); }
  /* Проценты положения ручек в макете были зашиты (14% / 33%) — там это была картинка.
     Теперь ручки настоящие: положение им проставляет JS каталога, поэтому фиксированных
     значений здесь быть не должно. touch-action:none — чтобы на телефоне перетаскивание
     ручки не перехватывалось прокруткой страницы. */
  .priceRange{ height:4px; background:var(--line); border-radius:2px; margin:16px 8px 0; position:relative; }
  .priceRange i{ position:absolute; height:4px; left:0; right:0; background:var(--ink); border-radius:2px; }
  .priceRange b{ position:absolute; width:16px; height:16px; top:-6px; margin-left:-8px; background:#fff; border:3px solid var(--ink); border-radius:50%; cursor:grab; touch-action:none; }
  .priceRange b:active{ cursor:grabbing; }
  .applyF{ width:100%; margin-top:16px; background:var(--ink); color:#fff; font-weight:700; padding:12px; border-radius:10px; font-size:13px; }
  .applyF:hover{ background:#000; }

  .sortBar{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:8px 12px; margin-bottom:16px; }
  /* На мобильной строка сортировки — выпадающая: её открывает кнопка «Сортировка».
     Иначе три чипа занимали бы две строки над каждой выдачей. */
  .sortBar[data-open="false"]{ display:none; }
  .sortLbl{ font-size:13px; color:var(--faint); }
  .sortChip{ padding:8px 12px; border-radius:8px; font-size:13px; font-weight:600; color:var(--muted); background:#f2f5f5; }
  .sortChip[data-on="true"]{ background:var(--ink); color:#fff; }
  .sortChip:hover{ color:var(--ink); }
  /* Мобильная сетка каталога — РОВНО 2 карточки в ряд (auto-fill с minmax(200px)
     на экране 375px давал одну колонку). С 700px возвращаем авторазмер. */
  .catGrid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }
  .pager{ display:flex; gap:6px; justify-content:center; margin-top:28px; }
  .pg{ min-width:38px; height:38px; border-radius:10px; border:1px solid var(--line); display:flex; align-items:center; justify-content:center; font-size:13px; font-weight:600; color:var(--muted); }
  .pg[data-on="true"]{ background:var(--ink); color:#fff; border-color:var(--ink); }
  .pg:hover{ border-color:var(--ink); }

  /* ---- PDP ---- */
  .pdp{ display:grid; grid-template-columns:1fr; gap:24px; align-items:start; margin-top:8px; }
  .gallery{ display:grid; grid-template-columns:1fr; gap:12px; }
  .thumbs{ display:flex; flex-direction:row; gap:12px; order:2; overflow-x:auto; }
  .thumb{ width:64px; height:64px; border-radius:8px; border:1px solid var(--line); overflow:hidden; }
  .thumb[data-on="true"]{ border-color:var(--ink); }
  .mainImg{ width:100%; aspect-ratio:1/1; border-radius:var(--r-card); object-fit:cover; display:block; }
  .pInfo{ display:flex; flex-direction:column; gap:16px; }
  .pMetaRow{ display:flex; flex-wrap:wrap; gap:16px; align-items:center; font-size:13px; color:var(--faint); }
  .pMetaRow .stars{ font-size:15px; }
  .inStock{ color:var(--green); font-weight:700; display:inline-flex; align-items:center; gap:6px; }
  .buyBox{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block); padding:20px; display:flex; flex-direction:column; gap:16px; }
  .bbPrice{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
  .bbPrice .big{ font-size:28px; font-weight:700; }
  .bbPrice .unit{ font-size:13px; color:var(--muted); font-weight:600; }
  .bbPrice .old{ font-size:17px; color:var(--faint); text-decoration:line-through; }
  .bbPrice .save{ font:700 12px/1 var(--font-body); background:#fdeef1; color:var(--red-d); padding:6px 8px; border-radius:6px; }
  .bbActions{ display:flex; gap:12px; align-items:stretch; }
  .qty{ display:flex; align-items:center; border:1px solid var(--line); border-radius:10px; overflow:hidden; }
  .qty button{ width:42px; align-self:stretch; font-size:20px; color:var(--muted); }
  .qty button:hover{ background:#f2f5f5; color:var(--ink); }
  .qty span{ width:44px; text-align:center; font-weight:700; font-size:15px; }
  .bbAdd{ flex:1; background:var(--red); color:#fff; font-weight:700; font-size:15px; border-radius:10px; display:flex; align-items:center; justify-content:center; gap:8px; padding:16px; }
  .bbAdd:hover{ background:var(--ink); color:#fff; }
  .bbAdd:active{ transform:translateY(1px); }
  .bbSecondary{ display:flex; gap:12px; }
  .bbGhost{ flex:1; border:1px solid var(--line); border-radius:10px; padding:12px; font-weight:700; font-size:13px; color:var(--muted); display:flex; align-items:center; justify-content:center; gap:8px; }
  .bbGhost:hover{ border-color:var(--ink); color:var(--ink); }
  .delivery{ border-top:1px dashed var(--line); padding-top:16px; display:flex; flex-direction:column; gap:12px; }
  .delRow{ display:flex; gap:12px; font-size:13px; }
  .delRow .di{ color:var(--ink); font-size:17px; flex:none; }
  .delRow b{ font-weight:700; } .delRow span{ color:var(--muted); }

  /* Боковых паддингов у вкладки нет, разводит их gap: тогда «Описание» стоит ровно
     на той же левой линии, что и текст под ним, а красное подчёркивание активной
     вкладки равно ширине слова, а не слову плюс воздух. */
  .tabsBar{ display:flex; gap:28px; border-bottom:1px solid var(--line); margin-top:8px; overflow-x:auto; }
  .tabBtn{ padding:12px 0; font-weight:700; font-size:15px; color:var(--muted); border-bottom:3px solid transparent; white-space:nowrap; }
  .tabBtn[data-on="true"]{ color:var(--ink); border-color:var(--red); }
  .tabBtn:hover{ color:var(--ink); }
  .pdpTabs{ min-width:0; margin-top:28px; }
  .specTable{ width:100%; border-collapse:collapse; margin-top:20px; }
  .specTable tr{ border-bottom:1px solid var(--line); }
  .specTable td{ padding:12px 4px; font-size:13px; vertical-align:top; }
  .specTable td:first-child{ color:var(--muted); width:52%; }
  .specTable td:last-child{ font-weight:600; }
  .docList{ display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:12px; margin-top:20px; }
  .doc{ display:flex; align-items:center; gap:12px; border:1px solid var(--line); border-radius:var(--r-card); padding:12px 16px; }
  .doc .dico{ width:38px; height:44px; border-radius:6px; background:#fdeef1; color:var(--red); display:flex; align-items:center; justify-content:center; font:700 10px/1 sans-serif; flex:none; }
  .doc b{ font-size:13px; display:block; } .doc span{ font-size:13px; color:var(--faint); }
  .doc .dl{ margin-left:auto; color:var(--ink); font-size:17px; }
  .reviews{ display:flex; flex-direction:column; gap:16px; margin-top:20px; }
  .revSummary{ display:flex; gap:20px; align-items:center; flex-wrap:wrap; background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:16px 20px; }
  .revBig{ font-size:28px; font-weight:700; line-height:1; }
  .review{ border:1px solid var(--line); border-radius:var(--r-card); padding:16px; }
  .revHead{ display:flex; align-items:center; gap:12px; margin-bottom:8px; }
  .revAva{ width:36px; height:36px; border-radius:50%; background:var(--teal-l); color:var(--ink); display:flex; align-items:center; justify-content:center; font-weight:700; font-size:15px; }
  .review b{ font-size:13px; } .review .rd{ font-size:13px; color:var(--faint); }
  .review p{ font-size:13px; color:#37413f; line-height:1.6; margin-top:6px; }

  /* ---- Footer ---- */
  .footer{ background:var(--ink); color:#aeb8b8; margin-top:8px; }
  .footIn{ max-width:1244px; margin:0 auto; padding:36px 20px 20px; }
  .fcols{ display:grid; grid-template-columns:1fr 1fr; gap:28px 20px; }
  /* h2, а не h3 и не h4. Подвал есть на КАЖДОЙ странице, и на тех, где в тексте
     нет ни одного h2, его заголовки оказывались первыми после h1 — получался
     пропуск уровня. С h2 порядок верный везде. Все три тега в селекторе, чтобы
     вид не зависел от того, каким тегом заголовок написан; размер задан здесь. */
  .fcol h2, .fcol h3, .fcol h4{ color:#fff; font-size:15px; margin-bottom:12px; }
  .fcol a{ display:block; color:#aeb8b8; font-size:13px; padding:6px 0; }
  .fcol a:hover{ color:#fff; }
  .fsoc{ display:flex; gap:8px; margin-top:12px; }
  .fsoc i{ width:34px; height:34px; border-radius:8px; background:#2a3335; display:flex; align-items:center; justify-content:center; color:#cfd6d6; font-size:15px; }
  .footBottom{ border-top:1px solid #2a3335; margin-top:28px; padding-top:20px; display:flex; flex-wrap:wrap; gap:12px; justify-content:space-between; font-size:13px; color:#7d8888; }
  .pays{ display:flex; gap:8px; } .pays i{ width:40px; height:26px; border-radius:4px; background:#2a3335; display:flex; align-items:center; justify-content:center; font:700 8px/1 sans-serif; color:#aeb8b8; }

  /* ---- PDP v2 ---- */
  .pdp2{ display:grid; grid-template-columns:1fr; gap:24px; margin-top:8px; align-items:start; }
  .mainWrap{ min-width:0; order:1; }
  .attrCol{ min-width:0; }
  /* Подпись и выбранное значение — одной строкой: «Цвет  База», а не в два этажа */
  .fHead{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; margin:0 0 8px; }
  .fLabel{ font-size:13px; color:var(--muted); }
  .fVal{ font-weight:700; font-size:15px; }
  .attrBlock{ margin-top:20px; }
  .fchips{ display:flex; gap:12px; }
  .fchip{ border:1px solid var(--line); border-radius:10px; padding:12px 20px; font-weight:700; font-size:15px; color:var(--ink); background:#fff; }
  .fchip[data-on="true"]{ border-color:var(--ink); box-shadow:none; }
  .colorRow{ display:flex; gap:12px; flex-wrap:wrap; }
  .cSw{ width:46px; height:46px; border-radius:10px; border:1px solid var(--line); }
  /* обводка выбранного — тонкая: 1px рамка + 1px кольцо */
  .cSw[data-on="true"]{ border-color:var(--ink); box-shadow:0 0 0 1px var(--ink); }
  /* Раздел «Все цвета» внизу карточки — цель ссылки «Все цвета (N)» */
  .colorAll{ display:grid; grid-template-columns:repeat(auto-fill,minmax(96px,1fr)); gap:16px; }
  .cAllItem{ margin:0; display:flex; flex-direction:column; align-items:center; gap:6px; text-align:center; }
  .cAllItem .cSw{ width:76px; height:76px; border-radius:var(--r-card); }
  .cAllItem figcaption{ font-size:13px; color:var(--muted); line-height:1.3; }
  .cAllItem .cSw[data-on="true"] + figcaption{ color:var(--ink); font-weight:700; }
  #v2AllColors{ scroll-margin-top:14px; }
  .moreLink{ display:inline-flex; margin-top:12px; font-size:13px; font-weight:700; color:var(--ink); }
  .moreLink:hover{ color:var(--red); }
  .attrList{ margin-top:24px; display:flex; flex-direction:column; gap:8px; }
  .attrRow{ font-size:15px; } .attrRow .k{ color:var(--muted); }
  .showroom{ margin-top:20px; display:flex; gap:16px; align-items:center; border:1px solid var(--line); border-radius:var(--r-card); padding:12px; }
  .showroom:hover{ border-color:#cfd8d8; }
  /* реальное фото зала вместо серой заглушки — кадрируем по центру */
  .showroom .simg{ width:96px; height:70px; border-radius:10px; flex:none; object-fit:cover; display:block; }
  .showroom b{ display:block; font-size:11px; letter-spacing:.1em; text-transform:uppercase; color:var(--faint); }
  .showroom p{ font-size:13px; font-weight:600; margin-top:4px; color:var(--ink); }
  .showroom .arr{ margin-left:auto; color:var(--faint); font-size:17px; }
  .artLine{ font-size:13px; color:var(--faint); margin-bottom:12px; }
  .buyCard{ border:1px solid var(--line); border-radius:var(--r-block); padding:16px; display:flex; flex-direction:column; gap:12px; background:#fafbfb; }
  .buyTop{ display:flex; gap:20px; }
  .buyLink{ display:flex; align-items:center; gap:6px; font-size:13px; color:var(--muted); font-weight:600; }
  .buyLink svg{ width:15px; height:15px; flex:none; fill:currentColor; stroke:none; }
  .buyLink:hover{ color:var(--ink); }
  .bigPrice{ font-size:28px; font-weight:700; }
  .bigPrice span{ display:block; font-size:13px; color:var(--muted); font-weight:600; margin-top:2px; }
  .ratingRow{ font-size:13px; color:var(--muted); } .ratingRow .stars{ color:var(--red); }
  .buyCard .bbAdd{ margin-top:2px; }
  .getGoods{ margin-top:4px; }
  .getGoods h4{ font-size:15px; margin-bottom:6px; }
  .getRow{ display:flex; gap:12px; align-items:flex-start; padding:12px 0; border-top:1px solid var(--line); }
  .getRow .gi{ font-size:17px; flex:none; }
  .getRow b{ font-size:13px; } .getRow p{ font-size:13px; color:var(--muted); margin-top:4px; line-height:1.5; }
  .getRow .arr{ margin-left:auto; color:var(--faint); font-size:17px; }
  .getRow .lnk{ color:var(--green); font-weight:600; }
  .charTable{ margin-top:16px; }
  .charTable .cr{ display:flex; align-items:baseline; gap:8px; padding:8px 0; font-size:15px; }
  .charTable .ck{ color:var(--muted); white-space:nowrap; }
  .charTable .dots{ flex:1; border-bottom:1px dotted #c3caca; transform:translateY(-3px); }
  .charTable .cv{ font-weight:600; text-align:right; }

  /* ---- stroymag v2 ---- */
  .perLine{ font-size:13px; color:var(--muted); }
  .cardStock{ font-size:13px; font-weight:600; color:var(--green); display:flex; align-items:center; gap:6px; }
  .cardStock::before{ content:''; width:7px; height:7px; border-radius:50%; background:var(--green); flex:none; }
  .cardStock[data-ok="false"]{ color:#b8860b; } .cardStock[data-ok="false"]::before{ background:var(--gold); }
  .smBtn{ width:42px; border:1px solid var(--line); border-radius:10px; color:var(--muted); font-size:20px; font-weight:700; display:flex; align-items:center; justify-content:center; }
  .smBtn:hover{ border-color:var(--ink); color:var(--ink); background:#f2f5f5; }
  .act{ position:relative; }
  .priceMain{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
  .pBig{ font-size:28px; font-weight:700; letter-spacing:-.01em; }
  /* зачёркнутая цена стоит В ОДНОЙ строке с основной, а не под ней */
  .priceMain .oldPrice{ font-size:17px; color:var(--faint); text-decoration:line-through; font-weight:600; white-space:nowrap; }
  /* фасовка и цена за единицу — мелкой строкой под ценами */
  .pSub{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; margin-top:-4px; font-size:13px; color:var(--muted); }
  /* точка-разделитель между фасовкой и ценой за единицу */
  .pSub > .pUnit + *::before, .pSub > .pUnit ~ *::before{ content:'· '; color:var(--faint); }
  .pSub .perLine{ font-size:13px; color:var(--muted); }
  .pUnit{ font-size:13px; color:var(--muted); font-weight:600; }
  .pRecalc{ font-size:13px; color:var(--muted); }
  .oldRow{ display:flex; gap:12px; align-items:center; }
  .wasOld{ font-size:15px; color:var(--faint); text-decoration:line-through; }
  .saveTag{ font:700 11.5px/1 var(--font-body); background:#fdeef1; color:var(--red-d); padding:6px 8px; border-radius:6px; }
  .stockList{ display:flex; flex-direction:column; gap:8px; border-top:1px solid var(--line); border-bottom:1px solid var(--line); padding:12px 0; }
  .stRow{ font-size:13px; color:#37413f; display:flex; align-items:center; gap:8px; }
  .stRow b{ font-weight:700; } .stRow .stx{ color:var(--faint); }
  .dotOk,.dotWait{ width:8px; height:8px; border-radius:50%; flex:none; }
  .dotOk{ background:var(--green); } .dotWait{ background:var(--gold); }
  .calc{ background:#f5f8f8; border:1px solid var(--line); border-radius:var(--r-card); padding:12px 12px; }
  .calcHead{ font-size:13px; font-weight:700; margin-bottom:8px; }
  .calcRow{ display:flex; align-items:center; justify-content:space-between; gap:12px; }
  .calcRow label{ font-size:13px; color:var(--muted); }
  .calcInp{ display:flex; align-items:center; border:1px solid var(--line); border-radius:8px; background:#fff; overflow:hidden; }
  .calcInp button{ width:34px; height:34px; font-size:17px; color:var(--muted); } .calcInp button:hover{ background:#eef1f1; color:var(--ink); }
  .calcInp span{ min-width:42px; text-align:center; font-weight:700; font-size:15px; }
  /* площадь можно вписать руками */
  .calcInp input{ width:56px; min-width:0; text-align:center; font-weight:700; font-size:15px;
    border:0; background:none; color:var(--ink); padding:0; -moz-appearance:textfield; }
  .calcInp input:focus{ outline:none; }
  .calcInp:focus-within{ border-color:var(--ink); }
  .calcOut{ font-size:13px; color:#37413f; margin-top:8px; } .calcOut b{ color:var(--ink); }
  /* ---- Оптовая лестница цен (v2Tiers) ---- */
  .tiers{ border:1px solid var(--line); border-radius:var(--r-card); overflow:hidden; margin-top:4px; }
  .tiersHead{ display:flex; align-items:center; justify-content:space-between; gap:8px; padding:12px 12px; background:var(--teal-l); }
  .tiersHead b{ font-size:13px; font-weight:700; }
  .tiersHead span{ font-size:11px; font-weight:700; color:#fff; background:var(--red); padding:4px 8px; border-radius:6px; white-space:nowrap; }
  .tiersHint{ font-size:11px; color:var(--muted); padding:8px 12px 0; line-height:1.4; }
  .tiersList{ padding:8px 6px 12px; }
  .tRow{ display:flex; align-items:baseline; gap:8px; padding:8px 6px; border-radius:8px; }
  .tRow .tQty{ flex:1; font-size:13px; color:var(--muted); min-width:0; }
  .tRow .tQty i{ font-style:normal; display:block; font-size:11px; color:var(--faint); }
  .tRow .tPrice{ font-size:15px; font-weight:700; color:var(--ink); white-space:nowrap; }
  .tRow .tSave{ font-size:11px; font-weight:700; color:var(--red); white-space:nowrap; min-width:38px; text-align:right; }
  /* активный уровень — тот, который сейчас даёт цену при выбранном количестве */
  .tRow[data-on="true"]{ background:#eaf6ef; }
  .tRow[data-on="true"] .tQty{ color:var(--ink); font-weight:700; }
  .tRow[data-on="true"] .tPrice{ color:#1a7f45; }
  .tiersNow{ font-size:13px; padding:0 12px 12px; color:#1a7f45; font-weight:700; line-height:1.4; }
  .tiersNow b{ color:var(--ink); }
  .qtyBuy{ display:flex; gap:12px; align-items:center; }
  .qtyBuy .qty{ height:46px; }
  .qtyBuy .bbAdd{ flex:1; height:46px; font-size:15px; padding:0; display:flex; align-items:center; justify-content:center; }
  .buy2{ display:flex; gap:12px; }
  .smetaBtn{ flex:1; border:1px solid var(--ink); color:var(--ink); font-weight:700; font-size:13px; border-radius:10px; padding:12px; }
  .smetaBtn:hover{ background:var(--ink); color:#fff; }
  /* Чёрная заливка — по просьбе владельца. Была светлая кнопка с серой подписью,
     её просто не замечали. Ховер уводим в чистый #000, а НЕ в --ink: у соседней
     .bbAdd ховер как раз уходит в --ink, и на одинаковом цвете две кнопки рядом
     читались бы как «обе нажаты». */
  .clickBuy{ flex:1; border:1px solid var(--ink); background:var(--ink); color:#fff; font-weight:700; font-size:13px; border-radius:10px; padding:8px; }
  .clickBuy:hover{ background:#000; border-color:#000; color:#fff; }
  .deliv{ display:flex; flex-direction:column; gap:4px; font-size:13px; color:var(--muted); border-top:1px dashed var(--line); padding-top:12px; }
  /* Позиция комплекта — две колонки: фото | текст. Отдельной галочки нет: выбор
     показывает сама карточка контуром. Что обведено — то и уедет в корзину.
     Так в карточку влезает больше текста, а состояние читается с одного взгляда,
     без поиска мелкого значка в углу. */
  .kitRow{ display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr)); gap:12px; margin-top:16px; }
  .kitItem{ display:flex; gap:12px; align-items:stretch; border:1px solid var(--line); border-radius:var(--r-card); padding:12px;
    background:#f6f8f8; cursor:pointer; transition:background .15s ease, border-color .15s ease, box-shadow .15s ease; }
  .kitItem[data-on="true"]{ background:#fff; border-color:var(--ink); box-shadow:0 0 0 1px var(--ink) inset; }
  .kitItem[data-on="false"]:hover{ border-color:#cfd8d8; background:#fff; }
  /* Невыбранная позиция гасится картинкой и ценой, но текст остаётся читаемым:
     человек должен понимать, от чего именно отказывается. */
  .kitItem[data-on="false"] .kitImg{ opacity:.55; }
  .kitItem[data-on="false"] .kitPrice{ color:var(--muted); }
  .kitImg{ width:60px; height:60px; border-radius:10px; flex:none; object-fit:cover; align-self:flex-start; }
  .kitInfo{ flex:1; min-width:0; display:flex; flex-direction:column; }
  .kitInfo b{ font-size:13px; display:block; line-height:1.3; }
  .kitNote{ font-size:11px; color:var(--muted); display:block; margin-top:4px; }
  .kitPrice{ font-size:15px; font-weight:700; margin-top:6px; }
  /* margin-top:auto прибивает «Подробнее» к низу карточки: в ряду карточки равной
     высоты, и ссылка стоит на одной линии во всех, как бы ни разошлись названия. */
  .kitMore{ margin-top:auto; padding-top:8px; align-self:flex-start; font-size:13px; font-weight:700; color:var(--red); }
  .kitMore:hover{ color:var(--red-d); }

  /* Пять и больше позиций — лента с прокруткой. Ширина карточки считается так,
     чтобы в ряд вставали четыре штуки и пятая выглядывала краем: видно фото и
     начало названия — этого хватает, чтобы понять, что список продолжается.
     Делитель 4.4 и есть «сузить процентов на десять». */
  /* Блок комплектации стоит между карточкой товара и вкладками, и обеим сторонам
     нужен воздух: сверху чуть больше общего шага секций, снизу — заметно больше,
     потому что у .tabsBar своих отступов почти нет (8px) и лента липла к вкладкам.
     Селектор двойной (.secHead.secHead--kit) намеренно: ниже по файлу общий
     .secHead ещё раз задаёт margin внутри container-запроса, и одиночный класс
     проиграл бы ему по порядку. */
  .secHead.secHead--kit{ margin-top:56px; }
  .kitBox{ margin-top:16px; margin-bottom:36px; }
  .kitBox .kitRow{ margin-top:0; }
  /* Полосу прокрутки прячем: листают стрелками и свайпом, а серая линия под
     карточками читалась как часть блока и мусорила. */
  .kitBox--scroll .kitRow{ display:flex; overflow-x:auto; scroll-snap-type:x proximity; scrollbar-width:none; -ms-overflow-style:none; }
  .kitBox--scroll .kitRow::-webkit-scrollbar{ width:0; height:0; display:none; }
  .kitBox--scroll .kitItem{ flex:0 0 calc((100% - 52px) / 4.4); scroll-snap-align:start; }
  @container (max-width:1099px){ .kitBox--scroll .kitItem{ flex-basis:calc((100% - 40px) / 3.4); } }
  @container (max-width:699px){ .kitBox--scroll .kitItem{ flex-basis:250px; } }

  /* Итог и кнопка живут в строке заголовка блока (.secHead уже space-between).
     align-items:center перебивает общий flex-end у .secHead: там он ставит «Все ›»
     на базовую линию заголовка, а здесь справа стоит крупная кнопка — ей нужна
     одна центральная ось с заголовком, иначе она сидит выше. */
  .secHead--kit{ align-items:center; }
  .secHead--kit .kitSum{ display:flex; align-items:center; gap:16px; flex:none; }
  .kitSumNum{ font-size:13px; color:var(--muted); white-space:nowrap; }
  .kitSumNum b{ font-size:15px; font-weight:700; color:var(--ink); }
  .kitBtn{ background:var(--ink); color:#fff; font-weight:700; font-size:13px; border-radius:10px; padding:12px 16px; white-space:nowrap; }
  .kitBtn:hover{ background:#000; }
  .kitBtn[disabled]{ opacity:.45; cursor:default; }
  .kitBtn[disabled]:hover{ background:var(--ink); }
  /* На узком экране заголовок и итог встают друг под друга, и итог снова читается
     полосой — как было до переноса наверх. */
  @container (max-width:699px){
    .secHead--kit{ display:block; }
    .secHead--kit .kitSum{ justify-content:space-between; gap:12px; margin-top:12px;
      background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:12px 16px; }
  }

  /* ---- Cart + Checkout (unified with site system) ---- */
  .shopLayout{ display:grid; grid-template-columns:1fr; gap:24px; align-items:start; margin-top:8px; }
  .shopMain{ min-width:0; } .shopAside{ min-width:0; }
  .asideH{ font-family:var(--font-head); font-size:var(--fs-h3); font-weight:var(--fw-head);
           letter-spacing:var(--ls-head); line-height:1.25; }
  .sumLine{ display:flex; justify-content:space-between; gap:12px; font-size:15px; } .sumLine b{ font-weight:700; } .sumLine b.red{ color:var(--red); }
  .sumTotalRow{ display:flex; justify-content:space-between; align-items:baseline; font-size:20px; font-weight:700; border-top:1px solid var(--line); padding-top:12px; margin-top:4px; }
  .miniList{ display:flex; flex-direction:column; gap:12px; border-bottom:1px solid var(--line); padding-bottom:12px; }
  .miniItem{ display:flex; justify-content:space-between; gap:12px; font-size:13px; color:#37413f; } .miniItem b{ white-space:nowrap; font-weight:700; }
  .buyCard .backLink{ text-align:center; margin-top:2px; }
  .cartList{ display:flex; flex-direction:column; }
  .cartRow{ display:grid; grid-template-columns:72px 1fr auto; grid-template-areas:"img info x" "img qty price"; gap:8px 16px; align-items:center; padding:20px 0; border-bottom:1px solid var(--line); }
  .cartRow:first-child{ padding-top:4px; }
  .cartImg{ grid-area:img; width:72px; height:72px; border-radius:10px; object-fit:cover; background:#eef1f1; align-self:start; }
  .cartInfo{ grid-area:info; }
  .cartName{ font-size:15px; font-weight:700; color:var(--ink); } .cartName:hover{ color:var(--red); }
  /* Каждая характеристика своей строкой: в одну строку они переносились как
     попало и слипались с названием. */
  .cartMeta{ font-size:13px; color:var(--muted); margin-top:6px; line-height:1.5; }
  .cartMeta span{ display:block; }
  /* Значения характеристик — чёрным. Красный на сайте означает «сюда можно нажать»,
     а фасовка и фактура ничего не открывают: цветом они врали про интерактивность. */
  .cartMeta b{ color:var(--ink); font-weight:700; }
  .cartMeta--tint{ margin-top:0; }
  .cartQtyWrap{ grid-area:qty; } .qLbl{ display:block; font-size:11px; color:var(--faint); margin-bottom:6px; }
  .cartLine{ grid-area:price; font-size:17px; font-weight:700; text-align:right; white-space:nowrap; }
  .cartX{ grid-area:x; width:34px; height:34px; border-radius:8px; color:var(--faint); font-size:15px; justify-self:end; }
  .cartX:hover{ background:#fdeef1; color:var(--red); }
  .promoRow{ display:flex; flex-wrap:wrap; gap:12px; align-items:center; border:1px solid var(--line); border-radius:var(--r-card); padding:16px; margin-top:16px; }
  .promoLbl{ font-weight:700; font-size:15px; }
  .promoInp{ flex:1; min-width:150px; border:1px solid var(--line); border-radius:10px; padding:12px 16px; background:#fff; outline:none; font-size:15px; }
  .promoInp:focus{ border-color:var(--ink); }
  .promoBtn{ background:#e2e7e7; color:var(--ink); font-weight:700; padding:12px 24px; border-radius:10px; font-size:15px; }
  .promoBtn:hover{ background:#d6dcdc; }
  .stepper{ display:flex; max-width:620px; margin:6px 0 16px; }
  .stepItem{ flex:1; position:relative; display:flex; flex-direction:column; align-items:center; }
  .stepLine{ position:absolute; top:19px; left:50%; width:100%; height:3px; background:var(--line); z-index:0; }
  .stepItem:last-child .stepLine{ display:none; }
  .stepItem[data-state="active"] .stepLine{ background:var(--red); }
  .stepDot{ position:relative; z-index:1; width:40px; height:40px; border-radius:50%; background:#d7dede; color:var(--ink); font-weight:700; font-size:17px; display:flex; align-items:center; justify-content:center; }
  .stepItem[data-state="active"] .stepDot{ background:var(--red); color:#fff; box-shadow:0 0 0 5px #fdeef1; }
  .stepLbl{ margin-top:8px; font-size:13px; color:var(--muted); text-align:center; padding:0 4px; }
  .stepItem[data-state="active"] .stepLbl{ color:var(--ink); font-weight:700; }
  /* Догнано до общего правила .secHead h2 (letter-spacing + line-height), иначе
     шаги оформления читались иначе, чем секции главной и карточки.
     margin-bottom = --head-gap: заголовок не должен лежать на своём блоке. */
  .coH2{ font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head);
         letter-spacing:var(--ls-head); line-height:1.25; margin-bottom:var(--head-gap); }
  .coRule{ display:none; }
  /* Ритм секций общий для всего сайта: между блоками --sec-gap, как у .secHead. */
  .coBlock{ margin-top:var(--sec-gap); }
  /* У первого шага секции сверху нет — отступ увёл бы левую колонку вниз
     относительно карточки «Ваш заказ», и колонки перестали бы начинаться вровень. */
  .coBlock:first-child{ margin-top:0; }
  .segToggle{ display:inline-flex; gap:12px; margin-bottom:24px; flex-wrap:wrap; }
  .segBtn{ background:#f2f5f5; color:var(--muted); font-weight:700; font-size:15px; padding:12px 24px; border-radius:10px; }
  .segBtn[data-on="true"]{ background:#fdeef1; color:var(--red); }
  .segBtn:hover{ color:var(--ink); }
  .coFields{ display:grid; grid-template-columns:1fr; gap:16px; }
  .coField{ display:flex; flex-direction:column; gap:6px; background:#f2f5f5; border-radius:10px; padding:12px 16px; }
  .coField.full{ grid-column:1/-1; }
  .coField span{ font-size:13px; color:var(--muted); } .coField span i{ color:#f0743a; font-style:normal; }
  .coField input,.coField textarea{ background:transparent; border:none; outline:none; font-size:15px; color:var(--ink); font-family:inherit; }
  .coField textarea{ min-height:110px; resize:vertical; }
  .coNav{ display:flex; align-items:center; gap:16px; margin-top:24px; flex-wrap:wrap; justify-content:flex-end; }
  .coNav.end{ justify-content:space-between; }
  .agree{ display:flex; align-items:center; gap:12px; font-size:15px; color:var(--ink); margin-right:auto; }
  .agree input{ width:20px; height:20px; accent-color:var(--red); }
  .navBtn{ background:var(--red); color:#fff; font-weight:700; font-size:15px; padding:16px 28px; border-radius:var(--r-card); }
  .navBtn:hover{ background:var(--ink); color:#fff; }
  .navGhost{ border:1px solid var(--line); color:var(--muted); font-weight:700; font-size:15px; padding:16px 20px; border-radius:var(--r-card); }
  .navGhost:hover{ border-color:var(--ink); color:var(--ink); }
  .optList{ display:flex; flex-direction:column; gap:16px; }
  .optCard{ display:grid; grid-template-columns:26px 72px 1fr; gap:16px; align-items:start; border:1px solid var(--line); border-radius:var(--r-card); padding:20px; cursor:pointer; background:#fff; }
  .optCard[data-on="true"]{ border-color:var(--red); box-shadow:0 0 0 1px var(--red) inset; }
  .optRadio{ width:26px; height:26px; border-radius:50%; border:2px solid var(--line); position:relative; margin-top:2px; }
  .optCard[data-on="true"] .optRadio{ border-color:var(--red); }
  .optCard[data-on="true"] .optRadio::after{ content:'✓'; position:absolute; inset:0; display:flex; align-items:center; justify-content:center; color:var(--red); font-size:15px; font-weight:700; }
  .optIco{ width:72px; height:66px; border-radius:var(--r-card); background:#f5f8f8; display:flex; align-items:center; justify-content:center; color:var(--ink); }
  .optIco svg{ width:34px; height:34px; fill:currentColor; stroke:none; }
  .optBody h4{ font-size:17px; font-weight:700; }
  .optPrice{ color:var(--red); font-weight:700; font-size:15px; margin:8px 0; }
  .optNote{ color:var(--muted); font-weight:700; font-size:13px; margin:8px 0; }
  .optBody p{ font-size:13px; color:#37413f; line-height:1.6; }
  .confMeta{ font-size:15px; color:var(--ink); margin-bottom:8px; } .confMeta span{ color:var(--faint); } .confMeta b{ font-weight:700; }
  .confList{ margin:16px 0; padding-left:24px; display:flex; flex-direction:column; gap:16px; }
  .confList li{ font-size:15px; } .confQty{ font-weight:700; margin-top:6px; }
  .okBox{ margin:16px 0; text-align:center; background:#fff; border:1px solid var(--line); border-radius:var(--r-block); padding:40px 24px; }
  .okIco{ width:60px; height:60px; border-radius:50%; background:var(--green); color:#fff; font-size:28px; display:flex; align-items:center; justify-content:center; margin:0 auto 16px; }
  .okBox h2{ font-size:20px; font-weight:700; } .okBox p{ color:var(--muted); margin:12px auto 24px; font-size:15px; line-height:1.7; max-width:44ch; }
  @container (min-width:700px){
    .shopLayout{ grid-template-columns:1fr 300px; }
    /* Сводка заказа липнет ПОД закреплённой панелью, а не под верх экрана.
       Было top:16px — панель (шапка + строка категорий) высотой ~142px накрывала
       верх карточки, и первые строки заказа с товарами уходили под неё.
       Высоту панели измеряет v2.js и кладёт в --sticky-h: на широком экране
       она одна, на планшете другая, после поворота третья.
       .is-tall — страховка: если сводка ВЫШЕ экрана, липкость снимаем совсем,
       иначе её нижняя часть (кнопка «Оформить заказ») стала бы недосягаемой. */
    .shopAside{ position:sticky; top:calc(var(--sticky-h, 0px) + 16px); }
    .shopAside.is-tall{ position:static; }
  }
  @container (min-width:1100px){
    .shopLayout{ grid-template-columns:1fr 340px; }
    /* align-items:start, а не center: при выросшем списке опций блок количества
       и цена всплывали к середине строки и переставали совпадать по вертикали
       с названием — ряд выглядел разъехавшимся. Ширины у количества и цены
       фиксированные, иначе колонки гуляют от строки к строке. */
    .cartRow{ grid-template-columns:96px minmax(0,1fr) minmax(0,auto) minmax(0,auto) 32px; grid-template-areas:"img info qty price x"; align-items:start; padding:20px 0; }
    .cartImg{ width:96px; height:96px; align-self:center; }
    .cartLine{ min-width:100px; }
    .coFields{ grid-template-columns:1fr 1fr; }
  }


  /* ============ TABLET (>=700) ============ */
  @container (min-width:700px){
    .util{ display:block; }
    /* линия-разделитель остаётся ОДНА — под строкой категорий; у шапки её снимаем,
       иначе меню оказывается зажатым между двумя линиями. На мобильной категорий нет,
       поэтому там граница шапки сохраняется (правило в базовом блоке). */
    .hdr{ border-bottom:none; }
    .wrap, .hdrIn, .catbarIn{ padding-left:var(--pad-x); padding-right:var(--pad-x); }
    .utilIn{ padding-left:var(--pad-x); padding-right:var(--pad-x); }
    .wrap.page{ padding-left:var(--pad-x); padding-right:var(--pad-x); }
    .pdp2{ grid-template-columns:1fr 1fr; grid-template-areas:"gallery attrs" "buy buy" "tabs tabs"; } .galleryCol{ grid-area:gallery; } .attrCol{ grid-area:attrs; } .buyCol{ grid-area:buy; } .pdpTabs{ grid-area:tabs; }
    .gallery{ grid-template-columns:64px 1fr; } .thumbs{ flex-direction:column; order:0; overflow:visible; }
    .searchWrap{ order:0; flex-basis:auto; flex:1; }
    .act{ display:flex; }
    .catbar{ display:block; }
    .burger{ display:none; }
    .logoTag{ display:block; }
    .heroGrid{ grid-template-columns:1.7fr 1fr; }
    .heroMain{ height:360px; } .heroMain h1, .heroMain h2{ font-size:28px; }
    /* На широком кадре текст слева — и вуаль тоже уезжает влево, чтобы не гасить пирог. */
    .heroMain.is3d::before{ background:
      radial-gradient(105% 118% at 70% 46%, rgba(5,7,11,0) 30%, rgba(5,7,11,.30) 72%, rgba(4,5,9,.70) 100%),
      linear-gradient(96deg,rgba(5,7,11,.93) 0%,rgba(5,7,11,.76) 26%,rgba(5,7,11,.16) 50%,rgba(5,7,11,0) 66%); }
    .heroMain.is3d .heroBottom{ margin-top:auto; }
    .heroDots{ position:absolute; right:26px; bottom:26px; padding:0; }
    .heroDots i{ background:rgba(255,255,255,.45); }
    .heroDots i[data-on="true"]{ background:#fff; }
    .promoCol{ grid-template-columns:none; grid-template-rows:1fr 1fr; grid-auto-flow:column; grid-auto-columns:100%; gap:var(--gap-card); overflow-x:auto; scroll-snap-type:x mandatory; scrollbar-width:none; }
    .promoBox > .promoCol{ scrollbar-width:none; -ms-overflow-style:none; }
    .promoBox > .promoCol::-webkit-scrollbar{ display:none; width:0; height:0; }
    .kolerovka{ grid-template-columns:1fr 1fr; }
    .helpMain{ grid-template-columns:1.2fr 1fr; gap:28px; }
    .formGrid{ grid-template-columns:1fr 1fr; }
    .field.full{ grid-column:1/-1; }
    .studioList{ grid-template-columns:1fr 1fr; }
    .distribGrid{ grid-template-columns:1.05fr 1fr; gap:44px; align-items:start; }
    .faqWrap{ grid-template-columns:1.6fr 1fr; }
    .catLayout{ grid-template-columns:240px 1fr; }
    .sidebar{ display:block; }
    .catTools{ display:none; }
    .sortBar[data-open]{ display:flex; }   /* та же специфичность, но правило ниже — перебивает мобильное скрытие */
    .catGrid{ grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:12px; }
    .catTop{ flex-direction:row; align-items:flex-end; justify-content:space-between; }
    .pdp{ grid-template-columns:1fr 1fr; }
    .fcols{ grid-template-columns:repeat(4,1fr); }
  }
  /* ============ DESKTOP (>=1100) ============ */
  @container (min-width:1100px){
    .catBtn{ display:flex; }
    .pdp2{ grid-template-columns:440px minmax(0,1fr) 320px; grid-template-areas:"gallery attrs buy" "tabs tabs buy"; } .galleryCol{ grid-area:gallery; } .attrCol{ grid-area:attrs; } .buyCol{ grid-area:buy; position:sticky; top:16px; align-self:start; } .pdpTabs{ grid-area:tabs; }
    /* 440, а не 400: основной блок стал заметно крупнее, и промо-плитки справа
       растягиваются вслед за ним — их высоту задаёт именно геро. */
    .heroMain{ height:440px; padding:40px; } .heroMain h1, .heroMain h2{ font-size:28px; }
    .heroMain p{ font-size:15px; }
    .kolerovka{ grid-template-columns:1.2fr 1fr; }
    .advStrip .advItem{ flex-direction:column; text-align:center; }
    .catLayout{ grid-template-columns:270px 1fr; }
    .pdp{ grid-template-columns:1.15fr .85fr; gap:36px; }
    .gallery{ grid-template-columns:72px 1fr; }
    .thumb{ width:72px; height:72px; }
  }

/* =========================================================================
   ЛОКАЛЬНЫЕ ДОБАВКИ (НЕ из макета) — минимум, которого в макете не было.
   В макете контент вкладок был свёрстан инлайн-стилями внутри prototype-разметки,
   переиспользовать их напрямую нельзя. Стили ниже повторяют те же значения.
   ========================================================================= */
.v2TabWrap{ margin-top:24px; }
.v2Tab{ font-size:15px; color:#37413f; line-height:1.7; max-width:70ch; }
.v2Tab p{ margin-top:12px; }
.v2Tab ul, .v2Tab ol{ margin:12px 0 0 20px; }
.v2Tab li{ margin-top:6px; }
.v2Tab h2, .v2Tab h3, .v2Tab h4{ font-weight:700; margin-top:24px; }
.v2Tab h3{ font-size:17px; } .v2Tab h4{ font-size:15px; }
.v2Tab img{ max-width:100%; height:auto; }
.v2Tab table{ width:100%; border-collapse:collapse; margin-top:12px; }
.v2Tab td, .v2Tab th{ border:1px solid var(--line); padding:8px 12px; text-align:left; }

/* цена «была» в блоке покупки — в макете этот класс жил только в карточках каталога */
/* .buyCard .oldPrice — правило снято: цена теперь inline в .priceMain (см. выше) */

/* поле количества: в макете это был неинтерактивный <span> */
.qty input{ width:44px; text-align:center; border:none; background:none; font:700 15px/1 var(--font-body); color:var(--ink); }

/* Галерея с настоящими <img>. В макете тут была серая заглушка .ph, поэтому
   размеров для картинок он не задаёт — без этих правил фото вылезает за сетку. */
.mainWrap img{ display:block; width:100%; height:auto; max-height:520px; object-fit:contain; }
/* Фактура выбранного цвета — плашкой в правом нижнем углу фото. Банка остаётся на виду:
   плашка накладывается поверх, а не подменяет снимок товара. */
.mainWrap{ position:relative; }
.texBadge{ position:absolute; right:10px; bottom:10px; width:132px; height:132px; border-radius:var(--r-card);
  overflow:hidden; background:#fff; border:3px solid #fff; box-shadow:0 6px 20px -6px rgba(15,30,30,.45); }
.texBadge img{ width:100%; height:100%; object-fit:cover; display:block; max-height:none; }
@container (max-width:699px){ .texBadge{ width:96px; height:96px; right:8px; bottom:8px; } }
.thumb img{ width:100%; height:100%; object-fit:cover; display:block; }
/* когда активное фото одно, колонка миниатюр не рисуется — сетка должна стать одноколоночной,
   иначе .mainWrap попадает в узкую колонку 64px и растягивает вёрстку */
.gallery.gallery--solo{ grid-template-columns:1fr; }

/* =========================================================================
   КОЛЕРОВКА — блок «Выбрать цвет» и модалка палитры.
   В макете такого блока не было; собран из его же токенов: рамка/радиус/отступы
   как у .showroom, акцент — var(--red), шрифт и цвета из :root. Розовый из
   образца-референса намеренно не переносился — у нас красный акцент.
   ========================================================================= */
.colorPick{ margin-top:2px; width:100%; display:flex; gap:16px; align-items:center; text-align:left;
  border:1px solid var(--line); border-radius:var(--r-card); padding:12px 16px; background:#fff; transition:border-color .15s ease; }
.colorPick:hover{ border-color:#cfd8d8; }
.cpIco{ width:44px; height:44px; flex:none; border-radius:var(--r-card); background:var(--teal-l);
  display:flex; align-items:center; justify-content:center; }
.cpIco svg{ width:26px; height:26px; }
/* палитра: контур штрихом, точки — акцентными цветами макета.
   Если залить всё одним fill, «дырки» палитры пропадают и иконка читается пятном. */
.cpIco .cpBody{ fill:none; stroke:var(--ink); stroke-width:1.6; }
.cpIco .d1{ fill:var(--red); }
.cpIco .d2{ fill:var(--gold); }
.cpIco .d3{ fill:var(--green); }
.cpIco .d4{ fill:var(--teal); }
.cpText{ display:block; }
.cpText b{ display:block; font-size:15px; font-weight:700; color:var(--ink); }
.cpChosen{ display:block; font-size:13px; color:var(--muted); margin-top:2px; }
.cpChosen i{ font-style:normal; font-weight:700; color:var(--red); }
.colorPick .arr{ margin-left:auto; color:var(--faint); font-size:17px; }
.cpNote{ margin-top:8px; font-size:13px; line-height:1.5; color:var(--muted); }

.cpModal[hidden]{ display:none; }
.cpModal{ position:fixed; inset:0; z-index:90; display:flex; align-items:center; justify-content:center; padding:16px; }
.cpBack{ position:absolute; inset:0; background:rgba(15,25,25,.5); }
.cpBox{ position:relative; width:min(720px,100%); max-height:86vh; display:flex; flex-direction:column;
  background:#fff; border-radius:var(--r-block); overflow:hidden; box-shadow:0 30px 80px -30px rgba(15,40,40,.6); }
.cpHead{ display:flex; align-items:center; justify-content:space-between; padding:16px 20px; border-bottom:1px solid var(--line); }
.cpHead b{ font-size:17px; font-weight:700; }
.cpClose{ font-size:24px; line-height:1; color:var(--muted); padding:0 4px; }
.cpClose:hover{ color:var(--ink); }
.cpSearch{ padding:12px 20px; border-bottom:1px solid var(--line); }
.cpSearch input{ width:100%; border:1px solid var(--line); border-radius:10px; padding:12px 16px; font-size:15px; color:var(--ink); }
.cpSearch input:focus{ outline:none; border-color:var(--ink); }
.cpGrid{ padding:16px 20px; overflow:auto; display:grid; gap:12px;
  grid-template-columns:repeat(auto-fill,minmax(96px,1fr)); }
.cpItem{ text-align:left; }
.cpItem .sw{ width:100%; aspect-ratio:1/1; border-radius:var(--r-card); border:2px solid var(--line); display:block; }
.cpItem[data-on="true"] .sw{ border-color:var(--ink); box-shadow:0 0 0 2px var(--ink); }
.cpItem .nm{ display:block; font-size:13px; font-weight:600; margin-top:6px; color:var(--ink); line-height:1.25; }
.cpItem .pr{ display:block; font-size:11px; color:var(--muted); }
.cpFoot{ display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:16px 20px; border-top:1px solid var(--line); font-size:13px; color:var(--muted); }
.cpReset{ font-size:13px; font-weight:700; color:var(--ink); border:1px solid var(--line); border-radius:10px; padding:8px 16px; background:#fff; }
.cpReset:hover{ border-color:var(--ink); }
.cpPlus{ display:block; margin-top:6px; font-size:13px; color:var(--muted); }
.cpPlus b{ color:var(--ink); }

/* ---- Попап карточки из блока комплектации («Подробнее») ----
   Живёт на базе .cpModal, но v2.js выносит его в конец <body> — наружу из .v2root
   с его container-type. Значит @container здесь не сработает бы вовсе (не осталось
   ни одного контейнера-предка), и адаптив написан на @media. */
.kmBox{ width:min(640px,100%); }
.kmBody{ display:flex; gap:20px; padding:20px; overflow:auto; }
.kmImgWrap{ flex:none; width:180px; }
.kmImgWrap img{ width:100%; aspect-ratio:1/1; object-fit:cover; border-radius:var(--r-card); display:block; background:#f4f6f6; }
.kmInfo{ flex:1; min-width:0; }
.kmWhy{ font-size:13px; font-weight:700; color:var(--red); line-height:1.35; }
.kmPrice{ margin-top:12px; font-size:15px; color:var(--muted); }
.kmPrice b{ font-size:24px; font-weight:700; color:var(--ink); }
.kmUnit{ font-size:13px; }
.kmUnit:not(:empty)::before{ content:' / '; }
.kmIntro{ margin-top:12px; font-size:13px; line-height:1.55; color:var(--muted); }
.kmIntro:empty{ display:none; }
.kmFoot{ justify-content:space-between; }
.kmLink{ font-size:13px; font-weight:700; color:var(--red); }
.kmLink:hover{ color:var(--red-d); }
@media (max-width:699px){
  .kmBody{ display:block; padding:16px; }
  .kmImgWrap{ width:140px; margin:0 auto 12px; }
  .kmFoot{ flex-wrap:wrap; gap:10px; }
}

/* =========================================================================
   Мобильное меню (.mm*) — из макета «Ceresit Shop v2».
   ВАЖНО: .v2root несёт container-type:inline-size, а это включает layout
   containment — значит .v2root становится содержащим блоком для position:fixed
   потомков, и оверлей внутри него перестаёт быть привязанным к экрану.
   Поэтому v2.js переносит .mmOverlay в конец <body>, наружу из .v2root.
   Стили живут здесь, вне container-запросов, чтобы работать после переноса.
   ========================================================================= */
.mmOverlay{ position:fixed; inset:0; background:rgba(15,20,22,.5); z-index:60; display:flex; }
.mmOverlay[hidden]{ display:none; }
.mmPanel{ background:#fff; width:min(340px,86vw); height:100%; display:flex; flex-direction:column;
  padding:20px; gap:16px; box-shadow:2px 0 40px rgba(0,0,0,.3); overflow-y:auto; }
.mmTop{ display:flex; align-items:center; justify-content:space-between; }
.mmTop .logo{ font-size:20px; }
.mmClose{ width:38px; height:38px; border-radius:10px; font-size:17px; color:var(--muted); }
.mmClose:hover{ background:#f2f5f5; color:var(--ink); }
.mmSearch{ display:flex; align-items:center; background:#fff; border:1.5px solid var(--line); border-radius:10px; overflow:hidden; }
.mmSearch:focus-within{ border-color:var(--muted); }
.mmNav{ display:flex; flex-direction:column; border-top:1px solid var(--line); }
.mmLink{ padding:16px 4px; font-weight:700; font-size:15px; color:var(--ink); border-bottom:1px solid var(--line); }
.mmLink:hover{ color:var(--red); }
.mmUtil{ display:flex; flex-direction:column; gap:12px; margin-top:auto; padding-top:8px; }
.mmUtil a{ font-size:15px; color:var(--muted); font-weight:600; }
.mmUtil a:hover{ color:var(--ink); }
.mmPhone{ color:var(--ink) !important; font-size:17px; font-weight:700 !important; }

/* Блок «связаться» в мобильном меню — сразу под категориями (чанк v2_mobmenu).
   Номер крупный и первым: с телефона позвонить быстрее, чем заполнять форму.
   Ниже — почта и кнопка запроса КП. Отделён снизу линией, чтобы не читался
   вместе с разделами «Колеровка / Доставка / Кейсы».
   Правила стоят ПОСЛЕ второго набора .mm* — в файле их два одинаковых, и
   побеждает нижний; выше эти строки просто перебивались бы. */
.mmContact{ display:flex; flex-direction:column; align-items:stretch; gap:10px;
  padding-bottom:16px; border-bottom:1px solid var(--line); }
.mmTel{ font-family:var(--font-head); font-size:23px; font-weight:800; line-height:1.1;
  letter-spacing:-.01em; color:var(--ink); white-space:nowrap; }
.mmTel:hover{ color:var(--red); }
.mmMail{ font-size:15px; font-weight:600; color:var(--muted); word-break:break-all; }
.mmMail:hover{ color:var(--ink); }
.mmKp{ margin-top:2px; width:100%; padding:12px; border-radius:10px; text-align:center;
  background:var(--red); color:#fff; font-weight:700; font-size:15px; }
.mmKp:hover{ background:var(--ink); color:#fff; }

/* пока меню открыто — страница под ним не прокручивается */
body.mmOpen{ overflow:hidden; }

/* ---- Корзина: то, чего нет в макете, но нужно живой странице ---- */
/* Счётчик и удаление — это формы, поэтому области грида вешаем на них,
   иначе форма станет элементом грида, а .cartQtyWrap/.cartX внутри неё — нет. */
form.cartQtyWrap{ grid-area:qty; }
.cartDel{ grid-area:x; justify-self:end; display:flex; }
.cartX{ display:flex; align-items:center; justify-content:center; }
/* white-space:nowrap на .cartLine нужен сумме, но подпись под ней от него вылезала
   за край на узком экране — ей перенос разрешаем */
.cartLine .cartEach{ display:block; font-size:13px; font-weight:600; color:var(--faint); margin-top:4px; white-space:normal; }

/* «Вы экономите» — справочная строка под итогом, не участвует в вычитании */
.sumSave{ display:flex; justify-content:space-between; gap:12px; font-size:13px; color:var(--muted); }
.sumSave b{ color:var(--green); font-weight:700; }

.promoMsg{ flex-basis:100%; font-size:13px; color:var(--green); font-weight:600; }
.promoMsg[data-err="true"]{ color:var(--red); }
.promoBtn[disabled]{ opacity:.55; cursor:default; }
.promoInp[disabled]{ color:var(--muted); background:#f2f5f5; }

.cartEmpty{ text-align:center; border:1px solid var(--line); border-radius:var(--r-block); padding:48px 24px; margin-top:8px; background:#fafbfb; }
.cartEmpty .ceIco{ width:64px; height:64px; border-radius:50%; background:#fdeef1; color:var(--red);
  display:flex; align-items:center; justify-content:center; margin:0 auto 20px; }
.cartEmpty .ceIco svg{ width:30px; height:30px; fill:currentColor; stroke:none; }
.cartEmpty h2{ font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head); letter-spacing:var(--ls-head); }
.cartEmpty p{ color:var(--muted); font-size:15px; line-height:1.7; margin:12px auto 24px; max-width:44ch; }
.cartEmpty .bbAdd{ display:inline-flex; flex:none; padding:16px 28px; }

/* ---- Оформление заказа: то, чего нет в макете, но нужно живой форме ---- */
/* В макете выбор — это data-on на карточке. На живой странице под ним настоящий
   radio, иначе форма не отправит выбор и не сработает клавиатура. Прячем его так,
   чтобы он не стал ячейкой грида .optCard и остался доступен для фокуса. */
.optCard{ position:relative; }
.optInput{ position:absolute; opacity:0; width:0; height:0; margin:0; pointer-events:none; }
.optInput:focus-visible ~ .optRadio{ outline:2px solid var(--ink); outline-offset:2px; }
.optIco img{ max-width:38px; max-height:38px; object-fit:contain; display:block; }
.optBody p{ margin-top:4px; }
.optBody p:empty{ display:none; }

.segToggle a.segBtn{ display:inline-flex; align-items:center; }
.segToggle a.segBtn:hover{ color:var(--ink); }

.coError,
.coMsg{ border-radius:var(--r-card); padding:12px 16px; font-size:15px; font-weight:600; margin-top:16px; }
.coError{ background:#fdeef1; color:var(--red-d); }
.coMsg{ background:#fdeef1; color:var(--red-d); }
.coMsg[data-ok="true"]{ background:#eaf7f0; color:#14713f; }

.okBox .navBtn{ display:inline-block; }

@container (max-width:699px){
  /* на узком экране строка промокода в макете переносила кнопку под поле и
     оставляла её висеть слева — собираем блок в аккуратный столбик */
  .promoRow{ flex-direction:column; align-items:stretch; }
  .promoInp, .promoBtn{ width:100%; }
}

/* ---- Первый шаг каталога: большие карточки разделов ----
   В макете этого экрана не было — он появился, когда каталог разбили на два шага
   (сначала разделы, потом товары с фильтрами по ветке). Собран из тех же токенов,
   что и .catCard, чтобы не расходиться с дизайн-системой макета. */
.secGrid{ display:grid; grid-template-columns:1fr; gap:12px; }
.secCard{ background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:16px; display:flex; flex-direction:column; gap:12px; transition:border-color .15s ease, box-shadow .15s ease; }
/* Наведение как у .catCard и .card — рамка чернеет, появляется тень. */
.secCard:hover{ border-color:var(--ink); box-shadow:0 8px 22px -14px rgba(20,26,28,.4); }
.secTop{ display:flex; gap:16px; align-items:center; }
.secIco{ width:64px; height:64px; border-radius:10px; object-fit:cover; flex:none; background:#f2f5f5; }
.secName{ display:flex; flex-direction:column; gap:4px; }
.secName b{ font-size:15px; font-weight:700; line-height:1.3; letter-spacing:-.01em; }
.secName i{ font-style:normal; font-size:13px; color:var(--faint); }
.secCard:hover .secName b{ color:var(--red); }
.secSubs{ display:flex; flex-direction:column; border-top:1px solid var(--line); padding-top:4px; }
.secSub{ display:flex; align-items:center; justify-content:space-between; gap:12px; font-size:13px; color:#37413f; padding:6px 0; }
.secSub span{ color:var(--faint); font-size:13px; }
.secSub:hover{ color:var(--red); }
.secSub.secMore{ color:var(--muted); font-weight:600; }
.secAll{ margin-top:auto; font-size:13px; font-weight:700; color:var(--ink); }
.secAll:hover{ color:var(--red); }

/* Адаптив — на container queries, как и весь макет: контейнер это .v2root */
@container (min-width:700px){ .secGrid{ grid-template-columns:repeat(2,1fr); } }
@container (min-width:1100px){ .secGrid{ grid-template-columns:repeat(4,1fr); } }

/* Воздух перед блоком «фильтры + сортировка + товары».
   В макете этого отступа не было, потому что там над ним не было карточек подразделов.
   Без него сайдбар и сортировка зрительно прилипают к карточкам.
   Отступ вешаем на .catLayout, а не на .catsGrid: .catsGrid используется ещё и на
   главной, там свои интервалы задаёт .secHead — трогать их не надо.
   На мобильной между ними стоит строка кнопок .catTools — ей нужен такой же отступ сверху,
   а .catLayout под ней, наоборот, поджимаем, чтобы кнопки и товары читались одним блоком. */
.catLayout{ margin-top:24px; }
.catTools{ margin-top:24px; }
@container (max-width:699px){ .catTools + .catLayout{ margin-top:12px; } }

/* .catIco в макете был серым квадратом-заглушкой, поэтому про object-fit там речи не шло.
   Теперь туда попадает фото товара — без contain оно растянулось бы по квадрату. */
img.catIco{ object-fit:contain; background:#fff; }

/* Форма заявки: успех и ошибки валидации (в макете не было — форма была статична) */
.formOk{ padding:24px; border:1px solid var(--green); border-radius:var(--r-card); background:#f2fbf6; }
.formOk b{ font-size:17px; color:var(--ink); } .formOk p{ margin-top:6px; font-size:13px; color:var(--muted); }
.fErr{ display:block; margin-top:6px; font-size:13px; color:var(--red); }
.v2form .field input.err, .v2form .field textarea.err{ border-color:var(--red); }

/* 3D-конфигуратор фасада (iframe) — заменил блок плашек подбора цвета на главной */
.cfgWrap{ margin-top:2px; }
/* ⚠️ Скругление и тень задаём ЗДЕСЬ, а не в атрибуте style у айфрейма. Инлайновый
   стиль перебивает любое правило CSS без !important — из-за него мобильное
   `border-radius:0` ниже молча не работало, и блок во всю ширину экрана оставался
   со скруглёнными углами: по краям светились серые уголки фона, а мягкая тень
   читалась как серая полоса сверху и снизу. Именно это владелец назвал
   «странным сереньким дефектом» (03.08.2026). */
.cfgWrap iframe{ height:min(720px,82vh); border-radius:var(--r-block);
  box-shadow:0 18px 50px -24px rgba(15,40,40,.5); }
/* Телефон: кадр 360px + панель ~420. Инлайн height у iframe перебивает
   обычное правило — поэтому !important. */
@media (max-width:900px){
  .cfgWrap iframe{ height:780px !important; }
}
.cfgNote{ margin-top:12px; font-size:13px; line-height:1.5; color:var(--muted); }
/* Блок заявки на главной — МОДАЛЬНОЕ окно поверх страницы (открывает кнопка в панели
   виджета). Раньше он раскрывался в потоке, и всё под ним съезжало вниз — было непонятно,
   что произошло. Теперь ничего не сдвигается: окно всплывает по центру, фон затемнён,
   страница под ним не прокручивается (body.leadOpen). */
@keyframes leadFade{ from{ opacity:0; } to{ opacity:1; } }
@keyframes leadIn{ from{ opacity:0; transform:translateY(18px) scale(.985); } to{ opacity:1; transform:none; } }

/* ⚠️ ОБЯЗАТЕЛЬНО и первым правилом. Атрибут `hidden` работает через браузерное
   `[hidden]{display:none}`, и ЛЮБОЙ свой `display` его перебивает: из-за `display:grid`
   ниже окно заявки висело открытым сразу при заходе на страницу, хотя в JS `lead.hidden`
   честно было `true`. Проверять такие вещи надо по computed display, а не по свойству. */
.leadBlock[hidden]{ display:none !important; }

.leadBlock{ position:fixed; inset:0; z-index:120; overflow:auto; overscroll-behavior:contain;
  display:grid; place-items:start center; padding:24px 16px;
  background:rgba(6,10,10,.62); animation:leadFade .18s ease both; }
.leadBlock .helpMain{ width:min(1100px,100%); margin:0; position:relative;
  animation:leadIn .3s cubic-bezier(.22,.61,.36,1) both; }
body.leadOpen{ overflow:hidden; }

/* крестик — в углу карточки, не наезжает на заголовок */
.leadClose{ position:absolute; top:10px; right:12px; z-index:1; width:36px; height:36px;
  display:flex; align-items:center; justify-content:center; border-radius:10px;
  font-size:24px; line-height:1; color:#cfd6d6; background:rgba(255,255,255,.06);
  border:1px solid rgba(255,255,255,.14); }
.leadClose:hover{ color:#fff; background:rgba(255,255,255,.14); }

@container (max-width:699px){ .leadBlock{ padding:12px 10px 24px; } .leadClose{ top:6px; right:6px; } }
@media (prefers-reduced-motion:reduce){ .leadBlock, .leadBlock .helpMain{ animation:none; } }

/* Сводка выбора из 3D-конфигуратора. Переехала ИЗ формы в левую колонку блока заявки:
   в форме она вклинивалась между полями и чекбоксом, а слева места достаточно.
   Три строки: «Ваш выбор» / Фасад: … / Цоколь: … — плюс воздух вокруг, чтобы не
   слипалась с текстом. Блок тёмный (лежит на .helpMain), поэтому подложка светлая. */
.cfgPick{ display:grid; gap:6px; margin:24px 0 2px; padding:16px 16px; border-radius:var(--r-card);
  background:rgba(255,255,255,.06); border:1px solid rgba(255,255,255,.14);
  font-size:13px; line-height:1.4; color:#fff; }
.cfgPick b{ font-size:11px; font-weight:700; letter-spacing:.07em; text-transform:uppercase; color:#9fb0b0; }
.cfgPick span{ color:#fff; }

/* Подвал фильтров: «Показать» применяет всё сразу, «Сбросить» — рядом, серым.
   Раньше «Показать» стояла внутри группы цены, из-за чего казалось, что галочки
   фасовки/производителя ей не подчиняются. */
.fFoot{ display:flex; align-items:center; gap:12px; padding-top:16px; }
.fFoot .applyF{ margin-top:0; flex:1; }
/* =========================================================================
   НИЖНЯЯ ШТОРКА — фильтр и сортировка на мобильной.
   Раньше и то и другое раскрывалось прямо в потоке страницы: список товаров
   уезжал вниз, и человек терял место, на которое смотрел. Теперь это плашка
   поверх выдачи.

   Высота НЕ задана: коробка тянется по содержимому, упирается в 90% экрана
   и дальше листается внутри себя. Мало фильтров — низкая шторка, много —
   почти во весь экран. За это отвечают три вещи вместе: max-height у .sheetBox,
   overflow-y у .sheetBody и min-height:0 (без него флекс-элемент не даёт
   себя сжать, и шторка вылезала бы за экран).

   Живёт в <body>, а не внутри .v2root: там container-type, из-за которого
   position:fixed цепляется за контейнер, а не за экран (та же грабля, что
   с мобильным меню). Поэтому и адаптив здесь на @media, а не на @container. */
.sheet[hidden]{ display:none; }
.sheet{ position:fixed; inset:0; z-index:80; display:flex; align-items:flex-end; }
.sheetBack{ position:absolute; inset:0; background:rgba(15,20,22,.45); opacity:0; transition:opacity .2s ease; }
.sheet[data-on="true"] .sheetBack{ opacity:1; }
.sheetBox{ position:relative; width:100%; max-height:90vh; max-height:90dvh;
  display:flex; flex-direction:column; background:#fff; border-radius:18px 18px 0 0;
  box-shadow:0 -14px 44px -20px rgba(15,40,40,.55);
  transform:translateY(100%); transition:transform .24s cubic-bezier(.32,.72,0,1); }
.sheet[data-on="true"] .sheetBox{ transform:none; }
@media (prefers-reduced-motion:reduce){ .sheetBox, .sheetBack{ transition:none; } }
.sheetGrip{ width:38px; height:4px; border-radius:3px; background:#d6dcdc; margin:8px auto 2px; flex:none; }
.sheetHead{ display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:8px 16px 12px; border-bottom:1px solid var(--line); flex:none; }
.sheetHead b{ font-size:16px; font-weight:700; }
.sheetClose{ font-size:26px; line-height:1; color:var(--muted); background:none; border:0; padding:0 4px; }
.sheetClose:hover{ color:var(--ink); }
.sheetBody{ overflow-y:auto; -webkit-overflow-scrolling:touch; min-height:0; padding:0 16px;
  overscroll-behavior:contain; }
.sheetFoot{ flex:none; padding:12px 16px calc(12px + env(safe-area-inset-bottom));
  border-top:1px solid var(--line); }
.sheetDone{ width:100%; background:var(--ink); color:#fff; font-weight:700; font-size:15px;
  border:0; border-radius:11px; padding:14px; }
.sheetDone:hover{ background:#000; }

/* Содержимое переезжает в шторку как есть, поэтому здесь снимаем с него
   «карточную» обвязку: своя рамка и фон внутри шторки выглядели бы коробкой
   в коробке. */
.sheetBody .sidebar{ display:block; background:none; border:0; border-radius:0; padding:0; }
.sheetBody .fGroup:first-child{ padding-top:8px; }
.sheetBody .fFoot{ padding-bottom:4px; }
.sheetBody .sortLbl{ display:none; }
.sheetBody .sortBar{ display:flex; flex-direction:column; align-items:stretch; gap:0;
  background:none; border:0; border-radius:0; padding:4px 0 0; margin:0; }
/* Сортировка в шторке — список строк с галочкой, а не полоса «таблеток»:
   на узком экране таблетки переносились в три ряда и читались как мусор. */
.sheetBody .sortChip{ display:flex; align-items:center; justify-content:space-between;
  background:none; border-radius:0; padding:15px 2px; font-size:15px; font-weight:600;
  color:var(--ink); border-bottom:1px solid var(--line); }
.sheetBody .sortChip:last-child{ border-bottom:0; }
.sheetBody .sortChip[data-on="true"]{ background:none; color:var(--ink); }
.sheetBody .sortChip[data-on="true"]::after{ content:'✓'; color:var(--red); font-size:16px; font-weight:700; }

.resetF{ font-size:13px; color:var(--muted); white-space:nowrap; }
.resetF:hover{ color:var(--red); }

/* Карточка подраздела (.catCard.sub): картинка и заголовок выровнены по ВЕРХНЕМУ краю,
   стрелки нет. У обычной .catCard содержимое центрируется по вертикали и справа стрелка —
   на подразделах с двухстрочными названиями это смотрелось вразнобой. */
.catCard.sub{ align-items:flex-start; }
.catCard.sub .ct{ padding-top:2px; }

/* Компактные карточки каталога на ГЛАВНОЙ (модификаторы, чтобы не задеть каталог,
   где .catsGrid переиспользуется с карточками подразделов): только фото + название,
   без подзаголовка и стрелки, карточка и фото мельче. */
/* вертикальные карточки: фото сверху, название и количество под ним — все разделы в один ряд/экран */
.catsGrid--mini{ grid-template-columns:repeat(auto-fit,minmax(140px,1fr)); gap:var(--gap-card); }
/* На телефоне — РОВНО две в ряд. auto-fit тут не годится: при ширине контента
   меньше ~300px в ряд помещается один minmax(140px), и разделы вытягивались
   в одну колонку (снимок владельца 03.08.2026). Жёсткие две колонки от этого
   не зависят, а minmax(0,1fr) не даёт длинному названию распирать колонку. */
@container (max-width:699px){ .catsGrid--mini{ grid-template-columns:repeat(2,minmax(0,1fr)); } }
.catCard--mini{ flex-direction:column; align-items:center; text-align:center; padding:16px 12px; gap:8px; }
.catCard--mini .catIco{ width:58px; height:58px; border-radius:10px; }
.catCard--mini .ct{ flex:none; }
.catCard--mini b{ font-size:13px; margin-bottom:2px; line-height:1.25; }
.catCard--mini span{ font-size:11px; }

/* Страница «Колеровка» (v2): вводный текст и крупный конфигуратор */
.cfgIntro{ max-width:70ch; font-size:15px; line-height:1.6; color:#37413f; margin:0 0 16px; }
.cfgWrap--full{ margin-top:4px; }

/* Полные названия товаров («Плиточный клей Церезит CM 9 Plus») длиннее коротких из
   макета, поэтому карточки в сетке разъезжались бы по высоте. Ограничиваем тремя
   строками: заголовок занимает фиксированное место, полный текст — в title. */
.cardName{ display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; min-height:52px; }

/* Кнопки «Показать» больше нет — фильтр применяется сразу. В подвале остаётся только
   «Сбросить», и он показывается лишь при активном фильтре: поэтому у пустого .fFoot
   не должно быть ни отступа, ни рамки, иначе внизу сайдбара висела бы пустая полоса. */
.fFoot{ padding-top:0; }
/* Отступ над «Сбросить фильтры» и под ней одинаковый — 16px. Сверху его даёт
   padding-top, снизу — padding-bottom самого сайдбара (тоже 16px), поэтому здесь
   padding-bottom не задаём. margin-top убран: зазор до линии уже даёт нижний
   padding последнего блока фильтров, с ним получалось 20px против 16px. */
.fFoot:has(.resetF:not([hidden])){ padding-top:16px; border-top:1px solid var(--line); margin-top:0; }
.fFoot .resetF{ display:block; text-align:center; font-weight:600; }

/* Пока подгружается новая выдача, список чуть гаснет — видно, что данные меняются.
   Прокрутку при этом не трогаем: страница не перезагружается, человек остаётся
   ровно там, где смотрел. */
#mse2_results{ transition:opacity .15s ease; }
#mse2_results[data-loading="true"]{ opacity:.45; pointer-events:none; }

/* =========================================================================
   ОТЗЫВЫ И ОЦЕНКИ (v2Reviews)
   Звезда — одна SVG-картинка в data:URI, серая подложка + красная заливка
   шириной в процентах. Так «4,9» рисуется честно, а не округляется до 5.
   Размер задаётся одной переменной --rvS, поэтому один и тот же компонент
   работает и в карточке каталога, и в шапке товара, и в блоке отзывов.

   ⚠️ Цвет заливки звезды — ЧИСЛОМ внутри data:URI (%23e4002b), а не var(--red):
   в data:URI переменная не подставляется, картинка там разбирается как отдельный
   документ. Значит при смене фирменного красного этот код надо править РУКАМИ,
   иначе звёзды останутся прежними, а кнопки поменяются — и никто не поймёт почему.
   Переменная называется --rvStarOn, а не --rvGold: имя с цветом устаревает
   при первой же перекраске (звёзды были золотыми до 03.08.2026).
   ========================================================================= */
.v2root{
  --rvGrey:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23d5dbdb' d='M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/%3E%3C/svg%3E");
  --rvStarOn:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23e4002b' d='M12 17.27 18.18 21l-1.64-7.03L22 9.24l-7.19-.61L12 2 9.19 8.63 2 9.24l5.46 4.73L5.82 21z'/%3E%3C/svg%3E");
}
.rvStars{ --rvS:16px; display:inline-flex; align-items:center; gap:2px; vertical-align:middle; flex:none; }
.rvStar{ position:relative; display:inline-block; width:var(--rvS); height:var(--rvS);
  background:var(--rvGrey) center/var(--rvS) var(--rvS) no-repeat; }
.rvStar b{ position:absolute; top:0; left:0; bottom:0; width:0;
  background:var(--rvStarOn) left center/var(--rvS) var(--rvS) no-repeat; }
.rvStars--sm{ --rvS:13px; }
.rvStars--lg{ --rvS:21px; gap:2px; }
/* Одиночная звезда-значок (v2rev_star1): пять звёзд остались только там, где
   показывают распределение. Размер тут не задаём — его берут .rvStars--sm в
   плитке и .pRate .rvStars на странице товара. */
.rvStars--one{ flex:none; }
.rvStar--sm{ --rvS:12px; position:relative; display:inline-block; width:var(--rvS); height:var(--rvS);
  background:var(--rvGrey) center/var(--rvS) var(--rvS) no-repeat; }
.rvStar--sm b{ background:var(--rvStarOn) left center/var(--rvS) var(--rvS) no-repeat; }

/* ---- оценка в карточке каталога (блок .cardMeta из макета) ---- */
.cardMeta .rvAvg{ font-size:13px; font-weight:700; color:var(--ink); }
.cardMeta .revCnt{ font-size:13px; color:var(--faint); }
/* Звезда осталась одна — на 13px рядом с цифрой она читалась мелкой точкой. */
.cardMeta .rvStars--one{ --rvS:14px; }

/* ---- строка с оценкой под названием товара ---- */
/* Строка рейтинга под названием. Все три части — звёзды, оценка, счётчик — одного
   кегля и по одной базовой линии: раньше «5,0» была жирнее и крупнее счётчика, и цифры
   гуляли по высоте. Подчёркивания нет — на кликабельность указывает красный счётчик. */
/* Отступ сверху положительный, не отрицательный: строка со звёздами — отдельная
   сущность под H1, а не его продолжение. С margin-top:-2px она липла к заголовку. */
.pRate{ display:inline-flex; align-items:center; gap:8px; margin:12px 0 12px; }
.pRate b{ font-size:15px; font-weight:700; color:var(--ink); line-height:1; }
.pRate span{ font-size:15px; font-weight:600; color:var(--red); line-height:1; border-bottom:0; }
.pRate:hover span{ color:var(--red-d); }
.pRate .rvStars{ --rvS:15px; }

/* ---- блок отзывов ---- */
.rvWrap{ scroll-margin-top:14px; margin-top:36px; }
.rvWrap .secHead h2{ display:flex; align-items:center; gap:8px; }
.rvCnt{ font-size:15px; font-weight:700; color:var(--muted); background:#eef1f1; border-radius:var(--r-block); padding:4px 12px; }
.rvOpen{ font-size:13px; font-weight:700; color:var(--red); }

/* Две колонки: слева лента, справа липкая сводка (десктоп — см. @container ниже).
   На мобилке колонки схлопываются, и сводка встаёт НАД лентой (order). */
.rvCols{ display:grid; gap:16px; align-items:start; }
.rvMain{ min-width:0; }
.rvSide{ min-width:0; }
.rvSideBtn{ width:100%; background:var(--red); color:#fff; font-weight:700; font-size:15px;
  padding:12px; border-radius:10px; display:flex; align-items:center; justify-content:center; transition:background .15s ease; }
.rvSideBtn:hover{ background:var(--ink); color:#fff; }
.rvTop{ display:grid; gap:20px; background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:20px; }
.rvBig{ display:flex; flex-direction:column; align-items:flex-start; gap:6px; }
.rvBigNum{ font-size:28px; font-weight:700; line-height:1; letter-spacing:-.02em; }
.rvBigSub{ font-size:13px; color:var(--muted); }
.rvBars{ display:flex; flex-direction:column; gap:6px; justify-content:center; }
.rvBar{ display:flex; align-items:center; gap:8px; font-size:13px; color:var(--muted); }
.rvBarK{ width:9px; text-align:right; font-weight:600; color:var(--ink); }
.rvBarLine{ flex:1; height:7px; border-radius:6px; background:#eef1f1; overflow:hidden; }
.rvBarLine b{ display:block; height:100%; background:var(--red); border-radius:6px; }
.rvBarN{ width:22px; text-align:right; font-variant-numeric:tabular-nums; }
.rvNote{ font-size:13px; line-height:1.5; color:var(--faint); border-top:1px solid var(--line); padding-top:12px; }

.rvMsg{ margin:16px 0 0; padding:12px 16px; border-radius:10px; font-size:15px; font-weight:600; }
.rvMsg--ok{ background:#e8f6ee; color:#136c42; }
.rvMsg--err{ background:#fdeef1; color:var(--red-d); }

/* ---- форма ---- */
.rvForm{ background:#fff; border:1px solid var(--line); border-radius:var(--r-card); padding:20px; margin-top:16px; }
.rvForm[hidden]{ display:none; }
.rvFormHead{ font-weight:700; font-size:17px; margin-bottom:12px; }
.rvFormRate{ display:flex; align-items:center; gap:12px; margin-bottom:16px; }
.rvFormLbl{ font-size:13px; font-weight:600; color:var(--muted); }
/* Звёзды-переключатель: input спрятан, кликаем по label. Порядок в разметке —
   от 5 к 1, поэтому «наведённая и все левее» подсвечиваются через ~ (соседей справа
   в CSS нет, а справа в разметке лежат как раз меньшие оценки). */
.rvPick{ display:inline-flex; flex-direction:row-reverse; gap:4px; }
.rvPick input{ position:absolute; opacity:0; width:0; height:0; }
.rvPick label{ cursor:pointer; line-height:0; padding:2px; }
.rvPick label .rvStar{ --rvS:26px; }
.rvPick label .rvStar b{ width:0; transition:width .1s ease; }
.rvPick input:checked ~ label .rvStar b{ width:100%; }
/* пока мышь над выбором — показываем ТО, на что наведён курсор, а не то, что выбрано */
.rvPick:hover input:checked ~ label .rvStar b{ width:0; }
.rvPick label:hover .rvStar b,
.rvPick label:hover ~ label .rvStar b{ width:100%; }
.rvPick input:focus-visible + label{ outline:2px solid var(--ink); border-radius:4px; }
.rvFormGrid{ display:grid; gap:12px; }
.rvFld{ display:flex; flex-direction:column; gap:6px; }
.rvFld > span{ font-size:13px; font-weight:600; color:var(--muted); }
.rvFld > span i{ font-style:normal; font-weight:500; color:var(--faint); }
.rvFld input, .rvFld textarea{ border:1.5px solid var(--line); border-radius:10px; padding:12px 12px;
  font-size:15px; color:var(--ink); background:#fff; outline:none; resize:vertical; width:100%; }
.rvFld input:focus, .rvFld textarea:focus{ border-color:var(--muted); }
.rvFld--full{ margin-top:12px; }
.rvHp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }
.rvFormFoot{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-top:16px; }
.rvSend{ background:var(--red); color:#fff; font-weight:700; font-size:15px; padding:12px 24px; border-radius:10px; }
.rvSend:hover{ background:var(--ink); color:#fff; }
.rvCancel{ font-size:13px; font-weight:600; color:var(--muted); }
.rvCancel:hover{ color:var(--ink); }
.rvPolicy{ font-size:13px; color:var(--faint); }

/* ---- список ---- */
/* Лента отзывов: без рамок-карточек — только отбивка между соседями.
   Так список читается как единый текст, а не как набор плашек. */
.rvList{ display:flex; flex-direction:column; margin-top:6px; }
.rvItem{ display:flex; gap:12px; background:none; border:0; padding:20px 0; }
.rvItem + .rvItem{ border-top:1px solid var(--line); }
.rvItem--hide{ display:none; }   /* снимается по одному в js/v2.js, порциями */
.rvAva{ flex:none; width:40px; height:40px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-weight:700; font-size:17px; color:#fff; background:var(--teal); }
.rvAva[data-c="0"]{ background:#2f6f5e; } .rvAva[data-c="1"]{ background:#3a5f88; }
.rvAva[data-c="2"]{ background:#8a5a2b; } .rvAva[data-c="3"]{ background:#6b4a7a; }
.rvAva[data-c="4"]{ background:#2b6f86; } .rvAva[data-c="5"]{ background:#7a5142; }
.rvBody{ min-width:0; flex:1; }
.rvHead{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-bottom:4px; }
.rvName{ font-size:15px; font-weight:700; }
.rvCity{ font-size:13px; color:var(--muted); }
.rvOk{ font-size:11px; font-weight:700; color:var(--green); background:#e8f6ee; border-radius:6px; padding:4px 8px; }
.rvDate{ font-size:13px; color:var(--faint); margin-left:auto; }
.rvText{ font-size:15px; line-height:1.6; color:#2c3634; margin-top:6px; }
.rvMore{ display:inline-flex; align-items:center; justify-content:center; width:auto; margin-top:16px;
  padding:12px 24px; border:1px solid var(--line); background:#fff;
  border-radius:10px; font-weight:700; font-size:15px; color:var(--ink); }
.rvMore:hover{ border-color:#cfd8d8; color:var(--red); }
.rvEmpty{ background:#fff; border:1px dashed #d6dede; border-radius:var(--r-card); padding:24px; margin-top:16px;
  font-size:15px; line-height:1.6; color:var(--muted); max-width:70ch; }

@container (min-width:700px){
  /* лента слева, сводка справа фиксированной колонкой */
  .rvCols{ grid-template-columns:minmax(0,1fr) 300px; gap:24px; }
  .rvSide{ position:sticky; top:14px; }
  .rvTop{ gap:16px; padding:20px; }
  .rvFormGrid{ grid-template-columns:1fr 1fr; }
}
@container (max-width:699px){
  /* одна колонка: сводка выше ленты — так же, как на мобилке у Петровича */
  .rvCols{ grid-template-columns:1fr; }
  .rvMain{ order:2; }
  .rvSide{ order:1; }
  .rvTop{ padding:16px; gap:16px; }
  .rvBigNum{ font-size:21px; }
  .rvBig{ flex-direction:row; align-items:center; gap:12px; flex-wrap:wrap; }
  .rvBigSub{ width:100%; }
  .rvItem{ padding:16px 0; gap:12px; }
  .rvAva{ width:34px; height:34px; font-size:14px; }
  .rvDate{ margin-left:0; width:100%; }
  .rvText{ font-size:14px; }
  .rvPick label .rvStar{ --rvS:30px; }
  .rvSend{ width:100%; justify-content:center; }
  .rvFormFoot{ gap:10px; }
}

/* ---- ТЕСТ: выбор цвета на 3D-доме (v2ColorHouse) ---- */
.chWrap{ margin:20px 0 40px; }
.chHead{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-bottom:12px; }
.chHead h2{ font-size:20px; font-weight:700; }
.chHead span{ font-size:13px; color:var(--muted); }
.chFrame{ border:1px solid var(--line); border-radius:var(--r-card); overflow:hidden; background:#0e1417; }
/* clamp, а не min(): если vh почему-то схлопывается в 0, кадр всё равно получит 420px */
.chFrame iframe{ display:block; width:100%; height:clamp(420px,78vh,700px); border:0; }
.chPick{ margin-top:16px; border:1px solid var(--line); border-radius:var(--r-card); padding:16px; background:#fafbfb; }
.chPickEmpty{ font-size:13px; color:var(--muted); line-height:1.5; }
.chPickBody{ display:flex; align-items:center; gap:12px; }
.chSw{ width:44px; height:44px; border-radius:10px; flex:none; box-shadow:inset 0 0 0 1px rgba(0,0,0,.15); }
.chInfo{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.chInfo b{ font-size:15px; font-weight:700; }
.chInfo span{ font-size:13px; color:var(--muted); }
#chForm{ margin-top:12px; }
#chForm .bbAdd{ width:100%; height:46px; }
@container (max-width:699px){ .chFrame iframe{ height:clamp(360px,70vh,560px); } }

/* auto-fit вместо auto-fill: при auto-fill сетка создаёт столько колонок, сколько влезает
   по минимальной ширине, и лишние остаются пустыми — ряд из 7 разделов не доходил до
   правого края. auto-fit схлопывает пустые треки, и карточки растягиваются на всю ширину,
   вровень с сеткой товаров под ними. */

/* ===== Вкладки карточки товара: единая типографика =====
   Контент вкладок приходит из базы (описание / применение / характеристики /
   инструкция). Раньше в нём мешались h2, h3 и h4 из разных источников, и отступы
   гуляли от товара к товару. Теперь правило одно: подзаголовок ВСЕГДА <h3>,
   между блоками всегда один и тот же отступ, от заголовка до текста — свой,
   меньший. Разметку под этот контракт готовит scripts/build_cards.py. */
.v2Tab{ max-width:78ch; }
.v2Tab > *{ margin-top:16px; }
.v2Tab > *:first-child{ margin-top:0; }

.v2Tab h2, .v2Tab h3, .v2Tab h4{ font-size:17px; line-height:1.35; font-weight:700; color:var(--ink); margin-top:28px; }
.v2Tab > h2:first-child, .v2Tab > h3:first-child, .v2Tab > h4:first-child{ margin-top:0; }
.v2Tab h2 + *, .v2Tab h3 + *, .v2Tab h4 + *{ margin-top:12px; }

.v2Tab p{ margin-top:16px; }
.v2Tab ul, .v2Tab ol{ margin:16px 0 0 20px; }
.v2Tab li{ margin-top:6px; }
.v2Tab li:first-child{ margin-top:0; }

/* Таблицы (характеристики, расход) — прокрутка вместо ломки сетки на мобилке */
.v2Tab .tableWrap{ margin-top:16px; overflow-x:auto; }
.v2Tab h3 + .tableWrap{ margin-top:12px; }
.v2Tab .tableWrap table{ margin-top:0; min-width:min(100%,440px); }

.v2Tab .specTable th{ width:58%; font-weight:500; color:var(--muted); }
.v2Tab .specTable td{ font-weight:700; }
.v2Tab .specTable tr:nth-child(odd) th, .v2Tab .specTable tr:nth-child(odd) td{ background:#fafbfb; }

.v2Tab .rashodTable thead th{ background:#f2f5f5; font-weight:700; color:var(--ink); }
.v2Tab .rashodTable td{ white-space:nowrap; }

@media (max-width:699px){
  .v2Tab .specTable th{ width:52%; }
  .v2Tab .tableWrap table{ font-size:14px; }
}

/* Уточнение к предыдущему блоку: auto-fit оставлен ТОЛЬКО для ленты разделов на главной
   (.catsGrid--mini). Там карточек ровно 7 и они должны заполнять ряд до края.
   Внутри каталога подразделов бывает 2–3, и auto-fit растягивал бы их на полэкрана —
   поэтому у .catsGrid остаётся auto-fill: карточки держат нормальную ширину. */

/* Попап колеровки с 3D-домом: виджет сам делит кадр на дом + палитру,
   поэтому от сайта нужен только крупный кадр. */
.cpBox--house{ width:min(1180px,100%); }
.cpHouse{ background:#0e1417; }
.cpHouse iframe{ display:block; width:100%; height:clamp(420px,72vh,660px); border:0; }
/* Мобилка: попап колеровки почти во весь экран — сверху остаётся узкая полоска.
   Лист выбора внутри виджета держит свою высоту, а всё оставшееся место
   достаётся визуализации дома. Тёмный контейнер — во всю ширину экрана. */
@container (max-width:699px){
  .cpModal{ padding:10px 8px; align-items:flex-start; }
  /* max-height:86vh стоит в базовом .cpBox — здесь его снимаем, иначе попап не дорастает */
  .cpBox--house{ width:100%; height:calc(100dvh - 20px); max-height:none; display:flex; flex-direction:column; }
  .cpBox--house .cpHouse{ flex:1; min-height:0; border-radius:var(--r-card); }
  .cpHouse iframe{ height:100%; }
  .cpX{ top:6px; right:8px; }
}

/* =========================================================================
   Полосы прокрутки у горизонтальных лент — скрыть.
   Ленты (товары, промо, разделы в шапке, миниатюры, вкладки) листаются пальцем и
   колесом, а серая полоса под каждым блоком читалась как элемент интерфейса и мусорила
   макет. Прокрутка остаётся, исчезает только её индикатор.
   Подсказка, что блок листается, никуда не делась: следующая карточка намеренно видна
   краем, плюс работает scroll-snap.
   padding-bottom у лент был резервом под эту самую полосу — снимаем вместе с ней,
   иначе под блоком остался бы пустой отступ.
   ========================================================================= */
.prodRow, .swatchRow, .catbarIn, .promoCol, .thumbs, .tabsBar, .v2Tab .tableWrap, .newsGrid--home{
  scrollbar-width:none;          /* Firefox */
  -ms-overflow-style:none;       /* старый Edge */
}
.prodRow::-webkit-scrollbar,
.swatchRow::-webkit-scrollbar,
.catbarIn::-webkit-scrollbar,
.promoCol::-webkit-scrollbar,
.thumbs::-webkit-scrollbar,
.tabsBar::-webkit-scrollbar,
.v2Tab .tableWrap::-webkit-scrollbar{ display:none; width:0; height:0; }

/* Нижний отступ нужен: полоса прокрутки скрыта, но тени карточек на наведении
   уходят вниз на ~14px, а `overflow-x:auto` режет всё, что вылезло за высоту
   ленты. Без этих 16px тень обрезалась ровно по нижней кромке карточки. */
.prodRow{ padding-bottom:16px; }
.swatchRow{ padding-bottom:0; }

/* Попап колеровки: только виджет, без белых полос. Крестик — поверх кадра. */
.cpBox--house{ background:transparent; box-shadow:none; }
.cpBox--house .cpHouse{ border-radius:var(--r-block); overflow:hidden; }
.cpX{ position:absolute; top:8px; right:10px; z-index:2; width:34px; height:34px; border-radius:8px;
  background:rgba(20,26,30,.55); color:#fff; font-size:20px; line-height:1; display:flex;
  align-items:center; justify-content:center; }
.cpX:hover{ background:rgba(20,26,30,.85); }

/* =========================================================================
   Страница колеровки: текст оригинала, разложенный по блокам.
   Слова НЕ менялись — менялась только группировка: рассказ о студии, про
   онлайн-выкрас, ассортимент штукатурок, этапы колеровки, преимущества,
   пробный выкрас. Раньше это шло одной простынёй абзацев подряд.
   ========================================================================= */
.kolText{ display:grid; gap:16px; margin-top:28px; }
.kolCard{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block); padding:24px; }
.kolCard h2{ font-family:var(--font-head); font-size:20px; font-weight:var(--fw-head); letter-spacing:var(--ls-head); line-height:1.25; margin-bottom:12px; }
.kolCard h3{ font-family:var(--font-head); font-size:17px; font-weight:700; line-height:1.35; margin-bottom:8px; }
.kolCard p{ font-size:15px; line-height:1.75; color:#37413f; }
.kolCard p + p{ margin-top:12px; }
.kolLead{ font-weight:700; color:var(--ink) !important; margin-bottom:16px; }

/* акцентный блок про онлайн-выкрас — он про сервис, который стоит выше на странице */
.kolCard--accent{ background:var(--ink); border-color:var(--ink); color:#cfd6d6; }
.kolCard--accent h3{ color:#fff; font-size:17px; }
.kolCard--accent p{ color:#cfd6d6; }

/* сноска в конце — тише основного текста */
.kolCard--note{ background:var(--teal-l); border-color:transparent; }

/* ассортимент: список штукатурок со ссылками на товары */
.kolPlast{ list-style:none; display:grid; grid-template-columns:1fr; gap:8px; }
.kolPlast li{ padding:12px 16px; border:1px solid var(--line); border-radius:10px; font-size:13px; line-height:1.5; color:#37413f; }
.kolPlast a{ font-weight:700; color:var(--ink); white-space:nowrap; }
.kolPlast a:hover{ color:var(--red); }

/* этапы колеровки — карточки по порядку, номер уже есть в самом заголовке */
.kolSteps{ display:grid; grid-template-columns:1fr; gap:12px; counter-reset:none; }
.kolStep{ padding:16px 16px; border:1px solid var(--line); border-radius:var(--r-card); background:#fcfdfd; }
.kolStep h3{ font-size:15px; margin-bottom:6px; }
.kolStep p{ font-size:13px; color:var(--muted); }

.kolPerks{ margin-top:0; }

@container (min-width:700px){
  .kolText{ gap:20px; }
  .kolCard{ padding:28px; }
  .kolCard h2{ font-size:24px; }
  .kolPlast{ grid-template-columns:1fr 1fr; }
  .kolSteps{ grid-template-columns:1fr 1fr; }
}
@container (min-width:1100px){
  .kolSteps{ grid-template-columns:repeat(4,1fr); }
}

/* =========================================================================
   Кейсы (страница работы партнёра + список работ)
   Слайдеры — на scroll-snap: трек прокручивается сам, кнопки лишь двигают его
   на ширину слайда. Свайп и клавиатура работают без JS, скрипт только рисует
   стрелки/точки. Библиотек нет намеренно: на v2-шаблонах вендорный бандл
   не подключается (см. HANDOFF).
   ========================================================================= */

/* ---- шапка кейса ---- */
/* Воздух над H1 и под ним задаём здесь, а не в .crumbs: крошки общие для
   каталога и карточки товара, там интервал другой и его трогать нельзя. */
/* Отступ под заголовком 24px — такой же, как между колонками .caseLayout. */
.caseHead{ margin:12px 0 24px; }
/* Ограничения ширины нет: при `max-width:24ch` заголовок ломался на две строки
   уже на «Деревня Ордынцы (Подольский район)» — 33 знака. Самый длинный
   заголовок кейса 46 знаков, на 28px это ~700px и свободно влезает в строку. */
.caseHead h1{ font-family:var(--font-head); font-size:var(--fs-h1); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.15; }
.caseMeta{ display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
.caseTag{ font:600 12.5px/1 var(--font-body); color:var(--muted); background:#f2f5f5; border-radius:8px; padding:8px 12px; }

/* Кадр объекта идёт первым и в разметке, и на экране — на любой ширине:
   сначала показываем объект, потом рассказываем. Перестановок через order
   больше нет, порядок задаёт сам чанк v2_case. */
.caseLayout{ display:grid; grid-template-columns:1fr; gap:24px; align-items:start; }
.caseCol{ min-width:0; }

.caseBlock + .caseBlock{ margin-top:28px; }
/* Заголовки секций кейса — ОДИН стиль на все: «Помогли в работе», «Материалы»
   и заголовки лент. Раньше этот был мелкой капслок-меткой 12px, а соседние —
   обычными h2, и на телефоне это читалось как два разных уровня.
   Кегль здесь НЕ задаём: он живёт в блоке типографики внизу файла вместе
   с .secHead h2 — иначе заголовки опять разъедутся. */
.caseBlock h2{ font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.25; color:var(--ink); margin-bottom:12px; }
.caseList{ list-style:none; display:flex; flex-direction:column; gap:12px; }
.caseList li{ position:relative; padding-left:20px; font-size:15px; line-height:1.6; color:#37413f; }
/* Точки чёрные, а не красные: красный на сайте — цвет действия, а это просто
   маркер списка. */
.caseList li::before{ content:''; position:absolute; left:3px; top:9px; width:6px; height:6px;
  border-radius:50%; background:var(--ink); }
.caseList a{ color:var(--ink); border-bottom:1px solid #d8dede; }
.caseList a:hover{ color:var(--red); border-color:currentColor; }

/* ---- слайдер ---- */
.slider{ position:relative; min-width:0; }
/* scroll-behavior:smooth здесь намеренно НЕТ: в части окружений программная
   прокрутка с ним просто не выполняется (проверено — scrollLeft остаётся 0).
   Плавность делает сам v2.js через requestAnimationFrame, это работает везде. */
.sliderTrack{ display:flex; gap:12px; overflow-x:auto; scroll-snap-type:x mandatory;
  scrollbar-width:none; }
.sliderTrack::-webkit-scrollbar{ display:none; }
.sliderTrack > *{ scroll-snap-align:start; flex:0 0 100%; min-width:0; }

.slideImg{ width:100%; aspect-ratio:4/3; object-fit:cover; border-radius:var(--r-block);
  display:block; background:#eef1f1; }

.sliderBtn{ position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  width:44px; height:44px; border-radius:50%; background:#fff; color:var(--ink);
  border:1px solid var(--line); box-shadow:0 6px 20px -8px rgba(15,40,40,.45);
  display:flex; align-items:center; justify-content:center; font-size:17px; }
.sliderBtn:hover{ border-color:var(--ink); }
.sliderBtn[disabled]{ opacity:0; pointer-events:none; }
.sliderBtn.prev{ left:12px; } .sliderBtn.next{ right:12px; }
@container (max-width:699px){ .sliderBtn{ display:none; } }

.sliderDots{ display:flex; justify-content:center; gap:8px; margin-top:12px; }
.sliderDots i{ width:7px; height:7px; border-radius:50%; background:#cfd6d6; cursor:pointer; }
.sliderDots i[data-on="true"]{ background:var(--red); width:20px; border-radius:4px; }

/* Галерея объекта: точки лежат НА снимке, а не строкой под ним. Тёмная
   подложка обязательна — без неё точки теряются на светлом фасаде.
   Счётчика «1 / 7» тут намеренно нет, точки показывают то же самое. */
.slider--photos .sliderDots{ position:absolute; left:50%; bottom:14px; z-index:2;
  transform:translateX(-50%); margin:0; padding:8px 12px; border-radius:10px;
  background:rgba(12,17,19,.55); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
.slider--photos .sliderDots i{ background:rgba(255,255,255,.45); }
.slider--photos .sliderDots i[data-on="true"]{ background:#fff; }

/* ---- материалы объекта: отдельной секцией под кадром ---- */
.caseMats{ margin-top:36px; }
.caseMats h2{ font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.25; margin-bottom:16px; }
/* перебивает display:flex у .caseList — правило ниже по файлу */
.caseMatsList{ display:grid; grid-template-columns:minmax(0,1fr); gap:12px 32px; }

/* ---- лента «Ещё работы наших партнёров» ---- */
.caseStrip{ margin-top:44px; }
.caseStrip .secHead{ margin-bottom:16px; }
.caseStrip .sliderTrack > *{ flex:0 0 78%; }
.caseCard{ display:block; min-width:0; }
.caseCard img{ width:100%; aspect-ratio:4/3; object-fit:cover; border-radius:var(--r-card);
  display:block; background:#eef1f1; transition:transform .2s ease; }
.caseCard:hover img{ transform:translateY(-2px); }
.caseCard b{ display:block; font-size:13px; font-weight:700; line-height:1.35;
  color:var(--ink); margin-top:12px; }
.caseCard:hover b{ color:var(--red); }
.caseCard span{ display:block; font-size:13px; color:var(--faint); margin-top:4px; }

/* ---- список всех работ ---- */
/* Здесь подпись лежит НА фото: тогда плитка — цельный прямоугольник, и большая
   карточка мозаики ровно накрывает четыре маленькие. Подпись под фото осталась
   только в лентах (.caseStrip), там карточки одного размера. */
.caseGrid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; margin-top:8px; }
.caseGrid > .caseCard{ position:relative; aspect-ratio:4/3; overflow:hidden;
  border-radius:var(--r-card); background:#eef1f1; }
.caseGrid > .caseCard img{ position:absolute; inset:0; width:100%; height:100%;
  aspect-ratio:auto; border-radius:0; }
.caseGrid > .caseCard::after{ content:''; position:absolute; left:0; right:0; bottom:0; height:60%;
  background:linear-gradient(to top, rgba(8,12,14,.85), rgba(8,12,14,.35) 45%, rgba(8,12,14,0)); }
.caseGrid > .caseCard b{ position:absolute; left:14px; right:14px; bottom:12px; z-index:1;
  margin:0; color:#fff; font-size:13px; text-shadow:0 1px 10px rgba(0,0,0,.5);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
/* базовый ховер сдвигает картинку вверх — у абсолютной это дало бы щель снизу */
.caseGrid > .caseCard:hover img{ transform:scale(1.05); }
.caseGrid > .caseCard:hover b{ color:#fff; }

@container (min-width:700px){
  .caseLayout{ grid-template-columns:minmax(0,1.15fr) minmax(0,1fr); gap:28px; }
  .caseHead{ margin:16px 0 24px; }
  .caseHead h1{ font-size:28px; }
  .caseMats{ margin-top:44px; }
  .caseMatsList{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .caseStrip .sliderTrack > *{ flex:0 0 calc((100% - 12px) / 2); }
  .caseGrid{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}
@container (min-width:1100px){
  .caseLayout{ grid-template-columns:minmax(0,1fr) minmax(0,420px); gap:40px; }
  .caseHead{ margin:24px 0 24px; }
  .caseHead h1{ font-size:28px; line-height:1.08; }
  .caseMats{ margin-top:56px; }
  .caseMatsList{ grid-template-columns:repeat(3,minmax(0,1fr)); }
  .caseStrip .sliderTrack > *{ flex:0 0 calc((100% - 36px) / 4); }

  /* Мозаика: блок из пяти работ — большая плитка 2×2 и четыре обычные рядом;
     в следующем блоке большая уходит вправо. Держится на dense-упаковке:
     у большой задана только колонка, строку подбирает сам грид, а маленькие
     сами затекают в оставшиеся клетки.
     :not(:nth-last-child(-n+4)) — про хвост: если за большой осталось меньше
     четырёх работ, она становится обычной, иначе в конце зияет дыра. */
  .caseGrid{ grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px; grid-auto-flow:row dense; }
  .caseGrid > .caseCard:nth-child(10n+1):not(:nth-last-child(-n+4)),
  .caseGrid > .caseCard:nth-child(10n+6):not(:nth-last-child(-n+4)){
    grid-row:span 2; aspect-ratio:auto; height:100%; }
  .caseGrid > .caseCard:nth-child(10n+1):not(:nth-last-child(-n+4)){ grid-column:1 / span 2; }
  .caseGrid > .caseCard:nth-child(10n+6):not(:nth-last-child(-n+4)){ grid-column:3 / span 2; }
  .caseGrid > .caseCard:nth-child(10n+1):not(:nth-last-child(-n+4)) b,
  .caseGrid > .caseCard:nth-child(10n+6):not(:nth-last-child(-n+4)) b{
    left:22px; right:22px; bottom:20px; font-size:17px; -webkit-line-clamp:3; }
}

/* =========================================================================
   ЗАГОЛОВКИ РАЗДЕЛОВ — МЕЛЬЧЕ (правка 30.07.2026)
   На 375px кегль 26/24px ломал «Каталог продукции» и «Оформление фасада
   Церезит» на две строки, а рядом ещё стоял красный CTA и отбирал ширину.
   Базовый кегль снижен в переменных (--fs-h1 26→24, --fs-h2 24→21) — это
   работает и на десктопе, как просили; ниже отдельный шаг для мобильной.
   Правится в ОДНОМ месте: сами переменные + этот блок. Точечно по секциям
   размер не задавать, иначе заголовки опять разъедутся по кеглям.
   ========================================================================= */
@container (max-width:699px){
  /* Зазоры на телефоне те же, что на десктопе — по правке 03.08.2026 сетка едина
     для обеих версий. Если когда-нибудь понадобится развести: переопределять ТОКЕН
     на .wrap, а не каждый блок по отдельности. На самом .v2root не сработает —
     он объявлен контейнером и своим же @container не выбирается. */
  .secHead{ margin:var(--sec-gap) 0 var(--head-gap); gap:12px; }
  /* На телефоне заголовок блока мельче, чем на десктопе: 28px из --fs-h2 ломали
     длинные названия на три-четыре строки («Ключевые преимущества декоративных
     штукатурок», дилер). 22px — компромисс: крупно, но в одну-две строки.
     ⚠️ Список селекторов обязан повторять группу общего правила (рядом с
     .secHead h2). Когда-то тут стоял только .secHead h2 — и на узком экране
     заголовки разъезжались: секции 18px, а дилер и преимущества 21px. */
  .secHead h2,
  .distrib h3,
  .advBlock__text h2,
  .roles__title,
  .cartEmpty h2,
  .caseBlock h2,
  .caseMats h2,
  .coH2{ font-size:20px; line-height:1.18; }
  h1.pTitle,
  .catTop h1,
  .caseHead h1{ font-size:20px; line-height:1.25; }
  .kolIntro h2{ font-size:20px; }
  .secHead .secMore{ font-size:13px; }
}

/* -------------------------------------------------------------------------
   3D-КОНФИГУРАТОР НА МОБИЛЬНОЙ — ВО ВСЮ ШИРИНУ ЭКРАНА.
   .wrap.page держит боковые отступы 12px. Блок с домом снимает их
   отрицательными марджинами (ровно на величину этих отступов) и отдаёт
   всю ширину экрана 3D-кадру. Радиус и тень при этом убираются: скруглённые
   углы, упирающиеся в края экрана, читаются как недоверстанный блок.
   ⚠️ Марджины должны совпадать с padding у .wrap.page — правишь один,
   правь и второй, иначе появится горизонтальная прокрутка страницы.
   На десктопе блок остаётся внутри сетки страницы, как был.
   ------------------------------------------------------------------------- */
@container (max-width:699px){
  /* Возвращено по правке 03.08.2026: во всю ширину экрана — РОВНО ОДИН блок на сайте,
     этот. Решение владельца: 3D-кадр с домом должен быть максимально крупным, всё
     остальное стоит по сетке с полями --pad-x.
     История: 30.07.2026 полную ширину уже отменяли — тогда блок был единственным без
     полей и читался как «сетка поехала». Сейчас это осознанное исключение, а не
     недосмотр: скругление снимаем, чтобы углы не упирались в края экрана.
     ⚠️ Марджины обязаны совпадать с боковым padding у .wrap.page — поэтому здесь
     тот же токен --pad-x, а не число. Разъедутся — появится горизонтальная прокрутка. */
  .cfgWrap{ margin-left:calc(-1 * var(--pad-x)); margin-right:calc(-1 * var(--pad-x)); }
  .cfgWrap iframe{ border-radius:0; }
}

/* -------------------------------------------------------------------------
   ПРОМО-ПЛИТКИ ПОД БАННЕРОМ НА МОБИЛЬНОЙ — РОВНО ДВЕ, БЕЗ ЛЕНТЫ.
   Плиток осталось две, а разметка тянулась с четырёх: .promoCol была
   горизонтальной лентой (overflow-x:auto + scroll-snap) со стрелками.
   Лента давала ровно тот симптом, на который жаловались, — вторая плитка
   уезжала за край экрана. Арифметика flex-basis совпадала (170.5+10+170.5=351),
   но любой сдвиг прокрутки или лишняя плитка снова обрежут вторую.
   Сетка 2 колонки убирает саму возможность: плитка физически не может
   оказаться за краем.
   ⚠️ Вернутся ТРИ и больше плиток — возвращать и ленту (правило выше по файлу),
   иначе третья сожмётся до нечитаемой.
   ------------------------------------------------------------------------- */
@container (max-width:699px){
  .promoCol{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr));
             overflow:visible; padding-bottom:0; }
  .promoCol .promoTile{ flex:none; }
  .promoBox .scrollArrow{ display:none !important; }
}

/* -------------------------------------------------------------------------
   КАРТОЧКА ТОВАРА: фасовка выше, отзывы отпущены от заголовка (30.07.2026)
   Работает и на мобильной, и на десктопе — просили везде.
   - .attrBlock (выбор фасовки) стоял на 20px от предыдущего блока и читался
     оторванным от цены; поднимаем до 12px.
   - под заголовком «Отзывы N» было 16px (12px на мобильной) — форма и лента
     прилипали к заголовку; отпускаем до 24/20px.
   Кегль самого заголовка снижен глобально (см. блок «ЗАГОЛОВКИ РАЗДЕЛОВ»).
   ------------------------------------------------------------------------- */
.attrBlock{ margin-top:12px; }
.rvWrap .secHead{ margin-bottom:24px; }
@container (max-width:699px){
  .rvWrap .secHead{ margin-bottom:20px; }
}

/* Картинки к этапам работ (перенесены с ceresit.ru). Идут ПОСЛЕ текста своего шага,
   поэтому отступ сверху меньше обычного — картинка визуально принадлежит абзацу над ней. */
.v2Tab .stepPic{ margin:12px 0 0; }
.v2Tab .stepPic img{ display:block; width:100%; max-width:520px; height:auto;
                     border:1px solid var(--line); border-radius:10px; }
@media (max-width:699px){ .v2Tab .stepPic img{ max-width:100%; } }

/* =========================================================================
   FAQ узкой колонкой + баннер подбора цвета (правка 30.07.2026).
   Было: вопросы во всю ширину и плитка «Системы утепления» сбоку. Строка в 100+
   знаков читается тяжело, а плитка вела на колеровку, но говорила про утепление.
   Стало: колонка ~70 знаков по центру, а плитка выросла в отдельный баннер
   на страницу колеровки — со своим текстом по теме.
   ========================================================================= */
.secHead--center{ justify-content:center; text-align:center; }
.faqWrap--narrow{ display:block; max-width:72ch; margin:0 auto; }

/* Просто чёрная плашка: фоновой картинки и градиента поверх неё больше нет,
   надстрочной подписи «Подбор цвета фасада» тоже. Текст слева, кнопка справа. */
.kolerCta{ position:relative; display:block; border-radius:var(--r-block);
  margin-top:var(--sec-gap); background:var(--ink); color:#fff; }
.kolerCta__in{ padding:24px; display:flex; flex-direction:column; align-items:flex-start; gap:20px; }
.kolerCta__text{ max-width:64ch; }
.kolerCta h3{ font-family:var(--font-head); font-size:20px; font-weight:700; line-height:1.22;
  letter-spacing:-.01em; margin:0 0 12px; color:#fff; }
.kolerCta p{ font-size:13px; line-height:1.65; color:#cfd6d6; }
.kolerCta__btn{ display:inline-flex; align-items:center; gap:8px; flex:none;
  background:var(--red); color:#fff; font-weight:700; font-size:13px;
  padding:12px 20px; border-radius:10px; white-space:nowrap; }
.kolerCta:hover .kolerCta__btn{ background:var(--ink); color:#fff; }
.kolerCta:hover{ color:#fff; }

@container (min-width:700px){
  /* с 700px текст и кнопка встают в строку: кнопка прижата к правому краю */
  .kolerCta__in{ flex-direction:row; align-items:center; justify-content:space-between;
    gap:32px; padding:36px 36px 36px 40px; }
  .kolerCta h3{ font-size:24px; }
  .kolerCta p{ font-size:15px; }
}

/* Серая плашка под блоком вопросов — во всю ширину контентной сетки.
   Внутри всё остаётся как было: заголовок по центру, колонка вопросов ~70 знаков.
   Белые карточки вопросов на сером фоне и дают ту самую слоистость с рефа. */
.faqPlate{ background:var(--bg); border-radius:var(--r-block); padding:28px 16px 32px; margin-top:var(--sec-gap); }
/* Заголовок внутри плашки не должен добавлять свой верхний отступ поверх padding:
   иначе сверху получается вдвое больше воздуха, чем снизу. Отступ сверху задаёт
   только padding самой плашки, и он равен нижнему. */
.faqPlate .secHead{ margin-top:0; margin-bottom:16px; }
.faqPlate > :first-child{ margin-top:0; }
@container (min-width:700px){ .faqPlate{ padding:36px 32px 36px; } }

/* =========================================================================
   НОВОСТИ — список (шаблон «Новости v2») и страница новости («Новость v2»).
   Раскладка по типовой схеме новостных разделов: сверху одна главная новость
   крупным блоком «текст | кадр», под ней ровная сетка остальных.
   Раздел не заводит своих цветов и кеглей — всё на общих токенах:
   заголовки --font-head/--fs-h*, акцент --red, рамки --line.
   ========================================================================= */

/* ---- главная новость ---- */
.newsHero{ display:grid; grid-template-columns:1fr; margin-top:8px; background:#fff;
  border:1px solid var(--line); border-radius:var(--r-block); overflow:hidden;
  transition:border-color .15s ease, box-shadow .15s ease; }
.newsHero:hover{ border-color:#cfd6d6; box-shadow:0 18px 40px -28px rgba(15,40,40,.5); }
/* на узком экране кадр идёт первым, на широком уезжает вправо — см. @container ниже */
.newsHeroBody{ display:flex; flex-direction:column; align-items:flex-start; gap:12px; padding:24px; order:2; }
.newsHeroImg{ display:block; order:1; background:#eef1f1; }
.newsHeroImg img{ width:100%; aspect-ratio:16/10; object-fit:cover; display:block; }
.newsHero b{ font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.22; color:var(--ink); }
.newsHero:hover b{ color:var(--red); }
.newsHeroText{ font-size:15px; line-height:1.6; color:#37413f;
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
.newsHeroBtn{ background:var(--red); color:#fff; font-weight:700; font-size:13px;
  padding:12px 20px; border-radius:10px; }
.newsHero:hover .newsHeroBtn{ background:var(--ink); color:#fff; }

/* рубрика и дата одной строкой над заголовком */
.newsEyebrow{ display:flex; align-items:center; gap:8px; font:700 11px/1 var(--font-body);
  letter-spacing:.1em; text-transform:uppercase; color:var(--red); }
.newsEyebrow .newsDate{ position:relative; padding-left:12px; color:var(--faint);
  font-weight:600; letter-spacing:.04em; }
.newsEyebrow .newsDate::before{ content:''; position:absolute; left:0; top:50%; transform:translateY(-50%);
  width:1px; height:11px; background:#d4dada; }

/* ---- лента остальных ---- */
.newsGrid{ display:grid; grid-template-columns:1fr; gap:var(--gap-card); margin-top:var(--head-gap); }
.newsCard{ display:flex; flex-direction:column; background:#fff; min-width:0;
  border:1px solid var(--line); border-radius:var(--r-card); overflow:hidden;
  transition:border-color .15s ease, box-shadow .15s ease; }
.newsCard:hover{ border-color:var(--ink); box-shadow:0 8px 22px -14px rgba(20,26,28,.4); }
.newsCardImg{ display:block; background:#eef1f1; }
.newsCardImg img{ width:100%; aspect-ratio:16/10; object-fit:cover; display:block; }
.newsCardBody{ display:flex; flex-direction:column; gap:8px; padding:16px; }
.newsCard .newsDate{ font:600 12px/1 var(--font-body); color:var(--faint); }
.newsCard b{ font-size:15px; font-weight:700; line-height:1.35; color:var(--ink);
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical; overflow:hidden; }
.newsCard:hover b{ color:var(--red); }
.newsCardText{ font-size:13px; line-height:1.55; color:var(--muted);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }

/* ---- страница новости ---- */
.newsArt{ max-width:760px; margin:0 auto; }   /* длина строки: шире читать тяжело */
.newsArtHead{ display:flex; flex-direction:column; gap:12px; margin:12px 0 24px; }
.newsArtHead h1{ font-family:var(--font-head); font-size:var(--fs-h1); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.15; }

/* Текст новости приходит из админки обычным HTML, поэтому стилизуем ТЕГИ,
   а не классы: разметку внутри поля никто не проставляет. */
.newsBody{ font-size:15px; line-height:1.7; color:#37413f; }
.newsBody > * + *{ margin-top:16px; }
.newsBody h2{ font-family:var(--font-head); font-size:var(--fs-h3); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); color:var(--ink); margin-top:28px; }
.newsBody h3{ font-size:17px; font-weight:700; color:var(--ink); margin-top:24px; }
.newsBody a{ color:var(--red); border-bottom:1px solid currentColor; }
.newsBody ul{ list-style:none; display:flex; flex-direction:column; gap:8px; }
.newsBody li{ position:relative; padding-left:20px; }
.newsBody li::before{ content:''; position:absolute; left:3px; top:11px; width:6px; height:6px;
  border-radius:50%; background:var(--red); }
.newsBody blockquote{ border-left:3px solid var(--red); padding:2px 0 2px 16px;
  color:var(--ink); font-weight:600; }
.newsBody strong{ color:var(--ink); }

/* картинка стоит там, где её поставил автор ([[+img_N]]), подпись под ней */
.newsFig{ margin:24px 0; }
.newsFig img{ width:100%; border-radius:var(--r-block); display:block; background:#eef1f1; }
.newsFig figcaption{ margin-top:8px; font-size:13px; line-height:1.5; color:var(--faint); }

.newsAuthor{ display:flex; align-items:center; gap:12px; margin-top:28px; padding-top:20px;
  border-top:1px solid var(--line); }
.newsAuthor span{ font:700 10.5px/1 var(--font-body); letter-spacing:.1em; text-transform:uppercase; color:var(--faint); }
.newsAuthor b{ font-size:15px; font-weight:700; color:var(--ink); }

.newsMore{ margin-top:48px; }
.newsMore .secHead{ margin-bottom:16px; }

@container (min-width:700px){
  .newsHero{ grid-template-columns:minmax(0,1fr) minmax(0,1fr); }
  .newsHeroBody{ order:1; padding:32px; gap:16px; justify-content:center; }
  .newsHeroImg{ order:2; }
  /* кадр тянется на высоту текстовой половины, поэтому пропорция снимается */
  .newsHeroImg img{ height:100%; aspect-ratio:auto; min-height:260px; }
  .newsGrid{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--gap-card); margin-top:var(--head-gap); }
}
@container (min-width:1100px){
  .newsHeroBody{ padding:40px; gap:16px; }
  .newsHeroImg img{ min-height:330px; }
  .newsGrid{ grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--gap-card); margin-top:var(--head-gap); }
  .newsArtHead{ margin:16px 0 28px; }
}

/* =========================================================================
   КОЛЕРОВКА — разбивка текста на блоки с картинками.
   Раскладка по схеме продуктовых страниц Apple: секции идут крупными
   чередующимися парами «текст | кадр», между ними много воздуха, картинка
   всегда работает на смысл соседнего абзаца, а не «для красоты».
   ⚠️ Слова страницы при этом НЕ менялись — только группировка (сверено
   пословно: 586 слов до и после). Подписей под картинками нет намеренно:
   подпись — это новые слова на странице, смысл несёт alt.
   ========================================================================= */

/* воздуха между секциями больше, чем в обычном тексте — иначе «стена» остаётся */
.kolText{ gap:28px; }

/* ---- пара «текст | кадр» ---- */
.kolSplit{ display:grid; grid-template-columns:1fr; gap:0; background:#fff;
  border:1px solid var(--line); border-radius:var(--r-block); overflow:hidden; }
.kolSplit__text{ padding:24px; display:flex; flex-direction:column; justify-content:center; }
.kolSplit__text p{ font-size:15px; line-height:1.75; color:#37413f; }
.kolSplit__text p + p{ margin-top:12px; }
.kolSplit__media{ background:#eef1f1; order:-1; }
.kolSplit__media img{ width:100%; height:100%; aspect-ratio:16/10; object-fit:cover; display:block; }
/* для рендеров на белом фоне: кадрировать нельзя, дом обрежется по краям */
.kolSplit__media--plain{ background:#f6f8f8; }
.kolSplit__media--plain img{ object-fit:contain; padding:16px; }

/* ---- карточка с широкой полосой-картинкой снизу ---- */
.kolCard--figure{ padding:0; overflow:hidden; }
.kolCard--figure .kolCard__body{ padding:24px; }
/* ⚠️ Пропорцию полосе НЕ задавать. Исходник — баннер 1920×229 (8.4:1) с пятью
   семействами цвета в ряд. При aspect-ratio:16/5 + cover в кадр попадали только
   38% ширины, то есть три семейства из пяти просто срезались. Полоса должна
   держать свою пропорцию: высота считается от ширины сама. */
.kolBand{ width:100%; height:auto; display:block; }

/* ---- ассортимент штукатурок плитками ---- */
.kolPlast--tiles{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }
.kolPlast--tiles li{ display:flex; flex-direction:column; gap:12px; padding:12px; }
.kolPlast--tiles img{ width:100%; aspect-ratio:1/1; object-fit:contain; display:block;
  background:#f6f8f8; border-radius:8px; padding:8px; }
.kolPlast--tiles span{ display:block; }

/* ---- этапы + кадр колеровки ---- */
.kolStepsWrap{ display:grid; grid-template-columns:1fr; gap:16px; }
.kolStepsPic{ background:#eef1f1; border-radius:var(--r-card); overflow:hidden; }
.kolStepsPic img{ width:100%; height:100%; aspect-ratio:4/3; object-fit:cover; display:block; }

/* ---- сноска про пробный выкрас + фасад ---- */
.kolCard--note.kolCard--figure{ display:grid; grid-template-columns:1fr; }
.kolNotePic{ background:#eef1f1; }
.kolNotePic img{ width:100%; height:100%; aspect-ratio:16/10; object-fit:cover; display:block; }

@container (min-width:700px){
  .kolText{ gap:36px; }
  .kolSplit{ grid-template-columns:minmax(0,1fr) minmax(0,1fr); align-items:stretch; }
  .kolSplit__text{ padding:32px; }
  /* кадр тянется на высоту текста, поэтому фиксированная пропорция снимается */
  .kolSplit__media img{ aspect-ratio:auto; min-height:260px; }
  .kolSplit__media{ order:0; }                    /* по умолчанию кадр справа */
  .kolSplit--rev .kolSplit__text{ order:2; }      /* в чётных секциях — слева */
  .kolSplit--rev .kolSplit__media{ order:1; }
  .kolCard--figure .kolCard__body{ padding:32px; }
  .kolPlast--tiles{ grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; }
  .kolStepsWrap{ grid-template-columns:minmax(0,1.35fr) minmax(0,1fr); gap:20px; align-items:start; }
  .kolStepsPic img{ aspect-ratio:3/4; }
  .kolCard--note.kolCard--figure{ grid-template-columns:minmax(0,1fr) minmax(0,.8fr); }
  .kolNotePic img{ aspect-ratio:auto; min-height:100%; }
}
@container (min-width:1100px){
  .kolText{ gap:44px; }
  .kolSplit__text{ padding:44px; }
  .kolSplit__media img{ min-height:340px; }
  .kolCard--figure .kolCard__body{ padding:40px; }
  .kolPlast--tiles{ grid-template-columns:repeat(4,minmax(0,1fr)); }
  .kolStepsWrap{ grid-template-columns:minmax(0,1.5fr) minmax(0,1fr); gap:24px; }
}

/* Лента новостей на главной — те же карточки, что в разделе, но ГОРИЗОНТАЛЬНОЙ лентой,
   как хиты продаж и товары со скидкой. Сеткой девять новостей занимали пол-экрана;
   лентой видно первые три-четыре, остальные листаются. Ширина карточки фиксированная,
   следующая намеренно видна краем — это и есть подсказка, что блок листается. */
.newsGrid--home{ display:flex; grid-template-columns:none; gap:12px;
  overflow-x:auto; scroll-snap-type:x proximity; }
.newsGrid--home > .newsCard{ flex:0 0 300px; scroll-snap-align:start; }
@container (max-width:699px){ .newsGrid--home > .newsCard{ flex:0 0 78%; } }

/* =========================================================================
   Преимущества: заголовок → описание → пункты списком, фото справа.
   Заменил ленту из шести плиток с галочками и отдельную плашку «Штукатурный фасад»
   над ней. Текст теперь объясняет, о чём речь, до того как читать перечисление,
   а фото показывает результат работы.
   ========================================================================= */
.advBlock{
  background:#fff; border:1px solid var(--line); border-radius:var(--r-block);
  padding:24px; margin-top:var(--sec-gap);
  display:grid; grid-template-columns:1fr; gap:var(--gap-card); align-items:center;
}
/* Вид заголовка задан общим правилом рядом с .secHead h2 — здесь ничего своего. */
.advBlock__lead{ font-size:15px; line-height:1.7; color:var(--muted); margin-top:12px; }
.advBlock__lead b{ color:var(--ink); }

/* Пункты — маркерами-точками, строго в один столбец, друг под другом. */
.advBlock__list{ list-style:none; margin-top:20px; display:grid; grid-template-columns:1fr; gap:var(--gap-card); }
.advBlock__list li{
  position:relative; padding-left:20px;
  font-size:15px; line-height:1.45; color:#37413f;
}
.advBlock__list li::before{
  content:''; position:absolute; left:0; top:8px;
  width:6px; height:6px; border-radius:50%; background:var(--red);
}
/* Фото блока преимуществ. Квадрат 1/1 — под него и подобран снимок, поэтому
   object-fit ничего не режет. Фон оставлен: он виден ровно до загрузки картинки
   и на её месте не появляется дыра (13.08.2026 сюда поставлено фото дома). */
.advBlock__photo{
  /* height:auto ОБЯЗАТЕЛЕН. В разметке у <img> проставлены width/height (чтобы
     браузер держал место до загрузки), а они подставляются как настоящая высота
     в пикселях и перебивают aspect-ratio: картинка вытягивалась в 586×1254
     вместо квадрата (поймано замером 13.08.2026). */
  width:100%; height:auto; aspect-ratio:1 / 1; object-fit:cover;
  border-radius:var(--r-block); display:block; background:var(--bg);
}

/* Фото занимает половину блока — это половина экрана по ширине контейнера. */
@container (min-width:700px){
  .advBlock{ grid-template-columns:1fr 1fr; padding:28px; gap:28px; }
}
@container (min-width:1100px){
  .advBlock{ padding:32px 36px; gap:40px; }
}

/* =========================================================================
   С КЕМ МЫ РАБОТАЕМ — роли и вкладки (главная)
   Композиция: крупный заголовок по центру → ряд вкладок → две колонки
   (пункты слева, фото справа) → кнопка под пунктами.

   Отличие от эталона одно и намеренное: акцент КРАСНЫЙ (--red), а не синий.
   Синяя кнопка на этом сайте спорила бы со всеми главными действиями
   («В корзину», «Отправить заявку»), которые красные. Поменять — две строки.

   Тексты пунктов собраны из Marketing/Стратегия: у каждой роли свой мотив
   (pyat-pochemu-po-rolyam.md) и свой набор офферов, который из мотива следует.
   ========================================================================= */
.roles{ margin-top:var(--sec-gap); }

/* Заголовок берёт общий вид блочного заголовка (правило рядом с .secHead h2).
   Был 36px по центру — как в эталоне-образце, но на этой странице он оказался
   единственным центрованным и самым крупным из всех. */

/* Вкладки прижаты влево, под заголовок: центрировать их, когда заголовок слева,
   значит снова разъехаться. */
/* Ряд вкладок. flex-wrap, а НЕ горизонтальная прокрутка: ролей всего пять,
   на узком экране они переносятся во вторую строку и остаются все на виду.
   Лента с прокруткой прятала бы половину сегментов за краем экрана. */
.roles__tabs{
  display:flex; flex-wrap:wrap; justify-content:flex-start; gap:6px;
  margin-top:16px;
}
.roleTab{
  padding:12px 20px; border-radius:var(--r-card);
  border:1px solid transparent; background:none;
  font-size:15px; font-weight:700; line-height:1.2; color:var(--muted);
  transition:color .15s, background .15s, border-color .15s;
}
.roleTab:hover{ color:var(--ink); }
.roleTab[aria-selected="true"]{
  color:var(--red); border-color:var(--red); background:#fff2f4;
}

.roles__body{
  margin-top:28px;
  display:grid; grid-template-columns:1fr 1fr; gap:36px; align-items:start;
}

/* В левой колонке лежат ВСЕ пять списков, показан один. Кнопка — одна на весь
   блок, а не своя в каждой вкладке: пять кнопок с одним id — это ровно тот
   случай, когда JS цепляется к первой, а остальные выглядят рабочими и молчат
   (LESSONS, дубликаты id). min-height держит высоту, чтобы блок не прыгал
   при переключении вкладок с разной длиной пунктов. */
.roles__left{ display:flex; flex-direction:column; min-height:352px; }

/* Переключение — своим атрибутом data-on, а НЕ штатным `hidden`: у hidden
   приоритет ниже, чем у display из класса, и элемент остаётся видимым
   (LESSONS, «атрибут hidden против своего display»). */
.roleList{ list-style:none; display:none; }
.roleList[data-on="true"]{ display:grid; grid-template-columns:1fr; gap:16px; }
.roleList li{
  position:relative; padding-left:20px;
  font-size:15px; line-height:1.5; color:#37413f;
}
.roleList li::before{
  content:''; position:absolute; left:0; top:9px;
  width:6px; height:6px; border-radius:50%; background:var(--red);
}
.roleList li b{ color:var(--ink); font-weight:700; }

.rolesCta{
  align-self:flex-start; margin-top:28px;
  background:var(--red); color:#fff; font-weight:700; font-size:15px;
  padding:12px 24px; border-radius:10px;
}
.rolesCta:hover{ background:var(--ink); color:#fff; }

/* Фото. Все пять лежат в разметке, показано одно: так браузер не запрашивает
   картинку заново при каждом переключении вкладки. loading="lazy" оставлен —
   блок стоит ниже сгиба. */
.rolePhoto{
  display:none; width:100%; aspect-ratio:4 / 3; object-fit:cover;
  border-radius:var(--r-block); background:var(--bg);
}
.rolePhoto[data-on="true"]{ display:block; }

@container (max-width:899px){
  /* Фото наверх, пункты под ним: на узком экране колонка с текстом длинная,
     и картинка, оставшись справа-внизу, читалась бы как чужая. */
  .roles__body{ grid-template-columns:1fr; gap:20px; }
  .roles__media{ order:1; }
  .roles__left{ order:2; min-height:0; }
}
@container (max-width:699px){
  .roles__tabs{ gap:6px; margin-top:20px; }
  .roleTab{ padding:10px 12px; font-size:14px; border-radius:10px; }
  .roles__body{ margin-top:20px; }
  .roleList[data-on="true"]{ gap:12px; }
  .roleList li{ font-size:14px; }
  .rolesCta{ align-self:stretch; text-align:center; padding:12px 20px; font-size:14px; }
}

/* -------------------------------------------------------------------------
   ГЛАВНАЯ: ВЫРАВНИВАНИЕ ЗАГОЛОВКОВ (правка 07.08.2026)
   Правило простое: все заголовки разделов — по ЛЕВОМУ краю (так и было),
   и ровно два блока — по центру:
     1) «Один поставщик — разные способы работать вместе» (.roles) вместе с
        рядом вкладок «прораб / дизайнер / …» — они читаются как обращение
        к разным аудиториям, а не как очередной раздел каталога;
     2) «Ответы на часто задаваемые вопросы» — блок и так узкий
        (.faqWrap--narrow, max-width 72ch, центрирован), заголовок у левого
        края висел отдельно от своего текста.
   FAQ ловим через :has(+ .faqWrap) — чтобы не трогать шаблон 19 в базе:
   его сейчас правит и параллельная сессия, лишний UPDATE там рискован.
   ⚠️ Появится второй блок с классом .faqWrap на странице — правило зацепит
   и его заголовок. Тогда заводить явный модификатор .secHead--center.
   ------------------------------------------------------------------------- */
.roles__title{ text-align:center; }
.roles__tabs{ justify-content:center; }
.secHead:has(+ .faqWrap){ justify-content:center; text-align:center; }

/* =========================================================================
   ПРАВКИ ПО ЗАМЕЧАНИЯМ ВЛАДЕЛЬЦА, 03.08.2026 (мобильная версия)
   Блок стоит в САМОМ КОНЦЕ файла осознанно: выше по файлу параллельная сессия
   добавила свои правила (центрирование заголовка и вкладок блока ролей), и при
   равной специфичности выигрывает то, что ниже.
   ========================================================================= */

/* ---- Вкладки ролей: одна строка с горизонтальной прокруткой ----
   Названия сокращены («Прорабы», «Застройщики», «Магазины»), но впятером они
   всё равно не помещаются в ширину телефона. Перенос давал четыре строки —
   вкладки читались как список, а не как переключатель. Лента прокручивается.
   ⚠️ justify-content должен быть flex-start: при center прокручиваемая лента
   прячет первые вкладки за левым краем, и до «Прорабов» не добраться. */
.roles__tabs{
  flex-wrap:nowrap; justify-content:flex-start;
  overflow-x:auto; overscroll-behavior-x:contain; scrollbar-width:none;
  /* лента идёт от края до края контейнера, но чипы начинаются по сетке */
  margin-left:calc(-1 * var(--pad-x)); margin-right:calc(-1 * var(--pad-x));
  padding-left:var(--pad-x); padding-right:var(--pad-x);
  scroll-padding-left:var(--pad-x);
}
.roles__tabs::-webkit-scrollbar{ display:none; }
.roleTab{ flex:0 0 auto; white-space:nowrap; padding:8px 16px; font-size:13px; }
@container (max-width:699px){
  .roleTab{ padding:8px 12px; font-size:14px; }
}

@container (max-width:699px){
  /* ---- FAQ и блок преимуществ живут по общей сетке страницы ----
     Оба были «карточками»: серая плашка у FAQ и белая рамка у преимуществ,
     каждая со своими внутренними полями. На телефоне это давало двойной отступ
     (поле страницы + поле карточки) и заголовок, сдвинутый внутрь относительно
     остальных секций. Убираем саму карточку — содержимое встаёт на общую сетку.
     На десктопе плашка и рамка остаются: там ширины хватает и они держат блок. */
  .faqPlate{ background:none; padding:0; border-radius:0; }
  .faqPlate .secHead{ margin-bottom:var(--head-gap); }
  .faqWrap{ margin-top:0; }

  .advBlock{ background:none; border:0; padding:0; border-radius:0; }

  /* ---- Блок с домом: во всю ширину — значит без тени и скругления ----
     Тень по краям блока, дотянутого до краёв экрана, читается как серая полоса
     сверху и снизу — владелец назвал это «странным сереньким дефектом».
     Скругление тут же: круглые углы, упирающиеся в кромку экрана, выглядят
     как недоверстанный блок. */
  .cfgWrap iframe{ border-radius:0; box-shadow:none; }
}

/* ---- Выполненные работы: лента карточек + кнопка под ней ----
   Было: сетка auto-fill minmax(180px) — на телефоне это одна карточка во всю
   ширину, каждая высотой почти в экран, и до следующей секции надо было
   пролистать шесть таких. Стало: лента, в кадре видно полторы карточки —
   сразу понятно, что её листают вбок.
   Кнопка «Смотреть все» переехала под ленту: в заголовке она не помещалась
   рядом с кеглем 22px и обрезалась правым краем. */
.secMoreBtn{
  display:block; margin-top:var(--gap-card); padding:12px 20px;
  border:1px solid var(--line); border-radius:var(--r-card);
  font-size:13px; font-weight:700; color:var(--ink); text-align:center;
  transition:border-color .15s, color .15s;
}
.secMoreBtn:hover{ border-color:var(--ink); color:var(--red); }
@container (min-width:700px){
  /* на десктопе кнопка не растягивается на всю ширину — она там вспомогательная */
  .secMoreBtn{ width:max-content; padding:12px 24px; }
}
@container (max-width:699px){
  .worksGrid{
    display:flex; grid-template-columns:none; gap:var(--gap-card);
    overflow-x:auto; scroll-snap-type:x proximity; scrollbar-width:none;
    margin-left:calc(-1 * var(--pad-x)); margin-right:calc(-1 * var(--pad-x));
    padding-left:var(--pad-x); padding-right:var(--pad-x);
  }
  .worksGrid::-webkit-scrollbar{ display:none; }
  .worksGrid > .workCard{ flex:0 0 62%; scroll-snap-align:start; }
}

/* =========================================================================
   ИНФОСТРАНИЦЫ v2 (правка 09.08.2026): about / доставка / контакты /
   политика / thanks / 404 переведены со старых шаблонов (3, 10, 2, 16) на
   новые «Страница v2» (30), «Контакты v2» (31), «Доставка v2» (32).
   Один контракт типографики — .pageBody — и три набора блоков.
   Слова всех страниц перенесены 1:1 из старых шаблонов/чанков.
   ========================================================================= */

/* ---- .pageBody: типографика голого контента (как контракт вкладок карточки) ---- */
.pageBody{ max-width:860px; }
.pageBody > *{ margin-top:16px; }
.pageBody > *:first-child{ margin-top:0; }
.pageBody h2{ font-family:var(--font-head); font-size:var(--fs-h3); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.3; margin-top:32px; }
.pageBody h3{ font-size:15px; font-weight:700; margin-top:24px; }
.pageBody h2 + *, .pageBody h3 + *{ margin-top:12px; }
.pageBody p{ font-size:15px; line-height:1.75; color:#37413f; }
.pageBody ul, .pageBody ol{ padding-left:20px; display:grid; gap:8px; }
.pageBody li{ font-size:15px; line-height:1.6; color:#37413f; }
.pageBody a{ color:var(--red); font-weight:600; }
.pageBody a:hover{ text-decoration:underline; }
.pageBody .tableWrap{ overflow-x:auto; }
.pageBody table{ border-collapse:collapse; width:100%; font-size:13px; }
.pageBody th{ text-align:left; font-weight:700; padding:8px 12px; background:var(--teal-l); }
.pageBody td{ padding:8px 12px; border-bottom:1px solid var(--line); color:#37413f; }
.pageBody th:first-child{ border-radius:8px 0 0 8px; }
.pageBody th:last-child{ border-radius:0 8px 8px 0; }
/* страница может быть шире контента: сплиты/сетки ниже сами задают ширину */
.pageWide{ max-width:none; }

/* ---- ABOUT: интро текст+фото ---- */
.aboutIntro{ display:grid; grid-template-columns:1fr; gap:20px; align-items:center; }
.aboutIntro__media img{ width:100%; border-radius:var(--r-block); display:block; object-fit:cover; aspect-ratio:4/3; }
.aboutIntro__text p{ font-size:15px; line-height:1.8; color:#37413f; }
.aboutIntro__text p + p{ margin-top:12px; }

/* ---- ABOUT: факты «в распоряжении компании» ---- */
.aboutFacts{ list-style:none; padding:0 !important; display:grid; grid-template-columns:1fr; gap:12px; }
.aboutFacts li{ background:var(--teal-l); border-radius:var(--r-card); padding:16px 16px;
  font-size:13px; line-height:1.55; color:#37413f; display:flex; gap:12px; }
.aboutFacts li::before{ content:'✓'; color:var(--red); font-weight:800; flex:none; }

/* ---- ABOUT: «почему мы» — карточки с иконками ---- */
.whyGrid{ display:grid; grid-template-columns:1fr; gap:12px; }
.whyCard{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block);
  padding:20px; display:flex; flex-direction:column; gap:8px; }
.whyCard img{ width:44px; height:44px; }
.whyCard b{ font-size:15px; font-weight:700; }
.whyCard p{ font-size:13px; line-height:1.6; color:var(--muted); }

/* ---- ДОСТАВКА: строка «иконка + текст» ---- */
.dpItem{ display:grid; grid-template-columns:52px minmax(0,1fr); gap:16px;
  background:#fff; border:1px solid var(--line); border-radius:var(--r-block);
  padding:20px; margin-top:16px; }
.dpItem__ico img{ width:44px; height:44px; }
.dpItem__body > * + *{ margin-top:12px; }
.dpItem__body h3{ font-size:17px; font-weight:700; margin:0; display:flex; flex-wrap:wrap; align-items:baseline; gap:8px; }
.dpItem__body h3 small{ font-size:13px; font-weight:700; color:var(--green); background:#e9f7ef;
  padding:4px 8px; border-radius:6px; white-space:nowrap; }
.dpItem__body p{ font-size:13px; line-height:1.7; color:#37413f; }
.dpItem__body ul{ padding-left:20px; display:grid; gap:6px; }
.dpItem__body li{ font-size:13px; line-height:1.55; color:#37413f; }
.dpNote{ background:var(--teal-l); border-radius:var(--r-card); padding:12px 16px; }
.dpNote p{ font-size:13px; color:var(--muted); margin:0; }
.dpOk{ list-style:none; padding:0 !important; }
.dpOk li{ display:flex; gap:8px; }
.dpOk li::before{ content:'✓'; color:var(--green); font-weight:800; flex:none; }

/* ---- КОНТАКТЫ ---- */
/* ---- Верх страницы контактов: колонка данных слева, фото магазина справа ----
   По макету Figma 58:3769. Данные идут простым списком «подпись + значение»,
   без карточек: строки короткие, и три белые коробки в ряд только растягивали
   блок по высоте. Фото — не декор: человеку перед поездкой полезно увидеть,
   как выглядит магазин внутри. */
.conHero{ display:grid; grid-template-columns:1fr; gap:24px; margin-top:20px; align-items:stretch; }
.conHero__info{ display:flex; flex-direction:column; align-items:flex-start; gap:18px; }
.conField{ display:flex; flex-direction:column; gap:2px; }
.conField b{ font-size:15px; font-weight:700; color:var(--ink); }
.conField a, .conField span{ font-size:15px; line-height:1.5; color:#37413f; }
.conField a:hover{ color:var(--red); }
.conHero__note{ font-size:15px; line-height:1.7; color:#37413f; max-width:52ch; }
.conHero .conRoute{ margin-top:0; }
.conHero .conSoc{ margin-top:0; }
/* Фото тянется на всю высоту текстовой колонки: при height:auto оно кончалось
   на середине, и справа зияла пустота — блок выглядел развалившимся. */
.conHero__photo{ height:100%; }
.conHero__photo img{ display:block; width:100%; height:100%; min-height:320px;
  object-fit:cover; object-position:center; border-radius:var(--r-block); }
@container (max-width:699px){ .conHero__photo img{ height:auto; min-height:0; } }
@container (min-width:700px){
  .conHero{ grid-template-columns:minmax(260px,1fr) 1.35fr; gap:40px; margin-top:28px; }
}

.conGrid{ display:grid; grid-template-columns:1fr; gap:12px; margin-top:16px; }
.conCard{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block); padding:20px; }
.conCard small{ display:block; font-size:11px; font-weight:700; letter-spacing:.07em;
  text-transform:uppercase; color:var(--faint); margin-bottom:12px; }
.conCard .conBig{ display:block; font-family:var(--font-head); font-size:20px; font-weight:700;
  color:var(--ink); letter-spacing:-.01em; }
.conCard .conBig:hover{ color:var(--red); }
.conCard a.conMore{ display:block; font-size:15px; font-weight:600; color:var(--ink); margin-top:6px; }
.conCard a.conMore:hover{ color:var(--red); }
.conCard p{ font-size:13px; line-height:1.65; color:#37413f; margin-top:8px; }
.conCard p.conMuted{ color:var(--muted); font-size:13px; }
.conRoute{ display:inline-flex; align-items:center; gap:8px; margin-top:12px; padding:12px 16px;
  border-radius:8px; background:var(--teal-l); font-size:13px; font-weight:700; color:var(--ink); }
.conRoute:hover{ background:var(--ink); color:#fff; }
.conMap{ margin-top:16px; border-radius:var(--r-block); overflow:hidden; border:1px solid var(--line); }
.conMap iframe{ display:block; width:100%; height:340px; border:0; }
.conSoc{ display:flex; gap:8px; margin-top:12px; flex-wrap:wrap; }
.conSoc a{ padding:8px 16px; border:1px solid var(--line); border-radius:8px; font-size:13px;
  font-weight:700; color:var(--ink); }
.conSoc a:hover{ border-color:var(--ink); background:var(--ink); color:#fff; }

/* ---- КОЛЕРОВКА: мягче и без «обводок на всю ширину» ----
   Просили: вместо рамочных полос — композиции «картинка + текст».
   1) интро больше не карточка (класс .kolIntro в контенте ресурса 16);
   2) базовая карточка потеряла жёсткую рамку — мягкий фон;
   3) преимущества — сетка карточек с галочками вместо простого списка. */
.kolIntro h2{ font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.25; margin-bottom:12px; max-width:30ch; }
.kolIntro p{ font-size:15px; line-height:1.8; color:#37413f; max-width:76ch; }
.kolCard{ border-color:transparent; background:#fafbfb; }
.kolCard--accent{ background:var(--ink); }
.kolCard--note{ background:var(--teal-l); }
.kolPlast li{ background:#fff; border-color:transparent; box-shadow:0 1px 0 rgba(20,26,28,.06); }
.kolStep{ background:#fff; border-color:transparent; border-left:3px solid var(--red); border-radius:10px; }
ul.kolPerks{ list-style:none; padding:0; display:grid; grid-template-columns:1fr; gap:12px; margin-top:6px; }
ul.kolPerks li{ background:#fff; border-radius:var(--r-card); padding:12px 16px;
  font-size:13px; line-height:1.55; color:#37413f; display:flex; gap:12px;
  box-shadow:0 1px 0 rgba(20,26,28,.06); }
ul.kolPerks li::before{ content:'✓'; width:22px; height:22px; border-radius:50%;
  background:var(--red); color:#fff; font-weight:800; font-size:13px;
  display:flex; align-items:center; justify-content:center; flex:none; }

/* ---- планшет и десктоп ---- */
@container (min-width:700px){
  .aboutIntro{ grid-template-columns:minmax(0,1.2fr) minmax(0,1fr); gap:24px; }
  .aboutFacts{ grid-template-columns:1fr 1fr; }
  .whyGrid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .dpItem{ padding:24px; }
  .conGrid{ grid-template-columns:repeat(3,minmax(0,1fr)); }
  .conGrid--two{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .conMap iframe{ height:420px; }
  ul.kolPerks{ grid-template-columns:1fr 1fr; }
}
@container (min-width:1100px){
  .whyGrid{ grid-template-columns:repeat(3,minmax(0,1fr)); }
  .aboutIntro{ gap:36px; }
}

/* =========================================================================
   КОЛЕРОВКА — раскладка по макету Figma (файл tkBYljM6…, узел 22:3004).
   Снято с макета: контейнер 1212, две колонки 597 + зазор 16, панель со
   внутренним отступом 40, карточка товара 271×339 с КВАДРАТНЫМ фото,
   сетка 4 в ряд с зазором 16, светлая панель #fafbfb, тёмная — var(--ink).

   Правила стоят ПОСЛЕ прежнего блока колеровки и переопределяют его:
   старая раскладка была «текст сбоку от фото», новая — «фото сверху, текст под ним».
   Ломать прежние правила нельзя: на них ещё держатся .kolCard--accent и сноска.
   ========================================================================= */

/* Крошки оставлены только в каталоге и карточке товара (просьба владельца).
   На остальных страницах первый блок иначе прижимается к шапке: раньше воздух
   давали сами крошки (padding 12/12). В макете от линии шапки до заголовка 61px,
   .wrap.page уже даёт 16 — добираем 44. */
.wrap.page > *:first-child:not(.crumbs){ margin-top:44px; }

/* На мобиле эти же 44px превращают первый экран в дыру: от шапки до баннера
   уходит 61px, а от края экрана до баннера — 16. Уравниваем по боковому полю:
   сверху ровно столько же, сколько по бокам. Десктоп не трогаем — там 61px
   по макету (см. комментарий выше). */
@media (max-width:699px){
  .wrap.page > *:first-child:not(.crumbs){ margin-top:0; }
}

/* ---- «Нужна помощь специалиста?» + автор идеи ----
   Блок вернули с оригинала (в v2 он потерялся). Вёрстка — в языке страницы:
   белая карточка с контуром, радиус блока, заголовок общими токенами. */
.kolExpert{ display:grid; grid-template-columns:1fr; gap:20px; align-items:start;
  background:#fff; border:1px solid var(--line); border-radius:var(--r-block); padding:24px; }
.kolExpert__main h2{ font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.25; margin-bottom:14px; }
.kolExpert__main p{ font-size:15px; line-height:1.75; color:#37413f; }
.kolExpert__note{ margin-top:12px; font-weight:700; color:var(--ink) !important; }
.kolExpert__note span{ color:var(--red); }
.kolExpert__btn{ display:inline-flex; align-items:center; margin-top:18px; padding:13px 22px;
  border:1px solid var(--red); color:var(--red); font-weight:700; font-size:14px; border-radius:var(--r-card); }
.kolExpert__btn:hover{ background:var(--red); color:#fff; }
.kolExpert__person{ display:grid; grid-template-columns:96px 1fr; gap:16px; align-items:start;
  background:var(--bg); border-radius:var(--r-card); padding:16px; }
.kolExpert__person img{ width:96px; height:96px; border-radius:50%; object-fit:cover; display:block; }
.kolExpert__person b{ display:block; font-family:var(--font-head); font-size:16px; color:var(--ink); }
.kolExpert__person span{ display:block; font-size:12px; color:var(--muted); margin-bottom:8px; }
.kolExpert__person p{ font-size:13.5px; line-height:1.6; color:#37413f; }
@container (min-width:700px){
  .kolExpert{ grid-template-columns:minmax(0,1fr) minmax(0,.85fr); gap:32px; padding:32px; }
}
@container (min-width:1100px){ .kolExpert{ padding:40px; gap:40px; } }

/* ─── Блок стал ЧЁРНЫМ и двухколоночным (правка 12.08.2026, просьба владельца) ───
   Было: белая карточка, слева текст + свёрнутая форма, справа карточка «Автор идеи».
   Стало: слева текст, справа — сама форма выезда. Карточка автора убрана из
   контента ресурса 16, правила .kolExpert__person ниже остались висеть без разметки.

   Правила стоят ПОСЛЕ базовых и перебивают их по порядку, а не весом: специфичность
   та же, менять её нельзя — .kolExpert__note держится на !important от прежнего блока,
   и повышение веса здесь сломало бы его обратно.

   Поля ввода намеренно оставлены БЕЛЫМИ: на чёрном они и есть основной свет карточки,
   а тёмные поля на тёмном фоне пришлось бы обводить — лишний контур на и без того
   плотном блоке. */
.kolExpert{ background:var(--ink); border-color:transparent; color:#fff; }
.kolExpert__main h2{ color:#fff; }
.kolExpert__main p{ color:rgba(255,255,255,.70); }
.kolExpert__note{ color:#fff !important; }
.kolExpert__note span{ color:#ff5470; }   /* --red на чёрном тускнеет, берём светлее */

.kolExpert__aside{ min-width:0; }
.kolExpert__formTitle{ font-family:var(--font-head); font-size:17px; font-weight:var(--fw-head);
  color:#fff; margin:0 0 14px; }
.kolExpert .authLabel{ color:rgba(255,255,255,.62); }

/* Согласие: воздух от телефона и ОДНА строка.
   flex-wrap:wrap оставлен намеренно — на узком экране строка переносится ЦЕЛИКОМ
   между «Согласен на обработку» и ссылкой, а не рвёт словосочетание пополам
   (именно так оно и выглядело до правки). nowrap на детях держит каждую часть
   неразрывной. */
.kolExpert__agree{ display:flex; align-items:center; flex-wrap:wrap; gap:4px 7px;
  margin-top:26px; font-size:13.5px; line-height:1.5; }
.kolExpert__agree .authCheckBox{ align-items:center; gap:9px; }
.kolExpert__agree .authCheckBox span,
.kolExpert__agree .authPolicy{ white-space:nowrap; }
.kolExpert__agree .authCheckBox span{ color:rgba(255,255,255,.78); }
/* Галочка красная, а не системная синяя. accent-color красит нативный чекбокс
   целиком — свой квадрат из ::before не нужен, и доступность не теряется. */
.kolExpert__agree input[type="checkbox"]{ flex:none; width:16px; height:16px;
  accent-color:var(--red); }
.kolExpert__agree .authPolicy{ color:#ff5470; text-decoration:underline;
  text-underline-offset:2px; }
.kolExpert__agree .authPolicy:hover{ color:#fff; }

.kolExpert__send{ margin-top:20px; }

/* ---- ВЕРТИКАЛЬНЫЙ РИТМ РОВНО ПО МАКЕТУ ----
   Снято по координатам узлов: между секциями 90, от заголовка секции до её панели 24,
   у преимуществ 36, от героя до конфигуратора 24, от конфигуратора до текста 90.
   Раньше страница жила на общем .kolText{gap:28–44} — отсюда и расхождение с макетом. */
.kolText{ gap:48px; margin-top:48px; }
.kolBlock{ display:grid; gap:24px; }
.kolBlock--perks{ gap:24px; }
.cfgWrap--full{ margin-top:24px; }
@container (min-width:700px){
  .kolText{ gap:64px; margin-top:64px; }
  .kolBlock--perks{ gap:36px; }
}
@container (min-width:1100px){
  .kolText{ gap:90px; margin-top:90px; }
}

/* ---- герой: заголовок слева, описание справа ---- */
.kolHero{ display:grid; grid-template-columns:1fr; gap:10px; margin-top:6px; }
.kolHero h1{ margin:0; }
.kolHero .cfgIntro{ max-width:none; margin:0; }

/* ---- заголовок секции НАД панелью. Типографика — общая с .secHead h2,
       иначе страница снова начнёт читаться как отдельный макет. ---- */
.kolHead{ font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.25; color:var(--ink); margin:0;
  /* В макете заголовки секций занимают 719–832px при контейнере 1212 — они НЕ тянутся
     во всю ширину, иначе строка уходит за комфортные ~70 знаков и читается тяжело. */
  max-width:832px; }

/* ⚠️ Заголовок внутри ТЁМНОЙ плашки. .kolHead покрашен в var(--ink) — на чёрном фоне
   он невидим. Раньше блок был на <h3> и его красило .kolCard--accent h3; после смены
   тега на h2.kolHead покраска потерялась, и заголовок пропал с экрана (текст в разметке
   при этом на месте — глазами не найдёшь, только замером цвета). */
.kolCard--accent .kolHead,
.kolCard--accent h2,
.kolCard--accent h3{ color:#fff; }

/* ---- светлая панель-подложка ---- */
.kolPanel{ background:#fafbfb; border:1px solid var(--line); border-radius:var(--r-block); padding:16px; }

/* ---- интро: заголовок | текст ---- */
.kolIntro{ display:grid; grid-template-columns:1fr; gap:10px; align-items:start; }
.kolIntro h2{ font-family:var(--font-head); font-size:var(--fs-h2); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.25; margin:0; }
.kolIntro p{ font-size:15px; line-height:1.75; color:#37413f; margin:0; }

/* ---- две равные карточки: фото сверху, текст под ним ---- */
/* align-items:stretch — карточки в паре обязаны быть равной высоты (в макете 597×646
   обе). При start каждая росла по своему тексту и низы не совпадали. */
.kolDuo{ display:grid; grid-template-columns:1fr; gap:16px; align-items:stretch; }
.kolDuo .kolSplit{ display:flex; flex-direction:column; padding:20px; gap:16px; background:#fff; height:100%; }
/* Подложка кадра — серая, как в макете (#e7ebeb). Промежуточный вариант с белым
   фоном и рамкой был ошибкой: в макете именно серая плашка. */
.kolDuo .kolSplit__media{ order:0; border-radius:var(--r-card); overflow:hidden;
  background:#e7ebeb; border:none; }
.kolDuo .kolSplit__media img{ aspect-ratio:16/9; height:auto; min-height:0; }
.kolDuo .kolSplit__media--plain img{ padding:12px; }
.kolDuo .kolSplit__text{ padding:0; display:block; }

/* ---- ассортимент плитками + восьмая ячейка-баннер ---- */
.kolPlast--tiles li{ background:#fff; border-radius:var(--r-card); }
/* Фото товара во всю ширину карточки: серая подложка с полями съедала кадр и
   читалась как лишняя рамка внутри рамки. */
/* В макете под фото товара — серая плашка #e7ebeb во всю ширину карточки
   (это ровно токен --line). Фото вписано внутрь и не кадрируется: у товаров
   разные пропорции, cover резал бы вёдра. */
.kolPlast--tiles img{ width:100%; aspect-ratio:1/1; object-fit:contain;
  background:#e7ebeb; padding:0; border-radius:var(--r-card); }
.kolPlast--tiles span{ font-size:13px; line-height:1.5; }

/* Баннер в каталог. Размер — тот же, что у карточки товара: он лежит в той же
   сетке и НЕ получает своей ширины, иначе восьмая ячейка выпадет из ряда. */
.kolPlast__cta{ padding:0 !important; border-color:transparent !important; background:var(--ink) !important;
  /* плитка сама себе контейнер: кегль заголовка считается от ЕЁ ширины, а не от экрана */
  container-type:inline-size; }
.kolPlast__cta > a{ display:flex; flex-direction:column; height:100%; padding:16px; gap:8px;
  color:#fff; text-decoration:none;
  /* ⚠️ white-space:normal обязателен: выше .kolPlast a задаёт nowrap (там это нужно,
     чтобы артикул «CT 174» не разрывался). Без сброса весь баннер идёт одной строкой
     и вылезает за карточку. */
  white-space:normal; min-width:0; }
.kolPlast__cta .kpcTitle{ font-family:var(--font-head); font-weight:var(--fw-head);
  line-height:1.12; letter-spacing:var(--ls-head); color:#fff; hyphens:none;
  /* Просили: слово «декоративные» — во всю ширину плитки. При кегле F его ширина
     ≈ 7.37×F (Inter 700), внутренняя ширина = 100cqw − 32px полей. Отсюда множитель
     0.135. clamp — страховка: на узкой плитке 2-в-ряд кегль не должен уходить в 12px,
     на широкой — распухать. Фиксированные 30px не годились: на 820px и 390px слово
     вылезало за карточку и уводило страницу вбок на 46px. */
  font-size:clamp(15px, calc((100cqw - 32px) * 0.135), 32px); }
.kolPlast__cta .kpcText{ font-size:13px; line-height:1.55; color:#b9c3c4; font-weight:400; }
.kolPlast__cta .kpcBtn{ margin-top:auto; align-self:stretch; text-align:center; background:var(--red); color:#fff;
  font-weight:700; font-size:14px; padding:13px 16px; border-radius:10px; white-space:nowrap; }
.kolPlast__cta:hover .kpcBtn{ background:var(--red-d); }

/* ---- этапы: широкое фото сверху, под ним четыре карточки ---- */
.kolPanel--steps{ display:grid; grid-template-columns:1fr; gap:16px; }
.kolPanel--steps .kolStepsPic{ border-radius:var(--r-card); overflow:hidden; }
.kolPanel--steps .kolStepsPic img{ aspect-ratio:16/9; height:auto; }
.kolPanel--steps .kolSteps{ grid-template-columns:1fr; gap:16px; }
.kolPanel--steps .kolStep{ background:#fff; }

/* ---- преимущества: фото слева, подзаголовок и список справа ---- */
.kolPerksWrap{ display:grid; grid-template-columns:1fr; gap:20px; align-items:start; }
.kolPerksPic{ background:#eef1f1; border-radius:var(--r-block); overflow:hidden; }
/* Остальные кадры — той же серой плашкой, единая логика с парой. */
.kolPanel--steps .kolStepsPic{ background:#e7ebeb; border:none; }
.kolPerksPic{ background:#e7ebeb; border:none; }

.kolPerksPic img{ width:100%; height:100%; aspect-ratio:4/3; object-fit:cover; display:block; }
.kolPerksBody h3{ font-family:var(--font-head); font-size:var(--fs-h3); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.3; color:var(--ink); margin-bottom:14px; }
.kolPerksBody .kolPerks{ display:grid; gap:10px; padding-left:20px; }
.kolPerksBody .kolPerks li{ font-size:15px; line-height:1.6; color:#37413f; }

/* ---- ПЛАНШЕТ ---- */
@container (min-width:700px){
  .kolHero{ grid-template-columns:1fr 1fr; gap:16px; align-items:start; }
  .kolIntro{ grid-template-columns:1fr 1fr; gap:16px; }
  .kolDuo{ grid-template-columns:1fr 1fr; }
  /* обе карточки в паре остаются «фото сверху» — прежнее правило разводило их в две
     колонки внутри самой карточки, здесь это уже не нужно */
  .kolDuo .kolSplit{ grid-template-columns:1fr; padding:20px; }
  .kolDuo .kolSplit__text{ padding:0; }
  .kolDuo .kolSplit__media img{ aspect-ratio:16/9; min-height:0; }
  .kolPanel{ padding:24px; }
  .kolPanel--steps .kolSteps{ grid-template-columns:1fr 1fr; }
  .kolPanel--steps .kolStepsPic img{ aspect-ratio:21/9; }
  .kolPerksWrap{ grid-template-columns:1fr 1fr; gap:28px; }
  .kolPerksPic img{ aspect-ratio:4/3; }
}

/* ---- ДЕСКТОП ---- */
@container (min-width:1100px){
  .kolHead{ font-size:var(--fs-h2); }
  .kolPanel{ padding:40px; }
  .kolPlast--tiles{ gap:16px; }
  .kolPanel--steps{ gap:16px; }
  .kolPanel--steps .kolSteps{ grid-template-columns:repeat(4,minmax(0,1fr)); }
  .kolPanel--steps .kolStepsPic img{ aspect-ratio:2.6/1; }
  .kolPerksWrap{ gap:72px; }
  .kolPerksPic img{ aspect-ratio:1.3/1; }
}

/* ---- догоняем более ранний блок колеровки (он идёт ВЫШЕ и своё уже задал) ---- */
/* в макете карточка шага без красной полосы слева */
.kolPanel--steps .kolStep{ background:#fff; border:1px solid var(--line); border-left:1px solid var(--line);
  border-radius:var(--r-card); padding:20px; }
/* в макете строка шага — 23px (4 строки в 92px), у нас было 20px и текст слипался */
.kolPanel--steps .kolStep h3{ font-size:15px; line-height:1.5; margin-bottom:10px; }
.kolPanel--steps .kolStep p{ font-size:13px; line-height:1.5; color:var(--muted); }
/* в макете список преимуществ простой: одна колонка, маркер-точка, без плашек */
.kolPerksBody ul.kolPerks{ display:grid; grid-template-columns:1fr; gap:10px; padding-left:20px;
  list-style:disc; margin-top:0; }
.kolPerksBody ul.kolPerks li{ display:list-item; background:none; box-shadow:none; padding:0;
  border-radius:0; font-size:15px; line-height:1.6; color:#37413f; }
.kolPerksBody ul.kolPerks li::before{ content:none; }
/* интро: ограничение ширины было нужно старой раскладке в одну колонку */
.kolIntro h2{ max-width:none; margin-bottom:0; }
.kolIntro p{ max-width:none; }
/* сноска про пробный выкрас: фото почти квадратное, широкий кадр его резал */
.kolCard--note .kolNotePic img{ aspect-ratio:1/1; }

@container (min-width:700px){
  .kolPerksBody ul.kolPerks{ grid-template-columns:1fr; }
}


/* мобильный кегль интро колеровки — В КОНЦЕ файла намеренно: базовое правило
   .kolIntro h2 стоит выше в блоке инфостраниц, а специфичность у них равная —
   побеждает последний. Перенесёшь выше — заголовок опять станет 28px. */
@container (max-width:699px){
  .kolIntro h2{ font-size:20px; }
}

/* ---- Логотип: картинка вместо текстовой пары «Ceresit·shop» ----
   Файл: img/cms-logo.svg (исходник — CeresitShopMSK/Логотип/CMS_Logo.svg, 535×115).
   Подпись «Официальный дилер Ceresit в Москве» входит В САМУ картинку, поэтому
   отдельный .logoTag из разметки убран — иначе она печаталась бы дважды.
   Размер задаём высотой: ширина считается сама по пропорции 535:115, и логотип
   не поедет, если однажды подменят файл с другим соотношением.
   ⚠️ Логотип стоит в ДВУХ чанках — v2_header и v2_mobmenu. Меняешь один — меняй оба. */
.logo img{ display:block; height:42px; width:auto; }
@container (max-width:699px){ .logo img{ height:30px; } }
.mmTop .logo img{ height:30px; }

/* ---- Шапка: компактная строка «Каталог» + поиск ----
   Кнопка «Каталог» была на кегле 15px с полями 12/20 — 42px высоты, тяжелее любой
   обычной кнопки сайта. Поджата до пропорций обычной кнопки, кегль внутри мельче.
   Поиск ужат ВМЕСТЕ с ней: рядом с кнопкой 36px поле в 44px читалось бы как
   рассогласованная строка. Радиус — общий токен карточки, как у всего остального. */
/* Скругление 4px, а не общее --r-card (12px): в шапке кнопка «Каталог» и поле
   поиска стоят рядом и должны читаться строже остального интерфейса. */
.catBtn{ gap:8px; font-size:13px; padding:8px 16px; border-radius:4px; }
.catBtn .bl{ gap:4px; }
.catBtn .bl span{ width:14px; height:2px; }
.search{ border-radius:4px; }
.searchInp{ padding:8px 16px 8px 0; font-size:13px; }
.searchIco{ padding:0 8px 0 12px; }

/* =========================================================================
   ВХОД И ЛИЧНЫЙ КАБИНЕТ v2 (правка 10.08.2026)
   /login и /cabinet были последними страницами на СТАРОМ дизайне (шаблоны 4 и 5,
   bootstrap-сетка, btn-outline-primary, вкладки на data-toggle). Переведены на
   шаблоны 33/34; здесь их стили — на тех же токенах, что вся v2 (--line, --r-block,
   --red, кегли из --fs-*), поэтому отступы и заголовки совпадают с главной и карточкой.
   ========================================================================= */

.authWrap{ max-width:720px; }
.authTabs{ display:flex; gap:6px; margin-bottom:16px; flex-wrap:wrap; }
.authTab{ padding:12px 16px; border-radius:var(--r-card); border:1px solid var(--line);
  background:#fff; font-size:13px; font-weight:700; color:var(--muted); font-family:inherit; }
.authTab:hover{ color:var(--ink); border-color:#d7dede; }
.authTab.is-active{ background:var(--ink); border-color:var(--ink); color:#fff; }

.authCard{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block); padding:20px; }
.authNote{ font-size:13px; line-height:1.6; color:var(--muted); margin-bottom:16px; }

.authField{ display:block; margin-top:12px; }
.authField:first-child{ margin-top:0; }
.authLabel{ display:block; font-size:13px; font-weight:700; color:var(--muted); margin-bottom:6px; }
.authLabel i{ color:var(--red); font-style:normal; }
.authField input,
.authField textarea{ width:100%; font-family:inherit; font-size:15px; color:var(--ink);
  background:#fff; border:1px solid var(--line); border-radius:10px; padding:12px 12px; outline:none; }
.authField textarea{ resize:vertical; min-height:74px; }
.authField input:focus,
.authField textarea:focus{ border-color:var(--ink); }

.authRow{ display:grid; grid-template-columns:1fr; gap:12px; margin-top:12px; }
.authRow .authField{ margin-top:0; }

.authCheck{ display:flex; gap:6px; align-items:flex-start; margin-top:16px; flex-wrap:wrap;
  font-size:13px; line-height:1.5; color:#37413f; }
.authCheck input{ margin-top:2px; flex:none; width:16px; height:16px; accent-color:var(--red); }
/* Галочка и ссылка — соседи, а не вложенность: клик по ссылке внутри label
   переключал бы согласие вместо перехода на страницу политики. */
.authCheckBox{ display:flex; gap:12px; align-items:flex-start; cursor:pointer; }
.authPolicy{ color:var(--red); text-decoration:underline; text-underline-offset:2px; }
.authPolicy:hover{ color:var(--red-d); }
.authHint{ display:block; margin-top:6px; font-size:12px; color:var(--faint); }
/* Экран «письмо отправлено» — он заменяет форму целиком после регистрации. */
.authDone b{ display:block; font-size:16px; font-weight:700; margin-bottom:8px; }
.authDone p{ font-size:14px; line-height:1.6; color:var(--muted); margin:0 0 8px; }
.authDone p:last-child{ margin-bottom:0; }

.authBtn{ margin-top:16px; width:100%; padding:12px 20px; border-radius:10px;
  background:var(--red); color:#fff; font-family:inherit; font-size:15px; font-weight:700; }
.authBtn:hover{ background:var(--ink); color:#fff; }
.authBtn[disabled]{ opacity:.6; }
.authLink{ display:block; width:100%; margin-top:12px; padding:6px; background:none;
  font-family:inherit; font-size:13px; font-weight:600; color:var(--muted); }
.authLink:hover{ color:var(--red); }

.authMsg{ margin-top:12px; padding:12px 12px; border-radius:10px; font-size:13px; line-height:1.5; }
.authMsg--ok{ background:#e9f7ef; color:#1a6b40; }
.authMsg--err{ background:#fdecef; color:#a3122e; }
.authMsg[hidden]{ display:none !important; }   /* см. LESSONS п. 34 */

.authSoc{ margin-top:16px; display:flex; align-items:center; gap:12px; flex-wrap:wrap;
  font-size:13px; color:var(--muted); }
.authSoc ul{ display:flex; gap:8px; list-style:none; }

/* ---- личный кабинет ---- */
.lkTop{ display:flex; align-items:center; justify-content:space-between; gap:16px;
  flex-wrap:wrap; margin-bottom:16px; }
.lkTabs{ display:flex; gap:6px; flex-wrap:wrap; }
.lkTab{ padding:12px 16px; border-radius:var(--r-card); border:1px solid var(--line);
  background:#fff; font-size:13px; font-weight:700; color:var(--muted); font-family:inherit; }
.lkTab:hover{ color:var(--ink); }
.lkTab.is-active{ background:var(--ink); border-color:var(--ink); color:#fff; }
.lkDiscount{ font-size:13px; color:var(--muted); }
.lkDiscount b{ font-size:17px; color:var(--red); margin-left:6px; }
.lkPane[hidden]{ display:none !important; }

.lkGrid{ display:grid; grid-template-columns:1fr; gap:20px; align-items:start; }
.lkPhoto{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block);
  padding:20px; display:flex; flex-direction:column; align-items:center; gap:12px; }
.lkPhoto img{ width:140px; height:140px; object-fit:cover; border-radius:50%; background:var(--teal-l); }
.lkPhotoBtn span{ display:inline-block; padding:8px 16px; border:1px solid var(--line);
  border-radius:8px; font-size:13px; font-weight:700; color:var(--ink); cursor:pointer; }
.lkPhotoBtn span:hover{ border-color:var(--ink); background:var(--ink); color:#fff; }
.lkPhotoHint{ font-size:11px; color:var(--red); text-align:center; }
.lkPhotoHint[hidden]{ display:none !important; }

.lkFields{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block); padding:20px; }
.lkSub{ font-family:var(--font-head); font-size:var(--fs-h3); font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); margin:24px 0 12px; }
.lkSub:first-child{ margin-top:0; }
.lkRow{ display:grid; grid-template-columns:1fr; gap:12px; }
.lkRow + .authField{ margin-top:12px; }
.lkErr{ display:block; font-size:11px; color:var(--red); font-style:normal; margin-top:4px; }
.lkErr:empty{ display:none; }

.lkPromo{ margin-top:20px; background:var(--teal-l); border-radius:var(--r-block); padding:16px; }
.lkPromo__head{ font-size:15px; font-weight:700; margin-bottom:8px; }
.lkPromo p{ font-size:13px; color:#37413f; line-height:1.6; }
.lkPromo__code{ margin:12px 0; font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:20px; font-weight:700; letter-spacing:.04em; color:var(--ink); }
.lkPromo__btn{ padding:8px 16px; border:1px solid var(--line); border-radius:8px; background:#fff;
  font-family:inherit; font-size:13px; font-weight:700; color:var(--ink); }
.lkPromo__btn:hover{ border-color:var(--ink); background:var(--ink); color:#fff; }

.lkBtns{ display:grid; grid-template-columns:1fr; gap:12px; margin-top:20px; align-items:center; }
.lkBtns .authBtn{ margin-top:0; }
.lkLogout{ text-align:center; padding:12px; border:1px solid var(--line); border-radius:10px;
  font-size:13px; font-weight:700; color:var(--muted); }
.lkLogout:hover{ border-color:var(--ink); color:var(--ink); }

@container (min-width:700px){
  .authRow{ grid-template-columns:1fr 1fr; }
  .authCard{ padding:28px; }
  .lkGrid{ grid-template-columns:minmax(0,240px) minmax(0,1fr); gap:24px; }
  .lkRow{ grid-template-columns:1fr 1fr; }
  .lkFields{ padding:28px; }
  .lkBtns{ grid-template-columns:minmax(0,1fr) minmax(0,200px); }
}

/* Иконки соцсетей на входе. Разметку даёт файл-чанк tpl.provider.tpl: голый
   <svg><use …#soc-vk></svg> БЕЗ width/height. В старом дизайне размер задавали
   правила .login__socials, на v2 их нет — и логотип ВК растягивался во весь блок
   (было ~350px). Размер задаём здесь; сам чанк не трогаем, он общий с оригиналом. */
.authSoc ul li a{ display:flex; width:40px; height:40px; border:1px solid var(--line);
  border-radius:10px; align-items:center; justify-content:center; }
.authSoc ul li a:hover{ border-color:var(--ink); background:var(--ink); }
.authSoc svg{ width:20px; height:20px; fill:var(--ink); }
.authSoc ul li a:hover svg{ fill:#fff; }

/* Форма «Написать руководству» (ресурс 274). Две карточки в ряд на десктопе,
   одна колонка на телефоне. .smTrap — honeypot: поле должно быть недоступно
   человеку, но остаться в DOM для ботов, поэтому уводим его за экран,
   а НЕ display:none (часть ботов такие поля пропускает). */
.smCols{ display:grid; grid-template-columns:1fr; gap:16px; margin-top:16px; }
.smCard{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block); padding:20px; }
.smCard .lkSub{ font-size:15px; }
.smCard select{ width:100%; font-family:inherit; font-size:15px; color:var(--ink);
  background:#fff; border:1px solid var(--line); border-radius:10px; padding:12px 12px; }
.smTrap{ position:absolute; left:-9999px; width:1px; height:1px; opacity:0; }
@container (min-width:700px){
  .smCols{ grid-template-columns:1fr 1fr; gap:20px; align-items:start; }
  .smCard{ padding:28px; }
}

/* Пустая вкладка «Мои заказы» */
.lkEmpty{ background:#fff; border:1px solid var(--line); border-radius:var(--r-block);
  padding:36px 24px; text-align:center; }
.lkEmpty b{ display:block; font-family:var(--font-head); font-size:var(--fs-h3);
  font-weight:var(--fw-head); margin-bottom:8px; }
.lkEmpty p{ font-size:13px; color:var(--muted); line-height:1.6; }
.lkEmpty__btn{ display:inline-block; width:auto; padding:12px 24px; margin-top:16px; }

/* ---- Блок дилера: описание основным кеглем ----
   Было 13,5px — мельче основного текста сайта, хотя это обычный читаемый абзац,
   а не подпись. Берём --fs-body (15px), чтобы кегль не пришлось догонять руками
   при следующей правке типографики. Подзаголовок «Фирменный магазин-студия»
   поднят до того же кегля: он вводит список и не должен быть мельче него. */
.distrib p{ font-size:var(--fs-body); }
.distribList li{ font-size:var(--fs-body); line-height:1.6; }
.distrib h4{ font-size:var(--fs-body); }

/* ---- Вкладки ролей по центру ----
   ⚠️ Именно `safe center`, а не просто `center`. Лента прокручиваемая: при обычном
   центрировании, когда вкладки не помещаются (телефон), контент выезжает за ЛЕВЫЙ
   край области прокрутки, и до первой вкладки «Прорабы» уже не добраться — прокрутка
   в отрицательную сторону невозможна. `safe` центрирует, пока есть место, и сам
   переключается на выравнивание по началу, как только начинается переполнение. */
.roles__tabs{ justify-content:safe center; }

/* ---- Блок преимуществ: не карточка, а обычная секция страницы ----
   Была белая карточка с рамкой и своими полями 24px внутри белой же страницы —
   рамка ничего не отделяла, а поля сдвигали текст внутрь относительно остальных
   секций. Убираем карточку целиком: содержимое встаёт на общую сетку страницы.
   (На узком экране это уже было сделано; теперь одинаково на всех ширинах.) */
.advBlock{ background:none; border:0; padding:0; border-radius:0; }

/* Описание и пункты — основным кеглем сайта. Было 14px: мельче обычного текста,
   хотя это и есть обычный текст, а не подпись. */
.advBlock__lead{ font-size:var(--fs-body); }
.advBlock__list li{ font-size:var(--fs-body); }

/* Маркеры списков — чёрные (цвет текста), а не красные. Красный на сайте отвечает
   за действие: кнопки, цена, активная вкладка. Когда им же покрашены точки простого
   перечисления, акцент размывается и список выглядит важнее, чем он есть. */
.advBlock__list li::before,
.roleList li::before{ background:var(--ink); }

/* ---- Дата в карточке новости — тем же кеглем, что и описание ----
   Было 12px против 13px у описания под ней: разница в один пиксель не читается
   как иерархия, а выглядит как случайность. Полужирность оставлена — она и
   отличает дату от текста, размер для этого не нужен. */
.newsCard .newsDate{ font-size:13px; color:var(--muted); }

/* ---- Вопрос в FAQ — основным кеглем ----
   Было 14px. Вопрос — это заголовок пункта, он не должен быть мельче обычного
   текста сайта (--fs-body 15px). */
.faqQ{ font-size:var(--fs-body); }

/* ---- Промо-плитки под баннером: заголовок 15, описание 13 ----
   Было 16 и 12,5 — заголовок крупнее основного текста сайта, а описание мельче
   всех прочих описаний. Приводим к общей типографике: заголовок --fs-body,
   описание — как описание новости и прочие вторичные строки.
   ⚠️ Ниже по файлу есть узкий вариант (.promoCol .promoTile b/span, 13,5/11,5) —
   он специфичнее и на телефоне перебьёт это. Меняешь тут — смотри и там. */
.promoTile b{ font-size:var(--fs-body); }
.promoTile span{ font-size:13px; }

/* Тот же кегль и в узком варианте плиток: правило .promoCol .promoTile специфичнее
   и иначе вернуло бы на телефоне 13,5/11,5 — два разных размера у одного элемента
   ровно то, от чего уходим. */
.promoCol .promoTile b{ font-size:var(--fs-body); }
.promoCol .promoTile span{ font-size:13px; }

/* Вторая, неглавная кнопка на экране «письмо отправлено»: действие полезное,
   но не основное — красной заливкой оно спорило бы с самой регистрацией. */
.authBtn--ghost{ background:#fff; color:var(--ink); border:1px solid var(--line); }
.authBtn--ghost:hover{ border-color:var(--ink); background:#fff; }
.authBtn--ghost[disabled]{ opacity:.5; }

/* Колонки в кабинете разъезжались на 12px: у .authField стоит margin-top:12px,
   а снимает его только :first-child. В сетке .lkRow первое поле — первый ребёнок
   (0), второе — нет (12px), поэтому ПРАВАЯ колонка всегда висела ниже левой.
   Внутри сетки вертикальный отступ задаёт gap, собственный margin полям не нужен. */
.lkRow > .authField{ margin-top:0; }

/* ─── Кабинет: ОДИН вертикальный ритм формы (правка 10.08.2026) ───────────
   Было: отступы складывались из трёх независимых источников — собственный
   margin-top у .authField, gap у сетки .lkRow и margin у .lkSub. Между полями
   ОДНОЙ строки выходило 24px, между строками 0, перед подзаголовком 22px —
   на телефоне это читалось как каша. Теперь расстояние задаёт ТОЛЬКО gap
   контейнера, а личные margin-ы обнулены.
   ⚠️ На мобильной .lkRow становится display:contents: сетка исчезает, её поля
   встают прямыми участниками общей колонки — поэтому шаг между ВСЕМИ полями
   одинаковый. Селекторы при этом по-прежнему видят .lkRow > .authField
   (display:contents не меняет дерево), на этом и держится обнуление margin. */
.lkFields{ display:flex; flex-direction:column; gap:16px; }
.lkFields > *{ margin-top:0; }
.lkRow{ gap:16px; }
.lkRow > .authField{ margin-top:0; }
.lkFields .lkSub{ margin:6px 0 0; }
.lkFields .lkSub:first-child{ margin-top:0; }
.lkFields .lkPromo, .lkFields .authCheck, .lkFields .lkBtns{ margin-top:0; }

@container (max-width:699px){
  .lkRow{ display:contents; }
  .lkGrid{ gap:16px; }
  .lkFields{ gap:14px; padding:18px; }
  .lkPhoto{ padding:18px; }
}

/* Добивка ритма кабинета: два поля выбивались из шага.
   1) «Адрес доставки» ловил старое правило `.lkRow + .authField{margin-top:12px}`
      (у него та же специфичность, что у моего обнуления, — побеждало то, что ниже,
      но правило лежит в другом блоке файла). Бьём точечно и однозначно.
   2) Подзаголовок «Сменить пароль» — намеренный смысловой отступ, но он должен быть
      ОДНОЙ понятной величиной, а не случайными 6px: 14 (gap) + 10 = 24px. */
.lkFields > .authField{ margin-top:0; }
.lkFields > .lkSub{ margin-top:10px; }
.lkFields > .lkSub:first-child{ margin-top:0; }

/* =========================================================================
   О КОМПАНИИ. Главный блок — по макету Figma (node 57:3623): кадр слева 599px,
   колонка текста справа, между ними 72px; внутри правой колонки вводный абзац,
   заголовок и список идут подряд. Остальные блоки — общие со страницей колеровки
   (.kolPanel, .kolPlast--tiles, .kolHead), поэтому своих стилей минимум.
   ========================================================================= */
.aboutMain{ display:grid; grid-template-columns:1fr; gap:20px; align-items:start; }
.aboutMain__pic{ border-radius:var(--r-block); overflow:hidden; background:#eef1f1; }
.aboutMain__pic img{ width:100%; height:100%; aspect-ratio:599/459; object-fit:cover; display:block; }
.aboutMain__text > p{ font-size:15px; line-height:1.75; color:#37413f; margin:0; }
/* Отступы сняты с макета (57:3623): абзац кончается на 351, подзаголовок 387 (+36),
   список 434 (+12). Список ПРОСТОЙ маркированный — плитками он в колонку 541px
   не влезал и вылезал за экран, из-за чего его когда-то и вынесли отдельной секцией. */
/* ⚠️ Селектор из ДВУХ классов намеренно: ниже в файле лежит .pageBody h3
   (класс+тег, специфичность выше одиночного класса) и перебивает и отступ, и кегль. */
.aboutMain .aboutMain__sub{ margin-top:36px; font-family:var(--font-head); font-size:20px;
  font-weight:var(--fw-head); letter-spacing:var(--ls-head); line-height:1.3; color:var(--ink); }
/* ⚠️ Выше в файле у .aboutFacts своё прежнее оформление: плашки с галочками и ДВЕ
   колонки на ≥700 (стр. ~2459 и ~2536). В макете здесь простой список в одну колонку,
   поэтому гасим всё явно. Отступ маркера — margin-left, а не padding: там padding:0 !important. */
.aboutMain .aboutFacts{ margin-top:12px; margin-left:20px; list-style:disc outside;
  display:grid; grid-template-columns:1fr; gap:10px; }
.aboutMain .aboutFacts li{ display:list-item; background:none; border-radius:0; padding:0;
  font-size:15px; line-height:1.6; color:#37413f; }
.aboutMain .aboutFacts li::before{ content:none; }
.aboutMain__pic{ background:#e7ebeb; }

/* Плитки преимуществ — без иконок: остались заголовок и строка объяснения.
   Раньше в ячейке стояла картинка whys-*.svg; убрана по просьбе, вместе с ней
   ушло и правило на размер иконки. */
.kolPlast--facts li{ gap:6px; }
.kolPlast--facts b{ display:block; font-size:15px; color:var(--ink); margin-bottom:4px; }
.kolPlast--facts span{ color:var(--muted); }
/* Кегль баннера здесь 20px: на колеровке он считается от ширины плитки и доходит
   до 32px — там это витрина каталога, а тут плитка стоит в ряду с обычными
   преимуществами. Подчёркивание при наведении снято: глобальное a:hover ложилось
   на всю плитку, включая описание и кнопку. */
.kolPlast--facts .kpcTitle{ font-size:20px; }
.kolPlast__cta > a:hover{ text-decoration:none; }

/* Сертификат: одна карточка, картинка целиком (кадрировать документ нельзя). */
.aboutCert{ display:grid; justify-items:center; }
.aboutCert__item{ margin:0; max-width:460px; }
.aboutCert__item img{ width:100%; height:auto; display:block; border-radius:var(--r-card);
  border:1px solid var(--line); background:#fff; }
.aboutCert__item figcaption{ margin-top:12px; font-size:13px; color:var(--muted); text-align:center; }

/* Выполненные работы: ровная сетка карточек .caseCard (мозаика .caseGrid здесь
   не нужна — работ на странице шесть, а не тридцать две). */
.aboutCases{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }

@container (min-width:700px){
  /* пропорции макета: 599 + 72 + 541 = 1212 при контейнере страницы */
  .aboutMain{ grid-template-columns:minmax(0,599fr) minmax(0,541fr); gap:72px; }
  .aboutCases{ grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; }
  .aboutCert__item{ max-width:520px; }
}

/* ---- Между блоками 90px на десктопе (как на колеровке) ----
   Колеровка уже живёт на ритме макета: .kolText{gap:90px}. Приводим к нему и
   остальные страницы — но только широкий экран. На телефоне 90px между секциями
   это почти пустой экран прокрутки, там остаются 48 из :root.
   ⚠️ Токен переопределяем на .wrap, а не на .v2root: .v2root сам объявлен
   контейнером и своим же @container не выбирается — правило просто не применится.
   Значение наследуется всем блокам внутри .wrap. */
@container (min-width:700px){ .wrap{ --sec-gap:90px; } }

/* ─── SEO-текст под каталогом: ЕДИНАЯ типографика (правка 10.08.2026) ──────
   Симптом: блок читался «сборной солянкой» — «Ассортимент Ceresit» серый и
   крупнее соседей, «Почему выбирают Ceresit?» мелкий, списки без отступов,
   часть строк подчёркнута, абзацы липли к спискам.
   Причина: у .seo были правила ТОЛЬКО для h3 и p, а контент писали годами и в
   нём вперемешку h2/h3/h4/ul/u. Что не описано — падало на глобальные стили,
   а `.seo{color:muted; font-size:13px}` красил блок в серую сноску.
   Решение — тот же приём, что для вкладок карточки и .pageBody (LESSONS 31):
   не подпирать каждый случай, а задать КОНТРАКТ на голые теги.

   ⚠️ ПОРЯДОК ПРАВИЛ ВАЖЕН. Сначала описываем ВИД тегов и НЕ трогаем в них
   вертикальные margin, а ритм задаём ОТДЕЛЬНЫМ блоком ниже. Сделал наоборот —
   `.seo p{margin:0}` (0,1,1) перебил `.seo > *{margin-top:14px}` (0,1,0),
   и все абзацы слиплись в один кусок: замер показал зазор 0. */
/* Последний блок страницы в две колонки: текст слева, серая плашка справа,
   внутри неё сертификат дилера. Раскладка повторяет .advBlock выше. */
.seo--split{ display:grid; grid-template-columns:1fr; gap:var(--gap-card); align-items:center; }
.seo__photo{ width:100%; aspect-ratio:1 / 1; border-radius:var(--r-block); background:var(--bg);
  display:flex; align-items:center; justify-content:center; padding:20px; }
.seo__photo img{ max-width:100%; max-height:100%; width:auto; height:auto;
  object-fit:contain; display:block; border-radius:8px; }
@container (min-width:700px){ .seo--split{ grid-template-columns:1fr 1fr; gap:28px; } }
@container (min-width:1100px){ .seo--split{ gap:40px; } }

.seo{ color:var(--ink); font-size:15px; line-height:1.75; }

.seo p{ font-size:15px; line-height:1.75; color:#37413f; }
.seo ul, .seo ol{ padding-left:20px; display:grid; gap:7px; }
.seo li{ font-size:15px; line-height:1.6; color:#37413f; }
.seo li::marker{ color:var(--faint); }
.seo strong, .seo b{ color:var(--ink); font-weight:700; }
/* в тексте попадаются <u> — на экране они читаются как ссылки, которых нет */
.seo u{ text-decoration:none; }
.seo a{ color:var(--red); font-weight:600; }
.seo a:hover{ text-decoration:underline; }
.seo h2, .seo h3, .seo h4{
  font-family:var(--font-head); color:var(--ink);
  letter-spacing:var(--ls-head); line-height:1.3; }
.seo h2, .seo h3{ font-size:var(--fs-h3); font-weight:var(--fw-head); }
.seo h4{ font-size:15px; font-weight:700; }

/* ── ритм: идёт ПОСЛЕДНИМ, поэтому вид тегов его не перебивает ── */
.seo > *{ margin:14px 0 0; }
.seo > *:first-child{ margin-top:0; }
.seo > h2, .seo > h3, .seo > h4{ margin-top:26px; }
/* отступ «заголовок → текст» задаётся один раз и не зависит от того,
   что идёт следом — абзац, список или таблица */
.seo > h2 + *, .seo > h3 + *, .seo > h4 + *{ margin-top:10px; }

@container (max-width:699px){
  .seo{ font-size:14.5px; padding:18px; }
  .seo p, .seo li{ font-size:14.5px; }
  .seo > h2, .seo > h3, .seo > h4{ margin-top:22px; }
}

/* ─── «Выезд специалиста»: форма разворачивается по кнопке (правка 10.08.2026) ──
   Блок снова выглядит как раньше — тёмная карточка с одной красной кнопкой,
   поля появляются только по клику. Механика — нативный <details>: без JS,
   доступна с клавиатуры и не зависит от общего js/v2.js, который сейчас правит
   параллельная сессия.

   ⚠️ Скрытие закрытого содержимого пришлось задать ЯВНО. Браузер прячет детей
   <details> своим правилом с нулевым весом, и любое авторское `display` у
   ребёнка его перебивает: форма показывалась при `open=false` (замер: высота
   238px при закрытом details). Поэтому `display:none !important` — тут это не
   перестраховка, а единственный способ выиграть у чужого правила.

   ⚠️ Треугольник-маркер у summary гасим двумя способами сразу (list-style и
   ::-webkit-details-marker) — иначе в Safari он остаётся и кнопка выглядит
   сломанной. */
.kolExpert__call{ margin-top:18px; }
.kolExpert__call:not([open]) > *:not(summary){ display:none !important; }

.kolExpert__call > summary{
  display:inline-flex; align-items:center; justify-content:center;
  list-style:none; cursor:pointer;
  padding:13px 26px; border:0; border-radius:var(--r-card);
  background:var(--red); color:#fff; font-size:14px; font-weight:700; }
.kolExpert__call > summary::-webkit-details-marker{ display:none; }
.kolExpert__call > summary::marker{ content:''; }
.kolExpert__call > summary:hover{ background:var(--red-d); }
.kolExpert__call[open] > summary{
  background:transparent; color:#fff; border:1px solid rgba(255,255,255,.35); }
.kolExpert__call[open] > summary:hover{ background:rgba(255,255,255,.1); }

.kolExpert__form{ margin-top:14px; }
.kolExpert__send{
  margin-top:16px; padding:13px 26px; border:0; border-radius:var(--r-card);
  background:var(--red); color:#fff; font-family:inherit; font-size:14px;
  font-weight:700; cursor:pointer; }
.kolExpert__send:hover{ background:var(--red-d); }

/* Шапка колеровки: лид «Штукатурный фасад…» — в ПРАВУЮ колонку, сразу под
   вводным текстом. В сетке .kolHero три ребёнка (h1, вводный текст, лид), и при
   автоматической раскладке лид падал во вторую строку ПЕРВОЙ колонки — под
   заголовок. Явно сажаем его во вторую колонку: строка выбирается сама, это
   ближайшая свободная — то есть ровно под вводным текстом. */
@container (min-width:700px){
  .kolHero .cfgIntro--lead{ grid-column:2; }
}

/* ---- КЕЙСЫ: правки 07.08.2026 ----
   1) Кадр объекта ровно в половину ширины. Было 1fr/420px (фото ~62%) — просили
      «в пол экрана», значит колонки равные на всех широких экранах.
   2) «Помогли в работе» — 20px. ⚠️ Сознательное отступление от общего правила
      «кегль только в блоке типографики»: этот заголовок стоит в узкой колонке
      рядом с фото и на общем --fs-h2 (28px) перебивал сам кадр. Остальные
      заголовки страницы (ленты товаров и работ) не трогаем — они .secHead h2.
   3) Точки галереи — чёрные. Тёмную подложку под ними меняем на светлую: чёрные
      точки на чёрной плашке не видно, а без плашки они теряются на тёмном фасаде. */
@container (min-width:700px){
  .caseLayout{ grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:28px; }
}
@container (min-width:1100px){
  .caseLayout{ grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:40px; }
}
.caseCol--text .caseBlock h2{ font-size:20px; }
.slider--photos .sliderDots{ background:rgba(255,255,255,.82); }
.slider--photos .sliderDots i{ background:rgba(12,17,19,.32); }
.slider--photos .sliderDots i[data-on="true"]{ background:var(--ink); }

/* ---- КЕЙСЫ, шапка списка (07.08.2026) ----
   Просили: заголовок 28px, а подпись — справа от него, с 7-й колонки
   двенадцатиколоночной сетки, как сделано на странице колеровки.
   Отступ от меню трогать не понадобилось: он и так ровно 60px
   (низ меню 141 → верх заголовка 201).
   Модификатор отдельный: .catTop общий с каталогом, и там шапка другая. */
.catTop--split h1{ margin:0; }
@container (min-width:700px){
  .catTop--split{ display:grid; grid-template-columns:repeat(12,minmax(0,1fr));
    column-gap:24px; row-gap:8px; align-items:start; }
  .catTop--split h1{ grid-column:1 / span 6; font-size:28px; line-height:1.2; }
  /* подпись — колонки 7–12: правая половина, ровно как в макете */
  /* в этой шапке подпись стоит своей колонкой грида и выравнена по макету —
     отступ сверху ей не нужен */
  .catTop--split .cnt{ grid-column:7 / span 6; font-size:15px; line-height:1.6;
    color:var(--muted); margin-top:0; }
}

/* ─── Страница «О компании»: общий вид секций (правка 10.08.2026) ──────────
   ⚠️ Контент страницы выводится внутри .pageBody, а там для голых тегов задан
   контракт `.pageBody h2{font-size:var(--fs-h3)}` = 18px. У него та же
   специфичность, что у `.secHead h2`, но правило лежит НИЖЕ по файлу — поэтому
   все заголовки страницы съезжали в 18px вместо 28px, хотя классы стояли
   правильные. Возвращаем секционный кегль явно. */
.pageBody .secHead h2{ font-size:var(--fs-h2); line-height:1.2; }
.pageBody .secHead{ margin:34px 0 16px; }
.pageBody .secHead:first-child{ margin-top:0; }

/* ---- Страница «О компании»: заголовок и ритм блоков (правка 12.08.2026) ----

   Кегль h1. Был 24px (--fs-h1) при заголовках секций в 28 (--fs-h2): главный
   заголовок страницы выглядел мельче собственных подзаголовков. Ставим 28.
   Правило общее для всех страниц на шаблоне «Страница v2» (about, policy,
   thanks, 404) — иначе пришлось бы городить класс на body ради одной страницы,
   а разнобой в кегле h1 между ними и есть та самая беда.

   Воздух от шапки. В шаблоне у h1 стоял inline `margin:6px 0 16px` — он весил
   больше любого правила из файла, и до заголовка оставалось 22px. Инлайн убран
   из шаблона, отступы теперь здесь. 60px — только на десктопе: на телефоне
   первый экран и без того короткий (см. правило для .wrap.page выше). */
h1.pTitle{ font-size:28px; margin:0 0 16px; }
@container (min-width:700px){
  /* 44, а не 60: .wrap.page сама даёт padding-top:16px, и от линии шапки до
     заголовка получается ровно заказанные 60. Замерено, а не выведено —
     ставить сюда 60 значит получить 76. Та же арифметика, что абзацем выше
     у первого блока страницы. */
  .wrap.page > h1.pTitle:first-child{ margin-top:44px; }
}

/* Двойной отступ между «Почему мы» и блоком вопросов: .kolText — грид с
   gap:90px, этого достаточно, а .faqPlate несла ещё и собственный
   margin-top:var(--sec-gap). Складывалось в 180px — вдвое больше, чем между
   остальными блоками страницы. Снимаем margin ТОЛЬКО внутри .kolText: на
   страницах, где .faqPlate стоит не в гриде, он по-прежнему нужен. */
.kolText > .faqPlate{ margin-top:0; }

/* «Наши совместные работы»: от заголовка до сетки 24px. .kolBlock уже даёт
   gap:24px, а .secHead добавлял снизу свои 16 — выходило 40. */
.kolBlock--works .secHead{ margin-bottom:0; }

/* ---- Крошки без «Главной» и плашка фильтра скидок (12.08.2026) ----
   pdoCrumbs с showHome=0 в корне каталога отдаёт ПУСТОЙ .crumbs — блок остаётся
   в потоке и держит свои отступы, то есть дыра на месте убранной строки.
   :empty схлопывает его начисто. Внутри крошек только теги-ссылки и разделители,
   текстовых узлов нет, поэтому :empty здесь срабатывает честно. */
.crumbs:empty{ display:none; }

/* «Вы вошли как …» вместо переключателя «новый / уже покупал» в оформлении.
   Тон спокойный: это не действие и не предупреждение, а справка о том, откуда
   взялись подставленные данные. */
.coAuth{ font-size:13.5px; line-height:1.6; color:var(--muted);
  background:var(--bg); border-radius:var(--r-card); padding:12px 14px; margin-bottom:16px; }
.coAuth b{ color:var(--ink); }
.coAuth a{ color:var(--red); text-decoration:underline; text-underline-offset:2px; }

/* «Только со скидкой ×» — снимаемая плашка над выдачей раздела. Появляется,
   когда в раздел пришли с витрины скидок (?sale=1). Ведёт на тот же раздел без
   параметра, то есть крестик = «показать всё». Красная заливка, а не контур:
   это единственное активное сужение выдачи, и его видно сразу. */
.saleChip{ display:inline-flex; align-items:center; gap:8px; margin-bottom:10px;
  padding:6px 12px; border-radius:999px; background:var(--red); color:#fff;
  font-size:12.5px; font-weight:700; line-height:1.3; }
.saleChip b{ font-weight:700; font-size:15px; line-height:1; opacity:.85; }
.saleChip:hover{ background:var(--ink); color:#fff; }

/* «В распоряжении нашей компании» — карточками на серой плашке, как «Почему мы».
   Раньше это был список с галочками (.studioList): он выбивался из страницы,
   где все остальные блоки — плитки. Модификатор --plain отличается от «Почему мы»
   только тем, что внутри плитки нет заголовка-строки, один абзац. */
.kolPlast--plain li span{ display:block; font-size:14px; line-height:1.6; color:#37413f; }
.kolPlast--plain li span b{ display:block; margin-bottom:6px; color:var(--ink); }

/* «Выполненные работы» — сетка и карточки те же, что на главной (.worksGrid /
   .workCard). Модификатор нужен лишь для того, чтобы на десктопе показывать
   ровно три карточки в ряд: на главной их шесть в ленте, здесь — плиткой. */
@container (min-width:700px){
  .worksGrid--about{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}

/* ---- Кнопка заявки вровень с низом фотографии ----
   Вкладки ролей разной длины (у прорабов пять пунктов, у дизайнеров короче),
   и кнопка прыгала вверх-вниз при переключении. Теперь левая колонка тянется
   на высоту строки (align-items:stretch), а кнопка прижата к её низу
   (margin-top:auto) — то есть всегда на одном уровне с нижним краем фото.
   margin-bottom у списка держит минимальный зазор на случай, когда текст
   вкладки почти дотягивается до низа и кнопка иначе прилипла бы к нему. */
@container (min-width:900px){
  .roles__body{ align-items:stretch; }
  .roles__left{ min-height:0; }
  .roleList[data-on="true"]{ margin-bottom:26px; }
  .rolesCta{ margin-top:auto; }
}

/* ---- Короткое окно «Заявка на сотрудничество» ----
   Карточка тёмная, как большое окно заявки: поля формы (.field input, .checkRow)
   на всём сайте нарисованы под тёмный фон, на белом они выглядели бы дырами. */
.rolCard{
  position:relative; width:min(440px,100%); margin:auto;
  background:var(--ink); color:#fff;
  border-radius:var(--r-block); padding:26px;
  animation:leadIn .3s cubic-bezier(.22,.61,.36,1) both;
}
.rolCard h3{ font-family:var(--font-head); font-size:20px; font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); padding-right:34px; }
.rolCard__sub{ margin-top:6px; font-size:13px; color:#aeb8b8; }
.rolCard__sub:empty{ display:none; }
.rolForm{ margin-top:18px; display:grid; gap:12px; }
.rolForm .checkRow{ margin-top:2px; }

/* «Спасибо, что выбрали нас» — на тёмной карточке, поэтому свой вид,
   а не общий .formOk (тот светлый, для формы на белой странице). */
.rolOk{ text-align:center; padding:8px 0 4px; }
.rolOk b{ display:block; font-family:var(--font-head); font-size:18px; color:#fff; }
.rolOk p{ margin-top:8px; font-size:14px; line-height:1.6; color:#aeb8b8; }

/* ---- «Наши совместные работы с клиентами» — мозаика на главной ----
   Один объект крупно слева, четыре мельче справа сеткой 2×2. Раньше здесь была
   ровная лента из шести одинаковых плиток: все кадры равного веса, глазу не за
   что зацепиться. Крупный кадр показывает масштаб работы, мелкие — что объектов
   много. Карточки те же (.workCard), меняется только раскладка. */
.worksMosaic{ display:grid; gap:var(--gap-card); grid-template-columns:1fr; }
.worksMosaic .workCard img{ aspect-ratio:4/3; }
@container (min-width:700px){
  .worksMosaic{ grid-template-columns:1fr 1fr; grid-template-rows:1fr 1fr; }
  /* крупный кадр занимает обе строки левой колонки */
  .worksMosaic .workCard--big{ grid-row:span 2; }
  .worksMosaic .workCard--big img{ height:100%; aspect-ratio:auto; }
  /* правая половина — четыре плитки 2×2 внутри своей колонки */
  .worksMosaic > .workCard:not(.workCard--big){ min-height:0; }
}
@container (min-width:900px){
  .worksMosaic{ grid-template-columns:1.32fr 1fr 1fr; }
  .worksMosaic .workCard--big{ grid-row:span 2; grid-column:1; }
}

/* ---- SEO-блок внизу страницы: без карточки, заголовок в общий кегль ----
   Контур ничего не отделял (карточка белая внутри белой страницы), а внутренние
   поля 24px сдвигали текст внутрь относительно остальных секций. Убираем карточку
   целиком — блок встаёт на общую сетку, как «Преимущества» и раздел вопросов.
   Заголовок берёт --fs-h2 (28px), то есть тот же кегль, что и все заголовки
   блоков; на телефоне он вместе с ними уходит в 22px. */
.seo{ background:none; border:0; padding:0; border-radius:0; }
.seo h2, .seo h3{ font-size:var(--fs-h2); }
@container (max-width:699px){
  .seo{ padding:0; }
  .seo h2, .seo h3{ font-size:22px; }
}

/* ---- «Почему мы» + сертификат: раскладка как у SEO-блока ----
   Слева заголовок и текст, справа сертификат в серой плашке. Было две секции
   подряд: сетка из шести плиток (пять фактов + тёмная плитка «Ждём вас в студии»)
   и отдельная секция «Сертификаты компании». Плитки дробили одну мысль на шесть
   карточек, а сертификат стоял сам по себе — теперь это один блок. */
.aboutWhy{ display:grid; grid-template-columns:1fr; gap:24px; align-items:center; }
.aboutWhy__text h2{ font-family:var(--font-head); font-size:var(--fs-h2);
  font-weight:var(--fw-head); letter-spacing:var(--ls-head); line-height:1.25; }
.aboutWhy__text p{ margin-top:16px; font-size:var(--fs-body); line-height:1.75; color:#37413f; }
.aboutWhy__text p b{ color:var(--ink); }
.aboutWhy__note{ color:var(--muted) !important; }
.aboutWhy__btn{ display:inline-flex; margin-top:18px; padding:12px 22px;
  background:var(--red); color:#fff; font-weight:700; font-size:14px; border-radius:var(--r-card); }
.aboutWhy__btn:hover{ background:var(--red-d); color:#fff; }

/* Плашка вокруг сертификата — сплошная серая, как плашка FAQ на главной
   (.faqPlate, background:var(--bg)). Была почти белая (#fafbfb) с контуром:
   на белой странице она читалась как рамка вокруг пустоты, а не как блок.
   Правка 12.08.2026 по просьбе владельца. */
.aboutWhy__cert{ margin:0; background:var(--bg); border:0;
  border-radius:var(--r-block); padding:24px; display:grid; place-items:center; }

/* Пять преимуществ списком с точками. Стили сняты с .aboutMain .aboutFacts —
   тот селектор привязан к своей секции и сюда не достаёт. li::before гасим:
   в файле выше есть общее правило, рисующее собственный маркер у списков
   внутри .pageBody, и с ним точка была бы двойной. */
.aboutWhy__list{ margin-top:16px; margin-left:20px; list-style:disc outside;
  font-size:var(--fs-body); line-height:1.75; color:#37413f; }
.aboutWhy__list li{ display:list-item; padding:0; background:none; border-radius:0; }
.aboutWhy__list li::before{ content:none; }
.aboutWhy__list li + li{ margin-top:8px; }
.aboutWhy__list b{ color:var(--ink); }

/* Кнопка «Контакты и проезд»: надпись была КРАСНОЙ НА КРАСНОМ — кнопка выглядела
   пустой плашкой. Причина не в самой кнопке: `.pageBody a{color:var(--red)}`
   (вес 0-1-1) перебивал одиночный `.aboutWhy__btn` (0-1-0). Поднимаем вес ровно
   настолько, чтобы выиграть, — тип + два класса. */
.pageBody a.aboutWhy__btn,
.pageBody a.aboutWhy__btn:hover{ color:#fff; }
.aboutWhy__cert img{ width:100%; max-width:380px; height:auto; display:block;
  border-radius:var(--r-card); border:1px solid var(--line); background:#fff; }

@container (min-width:900px){
  .aboutWhy{ grid-template-columns:minmax(0,1fr) minmax(0,.9fr); gap:40px; }
}
@container (max-width:699px){
  .aboutWhy__cert{ padding:16px; }
  .aboutWhy__btn{ width:100%; justify-content:center; }
}
/* На телефоне заголовок этого блока уходит в 22px вместе со всеми заголовками
   блоков — своё правило .aboutWhy__text h2 стоит ниже общей группы и иначе
   перебило бы её, оставив 28px там, где у соседей 22. */
@container (max-width:699px){ .aboutWhy__text h2{ font-size:22px; } }
/* Пропорция коробки сертификата задана атрибутами width/height у самой картинки
   (800×1217) — так браузер резервирует место ДО загрузки. Без этого коробка была
   высотой 2px, и отложенная загрузка (loading="lazy") в неё просто не срабатывала:
   картинка не запрашивалась вообще, в сети ноль обращений (поймано 03.08.2026). */
.aboutWhy__cert img{ height:auto; }


/* =========================================================================
   ОФОРМЛЕНИЕ ЗАКАЗА — правки по замечаниям 12.08.2026.
   Блок стоит В КОНЦЕ файла намеренно: правила выше (.coH2, .coBlock, .agree,
   .navBtn, мобильная группа заголовков) уже заданы, и переопределить их можно
   только ниже — специфичность у всех одинаковая.
   ========================================================================= */

/* заголовок страницы крупнее шагов: 28 против 20 */
.catTop--order h1{ font-size:28px; line-height:1.2; }
.catTop--order{ margin-bottom:24px; }          /* замер: .shopLayout сюда ничего не добавляет */

/* шаги — 20px и шаг между блоками 24 (было 48 от --sec-gap) */
.coH2{ font-size:20px; line-height:1.25; margin-bottom:16px; }
.coBlock{ margin-top:24px; }
.coBlock:first-child{ margin-top:0; }
@container (max-width:699px){
  /* иначе сработает общая мобильная группа заголовков и шаг станет 22 — крупнее десктопа */
  .coH2{ font-size:18px; }
  .catTop--order h1{ font-size:22px; }
}

/* адрес доставки живёт внутри выбранной карточки (переносит v2.js) */
.optBody #v2AddressWrap{ margin-top:14px; }
.optBody #v2AddressWrap .coField{ background:#fff; border:1px solid var(--line); }

/* комментарий — обычное поле с рамкой, а не серая плашка */
.coField--plain{ background:#fff; border:1px solid var(--line); }
.coField--plain:focus-within{ border-color:var(--ink); }

/* согласие и кнопка переехали в правую плашку */
.agree--aside{ display:flex; align-items:flex-start; gap:10px; margin:16px 0 0;
  font-size:13px; line-height:1.45; color:var(--muted); }
.agree--aside input{ width:18px; height:18px; flex:none; margin-top:1px; }
.agreeLink{ color:var(--red); text-decoration:underline; }
.agreeLink:hover{ color:var(--red-d); }
.navBtn--aside{ display:block; width:100%; text-align:center; margin-top:12px; }
.buyCard .backLink{ margin-top:12px; }

/* ---- Оформление заказа на узком экране ----
   1. Переключатель покупателя — в строку. Вертикально две широкие плашки съедали
      пол-экрана до того, как человек доходил до полей.
   2. У способов доставки и оплаты убраны иконка и кружок с галочкой: на 375 px
      они забирали треть ширины, и текст сжимался в колонку по три слова в строке.
      Что выбрано, показывает сама карточка — красной рамкой и красным заголовком,
      этого достаточно. */
@container (max-width:699px){
  .segToggle{ display:flex; flex-wrap:nowrap; gap:8px; }
  .segToggle .segBtn{ flex:1 1 0; min-width:0; text-align:center; justify-content:center;
    padding:12px 10px; font-size:14px; }

  .optCard{ grid-template-columns:1fr; gap:8px; padding:16px; }
  .optCard .optRadio,
  .optCard .optIco{ display:none; }
  .optCard[data-on="true"]{ border-color:var(--red); box-shadow:0 0 0 1px var(--red) inset; }
  .optCard[data-on="true"] .optBody h4{ color:var(--red); }
  /* Название и цена — одной строкой: «Самовывоз» и «Бесплатно» это одна мысль,
     а двумя строками они занимали двойную высоту на узком экране. */
  .optBody{ display:flex; flex-wrap:wrap; align-items:baseline; gap:0 8px; }
  .optBody h4, .optBody .optPrice{ margin:0; }
  .optBody p{ flex:1 1 100%; margin-top:8px; }
}


/* =========================================================================
   КОРЗИНА — компактная строка по образцу (12.08.2026).
   Всё в одну линию: фото, название с опциями, количество, цена, крестик.
   Количество и цена выровнены по ВЕРХНЕМУ краю — при длинном названии
   и нескольких опциях они иначе уезжали в середину строки.
   ========================================================================= */
.cartRow{ grid-template-columns:72px minmax(0,1fr) auto auto 34px;
  grid-template-areas:"img info qty price x"; align-items:start; gap:6px 16px; padding:16px 0; }
.cartQtyWrap{ align-self:start; }
.cartLine{ align-self:start; padding-top:2px; }
.cartX{ align-self:start; }
.qLbl{ display:none; }                       /* подпись «Количество» не нужна */

/* колеровка строкой-действием, как на образце */
.cartTint{ display:inline-block; margin-top:6px; padding:0; background:none; border:0;
  font-size:13px; font-weight:700; color:var(--red); cursor:pointer; text-align:left;
  text-decoration:underline; text-underline-offset:2px; }
.cartTint:hover{ color:var(--red-d); }
.cartTint b{ font-weight:700; }
.cartTint[disabled]{ opacity:.5; cursor:default; }

@container (max-width:699px){
  /* на телефоне в одну строку не влезает: цена и количество уходят под название */
  .cartRow{ grid-template-columns:64px minmax(0,1fr) 34px;
    grid-template-areas:"img info x" "img qty price"; gap:8px 12px; }
  .cartLine{ text-align:right; }
}

/* =========================================================================
   МОБИЛЬНАЯ ТИПОГРАФИКА ЗАГОЛОВКОВ (правка 12.08.2026, просьба владельца)

   На телефоне заголовки были набраны десктопным кеглем: «О компании» — 28px,
   «В распоряжении нашей компании» — 20px. На 375px это съедало первый экран.
   Вводим два уровня и держим их по всему сайту:

     уровень 1 — заголовок БЛОКА  → 22px  (было 28)
     уровень 2 — заголовок ВНУТРИ блока → 18px  (было 20)

   Блок стоит В КОНЦЕ файла намеренно. Почти все перечисленные правила уже
   заданы выше и часть из них — внутри своих контейнерных запросов с тем же
   весом селектора. Спор равных по весу решает порядок, поэтому перебить их
   можно только отсюда; поднимать вес селекторами вида .v2root .secHead h2
   нельзя — тогда следующая правка кегля наверху файла молча перестанет
   работать, и причину будут искать долго.

   Токен --fs-h2 переопределён здесь же: на нём висят заголовки, которые
   поимённо не перечислены (новые секции подхватят 22px сами).
   ========================================================================= */
@container (max-width:699px){
  .wrap{ --fs-h2:22px; }

  /* уровень 1 — заголовки блоков */
  h1.pTitle,
  .catTop h1,
  .catTop--split h1,
  .catTop--order h1,
  .caseHead h1,
  .secHead h2,
  .faqPlate .secHead h2,
  .aboutWhy__text h2,
  .kolIntro h2,
  .seo h2,
  .kolBlock > .secHead h2{ font-size:22px; line-height:1.22; }

  /* уровень 2 — заголовки внутри блоков.
     ⚠️ Часть этих заголовков в разметке — h2, а не h3, и это не ошибка: уровень
     подняли, чтобы в коде шло h1 → h2 → h3 без пропусков, а размер оставили
     прежний, здесь. Меняете размер — меняете вид, а не структуру.
     .seo .seoTitle перебивает `.seo h2` из уровня 1 выше (два класса против
     класса с тегом), поэтому подзаголовок SEO-текста остаётся 18px. */
  .aboutMain .aboutMain__sub,
  .seo .seoTitle,
  .rolCard h2,
  .kolCard h2,
  .kolerCta h3,
  .rolCard h3,
  .chHead h2,
  .okBox h2,
  .helpMain h2,
  .coH2,
  .caseCol--text .caseBlock h2,
  .kolPlast--facts .kpcTitle,
  .conCard .conBig,
  .kolExpert__formTitle,
  .seo h3{ font-size:18px; line-height:1.3; }
}

/* ---- Строка корзины: количество, цена, крестик ----
   Блок количества был растянут во всю колонку под одну цифру. Теперь он по
   содержимому и прижат влево; кнопки крупнее — по ним промахивались пальцем. */
.cartQtyWrap .qty{ display:inline-flex; align-items:center; width:auto; }
.cartQtyWrap .qty button{ width:40px; height:40px; font-size:19px; }
.cartQtyWrap .qty input{ width:52px; height:40px; text-align:center; }
form.cartQtyWrap{ margin-top:12px; justify-self:start; }
/* Цена и подпись под ней — по правому краю, подпись кеглем характеристик. */
.cartLine{ text-align:right; align-self:start; }
.cartLine .cartEach{ display:block; text-align:right; font-size:13px; font-weight:600;
  color:var(--muted); margin-top:4px; white-space:normal; }
/* Крестик — на одной линии с названием товара, а не по центру строки. */
.cartDel{ align-self:start; }
.cartTint{ display:inline-block; margin-top:6px; background:none; border:0; padding:0;
  font:700 13px/1.4 inherit; color:var(--red); cursor:pointer; text-align:left; }
.cartTint:hover{ color:var(--red-d); }

/* Корзина не должна вылезать за контейнер: цена прижата вправо, но колонка
   ужимается вместе с экраном. nowrap оставлен только самой сумме — она короткая. */
.cartRow{ max-width:100%; }
.cartLine{ min-width:0; overflow-wrap:anywhere; }
.cartInfo{ min-width:0; }
.cartName{ overflow-wrap:anywhere; }
@container (max-width:699px){
  .cartRow{ grid-template-columns:64px minmax(0,1fr) 28px; grid-template-areas:"img info x" "img qty price"; gap:6px 12px; }
  .cartLine{ font-size:16px; }
  .cartQtyWrap .qty button{ width:36px; height:36px; }
  .cartQtyWrap .qty input{ width:44px; height:36px; }
}

/* ---- Строка корзины на десктопе: всё по верхней грани ----
   Название, количество, цена и крестик начинаются на одном уровне — ряд читается
   одной строкой, а не лесенкой. Количество прижато к левому краю своей колонки,
   поэтому оно ближе к тексту, а не висит посреди пустоты. Текстовому блоку
   добавлен отступ от фото: раньше он к нему прилипал. */
@container (min-width:700px){
  .cartRow{ grid-template-columns:96px minmax(0,1fr) minmax(150px,190px) minmax(90px,120px) 32px;
    column-gap:24px; align-items:start; }
  .cartInfo{ padding-left:4px; }
  form.cartQtyWrap{ margin-top:0; justify-self:start; }
  .cartLine{ align-self:start; margin-top:0; }
  .cartDel{ align-self:start; }
  .cartName{ display:block; line-height:1.3; }
}

/* ---- Карусель главного баннера -------------------------------------------
   Баннер на главной — тот же слайдер, что у фотографий кейса (.slider из
   v2.js): свайп, scroll-snap, стрелки, точки и клавиши там уже написаны.
   Своей механики у баннера нет намеренно — один слайдер на сайт, один набор
   граблей. Слайды и их тексты лежат в чанке v2_hero_slides.

   Отличий от галереи три:
   1) слайд — это .heroMain, поэтому вся геометрия баннера (высота, радиус,
      отступы, поведение 3D-пирога) достаётся ему даром;
   2) фон у каждого слайда свой — через --shot прямо в чанке;
   3) точки лежат ВНУТРИ кадра, справа внизу: слева внизу стоит кнопка, а
      середину занимает 3D-пирог. */
.slider--hero{ display:flex; flex-direction:column; flex:1; }
.slider--hero .sliderTrack{ flex:1; align-items:stretch; }

/* Колонка баннера ОБЯЗАНА уметь сжиматься. В сетке .heroGrid автоминимум
   колонки равен min-content её содержимого, а лента из трёх слайдов с
   flex:0 0 100% (не сжимаются) отдаёт min-content в три экрана. Без этих двух
   строк на планшете колонка распирала сетку до 802px в контейнере 768px, а
   промо-блок справа схлопывался в 0 (замер DOM 12.08.2026). */
.heroLeft{ min-width:0; }
.slider--hero .sliderTrack{ min-width:0; }

/* Все слайды одной высоты. Высоту НЕ задаём числом жёстко: у слайда с 3D-пирогом
   она своя на каждом брейкпоинте (340/360/440, а с пирогом на узком экране 470),
   плюс на планшете текст второго слайда перерастал 360px — при height:auto
   баннер тогда прыгал с 360 на 436 между слайдами (замер DOM 12.08.2026).
   Поэтому min-height задаёт «не ниже макета», а height:auto + растяжение флексом
   подтягивают ВСЕ слайды под самый высокий. Если WebGL2 недоступен и 3D не
   завелось, баннер просто остаётся фотографией той же высоты. */
.slider--hero .heroMain{ height:auto; min-height:340px; }
@container (max-width:699px){ .slider--hero .heroMain{ min-height:470px; } }
@container (min-width:700px){ .slider--hero .heroMain{ min-height:360px; } }
@container (min-width:1100px){ .slider--hero .heroMain{ min-height:440px; } }

/* Фон слайда. Не задан --shot — остаётся общий снимок баннера, тот же, что
   был у одиночного .heroMain. Затемнение повторяет исходное: снимки светлые,
   на слабой вуали белый текст теряется. */
.slider--hero .heroMain{
  background:linear-gradient(120deg,rgba(18,20,24,.80),rgba(4,6,8,.52)),
             var(--shot,url('/img/hero-bg.jpg')) center/cover; }

/* Плашка «Акция» над заголовком. align-self обязателен: .heroMain — колоночный
   flex, без него плашка растянулась бы во всю ширину кадра. */
.heroTag{ align-self:flex-start; font:700 11px/1 var(--font-body); letter-spacing:.04em;
  text-transform:uppercase; background:var(--red); color:#fff; padding:6px 9px;
  border-radius:6px; margin-bottom:10px; }

/* Стрелки: на тёмном кадре белые кружки галереи выглядят заплаткой, поэтому
   здесь они стеклянные. На узком экране .sliderBtn скрыт общим правилом —
   листают свайпом, и это правильно: кнопка на баннере съедала бы текст. */
.slider--hero .sliderBtn{ background:rgba(10,13,18,.55); color:#fff;
  border-color:rgba(255,255,255,.28); box-shadow:none;
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px); }
.slider--hero .sliderBtn:hover{ background:var(--red); border-color:var(--red); }

/* Точки внутри кадра, у правого нижнего угла. Подложки нет намеренно: под ними
   тёмная часть баннера, а лишний прямоугольник спорил бы с кнопкой. */
.slider--hero .sliderDots{ position:absolute; right:20px; bottom:18px; margin:0; z-index:4; }
.slider--hero .sliderDots i{ background:rgba(255,255,255,.45); }
.slider--hero .sliderDots i[data-on="true"]{ background:#fff; }
@container (max-width:699px){
  .slider--hero .sliderDots{ right:14px; bottom:14px; }
}


/* =========================================================================
   ПОДВАЛ — логотип, иконки соцсетей/контактов, политика (12.08.2026)
   ========================================================================= */
.footLogo{ display:inline-block; margin-bottom:28px; }
.footLogo img{ display:block; height:38px; width:auto;
  /* логотип чёрный, подвал тёмный — выворачиваем в белый */
  filter:brightness(0) invert(1); opacity:.92; }
.footLogo:hover img{ opacity:1; }

/* .fsoc был текстовыми заглушками <i>; теперь настоящие ссылки-иконки */
.fsoc a{ width:34px; height:34px; border-radius:8px; background:#2a3335;
  display:flex; align-items:center; justify-content:center; color:#cfd6d6; }
.fsoc a:hover{ background:#39474a; }
.fsoc svg{ width:20px; height:20px; fill:currentColor; }
.fsoc svg rect{ fill:none; }        /* у иконки VK своя подложка — она тут лишняя */

.footPolicy{ color:#7d8888; text-decoration:underline; text-underline-offset:2px; }
.footPolicy:hover{ color:#cfd6d6; }
@container (max-width:699px){
  .footLogo img{ height:30px; }
  .footBottom{ flex-direction:column; align-items:flex-start; gap:8px; }
}

/* ─── Корзина на телефоне: нижняя строка «количество слева — цена справа» ───
   (правка 10.08.2026, по образцу карточки корзины Петровича)

   Было сломано: в мобильной сетке цена попадала в ТРЕТЬЮ колонку шириной 28px
   (она заведена под крестик удаления). Из-за этого «3 850 ₽ за единицу»
   рассыпалось в столбик по букве, а сумма с nowrap торчала за краем экрана.

   Стало: первая строка — картинка, название и крестик; вторая — количество и
   цена НА ОДНОЙ линии, количество прижато влево, цена вправо.

   ⚠️ Приём: оба элемента лежат в ОДНОЙ ячейке сетки (area "foot") и разводятся
   по краям через justify-self. Так третья колонка остаётся 28px под крестик, и
   широкая цена НЕ съедает ширину названия — а именно это и происходило, если
   отдать цене отдельную колонку (замер: название ужималось до ~167px).
   Ширина цены ограничена 58%, чтобы при длинной подписи «20 034 ₽ за шт»
   она не наехала на кнопки количества. */
@container (max-width:699px){
  .cartRow{
    /* ⚠️ Первая колонка равна ШИРИНЕ КАРТИНКИ. Стояло 64px при картинке 72px:
       фото вылезало из своей колонки на 8px и съедало зазор — название визуально
       липло к изображению (замер: 8px вместо 16px). */
    grid-template-columns:72px minmax(0,1fr) 28px;
    grid-template-areas:
      "img info x"
      "img foot foot";
    gap:10px 16px;              /* 16px по горизонтали — название отодвинуто от фото */
  }
  .cartImg{ width:72px; height:72px; }
  form.cartQtyWrap{ grid-area:foot; justify-self:start; align-self:center; margin-top:0; }
  .cartLine{
    grid-area:foot; justify-self:end; align-self:center;
    max-width:58%; text-align:right; font-size:17px; white-space:nowrap; padding-top:0; }
  /* Подпись «за шт.» — ТОЧНО тот же стиль, что у «Фасовка»/«Фактура» (.cartMeta):
     13px, цвет --muted, line-height 1.5, обычное начертание. Значения там жирные
     только внутри <b>, а сама подпись — нет. */
  .cartLine .cartEach{
    text-align:right; font-size:13px; font-weight:400; line-height:1.5;
    color:var(--muted); margin-top:2px; white-space:normal; }
}

/* ---- Кнопка баннера, открывающая окно ------------------------------------
   На баннере кнопка бывает двух видов: <a> ведёт на страницу, <button> с
   data-call открывает окно обратного звонка. Внешне это одна и та же красная
   кнопка, но у <button> браузер рисует свою рамку и берёт системный шрифт —
   сбрасываем, иначе на слайде-акции кнопка выглядит чужой. */
/* line-height 1.2 — ровно как у ссылки .heroBtn на соседнем слайде: при 1.5
   кнопка становилась на 5px выше и рядом смотрелась другой. */
button.heroBtn{ border:0; cursor:pointer; font-family:var(--font-body); line-height:1.2; }

/* Второстепенная ссылка рядом с кнопкой. На слайде акции главное действие —
   звонок, но путь на витрину скидок терять нельзя: кто не хочет разговаривать,
   идёт смотреть цены сам. .heroBottom — flex со space-between, поэтому ссылка
   встаёт к правому краю сама. На самых узких экранах убираем: там она отжимала
   кнопку и обе строки лезли друг на друга. */
.heroLink{ color:#fff; opacity:.82; font-size:13px; font-weight:600; white-space:nowrap; align-self:flex-end; }
.heroLink:hover{ opacity:1; text-decoration:underline; }
@container (max-width:429px){ .heroLink{ display:none; } }


/* ---- Слайд с нарисованной подложкой (баннер акции) -----------------------
   Подложка — рисунок из Figma, а плашка, заголовок, текст и кнопка лежат
   поверх настоящими элементами. Поэтому тёмной вуали здесь НЕТ: замер рисунка
   показал в зоне текста медиану яркости 94 из 255, белое читается и так,
   а вуаль перекрасила бы цвета макета.

   Положение кадра вынесено в переменную --shotPos прямо в чанк v2_hero_slides:
   двигать картинку должен тот, кто правит баннер, не трогая CSS. */
.slider--hero .heroArt{
  /* Раздельные свойства, а не сокращение: на телефоне подменяется ТОЛЬКО
     картинка (--shotMob), остальное остаётся общим. */
  background-image:var(--shot);
  background-position:var(--shotPos,center);
  background-size:cover;
  background-repeat:no-repeat;
}
/* Подложка под текстом — слева и на нет к середине. Нужна потому, что у кадра
   сверху небо: замер по зоне текста дал верхний дециль 209 и 15% пикселей
   светлее 200, белый заголовок по такому небу не читается. Гасим ТОЛЬКО левую
   часть — товары справа остаются в исходном цвете. */
.slider--hero .heroArt::before{
  content:''; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(90deg, rgba(10,12,16,.66) 0%, rgba(10,12,16,.46) 34%,
                                    rgba(10,12,16,0) 62%);
}
.slider--hero .heroArt > *{ position:relative; z-index:2; }
/* Текст держим в левой трети кадра: товары на рисунке начинаются примерно с
   середины, и общие ширины героя (заголовок 20ch, абзац 40ch) заводили строки
   прямо на вёдра — замер показал заезд на 60px. Здесь ширины свои, поуже. */
.slider--hero .heroArt h2{ max-width:300px; }
.slider--hero .heroArt p{ max-width:310px; }
/* Описание на баннере акции — 13px, а не общие 15px с брейкпоинта ≥1100:
   заголовок тут в четыре строки, и абзац тем же кеглем спорил с ним за внимание. */
.slider--hero .heroArt p{ font-size:13px; }
@container (max-width:699px){
  .slider--hero .heroArt h2, .slider--hero .heroArt p{ max-width:none; }
}
/* На узком экране кадр вертикальный, а рисунок горизонтальный — влезает около
   трети. Показываем правую часть: там товары, ради которых баннер и сделан. */
/* Планшет: свой кадр. Его слайд почти квадратный (456×360), и широкая
   десктопная картинка резалась бы по бокам на четверть. Нет --shotTab —
   подставляется десктопный, ничего не ломается. */
@container (min-width:700px) and (max-width:1099px){
  .slider--hero .heroArt{ background-image:var(--shotTab, var(--shot)); }
}
@container (max-width:699px){
  /* Телефон берёт свою картинку: широкий кадр здесь обрезался бы до трети. */
  .slider--hero .heroArt{ background-image:var(--shotMob, var(--shot)); background-position:72% center; }
  /* Вуаль ТОЛЬКО на узком экране. На десктопе её нет намеренно — там в кадре
     тёмные ступени и цвета макета остаются нетронутыми. Но на телефоне в кадр
     попадают светлые вёдра: замер рисунка в этой зоне дал медиану яркости 163
     и десятую часть пикселей светлее 200 — белый текст по ним не читается.
     Гасим сверху вниз: текст стоит вверху, товары внизу остаются в цвете. */
  .slider--hero .heroArt::before{
    background:linear-gradient(180deg, rgba(8,10,14,.80) 0%, rgba(8,10,14,.58) 45%,
                                       rgba(8,10,14,.18) 76%, rgba(8,10,14,0) 100%); }
}

/* Тёмная кнопка баннера — как на макете акции. Красная (.heroBtn) осталась
   основной по сайту, эта только для слайдов, где красный спорит с рисунком. */
.heroBtn--dark{ background:var(--ink); }
.heroBtn--dark:hover{ background:var(--red); color:#fff; }


/* =========================================================================
   ЗАЯВКИ ИЗ ШАПКИ: обратный звонок и запрос КП (13.08.2026)
   ========================================================================= */
.utilMail{ }
.kpBtn{ border:1px solid var(--ink); color:var(--ink); background:none; font-weight:700;
  font-size:13px; padding:9px 16px; border-radius:var(--r-card); white-space:nowrap; margin-left:auto; }
.kpBtn:hover{ background:var(--ink); color:#fff; }
@container (max-width:899px){ .kpBtn{ display:none; } }   /* в узкой шапке места нет */

.leadModal[hidden]{ display:none; }
.leadModal{ position:fixed; inset:0; z-index:95; display:flex; align-items:center;
  justify-content:center; padding:16px; }
.leadBack{ position:absolute; inset:0; background:rgba(15,20,22,.55); }
.leadBox{ position:relative; background:#fff; border-radius:var(--r-block); padding:28px;
  width:min(460px,100%); max-height:90vh; overflow:auto; }
.leadX{ position:absolute; top:10px; right:12px; width:34px; height:34px; border-radius:50%;
  background:none; color:var(--muted); font-size:22px; line-height:1; }
.leadX:hover{ background:var(--bg); color:var(--ink); }
/* h2, а не h3: модалка живёт в шапке и попадает на КАЖДУЮ страницу, а её
   заголовок шёл сразу после h1 — получался пропуск уровня на всём сайте.
   Размер задан здесь и от смены тега не меняется. */
.leadBox h2, .leadBox h3{ font-family:var(--font-head); font-size:20px; font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.25; padding-right:34px; }
.leadNote{ font-size:13.5px; line-height:1.6; color:var(--muted); margin-top:8px; }
/* Явное правило, а не расчёт на браузерное [hidden]: в режиме «Помочь выбрать»
   подпись пустая и абзац прячется, иначе от него остался бы отступ. */
.leadNote[hidden]{ display:none; }
.leadField{ display:flex; flex-direction:column; gap:5px; margin-top:14px; }
.leadField span{ font-size:12px; color:var(--muted); } .leadField i{ color:var(--red); font-style:normal; }
.leadField input, .leadField textarea{ border:1px solid var(--line); border-radius:10px;
  padding:11px 14px; font:15px/1.4 var(--font-body); color:var(--ink); background:#fff; outline:none; }
.leadField input:focus, .leadField textarea:focus{ border-color:var(--ink); }
.leadField textarea{ resize:vertical; min-height:80px; }
/* honeypot: спрятан от человека, но доступен боту — поэтому не display:none */
.leadHp{ position:absolute; left:-9999px; width:1px; height:1px; opacity:0; }

.leadFile{ display:flex; align-items:center; gap:10px; margin-top:14px; padding:12px 14px;
  border:1px dashed var(--line); border-radius:10px; cursor:pointer; }
.leadFile:hover{ border-color:var(--ink); }
.leadFile input{ position:absolute; width:1px; height:1px; opacity:0; }
.leadFileText{ font-size:13px; color:var(--muted); }

/* у обратного звонка комментария и файла нет — только имя и телефон */
/* Комментарий и файл нужны только запросу КП. И у обратного звонка, и у «Помочь
   выбрать» поля те же — имя и телефон, поэтому оба режима перечислены здесь.
   Забыть добавить сюда новый режим = он покажет лишние поля. */
.leadModal[data-kind="callback"] .leadOnlyKp,
.leadModal[data-kind="help"] .leadOnlyKp{ display:none; }
/* Обратное правило: строку «позвоните или оставьте заявку» прячем в режиме КП. */
.leadModal[data-kind="kp"] .leadCallNote{ display:none; }

/* Строка «Вы можете позвонить нам…» над полем «Имя» (чанк v2_callnote).
   Один набор правил на все формы: и на обычные страницы, и в модалку. */
.formCallNote{ margin:0 0 16px; font-size:13.5px; line-height:1.5; color:var(--muted); }
/* Номер красный СРАЗУ, а не по наведению. Было var(--ink), и на тёмной карточке
   формы (.rolCard, .formCard) это почти чёрный на чёрном — замер давал
   rgb(20,26,28), номер фактически не читался. */
.formCallNote a{ color:var(--red); font-weight:700; text-decoration:none; white-space:nowrap;
  border-bottom:1px solid currentColor; }
.formCallNote a:hover{ color:var(--red-d); }
/* На тёмных карточках --red-d уходит в грязь, поэтому там наведение держим ярким. */
.rolCard .formCallNote a:hover,
.formCard .formCallNote a:hover{ color:var(--red); }
/* В модалке строка идёт сразу под подписью-пояснением, отступ там нужен меньше. */
.leadCallNote .formCallNote{ margin-bottom:14px; }

.leadMsg{ margin-top:14px; font-size:13.5px; border-radius:10px; padding:10px 12px; }
.leadMsg[data-ok="true"]{ background:#eaf7f0; color:#166b45; }
.leadMsg[data-ok="false"]{ background:#fdeef1; color:var(--red-d); }
.leadSubmit{ width:100%; margin-top:16px; }
.leadPolicy{ margin-top:12px; font-size:12px; line-height:1.5; color:var(--faint); }
.leadPolicy a{ color:var(--muted); text-decoration:underline; }

/* ---- Список заказов в личном кабинете ------------------------------------
   Блок достался от старого бутстрап-шаблона и до сих пор не имел НИ ОДНОГО
   стиля: заказы шли сплошняком, отличить один от другого было нельзя.
   Разделитель задан владельцем именно так: отступ — линия — отступ, поэтому
   это .lkOrder + .lkOrder, а не рамка вокруг каждого заказа. У первого заказа
   ни линии, ни верхнего отступа нет — потому и соседский селектор.
   Порядок правил: телефон — база, широкий экран — в @container ниже. */
/* ВАЖНО: тильда, а не плюс. Между двумя карточками заказов лежит скрытый блок
   подробностей (.cabinet__order-inner, display:none), поэтому соседом .lkOrder
   является НЕ следующий заказ, и правило с `+` не срабатывало вообще: линии
   между заказами не появлялось, хотя стиль был написан. */
.lkOrder ~ .lkOrder{ margin-top:22px; border-top:1px solid var(--line); padding-top:22px; }

.lkOrderHead{ display:flex; flex-wrap:wrap; align-items:baseline; gap:6px 12px; }
.lkOrderNum{ font-weight:700; font-size:16px; color:var(--ink); }
.lkOrderDate{ font-size:13px; color:var(--muted); }
/* Статус уезжает вправо только когда в строке есть место: на узком экране
   flex-wrap переносит его на свою строку, и margin-left:auto ничего не ломает. */
.lkOrderStatus{ margin-left:auto; font-size:13px; }

.lkOrderGoods{ margin-top:12px; }
.lkOrderGoods p{ margin:0 0 6px; font-size:14px; line-height:1.5; }
.lkOrderGoods p:last-child{ margin-bottom:0; }
.lkOrderGoods a{ color:var(--ink); text-decoration:underline; text-underline-offset:2px; }
.lkOrderGoods a:hover{ color:var(--red); }
/* Товар снят с публикации: ссылка никуда не ведёт, поэтому и выглядит неактивной. */
.lkOrderGoods .text-muted, .lkOrderGoods a.text-muted{ color:var(--faint); text-decoration:none; }
.lkOrderGoods .text-nowrap{ white-space:nowrap; }

/* Доставка и оплата. dl/dt/dd несут браузерные отступы — сбрасываем, иначе
   строки разъезжаются по-разному в Safari и Chrome. */
.lkOrderMeta{ margin:12px 0 0; display:grid; gap:4px; }
.lkOrderMetaRow{ display:grid; grid-template-columns:104px 1fr; gap:10px; align-items:baseline; }
.lkOrderMeta dt{ margin:0; font-size:13px; color:var(--muted); }
.lkOrderMeta dd{ margin:0; font-size:14px; color:var(--ink); }

@container (min-width:700px){
  .lkOrder ~ .lkOrder{ margin-top:28px; padding-top:28px; }
  .lkOrderNum{ font-size:17px; }
  .lkOrderGoods{ margin-top:14px; }
  .lkOrderGoods p{ font-size:15px; }
  .lkOrderMetaRow{ grid-template-columns:120px 1fr; }
  .lkOrderMeta dd{ font-size:15px; }
}

/* ---- Оформление заказа: нумерация шагов, пояснения, ошибки ----------------
   Номера шагов НЕ вписаны в разметку: блок «Реквизиты организации» появляется
   только при оплате по счёту, и с ручными номерами получалось «3, потом 5».
   Счётчик считает только видимые блоки — скрытый display:none он пропускает. */
#v2Order{ counter-reset:coStep; }
#v2Order .coH2::before{ counter-increment:coStep; content:counter(coStep) ". "; }

.coHint{ margin:0 0 14px; font-size:14px; line-height:1.55; color:var(--muted); max-width:62ch; }

/* Поле с ошибкой. Подсвечиваем ВЕСЬ блок поля, а не рамку инпута: у .coField
   фон-плашка и своей рамки у input нет — тонкая обводка внутри неё терялась. */
.coField.is-err{ background:#fdeef1; box-shadow:inset 0 0 0 1.5px var(--red); }
.coField.is-err span{ color:var(--red-d); }
.optCard.is-err{ box-shadow:inset 0 0 0 1.5px var(--red); }
.agree.is-err span{ color:var(--red-d); }

/* ---- Закреплённая шапка при прокрутке -------------------------------------
   Просьба владельца: на мобильном меню и корзина должны оставаться под рукой,
   не надо мотать страницу вверх.

   ПОЧЕМУ sticky, а НЕ fixed: у .v2root стоит container-type:inline-size, а это
   включает layout containment — и .v2root становится содержащим блоком для
   position:fixed. Фиксированная шапка цеплялась бы за него, а не за экран, и
   уезжала при прокрутке (та же грабля, из-за которой v2.js переносит мобильное
   меню в конец body). Sticky привязывается к области прокрутки и работает.

   z-index 50 — ниже мобильного меню (60), модалок (80–95) и попапа колеровки (90),
   чтобы шапка не лезла поверх открытых окон. */
.hdr{ position:sticky; top:0; z-index:50; background:#fff; }

/* Тень появляется ТОЛЬКО когда шапка прилипла. Постоянная тень вернула бы линию
   под шапкой, которую на широком экране специально убрали (там разделяет .catbar),
   и на неприкреплённой шапке получалась бы двойная полоса. Класс ставит v2.js.

   ⚠️ Тень висит на НИЖНЕМ элементе прилипшего блока, а не на .hdr всегда.
   На широком экране под шапкой едет строка категорий, и тень от .hdr ложилась
   МЕЖДУ ними — получалась полоса поперёк закреплённой панели, будто это два
   разных куска. Поэтому там тень уезжает на .catbar, а у .hdr снимается. */
.hdr.is-stuck{ box-shadow:0 2px 12px rgba(15,20,22,.10); }

/* На широком экране под шапкой едет строка категорий — прилепляем и её, иначе
   каталог уезжает, а шапка висит с пустым низом. top задаётся из v2.js реальной
   высотой шапки: она разная на разных экранах, фиксированное число разъезжается. */
@container (min-width:700px){
  .catbar{ position:sticky; z-index:49; background:#fff; }
  /* Строка категорий видна — она и есть низ закреплённой панели. Тень отдаём ей,
     у шапки снимаем, иначе полоса ляжет поперёк, между шапкой и категориями. */
  .hdr.is-stuck{ box-shadow:none; }
  .catbar.is-stuck{ box-shadow:0 2px 12px rgba(15,20,22,.10); }
  /* Своя нижняя линия у категорий при этом лишняя — её роль берёт тень,
     иначе под панелью читаются две границы подряд. */
  .catbar.is-stuck{ border-bottom-color:transparent; }
}

/* ---- Живой поиск в шапке -------------------------------------------------
   Подсказки появляются под полем прямо во время ввода (скрипт в v2.js).
   Список позиционируется от .searchWrap, поэтому у неё position:relative. */
.searchWrap{ position:relative; }

/* Кнопка «Найти» внутри поля. Показывается с двух символов — атрибут hidden
   снимает v2.js. Прижата к правому краю поля, поэтому поле само её не обрезает. */
.searchGo{ flex:none; margin:4px; border:0; cursor:pointer; font:600 14px/1 var(--font-body);
  background:var(--red); color:#fff; border-radius:8px; padding:10px 16px; }
.searchGo:hover{ background:var(--ink); }
.searchGo[hidden]{ display:none; }

/* Выпадающий список. Пустой — не показывается вовсе (:empty), поэтому скрипту
   не нужен отдельный класс «закрыт»: он просто чистит содержимое. */
.liveList{ position:absolute; left:0; right:0; top:calc(100% + 6px); z-index:60;
  background:#fff; border:1px solid var(--line); border-radius:12px; overflow:hidden;
  box-shadow:0 18px 40px -12px rgba(20,26,28,.28); max-height:70vh; overflow-y:auto; }
.liveList:empty{ display:none; }

.lsItem{ display:flex; align-items:center; gap:12px; padding:10px 14px; color:var(--ink);
  border-bottom:1px solid var(--line); }
.lsItem:last-child{ border-bottom:0; }
.lsItem:hover{ background:var(--bg); }
.lsImg{ width:44px; height:44px; object-fit:contain; flex:none; background:#fff; }
/* Название занимает всё свободное место и обрезается многоточием в одну строку:
   в подсказке важна скорость чтения, а не полный текст. */
.lsName{ flex:1; min-width:0; font-size:14px; line-height:1.35;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.lsPrice{ flex:none; font-weight:700; font-size:14px; white-space:nowrap; }
.lsEmpty{ padding:14px; font-size:13px; color:var(--muted); }

@container (max-width:699px){
  .lsName{ font-size:13px; }
  .lsImg{ width:38px; height:38px; }
  .searchGo{ padding:9px 12px; font-size:13px; }
}

/* ---- Пустой поиск: отдельный экран -----------------------------------------
   Когда по запросу ничего нет, страница показывает ТОЛЬКО это: заголовок по
   центру и кнопку в каталог. Фильтры, сортировка и пустая сетка не рисуются
   вовсе (условие в шаблоне «Каталог v2»): фильтровать нечего, а пустой сайдбар
   рядом с пустой выдачей читается как поломка. */
.emptyFind{ display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; gap:22px; min-height:46vh; padding:40px 16px 64px; }
.emptyFind b{ font-family:var(--font-head); font-size:26px; font-weight:var(--fw-head);
  letter-spacing:var(--ls-head); line-height:1.25; color:var(--ink); max-width:22ch; }
.emptyBtn{ background:var(--red); color:#fff; font-weight:700; font-size:15px;
  padding:14px 26px; border-radius:10px; }
.emptyBtn:hover{ background:var(--ink); color:#fff; }
@container (max-width:699px){
  .emptyFind{ min-height:38vh; gap:18px; }
  .emptyFind b{ font-size:20px; }
  .emptyBtn{ font-size:14px; padding:12px 20px; }
}

/* ---- Корзина: смена фасовки прямо в строке ------------------------------
   Колеровку из корзины поменять было можно, а фасовку нет — приходилось удалять
   строку и заходить в товар заново. Чипы те же, что в карточке товара, только
   мельче: здесь это правка, а не выбор. Текущая фасовка показана disabled —
   нажимать на неё некуда, но видно, что выбрано. */
.cartSizes{ display:flex; align-items:center; flex-wrap:wrap; gap:8px; margin:10px 0; }
.cartSizes[hidden]{ display:none; }
/* Сами чипы лежат в отдельном контейнере (v2.js перерисовывает только его),
   поэтому расстояние между вариантами задаётся ЗДЕСЬ, а не gap-ом .cartSizes —
   иначе кнопки стояли впритык друг к другу. */
.csChips{ display:inline-flex; flex-wrap:wrap; gap:8px; }
.csLabel{ font-size:13px; color:var(--muted); }
.csChip{ font:600 12.5px/1 var(--font-body); color:var(--ink); background:#fff;
  border:1.5px solid var(--line); border-radius:8px; padding:6px 10px; cursor:pointer; }
.csChip:hover{ border-color:var(--ink); }
.csChip[data-on="true"]{ background:var(--ink); border-color:var(--ink); color:#fff; cursor:default; }

/* Пока запрос в пути, коробка корзины гаснет и не принимает кликов: иначе
   второе нажатие «+» ушло бы к уже устаревшему ключу строки. */
#v2CartBox[data-busy]{ opacity:.55; pointer-events:none; }
#v2CartBox{ transition:opacity .12s linear; }

/* «Перейти в корзину» под кнопкой в карточке товара. Появляется только после
   первого добавления — до него вести туда некуда (создаёт v2.js). */
.addedLink{ display:block; text-align:center; margin-top:10px; font:600 13.5px/1.2 var(--font-body);
  color:var(--red); }
.addedLink:hover{ color:var(--red-d); }

/* ---- Кнопка «Каталог» на десктопе: без иконки-бургера ----
   Три полоски рядом со словом «Каталог» — единственный бургер, который оставался
   виден на широком экране, и читались они как «открыть меню», хотя это обычная
   ссылка в каталог. Само слово справляется без иконки. */
@container (min-width:1100px){
  .catBtn .bl{ display:none; }
}

/* ---- Карточка товара: «уже в корзине» ------------------------------------
   Счётчик в карточке в этом состоянии правит саму строку корзины, поэтому он
   должен читаться как «живой», а не как заготовка для будущего добавления:
   рамка чернеет, кнопка перестаёт быть красной «В корзину» и ведёт в корзину. */
.inCart{ margin-top:10px; text-align:center; font:600 13.5px/1.3 var(--font-body); color:var(--muted); }
.inCart[hidden]{ display:none; }
.inCart b{ color:var(--ink); font-weight:700; }
.qtyBuy[data-in-cart="true"] .qty{ border-color:var(--ink); }
.qtyBuy[data-in-cart="true"] .bbAdd{ background:var(--ink); }
.qtyBuy[data-in-cart="true"] .bbAdd:hover{ background:#000; }

/* Кнопка покупки делит строку со счётчиком и живёт на flex:1, то есть ширина у неё
   остаточная. Надпись в состоянии «уже в корзине» длиннее обычной — без nowrap она
   разрывалась надвое внутри 46-пиксельной кнопки. */
.qtyBuy .bbAdd{ white-space:nowrap; }

/* ---- Мобильная панель покупки: прилипает к низу экрана -------------------
   На телефоне блок покупки уезжает под галерею, характеристики и описание —
   чтобы положить товар, надо было прокрутить страницу обратно наверх. Поэтому
   на узком экране v2.js ПЕРЕНОСИТ сюда сам <form> (счётчик, кнопку и скрытые
   поля с фасовкой/цветом/фактурой/колеровкой) — не копию, а тот же элемент.
   Копия разъехалась бы с оригиналом: количество здесь живое и правит корзину.

   ⚠️ Панель живёт в <body>, СНАРУЖИ .v2root: там container-type:inline-size,
   а он делает элемент содержащим блоком для position:fixed — внутри неё панель
   не держалась бы за экран, а уезжала со страницей (та же грабля, что с мобильным
   меню и попапами). Отсюда же и @media вместо @container: контейнера здесь нет. */
.buyBar{ display:none; }
@media (max-width:699px){
  .buyBar{
    display:block; position:fixed; left:0; right:0; bottom:0; z-index:55;
    background:#fff; border-top:1px solid var(--line);
    box-shadow:0 -6px 24px rgba(15,20,22,.10);
    padding:10px 12px calc(10px + env(safe-area-inset-bottom));
  }
  .buyBar .bbRow{ display:flex; align-items:center; gap:10px; }
  .buyBarPrice{ display:flex; flex-direction:column; line-height:1.15; flex:none; }
  .buyBarPrice b{ font:700 17px/1.15 var(--font-body); color:var(--ink); white-space:nowrap; }
  .buyBarPrice s{ font:600 12px/1.2 var(--font-body); color:var(--faint); text-decoration:line-through; white-space:nowrap; }
  .buyBarPrice s:empty{ display:none; }
  /* форма внутри панели — обычная строка, без отступов карточки */
  .buyBar form.ms2_form{ flex:1; margin:0; }
  .buyBar .qtyBuy{ gap:10px; }
  .buyBar .qtyBuy .qty{ height:44px; flex:none; }
  .buyBar .qtyBuy .bbAdd{ height:44px; }
  /* «В корзине: N штук» — тонкой строкой над кнопкой, а не отдельным блоком */
  .buyBar .inCart{ margin:0 0 8px; font-size:12.5px; }
  .buyBar .addedLink{ display:none; }   /* туда же ведёт сама кнопка */

  /* Чтобы панель не легла поверх подвала: подпираем страницу снизу.
     Класс ставит v2.js — на страницах без панели отступ не нужен. */
  body.hasBuyBar{ padding-bottom:78px; }
  /* Мобильное меню открыто — панель убираем, иначе торчит поверх шторки */
  body.mmOpen .buyBar{ display:none; }
}

/* ---- Метка «уже в корзине» на переключателях вариантов -------------------
   Каждая связка фасовка+цвет+фактура+колеровка — отдельная строка корзины.
   Раньше узнать, что 1 л лежит в корзине, а 2 л нет, можно было только
   перещёлкав все чипы. Теперь количество видно прямо на переключателе. */
#v2Facturas .fchip, #v2Colors .fchip, #v2Colors .cSw, #v2ColorsAll .cSw{ position:relative; }
.inCartMark{ position:absolute; top:-7px; right:-7px; min-width:18px; height:18px; padding:0 5px;
  border-radius:9px; background:var(--ink); color:#fff; font:700 11px/18px var(--font-body);
  font-style:normal; text-align:center; box-shadow:0 0 0 2px #fff; pointer-events:none; }
/* у выбранного чипа фон уже тёмный — метку делаем красной, иначе сливается */
.fchip[data-on="true"] .inCartMark{ background:var(--red); }

/* Образец цвета колеровки в строке корзины — чтобы она выглядела так же,
   как карточка товара, где цвет видно, а не только его название. */
/* Воздух между строкой фасовки и строкой колеровки: без него они слипались
   в одну кашу из подписей. */
.cartSizes + .cartMeta--tint{ margin-top:2px; }
.cartMeta--tint{ margin-bottom:2px; }

.tintSw{ display:inline-block; width:12px; height:12px; border-radius:3px; vertical-align:-1px;
  margin-right:6px; border:1px solid rgba(15,20,22,.18); }
.tintSw[hidden]{ display:none; }
