/* ═══════════════════════════════════════════════════════════════════════════
   ЛЕГИОН — стили сайта. Один файл на все страницы: главная, разделы, услуги.
   Палитра, типографика и правила — из брендбука /brand/ (концепция K2, схема 70/30).

   MOBILE-FIRST без исключений: базовые правила описывают телефон, расширения —
   только @media(min-width). Ни одного max-width-запроса в файле; если он
   появился, значит верстали от десктопа.
   ═══════════════════════════════════════════════════════════════════════════ */
:root{
  /* база 70% */
  --milk:#F2F1EE; --sunk:#E4E2DD; --line:#D8D5CF;
  /* графит 30% */
  --ink:#17191C; --ink2:#20242A;
  --grey:#5E6166; --grey-d:#A7ABB2;
  /* ── акцент: латунь, два тона под два фона ───────────────────────────────
     15.08 бронза заменена на латунь. Заказчик: «дорогого латунного у нас по
     всей видимости не получилось», сторонний человек на его экране прочитал
     прежний #9C5B2C как коричневый. Из присланной им шкалы выбран вариант,
     который он назвал сам, — «строгая архитектурная латунь» #A99572.

     Почему тонов два, а не один. Латунь живёт только на графите: на молочном
     фоне #A99572 даёт 2.6:1 и проваливается. Для светлых фонов та же латунь
     затемнена до #7C6B4A — 4.58:1 на молочном, 5.17:1 на белой карточке.
     Прежняя пара работала так же, только в обратную сторону: тёмная бронза
     держалась на светлом и слабела на графите.

     --brass    — на графите и тёмных экранах (6.06:1)
     --brass-d  — на молочном, белом и в подложках (5.8:1 на молочном, 5.0 на
                  подложке). 18.08.2026 затемнён с #7C6B4A: прежний давал 4.58:1
                  на молочном, но на sunk и на brass-soft падал до 4.0 — ссылки
                  «Весь раздел →» и подписи в раскрытой карточке системы не
                  дотягивали до 4.5:1. На графите он не используется никогда:
                  там только --brass
     Ставить их наоборот нельзя ни в одном месте: оба падают ниже AA. */
  --brass:#A99572; --brass-d:#6B5C3D; --brass-soft:rgba(124,107,74,.10);
  --h:'Manrope',system-ui,sans-serif;
  --s:'Inter',system-ui,sans-serif;
  --m:'JetBrains Mono',ui-monospace,Menlo,monospace;
  --serif:'Playfair Display',Georgia,serif;
  --wrap:1180px;
}
*{box-sizing:border-box;margin:0;padding:0}
/* Плавность прокрутки живёт в скрипте (ссылки-якоря в assets/layout.php), а не
   свойством на html. Глобальный scroll-behavior:smooth делает плавным ЛЮБОЕ
   программное перемещение: последовательные window.scrollTo прерывают друг друга
   и страница останавливается на полпути — так на главной блоки внизу оставались
   непрокрученными, а приёмка ловила «страница открывается пустой» через раз. */
html{-webkit-text-size-adjust:100%}
body{background:var(--milk);color:var(--ink);font-family:var(--s);font-size:17px;line-height:1.62;
  -webkit-font-smoothing:antialiased}
/* ⚠️ 19.08.2026: с body снят overflow-x:hidden. По MOBILE_STANDARD он «страховка,
   а не решение» — прячет уехавший элемент вместо того, чтобы его починить, и при
   этом ломает position:sticky у всех потомков (липкая схема систем на главной не
   работала). Горизонтальный скролл контролируется гейтом mobile_gutter_lint на
   320/360/393/430; появилось переполнение — ищем виновника, а не возвращаем строку. */
img{max-width:100%;height:auto;display:block}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{font-family:var(--h);letter-spacing:-.022em;font-weight:700;line-height:1.13}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 20px}
@media(min-width:641px){.wrap{padding:0 32px}}

section{padding:56px 0;border-top:1px solid var(--line)}
@media(min-width:641px){section{padding:88px 0}}
section.dark{background:var(--ink);color:var(--milk);border-top:0}
section.dark p{color:var(--grey-d)}

.kicker{display:block;font-family:var(--m);font-size:13px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--brass-d)}
/* Кикер из двух частей: на телефоне стопкой, с планшета — одной строкой через «·». */
.k-2l span{display:block}
.k-2l span + span{margin-top:4px}
@media(min-width:641px){
  .k-2l span,.k-2l span + span{display:inline;margin-top:0}
  /* Разделитель отбивается слева больше, чем справа: разрядка .2em кикера добавляет
     воздух только после символа, и без компенсации точка липнет к «ЛЕГИОН». */
  .k-2l span + span::before{content:"·";margin:0 .3em 0 .6em}
}
section.dark .kicker{color:var(--brass)}
.h-sec{font-size:clamp(27px,6.6vw,44px);margin:14px 0 0}
.lead{color:var(--grey);margin-top:15px;font-size:16.5px;max-width:68ch}
section.dark .lead{color:var(--grey-d)}
@media(min-width:641px){.lead{font-size:18.5px}}
.sec-head{margin-bottom:32px}
@media(min-width:641px){.sec-head{margin-bottom:46px}}

/* ── лок-ап ─────────────────────────────────────────────────────────────────
   Знак всегда слева от слова и масштабируется целиком: вертикальная сборка
   утверждённой формой не является. Размер — один font-size, остальное в em.

   ДВЕ ВЕРСИИ, и это решение заказчика от 15.08. Компактная (знак + слово) —
   в шапке. Полная (с дескриптором) — в подвале, в брендбуке, в презентациях
   и на носителях.

   Почему подпись ушла из шапки. Дескриптор должен быть равен по оптической
   ширине слову «ЛЕГИОН» — иначе, по его словам, «выглядит не как дизайнерское
   решение, а как не дотянули вёрстку логотипа». Равенство достигается связкой
   «кегль .147em + трекинг .385em» от вордмарка: 28 знаков моноширинного капса
   разгоняются ровно на ширину шести букв антиквы. Но кегль подписи при этом
   выходит в 6.8 раза мельче слова — в шапке, где лок-ап 24–27 px, это 3.5–4 px,
   то есть серая полоса. Читаемые 8–9 px начинаются от лок-апа в 55 px, а такой
   в строку шапки не встаёт. Отсюда и деление: равенство ширин там, где размер
   его позволяет; в шапке — компактная версия, как он и предложил сам. */
.lockup{display:flex;align-items:center;gap:.42em;font-size:24px}
.lockup svg{flex:none;width:1.85em;height:auto}
.lockup .wm{display:inline-block;font-family:var(--serif);font-weight:700;font-size:1em;letter-spacing:.05em;line-height:1}
/* Полная версия: подпись по ширине слова. Кегль и отступ в em от вордмарка —
   равенство держится на любом размере само. Отрицательный margin гасит хвост,
   который трекинг добавляет после последней буквы. */
.lockup-full .wm small{display:block;font-family:var(--m);font-size:.147em;font-weight:400;
  letter-spacing:.385em;margin-right:-.385em;margin-top:1.53em;line-height:1;
  color:var(--grey-d);white-space:nowrap;text-transform:uppercase}
.lockup-full .wm small i{font-style:normal;color:var(--brass)}
@media(min-width:941px){.lockup{font-size:27px}}

/* ── шапка с меню разделов ─────────────────────────────────────────────────
   Меню повторяет структуру сайта, а не якоря одной страницы: у каждого раздела
   выпадает список его страниц. Так с главной видно весь многостраничник. */
header{position:sticky;top:0;z-index:60;background:rgba(23,25,28,.94);
  backdrop-filter:blur(12px);border-bottom:1px solid rgba(242,241,238,.10)}
/* Высота считается от знака: при кегле лок-апа 24 px знак 52 px, ниже 68 px шапки
   он начинает касаться границы. Меняете кегль лок-апа — проверьте эти два числа.
   max-width шире общего .wrap: в 1180 px строка шапки не помещалась и кнопка
   «Обсудить проект» уезжала за правый край экрана. После перехода на двухслойное
   меню строка занимает 926 px (лок-ап 231 + меню 472 + кнопка 191 + зазоры 32),
   но запас оставлен: 1520 — предел, при котором шапка ещё читается как одна строка
   с контентом, а не расползается по краям монитора. */
.hd{display:flex;align-items:center;justify-content:space-between;gap:16px;height:68px;color:var(--milk);max-width:1520px}
@media(min-width:941px){.hd{height:80px}}
.nav{display:none}
/* Меню включается там, где помещается целиком: 926 px содержимого + 64 px полей =
   990, порог 1081 с запасом. История порога стоит того, чтобы её записать: восемь
   пунктов верхнего уровня требовали 1426 px, и кнопка уезжала за край экрана на
   всех ширинах от 1041 px — приходилось держать порог 1441 и отдавать ноутбуки
   бургеру. Пять пунктов бренд-логики вернули меню на 1081. Ниже порога работает
   бургер: он раскрывает ту же двухслойную структуру и ничего не прячет. */
@media(min-width:1081px){.nav{display:flex;gap:2px;align-items:center}}
.nav-i{position:relative}
/* nowrap обязателен: без него длинные названия разделов («Пожарная безопасность»)
   ломают шапку на две строки. Кегль и поля подобраны так, чтобы пять пунктов,
   лок-ап с подписью и кнопка укладывались в одну строку на пороге 1081 px. */
.nav-i > a{display:block;padding:9px 8px;font-size:13.4px;color:var(--grey-d);border-radius:8px;white-space:nowrap}
.nav-i:hover > a,.nav-i:focus-within > a{color:var(--milk);background:rgba(242,241,238,.07)}
.drop{position:absolute;top:100%;left:0;min-width:290px;background:var(--ink2);
  border:1px solid rgba(242,241,238,.14);border-radius:12px;padding:8px;
  opacity:0;visibility:hidden;transform:translateY(6px);transition:.16s;
  box-shadow:0 18px 40px rgba(0,0,0,.4)}
.nav-i:hover .drop,.nav-i:focus-within .drop{opacity:1;visibility:visible;transform:none}
.drop a{display:block;padding:9px 12px;border-radius:8px;font-size:14.5px;color:var(--grey-d);line-height:1.35}
.drop a:hover{background:rgba(242,241,238,.08);color:var(--milk)}
.drop .all{color:var(--brass);border-top:1px solid rgba(242,241,238,.12);margin-top:6px;padding-top:11px}
/* Мега-меню второго слоя: четыре силоса колонками в одном выпадающем списке.
   position:static у пункта + left/right:0 у списка растягивают его на всю ширину
   шапки — четыре колонки иначе не помещаются и вылезают за экран. */
.nav-mega{position:static}
.drop-mega{left:0;right:0;display:grid;grid-template-columns:repeat(4,1fr);gap:4px 18px;padding:18px}
.mega-col{display:flex;flex-direction:column}
.mega-h{font-family:var(--h);font-weight:600;font-size:14px;color:var(--milk)!important;
  padding-bottom:9px;margin-bottom:4px;border-bottom:1px solid rgba(242,241,238,.14)}
.mega-col a{font-size:13.8px;padding:7px 0}
.mega-col .all{margin-top:auto;border-top:0;padding-top:9px}
/* Кнопка появляется с 641 px: на телефоне место занято лок-апом и бургером, а на
   планшете и ноутбуке строка шапки без неё выглядит пустой — знак слева, бургер
   справа и ничего между. Селектор из двух классов намеренно: одноклассовый .hd-cta
   проиграл бы правилу .btn ниже по файлу. */
.hd .hd-cta{display:none}
/* margin-left:auto прижимает кнопку к бургеру: при justify-content:space-between и
   спрятанном меню она иначе повисает по центру пустой шапки. */
@media(min-width:641px){.hd .hd-cta{display:inline-flex;margin-left:auto;padding:12px 20px;font-size:15px}}
@media(min-width:1081px){.hd .hd-cta{padding:14px 26px;font-size:16px}}
.burger{display:inline-flex;align-items:center;justify-content:center;width:42px;height:42px;
  border:1px solid rgba(242,241,238,.22);border-radius:9px;background:none;color:var(--milk);cursor:pointer}
@media(min-width:1081px){.burger{display:none}}
.burger svg{width:20px;height:20px}
.m-menu{display:none;background:var(--ink2);border-top:1px solid rgba(242,241,238,.10);padding:10px 0 22px;
  max-height:calc(100dvh - 68px);overflow-y:auto}
.m-menu.open{display:block}
.m-sec{border-bottom:1px solid rgba(242,241,238,.08)}
.m-sec > button{width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:14px 0;background:none;border:0;color:var(--milk);font-family:var(--s);font-size:17px;
  text-align:left;cursor:pointer}
.m-sec > button svg{width:16px;height:16px;flex:none;transition:transform .2s;color:var(--grey-d)}
.m-sec.open > button svg{transform:rotate(180deg)}
.m-sub{display:none;padding:0 0 14px}
.m-sec.open .m-sub{display:block}
.m-sub a{display:block;padding:9px 0 9px 14px;color:var(--grey-d);font-size:15.5px;
  border-left:1px solid rgba(242,241,238,.14)}
.m-sub a.hub{color:var(--brass)}
.m-menu .flat{display:block;padding:14px 0;color:var(--milk);font-size:17px;
  border-bottom:1px solid rgba(242,241,238,.08)}
.m-menu .btn{margin-top:18px;width:100%}

/* ── кнопки ── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;padding:14px 26px;
  border-radius:10px;font-family:var(--s);font-weight:600;font-size:16px;cursor:pointer;
  border:1px solid transparent;transition:background .18s,color .18s,border-color .18s}
/* Главная кнопка меняет тон вместе с фоном — по тому же правилу, что и весь
   акцент. На светлом: тёмная латунь, белый текст (5.2:1). На графите латунная
   плашка светлая, а текст на ней графитовый (6.1:1) — так кнопка читается как
   металл, а не как коричневый прямоугольник, и не спорит с тёмным фоном. */
.btn-p{background:var(--brass-d);color:#fff}
.btn-p:hover{background:#6A5B3E}
header .btn-p,.hero .btn-p,section.dark .btn-p,.m-menu .btn-p{background:var(--brass);color:var(--ink)}
header .btn-p:hover,.hero .btn-p:hover,section.dark .btn-p:hover,.m-menu .btn-p:hover{background:#B7A078}
.btn-s{border-color:rgba(242,241,238,.34);color:var(--milk)}
.btn-s:hover{background:rgba(242,241,238,.08)}
.btn-d{border-color:var(--ink);color:var(--ink)}
.btn-d:hover{background:rgba(23,25,28,.06)}
.btns{display:flex;flex-direction:column;gap:12px;margin-top:30px}
@media(min-width:521px){.btns{flex-direction:row;flex-wrap:wrap;align-items:center}}

/* ── первый экран ──────────────────────────────────────────────────────────
   Фотография объекта под графитовой заливкой: снимок отдельно для телефона
   (вертикальный кадр, воздух сверху под заголовок) и для десктопа (широкий,
   пустая левая треть). Один и тот же кадр, обрезанный по-разному, на телефоне
   превращается в кашу — поэтому <picture> с двумя источниками, а не object-fit. */
.hero{background:var(--ink);color:var(--milk);position:relative;overflow:hidden;
  padding:44px 0 52px;border-top:0}
@media(min-width:941px){.hero{padding:96px 0 104px}}
.hero-bg{position:absolute;inset:0;z-index:0}
.hero-bg img{width:100%;height:100%;object-fit:cover;object-position:50% 78%}
/* Затемнение держит контраст текста, но кадр должен остаться видимым: на телефоне
   заголовок лежит на небе (там плотнее), а здание внизу открыто. Первая версия
   с .92 сверху съедала фотографию целиком — на экране оставался серый прямоугольник. */
.hero-bg::after{content:"";position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(23,25,28,.90) 0%,rgba(23,25,28,.80) 38%,rgba(23,25,28,.46) 72%,rgba(23,25,28,.72) 100%)}
@media(min-width:941px){
  .hero-bg img{object-position:70% 50%}
  .hero-bg::after{background:linear-gradient(90deg,rgba(23,25,28,.96) 0%,rgba(23,25,28,.88) 42%,rgba(23,25,28,.52) 78%,rgba(23,25,28,.62) 100%)}
}
.hero-in{position:relative;z-index:2}
.hero .kicker,.hero .kicker span{color:var(--brass)}
.hero h1{font-size:clamp(34px,9.4vw,74px);margin:16px 0 0;letter-spacing:-.03em}
.hero h1 em{font-style:normal;color:var(--brass)}
.hero .sub{color:#D5D7DA;font-size:17px;margin-top:20px;max-width:58ch}
@media(min-width:641px){.hero .sub{font-size:20px}}
.claim{font-family:var(--h);font-weight:600;font-size:16px;margin-top:26px;
  padding-left:16px;border-left:2px solid var(--brass);line-height:1.5}
@media(min-width:641px){.claim{font-size:19px}}
.hero-facts{display:grid;grid-template-columns:1fr 1fr;gap:20px 18px;margin-top:40px;
  padding-top:26px;border-top:1px solid rgba(242,241,238,.18)}
@media(min-width:941px){.hero-facts{grid-template-columns:repeat(4,1fr);gap:30px;margin-top:56px;max-width:960px}}
.hero-facts b{display:block;font-family:var(--h);font-size:26px;font-weight:700;letter-spacing:-.02em}
@media(min-width:641px){.hero-facts b{font-size:30px}}
.hero-facts span{display:block;font-size:13.5px;color:#C3C6CB;margin-top:5px;line-height:1.4}
/* «С 2014 года» — не число, поэтому кегль ниже: иначе плитка перевешивает соседние
   и строка ломается пополам на узком экране. */
.hero-facts b{overflow-wrap:break-word}
.hero-facts .yr{font-size:21px}
@media(min-width:641px){.hero-facts .yr{font-size:24px}}
/* География вынесена из первой строки вниз — просьба заказчика 14.08. */
.hero-geo{font-family:var(--m);font-size:13px;letter-spacing:.1em;text-transform:uppercase;
  color:#A7ABB2;margin-top:22px}

/* ── почему интегратор: заявление + четыре обещания ────────────────────────
   Второй блок страницы и самый крупный по кеглю после H1: по словам заказчика,
   это и есть его продукт. Плитки набраны как заголовки h2, потому что по смыслу
   они равноправны, а не подписи к картинкам. */
.h-claim{font-family:var(--h);font-weight:700;line-height:1.16;letter-spacing:-.025em;
  font-size:clamp(25px,6.2vw,40px);margin-top:16px;max-width:22ch}
@media(min-width:941px){.h-claim{max-width:26ch}}
/* Четыре опоры, а не четыре текстовые карточки. Заказчик 15.08: «я бы попросил
   дизайнера сделать это фактически четырьмя опорами продукта: 01 БЮДЖЕТ, 02 СРОК…
   и меньше текста. Этот блок должен давать ощущение — вот что я покупаю».
   Отсюда крупный набор слова, номер моноширинной латунью над ним и одна строка
   пояснения вместо двух предложений. Прежняя латунная черта под заголовком снята:
   её роль взял на себя номер. */
.promise{display:grid;gap:30px;margin-top:38px;padding-top:30px;
  border-top:1px solid rgba(242,241,238,.18);counter-reset:pr}
@media(min-width:641px){.promise{grid-template-columns:1fr 1fr;gap:38px 34px}}
@media(min-width:1041px){.promise{grid-template-columns:repeat(4,1fr);gap:34px;margin-top:52px}}
.promise > div::before{counter-increment:pr;content:"0" counter(pr);display:block;
  font-family:var(--m);font-size:13px;letter-spacing:.16em;color:var(--brass);margin-bottom:14px}
.promise h2{font-size:clamp(26px,6.4vw,32px);letter-spacing:-.025em;margin-bottom:12px;color:var(--milk)}
.promise p{color:var(--grey-d);font-size:15.5px;line-height:1.55;max-width:34ch}

/* ── что входит в контур: расшифровка под путём проекта ── */
.scope{display:grid;gap:16px;margin-top:34px;padding-top:30px;border-top:1px solid var(--line)}
@media(min-width:761px){.scope{grid-template-columns:1fr 1fr;gap:24px 34px}}
.scope h3{font-size:17.5px;margin-bottom:7px}
.scope p{color:var(--grey);font-size:15.3px;line-height:1.55}

/* ── плоская плашка-примечание (цифровой контур) ── */
.note-flat{margin-top:30px;border-left:2px solid var(--brass-d);padding:4px 0 4px 18px}
.note-flat b{display:block;font-family:var(--h);font-size:17px;margin-bottom:7px}
.note-flat p{color:var(--grey);font-size:15.3px;line-height:1.55}
.note-flat p span{font-family:var(--m);font-size:13px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--brass-d);margin-right:6px}

/* ── контраст моделей ── */
/* Живёт внутри секции «Почему интегратор», отсюда верхняя черта вместо границы
   секции: это продолжение одного аргумента, а не новый блок. */
.why-vs{margin-top:44px;padding-top:34px;border-top:1px solid rgba(242,241,238,.18)}
@media(min-width:641px){.why-vs{margin-top:58px;padding-top:46px}}
.why-vs .lead{margin-top:0;margin-bottom:24px}
.why-vs .vs-card{background:var(--ink2);border-color:rgba(242,241,238,.14)}
.why-vs .vs-card h3{color:var(--milk)}
.why-vs .vs-card li{color:var(--grey-d)}
.why-vs .vs-card.on{background:var(--milk);border-color:var(--milk);color:var(--ink)}
.why-vs .vs-card.on h3{color:var(--ink)}
.why-vs .vs-card.on li{color:var(--grey)}
.why-vs .vs-card.on li::before{background:var(--brass-d)}
/* В блоке «Обычная схема / С ЛЕГИОНОМ» карточки инвертированы относительно
   базовых: обычная тёмная, наша светлая. Поэтому кикеры красятся наоборот —
   светлая латунь на тёмной карточке, тёмная на светлой. */
.why-vs .vs-card .kicker{color:var(--brass)}
.why-vs .vs-card.on .kicker{color:var(--brass-d)}
.vs{display:grid;gap:14px;margin-top:6px}
@media(min-width:761px){.vs{grid-template-columns:1fr 1fr;gap:18px}}
.vs-card{border:1px solid var(--line);border-radius:14px;padding:24px 20px;background:#fff}
@media(min-width:641px){.vs-card{padding:30px 28px}}
.vs-card.on{background:var(--ink);border-color:var(--ink);color:var(--milk)}
.vs-card h3{font-size:19px;margin:12px 0 12px}
.vs-card ul{list-style:none;display:grid;gap:11px}
.vs-card li{position:relative;padding-left:22px;font-size:15.5px;color:var(--grey);line-height:1.5}
.vs-card.on li{color:var(--grey-d)}
.vs-card li::before{content:"";position:absolute;left:0;top:9px;width:9px;height:1.5px;background:var(--grey)}
.vs-card.on li::before{background:var(--brass);width:11px}

/* ── цепочка ответственности ──────────────────────────────────────────────
   padding-left:17px — это ровно радиус кружка-счётчика, который висит на линии
   с `left:-17px`. Без него самый левый пиксель блока приходится на 3 px от края
   экрана: цифры 01–05 липнут к рамке телефона, а весь остальной текст стоит на
   поле 20 px. Компенсация возвращает кружки на общее поле. С 941 px раскладка
   меняется на три колонки, счётчик встаёт в `left:0` — компенсация снимается. */
.chain{display:grid;gap:0;margin-top:8px;counter-reset:ch;padding-left:17px}
.chain-i{position:relative;padding:0 0 26px 44px;border-left:1px solid rgba(242,241,238,.18)}
.chain-i:last-child{border-left-color:transparent;padding-bottom:0}
.chain-i::before{counter-increment:ch;content:"0" counter(ch);position:absolute;left:-17px;top:-2px;
  width:34px;height:34px;border-radius:50%;background:var(--ink2);border:1px solid rgba(242,241,238,.22);
  display:flex;align-items:center;justify-content:center;font-family:var(--m);font-size:13px;color:var(--brass)}
.chain-i h3{font-size:17.5px;margin-bottom:7px}
.chain-i p{font-size:15.5px;color:var(--grey-d);max-width:62ch}
@media(min-width:941px){
  .chain{grid-template-columns:repeat(3,1fr);gap:30px 34px;margin-top:20px;padding-left:0}
  .chain-i{padding:22px 0 0;border-left:0;border-top:1px solid rgba(242,241,238,.18)}
  .chain-i:last-child{border-top-color:rgba(242,241,238,.18)}
  .chain-i::before{left:0;top:-18px}
}
.chain-sum{margin-top:34px;padding:22px 20px;border:1px solid rgba(169,149,114,.4);border-radius:14px;
  background:rgba(169,149,114,.07);font-family:var(--h);font-weight:600;font-size:16.5px;line-height:1.5}
@media(min-width:641px){.chain-sum{padding:26px 30px;font-size:19px;margin-top:44px}}

/* ── схема объекта ── */
.scheme{display:grid;gap:22px;margin-top:8px}
@media(min-width:941px){.scheme{grid-template-columns:1.05fr .95fr;gap:38px;align-items:start}}
/* Поля карточки на телефоне ужаты с 14 до 8 px: каждый пиксель ширины идёт в масштаб
   схемы, а от него зависит читаемость подписей уровней (см. .bld-lbl ниже).
   ⚠️ Выносить схему за поля .wrap отрицательными margin нельзя — это ломает поле
   экрана и ловится гейтом mobile_gutter_lint.js. Ширину добираем полями карточки. */
.scheme-fig{border:1px solid var(--line);border-radius:16px;background:#fff;padding:8px}
@media(min-width:641px){.scheme-fig{padding:22px}}
/* Липкой схема становится только там, где рядом есть колонка списка. */
@media(min-width:941px){.scheme-fig{position:sticky;top:96px}}
.scheme-fig svg{width:100%;height:auto;display:block}
.bld-shell{fill:none;stroke:#C9C5BE;stroke-width:1.4}
.bld-fill{fill:#F4F3F0}
/* Кегль в единицах viewBox, а не в экранных пикселях: холст 560 единиц рендерится
   на телефоне в 335 px, то есть масштаб 0.6 — и прежние 8.5 давали на экране 4.9 px,
   нечитаемую пыль. По формуле §4.2 канона (13 × viewBox_w / css_w) нужно 22 единицы;
   на десктопе те же 22 единицы дают 22 px и читаются как метки чертежа.
   Трекинг убавлен с .08em, иначе «КРОВЛЯ» вылезает из левой колонки на слой ЭОМ. */
.bld-lbl{font-family:'JetBrains Mono',monospace;font-size:22px;fill:var(--grey);letter-spacing:.02em}
/* Цвет — общий серый бренда: 5.6:1 на подложке разреза #F4F3F0. Прежний #8B8F95
   давал 2.93 и не проходил AA даже для крупного текста, а на телефоне подпись
   кеглем 13 px считается мелкой — там нужен порог 4.5. */
.sys-g{transition:opacity .22s}
.sys-g .ln{fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
.sys-g .dt{stroke:none}
.scheme-fig.act .sys-g{opacity:.13}
.scheme-fig.act .sys-g.on{opacity:1}
.sys-list{display:grid;gap:10px}
.sys-b{width:100%;text-align:left;border:1px solid var(--line);border-radius:13px;background:#fff;
  padding:16px 18px;cursor:pointer;font-family:var(--s);transition:border-color .18s,background .18s}
.sys-b:hover{border-color:#BDB8B0}
.sys-b.on{border-color:var(--brass-d);background:var(--brass-soft)}
/* Строка «название + аббревиатуры» переносится: аббревиатуры набраны nowrap, и на
   узком экране пара вроде «Пожарная безопасность / АПС · СОУЭ · АУПТ · ВПВ · ОГЗ»
   в одну строку не влезает — колонка раздувалась шире экрана и страница ехала вбок.
   min-width:0 обязателен: у элемента грида он по умолчанию auto, и колонка
   отказывается сжиматься до ширины родителя. */
.scheme > *,.sys-list,.sys-b{min-width:0}
.sys-b .t{display:flex;align-items:baseline;justify-content:space-between;gap:6px 12px;flex-wrap:wrap}
.sys-b h3{font-size:17px;color:var(--ink)}
.sys-b .ab{font-family:var(--m);font-size:13px;letter-spacing:.1em;color:var(--brass-d);white-space:nowrap}
.sys-b .body{display:none}
.sys-b.on .body{display:block}
.sys-b p{font-size:14.8px;color:var(--grey);margin-top:8px;line-height:1.5}
.sys-b .go{display:inline-block;margin-top:10px;font-size:14.5px;color:var(--brass-d);font-weight:600}
.sys-note{font-size:14.5px;color:var(--grey);margin-top:16px}

/* ── сетки карточек ── */
.grid{display:grid;gap:14px}
@media(min-width:641px){.grid{gap:18px}}
.g2{grid-template-columns:1fr}
.g3{grid-template-columns:1fr}
@media(min-width:641px){.g2,.g3{grid-template-columns:1fr 1fr}}
@media(min-width:941px){.g3{grid-template-columns:repeat(3,1fr)}}
/* Цвет текста задан явно, а не унаследован. section.dark ставит color:var(--milk)
   на всю секцию, а карточка внутри неё остаётся белой — заголовок h3 своего цвета
   не имел и наследовал молочный, то есть был белым по белому (контраст 1.06:1).
   Абзац это не задело: у .card p цвет прописан. Правило: у любого блока со своим
   фоном цвет текста объявляется вместе с фоном, иначе он зависит от того, в какую
   секцию блок положили. */
.card{background:#fff;color:var(--ink);border:1px solid var(--line);border-radius:14px;padding:22px 20px}
@media(min-width:641px){.card{padding:26px 26px}}
.card h3{font-size:18px;margin-bottom:9px}
.card p{color:var(--grey);font-size:15.5px;line-height:1.55}
/* section.dark p идёт с большей специфичностью и перекрашивал абзацы белой
   карточки в светло-серый — 2.3:1 на белом. Возвращаем цвет явно. */
section.dark .card p{color:var(--grey)}
section.dark .card h3,section.dark .card h4{color:var(--ink)}
.card .num{font-family:var(--m);font-size:13px;color:var(--brass-d);letter-spacing:.14em;margin-bottom:12px;display:block}
a.card{display:block;transition:border-color .18s,transform .18s}
a.card:hover{border-color:var(--brass-d);transform:translateY(-2px)}
a.card .go{display:inline-block;margin-top:12px;font-size:14.5px;color:var(--brass-d);font-weight:600}
.tag-soon{display:inline-block;font-family:var(--m);font-size:13px;letter-spacing:.1em;text-transform:uppercase;
  background:var(--sunk);color:var(--grey);border-radius:20px;padding:4px 9px;margin-left:8px;vertical-align:2px}

/* ── допуски: превью документа + его реквизиты ──────────────────────────────
   Раньше здесь стояли две голые картинки в inline-стилях, продублированные на
   главной и в /o-kompanii/. Документ без подписи не читается: на превью не
   видно ни номера, ни даты, ни того, что именно он разрешает. Поэтому карточка
   = превью первой страницы + реквизиты рядом. На телефоне превью сверху, с
   641px уходит в левую колонку фиксированной ширины. */
.docs{display:grid;gap:14px}
@media(min-width:941px){.docs{grid-template-columns:1fr 1fr;gap:18px}}
/* Селектор именно a.doc, а не .doc: выше в файле стоит a.card{display:block} с
   большей специфичностью — с одноклассовым .doc карточка оставалась блоком,
   превью растягивалось на всю ширину, а реквизиты уезжали под него. */
a.doc{padding:0;overflow:hidden;display:grid;grid-template-columns:minmax(0,1fr)}
@media(min-width:641px){a.doc{grid-template-columns:190px minmax(0,1fr);padding:0}}
@media(min-width:941px){a.doc{grid-template-columns:170px minmax(0,1fr)}}
/* min-width:0 обязателен: у картинки-грид-элемента минимальная ширина по
   умолчанию равна её собственной (1240px), колонка распирается на всю карточку
   и выдавливает текст за край — ровно это и случилось на первом прогоне. */
.doc img{display:block;width:100%;height:100%;min-width:0;max-height:260px;object-fit:cover;object-position:top;
  background:var(--sunk);border-bottom:1px solid var(--line)}
@media(min-width:641px){.doc img{max-height:none;border-bottom:0;border-right:1px solid var(--line)}}
.doc-t{padding:20px}
@media(min-width:641px){.doc-t{padding:24px 24px 22px}}
.doc-t h3{font-size:18px;margin-bottom:6px}
.doc-t b{display:block;font-family:var(--m);font-size:14px;letter-spacing:-.01em;color:var(--ink)}
.doc-m{display:block;color:var(--grey);font-size:14px;margin-top:3px}
.doc-t p{color:var(--grey);font-size:15px;line-height:1.5;margin-top:12px}
.doc-l{display:inline-block;margin-top:14px;font-size:14.5px;color:var(--brass-d);font-weight:600}

/* ── витрина раздела: хаб + список страниц ── */
.silo{border:1px solid var(--line);border-radius:16px;background:#fff;padding:22px 20px;
  display:flex;flex-direction:column}
@media(min-width:641px){.silo{padding:28px 26px}}
.silo h3{font-size:20px;margin-bottom:8px}
.silo > p{color:var(--grey);font-size:15.3px;line-height:1.5}
.silo ul{list-style:none;margin-top:16px;padding-top:14px;border-top:1px solid var(--line);
  display:grid;gap:2px;flex:1}
.silo li a{display:block;padding:7px 0;font-size:15.3px;color:var(--ink);line-height:1.4}
.silo li a:hover{color:var(--brass-d)}
.silo .more{margin-top:14px;font-size:14.5px;color:var(--brass-d);font-weight:600}

/* ── проекты ── */
.prj{display:grid;gap:16px;margin-top:8px}
@media(min-width:641px){.prj{grid-template-columns:1fr 1fr}}
@media(min-width:1041px){.prj{grid-template-columns:repeat(3,1fr)}}
.prj article{border:1px solid var(--line);border-radius:16px;overflow:hidden;background:#fff;
  display:flex;flex-direction:column}
.prj .ph{aspect-ratio:16/10;overflow:hidden;background:var(--sunk)}
.prj .ph img{width:100%;height:100%;object-fit:cover;transition:transform .5s}
/* Объект без своей фотографии: графитовая плашка со знаком вместо чужого кадра.
   Ставить сюда сток нельзя — под именем объекта должен быть этот объект. */
/* Заглушка вместо фотографии — плашка со знаком. Пропорция мельче кадра (16/10):
   17.08 в блоке комплексных объектов таких карточек стало четыре подряд, и в
   полный кадр они читались как «фото не загрузились». Полоса со знаком читается
   как приём, а не как дыра. */
/* Схема объекта вместо фотографии: SVG сам держит пропорцию 16/10, поэтому
   aspect-ratio здесь не нужен — иначе схема обрежется по краям. */
.prj .ph-scheme{background:var(--ink);overflow:hidden}
.prj .ph-scheme svg{display:block;width:100%;height:auto}
.prj .ph-mark{display:flex;align-items:center;justify-content:center;background:var(--ink);aspect-ratio:16/5}
.prj .ph-mark svg{width:44px;height:auto;opacity:.9}
.prj article:hover .ph img{transform:scale(1.04)}
.prj .bd{padding:20px;display:flex;flex-direction:column;gap:8px;flex:1}
/* .art-h — заголовок карточки в списке статей. Это h2 по структуре
   страницы, но по размеру он остаётся карточным: уровень заголовка
   и его кегль — разные вещи. */
.prj h3{font-size:18px}
.prj .art-h{font-size:21px;margin:0;letter-spacing:-.018em;line-height:1.26}
/* Карточка объекта в тёмной секции. Фон карточки белый всегда, а цвет текста
   до 19.08 наследовался от section.dark — молочный по белому, 1.13:1
   (поймал contrast_lint на /ovik/vodosnabzhenie-kanalizaciya/). Цвет объявляем
   там же, где фон, и сразу для всех узлов карточки. */
section.dark .prj article{color:var(--ink)}
section.dark .prj h3,section.dark .prj .art-h{color:var(--ink)}
section.dark .prj p,section.dark .prj .d{color:var(--grey)}
.prj .meta{font-family:var(--m);font-size:13px;letter-spacing:.06em;color:var(--grey)}
.prj .d{font-size:15px;color:var(--grey);line-height:1.5}
.prj .sys{margin-top:auto;padding-top:12px;border-top:1px solid var(--line);
  font-family:var(--m);font-size:13px;color:var(--brass-d);line-height:1.6}
.prj .area{display:inline-block;font-family:var(--h);font-weight:700;font-size:19px;color:var(--ink)}

/* ── развёрнутый кейс ───────────────────────────────────────────────────────
   Структура строк — заказчика: задача → что было сложно → что сделал ЛЕГИОН →
   результат. Подписи мелким моноширинным, содержание крупнее: читать нужно
   ответы, а не заголовки. */
.case{border:1px solid var(--line);border-radius:16px;overflow:hidden;background:#fff}
.case-ph{aspect-ratio:16/10;overflow:hidden;background:var(--sunk)}
@media(min-width:941px){.case{display:grid;grid-template-columns:1fr 1fr}.case-ph{aspect-ratio:auto;height:100%}}
.case-ph img{width:100%;height:100%;object-fit:cover}
.case-bd{padding:24px 20px}
@media(min-width:641px){.case-bd{padding:34px 32px}}
.case-bd h2,.case-bd .case-h{font-family:var(--h);font-weight:700;font-size:clamp(21px,5vw,30px);
  letter-spacing:-.022em;line-height:1.13}
.case-bd .meta{font-family:var(--m);font-size:13px;letter-spacing:.06em;color:var(--grey);margin-top:8px}
.case-bd .area{display:inline-block;font-family:var(--h);font-weight:700;font-size:22px;margin-top:12px}
/* Ссылка «дальше» вне силосных блоков: до 21.08 класс .more был описан только
   внутри .silo и .silo-flat, и в кейсе выглядел обычной ссылкой. Базовое правило
   ниже, точечные внутри силосов остаются и перебивают его по специфичности. */
.more{display:inline-block;font-size:14.5px;color:var(--brass-d);font-weight:600}
.case-rows{margin-top:20px;padding-top:18px;border-top:1px solid var(--line)}
.case-rows dt{font-family:var(--m);font-size:13px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--brass-d);margin-top:16px}
.case-rows dt:first-child{margin-top:0}
.case-rows dd{font-size:15.6px;line-height:1.55;color:var(--ink);margin-top:7px}
/* Кейс без фотографии объекта: схема держит собственную пропорцию 16/10, поэтому
   aspect-ratio с неё снимается — иначе на десктопе, где колонка тянется на всю
   высоту текста, схема обрезается по краям. */
.case-ph-scheme{background:var(--ink);display:flex;align-items:center}
.case-ph-scheme svg{display:block;width:100%;height:auto}
@media(min-width:941px){.case-ph-scheme{aspect-ratio:auto}}
.case-ph-mark{display:flex;align-items:center;justify-content:center;background:var(--ink)}
.case-ph-mark svg{width:56px;height:auto;opacity:.9}
/* Состав систем — тем же моноширинным, что и в карточке: кейс и плитка стоят
   рядом в одной секции и должны читаться как один формат. */
.case-sys{margin-top:20px;padding-top:14px;border-top:1px solid var(--line);
  font-family:var(--m);font-size:13px;color:var(--brass-d);line-height:1.6}

/* ── кадр с площадки рядом с описанием контура ──────────────────────────────
   Фотография вертикальная и небольшого разрешения (кадр из съёмки заказчика),
   поэтому ширина ограничена: растянутый на половину экрана кадр 464 px в ширину
   превращается в мыло. */
.crew{margin-top:16px;border:1px solid var(--line);border-radius:16px;overflow:hidden;background:#fff;
  display:grid;gap:0}
@media(min-width:761px){.crew{grid-template-columns:300px 1fr;align-items:stretch}}
/* Кроп смещён вниз: интересное в кадре — руки на трубе и форма компании, а по
   центру геометрического кадра приходится пустой потолок склада. */
.crew img{display:block;width:100%;height:100%;max-height:320px;object-fit:cover;
  object-position:50% 62%;background:var(--sunk)}
@media(min-width:761px){.crew img{max-height:360px}}
.crew figcaption{padding:24px 20px;align-self:center}
@media(min-width:641px){.crew figcaption{padding:30px 32px}}
.crew figcaption b{display:block;font-family:var(--h);font-weight:700;font-size:19px;letter-spacing:-.01em}
.crew figcaption p{margin-top:10px;font-size:15.4px;line-height:1.55;color:var(--grey)}

/* ── перечень объектов ── */
.obj-list{list-style:none;display:grid;gap:0}
@media(min-width:761px){.obj-list{grid-template-columns:1fr 1fr;column-gap:40px}}
.obj-list li{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  padding:15px 0;border-bottom:1px solid rgba(242,241,238,.14)}
/* Список рождался внутри тёмной секции, поэтому молочный заголовок и серая
   подпись были заданы как базовые. На светлой секции это давало ровно тот случай,
   который нельзя пропускать: молочный текст на молочном фоне, контраст 1:1 —
   пункт списка исчезал целиком. Базовые цвета теперь светлой темы, тёмная
   переопределяет их ниже. */
.obj-list b{font-family:var(--h);font-weight:600;font-size:16.5px;color:var(--ink)}
.obj-list span{font-family:var(--m);font-size:13px;letter-spacing:.06em;color:var(--grey);white-space:nowrap}
section.dark .obj-list b{color:var(--milk)}
section.dark .obj-list span{color:var(--grey-d)}
/* Модификатор для списков, где справа не аббревиатура, а пояснение фразой.
   Базовый .obj-list держит span в nowrap — он рассчитан на «АПС» и «СОУЭ, 1–5 тип».
   Длинная строка в нём растягивала страницу до 1135 px и давала горизонтальный
   скролл, которого на сайте быть не должно. Здесь строка переносится, а на
   телефоне пояснение уходит под заголовок. */
.obj-list.wide li{flex-direction:column;align-items:flex-start;gap:6px}
@media(min-width:761px){.obj-list.wide li{flex-direction:row;align-items:baseline;gap:20px}}
.obj-list.wide span{white-space:normal;font-family:var(--s);font-size:14.5px;letter-spacing:0;line-height:1.5}
@media(min-width:761px){.obj-list.wide span{text-align:right;max-width:56%}}

/* ── цифры ── */
/* Две колонки цифр — с 361 px. На 320 px (iPhone SE) вторая колонка вылезала
   за поле на 0,7 px: у элементов грида min-width:auto, и длинное слово внутри
   колонки не даёт ей ужаться. Лечится обоими способами сразу — одна колонка на
   узком экране и min-width:0 на ячейке. */
.nums{display:grid;grid-template-columns:1fr;gap:22px 18px}
.nums > div{min-width:0}
@media(min-width:361px){.nums{grid-template-columns:1fr 1fr;gap:26px 18px}}
@media(min-width:941px){.nums{grid-template-columns:repeat(4,1fr);gap:34px}}
.nums b{display:block;font-family:var(--h);font-size:clamp(30px,7.6vw,44px);font-weight:800;letter-spacing:-.03em}
.nums span{display:block;color:var(--grey-d);font-size:14.5px;margin-top:6px;line-height:1.45}

/* ── шаги ── */
.steps{display:grid;gap:0;margin-top:8px;border-top:1px solid var(--line)}
@media(min-width:761px){.steps{grid-template-columns:1fr 1fr;column-gap:36px}}
.step{display:grid;grid-template-columns:44px 1fr;gap:14px;align-items:baseline;
  padding:16px 0;border-bottom:1px solid var(--line)}
.step .n{font-family:var(--m);font-size:13px;color:var(--brass-d)}
/* На графите тёмная латунь даёт 3.4:1 — номера шагов и кикеры первого экрана
   там перекрашиваются в светлую. Правило общее: --brass-d живёт только на
   светлом фоне, --brass — только на тёмном. */
section.dark .step .n,.hero .step .n{color:var(--brass)}
.step p{font-size:16px;color:var(--ink)}

/* ── цифровой контур ── */
.dig{display:grid;gap:16px;margin-top:8px}
@media(min-width:761px){.dig{grid-template-columns:1fr 1fr;gap:18px}}
.dig-card{border:1px solid rgba(242,241,238,.14);border-radius:14px;padding:22px 20px;background:var(--ink2)}
@media(min-width:641px){.dig-card{padding:26px 28px}}
.dig-card h3{font-size:17.5px;margin-bottom:10px;color:var(--milk)}
.dig-card ul{list-style:none;display:grid;gap:9px;margin-top:12px}
.dig-card li{position:relative;padding-left:20px;font-size:15.3px;color:var(--grey-d);line-height:1.5}
.dig-card li::before{content:"";position:absolute;left:0;top:9px;width:8px;height:1.5px;background:var(--brass)}
.dig-st{font-family:var(--m);font-size:13px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--brass);display:block;margin-bottom:10px}

/* ── партнёрам ── */
.part{display:grid;gap:14px;margin-top:8px}
@media(min-width:761px){.part{grid-template-columns:1fr 1fr;gap:18px}}
.part-card{border:1px solid var(--line);border-radius:16px;background:#fff;padding:26px 22px}
@media(min-width:641px){.part-card{padding:32px 30px}}
.part-card h3{font-size:21px;margin-bottom:10px}
.part-card p{color:var(--grey);font-size:15.5px}
.part-card .dirs{font-family:var(--m);font-size:13px;color:var(--brass-d);margin-top:14px;line-height:1.8}

/* ── вопросы и ответы ───────────────────────────────────────────────────────
   Блок нужен людям и поиску одновременно: те же формулировки уходят в разметку
   FAQPage, поэтому текст ответа держим самодостаточным, без «см. выше». */
.faq{display:grid;gap:10px;margin-top:8px;max-width:900px}
.faq details{border:1px solid var(--line);border-radius:13px;background:#fff;overflow:hidden}
.faq summary{list-style:none;cursor:pointer;padding:18px 52px 18px 20px;position:relative;
  font-family:var(--h);font-weight:600;font-size:16.6px;line-height:1.4}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:22px;top:24px;width:9px;height:9px;
  border-right:2px solid var(--brass-d);border-bottom:2px solid var(--brass-d);
  transform:rotate(45deg);transition:transform .2s}
.faq details[open] summary::after{transform:rotate(225deg);top:27px}
.faq .a{padding:0 20px 20px;color:var(--grey);font-size:15.6px;line-height:1.6}
.faq .a a{color:var(--brass-d);font-weight:600}
@media(min-width:641px){.faq summary{padding:20px 56px 20px 26px;font-size:17.5px}.faq .a{padding:0 26px 24px}}

/* ── SEO-текст ── */
.txt{max-width:74ch}
.txt h3{font-size:20px;margin:26px 0 10px}
.txt p{color:var(--grey);font-size:16.2px;margin-bottom:12px;line-height:1.65}
.txt a{color:var(--brass-d);font-weight:600}
/* Приглушённый справочный блок: текст и ссылки на месте (поиск видит всё), убран
   только визуальный вес — иначе после премиальной подачи страница проваливается
   в «монтаж вентиляции Москва цена». Секция уже уходит фоном, поля меньше. */
/* ── статья блога ──────────────────────────────────────────────────────────
   Длинный текст живёт по другим правилам, чем блоки посадочной: колонка чтения
   ограничена по знакам, а не по пикселям, между смысловыми блоками — воздух,
   чтобы поисковый движок резал текст по границе мысли, а не посреди абзаца
   (ARTICLE_SKELETON_SPEC, чанкирование). */
.art{max-width:74ch}
.art > p{color:var(--grey);font-size:17px;line-height:1.7;margin-bottom:16px}
.art h2{font-size:clamp(23px,5.2vw,30px);letter-spacing:-.02em;margin:40px 0 12px}
.art h3{font-size:clamp(19px,4.2vw,22px);margin:28px 0 10px}
.art h2:first-child,.art h3:first-child{margin-top:0}
.art a{color:var(--brass-d);font-weight:600}
.art strong{color:var(--ink)}
.art ul,.art ol{margin:0 0 18px 0;padding-left:22px}
.art li{color:var(--grey);font-size:16.6px;line-height:1.62;margin-bottom:8px}
.art li::marker{color:var(--brass-d)}
/* Ключевые факты в начале: высокоплотный фактами блок — лучший кандидат на
   цитату в генеративной выдаче, поэтому он визуально выделен и стоит первым. */
.art .tldr{background:var(--sunk);border-left:2px solid var(--brass-d);border-radius:0 14px 14px 0;
  padding:20px 22px;margin:0 0 28px}
.art .tldr b{display:block;font-family:var(--m);font-size:13px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--brass-d);margin-bottom:12px}
.art .tldr ul{margin:0;padding-left:20px}
.art .tldr li{color:var(--ink);font-size:16.2px}
.art table{width:100%;border-collapse:collapse;font-size:15.6px;min-width:520px}
.art .tbl-wrap{margin:0 0 22px;overflow-x:auto}
/* ── Таблицы на телефоне: строка → карточка ────────────────────────────────
   Трёхколоночная таблица на 393 px рвёт каждое слово, а горизонтальную
   прокрутку внутри текста люди не замечают и не видят правую колонку.
   Поэтому базовое состояние (телефон) — карточки: первая ячейка становится
   заголовком, остальные — парами «подпись → значение», подпись берётся из
   шапки через data-th. С 761 px возвращается обычная таблица.
   Разметку проставляет фильтр вывода, поэтому паттерн работает и для таблиц
   из базы — статей блога. Эталон: _flot_standards/responsive_tables.php. */
table[data-cards]{display:block;width:100%;min-width:0;border:0;background:none}
table[data-cards] thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
table[data-cards] tbody{display:block}
table[data-cards] tr{display:block;background:#fff;border:1px solid var(--line);
  border-left:3px solid var(--brass-d);border-radius:14px;padding:14px 16px;margin:0 0 12px}
table[data-cards] td{display:grid;grid-template-columns:minmax(88px,38%) 1fr;gap:10px;
  align-items:baseline;padding:7px 0;border:0;font-size:15px;line-height:1.45;color:var(--grey)}
table[data-cards] td::before{content:attr(data-th);color:var(--grey);font-family:var(--m);
  font-size:13px;line-height:1.35;letter-spacing:.04em}
table[data-cards] td:first-child{display:block;font-family:var(--h);font-weight:700;font-size:17px;
  color:var(--ink);padding:0 0 10px;margin-bottom:8px;border-bottom:1px solid var(--line)}
table[data-cards] td:first-child::before{display:none}
table[data-cards] td + td{border-top:1px dashed var(--line)}
@media(min-width:761px){
  table[data-cards]{display:table;border-collapse:collapse}
  table[data-cards] thead{position:static;width:auto;height:auto;clip:auto}
  table[data-cards] tbody{display:table-row-group}
  table[data-cards] tr{display:table-row;background:none;border:0;border-left:0;border-radius:0;padding:0;margin:0}
  table[data-cards] td{display:table-cell;padding:12px 14px;border-bottom:1px solid var(--line);font-size:15.6px}
  table[data-cards] td::before{display:none}
  table[data-cards] td:first-child{display:table-cell;font-family:var(--s);font-weight:400;font-size:15.6px;
    color:var(--grey);padding:12px 14px;margin:0;border-bottom:1px solid var(--line)}
  table[data-cards] td + td{border-top:0}
}
.art th{text-align:left;font-family:var(--m);font-size:13px;letter-spacing:.06em;color:var(--grey);
  font-weight:400;padding:12px 14px;border-bottom:1px solid var(--line);background:var(--sunk)}
.art td{padding:12px 14px;border-bottom:1px solid var(--line);color:var(--grey);vertical-align:top}
.art tr:last-child td{border-bottom:0}
.art .note{background:var(--brass-soft);border-radius:14px;padding:18px 20px;margin:0 0 22px}
.art .note b{display:block;margin-bottom:6px}
.art .note p{color:var(--grey);font-size:16px;line-height:1.6;margin:0}
.art figure.infogr{margin:26px 0}
.art .faq{margin-top:14px}
.art-meta{margin-top:14px;font-family:var(--m);font-size:13px;letter-spacing:.04em;color:var(--grey)}
@media(min-width:941px){.art{max-width:74ch}}

.txt-quiet{background:var(--sunk);padding-top:40px;padding-bottom:40px}
@media(min-width:641px){.txt-quiet{padding-top:56px;padding-bottom:56px}}
.txt-quiet .kicker{color:var(--grey)}
.txt-quiet h2{font-family:var(--h);font-size:20px;font-weight:700;margin:10px 0 16px}
@media(min-width:641px){.txt-quiet h2{font-size:22px}}
.txt-quiet h3{font-size:17px;margin:22px 0 8px}
.txt-quiet p{font-size:15.2px;line-height:1.62;margin-bottom:10px}
/* На подложке #E4E2DD латунь даёт 4.0:1 — ниже AA для мелкого текста. Поэтому
   здесь ссылка графитовая, а латунь работает подчёркиванием: акцент виден,
   контраст самого текста 13.6:1. */
.txt-quiet .txt a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--brass-d);
  text-underline-offset:3px}

/* ── компактная карта разделов ──────────────────────────────────────────────
   Раньше это была витрина из пяти карточек в середине главной — «Что мы делаем
   на объекте». Заказчик 15.08 попросил снять её как дубль «Шести контуров»:
   «оставить Шесть контуров как главный брендовый блок, а Направления работ
   либо убрать совсем, либо максимально сжать и использовать как SEO-навигацию
   ближе к низу». Взят второй вариант, и это не формальность: витрина —
   единственное место, откуда главная ссылается на тридцать страниц услуг.
   Убрать её целиком значило бы оборвать им передачу веса с самой сильной
   страницы сайта ровно перед тем, как поиск начнёт их обходить. */
.silo-flat{display:grid;gap:24px;margin-top:28px;padding-top:26px;border-top:1px solid var(--line)}
@media(min-width:641px){.silo-flat{grid-template-columns:1fr 1fr;gap:26px 34px}}
@media(min-width:941px){.silo-flat{grid-template-columns:repeat(3,1fr)}}
/* Колонка текста на странице объекта уже общей: гейт меры считает знаки как
   ширина/(кегль×0,5), и 74ch при 16,2px давали 98 знаков при пороге 95.
   66ch — та же колонка, но внутри нормы читаемости. */
.case-txt{max-width:66ch}

/* Абзацы внутри плоского силоса — на ширину колонки текста, а не на всю
   ширину секции: без этого строка на десктопе доходила до 98 знаков при
   норме читаемости около 75. Раньше в этом блоке лежали только списки
   ссылок, поэтому ограничения не было. */
.silo-flat p{max-width:66ch;color:var(--grey);font-size:16.2px;line-height:1.65;margin-bottom:16px}
.silo-flat h3{font-family:var(--h);font-size:15.5px;font-weight:600;margin-bottom:11px;
  padding-bottom:10px;border-bottom:1px solid var(--line)}
.silo-flat ul{list-style:none;display:grid;gap:3px}
.silo-flat li a{display:block;font-size:14.6px;color:var(--grey);line-height:1.4;padding:2px 0}
.silo-flat li a:hover{color:var(--ink)}
.silo-flat .more{display:inline-block;margin-top:9px;font-size:13.6px;color:var(--brass-d);font-weight:600}
/* Один блок на всю ширину (перелинковка внизу страницы услуги): ссылки идут
   колонками, иначе восемь строк в одну колонку растягивают подвал страницы. */
.silo-flat.one{grid-template-columns:1fr}
@media(min-width:641px){.silo-flat.one ul{grid-template-columns:1fr 1fr;column-gap:34px}}
@media(min-width:941px){.silo-flat.one ul{grid-template-columns:repeat(3,1fr)}}

/* ── хлебные крошки ── */
.crumbs{font-size:13.5px;color:var(--grey);padding:16px 0 0;display:flex;flex-wrap:wrap;gap:6px}
/* Тач-цель крошек. Гейт page_ui_lint давал 22 px на телефоне при норме 44:
   ссылка занимала ровно высоту строки. Увеличиваем вертикальные отступы самой
   ссылки, а не кегль — визуально крошки те же, палец попадает. */
.crumbs a{color:var(--grey);display:inline-block;padding:11px 0;margin:-11px 0}
.crumbs a:hover{color:var(--brass-d)}
.crumbs span{color:var(--ink)}
/* Разделитель крошек — цветом текста, а не линии: var(--line) на молочном даёт
   1.3:1, то есть палочка между звеньями практически не видна. */
.crumbs i{font-style:normal;color:var(--grey)}

/* ── шапка внутренней страницы ── */
.pg-head{padding-top:26px;border-top:0}
@media(min-width:641px){.pg-head{padding-top:34px}}
.pg-head h1{font-size:clamp(28px,7vw,50px);margin-top:14px;letter-spacing:-.028em}
.pg-head .lead{margin-top:18px}

/* ── блок основателя ────────────────────────────────────────────────────────
   Фотографии пока нет, поэтому доверие держит типографика: цитата крупная, имя
   и должность — подписью под ней. Заказчик просил «не огромный личный бренд на
   полстраницы, а нормальное человеческое лицо компании», отсюда сдержанность. */
.founder{border-left:2px solid var(--brass-d);padding-left:22px;max-width:56ch}
@media(min-width:641px){.founder{padding-left:34px}}
.founder-q p{font-family:var(--h);font-weight:600;line-height:1.34;letter-spacing:-.015em;
  font-size:clamp(19px,4.6vw,28px);color:var(--ink)}
.founder-who{margin-top:22px}
.founder-who b{display:block;font-family:var(--h);font-size:17px}
.founder-who span{display:block;font-family:var(--m);font-size:13px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--brass-d);margin-top:7px}

/* ── страница в работе ──────────────────────────────────────────────────────
   ВАЖНО: у .stub только вертикальные отступы. Узел в разметке — <div class="wrap stub">,
   и shorthand `padding:38px 0 56px` обнулял боковые 20 px, унаследованные от .wrap:
   на телефоне заголовок и текст ложились вплотную к краю экрана. Заказчик заметил
   это первым (14.08, «текст слева совсем без отступа»). Любой класс, который живёт
   на одном узле с .wrap, задаёт padding только по вертикали. */
.stub{padding-top:38px;padding-bottom:56px}
@media(min-width:641px){.stub{padding-top:52px;padding-bottom:88px}}
.stub h1{font-size:clamp(28px,7vw,46px);margin-top:16px}
.stub .lead{margin-top:18px}
.stub-note{margin-top:26px;border:1px solid var(--line);border-radius:14px;background:#fff;padding:22px 20px}
@media(min-width:641px){.stub-note{padding:26px 28px}}
.stub-note b{display:block;font-family:var(--h);font-size:17px;margin-bottom:8px}
.stub-note p{color:var(--grey);font-size:15.5px}
.stub-links{margin-top:34px}
.stub-links h2{font-size:19px;margin-bottom:14px}
.stub-links ul{list-style:none;display:grid;gap:2px}
.stub-links li a{display:block;padding:10px 0;border-bottom:1px solid var(--line);font-size:16px}
.stub-links li a:hover{color:var(--brass-d)}

/* ── страница услуги ────────────────────────────────────────────────────────
   Три класса, которые повторяются на каждой странице услуги: строка фактов под
   лидом, регламент работ по периодичности и разбор стоимости. Заведены как общие,
   а не «под обслуживание АПС»: страниц услуг в ядре сорок, и каждая собирается
   этим же набором. */

/* Факты под первым экраном: чем подтверждена услуга. */
.svc-facts{display:grid;gap:18px;margin-top:30px;padding-top:24px;border-top:1px solid var(--line)}
@media(min-width:761px){.svc-facts{grid-template-columns:repeat(3,1fr);gap:28px}}
.svc-facts b{display:block;font-family:var(--h);font-size:17px;font-weight:700;letter-spacing:-.01em}
.svc-facts span{display:block;color:var(--grey);font-size:14.6px;margin-top:6px;line-height:1.45}
/* Плитка фактов в тёмной секции: подпись серым #5E6166 на графите даёт 2.83:1
   (поймал contrast_lint на посадочной странице из кабинета). Как и с .price-fx,
   .prj, .reg-i — цвет объявляем там же, где фон. */
section.dark .svc-facts b{color:var(--milk)}
section.dark .svc-facts span{color:var(--grey-d)}

/* Якорная навигация по суб-интентам. Человек с коммерческим запросом читает не
   сверху вниз, а идёт в свой вопрос: «что входит», «сколько стоит», «документы».
   Строкой с переносом, а не горизонтальной прокруткой — на телефоне скрытые
   вправо пункты просто не находят. */
.svc-nav{display:flex;flex-wrap:wrap;gap:8px;margin-top:26px}
.svc-nav a{display:inline-flex;align-items:center;min-height:40px;padding:8px 15px;
  border:1px solid var(--line);border-radius:999px;background:#fff;
  font-size:14.6px;color:var(--grey);line-height:1.2}
.svc-nav a:hover{border-color:var(--brass-d);color:var(--ink)}

/* Инфографика. По канону сети SVG — носитель логики и цифры, а не украшение:
   inline, self-contained, system-ui, без внешних ссылок и шрифтов.
   ⚠️ Ширина ограничена намеренно. Кегли внутри viewBox крупные (17–20 единиц при
   ширине 520), чтобы на экране 393 px подпись давала реальные ~13 px — порог
   читаемости из спеки. Без max-width на десктопе тот же текст раздувался бы до
   40 px и блок читался как плакат. */
.infogr{margin:26px auto 0;max-width:620px}
.infogr svg{display:block;border-radius:14px}
.infogr figcaption{margin-top:12px;font-size:14.6px;line-height:1.5;color:var(--grey);
  padding-left:14px;border-left:2px solid var(--brass-d)}
section.dark .infogr figcaption{color:var(--grey-d);border-left-color:var(--brass)}
@media(min-width:941px){.infogr{margin-top:34px}}

/* Рекомендательные письма: скан + пояснение. Документ показываем настоящий,
   открывается в полный размер — как лицензии на странице «О компании». */
.rec{display:grid;gap:18px;margin-top:26px;padding-top:26px;border-top:1px solid var(--line);
  align-items:start}
@media(min-width:641px){.rec{grid-template-columns:170px 1fr;gap:26px}}
.rec img{width:100%;max-width:220px;border:1px solid var(--line);border-radius:10px}
.rec b{display:block;font-family:var(--h);font-size:17px;margin-bottom:8px}
.rec p{color:var(--grey);font-size:15.3px;line-height:1.55}
.rec p a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--brass-d);
  text-underline-offset:3px}

/* Регламент: период работ + состав. Заказчик сравнивает подрядчиков именно по
   этой паре, поэтому период набран моноширинным и вынесен над названием. */
.reg{display:grid;gap:14px;margin-top:8px}
@media(min-width:761px){.reg{grid-template-columns:1fr 1fr;gap:18px}}
.reg-i{border:1px solid var(--line);border-radius:14px;background:#fff;padding:22px 20px}
@media(min-width:641px){.reg-i{padding:26px 26px}}
.reg-h{padding-bottom:14px;margin-bottom:14px;border-bottom:1px solid var(--line)}
.reg-p{display:block;font-family:var(--m);font-size:13px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--brass-d);margin-bottom:9px}
.reg-i h3{font-size:18px}
.reg-i ul{list-style:none;display:grid;gap:10px}
.reg-i li{position:relative;padding-left:20px;font-size:15.3px;color:var(--grey);line-height:1.5}
.reg-i li::before{content:"";position:absolute;left:0;top:9px;width:9px;height:1.5px;background:var(--brass-d)}
/* Карточка реестра в тёмной секции: фон карточки белый всегда, а текст до
   19.08 наследовал section.dark p — #A7ABB2 на белом, 2.3:1 (поймал
   contrast_lint на /kontakty/). Тот же случай, что и с .prj: цвет объявляем
   там же, где фон. */
section.dark .reg-i{color:var(--ink)}
section.dark .reg-i h3{color:var(--ink)}
section.dark .reg-i p,section.dark .reg-i li{color:var(--grey)}

/* Стоимость: цифра слева, факторы справа. Цифра — не обещание, а точка отсчёта,
   поэтому оговорка про обследование стоит внутри того же блока, а не сноской. */
.price{display:grid;gap:22px;margin-top:8px}
@media(min-width:941px){.price{grid-template-columns:.8fr 1.2fr;gap:44px;align-items:start}}
.price-fig{border-left:2px solid var(--brass-d);padding-left:20px}
@media(min-width:641px){.price-fig{padding-left:26px}}
.price-fig b{display:block;font-family:var(--h);font-size:clamp(32px,8vw,44px);font-weight:800;letter-spacing:-.03em}
.price-fig > span{display:block;font-family:var(--m);font-size:13px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--brass-d);margin-top:8px}
.price-fig p{color:var(--grey);font-size:15.3px;line-height:1.55;margin-top:16px}
.price-fx{list-style:none;display:grid;gap:0;border-top:1px solid var(--line)}
.price-fx li{padding:14px 0;border-bottom:1px solid var(--line);font-size:15.3px;color:var(--grey);line-height:1.5}
.price-fx b{font-family:var(--h);font-weight:600;color:var(--ink)}
/* Блок стоимости в тёмной секции. До 19.08 классы .price-fx были рассчитаны
   только на светлый фон: графитовый текст на графите давал 1:1, а серый — 2.83:1
   (поймал contrast_lint на странице огнезащитной обработки). Токены на тёмном
   объявляем сразу все, а не только цвет текста — иначе следующая страница
   повторит ошибку. */
section.dark .price-fx{border-top-color:rgba(242,241,238,.16)}
section.dark .price-fx li{color:var(--grey-d);border-bottom-color:rgba(242,241,238,.16)}
section.dark .price-fx b{color:var(--milk)}
section.dark .price-fig{border-left-color:var(--brass)}
section.dark .price-fig p{color:var(--grey-d)}

/* ── форма ── */
.cta-grid{display:grid;gap:30px}
@media(min-width:941px){.cta-grid{grid-template-columns:1fr 1.05fr;gap:56px;align-items:start}}
.cta-list{list-style:none;display:grid;gap:13px;margin-top:26px}
.cta-list li{position:relative;padding-left:26px;color:var(--grey-d);font-size:15.6px;line-height:1.5}
.cta-list li::before{content:"";position:absolute;left:0;top:7px;width:12px;height:7px;
  border-left:2px solid var(--brass);border-bottom:2px solid var(--brass);transform:rotate(-45deg)}
form{background:var(--ink2);border:1px solid rgba(242,241,238,.13);border-radius:16px;padding:22px 20px}
@media(min-width:641px){form{padding:30px 30px}}
.f-row{display:grid;gap:12px}
@media(min-width:601px){.f-row.two{grid-template-columns:1fr 1fr}}
.fld{display:block;margin-top:12px}
.fld > span{display:block;font-size:13px;color:var(--grey-d);margin-bottom:6px}
input,textarea,select{width:100%;padding:13px 15px;border-radius:10px;background:rgba(242,241,238,.05);
  border:1px solid rgba(242,241,238,.18);color:var(--milk);font-family:var(--s);font-size:16px}
textarea{min-height:104px;resize:vertical}
select{appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' stroke='%23A7ABB2' stroke-width='1.6' fill='none' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 15px center;background-size:12px;padding-right:40px}
input::placeholder,textarea::placeholder{color:#7C8087}
input:focus,textarea:focus,select:focus{outline:none;border-color:var(--brass);
  box-shadow:0 0 0 3px rgba(169,149,114,.18)}
.file{margin-top:12px;border:1px dashed rgba(242,241,238,.26);border-radius:12px;padding:16px;
  display:flex;align-items:center;gap:12px;cursor:pointer}
.file:hover{border-color:var(--brass)}
.file svg{width:22px;height:22px;flex:none;color:var(--brass)}
.file b{display:block;font-family:var(--h);font-size:15px;font-weight:600;color:var(--milk)}
.file small{display:block;font-size:13px;color:var(--grey-d);margin-top:3px}
.file input{display:none}
.agree{display:flex;gap:11px;margin-top:18px;font-size:13.4px;color:var(--grey-d);line-height:1.5}
.agree input{width:19px;height:19px;flex:none;margin-top:2px;accent-color:var(--brass)}
.agree a{color:var(--milk);text-decoration:underline}
form .btn{margin-top:18px;width:100%}
.f-note{font-size:13.4px;color:var(--grey-d);margin-top:14px;text-align:center}
.f-note a{color:var(--milk)}
.msg{display:none;margin-top:14px;border-radius:10px;padding:13px 15px;font-size:15px}
.msg.ok{background:rgba(47,107,74,.16);color:#8FD3AE}
.msg.err{background:rgba(200,70,50,.16);color:#F0A99A}
.hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}

/* ── подвал с картой сайта ── */
/* ── подвал ───────────────────────────────────────────────────────────────
   Три яруса вместо прежних пяти: лента «кто мы + контакты», карта сайта,
   строка реквизитов. До пересборки подвал занимал 1042 px на десктопе и
   2242 px на телефоне — половину экрана листали мимо. */
footer{position:relative;background:var(--ink);color:var(--grey-d);padding:34px 0 22px;font-size:15px;overflow:hidden}
@media(min-width:641px){footer{padding:44px 0 26px}}
/* Фоновый кадр. Затемнение — на градиенте поверх картинки, а не на самой
   картинке: так одно изображение работает и здесь, и в других тёмных блоках,
   а контраст текста задаётся кодом и виден линтеру. */
/* На телефоне cover сильно приближает кадр, и диагонали кабельных трасс
   начинают читаться как засветка под текстом — базовое (узкое) состояние
   гасит сильнее, на широком экране кадр отпускаем. */
.ft-bg{position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:linear-gradient(180deg,rgba(23,25,28,.92) 0%,rgba(23,25,28,.88) 40%,rgba(23,25,28,.97) 100%),
    url(/assets/img/footer-bg.webp);
  background-size:cover;background-position:center 35%}
@media(min-width:641px){
  .ft-bg{background-image:linear-gradient(180deg,rgba(23,25,28,.86) 0%,rgba(23,25,28,.80) 40%,rgba(23,25,28,.95) 100%),
    url(/assets/img/footer-bg.webp)}
}
footer .wrap{position:relative;z-index:1}

/* верхняя лента */
.ft-top{display:grid;gap:24px;padding-bottom:26px;border-bottom:1px solid rgba(242,241,238,.12)}
@media(min-width:941px){.ft-top{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:40px;align-items:start}}
.ft-brand p{margin:12px 0 0;line-height:1.55;font-size:14.6px;max-width:46ch}
.ft-contacts{display:grid;gap:16px}
@media(min-width:521px){.ft-contacts{grid-template-columns:auto 1fr;gap:16px 28px}}
@media(min-width:941px){.ft-contacts{grid-template-columns:repeat(3,minmax(0,1fr));gap:24px}}
.ft-contacts > div{display:grid;gap:4px;align-content:start}
.ft-contacts a,.ft-contacts span:not(.ft-k){font-size:14.6px;line-height:1.5}
.ft-contacts a:hover{color:var(--milk)}
.ft-k{display:block;font-size:11.5px;letter-spacing:.12em;text-transform:uppercase;color:#7E838B;margin-bottom:2px}
.ft-strong{color:var(--milk);font-size:17px!important;font-weight:600;letter-spacing:-.01em}
/* Кнопка мессенджера в подвале. Латунь здесь — вариант --brass: подвал тёмный,
   на графите он даёт 6.06:1. Светлый --brass-d сюда ставить нельзя, он рассчитан
   на молочный фон (CONTRAST_STANDARD). */
.ft-msg{display:inline-block;margin-top:6px;color:var(--brass)!important;
  border-bottom:1px solid rgba(169,149,114,.45);padding-bottom:1px}
.ft-msg:hover{color:var(--milk)!important;border-bottom-color:rgba(242,241,238,.6)}

/* карта сайта */
.ft-map{display:grid;grid-template-columns:1fr 1fr;gap:20px 18px;padding:26px 0;
  border-bottom:1px solid rgba(242,241,238,.12)}
@media(min-width:761px){.ft-map{grid-template-columns:repeat(4,1fr)}}
/* Семь колонок ставим только там, где семь разделов помещаются одним рядом:
   иначе «Компания» уезжает во второй ряд одна и оставляет под картой пустую
   полосу в треть экрана. */
@media(min-width:1361px){.ft-map{grid-template-columns:repeat(7,1fr);gap:22px 18px}}
.ft-map .ft-h{color:var(--milk);font-size:14px;font-weight:600;margin-bottom:9px;line-height:1.3}
.ft-map .ft-h a{color:inherit}
.ft-map ul{list-style:none;display:grid;gap:5px}
.ft-map a{font-size:13.6px;line-height:1.38}
.ft-map a:hover{color:var(--milk)}
.ft-all{color:#8D9299}

/* нижняя строка */
.ft-legal{margin-top:18px;display:flex;flex-wrap:wrap;gap:8px 20px;justify-content:space-between;
  align-items:baseline;font-size:12.8px}
.ft-legal-r{display:flex;flex-wrap:wrap;gap:8px 18px;align-items:baseline}
.ft-legal a:hover{color:var(--milk)}
/* Подпись студии: самая последняя ссылка страницы и самая тихая. Кегль мельче
   реквизитов заказчика, цвет на грани различимости, без подчёркивания — она
   должна находиться, когда её ищут, и не попадаться на глаза, когда не ищут.
   На графите #5A5E65 давал 2.7:1, поэтому серый берём светлее. */
.ft-dev{font-size:12px;letter-spacing:.02em;color:var(--grey-d)}
.ft-dev:hover{color:var(--milk)}
/* Подвал — единственное место на сайте с полным лок-апом. Подпись под словом
   включается только там, где узел помещается в свою колонку целиком; ниже
   этого порога смысл дескриптора несёт строка описания рядом. */
footer .lockup{font-size:26px;color:var(--milk)}
footer .lockup-full .wm small{display:none}
@media(min-width:941px){
  footer .lockup{font-size:38px}
  footer .lockup-full .wm small{display:block}
}

/* Появление блоков — только под классом .js: без скрипта контент виден всегда. */
.js .rv{opacity:0;transform:translateY(14px)}
.js .rv.in{opacity:1;transform:none;transition:opacity .5s ease,transform .5s ease}
@media(prefers-reduced-motion:reduce){.js .rv{opacity:1;transform:none}}

/* ── Подбор решения (/podbor/) ──────────────────────────────────────────────
   Шаги прячутся только когда работает скрипт: класс .js-on ставит сам квиз
   после инициализации. Без JS страница остаётся полным списком вопросов —
   и для человека, и для поисковика.

   Цвет у каждого состояния объявлен вместе с фоном (CONTRAST_STANDARD): белая
   кнопка — графитовый текст, выбранная графитовая — молочный. Латунь берём в
   варианте --brass-d: подложки здесь светлые. */
.qz{max-width:760px}
.qz-bar{height:3px;background:var(--sunk);border-radius:2px;overflow:hidden}
.qz-bar i{display:block;height:100%;width:0;background:var(--brass-d);transition:width .35s ease}
.qz-step{font-family:var(--m);font-size:12.5px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--grey);margin-top:10px}
.qz-step b{color:var(--ink)}
.qz-q{margin-top:22px}
.qz.js-on .qz-q{display:none}
.qz.js-on .qz-q.on{display:block}
.qz-q h2{font-size:clamp(23px,5.4vw,34px);letter-spacing:-.02em;margin-bottom:4px}
.qz-hint{color:var(--grey);font-size:15px;margin-top:6px}
.qz-opts{display:grid;gap:10px;margin-top:18px}
.qz-opts button{display:block;width:100%;text-align:left;cursor:pointer;
  background:#fff;color:var(--ink);border:1px solid var(--line);border-radius:12px;
  padding:15px 17px;font:inherit;font-size:16.5px;line-height:1.35;
  transition:border-color .15s ease,background .15s ease}
.qz-opts button:hover{border-color:var(--brass-d)}
.qz-opts button.on{background:var(--ink);color:var(--milk);border-color:var(--ink)}
.qz-next{margin-top:16px}
.qz-back{margin-top:18px;background:none;border:0;padding:0;cursor:pointer;font:inherit;
  font-size:14.5px;color:var(--grey)}
.qz-back:hover{color:var(--ink)}
.qz-sum{background:var(--sunk);color:var(--ink);border-radius:12px;padding:18px 20px;margin:16px 0 20px}
.qz-sum b{display:block;font-family:var(--m);font-size:12.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--brass-d);margin-bottom:10px}
.qz-sum dt{font-size:13px;color:var(--grey);margin-top:9px}
.qz-sum dt:first-of-type{margin-top:0}
.qz-sum dd{font-size:16px;color:var(--ink);margin-top:2px}
@media(min-width:760px){
  .qz-opts{grid-template-columns:1fr 1fr}
}
/* Ссылка на подбор под кнопками первого экрана. Экран тёмный, поэтому латунь
   берём в варианте --brass (6.06:1 на графите), а не светлую --brass-d. */
.hero-alt{margin-top:16px;font-size:15px;color:var(--grey-d)}
.hero-alt a{color:var(--brass);border-bottom:1px solid rgba(169,149,114,.4);padding-bottom:1px}
.hero-alt a:hover{color:var(--milk);border-bottom-color:rgba(242,241,238,.6)}

/* ── Плавающая кнопка заявки ──────────────────────────────────────────────
   Одна на весь сайт, печатается из legion_footer(). Латунь --brass на графите:
   пара проверена по контрасту (6.06:1), на светлом фоне этот тон брать нельзя.
   Тач-цель 48 px по высоте — ниже 40 гейт не пропускает. Отступ снизу считает
   скрипт: пока на экране баннер ПДн, кнопка стоит над ним (--pdn). */
.cta-float{position:fixed;right:18px;bottom:calc(18px + var(--pdn,0px));z-index:900;
  display:inline-flex;align-items:center;gap:9px;height:48px;padding:0 20px;
  border-radius:999px;background:var(--brass);color:#17191C;
  font:600 15px/1 var(--s);text-decoration:none;letter-spacing:.1px;
  box-shadow:0 18px 40px -16px rgba(0,0,0,.55);
  opacity:0;visibility:hidden;transform:translateY(12px);
  transition:opacity .22s ease,transform .22s ease,visibility .22s}
.cta-float.on{opacity:1;visibility:visible;transform:none}
.cta-float:hover{background:#BCA680;color:#17191C}
.cta-float:focus-visible{outline:2px solid #17191C;outline-offset:3px}
.cta-float svg{flex:none}
@media(max-width:520px){
  /* На телефоне подпись остаётся: круглая кнопка со значком читается как чат
     поддержки, а это другое обещание. Ужимаем поля, не смысл. */
  .cta-float{right:12px;bottom:calc(12px + var(--pdn,0px));height:46px;padding:0 16px;font-size:14.5px}
}
@media(prefers-reduced-motion:reduce){
  .cta-float{transition:none}
}

/* ── Кадр в начале статьи ─────────────────────────────────────────────────
   Растровый визуал обязателен: инлайновые SVG-схемы в разметке страницы
   картинками не считаются, и материал уходит в соцсети и в отчёты без единого
   изображения. */
.art figure.hero-img{margin:0 0 28px}
.hero-img img{display:block;width:100%;height:auto;border-radius:14px}
.hero-img figcaption{margin-top:12px;font-size:14.6px;line-height:1.5;color:var(--grey);
  border-left:2px solid var(--line);padding-left:12px}
section.dark .hero-img figcaption{color:var(--grey-d);border-left-color:var(--brass)}

/* Страховка от наследования: карточка FAQ всегда белая, поэтому её текст задаётся
   явно и не берётся у тёмной секции. 22.08.2026 гео-страницы городов поставили FAQ
   внутрь section.dark — заголовки вопросов стали молочными на белом, 1.13:1.
   Цвет у блока со своим фоном объявляется вместе с фоном, а не наследуется. */
.faq summary{color:var(--ink)}
section.dark .faq summary{color:var(--ink)}
section.dark .faq .a{color:var(--grey)}

/* Поле у полосы уведомления об аналитике. Полосу рисует канон сети
   (assets/js/cookie-banner.js, копия _flot_standards) inline-стилем с боковым
   padding 18 px — на экране 393 px это поле 18 вместо 20 по мобильному стандарту,
   и гейт полей краснеет на каждой странице сайта. Правим у себя: канон общий на
   весь флот, менять его из клиентского проекта нельзя. !important — потому что
   у полосы стиль инлайновый. */
#eco-pdn{padding-left:20px!important;padding-right:20px!important}

/* ── Знаки каналов связи ──────────────────────────────────────────────────
   Фирменный знак приложения белым по его же фирменной заливке. Плашка,
   радиус и сетка знака одни на все каналы: ряд держится конструкцией,
   а не подгонкой на глаз. Порт решения с sk-ludi.
   Контраст белого глифа к фирменной заливке местами ниже 3:1 (Telegram 2,9:1)
   — это допустимо: WCAG 1.4.11 выводит фирменные знаки из-под требования,
   а смысл несёт aria-label, а не глиф. */
.soc{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.soc-i{display:flex;align-items:center;justify-content:center;width:34px;height:34px;
  border-radius:10px;overflow:hidden;flex:0 0 auto;
  transition:transform .16s ease, box-shadow .16s ease, filter .16s ease}
.soc-i svg{width:34px;height:34px;display:block}
.soc-max{background:linear-gradient(135deg,#4CCFFF 0%,#5533EE 62%,#9933DD 100%)}
.soc-tg {background:linear-gradient(180deg,#2AABEE 0%,#229ED9 100%)}
.soc-wa {background:#25D366}
.soc-yt {background:#FF0000}
.soc-vk {background:#0077FF}
.soc-i:hover{transform:translateY(-2px);filter:saturate(1.12)}
/* В подвале плашка стоит на графите: тонкая светлая обводка отделяет тёмные
   знаки от фона, иначе Telegram и ВКонтакте сливаются с подложкой. */
.soc-ft{margin-top:10px}
.soc-ft .soc-i{box-shadow:0 0 0 1px rgba(255,255,255,.16)}
.soc-ft .soc-i:hover{box-shadow:0 0 0 1px rgba(255,255,255,.3),0 6px 14px rgba(0,0,0,.4)}
