/* ===================================================================
   opt.css — стили страницы /opt/ «Ткани оптом»
   Подключается последним, после всех css сайта.

   Порядок правил повторяет порядок секций на странице.
   Медиазапросы стоят сразу после правила, к которому относятся.

   Правила с пометкой [перенос] скопированы из /styles/printing.css
   (версия v=1769760544) — там они описывают компоненты, которые на сайте
   есть только на странице принтования. Сам printing.css к главной не
   подключается, поэтому нужные правила лежат здесь.

   Каждое такое правило ограничено своим классом секции: .opt-adv
   для секций 7 и 9. Без этого голый селектор
   вроде .printing-advantages__item уехал бы по всему сайту и сломал бы
   страницы, которых мы не видели, — прямой запрет из
   PRAVILO-izolyaciya-pravok.md.

   Перенесённые правила сайтовых этапов .steps удалены 23.08.2026: секция 8
   переведена на собственный компонент «Дорожка», сайтовый со страницы ушёл.

   При изменении вида этих компонентов на странице принтования их надо
   править и тут: два источника, синхронизация ручная.
   =================================================================== */


/* ===== Общее: заглушки блоков уровня 3 и служебные подписи ===== */
/* Только для прохода 1. В финальной вёрстке заглушек не остаётся. */

.opt-stub {
    margin: 0 0 20px;
    padding: 24px;
    border: 2px dashed #95C7EF;
    border-radius: 16px;
    background-color: #F1F8FE;
    color: #102F97;
    font-size: 15px;
    line-height: 1.5;
    text-align: center;
}

.opt-stub--inline {
    padding: 12px 16px;
    margin-bottom: 12px;
    font-size: 14px;
    text-align: left;
}

.opt-note {
    margin: 12px 0 0;
    font-size: 12px;
    line-height: 1.4;
    color: #9A9CA3;
}


/* ===== Секция 1. Первый экран ===== */
/* Фон первого экрана — стена из квадратных плиток ткани, поставлена
   25.08.2026 по решению заказчика. По краям ткани в полную силу, в середине
   прогалина, где стоит текст. Заливки поверх стены нет специально: она бы
   приглушила ткани, ради которых всё и затевалось.

   ЧТО ЗАМЕНИЛА. Видео драпировки под стеклянной карточкой с текстом слева.
   Правила фона, видео и карточки (.opt-hero__bg, .opt-hero__img,
   .opt-hero__video, .opt-hero__text вместе с блоком @supports про
   backdrop-filter) удалены целиком: ни один из этих узлов в разметке
   больше не встречается. Файлы роликов и постера на странице не нужны
   и в архив для выгрузки не кладутся — они остались в рабочей папке
   проекта, там их и брать, если фон решат вернуть.

   Заодно ушёл расчёт плотности матового стекла (55 % краски, blur 20 px):
   он был привязан к конкретному ролику и к тёмному тексту поверх него.
   Новый фон читаемость решает иначе — прогалиной, — и считать там нечего.

   Приём взят с лендинга /111/, композиция утверждена там 23.08.2026.
   Перенесён вместе с картинками, скриптом и списком тканей. */

.opt-hero {
    position: relative;
    overflow: hidden;
    display: flex;
    align-items: center;
    padding: 60px 0;
    background-color: #FFFFFF;
    min-height: 700px;
}

/* ПОЧЕМУ 700, А НЕ 540 КАК В ДОНОРЕ.

   Высота первого экрана здесь не украшение, а рабочее число: от неё
   напрямую зависит, останется ли на экране ткань.

   Скрипт вырезает прогалину по габаритам текста и растушёвывает её край
   ещё на 22 %. У донора текст занимал 359 px при высоте секции 540 —
   прогалина забирала две трети, треть оставалась тканью. Наш текст в тех же
   условиях занимает 440 px: заголовок длиннее на две трети, лид на треть,
   плюс бейдж сверху и подписи под цифрами фактов, которых у донора не было.
   При 540 прогалина с растушёвкой перекрывает секцию целиком и стена
   пропадает вся, до последней плитки. Замерено, не на глаз.

   700 возвращает донорскую пропорцию: текст занимает те же две трети,
   сверху и снизу остаются полосы ткани. Отсюда правило на будущее: правят
   текст первого экрана — проверяют, не пропала ли стена. Сокращают текст —
   высоту можно вернуть обратно. */

@media (max-width: 1199px) {
    .opt-hero {
        min-height: 640px;
    }
}

/* ===== НИЖЕ 992 — ШАПКА «ВОЛНА» =====

   Выбрана заказчиком 29.08.2026 из четырёх показанных вариантов.

   КАК УСТРОЕНО. Стена из тканей занимает только верх экрана, снизу её
   срезает фирменная волна, текст лежит на белом поле под волной. Ткань
   над текстом не перекрыта ничем — ни заливкой, ни притемнением.

   ЧТО ЭТО ЗАМЕНИЛО. Стену во весь экран под сплошной синей вуалью 72 %
   с белым текстом поверх. Вуаль (.opt-hero::before), притемнение плиток
   (filter: brightness) и перекраска текста в белый удалены целиком.
   К вуали не возвращаться без нового запроса заказчика: решение записано
   в HANDOFF.md, пункты 40-43.

   ЧЕМ ПЛАТИМ. Ткани достаётся верхняя треть экрана вместо всего экрана.
   Заказчик это видел и принял.

   --wall-h — ВЫСОТА ПОЛОСЫ ТКАНИ И ЕДИНСТВЕННОЕ ЧИСЛО, КОТОРОЕ ТУТ КРУТЯТ.
   От неё считаются три вещи: высота стены, положение волны и верхний отступ
   секции. Меняют её — остальное едет следом само.

   40vh держит пропорцию макета (330 полосы из 844 экрана) на любом телефоне.
   Границы clamp нужны по краям: на низком экране полоса иначе вырождается
   в ленту, на высоком планшете забирает пол-экрана. Первая строка —
   запасная, для браузеров без clamp().

   min-height снят: высоту секции теперь задаёт полоса ткани плюс текст,
   и прежние 560/520 только мешали бы читать расчёт.

   ВЕРХНИЙ ОТСТУП СЧИТАЕТСЯ ОТ ГОЛУБОЙ ПОЛОСЫ ВОЛНЫ, А НЕ ОТ КРАЯ ТКАНИ.
   Волна — лента, а не заливка: белое поле начинается не внизу картинки,
   а на самой кривой. Ниже всего голубое опускается почти у правого края,
   в точке 378 : 79 системы координат волны, — это и есть настоящая граница,
   от которой меряется воздух под ней.

   Отсюда −2 px. Замерено на живой странице: нижняя голубая точка приходится
   на 453 px, бейдж начинается на 466 — просвет 13 px. Он одинаков на 320,
   375 и 768: волна тянется по ширине экрана вместе со всей геометрией.

   Стояло +26 px, от нижнего края всей волны. Отступ получался 40 px у краёв
   и под 90 px посередине, где кривая уходит вверх, — заказчик увидел это
   как провал между волной и текстом. Разница 28 px, на столько же
   укоротилась вся секция.

   Меньше −2 px не ставить: бейдж заедет на голубое. Оставшийся воздух
   посередине убрать нельзя вовсе, это форма самой кривой. */

@media (max-width: 991px) {
    .opt-hero {
        --wall-h: 240px;
        --wall-h: clamp(240px, 40vh, 380px);
        display: block;
        min-height: 0;
        padding: calc(var(--wall-h) - 2px) 0 40px;
        background-color: #FFFFFF;
    }
}

/* Настройки стены, которые читает скрипт.

   --tile-hint — желаемая сторона плитки в px. По ней скрипт считает, сколько
   влезет колонок и строк. На узком экране плитка мельче, иначе четыре
   крупных квадрата в ряд читаются пятнами, а не стеной.

   --card-w и --card-h — размер раскрытой плитки: квадратный кадр плюс полоса
   подписи под ним. Скрипт по ним проверяет, поместится ли карточка, не
   налезая на текст и не попадая под обрез.

   --wall-veil — флаг «прогалины нет, стена сплошная». Ставится только
   на телефоне, см. ниже. */

.opt-hero {
    --tile-hint: 88;
    --card-w: 170;
    --card-h: 264;
    --wall-veil: 0;
}

/* Плитка на телефоне и планшете крупная: 3-4 в ряд.

   Прежние 74 и 60 px давали шесть плиток в ряд, и стена читалась цветными
   пятнами, а не тканью. Заказчик забраковал это 29.08.2026 во всех четырёх
   показанных вариантах.

   Числа подобраны так, чтобы в ряд всегда вставало 3-4 плитки: 240 даёт
   4 колонки на 991 и 3 на 768, 125 даёт ровно 3 на любом телефоне
   от 320 до 575. Скрипт делит ширину стены на это число и округляет. */

/* --wall-rotate — флаг «стена меняет ткани». Читает его скрипт.

   Смысл флага: на компьютере стена показывает себя раскрытием плитки
   с названием и ценой, на телефоне раскрывать негде — там вместо этого
   одна плитка раз в четыре секунды медленно проявляет другую ткань.
   Один приём выключает другой, поэтому флаг, а не два независимых
   правила. Подробности и арифметика трафика — в hero-wall.js.

   Значение по умолчанию стоит ДО медиазапроса. Иначе оно, стоя после него
   с той же силой селектора, перебило бы включение и смена не запускалась
   бы нигде. */

.opt-hero {
    --wall-rotate: 0;
}

@media (max-width: 991px) {
    .opt-hero {
        --tile-hint: 240;
        --card-w: 148;
        --card-h: 242;
        --wall-rotate: 1;
    }
}

/* На планшете и телефоне прогалины в стене нет: стена идёт сплошной.

   Прогалина — это овал, который скрипт вырезает в стене по габаритам текста,
   чтобы текст лежал на чистом фоне. На широком экране она работает: текст
   стоит посреди стены, вокруг остаются поля с тканью.

   Ниже 992 текста под стеной нет вообще — он ушёл на белое поле под волной.
   Вырезать в полосе ткани дырку не по чему и незачем.

   --wall-veil: 1 — это и есть флаг «прогалину не считать». Имя осталось
   от прежнего варианта с синей вуалью; вуали больше нет, флаг живёт. */

@media (max-width: 991px) {
    .opt-hero {
        --wall-veil: 1;
    }
}

@media (max-width: 575px) {
    .opt-hero {
        --tile-hint: 125;
        --card-w: 130;
        --card-h: 224;
    }
}

/* Число колонок и строк проставляет скрипт, поэтому клетки всегда точно
   закрывают секцию и по краям не остаётся полосы фона. */

.opt-hero__wall {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-columns: repeat(var(--cols, 12), 1fr);
    grid-template-rows: repeat(var(--rows, 6), 1fr);
    gap: 6px;
}

/* Ниже 992 стена перестаёт быть фоном во весь экран и становится полосой
   ткани в верхней части. Высота одна на всех — --wall-h, объявлена выше
   у .opt-hero.

   Фон стены тёмный, а не белый: сквозь швы между плитками виден именно он.
   На белом швы пропадают и плитки слипаются в одно пятно, тёмная сетка
   держит их отдельными кадрами. Цвет — #0F172A, тот же, что у текста
   страницы; своей краски не появилось. */

@media (max-width: 991px) {
    .opt-hero__wall {
        height: var(--wall-h);
        gap: 4px;
        background-color: #0F172A;
    }
}

/* ВОЛНА. Срезает низ полосы ткани и передаёт экран белому полю с текстом.

   Приём не новый: тот же срезанный край заливкой #E0EAF2 уже стоит
   на других экранах сайта. Разметка волны — в index.html, две кривые
   в одном svg: верхняя рисует голубую полосу, нижняя закрывает её белым.

   Положение считается от --wall-h, а не задаётся числом. -94px — насколько
   волна заходит вверх на ткань; 120px — её высота. В сумме нижний край
   волны стоит на 26 px ниже полосы ткани, и ровно на столько же больше
   верхний отступ секции: текст начинается там, где волна кончилась.
   Трогают одно — правят и второе.

   На десктопе волны нет: там стена во весь экран и текст лежит на ней. */

.opt-hero__wave {
    display: none;
}

@media (max-width: 991px) {
    .opt-hero__wave {
        display: block;
        position: absolute;
        left: 0;
        top: calc(var(--wall-h) - 94px);
        z-index: 2;
        width: 100%;
        height: 120px;
    }
}

.opt-hero__slot {
    position: relative;
}

/* Плитка лежит абсолютом внутри клетки и раскрывается в место, которое ей
   посчитал скрипт: --ax и --ay — сдвиг относительно клетки, --aw и --ah —
   конечный размер. Симметричного роста нет специально: у края экрана плитка
   раскрывается в сторону центра и не попадает под обрез.

   Скорости разные. Раскрывается неспешно, .42s, — это показ. Сворачивается
   быстро, .3s, — это уборка, её не разглядывают. Быстрое значение стоит
   в основном правиле, поэтому применяется как раз при снятии класса. */

.opt-hero__card {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: 6px;
    background: #E2EAF2;
    transition: top .3s ease, left .3s ease, width .3s ease, height .3s ease, box-shadow .3s ease;
}

.opt-hero__card picture {
    flex: 1 1 auto;
    min-height: 0;
    display: block;
}

/* Картинка проявляется, а не возникает рывком.

   До прихода картинки плитка залита средним цветом своей ткани — его ставит
   скрипт по полю c из json. Класс is-ready вешает он же, когда браузер
   сказал, что картинка загружена.

   Прозрачность по умолчанию нулевая. Это безопасно: без скрипта плиток
   в разметке нет вовсе, а значит и прятать нечего. */

.opt-hero__card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0;
    transition: opacity .35s ease;
}

.opt-hero__card img.is-ready {
    opacity: 1;
}

/* Кадр смены: новая ткань проявляется поверх прежней.

   Прежний кадр не гасим специально. Гасить оба навстречу — значит на
   середине показать сквозь них подложку, и ровное проявление превращается
   в мигание. Новый кадр непрозрачен к концу перехода, поэтому старый
   просто исчезает под ним, а скрипт убирает его следом.

   Кривая ease-out-quart: быстро набирает и мягко доводит до конца. Ткань
   успевает прочитаться до того, как проявление формально закончилось,
   и смена не выглядит долгой при своих 900 мс.

   Правило общее, не в медиазапросе: узел .opt-hero__shot создаётся только
   на тех ширинах, где смена включена, и на компьютере его в разметке нет. */

.opt-hero__shot {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    transition: opacity .9s cubic-bezier(.25, 1, .5, 1);
}

.opt-hero__shot.is-in {
    opacity: 1;
}

/* Просят не анимировать — смена не запускается вовсе, скрипт проверяет
   это первым делом. Правило ниже страхует случай, когда настройку
   переключили при уже открытой странице: начатое проявление
   доводится мгновенно, кадр не зависает полупрозрачным. */

@media (prefers-reduced-motion: reduce) {
    .opt-hero__shot {
        transition: none;
    }
}

/* Поверх соседей плитка держится и пока раскрыта, и всё время, пока
   сворачивается. Если отпустить её раньше, она на полпути ныряет под
   соседние плитки и по краям мелькают углы. */

.opt-hero__slot.is-awake,
.opt-hero__slot.is-leaving {
    z-index: 5;
}

.opt-hero__slot.is-awake {
    z-index: 100;
}

.opt-hero__slot.is-awake .opt-hero__card {
    top: var(--ay, 0px);
    left: var(--ax, 0px);
    width: var(--aw, 100%);
    height: var(--ah, 100%);
    box-shadow: 0 18px 40px rgba(15, 23, 42, .28);
    transition: top .42s cubic-bezier(.2, .7, .3, 1), left .42s cubic-bezier(.2, .7, .3, 1), width .42s cubic-bezier(.2, .7, .3, 1), height .42s cubic-bezier(.2, .7, .3, 1), box-shadow .42s ease;
}

/* Подпись стоит ПОД кадром, а не поверх: ткань ничем не закрывается.
   В покое её высота ноль, поэтому плитка показывает картинку целиком.
   Гаснет мгновенно и без задержки — сначала пропадает текст, потом уезжает
   карточка, а не наоборот.

   Тёмная подложка — единственный способ гарантировать читаемость подписи
   поверх любой ткани. */

.opt-hero__cap {
    flex: 0 0 auto;
    height: 0;
    padding: 0 10px;
    overflow: hidden;
    background: rgba(15, 23, 42, .9);
    opacity: 0;
    transition: height .3s ease, padding .3s ease, opacity .1s ease;
}

.opt-hero__slot.is-awake .opt-hero__cap {
    height: 94px;
    padding: 9px 10px;
    opacity: 1;
    transition: height .42s cubic-bezier(.2, .7, .3, 1), padding .42s cubic-bezier(.2, .7, .3, 1), opacity .24s ease .2s;
}

/* Названия тканей бывают длинные — «Атлас сатин стретч жемчужный
   с розовинкой» занимает три строки и выдавливает цену за край подписи.
   Обрезаем в две строки, цену показываем всегда: она важнее хвоста названия. */

.opt-hero__cap-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    line-height: 130%;
}

.opt-hero__cap-desc {
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin-top: 2px;
    color: rgba(255, 255, 255, .72);
    font-size: 10px;
    line-height: 130%;
}

.opt-hero__cap-price {
    display: block;
    margin-top: 3px;
    color: #FFD400;
    font-size: 12px;
    font-style: normal;
    font-weight: 600;
}

/* Текст первого экрана. Стоит по центру, поверх стены.

   ШИРИНА ТЕКСТА ЗДЕСЬ — РАБОЧЕЕ ЧИСЛО, А НЕ ВКУС. Скрипт вырезает прогалину
   по габаритам этого блока. Шире блок — шире прогалина и уже поле между
   текстом и краем секции. А в это поле должны поместиться сразу две вещи:
   полоса ткани, ради которой всё затевалось, и раскрытая карточка.

   Отсюда формула вместо простого числа: держим поле по краям постоянным,
   170 px с каждой стороны, а ширину текста отдаём тому, что осталось.
   На широком экране упираемся в 940 — дальше строка становится слишком
   длинной для чтения.

   Что было до формулы. Стояло твёрдое 940, и на 1200 поле схлопывалось
   до 130 px: полосы ткани по бокам не оставалось, карточке было некуда
   встать, показ выключался целиком. Замерено: ноль плиток из 104.
   Ступеньки по брейкпоинтам эту беду не лечат — они ломаются каждая
   на своей нижней границе, и приходится ставить всё новые.

   Первая строка — запасная, для браузеров без min(): там останется 940,
   как было. Вторая — рабочая.

   На планшете и телефоне ограничение снимается: там прогалины нет вовсе,
   текст идёт во всю ширину контейнера. */

.opt-hero__inner {
    position: relative;
    z-index: 2;
    max-width: 940px;
    max-width: min(940px, calc(100vw - 340px));
    text-align: center;
}

@media (max-width: 991px) {
    .opt-hero__inner {
        max-width: none;
    }
}

/* Размер заголовка идёт в паре с шириной текста выше: та сужается вместе
   с экраном, и твёрдые 54 px на суженном блоке уводят заголовок в три
   строки. Три строки — это плюс 60 px к высоте прогалины, то есть минус
   полоса ткани сверху и снизу.

   Поэтому размер тоже плавный. 3.75vw подобран так, чтобы заголовок
   оставался в двух строках на всём ходу: на 1440 даёт ровно 54, на 1280 —
   48, на 1024 — 38. Первая строка — запасная, для браузеров без clamp(). */

.opt-hero__title {
    margin: 16px 0 0;
    font-size: 54px;
    font-size: clamp(38px, 3.75vw, 54px);
    line-height: 1.06;
    font-weight: 700;
    color: #0F172A;
    letter-spacing: -1.2px;
    text-wrap: balance;
}

@media (max-width: 991px) {
    .opt-hero__title {
        font-size: 36px;
        letter-spacing: -0.6px;
    }
}

@media (max-width: 575px) {
    .opt-hero__title {
        font-size: 27px;
    }
}

/* Лид уже заголовка: длинная строка в 940 px читается тяжело, глазу негде
   зацепиться при переходе на следующую. 640 даёт привычные 80-90 знаков. */

.opt-hero__lead {
    max-width: 640px;
    margin: 16px auto 0;
    font-size: 16px;
    line-height: 22.4px;
    color: #0F172A;
    text-wrap: pretty;
}

/* Ниже 576 лид чуть мельче: он стоит на белом поле волны, а его высота
   напрямую решает, влезает ли первый экран в телефон целиком. */

@media (max-width: 575px) {
    .opt-hero__lead {
        margin-top: 12px;
        font-size: 15px;
        line-height: 21px;
    }
}

.opt-hero__btns {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin-top: 28px;
}

/* Кнопки на телефоне идут столбиком во всю ширину. Цвет у синей кнопки
   сайтовый, .btn-blue без правок: она стоит на белом поле волны, а не
   на синей вуали, и перекрашивать её больше незачем. */

@media (max-width: 575px) {
    .opt-hero__btns {
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
        margin-top: 20px;
    }
}

/* Пальцу нужно 44 px. Замерено на 375: сайтовая .btn-blue давала в первом
   экране 40 px, контурная 42 — обе ниже порога. Это и расхождение
   с собственной работой: форма в секции 14 даёт 52 px, кнопки счётчика
   в секции 6 — 50, строки ступеней — 53. Первый экран был единственным
   местом, где кнопки оказались мельче остальных.

   Правится отступом, а не высотой: у сайтовой кнопки строка 16 px / 1.2,
   то есть 19,2 px, плюс 2 x 13 = 45,2. У контурной те же 19,2 плюс
   2 x 12 и две рамки по 1 px — те же 45,2. Числа разные специально,
   чтобы кнопки вышли одинаковыми, а не «примерно такими же».

   Правило скоупнуто на .opt-hero: сайтовую кнопку в других местах
   страницы оно не трогает. */

@media (max-width: 991px) {
    .opt-hero .btn-blue {
        padding: 13px 16px;
    }
}

/* Видимая обводка фокуса. На сайте обводка погашена глобально
   (styles/cart-style.css), и без своего правила кнопка первого экрана
   при ходьбе табом ничем не отзывалась: менялся только цвет, ровно как
   при наведении. Для клавиатуры это не отличимо от «ничего не произошло».

   Значения те же, что у всех остальных своих компонентов, — 2 px #102F97
   с отступом 2 px, см. .opt-calc__tier и .opt-segments__card. Первый экран
   был единственным местом, где этого правила не хватало. */

/* !important ЗДЕСЬ ОБЯЗАТЕЛЕН, И ВОТ ПОЧЕМУ.

   В сайтовом main.min.css стоит правило `:focus { outline: 0 !important; }`.
   Оно глушит обводку на всей странице, и специфичностью его не перебить:
   !important побеждает любой селектор без !important, сколько классов
   к нему ни добавляй. Единственный способ вернуть обводку, не трогая
   чужой файл, — ответить тем же.

   Правило изоляции проекта это допускает: «!important — крайняя мера,
   и рядом с ним комментарий, что он перебивает и почему иначе не вышло».
   Это тот случай.

   ЗАЧЕМ ВООБЩЕ. Без обводки страница не проходит собственное требование
   `PRODUCT.md`: «вся интерактивность доступна с клавиатуры, фокус виден».
   При ходьбе табом кнопки менялись только цветом, ровно как при наведении,
   и понять, где сейчас курсор, было нельзя.

   ОБНАРУЖЕНО 29.08.2026 замером в браузере. Все девять правил фокуса
   в этом файле были мёртвыми с момента написания — проверка «правило
   есть в таблице стилей» этого не ловит, надо смотреть, какое правило
   победило. Единственное, что работало, — `.opt-segments__card`:
   там кольцо нарисовано через box-shadow, а его сайт не глушит. */

.opt-hero .btn-blue:focus-visible,
.opt-hero__btn-ghost:focus-visible {
    outline: 2px solid #102F97 !important;
    outline-offset: 2px;
}

/* Вторая кнопка — белая заливка с синей рамкой и синим текстом. Осталась
   от прежнего первого экрана без изменений: она была нарисована под фон
   из ткани, а стена — та же задача. Прозрачная контурная кнопка на ткани
   теряет края, белая заливка отделяет её от фона при любой плитке.
   На белом поле волны кнопку держит синяя рамка — трогать нечего. */

.opt-hero__btn-ghost {
    display: inline-block;
    padding: 10.5px 16px;
    border: 1px solid #102F97;
    border-radius: 8px;
    background: #FFFFFF;
    color: #102F97;
    font-size: 16px;
    line-height: 1.2;
    text-decoration: none;
    transition: all 300ms ease-in-out;
}

.opt-hero__btn-ghost:hover,
.opt-hero__btn-ghost:focus {
    border-color: #102F97;
    background: #102F97;
    color: #FFFFFF;
    text-decoration: none;
}

/* Высота под палец, пара к правилу для .btn-blue выше. 19,2 px строки
   плюс 2 x 12 отступа плюс две рамки по 1 px = 45,2 — ровно столько же,
   сколько у синей кнопки, чтобы кнопки вышли одинаковыми.

   Медиазапрос стоит здесь, а не в блоке кнопок выше. Там он уже был
   и не работал: сила селектора та же, а базовое правило .opt-hero__btn-ghost
   идёт ниже по файлу и перебивало его. */

@media (max-width: 991px) {
    .opt-hero__btn-ghost {
        padding: 12px 16px;
    }
}

/* Факты: столбцы с вертикальными волосяными линиями.
   Читается как таблица параметров, а не как отдельный виджет.

   Разделители переехали с левой границы на правую: у центрированного блока
   первый и последний столбец должны быть без линии по внешнему краю, а при
   border-left линия оставалась бы у последнего. */

.opt-hero__facts {
    display: flex;
    flex-wrap: wrap;
    margin: 28px 0 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid rgba(16, 47, 151, 0.25);
}

.opt-hero__fact {
    flex: 1 1 0;
    min-width: 180px;
    margin: 0;
    padding: 18px 20px 4px;
    border-right: 1px solid rgba(16, 47, 151, 0.25);
}

.opt-hero__fact:last-child {
    border-right: 0;
}

@media (max-width: 1199px) {
    .opt-hero__fact {
        padding: 14px 16px 4px;
    }
}

/* На телефоне факты остаются тремя столбцами, а не встают друг под друга.

   Раньше они складывались в три строки: на синей вуали текста было мало
   и место позволяло. Теперь верх экрана забрала полоса ткани, и три строки
   уводят кнопки за нижний край. Три столбца занимают 60 px вместо 150.

   Цифра мельчает до 14 px, подпись до 11 px. Это не вкус, а замер: самое
   длинное значение, «в день оплаты», занимает при 15 px 105 px, а столбец
   на экране 375 даёт 100. Значение рвалось на две строки, подпись под ним
   съезжала вниз, и ряд переставал читаться таблицей. При 14 px влезает. */

@media (max-width: 575px) {
    .opt-hero__facts {
        margin-top: 18px;
    }

    .opt-hero__fact {
        min-width: 0;
        padding: 14px 5px 0;
    }
}

.opt-hero__fact-value {
    display: block;
    white-space: nowrap;
    font-size: 20px;
    line-height: 1.15;
    font-weight: 700;
    color: #0F172A;
    letter-spacing: -0.4px;
}

@media (max-width: 1199px) {
    .opt-hero__fact-value {
        font-size: 18px;
    }
}

@media (max-width: 575px) {
    .opt-hero__fact-value {
        font-size: 14px;
        letter-spacing: -0.3px;
        white-space: normal;
    }
}

.opt-hero__fact-label {
    display: block;
    margin-top: 4px;
    font-size: 13px;
    line-height: 17px;
    color: #0F172A;
}

@media (max-width: 575px) {
    .opt-hero__fact-label {
        margin-top: 3px;
        font-size: 11px;
        line-height: 14px;
        color: #666666;
    }
}

/* Плашка-бейдж (уровень 2: Highlight из дизайн-системы).
   Используется на первом экране и в секции 6.

   ЦВЕТ ТЕКСТА ИСПРАВЛЕН 29.08.2026 ПО ЗАМЕРУ КОНТРАСТА. Стоял барвинковый
   #5D7DCF — он давал по жёлтому #FDEFC5 всего 3,46 : 1 при норме 4,5 для
   текста 14 px. Это нарушало собственное правило дизайн-системы «контраст
   основного текста не ниже 4,5:1» и било по обоим местам, где плашка стоит.

   Взят чертёжный синий #102F97 — 9,77 : 1. Своей краски не появилось: это
   основной синий системы, тот же, что у кнопки рядом. Барвинковый в системе
   остаётся, но он цвет наведения на кнопке, а не цвет текста по жёлтому. */

.opt-highlight {
    display: inline-block;
    padding: 5px 16px 6px;
    border-radius: 16px;
    background-color: #FDEFC5;
    color: #102F97;
    font-size: 14px;
    line-height: 20px;
    font-weight: 500;
}


/* ===== Секция 2. Полоса цифр о компании ===== */
/* Уровень 2. Компонента на сайте нет; значения — токен StatItem из
   дизайн-системы: цифра 30 px / 700 / #102F97, подпись 14/18 / #666666.
   Композиция выбрана заказчиком 21.08 из восьми показанных вариантов —
   «один герой и четыре рядом». Главная цифра вынесена крупно слева,
   остальные четыре сеткой справа. Это решает две вещи: задаёт порядок
   чтения и снимает проблему ряда из пяти неравных ячеек.
   Разделитель #95C7EF — цвет рамки полей ввода на сайте.
   Подложка #F1F8FE — цвет подсветки строки на сайте. */

.opt-facts__row {
    display: flex;
    flex-wrap: wrap;
    gap: 40px;
    align-items: stretch;
}

.opt-facts__hero {
    flex: 1 1 300px;
    padding-right: 40px;
    border-right: 1px solid #95C7EF;
}

@media (max-width: 991px) {
    .opt-facts__hero {
        padding-right: 0;
        padding-bottom: 32px;
        border-right: 0;
        border-bottom: 1px solid #95C7EF;
    }
}

.opt-facts__hero-value {
    display: block;
    font-size: 84px;
    line-height: 1;
    font-weight: 700;
    color: #102F97;
    letter-spacing: -1px;
}

@media (max-width: 991px) {
    .opt-facts__hero-value {
        font-size: 64px;
    }
}

@media (max-width: 575px) {
    .opt-facts__hero-value {
        font-size: 52px;
    }
}

.opt-facts__hero-label {
    display: block;
    margin-top: 10px;
    font-size: 18px;
    line-height: 24px;
    color: #0F172A;
}

.opt-facts__hero-text {
    margin: 20px 0 0;
    font-size: 14px;
    line-height: 20px;
    color: #666666;
}

.opt-facts__grid {
    flex: 1 1 420px;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 28px 32px;
    align-content: center;
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (max-width: 575px) {
    .opt-facts__grid {
        grid-template-columns: 1fr;
    }
}

.opt-facts__item {
    margin: 0;
}

.opt-facts__value {
    display: block;
    margin-bottom: 4px;
    font-size: 30px;
    line-height: 1.1;
    font-weight: 700;
    color: #102F97;
}

@media (max-width: 767px) {
    .opt-facts__value {
        font-size: 24px;
    }
}

.opt-facts__label {
    display: block;
    font-size: 14px;
    line-height: 18px;
    color: #666666;
}


/* ===== Секция 3. Кому мы поставляем ===== */
/* Уровень 3, собственный компонент. Пересобрана 23.08.2026, вечер по макету
   заказчика: ряд из четырёх карточек с фотографией сверху, под ними
   синяя плашка с условиями выбранного формата.

   Про «ряд одинаковых карточек». Решение 10 в HANDOFF.md запрещало этот
   приём после того, как заказчик забраковал плитки словами «смотрится
   бедненько». Здесь запрет снят самим заказчиком, и причина в другом
   устройстве карточки: в забракованном варианте была «иконка + заголовок
   + текст», здесь карточку ведёт фотография формата. Посетитель узнаёт
   свой мир на снимке раньше, чем читает подпись, — ровно то, ради чего
   запрет и вводился.

   Про цвет плашки. На макете она почти чёрно-синяя. Заказчик просил взять
   цвета сайта, поэтому плашка залита основным синим #102F97: это самый
   тёмный синий, который на сайте есть в роли заливки. Кнопка на ней —
   сайтовая .btn-lightblue: светлая кнопка на синем фоне это её штатная
   роль, синяя кнопка на синей плашке не читалась бы.

   Переключение вкладок поднимает opt.js по классу .js-opt-segments:
   он переключает .is-active на .opt-segments__card и __panel. Разметку
   кадров скрипт тоже умеет, но здесь она не нужна — фотография живёт
   внутри карточки и не меняется. */

/* Заголовок прижат к левому краю — как у всех остальных секций страницы.
   Ограничение ширины оставлено: на всю строку в 1200 px заголовок читается
   тяжело, глазу приходится возвращаться через весь экран. Сам .title-h2
   сайтовый, меняем только ширину — разметка та же.

   Прежний вариант с выключкой по центру отменён заказчиком 24.08.2026
   вместе с бровкой «Кому мы поставляем»: по центру заголовок работал в паре
   с бровкой, один — нет. */
.opt-segments__title {
    max-width: 860px;
}

/* ——— Ряд карточек формата ——— */

/* minmax(0, 1fr), а не 1fr: колонка грида по умолчанию не сжимается
   ниже своего содержимого, и длинное название формата распирает ряд
   в горизонтальную прокрутку. На этой странице так уже ломалось дважды. */
.opt-segments__cards {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 20px;
}

@media (max-width: 991px) {
    .opt-segments__cards {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 479px) {
    .opt-segments__cards {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* Карточка — кнопка, поэтому сбрасываем всё, что браузер рисует кнопке
   по умолчанию. Тень сайтовая, синяя: #C5DBED в разведённом виде. */
/* Карточка — колонка, а не блок. У <button> браузер центрирует содержимое
   по вертикали, и у карточек с однострочным названием сверху и снизу
   оставалось по 10 px пустоты, из-за чего кадры в ряду не совпадали
   по высоте. Колонка прижимает кадр к верху, а лишнюю высоту отдаёт
   подписи. Замечание заказчика 23.08.2026. */
.opt-segments__card {
    display: flex;
    flex-direction: column;
    width: 100%;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 12px;
    background-color: #ffffff;
    box-shadow: 0 4px 24px rgba(197, 219, 237, 0.4);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    overflow: hidden;
    transition: all 0.3s ease-in-out;
}

/* Рамка выбранной карточки нарисована тенью, а не border: рамка сдвинула
   бы содержимое на 2 px, а по правилу дизайн-системы при выборе и
   наведении ничего не должно двигаться. */
.opt-segments__card.is-active {
    box-shadow: 0 0 0 2px #102F97, 0 4px 24px rgba(197, 219, 237, 0.4);
}

.opt-segments__card:hover,
.opt-segments__card:focus-visible {
    box-shadow: 0 0 0 2px #5D7DCF, 0 4px 24px rgba(197, 219, 237, 0.4);
}

.opt-segments__card.is-active:hover,
.opt-segments__card.is-active:focus-visible {
    box-shadow: 0 0 0 2px #102F97, 0 4px 24px rgba(197, 219, 237, 0.4);
}

/* ——— Фотография формата ——— */

.opt-segments__shot {
    position: relative;
    display: block;
    flex: 0 0 auto;
    background-color: #F0F5F9;
}

.opt-segments__shot img {
    display: block;
    width: 100%;
    height: auto;
}

/* Отметка выбора. Не появляется из ниоткуда рывком: у неё тот же
   переход, что у всей карточки. */
.opt-segments__check {
    position: absolute;
    top: 12px;
    right: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background-color: #102F97;
    color: #ffffff;
    opacity: 0;
    transition: all 0.3s ease-in-out;
}

.opt-segments__card.is-active .opt-segments__check {
    opacity: 1;
}

@media (max-width: 767px) {
    .opt-segments__check {
        top: 8px;
        right: 8px;
        width: 24px;
        height: 24px;
    }
}

/* ——— Подпись карточки ——— */

/* Подпись забирает всю оставшуюся высоту карточки: так лишние пиксели
   уходят под текст, а не в поля вокруг кадра. */
.opt-segments__body {
    flex: 1 1 auto;
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 16px;
}

@media (max-width: 1199px) {
    .opt-segments__body {
        padding: 14px;
        gap: 10px;
    }
}

/* Иконка формата: посетитель опознаёт себя ещё до чтения подписи.
   Плашка не сжимается — иначе длинное название её сплющивает. */
.opt-segments__ico {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 8px;
    background-color: #DDEDFA;
    color: #102F97;
    transition: all 0.3s ease-in-out;
}

.opt-segments__card.is-active .opt-segments__ico {
    background-color: #102F97;
    color: #ffffff;
}

@media (max-width: 1199px) {
    .opt-segments__ico {
        width: 36px;
        height: 36px;
    }
}

/* min-width: 0 обязателен: без него флекс-элемент не сжимается ниже
   самого длинного слова и ломает карточку. */
.opt-segments__text {
    display: block;
    min-width: 0;
}

.opt-segments__name {
    display: block;
    margin-bottom: 4px;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.25;
    color: #0F172A;
    transition: all 0.3s ease-in-out;
}

.opt-segments__card.is-active .opt-segments__name {
    color: #102F97;
}

@media (max-width: 1199px) {
    .opt-segments__name {
        font-size: 15px;
    }
}

.opt-segments__desc {
    display: block;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.4;
    color: #666666;
}

@media (max-width: 1199px) {
    .opt-segments__desc {
        font-size: 13px;
    }
}

/* ——— Плашка условий выбранного формата ——— */

/* Панели лежат друг на друге в одной ячейке грида: так высота плашки
   не скачет при переключении и не дёргает страницу под собой. */
.opt-segments__panels {
    display: grid;
    margin-top: 20px;
}

.opt-segments__panel {
    position: relative;
    grid-area: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 28px;
    padding: 26px 28px;
    border-radius: 14px;
    background-color: #102F97;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.7s ease-in-out, visibility 0.7s ease-in-out;
}

/* Переход медленнее общесайтовых 300 мс — 700 мс, по просьбе заказчика
   от 23.08: на автопоказе быстрая смена читается как мигание. */
.opt-segments__panel.is-active {
    opacity: 1;
    visibility: visible;
}

/* Кому движение мешает — системная настройка «уменьшить движение».
   Автопоказ при ней тоже не запускается, это делает opt.js. */
@media (prefers-reduced-motion: reduce) {
    .opt-segments__panel {
        transition: none;
    }
}

@media (max-width: 1199px) {
    .opt-segments__panel {
        gap: 20px;
        padding: 22px 24px;
    }
}

@media (max-width: 991px) {
    .opt-segments__panel {
        flex-direction: column;
        align-items: stretch;
        gap: 22px;
    }
}

@media (max-width: 767px) {
    .opt-segments__panel {
        padding: 20px;
    }
}

/* Уголок от плашки к выбранной карточке. Без него не читалось, что
   цифры внизу относятся к одному выбранному формату, а не ко всем сразу.
   Замечание заказчика 26.08.2026.

   Уголок живёт на самой плашке, а не на карточке: у карточки overflow: hidden
   под скругление фотографии, и всё, что торчит за её край, срезалось бы. А так
   уголок гаснет и проявляется вместе со своей плашкой и сам собой «переезжает» к нужной
   карточке при переключении и на автопоказе.

   Треугольник нарисован границами, а не clip-path: блок уходит на живой
   сайт, где есть старые браузеры. */
.opt-segments__panel::before {
    content: "";
    position: absolute;
    bottom: 100%;
    width: 0;
    height: 0;
    border-left: 13px solid transparent;
    border-right: 13px solid transparent;
    border-bottom: 14px solid #102F97;
    transform: translateX(-50%);
}

/* Центр i-й карточки в ряду из четырёх равных с зазором 20 px:
   ширина карточки — (100% − 60px)/4, плюс зазоры слева. Плашка и ряд
   карточек одинаковой ширины и выровнены по левому краю, поэтому проценты
   от плашки совпадают с процентами от ряда. */
.opt-segments__panel:nth-child(1)::before {
    left: calc((100% - 60px) / 8);
}

.opt-segments__panel:nth-child(2)::before {
    left: calc((100% - 60px) / 4 * 1.5 + 20px);
}

.opt-segments__panel:nth-child(3)::before {
    left: calc((100% - 60px) / 4 * 2.5 + 40px);
}

.opt-segments__panel:nth-child(4)::before {
    left: calc((100% - 60px) / 4 * 3.5 + 60px);
}

/* Ниже 991 px карточки встают в два ряда, и плашка стоит под нижним.
   Уголок там указывал бы на соседнюю карточку, а не на выбранную, поэтому снят. */
@media (max-width: 991px) {
    .opt-segments__panel::before {
        display: none;
    }
}

/* Показатели разделены волосяными вертикальными линиями — приём,
   утверждённый заказчиком. Точек и буллетов между фактами быть не должно. */
.opt-segments__figs {
    display: flex;
    align-items: center;
    min-width: 0;
}

@media (max-width: 991px) {
    .opt-segments__figs {
        flex-wrap: wrap;
        gap: 18px 0;
    }
}

@media (max-width: 575px) {
    .opt-segments__figs {
        display: block;
    }
}

/* min-width: 0 у колонок снят намеренно: с ним flex сжимал колонку «цена»
   ниже её содержимого и «от 165 ₽/м» либо рвалось на две строки, либо
   наезжало на разделительную линию. Без него колонка не уже своего текста,
   а лишнюю ширину отдаёт колонка «условия» — она и рассчитана на перенос. */
.opt-segments__item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 0 28px;
    border-left: 1px solid rgba(255, 255, 255, 0.25);
}

.opt-segments__item:first-child {
    padding-left: 0;
    border-left: none;
}

@media (max-width: 1199px) {
    .opt-segments__item {
        gap: 12px;
        padding: 0 18px;
    }
}

@media (max-width: 991px) {
    .opt-segments__item {
        flex: 1 1 50%;
    }

    /* Во втором ряду левая линия у первого элемента ряда лишняя. */
    .opt-segments__item:nth-child(odd) {
        padding-left: 0;
        border-left: none;
    }
}

@media (max-width: 575px) {
    .opt-segments__item {
        padding: 14px 0 0;
        border-left: none;
        border-top: 1px solid rgba(255, 255, 255, 0.25);
    }

    .opt-segments__item:first-child {
        padding-top: 0;
        border-top: none;
    }
}

.opt-segments__item-ico {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.14);
    color: #ffffff;
}

@media (max-width: 1199px) {
    .opt-segments__item-ico {
        width: 38px;
        height: 38px;
    }
}

.opt-segments__item-text {
    display: block;
}

/* Подпись голубой плашкой #DDEDFA, а не серым: правило дизайн-системы —
   серый текст на цветном фоне выглядит выцветшим. Контраст к #102F97
   при этом 9,4:1. */
.opt-segments__label {
    display: block;
    margin-bottom: 2px;
    white-space: nowrap;
    font-size: 12px;
    font-weight: 600;
    line-height: 16px;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #DDEDFA;
}

/* Значения-числа и подписи держатся в одну строку (см. white-space выше и у __value).
   Но на средних экранах три колонки ещё стоят в ряд, и длинная подпись
   «минимальная сумма заказа» забирает ширину у соседней «условий» — текст там
   вытягивается вдвое (132 px вместо 57). Поэтому здесь подписи разрешён перенос,
   а сами значения остаются в одну строку. */
@media (max-width: 1199px) {
    .opt-segments__label {
        white-space: normal;
    }
}

.opt-segments__value {
    display: block;
    font-size: 20px;
    font-weight: 700;
    line-height: 1.2;
    color: #ffffff;
    white-space: nowrap;
}

@media (max-width: 1199px) {
    .opt-segments__value {
        font-size: 18px;
    }
}

/* У «условий» значение не число, а фраза в две строки: крупный кегль
   ей не идёт, читается как заголовок. */
.opt-segments__value--text {
    font-size: 15px;
    font-weight: 500;
    line-height: 1.35;
    white-space: normal;
}

@media (max-width: 1199px) {
    .opt-segments__value--text {
        font-size: 14px;
    }
}

/* Кнопка сайтовая .btn-lightblue — светлая кнопка на синем фоне это её
   штатная роль. Сайтовый класс .btn намеренно не поставлен: он переводит
   надпись в капслок, а на макете заказчика обычный регистр. У прежней
   кнопки этого блока было так же. Свой класс добавлен только под размер
   и нерушимость строки. */
.opt-segments__btn {
    flex: 0 0 auto;
    padding: 13px 22px;
    font-weight: 500;
    white-space: nowrap;
}

@media (max-width: 991px) {
    .opt-segments__btn {
        text-align: center;
    }
}

/* Обводка фокуса. Сайт гасит её глобально (styles/cart-style.css), поэтому
   каждый свой интерактивный элемент возвращает её сам. Значения одни на всё:
   2 px с отступом 2 px, синие #102F97 на светлом фоне и белые на синем.
   Здесь белая: кнопка светло-голубая, но лежит она на синей панели условий,
   и обводка с отступом попадает именно на синее. */

.opt-segments__btn:focus-visible {
    /* !important бьёт сайтовое :focus { outline: 0 !important }.
       Разбор — у .opt-hero .btn-blue:focus-visible. */
    outline: 2px solid #FFFFFF !important;
    outline-offset: 2px;
}

/* ===== Секция 8. Порядок действий при браке ===== */
/* Уровень 3, собственный компонент «Дорожка». Заменил сайтовый .steps:
   тот рисует три равные плитки без порядка и без движения, а заказчику
   нужен именно путь — сначала один, потом два, потом три.
   Вариант выбран заказчиком 23.08.2026 из пяти на _varianty/varianty-defekt.html.

   Правила сайтового .steps, лежавшие здесь по решению 4 (перенос из
   printing.css), удалены: компонент со страницы ушёл, правила осиротели. */

.opt-steps__way {
    position: relative;
}

/* Линия идёт от центра первого круга до центра третьего и дальше не тянется:
   на третьем шаге пути больше нет, и линия не должна обещать продолжение.
   Круги стоят по центру своих колонок, поэтому левый конец — половина колонки:
   (1200 − 2×30) / 6 = 190 px, то есть calc(16.6667% − 10px).
   Ширина — расстояние между центрами крайних колонок, 2×(колонка + промежуток). */
.opt-steps__track {
    position: absolute;
    left: calc(16.6667% - 10px);
    top: 36px;
    width: calc(66.6667% + 20px);
    height: 2px;
    background: #E5E5E5;
}

.opt-steps__track i {
    display: block;
    height: 100%;
    width: 0;
    background: #102F97;
    transition: width 0.9s ease-in-out;
}

@media (max-width: 767px) {
    .opt-steps__track {
        display: none;
    }
}

.opt-steps__row {
    position: relative;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 30px;
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (max-width: 767px) {
    .opt-steps__row {
        grid-template-columns: minmax(0, 1fr);
        gap: 26px;
    }
}

/* Сайт вешает на li в контентной зоне margin-left 10px, padding-left 20px
   и свой маркер. Для шага дорожки это лишнее: номер рисует круг, а отступы
   сужали колонку на 30 px, и линия переставала попадать в центры кругов. */
/* Шаг выключен по центру: круг с номером стоит ровно посередине своей подписи,
   и колонка читается как одна вертикаль, а не как номер, приклеенный слева. */
.opt-steps__st {
    min-width: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: center;
}

.opt-steps__st::before,
.opt-steps__st::after {
    content: none;
}

/* Круг с номером. Пройденные остаются в синем контуре — видно не только,
   где ты сейчас, но и сколько уже позади.

   ЦВЕТ НОМЕРА ИСПРАВЛЕН 29.08.2026 ПО ЗАМЕРУ. Стоял #9A9CA3 — это сайтовый
   цвет ссылок навигации, и как цвет текста он не проходит: 2,74 : 1 по белому
   при норме 3 для крупного жирного. Взят #666666 — 5,74 : 1, тот самый цвет
   подписей, который дизайн-система называет прямо: «на полосе #F0F5F9
   подписи — #666666, не светлее».

   Иерархия от этого не теряется: текущий шаг отличается не оттенком серого,
   а тем, что его круг залит синим с белой цифрой, а подпись лежит на белой
   плашке с синей тенью. Раньше вся разница держалась на цвете — теперь
   на форме, как и задумано. */

.opt-steps__cir {
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 74px;
    height: 74px;
    border-radius: 50%;
    background: #FFFFFF;
    border: 2px solid #E5E5E5;
    font-size: 32px;
    font-weight: 700;
    line-height: 1;
    color: #666666;
    transition: all 0.5s ease-in-out;
}

.opt-steps__st.is-done .opt-steps__cir {
    border-color: #102F97;
    color: #102F97;
}

.opt-steps__st.is-active .opt-steps__cir {
    background: #102F97;
    border-color: #102F97;
    color: #FFFFFF;
}

@media (max-width: 767px) {
    .opt-steps__cir {
        width: 58px;
        height: 58px;
        font-size: 26px;
    }
}

/* Подпись активного шага встаёт на белую плашку с фирменной синей тенью.
   Поля одинаковые у всех трёх, меняется только заливка, поэтому при
   переключении ничего не прыгает. */
.opt-steps__body {
    margin-top: 16px;
    padding: 16px 18px;
    border-radius: 12px;
    background: transparent;
    box-shadow: 0 0 0 0 rgba(197, 219, 237, 0);
    transition: all 0.5s ease-in-out;
}

.opt-steps__st.is-active .opt-steps__body {
    background: #FFFFFF;
    box-shadow: 0 4px 24px rgba(197, 219, 237, 0.75);
}

@media (max-width: 767px) {
    .opt-steps__body {
        margin-top: 12px;
        padding: 14px 16px;
    }
}

/* Подпись непройденного шага. Цвет тот же #666666 и по той же причине,
   что у круга выше: #9A9CA3 давал по синеватой полосе 2,5 : 1 при норме 3.
   Текущий шаг синеет — #102F97, — так что разница остаётся. */

.opt-steps__t {
    margin: 0 0 8px;
    font-size: 18px;
    line-height: 25px;
    font-weight: 600;
    color: #666666;
    transition: all 0.5s ease-in-out;
}

.opt-steps__st.is-done .opt-steps__t {
    color: #0F172A;
}

.opt-steps__st.is-active .opt-steps__t {
    color: #102F97;
}

@media (max-width: 767px) {
    .opt-steps__t {
        font-size: 17px;
    }
}

/* Описание шага — самое тяжёлое место из найденных: 15 px обычным весом
   при 2,5 : 1 и норме 4,5. Это уже не оттенок, а нечитаемый текст.
   #666666 даёт 5,23 по полосе и 5,74 по белому. */

.opt-steps__d {
    margin: 0;
    font-size: 15px;
    line-height: 22px;
    color: #666666;
    transition: all 0.5s ease-in-out;
}

.opt-steps__st.is-active .opt-steps__d {
    color: #666666;
}

/* ===== Секция 4. Перед закупкой ===== */
/* Уровень 3, собственный компонент. Композиция и оформление взяты
   из макета заказчика от 23.08.2026: слева заголовок, лид, три
   пункта карточками с иконками и кнопка со стрелкой; справа крупный
   кадр коробки с образцами, уходящий за правый край экрана.

   Сайтовые компоненты two-column и card-product-descriptor больше
   не используются: первый ставит две равные колонки без выхода за
   контейнер, второй рисует иконку картинкой 50×50 и не даёт
   разделить название пункта и описание на две строки. */

/* Кадр вписан в ширину контента и за край экрана больше не уходит,
   поэтому обрезка секции не нужна. Решение заказчика 23.08.2026:
   прежний вариант с вылетом за правый край отменён. */

.opt-samples__row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
    gap: 60px;
    align-items: center;
}

@media (max-width: 1199px) {
    .opt-samples__row {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 36px;
    }
}

@media (max-width: 991px) {
    .opt-samples__row {
        grid-template-columns: minmax(0, 1fr);
        gap: 28px;
    }
}

/* ——— Левая половина: текст ——— */

/* Заголовок вынесен из левой колонки на всю ширину контейнера и стоит
   над обеими колонками. Внутри колонки шириной около 560 px он ломался
   на три строки; во всю строку 1200 px помещается в одну.

   Ограничение max-width: 18ch снято — оно и держало те три строки.
   Отступ снизу 40 px, как между заголовком и содержимым в остальных
   секциях страницы. Решение заказчика 24.08.2026. */
.opt-samples__title {
    margin-bottom: 40px;
}

@media (max-width: 991px) {
    .opt-samples__title {
        margin-bottom: 25px;
    }
}

.opt-samples__lead {
    margin: 0 0 28px;
    max-width: 52ch;
    font-size: 16px;
    line-height: 24px;
    color: #666666;
    text-wrap: pretty;
}

.opt-samples__list {
    margin: 0 0 28px;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 12px;
}

/* Пункт — строка с иконкой, а не карточка в ряду одинаковых плиток:
   пункты читаются сверху вниз и могут быть разной высоты. */
/* align-items: stretch, а не start — от этого зависит высота плашки
   с иконкой: она должна равняться всему тексту пункта, заголовку
   вместе с двумя строками описания. Решение заказчика 23.08.2026. */
/* margin: 0 обязателен. В ext/extended.css живёт правило
   `color__slider, li { margin-left: 10px }` — у первого селектора потерялась
   точка, и голый li разошёлся по всему сайту. Из-за него карточки пунктов
   стояли на 10 px правее заголовка, лида и кнопки: колонка выглядела
   сломанной, хотя в разметке всё было выровнено. Правило сайтовое, чинить
   его в чужом файле нельзя, поэтому гасим у себя. */
.opt-samples__item {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    gap: 18px;
    align-items: stretch;
    margin: 0;
    padding: 16px 18px;
    border-radius: 12px;
    background: #FFFFFF;
}

@media (max-width: 575px) {
    .opt-samples__item {
        grid-template-columns: 52px minmax(0, 1fr);
        gap: 12px;
        padding: 14px;
    }
}

/* Высота не задана числом: плашка тянется по высоте строки сетки,
   то есть по самому тексту. Если у пункта станет три строки описания
   вместо двух — плашка вырастет сама. */
.opt-samples__ico {
    display: grid;
    place-items: center;
    width: 64px;
    border-radius: 12px;
    background: #DDEDFA;
    color: #102F97;
}

@media (max-width: 575px) {
    .opt-samples__ico {
        width: 52px;
        border-radius: 10px;
    }
}

.opt-samples__ico img {
    display: block;
    width: 32px;
    height: 32px;
}

@media (max-width: 575px) {
    .opt-samples__ico img {
        width: 26px;
        height: 26px;
    }
}

.opt-samples__body {
    display: block;
    padding-top: 3px;
}

.opt-samples__name {
    display: block;
    margin-bottom: 3px;
    font-size: 16px;
    line-height: 22px;
    font-weight: 600;
    color: #0F172A;
}

.opt-samples__desc {
    display: block;
    font-size: 15px;
    line-height: 21px;
    color: #666666;
    text-wrap: pretty;
}

/* Кнопка со стрелкой у дальнего края: стрелка отбита от подписи
   и показывает направление, а не жмётся к ней вплотную. */
.opt-samples__cta {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 40px;
    min-width: 340px;
    padding: 17px 24px;
    border: none;
    border-radius: 8px;
    background: #102F97;
    font: inherit;
    font-size: 16px;
    line-height: 20px;
    font-weight: 600;
    color: #FFFFFF;
    text-decoration: none;
    cursor: pointer;
    transition: all 300ms ease-in-out;
}

.opt-samples__cta:hover,
.opt-samples__cta:focus {
    background: #5D7DCF;
    color: #FFFFFF;
}

.opt-samples__cta:focus-visible {
    /* !important бьёт сайтовое :focus { outline: 0 !important }.
       Разбор — у .opt-hero .btn-blue:focus-visible. */
    outline: 2px solid #102F97 !important;
    outline-offset: 2px;
}

.opt-samples__cta svg {
    flex: 0 0 auto;
}

@media (max-width: 575px) {
    .opt-samples__cta {
        min-width: 0;
        width: 100%;
        gap: 16px;
        padding: 15px 18px;
    }
}

/* ——— Правая половина: кадр ——— */

/* Кадр выходит за правый край контейнера до края экрана. Приём из
   макета заказчика: фотография не заперта в колонку, а продолжает
   страницу. Скруглены только левые углы — правых у неё нет, она
   упирается в край. */
/* Кадр стоит в своей колонке и никуда не вылезает. */
.opt-samples__media {
    min-width: 0;
}

@media (max-width: 991px) {
    .opt-samples__media {
        order: -1;
    }
}

/* Высота не задаётся числом: кадр перерезан под пропорцию 4:3 и держит
   её сам через width и height в атрибутах. Кроп сделан вокруг коробки,
   поэтому смещать кадрирование через object-position больше не нужно —
   коробка и так по центру. */
.opt-samples__img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 20px;
}




/* ===== Секция 5. Популярные ткани для опта ===== */
/* Уровень 1: карусель и карточки товара сайтовые, не тронуты.
   Своя только отбивка: ссылка «Смотреть все» стояла вплотную к нижнему
   краю карточек и читалась как их часть. Замечание заказчика 23.08.2026. */

.opt-fabrics .slider-section__footer {
    margin-top: 32px;
}

@media (max-width: 767px) {
    .opt-fabrics .slider-section__footer {
        margin-top: 24px;
    }
}

/* ===== Секция 6. Пример расчёта ===== */
/* Уровень 3, собственный компонент. Композиция взята из прототипа
   по решению заказчика 23.08.2026: белая карточка расчёта слева,
   синяя плашка крупного опта справа.

   Отступление, принятое сознательно: кнопка на синей плашке жёлтая.
   #FFCB00 — настоящий токен бренда, новых цветов не введено, но
   роль у него в дизайн-системе другая: точка в логотипе, значок
   бургера, акценты в ценах. Здесь он работает призывом. Заказчик
   показал этот макет дважды со словами «делаем так».
   Обоснование — в _docs/DEVIATIONS.md. */

/* minmax(0, …) обязателен: колонка сетки по умолчанию не сжимается
   ниже содержимого, и числовое поле счётчика распирало блок за край
   экрана на телефоне. */
.opt-calc__row {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 28px;
    align-items: stretch;
}

@media (max-width: 991px) {
    .opt-calc__row {
        grid-template-columns: minmax(0, 1fr);
        gap: 20px;
    }
}

.opt-calc__card,
.opt-calc__aside {
    min-width: 0;
}

/* ——— Левая половина: расчёт ——— */

.opt-calc__card {
    padding: 32px 36px;
    border-radius: 20px;
    background: #FFFFFF;
    box-shadow: 0 4px 24px rgba(197, 219, 237, 0.4);
}

@media (max-width: 767px) {
    .opt-calc__card {
        padding: 22px 20px;
    }
}

.opt-calc__label {
    display: block;
    margin-bottom: 10px;
    font-size: 13px;
    line-height: 17px;
    color: #666666;
}

.opt-calc__pick {
    display: block;
    width: 100%;
    padding: 15px 16px;
    border: 1px solid #DDDDDD;
    border-radius: 8px;
    background: #FFFFFF;
    font: inherit;
    font-size: 16px;
    line-height: 22px;
    color: #0F172A;
    transition: all 300ms ease-in-out;
}

.opt-calc__pick::placeholder {
    color: #666666;
    opacity: 1;
}

.opt-calc__pick:hover {
    border-color: #95C7EF;
}

.opt-calc__pick:focus {
    outline: none;
    border-color: #102F97;
}

.opt-calc__chosen {
    margin: 10px 0 0;
    font-size: 13px;
    line-height: 18px;
    color: #666666;
}

.opt-calc__chosen.is-selected {
    color: #0F172A;
}

.opt-calc__chosen.is-selected b {
    color: #102F97;
}

.opt-calc__search {
    position: relative;
}

.opt-calc__dropdown {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 10;
    max-height: 240px;
    overflow-y: auto;
    padding: 6px 0;
    border: 1px solid #DDDDDD;
    border-radius: 8px;
    background: #FFFFFF;
    box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12);
}

.opt-calc__dropdown[hidden] {
    display: none;
}

.opt-calc__dropdown-item {
    display: block;
    width: 100%;
    padding: 10px 16px;
    border: none;
    background: transparent;
    font: inherit;
    font-size: 15px;
    line-height: 20px;
    color: #0F172A;
    text-align: left;
    cursor: pointer;
    transition: background-color 150ms ease;
}

.opt-calc__dropdown-item:hover,
.opt-calc__dropdown-item:focus {
    background-color: #F1F8FE;
    outline: none;
}

.opt-calc__dropdown-empty {
    padding: 12px 16px;
    font-size: 14px;
    line-height: 20px;
    color: #666666;
}

@media (max-width: 575px) {
    .opt-calc__dropdown {
        max-height: 200px;
    }
}

.opt-calc__title {
    margin: 26px 0 4px;
    font-size: 18px;
    line-height: 24px;
    font-weight: 600;
    color: #0F172A;
}

/* Ступени цены. Строки, а не плитки: список читается сверху вниз,
   как прайс, и не превращается в ряд одинаковых карточек. */
.opt-calc__tiers {
    border-bottom: 1px solid #E5E5E5;
}

.opt-calc__tier {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 16px;
    width: 100%;
    padding: 14px 0;
    border: none;
    border-top: 1px solid #E5E5E5;
    background: none;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: all 300ms ease-in-out;
}

.opt-calc__tier.is-hidden {
    display: none;
}

.opt-calc__tier:hover .opt-calc__tiervol {
    color: #102F97;
}

.opt-calc__tier:focus-visible {
    /* !important бьёт сайтовое :focus { outline: 0 !important }.
       Разбор — у .opt-hero .btn-blue:focus-visible. */
    outline: 2px solid #102F97 !important;
    outline-offset: 2px;
}

.opt-calc__tiervol {
    font-size: 16px;
    line-height: 22px;
    color: #666666;
    transition: all 300ms ease-in-out;
}

.opt-calc__tier[aria-pressed="true"] .opt-calc__tiervol {
    color: #0F172A;
    font-weight: 500;
}

.opt-calc__tierrate {
    font-size: 18px;
    line-height: 24px;
    font-weight: 700;
    color: #0F172A;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    transition: all 300ms ease-in-out;
}

.opt-calc__tier[aria-pressed="true"] .opt-calc__tierrate {
    color: #102F97;
}

/* Ступень, которая только что вступила в силу, один раз наливается
   светло-синим и гаснет.

   ЗАЧЕМ. Переход порога — главное событие этой секции и главный довод
   страницы: набрал метраж, цена за метр упала. До этого событие
   происходило молча. Ступени переключали постоянную подсветку — тёмная
   подпись объёма, синяя цена, — но подсветка отвечает на вопрос «какая
   ступень действует сейчас», а не «что сейчас изменилось». Посетитель
   жмёт плюс, смотрит на счётчик и на сумму, а смена ступени происходит
   на 100 px выше и остаётся незамеченной. Связь «добавил метры → упала
   цена» приходится достраивать самому.

   ПОЧЕМУ ЗАЛИВКА, А НЕ ДВИЖЕНИЕ. Дизайн-система разрешает ровно два
   языка: «Только затухания и смены цвета», «Ничего не двигается».
   Строка не подпрыгивает, не увеличивается и не обводится рамкой —
   она на секунду становится подсвеченной строкой ведомости и гаснет.
   Это же снимает вопрос со скачком вёрстки: цвет фона не меняет
   геометрию, соседние строки стоят на месте.

   ЦВЕТ НЕ ВЫДУМАН. #F1F8FE — сайтовый цвет подсветки строки, тот же,
   что под полосой цифр в секции 2. Своей краски не появилось.

   СИММЕТРИЧНО В ОБЕ СТОРОНЫ. Метраж уменьшили, цена выросла — отмечаем
   так же. Это отметка «теперь действует эта строка», а не поздравление
   с выгодой: страница говорит фактами, а не подбадривает. */

@keyframes opt-calc-stupen {
    from { background-color: #F1F8FE; }
    to   { background-color: rgba(241, 248, 254, 0); }
}

.opt-calc__tier.is-stupen {
    animation: opt-calc-stupen 1.1s ease-out;
}

/* Просят не анимировать — отметки нет. Информация при этом не теряется:
   какая ступень действует, по-прежнему видно по постоянной подсветке. */

@media (prefers-reduced-motion: reduce) {
    .opt-calc__tier.is-stupen {
        animation: none;
    }
}


/* Строка счётчика: слева сам счётчик, справа сумма. Раньше они стояли друг
   под другом и счётчик тянулся на всю ширину карточки — поле ввода выходило
   452 px и налезало на кнопку «плюс», до неё было не дотянуться.
   Замечание заказчика 23.08.2026. */
.opt-calc__countrow {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px 24px;
    margin-top: 22px;
}

@media (max-width: 575px) {
    .opt-calc__countrow {
        gap: 12px 16px;
    }
}

/* Счётчик по содержимому, а не на всю ширину. */
.opt-calc__count {
    flex: 0 0 auto;
    display: flex;
    align-items: stretch;
    gap: 8px;
}

.opt-calc__countbtn {
    flex: 0 0 auto;
    width: 48px;
    border: 1px solid #DDDDDD;
    border-radius: 8px;
    background: #FFFFFF;
    font: inherit;
    font-size: 20px;
    line-height: 1;
    color: #0F172A;
    cursor: pointer;
    transition: all 300ms ease-in-out;
}

.opt-calc__countbtn:hover {
    border-color: #102F97;
    color: #102F97;
}

.opt-calc__countbtn:focus-visible {
    /* !important бьёт сайтовое :focus { outline: 0 !important }.
       Разбор — у .opt-hero .btn-blue:focus-visible. */
    outline: 2px solid #102F97 !important;
    outline-offset: 2px;
}

/* Поле и единица измерения — одна связка. Единица лежит поверх поля
   на позиционировании, а не сдвигается отрицательным отступом: отступ
   утаскивал за собой кнопку «плюс» и она оказывалась под полем. */
.opt-calc__countfield {
    position: relative;
    flex: 0 0 auto;
    display: block;
}

.opt-calc__countinput {
    display: block;
    width: 96px;
    padding: 13px 30px 13px 12px;
    border: 1px solid #DDDDDD;
    border-radius: 8px;
    background: #FFFFFF;
    font: inherit;
    font-size: 18px;
    font-weight: 600;
    text-align: center;
    color: #0F172A;
    font-variant-numeric: tabular-nums;
    -moz-appearance: textfield;
}

.opt-calc__countinput::-webkit-outer-spin-button,
.opt-calc__countinput::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.opt-calc__countinput:focus {
    outline: none;
    border-color: #102F97;
}

.opt-calc__countunit {
    position: absolute;
    top: 50%;
    right: 12px;
    transform: translateY(-50%);
    font-size: 15px;
    line-height: 1;
    color: #666666;
    pointer-events: none;
}

/* Сумма стоит в одной строке со счётчиком и прижата к правому краю
   карточки: изменил метраж — увидел результат, не переводя взгляд вниз. */
.opt-calc__total {
    flex: 0 1 auto;
    margin: 0 0 0 auto;
    font-size: 16px;
    line-height: 24px;
    color: #666666;
    text-align: right;
}

@media (max-width: 575px) {
    .opt-calc__total {
        margin-left: 0;
        text-align: left;
    }
}

.opt-calc__total b {
    font-size: 26px;
    font-weight: 700;
    color: #0F172A;
    letter-spacing: -.01em;
    font-variant-numeric: tabular-nums;
}

.opt-calc__totalnote {
    font-size: 14px;
}

/* ——— Правая половина: крупный опт ——— */

.opt-calc__aside {
    display: flex;
    flex-direction: column;
    padding: 32px 36px;
    border-radius: 20px;
    background: #102F97;
    color: #FFFFFF;
}

@media (max-width: 767px) {
    .opt-calc__aside {
        padding: 24px 20px;
    }
}

.opt-calc__badge {
    display: inline-block;
    align-self: flex-start;
    margin-bottom: 18px;
    padding: 6px 14px;
    border: 1px solid #FFCB00;
    border-radius: 100px;
    font-size: 13px;
    line-height: 18px;
    font-weight: 600;
    color: #FFCB00;
}

.opt-calc__asidetitle {
    margin: 0 0 12px;
    font-size: 24px;
    line-height: 32px;
    font-weight: 600;
    color: #FFFFFF;
    text-wrap: balance;
}

@media (max-width: 991px) {
    .opt-calc__asidetitle {
        font-size: 20px;
        line-height: 28px;
    }
}

.opt-calc__asidetext {
    margin: 0 0 28px;
    max-width: 44ch;
    font-size: 16px;
    line-height: 24px;
    color: #DDEDFA;
    text-wrap: pretty;
}

/* Призыв прижат к низу плашки: она равна по высоте карточке расчёта.
   Весь запас высоты собирается здесь, над кнопкой, — это единственная
   пауза в плашке, и она работает как разбег перед действием. */
.opt-calc__cta {
    display: block;
    margin-top: auto;
    padding: 16px 24px;
    border: none;
    border-radius: 8px;
    background: #FFCB00;
    font: inherit;
    font-size: 16px;
    line-height: 20px;
    font-weight: 600;
    color: #0F172A;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: all 300ms ease-in-out;
}

.opt-calc__cta:hover,
.opt-calc__cta:focus {
    background: #FFB942;
    color: #0F172A;
}

.opt-calc__cta:focus-visible {
    /* !important бьёт сайтовое :focus { outline: 0 !important }.
       Разбор — у .opt-hero .btn-blue:focus-visible. */
    outline: 2px solid #FFFFFF !important;
    outline-offset: 2px;
}

/* Ниже 991 px плашка уходит под карточку расчёта и перестаёт тянуться
   по её высоте — запаса высоты больше нет, и margin-top: auto выше
   схлопывается в ноль: кнопка вставала вплотную к телефону менеджера.
   Здесь отступ задан явно. Замечание заказчика 26.08.2026. */
@media (max-width: 991px) {
    .opt-calc__cta {
        margin-top: 24px;
    }
}

/* Блок менеджера поднят под текст и отбит волосяной линией: раньше он стоял
   под кнопкой, а между текстом и кнопкой зияло 170 px пустоты. Теперь пустота
   уходит в дыхание над кнопкой, а плашка читается сверху вниз:
   кому — что — с кем говорить — что сделать. Замечание заказчика 23.08.2026. */
.opt-calc__mgr {
    display: flex;
    align-items: center;
    gap: 14px;
    margin-top: 4px;
    padding-top: 22px;
    border-top: 1px solid rgba(255, 255, 255, 0.22);
}

@media (max-width: 991px) {
    .opt-calc__mgr {
        gap: 12px;
        padding-top: 18px;
    }
}

/* Кружок с буквой имени. Светлая плашка дизайн-системы на чертёжном синем:
   пятно тёплой светлоты в холодном поле, к нему тянется взгляд.
   Сюда же встанет фотография, когда её дадут, — размер и форма те же. */
.opt-calc__mgravatar {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: #DDEDFA;
    font-size: 20px;
    font-weight: 700;
    line-height: 1;
    color: #102F97;
    overflow: hidden;
}

.opt-calc__mgravatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

@media (max-width: 991px) {
    .opt-calc__mgravatar {
        width: 46px;
        height: 46px;
        font-size: 18px;
    }
}

.opt-calc__mgrinfo {
    display: block;
    min-width: 0;
}

.opt-calc__mgrname {
    display: block;
    font-size: 15px;
    line-height: 21px;
    font-weight: 600;
    color: #FFFFFF;
}

.opt-calc__mgrtel {
    display: inline-block;
    margin-top: 2px;
    font-size: 17px;
    font-weight: 600;
    line-height: 22px;
    color: #FFFFFF;
    text-decoration: none;
    transition: all 300ms ease-in-out;
}

.opt-calc__mgrtel:hover {
    color: #FFFFFF;
}

/* Обводка белая: ссылка лежит на синей панели менеджера. Наведение здесь
   ничего не меняет — цвет остаётся белым, — поэтому без своей обводки
   клавиатура вообще не получала отклика. */

.opt-calc__mgrtel:focus-visible {
    /* !important бьёт сайтовое :focus { outline: 0 !important }.
       Разбор — у .opt-hero .btn-blue:focus-visible. */
    outline: 2px solid #FFFFFF !important;
    outline-offset: 2px;
}

/* Курсор, который печатает сам. Появляется только пока идёт набор:
   скрипт снимает класс, как только посетитель берёт поле себе. */
.opt-calc__pick.is-typing {
    caret-color: transparent;
}

@media (prefers-reduced-motion: reduce) {
    /* Печать не запускается вовсе, см. opt.js — поле сразу показывает
       обычную подсказку. Здесь возвращаем каретку. */
    .opt-calc__pick.is-typing {
        caret-color: auto;
    }
}


/* ===== Секции 7 и 9. Преимущества и документы ===== */

/* Порог бесплатной доставки. В прототипе тут стоял ползунок «сумма заказа»,
   заказчик его убрал 23.08.2026, но сам факт из секции пропал вместе с ним.
   Возвращаем фактом, а не виджетом.

   Форма выбрана так, чтобы не спорить с четырьмя карточками ниже: не карточка
   и не плашка, а строка на двух волосяных линиях — читается как условие
   над списком, а не как пятый пункт списка. Пятым пунктом строка сломала бы
   сетку 2 x 2, которую держит перенесённый сайтовый компонент.

   Герой строки — сумма: 30 px основным синим против 18 px у подписи. Это
   единственное число секции, и человек ищет глазами именно его.

   Цвет примечания — основной #0F172A, а не мета-серый #666666: секция лежит
   на фоне-шёлке, где мелкий серый даёт 4,07 при норме 4,5. Новых случаев
   этой проблемы не добавляем. */
.opt-ship {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 14px;
    margin: 0 0 30px;
    padding: 18px 0;
    border-top: 1px solid #E5E5E5;
    border-bottom: 1px solid #E5E5E5;
}

.opt-ship__label {
    font-size: 18px;
    font-weight: 600;
    line-height: 1.4;
    color: #0F172A;
}

.opt-ship__sum {
    font-size: 30px;
    font-weight: 700;
    line-height: 1.2;
    color: #102F97;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

/* Примечание уезжает к правому краю: между суммой и условием получается
   разрыв, и строка не читается как одна длинная фраза. */
.opt-ship__note {
    margin-left: auto;
    font-size: 15px;
    font-weight: 400;
    line-height: 1.5;
    color: #0F172A;
}

@media (max-width: 991px) {
    .opt-ship__note {
        margin-left: 0;
        flex-basis: 100%;
    }
}

@media (max-width: 767px) {
    .opt-ship {
        margin-bottom: 20px;
        padding: 14px 0;
    }

    .opt-ship__label {
        font-size: 16px;
    }

    .opt-ship__sum {
        font-size: 24px;
    }

    .opt-ship__note {
        font-size: 14px;
    }
}

/* [перенос] карточки с иконками */
.opt-adv .printing-advantages__list {
    list-style: none;
    margin: 0 0 30px;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

.opt-adv .printing-advantages__item {
    display: flex;
    flex-grow: 2;
    align-items: center;
    width: calc(50% - 20px);
    gap: 25px;
    padding: 20px;
    margin: 0;
    background-color: #ffffff;
    border-radius: 16px;
    box-shadow: 0px 6px 40px 10px #C5DBED;
}

@media (max-width: 767px) {
    .opt-adv .printing-advantages__item {
        width: 100%;
        gap: 15px;
    }
}

.opt-adv .printing-advantages__icon {
    flex-shrink: 0;
    width: 60px;
    height: 60px;
    background: linear-gradient(135deg, #63aeeb 0%, #5d7dcf 100%);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}

@media (max-width: 767px) {
    .opt-adv .printing-advantages__icon {
        width: 50px;
        height: 50px;
    }
}

.opt-adv .printing-advantages__icon svg {
    width: 32px;
    height: 32px;
    color: #fff;
}

@media (max-width: 767px) {
    .opt-adv .printing-advantages__icon svg {
        width: 28px;
        height: 28px;
    }
}

.opt-adv .printing-advantages__text {
    flex: 1;
    font-size: 16px;
    font-weight: 500;
}

@media (max-width: 767px) {
    .opt-adv .printing-advantages__text {
        font-size: 15px;
    }
}


/* ===== Секция 14. Форма заявки ===== */

/* Карточка целиком — сайтовый компонент .fabric-search-form с модификатором
   --new. На сайте он живёт в каталоге под названием «Не можете найти нужную
   ткань?» и уже даёт ровно то, что нужно этой форме: набор полей (имя,
   телефон и e-mail в строку, свободное поле про задачу), белые поля со
   светло-синей рамкой #D7DEF3, состояние фокуса, состояние ошибки и разметку
   сообщений об ошибке. Своя реализация всего этого была бы дублем.

   Прежняя сборка на .printing-form отменена: она держала два отдельных блока
   на голубой подложке, а по макету нужна одна карточка с синей панелью слева.
   Перенесённые под неё правила из printing.css удалены — компонент со
   страницы ушёл, правила без него мусор.

   Свои правила делают три вещи: собирают карточку в две колонки, переодевают
   левую в синюю панель и чинят строку из двух полей. Всё ограничено .opt-form,
   каталожная форма остаётся прежней. */

/* Ширина 1080 px, а не сайтовые 930: карточка держит нижний край страницы
   и должна читаться как главный блок. Полные 1200 не берём — поля вышли бы
   шире 600 px, и строка ввода перестаёт быть строкой. */
.opt-form {
    display: flex;
    align-items: stretch;
    max-width: 1080px;
    margin: 0 auto;
    padding: 0;
    border-radius: 16px;
    overflow: hidden;
    background: #FFFFFF;
    box-shadow: 0px 6px 40px 10px #C5DBED;
}

@media (max-width: 991px) {
    .opt-form {
        flex-direction: column;
        border-radius: 12px;
    }
}

/* Синяя панель. Сайтовые ширины у .fabric-search-form__desc заданы под
   каталог (calc(100% - 360px), потом max-width 415px), поэтому переопределяем
   обе. Селектор из двух классов — иначе сайтовое правило с --new не перебить. */
/* Панель не плоская. Приём тот же, что на промо-полосе секции 12 и по той же
   причине: ровная заливка одним цветом на площади 454 x 626 читается как
   непрокрашенное место. Два слоя объёма — световое пятно в верхнем левом углу,
   где стоит логотип, и затемнение в нижнем правом, под кнопкой соседней
   колонки. Обе краски сайтовые: барвинковый #5D7DCF и синий #002C9E,
   новых в палитру не вводим. Ноль байт загрузки.

   Контраст считан по самой светлой точке пятна: белый текст держит 7,07 : 1,
   светло-голубой абзац 5,92 : 1 при норме 4,5. Затемнение контраст только
   поднимает. */
.opt-form .opt-form__desc {
    flex: 0 0 42%;
    width: 42%;
    max-width: 42%;
    justify-content: flex-start;
    padding: 48px 44px;
    background-color: #102F97;
    background-image:
        radial-gradient(120% 90% at 8% 0%, rgba(93, 125, 207, 0.40) 0%, rgba(93, 125, 207, 0) 60%),
        radial-gradient(100% 80% at 100% 100%, rgba(0, 44, 158, 0.55) 0%, rgba(0, 44, 158, 0) 65%);
}

@media (max-width: 991px) {
    .opt-form .opt-form__desc {
        flex: 0 0 auto;
        width: 100%;
        max-width: 100%;
        padding: 28px 20px;
    }
}

.opt-form__logo {
    display: block;
    width: 160px;
    height: auto;
    margin: 0 0 40px;
}

@media (max-width: 991px) {
    .opt-form__logo {
        width: 132px;
        margin-bottom: 24px;
    }
}

/* Заголовок секции 14.

   По центру — как у секции FAQ выше, чтобы две соседние секции не
   расходились по построению. Размер, цвет и нижний отступ сайтовые,
   из .title-h2, поэтому здесь только выравнивание.

   Под заголовком стояла подпись «Каталог — это ещё не всё, что у нас есть»,
   снята 25.08.2026 по решению заказчика. Вместе с ней убраны правила
   .opt-formsec__lead и укороченный нижний отступ заголовка: без подписи
   заголовку нужен обычный сайтовый отступ до карточки формы. */

.opt-formsec__title {
    text-align: center;
}


/* Название формы внутри синей карточки.

   Сайтовый компонент держит здесь h2, и сайтовое правило делает его
   inline-flex в колонку шириной 340 px под два span. У нас это уже не h2,
   а div (см. разметку: два h2 на одну секцию — перебор), и заголовок один,
   поэтому все нужные свойства заданы здесь явно. Вид от смены тега
   не меняется. */
.opt-form .opt-form__title {
    display: block;
    max-width: 100%;
    margin: 0 0 20px;
    font-size: 30px;
    font-weight: 600;
    line-height: 1.3;
    color: #FFFFFF;
}

@media (max-width: 991px) {
    .opt-form .opt-form__title {
        font-size: 22px;
        margin-bottom: 14px;
    }
}

/* Подложка бейджей #DDEDFA в роли текста по синему: 10,9 : 1, читается
   спокойнее чистого белого и не спорит с заголовком. */
.opt-form .opt-form__desc p {
    margin: 0;
    font-size: 16px;
    font-weight: 400;
    line-height: 1.7;
    color: #DDEDFA;
}

@media (max-width: 991px) {
    .opt-form .opt-form__desc p {
        font-size: 15px;
        line-height: 1.5;
    }
}

/* Три условия внизу панели. margin-top: auto прижимает список к низу:
   высоту карточки задаёт форма справа, и без этого список висел бы
   сразу под абзацем, а под ним оставалась бы пустая треть панели.

   Список свой, а не сайтовый .chekc-list: тот рассчитан на тёмный текст
   по светлой подложке и рисует синюю галочку, которая по синему пропадает.
   list-style и отступы гасим явно — сайт вешает свои на li в контентной зоне. */
/* Волосяная линия над группой. Высоту панели задаёт форма справа, поэтому
   между абзацем и условиями остаётся около 140 px воздуха. Без линии это
   читается как дыра, с линией — как подвал панели: сверху обещание, снизу
   условия, на которых оно выполняется. */
.opt-form__list {
    width: 100%;
    margin: auto 0 0;
    padding: 24px 0 0;
    border-top: 1px solid rgba(255, 255, 255, 0.18);
    list-style: none;
}

.opt-form__list li {
    display: flex;
    align-items: center;
    gap: 14px;
    margin: 0 0 18px;
    padding: 0;
    font-size: 15px;
    line-height: 1.4;
    color: #FFFFFF;
    list-style: none;
}

.opt-form__list li:last-child {
    margin-bottom: 0;
}

.opt-form__list li::before {
    display: none;
}

@media (max-width: 991px) {
    .opt-form__list {
        margin-top: 24px;
    }

    .opt-form__list li {
        font-size: 14px;
        gap: 12px;
    }
}

/* Плитка иконки — белая завеса 12 % поверх синего.

   Иконки светло-голубые #DDEDFA, а не жёлтые, хотя жёлтый в палитре есть.
   На этой странице #FFCB00 — цвет действия: им покрашена кнопка крупного опта
   в секции 6 по прямому указанию заказчика. Три жёлтых квадрата 36 px в панели
   перетягивают взгляд с заголовка и с кнопки отправки, то есть с того, ради
   чего секция стоит. Единственное тёплое пятно в панели — точка в логотипе,
   и этого достаточно. */
.opt-form__ico {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.12);
    color: #DDEDFA;
}

.opt-form__ico svg {
    width: 18px;
    height: 18px;
}

@media (max-width: 991px) {
    .opt-form__ico {
        width: 32px;
        height: 32px;
        border-radius: 8px;
    }

    .opt-form__ico svg {
        width: 16px;
        height: 16px;
    }
}


.opt-form .opt-form__form {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
    padding: 48px 44px;
}

@media (max-width: 991px) {
    .opt-form .opt-form__form {
        padding: 24px 20px 28px;
    }
}

/* Модификатор --new делает .form-group блочным, а --two-field рассчитан
   на флекс: без этого телефон и e-mail встают друг под друга. Ширину полей
   сайт задаёт как 48 % — заменяем на flex, чтобы поля делили строку поровну
   при любом gap. */
.opt-form .form-group--two-field {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
}

.opt-form .form-group--two-field .form-control {
    flex: 1 1 0;
    min-width: 0;
    max-width: none;
}

@media (max-width: 575px) {
    .opt-form .form-group--two-field {
        gap: 12px;
    }

    .opt-form .form-group--two-field .form-control {
        flex: 0 0 100%;
    }
}

.opt-form textarea.form-control {
    display: block;
    width: 100%;
    resize: none;
}

/* Согласие: сайтовый .form-group--checkbox оформлен только внутри оформления
   заказа и окна авторизации, здесь он приходит голым. Свои правила — только
   раскладка и размер, вид галочки остаётся системным. */
.opt-form .form-group--checkbox {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 20px;
}

.opt-form .form-group--checkbox input {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    margin: 3px 0 0;
}

.opt-form .form-group--checkbox label {
    margin: 0;
    font-size: 14px;
    line-height: 1.5;
    color: #0F172A;
}

.opt-form .form-group--checkbox a {
    color: #102F97;
    text-decoration: underline;
}

.opt-form .opt-form__captcha {
    display: block;
    margin-bottom: 20px;
}

.opt-form .opt-form__submit {
    width: 100%;
    padding: 16px 20px;
    font-size: 16px;
    font-weight: 600;
    line-height: 20px;
    text-transform: initial;
}

/* Обводка синяя: кнопка синяя, но стоит на белой половине карточки,
   и обводка с отступом ложится на белое. Это главная кнопка страницы —
   без видимого фокуса до неё нельзя было дойти с клавиатуры осознанно. */

.opt-form .opt-form__submit:focus-visible {
    /* !important бьёт сайтовое :focus { outline: 0 !important }.
       Разбор — у .opt-hero .btn-blue:focus-visible. */
    outline: 2px solid #102F97 !important;
    outline-offset: 2px;
}

.opt-form__note {
    margin: 16px 0 0;
    font-size: 15px;
    line-height: 1.5;
    color: #0F172A;
    text-align: center;
}

/* Подпись под кнопкой встаёт по её середине.

   В сайтовом main.min.css лежит правило .fabric-search-form p с
   max-width: 450 px. Кнопка над подписью шире — она тянется во всю
   ширину карточки, 538 px. Подпись центрируется внутри своих 450 px
   и потому уезжает левее середины кнопки на 44 px.

   Снимаем ограничение только со своей подписи. Отдельным правилом,
   а не строкой выше: там всего один класс, и сайтовый селектор
   «класс + тег» его перебивает. Два класса подряд весомее.
   Чужой файл при этом не тронут. */

.opt-form .opt-form__note {
    max-width: none;
}

/* ===== Секция 10. Личный кабинет оптовика ===== */

/* Вариант 1 «Кабинет как есть», выбран заказчиком 23.08.2026 на странице
   _varianty/varianty-kabinet.html. Прямая сборка присланного макета:
   синяя шапка с «ИП», суммой закупок за год и тремя строками заказов.

   Классы переименованы под свой префикс. На странице вариантов блок звался
   .a / .a__ord / .st — такие голые имена в общий css выносить нельзя,
   они бы столкнулись с чем угодно на сайте.

   Левая колонка осталась сайтовой: .two-column__bubble, .chekc-list и
   .btn-blue уже дают нужный вид, свои .k-* со страницы вариантов были
   времянкой на время показа и сюда не переносятся.

   Тени у двух колонок разные: у сайтового пузыря слева тёпло-серая,
   у карточки справа холодная синяя. Осознанное отступление, см.
   _docs/TOKENS-DIFF.md. */
.opt-acc {
    border-radius: 20px;
    overflow: hidden;
    background: #FFFFFF;
    box-shadow: 0 4px 24px rgba(197, 219, 237, 0.75);
}

.opt-acc__top {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 20px 24px;
    background: #102F97;
    color: #FFFFFF;
}

/* Сумма за год переносится под имя, а не жмёт его. Порог 991 px —
   сайтовый: с него колонка становится calc(50% - 10px) и имени
   покупателя перестаёт хватать места. */
@media (max-width: 991px) {
    .opt-acc__top {
        flex-wrap: wrap;
    }
}

.opt-acc__ava {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 10px;
    background: #FFCB00;
    color: #102F97;
    font-size: 15px;
    font-weight: 700;
}

/* min-width: 0 обязателен: без него флекс-элемент не сжимается ниже
   своего содержимого и вытесняет сумму за год за край карточки. */
.opt-acc__who {
    flex: 1 1 auto;
    min-width: 0;
}

/* Цвет задан явно, хотя синяя шапка уже красит содержимое в белый:
   в main.min.css есть голое правило p { color: #2b2b2b }, и оно
   перебивает наследование. По той же причине цвет проставлен
   названию ткани ниже. */
.opt-acc__client {
    margin: 0;
    color: #FFFFFF;
    font-size: 17px;
    font-weight: 600;
    line-height: 23px;
}

.opt-acc__place {
    margin: 2px 0 0;
    font-size: 14px;
    line-height: 20px;
    color: #DDEDFA;
}

.opt-acc__year {
    flex: 0 0 auto;
    text-align: right;
}

.opt-acc__yearcap {
    display: block;
    font-size: 12px;
    line-height: 16px;
    color: #DDEDFA;
}

.opt-acc__yearval {
    display: block;
    font-size: 18px;
    font-weight: 700;
    line-height: 24px;
}

/* Подпись списка заказов. 12 px прописными с разрядкой — и цвет #9A9CA3
   давал 2,74 : 1 при норме 4,5. Мелкий текст прописными читается тяжелее
   строчного, и приглушать его нельзя вовсе. #666666 — 5,74 : 1. */

.opt-acc__cap {
    margin: 0;
    padding: 18px 24px 10px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #666666;
}

/* Сброс сайтовых правил для списков в контентной зоне: там на li висят
   свой маркер и отступы, из-за которых колонка уезжает вправо. */
.opt-acc__list {
    margin: 0;
    padding: 0 8px 14px;
    list-style: none;
}

/* Промежутки 10 px, а не 12 px, как на странице вариантов: там карточка
   была 610 px, здесь колонка сайта даёт 580 px. Каждая строка — своя
   сетка, и ширина под название зависит от того, какой в ней бейдж:
   у «Доставлен» она самая узкая. Четыре промежутка и поля по 10 px
   возвращают 12 px, которых не хватало длинному названию. */
.opt-acc__ord {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) auto auto auto;
    gap: 10px;
    align-items: center;
    margin: 0;
    padding: 12px 10px;
    list-style: none;
    border-radius: 12px;
    transition: background 0.4s ease-in-out;
}

/* Строка, которая сейчас меняет состояние, подсвечивается холодной
   полосой — иначе смена статуса проходит незамеченной. */
.opt-acc__ord.is-active {
    background: #F0F5F9;
}

/* Порог 1259 px, а не телефонный 767 px, и не сайтовый 1199 px.

   Пять колонок в строке помещаются только при полной ширине контейнера:
   .container это 1230 px минус поля, колонка получает ровно 580 px,
   и длинному названию ткани остаётся 12 px запаса. Стоит контейнеру
   начать сжиматься — запас уходит в минус и название рвётся на две
   строки. Контейнер перестаёт быть полным, когда окну не хватает
   1230 px плюс полоса прокрутки, а её ширина у разных систем разная,
   от нуля до 17 px. Отсюда 1259: с 1260 px контейнер гарантированно
   полный при любой полосе.

   Ниже строка складывается: фотография держит левый край, статус
   и сумма встают в одну строку под названием, кнопка уходит вниз
   во всю ширину. Так же она выглядит на планшете и телефоне. */
@media (max-width: 1259px) {
    .opt-acc__ord {
        grid-template-columns: 52px minmax(0, 1fr);
        grid-template-areas:
            'p m'
            'p s'
            'b b';
        gap: 6px 12px;
        padding: 12px;
    }
}

.opt-acc__pic {
    display: block;
    width: 64px;
    height: 64px;
    border-radius: 8px;
    object-fit: cover;
}

@media (max-width: 1259px) {
    .opt-acc__pic {
        grid-area: p;
        width: 52px;
        height: 52px;
    }
}

.opt-acc__main {
    min-width: 0;
}

@media (max-width: 1259px) {
    .opt-acc__main {
        grid-area: m;
    }
}

/* Название ткани 15 px, а не 17 px, как вышло на странице вариантов.
   Там в разметке стоял класс шапки, и строки заказов случайно набрались
   её кеглем. В колонке страницы она на 30 px уже, чем на показе, и при
   17 px два названия из трёх переносятся на вторую строку: длинному
   нужно 194 px, а есть 180. При 15 px запас 8 px, и заодно имя покупателя
   в синей шапке остаётся крупнее строк списка, как и задумано. */
.opt-acc__ordname {
    margin: 0 0 3px;
    color: #0F172A;
    font-size: 15px;
    font-weight: 600;
    line-height: 21px;
}

.opt-acc__meta {
    margin: 0;
    font-size: 13px;
    line-height: 18px;
    color: #666666;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.opt-acc__sum {
    font-size: 16px;
    font-weight: 700;
    white-space: nowrap;
}

@media (max-width: 1259px) {
    .opt-acc__sum {
        grid-area: s;
        justify-self: end;
    }
}

.opt-acc__rep {
    padding: 9px 16px;
    border: 1px solid #102F97;
    border-radius: 8px;
    background: #FFFFFF;
    font: inherit;
    font-size: 14px;
    font-weight: 500;
    color: #102F97;
    white-space: nowrap;
    cursor: pointer;
    transition: all 0.3s ease-in-out;
}

.opt-acc__rep:hover {
    background: #DDEDFA;
}

/* Повторить можно только то, что уже доставлено. */
.opt-acc__rep[disabled] {
    border-color: #E5E5E5;
    background: #FFFFFF;
    color: #9A9CA3;
    cursor: default;
}

.opt-acc__rep.is-added {
    border-color: #102F97;
    background: #102F97;
    color: #FFFFFF;
}

@media (max-width: 1259px) {
    .opt-acc__rep {
        grid-area: b;
        margin-top: 6px;
    }
}

/* На планшете и узком ноутбуке кнопку не растягиваем: в карточке
   шириной под 560 px кнопка во всю строку читается как главный призыв
   и спорит с настоящей кнопкой «Войти в кабинет» в соседней колонке.
   На телефоне растянутая кнопка уместна — там она одна в строке. */
@media (min-width: 768px) and (max-width: 1259px) {
    .opt-acc__rep {
        justify-self: start;
    }
}

/* Бейдж состояния заказа. Три цвета взяты из сайтовой палитры:
   подложка бейджей #DDEDFA для отправленного, жёлтый и зелёный —
   осветлённые #FFCB00 и #75B819 под тот же приём. */
.opt-acc__st {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border-radius: 100px;
    font-size: 12px;
    font-weight: 600;
    line-height: 16px;
    white-space: nowrap;
    transition: all 0.4s ease-in-out;
}

/* Значок «В работе». Тёмный янтарь по жёлтому давал 4,29 : 1 — не хватало
   0,21 до нормы. Затемнён на пять пунктов, до #856800: 4,61 : 1. Это тот же
   расчётный тёмный янтарь, что стоял, просто доведённый до порога, а не новый
   цвет в палитре. */

.opt-acc__st--work {
    background: #FDEFC5;
    color: #856800;
}

.opt-acc__st--sent {
    background: #DDEDFA;
    color: #102F97;
}

.opt-acc__st--done {
    background: #E8F5D8;
    color: #4B7A0F;
}

@media (max-width: 1259px) {
    .opt-acc__status {
        grid-area: s;
        justify-self: start;
    }
}

/* Левая колонка секции. Сайтовый пузырь тянется на высоту соседа,
   а содержимого в нём вдвое меньше, чем в карточке кабинета: текст
   с кнопкой прижимались к верхнему краю, а под ними оставалось
   больше полутора сотен пикселей пустоты.

   Правила ограничены классом секции .opt-accsec: .two-column__bubble
   и .btn-blue — сайтовые классы, и без ограничения правки уехали бы
   на все страницы сайта, где эти компоненты используются. */
.opt-accsec .two-column__bubble {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 40px;
}

@media (max-width: 991px) {
    .opt-accsec .two-column__bubble {
        padding: 30px 20px;
    }
}

/* В колонке кнопка по умолчанию растянулась бы во всю ширину пузыря.
   Отступ сверху отделяет её от списка: вплотную она читалась как
   четвёртый пункт. */
.opt-accsec .btn-blue {
    align-self: flex-start;
    margin-top: 28px;
}


/* ===== Фон страницы ===== */

/* Ровный белый под всей контентной зоной.

   До 24.08.2026 здесь лежала фотография белого шёлка, закреплённая
   неподвижно: контент ехал поверх, и страница читалась как лист, положенный
   на ткань. Заказчик её убрал. Правило и картинки сняты целиком, файлы
   фона перенесены в _masters/silk/ — если фактуру решат вернуть, они там.

   Белый задан явно, а не оставлен на умолчание браузера. Белые секции
   страницы прозрачны: свой цвет есть только у серых полос .blue-bg.
   Без этого правила под ними просвечивал бы фон страницы сайта, каким бы
   он ни оказался, и мы бы за него не отвечали.

   Побочный выигрыш: мелкий серый текст #666666 в шести белых секциях лежал
   на фактуре и давал контраст 4,07 при норме 4,5. На ровном белом он даёт
   5,73, и вопрос закрыт сам собой без осветления и завес. */
.opt-page {
    background-color: #FFFFFF;
}


/* ===== Секция 11. Клиенты ===== */

/* Карусель логотипов на сайтовом Slick — своей реализации тут не нужно,
   плагин уже поднят на секции 5 и умеет всё, что требуется: бесконечный
   круг, автопрокрутка, перетаскивание мышью.

   Настройки поднимает opt.js по классу .js-opt-clients: сайтовые функции
   initProductSlick* заточены под карточки товара и наружу не выведены.

   Монограммы — заглушки под настоящие логотипы. Когда логотипы придут,
   .opt-clients__logo меняется на <picture> с картинкой 64 x 64 в 1x и 2x,
   правила размера и скругления останутся те же. */
.opt-clients__track {
    margin: 0 -10px;
}

/* Пока Slick не поднялся, карточки лежат в ряд, а не столбиком:
   иначе при медленном интернете видно, как секция схлопывается. */
.opt-clients__track:not(.slick-initialized) {
    display: flex;
    overflow: hidden;
}

.opt-clients__item {
    padding: 0 10px;
    outline: none;
}

.opt-clients__track:not(.slick-initialized) .opt-clients__item {
    flex: 0 0 20%;
}

@media (max-width: 1199px) {
    .opt-clients__track:not(.slick-initialized) .opt-clients__item {
        flex-basis: 25%;
    }
}

@media (max-width: 991px) {
    .opt-clients__track:not(.slick-initialized) .opt-clients__item {
        flex-basis: 33.333%;
    }
}

@media (max-width: 767px) {
    .opt-clients__track:not(.slick-initialized) .opt-clients__item {
        flex-basis: 50%;
    }
}

/* Высоту держим одинаковой у всех карточек: Slick кладёт слайды в строку
   и по высоте их не равняет, а названия у клиентов разной длины. */
.opt-clients__card {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    height: 100%;
    min-height: 168px;
    padding: 24px 16px 20px;
    border: 1px solid #E5E5E5;
    border-radius: 16px;
    background: #FFFFFF;
    text-align: center;
    transition: all 0.3s ease-in-out;
}

.opt-clients__card:hover {
    border-color: #95C7EF;
    box-shadow: 0 6px 24px rgba(197, 219, 237, 0.55);
}

/* Монограмма-заглушка. Цвет чередуется через одну карточку, чтобы ряд
   не выглядел как таблица: нечётные — основной синий, чётные — тёмный. */
.opt-clients__logo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    margin-bottom: 16px;
    border-radius: 12px;
    background: #102F97;
    color: #FFFFFF;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.opt-clients__item:nth-child(even) .opt-clients__logo {
    background: #0F172A;
}

.opt-clients__name {
    margin-bottom: 4px;
    font-size: 15px;
    font-weight: 600;
    line-height: 21px;
    color: #0F172A;
}

.opt-clients__kind {
    font-size: 13px;
    line-height: 18px;
    color: #666666;
}

/* Курсор показывает, что ленту можно тащить. Slick сам этого не делает. */
.opt-clients .slick-list {
    cursor: grab;
}

.opt-clients .slick-list:active {
    cursor: grabbing;
}

/* Slick кладёт слайды в строку через float и по высоте их не равняет.
   Флекс на дорожке выравнивает карточки под самую высокую. */
.opt-clients .slick-track {
    display: flex;
    align-items: stretch;
}

.opt-clients .slick-slide {
    height: auto;
    float: none;
}


/* ===== Секция 12. Промо-полоса «Остатки −70 %» ===== */

/* Композиция «Ярлык», выбрана заказчиком 24.08.2026 из трёх на
   _varianty/varianty-promo.html. Скидка вынесена на белый ярлык
   с пробитым отверстием — такой, какой вешают на рулон, — а за ним
   идёт линия перфорации, как у отрывного талона. Приём из мира
   заказчика, а не из мира распродаж.

   Цвета все свои. Оранжевого из прототипа в палитре сайта нет,
   зато есть жёлтый #FFCB00, янтарный #FFB942 — цвет ссылки
   «Распродажа», и красный #F53C34 — цвет цены по скидке. Оранжевый
   сам получается на переходе между янтарём и красным.

   Направление рампы не случайное: светлый край слева, где лежит текст
   (тёмная краска держит там 5,1:1 даже у подписи), тёмный справа, где
   стоят белые ячейки счётчика и белая кнопка. Заодно полоса
   «нагревается» в сторону кнопки, и глаз идёт туда же.

   Сверху два слоя объёма: световое пятно из левого верхнего угла
   и лёгкое затемнение в правом нижнем. Без них рампа читается
   как заливка, а не как поверхность.

   Полоса собрана карточкой внутри контейнера, а не во всю ширину экрана:
   во всю ширину она кричала бы на всю страницу, а по правилам голоса
   мы спокойный старший партнёр, а не скидочный маркетплейс. */
.opt-sale__band {
    display: flex;
    align-items: center;
    gap: 34px;
    padding: 30px 40px 30px 30px;
    border-radius: 20px;
    background:
        radial-gradient(90% 150% at 10% -25%, rgba(255, 255, 255, 0.45) 0%, rgba(255, 255, 255, 0) 62%),
        radial-gradient(75% 130% at 102% 125%, rgba(15, 23, 42, 0.20) 0%, rgba(15, 23, 42, 0) 58%),
        linear-gradient(100deg, #FFCB00 0%, #FFB942 45%, #F53C34 100%);
}

/* Когда полоса переносится в две строки, рампа разворачивается сверху вниз.
   Логика та же, только по другой оси: наверху светлое, там текст; внизу
   тёмное, там белые ячейки и белая кнопка. Если оставить рампу
   горизонтальной, текст во всю ширину заезжает в красный край,
   и контраст подписи падает с 5,1 до 3,8 — ниже нормы. */
@media (max-width: 1199px) {
    .opt-sale__band {
        flex-wrap: wrap;
        gap: 24px;
        padding: 26px 24px;
        background:
            radial-gradient(120% 80% at 8% -10%, rgba(255, 255, 255, 0.45) 0%, rgba(255, 255, 255, 0) 60%),
            radial-gradient(110% 70% at 100% 115%, rgba(15, 23, 42, 0.20) 0%, rgba(15, 23, 42, 0) 58%),
            linear-gradient(172deg, #FFCB00 0%, #FFB942 45%, #F53C34 100%);
    }
}

/* Ярлык. Поворот маленький, на два градуса: больше — и он начинает
   выглядеть наклейкой, а не биркой. От экранного диктора скрыт:
   величина скидки повторена словами в подписи под заголовком. */
.opt-sale__tag {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 158px;
    padding: 20px 14px 18px;
    border-radius: 14px;
    background: #FFFFFF;
    transform: rotate(-2deg);
    box-shadow: 0 10px 30px rgba(15, 23, 42, 0.18);
}

@media (max-width: 575px) {
    .opt-sale__tag {
        width: 100%;
        transform: none;
    }
}

.opt-sale__hole {
    width: 14px;
    height: 14px;
    margin-bottom: 10px;
    border-radius: 50%;
    background: rgba(15, 23, 42, 0.16);
}

.opt-sale__num {
    font-size: 44px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: -0.02em;
    color: #0F172A;
}

.opt-sale__word {
    margin-top: 6px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #666666;
}

/* Линия перфорации: ряд точек, как на отрывном талоне. */
.opt-sale__perf {
    flex: 0 0 auto;
    align-self: stretch;
    width: 2px;
    margin: 6px 0;
    background: repeating-linear-gradient(180deg,
        rgba(15, 23, 42, 0.30) 0 6px,
        rgba(15, 23, 42, 0) 6px 14px);
}

/* На перенесённой раскладке перфорация только мешает: она разделяла
   ярлык и текст по горизонтали, а они уже стоят друг под другом. */
@media (max-width: 1199px) {
    .opt-sale__perf {
        display: none;
    }
}

.opt-sale__text {
    flex: 1 1 auto;
    min-width: 0;
}

.opt-sale__title {
    margin: 0 0 8px;
    font-size: 22px;
    font-weight: 600;
    line-height: 30px;
    color: #0F172A;
}

@media (max-width: 991px) {
    .opt-sale__title {
        font-size: 18px;
        line-height: 25px;
    }
}

/* Не отдельный цвет, а прозрачность основного текста #0F172A.
   Своей коричневой краски в дизайн-системе нет, а вводить её ради
   одной полосы нельзя — второй уровень текста делаем прозрачностью. */
.opt-sale__sub {
    margin: 0;
    font-size: 15px;
    line-height: 22px;
    color: rgba(15, 23, 42, 0.75);
}

/* Счётчик и кнопка выровнены по НИЖНЕМУ краю, а не по центру.

   По центру они и стояли сначала, и это было замечание заказчика:
   «вроде одной высоты, а на разных высотах». Причина в том, что
   у счётчика над ячейками есть ещё строка подписи. При выравнивании
   по центру кнопка вставала ровно между подписью и ячейками — то есть
   не в линию ни с тем, ни с другим.

   Теперь кнопка ровно той же высоты, что ячейки счётчика, и стоит
   с ними в одну строку. Подпись висит над этой строкой и читается
   как заголовок к счётчику. */
.opt-sale__side {
    flex: 0 0 auto;
    display: flex;
    align-items: flex-end;
    gap: 24px;
}

@media (max-width: 1199px) {
    .opt-sale__side {
        width: 100%;
        justify-content: space-between;
    }
}

@media (max-width: 575px) {
    .opt-sale__side {
        flex-direction: column;
        align-items: stretch;
        gap: 16px;
    }
}

.opt-sale__cap {
    display: block;
    margin-bottom: 8px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: rgba(15, 23, 42, 0.75);
}

.opt-sale__cells {
    display: flex;
    gap: 8px;
}

/* Ширина ячейки фиксированная: без неё полоса дёргалась бы каждую
   секунду, когда «9» сменяется на «10». Высота задана числом,
   а не набором отступов, потому что по ней равняется кнопка. */
.opt-sale__cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 62px;
    height: 58px;
    border-radius: 12px;
    background: rgba(255, 255, 255, 0.94);
}

@media (max-width: 575px) {
    .opt-sale__cell {
        flex: 1 1 0;
        width: auto;
    }
}

.opt-sale__val {
    font-size: 22px;
    font-weight: 700;
    line-height: 26px;
    color: #0F172A;
    font-variant-numeric: tabular-nums;
}

.opt-sale__unit {
    font-size: 11px;
    font-style: normal;
    line-height: 15px;
    color: #666666;
}

/* Кнопка белая: на янтаре синяя сайтовая кнопка теряется, а белая
   работает как в прототипе. Высота — ровно как у ячеек счётчика,
   отсюда height вместо вертикальных отступов. */
.opt-sale__btn {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    height: 58px;
    padding: 0 26px;
    border-radius: 8px;
    background: #FFFFFF;
    color: #102F97;
    font-size: 16px;
    font-weight: 600;
    line-height: 20px;
    text-decoration: none;
    white-space: nowrap;
    transition: all 0.3s ease-in-out;
}

.opt-sale__btn:hover,
.opt-sale__btn:focus {
    background: #F1F8FE;
    color: #002C9E;
    text-decoration: none;
}

/* Обводка синяя: кнопка белая и лежит на янтарно-красной ленте, синее
   по тёплому читается уверенно. Правило :focus выше меняет только заливку
   и от наведения не отличается — для клавиатуры этого мало. */

.opt-sale__btn:focus-visible {
    /* !important бьёт сайтовое :focus { outline: 0 !important }.
       Разбор — у .opt-hero .btn-blue:focus-visible. */
    outline: 2px solid #102F97 !important;
    outline-offset: 2px;
}

@media (max-width: 575px) {
    .opt-sale__btn {
        justify-content: center;
    }
}

/* Когда срок вышел: счётчик прячется, на его месте строка из
   data-opt-over. Нулей на полосе висеть не должно. */
.opt-sale__over {
    font-size: 15px;
    font-weight: 600;
    line-height: 22px;
    color: #0F172A;
}


/* ===== Секция 13. FAQ ===== */
/* Аккордеон сайтовый, .accordion-block--new. Разметка и вид его родные,
   меняем только положение на странице.

   На сайте он живёт в узкой колонке каталога, где ширина 710 px и прижатие
   влево — правильные. В контейнере 1200 px та же полоса висит у левого края
   без опоры: справа остаётся 490 px пустоты. Поэтому центрируем её вместе
   с заголовком.

   Сайтовый margin-top: 80 px тоже оттуда: в каталоге аккордеон идёт после
   seo-текста, а не после своего заголовка. Здесь он схлопывается с нижним
   отступом .title-h2 в 80 px, и заголовок отрывается от блока — на странице
   расстояние между заголовком и содержимым везде 40 px. Обнуляем, чтобы
   работал отступ заголовка.

   Оба правила ограничены .opt-faq: на страницах каталога аккордеон должен
   остаться прежним. */
.opt-faq__title {
    text-align: center;
}

.opt-faq .accordion-block--new {
    margin-top: 0;
    margin-left: auto;
    margin-right: auto;
}


/* ===== Подвал: заливка волны ===== */

/* Сайтовый подвал .footer-new залит не цветом, а картинкой: SVG-волна цвета
   #E0EAF2, прижатая к верху и растянутая по ширине. Всё, что выше линии
   волны, остаётся прозрачным — и на нашей странице там просвечивает белый
   фон. Справа, где волна опускается ниже всего, получается заметная белая
   прогалина между последней секцией и подвалом.

   Заливаем ровным цветом: тем же #E0EAF2, что и сама волна. Верхний край
   подвала становится прямой линией.

   Правило ограничено меткой .opt-body на body этой страницы. Подвал общий
   для всего сайта, и без метки заливка уехала бы на все страницы разом —
   прямой запрет из PRAVILO-izolyaciya-pravok.md. Волну при этом не удаляем,
   а перекрываем: убрали метку — вернулась как была. */

.opt-body .footer-new {
    background-image: none;
    background-color: #E0EAF2;
}
