/*
	=========================================================================
	==== ПУБЛИЧНАЯ СТРАНИЦА САЙТА КЛИЕНТА: ОБВЯЗКА ДОКУМЕНТА ================
	(2026-08-13)
	=========================================================================

	ГРАНИЦА С `stheme.css` СТРОГАЯ, И ЕЕ НЕЛЬЗЯ РАЗМЫВАТЬ:

	  stheme.css — СТИЛИ САМОГО САЙТА. Всё, что владелец собрал блоками:
	               сетка, секции, карточки, типографика, темы. Один и тот же
	               файл работает и в конструкторе, и здесь;

	  stsite.css — ТО, ЧЕГО В КОНСТРУКТОРЕ НЕТ ВОВСЕ: сам документ, полоса
	               предпросмотра владельца, переключатель день/ночь,
	               выдача живого поиска и заглушка 404.

	Правило простое: появилось у блока — значит в stheme.css. Появилось
	у СТРАНИЦЫ как у документа — значит сюда.

	ПРЕФИКС ОДИН — `st-`, переменные только `--st-*`. Ни одного класса
	Metronic здесь нет и быть не может: бандл сервиса на публичную
	страницу не подключается вовсе
*/

html {
	/* Плавная прокрутка нужна якорям меню. Просьбу уменьшить движение
	   уважаем безусловно — правило ниже */
	scroll-behavior: smooth;
	-webkit-text-size-adjust: 100%;
	/*
		ЯКОРЬ НЕ ПРЯЧЕТСЯ ПОД ЗАКРЕПЛЕННОЙ ПОЛОСОЙ (2026-08-17).

		Полоса предпросмотра стала `sticky` и висит у верхнего края.
		Без этой строки переход по якорю меню ставил бы начало секции
		РОВНО ПОД нее — заголовок оказывался бы срезан, и владелец решил бы,
		что прокрутка промахивается.

		Нет полосы — переменной нет, запас нулевой, поведение прежнее
	*/
	scroll-padding-top: var(--st-bar-h, 0px);
}

body.st-body {
	margin: 0;
	padding: 0;
	min-height: 100vh;
}

/* Корень сайта занимает экран целиком: короткая страница не должна
   заканчиваться полосой фона документа посреди экрана */
.st-site--live {
	min-height: 100vh;
}

/* ==== ПОЛОСА ПРЕДПРОСМОТРА ВЛАДЕЛЬЦА ==================================== */
/*
	ПОКАЗЫВАЕТСЯ ТОЛЬКО ВЛАДЕЛЬЦУ и только когда сайт или страница
	посетителю НЕ видны. Молча показать владельцу рабочий сайт значило бы
	соврать: на этом же адресе посторонний получает 404.

	ЦВЕТА СВОИ, А НЕ ТЕМЫ САЙТА, и это осознанно: полоса — сообщение
	СЕРВИСА, и сливаться с оформлением витрины она не должна.

	==== КНОПКА ПАЛИТРЫ УХОДИТ ПОД ПОЛОСУ (исправлено 2026-08-15) ====

	ЧТО НЕ СРАБОТАЛО. Сначала полосе сделали тоньше и зарезервировали
	справа место под кнопку — но кнопка закреплена за ОКНОМ (`position:
	fixed; top: 16px`), а не за содержимым, и она ложилась НА ПОЛОСУ
	независимо от ее отступов. Резерв помогал только тексту.

	ЧТО РАБОТАЕТ. Кнопка начинается НИЖЕ полосы: ее отступ считается
	от переменной `--st-bar-h`, куда `initPreviewBar()` (stsite.js) кладет
	ФАКТИЧЕСКУЮ высоту полосы — та зависит от длины текста и ширины экрана,
	и зашить ее числом нельзя. Нет полосы — переменной нет, и отступ
	обнуляется.

	Резерв справа поэтому снят: полоса снова использует всю ширину.

	==== ПОЛОСА ЗАКРЕПЛЕНА У ВЕРХНЕГО КРАЯ (2026-08-17) ====

	ЧТО БЫЛО ВИДНО: стоило прокрутить страницу, полоса уезжала вверх —
	а кнопка палитры оставалась со своим отступом, и в правом верхнем углу
	зияла пустая полоса высотой с уехавшее сообщение.

	ПРИЧИНА В РАССОГЛАСОВАНИИ: кнопка закреплена за ОКНОМ (`fixed`),
	а полоса ехала вместе с содержимым (`relative`). Отступ, взятый
	от высоты полосы, верен только пока полоса на экране.

	ЛЕЧЕНИЕ — `sticky`, А НЕ `fixed`, и это важно. `fixed` вынул бы полосу
	из потока, и странице потребовался бы отступ сверху ровно в ее высоту;
	высота динамическая (текст переносится), значит отступ пришлось бы
	ставить скриптом — то есть при загрузке содержимое на кадр-другой
	подлезало бы под полосу. `sticky` оставляет полосу В ПОТОКЕ: место она
	занимает сама, резервировать нечего, а при прокрутке прилипает
	к верхнему краю. Отступ кнопки становится верным на ЛЮБОЙ прокрутке.

	СООБЩЕНИЕ ВИДНО ВСЕГДА, и это не побочный эффект, а польза: владелец,
	забывший опубликовать сайт, узнает об этом не только на первом экране
*/
.st-preview-bar {
	position: sticky;
	top: 0;
	z-index: 60;
	display: flex;
	align-items: center;
	justify-content: center;
	flex-wrap: wrap;
	gap: 4px 12px;
	padding: 6px 16px;
	background-color: #FFF4D6;
	color: #6B4E00;
	font-family: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
	font-size: 13px;
	line-height: 1.35;
	text-align: center;
}

.st-preview-bar__icon {
	font-size: 16px;
	color: #B98900;
}

@media (max-width: 575.98px) {
	.st-preview-bar {
		padding: 6px 12px;
		font-size: 12px;
	}
}

.st-preview-bar__link {
	color: #6B4E00;
	font-weight: 700;
	text-decoration: underline;
	white-space: nowrap;
}

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

	Сайт грузит страницы сам (`initNav` в stsite.js), и у посетителя
	пропал привычный признак работы — индикатор вкладки браузера. Без
	замены он жмет ссылку второй раз, считая, что не попал.

	ПОЛОСА НЕ ПОКАЗЫВАЕТ ПРОГРЕСС, А ПОКАЗЫВАЕТ ЗАНЯТОСТЬ: сколько
	осталось, мы не знаем (ответ приходит целиком), и врущая шкала хуже
	честного движения.

	ЦВЕТ — АКЦЕНТ ТЕМЫ САЙТА: это часть витрины, а не сообщение сервиса
	(в отличие от полосы предпросмотра выше). Узел лежит ВНЕ корня сайта
	и переживает подмену содержимого, поэтому переменную берет
	у документа с запасным значением
*/
.st-navbar {
	position: fixed;
	top: 0;
	left: 0;
	right: 0;
	height: 3px;
	z-index: 2000;
	opacity: 0;
	transition: opacity 0.2s ease;
	pointer-events: none;
	background: linear-gradient(
		90deg,
		transparent,
		var(--st-accent, #2E6BFF),
		transparent
	);
	background-size: 40% 100%;
	background-repeat: no-repeat;
}

.st-navbar--on {
	opacity: 1;
	animation: stNavSlide 1s linear infinite;
}

@keyframes stNavSlide {
	from { background-position: -40% 0; }
	to { background-position: 140% 0; }
}

/* Просьба «без движения» гасит бег полосы, но не саму полосу: признак
   занятости нужен и здесь */
@media (prefers-reduced-motion: reduce) {
	.st-navbar--on {
		animation: none;
		background-size: 100% 100%;
	}
}

/* ==== ПЕРЕКЛЮЧАТЕЛЬ ДЕНЬ/НОЧЬ ========================================== */
/*
	КНОПКИ НЕТ В РАЗМЕТКЕ САЙТА: ее создает stsite.js и только тогда, когда
	владелец оставил посетителю ОБА режима. Кнопка с одним положением —
	ложное обещание, а разметка, которую прячут стилями, все равно уезжает
	посетителю.

	==== КНОПКА ЖИВЕТ В `<body>`, А НЕ В КОРНЕ САЙТА ====
	(окончательное лечение «убежала в нижний левый угол», 2026-08-16)

	ПЕРВЫЙ ДИАГНОЗ БЫЛ НЕВЕРНЫМ, и его стоит помнить, чтобы не поставить
	снова: считалось, что виноват недействительный `calc()` в `top`
	(`--st-bar-h` могла принять нечисловой замер, и тогда `top`
	сбрасывается в `auto`, то есть в статическое место). Замер починили,
	`calc()` убрали — кнопка осталась в углу.

	НАСТОЯЩАЯ ПРИЧИНА: `position: fixed` отсчитывается НЕ ОТ ОКНА, если
	у ЛЮБОГО предка есть `transform`, `filter`, `backdrop-filter`,
	`perspective`, `will-change` этих свойств или `contain`. Кнопка лежала
	внутри `#stSite` — под слоями фона, анимациями появления и эффектами
	блоков, — и первый же такой предок молча становился ее системой
	координат.

	ЭТО НЕВОЗМОЖНО ПОЧИНИТЬ ПРАВИЛОМ CSS: containing block выбирает
	ПРЕДОК, а не сам элемент. Единственное настоящее лечение — вынести
	узел из-под предков сайта, что и сделано (`document.body.appendChild`
	в stsite.js). Поэтому здесь больше НЕТ корня `.st-site` в селекторе:
	кнопка ему больше не принадлежит.

	ЦВЕТА НЕ ПОТЕРЯЛИСЬ: `i_site` объявляет палитру еще и на
	`html[data-st-mode="…"]` (без слоев фона), и переменные `--st-*`
	доходят сюда наследованием — тот же прием, что у полосы загрузки.

	СМЕЩЕНИЕ ПОД ПОЛОСУ ПРЕДПРОСМОТРА ДАЕТ `margin-top`, А НЕ `calc()`
	в `top`: отвалится переменная — кнопка останется в углу и в худшем
	случае наедет на полосу, а не уедет вниз страницы.

	`left`/`bottom` заданы ЯВНО: неуказанная сторона у фиксированного
	элемента — это снова «статическое место», и полагаться на умолчание
	здесь нельзя
*/
.st-mode {
	position: fixed;
	top: 16px;
	right: 16px;
	bottom: auto;
	left: auto;
	/* Высоту полосы предпросмотра (если она есть) кладет `initPreviewBar()`
	   в stsite.js — см. пояснение у `.st-preview-bar` */
	margin-top: var(--st-bar-h, 0px);
	z-index: 45;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	padding: 0;
	border: 1px solid var(--st-border);
	border-radius: 999px;
	background-color: var(--st-surface);
	color: var(--st-text);
	/* ШРИФТ ЗАДАН ЯВНО: кнопка уехала из-под `.st-site`, а вместе с ним
	   и из-под сброса `:where(.st-site) button { font: inherit }`.
	   Без этой строки браузер поставил бы ей свой системный шрифт */
	font-family: var(--st-font, 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif);
	font-size: 18px;
	line-height: 1;
	cursor: pointer;
	box-shadow: var(--st-shadow, 0 6px 24px rgba(24, 32, 48, 0.08));
	transition: transform 0.15s ease, background-color 0.15s ease;
}

.st-mode:hover {
	transform: scale(1.06);
	background-color: var(--st-surface-alt);
}

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

/*
	==== ЦВЕТ ЗНАЧКА — ПО САМОМУ ЗНАЧКУ (исправлено 2026-08-15) ====

	СОЛНЦЕ ЖЁЛТОЕ, МЕСЯЦ СИНИЙ. Правило простое до очевидности, и потому
	единственно верное: жёлтый месяц и синее солнце читаются как ошибка
	отрисовки, сколько бы смысла ни вкладывалось в «цвет текущей палитры».

	КАКОЙ ЗНАЧОК В КАКОЙ ПАЛИТРЕ — РЕШАЕТ `paint()` В stsite.js, И ОН
	ПОКАЗЫВАЕТ ДЕЙСТВИЕ, А НЕ СОСТОЯНИЕ: в ТЁМНОЙ палитре нарисовано
	СОЛНЦЕ («включить светлую»), в СВЕТЛОЙ — МЕСЯЦ. Отсюда и селекторы:
	`[data-st-mode="dark"]` красит солнце, `[data-st-mode="light"]` — месяц.
	**Поменяется набор значков в `paint()` — поменять и здесь.**

	Красится ТОЛЬКО значок: подложка кнопки остается поверхностью темы,
	иначе кнопка превратилась бы в цветное пятно поверх витрины.

	Значения зашиты, а не взяты из темы: акцент витрины бывает любым,
	вплоть до совпадения с фоном кнопки, а этот цвет обязан работать
	на всех сайтах одинаково
*/
html[data-st-mode="dark"] .st-mode i {
	color: #F5A623;
}

html[data-st-mode="light"] .st-mode i {
	color: #6E9BFF;
}

/*
	==== СМЕНА ПАЛИТРЫ: СВЕТ РАСХОДИТСЯ ИЗ КНОПКИ И ВТЯГИВАЕТСЯ В НЕЁ ====
	(2026-08-15)

	ОСНОВНОЙ ПУТЬ — View Transitions API: браузер сам делает снимок старого
	состояния, а мы анимируем КРУГ отсечения у нового или у старого слоя.
	Радиус и центр приходят переменными от `stsite.js` — он один знает,
	где физически стоит кнопка.

	НАПРАВЛЕНИЕ РАЗНОЕ, И ЭТО СМЫСЛ ЭФФЕКТА:
	  ВКЛЮЧИЛИ СВЕТЛУЮ — круг РАСТЁТ у НОВОГО слоя: свет расходится
	    от кнопки и перекрашивает страницу;
	  ВКЛЮЧИЛИ ТЁМНУЮ — круг СЖИМАЕТСЯ у СТАРОГО слоя: свет втягивается
	    обратно в кнопку. Растить темноту поверх света значило бы
	    показать ровно тот же жест в обе стороны.

	СНИМКИ НЕ СМЕШИВАЮТСЯ: штатное перекрестное затухание отключено,
	иначе поверх круга шло бы еще и полупрозрачное наложение — и граница
	света размылась бы в грязь
*/
::view-transition-old(root),
::view-transition-new(root) {
	animation: none;
	mix-blend-mode: normal;
}

/*
	==== `both` У ЗАПОЛНЕНИЯ — НЕ УКРАШЕНИЕ, А ЛЕЧЕНИЕ ВСПЫШКИ ====
	(исправлено 2026-08-15)

	ЧТО БЫЛО ВИДНО: переключение в ТЁМНУЮ давало яркое моргание всего
	экрана В САМОМ КОНЦЕ анимации; обратное направление шло чисто.

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

	`both` удерживает и первый кадр, и последний
*/
html[data-st-anim="light"]::view-transition-old(root) {
	z-index: 1;
}

html[data-st-anim="light"]::view-transition-new(root) {
	z-index: 2;
	animation: st-mode-in 0.5s ease-out both;
}

html[data-st-anim="dark"]::view-transition-old(root) {
	z-index: 2;
	animation: st-mode-out 0.5s ease-in both;
}

html[data-st-anim="dark"]::view-transition-new(root) {
	z-index: 1;
}

@keyframes st-mode-in {
	from { clip-path: circle(0 at var(--st-mode-x, 50%) var(--st-mode-y, 50%)); }
	to { clip-path: circle(var(--st-mode-r, 150%) at var(--st-mode-x, 50%) var(--st-mode-y, 50%)); }
}

@keyframes st-mode-out {
	from { clip-path: circle(var(--st-mode-r, 150%) at var(--st-mode-x, 50%) var(--st-mode-y, 50%)); }
	to { clip-path: circle(0 at var(--st-mode-x, 50%) var(--st-mode-y, 50%)); }
}

/*
	ФОЛБЭК ДЛЯ БРАУЗЕРОВ БЕЗ View Transitions — МЯГКОЕ ЗАТУХАНИЕ.

	Круг отсечения без снимка старого состояния не построить: обрезать
	было бы нечего. Поэтому запасной вариант другой по природе — общий
	короткий переход цвета. Класс ставит скрипт и снимает его по таймеру:
	держать переход на корне постоянно нельзя, он тормозил бы наведение
	на каждый элемент страницы
*/
.st-site--fading,
.st-site--fading * {
	transition: background-color 0.35s ease, color 0.35s ease,
		border-color 0.35s ease, fill 0.35s ease !important;
}

/* Системная просьба «без движения» старше любой красоты: палитра
   меняется мгновенно, обоими путями */
@media (prefers-reduced-motion: reduce) {
	html[data-st-anim]::view-transition-old(root),
	html[data-st-anim]::view-transition-new(root) {
		animation: none;
	}

	.st-site--fading,
	.st-site--fading * {
		transition: none !important;
	}
}

/*
	КНОПКА УХОДИТ ОТ НИЖНЕЙ ПАНЕЛИ НАВИГАЦИИ, а не ложится на нее:
	на телефоне правый верхний угол свободен, а нижний занят панелью
*/
@media (max-width: 575.98px) {
	.st-mode {
		top: 12px;
		right: 12px;
		width: 36px;
		height: 36px;
		font-size: 16px;
	}
}

/* ==== ЖИВОЙ ПОИСК ТОВАРОВ ============================================== */
/*
	ВЫДАЧА ЛЕЖИТ В САМОМ БЛОКЕ, а не всплывающим слоем в конце документа:
	переменные темы объявлены на корне сайта и наследуются по дереву —
	вынеси список наружу, и он перестал бы краситься темой.

	СПИСОК ПЕРЕКРЫВАЕТ СОДЕРЖИМОЕ, а не раздвигает его: страница
	не должна прыгать на каждую набранную букву
*/
.st-site .st-search {
	position: relative;
}

.st-site .st-search__drop {
	position: absolute;
	left: 0;
	right: 0;
	top: calc(100% + 6px);
	z-index: 30;
	max-height: 60vh;
	overflow-y: auto;
	padding: 6px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	box-shadow: var(--st-shadow, 0 6px 24px rgba(24, 32, 48, 0.08));
}

.st-site .st-search__item {
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 8px 10px;
	border-radius: var(--st-radius-sm);
	color: var(--st-text);
	text-decoration: none;
	cursor: pointer;
}

.st-site .st-search__item:hover {
	background-color: var(--st-surface-alt);
}

.st-site .st-search__thumb {
	flex: 0 0 auto;
	width: 44px;
	height: 44px;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface-alt);
	object-fit: cover;
}

.st-site .st-search__name {
	flex: 1 1 auto;
	min-width: 0;
	font-size: 14px;
	line-height: 1.35;
}

.st-site .st-search__price {
	flex: 0 0 auto;
	font-weight: 700;
	white-space: nowrap;
}

/* Пустая выдача и ошибка выглядят одинаково: посетителю важен факт,
   а не его причина */
.st-site .st-search__none {
	padding: 12px 10px;
	color: var(--st-muted);
	font-size: 14px;
	text-align: center;
}

/* ==== ЗАГЛУШКА 404 ===================================================== */

.st-site--notice {
	display: flex;
	align-items: center;
	justify-content: center;
	padding: 24px;
}

.st-notice {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 12px;
	max-width: 520px;
	text-align: center;
	color: var(--st-text);
}

.st-notice__logo {
	max-width: 180px;
	max-height: 72px;
	object-fit: contain;
}

.st-notice__brand {
	font-size: 18px;
	font-weight: 700;
}

/*
	КРУПНАЯ ЦИФРА ПРИГЛУШЕНА, А НЕ АКЦЕНТНА: это не действие и не главное
	на экране — главное здесь объяснение и путь дальше
*/
.st-notice__code {
	font-size: 72px;
	font-weight: 800;
	line-height: 1;
	color: var(--st-muted);
	opacity: 0.35;
}

.st-notice__title {
	font-size: 22px;
	font-weight: 700;
}

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

.st-notice__btn {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	margin-top: 6px;
	padding: 10px 22px;
	border-radius: var(--st-radius-sm);
	background-color: var(--st-accent);
	color: var(--st-accent-text);
	font-weight: 600;
	text-decoration: none;
}

/* ПРИГЛАШЕНИЕ ВОЙТИ НА ЗАГЛУШКЕ (матрица доступа, 2026-08-15). Сама
   карточка `.st-locked` описана в stheme.css — здесь только ее место
   в композиции заглушки: ширина ограничена, иначе на широком экране
   кнопки разъехались бы по краям */
.st-notice__locked {
	width: 100%;
	max-width: 420px;
	margin-top: 6px;
}

/* ==== УВАЖЕНИЕ К СИСТЕМНОЙ НАСТРОЙКЕ ==================================== */
/*
	Плавная прокрутка к якорю — украшение, и просьбу уменьшить движение
	оно обязано слушать безусловно. То же правило действует у анимаций
	появления и фонов (stheme.css)
*/
@media (prefers-reduced-motion: reduce) {
	html {
		scroll-behavior: auto;
	}

	.st-mode {
		transition: none;
	}

	.st-mode:hover {
		transform: none;
	}
}

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

	ПОЧЕМУ НЕ В `stheme.css`: тот файл грузит и КОНСТРУКТОР, а этих
	страниц в нем нет вовсе — правила уехали бы в редактор мертвым весом.
*/

/*
	ОБЛАСТЬ КАТАЛОГА — ОБЫЧНЫЙ ПОТОК, А НЕ 2D-СЕТКА.

	У системной страницы нет ни колонок, ни уровней: раздавать ей
	`grid-template-rows` не из чего, а сетка с одним элементом молча
	растянула бы его на минимальную высоту дорожки
*/
.st-site .st-page--flat {
	display: block;
	grid-template-columns: none;
	grid-template-rows: none;
}

.st-site .st-catalog {
	padding-top: 24px;
	padding-bottom: 32px;
}

.st-site .st-catalog .st-crumbs {
	margin-bottom: 18px;
}

/* ==== БРЕНД И ПОДБОРКА ================================================== */

.st-site .st-catalog__head {
	display: flex;
	align-items: center;
	gap: 20px;
	flex-wrap: wrap;
	margin-bottom: 20px;
}

.st-site .st-catalog__cover {
	flex: 0 0 180px;
	width: 180px;
	height: 120px;
	border-radius: var(--st-radius);
	background-color: var(--st-surface-alt);
	background-size: cover;
	background-position: center;
}

.st-site .st-catalog__intro {
	flex: 1 1 320px;
	min-width: 0;
}

.st-site .st-catalog__kind {
	font-size: 13px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--st-muted);
}

.st-site .st-catalog__title {
	margin: 4px 0 8px;
	font-size: 30px;
	font-weight: 700;
	line-height: 1.2;
	color: var(--st-text);
}

.st-site .st-catalog__chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 22px;
}

/* ==== ПОДСКАЗКИ (st-tip) ================================================ */
/*
	ПОДСКАЗКА ЦЕЛИКОМ НА CSS, И ЭТО ГЛАВНОЕ ЕЕ СВОЙСТВО.

	В сервисе подсказки делает bootstrap.Tooltip — по экземпляру на кнопку,
	и каждую перерисовку их приходится уничтожать и заводить заново
	(см. `disposeTooltips` в steditor.js). На сайте, где страницы
	подгружаются без перезагрузки, такой компонент пришлось бы
	переинициализировать после КАЖДОГО перехода, а забытый экземпляр
	оставлял бы висеть подсказку от кнопки, которой уже нет.

	Здесь подсказка — свойство самого узла: пришла новая разметка,
	пришли и подсказки. Инициализировать нечего, ломаться нечему.

	ПРАВИЛО ПРИМЕНЕНИЯ: `data-st-tip="текст"` на КАЖДОМ значке без подписи.
	`aria-label` при этом обязателен отдельно — подсказка видна только
	зрячему пользователю мыши
*/
.st-site [data-st-tip] {
	position: relative;
}

.st-site [data-st-tip]::after {
	content: attr(data-st-tip);
	position: absolute;
	left: 50%;
	bottom: calc(100% + 8px);
	z-index: 60;
	max-width: 220px;
	width: max-content;
	padding: 5px 9px;
	border-radius: 6px;
	background-color: rgba(24, 32, 48, 0.92);
	color: #FFFFFF;
	font-size: 12px;
	font-weight: 500;
	line-height: 1.35;
	white-space: normal;
	text-align: center;
	transform: translateX(-50%) translateY(3px);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 0.12s ease, transform 0.12s ease, visibility 0.12s;
}

/* Хвостик рисуется вторым слоем: отдельного узла у подсказки нет вовсе */
.st-site [data-st-tip]::before {
	content: '';
	position: absolute;
	left: 50%;
	bottom: calc(100% + 3px);
	z-index: 60;
	border: 5px solid transparent;
	border-top-color: rgba(24, 32, 48, 0.92);
	transform: translateX(-50%) translateY(3px);
	opacity: 0;
	visibility: hidden;
	pointer-events: none;
	transition: opacity 0.12s ease, transform 0.12s ease, visibility 0.12s;
}

.st-site [data-st-tip]:hover::after,
.st-site [data-st-tip]:hover::before,
.st-site [data-st-tip]:focus-visible::after,
.st-site [data-st-tip]:focus-visible::before {
	opacity: 1;
	visibility: visible;
	transform: translateX(-50%) translateY(0);
}

/* Подсказка снизу — для значков у самого верха окна (кнопка темы,
   кнопки карты): сверху ей просто некуда встать */
.st-site [data-st-tip][data-st-tip-at="bottom"]::after {
	bottom: auto;
	top: calc(100% + 8px);
}

.st-site [data-st-tip][data-st-tip-at="bottom"]::before {
	bottom: auto;
	top: calc(100% + 3px);
	border-top-color: transparent;
	border-bottom-color: rgba(24, 32, 48, 0.92);
}

/*
	==== БОКОВЫЕ ПОЛОЖЕНИЯ (2026-08-16) ====

	Понадобились значкам свойств на обложке товара: они стоят СТОЛБИКОМ
	у края карточки, и подсказка сверху накрывала бы соседний значок
	того же столбика, а у верхнего еще и вылезала бы за обложку.

	СДВИГ ПОЯВЛЕНИЯ РАЗВЕРНУТ ПО ОСИ: у верхней подсказки плашка
	подъезжает СНИЗУ ВВЕРХ, у боковой — от значка НАРУЖУ. Тот же жест
	вдоль неправильной оси читался бы как подергивание
*/
.st-site [data-st-tip][data-st-tip-at="right"]::after {
	bottom: auto;
	left: calc(100% + 8px);
	top: 50%;
	transform: translateY(-50%) translateX(-3px);
}

.st-site [data-st-tip][data-st-tip-at="right"]::before {
	bottom: auto;
	left: calc(100% + 3px);
	top: 50%;
	border-top-color: transparent;
	border-right-color: rgba(24, 32, 48, 0.92);
	border-left-width: 0;
	transform: translateY(-50%) translateX(-3px);
}

.st-site [data-st-tip][data-st-tip-at="left"]::after {
	bottom: auto;
	left: auto;
	right: calc(100% + 8px);
	top: 50%;
	transform: translateY(-50%) translateX(3px);
}

.st-site [data-st-tip][data-st-tip-at="left"]::before {
	bottom: auto;
	left: auto;
	right: calc(100% + 3px);
	top: 50%;
	border-top-color: transparent;
	border-left-color: rgba(24, 32, 48, 0.92);
	border-right-width: 0;
	transform: translateY(-50%) translateX(3px);
}

/* Показ боковых: общее правило возвращает `translateX(-50%)`, который
   боковым положениям не нужен вовсе — иначе плашка уехала бы на половину
   своей ширины влево */
.st-site [data-st-tip][data-st-tip-at="right"]:hover::after,
.st-site [data-st-tip][data-st-tip-at="right"]:hover::before,
.st-site [data-st-tip][data-st-tip-at="right"]:focus-visible::after,
.st-site [data-st-tip][data-st-tip-at="right"]:focus-visible::before,
.st-site [data-st-tip][data-st-tip-at="left"]:hover::after,
.st-site [data-st-tip][data-st-tip-at="left"]:hover::before,
.st-site [data-st-tip][data-st-tip-at="left"]:focus-visible::after,
.st-site [data-st-tip][data-st-tip-at="left"]:focus-visible::before {
	transform: translateY(-50%) translateX(0);
}

/* НА ПАЛЬЦЕВЫХ ЭКРАНАХ ПОДСКАЗОК НЕТ: наведения там не существует,
   а «залипшая» после касания подсказка перекрывает то, по чему нажали */
@media (hover: none) {
	.st-site [data-st-tip]::after,
	.st-site [data-st-tip]::before {
		display: none;
	}
}

/* ==== СЧЕТЧИК СИМВОЛОВ У ПОЛЯ (st-maxlen, 2026-08-17) =================== */
/*
	Плашка «осталось N» под полем с `maxlength`. Тот же ответ, что дает
    счетчик сервиса в кабинете, но собранный своими руками — плагин
	bootstrap-maxlength лежит внутри бандла Метроника вместе с jQuery,
	а публичная страница ни того, ни другого не грузит (та же причина,
	по которой здесь нет select2).

	ПЛАШКА ЗАНИМАЕТ МЕСТО ВСЕГДА, А ПОКАЗЫВАЕТСЯ ПО НАДОБНОСТИ:
	высота зарезервирована `min-height`, поэтому появление счетчика
	не дергает форму вниз ровно в тот момент, когда человек печатает
	последние символы
*/
.st-site .st-maxlen {
	display: block;
	min-height: 1em;
	margin-top: 4px;
	font-size: 12px;
	line-height: 1;
	color: var(--st-muted);
	opacity: 0;
	transition: opacity 0.15s ease;
}

.st-site .st-maxlen--on {
	opacity: 1;
}

/* Предел исчерпан: дальше символы просто не вводятся, и сказать об этом
   надо иначе, чем «осталось 7» */
.st-site .st-maxlen--full {
	color: var(--st-danger);
}

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

/* ==== СПИСКИ (st-select) ================================================ */
/*
	ВИД СНЯТ С SELECT2 СЕРВИСА, а собран своими руками — почему именно так,
	подробно объяснено в stsite.js (короткий ответ: отдельного файла select2
	в проекте нет, он внутри двухмегабайтного бандла Метроника вместе
	с jQuery, и публичной странице это не по карману).

	Оригинальный `<select>` не удаляется, а прячется: он остается значением
	формы и адресатом чужих подписок. Прячется РАЗМЕРОМ, а не `display:
	none` — скрытое поле не участвует в проверке формы браузером,
	и `required` на нем перестал бы работать
*/
.st-site .st-select {
	position: relative;
	display: inline-block;
	min-width: 180px;
	max-width: 100%;
}

.st-site .st-select__native {
	position: absolute;
	left: 12px;
	bottom: 0;
	width: 0;
	height: 0;
	padding: 0;
	border: 0;
	opacity: 0;
	pointer-events: none;
}

.st-site .st-select__btn {
	display: flex;
	align-items: center;
	gap: 8px;
	width: 100%;
	padding: 9px 12px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	color: var(--st-text);
	font: inherit;
	font-size: 14px;
	text-align: left;
	cursor: pointer;
}

.st-site .st-select__btn:hover,
.st-site .st-select--open .st-select__btn {
	border-color: var(--st-accent, #2E6BFF);
}

.st-site .st-select--off .st-select__btn {
	opacity: 0.55;
	cursor: not-allowed;
}

.st-site .st-select__label {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Стрелка нарисована рамками: подключать ради нее шрифт значков
   на страницу, где их может не быть вовсе, незачем */
.st-site .st-select__arrow {
	flex: 0 0 auto;
	width: 7px;
	height: 7px;
	margin-bottom: 3px;
	border-right: 1.5px solid currentColor;
	border-bottom: 1.5px solid currentColor;
	opacity: 0.6;
	transform: rotate(45deg);
	transition: transform 0.15s ease;
}

.st-site .st-select--open .st-select__arrow {
	margin-bottom: -3px;
	transform: rotate(-135deg);
}

.st-site .st-select__list {
	position: absolute;
	left: 0;
	right: 0;
	top: calc(100% + 6px);
	z-index: 30;
	display: none;
	max-height: 260px;
	overflow-y: auto;
	padding: 6px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm);
	background-color: var(--st-surface);
	box-shadow: var(--st-shadow, 0 6px 24px rgba(24, 32, 48, 0.08));
}

.st-site .st-select--open .st-select__list {
	display: block;
}

/*
	==== СВОЯ ПОЛОСА ПРОКРУТКИ СПИСКА (2026-08-21) ====

	СИСТЕМНАЯ ПОЛОСА ВЫБИВАЛАСЬ ИЗ КАРТИНЫ, и это не придирка: браузер
	рисует ее шириной в 15-17 px, прямоугольной, серой и в СВОЕЙ палитре —
	на темной теме сайта она оставалась светлой планкой у самого края
	скругленной коробки. Рядом с полем, у которого свои скругления
	и своя палитра, это читается как чужой элемент, «прилипший» к списку.

	СТИЛЯМИ, А НЕ СВОИМ ПОЛЗУНКОМ НА СКРИПТЕ. В конструкторе полоса сетки
	значков нарисована вручную (`st-iconpicker__bar`), и там это оправдано:
	сетка большая, ползунок несет еще и подсказку «листается дальше».
	Здесь список короткий, а свой ползунок означал бы обработчики
    прокрутки и перетаскивания на каждом поле сайта — цена выше пользы.

	==== СОБСТВЕННЫХ ПРАВИЛ ПОЛОСЫ ЗДЕСЬ БОЛЬШЕ НЕТ (2026-08-22) ====

	Они были написаны ДО того, как вид полосы стал настройкой оформления
	сайта, и с ее появлением превратились в исключение: владелец выбирал
	плавающую пилюлю, а выпадающий список упрямо показывал свою тонкую
	серую. Теперь общее правило (см. `steditorScrollCss` и `i_site`)
	красит и его — оно напечатано с нулевым весом через `:where()`,
	поэтому любое авторское правило по-прежнему сильнее.

	ОСТАЛОСЬ `overscroll-behavior`: это не оформление, а поведение —
	прокрутка списка до края не должна утаскивать за собой страницу
*/
.st-site .st-select__list {
	overscroll-behavior: contain;
}

.st-site .st-select__opt {
	padding: 8px 10px;
	border-radius: var(--st-radius-sm);
	color: var(--st-text);
	font-size: 14px;
	cursor: pointer;
}

.st-site .st-select__opt:hover {
	background-color: var(--st-surface-alt);
}

.st-site .st-select__opt--on {
	background-color: var(--st-surface-alt);
	font-weight: 600;
}

.st-site .st-select__opt--off {
	opacity: 0.45;
	cursor: not-allowed;
}

/*
	==== СТРОКА С ОБЛОЖКОЙ (2026-08-21) ====

	ПОЯВИЛАСЬ РАДИ КАЛЬКУЛЯТОРА МАТЕРИАЛА: покрытия различаются рисунком,
	и список из одних названий заставлял покупателя выбирать вслепую.
	Правила общие, а не «калькуляторные»: картинку получает ЛЮБОЙ пункт
	с `data-st-image`, откуда бы он ни пришел.

	`--rich` СТАВИТ КЛИЕНТ ПО ФАКТУ ДАННЫХ. Плотность строки со сторонним
	изображением другая, а угадать ее по классу списка нельзя: один
	и тот же список бывает и с обложками, и без них
*/
.st-site .st-select__pic {
	flex: 0 0 auto;
	display: block;
	width: 34px;
	height: 34px;
	overflow: hidden;
	border: 1px solid var(--st-border);
	border-radius: 8px;
	background-color: var(--st-surface-alt);
}

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

/* Подпись рядом с обложкой обязана ужиматься, а не выталкивать картинку:
   названия товаров длинные, а ширина поля задана формой */
.st-site .st-select__text {
	flex: 1 1 auto;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.st-site .st-select__label,
.st-site .st-select__opt {
	display: flex;
	align-items: center;
	gap: 10px;
}

/* Кнопка с обложкой выше обычной ровно на высоту картинки —
   отступы поля при этом остаются теми же */
.st-site .st-select--rich .st-select__btn {
	padding-top: 6px;
	padding-bottom: 6px;
}

.st-site .st-select--rich .st-select__opt {
	padding-top: 6px;
	padding-bottom: 6px;
}

/* ==== ФИЛЬТРЫ И СОРТИРОВКА КАТАЛОГА (2026-08-18) ====================== */
/*
	РЯДАМИ, А НЕ БОКОВОЙ КОЛОНКОЙ. Боковая панель фильтров съедает четверть
	ширины витрины на ПК и уезжает под спойлер на телефоне — а фильтров
	здесь пять, и все они короткие. Ряд «подпись — значения» читается
	одинаково на любом экране.

	ЗНАЧЕНИЯ — ОБЫЧНЫЕ ССЫЛКИ (`.st-chip`), тот же элемент, что у ссылок
	на бренд и подборку: два разных вида «кликабельной пилюли» на одной
	странице читались бы как разные по смыслу
*/
.st-site .st-filters {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin-bottom: 18px;
	padding: 14px 16px;
	border: 1px solid var(--st-border);
	border-radius: var(--st-radius-sm, 10px);
	background-color: var(--st-surface);
}

.st-site .st-filters__row,
.st-site .st-filters__sort {
	display: flex;
	align-items: baseline;
	flex-wrap: wrap;
	gap: 8px 12px;
}

.st-site .st-filters__label {
	min-width: 140px;
	color: var(--st-muted);
	font-size: 13px;
}

.st-site .st-filters__values {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
}

/* Пилюля выбора мельче обычной: их в ряду бывает по десять, и полный
   размер превращал бы фильтры в главный элемент страницы */
.st-site .st-chip--pick {
	padding: 5px 11px;
	font-size: 13px;
	font-weight: 500;
	text-decoration: none;
}

.st-site .st-chip--on {
	border-color: var(--st-accent);
	background-color: var(--st-accent);
	color: var(--st-accent-text);
}

/* Сколько товаров с таким значением. Приглушен: это подсказка о размере
   выборки, а не часть названия */
.st-site .st-chip__count {
	opacity: 0.6;
	font-size: 12px;
}

.st-site .st-filters__foot {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 10px;
	padding-top: 8px;
	border-top: 1px dashed var(--st-border);
	color: var(--st-muted);
	font-size: 13px;
}

.st-site .st-filters__reset {
	color: var(--st-accent);
	font-size: 13px;
	font-weight: 600;
	text-decoration: none;
}

@media (max-width: 575.98px) {
	.st-site .st-filters__label {
		min-width: 100%;
	}
}
