﻿/* ============================================================================
   Лендинг по финал.psd и чтомы.psd.

   Все координаты — из макета, поделённые на 2 (холст 2560 = 1280 CSS-пикселей).
   Секции построены на сетке 1168 px: именно столько занимает контент в макете
   (от x=112 до x=2448 при холсте 2560).
   ========================================================================== */

/* Класса .bl-page в разметке нет — правило досталось от прежней вёрстки
   и ничего не обрезало. Вылет арта убран не обрезкой, а самим положением
   (см. .bl-hero__art ниже). */

/* Шапка прибита к верху окна, поэтому прокрутка по якорю обязана
   останавливаться на её высоту раньше — иначе заголовок секции уезжает
   под полосу. */
.bl-offers,
.bl-process,
.bl-order,
.bl-orderwin,
.bl-reviews,
.bl-faq { scroll-margin-top: calc(var(--bl-header-h) + 12px); }


/* ── Hero ────────────────────────────────────────────────────────────────── */
/* Арт в макете свисает ниже границы секции (до y=810 при заголовке следующей
   секции на 794) — поэтому не обрезаем, а просто пускаем поверх. */
.bl-hero {
    position: relative;
    height: 622px;
    margin-top: var(--bl-header-h);
}

/* Подложка героя. В макете за Виндж не пустая чернота, а дым с парящими
   гербами рангов Deadlock — в PSD они лежат режимом «осветление основы»
   поверх почти чёрного фона, поэтому светятся еле-еле. Режим наложения
   посчитан заранее и запечён в картинку: так результат не зависит от того,
   что окажется под ним.
   Высота 732 — вся высота подложки в макете; секция ниже (622), поэтому
   низ с крупным гербом свисает под неё, как и нарисовано.

   Картинка не тянется по ширине и стоит по центру в натуральную величину,
   а её края растушёваны прямо в файле (альфа сходит на нуль: слева 88 px,
   справа 300, снизу 74 — гербы лежат в x 100…906 и y 74…645, растушёвка их
   не задевает).

   Под картинкой лежат две полоски — hero-backdrop-edge-l/r.webp. Это столбец
   самой подложки, снятый там, где её альфа выходит на плато; растянутый на
   половину ширины, он продолжает тон подложки до края экрана. Раньше это была
   страховка на редкий случай — теперь поля на главной есть всегда, она мельче
   макетной ширины на 8% (см. body.bl-home в bl.css). Без полосок по краю
   оставалась бы голая заливка страницы, светлее подложки, и кромка читалась
   вертикальной линией.

   Столбец сглажен по вертикали. Он растягивается на всю ширину поля, и любая
   деталь в нём — светлая полоса дыма, край рамки на фотографии — становилась
   прямой линией через весь край экрана: у героя такая линия на 190-й строке
   была вдвое ярче фона. Теперь в столбце остался один тон, деталей нет:
   перепад с соседними строками меньше единицы яркости. На стык с картинкой
   сглаживание не влияет — у подложки на краю альфа уже нулевая, там и так
   виден только столбец.

   Середина подложки непрозрачна (альфа 255), поэтому полоски видны ровно там,
   где картинка сходит на нет, и нигде больше; сверху и снизу у них та же
   растушёвка, что у самой подложки, — концы полосок сглаживание не трогает.
   Весят 300–400 байт. */
.bl-hero::before {
    content: '';
    position: absolute;
    z-index: 0;
    top: 0;
    left: 0;
    right: 0;
    height: 732px;
    pointer-events: none;
    background:
        image-set(url('../img/design/hero-backdrop.webp') 1x,
                  url('../img/design/hero-backdrop@2x.webp') 2x) no-repeat 50% 0 / 1280px 732px,
        url('../img/design/hero-backdrop-edge-l.webp?v=2') no-repeat left  0 / 50.5% 732px,
        url('../img/design/hero-backdrop-edge-r.webp?v=2') no-repeat right 0 / 50.5% 732px;
}
.bl-hero__inner {
    position: relative;
    z-index: 2;
    max-width: calc(var(--bl-container) + 32px);
    height: 100%;
    margin-inline: auto;
    padding-inline: 16px;
}

/* Виндж прижата к правому краю окна — так просил владелец. Раньше стояла на
   макетном месте относительно контейнера, right: max(0px, calc(50% - 640px)):
   в макете её правый край выходит за контейнер ровно на 56 px (арт занимает
   x=608…1280 при контейнере 56…1224) — эти 56 и были полем справа.
   От ширины окна положение не зависит: главная целиком масштабируется зумом,
   и полоса вёрстки на любом мониторе от 1200 до 3840 остаётся той же ~1390 px
   (замерено на 1280 и на 1920).

   Но и после этого справа оставалась тёмная полоса, и вот из чего она
   складывалась. 14 px — скроллбар: он рисуется браузером, под него страница
   не заходит вовсе. Ещё 10 px — пустой хвост самого файла: замер по альфе на
   фоне #0B0813 показал, что до правого края картинки содержимого фактически
   нет (меньше 10 % строк). Остальное — не пустота, а сама живопись: там у неё
   плечо в тени, почти чёрное.

   Поэтому арт сдвинут вправо ещё на 48 px и подрезан рамкой-обёрткой.
   Обрезка, а не отрицательный right у самой картинки: без обёртки страница
   получала бы горизонтальную прокрутку (проверено: scrollWidth 1492 против
   окна 1430). overflow:hidden на .bl-hero не годится — арт намеренно свисает
   ниже секции, его бы срезало по низу.

   По вертикали арт начинается на 3 px выше секции (в макете y=77,5 против
   границы шапки 80): картинка обрезана по верхнему краю, и эти три пиксельных
   строки должны уходить под полосу — иначе край её волос читается линией
   в правом верхнем углу. */
.bl-hero__artbox {
    position: absolute;
    z-index: 1;
    top: -3px;
    right: 0;
    width: 624px;                /* 672 − 48: на столько ушёл тёмный хвост */
    height: 732px;
    overflow: hidden;
    pointer-events: none;
}
.bl-hero__art {
    position: absolute;
    top: 0;
    right: -48px;
    width: 672px;
    height: 732px;
    object-fit: contain;
    object-position: top right;
}

.bl-hero__title {
    margin: 0;
    font-weight: 600;
    letter-spacing: -0.01em;
}
/* Строки «Сезон 31.07–07.10 начался…» над заголовком больше нет — владелец
   попросил её убрать. Заголовок, лид и кнопки при этом стоят ровно там же, где
   стояли с ней: низ героя фиксирован (622), и любой сдвиг колонки вниз увёл бы
   кнопки на арт, а вверх — оставил бы пустоту под ними. Поэтому место, которое
   занимала строка, отдано отступам.

   Без плашки скидки заголовок первый в колонке: 177 = прежние 116 над строкой
   сезона + её 19 + 42 от неё до заголовка. С плашкой отступ считается от неё,
   см. .bl-hero__promo ниже.

   Именно padding, а не margin: у .bl-hero__inner нет ни рамки, ни поля сверху,
   и верхний margin первого блочного потомка схлопывается с margin самой секции
   (там 80 под шапку) — вместо 80 + 177 выходило max(80, 177), и заголовок
   подпрыгивал на 80 px вверх. Плашку это не касалось: она inline-flex, у
   строчных элементов margin не схлопывается. */
.bl-hero__title:first-child { padding-top: 177px; }
/* Отрицательные отступы — оптическая подводка к левой линии колонки. Рамка
   строки на линии стоит и так, но у первой литеры есть левый полуапрош, и краска
   начинается правее: «наша забота» кеглем 97 отходила от вертикали на 4,7 px —
   на самом крупном тексте страницы это был единственный заметный разрыв в общем
   левом крае. Полуапрош пропорционален кеглю, поэтому отступ в em.

   Числа сняты с рендера страницы, а не из шрифта: measureText в Chrome отдаёт
   actualBoundingBoxLeft примерно в полтора раза больше настоящего.

   Значение зависит от ПЕРВОЙ БУКВЫ строки. У «П» и «R» полуапрош одинаковый,
   поэтому у первой строки язык не разделён; у «н» он 0,049em, а у «o» из
   английского «our job» — 0,019em, отсюда две записи. Меняется текст заголовка —
   замер надо повторить, иначе строка уедет за линию. */
.bl-hero__title span {
    display: block;
    margin-left: -0.042em;
    font-size: var(--bl-fs-hero-1);
    line-height: 1;
}
.bl-hero__title strong {
    display: block;
    margin-top: 2px;
    font-size: var(--bl-fs-hero-2);
    font-weight: 600;
    line-height: .95;
}
html[lang="ru"] .bl-hero__title strong { margin-left: -0.049em; }
html[lang="en"] .bl-hero__title strong { margin-left: -0.019em; }

/* Подзаголовок в макете набран мелко и светлым начертанием — 12,7 px.
   Это не опечатка, размер снят с матрицы текстового слоя.

   Ширина 348, а не макетные 334: в макете вторая строка занимает ровно 334 px,
   но тот же шрифт в браузере набирает её на 3,5 % шире — при 340 она ломалась
   на третью строку, которой в макете нет. Интерлиньяж 15,5 снят с расстояния
   между строками в PSD (31 пиксель холста), а не выведен из кегля: 1.06
   склеивало строки вдвое теснее макета.

   Цвет: слой подзаголовка лежит в PSD с непрозрачностью 128/255, то есть текст
   там серый, а не белый. */
.bl-hero__lead {
    max-width: 348px;
    margin: 26px 0 0;
    font-size: var(--bl-fs-hero-lead);
    font-weight: 300;
    line-height: 15.5px;
    color: var(--bl-text-dim);
}

.bl-hero__cta {
    display: flex;
    gap: 20px;
    margin-top: 38px;
}
/* В макете кнопки 226×39 и 175×39 при кегле 20. Владелец попросил крупнее,
   поэтому пропорции макета сохранены, а размер поднят на четверть: высота 50,
   кегль 22, ширины 282 и 218. Ниже 768 ширины снимаются — там кнопки тянутся
   по экрану (см. адаптив). */
.bl-hero__cta .bl-btn {
    height: 50px;
    min-width: 218px;
    padding: 0 38px;
    font-size: 22px;
}
.bl-hero__cta .bl-btn--primary { min-width: 282px; }

/* Плашка «−15% на первый заказ» под кнопками героя. Своё место в макете у неё
   не задано — её там нет, — поэтому берётся то, что не ломает раскладку PSD:
   под кнопками, где до низа секции остаётся ~148 px пустоты. Между лидом и
   кнопками её ставить нельзя — сдвинулся бы весь низ героя, у которого высота
   фиксированная (622), и кнопки уехали бы на арт.

   Тон — тот же фиолетовый акцент, что у активной карточки коуча,
   но заливкой в 10 %: рядом стоит крупная фиолетовая кнопка, и вторая сплошная
   плашка спорила бы с ней за внимание. */
/* Плашка стоит ПЕРВОЙ в колонке героя — по просьбе владельца скидка должна
   читаться раньше заголовка. Она условная: скидки может не быть вовсе, и тогда
   верхний отступ колонки держит сам заголовок (.bl-hero__title:first-child). */
.bl-hero__promo {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px 8px 10px;
    border: 1px solid rgba(138, 92, 245, .38);
    border-radius: 999px;
    background: rgba(138, 92, 245, .10);
    font-size: 15px;
    line-height: 1;
}
/* Плашка встала на место убранной строки сезона: до заголовка 42 px — ровно
   тот зазор, что был у той строки. Сверху 149 (прежде 76): у шапки она
   прижималась к полосе меню и читалась приставкой к ней, а не частью текста
   героя. Промежуточный вариант со 106 сверху и 85 до заголовка владельцу
   показался всё ещё высоким. Заголовок стоит на прежнем месте:
   149 + высота плашки 42,5 + 42 = 233,5 от шапки, как было со строкой сезона.

   Влево плашка не вынесена: на общей левой линии стоит её внешняя граница. */
.bl-hero__promo { margin-top: 149px; }
.bl-hero__promo + .bl-hero__title { margin-top: 42px; }

.bl-hero__promo-pct {
    padding: 5px 10px;
    border-radius: 999px;
    background: var(--bl-violet, #8A5CF5);
    color: #120E1C;
    font-weight: 600;
    font-size: 15px;
    line-height: 1;
    white-space: nowrap;
}
.bl-hero__promo-text {
    color: var(--bl-text-dim, rgba(255, 255, 255, .72));
    font-weight: 300;
}
.bl-hero__promo-text b { color: #fff; font-weight: 600; }

/* Неделя повышенной скидки. Обводка, а не заливка: сплошной чип рядом с таким же
   сплошным «−15 %» превратил бы плашку в две кнопки подряд. */
.bl-hero__promo.is-boosted {
    border-color: rgba(138, 92, 245, .75);
    box-shadow: 0 0 26px rgba(138, 92, 245, .22);
}
.bl-hero__promo-hot {
    margin: 0 2px 0 6px;
    padding: 3px 9px;
    border: 1px solid rgba(138, 92, 245, .75);
    border-radius: 999px;
    color: var(--bl-violet, #8A5CF5);
    font-weight: 600;
    font-size: 13px;
    white-space: nowrap;
}

/* Подложка страницы. В макете за секциями «Что мы предлагаем», «Процесс»,
   «Оформление заказа» и отзывами лежат три засвеченные фотографии — интерьер,
   ночной город и стол с сундуком (в PSD это слои группы «Фон» в режиме
   «осветление основы»). Раньше их не было вовсе: фон был ровной темнотой,
   и секции выглядели пустее макета. Режим наложения посчитан питоном
   и запечён в картинку; края сведены в прозрачность, чтобы на широких
   экранах не было видно кромок.

   Элемент лежит внутри «Что мы предлагаем», но тянется на все три секции
   ниже: z-index -1 кладёт его за их содержимое, но выше фона страницы.
   Ширина по вьюпорту, а картинка внутри стоит по центру в натуральную
   величину — так на экране 1200–1280 не появляется горизонтальная прокрутка.
   По бокам, как и у героя, продолжение кромки полосками (см. .bl-hero::before). */
.bl-backdrop {
    position: absolute;
    z-index: -1;
    top: 93px;                    /* макетные 794,5 от верха страницы */
    left: 0;
    right: 0;
    height: 2492px;
    pointer-events: none;
    background:
        image-set(url('../img/design/page-backdrop.webp') 1x,
                  url('../img/design/page-backdrop@2x.webp') 2x) no-repeat 50% 0 / 1280px 2492px,
        url('../img/design/page-backdrop-edge-l.webp?v=2') no-repeat left  0 / 50.5% 2492px,
        url('../img/design/page-backdrop-edge-r.webp?v=2') no-repeat right 0 / 50.5% 2492px;
}

/* ── Что мы предлагаем ───────────────────────────────────────────────────── */
.bl-offers { position: relative; padding-top: 88px; }
.bl-offers__grid {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 52px;
}

.bl-offer {
    /* Перелистывание лицевой стороны на описание: намеренно неспешное,
       чтобы взгляд успевал прочитать карточку, а не ловить вспышку. */
    --bl-offer-flip: .62s;
    --bl-offer-ease: cubic-bezier(.4, 0, .2, 1);
    position: relative;
    height: 602px;
    border-radius: var(--bl-radius-card);
    overflow: hidden;
    text-decoration: none;
    color: var(--bl-text);
    isolation: isolate;
    /* Слова на лицевой стороне заданы в долях ширины карточки (cqw): на планшете
       и телефоне карточка уже макетных 355, и пиксельные кегли снова вылезали
       бы за край. */
    container-type: inline-size;
}
/* Обычное состояние: кадр из игры, крупное слово и персонаж поверх него.
   Кадр в макете лежит не на пустоте: под ним залита лиловая диагональная
   заливка (#875BEF → #52398B), а сам кадр стоит с непрозрачностью 80 % и,
   главное, с поднятым чёрным ползунком «Это слой» (Blend If 25/60) — сквозь
   кадр проходят только его светлые куски, тёмные пропускают заливку.
   Всё это запечено в картинку, здесь просто фон. */
.bl-offer__face {
    position: absolute;
    inset: 0;
    border-radius: inherit;
    overflow: hidden;
    background-image: image-set(url('../img/design/card-art.webp?v=3') 1x,
                                url('../img/design/card-art@2x.webp?v=3') 2x);
    background-size: 1280px 720px;
    background-repeat: no-repeat;
    transition: opacity var(--bl-offer-flip) var(--bl-offer-ease);
}
/* Кегли слов в макете одинаковые (150,83 и 81,78 у «бровки»), трекинг нулевой,
   начертание Black — то же, что у нас. Но чернила нашего шрифта шире макетных
   на 2–5 %: «буст» и «кали» вылезали за карточку, у «буст» срезало «т», а три
   карточки читались набранными вразнобой. Кегль каждого слова подобран так,
   чтобы чернила ложились в карточку от 1 до 354 (у «коу» и «бровки» — своя
   ширина, как в макете, по центру карточки); left подгоняет левый край
   с поправкой на боковой отступ глифа, top — на осадку строки от меньшего
   кегля. Числа сняты измерением рендера, а не подобраны на глаз. */
.bl-offer__word {
    position: absolute;
    font-size: 40.85cqw;          /* 145 px при макетных 355 */
    font-weight: 900;
    line-height: .9;
    letter-spacing: -0.02em;
    white-space: nowrap;
}
.bl-offer__word--small { font-size: 21.55cqw; }   /* 76,5 px */
.bl-offer__char {
    position: absolute;
    pointer-events: none;
}

/* Состояние наведения: карточка заливается фиолетовым и показывает описание.
   Раскладка снята с чтомы.psd — файл специально прислан под это состояние. */
.bl-offer__back {
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: inherit;
    overflow: hidden;
    opacity: 0;
    background: linear-gradient(128deg, rgba(139, 91, 246, .93) 0%, rgba(104, 66, 200, .90) 55%, rgba(85, 52, 170, .93) 100%);
    transition: opacity var(--bl-offer-flip) var(--bl-offer-ease);
}
.bl-offer:hover .bl-offer__back,
.bl-offer:focus-visible .bl-offer__back { opacity: 1; }
.bl-offer:hover .bl-offer__face { opacity: .35; }

.bl-offer__logo { position: absolute; top: 18px; left: 154px; width: 47px; height: 47px; }
.bl-offer__title {
    position: absolute;
    top: 90px;
    left: 0;
    right: 0;
    text-align: center;
    font-size: var(--bl-fs-card-title);
    font-weight: 800;
    line-height: 1;
}
.bl-offer__desc {
    position: absolute;
    top: 156px;
    left: 48px;
    width: 262px;
    text-align: center;
    font-size: var(--bl-fs-card-text);
    font-weight: 300;
    line-height: 24px;
}
.bl-offer__list {
    position: absolute;
    top: 319px;
    left: 0;
    right: 0;
    margin: 0;
    padding: 0;
    list-style: none;
    text-align: center;
}
.bl-offer__list li {
    margin-bottom: 11px;
    font-size: var(--bl-fs-card-text);
    font-weight: 500;
    line-height: 16px;
}
.bl-offer__list li::before {
    content: '';
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-right: 13px;
    border-radius: 50%;
    background: currentColor;
    vertical-align: middle;
}
.bl-offer__price {
    position: absolute;
    top: 423px;
    left: 0;
    right: 0;
    text-align: center;
    font-size: var(--bl-fs-card-price);
    font-weight: 500;
    line-height: 1;
}
.bl-offer__price b { font-weight: 700; }
.bl-offer__cta {
    position: absolute;
    top: 490px;
    left: 52px;
    width: 250px;
    height: 59px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--bl-radius-pill);
    background: #16141F;
    font-size: 35px;
    font-weight: 600;
    letter-spacing: .02em;
    transition: background var(--bl-offer-flip) var(--bl-offer-ease);
}
.bl-offer:hover .bl-offer__cta { background: #110d19; }

/* Позиции слов и персонажей — у каждой карточки свои, как нарисовано. */
.bl-offer--boost  .bl-offer__face { background-position: -56px -60px; }
.bl-offer--calib  .bl-offer__face { background-position: -462px -60px; }
.bl-offer--coach  .bl-offer__face { background-position: -870px -60px; }

.bl-offer--boost .bl-offer__word  { top: 22.3px; left: -1.35cqw; }
/* Высота 472, а не 470: при 470 персонаж кончался на 600, и по низу карточки
   оставались два пикселя лиловой подложки — их и было видно светлой полоской.
   В макете фигура доходит до самого низа. */
.bl-offer--boost .bl-offer__char  { top: 130px; left: 36px; width: 360px; height: 472px; }

.bl-offer--calib .bl-offer__word  { top: 391.6px; left: -1.58cqw; font-size: 40.28cqw; }
/* Кегль повторён здесь намеренно: .bl-offer--calib .bl-offer__word весомее
   одиночного .bl-offer__word--small и иначе перебивает его. */
.bl-offer--calib .bl-offer__word--small { top: 490.5px; left: 8.23cqw; font-size: 21.55cqw; }
/* Мышь висит вверх ногами — так просил владелец. Крутим стилем, а не самим
   файлом: арт лежит в двух плотностях, и переворачивать пришлось бы оба.
   Поворот идёт вокруг центра картинки, поэтому рамка остаётся прежней: те же
   2 px срезаются сверху (только теперь это ствол, а не кончики крыльев),
   а по горизонтали вылет почти симметричен — 52 слева, 51 справа. */
.bl-offer--calib .bl-offer__char  { top: -2px; left: -52px; width: 458px; height: 398px; transform: rotate(180deg); }

.bl-offer--coach .bl-offer__word  { top: 23.3px; left: 9.92cqw; font-size: 40.70cqw; }
.bl-offer--coach .bl-offer__word--second { top: 116.7px; left: -1.10cqw; font-size: 41.55cqw; }
.bl-offer--coach .bl-offer__char  { top: 198px; left: -28px; width: 370px; height: 495px; }

/* По-английски слова другой длины: «boost» и «ching» на русских кеглях
   вылезали за карточку так же, как раньше «буст». Макета для английского нет,
   поэтому правило проще русского: один кегль на все крупные слова (по самому
   широкому — «boost» ровно в ширину карточки) и выключка по центру, а не
   заподлицо — иначе разница в длине слов читалась бы рванью справа. */
html[lang="en"] .bl-offer__word {
    left: 0;
    right: 0;
    font-size: 33.66cqw;          /* 119,5 px при макетных 355 */
    text-align: center;
}
html[lang="en"] .bl-offer--calib .bl-offer__word--small { font-size: 18.03cqw; }
html[lang="en"] .bl-offer--coach .bl-offer__word { font-size: 32.96cqw; }
html[lang="en"] .bl-offer--coach .bl-offer__word--second { font-size: 33.66cqw; }

/* ── Процесс ─────────────────────────────────────────────────────────────
   Четыре карточки 268×368 в шахматном порядке: нечётные выше, чётные ниже
   на 143 px. Номера — кружки 101 px, вынесенные за карточку.

   Подложка карточек — одна картинка на всю сетку 1168×512, каждая карточка
   показывает свой кусок. Это ровно то, что нарисовано в макете: в PSD
   подложки четырёх карточек лежат на общем холсте, две из них со сдвигом
   на те же 143 px, что и сама карточка.

   Карточки лиловые: под фото залито #563B96, само фото приглушено диапазоном
   наложения (Blend If 39/73 по своему слою и 0/110 по подложке), а между ними
   лежит белое слово «boostlock» — из-под фото видны его куски. Всё запечено
   в картинку. Своей заливки у элемента нет: у спрайта собственные скруглённые
   края с прозрачностью, и цвет под ними давал бы тёмный ободок.

   Пересобрать спрайт, сведя группу «Процесс» в PSD саму по себе, нельзя:
   слои карточки блендятся с артом страницы под секцией, и без подложки
   фотошоп даёт почти чёрные карточки вместо лиловых (проверено, откачено). */
.bl-process { position: relative; padding-top: 69px; }
.bl-process__grid {
    position: relative;
    z-index: 1;
    height: 512px;
}
.bl-step {
    position: absolute;
    top: 0;
    width: 268px;
    height: 368px;
    padding: 40px 24px;
    border-radius: 26px;
    overflow: hidden;
    background: image-set(url('../img/design/step-art.webp?v=3') 1x,
                          url('../img/design/step-art@2x.webp?v=3') 2x) no-repeat;
    background-size: 1168px 512px;
    text-align: center;
}
.bl-step:nth-child(1) { left: 0;     background-position: 0 0; }
.bl-step:nth-child(2) { left: 300px; top: 143px; background-position: -300px -143px; }
.bl-step:nth-child(3) { left: 600px; background-position: -600px 0; }
.bl-step:nth-child(4) { left: 900px; top: 143px; background-position: -900px -143px; }

/* Заголовок занимает фиксированные две строки и центрируется в них: в макете
   у «Оплатите» и «Готово» строка одна, у остальных две, а описание под ними
   в обоих случаях начинается на одной и той же высоте. */
.bl-step__title {
    display: flex;
    flex-direction: column;
    justify-content: center;
    height: 54px;
    margin: 0;
    font-size: var(--bl-fs-step-title);
    font-weight: 700;
    line-height: 27px;
}
.bl-step__text {
    margin: 35px 0 0;
    font-size: var(--bl-fs-step-text);
    font-weight: 300;
    line-height: 22.5px;
}
.bl-step__text b { font-weight: 500; }

.bl-step__num {
    position: absolute;
    z-index: 2;
    width: 101px;
    height: 101px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: #fff;
    color: var(--bl-violet);
    font-size: var(--bl-fs-step-num);
    font-weight: 900;
    line-height: 1;
}
.bl-step__num:nth-of-type(1) { left: 84px;   top: 411px; }
.bl-step__num:nth-of-type(2) { left: 384px;  top: 0; }
.bl-step__num:nth-of-type(3) { left: 684px;  top: 411px; }
.bl-step__num:nth-of-type(4) { left: 984px;  top: 0; }

/* ── Оформление заказа ───────────────────────────────────────────────────── */
.bl-order { position: relative; padding-top: 83px; }
/* Фон карточки — картинка из макета, а не градиент с фотографией поверх.
   Ночной кадр лежит в PSD режимом «осветление основы» (COLOR_DODGE) с поднятым
   чёрным ползунком «Наложить, если»: сквозь него проходят только средние тона,
   тёмные пропускают лиловую заливку. Ни overlay, ни color-dodge в CSS этого
   не повторяют — цвет уезжал на 30–80 единиц из 255. Наложение посчитано
   питоном и запечено в файл (rebuild2.py в скрэтчпаде), расхождение с плоской
   копией фотошопа — меньше единицы.
   Светлой обводки по кромке, которая есть в макете (слои Layer 8 и его копия:
   непрозрачны 0,66 % пикселей, и все по краю), в картинке нет — владелец
   попросил убрать её вместе с обводкой кнопок. Тон карточки на 10 % темнее
   и на 12 % ближе к серому, чем в макете, — тоже по его просьбе; приглушение
   запечено в файл, а не сделано фильтром, иначе оно задело бы текст и кота.
   Заливка под картинкой нужна только для мобильной раскладки, где карточка
   вырастает выше 602 px. */
.bl-order__card {
    position: relative;
    z-index: 1;
    height: 602px;
    border-radius: var(--bl-radius-card);
    overflow: hidden;
    background: image-set(url('../img/design/order-card.webp?v=3') 1x,
                          url('../img/design/order-card@2x.webp?v=3') 2x) no-repeat 50% 0
                #3F2B70;
    background-size: 1168px 602px;
}
.bl-order__cat {
    position: absolute;
    right: 46px;
    bottom: -8px;
    width: 498px;
    height: 610px;
    pointer-events: none;
}
/* В макете обе строки ровно одной ширины (649 px холста): дизайнер подобрал
   кегли 84 и 88 так, чтобы «Выбери» и «услугу» встали заподлицо. У нашего
   начертания метрики другие — на тех же кеглях «Выбери» выходит на 39 px шире,
   и блок читался рваным. Кегли подобраны заново (82/90), а остаток в 3 %
   добирается scaleX: он незаметен, зато края сходятся точно.
   Каждая строка — блок по своему тексту (width: fit-content) с автополями:
   тогда scaleX крутится вокруг её собственного центра и обе строки остаются
   на оси блока. Ширина блока с запасом, чтобы строки в него влезали до
   масштабирования; центр — над кнопками: 101 + 380/2 = 291 = 58 + 466/2. */
.bl-order__lead {
    position: absolute;
    top: 46px;
    left: 101px;
    width: 380px;
    font-size: 82px;
    font-weight: 900;
    line-height: 61px;
    text-align: center;
    letter-spacing: -0.01em;
}
.bl-order__lead span:last-child { font-size: 90px; }
.bl-order__lead span {
    display: block;
    width: fit-content;
    margin-inline: auto;
    white-space: nowrap;
    transform-origin: 50% 50%;
}
.bl-order__lead span:first-child { transform: scaleX(.968); }
.bl-order__lead span:last-child  { transform: scaleX(1.036); }
/* По-английски «Choose a service» длиннее русского «Выбери услугу»: на макетном
   кегле строка переносилась третьей и наезжала на кнопки. Свои кегли и своя
   ширина блока, выравнивание — то же. */
html[lang="en"] .bl-order__lead {
    left: 141px;
    width: 300px;
    font-size: 66px;
    line-height: 52px;
}
html[lang="en"] .bl-order__lead span:last-child { font-size: 58px; }
html[lang="en"] .bl-order__lead span:first-child { transform: scaleX(1.022); }
html[lang="en"] .bl-order__lead span:last-child  { transform: scaleX(.977); }
.bl-order__buttons {
    position: absolute;
    top: 201px;
    left: 58px;
    width: 466px;
    display: grid;
    gap: 24px;
}
/* Пилюля один в один с «финал.psd».

   Главное, что было упущено раньше: кнопка в макете не залита цветом.
   Это полупрозрачная чёрная вуаль поверх карточки — сквозь неё видно и узор
   карточки, и полутоновые точки, и звёздочку у правого торца. Проверено
   числом: карточка собрана заново без кнопок, и внутри кнопки флэттен
   совпадает с моделью F = (1-a)*C, где C — карточка под ней. По каналам
   альфа сходится (на 92 % длины 0,628 / 0,614 / 0,636 — то есть вуаль
   нейтрально-чёрная, не цветная), а разброс узора внутри кнопки составляет
   38 % от разброса снаружи — ровно столько, сколько пропускает вуаль.

   Профиль альфы по длине (замер через каждые 60 px, доля ширины -> альфа):
   9 %:0,03  15 %:0,06  21 %:0,09  34 %:0,14  41 %:0,15  47 %:0,24  54 %:0,42
   60 %:0,45  67 %:0,45  73 %:0,54  79 %:0,53  86 %:0,58  92 %:0,63.
   Ниже эти же точки пересчитаны в координату градиента под 125,7°: у линии
   градиента для 466x99 длина 436 px, поэтому левый край кнопки приходится
   на 6,6 % линии, правый — на 93,4 %.

   Отсюда и «кнопка делится на две части»: в файле она и есть такая —
   слева почти прозрачная, справа затемняет карточку вдвое. Раньше мы клали
   вместо неё непрозрачную заливку, и правая половина выходила глухой,
   без узора.

   Поверх — белая обводка макета (слои «Layer 9» и «Layer 9 copy», два
   одинаковых слоя режимом «перекрытие»). Профиль снят со слоя: толщина 3 px
   при 2x = 1,5 CSS, альфа держится на единице до 45 % ширины и сходит к нулю
   у правого торца (0,91 на 54 %, 0,76 на 64 %, 0,56 на 73 %, 0,32 на 82 %,
   0,12 на 91 %). В CSS стоят удвоенные значения 1-(1-a)^2 — так одна рамка
   даёт то же, что в макете два слоя. Режим «перекрытие» не нужен: белый
   в нём всегда даёт 255, то есть в точности обычный белый с той же альфой.
   Цвет линии не чистый белый, а rgb(200,200,200): в файле она тонкая и ни
   один пиксель не набирает полного покрытия — гребень по замеру 2x-рендера
   держится на 190–215 из 255.

   Вуаль умножает то, что под ней, поэтому приглушение карточки
   ((c*0.88 + серый*0.12) * 0.90, просьба владельца от 2026-08-19) кнопка
   наследует сама — отдельно подгонять её цвета больше не нужно. */
.bl-order__btn {
    position: relative;
    height: 99px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: var(--bl-radius-pill);
    background: linear-gradient(125.7deg,
        rgba(0, 0, 0, 0)    0%,
        rgba(0, 0, 0, .03)  14%,
        rgba(0, 0, 0, .06)  20%,
        rgba(0, 0, 0, .09)  25%,
        rgba(0, 0, 0, .14)  36%,
        rgba(0, 0, 0, .15)  42%,
        rgba(0, 0, 0, .24)  47%,
        rgba(0, 0, 0, .42)  53%,
        rgba(0, 0, 0, .45)  59%,
        rgba(0, 0, 0, .45)  65%,
        rgba(0, 0, 0, .54)  70%,
        rgba(0, 0, 0, .53)  75%,
        rgba(0, 0, 0, .58)  81%,
        rgba(0, 0, 0, .63)  86%,
        rgba(0, 0, 0, .69) 100%);
    color: var(--bl-text);
    font-family: var(--bl-font);
    font-size: var(--bl-fs-service);
    font-weight: 600;
    letter-spacing: .02em;
    cursor: pointer;
    transition: filter .22s ease, transform .22s cubic-bezier(.2, .7, .3, 1),
                box-shadow .22s ease;
}
/* Обводка макета: рамка в 1,5 px, яркая слева и сходящая на нет справа.
   Рисуется градиентом по всей кнопке и обрезается маской до одной рамки:
   две одинаковые маски, у внутренней бокс content-box, XOR оставляет только
   поля — это и есть рамка со скруглением, повторяющим кнопку. */
.bl-order__btn::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1.5px;
    background: linear-gradient(90deg,
        rgba(200, 200, 200, 1)   0%,
        rgba(200, 200, 200, 1)   45%,
        rgba(200, 200, 200, .99) 54%,
        rgba(200, 200, 200, .94) 64%,
        rgba(200, 200, 200, .81) 73%,
        rgba(200, 200, 200, .54) 82%,
        rgba(200, 200, 200, .23) 91%,
        rgba(200, 200, 200, 0)   100%);
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask-composite: exclude;
    pointer-events: none;
}
/* Наведение. Кнопка — полупрозрачная вуаль поверх узора карточки, поэтому
   ярче всего читается не смена заливки, а то, что вуаль будто редеет:
   brightness поднимает и её, и обводку, и надпись разом. Плюс подъём на 2 px
   и тень под кнопкой: карточка сама лиловая, поэтому фиолетовое свечение
   на ней тонет, а тёмная тень отрывает кнопку от фона.
   Блик (::after) проходит по кнопке один раз слева направо. Он размером
   в 2,6 ширины кнопки, поэтому виден только его гребень; в покое стоит
   за левым краем и не рисуется вовсе (opacity 0). */
.bl-order__btn::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(105deg,
        transparent 40%,
        rgba(255, 255, 255, .24) 50%,
        transparent 60%);
    background-size: 260% 100%;
    background-position: 100% 0;
    background-repeat: no-repeat;
    opacity: 0;
    pointer-events: none;
}
.bl-order__btn:hover {
    transform: translateY(-3px);
    filter: brightness(1.2);
    box-shadow: 0 16px 30px -14px rgba(0, 0, 0, .6);
}
.bl-order__btn:hover::after {
    opacity: 1;
    animation: bl-btn-shine .85s cubic-bezier(.25, .6, .3, 1);
}
.bl-order__btn:active {
    transform: translateY(0);
    filter: brightness(1.08);
    box-shadow: 0 4px 10px -8px rgba(0, 0, 0, .5);
}
@keyframes bl-btn-shine {
    from { background-position: 100% 0; }
    to   { background-position: 0 0; }
}
/* Кому анимации мешают — остаётся только подсветка. */
@media (prefers-reduced-motion: reduce) {
    .bl-order__btn { transition: filter .18s ease; }
    .bl-order__btn:hover { transform: none; }
    .bl-order__btn:hover::after { animation: none; opacity: 0; }
}

/* Пока выбрана услуга, карточка выбора уступает место окну заказа —
   заголовок секции при этом остаётся на месте, как в макете. */
.bl-order.is-picked .bl-order__card { display: none; }
.bl-order.is-picked { padding-bottom: 0; }


/* ── Окно оформления заказа ──────────────────────────────────────────────
   Раскладка из «оформление заказа.psd»: та же карточка, что у входа
   и регистрации, и уменьшена она тем же коэффициентом — 476×601 вместо
   макетных 635×801 (почему так, написано в шапке bl-auth.css).
   Разметка модалки прежняя — меняется только оформление, порядок блоков
   задан flex-order.
   Селекторы с .pay-modal впереди: базовые стили лежат в <style> внизу страницы
   и по порядку идут позже этого файла. */
.pay-modal .pay-modal-backdrop { background: rgba(9, 6, 16, .74); backdrop-filter: blur(6px); }
.pay-modal .pay-modal-card {
    display: flex;
    flex-direction: column;
    width: 476px;
    max-width: calc(100vw - 32px);
    min-height: 601px;
    padding: 33px 38px 37px;
    border-radius: 26px;
    border: 1px solid rgba(146, 116, 232, .5);
    background: linear-gradient(40deg, #271A46 0%, #302056 55%, #432C76 100%);
    box-shadow: 0 40px 90px rgba(0, 0, 0, .6);
    overflow: hidden;
    text-align: center;
    font-family: var(--bl-font);
}
.pay-modal .pay-modal-card::before {
    content: '';
    position: absolute;
    inset: 0;
    background: url('../img/design/auth-art.webp') no-repeat 50% -45px;
    background-size: 734px auto;
    opacity: .16;
    pointer-events: none;
}
.pay-modal .pay-modal-card > * { position: relative; }

.pay-modal .pay-modal-x {
    position: absolute;
    top: 19px;
    right: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--bl-red);
    color: #fff;
    cursor: pointer;
}
.pay-modal .pay-modal-x svg { width: 9px; height: 9px; }
.pay-modal .pay-modal-brand {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-bottom: 3px;
    font-size: 14px;
    font-weight: 800;
}
.pay-modal .pay-modal-brand img { width: 21px; height: 21px; }
.pay-modal .pay-modal-title {
    margin: 0 0 22px;
    font-size: 27.8px;
    font-weight: 500;
    color: var(--bl-text);
}
/* Пояснение в макете не нарисовано — всё сказано подписями блоков. */
.pay-modal .pay-modal-sub { display: none; }

/* Порядок: промокод → цена → оферта → способы оплаты. */
.pay-modal .pay-promo { order: 1; margin: 0 0 18px; }
.pay-modal .pay-summary { order: 2; }
.pay-modal .pay-offer { order: 3; }
.pay-modal .pay-modal-providers-label { order: 4; }
.pay-modal .pay-modal-opt { order: 5; }
.pay-modal .pay-modal-close { order: 6; }

.pay-modal .pay-promo-label {
    margin-bottom: 6px;
    font-size: 13.9px;
    font-weight: 500;
    line-height: 1.1;
    color: var(--bl-text);
}
.pay-modal .pay-promo-row { position: relative; display: block; }
.pay-modal .pay-promo-input {
    width: 100%;
    height: 41px;
    padding: 0 56px 0 19px;
    border: 1px solid transparent;
    border-radius: 14px;
    background: #151324;
    color: var(--bl-text);
    font-family: inherit;
    font-size: 13.9px;
    font-weight: 300;
    text-align: left;
}
.pay-modal .pay-promo-input:focus { border-color: var(--bl-violet); }
/* Кнопка в макете — зелёный кружок с галочкой; текстовую подпись прячем,
   но оставляем в разметке для скринридеров. */
.pay-modal .pay-promo-btn {
    position: absolute;
    top: 50%;
    right: 12px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--bl-green);
    color: #fff;
}
.pay-modal .pay-promo-btn:hover { filter: brightness(1.1); }
.pay-modal .pay-promo-btn-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}
.pay-modal .pay-promo-result { margin-top: 8px; font-size: 11.5px; text-align: left; }

/* Цена и скидки — тёмная плашка; строка «К оплате» в макете уже вне её,
   прямо на карточке. Итог JS всегда рисует последним, поэтому плашку
   набирают все строки, кроме него. */
.pay-modal .pay-summary {
    margin: 0 0 20px;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    font-size: 13.9px;
    text-align: left;
}
.pay-modal .pay-sum-row {
    padding: 3px 25px;
    background: #151324;
    color: var(--bl-text);
    font-weight: 500;
}
.pay-modal .pay-sum-row:first-child { padding-top: 12px; border-radius: 14px 14px 0 0; }
.pay-modal .pay-sum-row:not(.pay-sum-total):nth-last-child(2) { padding-bottom: 12px; border-radius: 0 0 14px 14px; }
.pay-modal .pay-sum-row.pay-sum-disc { color: var(--bl-green); }
.pay-modal .pay-sum-row.pay-sum-total {
    margin-top: 16px;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    font-size: 27.8px;
    font-weight: 500;
}
.pay-modal .pay-sum-total .pay-new { color: var(--bl-green); font-weight: 900; }
.pay-modal .pay-old { font-size: 13.9px; }

/* Оферта: текст слева, квадратный чекбокс справа — как нарисовано. */
.pay-modal .pay-offer {
    align-items: center;
    justify-content: center;
    gap: 13px;
    margin: 0 0 26px;
    font-size: 13.9px;
    font-weight: 300;
    line-height: 1.35;
    color: var(--bl-text);
    text-align: left;
}
.pay-modal .pay-offer-text { flex: 0 1 308px; }
.pay-modal .pay-offer input {
    order: 1;
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    margin: 0;
    border-radius: 6px;
    accent-color: var(--bl-violet);
}
.pay-modal .pay-offer a { color: var(--bl-text); text-decoration: underline; }

.pay-modal .pay-modal-providers-label {
    margin: 0 0 11px;
    font-size: 13.9px;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--bl-text);
}

/* Строка способа оплаты: слева название и описание, справа «Оплатить». */
.pay-modal .pay-modal-opt {
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 55px;
    margin-bottom: 18px;
    padding: 9px 24px 9px 19px;
    border: 1px solid transparent;
    border-radius: 14px;
    background: #151324;
    text-align: left;
}
.pay-modal .pay-modal-opt:hover { border-color: rgba(146, 116, 232, .6); background: #1c1629; }
.pay-modal .pay-modal-opt-texts { flex: 1 1 auto; min-width: 0; }
.pay-modal .pay-modal-opt-row { display: flex; align-items: center; gap: 8px; }
.pay-modal .pay-modal-opt-title { font-size: 13.9px; font-weight: 700; }
.pay-modal .pay-modal-opt-badge {
    background: var(--bl-green);
    color: #0B0813;
    font-size: 10px;
}
/* Сноска про возврат в макете набрана совсем мелко (≈8 px). Держим 10:
   ниже строка перестаёт читаться, а смысла в ней ровно на прочтение. */
.pay-modal .pay-modal-opt-desc { margin-top: 3px; font-size: 10px; font-weight: 300; color: var(--bl-text-dim); }
.pay-modal .pay-modal-opt-go {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 126px;
    height: 32px;
    border-radius: 999px;
    background: var(--bl-grad-primary);
    color: #fff;
    font-size: 16.5px;
    font-weight: 600;
}
/* Крестик в углу закрывает окно — текстовая «Отмена» в макете не нужна. */
.pay-modal .pay-modal-close { display: none; }

/* 660, а не 700: ровно на этой ширине базовые стили модалки внизу страницы
   переводят её в шторку (align-items: flex-end). При разных порогах в промежутке
   получалась карточка со скруглением только сверху, висящая по центру экрана. */
@media (max-width: 660px) {
    .pay-modal .pay-modal-card {
        width: 100%;
        max-width: 100%;
        min-height: 0;
        padding: 28px 18px max(22px, env(safe-area-inset-bottom));
        border-radius: 24px 24px 0 0;
        /* Шторка ограничена 92vh. Без прокрутки всё, что не влезло
           (длинный список скидок, третий провайдер), просто обрезалось бы:
           overflow:hidden карточка получает из десктопного правила. */
        overflow-y: auto;
        overscroll-behavior: contain;
    }
    .pay-modal .pay-modal-title { margin-bottom: 20px; font-size: 24px; }
    .pay-modal .pay-promo-label,
    .pay-modal .pay-summary,
    .pay-modal .pay-offer,
    .pay-modal .pay-modal-providers-label,
    .pay-modal .pay-modal-opt-title { font-size: 15px; }
    .pay-modal .pay-promo-input { height: 48px; font-size: 15px; }
    .pay-modal .pay-sum-row.pay-sum-total { font-size: 24px; }
    .pay-modal .pay-modal-opt { flex-wrap: wrap; padding: 14px 16px; }
    /* Десктопные 10 px сноски на телефоне не читаются вовсе. */
    .pay-modal .pay-modal-opt-desc { font-size: 12.5px; }
    .pay-modal .pay-modal-opt-badge { font-size: 11px; }
    .pay-modal .pay-modal-opt-go { width: 100%; height: 40px; font-size: 17px; }
    .pay-modal .pay-modal-x { top: 14px; right: 14px; width: 30px; height: 30px; }
}


/* ── Отзывы ──────────────────────────────────────────────────────────────── */
/* Отступ до подвала — макетный: в финал.psd между низом карточек (3410) и
   верхом подвала (3672) 262 px пустоты, а у нас было 96 — подвал упирался
   в отзывы, и переход между «частями» читался обрывом. Заодно страница стала
   ровно макетной высоты, и фоновый градиент body раскладывается как в макете. */
.bl-reviews { position: relative; padding: 83px 0 259px; }
.bl-reviews__grid {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 48px;
}
.bl-review {
    position: relative;
    height: 176px;
    padding: 22px 33px;
    border-radius: 22px;
    background: linear-gradient(115deg, #8B5BF6 0%, #7A4BE0 55%, #6A3DCB 100%);
}
.bl-review::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: url('../img/design/review-bg.webp') no-repeat 100% 0;
    background-size: 345px 303px;
    opacity: .5;
    mix-blend-mode: soft-light;
}
.bl-review__stars { display: flex; gap: 6px; }
.bl-review__stars img { width: 20px; height: 20px; }
.bl-review__text {
    margin: 27px 0 0;
    font-size: var(--bl-fs-review);
    font-weight: 400;
    line-height: 19.3px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
/* Подпись «что заказывали» — под звёздами, в зазоре, который и так был пустым.
   Ниже её ставить некуда: у карточки фиксированная высота 176 из макета, текст
   занимает две строки, а автор прибит к нижнему краю — свободного места между
   ними нет. Поэтому строка встаёт в отступ над текстом, а сам текст в этом
   случае поджимается соседним селектором ниже.

   Одна строка с многоточием: «Групповой буст: Ritualist IV → Phantom II» в узкой
   колонке не помещается, а перенос съел бы строку текста отзыва. */
.bl-review__order {
    margin-top: 12px;
    font-size: 12px;
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: .01em;
    color: rgba(255, 255, 255, .78);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.bl-review__order + .bl-review__text { margin-top: 8px; }

.bl-review__author {
    position: absolute;
    left: 32px;
    bottom: 21px;
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 15px;
    font-weight: 300;
}
/* Кружок с инициалами автора. Раньше был пустым белым пятном, а рядом стояло
   «М***»; теперь буквы переехали в кружок, а имя показывается целиком. Две
   буквы («МД») в 37 px помещаются при кегле 15 — на большем «МД» упиралось
   в края. */
.bl-review__avatar {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 37px;
    height: 36px;
    border-radius: 50%;
    background: #fff;
    color: #4A3187;
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
    letter-spacing: .02em;
}
/* Длинный ник не должен выталкивать паучка из угла карточки: подпись автора
   прибита к левому нижнему углу, справа от неё сидит маскот. */
.bl-review__name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 178px;
}
a.bl-review__author { text-decoration: none; color: inherit; }
a.bl-review__author:hover { text-decoration: underline; }
/* Свободное место в ряду: приглашение вместо карточки — звёзд у него нет,
   поэтому текст встаёт туда же, где он стоит в настоящем отзыве. */
.bl-review--empty { background: linear-gradient(115deg, #6E51B4 0%, #634AA4 55%, #573F92 100%); }
.bl-review--empty .bl-review__text { margin-top: 47px; opacity: .85; }
.bl-reviews__all {
    display: inline-block;
    margin-top: 34px;
    color: var(--bl-text);
    font-size: 17px;
    font-weight: 300;
    text-decoration: underline;
}
/* Паучок сидит в правом нижнем углу и слегка выходит за карточку — как в макете. */
.bl-review__mascot {
    position: absolute;
    right: -20px;
    bottom: -24px;
    width: 69px;
    height: 85px;
    pointer-events: none;
}

/* ── FAQ ─────────────────────────────────────────────────────────────────
   Идёт последней секцией. Своего верхнего отступа не имеет: у отзывов по
   макету 259 px нижнего поля, и второй отступ поверх него оторвал бы FAQ
   от страницы.

   Аккордеон на <details>/<summary>: строки-вопросы в спокойной тёмной
   карточке, раскрытая подсвечивается фиолетовым. Насыщенную заливку, как
   у карточек отзывов, здесь не берём — под ней девять строк подряд читаются
   как стена, а это самый длинный текст на странице. */
/* Отзывы по макету заканчиваются 259 px пустоты — там кончалась страница.
   Теперь за ними идёт FAQ, и весь этот зазор читается как обрыв: подтягиваем
   секцию вверх, оставляя между блоками обычный для страницы воздух. На телефоне
   у отзывов поле и так урезано до 96 — там подтягивать нечего (см. адаптив). */
.bl-faq { position: relative; margin-top: -140px; padding: 0 0 120px; }
.bl-faq .bl-section-title { margin-bottom: 44px; }
.bl-faq__list { display: flex; flex-direction: column; gap: 14px; }
.bl-faq__item {
    border-radius: 22px;
    border: 1px solid var(--bl-hairline);
    background: rgba(255, 255, 255, .04);
    transition: border-color .18s ease, background .18s ease;
}
.bl-faq__item:hover { border-color: rgba(190, 168, 255, .40); }
.bl-faq__item[open] {
    border-color: rgba(138, 92, 245, .55);
    background: rgba(138, 92, 245, .10);
}
/* Нативный треугольник убираем (в Safari он висит на ::-webkit-details-marker,
   в остальных — на list-style), вместо него свой «+». */
.bl-faq__q {
    list-style: none;
    display: flex;
    align-items: center;
    gap: 20px;
    padding: 22px 28px;
    cursor: pointer;
}
.bl-faq__q::-webkit-details-marker { display: none; }
/* Рамку фокуса рисуем ВНУТРЬ строки (offset отрицательный): снаружи она у
   раскрытого вопроса ложилась на первую строку ответа. Видно её при переходе
   по ссылке-якорю и с клавиатуры. */
.bl-faq__q:focus-visible { outline: 2px solid var(--bl-violet); outline-offset: -2px; border-radius: 22px; }
.bl-faq__qtext { flex: 1 1 auto; font-size: 20px; font-weight: 500; line-height: 1.3; }
/* «+» из двух полосок: на раскрытии вертикальная уезжает и гаснет, остаётся «−».
   Символом это не набрано, потому что «+» и «−» в шрифте разной ширины и
   значок дёргался бы при каждом клике. */
.bl-faq__sign { position: relative; flex: 0 0 22px; width: 22px; height: 22px; }
.bl-faq__sign::before,
.bl-faq__sign::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: 14px;
    height: 2px;
    border-radius: 2px;
    background: var(--bl-violet);
    transform: translate(-50%, -50%);
    transition: transform .18s ease, opacity .18s ease;
}
.bl-faq__sign::after { transform: translate(-50%, -50%) rotate(90deg); }
.bl-faq__item[open] .bl-faq__sign::after { transform: translate(-50%, -50%) rotate(0deg); opacity: 0; }
/* Ответы светлее обычного приглушённого текста (--bl-text-dim, 62%): это самый
   длинный текст на странице, и на 62% девять абзацев подряд читаются тяжело. */
.bl-faq__a {
    margin: 0;
    padding: 0 70px 24px 28px;
    font-size: 17px;
    font-weight: 300;
    line-height: 1.6;
    color: rgba(255, 255, 255, .74);
}
.bl-faq__foot { margin-top: 30px; font-size: 17px; font-weight: 300; color: var(--bl-text-dim); }
.bl-faq__foot a { color: var(--bl-text); text-decoration: underline; }
.bl-faq__foot a:hover { color: var(--bl-violet); }

/* ── Адаптив ─────────────────────────────────────────────────────────────
   Ниже 1280 макета нет: раскладываем в поток, как это сделано сейчас. */
@media (max-width: 1199.98px) {
    /* Ниже 1200 раскладка перестаёт быть макетной: секции едут по высоте,
       и подложка встала бы не на свои места. */
    .bl-backdrop { display: none; }
    .bl-hero { height: auto; padding: 8px 0 48px; }
    /* Ниже 1200 арт Виндж не показываем совсем — по просьбе владельца
       (2026-08-19: «для телефона можешь убирать женщину, для айпадов тоже»).
       В потоке она занимала весь первый экран телефона, а текст уезжал
       за сгиб; никакой уменьшенной копии вместо неё не нужно — дым и гербы
       на подложке первый экран держат сами. */
    .bl-hero__artbox { display: none; }
    /* Подложку не растягиваем: гербы должны остаться того же размера, что
       и на десктопе. Секция здесь выше картинки — низ просто уходит в фон,
       по краям она и так в него сходит. */
    .bl-hero::before { height: 100%; background-size: 1320px auto, 50.5% 100%, 50.5% 100%; }
    .bl-offers__grid { gap: 28px; }
    /* Высота остаётся макетной: при 540 у «калибровки» нижние слова, посаженные
       по макетной сетке, срезало нижним краем карточки. */
    /* Ряды разведены на 175: между карточками теперь живёт номер (101 + 42
       зазора, как в макете), а не пустота. */
    .bl-process__grid { height: auto; display: grid; grid-template-columns: repeat(2, 268px); justify-content: center; gap: 175px 40px; margin-bottom: 110px; }
    .bl-step, .bl-step:nth-child(n) { position: relative; left: auto; top: auto; }
    /* Номера — не абсолют по сетке: так все четыре вставали в одну точку
       и виднелся только последний. Кладём каждый в клетку своей карточки
       (карточкам клетки тоже назначаем явно, иначе автопоток обойдёт занятые
       и уедет на третий ряд) и опускаем под её низ — как у нечётных карточек
       в макете. */
    .bl-step:nth-child(1), .bl-step__num:nth-of-type(1) { grid-area: 1 / 1; }
    .bl-step:nth-child(2), .bl-step__num:nth-of-type(2) { grid-area: 1 / 2; }
    .bl-step:nth-child(3), .bl-step__num:nth-of-type(3) { grid-area: 2 / 1; }
    .bl-step:nth-child(4), .bl-step__num:nth-of-type(4) { grid-area: 2 / 2; }
    .bl-step__num, .bl-step__num:nth-of-type(n) {
        position: relative;
        left: auto;
        top: auto;
        justify-self: center;
        align-self: end;
        margin-bottom: -143px;      /* 101 кружок + 42 зазора — как в макете */
    }
    /* Карточка становится выше макетных 602 — кадр тянем по ширине,
       низ добирает заливка. */
    .bl-order__card { height: auto; padding: 46px 32px 46px; background-size: cover; }
    .bl-order__lead, .bl-order__buttons { position: relative; top: auto; left: auto; width: auto; }
    .bl-order__lead { margin-bottom: 34px; text-align: left; }
    .bl-order__buttons { max-width: 466px; }
    .bl-order__cat { right: 0; width: 380px; height: auto; opacity: .9; }
    .bl-reviews__grid { gap: 28px; }
}

/* Планшет. В одну колонку карточки услуг сваливались уже с 900, и лента
   из трёх штук по 602 растягивала страницу на полтора экрана впустую —
   при 768 рядом свободно встают две. Ширина 354 из макета сохраняется
   как потолок, колонка при необходимости чуть уже. */
@media (max-width: 900px) {
    .bl-offers__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; justify-items: center; }
    .bl-offer { width: 100%; max-width: 354px; }
    .bl-reviews__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .bl-order__cat { display: none; }
}

@media (max-width: 660px) {
    .bl-offers__grid, .bl-reviews__grid { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
    /* Карточка отзыва во всю ширину экрана: вылет паучка вправо давал
       горизонтальную прокрутку на телефоне — убираем его внутрь. */
    .bl-review__mascot { right: 2px; bottom: -14px; }
}

@media (max-width: 767.98px) {
    /* Та же логика, что на компьютере: заголовок на прежнем месте, плашка на
       месте строки сезона — 22 px до заголовка, как было у той строки (сверху
       74 вместо прежних 34). Без плашки 84 = прежние 34 над строкой сезона +
       её 28 (две строки) + 22 до заголовка. */
    .bl-hero__title:first-child { padding-top: 84px; }
    .bl-hero__promo + .bl-hero__title { margin-top: 22px; }
    .bl-hero__promo {
        margin-top: 74px;
        padding: 7px 14px 7px 8px;
        gap: 8px;
        font-size: 13px;
    }
    .bl-hero__promo-pct { font-size: 13px; padding: 5px 9px; }
    .bl-hero__promo-note { display: none; }
    .bl-hero__promo-hot { font-size: 12px; padding: 3px 8px; }
    .bl-hero__lead { margin-top: 22px; font-size: 14px; line-height: 1.45; max-width: none; }
    .bl-hero__cta { margin-top: 28px; flex-wrap: wrap; gap: 12px; }
    /* Крупные кнопки макета в 375 не влезают вдвоём: «Оформить заказ» ломался
       на две строки, у «Подробнее» срезало хвост. Кегль и поля меньше, перенос
       запрещён — если не помещаются, ряд переносится целиком. */
    .bl-hero__cta .bl-btn, .bl-hero__cta .bl-btn--primary {
        min-width: 0;
        flex: 1 1 150px;
        height: 46px;
        padding: 0 16px;
        font-size: 17px;
        white-space: nowrap;
    }
    .bl-offers, .bl-process, .bl-order, .bl-reviews { padding-top: 56px; }
    /* Макетные 259 px до подвала на телефоне — полэкрана пустоты. */
    .bl-reviews { padding-bottom: 96px; }
    .bl-process__grid { grid-template-columns: 268px; gap: 175px; }
    .bl-step:nth-child(1), .bl-step__num:nth-of-type(1) { grid-area: 1 / 1; }
    .bl-step:nth-child(2), .bl-step__num:nth-of-type(2) { grid-area: 2 / 1; }
    .bl-step:nth-child(3), .bl-step__num:nth-of-type(3) { grid-area: 3 / 1; }
    .bl-step:nth-child(4), .bl-step__num:nth-of-type(4) { grid-area: 4 / 1; }
    .bl-order__lead { font-size: 46px; line-height: 40px; }
    .bl-order__lead span:last-child { font-size: 48px; }
    .bl-order__btn { height: 72px; }
    /* FAQ: строки уже, поля меньше — вопрос из двух слов не должен занимать
       на телефоне четверть экрана. */
    .bl-faq { margin-top: 0; padding-bottom: 72px; }
    .bl-faq .bl-section-title { margin-bottom: 28px; }
    .bl-faq__list { gap: 10px; }
    .bl-faq__q { gap: 14px; padding: 16px 18px; }
    .bl-faq__qtext { font-size: 16px; }
    .bl-faq__a { padding: 0 18px 18px; font-size: 15px; }
    .bl-faq__foot { margin-top: 22px; font-size: 15px; }
}

/* ── Окно заказа ─────────────────────────────────────────────────────────
   В макете окно занимает тот же прямоугольник 1168×602, что и карточка
   «Выбери услугу», и подменяет её на месте. Внутри — прежний мастер заказа
   (те же id и обработчики), ему меняется только оформление.
   Цвета сняты пипеткой с «окно рейтинг.psd». */
.bl-orderwin { position: relative; }
/* Верхний отступ секции гасим селектором из двух классов, а не одним:
   `.calc-section { padding: 5rem 0 3rem }` лежит в <style> внизу Index.cshtml
   и по порядку идёт позже этого файла, поэтому одноклассовый `.bl-orderwin`
   его не перебивал. Из-за этого окно заказа вставало на 80 px ниже карточки
   «Выбери услугу», которую оно подменяет: при выборе услуги форма заметно
   уезжала вниз вместо того, чтобы встать ровно на её место. */
.calc-section.bl-orderwin { padding-top: 0; }
.bl-orderwin[hidden] { display: none; }
.bl-orderwin__card {
    position: relative;
    min-height: 602px;
    /* Боковой отступ 150 — из макета: заголовок начинается на 153 от края окна,
       сетка рангов на 150. При нём 6 плиток по 118 с зазором 32 занимают
       ровно внутреннюю ширину (868). */
    padding: 49px 149px 46px;   /* 149, а не 150: при ровно 868 шесть плиток
                                   не влезали из-за округления и ряд ломался */
    border-radius: var(--bl-radius-card);
    /* Светлой рамки по краю окна нет: владелец просил убрать — она читалась
       белым ободком по бокам формы. */
    /* Фон карточки — картинка из «окно рейтинг.psd»: по диагонали её пересекают
       световые полосы, одного градиента для этого мало. Тот же фон во всех
       остальных макетах окон заказа (калибровка, отыгрыш, коучинг, оплата).

       Картинка кладётся сверху на макетную высоту 602 и не тянется: карточка
       на живой странице бывает выше (до 761 на шагах выбора ранга), а
       растянутые по вертикали полосы меняют наклон. Низ картинки сведён
       в прозрачность прямо в файле, поэтому там, где она заканчивается,
       стыка не видно — дальше идёт градиент того же тона.
       Градиент снят пипеткой: угол #2B1D49, центр #302053, низ #35235D. */
    background: image-set(url('../img/design/orderwin-bg.webp') 1x,
                          url('../img/design/orderwin-bg@2x.webp') 2x)
                no-repeat 0 0 / 100% 602px,
                linear-gradient(125deg, #2B1D49 0%, #302053 50%, #35235D 100%);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .45);
}
.bl-orderwin__close {
    position: absolute;
    top: 27px;
    right: 27px;
    z-index: 3;
    width: 35px;
    height: 35px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: var(--bl-red);
    color: #fff;
    cursor: pointer;
    transition: filter .15s ease;
}
.bl-orderwin__close:hover { filter: brightness(1.15); }
.bl-orderwin__brand {
    position: absolute;
    top: 45px;
    right: 84px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: var(--bl-fs-nav);
    font-weight: 800;
    line-height: 1;
}

/* Прежняя «оболочка» мастера внутри окна не рисует ничего своего:
   рамку, фон и отступы задаёт карточка выше. */
.bl-orderwin .order-shell {
    max-width: none;
    margin: 0;
    padding: 0;
    border: 0 !important;
    border-radius: 0;
    background: none !important;
    box-shadow: none;
}
.bl-orderwin .order-tab { padding: 0; }
/* У мастера свой контейнер .wz шириной 720 — в окне он не нужен:
   сетка рангов в макете занимает всю внутреннюю ширину (868). */
.bl-orderwin .wz { max-width: none; margin: 0; }

/* Переключатель услуг в окне не нужен — услуга выбрана кнопкой снаружи.
   Скрываем и его, и служебную «лесенку» шагов: в макете их нет. */
.bl-orderwin .order-type-tabs,
.bl-orderwin .wz-progress,
.bl-orderwin .wz-labels,
.bl-orderwin .breadcrumbs,
.bl-orderwin .idx-title { display: none !important; }

.bl-orderwin .wz-title {
    margin-bottom: 4px;
    font-size: 27px;
    font-weight: 700;
    line-height: 1.1;
    color: var(--bl-text);
}
.bl-orderwin .wz-sub {
    margin-bottom: 20px;
    font-size: 14px;
    font-weight: 300;
    color: var(--bl-text-dim);
}

/* Кнопка подсказки «i» на шагах выбора ранга. В окне заголовок шага 27 px —
   кнопка растёт вместе с ним, иначе рядом с ним выглядит соринкой. Панель под
   фон окна: на фиолетовой карточке тёмный прямоугольник мастера смотрелся дырой. */
.bl-orderwin .wz-head { gap: 11px; margin-bottom: 4px; }
.bl-orderwin .rk-info__btn {
    width: 22px;
    height: 22px;
    flex-basis: 22px;
    font-size: 12px;
    border-color: rgba(190, 168, 255, .55);
    background: rgba(255, 255, 255, .06);
    color: var(--bl-text);
}
.bl-orderwin .rk-info__btn:hover,
.bl-orderwin .rk-info.is-open .rk-info__btn {
    border-color: var(--bl-violet);
    background: rgba(138, 92, 245, .35);
    color: #fff;
}
/* Панель заметно темнее карточки окна (её градиент #2B1D49…#35235D): в один тон
   с фоном она читалась не как всплывающая подсказка, а как дыра в макете. */
.bl-orderwin .rk-info__panel {
    width: 320px;
    border-radius: 18px;
    border-color: rgba(190, 168, 255, .5);
    background: linear-gradient(150deg, #241847 0%, #1B1136 100%);
    box-shadow: 0 24px 48px rgba(0, 0, 0, .5);
}
.bl-orderwin .rk-info__title { font-size: 14px; color: var(--bl-text); }
.bl-orderwin .rk-info__rank { font-size: 13px; color: rgba(255, 255, 255, .8); }
.bl-orderwin .rk-info__price { font-size: 13px; color: var(--bl-text); }
.bl-orderwin .rk-info__note {
    font-size: 11.5px;
    color: rgba(255, 255, 255, .7);
    border-top-color: rgba(255, 255, 255, .16);
}

/* Плитка ранга: 118×118 со скруглением, подпись сверху — как в макете. */
/* Ряд из шести плиток занимает всю ширину, неполный второй ряд центрируется —
   как нарисовано. */
.bl-orderwin .rk-grid { --rk-gap: 32px; gap: 32px; justify-content: center; }
.bl-orderwin .rk-tile {
    flex: 0 0 118px;
    padding: 0;
    border: 0;
    background: none;
}
.bl-orderwin .rk-name {
    order: -1;
    margin: 0 0 11px;
    font-size: 14.5px;
    font-weight: 400;
    letter-spacing: 0;
    text-transform: none;
    color: var(--bl-text);
}
/* Плитка — строгий квадрат со скруглением 18, как в макете: обводка идёт по
   самой плитке, а не по контуру картинки, поэтому у всех рангов она одинаковая. */
.bl-orderwin .rk-badge {
    width: 118px;
    height: 118px;
    aspect-ratio: 1 / 1;
    padding: 12px;
    border-radius: 18px;
    border: 1px solid rgba(190, 168, 255, .55);
    background: linear-gradient(150deg, #56398F 0%, #4A3080 100%);
    transition: border-color .15s ease, box-shadow .15s ease;
}
/* Иконки рангов в игре разной пропорции (Oracle широкий, Initiate высокий):
   вписываем каждую в один и тот же квадрат, иначе ряд выглядит рваным. */
.bl-orderwin .rk-badge img {
    width: 100%;
    height: 100%;
    max-width: none;
    object-fit: contain;
}
/* Под курсором обводка не меняется вовсе. Раньше на наведении светлела кромка
   плитки и под ней проступала фиолетовая подложка (.rk-tile:hover из стилей
   мастера) — вместе это читалось как выбор: посмотрел на ранг, а он выглядит
   отмеченным. Обводка теперь означает ровно одно — этот ранг выбран нажатием.
   Отклик на наведение остался, но не обводкой: у невыбранных плиток иконка
   приглушена в серый, под курсором она оживает. */
/* :not(.selected) обязателен: подложку выбранной плитки рисует .rk-tile.selected
   из стилей мастера, и без исключения наведение на выбранный ранг эту подложку
   бы снимало — плитка мигала бы под курсором. */
.bl-orderwin .rk-tile:hover:not(.selected) { background: none; }
.bl-orderwin .rk-tile:hover:not(.selected) .rk-badge img { filter: grayscale(.15) brightness(.98); }
/* Выбранная плитка: тонкая светлая кромка плюс фиолетовое свечение вокруг.
   Раньше тут стояла белая обводка в 3 px (border + box-shadow 2 px) — она
   выглядела наклейкой поверх плитки и спорила по весу с самой иконкой. */
.bl-orderwin .rk-tile.selected .rk-badge {
    border-color: rgba(255, 255, 255, .92);
    box-shadow: 0 0 0 3px rgba(138, 92, 245, .5),
                0 6px 22px rgba(138, 92, 245, .38);
}
.bl-orderwin .rk-tile.selected .rk-name { color: var(--bl-text); }

/* Степпер подразделения — одна цельная пилюля вместо трёх отдельных плашек:
   кружки «−» и «+» проявляются только под курсором, цифра стоит по центру
   в фиксированной ширине, чтобы не дёргалась между I и IV. */
.bl-orderwin .rk-divs {
    gap: 0;
    height: 30px;
    margin-top: 10px;
    padding: 0 3px;
    border-radius: var(--bl-radius-pill);
    border: 1px solid rgba(190, 168, 255, .3);
    background: rgba(11, 8, 19, .42);
}
.bl-orderwin .rk-div {
    min-width: 34px;
    font-family: var(--bl-font);
    font-size: 14px;
    font-weight: 600;
    letter-spacing: .06em;
    color: var(--bl-text);
}
.bl-orderwin .rk-step {
    flex: 0 0 24px;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 0;
    background: none;
    color: rgba(255, 255, 255, .72);
    font-size: 17px;
}
.bl-orderwin .rk-step:hover:not(:disabled) { background: rgba(255, 255, 255, .15); color: #fff; }
.bl-orderwin .rk-step:disabled { opacity: .28; }

/* Сетка героев — десять в ряду, плитки 70×86 с шагом 88, как в макете.
   Базовая сетка авто-заполнением давала разную ширину в каждом ряду. */
.bl-orderwin .heroes-grid-compact {
    grid-template-columns: repeat(10, 70px);
    gap: 11px 18px;
    justify-content: center;
}
.bl-orderwin .hero-item-sm {
    width: 70px;
    height: 86px;
    border-radius: 14px;
    border: 1px solid rgba(190, 168, 255, .35);
    background: rgba(255, 255, 255, .06);
}
/* Портреты героев приходят разного размера — обрезаем по плитке,
   иначе картинки съезжают и ряд идёт лесенкой. */
.bl-orderwin .hero-item-sm img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 0;
    display: block;
}
.bl-orderwin .hero-item-sm:hover { border-color: rgba(255, 255, 255, .7); }
.bl-orderwin .hero-item-sm.selected {
    border-color: #fff;
    box-shadow: 0 0 0 2px #fff;
    background: rgba(255, 255, 255, .14);
}

/* Поля Steam — тёмные «пилюли» из макета. */
.bl-orderwin .order-input,
.bl-orderwin .wz-input {
    height: 47px;
    padding: 0 24px;
    border: 0;
    border-radius: var(--bl-radius-field);
    background: var(--bl-field);
    color: var(--bl-text);
    font-size: 16px;
    font-weight: 300;
}
.bl-orderwin .order-input::placeholder { color: var(--bl-text-faint); }

/* Нижняя строка: слева пилюля с ценой, справа «Далее». */
.bl-orderwin .wz-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    margin-top: 34px;
    border: 0;
    padding: 0;
}
.bl-orderwin .wz-nav-btn {
    min-width: 193px;
    height: 47px;
    padding: 0 28px;
    border: 0;
    border-radius: var(--bl-radius-pill);
    background: linear-gradient(96deg, #4D3388, #6A45B8);
    color: var(--bl-text);
    font-family: var(--bl-font);
    font-size: 23px;
    font-weight: 300;
    cursor: pointer;
    transition: filter .15s ease;
}
.bl-orderwin .wz-nav-btn:hover { filter: brightness(1.15); }
.bl-orderwin .wz-nav-back { order: -1; background: rgba(255, 255, 255, .12); }

/* Пилюля с ценой на промежуточных шагах мастера — 376×46, как в макете. */
.bl-orderwin .wz-pricebar {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 375px;
    min-height: 46px;
    margin-top: 24px;
    padding: 0 28px;
    border: 0;
    border-radius: var(--bl-radius-pill);
    background: linear-gradient(96deg, #4D3388, #6A45B8);
    font-size: 23px;
    font-weight: 400;
}
/* А на шаге оплаты подложки нет: слева «К оплате», справа кнопка — как везде. */
.bl-orderwin .wz-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    min-width: 0;
    margin-top: 30px;
    padding: 0;
    border: 0;
    background: none;
}
.bl-orderwin .wz-summary-price {
    display: flex;
    align-items: baseline;
    gap: 10px;
    font-size: 37px;
    font-weight: 500;
    line-height: 1;
}
/* ── Текст внутри окна заказа ────────────────────────────────────────────
   Мастер достался от старого сайта, и мелочь в нём набрана россыпью:
   11 / 11,5 / 12 / 14,5 px, цвета — приглушённо-серые (--muted, #9c93b1),
   а цена ещё и моноширинным шрифтом. На тёмно-фиолетовой карточке, а тем
   более на светлой пилюле цены, всё это буквально сливалось с подложкой.

   Сводим к одной шкале: 27 — заголовок шага, 23 — строка цены и кнопки,
   15 — все подписи и подсказки. Ничего прозрачнее 0,78 на карточке
   и 0,92 на пилюле: контраст к фону получается 8,6:1 и 7:1. */
.bl-orderwin .wz-sub,
.bl-orderwin .wz-price-range,
.bl-orderwin .wz-summary-range,
.bl-orderwin .order-hint,
.bl-orderwin .wz-hint,
.bl-orderwin .field-hint {
    font-size: 15px;
    font-weight: 300;
    line-height: 1.4;
    color: rgba(255, 255, 255, .78);
}
.bl-orderwin .wz-price-range,
.bl-orderwin .wz-summary-range { margin: 0 0 4px; }
.bl-orderwin .rk-name { font-size: 15px; }
/* Счётчик героев рядом с заголовком и цифра подразделения в степпере —
   последние два места, где оставался кегль 12. */
.bl-orderwin .wz-title-count {
    font-size: 17px;
    font-weight: 400;
    color: rgba(255, 255, 255, .78);
}
.bl-orderwin .rk-div { font-size: 14px; }

/* Цена везде одним шрифтом с остальным окном: моноширинный из старой темы
   выбивался из набора сильнее всего. */
.bl-orderwin .price-val,
.bl-orderwin .price-label,
.bl-orderwin .unl-row-price,
.bl-orderwin .unl-total {
    font-family: var(--bl-font);
    letter-spacing: 0;
}
/* Базовый .price-label покрашен в --muted — на тёмно-фиолетовой карточке это
   3,9:1 даже в 37 px. Подпись к цене приглушать незачем: она часть суммы. */
.bl-orderwin .price-label { color: rgba(255, 255, 255, .92); }
.bl-orderwin .price-val { color: var(--bl-green); font-weight: 900; }
.bl-orderwin .wz-summary-price .price-val { font-size: 37px; }

/* Пилюля цены — самый светлый фон в окне, поэтому подпись на ней почти
   белая и того же кегля, что и число рядом. */
.bl-orderwin .wz-pricebar .price-label {
    font-size: 23px;
    font-weight: 400;
    color: rgba(255, 255, 255, .92);
}
/* Зелёный на этой пилюле даёт всего 3,9:1 — на светлом фиолетовом он тускнеет.
   В макете надпись в пилюле сплошь светлая, поэтому и цену тут пишем белым;
   зелёным она остаётся на шаге оплаты, где под ней тёмная карточка. */
.bl-orderwin .wz-pricebar .price-val { font-size: 23px; font-weight: 700; color: #fff; }

/* Шаг оплаты. Подпись «К оплате —» стояла 12 px рядом с числом в 37 —
   пара выглядела так, будто подпись забыли увеличить. */
.bl-orderwin .wz-summary-price .price-label {
    font-size: 37px;
    font-weight: 500;
    color: rgba(255, 255, 255, .92);
}

/* Старая цена и цена со скидкой. .price-new была залита фиолетовым #8A5CF5 —
   тем же, что и пилюля под ней, так что скидочная цена буквально пропадала
   в фоне. Обе строки теперь наследуют оформление .price-val, а зачёркнутая
   отличается не цветом на грани видимости, а прозрачностью. */
.bl-orderwin .price-new {
    color: inherit;
    font-family: inherit;
    font-size: inherit;
    font-weight: inherit;
}
.bl-orderwin .price-old {
    font-size: 17px;
    font-weight: 500;
    color: rgba(255, 255, 255, .62);
    opacity: 1;
}

/* Плашка «Скидка на первый заказ». */
.bl-orderwin .fo-discount-title { font-size: 17px; font-weight: 700; color: var(--bl-text); }
.bl-orderwin .fo-discount-sub { font-size: 15px; color: rgba(255, 255, 255, .78); }
/* Тёмный текст на #8A5CF5 даёт 4,1:1 — для плашки мало. Фон глубже, текст белый. */
.bl-orderwin .fo-discount-badge {
    font-size: 15px;
    background: #5E33C9;
    color: #fff;
}

/* Строчка «Оплата: СБП / крипта» под кнопкой. Подпись была rgb(97,87,120)
   на тёмно-фиолетовом — 2,2:1, читалась только если знать, что она там есть. */
.bl-orderwin .pay-methods-label { font-size: 14px; color: rgba(255, 255, 255, .78); }
.bl-orderwin .pay-chip { font-size: 14px; color: var(--bl-text); }
.bl-orderwin .steam-notice { font-weight: 300; color: rgba(255, 255, 255, .82); }

/* Калибровка и отыгрыш. Цена в строке была залита #8A5CF5 — ровно тем же
   фиолетовым, что и карточка под ней: 35 px, и почти не видно. В макете
   все цены на этом экране зелёные, ей и возвращаем зелёный.
   Подпись под названием строки и подсказка снизу подтягиваются к общей
   шкале окна: 15 px вместо 13 и 11,5. */
.bl-orderwin .unl-row-price { color: var(--bl-green); }
.bl-orderwin .unl-row-sub {
    font-size: 15px;
    font-weight: 300;
    color: rgba(255, 255, 255, .78);
}
.bl-orderwin .unl-hint { font-size: 15px; color: #F0B429; }
.bl-orderwin .unl-heroes-label { font-size: 15px; color: rgba(255, 255, 255, .78); }
.bl-orderwin .unl-count { color: var(--bl-text); font-weight: 600; font-family: var(--bl-font); }

/* Коучинг. Описание услуги идёт голым <p> из старой разметки — 13 px
   приглушённо-сиреневым; цена за час была белой на 45 %. */
.bl-orderwin .calibration-block > p,
.bl-orderwin .calibration-desc {
    font-size: 15px;
    font-weight: 300;
    line-height: 1.4;
    color: rgba(255, 255, 255, .78);
}
.bl-orderwin .calibration-desc { font-size: 19px; }
.bl-orderwin .wz-pricebar .wz-price-range { color: rgba(255, 255, 255, .92); font-size: 17px; }

@media (max-width: 1199.98px) {
    /* Картинка-фон рассчитана на макетные 1168×602. На узкой карточке её
       пришлось бы сжимать по горизонтали вдвое, и световые полосы легли бы
       поперёк — оставляем один градиент. */
    .bl-orderwin__card {
        min-height: 0;
        padding: 56px 24px 32px;
        /* Именно background целиком, а не background-image: у макетного фона
           два слоя и своя размерность (100% 602px, no-repeat). Замена одного
           background-image оставляла эти значения в силе, и градиент красил
           только верхние 602 px карточки — ниже она была прозрачной, а поперёк
           неё шла граница. На телефоне карточка длиннее 602 почти всегда. */
        background: linear-gradient(125deg, #2B1D49 0%, #302053 50%, #35235D 100%);
    }
    .bl-orderwin .rk-tile { flex: 0 0 96px; }
    .bl-orderwin .rk-badge { width: 96px; height: 96px; }
    /* Ниже макета плитки тянутся по ширине: жёсткие 70 px на телефоне давали
       два героя в ряд и список почти на две тысячи пикселей. */
    .bl-orderwin .heroes-grid-compact {
        grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
        gap: 8px;
    }
    .bl-orderwin .hero-item-sm { width: auto; height: auto; aspect-ratio: 70 / 86; }
    .bl-orderwin__brand { display: none; }
    .bl-orderwin .rk-grid { --rk-gap: 16px; }
}

/* ── Окно заказа: калибровка, отыгрыш, коучинг ───────────────────────────
   Координаты из «меню калибровка отыгрыш герои.psd» и «меню коучинг.psd».
   Те файлы нарисованы окном 876×452, на странице оно 1168×602 — поэтому
   все размеры оттуда домножены на 1,333. */

/* Вкладки «Калибровка / Отыгрыш 60 игр / Отыгрыш героев» — тёмные пилюли
   в один ряд, без общей подложки. Ряд центрируется: в макете он отступает
   от краёв окна на одинаковые 37 px. */
.bl-orderwin .unl-subtabs {
    max-width: none;
    margin: 0 0 46px;
    padding: 0;
    gap: 38px;
    border: 0;
    background: none;
    justify-content: center;
}
.bl-orderwin .unl-subtab {
    flex: 0 0 auto;
    min-width: 203px;
    height: 35px;
    padding: 0 26px;
    border-radius: var(--bl-radius-pill);
    background: #16141F;
    color: var(--bl-text);
    font-size: 20px;
    font-weight: 500;
    line-height: 35px;
}
.bl-orderwin .unl-subtab:hover { background: #1f182e; color: var(--bl-text); }
.bl-orderwin .unl-subtab.active {
    background: #16141F;
    color: var(--bl-text);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .75);
}

/* Название услуги в окне даёт вкладка сверху — отдельный заголовок в макете
   не нарисован, поэтому прячем. Внутренние отступы формы обнуляем: поля должны
   идти во всю ширину окна. */
.bl-orderwin .calibration-block { text-align: left; padding: 0; }
.bl-orderwin .calibration-block h3 { display: none; }
.bl-orderwin .calibration-block form { padding: 0; }
.bl-orderwin .calibration-desc {
    margin: 0 0 2px;
    font-size: 19px;
    font-weight: 600;
    text-align: left;
}
.bl-orderwin .calibration-desc strong { color: var(--bl-green) !important; }
.bl-orderwin .calibration-note {
    margin: 0 0 22px;
    font-size: 16px;
    font-weight: 300;
    color: var(--bl-text-dim);
    text-align: left;
}

/* Данные Steam: два поля во всю ширину окна, подпись сверху, сноска снизу. */
.bl-orderwin .bl-steam {
    max-width: none !important;
    margin: 0 0 24px !important;
    text-align: left !important;
}
.bl-orderwin .bl-steam .order-input {
    height: 56px;
    margin-bottom: 17px !important;
}
/* Подпись «Данные Steam» над полями — она есть на всех трёх экранах макета. */
.bl-orderwin .steam-caption {
    margin: 0 0 14px;
    font-size: 18.5px;
    font-weight: 500;
    color: var(--bl-text);
}
.bl-orderwin .steam-notice {
    margin-top: 4px;
    font-size: 14px;
    font-weight: 200;
    color: var(--bl-text-dim);
    background: none;
    border: 0;
    padding: 0;
}
.bl-orderwin .steam-notice svg { display: none; }
/* Ошибка формата Steam и примерный срок — тем же кеглем, что заметка под полями. */
.bl-orderwin .steam-err { font-size: 14px; margin: 8px 0 0; }
.bl-orderwin .order-eta { font-size: 14px; font-weight: 300; margin: 8px 0 0; color: var(--bl-text-dim); }
.bl-orderwin .order-eta b { color: var(--bl-text); font-weight: 600; }

/* Счётчик часов коучинга: круглая «−», пилюля со значением, круглая «+». */
.bl-orderwin .bl-hours {
    max-width: none;
    margin: 0 0 26px;
    text-align: left;
}
.bl-orderwin .bl-hours__label {
    display: block;
    margin: 0 0 8px 131px;
    font-size: 16px;
    font-weight: 300;
    color: var(--bl-text);
}
.bl-orderwin .bl-hours__row {
    display: flex;
    align-items: center;
    gap: 6px;
    justify-content: flex-start;
}
.bl-orderwin .coaching-step-btn {
    width: 46px;
    height: 47px;
    flex: 0 0 46px;
    border: 0;
    border-radius: 50%;
    background: #16141F;
    font-size: 26px;
    font-weight: 700;
    line-height: 1;
}
.bl-orderwin .coaching-step-btn--minus { color: #CE1A1A; }
.bl-orderwin .coaching-step-btn--plus { color: var(--bl-green); }
.bl-orderwin .coaching-step-btn:hover { background: #211a30; }
.bl-orderwin .coaching-hours-input {
    width: 256px;
    height: 47px;
    text-align: center;
    font-size: 29px;
    font-weight: 800;
    background: #16141F;
    border-radius: var(--bl-radius-pill);
}
.bl-orderwin .bl-hours__hint {
    margin: 6px 0 0 131px;
    font-size: 16px;
    font-weight: 300;
    color: var(--bl-text);
    text-align: left;
}
.bl-orderwin .bl-hours__hint b { font-weight: 700; }

/* Итоговая строка: слева «К оплате», справа «Оплатить» 235×48. */
.bl-orderwin .order-submit-btn {
    display: block;
    min-width: 235px;
    height: 48px;
    margin-left: auto;
    padding: 0 30px;
    border: 0;
    border-radius: var(--bl-radius-pill);
    background: var(--bl-grad-primary);
    color: var(--bl-text);
    font-size: 26px;
    font-weight: 600;
    line-height: 48px;
}
.bl-orderwin .order-submit-btn:disabled { opacity: .45; }

/* Карточка отыгрыша — фиолетовая плашка с двумя строками и ценами. */
.bl-orderwin .unl-card,
.bl-orderwin .unl-summary {
    border-radius: 26px;
    border: 0;
    background: linear-gradient(120deg, #6B48C4 0%, #5A3BAA 100%);
    padding: 24px 32px;
}

/* Шаг «Данные Steam» в мастере буста — те же поля 56 px во всю ширину окна,
   что и на вкладке калибровки: в макете это один и тот же экран оплаты. */
.bl-orderwin .steam-field-row { gap: 17px; }
.bl-orderwin .steam-field-row .order-input { height: 56px; }
.bl-orderwin #steamFields .steam-notice { order: 1; margin: 4px 0 0; }
.bl-orderwin #steamFields { display: flex; flex-direction: column; }
.bl-orderwin #steamFields .wz-title { order: -1; }

/* Итоговая плашка шага оформления: цена слева, кнопка справа. */
.bl-orderwin .wz-summary { flex-wrap: nowrap; }
.bl-orderwin .wz-summary .order-submit-btn { margin-left: auto; }


/* ── Отыгрыш: карточка услуги и выбор героев ─────────────────────────────
   По умолчанию (телефон, мобильные панели заказа) сетка героев живёт прямо
   в форме, как и раньше: обёртки модалки прозрачны для раскладки, а кнопки,
   которые её открывают, скрыты. Модалкой сетка становится только там, где
   показывается окно заказа. */
.unl-picker,
.unl-picker__card { display: contents; }
.unl-picker__close,
.unl-pick-btn,
.unl-pick-link { display: none; }

@media (min-width: 661px) {
    /* Блок отыгрыша в окне: своего заголовка в макете нет — его роль играет
       вкладка сверху, поэтому и h3, и вводный абзац убираем, а форме снимаем
       собственную ширину 520 (из-за неё сетка героев и выезжала за окно). */
    .bl-orderwin .unl-block { padding: 0; text-align: left; }
    .bl-orderwin .unl-block > h3,
    .bl-orderwin .unl-block > .calibration-desc { display: none; }
    .bl-orderwin .unl-form { max-width: none; margin: 0; }

    /* Карточка «Отыгрыш 60 игр»: 865×136 с двумя строками — как в макете. */
    .bl-orderwin .unl-card { padding: 24px 32px 21px; margin-bottom: 26px; }
    .bl-orderwin .unl-row { padding: 0; margin-bottom: 16px; }
    .bl-orderwin .unl-row:last-child { margin-bottom: 0; }
    .bl-orderwin .unl-row-title { font-size: 18.5px; font-weight: 600; line-height: 1.05; }
    /* Кегль и вес подписи против макета подняты (там 13/200): в макетном
       наборе строка сливалась с карточкой. Остальная типографика окна
       живёт по общей шкале выше. */
    .bl-orderwin .unl-row-sub { font-size: 15px; font-weight: 300; line-height: 1.25; }
    .bl-orderwin .unl-row-price { font-size: 35px; font-weight: 900; line-height: 1; }

    /* «Отыгрыш героев» в макете начинается ниже — под вкладками там не карточка,
       а строка текста; ставим ей собственный верхний отступ. */
    .bl-orderwin #unlpBlock .unl-card,
    .bl-orderwin #munlpBlock .unl-card { padding-top: 30px; margin-bottom: 40px; }

    /* Поля Steam здесь те же, что и на калибровке: 864×56 с шагом 73. */
    .bl-orderwin .unl-steam { margin: 0 0 22px; }
    .bl-orderwin .unl-steam .order-input {
        display: block;
        width: 100%;
        height: 56px;
        margin-bottom: 17px;
    }

    /* Подвал формы: слева итог, справа кнопка оплаты — как в макете. */
    .bl-orderwin .unl-foot {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 24px;
    }
    .bl-orderwin .unl-foot .unl-total {
        margin: 0;
        border: 0;
        padding: 0;
        font-size: 37px;
        font-weight: 500;
        line-height: 1;
    }
    .bl-orderwin .unl-foot .price-label { font-size: 37px; font-weight: 500; }
    .bl-orderwin .unl-foot .price-val { font-size: 37px; font-weight: 900; color: var(--bl-green); }
    .bl-orderwin .unl-hint { margin-top: 10px; text-align: right; }

    /* Строку с доплатой в макете открывает ссылка «Выбрать», а не тумблер.
       Сам чекбокс остаётся — это поле формы; клики по строке гасим, иначе
       label молча включал бы платную опцию без единого признака на экране. */
    .bl-orderwin .unl-row--sub { pointer-events: none; }
    .bl-orderwin .unl-row--sub .fo-switch { display: none; }
    .bl-orderwin .unl-pick-link {
        display: inline-block;
        margin-left: 18px;
        padding: 0;
        border: 0;
        background: none;
        color: var(--bl-text);
        font-family: var(--bl-font);
        font-size: 17px;
        font-weight: 300;
        text-decoration: underline;
        cursor: pointer;
        pointer-events: auto;
    }

    /* «Отыгрыш героев»: подложки у строки в макете нет, справа — кнопка 315×48. */
    .bl-orderwin #unlpBlock .unl-card,
    .bl-orderwin #munlpBlock .unl-card { padding: 0; border: 0; background: none; }
    .bl-orderwin .unl-pick-btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: 0 0 auto;
        min-width: 315px;
        height: 48px;
        margin-left: 24px;
        border: 0;
        border-radius: var(--bl-radius-pill);
        background: var(--bl-grad-primary);
        color: var(--bl-text);
        font-family: var(--bl-font);
        font-size: 26px;
        font-weight: 500;
        cursor: pointer;
        transition: filter .15s ease;
    }
    .bl-orderwin .unl-pick-btn:hover { filter: brightness(1.12); }

    /* Окно выбора героев поверх окна заказа: в макете это карточка 735×395
       внутри окна 876×452, то есть 980×527 на странице. Плитки 44×54 с шагом
       55×61 — на странице 59×72 с зазором 15×10. */
    .bl-orderwin .unl-picker {
        display: none;
        position: absolute;
        inset: 0;
        z-index: 5;
        border-radius: var(--bl-radius-card);
        background: rgba(11, 8, 19, .55);
    }
    .bl-orderwin .unl-picker.is-open {
        display: flex;
        align-items: center;
        justify-content: center;
    }
    .bl-orderwin .unl-picker__card {
        display: block;
        position: relative;
        width: min(980px, calc(100% - 48px));
        max-height: calc(100% - 40px);
        overflow-y: auto;
        padding: 40px 40px 36px;
        border-radius: 28px;
        border: 1px solid rgba(146, 116, 232, .45);
        background: linear-gradient(130deg, #2E2150 0%, #37265F 52%, #3E2B6B 100%);
        box-shadow: 0 30px 70px rgba(0, 0, 0, .5);
    }
    /* Пока опция «на моих героях» выключена, расчёт прячет сетку инлайновым
       стилем. В открытом окне показывать нечего иное — снимаем. */
    .bl-orderwin .unl-picker .unl-heroes { display: block !important; padding: 0; }
    .bl-orderwin .unl-picker .unl-heroes-label {
        margin: 0 0 26px;
        padding-right: 40px;
        font-size: 20px;
        font-weight: 600;
        color: var(--bl-text);
    }
    .bl-orderwin .unl-picker .unl-count { color: var(--bl-green); font-weight: 700; }
    .bl-orderwin .unl-picker .heroes-grid-compact {
        grid-template-columns: repeat(auto-fill, 59px);
        gap: 10px 15px;
        justify-content: center;
        max-width: 725px;
        margin-inline: auto;
    }
    .bl-orderwin .unl-picker .hero-item-sm {
        width: 59px;
        height: 72px;
        border-radius: 12px;
    }
    .bl-orderwin .unl-picker__close {
        display: flex;
        align-items: center;
        justify-content: center;
        position: absolute;
        top: 26px;
        right: 26px;
        width: 21px;
        height: 21px;
        padding: 0;
        border: 0;
        border-radius: 50%;
        background: var(--bl-red);
        color: #fff;
        cursor: pointer;
    }

    /* Верхний зазор у панелей разный: у калибровки под вкладками ещё 22 px,
       у отыгрыша карточка идёт сразу — поэтому отступ живёт не у вкладок. */
    .bl-orderwin .unl-subtabs { margin-bottom: 24px; }
    .bl-orderwin .calibration-block { padding-top: 22px; }
}

/* Телефон: макетных 203 px под вкладку нет — три штуки не влезают в экран
   и вылезали за него. Возвращаем тянущиеся кнопки, как было до окна заказа. */
/* Узкий телефон: при 320 карточка окна 288, и боковые 24 оставляли мастеру
   238 — ранги и герои в такую полосу уже не раскладываются по-человечески. */
@media (max-width: 400px) {
    .bl-orderwin__card { padding: 48px 12px 26px; }
    .bl-orderwin__close { top: 16px; right: 16px; }
}

/* Сетка рангов на узком экране ───────────────────────────────────────────
   В окне заказа плитка зафиксирована в 96 px (см. медиазапрос 1199.98 выше):
   на макетной ширине это ровно шесть штук в ряд. На телефоне те же 96 плюс
   зазор 32 давали два ранга в ряд и колонку высотой 1222 px — одиннадцать
   рангов листались дольше, чем весь остальной заказ.

   Возвращаем механику исходного мастера: ширина плитки считается от числа
   колонок, а зазор берётся из той же переменной. Переопределить один
   --rk-gap было мало: в .bl-orderwin .rk-grid рядом с переменной стоял
   ещё и литеральный gap: 32px, и он продолжал действовать.

   Колонок три, а не четыре: под плиткой стоит степпер подразделения
   шириной 90 px, и при четырёх колонках (75 px на плитку) он вылезал бы
   за её края. Три даёт плитку в 101 px — и степпер помещается, и герб
   на гербовой картинке остаётся различимым. */
@media (max-width: 991.98px) {
    .bl-orderwin .rk-grid { --rk-cols: 4; --rk-gap: 10px; gap: var(--rk-gap); }
    .bl-orderwin .rk-tile {
        flex: 0 0 calc((100% - (var(--rk-cols) - 1) * var(--rk-gap)) / var(--rk-cols));
    }
    /* Бейдж тянется за плиткой: жёсткие 96 не давали ей сжаться. */
    .bl-orderwin .rk-badge {
        width: 100%;
        height: auto;
        padding: 9px;
        border-radius: 15px;
    }
    .bl-orderwin .rk-name { margin-bottom: 8px; font-size: 13px; }
}
@media (max-width: 600px) {
    .bl-orderwin .rk-grid { --rk-cols: 3; --rk-gap: 8px; }
    .bl-orderwin .rk-name { font-size: 12.5px; }
}

@media (max-width: 660px) {
    /* Мобильный переключатель услуг: 11 px и #555 — неактивная вкладка была
       почти неотличима от подложки, а её ещё и нажимать надо. */
    /* Переключатель услуг стоит в разметке ПОСЛЕ мастера буста, а показываться
       должен над ним. В старой вёрстке это делал flex-order на .calc-section
       .container; в окне заказа общий родитель теперь .bl-orderwin__card,
       и он блочный — order не действовал, и на вкладке «Рейтинг» переключатель
       уезжал под весь список рангов, в самый низ карточки. Делаем карточку
       колонкой — прежние order:1 и order:2 снова работают. */
    .bl-orderwin__card { display: flex; flex-direction: column; }

    /* Мобильная форма собрана ещё в старом дизайне: у неё своя карточка —
       фотография PhoneBg под тёмной вуалью, фиолетовая рамка и тень. Внутри
       нового окна заказа это карточка в карточке: фотография спорит со
       световыми полосами окна, а почти чёрная полоса вкладок не совпадает
       с ним ни по тону, ни по форме. Поверхность даёт само окно, поэтому
       у обёртки убираем всё её оформление. */
    .bl-orderwin #mobileOrderWrap { border: 0; border-radius: 0; box-shadow: none; }
    .bl-orderwin #mobileOrderWrap::before,
    .bl-orderwin #mobileOrderWrap::after { display: none; }
    .bl-orderwin #mobCalibrationPanel,
    .bl-orderwin #mobCoachingPanel { padding-left: 0; padding-right: 0; }

    /* Полоса вкладок: вместо тёмной плашки со стеклом — прозрачная строка
       с тонкой чертой снизу, как у остального окна. */
    .bl-orderwin .mob-type-tabs {
        margin-bottom: 20px;
        background: none;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        border-bottom: 1px solid rgba(190, 168, 255, .3);
    }
    .bl-orderwin .mob-type-tab {
        padding: 10px 0 12px;
        font-size: 13px;
        font-weight: 500;
        letter-spacing: .04em;
        color: rgba(255, 255, 255, .70);
    }
    .bl-orderwin .mob-type-tab.active {
        color: var(--bl-text);
        background: none;
        border-bottom-color: var(--bl-violet);
    }

    /* Поля ввода — те же пилюли, что и в окне на десктопе. Часы коучинга
       исключены: у них своя ширина и кегль (см. .coaching-hours-input). */
    .bl-orderwin .mob-input:not(.coaching-hours-input) {
        height: 46px;
        padding: 0 18px;
        border: 1px solid rgba(190, 168, 255, .4);
        border-radius: var(--bl-radius-pill);
        background: #16141F;
        color: var(--bl-text);
        font-family: var(--bl-font);
        font-size: 15px;
    }
    .bl-orderwin .mob-input:not(.coaching-hours-input)::placeholder { color: rgba(255, 255, 255, .45); }
    .bl-orderwin .mob-input:not(.coaching-hours-input):focus { border-color: var(--bl-violet); }

    /* Кнопка оплаты — та же пилюля с градиентом, что и .order-submit-btn
       на десктопе; в старой теме она была жёлтой с чёрным текстом. */
    .bl-orderwin .mob-submit-btn {
        height: 47px;
        padding: 0 28px;
        border: 0;
        border-radius: var(--bl-radius-pill);
        background: var(--bl-grad-primary);
        color: var(--bl-text);
        font-family: var(--bl-font);
        font-size: 20px;
        font-weight: 600;
    }
    .bl-orderwin .mob-submit-btn:disabled { opacity: .45; }

    /* Пилюля цены нарисована в макете шириной 376 — это шире всей карточки
       на телефоне, и сумма вылезала за её край. Ставим по ширине карточки
       и в две строки: диапазон рангов сверху, итог под ним. */
    .bl-orderwin .wz-pricebar {
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 2px;
        min-width: 0;
        width: 100%;
        padding: 9px 16px;
    }
    .bl-orderwin .wz-pricebar .price-label,
    .bl-orderwin .wz-pricebar .price-val { font-size: 18px; }
    .bl-orderwin .wz-pricebar .wz-price-range { font-size: 14px; }

    /* Две кнопки по 193 с зазором 24 требуют 410 px — столько на телефоне
       не даёт ни один экран, и «Далее» уезжала за карточку. Делим место
       поровну; макетный кегль 23 на такой кнопке всё равно не помещается. */
    .bl-orderwin .wz-nav { gap: 10px; margin-top: 24px; }
    .bl-orderwin .wz-nav-btn {
        flex: 1 1 0;
        min-width: 0;
        max-width: 193px;
        height: 44px;
        padding: 0 12px;
        font-size: 17px;
    }

    .bl-orderwin .unl-subtabs { gap: 6px; margin-bottom: 16px; flex-wrap: wrap; }
    .bl-orderwin .unl-subtab {
        flex: 1 1 auto;
        min-width: 0;
        height: auto;
        padding: 8px 10px;
        font-size: 12px;
        line-height: 1.2;
    }
}

/* ═══ Витрина коучей во вкладке коучинга ═══════════════════════════════════
   Живёт здесь, а не в <style> внизу Index.cshtml: тот файл уже 2600 строк и
   самый нагруженный в проекте. Имена классов новые (.bl-coach*), поэтому с
   правилами инлайнового блока они не пересекаются и порядок загрузки не важен.

   Карточки лежат горизонтальным скроллером, а не сеткой: блок стоит внутри
   узкой формы заказа, коучей может быть и три, и тридцать, а вертикальный
   список отодвинул бы кнопку оплаты за экран.
   ────────────────────────────────────────────────────────────────────────── */
.bl-coachpick {
    max-width: min(520px, 100%);
    margin: 0 auto 16px;
    text-align: left;
}

.bl-coachpick__head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.bl-coachpick__title {
    font-size: 14px;
    font-weight: 700;
    color: #fff;
}

.bl-coachpick__hint {
    font-size: 12px;
    color: var(--bl-text-dim, rgba(255, 255, 255, .62));
}

.bl-coachpick__row {
    display: flex;
    gap: 10px;
    overflow-x: auto;
    padding: 2px 2px 10px;
    scroll-snap-type: x proximity;
    scrollbar-width: thin;
    scrollbar-color: var(--bl-violet, #8A5CF5) transparent;
}

.bl-coachpick__row::-webkit-scrollbar { height: 6px; }
.bl-coachpick__row::-webkit-scrollbar-track { background: transparent; }
.bl-coachpick__row::-webkit-scrollbar-thumb {
    background: rgba(138, 92, 245, .55);
    border-radius: 3px;
}

/* Сама радиокнопка не прячется display:none — так её теряют клавиатура и
   скринридер. Убираем визуально, оставляя в потоке фокуса. */
.bl-coach {
    position: relative;
    flex: 0 0 186px;
    scroll-snap-align: start;
    cursor: pointer;
    margin: 0;
}

.bl-coach__radio {
    position: absolute;
    inset: 0;
    opacity: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}

.bl-coach__inner {
    display: flex;
    flex-direction: column;
    gap: 6px;
    height: 100%;
    padding: 11px 12px 12px;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: 12px;
    background: rgba(255, 255, 255, .035);
    transition: border-color .16s, background .16s, transform .16s;
    pointer-events: none;
}

.bl-coach:hover .bl-coach__inner {
    border-color: rgba(138, 92, 245, .5);
    transform: translateY(-2px);
}

.bl-coach__radio:checked + .bl-coach__inner {
    border-color: var(--bl-violet, #8A5CF5);
    background: rgba(138, 92, 245, .14);
}

.bl-coach__radio:focus-visible + .bl-coach__inner {
    outline: 2px solid var(--bl-violet, #8A5CF5);
    outline-offset: 2px;
}

.bl-coach__top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
}

.bl-coach__name {
    font-size: 13px;
    font-weight: 700;
    color: #fff;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.bl-coach__rank {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
    font-size: 10px;
    font-weight: 600;
    color: var(--bl-text-dim, rgba(255, 255, 255, .62));
    white-space: nowrap;
}

/* object-fit обязателен: арты героев и иконки рангов не квадратные, а в карточке
   им задан жёсткий бокс 26x26 / 18x18. Без него браузер растягивает картинку и
   персонажи выглядят сплющенными. */
.bl-coach__rank-ico { display: block; object-fit: contain; }

.bl-coach__heroes { display: flex; gap: 4px; }

.bl-coach__hero {
    border-radius: 6px;
    background: rgba(0, 0, 0, .28);
    object-fit: cover;
}

/* Описание обрезаем тремя строками: карточки в одном ряду обязаны быть одной
   высоты, иначе ряд «прыгает», а длинный текст всё равно читают на витрине.
   Три строки — это только СВЁРНУТЫЙ вид, полный текст доступен всегда: на
   компьютере — подсказкой браузера по наведению (атрибут title в разметке),
   везде, включая телефон, — разворотом по выбору карточки, см. правило ниже. */
.bl-coach__bio {
    font-size: 11.5px;
    line-height: 1.45;
    color: var(--bl-text-dim, rgba(255, 255, 255, .62));
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Цена часа на карточке. Стоит НАД .bl-coach__pick, у которого margin-top:auto —
   поэтому прижимается к нижнему краю вместе с ним, а не уезжает под описание
   переменной высоты. */
.bl-coach__price {
    margin-top: auto;
    font-size: 12px;
    font-weight: 700;
    color: var(--bl-violet, #8A5CF5);
}

.bl-coach__pick {
    margin-top: 6px;
    align-self: flex-start;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: 3px 9px;
    border-radius: 20px;
    color: var(--bl-text-dim, rgba(255, 255, 255, .62));
    background: rgba(255, 255, 255, .07);
    transition: background .16s, color .16s;
}

.bl-coach__radio:checked + .bl-coach__inner .bl-coach__pick {
    background: var(--bl-violet, #8A5CF5);
    color: #1c162a;
}

/* Выбранная карточка показывает описание целиком.

   Почему не всплывающей подсказкой поверх карточки: ряд коучей — горизонтальный
   скроллер (.bl-coachpick__row, overflow-x: auto), а скроллер обрезает всё, что
   вылезло за его бокс, по ОБЕИМ осям. Любой поповер над карточкой был бы срезан.

   Почему по :checked, а не по :hover: на телефоне наведения не существует вовсе,
   и раньше длинное описание там нельзя было дочитать никак. Выбор карточки —
   единственный жест, одинаково доступный мыши и пальцу, и он же означает интерес
   именно к этому коучу. Карточка при этом становится выше, а соседи тянутся за
   ней флексом, поэтому ряд остаётся ровным. */
.bl-coach__radio:checked + .bl-coach__inner .bl-coach__bio {
    display: block;
    -webkit-line-clamp: none;
    line-clamp: none;
    overflow: visible;
}

.bl-coach--any .bl-coach__inner { border-style: dashed; }

@media (max-width: 560px) {
    .bl-coach { flex: 0 0 158px; }
}
