/*
	СТИЛИ КЛИЕНТСКОГО САЙТА (steditor) — ОТДЕЛЬНЫЙ БАНДЛ.

	ПРИНЦИП ИЗОЛЯЦИИ (несущий, не нарушать):
	  1) сайт клиента — ОТДЕЛЬНАЯ сущность от сервиса. Ни один селектор
	     этого файла не действует вне корневой обертки `.st-site`;
	  2) внутри разметки сайта НЕ используются классы Metronic/Bootstrap —
	     только собственные `st-*`. Поэтому смена темы сайта не может
	     сломать интерфейс сервиса вокруг конструктора, а стили сервиса
	     не протекают в предпросмотр;
	  3) все переменные оформления — с префиксом `--st-*` (значения тем
	     приходят инлайном, см. steditorThemeStyle() в functions.php).
	     Пересечений с `--bs-*` быть не должно;
	  4) базовые свойства элементов внутри сайта задаются здесь ЯВНО
	     (сброс ниже) — чтобы правила бандла Metronic для голых тегов
	     (h1, p, ul, img, button) не влияли на сайт.

	Светлая и темная палитры разведены атрибутом `data-st-mode` на корне.
*/

/* ==== КОРЕНЬ И СБРОС ==================================================== */

/*
	==== `hidden` ОБЯЗАН ПРЯТАТЬ — ОДНО ПРАВИЛО НА ВЕСЬ САЙТ (2026-08-21) ====

	НАСТОЯЩАЯ ПРИЧИНА «БЛОК СРАВНЕНИЯ ПУСТОЙ». Скрипты сайта показывают
	и прячут узлы СВОЙСТВОМ `hidden` (`box.hidden = false`,
	`empty.hidden = true`) — так устроены и корзина, и заказы, и сравнение.
	Но `[hidden] { display: none }` живет в ТАБЛИЦЕ БРАУЗЕРА, а любое
	авторское правило вида `.st-empty { display: flex }` ее перебивает
	независимо от специфичности: авторский уровень всегда старше UA.

	Итог был такой: `versusRender()` честно снимал заглушку
	(`empty.hidden = true`), а `.st-empty` с `display: flex` продолжал
	ее показывать — покупатель добавлял два товара и все равно читал
	«Отметьте товары кнопкой «Сравнить»».

	ЛЕЧИТСЯ ОДНИМ ПРАВИЛОМ, А НЕ ЛАТКОЙ НА КАЖДЫЙ КЛАСС. В файле уже семь
	точечных пар `.st-cart__note[hidden]`, `.st-pdp__cart-note[hidden]`
	и т.п. — каждая появилась после того, как очередное состояние
	«не пряталось». Восьмую заводить нельзя: любой НОВЫЙ класс с `display`
	принесет ту же ошибку заново. Правило ниже закрывает весь класс
	ошибок сразу, поэтому у него `!important` — иначе его перебьет
	ровно то же самое авторское `display`.

	`.st-tabs [hidden]` ниже по файлу оставлен намеренно: вкладки прячут
	СВОИ блоки, у которых `display` приходит инлайном от сетки, — там
	важен не только этот уровень
*/
.st-site [hidden] {
	display: none !important;
}

.st-site {
	/* Страховка на случай, если тема не отдала переменные */
	--st-bg: #F4F6F9;
	--st-surface: #FFFFFF;
	--st-surface-alt: #EEF2F6;
	--st-border: #E3E8EF;
	--st-text: #1B1F27;
	--st-muted: #78818F;
	--st-accent: #2F8F5B;
	--st-accent-text: #FFFFFF;
	--st-danger: #D64550;
	/*
		СМЫСЛОВЫЕ ЦВЕТА ЗНАЧКА (2026-08-22, `$_AI['icon_colors']`).

		ОНИ НЕ ЗАВИСЯТ ОТ ПАЛИТРЫ НАМЕРЕННО: «успех» и «внимание» —
		это устоявшиеся значения светофора, и перекрась мы их вслед
		за темой, галочка на витрине перестала бы читаться как галочка.
		Акцент, текст и приглушенный ведут себя ровно наоборот — они
		и есть тема, и объявлены выше.

		Тема вправе их переопределить: правила берут их через `var()`
		с запасным значением, поэтому объявление здесь — не догма,
		а разумное умолчание
	*/
	--st-success: #2F8F5B;
	--st-warning: #E0A32E;
	--st-info: #3E8FD4;
	--st-font: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
	--st-radius: 16px;
	--st-radius-sm: 10px;
	--st-shadow: 0 6px 24px rgba(24, 32, 48, 0.08);

	/*
		ЦВЕТ ТЕКСТА ТЕМЫ, НЕ ЗАВИСЯЩИЙ ОТ ПЕРЕОПРЕДЕЛЕНИЙ ВНУТРИ СТРАНИЦЫ
		(2026-08-04).

		Секция вправе задать СВОЙ `--st-text` (белый на темном фоне бренда),
		и он расходится по всему ее поддереву. Но элементы со СВОЕЙ СВЕТЛОЙ
		ПОДЛОЖКОЙ — карточки, поля поиска, выпадашки меню — обязаны остаться
		с темным текстом: белый на белом не читается.

		Значение подставляется ЗДЕСЬ, на корне, и дальше наследуется
		неизменным: `var()` внутри пользовательского свойства раскрывается
		в момент вычисления НА СВОЕМ элементе, поэтому переопределение
		`--st-text` в потомке этой переменной уже не касается
	*/
	--st-text-base: var(--st-text);

	display: block;
	background-color: var(--st-bg);
	color: var(--st-text);
	font-family: var(--st-font);
	font-size: 16px;
	line-height: 1.5;
	text-align: left;
}

.st-site *,
.st-site *::before,
.st-site *::after {
	box-sizing: border-box;
}

.st-site h1,
.st-site h2,
.st-site h3,
.st-site h4,
.st-site p,
.st-site ul,
.st-site ol,
.st-site figure {
	margin: 0;
	padding: 0;
	font-weight: inherit;
	font-size: inherit;
	color: inherit;
}

.st-site ul,
.st-site ol {
	list-style: none;
}

/*
	==== СБРОС ИНТЕРАКТИВНЫХ ТЕГОВ ЖИВЕТ В `:where()` ====
	(правка 2026-08-14 — ПАРИТЕТ КНОПОК, читать целиком)

	БЫЛО: `.st-site a`, `.st-site button` … — специфичность (0,1,1).
	А ВСЕ фирменные правила блоков — ОДИН класс, (0,1,0). То есть сброс
	`color: inherit` / `font: inherit` МОЛЧА ПЕРЕБИВАЛ их: у `.st-lead__btn`
	не работал ни `color: var(--st-accent-text)`, ни `font-size` —
	зеленая кнопка рисовала текст ЦВЕТОМ ТЕКСТА СТРАНИЦЫ (в светлой
	палитре почти черным), а не белым.

	ЭТО НЕ ТЕОРИЯ: в файле уже был локальный обход того же капкана —
	`.st-site .st-docview__btn` (просмотрщик PDF) написан с лишним
	корнем ИМЕННО чтобы победить этот сброс.

	СТАЛО: селектор корня спрятан в `:where()`, который не добавляет
	специфичности вовсе, — правило превращается в (0,0,1), то есть
	в обычный сброс уровня тега. Он по-прежнему сильнее СТИЛЕЙ БРАУЗЕРА
	(авторская таблица старше UA-таблицы независимо от специфичности)
	и по-прежнему не дает правилам бандла Metronic для голых тегов
	достать до сайта, но НЕ СПОРИТ ни с одним классом `st-*`.

	ПОЧЕМУ ЭТО И ЕСТЬ ЛЕЧЕНИЕ РАСХОЖДЕНИЯ «КОНСТРУКТОР ↔ САЙТ»: файл
	у обоих контуров ОДИН, значит и результат теперь один — кнопка
	считает свой цвет по `--st-accent-text` темы и там, и там.
	Самопроверка после правки: `.st-lead__btn` / `.st-timer__btn` /
	`.st-cta__btn` в канвасе и на странице обязаны совпасть по фону,
	цвету текста и цвету значка в ОБЕИХ палитрах
*/
:where(.st-site) a {
	color: inherit;
	text-decoration: none;
}

.st-site img,
.st-site video {
	display: block;
	max-width: 100%;
	height: auto;
	border: 0;
}

:where(.st-site) button,
:where(.st-site) input,
:where(.st-site) select,
:where(.st-site) textarea {
	font: inherit;
	color: inherit;
	margin: 0;
}

/*
	==== ЗНАЧОК ИЗ ФАЙЛА (`.st-icon`, 2026-08-21) ====

	ОБЩИЕ ПРАВИЛА ДЛЯ ТРЕХ ИСТОЧНИКОВ ЗНАЧКА. Раньше значок в блоке был
	всегда глифом шрифта, и размер ему задавал `font-size` места. Теперь
	это может быть КАРТИНКА (свой SVG) или КОНТЕЙНЕР АНИМАЦИИ (Lottie),
    а у них своей «кегли» нет вовсе.

	РАЗМЕР БЕРЕТСЯ ОТ ТЕКСТА (`1em`), и это ключевое решение: место
	не обязано ничего знать о том, какой источник выбрал владелец.
	Поставил блок значку 20 px — столько же займет и глиф, и картинка,
	и анимация. Иначе каждое место пришлось бы учить трем разным
	способам задать размер.

	`aspect-ratio` ВМЕСТО ФИКСИРОВАННОЙ ВЫСОТЫ: несимметричный SVG
	(широкая стрелка, длинная линия) иначе растянулся бы в квадрат
*/
.st-site .st-icon {
	display: inline-block;
	flex: 0 0 auto;
	width: 1em;
	height: 1em;
	vertical-align: -0.125em;
}

.st-site .st-icon--svg {
	object-fit: contain;
}

/* Контейнер анимации: пока файл не приехал, место уже занято — иначе
   строка «дергалась» бы в момент появления значка */
.st-site .st-icon--lottie > svg {
	display: block;
	width: 100%;
	height: 100%;
}

/*
	==== ВСЕ ТЕКСТОВЫЕ ОБЛАСТИ САЙТА РАСТУТ САМИ (2026-08-21) ====

	ПРАВИЛО ОБЩЕЕ, А НЕ ПО МЕСТАМ. Ручка изменения размера в правом нижнем
	углу — системный элемент браузера: ее нельзя ни перекрасить, ни
	вписать в скругление поля, а на темной теме она остается светлой
	насечкой. Плюс она предлагает работу, которой человек делать не должен:
	поле обязано подстроиться само.

	ВЫСОТУ СЧИТАЕТ `autoSize()` в stsite.js — по содержимому, до потолка.
	Потолок стоит здесь же: без него вставленная простыня растянула бы
	форму на несколько экранов и увезла кнопку отправки за край.

	ТРИ МЕСТА (форма заявки, комментарий к заказу, отзыв) раньше держали
	`resize` каждое свое — теперь ответ один на всех, и новая форма
    получит его без единой строки
*/
:where(.st-site) textarea {
	resize: none;
	overflow-y: auto;
	max-height: 340px;
}

/*
	==== ФИРМЕННЫЕ КНОПКИ: ЦВЕТ ЗНАЧКА = ЦВЕТ ТЕКСТА ====

	Значки внутри кнопок (`<i class="ki-*">`, инлайновый SVG) свой цвет
	не наследуют автоматически: у `ki-*` он задан отдельно. Правится
	ТОЛЬКО `color` — сами `fill`/`stroke` в нашей разметке написаны через
	`currentColor` и подтянутся сами. Трогать их правилом НЕЛЬЗЯ: CSS
	сильнее презентационного атрибута, и `fill: currentColor` залил бы
	контурные значки, у которых в разметке стоит `fill="none"`
*/
.st-site .st-lead__btn i,
.st-site .st-lead__btn svg,
.st-site .st-timer__btn i,
.st-site .st-timer__btn svg,
.st-site .st-cta__btn i,
.st-site .st-cta__btn svg,
.st-site .st-cookie__btn i,
.st-site .st-cookie__btn svg {
	color: inherit;
}

/*
	==== ЛЮБОЙ ЗНАЧОК НАСЛЕДУЕТ ЦВЕТ МЕСТА (2026-08-21) ====

	ПЕРЕЧИСЛЯТЬ СЕЛЕКТОРЫ ПОШТУЧНО БОЛЬШЕ НЕЛЬЗЯ — и вот почему это стало
	видно именно сейчас. Пока набор значков был один, `ki-*` красились
    правилами Метроника, и мы гасили их в тех местах, где цвет ЗНАЧИМ:
	кнопки, бейджи, наличие товара. Список рос, но был конечным.

	С приходом Font Awesome и Line Awesome тот же список пришлось бы
	переписать заново для каждого нового шрифта: у `fa-*` и `la-*` свои
	базовые правила, и там, где мы гасили только `ki-*`, значок нового
	набора остался серым. Владелец увидел это первым же — звезда
	Font Awesome на зеленой кнопке была серой, хотя подпись рядом белая.

	ПОЭТОМУ ПРАВИЛО ОДНО И ПРО ЭЛЕМЕНТ, А НЕ ПРО ШРИФТ: на сайте `<i>`
	используется ТОЛЬКО как значок, и цвет ему задает место, в котором
	он стоит. Новый набор значков теперь ведет себя правильно
	без единой строки.

	ГДЕ ЦВЕТ ЗНАЧКА СВОЙ (обязательная звездочка формы, значок упаковки
	акцентом), правила остаются рабочими — см. про вес ниже.

	==== ПОЧЕМУ КОРЕНЬ НАПИСАН ДВАЖДЫ (`.st-site.st-site`) ====

	ЭТО НЕ ОПЕЧАТКА, А СПОСОБ ПОДНЯТЬ ВЕС ПРАВИЛА, не прибегая
	к `!important`. Первая версия правила (`.st-site i`, вес 0-1-1)
	не сработала: значок Font Awesome на кнопке остался серым, потому
	что его перебивало правило иконочного шрифта с двумя классами.
	`!important` здесь был бы хуже — он снес бы и НАШИ осмысленные
	цвета значков.

	Повтор класса дает вес 0-2-1: этого хватает, чтобы перебить
	правила шрифтов, и РОВНО НЕ ХВАТАЕТ, чтобы перебить наши
	собственные пары вида `.st-cart__field i` (тот же вес 0-2-1,
	но они стоят НИЖЕ по файлу и потому выигрывают). Обязательная
	звездочка формы остается красной, значок наличия — зеленым,
	а значок любого набора наследует цвет своего места
*/
.st-site.st-site i {
	color: inherit;
}

/* ==== ФОН САЙТА (глобальная настройка) ================================= */
/*
	Слои рисуются ПСЕВДОЭЛЕМЕНТАМИ корня, а не отдельной разметкой:
	  ::before — сам фон (картинка / цвет / градиент; у видео — черная
	             подложка, пока файл грузится);
	  ::after  — ЗАТЕМНЕНИЕ поверх видео и, при желании, паттерн.
	Значения приходят инлайном из steditorBackgroundCss().

	ЗАТЕМНЕНИЕ НАД ВИДЕО — НЕ КОСМЕТИКА: без него текст поверх движущегося
	кадра нечитаем, поэтому слой существует всегда, регулируется только
	его плотность.

	ВАЖНО, ПОЧЕМУ СЛОИ `absolute`, А НЕ `fixed`: в конструкторе сайт
	живет внутри «листа» (.ste-paper) фиксированной ширины, и `fixed`
	отсчитывался бы от ОКНА БРАУЗЕРА — фон вылез бы за пределы листа
	и залил интерфейс редактора. Абсолютные слои растягиваются ровно
	по корню сайта и ведут себя одинаково в предпросмотре и на странице.
*/
.st-site.st-bg-on {
	position: relative;
	background-color: transparent;
}

.st-site.st-bg-on::before,
.st-site.st-bg-on::after {
	content: '';
	position: absolute;
	inset: 0;
	pointer-events: none;
}

/* Порядок слоев: видео → фон (::before) → затемнение (::after) →
   паттерн → содержимое */
.st-site.st-bg-on::before {
	z-index: 0;
}

.st-site.st-bg-on::after {
	z-index: 1;
}

/*
	Видео фона — настоящий элемент: псевдоэлементом его не нарисовать.

	==== НАСТОЯЩАЯ ПРИЧИНА «ФОН ВЫЛЕЗАЕТ ЗА СЕКЦИЮ» — КОЛЛИЗИЯ ИМЕН ====
	(найдено 2026-08-04, после трех неверных диагнозов)

	Контейнер фона получает класс-модификатор ТИПА: `st-bg-image`,
	`st-bg-color`, … и `st-bg-video`. А элемент `<video>` носил РОВНО ТО ЖЕ
	ИМЯ — значит правило, написанное для КАДРА, применялось И К САМОЙ
	СЕКЦИИ: она получала `position: absolute` и выпадала из потока, дорожка
	уровня схлопывалась до минимума, а блоки из секции вываливались наружу.
	У фона-картинки модификатор другой, поэтому картинка работала —
	и эта разница увела диагноз в сторону (сначала на специфичность
	сброса тегов, потом на цепочку процентов высоты).

	ТЕПЕРЬ У КАДРА СВОЕГО КЛАССА НЕТ ВОВСЕ: он адресуется как ребенок
	рамки. Совпасть с модификатором типа больше нечему.
	ИМЕНА `st-bg-{тип}` ЗАРЕЗЕРВИРОВАНЫ за модификаторами контейнера —
	ни один элемент внутри фона такое имя носить не должен.

	ВЕС (0,3,0) ВЗЯТ НЕ СЛУЧАЙНО: выше в этом же файле лежит сброс базовых
	тегов `.st-site video` (0,1,1) с `height: auto`, и его тоже нужно
	перебить — иначе кадр развернется в собственный размер.

	РЕЖИМ НАЛОЖЕНИЯ — ПЕРЕМЕННЫМИ: `object-fit` и `object-position`
	приходят из настроек фона (steditorBackgroundCss), умолчание `cover`
	повторяет прежнее поведение
*/
/*
	РАМКА ВИДЕО — АБСОЛЮТНАЯ ОБЕРТКА С ОБРЕЗКОЙ.

	Она и есть гарантия «фон не выйдет за свою коробку»: высота самого кадра
	зависит от цепочки процентов (секция → обертка сетки → дорожка уровня),
	а в этой цепочке хватает мест, где процент разрешается не в то, что
	ожидаешь. `overflow: hidden` снимает вопрос целиком — за границы рамки
	не выйдет ничто, чем бы ни оказалась вычисленная высота.

	ОБРЕЗАЕТСЯ ТОЛЬКО ФОН, А НЕ СОДЕРЖИМОЕ: рамка отдельный слой, и мини-
	панели блоков, всплывашки и подсказки редактора она не задевает —
	поэтому `overflow: hidden` на саму секцию вешать НЕЛЬЗЯ
*/
.st-site .st-bg-frame {
	position: absolute;
	inset: 0;
	z-index: 0;
	display: block;
	overflow: hidden;
	pointer-events: none;
	border-radius: inherit;
}

.st-site .st-bg-frame > video {
	position: absolute;
	inset: 0;
	z-index: 0;
	width: 100%;
	height: 100%;
	object-fit: var(--st-bg-fit, cover);
	object-position: var(--st-bg-pos, center);
	pointer-events: none;
}

/* ПАТТЕРН — ОТДЕЛЬНЫЙ СЛОЙ, а не часть затемнения: у него своя
   прозрачность, и внутри затемняющего слоя ее было бы не задать
   (opacity родителя перемножилась бы с opacity текстуры) */
.st-bg-pattern {
	position: absolute;
	inset: 0;
	z-index: 2;
	display: block;
	pointer-events: none;
}

/*
	Содержимое обязано лежать НАД слоями фона.

	ЭТАП C: прямые дети корня — уже не блоки, а ОБЛАСТИ (общая шапка,
	страница, общий подвал). Поднимаем именно их: перечислять внуков
	пришлось бы бесконечно
*/
.st-site.st-bg-on > .st-chrome,
.st-site.st-bg-on > .st-page,
.st-site.st-bg-on > .st-block,
.st-site.st-bg-on > .st-footer,
.st-site.st-bg-on > .ste-block {
	position: relative;
	z-index: 3;
}

/* ==== СЕКЦИЯ — КОНТЕЙНЕР БЛОКОВ СО СВОИМ ФОНОМ (2026-08-04) ============ */
/*
	СЕКЦИЯ ПОВТОРЯЕТ УСТРОЙСТВО КОРНЯ САЙТА, и это осознанно: те же слои
	(::before — фон, ::after — затемнение, .st-bg-frame, .st-bg-pattern),
	тот же класс-включатель `st-bg-on`, тот же генератор CSS
	(steditorBackgroundCss с ДРУГИМ селектором). Второй механики фона
	в проекте нет — она разъехалась бы с первой при первой же правке.

	ВНУТРИ СЕКЦИИ ЛЕЖИТ ЕЩЕ ОДНА 2D-СЕТКА (`.st-section__grid`, класс
	`st-page` переиспользован ради его правил колонок и коробки).
	Вложенность ровно одна: секции внутри секции не бывает
*/
.st-section {
	position: relative;
}

/*
	==== ЦВЕТ ТЕКСТА СЕКЦИИ ДОЛЖЕН ДЕЙСТВОВАТЬ НА ЕЕ БЛОКИ ====
	(правка 2026-08-04)

	ГРАБЛИ, ИЗ-ЗА КОТОРЫХ НАСТРОЙКА НЕ РАБОТАЛА: секция объявляет
	`--st-text` инлайном, но ЦВЕТ (`color: var(--st-text)`) объявлен ровно
	ОДИН раз — на корне сайта. Переменная в потомке переопределяется,
	а само свойство `color` там больше никем не объявлено: заголовки
	и абзацы стоят на `color: inherit` и наследуют УЖЕ ВЫЧИСЛЕННЫЙ темный
	цвет корня. Переопределить переменную мало — надо ПЕРЕОБЪЯВИТЬ свойство.

	Секция делает это у себя, и дальше каскад разносит цвет по всем ее
	блокам. Если своего цвета у секции нет, переменная приходит из темы —
	результат тот же, что и был.

	ЭЛЕМЕНТЫ СО СВОИМ ФОНОМ (белые карточки, поля поиска) не задеты:
	они красят текст своими переменными, и на светлой подложке он обязан
	оставаться темным
*/
.st-site .st-section {
	color: var(--st-text);
}

/*
	ИСКЛЮЧЕНИЕ: ЭЛЕМЕНТЫ СО СВОЕЙ СВЕТЛОЙ ПОДЛОЖКОЙ.

	Карточки товаров, блок контактов, поле поиска, выпадашка меню и прочее,
	что рисует себе собственный фон (`--st-surface`), обязаны сохранить
	ТЕМАТИЧЕСКИЙ цвет текста. Иначе белый текст темной секции ложился бы
	на белую карточку и исчезал — настройка «цвет текста секции» чинила бы
	одно и ломала другое.

	Список закрытый и короткий: это ровно те элементы, у которых есть свой
	фон. Добавляя новый такой блок, впишите его сюда — иначе он потеряет
	читаемость внутри темной секции
*/
.st-site .st-section .st-contacts,
.st-site .st-section .st-social,
.st-site .st-section .st-search__field,
.st-site .st-section .st-search__input,
.st-site .st-section .st-brand,
.st-site .st-section .st-collection,
.st-site .st-section .st-card,
.st-site .st-section .st-product,
.st-site .st-section .st-media__item,
.st-site .st-section .st-map,
.st-site .st-section .st-rich table,
.st-site .st-section .st-menu__sub,
.st-site .st-section .st-menu--pills .st-menu__link,
.st-site .st-section .st-views {
	color: var(--st-text-base);
}

/*
	==== ВЫСОТУ СЕКЦИИ ЗАДАЕТ ЕЕ СОДЕРЖИМОЕ, А НЕ ПРОЦЕНТ ====
	(правка 2026-08-04, по итогам приемки)

	СИМПТОМ БЫЛ ТАКОЙ: у секции с фоном полоса схлопывалась до высоты
	одного уровня (~152 px = минимум дорожки 120 плюс отступы блока 2×16),
	а блоки из нее ВЫВАЛИВАЛИСЬ и наезжали на содержимое страницы под ней.

	ПРИЧИНА — ФИКСАЦИЯ ВЫСОТЫ ПРОЦЕНТОМ. Правила `.st-page > .st-block`
	и `.ste-block > .st-block` дают секции `height: 100%`, чтобы она
	заполнила свой прямоугольник (без этого не в чем выравнивать содержимое
	по вертикали). Для КОНТЕЙНЕРА это вредно: процент разрешается от
	МИНИМУМА дорожки уровня, и содержимое собственной сетки оказывается
	снаружи.

	ЛЕЧЕНИЕ — В ИСТОЧНИКЕ: оба правила `height: 100%` теперь ЯВНО
	ИСКЛЮЧАЮТ `.st-section` (см. `:not(.st-section)` ниже и в steditor.css).
	Спорить весами не с чем — правило к секции просто не относится.
	Здесь остается только НИЖНЯЯ ГРАНИЦА: секция не мельче своего
	прямоугольника, но расти ей ничто не мешает. Пара к ней — `flex: 1 0 auto`
	у внутренней сетки: сжиматься ниже содержимого она не должна ни при
	какой высоте родителя
*/
.st-site .st-section.st-block {
	min-height: 100%;
}

.st-section.st-bg-on {
	background-color: transparent;
}

/*
	==== ГРАНИЦЫ ФОНА СЕКЦИИ (2026-08-14) ====

	ПОЧЕМУ ЭТО ВООБЩЕ ПОНАДОБИЛОСЬ. Секция — элемент сетки области,
	и как у любого блока у нее есть СВОЙ горизонтальный отступ
	(`.st-block { padding: … 20px }`). Слои фона лежали `inset: 0`,
	то есть закрашивали и этот отступ: фоновая секция выходила на 20 px
	левее и правее, чем содержимое соседнего блока без фона. На глаз это
	читалось как съехавшая верстка — именно с этой жалобы правка и начата.

	УМОЛЧАНИЕ `st-section--bgbox`: слои вдвигаются на `--st-section-bleed`,
	и левая/правая границы фона совпадают с границами содержимого соседей.
	`st-section--bgfull` возвращает прежнее поведение — фон до краев самой
	секции (нужен геройским полосам).

	ВЕЛИЧИНА СДВИГА У СЕКЦИИ «ВО ВСЮ ШИРИНУ» ДРУГАЯ. Такая секция гасит
	свой отступ отрицательным полем `--st-gutter` и доходит до краев
	области, поэтому вернуть фон к коробке страницы стоит `gutter + 20px`.
	Переменная объявляется НА САМОЙ СЕКЦИИ (а не наследуется), иначе
	вложенная секция посчитала бы чужой gutter
*/
.st-section {
	/* НАСКОЛЬКО ВДВИНУТЬ ФОН, чтобы он встал вровень с содержимым соседей.
	   У обычной секции это ее собственный горизонтальный отступ */
	--st-section-bleed: 20px;
	/* НАСКОЛЬКО ОТСТУПИТЬ СОДЕРЖИМОМУ, чтобы оно осталось в коробке
	   страницы. У обычной секции — ноль: внутренняя сетка и так начинается
	   от ее content-box, то есть ровно там же, где кромка фона */
	--st-section-inset: 0px;
}

.st-section.st-block--full {
	--st-section-bleed: calc(var(--st-gutter, 0px) + 20px);
	--st-section-inset: var(--st-gutter, 0px);
}

/* Секция «во всю ширину» с фоном «вровень»: содержимое обязано зайти
   внутрь кромки фона, а она сама вдвинута на gutter + отступ блока */
.st-section.st-block--full.st-section--bgbox {
	--st-section-inset: calc(var(--st-gutter, 0px) + 20px);
}

.st-section.st-bg-on::before,
.st-section.st-bg-on::after {
	content: '';
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.st-section--bgbox.st-bg-on::before,
.st-section--bgbox.st-bg-on::after,
.st-section--bgbox.st-bg-on > .st-bg-frame,
.st-section--bgbox.st-bg-on > .st-bg-pattern {
	left: var(--st-section-bleed);
	right: var(--st-section-bleed);
	border-radius: var(--st-radius);
}

/*
	==== ВНУТРЕННИЕ ОТСТУПЫ СЕКЦИИ ====

	Воздух между рамкой фона и вложенными блоками. Ставится НА ВНУТРЕННЮЮ
	СЕТКУ, а не на саму секцию, и это принципиально: паддинг секции входит
	в ее коробку, а коробка секции — это ячейка сетки области, размеченная
	координатами. Раздуй ее — и соседний блок уехал бы.

	ДВОЙНЫХ ОТСТУПОВ У ВЛОЖЕННЫХ БЛОКОВ НЕТ: их собственный горизонтальный
	отступ (20 px) — это ритм СЕТКИ (зазор между соседями по колонкам),
	а отступ секции — поле вокруг всей сетки. Складываться им не в чем:
	первый живет внутри ячейки, второй снаружи всех ячеек
*/
.st-section--pad-none > .st-section__grid { --st-section-pad: 0px; }
.st-section--pad-sm > .st-section__grid { --st-section-pad: 16px; }
.st-section--pad-md > .st-section__grid { --st-section-pad: 32px; }
.st-section--pad-lg > .st-section__grid { --st-section-pad: 48px; }
.st-section--pad-xl > .st-section__grid { --st-section-pad: 64px; }

/* НА ТЕЛЕФОНЕ ПОЛЕ КОРОЧЕ: 48-64 px по бокам съедают половину экрана.
   Устройство фиксируется атрибутом (в конструкторе медиазапросы врут)
   и медиазапросом (на публичной странице ширина честная) */
.st-site[data-st-device="mobile"] .st-section--pad-lg > .st-section__grid,
.st-site[data-st-device="mobile"] .st-section--pad-xl > .st-section__grid {
	--st-section-pad: 20px;
}

@media (max-width: 575.98px) {
	.st-site--live .st-section--pad-lg > .st-section__grid,
	.st-site--live .st-section--pad-xl > .st-section__grid {
		--st-section-pad: 20px;
	}
}

.st-section.st-bg-on::before {
	z-index: 0;
}

.st-section.st-bg-on::after {
	z-index: 1;
}

/* Содержимое секции — НАД ее слоями фона (пара к правилу корня сайта) */
.st-section.st-bg-on > .st-section__grid {
	position: relative;
	z-index: 3;
}

.st-section.st-bg-animate.st-bg-on::before {
	animation: stBgShift var(--st-bg-speed, 12s) ease infinite;
}

@media (max-width: 767.98px) {
	.st-section.st-bg-animate-desktop.st-bg-on::before {
		animation: none;
	}
}

/*
	ВНУТРЕННЯЯ СЕТКА НЕ ПОВТОРЯЕТ КОРОБКУ СТРАНИЦЫ ДВАЖДЫ.

	Коробку уже задала САМА СЕКЦИЯ (она — элемент внешней сетки и лежит
	внутри отступов `--st-gutter` области). Повторный отступ внутри
	съел бы содержимое второй раз, и блоки внутри секции оказались бы
	заметно уже соседей снаружи — то есть выглядели бы поломкой.
	У секции «во всю ширину экрана» (`st-block--full`) коробка, наоборот,
	нужна: иначе ее содержимое разъедется до краев окна.

	==== ОТСЮДА ЖЕ ИДУТ ВНУТРЕННИЕ ОТСТУПЫ СЕКЦИИ (2026-08-14) ====

	ГОРИЗОНТАЛЬ = «вернуться в коробку» + «поле». Первое слагаемое
	(`--st-section-inset`) зависит от того, где начинается сетка и докуда
	доходит фон, второе (`--st-section-pad`) задает владелец.
	ВЕРТИКАЛЬ — только поле: сверху и снизу возвращаться некуда.

	ОТСТУП СТОИТ НА СЕТКЕ, А НЕ НА САМОЙ СЕКЦИИ, и это несущее: коробка
	секции — ЯЧЕЙКА 2D-сетки области, размеченная координатами. Раздуй ее
	паддингом — и соседний по уровню блок уехал бы
*/
.st-section > .st-section__grid {
	/*
		`.st-block` — флекс-колонка (так сделано ради вертикального
		выравнивания содержимого), поэтому внутренняя сетка ЗАНИМАЕТ
		ОСТАТОК высоты секции.

		`flex-shrink: 0` ОБЯЗАТЕЛЕН (правка 2026-08-04): с единицей сетка
		послушно ужималась под ошибочно посчитанную высоту родителя,
		и блоки вываливались из секции. Расти она может, сжиматься ниже
		своего содержимого — нет. Пара к `min-height` у самой секции
	*/
	flex: 1 0 auto;
	padding-top: var(--st-section-pad, 32px);
	padding-bottom: var(--st-section-pad, 32px);
	padding-left: calc(var(--st-section-inset, 0px) + var(--st-section-pad, 32px));
	padding-right: calc(var(--st-section-inset, 0px) + var(--st-section-pad, 32px));
}

/* ==== ОБЛАСТИ СТРАНИЦЫ (ЭТАП C) ======================================== */

/*
	ОБЩАЯ ШАПКА и ОБЩИЙ ПОДВАЛ — обертки без собственного оформления:
	рисовать их как «полосы» нельзя, иначе тема сайта не смогла бы сделать
	шапку прозрачной поверх геройской секции.
	Всё видимое здесь — только обвязка редактора (steditor.css)

	==== ОБЛАСТЬ — ЭТО 2D-СЕТКА (ШАГ D) ====

	ДВЕНАДЦАТЬ КОЛОНОК × УРОВНИ. Раньше сеткой была САМА СЕКЦИЯ: каждый
	блок раскладывал свои двенадцать дорожек и занимал в них место, поэтому
	два блока рядом были физически невозможны — они лежали в разных сетках.
	Теперь сетка ОДНА на область, а блок — ее элемент с прямоугольником
	[col … col+span) × [level … level+levels).

	КОРОБКА СТРАНИЦЫ ЗАДАНА ОТСТУПАМИ, А НЕ max-width, и это несущее:
	ширину коробки надо уметь ОТМЕНИТЬ для геройской секции «во всю ширину»,
	а отступ отменяется отрицательным полем той же величины
	(`--st-gutter` ниже). С `max-width` вырваться из коробки было бы нечем:
	`100vw` в конструкторе отмерял бы от ОКНА БРАУЗЕРА, а не от «листа».

	ВЫСОТА УРОВНЯ — `minmax(--st-level, auto)`: уровень задает МИНИМУМ,
	а содержимое вправе быть выше. Иначе блок с длинным текстом обрезался бы,
	а владелец получил бы «переполнение в никуда»
*/
.st-chrome,
.st-page {
	--st-gutter: max(0px, calc((100% - var(--st-page, 1220px)) / 2));

	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	/* ДОРОЖКИ УРОВНЕЙ ЗАДАЮТСЯ ЯВНО (число приходит от сервера): у НЕЯВНЫХ
	   дорожек вычисленное значение grid-template-rows не гарантировано,
	   а конструктор считает по нему всю геометрию. grid-auto-rows остается
	   страховкой на случай блока, уехавшего за объявленный предел */
	grid-template-rows: repeat(var(--st-levels, 1), minmax(var(--st-level, 120px), auto));
	grid-auto-rows: minmax(var(--st-level, 120px), auto);
	align-items: stretch;
	padding-left: var(--st-gutter);
	padding-right: var(--st-gutter);
}

/*
	==== СИСТЕМНАЯ СТРАНИЦА: ДОРОЖКИ МЕРЯЮТСЯ СОДЕРЖИМЫМ (2026-08-21) ====

	ЧТО ЧИНИТ. На карточке товара и в профиле между блоками зияли полосы
	пустоты, заметно шире обычного ритма, — при том что на страницах,
	собранных владельцем, отступы нормальные.

	ПРИЧИНА БЫЛА НЕ В ОТСТУПАХ, А В МИНИМУМЕ ДОРОЖКИ. Уровень объявлен
	как `minmax(--st-level, auto)`, то есть занимает не меньше 120 px даже
	под коротким блоком. Владелец с этим не сталкивается: он расставляет
	блоки мышью по ЭТОЙ ЖЕ сетке и получает ровно то, что нарисовал.
	А раскладку системных страниц задает СЕРВИС (`system_pages.layout`) —
	по уровню на блок, не зная высоты содержимого. «Название», «Цена»,
	«Наличие», «Упаковка» короче ста двадцати пикселей, и под каждым
	оставалась полоса воздуха.

	ПОЧЕМУ НЕ УМЕНЬШИТЬ `--st-level` ГЛОБАЛЬНО: это переставило бы блоки
	на ВСЕХ уже собранных сайтах клиентов — сетка, по которой владелец
	раскладывал страницу, поехала бы у него под ногами. Здесь же
	минимума не было ни у кого: эту раскладку никто руками не рисовал.

	РИТМ ОСТАЕТСЯ ПРЕЖНИМ И ОБЩИМ: расстояние между блоками задают их
	собственные отступы (`--st-pad-y`), как и на любой другой странице.
	Именно поэтому «Отзывы → Как с нами связаться» выглядели правильно
	и раньше — подвал это отдельная область со своей сеткой
*/
.st-site .st-page--sys {
	--st-level: 0px;
}

/* Анимация переливания градиента. Скорость приходит переменной
   --st-bg-speed из настроек фона */
@keyframes stBgShift {
	0% { background-position: 0% 50%; }
	50% { background-position: 100% 50%; }
	100% { background-position: 0% 50%; }
}

.st-site.st-bg-animate.st-bg-on::before {
	animation: stBgShift var(--st-bg-speed, 12s) ease infinite;
}

/* Экономия батареи на телефонах — НАСТРОЙКА владельца, а не запрет:
   класс ставится только когда он не включил анимацию на мобильных */
@media (max-width: 767.98px) {
	.st-site.st-bg-animate-desktop.st-bg-on::before {
		animation: none;
	}
}

/* ==== СЕТКА СТРАНИЦЫ ==================================================== */

/* Отступы блоков РАВНОМЕРНЫЕ, без правил на соседей: в конструкторе
   каждый блок обернут своей рамкой редактора, и соседние `.st-block`
   перестают быть братьями — правило вида `.st-block + .st-block` там
   молча не сработало бы */
.st-site {
	padding: 12px 0;
}

/*
	МЕСТО ПОД ЗАКРЕПЛЕННУЮ НИЖНЮЮ ПАНЕЛЬ (правка 2026-08-03).

	Панель вынута из потока, поэтому последний блок страницы уехал бы
	под нее. Отступ ставится ТОЛЬКО когда панель есть — по факту ее наличия
	в разметке, а не по устройству: презентацию выбирает сервер, и владелец
	вправе включить панель хоть на ПК
*/
.st-site:has(.st-nav) {
	padding-bottom: var(--st-nav-space, 78px);
}

/*
	СЕКЦИЯ — ЭЛЕМЕНТ 2D-СЕТКИ ОБЛАСТИ (ШАГ D).

	Прямоугольник блока приезжает четырьмя переменными, которые ставит
	сервер (`websiteBlocksPack`): стартовая колонка и ширина, стартовый
	уровень и высота. Блок занимает РОВНО свой прямоугольник — суженный
	до трех колонок он и на экране трех колонок, а справа остается
	настоящее свободное место, куда встанет сосед.

	В КОНСТРУКТОРЕ ЭЛЕМЕНТ СЕТКИ — ОБЕРТКА РЕДАКТОРА (`.ste-block`),
	а не сама секция: рамка, мини-панель и хваты обязаны совпадать
	с границами блока. Правило для нее — в steditor.css, координаты те же
*/
.st-page > .st-block,
.st-chrome > .st-block {
	grid-column: var(--st-col-start, 1) / span var(--st-span, 12);
	grid-row: var(--st-row-start, auto) / span var(--st-rows, 1);
}

/*
	==== СЕКЦИЯ — КОЛОНКА, А НЕ ПРОСТО БЛОК (2026-08-04) ====

	Нужно ради ВЕРТИКАЛЬНОГО ВЫРАВНИВАНИЯ. В 2D-сетке блок почти всегда
	выше своего содержимого: он либо занимает несколько уровней, либо стоит
	рядом с высоким соседом и растягивается вместе с ним. До сих пор
	содержимое молча прижималось к верху, и другого выбора не было.

	`flex-direction: column` + `justify-content` дают его одним свойством,
	а для ЕДИНСТВЕННОГО ребенка (`.st-container` есть у всех типов без
	исключения) колонка ведет себя ровно как обычный блок — верстка типов
	не меняется
*/
.st-block {
	display: flex;
	flex-direction: column;
	justify-content: flex-start;
	min-width: 0;
	/*
		ВЕРТИКАЛЬНЫЙ ОТСТУП — ЧЕРЕЗ ПЕРЕМЕННУЮ (правка 2026-08-10), потому что
		снизу к нему ПРИБАВЛЯЕТСЯ спейсер (`common.spacer_after`). Прямое
		значение здесь и в правилах `.st-block--pad-*` затирало бы сумму,
		и доп. отступ пропадал бы у любой секции со своими отступами
	*/
	padding: var(--st-pad-y, 16px) 20px;
}

/*
	==== ДОП. ОТСТУП СНИЗУ, В СТРОКАХ (2026-08-10) ====

	ЧТО ЭТО. Точечная пауза ПОСЛЕ блока — не «характер секции» (для него есть
	`pad`, он симметричен), а разрыв ритма именно в этом месте страницы.
	Правится пробелом и Shift+пробелом при выделенном блоке.

	ВЕЛИЧИНА СТРОКИ ЖИВЕТ ЗДЕСЬ И БОЛЬШЕ НИГДЕ — это единственный источник
	размера, как у ширины страницы. Сервер отдает только ЧИСЛО строк
	(`--st-spacer`), а класс включает правило: без него `calc()` считался бы
	у каждого блока сайта впустую.

	ПОЧЕМУ padding, А НЕ margin: блок — элемент сетки с `height: 100%`,
	и внешний отступ вылез бы за его дорожку вместо того, чтобы раздвинуть ее
*/
/*
	ВЕЛИЧИНА СТРОКИ ОБЪЯВЛЕНА НА КОРНЕ САЙТА, а не на самом блоке, и это
	не мелочь: ту же величину читает ПОМЕТКА ПУНКТИРОМ в конструкторе
	(`.ste-spacer` в steditor.css), а она лежит в ОБЕРТКЕ блока — то есть
	не внутри `.st-block`, а рядом с ним. Объяви размер на блоке — пунктир
	унаследовать его не смог бы и разъехался бы с настоящим зазором.
	Обвязка редактора при этом живет ВНУТРИ `.st-site`, поэтому корень
	накрывает обоих
*/
.st-site {
	--st-spacer-line: 28px;
}

/* НА УЗКОМ ЭКРАНЕ СТРОКА КОРОЧЕ: тот же ритм читается как провал, а место
   дороже. Правило работает и в узком «листе» конструктора — там устройство
   задает атрибут, а не ширина окна */
.st-site[data-st-device="mobile"],
.st-site[data-st-device="tablet"] {
	--st-spacer-line: 18px;
}

.st-site .st-block--spaced {
	padding-bottom: calc(var(--st-pad-y, 16px) + var(--st-spacer, 0) * var(--st-spacer-line, 28px));
}

.st-block--vcenter { justify-content: center; }
.st-block--vbottom { justify-content: flex-end; }

/*
	СЕКЦИЯ ЗАПОЛНЯЕТ СВОЙ ПРЯМОУГОЛЬНИК ЦЕЛИКОМ.

	Без этого выравнивать было бы не в чем: секция была бы ровно по высоте
	содержимого, а свободное место оставалось бы у элемента сетки — снаружи.
	В РЕДАКТОРЕ элемент сетки — обертка, и парное правило для нее живет
	в steditor.css: классы `ste-*` в файле стилей САЙТА недопустимы.

	==== КОНТЕЙНЕР (`.st-section`) ИСКЛЮЧЕН ЯВНО (правка 2026-08-04) ====

	И это НЕ борьба весов, а отказ от нее. Первая попытка чинить последствие
	(перебить `height: 100%` селектором потяжелее) была неверной по существу:
	правило просто НЕ ДОЛЖНО касаться контейнера. У обычного блока фиксация
	высоты нужна ради вертикального выравнивания содержимого; у секции
	выравнивания нет вовсе, зато есть СВОЯ ВНУТРЕННЯЯ СЕТКА, высоту которой
	задает ее содержимое. С `height: 100%` секция получала высоту МИНИМУМА
	дорожки уровня (~120 px), а блоки из нее вываливались наружу
	и наезжали на страницу.

	`:not(.st-section)` дает вес (0,3,0) и, что важнее, работает
	ДЕТЕРМИНИРОВАННО: спорить с ним нечему — правило к секции не относится.
	Свою нижнюю границу секция держит через `min-height` выше
*/
.st-page > .st-block:not(.st-section),
.st-chrome > .st-block:not(.st-section) {
	height: 100%;
}

/*
	СЕКЦИЯ ВО ВСЮ ШИРИНУ: без нее геройские секции с фоном невозможны —
	контент упирался бы в коробку страницы. Коробку задает ОТСТУП области,
	поэтому отменяется она отрицательным полем той же величины.
	Имеет смысл только у блока, занимающего весь уровень, — сервер и не
	ставит этот класс никому другому
*/
.st-block--full {
	margin-left: calc(-1 * var(--st-gutter, 0px));
	margin-right: calc(-1 * var(--st-gutter, 0px));
	padding-left: 0;
	padding-right: 0;
}

/*
	ТРИ УРОВНЯ ШИРИНЫ СТРАНИЦЫ — ЕДИНСТВЕННЫЙ ИСТОЧНИК РАЗМЕРОВ.
	Справочник в config.php хранит только названия и пояснения: числа —
	это оформление, и им место здесь. Уровень приходит атрибутом на корень.

	ВАЖНО: у «во всю ширину» значение 100%, а НЕ none — из него считается
	отступ коробки (`--st-gutter`), и `calc()` с `none` был бы невалиден,
	то есть коробка сломалась бы молча
*/
.st-site {
	--st-page: 1220px;
	/* БАЗОВАЯ ВЫСОТА ОДНОГО УРОВНЯ. Это МИНИМУМ строки, а не жесткий
	   размер: содержимое вправе быть выше (grid-auto-rows: minmax(...,auto)) */
	--st-level: 120px;
}

.st-site[data-st-page="narrow"] {
	--st-page: 1000px;
}

.st-site[data-st-page="wide"] {
	--st-page: 100%;
}

/* Контейнер своей ширины и своих колонок больше не держит: место блока
   целиком задано его прямоугольником в сетке области */
.st-container {
	width: 100%;
	min-width: 0;
}

/*
	ЦЕНТРИРОВАННЫЙ БЛОК — РОВНО ПО ЦЕНТРУ УРОВНЯ.

	Через стартовую колонку центр не выразить точно: колонка целая, а остаток
	уровня при нечетной разнице пополам не делится — блок шириной 11 из 12
	«по центру» прижимался бы влево на полколонки.

	Поэтому блок, стоящий на уровне ОДИН и выровненный по центру, занимает
	все двенадцать колонок, а его ширину задает процент от них: при нечетной
	ширине он честно встает на полуколонки. На этом же держится симметричное
	изменение ширины в редакторе.

	ТОЛЬКО ДЛЯ ОДИНОЧНОГО НА УРОВНЕ (шаг D): у блока с соседями место явное,
	и занимать ради центровки весь уровень он не вправе — сервер ставит этот
	класс, только когда `alone`
*/
.st-page > .st-block--center,
.st-chrome > .st-block--center {
	grid-column: 1 / span 12;
	width: calc(var(--st-span, 12) / 12 * 100%);
	margin-left: auto;
	margin-right: auto;
}

/*
	ВЫСОКИЙ БЛОК (levels > 1) РАСТЯГИВАЕТ СОДЕРЖИМОЕ.

	Уровни дают блоку высоту, но содержимое об этом не знает: картинка
	осталась бы своего размера, а под ней зияла бы пустота. Класс ставит
	сервер только растяжимым типам (`block_grow`), и только когда высота
	больше одного уровня — иначе `height: 100%` внутри строки, которая
	сама сжимается по содержимому, дал бы схлопывание в ноль
*/
/*
	РАСТЯЖЕНИЕ И ВЫРАВНИВАНИЕ — ВЗАИМОИСКЛЮЧАЮЩИ, и это осознанно:
	содержимое, растянутое на всю высоту, выравнивать не в чем. Поэтому
	`height: 100%` действует ТОЛЬКО при выравнивании по верху (умолчание);
	выбрав центр или низ, владелец говорит «оставь содержимому его высоту
	и прижми вот сюда» — и получает именно это
*/
.st-block--tall:not(.st-block--vcenter):not(.st-block--vbottom) > .st-container {
	height: 100%;
}

.st-block--tall:not(.st-block--vcenter):not(.st-block--vbottom) .st-media__item,
.st-block--tall:not(.st-block--vcenter):not(.st-block--vbottom) .st-media__grid,
.st-block--tall:not(.st-block--vcenter):not(.st-block--vbottom) .st-media,
.st-block--tall:not(.st-block--vcenter):not(.st-block--vbottom) .swiper,
.st-block--tall:not(.st-block--vcenter):not(.st-block--vbottom) .st-map {
	height: 100%;
}

/* Сетка кадров тянется вместе с блоком: без этого ряды остались бы
   своей высоты, а внизу зияла бы пустота */
.st-block--tall:not(.st-block--vcenter):not(.st-block--vbottom) .st-media__grid {
	grid-auto-rows: minmax(0, 1fr);
}

.st-block--tall:not(.st-block--vcenter):not(.st-block--vbottom) .st-media__item img,
.st-block--tall:not(.st-block--vcenter):not(.st-block--vbottom) .st-media__item video {
	height: 100%;
	object-fit: cover;
}

/* ==== РАЗДЕЛИТЕЛЬ ====================================================== */
/*
	Черта рисуется ВЕРХНЕЙ ГРАНИЦЕЙ, а не фоном: только так работают
	пунктир, точки и двойная линия одним свойством. Толщина, цвет, стиль
	и прозрачность приходят инлайном из настроек блока (это СОДЕРЖИМОЕ,
	общее для всех устройств), ширина и положение — из сетки выше
*/
.st-site .st-divider {
	width: 100%;
	height: 0;
	margin: 0;
	border: 0;
	border-top: 2px solid var(--st-border);
}

/* ==== ВИДИМОСТЬ ПО УСТРОЙСТВАМ ========================================= */
/*
	КЛАССОВ `st-hide-{устройство}` БОЛЬШЕ НЕТ — и это осознанное решение
	этапа B, а не потеря.

	Раньше блок выводился всегда, а прятал его медиазапрос. Теперь раскладку
	устройства собирает СЕРВЕР (websiteLayoutMerge = merge(base,
	overrides[device])): блок, скрытый на устройстве, в разметку просто
	не попадает. Так честнее (посетитель не качает лишнее) и, главное,
	ЭТО ЕДИНСТВЕННЫЙ СПОСОБ ПОКАЗАТЬ ПРАВДУ В КОНСТРУКТОРЕ: медиазапросы
	внутри узкого «листа» считаются от ОКНА БРАУЗЕРА и в мобильном
	предпросмотре не срабатывают вовсе.

	Точки перелома при этом остаются ОДНИМ набором на весь конструктор:
	>= 992 — ПК, 576…991 — планшет, < 576 — телефон. С ними согласованы
	ширины «листа» в steditor.css (820 px и 400 px)
*/

/* ==== АНИМАЦИЯ ПОЯВЛЕНИЯ ПРИ ПРОКРУТКЕ ================================= */
/*
	Класс `st-anim-in` вешает наблюдатель (steditor.js), когда секция
	попадает в кадр. УВАЖЕНИЕ К prefers-reduced-motion ОБЯЗАТЕЛЬНО:
	у посетителей, попросивших уменьшить анимацию, движения нет вовсе
	и блок сразу виден — правило в конце секции
*/
/*
	ВАЖНО: стартовое `opacity: 0` включается ТОЛЬКО когда наблюдатель
	действительно запущен (класс `st-anim-ready` на корне ставит JS).
	Иначе при неудачной загрузке скрипта — или на странице, где его
	еще нет, — блоки с анимацией остались бы навсегда невидимыми
*/
.st-anim-ready [data-st-anim] {
	opacity: 0;
	transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.2, 0.7, 0.3, 1);
	will-change: opacity, transform;
}

.st-anim-ready [data-st-anim="up"] { transform: translateY(28px); }
.st-anim-ready [data-st-anim="down"] { transform: translateY(-28px); }
.st-anim-ready [data-st-anim="left"] { transform: translateX(-28px); }
.st-anim-ready [data-st-anim="right"] { transform: translateX(28px); }
.st-anim-ready [data-st-anim="zoom"] { transform: scale(0.94); }

.st-anim-ready [data-st-anim].st-anim-in {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	.st-anim-ready [data-st-anim] {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}

	.st-site.st-bg-animate.st-bg-on::before {
		animation: none !important;
	}

	/*
		ПЕРВАЯ ВОЛНА БЛОКОВ (2026-08-10) уважает ту же просьбу: раскрытие
		аккордеона, поворот стрелки и отклик кнопки заявки — это движение,
		и посетителю, попросившему его уменьшить, оно не нужно.
		Само действие при этом РАБОТАЕТ: гасится анимация, а не поведение
	*/
	.st-faq__item[open] .st-faq__a {
		animation: none !important;
	}

	.st-faq__chevron,
	.st-lead__btn,
	.st-field__input {
		transition: none !important;
	}

	.st-lead__btn:active {
		transform: none !important;
	}

	/*
		==== ВТОРАЯ ВОЛНА (2026-08-13) ====

		ПРАВИЛО ЗДЕСЬ ГАСИТ ТОЛЬКО ПЕРЕХОДЫ. Главное — конечное состояние
		вместо движения — делает СКРИПТ, и иначе не выйдет:
		  ТАЙМЕР — цифры обновляются без анимации переворота, но тикать
		    продолжают: отсчет это не украшение, а данные;
		  СЧЕТЧИКИ — конечное число ставится сразу, счета от нуля нет вовсе.
		CSS про это ничего не знает, поэтому steditor.js проверяет
		prefers-reduced-motion сам (matchMedia) — вторая половина одного
		и того же правила
	*/
	.st-timer__btn,
	.st-cta__btn,
	.st-doc,
	.st-sbtn {
		transition: none !important;
	}

	.st-timer__btn:active,
	.st-cta__btn:active,
	.st-doc:hover,
	.st-sbtn:hover {
		transform: none !important;
	}

	.st-cta.st-bg-animate.st-bg-on::before {
		animation: none !important;
	}
}

.st-title {
	font-size: 24px;
	font-weight: 700;
	letter-spacing: -0.01em;
	margin-bottom: 16px;
}

.st-subtitle {
	color: var(--st-muted);
	font-size: 14px;
	margin-top: -10px;
	margin-bottom: 16px;
}

/* Пустое состояние внутри блока (нет данных источника) */
.st-empty {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 22px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
	color: var(--st-muted);
	font-size: 14px;
}

/* ======================================================================= */
/* ==== ПЕРВАЯ ВОЛНА БЛОКОВ ЛЕНДИНГА (2026-08-10) ======================== */
/* ======================================================================= */
/*
	ШЕСТЬ ТИПОВ: прайс, преимущества, этапы, отзывы, вопросы и форма заявки.

	ПРАВИЛА, ОБЩИЕ ДЛЯ ВСЕЙ ВОЛНЫ (не переигрывать в отдельном блоке):

	1) НИ ОДНОГО СОБСТВЕННОГО ЦВЕТА. Все берется из переменных темы
	   (--st-surface, --st-border, --st-text, --st-muted, --st-accent),
	   поэтому обе палитры — светлая и темная — работают сами собой,
	   без второго набора правил.

	2) ПЛОТНОСТЬ — ОДНА ОСЬ НА ВСЕ ШЕСТЬ (`--st-dense`): множитель
	   вертикальных отступов внутри блока. Компактный список и просторная
	   витрина отличаются ровно этим числом, а не своим набором размеров
	   у каждого типа.

	3) ВСЕ АНИМАЦИИ УВАЖАЮТ prefers-reduced-motion — правило в конце файла
	   гасит переходы безусловно
*/
.st-price,
.st-cards,
.st-steps,
.st-reviews,
.st-faq,
.st-lead {
	--st-dense: 1;
}

.st-price--compact,
.st-cards--compact,
.st-steps--compact,
.st-reviews--compact,
.st-faq--compact,
.st-lead--compact {
	--st-dense: 0.6;
}

/* ==== ПРАЙС / ТАБЛИЦА ================================================== */
/*
	ГОРИЗОНТАЛЬНЫЙ СКРОЛЛ — ОБЕРТКА, А НЕ САМА ТАБЛИЦА: прокручиваться
	обязана таблица целиком вместе с шапкой, а `overflow` на <table>
	браузеры трактуют по-разному.

	СКРОЛЛ ВКЛЮЧАЕТ КЛАСС, который ставит сервер по числу колонок и порогу
	владельца. Держать его всегда нельзя: `min-width` у таблицы растянул бы
	даже двухколоночный прайс и дал бы полосу прокрутки на пустом месте
*/
.st-price__scroll {
	width: 100%;
}

.st-price--scroll .st-price__scroll {
	overflow-x: auto;
	/* Инерционная прокрутка на тач-экранах и место под полосу, чтобы она
	   не наезжала на последнюю строку */
	-webkit-overflow-scrolling: touch;
	padding-bottom: 4px;
}

.st-price--scroll .st-price__table {
	/* Ширина колонки, ниже которой текст начинает рваться по символам.
	   Именно она и создает прокрутку, когда колонок много */
	min-width: calc(var(--st-price-cols, 4) * 140px);
}

.st-price__table {
	width: 100%;
	border-collapse: collapse;
	font-size: 15px;
	color: var(--st-text);
}

.st-price__cell {
	padding: calc(12px * var(--st-dense, 1)) 14px;
	border-bottom: 1px solid var(--st-border);
	vertical-align: middle;
}

.st-price__cell--left { text-align: left; }
.st-price__cell--center { text-align: center; }
.st-price__cell--right { text-align: right; }

.st-price thead .st-price__cell {
	font-weight: 700;
	white-space: nowrap;
	color: var(--st-text);
}

/* ПОДСВЕТКА ШАПКИ — отдельной настройкой: у прайса на цветном фоне секции
   серая плашка иногда лишняя */
.st-price--head thead .st-price__cell {
	background-color: var(--st-surface-alt);
}

.st-price--head thead .st-price__cell:first-child {
	border-top-left-radius: var(--st-radius-sm);
	border-bottom-left-radius: var(--st-radius-sm);
}

.st-price--head thead .st-price__cell:last-child {
	border-top-right-radius: var(--st-radius-sm);
	border-bottom-right-radius: var(--st-radius-sm);
}

/* ЗЕБРА СЧИТАЕТСЯ ПО ЧЕТНЫМ СТРОКАМ ТЕЛА, а не всей таблицы: иначе шапка
   сдвигала бы чередование на единицу */
.st-price--zebra tbody tr:nth-child(even) {
	background-color: var(--st-surface-alt);
}

.st-price tbody tr:last-child .st-price__cell {
	border-bottom: 0;
}

/* ==== ПРЕИМУЩЕСТВА ==================================================== */
/*
	СЕТКА КАРТОЧЕК. Число колонок приходит переменной `--st-cols` — той же,
	что у товаров и медиа: правило адаптива в проекте одно, и второго набора
	точек перелома для карточек быть не должно
*/
.st-cards {
	display: grid;
	gap: calc(16px * var(--st-dense, 1));
	grid-template-columns: repeat(var(--st-cols, 3), minmax(0, 1fr));
}

.st-card {
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: calc(20px * var(--st-dense, 1)) 20px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
	min-width: 0;
}

.st-cards--center .st-card { align-items: center; text-align: center; }
.st-cards--right .st-card { align-items: flex-end; text-align: right; }

.st-card__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 48px;
	height: 48px;
	border-radius: var(--st-radius-sm);
	/* Подложка значка — акцент темы с прозрачностью: так она остается
	   уместной и на светлой, и на темной палитре без второго цвета */
	background-color: color-mix(in srgb, var(--st-accent) 14%, transparent);
	color: var(--st-accent);
	font-size: 24px;
	flex: 0 0 auto;
}

/* СВОЙ SVG ВЫВОДИТСЯ КАРТИНКОЙ, а не встраиванием (встроенный SVG —
   вектор XSS), поэтому цветом темы он не красится: цвет задает сам файл */
.st-card__svg {
	max-width: 28px;
	max-height: 28px;
	object-fit: contain;
}

.st-card__title {
	font-size: 16px;
	font-weight: 700;
	color: var(--st-text);
}

.st-card__text {
	font-size: 14px;
	line-height: 1.55;
	color: var(--st-muted);
}

/* ==== ЭТАПЫ РАБОТЫ ==================================================== */
/*
	ДВЕ ОРИЕНТАЦИИ ОДНОЙ ЛЕНТЫ, и решает между ними СЕРВЕР (он знает
	устройство), а не медиазапрос: внутри узкого «листа» конструктора
	медиазапросы считаются от окна браузера и врут.

	СОЕДИНИТЕЛЬНАЯ ЛИНИЯ — псевдоэлемент шага, а не отдельный узел:
	у последнего шага ее быть не должно, и `:last-child` решает это
	без единой строки в разметке
*/
.st-steps {
	display: grid;
	gap: calc(18px * var(--st-dense, 1));
}

.st-steps--row {
	grid-template-columns: repeat(var(--st-cols, 4), minmax(0, 1fr));
}

.st-steps--column {
	grid-template-columns: minmax(0, 1fr);
}

.st-step {
	position: relative;
	display: flex;
	gap: 14px;
	min-width: 0;
}

/* В ЛЕНТЕ шаг раскладывается сверху вниз (номер над текстом), в столбце —
   слева направо (номер сбоку). Это не украшение: в строке номер сбоку
   съел бы половину узкой колонки */
.st-steps--row .st-step {
	flex-direction: column;
}

.st-steps--row.st-steps--center .st-step { align-items: center; text-align: center; }
.st-steps--row.st-steps--right .st-step { align-items: flex-end; text-align: right; }

/*
	==== ИНДИКАТОР ШАГА ПО МОТИВАМ METRONIC STEPPER (2026-08-14) ====

	ТРИ ОТЛИЧИЯ ОТ ПРЕЖНЕГО КРУЖКА, и все три взяты у степпера Метроника:
	  1) СВЕТЛОЕ КОЛЬЦО вокруг индикатора (`box-shadow`, а не `border`):
	     граница съела бы 8 px внутреннего диаметра, а тень рисуется
	     СНАРУЖИ коробки и геометрию не трогает — линия по-прежнему
	     дотягивается от края в 44 px;
	  2) ЦВЕТА ЧЕРЕЗ ПЕРЕМЕННЫЕ с умолчанием из темы: внутри секции
	     со своим фоном акцент темы может потеряться, и владелец обязан
	     иметь возможность перекрасить индикаторы, не трогая весь сайт;
	  3) ЛИНИЯ КРАСИТСЯ ОТДЕЛЬНОЙ переменной — в Метронике она заметно
	     светлее индикатора, и «одним цветом» это не выражается
*/
.st-steps {
	--st-step-mark: var(--st-accent);
	--st-step-ink: var(--st-accent-text);
	--st-step-line: var(--st-border);
}

.st-step__mark {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background-color: var(--st-step-mark);
	color: var(--st-step-ink);
	box-shadow: 0 0 0 4px color-mix(in srgb, var(--st-step-mark) 16%, transparent);
	font-size: 18px;
	font-weight: 700;
	flex: 0 0 auto;
	/* Кружок обязан лежать ПОВЕРХ соединительной линии — иначе она
	   просвечивала бы сквозь номер */
	position: relative;
	z-index: 1;
}

.st-step__svg {
	max-width: 24px;
	max-height: 24px;
	object-fit: contain;
}

.st-step__body {
	min-width: 0;
}

.st-step__title {
	font-size: 16px;
	font-weight: 700;
	color: var(--st-text);
	margin-bottom: 4px;
}

.st-step__text {
	font-size: 14px;
	line-height: 1.55;
	color: var(--st-muted);
}

/*
	ЛИНИЯ МЕЖДУ ШАГАМИ. Тянется от кружка ВПРАВО (в ленте) или ВНИЗ
	(в столбце) до следующего шага. Ширина зазора взята из `gap` той же
	формулой — иначе линия не дотягивалась бы при смене плотности
*/
.st-steps--line .st-step:not(:last-child)::after {
	content: '';
	position: absolute;
	background-color: var(--st-step-line);
}

.st-steps--line.st-steps--row .st-step:not(:last-child)::after {
	top: 21px;
	left: 44px;
	height: 2px;
	width: calc(100% - 44px + 18px * var(--st-dense, 1));
}

/* В ленте с центрированным содержимым кружок стоит посередине колонки,
   и линия обязана идти от его центра, а не от левого края */
.st-steps--line.st-steps--row.st-steps--center .st-step:not(:last-child)::after {
	left: calc(50% + 22px);
	width: calc(50% - 22px + 18px * var(--st-dense, 1) + 50% - 22px);
}

.st-steps--line.st-steps--column .st-step:not(:last-child)::after {
	left: 21px;
	top: 44px;
	width: 2px;
	height: calc(100% - 44px + 18px * var(--st-dense, 1));
}

/*
	==== ПОЯВЛЕНИЕ ШАГОВ ПО ОЧЕРЕДИ (2026-08-14) ====

	СМЫСЛ, А НЕ УКРАШЕНИЕ: последовательность шагов и читается
	последовательно. Одновременное появление всех четырех эту
	последовательность гасит — они превращаются в четыре равноправные
	карточки.

	СТАРТОВОЕ СОСТОЯНИЕ СТАВИТСЯ ТОЛЬКО ПРИ КЛАССЕ `--anim` И ТОЛЬКО ДО
	ПРИХОДА НАБЛЮДАТЕЛЯ. Без второго условия шаги остались бы невидимыми
	навсегда там, где IntersectionObserver недоступен, — поэтому класс
	`st-steps--on` ставит скрипт, а не CSS.

	ЗАДЕРЖКА — ПЕРЕМЕННОЙ С САМОГО ШАГА (`--st-step-delay`, печатает
	сервер): классов на каждый номер пришлось бы завести конечное число,
	а шагов у владельца может быть сколько угодно
*/
.st-steps--anim .st-step {
	opacity: 0;
	transform: translateY(12px);
	transition: opacity 0.45s ease, transform 0.45s ease;
	transition-delay: var(--st-step-delay, 0ms);
}

.st-steps--anim.st-steps--on .st-step {
	opacity: 1;
	transform: none;
}

/*
	==== ПРОСЬБУ УМЕНЬШИТЬ ДВИЖЕНИЕ СЛУШАЕМ БЕЗУСЛОВНО ====

	И ГЛАВНОЕ — КОНЕЧНОЕ СОСТОЯНИЕ ЗДЕСЬ ЖЕ, а не только в скрипте:
	погасить переход и оставить `opacity: 0` значило бы спрятать блок
	от того, кто попросил всего лишь не двигать его
*/
@media (prefers-reduced-motion: reduce) {
	.st-steps--anim .st-step {
		opacity: 1 !important;
		transform: none !important;
		transition: none !important;
	}
}

/* ==== ОТЗЫВЫ ========================================================== */

.st-reviews__grid {
	display: grid;
	gap: calc(16px * var(--st-dense, 1));
	grid-template-columns: repeat(var(--st-cols, 3), minmax(0, 1fr));
}

.st-review {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: calc(20px * var(--st-dense, 1)) 20px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
	min-width: 0;
	/* В КАРУСЕЛИ КАРТОЧКИ РАЗНОЙ ДЛИНЫ выравниваются по высоте слайда:
	   иначе лента отзывов выглядит рваной снизу */
	height: 100%;
}

.st-reviews--center .st-review { text-align: center; align-items: center; }
.st-reviews--right .st-review { text-align: right; align-items: flex-end; }

.st-review__head {
	display: flex;
	align-items: center;
	gap: 12px;
	min-width: 0;
}

.st-review__photo {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	overflow: hidden;
	background-color: var(--st-surface-alt);
	color: var(--st-muted);
	font-size: 18px;
	font-weight: 700;
	flex: 0 0 auto;
}

.st-review__photo img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.st-review__who {
	display: flex;
	flex-direction: column;
	min-width: 0;
}

.st-review__name {
	font-size: 15px;
	font-weight: 700;
	color: var(--st-text);
}

.st-review__date {
	font-size: 12px;
	color: var(--st-muted);
}

.st-review__rating {
	display: flex;
	gap: 2px;
	font-size: 15px;
	/* Незаполненная звезда — приглушенная, а не пустая: контур на цветном
	   фоне секции почти не читается */
	color: color-mix(in srgb, var(--st-muted) 40%, transparent);
}

.st-review__star--on {
	color: var(--st-accent);
}

.st-review__text {
	font-size: 14px;
	line-height: 1.6;
	color: var(--st-text);
}

/* ==== FAQ / АККОРДЕОН ================================================== */
/*
	РАСКРЫТИЕ ДЕРЖИТСЯ НА <details>/<summary> — без единой строки скрипта.
	Блок обязан работать на публичной странице ДО загрузки JS и оставаться
	доступным с клавиатуры; браузер дает и то и другое бесплатно.

	СТРЕЛКА-МАРКЕР БРАУЗЕРА УБИРАЕТСЯ (`::-webkit-details-marker` и
	`list-style`) — она выглядит по-разному в каждой системе, а блок обязан
	быть одинаковым у всех
*/
.st-faq {
	display: flex;
	flex-direction: column;
	gap: calc(10px * var(--st-dense, 1));
}

.st-faq__item {
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	overflow: hidden;
}

.st-faq__q {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: calc(16px * var(--st-dense, 1)) 18px;
	cursor: pointer;
	font-size: 16px;
	font-weight: 600;
	color: var(--st-text);
	list-style: none;
	user-select: none;
}

.st-faq__q::-webkit-details-marker {
	display: none;
}

.st-faq__text {
	min-width: 0;
}

.st-faq__chevron {
	flex: 0 0 auto;
	font-size: 14px;
	color: var(--st-muted);
	transition: transform 0.2s ease;
}

.st-faq__item[open] .st-faq__chevron {
	transform: rotate(180deg);
}

.st-faq__a {
	padding: 0 18px calc(16px * var(--st-dense, 1));
	font-size: 14px;
	line-height: 1.65;
	color: var(--st-muted);
}

/*
	ПЛАВНОЕ РАСКРЫТИЕ. `interpolate-size` и `transition` по `content-visibility`
	поддержаны не везде, поэтому анимируется только ПОЯВЛЕНИЕ содержимого —
	это работает во всех браузерах и деградирует в мгновенное раскрытие,
	а не в поломку
*/
.st-faq__item[open] .st-faq__a {
	animation: stFaqOpen 0.22s ease;
}

@keyframes stFaqOpen {
	from { opacity: 0; transform: translateY(-6px); }
	to { opacity: 1; transform: none; }
}

/* ==== ФОРМА ЗАЯВКИ ==================================================== */

.st-lead {
	display: flex;
	flex-direction: column;
	gap: calc(14px * var(--st-dense, 1));
	padding: calc(24px * var(--st-dense, 1)) 24px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
}

.st-lead--center { text-align: center; }
.st-lead--right { text-align: right; }

.st-lead__title {
	font-size: 22px;
	font-weight: 700;
	color: var(--st-text);
}

.st-lead__subtitle {
	font-size: 14px;
	line-height: 1.55;
	color: var(--st-muted);
	margin-top: -8px;
}

.st-lead__form {
	display: flex;
	flex-direction: column;
	gap: calc(12px * var(--st-dense, 1));
	/* Форма всегда выровнена по левому краю, даже когда заголовок по центру:
	   поля ввода, разъехавшиеся по краям, заполнять невозможно */
	text-align: left;
}

.st-field {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.st-field__label {
	font-size: 13px;
	font-weight: 600;
	color: var(--st-text);
}

.st-field__req {
	color: var(--st-danger);
	margin-left: 2px;
}

.st-field__input {
	width: 100%;
	padding: 11px 14px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-bg);
	color: var(--st-text);
	font-family: inherit;
	font-size: 15px;
	outline: none;
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

/*
	==== ФОКУС БЕЗ «ПРИЗРАЧНОЙ ПОДСВЕТКИ» (2026-08-21) ====

	БЫЛО: `box-shadow: 0 0 0 3px` акцентом с прозрачностью — трехпиксельное
	цветное гало вокруг поля. На светлой теме оно читалось как размытая
	тень, на темной — как свечение, и в обоих случаях спорило с аккуратной
	рамкой самого поля.

	СТАЛО: фокус показывают ТРИ ТИХИХ ИЗМЕНЕНИЯ вместо одного громкого —
	рамка становится акцентной, фон чуть светлее (поле «поднимается»
	над формой) и появляется тонкая внутренняя линия в цвет акцента.
	`inset` принципиален: тень внутри поля не может задеть соседей
	и не создает ореола на любом фоне.

	ОТДЕЛЬНО ПРО ДОСТУПНОСТЬ. Убрать видимый фокус нельзя — им пользуются
	с клавиатуры; поэтому изменение остается ЗАМЕТНЫМ (рамка + фон),
	просто перестает быть свечением
*/
.st-field__input:focus {
	border-color: var(--st-accent);
	background-color: var(--st-surface);
	box-shadow: inset 0 0 0 1px var(--st-accent);
}

/*
	==== ТЕКСТОВАЯ ОБЛАСТЬ РАСТЕТ САМА (2026-08-21) ====

	РУЧКА В УГЛУ УБРАНА (`resize: none`), и это половина решения: без
	второй половины поле упиралось бы во внутреннюю прокрутку. Высоту
	по содержимому считает `autoSize()` в stsite.js.

	ПОТОЛОК ОСТАЕТСЯ: вставленная простыня текста иначе растянула бы форму
	на три экрана, и кнопка отправки уехала бы за край. Дойдя до потолка,
	поле честно включает свою прокрутку — но это уже осознанный предел,
	а не стартовое состояние
*/
.st-field__input--area {
	resize: none;
	overflow-y: auto;
	min-height: 84px;
	max-height: 340px;
}

/*
	ЛОВУШКА ДЛЯ РОБОТОВ. Спрятана КЛАССОМ, а не атрибутом `hidden`
	и не инлайновым `display: none`: робот читает разметку, и явно скрытое
	поле он пропустит, а поле с невинным именем заполнит.
	`position: absolute` + вынос за экран — способ, который не отключает
	поле для автозаполнения и не ломает раскладку формы
*/
.st-lead__trap {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
	opacity: 0;
	pointer-events: none;
}

/*
	==== ФЛАЖОК — СВОЙ, А НЕ СИСТЕМНЫЙ (2026-08-21) ====

	БЫЛО: обычный `<input type="checkbox">` с `accent-color`. Этого мало,
	и вот почему: `accent-color` красит ТОЛЬКО заливку, а форму, размер,
	скругление и галочку по-прежнему рисует операционная система —
	в Windows это резкий синеватый квадрат с тонкой галочкой, на macOS
	другой, на Android третий. Рядом с полями сайта, у которых свои
	скругления и своя палитра, он читается как чужой элемент.

	ВИД ВЗЯТ У ФЛАЖКОВ СЕРВИСА (Metronic `form-check-custom
	form-check-solid`): скругленный квадрат 20 px, в отмеченном
    состоянии — заливка акцентом и белая галочка.

	ГАЛОЧКА — ФОНОВЫЙ SVG, А НЕ ШРИФТ И НЕ ПСЕВДОЭЛЕМЕНТ С РАМКАМИ.
	Шрифта значков у флажка может не быть (он рисуется до загрузки),
	а «галочка из двух рамок» разъезжается при масштабировании страницы.
	SVG в `data:` не требует ни запроса, ни шрифта.

	ФОКУС — ТОТ ЖЕ, ЧТО У ПОЛЕЙ: внутренняя линия акцентом, без гало
*/
.st-check {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	cursor: pointer;
}

.st-check__box {
	appearance: none;
	-webkit-appearance: none;
	flex: 0 0 auto;
	width: 20px;
	height: 20px;
	margin-top: 1px;
	border: 1px solid var(--st-border);
	border-radius: 6px;
	background-color: var(--st-bg);
	background-position: center;
	background-repeat: no-repeat;
	background-size: 12px 12px;
	cursor: pointer;
	transition: background-color 0.15s ease, border-color 0.15s ease;
}

.st-check__box:hover {
	border-color: var(--st-accent);
}

.st-check__box:checked {
	border-color: var(--st-accent);
	background-color: var(--st-accent);
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 8.6l3.6 3.6 7.4-8.4'/%3E%3C/svg%3E");
}

.st-check__box:focus-visible {
	outline: none;
	border-color: var(--st-accent);
	box-shadow: inset 0 0 0 1px var(--st-accent);
}

.st-check__text {
	font-size: 13px;
	line-height: 1.5;
	color: var(--st-muted);
}

.st-check__link {
	color: var(--st-accent);
	text-decoration: underline;
}

.st-lead__btn {
	align-self: flex-start;
	padding: 12px 26px;
	border: 0;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-accent);
	color: var(--st-accent-text);
	font-family: inherit;
	font-size: 15px;
	font-weight: 700;
	cursor: pointer;
	transition: filter 0.15s ease, transform 0.15s ease;
}

.st-lead__btn:hover {
	filter: brightness(1.06);
}

.st-lead__btn:active {
	transform: translateY(1px);
}

.st-lead__btn:disabled {
	opacity: 0.6;
	cursor: default;
}

/*
	==== ПУСТАЯ ЗАМЕТКА НЕ ЗАНИМАЕТ МЕСТА ====
	(правка 2026-08-14)

	БЫЛО: `min-height: 20px` резервировал место под ответ ЗАРАНЕЕ, чтобы
	сообщение об ошибке не сдвигало кнопку под пальцем. Цена — постоянная
	пустая полоса под кнопкой на КАЖДОЙ форме, которую никто ни разу
	не отправлял (то есть в конструкторе — всегда).

	СТАЛО: пустой узел выключен из потока целиком (`:empty`), а от прыжка
	кнопки страхует не пустота, а `scroll-margin`-подобный прием
	не нужен вовсе: заметка стоит ПОД кнопкой и растет ВНИЗ — кнопка
	остается на месте, двигается только то, что ниже нее.

	`:empty` СЧИТАЕТ И ПРОБЕЛЫ: узел рисуется шаблоном БЕЗ переноса строки
	внутри (`<div …></div>`), и скрипт кладет в него текст через
	`textContent` — лишнего текстового узла там не появляется
*/
.st-lead__note {
	font-size: 13px;
	line-height: 1.4;
}

.st-lead__note:empty {
	display: none;
}

.st-lead__note--ok { color: var(--st-accent); }
.st-lead__note--bad { color: var(--st-danger); }

/* Пометка тестового режима: видна только в конструкторе (шаблон рисует ее,
   пока страница не публичная) */
.st-lead__preview {
	font-size: 12px;
	color: var(--st-muted);
	border-top: 1px dashed var(--st-border);
	padding-top: 10px;
}

/* ======================================================================= */
/* ==== ВТОРАЯ ВОЛНА БЛОКОВ ЛЕНДИНГА (2026-08-13) ======================== */
/* ======================================================================= */
/*
	ШЕСТЬ ТИПОВ: таймер акции, до/после, счетчики, CTA-баннер, сертификаты
	и соц-кнопки.

	ПРАВИЛА ТЕ ЖЕ, ЧТО У ПЕРВОЙ ВОЛНЫ, и переигрывать их в отдельном блоке
	нельзя:

	1) НИ ОДНОГО СОБСТВЕННОГО ЦВЕТА — все из переменных темы. Единственное
	   исключение — CTA-баннер поверх фотографии или видео: там текст белый,
	   и это не вопрос вкуса (цвет темы на кадре пропадает).

	2) ПЛОТНОСТЬ — та же ось `--st-dense`.

	3) ДВИЖЕНИЕ ЖИВЕТ ТОЛЬКО В ЗОНЕ ВИДИМОСТИ, а prefers-reduced-motion
	   выдает конечное состояние сразу (правило в конце файла)
*/
.st-timer,
.st-compare,
.st-counters,
.st-cta,
.st-docs,
.st-socials-row {
	--st-dense: 1;
}

.st-timer--compact,
.st-compare--compact,
.st-counters--compact,
.st-cta--compact,
.st-docs--compact,
.st-socials-row--compact {
	--st-dense: 0.6;
}

/* ==== ТАЙМЕР АКЦИИ ===================================================== */

/*
	==== КАСТОМИЗАЦИЯ ТАЙМЕРА (2026-08-14) ====

	ПЕРЕМЕННЫЕ С УМОЛЧАНИЕМ ИЗ ТЕМЫ. Пустая настройка переменную
	не печатает, и работает значение отсюда — таймер следует за палитрой
	сайта сам, без единой правки. Заданная владельцем — перебивает.

	СВОЙ ФОН У БЛОКА — теми же пятью типами, что у сайта, секции
	и CTA-баннера (`st-bg-on` + слои `::before/::after`), поэтому таймеру
	нужен `position: relative` и подъем содержимого над слоями
*/
.st-timer {
	--st-timer-plate: var(--st-surface);
	--st-timer-border: var(--st-border);
	--st-timer-num: var(--st-text);
	--st-timer-label: var(--st-muted);
	--st-timer-title: var(--st-text);
	--st-timer-subtitle: var(--st-muted);
	--st-timer-radius: var(--st-radius);

	position: relative;
	display: flex;
	flex-direction: column;
	gap: calc(14px * var(--st-dense, 1));
	align-items: center;
}

/* Свой фон блока: слои лежат внутри коробки таймера, а не секции —
   иначе они закрасили бы весь прямоугольник блока на сетке */
.st-timer.st-bg-on {
	padding: calc(24px * var(--st-dense, 1));
	border-radius: var(--st-radius);
	overflow: hidden;
	background-color: transparent;
}

.st-timer.st-bg-on::before,
.st-timer.st-bg-on::after {
	content: '';
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.st-timer.st-bg-on::before { z-index: 0; }
.st-timer.st-bg-on::after { z-index: 1; }

/*
	СОДЕРЖИМОЕ НАД СЛОЯМИ ФОНА.

	РАМКА ВИДЕО И ПАТТЕРН ИСКЛЮЧЕНЫ ЯВНО: это САМИ слои фона, и подними
	их до третьего уровня — кадр видео лег бы поверх цифр таймера.
	Свой z-index у них уже задан (0 и 2)
*/
.st-timer.st-bg-on > *:not(.st-bg-frame):not(.st-bg-pattern) {
	position: relative;
	z-index: 3;
}

.st-timer.st-bg-animate.st-bg-on::before {
	animation: stBgShift var(--st-bg-speed, 12s) ease infinite;
}

@media (max-width: 767.98px) {
	.st-timer.st-bg-animate-desktop.st-bg-on::before {
		animation: none;
	}
}

.st-timer--left { align-items: flex-start; text-align: left; }
.st-timer--center { align-items: center; text-align: center; }
.st-timer--right { align-items: flex-end; text-align: right; }

.st-timer__title {
	font-size: 24px;
	font-weight: 700;
	line-height: 1.25;
	color: var(--st-timer-title);
}

.st-timer__subtitle {
	font-size: 15px;
	line-height: 1.55;
	color: var(--st-timer-subtitle);
	max-width: 620px;
}

.st-timer__plates {
	display: flex;
	flex-wrap: wrap;
	align-items: stretch;
	gap: calc(12px * var(--st-dense, 1));
}

/* ВЫРАВНИВАНИЕ РЯДА ПЛАШЕК ЗАДАЕТСЯ ЯВНО, а не наследуется от обертки:
   `justify-content: inherit` у колонки-родителя означало бы «прижать
   по вертикали», то есть совсем не то, что просил владелец */
.st-timer--left .st-timer__plates { justify-content: flex-start; }
.st-timer--center .st-timer__plates { justify-content: center; }
.st-timer--right .st-timer__plates { justify-content: flex-end; }

/*
	ПЛАШКА — КОЛОНКА ФИКСИРОВАННОЙ ШИРИНЫ.

	Ширина задана НЕ ради красоты: цифра меняется каждую секунду, и без нее
	«9» и «10» перекраивали бы всю строку на каждом тике. По той же причине
	шаблон печатает часы, минуты и секунды с ведущим нулем
*/
.st-timer__plate {
	position: relative;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	min-width: 74px;
	padding: calc(14px * var(--st-dense, 1)) 12px;
	border: 1px solid var(--st-timer-border);
	border-radius: var(--st-timer-radius);
	background-color: var(--st-timer-plate);
}

/*
	==== РАЗДЕЛИТЕЛЬ МЕЖДУ ПЛАШКАМИ (2026-08-14) ====

	ПСЕВДОЭЛЕМЕНТ, А НЕ УЗЕЛ В РАЗМЕТКЕ: набор плашек зависит от настроек
	(дни и секунды отключаемы), и вставлять разделители в шаблон значило бы
	считать, между какими именно плашками они нужны, и не поставить лишний
	после последней. `:last-child` решает это без единой строки в PHP.

	Разделитель ЖИВЕТ В ЗАЗОРЕ (`gap`), поэтому позиционируется за правой
	границей плашки на половину зазора — при любой плотности
*/
.st-timer--sep-colon .st-timer__plate:not(:last-child)::after,
.st-timer--sep-dot .st-timer__plate:not(:last-child)::after {
	position: absolute;
	top: calc(14px * var(--st-dense, 1));
	right: calc(-6px * var(--st-dense, 1));
	transform: translateX(50%);
	color: var(--st-timer-label);
	font-weight: 700;
	line-height: 1.05;
	/* КЕГЛЬ ПОВТОРЯЕТ ЦИФРУ, а не наследуется: наследование дало бы
	   размер текста страницы (16px), и разделитель терялся бы рядом
	   с 34-пиксельным числом */
	font-size: 30px;
	pointer-events: none;
}

.st-timer--sm .st-timer__plate:not(:last-child)::after { font-size: 22px; }
.st-timer--lg .st-timer__plate:not(:last-child)::after { font-size: 40px; }

.st-timer--sep-colon .st-timer__plate:not(:last-child)::after { content: ':'; }
.st-timer--sep-dot .st-timer__plate:not(:last-child)::after { content: '·'; }

/* БЕЗ ПЛАШЕК — только цифры: подложка и рамка снимаются, отступы остаются
   минимальными, чтобы строка не разъезжалась */
.st-timer--flat .st-timer__plate {
	min-width: 62px;
	padding: 0 4px;
	border: 0;
	background-color: transparent;
}

.st-timer__num {
	font-size: 34px;
	font-weight: 800;
	line-height: 1.05;
	color: var(--st-timer-num);
	/* ЦИФРЫ ОДНОЙ ШИРИНЫ: без этого «11» и «17» занимают разное место,
	   и число дергается внутри плашки раз в секунду */
	font-variant-numeric: tabular-nums;
	font-feature-settings: 'tnum';
}

.st-timer--sm .st-timer__num { font-size: 26px; }
.st-timer--lg .st-timer__num { font-size: 46px; }

.st-timer--sm .st-timer__plate { min-width: 62px; }
.st-timer--lg .st-timer__plate { min-width: 92px; }

.st-timer__label {
	font-size: 12px;
	line-height: 1.2;
	color: var(--st-timer-label);
	text-transform: lowercase;
}

/*
	ТЕКСТ ЗАВЕРШЕНИЯ ЛЕЖИТ В РАЗМЕТКЕ ВСЕГДА, видимость решает класс.
	Собирать его из JS значило бы держать копию верстки в скрипте — и получить
	пустое место, если скрипт не загрузился
*/
.st-timer__over { display: none; }

.st-timer--done .st-timer__plates { display: none; }

.st-timer--done .st-timer__over {
	display: block;
	font-size: 20px;
	font-weight: 700;
	color: var(--st-text);
	padding: calc(16px * var(--st-dense, 1)) 20px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius);
}

.st-timer__btn {
	display: inline-block;
	padding: 12px 26px;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-accent);
	color: var(--st-accent-text);
	font-size: 15px;
	font-weight: 600;
	text-decoration: none;
	transition: filter 0.15s ease, transform 0.12s ease;
}

.st-timer__btn:hover { filter: brightness(1.08); }
.st-timer__btn:active { transform: translateY(1px); }

/* ==== ДО / ПОСЛЕ ======================================================= */
/*
	ВЕРХНИЙ КАДР ОБРЕЗАЕТСЯ `clip-path`, А НЕ ШИРИНОЙ ОБЕРТКИ, и это
	несущее решение. Классический прием «обертка с overflow: hidden» требует,
	чтобы картинка ВНУТРИ нее знала ширину ВСЕГО кадра, — а ее без замера
	на клиенте не получить, и повторять замер пришлось бы на каждое изменение
	размера окна. `clip-path: inset()` считает от собственной коробки
	элемента: обе картинки остаются одного размера и совмещены пиксель
	в пиксель без единой строки измерений
*/
.st-compare {
	position: relative;
	width: 100%;
	aspect-ratio: var(--st-compare-ratio, 16 / 9);
	overflow: hidden;
	border-radius: var(--st-radius);
	background-color: var(--st-surface-alt);
	/* Палец, тянущий разделитель, не должен прокручивать страницу */
	touch-action: none;
	user-select: none;
	-webkit-user-select: none;
}

.st-compare__pane {
	position: absolute;
	inset: 0;
	display: block;
}

.st-compare__pane--before {
	clip-path: inset(0 calc(100% - var(--st-compare-pos, 50%)) 0 0);
}

.st-compare__img {
	display: block;
	width: 100%;
	height: 100%;
	/* БЕЗ ИСКАЖЕНИЙ: кадр вписывается по большей стороне и обрезается,
	   а не растягивается под коробку */
	object-fit: cover;
	object-position: center;
	pointer-events: none;
}

.st-compare__tag {
	position: absolute;
	top: 12px;
	padding: 5px 12px;
	border-radius: 999px;
	background-color: rgba(12, 16, 24, 0.62);
	color: #FFFFFF;
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.02em;
}

.st-compare__tag--before { left: 12px; }
.st-compare__tag--after { right: 12px; }

.st-compare__line {
	position: absolute;
	top: 0;
	bottom: 0;
	left: var(--st-compare-pos, 50%);
	width: 2px;
	margin-left: -1px;
	background-color: #FFFFFF;
	box-shadow: 0 0 0 1px rgba(12, 16, 24, 0.25);
	pointer-events: none;
}

/*
	РУЧКА — НАСТОЯЩИЙ ЭЛЕМЕНТ УПРАВЛЕНИЯ: свой фокус, роль ползунка
	и значение. Без нее блок был бы недоступен всем, кто не пользуется мышью
*/
.st-compare__handle {
	position: absolute;
	top: 50%;
	left: var(--st-compare-pos, 50%);
	width: 46px;
	height: 46px;
	margin: -23px 0 0 -23px;
	border-radius: 999px;
	background-color: #FFFFFF;
	box-shadow: 0 4px 16px rgba(12, 16, 24, 0.28);
	cursor: ew-resize;
	touch-action: none;
	display: flex;
	align-items: center;
	justify-content: center;
}

.st-compare__handle:focus-visible {
	outline: 3px solid var(--st-accent);
	outline-offset: 2px;
}

.st-compare__grip {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 1px;
	color: #1B1F27;
	font-size: 13px;
	pointer-events: none;
}

/* KeenIcons навязывает значкам свой цвет правилом в конце plugins.bundle.css,
   и оно бьет по самому <i>. Те же грабли, что у карточки ассистента */
.st-compare__grip i { color: inherit; }

/* ==== СЧЕТЧИКИ ========================================================= */

.st-counters {
	display: grid;
	grid-template-columns: repeat(var(--st-cols, 4), minmax(0, 1fr));
	gap: calc(18px * var(--st-dense, 1));
}

.st-counters--left { text-align: left; }
.st-counters--center { text-align: center; }
.st-counters--right { text-align: right; }

.st-counter {
	display: flex;
	flex-direction: column;
	gap: 6px;
	padding: calc(20px * var(--st-dense, 1)) 16px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
}

.st-counters--center .st-counter { align-items: center; }
.st-counters--right .st-counter { align-items: flex-end; }

.st-counter__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 44px;
	height: 44px;
	border-radius: 999px;
	background-color: var(--st-surface-alt);
	color: var(--st-accent);
	font-size: 20px;
	margin-bottom: 4px;
}

.st-counter__icon i { color: inherit; }

.st-counter__svg {
	display: block;
	width: 24px;
	height: 24px;
	object-fit: contain;
}

.st-counter__value {
	display: flex;
	align-items: baseline;
	gap: 4px;
	color: var(--st-text);
	font-size: 34px;
	font-weight: 800;
	line-height: 1.1;
}

.st-counters--center .st-counter__value { justify-content: center; }
.st-counters--right .st-counter__value { justify-content: flex-end; }

.st-counter__num {
	/* Цифры одной ширины: иначе число прыгает по ширине на каждом кадре
	   анимации — та же причина, что у плашек таймера */
	font-variant-numeric: tabular-nums;
	font-feature-settings: 'tnum';
}

.st-counter__fix {
	font-size: 20px;
	font-weight: 700;
	color: var(--st-accent);
}

.st-counter__label {
	font-size: 14px;
	line-height: 1.45;
	color: var(--st-muted);
}

/* ==== CTA-БАННЕР ======================================================= */
/*
	СОБСТВЕННЫЙ ФОН ТЕХ ЖЕ ПЯТИ ТИПОВ, что у сайта и секции: слои рисуются
	псевдоэлементами `::before` (фон) и `::after` (затемнение), правила
	значений собирает steditorBackgroundCss(). Здесь только геометрия слоев —
	пара к правилам секции выше
*/
.st-cta {
	position: relative;
	overflow: hidden;
	border-radius: var(--st-radius);
	border: 1px solid var(--st-border);
	background-color: var(--st-surface);
	padding: calc(34px * var(--st-dense, 1)) 30px;
}

.st-cta--sm { padding: calc(22px * var(--st-dense, 1)) 24px; }
.st-cta--lg { padding: calc(56px * var(--st-dense, 1)) 36px; }

/* ФОН ЕСТЬ — СВОЯ РАМКА НЕ НУЖНА: она резала бы кадр тонкой светлой
   полоской по периметру */
.st-cta.st-bg-on { border-color: transparent; }

.st-cta.st-bg-on::before,
.st-cta.st-bg-on::after {
	content: '';
	position: absolute;
	inset: 0;
	pointer-events: none;
}

.st-cta.st-bg-on::before { z-index: 0; }
.st-cta.st-bg-on::after { z-index: 1; }

/* Содержимое — НАД слоями фона (пара к правилам корня сайта и секции) */
.st-cta__body {
	position: relative;
	z-index: 3;
	display: flex;
	flex-direction: column;
	gap: calc(12px * var(--st-dense, 1));
	align-items: center;
	text-align: center;
}

.st-cta--left .st-cta__body { align-items: flex-start; text-align: left; }
.st-cta--right .st-cta__body { align-items: flex-end; text-align: right; }

.st-cta.st-bg-animate.st-bg-on::before {
	animation: st-bg-move var(--st-bg-speed, 12s) ease infinite;
}

.st-cta__title {
	font-size: 28px;
	font-weight: 800;
	line-height: 1.2;
	color: var(--st-cta-fg, var(--st-text));
}

.st-cta--sm .st-cta__title { font-size: 22px; }
.st-cta--lg .st-cta__title { font-size: 36px; }

.st-cta__text {
	font-size: 16px;
	line-height: 1.6;
	max-width: 720px;
	color: var(--st-cta-muted, var(--st-muted));
}

.st-cta__btn {
	display: inline-block;
	margin-top: 4px;
	padding: 13px 30px;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-accent);
	color: var(--st-accent-text);
	font-size: 15px;
	font-weight: 600;
	text-decoration: none;
	transition: filter 0.15s ease, transform 0.12s ease;
}

.st-cta__btn:hover { filter: brightness(1.08); }
.st-cta__btn:active { transform: translateY(1px); }

/*
	ТЕКСТ НА МЕДИА-ФОНЕ БЕЛЫЙ, И ЭТО НЕ ВОПРОС ВКУСА: на фотографии укладки
	или кадре видео темный текст темы пропадает. Затемняющий слой при этом
	обязателен и не слабее 20% — его плотность собирает шаблон
*/
.st-cta--ink {
	--st-cta-fg: #FFFFFF;
	--st-cta-muted: rgba(255, 255, 255, 0.82);
}

.st-cta--ink .st-cta__btn {
	background-color: #FFFFFF;
	color: #1B1F27;
}

/* ==== СЕРТИФИКАТЫ И ДОКУМЕНТЫ ========================================== */

.st-docs {
	display: grid;
	grid-template-columns: repeat(var(--st-cols, 4), minmax(0, 1fr));
	gap: calc(16px * var(--st-dense, 1));
}

.st-doc {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: calc(12px * var(--st-dense, 1));
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
	color: var(--st-text);
	text-decoration: none;
	transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

.st-doc:hover {
	border-color: var(--st-accent);
	transform: translateY(-2px);
	box-shadow: var(--st-shadow);
}

/* ОБЛОЖКА ФИКСИРОВАННОГО СООТНОШЕНИЯ: сканы сертификатов приходят разной
   высоты, и без общей коробки сетка карточек шла бы ступенькой */
.st-doc__cover {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 3 / 4;
	overflow: hidden;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface-alt);
}

.st-doc__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* PDF ОБЛОЖКИ НЕ ИМЕЕТ — взять ее неоткуда без рендера первой страницы,
   а он делается на сервере и стоит дороже, чем помогает. Вместо нее значок */
.st-doc__glyph {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: 100%;
	color: var(--st-muted);
	font-size: 44px;
}

.st-doc__glyph i { color: inherit; }

.st-doc__badge {
	position: absolute;
	left: 8px;
	bottom: 8px;
	padding: 3px 9px;
	border-radius: 999px;
	background-color: rgba(12, 16, 24, 0.68);
	color: #FFFFFF;
	font-size: 11px;
	font-weight: 700;
	letter-spacing: 0.04em;
}

.st-doc__body {
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-width: 0;
}

.st-doc__name {
	font-size: 14px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--st-text);
}

.st-doc__desc {
	font-size: 12px;
	line-height: 1.45;
	color: var(--st-muted);
}

/*
	==== ВСТРОЕННЫЙ ПРОСМОТРЩИК PDF ====

	Живет ВНУТРИ корня сайта (`.st-site`), а не в теле страницы: так он
	красится переменными темы сайта и одинаково работает в конструкторе
	и на будущей публичной странице. Разметку создает steditor.js, а размеры
	и цвета — здесь.

	z-index выше окна Bootstrap (1055) и открытого select2 (2010): в
	конструкторе просмотрщик живет внутри модалки и обязан быть над ней
*/
.st-site .st-docview {
	position: fixed;
	inset: 0;
	z-index: 2060;
	display: flex;
	flex-direction: column;
	background-color: rgba(8, 11, 17, 0.86);
	padding: 16px;
	gap: 12px;
}

.st-site .st-docview__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	color: #FFFFFF;
	flex: 0 0 auto;
}

.st-site .st-docview__name {
	font-size: 15px;
	font-weight: 600;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.st-site .st-docview__acts {
	display: flex;
	align-items: center;
	gap: 8px;
	flex: 0 0 auto;
}

.st-site .st-docview__btn {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 14px;
	border: 1px solid rgba(255, 255, 255, 0.28);
	border-radius: var(--st-radius-sm);
	background-color: rgba(255, 255, 255, 0.08);
	color: #FFFFFF;
	font-size: 13px;
	font-weight: 600;
	text-decoration: none;
	cursor: pointer;
}

.st-site .st-docview__btn:hover { background-color: rgba(255, 255, 255, 0.18); }
.st-site .st-docview__btn i { color: inherit; }

.st-site .st-docview__frame {
	flex: 1 1 auto;
	width: 100%;
	min-height: 0;
	border: 0;
	border-radius: var(--st-radius-sm);
	background-color: #FFFFFF;
}

/* ==== СОЦ-КНОПКИ ======================================================= */

.st-socials-row {
	display: flex;
	flex-wrap: wrap;
	gap: calc(10px * var(--st-dense, 1));
}

.st-socials-row--left { justify-content: flex-start; }
.st-socials-row--center { justify-content: center; }
.st-socials-row--right { justify-content: flex-end; }

/* КРУПНЫЕ ПЛИТКИ — СЕТКА, а не строка: у плитки есть ширина колонки,
   и число колонок задает владелец тем же полем, что у остальных сеток */
.st-socials-row--tiles {
	display: grid;
	grid-template-columns: repeat(var(--st-cols, 6), minmax(0, 1fr));
}

.st-sbtn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 10px;
	padding: 12px 16px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	color: var(--st-text);
	font-size: 14px;
	font-weight: 600;
	text-decoration: none;
	transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

.st-sbtn:hover {
	border-color: var(--st-accent);
	transform: translateY(-2px);
	box-shadow: var(--st-shadow);
}

/* ТОЛЬКО ЗНАЧКИ — квадратная кнопка: подписи нет, и прямоугольник
   с воздухом по бокам выглядел бы поломанным */
.st-socials-row--icons .st-sbtn {
	width: 52px;
	height: 52px;
	padding: 0;
	border-radius: 999px;
}

.st-socials-row--icons.st-socials-row--sm .st-sbtn { width: 42px; height: 42px; }
.st-socials-row--icons.st-socials-row--lg .st-sbtn { width: 64px; height: 64px; }

.st-socials-row--tiles .st-sbtn {
	flex-direction: column;
	gap: 8px;
	padding: 20px 12px;
	border-radius: var(--st-radius);
	text-align: center;
}

.st-sbtn__logo {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
}

/* РАЗМЕР ЗНАЧКА ЗАДАЕТСЯ ОБЕРТКЕ, А НЕ ФАЙЛУ: логотипы приходят
   из общего каталога площадок ($_SOURCES) с подставленными шириной
   и высотой, и переопределять их надо снаружи */
.st-sbtn__logo svg {
	display: block;
	width: 24px;
	height: 24px;
}

.st-socials-row--sm .st-sbtn__logo svg { width: 20px; height: 20px; }
.st-socials-row--lg .st-sbtn__logo svg { width: 30px; height: 30px; }
.st-socials-row--tiles .st-sbtn__logo svg { width: 34px; height: 34px; }

.st-sbtn__title {
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}

/* ==== ЛОГОТИП (закрепленный блок) ====================================== */

.st-logo {
	display: flex;
	padding: 10px 0;
}

.st-logo--left { justify-content: flex-start; }
.st-logo--center { justify-content: center; }
.st-logo--right { justify-content: flex-end; }

.st-logo__img {
	width: auto;
	object-fit: contain;
}

.st-logo__img--sm { max-height: 56px; }
.st-logo__img--md { max-height: 92px; }
.st-logo__img--lg { max-height: 140px; }

.st-logo__text {
	font-size: 28px;
	font-weight: 800;
	letter-spacing: -0.02em;
	color: var(--st-text);
}

.st-logo--sm .st-logo__text { font-size: 22px; }
.st-logo--lg .st-logo__text { font-size: 38px; }

/* ==== КОНТАКТЫ, АДРЕС, ЧАСЫ РАБОТЫ ===================================== */

.st-contacts {
	display: grid;
	gap: 16px;
	padding: 20px;
	background-color: var(--st-surface);
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	box-shadow: var(--st-shadow);
}

.st-contacts--row {
	grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.st-contacts--column {
	grid-template-columns: 1fr;
}

.st-contact__label {
	color: var(--st-muted);
	font-size: 12px;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	margin-bottom: 4px;
}

.st-contact__value {
	font-size: 16px;
	font-weight: 600;
	word-break: break-word;
}

.st-socials {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.st-social {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 6px 10px;
	border: 1px solid var(--st-border);
	border-radius: 999px;
	background-color: var(--st-surface-alt);
	font-size: 13px;
	font-weight: 600;
}

.st-social svg {
	display: block;
	border-radius: 5px;
}

.st-schedule {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.st-schedule__row {
	display: flex;
	justify-content: space-between;
	gap: 12px;
	font-size: 14px;
}

.st-schedule__day {
	color: var(--st-muted);
}

.st-schedule__time {
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}

.st-schedule__row--off .st-schedule__time {
	color: var(--st-muted);
	font-weight: 500;
}

/* ==== ПОИСК ============================================================= */

.st-search {
	display: flex;
}

.st-search--narrow .st-search__field { max-width: 380px; }
.st-search--wide .st-search__field { max-width: 620px; }
.st-search--full .st-search__field { max-width: none; }

.st-search__field {
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	padding: 12px 16px;
	background-color: var(--st-surface);
	border: 1px solid var(--st-border);
	border-radius: 999px;
	box-shadow: var(--st-shadow);
}

.st-search--sm .st-search__field { padding: 8px 14px; font-size: 14px; }
.st-search--lg .st-search__field { padding: 16px 20px; font-size: 18px; }

.st-search__input {
	flex: 1 1 auto;
	min-width: 0;
	border: 0;
	outline: 0;
	background: transparent;
	color: var(--st-text);
}

.st-search__input::placeholder {
	color: var(--st-muted);
}

.st-search__icon {
	flex: 0 0 auto;
	width: 18px;
	height: 18px;
	color: var(--st-muted);
}

/* ==== БРЕНДЫ ============================================================ */

.st-brands {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}

.st-brand {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 10px 14px;
	background-color: var(--st-surface);
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	font-size: 14px;
	font-weight: 600;
}

.st-brand__logo {
	width: 34px;
	height: 34px;
	border-radius: 8px;
	object-fit: cover;
	background-color: var(--st-surface-alt);
}

.st-brand__letter {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 34px;
	height: 34px;
	border-radius: 8px;
	background-color: var(--st-accent);
	color: var(--st-accent-text);
	font-weight: 700;
}

.st-brands--text .st-brand {
	background: transparent;
	border-color: transparent;
	padding: 4px 0;
}

/* Плитка бренда стала ссылкой на его страницу (2026-08-14) — та же
   механика отклика, что у карточки товара */
.st-brand--link {
	cursor: pointer;
	transition: border-color 0.15s ease, transform 0.15s ease;
}

.st-brand--link:hover {
	border-color: var(--st-accent);
	transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
	.st-brand--link {
		transition: none !important;
	}

	.st-brand--link:hover {
		transform: none !important;
	}
}

/*
	==== ПОЯСНЯЮЩАЯ ПЛАШКА БЛОКА (2026-08-16) ====

	ЭТО РАЗМЕТКА САЙТА, А НЕ ОБВЯЗКА КОНСТРУКТОРА, и потому живет здесь,
	а не в steditor.css: плашку печатает шаблон блока внутри `.st-container`
	и красит она себя переменными ТЕМЫ САЙТА. Показывается она только
	в конструкторе (условие в шаблоне), но выглядеть обязана частью
	витрины — иначе владелец принял бы ее за ошибку верстки
*/
.st-note {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	margin-bottom: 12px;
	padding: 10px 12px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface-alt);
	color: var(--st-muted);
	font-size: 13px;
	line-height: 1.4;
}

.st-note i {
	flex: 0 0 auto;
	margin-top: 1px;
	color: var(--st-accent);
	font-size: 15px;
}

/* ==== КОЛЛЕКЦИИ ======================================================== */
/*
	ПАРА К БЛОКУ БРЕНДОВ (2026-08-16), и оформление у них родственное
	намеренно: соседние ленты одной иерархии обязаны читаться как пара.

	ОТЛИЧИЕ РОВНО ОДНО И ОНО СОДЕРЖАТЕЛЬНОЕ: у бренда логотип — маленькая
	марка рядом с названием, у коллекции обложка — САМА ВИТРИНА (по ней
	покупатель и выбирает линейку). Поэтому у коллекции карточка
	вертикальная, с крупной обложкой 4:3, а сетка — колонками,
	а не переносом строк.

	КЛАССЫ СВОИ, А НЕ `st-card*` И НЕ `st-brand*`. Грабли уже стоили
	проекта одного вида витрины (см. `.st-product` против `.st-card`
	в памяти): общий класс у двух разных объектов означает, что отступы
	одного молча приезжают другому, а кто победит — решает порядок
	объявлений в файле
*/
.st-collections {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
	gap: 14px;
}

.st-collection {
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background-color: var(--st-surface);
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	color: inherit;
	text-decoration: none;
}

.st-collection__cover {
	position: relative;
	display: block;
	width: 100%;
	aspect-ratio: 4 / 3;
	background-color: var(--st-surface-alt);
}

.st-collection__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Буква вместо обложки — тот же прием, что у плитки бренда и у фильтра
   маркета: пустой серый прямоугольник читался бы как незагрузившееся фото */
.st-collection__letter {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background-color: var(--st-accent);
	color: var(--st-accent-text);
	font-size: 30px;
	font-weight: 700;
}

.st-collection__body {
	display: flex;
	flex-direction: column;
	gap: 3px;
	padding: 10px 12px 12px;
}

.st-collection__title {
	font-size: 14px;
	font-weight: 600;
	line-height: 1.3;
}

.st-collection__note {
	color: var(--st-muted);
	font-size: 12px;
}

/*
	ПРОСТОЙ СПИСОК — БЕЗ ОБЛОЖЕК И БЕЗ СЕТКИ КОЛОНОК. Разметка обложку
	в этом виде не печатает вовсе (условие в шаблоне), поэтому здесь
	меняется только раскладка ленты: колонки шириной 200px под одну
	строку текста дали бы длинную гребенку пустых карточек
*/
.st-collections--text {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.st-collections--text .st-collection {
	background: transparent;
	border-color: transparent;
	border-radius: 0;
}

.st-collections--text .st-collection__body {
	flex-direction: row;
	align-items: baseline;
	gap: 8px;
	padding: 5px 0;
}

/* Отклик карточки — тот же, что у плитки бренда и карточки товара */
.st-collection--link {
	cursor: pointer;
	transition: border-color 0.15s ease, transform 0.15s ease;
}

.st-collection--link:hover {
	border-color: var(--st-accent);
	transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
	.st-collection--link {
		transition: none !important;
	}

	.st-collection--link:hover {
		transform: none !important;
	}
}

/* ==== МЕДИА ============================================================= */

.st-media__grid {
	display: grid;
	gap: 12px;
	grid-template-columns: repeat(var(--st-media-cols, 3), minmax(0, 1fr));
}

.st-media__item {
	position: relative;
	overflow: hidden;
	border-radius: var(--st-radius);
	background-color: var(--st-surface-alt);
	border: 1px solid var(--st-border);
}

.st-media__item img,
.st-media__item video {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.st-media--sm .st-media__item { height: 160px; }
.st-media--md .st-media__item { height: 260px; }
.st-media--lg .st-media__item { height: 380px; }

.st-media__caption {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	padding: 10px 14px;
	background: linear-gradient(to top, rgba(0, 0, 0, 0.65), rgba(0, 0, 0, 0));
	color: #fff;
	font-size: 13px;
	font-weight: 600;
}

/* Кадр, открывающий полноэкранный просмотр (2026-08-14). Курсор — часть
   обещания: без него владелец не догадается, что кадр кликабелен */
.st-media__item--zoom {
	display: block;
	cursor: zoom-in;
}

/* ======================================================================= */
/* ==== КОНТРОЛЫ СЛАЙДЕРА (2026-08-14) =================================== */
/* ======================================================================= */
/*
	ЧТО БЫЛО НЕ ТАК С ПРЕЖНИМ УМОЛЧАНИЕМ. Стрелки и активная точка красились
	АКЦЕНТОМ ТЕМЫ прямо поверх кадра. На светлой фотографии зеленая стрелка
	размывалась, на темной — тонула; читаемость контрола зависела от того,
	какую картинку загрузил владелец, а он про это не думает вовсе.

	УМОЛЧАНИЕ ТЕПЕРЬ НЕЙТРАЛЬНОЕ И САМОДОСТАТОЧНОЕ: светлая стрелка внутри
	ПОЛУПРОЗРАЧНОЙ ТЕМНОЙ КНОПКИ. Такой контрол виден на любом кадре,
	потому что несет свой фон с собой, — та же механика, что у листалок
	в мессенджерах.

	ЦВЕТА — ПЕРЕМЕННЫМИ, чтобы владелец мог перекрасить контрол под свою
	фотографию, НЕ трогая остальные слайдеры сайта. Пустая настройка
	переменную не печатает вовсе, и работает значение по умолчанию отсюда.

	SWIPER СВОИ КЛАССЫ СТАВИТ САМ — переопределяем их, а не переименовываем:
	плагин ищет `.swiper-button-next` буквально
*/
.st-media .swiper {
	border-radius: var(--st-radius);
}

.st-slider {
	/* Размер «средний». Меняется классом ниже — числа собраны в одном
	   месте, чтобы стрелка и точки росли согласованно */
	--st-slider-btn: 40px;
	--st-slider-icon: 15px;
	--st-slider-dot-size: 8px;

	--st-slider-arrow: #FFFFFF;
	--st-slider-arrow-bg: rgba(17, 20, 26, 0.55);
	--st-slider-arrow-bg-hover: rgba(17, 20, 26, 0.78);
	--st-slider-dot: #FFFFFF;
}

.st-slider--sm {
	--st-slider-btn: 32px;
	--st-slider-icon: 12px;
	--st-slider-dot-size: 6px;
}

.st-slider--lg {
	--st-slider-btn: 52px;
	--st-slider-icon: 19px;
	--st-slider-dot-size: 10px;
}

/*
	СТРЕЛКА. `swiper-button-*` рисует значок ШРИФТОМ (::after), поэтому
	размер задается `font-size`, а не шириной элемента, — свои размеры
	по умолчанию плагин прописывает через `--swiper-navigation-size`,
	и спорить с ним переменной честнее, чем перекрывать правилами
*/
.st-media .swiper-button-next,
.st-media .swiper-button-prev {
	width: var(--st-slider-btn, 40px);
	height: var(--st-slider-btn, 40px);
	margin-top: calc(var(--st-slider-btn, 40px) / -2);
	color: var(--st-slider-arrow, #FFFFFF);
	transition: background-color 0.15s ease, opacity 0.15s ease;
}

.st-media .swiper-button-next::after,
.st-media .swiper-button-prev::after {
	font-size: var(--st-slider-icon, 15px);
	font-weight: 800;
}

/* Кнопка-подложка: она и есть причина, по которой стрелка видна на любом
   фоне. `plain` от нее отказывается осознанно */
.st-slider--arrows-circle .swiper-button-next,
.st-slider--arrows-circle .swiper-button-prev,
.st-slider--arrows-square .swiper-button-next,
.st-slider--arrows-square .swiper-button-prev {
	background-color: var(--st-slider-arrow-bg);
	border-radius: 999px;
}

.st-slider--arrows-square .swiper-button-next,
.st-slider--arrows-square .swiper-button-prev {
	border-radius: var(--st-radius-sm);
}

.st-slider--arrows-circle .swiper-button-next:hover,
.st-slider--arrows-circle .swiper-button-prev:hover,
.st-slider--arrows-square .swiper-button-next:hover,
.st-slider--arrows-square .swiper-button-prev:hover {
	background-color: var(--st-slider-arrow-bg-hover);
}

/*
	ГОЛАЯ СТРЕЛКА БЕЗ ПОДЛОЖКИ обязана хотя бы отбрасывать тень: иначе
	на кадре своего же цвета она исчезает совсем
*/
.st-slider--arrows-plain .swiper-button-next,
.st-slider--arrows-plain .swiper-button-prev {
	background: transparent;
	filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.55));
}

/* ==== ИНДИКАТОР ==== */

.st-media .swiper-pagination-bullet {
	width: var(--st-slider-dot-size, 8px);
	height: var(--st-slider-dot-size, 8px);
	background-color: var(--st-slider-dot, #FFFFFF);
	opacity: 0.45;
	transition: opacity 0.15s ease, width 0.15s ease;
}

.st-media .swiper-pagination-bullet-active {
	background-color: var(--st-slider-dot, #FFFFFF);
	opacity: 1;
}

/*
	ЧЁРТОЧКИ — ТОТ ЖЕ ЭЛЕМЕНТ, ДРУГАЯ ГЕОМЕТРИЯ: активная растягивается
	вдвое. Заводить второй набор узлов ради этого нельзя — их рисует Swiper
*/
.st-slider--dots-bars .swiper-pagination-bullet {
	width: calc(var(--st-slider-dot-size, 8px) * 2.5);
	height: calc(var(--st-slider-dot-size, 8px) * 0.5);
	border-radius: 2px;
}

.st-slider--dots-bars .swiper-pagination-bullet-active {
	width: calc(var(--st-slider-dot-size, 8px) * 4);
}

/*
	ЦИФРЫ («2 / 7») — режим `fraction` у Swiper, но переключать его
	из скрипта не нужно: тот же счетчик собирается CSS-счетчиками нельзя,
	поэтому режим включает JS по классу обертки (см. initSwipers).
	Здесь только оформление плашки
*/
.st-slider--dots-numbers .swiper-pagination {
	left: 50%;
	right: auto;
	transform: translateX(-50%);
	width: auto;
	padding: 3px 12px;
	border-radius: 999px;
	background-color: var(--st-slider-arrow-bg);
	color: var(--st-slider-dot, #FFFFFF);
	font-size: 13px;
	font-weight: 700;
}

/* Владелец выключил стрелки — узлов в разметке нет вовсе (шаблон их
   не рисует). Класс остается признаком для будущих правил */
.st-slider--noarrows .swiper-button-next,
.st-slider--noarrows .swiper-button-prev {
	display: none;
}

/*
	==== «ОБЪЁМНЫЙ ПОТОК»: СЛАЙД УЖЕ КОРОБКИ (2026-08-22) ====

	В этом эффекте смысл — в ВИДИМЫХ СОСЕДЯХ: центральный кадр стоит прямо,
	боковые отвернуты и уведены вглубь. Слайд во всю ширину коробки
	не оставляет им места вовсе, соседи прячутся ровно под центральным,
	и при перетаскивании выезжают из-под него рывком — это и читалось
	как «слайд улетает от курсора».

	ШИРИНА ЗАДАЕТСЯ ЗДЕСЬ, А НЕ В СКРИПТЕ: скрипт ставит
	`slidesPerView: 'auto'`, то есть спрашивает ширину у CSS. Так оформление
	остается в теме, а поведение — в поведении.

	`min()` С ПОТОЛКОМ: на широком экране доля от коробки дала бы кадр
	в тысячу с лишним пикселей, и соседи уехали бы за край; на узком —
	наоборот, доля важнее фиксированного числа
*/
.st-site .st-slider--fx-coverflow .swiper-slide {
	width: min(72%, 680px);
}

/* На телефоне соседи все равно не помещаются осмысленно — оставляем
   им узкую полоску, чтобы эффект читался, а кадр не превращался в марку */
@media (max-width: 575.98px) {
	.st-site .st-slider--fx-coverflow .swiper-slide {
		width: 86%;
	}
}

@media (prefers-reduced-motion: reduce) {
	.st-media .swiper-button-next,
	.st-media .swiper-button-prev,
	.st-media .swiper-pagination-bullet {
		transition: none !important;
	}
}

/* ==== ТЕКСТОВЫЙ БЛОК =================================================== */
/*
	Содержимое ограниченного CKEditor: заголовки, списки, ТАБЛИЦЫ, иконки
	KeenIcons. Стилизуем ТОЛЬКО внутри .st-rich — сброс тегов выше
	обнулил бы разметку контента
*/

.st-rich--sm { font-size: 14px; }
.st-rich--md { font-size: 16px; }
.st-rich--lg { font-size: 19px; }

.st-rich--left { text-align: left; }
.st-rich--center { text-align: center; }
.st-rich--right { text-align: right; }

.st-rich h1,
.st-rich h2,
.st-rich h3,
.st-rich h4,
.st-rich h5,
.st-rich h6 {
	font-weight: 700;
	line-height: 1.25;
	margin: 1.2em 0 0.5em;
}

.st-rich > :first-child { margin-top: 0; }
.st-rich > :last-child { margin-bottom: 0; }

.st-rich h1 { font-size: 1.9em; }
.st-rich h2 { font-size: 1.6em; }
.st-rich h3 { font-size: 1.35em; }
.st-rich h4 { font-size: 1.15em; }

.st-rich p {
	margin: 0 0 0.9em;
}

.st-rich ul,
.st-rich ol {
	margin: 0 0 0.9em;
	padding-left: 1.4em;
	list-style: revert;
}

.st-rich li {
	margin-bottom: 0.3em;
}

.st-rich a {
	color: var(--st-accent);
	text-decoration: underline;
}

.st-rich blockquote {
	margin: 0 0 0.9em;
	padding: 10px 18px;
	border-left: 3px solid var(--st-accent);
	color: var(--st-muted);
}

.st-rich hr {
	margin: 1.2em 0;
	border: 0;
	border-top: 1px solid var(--st-border);
}

/* Таблицы CKEditor приходят обернутыми в <figure class="table"> */
.st-rich figure.table,
.st-rich table {
	max-width: 100%;
	margin: 0 0 0.9em;
	overflow-x: auto;
}

.st-rich table {
	width: 100%;
	border-collapse: collapse;
	background-color: var(--st-surface);
	border-radius: var(--st-radius-sm);
}

.st-rich th,
.st-rich td {
	padding: 8px 12px;
	border: 1px solid var(--st-border);
	text-align: left;
}

.st-rich th {
	background-color: var(--st-surface-alt);
	font-weight: 600;
}

.st-rich figcaption {
	color: var(--st-muted);
	font-size: 0.85em;
	padding-top: 6px;
}

/* ==== ПРОИЗВОЛЬНЫЙ HTML ================================================ */
/*
	Свой код владельца. Оформления НАРОЧНО почти нет: блок и придуман,
	чтобы виджет выглядел так, как задумал автор. Ограничиваем только
	переполнение — чужой код не должен ломать ширину страницы
*/

.st-html {
	max-width: 100%;
	overflow-x: auto;
}

.st-html iframe,
.st-html img,
.st-html video {
	max-width: 100%;
}

/* ==== КАРТА (Яндекс.Карты) ============================================= */

.st-map {
	position: relative;
	overflow: hidden;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface-alt);
}

.st-map--sm { height: 240px; }
.st-map--md { height: 380px; }
.st-map--lg { height: 540px; }

.st-map__canvas {
	width: 100%;
	height: 100%;
}

/* Заглушка без ключа API: честный адрес вместо пустого прямоугольника */
.st-map__stub {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 10px;
	height: 100%;
	padding: 24px;
	text-align: center;
	background-color: var(--st-surface);
}

.st-map__pin {
	color: var(--st-accent);
}

.st-map__pin svg {
	width: 44px;
	height: 44px;
}

.st-map__address {
	font-size: 16px;
	font-weight: 600;
}

.st-map__note {
	color: var(--st-muted);
	font-size: 13px;
}

/* Адрес не распознан геокодером: причина названа словами, а не дырой */
.st-map__note--fail {
	color: var(--st-danger);
	font-weight: 600;
}

/*
	==== ДЕНЬ / НОЧЬ ====

	ЗДЕСЬ ПУСТО, И ЭТО ПРАВИЛЬНО. Тема карты — штатное свойство JS API 3.0
	(`theme: 'light' | 'dark'`), ее выставляет steditor.js по атрибуту
	`data-st-mode` корня сайта и меняет через `map.update()` без
	пересоздания карты.

	ФИЛЬТРОВ НАД ТАЙЛАМИ БОЛЬШЕ НЕТ (и возвращать их не надо): подкрашенная
	инверсией дневная карта — это не ночная схема, а вывернутая наизнанку
	дневная. Яндекс рисует ночную сам.

	==== МЕТКА И КНОПКИ МАСШТАБА — СВОИ ====

	В v3 маркер это обычный DOM-узел, поэтому метка рисуется цветами темы
	сайта и одинаково читается на обеих подложках. Кнопки зума тоже свои:
	штатный контрол живет в отдельном пакете, который пришлось бы тянуть
	с чужого CDN ради двух кнопок
*/
.st-map__marker {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 2px;
	color: var(--st-accent);
	/*
		Узел маркера якорится СВОИМ ЦЕНТРОМ на координате, а у булавки
		точка — это ее носик. Без сдвига метка встала бы серединой
		на здание и «указывала» бы на соседнее
	*/
	transform: translate(-50%, -100%);
	pointer-events: none;
}

.st-map__marker svg {
	width: 40px;
	height: 40px;
	filter: drop-shadow(0 2px 6px rgba(15, 20, 30, 0.35));
}

.st-map__marker-label {
	max-width: 200px;
	padding: 3px 8px;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	color: var(--st-text-base);
	font-size: 12px;
	font-weight: 600;
	line-height: 1.3;
	text-align: center;
	box-shadow: var(--st-shadow);
}

.st-map__zoom {
	position: absolute;
	right: 12px;
	bottom: 32px;
	z-index: 2;
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.st-map__zoom-btn {
	width: 32px;
	height: 32px;
	padding: 0;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	color: var(--st-text-base);
	font-size: 18px;
	font-weight: 600;
	line-height: 1;
	cursor: pointer;
	box-shadow: var(--st-shadow);
	transition: background-color 0.15s ease, color 0.15s ease;
}

.st-map__zoom-btn:hover {
	background-color: var(--st-accent);
	color: var(--st-accent-text);
}

@media (prefers-reduced-motion: reduce) {
	.st-map__zoom-btn {
		transition: none;
	}
}

/* ==== МЕНЮ / НАВИГАЦИЯ ================================================= */
/*
	Строится из якорей секций. Плавная прокрутка — свойством корня
	(в конструкторе клик дополнительно перехватывает steditor.js,
	потому что прокручивается холст, а не окно)
*/

.st-site {
	scroll-behavior: smooth;
}

/* Секция с якорем не должна упираться в верхний край: если над ней
   висит прилипающее меню, заголовок оказался бы под ним */
.st-block[id] {
	scroll-margin-top: 70px;
}

/*
	НАВИГАЦИЯ (этап C): пункты собираются из страниц, якорей и своих ссылок,
	вложенность — ДВА уровня. Разметка одна и та же и в общей шапке сайта,
	и обычным блоком страницы
*/
.st-menu {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
}

.st-menu__list {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	width: 100%;
}

.st-menu--left .st-menu__list { justify-content: flex-start; }
.st-menu--center .st-menu__list { justify-content: center; }
.st-menu--right .st-menu__list { justify-content: flex-end; }

.st-menu--left { justify-content: flex-start; }
.st-menu--center { justify-content: center; }
.st-menu--right { justify-content: flex-end; }

/* Пункт с подуровнем — контекст позиционирования выпадашки */
.st-menu__item {
	position: relative;
}

.st-menu__link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 8px 16px;
	font-size: 14px;
	font-weight: 600;
	color: var(--st-text);
	border-radius: 999px;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.st-menu--pills .st-menu__link {
	background-color: var(--st-surface);
	border: 1px solid var(--st-border);
}

.st-menu--pills .st-menu__link:hover,
.st-menu--pills .st-menu__link--active {
	background-color: var(--st-accent);
	border-color: var(--st-accent);
	color: var(--st-accent-text);
}

.st-menu--text .st-menu__link {
	padding: 8px 10px;
	color: var(--st-muted);
}

.st-menu--text .st-menu__link:hover,
.st-menu--text .st-menu__link--active {
	color: var(--st-text);
}

.st-menu--underline .st-menu__link {
	padding: 8px 4px;
	border-radius: 0;
	border-bottom: 2px solid transparent;
}

.st-menu--underline .st-menu__link:hover,
.st-menu--underline .st-menu__link--active {
	border-bottom-color: var(--st-accent);
}

/* Стрелка у пункта с подуровнем: чистый CSS, без иконочного шрифта —
   сайт клиента не должен тянуть шрифты сервиса */
.st-menu__caret {
	width: 0;
	height: 0;
	border-left: 4px solid transparent;
	border-right: 4px solid transparent;
	border-top: 5px solid currentColor;
	opacity: 0.7;
}

/*
	ВТОРОЙ УРОВЕНЬ. На широком экране — выпадашка по наведению и фокусу
	(:focus-within нужен клавиатуре и тач-устройствам, где :hover
	срабатывает не всегда). Третьего уровня нет намеренно
*/
.st-menu__sub {
	position: absolute;
	top: 100%;
	left: 0;
	z-index: 30;
	display: flex;
	flex-direction: column;
	min-width: 180px;
	margin-top: 4px;
	padding: 6px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	box-shadow: var(--st-shadow);
	opacity: 0;
	visibility: hidden;
	transition: opacity 0.15s ease;
}

.st-menu__item--has:hover > .st-menu__sub,
.st-menu__item--has:focus-within > .st-menu__sub {
	opacity: 1;
	visibility: visible;
}

.st-menu__sublink {
	display: block;
	padding: 7px 10px;
	border-radius: var(--st-radius-sm);
	color: var(--st-text);
	font-size: 13px;
	font-weight: 500;
	white-space: nowrap;
}

.st-menu__sublink:hover,
.st-menu__sublink--active {
	background-color: var(--st-surface-alt);
}

/*
	==== ОФОРМЛЕНИЕ ОТДЕЛЬНОГО ПУНКТА (правка 2026-08-03) ====

	Цвета состояний уезжают на сам элемент ссылки переменными --st-mi-*
	(их ставит steditorMenuItemStyle в functions.php), а правила ниже
	их только читают. Так девять цветов одного пункта не превращаются
	в девять правил на каждый пункт, а пустое значение честно означает
	«как в теме»: переменная просто не выводится и работает запасной
	вариант в var().

	ДВЕ ИКОНКИ: обычная и та, что показывается при наведении и в активном
	пункте (ходовой прием витрин — контурная и сплошная). Вторая
	не задана — остается первая.

	ИКОНКИ БЕРУТСЯ ИЗ НАБОРА KeenIcons. Это осознанное исключение
	из правила «сайт не тянет шрифты сервиса»: тот же набор уже
	вставляется в текстовые блоки через CKEditor. ПУБЛИЧНАЯ СТРАНИЦА
	ОБЯЗАНА подключить стили KeenIcons, иначе значки меню не отрисуются
*/
.st-menu__icon,
.st-nav__icon {
	line-height: 1;
	color: var(--st-mi-ic, currentColor);
	transition: color 0.15s ease;
}

/* Вторая иконка лежит поверх первой и проявляется вместе с состоянием */
.st-menu__icon--on,
.st-nav__icon--on {
	display: none;
}

.st-menu__link:hover .st-menu__icon--on,
.st-menu__link--active .st-menu__icon--on,
.st-nav__btn:hover .st-nav__icon--on,
.st-nav__btn--active .st-nav__icon--on {
	display: inline-block;
}

.st-menu__link:hover .st-menu__icon:not(.st-menu__icon--on),
.st-menu__link--active .st-menu__icon:not(.st-menu__icon--on),
.st-nav__btn:hover .st-nav__icon:not(.st-nav__icon--on),
.st-nav__btn--active .st-nav__icon:not(.st-nav__icon--on) {
	display: none;
}

/* Иконка одна — прятать ее нечем, значит она остается на всех состояниях */
.st-menu__link .st-menu__icon:only-of-type,
.st-nav__btn .st-nav__icon:only-of-type {
	display: inline-block;
}

/* ЦВЕТА ПУНКТА ПО СОСТОЯНИЯМ. Заданные владельцем перебивают тему,
   незаданные — наследуют ее (var() с запасным вариантом) */
.st-menu__link[style*="--st-mi-bg"] {
	background-color: var(--st-mi-bg);
}

.st-menu__link:hover {
	background-color: var(--st-mi-bg-h, var(--st-mi-bg));
	color: var(--st-mi-tx-h, var(--st-mi-tx));
}

.st-menu__link--active {
	background-color: var(--st-mi-bg-a, var(--st-mi-bg));
	color: var(--st-mi-tx-a, var(--st-mi-tx));
}

.st-menu__link[style*="--st-mi-tx"] {
	color: var(--st-mi-tx);
}

.st-menu__link:hover .st-menu__icon {
	color: var(--st-mi-ic-h, var(--st-mi-ic, currentColor));
}

.st-menu__link--active .st-menu__icon {
	color: var(--st-mi-ic-a, var(--st-mi-ic, currentColor));
}

/* Подпись отключена, а иконка есть — текст прячем, но из разметки
   не убираем: он нужен экранным читалкам */
.st-menu__link--noname .st-menu__text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
}

/*
	==== НИЖНЯЯ ПАНЕЛЬ НАВИГАЦИИ (правка 2026-08-03) ====

	ЗАМЕНИЛА «ГАМБУРГЕР» НА ПЛАНШЕТЕ И ТЕЛЕФОНЕ. Выпадающий список сверху
	требовал двух касаний и уводил палец в самый неудобный угол экрана;
	панель снизу — ровно то, что делает сам сервис, и то, чего человек
	ждет от витрины на телефоне.

	Презентацию выбирает СЕРВЕР (websiteMenuNav): панель приходит в разметке
	только там, где она нужна, — CSS ничего не переключает. Поэтому одна
	и та же разметка годится и предпросмотру конструктора, и будущей
	публичной странице, и случаю с отключенным JS.

	ПАНЕЛЬ ПЛОСКАЯ: второй уровень сюда не идет — вложенность под пальцем
	на панели из иконок неуправляема (то же соображение, что похоронило
	третий уровень меню).

	==== ПОЧЕМУ FIXED, А НЕ STICKY (правка 2026-08-03) ====

	Прежнее `position: sticky` НЕ РАБОТАЛО В ПРИНЦИПЕ: липкий элемент
	удерживается в границах СВОЕГО родителя, а панель лежит внутри секции
	блока «Меню» — короткой и, как правило, стоящей в ОБЩЕЙ ШАПКЕ, то есть
	в самом верху ленты. Прилипать было некуда, и панель честно оставалась
	в потоке на месте своего блока.

	Нижняя панель по определению принадлежит ЭКРАНУ, а не ленте, — значит
	из потока ее надо вынимать. На публичной странице экран = окно браузера,
	и этих трех строк достаточно. В конструкторе экран = холст, поэтому
	steditor.css переопределяет геометрию переменными (см. placeNav)
*/
.st-nav {
	position: fixed;
	left: 0;
	right: 0;
	bottom: 0;
	z-index: 40;
	display: flex;
	align-items: stretch;
	justify-content: space-around;
	gap: 4px;
	padding: 6px 8px;
	border-top: 1px solid var(--st-border);
	border-radius: var(--st-radius) var(--st-radius) 0 0;
	background-color: var(--st-surface);
	box-shadow: 0 -4px 18px rgba(0, 0, 0, 0.08);
}

.st-nav__btn {
	flex: 1 1 0;
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 3px;
	padding: 7px 4px;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-mi-bg, transparent);
	color: var(--st-mi-tx, var(--st-muted));
	font-size: 11px;
	font-weight: 600;
	line-height: 1.15;
	text-align: center;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.st-nav__btn .st-nav__icon {
	font-size: 20px;
}

.st-nav__btn:hover {
	background-color: var(--st-mi-bg-h, var(--st-surface-alt));
	color: var(--st-mi-tx-h, var(--st-text));
}

.st-nav__btn:hover .st-nav__icon {
	color: var(--st-mi-ic-h, var(--st-mi-ic, currentColor));
}

/* АКТИВНЫЙ ПУНКТ — один акцент: посетитель должен видеть, где он */
.st-nav__btn--active {
	background-color: var(--st-mi-bg-a, var(--st-surface-alt));
	color: var(--st-mi-tx-a, var(--st-accent));
}

.st-nav__btn--active .st-nav__icon {
	color: var(--st-mi-ic-a, var(--st-mi-ic, var(--st-accent)));
}

.st-nav__text {
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Подпись выключена владельцем — остается одна иконка (текст прячем
   доступным способом, а не display:none) */
.st-nav__btn--icon .st-nav__text {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip-path: inset(50%);
}

/*
	ВАРИАНТ «ТОЛЬКО НАЗВАНИЕ У АКТИВНОГО» — как в интерфейсе сервиса:
	у выбранного пункта иконка уступает место подписи, и он читается
	как ярлык, а не как еще один значок в ряду
*/
.st-nav__btn--label.st-nav__btn--active .st-nav__icon {
	display: none;
}

.st-nav__btn--label.st-nav__btn--active .st-nav__text {
	position: static;
	width: auto;
	height: auto;
	clip-path: none;
	font-size: 13px;
}

/*
	ПУНКТ БЕЗ ИКОНКИ ВОВСЕ: подпись обязана остаться видимой, иначе кнопка
	была бы пустой. Решает это СЕРВЕР — класс `--icon` не ставится, когда
	иконки нет. Селектор `:has()` тут был бы уместнее, но проект его
	намеренно не использует (поддержка шире у обычных классов — то же
	решение, что у «прилипающего» меню)
*/


/* ==== ХЛЕБНЫЕ КРОШКИ ==================================================== */

/*
	Путь «Главная → раздел». На главной вырождается в один пункт, поэтому
	по умолчанию блок там не выводится — решение принимает сервер, CSS
	просто рисует то, что пришло
*/
.st-crumbs {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 6px;
	color: var(--st-muted);
}

.st-crumbs--left { justify-content: flex-start; }
.st-crumbs--center { justify-content: center; }
.st-crumbs--right { justify-content: flex-end; }

.st-crumbs--sm { font-size: 12px; }
.st-crumbs--md { font-size: 14px; }
.st-crumbs--lg { font-size: 16px; }

.st-crumbs__item {
	color: var(--st-muted);
	transition: color 0.15s ease;
}

.st-crumbs__item:hover {
	color: var(--st-accent);
}

.st-crumbs__item--current {
	color: var(--st-text);
	font-weight: 600;
}

.st-crumbs__sep {
	color: var(--st-border);
}

/* Прилипание: липкой становится сама СЕКЦИЯ (у нее и атрибут
   data-st-sticky), иначе меню уехало бы из своего контейнера.
   Селектор по атрибуту, а не `:has()` — поддержка шире */
.st-block[data-st-sticky] {
	position: sticky;
	top: 0;
	z-index: 20;
	background-color: var(--st-bg);
	backdrop-filter: blur(6px);
}

/* ==== ТОВАРЫ ============================================================ */

/*
	ШАПКА ВИТРИНЫ (заголовок + переключатель режимов).

	ОТСТУП СНИЗУ ОБЯЗАТЕЛЕН (правка 2026-08-14). Раньше воздух под шапкой
	давал ТОЛЬКО `margin-bottom` заголовка — а он у витрины обнулен
	инлайном (`.st-title` стоит в одной строке с переключателем). В итоге
	пилюля режимов лежала ВПРИТЫК к первой строке карточек; в темной
	палитре это било в глаза сильнее, потому что подложка пилюли
	(`--st-surface-alt`) и фон карточек там почти одного тона и сливались
	в одно пятно
*/
.st-products__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	flex-wrap: wrap;
	margin-bottom: 14px;
}

/* Переключатель режимов показа. В конструкторе это ВИТРИНА оставленных
   владельцем режимов (кнопки disabled — глобальное правило инертности),
   на публичном сайте — рабочий переключатель (stsite.js) */
.st-views {
	display: inline-flex;
	gap: 4px;
	padding: 4px;
	background-color: var(--st-surface-alt);
	border-radius: 999px;
}

.st-views__btn {
	padding: 6px 12px;
	border: 0;
	border-radius: 999px;
	background: transparent;
	color: var(--st-muted);
	font-size: 13px;
	font-weight: 600;
	cursor: default;
}

/* На сайте кнопка рабочая — и обязана выглядеть рабочей */
.st-views[data-st-views] .st-views__btn {
	cursor: pointer;
}

/*
	==== ИКОНОЧНЫЙ ВИД ПЕРЕКЛЮЧАТЕЛЯ (2026-08-15) ====

	ТОТ ЖЕ ОРГАН УПРАВЛЕНИЯ, ДРУГАЯ ПЛОТНОСТЬ. Кнопка становится квадратной
	(значок без подписи в прямоугольнике выглядит смещенным), название
	уходит в `title` — разметку готовит шаблон, здесь только размеры.

	Классы, порядок и контракт с `stsite.js` общие с текстовым видом:
	второй ветки в скрипте нет и не должно быть
*/
.st-views--icons .st-views__btn {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	font-size: 15px;
}

.st-views__btn--active {
	background-color: var(--st-surface);
	color: var(--st-text);
	box-shadow: var(--st-shadow);
}

.st-grid {
	display: grid;
	gap: 14px;
	grid-template-columns: repeat(var(--st-cols, 4), minmax(0, 1fr));
}

.st-product {
	position: relative;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	background-color: var(--st-surface);
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	box-shadow: var(--st-shadow);
}

/*
	==== РАСТЯНУТАЯ ССЫЛКА КАРТОЧКИ (2026-08-16) ====

	Карточка перестала быть одним большим `<a>` (пояснение —
	в `websiteProductCard`): внутри понадобился второй орган управления,
	сердечко избранного, а кнопка внутри ссылки невалидна.

	ССЫЛКА ПУСТАЯ И НАКРЫВАЕТ ВСЁ. Отсюда порядок слоев, и он не косметика:
	  1 — ссылка (нажатие в любом месте ведет на товар);
	  2 — столбик значков свойств: под ссылкой у него не работало бы
	      наведение, то есть пропали бы подсказки;
	  3 — сердечко: его нажатие обязано выигрывать у перехода
*/
.st-product__link {
	position: absolute;
	inset: 0;
	z-index: 1;
	display: block;
	border-radius: inherit;
}

/*
	==== СЕРДЕЧКО ИЗБРАННОГО ====

	ПОДЛОЖКА ОБЯЗАТЕЛЬНА, как у значков свойств: кнопка лежит поверх
	фотографии, и без своего фона она пропадала бы то на светлом кадре,
	то на темном.

	ЗАЛИТОЕ СЕРДЦЕ — ОТЛОЖЕНО, КОНТУРНОЕ — НЕТ. Значок один и тот же
	(`ki-solid ki-heart`), разница только в цвете и заливке: два разных
	значка в двух состояниях давали бы заметный скачок формы при нажатии
*/
.st-fav {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background-color: var(--st-surface);
	box-shadow: var(--st-shadow);
	color: var(--st-muted);
	font-size: 16px;
	line-height: 1;
	cursor: pointer;
	transition: color 0.15s ease, transform 0.15s ease;
}

.st-fav i {
	color: inherit;
}

.st-fav:hover {
	color: var(--st-danger);
	transform: scale(1.08);
}

.st-fav--on {
	color: var(--st-danger);
}

/* Отклик на само нажатие: состояние меняется мгновенно, и без короткого
   толчка глазом это читается как «ничего не произошло» */
.st-fav--beat {
	animation: stFavBeat 0.35s ease;
}

@keyframes stFavBeat {
	0% { transform: scale(1); }
	45% { transform: scale(1.28); }
	100% { transform: scale(1); }
}

/*
	==== СЕРДЕЧКО БОЛЬШЕ НЕ ПОЗИЦИОНИРУЕТ СЕБЯ САМО ====
	(переделка 2026-08-17)

	Место в углу обложки ему дает слой-накладка `.st-product__over`
	(см. ниже) — своих `position`, `top`, `left` и `right` у кнопки нет
	вовсе. Ровно поэтому она и не может больше оказаться в потоке
	обложки: в потоке обложки ее нет.

	ИСТОРИЯ, ЧТОБЫ НЕ ЗАВЕЛИ ЗАНОВО. Здесь стояло
	`position: absolute; top: 8px; right: 8px` плюс пара модификаторов
	стороны. На готовом сайте кнопка все равно вставала в поток: занимала
	строку над картинкой, сдвигала ее вниз (появлялась полоса фона)
	и накрывала первый значок свойств. Три попытки починить это стилями
	не дали ничего — и это диагноз самой конструкции, а не очередная
	опечатка в правиле
*/
.st-product__fav {
	flex: 0 0 auto;
}

@media (prefers-reduced-motion: reduce) {
	.st-fav {
		transition: none !important;
	}

	.st-fav:hover {
		transform: none !important;
	}

	.st-fav--beat {
		animation: none !important;
	}
}

/*
	==== КАРТОЧКА-ССЫЛКА (2026-08-14) ====

	Тег карточки стал `<a>` (страница товара `/product/000019`). Отклик
	живет ЗДЕСЬ, а не в `:hover` самой `.st-product`: у карточки без адреса
	(товар внешней площадки без ссылки) обещать переход нельзя.

	В КОНСТРУКТОРЕ ОТКЛИКА НЕТ ВОВСЕ — там ссылка инертна, и «поднимающаяся
	под курсором» карточка была бы ложным обещанием (правило ниже,
	в steditor.css, гасит наведение вместе с переходом)
*/
.st-product--link {
	cursor: pointer;
	transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.st-product--link:hover {
	transform: translateY(-2px);
	border-color: var(--st-accent);
}

@media (prefers-reduced-motion: reduce) {
	.st-product--link {
		transition: none !important;
	}

	.st-product--link:hover {
		transform: none !important;
	}
}

/*
	==== ОБЛОЖКА: КВАДРАТ И НАСТОЯЩАЯ КАРТИНКА (2026-08-15) ====

	ПРОПОРЦИЯ 1:1 — как у `.market-product-cover` в кабинете. Прежние 72%
	резали образец ламината по высоте, и одна и та же фотография выглядела
	в маркете и на витрине по-разному.

	ВНУТРИ `<img>`, А НЕ ФОН БЛОКА. Фон невозможно загрузить лениво без
	скрипта, у него нет `alt`, и он не участвует в подборе размера
	браузером. Заливка оставлена как подложка на время загрузки и для
	товара без фотографии
*/
/*
	ОБРЕЗКИ У ОБЛОЖКИ БОЛЬШЕ НЕТ (правка 2026-08-16). Кадрирует картинку
	сам `<img>` (`object-fit: cover` в размер обложки), а скругление углов
	держит `overflow: hidden` САМОЙ КАРТОЧКИ. Вторая обрезка была лишней
	и мешала одному: она срезала подсказку значка свойств, которая
	по определению выходит за пределы кружка
*/
.st-product__cover {
	position: relative;
	width: 100%;
	aspect-ratio: 1 / 1;
	background-color: var(--st-surface-alt);
}

.st-product__img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/*
	==== ЗНАЧКИ СВОЙСТВ ПОВЕРХ ОБЛОЖКИ ====

	СТОЛБИК У КРАЯ, НЕ РЯД: значков до пяти, а ряд из пяти кружков занял бы
	всю ширину карточки в плитке из четырех колонок.

	СТОРОНА — КЛАСС, А НЕ ПЕРЕМЕННАЯ: их ровно две, и обе меняют только
	одно свойство. Подложка кружка берется у поверхности темы (как
	`.market-product-prop` берет `--bs-body-bg`): значок обязан читаться
	и на темной фотографии, и на светлой
*/
/*
	==== СЛОЙ-НАКЛАДКА ОБЛОЖКИ (2026-08-17) ====

	ОДИН абсолютный узел на все, что рисуется поверх фотографии: столбик
	значков свойств у одного края и сердечко избранного у другого.
	Подробный разбор — в `websiteProductCard()`; коротко: пока это были
	ДВА независимых абсолютных элемента, каждый со своей парой
	`left`/`right`, сердечко на сайте выпадало в поток обложки и накрывало
	первый значок. Позиционируется теперь РОВНО ОДИН узел, а места внутри
	раздает флекс — промахнуться мимо угла стало нечем.

	`inset: 8px` ЗАМЕНЯЕТ ПРЕЖНИЕ `top/left/right: 8px` У ОБОИХ ДЕТЕЙ:
	отступ от края обложки стал свойством слоя и задан ОДИН раз.

	СТОРОНА — ОДНО СВОЙСТВО (`row-reverse`), а не две пары правил у двух
	элементов: «сердечко напротив значков» перестало быть договоренностью
	классов и стало свойством раскладки.

	`pointer-events: none` У САМОГО СЛОЯ ОБЯЗАТЕЛЕН: он накрывает всю
	обложку, а под ним лежит растянутая ссылка карточки — без этого
	нажатие по фотографии перестало бы вести на товар. Детям событие
	возвращается явно.

	z-index 3 — ВЫШЕ РАСТЯНУТОЙ ССЫЛКИ (у нее 1): под ней у значков
	не работало бы наведение, а вместе с ним пропали бы подсказки,
	и не нажималось бы сердечко
*/
.st-product__over {
	position: absolute;
	inset: 8px;
	z-index: 3;
	display: flex;
	flex-direction: row;
	align-items: flex-start;
	justify-content: space-between;
	gap: 8px;
	pointer-events: none;
}

/* Значки справа — сердечко уходит налево, и наоборот */
.st-product__over--right {
	flex-direction: row-reverse;
}

.st-product__over > * {
	pointer-events: auto;
}

.st-product__props {
	display: flex;
	flex-direction: column;
	gap: 8px;
	/* Пустой столбик остается вторым полюсом раскладки (без него
	   `space-between` прижал бы одинокое сердечко к чужому краю),
	   но места не занимает и нажатия не перехватывает */
	min-width: 0;
}

.st-product__props:empty {
	pointer-events: none;
}

.st-product__prop {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	border-radius: 50%;
	background-color: var(--st-surface);
	box-shadow: var(--st-shadow);
	font-size: 15px;
	line-height: 1;
}

.st-product__body {
	display: flex;
	flex-direction: column;
	gap: 4px;
	padding: 12px 14px 14px;
	/* ТЕЛО ЗАБИРАЕТ ОСТАТОК ВЫСОТЫ КАРТОЧКИ — иначе строке рейтинга
	   нечего прижимать к низу (`margin-top: auto` у .st-product__rating),
	   и у товаров с коротким и длинным названием она встала бы на разной
	   высоте: ряд плиток выглядел бы неровным */
	flex: 1 1 auto;
}

.st-product__price {
	font-size: 17px;
	font-weight: 700;
}

.st-product__price-old {
	margin-left: 6px;
	color: var(--st-muted);
	font-size: 13px;
	font-weight: 500;
	text-decoration: line-through;
}

.st-product__title {
	color: var(--st-muted);
	font-size: 14px;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Список */
.st-list {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

.st-list .st-product {
	flex-direction: row;
	align-items: stretch;
}

/* В СТРОКЕ ОБЛОЖКА ТЕРЯЕТ КВАДРАТ НАМЕРЕННО: высоту строки задает текст,
   и жесткая пропорция сделала бы карточку выше него */
.st-list .st-product__cover {
	flex: 0 0 132px;
	width: 132px;
	aspect-ratio: auto;
}

.st-list .st-product__body {
	justify-content: center;
}

/*
	Карусель: горизонтальная прокрутка без внешних зависимостей —
	слайдер Swiper используется только в медиа-блоке.

	==== ПОЛОСЫ ПРОКРУТКИ НЕТ, ЛЕНТА ТЯНЕТСЯ ЗАХВАТОМ (2026-08-15) ====

	Системная полоса под карточками выдавала «прокручиваемый div» вместо
	карусели и на macOS появлялась только во время прокрутки — то есть
	у половины посетителей карусель вообще ничем не отличалась от обрезанной
	строки. Взамен даны два понятных признака: курсор-ладонь и то, что лента
	едет за курсором (`initCarousel` в stsite.js; пальцем она ехала всегда).

	`scroll-behavior` НЕ ЗАДАЕТСЯ: плавная прокрутка спорит с перетаскиванием
	— лента продолжала бы «доезжать» после того, как ее отпустили
*/
.st-carousel {
	display: flex;
	gap: 14px;
	overflow-x: auto;
	padding-bottom: 6px;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-ms-overflow-style: none;
}

.st-carousel::-webkit-scrollbar {
	display: none;
}

.st-carousel .st-product {
	flex: 0 0 240px;
	scroll-snap-align: start;
}

/*
	КУРСОР-ЛАДОНЬ ТОЛЬКО НА САЙТЕ (`data-st-view-box` есть лишь у публичной
	разметки): в конструкторе лента не тянется — это общее правило
	инертности, и обещать захват там нельзя
*/
.st-carousel[data-st-view-box] {
	cursor: grab;
}

.st-carousel[data-st-view-box].st-carousel--drag {
	cursor: grabbing;
	scroll-snap-type: none;
}

/*
	ПОКА ЛЕНТУ ТЯНУТ, КАРТОЧКА НЕ ЛОВИТ КУРСОР: иначе на ней срабатывал бы
	отклик наведения, а отпускание превращалось бы в переход на товар
*/
.st-carousel--drag .st-product {
	pointer-events: none;
}

/* ==== ЛЕНИВАЯ ЗАГРУЗКА В КОНТУРЕ САЙТА ================================= */

/*
	==== ЗАГЛУШКИ НА ПЕРЕМЕННЫХ ТЕМЫ САЙТА (2026-08-15) ====

	Контракт разметки общий с кабинетом (`data-lazy` + `data-src`,
	класс `lazy-loaded` после загрузки), А ОФОРМЛЕНИЕ СВОЕ, и это
	обязательно: заглушки кабинета (`c_lazy`) написаны на `--bs-gray-*`,
	которых на публичном сайте нет вовсе, а в конструкторе они дают
	СЕРЫЙ прямоугольник посреди темной темы витрины.

	ВЕС СЕЛЕКТОРА ВЗЯТ С ЗАПАСОМ (`.st-site img[data-lazy]` = 0,1,2 против
	0,1,1 у `c_lazy`): стили кабинета приходят инлайном в конце `<head>`,
	то есть при равном весе побеждали бы они.

	ГРУЗИТ КАРТИНКИ РАЗНЫЙ КОД: в кабинете — Lozad из бандла сервиса,
	на сайте — `initLazy()` в stsite.js (бандла Metronic там нет).
	Разметка и классы у обоих одни, поэтому правило здесь одно
*/
@keyframes stLazyPulse {
	0%, 100% { opacity: 1; }
	50% { opacity: 0.55; }
}

/*
	ПОДЛОЖКА ЖИВЕТ ТОЛЬКО ДО ЗАГРУЗКИ. Оставь ее насовсем — и логотип
	бренда с прозрачным фоном получил бы под собой серый прямоугольник
	навсегда, хотя его прозрачность и есть часть оформления
*/
.st-site img[data-lazy]:not(.lazy-loaded),
.st-site [data-lazy][data-background-image]:not(.lazy-loaded) {
	background-color: var(--st-surface-alt);
}

.st-site img[data-lazy] {
	transition: filter 0.4s ease;
}

.st-site img[data-lazy]:not(.lazy-loaded),
.st-site [data-lazy][data-background-image]:not(.lazy-loaded) {
	animation: stLazyPulse 1.6s ease-in-out infinite;
}

/* Blur-up: пока грузится оригинал, в `src` стоит мини-копия 64 px */
.st-site img[data-lazy].lazy-lqip:not(.lazy-loaded) {
	filter: blur(14px);
	clip-path: inset(0);
}

.st-site [data-lazy][data-background-image] {
	position: relative;
	overflow: hidden;
}

.st-site [data-lazy][data-background-image]::before {
	content: "";
	position: absolute;
	inset: 0;
	background-image: var(--lazy-lqip, none);
	background-size: cover;
	background-position: center;
	filter: blur(14px);
	transform: scale(1.08);
	pointer-events: none;
	transition: opacity 0.4s ease;
}

.st-site [data-lazy][data-background-image].lazy-loaded::before {
	opacity: 0;
	animation: none;
}

/* Просьба «без движения» гасит пульсацию: она идет бесконечно и потому
   раздражает сильнее любой разовой анимации */
@media (prefers-reduced-motion: reduce) {
	.st-site img[data-lazy]:not(.lazy-loaded),
	.st-site [data-lazy][data-background-image]:not(.lazy-loaded) {
		animation: none;
	}
}

/* ==== ПОДВАЛ (закрепленный блок) ======================================= */

/*
	ПОДВАЛ ЛЕЖИТ ВНУТРИ КОНТЕЙНЕРА СЕКЦИИ (правка 2026-08-03): закрепленному
	блоку разрешили ШИРИНУ В КОЛОНКАХ, а она задается сеткой секции — как
	у обычных блоков. Раньше `.st-footer` был отдельной полосой во всю
	ширину, и никакой ширины у него быть не могло
*/
.st-footer {
	padding: 22px 20px 30px;
	border-top: 1px solid var(--st-border);
	color: var(--st-muted);
	font-size: 13px;
	line-height: 1.6;
}

/* РАСПОЛОЖЕНИЕ ТЕКСТА — вторая (и последняя) настройка подвала.
   Сам текст по-прежнему приходит из глобального дисклеймера сервиса */
.st-footer--left { text-align: left; }
.st-footer--center { text-align: center; }
.st-footer--right { text-align: right; }

.st-footer p {
	margin-bottom: 8px;
}

.st-footer p:last-child {
	margin-bottom: 0;
}

.st-footer img {
	max-width: 100%;
	border-radius: var(--st-radius-sm);
}

/* ==== АДАПТИВ =========================================================== */
/*
	КОЛОНКИ СЕТОК.

	Число колонок задает САМА СЕКЦИЯ переменной --st-cols (сетка товаров)
	или --st-media-cols (сетка медиа): значение устройства в нее уже
	подставлено сервером при сборке раскладки (websiteLayoutMerge —
	merge(base, overrides[device])). Правила ниже остаются РАЗУМНЫМ
	УМОЛЧАНИЕМ на случай, когда владелец своего числа не задавал:
	четыре плитки в ряд на телефоне нечитаемы
*/

@media (min-width: 992px) {
	.st-grid { grid-template-columns: repeat(var(--st-cols, 4), minmax(0, 1fr)); }
	.st-media__grid { grid-template-columns: repeat(var(--st-media-cols, 3), minmax(0, 1fr)); }
}

/*
	СЕТКИ ПЕРВОЙ ВОЛНЫ ЖИВУТ ПО ТЕМ ЖЕ ПРАВИЛАМ, ЧТО И СЕТКА ТОВАРОВ
	(2026-08-10): те же точки перелома, та же переменная `--st-cols`, тот же
	приоритет ЯВНО заданного числа колонок (`--st-cols-fixed`).
	Второго набора правил адаптива в проекте быть не должно — он разошелся бы
	с первым на первой же правке
*/
@media (max-width: 991.98px) {
	.st-grid { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 3)), minmax(0, 1fr)); }
	.st-media__grid { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-media-cols, 3), 2)), minmax(0, 1fr)); }
	.st-cards,
	.st-reviews__grid { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 3), 2)), minmax(0, 1fr)); }
	/* ВТОРАЯ ВОЛНА: те же точки перелома и то же правило приоритета явно
	   заданного числа колонок */
	.st-counters { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 2)), minmax(0, 1fr)); }
	.st-docs { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 3)), minmax(0, 1fr)); }
	.st-socials-row--tiles { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 6), 4)), minmax(0, 1fr)); }
	/* ЛЕНТА ЭТАПОВ НА УЗКОМ ЭКРАНЕ РАЗВОРАЧИВАЕТСЯ В СТОЛБЕЦ, и это
	   запасной вариант: обычно ориентацию решает сервер по устройству —
	   медиазапросы внутри «листа» конструктора считаются от окна и врут */
	.st-steps--row { grid-template-columns: minmax(0, 1fr); }
	.st-steps--row .st-step { flex-direction: row; }
	.st-steps--line.st-steps--row .st-step:not(:last-child)::after { display: none; }
}

@media (max-width: 575.98px) {
	/* Отступ переменной, а не прямым padding: снизу к нему прибавляется
	   спейсер (см. `.st-block--spaced`) */
	.st-block { --st-pad-y: 20px; padding-left: 14px; padding-right: 14px; }
	.st-block--full { padding-left: 0; padding-right: 0; }
	.st-title { font-size: 20px; }
	.st-grid { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 2)), minmax(0, 1fr)); }
	.st-media__grid { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-media-cols, 3), 1)), minmax(0, 1fr)); }
	.st-list .st-product__cover { flex-basis: 96px; width: 96px; }
	.st-contacts--row { grid-template-columns: 1fr; }
	.st-map--lg { height: 380px; }
	/* ПЕРВАЯ ВОЛНА: на телефоне карточки идут в одну колонку, форма
	   и таблица занимают всю ширину */
	.st-cards,
	.st-reviews__grid { grid-template-columns: repeat(var(--st-cols-fixed, 1), minmax(0, 1fr)); }
	.st-lead { padding-left: 16px; padding-right: 16px; }
	.st-lead__btn { align-self: stretch; text-align: center; }
	/* ВТОРАЯ ВОЛНА НА ТЕЛЕФОНЕ: счетчики в две колонки (короткая цифра
	   с подписью читается и так), документы в две, плитки соцсетей в три.
	   В одну колонку уходят только сами блоки, а не их содержимое */
	.st-counters { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 2)), minmax(0, 1fr)); }
	.st-docs { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 2)), minmax(0, 1fr)); }
	.st-socials-row--tiles { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 6), 3)), minmax(0, 1fr)); }
	.st-cta { padding-left: 18px; padding-right: 18px; }
	.st-cta__title { font-size: 22px; }
	.st-timer__plate { min-width: 64px; }
	.st-timer__num { font-size: 28px; }
	/* Строка спейсера на настоящем узком экране — та же, что в предпросмотре
	   телефона: значение одно, просто задается двумя путями */
	.st-site { --st-spacer-line: 18px; }
}

/* ==== ФИКСАЦИЯ УСТРОЙСТВА (этап B) ===================================== */
/*
	ГРАБЛИ, ИЗ-ЗА КОТОРЫХ УЗКИЙ ПРЕДПРОСМОТР ВРАЛ БЫ.

	Медиазапросы внутри «листа» конструктора считаются от ОКНА БРАУЗЕРА,
	а не от ширины листа: в мобильном предпросмотре шириной 400 px они
	по-прежнему видят широкое окно и раскладывают сетки по-десктопному.
	Поэтому конструктор ФИКСИРУЕТ устройство атрибутом `data-st-device`
	на корне сайта, а правила ниже перебивают медиазапросы специфичностью
	(0,2,1 против 0,1,0) независимо от порядка.

	На НАСТОЯЩЕЙ публичной странице атрибута не будет: там ширина окна
	честная, и работают обычные медиазапросы выше
*/
.st-site[data-st-device="desktop"] .st-grid {
	grid-template-columns: repeat(var(--st-cols, 4), minmax(0, 1fr));
}

.st-site[data-st-device="desktop"] .st-media__grid {
	grid-template-columns: repeat(var(--st-media-cols, 3), minmax(0, 1fr));
}

/*
	СЕТКИ ПЕРВОЙ ВОЛНЫ ФИКСИРУЮТСЯ ТЕМ ЖЕ АТРИБУТОМ (2026-08-10): в узком
	«листе» медиазапросы видят широкое окно браузера, и без этих правил
	мобильный предпросмотр показывал бы три карточки в ряд
*/
.st-site[data-st-device="desktop"] .st-cards,
.st-site[data-st-device="desktop"] .st-reviews__grid {
	grid-template-columns: repeat(var(--st-cols, 3), minmax(0, 1fr));
}

.st-site[data-st-device="tablet"] .st-cards,
.st-site[data-st-device="tablet"] .st-reviews__grid {
	grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 3), 2)), minmax(0, 1fr));
}

.st-site[data-st-device="mobile"] .st-cards,
.st-site[data-st-device="mobile"] .st-reviews__grid {
	grid-template-columns: repeat(var(--st-cols-fixed, 1), minmax(0, 1fr));
}

.st-site[data-st-device="mobile"] .st-lead__btn {
	align-self: stretch;
	text-align: center;
}

/*
	СЕТКИ ВТОРОЙ ВОЛНЫ ФИКСИРУЮТСЯ ТЕМ ЖЕ АТРИБУТОМ (2026-08-13) — иначе
	мобильный предпросмотр показывал бы четыре счетчика в ряд: медиазапросы
	в узком «листе» видят широкое окно браузера
*/
.st-site[data-st-device="desktop"] .st-counters { grid-template-columns: repeat(var(--st-cols, 4), minmax(0, 1fr)); }
.st-site[data-st-device="desktop"] .st-docs { grid-template-columns: repeat(var(--st-cols, 4), minmax(0, 1fr)); }
.st-site[data-st-device="desktop"] .st-socials-row--tiles { grid-template-columns: repeat(var(--st-cols, 6), minmax(0, 1fr)); }

.st-site[data-st-device="tablet"] .st-counters { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 2)), minmax(0, 1fr)); }
.st-site[data-st-device="tablet"] .st-docs { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 3)), minmax(0, 1fr)); }
.st-site[data-st-device="tablet"] .st-socials-row--tiles { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 6), 4)), minmax(0, 1fr)); }

.st-site[data-st-device="mobile"] .st-counters { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 2)), minmax(0, 1fr)); }
.st-site[data-st-device="mobile"] .st-docs { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 2)), minmax(0, 1fr)); }
.st-site[data-st-device="mobile"] .st-socials-row--tiles { grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 6), 3)), minmax(0, 1fr)); }

.st-site[data-st-device="mobile"] .st-cta__title { font-size: 22px; }
.st-site[data-st-device="mobile"] .st-timer__plate { min-width: 64px; }
.st-site[data-st-device="mobile"] .st-timer__num { font-size: 28px; }

/*
	ЯВНО ЗАДАННОЕ ЧИСЛО КОЛОНОК НЕ УРЕЗАЕТСЯ: `--st-cols-fixed` ставит
	секция, у которой владелец ЗАДАЛ колонки именно для этого устройства.
	Умолчание («на телефоне не больше двух») спасает того, кто о телефоне
	не думал, но не должно спорить с явным решением
*/
.st-site[data-st-device="tablet"] .st-grid {
	grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 3)), minmax(0, 1fr));
}

.st-site[data-st-device="tablet"] .st-media__grid {
	grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-media-cols, 3), 2)), minmax(0, 1fr));
}

.st-site[data-st-device="mobile"] .st-grid {
	grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-cols, 4), 2)), minmax(0, 1fr));
}

.st-site[data-st-device="mobile"] .st-media__grid {
	grid-template-columns: repeat(var(--st-cols-fixed, min(var(--st-media-cols, 3), 1)), minmax(0, 1fr));
}

/* Отступ узкого экрана — ТОЖЕ переменной (правка 2026-08-10): прямое
   значение затерло бы сумму «свой отступ + спейсер» */
.st-site[data-st-device="mobile"] .st-block {
	--st-pad-y: 20px;

	padding-left: 14px;
	padding-right: 14px;
}

.st-site[data-st-device="mobile"] .st-block--full {
	padding-left: 0;
	padding-right: 0;
}

.st-site[data-st-device="mobile"] .st-title {
	font-size: 20px;
}

.st-site[data-st-device="mobile"] .st-contacts--row {
	grid-template-columns: 1fr;
}

/* ==== ВЕРТИКАЛЬНЫЕ ОТСТУПЫ СЕКЦИИ (этап B) ============================= */
/*
	Своя настройка секции, переопределяемая по устройствам: на телефоне
	секции почти всегда нужно меньше воздуха, чем на ПК. Класс ставится
	ТОЛЬКО когда владелец задал значение — иначе отступ дает тема
*/
/*
	ОТСТУПЫ ЗАДАЮТСЯ ПЕРЕМЕННОЙ, А НЕ ПРЯМЫМ padding (правка 2026-08-10).

	Понадобилось спейсеру (`common.spacer_after`): его величина ПРИБАВЛЯЕТСЯ
	к собственному отступу секции, а прямой `padding-bottom` в этих четырех
	правилах затирал бы сумму — и «доп. отступ» молча пропадал бы у любой
	секции, где владелец задал свои отступы.
	Величина отступа теперь живет в `--st-pad-y`, а складывает их одно
	правило `.st-block` выше
*/
.st-site .st-block--pad-none { --st-pad-y: 0px; }
.st-site .st-block--pad-sm { --st-pad-y: 14px; }
.st-site .st-block--pad-md { --st-pad-y: 34px; }
.st-site .st-block--pad-lg { --st-pad-y: 64px; }
/* ==== КАРТОЧКА-МАРКЕР ИИ-АССИСТЕНТА (2026-08-05) ======================= */
/*
	ЧТО ЭТО И ЧЕГО ЭТО НЕ ЕСТЬ. Сам виджет ассистента — плавающая кнопка
	с выдвижной панелью, у него свой бандл (stwidget.css) и своя геометрия.
	Здесь описан только ЯКОРЬ В КОНСТРУКТОРЕ: без видимого представления
	блок нельзя ни выбрать, ни настроить, ни удалить — он существовал бы
	лишь в JSON.

	НА САЙТ КАРТОЧКА НЕ ПОПАДАЕТ ВОВСЕ (шаблон рисует ее только при
	$editor), поэтому здесь нет ни одного правила «как на публичной
	странице»: их просто не к чему применять.

	Стили лежат в файле САЙТА, а не конструктора, потому что классы у нее
	`st-*` и рисуется она внутри `.st-site` — по переменным его темы
*/
.st-site .st-ai-card {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 16px 18px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	/* Собственный текст карточки не наследует цвет секции: она служебная
	   и обязана читаться на любом фоне, который владелец выбрал секции */
	color: var(--st-text-base);
}

.st-site .st-ai-card__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	border-radius: 999px;
	background-color: var(--st-accent);
	/*
		ЗНАЧОК БЕЛЫЙ, А НЕ `--st-accent-text` (правка 2026-08-06).

		У ТЕМНОЙ палитры темы «текст на акценте» — почти черный (#0F1218),
		и на брендовом зеленом кружке значок выходил тусклым пятном: карточка
		читалась как выключенная, хотя ассистент подключен.

		Настоящая кнопка виджета решает это расчетом контраста на сервере
		(websiteInkColor), но карточка — СЛУЖЕБНЫЙ МАРКЕР конструктора,
		на сайт она не попадает, и городить ради нее инлайновый стиль
		незачем. Плата честная: со светлым акцентом значок побледнеет —
		тогда и здесь понадобится расчет
	*/
	color: #FFFFFF;
	font-size: 20px;
	overflow: hidden;
}

/*
	ЛОГОТИП ПРОВАЙДЕРА ВМЕСТО ЗНАЧКА.

	АКЦЕНТНАЯ ПОДЛОЖКА УБИРАЕТСЯ: у файлов логотипов СВОЙ фирменный фон
	(красный квадрат Яндекса, синий DeepSeek), и зеленый кружок под ними
	читался бы как ошибка верстки.

	СКРУГЛЕНИЕ, А НЕ КРУГ: логотип — чужая марка со своей композицией,
	и круглая обрезка съедала бы ее углы. `contain` обязателен по той же
	причине, что и в плитках выбора провайдера: файлы подменяемые,
	и пропорции у них будут любые
*/
.st-site .st-ai-card__icon--logo {
	background-color: transparent;
	border-radius: 12px;
}

/*
	KeenIcons НАВЯЗЫВАЕТ значкам свой цвет правилом в конце
	plugins.bundle.css (`.ki-outline{color:var(--bs-text-muted)}`), и оно
	бьет по самому `<i>`, а не наследуется. Без этой строки белый цвет,
	заданный выше родителю, до значка не доходил — карточка выглядела
	выключенной. Те же грабли у кнопки виджета и у значков разделов панели
*/
.st-site .st-ai-card__icon i {
	color: inherit;
}

.st-site .st-ai-card__icon img {
	display: block;
	width: 100%;
	height: 100%;
	border-radius: inherit;
	object-fit: contain;
}

.st-site .st-ai-card__body {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.st-site .st-ai-card__title {
	font-weight: 700;
}

.st-site .st-ai-card__note {
	font-size: 13px;
	color: var(--st-muted);
}

.st-site .st-ai-card__hint {
	font-size: 12px;
	color: var(--st-muted);
	opacity: 0.85;
}

/* ==== ПУБЛИЧНАЯ СТРАНИЦА: ОДИН DOM, ТРИ РАСКЛАДКИ ====================== */
/*
	(2026-08-13)

	ЧТО ЭТО РЕШАЕТ. Конструктор рисует раскладку ОДНОГО устройства —
	владелец выбирает его переключателем, и координаты приезжают четырьмя
	переменными. Публичная страница устройства посетителя не знает: она
	считает ТРИ раскладки (merge для desktop/tablet/mobile) и выводит
	ОДИН DOM, где различия выражены переменными с суффиксом точки перелома.

	ПОЧЕМУ НЕ ТРИ КОПИИ РАЗМЕТКИ: три копии — это тройной вес страницы,
	тройной DOM для поисковика и три экземпляра каждого якоря, поля формы
	и картинки. Второй узел появляется РОВНО ТАМ, где разметка честно
	разная (нижняя панель навигации вместо строки меню, переопределенное
	выравнивание), и гасится классом `st-off-*` на остальных ширинах.

	СУФФИКСЫ КОРОТКИЕ (`-d` / `-t` / `-m`) НАМЕРЕННО: переменные пишутся
	на КАЖДЫЙ блок страницы, и полные имена устройств раздули бы разметку
	впустую.

	КАСКАД ЗАМЕНЯЕТ ПОВТОРЫ: сервер печатает значение планшета и телефона,
	только если оно ОТЛИЧАЕТСЯ от ПК, а `var(--x-t, var(--x-d))` берет
	недостающее у базы — ровно как переопределения устройств в модели.

	ВСЕ ПРАВИЛА ЗДЕСЬ ПОД `.st-site--live`. Этого класса в конструкторе
	нет: там устройство фиксировано атрибутом `data-st-device`, и два
	механизма координат столкнулись бы лбами
*/

/* ==== ПК (БАЗА) ==== */

.st-site--live .st-block {
	--st-col-start: var(--st-col-start-d, 1);
	--st-span: var(--st-span-d, 12);
	--st-row-start: var(--st-row-start-d, auto);
	--st-rows: var(--st-rows-d, 1);
	--st-spacer: var(--st-spacer-d, 0);
}

.st-site--live .st-page,
.st-site--live .st-chrome,
.st-site--live .st-section__grid {
	--st-levels: var(--st-levels-d, 1);
}

/*
	ЦЕНТРОВКА И ГАШЕНИЕ ВАРИАНТА — ВНУТРИ МЕДИАЗАПРОСА ПК, в отличие
	от переменных выше.

	ГРАБЛИ, КОТОРЫЕ ЭТО ЛЕЧИТ: `.st-off-d` без медиазапроса спрятал бы
	вариант НА ВСЕХ ширинах — то есть узел, предназначенный планшету
	и телефону, не показался бы нигде. Переменные так вести себя не могут
	(их перекрывают медиазапросы ниже), а вот `display: none` перекрывать
	нечем.

	Центровка повторяет правило `.st-block--center`: второго способа
	центрировать элемент 2D-сетки нет
*/
@media (min-width: 992px) {
	.st-site--live .st-page > .st-center-d,
	.st-site--live .st-chrome > .st-center-d {
		grid-column: 1 / span 12;
		width: calc(var(--st-span, 12) / 12 * 100%);
		margin-left: auto;
		margin-right: auto;
	}

	.st-site--live .st-off-d {
		display: none;
	}
}

/* ==== ПЛАНШЕТ (576…991) ==== */

@media (min-width: 576px) and (max-width: 991.98px) {
	.st-site--live .st-block {
		--st-col-start: var(--st-col-start-t, var(--st-col-start-d, 1));
		--st-span: var(--st-span-t, var(--st-span-d, 12));
		--st-row-start: var(--st-row-start-t, var(--st-row-start-d, auto));
		--st-rows: var(--st-rows-t, var(--st-rows-d, 1));
		--st-spacer: var(--st-spacer-t, var(--st-spacer-d, 0));
	}

	.st-site--live .st-page,
	.st-site--live .st-chrome,
	.st-site--live .st-section__grid {
		--st-levels: var(--st-levels-t, var(--st-levels-d, 1));
	}

	.st-site--live .st-page > .st-center-t,
	.st-site--live .st-chrome > .st-center-t {
		grid-column: 1 / span 12;
		width: calc(var(--st-span, 12) / 12 * 100%);
		margin-left: auto;
		margin-right: auto;
	}

	.st-site--live .st-off-t {
		display: none;
	}

	/* Строка спейсера на узком экране короче — то же значение, что дает
	   атрибут устройства в конструкторе */
	.st-site--live {
		--st-spacer-line: 18px;
	}
}

/* ==== ТЕЛЕФОН (<576) ==== */

@media (max-width: 575.98px) {
	.st-site--live .st-block {
		--st-col-start: var(--st-col-start-m, var(--st-col-start-d, 1));
		--st-span: var(--st-span-m, var(--st-span-d, 12));
		--st-row-start: var(--st-row-start-m, var(--st-row-start-d, auto));
		--st-rows: var(--st-rows-m, var(--st-rows-d, 1));
		--st-spacer: var(--st-spacer-m, var(--st-spacer-d, 0));
	}

	.st-site--live .st-page,
	.st-site--live .st-chrome,
	.st-site--live .st-section__grid {
		--st-levels: var(--st-levels-m, var(--st-levels-d, 1));
	}

	.st-site--live .st-page > .st-center-m,
	.st-site--live .st-chrome > .st-center-m {
		grid-column: 1 / span 12;
		width: calc(var(--st-span, 12) / 12 * 100%);
		margin-left: auto;
		margin-right: auto;
	}

	.st-site--live .st-off-m {
		display: none;
	}

	.st-site--live {
		--st-spacer-line: 18px;
	}
}

/*
	==== МЕСТО ПОД НИЖНЮЮ ПАНЕЛЬ НАВИГАЦИИ ====

	Панель вынута из потока (position: fixed), и последний блок страницы
	уехал бы под нее. Общее правило `.st-site:has(.st-nav)` резервирует
	место ВСЕГДА — а на публичной странице панель лежит в разметке даже
	там, где она невидима (это второй вариант блока «Меню»).

	Поэтому здесь резерв СНИМАЕТСЯ на тех ширинах, где вариант с панелью
	погашен: `:has(.st-block.st-off-X .st-nav)` читается как «панель есть,
	но на этой ширине она выключена». Когда владелец включил панель
	на всех устройствах, вариант один, класса `st-off-*` у него нет —
	и место резервируется везде, как и должно
*/
@media (min-width: 992px) {
	.st-site.st-site--live:has(.st-block.st-off-d .st-nav) {
		padding-bottom: 12px;
	}
}

@media (min-width: 576px) and (max-width: 991.98px) {
	.st-site.st-site--live:has(.st-block.st-off-t .st-nav) {
		padding-bottom: 12px;
	}
}

@media (max-width: 575.98px) {
	.st-site.st-site--live:has(.st-block.st-off-m .st-nav) {
		padding-bottom: 12px;
	}
}

/* ======================================================================= */
/* ==== ПАНЕЛЬ СОГЛАСИЯ НА COOKIE (2026-08-14) =========================== */
/* ======================================================================= */
/*
	СИСТЕМНЫЙ БЛОК ПОДВАЛА: он есть на каждом сайте и не удаляется.
	Стили лежат в ОБЩЕМ файле темы (а не в `stsite.css`), потому что панель
	видна и в конструкторе — владелец обязан видеть, что настраивает.

	ЗАКРЕПЛЕНА ЗА ОКНОМ (`position: fixed`), И ЭТО ЕДИНСТВЕННОЕ МЕСТО
	В ФАЙЛЕ, ГДЕ FIXED ОПРАВДАН НА СОДЕРЖИМОМ БЛОКА. Обычно фиксированное
	позиционирование в конструкторе запрещено (в «листе» оно отсчитывается
	от ОКНА БРАУЗЕРА и вылезает за пределы предпросмотра) — здесь это
	и требуется: панель обязана лежать поверх страницы, а в конструкторе
	владелец видит ее ровно там, где увидит посетитель.

	ЦВЕТА — ПЕРЕМЕННЫЕ С УМОЛЧАНИЕМ ИЗ ПАЛИТРЫ ТЕМЫ. Пустая настройка
	переменную не печатает, и работает значение отсюда: сайт с любой темой
	получает читаемую панель без единой правки
*/
.st-site .st-cookie {
	--st-cookie-bg: var(--st-surface);
	--st-cookie-fg: var(--st-text-base);
	--st-cookie-btn-bg: var(--st-accent);
	--st-cookie-btn-fg: var(--st-accent-text);

	position: fixed;
	/*
		==== 1300, А НЕ 1200 (исправлено 2026-08-15) ====

		У КОРНЯ ВИДЖЕТА АССИСТЕНТА (`.stw`) БЫЛ РОВНО ТОТ ЖЕ 1200, а идет
		он в документе ПОЗЖЕ — значит выигрывал. Корень растянут на весь
		экран, и хотя сам он `pointer-events: none`, его кнопка
		(`pointer-events: auto`) стоит в том же нижнем углу и НАКРЫВАЛА
		кнопку «Принять»: нажатие уходило виджету, панель не закрывалась.

		Старшинство отдано согласию осознанно: до ответа посетителя это
		САМЫЙ ВАЖНЫЙ элемент страницы. Чтобы кнопка ассистента при этом
		не оказалась под панелью, она поднимается на ее высоту —
		см. `--st-cookie-h` в stwidget.css
	*/
	z-index: 1300;
	bottom: var(--st-cookie-offset, 20px);
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 14px 18px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-cookie-bg);
	color: var(--st-cookie-fg);
	box-shadow: 0 10px 34px rgba(12, 16, 24, 0.22);
}

/*
	==== ШИРИНА И МЕСТО — ИЗ СЕТКИ, ЧЕТЫРЕ ПРЕСЕТА УДАЛЕНЫ (2026-08-15) ====

	Было: `--wide` / `--center` / `--left` / `--right` — четыре готовых
	положения и два зашитых потолка ширины (420 и 560 px). Стало: те же
	`span` и `col`, что у любого блока сетки, — то есть НЕПРЕРЫВНОЕ место
	(«с 5-й колонки шириной в 6» пресетом не выразить) и ширина, которую
	владелец тянет якорями прямо на холсте.

	ДОРОЖКА СЧИТАЕТСЯ ОТ ОКНА, А НЕ ОТ КОНТЕЙНЕРА САЙТА. Полоса —
	`position: fixed`, и проценты в `left`/`width` у нее разрешаются
	по ширине ОКНА. Отсюда бесплатно берется требуемое поведение:
	крайняя колонка прижимает полосу к КРАЮ ЭКРАНА, а не к границе
	содержимого. `100%` вместо `100vw` выбрано намеренно — `vw` считает
	вместе с полосой прокрутки и дает горизонтальный вылет.

	ПОЛОЖЕНИЕ — ТОЛЬКО ПО ГОРИЗОНТАЛИ. Панель всегда у нижнего края:
	согласие сверху перекрывает шапку и читается как рекламный баннер
*/
/*
	==== ДВЕ ДОРОЖКИ, И ВЫБОР МЕЖДУ НИМИ — ЭТО ПРАВИЛО (2026-08-15) ====

	ПО УМОЛЧАНИЮ ПОЛОСА ЖИВЕТ В КОРОБКЕ СТРАНИЦЫ (`--st-page`), а не во всю
	ширину окна. Причина: «во всю ширину» у полосы согласия читается как
	«во всю ширину САЙТА», а сайт с обычной или узкой страницей заканчивается
	раньше края экрана — полоса выпирала за его содержимое и выглядела
	чужой деталью поверх витрины.

	ПРИЖАТАЯ К ОДНОМУ КРАЮ — ИСКЛЮЧЕНИЕ (`--edge`). Если владелец увел
	полосу к левому или правому краю, он хочет ИМЕННО УГОЛ ЭКРАНА:
	коробка страницы там только мешала бы, оставляя необъяснимый зазор.
	Класс ставит шаблон (`e_user_steditor_cookie`), потому что «прижата
	ровно к одному краю» — это арифметика по `col` и `span`, а CSS
	сравнивать числа не умеет.

	ДВЕ ПЕРЕМЕННЫЕ, И ПУТАТЬ ИХ НЕЛЬЗЯ: `--st-cookie-track` — ДЛИНА
	дорожки, по которой раскладываются двенадцать колонок;
	`--st-cookie-rail` — где эта дорожка НАЧИНАЕТСЯ
*/
.st-site .st-cookie {
	--st-cookie-track: min(
		calc(100% - 2 * var(--st-cookie-offset, 20px)),
		var(--st-page, 1220px)
	);
	--st-cookie-rail: calc((100% - var(--st-cookie-track)) / 2);

	left: calc(var(--st-cookie-rail)
		+ var(--st-cookie-track) * var(--st-cookie-col, 0) / 12);
	right: auto;
	width: calc(var(--st-cookie-track) * var(--st-cookie-span, 12) / 12);
}

/* Прижата к краю — считаем от ОКНА: у края экрана коробка страницы
   не при чем (см. пояснение выше) */
.st-site .st-cookie--edge {
	--st-cookie-track: calc(100% - 2 * var(--st-cookie-offset, 20px));
	--st-cookie-rail: var(--st-cookie-offset, 20px);
}

/*
	НА ТЕЛЕФОНЕ ПОЛОСА ВСЕГДА ВО ВСЮ ШИРИНУ.

	Разметка публичной страницы одна на три раскладки, а переменные полосы
	печатаются по ПК — на узком экране треть экрана превратила бы согласие
	в нечитаемый столбик. Тот же порог и то же правило, что у
	`block_min_span_mobile._default = 12` на сервере
*/
@media (max-width: 767.98px) {
	.st-site .st-cookie {
		/* На узком экране коробка страницы и так шире него — дорожка
		   всегда идет от края до края, поэтому пересчитываем обе переменные */
		--st-cookie-track: calc(100% - 2 * var(--st-cookie-offset, 20px));
		--st-cookie-rail: var(--st-cookie-offset, 20px);

		left: var(--st-cookie-offset, 20px);
		width: var(--st-cookie-track);
	}
}

/*
	РАЗМЕР — С ПРЕФИКСОМ `.st-site` (исправлено 2026-08-15). Без него
	у правил вес 0,1,0 против 0,2,0 у базового объявления выше: `font-size`
	применялся (его в базе нет), а `padding` молча проигрывал — панель
	«маленькая» и «крупная» отличались только кеглем
*/
.st-site .st-cookie--sm { padding: 10px 14px; font-size: 13px; }
.st-site .st-cookie--lg { padding: 20px 24px; font-size: 16px; }

.st-cookie__icon {
	flex: 0 0 auto;
	/* РАЗМЕР ЗАДАН ОДНОЙ ПЕРЕМЕННОЙ (шаблон печатает `--st-cookie-icon`),
	   и она же ниже держит габарит своего SVG: значок из набора и свой файл
	   обязаны занимать одно место, иначе смена значка перекраивает панель */
	font-size: var(--st-cookie-icon, 24px);
	line-height: 1;
	color: var(--st-accent);
}

/*
	==== ЦВЕТ ЗНАЧКА — СЕЛЕКТОРОМ ОТ ТЕГА (2026-08-22) ====

	ЗНАЧОК ПОБЕЛЕЛ НЕ САМ. Правило выше объявлено ОДНИМ КЛАССОМ (0,1,0),
	а с 2026-08-21 в файле стоит `.st-site.st-site i { color: inherit }`
	(0,2,1) — общее правило, снявшее серый цвет со значков Font Awesome
	и Line Awesome. Оно тяжелее и выигрывает: значок панели согласия начал
	наследовать цвет текста полосы, то есть стал белым.

	ЛЕЧЕНИЕ ТО ЖЕ, ЧТО У ЗНАЧКА УПАКОВКИ И ЗНАЧКА ПРИМЕРКИ: селектор
	от ТЕГА (`i.` = 0,2,1) и ниже по файлу — при равном весе выигрывает
	последний. `!important` здесь был бы хуже болезни: он перебил бы
	и цвет, выбранный владельцем в настройках значка (тот едет инлайном)
*/
.st-site i.st-cookie__icon {
	color: var(--st-accent);
}

/*
	СВОЙ SVG — КАРТИНКА, А НЕ ШРИФТ: цвет ей задает сам файл (встроенный
	SVG на публичной странице — вектор XSS, см. шаблон). Отсюда и `contain`:
	пропорции чужого файла неизвестны, а квадратное место под значок —
	известно
*/
.st-cookie__icon--svg {
	width: var(--st-cookie-icon, 24px);
	height: var(--st-cookie-icon, 24px);
	object-fit: contain;
}

/*
	==== РАСКЛАДКА ПО ОБРАЗЦАМ ВЛАДЕЛЬЦА (2026-08-15) ====

	ПОЛОСОЙ (`--row`) — поведение по умолчанию, отдельного класса ему
	не нужно: правила выше уже описывают ряд.

	КАРТОЧКОЙ (`--card`) — колонка: значок сверху, кнопка во всю ширину.
	Так собраны узкие панели в углу экрана: кнопка рядом с двумя строками
	текста в колонке шириной в три сетки ужалась бы до нечитаемой
*/
.st-site .st-cookie--card {
	flex-direction: column;
	align-items: flex-start;
}

/*
	ТЕКСТ И КНОПКА — ВО ВСЮ ШИРИНУ КАРТОЧКИ. `align-items` у колонки жмет
	детей по содержимому, и без этих двух правил абзац вставал бы «лесенкой»
	по самой длинной строке, а выравнивание по центру было бы не видно вовсе
*/
.st-site .st-cookie--card .st-cookie__body {
	width: 100%;
}

.st-site .st-cookie--card .st-cookie__btn {
	width: 100%;
	text-align: center;
}

/*
	ВЫРАВНИВАНИЕ ПО ЦЕНТРУ — только для карточки имеет полный смысл, но
	класс общий: в полосе оно центрирует текст внутри своей колонки, и это
	ровно то, что видно в образцах с короткой надписью
*/
.st-site .st-cookie--al-center {
	text-align: center;
}

.st-site .st-cookie--card.st-cookie--al-center {
	align-items: center;
}

/*
	==== ФОРМА УГЛОВ: ДВА НЕЗАВИСИМЫХ НАБОРА ====

	Панель и кнопка настраиваются по отдельности (в образцах встречается
	капсульная кнопка на панели с прямыми углами и наоборот), а список
	значений у них ОДИН — справочник `cookie_shapes` в конфиге приложения.
	`md` — радиус темы, поэтому своего правила у него нет: он и так стоит
	в базовом объявлении
*/
.st-site .st-cookie--r-sq { border-radius: 0; }
.st-site .st-cookie--r-lg { border-radius: calc(var(--st-radius) * 2); }
.st-site .st-cookie--r-pill { border-radius: 999px; }

.st-site .st-cookie__btn--r-sq { border-radius: 0; }
.st-site .st-cookie__btn--r-lg { border-radius: calc(var(--st-radius-sm) * 2); }
.st-site .st-cookie__btn--r-pill { border-radius: 999px; }

/*
	КАПСУЛЬНОЙ ПАНЕЛИ НУЖНЫ БОКОВЫЕ ОТСТУПЫ ПОБОЛЬШЕ: при радиусе 999px
	содержимое у краев заезжает на скругление. Правило идет ПОСЛЕ
	`--sm`/`--lg` намеренно — размер задает вертикаль, форма правит
	горизонталь, и спорить им не о чем
*/
.st-site .st-cookie--r-pill:not(.st-cookie--card) {
	padding-left: 26px;
	padding-right: 26px;
}

.st-cookie__body {
	flex: 1 1 auto;
	min-width: 0;
}

.st-cookie__title {
	font-weight: 700;
	margin-bottom: 2px;
}

.st-cookie__text {
	font-size: 0.9em;
	line-height: 1.45;
	opacity: 0.88;
}

.st-cookie__link {
	color: var(--st-accent);
	text-decoration: underline;
}

.st-cookie__btn {
	flex: 0 0 auto;
	padding: 10px 22px;
	border: 0;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-cookie-btn-bg);
	color: var(--st-cookie-btn-fg);
	font-family: inherit;
	font-size: 0.9em;
	font-weight: 700;
	cursor: pointer;
	transition: filter 0.15s ease;
}

.st-cookie__btn:hover {
	filter: brightness(1.06);
}

/*
	СОГЛАСИЕ УЖЕ ДАНО — ПАНЕЛИ НЕТ. Класс ставит `stsite.js` СРАЗУ при
	старте (до первой отрисовки он не успевает, поэтому переход гасится
	отдельно — иначе панель уезжала бы вниз на каждой странице)
*/
.st-cookie--done {
	display: none;
}

/* НА ТЕЛЕФОНЕ — КОЛОНКОЙ: кнопка рядом с двумя строками текста
   ужимается до нечитаемой ширины */
.st-site[data-st-device="mobile"] .st-cookie,
.st-site[data-st-device="tablet"] .st-cookie {
	flex-wrap: wrap;
}

@media (max-width: 575.98px) {
	/*
		ОСТАЛАСЬ ТОЛЬКО РАСКЛАДКА СОДЕРЖИМОГО (правка 2026-08-15).
		Прежде здесь же правились `left/right/max-width/transform` — остатки
		эпохи четырех пресетов положения. Теперь место и ширину полосы
		задают `--st-cookie-track` и `--st-cookie-rail`, и правила,
		дергающие `right` поверх заданной `width`, только спорили бы с ними
	*/
	.st-site--live .st-cookie {
		flex-wrap: wrap;
	}

	.st-site--live .st-cookie__btn {
		width: 100%;
		text-align: center;
	}
}

@media (prefers-reduced-motion: reduce) {
	.st-cookie__btn {
		transition: none !important;
	}
}

/* ==================================================================
   ==== ВХОД УЧАСТНИКА И ЕГО ПРОФИЛЬ (2026-08-15) ===================
   ==================================================================

   ДВА БЛОКА, ОДНА ПАЛИТРА. Кнопки входа красятся ЛИБО фирменными
   цветами провайдера (`--st-auth-bg` / `--st-auth-fg`, их печатает
   шаблон инлайном), ЛИБО акцентом сайта — и второй набор правил под
   второй режим не нужен: переменные просто не приходят, и работает
   значение отсюда */
.st-site .st-auth {
	--st-auth-bg: var(--st-accent);
	--st-auth-fg: var(--st-accent-text);

	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

.st-site .st-auth--column {
	flex-direction: column;
}

.st-site .st-auth--al-left 	{ justify-content: flex-start; align-items: flex-start; }
.st-site .st-auth--al-center { justify-content: center; align-items: center; }
.st-site .st-auth--al-right { justify-content: flex-end; align-items: flex-end; }

/* ВО ВСЮ ШИРИНУ — ТОЛЬКО У СТОЛБИКА ПО-НАСТОЯЩЕМУ ОСМЫСЛЕННО, но
   правило общее: в строке кнопки честно делят ширину поровну, и это
   ровно то, чего ждет владелец, поставив флажок */
.st-site .st-auth--wide {
	align-items: stretch;
}

.st-site .st-auth--wide .st-auth__btn {
	flex: 1 1 auto;
	justify-content: center;
}

.st-site .st-auth__text {
	margin-bottom: 12px;
	color: var(--st-text-muted);
	font-size: 0.95em;
	line-height: 1.5;
}

.st-site .st-auth__btn {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 11px 18px;
	border: 0;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-auth-bg);
	color: var(--st-auth-fg);
	font-family: inherit;
	font-size: 0.95em;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	cursor: pointer;
	transition: filter 0.15s ease;
}

.st-site .st-auth__btn:hover {
	filter: brightness(1.08);
}

/* ЗНАЧОК НАСЛЕДУЕТ ЦВЕТ ПОДПИСИ (`currentColor` во встроенной марке) —
   поэтому у фирменной и «тематической» кнопки он свой без единого
   лишнего правила */
.st-site .st-auth__logo {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
}

.st-site .st-auth--sm .st-auth__btn { padding: 8px 14px; font-size: 0.85em; }
.st-site .st-auth--lg .st-auth__btn { padding: 14px 24px; font-size: 1.05em; }

/* ТОЛЬКО ЗНАЧОК — КВАДРАТНАЯ КНОПКА: подпись убрали, и прямоугольник
   с пустотой по бокам выглядел бы обрезанным. Класс ставит шаблон —
   правило по наличию дочернего узла (`:has`) здесь ни к чему */
.st-site .st-auth--v-icons .st-auth__btn { padding: 11px; }
.st-site .st-auth--sm.st-auth--v-icons .st-auth__btn { padding: 8px; }
.st-site .st-auth--lg.st-auth--v-icons .st-auth__btn { padding: 14px; }

.st-site .st-auth--r-sq .st-auth__btn { border-radius: 0; }
.st-site .st-auth--r-lg .st-auth__btn { border-radius: calc(var(--st-radius-sm) * 2); }
.st-site .st-auth--r-pill .st-auth__btn { border-radius: 999px; }

/* ==== ПРОФИЛЬ УЧАСТНИКА ====

   КОРЕНЬ БЛОКА — ТОЧКА ОТСЧЕТА ДЛЯ ПАНЕЛИ (`position: relative`):
   выпадающая панель прижимается к аватару, а не к странице */
.st-site .st-member {
	position: relative;
	display: flex;
}

.st-site .st-member--al-left 	{ justify-content: flex-start; }
.st-site .st-member--al-center 	{ justify-content: center; }
.st-site .st-member--al-right 	{ justify-content: flex-end; }

.st-site .st-member__head {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	padding: 6px 12px 6px 6px;
	border: 1px solid var(--st-border);
	border-radius: 999px;
	background: var(--st-surface);
	color: var(--st-text-base);
	font-family: inherit;
	font-size: 0.95em;
	text-decoration: none;
	cursor: pointer;
	transition: border-color 0.15s ease;
}

.st-site .st-member__head:hover {
	border-color: var(--st-accent);
}

.st-site .st-member__ava {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	overflow: hidden;
	background: var(--st-accent);
	color: var(--st-accent-text);
	font-weight: 700;
	line-height: 1;
}

.st-site .st-member__ava img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.st-site .st-member__ava--lg {
	width: 48px;
	height: 48px;
	font-size: 1.2em;
}

.st-site .st-member__name {
	max-width: 160px;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.st-site .st-member--sm .st-member__ava { width: 26px; height: 26px; font-size: 0.85em; }
.st-site .st-member--lg .st-member__ava { width: 40px; height: 40px; font-size: 1.1em; }

/* ==== ПАНЕЛЬ И МОДАЛ — ОДНА РАЗМЕТКА, ДВА ПОЛОЖЕНИЯ ====

   Разводит их `data-st-member` на корне блока: содержимое карточки
   одинаково, и держать две его копии в шаблоне было бы прямой дорогой
   к расхождению */
.st-site .st-member__drop[hidden] {
	display: none;
}

/*
	==== УГОЛ ПОКУПАТЕЛЯ В ШАПКЕ (2026-08-16) ====

	ОДИН РЯД НА ТРИ ВЕЩИ: избранное, корзина, профиль. Раньше профиль был
	отдельным блоком, а корзины в шапке не было вовсе — и владелец
	выравнивал бы три независимых блока между собой руками на каждом
	устройстве. Теперь это один блок и один flex-ряд.

	ПОРЯДОК В РАЗМЕТКЕ (избранное → корзина → профиль) — от менее важного
	к более: у правого края шапки взгляд останавливается последним,
	и там должно стоять то, ради чего покупатель сюда смотрит

	СЧЕТЧИК — НАД ЗНАЧКОМ И БЕЗ НУЛЯ: пустой кружок читается как ошибка
	загрузки, а не как «ничего не отложено»
*/
.st-site .st-hbar {
	display: flex;
	align-items: center;
	gap: 6px;
	flex-wrap: wrap;
}

.st-site .st-hbar--al-left { justify-content: flex-start; }
.st-site .st-hbar--al-center { justify-content: center; }
.st-site .st-hbar--al-right { justify-content: flex-end; }

.st-site .st-hbar__btn {
	position: relative;
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 8px 10px;
	border-radius: var(--st-radius-sm);
	color: inherit;
	font-size: 14px;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.st-site .st-hbar__btn i {
	color: inherit;
	font-size: 19px;
}

.st-site .st-hbar__btn:hover {
	background-color: var(--st-surface-alt);
	color: var(--st-accent);
}

/*
	БЕЙДЖ ПРИЖАТ К ПРАВОМУ ВЕРХНЕМУ УГЛУ САМОЙ КНОПКИ, а не значка:
	у текстового вида значок стоит слева от подписи, и привязка к нему
	увела бы счетчик на середину кнопки
*/
.st-site .st-hbar__badge {
	position: absolute;
	top: 2px;
	right: 2px;
	min-width: 16px;
	height: 16px;
	padding: 0 4px;
	border-radius: 999px;
	background-color: var(--st-accent);
	color: var(--st-accent-text);
	font-size: 10px;
	font-weight: 700;
	line-height: 16px;
	text-align: center;
}

/* Иконочный вид уже: подписи в нем нет, и боковые отступы под нее
   оставляли бы кнопку неоправданно широкой */
.st-site .st-hbar__btn--icon {
	padding: 8px;
}

/* ПЛАШКА ВЫКЛЮЧЕННОГО БЛОКА — ТОЛЬКО В КОНСТРУКТОРЕ (условие в шаблоне).
   Блок нельзя удалить, поэтому выключенным он обязан оставаться видимым */
.st-site .st-hbar__off {
	color: var(--st-muted);
	font-size: 12px;
	font-style: italic;
}

@media (prefers-reduced-motion: reduce) {
	.st-site .st-hbar__btn {
		transition: none !important;
	}
}

.st-site .st-member--panel .st-member__drop {
	position: absolute;
	z-index: 60;
	top: calc(100% + 8px);
	right: 0;
	min-width: 240px;
}

.st-site .st-member--al-left.st-member--panel .st-member__drop {
	right: auto;
	left: 0;
}

/* МОДАЛ ПЕРЕКРЫВАЕТ СТРАНИЦУ ЦЕЛИКОМ. z-index ниже панели согласия
   (1300): до ответа о cookie она остается самым важным элементом
   страницы — то же правило старшинства, что у кнопки ассистента */
.st-site .st-member--modal .st-member__drop {
	position: fixed;
	z-index: 1200;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 20px;
	background: rgba(12, 16, 24, 0.55);
}

.st-site .st-member__card {
	display: flex;
	flex-direction: column;
	gap: 10px;
	width: 100%;
	max-width: 340px;
	padding: 16px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background: var(--st-surface);
	color: var(--st-text-base);
	box-shadow: 0 12px 36px rgba(12, 16, 24, 0.22);
}

.st-site .st-member__row {
	display: flex;
	align-items: center;
	gap: 12px;
}

.st-site .st-member__info {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	min-width: 0;
}

.st-site .st-member__title {
	font-weight: 700;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.st-site .st-member__mail {
	color: var(--st-text-muted);
	font-size: 0.85em;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

/* КРЕСТИК НУЖЕН ТОЛЬКО МОДАЛУ: панель закрывается кликом мимо нее
   и клавишей Esc, а в модале «мимо» — это затемнение на весь экран,
   и попасть по нему пальцем на телефоне почти негде */
.st-site .st-member__close {
	flex: 0 0 auto;
	border: 0;
	background: none;
	color: var(--st-text-muted);
	font-size: 1.5em;
	line-height: 1;
	cursor: pointer;
}

.st-site .st-member--panel .st-member__close {
	display: none;
}

.st-site .st-member__link {
	display: block;
	padding: 9px 12px;
	border-radius: var(--st-radius-sm);
	background: var(--st-surface-2, rgba(127, 127, 127, 0.08));
	color: var(--st-text-base);
	font-size: 0.9em;
	text-decoration: none;
}

.st-site .st-member__link:hover {
	background: var(--st-accent);
	color: var(--st-accent-text);
}

.st-site .st-member__link--out {
	color: var(--st-danger, #E4572E);
}

@media (prefers-reduced-motion: reduce) {
	.st-site .st-auth__btn,
	.st-site .st-member__head {
		transition: none !important;
	}
}

/* ==== ЗАКРЫТО ДО ВХОДА (матрица доступа, 2026-08-15) ==============

   ОДИН ВИД НА ВСЕ ЗАКРЫТЫЕ МЕСТА — витрину, корзину, отзывы, чат.
   Разный вид читался бы как набор разных ошибок, а это одно и то же
   состояние: «сюда пускают участников». Текст меняется, оформление нет */
.st-site .st-locked {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 14px;
	padding: 28px 20px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius);
	background: var(--st-surface);
	color: var(--st-text-base);
	text-align: center;
}

.st-site .st-locked__text {
	font-size: 0.95em;
	line-height: 1.5;
}

.st-site .st-locked__note {
	color: var(--st-text-muted);
	font-size: 0.85em;
}

.st-site .st-locked__btns {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 10px;
}

/* Кнопка та же, что у блока входа, но своим классом: приглашение живет
   внутри чужих блоков, и наследовать оформление блока авторизации
   (столбик, «во всю ширину», выравнивание) ему нельзя */
.st-site .st-locked__btn {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	padding: 10px 16px;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-auth-bg, var(--st-accent));
	color: var(--st-auth-fg, var(--st-accent-text));
	font-size: 0.9em;
	font-weight: 600;
	line-height: 1;
	text-decoration: none;
}

.st-site .st-locked__logo {
	display: inline-flex;
	align-items: center;
}

/* ==== КОРЗИНА (2026-08-15) =======================================

   СТРОКА — ГИБКИЙ РЯД, А НЕ ТАБЛИЦА: на телефоне колонки таблицы
   не переносятся, а строка корзины обязана сложиться в два уровня */
.st-site .st-cart {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.st-site .st-cart__row {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 12px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background: var(--st-surface);
}

.st-site .st-cart__cover {
	display: flex;
	flex: 0 0 auto;
	align-items: center;
	justify-content: center;
	width: 56px;
	height: 56px;
	border-radius: var(--st-radius-sm);
	overflow: hidden;
	background: rgba(127, 127, 127, 0.08);
}

.st-site .st-cart__cover img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.st-site .st-cart__info {
	display: flex;
	flex: 1 1 auto;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.st-site .st-cart__name {
	color: var(--st-text-base);
	font-weight: 600;
	text-decoration: none;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.st-site a.st-cart__name:hover {
	color: var(--st-accent);
}

.st-site .st-cart__price {
	color: var(--st-text-muted);
	font-size: 0.85em;
}

/* ЗА ЧТО ЭТА ЦЕНА («за упаковку 2.182 м²»). Мельче и тусклее самой цены:
   ответ на второй вопрос, а не на первый (2026-08-18) */
.st-site .st-cart__unit {
	color: var(--st-text-muted);
	font-size: 0.75em;
	opacity: 0.85;
}

/* СЧЕТЧИК — ДВЕ КНОПКИ И ЧИСЛО. Ширина числа фиксирована: иначе
   ряд дергался бы при переходе с «9» на «10» */
.st-site .st-cart__qty {
	display: inline-flex;
	flex: 0 0 auto;
	align-items: center;
	gap: 2px;
	border: 1px solid var(--st-border);
	border-radius: 999px;
}

.st-site .st-cart__step {
	width: 28px;
	height: 28px;
	border: 0;
	border-radius: 50%;
	background: none;
	color: var(--st-text-base);
	font-size: 1.1em;
	line-height: 1;
	cursor: pointer;
}

.st-site .st-cart__step:hover {
	background: rgba(127, 127, 127, 0.12);
}

.st-site .st-cart__num {
	min-width: 24px;
	text-align: center;
	font-variant-numeric: tabular-nums;
}

.st-site .st-cart__sum {
	flex: 0 0 auto;
	min-width: 90px;
	text-align: right;
	font-weight: 700;
}

.st-site .st-cart__drop {
	flex: 0 0 auto;
	border: 0;
	background: none;
	color: var(--st-text-muted);
	font-size: 1.3em;
	line-height: 1;
	cursor: pointer;
}

.st-site .st-cart__drop:hover {
	color: var(--st-danger, #E4572E);
}

.st-site .st-cart__foot[hidden] {
	display: none;
}

.st-site .st-cart__foot {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding-top: 6px;
}

.st-site .st-cart__total {
	display: flex;
	align-items: baseline;
	gap: 10px;
	font-size: 1.1em;
}

.st-site .st-cart__total-sum {
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}

.st-site .st-cart__btns {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px;
}

.st-site .st-cart__clear {
	padding: 10px 16px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background: none;
	color: var(--st-text-muted);
	font-family: inherit;
	font-size: 0.9em;
	cursor: pointer;
}

.st-site .st-cart__checkout {
	padding: 12px 24px;
	border: 0;
	border-radius: var(--st-radius-sm);
	background: var(--st-accent);
	color: var(--st-accent-text);
	font-family: inherit;
	font-size: 0.95em;
	font-weight: 700;
	cursor: pointer;
}

.st-site .st-cart__checkout:disabled {
	opacity: 0.6;
	cursor: default;
}

.st-site .st-cart__note {
	padding: 8px 12px;
	border-radius: var(--st-radius-sm);
	background: rgba(127, 127, 127, 0.08);
	font-size: 0.85em;
}

.st-site .st-cart__note[hidden] {
	display: none;
}

/* ОШИБКА КРАСИТСЯ, А НЕ ПОДПИСЫВАЕТСЯ СЛОВОМ «ошибка»: строка одна
   и та же, меняется только ее смысл */
.st-site .st-cart__note--bad {
	background: rgba(228, 87, 46, 0.12);
	color: var(--st-danger, #E4572E);
}

.st-site .st-cart--sm .st-cart__row { padding: 8px; gap: 8px; }
.st-site .st-cart--sm .st-cart__cover { width: 44px; height: 44px; }
.st-site .st-cart--lg .st-cart__row { padding: 16px; gap: 16px; }
.st-site .st-cart--lg .st-cart__cover { width: 72px; height: 72px; }

/* НА ТЕЛЕФОНЕ СТРОКА СКЛАДЫВАЕТСЯ: счетчик и сумма уходят на второй
   уровень, название получает всю ширину */
@media (max-width: 575.98px) {
	.st-site .st-cart__row {
		flex-wrap: wrap;
	}

	.st-site .st-cart__info {
		flex: 1 1 100%;
		order: -1;
	}

	.st-site .st-cart__sum {
		flex: 1 1 auto;
	}
}

/* ==== «В КОРЗИНУ» НА СТРАНИЦЕ ТОВАРА ==== */
.st-site .st-pdp__buy {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 12px;
	margin: 4px 0 8px;
}

.st-site .st-pdp__cart {
	padding: 14px 28px;
	border: 0;
	border-radius: var(--st-radius-sm);
	background: var(--st-accent);
	color: var(--st-accent-text);
	font-family: inherit;
	font-size: 1em;
	font-weight: 700;
	cursor: pointer;
	transition: filter 0.15s ease;
}

.st-site .st-pdp__cart:hover {
	filter: brightness(1.08);
}

.st-site .st-pdp__cart:disabled {
	opacity: 0.6;
	cursor: default;
}

/*
	СЕРДЕЧКО В РЯДУ ПОКУПКИ (2026-08-16) — тот же компонент `.st-fav`,
	что на плитке, только крупнее и с рамкой. Рамка нужна ИМЕННО ЗДЕСЬ:
	на плитке кнопка лежит поверх фотографии и отделяется от нее тенью,
	а в ряду с кнопкой «В корзину» она стоит на фоне страницы, где тень
	почти не читается
*/
.st-site .st-pdp__fav {
	width: 48px;
	height: 48px;
	border: 1px solid var(--st-border);
	box-shadow: none;
	font-size: 20px;
}

.st-site .st-pdp__cart-note {
	color: var(--st-text-muted);
	font-size: 0.9em;
}

.st-site .st-pdp__cart-note[hidden] {
	display: none;
}

/* Ошибка красится тем же классом, что в блоке корзины: строка одна
   на оба места, и второго имени состояния заводить незачем */
.st-site .st-pdp__cart-note.st-cart__note--bad {
	color: var(--st-danger, #E4572E);
}

@media (prefers-reduced-motion: reduce) {
	.st-site .st-pdp__cart {
		transition: none !important;
	}
}

/* ==== ЗАКАЗЫ УЧАСТНИКА В ПАНЕЛИ ПРОФИЛЯ (2026-08-15) =============

   Список раскрывается ВНУТРИ панели, а не отдельной страницей: своей
   страницы у него нет намеренно (см. шаблон блока). Отсюда потолок
   высоты со своей прокруткой — иначе десяток заказов вытянул бы панель
   за край экрана */
.st-site .st-member__orders {
	max-height: 260px;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.st-site .st-member__orders[hidden] {
	display: none;
}

.st-site .st-member__orders-note {
	color: var(--st-text-muted);
	font-size: 0.85em;
}

.st-site .st-member__order {
	padding: 10px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	font-size: 0.85em;
}

.st-site .st-member__order-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin-bottom: 6px;
}

.st-site .st-member__order-num {
	font-weight: 700;
}

/* СТАТУС КРАСИТСЯ ПО СПРАВОЧНИКУ (`color` приходит с сервера), а имена
   цветов те же, что у остальной темы: заводить палитру статусов заново
   значило бы держать два набора «успех / внимание / ошибка» */
.st-site .st-member__order-status {
	padding: 2px 8px;
	border-radius: 999px;
	background: rgba(127, 127, 127, 0.12);
	font-size: 0.9em;
	white-space: nowrap;
}

.st-site .st-member__order-status--success 	{ background: rgba(47, 143, 91, 0.16); color: #2F8F5B; }
.st-site .st-member__order-status--warning 	{ background: rgba(240, 173, 78, 0.18); color: #B87400; }
.st-site .st-member__order-status--danger 	{ background: rgba(228, 87, 46, 0.16); color: #E4572E; }

.st-site .st-member__order-item,
.st-site .st-member__order-track {
	color: var(--st-text-muted);
}

.st-site .st-member__order-total {
	margin-top: 4px;
	font-weight: 700;
}

/* ==== ФОРМА ЗАКАЗА В КОРЗИНЕ ==== */
.st-site .st-cart__form[hidden] {
	display: none;
}

.st-site .st-cart__form {
	display: flex;
	flex-direction: column;
	gap: 10px;
	padding: 16px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background: var(--st-surface);
}

.st-site .st-cart__form-title {
	font-weight: 700;
}

.st-site .st-cart__field {
	display: flex;
	flex-direction: column;
	gap: 4px;
	font-size: 0.85em;
}

/* ЗВЕЗДОЧКА ОБЯЗАТЕЛЬНОГО ПОЛЯ — ЦВЕТОМ, А НЕ СЛОВОМ: подпись «Телефон
   (обязательно)» съедает строку в узкой колонке */
.st-site .st-cart__field i {
	color: var(--st-danger, #E4572E);
	font-style: normal;
}

.st-site .st-cart__field input,
.st-site .st-cart__field textarea {
	padding: 10px 12px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background: var(--st-bg, transparent);
	color: var(--st-text-base);
	font-family: inherit;
	font-size: 1rem;
}

.st-site .st-cart__field input:focus,
.st-site .st-cart__field textarea:focus {
	outline: none;
	border-color: var(--st-accent);
	box-shadow: inset 0 0 0 1px var(--st-accent);
}

.st-site .st-cart__form-btns {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
}

/* ==== ОТЗЫВЫ О ТОВАРАХ (2026-08-15) ==============================

   ЗВЕЗДЫ — ЗНАЧКИ ТЕМЫ, а не символы Unicode: символ звезды выглядит
   по-разному в каждой системе, а рейтинг обязан быть одинаковым у всех
   посетителей (то же правило, что у блока «Отзывы») */
.st-site .st-stars {
	display: inline-flex;
	align-items: center;
	gap: 1px;
	color: #F0AD4E;
	line-height: 1;
}

.st-site .st-stars--lg {
	font-size: 1.3em;
}

/* РЕЙТИНГ НА ПЛИТКЕ — под названием и мельче него: он подсказка,
   а не заголовок карточки */
/*
	==== РЕЙТИНГ И ОТЗЫВЫ — ПО КРАЯМ СТРОКИ (2026-08-17) ====

	Оценка слева, число отзывов справа: две величины отвечают на разные
	вопросы, и слитые в одну запись «4,3 (7)» они читаются как одна
	непонятная. Раскладка ходовая для витрин, и владелец узнает ее
	без объяснений.

	`margin-top: auto` ПРИЖИМАЕТ СТРОКУ К НИЗУ КАРТОЧКИ: у товаров
	название бывает в одну строку и в три, и без этого рейтинг вставал
	бы у каждой плитки на своей высоте — ряд выглядел бы неровным
*/
.st-site .st-product__rating {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	margin-top: auto;
	padding-top: 6px;
	font-size: 0.8em;
}

/* Звезды и число — одна величина, поэтому и одна группа: разрывать их
   выравниванием по краям нельзя */
.st-site .st-product__rating-mark {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-width: 0;
}

.st-site .st-product__rating-num {
	font-weight: 700;
}

.st-site .st-product__reviews,
.st-site .st-product__rating-cnt {
	color: var(--st-text-muted);
	white-space: nowrap;
}

.st-site .st-reviews__summary {
	display: flex;
	align-items: center;
	gap: 10px;
	margin-bottom: 16px;
}

.st-site .st-reviews__avg {
	font-size: 1.4em;
	font-weight: 700;
}

.st-site .st-reviews__count {
	color: var(--st-text-muted);
	font-size: 0.9em;
}

.st-site .st-review {
	padding: 14px 0;
	border-top: 1px solid var(--st-border);
}

.st-site .st-review__head {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
	margin-bottom: 6px;
}

.st-site .st-review__author {
	font-weight: 700;
}

.st-site .st-review__date {
	color: var(--st-text-muted);
	font-size: 0.85em;
}

.st-site .st-review__text {
	line-height: 1.55;
}

.st-site .st-review__photos {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 10px;
}

.st-site .st-review__photo img {
	width: 84px;
	height: 84px;
	border-radius: var(--st-radius-sm);
	object-fit: cover;
}

/* ==== ФОРМА ОТЗЫВА ====

   ОЦЕНКА — РАДИОКНОПКИ ПОД ЗВЕЗДАМИ. Порядок в разметке ОБРАТНЫЙ
   (от пяти к одной), и это не небрежность: правило `~` в CSS достает
   только СЛЕДУЮЩИХ соседей, поэтому «подсветить выбранную и все левее»
   выражается лишь через обратный порядок с `row-reverse` */
.st-site .st-review-form {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin-top: 18px;
	padding: 16px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background: var(--st-surface);
}

.st-site .st-review-form__title {
	font-weight: 700;
}

.st-site .st-review-form__stars {
	display: flex;
	flex-direction: row-reverse;
	justify-content: flex-end;
	gap: 2px;
	font-size: 1.5em;
}

.st-site .st-review-form__stars input {
	position: absolute;
	width: 1px;
	height: 1px;
	opacity: 0;
	pointer-events: none;
}

.st-site .st-review-form__stars label {
	color: var(--st-border);
	cursor: pointer;
	line-height: 1;
}

.st-site .st-review-form__stars input:checked ~ label,
.st-site .st-review-form__stars label:hover,
.st-site .st-review-form__stars label:hover ~ label {
	color: #F0AD4E;
}

/* ФОКУС С КЛАВИАТУРЫ ВИДЕН: сам input спрятан, и без этого правила
   выбрать оценку без мыши было бы нельзя «вслепую» */
.st-site .st-review-form__stars input:focus-visible + label {
	outline: 2px solid var(--st-accent);
	outline-offset: 2px;
}

.st-site .st-review-form textarea {
	padding: 10px 12px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background: var(--st-bg, transparent);
	color: var(--st-text-base);
	font-family: inherit;
	font-size: 1rem;
}

.st-site .st-review-form textarea:focus {
	outline: none;
	border-color: var(--st-accent);
	box-shadow: inset 0 0 0 1px var(--st-accent);
}

.st-site .st-review-form__files {
	display: flex;
	flex-direction: column;
	gap: 4px;
	color: var(--st-text-muted);
	font-size: 0.85em;
}

.st-site .st-review-form__btns {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 12px;
}

.st-site .st-review-form__send {
	padding: 11px 22px;
	border: 0;
	border-radius: var(--st-radius-sm);
	background: var(--st-accent);
	color: var(--st-accent-text);
	font-family: inherit;
	font-weight: 700;
	cursor: pointer;
}

.st-site .st-review-form__send:disabled {
	opacity: 0.6;
	cursor: default;
}

.st-site .st-review-form__note[hidden] {
	display: none;
}

.st-site .st-review-form__note--bad {
	color: var(--st-danger, #E4572E);
}

.st-site .st-review-hint {
	margin-top: 14px;
	color: var(--st-text-muted);
	font-size: 0.9em;
}

/*
	==== ПУНКТ МЕНЮ, КОТОРЫЙ ОТКРЫВАЕТ ОКНО (2026-08-16) ====

	Такой пункт — `<button>`, а не `<a>`: адреса у него нет (пояснение
	в `websiteMenuFromTree`). Оформление у него ОБЩЕЕ со ссылкой — те же
	классы `.st-menu__link` / `.st-nav__btn`, — но браузер дает кнопке
	свою рамку, свой фон и свой курсор. Снимаем ровно их: всё остальное
	приходит из правил самого меню, и второй копии его оформления
	здесь быть не должно.

	`text-align: inherit` — потому что у кнопки он `center` по умолчанию,
	а пункты меню в подуровне выровнены по левому краю
*/
.st-site button.st-menu__link,
.st-site button.st-menu__sublink,
.st-site button.st-nav__btn {
	appearance: none;
	-webkit-appearance: none;
	border: 0;
	background: none;
	text-align: inherit;
	cursor: pointer;
}

/* ==== БЛОК «ТАБЫ» (2026-08-16) ======================================== */
/*
	КОНТЕЙНЕР ОДИН, ВКЛАДОК НЕСКОЛЬКО. Дети лежат в ОДНОЙ сетке, а видима
	ровно одна группа: скрытый элемент грида (`hidden` = `display: none`)
	исчезает из раскладки целиком — ни дорожки, ни ячейки от него
	не остается. Поэтому одна сетка ведет себя в точности как отдельная
	сетка на вкладку, но без второго набора правил и без второго ключа
	контейнера в машине перетаскивания.

	`[hidden]` ЗАДАН ЯВНО И С `!important`: у `.st-block` есть свой
	`display`, и он перебил бы стандартное поведение атрибута — блок
	чужой вкладки остался бы видимым
*/
.st-site .st-tabs [hidden] {
	display: none !important;
}

.st-site .st-tabs {
	--st-tabs-gap: 8px;
	--st-tabs-radius: var(--st-radius-sm);
	--st-tabs-bg: transparent;
	--st-tabs-fg: var(--st-muted);
	--st-tabs-bg-h: var(--st-surface-alt);
	--st-tabs-fg-h: var(--st-text-base);
	--st-tabs-bg-a: var(--st-accent);
	--st-tabs-fg-a: var(--st-accent-text);
}

/*
	ЛЕНТА ПУНКТОВ — КАРУСЕЛЬ БЕЗ ПОЛОСЫ ПРОКРУТКИ, ровно как у витрины
	товаров и по той же причине: системная полоса выдает «прокручиваемый
	div», а на macOS показывается только во время прокрутки — то есть
	у половины посетителей лента выглядела бы просто обрезанной.

	ПЕРЕНОСА НА ВТОРУЮ СТРОКУ НЕТ НАМЕРЕННО (`flex-wrap: nowrap`):
	вкладки — это ОДНА полоса переключателя, и разорванная надвое она
	перестает читаться как один орган управления
*/
.st-site .st-tabs__bar {
	display: flex;
	flex-wrap: nowrap;
	gap: var(--st-tabs-gap);
	overflow-x: auto;
	scrollbar-width: none;
	-ms-overflow-style: none;
	scroll-snap-type: x proximity;
}

.st-site .st-tabs__bar::-webkit-scrollbar {
	display: none;
}

.st-site .st-tabs__bar--left { justify-content: flex-start; }
.st-site .st-tabs__bar--right { justify-content: flex-end; }
.st-site .st-tabs__bar--center { justify-content: center; }

/* ПРИЖАТАЯ ЛЕНТА НЕ ЦЕНТРИРУЕТСЯ, КОГДА НЕ ВЛЕЗАЕТ: у переполненного
   flex-контейнера `justify-content` срезал бы первый пункт за левый край,
   и добраться до него было бы нельзя ни прокруткой, ни пальцем */
.st-site .st-tabs__bar--center > :first-child,
.st-site .st-tabs__bar--right > :first-child {
	margin-left: auto;
}

.st-site .st-tabs__bar--center > :last-child {
	margin-right: auto;
}

.st-site .st-tabs__btn {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	flex: 0 0 auto;
	scroll-snap-align: start;
	padding: 9px 16px;
	border: 1px solid transparent;
	border-radius: var(--st-tabs-radius);
	background-color: var(--st-tabs-bg);
	color: var(--st-tabs-fg);
	font-family: inherit;
	font-size: 14px;
	font-weight: 600;
	line-height: 1.2;
	white-space: nowrap;
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.st-site .st-tabs__btn i {
	color: inherit;
	font-size: 1.1em;
}

.st-site .st-tabs__svg {
	width: 1.1em;
	height: 1.1em;
	object-fit: contain;
}

.st-site .st-tabs__btn:hover {
	background-color: var(--st-tabs-bg-h);
	color: var(--st-tabs-fg-h);
}

.st-site .st-tabs__btn--on,
.st-site .st-tabs__btn--on:hover {
	background-color: var(--st-tabs-bg-a);
	color: var(--st-tabs-fg-a);
}

.st-site .st-tabs--sm .st-tabs__btn { padding: 6px 12px; font-size: 13px; }
.st-site .st-tabs--lg .st-tabs__btn { padding: 12px 22px; font-size: 16px; }

/*
	==== ВИДЫ ====

	ПОДЧЕРКИВАНИЕ — линия под всей лентой плюс своя у выбранной кнопки:
	классические вкладки «приклеены» к содержимому, и без общей линии
	это ощущение теряется. Фон у них не красится вовсе — иначе получились
	бы те же пилюли
*/
.st-site .st-tabs--underline .st-tabs__bar {
	border-bottom: 1px solid var(--st-border);
	gap: calc(var(--st-tabs-gap) + 8px);
}

.st-site .st-tabs--underline .st-tabs__btn {
	padding-left: 2px;
	padding-right: 2px;
	border-radius: 0;
	border-bottom: 2px solid transparent;
	background-color: transparent;
	/* Линия кнопки обязана лечь ПОВЕРХ линии ленты, а не под ней */
	margin-bottom: -1px;
}

.st-site .st-tabs--underline .st-tabs__btn:hover {
	background-color: transparent;
	color: var(--st-tabs-fg-h);
}

.st-site .st-tabs--underline .st-tabs__btn--on,
.st-site .st-tabs--underline .st-tabs__btn--on:hover {
	background-color: transparent;
	color: var(--st-tabs-bg-a);
	border-bottom-color: var(--st-tabs-bg-a);
}

/* СЕГМЕНТЫ — единый блок-переключатель: общая подложка, кнопки без
   промежутков внутри нее */
.st-site .st-tabs--segment .st-tabs__bar {
	gap: 2px;
	padding: 3px;
	border-radius: calc(var(--st-tabs-radius) + 3px);
	background-color: var(--st-surface-alt);
}

.st-site .st-tabs--segment .st-tabs__btn {
	flex: 1 1 auto;
	justify-content: center;
}

/*
	==== ЕДИНЫЙ ВЕРТИКАЛЬНЫЙ РИТМ ПОД ТАБАМИ (2026-08-17) ====

	ШАГ РИТМА СТРАНИЦЫ СКЛАДЫВАЕТСЯ ИЗ ДВУХ ПОЛОВИН: нижнего отступа
	верхнего блока и верхнего отступа нижнего (обе — `--st-pad-y`
	у `.st-block`). Так расстояние между любыми двумя соседями получается
	одинаковым, кто бы они ни были.

	У ТАБОВ ЭТИХ ПОЛОВИН ОКАЗЫВАЛОСЬ ТРИ. Последний блок ВНУТРИ вкладки —
	такой же `.st-block` и дает свою нижнюю половину; вторую добавляет сам
	блок табов; третью — следующий блок страницы. Под табами выходил
	полуторный шаг, и на глаз это читалось как лишняя дыра ровно в одном
	месте страницы.

	СНИМАЕТСЯ ИМЕННО НИЖНЯЯ ПОЛОВИНА БЛОКА ТАБОВ. Верхнюю трогать нельзя —
	над лентой вкладок воздух обязан быть; половину изнутри вкладки тоже —
	это ритм самих блоков, и без нее последний блок прилипал бы к краю.

	ВЕЛИЧИНА БЕРЕТСЯ ИЗ ТОЙ ЖЕ ПЕРЕМЕННОЙ, ЧТО И САМ ОТСТУП: владелец
	вправе задать блоку табов свои отступы (`.st-block--pad-*` меняют
	`--st-pad-y`), и зашитые здесь 16px разъехались бы с ними при первой
	же такой настройке. Спейсер (`common.spacer_after`) при этом
	не страдает: он прибавляется к отступу отдельным слагаемым и остается.

	ПРАВИЛО НА `.st-tabs`, А НЕ НА САМОМ БЛОКЕ: `.st-tabs` печатается
	ТОЛЬКО когда вкладки есть. У блока без вкладок внутри стоит подсказка
	«вкладок пока нет» — прижимать ее к нижнему краю не за что
*/
.st-site .st-tabs {
	margin-bottom: calc(-1 * var(--st-pad-y, 16px));
}

.st-site .st-tabs__body {
	padding-top: 16px;
}

.st-site .st-tabs__body--pad-none { padding: 8px 0 0; }
.st-site .st-tabs__body--pad-sm { padding: 12px 0 0; }
.st-site .st-tabs__body--pad-md { padding: 16px 0 0; }
.st-site .st-tabs__body--pad-lg { padding: 24px 0 0; }
.st-site .st-tabs__body--pad-xl { padding: 32px 0 0; }

@media (prefers-reduced-motion: reduce) {
	.st-site .st-tabs__btn {
		transition: none !important;
	}
}

/* ==== БЛОК «КНОПКА» (2026-08-16) ====================================== */
/*
	ОДИН НАБОР ПРАВИЛ НА `<a>` И НА `<button>`. Тег выбирает ДЕЙСТВИЕ
	(переход — только ссылка, у нее обязаны работать средняя кнопка мыши
	и «открыть в новой вкладке»), а оформление у них общее — иначе
	владелец, сменив действие, увидел бы другую кнопку.

	ЦВЕТА ИДУТ ПЕРЕМЕННЫМИ С ЗАПАСНЫМ ЗНАЧЕНИЕМ ТЕМЫ: не задал владелец —
	кнопка следует за палитрой сайта сама, в том числе при переключении
	светлой и темной.

	`--st-btn-bg-h` по умолчанию РАВЕН основному фону, а «темнее»
	отрабатывает `filter: brightness()`: вычислять оттенок наведения
	из произвольного hex средствами CSS нечем, а требовать второй цвет
	ради типового случая — лишняя работа владельцу
*/
.st-btn {
	--st-btn-bg: var(--st-accent);
	--st-btn-fg: var(--st-accent-text);

	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	max-width: 100%;
	border: 1px solid transparent;
	font-family: inherit;
	font-weight: 600;
	line-height: 1.2;
	text-align: center;
	text-decoration: none;
	cursor: pointer;
	transition: filter 0.15s ease, background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.st-btn i {
	color: inherit;
	font-size: 1.15em;
}

.st-btn__svg {
	width: 1.2em;
	height: 1.2em;
	object-fit: contain;
}

.st-btn__label {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* ==== ВИДЫ ==== */

.st-btn--solid {
	background-color: var(--st-btn-bg);
	color: var(--st-btn-fg);
}

.st-btn--outline {
	background-color: transparent;
	border-color: var(--st-btn-bg);
	color: var(--st-btn-bg);
}

/* У ССЫЛКИ ЦВЕТ ТЕКСТА БЕРЕТСЯ У ФОНА, а не у `--st-btn-fg`: фон здесь
   не рисуется вовсе, и «цвет текста на фоне» превратился бы в белое
   на белом */
.st-btn--link {
	padding-left: 0;
	padding-right: 0;
	background-color: transparent;
	color: var(--st-btn-bg);
}

.st-btn--link .st-btn__label {
	text-decoration: underline;
	text-underline-offset: 3px;
}

/* ==== РАЗМЕРЫ И ФОРМЫ ==== */

.st-btn--sm { padding: 8px 16px; font-size: 13px; }
.st-btn--md { padding: 12px 22px; font-size: 15px; }
.st-btn--lg { padding: 16px 30px; font-size: 17px; }

.st-btn--round { border-radius: var(--st-radius-sm); }
.st-btn--pill { border-radius: 999px; }
.st-btn--square { border-radius: 0; }

/* Кнопка без подписи — квадрат под значок: боковые отступы под текст
   сделали бы ее вытянутой при пустом центре */
.st-btn--icon.st-btn--sm { padding: 8px; }
.st-btn--icon.st-btn--md { padding: 12px; }
.st-btn--icon.st-btn--lg { padding: 16px; }

.st-btn--wide {
	display: flex;
	width: 100%;
}

/* ==== НАВЕДЕНИЕ ==== */
/*
	ПОРЯДОК ВАЖЕН: сначала общий отклик яркостью (работает при любом
	цвете, в том числе не заданном), затем — явные цвета владельца,
	если он их задал. Обратный порядок гасил бы его выбор фильтром
*/
.st-btn:hover {
	filter: brightness(1.08);
}

.st-btn--outline:hover,
.st-btn--link:hover {
	filter: none;
	background-color: color-mix(in srgb, var(--st-btn-bg) 12%, transparent);
}

.st-btn[style*="--st-btn-bg-h"]:hover {
	filter: none;
	background-color: var(--st-btn-bg-h);
	border-color: var(--st-btn-bg-h);
}

.st-btn[style*="--st-btn-fg-h"]:hover {
	color: var(--st-btn-fg-h);
}

/* Контурная и ссылка красят наведением ТЕКСТ, а не фон: заливка сделала
   бы их сплошными, то есть третьим видом */
.st-btn--outline[style*="--st-btn-bg-h"]:hover,
.st-btn--link[style*="--st-btn-bg-h"]:hover {
	background-color: transparent;
	color: var(--st-btn-bg-h);
	border-color: var(--st-btn-bg-h);
}

.st-btnbox {
	display: flex;
}

.st-btnbox--left { justify-content: flex-start; }
.st-btnbox--center { justify-content: center; }
.st-btnbox--right { justify-content: flex-end; }

/* ==== АНИМАЦИИ ПОКОЯ ==== */
/*
	ТОЛЬКО ТО, ЧТО НЕ МЕШАЕТ ЧИТАТЬ СОСЕДНИЙ ТЕКСТ. Кнопка стоит в потоке
	страницы, а не в углу экрана, как виджет ассистента: вращение
	и дрожание рядом с абзацем делают его нечитаемым
*/
.st-btn--anim-pulse {
	animation: stBtnPulse 2.4s ease-in-out infinite;
}

@keyframes stBtnPulse {
	0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--st-btn-bg) 55%, transparent); }
	60% { box-shadow: 0 0 0 12px color-mix(in srgb, var(--st-btn-bg) 0%, transparent); }
}

.st-btn--anim-float {
	animation: stBtnFloat 3s ease-in-out infinite;
}

@keyframes stBtnFloat {
	0%, 100% { transform: translateY(0); }
	50% { transform: translateY(-3px); }
}

/* БЛИК — ПСЕВДОЭЛЕМЕНТОМ ПОВЕРХ, поэтому кнопке нужен свой контекст
   наложения и обрезка: без `overflow` полоса выезжала бы за ее пределы */
.st-btn--anim-shine {
	position: relative;
	overflow: hidden;
}

.st-btn--anim-shine::after {
	content: '';
	position: absolute;
	top: 0;
	bottom: 0;
	width: 40%;
	background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.35), transparent);
	animation: stBtnShine 3.2s ease-in-out infinite;
	pointer-events: none;
}

@keyframes stBtnShine {
	0% { left: -50%; }
	55%, 100% { left: 120%; }
}

@media (prefers-reduced-motion: reduce) {
	.st-btn,
	.st-btn--anim-pulse,
	.st-btn--anim-float,
	.st-btn--anim-shine::after {
		animation: none !important;
		transition: none !important;
	}

	.st-btn--anim-float {
		transform: none !important;
	}
}

/* ======================================================================= */
/* ==== ОВЕРЛЕИ: МОДАЛЬНЫЕ ОКНА И БОКОВЫЕ ПАНЕЛИ (2026-08-16) ============ */
/* ======================================================================= */
/*
	ОДИН НАБОР ПРАВИЛ НА ДВА ТИПА. Модал и панель — это одна коробка
	с разной геометрией: общая подложка, общая шапка, общее тело, общий
	футер. Развести их по двум компонентам значило бы дважды описать
	одно и то же и один раз ошибиться.

	ГДЕ ЖИВУТ ЭТИ ПРАВИЛА. В `stheme.css`, а не в `stsite.css`, потому что
	оверлей рисуется В ОБОИХ КОНТУРАХ: на сайте — по нажатию триггера,
	в конструкторе — в режиме правки тела. Файл `stsite.css` конструктор
	не грузит вовсе.

	ЗАЧЕМ ПЕРЕМЕННЫЕ `--st-ov-*`, А НЕ КЛАССЫ. Радиус, отступ и пара
	цветов — величины произвольные, и класс на каждое значение пришлось бы
	заводить конечным набором. Классами остается только то, у чего значений
	ровно столько, сколько в справочнике: тип, сторона, размер, анимация.

	СТАРШИНСТВО СЛОЕВ (числа согласованы, менять только все сразу):
	  1200 — виджет ассистента;
	  1300 — полоса согласия на cookie;
	  1400 — ОВЕРЛЕЙ: он открыт прямым действием человека и обязан быть
	         выше и виджета, и полосы согласия;
	  2000 — полоса загрузки перехода (тонкая линия у верхнего края,
	         она ничего не перекрывает и видна всегда).
*/
.st-site .st-ov {
	--st-ov-radius: var(--st-radius);
	--st-ov-bg: var(--st-surface);
	--st-ov-fg: var(--st-text-base);
	--st-ov-pad: 24px;
	--st-ov-width: 720px;

	position: fixed;
	inset: 0;
	z-index: 1400;
	display: flex;
	font-family: var(--st-font);
	color: var(--st-ov-fg);
}

/* ЗАМОК ПРОКРУТКИ — НА ДОКУМЕНТЕ, А НЕ НА КОРНЕ САЙТА: прокручивается
   именно документ, и `overflow: hidden` на внутреннем узле его не остановит */
.st-ov-lock {
	overflow: hidden;
}

.st-site .st-ov__dim {
	position: absolute;
	inset: 0;
	background: rgba(12, 16, 24, 0.55);
	opacity: 0;
	transition: opacity 0.25s ease;
}

.st-site .st-ov--nodim .st-ov__dim {
	background: transparent;
}

.st-site .st-ov--blur .st-ov__dim {
	backdrop-filter: blur(4px);
}

.st-site .st-ov--on .st-ov__dim {
	opacity: 1;
}

/*
	КОРОБКА ОКНА. `max-height` и собственная прокрутка ТЕЛА обязательны:
	содержимое собирает владелец, и оно бывает длиннее экрана — без этого
	шапка с кнопкой закрытия уезжала бы за верхний край, и окно
	превращалось бы в ловушку
*/
.st-site .st-ov__box {
	position: relative;
	display: flex;
	flex-direction: column;
	max-height: 100%;
	background-color: var(--st-ov-bg);
	color: var(--st-ov-fg);
	box-shadow: 0 24px 70px rgba(12, 16, 24, 0.28);
	transition: opacity 0.25s ease, transform 0.25s ease;
}

/* ==== МОДАЛ: ПО ЦЕНТРУ ==== */

.st-site .st-ov--modal {
	align-items: center;
	justify-content: center;
	padding: 20px;
}

.st-site .st-ov--modal .st-ov__box {
	width: 100%;
	max-width: var(--st-ov-width);
	border-radius: var(--st-ov-radius);
	overflow: hidden;
}

.st-site .st-ov--size-sm { --st-ov-width: 480px; }
.st-site .st-ov--size-md { --st-ov-width: 720px; }
.st-site .st-ov--size-lg { --st-ov-width: 960px; }

/* «Во весь экран» — это ОТСУТСТВИЕ коробки, а не очень большая коробка:
   у такого окна не бывает ни скругления, ни полей вокруг */
.st-site .st-ov--modal.st-ov--size-full {
	padding: 0;
}

.st-site .st-ov--modal.st-ov--size-full .st-ov__box {
	max-width: none;
	height: 100%;
	max-height: none;
	border-radius: 0;
}

/* ==== ПАНЕЛЬ: ОТ КРАЯ ==== */

.st-site .st-ov--panel .st-ov__box {
	position: absolute;
	max-height: none;
}

.st-site .st-ov--side-right .st-ov__box,
.st-site .st-ov--side-left .st-ov__box {
	top: 0;
	bottom: 0;
	width: min(100%, var(--st-ov-width));
}

.st-site .st-ov--side-right .st-ov__box { right: 0; }
.st-site .st-ov--side-left .st-ov__box { left: 0; }

.st-site .st-ov--side-top .st-ov__box,
.st-site .st-ov--side-bottom .st-ov__box {
	left: 0;
	right: 0;
	width: auto;
	/* ВЫСОТА ГОРИЗОНТАЛЬНОЙ ПАНЕЛИ — ПО СОДЕРЖИМОМУ, но не выше 85%
	   экрана: «шторка» во весь экран перестает читаться как шторка
	   и становится плохим модалом */
	max-height: 85%;
}

.st-site .st-ov--side-top .st-ov__box { top: 0; }
.st-site .st-ov--side-bottom .st-ov__box { bottom: 0; }

/* ==== ШАПКА, ТЕЛО, ФУТЕР ==== */

.st-site .st-ov__head {
	display: flex;
	align-items: center;
	gap: 10px;
	flex: 0 0 auto;
	padding: 16px var(--st-ov-pad);
	border-bottom: 1px solid var(--st-border);
}

.st-site .st-ov__icon {
	color: var(--st-accent);
	font-size: 20px;
}

.st-site .st-ov__title {
	flex: 1 1 auto;
	min-width: 0;
	font-size: 17px;
	font-weight: 700;
	line-height: 1.25;
}

.st-site .st-ov__close {
	flex: 0 0 auto;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background-color: transparent;
	color: var(--st-muted);
	font-size: 26px;
	line-height: 1;
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.st-site .st-ov__close:hover {
	background-color: var(--st-surface-alt);
	color: var(--st-danger);
}

/*
	ТЕЛО ПРОКРУЧИВАЕТСЯ САМО, а не вместе с окном: шапка с кнопкой
	закрытия обязана оставаться на месте при любой длине содержимого.
	`min-height: 0` — без него flex-элемент отказывается сжиматься ниже
	своего содержимого и прокрутки не появляется вовсе
*/
.st-site .st-ov__body {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	padding: var(--st-ov-pad);
}

.st-site .st-ov__foot {
	flex: 0 0 auto;
	padding: 14px var(--st-ov-pad);
	border-top: 1px solid var(--st-border);
	color: var(--st-muted);
	font-size: 13px;
	line-height: 1.45;
}

/* Подсказка пустого тела — ТОЛЬКО В КОНСТРУКТОРЕ (условие в шаблоне) */
.st-site .st-ov__empty {
	padding: 28px 16px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius-sm);
	color: var(--st-muted);
	font-size: 13px;
	text-align: center;
}

/* ==== АНИМАЦИИ ПОЯВЛЕНИЯ ==== */
/*
	СТАРТОВОЕ СОСТОЯНИЕ ЗАДАЕТ ВИД, КОНЕЧНОЕ — ОДНО НА ВСЕХ (`--on`).
	Так закрытие получается тем же переходом наоборот и не требует
	ни второго набора правил, ни второго класса.

	У ПАНЕЛИ «ВЫЕЗД» ИДЕТ ОТ ЕЁ СТОРОНЫ, у модала — снизу вверх. Это
	не разные анимации, а одна: «выезд» означает «оттуда, где окно живет»,
	и для панели справа это справа
*/
.st-site .st-ov--anim-fade .st-ov__box { opacity: 0; }
.st-site .st-ov--anim-scale .st-ov__box { opacity: 0; transform: scale(0.94); }
.st-site .st-ov--anim-slide.st-ov--modal .st-ov__box { opacity: 0; transform: translateY(24px); }

.st-site .st-ov--anim-slide.st-ov--side-right .st-ov__box { transform: translateX(100%); }
.st-site .st-ov--anim-slide.st-ov--side-left .st-ov__box { transform: translateX(-100%); }
.st-site .st-ov--anim-slide.st-ov--side-top .st-ov__box { transform: translateY(-100%); }
.st-site .st-ov--anim-slide.st-ov--side-bottom .st-ov__box { transform: translateY(100%); }

/* ПАНЕЛЬ ВЫЕЗЖАЕТ ДАЖЕ БЕЗ ЯВНОГО ВЫБОРА. Проявляющаяся на месте панель
   читается как дефект отрисовки: у выдвижного элемента движение и есть
   объяснение того, откуда он взялся */
.st-site .st-ov--anim-fade.st-ov--side-right .st-ov__box,
.st-site .st-ov--anim-scale.st-ov--side-right .st-ov__box { transform: translateX(100%); }
.st-site .st-ov--anim-fade.st-ov--side-left .st-ov__box,
.st-site .st-ov--anim-scale.st-ov--side-left .st-ov__box { transform: translateX(-100%); }
.st-site .st-ov--anim-fade.st-ov--side-top .st-ov__box,
.st-site .st-ov--anim-scale.st-ov--side-top .st-ov__box { transform: translateY(-100%); }
.st-site .st-ov--anim-fade.st-ov--side-bottom .st-ov__box,
.st-site .st-ov--anim-scale.st-ov--side-bottom .st-ov__box { transform: translateY(100%); }

.st-site .st-ov--anim-none .st-ov__box,
.st-site .st-ov--anim-none .st-ov__dim {
	transition: none;
}

.st-site .st-ov--anim-none .st-ov__box { opacity: 1; transform: none; }
.st-site .st-ov--anim-none .st-ov__dim { opacity: 1; }

.st-site .st-ov--on .st-ov__box {
	opacity: 1;
	transform: none;
}

/*
	СИСТЕМНАЯ ПРОСЬБА СТАРШЕ ВЫБОРА ВЛАДЕЛЬЦА. Гасим не только переход,
	но и СТАРТОВОЕ состояние: без второй половины правила окно у такого
	посетителя осталось бы прозрачным или уехавшим за край — то есть
	невидимым
*/
@media (prefers-reduced-motion: reduce) {
	.st-site .st-ov__box,
	.st-site .st-ov__dim,
	.st-site .st-ov__close {
		transition: none !important;
	}

	.st-site .st-ov__box {
		opacity: 1 !important;
		transform: none !important;
	}

	.st-site .st-ov__dim {
		opacity: 1 !important;
	}
}

/*
	НА ТЕЛЕФОНЕ вертикальная панель занимает почти всю ширину, а модал
	теряет поля: 20 px от каждого края на экране 360 px — это десятая
	часть окна, отданная пустоте
*/
@media (max-width: 575.98px) {
	.st-site .st-ov--modal {
		padding: 12px;
	}

	.st-site .st-ov--side-right .st-ov__box,
	.st-site .st-ov--side-left .st-ov__box {
		width: min(100%, 92vw);
	}

	.st-site .st-ov {
		--st-ov-pad: 16px;
	}
}

/* ==== ЧРОМ ПРОКРУТКИ: ИНДИКАТОР ЧТЕНИЯ И КНОПКА «НАВЕРХ» ============== */
/*
	(2026-08-18)

	ОБА ЭЛЕМЕНТА — ЗАМЕНА ОРИЕНТИРА, А НЕ УКРАШЕНИЕ. Владелец вправе
	спрятать полосу прокрутки совсем (`options.scroll.style = hidden`),
	и тогда «сколько осталось» и «как быстро вернуться наверх» посетителю
	не отвечает больше ничто.

	РАЗМЕТКА ЛЕЖИТ ВНУТРИ КОРНЯ САЙТА, ХОТЯ ВИЗУАЛЬНО ОБА НАД НИМ, — тот же
	прием, что у виджета ассистента: закрепление за окном дает `fixed`,
	а переменные палитры наследуются по ДЕРЕВУ, и вне корня их бы не было.

	ЦВЕТА ПРИЕЗЖАЮТ ИНЛАЙНОМ И СРАЗУ ПАРОЙ (светлый и темный): переключение
	палитры на сайте меняет ОДИН атрибут и не ходит на сервер, поэтому
	темное значение обязано уже лежать в разметке (steditorScrollHtml).

	В КОНСТРУКТОРЕ ИХ НЕТ ВОВСЕ — там окно принадлежит кабинету
*/
.st-site .st-progress {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	height: var(--st-progress-size, 3px);
	z-index: 1210;
	pointer-events: none;
	background-color: transparent;
}

/*
	ПОЛОСА РАСТЕТ `transform`-ом, А НЕ ШИРИНОЙ: ширина пересчитывает
	раскладку на каждый такт прокрутки, трансформация — нет. Скрипт
	пишет только множитель (`--st-progress`, 0…1)
*/
.st-site .st-progress__bar {
	display: block;
	width: 100%;
	height: 100%;
	transform-origin: left center;
	transform: scaleX(var(--st-progress, 0));
	background-color: var(--st-progress-color, #2F8F5B);
}

.st-site[data-st-mode="dark"] .st-progress__bar {
	background-color: var(--st-progress-color-dark, var(--st-progress-color, #2F8F5B));
}

/*
	КНОПКА «НАВЕРХ» ПОЯВЛЯЕТСЯ ПОСЛЕ ПЕРВОГО ЭКРАНА (класс ставит stsite.js).
	До этого она не просто прозрачная, а `visibility: hidden` — иначе
	невидимая кнопка перехватывала бы нажатия в углу экрана.

	`--st-cookie-h` — ТА ЖЕ ПОПРАВКА, ЧТО У КНОПКИ ВИДЖЕТА: пока внизу висит
	полоса согласия, обе кнопки обязаны подняться над ней, иначе они
	перекрывают текст согласия
*/
.st-site .st-top {
	position: fixed;
	bottom: calc(24px + var(--st-cookie-h, 0px));
	z-index: 1150;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 46px;
	height: 46px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background-color: var(--st-top-color, #2F8F5B);
	color: var(--st-top-text, #FFFFFF);
	box-shadow: var(--st-shadow, 0 6px 24px rgba(24, 32, 48, 0.18));
	cursor: pointer;
	opacity: 0;
	visibility: hidden;
	transform: translateY(12px);
	transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ease;
}

.st-site[data-st-mode="dark"] .st-top {
	background-color: var(--st-top-color-dark, var(--st-top-color, #2F8F5B));
	color: var(--st-top-text-dark, var(--st-top-text, #FFFFFF));
}

.st-site .st-top--right {
	right: 24px;
}

.st-site .st-top--left {
	left: 24px;
}

.st-site .st-top--on {
	opacity: 1;
	visibility: visible;
	transform: none;
}

/* Значок красится ВМЕСТЕ с кнопкой: правило `.ki-*{color:...}` из конца
   keenicons иначе оставило бы стрелку серой на цветном круге */
.st-site .st-top i {
	color: inherit;
	font-size: 1.25rem;
	line-height: 1;
}

/* КНОПКА ВИДЖЕТА АССИСТЕНТА СИДИТ В ТОМ ЖЕ УГЛУ. Сторону выбирает
   владелец, но если он выбрал ту же — поднимаем «наверх» над виджетом,
   а не оставляем две круглые кнопки друг на друге (класс ставит stsite.js) */
.st-site .st-top--stacked {
	bottom: calc(24px + var(--st-cookie-h, 0px) + 72px);
}

@media (max-width: 575.98px) {
	.st-site .st-top {
		width: 40px;
		height: 40px;
		bottom: calc(16px + var(--st-cookie-h, 0px));
	}

	.st-site .st-top--right {
		right: 16px;
	}

	.st-site .st-top--left {
		left: 16px;
	}

	.st-site .st-top--stacked {
		bottom: calc(16px + var(--st-cookie-h, 0px) + 64px);
	}
}

@media (prefers-reduced-motion: reduce) {
	.st-site .st-top {
		transition: none;
	}
}

/* ==== КАЛЬКУЛЯТОР МАТЕРИАЛА (2026-08-18) ============================== */
/*
	ДВЕ КОЛОНКИ НА ШИРОКОМ ЭКРАНЕ: слева ввод, справа результат. Результат
	стоит РЯДОМ, а не под формой, и это не вкусовщина — покупатель меняет
	площадь и способ укладки, глядя на цифры, и прокрутка между причиной
	и следствием ломала бы весь смысл блока.

	Поля переиспользуют `.st-field` формы заявки: два разных вида поля ввода
	на одном сайте читались бы как недоделка.

	КОЛОНКИ РАВНОЙ ВЫСОТЫ (`stretch`, а не `start`), и это не косметика:
	коробка результата ЗАЛИТА ФОНОМ, поэтому ее нижний край видно — и пока
	высота была по содержимому, край обрывался где-то посреди формы,
	а сама коробка читалась как приподнятая над левой колонкой. Лишнюю
	высоту забирает ОДИН промежуток — перед кнопкой корзины (см. ниже),
	а не разрывы между строками результата
*/
.st-site .st-calc {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
	gap: 20px;
	align-items: stretch;
	padding: 20px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius, 16px);
	background-color: var(--st-surface);
}

.st-site .st-calc__form {
	display: flex;
	flex-direction: column;
	gap: 12px;
	min-width: 0;
}

.st-site .st-calc__field {
	width: 100%;
}

/*
	==== ЧИСЛОВОЕ ПОЛЕ СО СЧЕТЧИКОМ (`.st-num`, 2026-08-21) ====

	ВИД ПОВТОРЯЕТ СЧЕТЧИК СЕРВИСА (`.ste-dialer`): две стрелки друг над
	другом у правого края, обе появляются по наведению на поле. Скрывать
	их в покое — не украшательство: поле площади читается как обычное
	числовое, и постоянная пара стрелок в узкой колонке формы отнимает
	у значения место, которого там и так немного.

	СТРЕЛКИ НАРИСОВАНЫ РАМКАМИ, а не шрифтом значков: на публичной
	странице шрифт грузится отдельным файлом, и до его загрузки счетчик
	показывал бы два пустых квадрата.

	ПОЛЕ ПОЛУЧАЕТ ПРАВОЕ ПОЛЕ ПОД СТРЕЛКИ ВСЕГДА, а не только при
	наведении: иначе длинное значение прыгало бы под курсором
*/
.st-site .st-num {
	position: relative;
	display: block;
}

.st-site .st-num__input {
	padding-right: 38px;
}

.st-site .st-num__ctrl {
	position: absolute;
	top: 50%;
	right: 6px;
	display: flex;
	flex-direction: column;
	gap: 2px;
	transform: translateY(-50%);
	opacity: 0;
	transition: opacity 0.15s ease;
}

.st-site .st-num:hover .st-num__ctrl,
.st-site .st-num:focus-within .st-num__ctrl {
	opacity: 1;
}

.st-site .st-num__btn {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 24px;
	height: 16px;
	padding: 0;
	border: 0;
	border-radius: 5px;
	background-color: transparent;
	color: var(--st-muted);
	cursor: pointer;
}

.st-site .st-num__btn:hover {
	background-color: var(--st-surface-alt);
	color: var(--st-accent);
}

/* Сама стрелка: квадрат 6×6 из двух рамок, повернутый на 45° */
.st-site .st-num__btn::before {
	content: '';
	width: 6px;
	height: 6px;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
}

.st-site .st-num__btn--up::before {
	transform: rotate(-135deg);
	margin-top: 3px;
}

.st-site .st-num__btn--down::before {
	transform: rotate(45deg);
	margin-bottom: 3px;
}

/* Стороны комнаты — одной строкой со знаком умножения между ними:
   так видно, что это ОДНА величина, введенная двумя числами */
.st-site .st-calc__sides {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
	align-items: end;
	gap: 8px;
}

.st-site .st-calc__x {
	padding-bottom: 10px;
	color: var(--st-muted);
}

.st-site .st-calc__out {
	display: flex;
	flex-direction: column;
	gap: 8px;
	min-width: 0;
	padding: 16px;
	border-radius: var(--st-radius-sm, 10px);
	background-color: var(--st-surface-alt);
}

.st-site .st-calc__row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 10px;
}

.st-site .st-calc__label {
	color: var(--st-muted);
	font-size: 14px;
}

.st-site .st-calc__value {
	color: var(--st-text);
	font-weight: 600;
	text-align: right;
}

/* Главная строка (упаковки) и итог крупнее остальных: это ДВА ответа,
   ради которых калькулятор открывают, — «сколько брать» и «сколько стоит» */
.st-site .st-calc__row--main .st-calc__value {
	font-size: 20px;
}

.st-site .st-calc__row--total {
	margin-top: 4px;
	margin-bottom: 8px;
	padding-top: 8px;
	border-top: 1px solid var(--st-border);
}

.st-site .st-calc__row--total .st-calc__value {
	font-size: 22px;
	color: var(--st-accent);
}

/* КНОПКА ПРИЖАТА К НИЗУ КОРОБКИ (`auto` вместо фиксированного отступа):
   колонки равной высоты, и вся лишняя высота уходит СЮДА — призыв
   к действию стоит на нижней линии формы, а не висит посередине */
.st-site .st-calc__cart {
	margin-top: auto;
	padding: 11px 18px;
	border: 0;
	border-radius: var(--st-radius-sm, 10px);
	background-color: var(--st-accent);
	color: var(--st-accent-text);
	font-size: 15px;
	font-weight: 600;
	cursor: pointer;
}

/* Выключенная кнопка обязана ВЫГЛЯДЕТЬ выключенной: до ввода площади
   класть в корзину нечего, и живой вид обещал бы работу, которой нет */
.st-site .st-calc__cart:disabled {
	opacity: 0.45;
	cursor: default;
}

.st-site .st-calc__msg:empty {
	display: none;
}

.st-site .st-calc__msg {
	font-size: 13px;
	color: var(--st-muted);
}

.st-site .st-calc__note {
	margin-top: 10px;
	font-size: 13px;
	color: var(--st-muted);
}

/* НА УЗКОМ ЭКРАНЕ — ОДНА КОЛОНКА. Правило дублируется по атрибуту
   устройства: в конструкторе медиазапросы считаются от окна браузера,
   а не от ширины «листа» (та же ловушка, что у всех сеток сайта) */
.st-site[data-st-device="mobile"] .st-calc,
.st-site[data-st-device="tablet"] .st-calc {
	grid-template-columns: minmax(0, 1fr);
}

@media (max-width: 767.98px) {
	.st-site .st-calc {
		grid-template-columns: minmax(0, 1fr);
	}
}


/* ==== БЕЙДЖИ ОБЛОЖКИ: СКИДКА И НАЛИЧИЕ (2026-08-18) =================== */
/*
	ВНИЗУ ОБЛОЖКИ, А НЕ В УГЛУ СВЕРХУ, И ЭТО ВЫНУЖДЕННО: оба верхних угла
	заняты — столбиком значков свойств и сердечком избранного. Третий
	житель наверху накрыл бы одного из них.

	НИЖЕ РАСТЯНУТОЙ ССЫЛКИ ПО СЛОЯМ (`z-index` не задан): бейдж не должен
	перехватывать нажатие — вся карточка ведет на товар, и «промах мимо
	ссылки» на самом заметном элементе обложки читался бы как поломка.

	ЦВЕТА ЗАШИТЫ: «скидка» и «нет в наличии» обязаны читаться одинаково
	на всех витринах независимо от акцента темы
*/
.st-site .st-product__flags {
	position: absolute;
	left: 8px;
	right: 8px;
	bottom: 8px;
	display: flex;
	flex-wrap: wrap;
	gap: 4px;
	pointer-events: none;
}

.st-site .st-product__flag {
	padding: 3px 8px;
	border-radius: 999px;
	background-color: var(--st-surface);
	color: var(--st-text-base);
	font-size: 11px;
	font-weight: 700;
	line-height: 1.4;
	box-shadow: 0 2px 8px rgba(16, 24, 40, 0.12);
}

.st-site .st-product__flag--sale {
	background-color: #F1416C;
	color: #FFFFFF;
}

/* «Под заказ» — предупреждение, а не отказ: товар купить можно,
   просто не сегодня */
.st-site .st-product__flag--wait {
	background-color: #FFF4D6;
	color: #7A5C00;
}

.st-site .st-product__flag--off {
	background-color: #2B2F38;
	color: #FFFFFF;
}

/*
	==== ПРИЗНАК ТОВАРА: «ХИТ» И «НОВИНКА» (2026-08-21) ====

	ЕДИНСТВЕННЫЕ БЕЙДЖИ ОБЛОЖКИ, БЕРУЩИЕ ЦВЕТ У ТЕМЫ, и это не отступление
	от правила выше, а его вторая половина. Зашиты те бейджи, что обязаны
	читаться ОДИНАКОВО ВЕЗДЕ: скидка — про деньги, «нет в наличии» —
	про отказ, и подмена их цвета акцентом витрины сделала бы отказ
	похожим на украшение. «Хит» и «новинка» — наоборот, ВЫДЕЛЕНИЕ, и его
	смысл в том, чтобы совпадать с акцентом магазина.

	ТЕКСТ БЕРЕТСЯ ИЗ ПАРНОЙ ПЕРЕМЕННОЙ ТЕМЫ (`--st-accent-text`), а не
	задается белым: акцент витрины бывает светлым, и белая надпись на нем
	исчезла бы. Эту пару уже используют кнопки сайта — второго ответа
	на вопрос «чем писать по акценту» в проекте быть не должно.

	«НОВИНКА» — ЗЕЛЕНЫМ ТОГО ЖЕ ТОНА, ЧТО БЕЙДЖ `st-badge--good`, но
	СПЛОШНЫМ, а не полупрозрачным: бейджи над названием лежат на фоне
	страницы, а этот — НА ФОТОГРАФИИ, и прозрачная подложка показала бы
	сквозь себя кадр
*/
.st-site .st-product__flag--accent {
	background-color: var(--st-accent);
	color: var(--st-accent-text);
}

.st-site .st-product__flag--good {
	background-color: #3FA76C;
	color: #FFFFFF;
}


/* ==== ДОСТАВКА И ОПЛАТА (2026-08-18) ================================== */
/*
	ДВА СПИСКА РЯДОМ. Число колонок задает владелец (`--st-cols`), но если
	заполнен только один список, разметка сама отдает ему всю ширину —
	колонка-призрак читалась бы как недогруженная страница.

	СТРОКА — ЗНАЧОК СЛЕВА, СОДЕРЖИМОЕ СПРАВА. Стоимость (`note`) стоит
	в одной строке с названием и прижата к правому краю: покупатель ищет
	глазами цифру, и она обязана попадаться раньше пояснения
*/
/*
	==== ПЕРЕРАБОТКА ВИДА (2026-08-21) ====

	ЧТО БЫЛО НЕ ТАК: блок выглядел черновиком. Строки лежали на голом фоне
	страницы без единой границы, значок стоял в бледном квадрате, а группы
	«Доставка» и «Оплата» отличались от соседних блоков только заголовком —
	то есть визуально это был не блок, а два списка, оставленных на листе.
	Отдельно ломало ритм то, что стоимость («500») висела в воздухе справа,
	далеко от своей строки: на широкой колонке между названием и ценой
	получалась пустая полоса в пол-экрана.

	ЧТО СТАЛО:
	  · КАЖДАЯ СТРОКА — КАРТОЧКА (поверхность, рамка, скругление). Тот же
	    язык, что у карточек преимуществ и этапов: список способов доставки
	    читается как набор вариантов, а не как абзац;
	  · СТОИМОСТЬ СТАЛА ПЛАШКОЙ и прижата к названию, а не к краю колонки:
	    цифра относится к СПОСОБУ, и разрыв в пол-экрана эту связь рвал;
	  · ЗНАЧОК получил акцентную подложку и стал крупнее — он теперь
	    несущий элемент строки, а не серый квадрат рядом с текстом;
	  · ЗАГОЛОВОК ГРУППЫ получил подчеркивание-разделитель: две колонки
	    иначе сливались в одну ленту на широком экране
*/
.st-site .st-delivery {
	display: grid;
	grid-template-columns: repeat(var(--st-cols, 2), minmax(0, 1fr));
	gap: 28px;
}

.st-site .st-delivery__group {
	display: flex;
	flex-direction: column;
	gap: 10px;
	min-width: 0;
}

.st-site .st-delivery__head {
	padding-bottom: 10px;
	border-bottom: 1px solid var(--st-border);
	margin-bottom: 4px;
	font-size: 17px;
	font-weight: 700;
	color: var(--st-text);
}

.st-site .st-delivery__row {
	display: flex;
	align-items: flex-start;
	gap: 14px;
	padding: 14px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius, 16px);
	background-color: var(--st-surface);
	transition: border-color 0.15s ease;
}

.st-site .st-delivery__row:hover {
	border-color: color-mix(in srgb, var(--st-accent) 45%, var(--st-border));
}

/* Плотность меняет только воздух внутри строк: содержимое у них одно
   и то же, а «компактно» отличается именно этим */
.st-site .st-delivery--compact .st-delivery__row { padding: 10px 12px; }
.st-site .st-delivery--comfort .st-delivery__row { padding: 14px; }

.st-site .st-delivery__icon {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 42px;
	height: 42px;
	border-radius: var(--st-radius-sm, 10px);
	/* Подложка акцентом с прозрачностью, а не отдельным цветом: тема
	   сайта задает ОДИН акцент, и плашка обязана следовать за ним */
	background-color: color-mix(in srgb, var(--st-accent) 12%, transparent);
	color: var(--st-accent);
	font-size: 20px;
}

/* Место значка сохраняется даже когда его нет: иначе строки без значка
   съезжали бы влево и список переставал читаться столбцом */
.st-site .st-delivery__icon--empty {
	background-color: transparent;
}

.st-site .st-delivery__icon i {
	color: inherit;
}

.st-site .st-delivery__svg,
.st-site .st-delivery__icon img {
	max-width: 22px;
	max-height: 22px;
}

.st-site .st-delivery__body {
	min-width: 0;
	flex: 1 1 auto;
}

/*
	СТОИМОСТЬ СТОИТ РЯДОМ С НАЗВАНИЕМ, А НЕ У КРАЯ КОЛОНКИ. Прежний
	`justify-content: space-between` разносил их по разным концам строки,
	и на широкой колонке между «Доставка по городу» и «500» оставалась
	пустая полоса в пол-экрана — цифра переставала читаться как цена
	ЭТОГО способа. `margin-right: auto` у названия дает тот же результат
	при узкой колонке (перенос) и не рвет пару при широкой
*/
.st-site .st-delivery__line {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
}

.st-site .st-delivery__name {
	font-size: 16px;
	font-weight: 600;
	color: var(--st-text);
}

/* Цена — плашкой: так она не спорит с названием весом шрифта
   и остается заметной даже в конце длинной строки */
.st-site .st-delivery__note {
	flex: 0 0 auto;
	padding: 2px 8px;
	border-radius: 999px;
	background-color: color-mix(in srgb, var(--st-accent) 14%, transparent);
	color: var(--st-accent);
	font-size: 13px;
	font-weight: 700;
	white-space: nowrap;
}

.st-site .st-delivery__text {
	margin-top: 2px;
	color: var(--st-muted);
	font-size: 14px;
	line-height: 1.45;
}

.st-site .st-delivery__foot {
	margin-top: 18px;
	color: var(--st-muted);
	font-size: 13px;
}

/* НА УЗКОМ ЭКРАНЕ — ОДНА КОЛОНКА. Правило дублируется по атрибуту
   устройства: в конструкторе медиазапросы считаются от окна браузера,
   а не от ширины «листа» */
.st-site[data-st-device="mobile"] .st-delivery,
.st-site[data-st-device="tablet"] .st-delivery {
	grid-template-columns: minmax(0, 1fr);
}

@media (max-width: 767.98px) {
	.st-site .st-delivery {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* Кнопка под списками доставки/услуг: отбивка сверху и та же линия
   выравнивания, что у содержимого блока (2026-08-18) */
.st-site .st-delivery__act {
	margin-top: 18px;
}


/* ==== СРАВНЕНИЕ ТОВАРОВ (2026-08-19) ================================== */
/*
	ТАБЛИЦА С ГОРИЗОНТАЛЬНОЙ ПРОКРУТКОЙ — единственный честный ответ
	на «четыре товара и экран 360 px» (тот же довод, что у блока «Прайс»):
	перенос по символам ломает значения, а «карточками вместо колонок»
	превращает сравнение в другой блок.

	ПЕРВАЯ КОЛОНКА (названия характеристик) ПРИЛИПАЕТ к левому краю:
	прокрутив таблицу на третий товар, покупатель обязан видеть, ЧТО
	именно он сейчас сравнивает
*/
/*
	==== ПЕРЕРАБОТКА ВИДА (2026-08-21) ====

	ЧТО БЫЛО НЕ ТАК. Обложка занимала ВСЮ ширину колонки — на двух товарах
	это два квадрата по трети экрана, и первая характеристика оказывалась
	ниже сгиба. Таблицу открывают ради строк, а показывала она картинки.
	Сетка при этом была нарисована линиями со всех сторон и читалась
	как выгрузка из таблицы, а не как часть витрины.

	ЧТО СТАЛО:
	  · шапка колонки — КАРТОЧКА с обложкой 72 px: обложка здесь для
	    узнавания товара, а не для разглядывания рисунка;
	  · вертикальных линий больше нет — колонки разделяет ВОЗДУХ,
	    а строки читаются по горизонтальным линиям, как в прайсе;
	  · четные строки подложены — глаз не теряет строку на широком экране;
	  · РАЗЛИЧАЮЩИЕСЯ СТРОКИ ПОМЕЧЕНЫ (см. `--diff` ниже) — ради этого
	    таблицу и открывают.

	ПЕРВАЯ КОЛОНКА ПРИЛИПАЕТ к левому краю: прокрутив таблицу на третий
	товар, покупатель обязан видеть, ЧТО именно он сейчас сравнивает
*/
/*
	ВИД ПОЛОСЫ ЗДЕСЬ НЕ ЗАДАЕТСЯ (2026-08-22): его берет общее правило
	сайта — то самое, которое владелец настраивает в оформлении
	(см. `steditorScrollCss`). Прежние три правила были написаны раньше
	этой настройки и делали таблицу сравнения исключением из нее
*/
.st-site .st-versus__scroll {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.st-site .st-versus__table {
	width: 100%;
	border-collapse: collapse;
	font-size: 14px;
}

.st-site .st-versus__corner,
.st-site .st-versus__label {
	position: sticky;
	left: 0;
	z-index: 1;
	min-width: 160px;
	max-width: 240px;
	padding: 12px 14px;
	background-color: var(--st-surface);
	color: var(--st-muted);
	font-weight: 500;
	text-align: left;
	vertical-align: middle;
}

.st-site .st-versus__corner {
	font-size: 12px;
	font-weight: 600;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	vertical-align: bottom;
	padding-bottom: 16px;
}

.st-site .st-versus__col {
	min-width: 220px;
	padding: 0 8px 14px;
	text-align: left;
	vertical-align: bottom;
}

/* Карточка товара в шапке: обложка слева, данные справа, крестик
   в правом верхнем углу самой карточки */
.st-site .st-versus__card {
	position: relative;
	display: flex;
	align-items: flex-start;
	gap: 12px;
	padding: 12px 40px 12px 12px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius, 16px);
	background-color: var(--st-surface);
}

.st-site .st-versus__cover {
	display: block;
	flex: 0 0 auto;
	width: 72px;
	height: 72px;
	overflow: hidden;
	border-radius: var(--st-radius-sm, 10px);
	background-color: var(--st-surface-alt);
}

.st-site .st-versus__cover img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.st-site .st-versus__info {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.st-site .st-versus__name {
	display: block;
	color: var(--st-text-base);
	font-weight: 600;
	line-height: 1.3;
	text-decoration: none;
}

.st-site .st-versus__name:hover {
	color: var(--st-accent);
}

.st-site .st-versus__price {
	display: block;
	margin-top: 4px;
	font-weight: 700;
}

.st-site .st-versus__pack {
	display: block;
	color: var(--st-muted);
	font-size: 12px;
}

.st-site .st-versus__stock {
	display: block;
	margin-top: 2px;
	font-size: 12px;
	font-weight: 600;
}

.st-site .st-versus__stock--ok { color: #47BE7D; }
.st-site .st-versus__stock--wait { color: #F1BC00; }
.st-site .st-versus__stock--off { color: var(--st-danger); }

/*
	==== КРЕСТИК: ГЛИФ ЗАМЕНЕН НА ДВЕ ЛИНИИ (2026-08-21) ====

	БЫЛО `&times;` текстом — и он стоял НЕ ПО ЦЕНТРУ кнопки. Причина
	не в отступах: у текстового символа своя метрика, он сидит на базовой
	линии шрифта, а высота строки и надстрочный запас у каждого шрифта
	свои. Никакой `line-height` не центрирует его надежно во всех
	начертаниях сразу — именно поэтому крестик «уехал».

	ПОЭТОМУ КРЕСТ НАРИСОВАН ДВУМЯ ПСЕВДОЭЛЕМЕНТАМИ: это геометрия,
	а не текст, и центр у нее ровно там, где центр кнопки, в любом шрифте
	и при любом масштабе страницы
*/
.st-site .st-versus__drop {
	position: absolute;
	top: 8px;
	right: 8px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 26px;
	height: 26px;
	padding: 0;
	border: 0;
	border-radius: 999px;
	background-color: var(--st-surface-alt);
	color: var(--st-muted);
	cursor: pointer;
	transition: background-color 0.15s ease, color 0.15s ease;
}

.st-site .st-versus__drop:hover {
	background-color: var(--st-danger, #E4572E);
	color: #FFFFFF;
}

.st-site .st-versus__drop-x {
	position: relative;
	display: block;
	width: 11px;
	height: 11px;
}

.st-site .st-versus__drop-x::before,
.st-site .st-versus__drop-x::after {
	content: '';
	position: absolute;
	top: 50%;
	left: 0;
	width: 100%;
	height: 1.5px;
	border-radius: 2px;
	background-color: currentColor;
}

.st-site .st-versus__drop-x::before { transform: rotate(45deg); }
.st-site .st-versus__drop-x::after { transform: rotate(-45deg); }

.st-site .st-versus__cell {
	padding: 12px 14px;
	color: var(--st-text-base);
	vertical-align: middle;
}

.st-site .st-versus__cell--none {
	color: var(--st-muted);
}

/* Строки разделяются линией сверху и через одну подложены: на широком
   экране взгляд иначе теряет строку между колонками */
.st-site .st-versus__tr > * {
	border-top: 1px solid var(--st-border);
}

.st-site .st-versus__tr:nth-child(even) > * {
	background-color: var(--st-surface-alt);
}

/*
	==== ОТМЕТКА РАЗЛИЧИЙ (2026-08-21) ====

	ГЛАВНОЕ, ЧЕГО ТАБЛИЦЕ НЕ ХВАТАЛО. Двадцать одинаковых строк и три
	разных выглядели совершенно одинаково — покупатель искал отличия
	глазами, хотя сервер их уже посчитал (`row.same`).

	ПОМЕЧАЕТСЯ ПОЛОСОЙ СЛЕВА И ЖИРНЫМ ЗНАЧЕНИЕМ, а не цветным фоном
	всей строки: фон спорил бы с подложкой четных строк и с палитрой
	темы, а полоса читается как указатель и не мешает читать сами числа.
	Название характеристики при этом становится обычного цвета текста —
	«эта строка важна», а не приглушенная подпись
*/
.st-site .st-versus__tr--diff .st-versus__label {
	position: relative;
	color: var(--st-text-base);
	font-weight: 600;
}

.st-site .st-versus__tr--diff .st-versus__label::before {
	content: '';
	position: absolute;
	top: 8px;
	bottom: 8px;
	left: 0;
	width: 3px;
	border-radius: 0 3px 3px 0;
	background-color: var(--st-accent);
}

.st-site .st-versus__tr--diff .st-versus__cell {
	font-weight: 600;
}

.st-site .st-versus__same {
	padding: 16px 0 0;
	color: var(--st-muted);
	font-size: 14px;
}

/* На узком экране карточка шапки ужимается: обложка меньше, крестик
   ближе — иначе колонка не влезает даже в горизонтальную прокрутку */
@media (max-width: 575.98px) {
	.st-site .st-versus__col {
		min-width: 190px;
	}

	.st-site .st-versus__cover {
		width: 56px;
		height: 56px;
	}
}

/* ==== ОПТОВЫЕ ЦЕНЫ «ОТ N м²» (2026-08-19) ============================ */
/*
	ПОД ЦЕНОЙ, РЯДОМ С ЧИСЛАМИ — там, где считают деньги. Пилюлями, а не
	таблицей: порогов два-три, и таблица из двух строк выглядит тяжелее,
	чем сам ответ
*/
.st-site .st-tiers {
	margin-top: 12px;
	padding: 12px 14px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius-sm, 10px);
}

.st-site .st-tiers__head {
	margin-bottom: 8px;
	font-size: 14px;
	font-weight: 700;
	color: var(--st-text);
}

.st-site .st-tiers__list {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.st-site .st-tiers__item {
	display: inline-flex;
	align-items: baseline;
	gap: 6px;
	padding: 5px 11px;
	border-radius: 999px;
	background-color: var(--st-surface-alt);
	font-size: 13px;
}

.st-site .st-tiers__from {
	color: var(--st-muted);
}

.st-site .st-tiers__off {
	color: var(--st-accent);
	font-weight: 700;
}

.st-site .st-tiers__note {
	margin-top: 8px;
	color: var(--st-muted);
	font-size: 12px;
}

/* Строка скидки в калькуляторе: тот же акцент, что у порогов на странице
   товара, — обещание и расчет обязаны выглядеть одним и тем же */
.st-site .st-calc__row--sale .st-calc__value {
	color: var(--st-accent);
	font-weight: 700;
}


/* ==== АКЦИИ (2026-08-19) ============================================== */
/*
	КАРТОЧКИ В СЕТКУ, как у преимуществ, но с двумя своими элементами:
	плашкой условия сверху («−15%», «от 30 м²») и сроком внизу. Плашка
	стоит ПЕРВОЙ, потому что читают карточку ради нее
*/
.st-site .st-promos {
	display: grid;
	grid-template-columns: repeat(var(--st-cols, 3), minmax(0, 1fr));
	gap: 16px;
}

.st-site .st-promo {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 8px;
	padding: 18px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius, 16px);
	background-color: var(--st-surface);
}

.st-site .st-promos--compact .st-promo {
	padding: 14px;
	gap: 6px;
}

.st-site .st-promo__note {
	align-self: flex-start;
	padding: 4px 10px;
	border-radius: 999px;
	background-color: var(--st-accent);
	color: var(--st-accent-text);
	font-size: 13px;
	font-weight: 700;
}

.st-site .st-promo__title {
	font-size: 17px;
	font-weight: 700;
	color: var(--st-text);
}

.st-site .st-promo__text {
	color: var(--st-muted);
	font-size: 14px;
	line-height: 1.45;
}

.st-site .st-promo__till {
	display: flex;
	align-items: center;
	gap: 6px;
	margin-top: auto;
	color: var(--st-muted);
	font-size: 13px;
}

.st-site .st-promo__till i {
	color: inherit;
	font-size: 15px;
}

.st-site .st-promo__btn {
	align-self: flex-start;
	margin-top: 4px;
}

/*
	ПРОСРОЧЕННАЯ АКЦИЯ ВИДНА ТОЛЬКО В КОНСТРУКТОРЕ (на сайте ее нет вовсе).
	Приглушение, а не скрытие: владелец должен понять, ПОЧЕМУ карточки нет
	на витрине, и поправить срок — а не решить, что блок сломался
*/
.st-site .st-promo--off {
	opacity: 0.55;
	border-style: dashed;
}

.st-site .st-promo__over {
	color: var(--st-danger);
	font-size: 12px;
	font-weight: 600;
}

.st-site[data-st-device="mobile"] .st-promos {
	grid-template-columns: minmax(0, 1fr);
}

@media (max-width: 767.98px) {
	.st-site .st-promos {
		grid-template-columns: minmax(0, 1fr);
	}
}


/* ==== НЕСКОЛЬКО ТОЧЕК ПРОДАЖ НА КАРТЕ (2026-08-19) ==================== */
/*
	КАРТА И СПИСОК РЯДОМ, а не список под картой: выбирая салон, покупатель
	держит перед глазами обе половины — метку и адрес с часами работы.
	На узком экране список уезжает ПОД карту (media-запрос ниже): в две
	колонки на телефоне не читается ни одна из них.

	КОРОБКА ПЕЧАТАЕТСЯ ТОЛЬКО ПОД СПИСОК (см. ветку `map`
	в e_user_steditor_block): у карты без списка разметка осталась прежней
*/
.st-site .st-map-box {
	display: grid;
	grid-template-columns: minmax(0, 2fr) minmax(240px, 1fr);
	gap: 16px;
	align-items: stretch;
}

/* Список выше карты не растет: у карты своя высота, а список прокручивается
   внутри себя — иначе десять салонов растянули бы блок на два экрана */
.st-site .st-map__list {
	display: flex;
	flex-direction: column;
	gap: 8px;
	max-height: 100%;
	overflow-y: auto;
}

.st-site .st-map__item {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	width: 100%;
	padding: 12px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	color: inherit;
	text-align: left;
	cursor: pointer;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}

.st-site .st-map__item:hover {
	border-color: var(--st-accent);
}

/* Выбранная точка — та, к которой сейчас ведена карта. Без этой отметки
   в списке из пяти салонов не понять, чья метка в центре */
.st-site .st-map__item--on {
	border-color: var(--st-accent);
	background-color: var(--st-surface-alt);
}

.st-site .st-map__pin-sm {
	flex: 0 0 auto;
	color: var(--st-accent);
}

.st-site .st-map__pin-sm svg {
	width: 20px;
	height: 20px;
}

.st-site .st-map__item-body {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.st-site .st-map__item-title {
	font-size: 14px;
	font-weight: 700;
	color: var(--st-text);
}

.st-site .st-map__item-address,
.st-site .st-map__item-note {
	color: var(--st-muted);
	font-size: 13px;
	line-height: 1.4;
}

.st-site[data-st-device="mobile"] .st-map-box,
.st-site[data-st-device="tablet"] .st-map-box {
	grid-template-columns: minmax(0, 1fr);
}

.st-site[data-st-device="mobile"] .st-map__list,
.st-site[data-st-device="tablet"] .st-map__list {
	max-height: 260px;
}

@media (max-width: 991.98px) {
	.st-site .st-map-box {
		grid-template-columns: minmax(0, 1fr);
	}

	.st-site .st-map__list {
		max-height: 260px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.st-site .st-map__item {
		transition: none;
	}
}


/* ==== КВИЗ-ПОДБОР (2026-08-19) ======================================== */
/*
	ОДИН ВОПРОС НА ЭКРАНЕ — вся подача блока держится на этом: длинная
	анкета отпугивает, а один вопрос с крупными кнопками проходится
	не задумываясь. Шаги печатает сервер, показывает нужный скрипт
	(`hidden` у остальных), поэтому своих правил видимости здесь нет
*/
.st-site .st-quiz {
	display: flex;
	flex-direction: column;
	gap: 16px;
	padding: 20px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
}

.st-site .st-quiz__note {
	color: var(--st-muted);
	font-size: 14px;
	line-height: 1.5;
}

/* ПОЛОСА ПРОГРЕССА РАСТЕТ transform-ом, а не шириной: ширина заставляет
   браузер пересчитывать раскладку, а полоса меняется на каждый ответ */
.st-site .st-quiz__bar {
	height: 4px;
	overflow: hidden;
	border-radius: 999px;
	background-color: var(--st-surface-alt);
}

.st-site .st-quiz__bar-on {
	display: block;
	width: 100%;
	height: 100%;
	border-radius: inherit;
	background-color: var(--st-accent);
	transform: scaleX(var(--st-part, 0));
	transform-origin: left center;
	transition: transform 0.25s ease;
}

.st-site .st-quiz__step {
	display: flex;
	flex-direction: column;
	gap: 10px;
}

/*
	В КОНСТРУКТОРЕ ШАГИ ИДУТ ЛЕНТОЙ (там видны все сразу), и между ними
	нужна черта: без нее вопросы слипаются в один длинный список
*/
.st-site .st-quiz__step + .st-quiz__step {
	padding-top: 16px;
	border-top: 1px dashed var(--st-border);
}

.st-site .st-quiz__num {
	color: var(--st-muted);
	font-size: 12px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
}

.st-site .st-quiz__q {
	font-size: 20px;
	font-weight: 700;
	line-height: 1.3;
	color: var(--st-text);
}

.st-site .st-quiz__hint {
	color: var(--st-muted);
	font-size: 13px;
	line-height: 1.45;
}

/*
	ВАРИАНТЫ — СЕТКА С АВТОПОДБОРОМ ШИРИНЫ, а не заданное число колонок:
	у вопроса «куда кладете» их три, у вопроса «бюджет» — пять, и владелец
	не должен настраивать раскладку каждому вопросу отдельно
*/
.st-site .st-quiz__opts {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	gap: 10px;
}

.st-site .st-quiz__opt {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 14px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface-alt);
	color: inherit;
	text-align: left;
	cursor: pointer;
	transition: border-color 0.15s ease, background-color 0.15s ease;
}

.st-site .st-quiz__opt:hover {
	border-color: var(--st-accent);
}

/* Выбранный вариант остается отмеченным и после возврата назад: человек,
   вернувшийся посмотреть свой ответ, должен его увидеть */
.st-site .st-quiz__opt--on {
	border-color: var(--st-accent);
	background-color: var(--st-surface);
	box-shadow: inset 0 0 0 1px var(--st-accent);
}

.st-site .st-quiz__icon {
	flex: 0 0 auto;
	font-size: 22px;
	color: var(--st-accent);
}

.st-site .st-quiz__opt-body {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
}

.st-site .st-quiz__label {
	font-size: 15px;
	font-weight: 600;
	color: var(--st-text);
}

.st-site .st-quiz__opt-hint {
	color: var(--st-muted);
	font-size: 12px;
	line-height: 1.4;
}

/* «Назад» — приглушенная ссылка, а не кнопка: главное действие на экране
   это выбор варианта, и второй яркий орган управления спорил бы с ним */
.st-site .st-quiz__back,
.st-site .st-quiz__restart {
	align-self: flex-start;
	padding: 0;
	border: 0;
	background: none;
	color: var(--st-muted);
	font-size: 13px;
	font-weight: 600;
	text-decoration: underline;
	cursor: pointer;
}

.st-site .st-quiz__back:hover,
.st-site .st-quiz__restart:hover {
	color: var(--st-accent);
}

.st-site .st-quiz__result {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.st-site .st-quiz__rtitle {
	font-size: 20px;
	font-weight: 700;
	color: var(--st-text);
}

.st-site .st-quiz__count {
	color: var(--st-muted);
	font-size: 13px;
}

.st-site .st-quiz__count:empty {
	display: none;
}

.st-site .st-quiz__none {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 12px;
}

.st-site .st-quiz__wait {
	color: var(--st-muted);
	font-size: 14px;
}

.st-site[data-st-device="mobile"] .st-quiz__opts {
	grid-template-columns: minmax(0, 1fr);
}

@media (max-width: 575.98px) {
	.st-site .st-quiz__opts {
		grid-template-columns: minmax(0, 1fr);
	}

	.st-site .st-quiz__q {
		font-size: 18px;
	}
}

@media (prefers-reduced-motion: reduce) {
	.st-site .st-quiz__bar-on,
	.st-site .st-quiz__opt {
		transition: none;
	}
}


/* ==== РАССРОЧКА (2026-08-19) ========================================== */
/*
	ПОЛЕ СУММЫ СВЕРХУ, СРОКИ ПОД НИМ: покупатель сначала называет свою
	сумму и лишь затем читает платежи — обратный порядок заставлял бы
	его смотреть на числа, посчитанные не для него
*/
.st-site .st-credit {
	display: flex;
	flex-direction: column;
	gap: 14px;
	padding: 20px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
}

.st-site .st-credit__note {
	color: var(--st-muted);
	font-size: 14px;
	line-height: 1.5;
}

.st-site .st-credit__form {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}

.st-site .st-credit__field {
	flex: 1 1 180px;
	min-width: 0;
}

/* Сумма в рассрочку — итог ввода, поэтому она крупнее полей и стоит
   между ними и таблицей: именно её делят на месяцы строки ниже */
.st-site .st-credit__sub {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	padding-bottom: 12px;
	border-bottom: 1px solid var(--st-border);
}

.st-site .st-credit__sub-label {
	color: var(--st-muted);
	font-size: 13px;
}

.st-site .st-credit__sub-value {
	font-size: 20px;
	font-weight: 700;
	color: var(--st-text);
}

.st-site .st-credit__terms {
	display: flex;
	flex-direction: column;
	gap: 8px;
}

.st-site .st-credit__row {
	display: grid;
	grid-template-columns: minmax(0, 1fr) auto minmax(0, auto);
	align-items: baseline;
	gap: 12px;
	padding: 12px 14px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface-alt);
}

.st-site .st-credit__months {
	font-size: 14px;
	font-weight: 600;
	color: var(--st-text);
}

.st-site .st-credit__tag {
	margin-left: 8px;
	color: var(--st-muted);
	font-size: 12px;
	font-weight: 500;
}

/* Платеж — то, ради чего блок открывают, и он крупнее всего в строке */
.st-site .st-credit__pay {
	font-size: 18px;
	font-weight: 700;
	color: var(--st-accent);
	white-space: nowrap;
}

.st-site .st-credit__per {
	margin-left: 2px;
	color: var(--st-muted);
	font-size: 12px;
	font-weight: 500;
}

.st-site .st-credit__over {
	color: var(--st-muted);
	font-size: 12px;
	text-align: right;
}

.st-site .st-credit__partner {
	color: var(--st-muted);
	font-size: 13px;
}

.st-site .st-credit__act {
	display: flex;
}

/*
	ДИСКЛЕЙМЕР МЕЛКИЙ, НО ЧИТАЕМЫЙ. Спрятать его в цвет фона было бы
	ровно тем нарушением, ради которого он и обязателен: расчет платежа
	это реклама финансовой услуги
*/
.st-site .st-credit__disc {
	padding-top: 10px;
	border-top: 1px solid var(--st-border);
	color: var(--st-muted);
	font-size: 11px;
	line-height: 1.45;
}

.st-site[data-st-device="mobile"] .st-credit__row {
	grid-template-columns: minmax(0, 1fr);
	gap: 4px;
}

.st-site[data-st-device="mobile"] .st-credit__over {
	text-align: left;
}

@media (max-width: 575.98px) {
	.st-site .st-credit__row {
		grid-template-columns: minmax(0, 1fr);
		gap: 4px;
	}

	.st-site .st-credit__over {
		text-align: left;
	}
}

/* ======================================================================= */
/* ==== СТРАНИЦА ТОВАРА: ПЕРЕЕХАЛО ИЗ stsite.css (2026-08-20) ============ */
/* ======================================================================= */
/*
	ПОЧЕМУ ПЕРЕЕХАЛО. Эти правила лежали в `stsite.css` с пометкой
	«в конструкторе этих страниц нет вовсе, и тащить их правила в общий
	`stheme.css` незачем». Пометка устарела: страница товара стала
	СИСТЕМНОЙ СТРАНИЦЕЙ КОНСТРУКТОРА, ее блоки рисуются на холсте, —
	а холст грузит только `stheme.css`. Без переезда владелец правил бы
	карточку товара без единого стиля.

	В `stsite.css` остались правила, которых в конструкторе действительно
	нет: переключатель день/ночь, полоса предпросмотра, живой поиск,
	заглушка 404, страницы БРЕНДА и ПОДБОРКИ, фильтры каталога
*/
/* ==== КАРТОЧКА ТОВАРА =================================================== */

.st-site .st-pdp {
	display: grid;
	grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
	gap: 28px;
	align-items: start;
}

.st-site .st-pdp__cover {
	position: relative;
	display: block;
	overflow: hidden;
	border-radius: var(--st-radius);
	background-color: var(--st-surface-alt);
	box-shadow: var(--st-shadow);
}

/* Товар без единого кадра: коробка обязана сохранить пропорции, иначе
   вся раскладка страницы схлопнется */
.st-site .st-pdp__cover--empty {
	padding-top: 72%;
}

.st-site .st-pdp__image {
	width: 100%;
	height: auto;
	display: block;
}

.st-site .st-pdp__badge {
	position: absolute;
	top: 12px;
	left: 12px;
	padding: 4px 10px;
	border-radius: 999px;
	background-color: var(--st-danger);
	color: #FFFFFF;
	font-size: 13px;
	font-weight: 700;
}

.st-site .st-pdp__thumbs {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 10px;
}

.st-site .st-pdp__thumb {
	display: block;
	width: 84px;
	height: 84px;
	overflow: hidden;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface-alt);
}

.st-site .st-pdp__thumb img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.st-site .st-pdp__info {
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.st-site .st-pdp__title {
	margin: 0;
	font-size: 30px;
	font-weight: 700;
	line-height: 1.25;
	color: var(--st-text);
}

.st-site .st-pdp__price {
	font-size: 28px;
	font-weight: 700;
	color: var(--st-text);
}

.st-site .st-pdp__price-old {
	margin-left: 10px;
	font-size: 17px;
	font-weight: 500;
	color: var(--st-muted);
	text-decoration: line-through;
}

/* ЦЕНА ОДНОЙ УПАКОВКИ — вторая строка под ценой за метр (2026-08-18).
   Мельче: это ответ на второй вопрос, но именно эта сумма попадет
   в корзину за одну единицу товара */
.st-site .st-pdp__price-pack {
	margin-top: 4px;
	font-size: 14px;
	color: var(--st-muted);
}

/*
	ВЫГОДА В РУБЛЯХ — плашка рядом со старой ценой (та же пара, что
	в кабинете). ЦВЕТ ЗАШИТ, А НЕ ВЗЯТ У ТЕМЫ: акцент витрины бывает любым,
	вплоть до зеленого, а «выгода» обязана читаться как выгода на всех
	сайтах одинаково
*/
.st-site .st-pdp__save {
	display: inline-block;
	margin-left: 10px;
	padding: 3px 9px;
	border-radius: 6px;
	background-color: rgba(241, 65, 108, 0.12);
	color: #F1416C;
	font-size: 12px;
	font-weight: 700;
	vertical-align: middle;
}

/*
	==== СВОДКА КЛЮЧЕВЫХ СВОЙСТВ (2026-08-15) ====

	ТА ЖЕ ПЛИТКА В ДВЕ КОЛОНКИ, ЧТО В КАБИНЕТЕ (`e_user_market_product_view`,
	блок хайлайтов): крупный значок слева, значение и подпись справа.
	Рамка ПУНКТИРНАЯ — как там же: сводка не карточка товара и не должна
	спорить с ней плотностью.

	ЗНАЧКАМИ ПОВЕРХ ФОТО ЭТО НЕ ДЕЛАЕТСЯ: на странице товара есть место
	для значения и подписи, а значок без них требует навести курсор —
	действие, которого на телефоне не существует. Значками сводка идет
	только в СЕТКЕ (`.st-product__props`), где места нет
*/
.st-site .st-pdp__props {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 10px;
}

.st-site .st-pdp__prop {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 12px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius);
}

.st-site .st-pdp__prop-icon {
	flex-shrink: 0;
	font-size: 26px;
	line-height: 1;
}

.st-site .st-pdp__prop-value {
	font-size: 15px;
	font-weight: 700;
	color: var(--st-text);
}

/*
	ПОДПИСЬ КАПСОМ — как в кабинете. Регистр здесь несет работу: значение
	и подпись стоят одно под другим, и без разницы в начертании «20 лет»
	и «срок службы» читаются как одна фраза
*/
.st-site .st-pdp__prop-label {
	font-size: 11px;
	color: var(--st-muted);
	text-transform: uppercase;
	letter-spacing: 0.03em;
}

/* ==== БЕЙДЖИ, ТИЗЕР И УПАКОВКА (2026-08-15) ============================ */

.st-site .st-pdp__badges {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

/*
	ТРИ РОЛИ, А НЕ ТРИ ЦВЕТА: `accent` — признак товара, `plain` —
	нейтральное значение (цвет декора), `good` — «с этим все в порядке»
	(класс эмиссии). Раскрашивает их тема САЙТА, поэтому зашитых цветов
	здесь нет: подложка собирается из акцента через `color-mix`, ровно
	как у значка карточки преимуществ
*/
.st-site .st-badge {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	padding: 4px 10px;
	border-radius: 999px;
	font-size: 12px;
	font-weight: 600;
	line-height: 1.4;
}

.st-site .st-badge--accent {
	background-color: color-mix(in srgb, var(--st-accent) 14%, transparent);
	color: var(--st-accent);
}

.st-site .st-badge--plain {
	background-color: var(--st-surface-alt);
	color: var(--st-text-base);
}

.st-site .st-badge--good {
	background-color: rgba(80, 205, 137, 0.16);
	color: #3FA76C;
}

.st-site[data-st-mode="dark"] .st-badge--good {
	color: #6FDCA0;
}

.st-site .st-pdp__teaser {
	color: var(--st-muted);
	font-size: 15px;
	line-height: 1.55;
}

/*
	ПЛАШКА «ОДНА УПАКОВКА» — тот же прием, что в кабинете: пунктирная
	рамка акцентом и его же полупрозрачная подложка. Это не характеристика,
	а ответ на вопрос «что я получу за одну упаковку», и он обязан
	отличаться от таблицы по весу
*/
.st-site .st-pdp__pack {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 14px 16px;
	border: 1px dashed var(--st-accent);
	border-radius: var(--st-radius);
	background-color: color-mix(in srgb, var(--st-accent) 8%, transparent);
}

/*
	ЦВЕТ СТАВИТСЯ ОТ ТЕГА (исправлено 2026-08-22) — та же ловушка, что
	у значка примерки ниже: иконочный шрифт красит элемент `i` селектором
	(0,1,1), а одиночный класс (0,1,0) ему проигрывает, и значок упаковки
	оставался белым при честно акцентной рамке. Три тега — три вида
	значка: глиф, свой SVG, анимация Lottie
*/
.st-site i.st-pdp__pack-icon,
.st-site img.st-pdp__pack-icon,
.st-site span.st-pdp__pack-icon {
	flex-shrink: 0;
	font-size: 30px;
	line-height: 1;
	color: var(--st-accent);
}

.st-site .st-pdp__pack-title {
	font-size: 14px;
	font-weight: 700;
	color: var(--st-text);
}

.st-site .st-pdp__pack-text {
	font-size: 13px;
	color: var(--st-text-base);
}

/* Описание идет отдельным разделом под характеристиками — в той же
   пунктирной коробке, что и они (порядок «сначала цифры, потом текст»
   взят у кабинета) */
.st-site .st-pdp__desc {
	padding: 18px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius);
}

.st-site .st-pdp__links {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

/*
	ЧИП — ССЫЛКА НА РОДИТЕЛЬСКУЮ СУЩНОСТЬ (бренд, подборка).
	Подпись внутри чипа объясняет, КУДА он ведет: «Бренд» рядом
	с названием читается однозначно, а одно название — нет
*/
.st-site .st-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	padding: 7px 14px;
	border: 1px solid var(--st-border);
	border-radius: 999px;
	background-color: var(--st-surface);
	color: var(--st-text-base);
	font-size: 14px;
	font-weight: 600;
	cursor: pointer;
	transition: border-color 0.15s ease;
}

.st-site .st-chip:hover {
	border-color: var(--st-accent);
}

.st-site .st-chip__label {
	color: var(--st-muted);
	font-weight: 500;
}

/* ==== ХАРАКТЕРИСТИКИ ==================================================== */

/*
	==== ПЕРЕДЕЛАНО ПОД КАБИНЕТ (2026-08-15) ====

	БЫЛО: группы одна под другой во всю ширину, значения слева, рамка
	сплошная, значков нет. Данные те же, что в маркете, а страница
	читалась совсем иначе.

	СТАЛО: сетка карточек (три в ряд на широком экране), пунктирная рамка,
	значок группы, строка «метка слева — значение справа». Разница
	с кабинетом теперь только в палитре: там классы Metronic, здесь `st-*`
	на переменных темы сайта
*/
/*
	==== ОТБИВКА СВЕРХУ СНЯТА (2026-08-21) ====

	Эти 40 px появились, когда страница товара была ОДНИМ шаблоном
	(`e_site_catalog`): характеристики шли внутри общего контейнера сразу
	за столбцом покупки, и отделять их было нечем, кроме собственного
	отступа.

	ПОСЛЕ ПЕРЕЕЗДА В КОНСТРУКТОР ЭТО СТАЛО ЛИШНИМ СЛОЕМ: характеристики —
	ОТДЕЛЬНЫЙ БЛОК на сетке страницы, и вертикальный ритм ему уже задает
	`--st-pad-y` самого блока, как и любому другому. Старый отступ
	складывался с новым, и над «Характеристиками» получалась двойная
	пауза — заметно шире, чем между блоками на страницах, собранных
	владельцем.

	ПРАВИЛО НА БУДУЩЕЕ: у блока конструктора не бывает СВОИХ внешних
	отступов. Расстояние между блоками — это всегда их `--st-pad-y`
	плюс спейсер; собственный `margin` у содержимого блока спорит
	с настройкой владельца и всегда выигрывает у нее молча
*/
.st-site .st-specs {
	margin-top: 0;
}

.st-site .st-specs__head {
	margin: 0 0 18px;
	font-size: 22px;
	font-weight: 700;
	color: var(--st-text);
}

/*
	ТРИ КОЛОНКИ, НО ЧЕРЕЗ `auto-fit`, А НЕ ЧИСЛОМ: у товара бывает две
	заполненные группы из трех, и жесткая тройка оставила бы пустую
	дорожку. Минимум в 260px — та ширина, ниже которой пара
	«характеристика — значение» начинает переноситься
*/
.st-site .st-specs__grid {
	display: grid;
	gap: 16px;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

/*
	РАМКА ПУНКТИРНАЯ — как в кабинете: карточка характеристик не объект
	витрины, а способ сгруппировать строки, и сплошная рамка спорила бы
	по весу с карточками товаров
*/
.st-site .st-specs__group {
	padding: 18px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius);
	color: var(--st-text-base);
}

.st-site .st-specs__title {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-bottom: 8px;
	font-size: 15px;
	font-weight: 700;
	color: var(--st-text);
}

/* Значок группы — акцентом темы: он опознавательный знак раздела,
   а не самостоятельная деталь оформления */
.st-site .st-specs__title i {
	color: var(--st-accent);
	font-size: 18px;
}

.st-site .st-specs__rows {
	margin: 0;
}

/*
	СТРОКА — МЕТКА СЛЕВА, ЗНАЧЕНИЕ СПРАВА, по базовой линии.
	Выравнивание значений по ПРАВОМУ краю не украшение: в карточке
	шириной в треть страницы столбец значений читается только когда
	у него есть край
*/
.st-site .st-specs__row {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	gap: 12px;
	padding: 7px 0;
	border-bottom: 1px dashed var(--st-border);
}

.st-site .st-specs__row:last-child {
	border-bottom: 0;
}

.st-site .st-specs__key {
	margin: 0;
	color: var(--st-muted);
	font-size: 13px;
}

.st-site .st-specs__value {
	margin: 0;
	font-size: 13px;
	font-weight: 600;
	text-align: right;
}

/* ==== АДАПТИВ =========================================================== */
/*
	ТОЧКИ ПЕРЕЛОМА ТЕ ЖЕ, ЧТО У САЙТА (992 / 576) — второго набора ширин
	в проекте быть не должно
*/
@media (max-width: 991.98px) {
	.st-site .st-pdp {
		grid-template-columns: minmax(0, 1fr);
		gap: 20px;
	}

	.st-site .st-pdp__title { font-size: 25px; }
	.st-site .st-pdp__price { font-size: 24px; }
	.st-site .st-catalog__title { font-size: 25px; }
}

@media (max-width: 575.98px) {
	/*
		НА ТЕЛЕФОНЕ СТРОКА ЛОМАЕТСЯ В ДВЕ, а не жмется в одну линию:
		«Класс пожарной опасности» и «КМ2» рядом оставляют значению
		четверть ширины. Значение при этом возвращается к ЛЕВОМУ краю —
		прижимать его вправо не к чему, столбца больше нет
	*/
	.st-site .st-specs__row {
		display: block;
		padding: 8px 0;
	}

	.st-site .st-specs__value {
		margin-top: 2px;
		text-align: left;
	}

	.st-site .st-catalog__cover {
		flex-basis: 100%;
		width: 100%;
	}

	.st-site .st-pdp__thumb {
		width: 64px;
		height: 64px;
	}

	/* Две колонки сводки на телефоне дают меньше половины строки
	   на значение — подпись «Стойкость к влаге» переносилась бы трижды */
	.st-site .st-pdp__props {
		grid-template-columns: minmax(0, 1fr);
	}
}

/* ==== «С ЭТИМ ТОВАРОМ БЕРУТ» (2026-08-18) ============================= */
/*
	Ряд довесков под карточкой товара. Отдельного оформления у него почти
	нет — это ТА ЖЕ витрина, просто короткая: карточки рисует
	`websiteProductCard()`, сетка та же `.st-grid`.

	ОТБИВКА СВЕРХУ СНЯТА (2026-08-21) по той же причине, что у характеристик:
	«с этим товаром берут» — отдельный БЛОК страницы, и расстояние до соседа
	задает его собственный `--st-pad-y`. Прежние 28 px складывались с ним
	и давали над рядом двойную паузу
*/
.st-site .st-related {
	margin-top: 0;
}

/* ==== НАЛИЧИЕ НА СТРАНИЦЕ ТОВАРА (2026-08-18) ======================== */
/*
	СТРОКА ПОД ЦЕНОЙ, а не бейдж на фотографии: на странице товара наличие —
	часть ответа «брать или искать дальше», и читать его нужно вместе
	с ценой, а не искать глазами по кадру.

	ЦВЕТА ЗАШИТЫ, А НЕ ВЗЯТЫ У ТЕМЫ (тот же довод, что у плашки «Выгода»):
	акцент витрины бывает любым, вплоть до красного, а «есть / привезем /
	нет» обязаны читаться одинаково на всех сайтах
*/
.st-site .st-pdp__stock {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-top: 8px;
	font-size: 14px;
	font-weight: 600;
}

.st-site .st-pdp__stock--ok { color: #47BE7D; }
.st-site .st-pdp__stock--wait { color: #F1BC00; }
.st-site .st-pdp__stock--off { color: var(--st-danger); }

/* Место кнопки «В корзину» у товара, которого нет. Не выключенная кнопка,
   а текст: выключенная кнопка все равно обещает покупку */
.st-site .st-pdp__out {
	display: inline-flex;
	align-items: center;
	padding: 11px 18px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius-sm, 10px);
	color: var(--st-muted);
	font-size: 15px;
	font-weight: 600;
}

/* ==== БЫСТРЫЙ ЗАКАЗ (2026-08-19) ===================================== */
/*
	КНОПКА ВТОРОСТЕПЕННАЯ ПО ВИДУ, и это осознанно: основной путь — корзина
	(там видно сумму, доставку и оформление), а «в один клик» — короткая
	дорога для того, кто уже решил. Сделай ее такой же яркой — и покупатель
	начнет заказывать по телефону то, что мог бы оформить сам
*/
.st-site .st-quick {
	margin-top: 12px;
}

.st-site .st-quick__open {
	padding: 0;
	border: 0;
	background: none;
	color: var(--st-accent);
	font-family: inherit;
	font-size: 15px;
	font-weight: 600;
	text-decoration: underline;
	cursor: pointer;
}

.st-site .st-quick__form {
	margin-top: 10px;
	padding: 14px;
	border: 1px dashed var(--st-border);
	border-radius: var(--st-radius-sm, 10px);
	background-color: var(--st-surface);
}

.st-site .st-quick__note {
	margin-bottom: 10px;
	color: var(--st-muted);
	font-size: 13px;
}

.st-site .st-quick__row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
}

.st-site .st-quick__row .st-field__input {
	flex: 1 1 200px;
	min-width: 0;
}

.st-site .st-quick__consent {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	margin-top: 10px;
	color: var(--st-muted);
	font-size: 12px;
	line-height: 1.4;
}

.st-site .st-quick__msg:empty {
	display: none;
}

.st-site .st-quick__msg {
	margin-top: 10px;
	color: var(--st-accent);
	font-size: 13px;
	font-weight: 600;
}

/* Ошибка — своим цветом: «не отправилось» и «отправлено» обязаны
   отличаться не только словами */
.st-site .st-quick__msg--bad {
	color: var(--st-danger);
}

/* ======================================================================= */
/* ==== НАСТРАИВАЕМЫЕ ЧАСТИ СТРАНИЦЫ ТОВАРА (2026-08-20) ================= */
/* ======================================================================= */
/*
	ЧТО ЗДЕСЬ ПОЯВИЛОСЬ И ПОЧЕМУ. Правила выше переехали из `stsite.css`
	КАК ЕСТЬ — страница обязана выглядеть ровно так же, как до переезда.
	А ниже лежит то, чего раньше быть не могло: у каждой части карточки
	появились СВОИ настройки, и им нужны классы-модификаторы.

	ДВУХКОЛОНОЧНОЙ СЕТКИ `.st-pdp` БОЛЬШЕ НЕТ. Раньше «фотография слева,
	покупка справа» задавалась ею; теперь это ОБЫЧНЫЕ КООРДИНАТЫ блоков
	на 12-колоночной сетке страницы, и меняет их владелец мышью. Старое
	правило оставлено нетронутым: оно больше ни на что не действует,
	но и не мешает
*/

/* ФОРМУ ОБЛОЖКИ ЗАДАЕТ ПЕРЕМЕННАЯ, А НЕ КЛАСС НА КАЖДОЕ СООТНОШЕНИЕ:
   значений четыре сейчас и будет больше, а правило нужно ровно одно */
.st-site .st-pdp__cover[style*="--st-pdp-ratio"] {
	aspect-ratio: var(--st-pdp-ratio);
}

.st-site .st-pdp__cover[style*="--st-pdp-ratio"] .st-pdp__image {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

/* Миниатюры столбиком слева — обложка и лента меняются местами.
   `grid`, а не `flex`: ширина ленты фиксирована, а обложка забирает
   остаток, и в flex это потребовало бы `min-width: 0` на обоих */
.st-site .st-pdp__media--th-left {
	display: grid;
	grid-template-columns: 76px minmax(0, 1fr);
	gap: 12px;
	align-items: start;
}

.st-site .st-pdp__media--th-left .st-pdp__cover {
	order: 2;
}

.st-site .st-pdp__media--th-left .st-pdp__thumbs {
	order: 1;
	flex-direction: column;
}

/* ==== СЛАЙДЕР ГАЛЕРЕИ — SWIPER (переделано 2026-08-21) ====

   БЫЛО: лента `scroll-snap`, которую листал сам браузер, и довод «второй
   экземпляр Swiper ради четырех кадров тянуть незачем». Довод не выдержал
   проверки: плагин на странице УЖЕ ЕСТЬ (блок «Медиа», витрина товаров),
   а у ленты не было ни стрелок, ни точек — на десктопе кадры листались
   только колесом с зажатым Shift.

   ОФОРМЛЕНИЕ КОНТРОЛОВ БЕРЕТСЯ ГОТОВОЕ: разметка несет те же классы
   `st-slider--*`, что и слайдер медиа-блока, и правила для них объявлены
   выше по файлу. Здесь — только то, что специфично для обложки товара:
   слайд обязан отдать высоту кадру, а не тянуться под самый высокий */
.st-site .st-pdp__media--slider .swiper {
	width: 100%;
}

.st-site .st-pdp__media--slider .swiper-slide {
	height: auto;
}

/* Обложка внутри слайда занимает его целиком: пропорцию задает
   переменная на самом слайдере, и второй источник высоты тут лишний */
.st-site .st-pdp__media--slider .st-pdp__cover {
	display: block;
	width: 100%;
	margin: 0;
}

/* Лента миниатюр в этом виде не нужна — кадры и есть слайды. Правило
   печатается, а не убирается из разметки: вид переключается настройкой,
   и вторая ветка шаблона ради этого не нужна */
.st-site .st-pdp__media--slider .st-pdp__thumbs {
	display: none;
}

/* Выравнивание названия и его размер — три ступени, как у прочих блоков */
.st-site .st-pdp__info--al-center {
	text-align: center;
}

.st-site .st-pdp__info--al-center .st-pdp__badges,
.st-site .st-pdp__info--al-center .st-pdp__props,
.st-site .st-pdp__info--al-center .st-pdp__links,
.st-site .st-pdp__info--al-center .st-pdp__buy {
	justify-content: center;
}

.st-site .st-pdp__title--sm { font-size: 24px; }
.st-site .st-pdp__title--lg { font-size: 38px; }

.st-site .st-pdp__price--sm { font-size: 24px; }
.st-site .st-pdp__price--lg { font-size: 38px; }

/* ЧИСЛО КОЛОНОК СВОДКИ — ПЕРЕМЕННОЙ. На телефоне оно принудительно
   становится одним: две колонки дают меньше половины строки на значение,
   и подпись «Стойкость к влаге» переносилась бы трижды (правило было
   и раньше, здесь оно только получило источник) */
.st-site .st-pdp__props {
	grid-template-columns: repeat(var(--st-pdp-props, 2), minmax(0, 1fr));
}

/* Свойства строками: значок, подпись и значение в одну линию —
   когда владельцу важнее компактность, чем акцент на цифре */
.st-site .st-pdp__props--rows {
	grid-template-columns: minmax(0, 1fr);
	gap: 0;
}

.st-site .st-pdp__props--rows .st-pdp__prop {
	padding: 9px 0;
	border-bottom: 1px dashed var(--st-border);
}

.st-site .st-pdp__props--rows .st-pdp__prop:last-child {
	border-bottom: 0;
}

/* Плашка упаковки без акцента — та же коробка нейтральным тоном */
.st-site .st-pdp__pack--plain {
	border-color: var(--st-border);
	background-color: transparent;
}

/* Приглушенный вариант плашки. Селекторы от тега — иначе правило
   выше (тоже от тега) его перебило бы */
.st-site .st-pdp__pack--plain i.st-pdp__pack-icon,
.st-site .st-pdp__pack--plain img.st-pdp__pack-icon,
.st-site .st-pdp__pack--plain span.st-pdp__pack-icon {
	color: var(--st-text-soft);
}

/* Характеристики одним списком: группы идут друг под другом во всю
   ширину — для узкого блока, где трем карточкам не хватает места */
.st-site .st-specs__grid--rows {
	grid-template-columns: minmax(0, 1fr);
}

/* Описание без рамки — только текст */
.st-site .st-pdp__desc--plain {
	border: 0;
	padding: 0;
	background: transparent;
}

/*
	СКЛАДЫВАНИЕ ОПИСАНИЯ НА ШТАТНОМ `details`.

	ЗАКРЫТОЕ СОСТОЯНИЕ ПОКАЗЫВАЕТ ЧАСТЬ ТЕКСТА, А НЕ ПРЯЧЕТ ВЕСЬ:
	кнопка «Читать целиком» под пустотой не объясняет, что там читать.
	Поэтому высота ограничена, а низ растворяется градиентом.
	`summary` вынесен ВНИЗ и лишен маркера — он здесь кнопка, а не
	заголовок раздела
*/
.st-site .st-pdp__more > div:first-child {
	max-height: 220px;
	overflow: hidden;
	-webkit-mask-image: linear-gradient(to bottom, #000 60%, transparent 100%);
	mask-image: linear-gradient(to bottom, #000 60%, transparent 100%);
}

.st-site .st-pdp__more[open] > div:first-child {
	max-height: none;
	-webkit-mask-image: none;
	mask-image: none;
}

.st-site .st-pdp__more-btn {
	display: inline-block;
	margin-top: 10px;
	color: var(--st-accent);
	font-weight: 600;
	cursor: pointer;
	list-style: none;
}

.st-site .st-pdp__more-btn::-webkit-details-marker {
	display: none;
}

/* Отзывы сеткой в две колонки — для широкого блока */
.st-site .st-reviews__list--grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
	gap: 14px;
}

/* ======================================================================= */
/* ==== СТРАНИЦА ПРОФИЛЯ УЧАСТНИКА (2026-08-20) ========================== */
/* ======================================================================= */

.st-site .st-mbr-card {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 18px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
}

.st-site .st-mbr-card--al-center {
	flex-direction: column;
	text-align: center;
}

.st-site .st-mbr-card__ava {
	flex-shrink: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 64px;
	height: 64px;
	overflow: hidden;
	border-radius: 50%;
	background-color: var(--st-surface-alt);
}

.st-site .st-mbr-card__ava img {
	width: 100%;
	height: 100%;
	object-fit: cover;
}

.st-site .st-mbr-card__letter {
	color: var(--st-text-soft);
	font-size: 26px;
	font-weight: 700;
}

.st-site .st-mbr-card__body {
	min-width: 0;
}

.st-site .st-mbr-card__name {
	color: var(--st-text);
	font-size: 20px;
	font-weight: 700;
	line-height: 1.25;
}

.st-site .st-mbr-card__meta {
	margin-top: 3px;
	color: var(--st-text-soft);
	font-size: 14px;
}

.st-site .st-mbr-card__links {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 12px;
}

.st-site .st-mbr-orders {
	display: flex;
	flex-direction: column;
	gap: 12px;
}

.st-site .st-mbr-order {
	padding: 14px 16px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius);
	background-color: var(--st-surface);
}

.st-site .st-mbr-order__head {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
}

.st-site .st-mbr-order__num {
	color: var(--st-text);
	font-weight: 700;
}

.st-site .st-mbr-order__date {
	color: var(--st-text-soft);
	font-size: 13px;
}

/*
	СТАТУС — ЦВЕТОМ ТЕМЫ, А НЕ СВОЕЙ ПАЛИТРОЙ. Ключи цветов приходят
	из общего справочника заказов сервиса (order_statuses.color),
	и раскрашивает их тема САЙТА через color-mix: второй набор цветов
	статусов разошелся бы с кабинетом владельца
*/
.st-site .st-mbr-order__status {
	margin-left: auto;
	padding: 2px 9px;
	border-radius: 999px;
	font-size: 12px;
	font-weight: 600;
	background-color: color-mix(in srgb, var(--st-accent) 12%, transparent);
	color: var(--st-accent);
}

.st-site .st-mbr-order__status--success {
	background-color: color-mix(in srgb, #47BE7D 14%, transparent);
	color: #47BE7D;
}

.st-site .st-mbr-order__status--warning {
	background-color: color-mix(in srgb, #F1BC00 16%, transparent);
	color: #F1BC00;
}

.st-site .st-mbr-order__status--danger {
	background-color: color-mix(in srgb, var(--st-danger) 14%, transparent);
	color: var(--st-danger);
}

.st-site .st-mbr-order__items {
	margin-top: 10px;
	padding-top: 10px;
	border-top: 1px dashed var(--st-border);
}

.st-site .st-mbr-order__item {
	display: flex;
	justify-content: space-between;
	gap: 12px;
	padding: 4px 0;
	color: var(--st-text-soft);
	font-size: 14px;
}

.st-site .st-mbr-order__foot {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 10px;
}

.st-site .st-mbr-order__sum {
	color: var(--st-text);
	font-size: 17px;
	font-weight: 700;
}

.st-site .st-mbr-order__track {
	color: var(--st-text-soft);
	font-size: 13px;
}

.st-site .st-mbr-data__note {
	margin-top: 14px;
	color: var(--st-text-soft);
	font-size: 14px;
	line-height: 1.5;
}

.st-site .st-mbr-data__acts {
	margin-top: 16px;
}

/* ВЫХОД — ССЫЛКА С ВИДОМ ВТОРОСТЕПЕННОЙ КНОПКИ: действие обратимое
   (войти можно снова), и красной кнопки оно не заслуживает */
.st-site .st-mbr-data__out {
	display: inline-flex;
	align-items: center;
	padding: 9px 18px;
	border: 1px solid var(--st-border);
	border-radius: 999px;
	color: var(--st-text-soft);
	font-weight: 600;
	text-decoration: none;
}

.st-site .st-mbr-data__out:hover {
	border-color: var(--st-danger);
	color: var(--st-danger);
}

/*
	МОДАЛЬНОЕ ОКНО ПРОФИЛЯ ПОКАЗЫВАЕТ ЦЕЛУЮ СТРАНИЦУ, поэтому коробка
	у него шире обычной панели и со своей прокруткой: содержимое задает
	владелец, и оно может быть любой высоты.

	==== ШИРИНА ПОДНЯТА ДО 960 px (2026-08-21) ====

	Вместе с переходом окна на НАСТОЯЩУЮ раскладку (`websitePublicArea`
	вместо ленты) у содержимого появились КОЛОНКИ, и прежние 720 px
	давали им по трети экрана телефона на каждую. 960 — та же величина,
	на которой сетка сайта еще держит две-три колонки, а `92vw` рядом
	по-прежнему не дает окну вылезти за узкий экран
*/
.st-site .st-member__card--page {
	position: relative;
	width: min(960px, 92vw);
	max-height: 82vh;
	overflow-y: auto;
	padding: 22px;
}

.st-site .st-member__card--page .st-block {
	padding-left: 0;
	padding-right: 0;
}

/*
	СЕТКА ВНУТРИ ОКНА СЧИТАЕТ КОЛОНКИ ОТ КОРОБКИ, А НЕ ОТ ЭКРАНА, —
	иначе двенадцать колонок раскладывались бы по ширине окна браузера
	и блок «на треть» вылезал бы за край. `container-type: inline-size`
	тут не нужен: дорожки заданы долями (`fr`), и им достаточно того,
	что родитель знает свою ширину
*/
.st-site .st-member__card--page .st-page {
	width: 100%;
	min-width: 0;
}

/* ЛЕНТА БЕЗ 2D-СЕТКИ. Класс каталожных страниц: у бренда и подборки
   нет ни колонок, ни уровней — координаты им задавать нечем.
   МОДАЛКА ПРОФИЛЯ ИМ БОЛЬШЕ НЕ ПОЛЬЗУЕТСЯ (2026-08-21): там координаты
   есть, и выбрасывать их было ошибкой */
.st-site .st-page--flat {
	display: block;
}

/*
	==== ПОМЕТКА «ЭТО ОБРАЗЕЦ» (только конструктор) ====

	Печатается ТОЛЬКО при $editor — на сайте ее нет ни в одном байте.
	Оформлена нарочито служебно (пунктир, приглушенный тон): это подпись
	редактора, а не элемент витрины, и спутать их владелец не должен
*/
.st-site .st-sysnote {
	display: flex;
	align-items: flex-start;
	gap: 8px;
	margin-bottom: 12px;
	padding: 8px 12px;
	border: 1px dashed var(--st-border);
	border-radius: 8px;
	color: var(--st-text-soft);
	font-size: 13px;
	line-height: 1.4;
}

.st-site .st-sysnote i {
	flex-shrink: 0;
	margin-top: 1px;
	color: var(--st-accent);
}

@media (max-width: 575.98px) {
	/* НА ТЕЛЕФОНЕ СВОДКА ВСЕГДА В ОДНУ КОЛОНКУ, чего бы ни выбрал
	   владелец: двум там не хватает ширины на подпись */
	.st-site .st-pdp__props {
		grid-template-columns: minmax(0, 1fr);
	}

	.st-site .st-pdp__media--th-left {
		grid-template-columns: minmax(0, 1fr);
	}

	.st-site .st-pdp__media--th-left .st-pdp__thumbs {
		flex-direction: row;
	}
}

/*
	==== ЗНАЧОК НАСЛЕДУЕТ ЦВЕТ СТРОКИ (2026-08-21) ====

	НА САЙТЕ ЭТО РАБОТАЛО, В КОНСТРУКТОРЕ — НЕТ, и разница не в стилях
	сайта, а в соседстве: холст живет внутри интерфейса сервиса, где
	иконочный шрифт Metronic задает элементу `i` СВОЙ цвет. Наследование
	от строки при этом не срабатывает — та же болезнь, что у бейджей
	и кнопок списков в `steditor.css`.

	ПОЭТОМУ ПРАВИЛО СТОИТ ЗДЕСЬ, А НЕ В `steditor.css`: значок должен
	наследовать цвет ВЕЗДЕ, где рисуется блок, — и на витрине, и на холсте.
	Перечислены места, где цвет строки ЗНАЧИМ (наличие, бейдж свойства,
	ссылки бренда, оптовые пороги): там серый значок читается как ошибка
	данных, а не как оформление.

	ПЛАШКИ УПАКОВКИ ЗДЕСЬ НЕТ НАМЕРЕННО: у ее значка цвет СВОЙ
	(`--st-accent`), и `inherit` ниже по файлу молча его отменил бы —
	правила одинакового веса решает порядок
*/
.st-site .st-pdp__stock i,
.st-site .st-badge i,
.st-site .st-chip i,
.st-site .st-tiers__item i {
	color: inherit;
}

/*
	==== ПРИГЛАШЕНИЕ К ПРИМЕРКЕ ЛАМИНАТА (2026-08-22) ====

	ЭТО ТОЛЬКО КАРТОЧКА С КНОПКОЙ: сама примерка живет в окне поверх
	страницы, у нее свой бандл и свой префикс (`stt-*`). Здесь ровно то,
	что покупатель видит ДО клика.

	ОФОРМЛЕНИЕ ВЗЯТО У ПЛАШКИ УПАКОВКИ (`st-pdp__pack`) НАМЕРЕННО:
	обе — приглашения, а не данные товара, и на странице их должно
	читаться как один вид элемента. Разъехавшись, они добавили бы
	карточке третий тип коробки без единой новой мысли
*/
.st-site .st-tryon {
	display: flex;
	align-items: center;
	gap: 16px;
	padding: 16px 18px;
	border: 1px dashed var(--st-accent);
	border-radius: var(--st-radius);
	background-color: color-mix(in srgb, var(--st-accent) 8%, transparent);
}

/* Владелец выключил акцент — остается обычная рамка темы */
.st-site .st-tryon--flat {
	border-style: solid;
	border-color: var(--st-border);
	background-color: transparent;
}

/* Вид «только кнопка»: коробки нет вовсе, кнопка встает в поток */
.st-site .st-tryon--plain {
	display: block;
	padding: 0;
	border: 0;
	background: none;
}

/*
	ЦВЕТ ЗНАЧКА СТАВИТСЯ ОТ ТЕГА, А НЕ ОТ ОДНОГО КЛАССА (2026-08-22).

	ТА ЖЕ ЛОВУШКА, ЧТО У МИНИ-ПАНЕЛИ БЛОКА (см. пояснение в steditor.css):
	вокруг холста живет интерфейс сервиса, где иконочный шрифт Metronic
	задает элементу `i` СВОЙ цвет — специфичность (0,1,1) выше, чем
	у одиночного класса (0,1,0), и значок оставался белым, хотя рамка
	карточки честно красилась акцентом.

	Три селектора, потому что значок бывает трех видов: глиф `<i>`,
	свой SVG (`<img>`) и анимация Lottie (`<span>`) — их выбирает
	владелец, и цвет обязан достаться любому
*/
.st-site i.st-tryon__icon,
.st-site img.st-tryon__icon,
.st-site span.st-tryon__icon {
	flex-shrink: 0;
	font-size: 32px;
	line-height: 1;
	color: var(--st-accent);
}

.st-site .st-tryon__body {
	flex: 1 1 auto;
	min-width: 0;
}

.st-site .st-tryon__title {
	font-size: 15px;
	font-weight: 700;
	color: var(--st-text);
}

.st-site .st-tryon__text {
	margin-top: 2px;
	font-size: 13px;
	color: var(--st-text-base);
}

.st-site .st-tryon__btn {
	flex-shrink: 0;
}

/* Значок В КНОПКЕ наследует ее цвет — в отличие от значка карточки
   выше: там он несущий, здесь он часть подписи */
.st-site .st-tryon .st-tryon__btn-icon {
	color: inherit;
}

/*
	НА ТЕЛЕФОНЕ КАРТОЧКА РАСКЛАДЫВАЕТСЯ СТОЛБИКОМ, а кнопка растягивается
	на всю ширину: в ряд со значком и двумя строками текста она сжимается
	до нечитаемой, а нажимают на этой странице именно ее
*/
@media (max-width: 575.98px) {
	.st-site .st-tryon {
		flex-wrap: wrap;
	}

	.st-site .st-tryon__btn {
		width: 100%;
		justify-content: center;
	}
}
