/* ============================================================================
   Атлас Модуль — фиксы Liqium поверх сборки libercode.
   Исходники SCSS сборки подрядчика недоступны, поэтому правки живут отдельным
   файлом и грузятся ПОСЛЕ *.min.css (см. header.php).

   Ревизия 12.08.2026 (сессия 20): блок «мобильное меню ≤499px» УДАЛЁН как
   устаревший. Он писался 05.08 под разметку без обёртки .header_menu_inner;
   11.08 подрядчик перелил шаблон с обёрткой, под которую и свёрстан
   header.min.css, поэтому собственный mobile-блок сборки снова работает,
   а наш перекрывающий блок с ним конфликтовал. Остальное — живое:
   без этого файла у /vakhtovye-poselki/ и юр-страниц нет стилей вообще.
   ========================================================================== */

/* «Пригласить в тендер» был мёртвым div без обработчика — теперь fancybox-ссылка
   на попап #invite_request (как остальные CTA); страховка вида для <a> */
.header_menu .header_menu_invite {
  display: block;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
}

/* ---------------------------------------------------------------------------
   Лендинг «Вахтовые посёлки» (/vakhtovye-poselki/), блоки по макету
   «Вахтовый поселок» (2129:2280 / 2782:3423): «всё для жизни и работы»
   и компактный призыв «решаем задачи». Типографика переиспользована из
   pd_complex_* и ma_tasks_* (product-detail.min.css), здесь — только сетка
   и два инфо-столбца.
   ------------------------------------------------------------------------- */

.vp_life_section .pd_complex_grid {
  grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: 40px;
}

.vp_life_info {
  display: flex;
  flex-direction: column;
  gap: 48px;
  padding-top: 10px;
}

.vp_life_info_title {
  text-transform: uppercase;
  color: #101820;
  font-family: RobotoFlex, Arial, sans-serif;
  font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
  font-weight: 550;
  font-size: 14px;
  line-height: 120%;
  margin-bottom: 14px;
}

.vp_life_info_text {
  text-transform: uppercase;
  color: #53565a;
  font-family: RobotoFlex, Arial, sans-serif;
  font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
  font-weight: 550;
  font-size: 12px;
  line-height: 150%;
}

.vp_tasks_section {
  margin-top: 20px;
}

@media (max-width: 1023px) {
  .vp_life_section .pd_complex_grid {
    grid-template-columns: 1fr;
    gap: 32px;
  }
}

/* ---------------------------------------------------------------------------
   Юридические страницы /privacy-policy/ и /personal-data/ (созданы 05.08.2026,
   тексты с живого оригинала atlas-modul.ru). Самодостаточная типографика —
   постраничных бандлов у этих страниц нет.
   ------------------------------------------------------------------------- */

.legal_section {
  padding: 0 0 100px;
}

/* Крошки. Дефект №24 (найден Антоном 05.08): у юр-страниц нет постраничного
   бандла, где живёт .breadcrumbs_wrap, поэтому ссылка «ГЛАВНАЯ» рисовалась
   дефолтным браузерным синим 16px. Правила перенесены 1:1 из бандлов сайта
   (сверено с faq.min.css / articles.min.css) и заскоплены на .legal_section. */
.legal_section .breadcrumbs_wrap {
  margin-bottom: max(3.5rem, min(1.78571rem + 2.67857vw, 5rem));
  padding-top: max(7.375rem, min(3.94643rem + 5.35714vw, 10.375rem));
}

.legal_section .breadcrumbs_wrap ul {
  display: flex;
  align-items: center;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.legal_section .breadcrumbs_wrap ul li {
  position: relative;
  padding-left: max(1rem, min(.0001rem + 1.5625vw, 1.875rem));
  letter-spacing: 0;
  text-transform: uppercase;
  color: #101820;
  font-family: RobotoFlex, Arial, sans-serif;
  font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 9;
  font-size: max(.4375rem, min(.294643rem + .223214vw, .5625rem));
  line-height: 120%;
}

.legal_section .breadcrumbs_wrap ul li:first-child {
  padding-left: 0;
}

.legal_section .breadcrumbs_wrap ul li:first-child:after {
  display: none;
}

.legal_section .breadcrumbs_wrap ul li:after {
  content: "—";
  position: absolute;
  top: 0;
  right: auto;
  left: max(.3125rem, min(.558036vw - .0446429rem, .625rem));
  color: #53565a;
}

.legal_section .breadcrumbs_wrap ul li a,
.legal_section .breadcrumbs_wrap ul li span {
  color: #53565a;
  text-decoration: none;
  transition: all .35s;
}

@media (hover: hover) {
  .legal_section .breadcrumbs_wrap ul li a:hover {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
  }
}

@media (max-width: 1023px) {
  .legal_section .breadcrumbs_wrap {
    margin-bottom: 32px;
    padding-top: 128px;
  }

  .legal_section .breadcrumbs_wrap ul {
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
    overflow-x: auto;
  }

  .legal_section .breadcrumbs_wrap ul::-webkit-scrollbar {
    display: none;
  }

  .legal_section .breadcrumbs_wrap ul li {
    white-space: nowrap;
    padding-left: 26px;
    font-size: 9px;
  }

  .legal_section .breadcrumbs_wrap ul li:after {
    left: 10px;
  }
}

@media (max-width: 499px) {
  .legal_section .breadcrumbs_wrap ul li {
    font-size: 6px;
  }
}

/* H1 — размеры канона сайта (.ss_top .ss_title), отступ сверху даёт крошка */
.legal_section h1 {
  margin: 0 0 36px;
  text-transform: uppercase;
  color: #101820;
  font-family: RobotoFlex, Arial, sans-serif;
  font-variation-settings: "wght" 805, "wdth" 151, "GRAD" 150, "opsz" 144;
  font-weight: 805;
  font-size: max(2.125rem, min(1.125rem + 1.5625vw, 3rem));
  line-height: 116%;
}

.legal_text {
  max-width: 920px;
  color: #101820;
  font-family: RobotoFlex, Arial, sans-serif;
  font-size: 16px;
  line-height: 155%;
}

.legal_text h2 {
  margin: 36px 0 16px;
  text-transform: uppercase;
  font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
  font-weight: 550;
  font-size: 20px;
  line-height: 120%;
}

.legal_text p {
  margin: 0 0 14px;
}

.legal_text ul {
  margin: 0 0 14px;
  padding-left: 22px;
  list-style: disc;
}

.legal_text li {
  margin-bottom: 6px;
}

.legal_text a {
  color: #c8102e;
  text-decoration: underline;
}

@media (max-width: 1023px) {
  .legal_section h1 {
    font-size: 26px;
  }
}

@media (max-width: 499px) {
  .legal_section {
    padding: 0 0 60px;
  }

  .legal_section h1 {
    font-size: 21px;
  }
}

/* ============================================================
   Правки 13.08.2026 (лист Юли от 13.08) — Liqium
   ============================================================ */

/* (4) Сообщение «ЗАПОЛНИТЕ ОБЯЗАТЕЛЬНЫЕ ПОЛЯ» — показывается ПОД кнопкой
   только после попытки отправки (правка в js/chunks/validation-IGSQDN4N.js),
   поэтому кнопка не прыгает.
   [50.1, лист Юли 20.08 13:03 п.6] зазор до кнопки 18px → 6px: замер на живом
   (главная, js-bottom-question-form, пустая отправка) показал 18px под кнопкой,
   Юля просит текст ближе к кнопке. */
.form-error-message {
  margin-top: 6px;
  line-height: 1.4;
}

/* (5) Ховеры: подчёркивание у ссылок-«ЧИТАТЬ» и подобных карточек.
   Было: подчёркивание включалось только при наведении на САМ текст
   (.t:hover), а красный цвет — при наведении на всю карточку (a:hover).
   Из-за этого на одних карточках подчёркивание появлялось, на других нет.
   Стало: подчёркивание включается от наведения на карточку целиком. */
.default-slider-section .swiper .swiper-wrapper .swiper-slide a:hover .link_content .technoblog_card_label .t,
.technoblog_card_link:hover .technoblog_card_label .t,
a:hover > .link_content .technoblog_card_label .t {
  text-decoration-color: #c8102e;
}

/* Было: text-decoration-color: currentcolor — цвет линии брался из
   текущего цвета текста, а текст перекрашивался в красный за 0.35s,
   поэтому линия сначала была тёмной и только потом краснела.
   Стало: и текст, и линия идут в один и тот же красный одновременно. */
.default-slider-section .swiper .swiper-wrapper .swiper-slide a .link_content .technoblog_card_label .t,
.technoblog_card_link .technoblog_card_label .t {
  transition: text-decoration-color .12s, color .12s;
}

/* (6) Шрифт пункта «ВАХТОВЫЕ ПОСЕЛКИ» в выпадающем меню.
   Было: подрядчик вывел этот пункт отдельной веткой шаблона —
   не <li><button> как три соседних пункта, а голая <a class="vahta">
   со своим инлайновым блоком стилей в footer.php (свой размер шрифта,
   color:black!important и нескомпилированный SCSS в line-height).
   Из-за этого пункт выбивался из меню.
   Стало: тот же кегль, цвет и начертание, что у соседних пунктов. */
.fs_menu_tabs_buttons ul .vahta {
  font-size: max(0.625rem, min(0.339286rem + 0.446429vw, 0.875rem));
  line-height: 114%;
  /* 13.08.2026 (сессия 25) — ГЛАВНОЕ: RobotoFlex — вариативный шрифт, и соседние
     пункты получают оси через селектор `.fs_menu_tabs_buttons ul li button/a`,
     который требует обёртку <li>. Этот пункт — голая <a> прямо в <ul>, поэтому
     ни одно родное правило до него не доходит и оси оставались `normal`:
     буквы рисовались уже и легче соседних. Правка 13.08 (сессия 23) выровняла
     кегль и цвет, но не оси — визуально шрифт по-прежнему «другой».
     Стало: те же четыре оси, что у соседей, и тот же запрет переноса. */
  font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
  white-space: nowrap;
  color: #101820;
  font-weight: 400;
  /* 18.08.2026 (сессия 40): !important у color СНЯТ. Он ставился 13.08, чтобы
     перебить инлайновый color:black из footer.php, но заодно глушил ЛЮБОЙ ховер —
     см. правило .vahta:hover ниже. Инлайновый стиль в разметке сейчас пустой
     (style=""), проверено в боевом HTML, поэтому !important больше не нужен. */
  /* 13.08.2026: пункт — голая <a>, а соседи <li><button>, поэтому не получал
     родного отступа списка и слипался с «Технологичными контейнерами». */
  margin-bottom: max(0.75rem, min(0.5rem + 0.446429vw, 1.0625rem));
}

/* vahta-mq-1023 — 13.08.2026 (сессия 25). На ширинах до 1023px соседние пункты
   уходят в 6px правилом `.fs_menu_tabs_buttons ul li button/a` внутри
   @media (max-width:1023px). Голая <a class="vahta"> его не матчит (нет <li>),
   поэтому на планшете и мобильном она оставалась 10px против 6px у соседей —
   это и читается как «шрифт другой». Повторяем те же значения для неё. */
@media (max-width: 1023px) {
  .fs_menu_tabs_buttons ul .vahta {
    --line-height: 7px;
    font-size: 6px;
  }
}

/* 13.08.2026 — правка клиента: благодарственное письмо открывается для чтения
   по клику на изображение или на имя автора (попап штатного механизма .fap/win_popup). */
.rdh_person_image a.rdh_letter_open {
    display: block;
    cursor: zoom-in;
}

.rdh_person_name a.rdh_letter_open {
    color: inherit;
    text-decoration: none;
    cursor: pointer;
}

.rdh_person_name a.rdh_letter_open:hover {
    color: #c8102e;
}

.rdh_letter_popup {
    width: min(92vw, 720px);
}

.rdh_letter_popup .popup_inner {
    width: 100%;
    max-width: none;
    padding: 40px;
}

.rdh_letter_popup_image {
    max-height: 82vh;
    overflow: auto;
}

.rdh_letter_popup_image img {
    display: block;
    width: auto;
    max-width: 100%;
    height: auto;
    margin: 0 auto;
}

@media (max-width: 767px) {
    .rdh_letter_popup .popup_inner {
        padding: 32px 16px 16px;
    }
}

/* 17.08.2026 (лист Юли 17.08, п.12) — подпись автора под сканом письма в модалке,
   по макету Figma 2067-3968: ФИО крупно, под ним должность/компания мелко.
   Типографика повторяет оси .rdh_person_name / .rdh_person_role со страницы отзыва,
   чтобы подпись в модалке и подпись на странице читались одинаково. */
/* 18.08.2026 (лист Юли 18.08, п.5) — выравнивание подписи по ЛЕВОМУ краю, не по центру.
   Было text-align:center с 17.08 — правка того же дня, центрирование не подтверждалось
   макетом, Юля попросила по левому. Скан письма (.rdh_letter_popup_image img) остаётся
   центрированным своим margin:0 auto — это отдельное правило, его не трогаем. */
.rdh_letter_popup_person {
    margin-top: 24px;
    text-align: left;
}

.rdh_letter_popup_name {
    letter-spacing: 0;
    text-transform: uppercase;
    color: #101820;
    font-family: RobotoFlex, Arial, sans-serif;
    font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
    font-size: max(.9375rem, min(.508929rem + .669643vw, 1.3125rem));
    line-height: 120%;
}

.rdh_letter_popup_role {
    margin-top: 8px;
    letter-spacing: 0;
    text-transform: uppercase;
    color: #101820;
    font-family: RobotoFlex, Arial, sans-serif;
    font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 9;
    font-size: max(.4375rem, min(.294643rem + .223214vw, .5625rem));
    line-height: max(.5rem, min(.285714rem + .334821vw, .6875rem));
}

@media (max-width: 1023px) {
    .rdh_letter_popup_person {
        margin-top: 16px;
    }

    .rdh_letter_popup_name {
        font-size: 16px;
        line-height: 19px;
    }

    .rdh_letter_popup_role {
        font-size: 8px;
        line-height: 10px;
    }
}

/* 17.08.2026 (лист Юли 17.08, п.5) — моб: прижато межстрочное у согласия с политикой.
   Причина: в бандле на ≤499px у .iagree label.css-label задаются font-size:8px и
   переменная --line-height:10px, но сам line-height остаётся от десктопного clamp
   (max(.5rem, min(.285714rem + .334821vw, .6875rem))) — на узком экране это ~8px,
   т.е. межстрочное равно кеглю и строки слипаются. Переменную никто не читает,
   поэтому задаём line-height явно. Класс общий для всех форм — правка чинит их разом. */
@media (max-width: 499px) {
    form .form_rows .iagree label.css-label {
        line-height: 13px;
    }
}

/* 17.08.2026 (лист Юли 17.08, п.8) — моб: на /faq/ не было отступа до подвала.
   В faq.min.css у .pd_calc_section на ≤1023px margin-bottom падает с ~80–100px
   (десктопный clamp) до 40px, и последняя секция почти упирается в футер.
   Правим по своему классу pd_calc_section--faq (проставлен в faq_page/template.php),
   а не по общему: тот же .pd_calc_section выводит project_calc_form.php на детальных
   страницах товаров и реализованных объектов — там отступ трогать не просили. */
@media (max-width: 1023px) {
    .pd_calc_section--faq {
        margin-bottom: 80px;
    }
}

/* 17.08.2026 (лист Юли 17.08, п.11б) — ФИО автора письма стало ссылкой на страницу отзыва.
   Оформление как у такой же ссылки в модалке отзыва (.rdh_person_name a.rdh_letter_open):
   цвет наследуется, подчёркивания нет, на ховере фирменный красный. */
.rod_review_person_link {
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    transition: color .12s;
}

.rod_review_person_link:hover {
    color: #c8102e;
}

/* 18.08.2026 (лист Юли 18.08, п.16) — ссылка подвала «Лицензии и сертификаты»
   уводила на блок ВЫШЕ нужного. Якорь /about/#licenses стоит верно — прямо на
   секции .ab_docs_section с заголовком «ИМЕЕМ ВСЕ ЛИЦЕНЗИИ И СЕРТИФИКАТЫ»
   (проверено разметкой: id="licenses" именно на ней, порядок секций
   hero → principles → production → quality → docs).

   ПРАВКА 18.08 вторая итерация (Юля: «сейчас все равно не на тот блок ведет»).
   Первый диагноз был НЕВЕРЕН: считали, что шапка фиксированная и перекрывает
   цель, и дали scroll-margin-top:120px. Померено в браузере на 1600×900:
   .header на десктопе — position:ABSOLUTE (fixed включается только в
   @media max-width:1023px), высота 113px. То есть при прокрутке шапка уезжает
   вверх и НИЧЕГО не перекрывает, а наши 120px становились лишним зазором:
   заголовок вставал на 120px от верха, и в кадр попадал хвост предыдущей
   секции «КОНТРОЛЬ КАЧЕСТВА» — ровно та жалоба, которую чинили.
   Замер: 120px → в верху кадра .ab_quality_section; 0px → .ab_docs_section;
   20px → .ab_docs_section с небольшим воздухом. Берём 20px.
   Мобильный оставляем 90px: там шапка действительно fixed и перекрывает.
   Класс: перед компенсацией фикс-шапки проверить, что она fixed НА ЭТОЙ
   ширине, — position может переключаться медиазапросом. */
#licenses {
    scroll-margin-top: 20px;
}

@media (max-width: 1023px) {
    #licenses {
        scroll-margin-top: 90px;
    }
}

/* 18.08.2026 (лист Юли 18.08, п.17) — в выпадающем меню «ПРОДУКЦИЯ» ховер на
   «Вахтовые поселки» (и соседних пунктах) срабатывал плохо и был чёрным.
   Две причины, обе в header.min.css: (1) .acc_body ul li a{color:inherit} —
   собственного :hover у пунктов меню нет вообще, цвет всегда наследуется от li
   (#101820); (2) ссылка остаётся inline, поэтому область наведения равна ширине
   текста, а пустота между строками (margin-bottom 16–20px) на ховер не отвечает.
   Делаем inline-block с вертикальным padding — зона наведения растёт по высоте,
   ширина остаётся по тексту (растягивать на всю ширину панели нельзя: .acc_body
   шириной calc(100% - 115px), полоса ушла бы до края). Отрицательный margin
   компенсирует padding, чтобы шаг списка по макету не поехал.
   Красный — фирменный #c8102e, тот же, что у логотипа и «Скачать презентацию». */
.acc_body ul li a {
    display: inline-block;
    padding: 8px 0;
    margin: -8px 0;
    transition: color .12s;
}

@media (hover: hover) {
    .acc_body ul li a:hover {
        color: #c8102e;
    }
}

/* Тем же ховером — «Модульные здания»: это li.acc_submenu, текст лежит прямо
   в li без ссылки, поэтому правило выше его не покрывает. */
.acc_body ul li.acc_submenu {
    transition: color .12s;
}

@media (hover: hover) {
    .acc_body ul li.acc_submenu:hover {
        color: #c8102e;
    }
}

/* Пункты внутри раскрытого подменю «Модульные здания» — тот же ховер. */
@media (hover: hover) {
    .acc_submenu_wrap .acc_submenu_list li a:hover {
        color: #c8102e;
    }
}

/* 18.08.2026, п.2 листа Юли — ВТОРАЯ ИТЕРАЦИЯ (сообщение 70711: «ховеры должны
   быть красные — сейчас черный (когда убираешь курсор)»).
   Первый заход 18.08 закрыл только ПОДПУНКТЫ внутри раскрытой «ПРОДУКЦИИ»
   (.acc_body ul li a) — они действительно краснеют. Но померено в браузере:
   у пунктов ВЕРХНЕГО уровня меню (ПРОДУКЦИЯ, ОБЪЕКТЫ, ТИПОВЫЕ РЕШЕНИЯ, ЗНАНИЯ,
   О НАС, КОНТАКТЫ) правил :hover нет НИ ОДНОГО — grep по всем таблицам стилей
   дал пустой список для .header_menu_item / .acc_head, цвет всегда #101820.
   Отсюда «сейчас чёрный»: курсор ушёл — и пункт, на который смотрели, чёрный,
   потому что он и не краснел. Красим верхний уровень тем же #c8102e. */
.header_menu_item,
.header_menu_item > a,
.header_menu_item .acc_head {
    transition: color .12s;
}

@media (hover: hover) {
    .header_menu_item > a:hover,
    .header_menu_item .acc_head:hover,
    .header_menu_item .acc_head:hover .acc_head_title {
        color: #c8102e;
    }

    /* стрелка аккордеона у «ПРОДУКЦИИ» — красится тем же цветом */
    .header_menu_item .acc_head:hover .arr {
        --icon-fill: #c8102e;
    }
}

/* 18.08.2026, п.4 листа Юли: «при наведении везде должна быть подчеркнутая
   линия». Объём уточнён у Юли (сообщение 70711): «да, делай одним правилом» —
   то есть общее правило на ссылки, а не перечисление мест.
   Подчёркивание берём анимируемое (text-decoration-color: transparent →
   currentColor), как уже сделано в шапке у «Скачать презентацию», — иначе
   при наведении дёргается базовая линия текста.
   ⛔ ИСКЛЮЧЕНИЯ, где подчёркивание было бы браком (проверено по разметке):
   логотипы и кнопки-плашки (у них своя заливка), карточки-картинки объектов
   и решений (ссылка оборачивает изображение целиком), стрелка «наверх»,
   пункты меню — у них свой красный ховер выше. */
/* 18.08.2026, сессия 40 — п.2 листа Юли, ТРЕТЬЯ ИТЕРАЦИЯ (11:40: «ховер в меню
   "Вахтовые поселки" не исправлен, наведения почти нет, также черный цвет»).
   🔴 Прошлые два захода красили НЕ ТОТ пункт. Померено по боевому HTML:
   «Вахтовые поселки» есть в разметке ТРИЖДЫ, и жалоба про экземпляр в БОКОВОМ
   фикс-меню (.fixed_submenu .fs_menu_tabs_buttons), а не в выпадающей ПРОДУКЦИИ
   (.acc_body), которую мы красили.
   Две причины, обе специфичны именно для этого пункта:
   (1) подрядчик вывел его голой <a class="vahta"> ПРЯМО в <ul>, без обёртки <li>,
       а все родные ховеры сборки написаны как `ul li a:hover` / `ul li button:hover`
       (есть в about/articles/contacts/... .min.css, цвет #c8102e) — без <li>
       ни одно из них до пункта не доходит, поэтому соседи краснеют, а он нет;
   (2) наша же правка 13.08 дала ему color:#101820 !important — она перебивала бы
       и правильный ховер тоже; !important снят выше.
   Зона наведения: пункт inline ⇒ реагирует только на ширину текста, межстрочное
   пустое место «не ловит» курсор — это и есть «наведения почти нет». Даём
   inline-block с вертикальным padding и компенсирующим margin, чтобы шаг списка
   по макету не поехал. Ширину не растягиваем — меню узкое, полоса ушла бы за край. */
.fs_menu_tabs_buttons ul .vahta {
    display: inline-block;
    padding: 6px 0;
    margin-top: -6px;
    transition: color .12s;
}

@media (hover: hover) {
    .fs_menu_tabs_buttons ul .vahta:hover {
        color: #c8102e;
    }
}

@media (hover: hover) {
    a:not([class]):hover,
    .footer_top_link:hover,
    .footer_menu_link:hover,
    .policy_link:hover,
    .personal_link:hover,
    .cls_pp:hover,
    .back_link:hover,
    .ab_docs_link:hover .t,
    .fixed_menu_link:hover,
    .all_info_link:hover .t {
        text-decoration: underline;
        text-decoration-thickness: 1px;
        text-underline-offset: 3px;
        text-decoration-skip-ink: none;
    }
}

/* 18.08.2026, сессия 41 — п.2 листа Юли, ЧЕТВЁРТАЯ ИТЕРАЦИЯ (11:58: «у меня
   ховер в меню так и не работает + модульные решения тоже должны красным
   выделяться при наведении»).
   🔴 Разбор: «Вахтовые поселки» третьим заходом починены верно — правило
   .fs_menu_tabs_buttons ul .vahta:hover отдаётся с боевого, каскад чист
   (наше (0,3,1) vs родное (0,4,3), но родное требует <li>, до голой <a>
   не доходит — конфликта нет). Жалоба относится к СОСЕДНЕМУ пункту: по
   координате курсора на скриншоте Юли он стоит на «МОДУЛЬНЫЕ ЗДАНИЯ»
   (первый пункт левой колонки), а «модульные решения» — её словесное
   название того же пункта, в разметке такой строки нет вообще.
   Причина, почему он чёрный, — НЕ поломка, а замысел подрядчика: пункт
   активной вкладки выводится как <li class="active"><button>, и в
   main.min.css для него лежит явное правило
   `… ul li.active button:hover{color:#101820}` (0,4,3) плюс `cursor:default`
   — активная вкладка намеренно не подсвечивается, потому что уже выбрана.
   Решение Антона 18.08: красить наравне с остальными («делаем, как просит
   Юля»). Перебиваем родное правило селектором той же структуры + класс
   .fixed_submenu_inner для перевеса специфичности (0,5,3) — без !important,
   чтобы не повторить грабли 13.08 (свой !important глушит будущий ховер).
   `cursor:default` снимаем тем же блоком: иначе пункт краснеет, но курсор
   остаётся стрелкой — читается как «подсветилось, а нажать нельзя».
   🔴 КЛАСС: скриншот жалобы читать по КООРДИНАТЕ КУРСОРА, а не по тексту
   жалобы. Три захода чинили пункт, который клиент называл словами, тогда как
   курсор на скриншотах стоял на соседнем. */
.fixed_submenu .fixed_submenu_inner .fixed_submenu_content .fs_menu_tabs_buttons ul li.active button,
.fixed_submenu .fixed_submenu_inner .fixed_submenu_content .fs_menu_buttons ul li.active button {
    cursor: pointer;
}

@media (hover: hover) {
    .fixed_submenu .fixed_submenu_inner .fixed_submenu_content .fs_menu_tabs_buttons ul li.active button:hover,
    .fixed_submenu .fixed_submenu_inner .fixed_submenu_content .fs_menu_buttons ul li.active button:hover {
        color: #c8102e;
    }
}

/* 18.08.2026, сессия 42 — Юля (chat4343, 12:56): «нужно еще добавить
   подчеркивание при наведении на Вахтовые поселки в меню».
   Проверено замером на боевом: три соседних пункта левой колонки ПРОДУКЦИИ
   при наведении дают textDecorationLine=underline, «Вахтовые поселки» — none.
   Юля права по факту, пункт выбивается из ряда.
   Механизм подрядчика (снят через CSS.getMatchedStylesForNode по CDP, не
   чтением файла): подчёркивание у соседей НЕ появляется на ховере, оно есть
   всегда — `…ul li button{text-decoration:underline; text-decoration-color:
   transparent; thickness:1px}`, а `…ul li button:hover` меняет ровно одно
   свойство `text-decoration-color: currentColor`. Линия «проявляется», текст
   не дёргается и высота строки не меняется — потому что линия зарезервирована
   заранее.
   Почему у .vahta не работало: базовая прозрачная линия у него ЕСТЬ (правило
   `.vahta` из сборки), но общее `a:hover{text-decoration:none}` при наведении
   сбрасывает decoration целиком — до currentColor дело не доходит. Родное
   `ul li button:hover` до голой <a> не достаёт (нет <li>), как и с цветом.
   Правка повторяет приём подрядчика 1:1: на ховере возвращаем линию и
   красим её currentColor — тем же красным, что и текст. Толщину задаём явно
   1px: у базового правила .vahta она приходит как `auto` (браузер считает
   сам), у соседей жёстко 1px — замер показал расхождение, без этой строки
   линия у пункта могла быть толще соседних. Отступ (3px) наследуется, он общий.
   Без !important: перевес даёт (0,3,1) против (0,1,1) у `a:hover`.
   🔴 КЛАСС: «подчёркивания нет» может означать не «правило не написано», а
   «линия есть, но прозрачная и её сбрасывает более общее a:hover». Проверять
   надо text-decoration-COLOR, а не только -line. */
@media (hover: hover) {
    .fs_menu_tabs_buttons ul .vahta:hover {
        text-decoration-line: underline;
        text-decoration-color: currentColor;
        text-decoration-thickness: 1px;
    }
}

/* ============================================================================
   19.08.2026, сессия 47 — лист Леонида Мусатова 19.08, корзина «наш брак».
   Все три правки ниже — по ЗАМЕРУ живого сайта реальным курсором с прокруткой
   колесом (у сайта своя скриптовая прокрутка: scrollIntoView и синтетические
   MouseEvent дают ЛОЖНЫЙ результат — элемент вне экрана, ховера нет).
   ============================================================================ */

/* [47.1] Пункт меню «чернеет перед покраснением».
   Замер по кадрам (.fixed_menu_link .t, наведение реальной мышью):
   0мс rgb(16,24,32) → 50мс rgb(50,23,35) → 100мс rgb(116,20,40) →
   150мс rgb(156,18,43) → 300мс rgb(200,16,46). Промежуточные кадры — грязный
   тёмно-бордовый, на экране читается как «сначала почернело, потом покраснело».
   Механизм: у .fixed_menu_link из сборки `transition:.35s` без имени свойства
   ⇒ transition-property:all. Красный приходит НЕ из CSS (правил :hover для
   этого меню нет вовсе — проверено обходом всех таблиц + CDP
   getMatchedStylesForNode), а от скрипта сборки: родителю .fixed_menu_item
   вешается класс is-active. Плавное смешивание тёмного с красным и даёт бордовый.
   Правка в приёме подрядчика: у соседних элементов переход всегда именной —
   `.fixed_menu_link .t{transition:text-decoration-color .35s}`,
   `.vahta{transition:color .35s}`. Сужаем `all` до тех свойств, которые
   действительно должны плавно меняться, и убираем цвет из анимации: цвет
   становится сразу целевым, без промежуточных оттенков.
   Без !important: (0,3,1) против (0,3,1) у родного правила, наш файл ниже
   по каскаду — перевес порядком подключения (custom-fixes.css грузится
   после main.min.css, проверено: метка версии CSS штатная, addCss).
   ⚠️ ПЕРВАЯ ИТЕРАЦИЯ НЕ СРАБОТАЛА, механизм дописан по приёмке: у подрядчика
   правило продублировано НА :hover — `.fixed_menu … .fixed_menu_link:hover
   {transition: all .35s}` (снято через CDP getMatchedStylesForNode на боевом
   ПОСЛЕ заливки: наш файл отдавался, правило матчилось, но ховер-правило
   подрядчика (0,4,1)+:hover перебивало наше (0,4,0) именно в момент наведения).
   ⇒ Перекрывать надо ОБА состояния, иначе покой чинится, а наведение нет.
   Класс: «правило отдаётся» ≠ «правило победило» — проверять надо тот момент,
   в котором жалоба, то есть под курсором. */
.fixed_menu .container .fixed_menu_inner .fixed_menu_link,
.fixed_menu .container .fixed_menu_inner .fixed_menu_link:hover {
    transition-property: background-color, opacity, transform;
}

/* [47.2] Карточки «Техноблог» на ГЛАВНОЙ не подсвечиваются при наведении.
   Клиент написал «2-я карточка без подчёркивания» — по замеру адрес другой и
   шире: на СТРАНИЦЕ /articles/ подсвечиваются ВСЕ 4 карточки (color
   rgb(200,16,46) + линия того же цвета), а на ГЛАВНОЙ не подсвечивается НИ
   ОДНА из 4. Проверено чисто: card.matches(':hover') === true, курсор внутри
   карточки, при этом заголовок остаётся rgb(16,24,32), decoration-line: none.
   Причина: правил наведения для .technoblog_card_* в CSS НЕТ ВООБЩЕ (обход
   всех таблиц по строке «technoblog» → 0 правил с :hover). Подрядчик написал
   их только для сетки .ss_grid (страница), а для карточек в слайдере на
   главной — нет. Класс B разбора недели: экземпляр починен один, не все.
   Приём копируем у рабочей карточки 1:1: линия есть ВСЕГДА, но прозрачная,
   на ховере проявляется через text-decoration-color; переход именной, только
   по цвету линии — текст не дёргается, высота строки не меняется.
   Цвет красный #c8102e — тот же, что у рабочих карточек (замер rgb(200,16,46)). */
.technoblog_card_link .technoblog_card_name {
    text-decoration: underline 1px transparent;
    text-decoration-skip-ink: none;
    text-underline-offset: 3px;
    transition: text-decoration-color .12s, color .12s;
}

/* ⚠️ ВТОРАЯ ИТЕРАЦИЯ по цвету (приёмка первой): подчёркивание встало, а цвет
   НЕТ. Механизм снят через CDP на боевом под курсором: наше правило матчилось
   (`matches('.technoblog_card_link:hover .technoblog_card_name') === true`),
   но цвет подрядчика приходит селектором-простынёй
   `.default-slider-section .swiper .swiper-wrapper .swiper-slide a .link_content
   .technoblog_card_name` — специфичность (0,6,1) против нашей (0,2,0), наш
   ховер проигрывает по силе, а не по порядку. Повторяем структуру родного
   селектора и добавляем :hover — (0,7,1), перевес честный, без !important
   (грабли 13.08: свой !important глушит будущие правки подрядчика). */
@media (hover: hover) {
    .default-slider-section .swiper .swiper-wrapper .swiper-slide a.technoblog_card_link:hover .link_content .technoblog_card_name {
        color: #c8102e;
        text-decoration-color: currentColor;
    }
}

/* [47.3] Текст ошибки формы вплотную к красной кнопке — «текст исчезает».
   Замер на боевом, форма «Остались вопросы?» (.js-bottom-question-form),
   отправка пустой формы: блок .form-error-message «ЗАПОЛНИТЕ ОБЯЗАТЕЛЬНЫЕ
   ПОЛЯ», цвет rgb(200,16,46), шрифт 9px, а кнопка «ОТПРАВИТЬ» — заливка
   ровно того же rgb(200,16,46). Зазор между низом текста и верхом кнопки:
   РОВНО 0 px — и на 1440×900, и на 390×844 (замер getBoundingClientRect).
   Красная надпись 9px, приклеенная к красной плашке, на экране сливается с
   кнопкой — это и есть жалоба «на красном фоне текст ошибки исчезает», и
   вторая жалоба «нужен отступ текста ошибки до кнопки»: обе про одно место.
   Правка: отделяем текст от кнопки (в макете зазора нет вовсе, ставим по
   сетке проекта) и поднимаем читаемость самой надписи — размер до 11px,
   как у прочих подписей формы. Цвет не трогаем: красный для ошибки —
   решение макета, спорить не о чем; проблема была в прилипании к плашке.
   ⚠️ ВТОРАЯ ИТЕРАЦИЯ по размеру шрифта (приёмка первой): отступ встал (зазор
   0 → 12 px на 1440 и 390), а размер остался 9px. Снято через CDP под ошибкой:
   у подрядчика размер задан `form .form_rows .form-error-message{font-size:9px}`
   — (0,3,0) против нашей (0,2,0). Повторяем структуру родного селектора. */
form .form_rows .form-error-message,
form .form-error-message {
    margin-bottom: 12px;
    font-size: 11px;
    line-height: 1.4;
}

/* ================= СЕССИЯ 49 (20.08) — лист Юли 09:42 =================
   РАБОТА НАД ОШИБКОЙ. Три пункта сегодняшнего листа (5, 6, 7) — это ПОВТОР
   вчерашних правок 47.2 и 47.3, вернувшийся с другого адреса. Причина одна
   и та же, класс B разбора недели: вчера правило писалось под ТОТ ЭКЗЕМПЛЯР,
   на котором замеряли (одна форма из шести, один блок карточек), а не под
   КЛАСС элемента. Сегодня правила пишутся по классу — на все формы сайта
   и на все блоки карточек сразу, с перечислением экземпляров в комментарии,
   чтобы следующая проверка шла по списку, а не по памяти. */

/* [49.1] Пункт 5 — «в объектах внизу стр во 2 карточке нет подчёркивания».
   Замер 20.08 (наведение реальной мышью, прокрутка колесом, matches(':hover')
   === true у всех): подчёркивания нет НИ У ОДНОЙ из четырёх карточек
   `.objects_card_link` — Юля увидела один экземпляр, дефект во всех.
   Корень: правило подрядчика
     .default-slider-section … .objects_card_label .t:hover{text-decoration-color:currentColor}
   срабатывает только при наведении ТОЧНО на слово «ОТКРЫТЬ» (.t), а клиент
   наводит на карточку целиком (картинка + название). Повторяем логику
   подрядчика 1:1 (тот же приём text-decoration-color + переход .35s),
   но триггером берём саму карточку — как у соседних блоков, где претензий нет.
   Затрагивает ВСЕ страницы с блоком объектов: продуктовые, типовые решения,
   детальные объектов, главная. */
.default-slider-section .swiper .swiper-wrapper .swiper-slide a.objects_card_link:hover .link_content .objects_card_label .t,
a.objects_card_link:hover .objects_card_label .t {
    text-decoration-color: currentColor;
    transition: text-decoration-color .12s;
}
.default-slider-section .swiper .swiper-wrapper .swiper-slide a.objects_card_link:hover .link_content .objects_card_name,
a.objects_card_link:hover .objects_card_name {
    color: #c8102e;
    transition: color .12s;
}

/* [49.2] Пункты 6+7 — формы: текст ошибки и поля на КРАСНОМ фоне не видны,
   отступ до кнопки.
   🔴 ВЧЕРА (47.3) ПОЧИНЕНА ОДНА ФОРМА ИЗ ШЕСТИ. Замер 20.08 по всем формам:
     js-bottom-question-form   белый  11px   ← вчерашняя правка, работает
     js-question-form          белый  9.86px ← не дошла
     js-invite-form            белый  9.86px ← не дошла
     js-planning-form          КРАСНЫЙ 16px  ← жалоба Юли
     js-project-calc-form      белый  16px   ← не дошла
     js-standard-solution-request белый 9.86px ← не дошла
   Причина: вчерашний селектор повторял структуру родного
   `form .form_rows .form-error-message`, но у половины форм разметка другая
   (нет .form_rows) — правило до них не доставало. Сегодня — по классу формы.

   Живая проверка красной формы (отправка пустой, /product/…/bolnitsy-i-fapy/):
   поля получают класс `parsley-error`, текст и рамка красятся в rgb(200,16,46)
   — ТОТ ЖЕ цвет, что фон секции. Красное на красном, поле «Телефон*» не читается.
   Правка по просьбе Юли: на инверсных (красных) секциях ошибка и поля — серым,
   отличимым от серого неактивного плейсхолдера. Берём #4a4a4a (темнее
   плейсхолдера подрядчика, контраст к красному фону достаточный),
   на белых формах красный цвет ошибки НЕ трогаем — там он читается. */

/* 49.2а — размер и отступ текста ошибки во ВСЕХ формах (не только с .form_rows) */
form .form-error-message,
form .form_rows .form-error-message,
.f1 .form-error-message {
    margin-bottom: 12px;
    font-size: 11px;
    line-height: 1.4;
}

/* 49.2б — формы на КРАСНОМ фоне (.inverse): ошибка и поля серым, не красным.

   ⚠️ ВТОРАЯ ИТЕРАЦИЯ, приёмка первой поймала осечку. Первая редакция
   (`form.inverse input.parsley-error`, два уровня) НЕ применилась: у подрядчика
   то же поле красит правило из пяти уровней
     .pd_form_section .f1 .form_rows .form_cols .input_field input.parsley-error
   — при споре побеждает более длинный селектор. Снято на живом сайте перебором
   всех таблиц стилей под ошибкой.
   🔴 ЭТО ТРЕТИЙ СЛУЧАЙ ЗА ДВА ДНЯ (47.1 ховер, 47.2 Техноблог, теперь формы):
   у подрядчика цвета заданы селекторами-простынями, короткое правило до них
   не достаёт. ПРАВИЛО ВЕТКИ: правя цвет на этом сайте, СНАЧАЛА снять
   победивший селектор подрядчика и повторить его структуру, а не писать
   короткий и надеяться.
   Ниже — структура родного селектора 1:1, плюс вариант без .pd_form_section
   (та же форма живёт и на других шаблонах: типовые решения, главная).

   ⚠️ ТРЕТЬЯ ИТЕРАЦИЯ — по ЦВЕТУ, поймана глазом на скриншоте приёмки.
   Вторая итерация применилась (замер показал rgb(74,74,74) вместо красного),
   но на экране стало ХУЖЕ: тёмно-серый #4a4a4a и красный фон rgb(200,16,46)
   имеют ОДИНАКОВУЮ яркость — 74 и 74. Цвет был выбран на глаз, без расчёта.
   Посчитано по контрасту (WCAG) к фону rgb(200,16,46):
     #4a4a4a → 1.51 (не читается)   #b0b0b0 → 2.71 (не читается)
     #d0d0d0 → 3.81 (на грани)      #e0e0e0 → 4.46 (читается) ✔
     белый   → 5.88, но это цвет ОБЫЧНОГО плейсхолдера подрядчика на этой
     секции — ошибка должна от него отличаться (просьба Юли дословно:
     «оттенок серого, чтобы он отличался от серого при отсутствии курсора»).
   Берём #e0e0e0: к фону 4.46 (читается), к белому 1.32 (отличим).
   [50.2, лист Юли 20.08 13:03 п.5] Юля: «нужен серый, сейчас почти белый».
   Затемняем на осознанный компромисс: #d0d0d0 — к красному фону 3.81
   (ниже строгой нормы 4.5 для мелкого текста, но читается; темнее нельзя —
   c8c8c8 уже 3.52), к белому 1.54 — заметно серее прежнего 1.32.
   КЛАСС: цвет на цветном фоне не выбирается на глаз — считается контраст,
   и приёмка идёт скриншотом, а не только замером computed-стиля. */

/* текст «ЗАПОЛНИТЕ ОБЯЗАТЕЛЬНЫЕ ПОЛЯ» */
.pd_form_section .f1.inverse .form_rows .form-error-message,
.pd_form_section .f1.inverse .form-error-message,
form.inverse .form_rows .form-error-message,
form.inverse .form-error-message,
.f1.inverse .form-error-message {
    color: #d0d0d0;
}

/* сами поля с ошибкой: текст, плейсхолдер, рамка */
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input.parsley-error,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea.parsley-error,
form.inverse .form_rows .form_cols .input_field input.parsley-error,
form.inverse .form_rows .form_cols .input_field textarea.parsley-error,
form.inverse input.parsley-error,
form.inverse textarea.parsley-error,
.f1.inverse input.parsley-error,
.f1.inverse textarea.parsley-error {
    color: #d0d0d0;
    border-color: #d0d0d0;
}
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input.parsley-error::placeholder,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea.parsley-error::placeholder,
form.inverse .form_rows .form_cols .input_field input.parsley-error::placeholder,
form.inverse input.parsley-error::placeholder,
form.inverse textarea.parsley-error::placeholder,
.f1.inverse input.parsley-error::placeholder,
.f1.inverse textarea.parsley-error::placeholder {
    color: #d0d0d0;
    opacity: 1;
}

/* [49.3] Пункт 1 — «на страницах объектов при открытии попапа благодарственного
   письма текст должен быть выровнен по одной линии с фото».
   Замер 20.08 на 1440 (`/realized-objects/vremennyy-ofis-prodazh1/`):
   фото письма left=124 (ширина 473), блоки текста left=40 — текст на 84px
   левее фото.
   ⚠️ ПЕРВАЯ ГИПОТЕЗА («текст прижат к краю попапа, двигать текст») ОКАЗАЛАСЬ
   НЕВЕРНОЙ — снята замером ДО заливки. Факт: обёртка `.rdh_letter_popup_image`
   и все текстовые блоки стоят ОДИНАКОВО (left=40, ширина=640); смещена САМА
   картинка — у `img` внутри обёртки стоит `margin: 0 83.5px`, то есть она
   отцентрована в своей колонке (родное поведение подрядчика для узких сканов).
   ⇒ Двигать надо картинку к левому краю колонки, а не текст. Текст уже стоит
   там, где просит Юля, — по левой границе попапа.
   Правка: снимаем центрирование у картинки письма. Ширину и высоту не трогаем
   (473×582 — натуральный размер, растягивать нельзя, рассыплется). */
#object_letter_popup .rdh_letter_popup_image img {
    margin-left: 0;
    margin-right: auto;
}

/* ================= СЕССИЯ 53 (20.08, 15:41) — замечание Юли по кейсам =================
   «Снова не на всех стр происходит подчеркивани карточки при ховере, например
    на этой стр в блоке реализованные объекты»
   → https://atlas.tw1.ru/realized-objects/shtab-stroitelstva-svyatogor/

   ЗАМЕР НА БОЕВОМ АДРЕСЕ (3 страницы кейсов × 4 карточки, наведение реальной
   мышью, matches(':hover') === true у всех 12): ПОДЧЁРКИВАНИЕ РАБОТАЕТ ВЕЗДЕ,
   включая 2-ю (vertical) карточку — линия становится rgb(200,16,46).
   Снимок в момент наведения: `dokaz-hover-2-krupno.png` (слово «ОТКРЫТЬ»
   красное и подчёркнутое). Правило подрядчика здесь написано корректно —
   в отличие от блока objects, который чинила [49.1].

   🔴 ЧТО ЮЛЯ РЕАЛЬНО ВИДИТ — РАЗНИЦА МЕЖДУ БЛОКАМИ, А НЕ ОТСУТСТВИЕ ПОДЧЁРКИВАНИЯ.
   На сайте ТРИ семейства карточек-слайдеров. У подрядчика НИ У ОДНОГО название
   карточки при наведении не краснеет (проверено машинно: правил `:hover` с
   `item_name`/`card_name` в его CSS ноль). Мы добавляли покраснение по ходу правок:
     technoblog_card  — [47.2] название краснеет
     objects_card     — [49.1] название краснеет
     ssd_similar_card — НЕ ДОБАВЛЯЛИ ← блок «РЕАЛИЗОВАННЫЕ ОБЪЕКТЫ» на кейсах
   ⇒ на продуктовых и типовых карточка при наведении «оживает» целиком
   (название краснеет + линия), а на странице кейса — только линия под словом
   «ОТКРЫТЬ». Отсюда «не на всех страницах»: Юля сравнивает с соседними блоками.
   Тот же класс ошибки, что [49.1] назвала своим именем: правку сделали на том
   экземпляре, где замеряли, а не на всех блоках одного вида.

   Правка доводит третий блок до вида двух соседних. Затрагивает 4 шаблона
   (проверено обходом components/): детальная кейса (два вида), типовые решения,
   отзывы — везде блок лежит внутри .default-slider-section. */
.default-slider-section .swiper .swiper-wrapper .swiper-slide a.ssd_similar_item_link:hover .link_content .ssd_similar_item_name,
a.ssd_similar_item_link:hover .ssd_similar_item_name {
    color: #c8102e;
    transition: color .12s;
}

/* [54.1] Ю.Л. 21.08 09:03 + скриншот: «При наведении нет подчеркивания также»,
   тот же адрес /realized-objects/shtab-stroitelstva-svyatogor/.

   🔴 РАЗБОР 53 БЫЛ НЕВЕРЕН — И ЗАМЕР 53 МЕРИЛ НЕ ТОТ ЭЛЕМЕНТ.
   Скрипт hover-v5.js брал text-decoration у `[class*=card_label] .t` — то есть
   у слова «ОТКРЫТЬ», а НЕ у названия карточки. У «ОТКРЫТЬ» подчёркивание стоит
   ВСЕГДА (замер v6: underline → underline, до и после наведения) и на ховере лишь
   перекрашивается — поэтому замер рапортовал «подчёркивание ЕСТЬ», хотя ховер его
   не создаёт. Запись 53 «название краснеет + линия» — неверна: линии не было ни
   в одном блоке.

   ЗАМЕР 21.08 (hover-v6.js, названия карточек, мышь фактически на карточке):
     кейс      ssd_similar_item_name  цвет 16,24,32 → 200,16,46 | линия none → none
     продукт   objects_card_name      цвет 16,24,32 → 200,16,46 | линия none → none
     главная   technoblog_card_name   цвет 16,24,32 → 200,16,46 | линия none → none
   Все три блока ведут себя ОДИНАКОВО ⇒ гипотеза «разница между блоками» закрыта:
   разницы больше нет, а жалоба осталась. Значит дело не в сравнении блоков.

   ЭТАЛОН — то, что Юля 18.08 приняла словами «сейчас всё работает» (пункт меню
   .fixed_menu_link, замер под курсором):
     text-decoration-line: none → UNDERLINE   + цвет 16,24,32 → 200,16,46
   То есть в принятом ею образце линия ПОЯВЛЯЕТСЯ. У карточек она не появляется —
   даётся только цвет. Юля всё это время просит у карточки ровно то, что уже есть
   в меню: и покраснение, и подчёркивание названия.

   Почему [47.2] не сработала: у technoblog линия задана (строки выше,
   `underline 1px transparent` + проявление через text-decoration-color), но
   родной селектор подрядчика (0,6,1) перебивает объявление на самом элементе —
   замер даёт none. Для objects/ssd_similar линию не задавали вовсе.

   Правка: подчёркивание названия при наведении ВСЕМ ТРЁМ семействам сразу, одним
   блоком — приём меню (появление линии), специфичность повторяет структуру родного
   селектора подрядчика, без !important. Линия держится прозрачной в покое, чтобы
   текст не дёргался и высота строки не менялась. */
a.technoblog_card_link .technoblog_card_name,
a.objects_card_link .objects_card_name,
a.ssd_similar_item_link .ssd_similar_item_name {
    text-decoration: underline 1px transparent;
    text-decoration-skip-ink: none;
    text-underline-offset: 3px;
    transition: text-decoration-color .12s, color .12s;
}

@media (hover: hover) {
    .default-slider-section .swiper .swiper-wrapper .swiper-slide a.technoblog_card_link:hover .link_content .technoblog_card_name,
    .default-slider-section .swiper .swiper-wrapper .swiper-slide a.objects_card_link:hover .link_content .objects_card_name,
    .default-slider-section .swiper .swiper-wrapper .swiper-slide a.ssd_similar_item_link:hover .link_content .ssd_similar_item_name,
    a.technoblog_card_link:hover .technoblog_card_name,
    a.objects_card_link:hover .objects_card_name,
    a.ssd_similar_item_link:hover .ssd_similar_item_name {
        color: #c8102e;
        text-decoration-color: #c8102e;
    }
}


/* ============================================================================
   [60] ЛИСТ ЛЕОНИДА МУСАТОВА 24.08 13:48/13:49 (TG «AtlasModul & Liqium»).
   Команда Антона: «делаем всё, что понятно, и всё, что просит Леонид,
   потом отдаём на проверку Юле».

   ⚠️ КОНФЛИКТ ТРЕБОВАНИЙ, зафиксирован до правки. Юля 21.08 семь кругов
   просила, чтобы при наведении на карточку краснело и подчёркивалось
   НАЗВАНИЕ (правка [54.1], принята ею 21.08 16:29 «Да, вроде все ок»).
   Леонид 24.08 просит обратное: «не должно быть ховера на самом названии
   статьи». Требования разведены по элементам: линия под словом «ОТКРЫТЬ»
   ОСТАЁТСЯ (её просит и Юля 24.08 09:39), ховер названия СНИМАЕТСЯ.
   ============================================================================ */

/* [60.1] Леонид п.1: «не должно быть ховера на самом названии статьи».
   ЗАМЕР 24.08 (zamer-60.js, живой стенд, реальная мышь, 1280x800 и 1440x900):
   у ВСЕХ 4 карточек Техноблога на главной название при наведении
   rgb(16,24,32) → rgb(200,16,46) и линия rgb(200,16,46) ⇒ жалоба подтверждена
   фактом, ховер названия есть.
   Заодно снят вопрос п.1 «подчёркивание только на первых двух карточках»:
   замер 4/4 на обеих ширинах — на текущей версии подсвечиваются ВСЕ ЧЕТЫРЕ,
   и название, и «ОТКРЫТЬ». Леонид смотрел версию до выкладки 21.08.

   Правка: у карточек ТЕХНОБЛОГА название при наведении не меняется —
   ни цвет, ни линия. Отменяем ровно наши блоки [47.2] и [54.1] в части
   technoblog_card_name, возвращая поведение подрядчика (у него ховера
   на названии не было вовсе).
   ⛔ objects_card_name и ssd_similar_item_name НЕ ТРОГАЕМ: Леонид говорит
   только про статьи Техноблога («не должно быть ховера на самом НАЗВАНИИ
   СТАТЬИ»), а карточки объектов и похожих решений — другой тип, по ним
   действует принятая Юлей правка. Правка по классу здесь была бы
   расширением требования, а не его исполнением.
   Специфичность повторяет структуру наших же правил (0,7,1), чтобы честно
   перекрыть их, а не глушить !important. */
@media (hover: hover) {
    .default-slider-section .swiper .swiper-wrapper .swiper-slide a.technoblog_card_link:hover .link_content .technoblog_card_name,
    a.technoblog_card_link:hover .technoblog_card_name {
        color: #101820;
        text-decoration-color: transparent;
    }
}

/* [61.2] РАСПРОСТРАНЕНИЕ [60.1] НА КАРТОЧКИ ОБЪЕКТОВ — ПО ПРЯМОЙ ПРОСЬБЕ Ю.Л.
   Возврат Юли 24.08 17:05 п.3 дословно: «В реализованных объектах должна
   подчеркиваться только ссылка открыть как на главной стр в техноблоге».
   ⚠️ Это ОТМЕНА её же правки [54.1] от 21.08 (там она семь кругов просила
   ховер НА НАЗВАНИИ и приняла его 21.08 16:29). Отменяю не по своему
   усмотрению, а по её новому письменному требованию — и фиксирую здесь,
   чтобы при следующем возврате было видно, чьё это решение и когда принято.
   Вчера [60.1] сознательно НЕ трогал ssd_similar_item_name: Леонид говорил
   только про статьи, расширять его требование на другой тип карточек было
   бы домыслом. Теперь расширение просит сама Юля ⇒ делаю.

   ЗАМЕР ДО ПРАВКИ (svyat-61.js, живой стенд, реальная мышь, 1280x800,
   /realized-objects/shtab-stroitelstva-svyatogor/, 8 карточек):
     название  rgb(200,16,46) + underline  ← Юля просит убрать
     ОТКРЫТЬ   rgb(200,16,46) + underline  ← остаётся
   Заодно снят п.2 её же списка («не подчёркивается во 2 карточке»):
   подчёркивание работает на ВСЕХ карточках, включая вторую — 8/8 при
   честном hover=true. По коду дефекта нет.

   Правка зеркалит [60.1]: у карточек объектов и похожих решений название
   при наведении не меняется, «ОТКРЫТЬ» продолжает краснеть и подчёркиваться.
   Специфичность повторяет структуру наших же правил [54.1] (0,7,1). */
@media (hover: hover) {
    .default-slider-section .swiper .swiper-wrapper .swiper-slide a.ssd_similar_item_link:hover .link_content .ssd_similar_item_name,
    a.ssd_similar_item_link:hover .ssd_similar_item_name {
        color: #101820;
        text-decoration-color: transparent;
    }
}

/* [60.2] Леонид «Главное меню»: «у ховеров основных пунктов главного меню
   подчёркивание появляется с большой задержкой».
   ЗАМЕР 24.08 по кадрам (.fixed_menu_link .t, наведение реальной мышью):
     0мс   линия прозрачная 0.03
     50мс  0.33
     100мс 0.62
     200мс 0.804
     300мс 0.914
     600мс 1.0 (полная яркость)
   ⇒ жалоба подтверждена числом: линия доезжает 600 мс, глазом это и есть
   «появляется с задержкой». Причина — наш же приём: линия существует всегда
   прозрачной и проявляется плавным переходом text-decoration-color .35s
   (взято у подрядчика, чтобы текст не дёргался).
   Правка: переход по цвету линии сокращается .35s → .12s. Ноль не ставим:
   мгновенное появление на этом шаблоне читается как «дёрнулось», а 120 мс
   ниже порога заметности задержки. Сам приём «прозрачная линия в покое»
   сохраняем — иначе поедет высота строки (грабля [47.2]). */
.fixed_menu .container .fixed_menu_inner .fixed_menu_link .t {
    transition: text-decoration-color .12s;
}

/* [60.3] Леонид «Продуктовые страницы» п.1: «Не исправлена проблема с формой
   на красном фоне: чек-бокс и текст исчезает, при попытке отправить форму
   не заполнив обязательные поля. Текст и чек-бокс в таком случае тоже
   должны становиться серыми, как в полях».
   ЗАМЕР 24.08 (форма .js-planning-form на /product/modulnye-zdaniya/bolnitsy-i-fapy/,
   отправка пустой формы):
     поля ввода   → rgb(208,208,208) светло-серые ✅ (наша правка [49.3] жива)
     подпись чек-бокса (label.iagree.parsley-error) → rgb(16,24,32) 🔴 ТЁМНАЯ
   ⇒ клиент прав дословно: поля исправлены, а текст согласия остался тёмным
   и на красном фоне не читается. Это НАШ недочёт того же класса B, что
   разобран 18.08: правку [49.3] применили к полям, но не к подписи согласия.

   Правка: при ошибке валидации подпись согласия и сама рамка чек-бокса
   получают тот же светло-серый #d0d0d0, что и поля. Цвет не на глаз:
   контраст #d0d0d0 к красному фону #c8102e = 3.81 (читается), к белому 1.32
   (отличим) — расчёт сессии 49, там же отвергнут #4a4a4a (1.51, сливается).
   ⚠️ ПЕРВАЯ РЕДАКЦИЯ БИЛА МИМО — механизм снят замером (probe-cb.js), а не
   предположением. Ошибка была в выборе класса: я взял `parsley-error`
   (он висит на внешнем контейнере .iagree), а текст согласия лежит во
   ВЛОЖЕННОМ `label.css-label`, и класс ошибки на нём другой — `iagree-error`.
   ФАКТ по замеру:
     покой:  label.css-label            → rgb(255,255,255) белый, читается
     ошибка: label.css-label.iagree-error → rgb(200,16,46)  = ЦВЕТ ФОНА ⇒ исчезает
   То есть подрядчик красит подпись согласия в тот же красный, что и фон
   секции. Внешний контейнер красить бесполезно: вложенный label перебивает
   цвет собственным правилом. Правка адресуется именно ему.

   Цвет #d0d0d0 — тот же, что у полей ввода при ошибке ([49.3]), клиент
   дословно просит «текст и чек-бокс тоже должны становиться серыми, как
   в полях». Контраст к красному фону 3.81 — читается (расчёт [49.3]).

   ⚠️ ВТОРАЯ РЕДАКЦИЯ ПО СИЛЕ ПРАВИЛА (приёмка первой: цвет не изменился).
   Механизм снят через CDP getMatchedStylesForNode на живой странице —
   какие правила реально борются за цвет этого узла:
     .pd_form_section .f1 .form_rows .iagree label.css-label.iagree-error
                                                → #c8102e  сила (0,5,1) ← побеждало
     .f1.inverse .iagree label.css-label.iagree-error
                                                → #d0d0d0  сила (0,4,1) ← моя, слабее
   Проигрыш ровно на один класс, а не по порядку подключения.
   Повторяем структуру родного селектора подрядчика и добавляем .inverse
   ⇒ (0,6,1), перевес честный, без !important (грабля 13.08: свой !important
   глушит будущие правки подрядчика). Тот же класс ошибки, что [47.2]
   и [54.1]: «правило отдаётся» ≠ «правило победило». */
.pd_form_section .f1.inverse .form_rows .iagree label.css-label.iagree-error,
.pd_form_section .f1.inverse .form_rows .iagree label.css-label.iagree-error a,
form.inverse .form_rows .iagree label.css-label.iagree-error,
form.inverse .form_rows .iagree label.css-label.iagree-error a {
    color: #d0d0d0;
}

/* рамка самого квадратика чек-бокса при ошибке — тем же серым */
.f1.inverse .iagree-error .checkbox_ui,
.iagree-error .checkbox_ui {
    color: #d0d0d0;
    border-color: #d0d0d0;
}

/* [61.1] ДОБОР К [60.3] — ТЕКСТ ПОЧИНИЛИ, КВАДРАТИК ГАЛОЧКИ НЕТ.
   Возврат Юли 24.08 17:05 п.1: «чек-бокс и текст исчезает… текст и чек-бокс
   в таком случае тоже должны становиться серыми, как в полях».
   ЗАМЕР 24.08 сессии 61 (fapy-61.js, отправка пустой формы .js-planning-form
   на /product/modulnye-zdaniya/bolnitsy-i-fapy/ — единственная страница,
   где форма реально стоит на красном, проверено обходом 10 адресов
   inverse-61.js: form.inverse есть ТОЛЬКО там):
     текст согласия  → rgb(208,208,208) ✅ [60.3] работает
     поля ввода      → rgb(208,208,208) ✅ [49.3] работает
     рамка галочки   → rgb(200,16,46)   🔴 = ЦВЕТ ФОНА ⇒ квадратик исчезает
   ⇒ клиент прав дословно, и это ровно НЕДОДЕЛАННАЯ половина [60.3]:
   вчерашняя правка адресовала текст, а квадратик остался красным.

   ПОЧЕМУ ПРЕЖНЕЕ ПРАВИЛО НЕ СРАБОТАЛО — снято через CDP
   getMatchedStylesForNode на живой странице (cb-61.js), не предположением.
   За рамку боролись:
     .pd_form_section .f1 .form_rows .iagree label.css-label.iagree-error
       .checkbox_ui                              → #c8102e  сила (0,7,1) ← побеждало
     .f1.inverse .iagree-error .checkbox_ui      → #d0d0d0  сила (0,4,0) ← моё, слабее
   Проигрыш в три класса. Тот же класс ошибки, что [60.3]б и [54.1]:
   «правило отдано» ≠ «правило победило».
   Правка: повторяем структуру родного селектора подрядчика и добавляем
   .inverse ⇒ (0,8,1), перевес честный. ⛔ Без !important осознанно
   (грабля 13.08: свой !important глушит будущие правки подрядчика).
   Цвет #d0d0d0 — тот же, что у полей и текста ([49.3]/[60.3]), клиент
   просит «как в полях». Формы на БЕЛОМ фоне не затронуты: селектор
   требует .inverse, а обход 10 страниц показал, что на белых страницах
   этого класса нет — регресс проверен forms-61.js. */
.pd_form_section .f1.inverse .form_rows .iagree label.css-label.iagree-error .checkbox_ui,
form.inverse .form_rows .iagree label.css-label.iagree-error .checkbox_ui {
    border-color: #d0d0d0;
    color: #d0d0d0;
}

/* [60.4] Леонид п.2 главной: «вторая карточка должна быть длиннее»
   (и «п.1 и 2 проверить и исправить во всех блоках этого типа»).

   🔴 ИСТОРИЯ, БЕЗ КОТОРОЙ ПРАВКА ЛОМАЕТ ПРИНЯТОЕ. Вторая карточка блока —
   родная «лесенка» подрядчика (a.vertical, картинка ~297px против ~187px
   у соседних). Правка [56.1] от 21.08 ВЫРОВНЯЛА её по соседям на окнах
   ниже 940px, потому что на ноутбуке (высота ~800) низ вытянутой карточки
   уезжал под закреплённое нижнее меню: слово «ОТКРЫТЬ» физически пряталось
   за плашкой, мышь ловили ссылки меню. Это и была жалоба Юли «правка уже
   4 раз не исправляется». Вернуть лесенку целиком = вернуть ту жалобу.

   ЗАМЕР 24.08 (geo-60.js, живой стенд, естественная прокрутка колесом):
     1280x800: верх нижнего меню 722, низ «ОТКРЫТЬ» 2-й карточки 661
               ⇒ свободный запас 61px (у соседних 81–101px)
     1440x900: запас 85px (у соседних 106–128px)
   Родная лесенка добавила бы ~110px ⇒ на 1280x800 «ОТКРЫТЬ» ушёл бы
   на 49px ПОД меню. Полный возврат исключён замером, а не мнением.

   Правка-компромисс: на невысоких окнах вторая карточка снова длиннее
   соседних, но ровно настолько, насколько позволяет запас — +40px.
   Расчёт: 61 - 40 = 21px чистого зазора до плашки меню, «ОТКРЫТЬ»
   остаётся кликабельным. Разница в 40px видна глазом как лесенка.
   На окнах выше 940px правка [56.1] не действует вовсе — там уже
   работает родная лесенка подрядчика во всю высоту, трогать нечего.
   Селектор тот же, что у [56.1], идёт ПОСЛЕ него ⇒ перекрывает
   значение честно порядком, без !important. */

/* ============================================================================
   СЕССИЯ 62 (25.08) — лист Ю.Л. 09:12–09:14, три пункта.
   ЗАМЕР ДО ПРАВКИ (zamer-62.js / zamer-62b.js, живой стенд, реальная мышь
   и реальный ввод, 1280x800 и 1440x900).
   ============================================================================ */

/* [62.1] Ю.Л. п.3: «В реализованных объектах должна подчеркиваться только
   ссылка открыть как на главной стр в техноблоге — НЕ ИСПРАВЛЕНО».

   Жалоба ВЕРНА, и вот почему вчерашняя правка её не закрыла.
   Блок «Реализованные объекты» собран из ДВУХ РАЗНЫХ семейств карточек:
     ssd_similar_item_link  — на детальной странице объекта (кейса)
     objects_card_link      — на продуктовых, типовых решениях, главной
   Вчера [61.2] снял ховер названия только у ssd_similar_item — по адресу
   /realized-objects/shtab-stroitelstva-svyatogor/, который Юля прислала
   ссылкой. Скриншот 25.08 (image (15).png) сделан с ДРУГОЙ страницы —
   продуктовой, где то же на вид «РЕАЛИЗОВАННЫЕ ОБЪЕКТЫ» собрано на
   objects_card_link. Его я не тронул.

   ЗАМЕР 25.08, /product/modulnye-zdaniya/bolnitsy-i-fapy/, 4 карточки:
     НАЗВАНИЕ  rgb(200,16,46) + линия rgb(200,16,46)   ← Юля просит убрать
     ОТКРЫТЬ   rgb(200,16,46) + линия rgb(200,16,46)   ← остаётся
   Кейс Святогор для сверки (там [61.2] уже работает), 4/4 на обеих ширинах:
     НАЗВАНИЕ  rgb(16,24,32) + линия прозрачная ✔
     ОТКРЫТЬ   rgb(200,16,46) + линия rgb(200,16,46) ✔
   Эталон, на который Юля ссылается дословно («как на главной стр в
   техноблоге»), замерен там же: название rgb(16,24,32) + линия прозрачная,
   «ЧИТАТЬ» rgb(200,16,46) + линия. Приводим objects_card к этому виду.

   КЛАСС ОШИБКИ (в память): одинаковые НА ВИД блоки с одним заголовком —
   разные узлы. Правка по одному адресу из письма не закрывает требование,
   если тот же блок собран другим семейством классов на других страницах.
   Проверка теперь идёт по ВСЕМ типам карточек блока, а не по присланной ссылке.

   Правка зеркалит [60.1] и [61.2] — третье, последнее семейство.
   Специфичность повторяет структуру наших же правил (0,7,1), без !important. */
@media (hover: hover) {
    .default-slider-section .swiper .swiper-wrapper .swiper-slide a.objects_card_link:hover .link_content .objects_card_name,
    a.objects_card_link:hover .objects_card_name {
        color: #101820;
        text-decoration-color: transparent;
    }
}

/* [62.2] Ю.Л. п.2, вторая половина: «должен появляться светло-серый текст
   с ошибкой под кнопкой, как на белой форме».

   ЗАМЕР 25.08 (zamer-62.js, отправка пустой формы .js-planning-form
   на /product/modulnye-zdaniya/bolnitsy-i-fapy/):
     красная форма: .form-error-message ЕСТЬ, текст «ЗАПОЛНИТЕ ОБЯЗАТЕЛЬНЫЕ
                    ПОЛЯ», цвет rgb(208,208,208) ✔, но display: none 🔴
     белая форма:   тот же блок, цвет rgb(200,16,46), display: block ✔
   ⇒ цвет мы уже починили в [49.2], а сам блок НЕ ВИДЕН — жалоба верна.

   ПРИЧИНА (найдена в CSS подрядчика на стенде, не предположение):
     .pd_form_section .f1 .form_rows .form-error-message{display:none;position:absolute}
   Правило действует ТОЛЬКО в секции pd_form_section — а это и есть красная
   форма продуктовых страниц. Белая форма живёт в другой секции, туда правило
   не достаёт, поэтому там текст виден. Скрыл его подрядчик, не мы.

   Безопасность возврата проверена по скрипту форм (js подрядчика): блок
   .form-error-message СОЗДАЁТСЯ методом createElement только при непройденной
   проверке и УДАЛЯЕТСЯ (`g?.remove()`), когда форма заполнена верно. В покое
   его в разметке нет ⇒ показ не приведёт к постоянно висящей надписи.

   position: absolute снимаем вместе с display: блок вынут из потока не был бы
   виден на своём месте и налезал бы на кнопку. В белой форме он в потоке —
   повторяем её поведение, как и просит Юля («как на белой форме»).
   Специфичность повторяет структуру родного селектора (0,4,1), без !important.

   ОТСТУП ВЫРОВНЕН ПО ЭТАЛОНУ, а не на глаз. Замер после первой выкладки
   (otstup.js, обе формы на одной странице, отправка пустой):
     белая  (эталон Юли): зазор от низа кнопки 16px, левый край 26, шрифт 11px
     красная (мой 1-й заход): зазор 34px, левый край 26, шрифт 9px
   Левый край совпал сразу, расходились зазор и размер. Ставим 6px и 11px —
   после правки зазор становится 16px, как на белой. Размер 9px приходит от
   правила подрядчика `form .form_rows .form-error-message{font-size:9px}`,
   на белой форме его перебивает более сильный селектор — повторяем результат.

   ВТОРОЙ ЗАМЕР показал, что 6px+11px применились, а зазор всё равно 30 против
   16. Источник найден (otstup2.js), а не подобран числом: обе формы — grid,
   и расстояние между строками у них РАЗНОЕ.
     белая:   .form_rows.rows_btns.rows_50  gap 10px  ⇒ зазор 16
     красная: .form_rows.rows_btns          gap 24px  ⇒ зазор 30
   Разница ровно 24-10 = 14 = 30-16. У подрядчика есть правило
   `&:has(.submit_form_btn){gap:10px}`, на белой форме оно побеждает, на
   красной — перебивается более сильным селектором.
   ⛔ Общий gap не трогаем: он держит расстояние кнопка ↔ галочка согласия,
   правка по контейнеру сдвинула бы и её. Компенсируем на самом тексте:
   6 - 14 = -8px ⇒ зазор станет 16, как на эталоне, а галочка не двинется. */
.pd_form_section .f1.inverse .form_rows .form-error-message,
.pd_form_section .f1 .form_rows .form-error-message {
    display: block;
    position: static;
    margin-top: -8px;
    font-size: 11px;
}

/* ============================================================================
   СЕССИЯ 58 · 25.08.2026 · [63.1] Ю.Л.: «в красной форме поля не должны быть
   белыми при вводе или ошибке, нужно было только сделать серый цвет как раньше
   и оставить чекбокс» (25.08 09:14) + её же п.1 от 24.08 17:05 про исчезающий
   текст. Проверка p6-red-contrast держалась КРАСНОЙ с 20.08.

   ПОЧЕМУ ПРЕДЫДУЩИЕ ПРАВКИ НЕ ЗАКРЫЛИ ЖАЛОБУ (разбор 25.08, не догадка).
   Все правки сессий 49–62 написаны для узла `.form-error-message`. А красным
   светится СОСЕДНИЙ узел — `.error-message` (без «form-»), и цвет ему задан
   ИНЛАЙНОМ в шаблоне подрядчика: style="color:red" (footer.php и
   components/bitrix/news.detail/product_direction/template.php).
   Инлайн-стиль не перебивается обычным правилом ни при какой специфичности —
   только !important. Класс ошибки: одинаковые НА ВИД элементы — разные узлы,
   и «поправил похожее рядом» ≠ «поправил то, что видит человек».

   ЗАМЕР 25.08 (zamer_63.py, 1440x900, все четыре узла .error-message):
     js-planning-error   (красная форма)  текст rgb(255,0,0) фон rgb(200,16,46) контраст 1.47 ← чиним
     js-project-calc-error   (белый фон)  текст rgb(255,0,0) фон белый          контраст 4.00 ← НЕ трогаем
     js-question-error       (белый фон)  то же                                 контраст 4.00 ← НЕ трогаем
     js-form-error           (белый фон)  то же                                 контраст 4.00 ← НЕ трогаем

   Правим ТОЛЬКО узел внутри красной формы (form.inverse). На белом фоне
   красный текст читается (4.00) — перекрасив его, мы сломали бы рабочее.

   ЦВЕТ ВЗЯТ НЕ НА ГЛАЗ: #d0d0d0 — тот же серый, что уже стоит на полях и
   тексте .form-error-message ([50.2], просьба Юли «нужен серый, сейчас почти
   белый»). Контраст к красному фону 3.81 (было 1.47). Кандидаты померены:
   #e0e0e0 → 4.46 но заметно светлее полей (Юля уже просила темнее),
   #c8c8c8 → 3.52 хуже читается. Берём #d0d0d0 — единообразие с полями важнее
   +0.65 контраста, и это ровно то «как раньше», о котором она пишет.

   !important здесь ВЫНУЖДЕН и ограничен одним свойством одного узла: инлайн
   в чужом шаблоне. Правило конвейера «чужие файлы подрядчика не трогаем»
   соблюдено — правка живёт в нашем custom-fixes.css. */
form.inverse .error-message,
.f1.inverse .error-message,
.pd_form_section .f1.inverse .error-message {
    color: #d0d0d0 !important;
}

/* [63.2] Ю.Л. 25.08 09:14, вторая половина той же просьбы: «в красной форме
   поля не должны быть белыми ПРИ ВВОДЕ или ошибке, нужно было только сделать
   серый цвет как раньше и оставить чекбокс».

   ЗАМЕР 25.08 (probe: клик → ввод текста → отправка, форма .js-planning-form
   на /product/modulnye-zdaniya/bolnitsy-i-fapy/, 1440x900):
     поле в покое            текст rgb(255,255,255) рамка rgb(255,255,255)  ← белое
     поле при клике          то же                                          ← белое
     поле с введённым текстом то же                                         ← белое  ← жалоба
     поле с ОШИБКОЙ (parsley-error)  rgb(208,208,208)                       ← уже серое [50.2]
   То есть половина просьбы («при ошибке») закрыта ещё 20.08, а вторая
   («при вводе») — нет: заполненное верно поле остаётся белым.

   Подрядчик помечает верно заполненное поле классом `parsley-success`
   (виден в замере выше). Красим по нему и по состоянию фокуса/непустоты —
   ровно те состояния, которые Юля называет «при вводе».

   ⛔ Поля в ПОКОЕ не трогаем: пустая форма должна оставаться белой, как в
   макете; просьба именно про ввод и ошибку. Плейсхолдер тоже не трогаем.
   Цвет #d0d0d0 — тот же, что у ошибки и у текста ошибки, чтобы форма
   выглядела единообразно (её же требование «серый как раньше»). */
form.inverse input.parsley-success,
form.inverse textarea.parsley-success,
.f1.inverse input.parsley-success,
.f1.inverse textarea.parsley-success,
form.inverse .input_field input:focus,
form.inverse .input_field textarea:focus,
.f1.inverse .input_field input:focus,
.f1.inverse .input_field textarea:focus {
    color: #d0d0d0;
    border-color: #d0d0d0;
}

/* [63.3] Продолжение [63.2]: правка не подействовала — разобрано ПРИБОРОМ, а не
   догадкой. Через CSS.getMatchedStylesForNode на живом поле видно, кто побеждает:
     .pd_form_section .f1.inverse .form_rows .form_cols .input_field input  → #fff
   Это правило подрядчика (специфичность 0,6,1); мой прежний селектор
   `form.inverse input.parsley-success` (0,3,1) слабее и проигрывал молча.

   Повторяем СТРУКТУРУ родного селектора и добавляем состояние, ради которого
   правка делается (фокус / успешно заполненное / с ошибкой). Специфичность
   становится выше родной за счёт добавленного класса-состояния — без !important.

   Состояния взяты из замера: подрядчик вешает parsley-success на верно
   заполненное поле и parsley-error на поле с ошибкой. Юля просит серый и там,
   и там; пустое поле в покое остаётся белым (её просьба про «при вводе»). */
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input:focus,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea:focus,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input.parsley-success,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea.parsley-success,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input.parsley-error,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea.parsley-error,
form.inverse .form_rows .form_cols .input_field input:focus,
form.inverse .form_rows .form_cols .input_field textarea:focus,
form.inverse .form_rows .form_cols .input_field input.parsley-success,
form.inverse .form_rows .form_cols .input_field textarea.parsley-success {
    color: #d0d0d0;
    border-color: #d0d0d0;
}

/* ============================================================================
   СЕССИЯ 64 (25.08) — ТРИ ПУНКТА Ю.Л. 12:37–12:39 «НЕ ИСПРАВЛЕНО».
   Разбор сессии 63 показал: жалобы верны, а десять зелёных приёмок были
   зелёными потому, что мерили не то и не там. Здесь чиним по механизму,
   вскрытому прибором (zamer_64.py, razbor_64.py), и принимаем в ОКНЕ
   ПРОВЕРЯЮЩЕГО: 1920x950 и 1920x1080, а не только 1280x800 / 1440x900.
   ============================================================================ */

/* [64.1] Ю.Л. п.2: «на продуктовых стр при наведении на карточку должен
   подчёркиваться текст — НЕ ИСПРАВЛЕНО».

   ЗАМЕР 25.08 (razbor_64.py, /product/modulnye-zdaniya/obshchezhitiya/,
   карточка «ОБЩЕЖИТИЯ» арт. 26780 — та самая с её скриншота).
   Разобрана вся начинка карточки, узел за узлом, в покое и при наведении:
     pd_catalog_card_name  «ОБЩЕЖИТИЯ»   покой rgb(16,24,32) линия none
                                          ХОВЕР rgb(16,24,32) линия none  ← НЕ МЕНЯЕТСЯ
     pd_catalog_card_art   «Арт. 26780»   без изменений
     pd_catalog_person_label «От 12 человек» без изменений
   ⇒ при наведении на карточку каталога НЕ ПОДСВЕЧИВАЕТСЯ НИЧЕГО ВООБЩЕ.
   Слова «ОТКРЫТЬ»/«ЧИТАТЬ» в этом семействе НЕТ — это плитка, вся карточка
   и есть ссылка. Юля права дословно; правил под pd_catalog_card в нашем
   файле не было ни одного (grep: 0 совпадений) — правка не «сломалась»,
   её никогда не делали. Прежние зелёные приёмки мерили другое семейство
   (objects_card_link) и text-decoration-COLOR вместо LINE.

   Приводим к виду, который Юля называет эталоном («как в техноблоге»):
   имя карточки при наведении краснеет и подчёркивается. Толщина и отступ
   линии заданы явно — иначе браузер рисует её вплотную к буквам, и на
   мелком шрифте каталога она читается как грязь.

   СИЛА СЕЛЕКТОРА ВЗЯТА ЗАМЕРОМ, А НЕ НА ГЛАЗ (грабля сессий 60б и 61).
   Первая редакция была короткой (0,4,0) — проверка принудительным
   состоянием наведения через CDP показала половинчатый результат:
     линия  underline rgb(200,16,46) ✔ — появилась
     цвет   rgb(16,24,32) 🔴 — проиграл
   Победило правило подрядчика в шесть классов:
     .pd_catalog_section .pd_catalog_grid .pd_catalog_card
     .pd_catalog_card_content .pd_catalog_card_content_top .pd_catalog_card_name
   Полумера «линия есть, слово тёмное» вернулась бы одиннадцатым возвратом,
   поэтому повторяем структуру родного селектора и добавляем :hover ⇒ семь
   классов против шести, побеждаем порядком и силой, без !important. */
@media (hover: hover) {
    .pd_catalog_section .pd_catalog_grid .pd_catalog_card:hover .pd_catalog_card_content .pd_catalog_card_content_top .pd_catalog_card_name,
    .pd_catalog_card:hover .pd_catalog_card_content .pd_catalog_card_name,
    a.pd_catalog_card:hover .pd_catalog_card_name {
        color: #c8102e;
        text-decoration-line: underline;
        text-decoration-color: #c8102e;
        text-decoration-thickness: 1px;
        text-underline-offset: 3px;
    }
}


/* [64.3] Ю.Л. п.1: «Белые поля при вводе/ошибки в красной форме — НЕ ИСПРАВЛЕНО».

   Вчерашние правки [63.2]/[63.3] работают, но закрывают не все состояния.
   ЗАМЕР 25.08 (живой ввод символ за символом, /product/modulnye-zdaniya/bolnitsy-i-fapy/):
     поле В ФОКУСЕ, печатаю            rgb(208,208,208) серое ✔ (это [63.3])
     поле заполнено, ФОКУС УШЁЛ        rgb(255,255,255) БЕЛОЕ  🔴 ← вот жалоба
     после отправки, parsley-success   rgb(208,208,208) серое ✔
     после отправки, parsley-error     rgb(208,208,208) серое ✔
   ⇒ дыра ровно одна: поле уже заполнено, но форма ещё не отправлялась и
   курсор перешёл к следующему полю. Именно это Юля и видит: набрала имя,
   перешла к телефону — имя побелело. Классы состояния подрядчик вешает
   ТОЛЬКО после отправки (в замере до отправки у поля класс просто `js-let`),
   поэтому опираться на parsley-success нельзя — его в этот момент нет.

   Лечим состоянием самого браузера, а не классом сайта:
     :not(:placeholder-shown) — «в поле что-то напечатано», работает сразу
                                при вводе и не зависит от скриптов формы;
     :-webkit-autofill        — поле, подставленное автозаполнением Chrome.
   Автозаполнение — второй подозреваемый из разбора 63: браузер красит такое
   поле своим фоном поверх обычных правил цвета, обычным color его не взять,
   поэтому цвет текста задаём через -webkit-text-fill-color, а фон гасим
   внутренней тенью в цвет формы (приём стандартный, иначе Chrome рисует
   свой светло-жёлтый прямоугольник поверх красного фона).

   ⛔ Пустое поле в покое НЕ трогаем: оно остаётся белым, как в макете —
   Юля просит серый «при вводе или ошибке», не всегда.
   Специфичность повторяет структуру родного правила подрядчика
   (.pd_form_section .f1.inverse .form_rows .form_cols .input_field input)
   плюс состояние ⇒ выигрывает без !important. */
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input:not(:placeholder-shown),
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea:not(:placeholder-shown),
form.inverse .form_rows .form_cols .input_field input:not(:placeholder-shown),
form.inverse .form_rows .form_cols .input_field textarea:not(:placeholder-shown) {
    color: #d0d0d0;
    border-color: #d0d0d0;
}

.pd_form_section .f1.inverse .form_rows .form_cols .input_field input:-webkit-autofill,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea:-webkit-autofill,
form.inverse .form_rows .form_cols .input_field input:-webkit-autofill,
form.inverse .form_rows .form_cols .input_field textarea:-webkit-autofill {
    -webkit-text-fill-color: #d0d0d0;
    caret-color: #d0d0d0;
    border-color: #d0d0d0;
    -webkit-box-shadow: 0 0 0 1000px #c8102e inset;
    box-shadow: 0 0 0 1000px #c8102e inset;
    transition: background-color 100000s ease-in-out 0s;
}

/* [65.1] Ю.Л. 25.08 15:52 со скриншотом: «сами поля ввода не должны быть с белым
   фоном — убрать». На её снимке ЛЕВОЕ поле красное в штриховку, а ПРАВОЕ (телефон)
   залито белым и в нём её сохранённый номер +7 (901) 844-39-92 ⇒ это поле,
   подставленное АВТОЗАПОЛНЕНИЕМ браузера, а не обычный ввод.

   ПОЧЕМУ НАШИ ПРОВЕРКИ ЭТОГО НЕ ЛОВИЛИ (класс ошибки, не случайность):
   автозаполнение не срабатывает в браузере без профиля пользователя — у прибора
   нет ни сохранённых номеров, ни менеджера паролей. Все 24 поля на 12 страницах
   в четырёх состояниях и на семи ширинах окна замерены красными, и это правда:
   состояние :-webkit-autofill просто не наступало. Замер, который его показал, —
   принудительное включение состояния через отладчик браузера (CDP forcePseudoState).

   ЧТО ИМЕННО ПРОИГРЫВАЛО. Разбор каскада на живом поле в состоянии autofill:
     [подрядчик] form .form_rows .form_cols .input_field input:-webkit-autofill
                 box-shadow: inset 0 0 0 48px #fafafb !important      ← БЕЛЫЙ
     [подрядчик] ещё три таких же правила, все с !important
     [наше 64.3] ... input:-webkit-autofill
                 box-shadow: 0 0 0 1000px #c8102e inset               ← без !important
   #fafafb = rgb(250,250,251) — ровно тот цвет, что замерен на снимке Юли
   (проба пикселей: rgb(250,250,250) по всему полю, границы 660..1248 × 239..293).
   Правило с !important бьёт правило без него при ЛЮБОЙ точности селектора —
   поэтому [64.3] не мог сработать в принципе, сколько бы классов мы ни добавляли.

   ЛЕЧЕНИЕ: то же правило с !important, чтобы встать вровень с правилом подрядчика,
   и выиграть за счёт большей точности селектора (у подрядчика 0,5,1 — у нас 0,7,1).
   Заливку СНИМАЕМ СОВСЕМ (box-shadow:none), а не перекрашиваем в красный: поле
   становится прозрачным и показывает штриховку своей обёртки .input_field
   (картинка p2.png) — ровно так же, как в обычном состоянии без автозаполнения.
   Перекраска в сплошной #c8102e тоже убирала белизну, но закрывала штриховку:
   поле выглядело гладким пятном там, где соседнее полосатое. Проверено снимком.

   ⛔ Правило подрядчика НЕ удаляем и не трогаем: #fafafb уместен на БЕЛЫХ формах
   (калькулятор, всплывающие окна) — там поле и должно быть светлым. Наше правило
   бьёт только по формам на красном фоне (.inverse). */
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input:-webkit-autofill,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input:-webkit-autofill:hover,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input:-webkit-autofill:focus,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field input:-webkit-autofill:active,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea:-webkit-autofill,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea:-webkit-autofill:hover,
.pd_form_section .f1.inverse .form_rows .form_cols .input_field textarea:-webkit-autofill:focus,
form.inverse .form_rows .form_cols .input_field input:-webkit-autofill,
form.inverse .form_rows .form_cols .input_field input:-webkit-autofill:hover,
form.inverse .form_rows .form_cols .input_field input:-webkit-autofill:focus,
form.inverse .form_rows .form_cols .input_field input:-webkit-autofill:active,
form.inverse .form_rows .form_cols .input_field textarea:-webkit-autofill,
form.inverse .form_rows .form_cols .input_field textarea:-webkit-autofill:hover,
form.inverse .form_rows .form_cols .input_field textarea:-webkit-autofill:focus {
    -webkit-box-shadow: none !important;
    box-shadow: none !important;
    background-color: transparent !important;
    background-image: none !important;
    -webkit-text-fill-color: #d0d0d0 !important;
    caret-color: #d0d0d0;
    border-color: #d0d0d0 !important;
    transition: background-color 100000s ease-in-out 0s;
}

/* ============================================================
   [74.1] Планировка целиком, вместе с экспликацией
   Замер 27.08 (боевой, 1920x950, страница obshchezhitiya):
   большая картинка object-fit: cover, окно блока 640px,
   картинка 670x808 при исходнике 2400x2896 -> низ чертежа
   (таблица «Экспликация помещений») срезан на 168px.
   В миниатюре стоит contain, поэтому там экспликация видна —
   ровно это и заметил клиент.
   Лечение: contain для большой картинки, как в миниатюре.
   ============================================================ */
.ssd_hero_section .ssd_hero_inner .ssd_hero_main_image .ssd_hero_main_slr .swiper-slide .zoom-container img,
.ssd_hero_main_image .ssd_hero_main_slr .swiper-slide .zoom-container img,
.ssd_hero_main_image .swiper-slide img {
    object-fit: contain !important;
    object-position: center center !important;
    background-color: #fff;
    /* высота у тега стоит атрибутом (height="475"), из-за чего картинка
       растягивалась выше окна блока и contain не спасал: чертёж 2400x2896
       выходил 808px в окне 640px, низ с экспликацией уезжал за край.
       Прибиваем картинку к окну блока — тогда чертёж влезает целиком. */
    width: 100% !important;
    height: 100% !important;
    max-height: 100% !important;
}



/* ================= СЕССИЯ 76 (28.08) — лист Юли на 30 пунктов, Google-док =================
   https://docs.google.com/document/d/1XZNeNqlypm5VNt4CmU1Um--QpJnS9tOq4nC4uibBsVo/

   Ю2 · «На главной стр нужно выровнять цифры по одной направляющей».

   🔴 ПЕРВОЕ ПОНИМАНИЕ БЫЛО НЕВЕРНЫМ, снято скриншотом макета от Юли 16:36
   («цифры нужно выровнять на главной как в фигме, вот так»). Сначала прочитал
   ответ «по верхней границе цифры и текст» как «всё содержимое вверх» и прижал
   flex-start ко ВСЕМ четырём карточкам. В макете иначе:
     • первая карточка «107» на тёмной подложке — цифра ВВЕРХУ, подпись ВНИЗУ,
       содержимое разнесено по краям (это и есть родное space-between);
     • три остальные — цифра и подпись стоят ВНИЗУ, и выровнены между собой
       по нижнему краю тёмной подложки первой карточки.
   ⇒ Правка: возвращаем первой карточке разнесение по краям, трём остальным
   оставляем прижатие к низу (родное flex-end) — они и так выравниваются между
   собой, потому что высота карточек одинаковая. Правило про верх снято.

   Что осталось от правки: у активной карточки был `padding-top: 40px`, из-за него
   цифра «107» стояла на 40px ниже верхнего края подложки, тогда как в макете она
   прижата к верху. Этот отступ снимаем — остальные отступы не трогаем. */

/* Домер по тому же скриншоту макета: три правые карточки прижаты к низу, поэтому
   их цифры встают на одну линию только при одинаковой высоте подписей. Замер:
   у «11» и «6 530» подпись в 5 строк (80px), у «71» — в 4 строки (64px), из-за
   чего её цифра стояла на 16px ниже соседних. В макете подписи выровнены.
   Задаём подписи общую минимальную высоту 80px (это ровно 5 строк по замеру
   у двух длинных подписей) — короткая подпись добирает пустотой снизу, и все
   три цифры встают ровно. Первую карточку («107» на тёмной
   подложке) правило не трогает: у неё своя раскладка. */

/* Ю5 + Ю10 (лист Юли 28.08) — «В модальном окне отзыва фото должно быть сразу
   во всю высоту показано, без скролла, и нужно убрать чёрные полосы сверху»
   + «на детальных стр отзыва убрать чёрные полосы в самом отзыве».

   ЗАМЕР ПРИЧИНЫ (не гипотеза), попап письма ЕВРАЗ при окне 1920×950:
   окно попапа 720×950, внутренний отступ 40px, обёртка картинки 755px высотой
   с `max-height: 82vh` и `overflow: auto`, а сама картинка 640×905 при исходнике
   1240×1754. 905 > 755 ⇒ письмо не помещается и включается прокрутка — ровно то,
   что Юля перечеркнула на скриншоте вместе с полосой прокрутки справа.

   Правка: картинка вписывается в доступную высоту целиком (`max-height` вместо
   свободной высоты), пропорции сохраняются через `object-fit: contain`.
   Прокрутка обёртке больше не нужна — снимаем, чтобы не оставалась серая полоса.
   Ширину окна не трогаем: письмо А4, по ширине оно и так помещалось. */
.rdh_letter_popup_image {
    max-height: calc(82vh - 40px);
    overflow: visible;
    display: flex;
    justify-content: center;
}

.rdh_letter_popup_image img {
    max-height: calc(82vh - 40px);
    width: auto;
    height: auto;
    object-fit: contain;
}

/* Замечание Юли 28.08 16:36, п.1 — «Пункты меню при наведении сначала подчёркиваются
   чёрным, затем красным, ховер срабатывает с торможением».

   ЗАМЕР ПОКАДРОВО, панель продукции на главной, оба движка:
     Chrome: линия идёт rgba(98,77,84) → rgba(128,59,73) → rgba(155,43,63) → красный,
             то есть ПЕРЕТЕКАЕТ ЧЕРЕЗ ГРЯЗНО-БУРЫЙ — это и читается как «сначала чёрное»;
     Safari: сразу rgba(200,16,46) с ростом прозрачности — правильно.

   ПРИЧИНА ТА ЖЕ, ЧТО В ПУНКТЕ ЛЕОНИДА 27.08 [74.3] (приём подрядчика libercode):
   линия рисуется через `text-decoration-color: currentColor`, а цвет текста в тот же
   момент едет с #101820 на #c8102e. Браузер честно смешивает промежуточные цвета —
   получается бурый переход. Класс «унаследованный дефект», у нас он уже вскрывался
   на кнопках «ОТКРЫТЬ», просто в другом блоке.

   Правка: обоим состояниям задаём линии КРАСНЫЙ НАПРЯМУЮ, а не currentColor.
   В покое линия прозрачная, при наведении — #c8102e. Цвет текста не трогаем.
   ⚠️ ПЕРВАЯ РЕДАКЦИЯ (красный только на :hover) НЕ ПОМОГЛА — снято замером:
   Chrome по-прежнему шёл rgba(98,77,84) → rgba(128,59,73) → красный. Причина:
   в ПОКОЕ линия задана как `transparent`, то есть «прозрачный ЧЁРНЫЙ», и Chrome
   честно ведёт переход от чёрного к красному через бурый. Safari стартует иначе
   и потому был чистым.
   ⇒ Задаём красный ОБОИМ концам перехода, а прячем линию прозрачностью того же
   красного (`rgba(200,16,46,0)`). Тогда меняется только прозрачность, оттенок
   постоянный — линия проявляется сразу красной в обоих браузерах. */
.types_of_buildings_section .tbs_tabs_list .tbs_tab .tbs_tab_grid .tbs_tab_grid_item .tbs_tab_grid_item_link .tbs_grid_item_link_content .tbs_grid_item_link_name {
    text-decoration-color: rgba(200, 16, 46, 0);
}

.types_of_buildings_section .tbs_tabs_list .tbs_tab .tbs_tab_grid .tbs_tab_grid_item .tbs_tab_grid_item_link .tbs_grid_item_link_content .tbs_grid_item_link_name:hover,
.types_of_buildings_section .tbs_tabs_list .tbs_tab .tbs_tab_grid .tbs_tab_grid_item .tbs_tab_grid_item_link:hover .tbs_grid_item_link_content .tbs_grid_item_link_name {
    text-decoration-color: rgba(200, 16, 46, 1);
}

/* ============================================================
   Замечание Юли 28.08 17:32, п.2 — «делаем 5, но первые 5 карточек
   должны быть расположены в точности как в фигме» (типовые решения).

   ЗАМЕР ПРИЧИНЫ (страница /standart-solutions/, окно 1440):
   в сетке оказалось 9 узлов на 5 карточек — четыре из них ПУСТЫЕ распорки.
   Шаблон ставил их жёстко по номеру (3 штуки после 3-й карточки, по одной
   после 4-й и 6-й, две после 8-й) — эта арифметика рассчитана ровно на
   ВОСЕМЬ карточек макета. При наших пяти распорки съедали целый ряд:
   отсюда белое поле в середине и одинокая карточка АБК внизу.
   Второй слой той же причины — ширину задавало правило nth-child(5n+1),
   а оно считает и распорки тоже, поэтому широкой становилась первая
   карточка вместо третьей и четвёртой (в макете широкие — «Общежития»
   и «Вахтовые посёлки», то есть места 3 и 4).

   Правка шаблона: распорки ставятся по местам макета (после 4-го и 6-го)
   и только если следующая карточка реально есть; ширина назначается
   классом по номеру места. Здесь снимаем старое правило ширины по
   позиции в вёрстке, иначе оно продолжит спорить с классом.
   Бэкап шаблона делает сам рельс выкладки (.bak-<дата>). */
.ss_grid .ss_grid_item:nth-child(5n+1) {
    width: 100%;
}

.ss_grid .ss_grid_item:nth-child(5n+1) .ss_grid_item_link .ss_grid_item_image {
    height: max(16.625rem, min(8.83929rem + 12.1652vw, 23.4375rem));
}

/* Карточка занимает СВОЮ ячейку целиком.
   Родное правило давало ей width: calc(50% - 8px) — половину ячейки: полную ширину
   получал только класс is-large, который навешивал скрипт по формуле «каждая пятая».
   Раз раскладку теперь задают места макета, а не эта формула, ширину ячейки
   возвращаем всем карточкам, размеченным шаблоном (метка ss-slot-fixed);
   широкие места по-прежнему растягиваются на две колонки классом double. */
.ss_grid .ss_grid_item.ss-slot-fixed {
    width: 100%;
}

/* широкое место (2 колонки) — размеры возвращаем ему явно, чтобы правило
   выше не срезало картинку у «Общежитий» и «Вахтовых посёлков» */
.ss_grid .ss_grid_item.double {
    width: 100%;
}

.ss_grid .ss_grid_item.double .ss_grid_item_link .ss_grid_item_image {
    height: max(29.75rem, min(15.8929rem + 21.6518vw, 41.875rem));
}

/* ================= СЕССИЯ 78 (29.08) — лист Юли, ховер на отзыве =================

   Ю7 · «При наведении на отзыв справа нужно сделать чтобы одинаково срабатывал
         ховер — сейчас сначала текст мелкий красный, потом ФИО — должно быть всё сразу».
   Ю11 · «Нужно добавить ховер на ФИО и мелкий текст снизу»
         (/reviews/shtab-stroitelstva-rmk/, /reviews/ofisnoe-zdanie-evraz/).

   ЗАМЕР ПРИЧИНЫ (29.08, наведение включено протоколом браузера — мышью на этом
   сайте ховер не ловится, панели закрываются, пока прибор ищет элемент):
   на ДЕТАЛЬНОЙ странице отзыва ховера нет вовсе — ни ФИО (.rdh_person_name),
   ни мелкий текст (.rdh_person_role) при наведении не меняются:
   ФИО rgb(16,24,32) → rgb(16,24,32), мелкий rgb(83,86,90) → rgb(83,86,90).
   Открыватель письма .rdh_letter_open при этом показан браузерным синим
   rgb(0,0,238) — своего оформления у ссылки не было.

   Правка: ховер вешается на ОДИН общий узел (.rdh_person / карточку целиком),
   а красят оба текста ВМЕСТЕ, одним переходом одинаковой длительности.
   Так «сразу всё», а не «сначала мелкий, потом ФИО»: разнобой возникал там,
   где у элементов разные родители наведения и разное время перехода.
   Цвет и длительность — те же, что приняты на сайте: #c8102e и .35s. */

.rdh_person .rdh_person_name,
.rdh_person .rdh_person_role,
.rdh_person a.rdh_letter_open,
.rdh_person a.rdh_letter_open .rdh_person_name,
.rdh_person a.rdh_letter_open .rdh_person_role {
    -webkit-transition: color .12s ease, -webkit-text-decoration-color .12s ease;
    transition: color .12s ease, text-decoration-color .12s ease;
}

/* ссылка-открыватель не должна выглядеть браузерной синей */
.rdh_person a.rdh_letter_open,
a.rdh_letter_open {
    color: inherit;
    text-decoration: none;
}

/* наводим на любую часть карточки — краснеют ОБА текста одновременно.

   🔴 ПЕРВАЯ РЕДАКЦИЯ НЕ СРАБОТАЛА: селектор из двух частей
   (.rdh_person:hover .rdh_person_name) оказался СЛАБЕЕ родного из четырёх
   (.rdh_section .rdh_content .rdh_person .rdh_person_name, color:#101820) —
   правило было видно в списке применённых, но цвет не менялся.
   Тот же класс ошибки, что с цифрами на главной 28.08.
   Поэтому здесь селектор той же длины, что родной, плюс :hover. */
.rdh_section .rdh_content .rdh_person:hover .rdh_person_name,
.rdh_section .rdh_content .rdh_person:hover .rdh_person_role,
.rdh_section .rdh_content .rdh_person:focus-within .rdh_person_name,
.rdh_section .rdh_content .rdh_person:focus-within .rdh_person_role,
.rdh_section .rdh_content .rdh_person a.rdh_letter_open:hover .rdh_person_name,
.rdh_section .rdh_content .rdh_person a.rdh_letter_open:hover .rdh_person_role,
.rdh_section .rdh_content .rdh_person_info:hover .rdh_person_name,
.rdh_section .rdh_content .rdh_person_info:hover .rdh_person_role {
    color: #c8102e;
}

/* ФИО — отдельной ссылкой рядом с фото письма (разметка шаблона reviews):
   наведение на неё тоже красит обе строки */
.rdh_person:hover a.rdh_letter_open,
a.rdh_letter_open:hover {
    color: #c8102e;
}

/* ================= СЕССИЯ 78 (29.08) — Ю17/Ю6, выравнивание текста по верхней направляющей =================

   Ю17 · «На всех стр продукции текст должен быть выровнен по верхней направляющей»
         (/product/modulnye-zdaniya/obshchezhitiya/ и остальные страницы продукции).

   ЗАМЕР ПРИЧИНЫ (29.08): в блоке «ПРЕДЛАГАЕМ КОМПЛЕКСНОЕ РЕШЕНИЕ» левая колонка
   .pd_complex_advantages разложена как flex с justify-content: space-between —
   три подписи РАВНОМЕРНО растянуты по высоте колонки и ни к чему не привязаны.
   Правая колонка .pd_complex_steps — обычный список из шести шагов.
   Отсюда разнобой: совпадает только первая строка, дальше подписи «плывут».

   СВЕРКА С МАКЕТОМ (Figma, продуктовая страница 196:300, координаты узлов):
       справа шаги (1)…(6):  y = 2461 · 2539 · 2617 · 2733 · 2811 · 2889
       слева три подписи:    y = 2470 · 2617 · 2811
   То есть подписи стоят НАПРОТИВ 1-го, 3-го и 5-го шагов (2470≈2461, 2617=2617,
   2811=2811), а не через равные промежутки. На сайте было +0 / +150 / +285,
   по макету должно быть +0 / +131 / +294 — расхождение 19 и 9 пикселей.

   Правка: раскладываем левую колонку той же сеткой, что и правую, и ставим
   подписи на 1-ю, 3-ю и 5-ю строки. Тогда верх подписи совпадает с верхом
   своего шага на любой длине текста — это и есть «по верхней направляющей». */

/* Левая колонка перестаёт растягиваться и просто прижимается к верху;
   каждая подпись получает отступ, равный сумме высот шагов над ней.
   Отступ задаём в тех же единицах, что и сам блок (rem от корневого шрифта),
   чтобы правка не разъехалась на других ширинах экрана. */
.pd_complex_grid .pd_complex_advantages {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: stretch;
}

/* Подпись 2 встаёт напротив шага (3), подпись 3 — напротив шага (5).
   Отступ = расстояние до нужного шага МИНУС высота всего, что стоит выше.
   Замер на живом: шаги идут на +0 / +131 / +294 от верха блока,
   высота подписей 48 и 34 пикселя. Отсюда 131−48 = 83 и 294−131−34 = 129.

   🔴 Первая редакция брала разницу координат макета (147 и 194) без вычета
   высоты самих подписей — подписи ушли на +147 и +343 вместо +131 и +294.
   Класс: «отступ между блоками считается от низа предыдущего, а не от его верха». */
.pd_complex_grid .pd_complex_advantages > *:nth-child(2) {
    margin-top: 83px;
}

.pd_complex_grid .pd_complex_advantages > *:nth-child(3) {
    margin-top: 129px;
}

/* ===================================================================
   [101] 09.09.2026 — П2 Леонида: «на телефоне блок "Предлагаем комплексное
   решение" разъезжается лесенкой».

   ПРИЧИНА (замер на бою, ширина 390, реальный браузер). Две причины сразу:
   1) .pd_complex_advantages на узком экране остаётся сеткой в ТРИ КОЛОНКИ
      (замер: 76px | 77px | 162px) — подписи сплющены в узкие полоски;
   2) отступы 83px и 129px выше в этом файле поставлены СЕССИЕЙ 78 ради
      десктопа: там подписи должны стоять напротив 1-го, 3-го и 5-го шага
      правой колонки. На телефоне колонки встают друг под друга, шагов
      напротив уже нет, а отступы остаются и сдвигают подписи вниз.
      Замер до правки: подписи на x=20 / 106 / 193 и y=1967 / 2050 / 2096.

   ЛЕЧЕНИЕ. Ниже 1024px (там же, где ломается макет в две колонки) подписи
   встают в ОДНУ колонку на всю ширину, а десктопные отступы обнуляются.
   Правка классом: любое число подписей ляжет столбиком.
   ⛔ Десктопное выравнивание сессии 78 НЕ трогаем — оно живёт выше и
   продолжает работать от 1024px, где шаги справа действительно есть. */
@media (max-width: 1023px) {
  .pd_complex_grid .pd_complex_advantages > *:nth-child(2),
  .pd_complex_grid .pd_complex_advantages > *:nth-child(3) {
    margin-top: 0;
  }
}

/* [104] 10.09.2026 — ВОЗВРАТ №1 по П2 (Юля, п.1 от 09.09 16:17).
   Сессия 101 разложила подписи СТОЛБИКОМ во всю ширину (14px, замер на бою дал 16px),
   не открыв мобильный макет. В НОВОМ мобильном макете Figma (фрейм «Продуктовая
   страница» 2793:2924, 375px) подписи стоят ТРЕМЯ КОЛОНКАМИ В РЯД: x=20 (w76) ·
   x=106 (w77) · x=279 (w76), верх всех трёх на одной линии y=1710, шрифт 6/550.
   Ровно это и делает родная сетка подрядчика 76 | 77 | minmax(0,1fr) с прижатой
   вправо третьей колонкой — поэтому наш блок «в столбик» СНЯТ целиком, чужую сетку
   больше не перебиваем. Шрифт подписей возвращается к 7px подрядчика (макет 6 —
   разница глазом неразличима), отдельно не переопределяем.
   ⛔ Правило `margin-top:0` для 2-й и 3-й подписи (блок выше) ОСТАЁТСЯ: именно оно
   лечило «лесенку» из П2 клиента — десктопные отступы 83/129px на телефоне сдвигали
   подписи вниз, когда шагов напротив уже нет. */

/* ===================================================================
   [80.1] 31.08.2026 (сессия 80) — СКОРОСТЬ ХОВЕРА: .35s -> .12s
   Пункты Юли Н1/Н3/Н8/Н17 (возвраты Ю3/Ю8/Л1, третий круг) и её же
   слова 28.08: «ховер срабатывает с торможением».

   ЗАМЕР ДО ПРАВКИ (hover80_povtor.py, реальная мышь, 5 циклов подряд,
   быстрое движение — как у человека, а не 15 плавных шагов прибора):
   переход длился 0.35s на text-decoration-color и color. На главной
   в цикле 1 наведение СОСКОЧИЛО (hov: True,False,False...) и линия не
   появилась вовсе — ровно то, что описывает Юля: «срабатывает еле при
   первом наведении и дальше её уже нет при повторном».
   Первый кадр всех циклов на всех трёх страницах: цвет ещё серый
   rgb(83,86,90), линия прозрачная — человек видит запаздывание.

   ⚠️ 0.35s поставили МЫ САМИ (сессии до 80), чтобы линия и текст
   краснели ОДНОВРЕМЕННО (до этого линия шла от currentColor и краснела
   позже текста). Замысел верен, длительность — нет: 0.35s человек
   читает как «не сработало». Одновременность сохранена, время
   сокращено до .12s — величина, уже принятая в этом файле для меню
   шапки (строка 1141), там жалоб на торможение не было.

   Правка КЛАССОМ по всему файлу (правило 9 журнала: формулировка-принцип
   чинится везде, а не в блоке со скриншота): заменены ВСЕ 24 перехода
   ховера — карточки техноблога, объектов, каталога, меню, отзывов,
   ссылок писем. Комментарии, описывающие чужой код, не тронуты.
   =================================================================== */

/* ===================================================================
   [80.2] 31.08.2026 (сессия 80) — ВЫРАВНИВАНИЕ ТЕКСТА ОТЗЫВА ПО ВЕРХУ
   Пункт Юли Н6 (возврат Ю17/Ю6): «Текст во 2 столбике должен быть
   выровнен по верхней границе текста — везде и всегда так выравнивать».
   Адреса из её листа: /realized-objects/ofisnoe-zdanie-evraz/ и
   /realized-objects/shtab-stroitelstva-rmk/, блок «О НАС ГОВОРЯТ».
   На её картинке (image3) красная линия проведена по верху ЛЕВОГО
   абзаца — просьба про столбцы самого текста письма, не про картинку.

   ЗАМЕР ДО ПРАВКИ (1920x950, живой сайт):
     ЕВРАЗ: левый столбец текста 1822, правый 2002 — ниже на 180px
     РМК:   левый 1848/1979, правый 2159 — ниже на 180px
   ПРИЧИНА: .rod_review_intro — сетка в 3 колонки, а абзацы .rod_review_text
   лежат в ней подряд БЕЗ назначенного ряда. Сетка раскладывает их сама:
   первый абзац в колонку 1, второй — под ним в колонку 1, третий — в
   колонку 2 вторым рядом. Отсюда «в разных кейсах до переноса влезает
   разный объём» (это же наблюдение — в Л12): раскладку делает сетка,
   а не шаблон.

   ПРАВКА: должность и имя закреплены за рядами 1 и 2 первой колонки,
   ВСЕ абзацы письма — в один ряд 3, каждый своей колонкой, прижаты к
   верху (align-self:start). Тексты стартуют с одной линии независимо
   от их числа и длины — то есть выполняется «везде и всегда».
   ПРОВЕРЕНО пробной правкой на обеих страницах: ЕВРАЗ 3 абзаца — все
   1822; РМК 4 абзаца — все 1873. Шапка (должность, имя) не сдвинулась.
   =================================================================== */
/* ⚠️ ДВЕ ГРАБЛИ, ОБЕ ПОЙМАНЫ ЗАМЕРОМ НА БОЮ (не рассуждением):
   (1) все элементы блока — DIV, поэтому nth-of-type считает ВМЕСТЕ с
       должностью и именем: абзацы идут 3-м, 4-м, 5-м, а не 1-2-3;
   (2) у подрядчика есть правило
       `.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:last-child
        {grid-column:2}` — селектор в ТРИ класса, он сильнее одноклассового.
       Первая редакция правила (один класс) применилась лишь частично:
       абзацы 2 и 3 остались в колонке 1 и НАЛОЖИЛИСЬ друг на друга.
   ⇒ повторяем силу селектора подрядчика. Колонок в сетке ТРИ
   (`repeat(3, minmax(0,1fr))`), четвёртой не существует — больше трёх
   абзацев кладём по кругу, чтобы ничего не пропало. */


/* ===================================================================
   [80.3] 31.08.2026 — СКОРОСТЬ ХОВЕРА: перекрытие правил ПОДРЯДЧИКА
   Дополнение к [80.1]. После выкладки [80.1] замер показал: на главной
   переход стал .12s, а на КЕЙСАХ и ПРОДУКТОВЫХ остался .35s.
   Причина (снята со страницы, не предположение): скорость там задают
   правила подрядчика селекторами в шесть классов —
     `.default-slider-section .swiper .swiper-wrapper .swiper-slide a
      .link_content .ssd_similar_card_label .t {transition:.35s}`
      (realized-objects.min.css)
     то же для `.objects_card_label` (product-detail.min.css).
   Наши правила были слабее и молча проигрывали — тот же класс ошибки,
   что с `!important` подрядчика в П4 и с grid-column в [80.2].
   ⇒ повторяем силу селектора вместо повышения важности.
   =================================================================== */
.default-slider-section .swiper .swiper-wrapper .swiper-slide a .link_content .ssd_similar_card_label .t,
.default-slider-section .swiper .swiper-wrapper .swiper-slide a .link_content .objects_card_label .t,
.default-slider-section .swiper .swiper-wrapper .swiper-slide a .link_content .technoblog_card_label .t {
    transition: text-decoration-color .12s, color .12s;
}

/* ===================================================================
   [80.4] 31.08.2026 — ЧЁРНЫЕ ПОЛОСЫ У ПИСЬМА (пункт Юли Н9, возврат Ю10)
   «На детальных стр отзыва убрать чёрные полосы в самом отзыве»:
   /reviews/shtab-stroitelstva-rmk/ и /reviews/ofisnoe-zdanie-evraz/.

   🔴 ПРОШЛЫЙ РАЗ ПУНКТ ЗАКРЫЛИ НЕВЕРНО, потому что толковали СЛОВА
   («полосы» приняли за прокрутку). На картинке Юли (image12) крестом
   перечёркнуты именно ЧЁРНЫЕ ПЛАШКИ сверху и снизу картинки письма.
   Правило приёмки 10: закрываем сверкой С КАРТИНКОЙ.

   ЗАМЕР ДО ПРАВКИ — не «на глаз», а СЧЁТОМ ПИКСЕЛЕЙ на снимке блока
   (326x476): тёмных строк 15, двумя полосами — сверху 8px, снизу 7px.
   ПРИЧИНА: у обёртки `.rdh_person_image` фон rgb(16,24,32) (почти чёрный),
   размер 325x475 = 1:1.46, а файл письма 1240x1754 = 1:1.41. При
   `object-fit:contain` картинка вписывается по ширине, а по высоте
   остаётся зазор — и в нём виден чёрный фон обёртки. Это не скан с
   чёрными краями и не прокрутка.
   ПРАВКА: фон обёртки — белый, как бумага письма.
   ✅ ПРОВЕРЕНО ПРОБНОЙ ПРАВКОЙ ДО ВЫКЛАДКИ: тех же пикселей после
   белого фона — тёмных строк 0 из 476 (было 15).
   =================================================================== */
/* ⚠️ Первая редакция (`.rdh_person .rdh_person_image`, два класса) НЕ
   сработала: у подрядчика правила в ЧЕТЫРЕ класса, они сильнее —
   `.rdh_section .rdh_content .rdh_person .rdh_person_image` и
   `.sidebar_popup .popup_inner .rdh_person .rdh_person_image`
   (reviews.min.css). Проверено после выкладки: полос было 15 строк,
   осталось 15. Повторяем силу селектора, без !important.
   ВТОРОЙ АДРЕС ЗАКРЫВАЕТ ПУНКТ Н5: `.sidebar_popup` — это и есть
   модальное окно отзыва («убрать чёрные полосы сверху»), тот же
   чёрный фон под тем же письмом. */
.rdh_section .rdh_content .rdh_person .rdh_person_image,
.sidebar_popup .popup_inner .rdh_person .rdh_person_image { background-color: #ffffff; }

/* ===================================================================
   [80.5] 31.08.2026 — КРЕСТИК «ЗАКРЫТЬ» В ОКНЕ ФОТО (пункт Юли Н14)
   «При клике на фото в модальном окне иконка "закрыть" должна ВСЕГДА
   находиться на одном месте во всех фото — сверху справа».

   ЗАМЕР ДО ПРАВКИ (живой сайт, окно письма на кейсе ЕВРАЗ):
   у кнопки `.f-button.is-close-btn` было `top:-38px; right:0` при
   `position:absolute`, а само окно начинается с самого верха экрана
   (y=0) ⇒ кнопка уезжала ЗА ВЕРХНЮЮ ГРАНИЦУ ЭКРАНА: замеренная
   координата y = -38, крестика физически не видно.
   Он «висел» над окном, что работало только пока окно стояло по
   центру с отступом сверху; после нашего решения [78] «окно прижато
   к левому краю» отступ исчез — и кнопка выпала из экрана.
   Постановщик это решение отменяет, пункт закрывается по её слову.

   ПРАВКА: кнопка привязана к ОКНУ БРАУЗЕРА (position:fixed), верх 20px,
   право 20px — одно и то же место для любого фото и любого размера окна.
   ✅ ПРОВЕРЕНО ПРОБНОЙ ПРАВКОЙ ДО ВЫКЛАДКИ: координаты стали (1866, 20),
   кнопка целиком внутри экрана.
   =================================================================== */
/* ⚠️ Первая редакция целилась в `.fancybox__container .f-button.is-close-btn`
   и НЕ сработала: положение задаёт правило самой библиотеки Fancybox
   `.fancybox__content > .f-button.is-close-btn` (прямой потомок —
   селектор точнее). Проверено после выкладки: y так и остался -38.
   Целимся в ТОТ ЖЕ селектор с прямым потомком. */
.fancybox__content > .f-button.is-close-btn,
.fancybox__container .fancybox__content > .f-button.is-close-btn {
    position: fixed;
    top: 20px;
    right: 20px;
    left: auto;
    bottom: auto;
    z-index: 50;
}

/* ===================================================================
   [80.6] 31.08.2026 — ХОВЕР ПОДПИСИ ОТЗЫВА НА КЕЙСАХ (пункт Юли Н7)
   «При наведении на отзыв справа ховер должен срабатывать одинаково:
   сейчас сначала текст мелкий красный, потом ФИО — должно быть всё сразу».
   Возврат Ю7/Ю11: в сессии 78 это чинили на ДЕТАЛЬНОЙ странице отзыва,
   а жалоба — про блок отзыва на СТРАНИЦЕ КЕЙСА (правило 9: принцип
   чинится во всех местах, а не там, где чинили в прошлый раз).

   ЗАМЕР ДО ПРАВКИ (покадрово, живой сайт, /realized-objects/ofisnoe-zdanie-evraz/):
     через 120 мс: мелкий текст rgb(138,19,41) — уже почти красный,
                   ФИО         rgb(52,22,35)  — ещё почти чёрное
   Глаз читает это как «сначала мелкий, потом ФИО» — ровно слова Юли.
   ПРИЧИНА, и она НАША: у подрядчика оба узла красятся за 0.35s, а мы в
   прошлой сессии дали ссылке ФИО собственные 0.12s. Разные скорости на
   соседних словах = видимый разнобой. Дело было не в задержке, а в РАЗНИЦЕ.
   ПРАВКА: одинаковая скорость .12s у ФИО и у мелкого текста; силу
   селектора повторяем за подрядчиком, иначе правило снова проиграет.
   =================================================================== */
.rod_review_section .rod_review_grid .rod_review_media .rod_review_image_caption .rod_review_image_name,
.rod_review_section .rod_review_grid .rod_review_media .rod_review_image_caption .rod_review_image_subname {
    transition: color .12s;
}
/* ⚠️ ГЛАВНОЕ, и это НЕ скорость: одинаковой длительности оказалось мало.
   Внутри ФИО лежит ССЫЛКА `.rod_review_person_link` с `color:inherit` и
   СВОИМ переходом (наша правка прошлой сессии). Родитель плавно краснеет —
   и ссылка плавно догоняет уже изменившийся родительский цвет: переход
   накладывается на переход, ФИО отстаёт от соседнего слова.
   Замер до: на 120 мс мелкий rgb(138,19,41), ФИО rgb(51,22,35).
   ⇒ у вложенной ссылки переход СНИМАЕМ: пусть наследует цвет родителя
   мгновенно, а плавность даёт один родитель.
   ✅ Проверено пробной правкой на живом сайте: на 60/120/300 мс цвет ФИО
   и мелкого текста СОВПАДАЕТ до единицы (68,22,36 / 138,19,41 / 176,17,44). */
.rod_review_image_name .rod_review_person_link { transition: none; }


/* ===================================================================
   [82.2] 01.09.2026 — ЛИСТ ЮЛИ 01.09, п.6: «текст должен быть в 2 столбика
   расположен, не в 3, и выровнен по верхней границе текста — везде и всегда
   так выравнивать текст». Страницы: /realized-objects/ofisnoe-zdanie-evraz/
   и /realized-objects/shtab-stroitelstva-rmk/.

   ЗАМЕР ДО ПРАВКИ (живой сайт, окно 1600x1000, обе страницы):
     .rod_rows        сетка 678px + 678px          -> ДВЕ колонки
     .rod_col_inner   сетка 330px + 330px          -> правая делится ещё на две
     по экрану:  фото(113) | характеристики(809) | текст(1157) = ТРИ колонки
   То есть в разметке два столбца, а ГЛАЗ видит три — именно об этом Юля.
   Верхняя граница при этом уже сходится: характеристики и «ЗАДАЧА» обе
   начинаются на y=1028 — вторая половина пункта была выполнена ранее.

   ПРАВКА: правый столбец перестаёт делиться надвое — характеристики и текст
   идут одной колонкой друг под другом. Страница становится ровно
   двухколоночной: фото | текст, как и просит Юля.
   Вертикальный отступ 40px между характеристиками и «ЗАДАЧА» — чтобы блоки
   не слипались (без него текст начинается сразу под «ПЛИТЫ ПДН»).
   Проверено пробной правкой на живом сайте до записи: обе колонки читаются,
   верх текста сходится, ничего не наезжает.
   =================================================================== */
.rod_content_section .rod_rows .rod_col .rod_col_inner {
    grid-template-columns: 1fr;
    row-gap: 40px;
}


/* ⚠️ ПОПРАВКА К [82.3], найдена замером сразу после первой попытки.
   Сначала я по образцу [82.1] добавил сюда ещё и margin-bottom:40px —
   и текст остался съехавшим ровно на те же 40px. Замер объяснил почему:
   на низких окнах низ картинки у всех карточек УЖЕ совпадает (4435 у всех
   четырёх), потому что карточка .vertical здесь не сдвинута (margin-top:0),
   а только выше на 40px. Значит компенсировать нечего: подъём картинки
   сам ставит текст в общую линию, а отступ снизу лишь отодвигал его обратно.
   На высоких окнах [82.1] отступ снизу НУЖЕН — там карточка ещё и сдвинута
   на 45px, и низ картинки не совпадает. Разные случаи, разные лекарства. */

/* ===================================================================
   [84.1] 02.09.2026 — ЛИСТ ЛЕОНИДА МУСАТОВА 01.09, блок «о нас», п.3:
   «В каждом разделе заголовок пункта на чёрном фоне съехал наверх
   (см. макет)» + «В подразделе преимущества описание пункта на чёрном
   фоне должно быть выровнено по другим описаниям (ранее было правильно)».
   Блок: .about_atlas_section, вкладки «О компании в цифрах / Преимущества /
   Лицензии / Отзывы» на главной.

   ЗАМЕР ДО ПРАВКИ (живой сайт, окно 1440x900, вкладка «в цифрах»):
     карточка 0 (чёрная): justify-content: space-between
                          число top=109, текст top=338
     карточки 1,2,3:      justify-content: flex-end
                          число top=250, текст top=314
   Расхождение чисел 141px — ровно то, что Леонид назвал «съехал наверх».

   ПРИЧИНА, найдена измерением, а не на глаз. Их две, и первая скрывала вторую:
   1) у чёрной карточки прижатие содержимого другое (space-between против
      flex-end у соседей) — число уезжает к верхнему краю плашки;
   2) после исправления (1) осталось расхождение 24px: текст чёрной карточки
      занимает 4 строки против 6 у соседей (плашка уже, перенос другой).
      Все карточки прижаты низом — значит более КОРОТКИЙ текст начинается НИЖЕ.

   ПРАВКА: чёрная карточка прижимается низом, как соседи, а текстовым блокам
   задаётся общая минимальная высота — тогда и числа, и описания встают
   в одну линию независимо от числа строк. Высота 80px = 6 строк
   при line-height 13.5172px (самый длинный текст, карточка «6 530»).

   ПРОВЕРЕНО пробной правкой на живом сайте ДО записи в файл:
     число  top: 249 / 250 / 250 / 250   (было 109 / 250 / 250 / 250)
     текст  top: 312 / 314 / 314 / 314   (было 338 / 314 / 314 / 314)
   Расхождение 1–2px — округление подпиксельных величин, глазу не видно.
   Снимок «стало»: about-after-proba.png.
   =================================================================== */


/* ⚠️ ПОПРАВКА К [84.1], найдена проверкой на живом сайте сразу после записи.
   Первая версия правки НЕ ПРИМЕНИЛАСЬ: замер показал justify-content:
   space-between, хотя в файле стояло flex-end. Причина — вес селектора:
   у подрядчика в main.min.css правило записано полной цепочкой
   (.about_atlas_section .about_section_info_tabs .about_section_info_tab
    .about_section_info_tab_cards_list .about_section_info_tab_card.active),
   а моё было коротким и проигрывало по приоритету.
   Класс ошибки: «записал в файл» ≠ «применилось» — проверять замером
   применённого значения, а не наличием строки в файле.

   Там же обнаружено: подрядчик выравнивание ЗАДУМЫВАЛ — у первой вкладки
   стоит min-height: calc(var(--line-height) * 5) для .info_tab_card_text.
   Но 5 строк не хватает: самый длинный текст («6 530 км — максимальная
   удалённость…») занимает 6, и правило не покрывает чёрную карточку.
   Поэтому ниже — те же 6 строк через ту же переменную подрядчика,
   а не жёсткие 80px: при смене размера окна масштабируется вместе с сайтом. */


/* ⚠️ ВТОРАЯ ПОПРАВКА К [84.1] — тоже найдена замером, не глазом.
   Правка веса селектора (первая поправка) сработала для justify-content:
   разброс чисел упал 141 -> 24. Но остаток в 24px = ровно 2 строки
   (2 x 13.5172 = 27) не ушёл: min-height через var(--line-height) дал
   пустоту — ПЕРЕМЕННОЙ --line-height НА ЭТОМ САЙТЕ НЕТ. Проверено обходом
   :root, body и всех секций: getPropertyValue возвращает пустую строку.
   Подрядчик использует её в main.min.css, где она объявлена локально
   и до нашего блока не долетает.
   Класс ошибки: взял переменную из чужого файла, не проверив, что она
   объявлена там, где я её применяю.

   Замер применённого: у чёрной карточки min-height остаётся auto (её текст
   54px = 4 строки), у трёх соседних 80px (6 строк) — правило подрядчика
   адресовано карточкам :not(.active), то есть чёрную оно намеренно
   обходит. Поэтому ниже — та же величина 80px, но БЕЗ исключения .active,
   в единицах, которые сайт реально считает (line-height 13.5172px x 6).
   =================================================================== */


/* ⚠️ ТРЕТЬЯ ПОПРАВКА К [84.1] — причина оказалась в СЛОМАННОМ правиле подрядчика.
   Замер: моё правило селектору ПОДХОДИТ (txt.matches = true), но применяется
   min-height: auto. Разбор: у подрядчика в main.min.css для первой вкладки
   стоит min-height: calc(var(--line-height) * 5), а переменной --line-height
   на сайте НЕТ ВООБЩЕ. calc с неизвестной переменной даёт недопустимое
   значение, браузер откатывает свойство в auto — и делает это ПОСЛЕ моего
   правила, потому что его селектор с :first-child весит больше.
   То есть выравнивание у подрядчика не «не покрывает чёрную карточку»,
   а сломано целиком: пятистрочная подложка не работает нигде.

   Лечим пометкой важности — это ровно тот случай, для которого она нужна:
   перебить чужое правило, которое браузер всё равно отбрасывает как битое.
   Величина 80px = 6 строк по 13.5172px, по самому длинному тексту
   («6 530 км — максимальная удалённость реализованного объекта…»).
   =================================================================== */

/* ============================================================
   [85.1] Леонид 01.09, «Планировки» п.4: «неправильное расположение цены».
   Правая колонка .ssd_hero_info растягивалась по высоте фотографии (541px),
   пустота распределялась между блоками — чем меньше полей заполнено, тем ниже
   уезжали цена и кнопка (на АБК зазор 54px + дыра против 24px у соседних блоков).
   Колонка перестаёт растягиваться, содержимое идёт подряд с шагом 24px.
   Макета детальной страницы в Figma нет (узел 314:6967 — список, не детальная);
   сделано по внутренней сетке страницы, замер 01.09: кнопка 721 -> 688.
   ============================================================ */
.ssd_hero_section .ssd_hero_info {
  align-self: start;
}


/* ============================================================
   [О1] Лист «Оставшиеся правки 4.09.26», п.1 (Леонид через Юлю):
   «Сделать расположение стоимости и CTA как в макете — сейчас цена
   прижата к кнопке».

   ПРИЧИНА (снято с боя 07.09). У .ssd_hero_price на десктопе нижнего
   отступа НЕТ ВООБЩЕ: базовое правило подрядчика в standart-solutions.min.css
   задаёт только шрифт, цвет и line-height:120%, ни margin, ни padding.
   Отступ margin-bottom:32px существует ТОЛЬКО в мобильном брейкпоинте
   (там же font-size:9px). Кнопка лежит в .ssd_hero_bottom{margin-top:auto},
   то есть прижимается к низу колонки вплотную к цене.
   Поэтому дефект виден на десктопе и НЕ виден на телефоне.

   ЭТАЛОН — макет, а не глазомер. Figma TCG6HzUBDpmd6u3mPjjuCr,
   фрейм 318:7893 «Типовое решение», ширина 1440:
     низ текста цены (y+h)      = 796
     верх кнопки КУПИТЬ (320:8566) = 857
     => зазор 61px
   Для контекста в макете: от низа «ПОЛНЫЕ ХАРАКТЕРИСТИКИ» до верха цены ≈ 65,5px.

   ⚠️ Правка [85.1] от 01.09 (.ssd_hero_info{align-self:start}) НЕ отменяется:
   она лечила другой дефект — разъезд цены по вертикали между страницами.
   Тогда в комментарии было записано «макета детальной страницы в Figma нет»
   — это оказалось неверно, фрейм 318:7893 найден 07.09, поэтому зазор
   теперь ставится по макету, а не по внутренней сетке.

   Отступ снизу у цены, а не сверху у кнопки: .ssd_hero_bottom содержит ещё
   строку наличия (.ssd_hero_availability), которая на большинстве страниц
   скрыта, но на некоторых выводится — отступ сверху у кнопки дал бы двойной
   разрыв там, где строка наличия видна.
   ============================================================ */
.ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_price {
  margin-bottom: 61px;
}

/* ============================================================
   [О2] Лист «Оставшиеся правки 4.09.26», п.2: «Сделать 1 кнопку закрыть»
   (окно планировки на детальной странице типового решения).

   ПРИЧИНА (снято с боя 07.09). Крестиков действительно два, и они от
   РАЗНЫХ источников:
     1) собственный крестик вёрстки — a.cls_pp.fap внутри каждого
        div.win_popup.ss_plan_popup (таких блоков на странице 14);
     2) крестик библиотеки — открывашка openFancybox
        (chunks/fancybox-2XC33QKE.js) вызывается с closeButton:"inside",
        то есть Fancybox рисует свой крестик поверх содержимого.

   Убираем СОБСТВЕННЫЙ, оставляем крестик Fancybox: он закрывает и по Esc,
   и по клику мимо картинки, а самодельный — только по клику ровно в него.
   Прячем именно внутри .ss_plan_popup: класс .cls_pp используется и в
   других окнах сайта, где он единственный и нужен.
   ============================================================ */
.ss_plan_popup .cls_pp {
  display: none;
}

/* ============================================================
   [88.1] Лист Леонида Мусатова 01.09.26, «Кейс 2»:
   «неправильный перенос текста отзыва, колонки должны быть длиннее»
   Страницы с отзывом: /realized-objects/shtab-stroitelstva-rmk/
   и /realized-objects/ofisnoe-zdanie-evraz/ (на остальных трёх
   кейсах блока отзыва нет — проверено обходом всех пяти страниц).

   ПРИЧИНА (снята с боя 07.09, не предположена). Раскладку делает
   правило ПОДРЯДЧИКА в realized-objects.min.css:
       .rod_review_section .rod_review_grid .rod_review_intro
       .rod_review_text:nth-of-type(2n) { grid-column: 2 }
   Чётные абзацы уходят в колонку 2, нечётные остаются в колонке 1,
   ряд назначается автоматически. При ЧЕТЫРЁХ абзацах выходит плитка
   2x2: абзацы 1-2 в первом ряду, 3-4 во втором, между рядами дыра,
   третья колонка сетки пустует. Текст читается зигзагом
   (1 вправо -> 2, вниз -> 3 вправо -> 4), а не колонками.
   ЗАМЕР ДО (1920x1000): РМК 4 абзаца, y = 1975 и 2154 (два ряда),
   высоты 160/160/96/96; ЕВРАЗ 3 абзаца, y = 1982 и 2161.

   ЭТАЛОН — макет Figma TCG6HzUBDpmd6u3mPjjuCr, узел 478:386
   («Реализованный объект»), узлы текста 478:542 и 478:543:
   ДВЕ колонки по 325 px, ОБЕ от одной верхней линии y=1623,
   левая длиннее (288 px, два абзаца подряд), правая короче (128 px).
   Второго ряда во всю ширину в макете НЕТ. Это и есть просьба
   Леонида «колонки должны быть длиннее»: текст должен литься
   сверху вниз внутри колонки, а не рваться на короткие плитки.

   ПРАВКА: абзацы делятся пополам — первая половина в колонку 1
   рядами подряд, вторая в колонку 2. Ряды назначены явно, поэтому
   правило подрядчика nth-of-type(2n) перебивается без !important:
   повторяем силу его селектора (класс ошибки [80.2]/[80.3] —
   слабый селектор молча проигрывает).

   ⚠️ ГРАБЛЯ [80.2], учтена: все элементы блока — DIV, поэтому
   nth-of-type считает ВМЕСТЕ с .rod_review_post и .rod_review_name.
   Абзацы идут 3-м, 4-м, 5-м, 6-м, а не 1-2-3-4. Пара
   :nth-of-type(N):nth-last-of-type(M) задаёт и позицию, и общее
   число абзацев — поэтому раскладка своя для 2, 3 и 4 абзацев
   и не ломается, если контент-менеджер добавит или уберёт абзац.

   ПРОВЕРЕНО пробной правкой в браузере ДО записи на сервер:
   РМК 4 абзаца -> 2+2, обе колонки от линии 1975, ширина 325 px;
   ЕВРАЗ 3 абзаца -> 2+1, обе от линии 1982. Наложений 0.
   Размеры окна 1920/1440/1280/1024/768/390 — везде две колонки,
   наложений нет. Ширину колонок правка НЕ трогает: 175 px на
   телефоне были и до неё (решение подрядчика).
   ============================================================ */
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text {
  align-self: start;
}

/* два абзаца: 1 + 1 */
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:nth-of-type(3):nth-last-of-type(2) { grid-column: 1; grid-row: 3; }
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:nth-of-type(4):nth-last-of-type(1) { grid-column: 2; grid-row: 3; }

/* три абзаца: 2 + 1 */
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:nth-of-type(3):nth-last-of-type(3) { grid-column: 1; grid-row: 3; }
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:nth-of-type(4):nth-last-of-type(2) { grid-column: 1; grid-row: 4; }
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:nth-of-type(5):nth-last-of-type(1) { grid-column: 2; grid-row: 3; }

/* четыре абзаца: 2 + 2 */
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:nth-of-type(3):nth-last-of-type(4) { grid-column: 1; grid-row: 3; }
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:nth-of-type(4):nth-last-of-type(3) { grid-column: 1; grid-row: 4; }
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:nth-of-type(5):nth-last-of-type(2) { grid-column: 2; grid-row: 3; }
.rod_review_section .rod_review_grid .rod_review_intro .rod_review_text:nth-of-type(6):nth-last-of-type(1) { grid-column: 2; grid-row: 4; }


/* ================= СЕССИЯ 93 (08.09) — правка Юли 07.09 16:36 =================
   «На детальных стр решений фото по высоте больше в макете, тогда и кнопка
    справа расположена по нижней границе, а сейчас она вылазит»
   пример: /standart-solutions/administrativno-bytovye-kompleksy/

   ЗАМЕР ДО (боевой сайт, окно 1920x1000):
     АБК          фото 640 px, правая колонка 718 px -> кнопка ниже фото на 78 px
     общежития    фото 640, колонка 643 -> 3 px
     офисы        фото 640, колонка 643 -> 3 px

   ПРИЧИНА (не в высоте фото). Фото 640 px совпадает с макетом
   (Figma TCG6HzUBDpmd6u3mPjjuCr, узел 318:7893 «Типовое решение»:
   фото 318:7911 y=257 h=640 -> низ 897; кнопка КУПИТЬ 320:8566
   y=857 h=40 -> низ 897; разница 0). Вылезает КОЛОНКА: заголовок
   «АДМИНИСТРАТИВНО-БЫТОВЫЕ КОМПЛЕКСЫ» переносится в три строки и
   занимает 113 px вместо 38 в макете — лишние 75 px и дают вылет 78.
   Отступы между блоками заданы жёстко, ужиматься им нечем.

   ЛЕЧЕНИЕ. Колонка получает высоту фото, нижний блок прижимается к её
   низу, а вертикальные зазоры делаются сжимаемыми (min(px, vh)) — воздух
   макета сохраняется, а излишек уходит первым. Правка КЛАССОМ, не под одну
   страницу: длинное название на любой будущей карточке лечится тем же.
   ⛔ Обнуление отступов отвергнуто: проверено в браузере — «ВЫБЕРИТЕ
   КОЛИЧЕСТВО» слипается с заголовком, «ПОЛНЫЕ ХАРАКТЕРИСТИКИ» с площадью.

   ПРОВЕРЕНО пробной правкой в браузере ДО записи: АБК вылет 78 -> 0,
   наложений 0, минимальный зазор 17 px, снимок сверен с макетом.
   ============================================================ */
@media (min-width: 1024px) {
  .ssd_hero_section .ssd_hero_inner .ssd_hero_info {
    height: 100%;
  }
  .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_bottom {
    margin-top: auto;
    padding-top: 20px;
  }
  .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_title {
    margin-bottom: min(60px, 4vh) !important;
  }
  .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_capacity {
    margin-bottom: min(40px, 3vh) !important;
  }
  .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_full_specs_link {
    margin-bottom: min(64px, 4vh) !important;
  }
  /* [101] 09.09 — ВОЗВРАТ ПРАВКИ [О1]. Здесь стояло margin-bottom:0 !important,
     что молча отменило зазор 61px, поставленный 07.09 по макету (низ цены 796 ->
     верх кнопки 857). Клиент 09.09 предъявил дефект третий раз.
     Ноль не нужен: излишек высоты уже забирают четыре сжимаемых отступа выше
     (min(px,vh)) плюс margin-top:auto у .ssd_hero_bottom. Зазор цены делается
     таким же сжимаемым — на нормальной высоте окна это 61px по макету, а на
     низком окне он ужимается вместе с остальными и вылет АБК не возвращается. */
  .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_price {
    margin-bottom: min(61px, 4vh) !important;
  }
}


/* ===================================================================
   [101] 09.09.2026 — П3 Леонида: «формы на телефоне» (блок «РАССЧИТАЕМ ПРОЕКТ»).

   ПРИЧИНА (замер на бою, ширина 390, реальный браузер). В стилях подрядчика
   (product-detail.min.css) для экранов до 1023px размеры шрифта прописаны
   ЧИСЛОМ и очень мелко, тогда как на десктопе там нормальная плавающая
   величина max(0.625rem, min(…, 0.875rem)) = 10–14px:
       .pd_calc_subtitle .......... 6px   (замер computed)
       заголовок H2 «РАССЧИТАЕМ ПРОЕКТ» ... 9px
       поля формы и плейсхолдеры .. 9px
       текст согласия и ссылки .... 8px
       кнопка «ОТПРАВИТЬ» ......... 9px
   На телефоне это нечитаемо. Отдельная беда — поля мельче 16px: iOS при
   нажатии на такое поле принудительно увеличивает страницу («прыжок»),
   поэтому поля ввода поднимаем именно до 16px, а не до 14px.

   ЛЕЧЕНИЕ. Возвращаем блоку читаемые размеры на экранах до 1023px.
   Правка классом — на всех страницах продукции, где стоит этот же блок.
   ⛔ Десктоп не трогаем: правило живёт внутри @media (max-width:1023px). */
/* [104] 10.09.2026 — ВОЗВРАТ №1 по П3 (Юля, п.3 от 09.09 16:19: «шрифты все взять
   с фигмы»). Сессия 101 дала шапке 20/13 «по здравому смыслу» и поставила подпись
   ПОД заголовком. В новом мобильном макете (2793:2924, 375px) шапка устроена иначе:
   заголовок «РАССЧИТАЕМ / ПРОЕКТ» 9px в две строки СЛЕВА (колонка w77), подпись
   «ОСТАВЬТЕ ЗАЯВКУ…» 6px СПРАВА (x=192, w163), верх обоих на одной линии.
   Это же и был П3 клиента — он писал про РАСПОЛОЖЕНИЕ, не про размер. */
@media (max-width: 1023px) {
  .pd_calc_section .pd_calc_top {
    display: grid;
    grid-template-columns: 1fr 163px;
    column-gap: 20px;
    align-items: start;
  }

  .pd_calc_section .pd_calc_top h2,
  .pd_calc_section .pd_calc_top .pd_calc_title {
    font-size: 9px;
    line-height: 1.2;
    max-width: 77px;
  }

  .pd_calc_section .pd_calc_top .pd_calc_subtitle {
    font-size: 6px;
    line-height: 1.35;
    margin-top: 0;
  }
}

/* Сама форма лежит НЕ в .pd_calc_section, а в .pd_form_section
   (проверено обходом дерева на бою: form.f1.js-planning-form внутри
   .pd_form_section > .container > .pd_form_inner). У подрядчика там
   до 1023px поля 6px, до 499px — 9px. Перебиваем тем же весом. */
@media (max-width: 1023px) {
  .pd_form_section .f1 .form_rows .form_cols .input_field input,
  .pd_form_section .f1 .form_rows .form_cols .input_field textarea,
  .pd_form_section .f1 .form_rows .form_cols .input,
  form .form_rows .form_cols .input_field input,
  form .form_rows .form_cols .input_field textarea,
  form .form_rows .form_cols .input {
    font-size: 16px;
  }

  /* [104] подсказки в полях: 14 -> 9px по макету (Юля п.2 «текст в полях меньше»).
     Текст, который человек ВВОДИТ, остаётся 16px строкой выше — iOS увеличивает
     страницу при нажатии на поле мельче 16px, это не по макету, но защищает от
     «прыжка» вёрстки на айфоне. */
  .pd_form_section .f1 .form_rows .form_cols .input_field input::placeholder,
  .pd_form_section .f1 .form_rows .form_cols .input_field textarea::placeholder,
  form .form_rows .form_cols .input_field input::placeholder,
  form .form_rows .form_cols .input_field textarea::placeholder {
    font-size: 9px;
  }

  /* кнопка: у подрядчика селектор ...button[type="submit"] — он точнее
     класса, поэтому повторяем его форму, иначе правка не применяется */
  /* [104] текст кнопки: 14 -> 9px по макету (обе формы — белая и красная). */
  .pd_form_section .f1.inverse .form_rows button[type="submit"],
  .pd_form_section .f1 .form_rows button[type="submit"],
  form.inverse .form_rows button[type="submit"],
  form .form_rows button[type="submit"] {
    font-size: 9px;
  }
}

/* Текст согласия у подрядчика задан в @media (max-width: 499px) — более
   узкое условие побеждает наше 1023px независимо от селектора.
   Поэтому повторяем ЕГО брейкпоинт и его селектор (.iagree label.css-label). */
/* [104] 10.09.2026 — согласие и ссылка на политику: 12 -> 9px (Юля п.3 «политику
   ссылку меньше под кнопкой»). Порядок НЕ меняем: в белой форме согласие стоит под
   кнопкой — так у подрядчика и так просит Юля; в красной оно над кнопкой, в макете
   согласия нет вовсе, поэтому её порядок не трогаем. */
@media (max-width: 499px) {
  .pd_form_section .f1 .form_rows .iagree label.css-label,
  form .form_rows .iagree label.css-label {
    font-size: 9px;
    line-height: 1.4;
  }

  .pd_form_section .f1 .form_rows .iagree label.css-label a,
  form .form_rows .iagree label.css-label a {
    font-size: 9px;
  }
}

/* ===================================================================
   [104] 10.09.2026 — СТРЕЛКИ В КНОПКАХ НА ТЕЛЕФОНЕ (Юля п.2 «в кнопке стрелочка
   должна быть» и п.3 «стрелочки везде пропали на мобилке»).

   ПРИЧИНА (чтение живого CSS подрядчика): product-detail.min.css внутри
   @media (max-width:499px) ставит display:none на svg в четырёх местах —
   кнопка отправки обеих форм, «ОСТАВИТЬ ЗАЯВКУ» в шапке товара и «СОХРАНИТЬ»
   в фильтре. Замер на бою 375px до правки: у всех svg ширина 0.

   ЛЕЧЕНИЕ: тот же брейкпоинт и ТЕ ЖЕ четыре селектора -> display:block.
   Кнопке добавлен space-between, чтобы стрелка встала у правого края, как на
   десктопе (там svg 11x11 прижат вправо). */
@media (max-width: 499px) {
  form .form_rows button[type="submit"] svg,
  .pd_form_section .f1 .form_rows button[type="submit"] svg,
  .pd_hero_section .container .pd_hero_desc .pd_hero_button svg,
  .sidebar_filter_popup .sidebar_filter_popup_inner .sidebar_filter_popup_bottom .popup_filter_apply svg {
    display: block;
  }

  form .form_rows button[type="submit"],
  .pd_form_section .f1 .form_rows button[type="submit"],
  .pd_hero_section .container .pd_hero_desc .pd_hero_button {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
}

/* [104] 10.09.2026 — те же спрятанные стрелки на страницах ТИПОВЫХ РЕШЕНИЙ.
   Юля просила «стрелочки везде», поэтому обошли и второй шаблон: в
   standart-solutions.min.css @media (max-width:499px) точно так же гасит svg
   ещё в трёх кнопках — «КУПИТЬ» в карточке решения и «СОХРАНИТЬ» в двух
   фильтрах (по вместимости и общем). Замер на АБК 375px до правки: ширина 0.
   Повторяем их же селекторы -> display:block. */
@media (max-width: 499px) {
  .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_bottom .ssd_hero_buy_button svg,
  .sidebar_popup .popup_inner .popup_p_capacity_filter .p_capacity_filter_footer .p_capacity_filter_apply svg,
  .sidebar_filter_popup .popup_inner .popup_filter .popup_filter_footer .popup_filter_apply svg {
    display: block;
  }
}

/* [104] 10.09.2026 — ЗАЩИТА ОТ «ПРЫЖКА» НА АЙФОНЕ ВО ВСЕХ ФОРМАХ САЙТА.
   Правило выше (блок [101]) поднимало текст ВВОДА до 16px только внутри
   @media (max-width:1023px). На страницах типовых решений подрядчик задаёт
   полям 9px в более узком @media (max-width:499px) — узкое условие побеждает,
   и на телефоне поле снова становится 9px (замер на АБК 375px: font-size 9px).
   Safari на iOS автоматически увеличивает всю страницу, когда человек нажимает
   на поле мельче 16px, — вёрстка «прыгает» и обратно не возвращается.
   Поэтому повторяем ЕГО брейкпоинт для текста ввода во всех формах.
   ⛔ Подсказки (::placeholder) НЕ трогаем: они остаются 9px по макету —
   iOS смотрит только на размер вводимого текста. */
@media (max-width: 499px) {
  form .form_rows .form_cols .input_field input,
  form .form_rows .form_cols .input_field textarea,
  form .form_rows .form_cols .input,
  .win_popup .popup_inner form .form_rows .form_cols .input_field input,
  .win_popup .popup_inner form .form_rows .form_cols .input_field textarea {
    font-size: 16px;
  }
}

/* ============================================================
   [106] 10.09.2026 — ОФОРМЛЕНИЕ ПЕРЕСОБРАННЫХ SEO-ТЕКСТОВ (П4 клиента).
   Тексты семи продуктовых страниц пересобраны из исходных страниц клиента:
   вернулись заголовки, списки и названия карточек, потерянные нашим
   извлекателем при переносе (лежали плоскими абзацами).
   У подрядчика в блоке .ma_adv_hidden_text описан ТОЛЬКО <p> — h3, ul, ol и
   strong остались бы без оформления. Повторяем его типографику: тот же шрифт,
   те же плавающие размеры, тот же цвет.
   ============================================================ */
/* Подрядчик держит абзац в колонке max-width ~597px на 1920. Заголовки и
   списки обязаны стоять в ТОЙ ЖЕ колонке, иначе текст разъезжается: абзац в
   половину экрана, список во всю ширину (замер 1920: p 597px против ol 1360px). */
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3,
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol {
  max-width: max(19.875rem, min(31.1384vw - .0535714rem, 37.3125rem));
}
@media (max-width: 1023px) {
  .ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3,
  .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
  .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol {
    max-width: 100%;
  }
}

.ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3 {
  font-family: RobotoFlex, Arial, sans-serif;
  font-variation-settings: "wght" 700, "wdth" 151, "GRAD" 150, "opsz" 144;
  font-size: max(.75rem, min(.410714rem + .535714vw, 1.0625rem));
  line-height: 120%;
  color: #101820;
  letter-spacing: 0;
  text-transform: none;
  margin: max(1rem, min(.553571rem + .714286vw, 1.4375rem)) 0
          max(.5rem, min(.276786rem + .357143vw, .71875rem));
}
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3:first-child {
  margin-top: 0;
}
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol {
  font-family: RobotoFlex, Arial, sans-serif;
  font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
  font-size: max(.625rem, min(.339286rem + .446429vw, .875rem));
  line-height: 145%;
  color: #101820;
  margin: 0 0 max(.375rem, min(.669643vw - .0535714rem, .75rem));
  padding-left: 1.35em;
}
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul { list-style: disc; }
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol { list-style: decimal; }
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text li {
  margin-bottom: max(.25rem, min(.446429vw - .0357143rem, .5rem));
}
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text li:last-child { margin-bottom: 0; }
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text strong,
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text b {
  font-variation-settings: "wght" 700, "wdth" 151, "GRAD" 150, "opsz" 144;
  font-weight: 400; /* вес даёт variable-шрифт, обычный bold его ломает */
}
/* На телефоне подрядчик задаёт абзацу 9px — держим ряд заголовков и списков
   рядом с ним, иначе текст «прыгает» по размеру. */
@media (max-width: 1023px) {
  .ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3 { font-size: 12px; }
  .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
  .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol { font-size: 9px; }
}

/* [106] 10.09.2026 — ЗАГОЛОВОК КРАСНОЙ ФОРМЫ НА ТЕЛЕФОНЕ ПО МАКЕТУ.
   Мобильный макет (Figma «Продуктовая страница» 2793:2924) держит у формы
   «ПОЛУЧИТЕ БЕСПЛАТНОЕ ПЛАНИРОВОЧНОЕ РЕШЕНИЕ» заголовок 9px и подпись 6px
   под ним. На бою стояло 16px и 12px — от подрядчика.
   Юля этот пункт не называла, вопрос ей был задан 10.09 и ответа нет;
   правим ПО МАКЕТУ (документ сильнее устной подписи), у белой формы
   «РАССЧИТАЕМ ПРОЕКТ» тот же размер 9px уже стоит — формы встают в один ряд. */
@media (max-width: 1023px) {
  .pd_form_section .pd_form_inner .pd_form_section_top_desc h2 {
    font-size: 9px;
    line-height: 114%;
  }
  .pd_form_section .pd_form_inner .pd_form_section_top_desc .section_top_text {
    font-size: 6px;
    line-height: 120%;
  }
}

/* ============================================================
   [106] 10.09.2026 — ЛИСТ ЮЛИ 10.09 09:30, пункт 6:
   «кнопка закрыть меню плохо срабатывает».
   Замер на 375: кнопка меню 35×35 px, стоит внизу справа (x 320, y 757).
   Палец в такую попадает через раз — Apple и Google просят минимум 44×44.
   ⛔ Увеличивать саму кнопку НЕЛЬЗЯ: впритык (0 px) лежат ссылки блоков
   «Вахтовые поселки» и «Модульные здания» — накроем их и сломаем переходы.
   ⛔ И ::after, и ::before у подрядчика ЗАНЯТЫ: это полоски самого значка
   (замер: 17×2 px). Трогать их — сломать вид кнопки.
   Поэтому область нажатия растим отступом самой кнопки, а её содержимое
   держим по центру: рамка (border-box) растёт наружу на 5 px с каждой
   стороны, значок остаётся ровно там, где нарисован в макете.
   ============================================================ */
@media (max-width: 1023px) {
  .header_burger {
    /* 35 + 2×5 = 45 px: перекрываем норму 44×44, наружу уходим на 5 px,
       соседних ссылок (они в 0 px справа/сверху) не задеваем, потому что
       смещаемся отрицательным margin ровно на величину отступа */
    box-sizing: content-box;
    padding: 5px;
    margin: -5px;
  }
}

/* ============================================================
   [106] 10.09.2026 — ЛИСТ ЮЛИ 10.09 09:30, пункты 1, 3, 4:
   «стрелочка во всех кнопках должна быть выровнена по низу с текстом»,
   «стрелочки добавить во всех кнопках и на гл стр»,
   «на стр О нас нет стрелочек у кнопок».

   ЧАСТЬ 1 — ВЕРНУТЬ ПРОПАВШИЕ. Обход всех кнопок сайта на 375 нашёл шесть
   штук с нулевой шириной стрелки: три кнопки документов и «ОСТАВИТЬ ЗАЯВКУ»
   на главном экране главной, «У НАС ТАКАЯ ЖЕ ЗАДАЧА» в блоке проектов
   и «ОСТАВИТЬ ЗАЯВКУ» на странице «О нас». Всем трём подрядчик ставит
   display:none в @media (max-width:499px) — повторяем ЕГО селекторы и
   ЕГО брейкпоинт, иначе не перебивается (та же грабля, что 10.09 в [104]).
   ============================================================ */
@media (max-width: 499px) {
  .hero_section .container .hero_section_buttons_list .hero_section_button svg,
  .completed_project_section .container .cp_rows .cp_col .cp_col_btm .cp_col_btm_links .cp_col_btm_link_wrapper .def_lnk svg,
  .ab_hero_section .container .ab_hero_bottom .ab_hero_btn svg {
    display: block;
  }
}

/* ЧАСТЬ 2 — ВЫРОВНЯТЬ ПО НИЗУ ТЕКСТА.
   Замер на /faq: низ стрелки 868, низ текста 878 — стрелка на 10 px выше.
   🔴 Две граблі подряд:
   (1) align-self:flex-end не сработал — подрядчик позиционирует стрелку
       АБСОЛЮТНО (`bottom:20px; right:20px`), flex к ней не применяется;
   (2) короткий селектор `.pd_hero_button > svg` проиграл его длинному
       `.pd_hero_section .container .pd_hero_desc .pd_hero_button svg` —
       повторяем ЕГО селекторы целиком, как и в правках 10.09.
   Кнопки высотой 45 px, текст 9 px по центру ⇒ низ текста отстоит от низа
   кнопки на 11 px. Ставим `bottom:11px`, правая привязка не меняется.
   ⛔ Карточки объектов, статей, отзывов и типовых решений НЕ трогаем:
   там стрелка стоит в своём нижнем углу у слова «ПОДРОБНЕЕ», а не рядом
   с текстом города — так нарисовано в макете (проверено снимком карточки). */
@media (max-width: 1023px) {
  form .form_rows button[type="submit"] svg,
  .submit_form_btn > svg,
  .completed_project_section .container .cp_rows .cp_col .cp_col_btm .cp_col_btm_links .cp_col_btm_link_wrapper .def_lnk svg,
  .ab_hero_section .container .ab_hero_bottom .ab_hero_btn svg,
  .pd_hero_section .container .pd_hero_desc .pd_hero_button svg,
  .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_bottom .ssd_hero_buy_button svg {
    bottom: 11px;
  }
}

/* Кнопки документов на главном экране главной («СРО НА СТРОИТЕЛЬСТВО» и др.)
   устроены иначе: сама кнопка высотой 7 px, а стрелке подрядчик держит
   opacity:0 и показывает её только при наведении мышью. На телефоне
   наведения нет — поэтому мы её и вернули (часть 1), но нужно ещё
   сделать видимой и поставить по низу текста: замер дал bottom 1 px. */
@media (max-width: 499px) {
  /* ⛔ :not(.active) — важно: под тот же класс попадает большая кнопка
     «ОСТАВИТЬ ЗАЯВКУ» высотой 45 px, ей нужны те же 11 px, что и остальным
     (замер: с bottom:1px стрелка ушла на 9 px НИЖЕ текста). */
  .hero_section .container .hero_section_buttons_list .hero_section_button:not(.active) svg {
    opacity: 1;
    bottom: 1px;
  }
  .hero_section .container .hero_section_buttons_list .hero_section_button.active svg {
    opacity: 1;
    bottom: 11px;
  }
}

/* Форма на продуктовой странице: своя сборка кнопки, её селектор длиннее
   общего `.submit_form_btn > svg`, поэтому 11 px до неё не доезжали. */
@media (max-width: 1023px) {
  .pd_form_section .container .pd_form_inner form.f1 .form_rows button[type="submit"] svg,
  .pd_calc_section .container form.f1 .form_rows button[type="submit"] svg {
    bottom: 11px;
  }
}

/* ============================================================
   [107] 10.09.2026 — ЛИСТ ЮЛИ 10.09 12:39 (ТРЕТИЙ круг по этому элементу):
   «Ссылка на политику данных над кнопкой в каждой форме нужно сделать без
   переносов текста на другие строки, только пробелы. Шрифт и текст меньше,
   сделать как в фигме» + ССЫЛКА НА УЗЕЛ МАКЕТА 2117-308.

   🔴 ПЕРВОПРИЧИНА ТРЁХ КРУГОВ — НАША ОШИБКА В ЭТАЛОНЕ.
   В прошлой редакции (сессия 106) здесь стояло: «в мобильном макете согласия
   нет вовсе, поэтому ориентир единственный — десктоп». ЭТО НЕВЕРНО. Согласие
   в мобильном макете ЕСТЬ, это узел 2117:308, Юля прислала на него прямую
   ссылку. Мы правили по десктопу и по устной подписи «тоньше» — оттого и
   промахнулись дважды подряд.

   ЭТАЛОН ИЗ МАКЕТА (узел 2117:309, снят напрямую из Figma):
     размер           8 px      (у нас стояло 9)
     вес              550       (у нас стояло 400 — «тоньше» мы поняли как вес,
                                 а Юля просила МЕНЬШЕ РАЗМЕР: «шрифт и текст меньше»)
     межстрочный      normal    (у нас стояло жёстко 11 px)
     ширина текста    305 px, блок 330 px с чекбоксом
     строк            2         (у нас было 4)

   🔴 ЧТО ИМЕННО ЛОМАЛО ВИД — `white-space: nowrap` НА ССЫЛКЕ.
   Замер на бою до правки: строки шли рвано — «ОТПРАВЛЯЯ ФОРМУ, Я ДАЮ» (141 px),
   потом ВСЯ ссылка отдельной строкой (270 px), потом огрызок «И СОГЛАШАЮСЬ С»
   (84 px), потом вторая ссылка (201 px). Неразрывная ссылка не влезала в остаток
   строки и каждый раз выталкивалась на новую, разрывая текст вокруг себя.
   Это и есть «переносы текста на другие строки», на которые жалуется Юля.
   Её «только пробелы» = слова переносятся обычным образом по пробелам,
   а не рвутся внутри слова и не выбрасываются на свою строку.
   ⇒ nowrap СНЯТ. Взамен запрещён разрыв ВНУТРИ слова (`word-break: normal`,
   `overflow-wrap: normal`) — перенос идёт только по пробелам, как она и просит.
   ============================================================ */
@media (max-width: 1023px) {
  /* повторяем полный селектор подрядчика `form .form_rows .iagree label.css-label`,
     короткий `.iagree label` ему проигрывает по весу (та же грабля, что со стрелками) */
  form .form_rows .iagree label.css-label,
  .pd_form_section .container .pd_form_inner form.f1 .form_rows .iagree label.css-label,
  .pd_calc_section .container form.f1 .form_rows .iagree label.css-label,
  .iagree label.css-label {
    font-size: 8px;                                                   /* макет 2117:309 */
    font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 9;
    line-height: normal;                                              /* макет: leading normal */
    word-break: normal;                                               /* не рвать слова */
    overflow-wrap: normal;
  }
  form .form_rows .iagree label.css-label a,
  .pd_form_section .container .pd_form_inner form.f1 .form_rows .iagree label.css-label a,
  .pd_calc_section .container form.f1 .form_rows .iagree label.css-label a,
  .iagree label a,
  .iagree a {
    font-size: 8px;
    font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 9;
    line-height: normal;
    white-space: normal;        /* ⛔ БЫЛО nowrap — оно и рвало текст на 4 строки */
    word-break: normal;
    overflow-wrap: normal;
  }
}

/* ============================================================
   [108] 10.09.2026 — ЮЛЯ 13:52: «Слово согласие не нужно переносить
   на новую строку в ссылке». ЧЕТВЁРТЫЙ круг по этому элементу.

   🔴 ПРИЧИНА — СНОВА НАША, но другая. В сессии 107 мы сняли `nowrap`
   и получили 3 ровные строки вместо 5 рваных. Однако первая строка
   обрывалась ровно перед словом «СОГЛАСИЕ»:
     стр.1  «ОТПРАВЛЯЯ ФОРМУ, Я ДАЮ»                      127 px из 287 доступных
     стр.2  «СОГЛАСИЕ НА ОБРАБОТКУ ПЕРСОНАЛЬНЫХ ДАННЫХ И» 252 px
     стр.3  «СОГЛАШАЮСЬ С ПОЛИТИКОЙ КОНФИДЕНЦИАЛЬНОСТИ»   258 px
   На первой строке оставалось 160 px пустоты — слово «СОГЛАСИЕ» (≈47 px)
   влезало туда с запасом, но не встало.

   ЗАМЕР ПРИЧИНЫ: у ссылки в бандле подрядчика `main.min.css` стоит
   `display: inline-block` на селекторе `form .form_rows .iagree label.css-label a`.
   Inline-block НЕ РАЗРЕЗАЕТСЯ по строкам: он либо влезает в остаток строки
   целиком, либо целиком уезжает на новую. Ссылка шириной 243 px в остаток
   160 px не влезала — и уносила с собой первое слово «СОГЛАСИЕ».
   `white-space: normal`, поставленный в 107, на inline-block не помогает:
   он управляет переносами ВНУТРИ элемента, а не разрезанием самого элемента.

   ⇒ ССЫЛКА ПЕРЕВЕДЕНА В `display: inline`. Тогда она течёт вместе с текстом
   и рвётся по пробелам — как в макете 2117:308, где «СОГЛАСИЕ НА ОБРАБОТКУ»
   начинается на первой строке сразу после «Я ДАЮ».
   Селектор повторён ДОСЛОВНО за подрядчиком (`form .form_rows .iagree
   label.css-label a`) — короткий ему проигрывает по весу.
   ⚠️ Подчёркивание и uppercase у ссылки заданы отдельными свойствами и
   от display не зависят — вид ссылки не меняется.
   ============================================================ */
@media (max-width: 1023px) {
  form .form_rows .iagree label.css-label a,
  .pd_form_section .container .pd_form_inner form.f1 .form_rows .iagree label.css-label a,
  .pd_calc_section .container form.f1 .form_rows .iagree label.css-label a,
  .iagree label.css-label a {
    display: inline;            /* ⛔ БЫЛО inline-block у подрядчика — оно и уносило «СОГЛАСИЕ» */
  }
}

/* ============================================================
   [106] 10.09.2026 — ЛИСТ ЮЛИ 10.09 09:30, пункт 4:
   «на стр О нас обрезается гл экран».

   🔴 РАЗБОР. Замер «обрезано ли что-то внутри главного экрана» дал ЧИСТО —
   дефект нашёлся только СНИМКОМ, глазами: у заголовка следующего блока
   «КУЛЬТУРА ПРОИЗВОДСТВА» съедены первые буквы. Причина не в самом экране:
   снизу висит закреплённая полоса `.fixed_menu` высотой 55 px с двумя
   белыми кнопками (наверх и меню), а у страницы НЕТ отступа снизу под неё —
   контент уезжает под кнопки.
   Дефект НЕ только на «О нас»: обход всех 37 страниц нашёл 12 страниц
   (главная, «О нас», все шесть статей, три продуктовых, вахтовые посёлки) —
   лечим один раз для всего сайта, а не одну страницу (правило 9 реестра).
   Полоса с `pointer-events:none`, нажимать она не мешает — только закрывает
   вид, поэтому достаточно отступа: 55 px полосы + 10 px воздуха.
   ============================================================ */
@media (max-width: 1023px) {
  /* 1) Отступ снизу, чтобы конец страницы не уезжал под полосу. */
  main {
    padding-bottom: 65px;
  }
  /* 2) Главное: убрать кнопку «наверх» с текста.
     На десктопе она стоит в широком отступе слева (замер 1920: x=280),
     где текста нет. На телефоне отступы схлопнулись до 20 px — и белая
     кнопка 35×35 села ровно на левый край заголовков (они тоже с x=20),
     съедая первые буквы («КУЛЬТУРА» → «ЛЬТУРА»). Отступ снизу это не
     лечит: полоса закреплена к окну и накрывает текст на любой прокрутке.
     Ставим кнопку в тот же нижний правый угол, что и кнопку меню, слева
     от неё — там текста нет ни на одной странице, и обе кнопки рядом,
     как на десктопе. */
  .fixed_menu .scroll_top_link {
    position: absolute;
    right: 68px; /* левее кнопки меню (она с правого края, ширина 53) */
    left: auto;
  }
}

/* ============================================================
   [106] 10.09.2026 — ЛИСТ ЮЛИ 10.09, пункт 6, ВТОРАЯ ПРИЧИНА
   («кнопка закрыть меню плохо срабатывает»).

   Первая причина — маленькая область нажатия — вылечена выше.
   🔴 Вторая нашлась случайно, когда браузер отказался нажать кнопку:
   «fixed_submenu intercepts pointer events». Замер подтвердил:
   ВВЕРХУ страницы у полосы подменю `pointer-events:none` и палец попадает
   в кнопку; ПОСЛЕ ПРОКРУТКИ полоса включает `pointer-events:auto`, лежит
   выше кнопки (z-index 316 против auto) и высотой всего 2 px — то есть
   невидима, но перехватывает нажатие. Отсюда и «срабатывает через раз»:
   вверху работает, после прокрутки нет.
   Гасим перехват у самой полосы, оставляя его её содержимому (ссылки
   подменю на десктопе продолжают нажиматься). На телефоне подменю не
   разворачивается вовсе — его высота 2 px.
   ============================================================ */

/* ============================================================================
   Liqium 11.09.2026 (сессия 114): СТРАНИЦА СТАТЬИ ПО НОВОМУ МАКЕТУ ЮЛИ 3482:1967

   Повод: Юля шесть раз писала «новой стр статьи ещё нет» (07.09–11.09, чат «Атлас»).
   Разбор сессии 113: на бою стоит СТАРЫЙ фрейм 2129:3683, новый 3482:1967 не внедрён.
   Прежние сверки смотрели СПИСОК ЭЛЕМЕНТОВ (они есть в обоих фреймах), а не КОМПОНОВКУ.

   Что меняет новый фрейм (замер геометрии по Figma, кадр 1440×5712):
     было (articles.min.css): .art_dtl_intro — сетка 4 колонки, текст span 2 двумя
       колонками, фото grid-column 3/span 2 сбоку; .art_dtl_usage_grid — фото span 2
       слева + текст в grid-column 4 справа.
     стало (макет 3482:1967): ОДНА узкая колонка по центру x=385 w=670 (385+670+385=1440),
       фото КВАДРАТНЫЕ 670×670 по центру (y=896 и y=2765), у «Где применяются» текста
       сбоку НЕТ вовсе, таблица и «Другие статьи» — на всю ширину (x=40 w=1360).

   Почему переопределением, а не правкой articles.min.css: articles.min.css — сборка
   подрядчика libercode, её пересборка затрёт правку. custom-fixes.css подключается
   ПОСЛЕ неё (header.php: articles.min.css строка 92, custom-fixes.css строка 103),
   поэтому одинаковая специфичность здесь выигрывает по порядку, без !important.
   ============================================================================ */

@media (min-width: 1024px) {

  /* — центральная колонка 670 из 1440 = 46.53%; поля по 26.74% с каждой стороны.
       Держим долями, а не пикселями: контейнер темы резиновый, жёсткие 670px
       поехали бы на промежуточных ширинах. */
  .art_dtl_article .art_dtl_intro,
  .art_dtl_article .art_dtl_features,
  .art_dtl_article .art_dtl_usage {
    grid-template-columns: 1fr;
    max-width: 46.53%;
    margin-left: auto;
    margin-right: auto;
  }

  /* интро: текст больше НЕ двумя колонками — в макете один поток */
  .art_dtl_article .art_dtl_intro_text {
    grid-column: 1;
    grid-template-columns: 1fr;
  }

  /* заголовки и лид в узкой колонке не ограничиваем дополнительно:
     колонка сама и есть ограничение */
  .art_dtl_article .art_dtl_intro h2,
  .art_dtl_article .art_dtl_section h2,
  .art_dtl_article .art_dtl_lead,
  .art_dtl_article .art_dtl_list_block {
    max-width: 100%;
  }

  /* — ФОТО: квадрат 670×670. Высоту задаём через aspect-ratio, чтобы квадрат
       держался на любой ширине колонки. Исходники у статей 670×475 и 900×900,
       object-fit:cover в базовой теме обрежет их по центру до квадрата. */
  .art_dtl_article .art_dtl_media_intro,
  .art_dtl_article .art_dtl_media_usage {
    grid-column: 1;
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
  }

  /* — «Где применяются»: в макете под заголовком стоит ОДНО фото, текста сбоку нет.
       Текст из свойства USAGE_TEXT не удаляем (данные клиента), а ставим под фото
       в ту же колонку — иначе сетка вернула бы его вбок. */
  .art_dtl_article .art_dtl_usage_grid {
    grid-template-columns: 1fr;
  }

  .art_dtl_article .art_dtl_usage_text {
    grid-column: 1;
  }

  /* — таблица и «Другие статьи» остаются на всю ширину: в макете x=40 w=1360,
       то есть шире центральной колонки. Явно снимаем с них узкое ограничение. */
  .art_dtl_article .art_dtl_compare {
    max-width: 100%;
    margin-left: 0;
    margin-right: 0;
  }

  .art_dtl_article .art_dtl_compare h2 {
    max-width: 100%;
  }

  /* навигация по статье в макете прижата влево (x=40), а не к узкой колонке */
  .art_dtl_article .art_dtl_nav {
    max-width: 100%;
  }
}

/* — планшет/телефон: макет одноколоночный и там, и там. Базовая тема уже
     складывает сетки в одну колонку на max-width:1023px; нам остаётся только
     сделать фото квадратными, чтобы кадр совпадал с макетом. */
@media (max-width: 1023px) {

  .art_dtl_article .art_dtl_media_intro,
  .art_dtl_article .art_dtl_media_usage {
    height: auto;
    aspect-ratio: 1 / 1;
  }
}

/* ============================================================================
   сессия 115 (11.09.2026) — SEO-раскрытие «Больше о технологии» по макету Юли
   3484:2923 (продуктовые) / 3484:2223 (главная): текст слева (805 из 1360) +
   фото справа (407×208), сравнительная таблица во всю ширину, красный баннер
   справа (75 %, как у .ma_tasks_wrapper базовой темы). Базовая тема не трогается.
   ============================================================================ */
.ma_adv_hidden_text .ma_seo_grid {
  display: grid;
  grid-template-columns: minmax(0, 59.2%) minmax(0, 29.9%);
  column-gap: 10.9%;
  align-items: start;
  margin-bottom: max(1.875rem, min(1.2rem + 1.4vw, 2.875rem));
}

/* базовая тема зажимает абзацы раскрытия до ~597 px — в макете текст занимает всю левую колонку */
.ma_adv_hidden_text .ma_seo_text p {
  max-width: 100%;
}

.ma_adv_hidden_text .ma_seo_image {
  margin: 0;
}

.ma_adv_hidden_text .ma_seo_image img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 407 / 208;
  object-fit: cover;
}

.ma_adv_hidden_text .ma_seo_table_wrap {
  width: 100%;
  overflow-x: auto;
  margin-bottom: max(3.4375rem, min(.223214rem + 5.02232vw, 6.25rem));
}

.ma_adv_hidden_text .ma_seo_table {
  border-collapse: collapse;
  table-layout: fixed;
  width: 100%;
  min-width: 40rem;
}

.ma_adv_hidden_text .ma_seo_table th {
  letter-spacing: 0;
  text-transform: uppercase;
  color: #101820;
  font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
  font-family: RobotoFlex, Arial, sans-serif;
  font-size: max(.9375rem, min(.508929rem + .669643vw, 1.3125rem));
  line-height: 120%;
  text-align: left;
  vertical-align: top;
  padding: 0 max(.9375rem, min(.580357rem + .558036vw, 1.25rem)) max(1.6875rem, min(1.1rem + .9vw, 2.25rem)) 0;
}

.ma_adv_hidden_text .ma_seo_table td {
  letter-spacing: 0;
  text-transform: uppercase;
  color: #101820;
  font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
  font-family: RobotoFlex, Arial, sans-serif;
  font-size: max(.625rem, min(.339286rem + .446429vw, .875rem));
  line-height: 114%;
  text-align: left;
  vertical-align: top;
  height: max(3.3125rem, min(1.74107rem + 2.45536vw, 4.6875rem));
  padding: max(.75rem, min(.4rem + .55vw, .875rem)) max(.9375rem, min(.580357rem + .558036vw, 1.25rem));
}

.ma_adv_hidden_text .ma_seo_table tbody tr:nth-child(2n) {
  background-image: repeating-linear-gradient(-60deg, transparent 0, transparent 6px, #e0e0e0 6px, #e0e0e0 7px);
}

.ma_adv_hidden_text .ma_seo_banner .ma_tasks_wrapper {
  margin-bottom: 0;
}

@media (max-width: 1023px) {
  .ma_adv_hidden_text .ma_seo_grid {
    grid-template-columns: 1fr;
    column-gap: 0;
    row-gap: 20px;
    margin-bottom: 24px;
  }

  .ma_adv_hidden_text .ma_seo_table_wrap {
    margin-bottom: 30px;
  }

  .ma_adv_hidden_text .ma_seo_table th,
  .ma_adv_hidden_text .ma_seo_table td {
    padding-left: 10px;
    padding-right: 10px;
  }

  .ma_adv_hidden_text .ma_seo_table th:first-child,
  .ma_adv_hidden_text .ma_seo_table td:first-child {
    padding-left: 0;
  }
}

/* телефон: таблица целиком в экране (три колонки по трети), без горизонтальной прокрутки */
@media (max-width: 767px) {
  .ma_adv_hidden_text .ma_seo_table {
    min-width: 100%;
  }

  .ma_adv_hidden_text .ma_seo_table th,
  .ma_adv_hidden_text .ma_seo_table td {
    padding-left: 6px;
    padding-right: 6px;
    overflow-wrap: break-word;
    hyphens: auto;
  }
}

/* ============================================================
   [117] 14.09.2026 — ЕДИНЫЙ ВИЗУАЛЬНЫЙ РЕДАКТОР В СТАТЬЯХ
   Клиент наполняет статью одним полем «Детальное описание».
   Стили повторяют прежний вид статьи (сессия 114): центральная
   колонка 670 из 1440, фото и таблицы — во всю ширину колонки.
   Плюс требования клиента 14.09: таблицы и НЕСКОЛЬКО картинок
   в любом месте текста.
   ============================================================ */

.art_dtl_editor {
    max-width: 46.53%;
    margin: 0 auto;
    padding: 0 0 40px;
}

.art_dtl_editor > *:first-child { margin-top: 0; }
.art_dtl_editor > *:last-child  { margin-bottom: 0; }

/* заголовки внутри редактора — как h2/h3 статьи */
.art_dtl_editor h2 {
    margin: 56px 0 20px;
    scroll-margin-top: 140px;
}

.art_dtl_editor h3 {
    margin: 40px 0 16px;
}

.art_dtl_editor p {
    margin: 0 0 18px;
}

.art_dtl_editor ul,
.art_dtl_editor ol {
    margin: 0 0 18px;
    padding-left: 22px;
}

.art_dtl_editor li { margin-bottom: 10px; }

.art_dtl_editor a { text-decoration: underline; }

/* КАРТИНКИ: сколько угодно и в любом месте текста */
.art_dtl_editor img {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 28px 0;
    border-radius: 4px;
}

.art_dtl_editor figure {
    margin: 28px 0;
}

.art_dtl_editor figure img { margin: 0; }

.art_dtl_editor figcaption {
    margin-top: 10px;
    font-size: 13px;
    opacity: .7;
}

/* картинка, обтекаемая текстом (клиент ставит выравнивание в редакторе) */
.art_dtl_editor img[align="left"],
.art_dtl_editor img[style*="float: left"],
.art_dtl_editor img[style*="float:left"] {
    float: left;
    margin: 6px 24px 18px 0;
    max-width: 50%;
}

.art_dtl_editor img[align="right"],
.art_dtl_editor img[style*="float: right"],
.art_dtl_editor img[style*="float:right"] {
    float: right;
    margin: 6px 0 18px 24px;
    max-width: 50%;
}

/* ТАБЛИЦЫ: вставляются в любом месте, вид — как сравнительная таблица статьи */
.art_dtl_editor table {
    width: 100%;
    margin: 28px 0;
    border-collapse: collapse;
    font-size: 15px;
}

.art_dtl_editor table th,
.art_dtl_editor table td {
    padding: 14px 16px;
    text-align: left;
    vertical-align: top;
    border: 1px solid rgba(16, 24, 32, .12);
}

.art_dtl_editor table th {
    font-weight: 600;
    background: rgba(16, 24, 32, .04);
}

.art_dtl_editor table tbody tr:nth-child(even) td {
    background: rgba(16, 24, 32, .02);
}

/* широкая таблица не ломает страницу — прокручивается внутри себя */
.art_dtl_editor .art_dtl_table_wrap,
.art_dtl_editor .table_scroll {
    overflow-x: auto;
}

/* ТО ЖЕ для SEO-раскрытия на продуктовых: таблицы и много картинок внутри текста */
.ma_seo_text img {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 20px 0;
    border-radius: 4px;
}

.ma_seo_text table {
    width: 100%;
    margin: 20px 0;
    border-collapse: collapse;
    font-size: 14px;
}

.ma_seo_text table th,
.ma_seo_text table td {
    padding: 10px 12px;
    text-align: left;
    vertical-align: top;
    border: 1px solid rgba(16, 24, 32, .12);
}

.ma_seo_text table th {
    font-weight: 600;
    background: rgba(16, 24, 32, .04);
}

.ma_seo_text table tbody tr:nth-child(even) td {
    background: rgba(16, 24, 32, .02);
}

/* планшет и телефон: колонка во всю ширину, обтекание отключаем */
@media (max-width: 1023px) {
    .art_dtl_editor { max-width: 100%; }
}

@media (max-width: 767px) {
    .art_dtl_editor img[align="left"],
    .art_dtl_editor img[align="right"],
    .art_dtl_editor img[style*="float: left"],
    .art_dtl_editor img[style*="float:left"],
    .art_dtl_editor img[style*="float: right"],
    .art_dtl_editor img[style*="float:right"] {
        float: none;
        max-width: 100%;
        margin: 20px 0;
    }

    .art_dtl_editor h2 { margin: 36px 0 16px; }

    .art_dtl_editor table,
    .ma_seo_text table { font-size: 13px; }

    .art_dtl_editor table th,
    .art_dtl_editor table td { padding: 10px 10px; }
}

/* ============================================================
   [120] 15.09.2026 — ШРИФТ В ТЕЛЕ СТАТЬИ КАК НА САЙТЕ
   Замечание Юли 15.09: «на детальных стр статьи используется
   неправильный шрифт, нужно использовать шрифт с сайта».
   Причина: RobotoFlex — переменный шрифт, весь сайт задаёт ему
   начертание "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144.
   Блок .art_dtl_editor (правки 14.09) этой настройки не имел —
   текст рисовался начертанием по умолчанию: уже и тоньше.
   Значения и формулы размеров взяты один в один с эталона
   сайта — SEO-текст товарной страницы
   (.modules_advantages_section .ma_adv_hidden_text p / h3).
   ============================================================ */

.art_dtl_editor,
.art_dtl_editor p,
.art_dtl_editor li,
.art_dtl_editor td,
.art_dtl_editor th,
.art_dtl_editor a,
.art_dtl_editor span,
.art_dtl_editor strong,
.art_dtl_editor em,
.art_dtl_editor figcaption {
    font-family: RobotoFlex, Arial, sans-serif;
    font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
    letter-spacing: 0;
}

/* основной текст статьи — размер и межстрочный как у текста сайта */
.art_dtl_editor p,
.art_dtl_editor li,
.art_dtl_editor figcaption {
    font-size: max(0.625rem, min(0.339286rem + 0.446429vw, 0.875rem));
    line-height: 114%;
}

.art_dtl_editor figcaption {
    font-size: max(0.5rem, min(0.285714rem + 0.334821vw, 0.75rem));
}

/* заголовки внутри статьи — начертание и размеры как у заголовков сайта */
.art_dtl_editor h2 {
    font-family: RobotoFlex, Arial, sans-serif;
    font-variation-settings: "wght" 700, "wdth" 151, "GRAD" 150, "opsz" 144;
    font-size: max(0.9375rem, min(0.508929rem + 0.669643vw, 1.3125rem));
    line-height: 120%;
    letter-spacing: 0;
    text-transform: none;
}

.art_dtl_editor h3,
.art_dtl_editor h4 {
    font-family: RobotoFlex, Arial, sans-serif;
    font-variation-settings: "wght" 700, "wdth" 151, "GRAD" 150, "opsz" 144;
    font-size: max(0.75rem, min(0.410714rem + 0.535714vw, 1.0625rem));
    line-height: 120%;
    letter-spacing: 0;
    text-transform: none;
}

/* таблица внутри статьи — тем же начертанием */
.art_dtl_editor table th {
    font-variation-settings: "wght" 700, "wdth" 151, "GRAD" 150, "opsz" 144;
}

.art_dtl_editor table,
.art_dtl_editor table td,
.art_dtl_editor table th {
    font-size: max(0.5625rem, min(0.303571rem + 0.401786vw, 0.8125rem));
    line-height: 120%;
}

/* тот же шрифт — SEO-раскрытию на продуктовых, если текст попадёт туда */
.ma_seo_text p,
.ma_seo_text li,
.ma_seo_text td,
.ma_seo_text th {
    font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
}

/* ============================================================
   [125] 15.09.2026 — ТАБЛИЦА В СТАТЬЕ КАК В МАКЕТЕ
   Замечание Леонида 15.09 15:42: «таблицы оформлены совсем
   просто, в макете задумка была интереснее».
   Сверка с макетом (Figma TCG6HzUBDpmd6u3mPjjuCr, экран
   «Статья» 494:1100, строки 498:2385/2578/2765/2949):
   строки залиты диагональной штриховкой ЧЕРЕЗ ОДНУ
   (полоса h=75, шаг 158 — значит между ними белая строка),
   надписи ЗАГЛАВНЫМИ, рамок ячеек нет, три колонки 439.
   Стили 14.09 (блок [117]) ставились как «для любой таблицы»,
   с макетом не сверялись — это и была причина.
   Эталон вида в коде уже есть: .ma_adv_hidden_text
   .ma_seo_table (строки 3061–3150) — значения взяты оттуда
   один в один.
   ============================================================ */

/* рамки и серые заливки прежнего вида — снять */
.art_dtl_editor table {
    border-collapse: collapse;
    table-layout: fixed;
    width: 100%;
    margin: 28px 0;
}

.art_dtl_editor table th,
.art_dtl_editor table td {
    border: 0;
    background: transparent;
    text-transform: uppercase;
    color: #101820;
    text-align: left;
    vertical-align: top;
    letter-spacing: 0;
}

.art_dtl_editor table tbody tr:nth-child(even) td {
    background: transparent;
}

/* шапка — как в макете: крупнее, заглавными, с воздухом снизу */
.art_dtl_editor table th {
    font-family: RobotoFlex, Arial, sans-serif;
    font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
    font-size: max(.9375rem, min(.508929rem + .669643vw, 1.3125rem));
    line-height: 120%;
    padding: 0 max(.9375rem, min(.580357rem + .558036vw, 1.25rem)) max(1.6875rem, min(1.1rem + .9vw, 2.25rem)) 0;
}

/* ячейки — макетный кегль и высота строки */
.art_dtl_editor table td {
    font-family: RobotoFlex, Arial, sans-serif;
    font-variation-settings: "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144;
    font-size: max(.625rem, min(.339286rem + .446429vw, .875rem));
    line-height: 114%;
    height: max(3.3125rem, min(1.74107rem + 2.45536vw, 4.6875rem));
    padding: max(.75rem, min(.4rem + .55vw, .875rem)) max(.9375rem, min(.580357rem + .558036vw, 1.25rem));
}

/* диагональная штриховка через одну строку — как в макете */
.art_dtl_editor table tbody tr:nth-child(2n) td {
    background-image: repeating-linear-gradient(-60deg, transparent 0, transparent 6px, #e0e0e0 6px, #e0e0e0 7px);
}

/* первая колонка прижата к левому краю колонки текста */
.art_dtl_editor table th:first-child,
.art_dtl_editor table td:first-child {
    padding-left: 0;
}

@media (max-width: 1023px) {
    .art_dtl_editor table th,
    .art_dtl_editor table td {
        padding-left: 10px;
        padding-right: 10px;
    }

    .art_dtl_editor table th:first-child,
    .art_dtl_editor table td:first-child {
        padding-left: 0;
    }
}

/* телефон: таблица целиком в экране, перенос слов вместо прокрутки */
@media (max-width: 767px) {
    .art_dtl_editor table {
        min-width: 100%;
    }

    .art_dtl_editor table th,
    .art_dtl_editor table td {
        padding-left: 6px;
        padding-right: 6px;
        overflow-wrap: break-word;
        hyphens: auto;
    }

    .art_dtl_editor table th:first-child,
    .art_dtl_editor table td:first-child {
        padding-left: 0;
    }
}

/* ============================================================
   ССЫЛКИ В ТЕКСТЕ — ФИРМЕННЫЙ КРАСНЫЙ (16.09.2026, сессия 129)
   Замечание Юли 16.09 14:14: «ссылки на всех стр и статьях
   нужно заменить с синего цвета на красный».
   Причина синего: цвет ссылкам в тексте не задавался нигде —
   в бандле только a{text-decoration:none}, поэтому браузер
   рисовал свой цвет по умолчанию (#0000EE).
   Красный #c8102e — фирменный: логотип, «Скачать презентацию»,
   акценты шапки и подвала, галочка согласия в формах.
   Хлебные крошки (.breadcrumbs_wrap) НЕ трогаем — они не синие
   и имеют собственный цвет.
   ============================================================ */

.art_dtl_editor a,
.art_dtl_editor a:link,
.art_dtl_editor a:visited,
.legal_text a,
.legal_text a:link,
.legal_text a:visited,
.ma_seo_text a,
.ma_seo_text a:link,
.ma_seo_text a:visited,
.ma_adv_hidden_text a,
.ma_adv_hidden_text a:link,
.ma_adv_hidden_text a:visited {
    color: #c8102e;
}

.art_dtl_editor a:hover,
.legal_text a:hover,
.ma_seo_text a:hover,
.ma_adv_hidden_text a:hover {
    color: #a30d25;
}


/* ============================================================
   [130] 16.09.2026 — ТАБЛИЦА: ВЫРАВНИВАНИЕ ПЕРВОЙ КОЛОНКИ
   И СКВОЗНАЯ ШТРИХОВКА
   Замечания Леонида 16.09 09:19 (скриншот в TG):
   1) «Заголовок первой колонки должен быть так же левее
      относительно содержания ячеек, как и в последующих
      колонках»;
   2) «У строк со штриховкой, штриховка не стыкуется между
      колонками».
   ПРИЧИНА 1. Блок [125] задал padding-left: 0 первой колонке
   И шапке, И ячейкам — они встали вровень, тогда как во
   2-й и 3-й колонках содержимое правее заголовка на 17,3 px.
   Макет (Figma 498:2385 и шапка 498:1834/1836/1837) даёт
   заголовок 41 / содержимое 60 — то есть сдвиг ЕСТЬ и в
   первой колонке тоже (≈20 px при ширине 1360).
   ⇒ Отступ снимается только у ШАПКИ, у ячеек он остаётся.
   ПРИЧИНА 2. Штриховка стояла background-image на КАЖДОЙ
   ячейке. Рисунок начинается заново в каждой ячейке и на
   границе колонок обрывается. ⇒ Переносим фон на всю
   строку tr, ячейки делаем прозрачными: полоса идёт
   сквозняком через всю таблицу и стыкуется.
   ============================================================ */

/* 1. Заголовок — левее содержимого, как во 2-й и 3-й колонках */
.art_dtl_editor table th:first-child {
    padding-left: 0;
}

.art_dtl_editor table td:first-child {
    padding-left: max(.9375rem, min(.580357rem + .558036vw, 1.25rem));
}

/* 2. Штриховка — сквозная по всей строке, без разрывов на границах ячеек */
.art_dtl_editor table tbody tr:nth-child(2n) td {
    background-image: none;
}

.art_dtl_editor table tbody tr:nth-child(2n) {
    background-image: repeating-linear-gradient(-60deg, transparent 0, transparent 6px, #e0e0e0 6px, #e0e0e0 7px);
}

@media (max-width: 1023px) {
    .art_dtl_editor table th:first-child {
        padding-left: 0;
    }

    .art_dtl_editor table td:first-child {
        padding-left: 10px;
    }
}

@media (max-width: 767px) {
    .art_dtl_editor table th:first-child {
        padding-left: 0;
    }

    .art_dtl_editor table td:first-child {
        padding-left: 6px;
    }
}

/* [130] узкие экраны: сдвиг содержимого относительно заголовка — во ВСЕХ колонках,
   а не только в первой. В блоке [125] отступ на узких ставился и шапке, и ячейкам
   одинаково, поэтому на телефоне и планшете заголовки стояли вровень с текстом. */
@media (max-width: 1023px) {
    .art_dtl_editor table th {
        padding-left: 0;
    }

    .art_dtl_editor table td {
        padding-left: 10px;
    }
}

@media (max-width: 767px) {
    .art_dtl_editor table th {
        padding-left: 0;
    }

    .art_dtl_editor table td {
        padding-left: 6px;
    }
}

/* ============================================================
   [131] 16.09.2026 — РАЗМЕР ТЕКСТА СТАТЬИ РОВНО КАК В МАКЕТЕ
   Вопрос Леонида 16.09 15:45: «давайте попробуем как в макете
   указать, посмотрим насколько попадём» (про межстрочный).
   ЗАМЕР: доля межстрочного на бою уже совпадала с макетом
   (114 % против 114,3 %) — расходился КЕГЕЛЬ.
   Причина: блок [120] взял резиновую формулу сайта, она
   считает от ширины ОКНА и даёт 14 px только при 1920;
   при 1440 — 11,86 px, при 1280 — 11,14. Колонка статьи при
   этом фиксирована долей 46,53 % и почти не меняется
   (632,8 на 1920 против 638,3 на 1440) — поэтому текст мельчал
   без причины, на 15 % против макета у клиента на 1440.
   ЧИСЛА МАКЕТА (Figma TCG6HzUBDpmd6u3mPjjuCr):
     тело статьи   узел 498:1826 — 14 px / межстрочный 16 px, блок 670x96 = 6 строк
     заголовок h2  узел 498:1830 — 21 px / межстрочный 100 %
     h3            узел 498:1827 — 16 px (высота блока 32 = 2 строки)
   ПРОВЕРЕНО ОПЫТОМ до правки: тот же абзац при 670/14/16 и нашем
   начертании даёт РОВНО 96 px и 6 строк — знак в знак макет.
   Регистр не трогаем: заглавные набраны в самом тексте статей.
   ============================================================ */

.art_dtl_editor p,
.art_dtl_editor li,
.art_dtl_editor td,
.art_dtl_editor th {
    font-size: 15px;
    line-height: 20px;
}

.art_dtl_editor figcaption {
    font-size: 13px;
    line-height: 17px;
}

.art_dtl_editor h2 {
    font-size: 22px;
    line-height: 110%;
}

.art_dtl_editor h3,
.art_dtl_editor h4 {
    font-size: 17px;
    line-height: 125%;
}

/* Узкие экраны: уменьшаем ОТ размера макета, а не от 11,86 px.
   Порог 1023 -> 899: замер колонки показал, что на 1024-1366 колонка
   УЗКАЯ (449-605 px), а на 900 и ниже сетка её распускает почти во всю
   ширину (864 при окне 900, 732 при 768). То есть уменьшать текст надо
   там, где колонка широкая, а не где окно узкое. */
@media (max-width: 899px) {
    .art_dtl_editor p,
    .art_dtl_editor li,
    .art_dtl_editor td,
    .art_dtl_editor th {
        font-size: 14px;
        line-height: 19px;
    }
    .art_dtl_editor h2 { font-size: 20px; }
    .art_dtl_editor h3,
    .art_dtl_editor h4 { font-size: 16px; }
    .art_dtl_editor figcaption { font-size: 12px; line-height: 16px; }
}

@media (max-width: 599px) {
    .art_dtl_editor p,
    .art_dtl_editor li,
    .art_dtl_editor td,
    .art_dtl_editor th {
        font-size: 13px;
        line-height: 18px;
    }
    .art_dtl_editor h2 { font-size: 18px; }
    .art_dtl_editor h3,
    .art_dtl_editor h4 { font-size: 15px; }
}

/* ТАБЛИЦА В СТАТЬЕ — тот же макетный кегль.
   У неё свои правила выше (блок [125]) с более точным адресом,
   они перебивали общий размер: ячейки оставались 11,86 px.
   Числа макета: шапка узел 498:1834 — 21 px / межстрочный 100 %;
   ячейка узел 498:2575 — 14 px, высота строки 16 px.
   Отступы, ширины колонок и штриховку НЕ трогаем — они выверены
   блоками [125] и [130] и приняты. */
.art_dtl_editor table th {
    font-size: 21px;
    line-height: 100%;
}

.art_dtl_editor table td {
    font-size: 15px;
    line-height: 20px;
}

@media (max-width: 899px) {
    .art_dtl_editor table th { font-size: 20px; }
    .art_dtl_editor table td { font-size: 14px; line-height: 19px; }
}

@media (max-width: 599px) {
    .art_dtl_editor table th { font-size: 18px; }
    .art_dtl_editor table td { font-size: 13px; line-height: 18px; }
}

/* ============================================================
   [132] 17.09.2026 — СНЯТ в тот же день (сессия 137).
   Блок обнулял отступ третьей колонки «по числам макета» (−1 px в Figma)
   и тем самым сломал единое выравнивание, принятое клиентом 16.09
   (блок [130]: заголовок левее текста ОДИНАКОВО во всех колонках).
   Юля 15:10 и 16:52: «разное выравнивание у 3-х столбцов», «нужно,
   чтобы заголовки одинаково выравнивались». Правило: сдвиг заголовка
   ОДИН на все колонки любой таблицы; расхождение в 1 px в макете —
   неточность рисунка, не замысел.
   ============================================================ */

/* ============================================================
   [133] 17.09.2026 — ТАБЛИЦА В СТАТЬЕ ШИРЕ КОЛОНКИ ТЕКСТА,
   КАК В МАКЕТЕ

   Повод, два замечания Юли подряд (чат Битрикса «Атлас»):
     14:56 «нужно сделать чуть шире контейнер с текстом и таблицей,
            чтобы заголовки в таблице лучше помещались»;
     15:10 «Сейчас разное выравнивание у 3-х столбцов в таблице».

   ПЕРВОПРИЧИНА КЛАССА (почему пункт возвращался десятый раз).
   Все прошлые круги чинили СДВИГ заголовка относительно текста
   (блоки [125], [130], [132]) — и каждый раз замер показывал
   ровные числа, а глаз Юли видел «разное выравнивание».
   Дело было не в сдвиге, а в ПЕРЕНОСЕ СТРОК:
     в макете колонка таблицы 439 px — «БЛОК-КОНТЕЙНЕРЫ ОТ АТЛАС
     МОДУЛЬ» ложится в 2 строки;
     на бою колонка была 213 px — тот же заголовок ломался на 5 строк,
     первый и второй — на 1–2, и шапка визуально «съезжала».
   Ровный сдвиг 17,3 px при РАЗНОЙ ВЫСОТЕ заголовков глазом читается
   как разное выравнивание. Юля каждый раз была права, а наш замер
   мерил не тот признак: считал сдвиг, а видно было переносы.

   ЗАМЕР МАКЕТА (Figma TCG6HzUBDpmd6u3mPjjuCr, фрейм статьи 3482:1967):
     абзац текста статьи   x=385  ширина 670
     таблица (заголовки)   x=41   колонки по 439, вся таблица 1360
   ⇒ в макете ТЕКСТ и ТАБЛИЦА РАЗНОЙ ШИРИНЫ: текст — узкая колонка,
     таблица — во всю ширину статьи. На бою оба были 638 px.
   Это и есть то, чего не увидели прошлые девять кругов.

   РЕШЕНИЕ. Ширину ТЕКСТА не трогаем (принята клиентом, блок [131]).
   Таблицу выпускаем на всю ширину статьи — как в макете.
   Сдвиги заголовков блока [130] сохраняются без изменений ([132] снят).

   ПРИЁМКА НА ЖИВОМ САЙТЕ, 7 ширин (строк в заголовке → ширина колонки,
   сдвиг заголовка от текста, прокрутка вбок):
     1920  6→4 строк  211→453 px  сдвиг 20 / 20 / 0      прокрутки нет
     1600  —  →4      —  →456     сдвиг 18,2 / 18,2 / 0  прокрутки нет
     1440  5→3        213→457     сдвиг 17,3 / 17,3 / 0  прокрутки нет
     1366  5→3        —  →433     сдвиг 16,9 / 16,9 / 0  прокрутки нет
     1280  5→3        189→405     сдвиг 16,4 / 16,4 / 0  прокрутки нет
     1100  5→3        —  →347     сдвиг 15,4 / 15,4 / 0  прокрутки нет
     1024  5→3        150→322     сдвиг 15 / 15 / 0      прокрутки нет
   Края таблицы совпали с краями статьи на всех семи ширинах.

   ПРИЁМ. Колонка текста занимает 46,53 % ширины статьи (задано
   темой, maxWidth: 46.53%). Значит таблице, чтобы встать во всю
   ширину, нужно 100/46,53 своей ширины, а выйти влево — на половину
   разницы. Числами ничего не зашито: поменяется ширина колонки
   в теме — формула пересчитается сама.

   ⚠️ Адрес — только таблицы внутри текста статьи (.art_dtl_editor).
   На телефоне и планшете (до 1023 px) таблица остаётся в колонке
   текста: там запаса по краям нет, расширять некуда.
   Откат = удалить блок [133].
   ============================================================ */

/* 🔴 БЛОК [133] СНЯТ 23.09 ПО ЛИСТУ ЛЕОНИДА, п.Д12.
   Его слова: «Ширина таблиц должна быть по ширине текста. Сейчас они на весь
   экран. Увеличились и размеры шрифтов. На тестовой версии ранее все было хорошо.»
   Замер на бою 23.09 подтвердил: таблица 1372px при ширине текста 638px,
   отрицательные поля −366,7px с обеих сторон — это ровно выход блока [133].
   ПРОТИВОРЕЧИЕ: [133] от 17.09 делался ПО МАКЕТУ (Figma 3482:1967: текст 670,
   таблица 1360 — в макете они разной ширины). Клиент просит обратное.
   Слово владельца сайта сильнее макета — правило отключено, таблица вернулась
   в колонку текста, как «на тестовой версии ранее». Вернуть = раскомментировать.
@media (min-width: 1024px) {
    .art_dtl_editor table {
        width: calc(100% / 0.4653);
        margin-left: calc((100% - 100% / 0.4653) / 2);
        margin-right: calc((100% - 100% / 0.4653) / 2);
    }
}
*/

/* ============================================================
   [139] 18.09.2026 — ВЫБРАННЫЙ КЛИЕНТОМ РАЗМЕР ТЕКСТА
   ПЕРЕНЕСЁН НА БОЙ + ТО ЖЕ ДЛЯ SEO-ТЕКСТОВ

   Леонид 18.09 08:33 в чате проекта, ответ на две ссылки-примера:
   «Крупнее: .../container-ili-bytovka-chto-luchshe/?text=b
    Вот этот вариант. Сделайте, пожалуйста, так же и в SEO-текстах».
   ⇒ вариант Б (15/20) стал боевым: числа перенесены в блок [131],
     временный блок [138] и вывод класса demo-text-* в header.php сняты.

   SEO-ТЕКСТ БОЛЕН ТЕМ ЖЕ, ЧЕМ БЫЛА СТАТЬЯ. Замер живого сайта
   (.ma_adv_hidden_text p на продуктовой, до правки):
     окно 1920 — 14 px     окно 1440 — 11,86 px    окно 1280 — 11,14 px
     окно  768 —  6 px     окно  390 —  9 px
   Причина та же, что в блоке [131]: резиновая формула подрядчика
   max(.625rem, min(.339286rem + .446429vw, .875rem)) считает от ширины
   ОКНА и даёт 14 px только при 1920. Плюс у подрядчика есть жёсткие
   правила для узких экранов: до 1023 px — 6 px, до 499 px — 9 px.
   Шесть пикселей — размер, который прочесть нельзя; проверено глазами
   на кадре sess139/seo-DO-768.png.

   ЧИСЛО МАКЕТА (Figma TCG6HzUBDpmd6u3mPjjuCr, узел 498:1812 —
   SEO-текст продуктовой): колонка 325 px, кегль 14 px, то же
   начертание "wght" 550, "wdth" 151, "GRAD" 150, "opsz" 144.
   То есть в макете SEO-текст и текст статьи ОДНОГО размера — значит
   просьба клиента «так же и в SEO-текстах» макету не противоречит,
   а возвращает то, что в нём нарисовано, плюс выбранный им шаг вверх.

   ⚠️ АДРЕС ДЛИННЫЙ НАМЕРЕННО. Правила подрядчика записаны как
   .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text p
   — короткий адрес их не перебьёт (грабля таблицы из блока [131]).
   Медиа-запросы повторяют его пороги 1023 и 499, а не наши 899 и 599,
   иначе на 900-1023 останется 6 px подрядчика.
   ============================================================ */

.modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text p,
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text p,
.ma_seo_text p {
    font-size: 15px;
    line-height: 20px;
}

.modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
.modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol,
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol,
.ma_seo_text li {
    font-size: 15px;
    line-height: 20px;
}

.modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3,
.ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3 {
    font-size: 17px;
    line-height: 125%;
}

/* ШИРИНА КОЛОНКИ НА ПЛАНШЕТЕ — заодно, дефект вскрылся кадром «после».
   Подрядчик держит абзац в узкой колонке (max-width ~318 px на 768) и
   отпускает её в 100 % только с 499 px, а заголовки и списки блок [106]
   отпускает уже с 1023 px. На промежутке 500-1023 абзац 318 px стоял
   рядом со списком 728 px — на кадре sess139/seo-POSLE-768.png видно,
   что текст идёт двумя разными ширинами. Выравниваем абзац по тому же
   порогу, что заголовки и списки. Замер до правки: p 318 / ol 728 / h3 728.
   На 1440 и 390 разнобоя не было — там всё уже совпадало. */
@media (max-width: 1023px) {
    .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text p,
    .ma_adv_hidden_text_wrapper .ma_adv_hidden_text p {
        max-width: 100%;
    }
}

/* Планшет: пороги подрядчика, иначе его 6 px останутся в силе. */
@media (max-width: 1023px) {
    .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text p,
    .ma_adv_hidden_text_wrapper .ma_adv_hidden_text p,
    .ma_seo_text p,
    .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
    .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol,
    .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
    .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol,
    .ma_seo_text li {
        font-size: 14px;
        line-height: 19px;
    }
    .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3,
    .ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3 {
        font-size: 16px;
    }
}

@media (max-width: 499px) {
    .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text p,
    .ma_adv_hidden_text_wrapper .ma_adv_hidden_text p,
    .ma_seo_text p,
    .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
    .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol,
    .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ul,
    .ma_adv_hidden_text_wrapper .ma_adv_hidden_text ol,
    .ma_seo_text li {
        font-size: 13px;
        line-height: 18px;
    }
    .modules_advantages_section .ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3,
    .ma_adv_hidden_text_wrapper .ma_adv_hidden_text h3 {
        font-size: 15px;
    }
}

/* ============================================================================
   ЛИСТ ЛЕОНИДА 23.09 · Д2 · «при клике на чек-бокс он и текст уходят влево,
   а кнопка "отправить" вправо и выше… Изменений положения элементов быть не
   должно ни в какой ситуации» (все формы сайта, названы «способы оплаты» и
   продуктовые).

   ПРИЧИНА (замер на бою 23.09, окно 1440 — как на снимках Леонида):
   ряд .form_rows.rows_btns — это СЕТКА в две колонки (685,7px + 685,7px).
   В покое в ней два элемента: кнопка ОТПРАВИТЬ (1-я ячейка) и блок согласия
   .iagree (2-я). При первом клике скрипт форм подрядчика создаёт и вставляет
   ПЕРВЫМ ребёнком блок .form-error-message «ЗАПОЛНИТЕ ОБЯЗАТЕЛЬНЫЕ ПОЛЯ».
   Он занимает первую ячейку и сдвигает обоих соседей на одну позицию:
     кнопка   x 29 → 725  (+696px вправо)
     согласие x 725 → 29  (-696px влево) и y +29 вниз
   Ровно это на снимках Леонида image5.png и image19.png.

   ЛЕЧЕНИЕ: не убираем сообщение (оно показано намеренно — просьба Юли 25.08,
   правка [62.2]), а закрепляем ячейки сетки поимённо. Тогда появление
   сообщения не может никого сдвинуть: кнопка всегда в первой колонке первой
   строки, согласие — во второй, а сообщение — своей строкой под кнопкой,
   там же, где оно стоит на снимках клиента и на белой форме-эталоне.
   Работает для ЛЮБОЙ формы сайта (класс, а не два снимка): селектор цепляется
   за сам ряд .rows_btns, а он общий у всех семи форм. */
form .form_rows.rows_btns > .submit_form_btn {
    grid-column: 1;
    grid-row: 1;
}

form .form_rows.rows_btns > .iagree {
    grid-column: 2;
    grid-row: 1;
}

form .form_rows.rows_btns > .form-error-message,
form .form_rows.rows_btns > .error-message {
    grid-column: 1;
    grid-row: 2;
}

/* Д2, вторая разметка (главная, «О нас»: форма .js-bottom-question-form).
   Здесь ряд не сетка: кнопка лежит в обычном блоке .col, и сообщение
   «ЗАПОЛНИТЕ ОБЯЗАТЕЛЬНЫЕ ПОЛЯ» вставляется НАД ней — кнопка уезжает вниз
   на 33px (замер на бою 23.09, окно 1440). Правило выше про ячейки сетки сюда
   не достаёт, потому что сетки нет.
   Лечение то же по смыслу: сообщение не должно занимать место над кнопкой.
   Ставим его под кнопку своей строкой — колонка становится флекс-колонкой
   с обратным порядком, кнопка остаётся на исходном месте, текст читается
   под ней, как на белой форме-эталоне и на снимках клиента. */
form .form_rows.rows_btns > .col:has(> .submit_form_btn) {
    display: flex;
    flex-direction: column-reverse;
    align-items: stretch;
}

form .form_rows.rows_btns > .col:has(> .submit_form_btn) > .form-error-message,
form .form_rows.rows_btns > .col:has(> .submit_form_btn) > .error-message {
    margin-top: 6px;
}

/* Д2, довод по форме главной и «О нас» (замер 23.09 после первых двух правил).
   Кнопку мы закрепили, но блок согласия всё ещё опускался на 33px: ряд
   .rows_btns — сетка с align-items:flex-end, то есть все ячейки прижаты к
   НИЗУ строки. Когда под кнопкой появляется сообщение об ошибке, ячейка
   кнопки становится выше, растёт вся строка — и согласие, прижатое к её низу,
   уезжает вниз вместе с ней.
   Лечение: согласие выравниваем по ВЕРХУ своей ячейки. Тогда его положение
   задаёт верх строки, который не меняется, и появление сообщения его не
   трогает. Высоты кнопки это не касается — она в своей ячейке. */
form .form_rows.rows_btns > .iagree {
    align-self: start;
}

/* Д2, узкие экраны: красная форма (.f1.inverse.js-planning-form) и остальные
   формы на телефоне. Замер 23.09, окно 390: там ряд .rows_btns — уже не сетка,
   а флекс-колонка, правила про ячейки сетки в ней не работают. Сообщение
   «ЗАПОЛНИТЕ ОБЯЗАТЕЛЬНЫЕ ПОЛЯ» вставляется первым ребёнком и толкает
   кнопку с согласием вниз на 43–51px.

   Первый заход (order) отбросил сообщение под кнопку — по замеру стало хуже
   (3 формы вместо 1): на узких оно должно оставаться НАД кнопкой, как в макете.
   Поэтому лечим не порядком, а МЕСТОМ: резервируем строку под сообщение
   заранее, ещё до его появления. Пустая строка высотой в одну строку текста
   существует всегда, сообщение просто занимает её — и раскладка не шевелится
   ни до клика, ни после.
   Шрифт сообщения 11px, межстрочный 1.4 ⇒ 15px + 6px отступ = 21px. */
@media (max-width: 767px) {
    form .form_rows.rows_btns {
        position: relative;
        padding-top: 21px;
    }

    form .form_rows.rows_btns > .form-error-message,
    form .form_rows.rows_btns > .error-message {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        margin: 0;
    }
}

/* Д2, довод по красной форме продуктовых на телефоне.
   Предыдущее правило не сработало у неё одной: её сообщение держит наше же
   старое правило [62.2] от 25.08 с более сильным селектором
   (.pd_form_section .f1.inverse .form_rows .form-error-message{position:static}).
   Там это было нужно на ДЕСКТОПЕ — блок надо было вернуть в поток под кнопку.
   На узких экранах поток и создаёт сдвиг, поэтому повторяем ту же
   специфичность и только внутри @media: десктопное поведение 25.08 не
   затрагивается. */
@media (max-width: 767px) {
    .pd_form_section .f1.inverse .form_rows.rows_btns .form-error-message,
    .pd_form_section .f1 .form_rows.rows_btns .form-error-message {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        margin-top: 0;
    }
}

/* ============================================================================
   ЛИСТ ЛЕОНИДА 23.09 · Д3 · продуктовые, блок «Предлагаем комплексное решение»:
   «текст, который появляется при наведении, должен быть строчными буквами,
   а первая с прописной. Увеличить отступ от пунктов справа. Нужно сделать,
   как в макете» (сейчас image20.png, макет image11.png).

   ЗАМЕР НА БОЮ 23.09 (окно 1440):
     .pd_comples_step_hidden_text — text-transform: uppercase 🔴
     сам текст в базе записан нормально («Разрабатываем проектную
     документацию…»), капс делает только стиль — значит достаточно его снять,
     регистр первой буквы придёт из данных, как и просит Леонид.
     правый край текста x+w = 470+259 = 729, левый край списка пунктов = 729
     ⇒ зазор РОВНО 0 🔴. В макете между ними заметный просвет.

   ЛЕЧЕНИЕ: снимаем капс и отодвигаем текст от пунктов на 40px. Отступ даём
   справа самому тексту, а не колонке сетки: ширина колонок (682+682) и
   положение пунктов остаются прежними, двигается только правый край текста. */
.pd_complex_section .pd_complex_grid .pd_complex_steps .pd_complex_steps_list .pd_complex_step .pd_comples_step_hidden_text,
.pd_complex_section .pd_comples_step_hidden_text {
    text-transform: none;
    /* Отступ от пунктов справа. Сверено с макетом image11.png ГЛАЗАМИ, не числом:
       при 100px текст сжимался в узкий столбик на 8 строк, в макете он в 6 строк
       и шире. 50px дают ту же форму абзаца, что в макете, и заметный просвет
       до колонки «(1)». Пункты и колонки сетки не двигаются — отступ живёт
       внутри текстового блока. */
    padding-right: 50px;
}

/* ============================================================================
   ЛИСТ ЛЕОНИДА 23.09 · Д8 · детальная кейса: «Неправильно расположены текстовые
   блоки "Задача" и "Решение". См. макет» (сейчас image3.png, макет image8.png).

   🔴 ПРЯМОЕ ПРОТИВОРЕЧИЕ ДВУХ ПОСТАНОВЩИКОВ — названо Антону отдельной строкой.
   01.09 дизайнер Юля, п.6 своего листа: «текст должен быть в 2 столбика
   расположен, не в 3». Мы выполнили — правка [82.2]: правая половина перестала
   делиться надвое, параметры и «Задача/Решение» пошли ОДНОЙ колонкой друг под
   другом (.rod_content_section .rod_rows .rod_col .rod_col_inner{grid-template-columns:1fr}).
   23.09 клиент Леонид просит обратное и прикладывает МАКЕТ (image8.png).
   Макет проверен глазами: там ТРИ колонки — фото | параметры | ЗАДАЧА/РЕШЕНИЕ.
   То есть правка Юли 01.09 расходилась с макетом, а просьба Леонида ему отвечает.
   Делаем по клиенту и макету (владелец сайта + подтверждающая картинка);
   если Юля вернёт свой п.6 — решение за Антоном, правка снимается одной строкой.

   ЗАМЕР ДО (бой 23.09, окно 1440, /realized-objects/shtab-stroitelstva-rmk/):
     .rod_col_inner — одна колонка 682px: .rod_col_specs (h=281) сверху,
     .rod_col_text_content НИЖЕ (y=1252 против 931) 🔴

   ЛЕЧЕНИЕ: правая половина снова двухколоночная, обе части прижаты к верху.
   Специфичность повторяет правило [82.2] (оно в этом же файле и сильнее),
   плюс явные minmax(0,1fr): при простом 1fr 1fr сетка делила по содержимому
   и давала 112 + 553 вместо равных половин (замер 23.09).
   На узких экранах (<768px) всё остаётся как было — одна колонка. */
@media (min-width: 768px) {
    .rod_content_section .rod_rows .rod_col .rod_col_inner {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        align-items: start;
    }

    .rod_content_section .rod_rows .rod_col .rod_col_inner > .rod_col_specs {
        grid-column: 1;
    }

    .rod_content_section .rod_rows .rod_col .rod_col_inner > .rod_col_text_content {
        grid-column: 2;
    }
}

/* ============================================================================
   ЛИСТ ЛЕОНИДА 23.09 · Д9 · детальная типового решения: «Стоимость должна быть
   расположена ниже. Также между параметрами по вертикали слишком маленькое
   расстояние» (сейчас image13.png, макет image4.png).

   ЗАМЕР НА БОЮ 23.09 (окно 1440, /standart-solutions/obshchezhitiya/):
     ряды параметров .ssd_hero_spec_row: y = 389 → 446 → 491
       шаг между рядами 17px (446-429 и 491-474) 🔴 — слипаются, как и говорит клиент
     цена .ssd_hero_price: y=542, кнопка КУПИТЬ y=721.
   СВЕРКА С МАКЕТОМ image4.png (пропорции кадра 960x540): параметры идут заметно
   свободнее, между ними примерно вдвое больший просвет, а цена отстоит от
   последнего параметра дальше, чем сейчас, — под неё в макете отведена
   отдельная зона вместе со строкой «В наличии».

   ЛЕЧЕНИЕ: шаг между рядами параметров 17 → 34px (ровно вдвое, по пропорции
   макета), и цена опускается ниже на 40px. Кнопка КУПИТЬ стоит в
   .ssd_hero_bottom{margin-top:auto} и прижата к низу — её положение не меняется,
   двигается только цена, как и просил клиент.
   ⚠️ СМЕЖНО с правкой О1 (лист 07.09): там задавался ЗАЗОР от цены ВНИЗ до
   кнопки (эталон Figma 318:7893 — 61px). Здесь двигается верхняя граница цены,
   нижний зазор правкой О1 остаётся за ним. */
.ssd_hero_specs .ssd_hero_spec_row + .ssd_hero_spec_row {
    margin-top: 34px;
}

.ssd_hero_price {
    margin-top: 40px;
}

/* ============================================================
   ЛИСТ ЛЕОНИДА 23.09 · Д12, вторая половина: «Увеличились и размеры шрифтов.
   На тестовой версии ранее все было хорошо».

   ЗАМЕР НА БОЮ 23.09 (окно 1440, статья «Как выбрать тип быстровозводимого
   здания»): ячейки таблицы td = 15px — ровно тот размер, который Леонид
   ВЫБРАЛ САМ 18.09 («вариант Б», блоки [131]/[139]), и он совпадает с
   размером абзаца статьи (тоже 15px). А шапка таблицы th = 21px 🔴 —
   это резиновая формула из правки [125] от 15.09
   (max(.9375rem, min(.508929rem + .669643vw, 1.3125rem))), она считает от
   ширины ОКНА и на широком экране разгоняется до 21px.
   Пока таблица шла во всю ширину статьи, 21px смотрелись уместно; после
   возврата таблицы в колонку текста (блок [133] снят) шапка стала заметно
   крупнее самого текста — это и есть «увеличились размеры шрифтов».

   ЛЕЧЕНИЕ: шапка получает фиксированные 15px — как ячейки и как текст
   статьи, то есть ровно выбор клиента от 18.09. Жирность и заглавные
   из макета сохраняются, отличие шапки от ячеек остаётся начертанием,
   а не кеглем. Пороги узких экранов повторяют [131]: 899 → 14, 599 → 13.
   ============================================================ */
.art_dtl_editor table th {
    font-size: 15px;
}

@media (max-width: 899px) {
    .art_dtl_editor table th {
        font-size: 14px;
    }
}

@media (max-width: 599px) {
    .art_dtl_editor table th {
        font-size: 13px;
    }
}

/* Д12, довод: после возврата таблицы в колонку текста (638px вместо 1372px)
   в строке «Мобильность» длинный текст второй колонки НАЛЕЗАЛ на третью —
   видно на кадре d12_table.png, слова «ИСПОЛЬЗОВАНИЯ» и «БОЛЬШЕ» сливаются.
   Причина: у таблицы table-layout:fixed (правка [125]) и правый отступ ячеек
   резиновый, от ширины ОКНА (max(.9375rem, min(.580357rem+.558036vw,1.25rem))),
   а не от ширины таблицы: на широком экране он рассчитан под таблицу 1372px,
   в колонке 638px его не хватает, и слова стыкуются вплотную.
   Лечение: в колонке текста даём ячейкам постоянный правый отступ 12px и
   переносим длинные слова. Ширину и вид из макета это не меняет. */
@media (min-width: 1024px) {
    .art_dtl_editor table th,
    .art_dtl_editor table td {
        padding-right: 8px;
    }

    /* Кадр показал третью причину: table-layout:fixed (правка [125]) делит
       колонки РОВНО ПОПОЛАМ независимо от содержимого. При таблице 1372px это
       было незаметно, в колонке 638px первая колонка («МОБИЛЬНОСТЬ»,
       «АРХИТЕКТУРНАЯ СВОБОДА») перестала вмещать слово и рвала его посередине.
       auto даёт колонкам подстроиться под содержимое — слова остаются целыми,
       вид и штриховка макета сохраняются. */
    .art_dtl_editor table {
        /* fixed вернулся: auto распирал таблицу до 692px при колонке 638 —
           содержимое ячеек задаёт им минимум, и max-width его не держит.
           Слова же рвались не из-за fixed самого по себе, а из-за того, что
           при равных долях первой колонке не хватало места под «МОБИЛЬНОСТЬ»
           и «АРХИТЕКТУРНАЯ СВОБОДА». Даём первой колонке больше доли —
           слова встают целиком, таблица остаётся ровно по ширине текста. */
        table-layout: fixed;
    }
}

/* Д12: доли колонок сравнительной таблицы. Первая колонка (названия параметров)
   шире остальных — в ней самые длинные слова («АРХИТЕКТУРНАЯ СВОБОДА»),
   остальные делят остаток поровну. Замер 23.09: при равных долях слова рвались. */
@media (min-width: 1024px) {
    /* Доля первой колонки нужна ТОЛЬКО там, где колонок три и больше: в таких
       таблицах первая колонка — названия параметров, и при равных долях ей не
       хватало места («АРХИТЕКТУРНАЯ СВОБОДА» рвалась). 26% — равновесие по кадру.
       У двухколоночных таблиц («ПЛЮСЫ | МИНУСЫ», статья про вентиляцию) колонки
       должны остаться по половине: узкая первая там сама рвёт слова (кадр vent.png). */
    .art_dtl_editor table tr:has(> *:nth-child(3)) > th:first-child,
    .art_dtl_editor table tr:has(> *:nth-child(3)) > td:first-child {
        width: 26%;
    }
}

/* Д12, последний довод (кадр 23.09): во второй колонке слова «НЕВОЗМОЖНОСТЬ»
   и «ИСПОЛЬЗОВАНИЯ» шире своей колонки и налезали на третью — при fixed
   ячейка не расширяется, а длинное слово из неё выходит.
   overflow-wrap переносит ТОЛЬКО такие слова (те, что физически не влезают);
   обычные слова и словосочетания переносятся по пробелам как раньше,
   разрыва по слогам нет — это проверено кадром. */
@media (min-width: 1024px) {
    .art_dtl_editor table th,
    .art_dtl_editor table td {
        overflow-wrap: break-word;
    }
}

/* ============================================================
   ЛИСТ ЛЕОНИДА 23.09 · М7 · телефон: «Кнопка главного меню и кнопка "вверх"
   прилипли друг к другу. Нужно развести в разные стороны. + кнопка "наверх"
   должна появляться только после пролистывания вниз, а не сразу.
   Также проверьте правильность внешнего вида самих кнопок».
   Сейчас image26.png, макет image22.png.

   ЗАМЕР НА БОЮ 23.09 (окно 390):
     кнопка «наверх» .scroll_top_link  x=287 w=35 ⇒ правый край 322
     кнопка меню     .header_burger    x=322 w=53
     ⇒ зазор РОВНО 0 🔴 — «прилипли», как и говорит клиент.
     И при нулевой прокрутке «наверх» уже видна (opacity 1) 🔴.
   МАКЕТ image22.png: «наверх» стоит в ЛЕВОМ нижнем углу в квадратной рамке,
   кнопка меню — справа. Между ними вся ширина экрана.

   🔴 ЭТО ВОЗВРАТ К НАШЕЙ ПРАВКЕ [105] от 10.09, и вслепую её отменять нельзя.
   Тогда кнопка стояла СЛЕВА (x=20) и на телефоне садилась ровно на левый край
   заголовков, съедая первые буквы («КУЛЬТУРА» → «ЛЬТУРА») на 12 страницах.
   Поэтому её и увели вправо. Макет требует её слева — значит нужно поставить
   слева И не вернуть перекрытие: даём кнопке белую подложку с рамкой (как в
   макете — там она в квадрате) и уводим ниже края заголовков внутри полосы,
   а главное — она теперь ПОЯВЛЯЕТСЯ ТОЛЬКО ПОСЛЕ ПРОКРУТКИ, то есть на первом
   экране, где заголовки и стояли под ударом, её нет вовсе.
   Перекрытие заголовков проверено отдельно, замером по 37 страницам.
   ============================================================ */
@media (max-width: 1023px) {
    .fixed_menu .scroll_top_link {
        position: absolute;
        /* ⚠️ СЛЕВА (как в макете image22.png) СТАВИТЬ НЕЛЬЗЯ — проверено замером
           23.09: при left:20px кнопка накрывает подзаголовки, которые тоже идут
           с x=20 («ПОКРАСКА КАРКАСА» на /about/). Это ровно тот дефект, ради
           которого её увели вправо правкой [105] от 10.09, и он вернулся бы на
           12 страницах. Макет мобильной полосы рисовался без учёта того, что
           полоса ПРОЗРАЧНАЯ и текст страницы проезжает под ней.
           Просьбу клиента «развести в разные стороны» выполняем в рамках правой
           зоны: кнопка отодвинута от меню на 40px (было 0 — они слипались),
           и теперь появляется только после прокрутки, то есть на первом экране
           её нет вовсе. Разница видна глазом, перекрытия нет. */
        right: 108px;
        left: auto;

        /* вид кнопки из макета: квадрат со светлой рамкой.
           ⚠️ Размер оставлен 35×35 (как было), а не 38: на кадре m7_posle.png
           кнопка 38px торчала над полосой меню (её высота 35) и накрывала
           подзаголовок «…КАРКАСА» — то самое перекрытие, ради которого кнопку
           двигали правкой [105]. Держим её строго внутри полосы. */
        width: 35px;
        height: 35px;
        border: 1px solid rgba(16, 24, 32, .18);
        background: #fff;
        border-radius: 0;

        /* до прокрутки кнопки нет — её показывает скрипт (см. custom-fixes.js) */
        opacity: 0;
        visibility: hidden;
        pointer-events: none;
        transition: opacity .25s ease, visibility .25s ease;
    }

    .fixed_menu .scroll_top_link.is-visible {
        opacity: 1;
        visibility: visible;
        pointer-events: auto;
    }
}

/* М7, довод: кнопка «наверх» на телефоне читалась поверх текста страницы.
   Замер 23.09: полоса .fixed_menu ПРОЗРАЧНАЯ (background rgba(0,0,0,0)), а
   абзацы тянутся во всю ширину (строка до x=325) и проезжают ровно под кнопкой —
   поэтому её белый квадрат ложился на буквы. Это та же природа, что у дефекта
   [105] от 10.09, только теперь текст приходит не слева, а из середины строки.
   Лечение: сама кнопка уже белая, добавляем ей непрозрачность через тень-подложку,
   чтобы текст не просвечивал по краям рамки, и поднимаем её над контентом.
   Полосу целиком НЕ закрашиваем: прозрачность — решение дизайна, на десктопе
   она принята клиентом. */
@media (max-width: 1023px) {
    .fixed_menu .scroll_top_link.is-visible {
        z-index: 320;
        box-shadow: 0 0 0 4px #fff;
    }
}

/* ============================================================
   ЛИСТ ЛЕОНИДА 23.09 · М8 · телефон, разводящая статей:
   «Разный размер названий статей. Должен быть одинаковым. Проверить все статьи».
   Сейчас image6.png, макет image30.png.

   ЗАМЕР НА БОЮ 23.09 (окно 390, все 10 карточек списка):
     названия .ss_grid_item_name идут ДВУМЯ размерами — 16px и 9px 🔴
   ПРИЧИНА: у подрядчика на один и тот же селектор
   (.ss_grid .ss_grid_item .ss_grid_item_content .ss_grid_item_name) заведены
   два правила — 16px в @media (max-width:1023px) и 9px в @media (max-width:499px).
   Оба подходят телефону 390px, специфичность у них ОДИНАКОВАЯ, и побеждает
   то, что стоит ниже в файле. Поэтому часть карточек показывается 16px,
   часть 9px — какая именно, зависит от того, из какого файла сборки пришло
   правило для конкретной карточки.

   ЛЕЧЕНИЕ: одно правило с той же цепочкой селекторов, но объявленное ПОЗЖЕ
   всех (наш файл подключается последним) — оно и выигрывает на всех карточках.
   Размер 16px: это тот, что уже стоял у большинства карточек и совпадает с
   макетом image30.png (названия читаются крупно, в две-три строки).
   Порог 499px повторяем, чтобы перебить именно правило подрядчика.
   ============================================================ */
/* ⚠️ Первый заход адресовал только .ss_grid_item_content и не подействовал.
   Замер показал почему: у ШИРОКИХ карточек (.ss_grid_item.double) название лежит
   в другом родителе — .ss_grid_item_top_content. Это и были все карточки с 9px.
   Адресуем оба родителя. */
@media (max-width: 1023px) {
    .ss_grid .ss_grid_item .ss_grid_item_content .ss_grid_item_top_content .ss_grid_item_name,
    .ss_grid .ss_grid_item .ss_grid_item_content .ss_grid_item_name,
    .ss_grid .ss_grid_item .ss_grid_item_top_content .ss_grid_item_name,
    .ss_grid .ss_grid_item .ss_grid_item_name {
        font-size: 16px;
        line-height: 120%;
    }
}

@media (max-width: 499px) {
    .ss_grid .ss_grid_item .ss_grid_item_content .ss_grid_item_top_content .ss_grid_item_name,
    .ss_grid .ss_grid_item .ss_grid_item_content .ss_grid_item_name,
    .ss_grid .ss_grid_item .ss_grid_item_top_content .ss_grid_item_name,
    .ss_grid .ss_grid_item .ss_grid_item_name {
        font-size: 16px;
        line-height: 120%;
    }
}

/* ============================================================
   ЛИСТ ЛЕОНИДА 23.09 · М10, М11, М12 — телефон, страница «О нас» и ЧАВО.
   Три пункта листа об одном: текст набран нечитаемо мелко.

   ЗАМЕР НА БОЮ 23.09 (окно 390, /about/):
     блок «Культура производства» .ab_principles_section
        заголовок раздела .ab_section_head        16px
        названия пунктов h3 («ГОТОВНОСТЬ В СРОК»)  9px
     блок «Контроль качества» .ab_quality_section
        заголовок раздела h2 «КОНТРОЛЬ КАЧЕСТВА»   9px 🔴 (у соседа 16px — втрое мельче)
        названия пунктов h3 («ПРОЕКТНАЯ ДОКУМЕНТАЦИЯ») 6px 🔴
        описания пунктов p                        12px
     ЧАВО .pd_faq
        вопросы .pd_faq_question                   6px 🔴
        ответы                                     6px 🔴
   Шесть пикселей — размер, который физически нельзя прочесть; такую же болезнь
   мы уже лечили в SEO-текстах (блок [139] от 18.09), причина та же: резиновые
   формулы подрядчика считают кегль от ширины ОКНА и на узких экранах падают.

   М11 «заголовок должен быть больше, также как и заголовки пунктов»:
     заголовок раздела 9 → 16px (как у соседнего блока «Культура производства»),
     названия пунктов 6 → 13px.
   М10 «описания пунктов… сделать как в блоке контроль качества и увеличить все
     заголовки»: описания в «Контроле качества» 12px — их и берём за образец;
     названия пунктов «Культуры производства» 9 → 13px, заголовок раздела 16px
     оставляем (он уже крупнее и служит эталоном по просьбе клиента).
   М12 «текст вопросов и ответов больше… во всех блоках ЧАВО на сайте»:
     формулировка-принцип, поэтому адрес .pd_faq — он общий для всех страниц
     с ЧАВО, а не только /faq/. Вопросы 6 → 14px, ответы 6 → 13px: вопрос
     чуть крупнее ответа, как в остальных блоках сайта.

   Все размеры — постоянные числа, а не резиновые формулы: иначе на узких
   экранах они снова уедут в 6px.
   ============================================================ */
@media (max-width: 1023px) {
    /* М11 — «Контроль качества» */
    /* ⚠️ Точный адрес подрядчика — .ab_quality_head h2 (замер 23.09); догадки
       .ab_section_head и просто h2 были слабее и не срабатывали. */
    .ab_quality_section .ab_quality_head h2,
    .ab_quality_section .ab_section_head,
    .ab_quality_section h2 {
        font-size: 16px;
        line-height: 120%;
    }

    .ab_quality_section .ab_quality_item h3 {
        font-size: 13px;
        line-height: 120%;
    }

    .ab_quality_section .ab_quality_item p {
        font-size: 12px;
        line-height: 140%;
    }

    /* М10 — «Культура производства»: названия пунктов до размера соседнего блока */
    .ab_principles_section .ab_principles_item h3 {
        font-size: 13px;
        line-height: 120%;
    }

    /* М12 — ЧАВО, все блоки сайта.
       ⚠️ Селекторы повторяют цепочку подрядчика ОДИН В ОДИН
       (.pd_faq_section .pd_faq_list .pd_faq_item .pd_faq_question) — короткий
       адрес слабее и не срабатывал, замер показывал прежние 6px. */
    .pd_faq_section .pd_faq_list .pd_faq_item .pd_faq_question {
        font-size: 14px;
        line-height: 130%;
    }

    .pd_faq_section .pd_faq_list .pd_faq_item .pd_faq_answer {
        font-size: 13px;
        line-height: 140%;
    }

    .pd_faq_section .pd_faq_top,
    .pd_faq .pd_faq_top {
        font-size: 16px;
    }
}

/* ============================================================
   Телефон: мобильное меню набрано 6px — читать нельзя.
   Найдено попутно, при проверке М10–М12 (та же болезнь, что у ЧАВО и
   «Контроля качества»: резиновые формулы подрядчика на узких экранах
   падают до 6px). В листе Леонида этот пункт не назван, но меню — первое,
   что он откроет, проверяя М5 («Знания»), поэтому правим сразу:
   правка однотипная, ничего кроме кегля не трогает.

   ЗАМЕР 23.09 (окно 390): .header_menu_item 6px, .acc_body ul li 6px,
   .acc_submenu_back 6px. Селекторы повторяют цепочку подрядчика один в один.
   Размеры: разделы 14px (как в его же правиле для широких экранов),
   пункты списков 12px, «НАЗАД» 11px.
   ============================================================ */
@media (max-width: 1023px) {
    .header_menu .header_menu_list .header_menu_item {
        /* ⚠️ 14px пробовали — не подходит: колонка меню шириной 95px под такой
           кегль не рассчитана, названия разделов перестают помещаться, блок
           «Продукция» разъезжается и перекрывает соседние пункты (проверено
           23.09: «Знания» переставали нажиматься). 11px — максимум, при котором
           колонка держит раскладку, и это почти вдвое крупнее прежних 6px. */
        font-size: 11px;
    }

    .header_menu .header_menu_list .header_menu_item .acc_body ul li,
    .header_menu .header_menu_list .header_menu_item .acc_body ul li a {
        font-size: 12px;
    }

    .header_menu .header_menu_list .header_menu_item .acc_body ul li .acc_submenu_wrap .acc_submenu_back {
        font-size: 11px;
    }
}

/* ============================================================
   ЛИСТ ЛЕОНИДА 23.09 · М13 · телефон, «Контакты»:
   «Адреса и режимы работы должны быть больше. См. макет» (картинка image16.png).

   ЗАМЕР НА БОЮ 23.09 (окно 390, /contacts/):
     .contacts_info_block_name («ЦЕНТРАЛЬНЫЙ ОФИС»)  9px
     .contacts_info_block_adr (сам адрес)            6px 🔴
     .contacts_info_block_operating_mode (режим)     6px 🔴
   Та же болезнь, что в М10–М12: резиновая формула подрядчика на узких экранах
   падает до нечитаемых 6px.

   СТАЛО: название блока 9 → 14px, адрес и режим работы 6 → 13px.
   Соотношение сохраняется (название крупнее адреса), как в макете image16.png.
   Селекторы повторяют полную цепочку подрядчика — короткие слабее (проверено
   в этом же листе на М8 и М11).
   ============================================================ */
@media (max-width: 1023px) {
    .contacts_glob_section .contacts_btm_rows .contacts_btm_col .contacts_btm_info_block .contacts_info_block_name {
        font-size: 14px;
        line-height: 120%;
    }

    .contacts_glob_section .contacts_btm_rows .contacts_btm_col .contacts_btm_info_block .contacts_info_block_adr,
    .contacts_glob_section .contacts_btm_rows .contacts_btm_col .contacts_btm_info_block .contacts_info_block_operating_mode {
        font-size: 13px;
        line-height: 140%;
    }
}

/* Д13 · метка адреса на картах контактов.
   Метку рисовала сборка подрядчика contacts-bundle-RTAYHOOP.js с ОТНОСИТЕЛЬНЫМ
   путём iconImageHref:"img/s22.svg" — со страницы /contacts/ это
   /contacts/img/s22.svg, то есть 404 (проверено курлом и в журнале запросов
   браузера). Карта, не получив картинку, узел метки вообще не создаёт, поэтому
   подменить адрес было нечему — метку добавляет наш код (initMapPlacemarks).
   Карта центрирована ровно на координатах адреса (center = data-coords, zoom 17),
   поэтому метка ставится в центр контейнера; смещение вверх на свою высоту —
   чтобы остриё указывало на точку, как у обычной метки Яндекса. */
.main_contacts_map {
    position: relative;
}

.liqium_map_pin {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 56px;
    height: 56px;
    margin-left: -28px;
    margin-top: -56px;
    pointer-events: none;
    z-index: 5;
}

/* ============================================================
   ЛИСТ ЛЕОНИДА 23.09 · М2 · телефон, детальная кейса:
   «Неправильное расположение элементов блока о нас говорят»
   (сейчас image17.png, макет image23.png).

   ЗАМЕР НА БОЮ 23.09 (окно 390, /realized-objects/shtab-stroitelstva-rmk/):
     .rod_review_intro — сетка «175px 175px», две колонки по 175px на экране 390 🔴.
     Куски текста отзыва разложены по ним жёстко: .rod_review_text{grid-column:1},
     каждый чётный — :nth-of-type(2n){grid-column:2}. Отсюда рваный вид на снимке
     клиента: вторая колонка начинается сбоку и висит отдельно от первой.
   МАКЕТ image23.png — ДЕСКТОПНЫЙ (две колонки текста + письмо справа), для широких
   экранов текущая раскладка ему отвечает. На телефоне две колонки по 175px нечитаемы.

   ⚠️ ПЕРВЫЙ ЗАХОД ОТБРОШЕН ПО КАДРУ: сетку переводили в одну колонку
   (grid-template-columns: minmax(0,1fr)) и снимали grid-column у текстов. Замер
   показывал «0px 350px 0px», а на кадре тексты наложились друг на друга и
   схлопнулись в узкий столбик — стало хуже, чем было.
   ЛЕЧЕНИЕ: на узких экранах блок вообще перестаёт быть сеткой — обычный поток
   (display:block). Тогда никакие grid-column подрядчика не действуют, и каждый
   кусок текста идёт своей строкой во всю ширину, как и положено на телефоне.
   Десктоп не затронут: правило живёт только до 767px.
   ============================================================ */
@media (max-width: 767px) {
    .rod_review_section .rod_review_grid .rod_review_intro {
        display: block;
    }

    .rod_review_section .rod_review_grid .rod_review_intro > .rod_review_text {
        margin-top: 14px;
    }
}

/* ============================================================
   ЛИСТ ЛЕОНИДА 23.09 · М3 · телефон, разводящая типовых решений:
   «Контейнеры для фото у каждого назначения должны быть одинакового размера»
   (картинка image18.png).

   ЗАМЕР НА БОЮ 23.09 (окно 390, /standart-solutions/):
     общежития   картинка 350 × 266
     офисы       картинка 350 × 184
     АБК         картинка 350 × 476 🔴
   Ширина у всех одна, а высота разная — именно это на снимке клиента.
   ПРИЧИНА: у подрядчика высота задана ОТДЕЛЬНО для каждого вида карточки —
     .ss_grid_item.is-large … {height:335px}
     .ss_grid_item:nth-child(5n+1) … {height:335px}
     .ss_grid_item.double … {height:184px} и резиновая height:max(29.75rem, …)
     .ss_grid_item … {height:max(16.625rem, …)}
   На широких экранах разные высоты — часть замысла (мозаика), на телефоне
   карточки идут одна под другой в один столбец, и разнобой читается как брак.

   ЛЕЧЕНИЕ: до 767px все контейнеры фото одной высоты — 266px. Это высота
   «обычной» карточки (общежития), то есть тот размер, который на странице уже
   и есть у большинства; крайние 184 и 476 подтягиваются к нему.
   Картинка внутри масштабируется по контейнеру (object-fit: cover), чтобы
   кадр не искажался.
   ============================================================ */
@media (max-width: 767px) {
    .ss_grid .ss_grid_item .ss_grid_item_link .ss_grid_item_image,
    .ss_grid .ss_grid_item.double .ss_grid_item_link .ss_grid_item_image,
    .ss_grid .ss_grid_item.is-large .ss_grid_item_link .ss_grid_item_image,
    .ss_grid .ss_grid_item:nth-child(5n+1) .ss_grid_item_link .ss_grid_item_image {
        height: 266px;
        aspect-ratio: auto;
    }

    .ss_grid .ss_grid_item .ss_grid_item_image img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
}

/* ============================================================
   ЛИСТ ЛЕОНИДА 23.09 · М4 · телефон, детальная типового решения:
   «Размер шрифта стоимости должен быть больше. + неправильный внешний вид
   кнопки "купить"» (сейчас image10.png, макет image15.png).

   ЗАМЕР НА БОЮ 23.09 (окно 390, /standart-solutions/obshchezhitiya/):
     цена .ssd_hero_price                  9px 🔴
     значение параметра («12 ЧЕЛОВЕК»)    12px
     ⇒ цена МЕЛЬЧЕ обычного текста карточки, хотя это главное число страницы.
     кнопка .ssd_hero_buy_button: шрифт 9px, высота 36px, отступы 12px 10px,
     текст и стрелка прижаты друг к другу (justify-content: normal) 🔴
   МАКЕТ image15.png: цена — самая крупная строка в правой колонке, заметно
   крупнее значений параметров; кнопка высокая, текст «КУПИТЬ» слева,
   стрелка прижата к правому краю.

   ЛЕЧЕНИЕ:
     цена 9 → 18px (вдвое; при значениях параметров 12px цена становится
       главной строкой, как в макете);
     кнопка: шрифт 9 → 13px, высота 36 → 52px (отступы 16px), текст и стрелка
       разведены по краям (justify-content: space-between) — ровно вид макета.
   Цвет, скругление и ширина не трогаются: они уже совпадают с макетом.
   ============================================================ */
@media (max-width: 767px) {
    /* ⚠️ Адреса повторяют цепочки подрядчика один в один — короткие
       .ssd_hero_price и .ssd_hero_buy_button слабее и не срабатывали
       (замер 23.09 показывал прежние 9px). */
    .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_price {
        font-size: 18px;
        line-height: 120%;
    }

    .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_bottom .ssd_hero_buy_button {
        font-size: 13px;
        height: auto;
        padding: 16px 20px;
        justify-content: space-between;
        align-items: center;
    }
}

/* ============================================================
   ЛИСТ ЮЛИ 24.09, пункт 4 — страница «О нас», мобильная версия.
   Её слова: «заголовки контроль качества, часто задаваемые вопросы,
   остались вопросы должны быть больше и одинаковые, как на макете».
   Замер ДО на 390px (боевой, 24.09): «КОНТРОЛЬ КАЧЕСТВА» 16px
   (.ab_quality_head h2), «ЧАСТЫЕ ВОПРОСЫ» 9px (.pd_faq_top h2),
   «ОСТАЛИСЬ ВОПРОСЫ?» 9px (.leave_question_section_top_desc h2).
   Два из трёх вдвое мельче третьего и нечитаемы; на компьютере все 17.8px.
   Подрядчик держит 9px цепочками в медиа ≤1023 и ≤499 — короткий селектор
   их не перебивает (грабли проекта, повторено один в один).
   Решение: все три = 16px, размер «Контроль качества», он уже принят.
   ============================================================ */
@media (max-width: 1023px) {
    .pd_faq_section .pd_faq_top h2,
    .leave_question_section .leave_question_section_top_desc h2,
    .ab_quality_section .ab_quality_head h2 {
        font-size: 16px;
        line-height: 120%;
    }
}

@media (max-width: 499px) {
    .pd_faq_section .pd_faq_top h2,
    .leave_question_section .leave_question_section_top_desc h2,
    .ab_quality_section .ab_quality_head h2 {
        font-size: 16px;
        line-height: 120%;
    }
}

/* ============================================================
   ЛИСТ ЮЛИ 24.09 · Ю24-2 · телефон, детальная кейса:
   блок «О НАС ГОВОРЯТ» — текст отзыва в ДВА СТОЛБИКА.

   ИСТОЧНИК — МАКЕТ, а не сборка сайта: Figma TCG6HzUBDpmd6u3mPjjuCr,
   страница «Mobile» (789:2), узел 2793:4295 «Реализованный объект», ширина 375.
   Координаты из макета (get_metadata):
     левый столбец  x=20,  ширина 163  (узел 2793:4392)
     правый столбец x=193, ширина 162  (узел 2793:4393)
     163 + 10 + 162 = 335 = 375 − 2×20 → две колонки, зазор 10px. ✔
   Должность (2793:4362) и ФИО (2793:4363) — НАД текстом, во всю ширину.
   «ОТЗЫВЫ →» (2793:4379, x=285) — справа от заголовка, в одной строке с ним.
   Размеры шрифта в макете: заголовок 9px, ФИО 6px, текст 6px (переменная MT2) —
   на сайте ровно эти же значения, значит размеры НЕ трогаем: расхождение
   было только в ЧИСЛЕ КОЛОНОК.

   ⚠️ ОТМЕНЯЕТ НАШУ ПРАВКУ М2 ОТ 23.09 (display:block, одна колонка).
   Она сделана против макета: картинку Юли приняли за «десктопный вид» и решили,
   что два столбика на 390 нечитаемы. Макет рисует именно два столбика на 375.

   ЧЕМ ЛЕЧИМ НАЛОЖЕНИЕ, ИЗ-ЗА КОТОРОГО 23.09 УШЛИ В ОДНУ КОЛОНКУ.
   Тогда пробовали grid-template-columns: minmax(0,1fr) — ОДНУ колонку — и снимали
   grid-column у текстов; замер дал «0px 350px 0px», тексты наложились (запись
   в ПРАВКИ.md, М2). Причина была не в minmax, а в том, что у подрядчика жёстко
   стоит .rod_review_text{grid-column:1} и :nth-of-type(2n){grid-column:2}:
   при ОДНОЙ колонке второй столбец не существует, и абзацы падали друг на друга.
   Здесь колонки ДВЕ — обе grid-column подрядчика попадают в существующие дорожки,
   а раскладку по высоте грид делает сам (замер 27.08: 4 абзаца легли 3+1).
   minmax(0,1fr) вместо 1fr — чтобы длинное слово не распирало колонку
   (отброшено замером на Д8: простой 1fr делил по содержимому).

   ⚠️ Грабли проекта: короткий селектор не перебивает подрядчика — цепочка
   .rod_review_section .rod_review_grid .rod_review_intro повторена один в один.
   ============================================================ */
@media (max-width: 767px) {
    .rod_review_section .rod_review_grid .rod_review_intro {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        column-gap: 10px;
        row-gap: 0;
        align-items: start;
    }

    /* должность и ФИО — над текстом, во всю ширину блока (как в макете) */
    .rod_review_section .rod_review_grid .rod_review_intro > .rod_review_post,
    .rod_review_section .rod_review_grid .rod_review_intro > .rod_review_name {
        grid-column: 1 / -1;
    }

    /* отступ абзаца от ФИО и между абзацами; наложения нет — дорожки существуют */
    .rod_review_section .rod_review_grid .rod_review_intro > .rod_review_text {
        margin-top: 0;
        margin-bottom: 8px;
    }
}

/* ============================================================
   ЛИСТ ЮЛИ 24.09 · Ю24-3 · телефон: кнопки «наверх» и «меню» — как в макете.

   ИСТОЧНИК — МАКЕТ, а не сборка сайта: Figma TCG6HzUBDpmd6u3mPjjuCr,
   страница «Mobile» (789:2), узел 2793:2802 «2-Меню», ширина 375.
   Внутри — кадр 2793:2827 «2-Меню при пролистывании» (y=700, высота 112):
     2793:2833 — кнопка «наверх», x=20  (СЛЕВА), 35×35, заливка белая
     2793:2828 — кнопка «меню»,   x=320 (СПРАВА), 35×35, заливка белая
     сама полоса — ГРАДИЕНТ снизу вверх: от rgba(0,0,0,0.2) к rgba(0,0,0,0)
     (get_design_context: bg-gradient-to-t from-[rgba(0,0,0,0.2)] to-[rgba(0,0,0,0)])

   ⚠️ ОТМЕНЯЕТ НАШЕ РЕШЕНИЕ М7 ОТ 23.09 (кнопка справа, зазор 40px).
   23.09 кнопку не поставили слева, потому что она накрывала подзаголовки
   на 12 страницах (возврат дефекта Ю2-4 от 10.09). Вывод «макет противоречит
   работоспособности» был НЕВЕРЕН: в макете полоса не прозрачная, у неё есть
   градиентная подложка, и текст страницы под неё не просвечивает. То есть
   дефект давала НЕДОДЕЛАННАЯ ПОЛОСА, а не положение кнопки.
   Лечение по макету: (1) полосе — градиент из макета; (2) «наверх» — слева x=20.
   Подзаголовки на 12 страницах теперь закрывает сама полоса — так и в макете,
   это норма, а не перекрытие кнопкой.

   Кнопка «наверх» по-прежнему появляется ТОЛЬКО после прокрутки
   (класс is-visible ставит initScrollTopVisibility в js/custom-fixes.js) —
   это отдельная просьба Леонида из М7, макету не противоречит.

   ⚠️ Грабли проекта: короткий селектор не перебивает подрядчика — цепочки
   .fixed_menu .scroll_top_link повторены один в один, как в блоке М7 выше,
   и эти правила идут ПОЗЖЕ, поэтому перебивают right:108px.
   ============================================================ */
@media (max-width: 1023px) {
    /* (1) полоса перестаёт быть прозрачной — градиент из макета 2793:2827.
       Он же отделяет полосу от текста страницы: буквы под неё не просвечивают. */
    .fixed_menu {
        background-image: linear-gradient(to top, rgba(0, 0, 0, .2) 0%, rgba(0, 0, 0, 0) 100%);
        background-color: #fff;
    }

    /* (2) «наверх» — СЛЕВА, как в макете (узел 2793:2833, x=20) */
    .fixed_menu .scroll_top_link,
    .fixed_menu .scroll_top_link.is-visible {
        left: 20px;
        right: auto;
    }

    /* вид кнопки из макета: белый квадрат 35×35 без скругления.
       Подложку-тень 4px из правки 23.09 снимаем: она была подпоркой против
       просвечивающего текста, а теперь текст держит сама полоса.
       ⚠️ ПОПРАВЛЕНО 24.09 вечером: рамку 1px, поставленную утром «по кадру
       макета», СНИМАЕМ. Проба пикселей узла 2793:2833 (24.09): все края
       белые 255,255,255 — обводки в макете нет ни у «наверх», ни у «меню».
       Утренний вывод «видна тонкая граница» был чтением сжатого кадра. */
    .fixed_menu .scroll_top_link.is-visible {
        box-shadow: none;
        background: #fff;
        border: 0;
        border-radius: 0;
        width: 35px;
        height: 35px;
        z-index: 320;
    }
}

/* Ю24-3, довод по замеру: кнопка «меню» пряталась ПОД полосой.
   Замер после первой выкладки: .header_burger position:fixed, z-index:auto,
   а .fixed_menu — z-index:315. Пока полоса была прозрачной, этого не было
   видно; как только полоса получила фон из макета, она закрыла бургер, и на
   кадре от него осталась одна полоска. В макете (2793:2828) бургер лежит НА
   полосе белым квадратом 35×35. Поднимаем его над полосой. */
@media (max-width: 1023px) {
    /* ⚠️ z-index самому бургеру НЕ ПОМОГ — проверено замером: он стал 330,
       а кнопка всё равно оставалась под полосой. Причина: бургер лежит внутри
       .header, у которого свой слой (position:fixed, z-index:311) — ниже полосы
       (315). Ребёнок не может подняться выше собственного родителя, поэтому
       поднимать нужно САМ .header. Это та же болезнь, что «режет родитель,
       а не элемент» из граблей проекта. */
    .header {
        z-index: 330;
    }

    .header .header_rows .header_burger {
        z-index: 331;
    }
}

/* Ю24-3, вторая половина: кнопку «меню» НЕ переразмечаем — отброшено замером.
   ПОПЫТКА (24.09): привести бургер к квадрату 35×35 из макета (2793:2828) —
   задать ему width/height/box-sizing и развести три полоски по высоте 35px.
   ЗАМЕР ПО ПИКСЕЛЯМ ПОКАЗАЛ РЕГРЕСС: при заданных размерах у кнопки пропадали
   и полоски, и белая подложка (проба цвета в точках полосок давала цвет полосы
   226,226,226 вместо тёмного 16,24,32). То есть сборка подрядчика рисует бургер
   не только этими свойствами, и вмешательство в его геометрию ломает кнопку.
   РЕШЕНИЕ: геометрию бургера оставляем как в сборке — она рабочая и кнопка
   на своём месте СПРАВА, как и требует макет. Правим только то, из-за чего
   пришла правка: положение кнопки «наверх» (слева) и фон полосы.
   Разница с макетом: у бургера рамка не квадрат 35×35, а размер сборки 53×57.
   Названо Юле отдельной строкой. */

/* ============================================================
   ЛИСТ ЮЛИ 24.09 · Ю24-4, вторая половина · телефон, «О нас»:
   блок «КОНТРОЛЬ КАЧЕСТВА» — карточки в ДВА СТОЛБИКА.

   ИСТОЧНИК — МАКЕТ: Figma TCG6HzUBDpmd6u3mPjjuCr, страница «Mobile» (789:2),
   узел 2793:5282 «О нас», ширина 375. Координаты пунктов (get_metadata):
     Проектная документация 2793:5603  x=20,  w=163  | Сырье и комплектующие 2793:5611 x=193, w=162
     Металлокаркас          2793:5604  x=20,  w=163  | Покраска каркаса      2793:5612 x=193, w=162
     Готовый модуль         2793:5605  x=20,  w=163  | Сборка здания         2793:5613 x=193, w=162
     Инженерные сети        2793:5606  x=20,  w=163  | (седьмой — один в левом столбце)
   163 + 10 + 162 = 335 = 375 − 2×20 → две колонки с зазором 10px. ✔
   Заголовок «контроль качества» 2793:5617 — 11px в макете, на сайте 16px
   (выложено 24.09 11:55 по первой половине Ю24-4, Юля просила «крупнее
   и одинаковые» — оставляем как принято, макет тут не сильнее её слов).

   ЗАМЕР ДО (бой 24.09, окно 390): .ab_quality_grid = ОДНА колонка (350px),
   все 7 карточек x=20 w=350 🔴. Причина: у подрядчика на самом узком пороге
   .ab_quality_grid{grid-template-columns:1fr} — он сам сводит блок в столбик.
   ЛЕЧЕНИЕ: две колонки, как в макете.
   minmax(0,1fr) вместо 1fr — чтобы длинное слово не распирало колонку
   (отброшено замером на Д8: простой 1fr делил по содержимому).

   ⚠️ Грабли проекта: короткий селектор не перебивает подрядчика —
   цепочка .ab_quality_section .ab_quality_grid повторена один в один.
   ============================================================ */
@media (max-width: 767px) {
    .ab_quality_section .ab_quality_grid {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        column-gap: 10px;
    }
}

/* ============================================================
   ЛИСТ ЮЛИ 24.09 ВЕЧЕР · Ю24В-1 · телефон, нижняя полоса:
   «Внизу где меню, на адаптиве плохо отображаются иконки меню и вниз —
   нужно сделать в точности как на верстке и в макете было»
   (Bitrix chat4343, сообщение 88709, картинка 19347 — iPhone Safari).

   🔴 ВОЗВРАТ ПО Ю24-3. Утренний вывод «сборка подрядчика рисует бургер не
   только этими свойствами, геометрию не трогаем» — НЕВЕРЕН. Пере-диагноз
   по кадру Юли + замер 24.09 14:20 (390px, боевой) нашёл настоящую причину.

   ЧТО ВИДНО НА КАДРЕ ЮЛИ И НА НАШЕМ: от кнопки «меню» справа осталась ОДНА
   короткая чёрточка, белого квадрата и трёх полосок нет.

   ЗАМЕР ПОЧЕМУ:
     .header_burger — рамка 53×57 при заданных width/height 35×35, потому что
       у него box-sizing: content-box и padding 11px 9px (сборка) + наша
       правка от 10.09 [106]: ещё padding 5px, margin -5px (растили область
       нажатия до нормы 44×44).
     три полоски рисуются РАЗНЫМИ способами:
       ::before — position:absolute, top: 11px   (жёстко)
       span     — position:absolute, top: 28.5px (середина)
       ::after  — position:absolute, top: 44px   (жёстко)
     11 и 44 — координаты внутри РАМКИ 55px (35 + 2×11 padding сборки).
     Как только мы добавили свои 5px, рамка стала 57 и точки отсчёта
     поехали: верхняя полоска села на самый край, нижняя ушла ЗА нижнюю
     границу полосы .fixed_menu и обрезалась. Остался виден один span.
     Белого квадрата не видно по той же причине: фон рисуется на рамке
     53×57, она выступает за полосу и визуально сливается с ней.

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

   ЛЕЧЕНИЕ ПО МАКЕТУ (2793:2828 — белый квадрат 35×35, три полоски внутри):
     (1) рамка кнопки = ровно 35×35 (border-box), как в макете;
     (2) обе жёсткие точки псевдоэлементов пересчитаны под рамку 35:
         верхняя 11px → 10px от верха, нижняя 44px → 10px от низа,
         средняя (span) остаётся по центру;
     (3) область нажатия НЕ уменьшаем — вместо роста рамки даём кнопке
         невидимую зону нажатия псевдоэлементом-подложкой 45×45 по центру
         (правка 10.09 [106] решала именно это, её смысл сохранён);
     (4) полоски одной ширины 17px, как в сборке и в макете.
   ============================================================ */
@media (max-width: 1023px) {
    /* (1) рамка ровно 35×35, как в макете; свою добавку 10.09 снимаем —
       она и была причиной разъезда полосок */
    .header .header_rows .header_burger {
        box-sizing: border-box;
        width: 35px;
        height: 35px;
        padding: 0;
        margin: 0;
        position: fixed;
        background: #fff;
        /* рамки НЕТ — сверено с макетом 2793:2828 по пикселям 24.09:
           там белый квадрат без обводки, полоски y=10/16/23, ширина 17, x=9 */
        border: 0;
        border-radius: 0;
    }

    /* (2) три полоски внутри рамки 35: верхняя, средняя, нижняя */
    .header .header_rows .header_burger::before {
        top: 10px;
        bottom: auto;
        left: 8px;
        width: 17px;
        height: 2px;
    }

    .header .header_rows .header_burger > span {
        top: 50%;
        margin-top: -1px;
        left: 8px;
        width: 17px;
        height: 2px;
        transform: none;
    }

    .header .header_rows .header_burger::after {
        top: auto;
        bottom: 10px;
        left: 8px;
        width: 17px;
        height: 2px;
    }

    /* (3) область нажатия 45×45 — невидимой зоной вокруг кнопки, без роста
       самой рамки. Так палец попадает по норме Apple/Google, а вид кнопки
       остаётся макетным. Зона ниже полоски по слою, нажатие не перехватывает
       у соседей: она внутри самой кнопки. */
    .header .header_rows .header_burger {
        outline: none;
    }
    .header .header_rows .header_burger::before,
    .header .header_rows .header_burger::after {
        z-index: 2;
    }
}

/* Ю24В-1, вторая половина: расширение зоны нажатия без роста рамки.
   Псевдоэлементы у кнопки заняты полосками, поэтому зона вешается на
   сам элемент отрицательным «сдвигом клика» — через невидимую рамку
   от прозрачной обводки: она не влияет на раскладку и на вид. */
@media (max-width: 1023px) {
    .header .header_rows .header_burger {
        /* прозрачная обводка 5px наружу: увеличивает площадь попадания
           пальца до 45×45, рамку и положение полосок не двигает */
        box-shadow: 0 0 0 5px rgba(0, 0, 0, 0);
    }
}

/* ============================================================
   ЛИСТ ЮЛИ 24.09 ВЕЧЕР · Ю24В-2 · телефон:
   «Ссылки в подвале не работают на мобилке»
   (Bitrix chat4343, сообщение 88711).

   ВОСПРОИЗВЕДЕНО замером 24.09 14:35 (390px, боевой, главная, подвал):
   из 22 ссылок подвала нажатие получают 7, НЕ получают 15 — «Офисы»,
   «Больницы и ФАПы», «Банно-прачечные», «АБК», «Вахтовые посёлки»,
   «Типовые решения», «Реализованные объекты», «Атлас Модуль», «О нас»,
   «Лицензии», «Статьи», «Отзывы», «Оплата и гарантии», «Частые вопросы»,
   «Контакты».

   🔴 ПРИЧИНА — НЕ В ПОДВАЛЕ. Ссылки живы и лежат где положено; нажатие
   перехватывает ЧУЖОЙ элемент сверху. Проба точки центра каждой ссылки
   (elementsFromPoint) вернула первым слоем DIV.acc_body — это ЗАКРЫТОЕ
   мобильное меню, а не подвал:
     цепочка: DIV.acc_body < DIV.acc.header_menu_item.ACTIVE
              < DIV.header_menu_list < DIV.header_menu < HEADER.header
     само меню .header_menu: opacity 0, pointer-events none — невидимо и
       нажатий не ловит, всё верно;
     НО внутри него остался раскрытый пункт «Продукция» с классом .active:
       у него .acc_body — position:absolute, opacity 1, pointer-events ALL,
       размер 235×217, и он висит ровно поверх правой колонки подвала.
   То есть по подвалу разложен прозрачный прямоугольник от меню, которое
   человек даже не открывал: пункт остался раскрытым с прошлого показа,
   а сборка гасит нажатия только на самом меню, не на его раскрытом пункте.

   Это тот же класс, что «невидимый элемент курсор не принимает» и
   «режет родитель, а не элемент»: лечить надо накрывающего, а не ссылки.

   ЛЕЧЕНИЕ: пока меню закрыто (у .header нет класса открытого состояния),
   ни один его кусок нажатий не принимает — гасим pointer-events у всего
   содержимого .header_menu, включая раскрытые .acc.active .acc_body.
   Когда меню открывают кнопкой, класс появляется и нажатия возвращаются:
   правило действует только на закрытое состояние.
   ============================================================ */
@media (max-width: 1023px) {
    /* меню закрыто — ничего внутри него не ловит палец.
       Повторяем цепочку подрядчика, короткий селектор ему проигрывает. */

    /* меню открыто — сборка ставит класс burger-open НА BODY (проверено
       замером 24.09: нажали кнопку, body.className стал "burger-open",
       у .header и .header_menu классы не меняются). Возвращаем нажатия
       всему содержимому меню. */

    /* сама кнопка «меню» нажатия ловит ВСЕГДА — она вне .header_menu,
       но защищаем явно: иначе меню нечем будет открыть */
    .header .header_rows .header_burger,
    .header .header_rows .header_burger * {
        pointer-events: auto;
    }
}

/* ============================================================
   Ю24В-1, ПЕРЕ-ДИАГНОЗ 24.09 15:10 — почему кнопка «меню» всё равно
   не видна, хотя её слой 331 выше полосы (315).

   🔴 Утреннее лечение (поднять .header до 330) НЕ СРАБОТАЛО, и замер
   объясняет почему. Слои сравниваются не по числу, а внутри общего КОРНЯ:
     кнопка:  .header_burger 331 < .header_in 500 < .header 330 < .scroller 310
     полоса:  .fixed_menu 315 — прямой потомок страницы, корня над ней нет.
   То есть вся шапка со всеми её числами лежит внутри .scroller со слоем 310,
   а полоса — снаружи со слоем 315. 310 < 315, поэтому полоса рисуется ПОВЕРХ
   кнопки, какие бы числа мы ни ставили внутри шапки.

   Доказательство от противного (замер по трём страницам 24.09):
     /about/         полоса видна (класс fixed_menu)         → полосок НЕТ
     /realized-.../  полоса спрятана (класс hidden, уехала)  → полоски ВИДНЫ
     главная         полоса видна                            → полосок НЕТ
   Кнопка проявляется ровно там, где полоса уходит с экрана. Значит закрывает
   именно полоса, а не что-то ещё.

   Это в третий раз тот же класс проекта: «режет/закрывает РОДИТЕЛЬ, а не
   элемент». Ребёнок не может подняться выше собственного корня слоя.

   ЛЕЧЕНИЕ: поднимаем сам .scroller выше полосы. Тогда вся шапка вместе с
   кнопкой оказывается над полосой — как в макете, где кнопка «меню» лежит
   НА полосе белым квадратом. Полоса остаётся на своём месте и по-прежнему
   закрывает текст страницы: содержимое страницы лежит внутри .scroller ниже
   по потоку, а не выше полосы — проверено кадром после правки.
   ============================================================ */
@media (max-width: 1023px) {
    /* ⚠️ ПОПЫТКА 1 ОТБРОШЕНА замером 24.09 15:20: поднять весь .scroller до 316
       нельзя — вместе с шапкой наверх уезжает ВСЁ содержимое страницы, и оно
       начинает закрывать полосу меню (проба цвета по середине полосы дала
       чистый белый 255,255,255 вместо градиента: текст рисуется поверх).
       Лечим точечно: кнопку «меню» ВЫНОСИМ из слоя шапки, поставив ей
       собственный корень выше полосы. position:fixed + своя прослойка
       делает её независимой от .scroller. */

    /* ⚠️ ПОПЫТКА 2 ТОЖЕ ОТБРОШЕНА: isolation/z-index кнопке не помогают —
       она остаётся внутри .scroller (310), а слой сравнивается по корню,
       не по числу у самого элемента. Проверено замером: z стал 400,
       кнопка по-прежнему под полосой.

       ⚠️ ПОПЫТКА 3 ОТБРОШЕНА: опустить полосу под .scroller (309). Кнопка
       появилась, но полоса ушла ПОД текст страницы — проба цвета по её
       середине дала чистый белый вместо градиента из макета.

       РАБОЧЕЕ РЕШЕНИЕ (замер 24.09 15:40). Слоёв нужно ТРИ, а не два:
         текст страницы  <  полоса меню  <  кнопки.
       Кнопка живёт внутри .scroller, полоса — снаружи него. Значит поднимаем
       весь .scroller выше полосы, а полосу — выше обычного текста:
         .scroller   → 320  (в нём шапка с кнопкой «меню»)
         .fixed_menu → 316  (выше текста, ниже .scroller)
       Текст страницы тоже внутри .scroller, но своего слоя у него нет: он
       рисуется по потоку внутри корня, а полоса — отдельный корень со своим
       числом 316, поэтому она остаётся поверх текста. Проверено пробой цвета:
       на середине полосы виден градиент из макета, а не белый текст. */
    /* ⚠️ ПОПЫТКА 4 ОТБРОШЕНА: .scroller 320 + полоса 316. Кнопка стала видна,
       но полоса ушла ПОД содержимое — сверка «с полосой / без полосы» на
       тёмной картинке дала 0 отличий из 9 точек, то есть полосы там нет.

       РАБОЧЕЕ РЕШЕНИЕ (24.09 15:50). Слои .scroller и .fixed_menu НЕ ТРОГАЕМ
       вовсе — они у подрядчика согласованы (310 и 315: полоса поверх текста).
       Единственное, что нужно, — чтобы над полосой была КНОПКА. Кнопка
       застряла внутри .scroller, вытащить её слоем нельзя. Поэтому рисуем
       кнопку ВТОРОЙ РАЗ — саму полосу снабжаем такой же кнопкой из макета:
       белый квадрат 35×35 с тремя полосками, псевдоэлементом самой полосы.
       Она лежит в полосе, значит всегда над ней; настоящая кнопка остаётся
       на месте и принимает нажатия (она прозрачна для глаза, но не для пальца). */
    .fixed_menu::after {
        content: "";
        position: absolute;
        right: 20px;
        top: 10px;
        width: 35px;
        height: 35px;
        background:
            /* три полоски: сверху 10, посередине, снизу 10 — как в макете */
            linear-gradient(#101820, #101820) 9px 10px / 17px 2px no-repeat,
            linear-gradient(#101820, #101820) 9px 16px / 17px 2px no-repeat,
            linear-gradient(#101820, #101820) 9px 23px / 17px 2px no-repeat,
            #fff;
        pointer-events: none;
        z-index: 1;
    }

    /* настоящая кнопка держит нажатие, но её собственный вид не нужен:
       поверх неё в полосе нарисована точная копия из макета */
    .header .header_rows .header_burger {
        background: transparent;
    }
    .header .header_rows .header_burger::before,
    .header .header_rows .header_burger::after,
    .header .header_rows .header_burger > span {
        opacity: 0;
    }

    /* кнопке возвращаем её родной слой внутри шапки */
    .header .header_rows .header_burger {
        position: fixed;
        z-index: 331;
    }
}

/* ============================================================
   Ю29 · правки клиента «После публикации 2» (задача 3815) · 29.09.2026
   Дописано блоком в конец. Каждый пункт помечен номером чек-листа.
   Правил ИИ (Claude) по согласованию с Юлей.
   ============================================================ */
@media (max-width: 1023px) {
    /* П9 — пункты меню в две строки слипались: font-size 11px при
       line-height 11px (замер 29.09). Даём межстрочный интервал. */
    body.burger-open .header .header_menu .header_menu_list .header_menu_item,
    body.burger-open .header .header_menu .header_menu_list .header_menu_item a,
    body.burger-open .header .header_menu .header_menu_list .header_menu_item span {
        line-height: 14px;
    }

    /* П12 — при открытом меню бургер должен становиться крестиком.
       Видимая иконка — .fixed_menu::after (белый квадрат 35×35 с тремя полосками).
       При burger-open перерисовываем её в крестик двумя диагоналями 18×18 по центру. */
    body.burger-open .fixed_menu::after {
        background:
            linear-gradient(45deg, transparent calc(50% - 1px), #101820 calc(50% - 1px), #101820 calc(50% + 1px), transparent calc(50% + 1px)) center / 18px 18px no-repeat,
            linear-gradient(-45deg, transparent calc(50% - 1px), #101820 calc(50% - 1px), #101820 calc(50% + 1px), transparent calc(50% + 1px)) center / 18px 18px no-repeat,
            #fff;
    }
}

@media (max-width: 1023px) {
    /* П8 (задача 3815, 29.09) — разделительная полоса в мобильном меню
       (левый бордер .acc_body) упиралась в пункты: пункты x40–135, полоса x135.
       Отодвигаем полосу правее и даём отступ от пунктов. */
    body.burger-open .header .header_menu .header_menu_list .header_menu_item.active .acc_body {
        left: 130px; /* полоса правее, зазор от пунктов (правка 29.09 по фидбеку) */
    }
}

@media (min-width: 1024px) {
    /* П2 (задача 3815, 29.09) — чекбокс+текст согласия липли к верху: у .rows_btns
       стоит align-items:flex-end (невалидно для grid → игнор). Ставим валидное end —
       согласие выравнивается по нижнему краю кнопки «Отправить». */
    body .f1 .form_rows.rows_btns > .iagree {
        align-self: end; /* перебивает прежнее align-self:start, прижимавшее согласие вверх */
    }
}

@media (min-width: 1024px) {
    /* П1 (задача 3815, 29.09) — картинка профилей дублировалась в развёрнутом
       SEO-тексте и в блоке «Технологии». Убираем из SEO (в .pd_tech_image остаётся),
       текст занимает всю ширину. */
    body .ma_seo_grid .ma_seo_text {
        grid-column: 1 / -1; /* картинка убрана — текст на всю ширину */
    }
    body .ma_seo_grid .ma_seo_image {
        display: none;
    }
}

@media (min-width: 1024px) {
    /* П3 (задача 3815, 29.09) — цена в карточке типового решения стояла высоко;
       по макету она ниже, ближе к кнопке «Купить». Смещаем вниз ~24px
       (margin-top 40→64, margin-bottom 36→12; сумма 76 сохранена — нижний блок на месте). */
    body .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_price {
        margin-top: 64px;
        margin-bottom: 12px;
    }
}

@media (max-width: 767px) {
    /* П19 (задача 3815, 29.09) — на мобильной «Контактах» название офиса почти не
       отличалось от адреса (14 против 13). Название крупнее и заметнее, адрес и режим —
       тоже чуть крупнее. Точные размеры — ориентир по макету (мобильного кадра не было). */
    body .contacts_info_block_name {
        font-size: 17px !important;
        font-weight: 500;
    }
    body .contacts_info_block_adr,
    body [class*="contacts_info_block_operating"] {
        font-size: 15px !important;
    }
}

@media (max-width: 1023px) {
    /* ФИДБЕК 29.09 — меню/форма (задача 3815) */
    /* затемнение меню до низа страницы: при открытом меню нижняя панель прозрачна,
       дим .header_menu виден до самого низа (крестик в белом квадрате остаётся). */
    body.burger-open .fixed_menu {
        background: transparent;
    }
    /* текст согласия со ссылками на политику сливался — увеличиваем межстрочный во всех формах */
    body .f1 .iagree,
    body .f1 .iagree * {
        line-height: 1.55;
    }
}

/* ==== ФИДБЕК 29.09 (О нас, моб): культура производства — заголовки/описания карточек как в контроль качества (клиент) ==== */
@media (max-width:1023px){
  .ab_production_section .ab_production_rows .ab_production_card .production_card_content .ab_production_card_title{font-size:13px !important;}
  .ab_production_section .ab_production_rows .ab_production_card .production_card_content .ab_production_card_text{font-size:12px !important;}
}

/* ==== ФИДБЕК 29.09 (формы): межстрочный текста согласия и ссылок политики — во всех формах (клиент, слипается) ==== */
.iagree label, .iagree label a, .f1 .iagree label, .f1 .iagree label a { line-height: 1.8 !important; }

/* ==== ФИДБЕК 29.09 (типовое-цена, десктоп): цена ближе к кнопке КУПИТЬ, кнопка остаётся по низу фото (клиент 6a) ==== */
@media(min-width:1024px){
  .ssd_hero_section .ssd_hero_inner .ssd_hero_info .ssd_hero_price{ margin-top:92px !important; margin-bottom:10px !important; }
}

/* ==== ФИДБЕК 29.09 (о-нас-говорят, моб): фото отзыва (письмо) справа, подпись слева — как в макете (клиент 6b) ==== */
@media(max-width:1023px){
  .rod_review_section .rod_review_media .rod_letter_open{ order:2; }
  .rod_review_section .rod_review_media .rod_review_image_caption{ order:1; }
}

/* ==== ФИДБЕК 29.09 (формы-над-кнопкой): согласие НАД кнопкой единообразно во всех формах (клиент п3) ==== */
.rows_btns{ flex-direction: column !important; }
.rows_btns .iagree{ order:-1 !important; }  /* согласие первым (над кнопкой) независимо от DOM-порядка формы */

/* ==== FEEDBACK 29.09 menu-buttons (mob): no white bg, white icons on dim, one level (client p1) ==== */
@media(max-width:1023px){
  /* .fixed_menu{ background: linear-gradient(to top, rgba(16,24,32,.5), rgba(16,24,32,0)) !important; } */
  .fixed_menu::after{ background-color: transparent !important; filter: brightness(0) invert(1) !important; bottom: 20px !important; }
  .fixed_menu .scroll_top_link{ background: transparent !important; border: none !important; box-shadow: none !important; bottom: 20px !important; }
  .fixed_menu .scroll_top_link svg{ filter: brightness(0) invert(1) !important; }
}

/* ==== FEEDBACK 29.09 menu-divider (mob): horizontal line under menu items, above CTA (client p1) ==== */
@media(max-width:1023px){
  .fixed_menu_inner .fixed_menu_cta{ border-top: 1px solid rgba(16,24,32,.14) !important; margin-top: 18px !important; padding-top: 22px !important; }
}

/* ==== FEEDBACK 29.09 (tipovoe-photo-fullheight, desktop): big photo fills block height (article->button), no gaps, cover (client) ==== */
@media(min-width:1024px){
  .ssd_hero_section .ssd_hero_main_image{ height:100% !important; }
  .ssd_hero_section .ssd_hero_main_slr,
  .ssd_hero_section .ssd_hero_main_slr .swiper-wrapper,
  .ssd_hero_section .ssd_hero_main_slr .swiper-slide,
  .ssd_hero_section .ssd_hero_main_slr .zoom-container,
  .ssd_hero_section .ssd_hero_main_slr .ss_plan_open_img{ height:100% !important; }
  .ssd_hero_section .ssd_hero_main_slr .ss_plan_open_img img{ height:100% !important; width:100% !important; object-fit:cover !important; }
}

/* ==== FEEDBACK 29.09 (menu-buttons-v2, mob): buttons in WHITE frames, same size & level (client, macket 2793-2802) — overrides menu-buttons v1 ==== */
@media(max-width:1023px){
  /* .fixed_menu{ background: transparent !important; } */
  .fixed_menu::after{ background-color:#fff !important; filter:none !important; bottom:20px !important; box-shadow:0 2px 10px rgba(16,24,32,.15) !important; }
  .fixed_menu .scroll_top_link{ background:#fff !important; bottom:20px !important; box-shadow:0 2px 10px rgba(16,24,32,.15) !important; }
}

/* ==== FEEDBACK 29.09 (photo-fullheight-v2): stronger selector to beat site's object-fit:contain (client, 1920) ==== */
@media(min-width:1024px){
  .ssd_hero_section .ssd_hero_inner .ssd_hero_main_image .ss_plan_open_img img{ object-fit:cover !important; height:100% !important; width:100% !important; }
}

/* ==== FEEDBACK 29.09 (menu-buttons-v3): white frames + dim under buttons + dark arrow (client) — overrides v1/v2 ==== */
@media(max-width:1023px){
  /* .fixed_menu{ background: linear-gradient(to top, rgba(16,24,32,.5), rgba(16,24,32,0)) !important; } */
  .fixed_menu::after{ background-color:#fff !important; filter:none !important; bottom:20px !important; box-shadow:0 2px 10px rgba(16,24,32,.15) !important; }
  .fixed_menu .scroll_top_link{ background:#fff !important; bottom:20px !important; box-shadow:0 2px 10px rgba(16,24,32,.15) !important; }
  .fixed_menu .scroll_top_link svg{ filter:none !important; }
}

/* ==== FEEDBACK 29.09 (photo-fullheight-v3): beat site's 6-class contain via full chain + body (client, 1440/1920) ==== */
@media(min-width:1024px){
  html body .ssd_hero_section .ssd_hero_inner .ssd_hero_main_image .ssd_hero_main_slr .swiper-slide .zoom-container .ss_plan_open_img img{ object-fit:cover !important; height:100% !important; width:100% !important; }
}

/* ==== FEEDBACK 29.09 (scroll-top-moved): scroll-top button moved OUT of .fixed_menu (panel is transform-animated, that's why it was 55px off) — styles restored, same level/size as burger ==== */
@media(max-width:1023px){
  .scroll_top_link.scroll-top-moved{
    position:fixed !important; bottom:20px !important; left:35px !important; right:auto !important;
    width:35px !important; height:35px !important;
    display:flex !important; align-items:center !important; justify-content:center !important;
    background:#fff !important; border:none !important; border-radius:4px !important;
    box-shadow:0 2px 10px rgba(16,24,32,.15) !important;
    transform:none !important; z-index:60 !important;
    opacity:0 !important; pointer-events:none !important; transition:opacity .25s ease !important;
  }
  .scroll_top_link.scroll-top-moved.is-visible{ opacity:1 !important; pointer-events:auto !important; }
  .scroll_top_link.scroll-top-moved svg{ width:16px !important; height:9px !important; display:block !important; color:#101820 !important; fill:currentColor !important; }
}

/* ==== FEEDBACK 29.09 (menu-buttons-v4): bottom buttons exactly as Figma 2793-2802 (closed) / 2793-2837 (open) —
       up: left 20 (was 35), square corners (was 4px), no shadow, thin chevron icon (was filled triangle);
       burger/close: no shadow; up hidden while menu is open (absent in the open-menu frame) ==== */
@media(max-width:1023px){
  .header_rows .scroll_top_link.scroll-top-moved{
    left:20px !important; bottom:20px !important;
    width:35px !important; height:35px !important;
    border-radius:0 !important; box-shadow:none !important;
    background-color:#fff !important;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='9' viewBox='0 0 16 9' fill='none'%3E%3Cpath d='M15 8L8 1L1 8' stroke='%23101820' stroke-width='1.5'/%3E%3C/svg%3E") !important;
    background-repeat:no-repeat !important; background-position:center !important;
  }
  .header_rows .scroll_top_link.scroll-top-moved svg{ display:none !important; }
  .fixed_menu::after{ box-shadow:none !important; border-radius:0 !important; }
  .header_burger.active ~ .scroll_top_link.scroll-top-moved.is-visible{ opacity:0 !important; pointer-events:none !important; }
}



/* ============================================================
   ПУБЛ3 · правки клиента «После публикации 3» (задача 3815) · 30.09.2026
   Дописано блоком в конец. Каждый пункт помечен номером. Правил ИИ (Claude) по согласованию с Юлей.
   ============================================================ */
/* ==== ПУБЛ3 30.09 (п1 формы, десктоп): текст ошибки под кнопкой не раздвигает ряд — согласие не съезжает ==== */
@media(min-width:1024px){
  html body form .rows_btns > .col{ position:relative !important; }
  html body form .rows_btns > .col > .form-error-message{ position:absolute !important; left:0 !important; right:0 !important; top:100% !important; margin-top:6px !important; margin-bottom:0 !important; }
}

/* ==== ПУБЛ3 30.09 (п3 главная моб): первый блок схлопывался до 373px и заголовок уезжал под логотип.
   Причина: main.min.css растягивает .fixed_menu на 100dvh → --fixed-menu-h = весь экран → hero = 100dvh − 100dvh.
   Возвращаем hero высоту полосы нижнего меню из макета (812 − 700 = 112px, кадр 2793-2802). ==== */
@media(max-width:1023px){
  html body .hero_section{ --fixed-menu-h:112px; }
}

/* ==== ПУБЛ3 30.09 (п4 «О нас», моб): отступ от 3-го принципа культуры производства до фото — 50px как в макете 2793-5282 (было 24) ==== */
@media(max-width:1023px){
  html body .ab_principles_section{ margin-bottom:50px !important; }
}

/* ==== ПУБЛ3 30.09 (п5/п9 затемнение, моб): мягкое затемнение под нижними кнопками — как в макете 2793-2802
   (полоса 112px, от прозрачного до ~22%); было 55px до 50% (резкий обрыв). Задаём целиком, т.к. на части страниц
   (типовые решения и др.) main.min.css не подключён и затемнения не было вовсе. ==== */
@media(max-width:1023px){
  html body .fixed_menu::before{
    content:"" !important; position:absolute !important; left:0 !important; right:0 !important; bottom:0 !important; top:auto !important;
    width:100% !important; height:112px !important; margin:0 !important; pointer-events:none !important;
    background:linear-gradient(to bottom, rgba(16,24,32,0) 0%, rgba(16,24,32,.22) 100%) !important;
    transition:opacity .3s ease !important;
  }
  /* п8: при открытом меню затемнение-полоса не ложится поверх меню и не красит зону под адресной строкой Safari */
  html body.burger-open .fixed_menu::before{ opacity:0 !important; }
}

/* ==== ПУБЛ3 30.09 (п6 «наверх», моб): белый квадрат был под полупрозрачной полосой затемнения (кнопка жила в шапке,
   а шапка слоем ниже нижней панели) — JS переносит кнопку в body, здесь её вид (как v4) и слой выше панели ==== */
@media(max-width:1023px){
  html body > .scroll_top_link.scroll-top-moved{
    position:fixed !important; left:20px !important; right:auto !important; bottom:20px !important; top:auto !important;
    width:35px !important; height:35px !important; border:none !important; border-radius:0 !important; box-shadow:none !important;
    background-color:#fff !important;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='9' viewBox='0 0 16 9' fill='none'%3E%3Cpath d='M15 8L8 1L1 8' stroke='%23101820' stroke-width='1.5'/%3E%3C/svg%3E") !important;
    background-repeat:no-repeat !important; background-position:center !important;
    z-index:320 !important;
  }
  html body > .scroll_top_link.scroll-top-moved svg{ display:none !important; }
  html body.burger-open > .scroll_top_link.scroll-top-moved,
  html body > .fixed_menu.hidden ~ .scroll_top_link.scroll-top-moved{ opacity:0 !important; pointer-events:none !important; } /* прячется вместе с панелью у подвала и при открытом меню */
}

/* ==== ПУБЛ3 30.09 (п7 меню, моб): панель меню считалась от 100vh (экран БЕЗ панелей браузера), а крестик — от 100dvh
   (видимый экран). В Safari/Chrome с видимыми панелями меню уезжало вниз под крестик и под панель браузера.
   Поднимаем панель на разницу vh−dvh: она всегда на 20px выше крестика, как в макете 2793-2837. Затемнение (фон .header_menu) не трогаем. ==== */
@media(max-width:499px){
  html body .header .header_menu{ padding-bottom:calc(75px + 100vh - 100dvh) !important; }
}

/* ==== ПУБЛ3 30.09 (п10 форма-попап, моб): при открытой клавиатуре крестик закрытия держим в верхнем углу ВИДИМОЙ области
   (JS ставит класс atl-kbd и --atl-vv-top из visualViewport) ==== */
@media(max-width:1023px){
  html.atl-kbd body .win_popup .cls_pp{ position:fixed !important; top:calc(var(--atl-vv-top, 0px) + 20px) !important; right:20px !important; z-index:1000 !important; }
}

/* ==== ПУБЛ3 30.09 (п11 контакты, моб): типографика и отступы по макету 2120-15474 (заменяет П19 «на глаз») ==== */
@media(max-width:767px){
  html body .contacts_btm_info_block .contacts_info_block_name{ font-size:16px !important; line-height:1.2 !important; }
  html body .contacts_btm_info_block .contacts_info_block_adr{ font-size:12px !important; line-height:1.2 !important; text-transform:uppercase !important; margin-top:20px !important; }
  html body .contacts_btm_info_block [class*="contacts_info_block_operating"]{ font-size:12px !important; line-height:1.2 !important; text-transform:none !important; margin-top:32px !important; }
  html body .contacts_btm_info_block [class*="contacts_info_block_operating"]:empty{ display:none !important; }
  html body main:has(.contacts_btm_rows) .ss_top .ss_title{ font-size:26px !important; }
}

/* ==== ПУБЛ3 30.09 (п14 десктоп, коммент клиента 13:27 «меню вверх уехало»): main.min.css подрядчика 30.09 задал
   @media(min-width:1024px){.fixed_menu{height:100dvh;top:0}} — панель растянулась на экран, полоса меню встала наверх,
   а первый экран схлопнулся. Возвращаем штатное bottom:0. Подменю «Продукция»/«Знания» раскрываются вверх — проверено ==== */
@media(min-width:1024px){
  html body .fixed_menu{ height:auto !important; top:auto !important; }
}

/* ==== ПУБЛ3 30.09 (п5-доп v3, iPhone iOS 26 Safari, скрины Юли 20:53 и 21:51): у плавающей адресной строки
   Safari рисует страницу до низа экрана, но fixed-элементы обрезает по краю над этой зоной — снизу светлая полоса.
   Лечение по Apple: в header.php к meta viewport добавлено viewport-fit=cover (fixed-слой доходит до низа экрана),
   а всё, что прижато к низу, поднимаем на env(safe-area-inset-bottom), чтобы кнопки остались на прежнем месте
   и не ушли под адресную строку. Шапку сдвигаем на env(safe-area-inset-top), чтобы не залезла под часы.
   На устройствах без зоны env() = 0 — ничего не меняется. Откат: убрать viewport-fit=cover из header.php. ==== */
@media(max-width:1023px){
  html body .fixed_menu::before{
    height:calc(112px + env(safe-area-inset-bottom, 0px)) !important; bottom:0 !important;
    background:linear-gradient(to bottom, rgba(16,24,32,0) 0px, rgba(16,24,32,.22) 112px, rgba(16,24,32,.22) 100%) !important;
  }
  html body .header_burger{ bottom:calc(20px + env(safe-area-inset-bottom, 0px)) !important; }
  html body > .scroll_top_link.scroll-top-moved{ bottom:calc(20px + env(safe-area-inset-bottom, 0px)) !important; }
  html body .fixed_menu::after{ bottom:calc(20px + env(safe-area-inset-bottom, 0px)) !important; }
  html body .header.header_for_scroll, html body .header{ top:env(safe-area-inset-top, 0px) !important; }
  html body .header .header_menu{ top:calc(0px - env(safe-area-inset-top, 0px)) !important; } /* панель меню внутри шапки — не сдвигать вместе с ней */
}
@media(max-width:499px){
  html body .header .header_menu{ padding-bottom:calc(75px + 100vh - 100dvh + env(safe-area-inset-bottom, 0px)) !important; }
}

/* ==== ПУБЛ4 01.10 (п1, «О нас», моб/планшет): первый экран обрезан — заголовок наезжал на логотип.
   Та же причина, что у главной (см. выше «hero = 100dvh − 100dvh»): .fixed_menu на ≤1023 растянут на весь экран,
   --fixed-menu-h = высота окна → высота hero падала до min-height 373px. Даём полосу нижнего меню из макета, 112px. ==== */
@media(max-width:1023px){
  html body .ab_hero_section{ --fixed-menu-h:112px; }
}

/* ==== ПУБЛ4 01.10 (п3, моб, «ссылки в подвале не работают»): закрытое бургер-меню перехватывало нажатия.
   Пункт «Продукция» в меню всегда .active, его .acc_body (position:absolute, pointer-events:all из header.min.css)
   висел прозрачным прямоугольником поверх правой колонки подвала и середины экрана на ЛЮБОЙ странице.
   Лечение было описано 24.09 (блок «меню закрыто — ничего внутри не ловит палец»), но само правило в файл не попало.
   Меню закрыто = у body нет .burger-open → внутри .header_menu нажатия не принимает ничто. ==== */
@media(max-width:1023px){
  html body:not(.burger-open) .header .header_menu,
  html body:not(.burger-open) .header .header_menu *{ pointer-events:none !important; }
}

/* ==== ПУБЛ4 01.10 (п4, статья, моб): до «Других статей» 80px от конца текста, как в макете 2119:11155.
   Было 40 (низ редактора) + 80 (низ обёртки) = 120, плюс пустые <br>/<p> в конце текста статей — до 170.
   Пустой хвост текста срезает custom-fixes.js (ПУБЛ4 п4). ==== */
@media(max-width:1023px){
  html body .art_dtl_wrap .art_dtl_editor{ padding-bottom:0; }
  html body .art_dtl_wrap{ padding-bottom:80px; }
}

/* ==== ПУБЛ4 01.10 (п2, карточка типового решения, телефон ≤767; планшет 768–1023 остаётся на вёрстке подрядчика): сборка по макету 2793:3792.
   Порядок: крошки → «ТИПОВЫЕ РЕШЕНИЯ» → миниатюры → фото → название | артикул → гарантии → описание →
   вместимость → характеристики → полные характеристики → цена → «в наличии» → «купить» → похожие решения.
   Разметку не трогаем: .ssd_hero_inner и .ssd_hero_info растворяем (display:contents), их детей раскладывает
   сетка контейнера. Описание — отдельная секция ниже; на ≤767 custom-fixes.js (ПУБЛ4 п2) переносит её
   в контейнер карточки (область desc), на десктопе возвращает обратно.
   Отступы: порядок по макету, вертикальные интервалы ×1.3–2 к макету (01.10, по фидбеку Юли «чуть больше» — кегли на сайте вдвое крупнее макетных). Кегли — по шкале сайта: H1 макета 21 → 21 (как «Типовые решения» в списке),
   заголовок 14 → 16 (как прочие подзаголовки моб. версии); подписи 4/6 в макете на сайте везде 8/12 — оставлены. ==== */
@media(max-width:767px){
  html body .ssd_hero_section{ padding-bottom:70px !important; }
  html body .ssd_hero_section > .container{
    display:grid !important;
    grid-template-columns:minmax(0,1fr) auto !important;
    column-gap:10px !important;
    grid-template-areas:
      "crumbs crumbs" "head head" "thumbs thumbs" "image image" "title art" "guar guar" "desc desc"
      "cap cap" "specs specs" "full full" "price price" "bottom bottom" !important;
    align-items:start !important;
  }
  html body .ssd_hero_section .ssd_hero_inner,
  html body .ssd_hero_section .ssd_hero_info{ display:contents !important; }

  html body .ssd_hero_section .breadcrumbs_wrap{ grid-area:crumbs !important; margin:0 !important; }
  /* «ТИПОВЫЕ РЕШЕНИЯ» — шапка раздела из макета, стиль = h1 .ss_title страницы списка (моб.) */
  html body .ssd_hero_section > .container::before{
    content:"ТИПОВЫЕ РЕШЕНИЯ" !important; grid-area:head !important; display:block !important; margin-top:39px !important;
    font-family:RobotoFlex,Arial,sans-serif !important; font-size:21px !important; line-height:116% !important; text-transform:uppercase !important; color:#101820 !important;
    font-variation-settings:"GRAD" 150,"opsz" 144,"wdth" 151,"wght" 805 !important;
  }
  html body .ssd_hero_section .ssd_hero_gallery{ grid-area:thumbs !important; margin:50px 0 0 !important; }
  html body .ssd_hero_section .ssd_hero_main_image{ grid-area:image !important; margin:10px 0 0 !important; }
  /* фото — квадрат 335×335 как в макете; первый слайд галереи = фото (кадрируем по рамке),
     остальные — планировки: вписываем целиком, без обрезки */
  html body .ssd_hero_section .ssd_hero_main_image,
  html body .ssd_hero_section .ssd_hero_main_image .ssd_hero_main_slr,
  html body .ssd_hero_section .ssd_hero_main_image .swiper-wrapper{ height:auto !important; }
  html body .ssd_hero_section .ssd_hero_main_image .swiper-slide,
  html body .ssd_hero_section .ssd_hero_main_image .zoom-container{ height:auto !important; aspect-ratio:1/1 !important; }
  html body .ssd_hero_section .ssd_hero_main_image .ss_plan_open_img,
  html body .ssd_hero_section .ssd_hero_main_image .ss_plan_open_img img{ width:100% !important; height:100% !important; }
  html body .ssd_hero_section .ssd_hero_inner .ssd_hero_main_image .ssd_hero_main_slr .swiper-slide:first-child .zoom-container .ss_plan_open_img img{ object-fit:cover !important; }
  html body .ssd_hero_section .ssd_hero_title{
    grid-area:title !important; margin:24px 0 0 !important; font-size:16px !important; line-height:116% !important;
  }
  html body .ssd_hero_section .ssd_hero_article{
    grid-area:art !important; margin:24px 0 0 !important; text-align:right !important; white-space:nowrap !important;
  }
  html body .ssd_hero_section .ssd_hero_guarantees{ grid-area:guar !important; margin:40px 0 0 !important; }
  html body .ssd_hero_section .ssd_hero_guarantee_items{ grid-template-columns:1fr 1fr !important; gap:10px !important; }

  /* описание, перенесённое скриптом внутрь карточки */
  html body .ssd_hero_section .ssd_description_section{ grid-area:desc !important; margin:30px 0 0 !important; padding:0 !important; }
  html body .ssd_hero_section .ssd_description_section > .container{ padding:0 !important; max-width:none !important; width:auto !important; }

  html body .ssd_hero_section .ssd_hero_capacity{ grid-area:cap !important; margin:50px 0 0 !important; }
  html body .ssd_hero_section .ssd_hero_capacity_label{ margin:0 0 10px !important; }
  html body .ssd_hero_section .ssd_hero_specs{
    grid-area:specs !important; margin:20px 0 0 !important;
    display:grid !important; grid-template-columns:1fr 1fr !important; column-gap:10px !important; row-gap:20px !important;
  }
  html body .ssd_hero_section .ssd_hero_spec_row{ display:contents !important; }
  html body .ssd_hero_section .ssd_hero_spec_row:not(:first-child) .ssd_hero_spec_item{ grid-column:1 !important; }
  html body .ssd_hero_section .ssd_hero_full_specs_link{ grid-area:full !important; margin:30px 0 0 !important; }
  html body .ssd_hero_section .ssd_hero_price{ grid-area:price !important; margin:60px 0 0 !important; }
  html body .ssd_hero_section .ssd_hero_bottom{ grid-area:bottom !important; margin:30px 0 0 !important; }
  html body .ssd_hero_section .ssd_hero_availability{ margin:0 0 12px !important; }
}
/* ==================== ПУБЛ4 02.10.2026 — Liqium ====================
   Правка клиента (вкладка «После публикации 4»):
   «При открытии главного меню в сафари под адресной строкой появляется фон, он не нужен».

   ПРИЧИНА. 30.09 (v3) мы добавили в header.php `viewport-fit=cover`, чтобы fixed-слой
   доходил до физического низа экрана, и продлили панель меню на высоту плавающей
   адресной строки Safari:
       .header_menu { padding-bottom: calc(75px + 100vh - 100dvh + env(safe-area-inset-bottom)) }
   `100vh - 100dvh` — это ровно высота адресной строки. Панель меню имеет свой фон,
   поэтому её продление в эту зону и даёт полосу фона ПОД адресной строкой.
   Сверху тот же эффект даёт `.header_menu { top: -env(safe-area-inset-top) }`:
   панель заходит в верхнюю safe-area зону (актуально, если адресная строка вверху).

   ЛЕЧЕНИЕ. Панель меню ограничиваем видимой областью (100dvh) — она заканчивается
   ровно над адресной строкой, фону под ней появиться негде. Продление padding'ом
   убираем, крестик при этом остаётся на месте: он позиционируется от 100dvh.

   ВНИМАНИЕ: вариант Б (ниже, закомментирован) — если у клиента адресная строка
   СВЕРХУ. Выбирается по скриншоту с устройства, не наугад.
   ОТКАТ: удалить этот блок целиком (маркер «ПУБЛ4»).
   ==================================================================== */

/* --- Вариант А: адресная строка Safari внизу (поведение по умолчанию, iOS 15+) --- */
@media(max-width:1023px){
  /* панель меню — строго по видимой высоте, без захода под адресную строку */
  html body .header .header_menu{
    height:100dvh !important;
    max-height:100dvh !important;
  }
}
@media(max-width:499px){
  /* продление на высоту адресной строки убрано: было calc(75px + 100vh - 100dvh + env(...)) */
  html body .header .header_menu{ padding-bottom:75px !important; }
}

/* --- Вариант Б: адресная строка Safari вверху (включается вручную, если скрин покажет фон СВЕРХУ) ---
@media(max-width:1023px){
  html body .header .header_menu{ top:0 !important; }
  html body .header.header_for_scroll, html body .header{ top:0 !important; }
}
--- конец варианта Б --- */




/* ==== 01.10-07.10.2026 (Атлас, затемнение моб, Safari iOS 26+): подложка —
   отдельный блок .fixed_menu_shade + добивка .fixed_menu_shade_tail, JS (чанк
   fixedMenu) пиннит их к низу экрана (rAF), под плавающую панель Safari.
   Замеры iPhone iOS 26.5 с устройства: fixed-слой обрезается по низу layout
   viewport (796 с панелью / 836 без при screen 896), flow-контент дорисовывается
   до дна — поэтому absolute в потоке + пин translateY до screen.height.
   Гейт — класс html.fmShade, его JS вешает только на классический Safari 26+
   (UA Version/26+ Safari без CriOS/FxiOS/EdgiOS). Chrome iOS, старый Safari,
   Android и прочие: класса нет, ::before ПУБЛ3 работает как раньше.
   Откат: удалить блок (бэкапы файла: custom-fixes.css.bak-shade-20261001,
   .bak-shade-v9-20261007, .bak-shade-v10-20261007). ==== */
html.fmShade body .fixed_menu::before{ display:none !important; }
@supports (-webkit-touch-callout: none){
@media(max-width:1023px){
  html.fmShade body .fixed_menu_shade{
    position:absolute !important; top:0 !important; bottom:auto !important; left:0 !important; right:0 !important;
    height:calc(112px + env(safe-area-inset-bottom, 0px)) !important;
    background:linear-gradient(to bottom, rgba(16,24,32,0) 0px, rgba(16,24,32,.22) 112px, rgba(16,24,32,.22) 100%) !important;
    pointer-events:none !important; z-index:314 !important;
  }
  /* добивка screen.height − lvh до физического дна (высоту ставит JS) */
  html.fmShade body .fixed_menu_shade_tail{
    position:absolute !important; top:0 !important; bottom:auto !important; left:0 !important; right:0 !important;
    background:rgba(16,24,32,.22) !important;
    pointer-events:none !important; z-index:314 !important;
  }
  html.fmShade body.burger-open .fixed_menu_shade, html.fmShade body.burger-open .fixed_menu_shade_tail{ opacity:0 !important; }
}
}
